2 * ReactOS W32 Subsystem
3 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 * COPYRIGHT: See COPYING in the top level directory
22 * PROJECT: ReactOS kernel
23 * PURPOSE: Window classes
24 * FILE: subsys/win32k/ntuser/wndproc.c
25 * PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
26 * Thomas Weidenmueller (w3seek@users.sourceforge.net)
28 * 06-06-2001 CSH Created
29 * NOTES: Please use the Callback Memory Management functions for
30 * callbacks to make sure, the memory is freed on thread
34 /* INCLUDES ******************************************************************/
41 /* CALLBACK MEMORY MANAGEMENT ************************************************/
43 typedef struct _INT_CALLBACK_HEADER
45 /* list entry in the W32THREAD structure */
48 INT_CALLBACK_HEADER
, *PINT_CALLBACK_HEADER
;
51 IntCbAllocateMemory(ULONG Size
)
53 PINT_CALLBACK_HEADER Mem
;
56 if(!(Mem
= ExAllocatePoolWithTag(PagedPool
, Size
+ sizeof(INT_CALLBACK_HEADER
),
62 W32Thread
= PsGetWin32Thread();
65 /* insert the callback memory into the thread's callback list */
67 InsertTailList(&W32Thread
->W32CallbackListHead
, &Mem
->ListEntry
);
73 IntCbFreeMemory(PVOID Data
)
75 PINT_CALLBACK_HEADER Mem
;
80 Mem
= ((PINT_CALLBACK_HEADER
)Data
- 1);
82 W32Thread
= PsGetWin32Thread();
85 /* remove the memory block from the thread's callback list */
86 RemoveEntryList(&Mem
->ListEntry
);
93 IntCleanupThreadCallbacks(PW32THREAD W32Thread
)
95 PLIST_ENTRY CurrentEntry
;
96 PINT_CALLBACK_HEADER Mem
;
98 while (!IsListEmpty(&W32Thread
->W32CallbackListHead
))
100 CurrentEntry
= RemoveHeadList(&W32Thread
->W32CallbackListHead
);
101 Mem
= CONTAINING_RECORD(CurrentEntry
, INT_CALLBACK_HEADER
,
109 /* FUNCTIONS *****************************************************************/
112 co_IntCallSentMessageCallback(SENDASYNCPROC CompletionCallback
,
115 ULONG_PTR CompletionCallbackContext
,
118 SENDASYNCPROC_CALLBACK_ARGUMENTS Arguments
;
121 Arguments
.Callback
= CompletionCallback
;
122 Arguments
.Wnd
= hWnd
;
124 Arguments
.Context
= CompletionCallbackContext
;
125 Arguments
.Result
= Result
;
129 Status
= NtW32Call(USER32_CALLBACK_SENDASYNCPROC
,
131 sizeof(SENDASYNCPROC_CALLBACK_ARGUMENTS
),
137 if (!NT_SUCCESS(Status
))
145 co_IntCallWindowProc(WNDPROC Proc
,
151 INT lParamBufferSize
)
153 WINDOWPROC_CALLBACK_ARGUMENTS StackArguments
;
154 PWINDOWPROC_CALLBACK_ARGUMENTS Arguments
;
158 ULONG ArgumentLength
;
161 if (0 < lParamBufferSize
)
163 ArgumentLength
= sizeof(WINDOWPROC_CALLBACK_ARGUMENTS
) + lParamBufferSize
;
164 Arguments
= IntCbAllocateMemory(ArgumentLength
);
165 if (NULL
== Arguments
)
167 DPRINT1("Unable to allocate buffer for window proc callback\n");
170 RtlMoveMemory((PVOID
) ((char *) Arguments
+ sizeof(WINDOWPROC_CALLBACK_ARGUMENTS
)),
171 (PVOID
) lParam
, lParamBufferSize
);
175 Arguments
= &StackArguments
;
176 ArgumentLength
= sizeof(WINDOWPROC_CALLBACK_ARGUMENTS
);
178 Arguments
->Proc
= Proc
;
179 Arguments
->IsAnsiProc
= IsAnsiProc
;
180 Arguments
->Wnd
= Wnd
;
181 Arguments
->Msg
= Message
;
182 Arguments
->wParam
= wParam
;
183 Arguments
->lParam
= lParam
;
184 Arguments
->lParamBufferSize
= lParamBufferSize
;
185 ResultPointer
= Arguments
;
186 ResultLength
= ArgumentLength
;
190 Status
= NtW32Call(USER32_CALLBACK_WINDOWPROC
,
198 if (!NT_SUCCESS(Status
))
200 if (0 < lParamBufferSize
)
202 IntCbFreeMemory(Arguments
);
206 Result
= Arguments
->Result
;
208 if (0 < lParamBufferSize
)
210 RtlMoveMemory((PVOID
) lParam
,
211 (PVOID
) ((char *) Arguments
+ sizeof(WINDOWPROC_CALLBACK_ARGUMENTS
)),
213 IntCbFreeMemory(Arguments
);
220 co_IntLoadSysMenuTemplate()
227 ResultPointer
= &Result
;
228 ResultLength
= sizeof(LRESULT
);
232 Status
= NtW32Call(USER32_CALLBACK_LOADSYSMENUTEMPLATE
,
240 if (!NT_SUCCESS(Status
))
244 return (HMENU
)Result
;
248 co_IntLoadDefaultCursors(VOID
)
254 BOOL DefaultCursor
= TRUE
;
256 ResultPointer
= &Result
;
257 ResultLength
= sizeof(LRESULT
);
261 Status
= NtW32Call(USER32_CALLBACK_LOADDEFAULTCURSORS
,
269 if (!NT_SUCCESS(Status
))
277 co_IntCallHookProc(INT HookId
,
283 PUNICODE_STRING ModuleName
)
285 ULONG ArgumentLength
;
291 PHOOKPROC_CALLBACK_ARGUMENTS Common
;
292 CBT_CREATEWNDW
*CbtCreateWnd
=NULL
;
294 PHOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS CbtCreatewndExtra
;
295 PUNICODE_STRING WindowName
= NULL
;
296 PUNICODE_STRING ClassName
= NULL
;
298 ArgumentLength
= sizeof(HOOKPROC_CALLBACK_ARGUMENTS
) - sizeof(WCHAR
)
299 + ModuleName
->Length
;
306 CbtCreateWnd
= (CBT_CREATEWNDW
*) lParam
;
307 ArgumentLength
+= sizeof(HOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS
);
308 WindowName
= (PUNICODE_STRING
) (CbtCreateWnd
->lpcs
->lpszName
);
309 ArgumentLength
+= WindowName
->Length
+ sizeof(WCHAR
);
310 ClassName
= (PUNICODE_STRING
) (CbtCreateWnd
->lpcs
->lpszClass
);
311 if (! IS_ATOM(ClassName
->Buffer
))
313 ArgumentLength
+= ClassName
->Length
+ sizeof(WCHAR
);
317 DPRINT1("Trying to call unsupported CBT hook %d\n", Code
);
322 ArgumentLength
+= sizeof(KBDLLHOOKSTRUCT
);
325 ArgumentLength
+= sizeof(MSLLHOOKSTRUCT
);
328 DPRINT1("Trying to call unsupported window hook %d\n", HookId
);
332 Argument
= IntCbAllocateMemory(ArgumentLength
);
333 if (NULL
== Argument
)
335 DPRINT1("HookProc callback failed: out of memory\n");
338 Common
= (PHOOKPROC_CALLBACK_ARGUMENTS
) Argument
;
339 Common
->HookId
= HookId
;
341 Common
->wParam
= wParam
;
342 Common
->lParam
= lParam
;
345 Common
->ModuleNameLength
= ModuleName
->Length
;
346 memcpy(Common
->ModuleName
, ModuleName
->Buffer
, ModuleName
->Length
);
347 Extra
= (PCHAR
) Common
->ModuleName
+ Common
->ModuleNameLength
;
355 Common
->lParam
= (LPARAM
) (Extra
- (PCHAR
) Common
);
356 CbtCreatewndExtra
= (PHOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS
) Extra
;
357 CbtCreatewndExtra
->Cs
= *(CbtCreateWnd
->lpcs
);
358 CbtCreatewndExtra
->WndInsertAfter
= CbtCreateWnd
->hwndInsertAfter
;
359 Extra
= (PCHAR
) (CbtCreatewndExtra
+ 1);
360 RtlCopyMemory(Extra
, WindowName
->Buffer
, WindowName
->Length
);
361 CbtCreatewndExtra
->Cs
.lpszName
= (LPCWSTR
) (Extra
- (PCHAR
) CbtCreatewndExtra
);
362 CbtCreatewndExtra
->Cs
.lpszClass
= ClassName
->Buffer
;
363 Extra
+= WindowName
->Length
;
364 *((WCHAR
*) Extra
) = L
'\0';
365 Extra
+= sizeof(WCHAR
);
366 if (! IS_ATOM(ClassName
->Buffer
))
368 RtlCopyMemory(Extra
, ClassName
->Buffer
, ClassName
->Length
);
369 CbtCreatewndExtra
->Cs
.lpszClass
=
370 (LPCWSTR
) MAKELONG(Extra
- (PCHAR
) CbtCreatewndExtra
, 1);
371 Extra
+= ClassName
->Length
;
372 *((WCHAR
*) Extra
) = L
'\0';
378 RtlCopyMemory(Extra
, (PVOID
) lParam
, sizeof(KBDLLHOOKSTRUCT
));
379 Common
->lParam
= (LPARAM
) (Extra
- (PCHAR
) Common
);
382 RtlCopyMemory(Extra
, (PVOID
) lParam
, sizeof(MSLLHOOKSTRUCT
));
383 Common
->lParam
= (LPARAM
) (Extra
- (PCHAR
) Common
);
387 ResultPointer
= &Result
;
388 ResultLength
= sizeof(LRESULT
);
392 Status
= NtW32Call(USER32_CALLBACK_HOOKPROC
,
400 IntCbFreeMemory(Argument
);
402 if (!NT_SUCCESS(Status
))