none
Interaktiven Prozess von Windows Service aus starten RRS feed

  • Allgemeine Diskussion

  • Hallo Leute,

    ich muss von einem Windows Dienst aus eine Applikation auf dem interaktiven Desktop (interaktiver User) starten. Soweit keine Probleme, wenn der Service unter LocalSystem läuft:

    DWORD dwSessionId = WTSGetActiveConsoleSessionId();
    if (dwSessionId != 0xFFFFFFFF)
    {
        if (WTSQueryUserToken(dwSessionId, &hUserToken))
        {
    	sa.bInheritHandle = TRUE;
    	pStartupInfo->cb = sizeof(*pStartupInfo);
    	pStartupInfo->lpDesktop = "winsta0\\default";
    
    	if (ImpersonateLoggedOnUser(hUserToken))
    	{
    		bRet = CreateProcessAsUser(hUserToken, szFile, szCmdLine, &sa, &sa, FALSE, dwCreationFlags, NULL, szPath, pStartupInfo, pProcessInfo);
    		RevertToSelf();
    	}
    	CloseHandle(hUserToken);
    }


    Wenn der Dienst jetzt aber unter einem anderen Konto läuft (z.B. eigener Domänen-Account), funktioniert natürlich WTSQueryUserToken nicht mehr.

    Also versuche ich es so:

    else if (GetLastError() == ERROR_PRIVILEGE_NOT_HELD || GetLastError() == ERROR_ACCESS_DENIED)
    {
    	DWORD dwProcSessionId = 0, dwProcId = 0;
    	PROCESSENTRY32 PEntry = {0};
    	HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    	if (hSnapShot == INVALID_HANDLE_VALUE)
    		return FALSE;
    
    	PEntry.dwSize = sizeof(PEntry);
    	BOOL bOK = Process32First(hSnapShot, &PEntry);
    	for(; bOK; bOK = Process32Next(hSnapShot, &PEntry))
    	{
    		if (strcmp(PEntry.szExeFile, "explorer.exe") == 0)
    		{
    			if (ProcessIdToSessionId(PEntry.th32ProcessID, &dwProcSessionId) && dwProcSessionId == dwSessionId)
    			{
    				dwProcId = PEntry.th32ProcessID;
    				bFound = TRUE;
    				break;
    			}
    		}
    	}
    	CloseHandle(hSnapShot);
    
    
    	if (bFound)
    	{
    		HANDLE hOwnToken = NULL;
    		if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hOwnToken))
    		{
    			LUID luid = {0};
    			TOKEN_PRIVILEGES adjTokenPrivileges = {0};
    	
    			if (LookupPrivilegeValue(NULL, SE_TCB_NAME, &luid))
    			{
    				adjTokenPrivileges.PrivilegeCount = 1;
    				adjTokenPrivileges.Privileges[0].Luid = luid;
    				adjTokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    				bRet = AdjustTokenPrivileges(hOwnToken, FALSE, &adjTokenPrivileges, sizeof(adjTokenPrivileges), NULL, NULL);
    			}
    			if (LookupPrivilegeValue(NULL, SE_INCREASE_QUOTA_NAME, &luid))
    			{
    				adjTokenPrivileges.PrivilegeCount = 1;
    				adjTokenPrivileges.Privileges[0].Luid = luid;
    				adjTokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    				bRet = AdjustTokenPrivileges(hOwnToken, FALSE, &adjTokenPrivileges, sizeof(adjTokenPrivileges), NULL, NULL);
    			}
    			if (LookupPrivilegeValue(NULL, SE_ASSIGNPRIMARYTOKEN_NAME, &luid))
    			{
    				adjTokenPrivileges.PrivilegeCount = 1;
    				adjTokenPrivileges.Privileges[0].Luid = luid;
    				adjTokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    				bRet = AdjustTokenPrivileges(hOwnToken, FALSE, &adjTokenPrivileges, sizeof(adjTokenPrivileges), NULL, NULL);
    			}
    			CloseHandle(hOwnToken);
    		}
    
    		HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwProcId);
    		if (hProcess)
    		{
    			HANDLE hToken = NULL;
    			if (OpenProcessToken(hProcess, TOKEN_DUPLICATE, &hToken))
    			{
    				pStartupInfo->cb = sizeof(*pStartupInfo);
    				pStartupInfo->lpDesktop = "winsta0\\default";
    
    				if (DuplicateTokenEx(hToken, MAXIMUM_ALLOWED/*TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE | TOKEN_QUERY*/, &sa, SecurityImpersonation, TokenPrimary, &hUserToken))
    				{
    					bRet = CreateProcessAsUser(hUserToken, szFile, szCmdLine, &sa, &sa, FALSE, CREATE_NEW_CONSOLE, NULL, szPath, pStartupInfo, pProcessInfo);
    						
    					CloseHandle(hUserToken);
    				}
    				CloseHandle(hToken);
    			}
    			CloseHandle(hProcess);
    		}
    	}
    }

    Erhalte aber wieder nur auf CreateProcessAsUser ERROR_PRIVILEGE_NOT_HELD, bei Verwendung von CreateProcessWithLogonW ERROR_ACCESS_DENIED.

    Wie kann ich also eine GUI Applikation unter dem interaktiven User starten, wenn mein Dienst z.B. unter demselben User läuft ??

    Log On des Users ist kein Problem, es wird davon ausgegangen, dass dieser Benutzer angemeldet ist...

    Vielen Dank im Voraus, hoffe es war verständlich. :)


    Donnerstag, 10. Mai 2012 07:57

Alle Antworten