Prise en charge du nommage UNC et du MUP

Cet article décrit comment un redirecteur réseau peut prendre en charge la convention de nommage uniforme (UNC) et le Multiple UNC Provider (MUP).

MUP est un composant en mode noyau, fourni par le système, responsable de la gestion des chemins UNC :

  • Il aide à localiser les ressources réseau identifiées à l’aide de l’UNC.

  • Il canalise tous les accès aux systèmes de fichiers distants en utilisant un nom UNC vers un redirecteur réseau capable de gérer les demandes de systèmes de fichiers distants. Le redirecteur réseau est le fournisseur UNC.

MUP est impliqué lorsqu’une application utilise un chemin UNC ; par exemple, une commande en ligne de commande telle que :

notepad \\server\public\readme.txt

MUP reçoit des commandes contenant des noms UNC provenant des applications. Il envoie le nom à chaque fournisseur UNC enregistré et à tout autre fournisseur réseau installé. Lorsqu’un fournisseur UNC identifie un nom UNC comme étant le sien, le MUP redirige automatiquement les futures instances de ce nom vers ce fournisseur.

MUP n’est pas impliqué lors d’une opération qui crée une lettre de lecteur mappée (comme la commande « NET USE », par exemple). À la place, le multiple provider router (MPR) et une DLL réseaux Windows en mode utilisateur pour le redirecteur réseau gèrent cette opération. Toutefois, une DLL de fournisseur WNet en mode utilisateur peut communiquer directement avec un pilote de redirecteur réseau en mode noyau pendant cette opération.

Pour les redirecteurs réseau conformes au modèle de redirection introduit dans Windows Vista, MUP est impliqué même lorsqu’un lecteur réseau mappé est utilisé. Les opérations de fichiers effectuées sur le lecteur mappé passent par le MUP pour atteindre le redirecteur réseau. Dans ce cas, MUP se contente de transmettre l’opération au redirecteur réseau concerné.

MUP fait partie du binaire mup.sys, qui inclut également le client DFS (Distributed File System).

Un redirecteur réseau en mode noyau possède normalement également une DLL WNet en mode utilisateur pour prendre en charge l’établissement de connexions à des ressources distantes (mapper des lettres de lecteur à des ressources distantes, par exemple). Le MPR est une DLL en mode utilisateur qui établit des connexions réseau sur la base de requêtes adressées aux fournisseurs WNet. Les appels au MPR résultent de l’une des opérations suivantes :

  • Une commande net use x: \\server\share émise à partir d’une invite de commande.

  • Une connexion de lettre de lecteur réseau établie à partir de l’Explorateur Windows.

  • Appels directs aux fonctions WNet.

Un redirecteur réseau doit s'enregistrer auprès de MUP pour gérer les noms UNC. Plusieurs fournisseurs UNC peuvent être enregistrés auprès de MUP. Ces fournisseurs UNC peuvent être un ou plusieurs des redirecteurs suivants :

  • Des mini-redirecteurs réseau basés sur RDBSS, tels que le redirecteur Server Message Block (SMB) et le redirecteur WebDAV.
  • Des redirecteurs hérités non basés sur RDBSS.

Résolution de préfixe

Le MUP détermine quel fournisseur peut traiter un chemin UNC dans une opération basée sur le nom, généralement une requête IRP_MJ_CREATE. Cette détermination est appelée « résolution de préfixe ». L’opération de résolution de préfixe a deux objectifs :

  • L’opération basée sur le nom qui a conduit à la résolution de préfixe est acheminée vers le fournisseur revendiquant le préfixe. En cas de succès, le MUP veille à ce que les opérations ultérieures basées sur le handle (IRP_MJ_READ et IRP_MJ_WRITE, par exemple) aillent au même fournisseur en contournant complètement le MUP.

  • Le fournisseur et son préfixe revendiqué sont enregistrés dans un cache de préfixe que MUP maintient. Pour les opérations ultérieures basées sur les noms, le MUP utilise ce cache de préfixes pour déterminer si un fournisseur a déjà réclamé un préfixe avant de tenter d'effectuer une résolution de préfixes. Chaque entrée de ce cache de préfixe est soumise à un délai d’expiration (appelé TTL) une fois qu’elle a été ajoutée au cache. Une entrée est supprimée après l’expiration de ce délai d’expiration, moment auquel MUP effectue à nouveau la résolution de préfixe pour ce préfixe lors d’une opération ultérieure basée sur le nom.

MUP effectue la résolution des préfixes en émettant une requête IOCTL_REDIR_QUERY_PATH aux redirecteurs de réseau enregistrés auprès de MUP. Les tampons d’entrée et de sortie pour IOCTL_REDIR_QUERY_PATH sont alloués à partir du pool non paginé.

Les redirecteurs de réseau ne doivent autoriser que les expéditeurs en mode noyau de cette IOCTL, en vérifiant que le membre RequesterMode de la structure IRP est KernelMode.

MUP utilise la structure QUERY_PATH_REQUEST pour les informations de demande.

Les fournisseurs UNC doivent utiliser la structure QUERY_PATH_RESPONSE pour les informations de réponse.

Tout redirecteur réseau hérité (non basé sur l’utilisation de RDBSS) qui s’enregistre comme fournisseur UNC auprès de MUP en appelant FsRtlRegisterUncProvider reçoit la demande IOCTL_REDIR_QUERY_PATH.

Un mini-redirecteur réseau qui indique qu’il prend en charge un fournisseur UNC reçoit cette revendication de préfixe comme s’il s’agissait d’un appel IRP_MJ_CREATE. Cette requête de création est similaire à un appel CreateFile en mode utilisateur avec l'indicateur FILE_CREATE_TREE_CONNECTION activé. Un mini-redirecteur réseau ne reçoit pas la revendication de préfixe comme un appel à MRxLowIOSubmit[LOWIO_OP_IOCTL]. Pour une revendication de préfixe, RDBSS envoie une demande MRxCreateSrvCall au mini-redirecteur réseau, suivie d’un appel à MRxSrvCallWinnerNotify et MRxCreateVNetRoot. Lorsqu’un mini-redirecteur réseau s’enregistre auprès de RDBSS, RDBSS copie la table de répartition du pilote du mini-redirecteur réseau pour la pointer vers les points d’entrée internes de RDBSS. Le RDBSS reçoit alors cet IOCTL_REDIR_QUERY_PATH en interne pour le mini-redirecteur de réseau et appelle MRxCreateSrvCall, MRxSrvCallWinnerNotify et MRxCreateVNetRoot. L’IRP original IOCTL_REDIR_QUERY_PATH est contenu dans la structure RX_CONTEXT transmise à la routine MRxCreateSrvCall. De plus, les membres suivants dans le RX_CONTEXT transmis à MRxCreateSrvCall sont modifiés :

  • Le membre MajorFunction est défini sur IRP_MJ_CREATE même si l'IRP d'origine était IRP_MJ_DEVICE_CONTROL.
  • Le membre PrefixClaim.SuppliedPathName.Buffer est défini sur le membre FilePathName de la structure QUERY_PATH_REQUEST.
  • Le membre PrefixClaim.SuppliedPathName.Length est défini sur le membre PathNameLength de la structure QUERY_PATH_REQUEST.
  • Le membre Create.NtCreateParameters.SecurityContext a pour valeur le membre SecurityContext de la structure QUERY_PATH_REQUEST.
  • Le membre Create.ThisIsATreeConnectOpen est défini sur TRUE.
  • Le bit RX_CONTEXT_CREATE_FLAG_UNC_NAME est défini dans le membre Create.Flags.

Si le mini-redirecteur de réseau veut voir les détails de la revendication de préfixe, il peut lire ces membres dans le RX_CONTEXT transmis à MRxCreateSrvCall. Sinon, il peut simplement tenter de se connecter au partage de serveur et renvoyer STATUS_SUCCESS si l'appel MRxCreateSrvCall a réussi. RDBSS fait la revendication de préfixe au nom du mini-redirecteur réseau.

Il y a un cas où un mini-redirecteur réseau pourrait recevoir cet IOCTL directement. Un mini-répartiteur de réseau peut enregistrer une copie de sa table de répartition des pilotes avant de s'initialiser et de s'enregistrer auprès du RDBSS. Après avoir appelé RxRegisterMinirdr pour s'enregistrer auprès du RDBSS, le mini-répartiteur de réseau peut enregistrer une copie des nouveaux points d'entrée de la table de répartition des pilotes installés par le RDBSS et restaurer sa table de répartition des pilotes d'origine. La table de répartition du pilote restaurée devrait être modifiée de manière à ce que, après avoir vérifié l’IRP reçu pour les IRP qui intéressent le mini-redirecteur réseau, l’appel soit transmis aux points d’entrée de la table de répartition du pilote RDBSS. RDBSS copie la table de répartition du pilote d’un mini-redirecteur réseau lorsque le pilote initialise RDBSS et appelle RxRegisterMinrdr. Un mini-redirecteur de réseau qui établit un lien avec rdbsslib.lib doit sauvegarder sa table de répartition des pilotes originale avant d'appeler RxDriverEntry à partir de sa routine DriverEntry pour initialiser la bibliothèque statique RDBSS et restaurer sa table de répartition des pilotes après avoir appelé RxRegisterMinrdr. Cette exigence est due au fait que RDBSS copie la table de répartition du mini-redirecteur réseau à la fois dans les routines RxDriverEntry et RxRegisterMinrdr.

La valeur de registre REG_SZ ProviderOrder contrôle l’ordre dans lequel les fournisseurs sont interrogés lors de la résolution de préfixe. Cette valeur est stockée sous la clé suivante :

HKLM\System\CurrentControlSet\Control\NetworkProvider\Order

Les noms de fournisseurs individuels dans la valeur de registre ProviderOrder sont séparés par des virgules, sans espace blanc en tête ou à la fin.

Par exemple, cette valeur pourrait contenir la chaîne :

RDPNP,LanmanWorkstation,WebClient

Étant donné un chemin UNC \\<serveur>\<partage>\<chemin>, MUP émet une demande de résolution de préfixe si le préfixe (\\serveur\partage ou \\serveur, par exemple) n’est pas trouvé dans le cache de préfixe MUP. MUP envoie une demande de résolution de préfixe à chaque fournisseur dans l’ordre suivant jusqu’à ce qu’un fournisseur revendique le préfixe, ou jusqu’à ce que tous les fournisseurs soient interrogés :

  1. Client TS (RDPNP)

  2. Redirecteur SMB (LanmanWorkstation)

  3. Redirecteur WebDAV (WebClient)

Les modifications apportées à la valeur de registre ProviderOrder nécessitent un redémarrage pour prendre effet dans MUP.

MUP utilise chaque nom de fournisseur répertorié pour trouver la clé de registre du fournisseur sous la clé de registre suivante :

HKLM\System\CurrentControlSet\Services\<ProviderName>

MUP lit ensuite la valeur DeviceName sous la sous-clé NetworkProvider pour trouver le nom de l'appareil avec lequel le fournisseur s'enregistrera. Lorsque le fournisseur s’enregistre réellement, MUP fait correspondre le nom du périphérique transmis avec la liste des noms de périphériques des fournisseurs connus. Il place ensuite le fournisseur dans une liste ordonnée aux fins de résolution de préfixe. L’ordre des fournisseurs dans cette liste est basé sur l’ordre spécifié dans la valeur de registre ProviderOrder précédemment mentionnée.

Le Multiple Provider Router (MPR), la DLL en mode utilisateur qui établit les connexions réseau en fonction des requêtes des fournisseurs WNet, respecte également cet ordre des fournisseurs.

MUP émet la requête de résolution de préfixe en série et s'arrête dès que le premier fournisseur réclame le préfixe. Ainsi, dans l’exemple précédent, si RDPNP revendique un préfixe, MUP ne fait pas appel aux redirecteurs SMB ou WebDAV.

La « résolution de préfixe en série » (par opposition à parallèle) empêche un redirecteur réseau avec une priorité ProviderOrder inférieure de provoquer des problèmes de performances pour un redirecteur réseau de priorité ProviderOrder supérieure. Prenons l'exemple d'un serveur distant doté d'un pare-feu configuré pour bloquer certains types de paquets TCP/IP (accès à HTTP, par exemple), mais pour en autoriser d'autres (accès à SMB, par exemple). Dans ce cas, même si le redirecteur réseau SMB est configuré comme premier fournisseur dans la valeur ProviderOrder et revendique rapidement le préfixe, le redirecteur WebDAV pourrait retarder considérablement la résolution de préfixe en attendant l’expiration du délai de connexion TCP.