aboutsummaryrefslogtreecommitdiff
path: root/src/libs/dutil/WixToolset.DUtil/proc3utl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/dutil/WixToolset.DUtil/proc3utl.cpp')
-rw-r--r--src/libs/dutil/WixToolset.DUtil/proc3utl.cpp129
1 files changed, 129 insertions, 0 deletions
diff --git a/src/libs/dutil/WixToolset.DUtil/proc3utl.cpp b/src/libs/dutil/WixToolset.DUtil/proc3utl.cpp
new file mode 100644
index 00000000..6d3cbc67
--- /dev/null
+++ b/src/libs/dutil/WixToolset.DUtil/proc3utl.cpp
@@ -0,0 +1,129 @@
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
5
6// Exit macros
7#define ProcExitOnLastError(x, s, ...) ExitOnLastErrorSource(DUTIL_SOURCE_PROCUTIL, x, s, __VA_ARGS__)
8#define ProcExitOnLastErrorDebugTrace(x, s, ...) ExitOnLastErrorDebugTraceSource(DUTIL_SOURCE_PROCUTIL, x, s, __VA_ARGS__)
9#define ProcExitWithLastError(x, s, ...) ExitWithLastErrorSource(DUTIL_SOURCE_PROCUTIL, x, s, __VA_ARGS__)
10#define ProcExitOnFailure(x, s, ...) ExitOnFailureSource(DUTIL_SOURCE_PROCUTIL, x, s, __VA_ARGS__)
11#define ProcExitOnRootFailure(x, s, ...) ExitOnRootFailureSource(DUTIL_SOURCE_PROCUTIL, x, s, __VA_ARGS__)
12#define ProcExitOnFailureDebugTrace(x, s, ...) ExitOnFailureDebugTraceSource(DUTIL_SOURCE_PROCUTIL, x, s, __VA_ARGS__)
13#define ProcExitOnNull(p, x, e, s, ...) ExitOnNullSource(DUTIL_SOURCE_PROCUTIL, p, x, e, s, __VA_ARGS__)
14#define ProcExitOnNullWithLastError(p, x, s, ...) ExitOnNullWithLastErrorSource(DUTIL_SOURCE_PROCUTIL, p, x, s, __VA_ARGS__)
15#define ProcExitOnNullDebugTrace(p, x, e, s, ...) ExitOnNullDebugTraceSource(DUTIL_SOURCE_PROCUTIL, p, x, e, s, __VA_ARGS__)
16#define ProcExitOnInvalidHandleWithLastError(p, x, s, ...) ExitOnInvalidHandleWithLastErrorSource(DUTIL_SOURCE_PROCUTIL, p, x, s, __VA_ARGS__)
17#define ProcExitOnWin32Error(e, x, s, ...) ExitOnWin32ErrorSource(DUTIL_SOURCE_PROCUTIL, e, x, s, __VA_ARGS__)
18#define ProcExitOnGdipFailure(g, x, s, ...) ExitOnGdipFailureSource(DUTIL_SOURCE_PROCUTIL, g, x, s, __VA_ARGS__)
19
20static HRESULT GetActiveSessionUserToken(
21 __out HANDLE *phToken
22 );
23
24
25/********************************************************************
26 ProcExecuteAsInteractiveUser() - runs process as currently logged in
27 user.
28*******************************************************************/
29extern "C" HRESULT DAPI ProcExecuteAsInteractiveUser(
30 __in_z LPCWSTR wzExecutablePath,
31 __in_z LPCWSTR wzCommandLine,
32 __out HANDLE *phProcess
33 )
34{
35 HRESULT hr = S_OK;
36 HANDLE hToken = NULL;
37 LPVOID pEnvironment = NULL;
38 LPWSTR sczFullCommandLine = NULL;
39 STARTUPINFOW si = { };
40 PROCESS_INFORMATION pi = { };
41
42 hr = GetActiveSessionUserToken(&hToken);
43 ProcExitOnFailure(hr, "Failed to get active session user token.");
44
45 if (!::CreateEnvironmentBlock(&pEnvironment, hToken, FALSE))
46 {
47 ProcExitWithLastError(hr, "Failed to create environment block for UI process.");
48 }
49
50 hr = StrAllocFormatted(&sczFullCommandLine, L"\"%ls\" %ls", wzExecutablePath, wzCommandLine);
51 ProcExitOnFailure(hr, "Failed to allocate full command-line.");
52
53 si.cb = sizeof(si);
54 if (!::CreateProcessAsUserW(hToken, wzExecutablePath, sczFullCommandLine, NULL, NULL, FALSE, CREATE_UNICODE_ENVIRONMENT, pEnvironment, NULL, &si, &pi))
55 {
56 ProcExitWithLastError(hr, "Failed to create UI process: %ls", sczFullCommandLine);
57 }
58
59 *phProcess = pi.hProcess;
60 pi.hProcess = NULL;
61
62LExit:
63 ReleaseHandle(pi.hThread);
64 ReleaseHandle(pi.hProcess);
65 ReleaseStr(sczFullCommandLine);
66
67 if (pEnvironment)
68 {
69 ::DestroyEnvironmentBlock(pEnvironment);
70 }
71
72 ReleaseHandle(hToken);
73
74 return hr;
75}
76
77
78static HRESULT GetActiveSessionUserToken(
79 __out HANDLE *phToken
80 )
81{
82 HRESULT hr = S_OK;
83 PWTS_SESSION_INFO pSessionInfo = NULL;
84 DWORD cSessions = 0;
85 DWORD dwSessionId = 0;
86 BOOL fSessionFound = FALSE;
87 HANDLE hToken = NULL;
88
89 // Loop through the sessions looking for the active one.
90 if (!::WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &pSessionInfo, &cSessions))
91 {
92 ProcExitWithLastError(hr, "Failed to enumerate sessions.");
93 }
94
95 for (DWORD i = 0; i < cSessions; ++i)
96 {
97 if (WTSActive == pSessionInfo[i].State)
98 {
99 dwSessionId = pSessionInfo[i].SessionId;
100 fSessionFound = TRUE;
101
102 break;
103 }
104 }
105
106 if (!fSessionFound)
107 {
108 ExitFunction1(hr = E_NOTFOUND);
109 }
110
111 // Get the user token from the active session.
112 if (!::WTSQueryUserToken(dwSessionId, &hToken))
113 {
114 ProcExitWithLastError(hr, "Failed to get active session user token.");
115 }
116
117 *phToken = hToken;
118 hToken = NULL;
119
120LExit:
121 ReleaseHandle(hToken);
122
123 if (pSessionInfo)
124 {
125 ::WTSFreeMemory(pSessionInfo);
126 }
127
128 return hr;
129}