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/subsystems/win32/win32k/include/hook.h?rev=52650&r1=52649&r2=52650&view=diff
==============================================================================
--- 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/subsystems/win32/win32k/include/msgqueue.h?rev=52650&r1=52649&r2=52650&view=diff
==============================================================================
--- 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/subsystems/win32/win32k/include/win32.h?rev=52650&r1=52649&r2=52650&view=diff
==============================================================================
--- 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/subsystems/win32/win32k/ntuser/hook.c?rev=52650&r1=52649&r2=52650&view=diff
==============================================================================
--- 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/subsystems/win32/win32k/ntuser/msgqueue.c?rev=52650&r1=52649&r2=52650&view=diff
==============================================================================
--- 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/subsystems/win32/win32k/ntuser/ntstubs.c?rev=52650&r1=52649&r2=52650&view=diff
==============================================================================
--- 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/subsystems/win32/win32k/ntuser/simplecall.c?rev=52650&r1=52649&r2=52650&view=diff
==============================================================================
--- 
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);


Reply via email to