2

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, though, I don't know.

4

4 回答 4

3

根据 winerror,Win32 错误 998 是以下本机状态值之一(将由操作系统或驱动程序返回):

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

根据您所说的“当尝试编写多个元素时”,访问冲突可能是一个可能的候选者。您确定要发送的缓冲区足够大吗?

对齐错误相当奇特,但如果设备有一些对齐要求并且开发人员选择使用这些特定错误,则可能是相关的。

-斯科特

于 2011-09-01T15:35:28.247 回答
2

在我看来,它仍然是并发访问。您写入此设备的单独线程将需要使用互斥锁或类似方法正确保护对文件的访问。要么在主线程中打开句柄并使其保持打开状态,要么保护每个线程中可能发生的整个 Open -> Write -> Close 序列(使用互斥锁)。

于 2011-09-01T15:49:53.913 回答
1

作为一种调试措施,因为它是您自己的驱动程序,您可以让驱动程序记录它正在接收的请求,例如,记录到事件日志中。设置两个相同的测试运行,除了一个运行主线程中的所有代码,另一个运行第二个线程中的所有代码。比较结果应该可以让您更好地了解正在发生的事情。

让您的驱动程序报告它返回给操作系统的任何错误代码也是一个好主意。

于 2011-09-03T23:25:02.487 回答
1

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.

于 2011-09-03T23:39:07.820 回答