Supporto per la denominazione UNC e MUP

Il provider UNC (MUP) multiplo è un componente in modalità kernel responsabile del canale di tutti gli accessi al file system remoto usando un nome UNC (Universal Naming Convention) a un reindirizzamento di rete (provider UNC) in grado di gestire le richieste del file system remoto. MUP è coinvolto quando un percorso UNC viene usato da un'applicazione come illustrato dall'esempio seguente che può essere eseguito da una riga di comando:

notepad \\server\public\readme.txt

MUP non è coinvolto durante un'operazione che crea una lettera di unità mappata ,ad esempio il comando "NET USE". Questa operazione viene gestita da più router provider (MPR) e da una DLL del provider WNet in modalità utente per il reindirizzamento di rete. Tuttavia, una DLL del provider WNet in modalità utente può comunicare direttamente con un driver di reindirizzamento di rete in modalità kernel durante questa operazione.

In Microsoft Windows Server 2003, Windows XP e Windows 2000, le operazioni di file remote eseguite in un'unità mappata che non rappresenta un'unità DFS (Distributed File System) non passano attraverso MUP. Queste operazioni passano direttamente al provider di rete che gestisce il mapping delle lettere di unità.

Per i reindirizzamenti di rete conformi al modello di reindirizzamento di Windows Vista, MUP è coinvolto anche quando viene usata un'unità di rete mappata. Le operazioni sui file eseguite nell'unità mappata passano attraverso MUP al reindirizzamento di rete. Si noti che in questo caso MUP passa semplicemente l'operazione al reindirizzamento di rete coinvolto.

MUP fa parte del file binario mup.sys , che include anche il client Microsoft DFS in Windows Server 2003, Windows XP e Windows 2000.

Un reindirizzamento della rete kernel avrà normalmente anche una DLL del provider WNet in modalità utente per supportare la definizione delle connessioni alle risorse remote (ad esempio mapping delle lettere di unità alle risorse remote). MpR è una DLL in modalità utente che stabilisce le connessioni di rete in base alle query ai provider di rete WNet. Le chiamate a MPR risulterebbero da una delle seguenti operazioni:

Comando "net use x: \\server\share" rilasciato da un prompt dei comandi.

Connessione alla lettera di unità di rete stabilita da Esplora risorse di Windows

Chiamate dirette alle funzioni WNet.

Un reindirizzamento di rete deve registrarsi con MUP per gestire i nomi UNC. È possibile registrare più provider UNC con MUP. Questi provider UNC possono essere uno o più dei seguenti:

  • Mini-reindirizzamento di rete basato su RDBSS

  • Reindirizzamento legacy non basato su RDBSS

MUP determina quale provider può gestire un percorso UNC in un'operazione basata su nome, in genere una richiesta di IRP_MJ_CREATE. Questo viene definito "risoluzione del prefisso". Prima di Windows Vista, l'operazione di risoluzione del prefisso serve due scopi:

  • L'operazione basata sul nome che ha generato la risoluzione del prefisso viene indirizzata al provider che richiede il prefisso. In caso di esito positivo, MUP garantisce che le operazioni successive basate su handle (IRP_MJ_READ e IRP_MJ_WRITE, ad esempio) vadano allo stesso provider ignorando completamente MUP.

  • Il provider e il prefisso richiesto vengono immessi in una cache di prefisso gestita da MUP. Per le operazioni successive basate sui nomi, MUP usa questa cache di prefisso per determinare se un provider ha già richiesto un prefisso prima di tentare di eseguire una risoluzione del prefisso. Ogni voce in questa cache di prefisso è soggetta a un timeout (denominato TTL) una volta aggiunto alla cache. Una voce viene generata dopo la scadenza di questo timeout, a questo punto di tempo MUP eseguirà nuovamente la risoluzione del prefisso per questo prefisso in un'operazione basata su nome successiva.

MUP esegue la risoluzione del prefisso eseguendo una richiesta di IOCTL_REDIR_QUERY_PATH ai reindirizzamenti di rete registrati con MUP. I buffer di input e output per IOCTL_REDIR_QUERY_PATH sono i seguenti:

Parametro disponibile all'indirizzo Formato struttura dati

Buffer di input

IrpSp-> Parameters.DeviceIoControl.Type3InputBuffer

QUERY_PATH_REQUEST

Buffer di output

IRP-UserBuffer>

QUERY_PATH_RESPONSE

IOCTL e le strutture di dati sono definiti in ntifs.h. I buffer vengono allocati dal pool non a pagina.

I reindirizzamenti di rete devono consentire solo mittenti in modalità kernel di questo IOCTL, verificando che il membro RequesterMode della struttura IRP sia KernelMode.

MUP usa la struttura di dati QUERY_PATH_REQUEST per le informazioni sulla richiesta.

typedef struct _QUERY_PATH_REQUEST {
    ULONG                PathNameLength;
    PIO_SECURITY_CONTEXT SecurityContext;
    WCHAR                FilePathName[1];
} QUERY_PATH_REQUEST, *PQUERY_PATH_REQUEST;
Membro struttura Descrizione

PathNameLength

Lunghezza, in byte, della stringa Unicode contenuta nel membro FilePathName .

Securitycontext

Puntatore al contesto di sicurezza.

FilePathName

Stringa Unicode non null terminata del percorso> di condivisione><del server><modulo<. La lunghezza della stringa, in byte, viene specificata dal membro PathNameLength .

I provider UNC devono usare la struttura di dati QUERY_PATH_RESPONSE per le informazioni sulla risposta.

typedef struct _QUERY_PATH_RESPONSE {
    ULONG  LengthAccepted;
} QUERY_PATH_RESPONSE, *PQUERY_PATH_RESPONSE;
Membro struttura Descrizione

LengthAccepted

Lunghezza, in byte, del prefisso richiesto dal provider dal percorso stringa Unicode specificato nel membro FilePathName della struttura QUERY_PATH_REQUEST.

Si noti che IOCTL_REDIR_QUERY_PATH è un METHOD_NEITHER IOCTL. Ciò significa che i buffer di input e output potrebbero non essere allo stesso indirizzo. Un errore comune da parte dei provider UNC consiste nell'presumere che il buffer di input e il buffer di output siano uguali e usino il puntatore del buffer di input per fornire la risposta.

Quando un provider UNC riceve una richiesta di IOCTL_REDIR_QUERY_PATH, deve determinare se può gestire il percorso UNC specificato nel membro FilePathName della struttura QUERY_PATH_REQUEST. In tal caso, deve aggiornare il membro LengthAccepted della struttura QUERY_PATH_RESPONSE con la lunghezza, in byte, del prefisso richiesto e completare l'IRP con STATUS_SUCCESS. Se il provider non riesce a gestire il percorso UNC specificato, deve non riuscire la richiesta di IOCTL_REDIR_QUERY_PATH con un codice di errore NTSTATUS appropriato e non deve aggiornare il membro LengthAccepted della struttura QUERY_PATH_RESPONSE. I provider non devono modificare nessuno degli altri membri o la stringa FilePathName in qualsiasi condizione.

Se il nome del prefisso \\server\share non viene riconosciuto in risposta a un IRP_MJ_CREATE o ad altri IP che usano nomi UNC, il codice NTSTATUS consigliato da restituire è uno dei seguenti:

STATUS_BAD_NETWORK_PATH
Impossibile trovare il percorso di rete. Il nome del computer (\server, ad esempio) non è valido o il reindirizzamento di rete non può risolvere il nome del computer (usando i meccanismi di risoluzione dei nomi disponibili).

STATUS_BAD_NETWORK_NAME
Impossibile trovare il nome della condivisione specificato nel server remoto. Il nome del computer (\server, ad esempio) è valido, ma non è possibile trovare il nome di condivisione specificato nel server remoto.

STATUS_INSUFFICIENT_RESOURCES
Sono state disponibili risorse insufficienti per allocare memoria per i buffer.

STATUS_INVALID_DEVICE_REQUEST
Una richiesta di IOCTL_REDIR_QUERY_PATH deve venire solo da MUP e la modalità del richiedente dell'IRP deve sempre essere KernelMode. Questo codice di errore viene restituito se la modalità del richiedente del thread chiamante non era KernelMode.

STATUS_INVALID_PARAMETER
Il membro PathNameLength nella struttura QUERY_PATH_REQUEST supera la lunghezza massima consentita, UNICODE_STRING_MAX_BYTES, per una stringa Unicode.

STATUS_LOGON_FAILURE o STATUS_ACCESS_DENIED
Se l'operazione di risoluzione del prefisso non è riuscita a causa di credenziali non valide o non corrette, il provider deve restituire il codice di errore esatto restituito dal server remoto; questi codici di errore non devono essere convertiti in STATUS_BAD_NETWORK_NAME o STATUS_BAD_NETWORK_PATH. I codici di errore come STATUS_LOGON_FAILURE e STATUS_ACCESS_DENIED fungono da meccanismo di feedback per l'utente che indica il requisito di usare le credenziali appropriate. Questi codici di errore vengono usati anche in alcuni casi per richiedere automaticamente all'utente le credenziali. Senza questi codici di errore, l'utente potrebbe presupporre che il computer non sia accessibile.

Se il reindirizzamento di rete non è in grado di risolvere un prefisso, deve restituire un codice NTSTATUS che corrisponde strettamente alla semantica prevista dall'elenco precedente di codici NTSTATUS consigliati. Un reindirizzamento di rete non deve restituire l'errore rilevato effettivo (STATUS_CONNECTION_REFUSED, ad esempio) direttamente a MUP se il codice NTSTATUS non è compreso nell'elenco precedente.

La lunghezza del prefisso richiesto dal provider dipende da un singolo provider UNC. La maggior parte dei provider richiede in genere la parte \\servername\sharename di un percorso del modulo \\<servername\<sharename>>>\<path.><>< Ad esempio, se un provider ha richiesto \\server\public dato un percorso \\server\public\dir1\dir2, tutte le operazioni basate su nome per il prefisso \\server\public (\server\public\file1, ad esempio) verranno indirizzate a tale provider automaticamente senza alcuna risoluzione del prefisso poiché il prefisso è già presente nella cache dei prefissi. Tuttavia, un percorso con il prefisso \server\marketing\presentation passerà attraverso la risoluzione dei prefisso.

Se un reindirizzamento di rete richiede un nome server (\\server, ad esempio), tutte le richieste per le condivisioni in questo server verranno inviate a questo reindirizzamento di rete. Questo comportamento è accettabile solo se non esiste alcuna possibilità di un'altra condivisione nello stesso server a cui si accede da un reindirizzamento di rete diverso. Ad esempio, un reindirizzamento di rete che dichiara \\server di un percorso UNC impedirà l'accesso da altri reindirizzamenti di rete ad altre condivisioni in questo server (l'accesso WebDAV a \\server\web, ad esempio).

Qualsiasi reindirizzamento di rete legacy (non basato sull'uso di RDBSS) che registra come provider UNC con MUP chiamando FsRtlRegisterUncProvider riceverà la richiesta di IOCTL_REDIR_QUERY_PATH.

Un mini-reindirizzamento di rete che indica il supporto come provider UNC riceverà questa attestazione di prefisso come se fosse una chiamata IRP_MJ_CREATE. Questa richiesta di creazione è simile a una chiamata Createfile in modalità utente con flag FILE_CREATE_TREE_CONNECTION impostata. Un mini-redirector di rete non riceverà l'attestazione del prefisso come chiamata a MRxLowIOSubmit[LOWIO_OP_IOCTL]. Per un'attestazione di prefisso, RDBSS invierà una richiesta MRxCreateSrvCall al mini-reindirizzamento di rete seguita da una chiamata a MRxSrvCallWinnerNotify e MRxCreateVNetRoot. Quando un mini-reindirizzamento di rete viene registrato con RDBSS, la tabella di invio driver per il mini-reindirizzamento di rete verrà copiata da RDBSS per puntare ai punti di ingresso RDBSS interni. RDBSS riceve quindi questa IOCTL_REDIR_QUERY_PATH internamente per il mini-reindirizzamento di rete e chiama MRxCreateSrvCall, MRxSrvCallWinnerNotify e MRxCreateVNetRoot. La IOCTL_REDIR_QUERY_PATH IRP originale sarà contenuta nella struttura RX_CONTEXT passata alla routine MRxCreateSrvCall . Inoltre, i membri seguenti nel RX_CONTEXT passati a MRxCreateSrvCall verranno modificati:

Il membro MajorFunction è impostato su IRP_MJ_CREATE anche se l'IRP originale era IRP_MJ_DEVICE_CONTROL.

Il membro PrefixClaim.SuppliedPathName.Buffer è impostato sul membro FilePathName della struttura QUERY_PATH_REQUEST.

Il membro PrefixClaim.SuppliedPathName.Length è impostato sul membro PathNameLength della struttura QUERY_PATH_REQUEST.

Il membro Create.NtCreateParameters.SecurityContext è impostato sul membro SecurityContext della struttura QUERY_PATH_REQUEST.

Il membro Create.ThisIsATreeConnectOpen è impostato su TRUE.

Il membro Create.Flags ha il set di bit RX_CONTEXT_CREATE_FLAG_UNC_NAME.

Se il mini-redirector di rete vuole visualizzare i dettagli dell'attestazione di prefisso, può leggere questi membri nella RX_CONTEXT passata a MRxCreateSrvCall. In caso contrario, può solo tentare di connettersi alla condivisione server e restituire STATUS_SUCCESS se la chiamata MRxCreateSrvCall ha avuto esito positivo. RDBSS eseguirà l'attestazione di prefisso per conto del mini-reindirizzamento di rete.

C'è un caso in cui un mini-reindirizzamento di rete potrebbe ricevere direttamente questo IOCTL. Un mini-reindirizzamento di rete potrebbe salvare una copia della tabella di invio del driver prima di inizializzare e registrare con RDBSS. Dopo aver chiamato RxRegisterMinirdr per la registrazione con RDBSS, il mini-reindirizzamento di rete potrebbe salvare una copia dei nuovi punti di ingresso della tabella di invio driver installati da RDBSS e ripristinare la tabella di invio del driver originale. La tabella di invio del driver ripristinata deve essere modificata in modo che dopo aver controllato l'IRP ricevuto per quelli di interesse per il mini-reindirizzamento di rete, la chiamata viene inoltrata ai punti di ingresso del driver RDBSS. RDBSS copia nella tabella di invio driver di un mini-reindirizzamento di rete quando il driver inizializza RDBSS e chiama RxRegisterMinrdr. Un mini-reindirizzamento di rete che collega a rdbsslib.lib deve salvare la tabella di invio del driver originale prima di chiamare RxDriverEntry dalla routine DriverEntry per inizializzare la libreria statica RDBSS e ripristinare la tabella di invio del driver dopo aver chiamato RxRegisterMinrdr. Ciò avviene perché RDBSS copia nella tabella di invio del mini-reindirizzamento di rete nelle routine RxDriverEntry e RxRegisterMinrdr .

L'ordine in cui i provider vengono sottoposti a query durante la risoluzione del prefisso è controllato dal valore del Registro di sistema providerOrder REG_SZ archiviato nella chiave seguente:

HKLM\System\CurrentControlSet\Control\NetworkProvider\Order

I singoli nomi di provider nel valore del Registro di sistema ProviderOrder sono separati da virgole senza spazi vuoti iniziali o finali.

Ad esempio, questo valore potrebbe contenere la stringa:

RDPNP,LanmanWorkstation,WebClient

Dato un percorso UNC \\<server\share\path>, MUP genera una richiesta di risoluzione del prefisso se il prefisso (\\server>\<<share> o \\server, ad esempio) non viene trovato nella cache del prefisso MUP. MUP invia una richiesta di risoluzione del prefisso a ogni provider nell'ordine seguente finché un provider non dichiara il prefisso (o tutti i provider sono stati sottoposti a query):

  1. Client TS (RDPNP)

  2. Reindirizzamento SMB (LanmanWorkstation)

  3. Reindirizzamento WebDAV (WebClient)

Le modifiche apportate al valore del Registro di sistema ProviderOrder richiedono un riavvio per l'esecuzione di MUP in Windows Server 2003, Windows XP e Windows 2000.

MUP usa ogni nome del provider elencato per trovare la chiave del Registro di sistema del provider nella chiave del Registro di sistema seguente:

HKLM\System\CurrentControlSet\Services\<ProviderName>

MUP legge quindi il valore DeviceName nella sottochiave NetworkProvider per trovare il nome del dispositivo con cui verrà registrato il provider. Quando il provider esegue effettivamente la registrazione, MUP corrisponde al nome del dispositivo passato con l'elenco dei nomi di dispositivi di provider noti e inserisce il provider in un elenco ordinato ai fini della risoluzione del prefisso. L'ordine dei provider in questo elenco è basato sull'ordine specificato nel valore del Registro di sistema ProviderOrder descritto in precedenza.

Si noti che questo ordine del provider viene rispettato anche dal router multi provider (MPR), la DLL in modalità utente che stabilisce le connessioni di rete in base alle query ai provider WNet.

Prima di Windows Server 2003 con Service Pack 1 e Windows XP con Service Pack 2, il comportamento MUP era quello di inviare richieste di risoluzione dei prefisso a tutti i provider "in parallelo" nell'ordine specificato nel valore del Registro di sistema ProviderOrder e quindi attendere che tutti i provider completino l'operazione di risoluzione del prefisso. Pertanto, anche se il primo provider ha richiesto il prefisso, MUP attende comunque che tutti gli altri provider completino l'operazione di risoluzione del prefisso. Quando più provider rispondono con un'attestazione di prefisso, MUP seleziona il provider in base all'ordine specificato nel valore del Registro di sistema ProviderOrder.

In Windows XP Service Pack 2 e versioni successive e in Windows Server 2003 Service Pack 1 e versioni successive, questo comportamento è cambiato leggermente. MUP genera la richiesta di risoluzione del prefisso in modo seriale e si arresta non appena il primo provider dichiara il prefisso. Pertanto, nell'esempio precedente, se RDPNP attestazione un prefisso, MUP non chiamerà i reindirizzamenti SMB o WebDAV.

Il motivo principale per cui questo comportamento è stato modificato è che uno schema "risoluzione del prefisso seriale" impedisce casi di un reindirizzamento di rete con priorità inferiore nel valore ProviderOrder per causare problemi di prestazioni per un reindirizzamento di rete di priorità superiore nel valore ProviderOrder. Si consideri ad esempio un server remoto, con un firewall sul posto, configurato per bloccare determinati tipi di pacchetti TCP/IP (ad esempio l'accesso a HTTP), ma per consentire ad altri utenti (ad esempio l'accesso SMB). In questo caso, anche se il reindirizzamento di rete SMB è configurato come primo provider nel valore ProviderOrder e dichiara rapidamente il prefisso, il reindirizzamento WebDAV potrebbe ritardare significativamente il completamento della risoluzione del prefisso aspettando il timeout della connessione TCP.