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/cl…
==============================================================================
--- 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/cl…
==============================================================================
--- 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/cl…
==============================================================================
--- 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/in…
==============================================================================
--- 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/subsy…
==============================================================================
--- 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/basesr…
==============================================================================
--- 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
     }