From 45ade6c2f57adaa9bde009063d3d5b9294dc5d35 Mon Sep 17 00:00:00 2001 From: Eric Pouech Date: Mon, 30 Aug 2010 22:19:18 +0200 Subject: [PATCH] ntdll: Allocate a console (without renderer) when starting a program from unix console. --- dlls/kernel32/console.c | 47 ++++++++++++++++++++++++++++++++++ dlls/kernel32/kernel_main.c | 21 ++------------- dlls/kernel32/kernel_private.h | 5 ++++ dlls/kernel32/process.c | 2 +- dlls/ntdll/thread.c | 14 +++++----- 5 files changed, 63 insertions(+), 26 deletions(-) diff --git a/dlls/kernel32/console.c b/dlls/kernel32/console.c index d760b658cff..e575d17940c 100644 --- a/dlls/kernel32/console.c +++ b/dlls/kernel32/console.c @@ -2715,3 +2715,50 @@ DWORD WINAPI GetConsoleProcessList(LPDWORD processlist, DWORD processcount) return 0; } + +BOOL CONSOLE_Init(RTL_USER_PROCESS_PARAMETERS *params) +{ + if (params->ConsoleHandle == KERNEL32_CONSOLE_SHELL) + { + HANDLE conin; + + /* FIXME: to be done even if program is a GUI ? */ + /* This is wine specific: we have no parent (we're started from unix) + * so, create a simple console with bare handles + */ + SERVER_START_REQ( alloc_console ) + { + req->access = GENERIC_READ | GENERIC_WRITE; + req->attributes = OBJ_INHERIT; + req->pid = 0xffffffff; + wine_server_call( req ); + conin = wine_server_ptr_handle( reply->handle_in ); + /* reply->event shouldn't be created by server */ + } + SERVER_END_REQ; + + if (!params->hStdInput) + params->hStdInput = conin; + } + + /* convert value from server: + * + 0 => INVALID_HANDLE_VALUE + * + console handle needs to be mapped + */ + if (!params->hStdInput) + params->hStdInput = INVALID_HANDLE_VALUE; + else if (VerifyConsoleIoHandle(console_handle_map(params->hStdInput))) + params->hStdInput = console_handle_map(params->hStdInput); + + if (!params->hStdOutput) + params->hStdOutput = INVALID_HANDLE_VALUE; + else if (VerifyConsoleIoHandle(console_handle_map(params->hStdOutput))) + params->hStdOutput = console_handle_map(params->hStdOutput); + + if (!params->hStdError) + params->hStdError = INVALID_HANDLE_VALUE; + else if (VerifyConsoleIoHandle(console_handle_map(params->hStdError))) + params->hStdError = console_handle_map(params->hStdError); + + return TRUE; +} diff --git a/dlls/kernel32/kernel_main.c b/dlls/kernel32/kernel_main.c index 2308d60fe2a..41647dd60cd 100644 --- a/dlls/kernel32/kernel_main.c +++ b/dlls/kernel32/kernel_main.c @@ -96,24 +96,7 @@ static BOOL process_attach( HMODULE module ) /* Setup computer name */ COMPUTERNAME_Init(); - /* convert value from server: - * + 0 => INVALID_HANDLE_VALUE - * + console handle needs to be mapped - */ - if (!params->hStdInput) - params->hStdInput = INVALID_HANDLE_VALUE; - else if (VerifyConsoleIoHandle(console_handle_map(params->hStdInput))) - params->hStdInput = console_handle_map(params->hStdInput); - - if (!params->hStdOutput) - params->hStdOutput = INVALID_HANDLE_VALUE; - else if (VerifyConsoleIoHandle(console_handle_map(params->hStdOutput))) - params->hStdOutput = console_handle_map(params->hStdOutput); - - if (!params->hStdError) - params->hStdError = INVALID_HANDLE_VALUE; - else if (VerifyConsoleIoHandle(console_handle_map(params->hStdError))) - params->hStdError = console_handle_map(params->hStdError); + CONSOLE_Init(params); /* copy process information from ntdll */ ENV_CopyStartupInformation(); @@ -128,7 +111,7 @@ static BOOL process_attach( HMODULE module ) /* finish the process initialisation for console bits, if needed */ __wine_set_signal_handler(SIGINT, CONSOLE_HandleCtrlC); - if (params->ConsoleHandle == (HANDLE)1) /* FIXME */ + if (params->ConsoleHandle == KERNEL32_CONSOLE_ALLOC) { HMODULE mod = GetModuleHandleA(0); if (RtlImageNtHeader(mod)->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI) diff --git a/dlls/kernel32/kernel_private.h b/dlls/kernel32/kernel_private.h index 4b295e7f63e..f741a92c294 100644 --- a/dlls/kernel32/kernel_private.h +++ b/dlls/kernel32/kernel_private.h @@ -28,6 +28,7 @@ BOOL WINAPI VerifyConsoleIoHandle(HANDLE); HANDLE WINAPI DuplicateConsoleHandle(HANDLE, DWORD, BOOL, DWORD); BOOL WINAPI CloseConsoleHandle(HANDLE handle); HANDLE WINAPI GetConsoleInputWaitHandle(void); +BOOL CONSOLE_Init(RTL_USER_PROCESS_PARAMETERS *params); static inline BOOL is_console_handle(HANDLE h) { @@ -46,6 +47,10 @@ static inline obj_handle_t console_handle_unmap(HANDLE h) return wine_server_obj_handle( h != INVALID_HANDLE_VALUE ? (HANDLE)((UINT_PTR)h ^ 3) : INVALID_HANDLE_VALUE ); } +/* Some Wine specific values for Console inheritance (params->ConsoleHandle) */ +#define KERNEL32_CONSOLE_ALLOC ((HANDLE)1) +#define KERNEL32_CONSOLE_SHELL ((HANDLE)2) + extern HMODULE kernel32_handle; extern const WCHAR *DIR_Windows; diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c index ef65a8636e5..c1816a84e6f 100644 --- a/dlls/kernel32/process.c +++ b/dlls/kernel32/process.c @@ -1527,7 +1527,7 @@ static startup_info_t *create_startup_info( LPCWSTR filename, LPCWSTR cmdline, info->console_flags = cur_params->ConsoleFlags; if (flags & CREATE_NEW_PROCESS_GROUP) info->console_flags = 1; - if (flags & CREATE_NEW_CONSOLE) info->console = (obj_handle_t)1; /* FIXME: cf. kernel_main.c */ + if (flags & CREATE_NEW_CONSOLE) info->console = wine_server_obj_handle(KERNEL32_CONSOLE_ALLOC); if (startup->dwFlags & STARTF_USESTDHANDLES) { diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c index 36f1499c1d2..df6c3e29f24 100644 --- a/dlls/ntdll/thread.c +++ b/dlls/ntdll/thread.c @@ -276,12 +276,14 @@ HANDLE thread_init(void) } else { - /* This is wine specific: we have no parent (we're started from unix) - * so, create a simple console with bare handles to unix stdio - */ - wine_server_fd_to_handle( 0, GENERIC_READ|SYNCHRONIZE, OBJ_INHERIT, ¶ms.hStdInput ); - wine_server_fd_to_handle( 1, GENERIC_WRITE|SYNCHRONIZE, OBJ_INHERIT, ¶ms.hStdOutput ); - wine_server_fd_to_handle( 2, GENERIC_WRITE|SYNCHRONIZE, OBJ_INHERIT, ¶ms.hStdError ); + if (isatty(0) || isatty(1) || isatty(2)) + params.ConsoleHandle = (HANDLE)2; /* see kernel32/kernel_private.h */ + if (!isatty(0)) + wine_server_fd_to_handle( 0, GENERIC_READ|SYNCHRONIZE, OBJ_INHERIT, ¶ms.hStdInput ); + if (!isatty(1)) + wine_server_fd_to_handle( 1, GENERIC_WRITE|SYNCHRONIZE, OBJ_INHERIT, ¶ms.hStdOutput ); + if (!isatty(2)) + wine_server_fd_to_handle( 2, GENERIC_WRITE|SYNCHRONIZE, OBJ_INHERIT, ¶ms.hStdError ); } /* initialize time values in user_shared_data */