-include/ndk/rtltypes.h: add MAX_ATOM_LEN define
authorGunnar Dalsnes <hardon@online.no>
Sat, 24 Sep 2005 02:50:02 +0000 (02:50 +0000)
committerGunnar Dalsnes <hardon@online.no>
Sat, 24 Sep 2005 02:50:02 +0000 (02:50 +0000)
-win32k: remove some NtUser syscalls and merge some NtUser syscalls
-crt/include/internal/file.h: correct spelling
-RtlAddAtomToAtomTable: check for max atom len
-RtlQueryAtomInAtomTable: fix bug. somehow lock wasnt always released.
-fix/reword windows classes impl. based on Wine. All but 2 winetests pass.
-ntoskrnl/rtl/atom.c: add fixme about global atom table
-remove desktop object lock
-dont link windows into the class object
-co_IntShellHookNotify: safely send notify messages
-misc win32k reorg/cleanup

svn path=/trunk/; revision=18022

23 files changed:
reactos/include/ndk/rtltypes.h
reactos/include/win32k/ntuser.h
reactos/lib/crt/include/internal/file.h
reactos/lib/rtl/atom.c
reactos/lib/user32/windows/caret.c
reactos/lib/user32/windows/class.c
reactos/lib/user32/windows/paint.c
reactos/lib/user32/windows/window.c
reactos/ntoskrnl/rtl/atom.c
reactos/subsys/win32k/include/class.h
reactos/subsys/win32k/include/desktop.h
reactos/subsys/win32k/include/win32.h
reactos/subsys/win32k/include/window.h
reactos/subsys/win32k/main/dllmain.c
reactos/subsys/win32k/ntuser/caret.c
reactos/subsys/win32k/ntuser/class.c
reactos/subsys/win32k/ntuser/cursoricon.c
reactos/subsys/win32k/ntuser/desktop.c
reactos/subsys/win32k/ntuser/misc.c
reactos/subsys/win32k/ntuser/painting.c
reactos/subsys/win32k/ntuser/window.c
reactos/subsys/win32k/ntuser/winsta.c
reactos/tools/nci/w32ksvc.db

index e8e9269..4620416 100644 (file)
 #define NLS_MB_OEM_CODE_PAGE_TAG NlsMbOemCodePageTag
 #define NLS_OEM_LEAD_BYTE_INFO NlsOemLeadByteInfo
 
+#define MAX_ATOM_LEN              255 /* TCHARS not including nullterm */
+
 /* List Macros */
 static __inline
 VOID
index 5343246..eb34926 100644 (file)
@@ -212,7 +212,6 @@ NtUserCallOneParam(
 #define TWOPARAM_ROUTINE_UNKNOWN            0x54
 #define TWOPARAM_ROUTINE_SHOWOWNEDPOPUPS    0x55
 #define TWOPARAM_ROUTINE_SWITCHTOTHISWINDOW 0x56
-#define TWOPARAM_ROUTINE_VALIDATERGN        0x57
 #define TWOPARAM_ROUTINE_SETWNDCONTEXTHLPID 0x58
 #define TWOPARAM_ROUTINE_SETCARETPOS        0x60
 #define TWOPARAM_ROUTINE_GETWINDOWINFO      0x61
@@ -894,11 +893,6 @@ NtUserGetWOWClass(
   DWORD Unknown0,
   DWORD Unknown1);
 
-BOOL
-STDCALL
-NtUserHideCaret(
-  HWND hWnd);
-
 DWORD
 STDCALL
 NtUserImpersonateDdeClientWindow(
@@ -935,20 +929,6 @@ NtUserInternalGetWindowText(
   LPWSTR lpString,
   INT nMaxCount);
 
-DWORD
-STDCALL
-NtUserInvalidateRect(
-HWND hWnd,
-CONST RECT *lpRect,
-BOOL bErase);
-
-DWORD
-STDCALL
-  NtUserInvalidateRgn(
-  HWND hWnd,
-  HRGN hRgn,
-  BOOL bErase);
-
 
 BOOL
 STDCALL
@@ -1575,7 +1555,8 @@ NtUserSetWinEventHook(
 BOOL
 STDCALL
 NtUserShowCaret(
-  HWND hWnd);
+  HWND hWnd,
+  BOOL bShow);
 
 DWORD
 STDCALL
@@ -1681,9 +1662,6 @@ NtUserUpdateInstance(
   DWORD Unknown1,
   DWORD Unknown2);
 
-BOOL STDCALL
-NtUserUpdateWindow( HWND hWnd );
-
 DWORD
 STDCALL
 NtUserUpdateLayeredWindow(
@@ -1715,10 +1693,6 @@ STDCALL
 NtUserValidateHandleSecure(
   DWORD Unknown0);
 
-VOID STDCALL
-NtUserValidateRect(HWND Wnd, const RECT* Rect);
-
-
 DWORD
 STDCALL
 NtUserVkKeyScanEx(
index 1a9fe09..edd99a0 100644 (file)
@@ -102,7 +102,7 @@ typedef struct _FDINFO
 #define fdinfo_bucket_idx(i) ((i) >> FDINFO_ENTRIES_PER_BUCKET_SHIFT)
 /* get position inside a bucket (0-31) from an fd */
 #define fdinfo_bucket_entry_idx(i) ((i) & (FDINFO_ENTRIES_PER_BUCKET - 1))
-/* get bucket ptr. (ptr. to fist fdinfo inside a bucket) from an fd */
+/* get bucket ptr. (ptr. to first fdinfo inside a bucket) from an fd */
 #define fdinfo_bucket(i) ( __pioinfo[fdinfo_bucket_idx(i)])
 /* get fdinfo ptr. from an fd */
 #define fdinfo(i) (fdinfo_bucket(i) + fdinfo_bucket_entry_idx(i))
index 67ed9a5..fc54bb3 100644 (file)
@@ -347,6 +347,12 @@ RtlAddAtomToAtomTable(IN PRTL_ATOM_TABLE AtomTable,
         if (HashLink != NULL)
           {
              ULONG AtomNameLen = wcslen(AtomName);
+             
+             if (AtomNameLen > MAX_ATOM_LEN)
+             {
+                Status = STATUS_INVALID_PARAMETER;
+                goto end;
+             }
 
              Entry = RtlpAllocAtomTableEntry(sizeof(RTL_ATOM_TABLE_ENTRY) -
                                              sizeof(Entry->Name) +
@@ -390,7 +396,7 @@ RtlAddAtomToAtomTable(IN PRTL_ATOM_TABLE AtomTable,
              Status = STATUS_OBJECT_NAME_INVALID;
           }
      }
-
+end:
    RtlpUnlockAtomTable(AtomTable);
 
    return Status;
@@ -592,6 +598,8 @@ RtlQueryAtomInAtomTable(PRTL_ATOM_TABLE AtomTable,
                         PULONG NameLength)
 {
    ULONG Length;
+   BOOL Unlock = FALSE;
+   
    union
      {
      /* A RTL_ATOM_TABLE_ENTRY has a "WCHAR Name[1]" entry at the end.
@@ -616,6 +624,7 @@ RtlQueryAtomInAtomTable(PRTL_ATOM_TABLE AtomTable,
    else
      {
         RtlpLockAtomTable(AtomTable);
+        Unlock = TRUE;
 
         Entry = RtlpGetAtomEntry(AtomTable,
                                  (ULONG)((USHORT)Atom - 0xC000));
@@ -676,10 +685,7 @@ RtlQueryAtomInAtomTable(PRTL_ATOM_TABLE AtomTable,
         Status = STATUS_INVALID_HANDLE;
      }
 
-   if (NULL != Entry && Entry != &NumberEntry.AtomTableEntry)
-     {
-        RtlpUnlockAtomTable(AtomTable);
-     }
+   if (Unlock) RtlpUnlockAtomTable(AtomTable);
 
    return Status;
 }
index a461bfa..95b76d0 100644 (file)
@@ -108,7 +108,7 @@ GetCaretPos(LPPOINT lpPoint)
 BOOL STDCALL
 HideCaret(HWND hWnd)
 {
-  return (BOOL)NtUserHideCaret(hWnd);
+  return NtUserShowCaret(hWnd, FALSE);
 }
 
 
@@ -139,7 +139,7 @@ SetCaretPos(int X,
 BOOL STDCALL
 ShowCaret(HWND hWnd)
 {
-  return (BOOL)NtUserShowCaret(hWnd);
+  return NtUserShowCaret(hWnd, TRUE);
 }
 
 /* EOF */
index de26575..9922089 100644 (file)
@@ -87,7 +87,14 @@ static BOOL GetClassInfoExCommon(
 
   w.lpszMenuName = (LPCWSTR)&str2;
   w.lpszClassName = (LPCWSTR)&str3;
+  
+  /* get info about system classes? */
+  if (!hInst) hInst = User32Instance;
+  
   retval = (BOOL)NtUserGetClassInfo(hInst, str, &w, TRUE, 0);
+  
+  w.hInstance = (hInst == User32Instance) ? 0 : hInst;
+  
   if ( !IS_ATOM(str) )
     HEAP_free(str);
 
index c4734d0..7ae652f 100644 (file)
@@ -157,7 +157,7 @@ InvalidateRect(
   CONST RECT *lpRect,
   BOOL bErase)
 {
-  return NtUserInvalidateRect( hWnd, lpRect, bErase );
+  return RedrawWindow( hWnd, lpRect, 0, RDW_INVALIDATE | (bErase ? RDW_ERASE : 0) ); 
 }
 
 
@@ -171,7 +171,7 @@ InvalidateRgn(
   HRGN hRgn,
   BOOL bErase)
 {
-  return NtUserInvalidateRgn( hWnd, hRgn, bErase );
+  return RedrawWindow(hWnd, NULL, hRgn, RDW_INVALIDATE | (bErase ? RDW_ERASE : 0) ); 
 }
 
 
@@ -224,7 +224,7 @@ STDCALL
 UpdateWindow(
   HWND hWnd)
 {
-  return NtUserUpdateWindow( hWnd );
+  return RedrawWindow( hWnd, NULL, 0, RDW_UPDATENOW | RDW_ALLCHILDREN );
 }
 
 
@@ -237,6 +237,8 @@ ValidateRect(
   HWND hWnd,
   CONST RECT *lpRect)
 {
+  /* FIXME: should RDW_NOCHILDREN be included too? Ros used to,
+     but Wine dont so i removed it... */
   return RedrawWindow(hWnd, lpRect, 0, RDW_VALIDATE);
 }
 
@@ -250,7 +252,9 @@ ValidateRgn(
   HWND hWnd,
   HRGN hRgn)
 {
-  return NtUserValidateRgn(hWnd, hRgn);
+  /* FIXME: should RDW_NOCHILDREN be included too? Ros used to,
+     but Wine dont so i removed it... */
+  return RedrawWindow( hWnd, NULL, hRgn, RDW_VALIDATE );
 }
 
 
index 7aaf4b5..d58164e 100644 (file)
@@ -221,7 +221,7 @@ CreateWindowExA(DWORD dwExStyle,
                                nHeight,
                                hWndParent,
                                hMenu,
-                               hInstance,
+            hInstance,
                                lpParam,
                                SW_SHOW,
                                FALSE);
@@ -304,7 +304,7 @@ CreateWindowExW(DWORD dwExStyle,
                                nHeight,
                                hWndParent,
                                hMenu,
-                               hInstance,
+            hInstance,
                                lpParam,
                                SW_SHOW,
                                TRUE);
index ed9d3bd..cfd6a2f 100644 (file)
@@ -14,6 +14,7 @@
 #define NDEBUG
 #include <internal/debug.h>
 
+
 /* PROTOTYPES ****************************************************************/
 
 static PRTL_ATOM_TABLE RtlpGetGlobalAtomTable(VOID);
@@ -38,6 +39,12 @@ RtlQueryAtomListInAtomTable(IN PRTL_ATOM_TABLE AtomTable,
 
 /* GLOBALS *******************************************************************/
 
+/* FIXME: this is WRONG! The global atom table should live in the WinSta struct
+ * and accessed thru win32k callouts.
+ * NOTE: There is a session/win32k global atom table also, but its private to
+ * win32k. Its used for RegisterWindowMessage() and for window classes.
+ * -Gunnar
+ */
 static PRTL_ATOM_TABLE GlobalAtomTable = NULL;
 
 /* FUNCTIONS *****************************************************************/
index d1dbde1..bcc034e 100644 (file)
@@ -7,6 +7,7 @@
 typedef struct _WNDCLASS_OBJECT
 {
   UINT    cbSize;
+  LONG    refs;                  /* windows using this class (is 0 after class creation) */
   UINT    style;
   WNDPROC lpfnWndProcA;
   WNDPROC lpfnWndProcW;
@@ -21,10 +22,8 @@ typedef struct _WNDCLASS_OBJECT
   HICON   hIconSm;
   BOOL Unicode;
   BOOL Global;
-  LIST_ENTRY ListEntry;
+  LIST_ENTRY ListEntry;          /* linked into owning process */
   PCHAR   ExtraData;
-  /* list of windows */
-  LIST_ENTRY ClassWindowsListHead;
 } WNDCLASS_OBJECT, *PWNDCLASS_OBJECT;
 
 NTSTATUS FASTCALL
@@ -33,24 +32,26 @@ InitClassImpl(VOID);
 NTSTATUS FASTCALL
 CleanupClassImpl(VOID);
 
-#define ClassDereferenceObject(ClassObj) \
-  ObmDereferenceObject(ClassObj)
+void FASTCALL DestroyProcessClasses(PW32PROCESS Process );
 
-BOOL FASTCALL
-ClassReferenceClassByAtom(
-   PWNDCLASS_OBJECT* Class,
+inline VOID FASTCALL 
+ClassDerefObject(PWNDCLASS_OBJECT Class);
+
+inline VOID FASTCALL 
+ClassRefObject(PWNDCLASS_OBJECT Class);
+
+PWNDCLASS_OBJECT FASTCALL
+ClassGetClassByAtom(
    RTL_ATOM Atom,
    HINSTANCE hInstance);
 
-BOOL FASTCALL
-ClassReferenceClassByName(
-   PWNDCLASS_OBJECT *Class,
+PWNDCLASS_OBJECT FASTCALL
+ClassGetClassByName(
    LPCWSTR ClassName,
    HINSTANCE hInstance);
 
-BOOL FASTCALL
-ClassReferenceClassByNameOrAtom(
-   PWNDCLASS_OBJECT *Class,
+PWNDCLASS_OBJECT FASTCALL
+ClassGetClassByNameOrAtom(
    LPCWSTR ClassNameOrAtom,
    HINSTANCE hInstance);
 
index 4edb045..5853126 100644 (file)
@@ -11,7 +11,7 @@ typedef struct _DESKTOP_OBJECT
     CSHORT Type;
     CSHORT Size;
     LIST_ENTRY ListEntry;
-    KSPIN_LOCK Lock;
+
     UNICODE_STRING Name;
     /* Pointer to the associated window station. */
     struct _WINSTATION_OBJECT *WindowStation;
index 08505e7..a1f57fd 100644 (file)
@@ -22,7 +22,7 @@ typedef struct _W32THREAD
 
 typedef struct _W32PROCESS
 {
-  LIST_ENTRY ClassListHead;
+  LIST_ENTRY ClassList;
   LIST_ENTRY MenuListHead;
   FAST_MUTEX PrivateFontListLock;
   LIST_ENTRY PrivateFontListHead;
index c9b01a9..6fe5799 100644 (file)
@@ -28,8 +28,6 @@ typedef struct _WINDOW_OBJECT
 {
   /* Pointer to the window class. */
   PWNDCLASS_OBJECT Class;
-  /* entry in the window list of the class object */
-  LIST_ENTRY ClassListEntry;
   /* Extended style. */
   DWORD ExStyle;
   /* Window name. */
index 7697dbf..f79c3a2 100644 (file)
@@ -70,7 +70,7 @@ Win32kProcessCallback(struct _EPROCESS *Process,
     {
       DPRINT("Creating W32 process PID:%d at IRQ level: %lu\n", Process->UniqueProcessId, KeGetCurrentIrql());
 
-      InitializeListHead(&Win32Process->ClassListHead);
+      InitializeListHead(&Win32Process->ClassList);
 
       InitializeListHead(&Win32Process->MenuListHead);
 
@@ -99,7 +99,9 @@ Win32kProcessCallback(struct _EPROCESS *Process,
       IntCleanupCurIcons(Process, Win32Process);
       IntEngCleanupDriverObjs(Process, Win32Process);
       CleanupMonitorImpl();
-
+      
+      /* no process windows should exist at this point, or the function will assert! */
+      DestroyProcessClasses(Win32Process);
 
       GDI_CleanupForProcess(Process);
 
index 18822d3..bd621dc 100644 (file)
@@ -9,17 +9,24 @@
  *       10/15/2003  Created
  */
 
+/* INCLUDES ******************************************************************/
+
 #include <w32k.h>
 
 #define NDEBUG
 #include <debug.h>
 
+/* DEFINES *****************************************************************/
+
 #define MIN_CARETBLINKRATE 100
 #define MAX_CARETBLINKRATE 10000
 #define DEFAULT_CARETBLINKRATE 530
 #define CARET_REGKEY L"\\Registry\\User\\.Default\\Control Panel\\Desktop"
 #define CARET_VALUENAME L"CursorBlinkRate"
 
+/* FUNCTIONS *****************************************************************/
+
+static
 BOOL FASTCALL
 co_IntHideCaret(PTHRDCARETINFO CaretInfo)
 {
@@ -69,6 +76,7 @@ IntSetCaretBlinkTime(UINT uMSeconds)
    return TRUE;
 }
 
+static
 UINT FASTCALL
 IntQueryCaretBlinkRate(VOID)
 {
@@ -134,6 +142,7 @@ IntQueryCaretBlinkRate(VOID)
    return (UINT)Val;
 }
 
+static
 UINT FASTCALL
 IntGetCaretBlinkTime(VOID)
 {
@@ -158,6 +167,7 @@ IntGetCaretBlinkTime(VOID)
    return Ret;
 }
 
+
 BOOL FASTCALL
 co_IntSetCaretPos(int X, int Y)
 {
@@ -197,6 +207,8 @@ IntSwitchCaretShowing(PVOID Info)
    return FALSE;
 }
 
+#if 0 //unused
+static
 VOID FASTCALL
 co_IntDrawCaret(HWND hWnd)
 {
@@ -210,8 +222,78 @@ co_IntDrawCaret(HWND hWnd)
       ThreadQueue->CaretInfo->Showing = 1;
    }
 }
+#endif
+
+
+
+BOOL FASTCALL co_UserHideCaret(PWINDOW_OBJECT Window OPTIONAL)
+{
+   PUSER_MESSAGE_QUEUE ThreadQueue;
+
+   if (Window) ASSERT_REFS_CO(Window);
+
+   if(Window && Window->OwnerThread != PsGetCurrentThread())
+   {
+      SetLastWin32Error(ERROR_ACCESS_DENIED);
+      return FALSE;
+   }
+
+   ThreadQueue = (PUSER_MESSAGE_QUEUE)PsGetWin32Thread()->MessageQueue;
+
+   if(Window && ThreadQueue->CaretInfo->hWnd != Window->hSelf)
+   {
+      SetLastWin32Error(ERROR_ACCESS_DENIED);
+      return FALSE;
+   }
+
+   if(ThreadQueue->CaretInfo->Visible)
+   {
+      IntKillTimer(ThreadQueue->CaretInfo->hWnd, IDCARETTIMER, TRUE);
+
+      co_IntHideCaret(ThreadQueue->CaretInfo);
+      ThreadQueue->CaretInfo->Visible = 0;
+      ThreadQueue->CaretInfo->Showing = 0;
+   }
+
+   return TRUE;
+}
+
+
+BOOL FASTCALL co_UserShowCaret(PWINDOW_OBJECT Window OPTIONAL)
+{
+   PUSER_MESSAGE_QUEUE ThreadQueue;
+
+   if (Window) ASSERT_REFS_CO(Window);
+
+   if(Window && Window->OwnerThread != PsGetCurrentThread())
+   {
+      SetLastWin32Error(ERROR_ACCESS_DENIED);
+      return FALSE;
+   }
+
+   ThreadQueue = (PUSER_MESSAGE_QUEUE)PsGetWin32Thread()->MessageQueue;
+
+   if(Window && ThreadQueue->CaretInfo->hWnd != Window->hSelf)
+   {
+      SetLastWin32Error(ERROR_ACCESS_DENIED);
+      return FALSE;
+   }
+
+   if(!ThreadQueue->CaretInfo->Visible)
+   {
+      ThreadQueue->CaretInfo->Visible = 1;
+      if(!ThreadQueue->CaretInfo->Showing)
+      {
+         co_IntSendMessage(ThreadQueue->CaretInfo->hWnd, WM_SYSTIMER, IDCARETTIMER, 0);
+      }
+      IntSetTimer(ThreadQueue->CaretInfo->hWnd, IDCARETTIMER, IntGetCaretBlinkTime(), NULL, TRUE);
+   }
+
+   return TRUE;
+}
 
 
+/* SYSCALLS *****************************************************************/
 
 BOOL
 STDCALL
@@ -317,105 +399,10 @@ CLEANUP:
 }
 
 
-BOOL FASTCALL co_UserHideCaret(PWINDOW_OBJECT Window OPTIONAL)
-{
-   PUSER_MESSAGE_QUEUE ThreadQueue;
-
-   if (Window) ASSERT_REFS_CO(Window);
-
-   if(Window && Window->OwnerThread != PsGetCurrentThread())
-   {
-      SetLastWin32Error(ERROR_ACCESS_DENIED);
-      return FALSE;
-   }
-
-   ThreadQueue = (PUSER_MESSAGE_QUEUE)PsGetWin32Thread()->MessageQueue;
-
-   if(Window && ThreadQueue->CaretInfo->hWnd != Window->hSelf)
-   {
-      SetLastWin32Error(ERROR_ACCESS_DENIED);
-      return FALSE;
-   }
-
-   if(ThreadQueue->CaretInfo->Visible)
-   {
-      IntKillTimer((Window ? Window->hSelf : 0), IDCARETTIMER, TRUE);
-
-      co_IntHideCaret(ThreadQueue->CaretInfo);
-      ThreadQueue->CaretInfo->Visible = 0;
-      ThreadQueue->CaretInfo->Showing = 0;
-   }
-
-   return TRUE;
-}
-
-
-BOOL
-STDCALL
-NtUserHideCaret(HWND hWnd OPTIONAL)
-{
-   PWINDOW_OBJECT Window = NULL;
-   DECLARE_RETURN(BOOL);
-   BOOL ret;
-
-   DPRINT("Enter NtUserHideCaret\n");
-   UserEnterExclusive();
-
-   if(hWnd && !(Window = UserGetWindowObject(hWnd)))
-   {
-      RETURN(FALSE);
-   }
-
-   if (Window) UserRefObjectCo(Window);
-   ret = co_UserHideCaret(Window);
-   if (Window) UserDerefObjectCo(Window);
-
-   RETURN(ret);
-
-CLEANUP:
-   DPRINT("Leave NtUserHideCaret, ret=%i\n",_ret_);
-   UserLeave();
-   END_CLEANUP;
-}
-
-
-BOOL FASTCALL co_UserShowCaret(PWINDOW_OBJECT Window OPTIONAL)
-{
-   PUSER_MESSAGE_QUEUE ThreadQueue;
-
-   if (Window) ASSERT_REFS_CO(Window);
-
-   if(Window && Window->OwnerThread != PsGetCurrentThread())
-   {
-      SetLastWin32Error(ERROR_ACCESS_DENIED);
-      return FALSE;
-   }
-
-   ThreadQueue = (PUSER_MESSAGE_QUEUE)PsGetWin32Thread()->MessageQueue;
-
-   if(Window && ThreadQueue->CaretInfo->hWnd != Window->hSelf)
-   {
-      SetLastWin32Error(ERROR_ACCESS_DENIED);
-      return FALSE;
-   }
-
-   if(!ThreadQueue->CaretInfo->Visible)
-   {
-      ThreadQueue->CaretInfo->Visible = 1;
-      if(!ThreadQueue->CaretInfo->Showing)
-      {
-         co_IntSendMessage(ThreadQueue->CaretInfo->hWnd, WM_SYSTIMER, IDCARETTIMER, 0);
-      }
-      IntSetTimer((Window ? Window->hSelf : 0), IDCARETTIMER, IntGetCaretBlinkTime(), NULL, TRUE);
-   }
-
-   return TRUE;
-}
-
 
 BOOL
 STDCALL
-NtUserShowCaret(HWND hWnd OPTIONAL)
+NtUserShowCaret(HWND hWnd OPTIONAL, BOOL bShow)
 {
    PWINDOW_OBJECT Window = NULL;
    DECLARE_RETURN(BOOL);
@@ -430,7 +417,12 @@ NtUserShowCaret(HWND hWnd OPTIONAL)
    }
 
    if (Window) UserRefObjectCo(Window);
-   ret = co_UserShowCaret(Window);
+   
+   if (bShow)
+      ret = co_UserShowCaret(Window);
+   else
+      ret = co_UserHideCaret(Window);
+      
    if (Window) UserDerefObjectCo(Window);
 
    RETURN(ret);
index d07dcad..78fc81b 100644 (file)
@@ -47,434 +47,222 @@ CleanupClassImpl(VOID)
    return(STATUS_SUCCESS);
 }
 
-BOOL FASTCALL
-ClassReferenceClassByAtom(
-   PWNDCLASS_OBJECT* Class,
-   RTL_ATOM Atom,
-   HINSTANCE hInstance)
-{
-   PWNDCLASS_OBJECT Current, BestMatch = NULL;
-   PLIST_ENTRY CurrentEntry;
-   PW32PROCESS Process = PsGetWin32Process();
-
-   CurrentEntry = Process->ClassListHead.Flink;
-   while (CurrentEntry != &Process->ClassListHead)
-   {
-      Current = CONTAINING_RECORD(CurrentEntry, WNDCLASS_OBJECT, ListEntry);
-
-      if (Current->Atom == Atom && (hInstance == NULL || Current->hInstance == hInstance))
-      {
-         *Class = Current;
-         ObmReferenceObject(Current);
-         return TRUE;
-      }
 
-      if (Current->Atom == Atom && Current->Global)
-         BestMatch = Current;
-
-      CurrentEntry = CurrentEntry->Flink;
-   }
+/* return TRUE if class became destroyed */
+inline VOID FASTCALL 
+ClassDerefObject(PWNDCLASS_OBJECT Class)
+{
+   ASSERT(Class->refs >= 1);
+   Class->refs--;   
+}
 
-   if (BestMatch != NULL)
-   {
-      *Class = BestMatch;
-      ObmReferenceObject(BestMatch);
-      return TRUE;
-   }
 
-   return FALSE;
+inline VOID FASTCALL 
+ClassRefObject(PWNDCLASS_OBJECT Class)
+{
+   ASSERT(Class->refs >= 0);
+   Class->refs++;
 }
 
-BOOL FASTCALL
-ClassReferenceClassByName(
-   PWNDCLASS_OBJECT *Class,
-   LPCWSTR ClassName,
-   HINSTANCE hInstance)
-{
-   PWINSTATION_OBJECT WinStaObject;
-   NTSTATUS Status;
-   BOOL Found;
-   RTL_ATOM ClassAtom;
 
-   if (!ClassName || !PsGetWin32Thread()->Desktop)
-      return FALSE;
+VOID FASTCALL DestroyClass(PWNDCLASS_OBJECT Class)
+{
+   PWINSTATION_OBJECT WinSta;
+   WinSta = PsGetWin32Thread()->Desktop->WindowStation;
+   
+   ASSERT(Class->refs == 0);
+   RemoveEntryList(&Class->ListEntry);
+   //FIXME: release ATOM
+   RtlDeleteAtomFromAtomTable(WinSta->AtomTable, Class->Atom);
+   ExFreePool(Class);
+}
 
-   WinStaObject = PsGetWin32Thread()->Desktop->WindowStation;
 
-   Status = RtlLookupAtomInAtomTable(
-               WinStaObject->AtomTable,
-               (LPWSTR)ClassName,
-               &ClassAtom);
+/* clean all process classes. all process windows must cleaned first!! */
+void FASTCALL DestroyProcessClasses(PW32PROCESS Process )
+{
+   PWNDCLASS_OBJECT Class;
 
-   if (!NT_SUCCESS(Status))
+   while (!IsListEmpty(&Process->ClassList))
    {
-      DPRINT1("Failed to lookup class atom!\n");
-      return FALSE;
+      Class = CONTAINING_RECORD(RemoveHeadList(&Process->ClassList), WNDCLASS_OBJECT, ListEntry);
+      DestroyClass(Class);
    }
-
-   Found = ClassReferenceClassByAtom(Class, ClassAtom, hInstance);
-
-   return Found;
 }
 
-BOOL FASTCALL
-ClassReferenceClassByNameOrAtom(
-   PWNDCLASS_OBJECT *Class,
-   LPCWSTR ClassNameOrAtom,
-   HINSTANCE hInstance)
-{
-   BOOL Found;
 
-   if (IS_ATOM(ClassNameOrAtom))
-      Found = ClassReferenceClassByAtom(Class, (RTL_ATOM)((ULONG_PTR)ClassNameOrAtom), hInstance);
-   else
-      Found = ClassReferenceClassByName(Class, ClassNameOrAtom, hInstance);
 
-   return Found;
-}
 
-DWORD STDCALL
-NtUserGetClassInfo(
-   HINSTANCE hInstance,
-   LPCWSTR lpClassName,
-   LPWNDCLASSEXW lpWndClassEx,
-   BOOL Ansi,
-   DWORD unknown3)
+PWNDCLASS_OBJECT FASTCALL
+ClassGetClassByAtom(RTL_ATOM Atom, HINSTANCE hInstance)
 {
    PWNDCLASS_OBJECT Class;
-   RTL_ATOM Atom;
-   DECLARE_RETURN(DWORD);
-
-   if (IS_ATOM(lpClassName))
-      DPRINT("NtUserGetClassInfo - %x (%lx)\n", lpClassName, hInstance);
-   else
-      DPRINT("NtUserGetClassInfo - %S (%lx)\n", lpClassName, hInstance);
-
-   UserEnterExclusive();
+   PW32PROCESS Process = PsGetWin32Process();
 
-   if (!ClassReferenceClassByNameOrAtom(&Class, lpClassName, hInstance))
+   LIST_FOR_EACH(Class, &Process->ClassList, WNDCLASS_OBJECT, ListEntry)
    {
-      SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST);
-      RETURN(0);
-   }
+      if (Class->Atom != Atom) continue;
 
-   lpWndClassEx->cbSize = sizeof(WNDCLASSEXW);
-   lpWndClassEx->style = Class->style;
-   if (Ansi)
-      lpWndClassEx->lpfnWndProc = Class->lpfnWndProcA;
-   else
-      lpWndClassEx->lpfnWndProc = Class->lpfnWndProcW;
-   lpWndClassEx->cbClsExtra = Class->cbClsExtra;
-   lpWndClassEx->cbWndExtra = Class->cbWndExtra;
-   /* This is not typo, we're really not going to use Class->hInstance here. */
-   lpWndClassEx->hInstance = hInstance;
-   lpWndClassEx->hIcon = Class->hIcon;
-   lpWndClassEx->hCursor = Class->hCursor;
-   lpWndClassEx->hbrBackground = Class->hbrBackground;
-   if (Class->lpszMenuName.MaximumLength)
-      RtlCopyUnicodeString((PUNICODE_STRING)lpWndClassEx->lpszMenuName, &Class->lpszMenuName);
-   else
-      lpWndClassEx->lpszMenuName = Class->lpszMenuName.Buffer;
-   lpWndClassEx->lpszClassName = lpClassName;
-   lpWndClassEx->hIconSm = Class->hIconSm;
-   Atom = Class->Atom;
-
-   ObmDereferenceObject(Class);
-
-   RETURN(Atom);
-
-CLEANUP:
-   DPRINT("Leave NtUserGetClassInfo, ret=%i\n",_ret_);
-   UserLeave();
-   END_CLEANUP;
+      if (!hInstance || Class->Global || Class->hInstance == hInstance) return Class;
+   }
+   
+   return NULL;
 }
 
-ULONG FASTCALL
-IntGetClassName(struct _WINDOW_OBJECT *WindowObject, LPWSTR lpClassName,
-                ULONG nMaxCount)
+
+PWNDCLASS_OBJECT FASTCALL
+ClassGetClassByName(LPCWSTR ClassName, HINSTANCE hInstance)
 {
-   ULONG Length;
-   LPWSTR Name;
-   PWINSTATION_OBJECT WinStaObject;
+   PWINSTATION_OBJECT WinSta;
    NTSTATUS Status;
+   RTL_ATOM Atom;
 
-   if(!PsGetWin32Thread()->Desktop)
-   {
-      return 0;
-   }
+   if (!ClassName || !PsGetWin32Thread()->Desktop)
+      return FALSE;
+
+   WinSta = PsGetWin32Thread()->Desktop->WindowStation;
 
-   WinStaObject = PsGetWin32Thread()->Desktop->WindowStation;
+   Status = RtlLookupAtomInAtomTable(
+               WinSta->AtomTable,
+               (LPWSTR)ClassName,
+               &Atom);
 
-   Length = 0;
-   Status = RtlQueryAtomInAtomTable(WinStaObject->AtomTable,
-                                    WindowObject->Class->Atom, NULL, NULL,
-                                    NULL, &Length);
-   Length += sizeof(WCHAR);
-   Name = ExAllocatePoolWithTag(PagedPool, Length, TAG_STRING);
-   Status = RtlQueryAtomInAtomTable(WinStaObject->AtomTable,
-                                    WindowObject->Class->Atom, NULL, NULL,
-                                    Name, &Length);
    if (!NT_SUCCESS(Status))
    {
-      DPRINT("IntGetClassName: RtlQueryAtomInAtomTable failed\n");
-      return 0;
-   }
-   Length /= sizeof(WCHAR);
-   if (Length > nMaxCount)
-   {
-      Length = nMaxCount;
+      DPRINT1("Failed to lookup class atom!\n");
+      return FALSE;
    }
-   wcsncpy(lpClassName, Name, Length);
-   /* FIXME: Check buffer size before doing this! */
-   *(lpClassName + Length) = 0;
-   ExFreePool(Name);
 
-   return Length;
+   return ClassGetClassByAtom(Atom, hInstance);
 }
 
-DWORD STDCALL
-NtUserGetClassName (
-   HWND hWnd,
-   LPWSTR lpClassName,
-   ULONG nMaxCount)
-{
-   PWINDOW_OBJECT Window;
-   DECLARE_RETURN(DWORD);
 
-   UserEnterShared();
-   DPRINT("Enter NtUserGetClassName\n");   
-
-   if (!(Window = UserGetWindowObject(hWnd)))
-   {
-      RETURN(0);
-   }
-
-   RETURN( IntGetClassName(Window, lpClassName, nMaxCount));
-
-CLEANUP:
-   DPRINT("Leave NtUserGetClassName, ret=%i\n",_ret_);
-   UserLeave();
-   END_CLEANUP;
-}
-
-DWORD STDCALL
-NtUserGetWOWClass(DWORD Unknown0,
-                  DWORD Unknown1)
+PWNDCLASS_OBJECT FASTCALL
+ClassGetClassByNameOrAtom(LPCWSTR ClassNameOrAtom, HINSTANCE hInstance)
 {
-   UNIMPLEMENTED;
-   return(0);
+   if (!ClassNameOrAtom) return NULL;
+   
+   if (IS_ATOM(ClassNameOrAtom))
+      return ClassGetClassByAtom((RTL_ATOM)((ULONG_PTR)ClassNameOrAtom), hInstance);
+   else
+      return ClassGetClassByName(ClassNameOrAtom, hInstance);
 }
 
-PWNDCLASS_OBJECT FASTCALL
-IntCreateClass(
+
+static
+BOOL FASTCALL
+IntRegisterClass(
    CONST WNDCLASSEXW *lpwcx,
    DWORD Flags,
    WNDPROC wpExtra,
    PUNICODE_STRING MenuName,
    RTL_ATOM Atom)
 {
-   PWNDCLASS_OBJECT ClassObject;
+   PWNDCLASS_OBJECT Class;
    ULONG  objectSize;
    BOOL Global;
 
-   Global = (Flags & REGISTERCLASS_SYSTEM) || (lpwcx->style & CS_GLOBALCLASS) ? TRUE : FALSE;
+   ASSERT(lpwcx);
+   ASSERT(Atom);
+   ASSERT(lpwcx->hInstance);
+
+   Global = (Flags & REGISTERCLASS_SYSTEM) || (lpwcx->style & CS_GLOBALCLASS);
 
    /* Check for double registration of the class. */
-   if (PsGetWin32Process() != NULL)
+   Class = ClassGetClassByAtom(Atom, lpwcx->hInstance);
+   if (Class && Global == Class->Global)
    {
-      if (ClassReferenceClassByAtom(&ClassObject, Atom, lpwcx->hInstance))
-      {
-         /*
-          * NOTE: We may also get a global class from
-                               * ClassReferenceClassByAtom. This simple check
-                               * prevents that we fail valid request.
-                               */
-         if (ClassObject->hInstance == lpwcx->hInstance)
-         {
-            SetLastWin32Error(ERROR_CLASS_ALREADY_EXISTS);
-            ObmDereferenceObject(ClassObject);
-            return(NULL);
-         }
-      }
+      /* can max have one class of each type (global/local) */
+      SetLastWin32Error(ERROR_CLASS_ALREADY_EXISTS);
+      return(FALSE);
    }
 
    objectSize = sizeof(WNDCLASS_OBJECT) + lpwcx->cbClsExtra;
-   ClassObject = ObmCreateObject(&gHandleTable, NULL, otClass, objectSize);
-   if (ClassObject == 0)
+   
+   //FIXME: allocate in session heap (or possibly desktop heap)
+   Class = ExAllocatePool(PagedPool, objectSize);
+   if (!Class)
    {
       SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
-      return(NULL);
-   }
-
-   ClassObject->cbSize = lpwcx->cbSize;
-   ClassObject->style = lpwcx->style;
-   ClassObject->cbClsExtra = lpwcx->cbClsExtra;
-   ClassObject->cbWndExtra = lpwcx->cbWndExtra;
-   ClassObject->hInstance = lpwcx->hInstance;
-   ClassObject->hIcon = lpwcx->hIcon;
-   ClassObject->hCursor = lpwcx->hCursor;
-   ClassObject->hbrBackground = lpwcx->hbrBackground;
-   ClassObject->Unicode = !(Flags & REGISTERCLASS_ANSI);
-   ClassObject->Global = Global;
-   ClassObject->hIconSm = lpwcx->hIconSm;
-   ClassObject->Atom = Atom;
+      return(FALSE);
+   }
+   RtlZeroMemory(Class, objectSize);
+
+   Class->cbSize = lpwcx->cbSize;
+   Class->style = lpwcx->style;
+   Class->cbClsExtra = lpwcx->cbClsExtra;
+   Class->cbWndExtra = lpwcx->cbWndExtra;
+   Class->hInstance = lpwcx->hInstance;
+   Class->hIcon = lpwcx->hIcon;
+   Class->hCursor = lpwcx->hCursor;
+   Class->hbrBackground = lpwcx->hbrBackground;
+   Class->Unicode = !(Flags & REGISTERCLASS_ANSI);
+   Class->Global = Global;
+   Class->hIconSm = lpwcx->hIconSm;
+   Class->Atom = Atom;
+   
    if (wpExtra == NULL)
    {
       if (Flags & REGISTERCLASS_ANSI)
       {
-         ClassObject->lpfnWndProcA = lpwcx->lpfnWndProc;
-         ClassObject->lpfnWndProcW = (WNDPROC)IntAddWndProcHandle(lpwcx->lpfnWndProc,FALSE);
+         Class->lpfnWndProcA = lpwcx->lpfnWndProc;
+         Class->lpfnWndProcW = (WNDPROC)IntAddWndProcHandle(lpwcx->lpfnWndProc,FALSE);
       }
       else
       {
-         ClassObject->lpfnWndProcW = lpwcx->lpfnWndProc;
-         ClassObject->lpfnWndProcA = (WNDPROC)IntAddWndProcHandle(lpwcx->lpfnWndProc,TRUE);
+         Class->lpfnWndProcW = lpwcx->lpfnWndProc;
+         Class->lpfnWndProcA = (WNDPROC)IntAddWndProcHandle(lpwcx->lpfnWndProc,TRUE);
       }
    }
    else
    {
       if (Flags & REGISTERCLASS_ANSI)
       {
-         ClassObject->lpfnWndProcA = lpwcx->lpfnWndProc;
-         ClassObject->lpfnWndProcW = wpExtra;
+         Class->lpfnWndProcA = lpwcx->lpfnWndProc;
+         Class->lpfnWndProcW = wpExtra;
       }
       else
       {
-         ClassObject->lpfnWndProcW = lpwcx->lpfnWndProc;
-         ClassObject->lpfnWndProcA = wpExtra;
+         Class->lpfnWndProcW = lpwcx->lpfnWndProc;
+         Class->lpfnWndProcA = wpExtra;
       }
    }
+   
    if (MenuName->Length == 0)
    {
-      ClassObject->lpszMenuName.Length =
-         ClassObject->lpszMenuName.MaximumLength = 0;
-      ClassObject->lpszMenuName.Buffer = MenuName->Buffer;
+      Class->lpszMenuName.Length =
+         Class->lpszMenuName.MaximumLength = 0;
+      Class->lpszMenuName.Buffer = MenuName->Buffer;
    }
    else
    {
-      ClassObject->lpszMenuName.Length =
-         ClassObject->lpszMenuName.MaximumLength = MenuName->MaximumLength;
-      ClassObject->lpszMenuName.Buffer = ExAllocatePoolWithTag(PagedPool, ClassObject->lpszMenuName.MaximumLength, TAG_STRING);
-      RtlCopyUnicodeString(&ClassObject->lpszMenuName, MenuName);
+      Class->lpszMenuName.Length =
+         Class->lpszMenuName.MaximumLength = MenuName->MaximumLength;
+      Class->lpszMenuName.Buffer = ExAllocatePoolWithTag(PagedPool, Class->lpszMenuName.MaximumLength, TAG_STRING);
+      RtlCopyUnicodeString(&Class->lpszMenuName, MenuName);
    }
+   
    /* Extra class data */
-   if (ClassObject->cbClsExtra != 0)
-   {
-      ClassObject->ExtraData = (PCHAR)(ClassObject + 1);
-      RtlZeroMemory(ClassObject->ExtraData, (ULONG)ClassObject->cbClsExtra);
-   }
-   else
-   {
-      ClassObject->ExtraData = NULL;
-   }
-
-   InitializeListHead(&ClassObject->ClassWindowsListHead);
-
-   return(ClassObject);
-}
-
-RTL_ATOM STDCALL
-NtUserRegisterClassExWOW(
-   CONST WNDCLASSEXW* lpwcx,
-   PUNICODE_STRING ClassName,
-   PUNICODE_STRING ClassNameCopy,
-   PUNICODE_STRING MenuName,
-   WNDPROC wpExtra, /* FIXME: Windows uses this parameter for something different. */
-   DWORD Flags,
-   DWORD Unknown7)
-
-/*
- * FUNCTION:
- *   Registers a new class with the window manager
- * ARGUMENTS:
- *   lpwcx          = Win32 extended window class structure
- *   bUnicodeClass = Whether to send ANSI or unicode strings
- *                   to window procedures
- *   wpExtra       = Extra window procedure, if this is not null, its used for the second window procedure for standard controls.
- * RETURNS:
- *   Atom identifying the new class
- */
-{
-   WNDCLASSEXW SafeClass;
-   PWINSTATION_OBJECT WinStaObject;
-   PWNDCLASS_OBJECT ClassObject;
-   NTSTATUS Status;
-   RTL_ATOM Atom;
-   DECLARE_RETURN(RTL_ATOM);
-
-   DPRINT("Enter NtUserRegisterClassExWOW\n");
-   UserEnterExclusive();
-
-   if (!lpwcx)
-   {
-      SetLastWin32Error(ERROR_INVALID_PARAMETER);
-      RETURN( (RTL_ATOM)0);
-   }
-
-   if (Flags & ~REGISTERCLASS_ALL)
-   {
-      SetLastWin32Error(ERROR_INVALID_FLAGS);
-      RETURN( (RTL_ATOM)0);
-   }
-
-   Status = MmCopyFromCaller(&SafeClass, lpwcx, sizeof(WNDCLASSEXW));
-   if (!NT_SUCCESS(Status))
-   {
-      SetLastNtError(Status);
-      RETURN( (RTL_ATOM)0);
-   }
+   if (Class->cbClsExtra)
+      Class->ExtraData = (PCHAR)(Class + 1);
 
-   /* Deny negative sizes */
-   if (lpwcx->cbClsExtra < 0 || lpwcx->cbWndExtra < 0)
+   if (Global)
    {
-      SetLastWin32Error(ERROR_INVALID_PARAMETER);
-      RETURN( (RTL_ATOM)0);
-   }
-
-   WinStaObject = PsGetWin32Thread()->Desktop->WindowStation;
-
-   if (ClassName->Length > 0)
-   {
-      DPRINT("NtUserRegisterClassExWOW(%S)\n", ClassName->Buffer);
-      /* FIXME - Safely copy/verify the buffer first!!! */
-      Status = RtlAddAtomToAtomTable(WinStaObject->AtomTable,
-                                     ClassName->Buffer,
-                                     &Atom);
-      if (!NT_SUCCESS(Status))
-      {
-         DPRINT1("Failed adding class name (%S) to atom table\n",
-                 ClassName->Buffer);
-         SetLastNtError(Status);
-         RETURN((RTL_ATOM)0);
-      }
+      /* global classes go last (incl. system classes) */
+      InsertTailList(&PsGetWin32Process()->ClassList, &Class->ListEntry);
    }
    else
    {
-      Atom = (RTL_ATOM)(ULONG)ClassName->Buffer;
-   }
-   ClassObject = IntCreateClass(&SafeClass, Flags, wpExtra, MenuName, Atom);
-   if (ClassObject == NULL)
-   {
-      if (ClassName->Length)
-      {
-         RtlDeleteAtomFromAtomTable(WinStaObject->AtomTable, Atom);
-      }
-      DPRINT("Failed creating window class object\n");
-      RETURN((RTL_ATOM)0);
+      /* local classes have priority so we put them first */
+      InsertHeadList(&PsGetWin32Process()->ClassList, &Class->ListEntry);
    }
-
-   InsertTailList(&PsGetWin32Process()->ClassListHead, &ClassObject->ListEntry);
-
-   RETURN(Atom);
-
-CLEANUP:
-   DPRINT("Leave NtUserRegisterClassExWOW, ret=%i\n",_ret_);
-   UserLeave();
-   END_CLEANUP;
+   
+   return TRUE;
 }
 
+
 ULONG FASTCALL
-IntGetClassLong(struct _WINDOW_OBJECT *Window, ULONG Offset, BOOL Ansi)
+IntGetClassLong(PWINDOW_OBJECT Window, ULONG Offset, BOOL Ansi)
 {
    LONG Ret;
 
@@ -540,28 +328,7 @@ IntGetClassLong(struct _WINDOW_OBJECT *Window, ULONG Offset, BOOL Ansi)
    return(Ret);
 }
 
-DWORD STDCALL
-NtUserGetClassLong(HWND hWnd, DWORD Offset, BOOL Ansi)
-{
-   PWINDOW_OBJECT Window;
-   DECLARE_RETURN(DWORD);
-
-   DPRINT("Enter NtUserGetClassLong\n");
-   UserEnterExclusive();
-
-   if (!(Window = UserGetWindowObject(hWnd)))
-   {
-      RETURN(0);
-   }
-
-   RETURN(IntGetClassLong(Window, Offset, Ansi));
-
-CLEANUP:
-   DPRINT("Leave NtUserGetClassLong, ret=%i\n",_ret_);
-   UserLeave();
-   END_CLEANUP;
-}
-
+static
 void FASTCALL
 co_IntSetClassLong(PWINDOW_OBJECT Window, ULONG Offset, LONG dwNewLong, BOOL Ansi)
 {
@@ -643,6 +410,144 @@ co_IntSetClassLong(PWINDOW_OBJECT Window, ULONG Offset, LONG dwNewLong, BOOL Ans
          break;
    }
 }
+/* SYSCALLS *****************************************************************/
+
+
+RTL_ATOM STDCALL
+NtUserRegisterClassExWOW(
+   CONST WNDCLASSEXW* lpwcx,
+   PUNICODE_STRING ClassName,
+   PUNICODE_STRING ClassNameCopy,//huhuhuhu???
+   PUNICODE_STRING MenuName,
+   WNDPROC wpExtra,
+   DWORD Flags,
+   DWORD Unknown7)
+
+/*
+ * FUNCTION:
+ *   Registers a new class with the window manager
+ * ARGUMENTS:
+ *   lpwcx          = Win32 extended window class structure
+ *   bUnicodeClass = Whether to send ANSI or unicode strings
+ *                   to window procedures
+ *   wpExtra       = Extra window procedure, if this is not null, its used for the second window procedure for standard controls.
+ * RETURNS:
+ *   Atom identifying the new class
+ */
+{
+   WNDCLASSEXW SafeClass;
+   PWINSTATION_OBJECT WinSta;
+   NTSTATUS Status;
+   RTL_ATOM Atom;
+   DECLARE_RETURN(RTL_ATOM);
+
+   DPRINT("Enter NtUserRegisterClassExWOW\n");
+   UserEnterExclusive();
+
+   if (!lpwcx)
+   {
+      SetLastWin32Error(ERROR_INVALID_PARAMETER);
+      RETURN( (RTL_ATOM)0);
+   }
+
+   if (Flags & ~REGISTERCLASS_ALL)
+   {
+      SetLastWin32Error(ERROR_INVALID_FLAGS);
+      RETURN( (RTL_ATOM)0);
+   }
+
+   Status = MmCopyFromCaller(&SafeClass, lpwcx, sizeof(WNDCLASSEXW));
+   if (!NT_SUCCESS(Status))
+   {
+      SetLastNtError(Status);
+      RETURN( (RTL_ATOM)0);
+   }
+
+   /* Deny negative sizes */
+   if (lpwcx->cbClsExtra < 0 || lpwcx->cbWndExtra < 0)
+   {
+      SetLastWin32Error(ERROR_INVALID_PARAMETER);
+      RETURN( (RTL_ATOM)0);
+   }
+
+   if (!lpwcx->hInstance)
+   {
+      SetLastWin32Error(ERROR_INVALID_PARAMETER);
+      RETURN( (RTL_ATOM)0);
+   }
+
+   WinSta = PsGetWin32Thread()->Desktop->WindowStation;
+
+   //FIXME: make ClassName ptr the atom, not buffer
+   if (ClassName->Length > 0)
+   {
+      DPRINT("NtUserRegisterClassExWOW(%S)\n", ClassName->Buffer);
+      /* FIXME - Safely copy/verify the buffer first!!! */
+      Status = RtlAddAtomToAtomTable(WinSta->AtomTable,
+                                     ClassName->Buffer,
+                                     &Atom);
+      if (!NT_SUCCESS(Status))
+      {
+         DPRINT1("Failed adding class name (%S) to atom table\n",
+                 ClassName->Buffer);
+         SetLastNtError(Status);
+         RETURN((RTL_ATOM)0);
+      }
+   }
+   else
+   {
+      Atom = (RTL_ATOM)(ULONG)ClassName->Buffer;
+   }
+
+   if (!Atom)
+   {
+      SetLastWin32Error(ERROR_INVALID_PARAMETER);
+      RETURN(0);
+   }
+
+   if (!IntRegisterClass(&SafeClass, Flags, wpExtra, MenuName, Atom))
+   {
+      if (ClassName->Length)
+      {
+         RtlDeleteAtomFromAtomTable(WinSta->AtomTable, Atom);
+      }
+      DPRINT("Failed creating window class object\n");
+      RETURN((RTL_ATOM)0);
+   }
+
+   RETURN(Atom);
+
+CLEANUP:
+   DPRINT("Leave NtUserRegisterClassExWOW, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
+}
+
+
+
+DWORD STDCALL
+NtUserGetClassLong(HWND hWnd, DWORD Offset, BOOL Ansi)
+{
+   PWINDOW_OBJECT Window;
+   DECLARE_RETURN(DWORD);
+
+   DPRINT("Enter NtUserGetClassLong\n");
+   UserEnterExclusive();
+
+   if (!(Window = UserGetWindowObject(hWnd)))
+   {
+      RETURN(0);
+   }
+
+   RETURN(IntGetClassLong(Window, Offset, Ansi));
+
+CLEANUP:
+   DPRINT("Leave NtUserGetClassLong, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
+}
+
+
 
 DWORD STDCALL
 NtUserSetClassLong(HWND hWnd,
@@ -689,61 +594,170 @@ NtUserSetClassWord(DWORD Unknown0,
 BOOL STDCALL
 NtUserUnregisterClass(
    LPCWSTR ClassNameOrAtom,
-   HINSTANCE hInstance,
+   HINSTANCE hInstance, /* can be 0 */
    DWORD Unknown)
 {
    PWNDCLASS_OBJECT Class;
-   PWINSTATION_OBJECT WinSta;
    DECLARE_RETURN(BOOL);
 
    DPRINT("Enter NtUserUnregisterClass(%S)\n", ClassNameOrAtom);
    UserEnterExclusive();
 
-   if (!ClassNameOrAtom || !PsGetWin32Thread()->Desktop)
+   if (!ClassNameOrAtom)
    {
-      SetLastWin32Error(ERROR_INVALID_PARAMETER);
-      RETURN( FALSE);
+      SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST);
+      RETURN(FALSE);
    }
 
-   WinSta = PsGetWin32Thread()->Desktop->WindowStation;
-
-   if (!ClassReferenceClassByNameOrAtom(&Class, ClassNameOrAtom, hInstance))
+   if (!(Class = ClassGetClassByNameOrAtom(ClassNameOrAtom, hInstance)))
    {
       SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST);
-      RETURN( FALSE);
+      RETURN(FALSE);
    }
 
-   if (Class->hInstance && Class->hInstance != hInstance)
+/* this was probably ment to prevent sysclass dereg
+Seems wrong. Any class can have NULL hInst, not only sysclasses
+
+*/
+//   if (Class->hInstance && Class->hInstance != hInstance)
+//   {
+//      SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST);
+//      RETURN( FALSE);
+//   }
+
+   if (Class->refs)
    {
-      ClassDereferenceObject(Class);
-      SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST);
-      RETURN( FALSE);
+      /* NOTE: the class will not be freed when its refs become 0 ie. no more
+       * windows are using it. I dunno why that is but its how Windows does it (and Wine).
+       * The class will hang around until the process exit. -Gunnar
+       */
+      SetLastWin32Error(ERROR_CLASS_HAS_WINDOWS);
+      RETURN(FALSE);
    }
 
-   if (!IsListEmpty(&Class->ClassWindowsListHead))
+   DestroyClass(Class);
+   
+   RETURN(TRUE);
+
+CLEANUP:
+   DPRINT("Leave NtUserUnregisterClass, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
+}
+
+/* NOTE: for system classes hInstance is not NULL here, but User32Instance */
+DWORD STDCALL
+NtUserGetClassInfo(
+   HINSTANCE hInstance,
+   LPCWSTR lpClassName,
+   LPWNDCLASSEXW lpWndClassEx,
+   BOOL Ansi,
+   DWORD unknown3)
+{
+   PWNDCLASS_OBJECT Class;
+   RTL_ATOM Atom;
+   DECLARE_RETURN(DWORD);
+
+   if (IS_ATOM(lpClassName))
+      DPRINT("NtUserGetClassInfo - %x (%lx)\n", lpClassName, hInstance);
+   else
+      DPRINT("NtUserGetClassInfo - %S (%lx)\n", lpClassName, hInstance);
+
+   UserEnterExclusive();
+
+   if (!hInstance)
    {
-      /* Dereference the ClassReferenceClassByNameOrAtom() call */
-      ObmDereferenceObject(Class);
-      SetLastWin32Error(ERROR_CLASS_HAS_WINDOWS);
-      RETURN( FALSE);
+      SetLastWin32Error(ERROR_INVALID_PARAMETER);
+      RETURN(0);
    }
 
-   /* Dereference the ClassReferenceClassByNameOrAtom() call */
-   ClassDereferenceObject(Class);
+   if (!(Class = ClassGetClassByNameOrAtom(lpClassName, hInstance)))
+   {
+      SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST);
+      RETURN(0);
+   }
 
-   RemoveEntryList(&Class->ListEntry);
+   lpWndClassEx->cbSize = sizeof(WNDCLASSEXW);
+   lpWndClassEx->style = Class->style;
+   if (Ansi)
+      lpWndClassEx->lpfnWndProc = Class->lpfnWndProcA;
+   else
+      lpWndClassEx->lpfnWndProc = Class->lpfnWndProcW;
+   lpWndClassEx->cbClsExtra = Class->cbClsExtra;
+   lpWndClassEx->cbWndExtra = Class->cbWndExtra;
+   /* This is not typo, we're really not going to use Class->hInstance here. */
+   /* Well, i think its wrong so i changed it -Gunnar */
+   lpWndClassEx->hInstance = Class->hInstance;
+   lpWndClassEx->hIcon = Class->hIcon;
+   lpWndClassEx->hCursor = Class->hCursor;
+   lpWndClassEx->hbrBackground = Class->hbrBackground;
+   if (Class->lpszMenuName.MaximumLength)
+      RtlCopyUnicodeString((PUNICODE_STRING)lpWndClassEx->lpszMenuName, &Class->lpszMenuName);
+   else
+      lpWndClassEx->lpszMenuName = Class->lpszMenuName.Buffer;
+   lpWndClassEx->lpszClassName = lpClassName;
+   lpWndClassEx->hIconSm = Class->hIconSm;
+   Atom = Class->Atom;
 
-   RtlDeleteAtomFromAtomTable(WinSta->AtomTable, Class->Atom);
+   RETURN(Atom);
+
+CLEANUP:
+   DPRINT("Leave NtUserGetClassInfo, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
+}
+
+
+
+DWORD STDCALL
+NtUserGetClassName (
+   HWND hWnd,
+   LPWSTR lpClassName,
+   ULONG nMaxCount /* in TCHARS */
+   )
+{
+   PWINDOW_OBJECT Window;
+   DECLARE_RETURN(DWORD);
+   PWINSTATION_OBJECT WinSta;
+   NTSTATUS Status;
 
-   /* Free the object */
-   ClassDereferenceObject(Class);
+   UserEnterShared();
+   DPRINT("Enter NtUserGetClassName\n");   
 
-   RETURN( TRUE);
+   if (!(Window = UserGetWindowObject(hWnd)))
+   {
+      RETURN(0);
+   }
+
+   WinSta = PsGetWin32Thread()->Desktop->WindowStation;
+   
+   nMaxCount *= sizeof(WCHAR);
+   
+   //FIXME: wrap in SEH to protect lpClassName access
+   Status = RtlQueryAtomInAtomTable(WinSta->AtomTable,
+                                    Window->Class->Atom, NULL, NULL,
+                                    lpClassName, &nMaxCount);
+   if (!NT_SUCCESS(Status))
+   {
+      SetLastNtError(Status);
+      RETURN(0);
+   }
+
+   RETURN(nMaxCount / sizeof(WCHAR));
 
 CLEANUP:
-   DPRINT("Leave NtUserUnregisterClass, ret=%i\n",_ret_);
+   DPRINT("Leave NtUserGetClassName, ret=%i\n",_ret_);
    UserLeave();
    END_CLEANUP;
 }
 
+DWORD STDCALL
+NtUserGetWOWClass(DWORD Unknown0,
+                  DWORD Unknown1)
+{
+   UNIMPLEMENTED;
+   return(0);
+}
+
+
 /* EOF */
index c4c843c..d092cae 100644 (file)
@@ -95,30 +95,6 @@ PCURICON_OBJECT FASTCALL UserGetCurIconObject(HCURSOR hCurIcon)
    return CurIcon;
 }
 
-#if 0
-
-static
-PCURICON_OBJECT FASTCALL IntGetCurIconObject(HCURSOR hCursor)
-{
-   PCURICON_OBJECT Cursor;
-   
-   if (!hCursor) return NULL;
-   
-   Cursor = (PCURICON_OBJECT)UserGetObject(&gHandleTable, hCursor, otCursorIcon);
-   if (!Cursor)
-   {
-      SetLastWin32Error(ERROR_INVALID_CURSOR_HANDLE);
-      return NULL;
-   }
-
-   ASSERT(USER_BODY_TO_HEADER(Cursor)->RefCount >= 0);
-   
-   USER_BODY_TO_HEADER(Cursor)->RefCount++;
-   
-   return Cursor;
-}
-#endif
-
 
 #define COLORCURSORS_ALLOWED FALSE
 HCURSOR FASTCALL
@@ -355,21 +331,17 @@ static BOOLEAN FASTCALL
 ReferenceCurIconByProcess(PCURICON_OBJECT CurIcon)
 {
    PW32PROCESS Win32Process;
-   PLIST_ENTRY Search;
    PCURICON_PROCESS Current;
 
    Win32Process = PsGetWin32Process();
 
-   Search = CurIcon->ProcessList.Flink;
-   while (Search != &CurIcon->ProcessList)
+   LIST_FOR_EACH(Current, &CurIcon->ProcessList, CURICON_PROCESS, ListEntry)
    {
-      Current = CONTAINING_RECORD(Search, CURICON_PROCESS, ListEntry);
       if (Current->Process == Win32Process)
       {
          /* Already registered for this process */
          return TRUE;
       }
-      Search = Search->Flink;
    }
 
    /* Not registered yet */
@@ -388,14 +360,10 @@ PCURICON_OBJECT FASTCALL
 IntFindExistingCurIconObject(PWINSTATION_OBJECT WinSta, HMODULE hModule,
                              HRSRC hRsrc, LONG cx, LONG cy)
 {
-   PLIST_ENTRY CurrentEntry;
    PCURICON_OBJECT CurIcon;
 
-   CurrentEntry = gCurIconList.Flink;
-   while (CurrentEntry != &gCurIconList)
+   LIST_FOR_EACH(CurIcon, &gCurIconList, CURICON_OBJECT, ListEntry)
    {
-      CurIcon = CONTAINING_RECORD(CurrentEntry, CURICON_OBJECT, ListEntry);
-      CurrentEntry = CurrentEntry->Flink;
 
       //    if(NT_SUCCESS(ObmReferenceObjectByPointer(Object, otCursorIcon))) //<- huh????
 //      ObmReferenceObject(  CurIcon);
@@ -460,7 +428,6 @@ IntDestroyCurIconObject(PWINSTATION_OBJECT WinSta, PCURICON_OBJECT CurIcon, BOOL
    PSYSTEM_CURSORINFO CurInfo;
    HBITMAP bmpMask, bmpColor;
    BOOLEAN Ret;
-   PLIST_ENTRY Search;
    PCURICON_PROCESS Current = NULL;
    PW32PROCESS W32Process = PsGetWin32Process();
 
@@ -483,18 +450,15 @@ IntDestroyCurIconObject(PWINSTATION_OBJECT WinSta, PCURICON_OBJECT CurIcon, BOOL
 
    /* Now find this process in the list of processes referencing this object and
       remove it from that list */
-   Search = CurIcon->ProcessList.Flink;
-   while (Search != &CurIcon->ProcessList)
+   LIST_FOR_EACH(Current, &CurIcon->ProcessList, CURICON_PROCESS, ListEntry)
    {
-      Current = CONTAINING_RECORD(Search, CURICON_PROCESS, ListEntry);
       if (Current->Process == W32Process)
       {
+         RemoveEntryList(&Current->ListEntry);
          break;
       }
-      Search = Search->Flink;
    }
-   ASSERT(Search != &CurIcon->ProcessList);
-   RemoveEntryList(Search);
+   
    ExFreeToPagedLookasideList(&gProcessLookasideList, Current);
 
    /* If there are still processes referencing this object we can't destroy it yet */
@@ -541,9 +505,7 @@ VOID FASTCALL
 IntCleanupCurIcons(struct _EPROCESS *Process, PW32PROCESS Win32Process)
 {
    PWINSTATION_OBJECT WinSta;
-   PLIST_ENTRY CurrentEntry;
-   PCURICON_OBJECT CurIcon;
-   PLIST_ENTRY ProcessEntry;
+   PCURICON_OBJECT CurIcon, tmp;
    PCURICON_PROCESS ProcessData;
 
    WinSta = IntGetWinStaObj();
@@ -552,27 +514,19 @@ IntCleanupCurIcons(struct _EPROCESS *Process, PW32PROCESS Win32Process)
       return;
    }
 
-   CurrentEntry = gCurIconList.Flink;
-   while (CurrentEntry != &gCurIconList)
+   LIST_FOR_EACH_SAFE(CurIcon, tmp, &gCurIconList, CURICON_OBJECT, ListEntry)
    {
-      CurIcon = CONTAINING_RECORD(CurrentEntry, CURICON_OBJECT, ListEntry);
-      CurrentEntry = CurrentEntry->Flink;
-
-
 //      ObmReferenceObject(CurIcon);
       //    if(NT_SUCCESS(ObmReferenceObjectByPointer(Object, otCursorIcon)))
       {
-         ProcessEntry = CurIcon->ProcessList.Flink;
-         while (ProcessEntry != &CurIcon->ProcessList)
+         LIST_FOR_EACH(ProcessData, &CurIcon->ProcessList, CURICON_PROCESS, ListEntry)
          {
-            ProcessData = CONTAINING_RECORD(ProcessEntry, CURICON_PROCESS, ListEntry);
             if (Win32Process == ProcessData->Process)
             {
                RemoveEntryList(&CurIcon->ListEntry);
                IntDestroyCurIconObject(WinSta, CurIcon, TRUE);
                break;
             }
-            ProcessEntry = ProcessEntry->Flink;
          }
 
 //         ObmDereferenceObject(Object);
index 9b6e098..d785399 100644 (file)
@@ -96,18 +96,16 @@ IntDesktopObjectCreate(PVOID ObjectBody,
 
    RtlInitUnicodeString(&UnicodeString, (RemainingPath + 1));
 
-
-
-   KeInitializeSpinLock(&Desktop->Lock);
    InitializeListHead(&Desktop->ShellHookWindows);
 
    Desktop->WindowStation = (PWINSTATION_OBJECT)Parent;
 
    /* Put the desktop on the window station's list of associcated desktops */
-   ExInterlockedInsertTailList(
+//   ExInterlocked
+   InsertTailList(
       &Desktop->WindowStation->DesktopListHead,
-      &Desktop->ListEntry,
-      &Desktop->WindowStation->Lock);
+      &Desktop->ListEntry);//,
+//      &Desktop->WindowStation->Lock);
 
    return RtlCreateUnicodeString(&Desktop->Name, UnicodeString.Buffer);
 }
@@ -116,20 +114,41 @@ VOID STDCALL
 IntDesktopObjectDelete(PVOID DeletedObject)
 {
    PDESKTOP_OBJECT Desktop = (PDESKTOP_OBJECT)DeletedObject;
-   KIRQL OldIrql;
 
    DPRINT("Deleting desktop (0x%X)\n", Desktop);
 
    /* Remove the desktop from the window station's list of associcated desktops */
-   KeAcquireSpinLock(&Desktop->WindowStation->Lock, &OldIrql);
    RemoveEntryList(&Desktop->ListEntry);
-   KeReleaseSpinLock(&Desktop->WindowStation->Lock, OldIrql);
 
    RtlFreeUnicodeString(&Desktop->Name);
 }
 
 /* PRIVATE FUNCTIONS **********************************************************/
 
+static int GetSystemVersionString(LPWSTR buffer)
+{
+   RTL_OSVERSIONINFOEXW versionInfo;
+   int len;
+
+   versionInfo.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOEXW);
+
+   if (!NT_SUCCESS(RtlGetVersion((PRTL_OSVERSIONINFOW)&versionInfo)))
+      return 0;
+
+   if (versionInfo.dwMajorVersion <= 4)
+      len = swprintf(buffer,
+                     L"ReactOS Version %d.%d %s Build %d",
+                     versionInfo.dwMajorVersion, versionInfo.dwMinorVersion,
+                     versionInfo.szCSDVersion, versionInfo.dwBuildNumber&0xFFFF);
+   else
+      len = swprintf(buffer,
+                     L"ReactOS %s (Build %d)",
+                     versionInfo.szCSDVersion, versionInfo.dwBuildNumber&0xFFFF);
+
+   return len;
+}
+
+
 NTSTATUS FASTCALL
 IntParseDesktopPath(PEPROCESS Process,
                     PUNICODE_STRING DesktopPath,
@@ -562,6 +581,37 @@ IntHideDesktop(PDESKTOP_OBJECT Desktop)
 #endif
 }
 
+
+
+
+static
+HWND* FASTCALL
+UserBuildShellHookHwndList(PDESKTOP_OBJECT Desktop)
+{
+   ULONG entries=0;
+   PSHELL_HOOK_WINDOW Current;
+   HWND* list;
+   
+   /* fixme: if we save nb elements in desktop, we dont have to loop to find nb entries */
+   LIST_FOR_EACH(Current, &Desktop->ShellHookWindows, SHELL_HOOK_WINDOW, ListEntry)
+      entries++;
+
+   if (!entries) return NULL;
+
+   list = ExAllocatePool(PagedPool, sizeof(HWND) * (entries + 1)); /* alloc one extra for nullterm */
+   if (list)
+   {
+      HWND* cursor = list;
+      
+      LIST_FOR_EACH(Current, &Desktop->ShellHookWindows, SHELL_HOOK_WINDOW, ListEntry)
+         *cursor++ = Current->hWnd;
+   
+      *cursor = NULL; /* nullterm list */
+   }
+
+   return list;
+}
+
 /*
  * Send the Message to the windows registered for ShellHook
  * notifications. The lParam contents depend on the Message. See
@@ -570,9 +620,7 @@ IntHideDesktop(PDESKTOP_OBJECT Desktop)
 VOID co_IntShellHookNotify(WPARAM Message, LPARAM lParam)
 {
    PDESKTOP_OBJECT Desktop = IntGetActiveDesktop();
-   PLIST_ENTRY Entry, Entry2;
-   PSHELL_HOOK_WINDOW Current;
-   KIRQL OldLevel;
+   HWND* HwndList;
 
    static UINT MsgType = 0;
 
@@ -599,43 +647,23 @@ VOID co_IntShellHookNotify(WPARAM Message, LPARAM lParam)
       return;
    }
 
-   /* We have to do some tricks because the list could change
-    * between calls, and we can't keep the lock during the call
-    */
-
-   KeAcquireSpinLock(&Desktop->Lock, &OldLevel);
-   Entry = Desktop->ShellHookWindows.Flink;
-   while (Entry != &Desktop->ShellHookWindows)
+   HwndList = UserBuildShellHookHwndList(Desktop);
+   if (HwndList)
    {
-      Current = CONTAINING_RECORD(Entry, SHELL_HOOK_WINDOW, ListEntry);
-      KeReleaseSpinLock(&Desktop->Lock, OldLevel);
-
-      DPRINT("Sending notify\n");
-      co_IntPostOrSendMessage(Current->hWnd,
-                              MsgType,
-                              Message,
-                              lParam);
-
-      /* Loop again to find the window we were sending to. If it doesn't
-       * exist anymore, we just stop. This could leave an infinite loop
-       * if a window is removed and readded to the list. That's quite
-       * unlikely though.
-       */
-
-      KeAcquireSpinLock(&Desktop->Lock, &OldLevel);
-      Entry2 = Desktop->ShellHookWindows.Flink;
-      while (Entry2 != Entry &&
-             Entry2 != &Desktop->ShellHookWindows)
+      HWND* cursor = HwndList;
+      
+      for (; *cursor; cursor++)
       {
-         Entry2 = Entry2->Flink;
+         DPRINT("Sending notify\n");
+         co_IntPostOrSendMessage(*cursor,
+                                 MsgType,
+                                 Message,
+                                 lParam);
       }
 
-      if (Entry2 == Entry)
-         Entry = Entry->Flink;
-      else
-         break;
+      ExFreePool(HwndList);
    }
-   KeReleaseSpinLock(&Desktop->Lock, OldLevel);
+   
 }
 
 /*
@@ -650,7 +678,6 @@ BOOL IntRegisterShellHookWindow(HWND hWnd)
 {
    PDESKTOP_OBJECT Desktop = PsGetWin32Thread()->Desktop;
    PSHELL_HOOK_WINDOW Entry;
-   KIRQL OldLevel;
 
    DPRINT("IntRegisterShellHookWindow\n");
 
@@ -659,20 +686,16 @@ BOOL IntRegisterShellHookWindow(HWND hWnd)
     */
    IntDeRegisterShellHookWindow(hWnd);
 
-   Entry = ExAllocatePoolWithTag(NonPagedPool,
+   Entry = ExAllocatePoolWithTag(PagedPool,
                                  sizeof(SHELL_HOOK_WINDOW),
                                  TAG_WINSTA);
-   /* We have to walk this structure with while holding a spinlock, so we
-    * need NonPagedPool */
 
    if (!Entry)
       return FALSE;
 
    Entry->hWnd = hWnd;
 
-   KeAcquireSpinLock(&Desktop->Lock, &OldLevel);
    InsertTailList(&Desktop->ShellHookWindows, &Entry->ListEntry);
-   KeReleaseSpinLock(&Desktop->Lock, OldLevel);
 
    return TRUE;
 }
@@ -685,31 +708,27 @@ BOOL IntRegisterShellHookWindow(HWND hWnd)
 BOOL IntDeRegisterShellHookWindow(HWND hWnd)
 {
    PDESKTOP_OBJECT Desktop = PsGetWin32Thread()->Desktop;
-   PLIST_ENTRY Entry;
    PSHELL_HOOK_WINDOW Current;
-   KIRQL OldLevel;
-
-   KeAcquireSpinLock(&Desktop->Lock, &OldLevel);
 
-   Entry = Desktop->ShellHookWindows.Flink;
-   while (Entry != &Desktop->ShellHookWindows)
+   LIST_FOR_EACH(Current, &Desktop->ShellHookWindows, SHELL_HOOK_WINDOW, ListEntry)
    {
-      Current = CONTAINING_RECORD(Entry, SHELL_HOOK_WINDOW, ListEntry);
       if (Current->hWnd == hWnd)
       {
-         RemoveEntryList(Entry);
-         KeReleaseSpinLock(&Desktop->Lock, OldLevel);
-         ExFreePool(Entry);
+         RemoveEntryList(&Current->ListEntry);
+         ExFreePool(Current);
          return TRUE;
       }
-      Entry = Entry->Flink;
    }
 
-   KeReleaseSpinLock(&Desktop->Lock, OldLevel);
-
    return FALSE;
 }
 
+
+
+
+/* SYSCALLS *******************************************************************/
+
+
 /*
  * NtUserCreateDesktop
  *
@@ -759,7 +778,7 @@ NtUserCreateDesktop(
    CSR_API_MESSAGE Request;
    DECLARE_RETURN(HDESK);
 
-   DPRINT("Enter CreateDesktop: %wZ\n", lpszDesktopName);
+   DPRINT("Enter NtUserCreateDesktop: %wZ\n", lpszDesktopName);
    UserEnterExclusive();
 
    Status = IntValidateWindowStationHandle(
@@ -1035,6 +1054,10 @@ NtUserOpenInputDesktop(
    PDESKTOP_OBJECT Object;
    NTSTATUS Status;
    HDESK Desktop;
+   DECLARE_RETURN(HDESK);
+
+   DPRINT("Enter NtUserOpenInputDesktop\n");
+   UserEnterExclusive();
 
    DPRINT("About to open input desktop\n");
 
@@ -1049,7 +1072,7 @@ NtUserOpenInputDesktop(
    if (!NT_SUCCESS(Status))
    {
       DPRINT("Validation of input desktop handle (0x%X) failed\n", InputDesktop);
-      return (HDESK)0;
+      RETURN((HDESK)0);
    }
 
    /* Create a new handle to the object */
@@ -1068,11 +1091,16 @@ NtUserOpenInputDesktop(
    if (NT_SUCCESS(Status))
    {
       DPRINT("Successfully opened input desktop\n");
-      return (HDESK)Desktop;
+      RETURN((HDESK)Desktop);
    }
 
    SetLastNtError(Status);
-   return (HDESK)0;
+   RETURN((HDESK)0);
+   
+CLEANUP:
+   DPRINT("Leave NtUserOpenInputDesktop, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;   
 }
 
 /*
@@ -1102,6 +1130,10 @@ NtUserCloseDesktop(HDESK hDesktop)
 {
    PDESKTOP_OBJECT Object;
    NTSTATUS Status;
+   DECLARE_RETURN(BOOL);
+
+   DPRINT("Enter NtUserCloseDesktop\n");
+   UserEnterExclusive();
 
    DPRINT("About to close desktop handle (0x%X)\n", hDesktop);
 
@@ -1114,7 +1146,7 @@ NtUserCloseDesktop(HDESK hDesktop)
    if (!NT_SUCCESS(Status))
    {
       DPRINT("Validation of desktop handle (0x%X) failed\n", hDesktop);
-      return FALSE;
+      RETURN(FALSE);
    }
 
    ObDereferenceObject(Object);
@@ -1125,35 +1157,19 @@ NtUserCloseDesktop(HDESK hDesktop)
    if (!NT_SUCCESS(Status))
    {
       SetLastNtError(Status);
-      return FALSE;
+      RETURN(FALSE);
    }
 
-   return TRUE;
-}
-
-
-static int GetSystemVersionString(LPWSTR buffer)
-{
-   RTL_OSVERSIONINFOEXW versionInfo;
-   int len;
+   RETURN(TRUE);
 
-   versionInfo.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOEXW);
+CLEANUP:
+   DPRINT("Leave NtUserCloseDesktop, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;     
+}
 
-   if (!NT_SUCCESS(RtlGetVersion((PRTL_OSVERSIONINFOW)&versionInfo)))
-      return 0;
 
-   if (versionInfo.dwMajorVersion <= 4)
-      len = swprintf(buffer,
-                     L"ReactOS Version %d.%d %s Build %d",
-                     versionInfo.dwMajorVersion, versionInfo.dwMinorVersion,
-                     versionInfo.szCSDVersion, versionInfo.dwBuildNumber&0xFFFF);
-   else
-      len = swprintf(buffer,
-                     L"ReactOS %s (Build %d)",
-                     versionInfo.szCSDVersion, versionInfo.dwBuildNumber&0xFFFF);
 
-   return len;
-}
 
 /*
  * NtUserPaintDesktop
@@ -1179,6 +1195,10 @@ NtUserPaintDesktop(HDC hDC)
    BOOL doPatBlt = TRUE;
    PWINDOW_OBJECT WndDesktop;
    int len;
+   DECLARE_RETURN(BOOL);
+   
+   UserEnterExclusive();
+   DPRINT("Enter NtUserPaintDesktop\n");
 
    PWINSTATION_OBJECT WinSta = PsGetWin32Thread()->Desktop->WindowStation;
 
@@ -1186,7 +1206,7 @@ NtUserPaintDesktop(HDC hDC)
 
    hWndDesktop = IntGetDesktopWindow();
    if (!(WndDesktop = UserGetWindowObject(hWndDesktop)))
-      return FALSE;
+      RETURN(FALSE);
 
    DesktopBrush = (HBRUSH)IntGetClassLong(WndDesktop, GCL_HBRBACKGROUND, FALSE); //fixme: verify retval
 
@@ -1277,7 +1297,12 @@ NtUserPaintDesktop(HDC hDC)
       }
    }
 
-   return TRUE;
+   RETURN(TRUE);
+   
+CLEANUP:
+   DPRINT("Leave NtUserPaintDesktop, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;   
 }
 
 
@@ -1302,6 +1327,10 @@ NtUserSwitchDesktop(HDESK hDesktop)
 {
    PDESKTOP_OBJECT DesktopObject;
    NTSTATUS Status;
+   DECLARE_RETURN(BOOL);
+   
+   UserEnterExclusive();
+   DPRINT("Enter NtUserSwitchDesktop\n");
 
    DPRINT("About to switch desktop (0x%X)\n", hDesktop);
 
@@ -1314,7 +1343,7 @@ NtUserSwitchDesktop(HDESK hDesktop)
    if (!NT_SUCCESS(Status))
    {
       DPRINT("Validation of desktop handle (0x%X) failed\n", hDesktop);
-      return FALSE;
+      RETURN(FALSE);
    }
 
    /*
@@ -1326,7 +1355,7 @@ NtUserSwitchDesktop(HDESK hDesktop)
    {
       ObDereferenceObject(DesktopObject);
       DPRINT1("Switching desktop 0x%x denied because the work station is locked!\n", hDesktop);
-      return FALSE;
+      RETURN(FALSE);
    }
 
    /* FIXME: Fail if the desktop belong to an invisible window station */
@@ -1344,7 +1373,12 @@ NtUserSwitchDesktop(HDESK hDesktop)
 
    ObDereferenceObject(DesktopObject);
 
-   return TRUE;
+   RETURN(TRUE);
+   
+CLEANUP:
+   DPRINT("Leave NtUserSwitchDesktop, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;   
 }
 
 /*
@@ -1376,18 +1410,22 @@ NtUserGetThreadDesktop(DWORD dwThreadId, DWORD Unknown1)
    PDESKTOP_OBJECT DesktopObject;
    HDESK Ret, hThreadDesktop;
    OBJECT_HANDLE_INFORMATION HandleInformation;
+   DECLARE_RETURN(HDESK);
+   
+   UserEnterExclusive();
+   DPRINT("Enter NtUserGetThreadDesktop\n");
 
    if(!dwThreadId)
    {
       SetLastWin32Error(ERROR_INVALID_PARAMETER);
-      return 0;
+      RETURN(0);
    }
 
    Status = PsLookupThreadByThreadId((HANDLE)dwThreadId, &Thread);
    if(!NT_SUCCESS(Status))
    {
       SetLastWin32Error(ERROR_INVALID_PARAMETER);
-      return 0;
+      RETURN(0);
    }
 
    if(Thread->ThreadsProcess == PsGetCurrentProcess())
@@ -1396,7 +1434,7 @@ NtUserGetThreadDesktop(DWORD dwThreadId, DWORD Unknown1)
          in the same context */
       Ret = Thread->Tcb.Win32Thread->hDesktop;
       ObDereferenceObject(Thread);
-      return Ret;
+      RETURN(Ret);
    }
 
    /* get the desktop handle and the desktop of the thread */
@@ -1405,7 +1443,7 @@ NtUserGetThreadDesktop(DWORD dwThreadId, DWORD Unknown1)
    {
       ObDereferenceObject(Thread);
       DPRINT1("Desktop information of thread 0x%x broken!?\n", dwThreadId);
-      return NULL;
+      RETURN(NULL);
    }
 
    /* we could just use DesktopObject instead of looking up the handle, but latter
@@ -1425,7 +1463,7 @@ NtUserGetThreadDesktop(DWORD dwThreadId, DWORD Unknown1)
    if(!NT_SUCCESS(Status))
    {
       ObDereferenceObject(Thread);
-      return NULL;
+      RETURN(NULL);
    }
 
    /* lookup our handle table if we can find a handle to the desktop object,
@@ -1435,7 +1473,12 @@ NtUserGetThreadDesktop(DWORD dwThreadId, DWORD Unknown1)
    /* all done, we got a valid handle to the desktop */
    ObDereferenceObject(DesktopObject);
    ObDereferenceObject(Thread);
-   return Ret;
+   RETURN(Ret);
+   
+CLEANUP:
+   DPRINT("Leave NtUserGetThreadDesktop, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
 }
 
 /*
@@ -1451,7 +1494,11 @@ NtUserSetThreadDesktop(HDESK hDesktop)
    PW32THREAD W32Thread;
    PDESKTOP_OBJECT DesktopObject;
    NTSTATUS Status;
-
+   DECLARE_RETURN(BOOL);
+   
+   UserEnterExclusive();
+   DPRINT("Enter NtUserSetThreadDesktop\n");
+   
    /* Validate the new desktop. */
    Status = IntValidateDesktopHandle(
                hDesktop,
@@ -1462,7 +1509,7 @@ NtUserSetThreadDesktop(HDESK hDesktop)
    if (!NT_SUCCESS(Status))
    {
       DPRINT("Validation of desktop handle (0x%X) failed\n", hDesktop);
-      return FALSE;
+      RETURN(FALSE);
    }
 
    W32Thread = PsGetWin32Thread();
@@ -1477,7 +1524,12 @@ NtUserSetThreadDesktop(HDESK hDesktop)
    W32Thread->Desktop = DesktopObject;
    W32Thread->hDesktop = hDesktop;
 
-   return TRUE;
+   RETURN(TRUE);
+   
+CLEANUP:
+   DPRINT("Leave NtUserSetThreadDesktop, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
 }
 
 /* EOF */
index 3e0e1c5..8d7a5c7 100644 (file)
@@ -510,21 +510,6 @@ NtUserCallTwoParam(
          UNIMPLEMENTED
          RETURN( 0);
 
-      case TWOPARAM_ROUTINE_VALIDATERGN:
-         {
-            PWINDOW_OBJECT Window = UserGetWindowObject((HWND) Param1);
-            BOOL ret;
-
-            if (!Window)
-               RETURN(FALSE);
-
-            UserRefObjectCo(Window);
-            ret = co_UserValidateRgn(Window, (HRGN) Param2);
-            UserDerefObjectCo(Window);
-
-            RETURN((DWORD) ret);
-         }
-
       case TWOPARAM_ROUTINE_SETWNDCONTEXTHLPID:
          
          if(!(Window = UserGetWindowObject((HWND)Param1)))
index 156558b..df3f075 100644 (file)
@@ -292,11 +292,12 @@ co_IntPaintWindows(PWINDOW_OBJECT Window, ULONG Flags)
       {
          for (phWnd = List; *phWnd; ++phWnd)
          {
-            Window = IntGetWindowObject(*phWnd);
+            Window = UserGetWindowObject(*phWnd);
             if (Window && (Window->Style & WS_VISIBLE))
             {
+               UserRefObjectCo(Window);
                co_IntPaintWindows(Window, Flags);
-               ObmDereferenceObject(Window);
+               UserDerefObjectCo(Window);
             }
          }
          ExFreePool(List);
@@ -414,31 +415,21 @@ IntInvalidateWindows(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags)
    if (!(Flags & RDW_NOCHILDREN) && !(Window->Style & WS_MINIMIZE) &&
          ((Flags & RDW_ALLCHILDREN) || !(Window->Style & WS_CLIPCHILDREN)))
    {
-      HWND *List, *phWnd;
       PWINDOW_OBJECT Child;
 
-      if ((List = IntWinListChildren(Window)))
+      for (Child = Window->FirstChild; Child; Child = Child->NextSibling)
       {
-         for (phWnd = List; *phWnd; ++phWnd)
+         if (Child->Style & WS_VISIBLE)
          {
-            if(!(Child = UserGetWindowObject(*phWnd)))
-            {
-               continue;
-            }
-            
-            if (Child->Style & WS_VISIBLE)
-            {
-               /*
-                * Recursive call to update children UpdateRegion
-                */
-               HRGN hRgnTemp = NtGdiCreateRectRgn(0, 0, 0, 0);
-               NtGdiCombineRgn(hRgnTemp, hRgn, 0, RGN_COPY);
-               IntInvalidateWindows(Child, hRgnTemp, Flags);
-               NtGdiDeleteObject(hRgnTemp);
-            }
-
+            /*
+             * Recursive call to update children UpdateRegion
+             */
+            HRGN hRgnTemp = NtGdiCreateRectRgn(0, 0, 0, 0);
+            NtGdiCombineRgn(hRgnTemp, hRgn, 0, RGN_COPY);
+            IntInvalidateWindows(Child, hRgnTemp, Flags);
+            NtGdiDeleteObject(hRgnTemp);
          }
-         ExFreePool(List);
+
       }
    }
 
@@ -859,69 +850,6 @@ CLEANUP:
    END_CLEANUP;
 }
 
-/*
- * NtUserInvalidateRect
- *
- * Status
- *    @implemented
- */
-
-DWORD STDCALL
-NtUserInvalidateRect(HWND hWnd, CONST RECT *Rect, BOOL Erase)
-{
-   return NtUserRedrawWindow(hWnd, Rect, 0, RDW_INVALIDATE | (Erase ? RDW_ERASE : 0));
-}
-
-/*
- * NtUserInvalidateRgn
- *
- * Status
- *    @implemented
- */
-
-DWORD STDCALL
-NtUserInvalidateRgn(HWND hWnd, HRGN Rgn, BOOL Erase)
-{
-   return NtUserRedrawWindow(hWnd, NULL, Rgn, RDW_INVALIDATE | (Erase ? RDW_ERASE : 0));
-}
-
-
-
-BOOL FASTCALL
-co_UserValidateRgn(PWINDOW_OBJECT Window, HRGN hRgn)
-{
-   return co_UserRedrawWindow(Window, NULL, hRgn, RDW_VALIDATE | RDW_NOCHILDREN);
-}
-
-/*
- * NtUserValidateRgn
- *
- * Status
- *    @implemented
- */
-
-BOOL STDCALL
-NtUserValidateRgn(HWND hWnd, HRGN hRgn)
-{
-   return NtUserRedrawWindow(hWnd, NULL, hRgn, RDW_VALIDATE | RDW_NOCHILDREN);
-}
-
-/*
- * NtUserUpdateWindow
- *
- * Status
- *    @implemented
- */
-
-BOOL STDCALL
-NtUserUpdateWindow(HWND hWnd)
-{
-   return NtUserRedrawWindow(hWnd, NULL, 0, RDW_UPDATENOW | RDW_ALLCHILDREN);
-}
-
-
-
-
 
 INT FASTCALL
 co_UserGetUpdateRgn(PWINDOW_OBJECT Window, HRGN hRgn, BOOL bErase)
index dffa1e7..114a883 100644 (file)
@@ -293,8 +293,12 @@ static void IntSendDestroyMsg(HWND hWnd)
  *           IntDestroyWindow
  *
  * Destroy storage associated to a window. "Internals" p.358
+ *
+ * This is the "functional" DestroyWindows function ei. all stuff
+ * done in CreateWindow is undone here and not in DestroyWindow:-P
+  
  */
-static LRESULT co_IntDestroyWindow(PWINDOW_OBJECT Window,
+static LRESULT co_UserFreeWindow(PWINDOW_OBJECT Window,
                                    PW32PROCESS ProcessData,
                                    PW32THREAD ThreadData,
                                    BOOLEAN SendMessages)
@@ -343,7 +347,7 @@ static LRESULT co_IntDestroyWindow(PWINDOW_OBJECT Window,
                IntSendDestroyMsg(Child->hSelf);
             }
             else
-               co_IntDestroyWindow(Child, ProcessData, ThreadData, SendMessages);
+               co_UserFreeWindow(Child, ProcessData, ThreadData, SendMessages);
             
             UserDerefObject(Child);
          }
@@ -427,11 +431,8 @@ static LRESULT co_IntDestroyWindow(PWINDOW_OBJECT Window,
 
    IntDestroyScrollBars(Window);
 
-   /* remove the window from the class object */
-   RemoveEntryList(&Window->ClassListEntry);
-
    /* dereference the class */
-   ClassDereferenceObject(Window->Class);
+   ClassDerefObject(Window->Class);
    Window->Class = NULL;
 
    if(Window->WindowRegion)
@@ -1331,13 +1332,13 @@ co_IntCreateWindowEx(DWORD dwExStyle,
                      BOOL bUnicodeWindow)
 {
    PWINSTATION_OBJECT WinSta;
-   PWNDCLASS_OBJECT Class;
+   PWNDCLASS_OBJECT Class = NULL;
    PWINDOW_OBJECT Window = NULL;
    PWINDOW_OBJECT ParentWindow = NULL, OwnerWindow;
    HWND ParentWindowHandle;
    HWND OwnerWindowHandle;
    PMENU_OBJECT SystemMenu;
-   HANDLE Handle;
+   HWND hWnd;
    POINT Pos;
    SIZE Size;
 #if 0
@@ -1352,7 +1353,6 @@ co_IntCreateWindowEx(DWORD dwExStyle,
    CBT_CREATEWNDW CbtCreate;
    LRESULT Result;
    BOOL MenuChanged;
-   BOOL ClassFound;
    DECLARE_RETURN(HWND);
    BOOL HasOwner;
 
@@ -1398,8 +1398,8 @@ co_IntCreateWindowEx(DWORD dwExStyle,
    /* FIXME: parent must belong to the current process */
 
    /* Check the class. */
-   ClassFound = ClassReferenceClassByNameOrAtom(&Class, ClassName->Buffer, hInstance);
-   if (!ClassFound)
+   Class = ClassGetClassByNameOrAtom(ClassName->Buffer, hInstance);
+   if (!Class)
    {
       if (IS_ATOM(ClassName->Buffer))
       {
@@ -1414,55 +1414,52 @@ co_IntCreateWindowEx(DWORD dwExStyle,
       RETURN((HWND)0);
    }
 
+   ClassRefObject(Class);
+
    /* Check the window station. */
    if (PsGetWin32Thread()->Desktop == NULL)
    {
-      ClassDereferenceObject(Class);
-
       DPRINT("Thread is not attached to a desktop! Cannot create window!\n");
       RETURN( (HWND)0);
    }
    WinSta = PsGetWin32Thread()->Desktop->WindowStation;
+
+   //FIXME: Reference thread/desktop instead
    ObReferenceObjectByPointer(WinSta, KernelMode, ExWindowStationObjectType, 0);
 
    /* Create the window object. */
    Window = (PWINDOW_OBJECT)
-            ObmCreateObject(&gHandleTable, &Handle,
+            ObmCreateObject(&gHandleTable, (PHANDLE)&hWnd,
                             otWindow, sizeof(WINDOW_OBJECT) + Class->cbWndExtra
                            );
 
-   DPRINT("Created object with handle %X\n", Handle);
+   DPRINT("Created object with handle %X\n", hWnd);
    if (!Window)
    {
       ObDereferenceObject(WinSta);
-      ClassDereferenceObject(Class);
       SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
       RETURN( (HWND)0);
    }
 
    UserRefObjectCo(Window);
 
-
    ObDereferenceObject(WinSta);
 
    if (NULL == PsGetWin32Thread()->Desktop->DesktopWindow)
    {
       /* If there is no desktop window yet, we must be creating it */
-      PsGetWin32Thread()->Desktop->DesktopWindow = Handle;
+      PsGetWin32Thread()->Desktop->DesktopWindow = hWnd;
    }
 
    /*
     * Fill out the structure describing it.
     */
    Window->Class = Class;
-
-   InsertTailList(&Class->ClassWindowsListHead, &Window->ClassListEntry);
-
    Window->SystemMenu = (HMENU)0;
    Window->ContextHelpId = 0;
    Window->IDMenu = 0;
    Window->Instance = hInstance;
-   Window->hSelf = Handle;
+   Window->hSelf = hWnd;
    if (0 != (dwStyle & WS_CHILD))
    {
       Window->IDMenu = (UINT) hMenu;
@@ -1505,19 +1502,11 @@ co_IntCreateWindowEx(DWORD dwExStyle,
    Window->LastChild = NULL;
    Window->PrevSibling = NULL;
    Window->NextSibling = NULL;
+   Window->ExtraDataSize = Class->cbWndExtra;
 
    /* extra window data */
-   if (Class->cbWndExtra != 0)
-   {
+   if (Class->cbWndExtra)
       Window->ExtraData = (PCHAR)(Window + 1);
-      Window->ExtraDataSize = Class->cbWndExtra;
-      RtlZeroMemory(Window->ExtraData, Window->ExtraDataSize);
-   }
-   else
-   {
-      Window->ExtraData = NULL;
-      Window->ExtraDataSize = 0;
-   }
 
    InitializeListHead(&Window->PropListHead);
    InitializeListHead(&Window->WndObjListHead);
@@ -1530,7 +1519,6 @@ co_IntCreateWindowEx(DWORD dwExStyle,
                                   TAG_STRING);
       if (NULL == Window->WindowName.Buffer)
       {
-         ClassDereferenceObject(Class);
          DPRINT1("Failed to allocate mem for window name\n");
          SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
          RETURN( NULL);
@@ -1612,13 +1600,10 @@ co_IntCreateWindowEx(DWORD dwExStyle,
    Cs.dwExStyle = dwExStyle;
    CbtCreate.lpcs = &Cs;
    CbtCreate.hwndInsertAfter = HWND_TOP;
-   if (co_HOOK_CallHooks(WH_CBT, HCBT_CREATEWND, (WPARAM) Handle, (LPARAM) &CbtCreate))
+   if (co_HOOK_CallHooks(WH_CBT, HCBT_CREATEWND, (WPARAM) hWnd, (LPARAM) &CbtCreate))
    {
-
       /* FIXME - Delete window object and remove it from the thread windows list */
       /* FIXME - delete allocated DCE */
-
-      ClassDereferenceObject(Class);
       DPRINT1("CBT-hook returned !0\n");
       RETURN( (HWND) NULL);
    }
@@ -1827,7 +1812,6 @@ co_IntCreateWindowEx(DWORD dwExStyle,
    if (Result == (LRESULT)-1)
    {
       /* FIXME: Cleanup. */
-      ClassDereferenceObject(Class);
       DPRINT("IntCreateWindowEx(): send CREATE message failed.\n");
       RETURN((HWND)0);
    }
@@ -1911,7 +1895,7 @@ co_IntCreateWindowEx(DWORD dwExStyle,
    if ((!hWndParent) && (!HasOwner))
    {
       DPRINT("Sending CREATED notify\n");
-      co_IntShellHookNotify(HSHELL_WINDOWCREATED, (LPARAM)Handle);
+      co_IntShellHookNotify(HSHELL_WINDOWCREATED, (LPARAM)hWnd);
    }
    else
    {
@@ -1934,14 +1918,14 @@ co_IntCreateWindowEx(DWORD dwExStyle,
       co_WinPosShowWindow(Window, dwShowMode);
    }
 
-   DPRINT("IntCreateWindow(): = %X\n", Handle);
+   DPRINT("IntCreateWindow(): = %X\n", hWnd);
    DPRINT("WindowObject->SystemMenu = 0x%x\n", Window->SystemMenu);
-   RETURN((HWND)Handle);
+   RETURN(hWnd);
 
 CLEANUP:
    if (Window) UserDerefObjectCo(Window);
    if (ParentWindow) UserDerefObjectCo(ParentWindow);
-
+   if (!_ret_ && Class) ClassDerefObject(Class); /* only deref if failure (return 0) */
    END_CLEANUP;
 }
 
@@ -2164,7 +2148,7 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWINDOW_OBJECT Window)
    }
 
    /* Destroy the window storage */
-   co_IntDestroyWindow(Window, PsGetWin32Process(), PsGetWin32Thread(), TRUE);
+   co_UserFreeWindow(Window, PsGetWin32Process(), PsGetWin32Thread(), TRUE);
 
    return TRUE;
 }
@@ -4208,14 +4192,6 @@ NtUserUpdateLayeredWindow(DWORD Unknown0,
 }
 
 
-/*
- * @implemented
- */
-VOID STDCALL
-NtUserValidateRect(HWND hWnd, const RECT* Rect)
-{
-   return (VOID)NtUserRedrawWindow(hWnd, Rect, 0, RDW_VALIDATE | RDW_NOCHILDREN);
-}
 
 
 /*
index 40ab6ff..e8938d4 100644 (file)
@@ -107,6 +107,8 @@ IntWinStaObjectOpen(OB_OPEN_REASON Reason,
    PWINSTATION_OBJECT WinSta = (PWINSTATION_OBJECT)ObjectBody;
    NTSTATUS Status;
 
+DPRINT1("IntWinStaObjectOpen\n");
+
    if (Reason == ObCreateHandle)
    {
       DPRINT("Creating window station (0x%X)\n", WinSta);
@@ -115,10 +117,10 @@ IntWinStaObjectOpen(OB_OPEN_REASON Reason,
 
       InitializeListHead(&WinSta->DesktopListHead);
 
+DPRINT1("Create winsta atomtable\n");
       WinSta->AtomTable = NULL;
-
       Status = RtlCreateAtomTable(37, &WinSta->AtomTable);
-
+if (!NT_SUCCESS(Status)) DPRINT1("Error creating atom table\n");
       WinSta->SystemMenuTemplate = (HANDLE)0;
 
       DPRINT("Window station successfully created.\n");
index ced7a8e..1616bda 100644 (file)
@@ -417,15 +417,12 @@ NtUserGetWindowPlacement                2
 NtUserGetWindowLong                     3
 NtUserGetWindowRect                    2
 NtUserGetWOWClass                       2
-NtUserHideCaret                         1
 NtUserHiliteMenuItem                    4
 NtUserImpersonateDdeClientWindow        2
 NtUserInitializeClientPfnArrays         4
 NtUserInitTask                          11
 NtUserInsertMenuItem                   4
 NtUserInternalGetWindowText             3
-NtUserInvalidateRect                    3
-NtUserInvalidateRgn                     3
 NtUserIsClipboardFormatAvailable        1
 NtUserKillSystemTimer                   2
 NtUserKillTimer                         2
@@ -523,7 +520,7 @@ NtUserSetWindowsHookEx                  6
 NtUserSetWindowStationUser              4
 NtUserSetWindowWord                     3
 NtUserSetWinEventHook                   8
-NtUserShowCaret                         1
+NtUserShowCaret                         2
 NtUserShowScrollBar                     3
 NtUserShowWindow                        2
 NtUserShowWindowAsync                   2
@@ -544,12 +541,10 @@ NtUserUnregisterClass                   3
 NtUserUnregisterHotKey                  2
 NtUserUpdateInputContext                3
 NtUserUpdateInstance                    3
-NtUserUpdateWindow                     1
 NtUserUpdateLayeredWindow               9
 NtUserUpdatePerUserSystemParameters     2
 NtUserUserHandleGrantAccess             3
 NtUserValidateHandleSecure              1
-NtUserValidateRect                      2
 NtUserVkKeyScanEx                       3
 NtUserWaitForInputIdle                  3
 NtUserWaitForMsgAndEvent                1