Por que a conversão é necessária

Os drivers no modo kernel devem validar o tamanho de qualquer buffer de E/S passado de um aplicativo no modo de usuário. Se um aplicativo de 32 bits passar um buffer contendo tipos de dados de precisão de ponteiro para um driver de 64 bits e nenhuma conversão ocorrer, o driver esperará que o buffer seja maior do que realmente é. Isso ocorre porque a precisão do ponteiro é de 32 bits no Microsoft Windows de 32 bits e 64 bits no Windows de 64 bits. Por exemplo, considere a seguinte definição de estrutura:

typedef struct _DRIVER_DATA
{
    HANDLE           Event;
    UNICODE_STRING   ObjectName;
} DRIVER_DATA;

No Windows de 32 bits, o tamanho da estrutura de DRIVER_DATA é de 12 bytes. Esta tabela mostra os tamanhos dos membros Event e ObjectName da estrutura DRIVER_DATA:

Evento ObjectName (comprimento USHORT) ObjectName (comprimento máximo do USHORT) ObjectName (Buffer PWSTR)
32 bits 16 bits 16 bits 32 bits
(4 bytes) (2 bytes) (2 bytes) (4 bytes)

No Windows de 64 bits, o tamanho da estrutura DRIVER_DATA é de 24 bytes. (Os 4 bytes de preenchimento de estrutura são necessários para que o membro buffer possa ser alinhado em um limite de 8 bytes.)

Evento ObjectName (comprimento USHORT) ObjectName (comprimento máximo do USHORT) Vazio (Preenchimento de Estrutura) ObjectName (Buffer PWSTR)
64 bits 16 bits 16 bits 32 bits 64 bits
(8 bytes) (2 bytes) (2 bytes) (4 bytes) (8 bytes)

Se um driver de 64 bits receber 12 bytes de DRIVER_DATA quando esperava 24 bytes, a validação de tamanho falhará. Para evitar isso, o driver deve detectar se uma estrutura de DRIVER_DATA foi enviada por um aplicativo de 32 bits e, nesse caso, conversá-la adequadamente antes de executar a validação.

Por exemplo, uma versão com conversão da estrutura de DRIVER_DATA acima pode ser definida da seguinte maneira:

typedef struct _DRIVER_DATA32
{
    VOID *POINTER_32   Event;
    UNICODE_STRING32   ObjectName;
} DRIVER_DATA32;

Como ele contém apenas tipos de dados de precisão fixa, essa nova estrutura tem o mesmo tamanho no Windows de 32 bits e no Windows de 64 bits.

Evento ObjectName (comprimento USHORT) ObjectName (comprimento máximo do USHORT) ULONG Buffer
32 bits 16 bits 16 bits 32 bits
(4 bytes) (2 bytes) (2 bytes) (4 bytes)