aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/libs/dutil/WixToolset.DUtil/rmutil.cpp55
1 files changed, 27 insertions, 28 deletions
diff --git a/src/libs/dutil/WixToolset.DUtil/rmutil.cpp b/src/libs/dutil/WixToolset.DUtil/rmutil.cpp
index 95c8c8a4..a73ffde1 100644
--- a/src/libs/dutil/WixToolset.DUtil/rmutil.cpp
+++ b/src/libs/dutil/WixToolset.DUtil/rmutil.cpp
@@ -168,41 +168,40 @@ extern "C" HRESULT DAPI RmuAddProcessById(
168 DWORD cbPrevPriv = 0; 168 DWORD cbPrevPriv = 0;
169 DWORD er = ERROR_SUCCESS; 169 DWORD er = ERROR_SUCCESS;
170 BOOL fAdjustedPrivileges = FALSE; 170 BOOL fAdjustedPrivileges = FALSE;
171 BOOL fElevated = FALSE;
172 ProcElevated(::GetCurrentProcess(), &fElevated);
173
174 // Must be elevated to adjust process privileges
175 if (fElevated) {
176 // Adding SeDebugPrivilege in the event that the process targeted by ::OpenProcess() is in a another user context.
177 if (!::OpenProcessToken(::GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hToken))
178 {
179 RmExitWithLastError(hr, "Failed to get process token.");
180 }
181 171
172 // Best-effort attempt to enable SeDebugPrivilege in case the target process is in another user context.
173 if (::OpenProcessToken(::GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hToken))
174 {
182 priv.PrivilegeCount = 1; 175 priv.PrivilegeCount = 1;
183 priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 176 priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
184 if (!::LookupPrivilegeValueW(NULL, L"SeDebugPrivilege", &priv.Privileges[0].Luid)) 177 if (::LookupPrivilegeValueW(NULL, L"SeDebugPrivilege", &priv.Privileges[0].Luid))
185 {
186 RmExitWithLastError(hr, "Failed to get debug privilege LUID.");
187 }
188
189 cbPrevPriv = sizeof(TOKEN_PRIVILEGES);
190 pPrevPriv = static_cast<TOKEN_PRIVILEGES*>(MemAlloc(cbPrevPriv, TRUE));
191 RmExitOnNull(pPrevPriv, hr, E_OUTOFMEMORY, "Failed to allocate memory for empty previous privileges.");
192
193 if (!::AdjustTokenPrivileges(hToken, FALSE, &priv, cbPrevPriv, pPrevPriv, &cbPrevPriv))
194 { 178 {
195 LPVOID pv = MemReAlloc(pPrevPriv, cbPrevPriv, TRUE); 179 cbPrevPriv = sizeof(TOKEN_PRIVILEGES);
196 RmExitOnNull(pv, hr, E_OUTOFMEMORY, "Failed to allocate memory for previous privileges."); 180 pPrevPriv = static_cast<TOKEN_PRIVILEGES*>(MemAlloc(cbPrevPriv, TRUE));
197 pPrevPriv = static_cast<TOKEN_PRIVILEGES*>(pv); 181 if (pPrevPriv)
198
199 if (!::AdjustTokenPrivileges(hToken, FALSE, &priv, cbPrevPriv, pPrevPriv, &cbPrevPriv))
200 { 182 {
201 RmExitWithLastError(hr, "Failed to get debug privilege LUID."); 183 fAdjustedPrivileges = ::AdjustTokenPrivileges(hToken, FALSE, &priv, cbPrevPriv, pPrevPriv, &cbPrevPriv);
184 er = ::GetLastError(); // AdjustTokenPrivileges may succeed but still return ERROR_NOT_ALL_ASSIGNED.
185
186 if (!fAdjustedPrivileges && ERROR_INSUFFICIENT_BUFFER == er)
187 {
188 LPVOID pv = MemReAlloc(pPrevPriv, cbPrevPriv, TRUE);
189 pPrevPriv = static_cast<TOKEN_PRIVILEGES*>(pv);
190
191 if (pPrevPriv)
192 {
193 fAdjustedPrivileges = ::AdjustTokenPrivileges(hToken, FALSE, &priv, cbPrevPriv, pPrevPriv, &cbPrevPriv);
194 er = ::GetLastError(); // AdjustTokenPrivileges may succeed but still return ERROR_NOT_ALL_ASSIGNED.
195 }
196 }
197
198 // We actually only adjusted privileges if the privilege was assigned AND *succeeded*.
199 if (ERROR_SUCCESS != er)
200 {
201 fAdjustedPrivileges = FALSE;
202 }
202 } 203 }
203 } 204 }
204
205 fAdjustedPrivileges = TRUE;
206 } 205 }
207 206
208 hProcess = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwProcessId); 207 hProcess = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwProcessId);