Ho un servizio Windows in esecuzione con l'account Sistema locale che crea dispositivi DOS utilizzando la funzione DefineDosDevice. Il servizio è in esecuzione su un server desktop remoto W2K8. Se i dispositivi vengono creati utilizzando le credenziali del servizio, vengono creati nello spazio dei nomi del dispositivo GLOBAL e quindi visibili a tutti gli utenti. Ho bisogno dei dispositivi visibili solo per una particolare sessione di interazione.Perché i dispositivi DOS definiti in una sessione rappresentata non vengono visualizzati in Explorer
Compendo questo impersonando l'utente nella cui sessione desidero visualizzare le unità. Questo è abbastanza semplice, a condizione che l'ID della sessione sia disponibile. Ecco una semplice applicazione di test che ho scritto per illustrare il problema:
int _tmain(int argc, _TCHAR* argv[])
{
BOOL result = TRUE;
if(argc > 3 && !wcscmp(argv[2], L"/i"))
{
HANDLE hToken = 0;
DWORD dwSessionId = _wtoi(argv[3]);
result = WTSQueryUserToken(dwSessionId, &hToken);
if(result) result = ImpersonateLoggedOnUser(hToken);
}
if(result)
{
LPTSTR drive = argv[1];
DefineDosDevice(DDD_REMOVE_DEFINITION, drive, NULL);
result = DefineDosDevice(0, drive, L"C:\\test");
}
if(!result)
{
printf("Error: %d\n", GetLastError());
}
return 0;
}
Per verificare questo codice, ho creato un servizio che lancia una shell di comando con l'account LocalSystem:
sc create binpath test_svc = " cmd/K start "tipo = proprio tipo = interagisce
Questo servizio non si avvia, ma prima che non funzioni, genera una shell di comando in esecuzione con l'account LocalSystem.
Dal cmd.exe LocalSystem, corro:
MySubst.exe x:/i 2
che richiama ImpersonateLoggedOnUser(), allora chiama DefineDosDevice()
Da cmd.exe in esecuzione nella sessione dell'utente, eseguo:
MySubst.exe y:
che chiama DefineDosDevice senza invocare ImpersonateLoggedOnUser().
Questo funziona. Da cmd.exe posso accedere alle due unità X: e Y :. Posso lanciare notepad.exe dal menu di avvio e vedere le unità X: e Y :. Inoltre, se creo una nuova sessione di servizi terminal con un utente diverso, non vedo X: o Y :.
Tuttavia, Explorer mostra solo l'unità Y: in "tutti i computer". Y: è l'unità che è stata creata eseguendo la mia applicazione di prova da cmd.exe in esecuzione all'interno della sessione di destinazione, ovvero la rappresentazione non è stata eseguita. Se riavvio explorer.exe da Task Manager, vengono visualizzate entrambe le unità X: e Y :.
Ho utilizzato anche WinObj.exe da SysInternals per esaminare i dispositivi Win NT definiti. Quello che vedo è:
- Sessions
- 0
- DosDevices
00000000-000057607
(57607 è l'ID della sessione di login associato alla sessione che sto impersonando)
Il contenuto di "00.000.000-000.057.607" sono:
Global SymbolicLink \Global??
X: SymbolicLink \\??\C:\test
Y: SymbolicLink \\??\C:\test
Secondo WinObj, i due dispositivi dos sono identici. Appartengono alla stessa sessione e sessione di accesso. Sono collegamenti simbolici allo stesso oggetto NT.
Come può essere che uno di essi appaia in Explorer e l'altro no.
Se si interrompe e si riavvia Explorer, vengono visualizzate le unità? –
Potrebbe non essere possibile farlo solo con la rappresentazione. Potrebbe essere necessario avviare un processo effettivo nel contesto di destinazione per apportare la modifica a tuo nome. –
@HarryJohnston Un riavvio di Explorer causa la visualizzazione delle unità, ma non sono sicuro di cosa concludere. – FishesCycle