[CMAKE]
[reactos.git] / dll / win32 / user32 / windows / class.c
index f546aa4..df665d1 100644 (file)
@@ -32,8 +32,11 @@ GetClassInfoExA(
         IS_ATOM(lpszClass) ? lpszClass : 0,
         lpwcx);
 
-    //HACKHACK: This is ROS-specific and should go away
-    lpwcx->cbSize = sizeof(*lpwcx);
+    if (!lpwcx)
+    {
+       SetLastError( ERROR_NOACCESS );
+       return FALSE;
+    }
 
     if (hInstance == User32Instance)
     {
@@ -105,8 +108,14 @@ GetClassInfoExW(
         IS_ATOM(lpszClass) ? lpszClass : 0,
         lpwcx);
 
-    //HACKHACK: This is ROS-specific and should go away
-    lpwcx->cbSize = sizeof(*lpwcx);
+    /* From wine, for speed only, ReactOS supports the correct return in
+     * Win32k. cbSize is ignored.
+     */
+    if (!lpwcx)
+    {
+       SetLastError( ERROR_NOACCESS );
+       return FALSE;
+    }
 
     if (hInstance == User32Instance)
     {
@@ -266,11 +275,11 @@ IntGetClsWndProc(PWND pWnd, PCLS Class, BOOL Ansi)
 //
 // Based on IntGetClsWndProc
 //
-ULONG_PTR FASTCALL
+WNDPROC FASTCALL
 IntGetWndProc(PWND pWnd, BOOL Ansi)
 {
   INT i;
-  ULONG_PTR gcpd, Ret = 0;
+  WNDPROC gcpd, Ret = 0;
   PCLS Class = DesktopPtrToUser(pWnd->pcls);
 
   if (!Class) return Ret;
@@ -282,54 +291,209 @@ IntGetWndProc(PWND pWnd, BOOL Ansi)
          if (GETPFNSERVER(i) == pWnd->lpfnWndProc)
          {
             if (Ansi)
-               Ret = (ULONG_PTR)GETPFNCLIENTA(i);
+               Ret = GETPFNCLIENTA(i);
             else
-               Ret = (ULONG_PTR)GETPFNCLIENTW(i);
+               Ret = GETPFNCLIENTW(i);
          }
      }
      return Ret;
   }
-  // Wine Class tests: 
+  // Wine Class tests:
   /*  Edit controls are special - they return a wndproc handle when
       GetWindowLongPtr is called with a different A/W.
       On the other hand there is no W->A->W conversion so this control
       is treated specially.
    */
   if (Class->fnid == FNID_EDIT)
-     Ret = (ULONG_PTR)pWnd->lpfnWndProc;
+     Ret = pWnd->lpfnWndProc;
   else
   {
      // Set return proc.
-     Ret = (ULONG_PTR)pWnd->lpfnWndProc;
+     Ret = pWnd->lpfnWndProc;
 
      if (Class->fnid <= FNID_GHOST && Class->fnid >= FNID_BUTTON)
      {
         if (Ansi)
         {
            if (GETPFNCLIENTW(Class->fnid) == pWnd->lpfnWndProc)
-              Ret = (ULONG_PTR)GETPFNCLIENTA(Class->fnid);
+              Ret = GETPFNCLIENTA(Class->fnid);
         }
         else
         {
            if (GETPFNCLIENTA(Class->fnid) == pWnd->lpfnWndProc)
-              Ret = (ULONG_PTR)GETPFNCLIENTW(Class->fnid);
+              Ret = GETPFNCLIENTW(Class->fnid);
         }
      }
      // Return on the change.
-     if ( Ret != (ULONG_PTR)pWnd->lpfnWndProc)
+     if ( Ret != pWnd->lpfnWndProc)
         return Ret;
   }
 
   if ( Ansi == !!(pWnd->state & WNDS_ANSIWINDOWPROC) )
      return Ret;
 
-  gcpd = NtUserGetCPD( UserHMGetHandle(pWnd),
-                      (Ansi ? UserGetCPDA2U : UserGetCPDU2A )|UserGetCPDWindow,
-                       Ret);
+  gcpd = (WNDPROC)NtUserGetCPD( UserHMGetHandle(pWnd),
+                                (Ansi ? UserGetCPDA2U : UserGetCPDU2A )|UserGetCPDWindow,
+                                (ULONG_PTR)Ret);
 
   return (gcpd ? gcpd : Ret);
 }
 
+static ULONG_PTR FASTCALL
+IntGetClassLongA(PWND Wnd, PCLS Class, int nIndex)
+{
+       ULONG_PTR Ret = 0;
+
+    if (nIndex >= 0)
+    {
+        if (nIndex + sizeof(ULONG_PTR) < nIndex ||
+            nIndex + sizeof(ULONG_PTR) > Class->cbclsExtra)
+        {
+            SetLastError(ERROR_INVALID_PARAMETER);
+        }
+        else
+            Ret = *(PULONG_PTR)((ULONG_PTR)(Class + 1) + nIndex);
+    }
+    else
+    {
+        switch (nIndex)
+        {
+            case GCL_CBWNDEXTRA:
+                Ret = (ULONG_PTR)Class->cbwndExtra;
+                break;
+
+            case GCL_CBCLSEXTRA:
+                Ret = (ULONG_PTR)Class->cbclsExtra;
+                break;
+
+            case GCL_HBRBACKGROUND:
+                Ret = (ULONG_PTR)Class->hbrBackground;
+                if (Ret != 0 && Ret < 0x4000)
+                    Ret = (ULONG_PTR)GetSysColorBrush((ULONG)Ret - 1);
+                break;
+
+            case GCL_HMODULE:
+                //ERR("Cls 0x%x GCL_HMODULE 0x%x\n", Wnd->pcls, Class->hModule);
+                Ret = (ULONG_PTR)Class->hModule;
+                break;
+
+            case GCL_MENUNAME:
+                Ret = (ULONG_PTR)Class->lpszClientAnsiMenuName;
+                break;
+
+            case GCL_STYLE:
+                Ret = (ULONG_PTR)Class->style;
+                break;
+
+            case GCW_ATOM:
+                Ret = (ULONG_PTR)Class->atomClassName;
+                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_WNDPROC:
+                Ret = IntGetClsWndProc(Wnd, Class, TRUE);
+                break;
+
+            default:
+                SetLastError(ERROR_INVALID_INDEX);
+                break;
+        }
+    }
+
+       return Ret;
+}
+
+static ULONG_PTR FASTCALL
+IntGetClassLongW (PWND Wnd, PCLS Class, int nIndex)
+{
+       ULONG_PTR Ret = 0;
+
+    if (nIndex >= 0)
+    {
+        if (nIndex + sizeof(ULONG_PTR) < nIndex ||
+            nIndex + sizeof(ULONG_PTR) > Class->cbclsExtra)
+        {
+            SetLastError(ERROR_INVALID_PARAMETER);
+        }
+        else
+            Ret = *(PULONG_PTR)((ULONG_PTR)(Class + 1) + nIndex);
+    }
+    else
+    {
+        switch (nIndex)
+        {
+            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;
+                if (Ret != 0 && Ret < 0x4000)
+                    Ret = (ULONG_PTR)GetSysColorBrush((ULONG)Ret - 1);
+                break;
+
+            case GCL_HMODULE:
+                Ret = (ULONG_PTR)Class->hModule;
+                break;
+
+            case GCLP_MENUNAME:
+                Ret = (ULONG_PTR)Class->lpszClientUnicodeMenuName;
+                break;
+
+            case GCL_STYLE:
+                Ret = (ULONG_PTR)Class->style;
+                break;
+
+            case GCW_ATOM:
+                Ret = (ULONG_PTR)Class->atomClassName;
+                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_WNDPROC:
+                Ret = IntGetClsWndProc(Wnd, Class, FALSE);
+                break;
+
+            default:
+                SetLastError(ERROR_INVALID_INDEX);
+                break;
+        }
+    }
+
+       return Ret;
+}
+
 /*
  * @implemented
  */
@@ -351,95 +515,39 @@ GetClassLongA(HWND hWnd, int nIndex)
         Class = DesktopPtrToUser(Wnd->pcls);
         if (Class != NULL)
         {
-            if (nIndex >= 0)
-            {
-                if (nIndex + sizeof(ULONG_PTR) < nIndex ||
-                    nIndex + sizeof(ULONG_PTR) > Class->cbclsExtra)
-                {
-                    SetLastError(ERROR_INVALID_PARAMETER);
-                }
-                else
-                    Ret = *(PULONG_PTR)((ULONG_PTR)(Class + 1) + nIndex);
-            }
-            else
-            {
-                switch (nIndex)
-                {
-                    case GCL_CBWNDEXTRA:
-                        Ret = (ULONG_PTR)Class->cbwndExtra;
-                        break;
-
-                    case GCL_CBCLSEXTRA:
-                        Ret = (ULONG_PTR)Class->cbclsExtra;
-                        break;
-
-                    case GCL_HBRBACKGROUND:
-                        Ret = (ULONG_PTR)Class->hbrBackground;
-                        if (Ret != 0 && Ret < 0x4000)
-                            Ret = (ULONG_PTR)GetSysColorBrush((ULONG)Ret - 1);
-                        break;
-
-                    case GCL_HMODULE:
-                        //ERR("Cls 0x%x GCL_HMODULE 0x%x\n", Wnd->pcls, Class->hModule);
-                        Ret = (ULONG_PTR)Class->hModule;
-                        break;
-
-                    case GCL_MENUNAME:
-                        Ret = (ULONG_PTR)Class->lpszClientAnsiMenuName;
-                        break;
-
-                    case GCL_STYLE:
-                        Ret = (ULONG_PTR)Class->style;
-                        break;
-
-                    case GCW_ATOM:
-                        Ret = (ULONG_PTR)Class->atomClassName;
-                        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_WNDPROC:
-                        Ret = IntGetClsWndProc(Wnd, Class, TRUE);
-                        break;
-
-                    default:
-                        SetLastError(ERROR_INVALID_INDEX);
-                        break;
-                }
-            }
+#ifdef _WIN64
+                       switch (nIndex)
+                       {
+                               case GCLP_HBRBACKGROUND:
+                               case GCLP_HCURSOR:
+                               case GCLP_HICON:
+                               case GCLP_HICONSM:
+                               case GCLP_HMODULE:
+                               case GCLP_MENUNAME:
+                               case GCLP_WNDPROC:
+                                       SetLastError(ERROR_INVALID_INDEX);
+                                       break;
+
+                               default:
+                                       Ret = IntGetClassLongA(Wnd, Class, nIndex);
+                                       break;
+                       }
+#else
+                       Ret = IntGetClassLongA(Wnd, Class, nIndex);
+#endif
         }
         else
         {
-            /* This is a race condition! Call win32k to make sure we're getting
-               the correct result */
-            Wnd = NULL; /* Make sure we call NtUserGetClassLong */
-
             WARN("Invalid class for hwnd 0x%p!\n", hWnd);
         }
     }
     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
     {
-        Wnd = NULL; /* Make sure we call NtUserGetClassLong */
+        Ret = 0;
     }
     _SEH2_END;
 
-    if (Wnd == NULL)
-        Ret = NtUserGetClassLong(hWnd, nIndex, TRUE);
-
-    return Ret;
+    return (DWORD)Ret;
 }
 
 /*
@@ -463,95 +571,120 @@ GetClassLongW ( HWND hWnd, int nIndex )
         Class = DesktopPtrToUser(Wnd->pcls);
         if (Class != NULL)
         {
-            if (nIndex >= 0)
-            {
-                if (nIndex + sizeof(ULONG_PTR) < nIndex ||
-                    nIndex + sizeof(ULONG_PTR) > Class->cbclsExtra)
-                {
-                    SetLastError(ERROR_INVALID_PARAMETER);
-                }
-                else
-                    Ret = *(PULONG_PTR)((ULONG_PTR)(Class + 1) + nIndex);
-            }
-            else
-            {
-                switch (nIndex)
-                {
-                    case GCL_CBWNDEXTRA:
-                        Ret = (ULONG_PTR)Class->cbwndExtra;
-                        break;
-
-                    case GCL_CBCLSEXTRA:
-                        Ret = (ULONG_PTR)Class->cbclsExtra;
-                        break;
-
-                    case GCL_HBRBACKGROUND:
-                        Ret = (ULONG_PTR)Class->hbrBackground;
-                        if (Ret != 0 && Ret < 0x4000)
-                            Ret = (ULONG_PTR)GetSysColorBrush((ULONG)Ret - 1);
-                        break;
-
-                    case GCL_HMODULE:
-                        Ret = (ULONG_PTR)Class->hModule;
-                        break;
-
-                    case GCL_MENUNAME:
-                        Ret = (ULONG_PTR)Class->lpszClientUnicodeMenuName;
-                        break;
-
-                    case GCL_STYLE:
-                        Ret = (ULONG_PTR)Class->style;
-                        break;
-
-                    case GCW_ATOM:
-                        Ret = (ULONG_PTR)Class->atomClassName;
-                        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_WNDPROC:
-                        Ret = IntGetClsWndProc(Wnd, Class, FALSE);
-                        break;
-
-                    default:
-                        SetLastError(ERROR_INVALID_INDEX);
-                        break;
-                }
-            }
+#ifdef _WIN64
+                       switch (nIndex)
+                       {
+                               case GCLP_HBRBACKGROUND:
+                               case GCLP_HCURSOR:
+                               case GCLP_HICON:
+                               case GCLP_HICONSM:
+                               case GCLP_HMODULE:
+                               case GCLP_MENUNAME:
+                               case GCLP_WNDPROC:
+                                       SetLastError(ERROR_INVALID_INDEX);
+                                       break;
+
+                               default:
+                                       Ret = IntGetClassLongW(Wnd, Class, nIndex);
+                                       break;
+                       }
+#else
+                       Ret = IntGetClassLongW(Wnd, Class, nIndex);
+#endif
         }
         else
         {
-            /* This is a race condition! Call win32k to make sure we're getting
-               the correct result */
-            Wnd = NULL; /* Make sure we call NtUserGetClassLong */
+            WARN("Invalid class for hwnd 0x%p!\n", hWnd);
+        }
+    }
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+    {
+        Ret = 0;
+    }
+    _SEH2_END;
 
+    return (DWORD)Ret;
+}
+
+#ifdef _WIN64
+/*
+ * @implemented
+ */
+ULONG_PTR
+WINAPI
+GetClassLongPtrA(HWND hWnd,
+                 INT nIndex)
+{
+    PWND Wnd;
+    PCLS Class;
+    ULONG_PTR Ret = 0;
+
+    TRACE("%p %d\n", hWnd, nIndex);
+
+    Wnd = ValidateHwnd(hWnd);
+    if (!Wnd)
+        return 0;
+
+    _SEH2_TRY
+    {
+        Class = DesktopPtrToUser(Wnd->pcls);
+        if (Class != NULL)
+        {
+                       Ret = IntGetClassLongA(Wnd, Class, nIndex);
+        }
+        else
+        {
             WARN("Invalid class for hwnd 0x%p!\n", hWnd);
         }
     }
     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
     {
-        Wnd = NULL; /* Make sure we call NtUserGetClassLong */
+        Ret = 0;
     }
     _SEH2_END;
 
-    if (Wnd == NULL)
-        Ret = NtUserGetClassLong(hWnd, nIndex, FALSE);
+    return Ret;
+}
+
+/*
+ * @implemented
+ */
+ULONG_PTR
+WINAPI
+GetClassLongPtrW(HWND hWnd,
+                 INT nIndex)
+{
+    PWND Wnd;
+    PCLS Class;
+    ULONG_PTR Ret = 0;
+
+    TRACE("%p %d\n", hWnd, nIndex);
+
+    Wnd = ValidateHwnd(hWnd);
+    if (!Wnd)
+        return 0;
+
+    _SEH2_TRY
+    {
+        Class = DesktopPtrToUser(Wnd->pcls);
+        if (Class != NULL)
+        {
+                       Ret = IntGetClassLongW(Wnd, Class, nIndex);
+        }
+        else
+        {
+            WARN("Invalid class for hwnd 0x%p!\n", hWnd);
+        }
+    }
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+    {
+        Ret = 0;
+    }
+    _SEH2_END;
 
     return Ret;
 }
+#endif
 
 
 /*
@@ -617,79 +750,99 @@ GetClassNameW(
 WORD
 WINAPI
 GetClassWord(
-  HWND hWnd,
-  int nIndex)
-/*
- * NOTE: Obsoleted in 32-bit windows
- */
+  HWND hwnd,
+  int offset)
 {
-    TRACE("%p %x\n", hWnd, nIndex);
+    PWND Wnd;
+    PCLS class;
+    WORD retvalue = 0;
 
-    if ((nIndex < 0) && (nIndex != GCW_ATOM))
+    if (offset < 0) return GetClassLongA( hwnd, offset );
+
+    Wnd = ValidateHwnd(hwnd);
+    if (!Wnd)
         return 0;
 
-    return (WORD) NtUserGetClassLong ( hWnd, nIndex, TRUE );
+    class = DesktopPtrToUser(Wnd->pcls);
+    if (class == NULL) return 0;
+
+    if (offset <= class->cbclsExtra - sizeof(WORD))
+        memcpy( &retvalue, (char *)(class + 1) + offset, sizeof(retvalue) );
+    else
+        SetLastError( ERROR_INVALID_INDEX );
+
+    return retvalue;
 }
 
 
-/*
- * @implemented
- */
-LONG
-WINAPI
-GetWindowLongA ( HWND hWnd, int nIndex )
+LONG_PTR IntGetWindowLong( HWND hwnd, INT offset, UINT size, BOOL unicode )
 {
-    PWND Wnd;
+    LONG_PTR retvalue = 0;
+    WND *wndPtr;
 
-    Wnd = ValidateHwnd(hWnd);
-    if (Wnd == NULL)
+    if (offset == GWLP_HWNDPARENT)
+    {
+        HWND parent = GetAncestor( hwnd, GA_PARENT );
+        if (parent == GetDesktopWindow()) parent = GetWindow( hwnd, GW_OWNER );
+        return (ULONG_PTR)parent;
+    }
+
+    if (!(wndPtr = ValidateHwnd( hwnd )))
+    {
+        SetLastError( ERROR_INVALID_WINDOW_HANDLE );
         return 0;
+    }
 
-    if (nIndex >= 0)
+    if (offset >= 0)
     {
-        if ((DWORD)nIndex + sizeof(LONG) > Wnd->cbwndExtra)
+        if (offset > (int)(wndPtr->cbwndExtra - size))
         {
-            SetLastError(ERROR_INVALID_PARAMETER);
+            WARN("Invalid offset %d\n", offset );
+            SetLastError( ERROR_INVALID_INDEX );
             return 0;
         }
-        return *((LONG *)((PCHAR)(Wnd + 1) + nIndex));
+        retvalue = *((LONG_PTR *)((PCHAR)(wndPtr + 1) + offset));
+
+        /* WINE: special case for dialog window procedure */
+        //if ((offset == DWLP_DLGPROC) && (size == sizeof(LONG_PTR)) && (wndPtr->flags & WIN_ISDIALOG))
+        //    retvalue = (LONG_PTR)IntGetWndProc( (WNDPROC)retvalue, unicode );
+        return retvalue;
     }
-    else
-    {
-        switch (nIndex)
-        {
-            case GWL_EXSTYLE:
-                return Wnd->ExStyle;
-            case GWL_STYLE:
-                return Wnd->style;
-            case GWL_HINSTANCE:
-                return (LONG)Wnd->hModule;
-            case GWL_ID:
-                return Wnd->IDMenu;
-            case GWL_USERDATA:
-                return Wnd->dwUserData;
-
-            case GWL_HWNDPARENT:
-            {
-                HWND parent = GetAncestor( hWnd, GA_PARENT );
-                if (parent == GetDesktopWindow()) parent = GetWindow( hWnd, GW_OWNER );
-                return (LONG)parent;
-            }
-            case GWL_WNDPROC:
-                if (!TestWindowProcess(Wnd))
-                {
-                   SetLastError(ERROR_ACCESS_DENIED);
-                   return 0;
-                }
-                return IntGetWndProc(Wnd, TRUE);
 
-            default:
-                SetLastError(ERROR_INVALID_PARAMETER);
-                return 0;
-        }
+    switch(offset)
+    {
+    case GWLP_USERDATA:  retvalue = wndPtr->dwUserData; break;
+    case GWL_STYLE:      retvalue = wndPtr->style; break;
+    case GWL_EXSTYLE:    retvalue = wndPtr->ExStyle; break;
+    case GWLP_ID:        retvalue = wndPtr->IDMenu; break;
+    case GWLP_HINSTANCE: retvalue = (ULONG_PTR)wndPtr->hModule; break;
+    case GWLP_WNDPROC:
+       {
+               if (!TestWindowProcess(wndPtr))
+               {
+                       SetLastError(ERROR_ACCESS_DENIED);
+                       retvalue = 0;
+               }
+               retvalue = (ULONG_PTR)IntGetWndProc(wndPtr, !unicode);
+        break;
+       }
+    default:
+        WARN("Unknown offset %d\n", offset );
+        SetLastError( ERROR_INVALID_INDEX );
+        break;
     }
-}
+    return retvalue;
 
+}
+/*
+ * @implemented
+ */
+LONG
+WINAPI
+GetWindowLongA ( HWND hWnd, int nIndex )
+{
+    return IntGetWindowLong( hWnd, nIndex, sizeof(LONG), FALSE );
+}
 
 /*
  * @implemented
@@ -698,75 +851,57 @@ LONG
 WINAPI
 GetWindowLongW(HWND hWnd, int nIndex)
 {
-    PWND Wnd;
-
-    Wnd = ValidateHwnd(hWnd);
-    if (Wnd == NULL)
-        return 0;
-
-    if (nIndex >= 0)
-    {
-        if ((DWORD)nIndex + sizeof(LONG) > Wnd->cbwndExtra)
-        {
-            SetLastError(ERROR_INVALID_PARAMETER);
-            return 0;
-        }
-        return *((LONG *)((PCHAR)(Wnd + 1) + nIndex));
-    }
-    else
-    {
-        switch (nIndex)
-        {
-            case GWL_EXSTYLE:
-                return Wnd->ExStyle;
-            case GWL_STYLE:
-                return Wnd->style;
-            case GWL_HINSTANCE:
-                return (LONG)Wnd->hModule;
-            case GWL_ID:
-                return Wnd->IDMenu;
-            case GWL_USERDATA:
-                return Wnd->dwUserData;
-
-            case GWL_HWNDPARENT:
-            {
-                HWND parent = GetAncestor( hWnd, GA_PARENT );
-                if (parent == GetDesktopWindow()) parent = GetWindow( hWnd, GW_OWNER );
-                return (LONG)parent;
-            }
-            case GWL_WNDPROC:
-                if (!TestWindowProcess(Wnd))
-                {
-                   SetLastError(ERROR_ACCESS_DENIED);
-                   return 0;
-                }
-                return IntGetWndProc(Wnd, FALSE);
+    return IntGetWindowLong( hWnd, nIndex, sizeof(LONG), TRUE );
+}
 
-            default:
-                SetLastError(ERROR_INVALID_PARAMETER);
-                return 0;
-        }
-    }
+#ifdef _WIN64
+/*
+ * @implemented
+ */
+LONG_PTR
+WINAPI
+GetWindowLongPtrA(HWND hWnd,
+                  INT nIndex)
+{
+    return IntGetWindowLong( hWnd, nIndex, sizeof(LONG_PTR), FALSE );
 }
 
 /*
  * @implemented
  */
-WORD
+LONG_PTR
 WINAPI
-GetWindowWord(HWND hWnd, int nIndex)
+GetWindowLongPtrW(HWND hWnd,
+                  INT nIndex)
 {
-  return (WORD)GetWindowLongW(hWnd, nIndex);
+    return IntGetWindowLong( hWnd, nIndex, sizeof(LONG_PTR), TRUE );
+
 }
+#endif // _WIN64
 
 /*
  * @implemented
  */
 WORD
 WINAPI
-SetWindowWord ( HWND hWnd,int nIndex,WORD wNewWord )
+GetWindowWord(HWND hWnd, int nIndex)
 {
-  return (WORD)NtUserSetWindowLong ( hWnd, nIndex, (LONG)wNewWord, TRUE );
+    switch(nIndex)
+    {
+    case GWLP_ID:
+    case GWLP_HINSTANCE:
+    case GWLP_HWNDPARENT:
+        break;
+    default:
+        if (nIndex < 0)
+        {
+            WARN("Invalid offset %d\n", nIndex );
+            SetLastError( ERROR_INVALID_INDEX );
+            return 0;
+        }
+        break;
+    }
+    return IntGetWindowLong( hWnd, nIndex, sizeof(WORD), FALSE );
 }
 
 /*
@@ -809,7 +944,6 @@ CreateSmallIcon(HICON StdIcon)
    int SmallIconWidth;
    int SmallIconHeight;
    BITMAP StdBitmapInfo;
-   HDC hInfoDc = NULL;
    HDC hSourceDc = NULL;
    HDC hDestDc = NULL;
    ICONINFO SmallInfo;
@@ -845,15 +979,6 @@ CreateSmallIcon(HICON StdIcon)
       return StdIcon;
    }
 
-   /* Get a handle to a info DC and handles to DCs which can be used to
-      select a bitmap into. This is done to avoid triggering a switch to
-      graphics mode (if we're currently in text/blue screen mode) */
-   hInfoDc = CreateICW(NULL, NULL, NULL, NULL);
-   if (NULL == hInfoDc)
-   {
-      ERR("Failed to create info DC\n");
-      goto cleanup;
-   }
    hSourceDc = CreateCompatibleDC(NULL);
    if (NULL == hSourceDc)
    {
@@ -873,7 +998,7 @@ CreateSmallIcon(HICON StdIcon)
       ERR("Failed to select source color bitmap\n");
       goto cleanup;
    }
-   SmallInfo.hbmColor = CreateCompatibleBitmap(hInfoDc, SmallIconWidth,
+   SmallInfo.hbmColor = CreateCompatibleBitmap(hSourceDc, SmallIconWidth,
                                               SmallIconHeight);
    if (NULL == SmallInfo.hbmColor)
    {
@@ -899,8 +1024,7 @@ CreateSmallIcon(HICON StdIcon)
       ERR("Failed to select source mask bitmap\n");
       goto cleanup;
    }
-   SmallInfo.hbmMask = CreateBitmap(SmallIconWidth, SmallIconHeight, 1, 1,
-                                    NULL);
+   SmallInfo.hbmMask = CreateCompatibleBitmap(hSourceDc, SmallIconWidth, SmallIconHeight);
    if (NULL == SmallInfo.hbmMask)
    {
       ERR("Failed to create mask bitmap\n");
@@ -954,10 +1078,6 @@ cleanup:
    {
       DeleteDC(hSourceDc);
    }
-   if (NULL != hInfoDc)
-   {
-      DeleteDC(hInfoDc);
-   }
 
    return SmallIcon;
 }
@@ -1048,9 +1168,9 @@ RegisterClassExWOWW(WNDCLASSEXW *lpwcx,
    clsMenuName.pszClientAnsiMenuName = AnsiMenuName.Buffer;
    clsMenuName.pwszClientUnicodeMenuName = MenuName.Buffer;
    clsMenuName.pusMenuName = &MenuName;
-   
+
    Atom = NtUserRegisterClassExWOW( &WndClass,
-                                    &ClassName,  
+                                    &ClassName,
                                      NULL, //PUNICODE_STRING ClsNVersion,
                                     &clsMenuName,
                                      fnID,
@@ -1172,7 +1292,7 @@ SetClassLongA (HWND hWnd,
                int nIndex,
                LONG dwNewLong)
 {
-    PSTR lpStr = (PSTR)dwNewLong;
+    PSTR lpStr = (PSTR)(ULONG_PTR)dwNewLong;
     UNICODE_STRING Value = {0};
     BOOL Allocated = FALSE;
     DWORD Ret;
@@ -1195,7 +1315,7 @@ SetClassLongA (HWND hWnd,
         else
             Value.Buffer = (PWSTR)lpStr;
 
-        dwNewLong = (LONG)&Value;
+        dwNewLong = (LONG_PTR)&Value;
     }
     else if (nIndex == GCW_ATOM && lpStr != NULL)
     {
@@ -1213,7 +1333,7 @@ SetClassLongA (HWND hWnd,
         else
             Value.Buffer = (PWSTR)lpStr;
 
-        dwNewLong = (LONG)&Value;
+        dwNewLong = (LONG_PTR)&Value;
     }
 
     Ret = (DWORD)NtUserSetClassLong(hWnd,
@@ -1239,7 +1359,7 @@ SetClassLongW(HWND hWnd,
               int nIndex,
               LONG dwNewLong)
 {
-    PWSTR lpStr = (PWSTR)dwNewLong;
+    PWSTR lpStr = (PWSTR)(ULONG_PTR)dwNewLong;
     UNICODE_STRING Value = {0};
 
     TRACE("%p %d %lx\n", hWnd, nIndex, dwNewLong);
@@ -1256,7 +1376,7 @@ SetClassLongW(HWND hWnd,
         else
             Value.Buffer = lpStr;
 
-        dwNewLong = (LONG)&Value;
+        dwNewLong = (LONG_PTR)&Value;
     }
     else if (nIndex == GCW_ATOM && lpStr != NULL)
     {
@@ -1268,7 +1388,7 @@ SetClassLongW(HWND hWnd,
         else
             Value.Buffer = lpStr;
 
-        dwNewLong = (LONG)&Value;
+        dwNewLong = (LONG_PTR)&Value;
     }
 
     return (DWORD)NtUserSetClassLong(hWnd,
@@ -1277,6 +1397,33 @@ SetClassLongW(HWND hWnd,
                                      FALSE);
 }
 
+#ifdef _WIN64
+/*
+ * @unimplemented
+ */
+ULONG_PTR
+WINAPI
+SetClassLongPtrA(HWND hWnd,
+                 INT nIndex,
+                 LONG_PTR dwNewLong)
+{
+    UNIMPLEMENTED;
+    return 0;
+}
+
+/*
+ * @unimplemented
+ */
+ULONG_PTR
+WINAPI
+SetClassLongPtrW(HWND hWnd,
+                 INT nIndex,
+                 LONG_PTR dwNewLong)
+{
+    UNIMPLEMENTED;
+    return 0;
+}
+#endif // _WIN64
 
 /*
  * @implemented
@@ -1297,6 +1444,30 @@ SetClassWord(
     return (WORD) SetClassLongW ( hWnd, nIndex, wNewWord );
 }
 
+/*
+ * @implemented
+ */
+WORD
+WINAPI
+SetWindowWord ( HWND hWnd,int nIndex,WORD wNewWord )
+{
+    switch(nIndex)
+    {
+    case GWLP_ID:
+    case GWLP_HINSTANCE:
+    case GWLP_HWNDPARENT:
+        break;
+    default:
+        if (nIndex < 0)
+        {
+            WARN("Invalid offset %d\n", nIndex );
+            SetLastError( ERROR_INVALID_INDEX );
+            return 0;
+        }
+        break;
+    }
+    return NtUserSetWindowLong( hWnd, nIndex, wNewWord, FALSE );
+}
 
 /*
  * @implemented
@@ -1311,7 +1482,6 @@ SetWindowLongA(
   return NtUserSetWindowLong(hWnd, nIndex, dwNewLong, TRUE);
 }
 
-
 /*
  * @implemented
  */
@@ -1325,6 +1495,31 @@ SetWindowLongW(
   return NtUserSetWindowLong(hWnd, nIndex, dwNewLong, FALSE);
 }
 
+#ifdef _WIN64
+/*
+ * @implemented
+ */
+LONG_PTR
+WINAPI
+SetWindowLongPtrA(HWND hWnd,
+                  INT nIndex,
+                  LONG_PTR dwNewLong)
+{
+  return NtUserSetWindowLong(hWnd, nIndex, dwNewLong, FALSE);
+}
+
+/*
+ * @implemented
+ */
+LONG_PTR
+WINAPI
+SetWindowLongPtrW(HWND hWnd,
+                  INT nIndex,
+                  LONG_PTR dwNewLong)
+{
+  return NtUserSetWindowLong(hWnd, nIndex, dwNewLong, FALSE);
+}
+#endif
 
 /*
  * @implemented