Author: tkreuzer Date: Tue Mar 4 01:14:11 2008 New Revision: 32553
URL: http://svn.reactos.org/svn/reactos?rev=3D32553&view=3Drev Log: [FORMATTING] apply a consistent indentation (4 spaces), no code change
Modified: trunk/reactos/subsystems/win32/win32k/objects/gdiobj.c
Modified: trunk/reactos/subsystems/win32/win32k/objects/gdiobj.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win3= 2k/objects/gdiobj.c?rev=3D32553&r1=3D32552&r2=3D32553&view=3Ddiff =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D --- trunk/reactos/subsystems/win32/win32k/objects/gdiobj.c (original) +++ trunk/reactos/subsystems/win32/win32k/objects/gdiobj.c Tue Mar 4 01:14= :11 2008 @@ -54,7 +54,7 @@ static BOOL INTERNAL_CALL GDI_CleanupDummy(PVOID ObjectBody) { - return TRUE; + return TRUE; } =
typedef struct @@ -116,84 +116,89 @@ PGDI_HANDLE_TABLE INTERNAL_CALL GDIOBJ_iAllocHandleTable(OUT PSECTION_OBJECT *SectionObject) { - PGDI_HANDLE_TABLE HandleTable =3D NULL; - LARGE_INTEGER htSize; - UINT ObjType; - ULONG ViewSize =3D 0; - NTSTATUS Status; - - ASSERT(SectionObject !=3D NULL); - - htSize.QuadPart =3D sizeof(GDI_HANDLE_TABLE); - - Status =3D MmCreateSection((PVOID*)SectionObject, - SECTION_ALL_ACCESS, - NULL, - &htSize, - PAGE_READWRITE, - SEC_COMMIT, - NULL, - NULL); - if (!NT_SUCCESS(Status)) - return NULL; - - /* FIXME - use MmMapViewInSessionSpace once available! */ - Status =3D MmMapViewInSystemSpace(*SectionObject, - (PVOID*)&HandleTable, - &ViewSize); - if (!NT_SUCCESS(Status)) - { - ObDereferenceObject(*SectionObject); - *SectionObject =3D NULL; - return NULL; - } - - RtlZeroMemory(HandleTable, sizeof(GDI_HANDLE_TABLE)); - - HandleTable->LookasideLists =3D ExAllocatePoolWithTag(NonPagedPool, - BASE_OBJTYPE_COUNT *= sizeof(PAGED_LOOKASIDE_LIST), - TAG_GDIHNDTBLE); - if(HandleTable->LookasideLists =3D=3D NULL) - { - MmUnmapViewInSystemSpace(HandleTable); - ObDereferenceObject(*SectionObject); - *SectionObject =3D NULL; - return NULL; - } - - for(ObjType =3D 0; ObjType < BASE_OBJTYPE_COUNT; ObjType++) - { - if (ObjTypeInfo[ObjType].bUseLookaside) - { - ExInitializePagedLookasideList(HandleTable->LookasideLists + ObjType= , NULL, NULL, 0, - ObjTypeInfo[ObjType].ulBodySize, ObjT= ypeInfo[ObjType].Tag, 0); - } - } - - ShortDelay.QuadPart =3D -5000LL; /* FIXME - 0.5 ms? */ - - HandleTable->FirstFree =3D 0; - HandleTable->FirstUnused =3D RESERVE_ENTRIES_COUNT; - - return HandleTable; + PGDI_HANDLE_TABLE HandleTable =3D NULL; + LARGE_INTEGER htSize; + UINT ObjType; + ULONG ViewSize =3D 0; + NTSTATUS Status; + + ASSERT(SectionObject !=3D NULL); + + htSize.QuadPart =3D sizeof(GDI_HANDLE_TABLE); + + Status =3D MmCreateSection((PVOID*)SectionObject, + SECTION_ALL_ACCESS, + NULL, + &htSize, + PAGE_READWRITE, + SEC_COMMIT, + NULL, + NULL); + if (!NT_SUCCESS(Status)) + return NULL; + + /* FIXME - use MmMapViewInSessionSpace once available! */ + Status =3D MmMapViewInSystemSpace(*SectionObject, + (PVOID*)&HandleTable, + &ViewSize); + if (!NT_SUCCESS(Status)) + { + ObDereferenceObject(*SectionObject); + *SectionObject =3D NULL; + return NULL; + } + + RtlZeroMemory(HandleTable, sizeof(GDI_HANDLE_TABLE)); + + HandleTable->LookasideLists =3D ExAllocatePoolWithTag(NonPagedPool, + BASE_OBJTYPE_COUNT * sizeof(PAGED_LOOKAS= IDE_LIST), + TAG_GDIHNDTBLE); + if (HandleTable->LookasideLists =3D=3D NULL) + { + MmUnmapViewInSystemSpace(HandleTable); + ObDereferenceObject(*SectionObject); + *SectionObject =3D NULL; + return NULL; + } + + for (ObjType =3D 0; ObjType < BASE_OBJTYPE_COUNT; ObjType++) + { + if (ObjTypeInfo[ObjType].bUseLookaside) + { + ExInitializePagedLookasideList(HandleTable->LookasideLists + O= bjType, + NULL, + NULL, + 0, + ObjTypeInfo[ObjType].ulBodySize, + ObjTypeInfo[ObjType].Tag, + 0); + } + } + + ShortDelay.QuadPart =3D -5000LL; /* FIXME - 0.5 ms? */ + + HandleTable->FirstFree =3D 0; + HandleTable->FirstUnused =3D RESERVE_ENTRIES_COUNT; + + return HandleTable; } =
static __inline PPAGED_LOOKASIDE_LIST FindLookasideList(ULONG TypeIndex) { - return GdiHandleTable->LookasideLists + TypeIndex; + return GdiHandleTable->LookasideLists + TypeIndex; } =
static __inline BOOL RunCleanupCallback(PGDIOBJ pObj, ULONG TypeIndex) { - return ((GDICLEANUPPROC)ObjTypeInfo[TypeIndex].CleanupProc)(pObj); + return ((GDICLEANUPPROC)ObjTypeInfo[TypeIndex].CleanupProc)(pObj); } =
static __inline ULONG GetObjectSize(ULONG TypeIndex) { - return ObjTypeInfo[TypeIndex].ulBodySize; + return ObjTypeInfo[TypeIndex].ulBodySize; } =
#ifdef GDI_DEBUG @@ -204,88 +209,88 @@ static ULONG GDIHandleLocker[GDI_HANDLE_COUNT][GDI_STACK_LEVELS+1]; struct DbgOpenGDIHandle { - ULONG idx; - int count; + ULONG idx; + int count; }; #define H 1024 static struct DbgOpenGDIHandle h[H]; =
void IntDumpHandleTable(PGDI_HANDLE_TABLE HandleTable) { - int i, n =3D 0, j, k, J; - - if ( leak_reported ) - { - DPRINT1("gdi handle abusers already reported!\n"); - return; - } - - leak_reported =3D 1; - DPRINT1("reporting gdi handle abusers:\n"); - - /* step through GDI handle table and find out who our culprit is... */ - for ( i =3D RESERVE_ENTRIES_COUNT; i < GDI_HANDLE_COUNT; i++ ) - { - for ( j =3D 0; j < n; j++ ) - { + int i, n =3D 0, j, k, J; + + if (leak_reported) + { + DPRINT1("gdi handle abusers already reported!\n"); + return; + } + + leak_reported =3D 1; + DPRINT1("reporting gdi handle abusers:\n"); + + /* step through GDI handle table and find out who our culprit is... */ + for (i =3D RESERVE_ENTRIES_COUNT; i < GDI_HANDLE_COUNT; i++) + { + for (j =3D 0; j < n; j++) + { next: - J =3D h[j].idx; - for ( k =3D 0; k < GDI_STACK_LEVELS; k++ ) - { - if ( GDIHandleAllocator[i][k] - !=3D GDIHandleAllocator[J][k] ) - { - if ( ++j =3D=3D n ) - goto done; - else - goto next; - } - } - goto done; - } + J =3D h[j].idx; + for (k =3D 0; k < GDI_STACK_LEVELS; k++) + { + if (GDIHandleAllocator[i][k] + !=3D GDIHandleAllocator[J][k]) + { + if (++j =3D=3D n) + goto done; + else + goto next; + } + } + goto done; + } done: - if ( j < H ) - { - if ( j =3D=3D n ) - { - h[j].idx =3D i; - h[j].count =3D 1; - n =3D n + 1; - } - else - h[j].count++; - } - } - /* bubble sort time! weeeeee!! */ - for ( i =3D 0; i < n-1; i++ ) - { - if ( h[i].count < h[i+1].count ) - { - struct DbgOpenGDIHandle t; - t =3D h[i+1]; - h[i+1] =3D h[i]; - j =3D i; - while ( j > 0 && h[j-1].count < t.count ) - j--; - h[j] =3D t; - } - } - /* print the worst offenders... */ - DbgPrint ( "Worst GDI Handle leak offenders (out of %i unique locations):= \n", n ); - for ( i =3D 0; i < n && h[i].count > 1; i++ ) - { - int j; - DbgPrint ( " %i allocs: ", h[i].count ); - for ( j =3D 0; j < GDI_STACK_LEVELS; j++ ) - { - ULONG Addr =3D GDIHandleAllocator[h[i].idx][j]; - if ( !KiRosPrintAddress ( (PVOID)Addr ) ) - DbgPrint ( "<%X>", Addr ); - } - DbgPrint ( "\n" ); - } - if ( i < n && h[i].count =3D=3D 1 ) - DbgPrint ( "(list terminated - the remaining entries have 1 allocation o= nly)\n" ); + if (j < H) + { + if (j =3D=3D n) + { + h[j].idx =3D i; + h[j].count =3D 1; + n =3D n + 1; + } + else + h[j].count++; + } + } + /* bubble sort time! weeeeee!! */ + for (i =3D 0; i < n-1; i++) + { + if (h[i].count < h[i+1].count) + { + struct DbgOpenGDIHandle t; + t =3D h[i+1]; + h[i+1] =3D h[i]; + j =3D i; + while (j > 0 && h[j-1].count < t.count) + j--; + h[j] =3D t; + } + } + /* print the worst offenders... */ + DbgPrint("Worst GDI Handle leak offenders (out of %i unique locations)= :\n", n); + for (i =3D 0; i < n && h[i].count > 1; i++) + { + int j; + DbgPrint(" %i allocs: ", h[i].count); + for (j =3D 0; j < GDI_STACK_LEVELS; j++) + { + ULONG Addr =3D GDIHandleAllocator[h[i].idx][j]; + if (!KiRosPrintAddress((PVOID)Addr)) + DbgPrint("<%X>", Addr); + } + DbgPrint("\n"); + } + if (i < n && h[i].count =3D=3D 1) + DbgPrint("(list terminated - the remaining entries have 1 allocati= on only)\n"); } =
ULONG @@ -366,36 +371,36 @@ FASTCALL InterlockedPopFreeEntry() { - ULONG idxFirstFree, idxNextFree, idxPrev; - PGDI_TABLE_ENTRY pFreeEntry; - - DPRINT("Enter InterLockedPopFreeEntry\n"); - - do - { - idxFirstFree =3D GdiHandleTable->FirstFree; - if (idxFirstFree) - { - pFreeEntry =3D GdiHandleTable->Entries + idxFirstFree; - ASSERT(((ULONG)pFreeEntry->KernelData & ~GDI_HANDLE_INDEX_MASK) =3D=3D = 0); - idxNextFree =3D (ULONG)pFreeEntry->KernelData; - idxPrev =3D (ULONG)_InterlockedCompareExchange((LONG*)&GdiHandleTable->= FirstFree, idxNextFree, idxFirstFree); - } - else - { - idxFirstFree =3D GdiHandleTable->FirstUnused; - idxNextFree =3D idxFirstFree + 1; - if (idxNextFree >=3D GDI_HANDLE_COUNT) - { - DPRINT1("No more gdi handles left!\n"); - return 0; - } - idxPrev =3D (ULONG)_InterlockedCompareExchange((LONG*)&GdiHandleTable->= FirstUnused, idxNextFree, idxFirstFree); - } - } - while (idxPrev !=3D idxFirstFree); - - return idxFirstFree; + ULONG idxFirstFree, idxNextFree, idxPrev; + PGDI_TABLE_ENTRY pFreeEntry; + + DPRINT("Enter InterLockedPopFreeEntry\n"); + + do + { + idxFirstFree =3D GdiHandleTable->FirstFree; + if (idxFirstFree) + { + pFreeEntry =3D GdiHandleTable->Entries + idxFirstFree; + ASSERT(((ULONG)pFreeEntry->KernelData & ~GDI_HANDLE_INDEX_MASK= ) =3D=3D 0); + idxNextFree =3D (ULONG)pFreeEntry->KernelData; + idxPrev =3D (ULONG)_InterlockedCompareExchange((LONG*)&GdiHand= leTable->FirstFree, idxNextFree, idxFirstFree); + } + else + { + idxFirstFree =3D GdiHandleTable->FirstUnused; + idxNextFree =3D idxFirstFree + 1; + if (idxNextFree >=3D GDI_HANDLE_COUNT) + { + DPRINT1("No more gdi handles left!\n"); + return 0; + } + idxPrev =3D (ULONG)_InterlockedCompareExchange((LONG*)&GdiHand= leTable->FirstUnused, idxNextFree, idxFirstFree); + } + } + while (idxPrev !=3D idxFirstFree); + + return idxFirstFree; } =
/* Pushes an entry of the handle table to the free list, @@ -404,24 +409,24 @@ FASTCALL InterlockedPushFreeEntry(ULONG idxToFree) { - ULONG idxFirstFree, idxPrev; - PGDI_TABLE_ENTRY pFreeEntry; - - DPRINT("Enter InterlockedPushFreeEntry\n"); - - pFreeEntry =3D GdiHandleTable->Entries + idxToFree; - ASSERT((pFreeEntry->Type & GDI_ENTRY_BASETYPE_MASK) =3D=3D 0); - ASSERT(pFreeEntry->ProcessId =3D=3D 0); - pFreeEntry->UserData =3D NULL; - - do - { - idxFirstFree =3D GdiHandleTable->FirstFree; - pFreeEntry->KernelData =3D (PVOID)idxFirstFree; - - idxPrev =3D (ULONG)_InterlockedCompareExchange((LONG*)&GdiHandleTable->F= irstFree, idxToFree, idxFirstFree); - } - while (idxPrev !=3D idxFirstFree); + ULONG idxFirstFree, idxPrev; + PGDI_TABLE_ENTRY pFreeEntry; + + DPRINT("Enter InterlockedPushFreeEntry\n"); + + pFreeEntry =3D GdiHandleTable->Entries + idxToFree; + ASSERT((pFreeEntry->Type & GDI_ENTRY_BASETYPE_MASK) =3D=3D 0); + ASSERT(pFreeEntry->ProcessId =3D=3D 0); + pFreeEntry->UserData =3D NULL; + + do + { + idxFirstFree =3D GdiHandleTable->FirstFree; + pFreeEntry->KernelData =3D (PVOID)idxFirstFree; + + idxPrev =3D (ULONG)_InterlockedCompareExchange((LONG*)&GdiHandleTa= ble->FirstFree, idxToFree, idxFirstFree); + } + while (idxPrev !=3D idxFirstFree); } =
=
@@ -429,17 +434,17 @@ INTERNAL_CALL GDIOBJ_ValidateHandle(HGDIOBJ hObj, ULONG ObjectType) { - PGDI_TABLE_ENTRY Entry =3D GDI_HANDLE_GET_ENTRY(GdiHandleTable, hObj); - if((((ULONG_PTR)hObj & GDI_HANDLE_TYPE_MASK) =3D=3D ObjectType) && - (Entry->Type << GDI_ENTRY_UPPER_SHIFT) =3D=3D GDI_HANDLE_GET_UPPER(hO= bj)) - { - HANDLE pid =3D (HANDLE)((ULONG_PTR)Entry->ProcessId & ~0x1); - if(pid =3D=3D NULL || pid =3D=3D PsGetCurrentProcessId()) - { - return TRUE; - } - } - return FALSE; + PGDI_TABLE_ENTRY Entry =3D GDI_HANDLE_GET_ENTRY(GdiHandleTable, hObj); + if ((((ULONG_PTR)hObj & GDI_HANDLE_TYPE_MASK) =3D=3D ObjectType) && + (Entry->Type << GDI_ENTRY_UPPER_SHIFT) =3D=3D GDI_HANDLE_GET_UPPER= (hObj)) + { + HANDLE pid =3D (HANDLE)((ULONG_PTR)Entry->ProcessId & ~0x1); + if (pid =3D=3D NULL || pid =3D=3D PsGetCurrentProcessId()) + { + return TRUE; + } + } + return FALSE; } =
/*! @@ -455,123 +460,123 @@ HGDIOBJ INTERNAL_CALL GDIOBJ_AllocObj(ULONG ObjectType) { - PW32PROCESS W32Process; - POBJ newObject =3D NULL; - PPAGED_LOOKASIDE_LIST LookasideList =3D NULL; - HANDLE CurrentProcessId, LockedProcessId; - ULONG TypeIndex; + PW32PROCESS W32Process; + POBJ newObject =3D NULL; + PPAGED_LOOKASIDE_LIST LookasideList =3D NULL; + HANDLE CurrentProcessId, LockedProcessId; + ULONG TypeIndex; #ifdef GDI_DEBUG - ULONG Attempts =3D 0; + ULONG Attempts =3D 0; #endif =
- W32Process =3D PsGetCurrentProcessWin32Process(); - /* HACK HACK HACK: simplest-possible quota implementation - don't allow = a process - to take too many GDI objects, itself. */ - if ( W32Process && W32Process->GDIObjects >=3D 0x2710 ) + W32Process =3D PsGetCurrentProcessWin32Process(); + /* HACK HACK HACK: simplest-possible quota implementation - don't allo= w a process + to take too many GDI objects, itself. */ + if (W32Process && W32Process->GDIObjects >=3D 0x2710) + return NULL; + + ASSERT(ObjectType !=3D GDI_OBJECT_TYPE_DONTCARE); + + TypeIndex =3D GDI_OBJECT_GET_TYPE_INDEX(ObjectType); + if (ObjTypeInfo[TypeIndex].bUseLookaside) + { + LookasideList =3D FindLookasideList(TypeIndex); + if (LookasideList !=3D NULL) + { + newObject =3D ExAllocateFromPagedLookasideList(LookasideList); + } + } + else + { + newObject =3D ExAllocatePoolWithTag(PagedPool, + ObjTypeInfo[TypeIndex].ulBodySiz= e, + ObjTypeInfo[TypeIndex].Tag); + } + if (newObject !=3D NULL) + { + UINT Index; + PGDI_TABLE_ENTRY Entry; + LONG TypeInfo; + + CurrentProcessId =3D PsGetCurrentProcessId(); + LockedProcessId =3D (HANDLE)((ULONG_PTR)CurrentProcessId | 0x1); + + RtlZeroMemory(newObject, GetObjectSize(TypeIndex)); + + /* On Windows the higher 16 bit of the type field don't contain the + full type from the handle, but the base type. + (type =3D BRSUH, PEN, EXTPEN, basetype =3D BRUSH) */ + TypeInfo =3D (ObjectType & GDI_HANDLE_BASETYPE_MASK) | (ObjectType=
GDI_ENTRY_UPPER_SHIFT);
+ + Index =3D InterlockedPopFreeEntry(); + if (Index !=3D 0) + { + HANDLE PrevProcId; + + Entry =3D &GdiHandleTable->Entries[Index]; + +LockHandle: + PrevProcId =3D _InterlockedCompareExchangePointer((PVOID*)&Ent= ry->ProcessId, LockedProcessId, 0); + if (PrevProcId =3D=3D NULL) + { + HGDIOBJ Handle; + + Entry->KernelData =3D newObject; + + /* copy the reuse-counter */ + TypeInfo |=3D Entry->Type & GDI_ENTRY_REUSE_MASK; + + /* we found a free entry, no need to exchange this field a= tomically + since we're holding the lock */ + Entry->Type =3D TypeInfo; + + /* unlock the entry */ + (void)_InterlockedExchangePointer((PVOID*)&Entry->ProcessI= d, CurrentProcessId); + + GDIDBG_CAPTUREALLOCATOR(Index); + + if (W32Process !=3D NULL) + { + _InterlockedIncrement(&W32Process->GDIObjects); + } + Handle =3D (HGDIOBJ)((Index & 0xFFFF) | (TypeInfo << GDI_E= NTRY_UPPER_SHIFT)); + + DPRINT("GDIOBJ_AllocObj: 0x%x ob: 0x%x\n", Handle, newObje= ct); + return Handle; + } + else + { +#ifdef GDI_DEBUG + if (++Attempts > 20) + { + DPRINT1("[%d]Waiting on handle in index 0x%x\n", Attem= pts, Index); + } +#endif + /* damn, someone is trying to lock the object even though = it doesn't + eve nexist anymore, wait a little and try again! + FIXME - we shouldn't loop forever! Give up after some t= ime! */ + DelayExecution(); + /* try again */ + goto LockHandle; + } + } + + if (ObjTypeInfo[TypeIndex].bUseLookaside) + { + ExFreeToPagedLookasideList(LookasideList, newObject); + } + else + { + ExFreePool(newObject); + } + DPRINT1("Failed to insert gdi object into the handle table, no han= dles left!\n"); + GDIDBG_DUMPHANDLETABLE(); + } + else + { + DPRINT1("Not enough memory to allocate gdi object!\n"); + } return NULL; - - ASSERT(ObjectType !=3D GDI_OBJECT_TYPE_DONTCARE); - - TypeIndex =3D GDI_OBJECT_GET_TYPE_INDEX(ObjectType); - if (ObjTypeInfo[TypeIndex].bUseLookaside) - { - LookasideList =3D FindLookasideList(TypeIndex); - if(LookasideList !=3D NULL) - { - newObject =3D ExAllocateFromPagedLookasideList(LookasideList); - } - } - else - { - newObject =3D ExAllocatePoolWithTag(PagedPool, - ObjTypeInfo[TypeIndex].ulBodySize, - ObjTypeInfo[TypeIndex].Tag); - } - if(newObject !=3D NULL) - { - UINT Index; - PGDI_TABLE_ENTRY Entry; - LONG TypeInfo; - - CurrentProcessId =3D PsGetCurrentProcessId(); - LockedProcessId =3D (HANDLE)((ULONG_PTR)CurrentProcessId | 0x1); - - RtlZeroMemory(newObject, GetObjectSize(TypeIndex)); - - /* On Windows the higher 16 bit of the type field don't contain the - full type from the handle, but the base type. - (type =3D BRSUH, PEN, EXTPEN, basetype =3D BRUSH) */ - TypeInfo =3D (ObjectType & GDI_HANDLE_BASETYPE_MASK) | (ObjectType >> = GDI_ENTRY_UPPER_SHIFT); - - Index =3D InterlockedPopFreeEntry(); - if (Index !=3D 0) - { - HANDLE PrevProcId; - - Entry =3D &GdiHandleTable->Entries[Index]; - -LockHandle: - PrevProcId =3D _InterlockedCompareExchangePointer((PVOID*)&Entry->Pr= ocessId, LockedProcessId, 0); - if(PrevProcId =3D=3D NULL) - { - HGDIOBJ Handle; - - Entry->KernelData =3D newObject; - - /* copy the reuse-counter */ - TypeInfo |=3D Entry->Type & GDI_ENTRY_REUSE_MASK; - - /* we found a free entry, no need to exchange this field atomically - since we're holding the lock */ - Entry->Type =3D TypeInfo; - - /* unlock the entry */ - (void)_InterlockedExchangePointer((PVOID*)&Entry->ProcessId, Curre= ntProcessId); - - GDIDBG_CAPTUREALLOCATOR(Index); - - if(W32Process !=3D NULL) - { - _InterlockedIncrement(&W32Process->GDIObjects); - } - Handle =3D (HGDIOBJ)((Index & 0xFFFF) | (TypeInfo << GDI_ENTRY_UPP= ER_SHIFT)); - - DPRINT("GDIOBJ_AllocObj: 0x%x ob: 0x%x\n", Handle, newObject); - return Handle; - } - else - { -#ifdef GDI_DEBUG - if(++Attempts > 20) - { - DPRINT1("[%d]Waiting on handle in index 0x%x\n", Attempts, Index= ); - } -#endif - /* damn, someone is trying to lock the object even though it doe= sn't - eve nexist anymore, wait a little and try again! - FIXME - we shouldn't loop forever! Give up after some time! */ - DelayExecution(); - /* try again */ - goto LockHandle; - } - } - - if (ObjTypeInfo[TypeIndex].bUseLookaside) - { - ExFreeToPagedLookasideList(LookasideList, newObject); - } - else - { - ExFreePool(newObject); - } - DPRINT1("Failed to insert gdi object into the handle table, no handles= left!\n"); - GDIDBG_DUMPHANDLETABLE(); - } - else - { - DPRINT1("Not enough memory to allocate gdi object!\n"); - } - return NULL; } =
/*! @@ -587,164 +592,164 @@ BOOL INTERNAL_CALL GDIOBJ_FreeObj(HGDIOBJ hObj, DWORD ExpectedType) { - PGDI_TABLE_ENTRY Entry; - PPAGED_LOOKASIDE_LIST LookasideList; - HANDLE ProcessId, LockedProcessId, PrevProcId; - ULONG HandleType, HandleUpper, TypeIndex; - BOOL Silent; + PGDI_TABLE_ENTRY Entry; + PPAGED_LOOKASIDE_LIST LookasideList; + HANDLE ProcessId, LockedProcessId, PrevProcId; + ULONG HandleType, HandleUpper, TypeIndex; + BOOL Silent; #ifdef GDI_DEBUG - ULONG Attempts =3D 0; + ULONG Attempts =3D 0; #endif =
- DPRINT("GDIOBJ_FreeObj: hObj: 0x%08x\n", hObj); - - if(GDI_HANDLE_IS_STOCKOBJ(hObj)) - { - DPRINT1("GDIOBJ_FreeObj() failed, can't delete stock object handle: 0x= %x !!!\n", hObj); - GDIDBG_TRACECALLER(); + DPRINT("GDIOBJ_FreeObj: hObj: 0x%08x\n", hObj); + + if (GDI_HANDLE_IS_STOCKOBJ(hObj)) + { + DPRINT1("GDIOBJ_FreeObj() failed, can't delete stock object handle= : 0x%x !!!\n", hObj); + GDIDBG_TRACECALLER(); + return FALSE; + } + + ProcessId =3D PsGetCurrentProcessId(); + LockedProcessId =3D (HANDLE)((ULONG_PTR)ProcessId | 0x1); + + Silent =3D (ExpectedType & GDI_OBJECT_TYPE_SILENT); + ExpectedType &=3D ~GDI_OBJECT_TYPE_SILENT; + + HandleType =3D GDI_HANDLE_GET_TYPE(hObj); + HandleUpper =3D GDI_HANDLE_GET_UPPER(hObj); + + /* Check if we have the requested type */ + if ( (ExpectedType !=3D GDI_OBJECT_TYPE_DONTCARE && + HandleType !=3D ExpectedType) || + HandleType =3D=3D 0 ) + { + DPRINT1("Attempted to free object 0x%x of wrong type (Handle: 0x%x= , expected: 0x%x)\n", + hObj, HandleType, ExpectedType); + GDIDBG_TRACECALLER(); + return FALSE; + } + + Entry =3D GDI_HANDLE_GET_ENTRY(GdiHandleTable, hObj); + +LockHandle: + /* lock the object, we must not delete global objects, so don't exchan= ge the locking + process ID to zero when attempting to lock a global object... */ + PrevProcId =3D _InterlockedCompareExchangePointer((PVOID*)&Entry->Proc= essId, LockedProcessId, ProcessId); + if (PrevProcId =3D=3D ProcessId) + { + if ( (Entry->KernelData !=3D NULL) && + ((Entry->Type << GDI_ENTRY_UPPER_SHIFT) =3D=3D HandleUpper) && + ((Entry->Type & GDI_ENTRY_BASETYPE_MASK) =3D=3D (HandleUpper = & GDI_ENTRY_BASETYPE_MASK)) ) + { + POBJ Object; + + Object =3D Entry->KernelData; + + if (Object->cExclusiveLock =3D=3D 0) + { + BOOL Ret; + PW32PROCESS W32Process =3D PsGetCurrentProcessWin32Process= (); + + /* Clear the basetype field so when unlocking the handle i= t gets finally deleted and increment reuse counter */ + Entry->Type =3D (Entry->Type + GDI_ENTRY_REUSE_INC) & ~GDI= _ENTRY_BASETYPE_MASK; + + /* unlock the handle slot */ + (void)_InterlockedExchangePointer((PVOID*)&Entry->ProcessI= d, NULL); + + /* push this entry to the free list */ + InterlockedPushFreeEntry(GDI_ENTRY_TO_INDEX(GdiHandleTable= , Entry)); + + if (W32Process !=3D NULL) + { + _InterlockedDecrement(&W32Process->GDIObjects); + } + + /* call the cleanup routine. */ + TypeIndex =3D GDI_OBJECT_GET_TYPE_INDEX(HandleType); + Ret =3D RunCleanupCallback(Object, TypeIndex); + + /* Now it's time to free the memory */ + if (ObjTypeInfo[TypeIndex].bUseLookaside) + { + LookasideList =3D FindLookasideList(TypeIndex); + if (LookasideList !=3D NULL) + { + ExFreeToPagedLookasideList(LookasideList, Object); + } + } + else + { + ExFreePool(Object); + } + + return Ret; + } + else + { + /* + * The object is currently locked, so freeing is forbidden! + */ + DPRINT1("Object->cExclusiveLock =3D %d\n", Object->cExclus= iveLock); + GDIDBG_TRACELOCKER(GDI_HANDLE_GET_INDEX(hObj)); + ASSERT(FALSE); + } + } + else + { + LockErrorDebugOutput(hObj, Entry, "GDIOBJ_FreeObj"); + (void)_InterlockedExchangePointer((PVOID*)&Entry->ProcessId, P= revProcId); + } + } + else if (PrevProcId =3D=3D LockedProcessId) + { +#ifdef GDI_DEBUG + if (++Attempts > 20) + { + DPRINT1("[%d]Waiting on 0x%x\n", Attempts, hObj); + } +#endif + /* the object is currently locked, wait some time and try again. + FIXME - we shouldn't loop forever! Give up after some time! */ + DelayExecution(); + /* try again */ + goto LockHandle; + } + else + { + if (!Silent) + { + if (((ULONG_PTR)PrevProcId & ~0x1) =3D=3D 0) + { + DPRINT1("Attempted to free global gdi handle 0x%x, caller = needs to get ownership first!!!\n", hObj); + DPRINT1("Type =3D 0x%lx, KernelData =3D 0x%p, ProcessId = =3D 0x%p\n", Entry->Type, Entry->KernelData, Entry->ProcessId); + } + else + { + DPRINT1("Attempted to free foreign handle: 0x%x Owner: 0x%= x from Caller: 0x%x\n", hObj, (ULONG_PTR)PrevProcId & ~0x1, (ULONG_PTR)Proc= essId & ~0x1); + } + GDIDBG_TRACECALLER(); + GDIDBG_TRACEALLOCATOR(GDI_HANDLE_GET_INDEX(hObj)); + } + } + return FALSE; - } - - ProcessId =3D PsGetCurrentProcessId(); - LockedProcessId =3D (HANDLE)((ULONG_PTR)ProcessId | 0x1); - - Silent =3D (ExpectedType & GDI_OBJECT_TYPE_SILENT); - ExpectedType &=3D ~GDI_OBJECT_TYPE_SILENT; - - HandleType =3D GDI_HANDLE_GET_TYPE(hObj); - HandleUpper =3D GDI_HANDLE_GET_UPPER(hObj); - - /* Check if we have the requested type */ - if ( (ExpectedType !=3D GDI_OBJECT_TYPE_DONTCARE && - HandleType !=3D ExpectedType) || - HandleType =3D=3D 0 ) - { - DPRINT1("Attempted to free object 0x%x of wrong type (Handle: 0x%x, ex= pected: 0x%x)\n", - hObj, HandleType, ExpectedType); - GDIDBG_TRACECALLER(); - return FALSE; - } - - Entry =3D GDI_HANDLE_GET_ENTRY(GdiHandleTable, hObj); - -LockHandle: - /* lock the object, we must not delete global objects, so don't exchange= the locking - process ID to zero when attempting to lock a global object... */ - PrevProcId =3D _InterlockedCompareExchangePointer((PVOID*)&Entry->Proces= sId, LockedProcessId, ProcessId); - if(PrevProcId =3D=3D ProcessId) - { - if( (Entry->KernelData !=3D NULL) && - ((Entry->Type << GDI_ENTRY_UPPER_SHIFT) =3D=3D HandleUpper) && - ((Entry->Type & GDI_ENTRY_BASETYPE_MASK) =3D=3D (HandleUpper & GDI= _ENTRY_BASETYPE_MASK)) ) - { - POBJ Object; - - Object =3D Entry->KernelData; - - if(Object->cExclusiveLock =3D=3D 0) - { - BOOL Ret; - PW32PROCESS W32Process =3D PsGetCurrentProcessWin32Process(); - - /* Clear the basetype field so when unlocking the handle it gets f= inally deleted and increment reuse counter */ - Entry->Type =3D (Entry->Type + GDI_ENTRY_REUSE_INC) & ~GDI_ENTRY_B= ASETYPE_MASK; - - /* unlock the handle slot */ - (void)_InterlockedExchangePointer((PVOID*)&Entry->ProcessId, NULL); - - /* push this entry to the free list */ - InterlockedPushFreeEntry(GDI_ENTRY_TO_INDEX(GdiHandleTable, Entry)= ); - - if(W32Process !=3D NULL) - { - _InterlockedDecrement(&W32Process->GDIObjects); - } - - /* call the cleanup routine. */ - TypeIndex =3D GDI_OBJECT_GET_TYPE_INDEX(HandleType); - Ret =3D RunCleanupCallback(Object, TypeIndex); - - /* Now it's time to free the memory */ - if (ObjTypeInfo[TypeIndex].bUseLookaside) - { - LookasideList =3D FindLookasideList(TypeIndex); - if(LookasideList !=3D NULL) - { - ExFreeToPagedLookasideList(LookasideList, Object); - } - } - else - { - ExFreePool(Object); - } - - return Ret; - } - else - { - /* - * The object is currently locked, so freeing is forbidden! - */ - DPRINT1("Object->cExclusiveLock =3D %d\n", Object->cExclusiveLock); - GDIDBG_TRACELOCKER(GDI_HANDLE_GET_INDEX(hObj)); - ASSERT(FALSE); - } - } - else - { - LockErrorDebugOutput(hObj, Entry, "GDIOBJ_FreeObj"); - (void)_InterlockedExchangePointer((PVOID*)&Entry->ProcessId, PrevPro= cId); - } - } - else if(PrevProcId =3D=3D LockedProcessId) - { -#ifdef GDI_DEBUG - if(++Attempts > 20) - { - DPRINT1("[%d]Waiting on 0x%x\n", Attempts, hObj); - } -#endif - /* the object is currently locked, wait some time and try again. - FIXME - we shouldn't loop forever! Give up after some time! */ - DelayExecution(); - /* try again */ - goto LockHandle; - } - else - { - if(!Silent) - { - if(((ULONG_PTR)PrevProcId & ~0x1) =3D=3D 0) - { - DPRINT1("Attempted to free global gdi handle 0x%x, caller needs to= get ownership first!!!\n", hObj); - DPRINT1("Type =3D 0x%lx, KernelData =3D 0x%p, ProcessId =3D 0x%p\n= ", Entry->Type, Entry->KernelData, Entry->ProcessId); - } - else - { - DPRINT1("Attempted to free foreign handle: 0x%x Owner: 0x%x from C= aller: 0x%x\n", hObj, (ULONG_PTR)PrevProcId & ~0x1, (ULONG_PTR)ProcessId & = ~0x1); - } - GDIDBG_TRACECALLER(); - GDIDBG_TRACEALLOCATOR(GDI_HANDLE_GET_INDEX(hObj)); - } - } - - return FALSE; } =
BOOL FASTCALL IsObjectDead(HGDIOBJ hObject) { - INT Index =3D GDI_HANDLE_GET_INDEX(hObject); - PGDI_TABLE_ENTRY Entry =3D &GdiHandleTable->Entries[Index]; - // We check to see if the objects are knocking on deaths door. - if ((Entry->Type & ~GDI_ENTRY_REUSE_MASK) !=3D 0 && Entry->KernelData != =3D NULL) - return FALSE; - else - { - DPRINT1("Object 0x%x currently being destroyed!!!\n",hObject); - return TRUE; // return true and move on. - } + INT Index =3D GDI_HANDLE_GET_INDEX(hObject); + PGDI_TABLE_ENTRY Entry =3D &GdiHandleTable->Entries[Index]; + // We check to see if the objects are knocking on deaths door. + if ((Entry->Type & ~GDI_ENTRY_REUSE_MASK) !=3D 0 && Entry->KernelData = !=3D NULL) + return FALSE; + else + { + DPRINT1("Object 0x%x currently being destroyed!!!\n",hObject); + return TRUE; // return true and move on. + } } =
=
@@ -757,17 +762,17 @@ FASTCALL NtGdiDeleteObject(HGDIOBJ hObject) { - DPRINT("NtGdiDeleteObject handle 0x%08x\n", hObject); - if(!IsObjectDead(hObject)) - { - return NULL !=3D hObject - ? GDIOBJ_FreeObj(hObject, GDI_OBJECT_TYPE_DONTCARE) : FALSE; - } - else - { - DPRINT1("Attempt DeleteObject 0x%x currently being destroyed!!!\n",hO= bject); - return TRUE; // return true and move on. - } + DPRINT("NtGdiDeleteObject handle 0x%08x\n", hObject); + if (!IsObjectDead(hObject)) + { + return NULL !=3D hObject + ? GDIOBJ_FreeObj(hObject, GDI_OBJECT_TYPE_DONTCARE) : FALSE; + } + else + { + DPRINT1("Attempt DeleteObject 0x%x currently being destroyed!!!\n"= ,hObject); + return TRUE; // return true and move on. + } } =
/*! @@ -775,63 +780,64 @@ * \param Process - PID of the process that will be destroyed. */ BOOL INTERNAL_CALL -GDI_CleanupForProcess (struct _EPROCESS *Process) -{ - PGDI_TABLE_ENTRY Entry, End; - PEPROCESS CurrentProcess; - PW32PROCESS W32Process; - HANDLE ProcId; - ULONG Index =3D RESERVE_ENTRIES_COUNT; - - DPRINT("Starting CleanupForProcess prochandle %x Pid %d\n", Process, Pro= cess->UniqueProcessId); - CurrentProcess =3D PsGetCurrentProcess(); - if (CurrentProcess !=3D Process) - { - KeAttachProcess(&Process->Pcb); - } - W32Process =3D (PW32PROCESS)Process->Win32Process; - ASSERT(W32Process); - - if(W32Process->GDIObjects > 0) - { - /* FIXME - Instead of building the handle here and delete it using GDI= OBJ_FreeObj - we should delete it directly here! */ - ProcId =3D Process->UniqueProcessId; - - End =3D &GdiHandleTable->Entries[GDI_HANDLE_COUNT]; - for(Entry =3D &GdiHandleTable->Entries[RESERVE_ENTRIES_COUNT]; - Entry !=3D End; - Entry++, Index++) - { - /* ignore the lock bit */ - if((HANDLE)((ULONG_PTR)Entry->ProcessId & ~0x1) =3D=3D ProcId && (En= try->Type & ~GDI_ENTRY_REUSE_MASK) !=3D 0) - { - HGDIOBJ ObjectHandle; - - /* Create the object handle for the entry, the lower(!) 16 bit of = the - Type field includes the type of the object including the stock - object flag - but since stock objects don't have a process id w= e can - simply ignore this fact here. */ - ObjectHandle =3D (HGDIOBJ)(Index | (Entry->Type << GDI_ENTRY_UPPER= _SHIFT)); - - if(GDIOBJ_FreeObj(ObjectHandle, GDI_OBJECT_TYPE_DONTCARE) && - W32Process->GDIObjects =3D=3D 0) - { - /* there are no more gdi handles for this process, bail */ - break; - } - } - } - } - - if (CurrentProcess !=3D Process) - { - KeDetachProcess(); - } - - DPRINT("Completed cleanup for process %d\n", Process->UniqueProcessId); - - return TRUE; +GDI_CleanupForProcess(struct _EPROCESS *Process) +{ + PGDI_TABLE_ENTRY Entry, End; + PEPROCESS CurrentProcess; + PW32PROCESS W32Process; + HANDLE ProcId; + ULONG Index =3D RESERVE_ENTRIES_COUNT; + + DPRINT("Starting CleanupForProcess prochandle %x Pid %d\n", Process, P= rocess->UniqueProcessId); + CurrentProcess =3D PsGetCurrentProcess(); + if (CurrentProcess !=3D Process) + { + KeAttachProcess(&Process->Pcb); + } + W32Process =3D (PW32PROCESS)Process->Win32Process; + ASSERT(W32Process); + + if (W32Process->GDIObjects > 0) + { + /* FIXME - Instead of building the handle here and delete it using= GDIOBJ_FreeObj + we should delete it directly here! */ + ProcId =3D Process->UniqueProcessId; + + End =3D &GdiHandleTable->Entries[GDI_HANDLE_COUNT]; + for (Entry =3D &GdiHandleTable->Entries[RESERVE_ENTRIES_COUNT]; + Entry !=3D End; + Entry++, Index++) + { + /* ignore the lock bit */ + if ( (HANDLE)((ULONG_PTR)Entry->ProcessId & ~0x1) =3D=3D ProcI= d && + (Entry->Type & ~GDI_ENTRY_REUSE_MASK) !=3D 0 ) + { + HGDIOBJ ObjectHandle; + + /* Create the object handle for the entry, the lower(!) 16= bit of the + Type field includes the type of the object including th= e stock + object flag - but since stock objects don't have a proc= ess id we can + simply ignore this fact here. */ + ObjectHandle =3D (HGDIOBJ)(Index | (Entry->Type << GDI_ENT= RY_UPPER_SHIFT)); + + if (GDIOBJ_FreeObj(ObjectHandle, GDI_OBJECT_TYPE_DONTCARE)= && + W32Process->GDIObjects =3D=3D 0) + { + /* there are no more gdi handles for this process, bai= l */ + break; + } + } + } + } + + if (CurrentProcess !=3D Process) + { + KeDetachProcess(); + } + + DPRINT("Completed cleanup for process %d\n", Process->UniqueProcessId); + + return TRUE; } =
/*! @@ -845,129 +851,129 @@ * \todo Get rid of the ExpectedType parameter! */ PGDIOBJ INTERNAL_CALL -GDIOBJ_LockObj (HGDIOBJ hObj, DWORD ExpectedType) -{ - ULONG HandleIndex; - PGDI_TABLE_ENTRY Entry; - HANDLE ProcessId, HandleProcessId, LockedProcessId, PrevProcId; - POBJ Object =3D NULL; - ULONG HandleType, HandleUpper; - - HandleIndex =3D GDI_HANDLE_GET_INDEX(hObj); - HandleType =3D GDI_HANDLE_GET_TYPE(hObj); - HandleUpper =3D GDI_HANDLE_GET_UPPER(hObj); - - /* Check that the handle index is valid. */ - if (HandleIndex >=3D GDI_HANDLE_COUNT) - return NULL; - - Entry =3D &GdiHandleTable->Entries[HandleIndex]; - - /* Check if we have the requested type */ - if ( (ExpectedType !=3D GDI_OBJECT_TYPE_DONTCARE && - HandleType !=3D ExpectedType) || - HandleType =3D=3D 0 ) - { - DPRINT1("Attempted to lock object 0x%x of wrong type (Handle: 0x%x, = requested: 0x%x)\n", - hObj, HandleType, ExpectedType); - GDIDBG_TRACECALLER(); - GDIDBG_TRACEALLOCATOR(GDI_HANDLE_GET_INDEX(hObj)); - return NULL; - } - - ProcessId =3D (HANDLE)((ULONG_PTR)PsGetCurrentProcessId() & ~1); - HandleProcessId =3D (HANDLE)((ULONG_PTR)Entry->ProcessId & ~1); - - /* Check for invalid owner. */ - if (ProcessId !=3D HandleProcessId && HandleProcessId !=3D NULL) - { - DPRINT1("Tried to lock object (0x%p) of wrong owner! ProcessId =3D %= p, HandleProcessId =3D %p\n", hObj, ProcessId, HandleProcessId); - GDIDBG_TRACECALLER(); - GDIDBG_TRACEALLOCATOR(GDI_HANDLE_GET_INDEX(hObj)); - return NULL; - } - - /* - * Prevent the thread from being terminated during the locking process. - * It would result in undesired effects and inconsistency of the global - * handle table. - */ - - KeEnterCriticalRegion(); - - /* - * Loop until we either successfully lock the handle entry & object or - * fail some of the check. - */ - - for (;;) - { - /* Lock the handle table entry. */ - LockedProcessId =3D (HANDLE)((ULONG_PTR)HandleProcessId | 0x1); - PrevProcId =3D _InterlockedCompareExchangePointer((PVOID*)&Entry->Pr= ocessId, - LockedProcessId, - HandleProcessId); - - if (PrevProcId =3D=3D HandleProcessId) - { - /* - * We're locking an object that belongs to our process or it's a - * global object if HandleProcessId is 0 here. - */ - - if ( (Entry->KernelData !=3D NULL) && - ((Entry->Type << GDI_ENTRY_UPPER_SHIFT) =3D=3D HandleUpper) ) - { - PW32THREAD Thread =3D PsGetCurrentThreadWin32Thread(); - Object =3D Entry->KernelData; - - if (Object->cExclusiveLock =3D=3D 0) - { - Object->Tid =3D Thread; - Object->cExclusiveLock =3D 1; - GDIDBG_CAPTURELOCKER(GDI_HANDLE_GET_INDEX(hObj)) +GDIOBJ_LockObj(HGDIOBJ hObj, DWORD ExpectedType) +{ + ULONG HandleIndex; + PGDI_TABLE_ENTRY Entry; + HANDLE ProcessId, HandleProcessId, LockedProcessId, PrevProcId; + POBJ Object =3D NULL; + ULONG HandleType, HandleUpper; + + HandleIndex =3D GDI_HANDLE_GET_INDEX(hObj); + HandleType =3D GDI_HANDLE_GET_TYPE(hObj); + HandleUpper =3D GDI_HANDLE_GET_UPPER(hObj); + + /* Check that the handle index is valid. */ + if (HandleIndex >=3D GDI_HANDLE_COUNT) + return NULL; + + Entry =3D &GdiHandleTable->Entries[HandleIndex]; + + /* Check if we have the requested type */ + if ( (ExpectedType !=3D GDI_OBJECT_TYPE_DONTCARE && + HandleType !=3D ExpectedType) || + HandleType =3D=3D 0 ) + { + DPRINT1("Attempted to lock object 0x%x of wrong type (Handle: 0x%x= , requested: 0x%x)\n", + hObj, HandleType, ExpectedType); + GDIDBG_TRACECALLER(); + GDIDBG_TRACEALLOCATOR(GDI_HANDLE_GET_INDEX(hObj)); + return NULL; + } + + ProcessId =3D (HANDLE)((ULONG_PTR)PsGetCurrentProcessId() & ~1); + HandleProcessId =3D (HANDLE)((ULONG_PTR)Entry->ProcessId & ~1); + + /* Check for invalid owner. */ + if (ProcessId !=3D HandleProcessId && HandleProcessId !=3D NULL) + { + DPRINT1("Tried to lock object (0x%p) of wrong owner! ProcessId =3D= %p, HandleProcessId =3D %p\n", hObj, ProcessId, HandleProcessId); + GDIDBG_TRACECALLER(); + GDIDBG_TRACEALLOCATOR(GDI_HANDLE_GET_INDEX(hObj)); + return NULL; + } + + /* + * Prevent the thread from being terminated during the locking process. + * It would result in undesired effects and inconsistency of the global + * handle table. + */ + + KeEnterCriticalRegion(); + + /* + * Loop until we either successfully lock the handle entry & object or + * fail some of the check. + */ + + for (;;) + { + /* Lock the handle table entry. */ + LockedProcessId =3D (HANDLE)((ULONG_PTR)HandleProcessId | 0x1); + PrevProcId =3D _InterlockedCompareExchangePointer((PVOID*)&Entry->= ProcessId, + LockedProcessId, + HandleProcessId); + + if (PrevProcId =3D=3D HandleProcessId) + { + /* + * We're locking an object that belongs to our process or it's= a + * global object if HandleProcessId is 0 here. + */ + + if ( (Entry->KernelData !=3D NULL) && + ((Entry->Type << GDI_ENTRY_UPPER_SHIFT) =3D=3D HandleUppe= r) ) + { + PW32THREAD Thread =3D PsGetCurrentThreadWin32Thread(); + Object =3D Entry->KernelData; + + if (Object->cExclusiveLock =3D=3D 0) + { + Object->Tid =3D Thread; + Object->cExclusiveLock =3D 1; + GDIDBG_CAPTURELOCKER(GDI_HANDLE_GET_INDEX(hObj)) + } + else + { + if (Object->Tid !=3D Thread) + { + /* Unlock the handle table entry. */ + (void)_InterlockedExchangePointer((PVOID*)&Entry->= ProcessId, PrevProcId); + + DelayExecution(); + continue; + } + _InterlockedIncrement((PLONG)&Object->cExclusiveLock); + } } else { - if (Object->Tid !=3D Thread) - { - /* Unlock the handle table entry. */ - (void)_InterlockedExchangePointer((PVOID*)&Entry->Proces= sId, PrevProcId); - - DelayExecution(); - continue; - } - _InterlockedIncrement((PLONG)&Object->cExclusiveLock); - } - } - else - { + /* + * Debugging code. Report attempts to lock deleted handles= and + * locking type mismatches. + */ + LockErrorDebugOutput(hObj, Entry, "GDIOBJ_LockObj"); + } + + /* Unlock the handle table entry. */ + (void)_InterlockedExchangePointer((PVOID*)&Entry->ProcessId, P= revProcId); + + break; + } + else + { /* - * Debugging code. Report attempts to lock deleted handles and - * locking type mismatches. + * The handle is currently locked, wait some time and try agai= n. */ - LockErrorDebugOutput(hObj, Entry, "GDIOBJ_LockObj"); - } - - /* Unlock the handle table entry. */ - (void)_InterlockedExchangePointer((PVOID*)&Entry->ProcessId, Prev= ProcId); - - break; - } - else - { - /* - * The handle is currently locked, wait some time and try again. - */ - - DelayExecution(); - continue; - } - } - - KeLeaveCriticalRegion(); - - return Object; + + DelayExecution(); + continue; + } + } + + KeLeaveCriticalRegion(); + + return Object; } =
=
@@ -983,114 +989,114 @@ * \todo Get rid of the ExpectedType parameter! */ PGDIOBJ INTERNAL_CALL -GDIOBJ_ShareLockObj (HGDIOBJ hObj, DWORD ExpectedType) -{ - ULONG HandleIndex; - PGDI_TABLE_ENTRY Entry; - HANDLE ProcessId, HandleProcessId, LockedProcessId, PrevProcId; - POBJ Object =3D NULL; - ULONG_PTR HandleType, HandleUpper; - - HandleIndex =3D GDI_HANDLE_GET_INDEX(hObj); - HandleType =3D GDI_HANDLE_GET_TYPE(hObj); - HandleUpper =3D GDI_HANDLE_GET_UPPER(hObj); - - /* Check that the handle index is valid. */ - if (HandleIndex >=3D GDI_HANDLE_COUNT) - return NULL; - - /* Check if we have the requested type */ - if ( (ExpectedType !=3D GDI_OBJECT_TYPE_DONTCARE && - HandleType !=3D ExpectedType) || - HandleType =3D=3D 0 ) - { - DPRINT1("Attempted to lock object 0x%x of wrong type (Handle: 0x%x, = requested: 0x%x)\n", - hObj, HandleType, ExpectedType); - return NULL; - } - - Entry =3D &GdiHandleTable->Entries[HandleIndex]; - - ProcessId =3D (HANDLE)((ULONG_PTR)PsGetCurrentProcessId() & ~1); - HandleProcessId =3D (HANDLE)((ULONG_PTR)Entry->ProcessId & ~1); - - /* Check for invalid owner. */ - if (ProcessId !=3D HandleProcessId && HandleProcessId !=3D NULL) - { - return NULL; - } - - /* - * Prevent the thread from being terminated during the locking process. - * It would result in undesired effects and inconsistency of the global - * handle table. - */ - - KeEnterCriticalRegion(); - - /* - * Loop until we either successfully lock the handle entry & object or - * fail some of the check. - */ - - for (;;) - { - /* Lock the handle table entry. */ - LockedProcessId =3D (HANDLE)((ULONG_PTR)HandleProcessId | 0x1); - PrevProcId =3D _InterlockedCompareExchangePointer((PVOID*)&Entry->Pr= ocessId, - LockedProcessId, - HandleProcessId); - - if (PrevProcId =3D=3D HandleProcessId) - { - /* - * We're locking an object that belongs to our process or it's a - * global object if HandleProcessId is 0 here. - */ - - if ( (Entry->KernelData !=3D NULL) && - (HandleUpper =3D=3D (Entry->Type << GDI_ENTRY_UPPER_SHIFT)) ) - { - Object =3D (POBJ)Entry->KernelData; +GDIOBJ_ShareLockObj(HGDIOBJ hObj, DWORD ExpectedType) +{ + ULONG HandleIndex; + PGDI_TABLE_ENTRY Entry; + HANDLE ProcessId, HandleProcessId, LockedProcessId, PrevProcId; + POBJ Object =3D NULL; + ULONG_PTR HandleType, HandleUpper; + + HandleIndex =3D GDI_HANDLE_GET_INDEX(hObj); + HandleType =3D GDI_HANDLE_GET_TYPE(hObj); + HandleUpper =3D GDI_HANDLE_GET_UPPER(hObj); + + /* Check that the handle index is valid. */ + if (HandleIndex >=3D GDI_HANDLE_COUNT) + return NULL; + + /* Check if we have the requested type */ + if ( (ExpectedType !=3D GDI_OBJECT_TYPE_DONTCARE && + HandleType !=3D ExpectedType) || + HandleType =3D=3D 0 ) + { + DPRINT1("Attempted to lock object 0x%x of wrong type (Handle: 0x%x= , requested: 0x%x)\n", + hObj, HandleType, ExpectedType); + return NULL; + } + + Entry =3D &GdiHandleTable->Entries[HandleIndex]; + + ProcessId =3D (HANDLE)((ULONG_PTR)PsGetCurrentProcessId() & ~1); + HandleProcessId =3D (HANDLE)((ULONG_PTR)Entry->ProcessId & ~1); + + /* Check for invalid owner. */ + if (ProcessId !=3D HandleProcessId && HandleProcessId !=3D NULL) + { + return NULL; + } + + /* + * Prevent the thread from being terminated during the locking process. + * It would result in undesired effects and inconsistency of the global + * handle table. + */ + + KeEnterCriticalRegion(); + + /* + * Loop until we either successfully lock the handle entry & object or + * fail some of the check. + */ + + for (;;) + { + /* Lock the handle table entry. */ + LockedProcessId =3D (HANDLE)((ULONG_PTR)HandleProcessId | 0x1); + PrevProcId =3D _InterlockedCompareExchangePointer((PVOID*)&Entry->= ProcessId, + LockedProcessId, + HandleProcessId); + + if (PrevProcId =3D=3D HandleProcessId) + { + /* + * We're locking an object that belongs to our process or it's= a + * global object if HandleProcessId is 0 here. + */ + + if ( (Entry->KernelData !=3D NULL) && + (HandleUpper =3D=3D (Entry->Type << GDI_ENTRY_UPPER_SHIFT= )) ) + { + Object =3D (POBJ)Entry->KernelData; =
#ifdef GDI_DEBUG - if (_InterlockedIncrement((PLONG)&Object->ulShareCount) =3D=3D= 1) - { - memset(GDIHandleLocker[HandleIndex], 0x00, GDI_STACK_LEVE= LS * sizeof(ULONG)); - RtlCaptureStackBackTrace(1, GDI_STACK_LEVELS, (PVOID*)GDI= HandleLocker[HandleIndex], NULL); - } + if (_InterlockedIncrement((PLONG)&Object->ulShareCount) = =3D=3D 1) + { + memset(GDIHandleLocker[HandleIndex], 0x00, GDI_STACK_L= EVELS * sizeof(ULONG)); + RtlCaptureStackBackTrace(1, GDI_STACK_LEVELS, (PVOID*)= GDIHandleLocker[HandleIndex], NULL); + } #else - _InterlockedIncrement((PLONG)&Object->ulShareCount); + _InterlockedIncrement((PLONG)&Object->ulShareCount); #endif - } - else - { + } + else + { + /* + * Debugging code. Report attempts to lock deleted handles= and + * locking type mismatches. + */ + LockErrorDebugOutput(hObj, Entry, "GDIOBJ_ShareLockObj"); + } + + /* Unlock the handle table entry. */ + (void)_InterlockedExchangePointer((PVOID*)&Entry->ProcessId, P= revProcId); + + break; + } + else + { /* - * Debugging code. Report attempts to lock deleted handles and - * locking type mismatches. + * The handle is currently locked, wait some time and try agai= n. */ - LockErrorDebugOutput(hObj, Entry, "GDIOBJ_ShareLockObj"); - } - - /* Unlock the handle table entry. */ - (void)_InterlockedExchangePointer((PVOID*)&Entry->ProcessId, Prev= ProcId); - - break; - } - else - { - /* - * The handle is currently locked, wait some time and try again. - */ - - DelayExecution(); - continue; - } - } - - KeLeaveCriticalRegion(); - - return Object; + + DelayExecution(); + continue; + } + } + + KeLeaveCriticalRegion(); + + return Object; } =
=
@@ -1121,411 +1127,411 @@ BOOL INTERNAL_CALL GDIOBJ_OwnedByCurrentProcess(HGDIOBJ ObjectHandle) { - PGDI_TABLE_ENTRY Entry; - HANDLE ProcessId; - BOOL Ret; - - DPRINT("GDIOBJ_OwnedByCurrentProcess: ObjectHandle: 0x%08x\n", ObjectHan= dle); - - if(!GDI_HANDLE_IS_STOCKOBJ(ObjectHandle)) - { - ProcessId =3D PsGetCurrentProcessId(); - - Entry =3D GDI_HANDLE_GET_ENTRY(GdiHandleTable, ObjectHandle); - Ret =3D Entry->KernelData !=3D NULL && - (Entry->Type & ~GDI_ENTRY_REUSE_MASK) !=3D 0 && - (HANDLE)((ULONG_PTR)Entry->ProcessId & ~0x1) =3D=3D ProcessId; - - return Ret; - } - - return FALSE; + PGDI_TABLE_ENTRY Entry; + HANDLE ProcessId; + BOOL Ret; + + DPRINT("GDIOBJ_OwnedByCurrentProcess: ObjectHandle: 0x%08x\n", ObjectH= andle); + + if (!GDI_HANDLE_IS_STOCKOBJ(ObjectHandle)) + { + ProcessId =3D PsGetCurrentProcessId(); + + Entry =3D GDI_HANDLE_GET_ENTRY(GdiHandleTable, ObjectHandle); + Ret =3D Entry->KernelData !=3D NULL && + (Entry->Type & ~GDI_ENTRY_REUSE_MASK) !=3D 0 && + (HANDLE)((ULONG_PTR)Entry->ProcessId & ~0x1) =3D=3D ProcessI= d; + + return Ret; + } + + return FALSE; } =
BOOL INTERNAL_CALL GDIOBJ_ConvertToStockObj(HGDIOBJ *phObj) { -/* - * FIXME !!!!! THIS FUNCTION NEEDS TO BE FIXED - IT IS NOT SAFE WHEN OTHER= THREADS - * MIGHT ATTEMPT TO LOCK THE OBJECT DURING THIS CALL!!! - */ - PGDI_TABLE_ENTRY Entry; - HANDLE ProcessId, LockedProcessId, PrevProcId; - PW32THREAD Thread; - HGDIOBJ hObj; + /* + * FIXME !!!!! THIS FUNCTION NEEDS TO BE FIXED - IT IS NOT SAFE WHEN O= THER THREADS + * MIGHT ATTEMPT TO LOCK THE OBJECT DURING THIS CALL!!! + */ + PGDI_TABLE_ENTRY Entry; + HANDLE ProcessId, LockedProcessId, PrevProcId; + PW32THREAD Thread; + HGDIOBJ hObj; #ifdef GDI_DEBUG - ULONG Attempts =3D 0; + ULONG Attempts =3D 0; #endif =
- ASSERT(phObj); - hObj =3D *phObj; - - DPRINT("GDIOBJ_ConvertToStockObj: hObj: 0x%08x\n", hObj); - - Thread =3D PsGetCurrentThreadWin32Thread(); - - if(!GDI_HANDLE_IS_STOCKOBJ(hObj)) - { - ProcessId =3D PsGetCurrentProcessId(); - LockedProcessId =3D (HANDLE)((ULONG_PTR)ProcessId | 0x1); - - Entry =3D GDI_HANDLE_GET_ENTRY(GdiHandleTable, hObj); + ASSERT(phObj); + hObj =3D *phObj; + + DPRINT("GDIOBJ_ConvertToStockObj: hObj: 0x%08x\n", hObj); + + Thread =3D PsGetCurrentThreadWin32Thread(); + + if (!GDI_HANDLE_IS_STOCKOBJ(hObj)) + { + ProcessId =3D PsGetCurrentProcessId(); + LockedProcessId =3D (HANDLE)((ULONG_PTR)ProcessId | 0x1); + + Entry =3D GDI_HANDLE_GET_ENTRY(GdiHandleTable, hObj); =
LockHandle: - /* lock the object, we must not convert stock objects, so don't check!= !! */ - PrevProcId =3D _InterlockedCompareExchangePointer((PVOID*)&Entry->Proc= essId, LockedProcessId, ProcessId); - if(PrevProcId =3D=3D ProcessId) - { - LONG NewType, PrevType, OldType; - - /* we're locking an object that belongs to our process. First calcul= ate - the new object type including the stock object flag and then try = to - exchange it.*/ - /* On Windows the higher 16 bit of the type field don't contain the - full type from the handle, but the base type. - (type =3D BRSUH, PEN, EXTPEN, basetype =3D BRUSH) */ - OldType =3D ((ULONG)hObj & GDI_HANDLE_BASETYPE_MASK) | ((ULONG)hObj =
GDI_ENTRY_UPPER_SHIFT);
- /* We are currently not using bits 24..31 (flags) of the type field,= but for compatibility - we copy them as we can't get them from the handle */ - OldType |=3D Entry->Type & GDI_ENTRY_FLAGS_MASK; - - /* As the object should be a stock object, set it's flag, but only i= n the lower 16 bits */ - NewType =3D OldType | GDI_ENTRY_STOCK_MASK; - - /* Try to exchange the type field - but only if the old (previous ty= pe) matches! */ - PrevType =3D _InterlockedCompareExchange(&Entry->Type, NewType, OldT= ype); - if(PrevType =3D=3D OldType && Entry->KernelData !=3D NULL) - { - PW32THREAD PrevThread; - POBJ Object; - - /* We successfully set the stock object flag. - KernelData should never be NULL here!!! */ - ASSERT(Entry->KernelData); - - Object =3D Entry->KernelData; - - PrevThread =3D Object->Tid; - if(Object->cExclusiveLock =3D=3D 0 || PrevThread =3D=3D Thread) - { - /* dereference the process' object counter */ - if(PrevProcId !=3D GDI_GLOBAL_PROCESS) - { - PEPROCESS OldProcess; - PW32PROCESS W32Process; - NTSTATUS Status; - - /* FIXME */ - Status =3D PsLookupProcessByProcessId((HANDLE)((ULONG_PTR)Prev= ProcId & ~0x1), &OldProcess); - if(NT_SUCCESS(Status)) - { - W32Process =3D (PW32PROCESS)OldProcess->Win32Process; - if(W32Process !=3D NULL) - { - _InterlockedDecrement(&W32Process->GDIObjects); - } - ObDereferenceObject(OldProcess); - } - } - - /* remove the process id lock and make it global */ - (void)_InterlockedExchangePointer((PVOID*)&Entry->ProcessId, GDI= _GLOBAL_PROCESS); - - hObj =3D (HGDIOBJ)((ULONG)(hObj) | GDI_HANDLE_STOCK_MASK); - *phObj =3D hObj; - - /* we're done, successfully converted the object */ - return TRUE; + /* lock the object, we must not convert stock objects, so don't ch= eck!!! */ + PrevProcId =3D _InterlockedCompareExchangePointer((PVOID*)&Entry->= ProcessId, LockedProcessId, ProcessId); + if (PrevProcId =3D=3D ProcessId) + { + LONG NewType, PrevType, OldType; + + /* we're locking an object that belongs to our process. First = calculate + the new object type including the stock object flag and the= n try to + exchange it.*/ + /* On Windows the higher 16 bit of the type field don't contai= n the + full type from the handle, but the base type. + (type =3D BRSUH, PEN, EXTPEN, basetype =3D BRUSH) */ + OldType =3D ((ULONG)hObj & GDI_HANDLE_BASETYPE_MASK) | ((ULONG= )hObj >> GDI_ENTRY_UPPER_SHIFT); + /* We are currently not using bits 24..31 (flags) of the type = field, but for compatibility + we copy them as we can't get them from the handle */ + OldType |=3D Entry->Type & GDI_ENTRY_FLAGS_MASK; + + /* As the object should be a stock object, set it's flag, but = only in the lower 16 bits */ + NewType =3D OldType | GDI_ENTRY_STOCK_MASK; + + /* Try to exchange the type field - but only if the old (previ= ous type) matches! */ + PrevType =3D _InterlockedCompareExchange(&Entry->Type, NewType= , OldType); + if (PrevType =3D=3D OldType && Entry->KernelData !=3D NULL) + { + PW32THREAD PrevThread; + POBJ Object; + + /* We successfully set the stock object flag. + KernelData should never be NULL here!!! */ + ASSERT(Entry->KernelData); + + Object =3D Entry->KernelData; + + PrevThread =3D Object->Tid; + if (Object->cExclusiveLock =3D=3D 0 || PrevThread =3D=3D T= hread) + { + /* dereference the process' object counter */ + if (PrevProcId !=3D GDI_GLOBAL_PROCESS) + { + PEPROCESS OldProcess; + PW32PROCESS W32Process; + NTSTATUS Status; + + /* FIXME */ + Status =3D PsLookupProcessByProcessId((HANDLE)((UL= ONG_PTR)PrevProcId & ~0x1), &OldProcess); + if (NT_SUCCESS(Status)) + { + W32Process =3D (PW32PROCESS)OldProcess->Win32P= rocess; + if (W32Process !=3D NULL) + { + _InterlockedDecrement(&W32Process->GDIObje= cts); + } + ObDereferenceObject(OldProcess); + } + } + + /* remove the process id lock and make it global */ + (void)_InterlockedExchangePointer((PVOID*)&Entry->Proc= essId, GDI_GLOBAL_PROCESS); + + hObj =3D (HGDIOBJ)((ULONG)(hObj) | GDI_HANDLE_STOCK_MA= SK); + *phObj =3D hObj; + + /* we're done, successfully converted the object */ + return TRUE; + } + else + { +#ifdef GDI_DEBUG + if (++Attempts > 20) + { + DPRINT1("[%d]Locked by 0x%x (we're 0x%x)\n", Attem= pts, PrevThread, Thread); + } +#endif + /* WTF?! The object is already locked by a different t= hread! + Release the lock, wait a bit and try again! + FIXME - we should give up after some time unless we= want to wait forever! */ + (void)_InterlockedExchangePointer((PVOID*)&Entry->Proc= essId, PrevProcId); + + DelayExecution(); + goto LockHandle; + } + } + else + { + DPRINT1("Attempted to convert object 0x%x that is deleted!= Should never get here!!!\n", hObj); + DPRINT1("OldType =3D 0x%x, Entry->Type =3D 0x%x, NewType = =3D 0x%x, Entry->KernelData =3D 0x%x\n", OldType, Entry->Type, NewType, Ent= ry->KernelData); + } + } + else if (PrevProcId =3D=3D LockedProcessId) + { +#ifdef GDI_DEBUG + if (++Attempts > 20) + { + DPRINT1("[%d]Waiting on 0x%x\n", Attempts, hObj); + } +#endif + /* the object is currently locked, wait some time and try agai= n. + FIXME - we shouldn't loop forever! Give up after some time!= */ + DelayExecution(); + /* try again */ + goto LockHandle; } else { -#ifdef GDI_DEBUG - if(++Attempts > 20) - { - DPRINT1("[%d]Locked by 0x%x (we're 0x%x)\n", Attempts, PrevT= hread, Thread); - } -#endif - /* WTF?! The object is already locked by a different thread! - Release the lock, wait a bit and try again! - FIXME - we should give up after some time unless we want to w= ait forever! */ - (void)_InterlockedExchangePointer((PVOID*)&Entry->ProcessId, Pre= vProcId); - - DelayExecution(); - goto LockHandle; - } - } - else - { - DPRINT1("Attempted to convert object 0x%x that is deleted! Should = never get here!!!\n", hObj); - DPRINT1("OldType =3D 0x%x, Entry->Type =3D 0x%x, NewType =3D 0x%x,= Entry->KernelData =3D 0x%x\n", OldType, Entry->Type, NewType, Entry->Kerne= lData); - } - } - else if(PrevProcId =3D=3D LockedProcessId) - { -#ifdef GDI_DEBUG - if(++Attempts > 20) - { - DPRINT1("[%d]Waiting on 0x%x\n", Attempts, hObj); - } -#endif - /* the object is currently locked, wait some time and try again. - FIXME - we shouldn't loop forever! Give up after some time! */ - DelayExecution(); - /* try again */ - goto LockHandle; - } - else - { - DPRINT1("Attempted to convert invalid handle: 0x%x\n", hObj); - } - } - - return FALSE; + DPRINT1("Attempted to convert invalid handle: 0x%x\n", hObj); + } + } + + return FALSE; } =
void INTERNAL_CALL GDIOBJ_SetOwnership(HGDIOBJ ObjectHandle, PEPROCESS NewOwner) { - PGDI_TABLE_ENTRY Entry; - HANDLE ProcessId, LockedProcessId, PrevProcId; - PW32THREAD Thread; + PGDI_TABLE_ENTRY Entry; + HANDLE ProcessId, LockedProcessId, PrevProcId; + PW32THREAD Thread; #ifdef GDI_DEBUG - ULONG Attempts =3D 0; + ULONG Attempts =3D 0; #endif =
- DPRINT("GDIOBJ_SetOwnership: hObj: 0x%x, NewProcess: 0x%x\n", ObjectHand= le, (NewOwner ? PsGetProcessId(NewOwner) : 0)); - - Thread =3D PsGetCurrentThreadWin32Thread(); - - if(!GDI_HANDLE_IS_STOCKOBJ(ObjectHandle)) - { - ProcessId =3D PsGetCurrentProcessId(); - LockedProcessId =3D (HANDLE)((ULONG_PTR)ProcessId | 0x1); - - Entry =3D GDI_HANDLE_GET_ENTRY(GdiHandleTable, ObjectHandle); + DPRINT("GDIOBJ_SetOwnership: hObj: 0x%x, NewProcess: 0x%x\n", ObjectHa= ndle, (NewOwner ? PsGetProcessId(NewOwner) : 0)); + + Thread =3D PsGetCurrentThreadWin32Thread(); + + if (!GDI_HANDLE_IS_STOCKOBJ(ObjectHandle)) + { + ProcessId =3D PsGetCurrentProcessId(); + LockedProcessId =3D (HANDLE)((ULONG_PTR)ProcessId | 0x1); + + Entry =3D GDI_HANDLE_GET_ENTRY(GdiHandleTable, ObjectHandle); =
LockHandle: - /* lock the object, we must not convert stock objects, so don't check!= !! */ - PrevProcId =3D _InterlockedCompareExchangePointer((PVOID*)&Entry->Proc= essId, ProcessId, LockedProcessId); - if(PrevProcId =3D=3D ProcessId) - { - PW32THREAD PrevThread; - - if((Entry->Type & ~GDI_ENTRY_REUSE_MASK) !=3D 0 && Entry->KernelData= !=3D NULL) - { - POBJ Object =3D Entry->KernelData; - - PrevThread =3D Object->Tid; - if(Object->cExclusiveLock =3D=3D 0 || PrevThread =3D=3D Thread) - { - PEPROCESS OldProcess; - PW32PROCESS W32Process; - NTSTATUS Status; - - /* dereference the process' object counter */ - /* FIXME */ - if((ULONG_PTR)PrevProcId & ~0x1) - { - Status =3D PsLookupProcessByProcessId((HANDLE)((ULONG_PTR)Prev= ProcId & ~0x1), &OldProcess); - if(NT_SUCCESS(Status)) - { - W32Process =3D (PW32PROCESS)OldProcess->Win32Process; - if(W32Process !=3D NULL) - { - _InterlockedDecrement(&W32Process->GDIObjects); - } - ObDereferenceObject(OldProcess); - } - } - - if(NewOwner !=3D NULL) - { - ProcessId =3D PsGetProcessId(NewOwner); - - /* Increase the new process' object counter */ - W32Process =3D (PW32PROCESS)NewOwner->Win32Process; - if(W32Process !=3D NULL) - { - _InterlockedIncrement(&W32Process->GDIObjects); - } - } - else - ProcessId =3D 0; - - /* remove the process id lock and change it to the new process i= d */ - (void)_InterlockedExchangePointer((PVOID*)&Entry->ProcessId, Pro= cessId); - - /* we're done! */ - return; + /* lock the object, we must not convert stock objects, so don't ch= eck!!! */ + PrevProcId =3D _InterlockedCompareExchangePointer((PVOID*)&Entry->= ProcessId, ProcessId, LockedProcessId); + if (PrevProcId =3D=3D ProcessId) + { + PW32THREAD PrevThread; + + if ((Entry->Type & ~GDI_ENTRY_REUSE_MASK) !=3D 0 && Entry->Ker= nelData !=3D NULL) + { + POBJ Object =3D Entry->KernelData; + + PrevThread =3D Object->Tid; + if (Object->cExclusiveLock =3D=3D 0 || PrevThread =3D=3D T= hread) + { + PEPROCESS OldProcess; + PW32PROCESS W32Process; + NTSTATUS Status; + + /* dereference the process' object counter */ + /* FIXME */ + if ((ULONG_PTR)PrevProcId & ~0x1) + { + Status =3D PsLookupProcessByProcessId((HANDLE)((UL= ONG_PTR)PrevProcId & ~0x1), &OldProcess); + if (NT_SUCCESS(Status)) + { + W32Process =3D (PW32PROCESS)OldProcess->Win32P= rocess; + if (W32Process !=3D NULL) + { + _InterlockedDecrement(&W32Process->GDIObje= cts); + } + ObDereferenceObject(OldProcess); + } + } + + if (NewOwner !=3D NULL) + { + ProcessId =3D PsGetProcessId(NewOwner); + + /* Increase the new process' object counter */ + W32Process =3D (PW32PROCESS)NewOwner->Win32Process; + if (W32Process !=3D NULL) + { + _InterlockedIncrement(&W32Process->GDIObjects); + } + } + else + ProcessId =3D 0; + + /* remove the process id lock and change it to the new= process id */ + (void)_InterlockedExchangePointer((PVOID*)&Entry->Proc= essId, ProcessId); + + /* we're done! */ + return; + } + else + { +#ifdef GDI_DEBUG + if (++Attempts > 20) + { + DPRINT1("[%d]Locked by 0x%x (we're 0x%x)\n", Attem= pts, PrevThread, Thread); + } +#endif + /* WTF?! The object is already locked by a different t= hread! + Release the lock, wait a bit and try again! DO rese= t the pid lock + so we make sure we don't access invalid memory in c= ase the object is + being deleted in the meantime (because we don't hav= e aquired a reference + at this point). + FIXME - we should give up after some time unless we= want to wait forever! */ + (void)_InterlockedExchangePointer((PVOID*)&Entry->Proc= essId, PrevProcId); + + DelayExecution(); + goto LockHandle; + } + } + else + { + DPRINT1("Attempted to change ownership of an object 0x%x c= urrently being destroyed!!!\n", ObjectHandle); + DPRINT1("Entry->Type =3D 0x%lx, Entry->KernelData =3D 0x%p= \n", Entry->Type, Entry->KernelData); + } + } + else if (PrevProcId =3D=3D LockedProcessId) + { +#ifdef GDI_DEBUG + if (++Attempts > 20) + { + DPRINT1("[%d]Waiting on 0x%x\n", Attempts, ObjectHandle); + } +#endif + /* the object is currently locked, wait some time and try agai= n. + FIXME - we shouldn't loop forever! Give up after some time!= */ + DelayExecution(); + /* try again */ + goto LockHandle; + } + else if (((ULONG_PTR)PrevProcId & ~0x1) =3D=3D 0) + { + /* allow changing ownership of global objects */ + ProcessId =3D NULL; + LockedProcessId =3D (HANDLE)((ULONG_PTR)ProcessId | 0x1); + goto LockHandle; + } + else if ((HANDLE)((ULONG_PTR)PrevProcId & ~0x1) !=3D PsGetCurrentP= rocessId()) + { + DPRINT1("Attempted to change ownership of object 0x%x (pid: 0x= %x) from pid 0x%x!!!\n", ObjectHandle, (ULONG_PTR)PrevProcId & ~0x1, PsGetC= urrentProcessId()); } else { -#ifdef GDI_DEBUG - if(++Attempts > 20) - { - DPRINT1("[%d]Locked by 0x%x (we're 0x%x)\n", Attempts, PrevThr= ead, Thread); - } -#endif - /* WTF?! The object is already locked by a different thread! - Release the lock, wait a bit and try again! DO reset the pid = lock - so we make sure we don't access invalid memory in case the ob= ject is - being deleted in the meantime (because we don't have aquired = a reference - at this point). - FIXME - we should give up after some time unless we want to w= ait forever! */ - (void)_InterlockedExchangePointer((PVOID*)&Entry->ProcessId, Pre= vProcId); - - DelayExecution(); - goto LockHandle; - } - } - else - { - DPRINT1("Attempted to change ownership of an object 0x%x currently= being destroyed!!!\n", ObjectHandle); - DPRINT1("Entry->Type =3D 0x%lx, Entry->KernelData =3D 0x%p\n", Ent= ry->Type, Entry->KernelData); - } - } - else if(PrevProcId =3D=3D LockedProcessId) - { -#ifdef GDI_DEBUG - if(++Attempts > 20) - { - DPRINT1("[%d]Waiting on 0x%x\n", Attempts, ObjectHandle); - } -#endif - /* the object is currently locked, wait some time and try again. - FIXME - we shouldn't loop forever! Give up after some time! */ - DelayExecution(); - /* try again */ - goto LockHandle; - } - else if(((ULONG_PTR)PrevProcId & ~0x1) =3D=3D 0) - { - /* allow changing ownership of global objects */ - ProcessId =3D NULL; - LockedProcessId =3D (HANDLE)((ULONG_PTR)ProcessId | 0x1); - goto LockHandle; - } - else if((HANDLE)((ULONG_PTR)PrevProcId & ~0x1) !=3D PsGetCurrentProces= sId()) - { - DPRINT1("Attempted to change ownership of object 0x%x (pid: 0x%x) fr= om pid 0x%x!!!\n", ObjectHandle, (ULONG_PTR)PrevProcId & ~0x1, PsGetCurrent= ProcessId()); - } - else - { - DPRINT1("Attempted to change owner of invalid handle: 0x%x\n", Objec= tHandle); - } - } + DPRINT1("Attempted to change owner of invalid handle: 0x%x\n",= ObjectHandle); + } + } } =
void INTERNAL_CALL GDIOBJ_CopyOwnership(HGDIOBJ CopyFrom, HGDIOBJ CopyTo) { - PGDI_TABLE_ENTRY FromEntry; - PW32THREAD Thread; - HANDLE FromProcessId, FromLockedProcessId, FromPrevProcId; + PGDI_TABLE_ENTRY FromEntry; + PW32THREAD Thread; + HANDLE FromProcessId, FromLockedProcessId, FromPrevProcId; #ifdef GDI_DEBUG - ULONG Attempts =3D 0; + ULONG Attempts =3D 0; #endif =
- DPRINT("GDIOBJ_CopyOwnership: from: 0x%x, to: 0x%x\n", CopyFrom, CopyTo); - - Thread =3D PsGetCurrentThreadWin32Thread(); - - if(!GDI_HANDLE_IS_STOCKOBJ(CopyFrom) && !GDI_HANDLE_IS_STOCKOBJ(CopyTo)) - { - FromEntry =3D GDI_HANDLE_GET_ENTRY(GdiHandleTable, CopyFrom); - - FromProcessId =3D (HANDLE)((ULONG_PTR)FromEntry->ProcessId & ~0x1); - FromLockedProcessId =3D (HANDLE)((ULONG_PTR)FromProcessId | 0x1); + DPRINT("GDIOBJ_CopyOwnership: from: 0x%x, to: 0x%x\n", CopyFrom, CopyT= o); + + Thread =3D PsGetCurrentThreadWin32Thread(); + + if (!GDI_HANDLE_IS_STOCKOBJ(CopyFrom) && !GDI_HANDLE_IS_STOCKOBJ(CopyT= o)) + { + FromEntry =3D GDI_HANDLE_GET_ENTRY(GdiHandleTable, CopyFrom); + + FromProcessId =3D (HANDLE)((ULONG_PTR)FromEntry->ProcessId & ~0x1); + FromLockedProcessId =3D (HANDLE)((ULONG_PTR)FromProcessId | 0x1); =
LockHandleFrom: - /* lock the object, we must not convert stock objects, so don't check!= !! */ - FromPrevProcId =3D _InterlockedCompareExchangePointer((PVOID*)&FromEnt= ry->ProcessId, FromProcessId, FromLockedProcessId); - if(FromPrevProcId =3D=3D FromProcessId) - { - PW32THREAD PrevThread; - POBJ Object; - - if((FromEntry->Type & ~GDI_ENTRY_REUSE_MASK) !=3D 0 && FromEntry->Ke= rnelData !=3D NULL) - { - Object =3D FromEntry->KernelData; - - /* save the pointer to the calling thread so we know it was this t= hread - that locked the object */ - PrevThread =3D Object->Tid; - if(Object->cExclusiveLock =3D=3D 0 || PrevThread =3D=3D Thread) - { - /* now let's change the ownership of the target object */ - - if(((ULONG_PTR)FromPrevProcId & ~0x1) !=3D 0) - { - PEPROCESS ProcessTo; - /* FIXME */ - if(NT_SUCCESS(PsLookupProcessByProcessId((HANDLE)((ULONG_PTR)F= romPrevProcId & ~0x1), &ProcessTo))) - { - GDIOBJ_SetOwnership(CopyTo, ProcessTo); - ObDereferenceObject(ProcessTo); - } - } - else - { - /* mark the object as global */ - GDIOBJ_SetOwnership(CopyTo, NULL); - } - - (void)_InterlockedExchangePointer((PVOID*)&FromEntry->ProcessId,= FromPrevProcId); + /* lock the object, we must not convert stock objects, so don't ch= eck!!! */ + FromPrevProcId =3D _InterlockedCompareExchangePointer((PVOID*)&Fro= mEntry->ProcessId, FromProcessId, FromLockedProcessId); + if (FromPrevProcId =3D=3D FromProcessId) + { + PW32THREAD PrevThread; + POBJ Object; + + if ((FromEntry->Type & ~GDI_ENTRY_REUSE_MASK) !=3D 0 && FromEn= try->KernelData !=3D NULL) + { + Object =3D FromEntry->KernelData; + + /* save the pointer to the calling thread so we know it wa= s this thread + that locked the object */ + PrevThread =3D Object->Tid; + if (Object->cExclusiveLock =3D=3D 0 || PrevThread =3D=3D T= hread) + { + /* now let's change the ownership of the target object= */ + + if (((ULONG_PTR)FromPrevProcId & ~0x1) !=3D 0) + { + PEPROCESS ProcessTo; + /* FIXME */ + if (NT_SUCCESS(PsLookupProcessByProcessId((HANDLE)= ((ULONG_PTR)FromPrevProcId & ~0x1), &ProcessTo))) + { + GDIOBJ_SetOwnership(CopyTo, ProcessTo); + ObDereferenceObject(ProcessTo); + } + } + else + { + /* mark the object as global */ + GDIOBJ_SetOwnership(CopyTo, NULL); + } + + (void)_InterlockedExchangePointer((PVOID*)&FromEntry->= ProcessId, FromPrevProcId); + } + else + { +#ifdef GDI_DEBUG + if (++Attempts > 20) + { + DPRINT1("[%d]Locked by 0x%x (we're 0x%x)\n", Attem= pts, PrevThread, Thread); + } +#endif + /* WTF?! The object is already locked by a different t= hread! + Release the lock, wait a bit and try again! DO rese= t the pid lock + so we make sure we don't access invalid memory in c= ase the object is + being deleted in the meantime (because we don't hav= e aquired a reference + at this point). + FIXME - we should give up after some time unless we= want to wait forever! */ + (void)_InterlockedExchangePointer((PVOID*)&FromEntry->= ProcessId, FromPrevProcId); + + DelayExecution(); + goto LockHandleFrom; + } + } + else + { + DPRINT1("Attempted to copy ownership from an object 0x%x c= urrently being destroyed!!!\n", CopyFrom); + } + } + else if (FromPrevProcId =3D=3D FromLockedProcessId) + { +#ifdef GDI_DEBUG + if (++Attempts > 20) + { + DPRINT1("[%d]Waiting on 0x%x\n", Attempts, CopyFrom); + } +#endif + /* the object is currently locked, wait some time and try agai= n. + FIXME - we shouldn't loop forever! Give up after some time!= */ + DelayExecution(); + /* try again */ + goto LockHandleFrom; + } + else if ((HANDLE)((ULONG_PTR)FromPrevProcId & ~0x1) !=3D PsGetCurr= entProcessId()) + { + /* FIXME - should we really allow copying ownership from objec= ts that we don't even own? */ + DPRINT1("WARNING! Changing copying ownership of object 0x%x (p= id: 0x%x) to pid 0x%x!!!\n", CopyFrom, (ULONG_PTR)FromPrevProcId & ~0x1, Ps= GetCurrentProcessId()); + FromProcessId =3D (HANDLE)((ULONG_PTR)FromPrevProcId & ~0x1); + FromLockedProcessId =3D (HANDLE)((ULONG_PTR)FromProcessId | 0x= 1); + goto LockHandleFrom; } else { -#ifdef GDI_DEBUG - if(++Attempts > 20) - { - DPRINT1("[%d]Locked by 0x%x (we're 0x%x)\n", Attempts, PrevThr= ead, Thread); - } -#endif - /* WTF?! The object is already locked by a different thread! - Release the lock, wait a bit and try again! DO reset the pid = lock - so we make sure we don't access invalid memory in case the ob= ject is - being deleted in the meantime (because we don't have aquired = a reference - at this point). - FIXME - we should give up after some time unless we want to w= ait forever! */ - (void)_InterlockedExchangePointer((PVOID*)&FromEntry->ProcessId,= FromPrevProcId); - - DelayExecution(); - goto LockHandleFrom; - } - } - else - { - DPRINT1("Attempted to copy ownership from an object 0x%x currently= being destroyed!!!\n", CopyFrom); - } - } - else if(FromPrevProcId =3D=3D FromLockedProcessId) - { -#ifdef GDI_DEBUG - if(++Attempts > 20) - { - DPRINT1("[%d]Waiting on 0x%x\n", Attempts, CopyFrom); - } -#endif - /* the object is currently locked, wait some time and try again. - FIXME - we shouldn't loop forever! Give up after some time! */ - DelayExecution(); - /* try again */ - goto LockHandleFrom; - } - else if((HANDLE)((ULONG_PTR)FromPrevProcId & ~0x1) !=3D PsGetCurrentPr= ocessId()) - { - /* FIXME - should we really allow copying ownership from objects tha= t we don't even own? */ - DPRINT1("WARNING! Changing copying ownership of object 0x%x (pid: 0x= %x) to pid 0x%x!!!\n", CopyFrom, (ULONG_PTR)FromPrevProcId & ~0x1, PsGetCur= rentProcessId()); - FromProcessId =3D (HANDLE)((ULONG_PTR)FromPrevProcId & ~0x1); - FromLockedProcessId =3D (HANDLE)((ULONG_PTR)FromProcessId | 0x1); - goto LockHandleFrom; - } - else - { - DPRINT1("Attempted to copy ownership from invalid handle: 0x%x\n", C= opyFrom); - } - } + DPRINT1("Attempted to copy ownership from invalid handle: 0x%x= \n", CopyFrom); + } + } } =
PVOID INTERNAL_CALL @@ -1563,24 +1569,24 @@ APIENTRY NtGdiCreateClientObj( IN ULONG ulType - ) +) { // ATM we use DC object for KernelData. I think it should be at a minimum = GDIOBJEMPTYHDR. // The UserData is set in user mode, so it is always NULL. // - INT Index; - PGDI_TABLE_ENTRY Entry; - HANDLE handle =3D GDIOBJ_AllocObj(GDI_OBJECT_TYPE_CLIOBJ); + INT Index; + PGDI_TABLE_ENTRY Entry; + HANDLE handle =3D GDIOBJ_AllocObj(GDI_OBJECT_TYPE_CLIOBJ); // Need to change handle type based on ulType. - Index =3D GDI_HANDLE_GET_INDEX((HGDIOBJ)handle); - Entry =3D &GdiHandleTable->Entries[Index]; + Index =3D GDI_HANDLE_GET_INDEX((HGDIOBJ)handle); + Entry =3D &GdiHandleTable->Entries[Index]; // mask out lower half and set the type by ulType. - Entry->Type &=3D GDI_HANDLE_UPPER_MASK; - Entry->Type |=3D ulType >> GDI_ENTRY_UPPER_SHIFT; + Entry->Type &=3D GDI_HANDLE_UPPER_MASK; + Entry->Type |=3D ulType >> GDI_ENTRY_UPPER_SHIFT; // mask out handle type than set it by ulType. - handle =3D (HANDLE)(((ULONG_PTR)(handle)) & (GDI_HANDLE_REUSE_MASK|GDI_H= ANDLE_STOCK_MASK|0x0ffff)); - handle =3D (HANDLE)(((ULONG_PTR)(handle)) | ulType); - return handle; + handle =3D (HANDLE)(((ULONG_PTR)(handle)) & (GDI_HANDLE_REUSE_MASK|GDI= _HANDLE_STOCK_MASK|0x0ffff)); + handle =3D (HANDLE)(((ULONG_PTR)(handle)) | ulType); + return handle; } =
W32KAPI @@ -1588,9 +1594,9 @@ APIENTRY NtGdiDeleteClientObj( IN HANDLE h - ) -{ - return GDIOBJ_FreeObj(h, GDI_OBJECT_TYPE_CLIOBJ); +) +{ + return GDIOBJ_FreeObj(h, GDI_OBJECT_TYPE_CLIOBJ); } =
/* EOF */