[win32k]
[reactos.git] / reactos / 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;
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;
337 UNICODE_STRING ClassName;
338 PANSI_STRING asWindowName;
339 PANSI_STRING asClassName;
340 PTHREADINFO pti;
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 CbtCreateWnd = (CBT_CREATEWNDW *) lParam;
360 ArgumentLength += sizeof(HOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS);
361
362 asWindowName = (PANSI_STRING)&WindowName;
363 asClassName = (PANSI_STRING)&ClassName;
364
365 if (Ansi)
366 {
367 RtlInitAnsiString(asWindowName, (PCSZ)CbtCreateWnd->lpcs->lpszName);
368 ArgumentLength += WindowName.Length + sizeof(CHAR);
369 }
370 else
371 {
372 RtlInitUnicodeString(&WindowName, CbtCreateWnd->lpcs->lpszName);
373 ArgumentLength += WindowName.Length + sizeof(WCHAR);
374 }
375
376 if (! IS_ATOM(CbtCreateWnd->lpcs->lpszClass))
377 {
378 if (Ansi)
379 {
380 RtlInitAnsiString(asClassName, (PCSZ)CbtCreateWnd->lpcs->lpszClass);
381 ArgumentLength += ClassName.Length + sizeof(CHAR);
382 }
383 else
384 {
385 RtlInitUnicodeString(&ClassName, CbtCreateWnd->lpcs->lpszClass);
386 ArgumentLength += ClassName.Length + sizeof(WCHAR);
387 }
388 }
389 break;
390
391 case HCBT_MOVESIZE:
392 ArgumentLength += sizeof(RECTL);
393 break;
394 case HCBT_ACTIVATE:
395 ArgumentLength += sizeof(CBTACTIVATESTRUCT);
396 break;
397 case HCBT_CLICKSKIPPED:
398 ArgumentLength += sizeof(MOUSEHOOKSTRUCT);
399 break;
400 /* ATM pass on */
401 case HCBT_KEYSKIPPED:
402 case HCBT_MINMAX:
403 case HCBT_SETFOCUS:
404 case HCBT_SYSCOMMAND:
405 /* These types pass through. */
406 case HCBT_DESTROYWND:
407 case HCBT_QS:
408 break;
409 default:
410 DPRINT1("Trying to call unsupported CBT hook %d\n", Code);
411 return 0;
412 }
413 break;
414 case WH_KEYBOARD_LL:
415 ArgumentLength += sizeof(KBDLLHOOKSTRUCT);
416 break;
417 case WH_MOUSE_LL:
418 ArgumentLength += sizeof(MSLLHOOKSTRUCT);
419 break;
420 case WH_MOUSE:
421 ArgumentLength += sizeof(MOUSEHOOKSTRUCT);
422 break;
423 case WH_CALLWNDPROC:
424 ArgumentLength += sizeof(CWPSTRUCT);
425 break;
426 case WH_CALLWNDPROCRET:
427 ArgumentLength += sizeof(CWPRETSTRUCT);
428 break;
429 case WH_MSGFILTER:
430 case WH_SYSMSGFILTER:
431 case WH_GETMESSAGE:
432 ArgumentLength += sizeof(MSG);
433 break;
434 case WH_FOREGROUNDIDLE:
435 case WH_KEYBOARD:
436 case WH_SHELL:
437 break;
438 default:
439 DPRINT1("Trying to call unsupported window hook %d\n", HookId);
440 return 0;
441 }
442
443 Argument = IntCbAllocateMemory(ArgumentLength);
444 if (NULL == Argument)
445 {
446 DPRINT1("HookProc callback failed: out of memory\n");
447 return 0;
448 }
449 Common = (PHOOKPROC_CALLBACK_ARGUMENTS) Argument;
450 Common->HookId = HookId;
451 Common->Code = Code;
452 Common->wParam = wParam;
453 Common->lParam = lParam;
454 Common->Proc = Proc;
455 Common->Ansi = Ansi;
456 Common->ModuleNameLength = ModuleName->Length;
457 memcpy(Common->ModuleName, ModuleName->Buffer, ModuleName->Length);
458 Extra = (PCHAR) Common->ModuleName + Common->ModuleNameLength;
459
460 switch(HookId)
461 {
462 case WH_CBT:
463 switch(Code)
464 {
465 case HCBT_CREATEWND:
466 Common->lParam = (LPARAM) (Extra - (PCHAR) Common);
467 CbtCreatewndExtra = (PHOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS) Extra;
468 RtlCopyMemory( &CbtCreatewndExtra->Cs, CbtCreateWnd->lpcs, sizeof(CREATESTRUCTW) );
469 CbtCreatewndExtra->WndInsertAfter = CbtCreateWnd->hwndInsertAfter;
470 Extra = (PCHAR) (CbtCreatewndExtra + 1);
471 RtlCopyMemory(Extra, WindowName.Buffer, WindowName.Length);
472 CbtCreatewndExtra->Cs.lpszName = (LPCWSTR) (Extra - (PCHAR) CbtCreatewndExtra);
473 CbtCreatewndExtra->Cs.lpszClass = ClassName.Buffer;
474 Extra += WindowName.Length;
475 if (Ansi)
476 {
477 *((CHAR *) Extra) = '\0';
478 Extra += sizeof(CHAR);
479 }
480 else
481 {
482 *((WCHAR *) Extra) = L'\0';
483 Extra += sizeof(WCHAR);
484 }
485
486 if (! IS_ATOM(ClassName.Buffer))
487 {
488 RtlCopyMemory(Extra, ClassName.Buffer, ClassName.Length);
489 CbtCreatewndExtra->Cs.lpszClass =
490 (LPCWSTR)(ULONG_PTR) MAKELONG(Extra - (PCHAR) CbtCreatewndExtra, 1);
491 Extra += ClassName.Length;
492
493 if (Ansi)
494 *((CHAR *) Extra) = '\0';
495 else
496 *((WCHAR *) Extra) = L'\0';
497 }
498 break;
499 case HCBT_CLICKSKIPPED:
500 RtlCopyMemory(Extra, (PVOID) lParam, sizeof(MOUSEHOOKSTRUCT));
501 Common->lParam = (LPARAM) (Extra - (PCHAR) Common);
502 break;
503 case HCBT_MOVESIZE:
504 RtlCopyMemory(Extra, (PVOID) lParam, sizeof(RECTL));
505 Common->lParam = (LPARAM) (Extra - (PCHAR) Common);
506 break;
507 case HCBT_ACTIVATE:
508 RtlCopyMemory(Extra, (PVOID) lParam, sizeof(CBTACTIVATESTRUCT));
509 Common->lParam = (LPARAM) (Extra - (PCHAR) Common);
510 break;
511 }
512 break;
513 case WH_KEYBOARD_LL:
514 RtlCopyMemory(Extra, (PVOID) lParam, sizeof(KBDLLHOOKSTRUCT));
515 Common->lParam = (LPARAM) (Extra - (PCHAR) Common);
516 break;
517 case WH_MOUSE_LL:
518 RtlCopyMemory(Extra, (PVOID) lParam, sizeof(MSLLHOOKSTRUCT));
519 Common->lParam = (LPARAM) (Extra - (PCHAR) Common);
520 break;
521 case WH_MOUSE:
522 RtlCopyMemory(Extra, (PVOID) lParam, sizeof(MOUSEHOOKSTRUCT));
523 Common->lParam = (LPARAM) (Extra - (PCHAR) Common);
524 break;
525 case WH_CALLWNDPROC:
526 RtlCopyMemory(Extra, (PVOID) lParam, sizeof(CWPSTRUCT));
527 Common->lParam = (LPARAM) (Extra - (PCHAR) Common);
528 break;
529 case WH_CALLWNDPROCRET:
530 RtlCopyMemory(Extra, (PVOID) lParam, sizeof(CWPRETSTRUCT));
531 Common->lParam = (LPARAM) (Extra - (PCHAR) Common);
532 break;
533 case WH_MSGFILTER:
534 case WH_SYSMSGFILTER:
535 case WH_GETMESSAGE:
536 RtlCopyMemory(Extra, (PVOID) lParam, sizeof(MSG));
537 Common->lParam = (LPARAM) (Extra - (PCHAR) Common);
538 // DPRINT1("KHOOK Memory: %x\n",Common);
539 break;
540 case WH_FOREGROUNDIDLE:
541 case WH_KEYBOARD:
542 case WH_SHELL:
543 break;
544 }
545
546 ResultPointer = NULL;
547 ResultLength = sizeof(LRESULT);
548
549 UserLeaveCo();
550
551 Status = KeUserModeCallback(USER32_CALLBACK_HOOKPROC,
552 Argument,
553 ArgumentLength,
554 &ResultPointer,
555 &ResultLength);
556
557 UserEnterCo();
558
559 _SEH2_TRY
560 {
561 ProbeForRead(ResultPointer, sizeof(LRESULT), 1);
562 /* Simulate old behaviour: copy into our local buffer */
563 Result = *(LRESULT*)ResultPointer;
564 }
565 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
566 {
567 Result = 0;
568 }
569 _SEH2_END;
570
571 if (!NT_SUCCESS(Status))
572 {
573 return 0;
574 }
575
576 if (HookId == WH_CBT && Code == HCBT_CREATEWND)
577 {
578 if (CbtCreatewndExtra)
579 {
580 _SEH2_TRY
581 { /*
582 The parameters could have been changed, include the coordinates
583 and dimensions of the window. We copy it back.
584 */
585 CbtCreateWnd->hwndInsertAfter = CbtCreatewndExtra->WndInsertAfter;
586 CbtCreateWnd->lpcs->x = CbtCreatewndExtra->Cs.x;
587 CbtCreateWnd->lpcs->y = CbtCreatewndExtra->Cs.y;
588 CbtCreateWnd->lpcs->cx = CbtCreatewndExtra->Cs.cx;
589 CbtCreateWnd->lpcs->cy = CbtCreatewndExtra->Cs.cy;
590 }
591 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
592 {
593 Result = 0;
594 }
595 _SEH2_END;
596 }
597 }
598
599 if (Argument) IntCbFreeMemory(Argument);
600
601 return Result;
602 }
603
604 //
605 // Events are notifications w/o results.
606 //
607 LRESULT
608 APIENTRY
609 co_IntCallEventProc(HWINEVENTHOOK hook,
610 DWORD event,
611 HWND hWnd,
612 LONG idObject,
613 LONG idChild,
614 DWORD dwEventThread,
615 DWORD dwmsEventTime,
616 WINEVENTPROC Proc)
617 {
618 LRESULT Result = 0;
619 NTSTATUS Status;
620 PEVENTPROC_CALLBACK_ARGUMENTS Common;
621 ULONG ArgumentLength, ResultLength;
622 PVOID Argument, ResultPointer;
623
624 ArgumentLength = sizeof(EVENTPROC_CALLBACK_ARGUMENTS);
625
626 Argument = IntCbAllocateMemory(ArgumentLength);
627 if (NULL == Argument)
628 {
629 DPRINT1("EventProc callback failed: out of memory\n");
630 return 0;
631 }
632 Common = (PEVENTPROC_CALLBACK_ARGUMENTS) Argument;
633 Common->hook = hook;
634 Common->event = event;
635 Common->hwnd = hWnd;
636 Common->idObject = idObject;
637 Common->idChild = idChild;
638 Common->dwEventThread = dwEventThread;
639 Common->dwmsEventTime = dwmsEventTime;
640 Common->Proc = Proc;
641
642 ResultPointer = NULL;
643 ResultLength = sizeof(LRESULT);
644
645 UserLeaveCo();
646
647 Status = KeUserModeCallback(USER32_CALLBACK_EVENTPROC,
648 Argument,
649 ArgumentLength,
650 &ResultPointer,
651 &ResultLength);
652
653 UserEnterCo();
654
655 IntCbFreeMemory(Argument);
656
657 if (!NT_SUCCESS(Status))
658 {
659 return 0;
660 }
661
662 return Result;
663 }
664
665 //
666 // Callback Load Menu and results.
667 //
668 HMENU
669 APIENTRY
670 co_IntCallLoadMenu( HINSTANCE hModule,
671 PUNICODE_STRING pMenuName )
672 {
673 LRESULT Result = 0;
674 NTSTATUS Status;
675 PLOADMENU_CALLBACK_ARGUMENTS Common;
676 ULONG ArgumentLength, ResultLength;
677 PVOID Argument, ResultPointer;
678
679 ArgumentLength = sizeof(LOADMENU_CALLBACK_ARGUMENTS);
680
681 ArgumentLength += pMenuName->Length + sizeof(WCHAR);
682
683 Argument = IntCbAllocateMemory(ArgumentLength);
684 if (NULL == Argument)
685 {
686 DPRINT1("LoadMenu callback failed: out of memory\n");
687 return 0;
688 }
689 Common = (PLOADMENU_CALLBACK_ARGUMENTS) Argument;
690
691 // Help Intersource check and MenuName is now 4 bytes + so zero it.
692 RtlZeroMemory(Common, ArgumentLength);
693
694 Common->hModule = hModule;
695 if (pMenuName->Length)
696 RtlCopyMemory(&Common->MenuName, pMenuName->Buffer, pMenuName->Length);
697 else
698 RtlCopyMemory(&Common->MenuName, &pMenuName->Buffer, sizeof(WCHAR));
699
700 ResultPointer = NULL;
701 ResultLength = sizeof(LRESULT);
702
703 UserLeaveCo();
704
705 Status = KeUserModeCallback(USER32_CALLBACK_LOADMENU,
706 Argument,
707 ArgumentLength,
708 &ResultPointer,
709 &ResultLength);
710
711 UserEnterCo();
712
713 Result = *(LRESULT*)ResultPointer;
714
715 IntCbFreeMemory(Argument);
716
717 if (!NT_SUCCESS(Status))
718 {
719 return 0;
720 }
721
722 return (HMENU)Result;
723 }
724
725 NTSTATUS
726 APIENTRY
727 co_IntClientThreadSetup(VOID)
728 {
729 NTSTATUS Status;
730 ULONG ArgumentLength, ResultLength;
731 PVOID Argument, ResultPointer;
732
733 ArgumentLength = ResultLength = 0;
734 Argument = ResultPointer = NULL;
735
736 UserLeaveCo();
737
738 Status = KeUserModeCallback(USER32_CALLBACK_CLIENTTHREADSTARTUP,
739 Argument,
740 ArgumentLength,
741 &ResultPointer,
742 &ResultLength);
743
744 UserEnterCo();
745
746 return Status;
747 }
748
749
750 /* EOF */