// comparisons, remove registration of the atom if not zeroed.
if (Class->atomClassName)
IntDeregisterClassAtom(Class->atomClassName);
+ // Dereference non-versioned class name
+ if (Class->atomNVClassName)
+ IntDeregisterClassAtom(Class->atomNVClassName);
if (Class->pdce)
{
- DceFreeClassDCE(((PDCE)Class->pdce)->hDC);
+ DceFreeClassDCE(Class->pdce);
Class->pdce = NULL;
}
if (IntRegisterClassAtom(&ClassName, &Atom))
{
gpsi->atomSysClass[i] = Atom;
- ERR("Reg Control Atoms 0x%x\n",Atom);
+ TRACE("Reg Control Atom %ls: 0x%x\n", ControlsList[i], Atom);
}
i++;
}
/* Update the base class first */
Class = Class->pclsBase;
-
- if (!IntRegisterClassAtom(ClassName,
- &Atom))
+ if (ClassName->Length > 0)
{
- return FALSE;
+ if (!IntRegisterClassAtom(ClassName,
+ &Atom))
+ {
+ ERR("RegisterClassAtom failed ! %x\n", EngGetLastError());
+ return FALSE;
+ }
+ }
+ else
+ {
+ if (IS_ATOM(ClassName->Buffer))
+ {
+ Atom = (ATOM)((ULONG_PTR)ClassName->Buffer & 0xffff); // XXX: are we missing refcount here ?
+ }
+ else
+ {
+ EngSetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
}
- IntDeregisterClassAtom(Class->atomClassName);
+ IntDeregisterClassAtom(Class->atomNVClassName);
- Class->atomClassName = Atom;
+ Class->atomNVClassName = Atom;
/* Update the clones */
Class = Class->pclsClone;
while (Class != NULL)
{
- Class->atomClassName = Atom;
+ Class->atomNVClassName = Atom;
Class = Class->pclsNext;
}
FASTCALL
IntCreateClass(IN CONST WNDCLASSEXW* lpwcx,
IN PUNICODE_STRING ClassName,
+ IN PUNICODE_STRING ClassVersion,
IN PUNICODE_STRING MenuName,
IN DWORD fnID,
IN DWORD dwFlags,
{
SIZE_T ClassSize;
PCLS Class = NULL;
- RTL_ATOM Atom;
+ RTL_ATOM Atom, verAtom;
WNDPROC WndProc;
PWSTR pszMenuName = NULL;
NTSTATUS Status = STATUS_SUCCESS;
return NULL;
}
+ if (!IntRegisterClassAtom(ClassVersion,
+ &verAtom))
+ {
+ ERR("Failed to register version class atom!\n");
+ IntDeregisterClassAtom(Atom);
+ return NULL;
+ }
+
ClassSize = sizeof(*Class) + lpwcx->cbClsExtra;
if (MenuName->Length != 0)
{
Class->rpdeskParent = Desktop;
Class->pclsBase = Class;
- Class->atomClassName = Atom;
+ Class->atomClassName = verAtom;
+ Class->atomNVClassName = Atom;
Class->fnid = fnID;
Class->CSF_flags = dwFlags;
Class);
Class = NULL;
+ IntDeregisterClassAtom(verAtom);
IntDeregisterClassAtom(Atom);
}
}
UserHeapFree(pszMenuName);
IntDeregisterClassAtom(Atom);
+ IntDeregisterClassAtom(verAtom);
EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
}
- TRACE("Created class 0x%p with name %wZ and proc 0x%p for atom 0x%x and hInstance 0x%p, global %u\n",
- Class, ClassName, Class->lpfnWndProc, Atom, Class->hModule, Class->Global);
+ TRACE("Created class 0x%p with name %wZ and proc 0x%p for atom 0x%x and version atom 0x%x and hInstance 0x%p, global %u\n",
+ Class, ClassName, Class ? Class->lpfnWndProc : NULL, Atom, verAtom,
+ Class ? Class->hModule : NULL , Class ? Class->Global : 0);
return Class;
}
}
else
{
- if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
- {
- EngSetLastError(ERROR_CLASS_DOES_NOT_EXIST);
- }
- else
+ if (Status != STATUS_OBJECT_NAME_NOT_FOUND)
{
SetLastNtError(Status);
}
Link);
if (Class == NULL)
{
- EngSetLastError(ERROR_CLASS_DOES_NOT_EXIST);
return (RTL_ATOM)0;
}else{TRACE("Step 4: 0x%p\n",Class );}
ERR("Class \"%wZ\" not found\n", ClassName);
}
- EngSetLastError(ERROR_CANNOT_FIND_WND_CLASS);
return NULL;
}
RTL_ATOM
UserRegisterClass(IN CONST WNDCLASSEXW* lpwcx,
IN PUNICODE_STRING ClassName,
+ IN PUNICODE_STRING ClassVersion,
IN PUNICODE_STRING MenuName,
IN DWORD fnID,
IN DWORD dwFlags)
pi = pti->ppi;
// Need only to test for two conditions not four....... Fix more whine tests....
- if ( IntGetAtomFromStringOrAtom( ClassName, &ClassAtom) &&
+ if ( IntGetAtomFromStringOrAtom( ClassVersion, &ClassAtom) &&
ClassAtom != (RTL_ATOM)0 &&
!(dwFlags & CSF_SERVERSIDEPROC) ) // Bypass Server Sides
{
Class = IntCreateClass(lpwcx,
ClassName,
+ ClassVersion,
MenuName,
fnID,
dwFlags,
(void)InterlockedExchangePointer((PVOID*)List,
Class);
- Ret = Class->atomClassName;
+ Ret = Class->atomNVClassName;
}
else
{
&Link);
if (ClassAtom == (RTL_ATOM)0)
{
+ EngSetLastError(ERROR_CLASS_DOES_NOT_EXIST);
TRACE("UserUnregisterClass: No Class found.\n");
return FALSE;
}
/* Query the class name */
Status = RtlQueryAtomInAtomTable(gAtomTable,
- Atom ? Atom : Class->atomClassName,
+ Atom ? Atom : Class->atomNVClassName,
NULL,
NULL,
szTemp,
/* Query the atom name */
Status = RtlQueryAtomInAtomTable(gAtomTable,
- Atom ? Atom : Class->atomClassName,
+ Atom ? Atom : Class->atomNVClassName,
NULL,
NULL,
ClassName->Buffer,
{
PUNICODE_STRING Value = (PUNICODE_STRING)NewLong;
- Ret = (ULONG_PTR)Class->atomClassName;
+ Ret = (ULONG_PTR)Class->atomNVClassName;
if (!IntSetClassAtom(Class,
Value))
{
wc.hIcon = NULL;
//// System Cursors should be initilized!!!
- if (DefaultServerClasses[i].hCursor == (HICON)OCR_NORMAL &&
- SYSTEMCUR(ARROW) != NULL)
+ wc.hCursor = NULL;
+ if (DefaultServerClasses[i].hCursor == (HICON)OCR_NORMAL)
{
- wc.hCursor = UserHMGetHandle(SYSTEMCUR(ARROW));
- }
- else
- {
- ERR("SYSTEMCUR(ARROW) == NULL, should not happen!!\n");
- wc.hCursor = NULL;
+ if (SYSTEMCUR(ARROW) == NULL)
+ {
+ ERR("SYSTEMCUR(ARROW) == NULL, should not happen!!\n");
+ }
+ else
+ {
+ wc.hCursor = UserHMGetHandle(SYSTEMCUR(ARROW));
+ }
}
hBrush = DefaultServerClasses[i].hBrush;
wc.hIconSm = NULL;
Class = IntCreateClass( &wc,
+ &ClassName,
&ClassName,
&MenuName,
DefaultServerClasses[i].fiId,
NtUserRegisterClassExWOW(
WNDCLASSEXW* lpwcx,
PUNICODE_STRING ClassName,
- PUNICODE_STRING ClsNVersion,
+ PUNICODE_STRING ClsVersion,
PCLSMENUNAME pClassMenuName,
DWORD fnID,
DWORD Flags,
*/
{
WNDCLASSEXW CapturedClassInfo = {0};
- UNICODE_STRING CapturedName = {0}, CapturedMenuName = {0};
+ UNICODE_STRING CapturedName = {0}, CapturedMenuName = {0}, CapturedVersion = {0};
RTL_ATOM Ret = (RTL_ATOM)0;
PPROCESSINFO ppi = GetW32ProcessInfo();
BOOL Exception = FALSE;
sizeof(WNDCLASSEXW));
CapturedName = ProbeForReadUnicodeString(ClassName);
+ CapturedVersion = ProbeForReadUnicodeString(ClsVersion);
ProbeForRead(pClassMenuName,
sizeof(CLSMENUNAME),
}
}
+ if (CapturedVersion.Length != 0)
+ {
+ ProbeForRead(CapturedVersion.Buffer,
+ CapturedVersion.Length,
+ sizeof(WCHAR));
+ }
+ else
+ {
+ if (!IS_ATOM(CapturedVersion.Buffer))
+ {
+ ERR("NtUserRegisterClassExWOW ClassName Error!\n");
+ goto InvalidParameter;
+ }
+ }
+
if (CapturedMenuName.Length != 0)
{
ProbeForRead(CapturedMenuName.Buffer,
/* Register the class */
Ret = UserRegisterClass(&CapturedClassInfo,
&CapturedName,
+ &CapturedVersion,
&CapturedMenuName,
fnID,
Flags);
/* Probe the parameters */
if (Offset == GCW_ATOM || Offset == GCLP_MENUNAME)
{
- Value = ProbeForReadUnicodeString((PUNICODE_STRING)dwNewLong);
+ /* FIXME: Resource ID can be passed directly without UNICODE_STRING ? */
+ if (IS_ATOM(dwNewLong))
+ {
+ Value.MaximumLength = 0;
+ Value.Length = 0;
+ Value.Buffer = (PWSTR)dwNewLong;
+ }
+ else
+ {
+ Value = ProbeForReadUnicodeString((PUNICODE_STRING)dwNewLong);
+ }
+
if (Value.Length & 1)
{
goto InvalidParameter;
Offset,
dwNewLong,
Ansi);
+ switch(Offset)
+ {
+ case GCLP_HICONSM:
+ case GCLP_HICON:
+ {
+ if (Ret && Ret != dwNewLong)
+ UserPaintCaption(Window, DC_ICON);
+ }
+ }
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
// If null instance use client.
if (!hInstance) hInstance = hModClient;
- TRACE("GetClassInfo(%wZ, %p)\n", SafeClassName, hInstance);
+ TRACE("GetClassInfo(%wZ, %p)\n", &SafeClassName, hInstance);
/* NOTE: Need exclusive lock because getting the wndproc might require the
creation of a call procedure handle */
NULL);
if (ClassAtom != (RTL_ATOM)0)
{
+ ClassAtom = Class->atomNVClassName;
Ret = UserGetClassInfo(Class, &Safewcexw, bAnsi, hInstance);
}
else