-W32k/NtUser separation
[reactos.git] / reactos / subsys / win32k / ntuser / class.c
1 /*
2 * ReactOS W32 Subsystem
3 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
4 *
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.
9 *
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.
14 *
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.
18 */
19 /* $Id: class.c,v 1.21 2003/08/04 16:54:54 gdalsnes Exp $
20 *
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)
26 * REVISION HISTORY:
27 * 06-06-2001 CSH Created
28 */
29 /* INCLUDES ******************************************************************/
30
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>
40
41 #define NDEBUG
42 #include <debug.h>
43
44 /* FUNCTIONS *****************************************************************/
45
46 NTSTATUS FASTCALL
47 InitClassImpl(VOID)
48 {
49 return(STATUS_SUCCESS);
50 }
51
52 NTSTATUS FASTCALL
53 CleanupClassImpl(VOID)
54 {
55 return(STATUS_SUCCESS);
56 }
57
58
59 NTSTATUS FASTCALL
60 ClassReferenceClassByAtom(PWNDCLASS_OBJECT* Class,
61 RTL_ATOM Atom)
62 {
63 PWNDCLASS_OBJECT Current;
64 PLIST_ENTRY CurrentEntry;
65 PW32PROCESS Process = PsGetWin32Process();
66
67 ExAcquireFastMutexUnsafe (&Process->ClassListLock);
68 CurrentEntry = Process->ClassListHead.Flink;
69 while (CurrentEntry != &Process->ClassListHead)
70 {
71 Current = CONTAINING_RECORD(CurrentEntry, WNDCLASS_OBJECT, ListEntry);
72
73 if (Current->Class.lpszClassName == (LPWSTR)(ULONG)Atom)
74 {
75 *Class = Current;
76 ObmReferenceObject(Current);
77 ExReleaseFastMutexUnsafe (&Process->ClassListLock);
78 return(STATUS_SUCCESS);
79 }
80
81 CurrentEntry = CurrentEntry->Flink;
82 }
83 ExReleaseFastMutexUnsafe (&Process->ClassListLock);
84
85 return(STATUS_NOT_FOUND);
86 }
87
88 NTSTATUS STDCALL
89 ClassReferenceClassByName(PWNDCLASS_OBJECT *Class,
90 PWSTR ClassName)
91 {
92 PWINSTATION_OBJECT WinStaObject;
93 NTSTATUS Status;
94 RTL_ATOM ClassAtom;
95
96 if (!ClassName)
97 {
98 return(STATUS_INVALID_PARAMETER);
99 }
100
101 Status = ValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
102 KernelMode,
103 0,
104 &WinStaObject);
105 if (!NT_SUCCESS(Status))
106 {
107 DPRINT("Validation of window station handle (0x%X) failed\n",
108 PROCESS_WINDOW_STATION());
109 return(STATUS_UNSUCCESSFUL);
110 }
111
112 Status = RtlLookupAtomInAtomTable(WinStaObject->AtomTable,
113 ClassName,
114 &ClassAtom);
115
116 if (!NT_SUCCESS(Status))
117 {
118 ObDereferenceObject(WinStaObject);
119 return(Status);
120 }
121 Status = ClassReferenceClassByAtom(Class,
122 ClassAtom);
123
124 ObDereferenceObject(WinStaObject);
125 return(Status);
126 }
127
128 NTSTATUS FASTCALL
129 ClassReferenceClassByNameOrAtom(PWNDCLASS_OBJECT *Class,
130 LPWSTR ClassNameOrAtom)
131 {
132 NTSTATUS Status;
133
134 if (IS_ATOM(ClassNameOrAtom))
135 {
136 Status = ClassReferenceClassByAtom(Class,
137 (RTL_ATOM)((ULONG_PTR)ClassNameOrAtom));
138 }
139 else
140 {
141 Status = ClassReferenceClassByName(Class,
142 ClassNameOrAtom);
143 }
144
145 if (!NT_SUCCESS(Status))
146 {
147 SetLastNtError(Status);
148 }
149
150 return(Status);
151 }
152
153 DWORD STDCALL
154 NtUserGetClassInfo(IN LPWSTR ClassName,
155 IN ULONG InfoClass,
156 OUT PVOID Info,
157 IN ULONG InfoLength,
158 OUT PULONG ReturnedLength)
159 {
160 UNIMPLEMENTED;
161
162 return(0);
163 }
164
165 DWORD STDCALL
166 NtUserGetClassName(DWORD Unknown0,
167 DWORD Unknown1,
168 DWORD Unknown2)
169 {
170 UNIMPLEMENTED;
171
172 return(0);
173 }
174
175 DWORD STDCALL
176 NtUserGetWOWClass(DWORD Unknown0,
177 DWORD Unknown1)
178 {
179 UNIMPLEMENTED;
180
181 return(0);
182 }
183
184 PWNDCLASS_OBJECT FASTCALL
185 W32kCreateClass(LPWNDCLASSEXW lpwcx,
186 BOOL bUnicodeClass,
187 RTL_ATOM Atom)
188 {
189 PWNDCLASS_OBJECT ClassObject;
190 WORD objectSize;
191 LPTSTR namePtr;
192
193 objectSize = sizeof(WNDCLASS_OBJECT) +
194 (lpwcx->lpszMenuName != 0 ? ((wcslen (lpwcx->lpszMenuName) + 1) * 2) : 0);
195 ClassObject = ObmCreateObject(NULL, NULL, otClass, objectSize);
196 if (ClassObject == 0)
197 {
198 return(NULL);
199 }
200
201 ClassObject->Class = *lpwcx;
202 ClassObject->Unicode = bUnicodeClass;
203 if (lpwcx->lpszMenuName != 0)
204 {
205 namePtr = (LPTSTR)(((PCHAR)ClassObject) + sizeof (WNDCLASS_OBJECT));
206 ClassObject->Class.lpszMenuName = namePtr;
207 wcscpy (namePtr, lpwcx->lpszMenuName);
208 }
209 ClassObject->Class.lpszClassName = (LPWSTR)(ULONG)Atom;
210 return(ClassObject);
211 }
212
213 RTL_ATOM STDCALL
214 NtUserRegisterClassExWOW(LPWNDCLASSEXW lpwcx,
215 BOOL bUnicodeClass,
216 DWORD Unknown2,
217 DWORD Unknown3,
218 DWORD Unknown4,
219 DWORD Unknown5)
220 /*
221 * FUNCTION:
222 * Registers a new class with the window manager
223 * ARGUMENTS:
224 * lpcx = Win32 extended window class structure
225 * bUnicodeClass = Wether to send ANSI or unicode strings
226 * to window procedures
227 * RETURNS:
228 * Atom identifying the new class
229 */
230 {
231 PWINSTATION_OBJECT WinStaObject;
232 PWNDCLASS_OBJECT ClassObject;
233 NTSTATUS Status;
234 RTL_ATOM Atom;
235
236 DPRINT("About to open window station handle (0x%X)\n",
237 PROCESS_WINDOW_STATION());
238
239 Status = ValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
240 KernelMode,
241 0,
242 &WinStaObject);
243 if (!NT_SUCCESS(Status))
244 {
245 DPRINT("Validation of window station handle (0x%X) failed\n",
246 PROCESS_WINDOW_STATION());
247 return((RTL_ATOM)0);
248 }
249 if (!IS_ATOM(lpwcx->lpszClassName))
250 {
251 Status = RtlAddAtomToAtomTable(WinStaObject->AtomTable,
252 (LPWSTR)lpwcx->lpszClassName,
253 &Atom);
254 if (!NT_SUCCESS(Status))
255 {
256 ObDereferenceObject(WinStaObject);
257 DPRINT("Failed adding class name (%wS) to atom table\n",
258 lpwcx->lpszClassName);
259 SetLastNtError(Status);
260 return((RTL_ATOM)0);
261 }
262 }
263 else
264 {
265 Atom = (RTL_ATOM)(ULONG)lpwcx->lpszClassName;
266 }
267 ClassObject = W32kCreateClass(lpwcx, bUnicodeClass, Atom);
268 if (ClassObject == NULL)
269 {
270 if (!IS_ATOM(lpwcx->lpszClassName))
271 {
272 RtlDeleteAtomFromAtomTable(WinStaObject->AtomTable, Atom);
273 }
274 ObDereferenceObject(WinStaObject);
275 DPRINT("Failed creating window class object\n");
276 SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
277 return((RTL_ATOM)0);
278 }
279 ExAcquireFastMutex(&PsGetWin32Process()->ClassListLock);
280 InsertTailList(&PsGetWin32Process()->ClassListHead, &ClassObject->ListEntry);
281 ExReleaseFastMutex(&PsGetWin32Process()->ClassListLock);
282
283 ObDereferenceObject(WinStaObject);
284
285 return(Atom);
286 }
287
288 ULONG FASTCALL
289 W32kGetClassLong(PWINDOW_OBJECT WindowObject, ULONG Offset)
290 {
291 LONG Ret;
292 switch (Offset)
293 {
294 case GCL_STYLE:
295 Ret = WindowObject->Class->Class.style;
296 break;
297 case GCL_CBWNDEXTRA:
298 Ret = WindowObject->Class->Class.cbWndExtra;
299 break;
300 case GCL_CBCLSEXTRA:
301 Ret = WindowObject->Class->Class.cbClsExtra;
302 break;
303 case GCL_HMODULE:
304 Ret = (ULONG)WindowObject->Class->Class.hInstance;
305 break;
306 case GCL_HBRBACKGROUND:
307 Ret = (ULONG)WindowObject->Class->Class.hbrBackground;
308 break;
309 default:
310 Ret = 0;
311 break;
312 }
313 return(Ret);
314 }
315
316 DWORD STDCALL
317 NtUserGetClassLong(HWND hWnd, DWORD Offset)
318 {
319 PWINDOW_OBJECT WindowObject;
320 LONG Ret;
321
322 WindowObject = W32kGetWindowObject(hWnd);
323 if (WindowObject == NULL)
324 {
325 return(0);
326 }
327 Ret = W32kGetClassLong(WindowObject, Offset);
328 W32kReleaseWindowObject(WindowObject);
329 return(Ret);
330 }
331
332 DWORD STDCALL
333 NtUserSetClassLong(HWND hWnd, int Index, LONG NewValue, DWORD unk)
334 {
335 UNIMPLEMENTED;
336
337 return(0);
338 }
339
340 DWORD STDCALL
341 NtUserSetClassWord(DWORD Unknown0,
342 DWORD Unknown1,
343 DWORD Unknown2)
344 {
345 UNIMPLEMENTED;
346
347 return(0);
348 }
349
350 DWORD STDCALL
351 NtUserUnregisterClass(DWORD Unknown0,
352 DWORD Unknown1,
353 DWORD Unknown2)
354 {
355 UNIMPLEMENTED;
356
357 return(0);
358 }
359
360 /* EOF */