From 54ac0f497c9a1849197dd07c0b529d15483b29a5 Mon Sep 17 00:00:00 2001 From: Giannis Adamopoulos Date: Tue, 12 Jul 2011 08:34:00 +0000 Subject: [PATCH] [user32] - Convert LOADUSERAPIHOOK macro to an inline function - Implement ClientLoadLibrary callback from win32k svn path=/branches/GSoC_2011/ThemesSupport/; revision=52648 --- dll/win32/user32/controls/scrollbar.c | 6 +- dll/win32/user32/include/user32.h | 39 ++++++---- dll/win32/user32/misc/desktop.c | 6 +- dll/win32/user32/misc/dllmain.c | 2 + dll/win32/user32/misc/usrapihk.c | 2 +- dll/win32/user32/windows/defwnd.c | 4 +- dll/win32/user32/windows/draw.c | 2 +- dll/win32/user32/windows/hook.c | 105 ++++++++++++++++++++++++++ dll/win32/user32/windows/nonclient.c | 4 +- dll/win32/user32/windows/paint.c | 2 +- include/reactos/win32k/callback.h | 14 +++- 11 files changed, 158 insertions(+), 28 deletions(-) diff --git a/dll/win32/user32/controls/scrollbar.c b/dll/win32/user32/controls/scrollbar.c index 5a37fa6b8c3..41f72404889 100644 --- a/dll/win32/user32/controls/scrollbar.c +++ b/dll/win32/user32/controls/scrollbar.c @@ -1482,7 +1482,7 @@ BOOL WINAPI EnableScrollBar( HWND hwnd, UINT nBar, UINT flags ) { BOOL Hook, Ret = FALSE; - LOADUSERAPIHOOK + LoadUserApiHook(); Hook = BeginIfHookedUserApiHook(); @@ -1534,7 +1534,7 @@ GetScrollInfo(HWND Wnd, INT SBType, LPSCROLLINFO Info) { BOOL Hook, Ret = FALSE; - LOADUSERAPIHOOK + LoadUserApiHook(); Hook = BeginIfHookedUserApiHook(); @@ -1615,7 +1615,7 @@ SetScrollInfo(HWND Wnd, int SBType, LPCSCROLLINFO Info, BOOL bRedraw) BOOL Hook; INT Ret = 0; - LOADUSERAPIHOOK + LoadUserApiHook(); Hook = BeginIfHookedUserApiHook(); diff --git a/dll/win32/user32/include/user32.h b/dll/win32/user32/include/user32.h index f93eee60a27..9b94224a7ca 100644 --- a/dll/win32/user32/include/user32.h +++ b/dll/win32/user32/include/user32.h @@ -45,6 +45,11 @@ /* SEH Support with PSEH */ #include +extern PPROCESSINFO g_ppi; +extern ULONG_PTR g_ulSharedDelta; +extern PSERVERINFO gpsi; +extern BOOL gfServerProcess; + #define HOOKID_TO_FLAG(HookId) (1 << ((HookId) + 1)) #define ISITHOOKED(HookId) (GetWin32ClientInfo()->fsHooks & HOOKID_TO_FLAG(HookId) ||\ (GetWin32ClientInfo()->pDeskInfo && GetWin32ClientInfo()->pDeskInfo->fsHooks & HOOKID_TO_FLAG(HookId))) @@ -53,30 +58,38 @@ extern RTL_CRITICAL_SECTION gcsUserApiHook; extern USERAPIHOOK guah; +extern HINSTANCE ghmodUserApiHook; BOOL FASTCALL BeginIfHookedUserApiHook(VOID); BOOL FASTCALL EndUserApiHook(VOID); BOOL FASTCALL IsInsideUserApiHook(VOID); VOID FASTCALL ResetUserApiHook(PUSERAPIHOOK); BOOL FASTCALL IsMsgOverride(UINT,PUAHOWP); +BOOL WINAPI InitUserApiHook(HINSTANCE hInstance, USERAPIHOOKPROC pfn); +BOOL WINAPI ClearUserApiHook(HINSTANCE hInstance); + +static __inline void LoadUserApiHook() +{ + if(!(gpsi->dwSRVIFlags & SRVINFO_APIHOOK)) + return; + + if(IsInsideUserApiHook()) + return; -#define LOADUSERAPIHOOK \ - if (!gfServerProcess && \ - !IsInsideUserApiHook() && \ - (gpsi->dwSRVIFlags & SRVINFO_APIHOOK) && \ - !RtlIsThreadWithinLoaderCallout()) \ - { \ - NtUserCallNoParam(NOPARAM_ROUTINE_LOADUSERAPIHOOK); \ - } \ + /* HACK! Please remove when gfServerProcess is correct */ +#if 0 + if(gfServerProcess) + return; +#endif + if(RtlIsThreadWithinLoaderCallout()) + return; + + NtUserCallNoParam(NOPARAM_ROUTINE_LOADUSERAPIHOOK); +} /* FIXME: Use ntgdi.h then cleanup... */ LONG WINAPI GdiGetCharDimensions(HDC, LPTEXTMETRICW, LONG *); BOOL FASTCALL IsMetaFile(HDC); -extern PPROCESSINFO g_ppi; -extern ULONG_PTR g_ulSharedDelta; -extern PSERVERINFO gpsi; -extern BOOL gfServerProcess; - static __inline PVOID SharedPtrToUser(PVOID Ptr) { diff --git a/dll/win32/user32/misc/desktop.c b/dll/win32/user32/misc/desktop.c index 1a317beb3f3..15fc95a0239 100644 --- a/dll/win32/user32/misc/desktop.c +++ b/dll/win32/user32/misc/desktop.c @@ -113,7 +113,7 @@ GetSystemMetrics(int nIndex) return RealGetSystemMetrics(nIndex); } - LOADUSERAPIHOOK + LoadUserApiHook(); Hook = BeginIfHookedUserApiHook(); @@ -336,7 +336,7 @@ SystemParametersInfoA(UINT uiAction, { BOOL Hook, Ret = FALSE; - LOADUSERAPIHOOK + LoadUserApiHook(); Hook = BeginIfHookedUserApiHook(); @@ -368,7 +368,7 @@ SystemParametersInfoW(UINT uiAction, { BOOL Hook, Ret = FALSE; - LOADUSERAPIHOOK + LoadUserApiHook(); Hook = BeginIfHookedUserApiHook(); diff --git a/dll/win32/user32/misc/dllmain.c b/dll/win32/user32/misc/dllmain.c index b3c46ff7c9b..919cb89b44a 100644 --- a/dll/win32/user32/misc/dllmain.c +++ b/dll/win32/user32/misc/dllmain.c @@ -217,6 +217,8 @@ Init(VOID) (PVOID)User32CallLoadMenuFromKernel; KernelCallbackTable[USER32_CALLBACK_CLIENTTHREADSTARTUP] = (PVOID)User32CallClientThreadSetupFromKernel; + KernelCallbackTable[USER32_CALLBACK_CLIENTLOADLIBRARY] = + (PVOID)User32CallClientLoadLibraryFromKernel; NtUserProcessConnect( NtCurrentProcess(), &UserCon, diff --git a/dll/win32/user32/misc/usrapihk.c b/dll/win32/user32/misc/usrapihk.c index 24ebdf5f503..4dabbbe9942 100644 --- a/dll/win32/user32/misc/usrapihk.c +++ b/dll/win32/user32/misc/usrapihk.c @@ -318,7 +318,7 @@ MDIRedrawFrame(HWND hWnd, DWORD flags) { BOOL Hook, Ret = FALSE; - LOADUSERAPIHOOK + LoadUserApiHook(); Hook = BeginIfHookedUserApiHook(); diff --git a/dll/win32/user32/windows/defwnd.c b/dll/win32/user32/windows/defwnd.c index e8fda2ffb07..129fdd17e38 100644 --- a/dll/win32/user32/windows/defwnd.c +++ b/dll/win32/user32/windows/defwnd.c @@ -2209,7 +2209,7 @@ DefWindowProcA(HWND hWnd, BOOL Hook, msgOverride = FALSE; LRESULT Result = 0; - LOADUSERAPIHOOK + LoadUserApiHook(); Hook = BeginIfHookedUserApiHook(); if (Hook) @@ -2242,7 +2242,7 @@ DefWindowProcW(HWND hWnd, BOOL Hook, msgOverride = FALSE; LRESULT Result = 0; - LOADUSERAPIHOOK + LoadUserApiHook(); Hook = BeginIfHookedUserApiHook(); if (Hook) diff --git a/dll/win32/user32/windows/draw.c b/dll/win32/user32/windows/draw.c index 5ecf9a53462..d9c2dd6b549 100644 --- a/dll/win32/user32/windows/draw.c +++ b/dll/win32/user32/windows/draw.c @@ -1457,7 +1457,7 @@ DrawFrameControl(HDC hDC, LPRECT rc, UINT uType, UINT uState) { BOOL Hook, Ret = FALSE; - LOADUSERAPIHOOK + LoadUserApiHook(); Hook = BeginIfHookedUserApiHook(); diff --git a/dll/win32/user32/windows/hook.c b/dll/win32/user32/windows/hook.c index ff982eebcc6..40581eb7b6a 100644 --- a/dll/win32/user32/windows/hook.c +++ b/dll/win32/user32/windows/hook.c @@ -427,6 +427,111 @@ SetWindowsHookExW( return IntSetWindowsHook(idHook, lpfn, hMod, dwThreadId, FALSE); } +HINSTANCE ClientLoadLibrary(PUNICODE_STRING pstrLibName, + PUNICODE_STRING pstrInitFunc, + BOOL Unload, + BOOL ApiHook) +{ + HINSTANCE hLibrary; + PVOID pInitFunction; + NTSTATUS Status; + ANSI_STRING InitFuncName; + BOOL Result = FALSE; + + /* Check if we have to load the module */ + if(Unload == FALSE) + { + ASSERT(pstrLibName->Buffer != NULL); + + /* Load it */ + hLibrary = LoadLibrary(pstrLibName->Buffer); + if(hLibrary == 0) + { + return hLibrary; + } + + if(ApiHook == FALSE) + { + /* There is nothing more to do for a global hook*/ + return hLibrary; + } + + /* Initialize the user api hook */ + ASSERT(pstrInitFunc->Buffer); + + Status = RtlUnicodeStringToAnsiString(&InitFuncName, + pstrInitFunc, + TRUE); + + /* Get the address of the initialization routine */ + pInitFunction = GetProcAddress(hLibrary, InitFuncName.Buffer); + if(pInitFunction) + { + /* Call the initialization routine */ + Result = InitUserApiHook(hLibrary, (USERAPIHOOKPROC)pInitFunction); + } + RtlFreeAnsiString(&InitFuncName); + + /* In case of error unload the library */ + if(Result == FALSE) + { + FreeLibrary(hLibrary); + hLibrary = 0; + } + } + else + { + /* Cleanup user api hook before unloading */ + if(ApiHook == TRUE) + { + Result = ClearUserApiHook(ghmodUserApiHook); + hLibrary = Result ? ghmodUserApiHook : 0; + } + else + { + hLibrary = GetModuleHandle(pstrLibName->Buffer); + Result = (hLibrary != 0); + } + + if(Result == TRUE) + { + Result = FreeLibrary(hLibrary); + if(Result == FALSE) + { + hLibrary = 0; + } + } + } + + return hLibrary; +} + +NTSTATUS WINAPI +User32CallClientLoadLibraryFromKernel(PVOID Arguments, ULONG ArgumentLength) +{ + HINSTANCE Result; + PCLIENT_LOAD_LIBRARY_ARGUMENTS Argument; + + /* Retireve the callback parameters */ + Argument = (PCLIENT_LOAD_LIBRARY_ARGUMENTS)Arguments; + if(Argument->strLibraryName.Buffer != NULL) + { + Argument->strLibraryName.Buffer = (PWCHAR)((ULONG_PTR)Argument->strLibraryName.Buffer + (ULONG_PTR)Argument); + } + if(Argument->strInitFuncName.Buffer != NULL) + { + Argument->strInitFuncName.Buffer = (PWCHAR)((ULONG_PTR)Argument->strInitFuncName.Buffer + (ULONG_PTR)Argument); + } + + /* Call the implementation of the callback */ + Result = ClientLoadLibrary(&Argument->strLibraryName, + &Argument->strInitFuncName, + Argument->Unload, + Argument->ApiHook); + + return ZwCallbackReturn(&Result, sizeof(HINSTANCE), STATUS_SUCCESS); +} + NTSTATUS WINAPI User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength) { diff --git a/dll/win32/user32/windows/nonclient.c b/dll/win32/user32/windows/nonclient.c index 19f18256f15..5d3d9afe675 100644 --- a/dll/win32/user32/windows/nonclient.c +++ b/dll/win32/user32/windows/nonclient.c @@ -1104,7 +1104,7 @@ AdjustWindowRectEx(LPRECT lpRect, { BOOL Hook, Ret = FALSE; - LOADUSERAPIHOOK + LoadUserApiHook(); Hook = BeginIfHookedUserApiHook(); @@ -1148,7 +1148,7 @@ DrawCaption(HWND hWnd, HDC hDC, LPCRECT lprc, UINT uFlags) { BOOL Hook, Ret = FALSE; - LOADUSERAPIHOOK + LoadUserApiHook(); Hook = BeginIfHookedUserApiHook(); diff --git a/dll/win32/user32/windows/paint.c b/dll/win32/user32/windows/paint.c index dff5f98afd3..fd7cc57fafb 100644 --- a/dll/win32/user32/windows/paint.c +++ b/dll/win32/user32/windows/paint.c @@ -200,7 +200,7 @@ SetWindowRgn( BOOL Hook; int Ret = 0; - LOADUSERAPIHOOK + LoadUserApiHook(); Hook = BeginIfHookedUserApiHook(); diff --git a/include/reactos/win32k/callback.h b/include/reactos/win32k/callback.h index 76792380bd2..5e1cd08c4bb 100644 --- a/include/reactos/win32k/callback.h +++ b/include/reactos/win32k/callback.h @@ -9,7 +9,8 @@ #define USER32_CALLBACK_EVENTPROC (5) #define USER32_CALLBACK_LOADMENU (6) #define USER32_CALLBACK_CLIENTTHREADSTARTUP (7) -#define USER32_CALLBACK_MAXIMUM (7) +#define USER32_CALLBACK_CLIENTLOADLIBRARY (8) +#define USER32_CALLBACK_MAXIMUM (8) typedef struct _WINDOWPROC_CALLBACK_ARGUMENTS { @@ -76,6 +77,14 @@ typedef struct _LOADMENU_CALLBACK_ARGUMENTS WCHAR MenuName[1]; } LOADMENU_CALLBACK_ARGUMENTS, *PLOADMENU_CALLBACK_ARGUMENTS; +typedef struct _CLIENT_LOAD_LIBRARY_ARGUMENTS +{ + UNICODE_STRING strLibraryName; + UNICODE_STRING strInitFuncName; + BOOL Unload; + BOOL ApiHook; +} CLIENT_LOAD_LIBRARY_ARGUMENTS, *PCLIENT_LOAD_LIBRARY_ARGUMENTS; + NTSTATUS WINAPI User32CallWindowProcFromKernel(PVOID Arguments, ULONG ArgumentLength); NTSTATUS WINAPI @@ -92,5 +101,6 @@ NTSTATUS WINAPI User32CallLoadMenuFromKernel(PVOID Arguments, ULONG ArgumentLength); NTSTATUS WINAPI User32CallClientThreadSetupFromKernel(PVOID Arguments, ULONG ArgumentLength); - +NTSTATUS WINAPI +User32CallClientLoadLibraryFromKernel(PVOID Arguments, ULONG ArgumentLength); #endif /* __INCLUDE_USER32_CALLBACK_H */ -- 2.17.1