diff --git a/reactos/dll/win32/user32/include/user32p.h b/reactos/dll/win32/user32/include/user32p.h index 687ad62876c..c69b2277db4 100644 --- a/reactos/dll/win32/user32/include/user32p.h +++ b/reactos/dll/win32/user32/include/user32p.h @@ -23,11 +23,14 @@ extern HINSTANCE User32Instance; extern PPROCESSINFO g_ppi; extern ULONG_PTR g_ulSharedDelta; extern PSERVERINFO gpsi; -extern BOOL gfServerProcess; +extern BOOLEAN gfServerProcess; extern PUSER_HANDLE_TABLE gHandleTable; extern PUSER_HANDLE_ENTRY gHandleEntries; extern CRITICAL_SECTION U32AccelCacheLock; extern HINSTANCE hImmInstance; +extern RTL_CRITICAL_SECTION gcsUserApiHook; +extern USERAPIHOOK guah; +extern HINSTANCE ghmodUserApiHook; #define IS_ATOM(x) \ (((ULONG_PTR)(x) > 0x0) && ((ULONG_PTR)(x) < 0x10000)) @@ -51,13 +54,13 @@ extern void SPY_ExitMessage(INT iFlag, HWND hwnd, UINT msg, LRESULT lReturn, WPA extern int SPY_Init(void); /* definitions for usrapihk.c */ -extern RTL_CRITICAL_SECTION gcsUserApiHook; -extern USERAPIHOOK guah; 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); /* definitions for message.c */ BOOL FASTCALL MessageInit(VOID); diff --git a/reactos/dll/win32/user32/misc/dllmain.c b/reactos/dll/win32/user32/misc/dllmain.c index 242eee15e56..164a5aa4969 100644 --- a/reactos/dll/win32/user32/misc/dllmain.c +++ b/reactos/dll/win32/user32/misc/dllmain.c @@ -13,7 +13,7 @@ PUSER_HANDLE_TABLE gHandleTable = NULL; PUSER_HANDLE_ENTRY gHandleEntries = NULL; PSERVERINFO gpsi = NULL; ULONG_PTR g_ulSharedDelta; -BOOL gfServerProcess = FALSE; +BOOLEAN gfServerProcess = FALSE; WCHAR szAppInit[KEY_LENGTH]; @@ -198,7 +198,7 @@ Init(VOID) { USERCONNECT UserCon; PVOID *KernelCallbackTable; - + /* Set up the kernel callbacks. */ KernelCallbackTable = NtCurrentPeb()->KernelCallbackTable; KernelCallbackTable[USER32_CALLBACK_WINDOWPROC] = @@ -217,6 +217,8 @@ Init(VOID) (PVOID)User32CallLoadMenuFromKernel; KernelCallbackTable[USER32_CALLBACK_CLIENTTHREADSTARTUP] = (PVOID)User32CallClientThreadSetupFromKernel; + KernelCallbackTable[USER32_CALLBACK_CLIENTLOADLIBRARY] = + (PVOID)User32CallClientLoadLibraryFromKernel; NtUserProcessConnect( NtCurrentProcess(), &UserCon, @@ -229,8 +231,9 @@ Init(VOID) gHandleEntries = SharedPtrToUser(gHandleTable->handles); RtlInitializeCriticalSection(&gcsUserApiHook); - gfServerProcess = TRUE; // FIXME HAX! Used in CsrClientConnectToServer(,,,,&gfServerProcess); + gfServerProcess = FALSE; // FIXME HAX! Used in CsrClientConnectToServer(,,,,&gfServerProcess); + //CsrClientConnectToServer(L"\\Windows", 0, NULL, 0, &gfServerProcess); //ERR("1 SI 0x%x : HT 0x%x : D 0x%x\n", UserCon.siClient.psi, UserCon.siClient.aheList, g_ulSharedDelta); /* Allocate an index for user32 thread local data. */ diff --git a/reactos/dll/win32/user32/misc/usrapihk.c b/reactos/dll/win32/user32/misc/usrapihk.c index 67bbada0d61..8ed33e8582a 100644 --- a/reactos/dll/win32/user32/misc/usrapihk.c +++ b/reactos/dll/win32/user32/misc/usrapihk.c @@ -200,7 +200,7 @@ ClearUserApiHook(HINSTANCE hInstance) if ( ghmodUserApiHook == hInstance ) { pfn1 = gpfnInitUserApi; - if ( --gcLoadUserApiHook == 1 ) + if ( --gcLoadUserApiHook == 0 ) { gfUserApiHook = 0; ResetUserApiHook(&guah); @@ -228,7 +228,7 @@ ClearUserApiHook(HINSTANCE hInstance) RtlEnterCriticalSection(&gcsUserApiHook); pfn1 = gpfnInitUserApi; - if ( --gcLoadUserApiHook == 1 ) + if ( --gcLoadUserApiHook == 0 ) { if ( gcCallUserApiHook ) { @@ -392,7 +392,5 @@ BOOL WINAPI RegisterUserApiHook(PUSERAPIHOOKINFO puah) */ BOOL WINAPI UnregisterUserApiHook(VOID) { - // Direct call to Win32k! Here only as a prototype..... - UNIMPLEMENTED; - return FALSE; + return NtUserUnregisterUserApiHook(); } diff --git a/reactos/dll/win32/user32/windows/defwnd.c b/reactos/dll/win32/user32/windows/defwnd.c index 5e76a06a2f4..5b6ccda8d7a 100644 --- a/reactos/dll/win32/user32/windows/defwnd.c +++ b/reactos/dll/win32/user32/windows/defwnd.c @@ -2200,7 +2200,13 @@ DefWindowProcA(HWND hWnd, Hook = BeginIfHookedUserApiHook(); if (Hook) + { msgOverride = IsMsgOverride(Msg, &guah.DefWndProcArray); + if(msgOverride == FALSE) + { + EndUserApiHook(); + } + } /* Bypass SEH and go direct. */ if (!Hook || !msgOverride) @@ -2233,7 +2239,13 @@ DefWindowProcW(HWND hWnd, Hook = BeginIfHookedUserApiHook(); if (Hook) + { msgOverride = IsMsgOverride(Msg, &guah.DefWndProcArray); + if(msgOverride == FALSE) + { + EndUserApiHook(); + } + } /* Bypass SEH and go direct. */ if (!Hook || !msgOverride) diff --git a/reactos/dll/win32/user32/windows/hook.c b/reactos/dll/win32/user32/windows/hook.c index 08a9a55c729..97c74f01c9d 100644 --- a/reactos/dll/win32/user32/windows/hook.c +++ b/reactos/dll/win32/user32/windows/hook.c @@ -427,6 +427,126 @@ 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; + + TRACE("ClientLoadLibrary: pid: %d, strLibraryName: %S, " + "strInitFuncName: %S, Unload: %d, ApiHook:%d\n", + GetCurrentProcessId(), + pstrLibName->Buffer, + pstrInitFunc->Buffer, + Unload, + ApiHook); + + /* 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) + { + hLibrary = ghmodUserApiHook; + Result = ClearUserApiHook(ghmodUserApiHook); + /* Check if we can we unload it now */ + if(Result == FALSE) + { + /* Return success because we are going to free + the library in EndUserApiHook*/ + return hLibrary; + } + } + 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) {