diff options
| -rw-r--r-- | src/libs/dutil/WixToolset.DUtil/rmutil.cpp | 55 |
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); |
