mirror of
https://github.com/reactos/reactos.git
synced 2025-01-03 21:09:19 +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);
|
||||
}
|
||||
|
||||
DWORD
|
||||
WINAPI
|
||||
CreateSystemThreads(PVOID pParam)
|
||||
{
|
||||
NtUserCallOneParam((DWORD_PTR)pParam, ONEPARAM_ROUTINE_CREATESYSTEMTHREADS);
|
||||
DPRINT1("This thread should not terminate!\n");
|
||||
DbgBreakPoint();
|
||||
return 0;
|
||||
}
|
||||
|
||||
BOOL WINAPI
|
||||
Win32CsrInitialization(PCSRSS_API_DEFINITION *ApiDefinitions,
|
||||
PCSRPLUGIN_SERVER_PROCS ServerProcs,
|
||||
|
@ -200,6 +210,33 @@ Win32CsrInitialization(PCSRSS_API_DEFINITION *ApiDefinitions,
|
|||
|
||||
RtlInitializeCriticalSection(&Win32CsrDefineDosDeviceCritSec);
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,10 +24,6 @@ HANDLE ghKeyboardDevice;
|
|||
|
||||
static DWORD LastInputTick = 0;
|
||||
static HANDLE MouseDeviceHandle;
|
||||
static HANDLE MouseThreadHandle;
|
||||
static CLIENT_ID MouseThreadId;
|
||||
static HANDLE KeyboardThreadHandle;
|
||||
static CLIENT_ID KeyboardThreadId;
|
||||
static HANDLE RawInputThreadHandle;
|
||||
static CLIENT_ID RawInputThreadId;
|
||||
static KEVENT InputThreadsStart;
|
||||
|
@ -212,7 +208,7 @@ MouseThreadMain(PVOID StartContext)
|
|||
DueTime.QuadPart = (LONGLONG)(-10000000);
|
||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||
Status = KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, &DueTime);
|
||||
Status = NtOpenFile(&MouseDeviceHandle,
|
||||
Status = ZwOpenFile(&MouseDeviceHandle,
|
||||
FILE_ALL_ACCESS,
|
||||
&MouseObjectAttributes,
|
||||
&Iosb,
|
||||
|
@ -221,12 +217,12 @@ MouseThreadMain(PVOID StartContext)
|
|||
} while (!NT_SUCCESS(Status));
|
||||
|
||||
/* Need to setup basic win32k for this thread to process WH_MOUSE_LL messages. */
|
||||
Status = Win32kInitWin32Thread(PsGetCurrentThread());
|
||||
/*Status = Win32kInitWin32Thread(PsGetCurrentThread());
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ERR("Win32K: Failed making mouse thread a win32 thread.\n");
|
||||
return; //(Status);
|
||||
}
|
||||
}*/
|
||||
|
||||
ptiMouse = PsGetCurrentThreadWin32Thread();
|
||||
ptiMouse->TIF_flags |= TIF_SYSTEMTHREAD;
|
||||
|
@ -249,7 +245,7 @@ MouseThreadMain(PVOID StartContext)
|
|||
TRACE("Mouse Input Thread Starting...\n");
|
||||
|
||||
/*FIXME: Does mouse attributes need to be used for anything */
|
||||
Status = NtDeviceIoControlFile(MouseDeviceHandle,
|
||||
Status = ZwDeviceIoControlFile(MouseDeviceHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
|
@ -268,7 +264,7 @@ MouseThreadMain(PVOID StartContext)
|
|||
while(InputThreadsRunning)
|
||||
{
|
||||
MOUSE_INPUT_DATA MouseInput;
|
||||
Status = NtReadFile(MouseDeviceHandle,
|
||||
Status = ZwReadFile(MouseDeviceHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
|
@ -304,7 +300,7 @@ MouseThreadMain(PVOID StartContext)
|
|||
}
|
||||
}
|
||||
|
||||
static VOID APIENTRY
|
||||
VOID NTAPI
|
||||
KeyboardThreadMain(PVOID StartContext)
|
||||
{
|
||||
UNICODE_STRING KeyboardDeviceName = RTL_CONSTANT_STRING(L"\\Device\\KeyboardClass0");
|
||||
|
@ -321,11 +317,11 @@ KeyboardThreadMain(PVOID StartContext)
|
|||
{
|
||||
LARGE_INTEGER DueTime;
|
||||
KEVENT Event;
|
||||
DueTime.QuadPart = (LONGLONG)(-10000000);
|
||||
DueTime.QuadPart = (LONGLONG)(-100000000);
|
||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||
Status = KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, &DueTime);
|
||||
Status = NtOpenFile(&ghKeyboardDevice,
|
||||
FILE_ALL_ACCESS,
|
||||
Status = ZwOpenFile(&ghKeyboardDevice,
|
||||
FILE_READ_ACCESS,//FILE_ALL_ACCESS,
|
||||
&KeyboardObjectAttributes,
|
||||
&Iosb,
|
||||
0,
|
||||
|
@ -343,12 +339,12 @@ KeyboardThreadMain(PVOID StartContext)
|
|||
the message from the system message queue would be responsible
|
||||
for WH_KEYBOARD_LL processing and we wouldn't need this thread
|
||||
to be a win32 thread. */
|
||||
Status = Win32kInitWin32Thread(PsGetCurrentThread());
|
||||
/*Status = Win32kInitWin32Thread(PsGetCurrentThread());
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ERR("Win32K: Failed making keyboard thread a win32 thread.\n");
|
||||
return; //(Status);
|
||||
}
|
||||
}*/
|
||||
|
||||
ptiKeyboard = PsGetCurrentThreadWin32Thread();
|
||||
ptiKeyboard->TIF_flags |= TIF_SYSTEMTHREAD;
|
||||
|
@ -379,7 +375,7 @@ KeyboardThreadMain(PVOID StartContext)
|
|||
|
||||
TRACE("KeyInput @ %08x\n", &KeyInput);
|
||||
|
||||
Status = NtReadFile (ghKeyboardDevice,
|
||||
Status = ZwReadFile (ghKeyboardDevice,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
|
@ -479,7 +475,7 @@ RawInputThreadMain(PVOID StartContext)
|
|||
//
|
||||
for(;;)
|
||||
{
|
||||
TRACE( "Raw Input Thread Waiting for start event\n" );
|
||||
TRACE("Raw Input Thread Waiting for start event\n");
|
||||
|
||||
Status = KeWaitForMultipleObjects( 2,
|
||||
Objects,
|
||||
|
@ -489,13 +485,30 @@ RawInputThreadMain(PVOID StartContext)
|
|||
TRUE,
|
||||
NULL,
|
||||
NULL);
|
||||
TRACE( "Raw Input Thread Starting...\n" );
|
||||
TRACE("Raw Input Thread Starting...\n");
|
||||
|
||||
ProcessTimers();
|
||||
}
|
||||
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
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
|
@ -532,30 +545,6 @@ InitInputImpl(VOID)
|
|||
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;
|
||||
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
|
||||
*/
|
||||
if(!ThreadHasInputAccess(pti) ||
|
||||
!IntIsActiveDesktop(pti->rpdesk))
|
||||
!IntIsActiveDesktop(pti->rpdesk))
|
||||
{
|
||||
EngSetLastError(ERROR_ACCESS_DENIED);
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
|
@ -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 */
|
||||
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 */
|
||||
Msg.hwnd = pFocusQueue->FocusWindow;
|
||||
|
|
|
@ -378,6 +378,8 @@ NtUserCallOneParam(
|
|||
case ONEPARAM_ROUTINE_MESSAGEBEEP:
|
||||
RETURN ( UserPostMessage(hwndSAS, WM_LOGONNOTIFY, LN_MESSAGE_BEEP, Param) );
|
||||
/* TODO: Implement sound sentry */
|
||||
case ONEPARAM_ROUTINE_CREATESYSTEMTHREADS:
|
||||
RETURN(CreateSystemThreads(Param));
|
||||
}
|
||||
ERR("Calling invalid routine number 0x%x in NtUserCallOneParam(), Param=0x%x\n",
|
||||
Routine, Param);
|
||||
|
|
Loading…
Reference in a new issue