使用线程时的Windows WriteFile问题

发布于 2024-12-02 06:40:48 字数 1308 浏览 4 评论 0原文

我的公司正在开发一种需要与软件通信的硬件。为此,我们制作了一个驱动程序,可以对硬件进行写入和读取。要访问驱动程序,我们使用以下命令:

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

使用以下函数完成读取和写入:

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

最后

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

,CloseHandle(device) 来关闭文件。

在从主线程调用函数的情况下,这工作得很好。如果从其他线程调用它们,当尝试写入多个元素时,我们会收到错误 998 (no_access)。这些线程是使用

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

我在这里没有想法创建的,有什么建议吗?

编辑: 运行以下序列时:

Main_thread:
CreateFile
Write
Close
CreateThread
WaitForThread

Thread_B:
CreateFile
Write
Close

Main_Thread 成功而 Thread_B 未成功。但是,当写入少量数据时,这种方法效果很好。这可能是因为Thread_B没有继承Main_Thread的所有访问权限吗?

编辑2: 这里有很多好的想法,非常感谢!在解决这个问题之后,情况似乎如下:

API 包含一个队列线程,处理进出设备的所有包。该线程处理指向包对象的指针。当指针到达队列的前端时,调用“send_and_get”函数。如果包中的数组分配在调用“send_and_get”函数的同一线程中,则一切正常。如果数组在其他线程中分配,则发送失败。但如何解决这个问题,我不知道。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

败给现实 2024-12-09 06:40:48

根据 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

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

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

-斯科特

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

夏尔 2024-12-09 06:40:48

对我来说仍然听起来像是并发访问。
写入此设备的单独线程需要使用互斥体或类似工具来正确保护对文件的访问。要么在主线程中打开句柄并使其保持打开状态,要么保护整个 Open ->写->每个线程中可能发生的关闭序列(使用互斥锁)。

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).

撧情箌佬 2024-12-09 06:40:48

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

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

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.

单调的奢华 2024-12-09 06:40:48

您应该检查的第一件事是,即使在请求到达您的驱动程序之前,您的驱动程序或内核模式 I/O 管理器(负责启动 IRP 并调用您的驱动程序)是否报告了错误 (998)。您应该能够发现这一点,因为这是您的驱动程序。只需记录对驱动程序 Dispatch 例程的调用、它返回的内容、它执行的操作(它是否调用其他驱动程序或使用错误代码等调用 IoCompleteRequest),事情就会变得清晰。

从您描述的情况来看,该错误很可能是由您的驱动程序引起的。例如,您的驱动程序可能会在对CreateFile(驱动程序的IRP_MJ_CREATE)的响应上分配一些全局状态结构,并在文件创建时清除它。已关闭。如果同时打开两个文件,然后关闭一个文件,而第二个文件仍接收 I/O 请求,则此类驱动程序将无法正常工作。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文