2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Win32k subsystem
4 * PURPOSE: Callback to usermode support
5 * FILE: win32ss/user/ntuser/callback.c
6 * PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
7 * Thomas Weidenmueller (w3seek@users.sourceforge.net)
8 * NOTES: Please use the Callback Memory Management functions for
9 * callbacks to make sure, the memory is freed on thread
14 DBG_DEFAULT_CHANNEL(UserCallback
);
17 /* CALLBACK MEMORY MANAGEMENT ************************************************/
19 typedef struct _INT_CALLBACK_HEADER
21 /* List entry in the THREADINFO structure */
24 INT_CALLBACK_HEADER
, *PINT_CALLBACK_HEADER
;
27 IntCbAllocateMemory(ULONG Size
)
29 PINT_CALLBACK_HEADER Mem
;
30 PTHREADINFO W32Thread
;
32 if(!(Mem
= ExAllocatePoolWithTag(PagedPool
, Size
+ sizeof(INT_CALLBACK_HEADER
),
38 W32Thread
= PsGetCurrentThreadWin32Thread();
41 /* Insert the callback memory into the thread's callback list */
43 InsertTailList(&W32Thread
->W32CallbackListHead
, &Mem
->ListEntry
);
49 IntCbFreeMemory(PVOID Data
)
51 PINT_CALLBACK_HEADER Mem
;
52 PTHREADINFO W32Thread
;
54 W32Thread
= PsGetCurrentThreadWin32Thread();
57 if (W32Thread
->TIF_flags
& TIF_INCLEANUP
)
59 ERR("CbFM Thread is already in cleanup\n");
65 Mem
= ((PINT_CALLBACK_HEADER
)Data
- 1);
67 /* Remove the memory block from the thread's callback list */
68 RemoveEntryList(&Mem
->ListEntry
);
71 ExFreePoolWithTag(Mem
, USERTAG_CALLBACK
);
75 IntCleanupThreadCallbacks(PTHREADINFO W32Thread
)
77 PLIST_ENTRY CurrentEntry
;
78 PINT_CALLBACK_HEADER Mem
;
80 while (!IsListEmpty(&W32Thread
->W32CallbackListHead
))
82 CurrentEntry
= RemoveHeadList(&W32Thread
->W32CallbackListHead
);
83 Mem
= CONTAINING_RECORD(CurrentEntry
, INT_CALLBACK_HEADER
,
87 ExFreePoolWithTag(Mem
, USERTAG_CALLBACK
);
92 // Pass the Current Window handle and pointer to the Client Callback.
93 // This will help user space programs speed up read access with the window object.
96 IntSetTebWndCallback (HWND
* hWnd
, PWND
* pWnd
, PVOID
* pActCtx
)
99 PWND Window
= UserGetWindowObject(*hWnd
);
100 PCLIENTINFO ClientInfo
= GetWin32ClientInfo();
102 *hWnd
= ClientInfo
->CallbackWnd
.hWnd
;
103 *pWnd
= ClientInfo
->CallbackWnd
.pWnd
;
104 *pActCtx
= ClientInfo
->CallbackWnd
.pActCtx
;
108 ClientInfo
->CallbackWnd
.hWnd
= hWndS
;
109 ClientInfo
->CallbackWnd
.pWnd
= DesktopHeapAddressToUser(Window
);
110 ClientInfo
->CallbackWnd
.pActCtx
= Window
->pActCtx
;
112 else //// What if Dispatching WM_SYS/TIMER with NULL window? Fix AbiWord Crash when sizing.
114 ClientInfo
->CallbackWnd
.hWnd
= hWndS
;
115 ClientInfo
->CallbackWnd
.pWnd
= Window
;
116 ClientInfo
->CallbackWnd
.pActCtx
= 0;
121 IntRestoreTebWndCallback (HWND hWnd
, PWND pWnd
, PVOID pActCtx
)
123 PCLIENTINFO ClientInfo
= GetWin32ClientInfo();
125 ClientInfo
->CallbackWnd
.hWnd
= hWnd
;
126 ClientInfo
->CallbackWnd
.pWnd
= pWnd
;
127 ClientInfo
->CallbackWnd
.pActCtx
= pActCtx
;
130 /* FUNCTIONS *****************************************************************/
132 /* Calls ClientLoadLibrary in user32 */
135 co_IntClientLoadLibrary(PUNICODE_STRING pstrLibName
,
136 PUNICODE_STRING pstrInitFunc
,
142 ULONG ArgumentLength
;
143 PCLIENT_LOAD_LIBRARY_ARGUMENTS pArguments
;
146 ULONG_PTR pLibNameBuffer
= 0, pInitFuncBuffer
= 0;
148 /* Do not allow the desktop thread to do callback to user mode */
149 ASSERT(PsGetCurrentThreadWin32Thread() != gptiDesktopThread
);
151 TRACE("co_IntClientLoadLibrary: %S, %S, %d, %d\n", pstrLibName
->Buffer
, pstrLibName
->Buffer
, Unload
, ApiHook
);
153 /* Calculate the size of the argument */
154 ArgumentLength
= sizeof(CLIENT_LOAD_LIBRARY_ARGUMENTS
);
157 pLibNameBuffer
= ArgumentLength
;
158 ArgumentLength
+= pstrLibName
->Length
+ sizeof(WCHAR
);
162 pInitFuncBuffer
= ArgumentLength
;
163 ArgumentLength
+= pstrInitFunc
->Length
+ sizeof(WCHAR
);
166 /* Allocate the argument */
167 pArguments
= IntCbAllocateMemory(ArgumentLength
);
168 if(pArguments
== NULL
)
173 /* Fill the argument */
174 pArguments
->Unload
= Unload
;
175 pArguments
->ApiHook
= ApiHook
;
178 /* Copy the string to the callback memory */
179 pLibNameBuffer
+= (ULONG_PTR
)pArguments
;
180 pArguments
->strLibraryName
.Buffer
= (PWCHAR
)pLibNameBuffer
;
181 pArguments
->strLibraryName
.MaximumLength
= pstrLibName
->Length
+ sizeof(WCHAR
);
182 RtlCopyUnicodeString(&pArguments
->strLibraryName
, pstrLibName
);
184 /* Fix argument pointer to be relative to the argument */
185 pLibNameBuffer
-= (ULONG_PTR
)pArguments
;
186 pArguments
->strLibraryName
.Buffer
= (PWCHAR
)(pLibNameBuffer
);
190 RtlZeroMemory(&pArguments
->strLibraryName
, sizeof(UNICODE_STRING
));
195 /* Copy the strings to the callback memory */
196 pInitFuncBuffer
+= (ULONG_PTR
)pArguments
;
197 pArguments
->strInitFuncName
.Buffer
= (PWCHAR
)pInitFuncBuffer
;
198 pArguments
->strInitFuncName
.MaximumLength
= pstrInitFunc
->Length
+ sizeof(WCHAR
);
199 RtlCopyUnicodeString(&pArguments
->strInitFuncName
, pstrInitFunc
);
201 /* Fix argument pointers to be relative to the argument */
202 pInitFuncBuffer
-= (ULONG_PTR
)pArguments
;
203 pArguments
->strInitFuncName
.Buffer
= (PWCHAR
)(pInitFuncBuffer
);
207 RtlZeroMemory(&pArguments
->strInitFuncName
, sizeof(UNICODE_STRING
));
210 /* Do the callback */
213 Status
= KeUserModeCallback(USER32_CALLBACK_CLIENTLOADLIBRARY
,
221 /* Free the argument */
222 IntCbFreeMemory(pArguments
);
224 if(!NT_SUCCESS(Status
))
231 /* Probe and copy the usermode result data */
232 ProbeForRead(ResultPointer
, sizeof(HMODULE
), 1);
233 bResult
= *(BOOL
*)ResultPointer
;
235 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
245 co_IntCallSentMessageCallback(SENDASYNCPROC CompletionCallback
,
248 ULONG_PTR CompletionCallbackContext
,
251 SENDASYNCPROC_CALLBACK_ARGUMENTS Arguments
;
252 PVOID ResultPointer
, pActCtx
;
257 /* Do not allow the desktop thread to do callback to user mode */
258 ASSERT(PsGetCurrentThreadWin32Thread() != gptiDesktopThread
);
260 Arguments
.Callback
= CompletionCallback
;
261 Arguments
.Wnd
= hWnd
;
263 Arguments
.Context
= CompletionCallbackContext
;
264 Arguments
.Result
= Result
;
266 IntSetTebWndCallback (&hWnd
, &pWnd
, &pActCtx
);
270 Status
= KeUserModeCallback(USER32_CALLBACK_SENDASYNCPROC
,
272 sizeof(SENDASYNCPROC_CALLBACK_ARGUMENTS
),
278 IntRestoreTebWndCallback (hWnd
, pWnd
, pActCtx
);
280 if (!NT_SUCCESS(Status
))
282 ERR("KeUserModeCallback failed with %lx\n", Status
);
289 co_IntCallWindowProc(WNDPROC Proc
,
295 INT lParamBufferSize
)
297 WINDOWPROC_CALLBACK_ARGUMENTS StackArguments
;
298 PWINDOWPROC_CALLBACK_ARGUMENTS Arguments
;
300 PVOID ResultPointer
, pActCtx
;
303 ULONG ArgumentLength
;
306 TRACE("co_IntCallWindowProc(Proc %p, IsAnsiProc: %s, Wnd %p, Message %u, wParam %Iu, lParam %Id, lParamBufferSize %d)\n",
307 Proc
, IsAnsiProc
? "TRUE" : "FALSE", Wnd
, Message
, wParam
, lParam
, lParamBufferSize
);
309 /* Do not allow the desktop thread to do callback to user mode */
310 ASSERT(PsGetCurrentThreadWin32Thread() != gptiDesktopThread
);
312 if (lParamBufferSize
!= -1)
314 ArgumentLength
= sizeof(WINDOWPROC_CALLBACK_ARGUMENTS
) + lParamBufferSize
;
315 Arguments
= IntCbAllocateMemory(ArgumentLength
);
316 if (NULL
== Arguments
)
318 ERR("Unable to allocate buffer for window proc callback\n");
321 RtlMoveMemory((PVOID
) ((char *) Arguments
+ sizeof(WINDOWPROC_CALLBACK_ARGUMENTS
)),
322 (PVOID
) lParam
, lParamBufferSize
);
326 Arguments
= &StackArguments
;
327 ArgumentLength
= sizeof(WINDOWPROC_CALLBACK_ARGUMENTS
);
329 Arguments
->Proc
= Proc
;
330 Arguments
->IsAnsiProc
= IsAnsiProc
;
331 Arguments
->Wnd
= Wnd
;
332 Arguments
->Msg
= Message
;
333 Arguments
->wParam
= wParam
;
334 Arguments
->lParam
= lParam
;
335 Arguments
->lParamBufferSize
= lParamBufferSize
;
336 ResultPointer
= NULL
;
337 ResultLength
= ArgumentLength
;
339 IntSetTebWndCallback (&Wnd
, &pWnd
, &pActCtx
);
343 Status
= KeUserModeCallback(USER32_CALLBACK_WINDOWPROC
,
348 if (!NT_SUCCESS(Status
))
350 ERR("Error Callback to User space Status %lx Message %d\n",Status
,Message
);
357 /* Simulate old behaviour: copy into our local buffer */
358 RtlMoveMemory(Arguments
, ResultPointer
, ArgumentLength
);
360 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
362 ERR("Failed to copy result from user mode, Message %u lParam size %d!\n", Message
, lParamBufferSize
);
363 Status
= _SEH2_GetExceptionCode();
369 IntRestoreTebWndCallback (Wnd
, pWnd
, pActCtx
);
371 if (!NT_SUCCESS(Status
))
373 ERR("Call to user mode failed! 0x%08lx\n",Status
);
374 if (lParamBufferSize
!= -1)
376 IntCbFreeMemory(Arguments
);
380 Result
= Arguments
->Result
;
382 if (lParamBufferSize
!= -1)
384 PTHREADINFO pti
= PsGetCurrentThreadWin32Thread();
385 // Is this message being processed from inside kernel space?
386 BOOL InSendMessage
= (pti
->pcti
->CTI_flags
& CTI_INSENDMESSAGE
);
388 TRACE("Copy lParam Message %u lParam %d!\n", Message
, lParam
);
392 TRACE("Don't copy lParam, Message %u Size %d lParam %d!\n", Message
, lParamBufferSize
, lParam
);
394 // Write back to user/kernel space. Also see g_MsgMemory.
396 case WM_GETMINMAXINFO
:
400 case WM_STYLECHANGING
:
401 case WM_WINDOWPOSCHANGING
:
406 TRACE("Copy lParam, Message %u Size %d lParam %d!\n", Message
, lParamBufferSize
, lParam
);
408 // Copy into kernel space.
409 RtlMoveMemory((PVOID
) lParam
,
410 (PVOID
) ((char *) Arguments
+ sizeof(WINDOWPROC_CALLBACK_ARGUMENTS
)),
415 { // Copy into user space.
416 RtlMoveMemory((PVOID
) lParam
,
417 (PVOID
) ((char *) Arguments
+ sizeof(WINDOWPROC_CALLBACK_ARGUMENTS
)),
420 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
422 ERR("Failed to copy lParam to user space, Message %u!\n", Message
);
428 IntCbFreeMemory(Arguments
);
435 co_IntLoadSysMenuTemplate(VOID
)
442 /* Do not allow the desktop thread to do callback to user mode */
443 ASSERT(PsGetCurrentThreadWin32Thread() != gptiDesktopThread
);
445 ResultPointer
= NULL
;
446 ResultLength
= sizeof(LRESULT
);
450 Status
= KeUserModeCallback(USER32_CALLBACK_LOADSYSMENUTEMPLATE
,
455 if (NT_SUCCESS(Status
))
457 /* Simulate old behaviour: copy into our local buffer */
460 ProbeForRead(ResultPointer
, sizeof(LRESULT
), 1);
461 Result
= *(LRESULT
*)ResultPointer
;
463 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
472 return (HMENU
)Result
;
475 extern HCURSOR gDesktopCursor
;
478 co_IntLoadDefaultCursors(VOID
)
483 BOOL DefaultCursor
= TRUE
;
485 /* Do not allow the desktop thread to do callback to user mode */
486 ASSERT(PsGetCurrentThreadWin32Thread() != gptiDesktopThread
);
488 ResultPointer
= NULL
;
489 ResultLength
= sizeof(HCURSOR
);
493 Status
= KeUserModeCallback(USER32_CALLBACK_LOADDEFAULTCURSORS
,
501 if (!NT_SUCCESS(Status
))
506 /* HACK: The desktop class doen't have a proper cursor yet, so set it here */
507 gDesktopCursor
= *((HCURSOR
*)ResultPointer
);
513 co_IntCallHookProc(INT HookId
,
521 PUNICODE_STRING ModuleName
)
523 ULONG ArgumentLength
;
524 PVOID Argument
= NULL
;
529 PHOOKPROC_CALLBACK_ARGUMENTS Common
;
530 CBT_CREATEWNDW
*CbtCreateWnd
= NULL
;
532 PHOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS CbtCreatewndExtra
= NULL
;
540 /* Do not allow the desktop thread to do callback to user mode */
541 ASSERT(PsGetCurrentThreadWin32Thread() != gptiDesktopThread
);
543 pti
= PsGetCurrentThreadWin32Thread();
544 if (pti
->TIF_flags
& TIF_INCLEANUP
)
546 ERR("Thread is in cleanup and trying to call hook %d\n", Code
);
550 ArgumentLength
= sizeof(HOOKPROC_CALLBACK_ARGUMENTS
);
555 TRACE("WH_CBT: Code %d\n", Code
);
559 pWnd
= UserGetWindowObject((HWND
) wParam
);
562 ERR("WH_CBT HCBT_CREATEWND wParam bad hWnd!\n");
565 TRACE("HCBT_CREATEWND AnsiCreator %s, AnsiHook %s\n", pWnd
->state
& WNDS_ANSICREATOR
? "True" : "False", Ansi
? "True" : "False");
566 // Due to KsStudio.exe, just pass the callers original pointers
567 // except class which point to kernel space if not an atom.
568 // Found by, Olaf Siejka
569 CbtCreateWnd
= (CBT_CREATEWNDW
*) lParam
;
570 ArgumentLength
+= sizeof(HOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS
);
574 ArgumentLength
+= sizeof(RECTL
);
577 ArgumentLength
+= sizeof(CBTACTIVATESTRUCT
);
579 case HCBT_CLICKSKIPPED
:
580 ArgumentLength
+= sizeof(MOUSEHOOKSTRUCT
);
583 case HCBT_KEYSKIPPED
:
586 case HCBT_SYSCOMMAND
:
587 /* These types pass through. */
588 case HCBT_DESTROYWND
:
592 ERR("Trying to call unsupported CBT hook %d\n", Code
);
597 ArgumentLength
+= sizeof(KBDLLHOOKSTRUCT
);
600 ArgumentLength
+= sizeof(MSLLHOOKSTRUCT
);
603 ArgumentLength
+= sizeof(MOUSEHOOKSTRUCT
);
607 CWPSTRUCT
* pCWP
= (CWPSTRUCT
*) lParam
;
608 ArgumentLength
+= sizeof(CWPSTRUCT
);
609 lParamSize
= lParamMemorySize(pCWP
->message
, pCWP
->wParam
, pCWP
->lParam
);
610 ArgumentLength
+= lParamSize
;
613 case WH_CALLWNDPROCRET
:
615 CWPRETSTRUCT
* pCWPR
= (CWPRETSTRUCT
*) lParam
;
616 ArgumentLength
+= sizeof(CWPRETSTRUCT
);
617 lParamSize
= lParamMemorySize(pCWPR
->message
, pCWPR
->wParam
, pCWPR
->lParam
);
618 ArgumentLength
+= lParamSize
;
622 case WH_SYSMSGFILTER
:
624 ArgumentLength
+= sizeof(MSG
);
626 case WH_FOREGROUNDIDLE
:
631 ERR("Trying to call unsupported window hook %d\n", HookId
);
635 Argument
= IntCbAllocateMemory(ArgumentLength
);
636 if (NULL
== Argument
)
638 ERR("HookProc callback failed: out of memory\n");
641 Common
= (PHOOKPROC_CALLBACK_ARGUMENTS
) Argument
;
642 Common
->HookId
= HookId
;
644 Common
->wParam
= wParam
;
645 Common
->lParam
= lParam
;
648 Common
->offPfn
= offPfn
;
650 RtlZeroMemory(&Common
->ModuleName
, sizeof(Common
->ModuleName
));
651 if (ModuleName
->Buffer
&& ModuleName
->Length
)
653 RtlCopyMemory(&Common
->ModuleName
, ModuleName
->Buffer
, ModuleName
->Length
);
654 // If ModuleName->Buffer NULL while in destroy,
655 // this will make User32:Hook.c complain about not loading the library module.
656 // Fix symptom for CORE-10549.
658 Extra
= (PCHAR
) Common
+ sizeof(HOOKPROC_CALLBACK_ARGUMENTS
);
664 { // Need to remember this is not the first time through! Call Next Hook?
666 CbtCreatewndExtra
= (PHOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS
) Extra
;
667 RtlCopyMemory( &CbtCreatewndExtra
->Cs
, CbtCreateWnd
->lpcs
, sizeof(CREATESTRUCTW
) );
668 CbtCreatewndExtra
->WndInsertAfter
= CbtCreateWnd
->hwndInsertAfter
;
669 CbtCreatewndExtra
->Cs
.lpszClass
= CbtCreateWnd
->lpcs
->lpszClass
;
670 CbtCreatewndExtra
->Cs
.lpszName
= CbtCreateWnd
->lpcs
->lpszName
;
671 Common
->lParam
= (LPARAM
) (Extra
- (PCHAR
) Common
);
673 case HCBT_CLICKSKIPPED
:
674 RtlCopyMemory(Extra
, (PVOID
) lParam
, sizeof(MOUSEHOOKSTRUCT
));
675 Common
->lParam
= (LPARAM
) (Extra
- (PCHAR
) Common
);
678 RtlCopyMemory(Extra
, (PVOID
) lParam
, sizeof(RECTL
));
679 Common
->lParam
= (LPARAM
) (Extra
- (PCHAR
) Common
);
682 RtlCopyMemory(Extra
, (PVOID
) lParam
, sizeof(CBTACTIVATESTRUCT
));
683 Common
->lParam
= (LPARAM
) (Extra
- (PCHAR
) Common
);
688 RtlCopyMemory(Extra
, (PVOID
) lParam
, sizeof(KBDLLHOOKSTRUCT
));
689 Common
->lParam
= (LPARAM
) (Extra
- (PCHAR
) Common
);
692 RtlCopyMemory(Extra
, (PVOID
) lParam
, sizeof(MSLLHOOKSTRUCT
));
693 Common
->lParam
= (LPARAM
) (Extra
- (PCHAR
) Common
);
696 RtlCopyMemory(Extra
, (PVOID
) lParam
, sizeof(MOUSEHOOKSTRUCT
));
697 Common
->lParam
= (LPARAM
) (Extra
- (PCHAR
) Common
);
700 /* For CALLWNDPROC and CALLWNDPROCRET, we must be wary of the fact that
701 * lParam could be a pointer to a buffer. This buffer must be exported
702 * to user space too */
703 RtlCopyMemory(Extra
, (PVOID
) lParam
, sizeof(CWPSTRUCT
));
704 Common
->lParam
= (LPARAM
) (Extra
- (PCHAR
) Common
);
707 RtlCopyMemory(Extra
+ sizeof(CWPSTRUCT
), (PVOID
)((CWPSTRUCT
*)lParam
)->lParam
, lParamSize
);
708 ((CWPSTRUCT
*)Extra
)->lParam
= (LPARAM
)lParamSize
;
711 case WH_CALLWNDPROCRET
:
712 RtlCopyMemory(Extra
, (PVOID
) lParam
, sizeof(CWPRETSTRUCT
));
713 Common
->lParam
= (LPARAM
) (Extra
- (PCHAR
) Common
);
716 RtlCopyMemory(Extra
+ sizeof(CWPRETSTRUCT
), (PVOID
)((CWPRETSTRUCT
*)lParam
)->lParam
, lParamSize
);
717 ((CWPRETSTRUCT
*)Extra
)->lParam
= (LPARAM
)lParamSize
;
721 case WH_SYSMSGFILTER
:
724 RtlCopyMemory(Extra
, (PVOID
) pMsg
, sizeof(MSG
));
725 Common
->lParam
= (LPARAM
) (Extra
- (PCHAR
) Common
);
727 case WH_FOREGROUNDIDLE
:
733 ResultPointer
= NULL
;
734 ResultLength
= ArgumentLength
;
738 Status
= KeUserModeCallback(USER32_CALLBACK_HOOKPROC
,
746 if (!NT_SUCCESS(Status
))
748 ERR("Failure to make Callback! Status 0x%x\n",Status
);
756 /* Simulate old behaviour: copy into our local buffer */
757 RtlMoveMemory(Argument
, ResultPointer
, ArgumentLength
);
758 Result
= Common
->Result
;
760 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
769 ERR("ERROR: Hook %d Code %d ResultPointer 0x%p ResultLength %u\n",HookId
,Code
,ResultPointer
,ResultLength
);
772 /* Support write backs... SEH is in UserCallNextHookEx. */
780 if (CbtCreatewndExtra
)
782 The parameters could have been changed, include the coordinates
783 and dimensions of the window. We copy it back.
785 CbtCreateWnd
->hwndInsertAfter
= CbtCreatewndExtra
->WndInsertAfter
;
786 CbtCreateWnd
->lpcs
->x
= CbtCreatewndExtra
->Cs
.x
;
787 CbtCreateWnd
->lpcs
->y
= CbtCreatewndExtra
->Cs
.y
;
788 CbtCreateWnd
->lpcs
->cx
= CbtCreatewndExtra
->Cs
.cx
;
789 CbtCreateWnd
->lpcs
->cy
= CbtCreatewndExtra
->Cs
.cy
;
795 RtlCopyMemory((PVOID
) lParam
, Extra
, sizeof(RECTL
));
800 // "The GetMsgProc hook procedure can examine or modify the message."
804 RtlCopyMemory((PVOID
) pMsg
, Extra
, sizeof(MSG
));
812 ERR("Exception CallHookProc HookId %d Code %d\n",HookId
,Code
);
814 if (Argument
) IntCbFreeMemory(Argument
);
820 // Events are notifications w/o results.
824 co_IntCallEventProc(HWINEVENTHOOK hook
,
837 PEVENTPROC_CALLBACK_ARGUMENTS Common
;
838 ULONG ArgumentLength
, ResultLength
;
839 PVOID Argument
, ResultPointer
;
841 ArgumentLength
= sizeof(EVENTPROC_CALLBACK_ARGUMENTS
);
843 Argument
= IntCbAllocateMemory(ArgumentLength
);
844 if (NULL
== Argument
)
846 ERR("EventProc callback failed: out of memory\n");
849 Common
= (PEVENTPROC_CALLBACK_ARGUMENTS
) Argument
;
851 Common
->event
= event
;
853 Common
->idObject
= idObject
;
854 Common
->idChild
= idChild
;
855 Common
->dwEventThread
= dwEventThread
;
856 Common
->dwmsEventTime
= dwmsEventTime
;
859 Common
->offPfn
= offPfn
;
861 ResultPointer
= NULL
;
862 ResultLength
= sizeof(LRESULT
);
866 Status
= KeUserModeCallback(USER32_CALLBACK_EVENTPROC
,
874 IntCbFreeMemory(Argument
);
876 if (!NT_SUCCESS(Status
))
885 // Callback Load Menu and results.
889 co_IntCallLoadMenu( HINSTANCE hModule
,
890 PUNICODE_STRING pMenuName
)
894 PLOADMENU_CALLBACK_ARGUMENTS Common
;
895 ULONG ArgumentLength
, ResultLength
;
896 PVOID Argument
, ResultPointer
;
898 ArgumentLength
= sizeof(LOADMENU_CALLBACK_ARGUMENTS
);
900 ArgumentLength
+= pMenuName
->Length
+ sizeof(WCHAR
);
902 Argument
= IntCbAllocateMemory(ArgumentLength
);
903 if (NULL
== Argument
)
905 ERR("LoadMenu callback failed: out of memory\n");
908 Common
= (PLOADMENU_CALLBACK_ARGUMENTS
) Argument
;
910 // Help Intersource check and MenuName is now 4 bytes + so zero it.
911 RtlZeroMemory(Common
, ArgumentLength
);
913 Common
->hModule
= hModule
;
914 if (pMenuName
->Length
)
915 RtlCopyMemory(&Common
->MenuName
, pMenuName
->Buffer
, pMenuName
->Length
);
917 Common
->InterSource
= pMenuName
->Buffer
;
919 ResultPointer
= NULL
;
920 ResultLength
= sizeof(LRESULT
);
924 Status
= KeUserModeCallback(USER32_CALLBACK_LOADMENU
,
932 if (NT_SUCCESS(Status
))
934 Result
= *(LRESULT
*)ResultPointer
;
941 IntCbFreeMemory(Argument
);
943 return (HMENU
)Result
;
948 co_IntClientThreadSetup(VOID
)
951 ULONG ArgumentLength
, ResultLength
;
952 PVOID Argument
, ResultPointer
;
954 /* Do not allow the desktop thread to do callback to user mode */
955 ASSERT(PsGetCurrentThreadWin32Thread() != gptiDesktopThread
);
957 ArgumentLength
= ResultLength
= 0;
958 Argument
= ResultPointer
= NULL
;
962 Status
= KeUserModeCallback(USER32_CALLBACK_CLIENTTHREADSTARTUP
,
974 co_IntCopyImage(HANDLE hnd
, UINT type
, INT desiredx
, INT desiredy
, UINT flags
)
978 ULONG ArgumentLength
, ResultLength
;
979 PVOID Argument
, ResultPointer
;
980 PCOPYIMAGE_CALLBACK_ARGUMENTS Common
;
982 ArgumentLength
= ResultLength
= 0;
983 Argument
= ResultPointer
= NULL
;
985 ArgumentLength
= sizeof(COPYIMAGE_CALLBACK_ARGUMENTS
);
987 Argument
= IntCbAllocateMemory(ArgumentLength
);
988 if (NULL
== Argument
)
990 ERR("CopyImage callback failed: out of memory\n");
993 Common
= (PCOPYIMAGE_CALLBACK_ARGUMENTS
) Argument
;
995 Common
->hImage
= hnd
;
996 Common
->uType
= type
;
997 Common
->cxDesired
= desiredx
;
998 Common
->cyDesired
= desiredy
;
999 Common
->fuFlags
= flags
;
1003 Status
= KeUserModeCallback(USER32_CALLBACK_COPYIMAGE
,
1012 if (NT_SUCCESS(Status
))
1014 Handle
= *(HANDLE
*)ResultPointer
;
1018 ERR("CopyImage callback failed!\n");
1022 IntCbFreeMemory(Argument
);
1029 co_IntGetCharsetInfo(LCID Locale
, PCHARSETINFO pCs
)
1032 ULONG ArgumentLength
, ResultLength
;
1033 PVOID Argument
, ResultPointer
;
1034 PGET_CHARSET_INFO Common
;
1036 ArgumentLength
= sizeof(GET_CHARSET_INFO
);
1038 Argument
= IntCbAllocateMemory(ArgumentLength
);
1039 if (NULL
== Argument
)
1041 ERR("GetCharsetInfo callback failed: out of memory\n");
1044 Common
= (PGET_CHARSET_INFO
) Argument
;
1046 Common
->Locale
= Locale
;
1048 ResultPointer
= NULL
;
1049 ResultLength
= ArgumentLength
;
1053 Status
= KeUserModeCallback(USER32_CALLBACK_GETCHARSETINFO
,
1059 if (NT_SUCCESS(Status
))
1063 /* Need to copy into our local buffer */
1064 RtlMoveMemory(Argument
, ResultPointer
, ArgumentLength
);
1066 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1068 ERR("Failed to copy result from user mode!\n");
1069 Status
= _SEH2_GetExceptionCode();
1076 RtlCopyMemory(pCs
, &Common
->Cs
, sizeof(CHARSETINFO
));
1078 IntCbFreeMemory(Argument
);
1080 if (!NT_SUCCESS(Status
))
1082 ERR("GetCharsetInfo Failed!!\n");
1090 co_IntSetWndIcons(VOID
)
1093 ULONG ArgumentLength
, ResultLength
;
1094 PVOID Argument
, ResultPointer
;
1095 PSETWNDICONS_CALLBACK_ARGUMENTS Common
;
1097 ResultPointer
= NULL
;
1098 ResultLength
= ArgumentLength
= sizeof(SETWNDICONS_CALLBACK_ARGUMENTS
);
1100 Argument
= IntCbAllocateMemory(ArgumentLength
);
1101 if (NULL
== Argument
)
1103 ERR("Set Window Icons callback failed: out of memory\n");
1106 Common
= (PSETWNDICONS_CALLBACK_ARGUMENTS
) Argument
;
1110 Status
= KeUserModeCallback(USER32_CALLBACK_SETWNDICONS
,
1119 if (!NT_SUCCESS(Status
))
1121 ERR("Set Window Icons callback failed!\n");
1122 IntCbFreeMemory(Argument
);
1126 RtlMoveMemory(Common
, ResultPointer
, ArgumentLength
);
1127 gpsi
->hIconSmWindows
= Common
->hIconSmWindows
;
1128 gpsi
->hIconWindows
= Common
->hIconWindows
;
1130 IntLoadSystenIcons(Common
->hIconSample
, OIC_SAMPLE
);
1131 IntLoadSystenIcons(Common
->hIconHand
, OIC_HAND
);
1132 IntLoadSystenIcons(Common
->hIconQuestion
, OIC_QUES
);
1133 IntLoadSystenIcons(Common
->hIconBang
, OIC_BANG
);
1134 IntLoadSystenIcons(Common
->hIconNote
, OIC_NOTE
);
1135 IntLoadSystenIcons(gpsi
->hIconWindows
, OIC_WINLOGO
);
1136 IntLoadSystenIcons(gpsi
->hIconSmWindows
, OIC_WINLOGO
+1);
1138 ERR("hIconSmWindows %p hIconWindows %p \n",gpsi
->hIconSmWindows
,gpsi
->hIconWindows
);
1140 IntCbFreeMemory(Argument
);
1146 co_IntDeliverUserAPC(VOID
)
1149 PVOID ResultPointer
;
1153 Status
= KeUserModeCallback(USER32_CALLBACK_DELIVERUSERAPC
,
1162 if (!NT_SUCCESS(Status
))
1164 ERR("Delivering User APC callback failed!\n");
1169 co_IntSetupOBM(VOID
)
1172 ULONG ArgumentLength
, ResultLength
;
1173 PVOID Argument
, ResultPointer
;
1174 PSETOBM_CALLBACK_ARGUMENTS Common
;
1176 ResultPointer
= NULL
;
1177 ResultLength
= ArgumentLength
= sizeof(SETOBM_CALLBACK_ARGUMENTS
);
1179 Argument
= IntCbAllocateMemory(ArgumentLength
);
1180 if (NULL
== Argument
)
1182 ERR("Set Window Icons callback failed: out of memory\n");
1185 Common
= (PSETOBM_CALLBACK_ARGUMENTS
) Argument
;
1189 Status
= KeUserModeCallback(USER32_CALLBACK_SETOBM
,
1198 if (!NT_SUCCESS(Status
))
1200 ERR("Set Window Icons callback failed!\n");
1201 IntCbFreeMemory(Argument
);
1205 RtlMoveMemory(Common
, ResultPointer
, ArgumentLength
);
1206 RtlCopyMemory(gpsi
->oembmi
, Common
->oembmi
, sizeof(gpsi
->oembmi
));
1208 IntCbFreeMemory(Argument
);