diff --git a/reactos/include/napi/win32.h b/reactos/include/napi/win32.h index 843cb5cd27b..77c6124e0e8 100644 --- a/reactos/include/napi/win32.h +++ b/reactos/include/napi/win32.h @@ -8,6 +8,7 @@ typedef struct _W32THREAD LIST_ENTRY WindowListHead; struct _KBDTABLES* KeyboardLayout; struct _DESKTOP_OBJECT* Desktop; + DWORD MessagePumpHookValue; } __attribute__((packed)) W32THREAD, *PW32THREAD; typedef struct _W32PROCESS diff --git a/reactos/include/win32k/ntuser.h b/reactos/include/win32k/ntuser.h index 75d379f9b1e..2d5dc86eaec 100644 --- a/reactos/include/win32k/ntuser.h +++ b/reactos/include/win32k/ntuser.h @@ -157,6 +157,8 @@ NtUserCallNextHookEx( #define NOPARAM_ROUTINE_REGISTER_PRIMITIVE 0xffff0001 /* Private ROS */ #define NOPARAM_ROUTINE_DESTROY_CARET 0xffff0002 +#define NOPARAM_ROUTINE_UNINIT_MESSAGE_PUMP 0xffff0003 +#define NOPARAM_ROUTINE_INIT_MESSAGE_PUMP 0xffff0004 DWORD STDCALL NtUserCallNoParam( diff --git a/reactos/lib/user32/misc/dllmain.c b/reactos/lib/user32/misc/dllmain.c index 611cb1eec78..095e6869c98 100644 --- a/reactos/lib/user32/misc/dllmain.c +++ b/reactos/lib/user32/misc/dllmain.c @@ -14,6 +14,7 @@ DWORD DebugTraceLevel = MIN_TRACE; #endif /* DBG */ +extern RTL_CRITICAL_SECTION gcsMPH; static ULONG User32TlsIndex; /* To make the linker happy */ @@ -85,6 +86,7 @@ Init(VOID) MenuInit(); RtlInitializeCriticalSection(&U32AccelCacheLock); + RtlInitializeCriticalSection(&gcsMPH); GdiDllInitialize(NULL, DLL_PROCESS_ATTACH, NULL); diff --git a/reactos/lib/user32/misc/stubs.c b/reactos/lib/user32/misc/stubs.c index d952b77aa11..b709e4931c4 100644 --- a/reactos/lib/user32/misc/stubs.c +++ b/reactos/lib/user32/misc/stubs.c @@ -1,6 +1,6 @@ -/* $Id: stubs.c,v 1.52 2003/11/19 12:48:47 weiden Exp $ +/* $Id: stubs.c,v 1.53 2003/11/19 13:19:39 weiden Exp $ * - * COPYRIGHT: See COPYING WINBOOLthe top level directory + * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS user32.dll * FILE: lib/user32/misc/stubs.c * PURPOSE: User32.dll stubs @@ -217,9 +217,9 @@ MsgWaitForMultipleObjects( */ DWORD STDCALL -MsgWaitForMultipleObjectsEx( +RealMsgWaitForMultipleObjectsEx( DWORD nCount, - CONST HANDLE pHandles, + LPHANDLE pHandles, DWORD dwMilliseconds, DWORD dwWakeMask, DWORD dwFlags) @@ -1093,3 +1093,83 @@ VOID STDCALL InitializeLpkHooks(FARPROC *hookfuncs) { UNIMPLEMENTED; } + +/* + * @unimplemented + */ +WORD STDCALL InitializeWin32EntryTable(UCHAR* EntryTablePlus0x1000) +{ + UNIMPLEMENTED; + return FALSE; +} + +/* + * @unimplemented + */ +BOOL STDCALL IsServerSideWindow(HWND wnd) +{ + UNIMPLEMENTED; + return FALSE; +} + +typedef BOOL (CALLBACK *THEME_HOOK_FUNC) (DWORD state,PVOID arg2); //return type and 2nd parameter unknown +/* + * @unimplemented + */ +BOOL STDCALL RegisterUserApiHook(HINSTANCE instance,THEME_HOOK_FUNC proc) +{ + UNIMPLEMENTED; + return FALSE; +} + +/* + * @unimplemented + */ +BOOL STDCALL UnregisterUserApiHook(VOID) +{ + UNIMPLEMENTED; + return FALSE; +} + +/* + * @unimplemented + */ +BOOL STDCALL IsWindowInDestroy(HWND wnd) +{ + UNIMPLEMENTED; + return FALSE; +} + +/* + * @unimplemented + */ +HKL STDCALL LoadKeyboardLayoutEx(DWORD unknown,LPCWSTR pwszKLID,UINT Flags) //1st parameter unknown +{ + UNIMPLEMENTED; + return FALSE; +} + +/* + * @unimplemented + */ +VOID STDCALL AllowForegroundActivation(VOID) +{ + UNIMPLEMENTED; +} + +/* + * @unimplemented + */ +VOID STDCALL ShowStartGlass(DWORD unknown) +{ + UNIMPLEMENTED; +} + +/* + * @unimplemented + */ +BOOL STDCALL DdeGetQualityOfService(HWND hWnd, DWORD Reserved, PSECURITY_QUALITY_OF_SERVICE pqosPrev) +{ + UNIMPLEMENTED; + return FALSE; +} diff --git a/reactos/lib/user32/user32.def b/reactos/lib/user32/user32.def index ca29f4e05ba..47f21bc30e2 100644 --- a/reactos/lib/user32/user32.def +++ b/reactos/lib/user32/user32.def @@ -5,7 +5,7 @@ ActivateKeyboardLayout@8 AdjustWindowRect@12 AdjustWindowRectEx@16 AlignRects@16 -;AllowForegroundActivation +AllowForegroundActivation@0 AllowSetForegroundWindow@4 AnimateWindow@12 AnyPopup@0 @@ -121,7 +121,7 @@ DdeFreeDataHandle@4 DdeFreeStringHandle@8 DdeGetData@16 DdeGetLastError@4 -;DdeGetQualityOfService +DdeGetQualityOfService@12 DdeImpersonateClient@4 DdeInitializeA@16 DdeInitializeW@16 @@ -399,7 +399,7 @@ InSendMessage@0 InSendMessageEx@4 InflateRect@12 InitializeLpkHooks@4 -;InitializeWin32EntryTable +InitializeWin32EntryTable@4 InsertMenuA@20 InsertMenuItemA@16 InsertMenuItemW@16 @@ -428,10 +428,10 @@ IsHungAppWindow@4 IsIconic@4 IsMenu@4 IsRectEmpty@4 -;IsServerSideWindow +IsServerSideWindow@4 IsWindow@4 IsWindowEnabled@4 -;IsWindowInDestroy +IsWindowInDestroy@4 IsWindowUnicode@4 IsWindowVisible@4 IsWinEventHookInstalled@4 @@ -451,7 +451,7 @@ LoadIconW@8 LoadImageA@24 LoadImageW@24 LoadKeyboardLayoutA@8 -;LoadKeyboardLayoutEx +LoadKeyboardLayoutEx@12 LoadKeyboardLayoutW@8 LoadLocalFonts@0 LoadMenuA@8 @@ -547,12 +547,12 @@ RegisterDeviceNotificationA@12 RegisterDeviceNotificationW@12 RegisterHotKey@16 RegisterLogonProcess@8 -;RegisterMessagePumpHook +RegisterMessagePumpHook@4 RegisterRawInputDevices@12 RegisterServicesProcess@4 RegisterShellHookWindow@4 RegisterSystemThread@8 -;RegisterUserApiHook +RegisterUserApiHook@8 RegisterTasklist@4 RegisterWindowMessageA@4 RegisterWindowMessageW@4 @@ -660,7 +660,7 @@ ShowCaret@4 ShowCursor@4 ShowOwnedPopups@8 ShowScrollBar@12 -;ShowStartGlass +ShowStartGlass@4 ShowWindow@8 ShowWindowAsync@8 SoftModalMessageBox@4 @@ -697,8 +697,8 @@ UnregisterClassA@8 UnregisterClassW@8 UnregisterDeviceNotification@4 UnregisterHotKey@8 -;UnregisterMessagePumpHook -;UnregisterUserApiHook +UnregisterMessagePumpHook@0 +UnregisterUserApiHook@0 UpdateLayeredWindow@36 ;UpdatePerUserSystemParameters UpdateWindow@4 diff --git a/reactos/lib/user32/user32.edf b/reactos/lib/user32/user32.edf index 815707ebbde..85359c91461 100644 --- a/reactos/lib/user32/user32.edf +++ b/reactos/lib/user32/user32.edf @@ -5,7 +5,7 @@ ActivateKeyboardLayout=ActivateKeyboardLayout@8 AdjustWindowRect=AdjustWindowRect@12 AdjustWindowRectEx=AdjustWindowRectEx@16 AlignRects=AlignRects@16 -;AllowForegroundActivation +AllowForegroundActivation=AllowForegroundActivation@0 AllowSetForegroundWindow=AllowSetForegroundWindow@4 AnimateWindow=AnimateWindow@12 AnyPopup=AnyPopup@0 @@ -121,7 +121,7 @@ DdeFreeDataHandle=DdeFreeDataHandle@4 DdeFreeStringHandle=DdeFreeStringHandle@8 DdeGetData=DdeGetData@16 DdeGetLastError=DdeGetLastError@4 -;DdeGetQualityOfService +DdeGetQualityOfService=DdeGetQualityOfService@12 DdeImpersonateClient=DdeImpersonateClient@4 DdeInitializeA=DdeInitializeA@16 DdeInitializeW=DdeInitializeW@16 @@ -400,7 +400,7 @@ InSendMessage=InSendMessage@0 InSendMessageEx=InSendMessageEx@4 InflateRect=InflateRect@12 InitializeLpkHooks=InitializeLpkHooks@4 -;InitializeWin32EntryTable +InitializeWin32EntryTable=InitializeWin32EntryTable@4 InsertMenuA=InsertMenuA@20 InsertMenuItemA=InsertMenuItemA@16 InsertMenuItemW=InsertMenuItemW@16 @@ -429,10 +429,10 @@ IsHungAppWindow=IsHungAppWindow@4 IsIconic=IsIconic@4 IsMenu=IsMenu@4 IsRectEmpty=IsRectEmpty@4 -;IsServerSideWindow +IsServerSideWindow=IsServerSideWindow@4 IsWindow=IsWindow@4 IsWindowEnabled=IsWindowEnabled@4 -;IsWindowInDestroy +IsWindowInDestroy=IsWindowInDestroy@4 IsWindowUnicode=IsWindowUnicode@4 IsWindowVisible=IsWindowVisible@4 IsWinEventHookInstalled=IsWinEventHookInstalled@4 @@ -452,7 +452,7 @@ LoadIconW=LoadIconW@8 LoadImageA=LoadImageA@24 LoadImageW=LoadImageW@24 LoadKeyboardLayoutA=LoadKeyboardLayoutA@8 -;LoadKeyboardLayoutEx +LoadKeyboardLayoutEx=LoadKeyboardLayoutEx@12 LoadKeyboardLayoutW=LoadKeyboardLayoutW@8 LoadLocalFonts=LoadLocalFonts@0 LoadMenuA=LoadMenuA@8 @@ -549,12 +549,12 @@ RegisterDeviceNotificationA=RegisterDeviceNotificationA@12 RegisterDeviceNotificationW=RegisterDeviceNotificationW@12 RegisterHotKey=RegisterHotKey@16 RegisterLogonProcess=RegisterLogonProcess@8 -;RegisterMessagePumpHook +RegisterMessagePumpHook=RegisterMessagePumpHook@4 RegisterRawInputDevices=RegisterRawInputDevices@12 RegisterServicesProcess=RegisterServicesProcess@4 RegisterShellHookWindow=RegisterShellHookWindow@4 RegisterSystemThread=RegisterSystemThread@8 -;RegisterUserApiHook +RegisterUserApiHook=RegisterUserApiHook@8 RegisterTasklist=RegisterTasklist@4 RegisterWindowMessageA=RegisterWindowMessageA@4 RegisterWindowMessageW=RegisterWindowMessageW@4 @@ -662,7 +662,7 @@ ShowCaret=ShowCaret@4 ShowCursor=ShowCursor@4 ShowOwnedPopups=ShowOwnedPopups@8 ShowScrollBar=ShowScrollBar@12 -;ShowStartGlass +ShowStartGlass=ShowStartGlass@4 ShowWindow=ShowWindow@8 ShowWindowAsync=ShowWindowAsync@8 SoftModalMessageBox=SoftModalMessageBox@4 @@ -700,8 +700,8 @@ UnregisterClassA=UnregisterClassA@8 UnregisterClassW=UnregisterClassW@8 UnregisterDeviceNotification=UnregisterDeviceNotification@4 UnregisterHotKey=UnregisterHotKey@8 -;UnregisterMessagePumpHook -;UnregisterUserApiHook +UnregisterMessagePumpHook=UnregisterMessagePumpHook@0 +UnregisterUserApiHook=UnregisterUserApiHook@0 UpdateLayeredWindow=UpdateLayeredWindow@36 ;UpdatePerUserSystemParameters UpdateWindow=UpdateWindow@4 diff --git a/reactos/lib/user32/windows/message.c b/reactos/lib/user32/windows/message.c index dc306a16b05..07e462d5c59 100644 --- a/reactos/lib/user32/windows/message.c +++ b/reactos/lib/user32/windows/message.c @@ -1,4 +1,4 @@ -/* $Id: message.c,v 1.27 2003/11/11 20:28:21 gvg Exp $ +/* $Id: message.c,v 1.28 2003/11/19 13:19:39 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS user32.dll @@ -899,7 +899,7 @@ ReleaseCapture(VOID) */ DWORD STDCALL -GetQueueStatus(UINT flags) +RealGetQueueStatus(UINT flags) { DWORD ret; WORD changed_bits, wake_bits; @@ -950,7 +950,126 @@ WINBOOL STDCALL SetMessageQueue(int cMessagesMax) /* Function does nothing on 32 bit windows */ return TRUE; } +typedef DWORD (WINAPI * RealGetQueueStatusProc)(UINT flags); +typedef DWORD (WINAPI * RealMsgWaitForMultipleObjectsExProc)(DWORD nCount, LPHANDLE lpHandles, DWORD dwMilliseconds, DWORD dwWakeMask, DWORD dwFlags); +typedef struct _USER_MESSAGE_PUMP_ADDRESSES { + DWORD cbSize; + //NtUserRealInternalGetMessageProc NtUserRealInternalGetMessage; + //NtUserRealWaitMessageExProc NtUserRealWaitMessageEx; + RealGetQueueStatusProc RealGetQueueStatus; + RealMsgWaitForMultipleObjectsExProc RealMsgWaitForMultipleObjectsEx; +} USER_MESSAGE_PUMP_ADDRESSES, * PUSER_MESSAGE_PUMP_ADDRESSES; +DWORD +STDCALL +RealMsgWaitForMultipleObjectsEx( + DWORD nCount, + LPHANDLE pHandles, + DWORD dwMilliseconds, + DWORD dwWakeMask, + DWORD dwFlags); -/* EOF */ +typedef BOOL (WINAPI * MESSAGEPUMPHOOKPROC)(BOOL Unregistering,PUSER_MESSAGE_PUMP_ADDRESSES MessagePumpAddresses); + +RTL_CRITICAL_SECTION gcsMPH; +MESSAGEPUMPHOOKPROC gpfnInitMPH; +DWORD gcLoadMPH = 0; +USER_MESSAGE_PUMP_ADDRESSES gmph = {sizeof(USER_MESSAGE_PUMP_ADDRESSES), + //NtUserRealInternalGetMessage, + //NtUserRealInternalWaitMessageEx, + RealGetQueueStatus, + RealMsgWaitForMultipleObjectsEx +}; + +DWORD gfMessagePumpHook = 0; + +BOOL WINAPI IsInsideMessagePumpHook() +{ + if(!gfMessagePumpHook) + return FALSE; + + /* Since our TEB doesnt match that of real windows, testing this value is useless until we know what it does + PUCHAR NtTeb = (PUCHAR)NtCurrentTeb(); + + if(!*(PLONG*)&NtTeb[0x708]) + return FALSE; + + if(**(PLONG*)&NtTeb[0x708] <= 0) + return FALSE;*/ + + return TRUE; +} + +void WINAPI ResetMessagePumpHook(PUSER_MESSAGE_PUMP_ADDRESSES Addresses) +{ + Addresses->cbSize = sizeof(USER_MESSAGE_PUMP_ADDRESSES); + //Addresses->NtUserRealInternalGetMessage = (NtUserRealInternalGetMessageProc)NtUserRealInternalGetMessage; + //Addresses->NtUserRealWaitMessageEx = (NtUserRealWaitMessageExProc)NtUserRealInternalWaitMessageEx; + Addresses->RealGetQueueStatus = RealGetQueueStatus; + Addresses->RealMsgWaitForMultipleObjectsEx = RealMsgWaitForMultipleObjectsEx; +} + +BOOL WINAPI RegisterMessagePumpHook(MESSAGEPUMPHOOKPROC Hook) +{ + RtlEnterCriticalSection(&gcsMPH); + if(!Hook) { + SetLastError(ERROR_INVALID_PARAMETER); + RtlLeaveCriticalSection(&gcsMPH); + return FALSE; + } + if(!gcLoadMPH) { + USER_MESSAGE_PUMP_ADDRESSES Addresses; + gpfnInitMPH = Hook; + ResetMessagePumpHook(&Addresses); + if(!Hook(FALSE, &Addresses) || !Addresses.cbSize) { + RtlLeaveCriticalSection(&gcsMPH); + return FALSE; + } + memcpy(&gmph, &Addresses, Addresses.cbSize); + } else { + if(gpfnInitMPH != Hook) { + RtlLeaveCriticalSection(&gcsMPH); + return FALSE; + } + } + if(NtUserCallNoParam(NOPARAM_ROUTINE_INIT_MESSAGE_PUMP)) { + RtlLeaveCriticalSection(&gcsMPH); + return FALSE; + } + if (!gcLoadMPH++) { + InterlockedExchange(&gfMessagePumpHook, 1); + } + RtlLeaveCriticalSection(&gcsMPH); + return TRUE; +} + +BOOL WINAPI UnregisterMessagePumpHook(VOID) +{ + RtlEnterCriticalSection(&gcsMPH); + if(gcLoadMPH > 0) { + if(NtUserCallNoParam(NOPARAM_ROUTINE_UNINIT_MESSAGE_PUMP)) { + gcLoadMPH--; + if(!gcLoadMPH) { + InterlockedExchange(&gfMessagePumpHook, 0); + gpfnInitMPH(TRUE, NULL); + ResetMessagePumpHook(&gmph); + gpfnInitMPH = 0; + } + RtlLeaveCriticalSection(&gcsMPH); + return TRUE; + } + } + RtlLeaveCriticalSection(&gcsMPH); + return FALSE; +} + +DWORD WINAPI GetQueueStatus(UINT flags) +{ + return IsInsideMessagePumpHook() ? gmph.RealGetQueueStatus(flags) : RealGetQueueStatus(flags); +} + +DWORD WINAPI MsgWaitForMultipleObjectsEx(DWORD nCount, LPHANDLE lpHandles, DWORD dwMilliseconds, DWORD dwWakeMask, DWORD dwFlags) +{ + return IsInsideMessagePumpHook() ? gmph.RealMsgWaitForMultipleObjectsEx(nCount, lpHandles,dwMilliseconds, dwWakeMask, dwFlags) : RealMsgWaitForMultipleObjectsEx(nCount, lpHandles,dwMilliseconds, dwWakeMask, dwFlags); +} diff --git a/reactos/subsys/win32k/include/msgqueue.h b/reactos/subsys/win32k/include/msgqueue.h index 840a6ca8165..1c64b8b0017 100644 --- a/reactos/subsys/win32k/include/msgqueue.h +++ b/reactos/subsys/win32k/include/msgqueue.h @@ -138,7 +138,8 @@ MsqInsertSystemMessage(MSG* Msg, BOOL RemMouseMoveMsg); inline BOOL MsqIsSignaled( PUSER_MESSAGE_QUEUE queue ); inline VOID MsqSetQueueBits( PUSER_MESSAGE_QUEUE queue, WORD bits ); inline VOID MsqClearQueueBits( PUSER_MESSAGE_QUEUE queue, WORD bits ); - +BOOL IntInitMessagePumpHook(); +BOOL IntUninitMessagePumpHook(); #define MAKE_LONG(x, y) ((((y) & 0xFFFF) << 16) | ((x) & 0xFFFF)) #endif /* _WIN32K_MSGQUEUE_H */ diff --git a/reactos/subsys/win32k/main/dllmain.c b/reactos/subsys/win32k/main/dllmain.c index 00dddfe90d4..78e703b5026 100644 --- a/reactos/subsys/win32k/main/dllmain.c +++ b/reactos/subsys/win32k/main/dllmain.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: dllmain.c,v 1.51 2003/11/18 23:33:31 weiden Exp $ +/* $Id: dllmain.c,v 1.52 2003/11/19 13:19:40 weiden Exp $ * * Entry Point for win32k.sys */ @@ -127,6 +127,7 @@ Win32kThreadCallback (struct _ETHREAD *Thread, IntDestroyCaret(Win32Thread); Win32Thread->MessageQueue = MsqCreateMessageQueue(Thread); Win32Thread->KeyboardLayout = W32kGetDefaultKeyLayout(); + Win32Thread->MessagePumpHookValue = 0; InitializeListHead(&Win32Thread->WindowListHead); ExInitializeFastMutex(&Win32Thread->WindowListLock); diff --git a/reactos/subsys/win32k/ntuser/message.c b/reactos/subsys/win32k/ntuser/message.c index 6a7467982a3..247d3a53ebb 100644 --- a/reactos/subsys/win32k/ntuser/message.c +++ b/reactos/subsys/win32k/ntuser/message.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: message.c,v 1.32 2003/11/18 20:49:39 navaraf Exp $ +/* $Id: message.c,v 1.33 2003/11/19 13:19:40 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -593,4 +593,22 @@ NtUserGetQueueStatus(BOOL ClearChanges) return Result; } +BOOL STDCALL +IntInitMessagePumpHook() +{ + PsGetCurrentThread()->Win32Thread->MessagePumpHookValue++; + return TRUE; +} + +BOOL STDCALL +IntUninitMessagePumpHook() +{ + if (PsGetCurrentThread()->Win32Thread->MessagePumpHookValue <= 0) + { + return FALSE; + } + PsGetCurrentThread()->Win32Thread->MessagePumpHookValue--; + return TRUE; +} + /* EOF */ diff --git a/reactos/subsys/win32k/ntuser/misc.c b/reactos/subsys/win32k/ntuser/misc.c index 3334e54d929..be41f0907e4 100644 --- a/reactos/subsys/win32k/ntuser/misc.c +++ b/reactos/subsys/win32k/ntuser/misc.c @@ -1,4 +1,4 @@ -/* $Id: misc.c,v 1.25 2003/11/19 12:25:03 weiden Exp $ +/* $Id: misc.c,v 1.26 2003/11/19 13:19:40 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -64,6 +64,14 @@ NtUserCallNoParam(DWORD Routine) Result = (DWORD)IntDestroyCaret(PsGetCurrentThread()->Win32Thread); break; + case NOPARAM_ROUTINE_INIT_MESSAGE_PUMP: + Result = (DWORD)IntInitMessagePumpHook(); + break; + + case NOPARAM_ROUTINE_UNINIT_MESSAGE_PUMP: + Result = (DWORD)IntUninitMessagePumpHook(); + break; + default: DPRINT1("Calling invalid routine number 0x%x in NtUserCallTwoParam\n"); SetLastWin32Error(ERROR_INVALID_PARAMETER);