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.
19 /* $Id: class.c,v 1.27 2003/08/11 10:30:19 gvg Exp $
21 * COPYRIGHT: See COPYING in the top level directory
22 * PROJECT: ReactOS kernel
23 * PURPOSE: Window classes
24 * FILE: subsys/win32k/ntuser/class.c
25 * PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
27 * 06-06-2001 CSH Created
29 /* INCLUDES ******************************************************************/
31 #include <ddk/ntddk.h>
32 #include <win32k/win32k.h>
33 #include <napi/win32.h>
34 #include <include/class.h>
35 #include <include/error.h>
36 #include <include/winsta.h>
37 #include <include/object.h>
38 #include <include/guicheck.h>
39 #include <include/window.h>
44 /* FUNCTIONS *****************************************************************/
49 return(STATUS_SUCCESS
);
53 CleanupClassImpl(VOID
)
55 return(STATUS_SUCCESS
);
60 ClassReferenceClassByAtom(PWNDCLASS_OBJECT
* Class
,
63 PWNDCLASS_OBJECT Current
;
64 PLIST_ENTRY CurrentEntry
;
65 PW32PROCESS Process
= PsGetWin32Process();
67 ExAcquireFastMutexUnsafe (&Process
->ClassListLock
);
68 CurrentEntry
= Process
->ClassListHead
.Flink
;
69 while (CurrentEntry
!= &Process
->ClassListHead
)
71 Current
= CONTAINING_RECORD(CurrentEntry
, WNDCLASS_OBJECT
, ListEntry
);
73 if (Current
->lpszClassName
== (PUNICODE_STRING
)(ULONG
)Atom
)
76 ObmReferenceObject(Current
);
77 ExReleaseFastMutexUnsafe (&Process
->ClassListLock
);
78 return(STATUS_SUCCESS
);
81 CurrentEntry
= CurrentEntry
->Flink
;
83 ExReleaseFastMutexUnsafe (&Process
->ClassListLock
);
85 return(STATUS_NOT_FOUND
);
89 ClassReferenceClassByName(PWNDCLASS_OBJECT
*Class
,
92 PWINSTATION_OBJECT WinStaObject
;
98 return(STATUS_INVALID_PARAMETER
);
101 Status
= ValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
105 if (!NT_SUCCESS(Status
))
107 DPRINT("Validation of window station handle (0x%X) failed\n",
108 PROCESS_WINDOW_STATION());
109 return(STATUS_UNSUCCESSFUL
);
112 Status
= RtlLookupAtomInAtomTable(WinStaObject
->AtomTable
,
116 if (!NT_SUCCESS(Status
))
118 ObDereferenceObject(WinStaObject
);
121 Status
= ClassReferenceClassByAtom(Class
,
124 ObDereferenceObject(WinStaObject
);
129 ClassReferenceClassByNameOrAtom(PWNDCLASS_OBJECT
*Class
,
130 LPWSTR ClassNameOrAtom
)
134 if (IS_ATOM(ClassNameOrAtom
))
136 Status
= ClassReferenceClassByAtom(Class
,
137 (RTL_ATOM
)((ULONG_PTR
)ClassNameOrAtom
));
141 Status
= ClassReferenceClassByName(Class
,
145 if (!NT_SUCCESS(Status
))
147 SetLastNtError(Status
);
154 NtUserGetClassInfo(HINSTANCE hInst
,
160 PWNDCLASS_OBJECT Class
;
162 Status
= ClassReferenceClassByNameOrAtom(&Class
,(LPWSTR
)str
);
163 if (!NT_SUCCESS(Status
))
165 SetLastNtError(Status
);
168 wcex
->cbSize
= sizeof(LPWNDCLASSEXW
);
169 wcex
->style
= Class
->style
;
172 wcex
->lpfnWndProc
= Class
->lpfnWndProcA
;
176 wcex
->lpfnWndProc
= Class
->lpfnWndProcW
;
178 wcex
->cbClsExtra
= Class
->cbClsExtra
;
179 wcex
->cbWndExtra
= Class
->cbWndExtra
;
180 wcex
->hInstance
= Class
->hInstance
;
181 wcex
->hIcon
= Class
->hIcon
;
182 wcex
->hCursor
= Class
->hCursor
;
183 wcex
->hbrBackground
= Class
->hbrBackground
;
184 wcex
->lpszMenuName
= (LPCWSTR
)Class
->lpszMenuName
;
185 wcex
->lpszClassName
= (LPCWSTR
)Class
->lpszClassName
;
186 wcex
->hIconSm
= Class
->hIconSm
;
191 W32kGetClassName(struct _WINDOW_OBJECT
*WindowObject
,
198 PWINSTATION_OBJECT WinStaObject
;
200 if (IS_ATOM(WindowObject
->Class
->lpszClassName
))
202 DPRINT("About to open window station handle (0x%X)\n",
203 PROCESS_WINDOW_STATION());
204 Status
= ValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
208 if (!NT_SUCCESS(Status
))
210 DPRINT("Validation of window station handle (0x%X) failed\n",
211 PROCESS_WINDOW_STATION());
215 Status
= RtlQueryAtomInAtomTable(WinStaObject
->AtomTable
,(RTL_ATOM
)WindowObject
->Class
->lpszClassName
,NULL
,NULL
,name
,&length
);
216 name
= ExAllocatePool(PagedPool
,length
+1);
218 Status
= RtlQueryAtomInAtomTable(WinStaObject
->AtomTable
,(RTL_ATOM
)WindowObject
->Class
->lpszClassName
,NULL
,NULL
,name
,&length
);
219 if (!NT_SUCCESS(Status
))
221 DPRINT("Validation of window station handle (0x%X) failed\n",
222 PROCESS_WINDOW_STATION());
225 ObDereferenceObject(WinStaObject
);
229 name
= WindowObject
->Class
->lpszClassName
->Buffer
;
230 length
= WindowObject
->Class
->lpszClassName
->Length
/ sizeof(WCHAR
);
233 if (length
> nMaxCount
)
237 *(lpClassName
+length
) = 0;
238 wcsncpy(lpClassName
,name
,length
);
252 PWINDOW_OBJECT WindowObject
;
255 WindowObject
= W32kGetWindowObject(hWnd
);
256 if (WindowObject
== NULL
)
260 Ret
= W32kGetClassName(WindowObject
, lpClassName
, nMaxCount
);
261 W32kReleaseWindowObject(WindowObject
);
266 NtUserGetWOWClass(DWORD Unknown0
,
273 PWNDCLASS_OBJECT FASTCALL
274 W32kCreateClass(CONST WNDCLASSEXW
*lpwcx
,
278 PWNDCLASS_OBJECT ClassObject
;
280 objectSize
= sizeof(WNDCLASS_OBJECT
);
281 ClassObject
= ObmCreateObject(NULL
, NULL
, otClass
, objectSize
);
282 if (ClassObject
== 0)
287 ClassObject
->cbSize
= lpwcx
->cbSize
;
288 ClassObject
->style
= lpwcx
->style
;
289 ClassObject
->cbClsExtra
= lpwcx
->cbClsExtra
;
290 ClassObject
->cbWndExtra
= lpwcx
->cbWndExtra
;
291 ClassObject
->hInstance
= lpwcx
->hInstance
;
292 ClassObject
->hIcon
= lpwcx
->hIcon
;
293 ClassObject
->hCursor
= lpwcx
->hCursor
;
294 ClassObject
->hbrBackground
= lpwcx
->hbrBackground
;
295 ClassObject
->Unicode
= bUnicodeClass
;
296 ClassObject
->hIconSm
= lpwcx
->hIconSm
;
297 ClassObject
->lpszClassName
= (PUNICODE_STRING
)(ULONG
)Atom
;
300 ClassObject
->lpfnWndProcW
= lpwcx
->lpfnWndProc
;
301 ClassObject
->lpfnWndProcA
= lpwcx
->lpfnWndProc
+0x80000000;
305 ClassObject
->lpfnWndProcA
= lpwcx
->lpfnWndProc
;
306 ClassObject
->lpfnWndProcW
= lpwcx
->lpfnWndProc
+0x80000000;
308 if (IS_INTRESOURCE(lpwcx
->lpszMenuName
))
310 ClassObject
->lpszMenuName
= (PUNICODE_STRING
)lpwcx
->lpszMenuName
;
314 ClassObject
->lpszMenuName
= ExAllocatePool(NonPagedPool
,sizeof(UNICODE_STRING
));
315 RtlCreateUnicodeString(ClassObject
->lpszMenuName
,(LPWSTR
)lpwcx
->lpszMenuName
);
321 NtUserRegisterClassExWOW(
322 CONST WNDCLASSEXW
*lpwcx
,
330 * Registers a new class with the window manager
332 * lpwcx = Win32 extended window class structure
333 * bUnicodeClass = Whether to send ANSI or unicode strings
334 * to window procedures
336 * Atom identifying the new class
339 PWINSTATION_OBJECT WinStaObject
;
340 PWNDCLASS_OBJECT ClassObject
;
343 DPRINT("About to open window station handle (0x%X)\n",
344 PROCESS_WINDOW_STATION());
345 Status
= ValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
349 if (!NT_SUCCESS(Status
))
351 DPRINT("Validation of window station handle (0x%X) failed\n",
352 PROCESS_WINDOW_STATION());
355 if (!IS_ATOM(lpwcx
->lpszClassName
))
357 Status
= RtlAddAtomToAtomTable(WinStaObject
->AtomTable
,
358 (LPWSTR
)lpwcx
->lpszClassName
,
360 if (!NT_SUCCESS(Status
))
362 ObDereferenceObject(WinStaObject
);
363 DPRINT("Failed adding class name (%wS) to atom table\n",
364 lpwcx
->lpszClassName
);
365 SetLastNtError(Status
);
371 Atom
= (RTL_ATOM
)(ULONG
)lpwcx
->lpszClassName
;
373 ClassObject
= W32kCreateClass(lpwcx
, bUnicodeClass
, Atom
);
374 if (ClassObject
== NULL
)
376 if (!IS_ATOM(lpwcx
->lpszClassName
))
378 RtlDeleteAtomFromAtomTable(WinStaObject
->AtomTable
, Atom
);
380 ObDereferenceObject(WinStaObject
);
381 DPRINT("Failed creating window class object\n");
382 SetLastNtError(STATUS_INSUFFICIENT_RESOURCES
);
385 ExAcquireFastMutex(&PsGetWin32Process()->ClassListLock
);
386 InsertTailList(&PsGetWin32Process()->ClassListHead
, &ClassObject
->ListEntry
);
387 ExReleaseFastMutex(&PsGetWin32Process()->ClassListLock
);
388 ObDereferenceObject(WinStaObject
);
393 W32kGetClassLong(struct _WINDOW_OBJECT
*WindowObject
, ULONG Offset
, BOOL Ansi
)
399 Ret
= WindowObject
->Class
->cbWndExtra
;
402 Ret
= WindowObject
->Class
->cbClsExtra
;
404 case GCL_HBRBACKGROUND
:
405 Ret
= (ULONG
)WindowObject
->Class
->hbrBackground
;
408 Ret
= (ULONG
)WindowObject
->Class
->hCursor
;
411 Ret
= (ULONG
)WindowObject
->Class
->hIcon
;
414 Ret
= (ULONG
)WindowObject
->Class
->hIconSm
;
417 Ret
= (ULONG
)WindowObject
->Class
->hInstance
;
420 Ret
= (ULONG
)WindowObject
->Class
->lpszMenuName
;
423 Ret
= WindowObject
->Class
->style
;
428 Ret
= (ULONG
)WindowObject
->Class
->lpfnWndProcA
;
432 Ret
= (ULONG
)WindowObject
->Class
->lpfnWndProcW
;
443 NtUserGetClassLong(HWND hWnd
, DWORD Offset
, BOOL Ansi
)
445 PWINDOW_OBJECT WindowObject
;
448 WindowObject
= W32kGetWindowObject(hWnd
);
449 if (WindowObject
== NULL
)
453 Ret
= W32kGetClassLong(WindowObject
, Offset
, Ansi
);
454 W32kReleaseWindowObject(WindowObject
);
459 W32kSetClassLong(PWINDOW_OBJECT WindowObject
, ULONG Offset
, LONG dwNewLong
, BOOL Ansi
)
465 WindowObject
->Class
->cbWndExtra
= dwNewLong
;
468 WindowObject
->Class
->cbClsExtra
= dwNewLong
;
470 case GCL_HBRBACKGROUND
:
471 WindowObject
->Class
->hbrBackground
= (HBRUSH
)dwNewLong
;
474 WindowObject
->Class
->hCursor
= (HCURSOR
)dwNewLong
;
477 WindowObject
->Class
->hIcon
= (HICON
)dwNewLong
;
480 WindowObject
->Class
->hIconSm
= (HICON
)dwNewLong
;
483 WindowObject
->Class
->hInstance
= (HINSTANCE
)dwNewLong
;
486 if (!IS_INTRESOURCE(dwNewLong
))
488 str
= ExAllocatePool(PagedPool
,sizeof(UNICODE_STRING
)+((PUNICODE_STRING
)dwNewLong
)->Length
);
489 memcpy(str
,(PUNICODE_STRING
)dwNewLong
,sizeof(UNICODE_STRING
)+((PUNICODE_STRING
)dwNewLong
)->Length
);
490 WindowObject
->Class
->lpszMenuName
= str
;
494 WindowObject
->Class
->lpszMenuName
= (PUNICODE_STRING
)dwNewLong
;
498 WindowObject
->Class
->style
= dwNewLong
;
503 WindowObject
->Class
->lpfnWndProcA
= (WNDPROC
)dwNewLong
;
504 WindowObject
->Class
->lpfnWndProcW
= (WNDPROC
)dwNewLong
+0x80000000;
508 WindowObject
->Class
->lpfnWndProcW
= (WNDPROC
)dwNewLong
;
509 WindowObject
->Class
->lpfnWndProcA
= (WNDPROC
)dwNewLong
+0x80000000;
516 NtUserSetClassLong(HWND hWnd
,
521 PWINDOW_OBJECT WindowObject
;
524 WindowObject
= W32kGetWindowObject(hWnd
);
525 if (WindowObject
== NULL
)
529 Ret
= W32kGetClassLong(WindowObject
, Offset
, Ansi
);
530 W32kSetClassLong(WindowObject
, Offset
, dwNewLong
, Ansi
);
531 W32kReleaseWindowObject(WindowObject
);
536 NtUserSetClassWord(DWORD Unknown0
,
545 NtUserUnregisterClass(DWORD Unknown0
,