Suporte para nomenclatura UNC e MUP

Este artigo descreve como um redirecionador de rede pode oferecer suporte à nomeação UNC e ao MUP (Provedor UNC Múltiplo).

O MUP é um serviço do Windows que ajuda a localizar recursos de rede identificados usando UNC (convenção de nomenclatura uniforme). É um componente de modo kernel responsável por canalizar todos os acessos remotos ao sistema de arquivos usando um nome UNC para um redirecionador de rede (o provedor UNC) capaz de lidar com as solicitações do sistema de arquivos remoto. O MUP está envolvido quando um aplicativo usa um caminho UNC; Por exemplo, um comando de linha de comando como:

notepad \\server\public\readme.txt

O MUP recebe comandos contendo nomes UNC de aplicativos. Ele envia o nome para cada provedor UNC registrado, estação de trabalho LAN Manager e quaisquer outros que estejam instalados. Quando um provedor UNC identifica um nome UNC como seu, o MUP redireciona automaticamente instâncias futuras desse nome para esse provedor.

O MUP não está envolvido durante uma operação que cria uma letra de unidade mapeada (o comando "NET USE", por exemplo). Essa operação é manipulada pelo roteador de vários provedores (MPR) e uma DLL de provedor de rede do Windows (WNet) de modo de usuário para o redirecionador de rede. No entanto, uma DLL do provedor WNet de modo de usuário pode se comunicar diretamente com um driver de redirecionador de rede de modo kernel durante essa operação.

Antes do Windows Vista, as operações de arquivo remoto executadas em uma unidade mapeada que não representam uma unidade DFS (Sistema de Arquivos Distribuídos) não passam pelo MUP. Essas operações passam diretamente para o provedor de rede que processou o mapeamento de letra da unidade.

Para redirecionadores de rede que estão em conformidade com o modelo de redirecionador atualizado introduzido no Windows Vista, o MUP está envolvido mesmo quando uma unidade de rede mapeada é usada. As operações de arquivo executadas na unidade mapeada passam pelo MUP até o redirecionador de rede. Nesse caso, o MUP simplesmente passa a operação para o redirecionador de rede envolvido.

O MUP faz parte do binário mup.sys , que também inclui o cliente DFS (Distributed File System).

Um redirecionador de rede do kernel normalmente também tem uma DLL do provedor WNet no modo de usuário para oferecer suporte ao estabelecimento de conexões com recursos remotos (mapeamento de letras de unidade para recursos remotos, por exemplo). O MPR é uma DLL de modo de usuário que estabelece conexões de rede com base em consultas a provedores WNet. As chamadas para o MPR são resultado de qualquer uma das seguintes operações:

  • Um net use x: \\server\share comando emitido a partir de um prompt de comando.

  • Uma conexão de letra de unidade de rede estabelecida a partir do Windows Explorer.

  • Chamadas diretas para funções WNet.

Um redirecionador de rede deve se registrar no MUP para lidar com nomes UNC. Pode haver vários provedores UNC registrados no MUP. Esses provedores UNC podem ser um ou mais dos seguintes redirecionadores:

  • Mini-redirecionadores de rede baseados em RDBSS, como redirecionador SMB (Server Message Block) e redirecionador WebDAV.
  • Redirecionadores legados não baseados em RDBSS.

Resolução de prefixos

O MUP determina qual provedor pode manipular um caminho UNC em uma operação baseada em nome, normalmente uma solicitação IRP_MJ_CREATE. Essa determinação é conhecida como "resolução de prefixo". A operação de resolução de prefixo serve a duas finalidades:

  • A operação baseada em nome que resultou na resolução de prefixo é roteada para o provedor que reivindica o prefixo. Caso seja bem-sucedido, o MUP garante que as operações subsequentes baseadas em identificador (IRP_MJ_READ e IRP_MJ_WRITE, por exemplo) vão para o mesmo provedor ignorando completamente o MUP.

  • O provedor e seu prefixo reivindicado são inseridos em um cache de prefixo que o MUP mantém. Para operações subsequentes baseadas em nome, o MUP usa o cache de prefixo para determinar se um provedor já reivindicou um prefixo antes de tentar executar uma resolução de prefixo. Cada entrada nesse cache de prefixo está sujeita a um tempo limite (conhecido como TTL) depois de adicionada ao cache. Uma entrada é descartada depois que esse tempo limite expira, momento em que o MUP executa a resolução de prefixo novamente para esse prefixo em uma operação subsequente baseada em nome.

O MUP executa a resolução de prefixo emitindo a solicitação IOCTL_REDIR_QUERY_PATH para redirecionadores de rede registrados no MUP. Os buffers de entrada e saída para IOCTL_REDIR_QUERY_PATH são alocados do pool não paginado.

Os redirecionadores de rede só devem permitir remetentes no modo kernel dessa IOCTL, verificando se o membro RequesterMode da estrutura IRP é KernelMode.

O MUP usa a estrutura QUERY_PATH_REQUEST para as informações da solicitação.

Os provedores UNC devem usar a estrutura QUERY_PATH_RESPONSE para as informações de resposta.

Qualquer redirecionador de rede herdado (não baseado no uso de RDBSS) que se registra como um provedor UNC com MUP chamando FsRtlRegisterUncProvider recebe a solicitação IOCTL_REDIR_QUERY_PATH.

Um mini-redirecionador de rede que indica suporte como um provedor UNC recebe essa declaração de prefixo como se fosse uma chamada IRP_MJ_CREATE. Essa solicitação de criação é semelhante a uma chamada CreateFile com o sinalizador FILE_CREATE_TREE_CONNECTION definido. Um mini-redirecionador de rede não recebe a declaração de prefixo como uma chamada para MRxLowIOSubmit[LOWIO_OP_IOCTL]. Para uma declaração de prefixo, o RDBSS envia uma solicitação MRxCreateSrvCall para o mini-redirecionador de rede seguida por uma chamada para MRxSrvCallWinnerNotify e MRxCreateVNetRoot. Quando um mini-redirecionador de rede se registra com RDBSS, o RDBSS copia a tabela de despacho do driver para o mini-redirecionador de rede para apontar para pontos de entrada RDBSS internos. Em seguida, o RDBSS recebe esse IOCTL_REDIR_QUERY_PATH internamente para o mini-redirecionador de rede e chama MRxCreateSrvCall, MRxSrvCallWinnerNotify e MRxCreateVNetRoot. O IRP IOCTL_REDIR_QUERY_PATH original está contido na estrutura RX_CONTEXT passada para a rotina MRxCreateSrvCall. Além disso, os seguintes membros no RX_CONTEXT passados para MRxCreateSrvCall são modificados:

  • O membro MajorFunction será definido como IRP_MJ_CREATE mesmo que o IRP original seja IRP_MJ_DEVICE_CONTROL.
  • O membro PrefixClaim.SuppliedPathName.Buffer será definido como FilePathName da estrutura QUERY_PATH_REQUEST.
  • O membro PrefixClaim.SuppliedPathName.Length será definido como o membro PathNameLength da estrutura QUERY_PATH_REQUEST.
  • O membro Create.NtCreateParameters.SecurityContext está definido como o membro SecurityContext da estrutura QUERY_PATH_REQUEST.
  • O membro Create.ThisIsATreeConnectOpen é definido como TRUE.
  • O membro Create.Flags tem o conjunto de bits RX_CONTEXT_CREATE_FLAG_UNC_NAME.

Se o mini-redirecionador de rede quiser ver detalhes da declaração de prefixo, ele poderá ler esses membros no RX_CONTEXT passado para MRxCreateSrvCall. Caso contrário, ele só poderá tentar se conectar ao compartilhamento do servidor e retornar STATUS_SUCCESS se a chamada MRxCreateSrvCall for bem-sucedida. O RDBSS faz a declaração de prefixo em nome do mini-redirecionador de rede.

Há um caso em que um mini-redirecionador de rede poderia receber essa IOCTL diretamente. Um mini-redirecionador de rede poderia salvar uma cópia da tabela de despacho de driver antes de inicializar e registrar com RDBSS. Depois de chamar RxRegisterMinirdr para se registrar com RDBSS, o mini-redirecionador de rede pode salvar uma cópia dos novos pontos de entrada da tabela de despacho de driver instalados pelo RDBSS e restaurar sua tabela de despacho de driver original. A tabela de despacho de driver restaurada precisaria ser modificada para que, depois de verificar o IRP recebido para os IRPs de interesse para o mini-redirecionador de rede, a chamada seja encaminhada para os pontos de entrada de despacho do driver RDBSS. O RDBSS copia a tabela de despacho do driver de um mini-redirecionador de rede quando o driver inicializa o RDBSS e chama RxRegisterMinrdr. Um mini-redirecionador de rede que se vincula a rdbsslib.lib deve salvar sua tabela de despacho de driver original antes de chamar RxDriverEntry da rotina DriverEntry para inicializar a biblioteca estática de RDBSS e restaurar a tabela de despacho de driver após chamar RxRegisterMinrdr. Esse requisito ocorre porque o RDBSS copia pela tabela de despacho do mini-redirecionador de rede nas rotinas RxDriverEntry e RxRegisterMinrdr .

O valor do Registro REG_SZ ProviderOrder controla a ordem na qual os provedores são consultados durante a resolução de prefixo. Esse valor é armazenado sob a seguinte chave:

HKLM\System\CurrentControlSet\Control\NetworkProvider\Order

Os nomes de provedores individuais no valor do registro ProviderOrder são separados por vírgulas, sem espaço em branco à esquerda ou à direita.

Por exemplo, esse valor pode conter a cadeia de caracteres:

RDPNP,LanmanWorkstation,WebClient

Dado um caminho UNC \\<servidor>\<compartilhamento>\<caminho>, o MUP emite uma solicitação de resolução de prefixo se o prefixo (\\servidor\compartilhamento ou \\servidor, por exemplo) não for encontrado no cache de prefixo do MUP. O MUP envia uma solicitação de resolução de prefixo para cada provedor na seguinte ordem até que um provedor reivindique o prefixo ou até que todos os provedores sejam consultados:

  1. Cliente TS (RDPNP)

  2. Redirecionador SMB (LanmanWorkstation)

  3. Redirecionador WebDAV (WebClient)

As alterações no valor do Registro ProviderOrder exigem uma reinicialização para ter efeito no MUP.

O MUP usa cada nome de provedor listado para localizar a chave do registro do provedor na seguinte chave do registro:

HKLM\System\CurrentControlSet\Services\<ProviderName>

Em seguida, o MUP lê o valor DeviceName na subchave NetworkProvider para localizar o nome do dispositivo com o qual o provedor se registrará. Quando o provedor realmente se registra, o MUP corresponde ao nome do dispositivo passado com a lista de nomes de dispositivos de provedores conhecidos. Em seguida, ele coloca o provedor em uma lista ordenada para fins de resolução de prefixo. A ordem dos provedores nesta lista é baseada na ordem especificada no valor do Registro ProviderOrder discutido anteriormente.

O MPR (Multiple Provider Router), a DLL de modo de usuário que estabelece conexões de rede com base em consultas a provedores WNet, também honra essa ordem de provedor.

O MUP emite a solicitação de resolução de prefixo em série e interrompe assim que o primeiro provedor reivindica o prefixo. Assim, no exemplo anterior, se RDPNP reivindicar um prefixo, o MUP não chamará os redirecionadores SMB ou WebDAV.

"Resolução de prefixo serial" (versus paralelo) impede que um redirecionador de rede com prioridade ProviderOrder mais baixa cause problemas de desempenho para um redirecionador de rede de prioridade ProviderOrder mais alta. Por exemplo, considere um servidor remoto, com um firewall instalado, configurado para bloquear certos tipos de pacote TCP/IP (acesso a HTTP, por exemplo), mas para permitir outros (acesso SMB, por exemplo). Nesse caso, mesmo que o redirecionador de rede SMB esteja configurado como o primeiro provedor no valor ProviderOrder e reivindique o prefixo rapidamente, o redirecionador WebDAV pode atrasar significativamente a conclusão da resolução do prefixo aguardando o tempo limite da conexão TCP.