ReactOS 0.4.17-dev-1190-g4c812f4
input.c File Reference
#include <win32k.h>
Include dependency graph for input.c:

Go to the source code of this file.

Macros

#define LAST_RIT_EVENT_UPDATE_INTERVAL   1000UL
 

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
 
PINPUT_DEVICE_INFO gpInputDeviceInfo = NULL
 
PERESOURCE gpDeviceInfoListMutex = NULL
 
static DWORD LastInputTick = 0
 
static HANDLE ghMouseDevice
 

Macro Definition Documentation

◆ LAST_RIT_EVENT_UPDATE_INTERVAL

#define LAST_RIT_EVENT_UPDATE_INTERVAL   1000UL

Definition at line 17 of file input.c.

Function Documentation

◆ DBG_DEFAULT_CHANNEL()

DBG_DEFAULT_CHANNEL ( UserInput  )

◆ DoTheScreenSaver()

VOID FASTCALL DoTheScreenSaver ( VOID  )

Definition at line 66 of file input.c.

67{
68 DWORD Test, TO;
69
70 if (gspv.iScrSaverTimeout > 0) // Zero means Off.
71 {
74 TO = 1000 * gspv.iScrSaverTimeout;
75 if (Test > TO)
76 {
77 TRACE("Screensaver Message Start! Tick %lu Timeout %d \n", Test, gspv.iScrSaverTimeout);
78
79 if (ppiScrnSaver) // We are or we are not the screensaver, prevent reentry...
80 {
81 if (!(ppiScrnSaver->W32PF_flags & W32PF_IDLESCREENSAVER))
82 {
83 ppiScrnSaver->W32PF_flags |= W32PF_IDLESCREENSAVER;
84 ERR("Screensaver is Idle\n");
85 }
86 }
87 else
88 {
90 if (ForegroundQueue && ForegroundQueue->spwndActive)
92 else
94 }
95 }
96 }
97}
#define ERR(fmt,...)
Definition: precomp.h:57
#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:39
#define LN_START_SCREENSAVE
Definition: undocuser.h:122
#define W32PF_IDLESCREENSAVER
Definition: win32.h:27
PUSER_MESSAGE_QUEUE FASTCALL IntGetFocusMessageQueue(VOID)
Definition: desktop.c:1335
static DWORD LastInputTick
Definition: input.c:30
PPROCESSINFO ppiScrnSaver
Definition: main.c:30
BOOL FASTCALL UserPostMessage(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: message.c:1397
SPIVALUES gspv
Definition: sysparams.c:17

Referenced by HungAppSysTimerProc().

◆ InitInputImpl()

NTSTATUS NTAPI InitInputImpl ( VOID  )

Definition at line 404 of file input.c.

405{
407 if (!MasterTimer)
408 {
409 ERR("Failed to allocate memory\n");
410 ASSERT(FALSE);
411 return STATUS_UNSUCCESSFUL;
412 }
414
415 return STATUS_SUCCESS;
416}
#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:23
#define USERTAG_SYSTEM
Definition: tags.h:282

Referenced by DriverEntry().

◆ IntBlockInput()

BOOL FASTCALL IntBlockInput ( PTHREADINFO  pti,
BOOL  BlockIt 
)

Definition at line 419 of file input.c.

420{
421 PTHREADINFO OldBlock;
422 ASSERT(pti);
423
424 if(!pti->rpdesk || ((pti->TIF_flags & TIF_INCLEANUP) && BlockIt))
425 {
426 /*
427 * Fail blocking if exiting the thread
428 */
429
430 return FALSE;
431 }
432
433 /*
434 * FIXME: Check access rights of the window station
435 * e.g. services running in the service window station cannot block input
436 */
437 if(!ThreadHasInputAccess(pti) ||
439 {
441 return FALSE;
442 }
443
444 ASSERT(pti->rpdesk);
445 OldBlock = pti->rpdesk->BlockInputThread;
446 if(OldBlock)
447 {
448 if(OldBlock != pti)
449 {
451 return FALSE;
452 }
453 pti->rpdesk->BlockInputThread = (BlockIt ? pti : NULL);
454 return OldBlock == NULL;
455 }
456
457 pti->rpdesk->BlockInputThread = (BlockIt ? pti : NULL);
458 return OldBlock == NULL;
459}
#define IntIsActiveDesktop(Desktop)
Definition: desktop.h:174
#define NULL
Definition: types.h:112
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
#define TIF_INCLEANUP
Definition: ntuser.h:266
FLONG TIF_flags
Definition: win32.h:96
struct _DESKTOP * rpdesk
Definition: win32.h:93
#define ThreadHasInputAccess(W32Thread)
Definition: input.h:103
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:21

Referenced by ExitThreadCallback(), and NtUserBlockInput().

◆ IntLastInputTick()

static DWORD FASTCALL IntLastInputTick ( BOOL  bUpdate)
static

Definition at line 41 of file input.c.

42{
43 if (bUpdate)
44 {
46 if (gpsi)
47 {
48 gpsi->dwLastRITEventTickCount = LastInputTick;
49 if (gpsi->dwLastRITEventTickCount - gpsi->dwLastSystemRITEventTickCountUpdate >
51 {
52 SharedUserData->LastSystemRITEventTickCount = LastInputTick;
53 gpsi->dwLastSystemRITEventTickCountUpdate = LastInputTick;
54 }
55 }
56 }
57 return LastInputTick;
58}
PSERVERINFO gpsi
Definition: imm.c:18
#define SharedUserData
#define LAST_RIT_EVENT_UPDATE_INTERVAL
Definition: input.c:17

Referenced by RawInputThreadMain().

◆ IsRemoveAttachThread()

BOOL FASTCALL IsRemoveAttachThread ( PTHREADINFO  pti)

Definition at line 481 of file input.c.

482{
484 PATTACHINFO pai;
485 BOOL Ret = TRUE;
486 PTHREADINFO ptiFrom = NULL, ptiTo = NULL;
487
488 do
489 {
490 if (!gpai) return TRUE;
491
492 pai = gpai; // Bottom of the list.
493
494 do
495 {
496 if (pai->pti2 == pti)
497 {
498 ptiFrom = pai->pti1;
499 ptiTo = pti;
500 break;
501 }
502 if (pai->pti1 == pti)
503 {
504 ptiFrom = pti;
505 ptiTo = pai->pti2;
506 break;
507 }
508 pai = pai->paiNext;
509
510 } while (pai);
511
512 if (!pai && !ptiFrom && !ptiTo) break;
513
514 Status = UserAttachThreadInput(ptiFrom, ptiTo, FALSE);
515 if (!NT_SUCCESS(Status)) Ret = FALSE;
516
517 } while (Ret);
518
519 return Ret;
520}
LONG NTSTATUS
Definition: precomp.h:26
#define TRUE
Definition: types.h:120
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
unsigned int BOOL
Definition: ntddk_ex.h:94
Status
Definition: gdiplustypes.h:24
PTHREADINFO pti2
Definition: input.h:46
struct _ATTACHINFO * paiNext
Definition: input.h:44
PTHREADINFO pti1
Definition: input.h:45
PATTACHINFO gpai
Definition: input.c:24
NTSTATUS FASTCALL UserAttachThreadInput(PTHREADINFO ptiFrom, PTHREADINFO ptiTo, BOOL fAttach)
Definition: input.c:523

Referenced by ExitThreadCallback().

◆ NtUserAttachThreadInput()

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

Definition at line 708 of file input.c.

712{
714 PTHREADINFO pti, ptiTo;
715 BOOL Ret = FALSE;
716
718 TRACE("Enter NtUserAttachThreadInput %s\n",(fAttach ? "TRUE" : "FALSE" ));
719
720 pti = IntTID2PTI(UlongToHandle(idAttach));
721 ptiTo = IntTID2PTI(UlongToHandle(idAttachTo));
722
723 if ( !pti || !ptiTo )
724 {
725 TRACE("AttachThreadInput pti or ptiTo NULL.\n");
727 goto Exit;
728 }
729
730 Status = UserAttachThreadInput( pti, ptiTo, fAttach);
731 if (!NT_SUCCESS(Status))
732 {
733 TRACE("AttachThreadInput Error Status 0x%x. \n",Status);
735 }
736 else Ret = TRUE;
737
738Exit:
739 TRACE("Leave NtUserAttachThreadInput, ret=%d\n",Ret);
740 UserLeave();
741 return Ret;
742}
#define UlongToHandle(ul)
Definition: basetsd.h:91
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:255
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:247
static void Exit(void)
Definition: sock.c:1330
PTHREADINFO FASTCALL IntTID2PTI(HANDLE id)
Definition: misc.c:41
NTSYSAPI ULONG WINAPI RtlNtStatusToDosError(NTSTATUS)

◆ NtUserBlockInput()

BOOL APIENTRY NtUserBlockInput ( BOOL  BlockIt)

Definition at line 463 of file input.c.

465{
466 BOOL ret;
467
468 TRACE("Enter NtUserBlockInput\n");
470
472
473 UserLeave();
474 TRACE("Leave NtUserBlockInput, ret=%i\n", ret);
475
476 return ret;
477}
return ret
Definition: mutex.c:147
PVOID NTAPI PsGetCurrentThreadWin32Thread(VOID)
Definition: thread.c:829
BOOL FASTCALL IntBlockInput(PTHREADINFO pti, BOOL BlockIt)
Definition: input.c:419

Referenced by BlockInput().

◆ NtUserSendInput()

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

Definition at line 751 of file input.c.

755{
756 PTHREADINFO pti;
757 UINT uRet = 0;
758
759 TRACE("Enter NtUserSendInput\n");
761
763 ASSERT(pti);
764
765 if (!pti->rpdesk)
766 {
767 goto cleanup;
768 }
769
770 if (!nInputs || !pInput || cbSize != sizeof(INPUT))
771 {
773 goto cleanup;
774 }
775
776 /*
777 * FIXME: Check access rights of the window station
778 * e.g. services running in the service window station cannot block input
779 */
780 if (!ThreadHasInputAccess(pti) ||
782 {
784 goto cleanup;
785 }
786
787 while (nInputs--)
788 {
789 INPUT SafeInput;
791
792 Status = MmCopyFromCaller(&SafeInput, pInput++, sizeof(INPUT));
793 if (!NT_SUCCESS(Status))
794 {
796 goto cleanup;
797 }
798
799 switch (SafeInput.type)
800 {
801 case INPUT_MOUSE:
802 if (UserSendMouseInput(&SafeInput.mi, TRUE))
803 uRet++;
804 break;
805 case INPUT_KEYBOARD:
806 if (UserSendKeyboardInput(&SafeInput.ki, TRUE))
807 uRet++;
808 break;
809 case INPUT_HARDWARE:
810 FIXME("INPUT_HARDWARE not supported!\n");
811 break;
812 default:
813 ERR("SendInput(): Invalid input type: 0x%x\n", SafeInput.type);
814 break;
815 }
816 }
817
818cleanup:
819 TRACE("Leave NtUserSendInput, ret=%u\n", uRet);
820 UserLeave();
821 return uRet;
822}
#define FIXME(fmt,...)
Definition: precomp.h:53
static void cleanup(void)
Definition: main.c:1335
unsigned int UINT
Definition: sysinfo.c:13
#define MmCopyFromCaller
Definition: polytest.cpp:29
KEYBDINPUT ki
Definition: winable.h:62
DWORD type
Definition: winable.h:59
MOUSEINPUT mi
Definition: winable.h:61
UINT32 cbSize
VOID FASTCALL SetLastNtError(_In_ NTSTATUS Status)
Definition: error.c:30
BOOL NTAPI UserSendKeyboardInput(KEYBDINPUT *pKbdInput, BOOL bInjected)
Definition: keyboard.c:1333
BOOL NTAPI UserSendMouseInput(MOUSEINPUT *pMouseInput, BOOL bInjected)
Definition: mouse.c:235
#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 106 of file input.c.

107{
112
113 RtlInitUnicodeString(&DeviceName, pszDeviceName);
114
116 &DeviceName,
118 NULL,
119 NULL);
120
121 Status = ZwOpenFile(pHandle,
124 &Iosb,
125 0,
126 0);
127 if (NT_SUCCESS(Status) && ppObject)
128 {
131 }
132
133 return Status;
134}
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
return Iosb
Definition: create.c:4403
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:115
#define KernelMode
Definition: asm.h:38
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:493
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_opt_ PCUNICODE_STRING DeviceName
Definition: wdfdevice.h:3281

Referenced by RawInputThreadMain().

◆ RawInputThreadMain()

VOID NTAPI RawInputThreadMain ( VOID  )

Definition at line 142 of file input.c.

143{
144 NTSTATUS MouStatus = STATUS_UNSUCCESSFUL, KbdStatus = STATUS_UNSUCCESSFUL, Status;
145 IO_STATUS_BLOCK MouIosb, KbdIosb;
146 PFILE_OBJECT pKbdDevice = NULL, pMouDevice = NULL;
148 //LARGE_INTEGER WaitTimeout;
149 PVOID WaitObjects[4], pSignaledObject = NULL;
151 ULONG cWaitObjects = 0, cMaxWaitObjects = 2;
152 MOUSE_INPUT_DATA MouseInput;
153 KEYBOARD_INPUT_DATA KeyInput;
155 HWINSTA hWinSta;
158
159 RtlZeroMemory(&Mouse, sizeof(Mouse));
160 Mouse.DeviceType = RIM_TYPEMOUSE;
161 RtlInitUnicodeString(&Mouse.DeviceName, L"\\Device\\PointerClass0");
162 Mouse.Mouse.Attributes.NumberOfButtons = 2;
163
165 Keyboard.DeviceType = RIM_TYPEKEYBOARD;
166 RtlInitUnicodeString(&Keyboard.DeviceName, L"\\Device\\KeyboardClass0");
167
168 ByteOffset.QuadPart = (LONGLONG)0;
169 //WaitTimeout.QuadPart = (LONGLONG)(-10000000);
170
174
175 TRACE("Raw Input Thread %p\n", ptiRawInput);
176
179
181 0,
182 NULL,
185 UserMode,
186 (PHANDLE)&hWinSta);
187 if (NT_SUCCESS(Status))
188 {
190 }
191 else
192 {
193 ASSERT(FALSE);
194 /* Failed to open the interactive winsta! What now? */
195 }
196
201
204 UserLeave();
205
208
210 for (;;)
211 {
212 if (!ghMouseDevice)
213 {
214 /* Check if mouse device already exists */
215 Status = OpenInputDevice(&ghMouseDevice, &pMouDevice, Mouse.DeviceName.Buffer);
216 if (NT_SUCCESS(Status))
217 {
218 ++cMaxWaitObjects;
219 TRACE("Mouse connected!\n");
220 Mouse.Handle = ghMouseDevice;
221 Mouse.pNextDeviceInfo = gpInputDeviceInfo;
223 }
224 }
225 if (!ghKeyboardDevice)
226 {
227 /* Check if keyboard device already exists */
228 Status = OpenInputDevice(&ghKeyboardDevice, &pKbdDevice, Keyboard.DeviceName.Buffer);
229 if (NT_SUCCESS(Status))
230 {
231 ++cMaxWaitObjects;
232 TRACE("Keyboard connected!\n");
233 Keyboard.Handle = ghKeyboardDevice;
234 Keyboard.pNextDeviceInfo = gpInputDeviceInfo;
236 // Get and load keyboard attributes.
238 Keyboard.Keyboard.Attributes = gKeyboardInfo;
240 // Register the Window hotkey.
242 // Register the Window Snap hotkey.
247 // Register the debug hotkeys.
249 UserLeave();
250 }
251 }
252
253 /* Reset WaitHandles array */
254 cWaitObjects = 0;
255 WaitObjects[cWaitObjects++] = ShutdownEvent;
256 WaitObjects[cWaitObjects++] = MasterTimer;
257
258 if (ghMouseDevice)
259 {
260 /* Try to read from mouse if previous reading is not pending */
261 if (MouStatus != STATUS_PENDING)
262 {
263 MouStatus = ZwReadFile(ghMouseDevice,
264 NULL,
265 NULL,
266 NULL,
267 &MouIosb,
268 &MouseInput,
269 sizeof(MOUSE_INPUT_DATA),
270 &ByteOffset,
271 NULL);
272 }
273
274 if (MouStatus == STATUS_PENDING)
275 WaitObjects[cWaitObjects++] = &pMouDevice->Event;
276 }
277
279 {
280 /* Try to read from keyboard if previous reading is not pending */
281 if (KbdStatus != STATUS_PENDING)
282 {
283 KbdStatus = ZwReadFile(ghKeyboardDevice,
284 NULL,
285 NULL,
286 NULL,
287 &KbdIosb,
288 &KeyInput,
289 sizeof(KEYBOARD_INPUT_DATA),
290 &ByteOffset,
291 NULL);
292
293 }
294 if (KbdStatus == STATUS_PENDING)
295 WaitObjects[cWaitObjects++] = &pKbdDevice->Event;
296 }
297
298 /* If all objects are pending, wait for them */
299 if (cWaitObjects == cMaxWaitObjects)
300 {
301 Status = KeWaitForMultipleObjects(cWaitObjects,
302 WaitObjects,
303 WaitAny,
306 TRUE,
307 NULL,//&WaitTimeout,
309
310 if ((Status >= STATUS_WAIT_0) &&
311 (Status < (STATUS_WAIT_0 + (LONG)cWaitObjects)))
312 {
313 /* Some device has finished reading */
314 pSignaledObject = WaitObjects[Status - STATUS_WAIT_0];
315
316 /* Check if it is mouse or keyboard and update status */
317 if ((MouStatus == STATUS_PENDING) &&
318 (pSignaledObject == &pMouDevice->Event))
319 {
320 MouStatus = MouIosb.Status;
321 }
322 else if ((KbdStatus == STATUS_PENDING) &&
323 (pSignaledObject == &pKbdDevice->Event))
324 {
325 KbdStatus = KbdIosb.Status;
326 }
327 else if (pSignaledObject == MasterTimer)
328 {
330 }
331 else if (pSignaledObject == ShutdownEvent)
332 {
333 break;
334 }
335 else ASSERT(FALSE);
336 }
337 }
338
339 /* Have we successed reading from mouse? */
340 if (NT_SUCCESS(MouStatus) && MouStatus != STATUS_PENDING)
341 {
342 TRACE("MouseEvent\n");
343
344 /* Set LastInputTick */
346
347 /* Process data */
349 UserProcessMouseInput(&Mouse, &MouseInput);
350 UserLeave();
351 }
352 else if (MouStatus != STATUS_PENDING)
353 ERR("Failed to read from mouse: %x.\n", MouStatus);
354
355 /* Have we successed reading from keyboard? */
356 if (NT_SUCCESS(KbdStatus) && KbdStatus != STATUS_PENDING)
357 {
358 TRACE("KeyboardEvent: %s %04x\n",
359 (KeyInput.Flags & KEY_BREAK) ? "up" : "down",
360 KeyInput.MakeCode);
361
362 /* Set LastInputTick */
364
365 /* Process data */
368 UserLeave();
369 }
370 else if (KbdStatus != STATUS_PENDING)
371 ERR("Failed to read from keyboard: %x.\n", KbdStatus);
372 }
373
374 if (ghMouseDevice)
375 {
378 ObDereferenceObject(pMouDevice);
380 }
381
383 {
386 ObDereferenceObject(pKbdDevice);
388 }
389
392
393 ERR("Raw Input Thread Exit!\n");
394}
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
static HANDLE ShutdownEvent
Definition: dcomlaunch.c:28
#define L(x)
Definition: resources.c:13
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
NTSTATUS ExInitializeResourceLite(PULONG res)
Definition: env_spec_w32.h:641
#define ExDeleteResourceLite(res)
Definition: env_spec_w32.h:647
IN PDCB IN PCCB IN VBO IN OUT PULONG OUT PDIRENT OUT PBCB OUT PVBO ByteOffset
Definition: fatprocs.h:732
_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
@ Keyboard
Definition: i8042prt.h:115
@ Mouse
Definition: i8042prt.h:116
#define PWND_BOTTOM
Definition: ntuser.h:773
struct _THREADINFO * GetW32ThreadInfo(VOID)
Definition: misc.c:806
#define TIF_SYSTEMTHREAD
Definition: ntuser.h:268
#define LOW_REALTIME_PRIORITY
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define UserMode
Definition: asm.h:39
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:599
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
#define STATUS_WAIT_0
Definition: ntstatus.h:330
PWINSTATION_OBJECT InputWindowStation
Definition: winsta.c:21
BOOL FASTCALL UserSetProcessWindowStation(HWINSTA hWindowStation)
Definition: winsta.c:1614
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3411
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:2769
long LONG
Definition: pedump.c:60
NTSTATUS NTAPI PoRequestShutdownEvent(OUT PVOID *Event)
Definition: poshtdwn.c:384
#define MOD_WIN
Definition: winuser.h:2686
#define VK_UP
Definition: winuser.h:2261
#define VK_LEFT
Definition: winuser.h:2260
#define VK_RIGHT
Definition: winuser.h:2262
#define VK_DOWN
Definition: winuser.h:2263
struct _CLIENTINFO * pClientInfo
Definition: win32.h:95
#define STATUS_PENDING
Definition: telnetd.h:14
KPRIORITY NTAPI KeSetPriorityThread(IN PKTHREAD Thread, IN KPRIORITY Priority)
Definition: thrdobj.c:1300
int64_t LONGLONG
Definition: typedefs.h:68
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
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:447
VOID FASTCALL SetDebugHotKeys(VOID)
Definition: hotkey.c:46
static NTSTATUS NTAPI OpenInputDevice(PHANDLE pHandle, PFILE_OBJECT *ppObject, CONST WCHAR *pszDeviceName)
Definition: input.c:106
static HANDLE ghMouseDevice
Definition: input.c:31
HANDLE ghKeyboardDevice
Definition: input.c:26
PTHREADINFO ptiRawInput
Definition: input.c:22
static DWORD FASTCALL IntLastInputTick(BOOL bUpdate)
Definition: input.c:41
PINPUT_DEVICE_INFO gpInputDeviceInfo
Definition: input.c:27
PERESOURCE gpDeviceInfoListMutex
Definition: input.c:28
KEYBOARD_ATTRIBUTES gKeyboardInfo
Definition: keyboard.c:17
VOID NTAPI UserProcessKeyboardInput(PINPUT_DEVICE_INFO pDeviceInfo, PKEYBOARD_INPUT_DATA pKeyInput)
Definition: keyboard.c:1474
VOID NTAPI UserProcessMouseInput(PINPUT_DEVICE_INFO pDeviceInfo, PMOUSE_INPUT_DATA pMouseInputData)
Definition: mouse.c:104
VOID NTAPI UserInitKeyboard(HANDLE hKeyboardDevice)
Definition: keyboard.c:178
VOID FASTCALL ProcessTimers(VOID)
Definition: timer.c:452
VOID FASTCALL StartTheTimers(VOID)
Definition: timer.c:374
* PFILE_OBJECT
Definition: iotypes.h:1998
@ UserRequest
Definition: ketypes.h:473
#define ObDereferenceObject
Definition: obfuncs.h:203
#define NT_ASSERT
Definition: rtlfuncs.h:3334

Referenced by UserSystemThreadProc().

◆ UserAttachThreadInput()

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

Definition at line 523 of file input.c.

524{
525 MSG msg;
526 PATTACHINFO pai;
527 PCURICON_OBJECT CurIcon;
528
529 /* Can not be the same thread. */
530 if (ptiFrom == ptiTo) return STATUS_INVALID_PARAMETER;
531
532 /* Do not attach to system threads or between different desktops. */
533 if (ptiFrom->TIF_flags & TIF_DONTATTACHQUEUE ||
535 ptiFrom->rpdesk != ptiTo->rpdesk)
537
538 /* MSDN Note:
539 Keyboard and mouse events received by both threads are processed by the thread specified by the idAttachTo.
540 */
541
542 /* If Attach set, allocate and link. */
543 if (fAttach)
544 {
546 if (!pai) return STATUS_NO_MEMORY;
547
548 pai->paiNext = gpai;
549 pai->pti1 = ptiFrom;
550 pai->pti2 = ptiTo;
551 gpai = pai;
552 paiCount++;
553 ERR("Attach Allocated! ptiFrom 0x%p ptiTo 0x%p paiCount %d\n",ptiFrom,ptiTo,paiCount);
554
555 if (ptiTo->MessageQueue != ptiFrom->MessageQueue)
556 {
557
558 ptiTo->MessageQueue->iCursorLevel -= ptiFrom->iCursorLevel;
559
560 if (ptiFrom->MessageQueue == gpqForeground)
561 {
562 ERR("ptiFrom is Foreground\n");
563 ptiTo->MessageQueue->spwndActive = ptiFrom->MessageQueue->spwndActive;
564 ptiTo->MessageQueue->spwndFocus = ptiFrom->MessageQueue->spwndFocus;
565 ptiTo->MessageQueue->spwndCapture = ptiFrom->MessageQueue->spwndCapture;
566 ptiTo->MessageQueue->QF_flags ^= ((ptiTo->MessageQueue->QF_flags ^ ptiFrom->MessageQueue->QF_flags) & QF_CAPTURELOCKED);
567 RtlCopyMemory(&ptiTo->MessageQueue->CaretInfo,
568 &ptiFrom->MessageQueue->CaretInfo,
569 sizeof(ptiTo->MessageQueue->CaretInfo));
572 gptiForeground = ptiTo;
573 }
574 else
575 {
576 ERR("ptiFrom NOT Foreground\n");
577 if ( ptiTo->MessageQueue->spwndActive == 0 )
578 ptiTo->MessageQueue->spwndActive = ptiFrom->MessageQueue->spwndActive;
579 if ( ptiTo->MessageQueue->spwndFocus == 0 )
580 ptiTo->MessageQueue->spwndFocus = ptiFrom->MessageQueue->spwndFocus;
581 }
582
583 CurIcon = ptiFrom->MessageQueue->CursorObject;
584
585 MsqDestroyMessageQueue(ptiFrom);
586
587 if (CurIcon)
588 {
589 // Could be global. Keep it above the water line!
590 UserReferenceObject(CurIcon);
591 }
592
593 if (CurIcon && UserObjectInDestroy(UserHMGetHandle(CurIcon)))
594 {
595 UserDereferenceObject(CurIcon);
596 CurIcon = NULL;
597 }
598
599 ptiFrom->MessageQueue = ptiTo->MessageQueue;
600
601 // Pass cursor From if To is null. Pass test_SetCursor parent_id == current pti ID.
602 if (CurIcon && ptiTo->MessageQueue->CursorObject == NULL)
603 {
604 ERR("ptiTo receiving ptiFrom Cursor\n");
605 ptiTo->MessageQueue->CursorObject = CurIcon;
606 }
607
608 ptiFrom->MessageQueue->cThreads++;
609 ERR("ptiTo S Share count %u\n", ptiFrom->MessageQueue->cThreads);
610
612 }
613 else
614 {
615 ERR("Attach Threads are already associated!\n");
616 }
617 }
618 else /* If clear, unlink and free it. */
619 {
620 BOOL Hit = FALSE;
621 PATTACHINFO *ppai;
622
623 if (!gpai) return STATUS_INVALID_PARAMETER;
624
625 /* Search list and free if found or return false. */
626 ppai = &gpai;
627 while (*ppai != NULL)
628 {
629 if ( (*ppai)->pti2 == ptiTo && (*ppai)->pti1 == ptiFrom )
630 {
631 pai = *ppai;
632 /* Remove it from the list */
633 *ppai = (*ppai)->paiNext;
635 paiCount--;
636 Hit = TRUE;
637 break;
638 }
639 ppai = &((*ppai)->paiNext);
640 }
641
642 if (!Hit) return STATUS_INVALID_PARAMETER;
643
644 ERR("Attach Free! ptiFrom 0x%p ptiTo 0x%p paiCount %d\n",ptiFrom,ptiTo,paiCount);
645
646 if (ptiTo->MessageQueue == ptiFrom->MessageQueue)
647 {
648 PWND spwndActive = ptiTo->MessageQueue->spwndActive;
649 PWND spwndFocus = ptiTo->MessageQueue->spwndFocus;
650
651 if (gptiForeground == ptiFrom)
652 {
653 ERR("ptiTo is now pti FG.\n");
654 // MessageQueue foreground is set so switch threads.
655 gptiForeground = ptiTo;
656 }
657 ptiTo->MessageQueue->cThreads--;
658 ERR("ptiTo E Share count %u\n", ptiTo->MessageQueue->cThreads);
659 ASSERT(ptiTo->MessageQueue->cThreads >= 1);
660
662
663 ptiFrom->MessageQueue = MsqCreateMessageQueue(ptiFrom);
664
665 if (spwndActive)
666 {
667 if (spwndActive->head.pti == ptiFrom)
668 {
669 ptiFrom->MessageQueue->spwndActive = spwndActive;
670 ptiTo->MessageQueue->spwndActive = 0;
671 }
672 }
673 if (spwndFocus)
674 {
675 if (spwndFocus->head.pti == ptiFrom)
676 {
677 ptiFrom->MessageQueue->spwndFocus = spwndFocus;
678 ptiTo->MessageQueue->spwndFocus = 0;
679 }
680 }
681 ptiTo->MessageQueue->iCursorLevel -= ptiFrom->iCursorLevel;
682 }
683 else
684 {
685 ERR("Detaching Threads are not associated!\n");
686 }
687 }
688 /* Note that key state, which can be ascertained by calls to the GetKeyState
689 or GetKeyboardState function, is reset after a call to AttachThreadInput.
690 ATM which one?
691 */
692 RtlCopyMemory(ptiTo->MessageQueue->afKeyState, gafAsyncKeyState, sizeof(gafAsyncKeyState));
693
694 ptiTo->MessageQueue->msgDblClk.message = 0;
695
696 /* Generate mouse move message */
697 msg.message = WM_MOUSEMOVE;
698 msg.wParam = UserGetMouseButtonsState();
699 msg.lParam = MAKELPARAM(gpsi->ptCursor.x, gpsi->ptCursor.y);
700 msg.pt = gpsi->ptCursor;
702
703 return STATUS_SUCCESS;
704}
#define msg(x)
Definition: auth_time.c:54
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
PTHREADINFO gptiForeground
Definition: focus.c:15
#define PagedPool
Definition: env_spec_w32.h:308
PUSER_MESSAGE_QUEUE gpqForeground
Definition: focus.c:13
#define TIF_DONTATTACHQUEUE
Definition: ntuser.h:272
#define UserHMGetHandle(obj)
Definition: ntuser.h:233
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:2434
PUSER_MESSAGE_QUEUE FASTCALL MsqCreateMessageQueue(PTHREADINFO pti)
Definition: msgqueue.c:2407
#define QF_CAPTURELOCKED
Definition: msgqueue.h:114
#define IntReferenceMessageQueue(MsgQueue)
Definition: msgqueue.h:220
#define IntDereferenceMessageQueue(MsgQueue)
Definition: msgqueue.h:223
#define MAKELPARAM(l, h)
Definition: winuser.h:4116
#define WM_MOUSEMOVE
Definition: winuser.h:1803
INT iCursorLevel
Definition: win32.h:128
struct _USER_MESSAGE_QUEUE * MessageQueue
Definition: win32.h:90
Definition: ntuser.h:698
THRDESKHEAD head
Definition: ntuser.h:699
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:1347
INT paiCount
Definition: input.c:25
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:647
BOOL FASTCALL UserObjectInDestroy(HANDLE h)
Definition: object.c:707
VOID FASTCALL UserReferenceObject(PVOID obj)
Definition: object.c:754
#define USERTAG_ATTACHINFO
Definition: tags.h:197

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

Variable Documentation

◆ ghKeyboardDevice

HANDLE ghKeyboardDevice = NULL

Definition at line 26 of file input.c.

Referenced by ProcessKeyEvent(), and RawInputThreadMain().

◆ ghMouseDevice

HANDLE ghMouseDevice
static

Definition at line 31 of file input.c.

Referenced by RawInputThreadMain().

◆ gpai

PATTACHINFO gpai = NULL

Definition at line 24 of file input.c.

Referenced by IsRemoveAttachThread(), and UserAttachThreadInput().

◆ gpDeviceInfoListMutex

PERESOURCE gpDeviceInfoListMutex = NULL

◆ gpInputDeviceInfo

PINPUT_DEVICE_INFO gpInputDeviceInfo = NULL

◆ LastInputTick

DWORD LastInputTick = 0
static

Definition at line 30 of file input.c.

Referenced by DoTheScreenSaver(), and IntLastInputTick().

◆ MasterTimer

PKTIMER MasterTimer = NULL

Definition at line 23 of file input.c.

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

◆ paiCount

INT paiCount = 0

Definition at line 25 of file input.c.

Referenced by UserAttachThreadInput().

◆ ptiRawInput

PTHREADINFO ptiRawInput

Definition at line 22 of file input.c.

Referenced by IntSetTimer(), and RawInputThreadMain().