| 28 | |
| 29 | |
| 30 | ResultType Script::DoRunAs(LPTSTR aCommandLine, LPTSTR aWorkingDir, bool aDisplayErrors, WORD aShowWindow |
| 31 | , Var *aOutputVar, PROCESS_INFORMATION &aPI, bool &aSuccess // Output parameters we set for caller, but caller must have initialized aSuccess to false. |
| 32 | , HANDLE &aNewProcess, DWORD &aLastError) // Same, but initialize to NULL. |
| 33 | { |
| 34 | typedef BOOL (WINAPI *MyCreateProcessWithLogonW)( |
| 35 | LPCWSTR lpUsername, // user's name |
| 36 | LPCWSTR lpDomain, // user's domain |
| 37 | LPCWSTR lpPassword, // user's password |
| 38 | DWORD dwLogonFlags, // logon option |
| 39 | LPCWSTR lpApplicationName, // executable module name |
| 40 | LPWSTR lpCommandLine, // command-line string |
| 41 | DWORD dwCreationFlags, // creation flags |
| 42 | LPVOID lpEnvironment, // new environment block |
| 43 | LPCWSTR lpCurrentDirectory, // current directory name |
| 44 | LPSTARTUPINFOW lpStartupInfo, // startup information |
| 45 | LPPROCESS_INFORMATION lpProcessInfo // process information |
| 46 | ); |
| 47 | // Set up wide char version that we need for CreateProcessWithLogon |
| 48 | // init structure for running programs (wide char version) |
| 49 | STARTUPINFOW wsi = {0}; |
| 50 | wsi.cb = sizeof(STARTUPINFOW); |
| 51 | wsi.dwFlags = STARTF_USESHOWWINDOW; |
| 52 | wsi.wShowWindow = aShowWindow; |
| 53 | // The following are left initialized to 0/NULL (initialized earlier above): |
| 54 | //wsi.lpReserved = NULL; |
| 55 | //wsi.lpDesktop = NULL; |
| 56 | //wsi.lpTitle = NULL; |
| 57 | //wsi.cbReserved2 = 0; |
| 58 | //wsi.lpReserved2 = NULL; |
| 59 | |
| 60 | #ifndef UNICODE |
| 61 | // Convert to wide character format: |
| 62 | WCHAR command_line_wide[LINE_SIZE], working_dir_wide[MAX_PATH]; |
| 63 | ToWideChar(aCommandLine, command_line_wide, LINE_SIZE); // Dest. size is in wchars, not bytes. |
| 64 | if (aWorkingDir && *aWorkingDir) |
| 65 | ToWideChar(aWorkingDir, working_dir_wide, MAX_PATH); // Dest. size is in wchars, not bytes. |
| 66 | else |
| 67 | *working_dir_wide = 0; // wide-char terminator. |
| 68 | |
| 69 | if (lpfnDLLProc(mRunAsUser, mRunAsDomain, mRunAsPass, LOGON_WITH_PROFILE, 0 |
| 70 | , command_line_wide, 0, 0, *working_dir_wide ? working_dir_wide : NULL, &wsi, &aPI)) |
| 71 | #else |
| 72 | if (CreateProcessWithLogonW(mRunAsUser, mRunAsDomain, mRunAsPass, LOGON_WITH_PROFILE, 0 |
| 73 | , aCommandLine, 0, 0, aWorkingDir && *aWorkingDir ? aWorkingDir : NULL, &wsi, &aPI)) |
| 74 | #endif |
| 75 | { |
| 76 | aSuccess = true; |
| 77 | if (aPI.hThread) |
| 78 | CloseHandle(aPI.hThread); // Required to avoid memory leak. |
| 79 | aNewProcess = aPI.hProcess; |
| 80 | if (aOutputVar) |
| 81 | aOutputVar->Assign(aPI.dwProcessId); |
| 82 | } |
| 83 | else |
| 84 | aLastError = GetLastError(); // Caller will use this to get an error message and set g->LastError if needed. |
| 85 | return OK; |
| 86 | } |
| 87 | |