Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/147.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在C+中确定运行时操作系统的字长+;? 我有一个C++程序,它是为x86(32位)编译的。它正在调用内核模式驱动程序。驱动程序是根据两个操作系统的字大小编译的。目标操作系统可能是32位或64位(在我的windows中)_C++_Winapi_Driver_Word Size - Fatal编程技术网

如何在C+中确定运行时操作系统的字长+;? 我有一个C++程序,它是为x86(32位)编译的。它正在调用内核模式驱动程序。驱动程序是根据两个操作系统的字大小编译的。目标操作系统可能是32位或64位(在我的windows中)

如何在C+中确定运行时操作系统的字长+;? 我有一个C++程序,它是为x86(32位)编译的。它正在调用内核模式驱动程序。驱动程序是根据两个操作系统的字大小编译的。目标操作系统可能是32位或64位(在我的windows中),c++,winapi,driver,word-size,C++,Winapi,Driver,Word Size,我的问题是确定驱动程序返回的指针的大小,因为操作系统调用需要它 如果系统的字长为32位,则用户模式程序的以下调用有效: HANDLE device = OpenDevice(); HANDLE packageReceivedEvent = CreateEvent(NULL, FALSE, FALSE, NULL); bool result = DeviceIoControl( device, IOCTL_CODE, &packageReceivedEvent, /

我的问题是确定驱动程序返回的指针的大小,因为操作系统调用需要它

如果系统的字长为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
设置为预期的最大字长就足够了,但是有更好的解决方案吗?

您需要这样的代码

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位窗口中运行。用于在运行时确定它-使用。有些驱动程序只接受64位布局结构,有些可以通过调用确定32位进程,并等待32位进程的32位布局结构。显然,您的驱动程序只接受64位布局结构。所以您需要传递8或4个字节作为输入大小,这取决于windows 64或32


也许设置DeviceIoControl的大小就足够了 简单到预期的最大字数,但是否有更好的 解决方案

这不是一个解决方案:

  • 在32位系统中,驱动程序可以检查
    InputBufferLength==
    sizeof(句柄)
    (如果为false,则返回
    状态\u信息\u长度\u不匹配)
    或者
    InputBufferLength>=sizeof(句柄)
  • 在64位系统中,如果您简单地说
    InputBufferLength==8
    ,但是 输入缓冲区的高32位将包含哪些数据?在您的代码中 通过packageReceivedEvent=CreateEvent(NULL、FALSE、FALSE、NULL)仅初始化低32位-所以你需要先分配8字节的缓冲区 纠正它

您是否检查过这是否确实是一个问题?通常操作系统是智能的,不需要大量的锅炉板代码来使用指针,如果您是32位程序,只需给您一个有效的32位指针,如果您是64位程序,只需给您一个有效的64位指针。在64位系统上使用64位版本的程序。这是一种默认。在32位系统上使用32位版本的程序。这些现在已经很少见了。你说的“32位编译器”是什么意思?编译器是产生可执行文件的可执行文件。由于Windows可执行文件可以是32位和64位,因此有4种理论组合,并且只有生成64位可执行文件的64位编译器才明确不是“32位编译器”。@nwp:指针将由操作系统正确翻译,但在此之前,驱动程序会抛出一个错误,因为它看到缓冲区太小,无法容纳其指针大小。@MSalters:你说得对。我指的是编译目标,而不是编译器本身。我对问题进行了相应的编辑。“单词大小”指的是机器单词的大小,而不是Windows
Word
typedef,也不是英特尔汇编语法-w后缀或“Word ptr”-所有这些都是16位的向后兼容性。大多数现代英特尔处理器中的字大小是64位。@conio-在这种情况下,我认为寄存器大小(常规)更为正确。从windows视图中,需要确切说明指针大小(等于寄存器大小)