Suporte a solicitações do Gerenciador de montagem em um driver de classe de armazenamento

O gerenciador de montagem fornecido pelo sistema é responsável por gerenciar nomes de volume. Para cada volume, ele armazena um nome que é exclusivo e permanentemente identificado com o volume, mesmo depois que o volume é removido do sistema. Ele também gerencia nomes menos permanentes, como letras de unidade, que persistem nas reinicializações, mas cujas atribuições podem mudar à medida que os volumes são adicionados ou removidos do sistema.

O gerenciador de montagem fornece uma interface exclusiva para cada volume no sistema, criando um link simbólico para o objeto de dispositivo do volume. Como os próprios links simbólicos e os objetos de dispositivo de destino não persistem quando o sistema é reiniciado, o gerenciador de montagem preserva o nome do link simbólico em um banco de dados de nomes persistente no Registro.

Esse nome de link simbólico é chamado de nome de volume exclusivo. Como um rótulo de volume tradicional, ele persiste quando o sistema é reiniciado. Como uma letra de unidade e ao contrário de um rótulo de volume, esse nome é exclusivo. Segue-se o formato para nomes de volume exclusivos, em que GUID é um identificador global exclusivo que identifica o volume.

"\?? \Volume{GUID}\

O banco de dados de nomes persistentes do gerenciador de montagem está localizado na chave do Registro MountedDevices do hive SYSTEM (HKLM/SYSTEM/MountedDevices) do registro. Além de nomes de volume exclusivos, o gerenciador de montagem também armazena nomes de pontos de montagem em seu banco de dados de nomes persistentes. Os nomes de ponto de montagem podem ser subdivididos em duas categorias: nomes de caminho no estilo Win32 que servem como o diretório raiz do sistema de arquivos do volume montado e letras de unidade.

Cada nome de link simbólico persistente no banco de dados aparece como o nome de um valor do Registro sob a chave MountedDevices acompanhada por uma ID exclusiva. O ID exclusivo é outro identificador exclusivo de um volume (diferente do nome do volume exclusivo). Ele ajuda a identificar quais dos nomes de links simbólicos persistentes potencialmente numerosos se referem ao mesmo volume.

Por exemplo, um único volume com um nome de volume exclusivo de **"\\?\Volume{**7603f260-142a-11d4-ac67-806d6172696f }\" pode ter uma letra de unidade "\DosDevices\D:" e dois pontos de montagem "\DosDevices\C:\mymount" e "\DosDevices\E:\FilesysD\mnt". Essa combinação produziria quatro entradas no banco de dados de nomes de link simbólico persistente do gerenciador de montagem: uma para o nome de volume exclusivo, uma para a letra da unidade e duas para os dois nomes de ponto de montagem. Todas as quatro entradas compartilhariam o mesmo ID exclusivo. Assim, alguém visualizando a chave do Registro MountedDevices seria capaz de detectar que todos os quatro nomes persistentes apontam para o mesmo volume.

A captura de tela a seguir ilustra como os nomes persistentes aparecem na chave do Registro MountedDevices .

Captura de tela ilustrando como os nomes persistentes aparecem na chave do Registro MountedDevices.

O gerenciador de montagem conta com o mecanismo de notificação da interface do dispositivo Plug and Play para alertá-lo sobre a chegada e remoção de volume. Portanto, cada cliente (ou seja, cada driver de volume, geralmente um driver de classe) deve criar uma interface na classe de interface MOUNTDEV_MOUNTED_DEVICE_GUID chamando IoRegisterDeviceInterface para notificar o gerenciador de montagem da chegada no sistema do volume que ele gerencia. O GUID da classe de interface MOUNTDEV_MOUNTED_DEVICE_GUID é definido em mountmgr.h.

Ao receber uma notificação Plug and Play da chegada de uma interface de volume, o gerenciador de montagem envia ao cliente três IRPs de controle de dispositivo:

Em resposta a essas três IOCTLs, o cliente deve retornar o nome do objeto de dispositivo não persistente do volume (ou nome de destino) localizado no diretório Device da árvore de objetos do sistema (por exemplo: "\Device\HarddiskVolume1"), a ID de volume exclusiva e um nome de link simbólico persistente sugerido para o volume, respectivamente. Embora os clientes possam optar por ignorá IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME, eles são obrigados a fornecer uma ID de volume exclusiva ao receber IOCTL_MOUNTDEV_QUERY_DEVICE_NAME ou IOCTL_MOUNTDEV_QUERY_UNIQUE_ID. O gerenciador de montagem depende inteiramente do cliente para fornecer a ID de volume exclusiva. Se o cliente não fornecê-lo, o gerenciador de montagem não poderá atribuir pontos de montagem, como letras de unidade, ao volume.

Se um cliente alertar o gerenciador de montagem sobre a chegada de seu volume, mas não fornecer uma ID exclusiva para o volume quando consultado, o volume será colocado em uma lista de dispositivos montados inativos. Quando essa situação ocorre, os clientes podem enviar um IOCTL_MOUNTMGR_CHECK_UNPROCESSED_VOLUMES IOCTL para o gerenciador de montagem para solicitar que o gerenciador de montagem verifique novamente sua lista de dispositivos montados mortos e faça outra tentativa de consultar os clientes na lista para os IDs exclusivos de seus respectivos volumes.

Depois que o gerenciador de montagem recebe um ID de volume exclusivo para um volume recém-introduzido:

  • Ele pesquisa em seu banco de dados todos os nomes persistentes atribuídos a esse ID exclusivo.
  • Ele cria links simbólicos para o volume para cada nome de link simbólico persistente.

Quando o gerenciador de montagem detecta que um volume saiu da linha, ele exclui os links simbólicos que apontam para o objeto de dispositivo sem excluir os nomes de link simbólico correspondentes no banco de dados do gerenciador de montagem.

Para obter informações sobre como os clientes do gerenciador de montagem criam nomes simbólicos persistentes, consulte IOCTL_MOUNTMGR_CREATE_POINT.

Códigos de controle de E/S enviados por clientes do Mount Manager

O gerenciador de montagem publica uma interface que permite que os clientes do gerenciador de montagem definam, consultem e excluam nomes persistentes de volumes. Para acessar essa interface, os clientes podem obter um ponteiro para o objeto de dispositivo do gerenciador de montagem usando o nome do objeto MOUNTMGR_DEVICE_NAME, definido em Mountmgr.h. Por exemplo:

    // Obtain a pointer to the mount manager device object &
    // use it to send any of the I/O Control codes in this 
    // section to the mount manager.
    RtlInitUnicodeString(&name, MOUNTMGR_DEVICE_NAME);
    status = IoGetDeviceObjectPointer(&name,
                FILE_READ_ATTRIBUTES, 
                &fileObject, &deviceObject);
    irp = IoBuildDeviceIoControlRequest(
            IOCTL_MOUNTMGR_CREATE_POINT,
            deviceObject, createPoint, createPointSize, 
            NULL, 0, FALSE, &event, &ioStatus);
    status = IoCallDriver(deviceObject, irp);

A sequência de chamadas neste exemplo de pseudocódigo é simplificada por uma questão de brevidade. Para obter um exemplo de pseudocódigo mais completo, consulte IOCTL_MOUNTMGR_CREATE_POINT.

Os clientes do gerenciador de montagem podem enviar qualquer um dos códigos de controle IOCTL_MOUNTMGR_XXX documentados para o gerenciador de montagem, comoIOCTL_MOUNTMGR_CREATE_POINT.

Códigos de controle de E/S enviados pelo Gerenciador de montagem

O gerenciador de montagem pode enviar qualquer um dos códigos de controle IOCTL_MOUNTDEV_XXX documentados para seus clientes, como IOCTL_MOUNTDEV_QUERY_DEVICE_NAME.