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.26 2003/08/09 07:09:57 jimtabor 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 if (Class
->hInstance
!= hInst
)
172 wcex
->cbSize
= sizeof(LPWNDCLASSEXW
);
173 wcex
->style
= Class
->style
;
176 wcex
->lpfnWndProc
= Class
->lpfnWndProcA
;
180 wcex
->lpfnWndProc
= Class
->lpfnWndProcW
;
182 wcex
->cbClsExtra
= Class
->cbClsExtra
;
183 wcex
->cbWndExtra
= Class
->cbWndExtra
;
184 wcex
->hInstance
= Class
->hInstance
;
185 wcex
->hIcon
= Class
->hIcon
;
186 wcex
->hCursor
= Class
->hCursor
;
187 wcex
->hbrBackground
= Class
->hbrBackground
;
188 wcex
->lpszMenuName
= (LPCWSTR
)Class
->lpszMenuName
;
189 wcex
->lpszClassName
= (LPCWSTR
)Class
->lpszClassName
;
190 wcex
->hIconSm
= Class
->hIconSm
;
195 W32kGetClassName(struct _WINDOW_OBJECT
*WindowObject
,
202 PWINSTATION_OBJECT WinStaObject
;
204 if (IS_ATOM(WindowObject
->Class
->lpszClassName
))
206 DPRINT("About to open window station handle (0x%X)\n",
207 PROCESS_WINDOW_STATION());
208 Status
= ValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
212 if (!NT_SUCCESS(Status
))
214 DPRINT("Validation of window station handle (0x%X) failed\n",
215 PROCESS_WINDOW_STATION());
219 Status
= RtlQueryAtomInAtomTable(WinStaObject
->AtomTable
,(RTL_ATOM
)WindowObject
->Class
->lpszClassName
,NULL
,NULL
,name
,&length
);
220 name
= ExAllocatePool(PagedPool
,length
+1);
222 Status
= RtlQueryAtomInAtomTable(WinStaObject
->AtomTable
,(RTL_ATOM
)WindowObject
->Class
->lpszClassName
,NULL
,NULL
,name
,&length
);
223 if (!NT_SUCCESS(Status
))
225 DPRINT("Validation of window station handle (0x%X) failed\n",
226 PROCESS_WINDOW_STATION());
229 ObDereferenceObject(WinStaObject
);
233 name
= WindowObject
->Class
->lpszClassName
->Buffer
;
234 length
= WindowObject
->Class
->lpszClassName
->Length
/ sizeof(WCHAR
);
237 if (length
> nMaxCount
)
241 *(lpClassName
+length
) = 0;
242 wcsncpy(lpClassName
,name
,length
);
256 PWINDOW_OBJECT WindowObject
;
259 WindowObject
= W32kGetWindowObject(hWnd
);
260 if (WindowObject
== NULL
)
264 Ret
= W32kGetClassName(WindowObject
, lpClassName
, nMaxCount
);
265 W32kReleaseWindowObject(WindowObject
);
270 NtUserGetWOWClass(DWORD Unknown0
,
277 PWNDCLASS_OBJECT FASTCALL
278 W32kCreateClass(CONST WNDCLASSEXW
*lpwcx
,
282 PWNDCLASS_OBJECT ClassObject
;
284 objectSize
= sizeof(WNDCLASS_OBJECT
);
285 ClassObject
= ObmCreateObject(NULL
, NULL
, otClass
, objectSize
);
286 if (ClassObject
== 0)
291 ClassObject
->cbSize
= lpwcx
->cbSize
;
292 ClassObject
->style
= lpwcx
->style
;
293 ClassObject
->cbClsExtra
= lpwcx
->cbClsExtra
;
294 ClassObject
->cbWndExtra
= lpwcx
->cbWndExtra
;
295 ClassObject
->hInstance
= lpwcx
->hInstance
;
296 ClassObject
->hIcon
= lpwcx
->hIcon
;
297 ClassObject
->hCursor
= lpwcx
->hCursor
;
298 ClassObject
->hbrBackground
= lpwcx
->hbrBackground
;
299 ClassObject
->Unicode
= bUnicodeClass
;
300 ClassObject
->hIconSm
= lpwcx
->hIconSm
;
301 ClassObject
->lpszClassName
= (PUNICODE_STRING
)(ULONG
)Atom
;
304 ClassObject
->lpfnWndProcW
= lpwcx
->lpfnWndProc
;
305 ClassObject
->lpfnWndProcA
= (WNDPROC
)0xCCCCCCCC;
309 ClassObject
->lpfnWndProcA
= lpwcx
->lpfnWndProc
;
310 ClassObject
->lpfnWndProcW
= (WNDPROC
)0xCCCCCCCC;
312 if (IS_INTRESOURCE(lpwcx
->lpszMenuName
))
314 ClassObject
->lpszMenuName
= (PUNICODE_STRING
)lpwcx
->lpszMenuName
;
318 RtlCreateUnicodeString(ClassObject
->lpszMenuName
,(LPWSTR
)lpwcx
->lpszMenuName
);
324 NtUserRegisterClassExWOW(
325 CONST WNDCLASSEXW
*lpwcx
,
333 * Registers a new class with the window manager
335 * lpwcx = Win32 extended window class structure
336 * bUnicodeClass = Whether to send ANSI or unicode strings
337 * to window procedures
339 * Atom identifying the new class
342 PWINSTATION_OBJECT WinStaObject
;
343 PWNDCLASS_OBJECT ClassObject
;
346 DPRINT("About to open window station handle (0x%X)\n",
347 PROCESS_WINDOW_STATION());
348 Status
= ValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
352 if (!NT_SUCCESS(Status
))
354 DPRINT("Validation of window station handle (0x%X) failed\n",
355 PROCESS_WINDOW_STATION());
358 if (!IS_ATOM(lpwcx
->lpszClassName
))
360 Status
= RtlAddAtomToAtomTable(WinStaObject
->AtomTable
,
361 (LPWSTR
)lpwcx
->lpszClassName
,
363 if (!NT_SUCCESS(Status
))
365 ObDereferenceObject(WinStaObject
);
366 DPRINT("Failed adding class name (%wS) to atom table\n",
367 lpwcx
->lpszClassName
);
368 SetLastNtError(Status
);
374 Atom
= (RTL_ATOM
)(ULONG
)lpwcx
->lpszClassName
;
376 ClassObject
= W32kCreateClass(lpwcx
, bUnicodeClass
, Atom
);
377 if (ClassObject
== NULL
)
379 if (!IS_ATOM(lpwcx
->lpszClassName
))
381 RtlDeleteAtomFromAtomTable(WinStaObject
->AtomTable
, Atom
);
383 ObDereferenceObject(WinStaObject
);
384 DPRINT("Failed creating window class object\n");
385 SetLastNtError(STATUS_INSUFFICIENT_RESOURCES
);
388 ExAcquireFastMutex(&PsGetWin32Process()->ClassListLock
);
389 InsertTailList(&PsGetWin32Process()->ClassListHead
, &ClassObject
->ListEntry
);
390 ExReleaseFastMutex(&PsGetWin32Process()->ClassListLock
);
391 ObDereferenceObject(WinStaObject
);
396 W32kGetClassLong(struct _WINDOW_OBJECT
*WindowObject
, ULONG Offset
, BOOL Ansi
)
402 Ret
= WindowObject
->Class
->cbWndExtra
;
405 Ret
= WindowObject
->Class
->cbClsExtra
;
407 case GCL_HBRBACKGROUND
:
408 Ret
= (ULONG
)WindowObject
->Class
->hbrBackground
;
411 Ret
= (ULONG
)WindowObject
->Class
->hCursor
;
414 Ret
= (ULONG
)WindowObject
->Class
->hIcon
;
417 Ret
= (ULONG
)WindowObject
->Class
->hIconSm
;
420 Ret
= (ULONG
)WindowObject
->Class
->hInstance
;
423 Ret
= (ULONG
)WindowObject
->Class
->lpszMenuName
;
426 Ret
= WindowObject
->Class
->style
;
431 Ret
= (ULONG
)WindowObject
->Class
->lpfnWndProcA
;
435 Ret
= (ULONG
)WindowObject
->Class
->lpfnWndProcW
;
446 NtUserGetClassLong(HWND hWnd
, DWORD Offset
, BOOL Ansi
)
448 PWINDOW_OBJECT WindowObject
;
451 WindowObject
= W32kGetWindowObject(hWnd
);
452 if (WindowObject
== NULL
)
456 Ret
= W32kGetClassLong(WindowObject
, Offset
, Ansi
);
457 W32kReleaseWindowObject(WindowObject
);
462 W32kSetClassLong(PWINDOW_OBJECT WindowObject
, ULONG Offset
, LONG dwNewLong
, BOOL Ansi
)
468 WindowObject
->Class
->cbWndExtra
= dwNewLong
;
471 WindowObject
->Class
->cbClsExtra
= dwNewLong
;
473 case GCL_HBRBACKGROUND
:
474 WindowObject
->Class
->hbrBackground
= (HBRUSH
)dwNewLong
;
477 WindowObject
->Class
->hCursor
= (HCURSOR
)dwNewLong
;
480 WindowObject
->Class
->hIcon
= (HICON
)dwNewLong
;
483 WindowObject
->Class
->hIconSm
= (HICON
)dwNewLong
;
486 WindowObject
->Class
->hInstance
= (HINSTANCE
)dwNewLong
;
489 if (!IS_INTRESOURCE(dwNewLong
))
491 str
= ExAllocatePool(PagedPool
,sizeof(UNICODE_STRING
)+((PUNICODE_STRING
)dwNewLong
)->Length
);
492 memcpy(str
,(PUNICODE_STRING
)dwNewLong
,sizeof(UNICODE_STRING
)+((PUNICODE_STRING
)dwNewLong
)->Length
);
493 WindowObject
->Class
->lpszMenuName
= str
;
497 WindowObject
->Class
->lpszMenuName
= (PUNICODE_STRING
)dwNewLong
;
501 WindowObject
->Class
->style
= dwNewLong
;
506 WindowObject
->Class
->lpfnWndProcA
= (WNDPROC
)dwNewLong
;
507 WindowObject
->Class
->lpfnWndProcW
= (WNDPROC
)0xCCCCCCCC;
511 WindowObject
->Class
->lpfnWndProcW
= (WNDPROC
)dwNewLong
;
512 WindowObject
->Class
->lpfnWndProcA
= (WNDPROC
)0xCCCCCCCC;
519 NtUserSetClassLong(HWND hWnd
,
524 PWINDOW_OBJECT WindowObject
;
527 WindowObject
= W32kGetWindowObject(hWnd
);
528 if (WindowObject
== NULL
)
532 Ret
= W32kGetClassLong(WindowObject
, Offset
, Ansi
);
533 W32kSetClassLong(WindowObject
, Offset
, dwNewLong
, Ansi
);
534 W32kReleaseWindowObject(WindowObject
);
539 NtUserSetClassWord(DWORD Unknown0
,
548 NtUserUnregisterClass(DWORD Unknown0
,