- 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
This commit is contained in:
Hermès Bélusca-Maïto 2013-01-04 00:41:10 +00:00
parent 31776e274a
commit 7851c1a1c2
15 changed files with 218 additions and 79 deletions

View file

@ -1562,12 +1562,19 @@ NTAPI
NtUserCloseWindowStation( NtUserCloseWindowStation(
HWINSTA hWinSta); HWINSTA hWinSta);
DWORD /* Console commands for NtUserConsoleControl */
NTAPI typedef enum _CONSOLECONTROL
{
GuiConsoleWndClassAtom,
TuiConsoleWndClassAtom,
} CONSOLECONTROL, *PCONSOLECONTROL;
NTSTATUS
APIENTRY
NtUserConsoleControl( NtUserConsoleControl(
DWORD dwUnknown1, IN CONSOLECONTROL ConsoleCtrl,
DWORD dwUnknown2, IN PVOID ConsoleCtrlInfo,
DWORD dwUnknown3); IN DWORD ConsoleCtrlInfoLength);
HANDLE HANDLE
NTAPI NTAPI

View file

@ -50,6 +50,7 @@ typedef struct tagCSRSS_CONSOLE
struct tagCSRSS_CONSOLE *Prev, *Next; /* Next and Prev consoles in console wheel */ struct tagCSRSS_CONSOLE *Prev, *Next; /* Next and Prev consoles in console wheel */
struct tagCSRSS_CONSOLE_VTBL *Vtbl; /* Using CUI or GUI consoles */ struct tagCSRSS_CONSOLE_VTBL *Vtbl; /* Using CUI or GUI consoles */
CLIENT_ID ConsoleLeaderCID; /* Contains the Console Leader Process CID */
LIST_ENTRY ProcessList; LIST_ENTRY ProcessList;
LIST_ENTRY InputEvents; /* List head for input event queue */ LIST_ENTRY InputEvents; /* List head for input event queue */
@ -90,6 +91,19 @@ typedef struct tagCSRSS_CONSOLE
CONSOLE_SELECTION_INFO Selection; CONSOLE_SELECTION_INFO Selection;
} CSRSS_CONSOLE, *PCSRSS_CONSOLE; } 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 typedef struct tagCSRSS_CONSOLE_VTBL
{ {
VOID (WINAPI *InitScreenBuffer)(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER ScreenBuffer); VOID (WINAPI *InitScreenBuffer)(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER ScreenBuffer);
@ -146,6 +160,7 @@ NTSTATUS FASTCALL ConioConsoleFromProcessData(PCONSOLE_PROCESS_DATA ProcessData,
PCSRSS_CONSOLE *Console); PCSRSS_CONSOLE *Console);
VOID WINAPI ConioDeleteConsole(PCSRSS_CONSOLE Console); VOID WINAPI ConioDeleteConsole(PCSRSS_CONSOLE Console);
VOID WINAPI CsrInitConsoleSupport(VOID); 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 ConioPause(PCSRSS_CONSOLE Console, UINT Flags);
VOID FASTCALL ConioUnpause(PCSRSS_CONSOLE Console, UINT Flags); VOID FASTCALL ConioUnpause(PCSRSS_CONSOLE Console, UINT Flags);
VOID FASTCALL ConioConsoleCtrlEvent(DWORD Event, PCONSOLE_PROCESS_DATA ProcessData); VOID FASTCALL ConioConsoleCtrlEvent(DWORD Event, PCONSOLE_PROCESS_DATA ProcessData);

View file

@ -87,8 +87,8 @@ ConioConsoleCtrlEvent(DWORD Event, PCONSOLE_PROCESS_DATA ProcessData)
ConioConsoleCtrlEventTimeout(Event, ProcessData, 0); ConioConsoleCtrlEventTimeout(Event, ProcessData, 0);
} }
/* static */ NTSTATUS WINAPI NTSTATUS WINAPI
CsrInitConsole(PCSRSS_CONSOLE* NewConsole, int ShowCmd) CsrInitConsole(PCSRSS_CONSOLE* NewConsole, int ShowCmd, PCSR_PROCESS ConsoleLeaderProcess)
{ {
NTSTATUS Status; NTSTATUS Status;
SECURITY_ATTRIBUTES SecurityAttributes; SECURITY_ATTRIBUTES SecurityAttributes;
@ -127,6 +127,7 @@ CsrInitConsole(PCSRSS_CONSOLE* NewConsole, int ShowCmd)
Console->Header.Type = CONIO_CONSOLE_MAGIC; Console->Header.Type = CONIO_CONSOLE_MAGIC;
Console->Header.Console = Console; Console->Header.Console = Console;
Console->Mode = ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT; Console->Mode = ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT;
Console->ConsoleLeaderCID = ConsoleLeaderProcess->ClientId;
InitializeListHead(&Console->ProcessList); InitializeListHead(&Console->ProcessList);
InitializeListHead(&Console->BufferList); InitializeListHead(&Console->BufferList);
Console->ActiveBuffer = NULL; Console->ActiveBuffer = NULL;
@ -292,7 +293,8 @@ CSR_API(SrvAllocConsole)
{ {
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
PCSRSS_ALLOC_CONSOLE AllocConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.AllocConsoleRequest; 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"); DPRINT("SrvAllocConsole\n");
@ -306,8 +308,8 @@ CSR_API(SrvAllocConsole)
DPRINT1("SrvAllocConsole - Checkpoint 1\n"); DPRINT1("SrvAllocConsole - Checkpoint 1\n");
/* Initialize a new Console */ /* Initialize a new Console owned by the Console Leader Process */
Status = CsrInitConsole(&ProcessData->Console, AllocConsoleRequest->ShowCmd); Status = CsrInitConsole(&ProcessData->Console, AllocConsoleRequest->ShowCmd, ConsoleLeader);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("Console initialization failed\n"); DPRINT1("Console initialization failed\n");

View file

@ -17,6 +17,9 @@
#define NTOS_MODE_USER #define NTOS_MODE_USER
#include <ndk/ntndk.h> #include <ndk/ntndk.h>
/* Public Win32K Headers */
#include <ntuser.h>
/* CSRSS Header */ /* CSRSS Header */
#include <csr/csrsrv.h> #include <csr/csrsrv.h>

View file

@ -12,12 +12,14 @@
#include "guiconsole.h" #include "guiconsole.h"
#include <psapi.h> #include <psapi.h>
/* Public Win32K Headers */
#include <ntuser.h>
#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
/* GUI Console Window Class name */
#define GUI_CONSOLE_WINDOW_CLASS L"ConsoleWindowClass"
/* Not defined in any header file */ /* Not defined in any header file */
// extern VOID WINAPI PrivateCsrssManualGuiCheck(LONG Check); // extern VOID WINAPI PrivateCsrssManualGuiCheck(LONG Check);
// From win32ss/user/win32csr/dllmain.c // From win32ss/user/win32csr/dllmain.c
@ -194,7 +196,7 @@ GuiConsoleCreateSysMenu(PCSRSS_CONSOLE Console)
static VOID static VOID
GuiConsoleGetDataPointers(HWND hWnd, PCSRSS_CONSOLE *Console, PGUI_CONSOLE_DATA *GuiData) 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); *GuiData = (NULL == *Console ? NULL : (*Console)->PrivateData);
} }
@ -693,9 +695,9 @@ GuiConsoleInitScrollbar(PCSRSS_CONSOLE Console, HWND hwnd)
} }
static BOOL 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; PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA)Console->PrivateData;
HDC Dc; HDC Dc;
HFONT OldFont; HFONT OldFont;
@ -788,7 +790,7 @@ GuiConsoleHandleNcCreate(HWND hWnd, CREATESTRUCTW *Create)
DPRINT("Console %p GuiData %p\n", Console, GuiData); DPRINT("Console %p GuiData %p\n", Console, GuiData);
Console->PrivateData = 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); SetTimer(hWnd, CONGUI_UPDATE_TIMER, CONGUI_UPDATE_TIME, NULL);
GuiConsoleCreateSysMenu(Console); GuiConsoleCreateSysMenu(Console);
@ -1512,7 +1514,6 @@ GuiConsoleRightMouseDown(HWND hWnd)
} }
static VOID static VOID
GuiConsoleShowConsoleProperties(HWND hWnd, BOOL Defaults, PGUI_CONSOLE_DATA GuiData) GuiConsoleShowConsoleProperties(HWND hWnd, BOOL Defaults, PGUI_CONSOLE_DATA GuiData)
{ {
@ -2004,7 +2005,7 @@ GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
switch(msg) switch(msg)
{ {
case WM_NCCREATE: case WM_NCCREATE:
Result = (LRESULT) GuiConsoleHandleNcCreate(hWnd, (CREATESTRUCTW *) lParam); Result = (LRESULT) GuiConsoleHandleNcCreate(hWnd, (LPCREATESTRUCTW)lParam);
break; break;
case WM_PAINT: case WM_PAINT:
GuiConsoleHandlePaint(hWnd, (HDC)wParam); GuiConsoleHandlePaint(hWnd, (HDC)wParam);
@ -2074,8 +2075,6 @@ GuiConsoleNotifyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
PWCHAR Buffer, Title; PWCHAR Buffer, Title;
PCSRSS_CONSOLE Console = (PCSRSS_CONSOLE) lParam; PCSRSS_CONSOLE Console = (PCSRSS_CONSOLE) lParam;
switch(msg) switch(msg)
{ {
case WM_CREATE: case WM_CREATE:
@ -2095,7 +2094,7 @@ GuiConsoleNotifyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
Title = L""; Title = L"";
} }
NewWindow = CreateWindowExW(WS_EX_CLIENTEDGE, NewWindow = CreateWindowExW(WS_EX_CLIENTEDGE,
L"ConsoleWindowClass", GUI_CONSOLE_WINDOW_CLASS,
Title, Title,
WS_OVERLAPPEDWINDOW | WS_HSCROLL | WS_VSCROLL, WS_OVERLAPPEDWINDOW | WS_HSCROLL | WS_VSCROLL,
CW_USEDEFAULT, CW_USEDEFAULT,
@ -2104,18 +2103,19 @@ GuiConsoleNotifyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL,
NULL, NULL,
(HINSTANCE) GetModuleHandleW(NULL), (HINSTANCE)GetModuleHandleW(NULL),
(PVOID) Console); (PVOID)Console);
if (NULL != Buffer) if (NULL != Buffer)
{ {
HeapFree(ConSrvHeap, 0, Buffer); HeapFree(ConSrvHeap, 0, Buffer);
} }
if (NULL != NewWindow) if (NULL != NewWindow)
{ {
SetConsoleWndConsoleLeaderCID(Console);
SetWindowLongW(hWnd, GWL_USERDATA, GetWindowLongW(hWnd, GWL_USERDATA) + 1); SetWindowLongW(hWnd, GWL_USERDATA, GetWindowLongW(hWnd, GWL_USERDATA) + 1);
ShowWindow(NewWindow, (int)wParam); ShowWindow(NewWindow, (int)wParam);
} }
return (LRESULT) NewWindow; return (LRESULT)NewWindow;
case PM_DESTROY_CONSOLE: case PM_DESTROY_CONSOLE:
/* Window creation is done using a PostMessage(), so it's possible that the /* 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 * window that we want to destroy doesn't exist yet. So first empty the message
@ -2182,6 +2182,7 @@ static BOOL
GuiInit(VOID) GuiInit(VOID)
{ {
WNDCLASSEXW wc; WNDCLASSEXW wc;
ATOM ConsoleClassAtom;
if (NULL == NotifyWnd) if (NULL == NotifyWnd)
{ {
@ -2202,12 +2203,12 @@ GuiInit(VOID)
wc.hIconSm = NULL; wc.hIconSm = NULL;
if (RegisterClassExW(&wc) == 0) if (RegisterClassExW(&wc) == 0)
{ {
DPRINT1("Failed to register notify wndproc\n"); DPRINT1("Failed to register GUI notify wndproc\n");
return FALSE; return FALSE;
} }
wc.cbSize = sizeof(WNDCLASSEXW); wc.cbSize = sizeof(WNDCLASSEXW);
wc.lpszClassName = L"ConsoleWindowClass"; wc.lpszClassName = GUI_CONSOLE_WINDOW_CLASS;
wc.lpfnWndProc = GuiConsoleWndProc; wc.lpfnWndProc = GuiConsoleWndProc;
wc.style = 0; wc.style = 0;
wc.hInstance = (HINSTANCE)GetModuleHandleW(NULL); wc.hInstance = (HINSTANCE)GetModuleHandleW(NULL);
@ -2216,15 +2217,21 @@ GuiInit(VOID)
wc.hbrBackground = CreateSolidBrush(RGB(0,0,0)); wc.hbrBackground = CreateSolidBrush(RGB(0,0,0));
wc.lpszMenuName = NULL; wc.lpszMenuName = NULL;
wc.cbClsExtra = 0; wc.cbClsExtra = 0;
wc.cbWndExtra = 0; wc.cbWndExtra = GWLP_CONSOLEWND_ALLOC;
wc.hIconSm = LoadImageW(ConSrvDllInstance, MAKEINTRESOURCEW(1), IMAGE_ICON, wc.hIconSm = LoadImageW(ConSrvDllInstance, MAKEINTRESOURCEW(1), IMAGE_ICON,
GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON),
LR_SHARED); 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; return FALSE;
} }
else
{
NtUserConsoleControl(GuiConsoleWndClassAtom, &ConsoleClassAtom, sizeof(ATOM));
}
return TRUE; return TRUE;
} }
@ -2299,10 +2306,10 @@ GuiInitConsole(PCSRSS_CONSOLE Console, int ShowCmd)
HANDLE ThreadHandle; HANDLE ThreadHandle;
PGUI_CONSOLE_DATA GuiData; PGUI_CONSOLE_DATA GuiData;
if (! ConsInitialized) if (!ConsInitialized)
{ {
ConsInitialized = TRUE; ConsInitialized = TRUE;
if (! GuiInit()) if (!GuiInit())
{ {
ConsInitialized = FALSE; ConsInitialized = FALSE;
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
@ -2310,6 +2317,7 @@ GuiInitConsole(PCSRSS_CONSOLE Console, int ShowCmd)
} }
Console->Vtbl = &GuiVtbl; Console->Vtbl = &GuiVtbl;
Console->hWindow = NULL;
if (NULL == NotifyWnd) if (NULL == NotifyWnd)
{ {
GraphicsStartupEvent = CreateEventW(NULL, FALSE, FALSE, NULL); GraphicsStartupEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
@ -2321,7 +2329,7 @@ GuiInitConsole(PCSRSS_CONSOLE Console, int ShowCmd)
ThreadHandle = CreateThread(NULL, ThreadHandle = CreateThread(NULL,
0, 0,
GuiConsoleGuiThread, GuiConsoleGuiThread,
(PVOID) &GraphicsStartupEvent, (PVOID)&GraphicsStartupEvent,
0, 0,
NULL); NULL);
if (NULL == ThreadHandle) if (NULL == ThreadHandle)
@ -2350,9 +2358,9 @@ GuiInitConsole(PCSRSS_CONSOLE Console, int ShowCmd)
return STATUS_UNSUCCESSFUL; 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.. * to retrieve custom settings i.e. WindowSize etc..
* Ideally we could use SendNotifyMessage for this but its not * Ideally we could use SendNotifyMessage for this but its not
* yet implemented. * yet implemented.
@ -2362,7 +2370,7 @@ GuiInitConsole(PCSRSS_CONSOLE Console, int ShowCmd)
/* create console */ /* create console */
PostMessageW(NotifyWnd, PM_CREATE_CONSOLE, ShowCmd, (LPARAM)Console); PostMessageW(NotifyWnd, PM_CREATE_CONSOLE, ShowCmd, (LPARAM)Console);
/* wait untill initialization has finished */ /* wait until initialization has finished */
WaitForSingleObject(GuiData->hGuiInitEvent, INFINITE); 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); DPRINT("received event Console %p GuiData %p X %d Y %d\n", Console, Console->PrivateData, Console->Size.X, Console->Size.Y);
CloseHandle(GuiData->hGuiInitEvent); CloseHandle(GuiData->hGuiInitEvent);

View file

@ -321,9 +321,6 @@ ConsoleNewProcess(PCSR_PROCESS SourceProcess,
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
// Temporary ; move it to a header.
NTSTATUS WINAPI CsrInitConsole(PCSRSS_CONSOLE* NewConsole, int ShowCmd);
NTSTATUS NTSTATUS
NTAPI NTAPI
ConsoleConnect(IN PCSR_PROCESS CsrProcess, ConsoleConnect(IN PCSR_PROCESS CsrProcess,
@ -363,13 +360,11 @@ ConsoleConnect(IN PCSR_PROCESS CsrProcess,
if (!ConnectInfo->Console || if (!ConnectInfo->Console ||
ConnectInfo->Console != ProcessData->ParentConsole) ConnectInfo->Console != ProcessData->ParentConsole)
{ {
// PCSRSS_CONSOLE Console;
DPRINT1("ConsoleConnect - Allocate a new console\n"); DPRINT1("ConsoleConnect - Allocate a new console\n");
/* Initialize a new Console */ /* Initialize a new Console owned by the Console Leader Process */
NewConsole = TRUE; NewConsole = TRUE;
Status = CsrInitConsole(&ProcessData->Console, ConnectInfo->ShowCmd); Status = CsrInitConsole(&ProcessData->Console, ConnectInfo->ShowCmd, CsrProcess);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("Console initialization failed\n"); DPRINT1("Console initialization failed\n");

View file

@ -13,6 +13,11 @@
#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
/* TUI Console Window Class name */
#define TUI_CONSOLE_WINDOW_CLASS L"TuiConsoleWindowClass"
CRITICAL_SECTION ActiveConsoleLock; CRITICAL_SECTION ActiveConsoleLock;
static COORD PhysicalConsoleSize; static COORD PhysicalConsoleSize;
static HANDLE ConsoleDeviceHandle; static HANDLE ConsoleDeviceHandle;
@ -69,6 +74,7 @@ TuiInit(DWORD OemCP)
CONSOLE_SCREEN_BUFFER_INFO ScrInfo; CONSOLE_SCREEN_BUFFER_INFO ScrInfo;
DWORD BytesReturned; DWORD BytesReturned;
WNDCLASSEXW wc; WNDCLASSEXW wc;
ATOM ConsoleClassAtom;
USHORT TextAttribute = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED; USHORT TextAttribute = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED;
TuiStartService(L"Blue"); TuiStartService(L"Blue");
@ -98,8 +104,8 @@ TuiInit(DWORD OemCP)
ActiveConsole = NULL; ActiveConsole = NULL;
InitializeCriticalSection(&ActiveConsoleLock); InitializeCriticalSection(&ActiveConsoleLock);
if (! DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO, if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO,
NULL, 0, &ScrInfo, sizeof(ScrInfo), &BytesReturned, NULL)) NULL, 0, &ScrInfo, sizeof(ScrInfo), &BytesReturned, NULL))
{ {
DPRINT1("Failed to get console info\n"); DPRINT1("Failed to get console info\n");
return FALSE; return FALSE;
@ -108,14 +114,21 @@ TuiInit(DWORD OemCP)
RtlZeroMemory(&wc, sizeof(WNDCLASSEXW)); RtlZeroMemory(&wc, sizeof(WNDCLASSEXW));
wc.cbSize = sizeof(WNDCLASSEXW); wc.cbSize = sizeof(WNDCLASSEXW);
wc.lpszClassName = L"TuiConsoleWindowClass"; wc.lpszClassName = TUI_CONSOLE_WINDOW_CLASS;
wc.lpfnWndProc = TuiConsoleWndProc; wc.lpfnWndProc = TuiConsoleWndProc;
wc.hInstance = (HINSTANCE) GetModuleHandleW(NULL); wc.cbWndExtra = GWLP_CONSOLEWND_ALLOC;
if (RegisterClassExW(&wc) == 0) 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; return FALSE;
} }
else
{
NtUserConsoleControl(TuiConsoleWndClassAtom, &ConsoleClassAtom, sizeof(ATOM));
}
return TRUE; return TRUE;
} }
@ -179,8 +192,8 @@ TuiDrawRegion(PCSRSS_CONSOLE Console, SMALL_RECT *Region)
TuiCopyRect((char *) (ConsoleDraw + 1), Buff, Region); TuiCopyRect((char *) (ConsoleDraw + 1), Buff, Region);
if (! DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_DRAW, if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_DRAW,
NULL, 0, ConsoleDraw, ConsoleDrawSize, &BytesReturned, NULL)) NULL, 0, ConsoleDraw, ConsoleDrawSize, &BytesReturned, NULL))
{ {
DPRINT1("Failed to draw console\n"); DPRINT1("Failed to draw console\n");
HeapFree(ConSrvHeap, 0, ConsoleDraw); HeapFree(ConSrvHeap, 0, ConsoleDraw);
@ -222,8 +235,8 @@ TuiSetCursorInfo(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff)
Info.dwSize = ConioEffectiveCursorSize(Console, 100); Info.dwSize = ConioEffectiveCursorSize(Console, 100);
Info.bVisible = Buff->CursorInfo.bVisible; Info.bVisible = Buff->CursorInfo.bVisible;
if (! DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_SET_CURSOR_INFO, if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_SET_CURSOR_INFO,
&Info, sizeof(Info), NULL, 0, &BytesReturned, NULL)) &Info, sizeof(Info), NULL, 0, &BytesReturned, NULL))
{ {
DPRINT1( "Failed to set cursor info\n" ); DPRINT1( "Failed to set cursor info\n" );
return FALSE; return FALSE;
@ -247,9 +260,9 @@ TuiSetScreenInfo(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff, UINT OldCurs
Info.dwCursorPosition.Y = Buff->CurrentY; Info.dwCursorPosition.Y = Buff->CurrentY;
Info.wAttributes = Buff->DefaultAttrib; Info.wAttributes = Buff->DefaultAttrib;
if (! DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO, if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO,
&Info, sizeof(CONSOLE_SCREEN_BUFFER_INFO), NULL, 0, &Info, sizeof(CONSOLE_SCREEN_BUFFER_INFO), NULL, 0,
&BytesReturned, NULL)) &BytesReturned, NULL))
{ {
DPRINT1( "Failed to set cursor position\n" ); DPRINT1( "Failed to set cursor position\n" );
return FALSE; return FALSE;
@ -316,19 +329,20 @@ TuiConsoleThread(PVOID Data)
HWND NewWindow; HWND NewWindow;
MSG msg; MSG msg;
NewWindow = CreateWindowW(L"TuiConsoleWindowClass", NewWindow = CreateWindowW(TUI_CONSOLE_WINDOW_CLASS,
Console->Title.Buffer, Console->Title.Buffer,
0, 0,
-32000, -32000, 0, 0, -32000, -32000, 0, 0,
NULL, NULL, NULL, NULL,
(HINSTANCE) GetModuleHandleW(NULL), (HINSTANCE)GetModuleHandleW(NULL),
(PVOID) Console); (PVOID)Console);
Console->hWindow = NewWindow;
if (NULL == NewWindow) if (NULL == NewWindow)
{ {
DPRINT1("CSR: Unable to create console window\n"); DPRINT1("CSR: Unable to create console window\n");
return 1; return 1;
} }
Console->hWindow = NewWindow;
SetConsoleWndConsoleLeaderCID(Console);
SetForegroundWindow(Console->hWindow); SetForegroundWindow(Console->hWindow);
@ -368,10 +382,10 @@ TuiInitConsole(PCSRSS_CONSOLE Console)
{ {
HANDLE ThreadHandle; HANDLE ThreadHandle;
if (! ConsInitialized) if (!ConsInitialized)
{ {
ConsInitialized = TRUE; ConsInitialized = TRUE;
if (! TuiInit(Console->CodePage)) if (!TuiInit(Console->CodePage))
{ {
ConsInitialized = FALSE; ConsInitialized = FALSE;
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
@ -384,8 +398,12 @@ TuiInitConsole(PCSRSS_CONSOLE Console)
Console->ActiveBuffer->MaxX = PhysicalConsoleSize.X; Console->ActiveBuffer->MaxX = PhysicalConsoleSize.X;
Console->ActiveBuffer->MaxY = PhysicalConsoleSize.Y; Console->ActiveBuffer->MaxY = PhysicalConsoleSize.Y;
ThreadHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)TuiConsoleThread, ThreadHandle = CreateThread(NULL,
Console, 0, NULL); 0,
TuiConsoleThread,
(PVOID)Console,
0,
NULL);
if (NULL == ThreadHandle) if (NULL == ThreadHandle)
{ {
DPRINT1("CSR: Unable to create console thread\n"); DPRINT1("CSR: Unable to create console thread\n");
@ -451,9 +469,9 @@ TuiSwapConsole(int Next)
pos->X = (PhysicalConsoleSize.X - Title.Length) / 2; pos->X = (PhysicalConsoleSize.X - Title.Length) / 2;
/* redraw the console to clear off old title */ /* redraw the console to clear off old title */
ConioDrawConsole(ActiveConsole); ConioDrawConsole(ActiveConsole);
if (! DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER, if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER,
NULL, 0, Buffer, sizeof(COORD) + Title.Length, NULL, 0, Buffer, sizeof(COORD) + Title.Length,
&BytesReturned, NULL)) &BytesReturned, NULL))
{ {
DPRINT1( "Error writing to console\n" ); DPRINT1( "Error writing to console\n" );
} }

View file

@ -304,6 +304,8 @@ UserCreateThreadInfo(struct _ETHREAD *Thread)
if (ptiCurrent->KeyboardLayout) if (ptiCurrent->KeyboardLayout)
UserReferenceObject(ptiCurrent->KeyboardLayout); UserReferenceObject(ptiCurrent->KeyboardLayout);
ptiCurrent->TIF_flags &= ~TIF_INCLEANUP; 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; ptiCurrent->pcti = &ptiCurrent->cti;
/* Initialize the CLIENTINFO */ /* Initialize the CLIENTINFO */

View file

@ -559,15 +559,66 @@ NtUserCheckImeHotKey(
return 0; return 0;
} }
DWORD NTSTATUS
APIENTRY APIENTRY
NtUserConsoleControl( NtUserConsoleControl(
DWORD dwUnknown1, IN CONSOLECONTROL ConsoleCtrl,
DWORD dwUnknown2, IN PVOID ConsoleCtrlInfo,
DWORD dwUnknown3) IN DWORD ConsoleCtrlInfoLength)
{ {
STUB; NTSTATUS Status = STATUS_SUCCESS;
return 0;
/* 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 DWORD

View file

@ -21,6 +21,8 @@ BOOL gbInitialized;
HINSTANCE hModClient = NULL; HINSTANCE hModClient = NULL;
BOOL ClientPfnInit = FALSE; BOOL ClientPfnInit = FALSE;
PEPROCESS gpepCSRSS = NULL; PEPROCESS gpepCSRSS = NULL;
ATOM gaGuiConsoleWndClass;
ATOM gaTuiConsoleWndClass;
/* PRIVATE FUNCTIONS *********************************************************/ /* PRIVATE FUNCTIONS *********************************************************/
@ -105,7 +107,7 @@ UserInitialize(
// Set W32PF_Flags |= (W32PF_READSCREENACCESSGRANTED | W32PF_IOWINSTA) // Set W32PF_Flags |= (W32PF_READSCREENACCESSGRANTED | W32PF_IOWINSTA)
// Create Event for Diconnect Desktop. // Create Event for Diconnect Desktop.
Status = UserCreateWinstaDirectoy(); Status = UserCreateWinstaDirectory();
if (!NT_SUCCESS(Status)) return Status; if (!NT_SUCCESS(Status)) return Status;
/* Initialize Video. */ /* Initialize Video. */
@ -121,7 +123,9 @@ UserInitialize(
// Create ThreadInfo for this Thread! // 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 // Callback to User32 Client Thread Setup

View file

@ -16,6 +16,8 @@ extern PPROCESSINFO gppiList;
extern PPROCESSINFO ppiScrnSaver; extern PPROCESSINFO ppiScrnSaver;
extern PPROCESSINFO gppiInputProvider; extern PPROCESSINFO gppiInputProvider;
extern PEPROCESS gpepCSRSS; extern PEPROCESS gpepCSRSS;
extern ATOM gaGuiConsoleWndClass;
extern ATOM gaTuiConsoleWndClass;
INIT_FUNCTION NTSTATUS NTAPI InitUserImpl(VOID); INIT_FUNCTION NTSTATUS NTAPI InitUserImpl(VOID);
VOID FASTCALL CleanupUserImpl(VOID); VOID FASTCALL CleanupUserImpl(VOID);

View file

@ -37,6 +37,10 @@ PMENU_OBJECT FASTCALL UserGetMenuObject(HMENU hMenu);
PWND FASTCALL IntGetWindowObject(HWND hWnd); PWND FASTCALL IntGetWindowObject(HWND hWnd);
/*************** MAIN.C ***************/
NTSTATUS NTAPI UserCreateThreadInfo(struct _ETHREAD *Thread);
/*************** WINSTA.C ***************/ /*************** WINSTA.C ***************/
HWINSTA FASTCALL UserGetProcessWindowStation(VOID); HWINSTA FASTCALL UserGetProcessWindowStation(VOID);

View file

@ -3720,6 +3720,10 @@ CLEANUP:
DWORD APIENTRY DWORD APIENTRY
NtUserQueryWindow(HWND hWnd, DWORD Index) 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; PWND pWnd;
DWORD Result; DWORD Result;
DECLARE_RETURN(UINT); DECLARE_RETURN(UINT);
@ -3735,12 +3739,36 @@ NtUserQueryWindow(HWND hWnd, DWORD Index)
switch(Index) switch(Index)
{ {
case QUERY_WINDOW_UNIQUE_PROCESS_ID: 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; break;
}
case QUERY_WINDOW_UNIQUE_THREAD_ID: 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; break;
}
case QUERY_WINDOW_ACTIVE: case QUERY_WINDOW_ACTIVE:
Result = (DWORD)(pWnd->head.pti->MessageQueue->spwndActive ? UserHMGetHandle(pWnd->head.pti->MessageQueue->spwndActive) : 0); Result = (DWORD)(pWnd->head.pti->MessageQueue->spwndActive ? UserHMGetHandle(pWnd->head.pti->MessageQueue->spwndActive) : 0);

View file

@ -45,7 +45,7 @@ InitWindowStationImpl(VOID)
NTSTATUS NTSTATUS
NTAPI NTAPI
UserCreateWinstaDirectoy() UserCreateWinstaDirectory()
{ {
PPEB Peb; PPEB Peb;
NTSTATUS Status; NTSTATUS Status;

View file

@ -69,7 +69,7 @@ INIT_FUNCTION
NTSTATUS NTSTATUS
NTAPI NTAPI
InitWindowStationImpl(VOID); InitWindowStationImpl(VOID);
NTSTATUS NTAPI UserCreateWinstaDirectoy(); NTSTATUS NTAPI UserCreateWinstaDirectory();
VOID APIENTRY IntWinStaObjectDelete(PWIN32_DELETEMETHOD_PARAMETERS Parameters); VOID APIENTRY IntWinStaObjectDelete(PWIN32_DELETEMETHOD_PARAMETERS Parameters);
NTSTATUS APIENTRY IntWinStaObjectParse(PWIN32_PARSEMETHOD_PARAMETERS Parameters); NTSTATUS APIENTRY IntWinStaObjectParse(PWIN32_PARSEMETHOD_PARAMETERS Parameters);