[x64] problem thread stopped and KeWaitForSingleObject

Hello all,

I develop a driver for a smartcard reader.
I use a thread for execute the card tracking ( polling ).
I have a problem with this function : KeWaitForSingleObject
With xp 32 bit, my thread is stopped properly thanks to an event.
When my thread is stopped and “KeWaitForSingleObject” return a “status_success”

// Check if the thread is already complete
ntStatus = KeWaitForSingleObject ( &SmartcardExtension->ReaderExtension->PollingThreadHandle,
Executive,
KernelMode,
FALSE,
&Delay
);

here KeWaitForSingleObject return a STATUS_SUCCESS in 32bit.

With 64bit OS ( Vista, Seven and Xp ) I have a “status_timeout” with “Delay”
And If I replace “Delay” by “NULL” I have a BSOD or driver is blocked.

variable type :
HANDLE PollingThreadHandle;

is it that this problem can be caused by the cast for 64bit like presented here : http://msdn.microsoft.com/en-us/library/ff545635.aspx

Some one can help me please.

Thanks in advance,

Regards,

xxxxx@hotmail.com wrote:

I develop a driver for a smartcard reader.
I use a thread for execute the card tracking ( polling ).
I have a problem with this function : KeWaitForSingleObject
With xp 32 bit, my thread is stopped properly thanks to an event.
When my thread is stopped and “KeWaitForSingleObject” return a “status_success”

// Check if the thread is already complete
ntStatus = KeWaitForSingleObject ( &SmartcardExtension->ReaderExtension->PollingThreadHandle,
Executive,
KernelMode,
FALSE,
&Delay
);

here KeWaitForSingleObject return a STATUS_SUCCESS in 32bit.

With 64bit OS ( Vista, Seven and Xp ) I have a “status_timeout” with “Delay”
And If I replace “Delay” by “NULL” I have a BSOD or driver is blocked.

variable type :
HANDLE PollingThreadHandle;

There are a nearly infinite number of ways this could fail. Where does
the value PollingThreadHandle come from? Are you sure you’re not
closing the handle before you make the call? Did you get the handle
from user mode?


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Thank you Tim for your help,

PollingThreadHandle is typed HANDLE and its used for create my thread.

PsCreateSystemThread (
&readerExtension->PollingThreadHandle,
THREAD_ALL_ACCESS,
&ObjectAttributes,
NULL,
NULL,
BLT_CardTracking_Thread_EX,
&Context
);

My thread is correctly stopped and after I execute “KeWaitForSingleObject” for confirm it.

KeWaitForSingleObject wants a pointer to a dispatcher object, not a handle.

Take PollingThreadHandle and turn it into PollingThreadObject like this:

ObReferenceObjectByHandle(readerExtension->PollingThreadHandle, THREAD_ALL_ACCESS, NULL, KernelMode, &readerExtension->PollingThreadObject, NULL);

ZwClose(readerExtension->PollingThreadHandle);

Then wait on the PollingThreadObject

Thanks Steve for your help I try this use now.

Regards,

Kamel

I looked on MSDN and it’s necessary to use this :
NTSTATUS ObReferenceObjectByHandle(
__in HANDLE Handle,
__in ACCESS_MASK DesiredAccess,
__in_opt POBJECT_TYPE ObjectType,
__in KPROCESSOR_MODE AccessMode,
__out PVOID *Object,
__out_opt POBJECT_HANDLE_INFORMATION HandleInformation
);

you advised me to use this “&readerExtension->PollingThreadObject”, but what is it ?
An event ? if it’s case, this event wait something or it’s just necessary to release it after zwClose ?

Thanks in advance,

Best regards,

Make your code look like this…

In the device extension instead of:
HANDLE PollingThreadHandle;
replace with:
PETHREAD PollingThreadObject;

Then when you call PsCreateSystemThread,

Function(…)
{
HANDLE PollingThreadHandle;

PsCreateSystemThread (
&PollingThreadHandle,
THREAD_ALL_ACCESS,
&ObjectAttributes,
NULL,
NULL,
BLT_CardTracking_Thread_EX,
&Context
);

ObReferenceObjectByHandle(PollingThreadHandle, THREAD_ALL_ACCESS, NULL, KernelMode, &readerExtension->PollingThreadObject, NULL);

ZwClose(PollingThreadHandle);

So you are storing a pointer to the object, incrementing it’s reference count while doing so, then closing the handle (which you don’t need) - which will decrement it’s reference count. Now you have a pointer to the PETHREAD object that you can use in your call to KeWaitForSingleObject…


// Wait for the PollingThread to terminate
KeWaitForSingleObject(readerExtension->PollingThreadObject, Executive, KernelMode, FALSE, &Delay);

I’m not sure why or how your code worked properly in 32-bit!

Thanks a lot Steve for your help,
I try it immediately :slight_smile:

Always the same problem Steve.
I have updated my code with your example, but the last past

… // Wait for the PollingThread to terminate KeWaitForSingleObject(readerExtension->PollingThreadObject, Executive, KernelMode, FALSE, &Delay);

Return a STATUS_TIMEOUT, and if I execute an other keWait without delay, I have a BSOD

… // Wait for the PollingThread to terminate KeWaitForSingleObject(readerExtension->PollingThreadObject, Executive, KernelMode, FALSE, &Delay);

Thanks in advance for your help