| 38 | } |
| 39 | |
| 40 | py::tuple CreateProcessWithDllEx( |
| 41 | // positional-only args, like _winapi.CreateProcess |
| 42 | std::optional<std::wstring> application_name, std::optional<std::wstring> command_line, py::object proc_attrs_obj, |
| 43 | py::object thread_attrs_obj, bool inherit_handles, std::uint32_t creation_flags, |
| 44 | std::map<std::wstring, std::wstring> env, std::optional<std::wstring> current_directory, |
| 45 | py::object startup_info_obj, |
| 46 | // keyword-only |
| 47 | const std::string &dll_name) |
| 48 | { |
| 49 | STARTUPINFOEXW si; |
| 50 | ZeroMemory(&si, sizeof(si)); |
| 51 | si.StartupInfo.cb = sizeof(si); |
| 52 | si.StartupInfo.dwFlags = startup_info_obj.attr("dwFlags").cast<DWORD>(); |
| 53 | si.StartupInfo.wShowWindow = startup_info_obj.attr("wShowWindow").cast<WORD>(); |
| 54 | si.StartupInfo.hStdInput = get_handle(startup_info_obj, "hStdInput"); |
| 55 | si.StartupInfo.hStdOutput = get_handle(startup_info_obj, "hStdOutput"); |
| 56 | si.StartupInfo.hStdError = get_handle(startup_info_obj, "hStdError"); |
| 57 | |
| 58 | LPVOID lpEnvironment = nullptr; |
| 59 | std::wstring env_block; |
| 60 | if (!env.empty()) { |
| 61 | for (const auto &[key, value] : env) { |
| 62 | env_block += key + L"=" + value + L'\0'; |
| 63 | } |
| 64 | env_block += L'\0'; // Double null-terminate |
| 65 | lpEnvironment = env_block.data(); |
| 66 | } |
| 67 | |
| 68 | std::wstring app, cmd, cwd; |
| 69 | LPCWSTR lpAppName = nullptr; |
| 70 | LPCWSTR lpCwd = nullptr; |
| 71 | LPWSTR lpCmdLine = nullptr; |
| 72 | |
| 73 | if (application_name) { |
| 74 | app = application_name.value(); |
| 75 | lpAppName = app.c_str(); |
| 76 | } |
| 77 | if (command_line) { |
| 78 | cmd = command_line.value(); |
| 79 | lpCmdLine = &cmd[0]; // API expects mutable LPSTR |
| 80 | } |
| 81 | if (current_directory) { |
| 82 | cwd = current_directory.value(); |
| 83 | lpCwd = cwd.c_str(); |
| 84 | } |
| 85 | |
| 86 | PROCESS_INFORMATION pi; |
| 87 | ZeroMemory(&pi, sizeof(pi)); |
| 88 | |
| 89 | BOOL ok = DetourCreateProcessWithDllExW( |
| 90 | lpAppName, // Path of the executable to launch |
| 91 | lpCmdLine, // Command line (empty/null) |
| 92 | nullptr, // Process security attributes |
| 93 | nullptr, // Thread security attributes |
| 94 | inherit_handles ? TRUE : FALSE, // Inherit handles |
| 95 | creation_flags | EXTENDED_STARTUPINFO_PRESENT | CREATE_UNICODE_ENVIRONMENT, // Creation flags |
| 96 | lpEnvironment, // Environment block |
| 97 | lpCwd, // Current directory |
nothing calls this directly
no test coverage detected