3

我有一个必须以 32 位运行的 Windows 应用程序(因为我无法控制其他限制)。但是,我的应用程序必须调用和访问可能是 32 位或 64 位的驱动程序,具体取决于安装它的系统。

我通过 DeviceIoControl() 调用访问驱动程序,交换包含文件中声明的数据结构。数据结构包含声明为“DWORD_PTR”的字段(我也不控制的包含文件)。

我的问题是在 64 位系统上,驱动程序期望结构包含 64 位整数(因为 DWORD_PTR 声明)。但是,我的 32 位程序将那些 DWORD_PTR 视为 32 位整数。然后,我的数据结构的程序版本与驱动程序对这些结构的理解之间存在数据不匹配。

DeviceIoControl() 最终以 ERROR_INSUFFICIENT_BUFFER 失败(传递给系统调用的数据区域太小)。我确认如果我将 64 位版本的结构传递给驱动程序,我不会收到此错误。

从这个烂摊子中我有一些丑陋的选择。但我想知道是否有人有更好的建议?


解决方案:

  • 使用 REAL 64 位数据字段 (__int64) 声明共享结构的新副本
  • 动态检查操作系统架构 (32/64)
  • 对 DeviceIoControl() 调用使用 32 位或 64 位版本的结构。

缺点:

  • 我必须手动维护结构声明的显式 64 位副本。随着时间的推移,这可能会很痛苦。

我的其他解决方案是这个解决方案的变体,但它们总是涉及维护结构定义的一些副本(例如在用于 COM 服务器的 IDL 选项中)。

编辑:这是一个 Microsoft 驱动程序,它似乎不使用 IoIs32bitsProcess(irp)!

4

2 回答 2

5

您维护 32 位和 64 位版本的结构,并通过IoIs32BitProcess(irp)设备驱动DEVICE_CONTROL程序处理程序中的函数实现特殊处理,并在需要时将其转换为 64 位结构。这是常见的做法。

这是MSDN 上关于它的大量文档。

由于您后来提到您无法控制驱动程序源代码,因此我建议您在 64 位上维护自己的 32 位变体,并发送正确的变体来检查操作系统架构。看起来结构声明没有为驱动程序正确完成。

于 2009-04-09T03:22:14.843 回答
0

当包含带有结构 defs 的标头时,有没有办法操纵 #define 以便您始终使用 64 位定义?这对我来说似乎是最好的选择(如果可能的话)。

如果没有,我会在我自己的代码中隐藏 64 位结构——这样只有一个结构 def 需要注意,而不是一堆 if32bit/if64bit 的东西散布在各处——这似乎更容易出错。也许您可以执行以下操作:

_ASSERT(sizeof(myStruct) == sizeof(64bitStruct)) 

在您的应用程序开始时,因此如果您获得更新的标题,您的应用程序的第一次运行会提醒您需要同步。

于 2009-04-11T22:58:21.650 回答