Event KernelMode(64 bit Driver) -> UserMode (32 bit application)

Hi,
I would like to ask you for advice. I need SetEvent from Driver WDF (PCI card), when Interrupt occur to the application. We have used this code on the WIN XP x86 successfully (driver WDM) but now we need use to same on the WIN 7 x64 (driver wdf).

UserMode creates the event HANDLE successfully:

hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

Then passes it to Kernel Mode through IOCTL:

DeviceIoControl(
hdevice,
IOCTL_REGISTER_EVENT,
&hEvent,
sizeof(hEvent),
NULL,
0,
&junk,
NULL);

Which gets picked up in Kernel Mode:

Irp = WdfRequestWdmGetIrp(Request);
case IOCTL_REGISTER_EVENT:
devContext->HEvent = *(PHANDLE) Irp->AssociatedIrp.SystemBuffer;
KdPrint ((DRIVERNAME"\t\t\t\t HEvent is: (0x%p)\r\n", devContext->HEvent));

status = ObReferenceObjectByHandle(
devContext->HEvent,
EVENT_MODIFY_STATE,
*ExEventObjectType,
KernelMode,
&devContext->KEvent, NULL);

KdPrint ((DRIVERNAME"\t\t\t\t KEvent is: (0x%p)\r\n", devContext->KEvent));
if(!NT_SUCCESS(status)){
KdPrint((DRIVERNAME"\t\t\t\tObReferenceObjectByHandle() failed 0x%x\n", status));
devContext->HEvent = NULL;
devContext->KEvent = NULL;
}
break;

This code work correctly under the WIN XP x86, as I wrote upwards, but in the WIN 7 x64 i have problem with STATUS_INVALID_HANDLE, error code 0xc0000008, which get from ObReferenceObjectByHandle.

It is strange, because i compared hEvent from UserMode with HEvent from Kernel Mode and that value was equivalent. Maybe is problem in 32 bit app in 32 bit HANDLE and 64 bit HANDLE in Driver KernelMode.

But i tried this structure in UserMode:

typedef struct {
HANDLE hEvent;
HANDLE zero;
}s_handle;

I wanted same lenght. I got it, but problem still standing.

Please help me find out why the handle is invalid?

Handle type should be not KernelMode, but UserMode, because it comes from user mode.

2 Things to watch out for

1 If the app is 32 bits, the size of HANDLE is different and your driver code could referencing past the end of the buffer

2 There is no guarantee that kmdf calls your io callback in the context of the app. For the right context, you need to register an EvtIoInContext callback, turn the handle into the object and then forward the request to your normal io queue for further processing if needed.

d

dent from a phine with no keynoard

-----Original Message-----
From: xxxxx@seznam.cz
Sent: Saturday, March 19, 2011 4:44 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] Event KernelMode(64 bit Driver) -> UserMode (32 bit application)

Hi,
I would like to ask you for advice. I need SetEvent from Driver WDF (PCI card), when Interrupt occur to the application. We have used this code on the WIN XP x86 successfully (driver WDM) but now we need use to same on the WIN 7 x64 (driver wdf).

UserMode creates the event HANDLE successfully:

hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

Then passes it to Kernel Mode through IOCTL:

DeviceIoControl(
hdevice,
IOCTL_REGISTER_EVENT,
&hEvent,
sizeof(hEvent),
NULL,
0,
&junk,
NULL);

Which gets picked up in Kernel Mode:

Irp = WdfRequestWdmGetIrp(Request);
case IOCTL_REGISTER_EVENT:
devContext->HEvent = *(PHANDLE) Irp->AssociatedIrp.SystemBuffer;
KdPrint ((DRIVERNAME"\t\t\t\t HEvent is: (0x%p)\r\n", devContext->HEvent));

status = ObReferenceObjectByHandle(
devContext->HEvent,
EVENT_MODIFY_STATE,
*ExEventObjectType,
KernelMode,
&devContext->KEvent, NULL);

KdPrint ((DRIVERNAME"\t\t\t\t KEvent is: (0x%p)\r\n", devContext->KEvent));
if(!NT_SUCCESS(status)){
KdPrint((DRIVERNAME"\t\t\t\tObReferenceObjectByHandle() failed 0x%x\n", status));
devContext->HEvent = NULL;
devContext->KEvent = NULL;
}
break;

This code work correctly under the WIN XP x86, as I wrote upwards, but in the WIN 7 x64 i have problem with STATUS_INVALID_HANDLE, error code 0xc0000008, which get from ObReferenceObjectByHandle.

It is strange, because i compared hEvent from UserMode with HEvent from Kernel Mode and that value was equivalent. Maybe is problem in 32 bit app in 32 bit HANDLE and 64 bit HANDLE in Driver KernelMode.

But i tried this structure in UserMode:

typedef struct {
HANDLE hEvent;
HANDLE zero;
}s_handle;

I wanted same lenght. I got it, but problem still standing.

Please help me find out why the handle is invalid?


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

> status = ObReferenceObjectByHandle(

devContext->HEvent,
EVENT_MODIFY_STATE,
*ExEventObjectType,
KernelMode,

Must be Irp->RequestorMode, not KernelMode.

Also note that in WOW64 app, handles are 32bit, and in the kernel, they are 64bit. Just zero-extend them.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

Hi,
thank you very much for yours replies.

2Alex Grig:

I tried UserMode of course, but it still didn?t work.

2Doron Holan:

  1. I absolutely agree with you. For example hEvent after CreateEvent has value 0x00000160. I use DeviceIoControl for moving that HANDLE to the KernelMode and after

devContext->HEvent = *(PHANDLE) Irp->AssociatedIrp.SystemBuffer;
KdPrint ((DRIVERNAME"\t\t\t\t HEvent is: (0x%p)\r\n", devContext->HEvent));

i see 0x0000000000000160. It looked same, but something must be wrong, because incoming buffer has size 4 byte. I tried zero fill with structure s_handle and incoming buffer had 8 byte size, but i don?t know, if i did correct, because it didn?t work.

  1. There is no guarantee that kmdf calls your io callback in the context of the app. For the right context, you need to register an EvtIoInContext callback, turn the handle into the object and then forward the request to your normal io queue for further processing if needed.

Could you explain this closer? I should register that in EvtDeviceAdd?

2Maxim S. Shatskih:

Must be Irp->RequestorMode, not KernelMode.

I tried it of course. I tried many variations with ObReferenceObjectByHandle, but STATUS_INVALID_HANDLE still standing.

Also note that in WOW64 app, handles are 32bit, and in the kernel, they are 64bit. Just zero-extend them.

It looks interesting, i tried it, but maybe wrong. Could you write to me, as i should do that?

Good, thanks you very much for yours replies. I feel, we could solved it. This problem was discussed in the many forums, but nowhere was solved.

Yes, in evtdriverdeviceadd there is a WdfDeviceInitXxx call that you register this callback with.

d

dent from a phine with no keynoard

-----Original Message-----
From: xxxxx@seznam.cz
Sent: Sunday, March 20, 2011 5:31 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Event KernelMode(64 bit Driver) -> UserMode (32 bit application)

Hi,
thank you very much for yours replies.

2Alex Grig:

I tried UserMode of course, but it still didn?t work.

2Doron Holan:

  1. I absolutely agree with you. For example hEvent after CreateEvent has value 0x00000160. I use DeviceIoControl for moving that HANDLE to the KernelMode and after

devContext->HEvent = *(PHANDLE) Irp->AssociatedIrp.SystemBuffer;
KdPrint ((DRIVERNAME"\t\t\t\t HEvent is: (0x%p)\r\n", devContext->HEvent));

i see 0x0000000000000160. It looked same, but something must be wrong, because incoming buffer has size 4 byte. I tried zero fill with structure s_handle and incoming buffer had 8 byte size, but i don?t know, if i did correct, because it didn?t work.

  1. There is no guarantee that kmdf calls your io callback in the context of the app. For the right context, you need to register an EvtIoInContext callback, turn the handle into the object and then forward the request to your normal io queue for further processing if needed.

Could you explain this closer? I should register that in EvtDeviceAdd?

2Maxim S. Shatskih:

Must be Irp->RequestorMode, not KernelMode.

I tried it of course. I tried many variations with ObReferenceObjectByHandle, but STATUS_INVALID_HANDLE still standing.

Also note that in WOW64 app, handles are 32bit, and in the kernel, they are 64bit. Just zero-extend them.

It looks interesting, i tried it, but maybe wrong. Could you write to me, as i should do that?

Good, thanks you very much for yours replies. I feel, we could solved it. This problem was discussed in the many forums, but nowhere was solved.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

2Doron Holan:

Yes, i have done it. But that isn?t problem.

//
// Configure our queue of incoming requests
//
// We only use the default queue, and we support IRP_MJ_DEVICE_CONTROL,
// IRP_MJ_READ and IRP_MJ_WRITE.
//
WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&ioCallbacks,
WdfIoQueueDispatchSequential);

ioCallbacks.EvtIoDeviceControl = EvtDeviceControl;
ioCallbacks.EvtIoRead = EvtIoRead;
ioCallbacks.EvtIoWrite = EvtIoWrite;

status = WdfIoQueueCreate(device,
&ioCallbacks,
WDF_NO_OBJECT_ATTRIBUTES,
NULL); // optional pointer to receive queue handle

Invalid HANDLE still occur in ObReferenceObjectByHandle.

That is a normal io queue being created. That is not an in caller context callback. Look at the wdfdeviceinit set of APIs, you will find it

d

dent from a phine with no keynoard

-----Original Message-----
From: xxxxx@seznam.cz
Sent: Sunday, March 20, 2011 9:58 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Event KernelMode(64 bit Driver) -> UserMode (32 bit application)

2Doron Holan:

Yes, i have done it. But that isn?t problem.

//
// Configure our queue of incoming requests
//
// We only use the default queue, and we support IRP_MJ_DEVICE_CONTROL,
// IRP_MJ_READ and IRP_MJ_WRITE.
//
WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&ioCallbacks,
WdfIoQueueDispatchSequential);

ioCallbacks.EvtIoDeviceControl = EvtDeviceControl;
ioCallbacks.EvtIoRead = EvtIoRead;
ioCallbacks.EvtIoWrite = EvtIoWrite;

status = WdfIoQueueCreate(device,
&ioCallbacks,
WDF_NO_OBJECT_ATTRIBUTES,
NULL); // optional pointer to receive queue handle

Invalid HANDLE still occur in ObReferenceObjectByHandle.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

> ioCallbacks.EvtIoDeviceControl = EvtDeviceControl;

And where is EvtIoInCallerContext?


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

Yes,
thanks, i found it.

WdfDeviceInitSetIoInCallerContextCallback

EVT_WDF_IO_IN_CALLER_CONTEXT MyIoInCallerContext;

I could catch every requests, which app send me before insertion to the queue.

And i would like ask you. How could help me that thing to solved problem with STATUS_INVALID_HANDLE?

I ask, because i catch hEvent from UserMode in KernelMode in the EvtDeviceControl. That values are same but something must be wrong.

Go back and read my response why this function is different

d

dent from a phine with no keynoard

-----Original Message-----
From: xxxxx@seznam.cz
Sent: Sunday, March 20, 2011 3:52 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Event KernelMode(64 bit Driver) -> UserMode (32 bit application)

Yes,
thanks, i found it.

WdfDeviceInitSetIoInCallerContextCallback

EVT_WDF_IO_IN_CALLER_CONTEXT MyIoInCallerContext;

I could catch every requests, which app send me before insertion to the queue.

And i would like ask you. How could help me that thing to solved problem with STATUS_INVALID_HANDLE?

I ask, because i catch hEvent from UserMode in KernelMode in the EvtDeviceControl. That values are same but something must be wrong.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

wrote in message news:xxxxx@ntdev…
>
> And i would like ask you. How could help me that thing to solved problem
> with STATUS_INVALID_HANDLE?
> I ask, because i catch hEvent from UserMode in KernelMode in the
> EvtDeviceControl. That values are same but something must be wrong.
>

Handling of your DeviceIoControl begins in the state or context, where
usermode handles belong to the calling process.
WdfDeviceInitSetIoInCallerContextCallback lets you do things in this context
(though you are in kernel mode).
Outside of this context the same handle value will mean something wrong.

– pa

> And i would like ask you. How could help me that thing to solved problem with

STATUS_INVALID_HANDLE?

ObReferenceObjectByHandle uses the notion of current process internally.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

Hi,
problem with Invalid HANDLE is solved. Thank you very much for yours help.

Thanks for advice with EvtIoInContext , but i didn?t try it. But that idea was served to solved that problem.

I used DeviceIoControl(
hdevice[device_id],
IOCTL_REGISTER_EVENT,
&hEvent[device_id],
sizeof(hEvent[device_id]),
NULL,
0,
&junk,
NULL);
}

for get hEvent to the driver, but that was wrong, how Doron Holan wrote with bad Context.

I used WriteFile(hdevice, &hEvent, sizeof(hEvent), &junk, NULL) for hand over HANDLE to the Driver and in the DeviceIOControl catch its. My HANDLE was waiting for me in the user defined buffer.

So you are saying passing the handle in WriteFile works, while it doesn’t in DeviceIoControl? That means you are getting lucky. Use the InContext callback for this particular IOCTL, that is what it is designed to do.

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@seznam.cz
Sent: Monday, March 21, 2011 3:41 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Event KernelMode(64 bit Driver) -> UserMode (32 bit application)

Hi,
problem with Invalid HANDLE is solved. Thank you very much for yours help.

Thanks for advice with EvtIoInContext , but i didn?t try it. But that idea was served to solved that problem.

I used DeviceIoControl(
hdevice[device_id],
IOCTL_REGISTER_EVENT,
&hEvent[device_id],
sizeof(hEvent[device_id]),
NULL,
0,
&junk,
NULL);
}

for get hEvent to the driver, but that was wrong, how Doron Holan wrote with bad Context.

I used WriteFile(hdevice, &hEvent, sizeof(hEvent), &junk, NULL) for hand over HANDLE to the Driver and in the DeviceIOControl catch its. My HANDLE was waiting for me in the user defined buffer.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

2Doron Holan:

Maybe you are truth, so i getting lucky with this. But that really work and it isn?t luck, because i used it that for transfer data in/out to the device. WriteFile, DeviceIOControl, ReadFile… So and i used it that for hande over HANDLE.

Thanks all again.

You passed this information in a WDM driver successfully. KMDF has slightly different rules. I described those rules to you. You have chosen to ignore them. I don’t need to repeat myself anymore.

Thx
d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@seznam.cz
Sent: Monday, March 21, 2011 11:36 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Event KernelMode(64 bit Driver) -> UserMode (32 bit application)

2Doron Holan:

Maybe you are truth, so i getting lucky with this. But that really work and it isn?t luck, because i used it that for transfer data in/out to the device. WriteFile, DeviceIOControl, ReadFile… So and i used it that for hande over HANDLE.

Thanks all again.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

I don?t ignore that information Doron. I tried it, but i hurried and solution with WriteFile was so easy, quick and effective. Your solution is absolutely clear, thanks.

I hope, this discussion will serve other else people, which solving same problem.