2009-04-09 7 views
3

J'ai une application Windows qui doit être exécutée en 32 bits (en raison d'autres limitations hors de mon contrôle). Cependant, mon application doit appeler et accéder à un pilote qui peut être 32 bits ou 64 bits selon le système sur lequel il est installé.Utilisation d'un pilote 64 bits à partir d'une application 32 bits

J'accède au pilote via des appels DeviceIoControl(), en échangeant des structures de données déclarées dans un fichier include. Les structures de données contiennent des champs déclarés comme "DWORD_PTR" (le fichier d'inclusion que je ne contrôle pas non plus). Mon problème est que sur un système de 64 bits, le pilote s'attend à ce que les structures contiennent un entier de 64 bits (à cause de la déclaration DWORD_PTR). Cependant, mon programme 32 bits voit ces DWORD_PTR comme des entiers de 32 bits. J'ai alors une discordance de données entre ma version de programme des structures de données et la compréhension du conducteur de ces structures.

DeviceIoControl() échoue avec ERROR_INSUFFICIENT_BUFFER (La zone de données transmise à un appel système est trop petite). J'ai confirmé que je ne reçois pas cette erreur si je passe une version 64 bits des structures au pilote.

J'ai quelques options laids de ce gâchis. Mais je me demande si quelqu'un a de meilleures suggestions?


Solution:

  • déclarer une nouvelle copie des structures partagées avec de vrais champs de données 64-bits (__int64)
  • vérifier dynamiquement l'architecture du système d'exploitation (32/64)
  • Utilisation la version 32 bits ou 64 bits des structures pour les appels DeviceIoControl().

Inconvénients:

  • I doivent conserver une copie explicite 64 bits de la déclaration de structures manuellement. Cela peut être une douleur avec le temps.

Mes autres solutions sont la variation de celle-ci, mais ils toujours impliquent maintenant une copie de la définition des structures (par exemple dans un IDL pour les serveurs COM en option).

Modifier: Ceci est un pilote Microsoft et il semble qu'il n'utilise pas IoIs32bitsProcess (irp)!

Répondre

5

Vous gérez les versions 32 bits et 64 bits des structures et appliquez une gestion spéciale via la fonction IoIs32BitProcess(irp) dans le gestionnaire de périphérique DEVICE_CONTROL et convertissez-la en structure 64 bits chaque fois que nécessaire. C'est la manière commune de le faire.

Voici un good amount of documentation about it on MSDN.

Depuis plus tard mentionné que vous ne disposez pas de contrôle sur le code source du pilote, je vous suggère de maintenir votre propre variante 32 bits sur 64 bits et d'envoyer le bon contrôle de la Architecture OS Il semble que les déclarations de structure ne sont pas faites correctement pour le pilote.

+0

Je ne contrôle pas le pilote. IoIs32BitProcess() est appelé à partir du pilote, pas de mon application. Évidemment, non parce que j'obtiens des codes d'erreur ERROR_INSUFFICIENT_BUFFER (La zone de données passée à un appel système est trop petite.) –

+0

Oh si vous n'avez pas le contrôle sur le code source du pilote, vous devez avoir accès aux déclarations de structure pilote fournit. S'ils ne fournissent rien, vous devez expérimenter avec des structures 32 bits et 64 bits. –

+0

Ils fournissent des déclarations de structure. Mais ils déclarent les champs comme DWORD_PTR. Donc, je suis fondamentalement bloqué avec ma solution laide. Je travaille, je l'ai testé, mais j'espérais quelque chose de plus propre. –

0

Existe-t-il un moyen de manipuler un #define en incluant l'en-tête avec la structure defs de sorte que vous utilisez toujours la définition 64 bits? Cela semble être la meilleure option pour moi (si possible).Sinon, je ferais l'ombre à la structure 64 bits dans mon propre code - de cette façon, il n'y a qu'une structure à surveiller, plutôt qu'un tas de choses if32bit/if64bit saupoudré partout - qui semble plus sujettes aux bugs. Peut-être que vous pourriez faire quelque chose comme:

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

au début de votre application, donc si jamais vous-têtes plus récents, la première exécution de votre application vous rappellera que vous devez synchroniser.

Questions connexes