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