Développement de drivers d'imprimante 64 bits
Important
La plateforme d’impression moderne est le moyen privilégié de Windows pour communiquer avec les imprimantes. Nous vous recommandons d’utiliser le pilote de classe IPP en boîte de Microsoft, ainsi que les applications de support d’impression (PSA), pour personnaliser l’expérience d’impression dans Windows 10 et 11 pour le développement de périphériques d’impression.
Pour plus d’informations, veuillez consulter la section Plateforme d’impression moderne et le Guide de conception des applications de support d’impression.
Si vous écrivez un pilote 64 bits ou un pilote qui peut être compilé pour fonctionner sur des systèmes 32 bits et 64 bits, suivez les instructions de portage 64 bits dans Portage de votre pilote vers Windows 64 bits. Cette rubrique décrit certaines des limitations et certains des problèmes que vous pouvez rencontrer lors de l'écriture d'un pilote d'imprimante 64 bits.
Pour plus d'informations sur l'utilisation des décorations pour identifier l'architecture 64 bits, reportez-vous aux rubriques suivantes :
Limitations sur les poignées de contexte d'appareil.
Si une application 32 bits est exécutée sur une version 64 bits du système d'exploitation Microsoft Windows, un plug-in de pilote d'imprimante qui s'exécute dans le contexte du processus de démarrage Splwow64.exe ne doit pas appeler la fonction GDI CreateDC ; cet appel échouera.
Problèmes liés à l'écriture de pilotes 64 bits
Dans le code des pilotes 32 bits existants, faites attention aux conversions entre les types de pointeurs et les types d'entiers tels que DWORD ou ULONG. Si vous avez l'habitude d'écrire du code pour des machines 32 bits, vous pouvez supposer qu'une valeur de pointeur tient dans un DWORD ou un ULONG. Pour le code 64 bits, cette hypothèse est dangereuse. En effet, si vous faites passer un pointeur dans un type DWORD ou ULONG, un pointeur 64 bits risque d'être tronqué.
Au lieu de cela, cassez le pointeur dans le type DWORD_PTR ou ULONG_PTR. Un entier non signé de type DWORD_PTR ou ULONG_PTR est toujours suffisamment grand pour stocker l'intégralité du pointeur, que le code soit compilé pour un ordinateur 32 bits ou 64 bits.
Par exemple, le champ de pointeur pDrvOptItems.UserData de la structure OEMCUIPPARAM est de type ULONG_PTR. L'exemple de code suivant montre ce qu'il ne faut pas faire si vous copiez une valeur de pointeur de 64 bits dans ce champ.
PUSERDATA pData;
OEMCUIPPARAM->pDrvOptItems.UserData = (ULONG)pData; // Wrong
L'exemple de code précédent convertit le pointeur pData en type ULONG, ce qui peut tronquer la valeur du pointeur si sizeof(pData)> sizeof(ULONG). L'approche correcte consiste à convertir le pointeur en ULONG_PTR, comme le montre l'exemple de code suivant.
PUSERDATA pData;
OEMCUIPPARAM->pDrvOptItems.UserData = (ULONG_PTR)pData; // Correct
L'exemple de code précédent préserve les 64 bits de la valeur du pointeur.
Les fonctions 64 bits en ligne telles que PtrToUlong et UlongToPtr convertissent en toute sécurité les pointeurs et les entiers sans s'appuyer sur des hypothèses concernant la taille relative de ces types. Si un type est plus court que l'autre, il doit être étendu lors de la conversion vers le type plus long. Si le type le plus court est étendu en remplissant le bit de signe ou avec des zéros, chaque fonction Win64 peut gérer ces situations. Considérez l’exemple de code suivant.
ULONG ulHWPhysAddr[NUM_PHYS_ADDRS];
ulSlotPhysAddr[0] = ULONG(pulPhysHWBuffer) + HW_BUFFER_SIZE; // wrong
Vous devez remplacer l'exemple de code précédent par l'exemple de code suivant.
ULONG_PTR ulHWPhysAddr[NUM_PHYS_ADDRS];
ulSlotPhysAddr[0] = PtrToUlong(pulPhysHWBuffer) + HW_BUFFER_SIZE; // correct
Le deuxième exemple de code est préférable même si
ulSlotPhysAddr
peut représenter la valeur d'un registre matériel d'une longueur de 32 bits seulement plutôt que de 64 bits. Pour obtenir la liste de toutes les nouvelles fonctions d'aide Win64 permettant de convertir les types pointeur et entier, voir Nouveaux types de données.