| 94 | } |
| 95 | |
| 96 | int RestartAsAdministrator( |
| 97 | int argc, |
| 98 | wchar_t** argv) |
| 99 | { |
| 100 | // Get the exe path |
| 101 | wchar_t exe_path[MAX_PATH] = {}; |
| 102 | GetModuleFileNameW(NULL, exe_path, _countof(exe_path)); |
| 103 | |
| 104 | // Combine arguments into single string and remove --restart_as_admin to |
| 105 | // prevent an endless loop if the escalation fails. |
| 106 | std::wstring args; |
| 107 | for (int i = 1; i < argc; ++i) { |
| 108 | if (IsRestartAsAdminArg(argv[i])) continue; |
| 109 | |
| 110 | auto addQuotes = argv[i][0] != L'\"' && wcschr(argv[i], L' ') != nullptr; |
| 111 | if (addQuotes) { |
| 112 | args += L'\"'; |
| 113 | } |
| 114 | |
| 115 | args += argv[i]; |
| 116 | |
| 117 | if (addQuotes) { |
| 118 | args += L'\"'; |
| 119 | } |
| 120 | |
| 121 | args += L' '; |
| 122 | } |
| 123 | |
| 124 | // Re-run the process with the runas verb |
| 125 | DWORD code = 2; |
| 126 | |
| 127 | SHELLEXECUTEINFO info = {}; |
| 128 | info.cbSize = sizeof(info); |
| 129 | info.fMask = SEE_MASK_NOCLOSEPROCESS; // return info.hProcess for explicit wait |
| 130 | info.lpVerb = L"runas"; |
| 131 | info.lpFile = exe_path; |
| 132 | info.lpParameters = args.c_str(); |
| 133 | info.nShow = SW_SHOWDEFAULT; |
| 134 | auto ok = ShellExecuteEx(&info); |
| 135 | if (ok) { |
| 136 | WaitForSingleObject(info.hProcess, INFINITE); |
| 137 | GetExitCodeProcess(info.hProcess, &code); |
| 138 | CloseHandle(info.hProcess); |
| 139 | } else { |
| 140 | PrintError(L"error: failed to elevate privilege: "); |
| 141 | int e = GetLastError(); |
| 142 | switch (e) { |
| 143 | case ERROR_FILE_NOT_FOUND: PrintError(L"file not found.\n"); break; |
| 144 | case ERROR_PATH_NOT_FOUND: PrintError(L"path not found.\n"); break; |
| 145 | case ERROR_DLL_NOT_FOUND: PrintError(L"dll not found.\n"); break; |
| 146 | case ERROR_ACCESS_DENIED: PrintError(L"access denied.\n"); break; |
| 147 | case ERROR_CANCELLED: PrintError(L"cancelled.\n"); break; |
| 148 | case ERROR_NOT_ENOUGH_MEMORY: PrintError(L"out of memory.\n"); break; |
| 149 | case ERROR_SHARING_VIOLATION: PrintError(L"sharing violation.\n"); break; |
| 150 | default: PrintError(L"error code %u.\n", e); break; |
| 151 | } |
| 152 | } |
| 153 |
no test coverage detected