2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Win32k subsystem
4 * PURPOSE: Callback to usermode support
5 * FILE: subsystems/win32/win32k/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
;
100 ClientInfo
->CallbackWnd
.hWnd
= hWndS
;
101 ClientInfo
->CallbackWnd
.pWnd
= DesktopHeapAddressToUser(Window
);
102 ClientInfo
->CallbackWnd
.pActCtx
= Window
->pActCtx
;
106 IntRestoreTebWndCallback (HWND hWnd
, PWND pWnd
, PVOID pActCtx
)
108 PCLIENTINFO ClientInfo
= GetWin32ClientInfo();
110 ClientInfo
->CallbackWnd
.hWnd
= hWnd
;
111 ClientInfo
->CallbackWnd
.pWnd
= pWnd
;
112 ClientInfo
->CallbackWnd
.pActCtx
= pActCtx
;
115 /* FUNCTIONS *****************************************************************/
117 /* Calls ClientLoadLibrary in user32 */
120 co_IntClientLoadLibrary(PUNICODE_STRING pstrLibName
,
121 PUNICODE_STRING pstrInitFunc
,
127 ULONG ArgumentLength
;
128 PCLIENT_LOAD_LIBRARY_ARGUMENTS pArguments
;
131 ULONG_PTR pLibNameBuffer
= 0, pInitFuncBuffer
= 0;
133 /* Do not allow the desktop thread to do callback to user mode */
134 ASSERT(PsGetCurrentThreadWin32Thread() != gptiDesktopThread
);
136 TRACE("co_IntClientLoadLibrary: %S, %S, %d, %d\n", pstrLibName
->Buffer
, pstrLibName
->Buffer
, Unload
, ApiHook
);
138 /* Calculate the size of the argument */
139 ArgumentLength
= sizeof(CLIENT_LOAD_LIBRARY_ARGUMENTS
);
142 pLibNameBuffer
= ArgumentLength
;
143 ArgumentLength
+= pstrLibName
->Length
+ sizeof(WCHAR
);
147 pInitFuncBuffer
= ArgumentLength
;
148 ArgumentLength
+= pstrInitFunc
->Length
+ sizeof(WCHAR
);
151 /* Allocate the argument */
152 pArguments
= IntCbAllocateMemory(ArgumentLength
);
153 if(pArguments
== NULL
)
158 /* Fill the argument */
159 pArguments
->Unload
= Unload
;
160 pArguments
->ApiHook
= ApiHook
;
163 /* Copy the string to the callback memory */
164 pLibNameBuffer
+= (ULONG_PTR
)pArguments
;
165 pArguments
->strLibraryName
.Buffer
= (PWCHAR
)pLibNameBuffer
;
166 pArguments
->strLibraryName
.MaximumLength
= pstrLibName
->Length
+ sizeof(WCHAR
);
167 RtlCopyUnicodeString(&pArguments
->strLibraryName
, pstrLibName
);
169 /* Fix argument pointer to be relative to the argument */
170 pLibNameBuffer
-= (ULONG_PTR
)pArguments
;
171 pArguments
->strLibraryName
.Buffer
= (PWCHAR
)(pLibNameBuffer
);
175 RtlZeroMemory(&pArguments
->strLibraryName
, sizeof(UNICODE_STRING
));
180 /* Copy the strings to the callback memory */
181 pInitFuncBuffer
+= (ULONG_PTR
)pArguments
;
182 pArguments
->strInitFuncName
.Buffer
= (PWCHAR
)pInitFuncBuffer
;
183 pArguments
->strInitFuncName
.MaximumLength
= pstrInitFunc
->Length
+ sizeof(WCHAR
);
184 RtlCopyUnicodeString(&pArguments
->strInitFuncName
, pstrInitFunc
);
186 /* Fix argument pointers to be relative to the argument */
187 pInitFuncBuffer
-= (ULONG_PTR
)pArguments
;
188 pArguments
->strInitFuncName
.Buffer
= (PWCHAR
)(pInitFuncBuffer
);
192 RtlZeroMemory(&pArguments
->strInitFuncName
, sizeof(UNICODE_STRING
));
195 /* Do the callback */
198 Status
= KeUserModeCallback(USER32_CALLBACK_CLIENTLOADLIBRARY
,
206 /* Free the argument */
207 IntCbFreeMemory(pArguments
);
209 if(!NT_SUCCESS(Status
))
216 /* Probe and copy the usermode result data */
217 ProbeForRead(ResultPointer
, sizeof(HMODULE
), 1);
218 bResult
= *(BOOL
*)ResultPointer
;
220 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
230 co_IntCallSentMessageCallback(SENDASYNCPROC CompletionCallback
,
233 ULONG_PTR CompletionCallbackContext
,
236 SENDASYNCPROC_CALLBACK_ARGUMENTS Arguments
;
237 PVOID ResultPointer
, pActCtx
;
242 /* Do not allow the desktop thread to do callback to user mode */
243 ASSERT(PsGetCurrentThreadWin32Thread() != gptiDesktopThread
);
245 Arguments
.Callback
= CompletionCallback
;
246 Arguments
.Wnd
= hWnd
;
248 Arguments
.Context
= CompletionCallbackContext
;
249 Arguments
.Result
= Result
;
251 IntSetTebWndCallback (&hWnd
, &pWnd
, &pActCtx
);
255 Status
= KeUserModeCallback(USER32_CALLBACK_SENDASYNCPROC
,
257 sizeof(SENDASYNCPROC_CALLBACK_ARGUMENTS
),
263 IntRestoreTebWndCallback (hWnd
, pWnd
, pActCtx
);
265 if (!NT_SUCCESS(Status
))
273 co_IntCallWindowProc(WNDPROC Proc
,
279 INT lParamBufferSize
)
281 WINDOWPROC_CALLBACK_ARGUMENTS StackArguments
;
282 PWINDOWPROC_CALLBACK_ARGUMENTS Arguments
;
284 PVOID ResultPointer
, pActCtx
;
287 ULONG ArgumentLength
;
290 /* Do not allow the desktop thread to do callback to user mode */
291 ASSERT(PsGetCurrentThreadWin32Thread() != gptiDesktopThread
);
293 if (lParamBufferSize
!= -1)
295 ArgumentLength
= sizeof(WINDOWPROC_CALLBACK_ARGUMENTS
) + lParamBufferSize
;
296 Arguments
= IntCbAllocateMemory(ArgumentLength
);
297 if (NULL
== Arguments
)
299 ERR("Unable to allocate buffer for window proc callback\n");
302 RtlMoveMemory((PVOID
) ((char *) Arguments
+ sizeof(WINDOWPROC_CALLBACK_ARGUMENTS
)),
303 (PVOID
) lParam
, lParamBufferSize
);
307 Arguments
= &StackArguments
;
308 ArgumentLength
= sizeof(WINDOWPROC_CALLBACK_ARGUMENTS
);
310 Arguments
->Proc
= Proc
;
311 Arguments
->IsAnsiProc
= IsAnsiProc
;
312 Arguments
->Wnd
= Wnd
;
313 Arguments
->Msg
= Message
;
314 Arguments
->wParam
= wParam
;
315 Arguments
->lParam
= lParam
;
316 Arguments
->lParamBufferSize
= lParamBufferSize
;
317 ResultPointer
= NULL
;
318 ResultLength
= ArgumentLength
;
320 IntSetTebWndCallback (&Wnd
, &pWnd
, &pActCtx
);
324 Status
= KeUserModeCallback(USER32_CALLBACK_WINDOWPROC
,
332 /* Simulate old behaviour: copy into our local buffer */
333 RtlMoveMemory(Arguments
, ResultPointer
, ArgumentLength
);
335 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
337 ERR("Failed to copy result from user mode, Message %d lParam size %d!\n", Message
, lParamBufferSize
);
338 Status
= _SEH2_GetExceptionCode();
344 IntRestoreTebWndCallback (Wnd
, pWnd
, pActCtx
);
346 if (!NT_SUCCESS(Status
))
348 ERR("Call to user mode failed!\n");
349 if (lParamBufferSize
!= -1)
351 IntCbFreeMemory(Arguments
);
355 Result
= Arguments
->Result
;
357 if (lParamBufferSize
!= -1)
359 PTHREADINFO pti
= PsGetCurrentThreadWin32Thread();
360 // Is this message being processed from inside kernel space?
361 BOOL InSendMessage
= (pti
->pcti
->CTI_flags
& CTI_INSENDMESSAGE
);
363 TRACE("Copy lParam Message %d lParam %d!\n", Message
, lParam
);
367 TRACE("Don't copy lParam, Message %d Size %d lParam %d!\n", Message
, lParamBufferSize
, lParam
);
369 // Write back to user/kernel space. Also see g_MsgMemory.
371 case WM_GETMINMAXINFO
:
375 case WM_STYLECHANGING
:
376 case WM_WINDOWPOSCHANGING
:
379 TRACE("Copy lParam, Message %d Size %d lParam %d!\n", Message
, lParamBufferSize
, lParam
);
381 // Copy into kernel space.
382 RtlMoveMemory((PVOID
) lParam
,
383 (PVOID
) ((char *) Arguments
+ sizeof(WINDOWPROC_CALLBACK_ARGUMENTS
)),
388 { // Copy into user space.
389 RtlMoveMemory((PVOID
) lParam
,
390 (PVOID
) ((char *) Arguments
+ sizeof(WINDOWPROC_CALLBACK_ARGUMENTS
)),
393 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
395 ERR("Failed to copy lParam to user space, Message %d!\n", Message
);
401 IntCbFreeMemory(Arguments
);
408 co_IntLoadSysMenuTemplate()
415 /* Do not allow the desktop thread to do callback to user mode */
416 ASSERT(PsGetCurrentThreadWin32Thread() != gptiDesktopThread
);
418 ResultPointer
= NULL
;
419 ResultLength
= sizeof(LRESULT
);
423 Status
= KeUserModeCallback(USER32_CALLBACK_LOADSYSMENUTEMPLATE
,
428 if (NT_SUCCESS(Status
))
430 /* Simulate old behaviour: copy into our local buffer */
433 ProbeForRead(ResultPointer
, sizeof(LRESULT
), 1);
434 Result
= *(LRESULT
*)ResultPointer
;
436 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
445 return (HMENU
)Result
;
448 extern HCURSOR gDesktopCursor
;
451 co_IntLoadDefaultCursors(VOID
)
456 BOOL DefaultCursor
= TRUE
;
458 /* Do not allow the desktop thread to do callback to user mode */
459 ASSERT(PsGetCurrentThreadWin32Thread() != gptiDesktopThread
);
461 ResultPointer
= NULL
;
462 ResultLength
= sizeof(HCURSOR
);
466 Status
= KeUserModeCallback(USER32_CALLBACK_LOADDEFAULTCURSORS
,
474 /* HACK: The desktop class doen't have a proper cursor yet, so set it here */
475 gDesktopCursor
= *((HCURSOR
*)ResultPointer
);
477 if (!NT_SUCCESS(Status
))
485 co_IntCallHookProc(INT HookId
,
493 PUNICODE_STRING ModuleName
)
495 ULONG ArgumentLength
;
496 PVOID Argument
= NULL
;
501 PHOOKPROC_CALLBACK_ARGUMENTS Common
;
502 CBT_CREATEWNDW
*CbtCreateWnd
= NULL
;
504 PHOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS CbtCreatewndExtra
= NULL
;
512 /* Do not allow the desktop thread to do callback to user mode */
513 ASSERT(PsGetCurrentThreadWin32Thread() != gptiDesktopThread
);
515 pti
= PsGetCurrentThreadWin32Thread();
516 if (pti
->TIF_flags
& TIF_INCLEANUP
)
518 ERR("Thread is in cleanup and trying to call hook %d\n", Code
);
522 ArgumentLength
= sizeof(HOOKPROC_CALLBACK_ARGUMENTS
);
527 TRACE("WH_CBT: Code %d\n", Code
);
531 pWnd
= UserGetWindowObject((HWND
) wParam
);
534 ERR("WH_CBT HCBT_CREATEWND wParam bad hWnd!\n");
537 TRACE("HCBT_CREATEWND AnsiCreator %s, AnsiHook %s\n", pWnd
->state
& WNDS_ANSICREATOR
? "True" : "False", Ansi
? "True" : "False");
538 // Due to KsStudio.exe, just pass the callers original pointers
539 // except class which point to kernel space if not an atom.
540 // Found by, Olaf Siejka
541 CbtCreateWnd
= (CBT_CREATEWNDW
*) lParam
;
542 ArgumentLength
+= sizeof(HOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS
);
546 ArgumentLength
+= sizeof(RECTL
);
549 ArgumentLength
+= sizeof(CBTACTIVATESTRUCT
);
551 case HCBT_CLICKSKIPPED
:
552 ArgumentLength
+= sizeof(MOUSEHOOKSTRUCT
);
555 case HCBT_KEYSKIPPED
:
558 case HCBT_SYSCOMMAND
:
559 /* These types pass through. */
560 case HCBT_DESTROYWND
:
564 ERR("Trying to call unsupported CBT hook %d\n", Code
);
569 ArgumentLength
+= sizeof(KBDLLHOOKSTRUCT
);
572 ArgumentLength
+= sizeof(MSLLHOOKSTRUCT
);
575 ArgumentLength
+= sizeof(MOUSEHOOKSTRUCT
);
579 CWPSTRUCT
* pCWP
= (CWPSTRUCT
*) lParam
;
580 ArgumentLength
+= sizeof(CWPSTRUCT
);
581 lParamSize
= lParamMemorySize(pCWP
->message
, pCWP
->wParam
, pCWP
->lParam
);
582 ArgumentLength
+= lParamSize
;
585 case WH_CALLWNDPROCRET
:
587 CWPRETSTRUCT
* pCWPR
= (CWPRETSTRUCT
*) lParam
;
588 ArgumentLength
+= sizeof(CWPRETSTRUCT
);
589 lParamSize
= lParamMemorySize(pCWPR
->message
, pCWPR
->wParam
, pCWPR
->lParam
);
590 ArgumentLength
+= lParamSize
;
594 case WH_SYSMSGFILTER
:
596 ArgumentLength
+= sizeof(MSG
);
598 case WH_FOREGROUNDIDLE
:
603 ERR("Trying to call unsupported window hook %d\n", HookId
);
607 Argument
= IntCbAllocateMemory(ArgumentLength
);
608 if (NULL
== Argument
)
610 ERR("HookProc callback failed: out of memory\n");
613 Common
= (PHOOKPROC_CALLBACK_ARGUMENTS
) Argument
;
614 Common
->HookId
= HookId
;
616 Common
->wParam
= wParam
;
617 Common
->lParam
= lParam
;
620 Common
->offPfn
= offPfn
;
622 RtlZeroMemory(&Common
->ModuleName
, sizeof(Common
->ModuleName
));
623 RtlCopyMemory(&Common
->ModuleName
, ModuleName
->Buffer
, ModuleName
->Length
);
624 Extra
= (PCHAR
) Common
+ sizeof(HOOKPROC_CALLBACK_ARGUMENTS
);
630 { // Need to remember this is not the first time through! Call Next Hook?
632 CbtCreatewndExtra
= (PHOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS
) Extra
;
633 RtlCopyMemory( &CbtCreatewndExtra
->Cs
, CbtCreateWnd
->lpcs
, sizeof(CREATESTRUCTW
) );
634 CbtCreatewndExtra
->WndInsertAfter
= CbtCreateWnd
->hwndInsertAfter
;
635 CbtCreatewndExtra
->Cs
.lpszClass
= CbtCreateWnd
->lpcs
->lpszClass
;
636 CbtCreatewndExtra
->Cs
.lpszName
= CbtCreateWnd
->lpcs
->lpszName
;
637 Common
->lParam
= (LPARAM
) (Extra
- (PCHAR
) Common
);
639 case HCBT_CLICKSKIPPED
:
640 RtlCopyMemory(Extra
, (PVOID
) lParam
, sizeof(MOUSEHOOKSTRUCT
));
641 Common
->lParam
= (LPARAM
) (Extra
- (PCHAR
) Common
);
644 RtlCopyMemory(Extra
, (PVOID
) lParam
, sizeof(RECTL
));
645 Common
->lParam
= (LPARAM
) (Extra
- (PCHAR
) Common
);
648 RtlCopyMemory(Extra
, (PVOID
) lParam
, sizeof(CBTACTIVATESTRUCT
));
649 Common
->lParam
= (LPARAM
) (Extra
- (PCHAR
) Common
);
654 RtlCopyMemory(Extra
, (PVOID
) lParam
, sizeof(KBDLLHOOKSTRUCT
));
655 Common
->lParam
= (LPARAM
) (Extra
- (PCHAR
) Common
);
658 RtlCopyMemory(Extra
, (PVOID
) lParam
, sizeof(MSLLHOOKSTRUCT
));
659 Common
->lParam
= (LPARAM
) (Extra
- (PCHAR
) Common
);
662 RtlCopyMemory(Extra
, (PVOID
) lParam
, sizeof(MOUSEHOOKSTRUCT
));
663 Common
->lParam
= (LPARAM
) (Extra
- (PCHAR
) Common
);
666 /* For CALLWNDPROC and CALLWNDPROCRET, we must be wary of the fact that
667 * lParam could be a pointer to a buffer. This buffer must be exported
668 * to user space too */
669 RtlCopyMemory(Extra
, (PVOID
) lParam
, sizeof(CWPSTRUCT
));
670 Common
->lParam
= (LPARAM
) (Extra
- (PCHAR
) Common
);
673 RtlCopyMemory(Extra
+ sizeof(CWPSTRUCT
), (PVOID
)((CWPSTRUCT
*)lParam
)->lParam
, lParamSize
);
674 ((CWPSTRUCT
*)Extra
)->lParam
= (LPARAM
)lParamSize
;
677 case WH_CALLWNDPROCRET
:
678 RtlCopyMemory(Extra
, (PVOID
) lParam
, sizeof(CWPRETSTRUCT
));
679 Common
->lParam
= (LPARAM
) (Extra
- (PCHAR
) Common
);
682 RtlCopyMemory(Extra
+ sizeof(CWPRETSTRUCT
), (PVOID
)((CWPRETSTRUCT
*)lParam
)->lParam
, lParamSize
);
683 ((CWPRETSTRUCT
*)Extra
)->lParam
= (LPARAM
)lParamSize
;
687 case WH_SYSMSGFILTER
:
690 RtlCopyMemory(Extra
, (PVOID
) pMsg
, sizeof(MSG
));
691 Common
->lParam
= (LPARAM
) (Extra
- (PCHAR
) Common
);
693 case WH_FOREGROUNDIDLE
:
699 ResultPointer
= NULL
;
700 ResultLength
= ArgumentLength
;
704 Status
= KeUserModeCallback(USER32_CALLBACK_HOOKPROC
,
716 /* Simulate old behaviour: copy into our local buffer */
717 RtlMoveMemory(Argument
, ResultPointer
, ArgumentLength
);
718 Result
= Common
->Result
;
720 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
729 ERR("ERROR: Hook %d Code %d ResultPointer 0x%p ResultLength %u\n",HookId
,Code
,ResultPointer
,ResultLength
);
732 if (!NT_SUCCESS(Status
))
734 ERR("Failure to make Callback! Status 0x%x",Status
);
737 /* Support write backs... SEH is in UserCallNextHookEx. */
745 if (CbtCreatewndExtra
)
747 The parameters could have been changed, include the coordinates
748 and dimensions of the window. We copy it back.
750 CbtCreateWnd
->hwndInsertAfter
= CbtCreatewndExtra
->WndInsertAfter
;
751 CbtCreateWnd
->lpcs
->x
= CbtCreatewndExtra
->Cs
.x
;
752 CbtCreateWnd
->lpcs
->y
= CbtCreatewndExtra
->Cs
.y
;
753 CbtCreateWnd
->lpcs
->cx
= CbtCreatewndExtra
->Cs
.cx
;
754 CbtCreateWnd
->lpcs
->cy
= CbtCreatewndExtra
->Cs
.cy
;
760 RtlCopyMemory((PVOID
) lParam
, Extra
, sizeof(RECTL
));
765 // "The GetMsgProc hook procedure can examine or modify the message."
769 RtlCopyMemory((PVOID
) pMsg
, Extra
, sizeof(MSG
));
777 ERR("Exception CallHookProc HookId %d Code %d\n",HookId
,Code
);
779 if (Argument
) IntCbFreeMemory(Argument
);
785 // Events are notifications w/o results.
789 co_IntCallEventProc(HWINEVENTHOOK hook
,
800 PEVENTPROC_CALLBACK_ARGUMENTS Common
;
801 ULONG ArgumentLength
, ResultLength
;
802 PVOID Argument
, ResultPointer
;
804 ArgumentLength
= sizeof(EVENTPROC_CALLBACK_ARGUMENTS
);
806 Argument
= IntCbAllocateMemory(ArgumentLength
);
807 if (NULL
== Argument
)
809 ERR("EventProc callback failed: out of memory\n");
812 Common
= (PEVENTPROC_CALLBACK_ARGUMENTS
) Argument
;
814 Common
->event
= event
;
816 Common
->idObject
= idObject
;
817 Common
->idChild
= idChild
;
818 Common
->dwEventThread
= dwEventThread
;
819 Common
->dwmsEventTime
= dwmsEventTime
;
822 ResultPointer
= NULL
;
823 ResultLength
= sizeof(LRESULT
);
827 Status
= KeUserModeCallback(USER32_CALLBACK_EVENTPROC
,
835 IntCbFreeMemory(Argument
);
837 if (!NT_SUCCESS(Status
))
846 // Callback Load Menu and results.
850 co_IntCallLoadMenu( HINSTANCE hModule
,
851 PUNICODE_STRING pMenuName
)
855 PLOADMENU_CALLBACK_ARGUMENTS Common
;
856 ULONG ArgumentLength
, ResultLength
;
857 PVOID Argument
, ResultPointer
;
859 ArgumentLength
= sizeof(LOADMENU_CALLBACK_ARGUMENTS
);
861 ArgumentLength
+= pMenuName
->Length
+ sizeof(WCHAR
);
863 Argument
= IntCbAllocateMemory(ArgumentLength
);
864 if (NULL
== Argument
)
866 ERR("LoadMenu callback failed: out of memory\n");
869 Common
= (PLOADMENU_CALLBACK_ARGUMENTS
) Argument
;
871 // Help Intersource check and MenuName is now 4 bytes + so zero it.
872 RtlZeroMemory(Common
, ArgumentLength
);
874 Common
->hModule
= hModule
;
875 if (pMenuName
->Length
)
876 RtlCopyMemory(&Common
->MenuName
, pMenuName
->Buffer
, pMenuName
->Length
);
878 RtlCopyMemory(&Common
->MenuName
, &pMenuName
->Buffer
, sizeof(WCHAR
));
880 ResultPointer
= NULL
;
881 ResultLength
= sizeof(LRESULT
);
885 Status
= KeUserModeCallback(USER32_CALLBACK_LOADMENU
,
893 Result
= *(LRESULT
*)ResultPointer
;
895 IntCbFreeMemory(Argument
);
897 if (!NT_SUCCESS(Status
))
902 return (HMENU
)Result
;
907 co_IntClientThreadSetup(VOID
)
910 ULONG ArgumentLength
, ResultLength
;
911 PVOID Argument
, ResultPointer
;
913 /* Do not allow the desktop thread to do callback to user mode */
914 ASSERT(PsGetCurrentThreadWin32Thread() != gptiDesktopThread
);
916 ArgumentLength
= ResultLength
= 0;
917 Argument
= ResultPointer
= NULL
;
921 Status
= KeUserModeCallback(USER32_CALLBACK_CLIENTTHREADSTARTUP
,
933 co_IntCopyImage(HANDLE hnd
, UINT type
, INT desiredx
, INT desiredy
, UINT flags
)
937 ULONG ArgumentLength
, ResultLength
;
938 PVOID Argument
, ResultPointer
;
939 PCOPYIMAGE_CALLBACK_ARGUMENTS Common
;
941 ArgumentLength
= ResultLength
= 0;
942 Argument
= ResultPointer
= NULL
;
944 ArgumentLength
= sizeof(COPYIMAGE_CALLBACK_ARGUMENTS
);
946 Argument
= IntCbAllocateMemory(ArgumentLength
);
947 if (NULL
== Argument
)
949 ERR("CopyImage callback failed: out of memory\n");
952 Common
= (PCOPYIMAGE_CALLBACK_ARGUMENTS
) Argument
;
954 Common
->hImage
= hnd
;
955 Common
->uType
= type
;
956 Common
->cxDesired
= desiredx
;
957 Common
->cyDesired
= desiredy
;
958 Common
->fuFlags
= flags
;
962 Status
= KeUserModeCallback(USER32_CALLBACK_COPYIMAGE
,
971 Handle
= *(HANDLE
*)ResultPointer
;
973 IntCbFreeMemory(Argument
);
975 if (!NT_SUCCESS(Status
))
977 ERR("CopyImage callback failed!\n");
986 co_IntGetCharsetInfo(LCID Locale
, PCHARSETINFO pCs
)
989 ULONG ArgumentLength
, ResultLength
;
990 PVOID Argument
, ResultPointer
;
991 PGET_CHARSET_INFO Common
;
993 ArgumentLength
= sizeof(GET_CHARSET_INFO
);
995 Argument
= IntCbAllocateMemory(ArgumentLength
);
996 if (NULL
== Argument
)
998 ERR("GetCharsetInfo callback failed: out of memory\n");
1001 Common
= (PGET_CHARSET_INFO
) Argument
;
1003 Common
->Locale
= Locale
;
1005 ResultPointer
= NULL
;
1006 ResultLength
= ArgumentLength
;
1010 Status
= KeUserModeCallback(USER32_CALLBACK_GETCHARSETINFO
,
1018 /* Need to copy into our local buffer */
1019 RtlMoveMemory(Argument
, ResultPointer
, ArgumentLength
);
1021 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1023 ERR("Failed to copy result from user mode!\n");
1024 Status
= _SEH2_GetExceptionCode();
1030 RtlCopyMemory(pCs
, &Common
->Cs
, sizeof(CHARSETINFO
));
1032 IntCbFreeMemory(Argument
);
1034 if (!NT_SUCCESS(Status
))
1036 ERR("GetCharsetInfo Failed!!\n");
1044 co_IntSetWndIcons(VOID
)
1047 ULONG ArgumentLength
, ResultLength
;
1048 PVOID Argument
, ResultPointer
;
1049 PSETWNDICONS_CALLBACK_ARGUMENTS Common
;
1051 ResultPointer
= NULL
;
1052 ResultLength
= ArgumentLength
= sizeof(SETWNDICONS_CALLBACK_ARGUMENTS
);
1054 Argument
= IntCbAllocateMemory(ArgumentLength
);
1055 if (NULL
== Argument
)
1057 ERR("Set Window Icons callback failed: out of memory\n");
1060 Common
= (PSETWNDICONS_CALLBACK_ARGUMENTS
) Argument
;
1064 Status
= KeUserModeCallback(USER32_CALLBACK_SETWNDICONS
,
1073 /* FIXME: Need to setup Registry System Cursor & Icons via Callbacks at init time! */
1074 RtlMoveMemory(Common
, ResultPointer
, ArgumentLength
);
1075 gpsi
->hIconSmWindows
= Common
->hIconSmWindows
;
1076 gpsi
->hIconWindows
= Common
->hIconWindows
;
1078 ERR("hIconSmWindows %p hIconWindows %p \n",gpsi
->hIconSmWindows
,gpsi
->hIconWindows
);
1080 IntCbFreeMemory(Argument
);
1082 if (!NT_SUCCESS(Status
))
1084 ERR("Set Window Icons callback failed!\n");