ReactOS 0.4.15-dev-7907-g95bf896
input.c File Reference
#include <win32k.h>
Include dependency graph for input.c:

Go to the source code of this file.

Functions

 DBG_DEFAULT_CHANNEL (UserInput)
 
static DWORD FASTCALL IntLastInputTick (BOOL bUpdate)
 
VOID FASTCALL DoTheScreenSaver (VOID)
 
static NTSTATUS NTAPI OpenInputDevice (PHANDLE pHandle, PFILE_OBJECT *ppObject, CONST WCHAR *pszDeviceName)
 
VOID NTAPI RawInputThreadMain (VOID)
 
NTSTATUS NTAPI InitInputImpl (VOID)
 
BOOL FASTCALL IntBlockInput (PTHREADINFO pti, BOOL BlockIt)
 
BOOL APIENTRY NtUserBlockInput (BOOL BlockIt)
 
BOOL FASTCALL IsRemoveAttachThread (PTHREADINFO pti)
 
NTSTATUS FASTCALL UserAttachThreadInput (PTHREADINFO ptiFrom, PTHREADINFO ptiTo, BOOL fAttach)
 
BOOL APIENTRY NtUserAttachThreadInput (IN DWORD idAttach, IN DWORD idAttachTo, IN BOOL fAttach)
 
UINT APIENTRY NtUserSendInput (UINT nInputs, LPINPUT pInput, INT cbSize)
 

Variables

PTHREADINFO ptiRawInput
 
PKTIMER MasterTimer = NULL
 
PATTACHINFO gpai = NULL
 
INT paiCount = 0
 
HANDLE ghKeyboardDevice = NULL
 
static DWORD LastInputTick = 0
 
static HANDLE ghMouseDevice
 

Function Documentation

◆ DBG_DEFAULT_CHANNEL()

DBG_DEFAULT_CHANNEL ( UserInput  )

◆ DoTheScreenSaver()

VOID FASTCALL DoTheScreenSaver ( VOID  )

Definition at line 48 of file input.c.

49{
50 DWORD Test, TO;
51
52 if (gspv.iScrSaverTimeout > 0) // Zero means Off.
53 {
56 TO = 1000 * gspv.iScrSaverTimeout;
57 if (Test > TO)
58 {
59 TRACE("Screensaver Message Start! Tick %lu Timeout %d \n", Test, gspv.iScrSaverTimeout);
60
61 if (ppiScrnSaver) // We are or we are not the screensaver, prevent reentry...
62 {
63 if (!(ppiScrnSaver->W32PF_flags & W32PF_IDLESCREENSAVER))
64 {
65 ppiScrnSaver->W32PF_flags |= W32PF_IDLESCREENSAVER;
66 ERR("Screensaver is Idle\n");
67 }
68 }
69 else
70 {
72 if (ForegroundQueue && ForegroundQueue->spwndActive)
74 else
76 }
77 }
78 }
79}
#define ERR(fmt,...)
Definition: debug.h:110
#define EngGetTickCount32()
Definition: eng.h:43
unsigned long DWORD
Definition: ntddk_ex.h:95
HWND hwndSAS
Definition: winsta.c:24
#define TRACE(s)
Definition: solgame.cpp:4
INT iScrSaverTimeout
Definition: sysparams.h:110
#define WM_LOGONNOTIFY
Definition: undocuser.h:37
#define LN_START_SCREENSAVE
Definition: undocuser.h:121
#define W32PF_IDLESCREENSAVER
Definition: win32.h:27
PUSER_MESSAGE_QUEUE FASTCALL IntGetFocusMessageQueue(VOID)
Definition: desktop.c:1307
static DWORD LastInputTick
Definition: input.c:21
PPROCESSINFO ppiScrnSaver
Definition: main.c:29
BOOL FASTCALL UserPostMessage(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: message.c:1345
SPIVALUES gspv
Definition: sysparams.c:17

Referenced by HungAppSysTimerProc().

◆ InitInputImpl()

NTSTATUS NTAPI InitInputImpl ( VOID  )

Definition at line 360 of file input.c.

361{
363 if (!MasterTimer)
364 {
365 ERR("Failed to allocate memory\n");
366 ASSERT(FALSE);
367 return STATUS_UNSUCCESSFUL;
368 }
370
371 return STATUS_SUCCESS;
372}
#define FALSE
Definition: types.h:117
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define NonPagedPool
Definition: env_spec_w32.h:307
#define ASSERT(a)
Definition: mode.c:44
#define STATUS_SUCCESS
Definition: shellext.h:65
VOID NTAPI KeInitializeTimer(OUT PKTIMER Timer)
Definition: timerobj.c:233
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
PKTIMER MasterTimer
Definition: input.c:16
#define USERTAG_SYSTEM
Definition: tags.h:282

Referenced by DriverEntry().

◆ IntBlockInput()

BOOL FASTCALL IntBlockInput ( PTHREADINFO  pti,
BOOL  BlockIt 
)

Definition at line 375 of file input.c.

376{
377 PTHREADINFO OldBlock;
378 ASSERT(pti);
379
380 if(!pti->rpdesk || ((pti->TIF_flags & TIF_INCLEANUP) && BlockIt))
381 {
382 /*
383 * Fail blocking if exiting the thread
384 */
385
386 return FALSE;
387 }
388
389 /*
390 * FIXME: Check access rights of the window station
391 * e.g. services running in the service window station cannot block input
392 */
393 if(!ThreadHasInputAccess(pti) ||
395 {
397 return FALSE;
398 }
399
400 ASSERT(pti->rpdesk);
401 OldBlock = pti->rpdesk->BlockInputThread;
402 if(OldBlock)
403 {
404 if(OldBlock != pti)
405 {
407 return FALSE;
408 }
409 pti->rpdesk->BlockInputThread = (BlockIt ? pti : NULL);
410 return OldBlock == NULL;
411 }
412
413 pti->rpdesk->BlockInputThread = (BlockIt ? pti : NULL);
414 return OldBlock == NULL;
415}
#define NULL
Definition: types.h:112
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
#define TIF_INCLEANUP
Definition: ntuser.h:263
FLONG TIF_flags
Definition: win32.h:95
struct _DESKTOP * rpdesk
Definition: win32.h:92
#define IntIsActiveDesktop(Desktop)
Definition: desktop.h:172
#define ThreadHasInputAccess(W32Thread)
Definition: input.h:68
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:22

Referenced by ExitThreadCallback(), and NtUserBlockInput().

◆ IntLastInputTick()

static DWORD FASTCALL IntLastInputTick ( BOOL  bUpdate)
static

Definition at line 32 of file input.c.

33{
34 if (bUpdate)
35 {
37 if (gpsi) gpsi->dwLastRITEventTickCount = LastInputTick;
38 }
39 return LastInputTick;
40}
PSERVERINFO gpsi
Definition: imm.c:18

Referenced by RawInputThreadMain().

◆ IsRemoveAttachThread()

BOOL FASTCALL IsRemoveAttachThread ( PTHREADINFO  pti)

Definition at line 437 of file input.c.

438{
440 PATTACHINFO pai;
441 BOOL Ret = TRUE;
442 PTHREADINFO ptiFrom = NULL, ptiTo = NULL;
443
444 do
445 {
446 if (!gpai) return TRUE;
447
448 pai = gpai; // Bottom of the list.
449
450 do
451 {
452 if (pai->pti2 == pti)
453 {
454 ptiFrom = pai->pti1;
455 ptiTo = pti;
456 break;
457 }
458 if (pai->pti1 == pti)
459 {
460 ptiFrom = pti;
461 ptiTo = pai->pti2;
462 break;
463 }
464 pai = pai->paiNext;
465
466 } while (pai);
467
468 if (!pai && !ptiFrom && !ptiTo) break;
469
470 Status = UserAttachThreadInput(ptiFrom, ptiTo, FALSE);
471 if (!NT_SUCCESS(Status)) Ret = FALSE;
472
473 } while (Ret);
474
475 return Ret;
476}
LONG NTSTATUS
Definition: precomp.h:26
#define TRUE
Definition: types.h:120
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
unsigned int BOOL
Definition: ntddk_ex.h:94
Status
Definition: gdiplustypes.h:25
PTHREADINFO pti2
Definition: input.h:45
struct _ATTACHINFO * paiNext
Definition: input.h:43
PTHREADINFO pti1
Definition: input.h:44
PATTACHINFO gpai
Definition: input.c:17
NTSTATUS FASTCALL UserAttachThreadInput(PTHREADINFO ptiFrom, PTHREADINFO ptiTo, BOOL fAttach)
Definition: input.c:480

Referenced by ExitThreadCallback().

◆ NtUserAttachThreadInput()

BOOL APIENTRY NtUserAttachThreadInput ( IN DWORD  idAttach,
IN DWORD  idAttachTo,
IN BOOL  fAttach 
)

Definition at line 665 of file input.c.

669{
671 PTHREADINFO pti, ptiTo;
672 BOOL Ret = FALSE;
673
675 TRACE("Enter NtUserAttachThreadInput %s\n",(fAttach ? "TRUE" : "FALSE" ));
676
677 pti = IntTID2PTI(UlongToHandle(idAttach));
678 ptiTo = IntTID2PTI(UlongToHandle(idAttachTo));
679
680 if ( !pti || !ptiTo )
681 {
682 TRACE("AttachThreadInput pti or ptiTo NULL.\n");
684 goto Exit;
685 }
686
687 Status = UserAttachThreadInput( pti, ptiTo, fAttach);
688 if (!NT_SUCCESS(Status))
689 {
690 TRACE("AttachThreadInput Error Status 0x%x. \n",Status);
692 }
693 else Ret = TRUE;
694
695Exit:
696 TRACE("Leave NtUserAttachThreadInput, ret=%d\n",Ret);
697 UserLeave();
698 return Ret;
699}
#define UlongToHandle(ul)
Definition: basetsd.h:97
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
NTSYSAPI ULONG WINAPI RtlNtStatusToDosError(NTSTATUS)
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:251
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:242
static void Exit(void)
Definition: sock.c:1330
PTHREADINFO FASTCALL IntTID2PTI(HANDLE id)
Definition: misc.c:42

◆ NtUserBlockInput()

BOOL APIENTRY NtUserBlockInput ( BOOL  BlockIt)

Definition at line 419 of file input.c.

421{
422 BOOL ret;
423
424 TRACE("Enter NtUserBlockInput\n");
426
428
429 UserLeave();
430 TRACE("Leave NtUserBlockInput, ret=%i\n", ret);
431
432 return ret;
433}
PVOID NTAPI PsGetCurrentThreadWin32Thread(VOID)
Definition: thread.c:805
int ret
BOOL FASTCALL IntBlockInput(PTHREADINFO pti, BOOL BlockIt)
Definition: input.c:375

Referenced by BlockInput().

◆ NtUserSendInput()

UINT APIENTRY NtUserSendInput ( UINT  nInputs,
LPINPUT  pInput,
INT  cbSize 
)

Definition at line 708 of file input.c.

712{
713 PTHREADINFO pti;
714 UINT uRet = 0;
715
716 TRACE("Enter NtUserSendInput\n");
718
720 ASSERT(pti);
721
722 if (!pti->rpdesk)
723 {
724 goto cleanup;
725 }
726
727 if (!nInputs || !pInput || cbSize != sizeof(INPUT))
728 {
730 goto cleanup;
731 }
732
733 /*
734 * FIXME: Check access rights of the window station
735 * e.g. services running in the service window station cannot block input
736 */
737 if (!ThreadHasInputAccess(pti) ||
739 {
741 goto cleanup;
742 }
743
744 while (nInputs--)
745 {
746 INPUT SafeInput;
748
749 Status = MmCopyFromCaller(&SafeInput, pInput++, sizeof(INPUT));
750 if (!NT_SUCCESS(Status))
751 {
753 goto cleanup;
754 }
755
756 switch (SafeInput.type)
757 {
758 case INPUT_MOUSE:
759 if (UserSendMouseInput(&SafeInput.mi, TRUE))
760 uRet++;
761 break;
762 case INPUT_KEYBOARD:
763 if (UserSendKeyboardInput(&SafeInput.ki, TRUE))
764 uRet++;
765 break;
766 case INPUT_HARDWARE:
767 FIXME("INPUT_HARDWARE not supported!\n");
768 break;
769 default:
770 ERR("SendInput(): Invalid input type: 0x%x\n", SafeInput.type);
771 break;
772 }
773 }
774
775cleanup:
776 TRACE("Leave NtUserSendInput, ret=%u\n", uRet);
777 UserLeave();
778 return uRet;
779}
#define FIXME(fmt,...)
Definition: debug.h:111
static void cleanup(void)
Definition: main.c:1335
unsigned int UINT
Definition: ndis.h:50
#define MmCopyFromCaller
Definition: polytest.cpp:29
KEYBDINPUT ki
Definition: winable.h:62
DWORD type
Definition: winable.h:59
MOUSEINPUT mi
Definition: winable.h:61
VOID FASTCALL SetLastNtError(_In_ NTSTATUS Status)
Definition: error.c:31
BOOL NTAPI UserSendKeyboardInput(KEYBDINPUT *pKbdInput, BOOL bInjected)
Definition: keyboard.c:1110
BOOL NTAPI UserSendMouseInput(MOUSEINPUT *pMouseInput, BOOL bInjected)
Definition: mouse.c:168
#define INPUT_HARDWARE
Definition: winable.h:11
#define INPUT_KEYBOARD
Definition: winable.h:10
#define INPUT_MOUSE
Definition: winable.h:9

Referenced by keybd_event(), mouse_event(), and SendInput().

◆ OpenInputDevice()

static NTSTATUS NTAPI OpenInputDevice ( PHANDLE  pHandle,
PFILE_OBJECT ppObject,
CONST WCHAR pszDeviceName 
)
static

Definition at line 88 of file input.c.

89{
94
95 RtlInitUnicodeString(&DeviceName, pszDeviceName);
96
100 NULL,
101 NULL);
102
103 Status = ZwOpenFile(pHandle,
106 &Iosb,
107 0,
108 0);
109 if (NT_SUCCESS(Status) && ppObject)
110 {
113 }
114
115 return Status;
116}
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
return Iosb
Definition: create.c:4402
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define KernelMode
Definition: asm.h:34
NTSYSAPI NTSTATUS NTAPI ZwOpenFile(_Out_ PHANDLE FileHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes, _Out_ PIO_STATUS_BLOCK IoStatusBlock, _In_ ULONG ShareAccess, _In_ ULONG OpenOptions)
#define SYNCHRONIZE
Definition: nt_native.h:61
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define FILE_ALL_ACCESS
Definition: nt_native.h:651
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:494
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_opt_ PCUNICODE_STRING DeviceName
Definition: wdfdevice.h:3275

Referenced by RawInputThreadMain().

◆ RawInputThreadMain()

VOID NTAPI RawInputThreadMain ( VOID  )

Definition at line 124 of file input.c.

125{
126 NTSTATUS MouStatus = STATUS_UNSUCCESSFUL, KbdStatus = STATUS_UNSUCCESSFUL, Status;
127 IO_STATUS_BLOCK MouIosb, KbdIosb;
128 PFILE_OBJECT pKbdDevice = NULL, pMouDevice = NULL;
130 //LARGE_INTEGER WaitTimeout;
131 PVOID WaitObjects[4], pSignaledObject = NULL;
133 ULONG cWaitObjects = 0, cMaxWaitObjects = 2;
134 MOUSE_INPUT_DATA MouseInput;
135 KEYBOARD_INPUT_DATA KeyInput;
137 HWINSTA hWinSta;
138
139 ByteOffset.QuadPart = (LONGLONG)0;
140 //WaitTimeout.QuadPart = (LONGLONG)(-10000000);
141
145
146 TRACE("Raw Input Thread %p\n", ptiRawInput);
147
150
152 0,
153 NULL,
156 UserMode,
157 (PHANDLE)&hWinSta);
158 if (NT_SUCCESS(Status))
159 {
161 }
162 else
163 {
164 ASSERT(FALSE);
165 /* Failed to open the interactive winsta! What now? */
166 }
167
170 UserLeave();
171
174
176 for (;;)
177 {
178 if (!ghMouseDevice)
179 {
180 /* Check if mouse device already exists */
181 Status = OpenInputDevice(&ghMouseDevice, &pMouDevice, L"\\Device\\PointerClass0" );
182 if (NT_SUCCESS(Status))
183 {
184 ++cMaxWaitObjects;
185 TRACE("Mouse connected!\n");
186 }
187 }
188 if (!ghKeyboardDevice)
189 {
190 /* Check if keyboard device already exists */
191 Status = OpenInputDevice(&ghKeyboardDevice, &pKbdDevice, L"\\Device\\KeyboardClass0");
192 if (NT_SUCCESS(Status))
193 {
194 ++cMaxWaitObjects;
195 TRACE("Keyboard connected!\n");
196 // Get and load keyboard attributes.
199 // Register the Window hotkey.
201 // Register the Window Snap hotkey.
206 // Register the debug hotkeys.
208 UserLeave();
209 }
210 }
211
212 /* Reset WaitHandles array */
213 cWaitObjects = 0;
214 WaitObjects[cWaitObjects++] = ShutdownEvent;
215 WaitObjects[cWaitObjects++] = MasterTimer;
216
217 if (ghMouseDevice)
218 {
219 /* Try to read from mouse if previous reading is not pending */
220 if (MouStatus != STATUS_PENDING)
221 {
222 MouStatus = ZwReadFile(ghMouseDevice,
223 NULL,
224 NULL,
225 NULL,
226 &MouIosb,
227 &MouseInput,
228 sizeof(MOUSE_INPUT_DATA),
229 &ByteOffset,
230 NULL);
231 }
232
233 if (MouStatus == STATUS_PENDING)
234 WaitObjects[cWaitObjects++] = &pMouDevice->Event;
235 }
236
238 {
239 /* Try to read from keyboard if previous reading is not pending */
240 if (KbdStatus != STATUS_PENDING)
241 {
242 KbdStatus = ZwReadFile(ghKeyboardDevice,
243 NULL,
244 NULL,
245 NULL,
246 &KbdIosb,
247 &KeyInput,
248 sizeof(KEYBOARD_INPUT_DATA),
249 &ByteOffset,
250 NULL);
251
252 }
253 if (KbdStatus == STATUS_PENDING)
254 WaitObjects[cWaitObjects++] = &pKbdDevice->Event;
255 }
256
257 /* If all objects are pending, wait for them */
258 if (cWaitObjects == cMaxWaitObjects)
259 {
260 Status = KeWaitForMultipleObjects(cWaitObjects,
261 WaitObjects,
262 WaitAny,
265 TRUE,
266 NULL,//&WaitTimeout,
268
269 if ((Status >= STATUS_WAIT_0) &&
270 (Status < (STATUS_WAIT_0 + (LONG)cWaitObjects)))
271 {
272 /* Some device has finished reading */
273 pSignaledObject = WaitObjects[Status - STATUS_WAIT_0];
274
275 /* Check if it is mouse or keyboard and update status */
276 if ((MouStatus == STATUS_PENDING) &&
277 (pSignaledObject == &pMouDevice->Event))
278 {
279 MouStatus = MouIosb.Status;
280 }
281 else if ((KbdStatus == STATUS_PENDING) &&
282 (pSignaledObject == &pKbdDevice->Event))
283 {
284 KbdStatus = KbdIosb.Status;
285 }
286 else if (pSignaledObject == MasterTimer)
287 {
289 }
290 else if (pSignaledObject == ShutdownEvent)
291 {
292 break;
293 }
294 else ASSERT(FALSE);
295 }
296 }
297
298 /* Have we successed reading from mouse? */
299 if (NT_SUCCESS(MouStatus) && MouStatus != STATUS_PENDING)
300 {
301 TRACE("MouseEvent\n");
302
303 /* Set LastInputTick */
305
306 /* Process data */
308 UserProcessMouseInput(&MouseInput);
309 UserLeave();
310 }
311 else if (MouStatus != STATUS_PENDING)
312 ERR("Failed to read from mouse: %x.\n", MouStatus);
313
314 /* Have we successed reading from keyboard? */
315 if (NT_SUCCESS(KbdStatus) && KbdStatus != STATUS_PENDING)
316 {
317 TRACE("KeyboardEvent: %s %04x\n",
318 (KeyInput.Flags & KEY_BREAK) ? "up" : "down",
319 KeyInput.MakeCode);
320
321 /* Set LastInputTick */
323
324 /* Process data */
326 UserProcessKeyboardInput(&KeyInput);
327 UserLeave();
328 }
329 else if (KbdStatus != STATUS_PENDING)
330 ERR("Failed to read from keyboard: %x.\n", KbdStatus);
331 }
332
333 if (ghMouseDevice)
334 {
337 ObDereferenceObject(pMouDevice);
339 }
340
342 {
345 ObDereferenceObject(pKbdDevice);
347 }
348
349 ERR("Raw Input Thread Exit!\n");
350}
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
static HANDLE ShutdownEvent
Definition: dcomlaunch.c:28
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
IN PDCB IN PCCB IN VBO IN OUT PULONG OUT PDIRENT OUT PBCB OUT PVBO ByteOffset
Definition: fatprocs.h:731
_Must_inspect_result_ _In_ WAIT_TYPE _In_opt_ PLARGE_INTEGER _In_opt_ PKWAIT_BLOCK WaitBlockArray
Definition: fsrtlfuncs.h:1153
#define IDHK_SNAP_LEFT
Definition: hotkey.h:20
#define IDHK_WINKEY
Definition: hotkey.h:16
#define IDHK_SNAP_UP
Definition: hotkey.h:22
#define IDHK_SNAP_DOWN
Definition: hotkey.h:23
#define IDHK_SNAP_RIGHT
Definition: hotkey.h:21
#define PWND_BOTTOM
Definition: ntuser.h:769
struct _THREADINFO * GetW32ThreadInfo(VOID)
Definition: misc.c:805
#define TIF_SYSTEMTHREAD
Definition: ntuser.h:265
#define LOW_REALTIME_PRIORITY
#define UserMode
Definition: asm.h:35
NTSYSAPI NTSTATUS NTAPI ZwCancelIoFile(_In_ HANDLE FileHandle, _Out_ PIO_STATUS_BLOCK IoStatusBlock)
#define MAXIMUM_ALLOWED
Definition: nt_native.h:83
#define KEY_BREAK
Definition: ntddkbd.h:71
@ WaitAny
NTSTATUS NTAPI KeWaitForMultipleObjects(IN ULONG Count, IN PVOID Object[], IN WAIT_TYPE WaitType, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL, OUT PKWAIT_BLOCK WaitBlockArray OPTIONAL)
Definition: wait.c:586
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
#define STATUS_WAIT_0
Definition: ntstatus.h:237
#define STATUS_PENDING
Definition: ntstatus.h:82
PWINSTATION_OBJECT InputWindowStation
Definition: winsta.c:21
BOOL FASTCALL UserSetProcessWindowStation(HWINSTA hWindowStation)
Definition: winsta.c:1382
#define L(x)
Definition: ntvdm.h:50
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3379
NTSTATUS NTAPI ObOpenObjectByPointer(IN PVOID Object, IN ULONG HandleAttributes, IN PACCESS_STATE PassedAccessState, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PHANDLE Handle)
Definition: obhandle.c:2742
long LONG
Definition: pedump.c:60
NTSTATUS NTAPI PoRequestShutdownEvent(OUT PVOID *Event)
Definition: poshtdwn.c:384
struct _CLIENTINFO * pClientInfo
Definition: win32.h:94
KPRIORITY NTAPI KeSetPriorityThread(IN PKTHREAD Thread, IN KPRIORITY Priority)
Definition: thrdobj.c:1319
int64_t LONGLONG
Definition: typedefs.h:68
uint32_t ULONG
Definition: typedefs.h:59
POBJECT_TYPE ExWindowStationObjectType
Definition: win32k.c:21
BOOL FASTCALL UserRegisterHotKey(PWND pWnd, int id, UINT fsModifiers, UINT vk)
Definition: hotkey.c:431
VOID FASTCALL StartDebugHotKeys(VOID)
Definition: hotkey.c:44
static NTSTATUS NTAPI OpenInputDevice(PHANDLE pHandle, PFILE_OBJECT *ppObject, CONST WCHAR *pszDeviceName)
Definition: input.c:88
static HANDLE ghMouseDevice
Definition: input.c:22
HANDLE ghKeyboardDevice
Definition: input.c:19
PTHREADINFO ptiRawInput
Definition: input.c:15
static DWORD FASTCALL IntLastInputTick(BOOL bUpdate)
Definition: input.c:32
VOID NTAPI UserProcessKeyboardInput(PKEYBOARD_INPUT_DATA pKeyInput)
Definition: keyboard.c:1191
VOID NTAPI UserProcessMouseInput(PMOUSE_INPUT_DATA pMouseInputData)
Definition: mouse.c:40
VOID NTAPI UserInitKeyboard(HANDLE hKeyboardDevice)
Definition: keyboard.c:163
VOID FASTCALL ProcessTimers(VOID)
Definition: timer.c:446
VOID FASTCALL StartTheTimers(VOID)
Definition: timer.c:368
#define MOD_WIN
Definition: winuser.h:2644
#define VK_UP
Definition: winuser.h:2225
#define VK_LEFT
Definition: winuser.h:2224
#define VK_RIGHT
Definition: winuser.h:2226
#define VK_DOWN
Definition: winuser.h:2227
* PFILE_OBJECT
Definition: iotypes.h:1998
@ UserRequest
Definition: ketypes.h:421
#define ObDereferenceObject
Definition: obfuncs.h:203
#define NT_ASSERT
Definition: rtlfuncs.h:3310

Referenced by UserSystemThreadProc().

◆ UserAttachThreadInput()

NTSTATUS FASTCALL UserAttachThreadInput ( PTHREADINFO  ptiFrom,
PTHREADINFO  ptiTo,
BOOL  fAttach 
)

Definition at line 480 of file input.c.

481{
482 MSG msg;
483 PATTACHINFO pai;
484 PCURICON_OBJECT CurIcon;
485
486 /* Can not be the same thread. */
487 if (ptiFrom == ptiTo) return STATUS_INVALID_PARAMETER;
488
489 /* Do not attach to system threads or between different desktops. */
490 if (ptiFrom->TIF_flags & TIF_DONTATTACHQUEUE ||
492 ptiFrom->rpdesk != ptiTo->rpdesk)
494
495 /* MSDN Note:
496 Keyboard and mouse events received by both threads are processed by the thread specified by the idAttachTo.
497 */
498
499 /* If Attach set, allocate and link. */
500 if (fAttach)
501 {
503 if (!pai) return STATUS_NO_MEMORY;
504
505 pai->paiNext = gpai;
506 pai->pti1 = ptiFrom;
507 pai->pti2 = ptiTo;
508 gpai = pai;
509 paiCount++;
510 ERR("Attach Allocated! ptiFrom 0x%p ptiTo 0x%p paiCount %d\n",ptiFrom,ptiTo,paiCount);
511
512 if (ptiTo->MessageQueue != ptiFrom->MessageQueue)
513 {
514
515 ptiTo->MessageQueue->iCursorLevel -= ptiFrom->iCursorLevel;
516
517 if (ptiFrom->MessageQueue == gpqForeground)
518 {
519 ERR("ptiFrom is Foreground\n");
520 ptiTo->MessageQueue->spwndActive = ptiFrom->MessageQueue->spwndActive;
521 ptiTo->MessageQueue->spwndFocus = ptiFrom->MessageQueue->spwndFocus;
522 ptiTo->MessageQueue->spwndCapture = ptiFrom->MessageQueue->spwndCapture;
523 ptiTo->MessageQueue->QF_flags ^= ((ptiTo->MessageQueue->QF_flags ^ ptiFrom->MessageQueue->QF_flags) & QF_CAPTURELOCKED);
524 RtlCopyMemory(&ptiTo->MessageQueue->CaretInfo,
525 &ptiFrom->MessageQueue->CaretInfo,
526 sizeof(ptiTo->MessageQueue->CaretInfo));
529 gptiForeground = ptiTo;
530 }
531 else
532 {
533 ERR("ptiFrom NOT Foreground\n");
534 if ( ptiTo->MessageQueue->spwndActive == 0 )
535 ptiTo->MessageQueue->spwndActive = ptiFrom->MessageQueue->spwndActive;
536 if ( ptiTo->MessageQueue->spwndFocus == 0 )
537 ptiTo->MessageQueue->spwndFocus = ptiFrom->MessageQueue->spwndFocus;
538 }
539
540 CurIcon = ptiFrom->MessageQueue->CursorObject;
541
542 MsqDestroyMessageQueue(ptiFrom);
543
544 if (CurIcon)
545 {
546 // Could be global. Keep it above the water line!
547 UserReferenceObject(CurIcon);
548 }
549
550 if (CurIcon && UserObjectInDestroy(UserHMGetHandle(CurIcon)))
551 {
552 UserDereferenceObject(CurIcon);
553 CurIcon = NULL;
554 }
555
556 ptiFrom->MessageQueue = ptiTo->MessageQueue;
557
558 // Pass cursor From if To is null. Pass test_SetCursor parent_id == current pti ID.
559 if (CurIcon && ptiTo->MessageQueue->CursorObject == NULL)
560 {
561 ERR("ptiTo receiving ptiFrom Cursor\n");
562 ptiTo->MessageQueue->CursorObject = CurIcon;
563 }
564
565 ptiFrom->MessageQueue->cThreads++;
566 ERR("ptiTo S Share count %u\n", ptiFrom->MessageQueue->cThreads);
567
569 }
570 else
571 {
572 ERR("Attach Threads are already associated!\n");
573 }
574 }
575 else /* If clear, unlink and free it. */
576 {
577 BOOL Hit = FALSE;
578 PATTACHINFO *ppai;
579
580 if (!gpai) return STATUS_INVALID_PARAMETER;
581
582 /* Search list and free if found or return false. */
583 ppai = &gpai;
584 while (*ppai != NULL)
585 {
586 if ( (*ppai)->pti2 == ptiTo && (*ppai)->pti1 == ptiFrom )
587 {
588 pai = *ppai;
589 /* Remove it from the list */
590 *ppai = (*ppai)->paiNext;
592 paiCount--;
593 Hit = TRUE;
594 break;
595 }
596 ppai = &((*ppai)->paiNext);
597 }
598
599 if (!Hit) return STATUS_INVALID_PARAMETER;
600
601 ERR("Attach Free! ptiFrom 0x%p ptiTo 0x%p paiCount %d\n",ptiFrom,ptiTo,paiCount);
602
603 if (ptiTo->MessageQueue == ptiFrom->MessageQueue)
604 {
605 PWND spwndActive = ptiTo->MessageQueue->spwndActive;
606 PWND spwndFocus = ptiTo->MessageQueue->spwndFocus;
607
608 if (gptiForeground == ptiFrom)
609 {
610 ERR("ptiTo is now pti FG.\n");
611 // MessageQueue foreground is set so switch threads.
612 gptiForeground = ptiTo;
613 }
614 ptiTo->MessageQueue->cThreads--;
615 ERR("ptiTo E Share count %u\n", ptiTo->MessageQueue->cThreads);
616 ASSERT(ptiTo->MessageQueue->cThreads >= 1);
617
619
620 ptiFrom->MessageQueue = MsqCreateMessageQueue(ptiFrom);
621
622 if (spwndActive)
623 {
624 if (spwndActive->head.pti == ptiFrom)
625 {
626 ptiFrom->MessageQueue->spwndActive = spwndActive;
627 ptiTo->MessageQueue->spwndActive = 0;
628 }
629 }
630 if (spwndFocus)
631 {
632 if (spwndFocus->head.pti == ptiFrom)
633 {
634 ptiFrom->MessageQueue->spwndFocus = spwndFocus;
635 ptiTo->MessageQueue->spwndFocus = 0;
636 }
637 }
638 ptiTo->MessageQueue->iCursorLevel -= ptiFrom->iCursorLevel;
639 }
640 else
641 {
642 ERR("Detaching Threads are not associated!\n");
643 }
644 }
645 /* Note that key state, which can be ascertained by calls to the GetKeyState
646 or GetKeyboardState function, is reset after a call to AttachThreadInput.
647 ATM which one?
648 */
649 RtlCopyMemory(ptiTo->MessageQueue->afKeyState, gafAsyncKeyState, sizeof(gafAsyncKeyState));
650
651 ptiTo->MessageQueue->msgDblClk.message = 0;
652
653 /* Generate mouse move message */
654 msg.message = WM_MOUSEMOVE;
655 msg.wParam = UserGetMouseButtonsState();
656 msg.lParam = MAKELPARAM(gpsi->ptCursor.x, gpsi->ptCursor.y);
657 msg.pt = gpsi->ptCursor;
659
660 return STATUS_SUCCESS;
661}
#define msg(x)
Definition: auth_time.c:54
#define PagedPool
Definition: env_spec_w32.h:308
PUSER_MESSAGE_QUEUE gpqForeground
Definition: focus.c:13
#define TIF_DONTATTACHQUEUE
Definition: ntuser.h:269
#define UserHMGetHandle(obj)
Definition: ntuser.h:230
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
VOID FASTCALL co_MsqInsertMouseMessage(MSG *Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook)
Definition: msgqueue.c:580
VOID FASTCALL MsqDestroyMessageQueue(_In_ PTHREADINFO pti)
Definition: msgqueue.c:2411
PUSER_MESSAGE_QUEUE FASTCALL MsqCreateMessageQueue(PTHREADINFO pti)
Definition: msgqueue.c:2384
#define QF_CAPTURELOCKED
Definition: msgqueue.h:111
#define IntReferenceMessageQueue(MsgQueue)
Definition: msgqueue.h:217
#define IntDereferenceMessageQueue(MsgQueue)
Definition: msgqueue.h:220
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
INT iCursorLevel
Definition: win32.h:127
struct _USER_MESSAGE_QUEUE * MessageQueue
Definition: win32.h:89
Definition: ntuser.h:694
THRDESKHEAD head
Definition: ntuser.h:695
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1829
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
VOID FASTCALL IntSetFocusMessageQueue(PUSER_MESSAGE_QUEUE NewQueue)
Definition: desktop.c:1319
PTHREADINFO gptiForeground
Definition: focus.c:15
INT paiCount
Definition: input.c:18
WORD FASTCALL UserGetMouseButtonsState(VOID)
Definition: mouse.c:22
BYTE gafAsyncKeyState[256 *2/8]
Definition: keyboard.c:13
BOOL FASTCALL UserDereferenceObject(PVOID Object)
Definition: object.c:644
BOOL FASTCALL UserObjectInDestroy(HANDLE h)
Definition: object.c:703
VOID FASTCALL UserReferenceObject(PVOID obj)
Definition: object.c:731
#define USERTAG_ATTACHINFO
Definition: tags.h:197
#define MAKELPARAM(l, h)
Definition: winuser.h:4008
#define WM_MOUSEMOVE
Definition: winuser.h:1775

Referenced by co_IntSetParent(), co_UserCreateWindowEx(), co_UserDestroyWindow(), IntCreateWindow(), IntProcessOwnerSwap(), IsRemoveAttachThread(), and NtUserAttachThreadInput().

Variable Documentation

◆ ghKeyboardDevice

HANDLE ghKeyboardDevice = NULL

Definition at line 19 of file input.c.

Referenced by ProcessKeyEvent(), and RawInputThreadMain().

◆ ghMouseDevice

HANDLE ghMouseDevice
static

Definition at line 22 of file input.c.

Referenced by RawInputThreadMain().

◆ gpai

PATTACHINFO gpai = NULL

Definition at line 17 of file input.c.

Referenced by IsRemoveAttachThread(), and UserAttachThreadInput().

◆ LastInputTick

DWORD LastInputTick = 0
static

Definition at line 21 of file input.c.

Referenced by DoTheScreenSaver(), and IntLastInputTick().

◆ MasterTimer

PKTIMER MasterTimer = NULL

Definition at line 16 of file input.c.

Referenced by InitInputImpl(), IntSetTimer(), ProcessTimers(), and RawInputThreadMain().

◆ paiCount

INT paiCount = 0

Definition at line 18 of file input.c.

Referenced by UserAttachThreadInput().

◆ ptiRawInput

PTHREADINFO ptiRawInput

Definition at line 15 of file input.c.

Referenced by IntSetTimer(), and RawInputThreadMain().