[Win32k|User32]
authorJames Tabor <james.tabor@reactos.org>
Thu, 14 Jan 2010 13:33:04 +0000 (13:33 +0000)
committerJames Tabor <james.tabor@reactos.org>
Thu, 14 Jan 2010 13:33:04 +0000 (13:33 +0000)
- Started the user handle rewrite.

svn path=/trunk/; revision=45079

reactos/dll/win32/user32/include/user32p.h
reactos/include/reactos/win32k/ntuser.h
reactos/subsystems/win32/win32k/include/accelerator.h
reactos/subsystems/win32/win32k/include/cursoricon.h
reactos/subsystems/win32/win32k/include/menu.h
reactos/subsystems/win32/win32k/include/object.h
reactos/subsystems/win32/win32k/include/timer.h
reactos/subsystems/win32/win32k/ntuser/object.c
reactos/subsystems/win32/win32k/ntuser/timer.c

index fabbb09..093482f 100644 (file)
@@ -180,6 +180,8 @@ extern int SPY_Init(void);
 #define USER_BODY_TO_HEADER(ObjectBody) \
   ((PUSER_OBJECT_HEADER)(((PUSER_OBJECT_HEADER)ObjectBody) - 1))
 
+#define HANDLEENTRY_INDESTROY 1
+
 typedef struct _USER_HANDLE_ENTRY
 {
     void          *ptr;          /* pointer to object */
@@ -189,7 +191,8 @@ typedef struct _USER_HANDLE_ENTRY
         PTHREADINFO pti;          // pointer to Win32ThreadInfo
         PPROCESSINFO ppi;         // pointer to W32ProcessInfo
     };
-    unsigned short type;         /* object type (0 if free) */
+    unsigned char  type;         /* object type (0 if free) */
+    unsigned char  flags;
     unsigned short generation;   /* generation counter */
 } USER_HANDLE_ENTRY, * PUSER_HANDLE_ENTRY;
 
index f8dc6c4..21616a3 100644 (file)
@@ -94,13 +94,19 @@ typedef struct _THRDESKHEAD
 
 typedef struct _PROCDESKHEAD
 {
-  HANDLE h;
-  DWORD  cLockObj;  
+  HEAD;
   DWORD hTaskWow;
   struct _DESKTOP *rpdesk;
   PVOID       pSelf;
 } PROCDESKHEAD, *PPROCDESKHEAD;
 
+typedef struct _PROCMARKHEAD
+{
+  HEAD;
+  ULONG hTaskWow;
+  PPROCESSINFO ppi;
+} PROCMARKHEAD, *PPROCMARKHEAD;
+
 #define UserHMGetHandle(obj) ((obj)->head.h)
 
 /* Window Client Information structure */
index 367715c..d4ad598 100644 (file)
@@ -7,6 +7,7 @@
 
 typedef struct _ACCELERATOR_TABLE
 {
+  HEAD head;
   int Count;
   LPACCEL Table;
 } ACCELERATOR_TABLE, *PACCELERATOR_TABLE;
index 6e3b39a..c2b66b1 100644 (file)
@@ -11,6 +11,7 @@ typedef struct tagCURICON_PROCESS
 
 typedef struct _CURICON_OBJECT
 {
+  PROCMARKHEAD head;
   LIST_ENTRY ListEntry;
   HANDLE Self;
   LIST_ENTRY ProcessList;
index 92482c3..a89eb89 100644 (file)
@@ -29,6 +29,7 @@ typedef struct _MENU_ITEM
 
 typedef struct _MENU_OBJECT
 {
+  PROCDESKHEAD head;
   PEPROCESS Process;
   LIST_ENTRY ListEntry;
   PMENU_ITEM MenuItemList;
index c3452de..f36373d 100644 (file)
@@ -14,7 +14,7 @@
 #define USER_BODY_TO_HEADER(ObjectBody) \
   ((PUSER_OBJECT_HEADER)(((PUSER_OBJECT_HEADER)ObjectBody) - 1))
 
-
+#define HANDLEENTRY_INDESTROY 1
 
 typedef struct _USER_HANDLE_ENTRY
 {
@@ -25,7 +25,8 @@ typedef struct _USER_HANDLE_ENTRY
         PTHREADINFO pti;          // pointer to Win32ThreadInfo
         PPROCESSINFO ppi;         // pointer to W32ProcessInfo
     };
-    unsigned short type;         /* object type (0 if free) */
+    unsigned char  type;         /* object type (0 if free) */
+    unsigned char  flags;
     unsigned short generation;   /* generation counter */
 } USER_HANDLE_ENTRY, * PUSER_HANDLE_ENTRY;
 
index 128bf0f..a10cf6c 100644 (file)
@@ -3,6 +3,7 @@
 
 typedef struct _TIMER
 {
+  HEAD           head;
   LIST_ENTRY     ptmrList;
   PTHREADINFO    pti;
   PWINDOW_OBJECT pWnd;         // hWnd
index 20378f4..0b54f5e 100644 (file)
@@ -151,6 +151,7 @@ __inline static void *free_user_entry(PUSER_HANDLE_TABLE ht, PUSER_HANDLE_ENTRY
    ret = entry->ptr;
    entry->ptr  = ht->freelist;
    entry->type = 0;
+   entry->flags = 0;
    entry->pi = NULL;
    ht->freelist  = entry;
 
@@ -198,6 +199,7 @@ HANDLE UserAllocHandle(PUSER_HANDLE_TABLE ht, PVOID object, USER_OBJECT_TYPE typ
       return 0;
    entry->ptr  = object;
    entry->type = type;
+   entry->flags = 0;
    entry->pi = UserHandleOwnerByType(type);
    if (++entry->generation >= 0xffff)
       entry->generation = 1;
@@ -294,8 +296,6 @@ PVOID UserGetNextHandle(PUSER_HANDLE_TABLE ht, HANDLE* handle, USER_OBJECT_TYPE
    return NULL;
 }
 
-
-
 PVOID FASTCALL
 UserCreateObject(PUSER_HANDLE_TABLE ht, HANDLE* h,USER_OBJECT_TYPE type , ULONG size)
 {
@@ -401,7 +401,6 @@ BOOL FASTCALL UserDereferenceObject(PVOID obj)
 }
 
 
-
 BOOL FASTCALL UserCreateHandleTable(VOID)
 {
 
@@ -429,3 +428,162 @@ BOOL FASTCALL UserCreateHandleTable(VOID)
 
    return TRUE;
 }
+
+//
+// New
+//
+PVOID
+FASTCALL
+NewUserCreateObject( PUSER_HANDLE_TABLE ht,
+                     HANDLE* h,
+                     USER_OBJECT_TYPE type,
+                     ULONG size)
+{
+   HANDLE hi;
+   PVOID Object;
+   PTHREADINFO pti;
+   PPROCESSINFO ppi;
+   BOOL dt;
+
+   pti = GetW32ThreadInfo();
+   ppi = pti->ppi;
+
+   switch (type)
+   {
+      case otWindow:
+         Object = DesktopHeapAlloc(pti->rpdesk, size);
+         dt = TRUE;
+         break;
+
+      default:
+         Object = UserHeapAlloc(size);
+         dt = FALSE;
+         break;
+   }
+
+   if (!Object)
+      return NULL;
+
+
+   hi = UserAllocHandle(ht, Object, type );
+   if (!hi)
+   {
+      if (dt)
+         DesktopHeapFree(pti->rpdesk, Object);
+      else
+         UserHeapFree(Object);
+      return NULL;
+   }
+
+   RtlZeroMemory(Object, size);
+
+   switch (type)
+   {
+        case otWindow:
+        case otHook:
+            ((PTHRDESKHEAD)Object)->rpdesk = pti->rpdesk;
+            ((PTHRDESKHEAD)Object)->pSelf = Object;
+        case otEvent:
+            ((PTHROBJHEAD)Object)->pti = pti;
+            break;
+
+        case otMenu:
+        case otCallProc:
+            ((PPROCDESKHEAD)Object)->rpdesk = pti->rpdesk;
+            ((PPROCDESKHEAD)Object)->pSelf = Object;            
+            break;
+
+        case otCursorIcon:
+            ((PPROCMARKHEAD)Object)->ppi = ppi;
+            break;
+
+        default:
+            break;
+   }
+   /* Now set default headers. */
+   ((PHEAD)Object)->h = hi;
+   ((PHEAD)Object)->cLockObj = 2; // we need this, because we create 2 refs: handle and pointer!
+
+   if (h)
+      *h = hi;
+   return Object;
+}
+
+BOOL
+FASTCALL
+NewUserDereferenceObject(PVOID obj)
+{
+  ASSERT(((PHEAD)obj)->cLockObj >= 1);
+
+  if (--((PHEAD)obj)->cLockObj <= 0)
+  {
+     return TRUE;
+  }
+  return FALSE;
+}
+
+BOOL
+FASTCALL
+NewUserFreeHandle(PUSER_HANDLE_TABLE ht,  HANDLE handle )
+{
+  PUSER_HANDLE_ENTRY entry;
+  PVOID object;
+  USER_OBJECT_TYPE type;
+
+  if (!(entry = handle_to_entry( ht, handle )))
+  {
+     SetLastNtError( STATUS_INVALID_HANDLE );
+     return FALSE;
+  }
+
+  entry->flags = HANDLEENTRY_INDESTROY;
+
+  if (NewUserDereferenceObject(entry->ptr))
+  {
+     type = entry->type;
+     object = free_user_entry(ht, entry );
+
+     if (type == otWindow) // If more, go switch.
+     {
+        return DesktopHeapFree(GetW32ThreadInfo()->rpdesk, object);
+     }
+     return UserHeapFree(object);
+  }
+  return FALSE;
+}
+
+BOOL
+FASTCALL
+NewUserDeleteObject(HANDLE h, USER_OBJECT_TYPE type )
+{
+   PVOID body = UserGetObject(gHandleTable, h, type);
+   
+   if (!body) return FALSE;
+
+   ASSERT( ((PHEAD)body)->cLockObj >= 1);
+
+   return NewUserFreeHandle(gHandleTable, h);
+}
+
+VOID
+FASTCALL
+NewUserReferenceObject(PVOID obj)
+{
+   ASSERT(((PHEAD)obj)->cLockObj >= 0);
+
+   ((PHEAD)obj)->cLockObj++;
+}
+
+PVOID
+FASTCALL
+NewUserReferenceObjectByHandle(HANDLE handle, USER_OBJECT_TYPE type)
+{
+    PVOID object;
+
+    object = UserGetObject(gHandleTable, handle, type);
+    if (object)
+    {
+        NewUserReferenceObject(object);
+    }
+    return object;
+}
index d348e8a..c2bc5fb 100644 (file)
@@ -82,6 +82,7 @@ FindTimer(PWINDOW_OBJECT Window,
           UINT flags,
           BOOL Distroy)
 {
+  PLIST_ENTRY pLE;
   PTIMER pTmr = FirstpTmr;
   KeEnterCriticalRegion();
   do
@@ -100,7 +101,8 @@ FindTimer(PWINDOW_OBJECT Window,
        break;
     }
 
-    pTmr = (PTIMER)pTmr->ptmrList.Flink;
+    pLE = pTmr->ptmrList.Flink;
+    pTmr = CONTAINING_RECORD(pLE, TIMER, ptmrList);
   } while (pTmr != FirstpTmr);
   KeLeaveCriticalRegion();
 
@@ -111,6 +113,7 @@ PTIMER
 FASTCALL
 FindSystemTimer(PMSG pMsg)
 {
+  PLIST_ENTRY pLE;
   PTIMER pTmr = FirstpTmr;
   KeEnterCriticalRegion();
   do
@@ -121,7 +124,8 @@ FindSystemTimer(PMSG pMsg)
          (pTmr->flags & TMRF_SYSTEM) )
        break;
 
-    pTmr = (PTIMER)pTmr->ptmrList.Flink;
+    pLE = pTmr->ptmrList.Flink;
+    pTmr = CONTAINING_RECORD(pLE, TIMER, ptmrList);    
   } while (pTmr != FirstpTmr);
   KeLeaveCriticalRegion();
 
@@ -135,6 +139,7 @@ ValidateTimerCallback(PTHREADINFO pti,
                       WPARAM wParam,
                       LPARAM lParam)
 {
+  PLIST_ENTRY pLE;
   PTIMER pTmr = FirstpTmr;
 
   if (!pTmr) return FALSE;
@@ -144,11 +149,11 @@ ValidateTimerCallback(PTHREADINFO pti,
   {
     if ( (lParam == (LPARAM)pTmr->pfn) &&
          (pTmr->flags & (TMRF_SYSTEM|TMRF_RIT)) &&
-//       (pTmr->head.pti->ppi == pti->ppi) )
          (pTmr->pti->ppi == pti->ppi) )
        break;
 
-    pTmr = (PTIMER)pTmr->ptmrList.Flink;
+    pLE = pTmr->ptmrList.Flink;
+    pTmr = CONTAINING_RECORD(pLE, TIMER, ptmrList);
   } while (pTmr != FirstpTmr);
   KeLeaveCriticalRegion();
 
@@ -265,6 +270,7 @@ BOOL
 FASTCALL
 PostTimerMessages(PWINDOW_OBJECT Window)
 {
+  PLIST_ENTRY pLE;
   PUSER_MESSAGE_QUEUE ThreadQueue;
   MSG Msg;
   PTHREADINFO pti;
@@ -299,7 +305,8 @@ PostTimerMessages(PWINDOW_OBJECT Window)
            Hit = TRUE;
         }
 
-     pTmr = (PTIMER)pTmr->ptmrList.Flink;
+     pLE = pTmr->ptmrList.Flink;
+     pTmr = CONTAINING_RECORD(pLE, TIMER, ptmrList);
   } while (pTmr != FirstpTmr);
   KeLeaveCriticalRegion();
 
@@ -312,6 +319,7 @@ ProcessTimers(VOID)
 {
   LARGE_INTEGER TickCount, DueTime;
   LONG Time;
+  PLIST_ENTRY pLE;
   PTIMER pTmr = FirstpTmr;
 
   if (!pTmr) return;
@@ -327,7 +335,8 @@ ProcessTimers(VOID)
   {
     if (pTmr->flags & TMRF_WAITING)
     {
-       pTmr = (PTIMER)pTmr->ptmrList.Flink;
+       pLE = pTmr->ptmrList.Flink;
+       pTmr = CONTAINING_RECORD(pLE, TIMER, ptmrList);
        continue;
     }
 
@@ -363,7 +372,8 @@ ProcessTimers(VOID)
        else
           pTmr->cmsCountdown -= Time - TimeLast;
     }
-    pTmr = (PTIMER)pTmr->ptmrList.Flink;
+    pLE = pTmr->ptmrList.Flink;
+    pTmr = CONTAINING_RECORD(pLE, TIMER, ptmrList);
   } while (pTmr != FirstpTmr);
 
   // Restart the timer thread!