| 53 | } |
| 54 | |
| 55 | ULONG DistributionInfo::QueryUid(std::wstring_view userName) |
| 56 | { |
| 57 | // Create a pipe to read the output of the launched process. |
| 58 | HANDLE readPipe; |
| 59 | HANDLE writePipe; |
| 60 | SECURITY_ATTRIBUTES sa{sizeof(sa), nullptr, true}; |
| 61 | ULONG uid = UID_INVALID; |
| 62 | if (CreatePipe(&readPipe, &writePipe, &sa, 0)) |
| 63 | { |
| 64 | // Query the UID of the supplied username. |
| 65 | std::wstring command = L"/usr/bin/id -u "; |
| 66 | command += userName; |
| 67 | int returnValue = 0; |
| 68 | HANDLE child; |
| 69 | HRESULT hr = g_wslApi.WslLaunch(command.c_str(), true, GetStdHandle(STD_INPUT_HANDLE), writePipe, GetStdHandle(STD_ERROR_HANDLE), &child); |
| 70 | if (SUCCEEDED(hr)) |
| 71 | { |
| 72 | // Wait for the child to exit and ensure process exited successfully. |
| 73 | WaitForSingleObject(child, INFINITE); |
| 74 | DWORD exitCode; |
| 75 | if ((GetExitCodeProcess(child, &exitCode) == false) || (exitCode != 0)) |
| 76 | { |
| 77 | hr = E_INVALIDARG; |
| 78 | } |
| 79 | |
| 80 | CloseHandle(child); |
| 81 | if (SUCCEEDED(hr)) |
| 82 | { |
| 83 | char buffer[64]; |
| 84 | DWORD bytesRead; |
| 85 | |
| 86 | // Read the output of the command from the pipe and convert to a UID. |
| 87 | if (ReadFile(readPipe, buffer, (sizeof(buffer) - 1), &bytesRead, nullptr)) |
| 88 | { |
| 89 | buffer[bytesRead] = ANSI_NULL; |
| 90 | try |
| 91 | { |
| 92 | uid = std::stoul(buffer, nullptr, 10); |
| 93 | } |
| 94 | catch (...) |
| 95 | { |
| 96 | } |
| 97 | } |
| 98 | } |
| 99 | } |
| 100 | |
| 101 | CloseHandle(readPipe); |
| 102 | CloseHandle(writePipe); |
| 103 | } |
| 104 | |
| 105 | return uid; |
| 106 | } |