Inicializando um objeto device
Depois que IoCreateDevice retornar, dando ao chamador um ponteiro para um DeviceObject que contém um ponteiro para a extensão do dispositivo, os drivers devem configurar determinados campos nos objetos do dispositivo para seus respectivos dispositivos físicos, lógicos e/ou virtuais.
IoCreateDevice define o campo StackSize de um objeto de dispositivo recém-criado como um. Um driver de nível mais baixo pode ignorar esse campo. Quando um driver de nível superior chama IoAttachDeviceToDeviceStack para se anexar ao driver inferior seguinte, essa rotina define automaticamente o campo StackSize no objeto do dispositivo como o do objeto de dispositivo do driver mais um. No entanto, para alguns tipos de dispositivo, o driver de nível superior pode precisar definir o campo StackSize como um valor maior, conforme observado na documentação específica do dispositivo. Definir o tamanho da pilha garante que os IRPs enviados para o driver de nível superior contenham um local de pilha de E/S específico do driver, além do número correto de locais de pilha de E/S para todos os drivers de nível inferior na cadeia.
IoCreateDevice define o campo AlignmentRequirement de um objeto de dispositivo recém-criado para o tamanho da linha de cache de dados do processador menos um, para garantir que os buffers usados na E/S direta estejam alinhados corretamente. Depois que IoCreateDevice retornar, os drivers de dispositivo físico de nível mais baixo devem fazer o seguinte:
Subtraia um do requisito de alinhamento do dispositivo.
Compare o resultado da etapa 1 com o valor atual do AlignmentRequirement do objeto do dispositivo.
Se o requisito de alinhamento do dispositivo for maior, defina AlignmentRequirement como o resultado da etapa 1. Caso contrário, deixe o valor AlignmentRequirement conforme definido por IoCreateDevice.
Depois que qualquer driver de nível superior se encadeia por outro driver chamando IoGetDeviceObjectPointer, o driver de nível superior deve definir o campo AlignmentRequirement de seu objeto de dispositivo recém-criado como o do objeto de dispositivo do próximo driver de nível inferior. Como regra geral, um driver de nível superior não deve alterar esse valor. Se um driver de nível superior chamar IoAttachDevice ou IoAttachDeviceToDeviceStack, essas rotinas definirão automaticamente o campo AlignmentRequirement no objeto do dispositivo como o do objeto de dispositivo do driver de nível inferior.
IoGetDeviceObjectPointer retorna ponteiros para o objeto de dispositivo do driver de nível inferior e para o objeto de arquivo associado. Somente um FSD (ou, possivelmente, outro driver de nível mais alto) pode usar o ponteiro de objeto de arquivo retornado. Um driver intermediário que chama IoGetDeviceObjectPointer deve salvar esse ponteiro de objeto de arquivo para que ele possa ser desreferenciado chamando ObDereferenceObject quando o driver for descarregado.
Depois que um FSD monta o volume que contém o objeto de arquivo que representa um objeto de dispositivo de um driver inferior, um driver intermediário não pode se encadear entre o sistema de arquivos e o driver inferior chamando IoAttachDevice ou IoAttachDeviceToDeviceStack. Além disso, um FSD pode definir o membro SectorSize do objeto de dispositivo com base na geometria do hardware de volume subjacente quando ocorre uma montagem. Para obter mais informações, consulte DEVICE_OBJECT.
Um driver intermediário ou de nível mais baixo também define um bit em Flags do objeto de dispositivo por ORing com DO_DIRECT_IO ou com DO_BUFFERED_IO em cada objeto de dispositivo que ele cria. Drivers de nível mais alto de dispositivos lógicos ou virtuais podem evitar a configuração de Sinalizadores para E/S em buffer ou direta se o gravador de driver decidir que o trabalho adicional envolvido compensará o melhor desempenho do driver. Um driver intermediário deve configurar o campo Sinalizadores de seu objeto de dispositivo para corresponder ao do objeto de dispositivo do driver inferior.
Configurar um campo Sinalizadores de objeto de dispositivo com DO_DIRECT_IO ou DO_BUFFERED_IO determina como o gerenciador de E/S passa o acesso a buffers de usuário em todas as solicitações de transferência de dados enviadas posteriormente ao driver.
Em seguida, o driver pode definir quaisquer outros valores dependentes do dispositivo no objeto do dispositivo. Por exemplo, drivers não WDM para dispositivos de mídia removível devem ou o membro Flags do objeto de dispositivo com DO_VERIFY_VOLUME se detectarem (ou suspeitarem) uma alteração na mídia durante as operações de E/S. (Consulte Suporte a mídia removível para obter mais informações.) Drivers de dispositivos que exigem energia inrush devem ou o membro Flags com DO_POWER_INRUSH e drivers de dispositivos que não estão no caminho de paginação do sistema devem OU o membro Flags com DO_POWER_PAGABLE. Os drivers de função e filtro devem limpar o sinalizador de DO_DEVICE_INITIALIZING.
Depois de inicializar o objeto de dispositivo, um driver também pode inicializar quaisquer objetos definidos pelo Kernel e outras estruturas de dados definidas pelo sistema para as quais ele forneceu armazenamento na extensão do dispositivo. Precisamente quando um driver executa essas tarefas depende de seu dispositivo, do tipo do objeto e/ou da natureza dos dados. Em geral, todos os objetos ou estruturas de dados que podem persistir por meio de solicitações de início e parada PnP podem ser inicializados na rotina AddDevice . Aqueles que exigem informações de recurso fornecidas com uma solicitação de IRP_MN_START_DEVICE PnP ou que podem exigir alterações quando o dispositivo é interrompido e/ou reiniciado, devem ser inicializados quando o driver lida com a solicitação de IRP_MN_START_DEVICE . Para obter mais informações sobre rotinas AddDevice , consulte Escrevendo uma rotina AddDevice.