[Win32k|User32]

- Switch to the new user handle manager. Added more handle types to win32k. One or two step to WND, desktop heap supported.
- Test with every application in my test suite. Needs more testing and clean up. Bleeding edge!

svn path=/trunk/; revision=45085
This commit is contained in:
James Tabor 2010-01-15 13:47:25 +00:00
parent 44648580d7
commit fc70f9c60c
15 changed files with 134 additions and 261 deletions

View file

@ -322,13 +322,13 @@ GetUser32Handle(HANDLE handle)
static const BOOL g_ObjectHeapTypeShared[VALIDATE_TYPE_EVENT + 1] =
{
FALSE, /* VALIDATE_TYPE_FREE (not used) */
TRUE, /* VALIDATE_TYPE_WIN */ /* FIXME: FALSE once WINDOW_OBJECT is deleted! */
TRUE, /* VALIDATE_TYPE_MENU */
TRUE, /* VALIDATE_TYPE_WIN FALSE */
TRUE, /* VALIDATE_TYPE_MENU FALSE */
TRUE, /* VALIDATE_TYPE_CURSOR */
TRUE, /* VALIDATE_TYPE_MWPOS */
TRUE, /* VALIDATE_TYPE_HOOK */
TRUE, /* VALIDATE_TYPE_HOOK FALSE */
FALSE, /* (not used) */
TRUE, /* VALIDATE_TYPE_CALLPROC */
TRUE, /* VALIDATE_TYPE_CALLPROC FALSE */
TRUE, /* VALIDATE_TYPE_ACCEL */
FALSE, /* (not used) */
FALSE, /* (not used) */
@ -357,7 +357,10 @@ ValidateHandle(HANDLE handle, UINT uType)
uType = pEntry->type;
// Must have an entry and must be the same type!
if ( (!pEntry) || (pEntry->type != uType) || !pEntry->ptr )
if ( (!pEntry) ||
(pEntry->type != uType) ||
!pEntry->ptr ||
(pEntry->flags & HANDLEENTRY_INDESTROY) )
{
switch ( uType )
{ // Test (with wine too) confirms these results!
@ -442,6 +445,13 @@ ValidateCallProc(HANDLE hCallProc)
return NULL;
}
// HACK HACK HACK!
typedef struct _WNDX
{
THRDESKHEAD head;
PWND pWnd;
} WNDX, *PWNDX;
//
// Validate a window handle and return the pointer to the object.
//
@ -460,9 +470,6 @@ ValidateHwnd(HWND hwnd)
Wnd = ValidateHandle((HANDLE)hwnd, VALIDATE_TYPE_WIN);
if (Wnd != NULL)
{
/* FIXME: Check if handle table entry is marked as deleting and
return NULL in this case! */
#if 0
return Wnd;
#else
@ -473,8 +480,8 @@ ValidateHwnd(HWND hwnd)
!!! REMOVE AS SOON AS WINDOW_OBJECT NO LONGER EXISTS !!!
*/
if (*((PVOID*)Wnd) != NULL)
return DesktopPtrToUser(*((PVOID*)Wnd));
if ( ((PWNDX)Wnd)->pWnd != NULL)
return DesktopPtrToUser( ((PWNDX)Wnd)->pWnd );
#endif
}
@ -499,9 +506,6 @@ ValidateHwndNoErr(HWND hwnd)
Wnd = ValidateHandleNoErr((HANDLE)hwnd, VALIDATE_TYPE_WIN);
if (Wnd != NULL)
{
/* FIXME: Check if handle table entry is marked as deleting and
return NULL in this case! */
#if 0
return Wnd;
#else
@ -512,8 +516,8 @@ ValidateHwndNoErr(HWND hwnd)
!!! REMOVE AS SOON AS WINDOW_OBJECT NO LONGER EXISTS !!!
*/
if (*((PVOID*)Wnd) != NULL)
return DesktopPtrToUser(*((PVOID*)Wnd));
if ( ((PWNDX)Wnd)->pWnd != NULL)
return DesktopPtrToUser( ((PWNDX)Wnd)->pWnd );
#endif
}

View file

@ -28,11 +28,11 @@ DestroyCallProc(IN PDESKTOPINFO Desktop,
IN OUT PCALLPROCDATA CallProc);
PCALLPROCDATA
CloneCallProc(IN PDESKTOPINFO Desktop,
CloneCallProc(IN PDESKTOP Desktop,
IN PCALLPROCDATA CallProc);
PCALLPROCDATA
CreateCallProc(IN PDESKTOPINFO Desktop,
CreateCallProc(IN PDESKTOP Desktop,
IN WNDPROC WndProc,
IN BOOL Unicode,
IN PPROCESSINFO pi);

View file

@ -8,12 +8,6 @@
#define FIRST_USER_HANDLE 0x0020 /* first possible value for low word of user handle */
#define LAST_USER_HANDLE 0xffef /* last possible value for low word of user handle */
#define USER_HEADER_TO_BODY(ObjectHeader) \
((PVOID)(((PUSER_OBJECT_HEADER)ObjectHeader) + 1))
#define USER_BODY_TO_HEADER(ObjectBody) \
((PUSER_OBJECT_HEADER)(((PUSER_OBJECT_HEADER)ObjectBody) - 1))
#define HANDLEENTRY_INDESTROY 1
typedef struct _USER_HANDLE_ENTRY
@ -48,38 +42,32 @@ typedef enum _USER_OBJECT_TYPE
otWindow,
otMenu,
otCursorIcon,
otDWP,
otSMWP,
otHook,
otCallProc = 7,
otClipBoardData,
otCallProc,
otAccel,
otMonitor = 12,
otEvent = 15,
otTimer
otDDEaccess,
otDDEconv,
otDDExact,
otMonitor,
otKBDlayout,
otKBDfile,
otEvent,
otTimer,
otInputContext,
otHidData,
otDeviceInfo,
otTouchInput,
otGestureInfo
} USER_OBJECT_TYPE;
typedef struct _USER_OBJECT_HEADER
/*
* Header for user object
*/
{
// USER_OBJECT_TYPE Type;
LONG RefCount;
BOOL destroyed;
HANDLE hSelf;
// CSHORT Size;
} USER_OBJECT_HEADER, *PUSER_OBJECT_HEADER;
typedef struct _USER_REFERENCE_ENTRY
{
SINGLE_LIST_ENTRY Entry;
PVOID obj;
} USER_REFERENCE_ENTRY, *PUSER_REFERENCE_ENTRY;
#include <malloc.h>
#define USER_ASSERT(exp,file,line) \
@ -109,11 +97,11 @@ extern PUSER_HANDLE_TABLE gHandleTable;
VOID FASTCALL UserReferenceObject(PVOID obj);
PVOID FASTCALL UserReferenceObjectByHandle(HANDLE handle, USER_OBJECT_TYPE type);
BOOL FASTCALL UserDereferenceObject(PVOID obj);
PVOID FASTCALL UserCreateObject(PUSER_HANDLE_TABLE ht, HANDLE* h,USER_OBJECT_TYPE type , ULONG size);
PVOID FASTCALL UserCreateObject(PUSER_HANDLE_TABLE ht, struct _DESKTOP* pDesktop, HANDLE* h,USER_OBJECT_TYPE type , ULONG size);
BOOL FASTCALL UserDeleteObject(HANDLE h, USER_OBJECT_TYPE type );
PVOID UserGetObject(PUSER_HANDLE_TABLE ht, HANDLE handle, USER_OBJECT_TYPE type );
HANDLE UserAllocHandle(PUSER_HANDLE_TABLE ht, PVOID object, USER_OBJECT_TYPE type );
BOOL UserFreeHandle(PUSER_HANDLE_TABLE ht, HANDLE handle );
BOOL FASTCALL UserFreeHandle(PUSER_HANDLE_TABLE ht, HANDLE handle );
PVOID UserGetNextHandle(PUSER_HANDLE_TABLE ht, HANDLE* handle, USER_OBJECT_TYPE type );
PUSER_HANDLE_ENTRY handle_to_entry(PUSER_HANDLE_TABLE ht, HANDLE handle );
BOOL FASTCALL UserCreateHandleTable(VOID);
@ -152,8 +140,6 @@ UserDerefObjectCo(PVOID obj)
UserDereferenceObject(obj);
}
HANDLE FASTCALL UserObjectToHandle(PVOID obj);
VOID FASTCALL CreateStockObjects (VOID);
VOID FASTCALL CreateSysColorObjects (VOID);

View file

@ -9,7 +9,7 @@ PMENU_OBJECT FASTCALL UserGetMenuObject(HMENU hMenu);
#define ASSERT_REFS_CO(_obj_) \
{ \
LONG ref = USER_BODY_TO_HEADER(_obj_)->RefCount;\
LONG ref = ((PHEAD)_obj_)->cLockObj;\
if (!(ref >= 1)){ \
DPRINT1("ASSERT: obj 0x%x, refs %i\n", _obj_, ref); \
ASSERT(FALSE); \
@ -21,7 +21,7 @@ PMENU_OBJECT FASTCALL UserGetMenuObject(HMENU hMenu);
{ \
PSINGLE_LIST_ENTRY e; \
BOOL gotit=FALSE; \
LONG ref = USER_BODY_TO_HEADER(_obj_)->RefCount;\
LONG ref = ((PHEAD)_obj_)->cLockObj;\
if (!(ref >= 1)){ \
DPRINT1("obj 0x%x, refs %i\n", _obj_, ref); \
ASSERT(FALSE); \
@ -38,7 +38,7 @@ PMENU_OBJECT FASTCALL UserGetMenuObject(HMENU hMenu);
}
#endif
#define DUMP_REFS(obj) DPRINT1("obj 0x%x, refs %i\n",obj, USER_BODY_TO_HEADER(obj)->RefCount)
#define DUMP_REFS(obj) DPRINT1("obj 0x%x, refs %i\n",obj, ((PHEAD)obj)->cLockObj)
PWINDOW_OBJECT FASTCALL IntGetWindowObject(HWND hWnd);

View file

@ -20,10 +20,7 @@ BOOL FASTCALL UserUpdateUiState(PWND Wnd, WPARAM wParam);
typedef struct _WINDOW_OBJECT
{
/* NOTE: Do *NOT* Move this pointer anywhere in this structure! This
is a pointer to the WINDOW structure that eventually replaces
the WINDOW_OBJECT structure! USER32 expects this pointer to
be here until WINDOW_OBJECT has completely been superseded! */
THRDESKHEAD head;
PWND Wnd;
/* Pointer to the thread information */

View file

@ -86,7 +86,7 @@ PACCELERATOR_TABLE FASTCALL UserGetAccelObject(HACCEL hAccel)
return NULL;
}
ASSERT(USER_BODY_TO_HEADER(Accel)->RefCount >= 0);
ASSERT(Accel->head.cLockObj >= 0);
return Accel;
}
@ -357,7 +357,7 @@ NtUserCreateAcceleratorTable(
RETURN( (HACCEL) NULL );
}
Accel = UserCreateObject(gHandleTable, (PHANDLE)&hAccel, otAccel, sizeof(ACCELERATOR_TABLE));
Accel = UserCreateObject(gHandleTable, NULL, (PHANDLE)&hAccel, otAccel, sizeof(ACCELERATOR_TABLE));
if (Accel == NULL)
{

View file

@ -20,35 +20,30 @@ WNDPROC
GetCallProcHandle(IN PCALLPROCDATA CallProc)
{
/* FIXME - check for 64 bit architectures... */
return (WNDPROC)((ULONG_PTR)UserObjectToHandle(CallProc) | 0xFFFF0000);
return (WNDPROC)((ULONG_PTR)UserHMGetHandle(CallProc) | 0xFFFF0000);
}
VOID
DestroyCallProc(IN PDESKTOPINFO Desktop,
IN OUT PCALLPROCDATA CallProc)
{
/* FIXME - use new object manager! */
HANDLE Handle = UserObjectToHandle(CallProc);
UserDeleteObject(Handle,
otCallProc);
UserDeleteObject(UserHMGetHandle(CallProc), otCallProc);
}
PCALLPROCDATA
CloneCallProc(IN PDESKTOPINFO Desktop,
CloneCallProc(IN PDESKTOP Desktop,
IN PCALLPROCDATA CallProc)
{
PCALLPROCDATA NewCallProc;
HANDLE Handle;
/* FIXME - use new object manager! */
NewCallProc = (PCALLPROCDATA)UserCreateObject(gHandleTable,
Desktop,
&Handle,
otCallProc,
sizeof(CALLPROCDATA));
if (NewCallProc != NULL)
{
NewCallProc->head.h = Handle;
NewCallProc->pfnClientPrevious = CallProc->pfnClientPrevious;
NewCallProc->wType = CallProc->wType;
NewCallProc->spcpdNext = NULL;
@ -58,7 +53,7 @@ CloneCallProc(IN PDESKTOPINFO Desktop,
}
PCALLPROCDATA
CreateCallProc(IN PDESKTOPINFO Desktop,
CreateCallProc(IN PDESKTOP Desktop,
IN WNDPROC WndProc,
IN BOOL Unicode,
IN PPROCESSINFO pi)
@ -66,14 +61,13 @@ CreateCallProc(IN PDESKTOPINFO Desktop,
PCALLPROCDATA NewCallProc;
HANDLE Handle;
/* FIXME - use new object manager! */
NewCallProc = (PCALLPROCDATA)UserCreateObject(gHandleTable,
Desktop,
&Handle,
otCallProc,
sizeof(CALLPROCDATA));
if (NewCallProc != NULL)
{
NewCallProc->head.h = Handle;
NewCallProc->pfnClientPrevious = WndProc;
NewCallProc->wType |= Unicode ? UserGetCPDA2U : UserGetCPDU2A ;
NewCallProc->spcpdNext = NULL;
@ -90,7 +84,6 @@ UserGetCallProcInfo(IN HANDLE hCallProc,
/* NOTE: Accessing the WNDPROC_INFO structure may raise an exception! */
/* FIXME - use new object manager! */
CallProc = UserGetObject(gHandleTable,
hCallProc,
otCallProc);

View file

@ -95,7 +95,7 @@ PCURICON_OBJECT FASTCALL UserGetCurIconObject(HCURSOR hCurIcon)
return NULL;
}
ASSERT(USER_BODY_TO_HEADER(CurIcon)->RefCount >= 1);
ASSERT(CurIcon->head.cLockObj >= 1);
return CurIcon;
}
@ -348,7 +348,7 @@ IntCreateCurIconHandle()
PCURICON_OBJECT CurIcon;
HANDLE hCurIcon;
CurIcon = UserCreateObject(gHandleTable, &hCurIcon, otCursorIcon, sizeof(CURICON_OBJECT));
CurIcon = UserCreateObject(gHandleTable, NULL, &hCurIcon, otCursorIcon, sizeof(CURICON_OBJECT));
if (!CurIcon)
{

View file

@ -138,7 +138,7 @@ IntRemoveEvent(PEVENTHOOK pEH)
RemoveEntryList(&pEH->Chain);
GlobalEvents->Counts--;
if (!GlobalEvents->Counts) gpsi->dwInstalledEventHooks = 0;
UserDeleteObject(pEH->head.h, otEvent);
UserDeleteObject(UserHMGetHandle(pEH), otEvent);
KeLeaveCriticalRegion();
return TRUE;
}
@ -160,14 +160,14 @@ co_EVENT_CallEvents( DWORD event,
pEH = pEP->pEH;
Result = co_IntCallEventProc( pEH->head.h,
event,
hwnd,
pEP->idObject,
pEP->idChild,
(DWORD_PTR)(NtCurrentTeb()->ClientId).UniqueThread,
(DWORD)EngGetTickCount(),
pEH->Proc);
Result = co_IntCallEventProc( UserHMGetHandle(pEH),
event,
hwnd,
pEP->idObject,
pEP->idChild,
(DWORD_PTR)(NtCurrentTeb()->ClientId).UniqueThread,
(DWORD)EngGetTickCount(),
pEH->Proc);
return Result;
}
@ -323,7 +323,7 @@ NtUserSetWinEventHook(
}
}
pEH = UserCreateObject(gHandleTable, &Handle, otEvent, sizeof(EVENTHOOK));
pEH = UserCreateObject(gHandleTable, NULL, &Handle, otEvent, sizeof(EVENTHOOK));
if (pEH)
{
InsertTailList(&GlobalEvents->Events, &pEH->Chain);

View file

@ -62,9 +62,9 @@ IntGetHookObject(HHOOK hHook)
return NULL;
}
ASSERT(USER_BODY_TO_HEADER(Hook)->RefCount >= 0);
ASSERT(Hook->head.cLockObj >= 0);
USER_BODY_TO_HEADER(Hook)->RefCount++;
Hook->head.cLockObj++;
return Hook;
}
@ -98,13 +98,12 @@ IntAddHook(PETHREAD Thread, int HookId, BOOLEAN Global, PWINSTATION_OBJECT WinSt
}
}
Hook = UserCreateObject(gHandleTable, &Handle, otHook, sizeof(HOOK));
Hook = UserCreateObject(gHandleTable, NULL, &Handle, otHook, sizeof(HOOK));
if (NULL == Hook)
{
return NULL;
}
Hook->head.h = Handle;
Hook->Thread = Thread;
Hook->HookId = HookId;
@ -222,7 +221,7 @@ IntFreeHook(PHOOKTABLE Table, PHOOK Hook, PWINSTATION_OBJECT WinStaObj)
}
/* Close handle */
UserDeleteObject(Hook->head.h, otHook);
UserDeleteObject(UserHMGetHandle(Hook), otHook);
}
/* remove a hook, freeing it if the chain is not in use */
@ -1283,7 +1282,7 @@ NtUserSetWindowsHookEx(HINSTANCE Mod,
Hook->Proc = HookProc;
Hook->Ansi = Ansi;
Handle = Hook->head.h;
Handle = UserHMGetHandle(Hook);
/* Clear the client threads next hook. */
ClientInfo->phkCurrent = 0;
@ -1334,7 +1333,7 @@ NtUserUnhookWindowsHookEx(HHOOK Hook)
RETURN( FALSE);
}
ASSERT(Hook == HookObj->head.h);
ASSERT(Hook == UserHMGetHandle(HookObj));
IntRemoveHook(HookObj, WinStaObj, FALSE);

View file

@ -115,7 +115,7 @@ PMENU_OBJECT FASTCALL UserGetMenuObject(HMENU hMenu)
return NULL;
}
ASSERT(USER_BODY_TO_HEADER(Menu)->RefCount >= 0);
ASSERT(Menu->head.cLockObj >= 0);
return Menu;
}
@ -179,9 +179,9 @@ IntGetMenuObject(HMENU hMenu)
PMENU_OBJECT Menu = UserGetMenuObject(hMenu);
if (Menu)
{
ASSERT(USER_BODY_TO_HEADER(Menu)->RefCount >= 0);
ASSERT(Menu->head.cLockObj >= 0);
USER_BODY_TO_HEADER(Menu)->RefCount++;
Menu->head.cLockObj++;
}
return Menu;
}
@ -297,10 +297,11 @@ IntCreateMenu(PHANDLE Handle, BOOL IsMenuBar)
PMENU_OBJECT Menu;
PPROCESSINFO CurrentWin32Process;
Menu = (PMENU_OBJECT)UserCreateObject(
gHandleTable, Handle,
otMenu, sizeof(MENU_OBJECT));
Menu = (PMENU_OBJECT)UserCreateObject( gHandleTable,
NULL,
Handle,
otMenu,
sizeof(MENU_OBJECT));
if(!Menu)
{
*Handle = 0;
@ -407,10 +408,11 @@ IntCloneMenu(PMENU_OBJECT Source)
if(!Source)
return NULL;
Menu = (PMENU_OBJECT)UserCreateObject(
gHandleTable, &hMenu,
otMenu, sizeof(MENU_OBJECT));
Menu = (PMENU_OBJECT)UserCreateObject( gHandleTable,
NULL,
&hMenu,
otMenu,
sizeof(MENU_OBJECT));
if(!Menu)
return NULL;

View file

@ -89,13 +89,12 @@ IntCreateMonitorObject()
HANDLE Handle;
PMONITOR Monitor;
Monitor = UserCreateObject(gHandleTable, &Handle, otMonitor, sizeof (MONITOR));
Monitor = UserCreateObject(gHandleTable, NULL, &Handle, otMonitor, sizeof (MONITOR));
if (Monitor == NULL)
{
return NULL;
}
Monitor->head.h = Handle;
ExInitializeFastMutex(&Monitor->Lock);
return Monitor;
@ -139,7 +138,7 @@ UserGetMonitorObject(IN HMONITOR hMonitor)
return NULL;
}
ASSERT(USER_BODY_TO_HEADER(Monitor)->RefCount >= 0);
ASSERT(Monitor->head.cLockObj >= 0);
return Monitor;
}
@ -179,7 +178,7 @@ IntAttachMonitor(IN PDEVOBJ *pGdiDevice,
{
DPRINT("Couldn't duplicate monitor name!\n");
UserDereferenceObject(Monitor);
UserDeleteObject(Monitor->head.h, otMonitor);
UserDeleteObject(UserHMGetHandle(Monitor), otMonitor);
return STATUS_INSUFFICIENT_RESOURCES;
}
@ -406,7 +405,7 @@ IntGetMonitorsFromRect(OPTIONAL IN LPCRECTL pRect,
if (iCount < listSize)
{
if (hMonitorList != NULL)
hMonitorList[iCount] = Monitor->head.h;
hMonitorList[iCount] = UserHMGetHandle(Monitor);
if (monitorRectList != NULL)
monitorRectList[iCount] = IntersectionRect;
}
@ -418,7 +417,7 @@ IntGetMonitorsFromRect(OPTIONAL IN LPCRECTL pRect,
if (iCount < listSize)
{
if (hMonitorList != NULL)
hMonitorList[iCount] = NearestMonitor->head.h;
hMonitorList[iCount] = UserHMGetHandle(NearestMonitor);
}
iCount++;
}
@ -427,7 +426,7 @@ IntGetMonitorsFromRect(OPTIONAL IN LPCRECTL pRect,
if (iCount < listSize)
{
if (hMonitorList != NULL)
hMonitorList[iCount] = PrimaryMonitor->head.h;
hMonitorList[iCount] = UserHMGetHandle(PrimaryMonitor);
}
iCount++;
}
@ -763,7 +762,7 @@ NtUserMonitorFromPoint(
{
PMONITOR MonitorObj = IntGetPrimaryMonitor();
if (MonitorObj)
hMonitor = MonitorObj->head.h;
hMonitor = UserHMGetHandle(MonitorObj);
}
else if (dwFlags == MONITOR_DEFAULTTONEAREST)
{
@ -828,7 +827,7 @@ NtUserMonitorFromRect(
{
PMONITOR monitorObj = IntGetPrimaryMonitor();
if (monitorObj)
return monitorObj->head.h;
return UserHMGetHandle(monitorObj);
}
else if (dwFlags == MONITOR_DEFAULTTONEAREST)
{

View file

@ -168,6 +168,7 @@ UserHandleOwnerByType(USER_OBJECT_TYPE type)
switch (type)
{
case otWindow:
case otInputContext:
pi = GetW32ThreadInfo();
break;
@ -250,26 +251,6 @@ void *get_user_object_handle(PUSER_HANDLE_TABLE ht, HANDLE* handle, USER_OBJECT
return entry->ptr;
}
/* free a user handle */
BOOL UserFreeHandle(PUSER_HANDLE_TABLE ht, HANDLE handle )
{
PUSER_HANDLE_ENTRY entry;
PVOID object;
if (!(entry = handle_to_entry( ht, handle )))
{
SetLastNtError( STATUS_INVALID_HANDLE );
return FALSE;
}
object = free_user_entry(ht, entry );
/* We removed the handle, which was a reference! */
return UserDereferenceObject(object);
return TRUE;
}
/* return the next user handle after 'handle' that is of a given type */
PVOID UserGetNextHandle(PUSER_HANDLE_TABLE ht, HANDLE* handle, USER_OBJECT_TYPE type )
{
@ -296,111 +277,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)
{
HANDLE hi;
PUSER_OBJECT_HEADER hdr = UserHeapAlloc(size + sizeof(USER_OBJECT_HEADER));//ExAllocatePool(PagedPool, size + sizeof(USER_OBJECT_HEADER));
if (!hdr)
return NULL;
hi = UserAllocHandle(ht, USER_HEADER_TO_BODY(hdr), type );
if (!hi)
{
//ExFreePool(hdr);
UserHeapFree(hdr);
return NULL;
}
RtlZeroMemory(hdr, size + sizeof(USER_OBJECT_HEADER));
hdr->hSelf = hi;
hdr->RefCount = 2; // we need this, because we create 2 refs: handle and pointer!
if (h)
*h = hi;
return USER_HEADER_TO_BODY(hdr);
}
BOOL FASTCALL
UserDeleteObject(HANDLE h, USER_OBJECT_TYPE type )
{
PUSER_OBJECT_HEADER hdr;
PVOID body = UserGetObject(gHandleTable, h, type);
if (!body)
return FALSE;
hdr = USER_BODY_TO_HEADER(body);
ASSERT(hdr->RefCount >= 1);
hdr->destroyed = TRUE;
return UserFreeHandle(gHandleTable, h);
}
VOID FASTCALL UserReferenceObject(PVOID obj)
{
PUSER_OBJECT_HEADER hdr = USER_BODY_TO_HEADER(obj);
ASSERT(hdr->RefCount >= 0);
hdr->RefCount++;
}
PVOID FASTCALL UserReferenceObjectByHandle(HANDLE handle, USER_OBJECT_TYPE type)
{
PVOID object;
object = UserGetObject(gHandleTable, handle, type);
if(object)
{
UserReferenceObject(object);
}
return object;
}
HANDLE FASTCALL UserObjectToHandle(PVOID obj)
{
PUSER_OBJECT_HEADER hdr = USER_BODY_TO_HEADER(obj);
return hdr->hSelf;
}
BOOL FASTCALL UserDereferenceObject(PVOID obj)
{
PUSER_OBJECT_HEADER hdr = USER_BODY_TO_HEADER(obj);
ASSERT(hdr->RefCount >= 1);
hdr->RefCount--;
// You can not have a zero here!
if (!hdr->destroyed && hdr->RefCount == 0)
{
hdr->RefCount++; // BOUNCE!!!!!
DPRINT1("warning! Dereference to zero without deleting! Obj -> 0x%x\n", obj);
}
if (hdr->RefCount == 0 && hdr->destroyed)
{
// DPRINT1("info: something destroyed bcaise of deref, in use=%i\n",gpsi->cHandleEntries);
memset(hdr, 0x55, sizeof(USER_OBJECT_HEADER));
return UserHeapFree(hdr);
//ExFreePool(hdr);
return TRUE;
}
return FALSE;
}
BOOL FASTCALL UserCreateHandleTable(VOID)
{
@ -434,24 +310,31 @@ BOOL FASTCALL UserCreateHandleTable(VOID)
//
PVOID
FASTCALL
NewUserCreateObject( PUSER_HANDLE_TABLE ht,
HANDLE* h,
USER_OBJECT_TYPE type,
ULONG size)
UserCreateObject( PUSER_HANDLE_TABLE ht,
PDESKTOP pDesktop,
HANDLE* h,
USER_OBJECT_TYPE type,
ULONG size)
{
HANDLE hi;
PVOID Object;
PTHREADINFO pti;
PPROCESSINFO ppi;
BOOL dt;
PDESKTOP rpdesk = pDesktop;
pti = GetW32ThreadInfo();
ppi = pti->ppi;
if (!pDesktop) rpdesk = pti->rpdesk;
switch (type)
{
case otWindow:
Object = DesktopHeapAlloc(pti->rpdesk, size);
// case otWindow:
// case otMenu:
// case otHook:
// case otCallProc:
case otInputContext:
Object = DesktopHeapAlloc(rpdesk, size);
dt = TRUE;
break;
@ -469,7 +352,7 @@ NewUserCreateObject( PUSER_HANDLE_TABLE ht,
if (!hi)
{
if (dt)
DesktopHeapFree(pti->rpdesk, Object);
DesktopHeapFree(rpdesk, Object);
else
UserHeapFree(Object);
return NULL;
@ -481,7 +364,8 @@ NewUserCreateObject( PUSER_HANDLE_TABLE ht,
{
case otWindow:
case otHook:
((PTHRDESKHEAD)Object)->rpdesk = pti->rpdesk;
case otInputContext:
((PTHRDESKHEAD)Object)->rpdesk = rpdesk;
((PTHRDESKHEAD)Object)->pSelf = Object;
case otEvent:
((PTHROBJHEAD)Object)->pti = pti;
@ -489,7 +373,7 @@ NewUserCreateObject( PUSER_HANDLE_TABLE ht,
case otMenu:
case otCallProc:
((PPROCDESKHEAD)Object)->rpdesk = pti->rpdesk;
((PPROCDESKHEAD)Object)->rpdesk = rpdesk;
((PPROCDESKHEAD)Object)->pSelf = Object;
break;
@ -509,9 +393,10 @@ NewUserCreateObject( PUSER_HANDLE_TABLE ht,
return Object;
}
BOOL
FASTCALL
NewUserDereferenceObject(PVOID obj)
UserDereferenceObject(PVOID obj)
{
ASSERT(((PHEAD)obj)->cLockObj >= 1);
@ -524,7 +409,7 @@ NewUserDereferenceObject(PVOID obj)
BOOL
FASTCALL
NewUserFreeHandle(PUSER_HANDLE_TABLE ht, HANDLE handle )
UserFreeHandle(PUSER_HANDLE_TABLE ht, HANDLE handle )
{
PUSER_HANDLE_ENTRY entry;
PVOID object;
@ -538,23 +423,30 @@ NewUserFreeHandle(PUSER_HANDLE_TABLE ht, HANDLE handle )
entry->flags = HANDLEENTRY_INDESTROY;
if (NewUserDereferenceObject(entry->ptr))
if (UserDereferenceObject(entry->ptr))
{
type = entry->type;
object = free_user_entry(ht, entry );
if (type == otWindow) // If more, go switch.
switch (type)
{
return DesktopHeapFree(GetW32ThreadInfo()->rpdesk, object);
// case otWindow:
// case otMenu:
// case otHook:
// case otCallProc:
case otInputContext:
return DesktopHeapFree(((PTHRDESKHEAD)object)->rpdesk, object);
default:
return UserHeapFree(object);
}
return UserHeapFree(object);
}
return FALSE;
}
BOOL
FASTCALL
NewUserDeleteObject(HANDLE h, USER_OBJECT_TYPE type )
UserDeleteObject(HANDLE h, USER_OBJECT_TYPE type )
{
PVOID body = UserGetObject(gHandleTable, h, type);
@ -562,12 +454,12 @@ NewUserDeleteObject(HANDLE h, USER_OBJECT_TYPE type )
ASSERT( ((PHEAD)body)->cLockObj >= 1);
return NewUserFreeHandle(gHandleTable, h);
return UserFreeHandle(gHandleTable, h);
}
VOID
FASTCALL
NewUserReferenceObject(PVOID obj)
UserReferenceObject(PVOID obj)
{
ASSERT(((PHEAD)obj)->cLockObj >= 0);
@ -576,14 +468,14 @@ NewUserReferenceObject(PVOID obj)
PVOID
FASTCALL
NewUserReferenceObjectByHandle(HANDLE handle, USER_OBJECT_TYPE type)
UserReferenceObjectByHandle(HANDLE handle, USER_OBJECT_TYPE type)
{
PVOID object;
object = UserGetObject(gHandleTable, handle, type);
if (object)
{
NewUserReferenceObject(object);
UserReferenceObject(object);
}
return object;
}

View file

@ -49,13 +49,13 @@ CreateTimer(VOID)
if (!FirstpTmr)
{
FirstpTmr = UserCreateObject(gHandleTable, &Handle, otTimer, sizeof(TIMER));
FirstpTmr = UserCreateObject(gHandleTable, NULL, &Handle, otTimer, sizeof(TIMER));
if (FirstpTmr) InitializeListHead(&FirstpTmr->ptmrList);
Ret = FirstpTmr;
}
else
{
Ret = UserCreateObject(gHandleTable, &Handle, otTimer, sizeof(TIMER));
Ret = UserCreateObject(gHandleTable, NULL, &Handle, otTimer, sizeof(TIMER));
if (Ret) InsertTailList(&FirstpTmr->ptmrList, &Ret->ptmrList);
}
return Ret;
@ -69,7 +69,7 @@ RemoveTimer(PTIMER pTmr)
if (pTmr)
{
RemoveEntryList(&pTmr->ptmrList);
UserDeleteObject( USER_BODY_TO_HEADER(pTmr)->hSelf, otTimer);
UserDeleteObject( UserHMGetHandle(pTmr), otTimer);
return TRUE;
}
return FALSE;

View file

@ -93,9 +93,9 @@ PWINDOW_OBJECT FASTCALL IntGetWindowObject(HWND hWnd)
Window = UserGetWindowObject(hWnd);
if (Window)
{
ASSERT(USER_BODY_TO_HEADER(Window)->RefCount >= 0);
ASSERT(Window->head.cLockObj >= 0);
USER_BODY_TO_HEADER(Window)->RefCount++;
Window->head.cLockObj++;
}
return Window;
}
@ -129,7 +129,7 @@ PWINDOW_OBJECT FASTCALL UserGetWindowObject(HWND hWnd)
return NULL;
}
ASSERT(USER_BODY_TO_HEADER(Window)->RefCount >= 0);
ASSERT(Window->head.cLockObj >= 0);
return Window;
}
@ -1806,6 +1806,7 @@ co_IntCreateWindowEx(DWORD dwExStyle,
/* Create the window object. */
Window = (PWINDOW_OBJECT) UserCreateObject( gHandleTable,
pti->rpdesk,
(PHANDLE)&hWnd,
otWindow,
sizeof(WINDOW_OBJECT));