[WIN32K]
[reactos.git] / reactos / subsystems / win32 / win32k / ntuser / class.c
index 04008af..aa06be3 100644 (file)
@@ -9,7 +9,7 @@
  */
 /* INCLUDES ******************************************************************/
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
@@ -385,6 +385,8 @@ IntSetClassWndProc(IN OUT PCLS Class,
       Class->Unicode = !Ansi;
    }
 
+   if (!WndProc) WndProc = Class->lpfnWndProc;
+
    chWndProc = WndProc;
 
    // Check if CallProc handle and retrieve previous call proc address and set.
@@ -506,11 +508,19 @@ IntGetClassForDesktop(IN OUT PCLS BaseClass,
         if (Class != NULL)
         {
             /* simply clone the class */
-            RtlCopyMemory(Class,
-                          BaseClass,
-                          ClassSize);
+            RtlCopyMemory( Class, BaseClass, ClassSize);
+
             DPRINT("Clone Class 0x%x hM 0x%x\n %S\n",Class, Class->hModule, Class->lpszClientUnicodeMenuName);
 
+            /* restore module address if default user class Ref: Bug 4778 */
+            if ( Class->hModule != hModClient &&
+                 Class->fnid <= FNID_GHOST    &&
+                 Class->fnid >= FNID_BUTTON )
+            {
+               Class->hModule = hModClient;
+               DPRINT("Clone Class 0x%x Reset hM 0x%x\n",Class, Class->hModule);
+            }
+
             /* update some pointers and link the class */
             Class->rpdeskParent = Desktop;
             Class->cWndReferenceCount = 0;
@@ -541,7 +551,7 @@ IntGetClassForDesktop(IN OUT PCLS BaseClass,
                 Class->pclsClone = NULL;
                 Class->pclsBase = BaseClass;
                 Class->pclsNext = BaseClass->pclsClone;
-                (void)InterlockedExchangePointer(&BaseClass->pclsClone,
+                (void)InterlockedExchangePointer((PVOID*)&BaseClass->pclsClone,
                                                  Class);
             }
         }
@@ -1154,7 +1164,7 @@ IntGetClassAtom(IN PUNICODE_STRING ClassName,
                              &pi->pclsPrivateList,
                              Link);
         if (Class != NULL)
-        {
+        {  DPRINT("Step 1: 0x%x\n",Class );
             goto FoundClass;
         }
 
@@ -1165,7 +1175,7 @@ IntGetClassAtom(IN PUNICODE_STRING ClassName,
                              &pi->pclsPublicList,
                              Link);
         if (Class != NULL)
-        {
+        { DPRINT("Step 2: 0x%x 0x%x\n",Class, Class->hModule);
             goto FoundClass;
         }
 
@@ -1175,7 +1185,7 @@ IntGetClassAtom(IN PUNICODE_STRING ClassName,
                              &pi->pclsPrivateList,
                              Link);
         if (Class != NULL)
-        {
+        { DPRINT("Step 3: 0x%x\n",Class );
             goto FoundClass;
         }
 
@@ -1188,7 +1198,7 @@ IntGetClassAtom(IN PUNICODE_STRING ClassName,
         {
             SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST);
             return (RTL_ATOM)0;
-        }
+        }else{DPRINT("Step 4: 0x%x\n",Class );}
 
 FoundClass:
         *BaseClass = Class;
@@ -1197,6 +1207,57 @@ FoundClass:
     return Atom;
 }
 
+PCLS
+IntGetAndReferenceClass(PUNICODE_STRING ClassName, HINSTANCE hInstance)
+{
+   PCLS *ClassLink, Class = NULL;
+   RTL_ATOM ClassAtom;
+   PTHREADINFO pti;
+
+   pti = PsGetCurrentThreadWin32Thread();
+
+   if ( !(pti->ppi->W32PF_flags & W32PF_CLASSESREGISTERED ))
+   {
+      UserRegisterSystemClasses();
+   }
+
+   /* Check the class. */
+
+   DPRINT("Class %wZ\n", ClassName);
+
+   ClassAtom = IntGetClassAtom(ClassName,
+                               hInstance,
+                               pti->ppi,
+                               &Class,
+                               &ClassLink);
+
+   if (ClassAtom == (RTL_ATOM)0)
+   {
+      if (IS_ATOM(ClassName->Buffer))
+      {
+         DPRINT1("Class 0x%p not found\n", (DWORD_PTR) ClassName->Buffer);
+      }
+      else
+      {
+         DPRINT1("Class \"%wZ\" not found\n", ClassName);
+      }
+
+      SetLastWin32Error(ERROR_CANNOT_FIND_WND_CLASS);
+      return NULL;
+   }
+   DPRINT("ClassAtom %x\n", ClassAtom);
+   Class = IntReferenceClass(Class,
+                             ClassLink,
+                             pti->rpdesk);
+   if (Class == NULL)
+   {
+       DPRINT1("Failed to reference window class!\n");
+       return NULL;
+   }
+
+   return Class;
+}
+
 RTL_ATOM
 UserRegisterClass(IN CONST WNDCLASSEXW* lpwcx,
                   IN PUNICODE_STRING ClassName,
@@ -1229,7 +1290,7 @@ UserRegisterClass(IN CONST WNDCLASSEXW* lpwcx,
        if (Class != NULL && !Class->Global)
        {
           // local class already exists
-          DPRINT1("Local Class 0x%p does already exist!\n", ClassAtom);
+          DPRINT("Local Class 0x%p does already exist!\n", ClassAtom);
           SetLastWin32Error(ERROR_CLASS_ALREADY_EXISTS);
           return (RTL_ATOM)0;
        }
@@ -1243,7 +1304,7 @@ UserRegisterClass(IN CONST WNDCLASSEXW* lpwcx,
 
           if (Class != NULL && Class->Global)
           {
-             DPRINT1("Global Class 0x%p does already exist!\n", ClassAtom);
+             DPRINT("Global Class 0x%p does already exist!\n", ClassAtom);
              SetLastWin32Error(ERROR_CLASS_ALREADY_EXISTS);
              return (RTL_ATOM)0;
           }
@@ -1255,7 +1316,7 @@ UserRegisterClass(IN CONST WNDCLASSEXW* lpwcx,
                            MenuName,
                            fnID,
                            dwFlags,
-                           pti->Desktop,
+                           pti->rpdesk,
                            pi);
 
     if (Class != NULL)
@@ -1304,7 +1365,7 @@ UserUnregisterClass(IN PUNICODE_STRING ClassName,
                                 &Link);
     if (ClassAtom == (RTL_ATOM)0)
     {
-        DPRINT1("UserUnregisterClass: No Class found.\n");
+        DPRINT("UserUnregisterClass: No Class found.\n");
         return FALSE;
     }
 
@@ -1381,8 +1442,9 @@ UserGetClassName(IN PCLS Class,
                 }
 
                 /* allocate a temporary buffer that can hold the unicode class name */
-                szTemp = ExAllocatePool(PagedPool,
-                                        BufLen);
+                szTemp = ExAllocatePoolWithTag(PagedPool,
+                                               BufLen,
+                                               USERTAG_CLASS);
                 if (szTemp == NULL)
                 {
                     SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
@@ -1454,96 +1516,6 @@ UserGetClassName(IN PCLS Class,
     return Ret;
 }
 
-ULONG_PTR
-UserGetClassLongPtr(IN PCLS Class,
-                    IN INT Index,
-                    IN BOOL Ansi)
-{
-    ULONG_PTR Ret = 0;
-
-    if (Index >= 0)
-    {
-        PULONG_PTR Data;
-
-        TRACE("GetClassLong(%d)\n", Index);
-        if (Index + sizeof(ULONG_PTR) < Index ||
-            Index + sizeof(ULONG_PTR) > Class->cbclsExtra)
-        {
-            SetLastWin32Error(ERROR_INVALID_PARAMETER);
-            return 0;
-        }
-
-        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
-                   better choice for those architectures! */
-
-        TRACE("Result: %x\n", Ret);
-        return *Data;
-    }
-
-    switch (Index)
-    {
-        case GCL_CBWNDEXTRA:
-            Ret = (ULONG_PTR)Class->cbwndExtra;
-            break;
-
-        case GCL_CBCLSEXTRA:
-            Ret = (ULONG_PTR)Class->cbclsExtra;
-            break;
-
-        case GCLP_HBRBACKGROUND:
-            Ret = (ULONG_PTR)Class->hbrBackground;
-            break;
-
-        case GCLP_HCURSOR:
-            /* FIXME - get handle from pointer to CURSOR object */
-            Ret = (ULONG_PTR)Class->hCursor;
-            break;
-
-        case GCLP_HICON:
-            /* FIXME - get handle from pointer to ICON object */
-            Ret = (ULONG_PTR)Class->hIcon;
-            break;
-
-        case GCLP_HICONSM:
-            /* FIXME - get handle from pointer to ICON object */
-            Ret = (ULONG_PTR)Class->hIconSm;
-            break;
-
-        case GCLP_HMODULE:
-            Ret = (ULONG_PTR)Class->hModule;
-            break;
-
-        case GCLP_MENUNAME:
-            /* NOTE: Returns pointer in kernel heap! */
-            if (Ansi)
-                Ret = (ULONG_PTR)Class->lpszClientAnsiMenuName;
-            else
-                Ret = (ULONG_PTR)Class->lpszClientUnicodeMenuName;
-            break;
-
-        case GCL_STYLE:
-            Ret = (ULONG_PTR)Class->style;
-            break;
-
-        case GCLP_WNDPROC:
-            Ret = (ULONG_PTR)IntGetClassWndProc(Class, Ansi);
-            break;
-
-        case GCW_ATOM:
-            Ret = (ULONG_PTR)Class->atomClassName;
-            break;
-
-        default:
-            SetLastWin32Error(ERROR_INVALID_INDEX);
-            break;
-    }
-
-    return Ret;
-}
-
 static BOOL
 IntSetClassMenuName(IN PCLS Class,
                     IN PUNICODE_STRING MenuName)
@@ -2118,56 +2090,17 @@ InvalidParameter:
         SetLastNtError(_SEH2_GetExceptionCode());
     }
     _SEH2_END;
-
+/*
     if (!Ret)
     {
        DPRINT1("NtUserRegisterClassExWOW Null Return!\n");
     }
-
-    UserLeave();
-
-    return Ret;
-}
-
-ULONG_PTR APIENTRY
-NtUserGetClassLong(IN HWND hWnd,
-                   IN INT Offset,
-                   IN BOOL Ansi)
-{
-    PWINDOW_OBJECT Window;
-    ULONG_PTR Ret = 0;
-
-    if (Offset != GCLP_WNDPROC)
-    {
-        UserEnterShared();
-    }
-    else
-    {
-        UserEnterExclusive();
-    }
-
-    Window = UserGetWindowObject(hWnd);
-    if (Window != NULL)
-    {
-        Ret = UserGetClassLongPtr(Window->Wnd->pcls,
-                                  Offset,
-                                  Ansi);
-
-        if ( Ret != 0 &&
-             Offset == GCLP_MENUNAME &&
-             Window->Wnd->pcls->MenuNameIsString)
-        {
-            Ret = (ULONG_PTR)UserHeapAddressToUser((PVOID)Ret);
-        }
-    }
-
+ */
     UserLeave();
 
     return Ret;
 }
 
-
-
 ULONG_PTR APIENTRY
 NtUserSetClassLong(HWND hWnd,
                    INT Offset,
@@ -2185,7 +2118,7 @@ NtUserSetClassLong(HWND hWnd,
     Window = UserGetWindowObject(hWnd);
     if (Window != NULL)
     {
-        if (Window->ti->ppi != pi)
+        if (Window->pti->ppi != pi)
         {
             SetLastWin32Error(ERROR_ACCESS_DENIED);
             goto Cleanup;
@@ -2402,6 +2335,7 @@ InvalidParameter:
 
    if (Ret)
    {
+      DPRINT("GetClassInfo(%wZ, 0x%x)\n", ClassName, hInstance);
       ClassAtom = IntGetClassAtom( &SafeClassName,
                                     hInstance,
                                     ppi,