mirror of
https://github.com/reactos/reactos.git
synced 2025-03-30 17:10:22 +00:00
[NTUSER] Implement creating the system threads
- Add UserCreateSystemThread function that will signal csrss to create a new system thread. - NtUserCreateWindowStation: Create the raw input thread and the desktop thread when the IO window station gets created. - IntMakeHungWindowGhosted: Create the ghost system thread that will own all ghost windows. - Let the raw input thread manage the window station of csrss. [USERSRV] Remove system threads creating hack - Implement SrvCreateSystemThreads - Don't create the system threads in UserServerDllInitialization.
This commit is contained in:
parent
9924da34cc
commit
1a8d9f12d6
11 changed files with 183 additions and 72 deletions
|
@ -14,6 +14,7 @@ DBG_DEFAULT_CHANNEL(UserCsr);
|
|||
|
||||
PEPROCESS gpepCSRSS = NULL;
|
||||
PVOID CsrApiPort = NULL;
|
||||
DWORD gdwPendingSystemThreads = 0;
|
||||
|
||||
VOID
|
||||
InitCsrProcess(VOID /*IN PEPROCESS CsrProcess*/)
|
||||
|
@ -197,4 +198,83 @@ CsrClientCallServer(IN OUT PCSR_API_MESSAGE ApiMessage,
|
|||
return ApiMessage->Status;
|
||||
}
|
||||
|
||||
/*
|
||||
* UserSystemThreadProc
|
||||
*
|
||||
* Called form dedicated thread in CSRSS. RIT is started in context of this
|
||||
* thread because it needs valid Win32 process with TEB initialized.
|
||||
*/
|
||||
DWORD UserSystemThreadProc(BOOL bRemoteProcess)
|
||||
{
|
||||
DWORD Type;
|
||||
|
||||
if (!gdwPendingSystemThreads)
|
||||
{
|
||||
ERR("gdwPendingSystemThreads is 0!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Decide which thread this will be */
|
||||
if (gdwPendingSystemThreads & ST_RIT)
|
||||
Type = ST_RIT;
|
||||
else if (gdwPendingSystemThreads & ST_DESKTOP_THREAD)
|
||||
Type = ST_DESKTOP_THREAD;
|
||||
else
|
||||
Type = ST_GHOST_THREAD;
|
||||
|
||||
ASSERT(Type);
|
||||
|
||||
/* We will handle one of these threads right here so unmark it as pending */
|
||||
gdwPendingSystemThreads &= ~Type;
|
||||
|
||||
UserLeave();
|
||||
|
||||
TRACE("UserSystemThreadProc: %d\n", Type);
|
||||
|
||||
switch (Type)
|
||||
{
|
||||
case ST_RIT: RawInputThreadMain(); break;
|
||||
case ST_DESKTOP_THREAD: DesktopThreadMain(); break;
|
||||
case ST_GHOST_THREAD: UserGhostThreadEntry(); break;
|
||||
default: ERR("Wrong type: %x\n", Type);
|
||||
}
|
||||
|
||||
UserEnterShared();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
BOOL UserCreateSystemThread(DWORD Type)
|
||||
{
|
||||
USER_API_MESSAGE ApiMessage;
|
||||
PUSER_CREATE_SYSTEM_THREAD pCreateThreadRequest = &ApiMessage.Data.CreateSystemThreadRequest;
|
||||
|
||||
TRACE("UserCreateSystemThread: %d\n", Type);
|
||||
|
||||
ASSERT(UserIsEnteredExclusive());
|
||||
|
||||
if (gdwPendingSystemThreads & Type)
|
||||
{
|
||||
ERR("System thread 0x%x already pending for creation\n", Type);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* We can't pass a parameter to the new thread so mark what the new thread needs to do */
|
||||
gdwPendingSystemThreads |= Type;
|
||||
|
||||
/* Ask winsrv to create a new system thread. This new thread will enter win32k again calling UserSystemThreadProc */
|
||||
pCreateThreadRequest->bRemote = FALSE;
|
||||
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
|
||||
NULL,
|
||||
CSR_CREATE_API_NUMBER(USERSRV_SERVERDLL_INDEX, UserpCreateSystemThreads),
|
||||
sizeof(USER_CREATE_SYSTEM_THREAD));
|
||||
if (!NT_SUCCESS(ApiMessage.Status))
|
||||
{
|
||||
ERR("Csr call failed!\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -32,4 +32,11 @@ CsrClientCallServer(IN OUT PCSR_API_MESSAGE ApiMessage,
|
|||
IN CSR_API_NUMBER ApiNumber,
|
||||
IN ULONG DataLength);
|
||||
|
||||
#define ST_RIT (1<<0)
|
||||
#define ST_DESKTOP_THREAD (1<<1)
|
||||
#define ST_GHOST_THREAD (1<<2)
|
||||
|
||||
DWORD UserSystemThreadProc(BOOL bRemoteProcess);
|
||||
BOOL UserCreateSystemThread(DWORD Type);
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -36,6 +36,7 @@ PDESKTOP gpdeskInputDesktop = NULL;
|
|||
HDC ScreenDeviceContext = NULL;
|
||||
PTHREADINFO gptiDesktopThread = NULL;
|
||||
HCURSOR gDesktopCursor = NULL;
|
||||
PKEVENT gpDesktopThreadStartedEvent = NULL;
|
||||
|
||||
/* OBJECT CALLBACKS **********************************************************/
|
||||
|
||||
|
@ -243,6 +244,22 @@ InitDesktopImpl(VOID)
|
|||
ExDesktopObjectType->TypeInfo.DefaultNonPagedPoolCharge = sizeof(DESKTOP);
|
||||
ExDesktopObjectType->TypeInfo.GenericMapping = IntDesktopMapping;
|
||||
ExDesktopObjectType->TypeInfo.ValidAccessMask = DESKTOP_ALL_ACCESS;
|
||||
|
||||
/* Allocate memory for the event structure */
|
||||
gpDesktopThreadStartedEvent = ExAllocatePoolWithTag(NonPagedPool,
|
||||
sizeof(KEVENT),
|
||||
USERTAG_EVENT);
|
||||
if (!gpDesktopThreadStartedEvent)
|
||||
{
|
||||
ERR("Failed to allocate event!\n");
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
/* Initialize the kernel event */
|
||||
KeInitializeEvent(gpDesktopThreadStartedEvent,
|
||||
SynchronizationEvent,
|
||||
FALSE);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1501,6 +1518,8 @@ VOID NTAPI DesktopThreadMain(VOID)
|
|||
classes will be allocated from the shared heap */
|
||||
UserRegisterSystemClasses();
|
||||
|
||||
KeSetEvent(gpDesktopThreadStartedEvent, IO_NO_INCREMENT, FALSE);
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
Ret = co_IntGetPeekMessage(&Msg, 0, 0, 0, PM_REMOVE, TRUE);
|
||||
|
|
|
@ -86,6 +86,7 @@ extern PCLS DesktopWindowClass;
|
|||
extern HDC ScreenDeviceContext;
|
||||
extern PTHREADINFO gptiForeground;
|
||||
extern PTHREADINFO gptiDesktopThread;
|
||||
extern PKEVENT gpDesktopThreadStartedEvent;
|
||||
|
||||
typedef struct _SHELL_HOOK_WINDOW
|
||||
{
|
||||
|
|
|
@ -11,9 +11,34 @@
|
|||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
DBG_DEFAULT_CHANNEL(UserInput);
|
||||
|
||||
static UNICODE_STRING GhostClass = RTL_CONSTANT_STRING(GHOSTCLASSNAME);
|
||||
static UNICODE_STRING GhostProp = RTL_CONSTANT_STRING(GHOST_PROP);
|
||||
|
||||
PTHREADINFO gptiGhostThread = NULL;
|
||||
|
||||
/*
|
||||
* GhostThreadMain
|
||||
*
|
||||
* Creates ghost windows and exits when no non-responsive window remains.
|
||||
*/
|
||||
VOID NTAPI
|
||||
UserGhostThreadEntry(VOID)
|
||||
{
|
||||
TRACE("Ghost thread started\n");
|
||||
|
||||
UserEnterExclusive();
|
||||
|
||||
gptiGhostThread = PsGetCurrentThreadWin32Thread();
|
||||
|
||||
//TODO: Implement. This thread should handle all ghost windows and exit when no ghost window is needed.
|
||||
|
||||
gptiGhostThread = NULL;
|
||||
|
||||
UserLeave();
|
||||
}
|
||||
|
||||
BOOL FASTCALL IntIsGhostWindow(PWND Window)
|
||||
{
|
||||
BOOLEAN Ret = FALSE;
|
||||
|
@ -161,18 +186,10 @@ BOOL FASTCALL IntMakeHungWindowGhosted(HWND hwndHung)
|
|||
return FALSE; // already ghosting
|
||||
}
|
||||
|
||||
// TODO:
|
||||
// 1. Create a thread.
|
||||
// 2. Create a ghost window in the thread.
|
||||
// 3. Do message loop in the thread
|
||||
{
|
||||
static int bWarnedOnce = 0;
|
||||
if (!bWarnedOnce)
|
||||
{
|
||||
bWarnedOnce++;
|
||||
STUB;
|
||||
}
|
||||
}
|
||||
// TODO: Find a way to pass the hwnd of pHungWnd to the ghost thread as we can't pass parameters directly
|
||||
|
||||
return FALSE;
|
||||
if (!gptiGhostThread)
|
||||
UserCreateSystemThread(ST_GHOST_THREAD);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -1 +1,3 @@
|
|||
BOOL FASTCALL IntMakeHungWindowGhosted(HWND hwndHung);
|
||||
VOID NTAPI UserGhostThreadEntry(VOID);
|
||||
|
||||
|
|
|
@ -138,6 +138,7 @@ RawInputThreadMain(VOID)
|
|||
MOUSE_INPUT_DATA MouseInput;
|
||||
KEYBOARD_INPUT_DATA KeyInput;
|
||||
PVOID ShutdownEvent;
|
||||
HWINSTA hWinSta;
|
||||
|
||||
ByteOffset.QuadPart = (LONGLONG)0;
|
||||
//WaitTimeout.QuadPart = (LONGLONG)(-10000000);
|
||||
|
@ -151,6 +152,23 @@ RawInputThreadMain(VOID)
|
|||
KeSetPriorityThread(&PsGetCurrentThread()->Tcb,
|
||||
LOW_REALTIME_PRIORITY + 3);
|
||||
|
||||
Status = ObOpenObjectByPointer(InputWindowStation,
|
||||
0,
|
||||
NULL,
|
||||
MAXIMUM_ALLOWED,
|
||||
ExWindowStationObjectType,
|
||||
UserMode,
|
||||
(PHANDLE)&hWinSta);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
UserSetProcessWindowStation(hWinSta);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(FALSE);
|
||||
/* Failed to open the interactive winsta! What now? */
|
||||
}
|
||||
|
||||
UserEnterExclusive();
|
||||
StartTheTimers();
|
||||
UserLeave();
|
||||
|
@ -330,29 +348,6 @@ RawInputThreadMain(VOID)
|
|||
ERR("Raw Input Thread Exit!\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* CreateSystemThreads
|
||||
*
|
||||
* Called form dedicated thread in CSRSS. RIT is started in context of this
|
||||
* thread because it needs valid Win32 process with TEB initialized.
|
||||
*/
|
||||
DWORD NTAPI
|
||||
CreateSystemThreads(UINT Type)
|
||||
{
|
||||
UserLeave();
|
||||
|
||||
switch (Type)
|
||||
{
|
||||
case 0: RawInputThreadMain(); break;
|
||||
case 1: DesktopThreadMain(); break;
|
||||
default: ERR("Wrong type: %x\n", Type);
|
||||
}
|
||||
|
||||
UserEnterShared();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* InitInputImpl
|
||||
*
|
||||
|
|
|
@ -60,8 +60,8 @@ extern PATTACHINFO gpai;
|
|||
|
||||
/* General */
|
||||
INIT_FUNCTION NTSTATUS NTAPI InitInputImpl(VOID);
|
||||
VOID NTAPI RawInputThreadMain(VOID);
|
||||
BOOL FASTCALL IntBlockInput(PTHREADINFO W32Thread, BOOL BlockIt);
|
||||
DWORD NTAPI CreateSystemThreads(UINT Type);
|
||||
NTSTATUS FASTCALL UserAttachThreadInput(PTHREADINFO,PTHREADINFO,BOOL);
|
||||
BOOL FASTCALL IsRemoveAttachThread(PTHREADINFO);
|
||||
VOID FASTCALL DoTheScreenSaver(VOID);
|
||||
|
|
|
@ -392,7 +392,7 @@ NtUserCallOneParam(
|
|||
break;
|
||||
|
||||
case ONEPARAM_ROUTINE_CREATESYSTEMTHREADS:
|
||||
Result = CreateSystemThreads(Param);
|
||||
Result = UserSystemThreadProc(Param);
|
||||
break;
|
||||
|
||||
case ONEPARAM_ROUTINE_LOCKFOREGNDWINDOW:
|
||||
|
|
|
@ -497,7 +497,20 @@ IntCreateWindowStation(
|
|||
|
||||
InputWindowStation = WindowStation;
|
||||
WindowStation->Flags &= ~WSS_NOIO;
|
||||
|
||||
InitCursorImpl();
|
||||
|
||||
UserCreateSystemThread(ST_DESKTOP_THREAD);
|
||||
UserCreateSystemThread(ST_RIT);
|
||||
|
||||
/* Desktop functions require the desktop thread running so wait for it to initialize */
|
||||
UserLeaveCo();
|
||||
KeWaitForSingleObject(gpDesktopThreadStartedEvent,
|
||||
UserRequest,
|
||||
UserMode,
|
||||
FALSE,
|
||||
NULL);
|
||||
UserEnterCo();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -742,6 +755,8 @@ NtUserCreateWindowStation(
|
|||
return NULL;
|
||||
}
|
||||
|
||||
UserEnterExclusive();
|
||||
|
||||
/* Create the window station */
|
||||
Status = IntCreateWindowStation(&hWinSta,
|
||||
ObjectAttributes,
|
||||
|
@ -753,6 +768,8 @@ NtUserCreateWindowStation(
|
|||
Unknown4,
|
||||
Unknown5,
|
||||
Unknown6);
|
||||
UserLeave();
|
||||
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
TRACE("NtUserCreateWindowStation created window station '%wZ' with handle 0x%p\n",
|
||||
|
|
|
@ -121,8 +121,13 @@ CreateSystemThreads(PVOID pParam)
|
|||
|
||||
CSR_API(SrvCreateSystemThreads)
|
||||
{
|
||||
DPRINT1("%s not yet implemented\n", __FUNCTION__);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
NTSTATUS Status = CsrExecServerThread(CreateSystemThreads, 0);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Cannot start system thread!\n");
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
CSR_API(SrvActivateDebugger)
|
||||
|
@ -282,38 +287,6 @@ CSR_SERVER_DLL_INIT(UserServerDllInitialization)
|
|||
return Status;
|
||||
}
|
||||
|
||||
/*** From win32csr... See r54125 ***/
|
||||
{
|
||||
HANDLE ServerThread;
|
||||
CLIENT_ID ClientId;
|
||||
UINT i;
|
||||
|
||||
/* Start the Raw Input Thread and the Desktop Thread */
|
||||
for (i = 0; i < 2; ++i)
|
||||
{
|
||||
Status = RtlCreateUserThread(NtCurrentProcess(),
|
||||
NULL,
|
||||
TRUE,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
CreateSystemThreads,
|
||||
UlongToPtr(i),
|
||||
&ServerThread,
|
||||
&ClientId);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
NtResumeThread(ServerThread, NULL);
|
||||
NtClose(ServerThread);
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT1("Cannot start Raw Input Thread!\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
/*** END - From win32csr... ***/
|
||||
|
||||
/* All done */
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue