I have a Windows service running under the Local System account, which creates DOS devices using the DefineDosDevice function. The service runs on a remote W2K8 desktop server. If devices are created using service credentials, they are created in the namespace of GLOBAL devices and are therefore visible to all users. I need devices that are visible only for a specific interaction session.
I accomplish this by personifying the user in whose session I want the drives to display. This is pretty simple if a session id is available. Here is a simple test application that I wrote to illustrate the problem:
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;
}
, , LocalSystem:
sc create test_svc binpath = "cmd/K start" type = =
, , LocalSystem.
LocalSystem cmd.exe :
MySubst.exe x:/i 2
ImpersonateLoggedOnUser(), DefineDosDevice()
cmd.exe, , :
MySubst.exe y:
DefineDosDevice ImpersonateLoggedOnUser().
. cmd.exe X: Y:. notepad.exe "" X: Y:. , , X: Y:.
Explorer Y: " ". Y: , cmd.exe, , .. . explorer.exe , X: Y:.
WinObj.exe SysInternals Win NT. :
- Sessions
- 0
- DosDevices
00000000-000057607
(57607 - , , )
"00000000-000057607":
Global SymbolicLink \Global??
X: SymbolicLink \\??\C:\test
Y: SymbolicLink \\??\C:\test
WinObj, dos . . NT.
, Explorer, - .