ReactOS  r76032
msgqueue.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS Win32k subsystem
4  * PURPOSE: Message queues
5  * FILE: win32ss/user/ntuser/msgqueue.c
6  * PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
7  Alexandre Julliard
8  Maarten Lankhorst
9  */
10 
11 #include <win32k.h>
12 DBG_DEFAULT_CHANNEL(UserMsgQ);
13 
14 /* GLOBALS *******************************************************************/
15 
24 
25 /* FUNCTIONS *****************************************************************/
26 
29 NTAPI
31 {
32  // Setup Post Messages
35  return STATUS_NO_MEMORY;
37  NULL,
38  NULL,
39  0,
40  sizeof(USER_MESSAGE),
41  TAG_USRMSG,
42  256);
43  // Setup Send Messages
46  return STATUS_NO_MEMORY;
48  NULL,
49  NULL,
50  0,
51  sizeof(USER_SENT_MESSAGE),
52  TAG_USRMSG,
53  16);
54 
55  InitializeListHead(&usmList);
56 
57  return(STATUS_SUCCESS);
58 }
59 
62 {
63  PWND pWnd, pwndDesktop;
64 
65  /* Get the desktop window */
66  pwndDesktop = UserGetDesktopWindow();
67  if (!pwndDesktop)
68  return NULL;
69 
70  /* Loop all top level windows */
71  for (pWnd = pwndDesktop->spwndChild;
72  pWnd != NULL;
73  pWnd = pWnd->spwndNext)
74  {
75  if (pWnd->state2 & WNDS2_INDESTROY || pWnd->state & WNDS_DESTROYED)
76  {
77  TRACE("The Window is in DESTROY!\n");
78  continue;
79  }
80 
81  if ((pWnd->style & WS_VISIBLE) &&
83  IntPtInWindow(pWnd, x, y))
84  return pWnd;
85  }
86 
87  /* Window has not been found */
88  return pwndDesktop;
89 }
90 
94  PCURICON_OBJECT NewCursor,
95  BOOL ForceChange)
96 {
97  PCURICON_OBJECT OldCursor;
98  HDC hdcScreen;
99  PTHREADINFO pti;
100  PUSER_MESSAGE_QUEUE MessageQueue;
101  PWND pWnd;
102 
104  MessageQueue = pti->MessageQueue;
105 
106  OldCursor = MessageQueue->CursorObject;
107 
108  /* Check if cursors are different */
109  if (OldCursor == NewCursor)
110  return OldCursor;
111 
112  /* Update cursor for this message queue */
113  MessageQueue->CursorObject = NewCursor;
114 
115  /* If cursor is not visible we have nothing to do */
116  if (MessageQueue->iCursorLevel < 0)
117  return OldCursor;
118 
119  // Fixes the error message "Not the same cursor!".
120  if (gpqCursor == NULL)
121  {
122  gpqCursor = MessageQueue;
123  }
124 
125  /* Update cursor if this message queue controls it */
126  pWnd = IntTopLevelWindowFromPoint(gpsi->ptCursor.x, gpsi->ptCursor.y);
127  if (pWnd && pWnd->head.pti->MessageQueue == MessageQueue)
128  {
129  /* Get the screen DC */
130  if (!(hdcScreen = IntGetScreenDC()))
131  {
132  return NULL;
133  }
134 
135  if (NewCursor)
136  {
137  /* Call GDI to set the new screen cursor */
138  PCURICON_OBJECT CursorFrame = NewCursor;
139  if(NewCursor->CURSORF_flags & CURSORF_ACON)
140  {
141  FIXME("Should animate the cursor, using only the first frame now.\n");
142  CursorFrame = ((PACON)NewCursor)->aspcur[0];
143  }
144  GreSetPointerShape(hdcScreen,
145  CursorFrame->hbmAlpha ? NULL : NewCursor->hbmMask,
146  CursorFrame->hbmAlpha ? NewCursor->hbmAlpha : NewCursor->hbmColor,
147  CursorFrame->xHotspot,
148  CursorFrame->yHotspot,
149  gpsi->ptCursor.x,
150  gpsi->ptCursor.y,
151  CursorFrame->hbmAlpha ? SPS_ALPHA : 0);
152  }
153  else /* Note: OldCursor != NewCursor so we have to hide cursor */
154  {
155  /* Remove the cursor */
156  GreMovePointer(hdcScreen, -1, -1);
157  TRACE("Removing pointer!\n");
158  }
160  }
161 
162  /* Return the old cursor */
163  return OldCursor;
164 }
165 
166 /* Called from NtUserCallOneParam with Routine ONEPARAM_ROUTINE_SHOWCURSOR
167  * User32 macro NtUserShowCursor */
169 {
170  HDC hdcScreen;
171  PTHREADINFO pti;
172  PUSER_MESSAGE_QUEUE MessageQueue;
173  PWND pWnd;
174 
175  if (!(hdcScreen = IntGetScreenDC()))
176  {
177  return -1; /* No mouse */
178  }
179 
181  MessageQueue = pti->MessageQueue;
182 
183  /* Update counter */
184  MessageQueue->iCursorLevel += bShow ? 1 : -1;
185  pti->iCursorLevel += bShow ? 1 : -1;
186 
187  /* Check for trivial cases */
188  if ((bShow && MessageQueue->iCursorLevel != 0) ||
189  (!bShow && MessageQueue->iCursorLevel != -1))
190  {
191  /* Note: w don't update global info here because it is used only
192  internally to check if cursor is visible */
193  return MessageQueue->iCursorLevel;
194  }
195 
196  /* Check if cursor is above window owned by this MessageQueue */
197  pWnd = IntTopLevelWindowFromPoint(gpsi->ptCursor.x, gpsi->ptCursor.y);
198  if (pWnd && pWnd->head.pti->MessageQueue == MessageQueue)
199  {
200  if (bShow)
201  {
202  /* Show the pointer */
203  GreMovePointer(hdcScreen, gpsi->ptCursor.x, gpsi->ptCursor.y);
204  TRACE("Showing pointer!\n");
205  }
206  else
207  {
208  /* Remove the pointer */
209  GreMovePointer(hdcScreen, -1, -1);
210  TRACE("Removing pointer!\n");
211  }
212 
213  /* Update global info */
215  }
216 
217  return MessageQueue->iCursorLevel;
218 }
219 
222 {
223  DWORD dwRet = 0;
224  PTHREADINFO pti;
225  PUSER_MESSAGE_QUEUE MessageQueue;
226 
228  MessageQueue = pti->MessageQueue;
229 
230  if (dwKey < 0x100)
231  {
232  if (IS_KEY_DOWN(MessageQueue->afKeyState, dwKey))
233  dwRet |= 0xFF80; // If down, windows returns 0xFF80.
234  if (IS_KEY_LOCKED(MessageQueue->afKeyState, dwKey))
235  dwRet |= 0x1;
236  }
237  else
238  {
240  }
241  return dwRet;
242 }
243 
244 /* change the input key state for a given key */
245 static VOID
246 UpdateKeyState(PUSER_MESSAGE_QUEUE MessageQueue, WORD wVk, BOOL bIsDown)
247 {
248  TRACE("UpdateKeyState wVk: %u, bIsDown: %d\n", wVk, bIsDown);
249 
250  if (bIsDown)
251  {
252  /* If it's first key down event, xor lock bit */
253  if (!IS_KEY_DOWN(MessageQueue->afKeyState, wVk))
254  SET_KEY_LOCKED(MessageQueue->afKeyState, wVk, !IS_KEY_LOCKED(MessageQueue->afKeyState, wVk));
255 
256  SET_KEY_DOWN(MessageQueue->afKeyState, wVk, TRUE);
257  MessageQueue->afKeyRecentDown[wVk / 8] |= (1 << (wVk % 8));
258  }
259  else
260  SET_KEY_DOWN(MessageQueue->afKeyState, wVk, FALSE);
261 }
262 
263 /* update the input key state for a keyboard message */
264 static VOID
266 {
267  UCHAR key;
268  BOOL down = FALSE;
269 
270  TRACE("UpdateKeyStateFromMsg message:%u\n", msg->message);
271 
272  switch (msg->message)
273  {
274  case WM_LBUTTONDOWN:
275  down = TRUE;
276  /* fall through */
277  case WM_LBUTTONUP:
278  UpdateKeyState(MessageQueue, VK_LBUTTON, down);
279  break;
280  case WM_MBUTTONDOWN:
281  down = TRUE;
282  /* fall through */
283  case WM_MBUTTONUP:
284  UpdateKeyState(MessageQueue, VK_MBUTTON, down);
285  break;
286  case WM_RBUTTONDOWN:
287  down = TRUE;
288  /* fall through */
289  case WM_RBUTTONUP:
290  UpdateKeyState(MessageQueue, VK_RBUTTON, down);
291  break;
292  case WM_XBUTTONDOWN:
293  down = TRUE;
294  /* fall through */
295  case WM_XBUTTONUP:
296  if (msg->wParam == XBUTTON1)
297  UpdateKeyState(MessageQueue, VK_XBUTTON1, down);
298  else if (msg->wParam == XBUTTON2)
299  UpdateKeyState(MessageQueue, VK_XBUTTON2, down);
300  break;
301  case WM_KEYDOWN:
302  case WM_SYSKEYDOWN:
303  down = TRUE;
304  /* fall through */
305  case WM_KEYUP:
306  case WM_SYSKEYUP:
307  key = (UCHAR)msg->wParam;
308  UpdateKeyState(MessageQueue, key, down);
309  switch(key)
310  {
311  case VK_LCONTROL:
312  case VK_RCONTROL:
313  down = IS_KEY_DOWN(MessageQueue->afKeyState, VK_LCONTROL) || IS_KEY_DOWN(MessageQueue->afKeyState, VK_RCONTROL);
314  UpdateKeyState(MessageQueue, VK_CONTROL, down);
315  break;
316  case VK_LMENU:
317  case VK_RMENU:
318  down = IS_KEY_DOWN(MessageQueue->afKeyState, VK_LMENU) || IS_KEY_DOWN(MessageQueue->afKeyState, VK_RMENU);
319  UpdateKeyState(MessageQueue, VK_MENU, down);
320  break;
321  case VK_LSHIFT:
322  case VK_RSHIFT:
323  down = IS_KEY_DOWN(MessageQueue->afKeyState, VK_LSHIFT) || IS_KEY_DOWN(MessageQueue->afKeyState, VK_RSHIFT);
324  UpdateKeyState(MessageQueue, VK_SHIFT, down);
325  break;
326  }
327  break;
328  }
329 }
330 
331 /*
332  Get down key states from the queue of prior processed input message key states.
333 
334  This fixes the left button dragging on the desktop and release sticking outline issue.
335  USB Tablet pointer seems to stick the most and leaves the box outline displayed.
336  */
339 {
340  WPARAM ret = 0;
341 
342  if (gspv.bMouseBtnSwap)
343  {
344  if (IS_KEY_DOWN(MessageQueue->afKeyState, VK_RBUTTON)) ret |= MK_LBUTTON;
345  if (IS_KEY_DOWN(MessageQueue->afKeyState, VK_LBUTTON)) ret |= MK_RBUTTON;
346  }
347  else
348  {
349  if (IS_KEY_DOWN(MessageQueue->afKeyState, VK_LBUTTON)) ret |= MK_LBUTTON;
350  if (IS_KEY_DOWN(MessageQueue->afKeyState, VK_RBUTTON)) ret |= MK_RBUTTON;
351  }
352 
353  if (IS_KEY_DOWN(MessageQueue->afKeyState, VK_MBUTTON)) ret |= MK_MBUTTON;
354  if (IS_KEY_DOWN(MessageQueue->afKeyState, VK_SHIFT)) ret |= MK_SHIFT;
355  if (IS_KEY_DOWN(MessageQueue->afKeyState, VK_CONTROL)) ret |= MK_CONTROL;
356  if (IS_KEY_DOWN(MessageQueue->afKeyState, VK_XBUTTON1)) ret |= MK_XBUTTON1;
357  if (IS_KEY_DOWN(MessageQueue->afKeyState, VK_XBUTTON2)) ret |= MK_XBUTTON2;
358  return ret;
359 }
360 
363 {
364  PTHREADINFO Win32Thread;
365  HANDLE MessageEventHandle;
366  DWORD dwFlags = HIWORD(WakeMask);
367 
368  Win32Thread = PsGetCurrentThreadWin32Thread();
369  if (Win32Thread == NULL || Win32Thread->MessageQueue == NULL)
370  return 0;
371 
372 // Win32Thread->pEventQueueServer; IntMsqSetWakeMask returns Win32Thread->hEventQueueClient
373  MessageEventHandle = Win32Thread->hEventQueueClient;
374 
375  if (Win32Thread->pcti)
376  {
377  if ( (Win32Thread->pcti->fsChangeBits & LOWORD(WakeMask)) ||
378  ( (dwFlags & MWMO_INPUTAVAILABLE) && (Win32Thread->pcti->fsWakeBits & LOWORD(WakeMask)) ) )
379  {
380  ERR("Chg 0x%x Wake 0x%x Mask 0x%x\n",Win32Thread->pcti->fsChangeBits, Win32Thread->pcti->fsWakeBits, WakeMask);
381  KeSetEvent(Win32Thread->pEventQueueServer, IO_NO_INCREMENT, FALSE); // Wake it up!
382  return MessageEventHandle;
383  }
384  }
385 
386  IdlePing();
387 
388  return MessageEventHandle;
389 }
390 
393 {
394  PTHREADINFO Win32Thread;
395 
396  Win32Thread = PsGetCurrentThreadWin32Thread();
397  if (Win32Thread == NULL || Win32Thread->MessageQueue == NULL)
398  return FALSE;
399  // Very hacky, but that is what they do.
400  Win32Thread->pcti->fsWakeBits = 0;
401 
402  IdlePong();
403 
404  return TRUE;
405 }
406 
407 /*
408  Due to the uncertainty of knowing what was set in our multilevel message queue,
409  and even if the bits are all cleared. The same as cTimers/cPaintsReady.
410  I think this is the best solution... (jt) */
412 MsqWakeQueue(PTHREADINFO pti, DWORD MessageBits, BOOL KeyEvent)
413 {
414  PUSER_MESSAGE_QUEUE Queue;
415 
416  Queue = pti->MessageQueue;
417 
418  if (Queue->QF_flags & QF_INDESTROY)
419  {
420  ERR("This Message Queue is in Destroy!\n");
421  }
422  pti->pcti->fsWakeBits |= MessageBits;
423  pti->pcti->fsChangeBits |= MessageBits;
424 
425  // Start bit accounting to help clear the main set of bits.
426  if (MessageBits & QS_KEY)
427  {
428  pti->nCntsQBits[QSRosKey]++;
429  }
430  if (MessageBits & QS_MOUSE)
431  {
432  if (MessageBits & QS_MOUSEMOVE) pti->nCntsQBits[QSRosMouseMove]++;
433  if (MessageBits & QS_MOUSEBUTTON) pti->nCntsQBits[QSRosMouseButton]++;
434  }
435  if (MessageBits & QS_POSTMESSAGE) pti->nCntsQBits[QSRosPostMessage]++;
436  if (MessageBits & QS_SENDMESSAGE) pti->nCntsQBits[QSRosSendMessage]++;
437  if (MessageBits & QS_HOTKEY) pti->nCntsQBits[QSRosHotKey]++;
438  if (MessageBits & QS_EVENT) pti->nCntsQBits[QSRosEvent]++;
439 
440  if (KeyEvent)
442 }
443 
446 {
447  UINT ClrMask = 0;
448 
449  if (MessageBits & QS_KEY)
450  {
451  if (--pti->nCntsQBits[QSRosKey] == 0) ClrMask |= QS_KEY;
452  }
453  if (MessageBits & QS_MOUSEMOVE)
454  { // Account for tracking mouse moves..
455  if (pti->nCntsQBits[QSRosMouseMove])
456  {
457  pti->nCntsQBits[QSRosMouseMove] = 0; // Throttle down count. Up to > 3:1 entries are ignored.
458  ClrMask |= QS_MOUSEMOVE;
459  }
460  }
461  if (MessageBits & QS_MOUSEBUTTON)
462  {
463  if (--pti->nCntsQBits[QSRosMouseButton] == 0) ClrMask |= QS_MOUSEBUTTON;
464  }
465  if (MessageBits & QS_POSTMESSAGE)
466  {
467  if (--pti->nCntsQBits[QSRosPostMessage] == 0) ClrMask |= QS_POSTMESSAGE;
468  }
469  if (MessageBits & QS_TIMER) // ReactOS hard coded.
470  { // Handle timer bits here.
471  if ( pti->cTimersReady )
472  {
473  if (--pti->cTimersReady == 0) ClrMask |= QS_TIMER;
474  }
475  }
476  if (MessageBits & QS_PAINT) // ReactOS hard coded.
477  { // Handle paint bits here.
478  if ( pti->cPaintsReady )
479  {
480  if (--pti->cPaintsReady == 0) ClrMask |= QS_PAINT;
481  }
482  }
483  if (MessageBits & QS_SENDMESSAGE)
484  {
485  if (--pti->nCntsQBits[QSRosSendMessage] == 0) ClrMask |= QS_SENDMESSAGE;
486  }
487  if (MessageBits & QS_HOTKEY)
488  {
489  if (--pti->nCntsQBits[QSRosHotKey] == 0) ClrMask |= QS_HOTKEY;
490  }
491  if (MessageBits & QS_EVENT)
492  {
493  if (--pti->nCntsQBits[QSRosEvent] == 0) ClrMask |= QS_EVENT;
494  }
495 
496  pti->pcti->fsWakeBits &= ~ClrMask;
497  pti->pcti->fsChangeBits &= ~ClrMask;
498 }
499 
502 {
503  pti->cPaintsReady++;
504  MsqWakeQueue(pti, QS_PAINT, TRUE);
505 }
506 
509 {
511 }
512 
513 /*
514  Post the move or update the message still pending to be processed.
515  Do not overload the queue with mouse move messages.
516  */
519 {
521  PLIST_ENTRY ListHead;
522  PUSER_MESSAGE_QUEUE MessageQueue = pti->MessageQueue;
523 
524  ListHead = &MessageQueue->HardwareMessagesListHead;
525 
526  // Do nothing if empty.
527  if (!IsListEmpty(ListHead->Flink))
528  {
529  // Look at the end of the list,
530  Message = CONTAINING_RECORD(ListHead->Blink, USER_MESSAGE, ListEntry);
531 
532  // If the mouse move message is existing on the list,
533  if (Message->Msg.message == WM_MOUSEMOVE)
534  {
535  // Overwrite the message with updated data!
536  Message->Msg = *Msg;
537 
539  return;
540  }
541  }
542 
543  MsqPostMessage(pti, Msg, TRUE, QS_MOUSEMOVE, 0, ExtraInfo);
544 }
545 
546 /*
547  Bring together the mouse move message.
548  Named "Coalesce" from Amine email ;^) (jt).
549  */
552 {
553  MSG Msg;
554  LARGE_INTEGER LargeTickCount;
555 
556  // Force time stamp to update, keeping message time in sync.
557  if (gdwMouseMoveTimeStamp == 0)
558  {
559  KeQueryTickCount(&LargeTickCount);
561  }
562 
563  // Build mouse move message.
564  Msg.hwnd = NULL;
565  Msg.message = WM_MOUSEMOVE;
566  Msg.wParam = 0;
567  Msg.lParam = MAKELONG(gpsi->ptCursor.x, gpsi->ptCursor.y);
568  Msg.time = gdwMouseMoveTimeStamp;
569  Msg.pt = gpsi->ptCursor;
570 
571  // Post the move.
573 
574  // Zero the time stamp.
576 
577  // Clear flag since the move was posted.
578  pti->MessageQueue->QF_flags &= ~QF_MOUSEMOVED;
579 }
580 
583 {
584  LARGE_INTEGER LargeTickCount;
585  MSLLHOOKSTRUCT MouseHookData;
586 // PDESKTOP pDesk;
587  PWND pwnd, pwndDesktop;
588  HDC hdcScreen;
589  PTHREADINFO pti;
590  PUSER_MESSAGE_QUEUE MessageQueue;
591  PSYSTEM_CURSORINFO CurInfo;
592 
593  KeQueryTickCount(&LargeTickCount);
594  Msg->time = MsqCalculateMessageTime(&LargeTickCount);
595 
596  MouseHookData.pt.x = LOWORD(Msg->lParam);
597  MouseHookData.pt.y = HIWORD(Msg->lParam);
598  switch (Msg->message)
599  {
600  case WM_MOUSEWHEEL:
601  MouseHookData.mouseData = MAKELONG(0, GET_WHEEL_DELTA_WPARAM(Msg->wParam));
602  break;
603  case WM_XBUTTONDOWN:
604  case WM_XBUTTONUP:
605  case WM_XBUTTONDBLCLK:
606  case WM_NCXBUTTONDOWN:
607  case WM_NCXBUTTONUP:
608  case WM_NCXBUTTONDBLCLK:
609  MouseHookData.mouseData = MAKELONG(0, HIWORD(Msg->wParam));
610  break;
611  default:
612  MouseHookData.mouseData = 0;
613  break;
614  }
615 
616  MouseHookData.flags = flags; // LLMHF_INJECTED
617  MouseHookData.time = Msg->time;
618  MouseHookData.dwExtraInfo = dwExtraInfo;
619 
620  /* If the hook procedure returned non zero, dont send the message */
621  if (Hook)
622  {
623  if (co_HOOK_CallHooks(WH_MOUSE_LL, HC_ACTION, Msg->message, (LPARAM) &MouseHookData))
624  return;
625  }
626 
627  /* Get the desktop window */
628  pwndDesktop = UserGetDesktopWindow();
629  if (!pwndDesktop) return;
630 // pDesk = pwndDesktop->head.rpdesk;
631 
632  /* Check if the mouse is captured */
633  Msg->hwnd = IntGetCaptureWindow();
634  if (Msg->hwnd != NULL)
635  {
636  pwnd = UserGetWindowObject(Msg->hwnd);
637  }
638  else
639  {
640  pwnd = IntTopLevelWindowFromPoint(Msg->pt.x, Msg->pt.y);
641  if (pwnd) Msg->hwnd = pwnd->head.h;
642  }
643 
644  hdcScreen = IntGetScreenDC();
645  CurInfo = IntGetSysCursorInfo();
646 
647  /* Check if we found a window */
648  if (Msg->hwnd != NULL && pwnd != NULL)
649  {
650  pti = pwnd->head.pti;
651  MessageQueue = pti->MessageQueue;
652 
653  if (MessageQueue->QF_flags & QF_INDESTROY)
654  {
655  ERR("Mouse is over a Window with a Dead Message Queue!\n");
656  return;
657  }
658 
659  // Check to see if this is attached.
660  if ( pti != MessageQueue->ptiMouse &&
661  MessageQueue->cThreads > 1 )
662  {
663  // Set the send pti to the message queue mouse pti.
664  pti = MessageQueue->ptiMouse;
665  }
666 
667  if (Msg->message == WM_MOUSEMOVE)
668  {
669  /* Check if cursor should be visible */
670  if(hdcScreen &&
671  MessageQueue->CursorObject &&
672  MessageQueue->iCursorLevel >= 0)
673  {
674  /* Check if shape has changed */
675  if(CurInfo->CurrentCursorObject != MessageQueue->CursorObject)
676  {
677  /* Call GDI to set the new screen cursor */
678  GreSetPointerShape(hdcScreen,
679  MessageQueue->CursorObject->hbmAlpha ?
680  NULL : MessageQueue->CursorObject->hbmMask,
681  MessageQueue->CursorObject->hbmAlpha ?
682  MessageQueue->CursorObject->hbmAlpha : MessageQueue->CursorObject->hbmColor,
683  MessageQueue->CursorObject->xHotspot,
684  MessageQueue->CursorObject->yHotspot,
685  gpsi->ptCursor.x,
686  gpsi->ptCursor.y,
687  MessageQueue->CursorObject->hbmAlpha ? SPS_ALPHA : 0);
688 
689  } else
690  GreMovePointer(hdcScreen, Msg->pt.x, Msg->pt.y);
691  }
692  /* Check if we have to hide cursor */
693  else if (CurInfo->ShowingCursor >= 0)
694  GreMovePointer(hdcScreen, -1, -1);
695 
696  /* Update global cursor info */
697  CurInfo->ShowingCursor = MessageQueue->iCursorLevel;
698  CurInfo->CurrentCursorObject = MessageQueue->CursorObject;
699  gpqCursor = MessageQueue;
700 
701  /* Mouse move is a special case */
702  MessageQueue->QF_flags |= QF_MOUSEMOVED;
703  gdwMouseMoveExtraInfo = dwExtraInfo;
704  gdwMouseMoveTimeStamp = Msg->time;
706  }
707  else
708  {
709  if (!IntGetCaptureWindow())
710  {
711  // ERR("ptiLastInput is set\n");
712  // ptiLastInput = pti; // Once this is set during Reboot or Shutdown, this prevents the exit window having foreground.
713  // Find all the Move Mouse calls and fix mouse set active focus issues......
714  }
715 
716  // Post mouse move before posting mouse buttons, keep it in sync.
717  if (pti->MessageQueue->QF_flags & QF_MOUSEMOVED)
718  {
720  }
721 
722  TRACE("Posting mouse message to hwnd=%p!\n", UserHMGetHandle(pwnd));
723  MsqPostMessage(pti, Msg, TRUE, QS_MOUSEBUTTON, 0, dwExtraInfo);
724  }
725  }
726  else if (hdcScreen)
727  {
728  /* always show cursor on background; FIXME: set default pointer */
729  GreMovePointer(hdcScreen, Msg->pt.x, Msg->pt.y);
730  CurInfo->ShowingCursor = 0;
731  }
732 }
733 
736 {
738 
739  Message = ExAllocateFromPagedLookasideList(pgMessageLookasideList);
740  if (!Message)
741  {
742  return NULL;
743  }
744 
745  RtlZeroMemory(Message, sizeof(*Message));
746  RtlMoveMemory(&Message->Msg, Msg, sizeof(MSG));
747  PostMsgCount++;
748  return Message;
749 }
750 
753 {
754  TRACE("Post Destroy %d\n",PostMsgCount)
755  if (Message->pti == NULL)
756  {
757  ERR("Double Free Message\n");
758  return;
759  }
760  RemoveEntryList(&Message->ListEntry);
761  Message->pti = NULL;
762  ExFreeToPagedLookasideList(pgMessageLookasideList, Message);
763  PostMsgCount--;
764 }
765 
768 {
770 
771  if(!(Message = ExAllocateFromPagedLookasideList(pgSendMsgLookasideList)))
772  {
773  ERR("AllocateUserMessage(): Not enough memory to allocate a message");
774  return NULL;
775  }
776  RtlZeroMemory(Message, sizeof(USER_SENT_MESSAGE));
777 
778  if (KEvent)
779  {
780  Message->pkCompletionEvent = &Message->CompletionEvent;
781 
783  }
784  SendMsgCount++;
785  TRACE("AUM pti %p msg %p\n",PsGetCurrentThreadWin32Thread(),Message);
786  return Message;
787 }
788 
791 {
792  Message->pkCompletionEvent = NULL;
793 
794  /* Remove it from the list */
795  RemoveEntryList(&Message->ListEntry);
796 
797  ExFreeToPagedLookasideList(pgSendMsgLookasideList, Message);
798  SendMsgCount--;
799 }
800 
803 {
804  PTHREADINFO pti;
805  PUSER_SENT_MESSAGE SentMessage;
806  PUSER_MESSAGE PostedMessage;
807  PLIST_ENTRY CurrentEntry, ListHead;
808 
809  ASSERT(Window);
810 
811  pti = Window->head.pti;
812 
813  /* remove the posted messages for this window */
814  CurrentEntry = pti->PostedMessagesListHead.Flink;
815  ListHead = &pti->PostedMessagesListHead;
816  while (CurrentEntry != ListHead)
817  {
818  PostedMessage = CONTAINING_RECORD(CurrentEntry, USER_MESSAGE, ListEntry);
819 
820  if (PostedMessage->Msg.hwnd == Window->head.h)
821  {
822  if (PostedMessage->Msg.message == WM_QUIT && pti->QuitPosted == 0)
823  {
824  pti->QuitPosted = 1;
825  pti->exitCode = PostedMessage->Msg.wParam;
826  }
827  ClearMsgBitsMask(pti, PostedMessage->QS_Flags);
828  MsqDestroyMessage(PostedMessage);
829  CurrentEntry = pti->PostedMessagesListHead.Flink;
830  }
831  else
832  {
833  CurrentEntry = CurrentEntry->Flink;
834  }
835  }
836 
837  /* remove the sent messages for this window */
838  CurrentEntry = pti->SentMessagesListHead.Flink;
839  ListHead = &pti->SentMessagesListHead;
840  while (CurrentEntry != ListHead)
841  {
842  SentMessage = CONTAINING_RECORD(CurrentEntry, USER_SENT_MESSAGE, ListEntry);
843 
844  if(SentMessage->Msg.hwnd == Window->head.h)
845  {
846  ERR("Remove Window Messages %p From Sent Queue\n",SentMessage);
847 #if 0 // Should mark these as invalid and allow the rest clean up, so far no harm by just commenting out. See CORE-9210.
848  ClearMsgBitsMask(pti, SentMessage->QS_Flags);
849 
850  /* wake the sender's thread */
851  if (SentMessage->pkCompletionEvent != NULL)
852  {
854  }
855 
856  if (SentMessage->HasPackedLParam)
857  {
858  if (SentMessage->Msg.lParam)
859  ExFreePool((PVOID)SentMessage->Msg.lParam);
860  }
861 
862  /* free the message */
863  FreeUserMessage(SentMessage);
864 
865  CurrentEntry = pti->SentMessagesListHead.Flink;
866 #endif
867  CurrentEntry = CurrentEntry->Flink;
868  }
869  else
870  {
871  CurrentEntry = CurrentEntry->Flink;
872  }
873  }
874 }
875 
878  _In_ PTHREADINFO pti)
879 {
880  PUSER_SENT_MESSAGE SaveMsg, Message;
882  BOOL Ret;
883  LRESULT Result = 0;
884 
886 
887  if (IsListEmpty(&pti->SentMessagesListHead))
888  {
889  return(FALSE);
890  }
891 
892  /* remove it from the list of pending messages */
893  Entry = RemoveHeadList(&pti->SentMessagesListHead);
894  Message = CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, ListEntry);
895 
896  // Signal this message is being processed.
898 
899  SaveMsg = pti->pusmCurrent;
900  pti->pusmCurrent = Message;
901 
902  // Processing a message sent to it from another thread.
903  if ( ( Message->ptiSender && pti != Message->ptiSender) ||
904  ( Message->ptiCallBackSender && pti != Message->ptiCallBackSender ))
905  { // most likely, but, to be sure.
906  pti->pcti->CTI_flags |= CTI_INSENDMESSAGE; // Let the user know...
907  }
908 
909  /* Now insert it to the global list of messages that can be removed Justin Case there's Trouble */
910  InsertTailList(&usmList, &Message->ListEntry);
911 
912  ClearMsgBitsMask(pti, Message->QS_Flags);
913 
914  if (Message->HookMessage == MSQ_ISHOOK)
915  { // Direct Hook Call processor
916  Result = co_CallHook( Message->Msg.message, // HookId
917  (INT)(INT_PTR)Message->Msg.hwnd, // Code
918  Message->Msg.wParam,
919  Message->Msg.lParam);
920  }
921  else if(Message->HookMessage == MSQ_INJECTMODULE)
922  {
923  Result = IntLoadHookModule(Message->Msg.message,
924  (HHOOK)Message->Msg.lParam,
925  Message->Msg.wParam);
926  }
927  else if ((Message->CompletionCallback) &&
928  (Message->ptiCallBackSender == pti))
929  { /* Call the callback routine */
930  if (Message->QS_Flags & QS_SMRESULT)
931  {
933  Message->Msg.hwnd,
934  Message->Msg.message,
935  Message->CompletionCallbackContext,
936  Message->lResult);
937  /* Set callback to NULL to prevent reentry */
938  Message->CompletionCallback = NULL;
939  }
940  else
941  {
942  /* The message has not been processed yet, reinsert it. */
943  RemoveEntryList(&Message->ListEntry);
945  // List is occupied need to set the bit.
947  ERR("Callback Message not processed yet. Requeuing the message\n");
948  Ret = FALSE;
949  goto Exit;
950  }
951  }
952  else
953  { /* Call the window procedure. */
954  Result = co_IntSendMessage( Message->Msg.hwnd,
955  Message->Msg.message,
956  Message->Msg.wParam,
957  Message->Msg.lParam);
958  }
959 
960  /* If the message is a callback, insert it in the callback senders MessageQueue */
961  if (Message->CompletionCallback)
962  {
963  if (Message->ptiCallBackSender)
964  {
965  Message->lResult = Result;
966  Message->QS_Flags |= QS_SMRESULT;
967 
968  /* insert it in the callers message queue */
969  RemoveEntryList(&Message->ListEntry);
972  }
973  Ret = TRUE;
974  goto Exit;
975  }
976 
977  // Retrieve the result from callback.
978  if (Message->QS_Flags & QS_SMRESULT)
979  {
980  Result = Message->lResult;
981  }
982 
983  /* Let the sender know the result. */
984  Message->lResult = Result;
985 
986  if (Message->HasPackedLParam)
987  {
988  if (Message->Msg.lParam)
989  ExFreePool((PVOID)Message->Msg.lParam);
990  }
991 
992  // Clear busy signal.
993  Message->flags &= ~SMF_RECEIVERBUSY;
994 
995  /* Notify the sender. */
996  if (Message->pkCompletionEvent != NULL)
997  {
999  }
1000 
1001  /* free the message */
1002  if (Message->flags & SMF_RECEIVERFREE)
1003  {
1004  TRACE("Receiver Freeing Message %p\n",Message);
1005  FreeUserMessage(Message);
1006  }
1007 
1008  Ret = TRUE;
1009 Exit:
1010  /* do not hangup on the user if this is reentering */
1011  if (!SaveMsg) pti->pcti->CTI_flags &= ~CTI_INSENDMESSAGE;
1012  pti->pusmCurrent = SaveMsg;
1013 
1014  return Ret;
1015 }
1016 
1017 BOOL FASTCALL
1019  HWND hwnd,
1020  UINT Msg,
1021  WPARAM wParam,
1022  LPARAM lParam,
1024  ULONG_PTR CompletionCallbackContext,
1025  BOOL HasPackedLParam,
1026  INT HookMessage)
1027 {
1028 
1029  PTHREADINFO ptiSender;
1031 
1032  if(!(Message = AllocateUserMessage(FALSE)))
1033  {
1034  ERR("MsqSendMessageAsync(): Not enough memory to allocate a message");
1035  return FALSE;
1036  }
1037 
1038  ptiSender = PsGetCurrentThreadWin32Thread();
1039 
1040  Message->Msg.hwnd = hwnd;
1041  Message->Msg.message = Msg;
1042  Message->Msg.wParam = wParam;
1043  Message->Msg.lParam = lParam;
1044  Message->pkCompletionEvent = NULL; // No event needed.
1045  Message->ptiReceiver = ptiReceiver;
1046  Message->ptiCallBackSender = ptiSender;
1048  Message->CompletionCallbackContext = CompletionCallbackContext;
1049  Message->HookMessage = HookMessage;
1050  Message->HasPackedLParam = HasPackedLParam;
1051  Message->QS_Flags = QS_SENDMESSAGE;
1052  Message->flags = SMF_RECEIVERFREE;
1053 
1054  InsertTailList(&ptiReceiver->SentMessagesListHead, &Message->ListEntry);
1055  MsqWakeQueue(ptiReceiver, QS_SENDMESSAGE, TRUE);
1056 
1057  return TRUE;
1058 }
1059 
1062  HWND Wnd,
1063  UINT Msg,
1064  WPARAM wParam,
1065  LPARAM lParam,
1066  UINT uTimeout,
1067  BOOL Block,
1068  INT HookMessage,
1069  ULONG_PTR *uResult)
1070 {
1071  PTHREADINFO pti;
1072  PUSER_SENT_MESSAGE SaveMsg, Message;
1073  NTSTATUS WaitStatus;
1076  PWND pWnd;
1077  BOOLEAN SwapStateEnabled;
1078  LRESULT Result = 0;
1079 
1081  ASSERT(pti != ptirec);
1082  ASSERT(ptirec->pcti); // Send must have a client side to receive it!!!!
1083 
1084  /* Don't send from or to a dying thread */
1085  if (pti->TIF_flags & TIF_INCLEANUP || ptirec->TIF_flags & TIF_INCLEANUP)
1086  {
1087  // Unless we are dying and need to tell our parents.
1088  if (pti->TIF_flags & TIF_INCLEANUP && !(ptirec->TIF_flags & TIF_INCLEANUP))
1089  {
1090  // Parent notify is the big one. Fire and forget!
1091  TRACE("Send message from dying thread %u\n", Msg);
1092  co_MsqSendMessageAsync(ptirec, Wnd, Msg, wParam, lParam, NULL, 0, FALSE, HookMessage);
1093  }
1094  if (uResult) *uResult = -1;
1095  TRACE("MsqSM: Msg %u Current pti %lu or Rec pti %lu\n", Msg, pti->TIF_flags & TIF_INCLEANUP, ptirec->TIF_flags & TIF_INCLEANUP);
1096  return STATUS_UNSUCCESSFUL;
1097  }
1098 
1099  if (IsThreadSuspended(ptirec))
1100  {
1101  ERR("Sending to Suspended Thread Msg %lx\n",Msg);
1102  if (uResult) *uResult = -1;
1103  return STATUS_UNSUCCESSFUL;
1104  }
1105 
1106  // Should we do the same for No Wait?
1107  if ( HookMessage == MSQ_NORMAL )
1108  {
1109  pWnd = ValidateHwndNoErr(Wnd);
1110 
1111  // These can not cross International Border lines!
1112  if ( pti->ppi != ptirec->ppi && pWnd )
1113  {
1114  switch(Msg)
1115  {
1116  // Handle the special case when working with password transfers across bordering processes.
1117  case EM_GETLINE:
1118  case EM_SETPASSWORDCHAR:
1119  case WM_GETTEXT:
1120  // Look for edit controls setup for passwords.
1121  if ( gpsi->atomSysClass[ICLS_EDIT] == pWnd->pcls->atomClassName && // Use atomNVClassName.
1122  pWnd->style & ES_PASSWORD )
1123  {
1124  if (uResult) *uResult = -1;
1125  ERR("Running across the border without a passport!\n");
1127  return STATUS_UNSUCCESSFUL;
1128  }
1129  break;
1130  case WM_NOTIFY:
1131  if (uResult) *uResult = -1;
1132  ERR("Running across the border without a passport!\n");
1133  return STATUS_UNSUCCESSFUL;
1134  }
1135  }
1136 
1137  // These can not cross State lines!
1138  if ( Msg == WM_CREATE || Msg == WM_NCCREATE )
1139  {
1140  if (uResult) *uResult = -1;
1141  ERR("Can not tell the other State we have Create!\n");
1142  return STATUS_UNSUCCESSFUL;
1143  }
1144  }
1145 
1146  if(!(Message = AllocateUserMessage(TRUE)))
1147  {
1148  ERR("MsqSendMessage(): Not enough memory to allocate a message\n");
1149  if (uResult) *uResult = -1;
1151  }
1152 
1153  Timeout.QuadPart = Int32x32To64(-10000,uTimeout); // Pass SMTO test with a TO of 0x80000000.
1154  TRACE("Timeout val %lld\n",Timeout.QuadPart)
1155 
1156  Message->Msg.hwnd = Wnd;
1157  Message->Msg.message = Msg;
1158  Message->Msg.wParam = wParam;
1159  Message->Msg.lParam = lParam;
1160  Message->ptiReceiver = ptirec;
1161  Message->ptiSender = pti;
1162  Message->HookMessage = HookMessage;
1163  Message->QS_Flags = QS_SENDMESSAGE;
1164 
1165  SaveMsg = pti->pusmSent;
1166  pti->pusmSent = Message;
1167 
1168  /* Queue it in the destination's message queue */
1169  InsertTailList(&ptirec->SentMessagesListHead, &Message->ListEntry);
1170 
1171  MsqWakeQueue(ptirec, QS_SENDMESSAGE, TRUE);
1172 
1173  // First time in, turn off swapping of the stack.
1174  if (pti->cEnterCount == 0)
1175  {
1176  SwapStateEnabled = KeSetKernelStackSwapEnable(FALSE);
1177  }
1178  pti->cEnterCount++;
1179 
1180  if (Block)
1181  {
1182  PVOID WaitObjects[2];
1183 
1184  WaitObjects[0] = Message->pkCompletionEvent; // Wait 0
1185  WaitObjects[1] = ptirec->pEThread; // Wait 1
1186 
1187  UserLeaveCo();
1188 
1189  WaitStatus = KeWaitForMultipleObjects( 2,
1190  WaitObjects,
1191  WaitAny,
1192  UserRequest,
1193  UserMode,
1194  FALSE,
1195  (uTimeout ? &Timeout : NULL),
1196  NULL );
1197 
1198  UserEnterCo();
1199 
1200  if (WaitStatus == STATUS_TIMEOUT)
1201  {
1202  /* Look up if the message has not yet dispatched, if so
1203  make sure it can't pass a result and it must not set the completion event anymore */
1204  Entry = ptirec->SentMessagesListHead.Flink;
1205  while (Entry != &ptirec->SentMessagesListHead)
1206  {
1207  if (CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, ListEntry) == Message)
1208  {
1209  Message->pkCompletionEvent = NULL;
1210  RemoveEntryList(&Message->ListEntry);
1211  ClearMsgBitsMask(ptirec, Message->QS_Flags);
1212  InsertTailList(&usmList, &Message->ListEntry);
1213  break;
1214  }
1215  Entry = Entry->Flink;
1216  }
1217 
1218  ERR("MsqSendMessage (blocked) timed out 1 Status %lx\n", WaitStatus);
1219  }
1220  // Receiving thread passed on and left us hanging with issues still pending.
1221  else if (WaitStatus == STATUS_WAIT_1)
1222  {
1223  ERR("Bk Receiving Thread woken up dead!\n");
1224  Message->flags |= SMF_RECEIVERDIED;
1225  }
1226 
1227  while (co_MsqDispatchOneSentMessage(pti))
1228  ;
1229  }
1230  else
1231  {
1232  PVOID WaitObjects[3];
1233 
1234  WaitObjects[0] = Message->pkCompletionEvent; // Wait 0
1235  WaitObjects[1] = pti->pEventQueueServer; // Wait 1
1236  WaitObjects[2] = ptirec->pEThread; // Wait 2
1237 
1238  do
1239  {
1240  UserLeaveCo();
1241 
1242  WaitStatus = KeWaitForMultipleObjects( 3,
1243  WaitObjects,
1244  WaitAny,
1245  UserRequest,
1246  UserMode,
1247  FALSE,
1248  (uTimeout ? &Timeout : NULL),
1249  NULL);
1250 
1251  UserEnterCo();
1252 
1253  if (WaitStatus == STATUS_TIMEOUT)
1254  {
1255  /* Look up if the message has not yet been dispatched, if so
1256  make sure it can't pass a result and it must not set the completion event anymore */
1257  Entry = ptirec->SentMessagesListHead.Flink;
1258  while (Entry != &ptirec->SentMessagesListHead)
1259  {
1260  if (CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, ListEntry) == Message)
1261  {
1262  Message->pkCompletionEvent = NULL;
1263  RemoveEntryList(&Message->ListEntry);
1264  ClearMsgBitsMask(ptirec, Message->QS_Flags);
1265  InsertTailList(&usmList, &Message->ListEntry);
1266  break;
1267  }
1268  Entry = Entry->Flink;
1269  }
1270 
1271  ERR("MsqSendMessage timed out 2 Status %lx\n", WaitStatus);
1272  break;
1273  }
1274  // Receiving thread passed on and left us hanging with issues still pending.
1275  else if (WaitStatus == STATUS_WAIT_2)
1276  {
1277  ERR("NB Receiving Thread woken up dead!\n");
1278  Message->flags |= SMF_RECEIVERDIED;
1279  break;
1280  }
1281 
1282  if (WaitStatus == STATUS_USER_APC) break;
1283 
1284  while (co_MsqDispatchOneSentMessage(pti))
1285  ;
1286  } while (WaitStatus == STATUS_WAIT_1);
1287  }
1288 
1289  // Count is nil, restore swapping of the stack.
1290  if (--pti->cEnterCount == 0 )
1291  {
1292  KeSetKernelStackSwapEnable(SwapStateEnabled);
1293  }
1294 
1295  // Handle User APC
1296  if (WaitStatus == STATUS_USER_APC)
1297  {
1298  // The current thread is dying!
1299  TRACE("User APC\n");
1300 
1301  // The Message will be on the Trouble list until Thread cleanup.
1302  Message->flags |= SMF_SENDERDIED;
1303 
1305  ERR("User APC Returned\n"); // Should not see this message.
1306  }
1307 
1308  // Force this thread to wake up for the next go around.
1310 
1311  Result = Message->lResult;
1312 
1313  // Determine whether this message is being processed or not.
1315  {
1316  Message->flags |= SMF_RECEIVERFREE;
1317  }
1318 
1319  if (!(Message->flags & SMF_RECEIVERFREE))
1320  {
1321  TRACE("Sender Freeing Message %p ptirec %p bit %d list empty %d\n",Message,ptirec,!!(ptirec->pcti->fsChangeBits & QS_SENDMESSAGE),IsListEmpty(&ptirec->SentMessagesListHead));
1322  // Make it to this point, the message was received.
1323  FreeUserMessage(Message);
1324  }
1325 
1326  pti->pusmSent = SaveMsg;
1327 
1328  TRACE("MSM Allocation Count %d Status %lx Result %d\n",SendMsgCount,WaitStatus,Result);
1329 
1330  if (WaitStatus != STATUS_TIMEOUT)
1331  {
1332  if (uResult)
1333  {
1334  *uResult = (STATUS_WAIT_0 == WaitStatus ? Result : 0);
1335  }
1336  }
1337 
1338  return WaitStatus;
1339 }
1340 
1341 VOID FASTCALL
1343  MSG* Msg,
1344  BOOLEAN HardwareMessage,
1345  DWORD MessageBits,
1346  DWORD dwQEvent,
1347  LONG_PTR ExtraInfo)
1348 {
1350  PUSER_MESSAGE_QUEUE MessageQueue;
1351 
1352  if ( pti->TIF_flags & TIF_INCLEANUP || pti->MessageQueue->QF_flags & QF_INDESTROY )
1353  {
1354  ERR("Post Msg; Thread or Q is Dead!\n");
1355  return;
1356  }
1357 
1358  if(!(Message = MsqCreateMessage(Msg)))
1359  {
1360  return;
1361  }
1362 
1363  MessageQueue = pti->MessageQueue;
1364 
1365  if (!HardwareMessage)
1366  {
1368  }
1369  else
1370  {
1371  InsertTailList(&MessageQueue->HardwareMessagesListHead, &Message->ListEntry);
1372  }
1373 
1374  if (Msg->message == WM_HOTKEY) MessageBits |= QS_HOTKEY; // Justin Case, just set it.
1375  Message->dwQEvent = dwQEvent;
1376  Message->ExtraInfo = ExtraInfo;
1377  Message->QS_Flags = MessageBits;
1378  Message->pti = pti;
1379  MsqWakeQueue(pti, MessageBits, TRUE);
1380  TRACE("Post Message %d\n",PostMsgCount);
1381 }
1382 
1383 VOID FASTCALL
1385 {
1386  pti->QuitPosted = TRUE;
1387  pti->exitCode = ExitCode;
1389 }
1390 
1391 /***********************************************************************
1392  * MsqSendParentNotify
1393  *
1394  * Send a WM_PARENTNOTIFY to all ancestors of the given window, unless
1395  * the window has the WS_EX_NOPARENTNOTIFY style.
1396  */
1397 static void MsqSendParentNotify( PWND pwnd, WORD event, WORD idChild, POINT pt )
1398 {
1399  PWND pwndDesktop = UserGetDesktopWindow();
1400 
1401  /* pt has to be in the client coordinates of the parent window */
1402  pt.x += pwndDesktop->rcClient.left - pwnd->rcClient.left;
1403  pt.y += pwndDesktop->rcClient.top - pwnd->rcClient.top;
1404 
1405  for (;;)
1406  {
1407  PWND pwndParent;
1408 
1409  if (!(pwnd->style & WS_CHILD)) break;
1410  if (pwnd->ExStyle & WS_EX_NOPARENTNOTIFY) break;
1411  if (!(pwndParent = IntGetParent(pwnd))) break;
1412  if (pwndParent == pwndDesktop) break;
1413  pt.x += pwnd->rcClient.left - pwndParent->rcClient.left;
1414  pt.y += pwnd->rcClient.top - pwndParent->rcClient.top;
1415 
1416  pwnd = pwndParent;
1418  MAKEWPARAM( event, idChild ), MAKELPARAM( pt.x, pt.y ) );
1419  }
1420 }
1421 
1422 VOID
1423 FASTCALL
1424 IntTrackMouseMove(PWND pwndTrack, PDESKTOP pDesk, PMSG msg, USHORT hittest)
1425 {
1426 // PWND pwndTrack = IntChildrenWindowFromPoint(pwndMsg, msg->pt.x, msg->pt.y);
1427 // hittest = (USHORT)GetNCHitEx(pwndTrack, msg->pt); /// @todo WTF is this???
1428 
1429  if ( pDesk->spwndTrack != pwndTrack || // Change with tracking window or
1430  msg->message != WM_MOUSEMOVE || // Mouse click changes or
1431  pDesk->htEx != hittest) // Change in current hit test states.
1432  {
1433  TRACE("ITMM: Track Mouse Move!\n");
1434 
1435  /* Handle only the changing window track and mouse move across a border. */
1436  if ( pDesk->spwndTrack != pwndTrack ||
1437  (pDesk->htEx == HTCLIENT) ^ (hittest == HTCLIENT) )
1438  {
1439  TRACE("ITMM: Another Wnd %d or Across Border %d\n",
1440  pDesk->spwndTrack != pwndTrack,(pDesk->htEx == HTCLIENT) ^ (hittest == HTCLIENT));
1441 
1442  if ( pDesk->dwDTFlags & DF_TME_LEAVE )
1444  (pDesk->htEx != HTCLIENT) ? WM_NCMOUSELEAVE : WM_MOUSELEAVE,
1445  0, 0);
1446 
1447  if ( pDesk->dwDTFlags & DF_TME_HOVER )
1449 
1450  /* Clear the flags to sign a change. */
1451  pDesk->dwDTFlags &= ~(DF_TME_LEAVE|DF_TME_HOVER);
1452  }
1453  /* Set the Track window and hit test. */
1454  pDesk->spwndTrack = pwndTrack;
1455  pDesk->htEx = hittest;
1456  }
1457 
1458  /* Reset, Same Track window, Hover set and Mouse Clicks or Clobbered Hover box. */
1459  if ( pDesk->spwndTrack == pwndTrack &&
1460  ( msg->message != WM_MOUSEMOVE || !RECTL_bPointInRect(&pDesk->rcMouseHover, msg->pt.x, msg->pt.y)) &&
1461  pDesk->dwDTFlags & DF_TME_HOVER )
1462  {
1463  TRACE("ITMM: Reset Hover points!\n");
1464  // Restart timer for the hover period.
1466  // Reset desktop mouse hover from the system default hover rectangle.
1467  RECTL_vSetRect(&pDesk->rcMouseHover,
1468  msg->pt.x - gspv.iMouseHoverWidth / 2,
1469  msg->pt.y - gspv.iMouseHoverHeight / 2,
1470  msg->pt.x + gspv.iMouseHoverWidth / 2,
1471  msg->pt.y + gspv.iMouseHoverHeight / 2);
1472  }
1473 }
1474 
1475 BOOL co_IntProcessMouseMessage(MSG* msg, BOOL* RemoveMessages, BOOL* NotForUs, LONG_PTR ExtraInfo, UINT first, UINT last)
1476 {
1477  MSG clk_msg;
1478  POINT pt;
1479  UINT message;
1480  USHORT hittest;
1481  EVENTMSG event;
1483  BOOL eatMsg = FALSE;
1484 
1485  PWND pwndMsg, pwndDesktop;
1486  PUSER_MESSAGE_QUEUE MessageQueue;
1487  PTHREADINFO pti;
1488  PSYSTEM_CURSORINFO CurInfo;
1489  PDESKTOP pDesk;
1490 
1492  pwndDesktop = UserGetDesktopWindow();
1493  MessageQueue = pti->MessageQueue;
1494  CurInfo = IntGetSysCursorInfo();
1495  pwndMsg = ValidateHwndNoErr(msg->hwnd);
1496  clk_msg = MessageQueue->msgDblClk;
1497  pDesk = pwndDesktop->head.rpdesk;
1498 
1499  /* find the window to dispatch this mouse message to */
1500  if (MessageQueue->spwndCapture)
1501  {
1502  hittest = HTCLIENT;
1503  pwndMsg = MessageQueue->spwndCapture;
1504  }
1505  else
1506  {
1507  /*
1508  Start with null window. See wine win.c:test_mouse_input:WM_COMMAND tests.
1509  */
1510  pwndMsg = co_WinPosWindowFromPoint( NULL, &msg->pt, &hittest, FALSE);
1511  }
1512 
1513  TRACE("Got mouse message for %p, hittest: 0x%x\n", msg->hwnd, hittest);
1514 
1515  // Null window or not the same "Hardware" message queue.
1516  if (pwndMsg == NULL || pwndMsg->head.pti->MessageQueue != MessageQueue)
1517  {
1518  // Crossing a boundary, so set cursor. See default message queue cursor.
1519  IntSystemSetCursor(SYSTEMCUR(ARROW));
1520  /* Remove and ignore the message */
1521  *RemoveMessages = TRUE;
1522  return FALSE;
1523  }
1524 
1525  // Check to see if this is attached,
1526  if ( pwndMsg->head.pti != pti && // window thread is not current,
1527  MessageQueue->cThreads > 1 ) // and is attached...
1528  {
1529  // This is not for us and we should leave so the other thread can check for messages!!!
1530  *NotForUs = TRUE;
1531  *RemoveMessages = TRUE;
1532  return FALSE;
1533  }
1534 
1535  if ( MessageQueue == gpqCursor ) // Cursor must use the same Queue!
1536  {
1537  IntTrackMouseMove(pwndMsg, pDesk, msg, hittest);
1538  }
1539  else
1540  {
1541  ERR("Not the same cursor!\n");
1542  }
1543 
1544  msg->hwnd = UserHMGetHandle(pwndMsg);
1545 
1546  pt = msg->pt;
1547  message = msg->message;
1548 
1549  /* Note: windows has no concept of a non-client wheel message */
1550  if (message != WM_MOUSEWHEEL)
1551  {
1552  if (hittest != HTCLIENT)
1553  {
1554  message += WM_NCMOUSEMOVE - WM_MOUSEMOVE;
1555  msg->wParam = hittest; // Caution! This might break wParam check in DblClk.
1556  }
1557  else
1558  {
1559  /* coordinates don't get translated while tracking a menu */
1560  /* FIXME: should differentiate popups and top-level menus */
1561  if (!(MessageQueue->MenuOwner))
1562  {
1563  pt.x += pwndDesktop->rcClient.left - pwndMsg->rcClient.left;
1564  pt.y += pwndDesktop->rcClient.top - pwndMsg->rcClient.top;
1565  }
1566  }
1567  }
1568  msg->lParam = MAKELONG( pt.x, pt.y );
1569 
1570  /* translate double clicks */
1571 
1572  if ((msg->message == WM_LBUTTONDOWN) ||
1573  (msg->message == WM_RBUTTONDOWN) ||
1574  (msg->message == WM_MBUTTONDOWN) ||
1575  (msg->message == WM_XBUTTONDOWN))
1576  {
1577  BOOL update = *RemoveMessages;
1578 
1579  /* translate double clicks -
1580  * note that ...MOUSEMOVEs can slip in between
1581  * ...BUTTONDOWN and ...BUTTONDBLCLK messages */
1582 
1583  if ((MessageQueue->MenuOwner || MessageQueue->MoveSize) ||
1584  hittest != HTCLIENT ||
1585  (pwndMsg->pcls->style & CS_DBLCLKS))
1586  {
1587  if ((msg->message == clk_msg.message) &&
1588  (msg->hwnd == clk_msg.hwnd) &&
1589  // Only worry about XButton wParam.
1590  (msg->message != WM_XBUTTONDOWN || GET_XBUTTON_WPARAM(msg->wParam) == GET_XBUTTON_WPARAM(clk_msg.wParam)) &&
1591  ((msg->time - clk_msg.time) < (ULONG)gspv.iDblClickTime) &&
1592  (abs(msg->pt.x - clk_msg.pt.x) < UserGetSystemMetrics(SM_CXDOUBLECLK)/2) &&
1593  (abs(msg->pt.y - clk_msg.pt.y) < UserGetSystemMetrics(SM_CYDOUBLECLK)/2))
1594  {
1595  message += (WM_LBUTTONDBLCLK - WM_LBUTTONDOWN);
1596  if (update)
1597  {
1598  MessageQueue->msgDblClk.message = 0; /* clear the double click conditions */
1599  update = FALSE;
1600  }
1601  }
1602  }
1603 
1604  if (!((first == 0 && last == 0) || (message >= first || message <= last)))
1605  {
1606  TRACE("Message out of range!!!\n");
1607  return FALSE;
1608  }
1609 
1610  /* update static double click conditions */
1611  if (update) MessageQueue->msgDblClk = *msg;
1612  }
1613  else
1614  {
1615  if (!((first == 0 && last == 0) || (message >= first || message <= last)))
1616  {
1617  TRACE("Message out of range!!!\n");
1618  return FALSE;
1619  }
1620 
1621  // Update mouse move down keys.
1622  if (message == WM_MOUSEMOVE)
1623  {
1624  msg->wParam = MsqGetDownKeyState(MessageQueue);
1625  }
1626  }
1627 
1628  if (gspv.bMouseClickLock)
1629  {
1630  BOOL IsClkLck = FALSE;
1631 
1632  if(msg->message == WM_LBUTTONUP)
1633  {
1634  IsClkLck = ((msg->time - CurInfo->ClickLockTime) >= gspv.dwMouseClickLockTime);
1635  if (IsClkLck && (!CurInfo->ClickLockActive))
1636  {
1637  CurInfo->ClickLockActive = TRUE;
1638  }
1639  }
1640  else if (msg->message == WM_LBUTTONDOWN)
1641  {
1642  if (CurInfo->ClickLockActive)
1643  {
1644  IsClkLck = TRUE;
1645  CurInfo->ClickLockActive = FALSE;
1646  }
1647 
1648  CurInfo->ClickLockTime = msg->time;
1649  }
1650 
1651  if(IsClkLck)
1652  {
1653  /* Remove and ignore the message */
1654  *RemoveMessages = TRUE;
1655  TRACE("Remove and ignore the message\n");
1656  return FALSE;
1657  }
1658  }
1659 
1660  if (pti->TIF_flags & TIF_MSGPOSCHANGED)
1661  {
1662  pti->TIF_flags &= ~TIF_MSGPOSCHANGED;
1663  IntNotifyWinEvent(EVENT_OBJECT_LOCATIONCHANGE, NULL, OBJID_CLIENT, CHILDID_SELF, 0);
1664  }
1665 
1666  /* message is accepted now (but still get dropped) */
1667 
1668  event.message = msg->message;
1669  event.time = msg->time;
1670  event.hwnd = msg->hwnd;
1671  event.paramL = msg->pt.x;
1672  event.paramH = msg->pt.y;
1674 
1675  hook.pt = msg->pt;
1676  hook.hwnd = msg->hwnd;
1677  hook.wHitTestCode = hittest;
1678  hook.dwExtraInfo = ExtraInfo;
1679  if (co_HOOK_CallHooks( WH_MOUSE, *RemoveMessages ? HC_ACTION : HC_NOREMOVE,
1680  message, (LPARAM)&hook ))
1681  {
1682  hook.pt = msg->pt;
1683  hook.hwnd = msg->hwnd;
1684  hook.wHitTestCode = hittest;
1685  hook.dwExtraInfo = ExtraInfo;
1686  co_HOOK_CallHooks( WH_CBT, HCBT_CLICKSKIPPED, message, (LPARAM)&hook );
1687 
1688  ERR("WH_MOUSE dropped mouse message!\n");
1689 
1690  /* Remove and skip message */
1691  *RemoveMessages = TRUE;
1692  return FALSE;
1693  }
1694 
1695  if ((hittest == (USHORT)HTERROR) || (hittest == (USHORT)HTNOWHERE))
1696  {
1697  co_IntSendMessage( msg->hwnd, WM_SETCURSOR, (WPARAM)msg->hwnd, MAKELONG( hittest, msg->message ));
1698 
1699  /* Remove and skip message */
1700  *RemoveMessages = TRUE;
1701  return FALSE;
1702  }
1703 
1704  if ((*RemoveMessages == FALSE) || MessageQueue->spwndCapture)
1705  {
1706  /* Accept the message */
1707  msg->message = message;
1708  return TRUE;
1709  }
1710 
1711  if ((msg->message == WM_LBUTTONDOWN) ||
1712  (msg->message == WM_RBUTTONDOWN) ||
1713  (msg->message == WM_MBUTTONDOWN) ||
1714  (msg->message == WM_XBUTTONDOWN))
1715  {
1716  /* Send the WM_PARENTNOTIFY,
1717  * note that even for double/nonclient clicks
1718  * notification message is still WM_L/M/RBUTTONDOWN.
1719  */
1720  MsqSendParentNotify(pwndMsg, msg->message, 0, msg->pt );
1721 
1722  /* Activate the window if needed */
1723 
1724  if (pwndMsg != MessageQueue->spwndActive)
1725  {
1726  PWND pwndTop = pwndMsg;
1727  pwndTop = IntGetNonChildAncestor(pwndTop);
1728 
1729  TRACE("Mouse pti %p pwndMsg pti %p pwndTop pti %p\n",MessageQueue->ptiMouse,pwndMsg->head.pti,pwndTop->head.pti);
1730 
1731  if (pwndTop && pwndTop != pwndDesktop)
1732  {
1733  LONG ret = co_IntSendMessage( msg->hwnd,
1735  (WPARAM)UserHMGetHandle(pwndTop),
1736  MAKELONG( hittest, msg->message));
1737  switch(ret)
1738  {
1739  case MA_NOACTIVATEANDEAT:
1740  eatMsg = TRUE;
1741  /* fall through */
1742  case MA_NOACTIVATE:
1743  break;
1744  case MA_ACTIVATEANDEAT:
1745  eatMsg = TRUE;
1746  /* fall through */
1747  case MA_ACTIVATE:
1748  case 0:
1749  if (!co_IntMouseActivateWindow( pwndTop )) eatMsg = TRUE;
1750  break;
1751  default:
1752  ERR( "unknown WM_MOUSEACTIVATE code %d\n", ret );
1753  break;
1754  }
1755  }
1756  }
1757  }
1758 
1759  /* send the WM_SETCURSOR message */
1760 
1761  /* Windows sends the normal mouse message as the message parameter
1762  in the WM_SETCURSOR message even if it's non-client mouse message */
1763  co_IntSendMessage( msg->hwnd, WM_SETCURSOR, (WPARAM)msg->hwnd, MAKELONG( hittest, msg->message ));
1764 
1765  msg->message = message;
1766  return !eatMsg;
1767 }
1768 
1770 {
1771  EVENTMSG Event;
1773  PWND pWnd;
1774  UINT ImmRet;
1775  BOOL Ret = TRUE;
1776  WPARAM wParam = Msg->wParam;
1778 
1779  if (Msg->message == VK_PACKET)
1780  {
1781  pti->wchInjected = HIWORD(Msg->wParam);
1782  }
1783 
1784  if (Msg->message == WM_KEYDOWN || Msg->message == WM_SYSKEYDOWN ||
1785  Msg->message == WM_KEYUP || Msg->message == WM_SYSKEYUP)
1786  {
1787  switch (Msg->wParam)
1788  {
1789  case VK_LSHIFT: case VK_RSHIFT:
1790  Msg->wParam = VK_SHIFT;
1791  break;
1792  case VK_LCONTROL: case VK_RCONTROL:
1793  Msg->wParam = VK_CONTROL;
1794  break;
1795  case VK_LMENU: case VK_RMENU:
1796  Msg->wParam = VK_MENU;
1797  break;
1798  }
1799  }
1800 
1801  pWnd = ValidateHwndNoErr(Msg->hwnd);
1802  if (pWnd) UserRefObjectCo(pWnd, &Ref);
1803 
1804  Event.message = Msg->message;
1805  Event.hwnd = Msg->hwnd;
1806  Event.time = Msg->time;
1807  Event.paramL = (Msg->wParam & 0xFF) | (HIWORD(Msg->lParam) << 8);
1808  Event.paramH = Msg->lParam & 0x7FFF;
1809  if (HIWORD(Msg->lParam) & 0x0100) Event.paramH |= 0x8000;
1811 
1812  if (*RemoveMessages)
1813  {
1814  if ((Msg->message == WM_KEYDOWN) &&
1815  (Msg->hwnd != IntGetDesktopWindow()))
1816  {
1817  /* Handle F1 key by sending out WM_HELP message */
1818  if (Msg->wParam == VK_F1)
1819  {
1820  UserPostMessage( Msg->hwnd, WM_KEYF1, 0, 0 );
1821  }
1822  else if (Msg->wParam >= VK_BROWSER_BACK &&
1823  Msg->wParam <= VK_LAUNCH_APP2)
1824  {
1825  /* FIXME: Process keystate */
1826  co_IntSendMessage(Msg->hwnd, WM_APPCOMMAND, (WPARAM)Msg->hwnd, MAKELPARAM(0, (FAPPCOMMAND_KEY | (Msg->wParam - VK_BROWSER_BACK + 1))));
1827  }
1828  }
1829  else if (Msg->message == WM_KEYUP)
1830  {
1831  /* Handle VK_APPS key by posting a WM_CONTEXTMENU message */
1832  if (Msg->wParam == VK_APPS && pti->MessageQueue->MenuOwner == NULL)
1833  UserPostMessage( Msg->hwnd, WM_CONTEXTMENU, (WPARAM)Msg->hwnd, -1 );
1834  }
1835  }
1836 
1838  if ( *RemoveMessages && Msg->message == WM_SYSKEYDOWN )
1839  {
1840  if ( HIWORD(Msg->lParam) & KF_ALTDOWN )
1841  {
1842  if ( Msg->wParam == VK_ESCAPE || Msg->wParam == VK_TAB ) // Alt-Tab/ESC Alt-Shift-Tab/ESC
1843  {
1844  WPARAM wParamTmp;
1845 
1846  wParamTmp = UserGetKeyState(VK_SHIFT) & 0x8000 ? SC_PREVWINDOW : SC_NEXTWINDOW;
1847  TRACE("Send WM_SYSCOMMAND Alt-Tab/ESC Alt-Shift-Tab/ESC\n");
1848  co_IntSendMessage( Msg->hwnd, WM_SYSCOMMAND, wParamTmp, Msg->wParam );
1849 
1851  Ret = FALSE;
1853  goto Exit;
1854  }
1855  }
1856  }
1857 
1858  if ( *RemoveMessages && (Msg->message == WM_SYSKEYDOWN || Msg->message == WM_KEYDOWN) )
1859  {
1860  if (gdwLanguageToggleKey < 3)
1861  {
1862  if (IS_KEY_DOWN(gafAsyncKeyState, gdwLanguageToggleKey == 1 ? VK_LMENU : VK_CONTROL)) // L Alt 1 or Ctrl 2 .
1863  {
1864  if ( wParam == VK_LSHIFT ) gLanguageToggleKeyState = INPUTLANGCHANGE_FORWARD; // Left Alt - Left Shift, Next
1866  if ( wParam == VK_RSHIFT ) gLanguageToggleKeyState = INPUTLANGCHANGE_BACKWARD; // Left Alt - Right Shift, Previous
1867  }
1868  }
1869  }
1870 
1872  if ( *RemoveMessages && (Msg->message == WM_SYSKEYUP || Msg->message == WM_KEYUP) )
1873  {
1874  // When initializing win32k: Reading from the registry hotkey combination
1875  // to switch the keyboard layout and store it to global variable.
1876  // Using this combination of hotkeys in this function
1877 
1878  if ( gdwLanguageToggleKey < 3 &&
1880  {
1881  if ( Msg->wParam == VK_SHIFT && !(IS_KEY_DOWN(gafAsyncKeyState, VK_SHIFT)))
1882  {
1883  WPARAM wParamILR;
1884  PKL pkl = pti->KeyboardLayout;
1885 
1886  if (pWnd) UserDerefObjectCo(pWnd);
1887 
1889  if (!(pWnd = pti->MessageQueue->spwndFocus))
1890  {
1891  pWnd = pti->MessageQueue->spwndActive;
1892  }
1893  if (pWnd) UserRefObjectCo(pWnd, &Ref);
1894 
1895  if (pkl != NULL && gLanguageToggleKeyState)
1896  {
1897  TRACE("Posting WM_INPUTLANGCHANGEREQUEST KeyState %d\n", gLanguageToggleKeyState );
1898 
1899  wParamILR = gLanguageToggleKeyState;
1900  // If system character set and font signature send flag.
1901  if ( gSystemFS & pkl->dwFontSigs )
1902  {
1903  wParamILR |= INPUTLANGCHANGE_SYSCHARSET;
1904  }
1905 
1907  WM_INPUTLANGCHANGEREQUEST,
1908  wParamILR,
1909  (LPARAM)pkl->hkl );
1910 
1913  Ret = FALSE;
1915  goto Exit;
1916  }
1917  }
1918  }
1919  }
1920 
1922  *RemoveMessages ? HC_ACTION : HC_NOREMOVE,
1923  LOWORD(Msg->wParam),
1924  Msg->lParam))
1925  {
1926  /* skip this message */
1929  LOWORD(Msg->wParam),
1930  Msg->lParam );
1931 
1932  ERR("KeyboardMessage WH_KEYBOARD Call Hook return!\n");
1933 
1934  *RemoveMessages = TRUE;
1935 
1936  Ret = FALSE;
1937  }
1938 
1939  if ( pWnd && Ret && *RemoveMessages && Msg->message == WM_KEYDOWN && !(pti->TIF_flags & TIF_DISABLEIME))
1940  {
1941  if ( (ImmRet = IntImmProcessKey(pti->MessageQueue, pWnd, Msg->message, Msg->wParam, Msg->lParam)) )
1942  {
1943  if ( ImmRet & (IPHK_HOTKEY|IPHK_SKIPTHISKEY) )
1944  {
1945  ImmRet = 0;
1946  }
1947  if ( ImmRet & IPHK_PROCESSBYIME )
1948  {
1949  Msg->wParam = VK_PROCESSKEY;
1950  }
1951  }
1952  }
1953 Exit:
1954  if (pWnd) UserDerefObjectCo(pWnd);
1955  return Ret;
1956 }
1957 
1958 BOOL co_IntProcessHardwareMessage(MSG* Msg, BOOL* RemoveMessages, BOOL* NotForUs, LONG_PTR ExtraInfo, UINT first, UINT last)
1959 {
1960  if ( IS_MOUSE_MESSAGE(Msg->message))
1961  {
1962  return co_IntProcessMouseMessage(Msg, RemoveMessages, NotForUs, ExtraInfo, first, last);
1963  }
1964  else if ( IS_KBD_MESSAGE(Msg->message))
1965  {
1966  return co_IntProcessKeyboardMessage(Msg, RemoveMessages);
1967  }
1968 
1969  return TRUE;
1970 }
1971 
1972 /* check whether a message filter contains at least one potential hardware message */
1973 static INT FASTCALL
1975 {
1976  /* hardware message ranges are (in numerical order):
1977  * WM_NCMOUSEFIRST .. WM_NCMOUSELAST
1978  * WM_KEYFIRST .. WM_KEYLAST
1979  * WM_MOUSEFIRST .. WM_MOUSELAST
1980  */
1981  if (!last) --last;
1982  if (last < WM_NCMOUSEFIRST) return 0;
1983  if (first > WM_NCMOUSELAST && last < WM_KEYFIRST) return 0;
1984  if (first > WM_KEYLAST && last < WM_MOUSEFIRST) return 0;
1985  if (first > WM_MOUSELAST) return 0;
1986  return 1;
1987 }
1988 
1989 /* check whether message is in the range of mouse messages */
1991 {
1992  return ( //( message >= WM_NCMOUSEFIRST && message <= WM_NCMOUSELAST ) || This seems to break tests...
1993  ( message >= WM_MOUSEFIRST && message <= WM_MOUSELAST ) ||
1994  ( message >= WM_XBUTTONDOWN && message <= WM_XBUTTONDBLCLK ) ||
1995  ( message >= WM_MBUTTONDOWN && message <= WM_MBUTTONDBLCLK ) ||
1996  ( message >= WM_LBUTTONDOWN && message <= WM_RBUTTONDBLCLK ) );
1997 }
1998 
1999 BOOL APIENTRY
2001  IN BOOL Remove,
2002  IN PWND Window,
2003  IN UINT MsgFilterLow,
2004  IN UINT MsgFilterHigh,
2005  IN UINT QSflags,
2006  OUT MSG* pMsg)
2007 {
2008  BOOL AcceptMessage, NotForUs;
2009  PUSER_MESSAGE CurrentMessage;
2010  PLIST_ENTRY ListHead;
2011  MSG msg;
2012  ULONG_PTR idSave;
2013  DWORD QS_Flags;
2014  LONG_PTR ExtraInfo;
2015  BOOL Ret = FALSE;
2016  PUSER_MESSAGE_QUEUE MessageQueue = pti->MessageQueue;
2017 
2018  if (!filter_contains_hw_range( MsgFilterLow, MsgFilterHigh )) return FALSE;
2019 
2020  ListHead = MessageQueue->HardwareMessagesListHead.Flink;
2021 
2022  if (IsListEmpty(ListHead)) return FALSE;
2023 
2024  if (!MessageQueue->ptiSysLock)
2025  {
2026  MessageQueue->ptiSysLock = pti;
2027  pti->pcti->CTI_flags |= CTI_THREADSYSLOCK;
2028  }
2029 
2030  if (MessageQueue->ptiSysLock != pti)
2031  {
2032  ERR("Thread Q is locked to ptiSysLock 0x%p pti 0x%p\n",MessageQueue->ptiSysLock,pti);
2033  return FALSE;
2034  }
2035 
2036  while (ListHead != &MessageQueue->HardwareMessagesListHead)
2037  {
2038  CurrentMessage = CONTAINING_RECORD(ListHead, USER_MESSAGE, ListEntry);
2039  ListHead = ListHead->Flink;
2040 
2041  if (MessageQueue->idSysPeek == (ULONG_PTR)CurrentMessage)
2042  {
2043  TRACE("Skip this message due to it is in play!\n");
2044  continue;
2045  }
2046 /*
2047  MSDN:
2048  1: any window that belongs to the current thread, and any messages on the current thread's message queue whose hwnd value is NULL.
2049  2: retrieves only messages on the current thread's message queue whose hwnd value is NULL.
2050  3: handle to the window whose messages are to be retrieved.
2051  */
2052  if ( ( !Window || // 1
2053  ( Window == PWND_BOTTOM && CurrentMessage->Msg.hwnd == NULL ) || // 2
2054  ( Window != PWND_BOTTOM && Window->head.h == CurrentMessage->Msg.hwnd ) || // 3
2055  ( is_mouse_message(CurrentMessage->Msg.message) ) ) && // Null window for anything mouse.
2056  ( ( ( MsgFilterLow == 0 && MsgFilterHigh == 0 ) && CurrentMessage->QS_Flags & QSflags ) ||
2057  ( MsgFilterLow <= CurrentMessage->Msg.message && MsgFilterHigh >= CurrentMessage->Msg.message ) ) )
2058  {
2059  idSave = MessageQueue->idSysPeek;
2060  MessageQueue->idSysPeek = (ULONG_PTR)CurrentMessage;
2061 
2062  msg = CurrentMessage->Msg;
2063  ExtraInfo = CurrentMessage->ExtraInfo;
2064  QS_Flags = CurrentMessage->QS_Flags;
2065 
2066  NotForUs = FALSE;
2067 
2068  UpdateKeyStateFromMsg(MessageQueue, &msg);
2069  AcceptMessage = co_IntProcessHardwareMessage(&msg, &Remove, &NotForUs, ExtraInfo, MsgFilterLow, MsgFilterHigh);
2070 
2071  if (Remove)
2072  {
2073  if (CurrentMessage->pti != NULL && (MessageQueue->idSysPeek == (ULONG_PTR)CurrentMessage))
2074  {
2075  MsqDestroyMessage(CurrentMessage);
2076  }
2077  ClearMsgBitsMask(pti, QS_Flags);
2078  }
2079 
2080  MessageQueue->idSysPeek = idSave;
2081 
2082  if (NotForUs)
2083  {
2084  Ret = FALSE;
2085  break;
2086  }
2087 
2088  if (AcceptMessage)
2089  {
2090  *pMsg = msg;
2091  // Fix all but one wine win:test_GetMessagePos WM_TIMER tests. See PostTimerMessages.
2092  if (!RtlEqualMemory(&pti->ptLast, &msg.pt, sizeof(POINT)))
2093  {
2094  pti->TIF_flags |= TIF_MSGPOSCHANGED;
2095  }
2096  pti->ptLast = msg.pt;
2097  pti->timeLast = msg.time;
2098  MessageQueue->ExtraInfo = ExtraInfo;
2099  Ret = TRUE;
2100  break;
2101  }
2102  }
2103  }
2104 
2105  MessageQueue->ptiSysLock = NULL;
2106  pti->pcti->CTI_flags &= ~CTI_THREADSYSLOCK;
2107  return Ret;
2108 }
2109 
2112  IN BOOLEAN Remove,
2113  IN PWND Window,
2114  IN UINT MsgFilterLow,
2115  IN UINT MsgFilterHigh,
2116  IN UINT QSflags,
2117  OUT LONG_PTR *ExtraInfo,
2118  OUT DWORD *dwQEvent,
2119  OUT PMSG Message)
2120 {
2121  PUSER_MESSAGE CurrentMessage;
2122  PLIST_ENTRY ListHead;
2123  DWORD QS_Flags;
2124  BOOL Ret = FALSE;
2125 
2126  ListHead = pti->PostedMessagesListHead.Flink;
2127 
2128  if (IsListEmpty(ListHead)) return FALSE;
2129 
2130  while(ListHead != &pti->PostedMessagesListHead)
2131  {
2132  CurrentMessage = CONTAINING_RECORD(ListHead, USER_MESSAGE, ListEntry);
2133  ListHead = ListHead->Flink;
2134 /*
2135  MSDN:
2136  1: any window that belongs to the current thread, and any messages on the current thread's message queue whose hwnd value is NULL.
2137  2: retrieves only messages on the current thread's message queue whose hwnd value is NULL.
2138  3: handle to the window whose messages are to be retrieved.
2139  */
2140  if ( ( !Window || // 1
2141  ( Window == PWND_BOTTOM && CurrentMessage->Msg.hwnd == NULL ) || // 2
2142  ( Window != PWND_BOTTOM && Window->head.h == CurrentMessage->Msg.hwnd ) ) && // 3
2143  ( ( ( MsgFilterLow == 0 && MsgFilterHigh == 0 ) && CurrentMessage->QS_Flags & QSflags ) ||
2144  ( MsgFilterLow <= CurrentMessage->Msg.message && MsgFilterHigh >= CurrentMessage->Msg.message ) ) )
2145  {
2146  *Message = CurrentMessage->Msg;
2147  *ExtraInfo = CurrentMessage->ExtraInfo;
2148  QS_Flags = CurrentMessage->QS_Flags;
2149  if (dwQEvent) *dwQEvent = CurrentMessage->dwQEvent;
2150 
2151  if (Remove)
2152  {
2153  if (CurrentMessage->pti != NULL)
2154  {
2155  MsqDestroyMessage(CurrentMessage);
2156  }
2157  ClearMsgBitsMask(pti, QS_Flags);
2158  }
2159  Ret = TRUE;
2160  break;
2161  }
2162  }
2163 
2164  return Ret;
2165 }
2166 
2169  UINT MsgFilterMin, UINT MsgFilterMax)
2170 {
2172 
2173  // Post mouse moves before waiting for messages.
2174  if (pti->MessageQueue->QF_flags & QF_MOUSEMOVED)
2175  {
2176  IntCoalesceMouseMove(pti);
2177  }
2178 
2179  UserLeaveCo();
2180 
2181  ZwYieldExecution(); // Let someone else run!
2182 
2184  UserRequest,
2185  UserMode,
2186  FALSE,
2187  NULL );
2188  UserEnterCo();
2189  if ( ret == STATUS_USER_APC )
2190  {
2191  TRACE("MWFNW User APC\n");
2193  }
2194  return ret;
2195 }
2196 
2197 BOOL FASTCALL
2199 {
2200  LARGE_INTEGER LargeTickCount;
2201 
2202  KeQueryTickCount(&LargeTickCount);
2203 
2204  if ((LargeTickCount.u.LowPart - pti->timeLast) > MSQ_HUNG &&
2205  !(pti->pcti->fsWakeMask & QS_INPUT) &&
2206  !PsGetThreadFreezeCount(pti->pEThread) &&
2207  !(pti->ppi->W32PF_flags & W32PF_APPSTARTING))
2208  return TRUE;
2209 
2210  return FALSE;
2211 }
2212 
2213 BOOL FASTCALL
2215 {
2216  if (pti->pEThread)
2217  {
2218  BOOL Ret = TRUE;
2219  if (!(pti->pEThread->Tcb.SuspendCount) && !PsGetThreadFreezeCount(pti->pEThread)) Ret = FALSE;
2220  return Ret;
2221  }
2222  return FALSE;
2223 }
2224 
2225 VOID
2226 CALLBACK
2228 {
2229  DoTheScreenSaver();
2230  TRACE("HungAppSysTimerProc\n");
2231  // Process list of windows that are hung and waiting.
2232 }
2233 
2236 {
2237  InitializeListHead(&MessageQueue->HardwareMessagesListHead); // Keep here!
2238  MessageQueue->spwndFocus = NULL;
2239  MessageQueue->iCursorLevel = 0;
2240  MessageQueue->CursorObject = SYSTEMCUR(WAIT); // See test_initial_cursor.
2241  if (MessageQueue->CursorObject)
2242  {
2243  TRACE("Default cursor hcur %p\n",UserHMGetHandle(MessageQueue->CursorObject));
2244  UserReferenceObject(MessageQueue->CursorObject);
2245  }
2246  RtlCopyMemory(MessageQueue->afKeyState, gafAsyncKeyState, sizeof(gafAsyncKeyState));
2247  MessageQueue->ptiMouse = pti;
2248  MessageQueue->ptiKeyboard = pti;
2249  MessageQueue->cThreads++;
2250 
2251  return TRUE;
2252 }
2253 
2254 VOID FASTCALL
2256 {
2257  PLIST_ENTRY CurrentEntry;
2258  PUSER_MESSAGE CurrentMessage;
2259  PUSER_SENT_MESSAGE CurrentSentMessage;
2260 
2261  TRACE("MsqCleanupThreadMsgs %p\n",pti);
2262 
2263  // Clear it all out.
2264  if (pti->pcti)
2265  {
2266  pti->pcti->fsWakeBits = 0;
2267  pti->pcti->fsChangeBits = 0;
2268  }
2269 
2270  pti->nCntsQBits[QSRosKey] = 0;
2271  pti->nCntsQBits[QSRosMouseMove] = 0;
2272  pti->nCntsQBits[QSRosMouseButton] = 0;
2273  pti->nCntsQBits[QSRosPostMessage] = 0;
2274  pti->nCntsQBits[QSRosSendMessage] = 0;
2275  pti->nCntsQBits[QSRosHotKey] = 0;
2276  pti->nCntsQBits[QSRosEvent] = 0;
2277 
2278  /* cleanup posted messages */
2279  while (!IsListEmpty(&pti->PostedMessagesListHead))
2280  {
2281  CurrentEntry = pti->PostedMessagesListHead.Flink;
2282  CurrentMessage = CONTAINING_RECORD(CurrentEntry, USER_MESSAGE, ListEntry);
2283  ERR("Thread Cleanup Post Messages %p\n",CurrentMessage);
2284  if (CurrentMessage->dwQEvent)
2285  {
2286  if (CurrentMessage->dwQEvent == POSTEVENT_NWE)
2287  {
2288  ExFreePoolWithTag( (PVOID)CurrentMessage->ExtraInfo, TAG_HOOK);
2289  }
2290  }
2291  MsqDestroyMessage(CurrentMessage);
2292  }
2293 
2294  /* remove the messages that have not yet been dispatched */
2295  while (!IsListEmpty(&pti->SentMessagesListHead))
2296  {
2297  CurrentEntry = pti->SentMessagesListHead.Flink;
2298  CurrentSentMessage = CONTAINING_RECORD(CurrentEntry, USER_SENT_MESSAGE, ListEntry);
2299 
2300  ERR("Thread Cleanup Sent Messages %p\n",CurrentSentMessage);
2301 
2302  /* wake the sender's thread */
2303  if (CurrentSentMessage->pkCompletionEvent != NULL)
2304  {
2305  KeSetEvent(CurrentSentMessage->pkCompletionEvent, IO_NO_INCREMENT, FALSE);
2306  }
2307 
2308  if (CurrentSentMessage->HasPackedLParam)
2309  {
2310  if (CurrentSentMessage->Msg.lParam)
2311  ExFreePool((PVOID)CurrentSentMessage->Msg.lParam);
2312  }
2313 
2314  /* free the message */
2315  FreeUserMessage(CurrentSentMessage);
2316  }
2317 
2318  // Process Trouble Message List
2319  if (!IsListEmpty(&usmList))
2320  {
2321  CurrentEntry = usmList.Flink;
2322  while (CurrentEntry != &usmList)
2323  {
2324  CurrentSentMessage = CONTAINING_RECORD(CurrentEntry, USER_SENT_MESSAGE, ListEntry);
2325  CurrentEntry = CurrentEntry->Flink;
2326 
2327  TRACE("Found troubled messages %p on the list\n",CurrentSentMessage);
2328 
2329  if ( pti == CurrentSentMessage->ptiReceiver )
2330  {
2331  if (CurrentSentMessage->HasPackedLParam)
2332  {
2333  if (CurrentSentMessage->Msg.lParam)
2334  ExFreePool((PVOID)CurrentSentMessage->Msg.lParam);
2335  }
2336 
2337  /* free the message */
2338  FreeUserMessage(CurrentSentMessage);
2339  }
2340  else if ( pti == CurrentSentMessage->ptiSender ||
2341  pti == CurrentSentMessage->ptiCallBackSender )
2342  {
2343  // Determine whether this message is being processed or not.
2344  if ((CurrentSentMessage->flags & (SMF_RECEIVERBUSY|SMF_RECEIVEDMESSAGE)) != SMF_RECEIVEDMESSAGE)
2345  {
2346  CurrentSentMessage->flags |= SMF_RECEIVERFREE;
2347  }
2348 
2349  if (!(CurrentSentMessage->flags & SMF_RECEIVERFREE))
2350  {
2351 
2352  if (CurrentSentMessage->HasPackedLParam)
2353  {
2354  if (CurrentSentMessage->Msg.lParam)
2355  ExFreePool((PVOID)CurrentSentMessage->Msg.lParam);
2356  }
2357 
2358  /* free the message */
2359  FreeUserMessage(CurrentSentMessage);
2360  }
2361  }
2362  }
2363  }
2364 }
2365 
2366 VOID FASTCALL
2368 {
2369  PUSER_MESSAGE_QUEUE MessageQueue;
2370  PLIST_ENTRY CurrentEntry;
2371  PUSER_MESSAGE CurrentMessage;
2372 
2373  MessageQueue = pti->MessageQueue;
2374  MessageQueue->cThreads--;
2375 
2376  if (MessageQueue->cThreads)
2377  {
2378  if (MessageQueue->ptiSysLock == pti) MessageQueue->ptiSysLock = NULL;
2379  }
2380 
2381  if (MessageQueue->cThreads == 0)
2382  {
2383  /* cleanup posted messages */
2384  while (!IsListEmpty(&MessageQueue->HardwareMessagesListHead))
2385  {
2386  CurrentEntry = MessageQueue->HardwareMessagesListHead.Flink;
2387  CurrentMessage = CONTAINING_RECORD(CurrentEntry, USER_MESSAGE, ListEntry);
2388  ERR("MQ Cleanup Post Messages %p\n",CurrentMessage);
2389  MsqDestroyMessage(CurrentMessage);
2390  }
2391  }
2392 
2393  if (MessageQueue->CursorObject)
2394  {
2395  PCURICON_OBJECT pCursor = MessageQueue->CursorObject;
2396 
2397  /* Change to another cursor if we going to dereference current one
2398  Note: we can't use UserSetCursor because it uses current thread
2399  message queue instead of queue given for cleanup */
2400  if (IntGetSysCursorInfo()->CurrentCursorObject == pCursor)
2401  {
2402  HDC hdcScreen;
2403 
2404  /* Get the screen DC */
2405  hdcScreen = IntGetScreenDC();
2406  if (hdcScreen)
2407  GreMovePointer(hdcScreen, -1, -1);
2409  }
2410 
2411  TRACE("DereferenceObject pCursor\n");
2412  UserDereferenceObject(pCursor);
2413  }
2414 
2415  if (gpqForeground == MessageQueue)
2416  {
2418  }
2419  if (gpqForegroundPrev == MessageQueue)
2420  {
2422  }
2423  if (gpqCursor == MessageQueue)
2424  {
2425  gpqCursor = NULL;
2426  }
2427 }
2428 
2431 {
2432  PUSER_MESSAGE_QUEUE MessageQueue;
2433 
2434  MessageQueue = ExAllocatePoolWithTag(NonPagedPool,
2435  sizeof(*MessageQueue),
2436  USERTAG_Q);
2437 
2438  if (!MessageQueue)
2439  {
2440  return NULL;
2441  }
2442 
2443  RtlZeroMemory(MessageQueue, sizeof(*MessageQueue));
2444  /* hold at least one reference until it'll be destroyed */
2445  IntReferenceMessageQueue(MessageQueue);
2446  /* initialize the queue */
2447  if (!MsqInitializeMessageQueue(pti, MessageQueue))
2448  {
2449  IntDereferenceMessageQueue(MessageQueue);
2450  return NULL;
2451  }
2452 
2453  return MessageQueue;
2454 }
2455 
2456 VOID FASTCALL
2458 {
2459  PDESKTOP desk;
2460  PUSER_MESSAGE_QUEUE MessageQueue = pti->MessageQueue;
2461 
2462  NT_ASSERT(MessageQueue != NULL);
2463  MessageQueue->QF_flags |= QF_INDESTROY;
2464 
2465  /* remove the message queue from any desktops */
2466  if ((desk = InterlockedExchangePointer((PVOID*)&MessageQueue->Desktop, 0)))
2467  {
2469  IntDereferenceMessageQueue(MessageQueue);
2470  }
2471 
2472  /* clean it up */
2474 
2475  /* decrease the reference counter, if it hits zero, the queue will be freed */
2477  IntDereferenceMessageQueue(MessageQueue);
2478 }
2479 
2482 {
2483  LPARAM Ret;
2484  PTHREADINFO pti;
2485  PUSER_MESSAGE_QUEUE MessageQueue;
2486 
2488  MessageQueue = pti->MessageQueue;
2489  if(!MessageQueue)
2490  {
2491  return 0;
2492  }
2493 
2494  Ret = MessageQueue->ExtraInfo;
2495  MessageQueue->ExtraInfo = lParam;
2496 
2497  return Ret;
2498 }
2499 
2502 {
2503  PTHREADINFO pti;
2504  PUSER_MESSAGE_QUEUE MessageQueue;
2505 
2507  MessageQueue = pti->MessageQueue;
2508  if(!MessageQueue)
2509  {
2510  return 0;
2511  }
2512 
2513  return MessageQueue->ExtraInfo;
2514 }
2515 
2516 // ReplyMessage is called by the thread receiving the window message.
2517 BOOL FASTCALL
2519 {
2521  PTHREADINFO pti;
2522 
2524  Message = pti->pusmCurrent;
2525 
2526  if (!Message) return FALSE;
2527 
2528  if (Message->QS_Flags & QS_SMRESULT) return FALSE;
2529 
2530  // SendMessageXxx || Callback msg and not a notify msg
2531  if (Message->ptiSender || Message->CompletionCallback)
2532  {
2533  Message->lResult = lResult;
2534  Message->QS_Flags |= QS_SMRESULT;
2535  // See co_MsqDispatchOneSentMessage, change bits already accounted for and cleared and this msg is going away..
2536  }
2537  return TRUE;
2538 }
2539 
2540 HWND FASTCALL
2542 {
2543  HWND Prev;
2544  PUSER_MESSAGE_QUEUE MessageQueue;
2545 
2546  MessageQueue = pti->MessageQueue;
2547 
2548  switch(Type)
2549  {
2550  case MSQ_STATE_CAPTURE:
2551  Prev = MessageQueue->spwndCapture ? UserHMGetHandle(MessageQueue->spwndCapture) : 0;
2552  MessageQueue->spwndCapture = ValidateHwndNoErr(hWnd);
2553  return Prev;
2554  case MSQ_STATE_ACTIVE:
2555  Prev = MessageQueue->spwndActive ? UserHMGetHandle(MessageQueue->spwndActive) : 0;
2556  MessageQueue->spwndActive = ValidateHwndNoErr(hWnd);
2557  return Prev;
2558  case MSQ_STATE_FOCUS:
2559  Prev = MessageQueue->spwndFocus ? UserHMGetHandle(MessageQueue->spwndFocus) : 0;
2560  MessageQueue->spwndFocus = ValidateHwndNoErr(hWnd);
2561  return Prev;
2562  case MSQ_STATE_MENUOWNER:
2563  Prev = MessageQueue->MenuOwner;
2564  MessageQueue->MenuOwner = hWnd;
2565  return Prev;
2566  case MSQ_STATE_MOVESIZE:
2567  Prev = MessageQueue->MoveSize;
2568  MessageQueue->MoveSize = hWnd;
2569  return Prev;
2570  case MSQ_STATE_CARET:
2571  Prev = MessageQueue->CaretInfo.hWnd;
2572  MessageQueue->CaretInfo.hWnd = hWnd;
2573  return Prev;
2574  }
2575 
2576  return NULL;
2577 }
2578 
2579 SHORT
2580 APIENTRY
2582 {
2583  DWORD Ret;
2584 
2585  UserEnterShared();
2586 
2587  Ret = UserGetKeyState(key);
2588 
2589  UserLeave();
2590 
2591  return (SHORT)Ret;
2592 }
2593 
2594 
2595 DWORD
2596 APIENTRY
2598 {
2599  DWORD i, ret = TRUE;
2600  PTHREADINFO pti;
2601  PUSER_MESSAGE_QUEUE MessageQueue;
2602 
2603  UserEnterShared();
2604 
2606  MessageQueue = pti->MessageQueue;
2607 
2608  _SEH2_TRY
2609  {
2610  /* Probe and copy key state to an array */
2611  ProbeForWrite(lpKeyState, 256 * sizeof(BYTE), 1);
2612  for (i = 0; i < 256; ++i)
2613  {
2614  lpKeyState[i] = 0;
2615  if (IS_KEY_DOWN(MessageQueue->afKeyState, i))
2616  lpKeyState[i] |= KS_DOWN_BIT;
2617  if (IS_KEY_LOCKED(MessageQueue->afKeyState, i))
2618  lpKeyState[i] |= KS_LOCK_BIT;
2619  }
2620  }
2622  {
2624  ret = FALSE;
2625  }
2626  _SEH2_END;
2627 
2628  UserLeave();
2629 
2630  return ret;
2631 }
2632 
2633 BOOL
2634 APIENTRY
2636 {
2637  UINT i;
2638  BOOL bRet = TRUE;
2639  PTHREADINFO pti;
2640  PUSER_MESSAGE_QUEUE MessageQueue;
2641 
2643 
2645  MessageQueue = pti->MessageQueue;
2646 
2647  _SEH2_TRY
2648  {
2649  ProbeForRead(pKeyState, 256 * sizeof(BYTE), 1);
2650  for (i = 0; i < 256; ++i)
2651  {
2652  SET_KEY_DOWN(MessageQueue->afKeyState, i, pKeyState[i] & KS_DOWN_BIT);
2653  SET_KEY_LOCKED(MessageQueue->afKeyState, i, pKeyState[i] & KS_LOCK_BIT);
2654  }
2655  }
2657  {
2659  bRet = FALSE;
2660  }
2661  _SEH2_END;
2662 
2663  UserLeave();
2664 
2665  return bRet;
2666 }
2667 
2668 /* EOF */
#define WM_MBUTTONUP
Definition: winuser.h:1749
#define IS_KBD_MESSAGE(message)
Definition: msgqueue.h:246
DWORD *typedef PVOID
Definition: winlogon.h:52
BYTE gafAsyncKeyState[256 *2/8]
Definition: keyboard.c:13
#define WH_MOUSE
Definition: winuser.h:37
LIST_ENTRY ListEntry
Definition: msgqueue.h:10
DWORD time
Definition: winuser.h:3504
PUSER_MESSAGE_QUEUE gpqForeground
Definition: focus.c:12
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
#define HCBT_CLICKSKIPPED
Definition: winuser.h:61
UINT_PTR FASTCALL IntSetTimer(PWND Window, UINT_PTR IDEvent, UINT Elapse, TIMERPROC TimerFunc, INT Type)
Definition: timer.c:177
#define HDC
Definition: msvc.h:22
#define abs(i)
Definition: fconv.c:206
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
VOID FASTCALL UserEnterShared(VOID)
Definition: ntuser.c:237
#define MSQ_STATE_ACTIVE
Definition: ntuser.h:3529
#define IN
Definition: typedefs.h:38
#define MSQ_STATE_MOVESIZE
Definition: ntuser.h:3532
BOOL FASTCALL UserPostMessage(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: message.c:1189
static VOID UpdateKeyStateFromMsg(PUSER_MESSAGE_QUEUE MessageQueue, MSG *msg)
Definition: msgqueue.c:265
VOID FASTCALL MsqWakeQueue(PTHREADINFO pti, DWORD MessageBits, BOOL KeyEvent)
Definition: msgqueue.c:412
PTHREADINFO ptiSender
Definition: msgqueue.h:28
DWORD ExStyle
Definition: ntuser.h:663
PCURICON_OBJECT IntSystemSetCursor(PCURICON_OBJECT pcurNew)
Definition: cursoricon.c:230
Definition: tftpd.h:59
#define SM_CYDOUBLECLK
Definition: winuser.h:980
unsigned short WORD
Definition: ntddk_ex.h:93
#define WAIT
Definition: assyntax.h:676
DWORD htEx
Definition: desktop.h:32
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
VOID FASTCALL co_MsqInsertMouseMessage(MSG *Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook)
Definition: msgqueue.c:582
#define MAKEWPARAM(l, h)
Definition: winuser.h:3895
struct _USER_SENT_MESSAGE * pusmSent
Definition: win32.h:96
#define VK_PROCESSKEY
Definition: winuser.h:2271
ULONG NTAPI GreSetPointerShape(_In_ HDC hdc, _In_opt_ HBITMAP hbmMask, _In_opt_ HBITMAP hbmColor, _In_ LONG xHot, _In_ LONG yHot, _In_ LONG x, _In_ LONG y, _In_ FLONG fl)
Definition: mouse.c:671
PWND FASTCALL ValidateHwndNoErr(HWND hWnd)
Definition: window.c:96
VOID NTAPI ExInitializePagedLookasideList(IN PPAGED_LOOKASIDE_LIST Lookaside, IN PALLOCATE_FUNCTION Allocate OPTIONAL, IN PFREE_FUNCTION Free OPTIONAL, IN ULONG Flags, IN SIZE_T Size, IN ULONG Tag, IN USHORT Depth)
Definition: lookas.c:274
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define WM_MOUSEFIRST
Definition: winuser.h:1740
#define USERTAG_Q
Definition: tags.h:268
SHORT APIENTRY NtUserGetKeyState(INT key)
Definition: msgqueue.c:2581
#define MK_SHIFT
Definition: winuser.h:2313
struct _DESKTOP * rpdesk
Definition: ntuser.h:189
PWND spwndTrack
Definition: desktop.h:31
VOID FASTCALL MsqCleanupMessageQueue(PTHREADINFO pti)
Definition: msgqueue.c:2367
#define ID_EVENT_SYSTIMER_MOUSEHOVER
Definition: timer.h:27
PKEVENT pkCompletionEvent
Definition: msgqueue.h:25
UINT paramL
Definition: winuser.h:3502
long y
Definition: polytest.cpp:48
HDC FASTCALL IntGetScreenDC(VOID)
Definition: winsta.c:324
Type
Definition: Type.h:6
#define WM_CONTEXTMENU
Definition: richedit.h:64
#define WM_LBUTTONDOWN
Definition: winuser.h:1742
LRESULT lResult
Definition: msgqueue.h:26
struct _Entry Entry
Definition: kefuncs.h:640
HBITMAP hbmColor
Definition: cursoricon.h:20
#define TAG_HOOK
Definition: tags.h:5
WPARAM FASTCALL MsqGetDownKeyState(PUSER_MESSAGE_QUEUE MessageQueue)
Definition: msgqueue.c:338
long x
Definition: polytest.cpp:48
#define MK_LBUTTON
Definition: winuser.h:2311
ULONG_PTR dwExtraInfo
Definition: winuser.h:3742
#define MWMO_INPUTAVAILABLE
Definition: winuser.h:890
POINT last
Definition: font.c:45
#define TAG_USRMSG
Definition: tags.h:8
#define VK_LBUTTON
Definition: winuser.h:2134
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
#define QS_ALLPOSTMESSAGE
Definition: winuser.h:866
#define pt(x, y)
Definition: drawing.c:79
BOOL bMouseBtnSwap
Definition: sysparams.h:80
POINT pt
Definition: winuser.h:3062
#define VK_RMENU
Definition: winuser.h:2231
#define WM_HOTKEY
Definition: winuser.h:1830
struct _LIST_ENTRY * Blink
Definition: typedefs.h:120
return STATUS_SUCCESS
Definition: btrfs.c:2664
VOID FASTCALL IdlePing(VOID)
Definition: message.c:515
#define VK_LSHIFT
Definition: winuser.h:2226
#define MK_MBUTTON
Definition: winuser.h:2315
BOOLEAN FASTCALL co_MsqDispatchOneSentMessage(_In_ PTHREADINFO pti)
Definition: msgqueue.c:877
unsigned char * LPBYTE
Definition: typedefs.h:52
FLONG TIF_flags
Definition: win32.h:94
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1827
HANDLE FASTCALL IntMsqSetWakeMask(DWORD WakeMask)
Definition: msgqueue.c:362
BOOL FASTCALL MsqIsHung(PTHREADINFO pti)
Definition: msgqueue.c:2198
#define PWND_BOTTOM
Definition: ntuser.h:725
#define WM_GETTEXT
Definition: winuser.h:1590
VOID FASTCALL IntNotifyWinEvent(DWORD Event, PWND pWnd, LONG idObject, LONG idChild, DWORD flags)
Definition: event.c:179
const GLint * first
Definition: glext.h:5794
UINT cPaintsReady
Definition: win32.h:108
#define MAKELPARAM(l, h)
Definition: winuser.h:3894
PVOID NTAPI PsGetCurrentThreadWin32Thread(VOID)
Definition: thread.c:805
VOID FASTCALL IntTrackMouseMove(PWND pwndTrack, PDESKTOP pDesk, PMSG msg, USHORT hittest)
Definition: msgqueue.c:1424
BOOL FASTCALL IntKillTimer(PWND Window, UINT_PTR IDEvent, BOOL SystemTimer)
Definition: timer.c:573
PTHREADINFO ptiKeyboard
Definition: msgqueue.h:56
LPARAM FASTCALL MsqGetMessageExtraInfo(VOID)
Definition: msgqueue.c:2501
#define ICLS_EDIT
Definition: ntuser.h:868
PTHREADINFO pti
Definition: msgqueue.h:15
GLenum GLuint GLenum GLsizei const GLchar * message
Definition: glext.h:5579
#define CALLBACK
Definition: compat.h:27
HWND hWnd
Definition: settings.c:17
UINT uMsg
Definition: precomp.h:53
#define WM_QUIT
Definition: winuser.h:1595
LONG_PTR ExtraInfo
Definition: msgqueue.h:13
#define WS_EX_TRANSPARENT
Definition: pedump.c:649
LONG top
Definition: windef.h:320
static __inline VOID UserRefObjectCo(PVOID obj, PUSER_REFERENCE_ENTRY UserReferenceEntry)
Definition: object.h:25
HANDLE HWND
Definition: compat.h:13
#define MSQ_HUNG
Definition: msgqueue.h:3
HWND hwnd
Definition: winuser.h:3505
#define DF_TME_LEAVE
Definition: desktop.h:48
#define MA_ACTIVATE
Definition: winuser.h:2445
#define QS_TIMER
Definition: winuser.h:883
DWORD dwMouseClickLockTime
Definition: sysparams.h:77
ULONG_PTR gdwMouseMoveExtraInfo
Definition: msgqueue.c:21
#define QS_SMRESULT
Definition: undocuser.h:93
#define KS_LOCK_BIT
Definition: input.h:55
int UserShowCursor(BOOL bShow)
Definition: msgqueue.c:168
BOOLEAN QuitPosted
Definition: win32.h:104
BOOL FASTCALL UserDereferenceObject(PVOID Object)
Definition: object.c:610
Definition: win32.h:40
NTSTATUS FASTCALL co_MsqWaitForNewMessages(PTHREADINFO pti, PWND WndFilter, UINT MsgFilterMin, UINT MsgFilterMax)
Definition: msgqueue.c:2168
#define HC_NOREMOVE
Definition: winuser.h:51
#define VK_TAB
Definition: winuser.h:2143
#define WS_CHILD
Definition: pedump.c:617
#define SMF_SENDERDIED
Definition: msgqueue.h:39
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
RECT rcClient
Definition: ntuser.h:675
#define VK_MENU
Definition: winuser.h:2148
LONG left
Definition: windef.h:319
FORCEINLINE BOOL IntPtInWindow(PWND pwnd, INT x, INT y)
Definition: winpos.h:30
HWND FASTCALL IntGetCaptureWindow(VOID)
Definition: focus.c:32
int32_t INT_PTR
Definition: typedefs.h:62
#define InsertTailList(ListHead, Entry)
#define VK_ESCAPE
Definition: winuser.h:2158
struct _USER_SENT_MESSAGE * pusmCurrent
Definition: win32.h:97
SENDASYNCPROC CompletionCallback
Definition: msgqueue.h:30
INT iMouseHoverHeight
Definition: sysparams.h:84
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
static __inline LONG MsqCalculateMessageTime(IN PLARGE_INTEGER TickCount)
Definition: msgqueue.h:253
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define FASTCALL
Definition: nt_native.h:50
static INT FASTCALL filter_contains_hw_range(UINT first, UINT last)
Definition: msgqueue.c:1974
#define WM_NCCREATE
Definition: winuser.h:1655
#define HTNOWHERE
Definition: winuser.h:2418
RTL_ATOM atomClassName
Definition: ntuser.h:536
PSERVERINFO gpsi
Definition: main.c:27
int32_t INT
Definition: typedefs.h:56
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
UINT message
Definition: winuser.h:3501
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
DWORD DWORD
Definition: winlogon.h:75
#define IntReferenceMessageQueue(MsgQueue)
Definition: msgqueue.h:217
RECT rcMouseHover
Definition: desktop.h:33
#define IS_MOUSE_MESSAGE(message)
Definition: msgqueue.h:242
#define MSQ_STATE_FOCUS
Definition: ntuser.h:3530
#define MA_ACTIVATEANDEAT
Definition: winuser.h:2446
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:263
struct _LARGE_INTEGER::@2037 u
DWORD FASTCALL UserGetKeyState(DWORD dwKey)
Definition: msgqueue.c:221
LIST_ENTRY ListEntry
Definition: msgqueue.h:22
UINT cTimersReady
Definition: win32.h:109
UINT_PTR WPARAM
Definition: windef.h:230
#define HCBT_KEYSKIPPED
Definition: winuser.h:62
PPROCESSINFO ppi
Definition: win32.h:87
INT SendMsgCount
Definition: msgqueue.c:19
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define down(mutex)
Definition: glue.h:29
ACPI_EFI_EVENT Event
Definition: acefiex.h:633
#define ES_PASSWORD
Definition: pedump.c:670
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
INT iMouseHoverWidth
Definition: sysparams.h:83
#define IPHK_PROCESSBYIME
Definition: undocuser.h:138
#define STATUS_TIMEOUT
Definition: ntstatus.h:81
BOOL bMouseClickLock
Definition: sysparams.h:75
#define SPS_ALPHA
Definition: winddi.h:4039
VOID FASTCALL MsqDestroyMessage(PUSER_MESSAGE Message)
Definition: msgqueue.c:752
#define STATUS_WAIT_2
Definition: ntstatus.h:72
#define STATUS_WAIT_1
Definition: ntstatus.h:71
#define WH_MOUSE_LL
Definition: winuser.h:44
#define CURSORF_ACON
Definition: ntuser.h:1145
BOOL FASTCALL co_MsqSendMessageAsync(PTHREADINFO ptiReceiver, HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam, SENDASYNCPROC CompletionCallback, ULONG_PTR CompletionCallbackContext, BOOL HasPackedLParam, INT HookMessage)
Definition: msgqueue.c:1018
Definition: window.c:21
struct _USER_MESSAGE_QUEUE * ActiveMessageQueue
Definition: desktop.h:38
GLenum GLclampf GLint i
Definition: glfuncs.h:14
INT iDblClickTime
Definition: sysparams.h:88
VOID FASTCALL co_IntDeliverUserAPC(VOID)
Definition: callback.c:1146
#define STATUS_WAIT_0
Definition: ntstatus.h:223
#define WM_KEYFIRST
Definition: winuser.h:1680
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
UINT style
Definition: ntuser.h:548
#define QS_HOTKEY
Definition: winuser.h:867
#define VK_RBUTTON
Definition: winuser.h:2135
#define MA_NOACTIVATEANDEAT
Definition: winuser.h:2448
#define FALSE
Definition: types.h:117
#define ERROR_ACCESS_DENIED
Definition: compat.h:87
#define WM_PARENTNOTIFY
Definition: winuser.h:1769
long LONG
Definition: pedump.c:60
ULONG_PTR dwExtraInfo
Definition: winuser.h:3463
static __inline VOID UserDerefObjectCo(PVOID obj)
Definition: object.h:38
LIST_ENTRY SentMessagesListHead
Definition: win32.h:99
#define SET_KEY_DOWN(ks, vk, down)
Definition: input.h:100
BOOL FASTCALL co_MsqReplyMessage(LRESULT lResult)
Definition: msgqueue.c:2518
LONG_PTR LPARAM
Definition: windef.h:231
#define WM_SETCURSOR
Definition: winuser.h:1608
short SHORT
Definition: pedump.c:59
#define _SEH2_END
Definition: pseh2_64.h:7
PCURICON_OBJECT CurrentCursorObject
Definition: cursoricon.h:74
DWORD dwDTFlags
Definition: desktop.h:12
#define UserLeaveCo
Definition: ntuser.h:10
#define MSQ_ISHOOK
Definition: msgqueue.h:5
#define WM_MOUSELEAVE
Definition: commctrl.h:4929
#define FIXME(fmt,...)
Definition: debug.h:110
#define SMF_RECEIVERFREE
Definition: msgqueue.h:40
BOOL FASTCALL co_IntMouseActivateWindow(PWND Wnd)
Definition: focus.c:1136
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:47
#define CHILDID_SELF
Definition: winable.h:14
UINT paramH
Definition: winuser.h:3503
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define VK_SHIFT
Definition: winuser.h:2146
THRDESKHEAD head
Definition: ntuser.h:659
NTSYSAPI NTSTATUS NTAPI ZwYieldExecution(VOID)
#define APIENTRY
Definition: nt_native.h:48
Definition: object.h:3
#define MAKELONG(a, b)
Definition: typedefs.h:248
DWORD gSystemFS
Definition: kbdlayout.c:19
PTHREADINFO ptiReceiver
Definition: msgqueue.h:29
VOID CALLBACK SystemTimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
Definition: timer.c:280
smooth NULL
Definition: ftsmooth.c:557
BOOL co_IntProcessHardwareMessage(MSG *Msg, BOOL *RemoveMessages, BOOL *NotForUs, LONG_PTR ExtraInfo, UINT first, UINT last)
Definition: msgqueue.c:1958
INT exitCode
Definition: win32.h:106
Definition: input.h:26
#define QS_SENDMESSAGE
Definition: winuser.h:882
BOOL IntLoadHookModule(int iHookID, HHOOK hHook, BOOL Unload)
Definition: hook.c:31
#define WM_KEYDOWN
Definition: winuser.h:1681
#define IS_KEY_LOCKED(ks, vk)
Definition: input.h:99
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
DWORD QS_Flags
Definition: msgqueue.h:12
#define QF_INDESTROY
Definition: msgqueue.h:103
#define WH_CBT
Definition: winuser.h:35
struct _WND * spwndNext
Definition: ntuser.h:669
#define WM_MOUSEACTIVATE
Definition: winuser.h:1609
#define HTERROR
Definition: winuser.h:2416
INIT_FUNCTION NTSTATUS NTAPI MsqInitializeImpl(VOID)
Definition: msgqueue.c:30
ULONG_PTR CompletionCallbackContext
Definition: msgqueue.h:32
struct _CLIENTTHREADINFO * pcti
Definition: win32.h:90
PWND FASTCALL UserGetWindowObject(HWND hWnd)
Definition: window.c:103
DWORD dwQEvent
Definition: msgqueue.h:14
#define MK_RBUTTON
Definition: winuser.h:2312
VOID NTAPI KeQueryTickCount(IN PLARGE_INTEGER TickCount)
Definition: clock.c:165
#define WH_JOURNALRECORD
Definition: winuser.h:30
#define TIF_DISABLEIME
Definition: ntuser.h:265
int gLanguageToggleKeyState
Definition: keyboard.c:18
#define WM_RBUTTONDOWN
Definition: winuser.h:1745
LONG NTAPI UserGetSystemMetrics(ULONG Index)
Definition: metric.c:180
#define WM_APPCOMMAND
Definition: winuser.h:1833
DWORD dwTime
Definition: solitaire.cpp:25
#define QS_INPUT
Definition: winuser.h:871
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:243
#define UserHMGetHandle(obj)
Definition: ntuser.h:208
#define WM_NCMOUSELAST
Definition: msgqueue.h:240
#define IntDereferenceMessageQueue(MsgQueue)
Definition: msgqueue.h:220
#define SMF_RECEIVERBUSY
Definition: msgqueue.h:42
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
#define OBJID_CLIENT
Definition: winable.h:19
#define WM_NCMOUSEFIRST
Definition: msgqueue.h:239
unsigned char BOOLEAN
HWND FASTCALL MsqSetStateWindow(PTHREADINFO pti, ULONG Type, HWND hWnd)
Definition: msgqueue.c:2541
LRESULT APIENTRY co_CallHook(INT HookId, INT Code, WPARAM wParam, LPARAM lParam)
Definition: hook.c:322
Definition: msg.h:39
#define TRACE(s)
Definition: solgame.cpp:4
#define InterlockedExchangePointer(Target, Value)
Definition: dshow.h:45
#define CTI_THREADSYSLOCK
Definition: ntuser.h:160
unsigned int BOOL
Definition: ntddk_ex.h:94
VOID FASTCALL ClearMsgBitsMask(PTHREADINFO pti, UINT MessageBits)
Definition: msgqueue.c:445
#define EM_SETPASSWORDCHAR
Definition: winuser.h:1965
VOID FASTCALL MsqDestroyMessageQueue(_In_ PTHREADINFO pti)
Definition: msgqueue.c:2457
NTSYSAPI ULONG NTAPI RtlEqualMemory(CONST VOID *Source1, CONST VOID *Source2, ULONG Length)
#define TMRF_SYSTEM
Definition: timer.h:20
#define VK_APPS
Definition: winuser.h:2181
VOID NTAPI GreMovePointer(_In_ HDC hdc, _In_ LONG x, _In_ LONG y)
Definition: mouse.c:767
BOOL co_IntProcessKeyboardMessage(MSG *Msg, BOOL *RemoveMessages)
Definition: msgqueue.c:1769
PUSER_MESSAGE_QUEUE FASTCALL MsqCreateMessageQueue(PTHREADINFO pti)
Definition: msgqueue.c:2430
UINT WPARAM wParam
Definition: precomp.h:53
static void Exit(void)
Definition: sock.c:1272
#define CTI_INSENDMESSAGE
Definition: ntuser.h:161
#define MSQ_INJECTMODULE
Definition: msgqueue.h:6
#define WM_MOUSELAST
Definition: winuser.h:1767
PKEVENT pEventQueueServer
Definition: win32.h:124
HKL hkl
Definition: input.h:32
PUSER_MESSAGE_QUEUE gpqCursor
Definition: msgqueue.c:20
#define WM_KEYUP
Definition: winuser.h:1682
#define WS_EX_LAYERED
Definition: winuser.h:389
DWORD nCntsQBits[QSIDCOUNTS]
Definition: win32.h:147
#define QS_EVENT
Definition: undocuser.h:95
SPIVALUES gspv
Definition: sysparams.c:17
PSYSTEM_CURSORINFO IntGetSysCursorInfo(VOID)
Definition: cursoricon.c:187
VOID FASTCALL FreeUserMessage(PUSER_SENT_MESSAGE Message)
Definition: msgqueue.c:790
#define WM_KEYLAST
Definition: winuser.h:1694
VOID FASTCALL MsqPostMessage(PTHREADINFO pti, MSG *Msg, BOOLEAN HardwareMessage, DWORD MessageBits, DWORD dwQEvent, LONG_PTR ExtraInfo)
Definition: msgqueue.c:1342
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
#define WM_RBUTTONUP
Definition: winuser.h:1746
#define UserEnterCo
Definition: ntuser.h:9
BOOLEAN APIENTRY MsqPeekMessage(IN PTHREADINFO pti, IN BOOLEAN Remove, IN PWND Window, IN UINT MsgFilterLow, IN UINT MsgFilterHigh, IN UINT QSflags, OUT LONG_PTR *ExtraInfo, OUT DWORD *dwQEvent, OUT PMSG Message)
Definition: msgqueue.c:2111
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
#define SMF_RECEIVERDIED
Definition: msgqueue.h:38
#define POSTEVENT_NWE
Definition: msgqueue.h:125
VOID APIENTRY co_IntCallSentMessageCallback(SENDASYNCPROC CompletionCallback, HWND hWnd, UINT Msg, ULONG_PTR CompletionCallbackContext, LRESULT Result)
Definition: callback.c:245
GLbitfield flags
Definition: glext.h:7161
#define SC_PREVWINDOW
Definition: winuser.h:2535
VOID FASTCALL IntCoalesceMouseMove(PTHREADINFO pti)
Definition: msgqueue.c:551
PTHREADINFO ptiSysLock
Definition: msgqueue.h:52
VOID FASTCALL MsqDecPaintCountQueue(PTHREADINFO pti)
Definition: msgqueue.c:508
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
CHAR Message[80]
Definition: alive.c:5
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
LRESULT APIENTRY co_HOOK_CallHooks(INT HookId, INT Code, WPARAM wParam, LPARAM lParam)
Definition: hook.c:1089
ULONG_PTR idSysPeek
Definition: msgqueue.h:54
PWND FASTCALL UserGetDesktopWindow(VOID)
Definition: desktop.c:745
_In_ BOOLEAN Remove
Definition: psfuncs.h:110
unsigned char UCHAR
Definition: xmlstorage.h:181
int ret
DWORD dwMouseHoverTime
Definition: desktop.h:34
LONG timeLast
Definition: win32.h:101
PUSER_SENT_MESSAGE FASTCALL AllocateUserMessage(BOOL KEvent)
Definition: msgqueue.c:767
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
LRESULT FASTCALL co_IntSendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: message.c:1291
#define WM_MOUSEWHEEL
Definition: zmouse.h:18
VOID FASTCALL MsqPostMouseMove(PTHREADINFO pti, MSG *Msg, LONG_PTR ExtraInfo)
Definition: msgqueue.c:518
DBG_DEFAULT_CHANNEL(UserMsgQ)
#define VK_RCONTROL
Definition: winuser.h:2229
#define VK_LMENU
Definition: winuser.h:2230
#define QS_MOUSEMOVE
Definition: winuser.h:876
#define VK_RSHIFT
Definition: winuser.h:2227
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1170
HKEY key
Definition: reg.c:45
BYTE afKeyState[256 *2/8]
Definition: msgqueue.h:84
DWORD dwFontSigs
Definition: input.h:34
BOOL APIENTRY NtUserSetKeyboardState(LPBYTE pKeyState)
Definition: msgqueue.c:2635
ULONG CURSORF_flags
Definition: cursoricon.h:16
PUSER_MESSAGE FASTCALL MsqCreateMessage(LPMSG Msg)
Definition: msgqueue.c:735
#define WM_LBUTTONDBLCLK
Definition: winuser.h:1744
THRDCARETINFO CaretInfo
Definition: msgqueue.h:92
BOOL HasPackedLParam
Definition: msgqueue.h:34
#define WM_MBUTTONDBLCLK
Definition: winuser.h:1750
PTHREADINFO ptiCallBackSender
Definition: msgqueue.h:31
Definition: typedefs.h:117
#define CS_DBLCLKS
Definition: winuser.h:646
#define MA_NOACTIVATE
Definition: winuser.h:2447
PCURICON_OBJECT CursorObject
Definition: msgqueue.h:89
struct _cl_event * event
Definition: glext.h:7739
UINT UINT uTimeout
Definition: msvc.h:63
#define DF_TME_HOVER
Definition: desktop.h:47
struct tagKL * KeyboardLayout
Definition: win32.h:89
VOID FASTCALL SetLastNtError(NTSTATUS Status)
Definition: error.c:36
VOID FASTCALL DoTheScreenSaver(VOID)
Definition: input.c:50
#define TIF_MSGPOSCHANGED
Definition: ntuser.h:260
unsigned char BYTE
Definition: ntddk_ex.h:96
#define STATUS_USER_APC
Definition: ntstatus.h:78
#define ERR(fmt,...)
Definition: debug.h:109
#define _In_
Definition: no_sal2.h:204
HANDLE hEventQueueClient
Definition: win32.h:122
Definition: ntuser.h:657
struct _USER_MESSAGE_QUEUE * MessageQueue
Definition: win32.h:88
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:251
HWND FASTCALL IntGetDesktopWindow(VOID)
Definition: desktop.c:734
static VOID UpdateKeyState(PUSER_MESSAGE_QUEUE MessageQueue, WORD wVk, BOOL bIsDown)
Definition: msgqueue.c:246
VOID FASTCALL IntSetFocusMessageQueue(PUSER_MESSAGE_QUEUE NewQueue)
Definition: desktop.c:679
DWORD *typedef HANDLE
Definition: winlogon.h:52
#define MSQ_NORMAL
Definition: msgqueue.h:4
#define WS_EX_NOPARENTNOTIFY
Definition: pedump.c:646
LONG NTSTATUS
Definition: DriverTester.h:11
static ULONG Timeout
Definition: ping.c:61
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
VOID FASTCALL IdlePong(VOID)
Definition: message.c:545
BOOL co_IntProcessMouseMessage(MSG *msg, BOOL *RemoveMessages, BOOL *NotForUs, LONG_PTR ExtraInfo, UINT first, UINT last)
Definition: msgqueue.c:1475
BOOL FASTCALL IsThreadSuspended(PTHREADINFO pti)
Definition: msgqueue.c:2214
struct LOOKASIDE_ALIGN _PAGED_LOOKASIDE_LIST PAGED_LOOKASIDE_LIST
#define MSQ_STATE_CAPTURE
Definition: ntuser.h:3528
LIST_ENTRY PostedMessagesListHead
Definition: win32.h:131
unsigned short USHORT
Definition: pedump.c:61
ULONG NTAPI PsGetThreadFreezeCount(IN PETHREAD Thread)
Definition: thread.c:685
#define HC_ACTION
Definition: winuser.h:48
#define WM_SYSKEYUP
Definition: winuser.h:1686
#define IPHK_SKIPTHISKEY
Definition: undocuser.h:140
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
WCHAR wchInjected
Definition: win32.h:133
#define WM_LBUTTONUP
Definition: winuser.h:1743
#define WM_MBUTTONDOWN
Definition: winuser.h:1748
DWORD APIENTRY NtUserGetKeyboardState(LPBYTE lpKeyState)
Definition: msgqueue.c:2597
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
#define _SEH2_TRY
Definition: pseh2_64.h:5
PWND FASTCALL IntGetParent(PWND Wnd)
Definition: window.c:185
DWORD state
Definition: ntuser.h:660
struct @1419 Msg[]
#define QS_POSTMESSAGE
Definition: winuser.h:878
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
FORCEINLINE BOOL RECTL_bPointInRect(_In_ const RECTL *prcl, _In_ INT x, _In_ INT y)
Definition: rect.h:52
UINT WPARAM LPARAM lParam
Definition: precomp.h:53
unsigned int UINT
Definition: ndis.h:50
#define WM_MOUSEMOVE
Definition: winuser.h:1741
#define QS_MOUSEBUTTON
Definition: winuser.h:875
BOOL FASTCALL IntMsqClearWakeMask(VOID)
Definition: msgqueue.c:392
VOID FASTCALL MsqCleanupThreadMsgs(PTHREADINFO pti)
Definition: msgqueue.c:2255
#define MSQ_STATE_CARET
Definition: ntuser.h:3533
#define MK_CONTROL
Definition: winuser.h:2314
HBITMAP hbmMask
Definition: cursoricon.h:19
#define KF_ALTDOWN
Definition: winuser.h:2393
#define VK_F1
Definition: winuser.h:2199
#define W32PF_APPSTARTING
Definition: win32.h:10
#define VK_CONTROL
Definition: winuser.h:2147
#define QS_PAINT
Definition: winuser.h:877
HBITMAP hbmAlpha
Definition: cursoricon.h:21
UINT FASTCALL IntImmProcessKey(PUSER_MESSAGE_QUEUE MessageQueue, PWND pWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: ime.c:14
#define IPHK_HOTKEY
Definition: undocuser.h:137
BOOL APIENTRY co_MsqPeekHardwareMessage(IN PTHREADINFO pti, IN BOOL Remove, IN PWND Window, IN UINT MsgFilterLow, IN UINT MsgFilterHigh, IN UINT QSflags, OUT MSG *pMsg)
Definition: msgqueue.c:2000
PWND FASTCALL IntTopLevelWindowFromPoint(INT x, INT y)
Definition: msgqueue.c:61
VOID FASTCALL MsqIncPaintCountQueue(PTHREADINFO pti)
Definition: msgqueue.c:501
KEVENT CompletionEvent
Definition: msgqueue.h:35
#define msg(x)
Definition: auth_time.c:54
#define __WARNING_USING_UNINIT_VAR
Definition: suppress.h:31
PWND FASTCALL IntGetNonChildAncestor(PWND pWnd)
Definition: window.c:283
#define WH_KEYBOARD
Definition: winuser.h:32
static PPAGED_LOOKASIDE_LIST pgSendMsgLookasideList
Definition: msgqueue.c:17
#define OUT
Definition: typedefs.h:39
VOID FASTCALL MsqPostQuitMessage(PTHREADINFO pti, ULONG ExitCode)
Definition: msgqueue.c:1384
#define WM_CREATE
Definition: winuser.h:1580
#define WM_RBUTTONDBLCLK
Definition: winuser.h:1747
PUSER_MESSAGE_QUEUE gpqForegroundPrev
Definition: focus.c:13
#define KS_DOWN_BIT
Definition: input.h:54
#define WM_SYSKEYDOWN
Definition: winuser.h:1685
static void MsqSendParentNotify(PWND pwnd, WORD event, WORD idChild, POINT pt)
Definition: msgqueue.c:1397
VOID CALLBACK HungAppSysTimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
Definition: msgqueue.c:2227
#define EM_GETLINE
Definition: winuser.h:1942
UINT msg
Definition: msvc.h:92
#define HIWORD(l)
Definition: typedefs.h:246
struct tagACON * PACON
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:565
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:259
#define SYSTEMCUR(func)
Definition: cursoricon.h:129
DWORD state2
Definition: ntuser.h:661
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define WM_NCMOUSELEAVE
Definition: winuser.h:1808
#define ULONG_PTR
Definition: config.h:101
#define IS_KEY_DOWN(ks, vk)
Definition: input.h:98
LPARAM FASTCALL MsqSetMessageExtraInfo(LPARAM lParam)
Definition: msgqueue.c:2481
PTHREADINFO ptiMouse
Definition: msgqueue.h:55
NTSTATUS FASTCALL co_MsqSendMessage(PTHREADINFO ptirec, HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam, UINT uTimeout, BOOL Block, INT HookMessage, ULONG_PTR *uResult)
Definition: msgqueue.c:1061
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define SC_NEXTWINDOW
Definition: winuser.h:2534
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1097
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
INT iCursorLevel
Definition: win32.h:126
const TCHAR * CompletionCallback(unsigned __int64 &rnIndex, const BOOL *pblnForward, const TCHAR *pszContext, const TCHAR *pszBegin)
Definition: Completion.cpp:439
#define HTCLIENT
Definition: winuser.h:2419
BYTE afKeyRecentDown[256/8]
Definition: msgqueue.h:83
INT PostMsgCount
Definition: msgqueue.c:18
LONG_PTR LRESULT
Definition: windef.h:232
#define VK_LCONTROL
Definition: winuser.h:2228
#define QS_MOUSE
Definition: winuser.h:874
PCURICON_OBJECT FASTCALL UserSetCursor(PCURICON_OBJECT NewCursor, BOOL ForceChange)
Definition: msgqueue.c:93
struct LOOKASIDE_ALIGN _PAGED_LOOKASIDE_LIST * PPAGED_LOOKASIDE_LIST
#define QS_KEY
Definition: winuser.h:873
BOOLEAN FASTCALL MsqInitializeMessageQueue(PTHREADINFO pti, PUSER_MESSAGE_QUEUE MessageQueue)
Definition: msgqueue.c:2235
UINT message
Definition: winuser.h:3058
struct _WND * spwndChild
Definition: ntuser.h:672
void(CALLBACK * SENDASYNCPROC)(HWND, UINT, ULONG_PTR, LRESULT)
Definition: winuser.h:2859
#define SET_KEY_LOCKED(ks, vk, down)
Definition: input.h:103
#define WS_VISIBLE
Definition: pedump.c:620
FORCEINLINE VOID RECTL_vSetRect(_Out_ RECTL *prcl, _In_ LONG left, _In_ LONG top, _In_ LONG right, _In_ LONG bottom)
Definition: rect.h:5
INT INT y
Definition: msvc.h:62
#define MSQ_STATE_MENUOWNER
Definition: ntuser.h:3531
#define QF_MOUSEMOVED
Definition: msgqueue.h:99
static BOOL is_mouse_message(UINT message)
Definition: msgqueue.c:1990
#define VK_MBUTTON
Definition: winuser.h:2137
#define WM_SYSCOMMAND
Definition: winuser.h:1707
#define WNDS_DESTROYED
Definition: ntuser.h:604
struct _DESKTOP * Desktop
Definition: msgqueue.h:50
VOID APIENTRY MsqRemoveWindowMessagesFromQueue(PWND Window)
Definition: msgqueue.c:802
LIST_ENTRY HardwareMessagesListHead
Definition: msgqueue.h:59
INT cEnterCount
Definition: win32.h:129
#define LOWORD(l)
Definition: pedump.c:82
#define SM_CXDOUBLECLK
Definition: winuser.h:979
#define TIF_INCLEANUP
Definition: ntuser.h:240
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:27
#define Int32x32To64(a, b)
#define WM_KEYF1
Definition: msg.c:49
#define WM_NCMOUSEMOVE
Definition: winuser.h:1663
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define WM_NOTIFY
Definition: richedit.h:61
#define SMF_RECEIVEDMESSAGE
Definition: msgqueue.h:41
#define WNDS2_INDESTROY
Definition: ntuser.h:616
BOOLEAN NTAPI KeSetKernelStackSwapEnable(IN BOOLEAN Enable)
Definition: thrdobj.c:997
ATOM atomSysClass[ICLS_NOTUSED+1]
Definition: ntuser.h:1007
UINT WPARAM LPARAM LRESULT & lResult
Definition: precomp.h:53
PWND APIENTRY co_WinPosWindowFromPoint(IN PWND ScopeWin, IN POINT *WinPoint, IN OUT USHORT *HitTest, IN BOOL Ignore)
Definition: winpos.c:2739
LONGLONG QuadPart
Definition: typedefs.h:112
LIST_ENTRY usmList
Definition: msgqueue.c:23
static PPAGED_LOOKASIDE_LIST pgMessageLookasideList
Definition: msgqueue.c:16
#define _PRAGMA_WARNING_SUPPRESS(x)
Definition: suppress.h:28
Definition: path.c:42
#define INIT_FUNCTION
Definition: ntoskrnl.h:11
VOID FASTCALL UserReferenceObject(PVOID obj)
Definition: object.c:697
DWORD gdwLanguageToggleKey
Definition: keyboard.c:19
INT x
Definition: msvc.h:62
PCLS pcls
Definition: ntuser.h:678
DWORD gdwMouseMoveTimeStamp
Definition: msgqueue.c:22
#define NT_ASSERT
Definition: rtlfuncs.h:3312
DWORD style
Definition: ntuser.h:665