997cd4fb8b522b834ffd39d8f266bcfcd67ee8b6
[reactos.git] / subsystems / win32 / win32k / ntuser / callback.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * PURPOSE: Window classes
5 * FILE: subsys/win32k/ntuser/wndproc.c
6 * PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
7 * Thomas Weidenmueller (w3seek@users.sourceforge.net)
8 * REVISION HISTORY:
9 * 06-06-2001 CSH Created
10 * NOTES: Please use the Callback Memory Management functions for
11 * callbacks to make sure, the memory is freed on thread
12 * termination!
13 */
14
15 /* INCLUDES ******************************************************************/
16
17 #include <win32k.h>
18
19 #define NDEBUG
20 #include <debug.h>
21
22 /* CALLBACK MEMORY MANAGEMENT ************************************************/
23
24 typedef struct _INT_CALLBACK_HEADER
25 {
26 /* list entry in the THREADINFO structure */
27 LIST_ENTRY ListEntry;
28 }
29 INT_CALLBACK_HEADER, *PINT_CALLBACK_HEADER;
30
31 PVOID FASTCALL
32 IntCbAllocateMemory(ULONG Size)
33 {
34 PINT_CALLBACK_HEADER Mem;
35 PTHREADINFO W32Thread;
36
37 if(!(Mem = ExAllocatePoolWithTag(PagedPool, Size + sizeof(INT_CALLBACK_HEADER),
38 TAG_CALLBACK)))
39 {
40 return NULL;
41 }
42
43 W32Thread = PsGetCurrentThreadWin32Thread();
44 ASSERT(W32Thread);
45
46 /* insert the callback memory into the thread's callback list */
47
48 InsertTailList(&W32Thread->W32CallbackListHead, &Mem->ListEntry);
49
50 return (Mem + 1);
51 }
52
53 VOID FASTCALL
54 IntCbFreeMemory(PVOID Data)
55 {
56 PINT_CALLBACK_HEADER Mem;
57 PTHREADINFO W32Thread;
58
59 ASSERT(Data);
60
61 Mem = ((PINT_CALLBACK_HEADER)Data - 1);
62
63 W32Thread = PsGetCurrentThreadWin32Thread();
64 ASSERT(W32Thread);
65
66 /* remove the memory block from the thread's callback list */
67 RemoveEntryList(&Mem->ListEntry);
68
69 /* free memory */
70 ExFreePoolWithTag(Mem, TAG_CALLBACK);
71 }
72
73 VOID FASTCALL
74 IntCleanupThreadCallbacks(PTHREADINFO W32Thread)
75 {
76 PLIST_ENTRY CurrentEntry;
77 PINT_CALLBACK_HEADER Mem;
78
79 while (!IsListEmpty(&W32Thread->W32CallbackListHead))
80 {
81 CurrentEntry = RemoveHeadList(&W32Thread->W32CallbackListHead);
82 Mem = CONTAINING_RECORD(CurrentEntry, INT_CALLBACK_HEADER,
83 ListEntry);
84
85 /* free memory */
86 ExFreePool(Mem);
87 }
88 }
89
90
91 //
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.
94 //
95 static VOID
96 IntSetTebWndCallback (HWND * hWnd, PWND * pWnd)
97 {
98 HWND hWndS = *hWnd;
99 PWND Window = UserGetWindowObject(*hWnd);
100 PCLIENTINFO ClientInfo = GetWin32ClientInfo();
101
102 *hWnd = ClientInfo->CallbackWnd.hWnd;
103 *pWnd = ClientInfo->CallbackWnd.pWnd;
104
105 ClientInfo->CallbackWnd.hWnd = hWndS;
106 ClientInfo->CallbackWnd.pWnd = DesktopHeapAddressToUser(Window);
107 }
108
109 static VOID
110 IntRestoreTebWndCallback (HWND hWnd, PWND pWnd)
111 {
112 PCLIENTINFO ClientInfo = GetWin32ClientInfo();
113
114 ClientInfo->CallbackWnd.hWnd = hWnd;
115 ClientInfo->CallbackWnd.pWnd = pWnd;
116 }
117
118 /* FUNCTIONS *****************************************************************/
119
120 VOID APIENTRY
121 co_IntCallSentMessageCallback(SENDASYNCPROC CompletionCallback,
122 HWND hWnd,
123 UINT Msg,
124 ULONG_PTR CompletionCallbackContext,
125 LRESULT Result)
126 {
127 SENDASYNCPROC_CALLBACK_ARGUMENTS Arguments;
128 PVOID ResultPointer;
129 PWND pWnd;
130 ULONG ResultLength;
131 NTSTATUS Status;
132
133 Arguments.Callback = CompletionCallback;
134 Arguments.Wnd = hWnd;
135 Arguments.Msg = Msg;
136 Arguments.Context = CompletionCallbackContext;
137 Arguments.Result = Result;
138
139 IntSetTebWndCallback (&hWnd, &pWnd);
140
141 UserLeaveCo();
142
143 Status = KeUserModeCallback(USER32_CALLBACK_SENDASYNCPROC,
144 &Arguments,
145 sizeof(SENDASYNCPROC_CALLBACK_ARGUMENTS),
146 &ResultPointer,
147 &ResultLength);
148
149 UserEnterCo();
150
151 IntRestoreTebWndCallback (hWnd, pWnd);
152
153 if (!NT_SUCCESS(Status))
154 {
155 return;
156 }
157 return;
158 }
159
160 LRESULT APIENTRY
161 co_IntCallWindowProc(WNDPROC Proc,
162 BOOLEAN IsAnsiProc,
163 HWND Wnd,
164 UINT Message,
165 WPARAM wParam,
166 LPARAM lParam,
167 INT lParamBufferSize)
168 {
169 WINDOWPROC_CALLBACK_ARGUMENTS StackArguments;
170 PWINDOWPROC_CALLBACK_ARGUMENTS Arguments;
171 NTSTATUS Status;
172 PVOID ResultPointer;
173 PWND pWnd;
174 ULONG ResultLength;
175 ULONG ArgumentLength;
176 LRESULT Result;
177
178 if (0 < lParamBufferSize)
179 {
180 ArgumentLength = sizeof(WINDOWPROC_CALLBACK_ARGUMENTS) + lParamBufferSize;
181 Arguments = IntCbAllocateMemory(ArgumentLength);
182 if (NULL == Arguments)
183 {
184 DPRINT1("Unable to allocate buffer for window proc callback\n");
185 return -1;
186 }
187 RtlMoveMemory((PVOID) ((char *) Arguments + sizeof(WINDOWPROC_CALLBACK_ARGUMENTS)),
188 (PVOID) lParam, lParamBufferSize);
189 }
190 else
191 {
192 Arguments = &StackArguments;
193 ArgumentLength = sizeof(WINDOWPROC_CALLBACK_ARGUMENTS);
194 }
195 Arguments->Proc = Proc;
196 Arguments->IsAnsiProc = IsAnsiProc;
197 Arguments->Wnd = Wnd;
198 Arguments->Msg = Message;
199 Arguments->wParam = wParam;
200 Arguments->lParam = lParam;
201 Arguments->lParamBufferSize = lParamBufferSize;
202 ResultPointer = NULL;
203 ResultLength = ArgumentLength;
204
205 IntSetTebWndCallback (&Wnd, &pWnd);
206
207 UserLeaveCo();
208
209 Status = KeUserModeCallback(USER32_CALLBACK_WINDOWPROC,
210 Arguments,
211 ArgumentLength,
212 &ResultPointer,
213 &ResultLength);
214
215 _SEH2_TRY
216 {
217 /* Simulate old behaviour: copy into our local buffer */
218 RtlMoveMemory(Arguments, ResultPointer, ArgumentLength);
219 }
220 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
221 {
222 Status = _SEH2_GetExceptionCode();
223 }
224 _SEH2_END;
225
226 UserEnterCo();
227
228 IntRestoreTebWndCallback (Wnd, pWnd);
229
230 if (!NT_SUCCESS(Status))
231 {
232 if (0 < lParamBufferSize)
233 {
234 IntCbFreeMemory(Arguments);
235 }
236 return -1;
237 }
238 Result = Arguments->Result;
239
240 if (0 < lParamBufferSize)
241 {
242 RtlMoveMemory((PVOID) lParam,
243 (PVOID) ((char *) Arguments + sizeof(WINDOWPROC_CALLBACK_ARGUMENTS)),
244 lParamBufferSize);
245 IntCbFreeMemory(Arguments);
246 }
247
248 return Result;
249 }
250
251 HMENU APIENTRY
252 co_IntLoadSysMenuTemplate()
253 {
254 LRESULT Result = 0;
255 NTSTATUS Status;
256 PVOID ResultPointer;
257 ULONG ResultLength;
258
259 ResultPointer = NULL;
260 ResultLength = sizeof(LRESULT);
261
262 UserLeaveCo();
263
264 Status = KeUserModeCallback(USER32_CALLBACK_LOADSYSMENUTEMPLATE,
265 NULL,
266 0,
267 &ResultPointer,
268 &ResultLength);
269 if (NT_SUCCESS(Status))
270 {
271 /* Simulate old behaviour: copy into our local buffer */
272 _SEH2_TRY
273 {
274 ProbeForRead(ResultPointer, sizeof(LRESULT), 1);
275 Result = *(LRESULT*)ResultPointer;
276 }
277 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
278 {
279 Result = 0;
280 }
281 _SEH2_END
282 }
283
284 UserEnterCo();
285
286 return (HMENU)Result;
287 }
288
289 BOOL APIENTRY
290 co_IntLoadDefaultCursors(VOID)
291 {
292 NTSTATUS Status;
293 PVOID ResultPointer;
294 ULONG ResultLength;
295 BOOL DefaultCursor = TRUE;
296
297 ResultPointer = NULL;
298 ResultLength = sizeof(LRESULT);
299
300 UserLeaveCo();
301
302 Status = KeUserModeCallback(USER32_CALLBACK_LOADDEFAULTCURSORS,
303 &DefaultCursor,
304 sizeof(BOOL),
305 &ResultPointer,
306 &ResultLength);
307
308 UserEnterCo();
309
310 if (!NT_SUCCESS(Status))
311 {
312 return FALSE;
313 }
314 return TRUE;
315 }
316
317 LRESULT APIENTRY
318 co_IntCallHookProc(INT HookId,
319 INT Code,
320 WPARAM wParam,
321 LPARAM lParam,
322 HOOKPROC Proc,
323 BOOLEAN Ansi,
324 PUNICODE_STRING ModuleName)
325 {
326 ULONG ArgumentLength;
327 PVOID Argument = NULL;
328 LRESULT Result = 0;
329 NTSTATUS Status;
330 PVOID ResultPointer;
331 ULONG ResultLength;
332 PHOOKPROC_CALLBACK_ARGUMENTS Common;
333 CBT_CREATEWNDW *CbtCreateWnd = NULL;
334 PCHAR Extra;
335 PHOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS CbtCreatewndExtra = NULL;
336 UNICODE_STRING WindowName, ClassName;
337 ANSI_STRING asWindowName, asClassName;
338 PTHREADINFO pti;
339 PWND pWnd;
340 BOOL Hit = FALSE;
341
342 ASSERT(Proc);
343
344 pti = PsGetCurrentThreadWin32Thread();
345 if (pti->TIF_flags & TIF_INCLEANUP)
346 {
347 DPRINT1("Thread is in cleanup and trying to call hook %d\n", Code);
348 return 0;
349 }
350
351 ArgumentLength = sizeof(HOOKPROC_CALLBACK_ARGUMENTS) - sizeof(WCHAR)
352 + ModuleName->Length;
353 switch(HookId)
354 {
355 case WH_CBT:
356 switch(Code)
357 {
358 case HCBT_CREATEWND:
359 pWnd = UserGetWindowObject((HWND) wParam);
360 if (!pWnd)
361 {
362 DPRINT1("WH_CBT HCBT_CREATEWND wParam bad hWnd!\n");
363 goto Fault_Exit;
364 }
365
366 CbtCreateWnd = (CBT_CREATEWNDW *) lParam;
367 ArgumentLength += sizeof(HOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS);
368
369 if (Ansi)
370 {
371 RtlInitAnsiString(&asWindowName, NULL);
372 _SEH2_TRY
373 {
374 ProbeForRead(CbtCreateWnd->lpcs->lpszName, sizeof(CHAR), 1);
375 }
376 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
377 {
378 Hit = TRUE;
379 }
380 _SEH2_END;
381 if (Hit) // Client is at deaths door.
382 goto Fault_Exit;
383 if (CbtCreateWnd->lpcs->lpszName)
384 RtlInitAnsiString(&asWindowName, (PCSZ)CbtCreateWnd->lpcs->lpszName);
385 ArgumentLength += asWindowName.Length + sizeof(CHAR);
386 }
387 else
388 {
389 RtlInitUnicodeString(&WindowName, NULL);
390 _SEH2_TRY
391 {
392 ProbeForRead(CbtCreateWnd->lpcs->lpszName, sizeof(WCHAR), 1);
393 }
394 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
395 {
396 Hit = TRUE;
397 }
398 _SEH2_END;
399 if (Hit)
400 goto Fault_Exit;
401 if (CbtCreateWnd->lpcs->lpszName)
402 RtlInitUnicodeString(&WindowName, CbtCreateWnd->lpcs->lpszName);
403 ArgumentLength += WindowName.Length + sizeof(WCHAR);
404 }
405
406 if (!IS_ATOM(CbtCreateWnd->lpcs->lpszClass))
407 {
408 if (Ansi)
409 {
410 RtlInitAnsiString(&asClassName, NULL);
411 if (CbtCreateWnd->lpcs->lpszClass)
412 RtlInitAnsiString(&asClassName, (PCSZ)CbtCreateWnd->lpcs->lpszClass);
413 ArgumentLength += asClassName.Length + sizeof(CHAR);
414 }
415 else
416 {
417 RtlInitUnicodeString(&ClassName, NULL);
418 if (CbtCreateWnd->lpcs->lpszClass)
419 RtlInitUnicodeString(&ClassName, CbtCreateWnd->lpcs->lpszClass);
420 ArgumentLength += ClassName.Length + sizeof(WCHAR);
421 }
422 }
423 break;
424
425 case HCBT_MOVESIZE:
426 ArgumentLength += sizeof(RECTL);
427 break;
428 case HCBT_ACTIVATE:
429 ArgumentLength += sizeof(CBTACTIVATESTRUCT);
430 break;
431 case HCBT_CLICKSKIPPED:
432 ArgumentLength += sizeof(MOUSEHOOKSTRUCT);
433 break;
434 /* ATM pass on */
435 case HCBT_KEYSKIPPED:
436 case HCBT_MINMAX:
437 case HCBT_SETFOCUS:
438 case HCBT_SYSCOMMAND:
439 /* These types pass through. */
440 case HCBT_DESTROYWND:
441 case HCBT_QS:
442 break;
443 default:
444 DPRINT1("Trying to call unsupported CBT hook %d\n", Code);
445 goto Fault_Exit;
446 }
447 break;
448 case WH_KEYBOARD_LL:
449 ArgumentLength += sizeof(KBDLLHOOKSTRUCT);
450 break;
451 case WH_MOUSE_LL:
452 ArgumentLength += sizeof(MSLLHOOKSTRUCT);
453 break;
454 case WH_MOUSE:
455 ArgumentLength += sizeof(MOUSEHOOKSTRUCT);
456 break;
457 case WH_CALLWNDPROC:
458 ArgumentLength += sizeof(CWPSTRUCT);
459 break;
460 case WH_CALLWNDPROCRET:
461 ArgumentLength += sizeof(CWPRETSTRUCT);
462 break;
463 case WH_MSGFILTER:
464 case WH_SYSMSGFILTER:
465 case WH_GETMESSAGE:
466 ArgumentLength += sizeof(MSG);
467 break;
468 case WH_FOREGROUNDIDLE:
469 case WH_KEYBOARD:
470 case WH_SHELL:
471 break;
472 default:
473 DPRINT1("Trying to call unsupported window hook %d\n", HookId);
474 goto Fault_Exit;
475 }
476
477 Argument = IntCbAllocateMemory(ArgumentLength);
478 if (NULL == Argument)
479 {
480 DPRINT1("HookProc callback failed: out of memory\n");
481 goto Fault_Exit;
482 }
483 Common = (PHOOKPROC_CALLBACK_ARGUMENTS) Argument;
484 Common->HookId = HookId;
485 Common->Code = Code;
486 Common->wParam = wParam;
487 Common->lParam = lParam;
488 Common->Proc = Proc;
489 Common->Ansi = Ansi;
490 Common->ModuleNameLength = ModuleName->Length;
491 if (ModuleName->Buffer)
492 RtlCopyMemory(Common->ModuleName, ModuleName->Buffer, ModuleName->Length);
493 Extra = (PCHAR) Common->ModuleName + Common->ModuleNameLength;
494
495 switch(HookId)
496 {
497 case WH_CBT:
498 switch(Code)
499 {
500 case HCBT_CREATEWND:
501 Common->lParam = (LPARAM) (Extra - (PCHAR) Common);
502 CbtCreatewndExtra = (PHOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS) Extra;
503 RtlCopyMemory( &CbtCreatewndExtra->Cs, CbtCreateWnd->lpcs, sizeof(CREATESTRUCTW) );
504 CbtCreatewndExtra->WndInsertAfter = CbtCreateWnd->hwndInsertAfter;
505 Extra = (PCHAR) (CbtCreatewndExtra + 1);
506 CbtCreatewndExtra->Cs.lpszClass = ClassName.Buffer; // if Atom
507
508 if (Ansi)
509 {
510 if (asWindowName.Buffer)
511 RtlCopyMemory(Extra, asWindowName.Buffer, asWindowName.Length);
512 CbtCreatewndExtra->Cs.lpszName = (LPCWSTR) (Extra - (PCHAR) CbtCreatewndExtra);
513 Extra += asWindowName.Length;
514
515 *((CHAR *) Extra) = '\0';
516 Extra += sizeof(CHAR);
517 }
518 else
519 {
520 if (asWindowName.Buffer)
521 RtlCopyMemory(Extra, WindowName.Buffer, WindowName.Length);
522 CbtCreatewndExtra->Cs.lpszName = (LPCWSTR) (Extra - (PCHAR) CbtCreatewndExtra);
523 Extra += WindowName.Length;
524
525 *((WCHAR *) Extra) = L'\0';
526 Extra += sizeof(WCHAR);
527 }
528
529 if (!IS_ATOM(ClassName.Buffer))
530 {
531 if (Ansi)
532 {
533 if (asClassName.Buffer)
534 RtlCopyMemory(Extra, asClassName.Buffer, asClassName.Length);
535 CbtCreatewndExtra->Cs.lpszClass =
536 (LPCWSTR)(ULONG_PTR) MAKELONG(Extra - (PCHAR) CbtCreatewndExtra, 1);
537 Extra += asClassName.Length;
538
539 *((CHAR *) Extra) = '\0';
540 Extra += sizeof(CHAR);
541 }
542 else
543 {
544 if (ClassName.Buffer)
545 RtlCopyMemory(Extra, ClassName.Buffer, ClassName.Length);
546 CbtCreatewndExtra->Cs.lpszClass =
547 (LPCWSTR)(ULONG_PTR) MAKELONG(Extra - (PCHAR) CbtCreatewndExtra, 1);
548 Extra += ClassName.Length;
549
550 *((WCHAR *) Extra) = L'\0';
551 Extra += sizeof(WCHAR);
552 }
553 }
554 break;
555 case HCBT_CLICKSKIPPED:
556 RtlCopyMemory(Extra, (PVOID) lParam, sizeof(MOUSEHOOKSTRUCT));
557 Common->lParam = (LPARAM) (Extra - (PCHAR) Common);
558 break;
559 case HCBT_MOVESIZE:
560 RtlCopyMemory(Extra, (PVOID) lParam, sizeof(RECTL));
561 Common->lParam = (LPARAM) (Extra - (PCHAR) Common);
562 break;
563 case HCBT_ACTIVATE:
564 RtlCopyMemory(Extra, (PVOID) lParam, sizeof(CBTACTIVATESTRUCT));
565 Common->lParam = (LPARAM) (Extra - (PCHAR) Common);
566 break;
567 }
568 break;
569 case WH_KEYBOARD_LL:
570 RtlCopyMemory(Extra, (PVOID) lParam, sizeof(KBDLLHOOKSTRUCT));
571 Common->lParam = (LPARAM) (Extra - (PCHAR) Common);
572 break;
573 case WH_MOUSE_LL:
574 RtlCopyMemory(Extra, (PVOID) lParam, sizeof(MSLLHOOKSTRUCT));
575 Common->lParam = (LPARAM) (Extra - (PCHAR) Common);
576 break;
577 case WH_MOUSE:
578 RtlCopyMemory(Extra, (PVOID) lParam, sizeof(MOUSEHOOKSTRUCT));
579 Common->lParam = (LPARAM) (Extra - (PCHAR) Common);
580 break;
581 case WH_CALLWNDPROC:
582 RtlCopyMemory(Extra, (PVOID) lParam, sizeof(CWPSTRUCT));
583 Common->lParam = (LPARAM) (Extra - (PCHAR) Common);
584 break;
585 case WH_CALLWNDPROCRET:
586 RtlCopyMemory(Extra, (PVOID) lParam, sizeof(CWPRETSTRUCT));
587 Common->lParam = (LPARAM) (Extra - (PCHAR) Common);
588 break;
589 case WH_MSGFILTER:
590 case WH_SYSMSGFILTER:
591 case WH_GETMESSAGE:
592 RtlCopyMemory(Extra, (PVOID) lParam, sizeof(MSG));
593 Common->lParam = (LPARAM) (Extra - (PCHAR) Common);
594 break;
595 case WH_FOREGROUNDIDLE:
596 case WH_KEYBOARD:
597 case WH_SHELL:
598 break;
599 }
600
601 ResultPointer = NULL;
602 ResultLength = sizeof(LRESULT);
603
604 UserLeaveCo();
605
606 Status = KeUserModeCallback(USER32_CALLBACK_HOOKPROC,
607 Argument,
608 ArgumentLength,
609 &ResultPointer,
610 &ResultLength);
611
612 UserEnterCo();
613
614 _SEH2_TRY
615 {
616 ProbeForRead(ResultPointer, sizeof(LRESULT), 1);
617 /* Simulate old behaviour: copy into our local buffer */
618 Result = *(LRESULT*)ResultPointer;
619 }
620 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
621 {
622 Result = 0;
623 Hit = TRUE;
624 }
625 _SEH2_END;
626
627 if (!NT_SUCCESS(Status))
628 {
629 goto Fault_Exit;
630 }
631 /* Support write backs... SEH is in UserCallNextHookEx. */
632 switch (HookId)
633 {
634 case WH_CBT:
635 if (Code == HCBT_CREATEWND)
636 {
637 if (CbtCreatewndExtra)
638 {/*
639 The parameters could have been changed, include the coordinates
640 and dimensions of the window. We copy it back.
641 */
642 CbtCreateWnd->hwndInsertAfter = CbtCreatewndExtra->WndInsertAfter;
643 CbtCreateWnd->lpcs->x = CbtCreatewndExtra->Cs.x;
644 CbtCreateWnd->lpcs->y = CbtCreatewndExtra->Cs.y;
645 CbtCreateWnd->lpcs->cx = CbtCreatewndExtra->Cs.cx;
646 CbtCreateWnd->lpcs->cy = CbtCreatewndExtra->Cs.cy;
647 }
648 }
649 break;
650 // "The GetMsgProc hook procedure can examine or modify the message."
651 case WH_GETMESSAGE:
652 if (lParam)
653 {
654 RtlCopyMemory((PVOID) lParam, Extra, sizeof(MSG));
655 }
656 break;
657 }
658
659 Fault_Exit:
660 if (Hit)
661 {
662 DPRINT1("Exception CallHookProc HookId %d Code %d\n",HookId,Code);
663 }
664 if (Argument) IntCbFreeMemory(Argument);
665
666 return Result;
667 }
668
669 //
670 // Events are notifications w/o results.
671 //
672 LRESULT
673 APIENTRY
674 co_IntCallEventProc(HWINEVENTHOOK hook,
675 DWORD event,
676 HWND hWnd,
677 LONG idObject,
678 LONG idChild,
679 DWORD dwEventThread,
680 DWORD dwmsEventTime,
681 WINEVENTPROC Proc)
682 {
683 LRESULT Result = 0;
684 NTSTATUS Status;
685 PEVENTPROC_CALLBACK_ARGUMENTS Common;
686 ULONG ArgumentLength, ResultLength;
687 PVOID Argument, ResultPointer;
688
689 ArgumentLength = sizeof(EVENTPROC_CALLBACK_ARGUMENTS);
690
691 Argument = IntCbAllocateMemory(ArgumentLength);
692 if (NULL == Argument)
693 {
694 DPRINT1("EventProc callback failed: out of memory\n");
695 return 0;
696 }
697 Common = (PEVENTPROC_CALLBACK_ARGUMENTS) Argument;
698 Common->hook = hook;
699 Common->event = event;
700 Common->hwnd = hWnd;
701 Common->idObject = idObject;
702 Common->idChild = idChild;
703 Common->dwEventThread = dwEventThread;
704 Common->dwmsEventTime = dwmsEventTime;
705 Common->Proc = Proc;
706
707 ResultPointer = NULL;
708 ResultLength = sizeof(LRESULT);
709
710 UserLeaveCo();
711
712 Status = KeUserModeCallback(USER32_CALLBACK_EVENTPROC,
713 Argument,
714 ArgumentLength,
715 &ResultPointer,
716 &ResultLength);
717
718 UserEnterCo();
719
720 IntCbFreeMemory(Argument);
721
722 if (!NT_SUCCESS(Status))
723 {
724 return 0;
725 }
726
727 return Result;
728 }
729
730 //
731 // Callback Load Menu and results.
732 //
733 HMENU
734 APIENTRY
735 co_IntCallLoadMenu( HINSTANCE hModule,
736 PUNICODE_STRING pMenuName )
737 {
738 LRESULT Result = 0;
739 NTSTATUS Status;
740 PLOADMENU_CALLBACK_ARGUMENTS Common;
741 ULONG ArgumentLength, ResultLength;
742 PVOID Argument, ResultPointer;
743
744 ArgumentLength = sizeof(LOADMENU_CALLBACK_ARGUMENTS);
745
746 ArgumentLength += pMenuName->Length + sizeof(WCHAR);
747
748 Argument = IntCbAllocateMemory(ArgumentLength);
749 if (NULL == Argument)
750 {
751 DPRINT1("LoadMenu callback failed: out of memory\n");
752 return 0;
753 }
754 Common = (PLOADMENU_CALLBACK_ARGUMENTS) Argument;
755
756 // Help Intersource check and MenuName is now 4 bytes + so zero it.
757 RtlZeroMemory(Common, ArgumentLength);
758
759 Common->hModule = hModule;
760 if (pMenuName->Length)
761 RtlCopyMemory(&Common->MenuName, pMenuName->Buffer, pMenuName->Length);
762 else
763 RtlCopyMemory(&Common->MenuName, &pMenuName->Buffer, sizeof(WCHAR));
764
765 ResultPointer = NULL;
766 ResultLength = sizeof(LRESULT);
767
768 UserLeaveCo();
769
770 Status = KeUserModeCallback(USER32_CALLBACK_LOADMENU,
771 Argument,
772 ArgumentLength,
773 &ResultPointer,
774 &ResultLength);
775
776 UserEnterCo();
777
778 Result = *(LRESULT*)ResultPointer;
779
780 IntCbFreeMemory(Argument);
781
782 if (!NT_SUCCESS(Status))
783 {
784 return 0;
785 }
786
787 return (HMENU)Result;
788 }
789
790 NTSTATUS
791 APIENTRY
792 co_IntClientThreadSetup(VOID)
793 {
794 NTSTATUS Status;
795 ULONG ArgumentLength, ResultLength;
796 PVOID Argument, ResultPointer;
797
798 ArgumentLength = ResultLength = 0;
799 Argument = ResultPointer = NULL;
800
801 UserLeaveCo();
802
803 Status = KeUserModeCallback(USER32_CALLBACK_CLIENTTHREADSTARTUP,
804 Argument,
805 ArgumentLength,
806 &ResultPointer,
807 &ResultLength);
808
809 UserEnterCo();
810
811 return Status;
812 }
813
814
815 /* EOF */