mirror of
https://github.com/reactos/reactos.git
synced 2025-01-05 22:12:46 +00:00
[WIN32K/CSRSS]
- Spawn keyboard and mouse input threads in csrss user-mode process so they are valid Win32 threads and have TEB svn path=/trunk/; revision=54125
This commit is contained in:
parent
b4721b55d7
commit
81a9b72e90
4 changed files with 160 additions and 44 deletions
|
@ -178,6 +178,16 @@ PrivateCsrssManualGuiCheck(LONG Check)
|
||||||
NtUserCallOneParam(Check, ONEPARAM_ROUTINE_CSRSS_GUICHECK);
|
NtUserCallOneParam(Check, ONEPARAM_ROUTINE_CSRSS_GUICHECK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
WINAPI
|
||||||
|
CreateSystemThreads(PVOID pParam)
|
||||||
|
{
|
||||||
|
NtUserCallOneParam((DWORD_PTR)pParam, ONEPARAM_ROUTINE_CREATESYSTEMTHREADS);
|
||||||
|
DPRINT1("This thread should not terminate!\n");
|
||||||
|
DbgBreakPoint();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
BOOL WINAPI
|
BOOL WINAPI
|
||||||
Win32CsrInitialization(PCSRSS_API_DEFINITION *ApiDefinitions,
|
Win32CsrInitialization(PCSRSS_API_DEFINITION *ApiDefinitions,
|
||||||
PCSRPLUGIN_SERVER_PROCS ServerProcs,
|
PCSRPLUGIN_SERVER_PROCS ServerProcs,
|
||||||
|
@ -200,6 +210,33 @@ Win32CsrInitialization(PCSRSS_API_DEFINITION *ApiDefinitions,
|
||||||
|
|
||||||
RtlInitializeCriticalSection(&Win32CsrDefineDosDeviceCritSec);
|
RtlInitializeCriticalSection(&Win32CsrDefineDosDeviceCritSec);
|
||||||
InitializeListHead(&DosDeviceHistory);
|
InitializeListHead(&DosDeviceHistory);
|
||||||
|
|
||||||
|
{
|
||||||
|
HANDLE ServerThread;
|
||||||
|
CLIENT_ID ClientId;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
Status = RtlCreateUserThread(NtCurrentProcess(), NULL, TRUE, 0, 0, 0, (PTHREAD_START_ROUTINE)CreateSystemThreads, (PVOID)0, &ServerThread, &ClientId);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
NtResumeThread(ServerThread, NULL);
|
||||||
|
NtClose(ServerThread);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
DPRINT1("Cannot start keyboard thread!\n");
|
||||||
|
|
||||||
|
Status = RtlCreateUserThread(NtCurrentProcess(), NULL, TRUE, 0, 0, 0, (PTHREAD_START_ROUTINE)CreateSystemThreads, (PVOID)1, &ServerThread, &ClientId);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
NtResumeThread(ServerThread, NULL);
|
||||||
|
NtClose(ServerThread);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
DPRINT1("Cannot start mouse thread!\n");
|
||||||
|
|
||||||
|
DbgBreakPoint();
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,10 +24,6 @@ HANDLE ghKeyboardDevice;
|
||||||
|
|
||||||
static DWORD LastInputTick = 0;
|
static DWORD LastInputTick = 0;
|
||||||
static HANDLE MouseDeviceHandle;
|
static HANDLE MouseDeviceHandle;
|
||||||
static HANDLE MouseThreadHandle;
|
|
||||||
static CLIENT_ID MouseThreadId;
|
|
||||||
static HANDLE KeyboardThreadHandle;
|
|
||||||
static CLIENT_ID KeyboardThreadId;
|
|
||||||
static HANDLE RawInputThreadHandle;
|
static HANDLE RawInputThreadHandle;
|
||||||
static CLIENT_ID RawInputThreadId;
|
static CLIENT_ID RawInputThreadId;
|
||||||
static KEVENT InputThreadsStart;
|
static KEVENT InputThreadsStart;
|
||||||
|
@ -212,7 +208,7 @@ MouseThreadMain(PVOID StartContext)
|
||||||
DueTime.QuadPart = (LONGLONG)(-10000000);
|
DueTime.QuadPart = (LONGLONG)(-10000000);
|
||||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||||
Status = KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, &DueTime);
|
Status = KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, &DueTime);
|
||||||
Status = NtOpenFile(&MouseDeviceHandle,
|
Status = ZwOpenFile(&MouseDeviceHandle,
|
||||||
FILE_ALL_ACCESS,
|
FILE_ALL_ACCESS,
|
||||||
&MouseObjectAttributes,
|
&MouseObjectAttributes,
|
||||||
&Iosb,
|
&Iosb,
|
||||||
|
@ -221,12 +217,12 @@ MouseThreadMain(PVOID StartContext)
|
||||||
} while (!NT_SUCCESS(Status));
|
} while (!NT_SUCCESS(Status));
|
||||||
|
|
||||||
/* Need to setup basic win32k for this thread to process WH_MOUSE_LL messages. */
|
/* Need to setup basic win32k for this thread to process WH_MOUSE_LL messages. */
|
||||||
Status = Win32kInitWin32Thread(PsGetCurrentThread());
|
/*Status = Win32kInitWin32Thread(PsGetCurrentThread());
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
ERR("Win32K: Failed making mouse thread a win32 thread.\n");
|
ERR("Win32K: Failed making mouse thread a win32 thread.\n");
|
||||||
return; //(Status);
|
return; //(Status);
|
||||||
}
|
}*/
|
||||||
|
|
||||||
ptiMouse = PsGetCurrentThreadWin32Thread();
|
ptiMouse = PsGetCurrentThreadWin32Thread();
|
||||||
ptiMouse->TIF_flags |= TIF_SYSTEMTHREAD;
|
ptiMouse->TIF_flags |= TIF_SYSTEMTHREAD;
|
||||||
|
@ -249,7 +245,7 @@ MouseThreadMain(PVOID StartContext)
|
||||||
TRACE("Mouse Input Thread Starting...\n");
|
TRACE("Mouse Input Thread Starting...\n");
|
||||||
|
|
||||||
/*FIXME: Does mouse attributes need to be used for anything */
|
/*FIXME: Does mouse attributes need to be used for anything */
|
||||||
Status = NtDeviceIoControlFile(MouseDeviceHandle,
|
Status = ZwDeviceIoControlFile(MouseDeviceHandle,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
|
@ -268,7 +264,7 @@ MouseThreadMain(PVOID StartContext)
|
||||||
while(InputThreadsRunning)
|
while(InputThreadsRunning)
|
||||||
{
|
{
|
||||||
MOUSE_INPUT_DATA MouseInput;
|
MOUSE_INPUT_DATA MouseInput;
|
||||||
Status = NtReadFile(MouseDeviceHandle,
|
Status = ZwReadFile(MouseDeviceHandle,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
|
@ -304,7 +300,7 @@ MouseThreadMain(PVOID StartContext)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID APIENTRY
|
VOID NTAPI
|
||||||
KeyboardThreadMain(PVOID StartContext)
|
KeyboardThreadMain(PVOID StartContext)
|
||||||
{
|
{
|
||||||
UNICODE_STRING KeyboardDeviceName = RTL_CONSTANT_STRING(L"\\Device\\KeyboardClass0");
|
UNICODE_STRING KeyboardDeviceName = RTL_CONSTANT_STRING(L"\\Device\\KeyboardClass0");
|
||||||
|
@ -321,11 +317,11 @@ KeyboardThreadMain(PVOID StartContext)
|
||||||
{
|
{
|
||||||
LARGE_INTEGER DueTime;
|
LARGE_INTEGER DueTime;
|
||||||
KEVENT Event;
|
KEVENT Event;
|
||||||
DueTime.QuadPart = (LONGLONG)(-10000000);
|
DueTime.QuadPart = (LONGLONG)(-100000000);
|
||||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||||
Status = KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, &DueTime);
|
Status = KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, &DueTime);
|
||||||
Status = NtOpenFile(&ghKeyboardDevice,
|
Status = ZwOpenFile(&ghKeyboardDevice,
|
||||||
FILE_ALL_ACCESS,
|
FILE_READ_ACCESS,//FILE_ALL_ACCESS,
|
||||||
&KeyboardObjectAttributes,
|
&KeyboardObjectAttributes,
|
||||||
&Iosb,
|
&Iosb,
|
||||||
0,
|
0,
|
||||||
|
@ -343,12 +339,12 @@ KeyboardThreadMain(PVOID StartContext)
|
||||||
the message from the system message queue would be responsible
|
the message from the system message queue would be responsible
|
||||||
for WH_KEYBOARD_LL processing and we wouldn't need this thread
|
for WH_KEYBOARD_LL processing and we wouldn't need this thread
|
||||||
to be a win32 thread. */
|
to be a win32 thread. */
|
||||||
Status = Win32kInitWin32Thread(PsGetCurrentThread());
|
/*Status = Win32kInitWin32Thread(PsGetCurrentThread());
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
ERR("Win32K: Failed making keyboard thread a win32 thread.\n");
|
ERR("Win32K: Failed making keyboard thread a win32 thread.\n");
|
||||||
return; //(Status);
|
return; //(Status);
|
||||||
}
|
}*/
|
||||||
|
|
||||||
ptiKeyboard = PsGetCurrentThreadWin32Thread();
|
ptiKeyboard = PsGetCurrentThreadWin32Thread();
|
||||||
ptiKeyboard->TIF_flags |= TIF_SYSTEMTHREAD;
|
ptiKeyboard->TIF_flags |= TIF_SYSTEMTHREAD;
|
||||||
|
@ -379,7 +375,7 @@ KeyboardThreadMain(PVOID StartContext)
|
||||||
|
|
||||||
TRACE("KeyInput @ %08x\n", &KeyInput);
|
TRACE("KeyInput @ %08x\n", &KeyInput);
|
||||||
|
|
||||||
Status = NtReadFile (ghKeyboardDevice,
|
Status = ZwReadFile (ghKeyboardDevice,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
|
@ -479,7 +475,7 @@ RawInputThreadMain(PVOID StartContext)
|
||||||
//
|
//
|
||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
TRACE( "Raw Input Thread Waiting for start event\n" );
|
TRACE("Raw Input Thread Waiting for start event\n");
|
||||||
|
|
||||||
Status = KeWaitForMultipleObjects( 2,
|
Status = KeWaitForMultipleObjects( 2,
|
||||||
Objects,
|
Objects,
|
||||||
|
@ -489,13 +485,30 @@ RawInputThreadMain(PVOID StartContext)
|
||||||
TRUE,
|
TRUE,
|
||||||
NULL,
|
NULL,
|
||||||
NULL);
|
NULL);
|
||||||
TRACE( "Raw Input Thread Starting...\n" );
|
TRACE("Raw Input Thread Starting...\n");
|
||||||
|
|
||||||
ProcessTimers();
|
ProcessTimers();
|
||||||
}
|
}
|
||||||
ERR("Raw Input Thread Exit!\n");
|
ERR("Raw Input Thread Exit!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DWORD NTAPI
|
||||||
|
CreateSystemThreads(UINT Type)
|
||||||
|
{
|
||||||
|
UserLeave();
|
||||||
|
|
||||||
|
switch (Type)
|
||||||
|
{
|
||||||
|
case 0: KeyboardThreadMain(NULL); break;
|
||||||
|
case 1: MouseThreadMain(NULL); break;
|
||||||
|
default: ERR("Wrong type: %x\n", Type);
|
||||||
|
}
|
||||||
|
|
||||||
|
UserEnterShared();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
INIT_FUNCTION
|
INIT_FUNCTION
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
|
@ -532,30 +545,6 @@ InitInputImpl(VOID)
|
||||||
ERR("Win32K: Failed to create raw thread.\n");
|
ERR("Win32K: Failed to create raw thread.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = PsCreateSystemThread(&KeyboardThreadHandle,
|
|
||||||
THREAD_ALL_ACCESS,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
&KeyboardThreadId,
|
|
||||||
KeyboardThreadMain,
|
|
||||||
NULL);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
ERR("Win32K: Failed to create keyboard thread.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = PsCreateSystemThread(&MouseThreadHandle,
|
|
||||||
THREAD_ALL_ACCESS,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
&MouseThreadId,
|
|
||||||
MouseThreadMain,
|
|
||||||
NULL);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
ERR("Win32K: Failed to create mouse thread.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
InputThreadsRunning = TRUE;
|
InputThreadsRunning = TRUE;
|
||||||
KeSetEvent(&InputThreadsStart, IO_NO_INCREMENT, FALSE);
|
KeSetEvent(&InputThreadsStart, IO_NO_INCREMENT, FALSE);
|
||||||
|
|
||||||
|
@ -588,7 +577,7 @@ IntBlockInput(PTHREADINFO pti, BOOL BlockIt)
|
||||||
* e.g. services running in the service window station cannot block input
|
* e.g. services running in the service window station cannot block input
|
||||||
*/
|
*/
|
||||||
if(!ThreadHasInputAccess(pti) ||
|
if(!ThreadHasInputAccess(pti) ||
|
||||||
!IntIsActiveDesktop(pti->rpdesk))
|
!IntIsActiveDesktop(pti->rpdesk))
|
||||||
{
|
{
|
||||||
EngSetLastError(ERROR_ACCESS_DENIED);
|
EngSetLastError(ERROR_ACCESS_DENIED);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
|
@ -671,6 +671,83 @@ co_CallLowLevelKeyboardHook(WORD wVk, WORD wScanCode, DWORD dwFlags, BOOL bInjec
|
||||||
return co_HOOK_CallHooks(WH_KEYBOARD_LL, HC_ACTION, uMsg, (LPARAM)&KbdHookData);
|
return co_HOOK_CallHooks(WH_KEYBOARD_LL, HC_ACTION, uMsg, (LPARAM)&KbdHookData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SnapWindow
|
||||||
|
*
|
||||||
|
* Saves snapshot of specified window or whole screen in the clipboard
|
||||||
|
*/
|
||||||
|
static VOID
|
||||||
|
SnapWindow(HWND hWnd)
|
||||||
|
{
|
||||||
|
HBITMAP hbm = NULL, hbmOld;
|
||||||
|
HDC hdc = NULL, hdcMem;
|
||||||
|
SETCLIPBDATA scd;
|
||||||
|
INT cx, cy;
|
||||||
|
PWND pWnd = NULL;
|
||||||
|
|
||||||
|
TRACE("SnapWindow(%p)\n", hWnd);
|
||||||
|
|
||||||
|
/* If no windows is given, make snapshot of desktop window */
|
||||||
|
if (!hWnd)
|
||||||
|
hWnd = IntGetDesktopWindow();
|
||||||
|
|
||||||
|
pWnd = UserGetWindowObject(hWnd);
|
||||||
|
if (!pWnd)
|
||||||
|
{
|
||||||
|
ERR("Invalid window\n");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
hdc = UserGetDCEx(pWnd, NULL, DCX_USESTYLE | DCX_WINDOW);
|
||||||
|
if (!hdc)
|
||||||
|
{
|
||||||
|
ERR("UserGetDCEx failed!\n");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
cx = pWnd->rcWindow.right - pWnd->rcWindow.left;
|
||||||
|
cy = pWnd->rcWindow.bottom - pWnd->rcWindow.top;
|
||||||
|
|
||||||
|
hbm = NtGdiCreateCompatibleBitmap(hdc, cx, cy);
|
||||||
|
if (!hbm)
|
||||||
|
{
|
||||||
|
ERR("NtGdiCreateCompatibleBitmap failed!\n");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
hdcMem = NtGdiCreateCompatibleDC(hdc);
|
||||||
|
if (!hdcMem)
|
||||||
|
{
|
||||||
|
ERR("NtGdiCreateCompatibleDC failed!\n");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
hbmOld = NtGdiSelectBitmap(hdcMem, hbm);
|
||||||
|
NtGdiBitBlt(hdcMem, 0, 0, cx, cy, hdc, 0, 0, SRCCOPY, 0, 0);
|
||||||
|
NtGdiSelectBitmap(hdcMem, hbmOld);
|
||||||
|
IntGdiDeleteDC(hdcMem, FALSE);
|
||||||
|
|
||||||
|
/* Save snapshot in clipboard */
|
||||||
|
if (UserOpenClipboard(NULL))
|
||||||
|
{
|
||||||
|
UserEmptyClipboard();
|
||||||
|
scd.fIncSerialNumber = TRUE;
|
||||||
|
scd.fGlobalHandle = FALSE;
|
||||||
|
if (UserSetClipboardData(CF_BITMAP, hbm, &scd))
|
||||||
|
{
|
||||||
|
/* Bitmap is managed by system now */
|
||||||
|
hbm = NULL;
|
||||||
|
}
|
||||||
|
UserCloseClipboard();
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (hbm)
|
||||||
|
GreDeleteObject(hbm);
|
||||||
|
if (hdc)
|
||||||
|
UserReleaseDC(hWnd, hdc, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* UserSendKeyboardInput
|
* UserSendKeyboardInput
|
||||||
*
|
*
|
||||||
|
@ -765,7 +842,18 @@ ProcessKeyEvent(WORD wVk, WORD wScanCode, DWORD dwFlags, BOOL bInjected, DWORD d
|
||||||
|
|
||||||
/* If we have a focus queue, post a keyboard message */
|
/* If we have a focus queue, post a keyboard message */
|
||||||
pFocusQueue = IntGetFocusMessageQueue();
|
pFocusQueue = IntGetFocusMessageQueue();
|
||||||
if (pFocusQueue && bPostMsg)
|
if (bIsDown && wVk == VK_SNAPSHOT)
|
||||||
|
{
|
||||||
|
if (pFocusQueue &&
|
||||||
|
IS_KEY_DOWN(gafAsyncKeyState, VK_MENU) &&
|
||||||
|
!IS_KEY_DOWN(gafAsyncKeyState, VK_CONTROL))
|
||||||
|
{
|
||||||
|
SnapWindow(pFocusQueue->FocusWindow);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
SnapWindow(NULL);
|
||||||
|
}
|
||||||
|
else if (pFocusQueue && bPostMsg)
|
||||||
{
|
{
|
||||||
/* Init message */
|
/* Init message */
|
||||||
Msg.hwnd = pFocusQueue->FocusWindow;
|
Msg.hwnd = pFocusQueue->FocusWindow;
|
||||||
|
|
|
@ -378,6 +378,8 @@ NtUserCallOneParam(
|
||||||
case ONEPARAM_ROUTINE_MESSAGEBEEP:
|
case ONEPARAM_ROUTINE_MESSAGEBEEP:
|
||||||
RETURN ( UserPostMessage(hwndSAS, WM_LOGONNOTIFY, LN_MESSAGE_BEEP, Param) );
|
RETURN ( UserPostMessage(hwndSAS, WM_LOGONNOTIFY, LN_MESSAGE_BEEP, Param) );
|
||||||
/* TODO: Implement sound sentry */
|
/* TODO: Implement sound sentry */
|
||||||
|
case ONEPARAM_ROUTINE_CREATESYSTEMTHREADS:
|
||||||
|
RETURN(CreateSystemThreads(Param));
|
||||||
}
|
}
|
||||||
ERR("Calling invalid routine number 0x%x in NtUserCallOneParam(), Param=0x%x\n",
|
ERR("Calling invalid routine number 0x%x in NtUserCallOneParam(), Param=0x%x\n",
|
||||||
Routine, Param);
|
Routine, Param);
|
||||||
|
|
Loading…
Reference in a new issue