| 451 | } |
| 452 | |
| 453 | BOOL CreateProcessInJobAsAdmin( |
| 454 | HANDLE hJob, |
| 455 | LPCTSTR lpApplicationName, |
| 456 | LPTSTR lpCommandLine, |
| 457 | int nShow, |
| 458 | LPCTSTR lpCurrentDirectory, |
| 459 | LPPROCESS_INFORMATION ppi) |
| 460 | { |
| 461 | SHELLEXECUTEINFOW sei = { sizeof(sei) }; |
| 462 | sei.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI; |
| 463 | sei.lpVerb = L"runas"; |
| 464 | sei.lpFile = lpApplicationName; |
| 465 | sei.lpParameters = lpCommandLine; |
| 466 | sei.lpDirectory = lpCurrentDirectory; |
| 467 | sei.nShow = nShow; |
| 468 | |
| 469 | BOOL fRc = ShellExecuteEx(&sei); |
| 470 | if (fRc) |
| 471 | { |
| 472 | ppi->hProcess = sei.hProcess; |
| 473 | ppi->hThread = NULL; // Thread handle is not available from ShellExecuteEx |
| 474 | ppi->dwProcessId = GetProcessId(sei.hProcess); |
| 475 | ppi->dwThreadId = 0; // Thread ID is not available |
| 476 | fRc = AssignProcessToJobObject(hJob, ppi->hProcess); |
| 477 | if (!fRc) |
| 478 | { |
| 479 | TerminateProcess(ppi->hProcess, 0); |
| 480 | CloseHandle(ppi->hProcess); |
| 481 | ppi->hProcess = NULL; |
| 482 | } |
| 483 | } |
| 484 | return fRc; |
| 485 | } |
nothing calls this directly
no outgoing calls
no test coverage detected