* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Win32k subsystem
* PURPOSE: Window classes
- * FILE: subsystems/win32/win32k/ntuser/class.c
+ * FILE: win32ss/user/ntuser/class.c
* PROGRAMER: Thomas Weidenmueller <w3seek@reactos.com>
*/
#include <win32k.h>
DBG_DEFAULT_CHANNEL(UserClass);
-BOOL FASTCALL IntClassDestroyIcon(HANDLE hCurIcon);
+static PWSTR ControlsList[] =
+{
+ L"Button",
+ L"Edit",
+ L"Static",
+ L"ListBox",
+ L"ScrollBar",
+ L"ComboBox",
+ L"MDIClient",
+ L"ComboLBox",
+ L"DDEMLEvent",
+ L"DDEMLMom",
+ L"DMGClass",
+ L"DDEMLAnsiClient",
+ L"DDEMLUnicodeClient",
+ L"DDEMLAnsiServer",
+ L"DDEMLUnicodeServer",
+ L"IME",
+ L"Ghost",
+};
+
static NTSTATUS IntDeregisterClassAtom(IN RTL_ATOM Atom);
REGISTER_SYSCLASS DefaultServerClasses[] =
CS_GLOBALCLASS|CS_DBLCLKS,
NULL, // Use User32 procs
sizeof(ULONG)*2,
- (HICON)IDC_ARROW,
+ (HICON)OCR_NORMAL,
(HBRUSH)(COLOR_BACKGROUND),
FNID_DESKTOP,
ICLS_DESKTOP
CS_VREDRAW|CS_HREDRAW|CS_SAVEBITS,
NULL, // Use User32 procs
sizeof(LONG),
- (HICON)IDC_ARROW,
+ (HICON)OCR_NORMAL,
NULL,
FNID_SWITCH,
ICLS_SWITCH
CS_DBLCLKS|CS_SAVEBITS,
NULL, // Use User32 procs
sizeof(LONG),
- (HICON)IDC_ARROW,
+ (HICON)OCR_NORMAL,
(HBRUSH)(COLOR_MENU + 1),
FNID_MENU,
ICLS_MENU
CS_DBLCLKS|CS_VREDRAW|CS_HREDRAW|CS_PARENTDC,
NULL, // Use User32 procs
sizeof(SBWND)-sizeof(WND),
- (HICON)IDC_ARROW,
+ (HICON)OCR_NORMAL,
NULL,
FNID_SCROLLBAR,
ICLS_SCROLLBAR
CS_PARENTDC|CS_DBLCLKS,
NULL, // Use User32 procs
0,
- (HICON)IDC_ARROW,
+ (HICON)OCR_NORMAL,
0,
FNID_TOOLTIPS,
ICLS_TOOLTIPS
0,
NULL, // Use User32 procs
0,
- (HICON)IDC_ARROW,
+ (HICON)OCR_NORMAL,
0,
FNID_ICONTITLE,
ICLS_ICONTITLE
CS_GLOBALCLASS,
NULL, // Use User32 procs
0,
- (HICON)IDC_ARROW,
+ (HICON)OCR_NORMAL,
NULL,
FNID_MESSAGEWND,
ICLS_HWNDMESSAGE
// Fixes running the static test then run class test issue.
// Some applications do not use UnregisterClass before exiting.
- // Keep from reusing the same atom with case insensitive
+ // Keep from reusing the same atom with case insensitive
// 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)
{
IntFreeClassMenuName(Class);
}
-#ifdef NEW_CURSORICON
if (Class->spicn)
UserDereferenceObject(Class->spicn);
if (Class->spcur)
UserDereferenceObject(Class->spcur);
if (Class->spicnSm)
+ {
UserDereferenceObject(Class->spicnSm);
-#else
- if (Class->hIconSmIntern)
- IntClassDestroyIcon(Class->hIconSmIntern);
-#endif
+ /* Destroy the icon if we own it */
+ if ((Class->CSF_flags & CSF_CACHEDSMICON)
+ && !(UserObjectInDestroy(UserHMGetHandle(Class->spicnSm))))
+ IntDestroyCurIconObject(Class->spicnSm);
+ }
pDesk = Class->rpdeskParent;
Class->rpdeskParent = NULL;
return TRUE;
}
+BOOL FASTCALL
+RegisterControlAtoms(VOID)
+{
+ RTL_ATOM Atom;
+ UNICODE_STRING ClassName;
+ INT i = 0;
+
+ while ( i < ICLS_DESKTOP)
+ {
+ RtlInitUnicodeString(&ClassName, ControlsList[i]);
+ if (IntRegisterClassAtom(&ClassName, &Atom))
+ {
+ gpsi->atomSysClass[i] = Atom;
+ TRACE("Reg Control Atom %ls: 0x%x\n", ControlsList[i], Atom);
+ }
+ i++;
+ }
+ return TRUE;
+}
+
static NTSTATUS
IntDeregisterClassAtom(IN RTL_ATOM Atom)
{
/* 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;
}
/* Simply clone the class */
RtlCopyMemory( Class, BaseClass, ClassSize);
-#ifdef NEW_CURSORICON
/* Reference our objects */
if (Class->spcur)
UserReferenceObject(Class->spcur);
UserReferenceObject(Class->spicn);
if (Class->spicnSm)
UserReferenceObject(Class->spicnSm);
-#endif
TRACE("Clone Class 0x%p hM 0x%p\n %S\n",Class, Class->hModule, Class->lpszClientUnicodeMenuName);
NewClass->rpdeskParent = NULL;
NewClass->pclsBase = NewClass;
-#ifdef NEW_CURSORICON
if (NewClass->spcur)
UserReferenceObject(NewClass->spcur);
if (NewClass->spicn)
UserReferenceObject(NewClass->spicn);
if (NewClass->spicnSm)
UserReferenceObject(NewClass->spicnSm);
-#endif
-
/* Replace the class in the list */
(void)InterlockedExchangePointer((PVOID*)*ClassLinkPtr,
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)
{
/* FIXME: The class was created before being connected
to a desktop. It is possible for the desktop window,
but should it be allowed for any other case? */
+ TRACE("This CLASS has no Desktop to heap from! Atom %u\n",Atom);
Class = UserHeapAlloc(ClassSize);
}
Class->rpdeskParent = Desktop;
Class->pclsBase = Class;
- Class->atomClassName = Atom;
+ Class->atomClassName = verAtom;
+ Class->atomNVClassName = Atom;
Class->fnid = fnID;
Class->CSF_flags = dwFlags;
- if (LookupFnIdToiCls(Class->fnid, &iCls))
+ if (LookupFnIdToiCls(Class->fnid, &iCls) && gpsi->atomSysClass[iCls] == 0)
{
gpsi->atomSysClass[iCls] = Class->atomClassName;
}
Class->cbclsExtra = lpwcx->cbClsExtra;
Class->cbwndExtra = lpwcx->cbWndExtra;
Class->hModule = lpwcx->hInstance;
-#ifdef NEW_CURSORICON
Class->spicn = lpwcx->hIcon ? UserGetCurIconObject(lpwcx->hIcon) : NULL;
Class->spcur = lpwcx->hCursor ? UserGetCurIconObject(lpwcx->hCursor) : NULL;
Class->spicnSm = lpwcx->hIconSm ? UserGetCurIconObject(lpwcx->hIconSm) : NULL;
-#else
- Class->hIcon = lpwcx->hIcon;
- Class->hIconSm = lpwcx->hIconSm;
- Class->hCursor = lpwcx->hCursor;
-#endif
////
Class->hbrBackground = lpwcx->hbrBackground;
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->lpfnWndProc, Atom, verAtom, Class->hModule, Class->Global);
return Class;
}
return Class;
}
+_Success_(return)
BOOL
NTAPI
IntGetAtomFromStringOrAtom(
}
else
{
- if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
- {
- EngSetLastError(ERROR_CLASS_DOES_NOT_EXIST);
- }
- else
+ if (Status != STATUS_OBJECT_NAME_NOT_FOUND)
{
SetLastNtError(Status);
}
ASSERT(BaseClass != NULL);
- if (IntGetAtomFromStringOrAtom(ClassName,
- &Atom) &&
+ if (IntGetAtomFromStringOrAtom(ClassName, &Atom) &&
Atom != (RTL_ATOM)0)
{
PCLS Class;
Link);
if (Class == NULL)
{
- EngSetLastError(ERROR_CLASS_DOES_NOT_EXIST);
return (RTL_ATOM)0;
}else{TRACE("Step 4: 0x%p\n",Class );}
FoundClass:
*BaseClass = Class;
}
+ else
+ {
+ Atom = 0;
+ }
return Atom;
}
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,
return Ret;
}
-#ifndef NEW_CURSORICON
-BOOL FASTCALL
-IntClassDestroyIcon(HANDLE hCurIcon)
-{
- PCURICON_OBJECT CurIcon;
- BOOL Ret;
-
- if (!(CurIcon = UserGetCurIconObject(hCurIcon)))
- {
-
- ERR("hCurIcon was not found!\n");
- return FALSE;
- }
- /* Note: IntDestroyCurIconObject will remove our reference for us! */
- Ret = IntDestroyCurIconObject(CurIcon, GetW32ProcessInfo());
- if (!Ret)
- {
- ERR("hCurIcon was not Destroyed!\n");
- }
- return Ret;
-}
-#endif
-
ULONG_PTR
UserSetClassLongPtr(IN PCLS Class,
IN INT Index,
IN BOOL Ansi)
{
ULONG_PTR Ret = 0;
-#ifndef NEW_CURSORICON
- HANDLE hIconSmIntern = NULL;
-#endif
/* NOTE: For GCLP_MENUNAME and GCW_ATOM this function may raise an exception! */
}
break;
-#ifdef NEW_CURSORICON
case GCLP_HCURSOR:
{
PCURICON_OBJECT NewCursor = NULL;
break;
}
-#else
- case GCLP_HCURSOR:
- /* FIXME: Get handle from pointer to CURSOR object */
- Ret = (ULONG_PTR)Class->hCursor;
- Class->hCursor = (HANDLE)NewLong;
-
- /* Update the clones */
- Class = Class->pclsClone;
- while (Class != NULL)
- {
- Class->hCursor = (HANDLE)NewLong;
- Class = Class->pclsNext;
- }
- break;
-#endif
// MSDN:
// hIconSm, A handle to a small icon that is associated with the window class.
// If this member is NULL, the system searches the icon resource specified by
// the hIcon member for an icon of the appropriate size to use as the small icon.
- //
+ //
case GCLP_HICON:
-#ifdef NEW_CURSORICON
{
PCURICON_OBJECT NewIcon = NULL;
PCURICON_OBJECT NewSmallIcon = NULL;
{
/* We will change the small icon */
UserDereferenceObject(Class->spicnSm);
+ IntDestroyCurIconObject(Class->spicnSm);
Class->spicnSm = NULL;
Class->CSF_flags &= ~CSF_CACHEDSMICON;
}
IMAGE_ICON,
UserGetSystemMetrics( SM_CXSMICON ),
UserGetSystemMetrics( SM_CYSMICON ),
- LR_COPYFROMRESOURCE | LR_SHARED);
+ LR_COPYFROMRESOURCE);
}
if (!SmallIconHandle)
{
IMAGE_ICON,
UserGetSystemMetrics( SM_CXSMICON ),
UserGetSystemMetrics( SM_CYSMICON ),
- LR_SHARED);
+ 0);
}
if (SmallIconHandle)
{
}
break;
}
-#else
- /* FIXME: Get handle from pointer to ICON object */
- Ret = (ULONG_PTR)Class->hIcon;
- if (Class->hIcon == (HANDLE)NewLong) break;
- if (Ret && Class->hIconSmIntern)
- {
- IntClassDestroyIcon(Class->hIconSmIntern);
- Class->CSF_flags &= ~CSF_CACHEDSMICON;
- Class->hIconSmIntern = NULL;
- }
- if (NewLong && !Class->hIconSm)
- {
- hIconSmIntern = Class->hIconSmIntern = co_IntCopyImage( (HICON)NewLong, IMAGE_ICON,
- UserGetSystemMetrics( SM_CXSMICON ),
- UserGetSystemMetrics( SM_CYSMICON ), 0 );
- Class->CSF_flags |= CSF_CACHEDSMICON;
- }
- Class->hIcon = (HANDLE)NewLong;
-
- /* Update the clones */
- Class = Class->pclsClone;
- while (Class != NULL)
- {
- Class->hIcon = (HANDLE)NewLong;
- Class->hIconSmIntern = hIconSmIntern;
- Class = Class->pclsNext;
- }
- break;
-#endif
case GCLP_HICONSM:
-#ifdef NEW_CURSORICON
{
PCURICON_OBJECT NewSmallIcon = NULL;
+ BOOLEAN NewIconFromCache = FALSE;
if (NewLong)
{
return 0;
}
}
+ else
+ {
+ /* Create the new small icon from the large one */
+ HICON SmallIconHandle = NULL;
+ if((Class->spicn->CURSORF_flags & (CURSORF_LRSHARED | CURSORF_FROMRESOURCE))
+ == (CURSORF_LRSHARED | CURSORF_FROMRESOURCE))
+ {
+ SmallIconHandle = co_IntCopyImage(
+ UserHMGetHandle(Class->spicn),
+ IMAGE_ICON,
+ UserGetSystemMetrics( SM_CXSMICON ),
+ UserGetSystemMetrics( SM_CYSMICON ),
+ LR_COPYFROMRESOURCE);
+ }
+ if (!SmallIconHandle)
+ {
+ /* Retry without copying from resource */
+ SmallIconHandle = co_IntCopyImage(
+ UserHMGetHandle(Class->spicn),
+ IMAGE_ICON,
+ UserGetSystemMetrics( SM_CXSMICON ),
+ UserGetSystemMetrics( SM_CYSMICON ),
+ 0);
+ }
+ if (SmallIconHandle)
+ {
+ /* So use it */
+ NewSmallIcon = UserGetCurIconObject(SmallIconHandle);
+ NewIconFromCache = TRUE;
+ }
+ else
+ {
+ ERR("Failed getting a small icon for the class.\n");
+ }
+ }
if (Class->spicnSm)
{
- Ret = (ULONG_PTR)UserHMGetHandle(Class->spicnSm);
+ if (Class->CSF_flags & CSF_CACHEDSMICON)
+ {
+ /* We must destroy the icon if we own it */
+ IntDestroyCurIconObject(Class->spicnSm);
+ Ret = 0;
+ }
+ else
+ {
+ Ret = (ULONG_PTR)UserHMGetHandle(Class->spicnSm);
+ }
UserDereferenceObject(Class->spicnSm);
}
else
Ret = 0;
}
- Class->CSF_flags &= ~CSF_CACHEDSMICON;
+ if (NewIconFromCache)
+ Class->CSF_flags |= CSF_CACHEDSMICON;
+ else
+ Class->CSF_flags &= ~CSF_CACHEDSMICON;
Class->spicnSm = NewSmallIcon;
/* Update the clones */
UserDereferenceObject(Class->spicnSm);
if (NewSmallIcon)
UserReferenceObject(NewSmallIcon);
- Class->CSF_flags &= ~CSF_CACHEDSMICON;
+ if (NewIconFromCache)
+ Class->CSF_flags |= CSF_CACHEDSMICON;
+ else
+ Class->CSF_flags &= ~CSF_CACHEDSMICON;
Class->spicnSm = NewSmallIcon;
Class = Class->pclsNext;
}
}
break;
-#else
- /* FIXME: Get handle from pointer to ICON object */
- Ret = (ULONG_PTR)Class->hIconSm;
- if (Class->hIconSm == (HANDLE)NewLong) break;
- if (Class->CSF_flags & CSF_CACHEDSMICON)
- {
- if (Class->hIconSmIntern)
- {
- IntClassDestroyIcon(Class->hIconSmIntern);
- Class->hIconSmIntern = NULL;
- }
- Class->CSF_flags &= ~CSF_CACHEDSMICON;
- }
- if (Class->hIcon && !Class->hIconSmIntern)
- {
- hIconSmIntern = Class->hIconSmIntern = co_IntCopyImage( Class->hIcon, IMAGE_ICON,
- UserGetSystemMetrics( SM_CXSMICON ),
- UserGetSystemMetrics( SM_CYSMICON ), 0 );
-
- if (hIconSmIntern) Class->CSF_flags |= CSF_CACHEDSMICON;
- //// FIXME: Very hacky here but it passes the tests....
- Ret = 0; // Fixes 1009
- }
- Class->hIconSm = (HANDLE)NewLong;
-
- /* Update the clones */
- Class = Class->pclsClone;
- while (Class != NULL)
- {
- Class->hIconSm = (HANDLE)NewLong;
- Class->hIconSmIntern = hIconSmIntern;
- Class = Class->pclsNext;
- }
- break;
-#endif
case GCLP_HMODULE:
Ret = (ULONG_PTR)Class->hModule;
{
PUNICODE_STRING Value = (PUNICODE_STRING)NewLong;
- Ret = (ULONG_PTR)Class->atomClassName;
+ Ret = (ULONG_PTR)Class->atomNVClassName;
if (!IntSetClassAtom(Class,
Value))
{
lpwcx->cbClsExtra = Class->cbclsExtra;
lpwcx->cbWndExtra = Class->cbwndExtra;
-#ifdef NEW_CURSORICON
lpwcx->hIcon = Class->spicn ? UserHMGetHandle(Class->spicn) : NULL;
lpwcx->hCursor = Class->spcur ? UserHMGetHandle(Class->spcur) : NULL;
lpwcx->hIconSm = Class->spicnSm ? UserHMGetHandle(Class->spicnSm) : NULL;
-#else
- lpwcx->hIcon = Class->hIcon; /* FIXME: Get handle from pointer */
- lpwcx->hCursor = Class->hCursor; /* FIXME: Get handle from pointer */
- /* FIXME: Get handle from pointer */
- lpwcx->hIconSm = Class->hIconSm ? Class->hIconSm : Class->hIconSmIntern;
-#endif
lpwcx->hbrBackground = Class->hbrBackground;
/* Copy non-string to user first. */
}
//
-// ???
+// Register System Classes....
//
BOOL
FASTCALL
wc.cbClsExtra = 0;
wc.cbWndExtra = DefaultServerClasses[i].ExtraBytes;
wc.hIcon = NULL;
- wc.hCursor = DefaultServerClasses[i].hCursor;
+
+ //// System Cursors should be initilized!!!
+ wc.hCursor = NULL;
+ if (DefaultServerClasses[i].hCursor == (HICON)OCR_NORMAL)
+ {
+ if (SYSTEMCUR(ARROW) == NULL)
+ {
+ ERR("SYSTEMCUR(ARROW) == NULL, should not happen!!\n");
+ }
+ else
+ {
+ wc.hCursor = UserHMGetHandle(SYSTEMCUR(ARROW));
+ }
+ }
+
hBrush = DefaultServerClasses[i].hBrush;
if (hBrush <= (HBRUSH)COLOR_MENUBAR)
{
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;
if (Flags & ~(CSF_ANSIPROC))
{
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,
}
TRACE("NtUserRegisterClassExWOW MnuN %wZ\n",&CapturedMenuName);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ ERR("NtUserRegisterClassExWOW Exception Error!\n");
+ SetLastNtError(_SEH2_GetExceptionCode());
+ Exception = TRUE;
+ }
+ _SEH2_END;
+ if (!Exception)
+ {
/* Register the class */
Ret = UserRegisterClass(&CapturedClassInfo,
&CapturedName,
+ &CapturedVersion,
&CapturedMenuName,
fnID,
Flags);
}
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- ERR("NtUserRegisterClassExWOW Exception Error!\n");
- SetLastNtError(_SEH2_GetExceptionCode());
- }
- _SEH2_END;
-/*
+
if (!Ret)
{
- ERR("NtUserRegisterClassExWOW Null Return!\n");
+ TRACE("NtUserRegisterClassExWOW Null Return!\n");
}
- */
+
UserLeave();
return Ret;
/* 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