diff --git a/programs/wineconsole/wineconsole.c b/programs/wineconsole/wineconsole.c index 8752ec6b13d..c78a7f814b3 100644 --- a/programs/wineconsole/wineconsole.c +++ b/programs/wineconsole/wineconsole.c @@ -579,6 +579,53 @@ static BOOL WINECON_GetServerConfig(struct inner_data* data) return TRUE; } +/****************************************************************** + * WINECON_Spawn + * + * Spawn the child process when invoked with wineconsole foo bar + */ +static BOOL WINECON_Spawn(struct inner_data* data, LPWSTR cmdLine) +{ + PROCESS_INFORMATION info; + STARTUPINFOW startup; + BOOL done; + + /* we're in the case wineconsole ... spawn the new process */ + memset(&startup, 0, sizeof(startup)); + startup.cb = sizeof(startup); + startup.dwFlags = STARTF_USESTDHANDLES; + + /* the attributes of wineconsole's handles are not adequate for inheritance, so + * get them with the correct attributes before process creation + */ + if (!DuplicateHandle(GetCurrentProcess(), data->hConIn, GetCurrentProcess(), + &startup.hStdInput, GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE, TRUE, 0) || + !DuplicateHandle(GetCurrentProcess(), data->hConOut, GetCurrentProcess(), + &startup.hStdOutput, GENERIC_READ|GENERIC_WRITE, TRUE, 0) || + !DuplicateHandle(GetCurrentProcess(), data->hConOut, GetCurrentProcess(), + &startup.hStdError, GENERIC_READ|GENERIC_WRITE, TRUE, 0)) + { + WINE_ERR("Can't dup handles\n"); + /* no need to delete handles, we're exiting the program anyway */ + return FALSE; + } + + done = CreateProcessW(NULL, cmdLine, NULL, NULL, TRUE, 0L, NULL, NULL, &startup, &info); + if (done) + { + data->hProcess = info.hProcess; + CloseHandle(info.hThread); + } + else printf_res(IDS_CMD_LAUNCH_FAILED, wine_dbgstr_w(cmdLine)); + + /* we no longer need the handles passed to the child for the console */ + CloseHandle(startup.hStdInput); + CloseHandle(startup.hStdOutput); + CloseHandle(startup.hStdError); + + return done; +} + /****************************************************************** * WINECON_Init * @@ -587,7 +634,7 @@ static BOOL WINECON_GetServerConfig(struct inner_data* data) */ static struct inner_data* WINECON_Init(HINSTANCE hInst, DWORD pid, LPCWSTR appname, enum init_return (*backend)(struct inner_data*), - INT nCmdShow) + INT nCmdShow, WCHAR *cmdline) { struct condrv_input_info_params input_params; OBJECT_ATTRIBUTES attr = {sizeof(attr)}; @@ -708,7 +755,9 @@ static struct inner_data* WINECON_Init(HINSTANCE hInst, DWORD pid, LPCWSTR appna lstrlenW(appname) * sizeof(WCHAR), NULL, 0, NULL, NULL); if (!ret) goto error; + if (cmdline && !WINECON_Spawn(data, cmdline)) goto error; return data; + case init_failed: break; } @@ -720,52 +769,6 @@ static struct inner_data* WINECON_Init(HINSTANCE hInst, DWORD pid, LPCWSTR appna return NULL; } -/****************************************************************** - * WINECON_Spawn - * - * Spawn the child process when invoked with wineconsole foo bar - */ -static int WINECON_Spawn(struct inner_data* data, LPWSTR cmdLine) -{ - PROCESS_INFORMATION info; - STARTUPINFOW startup; - BOOL done; - - /* we're in the case wineconsole ... spawn the new process */ - memset(&startup, 0, sizeof(startup)); - startup.cb = sizeof(startup); - startup.dwFlags = STARTF_USESTDHANDLES; - - /* the attributes of wineconsole's handles are not adequate for inheritance, so - * get them with the correct attributes before process creation - */ - if (!DuplicateHandle(GetCurrentProcess(), data->hConIn, GetCurrentProcess(), - &startup.hStdInput, GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE, TRUE, 0) || - !DuplicateHandle(GetCurrentProcess(), data->hConOut, GetCurrentProcess(), - &startup.hStdOutput, GENERIC_READ|GENERIC_WRITE, TRUE, 0) || - !DuplicateHandle(GetCurrentProcess(), data->hConOut, GetCurrentProcess(), - &startup.hStdError, GENERIC_READ|GENERIC_WRITE, TRUE, 0)) - { - WINE_ERR("Can't dup handles\n"); - /* no need to delete handles, we're exiting the program anyway */ - return 1; - } - - done = CreateProcessW(NULL, cmdLine, NULL, NULL, TRUE, 0L, NULL, NULL, &startup, &info); - if (done) - { - data->hProcess = info.hProcess; - CloseHandle(info.hThread); - } - - /* we no longer need the handles passed to the child for the console */ - CloseHandle(startup.hStdInput); - CloseHandle(startup.hStdOutput); - CloseHandle(startup.hStdError); - - return !done; -} - struct wc_init { LPCSTR ptr; enum {from_event, from_process_name} mode; @@ -859,7 +862,7 @@ int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmdLine, INT nCmdSh { case from_event: /* case of wineconsole , signal process that created us that we're up and running */ - if (!(data = WINECON_Init(hInst, 0, NULL, wci.backend, nCmdShow))) return 1; + if (!(data = WINECON_Init(hInst, 0, NULL, wci.backend, nCmdShow, NULL))) return 1; ret = !SetEvent(wci.event); if (ret != 0) WINE_ERR("SetEvent failed.\n"); break; @@ -876,19 +879,9 @@ int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmdLine, INT nCmdSh MultiByteToWideChar(CP_ACP, 0, wci.ptr, -1, buffer, len); - if (!(data = WINECON_Init(hInst, GetCurrentProcessId(), buffer, wci.backend, nCmdShow))) - { - HeapFree(GetProcessHeap(), 0, buffer); - return 1; - } - ret = WINECON_Spawn(data, buffer); + data = WINECON_Init(hInst, GetCurrentProcessId(), buffer, wci.backend, nCmdShow, buffer); HeapFree(GetProcessHeap(), 0, buffer); - if (ret != 0) - { - WINECON_Delete(data); - printf_res(IDS_CMD_LAUNCH_FAILED, wine_dbgstr_a(wci.ptr)); - return ret; - } + if (!data) return 1; } break; default: