[WIN32K]
authorHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Fri, 4 Jan 2013 00:41:10 +0000 (00:41 +0000)
committerHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Fri, 4 Jan 2013 00:41:10 +0000 (00:41 +0000)
- Start to implement NtUserConsoleControl to allow the console server define Console Window Class atom.
- In UserInitialize, initialize the current thread by a call to UserCreateThreadInfo.
- In UserCreateThreadInfo, set the TIF_CSRSSTHREAD flag for threads created by CSRSS.
- In NtUserQueryWindow, when querying the process/thread ID associated to a given window, check whether the window was created by CSRSS and if so, if this is a Console window, get the process/thread ID of the associated console process (console leader process), instead of the CID of CSRSS.

[CONSRV]
- Introduce the concept of console leader process (to be used as the process owning the console window).
- Introduce extra console window information to store the PID and TID of the console leader process via new internal flags to be used by GetWindowLong.
- Effectively set the console window console leader CID at its creation.
- Improve CsrInitConsole to set a console leader process to the console being created.

This fixes http://jira.reactos.org/browse/CORE-122 in this branch.

[CONSRV-WIN32K]
Fix various code misspellings.

svn path=/branches/ros-csrss/; revision=58107

15 files changed:
win32ss/include/ntuser.h
win32ss/user/consrv/conio.h
win32ss/user/consrv/console.c
win32ss/user/consrv/consrv.h
win32ss/user/consrv/guiconsole.c
win32ss/user/consrv/handle.c
win32ss/user/consrv/tuiconsole.c
win32ss/user/ntuser/main.c
win32ss/user/ntuser/ntstubs.c
win32ss/user/ntuser/ntuser.c
win32ss/user/ntuser/ntuser.h
win32ss/user/ntuser/userfuncs.h
win32ss/user/ntuser/window.c
win32ss/user/ntuser/winsta.c
win32ss/user/ntuser/winsta.h

index be749e2..28fb20a 100644 (file)
@@ -1562,12 +1562,19 @@ NTAPI
 NtUserCloseWindowStation(
   HWINSTA hWinSta);
 
-DWORD
-NTAPI
+/* Console commands for NtUserConsoleControl */
+typedef enum _CONSOLECONTROL
+{
+    GuiConsoleWndClassAtom,
+    TuiConsoleWndClassAtom,
+} CONSOLECONTROL, *PCONSOLECONTROL;
+
+NTSTATUS
+APIENTRY
 NtUserConsoleControl(
-  DWORD dwUnknown1,
-  DWORD dwUnknown2,
-  DWORD dwUnknown3);
+    IN CONSOLECONTROL ConsoleCtrl,
+    IN PVOID ConsoleCtrlInfo,
+    IN DWORD ConsoleCtrlInfoLength);
 
 HANDLE
 NTAPI
index 9e34231..5965a10 100644 (file)
@@ -50,6 +50,7 @@ typedef struct tagCSRSS_CONSOLE
     struct tagCSRSS_CONSOLE *Prev, *Next; /* Next and Prev consoles in console wheel */
     struct tagCSRSS_CONSOLE_VTBL *Vtbl;   /* Using CUI or GUI consoles */
 
+    CLIENT_ID  ConsoleLeaderCID;          /* Contains the Console Leader Process CID */
     LIST_ENTRY ProcessList;
 
     LIST_ENTRY InputEvents;               /* List head for input event queue */
@@ -90,6 +91,19 @@ typedef struct tagCSRSS_CONSOLE
     CONSOLE_SELECTION_INFO Selection;
 } CSRSS_CONSOLE, *PCSRSS_CONSOLE;
 
+/**************************************************************\
+\** Define the Console Leader Process for the console window **/
+#define GWLP_CONSOLEWND_ALLOC  (2 * sizeof(LONG_PTR))
+#define GWLP_CONSOLE_LEADER_PID 0
+#define GWLP_CONSOLE_LEADER_TID 4
+
+#define SetConsoleWndConsoleLeaderCID(Console)  \
+do {    \
+    SetWindowLongPtrW((Console)->hWindow, GWLP_CONSOLE_LEADER_PID, (LONG_PTR)((Console)->ConsoleLeaderCID.UniqueProcess));  \
+    SetWindowLongPtrW((Console)->hWindow, GWLP_CONSOLE_LEADER_TID, (LONG_PTR)((Console)->ConsoleLeaderCID.UniqueThread ));  \
+} while(0)
+/**************************************************************/
+
 typedef struct tagCSRSS_CONSOLE_VTBL
 {
     VOID (WINAPI *InitScreenBuffer)(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER ScreenBuffer);
@@ -146,6 +160,7 @@ NTSTATUS FASTCALL ConioConsoleFromProcessData(PCONSOLE_PROCESS_DATA ProcessData,
                                               PCSRSS_CONSOLE *Console);
 VOID WINAPI ConioDeleteConsole(PCSRSS_CONSOLE Console);
 VOID WINAPI CsrInitConsoleSupport(VOID);
+NTSTATUS WINAPI CsrInitConsole(PCSRSS_CONSOLE* NewConsole, int ShowCmd, PCSR_PROCESS ConsoleLeaderProcess);
 VOID FASTCALL ConioPause(PCSRSS_CONSOLE Console, UINT Flags);
 VOID FASTCALL ConioUnpause(PCSRSS_CONSOLE Console, UINT Flags);
 VOID FASTCALL ConioConsoleCtrlEvent(DWORD Event, PCONSOLE_PROCESS_DATA ProcessData);
index 7c4a794..39dd4bd 100644 (file)
@@ -87,8 +87,8 @@ ConioConsoleCtrlEvent(DWORD Event, PCONSOLE_PROCESS_DATA ProcessData)
     ConioConsoleCtrlEventTimeout(Event, ProcessData, 0);
 }
 
-/* static */ NTSTATUS WINAPI
-CsrInitConsole(PCSRSS_CONSOLE* NewConsole, int ShowCmd)
+NTSTATUS WINAPI
+CsrInitConsole(PCSRSS_CONSOLE* NewConsole, int ShowCmd, PCSR_PROCESS ConsoleLeaderProcess)
 {
     NTSTATUS Status;
     SECURITY_ATTRIBUTES SecurityAttributes;
@@ -127,6 +127,7 @@ CsrInitConsole(PCSRSS_CONSOLE* NewConsole, int ShowCmd)
     Console->Header.Type = CONIO_CONSOLE_MAGIC;
     Console->Header.Console = Console;
     Console->Mode = ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT;
+    Console->ConsoleLeaderCID = ConsoleLeaderProcess->ClientId;
     InitializeListHead(&Console->ProcessList);
     InitializeListHead(&Console->BufferList);
     Console->ActiveBuffer = NULL;
@@ -292,7 +293,8 @@ CSR_API(SrvAllocConsole)
 {
     NTSTATUS Status = STATUS_SUCCESS;
     PCSRSS_ALLOC_CONSOLE AllocConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.AllocConsoleRequest;
-    PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrGetClientThread()->Process);
+    PCSR_PROCESS ConsoleLeader = CsrGetClientThread()->Process;
+    PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(ConsoleLeader);
 
     DPRINT("SrvAllocConsole\n");
 
@@ -306,8 +308,8 @@ CSR_API(SrvAllocConsole)
 
     DPRINT1("SrvAllocConsole - Checkpoint 1\n");
 
-    /* Initialize a new Console */
-    Status = CsrInitConsole(&ProcessData->Console, AllocConsoleRequest->ShowCmd);
+    /* Initialize a new Console owned by the Console Leader Process */
+    Status = CsrInitConsole(&ProcessData->Console, AllocConsoleRequest->ShowCmd, ConsoleLeader);
     if (!NT_SUCCESS(Status))
     {
         DPRINT1("Console initialization failed\n");
index ed5a18e..97b08a7 100644 (file)
@@ -17,6 +17,9 @@
 #define NTOS_MODE_USER
 #include <ndk/ntndk.h>
 
+/* Public Win32K Headers */
+#include <ntuser.h>
+
 /* CSRSS Header */
 #include <csr/csrsrv.h>
 
index d8741ef..e64aa73 100644 (file)
 #include "guiconsole.h"
 #include <psapi.h>
 
-/* Public Win32K Headers */
-#include <ntuser.h>
-
 #define NDEBUG
 #include <debug.h>
 
+
+/* GUI Console Window Class name */
+#define GUI_CONSOLE_WINDOW_CLASS L"ConsoleWindowClass"
+
+
 /* Not defined in any header file */
 // extern VOID WINAPI PrivateCsrssManualGuiCheck(LONG Check);
 // From win32ss/user/win32csr/dllmain.c
@@ -194,7 +196,7 @@ GuiConsoleCreateSysMenu(PCSRSS_CONSOLE Console)
 static VOID
 GuiConsoleGetDataPointers(HWND hWnd, PCSRSS_CONSOLE *Console, PGUI_CONSOLE_DATA *GuiData)
 {
-    *Console = (PCSRSS_CONSOLE) GetWindowLongPtrW(hWnd, GWL_USERDATA);
+    *Console = (PCSRSS_CONSOLE)GetWindowLongPtrW(hWnd, GWLP_USERDATA);
     *GuiData = (NULL == *Console ? NULL : (*Console)->PrivateData);
 }
 
@@ -693,9 +695,9 @@ GuiConsoleInitScrollbar(PCSRSS_CONSOLE Console, HWND hwnd)
 }
 
 static BOOL
-GuiConsoleHandleNcCreate(HWND hWnd, CREATESTRUCTW *Create)
+GuiConsoleHandleNcCreate(HWND hWnd, LPCREATESTRUCTW Create)
 {
-    PCSRSS_CONSOLE Console = (PCSRSS_CONSOLE) Create->lpCreateParams;
+    PCSRSS_CONSOLE Console = (PCSRSS_CONSOLE)Create->lpCreateParams;
     PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA)Console->PrivateData;
     HDC Dc;
     HFONT OldFont;
@@ -788,7 +790,7 @@ GuiConsoleHandleNcCreate(HWND hWnd, CREATESTRUCTW *Create)
 
     DPRINT("Console %p GuiData %p\n", Console, GuiData);
     Console->PrivateData = GuiData;
-    SetWindowLongPtrW(hWnd, GWL_USERDATA, (DWORD_PTR) Console);
+    SetWindowLongPtrW(hWnd, GWLP_USERDATA, (DWORD_PTR)Console);
 
     SetTimer(hWnd, CONGUI_UPDATE_TIMER, CONGUI_UPDATE_TIME, NULL);
     GuiConsoleCreateSysMenu(Console);
@@ -1512,7 +1514,6 @@ GuiConsoleRightMouseDown(HWND hWnd)
 
 }
 
-
 static VOID
 GuiConsoleShowConsoleProperties(HWND hWnd, BOOL Defaults, PGUI_CONSOLE_DATA GuiData)
 {
@@ -2004,7 +2005,7 @@ GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
     switch(msg)
     {
     case WM_NCCREATE:
-        Result = (LRESULT) GuiConsoleHandleNcCreate(hWnd, (CREATESTRUCTW *) lParam);
+        Result = (LRESULT) GuiConsoleHandleNcCreate(hWnd, (LPCREATESTRUCTW)lParam);
         break;
     case WM_PAINT:
         GuiConsoleHandlePaint(hWnd, (HDC)wParam);
@@ -2074,8 +2075,6 @@ GuiConsoleNotifyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
     PWCHAR Buffer, Title;
     PCSRSS_CONSOLE Console = (PCSRSS_CONSOLE) lParam;
 
-
-
     switch(msg)
     {
     case WM_CREATE:
@@ -2095,7 +2094,7 @@ GuiConsoleNotifyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
             Title = L"";
         }
         NewWindow = CreateWindowExW(WS_EX_CLIENTEDGE,
-                                    L"ConsoleWindowClass",
+                                    GUI_CONSOLE_WINDOW_CLASS,
                                     Title,
                                     WS_OVERLAPPEDWINDOW | WS_HSCROLL | WS_VSCROLL,
                                     CW_USEDEFAULT,
@@ -2104,18 +2103,19 @@ GuiConsoleNotifyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
                                     CW_USEDEFAULT,
                                     NULL,
                                     NULL,
-                                    (HINSTANCE) GetModuleHandleW(NULL),
-                                    (PVOID) Console);
+                                    (HINSTANCE)GetModuleHandleW(NULL),
+                                    (PVOID)Console);
         if (NULL != Buffer)
         {
             HeapFree(ConSrvHeap, 0, Buffer);
         }
         if (NULL != NewWindow)
         {
+            SetConsoleWndConsoleLeaderCID(Console);
             SetWindowLongW(hWnd, GWL_USERDATA, GetWindowLongW(hWnd, GWL_USERDATA) + 1);
             ShowWindow(NewWindow, (int)wParam);
         }
-        return (LRESULT) NewWindow;
+        return (LRESULT)NewWindow;
     case PM_DESTROY_CONSOLE:
         /* Window creation is done using a PostMessage(), so it's possible that the
          * window that we want to destroy doesn't exist yet. So first empty the message
@@ -2182,6 +2182,7 @@ static BOOL
 GuiInit(VOID)
 {
     WNDCLASSEXW wc;
+    ATOM ConsoleClassAtom;
 
     if (NULL == NotifyWnd)
     {
@@ -2202,12 +2203,12 @@ GuiInit(VOID)
     wc.hIconSm = NULL;
     if (RegisterClassExW(&wc) == 0)
     {
-        DPRINT1("Failed to register notify wndproc\n");
+        DPRINT1("Failed to register GUI notify wndproc\n");
         return FALSE;
     }
 
     wc.cbSize = sizeof(WNDCLASSEXW);
-    wc.lpszClassName = L"ConsoleWindowClass";
+    wc.lpszClassName = GUI_CONSOLE_WINDOW_CLASS;
     wc.lpfnWndProc = GuiConsoleWndProc;
     wc.style = 0;
     wc.hInstance = (HINSTANCE)GetModuleHandleW(NULL);
@@ -2216,15 +2217,21 @@ GuiInit(VOID)
     wc.hbrBackground = CreateSolidBrush(RGB(0,0,0));
     wc.lpszMenuName = NULL;
     wc.cbClsExtra = 0;
-    wc.cbWndExtra = 0;
+    wc.cbWndExtra = GWLP_CONSOLEWND_ALLOC;
     wc.hIconSm = LoadImageW(ConSrvDllInstance, MAKEINTRESOURCEW(1), IMAGE_ICON,
                             GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON),
                             LR_SHARED);
-    if (RegisterClassExW(&wc) == 0)
+
+    ConsoleClassAtom = RegisterClassExW(&wc);
+    if (ConsoleClassAtom == 0)
     {
-        DPRINT1("Failed to register console wndproc\n");
+        DPRINT1("Failed to register GUI console wndproc\n");
         return FALSE;
     }
+    else
+    {
+        NtUserConsoleControl(GuiConsoleWndClassAtom, &ConsoleClassAtom, sizeof(ATOM));
+    }
 
     return TRUE;
 }
@@ -2299,10 +2306,10 @@ GuiInitConsole(PCSRSS_CONSOLE Console, int ShowCmd)
     HANDLE ThreadHandle;
     PGUI_CONSOLE_DATA GuiData;
 
-    if (! ConsInitialized)
+    if (!ConsInitialized)
     {
         ConsInitialized = TRUE;
-        if (! GuiInit())
+        if (!GuiInit())
         {
             ConsInitialized = FALSE;
             return STATUS_UNSUCCESSFUL;
@@ -2310,6 +2317,7 @@ GuiInitConsole(PCSRSS_CONSOLE Console, int ShowCmd)
     }
 
     Console->Vtbl = &GuiVtbl;
+    Console->hWindow = NULL;
     if (NULL == NotifyWnd)
     {
         GraphicsStartupEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
@@ -2321,7 +2329,7 @@ GuiInitConsole(PCSRSS_CONSOLE Console, int ShowCmd)
         ThreadHandle = CreateThread(NULL,
                                     0,
                                     GuiConsoleGuiThread,
-                                    (PVOID) &GraphicsStartupEvent,
+                                    (PVOID)&GraphicsStartupEvent,
                                     0,
                                     NULL);
         if (NULL == ThreadHandle)
@@ -2350,9 +2358,9 @@ GuiInitConsole(PCSRSS_CONSOLE Console, int ShowCmd)
         return STATUS_UNSUCCESSFUL;
     }
 
-    Console->PrivateData = (PVOID) GuiData;
+    Console->PrivateData = (PVOID)GuiData;
     /*
-     * we need to wait untill the GUI has been fully initialized
+     * we need to wait until the GUI has been fully initialized
      * to retrieve custom settings i.e. WindowSize etc..
      * Ideally we could use SendNotifyMessage for this but its not
      * yet implemented.
@@ -2362,7 +2370,7 @@ GuiInitConsole(PCSRSS_CONSOLE Console, int ShowCmd)
     /* create console */
     PostMessageW(NotifyWnd, PM_CREATE_CONSOLE, ShowCmd, (LPARAM)Console);
 
-    /* wait untill initialization has finished */
+    /* wait until initialization has finished */
     WaitForSingleObject(GuiData->hGuiInitEvent, INFINITE);
     DPRINT("received event Console %p GuiData %p X %d Y %d\n", Console, Console->PrivateData, Console->Size.X, Console->Size.Y);
     CloseHandle(GuiData->hGuiInitEvent);
index 6a92235..c527f78 100644 (file)
@@ -321,9 +321,6 @@ ConsoleNewProcess(PCSR_PROCESS SourceProcess,
     return STATUS_SUCCESS;
 }
 
-// Temporary ; move it to a header.
-NTSTATUS WINAPI CsrInitConsole(PCSRSS_CONSOLE* NewConsole, int ShowCmd);
-
 NTSTATUS
 NTAPI
 ConsoleConnect(IN PCSR_PROCESS CsrProcess,
@@ -363,13 +360,11 @@ ConsoleConnect(IN PCSR_PROCESS CsrProcess,
     if (!ConnectInfo->Console ||
          ConnectInfo->Console != ProcessData->ParentConsole)
     {
-        // PCSRSS_CONSOLE Console;
-
         DPRINT1("ConsoleConnect - Allocate a new console\n");
 
-        /* Initialize a new Console */
+        /* Initialize a new Console owned by the Console Leader Process */
         NewConsole = TRUE;
-        Status = CsrInitConsole(&ProcessData->Console, ConnectInfo->ShowCmd);
+        Status = CsrInitConsole(&ProcessData->Console, ConnectInfo->ShowCmd, CsrProcess);
         if (!NT_SUCCESS(Status))
         {
             DPRINT1("Console initialization failed\n");
index fba5d8c..79f1c0b 100644 (file)
 #define NDEBUG
 #include <debug.h>
 
+
+/* TUI Console Window Class name */
+#define TUI_CONSOLE_WINDOW_CLASS L"TuiConsoleWindowClass"
+
+
 CRITICAL_SECTION ActiveConsoleLock;
 static COORD PhysicalConsoleSize;
 static HANDLE ConsoleDeviceHandle;
@@ -69,6 +74,7 @@ TuiInit(DWORD OemCP)
     CONSOLE_SCREEN_BUFFER_INFO ScrInfo;
     DWORD BytesReturned;
     WNDCLASSEXW wc;
+    ATOM ConsoleClassAtom;
     USHORT TextAttribute = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED;
 
     TuiStartService(L"Blue");
@@ -98,8 +104,8 @@ TuiInit(DWORD OemCP)
 
     ActiveConsole = NULL;
     InitializeCriticalSection(&ActiveConsoleLock);
-    if (! DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO,
-                          NULL, 0, &ScrInfo, sizeof(ScrInfo), &BytesReturned, NULL))
+    if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO,
+                         NULL, 0, &ScrInfo, sizeof(ScrInfo), &BytesReturned, NULL))
     {
         DPRINT1("Failed to get console info\n");
         return FALSE;
@@ -108,14 +114,21 @@ TuiInit(DWORD OemCP)
 
     RtlZeroMemory(&wc, sizeof(WNDCLASSEXW));
     wc.cbSize = sizeof(WNDCLASSEXW);
-    wc.lpszClassName = L"TuiConsoleWindowClass";
+    wc.lpszClassName = TUI_CONSOLE_WINDOW_CLASS;
     wc.lpfnWndProc = TuiConsoleWndProc;
-    wc.hInstance = (HINSTANCE) GetModuleHandleW(NULL);
-    if (RegisterClassExW(&wc) == 0)
+    wc.cbWndExtra = GWLP_CONSOLEWND_ALLOC;
+    wc.hInstance = (HINSTANCE)GetModuleHandleW(NULL);
+
+    ConsoleClassAtom = RegisterClassExW(&wc);
+    if (ConsoleClassAtom == 0)
     {
-        DPRINT1("Failed to register console wndproc\n");
+        DPRINT1("Failed to register TUI console wndproc\n");
         return FALSE;
     }
+    else
+    {
+        NtUserConsoleControl(TuiConsoleWndClassAtom, &ConsoleClassAtom, sizeof(ATOM));
+    }
 
     return TRUE;
 }
@@ -179,8 +192,8 @@ TuiDrawRegion(PCSRSS_CONSOLE Console, SMALL_RECT *Region)
 
     TuiCopyRect((char *) (ConsoleDraw + 1), Buff, Region);
 
-    if (! DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_DRAW,
-                          NULL, 0, ConsoleDraw, ConsoleDrawSize, &BytesReturned, NULL))
+    if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_DRAW,
+                         NULL, 0, ConsoleDraw, ConsoleDrawSize, &BytesReturned, NULL))
     {
         DPRINT1("Failed to draw console\n");
         HeapFree(ConSrvHeap, 0, ConsoleDraw);
@@ -222,8 +235,8 @@ TuiSetCursorInfo(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff)
     Info.dwSize = ConioEffectiveCursorSize(Console, 100);
     Info.bVisible = Buff->CursorInfo.bVisible;
 
-    if (! DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_SET_CURSOR_INFO,
-                          &Info, sizeof(Info), NULL, 0, &BytesReturned, NULL))
+    if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_SET_CURSOR_INFO,
+                         &Info, sizeof(Info), NULL, 0, &BytesReturned, NULL))
     {
         DPRINT1( "Failed to set cursor info\n" );
         return FALSE;
@@ -247,9 +260,9 @@ TuiSetScreenInfo(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff, UINT OldCurs
     Info.dwCursorPosition.Y = Buff->CurrentY;
     Info.wAttributes = Buff->DefaultAttrib;
 
-    if (! DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO,
-                          &Info, sizeof(CONSOLE_SCREEN_BUFFER_INFO), NULL, 0,
-                          &BytesReturned, NULL))
+    if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO,
+                         &Info, sizeof(CONSOLE_SCREEN_BUFFER_INFO), NULL, 0,
+                         &BytesReturned, NULL))
     {
         DPRINT1( "Failed to set cursor position\n" );
         return FALSE;
@@ -316,19 +329,20 @@ TuiConsoleThread(PVOID Data)
     HWND NewWindow;
     MSG msg;
 
-    NewWindow = CreateWindowW(L"TuiConsoleWindowClass",
+    NewWindow = CreateWindowW(TUI_CONSOLE_WINDOW_CLASS,
                               Console->Title.Buffer,
                               0,
                               -32000, -32000, 0, 0,
                               NULL, NULL,
-                              (HINSTANCE) GetModuleHandleW(NULL),
-                              (PVOID) Console);
-    Console->hWindow = NewWindow;
+                              (HINSTANCE)GetModuleHandleW(NULL),
+                              (PVOID)Console);
     if (NULL == NewWindow)
     {
         DPRINT1("CSR: Unable to create console window\n");
         return 1;
     }
+    Console->hWindow = NewWindow;
+    SetConsoleWndConsoleLeaderCID(Console);
 
     SetForegroundWindow(Console->hWindow);
 
@@ -368,10 +382,10 @@ TuiInitConsole(PCSRSS_CONSOLE Console)
 {
     HANDLE ThreadHandle;
 
-    if (! ConsInitialized)
+    if (!ConsInitialized)
     {
         ConsInitialized = TRUE;
-        if (! TuiInit(Console->CodePage))
+        if (!TuiInit(Console->CodePage))
         {
             ConsInitialized = FALSE;
             return STATUS_UNSUCCESSFUL;
@@ -384,8 +398,12 @@ TuiInitConsole(PCSRSS_CONSOLE Console)
     Console->ActiveBuffer->MaxX = PhysicalConsoleSize.X;
     Console->ActiveBuffer->MaxY = PhysicalConsoleSize.Y;
 
-    ThreadHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)TuiConsoleThread,
-                                Console, 0, NULL);
+    ThreadHandle = CreateThread(NULL,
+                                0,
+                                TuiConsoleThread,
+                                (PVOID)Console,
+                                0,
+                                NULL);
     if (NULL == ThreadHandle)
     {
         DPRINT1("CSR: Unable to create console thread\n");
@@ -451,9 +469,9 @@ TuiSwapConsole(int Next)
         pos->X = (PhysicalConsoleSize.X - Title.Length) / 2;
         /* redraw the console to clear off old title */
         ConioDrawConsole(ActiveConsole);
-        if (! DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER,
-                              NULL, 0, Buffer, sizeof(COORD) + Title.Length,
-                              &BytesReturned, NULL))
+        if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER,
+                             NULL, 0, Buffer, sizeof(COORD) + Title.Length,
+                             &BytesReturned, NULL))
         {
             DPRINT1( "Error writing to console\n" );
         }
index 04157ac..16f93a8 100644 (file)
@@ -304,6 +304,8 @@ UserCreateThreadInfo(struct _ETHREAD *Thread)
     if (ptiCurrent->KeyboardLayout)
         UserReferenceObject(ptiCurrent->KeyboardLayout);
     ptiCurrent->TIF_flags &= ~TIF_INCLEANUP;
+    if (Process == gpepCSRSS) /* If this thread is owned by CSRSS, mark it as such */
+        ptiCurrent->TIF_flags |= TIF_CSRSSTHREAD;
     ptiCurrent->pcti = &ptiCurrent->cti;
 
     /* Initialize the CLIENTINFO */
index 17418c8..cad4db6 100644 (file)
@@ -559,15 +559,66 @@ NtUserCheckImeHotKey(
     return 0;
 }
 
-DWORD
+NTSTATUS
 APIENTRY
 NtUserConsoleControl(
-    DWORD dwUnknown1,
-    DWORD dwUnknown2,
-    DWORD dwUnknown3)
+    IN CONSOLECONTROL ConsoleCtrl,
+    IN PVOID ConsoleCtrlInfo,
+    IN DWORD ConsoleCtrlInfoLength)
 {
-    STUB;
-    return 0;
+    NTSTATUS Status = STATUS_SUCCESS;
+
+    /* Allow only Console Server to perform this operation (via CSRSS) */
+    if (gpepCSRSS != PsGetCurrentProcess())
+        return STATUS_ACCESS_DENIED;
+
+    UserEnterExclusive();
+
+    switch (ConsoleCtrl)
+    {
+        case GuiConsoleWndClassAtom:
+        {
+            _SEH2_TRY
+            {
+                ProbeForRead(ConsoleCtrlInfo, ConsoleCtrlInfoLength, 1);
+                ASSERT(ConsoleCtrlInfoLength == sizeof(ATOM));
+                gaGuiConsoleWndClass = *(ATOM*)ConsoleCtrlInfo;
+            }
+            _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+            {
+                Status = _SEH2_GetExceptionCode();
+            }
+            _SEH2_END;
+
+            break;
+        }
+
+        case TuiConsoleWndClassAtom:
+        {
+            _SEH2_TRY
+            {
+                ProbeForRead(ConsoleCtrlInfo, ConsoleCtrlInfoLength, 1);
+                ASSERT(ConsoleCtrlInfoLength == sizeof(ATOM));
+                gaTuiConsoleWndClass = *(ATOM*)ConsoleCtrlInfo;
+            }
+            _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+            {
+                Status = _SEH2_GetExceptionCode();
+            }
+            _SEH2_END;
+
+            break;
+        }
+
+        default:
+            ERR("Calling invalid control %lu in NtUserConsoleControl\n", ConsoleCtrl);
+            Status = STATUS_INVALID_INFO_CLASS;
+            break;
+    }
+
+    UserLeave();
+
+    return Status;
 }
 
 DWORD
index 8385b33..5e0499e 100644 (file)
@@ -21,6 +21,8 @@ BOOL gbInitialized;
 HINSTANCE hModClient = NULL;
 BOOL ClientPfnInit = FALSE;
 PEPROCESS gpepCSRSS = NULL;
+ATOM gaGuiConsoleWndClass;
+ATOM gaTuiConsoleWndClass;
 
 /* PRIVATE FUNCTIONS *********************************************************/
 
@@ -105,7 +107,7 @@ UserInitialize(
 // Set W32PF_Flags |= (W32PF_READSCREENACCESSGRANTED | W32PF_IOWINSTA)
 // Create Event for Diconnect Desktop.
 
-    Status = UserCreateWinstaDirectoy();
+    Status = UserCreateWinstaDirectory();
     if (!NT_SUCCESS(Status)) return Status;
 
     /* Initialize Video. */
@@ -121,7 +123,9 @@ UserInitialize(
 // Create ThreadInfo for this Thread!
 // {
 
-    GetW32ThreadInfo();
+    /* Initialize the current thread. */
+    Status = UserCreateThreadInfo(PsGetCurrentThread());
+    if (!NT_SUCCESS(Status)) return Status;
 
 //    Callback to User32 Client Thread Setup
 
index d74e9c9..a3ad021 100644 (file)
@@ -16,6 +16,8 @@ extern PPROCESSINFO gppiList;
 extern PPROCESSINFO ppiScrnSaver;
 extern PPROCESSINFO gppiInputProvider;
 extern PEPROCESS gpepCSRSS;
+extern ATOM gaGuiConsoleWndClass;
+extern ATOM gaTuiConsoleWndClass;
 
 INIT_FUNCTION NTSTATUS NTAPI InitUserImpl(VOID);
 VOID FASTCALL CleanupUserImpl(VOID);
index 60c78dd..b890f93 100644 (file)
@@ -37,6 +37,10 @@ PMENU_OBJECT FASTCALL UserGetMenuObject(HMENU hMenu);
 
 PWND FASTCALL IntGetWindowObject(HWND hWnd);
 
+/*************** MAIN.C ***************/
+
+NTSTATUS NTAPI UserCreateThreadInfo(struct _ETHREAD *Thread);
+
 /*************** WINSTA.C ***************/
 
 HWINSTA FASTCALL UserGetProcessWindowStation(VOID);
index 217d8af..8f4be71 100644 (file)
@@ -3720,6 +3720,10 @@ CLEANUP:
 DWORD APIENTRY
 NtUserQueryWindow(HWND hWnd, DWORD Index)
 {
+/* Console Leader Process CID Window offsets */
+#define GWLP_CONSOLE_LEADER_PID 0
+#define GWLP_CONSOLE_LEADER_TID 4
+
    PWND pWnd;
    DWORD Result;
    DECLARE_RETURN(UINT);
@@ -3735,12 +3739,36 @@ NtUserQueryWindow(HWND hWnd, DWORD Index)
    switch(Index)
    {
       case QUERY_WINDOW_UNIQUE_PROCESS_ID:
-         Result = (DWORD)IntGetWndProcessId(pWnd);
+      {
+         if ( (pWnd->head.pti->TIF_flags & TIF_CSRSSTHREAD) &&
+              ( (pWnd->pcls->atomClassName == gaGuiConsoleWndClass) ||
+                (pWnd->pcls->atomClassName == gaTuiConsoleWndClass) ) )
+         {
+            // IntGetWindowLong(offset == GWLP_CONSOLE_LEADER_PID)
+            Result = (DWORD)(*((LONG_PTR*)((PCHAR)(pWnd + 1) + GWLP_CONSOLE_LEADER_PID)));
+         }
+         else
+         {
+            Result = (DWORD)IntGetWndProcessId(pWnd);
+         }
          break;
+      }
 
       case QUERY_WINDOW_UNIQUE_THREAD_ID:
-         Result = (DWORD)IntGetWndThreadId(pWnd);
+      {
+         if ( (pWnd->head.pti->TIF_flags & TIF_CSRSSTHREAD) &&
+              ( (pWnd->pcls->atomClassName == gaGuiConsoleWndClass) ||
+                (pWnd->pcls->atomClassName == gaTuiConsoleWndClass) ) )
+         {
+            // IntGetWindowLong(offset == GWLP_CONSOLE_LEADER_TID)
+            Result = (DWORD)(*((LONG_PTR*)((PCHAR)(pWnd + 1) + GWLP_CONSOLE_LEADER_TID)));
+         }
+         else
+         {
+            Result = (DWORD)IntGetWndThreadId(pWnd);
+         }
          break;
+      }
 
       case QUERY_WINDOW_ACTIVE:
          Result = (DWORD)(pWnd->head.pti->MessageQueue->spwndActive ? UserHMGetHandle(pWnd->head.pti->MessageQueue->spwndActive) : 0);
index 1f174ba..bcee979 100644 (file)
@@ -45,7 +45,7 @@ InitWindowStationImpl(VOID)
 
 NTSTATUS
 NTAPI
-UserCreateWinstaDirectoy()
+UserCreateWinstaDirectory()
 {
     PPEB Peb;
     NTSTATUS Status;
index f2d0fba..01d22d2 100644 (file)
@@ -69,7 +69,7 @@ INIT_FUNCTION
 NTSTATUS
 NTAPI
 InitWindowStationImpl(VOID);
-NTSTATUS NTAPI UserCreateWinstaDirectoy();
+NTSTATUS NTAPI UserCreateWinstaDirectory();
 
 VOID APIENTRY IntWinStaObjectDelete(PWIN32_DELETEMETHOD_PARAMETERS Parameters);
 NTSTATUS APIENTRY IntWinStaObjectParse(PWIN32_PARSEMETHOD_PARAMETERS Parameters);