开发者

Windows WriteFile problem when using threads

My company is developing a hardware that needs to communicate with software. To do this, we have made a driver that enables writing to and reading from the hardware. To access the driver, we use the command:

HANDLE device = CreateFile(DEVICE_NAME,
                                GENERIC_READ | GENERIC_WRITE,
                                0x00000007,
                                &sec,
                                OPEN_EXISTING,
                                0,
                                NULL);

Reading and writing is done using the functions:

WriteFile(device,&package,package.datasize,&bytesWritten,NULL);

and

ReadFile(device,returndata,returndatasize,&bytesRead,NULL);

And finally, CloseHandle(device), to close the file.

This works just fine in the case where the functions are called from the main thread. If they are called from some other thread, we get error 998 (no_acccess) when trying to Write more than a couple of elements. The threads are created using

CreateThread(NULL, 0, thread_func, NULL, 0, &thread_id);

I'm running out of ideas here, any suggestions?

edit: When running the following sequence:

Main_thread:
CreateFile
Write
Close
CreateThread
WaitForThread

Thread_B:
CreateFile
Write
Close

Main_Thread succeeds and Thread_B does not. However, when writing small sets of data, this works fine. May this be because Thread_B does not inherit all of Main_Thread's access privileges?

edit2: a lot of good thinking going on here, much appreciated! After some work on this problem, the following seems to be the case:

The api contains a Queue-thread, handling all packages going to and from the device. This thread handles pointers to package-objects. When a pointer reaches the front of the queue, a "send_and_get" function is called. If the arrays in the package is allocated in the same thread that calls the "send_and_get" function, everything works fine. If the arrays are allocated in some other thread, sending fails. How to fix this, th开发者_Go百科ough, I don't know.


According to winerror, Win32 error 998 is one of the following native status values (which would be returned by the O/S or the driver):

   998 ERROR_NOACCESS <--> 0x80000002 STATUS_DATATYPE_MISALIGNMENT
   998 ERROR_NOACCESS <--> 0xc0000005 STATUS_ACCESS_VIOLATION
   998 ERROR_NOACCESS <--> 0xc00002c5 STATUS_DATATYPE_MISALIGNMENT_ERROR

Access violation might be a likely candidate based on you saying, "when trying to Write more than a couple of elements." Are you sure the buffer that you're sending is large enough?

The alignment errors are fairly exotic, but might be relevant if the device has some alignment requirements and the developer chose to use these particular errors.

-scott


Still sounds to me like it's concurrent access. Your separate threads writing to this device will need to properly protect access to the file using a mutex or similar. Either open the handle in the main thread and leave it open or protect the whole Open -> Write -> Close sequence that can occur in each thread (with a mutex).


As a debugging measure, since it's your own driver, you could get the driver to log the requests it is receiving, e.g., into the event log. Set up two test runs which are identical except that one runs all the code in the main thread and the other runs all the code in a second thread. Comparing the results should give you a better insight into what is happening.

It would also be a good idea to get your driver to report any error codes that it is returning to the operating system.


First thing that you should check is if the error (998) reported by your driver or by the kernel-mode I/O manager (which is responsible to initiate the IRP and call your driver) even before the request reaches your driver. You should be able to discover this since this is your driver. Just log the calls to the driver's Dispatch routine, what it returns, what it does (does it call other drivers or calls IoCompleteRequest with an error code or etc.) and things should become clear.

From the scenario that you describe it seems that most likely the error is caused by your driver. For instance, your driver may allocate some global state structure on a response to CreateFile (which is driver's IRP_MJ_CREATE), and purge it when the file is closed. Such a driver won't function correctly if simultaneously two files are opened, then one is closed whereas the second still receives I/O requests.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜