From 2ce98492488fbf99e581fed4c80e7110e78f9f05 Mon Sep 17 00:00:00 2001 From: David Welch Date: Sun, 27 Jul 2003 21:35:50 +0000 Subject: [PATCH] - RegisterClassExA: Don't try to convert a class name which is an atom to unicode. - NtUserRegisterClass: Track classes by atom not by name. svn path=/trunk/; revision=5293 --- reactos/lib/user32/windows/class.c | 48 +++++++------ reactos/subsys/win32k/include/class.h | 6 +- reactos/subsys/win32k/ntuser/class.c | 98 ++++++++++++++------------- reactos/subsys/win32k/ntuser/winsta.c | 4 +- 4 files changed, 85 insertions(+), 71 deletions(-) diff --git a/reactos/lib/user32/windows/class.c b/reactos/lib/user32/windows/class.c index 8bea62cdb86..1d002aa33a7 100644 --- a/reactos/lib/user32/windows/class.c +++ b/reactos/lib/user32/windows/class.c @@ -1,4 +1,4 @@ -/* $Id: class.c,v 1.20 2003/07/10 21:04:31 chorns Exp $ +/* $Id: class.c,v 1.21 2003/07/27 21:35:50 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS user32.dll @@ -241,23 +241,27 @@ RegisterClassExA(CONST WNDCLASSEXA *lpwcx) WNDCLASSEXW Class; RTL_ATOM Atom; - if (!RtlCreateUnicodeStringFromAsciiz(&MenuName, (PCSZ)lpwcx->lpszMenuName)) - { - RtlFreeUnicodeString(&MenuName); - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return (ATOM)0; - } - - if (!RtlCreateUnicodeStringFromAsciiz(&ClassName, (PCSZ)lpwcx->lpszClassName)) + RtlMoveMemory(&Class, lpwcx, sizeof(WNDCLASSEXA)); + if (HIWORD((ULONG)lpwcx->lpszMenuName) != 0) { - RtlFreeUnicodeString(&ClassName); - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return (ATOM)0; + if (!RtlCreateUnicodeStringFromAsciiz(&MenuName, (PCSZ)lpwcx->lpszMenuName)) + { + RtlFreeUnicodeString(&MenuName); + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return (ATOM)0; + } + Class.lpszMenuName = MenuName.Buffer; + } + if (HIWORD((ULONG)lpwcx->lpszClassName) != 0) + { + if (!RtlCreateUnicodeStringFromAsciiz(&ClassName, (PCSZ)lpwcx->lpszClassName)) + { + RtlFreeUnicodeString(&ClassName); + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return (ATOM)0; + } + Class.lpszClassName = ClassName.Buffer; } - - RtlMoveMemory(&Class, lpwcx, sizeof(WNDCLASSEXA)); - Class.lpszMenuName = MenuName.Buffer; - Class.lpszClassName = ClassName.Buffer; Atom = NtUserRegisterClassExWOW(&Class, FALSE, @@ -266,8 +270,14 @@ RegisterClassExA(CONST WNDCLASSEXA *lpwcx) 0, 0); - RtlFreeUnicodeString(&ClassName); - RtlFreeUnicodeString(&MenuName); + if (HIWORD((ULONG)lpwcx->lpszMenuName) != 0) + { + RtlFreeUnicodeString(&ClassName); + } + if (HIWORD((ULONG)lpwcx->lpszClassName )!= 0) + { + RtlFreeUnicodeString(&MenuName); + } return (ATOM)Atom; } @@ -281,7 +291,7 @@ RegisterClassExW(CONST WNDCLASSEXW *lpwcx) { RTL_ATOM Atom; - Atom = NtUserRegisterClassExWOW((WNDCLASSEX*)lpwcx, + Atom = NtUserRegisterClassExWOW((WNDCLASSEXW*)lpwcx, TRUE, 0, 0, diff --git a/reactos/subsys/win32k/include/class.h b/reactos/subsys/win32k/include/class.h index f83c199d895..74d74b0a15a 100644 --- a/reactos/subsys/win32k/include/class.h +++ b/reactos/subsys/win32k/include/class.h @@ -22,8 +22,7 @@ NTSTATUS FASTCALL CleanupClassImpl(VOID); NTSTATUS STDCALL -ClassReferenceClassByName(PW32PROCESS Process, - PWNDCLASS_OBJECT *Class, +ClassReferenceClassByName(PWNDCLASS_OBJECT *Class, LPWSTR ClassName); NTSTATUS FASTCALL @@ -35,7 +34,8 @@ ClassReferenceClassByNameOrAtom(PWNDCLASS_OBJECT *Class, LPWSTR ClassNameOrAtom); PWNDCLASS_OBJECT FASTCALL W32kCreateClass(LPWNDCLASSEXW lpwcx, - BOOL bUnicodeClass); + BOOL bUnicodeClass, + RTL_ATOM ClassName); struct _WINDOW_OBJECT; ULONG FASTCALL W32kGetClassLong(struct _WINDOW_OBJECT *WindowObject, ULONG Offset); diff --git a/reactos/subsys/win32k/ntuser/class.c b/reactos/subsys/win32k/ntuser/class.c index 172c49ec9da..eb8ebbd8720 100644 --- a/reactos/subsys/win32k/ntuser/class.c +++ b/reactos/subsys/win32k/ntuser/class.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: class.c,v 1.19 2003/07/11 17:08:44 chorns Exp $ +/* $Id: class.c,v 1.20 2003/07/27 21:35:50 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -56,13 +56,13 @@ CleanupClassImpl(VOID) } -NTSTATUS STDCALL -ClassReferenceClassByName(PW32PROCESS Process, - PWNDCLASS_OBJECT* Class, - LPWSTR ClassName) +NTSTATUS FASTCALL +ClassReferenceClassByAtom(PWNDCLASS_OBJECT* Class, + RTL_ATOM Atom) { PWNDCLASS_OBJECT Current; PLIST_ENTRY CurrentEntry; + PW32PROCESS Process = PsGetWin32Process(); ExAcquireFastMutexUnsafe (&Process->ClassListLock); CurrentEntry = Process->ClassListHead.Flink; @@ -70,7 +70,7 @@ ClassReferenceClassByName(PW32PROCESS Process, { Current = CONTAINING_RECORD(CurrentEntry, WNDCLASS_OBJECT, ListEntry); - if (_wcsicmp(ClassName, Current->Class.lpszClassName) == 0) + if (Current->Class.lpszClassName == (LPWSTR)(ULONG)Atom) { *Class = Current; ObmReferenceObject(Current); @@ -85,16 +85,15 @@ ClassReferenceClassByName(PW32PROCESS Process, return(STATUS_NOT_FOUND); } -NTSTATUS FASTCALL -ClassReferenceClassByAtom(PWNDCLASS_OBJECT *Class, - RTL_ATOM ClassAtom) +NTSTATUS STDCALL +ClassReferenceClassByName(PWNDCLASS_OBJECT *Class, + PWSTR ClassName) { PWINSTATION_OBJECT WinStaObject; - ULONG ClassNameLength; - WCHAR ClassName[256]; NTSTATUS Status; + RTL_ATOM ClassAtom; - if (!ClassAtom) + if (!ClassName) { return(STATUS_INVALID_PARAMETER); } @@ -110,20 +109,19 @@ ClassReferenceClassByAtom(PWNDCLASS_OBJECT *Class, return(STATUS_UNSUCCESSFUL); } - ClassNameLength = sizeof(ClassName); - Status = RtlQueryAtomInAtomTable(WinStaObject->AtomTable, - ClassAtom, - NULL, - NULL, - &ClassName[0], - &ClassNameLength); - - Status = ClassReferenceClassByName(PsGetWin32Process(), - Class, - &ClassName[0]); - - ObDereferenceObject(WinStaObject); + Status = RtlLookupAtomInAtomTable(WinStaObject->AtomTable, + ClassName, + &ClassAtom); + + if (!NT_SUCCESS(Status)) + { + ObDereferenceObject(WinStaObject); + return(Status); + } + Status = ClassReferenceClassByAtom(Class, + ClassAtom); + ObDereferenceObject(WinStaObject); return(Status); } @@ -140,7 +138,7 @@ ClassReferenceClassByNameOrAtom(PWNDCLASS_OBJECT *Class, } else { - Status = ClassReferenceClassByName(PsGetWin32Process(), Class, + Status = ClassReferenceClassByName(Class, ClassNameOrAtom); } @@ -185,15 +183,15 @@ NtUserGetWOWClass(DWORD Unknown0, PWNDCLASS_OBJECT FASTCALL W32kCreateClass(LPWNDCLASSEXW lpwcx, - BOOL bUnicodeClass) + BOOL bUnicodeClass, + RTL_ATOM Atom) { PWNDCLASS_OBJECT ClassObject; WORD objectSize; LPTSTR namePtr; objectSize = sizeof(WNDCLASS_OBJECT) + - (lpwcx->lpszMenuName != 0 ? ((wcslen (lpwcx->lpszMenuName) + 1) * 2) : 0) + - ((wcslen (lpwcx->lpszClassName) + 1) * 2); + (lpwcx->lpszMenuName != 0 ? ((wcslen (lpwcx->lpszMenuName) + 1) * 2) : 0); ClassObject = ObmCreateObject(NULL, NULL, otClass, objectSize); if (ClassObject == 0) { @@ -201,16 +199,14 @@ W32kCreateClass(LPWNDCLASSEXW lpwcx, } ClassObject->Class = *lpwcx; - ClassObject->Unicode = bUnicodeClass; - namePtr = (LPTSTR)(((PCHAR)ClassObject) + sizeof (WNDCLASS_OBJECT)); + ClassObject->Unicode = bUnicodeClass; if (lpwcx->lpszMenuName != 0) { + namePtr = (LPTSTR)(((PCHAR)ClassObject) + sizeof (WNDCLASS_OBJECT)); ClassObject->Class.lpszMenuName = namePtr; wcscpy (namePtr, lpwcx->lpszMenuName); - namePtr += wcslen (lpwcx->lpszMenuName) + 1; } - ClassObject->Class.lpszClassName = namePtr; - wcscpy (namePtr, lpwcx->lpszClassName); + ClassObject->Class.lpszClassName = (LPWSTR)(ULONG)Atom; return(ClassObject); } @@ -250,23 +246,31 @@ NtUserRegisterClassExWOW(LPWNDCLASSEXW lpwcx, PROCESS_WINDOW_STATION()); return((RTL_ATOM)0); } - - Status = RtlAddAtomToAtomTable(WinStaObject->AtomTable, - (LPWSTR)lpwcx->lpszClassName, - &Atom); - if (!NT_SUCCESS(Status)) + if (!IS_ATOM(lpwcx->lpszClassName)) { - ObDereferenceObject(WinStaObject); - DPRINT("Failed adding class name (%wS) to atom table\n", - lpwcx->lpszClassName); - SetLastNtError(Status); - - return((RTL_ATOM)0); + Status = RtlAddAtomToAtomTable(WinStaObject->AtomTable, + (LPWSTR)lpwcx->lpszClassName, + &Atom); + if (!NT_SUCCESS(Status)) + { + ObDereferenceObject(WinStaObject); + DPRINT("Failed adding class name (%wS) to atom table\n", + lpwcx->lpszClassName); + SetLastNtError(Status); + return((RTL_ATOM)0); + } } - ClassObject = W32kCreateClass(lpwcx, bUnicodeClass); + else + { + Atom = (RTL_ATOM)(ULONG)lpwcx->lpszClassName; + } + ClassObject = W32kCreateClass(lpwcx, bUnicodeClass, Atom); if (ClassObject == NULL) { - RtlDeleteAtomFromAtomTable(WinStaObject->AtomTable, Atom); + if (!IS_ATOM(lpwcx->lpszClassName)) + { + RtlDeleteAtomFromAtomTable(WinStaObject->AtomTable, Atom); + } ObDereferenceObject(WinStaObject); DPRINT("Failed creating window class object\n"); SetLastNtError(STATUS_INSUFFICIENT_RESOURCES); diff --git a/reactos/subsys/win32k/ntuser/winsta.c b/reactos/subsys/win32k/ntuser/winsta.c index fe29ebb3e9b..4d991ec5c84 100644 --- a/reactos/subsys/win32k/ntuser/winsta.c +++ b/reactos/subsys/win32k/ntuser/winsta.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: winsta.c,v 1.19 2003/07/27 11:54:42 dwelch Exp $ +/* $Id: winsta.c,v 1.20 2003/07/27 21:35:50 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -167,7 +167,7 @@ InitWindowStationImpl(VOID) wcx.hbrBackground = NULL; wcx.lpszMenuName = NULL; wcx.lpszClassName = L"DesktopWindowClass"; - DesktopWindowClass = W32kCreateClass(&wcx, TRUE); + DesktopWindowClass = W32kCreateClass(&wcx, TRUE, (RTL_ATOM)32880); return(STATUS_SUCCESS); }