如何在C ++中确定运行时操作系统的字长?

时间:2017-02-13 10:26:42

标签: c++ winapi driver word-size

我有一个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简单地设置为最高预期字数就足够了,但是有更好的解决方案吗?

1 个答案:

答案 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可能就足够了   只是达到最高的预期字数,但有更好的   解?

这不是解决方案:

    32位系统驱动程序中的
  • 可以检查InputBufferLength == sizeof(HANDLE)(如果为false则返回STATUS_INFO_LENGTH_MISMATCH) 或InputBufferLength >= sizeof(HANDLE)
  • 如果您只是说InputBufferLength == 8,则在64位系统中
  • ,但是 什么数据将在高32位输入缓冲区?在你的代码中 由packageReceivedEvent = CreateEvent(NULL,FALSE, FALSE, NULL);初始化仅低32位 - 所以你需要先分配8字节缓冲区 正确的初始化