[ros-diffs] [weiden] 27941: Simplify and fix handling of menus for classes

weiden at svn.reactos.org weiden at svn.reactos.org
Sat Jul 28 13:05:33 CEST 2007


Author: weiden
Date: Sat Jul 28 15:05:33 2007
New Revision: 27941

URL: http://svn.reactos.org/svn/reactos?rev=27941&view=rev
Log:
Simplify and fix handling of menus for classes

Modified:
    trunk/reactos/include/reactos/win32k/ntuser.h
    trunk/reactos/subsystems/win32/win32k/ntuser/class.c

Modified: trunk/reactos/include/reactos/win32k/ntuser.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/win32k/ntuser.h?rev=27941&r1=27940&r2=27941&view=diff
==============================================================================
--- trunk/reactos/include/reactos/win32k/ntuser.h (original)
+++ trunk/reactos/include/reactos/win32k/ntuser.h Sat Jul 28 15:05:33 2007
@@ -47,14 +47,13 @@
     PWSTR MenuName;
     PSTR AnsiMenuName;
 
-    ULONG_PTR ClassExtraDataOffset;
-
     UINT Destroying : 1;
     UINT Unicode : 1;
     UINT System : 1;
     UINT Global : 1;
     UINT GlobalCallProc : 1;
     UINT GlobalCallProc2 : 1;
+    UINT MenuNameIsString : 1;
 } WINDOWCLASS, *PWINDOWCLASS;
 
 typedef struct _W32PROCESSINFO

Modified: trunk/reactos/subsystems/win32/win32k/ntuser/class.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntuser/class.c?rev=27941&r1=27940&r2=27941&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/class.c (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/class.c Sat Jul 28 15:05:33 2007
@@ -42,8 +42,7 @@
 IntFreeClassMenuName(IN OUT PWINDOWCLASS Class)
 {
     /* free the menu name, if it was changed and allocated */
-    if (Class->MenuName != NULL && !IS_INTRESOURCE(Class->MenuName) &&
-        Class->MenuName != (PWSTR)(Class + 1))
+    if (Class->MenuName != NULL && Class->MenuNameIsString)
     {
         UserHeapFree(Class->MenuName);
         Class->MenuName = NULL;
@@ -416,8 +415,7 @@
     {
         /* The window is created on a different desktop, we need to
            clone the class object to the desktop heap of the window! */
-        ClassSize = (SIZE_T)BaseClass->ClassExtraDataOffset +
-                    (SIZE_T)BaseClass->ClsExtra;
+        ClassSize = sizeof(*BaseClass) + (SIZE_T)BaseClass->ClsExtra;
 
         Class = DesktopHeapAlloc(Desktop,
                                  ClassSize);
@@ -651,8 +649,7 @@
     ASSERT(Class->Windows == 0);
     ASSERT(Class->Clone == NULL);
 
-    ClassSize = (SIZE_T)Class->ClassExtraDataOffset +
-                (SIZE_T)Class->ClsExtra;
+    ClassSize = sizeof(*Class) + (SIZE_T)Class->ClsExtra;
 
     /* allocate the new base class on the shared heap */
     NewClass = UserHeapAlloc(ClassSize);
@@ -664,15 +661,6 @@
 
         NewClass->Desktop = NULL;
         NewClass->Base = NewClass;
-
-        if (Class->MenuName == (PWSTR)(Class + 1))
-        {
-            ULONG_PTR AnsiDelta = (ULONG_PTR)Class->AnsiMenuName - (ULONG_PTR)Class->MenuName;
-
-            /* fixup the self-relative MenuName pointers */
-            NewClass->MenuName = (PWSTR)(NewClass + 1);
-            NewClass->AnsiMenuName = (PSTR)((ULONG_PTR)NewClass->MenuName + AnsiDelta);
-        }
 
         if (!NewClass->System && NewClass->CallProc != NULL &&
             !NewClass->GlobalCallProc)
@@ -833,6 +821,7 @@
     SIZE_T ClassSize;
     PWINDOWCLASS Class = NULL;
     RTL_ATOM Atom;
+    PWSTR pszMenuName = NULL;
     NTSTATUS Status = STATUS_SUCCESS;
 
     TRACE("lpwcx=%p ClassName=%wZ MenuName=%wZ wpExtra=%p dwFlags=%08x Desktop=%p pi=%p\n",
@@ -845,11 +834,13 @@
         return NULL;
     }
 
-    ClassSize = sizeof(WINDOWCLASS) + lpwcx->cbClsExtra;
+    ClassSize = sizeof(*Class) + lpwcx->cbClsExtra;
     if (MenuName->Length != 0)
     {
-        ClassSize += MenuName->Length + sizeof(UNICODE_NULL);
-        ClassSize += RtlUnicodeStringToAnsiSize(MenuName);
+        pszMenuName = UserHeapAlloc(MenuName->Length + sizeof(UNICODE_NULL) +
+                                    RtlUnicodeStringToAnsiSize(MenuName));
+        if (pszMenuName == NULL)
+            goto NoMem;
     }
 
     if (Desktop != NULL)
@@ -868,7 +859,7 @@
     if (Class != NULL)
     {
         RtlZeroMemory(Class,
-                      sizeof(ClassSize));
+                      ClassSize);
 
         Class->Desktop = Desktop;
         Class->Base = Class;
@@ -883,9 +874,7 @@
 
         _SEH_TRY
         {
-            PWSTR strBuf;
-            PSTR strBufA;
-            ANSI_STRING AnsiString;
+            PWSTR pszMenuNameBuffer = pszMenuName;
 
             /* need to protect with SEH since accessing the WNDCLASSEX structure
                and string buffers might raise an exception! We don't want to
@@ -901,26 +890,29 @@
             Class->hbrBackground = lpwcx->hbrBackground;
 
             /* make a copy of the string */
-            strBuf = (PWSTR)(Class + 1);
-            if (MenuName->Length != 0)
-            {
-                Class->MenuName = strBuf;
+            if (pszMenuNameBuffer != NULL)
+            {
+                Class->MenuNameIsString = TRUE;
+
+                Class->MenuName = pszMenuNameBuffer;
                 RtlCopyMemory(Class->MenuName,
                               MenuName->Buffer,
                               MenuName->Length);
-
-                strBuf += (MenuName->Length / sizeof(WCHAR)) + 1;
+                Class->MenuName[MenuName->Length / sizeof(WCHAR)] = UNICODE_NULL;
+
+                pszMenuNameBuffer += (MenuName->Length / sizeof(WCHAR)) + 1;
             }
             else
                 Class->MenuName = MenuName->Buffer;
 
             /* save an ansi copy of the string */
-            strBufA = (PSTR)strBuf;
-            if (MenuName->Length != 0)
-            {
-                Class->AnsiMenuName = strBufA;
+            if (pszMenuNameBuffer != NULL)
+            {
+                ANSI_STRING AnsiString;
+
+                Class->AnsiMenuName = (PSTR)pszMenuNameBuffer;
                 AnsiString.MaximumLength = RtlUnicodeStringToAnsiSize(MenuName);
-                AnsiString.Buffer = strBufA;
+                AnsiString.Buffer = Class->AnsiMenuName;
                 Status = RtlUnicodeStringToAnsiString(&AnsiString,
                                                       MenuName,
                                                       FALSE);
@@ -931,15 +923,10 @@
                     /* life would've been much prettier if ntoskrnl exported RtlRaiseStatus()... */
                     _SEH_LEAVE;
                 }
-
-                strBufA += AnsiString.Length + 1;
             }
             else
                 Class->AnsiMenuName = (PSTR)MenuName->Buffer;
 
-            /* calculate the offset of the extra data */
-            Class->ClassExtraDataOffset = (ULONG_PTR)strBufA - (ULONG_PTR)Class;
-
             if (!(dwFlags & REGISTERCLASS_ANSI))
                 Class->Unicode = TRUE;
 
@@ -957,6 +944,9 @@
             DPRINT1("Failed creating the class: 0x%x\n", Status);
 
             SetLastNtError(Status);
+
+            if (pszMenuName != NULL)
+                UserHeapFree(pszMenuName);
 
             DesktopHeapFree(Desktop,
                             Class);
@@ -967,7 +957,11 @@
     }
     else
     {
+NoMem:
         DPRINT1("Failed to allocate class on Desktop 0x%p\n", Desktop);
+
+        if (pszMenuName != NULL)
+            UserHeapFree(pszMenuName);
 
         IntDeregisterClassAtom(Atom);
 
@@ -1423,7 +1417,7 @@
             return 0;
         }
 
-        Data = (PULONG_PTR)((ULONG_PTR)Class + Class->ClassExtraDataOffset + Index);
+        Data = (PULONG_PTR)((ULONG_PTR)(Class + 1) + Index);
 
         /* FIXME - Data might be a unaligned pointer! Might be a problem on
                    certain architectures, maybe using RtlCopyMemory is a
@@ -1550,6 +1544,7 @@
                 IntFreeClassMenuName(Class);
                 Class->MenuName = strBufW;
                 Class->AnsiMenuName = AnsiString.Buffer;
+                Class->MenuNameIsString = TRUE;
 
                 /* update the clones */
                 Class = Class->Clone;
@@ -1557,6 +1552,7 @@
                 {
                     Class->MenuName = strBufW;
                     Class->AnsiMenuName = AnsiString.Buffer;
+                    Class->MenuNameIsString = TRUE;
 
                     Class = Class->Next;
                 }
@@ -1578,6 +1574,7 @@
         IntFreeClassMenuName(Class);
         Class->MenuName = MenuName->Buffer;
         Class->AnsiMenuName = (PSTR)MenuName->Buffer;
+        Class->MenuNameIsString = FALSE;
 
         /* update the clones */
         Class = Class->Clone;
@@ -1585,6 +1582,7 @@
         {
             Class->MenuName = MenuName->Buffer;
             Class->AnsiMenuName = (PSTR)MenuName->Buffer;
+            Class->MenuNameIsString = FALSE;
 
             Class = Class->Next;
         }
@@ -1619,7 +1617,7 @@
             return 0;
         }
 
-        Data = (PULONG_PTR)((ULONG_PTR)Class + Class->ClassExtraDataOffset + Index);
+        Data = (PULONG_PTR)((ULONG_PTR)(Class + 1) + Index);
 
         /* FIXME - Data might be a unaligned pointer! Might be a problem on
                    certain architectures, maybe using RtlCopyMemory is a
@@ -1631,7 +1629,7 @@
         Class = Class->Clone;
         while (Class != NULL)
         {
-            *(PULONG_PTR)((ULONG_PTR)Class + Class->ClassExtraDataOffset + Index) = NewLong;
+            *(PULONG_PTR)((ULONG_PTR)(Class + 1) + Index) = NewLong;
             Class = Class->Next;
         }
 
@@ -1961,7 +1959,7 @@
                                   Offset,
                                   Ansi);
 
-        if (Ret != 0 && Offset == GCLP_MENUNAME && !IS_INTRESOURCE(Ret))
+        if (Ret != 0 && Offset == GCLP_MENUNAME && Window->Class->MenuNameIsString)
         {
             Ret = (ULONG_PTR)DesktopHeapAddressToUser(Window->Class->Desktop,
                                                       (PVOID)Ret);
@@ -2196,8 +2194,7 @@
                 lpWndClassEx->lpszClassName = CapturedClassName.Buffer;
                 /* FIXME - handle Class->Desktop == NULL!!!!! */
 
-                if (Class->MenuName != NULL &&
-                    !IS_INTRESOURCE(Class->MenuName))
+                if (Class->MenuName != NULL && Class->MenuNameIsString)
                 {
                     lpWndClassEx->lpszMenuName = DesktopHeapAddressToUser(Class->Desktop,
                                                                           (Ansi ?




More information about the Ros-diffs mailing list