Escritura de controladores de impresora de 64 bits
Importante
La plataforma de impresión moderna es el medio preferido de Windows para comunicarse con impresoras. Se recomienda usar el controlador de clase de bandeja de entrada IPP de Microsoft, junto con aplicaciones de soporte técnico de impresión (PSA), para personalizar la experiencia de impresión en Windows 10 y 11 para el desarrollo de dispositivos de impresora.
Para obtener más información, consulte Plataforma de impresión moderna y la Guía de diseño de aplicaciones para compatibilidad con impresión.
Si va a escribir un controlador de 64 bits o un controlador que se puede compilar para ejecutarse en sistemas de 32 y 64 bits, siga las directrices de portabilidad de 64 bits que se indican en Migración del controlador a Windows de 64 bits. En este tema se describen algunas de las limitaciones y problemas que podrían surgir al escribir un controlador de impresora de 64 bits.
Para obtener más información sobre el uso de representaciones para identificar la arquitectura de 64 bits, consulte los temas siguientes:
Limitaciones en los identificadores de contexto del dispositivo
Si una aplicación de 32 bits se ejecuta en una versión de 64 bits del sistema operativo Microsoft Windows, un complemento de controlador de impresora que se ejecuta en el contexto del proceso de aplicación de código thunk Splwow64.exe no debería llamar a la función CreateDC de GDI; esta llamada producirá un error.
Problemas con la escritura de controladores de 64 bits
En el código de controlador de 32 bits existente, tenga cuidado con las conversiones entre tipos de puntero y tipos enteros, como DWORD o ULONG. Si está familiarizado con la escritura de código para máquinas de 32 bits, puede que esté acostumbrado a asumir que un valor de puntero se ajusta a un DWORD o ULONG. Asumir esto para código de 64 bits es peligroso. Si convierte un puntero al tipo DWORD o ULONG, es posible que se trunque un puntero de 64 bits.
En su lugar, convierta el puntero al tipo DWORD_PTR o ULONG_PTR. Un entero sin signo de tipo DWORD_PTR o ULONG_PTR siempre es lo suficientemente grande como para almacenar todo el puntero, independientemente de si el código se compila para un equipo de 32 o 64 bits.
Por ejemplo, el campo de puntero pDrvOptItems.UserData de la estructura OEMCUIPPARAM es de tipo ULONG_PTR. En el ejemplo de código siguiente se muestra lo que no se debe hacer si se copia un valor de puntero de 64 bits en este campo.
PUSERDATA pData;
OEMCUIPPARAM->pDrvOptItems.UserData = (ULONG)pData; // Wrong
En el ejemplo de código anterior se convierte el puntero pData al tipo ULONG, que puede truncar el valor de puntero si sizeof(pData) >sizeof(ULONG). El enfoque correcto consiste en convertir el puntero a ULONG_PTR, como se muestra en el ejemplo de código siguiente.
PUSERDATA pData;
OEMCUIPPARAM->pDrvOptItems.UserData = (ULONG_PTR)pData; // Correct
En el ejemplo de código anterior se conservan todos los 64 bits del valor de puntero.
Las funciones de 64 bits insertadas, como PtrToUlong y UlongToPtr , convierten de forma segura entre tipos de puntero y entero sin depender de suposiciones sobre los tamaños relativos de estos tipos. Si un tipo es más corto que el otro, debe extenderse al convertir al tipo más largo. Si el tipo más corto se extiende rellenando con el bit de signo o con ceros, cada función Win64 puede controlar estas situaciones. Observe el siguiente ejemplo de código.
ULONG ulHWPhysAddr[NUM_PHYS_ADDRS];
ulSlotPhysAddr[0] = ULONG(pulPhysHWBuffer) + HW_BUFFER_SIZE; // wrong
Debe reemplazar el ejemplo de código anterior por el ejemplo de código siguiente.
ULONG_PTR ulHWPhysAddr[NUM_PHYS_ADDRS];
ulSlotPhysAddr[0] = PtrToUlong(pulPhysHWBuffer) + HW_BUFFER_SIZE; // correct
Se prefiere el segundo ejemplo de código aunque
ulSlotPhysAddr
puede representar el valor de un registro de hardware que solo tiene 32 bits de longitud en lugar de 64 bits de longitud. Para obtener una lista de todas las nuevas funciones auxiliares de Win64 para convertir entre tipos de puntero y entero, consulte Nuevos tipos de datos.