ReactOS  0.4.14-dev-608-gd495a4f
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 
27 INIT_FUNCTION
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 
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 
555  // Force time stamp to update, keeping message time in sync.
556  if (gdwMouseMoveTimeStamp == 0)
557  {
559  }
560 
561  // Build mouse move message.
562  Msg.hwnd = NULL;
563  Msg.message = WM_MOUSEMOVE;
564  Msg.wParam = 0;
565  Msg.lParam = MAKELONG(gpsi->ptCursor.x, gpsi->ptCursor.y);
566  Msg.time = gdwMouseMoveTimeStamp;
567  Msg.pt = gpsi->ptCursor;
568 
569  // Post the move.
571 
572  // Zero the time stamp.
574 
575  // Clear flag since the move was posted.
576  pti->MessageQueue->QF_flags &= ~QF_MOUSEMOVED;
577 }
578 
581 {
582  MSLLHOOKSTRUCT MouseHookData;
583 // PDESKTOP pDesk;
584  PWND pwnd, pwndDesktop;
585  HDC hdcScreen;
586  PTHREADINFO pti;
587  PUSER_MESSAGE_QUEUE MessageQueue;
588  PSYSTEM_CURSORINFO CurInfo;
589 
590  Msg->time = EngGetTickCount32();
591 
592  MouseHookData.pt.x = LOWORD(Msg->lParam);
593  MouseHookData.pt.y = HIWORD(Msg->lParam);
594  switch (Msg->message)
595  {
596  case WM_MOUSEWHEEL:
597  MouseHookData.mouseData = MAKELONG(0, GET_WHEEL_DELTA_WPARAM(Msg->wParam));
598  break;
599  case WM_XBUTTONDOWN:
600  case WM_XBUTTONUP:
601  case WM_XBUTTONDBLCLK:
602  case WM_NCXBUTTONDOWN:
603  case WM_NCXBUTTONUP:
604  case WM_NCXBUTTONDBLCLK:
605  MouseHookData.mouseData = MAKELONG(0, HIWORD(Msg->wParam));
606  break;
607  default:
608  MouseHookData.mouseData = 0;
609  break;
610  }
611 
612  MouseHookData.flags = flags; // LLMHF_INJECTED
613  MouseHookData.time = Msg->time;
614  MouseHookData.dwExtraInfo = dwExtraInfo;
615 
616  /* If the hook procedure returned non zero, dont send the message */
617  if (Hook)
618  {
619  if (co_HOOK_CallHooks(WH_MOUSE_LL, HC_ACTION, Msg->message, (LPARAM) &MouseHookData))
620  return;
621  }
622 
623  /* Get the desktop window */
624  pwndDesktop = UserGetDesktopWindow();
625  if (!pwndDesktop) return;
626 // pDesk = pwndDesktop->head.rpdesk;
627 
628  /* Check if the mouse is captured */
629  Msg->hwnd = IntGetCaptureWindow();
630  if (Msg->hwnd != NULL)
631  {
632  pwnd = UserGetWindowObject(Msg->hwnd);
633  }
634  else
635  {
636  pwnd = IntTopLevelWindowFromPoint(Msg->pt.x, Msg->pt.y);
637  if (pwnd) Msg->hwnd = pwnd->head.h;
638  }
639 
640  hdcScreen = IntGetScreenDC();
641  CurInfo = IntGetSysCursorInfo();
642 
643  /* Check if we found a window */
644  if (Msg->hwnd != NULL && pwnd != NULL)
645  {
646  pti = pwnd->head.pti;
647  MessageQueue = pti->MessageQueue;
648 
649  if (MessageQueue->QF_flags & QF_INDESTROY)
650  {
651  ERR("Mouse is over a Window with a Dead Message Queue!\n");
652  return;
653  }
654 
655  // Check to see if this is attached.
656  if ( pti != MessageQueue->ptiMouse &&
657  MessageQueue->cThreads > 1 )
658  {
659  // Set the send pti to the message queue mouse pti.
660  pti = MessageQueue->ptiMouse;
661  }
662 
663  if (Msg->message == WM_MOUSEMOVE)
664  {
665  /* Check if cursor should be visible */
666  if(hdcScreen &&
667  MessageQueue->CursorObject &&
668  MessageQueue->iCursorLevel >= 0)
669  {
670  /* Check if shape has changed */
671  if(CurInfo->CurrentCursorObject != MessageQueue->CursorObject)
672  {
673  /* Call GDI to set the new screen cursor */
674  GreSetPointerShape(hdcScreen,
675  MessageQueue->CursorObject->hbmAlpha ?
676  NULL : MessageQueue->CursorObject->hbmMask,
677  MessageQueue->CursorObject->hbmAlpha ?
678  MessageQueue->CursorObject->hbmAlpha : MessageQueue->CursorObject->hbmColor,
679  MessageQueue->CursorObject->xHotspot,
680  MessageQueue->CursorObject->yHotspot,
681  gpsi->ptCursor.x,
682  gpsi->ptCursor.y,
683  MessageQueue->CursorObject->hbmAlpha ? SPS_ALPHA : 0);
684 
685  } else
686  GreMovePointer(hdcScreen, Msg->pt.x, Msg->pt.y);
687  }
688  /* Check if we have to hide cursor */
689  else if (CurInfo->ShowingCursor >= 0)
690  GreMovePointer(hdcScreen, -1, -1);
691 
692  /* Update global cursor info */
693  CurInfo->ShowingCursor = MessageQueue->iCursorLevel;
694  CurInfo->CurrentCursorObject = MessageQueue->CursorObject;
695  gpqCursor = MessageQueue;
696 
697  /* Mouse move is a special case */
698  MessageQueue->QF_flags |= QF_MOUSEMOVED;
699  gdwMouseMoveExtraInfo = dwExtraInfo;
700  gdwMouseMoveTimeStamp = Msg->time;
702  }
703  else
704  {
705  if (!IntGetCaptureWindow())
706  {
707  // ERR("ptiLastInput is set\n");
708  // ptiLastInput = pti; // Once this is set during Reboot or Shutdown, this prevents the exit window having foreground.
709  // Find all the Move Mouse calls and fix mouse set active focus issues......
710  }
711 
712  // Post mouse move before posting mouse buttons, keep it in sync.
713  if (pti->MessageQueue->QF_flags & QF_MOUSEMOVED)
714  {
716  }
717 
718  TRACE("Posting mouse message to hwnd=%p!\n", UserHMGetHandle(pwnd));
719  MsqPostMessage(pti, Msg, TRUE, QS_MOUSEBUTTON, 0, dwExtraInfo);
720  }
721  }
722  else if (hdcScreen)
723  {
724  /* always show cursor on background; FIXME: set default pointer */
725  GreMovePointer(hdcScreen, Msg->pt.x, Msg->pt.y);
726  CurInfo->ShowingCursor = 0;
727  }
728 }
729 
732 {
734 
735  Message = ExAllocateFromPagedLookasideList(pgMessageLookasideList);
736  if (!Message)
737  {
738  return NULL;
739  }
740 
741  RtlZeroMemory(Message, sizeof(*Message));
742  RtlMoveMemory(&Message->Msg, Msg, sizeof(MSG));
743  PostMsgCount++;
744  return Message;
745 }
746 
749 {
750  TRACE("Post Destroy %d\n",PostMsgCount);
751  if (Message->pti == NULL)
752  {
753  ERR("Double Free Message\n");
754  return;
755  }
756  RemoveEntryList(&Message->ListEntry);
757  Message->pti = NULL;
758  ExFreeToPagedLookasideList(pgMessageLookasideList, Message);
759  PostMsgCount--;
760 }
761 
764 {
766 
767  if(!(Message = ExAllocateFromPagedLookasideList(pgSendMsgLookasideList)))
768  {
769  ERR("AllocateUserMessage(): Not enough memory to allocate a message");
770  return NULL;
771  }
773 
774  if (KEvent)
775  {
776  Message->pkCompletionEvent = &Message->CompletionEvent;
777 
778  KeInitializeEvent(Message->pkCompletionEvent, NotificationEvent, FALSE);
779  }
780  SendMsgCount++;
781  TRACE("AUM pti %p msg %p\n",PsGetCurrentThreadWin32Thread(),Message);
782  return Message;
783 }
784 
787 {
788  Message->pkCompletionEvent = NULL;
789 
790  /* Remove it from the list */
791  RemoveEntryList(&Message->ListEntry);
792 
793  ExFreeToPagedLookasideList(pgSendMsgLookasideList, Message);
794  SendMsgCount--;
795 }
796 
799 {
800  PTHREADINFO pti;
801  PUSER_SENT_MESSAGE SentMessage;
802  PUSER_MESSAGE PostedMessage;
803  PLIST_ENTRY CurrentEntry, ListHead;
804 
805  ASSERT(Window);
806 
807  pti = Window->head.pti;
808 
809  /* remove the posted messages for this window */
810  CurrentEntry = pti->PostedMessagesListHead.Flink;
811  ListHead = &pti->PostedMessagesListHead;
812  while (CurrentEntry != ListHead)
813  {
814  PostedMessage = CONTAINING_RECORD(CurrentEntry, USER_MESSAGE, ListEntry);
815 
816  if (PostedMessage->Msg.hwnd == Window->head.h)
817  {
818  if (PostedMessage->Msg.message == WM_QUIT && pti->QuitPosted == 0)
819  {
820  pti->QuitPosted = 1;
821  pti->exitCode = PostedMessage->Msg.wParam;
822  }
823  ClearMsgBitsMask(pti, PostedMessage->QS_Flags);
824  MsqDestroyMessage(PostedMessage);
825  CurrentEntry = pti->PostedMessagesListHead.Flink;
826  }
827  else
828  {
829  CurrentEntry = CurrentEntry->Flink;
830  }
831  }
832 
833  /* remove the sent messages for this window */
834  CurrentEntry = pti->SentMessagesListHead.Flink;
835  ListHead = &pti->SentMessagesListHead;
836  while (CurrentEntry != ListHead)
837  {
838  SentMessage = CONTAINING_RECORD(CurrentEntry, USER_SENT_MESSAGE, ListEntry);
839 
840  if(SentMessage->Msg.hwnd == Window->head.h)
841  {
842  ERR("Remove Window Messages %p From Sent Queue\n",SentMessage);
843 #if 0 // Should mark these as invalid and allow the rest clean up, so far no harm by just commenting out. See CORE-9210.
844  ClearMsgBitsMask(pti, SentMessage->QS_Flags);
845 
846  /* wake the sender's thread */
847  if (SentMessage->pkCompletionEvent != NULL)
848  {
850  }
851 
852  if (SentMessage->HasPackedLParam)
853  {
854  if (SentMessage->Msg.lParam)
855  ExFreePool((PVOID)SentMessage->Msg.lParam);
856  }
857 
858  /* free the message */
859  FreeUserMessage(SentMessage);
860 
861  CurrentEntry = pti->SentMessagesListHead.Flink;
862 #endif
863  CurrentEntry = CurrentEntry->Flink;
864  }
865  else
866  {
867  CurrentEntry = CurrentEntry->Flink;
868  }
869  }
870 }
871 
874  _In_ PTHREADINFO pti)
875 {
876  PUSER_SENT_MESSAGE SaveMsg, Message;
878  BOOL Ret;
879  LRESULT Result = 0;
880 
882 
883  if (IsListEmpty(&pti->SentMessagesListHead))
884  {
885  return(FALSE);
886  }
887 
888  /* remove it from the list of pending messages */
889  Entry = RemoveHeadList(&pti->SentMessagesListHead);
891 
892  // Signal this message is being processed.
894 
895  SaveMsg = pti->pusmCurrent;
896  pti->pusmCurrent = Message;
897 
898  // Processing a message sent to it from another thread.
899  if ( ( Message->ptiSender && pti != Message->ptiSender) ||
900  ( Message->ptiCallBackSender && pti != Message->ptiCallBackSender ))
901  { // most likely, but, to be sure.
902  pti->pcti->CTI_flags |= CTI_INSENDMESSAGE; // Let the user know...
903  }
904 
905  /* Now insert it to the global list of messages that can be removed Justin Case there's Trouble */
906  InsertTailList(&usmList, &Message->ListEntry);
907 
908  ClearMsgBitsMask(pti, Message->QS_Flags);
909 
910  if (Message->HookMessage == MSQ_ISHOOK)
911  { // Direct Hook Call processor
912  Result = co_CallHook( Message->Msg.message, // HookId
913  (INT)(INT_PTR)Message->Msg.hwnd, // Code
914  Message->Msg.wParam,
915  Message->Msg.lParam);
916  }
917  else if(Message->HookMessage == MSQ_INJECTMODULE)
918  {
919  Result = IntLoadHookModule(Message->Msg.message,
920  (HHOOK)Message->Msg.lParam,
921  Message->Msg.wParam);
922  }
923  else if ((Message->CompletionCallback) &&
924  (Message->ptiCallBackSender == pti))
925  { /* Call the callback routine */
926  if (Message->QS_Flags & QS_SMRESULT)
927  {
928  co_IntCallSentMessageCallback(Message->CompletionCallback,
929  Message->Msg.hwnd,
930  Message->Msg.message,
931  Message->CompletionCallbackContext,
932  Message->lResult);
933  /* Set callback to NULL to prevent reentry */
934  Message->CompletionCallback = NULL;
935  }
936  else
937  {
938  /* The message has not been processed yet, reinsert it. */
939  RemoveEntryList(&Message->ListEntry);
940  InsertTailList(&Message->ptiCallBackSender->SentMessagesListHead, &Message->ListEntry);
941  // List is occupied need to set the bit.
942  MsqWakeQueue(Message->ptiCallBackSender, QS_SENDMESSAGE, TRUE);
943  ERR("Callback Message not processed yet. Requeuing the message\n");
944  Ret = FALSE;
945  goto Exit;
946  }
947  }
948  else
949  { /* Call the window procedure. */
950  Result = co_IntSendMessage( Message->Msg.hwnd,
951  Message->Msg.message,
952  Message->Msg.wParam,
953  Message->Msg.lParam);
954  }
955 
956  /* If the message is a callback, insert it in the callback senders MessageQueue */
957  if (Message->CompletionCallback)
958  {
959  if (Message->ptiCallBackSender)
960  {
961  Message->lResult = Result;
962  Message->QS_Flags |= QS_SMRESULT;
963 
964  /* insert it in the callers message queue */
965  RemoveEntryList(&Message->ListEntry);
966  InsertTailList(&Message->ptiCallBackSender->SentMessagesListHead, &Message->ListEntry);
967  MsqWakeQueue(Message->ptiCallBackSender, QS_SENDMESSAGE, TRUE);
968  }
969  Ret = TRUE;
970  goto Exit;
971  }
972 
973  // Retrieve the result from callback.
974  if (Message->QS_Flags & QS_SMRESULT)
975  {
976  Result = Message->lResult;
977  }
978 
979  /* Let the sender know the result. */
980  Message->lResult = Result;
981 
982  if (Message->HasPackedLParam)
983  {
984  if (Message->Msg.lParam)
985  ExFreePool((PVOID)Message->Msg.lParam);
986  }
987 
988  // Clear busy signal.
989  Message->flags &= ~SMF_RECEIVERBUSY;
990 
991  /* Notify the sender. */
992  if (Message->pkCompletionEvent != NULL)
993  {
994  KeSetEvent(Message->pkCompletionEvent, IO_NO_INCREMENT, FALSE);
995  }
996 
997  /* free the message */
998  if (Message->flags & SMF_RECEIVERFREE)
999  {
1000  TRACE("Receiver Freeing Message %p\n",Message);
1002  }
1003 
1004  Ret = TRUE;
1005 Exit:
1006  /* do not hangup on the user if this is reentering */
1007  if (!SaveMsg) pti->pcti->CTI_flags &= ~CTI_INSENDMESSAGE;
1008  pti->pusmCurrent = SaveMsg;
1009 
1010  return Ret;
1011 }
1012 
1013 BOOL FASTCALL
1015  HWND hwnd,
1016  UINT Msg,
1017  WPARAM wParam,
1018  LPARAM lParam,
1020  ULONG_PTR CompletionCallbackContext,
1021  BOOL HasPackedLParam,
1022  INT HookMessage)
1023 {
1024 
1025  PTHREADINFO ptiSender;
1027 
1029  {
1030  ERR("MsqSendMessageAsync(): Not enough memory to allocate a message");
1031  return FALSE;
1032  }
1033 
1034  ptiSender = PsGetCurrentThreadWin32Thread();
1035 
1036  Message->Msg.hwnd = hwnd;
1037  Message->Msg.message = Msg;
1038  Message->Msg.wParam = wParam;
1039  Message->Msg.lParam = lParam;
1040  Message->pkCompletionEvent = NULL; // No event needed.
1041  Message->ptiReceiver = ptiReceiver;
1042  Message->ptiCallBackSender = ptiSender;
1043  Message->CompletionCallback = CompletionCallback;
1044  Message->CompletionCallbackContext = CompletionCallbackContext;
1045  Message->HookMessage = HookMessage;
1046  Message->HasPackedLParam = HasPackedLParam;
1047  Message->QS_Flags = QS_SENDMESSAGE;
1048  Message->flags = SMF_RECEIVERFREE;
1049 
1050  InsertTailList(&ptiReceiver->SentMessagesListHead, &Message->ListEntry);
1051  MsqWakeQueue(ptiReceiver, QS_SENDMESSAGE, TRUE);
1052 
1053  return TRUE;
1054 }
1055 
1058  HWND Wnd,
1059  UINT Msg,
1060  WPARAM wParam,
1061  LPARAM lParam,
1062  UINT uTimeout,
1063  BOOL Block,
1064  INT HookMessage,
1065  ULONG_PTR *uResult)
1066 {
1067  PTHREADINFO pti;
1068  PUSER_SENT_MESSAGE SaveMsg, Message;
1069  NTSTATUS WaitStatus;
1072  PWND pWnd;
1073  BOOLEAN SwapStateEnabled;
1074  LRESULT Result = 0;
1075 
1077  ASSERT(pti != ptirec);
1078  ASSERT(ptirec->pcti); // Send must have a client side to receive it!!!!
1079 
1080  /* Don't send from or to a dying thread */
1081  if (pti->TIF_flags & TIF_INCLEANUP || ptirec->TIF_flags & TIF_INCLEANUP)
1082  {
1083  // Unless we are dying and need to tell our parents.
1084  if (pti->TIF_flags & TIF_INCLEANUP && !(ptirec->TIF_flags & TIF_INCLEANUP))
1085  {
1086  // Parent notify is the big one. Fire and forget!
1087  TRACE("Send message from dying thread %u\n", Msg);
1088  co_MsqSendMessageAsync(ptirec, Wnd, Msg, wParam, lParam, NULL, 0, FALSE, HookMessage);
1089  }
1090  if (uResult) *uResult = -1;
1091  TRACE("MsqSM: Msg %u Current pti %lu or Rec pti %lu\n", Msg, pti->TIF_flags & TIF_INCLEANUP, ptirec->TIF_flags & TIF_INCLEANUP);
1092  return STATUS_UNSUCCESSFUL;
1093  }
1094 
1095  if (IsThreadSuspended(ptirec))
1096  {
1097  ERR("Sending to Suspended Thread Msg %lx\n",Msg);
1098  if (uResult) *uResult = -1;
1099  return STATUS_UNSUCCESSFUL;
1100  }
1101 
1102  // Should we do the same for No Wait?
1103  if ( HookMessage == MSQ_NORMAL )
1104  {
1105  pWnd = ValidateHwndNoErr(Wnd);
1106 
1107  // These can not cross International Border lines!
1108  if ( pti->ppi != ptirec->ppi && pWnd )
1109  {
1110  switch(Msg)
1111  {
1112  // Handle the special case when working with password transfers across bordering processes.
1113  case EM_GETLINE:
1114  case EM_SETPASSWORDCHAR:
1115  case WM_GETTEXT:
1116  // Look for edit controls setup for passwords.
1117  if ( gpsi->atomSysClass[ICLS_EDIT] == pWnd->pcls->atomClassName && // Use atomNVClassName.
1118  pWnd->style & ES_PASSWORD )
1119  {
1120  if (uResult) *uResult = -1;
1121  ERR("Running across the border without a passport!\n");
1123  return STATUS_UNSUCCESSFUL;
1124  }
1125  break;
1126  case WM_NOTIFY:
1127  if (uResult) *uResult = -1;
1128  ERR("Running across the border without a passport!\n");
1129  return STATUS_UNSUCCESSFUL;
1130  }
1131  }
1132 
1133  // These can not cross State lines!
1134  if ( Msg == WM_CREATE || Msg == WM_NCCREATE )
1135  {
1136  if (uResult) *uResult = -1;
1137  ERR("Can not tell the other State we have Create!\n");
1138  return STATUS_UNSUCCESSFUL;
1139  }
1140  }
1141 
1142  if(!(Message = AllocateUserMessage(TRUE)))
1143  {
1144  ERR("MsqSendMessage(): Not enough memory to allocate a message\n");
1145  if (uResult) *uResult = -1;
1147  }
1148 
1149  Timeout.QuadPart = Int32x32To64(-10000,uTimeout); // Pass SMTO test with a TO of 0x80000000.
1150  TRACE("Timeout val %lld\n",Timeout.QuadPart);
1151 
1152  Message->Msg.hwnd = Wnd;
1153  Message->Msg.message = Msg;
1154  Message->Msg.wParam = wParam;
1155  Message->Msg.lParam = lParam;
1156  Message->ptiReceiver = ptirec;
1157  Message->ptiSender = pti;
1158  Message->HookMessage = HookMessage;
1159  Message->QS_Flags = QS_SENDMESSAGE;
1160 
1161  SaveMsg = pti->pusmSent;
1162  pti->pusmSent = Message;
1163 
1164  /* Queue it in the destination's message queue */
1165  InsertTailList(&ptirec->SentMessagesListHead, &Message->ListEntry);
1166 
1167  MsqWakeQueue(ptirec, QS_SENDMESSAGE, TRUE);
1168 
1169  // First time in, turn off swapping of the stack.
1170  if (pti->cEnterCount == 0)
1171  {
1172  SwapStateEnabled = KeSetKernelStackSwapEnable(FALSE);
1173  }
1174  pti->cEnterCount++;
1175 
1176  if (Block)
1177  {
1178  PVOID WaitObjects[2];
1179 
1180  WaitObjects[0] = Message->pkCompletionEvent; // Wait 0
1181  WaitObjects[1] = ptirec->pEThread; // Wait 1
1182 
1183  UserLeaveCo();
1184 
1185  WaitStatus = KeWaitForMultipleObjects( 2,
1186  WaitObjects,
1187  WaitAny,
1188  UserRequest,
1189  UserMode,
1190  FALSE,
1191  (uTimeout ? &Timeout : NULL),
1192  NULL );
1193 
1194  UserEnterCo();
1195 
1196  if (WaitStatus == STATUS_TIMEOUT)
1197  {
1198  /* Look up if the message has not yet dispatched, if so
1199  make sure it can't pass a result and it must not set the completion event anymore */
1200  Entry = ptirec->SentMessagesListHead.Flink;
1201  while (Entry != &ptirec->SentMessagesListHead)
1202  {
1203  if (CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, ListEntry) == Message)
1204  {
1205  Message->pkCompletionEvent = NULL;
1206  RemoveEntryList(&Message->ListEntry);
1207  ClearMsgBitsMask(ptirec, Message->QS_Flags);
1208  InsertTailList(&usmList, &Message->ListEntry);
1209  break;
1210  }
1211  Entry = Entry->Flink;
1212  }
1213 
1214  ERR("MsqSendMessage (blocked) timed out 1 Status %lx\n", WaitStatus);
1215  }
1216  // Receiving thread passed on and left us hanging with issues still pending.
1217  else if (WaitStatus == STATUS_WAIT_1)
1218  {
1219  ERR("Bk Receiving Thread woken up dead!\n");
1220  Message->flags |= SMF_RECEIVERDIED;
1221  }
1222 
1223  while (co_MsqDispatchOneSentMessage(pti))
1224  ;
1225  }
1226  else
1227  {
1228  PVOID WaitObjects[3];
1229 
1230  WaitObjects[0] = Message->pkCompletionEvent; // Wait 0
1231  WaitObjects[1] = pti->pEventQueueServer; // Wait 1
1232  WaitObjects[2] = ptirec->pEThread; // Wait 2
1233 
1234  do
1235  {
1236  UserLeaveCo();
1237 
1238  WaitStatus = KeWaitForMultipleObjects( 3,
1239  WaitObjects,
1240  WaitAny,
1241  UserRequest,
1242  UserMode,
1243  FALSE,
1244  (uTimeout ? &Timeout : NULL),
1245  NULL);
1246 
1247  UserEnterCo();
1248 
1249  if (WaitStatus == STATUS_TIMEOUT)
1250  {
1251  /* Look up if the message has not yet been dispatched, if so
1252  make sure it can't pass a result and it must not set the completion event anymore */
1253  Entry = ptirec->SentMessagesListHead.Flink;
1254  while (Entry != &ptirec->SentMessagesListHead)
1255  {
1256  if (CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, ListEntry) == Message)
1257  {
1258  Message->pkCompletionEvent = NULL;
1259  RemoveEntryList(&Message->ListEntry);
1260  ClearMsgBitsMask(ptirec, Message->QS_Flags);
1261  InsertTailList(&usmList, &Message->ListEntry);
1262  break;
1263  }
1264  Entry = Entry->Flink;
1265  }
1266 
1267  ERR("MsqSendMessage timed out 2 Status %lx\n", WaitStatus);
1268  break;
1269  }
1270  // Receiving thread passed on and left us hanging with issues still pending.
1271  else if (WaitStatus == STATUS_WAIT_2)
1272  {
1273  ERR("NB Receiving Thread woken up dead!\n");
1274  Message->flags |= SMF_RECEIVERDIED;
1275  break;
1276  }
1277 
1278  if (WaitStatus == STATUS_USER_APC) break;
1279 
1280  while (co_MsqDispatchOneSentMessage(pti))
1281  ;
1282  } while (WaitStatus == STATUS_WAIT_1);
1283  }
1284 
1285  // Count is nil, restore swapping of the stack.
1286  if (--pti->cEnterCount == 0 )
1287  {
1288  KeSetKernelStackSwapEnable(SwapStateEnabled);
1289  }
1290 
1291  // Handle User APC
1292  if (WaitStatus == STATUS_USER_APC)
1293  {
1294  // The current thread is dying!
1295  TRACE("User APC\n");
1296 
1297  // The Message will be on the Trouble list until Thread cleanup.
1298  Message->flags |= SMF_SENDERDIED;
1299 
1301  ERR("User APC Returned\n"); // Should not see this message.
1302  }
1303 
1304  // Force this thread to wake up for the next go around.
1306 
1307  Result = Message->lResult;
1308 
1309  // Determine whether this message is being processed or not.
1311  {
1312  Message->flags |= SMF_RECEIVERFREE;
1313  }
1314 
1315  if (!(Message->flags & SMF_RECEIVERFREE))
1316  {
1317  TRACE("Sender Freeing Message %p ptirec %p bit %d list empty %d\n",Message,ptirec,!!(ptirec->pcti->fsChangeBits & QS_SENDMESSAGE),IsListEmpty(&ptirec->SentMessagesListHead));
1318  // Make it to this point, the message was received.
1320  }
1321 
1322  pti->pusmSent = SaveMsg;
1323 
1324  TRACE("MSM Allocation Count %d Status %lx Result %d\n",SendMsgCount,WaitStatus,Result);
1325 
1326  if (WaitStatus != STATUS_TIMEOUT)
1327  {
1328  if (uResult)
1329  {
1330  *uResult = (STATUS_WAIT_0 == WaitStatus ? Result : 0);
1331  }
1332  }
1333 
1334  return WaitStatus;
1335 }
1336 
1337 VOID FASTCALL
1339  MSG* Msg,
1340  BOOLEAN HardwareMessage,
1341  DWORD MessageBits,
1342  DWORD dwQEvent,
1343  LONG_PTR ExtraInfo)
1344 {
1346  PUSER_MESSAGE_QUEUE MessageQueue;
1347 
1348  if ( pti->TIF_flags & TIF_INCLEANUP || pti->MessageQueue->QF_flags & QF_INDESTROY )
1349  {
1350  ERR("Post Msg; Thread or Q is Dead!\n");
1351  return;
1352  }
1353 
1354  if(!(Message = MsqCreateMessage(Msg)))
1355  {
1356  return;
1357  }
1358 
1359  MessageQueue = pti->MessageQueue;
1360 
1361  if (!HardwareMessage)
1362  {
1363  InsertTailList(&pti->PostedMessagesListHead, &Message->ListEntry);
1364  }
1365  else
1366  {
1367  InsertTailList(&MessageQueue->HardwareMessagesListHead, &Message->ListEntry);
1368  }
1369 
1370  if (Msg->message == WM_HOTKEY) MessageBits |= QS_HOTKEY; // Justin Case, just set it.
1371  Message->dwQEvent = dwQEvent;
1372  Message->ExtraInfo = ExtraInfo;
1373  Message->QS_Flags = MessageBits;
1374  Message->pti = pti;
1375  MsqWakeQueue(pti, MessageBits, TRUE);
1376  TRACE("Post Message %d\n",PostMsgCount);
1377 }
1378 
1379 VOID FASTCALL
1381 {
1382  pti->QuitPosted = TRUE;
1383  pti->exitCode = ExitCode;
1385 }
1386 
1387 /***********************************************************************
1388  * MsqSendParentNotify
1389  *
1390  * Send a WM_PARENTNOTIFY to all ancestors of the given window, unless
1391  * the window has the WS_EX_NOPARENTNOTIFY style.
1392  */
1393 static void MsqSendParentNotify( PWND pwnd, WORD event, WORD idChild, POINT pt )
1394 {
1395  PWND pwndDesktop = UserGetDesktopWindow();
1396 
1397  /* pt has to be in the client coordinates of the parent window */
1398  pt.x += pwndDesktop->rcClient.left - pwnd->rcClient.left;
1399  pt.y += pwndDesktop->rcClient.top - pwnd->rcClient.top;
1400 
1401  for (;;)
1402  {
1403  PWND pwndParent;
1404 
1405  if (!(pwnd->style & WS_CHILD)) break;
1406  if (pwnd->ExStyle & WS_EX_NOPARENTNOTIFY) break;
1407  if (!(pwndParent = IntGetParent(pwnd))) break;
1408  if (pwndParent == pwndDesktop) break;
1409  pt.x += pwnd->rcClient.left - pwndParent->rcClient.left;
1410  pt.y += pwnd->rcClient.top - pwndParent->rcClient.top;
1411 
1412  pwnd = pwndParent;
1414  MAKEWPARAM( event, idChild ), MAKELPARAM( pt.x, pt.y ) );
1415  }
1416 }
1417 
1418 VOID
1419 FASTCALL
1420 IntTrackMouseMove(PWND pwndTrack, PDESKTOP pDesk, PMSG msg, USHORT hittest)
1421 {
1422 // PWND pwndTrack = IntChildrenWindowFromPoint(pwndMsg, msg->pt.x, msg->pt.y);
1423 // hittest = (USHORT)GetNCHitEx(pwndTrack, msg->pt); /// @todo WTF is this???
1424 
1425  if ( pDesk->spwndTrack != pwndTrack || // Change with tracking window or
1426  msg->message != WM_MOUSEMOVE || // Mouse click changes or
1427  pDesk->htEx != hittest) // Change in current hit test states.
1428  {
1429  TRACE("ITMM: Track Mouse Move!\n");
1430 
1431  /* Handle only the changing window track and mouse move across a border. */
1432  if ( pDesk->spwndTrack != pwndTrack ||
1433  (pDesk->htEx == HTCLIENT) ^ (hittest == HTCLIENT) )
1434  {
1435  TRACE("ITMM: Another Wnd %d or Across Border %d\n",
1436  pDesk->spwndTrack != pwndTrack,(pDesk->htEx == HTCLIENT) ^ (hittest == HTCLIENT));
1437 
1438  if ( pDesk->dwDTFlags & DF_TME_LEAVE )
1440  (pDesk->htEx != HTCLIENT) ? WM_NCMOUSELEAVE : WM_MOUSELEAVE,
1441  0, 0);
1442 
1443  if ( pDesk->dwDTFlags & DF_TME_HOVER )
1445 
1446  /* Clear the flags to sign a change. */
1447  pDesk->dwDTFlags &= ~(DF_TME_LEAVE|DF_TME_HOVER);
1448  }
1449  /* Set the Track window and hit test. */
1450  pDesk->spwndTrack = pwndTrack;
1451  pDesk->htEx = hittest;
1452  }
1453 
1454  /* Reset, Same Track window, Hover set and Mouse Clicks or Clobbered Hover box. */
1455  if ( pDesk->spwndTrack == pwndTrack &&
1456  ( msg->message != WM_MOUSEMOVE || !RECTL_bPointInRect(&pDesk->rcMouseHover, msg->pt.x, msg->pt.y)) &&
1457  pDesk->dwDTFlags & DF_TME_HOVER )
1458  {
1459  TRACE("ITMM: Reset Hover points!\n");
1460  // Restart timer for the hover period.
1462  // Reset desktop mouse hover from the system default hover rectangle.
1463  RECTL_vSetRect(&pDesk->rcMouseHover,
1464  msg->pt.x - gspv.iMouseHoverWidth / 2,
1465  msg->pt.y - gspv.iMouseHoverHeight / 2,
1466  msg->pt.x + gspv.iMouseHoverWidth / 2,
1467  msg->pt.y + gspv.iMouseHoverHeight / 2);
1468  }
1469 }
1470 
1471 BOOL co_IntProcessMouseMessage(MSG* msg, BOOL* RemoveMessages, BOOL* NotForUs, LONG_PTR ExtraInfo, UINT first, UINT last)
1472 {
1473  MSG clk_msg;
1474  POINT pt;
1475  UINT message;
1476  USHORT hittest;
1477  EVENTMSG event;
1479  BOOL eatMsg = FALSE;
1480 
1481  PWND pwndMsg, pwndDesktop;
1482  PUSER_MESSAGE_QUEUE MessageQueue;
1483  PTHREADINFO pti;
1484  PSYSTEM_CURSORINFO CurInfo;
1485  PDESKTOP pDesk;
1486 
1488  pwndDesktop = UserGetDesktopWindow();
1489  MessageQueue = pti->MessageQueue;
1490  CurInfo = IntGetSysCursorInfo();
1491  pwndMsg = ValidateHwndNoErr(msg->hwnd);
1492  clk_msg = MessageQueue->msgDblClk;
1493  pDesk = pwndDesktop->head.rpdesk;
1494 
1495  /* find the window to dispatch this mouse message to */
1496  if (MessageQueue->spwndCapture)
1497  {
1498  hittest = HTCLIENT;
1499  pwndMsg = MessageQueue->spwndCapture;
1500  }
1501  else
1502  {
1503  /*
1504  Start with null window. See wine win.c:test_mouse_input:WM_COMMAND tests.
1505  */
1506  pwndMsg = co_WinPosWindowFromPoint( NULL, &msg->pt, &hittest, FALSE);
1507  }
1508 
1509  TRACE("Got mouse message for %p, hittest: 0x%x\n", msg->hwnd, hittest);
1510 
1511  // Null window or not the same "Hardware" message queue.
1512  if (pwndMsg == NULL || pwndMsg->head.pti->MessageQueue != MessageQueue)
1513  {
1514  // Crossing a boundary, so set cursor. See default message queue cursor.
1515  IntSystemSetCursor(SYSTEMCUR(ARROW));
1516  /* Remove and ignore the message */
1517  *RemoveMessages = TRUE;
1518  return FALSE;
1519  }
1520 
1521  // Check to see if this is attached,
1522  if ( pwndMsg->head.pti != pti && // window thread is not current,
1523  MessageQueue->cThreads > 1 ) // and is attached...
1524  {
1525  // This is not for us and we should leave so the other thread can check for messages!!!
1526  *NotForUs = TRUE;
1527  *RemoveMessages = TRUE;
1528  return FALSE;
1529  }
1530 
1531  if ( MessageQueue == gpqCursor ) // Cursor must use the same Queue!
1532  {
1533  IntTrackMouseMove(pwndMsg, pDesk, msg, hittest);
1534  }
1535  else
1536  {
1537  ERR("Not the same cursor!\n");
1538  }
1539 
1540  msg->hwnd = UserHMGetHandle(pwndMsg);
1541 
1542  pt = msg->pt;
1543  message = msg->message;
1544 
1545  /* Note: windows has no concept of a non-client wheel message */
1546  if (message != WM_MOUSEWHEEL)
1547  {
1548  if (hittest != HTCLIENT)
1549  {
1551  msg->wParam = hittest; // Caution! This might break wParam check in DblClk.
1552  }
1553  else
1554  {
1555  /* coordinates don't get translated while tracking a menu */
1556  /* FIXME: should differentiate popups and top-level menus */
1557  if (!(MessageQueue->MenuOwner))
1558  {
1559  pt.x += pwndDesktop->rcClient.left - pwndMsg->rcClient.left;
1560  pt.y += pwndDesktop->rcClient.top - pwndMsg->rcClient.top;
1561  }
1562  }
1563  }
1564  msg->lParam = MAKELONG( pt.x, pt.y );
1565 
1566  /* translate double clicks */
1567 
1568  if ((msg->message == WM_LBUTTONDOWN) ||
1569  (msg->message == WM_RBUTTONDOWN) ||
1570  (msg->message == WM_MBUTTONDOWN) ||
1571  (msg->message == WM_XBUTTONDOWN))
1572  {
1573  BOOL update = *RemoveMessages;
1574 
1575  /* translate double clicks -
1576  * note that ...MOUSEMOVEs can slip in between
1577  * ...BUTTONDOWN and ...BUTTONDBLCLK messages */
1578 
1579  if ((MessageQueue->MenuOwner || MessageQueue->MoveSize) ||
1580  hittest != HTCLIENT ||
1581  (pwndMsg->pcls->style & CS_DBLCLKS))
1582  {
1583  if ((msg->message == clk_msg.message) &&
1584  (msg->hwnd == clk_msg.hwnd) &&
1585  // Only worry about XButton wParam.
1586  (msg->message != WM_XBUTTONDOWN || GET_XBUTTON_WPARAM(msg->wParam) == GET_XBUTTON_WPARAM(clk_msg.wParam)) &&
1587  ((msg->time - clk_msg.time) < (ULONG)gspv.iDblClickTime) &&
1588  (abs(msg->pt.x - clk_msg.pt.x) < UserGetSystemMetrics(SM_CXDOUBLECLK)/2) &&
1589  (abs(msg->pt.y - clk_msg.pt.y) < UserGetSystemMetrics(SM_CYDOUBLECLK)/2))
1590  {
1592  if (update)
1593  {
1594  MessageQueue->msgDblClk.message = 0; /* clear the double click conditions */
1595  update = FALSE;
1596  }
1597  }
1598  }
1599 
1600  if (!((first == 0 && last == 0) || (message >= first || message <= last)))
1601  {
1602  TRACE("Message out of range!!!\n");
1603  return FALSE;
1604  }
1605 
1606  /* update static double click conditions */
1607  if (update) MessageQueue->msgDblClk = *msg;
1608  }
1609  else
1610  {
1611  if (!((first == 0 && last == 0) || (message >= first || message <= last)))
1612  {
1613  TRACE("Message out of range!!!\n");
1614  return FALSE;
1615  }
1616 
1617  // Update mouse move down keys.
1618  if (message == WM_MOUSEMOVE)
1619  {
1620  msg->wParam = MsqGetDownKeyState(MessageQueue);
1621  }
1622  }
1623 
1624  if (gspv.bMouseClickLock)
1625  {
1626  BOOL IsClkLck = FALSE;
1627 
1628  if(msg->message == WM_LBUTTONUP)
1629  {
1630  IsClkLck = ((msg->time - CurInfo->ClickLockTime) >= gspv.dwMouseClickLockTime);
1631  if (IsClkLck && (!CurInfo->ClickLockActive))
1632  {
1633  CurInfo->ClickLockActive = TRUE;
1634  }
1635  }
1636  else if (msg->message == WM_LBUTTONDOWN)
1637  {
1638  if (CurInfo->ClickLockActive)
1639  {
1640  IsClkLck = TRUE;
1641  CurInfo->ClickLockActive = FALSE;
1642  }
1643 
1644  CurInfo->ClickLockTime = msg->time;
1645  }
1646 
1647  if(IsClkLck)
1648  {
1649  /* Remove and ignore the message */
1650  *RemoveMessages = TRUE;
1651  TRACE("Remove and ignore the message\n");
1652  return FALSE;
1653  }
1654  }
1655 
1656  if (pti->TIF_flags & TIF_MSGPOSCHANGED)
1657  {
1658  pti->TIF_flags &= ~TIF_MSGPOSCHANGED;
1659  IntNotifyWinEvent(EVENT_OBJECT_LOCATIONCHANGE, NULL, OBJID_CLIENT, CHILDID_SELF, 0);
1660  }
1661 
1662  /* message is accepted now (but still get dropped) */
1663 
1664  event.message = msg->message;
1665  event.time = msg->time;
1666  event.hwnd = msg->hwnd;
1667  event.paramL = msg->pt.x;
1668  event.paramH = msg->pt.y;
1670 
1671  hook.pt = msg->pt;
1672  hook.hwnd = msg->hwnd;
1673  hook.wHitTestCode = hittest;
1674  hook.dwExtraInfo = ExtraInfo;
1675  if (co_HOOK_CallHooks( WH_MOUSE, *RemoveMessages ? HC_ACTION : HC_NOREMOVE,
1676  message, (LPARAM)&hook ))
1677  {
1678  hook.pt = msg->pt;
1679  hook.hwnd = msg->hwnd;
1680  hook.wHitTestCode = hittest;
1681  hook.dwExtraInfo = ExtraInfo;
1683 
1684  ERR("WH_MOUSE dropped mouse message!\n");
1685 
1686  /* Remove and skip message */
1687  *RemoveMessages = TRUE;
1688  return FALSE;
1689  }
1690 
1691  if ((hittest == (USHORT)HTERROR) || (hittest == (USHORT)HTNOWHERE))
1692  {
1693  co_IntSendMessage( msg->hwnd, WM_SETCURSOR, (WPARAM)msg->hwnd, MAKELONG( hittest, msg->message ));
1694 
1695  /* Remove and skip message */
1696  *RemoveMessages = TRUE;
1697  return FALSE;
1698  }
1699 
1700  if ((*RemoveMessages == FALSE) || MessageQueue->spwndCapture)
1701  {
1702  /* Accept the message */
1703  msg->message = message;
1704  return TRUE;
1705  }
1706 
1707  if ((msg->message == WM_LBUTTONDOWN) ||
1708  (msg->message == WM_RBUTTONDOWN) ||
1709  (msg->message == WM_MBUTTONDOWN) ||
1710  (msg->message == WM_XBUTTONDOWN))
1711  {
1712  /* Send the WM_PARENTNOTIFY,
1713  * note that even for double/nonclient clicks
1714  * notification message is still WM_L/M/RBUTTONDOWN.
1715  */
1716  MsqSendParentNotify(pwndMsg, msg->message, 0, msg->pt );
1717 
1718  /* Activate the window if needed */
1719 
1720  if (pwndMsg != MessageQueue->spwndActive)
1721  {
1722  PWND pwndTop = pwndMsg;
1723  pwndTop = IntGetNonChildAncestor(pwndTop);
1724 
1725  TRACE("Mouse pti %p pwndMsg pti %p pwndTop pti %p\n",MessageQueue->ptiMouse,pwndMsg->head.pti,pwndTop->head.pti);
1726 
1727  if (pwndTop && pwndTop != pwndDesktop)
1728  {
1729  LONG ret = co_IntSendMessage( msg->hwnd,
1731  (WPARAM)UserHMGetHandle(pwndTop),
1732  MAKELONG( hittest, msg->message));
1733  switch(ret)
1734  {
1735  case MA_NOACTIVATEANDEAT:
1736  eatMsg = TRUE;
1737  /* fall through */
1738  case MA_NOACTIVATE:
1739  break;
1740  case MA_ACTIVATEANDEAT:
1741  eatMsg = TRUE;
1742  /* fall through */
1743  case MA_ACTIVATE:
1744  case 0:
1745  if (!co_IntMouseActivateWindow( pwndTop )) eatMsg = TRUE;
1746  break;
1747  default:
1748  ERR( "unknown WM_MOUSEACTIVATE code %d\n", ret );
1749  break;
1750  }
1751  }
1752  }
1753  }
1754 
1755  /* send the WM_SETCURSOR message */
1756 
1757  /* Windows sends the normal mouse message as the message parameter
1758  in the WM_SETCURSOR message even if it's non-client mouse message */
1759  co_IntSendMessage( msg->hwnd, WM_SETCURSOR, (WPARAM)msg->hwnd, MAKELONG( hittest, msg->message ));
1760 
1761  msg->message = message;
1762  return !eatMsg;
1763 }
1764 
1766 {
1767  EVENTMSG Event;
1769  PWND pWnd;
1770  UINT ImmRet;
1771  BOOL Ret = TRUE;
1772  WPARAM wParam = Msg->wParam;
1774 
1775  if (Msg->message == VK_PACKET)
1776  {
1777  pti->wchInjected = HIWORD(Msg->wParam);
1778  }
1779 
1780  if (Msg->message == WM_KEYDOWN || Msg->message == WM_SYSKEYDOWN ||
1781  Msg->message == WM_KEYUP || Msg->message == WM_SYSKEYUP)
1782  {
1783  switch (Msg->wParam)
1784  {
1785  case VK_LSHIFT: case VK_RSHIFT:
1786  Msg->wParam = VK_SHIFT;
1787  break;
1788  case VK_LCONTROL: case VK_RCONTROL:
1789  Msg->wParam = VK_CONTROL;
1790  break;
1791  case VK_LMENU: case VK_RMENU:
1792  Msg->wParam = VK_MENU;
1793  break;
1794  }
1795  }
1796 
1797  pWnd = ValidateHwndNoErr(Msg->hwnd);
1798  if (pWnd) UserRefObjectCo(pWnd, &Ref);
1799 
1800  Event.message = Msg->message;
1801  Event.hwnd = Msg->hwnd;
1802  Event.time = Msg->time;
1803  Event.paramL = (Msg->wParam & 0xFF) | (HIWORD(Msg->lParam) << 8);
1804  Event.paramH = Msg->lParam & 0x7FFF;
1805  if (HIWORD(Msg->lParam) & 0x0100) Event.paramH |= 0x8000;
1807 
1808  if (*RemoveMessages)
1809  {
1810  if ((Msg->message == WM_KEYDOWN) &&
1811  (Msg->hwnd != IntGetDesktopWindow()))
1812  {
1813  /* Handle F1 key by sending out WM_HELP message */
1814  if (Msg->wParam == VK_F1)
1815  {
1816  UserPostMessage( Msg->hwnd, WM_KEYF1, 0, 0 );
1817  }
1818  else if (Msg->wParam >= VK_BROWSER_BACK &&
1819  Msg->wParam <= VK_LAUNCH_APP2)
1820  {
1821  /* FIXME: Process keystate */
1822  co_IntSendMessage(Msg->hwnd, WM_APPCOMMAND, (WPARAM)Msg->hwnd, MAKELPARAM(0, (FAPPCOMMAND_KEY | (Msg->wParam - VK_BROWSER_BACK + 1))));
1823  }
1824  }
1825  else if (Msg->message == WM_KEYUP)
1826  {
1827  /* Handle VK_APPS key by posting a WM_CONTEXTMENU message */
1828  if (Msg->wParam == VK_APPS && pti->MessageQueue->MenuOwner == NULL)
1829  UserPostMessage( Msg->hwnd, WM_CONTEXTMENU, (WPARAM)Msg->hwnd, -1 );
1830  }
1831  }
1832 
1834  if ( *RemoveMessages && Msg->message == WM_SYSKEYDOWN )
1835  {
1836  if ( HIWORD(Msg->lParam) & KF_ALTDOWN )
1837  {
1838  if ( Msg->wParam == VK_ESCAPE || Msg->wParam == VK_TAB ) // Alt-Tab/ESC Alt-Shift-Tab/ESC
1839  {
1840  WPARAM wParamTmp;
1841 
1842  wParamTmp = UserGetKeyState(VK_SHIFT) & 0x8000 ? SC_PREVWINDOW : SC_NEXTWINDOW;
1843  TRACE("Send WM_SYSCOMMAND Alt-Tab/ESC Alt-Shift-Tab/ESC\n");
1844  co_IntSendMessage( Msg->hwnd, WM_SYSCOMMAND, wParamTmp, Msg->wParam );
1845 
1847  Ret = FALSE;
1849  goto Exit;
1850  }
1851  }
1852  }
1853 
1854  if ( *RemoveMessages && (Msg->message == WM_SYSKEYDOWN || Msg->message == WM_KEYDOWN) )
1855  {
1856  if (gdwLanguageToggleKey < 3)
1857  {
1858  if (IS_KEY_DOWN(gafAsyncKeyState, gdwLanguageToggleKey == 1 ? VK_LMENU : VK_CONTROL)) // L Alt 1 or Ctrl 2 .
1859  {
1860  if ( wParam == VK_LSHIFT ) gLanguageToggleKeyState = INPUTLANGCHANGE_FORWARD; // Left Alt - Left Shift, Next
1862  if ( wParam == VK_RSHIFT ) gLanguageToggleKeyState = INPUTLANGCHANGE_BACKWARD; // Left Alt - Right Shift, Previous
1863  }
1864  }
1865  }
1866 
1868  if ( *RemoveMessages && (Msg->message == WM_SYSKEYUP || Msg->message == WM_KEYUP) )
1869  {
1870  // When initializing win32k: Reading from the registry hotkey combination
1871  // to switch the keyboard layout and store it to global variable.
1872  // Using this combination of hotkeys in this function
1873 
1874  if ( gdwLanguageToggleKey < 3 &&
1876  {
1877  if ( Msg->wParam == VK_SHIFT && !(IS_KEY_DOWN(gafAsyncKeyState, VK_SHIFT)))
1878  {
1879  WPARAM wParamILR;
1880  PKL pkl = pti->KeyboardLayout;
1881 
1882  if (pWnd) UserDerefObjectCo(pWnd);
1883 
1885  if (!(pWnd = pti->MessageQueue->spwndFocus))
1886  {
1887  pWnd = pti->MessageQueue->spwndActive;
1888  }
1889  if (pWnd) UserRefObjectCo(pWnd, &Ref);
1890 
1891  if (pkl != NULL && gLanguageToggleKeyState)
1892  {
1893  TRACE("Posting WM_INPUTLANGCHANGEREQUEST KeyState %d\n", gLanguageToggleKeyState );
1894 
1895  wParamILR = gLanguageToggleKeyState;
1896  // If system character set and font signature send flag.
1897  if ( gSystemFS & pkl->dwFontSigs )
1898  {
1899  wParamILR |= INPUTLANGCHANGE_SYSCHARSET;
1900  }
1901 
1903  WM_INPUTLANGCHANGEREQUEST,
1904  wParamILR,
1905  (LPARAM)pkl->hkl );
1906 
1909  Ret = FALSE;
1911  goto Exit;
1912  }
1913  }
1914  }
1915  }
1916 
1918  *RemoveMessages ? HC_ACTION : HC_NOREMOVE,
1919  LOWORD(Msg->wParam),
1920  Msg->lParam))
1921  {
1922  /* skip this message */
1925  LOWORD(Msg->wParam),
1926  Msg->lParam );
1927 
1928  ERR("KeyboardMessage WH_KEYBOARD Call Hook return!\n");
1929 
1930  *RemoveMessages = TRUE;
1931 
1932  Ret = FALSE;
1933  }
1934 
1935  if ( pWnd && Ret && *RemoveMessages && Msg->message == WM_KEYDOWN && !(pti->TIF_flags & TIF_DISABLEIME))
1936  {
1937  if ( (ImmRet = IntImmProcessKey(pti->MessageQueue, pWnd, Msg->message, Msg->wParam, Msg->lParam)) )
1938  {
1939  if ( ImmRet & (IPHK_HOTKEY|IPHK_SKIPTHISKEY) )
1940  {
1941  ImmRet = 0;
1942  }
1943  if ( ImmRet & IPHK_PROCESSBYIME )
1944  {
1945  Msg->wParam = VK_PROCESSKEY;
1946  }
1947  }
1948  }
1949 Exit:
1950  if (pWnd) UserDerefObjectCo(pWnd);
1951  return Ret;
1952 }
1953 
1954 BOOL co_IntProcessHardwareMessage(MSG* Msg, BOOL* RemoveMessages, BOOL* NotForUs, LONG_PTR ExtraInfo, UINT first, UINT last)
1955 {
1956  if ( IS_MOUSE_MESSAGE(Msg->message))
1957  {
1958  return co_IntProcessMouseMessage(Msg, RemoveMessages, NotForUs, ExtraInfo, first, last);
1959  }
1960  else if ( IS_KBD_MESSAGE(Msg->message))
1961  {
1962  return co_IntProcessKeyboardMessage(Msg, RemoveMessages);
1963  }
1964 
1965  return TRUE;
1966 }
1967 
1968 /* check whether a message filter contains at least one potential hardware message */
1969 static INT FASTCALL
1971 {
1972  /* hardware message ranges are (in numerical order):
1973  * WM_NCMOUSEFIRST .. WM_NCMOUSELAST
1974  * WM_KEYFIRST .. WM_KEYLAST
1975  * WM_MOUSEFIRST .. WM_MOUSELAST
1976  */
1977  if (!last) --last;
1978  if (last < WM_NCMOUSEFIRST) return 0;
1979  if (first > WM_NCMOUSELAST && last < WM_KEYFIRST) return 0;
1980  if (first > WM_KEYLAST && last < WM_MOUSEFIRST) return 0;
1981  if (first > WM_MOUSELAST) return 0;
1982  return 1;
1983 }
1984 
1985 /* check whether message is in the range of mouse messages */
1987 {
1988  return ( //( message >= WM_NCMOUSEFIRST && message <= WM_NCMOUSELAST ) || This seems to break tests...
1989  ( message >= WM_MOUSEFIRST && message <= WM_MOUSELAST ) ||
1990  ( message >= WM_XBUTTONDOWN && message <= WM_XBUTTONDBLCLK ) ||
1993 }
1994 
1995 BOOL APIENTRY
1997  IN BOOL Remove,
1998  IN PWND Window,
1999  IN UINT MsgFilterLow,
2000  IN UINT MsgFilterHigh,
2001  IN UINT QSflags,
2002  OUT MSG* pMsg)
2003 {
2004  BOOL AcceptMessage, NotForUs;
2005  PUSER_MESSAGE CurrentMessage;
2006  PLIST_ENTRY ListHead;
2007  MSG msg;
2008  ULONG_PTR idSave;
2009  DWORD QS_Flags;
2010  LONG_PTR ExtraInfo;
2011  BOOL Ret = FALSE;
2012  PUSER_MESSAGE_QUEUE MessageQueue = pti->MessageQueue;
2013 
2014  if (!filter_contains_hw_range( MsgFilterLow, MsgFilterHigh )) return FALSE;
2015 
2016  ListHead = MessageQueue->HardwareMessagesListHead.Flink;
2017 
2018  if (IsListEmpty(ListHead)) return FALSE;
2019 
2020  if (!MessageQueue->ptiSysLock)
2021  {
2022  MessageQueue->ptiSysLock = pti;
2023  pti->pcti->CTI_flags |= CTI_THREADSYSLOCK;
2024  }
2025 
2026  if (MessageQueue->ptiSysLock != pti)
2027  {
2028  ERR("Thread Q is locked to ptiSysLock 0x%p pti 0x%p\n",MessageQueue->ptiSysLock,pti);
2029  return FALSE;
2030  }
2031 
2032  while (ListHead != &MessageQueue->HardwareMessagesListHead)
2033  {
2034  CurrentMessage = CONTAINING_RECORD(ListHead, USER_MESSAGE, ListEntry);
2035  ListHead = ListHead->Flink;
2036 
2037  if (MessageQueue->idSysPeek == (ULONG_PTR)CurrentMessage)
2038  {
2039  TRACE("Skip this message due to it is in play!\n");
2040  continue;
2041  }
2042 /*
2043  MSDN:
2044  1: any window that belongs to the current thread, and any messages on the current thread's message queue whose hwnd value is NULL.
2045  2: retrieves only messages on the current thread's message queue whose hwnd value is NULL.
2046  3: handle to the window whose messages are to be retrieved.
2047  */
2048  if ( ( !Window || // 1
2049  ( Window == PWND_BOTTOM && CurrentMessage->Msg.hwnd == NULL ) || // 2
2050  ( Window != PWND_BOTTOM && Window->head.h == CurrentMessage->Msg.hwnd ) || // 3
2051  ( is_mouse_message(CurrentMessage->Msg.message) ) ) && // Null window for anything mouse.
2052  ( ( ( MsgFilterLow == 0 && MsgFilterHigh == 0 ) && CurrentMessage->QS_Flags & QSflags ) ||
2053  ( MsgFilterLow <= CurrentMessage->Msg.message && MsgFilterHigh >= CurrentMessage->Msg.message ) ) )
2054  {
2055  idSave = MessageQueue->idSysPeek;
2056  MessageQueue->idSysPeek = (ULONG_PTR)CurrentMessage;
2057 
2058  msg = CurrentMessage->Msg;
2059  ExtraInfo = CurrentMessage->ExtraInfo;
2060  QS_Flags = CurrentMessage->QS_Flags;
2061 
2062  NotForUs = FALSE;
2063 
2064  UpdateKeyStateFromMsg(MessageQueue, &msg);
2065  AcceptMessage = co_IntProcessHardwareMessage(&msg, &Remove, &NotForUs, ExtraInfo, MsgFilterLow, MsgFilterHigh);
2066 
2067  if (Remove)
2068  {
2069  if (CurrentMessage->pti != NULL && (MessageQueue->idSysPeek == (ULONG_PTR)CurrentMessage))
2070  {
2071  MsqDestroyMessage(CurrentMessage);
2072  }
2073  ClearMsgBitsMask(pti, QS_Flags);
2074  }
2075 
2076  MessageQueue->idSysPeek = idSave;
2077 
2078  if (NotForUs)
2079  {
2080  Ret = FALSE;
2081  break;
2082  }
2083 
2084  if (AcceptMessage)
2085  {
2086  *pMsg = msg;
2087  // Fix all but one wine win:test_GetMessagePos WM_TIMER tests. See PostTimerMessages.
2088  if (!RtlEqualMemory(&pti->ptLast, &msg.pt, sizeof(POINT)))
2089  {
2090  pti->TIF_flags |= TIF_MSGPOSCHANGED;
2091  }
2092  pti->ptLast = msg.pt;
2093  pti->timeLast = msg.time;
2094  MessageQueue->ExtraInfo = ExtraInfo;
2095  Ret = TRUE;
2096  break;
2097  }
2098  }
2099  }
2100 
2101  MessageQueue->ptiSysLock = NULL;
2102  pti->pcti->CTI_flags &= ~CTI_THREADSYSLOCK;
2103  return Ret;
2104 }
2105 
2108  IN BOOLEAN Remove,
2109  IN PWND Window,
2110  IN UINT MsgFilterLow,
2111  IN UINT MsgFilterHigh,
2112  IN UINT QSflags,
2113  OUT LONG_PTR *ExtraInfo,
2114  OUT DWORD *dwQEvent,
2115  OUT PMSG Message)
2116 {
2117  PUSER_MESSAGE CurrentMessage;
2118  PLIST_ENTRY ListHead;
2119  DWORD QS_Flags;
2120  BOOL Ret = FALSE;
2121 
2122  ListHead = pti->PostedMessagesListHead.Flink;
2123 
2124  if (IsListEmpty(ListHead)) return FALSE;
2125 
2126  while(ListHead != &pti->PostedMessagesListHead)
2127  {
2128  CurrentMessage = CONTAINING_RECORD(ListHead, USER_MESSAGE, ListEntry);
2129  ListHead = ListHead->Flink;
2130 /*
2131  MSDN:
2132  1: any window that belongs to the current thread, and any messages on the current thread's message queue whose hwnd value is NULL.
2133  2: retrieves only messages on the current thread's message queue whose hwnd value is NULL.
2134  3: handle to the window whose messages are to be retrieved.
2135  */
2136  if ( ( !Window || // 1
2137  ( Window == PWND_BOTTOM && CurrentMessage->Msg.hwnd == NULL ) || // 2
2138  ( Window != PWND_BOTTOM && Window->head.h == CurrentMessage->Msg.hwnd ) ) && // 3
2139  ( ( ( MsgFilterLow == 0 && MsgFilterHigh == 0 ) && CurrentMessage->QS_Flags & QSflags ) ||
2140  ( MsgFilterLow <= CurrentMessage->Msg.message && MsgFilterHigh >= CurrentMessage->Msg.message ) ) )
2141  {
2142  *Message = CurrentMessage->Msg;
2143  *ExtraInfo = CurrentMessage->ExtraInfo;
2144  QS_Flags = CurrentMessage->QS_Flags;
2145  if (dwQEvent) *dwQEvent = CurrentMessage->dwQEvent;
2146 
2147  if (Remove)
2148  {
2149  if (CurrentMessage->pti != NULL)
2150  {
2151  MsqDestroyMessage(CurrentMessage);
2152  }
2153  ClearMsgBitsMask(pti, QS_Flags);
2154  }
2155  Ret = TRUE;
2156  break;
2157  }
2158  }
2159 
2160  return Ret;
2161 }
2162 
2165  UINT MsgFilterMin, UINT MsgFilterMax)
2166 {
2168 
2169  // Post mouse moves before waiting for messages.
2170  if (pti->MessageQueue->QF_flags & QF_MOUSEMOVED)
2171  {
2172  IntCoalesceMouseMove(pti);
2173  }
2174 
2175  UserLeaveCo();
2176 
2177  ZwYieldExecution(); // Let someone else run!
2178 
2180  UserRequest,
2181  UserMode,
2182  FALSE,
2183  NULL );
2184  UserEnterCo();
2185  if ( ret == STATUS_USER_APC )
2186  {
2187  TRACE("MWFNW User APC\n");
2189  }
2190  return ret;
2191 }
2192 
2193 BOOL FASTCALL
2195 {
2196  if (EngGetTickCount32() - pti->timeLast > MSQ_HUNG &&
2197  !(pti->pcti->fsWakeMask & QS_INPUT) &&
2198  !PsGetThreadFreezeCount(pti->pEThread) &&
2199  !(pti->ppi->W32PF_flags & W32PF_APPSTARTING))
2200  return TRUE;
2201 
2202  return FALSE;
2203 }
2204 
2205 BOOL FASTCALL
2207 {
2208  if (pti->pEThread)
2209  {
2210  BOOL Ret = TRUE;
2211  if (!(pti->pEThread->Tcb.SuspendCount) && !PsGetThreadFreezeCount(pti->pEThread)) Ret = FALSE;
2212  return Ret;
2213  }
2214  return FALSE;
2215 }
2216 
2217 VOID
2218 CALLBACK
2220 {
2221  DoTheScreenSaver();
2222  TRACE("HungAppSysTimerProc\n");
2223  // Process list of windows that are hung and waiting.
2224 }
2225 
2228 {
2229  InitializeListHead(&MessageQueue->HardwareMessagesListHead); // Keep here!
2230  MessageQueue->spwndFocus = NULL;
2231  MessageQueue->iCursorLevel = 0;
2232  MessageQueue->CursorObject = SYSTEMCUR(WAIT); // See test_initial_cursor.
2233  if (MessageQueue->CursorObject)
2234  {
2235  TRACE("Default cursor hcur %p\n",UserHMGetHandle(MessageQueue->CursorObject));
2236  UserReferenceObject(MessageQueue->CursorObject);
2237  }
2238  RtlCopyMemory(MessageQueue->afKeyState, gafAsyncKeyState, sizeof(gafAsyncKeyState));
2239  MessageQueue->ptiMouse = pti;
2240  MessageQueue->ptiKeyboard = pti;
2241  MessageQueue->cThreads++;
2242 
2243  return TRUE;
2244 }
2245 
2246 VOID FASTCALL
2248 {
2249  PLIST_ENTRY CurrentEntry;
2250  PUSER_MESSAGE CurrentMessage;
2251  PUSER_SENT_MESSAGE CurrentSentMessage;
2252 
2253  TRACE("MsqCleanupThreadMsgs %p\n",pti);
2254 
2255  // Clear it all out.
2256  if (pti->pcti)
2257  {
2258  pti->pcti->fsWakeBits = 0;
2259  pti->pcti->fsChangeBits = 0;
2260  }
2261 
2262  pti->nCntsQBits[QSRosKey] = 0;
2263  pti->nCntsQBits[QSRosMouseMove] = 0;
2264  pti->nCntsQBits[QSRosMouseButton] = 0;
2265  pti->nCntsQBits[QSRosPostMessage] = 0;
2266  pti->nCntsQBits[QSRosSendMessage] = 0;
2267  pti->nCntsQBits[QSRosHotKey] = 0;
2268  pti->nCntsQBits[QSRosEvent] = 0;
2269 
2270  /* cleanup posted messages */
2271  while (!IsListEmpty(&pti->PostedMessagesListHead))
2272  {
2273  CurrentEntry = pti->PostedMessagesListHead.Flink;
2274  CurrentMessage = CONTAINING_RECORD(CurrentEntry, USER_MESSAGE, ListEntry);
2275  ERR("Thread Cleanup Post Messages %p\n",CurrentMessage);
2276  if (CurrentMessage->dwQEvent)
2277  {
2278  if (CurrentMessage->dwQEvent == POSTEVENT_NWE)
2279  {
2280  ExFreePoolWithTag( (PVOID)CurrentMessage->ExtraInfo, TAG_HOOK);
2281  }
2282  }
2283  MsqDestroyMessage(CurrentMessage);
2284  }
2285 
2286  /* remove the messages that have not yet been dispatched */
2287  while (!IsListEmpty(&pti->SentMessagesListHead))
2288  {
2289  CurrentEntry = pti->SentMessagesListHead.Flink;
2290  CurrentSentMessage = CONTAINING_RECORD(CurrentEntry, USER_SENT_MESSAGE, ListEntry);
2291 
2292  ERR("Thread Cleanup Sent Messages %p\n",CurrentSentMessage);
2293 
2294  /* wake the sender's thread */
2295  if (CurrentSentMessage->pkCompletionEvent != NULL)
2296  {
2297  KeSetEvent(CurrentSentMessage->pkCompletionEvent, IO_NO_INCREMENT, FALSE);
2298  }
2299 
2300  if (CurrentSentMessage->HasPackedLParam)
2301  {
2302  if (CurrentSentMessage->Msg.lParam)
2303  ExFreePool((PVOID)CurrentSentMessage->Msg.lParam);
2304  }
2305 
2306  /* free the message */
2307  FreeUserMessage(CurrentSentMessage);
2308  }
2309 
2310  // Process Trouble Message List
2311  if (!IsListEmpty(&usmList))
2312  {
2313  CurrentEntry = usmList.Flink;
2314  while (CurrentEntry != &usmList)
2315  {
2316  CurrentSentMessage = CONTAINING_RECORD(CurrentEntry, USER_SENT_MESSAGE, ListEntry);
2317  CurrentEntry = CurrentEntry->Flink;
2318 
2319  TRACE("Found troubled messages %p on the list\n",CurrentSentMessage);
2320 
2321  if ( pti == CurrentSentMessage->ptiReceiver )
2322  {
2323  if (CurrentSentMessage->HasPackedLParam)
2324  {
2325  if (CurrentSentMessage->Msg.lParam)
2326  ExFreePool((PVOID)CurrentSentMessage->Msg.lParam);
2327  }
2328 
2329  /* free the message */
2330  FreeUserMessage(CurrentSentMessage);
2331  }
2332  else if ( pti == CurrentSentMessage->ptiSender ||
2333  pti == CurrentSentMessage->ptiCallBackSender )
2334  {
2335  // Determine whether this message is being processed or not.
2336  if ((CurrentSentMessage->flags & (SMF_RECEIVERBUSY|SMF_RECEIVEDMESSAGE)) != SMF_RECEIVEDMESSAGE)
2337  {
2338  CurrentSentMessage->flags |= SMF_RECEIVERFREE;
2339  }
2340 
2341  if (!(CurrentSentMessage->flags & SMF_RECEIVERFREE))
2342  {
2343 
2344  if (CurrentSentMessage->HasPackedLParam)
2345  {
2346  if (CurrentSentMessage->Msg.lParam)
2347  ExFreePool((PVOID)CurrentSentMessage->Msg.lParam);
2348  }
2349 
2350  /* free the message */
2351  FreeUserMessage(CurrentSentMessage);
2352  }
2353  }
2354  }
2355  }
2356 }
2357 
2358 VOID FASTCALL
2360 {
2361  PUSER_MESSAGE_QUEUE MessageQueue;
2362  PLIST_ENTRY CurrentEntry;
2363  PUSER_MESSAGE CurrentMessage;
2364 
2365  MessageQueue = pti->MessageQueue;
2366  MessageQueue->cThreads--;
2367 
2368  if (MessageQueue->cThreads)
2369  {
2370  if (MessageQueue->ptiSysLock == pti) MessageQueue->ptiSysLock = NULL;
2371  }
2372 
2373  if (MessageQueue->cThreads == 0)
2374  {
2375  /* cleanup posted messages */
2376  while (!IsListEmpty(&MessageQueue->HardwareMessagesListHead))
2377  {
2378  CurrentEntry = MessageQueue->HardwareMessagesListHead.Flink;
2379  CurrentMessage = CONTAINING_RECORD(CurrentEntry, USER_MESSAGE, ListEntry);
2380  ERR("MQ Cleanup Post Messages %p\n",CurrentMessage);
2381  MsqDestroyMessage(CurrentMessage);
2382  }
2383  }
2384 
2385  if (MessageQueue->CursorObject)
2386  {
2387  PCURICON_OBJECT pCursor = MessageQueue->CursorObject;
2388 
2389  /* Change to another cursor if we going to dereference current one
2390  Note: we can't use UserSetCursor because it uses current thread
2391  message queue instead of queue given for cleanup */
2392  if (IntGetSysCursorInfo()->CurrentCursorObject == pCursor)
2393  {
2394  HDC hdcScreen;
2395 
2396  /* Get the screen DC */
2397  hdcScreen = IntGetScreenDC();
2398  if (hdcScreen)
2399  GreMovePointer(hdcScreen, -1, -1);
2401  }
2402 
2403  TRACE("DereferenceObject pCursor\n");
2404  UserDereferenceObject(pCursor);
2405  }
2406 
2407  if (gpqForeground == MessageQueue)
2408  {
2410  }
2411  if (gpqForegroundPrev == MessageQueue)
2412  {
2414  }
2415  if (gpqCursor == MessageQueue)
2416  {
2417  gpqCursor = NULL;
2418  }
2419 }
2420 
2423 {
2424  PUSER_MESSAGE_QUEUE MessageQueue;
2425 
2426  MessageQueue = ExAllocatePoolWithTag(NonPagedPool,
2427  sizeof(*MessageQueue),
2428  USERTAG_Q);
2429 
2430  if (!MessageQueue)
2431  {
2432  return NULL;
2433  }
2434 
2435  RtlZeroMemory(MessageQueue, sizeof(*MessageQueue));
2436  /* hold at least one reference until it'll be destroyed */
2437  IntReferenceMessageQueue(MessageQueue);
2438  /* initialize the queue */
2439  if (!MsqInitializeMessageQueue(pti, MessageQueue))
2440  {
2441  IntDereferenceMessageQueue(MessageQueue);
2442  return NULL;
2443  }
2444 
2445  return MessageQueue;
2446 }
2447 
2448 VOID FASTCALL
2450 {
2451  PDESKTOP desk;
2452  PUSER_MESSAGE_QUEUE MessageQueue = pti->MessageQueue;
2453 
2454  NT_ASSERT(MessageQueue != NULL);
2455  MessageQueue->QF_flags |= QF_INDESTROY;
2456 
2457  /* remove the message queue from any desktops */
2458  if ((desk = InterlockedExchangePointer((PVOID*)&MessageQueue->Desktop, 0)))
2459  {
2461  IntDereferenceMessageQueue(MessageQueue);
2462  }
2463 
2464  /* clean it up */
2466 
2467  /* decrease the reference counter, if it hits zero, the queue will be freed */
2469  IntDereferenceMessageQueue(MessageQueue);
2470 }
2471 
2474 {
2475  LPARAM Ret;
2476  PTHREADINFO pti;
2477  PUSER_MESSAGE_QUEUE MessageQueue;
2478 
2480  MessageQueue = pti->MessageQueue;
2481  if(!MessageQueue)
2482  {
2483  return 0;
2484  }
2485 
2486  Ret = MessageQueue->ExtraInfo;
2487  MessageQueue->ExtraInfo = lParam;
2488 
2489  return Ret;
2490 }
2491 
2494 {
2495  PTHREADINFO pti;
2496  PUSER_MESSAGE_QUEUE MessageQueue;
2497 
2499  MessageQueue = pti->MessageQueue;
2500  if(!MessageQueue)
2501  {
2502  return 0;
2503  }
2504 
2505  return MessageQueue->ExtraInfo;
2506 }
2507 
2508 // ReplyMessage is called by the thread receiving the window message.
2509 BOOL FASTCALL
2511 {
2513  PTHREADINFO pti;
2514 
2516  Message = pti->pusmCurrent;
2517 
2518  if (!Message) return FALSE;
2519 
2520  if (Message->QS_Flags & QS_SMRESULT) return FALSE;
2521 
2522  // SendMessageXxx || Callback msg and not a notify msg
2523  if (Message->ptiSender || Message->CompletionCallback)
2524  {
2525  Message->lResult = lResult;
2526  Message->QS_Flags |= QS_SMRESULT;
2527  // See co_MsqDispatchOneSentMessage, change bits already accounted for and cleared and this msg is going away..
2528  }
2529  return TRUE;
2530 }
2531 
2532 HWND FASTCALL
2534 {
2535  HWND Prev;
2536  PUSER_MESSAGE_QUEUE MessageQueue;
2537 
2538  MessageQueue = pti->MessageQueue;
2539 
2540  switch(Type)
2541  {
2542  case MSQ_STATE_CAPTURE:
2543  Prev = MessageQueue->spwndCapture ? UserHMGetHandle(MessageQueue->spwndCapture) : 0;
2544  MessageQueue->spwndCapture = ValidateHwndNoErr(hWnd);
2545  return Prev;
2546  case MSQ_STATE_ACTIVE:
2547  Prev = MessageQueue->spwndActive ? UserHMGetHandle(MessageQueue->spwndActive) : 0;
2548  MessageQueue->spwndActive = ValidateHwndNoErr(hWnd);
2549  return Prev;
2550  case MSQ_STATE_FOCUS:
2551  Prev = MessageQueue->spwndFocus ? UserHMGetHandle(MessageQueue->spwndFocus) : 0;
2552  MessageQueue->spwndFocus = ValidateHwndNoErr(hWnd);
2553  return Prev;
2554  case MSQ_STATE_MENUOWNER:
2555  Prev = MessageQueue->MenuOwner;
2556  MessageQueue->MenuOwner = hWnd;
2557  return Prev;
2558  case MSQ_STATE_MOVESIZE:
2559  Prev = MessageQueue->MoveSize;
2560  MessageQueue->MoveSize = hWnd;
2561  return Prev;
2562  case MSQ_STATE_CARET:
2563  Prev = MessageQueue->CaretInfo.hWnd;
2564  MessageQueue->CaretInfo.hWnd = hWnd;
2565  return Prev;
2566  }
2567 
2568  return NULL;
2569 }
2570 
2571 SHORT
2572 APIENTRY
2574 {
2575  DWORD Ret;
2576 
2577  UserEnterShared();
2578 
2579  Ret = UserGetKeyState(key);
2580 
2581  UserLeave();
2582 
2583  return (SHORT)Ret;
2584 }
2585 
2586 
2587 DWORD
2588 APIENTRY
2590 {
2591  DWORD i, ret = TRUE;
2592  PTHREADINFO pti;
2593  PUSER_MESSAGE_QUEUE MessageQueue;
2594 
2595  UserEnterShared();
2596 
2598  MessageQueue = pti->MessageQueue;
2599 
2600  _SEH2_TRY
2601  {
2602  /* Probe and copy key state to an array */
2603  ProbeForWrite(lpKeyState, 256 * sizeof(BYTE), 1);
2604  for (i = 0; i < 256; ++i)
2605  {
2606  lpKeyState[i] = 0;
2607  if (IS_KEY_DOWN(MessageQueue->afKeyState, i))
2608  lpKeyState[i] |= KS_DOWN_BIT;
2609  if (IS_KEY_LOCKED(MessageQueue->afKeyState, i))
2610  lpKeyState[i] |= KS_LOCK_BIT;
2611  }
2612  }
2614  {
2616  ret = FALSE;
2617  }
2618  _SEH2_END;
2619 
2620  UserLeave();
2621 
2622  return ret;
2623 }
2624 
2625 BOOL
2626 APIENTRY
2628 {
2629  UINT i;
2630  BOOL bRet = TRUE;
2631  PTHREADINFO pti;
2632  PUSER_MESSAGE_QUEUE MessageQueue;
2633 
2635 
2637  MessageQueue = pti->MessageQueue;
2638 
2639  _SEH2_TRY
2640  {
2641  ProbeForRead(pKeyState, 256 * sizeof(BYTE), 1);
2642  for (i = 0; i < 256; ++i)
2643  {
2644  SET_KEY_DOWN(MessageQueue->afKeyState, i, pKeyState[i] & KS_DOWN_BIT);
2645  SET_KEY_LOCKED(MessageQueue->afKeyState, i, pKeyState[i] & KS_LOCK_BIT);
2646  }
2647  }
2649  {
2651  bRet = FALSE;
2652  }
2653  _SEH2_END;
2654 
2655  UserLeave();
2656 
2657  return bRet;
2658 }
2659 
2660 /* EOF */
#define WM_MBUTTONUP
Definition: winuser.h:1765
#define IS_KBD_MESSAGE(message)
Definition: msgqueue.h:246
BYTE gafAsyncKeyState[256 *2/8]
Definition: keyboard.c:13
#define WH_MOUSE
Definition: winuser.h:37
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 abs(i)
Definition: fconv.c:206
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
VOID FASTCALL UserEnterShared(VOID)
Definition: ntuser.c:241
#define MSQ_STATE_ACTIVE
Definition: ntuser.h:3545
#define IN
Definition: typedefs.h:38
#define MSQ_STATE_MOVESIZE
Definition: ntuser.h:3548
BOOL FASTCALL UserPostMessage(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: message.c:1181
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:668
PCURICON_OBJECT IntSystemSetCursor(PCURICON_OBJECT pcurNew)
Definition: cursoricon.c:230
Definition: tftpd.h:59
#define SM_CYDOUBLECLK
Definition: winuser.h:990
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:580
#define MAKEWPARAM(l, h)
Definition: winuser.h:3984
struct _USER_SENT_MESSAGE * pusmSent
Definition: win32.h:96
#define VK_PROCESSKEY
Definition: winuser.h:2302
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:1756
#define USERTAG_Q
Definition: tags.h:268
SHORT APIENTRY NtUserGetKeyState(INT key)
Definition: msgqueue.c:2573
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
#define MK_SHIFT
Definition: winuser.h:2344
struct _DESKTOP * rpdesk
Definition: ntuser.h:189
PWND spwndTrack
Definition: desktop.h:31
VOID FASTCALL MsqCleanupMessageQueue(PTHREADINFO pti)
Definition: msgqueue.c:2359
#define ID_EVENT_SYSTIMER_MOUSEHOVER
Definition: timer.h:27
PKEVENT pkCompletionEvent
Definition: msgqueue.h:25
long y
Definition: polytest.cpp:48
HDC FASTCALL IntGetScreenDC(VOID)
Definition: winsta.c:347
Type
Definition: Type.h:6
#define WM_CONTEXTMENU
Definition: richedit.h:64
#define WM_LBUTTONDOWN
Definition: winuser.h:1758
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:2342
ULONG_PTR dwExtraInfo
Definition: winuser.h:3796
#define MWMO_INPUTAVAILABLE
Definition: winuser.h:900
POINT last
Definition: font.c:46
#define TAG_USRMSG
Definition: tags.h:8
#define VK_LBUTTON
Definition: winuser.h:2165
#define QS_ALLPOSTMESSAGE
Definition: winuser.h:876
#define pt(x, y)
Definition: drawing.c:79
BOOL bMouseBtnSwap
Definition: sysparams.h:82
#define VK_RMENU
Definition: winuser.h:2262
#define WM_HOTKEY
Definition: winuser.h:1861
struct _LIST_ENTRY * Blink
Definition: typedefs.h:120
#define EngGetTickCount32()
Definition: eng.h:43
#define WM_MOUSEWHEEL
Definition: treelist.c:96
VOID FASTCALL IdlePing(VOID)
Definition: message.c:515
#define VK_LSHIFT
Definition: winuser.h:2257
#define MK_MBUTTON
Definition: winuser.h:2346
BOOLEAN FASTCALL co_MsqDispatchOneSentMessage(_In_ PTHREADINFO pti)
Definition: msgqueue.c:873
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:2194
#define PWND_BOTTOM
Definition: ntuser.h:731
#define WM_GETTEXT
Definition: winuser.h:1600
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:3983
PVOID NTAPI PsGetCurrentThreadWin32Thread(VOID)
Definition: thread.c:805
VOID FASTCALL IntTrackMouseMove(PWND pwndTrack, PDESKTOP pDesk, PMSG msg, USHORT hittest)
Definition: msgqueue.c:1420
BOOL FASTCALL IntKillTimer(PWND Window, UINT_PTR IDEvent, BOOL SystemTimer)
Definition: timer.c:573
struct @1591 Msg[]
LONG NTSTATUS
Definition: precomp.h:26
PTHREADINFO ptiKeyboard
Definition: msgqueue.h:56
LPARAM FASTCALL MsqGetMessageExtraInfo(VOID)
Definition: msgqueue.c:2493
#define ICLS_EDIT
Definition: ntuser.h:874
PTHREADINFO pti
Definition: msgqueue.h:15
GLenum GLuint GLenum GLsizei const GLchar * message
Definition: glext.h:5579
static HDC
Definition: imagelist.c:92
#define CALLBACK
Definition: compat.h:27
HWND hWnd
Definition: settings.c:17
#define WM_QUIT
Definition: winuser.h:1605
LONG_PTR ExtraInfo
Definition: msgqueue.h:13
#define WS_EX_TRANSPARENT
Definition: pedump.c:649
LONG top
Definition: windef.h:307
static __inline VOID UserRefObjectCo(PVOID obj, PUSER_REFERENCE_ENTRY UserReferenceEntry)
Definition: object.h:25
#define MSQ_HUNG
Definition: msgqueue.h:3
#define DF_TME_LEAVE
Definition: desktop.h:48
#define MA_ACTIVATE
Definition: winuser.h:2476
#define QS_TIMER
Definition: winuser.h:893
DWORD dwMouseClickLockTime
Definition: sysparams.h:79
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
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
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:2164
#define HC_NOREMOVE
Definition: winuser.h:51
UINT_PTR WPARAM
Definition: windef.h:207
#define VK_TAB
Definition: winuser.h:2174
#define WS_CHILD
Definition: pedump.c:617
#define SMF_SENDERDIED
Definition: msgqueue.h:39
RECT rcClient
Definition: ntuser.h:681
#define VK_MENU
Definition: winuser.h:2179
LONG left
Definition: windef.h:306
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:2189
struct _USER_SENT_MESSAGE * pusmCurrent
Definition: win32.h:97
INT iMouseHoverHeight
Definition: sysparams.h:86
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
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:1970
#define WM_NCCREATE
Definition: winuser.h:1665
#define HTNOWHERE
Definition: winuser.h:2449
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
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
WPARAM wParam
Definition: combotst.c:138
#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:3546
#define MA_ACTIVATEANDEAT
Definition: winuser.h:2477
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:263
DWORD FASTCALL UserGetKeyState(DWORD dwKey)
Definition: msgqueue.c:221
_SEH2_TRY
Definition: create.c:4250
UINT cTimersReady
Definition: win32.h:109
#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
#define ES_PASSWORD
Definition: pedump.c:670
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
INT iMouseHoverWidth
Definition: sysparams.h:85
#define IPHK_PROCESSBYIME
Definition: undocuser.h:138
#define STATUS_TIMEOUT
Definition: ntstatus.h:81
BOOL bMouseClickLock
Definition: sysparams.h:77
#define SPS_ALPHA
Definition: winddi.h:4039
VOID FASTCALL MsqDestroyMessage(PUSER_MESSAGE Message)
Definition: msgqueue.c:748
#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:1151
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:1014
Definition: window.c:28
struct _USER_MESSAGE_QUEUE * ActiveMessageQueue
Definition: desktop.h:38
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
INT iDblClickTime
Definition: sysparams.h:90
VOID FASTCALL co_IntDeliverUserAPC(VOID)
Definition: callback.c:1146
#define STATUS_WAIT_0
Definition: ntstatus.h:223
#define WM_KEYFIRST
Definition: winuser.h:1696
unsigned char * LPBYTE
Definition: typedefs.h:52
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:877
#define VK_RBUTTON
Definition: winuser.h:2166
#define MA_NOACTIVATEANDEAT
Definition: winuser.h:2479
#define ERROR_ACCESS_DENIED
Definition: compat.h:87
#define WM_PARENTNOTIFY
Definition: winuser.h:1785
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
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:2510
#define WM_SETCURSOR
Definition: winuser.h:1618
short SHORT
Definition: pedump.c:59
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:4971
#define FIXME(fmt,...)
Definition: debug.h:110
#define SMF_RECEIVERFREE
Definition: msgqueue.h:40
BOOL FASTCALL co_IntMouseActivateWindow(PWND Wnd)
Definition: focus.c:1136
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:435
#define CHILDID_SELF
Definition: winable.h:14
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define VK_SHIFT
Definition: winuser.h:2177
THRDESKHEAD head
Definition: ntuser.h:659
NTSYSAPI NTSTATUS NTAPI ZwYieldExecution(VOID)
Definition: object.h:3
#define MAKELONG(a, b)
Definition: typedefs.h:248
DWORD gSystemFS
Definition: kbdlayout.c:22
unsigned char BOOLEAN
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:416
BOOL co_IntProcessHardwareMessage(MSG *Msg, BOOL *RemoveMessages, BOOL *NotForUs, LONG_PTR ExtraInfo, UINT first, UINT last)
Definition: msgqueue.c:1954
INT exitCode
Definition: win32.h:106
Definition: input.h:26
_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
#define QS_SENDMESSAGE
Definition: winuser.h:892
BOOL IntLoadHookModule(int iHookID, HHOOK hHook, BOOL Unload)
Definition: hook.c:31
#define WM_KEYDOWN
Definition: winuser.h:1697
#define IS_KEY_LOCKED(ks, vk)
Definition: input.h:99
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
LONG_PTR LPARAM
Definition: windef.h:208
DWORD QS_Flags
Definition: msgqueue.h:12
#define QF_INDESTROY
Definition: msgqueue.h:103
_In_ BOOLEAN Remove
Definition: psfuncs.h:110
#define WH_CBT
Definition: winuser.h:35
struct _WND * spwndNext
Definition: ntuser.h:675
#define WM_MOUSEACTIVATE
Definition: winuser.h:1619
#define HTERROR
Definition: winuser.h:2447
INIT_FUNCTION NTSTATUS NTAPI MsqInitializeImpl(VOID)
Definition: msgqueue.c:30
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:2343
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#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:1761
LONG NTAPI UserGetSystemMetrics(ULONG Index)
Definition: metric.c:180
#define WM_APPCOMMAND
Definition: winuser.h:1864
DWORD dwTime
Definition: solitaire.cpp:25
#define QS_INPUT
Definition: winuser.h:881
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:247
#define UserHMGetHandle(obj)
Definition: ntuser.h:208
#define WAIT
Definition: listbox.c:36
#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
HWND FASTCALL MsqSetStateWindow(PTHREADINFO pti, ULONG Type, HWND hWnd)
Definition: msgqueue.c:2533
LRESULT APIENTRY co_CallHook(INT HookId, INT Code, WPARAM wParam, LPARAM lParam)
Definition: hook.c:322
Definition: msg.h:42
#define TRACE(s)
Definition: solgame.cpp:4
#define InterlockedExchangePointer(Target, Value)
Definition: dshow.h:45
#define CTI_THREADSYSLOCK
Definition: ntuser.h:160
VOID FASTCALL ClearMsgBitsMask(PTHREADINFO pti, UINT MessageBits)
Definition: msgqueue.c:445
#define EM_SETPASSWORDCHAR
Definition: winuser.h:1996
VOID FASTCALL MsqDestroyMessageQueue(_In_ PTHREADINFO pti)
Definition: msgqueue.c:2449
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:2212
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:1765
PUSER_MESSAGE_QUEUE FASTCALL MsqCreateMessageQueue(PTHREADINFO pti)
Definition: msgqueue.c:2422
static void Exit(void)
Definition: sock.c:1331
#define CTI_INSENDMESSAGE
Definition: ntuser.h:161
#define MSQ_INJECTMODULE
Definition: msgqueue.h:6
#define WM_MOUSELAST
Definition: winuser.h:1783
PKEVENT pEventQueueServer
Definition: win32.h:124
HKL hkl
Definition: input.h:32
void(CALLBACK * SENDASYNCPROC)(HWND, UINT, ULONG_PTR, LRESULT)
Definition: winuser.h:2891
PUSER_MESSAGE_QUEUE gpqCursor
Definition: msgqueue.c:20
#define WM_KEYUP
Definition: winuser.h:1698
#define WS_EX_LAYERED
Definition: winuser.h:389
DWORD nCntsQBits[QSIDCOUNTS]
Definition: win32.h:147
#define QS_EVENT
Definition: undocuser.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
SPIVALUES gspv
Definition: sysparams.c:17
PSYSTEM_CURSORINFO IntGetSysCursorInfo(VOID)
Definition: cursoricon.c:187
unsigned long DWORD
Definition: ntddk_ex.h:95
VOID FASTCALL FreeUserMessage(PUSER_SENT_MESSAGE Message)
Definition: msgqueue.c:786
#define WM_KEYLAST
Definition: winuser.h:1710
VOID FASTCALL MsqPostMessage(PTHREADINFO pti, MSG *Msg, BOOLEAN HardwareMessage, DWORD MessageBits, DWORD dwQEvent, LONG_PTR ExtraInfo)
Definition: msgqueue.c:1338
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
#define WM_RBUTTONUP
Definition: winuser.h:1762
#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:2107
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:2566
VOID FASTCALL IntCoalesceMouseMove(PTHREADINFO pti)
Definition: msgqueue.c:551
PTHREADINFO ptiSysLock
Definition: msgqueue.h:52
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
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:1103
FORCEINLINE BOOL RECTL_bPointInRect(_In_ const RECTL *prcl, _In_ INT x, _In_ INT y)
Definition: rect.h:52
ULONG_PTR idSysPeek
Definition: msgqueue.h:54
PWND FASTCALL UserGetDesktopWindow(VOID)
Definition: desktop.c:1349
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:763
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:1281
VOID FASTCALL MsqPostMouseMove(PTHREADINFO pti, MSG *Msg, LONG_PTR ExtraInfo)
Definition: msgqueue.c:518
DBG_DEFAULT_CHANNEL(UserMsgQ)
#define VK_RCONTROL
Definition: winuser.h:2260
#define VK_LMENU
Definition: winuser.h:2261
#define QS_MOUSEMOVE
Definition: winuser.h:886
#define VK_RSHIFT
Definition: winuser.h:2258
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
HKEY key
Definition: reg.c:42
BYTE afKeyState[256 *2/8]
Definition: msgqueue.h:84
DWORD dwFontSigs
Definition: input.h:34
BOOL APIENTRY NtUserSetKeyboardState(LPBYTE pKeyState)
Definition: msgqueue.c:2627
ULONG CURSORF_flags
Definition: cursoricon.h:16
PUSER_MESSAGE FASTCALL MsqCreateMessage(LPMSG Msg)
Definition: msgqueue.c:731
unsigned char BYTE
Definition: mem.h:68
#define WM_LBUTTONDBLCLK
Definition: winuser.h:1760
THRDCARETINFO CaretInfo
Definition: msgqueue.h:92
BOOL HasPackedLParam
Definition: msgqueue.h:34
#define WM_MBUTTONDBLCLK
Definition: winuser.h:1766
PTHREADINFO ptiCallBackSender
Definition: msgqueue.h:31
Definition: typedefs.h:117
#define CS_DBLCLKS
Definition: winuser.h:646
#define MA_NOACTIVATE
Definition: winuser.h:2478
PCURICON_OBJECT CursorObject
Definition: msgqueue.h:89
struct _cl_event * event
Definition: glext.h:7739
#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:48
#define TIF_MSGPOSCHANGED
Definition: ntuser.h:260
#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:255
HWND FASTCALL IntGetDesktopWindow(VOID)
Definition: desktop.c:1338
FORCEINLINE VOID RECTL_vSetRect(_Out_ RECTL *prcl, _In_ LONG left, _In_ LONG top, _In_ LONG right, _In_ LONG bottom)
Definition: rect.h:5
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:1283
#define MSQ_NORMAL
Definition: msgqueue.h:4
_SEH2_END
Definition: create.c:4424
#define WS_EX_NOPARENTNOTIFY
Definition: pedump.c:646
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:1471
BOOL FASTCALL IsThreadSuspended(PTHREADINFO pti)
Definition: msgqueue.c:2206
struct LOOKASIDE_ALIGN _PAGED_LOOKASIDE_LIST PAGED_LOOKASIDE_LIST
#define MSQ_STATE_CAPTURE
Definition: ntuser.h:3544
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:1702
#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:1759
#define WM_MBUTTONDOWN
Definition: winuser.h:1764
DWORD APIENTRY NtUserGetKeyboardState(LPBYTE lpKeyState)
Definition: msgqueue.c:2589
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
PWND FASTCALL IntGetParent(PWND Wnd)
Definition: window.c:185
DWORD state
Definition: ntuser.h:665
#define QS_POSTMESSAGE
Definition: winuser.h:888
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
unsigned int UINT
Definition: ndis.h:50
#define WM_MOUSEMOVE
Definition: winuser.h:1757
#define QS_MOUSEBUTTON
Definition: winuser.h:885
BOOL FASTCALL IntMsqClearWakeMask(VOID)
Definition: msgqueue.c:392
VOID FASTCALL MsqCleanupThreadMsgs(PTHREADINFO pti)
Definition: msgqueue.c:2247
#define MSQ_STATE_CARET
Definition: ntuser.h:3549
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
#define MK_CONTROL
Definition: winuser.h:2345
HBITMAP hbmMask
Definition: cursoricon.h:19
#define KF_ALTDOWN
Definition: winuser.h:2424
#define VK_F1
Definition: winuser.h:2230
#define W32PF_APPSTARTING
Definition: win32.h:10
#define VK_CONTROL
Definition: winuser.h:2178
#define QS_PAINT
Definition: winuser.h:887
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:1996
PWND FASTCALL IntTopLevelWindowFromPoint(INT x, INT y)
Definition: msgqueue.c:61
VOID FASTCALL MsqIncPaintCountQueue(PTHREADINFO pti)
Definition: msgqueue.c:501
#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:323
#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:1380
#define WM_CREATE
Definition: winuser.h:1590
#define WM_RBUTTONDBLCLK
Definition: winuser.h:1763
PUSER_MESSAGE_QUEUE gpqForegroundPrev
Definition: focus.c:13
#define KS_DOWN_BIT
Definition: input.h:54
#define WM_SYSKEYDOWN
Definition: winuser.h:1701
static void MsqSendParentNotify(PWND pwnd, WORD event, WORD idChild, POINT pt)
Definition: msgqueue.c:1393
VOID CALLBACK HungAppSysTimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
Definition: msgqueue.c:2219
#define EM_GETLINE
Definition: winuser.h:1973
#define HIWORD(l)
Definition: typedefs.h:246
struct tagACON * PACON
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:566
#define SYSTEMCUR(func)
Definition: cursoricon.h:129
DWORD state2
Definition: ntuser.h:666
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define WM_NCMOUSELEAVE
Definition: winuser.h:1824
#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:2473
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:1057
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define SC_NEXTWINDOW
Definition: winuser.h:2565
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#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:2450
BYTE afKeyRecentDown[256/8]
Definition: msgqueue.h:83
INT PostMsgCount
Definition: msgqueue.c:18
LONG_PTR LRESULT
Definition: windef.h:209
#define VK_LCONTROL
Definition: winuser.h:2259
#define QS_MOUSE
Definition: winuser.h:884
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:883
BOOLEAN FASTCALL MsqInitializeMessageQueue(PTHREADINFO pti, PUSER_MESSAGE_QUEUE MessageQueue)
Definition: msgqueue.c:2227
struct _WND * spwndChild
Definition: ntuser.h:678
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define SET_KEY_LOCKED(ks, vk, down)
Definition: input.h:103
#define WS_VISIBLE
Definition: pedump.c:620
#define MSQ_STATE_MENUOWNER
Definition: ntuser.h:3547
#define QF_MOUSEMOVED
Definition: msgqueue.h:99
static BOOL is_mouse_message(UINT message)
Definition: msgqueue.c:1986
#define VK_MBUTTON
Definition: winuser.h:2168
#define WM_SYSCOMMAND
Definition: winuser.h:1723
#define WNDS_DESTROYED
Definition: ntuser.h:604
struct _DESKTOP * Desktop
Definition: msgqueue.h:50
VOID APIENTRY MsqRemoveWindowMessagesFromQueue(PWND Window)
Definition: msgqueue.c:798
LIST_ENTRY HardwareMessagesListHead
Definition: msgqueue.h:59
LPARAM lParam
Definition: combotst.c:139
INT cEnterCount
Definition: win32.h:129
#define LOWORD(l)
Definition: pedump.c:82
#define SM_CXDOUBLECLK
Definition: winuser.h:989
#define TIF_INCLEANUP
Definition: ntuser.h:240
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:27
base of all file and directory entries
Definition: entries.h:82
#define Int32x32To64(a, b)
#define WM_KEYF1
Definition: msg.c:52
#define WM_NCMOUSEMOVE
Definition: winuser.h:1673
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define WM_NOTIFY
Definition: richedit.h:61
#define APIENTRY
Definition: api.h:79
#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:1013
PWND APIENTRY co_WinPosWindowFromPoint(IN PWND ScopeWin, IN POINT *WinPoint, IN OUT USHORT *HitTest, IN BOOL Ignore)
Definition: winpos.c:2838
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:41
VOID FASTCALL UserReferenceObject(PVOID obj)
Definition: object.c:697
DWORD gdwLanguageToggleKey
Definition: keyboard.c:19
PCLS pcls
Definition: ntuser.h:684
DWORD gdwMouseMoveTimeStamp
Definition: msgqueue.c:22
#define NT_ASSERT
Definition: rtlfuncs.h:3312
DWORD style
Definition: ntuser.h:670