5

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.

+0

Se si interrompe e si riavvia Explorer, vengono visualizzate le unità? –

+0

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. –

+0

@HarryJohnston Un riavvio di Explorer causa la visualizzazione delle unità, ma non sono sicuro di cosa concludere. – FishesCycle

risposta

4

@arx e @HarryJohnston erano in the money. Se trasmetto un messaggio WM_DEVICECHANGE da un thread nella stessa sessione di Explorer, la nuova unità viene visualizzata in Risorse del computer. Ecco il codice:

DWORD recipients = BSM_ALLDESKTOPS | BSM_APPLICATIONS; 

DEV_BROADCAST_VOLUME msg; 
ZeroMemory(&msg, sizeof(msg)); 
msg.dbcv_size = sizeof(msg); 
msg.dbcv_devicetype = DBT_DEVTYP_VOLUME; 
msg.dbcv_unitmask = 1 << ('X' - 'A'); 

long success = BroadcastSystemMessage(0, &recipients, WM_DEVICECHANGE, DBT_DEVICEARRIVAL, (LPARAM)&msg); 
Problemi correlati