> 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
- 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.
=====>
-
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.
****
-
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.
****
-
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