Author: gadamopoulos
Date: Tue Jul 12 08:43:43 2011
New Revision: 52650
URL:
http://svn.reactos.org/svn/reactos?rev=52650&view=rev
Log:
[win32k]
- Implement NtUserRegisterUserApiHook and NtUserUnregisterUserApiHook
Modified:
branches/GSoC_2011/ThemesSupport/subsystems/win32/win32k/include/hook.h
branches/GSoC_2011/ThemesSupport/subsystems/win32/win32k/include/msgqueue.h
branches/GSoC_2011/ThemesSupport/subsystems/win32/win32k/include/win32.h
branches/GSoC_2011/ThemesSupport/subsystems/win32/win32k/ntuser/hook.c
branches/GSoC_2011/ThemesSupport/subsystems/win32/win32k/ntuser/msgqueue.c
branches/GSoC_2011/ThemesSupport/subsystems/win32/win32k/ntuser/ntstubs.c
branches/GSoC_2011/ThemesSupport/subsystems/win32/win32k/ntuser/simplecall.c
Modified: branches/GSoC_2011/ThemesSupport/subsystems/win32/win32k/include/hook.h
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/ThemesSupport/subsyst…
==============================================================================
--- branches/GSoC_2011/ThemesSupport/subsystems/win32/win32k/include/hook.h [iso-8859-1]
(original)
+++ branches/GSoC_2011/ThemesSupport/subsystems/win32/win32k/include/hook.h [iso-8859-1]
Tue Jul 12 08:43:43 2011
@@ -4,6 +4,13 @@
#define HOOKID_TO_INDEX(HookId) (HookId - WH_MINHOOK)
#define HOOKID_TO_FLAG(HookId) (1 << ((HookId) + 1))
#define ISITHOOKED(HookId) (((PTHREADINFO)PsGetCurrentThreadWin32Thread())->fsHooks
& HOOKID_TO_FLAG(HookId))
+
+/* NOTE: the following definition is not a real hook but
+ a pseudo-id that will be used only for
+ injecting user api hook module to all processes.
+ It is used internally in win32k */
+#define WH_APIHOOK WH_MAX + 1
+
typedef struct tagEVENTHOOK
{
@@ -43,4 +50,10 @@
LRESULT FASTCALL UserCallNextHookEx( PHOOK pHook, int Code, WPARAM wParam, LPARAM lParam,
BOOL Ansi);
BOOL FASTCALL IntUnhookWindowsHook(int,HOOKPROC);
+BOOL FASTCALL UserLoadApiHook();
+BOOL IntLoadHookModule(int iHookID, HHOOK hHook, BOOL Unload);
+BOOL FASTCALL UserUnregisterUserApiHook(BOOL Block);
+
+extern PPROCESSINFO ppiUahServer;
+
/* EOF */
Modified: branches/GSoC_2011/ThemesSupport/subsystems/win32/win32k/include/msgqueue.h
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/ThemesSupport/subsyst…
==============================================================================
--- branches/GSoC_2011/ThemesSupport/subsystems/win32/win32k/include/msgqueue.h
[iso-8859-1] (original)
+++ branches/GSoC_2011/ThemesSupport/subsystems/win32/win32k/include/msgqueue.h
[iso-8859-1] Tue Jul 12 08:43:43 2011
@@ -7,6 +7,7 @@
#define MSQ_NORMAL 0
#define MSQ_ISHOOK 1
#define MSQ_ISEVENT 2
+#define MSQ_INJECTMODULE 3
#define QSIDCOUNTS 6
Modified: branches/GSoC_2011/ThemesSupport/subsystems/win32/win32k/include/win32.h
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/ThemesSupport/subsyst…
==============================================================================
--- branches/GSoC_2011/ThemesSupport/subsystems/win32/win32k/include/win32.h [iso-8859-1]
(original)
+++ branches/GSoC_2011/ThemesSupport/subsystems/win32/win32k/include/win32.h [iso-8859-1]
Tue Jul 12 08:43:43 2011
@@ -30,6 +30,7 @@
#define W32PF_NOWINDOWGHOSTING (0x01000000)
#define W32PF_MANUALGUICHECK (0x02000000)
#define W32PF_CREATEDWINORDC (0x04000000)
+#define W32PF_APIHOOKLOADED (0x08000000)
extern BOOL ClientPfnInit;
extern HINSTANCE hModClient;
Modified: branches/GSoC_2011/ThemesSupport/subsystems/win32/win32k/ntuser/hook.c
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/ThemesSupport/subsyst…
==============================================================================
--- branches/GSoC_2011/ThemesSupport/subsystems/win32/win32k/ntuser/hook.c [iso-8859-1]
(original)
+++ branches/GSoC_2011/ThemesSupport/subsystems/win32/win32k/ntuser/hook.c [iso-8859-1]
Tue Jul 12 08:43:43 2011
@@ -24,7 +24,219 @@
PVOID pHookStructs;
} HOOKPACK, *PHOOKPACK;
+UNICODE_STRING strUahModule;
+UNICODE_STRING strUahInitFunc;
+PPROCESSINFO ppiUahServer;
+
/* PRIVATE FUNCTIONS *********************************************************/
+
+/* Calls ClientLoadLibrary in user32 in order to load or unload a module */
+BOOL
+IntLoadHookModule(int iHookID, HHOOK hHook, BOOL Unload)
+{
+ PPROCESSINFO ppi;
+ HMODULE hmod;
+
+ ppi = PsGetCurrentProcessWin32Process();
+
+ DPRINT("IntLoadHookModule. Client PID: %d\n",
PsGetProcessId(ppi->peProcess));
+
+ /* Check if this is the api hook */
+ if(iHookID == WH_APIHOOK)
+ {
+ if(!Unload && !(ppi->W32PF_flags & W32PF_APIHOOKLOADED))
+ {
+ /* Call ClientLoadLibrary in user32 */
+ hmod = co_IntClientLoadLibrary(&strUahModule, &strUahInitFunc,
Unload, TRUE);
+ if(hmod != 0)
+ {
+ ppi->W32PF_flags |= W32PF_APIHOOKLOADED;
+ return TRUE;
+ }
+ return FALSE;
+ }
+ else if(Unload && (ppi->W32PF_flags & W32PF_APIHOOKLOADED))
+ {
+ /* Call ClientLoadLibrary in user32 */
+ hmod = co_IntClientLoadLibrary(NULL, NULL, Unload, TRUE);
+ if(hmod != 0)
+ {
+ ppi->W32PF_flags &= ~W32PF_APIHOOKLOADED;
+ return TRUE;
+ }
+ return FALSE;
+ }
+
+ return TRUE;
+ }
+
+ UNIMPLEMENTED;
+
+ return FALSE;
+}
+
+/*
+IntHookModuleUnloaded:
+Sends a internal message to all threads of the requested desktop
+and notifies them that a global hook was destroyed
+and an injected module must be unloaded.
+As a result, IntLoadHookModule will be called for all the threads that
+will receive the special purpose internal message.
+*/
+BOOL
+IntHookModuleUnloaded(PDESKTOP pdesk, int iHookID, HHOOK hHook, BOOL Block)
+{
+ PTHREADINFO ptiCurrent;
+ PLIST_ENTRY ListEntry;
+ ULONG_PTR Result;
+ PPROCESSINFO ppiCsr;
+
+ DPRINT("IntHookModuleUnloaded: iHookID=%d\n", iHookID);
+
+ ppiCsr = PsGetProcessWin32Process(CsrProcess);
+
+ ListEntry = pdesk->PtiList.Flink;
+ while(ListEntry != &pdesk->PtiList)
+ {
+ ptiCurrent = CONTAINING_RECORD(ListEntry, THREADINFO, PtiLink);
+
+ /* FIXME: do some more security checks here */
+
+ /* FIXME: the first check is a reactos specific hack for system threads */
+ if(!PsIsSystemProcess(ptiCurrent->ppi->peProcess) &&
+ ptiCurrent->ppi != ppiCsr)
+ {
+ if(ptiCurrent->ppi->W32PF_flags & W32PF_APIHOOKLOADED)
+ {
+ DPRINT("IntHookModuleUnloaded: sending message to PID %d,
ppi=0x%x\n", PsGetProcessId(ptiCurrent->ppi->peProcess), ptiCurrent->ppi);
+ co_MsqSendMessage( ptiCurrent->MessageQueue,
+ 0,
+ iHookID,
+ TRUE,
+ (LPARAM)hHook,
+ 0,
+ Block,
+ MSQ_INJECTMODULE,
+ &Result);
+ }
+ }
+ ListEntry = ListEntry->Flink;
+ }
+
+ return TRUE;
+}
+
+BOOL
+FASTCALL
+UserLoadApiHook()
+{
+ return IntLoadHookModule(WH_APIHOOK, 0, FALSE);
+}
+
+BOOL
+FASTCALL
+UserRegisterUserApiHook(
+ PUNICODE_STRING pstrDllName,
+ PUNICODE_STRING pstrFuncName)
+{
+ PTHREADINFO pti, ptiCurrent;
+ HWND *List;
+ PWND DesktopWindow, pwndCurrent;
+ ULONG i;
+ ULONG_PTR Result;
+ PPROCESSINFO ppiCsr;
+
+ pti = PsGetCurrentThreadWin32Thread();
+ ppiCsr = PsGetProcessWin32Process(CsrProcess);
+
+ /* Fail if the api hook is already registered */
+ if(gpsi->dwSRVIFlags & SRVINFO_APIHOOK)
+ {
+ return FALSE;
+ }
+
+ DPRINT("UserRegisterUserApiHook. Server PID: %d\n",
PsGetProcessId(pti->ppi->peProcess));
+
+ /* Register the api hook */
+ gpsi->dwSRVIFlags |= SRVINFO_APIHOOK;
+
+ strUahModule = *pstrDllName;
+ strUahInitFunc = *pstrFuncName;
+ ppiUahServer = pti->ppi;
+
+ /* Broadcast an internal message to every top level window */
+ DesktopWindow = UserGetWindowObject(IntGetDesktopWindow());
+ List = IntWinListChildren(DesktopWindow);
+
+ if (List != NULL)
+ {
+ for (i = 0; List[i]; i++)
+ {
+ pwndCurrent = UserGetWindowObject(List[i]);
+ if(pwndCurrent == NULL)
+ {
+ continue;
+ }
+ ptiCurrent = pwndCurrent->head.pti;
+
+ /* FIXME: the first check is a reactos specific hack for system threads */
+ if(PsIsSystemProcess(ptiCurrent->ppi->peProcess) ||
+ ptiCurrent->ppi == ppiCsr)
+ {
+ continue;
+ }
+
+ co_MsqSendMessage( ptiCurrent->MessageQueue,
+ 0,
+ WH_APIHOOK,
+ FALSE, /* load the module */
+ 0,
+ 0,
+ TRUE,
+ MSQ_INJECTMODULE,
+ &Result);
+ if(Result == FALSE)
+ {
+ DPRINT1("Failed to inject module to process %d\n",
PsGetProcessId(ptiCurrent->ppi->peProcess));
+ }
+ }
+ ExFreePoolWithTag(List, USERTAG_WINDOWLIST);
+ }
+
+ return TRUE;
+}
+
+BOOL
+FASTCALL
+UserUnregisterUserApiHook(BOOL Block)
+{
+ PTHREADINFO pti;
+
+ pti = PsGetCurrentThreadWin32Thread();
+
+ /* Fail if the api hook is not registered */
+ if(!(gpsi->dwSRVIFlags & SRVINFO_APIHOOK))
+ {
+ return FALSE;
+ }
+
+ /* Only the process that registered the api hook can uregister it */
+ if(ppiUahServer != PsGetCurrentProcessWin32Process())
+ {
+ return FALSE;
+ }
+
+ DPRINT1("UserUnregisterUserApiHook. Server PID: %d\n",
PsGetProcessId(pti->ppi->peProcess));
+
+ /* Unregister the api hook */
+ gpsi->dwSRVIFlags &= ~SRVINFO_APIHOOK;
+ ppiUahServer = NULL;
+ ReleaseCapturedUnicodeString(&strUahModule, UserMode);
+ ReleaseCapturedUnicodeString(&strUahInitFunc, UserMode);
+
+ /* Notify all applications that the api hook module must be unloaded */
+ return IntHookModuleUnloaded(pti->rpdesk, WH_APIHOOK, 0, TRUE);
+}
static
LRESULT
@@ -1527,4 +1739,64 @@
END_CLEANUP;
}
+BOOL
+APIENTRY
+NtUserRegisterUserApiHook(
+ PUNICODE_STRING m_dllname1,
+ PUNICODE_STRING m_funname1,
+ DWORD dwUnknown3,
+ DWORD dwUnknown4)
+{
+ BOOL ret;
+ UNICODE_STRING strDllNameSafe;
+ UNICODE_STRING strFuncNameSafe;
+ NTSTATUS Status;
+
+ /* Probe and capture parameters */
+ Status = ProbeAndCaptureUnicodeString(&strDllNameSafe, UserMode, m_dllname1);
+ if(!NT_SUCCESS(Status))
+ {
+ EngSetLastError(RtlNtStatusToDosError(Status));
+ return FALSE;
+ }
+
+ Status = ProbeAndCaptureUnicodeString(&strFuncNameSafe, UserMode, m_funname1);
+ if(!NT_SUCCESS(Status))
+ {
+ ReleaseCapturedUnicodeString(&strDllNameSafe, UserMode);
+ EngSetLastError(RtlNtStatusToDosError(Status));
+ return FALSE;
+ }
+
+ UserEnterExclusive();
+
+ /* Call internal function */
+ ret = UserRegisterUserApiHook(&strDllNameSafe, &strFuncNameSafe);
+
+ UserLeave();
+
+ /* Cleanup only in case of failure */
+ if(ret == FALSE)
+ {
+ ReleaseCapturedUnicodeString(&strDllNameSafe, UserMode);
+ ReleaseCapturedUnicodeString(&strFuncNameSafe, UserMode);
+ }
+
+ return ret;
+}
+
+BOOL
+APIENTRY
+NtUserUnregisterUserApiHook(VOID)
+{
+ BOOL ret;
+
+ UserEnterExclusive();
+ ret = UserUnregisterUserApiHook(TRUE);
+ UserLeave();
+
+ return ret;
+}
+
+
/* EOF */
Modified: branches/GSoC_2011/ThemesSupport/subsystems/win32/win32k/ntuser/msgqueue.c
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/ThemesSupport/subsyst…
==============================================================================
--- branches/GSoC_2011/ThemesSupport/subsystems/win32/win32k/ntuser/msgqueue.c
[iso-8859-1] (original)
+++ branches/GSoC_2011/ThemesSupport/subsystems/win32/win32k/ntuser/msgqueue.c
[iso-8859-1] Tue Jul 12 08:43:43 2011
@@ -811,6 +811,12 @@
Message->Msg.wParam,
Message->Msg.lParam);
}
+ else if(Message->HookMessage == MSQ_INJECTMODULE)
+ {
+ Result = IntLoadHookModule(Message->Msg.message,
+ (HHOOK)Message->Msg.lParam,
+ Message->Msg.wParam);
+ }
else if ((Message->CompletionCallback)
&& (Message->CallBackSenderQueue == MessageQueue))
{ /* Call the callback routine */
Modified: branches/GSoC_2011/ThemesSupport/subsystems/win32/win32k/ntuser/ntstubs.c
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/ThemesSupport/subsyst…
==============================================================================
--- branches/GSoC_2011/ThemesSupport/subsystems/win32/win32k/ntuser/ntstubs.c [iso-8859-1]
(original)
+++ branches/GSoC_2011/ThemesSupport/subsystems/win32/win32k/ntuser/ntstubs.c [iso-8859-1]
Tue Jul 12 08:43:43 2011
@@ -891,20 +891,6 @@
BOOL
APIENTRY
-NtUserRegisterUserApiHook(
- PUNICODE_STRING m_dllname1,
- PUNICODE_STRING m_funname1,
- DWORD dwUnknown3,
- DWORD dwUnknown4)
-{
- UserEnterExclusive();
- UNIMPLEMENTED;
- UserLeave();
- return 0;
-}
-
-BOOL
-APIENTRY
NtUserRegisterRawInputDevices(
IN PCRAWINPUTDEVICE pRawInputDevices,
IN UINT uiNumDevices,
@@ -1038,14 +1024,6 @@
BOOL
APIENTRY
-NtUserUnregisterUserApiHook(VOID)
-{
- UNIMPLEMENTED;
- return 0;
-}
-
-BOOL
-APIENTRY
NtUserGetLayeredWindowAttributes(
HWND hwnd,
COLORREF *pcrKey,
Modified: branches/GSoC_2011/ThemesSupport/subsystems/win32/win32k/ntuser/simplecall.c
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/ThemesSupport/subsyst…
==============================================================================
--- branches/GSoC_2011/ThemesSupport/subsystems/win32/win32k/ntuser/simplecall.c
[iso-8859-1] (original)
+++ branches/GSoC_2011/ThemesSupport/subsystems/win32/win32k/ntuser/simplecall.c
[iso-8859-1] Tue Jul 12 08:43:43 2011
@@ -121,6 +121,9 @@
case NOPARAM_ROUTINE_RELEASECAPTURE:
RETURN( (DWORD_PTR)IntReleaseCapture());
+
+ case NOPARAM_ROUTINE_LOADUSERAPIHOOK:
+ RETURN(UserLoadApiHook());
default:
DPRINT1("Calling invalid routine number 0x%x in NtUserCallNoParam\n",
Routine);