* check return value of RtlDeleteAtomFromAtomTable

* simply, optimize, bugfix UserRegisterClass 
* allow de-registration for system classes
* set ERROR_CLASS_DOES_NOT_EXIST in case of errors
* reduces user32_winetest.exe class errors to 31 failures

svn path=/trunk/; revision=23082
This commit is contained in:
Johannes Anderwald 2006-07-16 15:16:55 +00:00
parent 6a8b5b1b25
commit 63a3c06ea0

View file

@ -171,10 +171,10 @@ IntRegisterClassAtom(IN PUNICODE_STRING ClassName,
return TRUE; return TRUE;
} }
static VOID static NTSTATUS
IntDeregisterClassAtom(IN RTL_ATOM Atom) IntDeregisterClassAtom(IN RTL_ATOM Atom)
{ {
RtlDeleteAtomFromAtomTable(gAtomTable, return RtlDeleteAtomFromAtomTable(gAtomTable,
Atom); Atom);
} }
@ -1147,39 +1147,29 @@ UserRegisterClass(IN CONST WNDCLASSEXW* lpwcx,
/* try to find a previously registered class */ /* try to find a previously registered class */
ClassAtom = IntGetClassAtom(ClassName, ClassAtom = IntGetClassAtom(ClassName,
NULL, lpwcx->hInstance,
NULL, pi,
NULL, &Class,
NULL); NULL);
if (ClassAtom != (RTL_ATOM)0) if (ClassAtom != (RTL_ATOM)0)
{ {
Class = IntFindClass(ClassAtom,
lpwcx->hInstance,
&pi->LocalClassList,
NULL);
if (Class != NULL)
{
goto ClassAlreadyExists;
}
/* if CS_GLOBALCLASS is set, try to find a previously registered global class.
Re-registering system classes as global classes seems to be allowed,
so we don't fail */
if (lpwcx->style & CS_GLOBALCLASS) if (lpwcx->style & CS_GLOBALCLASS)
{ {
Class = IntFindClass(ClassAtom, // global classes shall not have same names as system classes
NULL, if (Class->Global || Class->System)
((dwFlags & REGISTERCLASS_SYSTEM) ?
&pi->SystemClassList : &pi->GlobalClassList),
NULL);
if (Class != NULL)
{ {
ClassAlreadyExists:
DPRINT("Class 0x%p does already exist!\n", ClassAtom); DPRINT("Class 0x%p does already exist!\n", ClassAtom);
SetLastWin32Error(ERROR_CLASS_ALREADY_EXISTS); SetLastWin32Error(ERROR_CLASS_ALREADY_EXISTS);
return (RTL_ATOM)0; return (RTL_ATOM)0;
} }
} }
else if ( !Class->Global && !Class->System)
{
// local class already exists
DPRINT("Class 0x%p does already exist!\n", ClassAtom);
SetLastWin32Error(ERROR_CLASS_ALREADY_EXISTS);
return (RTL_ATOM)0;
}
} }
Class = IntCreateClass(lpwcx, Class = IntCreateClass(lpwcx,
@ -1244,13 +1234,6 @@ UserUnregisterClass(IN PUNICODE_STRING ClassName,
ASSERT(Class != NULL); ASSERT(Class != NULL);
if (Class->System)
{
DPRINT1("Attempted to unregister system class 0x%p!\n", ClassAtom);
SetLastWin32Error(ERROR_ACCESS_DENIED);
return FALSE;
}
if (Class->Windows != 0 || if (Class->Windows != 0 ||
Class->Clone != NULL) Class->Clone != NULL)
{ {
@ -1264,11 +1247,13 @@ UserUnregisterClass(IN PUNICODE_STRING ClassName,
/* unlink the class */ /* unlink the class */
*Link = Class->Next; *Link = Class->Next;
IntDeregisterClassAtom(Class->Atom); if (NT_SUCCESS(IntDeregisterClassAtom(Class->Atom)))
{
/* finally free the resources */ /* finally free the resources */
IntDestroyClass(Class); IntDestroyClass(Class);
return TRUE; return TRUE;
}
return FALSE;
} }
INT INT
@ -2117,7 +2102,6 @@ NtUserGetClassInfo(
{ {
goto Cleanup; goto Cleanup;
} }
_SEH_TRY _SEH_TRY
{ {
/* probe the paramters */ /* probe the paramters */
@ -2184,20 +2168,24 @@ InvalidParameter:
if (!(Class->Global || Class->System) && hInstance == NULL) if (!(Class->Global || Class->System) && hInstance == NULL)
{ {
SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST);
Ret = FALSE; Ret = FALSE;
} }
} }
} }
else
{
SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST);
}
} }
_SEH_HANDLE _SEH_HANDLE
{ {
SetLastNtError(_SEH_GetExceptionCode()); SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST);
} }
_SEH_END; _SEH_END;
Cleanup: Cleanup:
UserLeave(); UserLeave();
return Ret; return Ret;
} }