[Csrss|Win32k]
[reactos.git] / reactos / subsystems / win32 / win32k / ntuser / class.c
index 46508f7..81e0076 100644 (file)
@@ -9,7 +9,7 @@
  */
 /* INCLUDES ******************************************************************/
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
 
 REGISTER_SYSCLASS DefaultServerClasses[] =
 {
-/*  { ((PWSTR)((ULONG_PTR)(WORD)(0x8001))),
+  { ((PWSTR)((ULONG_PTR)(WORD)(0x8001))),
     CS_GLOBALCLASS|CS_DBLCLKS,
     NULL,
     0,
     IDC_ARROW,
-    (HBRUSH)(COLOR_BACKGROUND+1),
+    (HBRUSH)(COLOR_BACKGROUND + 1),
     FNID_DESKTOP,
     ICLS_DESKTOP
-  },*/
+  },
   { ((PWSTR)((ULONG_PTR)(WORD)(0x8003))),
     CS_VREDRAW|CS_HREDRAW|CS_SAVEBITS,
     NULL, // Use User32 procs
@@ -228,7 +228,7 @@ IntRegisterClassAtom(IN PUNICODE_STRING ClassName,
         /* FIXME - Don't limit to 64 characters! use SEH when allocating memory! */
         if (ClassName->Length / sizeof(WCHAR) >= sizeof(szBuf) / sizeof(szBuf[0]))
         {
-            SetLastWin32Error(ERROR_INVALID_PARAMETER);
+            EngSetLastError(ERROR_INVALID_PARAMETER);
             return (RTL_ATOM)0;
         }
 
@@ -551,13 +551,13 @@ IntGetClassForDesktop(IN OUT PCLS BaseClass,
                 Class->pclsClone = NULL;
                 Class->pclsBase = BaseClass;
                 Class->pclsNext = BaseClass->pclsClone;
-                (void)InterlockedExchangePointer((VOID*)&BaseClass->pclsClone,
+                (void)InterlockedExchangePointer((PVOID*)&BaseClass->pclsClone,
                                                  Class);
             }
         }
         else
         {
-            SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+            EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
         }
     }
     return Class;
@@ -588,7 +588,7 @@ IntMakeCloneBaseClass(IN OUT PCLS Class,
                       IN OUT PCLS *BaseClassLink,
                       IN OUT PCLS *CloneLink)
 {
-    PCLS Clone, BaseClass;
+    PCLS Clone;
 
     ASSERT(Class->pclsBase != Class);
     ASSERT(Class->pclsBase->pclsClone != NULL);
@@ -601,8 +601,6 @@ IntMakeCloneBaseClass(IN OUT PCLS Class,
     *CloneLink = Class->pclsNext;
     Class->pclsClone = Class->pclsBase->pclsClone;
 
-    BaseClass = Class->pclsBase;
-
     /* update the class information to make it a base class */
     Class->pclsBase = Class;
     Class->pclsNext = (*BaseClassLink)->pclsNext;
@@ -834,7 +832,7 @@ IntCheckProcessDesktopClasses(IN PDESKTOP Desktop,
     if (!Ret)
     {
         DPRINT1("Failed to move process classes from desktop 0x%p to the shared heap!\n", Desktop);
-        SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+        EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
     }
 
     return Ret;
@@ -1036,7 +1034,7 @@ NoMem:
 
         IntDeregisterClassAtom(Atom);
 
-        SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+        EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
     }
 
     return Class;
@@ -1090,7 +1088,7 @@ IntGetAtomFromStringOrAtom(IN PUNICODE_STRING ClassName,
             /* FIXME - Don't limit to 64 characters! use SEH when allocating memory! */
             if (ClassName->Length / sizeof(WCHAR) >= sizeof(szBuf) / sizeof(szBuf[0]))
             {
-                SetLastWin32Error(ERROR_INVALID_PARAMETER);
+                EngSetLastError(ERROR_INVALID_PARAMETER);
                 return (RTL_ATOM)0;
             }
 
@@ -1119,7 +1117,7 @@ IntGetAtomFromStringOrAtom(IN PUNICODE_STRING ClassName,
         {
             if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
             {
-                SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST);
+                EngSetLastError(ERROR_CLASS_DOES_NOT_EXIST);
             }
             else
             {
@@ -1196,7 +1194,7 @@ IntGetClassAtom(IN PUNICODE_STRING ClassName,
                              Link);
         if (Class == NULL)
         {
-            SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST);
+            EngSetLastError(ERROR_CLASS_DOES_NOT_EXIST);
             return (RTL_ATOM)0;
         }else{DPRINT("Step 4: 0x%x\n",Class );}
 
@@ -1207,6 +1205,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);
+      }
+
+      EngSetLastError(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,
@@ -1240,7 +1289,7 @@ UserRegisterClass(IN CONST WNDCLASSEXW* lpwcx,
        {
           // local class already exists
           DPRINT("Local Class 0x%p does already exist!\n", ClassAtom);
-          SetLastWin32Error(ERROR_CLASS_ALREADY_EXISTS);
+          EngSetLastError(ERROR_CLASS_ALREADY_EXISTS);
           return (RTL_ATOM)0;
        }
 
@@ -1254,7 +1303,7 @@ UserRegisterClass(IN CONST WNDCLASSEXW* lpwcx,
           if (Class != NULL && Class->Global)
           {
              DPRINT("Global Class 0x%p does already exist!\n", ClassAtom);
-             SetLastWin32Error(ERROR_CLASS_ALREADY_EXISTS);
+             EngSetLastError(ERROR_CLASS_ALREADY_EXISTS);
              return (RTL_ATOM)0;
           }
        }
@@ -1265,7 +1314,7 @@ UserRegisterClass(IN CONST WNDCLASSEXW* lpwcx,
                            MenuName,
                            fnID,
                            dwFlags,
-                           pti->Desktop,
+                           pti->rpdesk,
                            pi);
 
     if (Class != NULL)
@@ -1324,7 +1373,7 @@ UserUnregisterClass(IN PUNICODE_STRING ClassName,
         Class->pclsClone != NULL)
     {
         DPRINT("UserUnregisterClass: Class has a Window. Ct %d : Clone 0x%x\n", Class->cWndReferenceCount, Class->pclsClone);
-        SetLastWin32Error(ERROR_CLASS_HAS_WINDOWS);
+        EngSetLastError(ERROR_CLASS_HAS_WINDOWS);
         return FALSE;
     }
 
@@ -1391,11 +1440,12 @@ 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);
+                    EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
                     _SEH2_LEAVE;
                 }
 
@@ -1464,96 +1514,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)
@@ -1629,7 +1589,7 @@ IntSetClassMenuName(IN PCLS Class,
             }
         }
         else
-            SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+            EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
     }
     else
     {
@@ -1680,7 +1640,7 @@ UserSetClassLongPtr(IN PCLS Class,
         if (Index + sizeof(ULONG_PTR) < Index ||
             Index + sizeof(ULONG_PTR) > Class->cbclsExtra)
         {
-            SetLastWin32Error(ERROR_INVALID_PARAMETER);
+            EngSetLastError(ERROR_INVALID_PARAMETER);
             return 0;
         }
 
@@ -1720,7 +1680,7 @@ UserSetClassLongPtr(IN PCLS Class,
             break;
 
         case GCL_CBCLSEXTRA:
-            SetLastWin32Error(ERROR_INVALID_PARAMETER);
+            EngSetLastError(ERROR_INVALID_PARAMETER);
             break;
 
         case GCLP_HBRBACKGROUND:
@@ -1843,7 +1803,7 @@ UserSetClassLongPtr(IN PCLS Class,
         }
 
         default:
-            SetLastWin32Error(ERROR_INVALID_INDEX);
+            EngSetLastError(ERROR_INVALID_INDEX);
             break;
     }
 
@@ -1856,8 +1816,6 @@ UserGetClassInfo(IN PCLS Class,
                  IN BOOL Ansi,
                  HINSTANCE hInstance)
 {
-    PPROCESSINFO pi;
-
     if (!Class) return FALSE;
 
     lpwcx->style = Class->style;
@@ -1866,8 +1824,6 @@ UserGetClassInfo(IN PCLS Class,
     if (Class->fnid)
        lpwcx->style &= ~CS_GLOBALCLASS;
 
-    pi = GetW32ProcessInfo();
-
     lpwcx->lpfnWndProc = IntGetClassWndProc(Class, Ansi);
     
     lpwcx->cbClsExtra = Class->cbclsExtra;
@@ -2026,7 +1982,7 @@ NtUserRegisterClassExWOW(
     if (Flags & ~(CSF_ANSIPROC))
     {
         DPRINT1("NtUserRegisterClassExWOW Bad Flags!\n");
-        SetLastWin32Error(ERROR_INVALID_FLAGS);
+        EngSetLastError(ERROR_INVALID_FLAGS);
         return Ret;
     }
 
@@ -2103,7 +2059,7 @@ NtUserRegisterClassExWOW(
         {
             DPRINT1("NtUserRegisterClassExWOW MenuName Error!\n");
 InvalidParameter:
-            SetLastWin32Error(ERROR_INVALID_PARAMETER);
+            EngSetLastError(ERROR_INVALID_PARAMETER);
             _SEH2_LEAVE;
         }
 
@@ -2139,45 +2095,6 @@ InvalidParameter:
     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 +2102,7 @@ NtUserSetClassLong(HWND hWnd,
                    BOOL Ansi)
 {
     PPROCESSINFO pi;
-    PWINDOW_OBJECT Window;
+    PWND Window;
     ULONG_PTR Ret = 0;
 
     UserEnterExclusive();
@@ -2195,9 +2112,9 @@ NtUserSetClassLong(HWND hWnd,
     Window = UserGetWindowObject(hWnd);
     if (Window != NULL)
     {
-        if (Window->pti->ppi != pi)
+        if (Window->head.pti->ppi != pi)
         {
-            SetLastWin32Error(ERROR_ACCESS_DENIED);
+            EngSetLastError(ERROR_ACCESS_DENIED);
             goto Cleanup;
         }
 
@@ -2229,7 +2146,7 @@ NtUserSetClassLong(HWND hWnd,
                     else if (Offset == GCLP_MENUNAME && !IS_INTRESOURCE(Value.Buffer))
                     {
 InvalidParameter:
-                        SetLastWin32Error(ERROR_INVALID_PARAMETER);
+                        EngSetLastError(ERROR_INVALID_PARAMETER);
                         _SEH2_LEAVE;
                     }
                 }
@@ -2237,7 +2154,7 @@ InvalidParameter:
                 dwNewLong = (ULONG_PTR)&Value;
             }
 
-            Ret = UserSetClassLongPtr(Window->Wnd->pcls,
+            Ret = UserSetClassLongPtr(Window->pcls,
                                       Offset,
                                       dwNewLong,
                                       Ansi);
@@ -2298,7 +2215,7 @@ NtUserUnregisterClass(IN PUNICODE_STRING ClassNameOrAtom,
             if (!IS_ATOM(CapturedClassName.Buffer))
             {
 InvalidParameter:
-                SetLastWin32Error(ERROR_INVALID_PARAMETER);
+                EngSetLastError(ERROR_INVALID_PARAMETER);
                 _SEH2_LEAVE;
             }
         }
@@ -2357,7 +2274,9 @@ NtUserGetClassInfo(
 
       if (CapturedClassName.Length & 1)
       {
-         goto InvalidParameter;
+         EngSetLastError(ERROR_INVALID_PARAMETER);
+         Ret = FALSE;
+         _SEH2_LEAVE;
       }
 
       if (CapturedClassName.Length != 0)
@@ -2380,7 +2299,9 @@ NtUserGetClassInfo(
          if (!IS_ATOM(CapturedClassName.Buffer))
          {
             ERR("NtUserGetClassInfo() got ClassName instead of Atom!\n");
-            goto InvalidParameter;
+            EngSetLastError(ERROR_INVALID_PARAMETER);
+            Ret = FALSE;
+            _SEH2_LEAVE;
          }
 
          SafeClassName.Buffer = CapturedClassName.Buffer;
@@ -2388,21 +2309,13 @@ NtUserGetClassInfo(
          SafeClassName.MaximumLength = 0;
       }
 
-      if (ProbeForReadUint(&lpWndClassEx->cbSize) != sizeof(WNDCLASSEXW))
-      {
-InvalidParameter:
-         SetLastWin32Error(ERROR_INVALID_PARAMETER);
-         Ret = FALSE;
-         _SEH2_LEAVE;
-      }
-
       ProbeForWrite( lpWndClassEx, sizeof(WNDCLASSEXW), sizeof(ULONG));
 
       RtlCopyMemory( &Safewcexw, lpWndClassEx, sizeof(WNDCLASSEXW));
    }
    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
    {
-      SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST);
+      SetLastNtError(_SEH2_GetExceptionCode());
       Ret = FALSE;
    }
    _SEH2_END;
@@ -2429,7 +2342,7 @@ InvalidParameter:
       }
       else
       {
-         SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST);
+         EngSetLastError(ERROR_CLASS_DOES_NOT_EXIST);
          Ret = FALSE;
       }
    }
@@ -2450,7 +2363,7 @@ InvalidParameter:
    }
    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
    {
-      SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST);
+      EngSetLastError(ERROR_CLASS_DOES_NOT_EXIST);
       Ret = FALSE;
    }
    _SEH2_END;
@@ -2466,7 +2379,7 @@ NtUserGetClassName (IN HWND hWnd,
                     OUT PUNICODE_STRING ClassName,
                     IN BOOL Ansi)
 {
-    PWINDOW_OBJECT Window;
+    PWND Window;
     UNICODE_STRING CapturedClassName;
     INT Ret = 0;
 
@@ -2481,7 +2394,7 @@ NtUserGetClassName (IN HWND hWnd,
             CapturedClassName = *ClassName;
 
             /* get the class name */
-            Ret = UserGetClassName(Window->Wnd->pcls,
+            Ret = UserGetClassName(Window->pcls,
                                    &CapturedClassName,
                                    Ansi);
 
@@ -2552,7 +2465,7 @@ NtUserGetWOWClass(HINSTANCE hInstance,
   }
   _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
   {
-     SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST);
+     EngSetLastError(ERROR_CLASS_DOES_NOT_EXIST);
      Hit = TRUE;
   }
   _SEH2_END;
@@ -2566,7 +2479,7 @@ NtUserGetWOWClass(HINSTANCE hInstance,
                                    NULL);
      if (!ClassAtom)
      {
-        SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST);
+        EngSetLastError(ERROR_CLASS_DOES_NOT_EXIST);
      }
   }