Author: rharabien Date: Thu Oct 13 22:22:49 2011 New Revision: 54125
URL: http://svn.reactos.org/svn/reactos?rev=54125&view=rev Log: [WIN32K/CSRSS] - Spawn keyboard and mouse input threads in csrss user-mode process so they are valid Win32 threads and have TEB
Modified: trunk/reactos/subsystems/win32/csrss/win32csr/dllmain.c trunk/reactos/subsystems/win32/win32k/ntuser/input.c trunk/reactos/subsystems/win32/win32k/ntuser/keyboard.c trunk/reactos/subsystems/win32/win32k/ntuser/simplecall.c
Modified: trunk/reactos/subsystems/win32/csrss/win32csr/dllmain.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/win3... ============================================================================== --- trunk/reactos/subsystems/win32/csrss/win32csr/dllmain.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/csrss/win32csr/dllmain.c [iso-8859-1] Thu Oct 13 22:22:49 2011 @@ -178,6 +178,16 @@ 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 @@
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; }
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/input.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntu... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/ntuser/input.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/ntuser/input.c [iso-8859-1] Thu Oct 13 22:22:49 2011 @@ -24,10 +24,6 @@
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 @@ 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 @@ } 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 @@ 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 @@ while(InputThreadsRunning) { MOUSE_INPUT_DATA MouseInput; - Status = NtReadFile(MouseDeviceHandle, + Status = ZwReadFile(MouseDeviceHandle, NULL, NULL, NULL, @@ -304,7 +300,7 @@ } }
-static VOID APIENTRY +VOID NTAPI KeyboardThreadMain(PVOID StartContext) { UNICODE_STRING KeyboardDeviceName = RTL_CONSTANT_STRING(L"\Device\KeyboardClass0"); @@ -321,11 +317,11 @@ { 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 @@ 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 @@
TRACE("KeyInput @ %08x\n", &KeyInput);
- Status = NtReadFile (ghKeyboardDevice, + Status = ZwReadFile (ghKeyboardDevice, NULL, NULL, NULL, @@ -479,7 +475,7 @@ // for(;;) { - TRACE( "Raw Input Thread Waiting for start event\n" ); + TRACE("Raw Input Thread Waiting for start event\n");
Status = KeWaitForMultipleObjects( 2, Objects, @@ -489,11 +485,28 @@ 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 @@ -532,30 +545,6 @@ 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 @@ * 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;
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/keyboard.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntu... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/ntuser/keyboard.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/ntuser/keyboard.c [iso-8859-1] Thu Oct 13 22:22:49 2011 @@ -672,6 +672,83 @@ }
/* + * 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 * * Process keyboard input from input devices and SendInput API @@ -765,7 +842,18 @@
/* 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;
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/simplecall.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntu... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/ntuser/simplecall.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/ntuser/simplecall.c [iso-8859-1] Thu Oct 13 22:22:49 2011 @@ -378,6 +378,8 @@ 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);