1 #pragma once 2 3 #define MSQ_HUNG 5000 4 #define MSQ_NORMAL 0 5 #define MSQ_ISHOOK 1 6 #define MSQ_INJECTMODULE 2 7 8 typedef struct _USER_MESSAGE 9 { 10 LIST_ENTRY ListEntry; 11 MSG Msg; 12 DWORD QS_Flags; 13 LONG_PTR ExtraInfo; 14 DWORD dwQEvent; 15 PTHREADINFO pti; 16 } USER_MESSAGE, *PUSER_MESSAGE; 17 18 struct _USER_MESSAGE_QUEUE; 19 20 typedef struct _USER_SENT_MESSAGE 21 { 22 LIST_ENTRY ListEntry; 23 MSG Msg; 24 DWORD QS_Flags; // Original QS bits used to create this message. 25 PKEVENT pkCompletionEvent; 26 LRESULT lResult; 27 DWORD flags; 28 PTHREADINFO ptiSender; 29 PTHREADINFO ptiReceiver; 30 SENDASYNCPROC CompletionCallback; 31 PTHREADINFO ptiCallBackSender; 32 ULONG_PTR CompletionCallbackContext; 33 INT HookMessage; 34 BOOL HasPackedLParam; 35 KEVENT CompletionEvent; 36 } USER_SENT_MESSAGE, *PUSER_SENT_MESSAGE; 37 38 #define SMF_RECEIVERDIED 0x00000002 39 #define SMF_SENDERDIED 0x00000004 40 #define SMF_RECEIVERFREE 0x00000008 41 #define SMF_RECEIVEDMESSAGE 0x00000010 42 #define SMF_RECEIVERBUSY 0x00004000 43 44 typedef struct _USER_MESSAGE_QUEUE 45 { 46 /* Reference counter, only access this variable with interlocked functions! */ 47 LONG References; 48 49 /* Desktop that the message queue is attached to */ 50 struct _DESKTOP *Desktop; 51 52 PTHREADINFO ptiSysLock; 53 ULONG_PTR idSysLock; 54 ULONG_PTR idSysPeek; 55 PTHREADINFO ptiMouse; 56 PTHREADINFO ptiKeyboard; 57 58 /* Queue for hardware messages for the queue. */ 59 LIST_ENTRY HardwareMessagesListHead; 60 /* Last click message for translating double clicks */ 61 MSG msgDblClk; 62 /* Current capture window for this queue. */ 63 PWND spwndCapture; 64 /* Current window with focus (ie. receives keyboard input) for this queue. */ 65 PWND spwndFocus; 66 /* Current active window for this queue. */ 67 PWND spwndActive; 68 PWND spwndActivePrev; 69 /* Current move/size window for this queue */ 70 HWND MoveSize; 71 /* Current menu owner window for this queue */ 72 HWND MenuOwner; 73 /* Identifes the menu state */ 74 BYTE MenuState; 75 /* Message Queue Flags */ 76 DWORD QF_flags; 77 DWORD cThreads; // Shared message queue counter. 78 79 /* Extra message information */ 80 LPARAM ExtraInfo; 81 82 /* State of each key */ 83 BYTE afKeyRecentDown[256 / 8]; // 1 bit per key 84 BYTE afKeyState[256 * 2 / 8]; // 2 bits per key 85 86 /* Showing cursor counter (value>=0 - cursor visible, value<0 - cursor hidden) */ 87 INT iCursorLevel; 88 /* Cursor object */ 89 PCURICON_OBJECT CursorObject; 90 91 /* Caret information for this queue */ 92 THRDCARETINFO CaretInfo; 93 } USER_MESSAGE_QUEUE, *PUSER_MESSAGE_QUEUE; 94 95 #define QF_UPDATEKEYSTATE 0x00000001 96 #define QF_FMENUSTATUSBREAK 0x00000004 97 #define QF_FMENUSTATUS 0x00000008 98 #define QF_FF10STATUS 0x00000010 99 #define QF_MOUSEMOVED 0x00000020 100 #define QF_ACTIVATIONCHANGE 0x00000040 101 #define QF_TABSWITCHING 0x00000080 102 #define QF_KEYSTATERESET 0x00000100 103 #define QF_INDESTROY 0x00000200 104 #define QF_LOCKNOREMOVE 0x00000400 105 #define QF_FOCUSNULLSINCEACTIVE 0x00000800 106 #define QF_DIALOGACTIVE 0x00004000 107 #define QF_EVENTDEACTIVATEREMOVED 0x00008000 108 #define QF_TRACKMOUSELEAVE 0x00020000 109 #define QF_TRACKMOUSEHOVER 0x00040000 110 #define QF_TRACKMOUSEFIRING 0x00080000 111 #define QF_CAPTURELOCKED 0x00100000 112 #define QF_ACTIVEWNDTRACKING 0x00200000 113 114 /* Internal messages codes */ 115 enum internal_event_message 116 { 117 WM_ASYNC_SHOWWINDOW = 0x80000000, 118 WM_ASYNC_SETWINDOWPOS, 119 WM_ASYNC_SETACTIVEWINDOW, 120 WM_ASYNC_DESTROYWINDOW 121 }; 122 123 #define POSTEVENT_DAW 4 124 #define POSTEVENT_SAW 5 125 #define POSTEVENT_NWE 14 126 #define POSTEVENT_NONE 0xFFFF 127 128 extern LIST_ENTRY usmList; 129 130 BOOL FASTCALL MsqIsHung(PTHREADINFO pti, DWORD TimeOut); 131 VOID CALLBACK HungAppSysTimerProc(HWND,UINT,UINT_PTR,DWORD); 132 NTSTATUS FASTCALL co_MsqSendMessage(PTHREADINFO ptirec, 133 HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam, 134 UINT uTimeout, BOOL Block, INT HookMessage, ULONG_PTR *uResult); 135 PUSER_MESSAGE FASTCALL MsqCreateMessage(LPMSG Msg); 136 VOID FASTCALL MsqDestroyMessage(PUSER_MESSAGE Message); 137 VOID FASTCALL MsqPostMessage(PTHREADINFO, MSG*, BOOLEAN, DWORD, DWORD, LONG_PTR); 138 VOID FASTCALL MsqPostQuitMessage(PTHREADINFO pti, ULONG ExitCode); 139 BOOLEAN APIENTRY 140 MsqPeekMessage(IN PTHREADINFO pti, 141 IN BOOLEAN Remove, 142 IN PWND Window, 143 IN UINT MsgFilterLow, 144 IN UINT MsgFilterHigh, 145 IN UINT QSflags, 146 OUT LONG_PTR *ExtraInfo, 147 OUT DWORD *dwQEvent, 148 OUT PMSG Message); 149 BOOL APIENTRY 150 co_MsqPeekHardwareMessage(IN PTHREADINFO pti, 151 IN BOOL Remove, 152 IN PWND Window, 153 IN UINT MsgFilterLow, 154 IN UINT MsgFilterHigh, 155 IN UINT QSflags, 156 OUT MSG* pMsg); 157 BOOLEAN FASTCALL MsqInitializeMessageQueue(PTHREADINFO, PUSER_MESSAGE_QUEUE); 158 PUSER_MESSAGE_QUEUE FASTCALL MsqCreateMessageQueue(PTHREADINFO); 159 VOID FASTCALL MsqCleanupThreadMsgs(PTHREADINFO); 160 VOID FASTCALL MsqDestroyMessageQueue(_In_ PTHREADINFO pti); 161 CODE_SEG("INIT") NTSTATUS NTAPI MsqInitializeImpl(VOID); 162 BOOLEAN FASTCALL co_MsqDispatchOneSentMessage(_In_ PTHREADINFO pti); 163 NTSTATUS FASTCALL 164 co_MsqWaitForNewMessages(PTHREADINFO pti, PWND WndFilter, 165 UINT MsgFilterMin, UINT MsgFilterMax); 166 VOID FASTCALL MsqIncPaintCountQueue(PTHREADINFO); 167 VOID FASTCALL MsqDecPaintCountQueue(PTHREADINFO); 168 LRESULT FASTCALL co_IntSendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); 169 LRESULT FASTCALL co_IntPostOrSendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); 170 LRESULT FASTCALL 171 co_IntSendMessageTimeout(HWND hWnd, 172 UINT Msg, 173 WPARAM wParam, 174 LPARAM lParam, 175 UINT uFlags, 176 UINT uTimeout, 177 ULONG_PTR *uResult); 178 179 BOOL FASTCALL UserSendNotifyMessage( HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam ); 180 LRESULT FASTCALL co_IntSendMessageNoWait(HWND hWnd, 181 UINT Msg, 182 WPARAM wParam, 183 LPARAM lParam); 184 LRESULT FASTCALL 185 co_IntSendMessageWithCallBack(HWND hWnd, 186 UINT Msg, 187 WPARAM wParam, 188 LPARAM lParam, 189 SENDASYNCPROC CompletionCallback, 190 ULONG_PTR CompletionCallbackContext, 191 ULONG_PTR *uResult); 192 BOOL FASTCALL 193 co_MsqSendMessageAsync(PTHREADINFO ptiReceiver, 194 HWND hwnd, 195 UINT Msg, 196 WPARAM wParam, 197 LPARAM lParam, 198 SENDASYNCPROC CompletionCallback, 199 ULONG_PTR CompletionCallbackContext, 200 BOOL HasPackedLParam, 201 INT HookMessage); 202 203 VOID FASTCALL IntCoalesceMouseMove(PTHREADINFO); 204 LRESULT FASTCALL IntDispatchMessage(MSG* Msg); 205 BOOL FASTCALL IntTranslateKbdMessage(LPMSG lpMsg, UINT flags); 206 VOID FASTCALL co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook); 207 BOOL FASTCALL MsqIsClkLck(LPMSG Msg, BOOL Remove); 208 BOOL FASTCALL MsqIsDblClk(LPMSG Msg, BOOL Remove); 209 HWND FASTCALL MsqSetStateWindow(PTHREADINFO pti, ULONG Type, HWND hWnd); 210 BOOL APIENTRY IntInitMessagePumpHook(VOID); 211 BOOL APIENTRY IntUninitMessagePumpHook(VOID); 212 213 LPARAM FASTCALL MsqSetMessageExtraInfo(LPARAM lParam); 214 LPARAM FASTCALL MsqGetMessageExtraInfo(VOID); 215 VOID APIENTRY MsqRemoveWindowMessagesFromQueue(PWND pWindow); 216 217 #define IntReferenceMessageQueue(MsgQueue) \ 218 InterlockedIncrement(&(MsgQueue)->References) 219 220 #define IntDereferenceMessageQueue(MsgQueue) \ 221 do { \ 222 if(InterlockedDecrement(&(MsgQueue)->References) == 0) \ 223 { \ 224 TRACE("Free message queue 0x%p\n", (MsgQueue)); \ 225 ExFreePoolWithTag((MsgQueue), USERTAG_Q); \ 226 } \ 227 } while(0) 228 229 #define IS_BTN_MESSAGE(message,code) \ 230 ((message) == WM_LBUTTON##code || \ 231 (message) == WM_MBUTTON##code || \ 232 (message) == WM_RBUTTON##code || \ 233 (message) == WM_XBUTTON##code || \ 234 (message) == WM_NCLBUTTON##code || \ 235 (message) == WM_NCMBUTTON##code || \ 236 (message) == WM_NCRBUTTON##code || \ 237 (message) == WM_NCXBUTTON##code ) 238 239 #define WM_NCMOUSEFIRST WM_NCMOUSEMOVE 240 #define WM_NCMOUSELAST (WM_NCMOUSEFIRST+(WM_MOUSELAST-WM_MOUSEFIRST)) 241 242 #define IS_MOUSE_MESSAGE(message) \ 243 ((message >= WM_NCMOUSEFIRST && message <= WM_NCMOUSELAST) || \ 244 (message >= WM_MOUSEFIRST && message <= WM_MOUSELAST)) 245 246 #define IS_KBD_MESSAGE(message) \ 247 (message >= WM_KEYFIRST && message <= WM_KEYLAST) 248 249 HANDLE FASTCALL IntMsqSetWakeMask(DWORD WakeMask); 250 BOOL FASTCALL IntMsqClearWakeMask(VOID); 251 252 VOID FASTCALL IdlePing(VOID); 253 VOID FASTCALL IdlePong(VOID); 254 BOOL FASTCALL co_MsqReplyMessage(LRESULT); 255 VOID FASTCALL MsqWakeQueue(PTHREADINFO,DWORD,BOOL); 256 VOID FASTCALL ClearMsgBitsMask(PTHREADINFO,UINT); 257 BOOL FASTCALL IntCallMsgFilter(LPMSG,INT); 258 WPARAM FASTCALL MsqGetDownKeyState(PUSER_MESSAGE_QUEUE); 259 BOOL FASTCALL IsThreadSuspended(PTHREADINFO); 260 PUSER_SENT_MESSAGE FASTCALL AllocateUserMessage(BOOL); 261 VOID FASTCALL FreeUserMessage(PUSER_SENT_MESSAGE); 262 VOID FASTCALL MsqDestroyMessage(PUSER_MESSAGE); 263 264 int UserShowCursor(BOOL bShow); 265 PCURICON_OBJECT 266 FASTCALL 267 UserSetCursor(PCURICON_OBJECT NewCursor, 268 BOOL ForceChange); 269 270 DWORD APIENTRY IntGetQueueStatus(DWORD); 271 272 UINT lParamMemorySize(UINT Msg, WPARAM wParam, LPARAM lParam); 273 274 BOOL APIENTRY 275 co_IntGetPeekMessage( PMSG pMsg, 276 HWND hWnd, 277 UINT MsgFilterMin, 278 UINT MsgFilterMax, 279 UINT RemoveMsg, 280 BOOL bGMSG ); 281 BOOL FASTCALL 282 UserPostThreadMessage( PTHREADINFO pti, 283 UINT Msg, 284 WPARAM wParam, 285 LPARAM lParam ); 286 BOOL FASTCALL 287 co_IntWaitMessage( PWND Window, 288 UINT MsgFilterMin, 289 UINT MsgFilterMax ); 290 291 VOID FASTCALL 292 MsqReleaseModifierKeys(PUSER_MESSAGE_QUEUE MessageQueue); 293 294 /* EOF */ 295