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 */
47 } INT_CALLBACK_HEADER
, *PINT_CALLBACK_HEADER
;
50 IntCbAllocateMemory(ULONG Size
)
52 PINT_CALLBACK_HEADER Mem
;
55 if(!(Mem
= ExAllocatePoolWithTag(PagedPool
, Size
+ sizeof(INT_CALLBACK_HEADER
),
61 W32Thread
= PsGetWin32Thread();
64 /* insert the callback memory into the thread's callback list */
66 InsertTailList(&W32Thread
->W32CallbackListHead
, &Mem
->ListEntry
);
72 IntCbFreeMemory(PVOID Data
)
74 PINT_CALLBACK_HEADER Mem
;
79 Mem
= ((PINT_CALLBACK_HEADER
)Data
- 1);
81 W32Thread
= PsGetWin32Thread();
84 /* remove the memory block from the thread's callback list */
85 RemoveEntryList(&Mem
->ListEntry
);
92 IntCleanupThreadCallbacks(PW32THREAD W32Thread
)
94 PLIST_ENTRY CurrentEntry
;
95 PINT_CALLBACK_HEADER Mem
;
97 while (!IsListEmpty(&W32Thread
->W32CallbackListHead
))
99 CurrentEntry
= RemoveHeadList(&W32Thread
->W32CallbackListHead
);
100 Mem
= CONTAINING_RECORD(CurrentEntry
, INT_CALLBACK_HEADER
,
108 /* FUNCTIONS *****************************************************************/
111 IntCallSentMessageCallback(SENDASYNCPROC CompletionCallback
,
114 ULONG_PTR CompletionCallbackContext
,
117 SENDASYNCPROC_CALLBACK_ARGUMENTS Arguments
;
120 Arguments
.Callback
= CompletionCallback
;
121 Arguments
.Wnd
= hWnd
;
123 Arguments
.Context
= CompletionCallbackContext
;
124 Arguments
.Result
= Result
;
125 Status
= NtW32Call(USER32_CALLBACK_SENDASYNCPROC
,
127 sizeof(SENDASYNCPROC_CALLBACK_ARGUMENTS
),
130 if (!NT_SUCCESS(Status
))
138 IntCallWindowProc(WNDPROC Proc
,
144 INT lParamBufferSize
)
146 WINDOWPROC_CALLBACK_ARGUMENTS StackArguments
;
147 PWINDOWPROC_CALLBACK_ARGUMENTS Arguments
;
151 ULONG ArgumentLength
;
154 if (0 < lParamBufferSize
)
156 ArgumentLength
= sizeof(WINDOWPROC_CALLBACK_ARGUMENTS
) + lParamBufferSize
;
157 Arguments
= IntCbAllocateMemory(ArgumentLength
);
158 if (NULL
== Arguments
)
160 DPRINT1("Unable to allocate buffer for window proc callback\n");
163 RtlMoveMemory((PVOID
) ((char *) Arguments
+ sizeof(WINDOWPROC_CALLBACK_ARGUMENTS
)),
164 (PVOID
) lParam
, lParamBufferSize
);
168 Arguments
= &StackArguments
;
169 ArgumentLength
= sizeof(WINDOWPROC_CALLBACK_ARGUMENTS
);
171 Arguments
->Proc
= Proc
;
172 Arguments
->IsAnsiProc
= IsAnsiProc
;
173 Arguments
->Wnd
= Wnd
;
174 Arguments
->Msg
= Message
;
175 Arguments
->wParam
= wParam
;
176 Arguments
->lParam
= lParam
;
177 Arguments
->lParamBufferSize
= lParamBufferSize
;
178 ResultPointer
= Arguments
;
179 ResultLength
= ArgumentLength
;
180 Status
= NtW32Call(USER32_CALLBACK_WINDOWPROC
,
185 if (!NT_SUCCESS(Status
))
187 if (0 < lParamBufferSize
)
189 IntCbFreeMemory(Arguments
);
193 Result
= Arguments
->Result
;
195 if (0 < lParamBufferSize
)
197 RtlMoveMemory((PVOID
) lParam
,
198 (PVOID
) ((char *) Arguments
+ sizeof(WINDOWPROC_CALLBACK_ARGUMENTS
)),
200 IntCbFreeMemory(Arguments
);
207 IntLoadSysMenuTemplate()
214 ResultPointer
= &Result
;
215 ResultLength
= sizeof(LRESULT
);
216 Status
= NtW32Call(USER32_CALLBACK_LOADSYSMENUTEMPLATE
,
221 if (!NT_SUCCESS(Status
))
225 return (HMENU
)Result
;
229 IntLoadDefaultCursors(VOID
)
235 BOOL DefaultCursor
= TRUE
;
237 ResultPointer
= &Result
;
238 ResultLength
= sizeof(LRESULT
);
239 Status
= NtW32Call(USER32_CALLBACK_LOADDEFAULTCURSORS
,
244 if (!NT_SUCCESS(Status
))
252 IntCallHookProc(INT HookId
,
258 PUNICODE_STRING ModuleName
)
260 ULONG ArgumentLength
;
266 PHOOKPROC_CALLBACK_ARGUMENTS Common
;
267 CBT_CREATEWNDW
*CbtCreateWnd
;
269 PHOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS CbtCreatewndExtra
;
270 PUNICODE_STRING WindowName
;
271 PUNICODE_STRING ClassName
;
273 ArgumentLength
= sizeof(HOOKPROC_CALLBACK_ARGUMENTS
) - sizeof(WCHAR
)
274 + ModuleName
->Length
;
281 CbtCreateWnd
= (CBT_CREATEWNDW
*) lParam
;
282 ArgumentLength
+= sizeof(HOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS
);
283 WindowName
= (PUNICODE_STRING
) (CbtCreateWnd
->lpcs
->lpszName
);
284 ArgumentLength
+= WindowName
->Length
+ sizeof(WCHAR
);
285 ClassName
= (PUNICODE_STRING
) (CbtCreateWnd
->lpcs
->lpszClass
);
286 if (! IS_ATOM(ClassName
->Buffer
))
288 ArgumentLength
+= ClassName
->Length
+ sizeof(WCHAR
);
292 DPRINT1("Trying to call unsupported CBT hook %d\n", Code
);
297 ArgumentLength
+= sizeof(KBDLLHOOKSTRUCT
);
300 ArgumentLength
+= sizeof(MSLLHOOKSTRUCT
);
303 DPRINT1("Trying to call unsupported window hook %d\n", HookId
);
307 Argument
= IntCbAllocateMemory(ArgumentLength
);
308 if (NULL
== Argument
)
310 DPRINT1("HookProc callback failed: out of memory\n");
313 Common
= (PHOOKPROC_CALLBACK_ARGUMENTS
) Argument
;
314 Common
->HookId
= HookId
;
316 Common
->wParam
= wParam
;
317 Common
->lParam
= lParam
;
320 Common
->ModuleNameLength
= ModuleName
->Length
;
321 memcpy(Common
->ModuleName
, ModuleName
->Buffer
, ModuleName
->Length
);
322 Extra
= (PCHAR
) Common
->ModuleName
+ Common
->ModuleNameLength
;
330 Common
->lParam
= (LPARAM
) (Extra
- (PCHAR
) Common
);
331 CbtCreatewndExtra
= (PHOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS
) Extra
;
332 CbtCreatewndExtra
->Cs
= *(CbtCreateWnd
->lpcs
);
333 CbtCreatewndExtra
->WndInsertAfter
= CbtCreateWnd
->hwndInsertAfter
;
334 Extra
= (PCHAR
) (CbtCreatewndExtra
+ 1);
335 RtlCopyMemory(Extra
, WindowName
->Buffer
, WindowName
->Length
);
336 CbtCreatewndExtra
->Cs
.lpszName
= (LPCWSTR
) (Extra
- (PCHAR
) CbtCreatewndExtra
);
337 CbtCreatewndExtra
->Cs
.lpszClass
= ClassName
->Buffer
;
338 Extra
+= WindowName
->Length
;
339 *((WCHAR
*) Extra
) = L
'\0';
340 Extra
+= sizeof(WCHAR
);
341 if (! IS_ATOM(ClassName
->Buffer
))
343 RtlCopyMemory(Extra
, ClassName
->Buffer
, ClassName
->Length
);
344 CbtCreatewndExtra
->Cs
.lpszClass
=
345 (LPCWSTR
) MAKELONG(Extra
- (PCHAR
) CbtCreatewndExtra
, 1);
346 Extra
+= ClassName
->Length
;
347 *((WCHAR
*) Extra
) = L
'\0';
353 RtlCopyMemory(Extra
, (PVOID
) lParam
, sizeof(KBDLLHOOKSTRUCT
));
354 Common
->lParam
= (LPARAM
) (Extra
- (PCHAR
) Common
);
357 RtlCopyMemory(Extra
, (PVOID
) lParam
, sizeof(MSLLHOOKSTRUCT
));
358 Common
->lParam
= (LPARAM
) (Extra
- (PCHAR
) Common
);
362 ResultPointer
= &Result
;
363 ResultLength
= sizeof(LRESULT
);
364 Status
= NtW32Call(USER32_CALLBACK_HOOKPROC
,
370 IntCbFreeMemory(Argument
);
372 if (!NT_SUCCESS(Status
))