diff --git a/reactos/dll/win32/user32/include/user32p.h b/reactos/dll/win32/user32/include/user32p.h index fabbb092d4a..093482f507c 100644 --- a/reactos/dll/win32/user32/include/user32p.h +++ b/reactos/dll/win32/user32/include/user32p.h @@ -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; diff --git a/reactos/include/reactos/win32k/ntuser.h b/reactos/include/reactos/win32k/ntuser.h index f8dc6c4f52a..21616a3fc6a 100644 --- a/reactos/include/reactos/win32k/ntuser.h +++ b/reactos/include/reactos/win32k/ntuser.h @@ -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 */ diff --git a/reactos/subsystems/win32/win32k/include/accelerator.h b/reactos/subsystems/win32/win32k/include/accelerator.h index 367715cfc7b..d4ad5982876 100644 --- a/reactos/subsystems/win32/win32k/include/accelerator.h +++ b/reactos/subsystems/win32/win32k/include/accelerator.h @@ -7,6 +7,7 @@ typedef struct _ACCELERATOR_TABLE { + HEAD head; int Count; LPACCEL Table; } ACCELERATOR_TABLE, *PACCELERATOR_TABLE; diff --git a/reactos/subsystems/win32/win32k/include/cursoricon.h b/reactos/subsystems/win32/win32k/include/cursoricon.h index 6e3b39a43f4..c2b66b15b23 100644 --- a/reactos/subsystems/win32/win32k/include/cursoricon.h +++ b/reactos/subsystems/win32/win32k/include/cursoricon.h @@ -11,6 +11,7 @@ typedef struct tagCURICON_PROCESS typedef struct _CURICON_OBJECT { + PROCMARKHEAD head; LIST_ENTRY ListEntry; HANDLE Self; LIST_ENTRY ProcessList; diff --git a/reactos/subsystems/win32/win32k/include/menu.h b/reactos/subsystems/win32/win32k/include/menu.h index 92482c395ba..a89eb891950 100644 --- a/reactos/subsystems/win32/win32k/include/menu.h +++ b/reactos/subsystems/win32/win32k/include/menu.h @@ -29,6 +29,7 @@ typedef struct _MENU_ITEM typedef struct _MENU_OBJECT { + PROCDESKHEAD head; PEPROCESS Process; LIST_ENTRY ListEntry; PMENU_ITEM MenuItemList; diff --git a/reactos/subsystems/win32/win32k/include/object.h b/reactos/subsystems/win32/win32k/include/object.h index c3452dee3e2..f36373ddef2 100644 --- a/reactos/subsystems/win32/win32k/include/object.h +++ b/reactos/subsystems/win32/win32k/include/object.h @@ -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; diff --git a/reactos/subsystems/win32/win32k/include/timer.h b/reactos/subsystems/win32/win32k/include/timer.h index 128bf0febab..a10cf6cb76f 100644 --- a/reactos/subsystems/win32/win32k/include/timer.h +++ b/reactos/subsystems/win32/win32k/include/timer.h @@ -3,6 +3,7 @@ typedef struct _TIMER { + HEAD head; LIST_ENTRY ptmrList; PTHREADINFO pti; PWINDOW_OBJECT pWnd; // hWnd diff --git a/reactos/subsystems/win32/win32k/ntuser/object.c b/reactos/subsystems/win32/win32k/ntuser/object.c index 20378f45e16..0b54f5e0d60 100644 --- a/reactos/subsystems/win32/win32k/ntuser/object.c +++ b/reactos/subsystems/win32/win32k/ntuser/object.c @@ -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; +} diff --git a/reactos/subsystems/win32/win32k/ntuser/timer.c b/reactos/subsystems/win32/win32k/ntuser/timer.c index d348e8a2d4e..c2bc5fbdc0d 100644 --- a/reactos/subsystems/win32/win32k/ntuser/timer.c +++ b/reactos/subsystems/win32/win32k/ntuser/timer.c @@ -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!