diff --git a/dlls/user32/hook.c b/dlls/user32/hook.c
index b537b7b31d6d866cbbc2f11b2dd8afa66327314f..75e31e4ffc75158336aa1083611f87d482ce7b95 100644
--- a/dlls/user32/hook.c
+++ b/dlls/user32/hook.c
@@ -144,7 +144,6 @@ static HHOOK set_windows_hook( INT id, HOOKPROC proc, HINSTANCE inst, DWORD tid,
         return 0;
     }
 
-    /* FIXME: what if the tid belongs to another process? */
     if (tid)  /* thread-local hook */
     {
         if (id == WH_JOURNALRECORD ||
@@ -157,18 +156,23 @@ static HHOOK set_windows_hook( INT id, HOOKPROC proc, HINSTANCE inst, DWORD tid,
             SetLastError( ERROR_INVALID_PARAMETER );
             return 0;
         }
-        inst = 0;
     }
     else  /* system-global hook */
     {
         if (id == WH_KEYBOARD_LL || id == WH_MOUSE_LL) inst = 0;
-        else if (!inst || !(len = GetModuleFileNameW( inst, module, MAX_PATH )) || len >= MAX_PATH)
+        else if (!inst)
         {
             SetLastError( ERROR_HOOK_NEEDS_HMOD );
             return 0;
         }
     }
 
+    if (inst && (!(len = GetModuleFileNameW( inst, module, MAX_PATH )) || len >= MAX_PATH))
+    {
+        SetLastError( ERROR_INVALID_PARAMETER );
+        return 0;
+    }
+
     SERVER_START_REQ( set_hook )
     {
         req->id        = id;
diff --git a/server/hook.c b/server/hook.c
index c9bf3dbbb29fd753d482eedadaf3b56e4507aed4..9a20043e26491b573de879bc9b93397b49f769a5 100644
--- a/server/hook.c
+++ b/server/hook.c
@@ -420,7 +420,17 @@ DECL_HANDLER(set_hook)
     }
     else
     {
-        module = NULL;
+        /* module is optional only if hook is in current process */
+        if (!module_size)
+        {
+            module = NULL;
+            if (thread->process != current->process)
+            {
+                set_error( STATUS_INVALID_PARAMETER );
+                goto done;
+            }
+        }
+        else if (!(module = memdup( get_req_data(), module_size ))) goto done;
         global = 0;
     }