Author: gadamopoulos
Date: Fri Feb 17 11:07:14 2017
New Revision: 73806

URL: http://svn.reactos.org/svn/reactos?rev=73806&view=rev
Log:
[WIN32k]
 -Fix a couple of cases where we use the versioned class atom instead of the 
non versioned one.

[USER32]
- Add support for versioned classes in RegisterClassExWOWW, GetClassInfoExW, 
GetClassInfoExA, UnregisterClassA, UnregisterClassW, and User32CreateWindowEx
- Make ClassNameToVersion return the name of the versioned class and the 
library name that implements it while preserving a hack that lets user32 know 
which classes are registered by comctl32 (this is needed because the default 
activation context doesn't contain the non versioned classes yet).
- Make VersionRegisterClass to load the specified library and make it register 
its classes which is used when the class is not registered yet but its manifest 
is active.

Modified:
    trunk/reactos/win32ss/user/ntuser/class.c
    trunk/reactos/win32ss/user/ntuser/window.c
    trunk/reactos/win32ss/user/user32/windows/class.c
    trunk/reactos/win32ss/user/user32/windows/window.c

Modified: trunk/reactos/win32ss/user/ntuser/class.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/class.c?rev=73806&r1=73805&r2=73806&view=diff
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/class.c   [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/class.c   [iso-8859-1] Fri Feb 17 
11:07:14 2017
@@ -2743,6 +2743,7 @@
                                 NULL);
     if (ClassAtom != (RTL_ATOM)0)
     {
+        ClassAtom = Class->atomNVClassName;
         Ret = UserGetClassInfo(Class, &Safewcexw, bAnsi, hInstance);
     }
     else

Modified: trunk/reactos/win32ss/user/ntuser/window.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/window.c?rev=73806&r1=73805&r2=73806&view=diff
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/window.c  [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/window.c  [iso-8859-1] Fri Feb 17 
11:07:14 2017
@@ -2807,7 +2807,7 @@
          /* Do not send WM_GETTEXT messages in the kernel mode version!
             The user mode version however calls GetWindowText() which will
             send WM_GETTEXT messages to windows belonging to its processes */
-         if (!ClassAtom || Child->pcls->atomClassName == ClassAtom)
+         if (!ClassAtom || Child->pcls->atomNVClassName == ClassAtom)
          {
              // FIXME: LARGE_STRING truncated
              CurrentWindowName.Buffer = Child->strName.Buffer;
@@ -2999,7 +2999,7 @@
                                 (TopLevelWindow->strName.Length < 0xFFFF &&
                                  !RtlCompareUnicodeString(&WindowName, &ustr, 
TRUE));
                 ClassMatches = (ClassAtom == (RTL_ATOM)0) ||
-                               ClassAtom == 
TopLevelWindow->pcls->atomClassName;
+                               ClassAtom == 
TopLevelWindow->pcls->atomNVClassName;
 
                 if (WindowMatches && ClassMatches)
                 {

Modified: trunk/reactos/win32ss/user/user32/windows/class.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/user32/windows/class.c?rev=73806&r1=73805&r2=73806&view=diff
==============================================================================
--- trunk/reactos/win32ss/user/user32/windows/class.c   [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/user32/windows/class.c   [iso-8859-1] Fri Feb 17 
11:07:14 2017
@@ -13,177 +13,38 @@
 #include <wine/debug.h>
 WINE_DEFAULT_DEBUG_CHANNEL(user32);
 
+#define USE_VERSIONED_CLASSES
+
 /* From rtl/actctx.c and must match! */
-struct entity
-{
-    DWORD  kind;  // Activation context type
-    WCHAR *name;  // Class name
-    WCHAR *clsid; // Not supported yet but needed for menu name.
+struct strsection_header
+{
+    DWORD magic;
+    ULONG size;
+    DWORD unk1[3];
+    ULONG count;
+    ULONG index_offset;
+    DWORD unk2[2];
+    ULONG global_offset;
+    ULONG global_len;
 };
 
-struct dll_redirect
-{
-    WCHAR *name; // Dll name
-    WCHAR *hash;
-    DWORD  Data; // Junk
+struct wndclass_redirect_data
+{
+    ULONG size;
+    DWORD res;
+    ULONG name_len;
+    ULONG name_offset;  /* versioned name offset */
+    ULONG module_len;
+    ULONG module_offset;/* container name offset */
 };
 
-LPCWSTR
-FASTCALL
-ClassNameToVersion(
-  LPCTSTR lpszClass,
-  LPCWSTR lpszMenuName,
-  LPCWSTR *plpLibFileName,
-  HANDLE *pContext,
-  BOOL bAnsi)
-{
-    NTSTATUS Status;
-    UNICODE_STRING SectionName;
-    WCHAR SeactionNameBuf[MAX_PATH] = {0};
-    ACTCTX_SECTION_KEYED_DATA KeyedData = { sizeof(KeyedData) };
-
-    if (IS_ATOM(lpszClass))
-    {
-        SectionName.Buffer = (LPWSTR)&SeactionNameBuf;
-        SectionName.MaximumLength = sizeof(SeactionNameBuf);
-        if(!NtUserGetAtomName(LOWORD((DWORD_PTR)lpszClass), &SectionName))
-        {
-            return NULL;
-        }
-    }
-    else
-    {
-        if (bAnsi)
-        {
-            RtlCreateUnicodeStringFromAsciiz(&SectionName, (LPSTR)lpszClass);
-        }
-        else
-        {
-            RtlInitUnicodeString(&SectionName, lpszClass);
-        }
-    }
-    Status = RtlFindActivationContextSectionString( 
FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX,
-                                                    NULL,
-                                                    
ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION,
-                                                   &SectionName,
-                                                   &KeyedData );
-
-    if (NT_SUCCESS(Status) && KeyedData.ulDataFormatVersion == 1)
-    {
-        struct dll_redirect *dll = KeyedData.lpSectionBase;
-
-        if (plpLibFileName) *plpLibFileName = dll->name;
-
-        if (lpszMenuName)
-        {
-            WCHAR * mnubuf;
-            LPWSTR mnuNameW;
-            LPSTR mnuNameA;
-            int len = 0;
-            struct entity *entity = KeyedData.lpData;
-
-            FIXME("actctx: Needs to support menu name from redirected class!");
-
-            if (entity->clsid)
-            {
-                mnubuf = entity->clsid;
-                if (bAnsi)
-                {
-                    mnuNameA = (LPSTR)lpszMenuName;
-                    RtlUnicodeToMultiByteN( mnuNameA, 255, (PULONG)&len, 
mnubuf, strlenW(mnubuf) * sizeof(WCHAR) );
-                    mnuNameA[len] = 0;
-                }
-                else
-                {
-                    mnuNameW = (LPWSTR)lpszMenuName;
-                    len = strlenW(mnubuf) * sizeof(WCHAR);
-                    RtlCopyMemory((void *)mnuNameW, mnubuf, len);
-                    mnuNameW[len] = 0;
-                }
-            }
-        }
-        if (pContext) *pContext = KeyedData.hActCtx;
-    }
-
-    if (!IS_ATOM(lpszClass) && bAnsi)
-        RtlFreeUnicodeString(&SectionName);
-    if (KeyedData.hActCtx)
-        RtlReleaseActivationContext(KeyedData.hActCtx);
-
-    return lpszClass;
-}
-
 //
-// Ref: http://yvs-it.blogspot.com/2010/04/initcommoncontrolsex.html
-//
-BOOL
-FASTCALL
-Real_VersionRegisterClass(
-  PCWSTR pszClass,
-  LPCWSTR lpLibFileName,
-  HANDLE Contex,
-  HMODULE * phLibModule)
-{
-    BOOL Ret;
-    HMODULE hLibModule;
-    PREGISTERCLASSNAMEW pRegisterClassNameW;
-    UNICODE_STRING ClassName;
-    WCHAR ClassNameBuf[MAX_PATH] = {0};
-    RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED Frame = { 
sizeof(Frame), 1 };
-
-    RtlActivateActivationContextUnsafeFast(&Frame, Contex);
-
-    Ret = FALSE;
-    hLibModule = NULL;
-
-    _SEH2_TRY
-    {
-        hLibModule = LoadLibraryW(lpLibFileName);
-        if ( hLibModule )
-        {
-            if ((pRegisterClassNameW = (void*) GetProcAddress(hLibModule, 
"RegisterClassNameW")))
-            {
-                if (IS_ATOM(pszClass))
-                {
-                    ClassName.Buffer = (LPWSTR)&ClassNameBuf;
-                    ClassName.MaximumLength = sizeof(ClassNameBuf);
-                    if (!NtUserGetAtomName(LOWORD((DWORD_PTR)pszClass), 
&ClassName))
-                    {
-                        _SEH2_YIELD(goto Error_Exit);
-                    }
-                    pszClass = (PCWSTR)&ClassNameBuf;
-                }
-                Ret = pRegisterClassNameW(pszClass);
-            }
-        }
-    }
-    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-    {
-    }
-    _SEH2_END
-
-Error_Exit:
-    if ( Ret || !hLibModule )
-    {
-        if ( phLibModule ) *phLibModule = hLibModule;
-    }
-    else
-    {
-        DWORD save_error = GetLastError();
-        FreeLibrary(hLibModule);
-        SetLastError(save_error);
-    }
-
-    return Ret;
-}
-
-//
-// Use wine hack to process extened context classes.
+// Use wine hack to process extended context classes.
 //
 /***********************************************************************
  *           is_comctl32_class
  */
-static BOOL is_comctl32_class( const WCHAR *name )
+LPCWSTR is_comctl32_class( const WCHAR *name )
 {
     static const WCHAR classesW[][20] =
     {
@@ -213,13 +74,121 @@
     while (min <= max)
     {
         int res, pos = (min + max) / 2;
-        if (!(res = strcmpiW( name, classesW[pos] ))) return TRUE;
+        if (!(res = strcmpiW( name, classesW[pos] ))) return classesW[pos];
         if (res < 0) max = pos - 1;
         else min = pos + 1;
     }
-    return FALSE;
-}
-
+    return NULL;
+}
+
+LPCWSTR
+FASTCALL
+ClassNameToVersion(
+  const void* lpszClass,
+  LPCWSTR lpszMenuName,
+  LPCWSTR *plpLibFileName,
+  HANDLE *pContext,
+  BOOL bAnsi)
+{
+    LPCWSTR VersionedClass = NULL;
+    NTSTATUS Status;
+    UNICODE_STRING SectionName;
+    WCHAR SectionNameBuf[MAX_PATH] = {0};
+    ACTCTX_SECTION_KEYED_DATA KeyedData = { sizeof(KeyedData) };
+
+    if(!lpszClass)
+    {
+        ERR("Null class given !\n");
+        return NULL;
+    }
+
+    if (IS_ATOM(lpszClass))
+    {
+        RtlInitEmptyUnicodeString(&SectionName, SectionNameBuf, 
sizeof(SectionNameBuf));
+        if(!NtUserGetAtomName(LOWORD((DWORD_PTR)lpszClass), &SectionName))
+        {
+            ERR("Couldn't get atom name for atom %x !\n", 
LOWORD((DWORD_PTR)lpszClass));
+            return NULL;
+        }
+        SectionName.Length = wcslen(SectionNameBuf) * sizeof(WCHAR);
+        TRACE("ClassNameToVersion got name %wZ from atom\n", &SectionName);
+    }
+    else
+    {
+        if (bAnsi)
+        {
+            ANSI_STRING AnsiString;
+            RtlInitAnsiString(&AnsiString, lpszClass);
+            RtlInitEmptyUnicodeString(&SectionName, SectionNameBuf, 
sizeof(SectionNameBuf));
+            RtlAnsiStringToUnicodeString(&SectionName, &AnsiString, FALSE);
+        }
+        else
+        {
+            RtlInitUnicodeString(&SectionName, lpszClass);
+        }
+    }
+    Status = RtlFindActivationContextSectionString( 
FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX,
+                                                    NULL,
+                                                    
ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION,
+                                                   &SectionName,
+                                                   &KeyedData );
+
+#ifdef USE_VERSIONED_CLASSES
+    if (NT_SUCCESS(Status) && KeyedData.ulDataFormatVersion == 1)
+    {
+        struct strsection_header *SectionHeader = KeyedData.lpSectionBase;
+
+        /* Find activation context */
+        if(SectionHeader && SectionHeader->count > 0)
+        {
+            struct wndclass_redirect_data *WindowRedirectionData = 
KeyedData.lpData;
+            if(WindowRedirectionData && WindowRedirectionData->module_len)
+            {
+                LPCWSTR lpLibFileName;
+
+                VersionedClass = (WCHAR*)((BYTE*)WindowRedirectionData + 
WindowRedirectionData->name_offset);
+                lpLibFileName = (WCHAR*)((BYTE*)KeyedData.lpSectionBase + 
WindowRedirectionData->module_offset);
+                TRACE("Returning VersionedClass=%S, plpLibFileName=%S for 
class %S\n", VersionedClass, lpLibFileName, SectionName.Buffer);
+
+                if (pContext) *pContext = KeyedData.hActCtx;
+                if (plpLibFileName) *plpLibFileName = lpLibFileName;
+
+            }
+        }
+    }
+
+    if (KeyedData.hActCtx)
+        RtlReleaseActivationContext(KeyedData.hActCtx);
+#endif
+
+#ifndef DEFAULT_ACTIVATION_CONTEXTS_SUPPORTED
+    /* This block is a hack! */
+    if (!VersionedClass)
+    {
+        /* 
+         * In windows the default activation context always contains 
comctl32v5 
+         * In reactos we don't have a default activation context so we 
+         * mimic wine here.
+         */
+        VersionedClass = is_comctl32_class(SectionName.Buffer);
+        if (VersionedClass)
+        {
+            if (pContext) *pContext = 0;
+            if (plpLibFileName) *plpLibFileName = L"comctl32";
+        }
+    }
+#endif
+
+    /* 
+     * The returned strings are pointers in the activation context and 
+     * will get freed when the activation context gets freed 
+     */
+    return VersionedClass;
+}
+
+//
+// Ref: http://yvs-it.blogspot.com/2010/04/initcommoncontrolsex.html
+//
 BOOL
 FASTCALL
 VersionRegisterClass(
@@ -228,64 +197,61 @@
   HANDLE Contex,
   HMODULE * phLibModule)
 {
-    // Should be lpLibFileName.....
-    static const WCHAR comctl32W[] = 
{'c','o','m','c','t','l','3','2','.','d','l','l',0};
-    //
+    BOOL Ret = FALSE;
+    HMODULE hLibModule = NULL;
     PREGISTERCLASSNAMEW pRegisterClassNameW;
     UNICODE_STRING ClassName;
     WCHAR ClassNameBuf[MAX_PATH] = {0};
-    BOOL Ret = FALSE;
-    HMODULE hLibModule = NULL;
-
-    if (!IS_ATOM(pszClass) && is_comctl32_class( pszClass ))
-    {
-        _SEH2_TRY
-        {
-            hLibModule = LoadLibraryW(comctl32W);
-            if ( hLibModule )
+    RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED Frame = { 
sizeof(Frame), 1 };
+
+    RtlActivateActivationContextUnsafeFast(&Frame, Contex);
+
+    _SEH2_TRY
+    {
+        hLibModule = LoadLibraryW(lpLibFileName);
+        if ( hLibModule )
+        {
+            if ((pRegisterClassNameW = (void*) GetProcAddress(hLibModule, 
"RegisterClassNameW")))
             {
-                if ((pRegisterClassNameW = (void*) GetProcAddress(hLibModule, 
"RegisterClassNameW")))
+                if (IS_ATOM(pszClass))
                 {
-                    if (IS_ATOM(pszClass))
+                    ClassName.Buffer = ClassNameBuf;
+                    ClassName.MaximumLength = sizeof(ClassNameBuf);
+                    if (!NtUserGetAtomName(LOWORD((DWORD_PTR)pszClass), 
&ClassName))
                     {
-                        ClassName.Buffer = (LPWSTR)&ClassNameBuf;
-                        ClassName.MaximumLength = sizeof(ClassNameBuf);
-                        if (!NtUserGetAtomName(LOWORD((DWORD_PTR)pszClass), 
&ClassName))
-                        {
-                            ERR("Error while verifying ATOM\n");
-                            _SEH2_YIELD(goto Error_Exit);
-                        }
-                        pszClass = (PCWSTR)&ClassNameBuf;
+                        ERR("Error while verifying ATOM\n");
+                        _SEH2_YIELD(goto Error_Exit);
                     }
-                    Ret = pRegisterClassNameW(pszClass);
+                    pszClass = ClassName.Buffer;
                 }
+                Ret = pRegisterClassNameW(pszClass);
             }
-        }
-        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-        {
-        }
-        _SEH2_END
+            else
+            {
+                WARN("No RegisterClassNameW PROC\n");
+            }
+        }
+    }
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+    {
+    }
+    _SEH2_END
 
 Error_Exit:
-        if ( Ret || !hLibModule )
-        {
-            if ( phLibModule ) *phLibModule = hLibModule;
-        }
-        else
-        {
-            DWORD save_error = GetLastError();
-            FreeLibrary(hLibModule);
-            SetLastError(save_error);
-        }
-        TRACE( "%s retrying after loading comctl32\n", debugstr_w(pszClass) );
-        return Ret;
-    }
-    TRACE("NO ComCtl32 Class %S!\n",pszClass);
-    return FALSE;
-}
-//
-//
-//
+    if ( Ret || !hLibModule )
+    {
+        if ( phLibModule ) *phLibModule = hLibModule;
+    }
+    else
+    {
+        DWORD save_error = GetLastError();
+        FreeLibrary(hLibModule);
+        SetLastError(save_error);
+    }
+
+    RtlDeactivateActivationContextUnsafeFast(&Frame);
+    return Ret;
+}
 
 /*
  * @implemented
@@ -301,7 +267,10 @@
     LPCSTR pszMenuName;
     HMODULE hLibModule = NULL;
     DWORD save_error;
-    BOOL Ret, ClassFound = FALSE;
+    BOOL Ret, ClassFound = FALSE, ConvertedString = FALSE;
+    LPCWSTR lpszClsVersion;
+    HANDLE pCtx = NULL;
+    LPCWSTR lpLibFileName = NULL;
 
     TRACE("%p class/atom: %s/%04x %p\n", hInstance,
         IS_ATOM(lpszClass) ? NULL : lpszClass,
@@ -325,14 +294,19 @@
         return FALSE;
     }
 
-    if (IS_ATOM(lpszClass))
+    lpszClsVersion = ClassNameToVersion(lpszClass, NULL, &lpLibFileName, 
&pCtx, TRUE);
+    if (lpszClsVersion)
+    {
+        RtlInitUnicodeString(&ClassName, lpszClsVersion);
+    }
+    else if (IS_ATOM(lpszClass))
     {
         ClassName.Buffer = (PWSTR)((ULONG_PTR)lpszClass);
     }
     else
     {
-        if (!RtlCreateUnicodeStringFromAsciiz(&ClassName,
-                                              lpszClass))
+        ConvertedString = TRUE;
+        if (!RtlCreateUnicodeStringFromAsciiz(&ClassName, lpszClass))
         {
             SetLastError(ERROR_NOT_ENOUGH_MEMORY);
             return FALSE;
@@ -353,13 +327,14 @@
                                  (LPWSTR *)&pszMenuName,
                                  TRUE);
         if (Ret) break;
+        if (!lpLibFileName) break;
         if (!ClassFound)
         {
             save_error = GetLastError();
             if ( save_error == ERROR_CANNOT_FIND_WND_CLASS ||
                  save_error == ERROR_CLASS_DOES_NOT_EXIST )
             {
-                ClassFound = VersionRegisterClass(ClassName.Buffer, NULL, 
NULL, &hLibModule);
+                ClassFound = VersionRegisterClass(ClassName.Buffer, 
lpLibFileName, pCtx, &hLibModule);
                 if (ClassFound) continue;
             }
         }
@@ -379,7 +354,7 @@
 //       lpwcx->lpszMenuName  = pszMenuName;
     }
 
-    if (!IS_ATOM(lpszClass))
+    if (ConvertedString)
     {
         RtlFreeUnicodeString(&ClassName);
     }
@@ -403,6 +378,9 @@
     HMODULE hLibModule = NULL;
     DWORD save_error;
     BOOL Ret, ClassFound = FALSE;
+    LPCWSTR lpszClsVersion;
+    HANDLE pCtx = NULL;
+    LPCWSTR lpLibFileName = NULL;
 
     TRACE("%p class/atom: %S/%04x %p\n", hInstance,
         IS_ATOM(lpszClass) ? NULL : lpszClass,
@@ -429,14 +407,18 @@
         return FALSE;
     }
 
-    if (IS_ATOM(lpszClass))
+    lpszClsVersion = ClassNameToVersion(lpszClass, NULL, &lpLibFileName, 
&pCtx, FALSE);
+    if (lpszClsVersion)
+    {
+        RtlInitUnicodeString(&ClassName, lpszClsVersion);
+    }
+    else if (IS_ATOM(lpszClass))
     {
         ClassName.Buffer = (PWSTR)((ULONG_PTR)lpszClass);
     }
     else
     {
-        RtlInitUnicodeString(&ClassName,
-                             lpszClass);
+        RtlInitUnicodeString(&ClassName, lpszClass);
     }
 
     if (!RegisterDefaultClasses)
@@ -453,13 +435,14 @@
                                  &pszMenuName,
                                   FALSE);
         if (Ret) break;
+        if (!lpLibFileName) break;
         if (!ClassFound)
         {
             save_error = GetLastError();
             if ( save_error == ERROR_CANNOT_FIND_WND_CLASS ||
                  save_error == ERROR_CLASS_DOES_NOT_EXIST )
             {
-                ClassFound = VersionRegisterClass(ClassName.Buffer, NULL, 
NULL, &hLibModule);
+                ClassFound = VersionRegisterClass(ClassName.Buffer, 
lpLibFileName, pCtx, &hLibModule);
                 if (ClassFound) continue;
             }
         }
@@ -1419,12 +1402,11 @@
     ATOM Atom;
     WNDCLASSEXW WndClass;
     UNICODE_STRING ClassName;
+    UNICODE_STRING ClassVersion;
     UNICODE_STRING MenuName = {0};
     CLSMENUNAME clsMenuName;
     ANSI_STRING AnsiMenuName;
-    HMODULE hLibModule = NULL;
-    DWORD save_error;
-    BOOL ClassFound = FALSE;
+    LPCWSTR lpszClsVersion;
 
     if (lpwcx == NULL || lpwcx->cbSize != sizeof(WNDCLASSEXW) ||
         lpwcx->cbClsExtra < 0 || lpwcx->cbWndExtra < 0 ||
@@ -1495,40 +1477,27 @@
         RtlInitUnicodeString(&ClassName, WndClass.lpszClassName);
     }
 
+    ClassVersion = ClassName;
+    if (fnID == 0)
+    {
+        lpszClsVersion = ClassNameToVersion(lpwcx->lpszClassName, NULL, NULL, 
NULL, FALSE);
+        if (lpszClsVersion)
+        {
+            RtlInitUnicodeString(&ClassVersion, lpszClsVersion);
+        }
+    }
+
     clsMenuName.pszClientAnsiMenuName = AnsiMenuName.Buffer;
     clsMenuName.pwszClientUnicodeMenuName = MenuName.Buffer;
     clsMenuName.pusMenuName = &MenuName;
 
-    for(;;)
-    {
-        Atom = NtUserRegisterClassExWOW( &WndClass,
-                                         &ClassName,
-                                         &ClassName, //PUNICODE_STRING 
ClsNVersion,
-                                         &clsMenuName,
-                                         fnID,
-                                         dwFlags,
-                                         pdwWowData);
-
-        if (Atom) break;
-        if (!ClassFound)
-        {
-            save_error = GetLastError();
-            if ( save_error == ERROR_CANNOT_FIND_WND_CLASS ||
-                 save_error == ERROR_CLASS_DOES_NOT_EXIST )
-            {
-                ClassFound = VersionRegisterClass(ClassName.Buffer, NULL, 
NULL, &hLibModule);
-                if (ClassFound) continue;
-            }
-        }
-        if (hLibModule)
-        {
-            save_error = GetLastError();
-            FreeLibrary(hLibModule);
-            SetLastError(save_error);
-            hLibModule = 0;
-        }
-        break;
-    }
+    Atom = NtUserRegisterClassExWOW( &WndClass,
+                                     &ClassName,
+                                     &ClassVersion,
+                                     &clsMenuName,
+                                     fnID,
+                                     dwFlags,
+                                     pdwWowData);
 
     TRACE("atom=%04x wndproc=%p hinst=%p bg=%p style=%08x clsExt=%d winExt=%d 
class=%p\n",
            Atom, lpwcx->lpfnWndProc, lpwcx->hInstance, lpwcx->hbrBackground,
@@ -1886,16 +1855,23 @@
 {
     UNICODE_STRING ClassName = {0};
     BOOL Ret;
+    LPCWSTR lpszClsVersion;
+    BOOL ConvertedString = FALSE;
 
     TRACE("class/atom: %s/%04x %p\n",
         IS_ATOM(lpClassName) ? NULL : lpClassName,
         IS_ATOM(lpClassName) ? lpClassName : 0,
         hInstance);
 
-    if (!IS_ATOM(lpClassName))
-    {
-        if (!RtlCreateUnicodeStringFromAsciiz(&ClassName,
-                                              lpClassName))
+    lpszClsVersion = ClassNameToVersion(lpClassName, NULL, NULL, NULL, TRUE);
+    if (lpszClsVersion)
+    {
+        RtlInitUnicodeString(&ClassName, lpszClsVersion);
+    }
+    else if (!IS_ATOM(lpClassName))
+    {
+        ConvertedString = TRUE;
+        if (!RtlCreateUnicodeStringFromAsciiz(&ClassName, lpClassName))
         {
             SetLastError(ERROR_NOT_ENOUGH_MEMORY);
             return 0;
@@ -1904,11 +1880,9 @@
     else
         ClassName.Buffer = (PWSTR)((ULONG_PTR)lpClassName);
 
-    Ret = NtUserUnregisterClass(&ClassName,
-                                 hInstance,
-                                 0);
-
-    if (!IS_ATOM(lpClassName))
+    Ret = NtUserUnregisterClass(&ClassName, hInstance, 0);
+
+    if (ConvertedString)
         RtlFreeUnicodeString(&ClassName);
 
     return Ret;
@@ -1925,23 +1899,28 @@
   HINSTANCE hInstance)
 {
     UNICODE_STRING ClassName = {0};
+    LPCWSTR lpszClsVersion;
 
     TRACE("class/atom: %S/%04x %p\n",
         IS_ATOM(lpClassName) ? NULL : lpClassName,
         IS_ATOM(lpClassName) ? lpClassName : 0,
         hInstance);
 
-    if (!IS_ATOM(lpClassName))
-    {
-        RtlInitUnicodeString(&ClassName,
-                             lpClassName);
+    lpszClsVersion = ClassNameToVersion(lpClassName, NULL, NULL, NULL, FALSE);
+    if (lpszClsVersion)
+    {
+        RtlInitUnicodeString(&ClassName, lpszClsVersion);
+    }
+    else if (!IS_ATOM(lpClassName))
+    {
+        RtlInitUnicodeString(&ClassName, lpClassName);
     }
     else
+    {    
         ClassName.Buffer = (PWSTR)((ULONG_PTR)lpClassName);
-
-    return NtUserUnregisterClass(&ClassName,
-                                 hInstance,
-                                 0);
+    }
+
+    return NtUserUnregisterClass(&ClassName, hInstance, 0);
 }
 
 /* EOF */

Modified: trunk/reactos/win32ss/user/user32/windows/window.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/user32/windows/window.c?rev=73806&r1=73805&r2=73806&view=diff
==============================================================================
--- trunk/reactos/win32ss/user/user32/windows/window.c  [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/user32/windows/window.c  [iso-8859-1] Fri Feb 17 
11:07:14 2017
@@ -16,6 +16,7 @@
 WINE_DEFAULT_DEBUG_CHANNEL(user32);
 
 void MDI_CalcDefaultChildPos( HWND hwndClient, INT total, LPPOINT lpPos, INT 
delta, UINT *id );
+extern LPCWSTR FASTCALL ClassNameToVersion(const void *lpszClass, LPCWSTR 
lpszMenuName, LPCWSTR *plpLibFileName, HANDLE *pContext, BOOL bAnsi);
 
 /* FUNCTIONS *****************************************************************/
 
@@ -165,13 +166,18 @@
 {
     LARGE_STRING WindowName;
     LARGE_STRING lstrClassName, *plstrClassName;
+    LARGE_STRING lstrClassVersion, *plstrClassVersion;
     UNICODE_STRING ClassName;
+    UNICODE_STRING ClassVersion;
     WNDCLASSEXA wceA;
     WNDCLASSEXW wceW;
     HMODULE hLibModule = NULL;
     DWORD save_error;
     BOOL Unicode, ClassFound = FALSE;
     HWND Handle = NULL;
+    LPCWSTR lpszClsVersion;
+    HANDLE pCtx;
+    LPCWSTR lpLibFileName;
 
 #if 0
     DbgPrint("[window] User32CreateWindowEx style %d, exstyle %d, parent 
%d\n", dwStyle, dwExStyle, hWndParent);
@@ -263,11 +269,25 @@
 
     if (!Unicode) dwExStyle |= WS_EX_SETANSICREATOR;
 
+    lpszClsVersion = ClassNameToVersion(lpClassName, NULL, &lpLibFileName, 
&pCtx, !Unicode);
+    if (!lpszClsVersion)
+    {
+        plstrClassVersion = plstrClassName;
+    }
+    else
+    {
+        RtlInitUnicodeString(&ClassVersion, lpszClsVersion);
+        lstrClassVersion.Buffer = ClassVersion.Buffer;
+        lstrClassVersion.Length = ClassVersion.Length;
+        lstrClassVersion.MaximumLength = ClassVersion.MaximumLength;
+        plstrClassVersion = &lstrClassVersion;
+    }
+
     for(;;)
     {
        Handle = NtUserCreateWindowEx(dwExStyle,
                                      plstrClassName,
-                                     plstrClassName,
+                                     plstrClassVersion,
                                      &WindowName,
                                      dwStyle,
                                      x,
@@ -281,12 +301,13 @@
                                      dwFlags,
                                      NULL);
        if (Handle) break;
+       if (!lpLibFileName) break;
        if (!ClassFound)
        {
           save_error = GetLastError();
           if ( save_error == ERROR_CANNOT_FIND_WND_CLASS )
           {
-              ClassFound = VersionRegisterClass(ClassName.Buffer, NULL, NULL, 
&hLibModule);
+              ClassFound = VersionRegisterClass(ClassName.Buffer, 
lpLibFileName, pCtx, &hLibModule);
               if (ClassFound) continue;
           }
        }


Reply via email to