Question

J'ai une application Windows qui doit fonctionner comme 32 bits (en raison d'autres limitations hors de mon contrôle). Cependant, mon application doit appeler et accéder à un conducteur qui peut être 32 bits ou 64 bits en fonction du système dans lequel il est installé.

J'accéder au pilote au moyen d'appels DeviceIoControl (), l'échange de structures de données déclarées dans un fichier d'inclusion. Les structures de données contient les champs déclarés comme « DWORD_PTR » (le fichier include je ne contrôlais pas non plus).

Mon problème est que sur un système 64 bits, le pilote attend des structures pour contenir entier de 64 bits (à cause de déclaration DWORD_PTR). Cependant, mon programme 32 bits voit les DWORD_PTR comme des entiers de 32 bits. J'ai alors un décalage de données entre ma version du programme des structures de données et la compréhension du conducteur de ces structures.

DeviceIoControl () se termine-up échoue avec ERROR_INSUFFICIENT_BUFFER (La zone de données passée à un appel système est trop petit). Je confirme que je ne comprends pas cette erreur si je passe une version 64 bits du struct au conducteur.

J'ai quelques options laid sur ce gâchis. Mais je me demande si quelqu'un a des suggestions plus agréables?


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)
  • utiliser la version 32 bits ou 64 bits des structures de DeviceIoControl () appelle.

Désavantages:

  • I doivent maintenir une copie explicite 64 bits de la déclaration de structures manuellement. Il peut être une douleur au fil du 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).

Edit: Ceci est un pilote Microsoft et il semble qu'il n'utilise pas IoIs32bitsProcess (IRP)

Était-ce utile?

La solution

maintenir à la fois la version de 32 bits et 64 bits de structures et de mettre en œuvre un traitement spécial par l'intermédiaire de la fonction IoIs32BitProcess(irp) en pilote de périphérique gestionnaire d'DEVICE_CONTROL et de le convertir à la structure de 64 bits chaque fois que nécessaire. Ceci est la façon courante de le faire.

Voici un bonne quantité de documentation à ce sujet sur MSDN.

Puisque vous avez mentionné plus tard, vous ne pouvez pas contrôler le code source du pilote, je vous suggère de maintenir votre propre variante 32 bits sur 64 bits et d'envoyer le bon de vérifier l'architecture du système d'exploitation. On dirait que les déclarations de structure ne sont pas faites correctement pour le conducteur.

Autres conseils

Y at-il un moyen de manipuler un #define en incluant l'en-tête avec la structure defs de telle sorte que vous utilisez toujours la définition 64 bits? Cela semble être la meilleure option pour moi (si possible c'est).

Sinon, j'ombre la structure 64 bits dans mon propre code - de cette façon il n'y a qu'un def strucuture à surveiller, au lieu d'un tas de trucs if32bit / if64bit parsèment - qui semble plus bug sujets. 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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top