我有一个C ++程序,它是为x86(32位)编译的。它正在调用内核模式驱动程序。驱动程序是针对运行的OS的字大小进行编译的。目标操作系统可能是32位或64位(在我的情况下是Windows)。
我的问题是确定驱动程序返回的指针的大小,因为OS调用需要它。
如果系统的字大小为32位,则以下调用用户模式程序:
HANDLE device = OpenDevice();
HANDLE packageReceivedEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
bool result = DeviceIoControl(
device,
IOCTL_CODE,
&packageReceivedEvent, //for signaling
sizeof(HANDLE), //TODO does not work for 64 bit
nullptr,
0,
&recvBytes,
nullptr);
定义来自标准winbase.h和winnt.h。
我不能使用像sizeof(int)
那样的任何编译时解决方案,因为它们只会考虑用户模式程序,而不是它所依赖的驱动程序编译。
将DeviceIoControl
nInBufferSize
简单地设置为最高预期字数就足够了,但是有更好的解决方案吗?
答案 0 :(得分:1)
你需要像这样的代码
union {
__int64 v;
HANDLE packageReceivedEvent;
};
v = 0;
BOOL fOk = FALSE;
if (packageReceivedEvent = CreateEvent(NULL, FALSE, FALSE, NULL))
{
BOOL Wow64Process;
if (IsWow64Process(NtCurrentProcess(), &Wow64Process))
{
fOk = DeviceIoControl(
device,
IOCTL_CODE,
&packageReceivedEvent, //for signaling
Wow64Process ? 8 : 4,
nullptr,
0,
&recvBytes,
nullptr);
}
}
ULONG err = fOk ? NOERROR : GetLastError();
而不是"字长" (这总是2个字节)但是指针长度,对于32位代码是4个字节,对于64位代码是8个字节。司机总是必须是“本地人”。 - 因此当用户模式应用程序可以是32位或64位时,只有64位驱动程序可以在64位窗口中运行。在运行时确定它 - 使用IsWow64Process
。一些驱动程序只接受64位布局结构,有些可以通过调用IoIs32bitProcess
确定32位进程,并等待32位进程的32位布局结构。显然你的驱动程序只接受64位布局结构。所以你需要传递8或4个字节作为输入大小,取决于Windows 64或32
设置DeviceIoControl的nInBufferSize可能就足够了 只是达到最高的预期字数,但有更好的 解?
这不是解决方案:
InputBufferLength ==
sizeof(HANDLE)
(如果为false则返回STATUS_INFO_LENGTH_MISMATCH
)
或InputBufferLength >= sizeof(HANDLE)
InputBufferLength == 8
,则在64位系统中packageReceivedEvent = CreateEvent(NULL,FALSE, FALSE, NULL);
初始化仅低32位 - 所以你需要先分配8字节缓冲区
正确的初始化