ReactOS 0.4.17-dev-116-ga4b6fe9
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
 
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 64 of file input.c.

65{
66 DWORD Test, TO;
67
68 if (gspv.iScrSaverTimeout > 0) // Zero means Off.
69 {
72 TO = 1000 * gspv.iScrSaverTimeout;
73 if (Test > TO)
74 {
75 TRACE("Screensaver Message Start! Tick %lu Timeout %d \n", Test, gspv.iScrSaverTimeout);
76
77 if (ppiScrnSaver) // We are or we are not the screensaver, prevent reentry...
78 {
79 if (!(ppiScrnSaver->W32PF_flags & W32PF_IDLESCREENSAVER))
80 {
81 ppiScrnSaver->W32PF_flags |= W32PF_IDLESCREENSAVER;
82 ERR("Screensaver is Idle\n");
83 }
84 }
85 else
86 {
88 if (ForegroundQueue && ForegroundQueue->spwndActive)
90 else
92 }
93 }
94 }
95}
#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:1324
static DWORD LastInputTick
Definition: input.c:28
PPROCESSINFO ppiScrnSaver
Definition: main.c:30
BOOL FASTCALL UserPostMessage(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: message.c:1395
SPIVALUES gspv
Definition: sysparams.c:17

Referenced by HungAppSysTimerProc().

◆ InitInputImpl()

NTSTATUS NTAPI InitInputImpl ( VOID  )

Definition at line 376 of file input.c.

377{
379 if (!MasterTimer)
380 {
381 ERR("Failed to allocate memory\n");
382 ASSERT(FALSE);
383 return STATUS_UNSUCCESSFUL;
384 }
386
387 return STATUS_SUCCESS;
388}
#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 391 of file input.c.

392{
393 PTHREADINFO OldBlock;
394 ASSERT(pti);
395
396 if(!pti->rpdesk || ((pti->TIF_flags & TIF_INCLEANUP) && BlockIt))
397 {
398 /*
399 * Fail blocking if exiting the thread
400 */
401
402 return FALSE;
403 }
404
405 /*
406 * FIXME: Check access rights of the window station
407 * e.g. services running in the service window station cannot block input
408 */
409 if(!ThreadHasInputAccess(pti) ||
411 {
413 return FALSE;
414 }
415
416 ASSERT(pti->rpdesk);
417 OldBlock = pti->rpdesk->BlockInputThread;
418 if(OldBlock)
419 {
420 if(OldBlock != pti)
421 {
423 return FALSE;
424 }
425 pti->rpdesk->BlockInputThread = (BlockIt ? pti : NULL);
426 return OldBlock == NULL;
427 }
428
429 pti->rpdesk->BlockInputThread = (BlockIt ? pti : NULL);
430 return OldBlock == NULL;
431}
#define IntIsActiveDesktop(Desktop)
Definition: desktop.h:172
#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 ThreadHasInputAccess(W32Thread)
Definition: input.h:65
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 39 of file input.c.

40{
41 if (bUpdate)
42 {
44 if (gpsi)
45 {
46 gpsi->dwLastRITEventTickCount = LastInputTick;
47 if (gpsi->dwLastRITEventTickCount - gpsi->dwLastSystemRITEventTickCountUpdate >
49 {
50 SharedUserData->LastSystemRITEventTickCount = LastInputTick;
51 gpsi->dwLastSystemRITEventTickCountUpdate = LastInputTick;
52 }
53 }
54 }
55 return LastInputTick;
56}
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 453 of file input.c.

454{
456 PATTACHINFO pai;
457 BOOL Ret = TRUE;
458 PTHREADINFO ptiFrom = NULL, ptiTo = NULL;
459
460 do
461 {
462 if (!gpai) return TRUE;
463
464 pai = gpai; // Bottom of the list.
465
466 do
467 {
468 if (pai->pti2 == pti)
469 {
470 ptiFrom = pai->pti1;
471 ptiTo = pti;
472 break;
473 }
474 if (pai->pti1 == pti)
475 {
476 ptiFrom = pti;
477 ptiTo = pai->pti2;
478 break;
479 }
480 pai = pai->paiNext;
481
482 } while (pai);
483
484 if (!pai && !ptiFrom && !ptiTo) break;
485
486 Status = UserAttachThreadInput(ptiFrom, ptiTo, FALSE);
487 if (!NT_SUCCESS(Status)) Ret = FALSE;
488
489 } while (Ret);
490
491 return Ret;
492}
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: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:24
NTSTATUS FASTCALL UserAttachThreadInput(PTHREADINFO ptiFrom, PTHREADINFO ptiTo, BOOL fAttach)
Definition: input.c:495

Referenced by ExitThreadCallback().

◆ NtUserAttachThreadInput()

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

Definition at line 680 of file input.c.

684{
686 PTHREADINFO pti, ptiTo;
687 BOOL Ret = FALSE;
688
690 TRACE("Enter NtUserAttachThreadInput %s\n",(fAttach ? "TRUE" : "FALSE" ));
691
692 pti = IntTID2PTI(UlongToHandle(idAttach));
693 ptiTo = IntTID2PTI(UlongToHandle(idAttachTo));
694
695 if ( !pti || !ptiTo )
696 {
697 TRACE("AttachThreadInput pti or ptiTo NULL.\n");
699 goto Exit;
700 }
701
702 Status = UserAttachThreadInput( pti, ptiTo, fAttach);
703 if (!NT_SUCCESS(Status))
704 {
705 TRACE("AttachThreadInput Error Status 0x%x. \n",Status);
707 }
708 else Ret = TRUE;
709
710Exit:
711 TRACE("Leave NtUserAttachThreadInput, ret=%d\n",Ret);
712 UserLeave();
713 return Ret;
714}
#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 435 of file input.c.

437{
438 BOOL ret;
439
440 TRACE("Enter NtUserBlockInput\n");
442
444
445 UserLeave();
446 TRACE("Leave NtUserBlockInput, ret=%i\n", ret);
447
448 return ret;
449}
return ret
Definition: mutex.c:146
PVOID NTAPI PsGetCurrentThreadWin32Thread(VOID)
Definition: thread.c:805
BOOL FASTCALL IntBlockInput(PTHREADINFO pti, BOOL BlockIt)
Definition: input.c:391

Referenced by BlockInput().

◆ NtUserSendInput()

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

Definition at line 723 of file input.c.

727{
728 PTHREADINFO pti;
729 UINT uRet = 0;
730
731 TRACE("Enter NtUserSendInput\n");
733
735 ASSERT(pti);
736
737 if (!pti->rpdesk)
738 {
739 goto cleanup;
740 }
741
742 if (!nInputs || !pInput || cbSize != sizeof(INPUT))
743 {
745 goto cleanup;
746 }
747
748 /*
749 * FIXME: Check access rights of the window station
750 * e.g. services running in the service window station cannot block input
751 */
752 if (!ThreadHasInputAccess(pti) ||
754 {
756 goto cleanup;
757 }
758
759 while (nInputs--)
760 {
761 INPUT SafeInput;
763
764 Status = MmCopyFromCaller(&SafeInput, pInput++, sizeof(INPUT));
765 if (!NT_SUCCESS(Status))
766 {
768 goto cleanup;
769 }
770
771 switch (SafeInput.type)
772 {
773 case INPUT_MOUSE:
774 if (UserSendMouseInput(&SafeInput.mi, TRUE))
775 uRet++;
776 break;
777 case INPUT_KEYBOARD:
778 if (UserSendKeyboardInput(&SafeInput.ki, TRUE))
779 uRet++;
780 break;
781 case INPUT_HARDWARE:
782 FIXME("INPUT_HARDWARE not supported!\n");
783 break;
784 default:
785 ERR("SendInput(): Invalid input type: 0x%x\n", SafeInput.type);
786 break;
787 }
788 }
789
790cleanup:
791 TRACE("Leave NtUserSendInput, ret=%u\n", uRet);
792 UserLeave();
793 return uRet;
794}
#define FIXME(fmt,...)
Definition: precomp.h:53
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:30
BOOL NTAPI UserSendKeyboardInput(KEYBDINPUT *pKbdInput, BOOL bInjected)
Definition: keyboard.c:1333
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 104 of file input.c.

105{
110
111 RtlInitUnicodeString(&DeviceName, pszDeviceName);
112
114 &DeviceName,
116 NULL,
117 NULL);
118
119 Status = ZwOpenFile(pHandle,
122 &Iosb,
123 0,
124 0);
125 if (NT_SUCCESS(Status) && ppObject)
126 {
129 }
130
131 return Status;
132}
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:494
#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 140 of file input.c.

141{
142 NTSTATUS MouStatus = STATUS_UNSUCCESSFUL, KbdStatus = STATUS_UNSUCCESSFUL, Status;
143 IO_STATUS_BLOCK MouIosb, KbdIosb;
144 PFILE_OBJECT pKbdDevice = NULL, pMouDevice = NULL;
146 //LARGE_INTEGER WaitTimeout;
147 PVOID WaitObjects[4], pSignaledObject = NULL;
149 ULONG cWaitObjects = 0, cMaxWaitObjects = 2;
150 MOUSE_INPUT_DATA MouseInput;
151 KEYBOARD_INPUT_DATA KeyInput;
153 HWINSTA hWinSta;
154
155 ByteOffset.QuadPart = (LONGLONG)0;
156 //WaitTimeout.QuadPart = (LONGLONG)(-10000000);
157
161
162 TRACE("Raw Input Thread %p\n", ptiRawInput);
163
166
168 0,
169 NULL,
172 UserMode,
173 (PHANDLE)&hWinSta);
174 if (NT_SUCCESS(Status))
175 {
177 }
178 else
179 {
180 ASSERT(FALSE);
181 /* Failed to open the interactive winsta! What now? */
182 }
183
186 UserLeave();
187
190
192 for (;;)
193 {
194 if (!ghMouseDevice)
195 {
196 /* Check if mouse device already exists */
197 Status = OpenInputDevice(&ghMouseDevice, &pMouDevice, L"\\Device\\PointerClass0" );
198 if (NT_SUCCESS(Status))
199 {
200 ++cMaxWaitObjects;
201 TRACE("Mouse connected!\n");
202 }
203 }
204 if (!ghKeyboardDevice)
205 {
206 /* Check if keyboard device already exists */
207 Status = OpenInputDevice(&ghKeyboardDevice, &pKbdDevice, L"\\Device\\KeyboardClass0");
208 if (NT_SUCCESS(Status))
209 {
210 ++cMaxWaitObjects;
211 TRACE("Keyboard connected!\n");
212 // Get and load keyboard attributes.
215 // Register the Window hotkey.
217 // Register the Window Snap hotkey.
222 // Register the debug hotkeys.
224 UserLeave();
225 }
226 }
227
228 /* Reset WaitHandles array */
229 cWaitObjects = 0;
230 WaitObjects[cWaitObjects++] = ShutdownEvent;
231 WaitObjects[cWaitObjects++] = MasterTimer;
232
233 if (ghMouseDevice)
234 {
235 /* Try to read from mouse if previous reading is not pending */
236 if (MouStatus != STATUS_PENDING)
237 {
238 MouStatus = ZwReadFile(ghMouseDevice,
239 NULL,
240 NULL,
241 NULL,
242 &MouIosb,
243 &MouseInput,
244 sizeof(MOUSE_INPUT_DATA),
245 &ByteOffset,
246 NULL);
247 }
248
249 if (MouStatus == STATUS_PENDING)
250 WaitObjects[cWaitObjects++] = &pMouDevice->Event;
251 }
252
254 {
255 /* Try to read from keyboard if previous reading is not pending */
256 if (KbdStatus != STATUS_PENDING)
257 {
258 KbdStatus = ZwReadFile(ghKeyboardDevice,
259 NULL,
260 NULL,
261 NULL,
262 &KbdIosb,
263 &KeyInput,
264 sizeof(KEYBOARD_INPUT_DATA),
265 &ByteOffset,
266 NULL);
267
268 }
269 if (KbdStatus == STATUS_PENDING)
270 WaitObjects[cWaitObjects++] = &pKbdDevice->Event;
271 }
272
273 /* If all objects are pending, wait for them */
274 if (cWaitObjects == cMaxWaitObjects)
275 {
276 Status = KeWaitForMultipleObjects(cWaitObjects,
277 WaitObjects,
278 WaitAny,
281 TRUE,
282 NULL,//&WaitTimeout,
284
285 if ((Status >= STATUS_WAIT_0) &&
286 (Status < (STATUS_WAIT_0 + (LONG)cWaitObjects)))
287 {
288 /* Some device has finished reading */
289 pSignaledObject = WaitObjects[Status - STATUS_WAIT_0];
290
291 /* Check if it is mouse or keyboard and update status */
292 if ((MouStatus == STATUS_PENDING) &&
293 (pSignaledObject == &pMouDevice->Event))
294 {
295 MouStatus = MouIosb.Status;
296 }
297 else if ((KbdStatus == STATUS_PENDING) &&
298 (pSignaledObject == &pKbdDevice->Event))
299 {
300 KbdStatus = KbdIosb.Status;
301 }
302 else if (pSignaledObject == MasterTimer)
303 {
305 }
306 else if (pSignaledObject == ShutdownEvent)
307 {
308 break;
309 }
310 else ASSERT(FALSE);
311 }
312 }
313
314 /* Have we successed reading from mouse? */
315 if (NT_SUCCESS(MouStatus) && MouStatus != STATUS_PENDING)
316 {
317 TRACE("MouseEvent\n");
318
319 /* Set LastInputTick */
321
322 /* Process data */
324 UserProcessMouseInput(&MouseInput);
325 UserLeave();
326 }
327 else if (MouStatus != STATUS_PENDING)
328 ERR("Failed to read from mouse: %x.\n", MouStatus);
329
330 /* Have we successed reading from keyboard? */
331 if (NT_SUCCESS(KbdStatus) && KbdStatus != STATUS_PENDING)
332 {
333 TRACE("KeyboardEvent: %s %04x\n",
334 (KeyInput.Flags & KEY_BREAK) ? "up" : "down",
335 KeyInput.MakeCode);
336
337 /* Set LastInputTick */
339
340 /* Process data */
342 UserProcessKeyboardInput(&KeyInput);
343 UserLeave();
344 }
345 else if (KbdStatus != STATUS_PENDING)
346 ERR("Failed to read from keyboard: %x.\n", KbdStatus);
347 }
348
349 if (ghMouseDevice)
350 {
353 ObDereferenceObject(pMouDevice);
355 }
356
358 {
361 ObDereferenceObject(pKbdDevice);
363 }
364
365 ERR("Raw Input Thread Exit!\n");
366}
#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
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
#define PWND_BOTTOM
Definition: ntuser.h:769
struct _THREADINFO * GetW32ThreadInfo(VOID)
Definition: misc.c:806
#define TIF_SYSTEMTHREAD
Definition: ntuser.h:265
#define LOW_REALTIME_PRIORITY
#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:586
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:1392
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
#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
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:104
static HANDLE ghMouseDevice
Definition: input.c:29
HANDLE ghKeyboardDevice
Definition: input.c:26
PTHREADINFO ptiRawInput
Definition: input.c:22
static DWORD FASTCALL IntLastInputTick(BOOL bUpdate)
Definition: input.c:39
VOID NTAPI UserProcessKeyboardInput(PKEYBOARD_INPUT_DATA pKeyInput)
Definition: keyboard.c:1414
VOID NTAPI UserProcessMouseInput(PMOUSE_INPUT_DATA pMouseInputData)
Definition: mouse.c:40
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
#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
* PFILE_OBJECT
Definition: iotypes.h:1998
@ UserRequest
Definition: ketypes.h:473
#define ObDereferenceObject
Definition: obfuncs.h:203
#define NT_ASSERT
Definition: rtlfuncs.h:3327

Referenced by UserSystemThreadProc().

◆ UserAttachThreadInput()

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

Definition at line 495 of file input.c.

496{
497 MSG msg;
498 PATTACHINFO pai;
499 PCURICON_OBJECT CurIcon;
500
501 /* Can not be the same thread. */
502 if (ptiFrom == ptiTo) return STATUS_INVALID_PARAMETER;
503
504 /* Do not attach to system threads or between different desktops. */
505 if (ptiFrom->TIF_flags & TIF_DONTATTACHQUEUE ||
507 ptiFrom->rpdesk != ptiTo->rpdesk)
509
510 /* MSDN Note:
511 Keyboard and mouse events received by both threads are processed by the thread specified by the idAttachTo.
512 */
513
514 /* If Attach set, allocate and link. */
515 if (fAttach)
516 {
518 if (!pai) return STATUS_NO_MEMORY;
519
520 pai->paiNext = gpai;
521 pai->pti1 = ptiFrom;
522 pai->pti2 = ptiTo;
523 gpai = pai;
524 paiCount++;
525 ERR("Attach Allocated! ptiFrom 0x%p ptiTo 0x%p paiCount %d\n",ptiFrom,ptiTo,paiCount);
526
527 if (ptiTo->MessageQueue != ptiFrom->MessageQueue)
528 {
529
530 ptiTo->MessageQueue->iCursorLevel -= ptiFrom->iCursorLevel;
531
532 if (ptiFrom->MessageQueue == gpqForeground)
533 {
534 ERR("ptiFrom is Foreground\n");
535 ptiTo->MessageQueue->spwndActive = ptiFrom->MessageQueue->spwndActive;
536 ptiTo->MessageQueue->spwndFocus = ptiFrom->MessageQueue->spwndFocus;
537 ptiTo->MessageQueue->spwndCapture = ptiFrom->MessageQueue->spwndCapture;
538 ptiTo->MessageQueue->QF_flags ^= ((ptiTo->MessageQueue->QF_flags ^ ptiFrom->MessageQueue->QF_flags) & QF_CAPTURELOCKED);
539 RtlCopyMemory(&ptiTo->MessageQueue->CaretInfo,
540 &ptiFrom->MessageQueue->CaretInfo,
541 sizeof(ptiTo->MessageQueue->CaretInfo));
544 gptiForeground = ptiTo;
545 }
546 else
547 {
548 ERR("ptiFrom NOT Foreground\n");
549 if ( ptiTo->MessageQueue->spwndActive == 0 )
550 ptiTo->MessageQueue->spwndActive = ptiFrom->MessageQueue->spwndActive;
551 if ( ptiTo->MessageQueue->spwndFocus == 0 )
552 ptiTo->MessageQueue->spwndFocus = ptiFrom->MessageQueue->spwndFocus;
553 }
554
555 CurIcon = ptiFrom->MessageQueue->CursorObject;
556
557 MsqDestroyMessageQueue(ptiFrom);
558
559 if (CurIcon)
560 {
561 // Could be global. Keep it above the water line!
562 UserReferenceObject(CurIcon);
563 }
564
565 if (CurIcon && UserObjectInDestroy(UserHMGetHandle(CurIcon)))
566 {
567 UserDereferenceObject(CurIcon);
568 CurIcon = NULL;
569 }
570
571 ptiFrom->MessageQueue = ptiTo->MessageQueue;
572
573 // Pass cursor From if To is null. Pass test_SetCursor parent_id == current pti ID.
574 if (CurIcon && ptiTo->MessageQueue->CursorObject == NULL)
575 {
576 ERR("ptiTo receiving ptiFrom Cursor\n");
577 ptiTo->MessageQueue->CursorObject = CurIcon;
578 }
579
580 ptiFrom->MessageQueue->cThreads++;
581 ERR("ptiTo S Share count %u\n", ptiFrom->MessageQueue->cThreads);
582
584 }
585 else
586 {
587 ERR("Attach Threads are already associated!\n");
588 }
589 }
590 else /* If clear, unlink and free it. */
591 {
592 BOOL Hit = FALSE;
593 PATTACHINFO *ppai;
594
595 if (!gpai) return STATUS_INVALID_PARAMETER;
596
597 /* Search list and free if found or return false. */
598 ppai = &gpai;
599 while (*ppai != NULL)
600 {
601 if ( (*ppai)->pti2 == ptiTo && (*ppai)->pti1 == ptiFrom )
602 {
603 pai = *ppai;
604 /* Remove it from the list */
605 *ppai = (*ppai)->paiNext;
607 paiCount--;
608 Hit = TRUE;
609 break;
610 }
611 ppai = &((*ppai)->paiNext);
612 }
613
614 if (!Hit) return STATUS_INVALID_PARAMETER;
615
616 ERR("Attach Free! ptiFrom 0x%p ptiTo 0x%p paiCount %d\n",ptiFrom,ptiTo,paiCount);
617
618 if (ptiTo->MessageQueue == ptiFrom->MessageQueue)
619 {
620 PWND spwndActive = ptiTo->MessageQueue->spwndActive;
621 PWND spwndFocus = ptiTo->MessageQueue->spwndFocus;
622
623 if (gptiForeground == ptiFrom)
624 {
625 ERR("ptiTo is now pti FG.\n");
626 // MessageQueue foreground is set so switch threads.
627 gptiForeground = ptiTo;
628 }
629 ptiTo->MessageQueue->cThreads--;
630 ERR("ptiTo E Share count %u\n", ptiTo->MessageQueue->cThreads);
631 ASSERT(ptiTo->MessageQueue->cThreads >= 1);
632
634
635 ptiFrom->MessageQueue = MsqCreateMessageQueue(ptiFrom);
636
637 if (spwndActive)
638 {
639 if (spwndActive->head.pti == ptiFrom)
640 {
641 ptiFrom->MessageQueue->spwndActive = spwndActive;
642 ptiTo->MessageQueue->spwndActive = 0;
643 }
644 }
645 if (spwndFocus)
646 {
647 if (spwndFocus->head.pti == ptiFrom)
648 {
649 ptiFrom->MessageQueue->spwndFocus = spwndFocus;
650 ptiTo->MessageQueue->spwndFocus = 0;
651 }
652 }
653 ptiTo->MessageQueue->iCursorLevel -= ptiFrom->iCursorLevel;
654 }
655 else
656 {
657 ERR("Detaching Threads are not associated!\n");
658 }
659 }
660 /* Note that key state, which can be ascertained by calls to the GetKeyState
661 or GetKeyboardState function, is reset after a call to AttachThreadInput.
662 ATM which one?
663 */
664 RtlCopyMemory(ptiTo->MessageQueue->afKeyState, gafAsyncKeyState, sizeof(gafAsyncKeyState));
665
666 ptiTo->MessageQueue->msgDblClk.message = 0;
667
668 /* Generate mouse move message */
669 msg.message = WM_MOUSEMOVE;
670 msg.wParam = UserGetMouseButtonsState();
671 msg.lParam = MAKELPARAM(gpsi->ptCursor.x, gpsi->ptCursor.y);
672 msg.pt = gpsi->ptCursor;
674
675 return STATUS_SUCCESS;
676}
#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: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:2423
PUSER_MESSAGE_QUEUE FASTCALL MsqCreateMessageQueue(PTHREADINFO pti)
Definition: msgqueue.c:2396
#define QF_CAPTURELOCKED
Definition: msgqueue.h:111
#define IntReferenceMessageQueue(MsgQueue)
Definition: msgqueue.h:217
#define IntDereferenceMessageQueue(MsgQueue)
Definition: msgqueue.h:220
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:1336
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:643
BOOL FASTCALL UserObjectInDestroy(HANDLE h)
Definition: object.c:702
VOID FASTCALL UserReferenceObject(PVOID obj)
Definition: object.c:730
#define USERTAG_ATTACHINFO
Definition: tags.h:197
#define MAKELPARAM(l, h)
Definition: winuser.h:4116
#define WM_MOUSEMOVE
Definition: winuser.h:1803

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 29 of file input.c.

Referenced by RawInputThreadMain().

◆ gpai

PATTACHINFO gpai = NULL

Definition at line 24 of file input.c.

Referenced by IsRemoveAttachThread(), and UserAttachThreadInput().

◆ LastInputTick

DWORD LastInputTick = 0
static

Definition at line 28 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().