Details of a "HANDLE"? Usage of a HANDLE?

I have a WDF driver which i can open via CreateFile and get a handle back.
Now i can send DeviceIoControl to my driver. So far so good, working.
My driver uses multiple instances to access multiple hardware devices via USB.

The CreateFile is done inside a DLL.
This DLL is used via multiple threads from one application or
from different application.

When i call CreateFile, i get a HANDLE back, which i print (for debugging) via “%d”
and it displays me, e.g. 4996.

I call DeviceIoControls with this handle also there i can see the same handle
and also again in CloseHandle.

Now i have certain rare cases (perhaps collision cases between the two devices),
where i send the DeviceIoControl, but get back a result of 0, meaning error.
Calling GetLastError i get error 6 which means ERROR_INVALID_HANDLE.
I printed the used HANDLE and it is still my 4996.
I have also a debug output at every position of CloseHandle
and when i have not overseen it, i think i have not called CloseHandle for this HANDLE.

I don’t understand yet why i get ERROR_INVALID_HANDLE.
Is there some way how i can debug this, e.g. display all opened handles,
not related to a EXE file, but in general?
Can checking if a HANDLE is valid only be done by comparing against
INVALID_HANDLE_VALUE, which is simply a certain value, but then
this is not the case, because i still see the 4996 as handle value.

I also though about tracing open / close of the driver,
is this the way to go?

In general:

When i call CreateFile in one thread, i am almost sure,
i can use it for all threads. Are there special cases i must pay attention to?

When i open a HANDLE for one application, can i use the same handle
also for a different application or must i get a new one?

Do you call CreateFile BEFORE you start those threads that could be using the handle?
Do you make sure other threads are NOT using the handle (preferably, they should exit) when you call CloseHandle?

xxxxx@clibb.de” wrote in message
news:xxxxx@ntdev:

>
> In general:
>
> When i call CreateFile in one thread, i am almost sure,
> i can use it for all threads. Are there special cases i must pay attention to?
>
> When i open a HANDLE for one application, can i use the same handle
> also for a different application or must i get a new one?

A handle is process wide, so yes it works for all threads in that
process, and no it does not work for a different process or application.

Don Burn
Windows Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr

If the variable holding the file handle doesn’t change, and you’re making all your calls from the same process, t’s probably nothing at all related to your handle.

Win32 error codes (ERROR_INVALID_HANDLE) are an imprecise translation of the native Windows internal status codes (such as STATUS_SUCCESS) that the driver actually returns.

The driver’s probably returning some very sensible error code that the developer wasn’t aware is translated to ERROR_INVALID_HANDLE. For example, the native Window status code STATUS_PORT_DISCONNECTED comes back to a Win32 app as ERROR_INVALID_HANDLE. Don’t ask why, it’s just how it is.

Do you have the source code for this driver? If so, some debugging is in order to find the origin of this error.

Peter
OSR

>

xxxxx@clibb.de” wrote in message
> news:xxxxx@ntdev:
>
>>
>> In general:
>>
>> When i call CreateFile in one thread, i am almost sure,
>> i can use it for all threads. Are there special cases i must pay
>> attention to?
>>
>> When i open a HANDLE for one application, can i use the same handle
>> also for a different application or must i get a new one?
>
> A handle is process wide, so yes it works for all threads in that
> process, and no it does not work for a different process or application.

A handle is looked up in a process-specific handle table. So the
numerical value has no meaning unless it is instantiated in the other
process’s handle table.

You can use DuplicateHandle and specify the other process as the target
process. What you will get in this case is a numeric value for the
HANDLE, which is NOT usable in the creating process but is usable by the
target process, and now the problem is how to communicate that HANDLE
value to the process in which it is now valid.

You can also do it via inheritance; this is a special case. An
inheritable handle is like any other handle, and has a numerical value.
When you create a child process and specify that inheritable handles
should be inherited (one of the parameters to CreateProcess), all the
inheritable handles are duplicated implicitly in the child process, and
they have the same numerical values in the child process as in the parent
process.

Note that to call DuplicateHandle, you must have a process handle for the
target process.

If you have not created the device as an exclusive device, you can also do
CreateFile in any process. However, now you have to think about whether
or not you have process-local state for that handle, and if so you have to
create the state description block in CreateFile and add it to the
FILE_OBJECT using the FsContext or FsContext2 fields. You have to delete
this block of memory on the IRP_MJ_CLEANUP operation.Be very careful to
consider your device behavior to consider what happens if two different
processes are free to modify the state.

Also note that DuplicateHandle creates a handle that references the same
FILE_OBJECT as the original process, so you can’t keep per-handle state in
this case.

Consider the SetFilePosition operation as the classical example used to
illustrate per-handle state.

Consider I do two CreateFile operations, and get handles h1 and h2. The
two threads then have the following temporal behavior

Thread1 Thread2
SetFilePosition(h1, 1000);
SetFilePosition(h2, 2000);
ReadFile(h1, …, 100, …); // read 100 bytes from the file
ReadFile(h2, …, 100, …);

In this case, the use of h1 and h2 are independent because the file
position is kept in the FsContext block for the file system. So the
ReadFile using h1 reads the bytes 1000…1099, and the Readfile using h2
reads the bytes 2000…2099.

But consider if h2 was created not by CreateFile, but by DuplicateHandle.
In this case, the ReadFile using h1 reads 2000…2099. And the ReadFile
using h2 reads bytes 2100…2199.

Inheritance creates a duplicate handle. And DuplicateHandle and
inheritance are free to create their handles even if you have marked the
device as “exclusive” when you created it. The “exclusive” simply means
you cannot do another CreateFile if there is already an unclosed handle to
the device. Duplication and inheritance are permitted.
joe

>
>
> Don Burn
> Windows Filesystem and Driver Consulting
> Website: http://www.windrvr.com
> Blog: http://msmvps.com/blogs/WinDrvr
>
>
>
>
> —
> 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
>