howto pass a handle to a driver

Hi,

I want to pass down a handle to a driver.

As described here:
http://www.codeproject.com/KB/system/driveguicomm.aspx

Here is the code of my user mode application:

=================================================================================

hCommDevice = CreateFile( L"\\?\USB#VID_0908&PID_0001&MI_01#6&3221311a&0&0001#{7972cac1-2741-11d3-a46c-00a0cc3bc015}",
0,
FILE_SHARE_READ |
FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL);
LastError = GetLastError(); // is always 0 ==> CreateFile is always ok

BOOL SUCCEDED = DeviceIoControl( hCommDevice,
IO_REFERENCE_EVENT,
(LPVOID) ghCommEvent, sizeof (LPVOID),
NULL, 0,
&BytesReturned,
(LPOVERLAPPED) NULL);
LastError = GetLastError(); // returns 998

=================================================================================

DeviceIoControl fails and GetLastError returns:
998: ERROR_NOACCESS = Invalid access to memory location.

Also the breakpoint, which I placed in my IRP_MJ_DEVICE_CONTROL Dispatch function,
has not been hit.

Since the error code 998 says that there is some problem with memory / pointer…
I tried it this way:

=================================================================================

DeviceIoControl( hCommDevice,
IO_REFERENCE_EVENT,
======> NULL, 0, <======= // no input buffer.
NULL, 0,
&BytesReturned,
NULL );

=================================================================================

Now also my breakpoint in the IRP_MJ_DEVICE_CONTROL Dispatch function
has not been hit.

Now the last error code is 3758555139.

Unfortunately this is not a valid system error code. Because it is
outside the defined range of system error codes ( 0 … 15999 ).

So this system error code does not give me a hint on what might
be the reason for the occured error.

=====>

  1. Does somebody know the reason for the described errors?

  2. Can somebody tell me how to pass the event handle to my driver?

  3. Or can somebody tell me an URL to a code snippet with the correct values
    for CreateFile & DeviceIoControl to past down a handle into a driver.

Hi.

See what Doron Holan says here:
http://www.osronline.com/showThread.CFM?link=106081

You want to use an IOCTL other then METHOD_NEITHER, it is very insecure.
instead, use METHOD_BUFFERED and send a pointer to the handle, not the
handle
itself

DeviceIoControl(hCommDevice,
IO_REFERENCE_EVENT,
(LPVOID) &ghCommEvent, <== notice the &

and then retrieve the handle as HANDLE hEvent = *(HANDLE*) from
Irp->AssociatedIrp.SystemBuffer;

wrote news:xxxxx@ntdev…
> Hi,
>
> I want to pass down a handle to a driver.
>
> As described here:
> http://www.codeproject.com/KB/system/driveguicomm.aspx
>
>
> Here is the code of my user mode application:
>
>
> =================================================================================
>
>
> hCommDevice = CreateFile(
> L"\\?\USB#VID_0908&PID_0001&MI_01#6&3221311a&0&0001#{7972cac1-2741-11d3-a46c-00a0cc3bc015}",
> 0,
> FILE_SHARE_READ |
> FILE_SHARE_WRITE,
> NULL,
> OPEN_EXISTING,
> 0,
> NULL);
> LastError = GetLastError(); // is always 0 ==> CreateFile
> is always ok
>
>
> BOOL SUCCEDED = DeviceIoControl( hCommDevice,
> IO_REFERENCE_EVENT,
> (LPVOID) ghCommEvent, sizeof (LPVOID),
> NULL, 0,
> &BytesReturned,
> (LPOVERLAPPED) NULL);
> LastError = GetLastError(); // returns 998
>
>
> =================================================================================
>
>
> DeviceIoControl fails and GetLastError returns:
> 998: ERROR_NOACCESS = Invalid access to memory location.
>
> Also the breakpoint, which I placed in my IRP_MJ_DEVICE_CONTROL Dispatch
> function,
> has not been hit.
>
>
> Since the error code 998 says that there is some problem with memory /
> pointer…
> I tried it this way:
>
>
> =================================================================================
>
>
> DeviceIoControl( hCommDevice,
> IO_REFERENCE_EVENT,
> ======> NULL, 0, <======= // no input buffer.
> NULL, 0,
> &BytesReturned,
> NULL );
>
> =================================================================================
>
>
> Now also my breakpoint in the IRP_MJ_DEVICE_CONTROL Dispatch function
> has not been hit.
>
> Now the last error code is 3758555139.
>
> Unfortunately this is not a valid system error code. Because it is
> outside the defined range of system error codes ( 0 … 15999 ).
>
> So this system error code does not give me a hint on what might
> be the reason for the occured error.
>
>
>
> =====>
>
> 1. Does somebody know the reason for the described errors?
>
> 2. Can somebody tell me how to pass the event handle to my driver?
>
> 3. Or can somebody tell me an URL to a code snippet with the correct
> values
> for CreateFile & DeviceIoControl to past down a handle into a driver.
>
>
>

&ghCommEvent

-p

On Sep 23, 2011, at 5:55 AM, “xxxxx@live.com” wrote:

> Hi,
>
> I want to pass down a handle to a driver.
>
> As described here:
> http://www.codeproject.com/KB/system/driveguicomm.aspx
>
>
> Here is the code of my user mode application:
>
>
> =================================================================================
>
>
> hCommDevice = CreateFile( L"\\?\USB#VID_0908&PID_0001&MI_01#6&3221311a&0&0001#{7972cac1-2741-11d3-a46c-00a0cc3bc015}",
> 0,
> FILE_SHARE_READ |
> FILE_SHARE_WRITE,
> NULL,
> OPEN_EXISTING,
> 0,
> NULL);
> LastError = GetLastError(); // is always 0 ==> CreateFile is always ok
>
>
> BOOL SUCCEDED = DeviceIoControl( hCommDevice,
> IO_REFERENCE_EVENT,
> (LPVOID) ghCommEvent, sizeof (LPVOID),
> NULL, 0,
> &BytesReturned,
> (LPOVERLAPPED) NULL);
> LastError = GetLastError(); // returns 998
>
>
> =================================================================================
>
>
> DeviceIoControl fails and GetLastError returns:
> 998: ERROR_NOACCESS = Invalid access to memory location.
>
> Also the breakpoint, which I placed in my IRP_MJ_DEVICE_CONTROL Dispatch function,
> has not been hit.
>
>
> Since the error code 998 says that there is some problem with memory / pointer…
> I tried it this way:
>
>
> =================================================================================
>
>
> DeviceIoControl( hCommDevice,
> IO_REFERENCE_EVENT,
> ======> NULL, 0, <======= // no input buffer.
> NULL, 0,
> &BytesReturned,
> NULL );
>
> =================================================================================
>
>
> Now also my breakpoint in the IRP_MJ_DEVICE_CONTROL Dispatch function
> has not been hit.
>
> Now the last error code is 3758555139.
>
> Unfortunately this is not a valid system error code. Because it is
> outside the defined range of system error codes ( 0 … 15999 ).
>
> So this system error code does not give me a hint on what might
> be the reason for the occured error.
>
>
>
> =====>
>
> 1. Does somebody know the reason for the described errors?
>
> 2. Can somebody tell me how to pass the event handle to my driver?
>
> 3. Or can somebody tell me an URL to a code snippet with the correct values
> for CreateFile & DeviceIoControl to past down a handle into a driver.
>
>
>
> —
> 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
>

xxxxx@live.com wrote:

=================================================================================

hCommDevice = CreateFile( L"\\?\USB#VID_0908&PID_0001&MI_01#6&3221311a&0&0001#{7972cac1-2741-11d3-a46c-00a0cc3bc015}",

You don’t really have that hard-coded into your application, do you?
The numbers in that path identify a specific USB hub on your specific
computer, and a specific port on that hub. If you move to a different
computer, or change hubs, or insert a new hub, or change ports, this
path will not work. You need to be using the SetupDi APIs to find this
path, every single time.

If you are doing that, and you only included this line as an example for
the purposes of your question, then ignore my remark.

BOOL SUCCEDED = DeviceIoControl( hCommDevice,
IO_REFERENCE_EVENT,
(LPVOID) ghCommEvent, sizeof (LPVOID),
NULL, 0,
&BytesReturned,
(LPOVERLAPPED) NULL);
LastError = GetLastError(); // returns 998

Frank pointed out the right answer here – you need &ghCommEvent. Note,
however, that it is never necessary to cast NULL. NULL is compatible
with every pointer type. Casts are evil, and you should question every
one you write.

Now the last error code is 3758555139.

Unfortunately this is not a valid system error code. Because it is
outside the defined range of system error codes ( 0 … 15999 ).

Why do you think that? Error codes are 32-bit values. The top two bits
tell you about the severity of the error. There are other fields in
there as well. Check <winerror.h>.

> So this system error code does not give me a hint on what might
> be the reason for the occured error.

I’m always amazed when technically-oriented people look at a large
number like that and don’t automatically think “that number must be more
interesting in hex”. That’s 0xE0070003. which is a “customer-defined”
error code. When a driver returns an IoStatus value with bit 29 set
(like that one), the error code gets passed unchanged to the user-mode
application. It is presumed that the application will know what to do
with it.

Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.</winerror.h>

> Hi,

I want to pass down a handle to a driver.

As described here:
http://www.codeproject.com/KB/system/driveguicomm.aspx

Here is the code of my user mode application:

=================================================================================

hCommDevice = CreateFile(
L"\\?\USB#VID_0908&PID_0001&MI_01#6&3221311a&0&0001#{7972cac1-2741-11d3-a46c-00a0cc3bc015}",
0,
FILE_SHARE_READ |
FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL);

*******
Note that the value returned by GetLastError is generlaly UNDEFINED unless
the previous API is KNOWN to have FAILED. An API that succeeds usually
does not change the value returned by GetLastError, so it is unreliable as
coded here
*******

LastError = GetLastError(); // is always 0 ==>
CreateFile is always ok

*******
The comment above is erroneous; if LastError != 0 it does not prove that
CreateFile failed! THe only valid test is
if(hCommDevice != INVALID_HANDLE_VALUE)
{ /* failed */
LastError = GetLastError(); // the only place it is known to be valid
…deal with error
} /* failed */
*******

BOOL SUCCEDED = DeviceIoControl( hCommDevice,
IO_REFERENCE_EVENT,
(LPVOID) ghCommEvent, sizeof (LPVOID),

****
The suggestion implified by “gh”, that this is a global variable, is very
suspect. Why would you need a global variable?

It expects a valid pointer, and a handle is not a pointer; the (LPVOID)
cast is erroneous, because you are saying “This is the pointer to the
data” when it is really a handle. The correct expression here would be
&ghCommEvent

And if you are passing a handle, it should be sizeof(HANDLE)

Note that it is always suspect if you are trying to pass a handle to the
kernel; in general, this indicates a design failure in the driver, an
attempt to emulate some historically known RTOS model that signaled
events; you need to redesign your driver to not work this way. It is
weird and very un-Windows-like. You should not be signaling events in
your driver! Asynchronous I/O woulld be the correct approach to this
problem.
*******

NULL, 0,
&BytesReturned,
(LPOVERLAPPED) NULL);
*****
The (LPVOERLAPPED) cast is unnecessary. In general tossing casts around
like this only leads to programs that fail in obscure ways, as already
demonstrated by the erroneous (LPVOID) cast. Getting a program which is
fundamentally wrong to compile by tossing casts at it is not a good
approach.
*****

LastError = GetLastError(); // returns 998
****
Note that since you do this even if the DeviceIoControl succeeds, you have
no idea what LastError might mean at this point!
****

=================================================================================

DeviceIoControl fails and GetLastError returns:
998: ERROR_NOACCESS = Invalid access to memory location.

Also the breakpoint, which I placed in my IRP_MJ_DEVICE_CONTROL Dispatch
function,
has not been hit.
****
That’s because you passed in an illegal address for the buffer address,
because you fooled the compiler into accepting a handle as an address, and
the I/O Manager rightly rejected your call and never passed it to your
driver.
****

Since the error code 998 says that there is some problem with memory /
pointer…
I tried it this way:

=================================================================================

DeviceIoControl( hCommDevice,
IO_REFERENCE_EVENT,
======> NULL, 0, <======= // no input buffer.
NULL, 0,
&BytesReturned,
NULL );

=================================================================================

Now also my breakpoint in the IRP_MJ_DEVICE_CONTROL Dispatch function
has not been hit.

*****
I suspect that the I/O Manager determined that since there were no buffers
there is no need to pass this on. Seems odd, but it might account for it.
Fixing the program to pass the right information would make more sense,
and rewriting the driver to not need an event handle and work like a real
Windows driver would make even more sense.
*****

Now the last error code is 3758555139.

****
Note that you need to display this in hex as well. It is 0xE0070003.
THAT value has meaning! It suggests a user-defined error code (bit 29 is

  1. and after that you have to figure out why your driver returned this
    code.
    ****

Unfortunately this is not a valid system error code. Because it is
outside the defined range of system error codes ( 0 … 15999 ).

****
If you had displayed it in hex, its meaning would have been obvious. It
is a user-defined error code.
****

So this system error code does not give me a hint on what might
be the reason for the occured error.

=====>

  1. Does somebody know the reason for the described errors?
    ****
    Well, we could start with the design, which is totally weird, and go to
    the idea that you are calling the API incorrectly, are using casts
    incorrectly, and are failing to recognize that GetLastError has meaning
    ONLY iff the last API failed.
    ****

  2. Can somebody tell me how to pass the event handle to my driver?
    ****
    Rewrite your driver so it doesn’t use one. Or, if you have to use such a
    bizarre design, pass the address of the buffer that holds the handle, and
    pass it correctly.
    ****

  3. Or can somebody tell me an URL to a code snippet with the correct
    values
    for CreateFile & DeviceIoControl to past down a handle into a driver.

****
I find the whole concept suspicious. You are trying to emulate some weird
historicall driver model from some other OS and have written something
that is well outside normal Windows driver behavior. Since Windows
already HAS a means of signalling an event (asynchronous I/O), why are you
creating a whole duplicate of this existing mechanism?
****


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

Thanks for those fast and helpful answers.

I have further questions:


Correct path in:

CreateFile( L"\\?\USB#VID_0908&PID_0001&MI_01#6&3221311a&0&0001#{7972cac1-2741-11d3-a46c-0 0a0cc3bc015}", 0, …

1.a.
How should the path above look like, so that it also will work for the same driver but also on another computer?

1.a.a.
Can I find the correct path that also works on other computers, in the installation inf-file of the driver? - Or how / where can I find this correct path?

1.b. Where is a good & SHORT & usefull description (URL), who such a path can be build ( what must it contain & syntax )


Ok I past now the pointer of the handle. Look here:

BOOL SUCCEDED = DeviceIoControl( hCommDevice,
IO_REFERENCE_EVENT,
(LPVOID) & ghCommEvent, sizeof (HANDLE),

But the result is the same. DeviceIoControl fails and the last error code is still the same “customer-defined” error code 0xE0070003 ( 3758555139 ).

Also the breakpoint, which I placed in my IRP_MJ_DEVICE_CONTROL Dispatch function, has not been hit.

Does somebody know the meaning of that “customer-defined” error?

What must be fixed?

And how the event handle can be past properly to my driver?

Thanks in advance for your hints

Is this the same driver as your kbdclass filter? The name you pass to CreateFile is opaque, you never build it. that string is based on the device interface GUID your driver enables and in user mode, that your app enumerates instances of that guid. It boils down to the following calls

SetupDiGetClassDevs
SetupDiEnumDeviceInterfaces in a loop untile ERROR_NO_MORE_ITEMS is returned
For each instance found, call SetupDiGetDeviceInterfaceDetail once to get the size of the buffer, alloc, call SetupDiGetDeviceInterfaceDetail again with the right buffer size

WinDDK\7600.16385.1\src\general\toaster\exe\enum shows all of this, but not the loop (it just uses the first instance, not very robust but it serves its purpose)

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@live.com
Sent: Monday, September 26, 2011 9:33 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] howto pass a handle to a driver

Thanks for those fast and helpful answers.

I have further questions:


Correct path in:

CreateFile( L"\\?\USB#VID_0908&PID_0001&MI_01#6&3221311a&0&0001#{7972cac1-2741-11d3-a46c-0 0a0cc3bc015}", 0, …

1.a.
How should the path above look like, so that it also will work for the same driver but also on another computer?

1.a.a.
Can I find the correct path that also works on other computers, in the installation inf-file of the driver? - Or how / where can I find this correct path?

1.b. Where is a good & SHORT & usefull description (URL), who such a path can be build ( what must it contain & syntax )


Ok I past now the pointer of the handle. Look here:

BOOL SUCCEDED = DeviceIoControl( hCommDevice,
IO_REFERENCE_EVENT,
(LPVOID) & ghCommEvent, sizeof (HANDLE),

But the result is the same. DeviceIoControl fails and the last error code is still the same “customer-defined” error code 0xE0070003 ( 3758555139 ).

Also the breakpoint, which I placed in my IRP_MJ_DEVICE_CONTROL Dispatch function, has not been hit.

Does somebody know the meaning of that “customer-defined” error?

What must be fixed?

And how the event handle can be past properly to my driver?

Thanks in advance for your hints


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

> 1.b. Where is a good & SHORT & usefull description (URL), who such a path can be build

SetupDiGetDeviceInterfaceDetail

The syntax is not documented and you cannot rely on it. Just use the name given by the above call.


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

xxxxx@live.com wrote:

I have further questions:


Correct path in:

CreateFile( L"\\?\USB#VID_0908&PID_0001&MI_01#6&3221311a&0&0001#{7972cac1-2741-11d3-a46c-0 0a0cc3bc015}", 0, …

1.a.
How should the path above look like, so that it also will work for the same driver but also on another computer?
1.a.a.
Can I find the correct path that also works on other computers, in the installation inf-file of the driver? - Or how / where can I find this correct path?
1.b. Where is a good & SHORT & usefull description (URL), who such a path can be build ( what must it contain & syntax )

Maxim and Doron have already replied, but I want to add my two cents as
well.

You cannot construct a path like that. You do not have enough
information. What you need to do is use the Device Manager APIs
(SetupDiXxxx) to scan through the list of devices, find yours, and ask
it to give you the path. These APIs are a bit tedious, but they work
everywhere.

The process you need is exactly the same as the process for opening a
WinUSB device, and there are examples for that. You have a device
interface GUID, and you want the path of the first driver that exposes
that GUID. So, the example here can help you:
http://msdn.microsoft.com/en-us/library/windows/hardware/ff540174.aspx

Note the GetDeviceHandle function part way down. Remember that I told
you it was verbose. The basic philosophy is that use use
SetupDiGetClassDevs to fetch a “device info set”, which contains all of
the devices that implement your interface. Then, you use
SetupDiEnumDeviceInfo to loop through that set (even if there is only
one). Then you use SetupDiEnumDeviceInterfaces to loop through the
interfaces exposed by each device, then you use
SetupDiGetDeviceInterfaceDetail to fetch the path you must pass to
CreateFile.


Ok I past now the pointer of the handle. Look here:

BOOL SUCCEDED = DeviceIoControl( hCommDevice,
IO_REFERENCE_EVENT,
(LPVOID) & ghCommEvent, sizeof (HANDLE),

But the result is the same. DeviceIoControl fails and the last error code is still the same “customer-defined” error code 0xE0070003 ( 3758555139 ).

Also the breakpoint, which I placed in my IRP_MJ_DEVICE_CONTROL Dispatch function, has not been hit.

Does somebody know the meaning of that “customer-defined” error?

No one knows this. It’s coming from your device, right?


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