Suporte para nomenclatura UNC e MUP
Este artigo descreve como um redirecionador de rede pode dar suporte à nomenclatura de convenção de nomenclatura uniforme (UNC) e ao Provedor UNC Múltiplo (MUP).
O MUP é um componente de modo kernel fornecido pelo sistema responsável por lidar com caminhos UNC:
Ele ajuda a localizar recursos de rede identificados como usando UNC.
Ele canaliza todos os acessos remotos ao sistema de arquivos usando um nome UNC para um redirecionador de rede capaz de lidar com as solicitações do sistema de arquivos remoto. O redirecionador de rede é o provedor UNC.
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 e quaisquer outros provedores de rede 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). Em vez disso, o roteador de vários provedores (MPR) e uma DLL do provedor Windows Networking (WNet) de modo de usuário para o redirecionador de rede manipulam essa operação. 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.
Para redirecionadores de rede que estão em conformidade com o modelo de redirecionador incluído no Windows Vista, o MUP será envolvido mesmo quando uma unidade de rede mapeada for 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 da 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 resultam de qualquer uma das seguintes operações:
Um comando
net use x: \\server\share
emitido a partir de um prompt de comando.Uma conexão de drive de rede estabelecida por meio 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 o redirecionador SMB (Server Message Block) e o redirecionador WebDAV.
- Redirecionadores herdados não baseados em RDBSS.
Resolução de prefixo
O MUP determina qual provedor pode manipular um caminho UNC em uma operação baseada em nome, normalmente uma solicitação IRP_MJ_CREATE. Isso é conhecido como "resolução de prefixo". A operação de resolução de prefixo tem duas finalidades:
A operação baseada em nome que resultou na resolução do 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 o prefixo que ele reivindicou são inseridos em um cache de prefixo mantido pelo MUP. 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 no cache de prefixo está sujeita a um tempo limite (conhecido como TTL) depois de ser adicionada ao cache. Uma entrada é descartada depois que o tempo limite expira, momento em que o MUP executa a resolução de prefixo novamente para o prefixo em questão 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 de dados QUERY_PATH_REQUEST para as informações da solicitação.
Os provedores UNC devem usar a estrutura de dados 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 receberá 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, RDBSS envia uma solicitação MRxCreateSrvCall para o redirecionador de rede seguido por uma chamada para MRxSrvCallWinnerNotify e MRxCreateVNetRoot. Quando um mini-redirecionador de rede se registrar com RDBSS, RDBSS copia o driver para o mini-redirecionador de rede apontar para pontos de entrada RDBSS internos. Em seguida, o RDBSS recebe o IOCTL_REDIR_QUERY_PATH internamente para o mini-redirecionador de rede e chama MRxCreateSrvCall, MRxSrvCallWinnerNotify e MRxCreateVNetRoot. O IRP IOCTL_REDIR_QUERY_PATH original estará contido na estrutura RX_CONTEXT passada para a rotina MRxCreateSrvCall. Além disso, os seguintes membros no RX_CONTEXT passado 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 está 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 aqueles de interesse para o mini-redirecionador de rede, a chamada seja encaminhada para os pontos de entrada de despacho do driver RDBSS. O RDBSS copiará a tabela de despacho de driver de um mini-redirecionador de rede quando o driver inicializar o RDBSS e chamar 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. Isso 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 o caminho UNC \\<server>\<share>\<path>, o MUP emitirá uma solicitação de resolução de prefixo se o prefixo (\\server\share ou \\server, 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 solicite o prefixo ou todos os provedores tenham sido consultados:
Cliente TS (RDPNP)
Redirecionador SMB (LanmanWorkstation)
Redirecionador WebDAV (WebClient)
As alterações no valor do registro ProviderOrder exigem uma reinicialização para entrar em vigor 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 se baseia na ordem especificada no valor do registro ProviderOrder discutido acima.
O Roteador de Vários Provedores (MPR), a DLL de modo de usuário que estabelece conexões de rede com base em consultas a provedores WNet, também respeita 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.
A "resolução de prefixo serial" (versus paralela) impede que um redirecionador de rede com prioridade ProviderOrder mais baixa cause problemas de desempenho para um redirecionador de rede com 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.