从32位应用程序使用64位驱动程序

3
我有一个Windows应用程序必须以32位运行(因为其他限制不在我的控制范围内)。然而,我的应用程序需要调用和访问驱动程序,该驱动程序可能是32位或64位,这取决于安装它的系统。
我通过DeviceIoControl()调用访问驱动程序,交换在包含文件中声明的数据结构。数据结构包含声明为"DWORD_PTR"的字段(我也无法控制包含文件)。
我的问题是,在64位系统上,驱动程序希望这些结构包含64位整数(因为DWORD_PTR声明)。但是,我的32位程序将这些DWORD_PTR视为32位整数。然后,我的程序版本的数据结构与驱动程序对这些结构的理解存在数据不匹配。
DeviceIoControl()最终失败,并显示ERROR_INSUFFICIENT_BUFFER(传递给系统调用的数据区域太小)。我确认如果我向驱动程序传递一个64位版本的结构体,则不会出现此错误。
我有一些丑陋的选项可供选择。但是我想知道是否有更好的建议?
解决方案:
1.使用真实的64位数据字段(__int64)声明共享结构的新副本。 2.动态检查操作系统架构(32/64)。 3.为DeviceIoControl()调用使用32位或64位版本的结构。
缺点:
1.我必须手动维护显式的64位结构定义副本。随着时间的推移可能会很痛苦。
我的其他解决方案是这个的变化,但它们始终涉及维护某些结构定义的副本(例如在COM服务器选项的IDL中)。
编辑:这是一个Microsoft驱动程序,似乎它不使用IoIs32bitsProcess(irp)!
2个回答

5
你需要同时维护32位和64位版本的结构,并通过IoIs32BitProcess(irp)函数在设备驱动程序DEVICE_CONTROL处理程序中实现特殊处理,必要时将其转换为64位结构。这是常见的做法。
这里有一个MSDN上关于此的大量文档。 由于你后来提到你无法控制驱动程序源代码,我建议你为64位上的32位维护自己的变体,并检查操作系统架构以发送正确的变体。看起来结构声明没有正确完成驱动程序。

我无法控制驱动程序。IoIs32BitProcess() 是从驱动程序中调用的,而不是我的应用程序。显然它没有成功,因为我收到了错误代码 ERROR_INSUFFICIENT_BUFFER(传递给系统调用的数据区域太小)。 - Philibert Perusse
如果您无法控制驱动程序源代码,那么您基本上需要访问驱动程序提供的结构声明。如果它们没有提供任何内容,则需要尝试使用32位和64位结构进行实验。 - Sedat Kapanoglu
他们确实提供结构声明。但是他们将字段声明为DWORD_PTR。所以我基本上被困在了我的丑陋解决方案中。它可以工作,我测试过了,但我希望有更简洁的解决方案。 - Philibert Perusse
显然,他们没有以正确的方式提供结构。我想不出一个干净的解决方案来弥补脏实现 :) - Sedat Kapanoglu
最好考虑向开发驱动程序的团队提交一个错误报告。 - Sedat Kapanoglu

0

有没有一种方法可以在包含具有结构定义的头文件时操纵#define,以便始终使用64位定义?如果可能的话,这似乎是最好的选择。

如果不行,我会在自己的代码中隐藏64位结构 - 这样只需要关注一个结构定义,而不是到处都是if32bit/if64bit的东西 - 这似乎更容易出bug。也许你可以做类似这样的事情:

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

在您的应用程序开始时,如果您有更新的标头,则应用程序的第一次运行将提醒您需要同步。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接