Использование 64-битного драйвера из 32-битного приложения - PullRequest
3 голосов
/ 09 апреля 2009

У меня есть приложение для Windows, которое ДОЛЖНО работать как 32-разрядный (из-за других ограничений, которые я не контролирую). Однако мое приложение должно вызывать и обращаться к драйверу, который может быть 32-разрядным или 64-разрядным в зависимости от системы, в которой он установлен.

Я обращаюсь к драйверу через вызовы DeviceIoControl (), обмениваясь структурами данных, объявленными во включаемом файле. Структуры данных содержат поля, объявленные как «DWORD_PTR» (включаемый файл, который я тоже не контролирую).

Моя проблема в том, что в 64-битной системе драйвер ожидает, что структуры содержат 64-битное целое число (из-за объявления DWORD_PTR). Тем не менее, моя 32-битная программа видит эти DWORD_PTR как 32-битные целые числа. Затем у меня возникает несоответствие данных между моей программной версией структур данных и пониманием этих структур драйвером.

В результате DeviceIoControl () завершается с ошибкой ERROR_INSUFFICIENT_BUFFER (область данных, переданная системному вызову, слишком мала). Я подтвердил, что не получаю эту ошибку, если передаю 64-битную версию структур в драйвер.

У меня есть несколько ужасных вариантов из этого беспорядка. Но мне интересно, есть ли у кого-нибудь более приятные предложения?


Решение:

  • Объявить новую копию общих структур с РЕАЛЬНЫМИ 64-битными полями данных (__int64)
  • Динамическая проверка архитектуры ОС (32/64)
  • Используйте 32-битную или 64-битную версию структур для вызовов DeviceIoControl ().

Недостатки:

  • Я должен поддерживать явную 64-битную копию объявления структур вручную. Со временем это может быть болью.

Мои другие решения являются вариацией этого, но они ВСЕГДА включают поддержку некоторой копии определения структур (например, в опции IDL для COM-серверов).

Редактировать: Это драйвер Microsoft, и, похоже, он не использует IoIs32bitsProcess (irp)!

Ответы [ 2 ]

5 голосов
/ 09 апреля 2009

Вы поддерживаете как 32-битную, так и 64-битную версию структур и реализуете специальную обработку с помощью функции IoIs32BitProcess(irp) в обработчике драйвера устройства DEVICE_CONTROL и конвертируете ее в 64-битную структуру при необходимости. Это обычный способ сделать это.

Вот хорошее количество документации по MSDN.

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

0 голосов
/ 12 апреля 2009

Есть ли способ манипулировать #define при включении заголовка со структурными определениями, чтобы вы всегда использовали 64-битное определение? Мне кажется, это лучший вариант (если это возможно).

Если нет, то я бы затенял 64-битную структуру в своем собственном коде - таким образом, есть только одна структура, за которой стоит следить, а не куча вещей if32bit / if64bit, разбросанных повсюду - это кажется более подвержен ошибкам Возможно, вы могли бы сделать что-то вроде:

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

в начале вашего приложения, поэтому, если вы когда-нибудь получите новые заголовки, первый запуск вашего приложения будет напоминать вам о необходимости синхронизации.

...