Author: hbelusca Date: Tue Jan 1 23:36:19 2013 New Revision: 58096
URL: http://svn.reactos.org/svn/reactos?rev=58096&view=rev Log: [KERNEL32/BASESRV/CONSRV] - Fix console apps initialization. - Introduce a helper function InitConsoleCtrlHandling for initializing console control handling. - We now initialize the new created console when connecting the client (kernel32) to the server (consrv) by calling CsrClientConnectToServer with real parameters (not dummy ones). - Add/activate some debug prints (will be removed when all things work).
Part 1/2
Modified: branches/ros-csrss/dll/win32/kernel32/client/console/console.c branches/ros-csrss/dll/win32/kernel32/client/dllmain.c branches/ros-csrss/dll/win32/kernel32/client/proc.c branches/ros-csrss/dll/win32/kernel32/include/kernel32.h branches/ros-csrss/include/reactos/subsys/win/conmsg.h branches/ros-csrss/subsystems/win/basesrv/server.c
Modified: branches/ros-csrss/dll/win32/kernel32/client/console/console.c URL: http://svn.reactos.org/svn/reactos/branches/ros-csrss/dll/win32/kernel32/cli... ============================================================================== --- branches/ros-csrss/dll/win32/kernel32/client/console/console.c [iso-8859-1] (original) +++ branches/ros-csrss/dll/win32/kernel32/client/console/console.c [iso-8859-1] Tue Jan 1 23:36:19 2013 @@ -29,6 +29,8 @@ ULONG NrCtrlHandlers; ULONG NrAllocatedHandlers;
+HANDLE InputWaitHandle = INVALID_HANDLE_VALUE; + #define INPUTEXENAME_BUFLEN 256 static WCHAR InputExeName[INPUTEXENAME_BUFLEN];
@@ -76,7 +78,7 @@ UINT i; EXCEPTION_RECORD erException;
- DPRINT("Console Dispatcher Active: %lx %lx\n", CodeAndFlag, nCode); + DPRINT1("Console Dispatcher Active: %lx %lx\n", CodeAndFlag, nCode); SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
switch(nCode) @@ -174,6 +176,16 @@ return STATUS_SUCCESS; }
+VOID +WINAPI +InitConsoleCtrlHandling(VOID) +{ + /* Initialize Console Ctrl Handler */ + NrAllocatedHandlers = NrCtrlHandlers = 1; + CtrlHandlers = InitialHandler; + CtrlHandlers[0] = DefaultConsoleCtrlHandler; +} +
/* FUNCTIONS ******************************************************************/
@@ -321,10 +333,6 @@ WINAPI GetConsoleInputWaitHandle(VOID) { -/// HACK !!!!!!!!!!!!! - ASSERT(FALSE); - return NULL; - #if 0 NTSTATUS Status; CONSOLE_API_MESSAGE ApiMessage; @@ -341,6 +349,8 @@
return ApiMessage.Data.GetConsoleInputWaitHandle.InputWaitHandle; #endif + + return InputWaitHandle; }
@@ -786,8 +796,9 @@ NTSTATUS Status; CONSOLE_API_MESSAGE ApiMessage; PCSRSS_ALLOC_CONSOLE AllocConsoleRequest = &ApiMessage.Data.AllocConsoleRequest; - HANDLE hStdError; STARTUPINFO si; + + DPRINT1("AllocConsole called !!!!\n");
if (NtCurrentPeb()->ProcessParameters->ConsoleHandle) { @@ -798,9 +809,9 @@
GetStartupInfo(&si);
+ AllocConsoleRequest->ShowCmd = si.wShowWindow; + AllocConsoleRequest->Console = NULL; AllocConsoleRequest->CtrlDispatcher = ConsoleControlDispatcher; - AllocConsoleRequest->ConsoleNeeded = TRUE; - AllocConsoleRequest->ShowCmd = si.wShowWindow;
Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, @@ -814,15 +825,15 @@
NtCurrentPeb()->ProcessParameters->ConsoleHandle = AllocConsoleRequest->Console;
- SetStdHandle(STD_INPUT_HANDLE, AllocConsoleRequest->InputHandle); + SetStdHandle(STD_INPUT_HANDLE , AllocConsoleRequest->InputHandle ); SetStdHandle(STD_OUTPUT_HANDLE, AllocConsoleRequest->OutputHandle); - - hStdError = DuplicateConsoleHandle(AllocConsoleRequest->OutputHandle, - 0, - TRUE, - DUPLICATE_SAME_ACCESS); - - SetStdHandle(STD_ERROR_HANDLE, hStdError); + SetStdHandle(STD_ERROR_HANDLE , AllocConsoleRequest->ErrorHandle ); + + /* Initialize Console Ctrl Handler */ + InitConsoleCtrlHandling(); + + InputWaitHandle = AllocConsoleRequest->InputWaitHandle; + return TRUE; }
@@ -853,6 +864,10 @@ }
NtCurrentPeb()->ProcessParameters->ConsoleHandle = NULL; + + CloseHandle(InputWaitHandle); + InputWaitHandle = INVALID_HANDLE_VALUE; + return TRUE; }
Modified: branches/ros-csrss/dll/win32/kernel32/client/dllmain.c URL: http://svn.reactos.org/svn/reactos/branches/ros-csrss/dll/win32/kernel32/cli... ============================================================================== --- branches/ros-csrss/dll/win32/kernel32/client/dllmain.c [iso-8859-1] (original) +++ branches/ros-csrss/dll/win32/kernel32/client/dllmain.c [iso-8859-1] Tue Jan 1 23:36:19 2013 @@ -36,12 +36,9 @@ RTL_CRITICAL_SECTION BaseDllDirectoryLock; RTL_CRITICAL_SECTION ConsoleLock;
-extern BOOL WINAPI DefaultConsoleCtrlHandler(DWORD Event); extern DWORD WINAPI ConsoleControlDispatcher(IN LPVOID lpThreadParameter); -extern PHANDLER_ROUTINE InitialHandler[1]; -extern PHANDLER_ROUTINE* CtrlHandlers; -extern ULONG NrCtrlHandlers; -extern ULONG NrAllocatedHandlers; +extern HANDLE InputWaitHandle; + extern BOOL FASTCALL NlsInit(VOID); extern VOID FASTCALL NlsUninit(VOID);
@@ -55,9 +52,6 @@ BasepInitConsole(VOID) { NTSTATUS Status; - CONSOLE_API_MESSAGE ApiMessage; - PCSRSS_ALLOC_CONSOLE AllocConsoleRequest = &ApiMessage.Data.AllocConsoleRequest; - BOOLEAN NotConsole = FALSE; PRTL_USER_PROCESS_PARAMETERS Parameters = NtCurrentPeb()->ProcessParameters; LPCWSTR ExeName; STARTUPINFO si; @@ -65,12 +59,8 @@ ULONG SessionId = NtCurrentPeb()->SessionId; BOOLEAN InServer;
- // HACK - /* - CSR_CONNECTION_INFO CsrConnectionInfo; - ULONG ConnectionSize = sizeof(CsrConnectionInfo); - */ - // END HACK + CONSOLE_CONNECTION_INFO ConnectInfo; + ULONG ConnectInfoSize = sizeof(ConnectInfo);
WCHAR lpTest[MAX_PATH]; GetModuleFileNameW(NULL, lpTest, MAX_PATH); @@ -79,28 +69,33 @@ Parameters->ConsoleHandle, Parameters->StandardInput, Parameters->StandardOutput, Parameters->StandardError);
+ /* Initialize our global console DLL lock */ + Status = RtlInitializeCriticalSection(&ConsoleLock); + if (!NT_SUCCESS(Status)) return FALSE; + ConsoleInitialized = TRUE; + /* We have nothing to do if this isn't a console app... */ if (RtlImageNtHeader(GetModuleHandle(NULL))->OptionalHeader.Subsystem != IMAGE_SUBSYSTEM_WINDOWS_CUI) { DPRINT("Image is not a console application\n"); Parameters->ConsoleHandle = NULL; - AllocConsoleRequest->ConsoleNeeded = FALSE; + ConnectInfo.ConsoleNeeded = FALSE; // ConsoleNeeded is used for knowing whether or not this is a CUI app. } else { /* Assume one is needed */ GetStartupInfo(&si); - AllocConsoleRequest->ConsoleNeeded = TRUE; - AllocConsoleRequest->ShowCmd = si.wShowWindow; - - /* Handle the special flags given to us by BasepInitializeEnvironment */ + ConnectInfo.ConsoleNeeded = TRUE; + ConnectInfo.ShowCmd = si.wShowWindow; + + /* Handle the special flags given to us by BasePushProcessParameters */ if (Parameters->ConsoleHandle == HANDLE_DETACHED_PROCESS) { /* No console to create */ DPRINT("No console to create\n"); Parameters->ConsoleHandle = NULL; - AllocConsoleRequest->ConsoleNeeded = FALSE; + ConnectInfo.ConsoleNeeded = FALSE; } else if (Parameters->ConsoleHandle == HANDLE_CREATE_NEW_CONSOLE) { @@ -113,33 +108,29 @@ /* We'll get the real one soon */ DPRINT("Creating new invisible console\n"); Parameters->ConsoleHandle = NULL; - AllocConsoleRequest->ShowCmd = SW_HIDE; + ConnectInfo.ShowCmd = SW_HIDE; } else { if (Parameters->ConsoleHandle == INVALID_HANDLE_VALUE) { - Parameters->ConsoleHandle = 0; + Parameters->ConsoleHandle = NULL; } DPRINT("Using existing console: %x\n", Parameters->ConsoleHandle); } }
+ /* Now use the proper console handle */ + ConnectInfo.Console = Parameters->ConsoleHandle; + /* Initialize Console Ctrl Handler and input EXE name */ - ConsoleInitialized = TRUE; - RtlInitializeCriticalSection(&ConsoleLock); - NrAllocatedHandlers = 1; - NrCtrlHandlers = 1; - CtrlHandlers = InitialHandler; - CtrlHandlers[0] = DefaultConsoleCtrlHandler; + InitConsoleCtrlHandling(); + ConnectInfo.CtrlDispatcher = ConsoleControlDispatcher;
ExeName = wcsrchr(Parameters->ImagePathName.Buffer, L'\'); if (ExeName) SetConsoleInputExeNameW(ExeName + 1);
- /* Now use the proper console handle */ - AllocConsoleRequest->Console = Parameters->ConsoleHandle; - /* Setup the right Object Directory path */ if (!SessionId) { @@ -156,60 +147,44 @@ WIN_OBJ_DIR); }
- /* Connect to the base server */ - DPRINT("Connecting to CSR in BasepInitConsole...\n"); + /* Connect to the Console Server */ + DPRINT("Connecting to the Console Server in BasepInitConsole...\n"); Status = CsrClientConnectToServer(SessionDir, CONSRV_SERVERDLL_INDEX, - /* &CsrConnectionInfo, */ NULL, // TODO: Give it a console connection info - /* &ConnectionSize, */ NULL, // TODO: Give it a console connection info + &ConnectInfo, + &ConnectInfoSize, &InServer); if (!NT_SUCCESS(Status)) { - DPRINT1("Failed to connect to CSR (Status %lx)\n", Status); + DPRINT1("Failed to connect to the Console Server (Status %lx)\n", Status); return FALSE; }
/* Nothing to do for server-to-server */ if (InServer) return TRUE;
- /* - * Normally, we should be connecting to the Console CSR Server... - * but we don't have one yet, so we will instead simply send a create - * console message to the Base Server. When we finally have a Console - * Server, this code should be changed to send connection data instead. - */ - AllocConsoleRequest->CtrlDispatcher = ConsoleControlDispatcher; - Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, - NULL, - CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepAlloc), - sizeof(CSRSS_ALLOC_CONSOLE)); - if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = ApiMessage.Status)) - { - DPRINT1("CSR Failed to give us a console\n"); - /* We're lying here, so at least the process can load... */ - return TRUE; - } - /* Nothing to do if not a console app */ - if (NotConsole) return TRUE; + if (!ConnectInfo.ConsoleNeeded) return TRUE;
/* We got the handles, let's set them */ - if ((Parameters->ConsoleHandle = AllocConsoleRequest->Console)) + if ((Parameters->ConsoleHandle = ConnectInfo.Console)) { /* If we already had some, don't use the new ones */ if (!Parameters->StandardInput) { - Parameters->StandardInput = AllocConsoleRequest->InputHandle; + Parameters->StandardInput = ConnectInfo.InputHandle; } if (!Parameters->StandardOutput) { - Parameters->StandardOutput = AllocConsoleRequest->OutputHandle; + Parameters->StandardOutput = ConnectInfo.OutputHandle; } if (!Parameters->StandardError) { - Parameters->StandardError = AllocConsoleRequest->OutputHandle; - } - } + Parameters->StandardError = ConnectInfo.ErrorHandle; + } + } + + InputWaitHandle = ConnectInfo.InputWaitHandle;
DPRINT("Console setup: %lx, %lx, %lx, %lx\n", Parameters->ConsoleHandle, @@ -403,9 +378,9 @@ if (ConsoleInitialized == TRUE) { ConsoleInitialized = FALSE; - RtlDeleteCriticalSection (&ConsoleLock); + RtlDeleteCriticalSection(&ConsoleLock); } - RtlDeleteCriticalSection (&BaseDllDirectoryLock); + RtlDeleteCriticalSection(&BaseDllDirectoryLock); } break;
Modified: branches/ros-csrss/dll/win32/kernel32/client/proc.c URL: http://svn.reactos.org/svn/reactos/branches/ros-csrss/dll/win32/kernel32/cli... ============================================================================== --- branches/ros-csrss/dll/win32/kernel32/client/proc.c [iso-8859-1] (original) +++ branches/ros-csrss/dll/win32/kernel32/client/proc.c [iso-8859-1] Tue Jan 1 23:36:19 2013 @@ -581,6 +581,16 @@ CreateProcessRequest->CreationFlags = dwCreationFlags; CreateProcessRequest->bInheritHandles = InheritHandles;
+ /* + * For GUI applications we turn on the 2nd bit. This also allows + * us to know whether or not the application is a GUI or CUI app. + */ + if (IMAGE_SUBSYSTEM_WINDOWS_GUI == SectionImageInfo->SubSystemType) + { + CreateProcessRequest->ProcessHandle = (HANDLE) + ((ULONG_PTR)CreateProcessRequest->ProcessHandle | 2); + } + /* Call CSR */ DPRINT1("Calling CsrClientCallServer from BasepCreateFirstThread...\n"); Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, @@ -937,18 +947,18 @@ ProcessParameters->StandardError = StartupInfo->hStdError; }
- /* Use Special Flags for ConDllInitialize in Kernel32 */ + /* Use Special Flags for BasepInitConsole in Kernel32 */ if (CreationFlags & DETACHED_PROCESS) { ProcessParameters->ConsoleHandle = HANDLE_DETACHED_PROCESS; } + else if (CreationFlags & CREATE_NEW_CONSOLE) + { + ProcessParameters->ConsoleHandle = HANDLE_CREATE_NEW_CONSOLE; + } else if (CreationFlags & CREATE_NO_WINDOW) { ProcessParameters->ConsoleHandle = HANDLE_CREATE_NO_WINDOW; - } - else if (CreationFlags & CREATE_NEW_CONSOLE) - { - ProcessParameters->ConsoleHandle = HANDLE_CREATE_NEW_CONSOLE; } else {
Modified: branches/ros-csrss/dll/win32/kernel32/include/kernel32.h URL: http://svn.reactos.org/svn/reactos/branches/ros-csrss/dll/win32/kernel32/inc... ============================================================================== --- branches/ros-csrss/dll/win32/kernel32/include/kernel32.h [iso-8859-1] (original) +++ branches/ros-csrss/dll/win32/kernel32/include/kernel32.h [iso-8859-1] Tue Jan 1 23:36:19 2013 @@ -186,6 +186,8 @@ NTAPI BaseDllInitializeMemoryManager(VOID);
+VOID WINAPI InitConsoleCtrlHandling(VOID); + BOOL WINAPI VerifyConsoleIoHandle(HANDLE Handle);
BOOL WINAPI CloseConsoleHandle(HANDLE Handle);
Modified: branches/ros-csrss/include/reactos/subsys/win/conmsg.h URL: http://svn.reactos.org/svn/reactos/branches/ros-csrss/include/reactos/subsys... ============================================================================== --- branches/ros-csrss/include/reactos/subsys/win/conmsg.h [iso-8859-1] (original) +++ branches/ros-csrss/include/reactos/subsys/win/conmsg.h [iso-8859-1] Tue Jan 1 23:36:19 2013 @@ -114,7 +114,16 @@
typedef struct _CONSOLE_CONNECTION_INFO { - ULONG Dummy; + BOOL ConsoleNeeded; // Used for GUI apps only. + + /* Copied from CSRSS_ALLOC_CONSOLE */ + INT ShowCmd; + HANDLE Console; // ConsoleHandle // In fact, it is a PCSRSS_CONSOLE <-- correct that !! + HANDLE InputHandle; + HANDLE OutputHandle; + HANDLE ErrorHandle; + HANDLE InputWaitHandle; + LPTHREAD_START_ROUTINE CtrlDispatcher; } CONSOLE_CONNECTION_INFO, *PCONSOLE_CONNECTION_INFO;
@@ -157,12 +166,13 @@
typedef struct { - LPTHREAD_START_ROUTINE CtrlDispatcher; - BOOL ConsoleNeeded; INT ShowCmd; - HANDLE Console; + HANDLE Console; // ConsoleHandle // In fact, it is a PCSRSS_CONSOLE <-- correct that !! HANDLE InputHandle; HANDLE OutputHandle; + HANDLE ErrorHandle; + HANDLE InputWaitHandle; + LPTHREAD_START_ROUTINE CtrlDispatcher; } CSRSS_ALLOC_CONSOLE, *PCSRSS_ALLOC_CONSOLE;
typedef struct
Modified: branches/ros-csrss/subsystems/win/basesrv/server.c URL: http://svn.reactos.org/svn/reactos/branches/ros-csrss/subsystems/win/basesrv... ============================================================================== --- branches/ros-csrss/subsystems/win/basesrv/server.c [iso-8859-1] (original) +++ branches/ros-csrss/subsystems/win/basesrv/server.c [iso-8859-1] Tue Jan 1 23:36:19 2013 @@ -80,6 +80,11 @@ if (CreateProcessRequest->CreationFlags & CREATE_NEW_PROCESS_GROUP) { DebugFlags |= CsrProcessCreateNewGroup; + } + if ((Flags & 2) == 0) + { + DPRINT1("BaseSrvCreateProcess - Launching a Console process\n"); + DebugFlags |= CsrProcessIsConsoleApp; }
/* FIXME: SxS Stuff */ @@ -129,8 +134,8 @@ if (!CurrentThread) { DPRINT1("Server Thread TID: [%lx.%lx]\n", - CreateThreadRequest->ClientId.UniqueProcess, - CreateThreadRequest->ClientId.UniqueThread); + CreateThreadRequest->ClientId.UniqueProcess, + CreateThreadRequest->ClientId.UniqueThread); return STATUS_SUCCESS; // server-to-server }