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
;
56 Mem
= ((PINT_CALLBACK_HEADER
)Data
- 1);
58 W32Thread
= PsGetCurrentThreadWin32Thread();
61 /* Remove the memory block from the thread's callback list */
62 RemoveEntryList(&Mem
->ListEntry
);
65 ExFreePoolWithTag(Mem
, USERTAG_CALLBACK
);
69 IntCleanupThreadCallbacks(PTHREADINFO W32Thread
)
71 PLIST_ENTRY CurrentEntry
;
72 PINT_CALLBACK_HEADER Mem
;
74 while (!IsListEmpty(&W32Thread
->W32CallbackListHead
))
76 CurrentEntry
= RemoveHeadList(&W32Thread
->W32CallbackListHead
);
77 Mem
= CONTAINING_RECORD(CurrentEntry
, INT_CALLBACK_HEADER
,
81 ExFreePoolWithTag(Mem
, USERTAG_CALLBACK
);
86 // Pass the Current Window handle and pointer to the Client Callback.
87 // This will help user space programs speed up read access with the window object.
90 IntSetTebWndCallback (HWND
* hWnd
, PWND
* pWnd
, PVOID
* pActCtx
)
93 PWND Window
= UserGetWindowObject(*hWnd
);
94 PCLIENTINFO ClientInfo
= GetWin32ClientInfo();
96 *hWnd
= ClientInfo
->CallbackWnd
.hWnd
;
97 *pWnd
= ClientInfo
->CallbackWnd
.pWnd
;
98 *pActCtx
= ClientInfo
->CallbackWnd
.pActCtx
;
102 ClientInfo
->CallbackWnd
.hWnd
= hWndS
;
103 ClientInfo
->CallbackWnd
.pWnd
= DesktopHeapAddressToUser(Window
);
104 ClientInfo
->CallbackWnd
.pActCtx
= Window
->pActCtx
;
106 else //// What if Dispatching WM_SYS/TIMER with NULL window? Fix AbiWord Crash when sizing.
108 ClientInfo
->CallbackWnd
.hWnd
= hWndS
;
109 ClientInfo
->CallbackWnd
.pWnd
= Window
;
110 ClientInfo
->CallbackWnd
.pActCtx
= 0;
115 IntRestoreTebWndCallback (HWND hWnd
, PWND pWnd
, PVOID pActCtx
)
117 PCLIENTINFO ClientInfo
= GetWin32ClientInfo();
119 ClientInfo
->CallbackWnd
.hWnd
= hWnd
;
120 ClientInfo
->CallbackWnd
.pWnd
= pWnd
;
121 ClientInfo
->CallbackWnd
.pActCtx
= pActCtx
;
124 /* FUNCTIONS *****************************************************************/
126 /* Calls ClientLoadLibrary in user32 */
129 co_IntClientLoadLibrary(PUNICODE_STRING pstrLibName
,
130 PUNICODE_STRING pstrInitFunc
,
136 ULONG ArgumentLength
;
137 PCLIENT_LOAD_LIBRARY_ARGUMENTS pArguments
;
140 ULONG_PTR pLibNameBuffer
= 0, pInitFuncBuffer
= 0;
142 /* Do not allow the desktop thread to do callback to user mode */
143 ASSERT(PsGetCurrentThreadWin32Thread() != gptiDesktopThread
);
145 TRACE("co_IntClientLoadLibrary: %S, %S, %d, %d\n", pstrLibName
->Buffer
, pstrLibName
->Buffer
, Unload
, ApiHook
);
147 /* Calculate the size of the argument */
148 ArgumentLength
= sizeof(CLIENT_LOAD_LIBRARY_ARGUMENTS
);
151 pLibNameBuffer
= ArgumentLength
;
152 ArgumentLength
+= pstrLibName
->Length
+ sizeof(WCHAR
);
156 pInitFuncBuffer
= ArgumentLength
;
157 ArgumentLength
+= pstrInitFunc
->Length
+ sizeof(WCHAR
);
160 /* Allocate the argument */
161 pArguments
= IntCbAllocateMemory(ArgumentLength
);
162 if(pArguments
== NULL
)
167 /* Fill the argument */
168 pArguments
->Unload
= Unload
;
169 pArguments
->ApiHook
= ApiHook
;
172 /* Copy the string to the callback memory */
173 pLibNameBuffer
+= (ULONG_PTR
)pArguments
;
174 pArguments
->strLibraryName
.Buffer
= (PWCHAR
)pLibNameBuffer
;
175 pArguments
->strLibraryName
.MaximumLength
= pstrLibName
->Length
+ sizeof(WCHAR
);
176 RtlCopyUnicodeString(&pArguments
->strLibraryName
, pstrLibName
);
178 /* Fix argument pointer to be relative to the argument */
179 pLibNameBuffer
-= (ULONG_PTR
)pArguments
;
180 pArguments
->strLibraryName
.Buffer
= (PWCHAR
)(pLibNameBuffer
);
184 RtlZeroMemory(&pArguments
->strLibraryName
, sizeof(UNICODE_STRING
));
189 /* Copy the strings to the callback memory */
190 pInitFuncBuffer
+= (ULONG_PTR
)pArguments
;
191 pArguments
->strInitFuncName
.Buffer
= (PWCHAR
)pInitFuncBuffer
;
192 pArguments
->strInitFuncName
.MaximumLength
= pstrInitFunc
->Length
+ sizeof(WCHAR
);
193 RtlCopyUnicodeString(&pArguments
->strInitFuncName
, pstrInitFunc
);
195 /* Fix argument pointers to be relative to the argument */
196 pInitFuncBuffer
-= (ULONG_PTR
)pArguments
;
197 pArguments
->strInitFuncName
.Buffer
= (PWCHAR
)(pInitFuncBuffer
);
201 RtlZeroMemory(&pArguments
->strInitFuncName
, sizeof(UNICODE_STRING
));
204 /* Do the callback */
207 Status
= KeUserModeCallback(USER32_CALLBACK_CLIENTLOADLIBRARY
,
215 /* Free the argument */
216 IntCbFreeMemory(pArguments
);
218 if(!NT_SUCCESS(Status
))
225 /* Probe and copy the usermode result data */
226 ProbeForRead(ResultPointer
, sizeof(HMODULE
), 1);
227 bResult
= *(BOOL
*)ResultPointer
;
229 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
239 co_IntCallSentMessageCallback(SENDASYNCPROC CompletionCallback
,
242 ULONG_PTR CompletionCallbackContext
,
245 SENDASYNCPROC_CALLBACK_ARGUMENTS Arguments
;
246 PVOID ResultPointer
, pActCtx
;
251 /* Do not allow the desktop thread to do callback to user mode */
252 ASSERT(PsGetCurrentThreadWin32Thread() != gptiDesktopThread
);
254 Arguments
.Callback
= CompletionCallback
;
255 Arguments
.Wnd
= hWnd
;
257 Arguments
.Context
= CompletionCallbackContext
;
258 Arguments
.Result
= Result
;
260 IntSetTebWndCallback (&hWnd
, &pWnd
, &pActCtx
);
264 Status
= KeUserModeCallback(USER32_CALLBACK_SENDASYNCPROC
,
266 sizeof(SENDASYNCPROC_CALLBACK_ARGUMENTS
),
272 IntRestoreTebWndCallback (hWnd
, pWnd
, pActCtx
);
274 if (!NT_SUCCESS(Status
))
282 co_IntCallWindowProc(WNDPROC Proc
,
288 INT lParamBufferSize
)
290 WINDOWPROC_CALLBACK_ARGUMENTS StackArguments
;
291 PWINDOWPROC_CALLBACK_ARGUMENTS Arguments
;
293 PVOID ResultPointer
, pActCtx
;
296 ULONG ArgumentLength
;
299 TRACE("co_IntCallWindowProc(Proc %p, IsAnsiProc: %s, Wnd %p, Message %u, wParam %Iu, lParam %Id, lParamBufferSize %d)\n",
300 Proc
, IsAnsiProc
? "TRUE" : "FALSE", Wnd
, Message
, wParam
, lParam
, lParamBufferSize
);
302 /* Do not allow the desktop thread to do callback to user mode */
303 ASSERT(PsGetCurrentThreadWin32Thread() != gptiDesktopThread
);
305 if (lParamBufferSize
!= -1)
307 ArgumentLength
= sizeof(WINDOWPROC_CALLBACK_ARGUMENTS
) + lParamBufferSize
;
308 Arguments
= IntCbAllocateMemory(ArgumentLength
);
309 if (NULL
== Arguments
)
311 ERR("Unable to allocate buffer for window proc callback\n");
314 RtlMoveMemory((PVOID
) ((char *) Arguments
+ sizeof(WINDOWPROC_CALLBACK_ARGUMENTS
)),
315 (PVOID
) lParam
, lParamBufferSize
);
319 Arguments
= &StackArguments
;
320 ArgumentLength
= sizeof(WINDOWPROC_CALLBACK_ARGUMENTS
);
322 Arguments
->Proc
= Proc
;
323 Arguments
->IsAnsiProc
= IsAnsiProc
;
324 Arguments
->Wnd
= Wnd
;
325 Arguments
->Msg
= Message
;
326 Arguments
->wParam
= wParam
;
327 Arguments
->lParam
= lParam
;
328 Arguments
->lParamBufferSize
= lParamBufferSize
;
329 ResultPointer
= NULL
;
330 ResultLength
= ArgumentLength
;
332 IntSetTebWndCallback (&Wnd
, &pWnd
, &pActCtx
);
336 Status
= KeUserModeCallback(USER32_CALLBACK_WINDOWPROC
,
341 if (!NT_SUCCESS(Status
))
349 /* Simulate old behaviour: copy into our local buffer */
350 RtlMoveMemory(Arguments
, ResultPointer
, ArgumentLength
);
352 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
354 ERR("Failed to copy result from user mode, Message %u lParam size %d!\n", Message
, lParamBufferSize
);
355 Status
= _SEH2_GetExceptionCode();
361 IntRestoreTebWndCallback (Wnd
, pWnd
, pActCtx
);
363 if (!NT_SUCCESS(Status
))
365 ERR("Call to user mode failed! 0x%08lx\n",Status
);
366 if (lParamBufferSize
!= -1)
368 IntCbFreeMemory(Arguments
);
372 Result
= Arguments
->Result
;
374 if (lParamBufferSize
!= -1)
376 PTHREADINFO pti
= PsGetCurrentThreadWin32Thread();
377 // Is this message being processed from inside kernel space?
378 BOOL InSendMessage
= (pti
->pcti
->CTI_flags
& CTI_INSENDMESSAGE
);
380 TRACE("Copy lParam Message %u lParam %d!\n", Message
, lParam
);
384 TRACE("Don't copy lParam, Message %u Size %d lParam %d!\n", Message
, lParamBufferSize
, lParam
);
386 // Write back to user/kernel space. Also see g_MsgMemory.
388 case WM_GETMINMAXINFO
:
392 case WM_STYLECHANGING
:
393 case WM_WINDOWPOSCHANGING
:
398 TRACE("Copy lParam, Message %u Size %d lParam %d!\n", Message
, lParamBufferSize
, lParam
);
400 // Copy into kernel space.
401 RtlMoveMemory((PVOID
) lParam
,
402 (PVOID
) ((char *) Arguments
+ sizeof(WINDOWPROC_CALLBACK_ARGUMENTS
)),
407 { // Copy into user space.
408 RtlMoveMemory((PVOID
) lParam
,
409 (PVOID
) ((char *) Arguments
+ sizeof(WINDOWPROC_CALLBACK_ARGUMENTS
)),
412 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
414 ERR("Failed to copy lParam to user space, Message %u!\n", Message
);
420 IntCbFreeMemory(Arguments
);
427 co_IntLoadSysMenuTemplate(VOID
)
434 /* Do not allow the desktop thread to do callback to user mode */
435 ASSERT(PsGetCurrentThreadWin32Thread() != gptiDesktopThread
);
437 ResultPointer
= NULL
;
438 ResultLength
= sizeof(LRESULT
);
442 Status
= KeUserModeCallback(USER32_CALLBACK_LOADSYSMENUTEMPLATE
,
447 if (NT_SUCCESS(Status
))
449 /* Simulate old behaviour: copy into our local buffer */
452 ProbeForRead(ResultPointer
, sizeof(LRESULT
), 1);
453 Result
= *(LRESULT
*)ResultPointer
;
455 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
464 return (HMENU
)Result
;
467 extern HCURSOR gDesktopCursor
;
470 co_IntLoadDefaultCursors(VOID
)
475 BOOL DefaultCursor
= TRUE
;
477 /* Do not allow the desktop thread to do callback to user mode */
478 ASSERT(PsGetCurrentThreadWin32Thread() != gptiDesktopThread
);
480 ResultPointer
= NULL
;
481 ResultLength
= sizeof(HCURSOR
);
485 Status
= KeUserModeCallback(USER32_CALLBACK_LOADDEFAULTCURSORS
,
493 if (!NT_SUCCESS(Status
))
498 /* HACK: The desktop class doen't have a proper cursor yet, so set it here */
499 gDesktopCursor
= *((HCURSOR
*)ResultPointer
);
505 co_IntCallHookProc(INT HookId
,
513 PUNICODE_STRING ModuleName
)
515 ULONG ArgumentLength
;
516 PVOID Argument
= NULL
;
521 PHOOKPROC_CALLBACK_ARGUMENTS Common
;
522 CBT_CREATEWNDW
*CbtCreateWnd
= NULL
;
524 PHOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS CbtCreatewndExtra
= NULL
;
532 /* Do not allow the desktop thread to do callback to user mode */
533 ASSERT(PsGetCurrentThreadWin32Thread() != gptiDesktopThread
);
535 pti
= PsGetCurrentThreadWin32Thread();
536 if (pti
->TIF_flags
& TIF_INCLEANUP
)
538 ERR("Thread is in cleanup and trying to call hook %d\n", Code
);
542 ArgumentLength
= sizeof(HOOKPROC_CALLBACK_ARGUMENTS
);
547 TRACE("WH_CBT: Code %d\n", Code
);
551 pWnd
= UserGetWindowObject((HWND
) wParam
);
554 ERR("WH_CBT HCBT_CREATEWND wParam bad hWnd!\n");
557 TRACE("HCBT_CREATEWND AnsiCreator %s, AnsiHook %s\n", pWnd
->state
& WNDS_ANSICREATOR
? "True" : "False", Ansi
? "True" : "False");
558 // Due to KsStudio.exe, just pass the callers original pointers
559 // except class which point to kernel space if not an atom.
560 // Found by, Olaf Siejka
561 CbtCreateWnd
= (CBT_CREATEWNDW
*) lParam
;
562 ArgumentLength
+= sizeof(HOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS
);
566 ArgumentLength
+= sizeof(RECTL
);
569 ArgumentLength
+= sizeof(CBTACTIVATESTRUCT
);
571 case HCBT_CLICKSKIPPED
:
572 ArgumentLength
+= sizeof(MOUSEHOOKSTRUCT
);
575 case HCBT_KEYSKIPPED
:
578 case HCBT_SYSCOMMAND
:
579 /* These types pass through. */
580 case HCBT_DESTROYWND
:
584 ERR("Trying to call unsupported CBT hook %d\n", Code
);
589 ArgumentLength
+= sizeof(KBDLLHOOKSTRUCT
);
592 ArgumentLength
+= sizeof(MSLLHOOKSTRUCT
);
595 ArgumentLength
+= sizeof(MOUSEHOOKSTRUCT
);
599 CWPSTRUCT
* pCWP
= (CWPSTRUCT
*) lParam
;
600 ArgumentLength
+= sizeof(CWPSTRUCT
);
601 lParamSize
= lParamMemorySize(pCWP
->message
, pCWP
->wParam
, pCWP
->lParam
);
602 ArgumentLength
+= lParamSize
;
605 case WH_CALLWNDPROCRET
:
607 CWPRETSTRUCT
* pCWPR
= (CWPRETSTRUCT
*) lParam
;
608 ArgumentLength
+= sizeof(CWPRETSTRUCT
);
609 lParamSize
= lParamMemorySize(pCWPR
->message
, pCWPR
->wParam
, pCWPR
->lParam
);
610 ArgumentLength
+= lParamSize
;
614 case WH_SYSMSGFILTER
:
616 ArgumentLength
+= sizeof(MSG
);
618 case WH_FOREGROUNDIDLE
:
623 ERR("Trying to call unsupported window hook %d\n", HookId
);
627 Argument
= IntCbAllocateMemory(ArgumentLength
);
628 if (NULL
== Argument
)
630 ERR("HookProc callback failed: out of memory\n");
633 Common
= (PHOOKPROC_CALLBACK_ARGUMENTS
) Argument
;
634 Common
->HookId
= HookId
;
636 Common
->wParam
= wParam
;
637 Common
->lParam
= lParam
;
640 Common
->offPfn
= offPfn
;
642 RtlZeroMemory(&Common
->ModuleName
, sizeof(Common
->ModuleName
));
643 RtlCopyMemory(&Common
->ModuleName
, ModuleName
->Buffer
, ModuleName
->Length
);
644 Extra
= (PCHAR
) Common
+ sizeof(HOOKPROC_CALLBACK_ARGUMENTS
);
650 { // Need to remember this is not the first time through! Call Next Hook?
652 CbtCreatewndExtra
= (PHOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS
) Extra
;
653 RtlCopyMemory( &CbtCreatewndExtra
->Cs
, CbtCreateWnd
->lpcs
, sizeof(CREATESTRUCTW
) );
654 CbtCreatewndExtra
->WndInsertAfter
= CbtCreateWnd
->hwndInsertAfter
;
655 CbtCreatewndExtra
->Cs
.lpszClass
= CbtCreateWnd
->lpcs
->lpszClass
;
656 CbtCreatewndExtra
->Cs
.lpszName
= CbtCreateWnd
->lpcs
->lpszName
;
657 Common
->lParam
= (LPARAM
) (Extra
- (PCHAR
) Common
);
659 case HCBT_CLICKSKIPPED
:
660 RtlCopyMemory(Extra
, (PVOID
) lParam
, sizeof(MOUSEHOOKSTRUCT
));
661 Common
->lParam
= (LPARAM
) (Extra
- (PCHAR
) Common
);
664 RtlCopyMemory(Extra
, (PVOID
) lParam
, sizeof(RECTL
));
665 Common
->lParam
= (LPARAM
) (Extra
- (PCHAR
) Common
);
668 RtlCopyMemory(Extra
, (PVOID
) lParam
, sizeof(CBTACTIVATESTRUCT
));
669 Common
->lParam
= (LPARAM
) (Extra
- (PCHAR
) Common
);
674 RtlCopyMemory(Extra
, (PVOID
) lParam
, sizeof(KBDLLHOOKSTRUCT
));
675 Common
->lParam
= (LPARAM
) (Extra
- (PCHAR
) Common
);
678 RtlCopyMemory(Extra
, (PVOID
) lParam
, sizeof(MSLLHOOKSTRUCT
));
679 Common
->lParam
= (LPARAM
) (Extra
- (PCHAR
) Common
);
682 RtlCopyMemory(Extra
, (PVOID
) lParam
, sizeof(MOUSEHOOKSTRUCT
));
683 Common
->lParam
= (LPARAM
) (Extra
- (PCHAR
) Common
);
686 /* For CALLWNDPROC and CALLWNDPROCRET, we must be wary of the fact that
687 * lParam could be a pointer to a buffer. This buffer must be exported
688 * to user space too */
689 RtlCopyMemory(Extra
, (PVOID
) lParam
, sizeof(CWPSTRUCT
));
690 Common
->lParam
= (LPARAM
) (Extra
- (PCHAR
) Common
);
693 RtlCopyMemory(Extra
+ sizeof(CWPSTRUCT
), (PVOID
)((CWPSTRUCT
*)lParam
)->lParam
, lParamSize
);
694 ((CWPSTRUCT
*)Extra
)->lParam
= (LPARAM
)lParamSize
;
697 case WH_CALLWNDPROCRET
:
698 RtlCopyMemory(Extra
, (PVOID
) lParam
, sizeof(CWPRETSTRUCT
));
699 Common
->lParam
= (LPARAM
) (Extra
- (PCHAR
) Common
);
702 RtlCopyMemory(Extra
+ sizeof(CWPRETSTRUCT
), (PVOID
)((CWPRETSTRUCT
*)lParam
)->lParam
, lParamSize
);
703 ((CWPRETSTRUCT
*)Extra
)->lParam
= (LPARAM
)lParamSize
;
707 case WH_SYSMSGFILTER
:
710 RtlCopyMemory(Extra
, (PVOID
) pMsg
, sizeof(MSG
));
711 Common
->lParam
= (LPARAM
) (Extra
- (PCHAR
) Common
);
713 case WH_FOREGROUNDIDLE
:
719 ResultPointer
= NULL
;
720 ResultLength
= ArgumentLength
;
724 Status
= KeUserModeCallback(USER32_CALLBACK_HOOKPROC
,
732 if (!NT_SUCCESS(Status
))
734 ERR("Failure to make Callback! Status 0x%x",Status
);
742 /* Simulate old behaviour: copy into our local buffer */
743 RtlMoveMemory(Argument
, ResultPointer
, ArgumentLength
);
744 Result
= Common
->Result
;
746 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
755 ERR("ERROR: Hook %d Code %d ResultPointer 0x%p ResultLength %u\n",HookId
,Code
,ResultPointer
,ResultLength
);
758 /* Support write backs... SEH is in UserCallNextHookEx. */
766 if (CbtCreatewndExtra
)
768 The parameters could have been changed, include the coordinates
769 and dimensions of the window. We copy it back.
771 CbtCreateWnd
->hwndInsertAfter
= CbtCreatewndExtra
->WndInsertAfter
;
772 CbtCreateWnd
->lpcs
->x
= CbtCreatewndExtra
->Cs
.x
;
773 CbtCreateWnd
->lpcs
->y
= CbtCreatewndExtra
->Cs
.y
;
774 CbtCreateWnd
->lpcs
->cx
= CbtCreatewndExtra
->Cs
.cx
;
775 CbtCreateWnd
->lpcs
->cy
= CbtCreatewndExtra
->Cs
.cy
;
781 RtlCopyMemory((PVOID
) lParam
, Extra
, sizeof(RECTL
));
786 // "The GetMsgProc hook procedure can examine or modify the message."
790 RtlCopyMemory((PVOID
) pMsg
, Extra
, sizeof(MSG
));
798 ERR("Exception CallHookProc HookId %d Code %d\n",HookId
,Code
);
800 if (Argument
) IntCbFreeMemory(Argument
);
806 // Events are notifications w/o results.
810 co_IntCallEventProc(HWINEVENTHOOK hook
,
823 PEVENTPROC_CALLBACK_ARGUMENTS Common
;
824 ULONG ArgumentLength
, ResultLength
;
825 PVOID Argument
, ResultPointer
;
827 ArgumentLength
= sizeof(EVENTPROC_CALLBACK_ARGUMENTS
);
829 Argument
= IntCbAllocateMemory(ArgumentLength
);
830 if (NULL
== Argument
)
832 ERR("EventProc callback failed: out of memory\n");
835 Common
= (PEVENTPROC_CALLBACK_ARGUMENTS
) Argument
;
837 Common
->event
= event
;
839 Common
->idObject
= idObject
;
840 Common
->idChild
= idChild
;
841 Common
->dwEventThread
= dwEventThread
;
842 Common
->dwmsEventTime
= dwmsEventTime
;
845 Common
->offPfn
= offPfn
;
847 ResultPointer
= NULL
;
848 ResultLength
= sizeof(LRESULT
);
852 Status
= KeUserModeCallback(USER32_CALLBACK_EVENTPROC
,
860 IntCbFreeMemory(Argument
);
862 if (!NT_SUCCESS(Status
))
871 // Callback Load Menu and results.
875 co_IntCallLoadMenu( HINSTANCE hModule
,
876 PUNICODE_STRING pMenuName
)
880 PLOADMENU_CALLBACK_ARGUMENTS Common
;
881 ULONG ArgumentLength
, ResultLength
;
882 PVOID Argument
, ResultPointer
;
884 ArgumentLength
= sizeof(LOADMENU_CALLBACK_ARGUMENTS
);
886 ArgumentLength
+= pMenuName
->Length
+ sizeof(WCHAR
);
888 Argument
= IntCbAllocateMemory(ArgumentLength
);
889 if (NULL
== Argument
)
891 ERR("LoadMenu callback failed: out of memory\n");
894 Common
= (PLOADMENU_CALLBACK_ARGUMENTS
) Argument
;
896 // Help Intersource check and MenuName is now 4 bytes + so zero it.
897 RtlZeroMemory(Common
, ArgumentLength
);
899 Common
->hModule
= hModule
;
900 if (pMenuName
->Length
)
901 RtlCopyMemory(&Common
->MenuName
, pMenuName
->Buffer
, pMenuName
->Length
);
903 Common
->InterSource
= pMenuName
->Buffer
;
905 ResultPointer
= NULL
;
906 ResultLength
= sizeof(LRESULT
);
910 Status
= KeUserModeCallback(USER32_CALLBACK_LOADMENU
,
918 if (NT_SUCCESS(Status
))
920 Result
= *(LRESULT
*)ResultPointer
;
927 IntCbFreeMemory(Argument
);
929 return (HMENU
)Result
;
934 co_IntClientThreadSetup(VOID
)
937 ULONG ArgumentLength
, ResultLength
;
938 PVOID Argument
, ResultPointer
;
940 /* Do not allow the desktop thread to do callback to user mode */
941 ASSERT(PsGetCurrentThreadWin32Thread() != gptiDesktopThread
);
943 ArgumentLength
= ResultLength
= 0;
944 Argument
= ResultPointer
= NULL
;
948 Status
= KeUserModeCallback(USER32_CALLBACK_CLIENTTHREADSTARTUP
,
960 co_IntCopyImage(HANDLE hnd
, UINT type
, INT desiredx
, INT desiredy
, UINT flags
)
964 ULONG ArgumentLength
, ResultLength
;
965 PVOID Argument
, ResultPointer
;
966 PCOPYIMAGE_CALLBACK_ARGUMENTS Common
;
968 ArgumentLength
= ResultLength
= 0;
969 Argument
= ResultPointer
= NULL
;
971 ArgumentLength
= sizeof(COPYIMAGE_CALLBACK_ARGUMENTS
);
973 Argument
= IntCbAllocateMemory(ArgumentLength
);
974 if (NULL
== Argument
)
976 ERR("CopyImage callback failed: out of memory\n");
979 Common
= (PCOPYIMAGE_CALLBACK_ARGUMENTS
) Argument
;
981 Common
->hImage
= hnd
;
982 Common
->uType
= type
;
983 Common
->cxDesired
= desiredx
;
984 Common
->cyDesired
= desiredy
;
985 Common
->fuFlags
= flags
;
989 Status
= KeUserModeCallback(USER32_CALLBACK_COPYIMAGE
,
998 if (NT_SUCCESS(Status
))
1000 Handle
= *(HANDLE
*)ResultPointer
;
1004 ERR("CopyImage callback failed!\n");
1008 IntCbFreeMemory(Argument
);
1015 co_IntGetCharsetInfo(LCID Locale
, PCHARSETINFO pCs
)
1018 ULONG ArgumentLength
, ResultLength
;
1019 PVOID Argument
, ResultPointer
;
1020 PGET_CHARSET_INFO Common
;
1022 ArgumentLength
= sizeof(GET_CHARSET_INFO
);
1024 Argument
= IntCbAllocateMemory(ArgumentLength
);
1025 if (NULL
== Argument
)
1027 ERR("GetCharsetInfo callback failed: out of memory\n");
1030 Common
= (PGET_CHARSET_INFO
) Argument
;
1032 Common
->Locale
= Locale
;
1034 ResultPointer
= NULL
;
1035 ResultLength
= ArgumentLength
;
1039 Status
= KeUserModeCallback(USER32_CALLBACK_GETCHARSETINFO
,
1045 if (NT_SUCCESS(Status
))
1049 /* Need to copy into our local buffer */
1050 RtlMoveMemory(Argument
, ResultPointer
, ArgumentLength
);
1052 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1054 ERR("Failed to copy result from user mode!\n");
1055 Status
= _SEH2_GetExceptionCode();
1062 RtlCopyMemory(pCs
, &Common
->Cs
, sizeof(CHARSETINFO
));
1064 IntCbFreeMemory(Argument
);
1066 if (!NT_SUCCESS(Status
))
1068 ERR("GetCharsetInfo Failed!!\n");
1076 co_IntSetWndIcons(VOID
)
1079 ULONG ArgumentLength
, ResultLength
;
1080 PVOID Argument
, ResultPointer
;
1081 PSETWNDICONS_CALLBACK_ARGUMENTS Common
;
1083 ResultPointer
= NULL
;
1084 ResultLength
= ArgumentLength
= sizeof(SETWNDICONS_CALLBACK_ARGUMENTS
);
1086 Argument
= IntCbAllocateMemory(ArgumentLength
);
1087 if (NULL
== Argument
)
1089 ERR("Set Window Icons callback failed: out of memory\n");
1092 Common
= (PSETWNDICONS_CALLBACK_ARGUMENTS
) Argument
;
1096 Status
= KeUserModeCallback(USER32_CALLBACK_SETWNDICONS
,
1105 if (!NT_SUCCESS(Status
))
1107 ERR("Set Window Icons callback failed!\n");
1108 IntCbFreeMemory(Argument
);
1112 RtlMoveMemory(Common
, ResultPointer
, ArgumentLength
);
1113 gpsi
->hIconSmWindows
= Common
->hIconSmWindows
;
1114 gpsi
->hIconWindows
= Common
->hIconWindows
;
1116 IntLoadSystenIcons(Common
->hIconSample
, OIC_SAMPLE
);
1117 IntLoadSystenIcons(Common
->hIconHand
, OIC_HAND
);
1118 IntLoadSystenIcons(Common
->hIconQuestion
, OIC_QUES
);
1119 IntLoadSystenIcons(Common
->hIconBang
, OIC_BANG
);
1120 IntLoadSystenIcons(Common
->hIconNote
, OIC_NOTE
);
1121 IntLoadSystenIcons(gpsi
->hIconWindows
, OIC_WINLOGO
);
1122 IntLoadSystenIcons(gpsi
->hIconSmWindows
, OIC_WINLOGO
+1);
1124 ERR("hIconSmWindows %p hIconWindows %p \n",gpsi
->hIconSmWindows
,gpsi
->hIconWindows
);
1126 IntCbFreeMemory(Argument
);
1132 co_IntDeliverUserAPC(VOID
)
1135 PVOID ResultPointer
;
1139 Status
= KeUserModeCallback(USER32_CALLBACK_DELIVERUSERAPC
,
1148 if (!NT_SUCCESS(Status
))
1150 ERR("Delivering User APC callback failed!\n");
1155 co_IntSetupOBM(VOID
)
1158 ULONG ArgumentLength
, ResultLength
;
1159 PVOID Argument
, ResultPointer
;
1160 PSETOBM_CALLBACK_ARGUMENTS Common
;
1162 ResultPointer
= NULL
;
1163 ResultLength
= ArgumentLength
= sizeof(SETOBM_CALLBACK_ARGUMENTS
);
1165 Argument
= IntCbAllocateMemory(ArgumentLength
);
1166 if (NULL
== Argument
)
1168 ERR("Set Window Icons callback failed: out of memory\n");
1171 Common
= (PSETOBM_CALLBACK_ARGUMENTS
) Argument
;
1175 Status
= KeUserModeCallback(USER32_CALLBACK_SETOBM
,
1184 if (!NT_SUCCESS(Status
))
1186 ERR("Set Window Icons callback failed!\n");
1187 IntCbFreeMemory(Argument
);
1191 RtlMoveMemory(Common
, ResultPointer
, ArgumentLength
);
1192 RtlCopyMemory(gpsi
->oembmi
, Common
->oembmi
, sizeof(gpsi
->oembmi
));
1194 IntCbFreeMemory(Argument
);