2017-02-13 2 views
1

У меня есть программа на C++, которая скомпилирована для x86 (32 бит). Он вызывает драйвер режима ядра. Драйвер скомпилирован для того, чтобы размер слова операционной системы был запущен. Целевые операционные системы могут быть 32 или 64 бит (в моем случае окна).Как определить длину слова операционной системы во время выполнения на C++?

Моя проблема заключается в определении размера указателя, возвращаемого драйвером, поскольку это необходимо вызову ОС.

Следующий вызов программы пользовательского режим работал, если система имела размер слова 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), поскольку они будут рассматривать программу пользовательского режима, а не компиляцию драйвера, в зависимости от.

Возможно, было бы достаточно установить DeviceIoControlnInBufferSize просто наивысшим ожидаемым размером слова, но есть ли более приятное решение?

+0

проверили ли вы, если это на самом деле проблема? Обычно ОС являются умными и не требуют огромного количества кодовых табличек кодов для использования указателя и просто дают вам действительный 32-разрядный указатель, если вы являетесь 32-битной программой и действительным 64-разрядным указателем, если вы 64-битная программа. – nwp

+1

Используйте 64-разрядную версию вашей программы в 64-разрядной системе. Это своего рода дефолт. Используйте 32-разрядную версию вашей программы в 32-разрядной системе. Сейчас они редки. –

+1

Что вы подразумеваете под «32-битным компилятором»? Компилятор - это исполняемый файл, который создает исполняемые файлы.Поскольку исполняемые файлы Windows могут быть 32 и 64 битами, существует 4 теоретических комбинации, и только 64-битный компилятор, производящий 64-битные исполняемые файлы, недвусмысленно _not_ «32-битный компилятор». – MSalters

ответ

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 байта), а длина указателя, который составляет 4 байта для 32-битного кода и 8 байт для 64-битных кода. драйверы всегда должны быть «родными», поэтому только 64-битные драйверы могут запускаться в 64-битных окнах, когда приложения пользовательского режима могут быть 32 или 64 бит. для определения его во время выполнения - используйте IsWow64Process. некоторые драйверы допускают только 64-битные структуры компоновки, некоторые могут определять 32-битный процесс по вызову IoIs32bitProcess и ждать 32-битных структур компоновки из 32-битного процесса. очевидно, ваш драйвер принимает только 64-битные структуры компоновки. так что вам нужно передать 8 или 4 байта, как размер входного сигнала, зависит от окон 64 или 32


Вероятно, было бы достаточно, чтобы установить DeviceIOControl в nInBufferSize просто до самого высокого ожидаемого размера слова, но есть лучше решение?

это не решение:

  • в 32 битной системе водитель может проверить, что InputBufferLength == sizeof(HANDLE) (и вернуть STATUS_INFO_LENGTH_MISMATCH если ложь) или что InputBufferLength >= sizeof(HANDLE)
  • в 64 битной системе, если вы просто сказать, что InputBufferLength == 8, но какие данные будут в 32 битных входных буфера? в своем коде вы инициализации только низкое 32bits по packageReceivedEvent = CreateEvent(NULL,FALSE, FALSE, NULL); - так что вам нужно выделить 8 байты буфера первым и правильно INIT это
+1

«Размер слова» относится к размеру * машинного слова *, а не к типу Windows 'WORD' typedef, а не синтаксису сборки Intel -w postfix или« word ptr »- все из которых являются 16-разрядными для обратной совместимости. Размер слова в большинстве современных процессоров Intel 64-бит. – conio

+0

@conio - в этом случае я думаю, что более правильно сказать о * регистровом размере * (вообще). из окна вид точно нужно сказать о * размере указателя * (который равен * размер регистра *) – RbMm

Смежные вопросы