aboutsummaryrefslogtreecommitdiff
path: root/src/dutil/proc3utl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/dutil/proc3utl.cpp')
-rw-r--r--src/dutil/proc3utl.cpp114
1 files changed, 114 insertions, 0 deletions
diff --git a/src/dutil/proc3utl.cpp b/src/dutil/proc3utl.cpp
new file mode 100644
index 00000000..038f002b
--- /dev/null
+++ b/src/dutil/proc3utl.cpp
@@ -0,0 +1,114 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3#include "precomp.h"
4
5static HRESULT GetActiveSessionUserToken(
6 __out HANDLE *phToken
7 );
8
9
10/********************************************************************
11 ProcExecuteAsInteractiveUser() - runs process as currently logged in
12 user.
13*******************************************************************/
14extern "C" HRESULT DAPI ProcExecuteAsInteractiveUser(
15 __in_z LPCWSTR wzExecutablePath,
16 __in_z LPCWSTR wzCommandLine,
17 __out HANDLE *phProcess
18 )
19{
20 HRESULT hr = S_OK;
21 HANDLE hToken = NULL;
22 LPVOID pEnvironment = NULL;
23 LPWSTR sczFullCommandLine = NULL;
24 STARTUPINFOW si = { };
25 PROCESS_INFORMATION pi = { };
26
27 hr = GetActiveSessionUserToken(&hToken);
28 ExitOnFailure(hr, "Failed to get active session user token.");
29
30 if (!::CreateEnvironmentBlock(&pEnvironment, hToken, FALSE))
31 {
32 ExitWithLastError(hr, "Failed to create environment block for UI process.");
33 }
34
35 hr = StrAllocFormatted(&sczFullCommandLine, L"\"%ls\" %ls", wzExecutablePath, wzCommandLine);
36 ExitOnFailure(hr, "Failed to allocate full command-line.");
37
38 si.cb = sizeof(si);
39 if (!::CreateProcessAsUserW(hToken, wzExecutablePath, sczFullCommandLine, NULL, NULL, FALSE, CREATE_UNICODE_ENVIRONMENT, pEnvironment, NULL, &si, &pi))
40 {
41 ExitWithLastError(hr, "Failed to create UI process: %ls", sczFullCommandLine);
42 }
43
44 *phProcess = pi.hProcess;
45 pi.hProcess = NULL;
46
47LExit:
48 ReleaseHandle(pi.hThread);
49 ReleaseHandle(pi.hProcess);
50 ReleaseStr(sczFullCommandLine);
51
52 if (pEnvironment)
53 {
54 ::DestroyEnvironmentBlock(pEnvironment);
55 }
56
57 ReleaseHandle(hToken);
58
59 return hr;
60}
61
62
63static HRESULT GetActiveSessionUserToken(
64 __out HANDLE *phToken
65 )
66{
67 HRESULT hr = S_OK;
68 PWTS_SESSION_INFO pSessionInfo = NULL;
69 DWORD cSessions = 0;
70 DWORD dwSessionId = 0;
71 BOOL fSessionFound = FALSE;
72 HANDLE hToken = NULL;
73
74 // Loop through the sessions looking for the active one.
75 if (!::WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &pSessionInfo, &cSessions))
76 {
77 ExitWithLastError(hr, "Failed to enumerate sessions.");
78 }
79
80 for (DWORD i = 0; i < cSessions; ++i)
81 {
82 if (WTSActive == pSessionInfo[i].State)
83 {
84 dwSessionId = pSessionInfo[i].SessionId;
85 fSessionFound = TRUE;
86
87 break;
88 }
89 }
90
91 if (!fSessionFound)
92 {
93 ExitFunction1(hr = E_NOTFOUND);
94 }
95
96 // Get the user token from the active session.
97 if (!::WTSQueryUserToken(dwSessionId, &hToken))
98 {
99 ExitWithLastError(hr, "Failed to get active session user token.");
100 }
101
102 *phToken = hToken;
103 hToken = NULL;
104
105LExit:
106 ReleaseHandle(hToken);
107
108 if (pSessionInfo)
109 {
110 ::WTSFreeMemory(pSessionInfo);
111 }
112
113 return hr;
114}