ReactOS 0.4.15-dev-7788-g1ad9096
gdiobj.c File Reference
#include <win32k.h>
#include <debug.h>
Include dependency graph for gdiobj.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define ASSERT_LOCK_ORDER(hobj)
 
#define ASSERT_SHARED_OBJECT_TYPE(objt)
 
#define ASSERT_EXCLUSIVE_OBJECT_TYPE(objt)
 
#define ASSERT_TRYLOCK_OBJECT_TYPE(objt)
 
#define GDIOBJ_POOL_TAG(type)   ('00hG' + (((type) & 0x1f) << 24))
 

Enumerations

enum  {
  REF_MASK_REUSE = 0xff000000 , REF_INC_REUSE = 0x01000000 , REF_MASK_VALID = 0x00800000 , REF_MASK_COUNT = 0x007fffff ,
  REF_MASK_INUSE = 0x00ffffff
}
 

Functions

FORCEINLINE ULONG InterlockedReadUlong (_In_ _Interlocked_operand_ ULONG volatile *Source)
 
FORCEINLINE void INCREASE_THREAD_LOCK_COUNT (_In_ HANDLE hobj)
 
FORCEINLINE void DECREASE_THREAD_LOCK_COUNT (_In_ HANDLE hobj)
 
static VOID NTAPI GDIOBJ_vCleanup (PVOID ObjectBody)
 
static VOID InitLookasideList (UCHAR objt, ULONG cjSize)
 
NTSTATUS NTAPI InitGdiHandleTable (void)
 
FORCEINLINE VOID IncrementCurrentProcessGdiHandleCount (void)
 
FORCEINLINE VOID DecrementCurrentProcessGdiHandleCount (void)
 
static VOID IncrementGdiHandleCount (ULONG ulProcessId)
 
static VOID DecrementGdiHandleCount (ULONG ulProcessId)
 
static PENTRY ENTRY_pentPopFreeEntry (VOID)
 
static VOID ENTRY_vPushFreeEntry (PENTRY pentFree)
 
static PENTRY ENTRY_ReferenceEntryByHandle (HGDIOBJ hobj, FLONG fl)
 
static HGDIOBJ ENTRY_hInsertObject (PENTRY pentry, POBJ pobj, UCHAR objt, ULONG ulOwner)
 
POBJ NTAPI GDIOBJ_AllocateObject (UCHAR objt, ULONG cjSize, FLONG fl)
 
VOID NTAPI GDIOBJ_vFreeObject (POBJ pobj)
 
VOID NTAPI GDIOBJ_vDereferenceObject (POBJ pobj)
 
POBJ NTAPI GDIOBJ_ReferenceObjectByHandle (HGDIOBJ hobj, UCHAR objt)
 
VOID NTAPI GDIOBJ_vReferenceObjectByPointer (POBJ pobj)
 
PGDIOBJ NTAPI GDIOBJ_TryLockObject (HGDIOBJ hobj, UCHAR objt)
 
PGDIOBJ NTAPI GDIOBJ_LockObject (HGDIOBJ hobj, UCHAR objt)
 
VOID NTAPI GDIOBJ_vUnlockObject (POBJ pobj)
 
HGDIOBJ NTAPI GDIOBJ_hInsertObject (POBJ pobj, ULONG ulOwner)
 
VOID NTAPI GDIOBJ_vSetObjectOwner (POBJ pobj, ULONG ulNewOwner)
 
BOOL NTAPI GDIOBJ_bLockMultipleObjects (IN ULONG ulCount, IN HGDIOBJ *ahObj, OUT PGDIOBJ *apObj, IN UCHAR objt)
 
PVOID NTAPI GDIOBJ_pvGetObjectAttr (POBJ pobj)
 
VOID NTAPI GDIOBJ_vSetObjectAttr (POBJ pobj, PVOID pvObjAttr)
 
VOID NTAPI GDIOBJ_vDeleteObject (POBJ pobj)
 
BOOL NTAPI GreIsHandleValid (HGDIOBJ hobj)
 
BOOL NTAPI GreDeleteObject (HGDIOBJ hobj)
 
ULONG NTAPI GreGetObjectOwner (HGDIOBJ hobj)
 
BOOL NTAPI GreSetObjectOwnerEx (HGDIOBJ hobj, ULONG ulOwner, ULONG Flags)
 
BOOL NTAPI GreSetObjectOwner (HGDIOBJ hobj, ULONG ulOwner)
 
INT NTAPI GreGetObject (IN HGDIOBJ hobj, IN INT cbCount, OUT PVOID pvBuffer)
 
W32KAPI INT APIENTRY NtGdiExtGetObjectW (IN HANDLE hobj, IN INT cjBufferSize, OUT LPVOID lpBuffer)
 
W32KAPI HANDLE APIENTRY NtGdiCreateClientObj (IN ULONG ulType)
 
W32KAPI BOOL APIENTRY NtGdiDeleteClientObj (IN HANDLE hobj)
 
PGDIOBJ NTAPI GDIOBJ_ShareLockObj (HGDIOBJ hObj, DWORD ExpectedType)
 
BOOL NTAPI GDIOBJ_ConvertToStockObj (HGDIOBJ *phObj)
 
BOOL NTAPI GDIOBJ_ConvertFromStockObj (HGDIOBJ *phObj)
 
POBJ NTAPI GDIOBJ_AllocObjWithHandle (ULONG ObjectType, ULONG cjSize)
 
PVOID NTAPI GDI_MapHandleTable (PEPROCESS pProcess)
 
BOOL NTAPI GDI_CleanupForProcess (struct _EPROCESS *Process)
 
PGDI_POOL GetBrushAttrPool (VOID)
 HACK!
 

Variables

static PVOID gpvGdiHdlTblSection = NULL
 
PENTRY gpentHmgr
 
PULONG gpaulRefCount
 
volatile ULONG gulFirstFree
 
volatile ULONG gulFirstUnused
 
static PPAGED_LOOKASIDE_LIST gpaLookasideList
 
static const GDICLEANUPPROC apfnCleanup []
 
static const GDIOBJDELETEPROC apfnDelete []
 
PGDI_HANDLE_TABLE GdiHandleTable = NULL
 

Macro Definition Documentation

◆ ASSERT_EXCLUSIVE_OBJECT_TYPE

#define ASSERT_EXCLUSIVE_OBJECT_TYPE (   objt)

Definition at line 126 of file gdiobj.c.

◆ ASSERT_LOCK_ORDER

#define ASSERT_LOCK_ORDER (   hobj)

Definition at line 124 of file gdiobj.c.

◆ ASSERT_SHARED_OBJECT_TYPE

#define ASSERT_SHARED_OBJECT_TYPE (   objt)

Definition at line 125 of file gdiobj.c.

◆ ASSERT_TRYLOCK_OBJECT_TYPE

#define ASSERT_TRYLOCK_OBJECT_TYPE (   objt)

Definition at line 127 of file gdiobj.c.

◆ GDIOBJ_POOL_TAG

#define GDIOBJ_POOL_TAG (   type)    ('00hG' + (((type) & 0x1f) << 24))

Definition at line 134 of file gdiobj.c.

◆ NDEBUG

#define NDEBUG

Definition at line 50 of file gdiobj.c.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
REF_MASK_REUSE 
REF_INC_REUSE 
REF_MASK_VALID 
REF_MASK_COUNT 
REF_MASK_INUSE 

Definition at line 136 of file gdiobj.c.

137{
138 REF_MASK_REUSE = 0xff000000,
139 REF_INC_REUSE = 0x01000000,
140 REF_MASK_VALID = 0x00800000,
141 REF_MASK_COUNT = 0x007fffff,
142 REF_MASK_INUSE = 0x00ffffff,
143};
@ REF_MASK_REUSE
Definition: gdiobj.c:138
@ REF_INC_REUSE
Definition: gdiobj.c:139
@ REF_MASK_COUNT
Definition: gdiobj.c:141
@ REF_MASK_INUSE
Definition: gdiobj.c:142
@ REF_MASK_VALID
Definition: gdiobj.c:140

Function Documentation

◆ DECREASE_THREAD_LOCK_COUNT()

FORCEINLINE void DECREASE_THREAD_LOCK_COUNT ( _In_ HANDLE  hobj)

Definition at line 79 of file gdiobj.c.

81{
84 if (pti)
85 {
86#if DBG
87 pti->acExclusiveLockCount[((ULONG_PTR)hobj >> 16) & 0x1f]--;
88#endif
89 pti->cExclusiveLocks--;
90 }
91}
#define ULONG_PTR
Definition: config.h:101
#define DBG_UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:318
PVOID NTAPI PsGetCurrentThreadWin32Thread(VOID)
Definition: thread.c:805
ULONG cExclusiveLocks
Definition: win32.h:158

Referenced by GDIOBJ_vDeleteObject(), and GDIOBJ_vUnlockObject().

◆ DecrementCurrentProcessGdiHandleCount()

FORCEINLINE VOID DecrementCurrentProcessGdiHandleCount ( void  )

Definition at line 340 of file gdiobj.c.

341{
343 if (ppi) InterlockedDecrement((LONG*)&ppi->GDIHandleCount);
344}
#define InterlockedDecrement
Definition: armddk.h:52
PVOID NTAPI PsGetCurrentProcessWin32Process(VOID)
Definition: process.c:1183
long LONG
Definition: pedump.c:60

Referenced by GDIOBJ_vDereferenceObject().

◆ DecrementGdiHandleCount()

static VOID DecrementGdiHandleCount ( ULONG  ulProcessId)
inlinestatic

Definition at line 365 of file gdiobj.c.

366{
367 PEPROCESS pep;
368 PPROCESSINFO ppi;
370
371 Status = PsLookupProcessByProcessId(ULongToHandle(ulProcessId), &pep);
374
375 ppi = PsGetProcessWin32Process(pep);
376 if (ppi) InterlockedDecrement((LONG*)&ppi->GDIHandleCount);
378}
LONG NTSTATUS
Definition: precomp.h:26
#define ULongToHandle(h)
Definition: basetsd.h:81
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
Status
Definition: gdiplustypes.h:25
#define __analysis_assume(expr)
Definition: ms_sal.h:2893
PVOID NTAPI PsGetProcessWin32Process(PEPROCESS Process)
Definition: process.c:1193
NTSTATUS NTAPI PsLookupProcessByProcessId(IN HANDLE ProcessId, OUT PEPROCESS *Process)
Definition: process.c:919
#define ObDereferenceObject
Definition: obfuncs.h:203
#define NT_ASSERT
Definition: rtlfuncs.h:3310

Referenced by GDIOBJ_vSetObjectOwner().

◆ ENTRY_hInsertObject()

static HGDIOBJ ENTRY_hInsertObject ( PENTRY  pentry,
POBJ  pobj,
UCHAR  objt,
ULONG  ulOwner 
)
static

Definition at line 539 of file gdiobj.c.

540{
541 ULONG ulIndex;
542
543 /* Calculate the handle index */
544 ulIndex = pentry - gpentHmgr;
545
546 /* Update the fields in the ENTRY */
547 pentry->einfo.pobj = pobj;
548 pentry->Objt = objt & 0x1f;
549 pentry->FullUnique = (pentry->FullUnique & 0xff00) | objt;
550 pentry->ObjectOwner.ulObj = ulOwner;
551
552 /* Make the handle valid with 1 reference */
553 ASSERT((gpaulRefCount[ulIndex] & REF_MASK_INUSE) == 0);
555
556 /* Return the handle */
557 return (HGDIOBJ)(((ULONG_PTR)pentry->FullUnique << 16) | ulIndex);
558}
#define InterlockedOr
Definition: interlocked.h:224
#define ASSERT(a)
Definition: mode.c:44
union _ENTRY::_OBJECTOWNER ObjectOwner
UCHAR Objt
Definition: ntgdihdl.h:236
union _ENTRY::_EINFO einfo
USHORT FullUnique
Definition: ntgdihdl.h:235
uint32_t ULONG
Definition: typedefs.h:59
struct _BASEOBJECT * pobj
Definition: ntgdihdl.h:221
ULONG ulObj
Definition: ntgdihdl.h:232
PENTRY gpentHmgr
Definition: gdiobj.c:149
PULONG gpaulRefCount
Definition: gdiobj.c:150

Referenced by GDIOBJ_hInsertObject().

◆ ENTRY_pentPopFreeEntry()

static PENTRY ENTRY_pentPopFreeEntry ( VOID  )
static

Definition at line 382 of file gdiobj.c.

383{
384 ULONG iFirst, iNext, iPrev;
385 PENTRY pentFree;
386
387 DPRINT("Enter InterLockedPopFreeEntry\n");
388
389 do
390 {
391 /* Get the index and sequence number of the first free entry */
393
394 /* Check if we have a free entry */
395 if (!(iFirst & GDI_HANDLE_INDEX_MASK))
396 {
397 /* Increment FirstUnused and get the new index */
399
400 /* Check if we have unused entries left */
401 if (iFirst >= GDI_HANDLE_COUNT)
402 {
403 DPRINT1("No more GDI handles left!\n");
404#if DBG_ENABLE_GDIOBJ_BACKTRACES
405 DbgDumpGdiHandleTableWithBT();
406#endif
408 return 0;
409 }
410
411 /* Return the old entry */
412 return &gpentHmgr[iFirst];
413 }
414
415 /* Get a pointer to the first free entry */
416 pentFree = &gpentHmgr[iFirst & GDI_HANDLE_INDEX_MASK];
417
418 /* Create a new value with an increased sequence number */
419 iNext = GDI_HANDLE_GET_INDEX(pentFree->einfo.hFree);
420 iNext |= (iFirst & ~GDI_HANDLE_INDEX_MASK) + 0x10000;
421
422 /* Try to exchange the FirstFree value */
424 iNext,
425 iFirst);
426 }
427 while (iPrev != iFirst);
428
429 /* Sanity check: is entry really free? */
430 ASSERT(((ULONG_PTR)pentFree->einfo.pobj & ~GDI_HANDLE_INDEX_MASK) == 0);
431
432 return pentFree;
433}
#define InterlockedIncrement
Definition: armddk.h:53
#define DPRINT1
Definition: precomp.h:8
#define GDI_HANDLE_GET_INDEX(h)
Definition: gdi.h:28
#define GDI_HANDLE_COUNT
Definition: gdi.h:12
#define GDI_HANDLE_INDEX_MASK
Definition: gdi.h:16
#define InterlockedCompareExchange
Definition: interlocked.h:104
#define DPRINT
Definition: sndvol32.h:71
Definition: ntgdihdl.h:218
uint32_t ULONG_PTR
Definition: typedefs.h:65
HGDIOBJ hFree
Definition: ntgdihdl.h:222
volatile ULONG gulFirstUnused
Definition: gdiobj.c:152
volatile ULONG gulFirstFree
Definition: gdiobj.c:151
FORCEINLINE ULONG InterlockedReadUlong(_In_ _Interlocked_operand_ ULONG volatile *Source)
Definition: gdiobj.c:55

Referenced by GDIOBJ_hInsertObject().

◆ ENTRY_ReferenceEntryByHandle()

static PENTRY ENTRY_ReferenceEntryByHandle ( HGDIOBJ  hobj,
FLONG  fl 
)
static

Definition at line 478 of file gdiobj.c.

479{
480 ULONG ulIndex, cNewRefs, cOldRefs;
481 PENTRY pentry;
482
483 /* Get the handle index and check if its too big */
484 ulIndex = GDI_HANDLE_GET_INDEX(hobj);
485
486 /* Get pointer to the entry */
487 pentry = &gpentHmgr[ulIndex];
488
489 /* Get the current reference count */
490 cOldRefs = gpaulRefCount[ulIndex];
491
492 do
493 {
494 /* Check if the slot is deleted */
495 if ((cOldRefs & REF_MASK_VALID) == 0)
496 {
497 DPRINT("GDIOBJ: Slot is not valid: 0x%lx, hobh=%p\n", cOldRefs, hobj);
498 return NULL;
499 }
500
501 /* Check if the unique value matches */
502 if (pentry->FullUnique != (USHORT)((ULONG_PTR)hobj >> 16))
503 {
504 DPRINT("GDIOBJ: Wrong unique value. Handle: 0x%4x, entry: 0x%4x\n",
505 (USHORT)((ULONG_PTR)hobj >> 16), pentry->FullUnique);
506 return NULL;
507 }
508
509 /* Check if the object owner is this process or public */
510 if (!(fl & GDIOBJFLAG_IGNOREPID) &&
513 {
514 DPRINT("GDIOBJ: Cannot reference foreign handle %p, pentry=%p:%lx.\n",
515 hobj, pentry, pentry->ObjectOwner.ulObj);
516 return NULL;
517 }
518
519 /* Try to atomically increment the reference count */
520 cNewRefs = cOldRefs + 1;
521 cOldRefs = InterlockedCompareExchange((PLONG)&gpaulRefCount[ulIndex],
522 cNewRefs,
523 cOldRefs);
524 }
525 while (cNewRefs != cOldRefs + 1);
526
527 /* Integrity checks */
528 ASSERT((pentry->FullUnique & 0x1f) == pentry->Objt);
529 ASSERT(pentry->einfo.pobj != NULL);
530
531 /* Check if lower 32 bits match, the upper 32 bits are ignored */
532 ASSERT(pentry->einfo.pobj->hHmgr == UlongToPtr(PtrToUlong(hobj)));
533
534 return pentry;
535}
#define NULL
Definition: types.h:112
#define UlongToPtr(u)
Definition: config.h:106
#define PtrToUlong(u)
Definition: config.h:107
@ GDIOBJFLAG_IGNOREPID
Definition: gdiobj.h:72
#define GDI_OBJ_HMGR_PUBLIC
Definition: ntgdihdl.h:116
HANDLE NTAPI PsGetCurrentProcessId(VOID)
Definition: process.c:1123
unsigned short USHORT
Definition: pedump.c:61
int32_t * PLONG
Definition: typedefs.h:58
_In_ FLONG fl
Definition: winddi.h:1279

Referenced by GDIOBJ_ConvertFromStockObj(), GDIOBJ_ConvertToStockObj(), GDIOBJ_LockObject(), GDIOBJ_ReferenceObjectByHandle(), GDIOBJ_TryLockObject(), GreDeleteObject(), GreIsHandleValid(), and GreSetObjectOwnerEx().

◆ ENTRY_vPushFreeEntry()

static VOID ENTRY_vPushFreeEntry ( PENTRY  pentFree)
static

Definition at line 439 of file gdiobj.c.

440{
441 ULONG iToFree, iFirst, iPrev, idxToFree;
442
443 DPRINT("Enter ENTRY_vPushFreeEntry\n");
444
445 idxToFree = pentFree - gpentHmgr;
446 ASSERT((gpaulRefCount[idxToFree] & REF_MASK_INUSE) == 0);
447
448 /* Initialize entry */
449 pentFree->Objt = GDIObjType_DEF_TYPE;
450 pentFree->ObjectOwner.ulObj = 0;
451 pentFree->pUser = NULL;
452
453 /* Increase reuse counter in entry and reference counter */
455 pentFree->FullUnique += 0x0100;
456
457 do
458 {
459 /* Get the current first free index and sequence number */
461
462 /* Set the einfo.pobj member to the index of the first free entry */
463 pentFree->einfo.pobj = UlongToPtr(iFirst & GDI_HANDLE_INDEX_MASK);
464
465 /* Combine new index and increased sequence number in iToFree */
466 iToFree = idxToFree | ((iFirst & ~GDI_HANDLE_INDEX_MASK) + 0x10000);
467
468 /* Try to atomically update the first free entry */
470 iToFree,
471 iFirst);
472 }
473 while (iPrev != iFirst);
474}
#define InterlockedExchangeAdd
Definition: interlocked.h:181
@ GDIObjType_DEF_TYPE
Definition: ntgdityp.h:120
PVOID pUser
Definition: ntgdihdl.h:238

Referenced by GDIOBJ_vDereferenceObject().

◆ GDI_CleanupForProcess()

BOOL NTAPI GDI_CleanupForProcess ( struct _EPROCESS Process)

Definition at line 1582 of file gdiobj.c.

1583{
1584 PENTRY pentry;
1585 ULONG ulIndex;
1586 DWORD dwProcessId;
1587 PPROCESSINFO ppi;
1588
1589 DPRINT("CleanupForProcess prochandle %p Pid %p\n",
1590 Process, Process->UniqueProcessId);
1591
1593
1594 /* Get the current process Id */
1595 dwProcessId = PtrToUlong(PsGetCurrentProcessId());
1596
1597 /* Loop all handles in the handle table */
1598 for (ulIndex = RESERVE_ENTRIES_COUNT; ulIndex < gulFirstUnused; ulIndex++)
1599 {
1600 pentry = &gpentHmgr[ulIndex];
1601
1602 /* Check if the object is owned by the process */
1603 if (pentry->ObjectOwner.ulObj == dwProcessId)
1604 {
1605 ASSERT(pentry->einfo.pobj->cExclusiveLock == 0);
1606
1607 /* Reference the object and delete it */
1610 }
1611 }
1612
1613#if DBG
1615#endif
1616
1618 DPRINT("Completed cleanup for process %p\n", Process->UniqueProcessId);
1619 if (ppi->GDIHandleCount != 0)
1620 {
1621 DPRINT1("Leaking %d handles!\n", ppi->GDIHandleCount);
1622 ASSERT(FALSE);
1623 }
1624
1625 /* Loop all handles in the handle table */
1626 for (ulIndex = RESERVE_ENTRIES_COUNT; ulIndex < gulFirstUnused; ulIndex++)
1627 {
1628 pentry = &gpentHmgr[ulIndex];
1629
1630 /* Check if the object is owned by the process */
1631 if (pentry->ObjectOwner.ulObj == dwProcessId)
1632 {
1633 DPRINT1("Leaking object. Index=%lx, type=0x%x, refcount=%lx\n",
1634 ulIndex, pentry->Objt, gpaulRefCount[ulIndex]);
1635 DBG_DUMP_EVENT_LIST(&pentry->einfo.pobj->slhLog);
1636 //DBG_CLEANUP_EVENT_LIST(&pentry->einfo.pobj->slhLog);
1637 ASSERT(FALSE);
1638 }
1639 }
1640
1641 return TRUE;
1642}
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
unsigned long DWORD
Definition: ntddk_ex.h:95
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
#define DBG_DUMP_EVENT_LIST(pslh)
Definition: gdidebug.h:111
BOOL NTAPI DbgGdiHTIntegrityCheck(VOID)
static const unsigned RESERVE_ENTRIES_COUNT
Definition: gdiobj.h:11
VOID NTAPI GDIOBJ_vDeleteObject(POBJ pobj)
Definition: gdiobj.c:1111
#define PsGetCurrentProcess
Definition: psfuncs.h:17

Referenced by GdiProcessDestroy().

◆ GDI_MapHandleTable()

PVOID NTAPI GDI_MapHandleTable ( PEPROCESS  pProcess)

Definition at line 1552 of file gdiobj.c.

1553{
1554 PVOID pvMappedView = NULL;
1556 LARGE_INTEGER liOffset;
1557 SIZE_T cjViewSize = sizeof(GDI_HANDLE_TABLE);
1558
1559 liOffset.QuadPart = 0;
1560
1562 ASSERT(pProcess != NULL);
1563
1565 pProcess,
1566 &pvMappedView,
1567 0,
1568 0,
1569 &liOffset,
1570 &cjViewSize,
1571 ViewUnmap,
1574
1575 if (!NT_SUCCESS(Status))
1576 return NULL;
1577
1578 return pvMappedView;
1579}
#define PAGE_READONLY
Definition: compat.h:138
struct _GDI_HANDLE_TABLE GDI_HANDLE_TABLE
#define SEC_NO_CHANGE
Definition: mmtypes.h:95
@ ViewUnmap
Definition: nt_native.h:1279
NTSTATUS NTAPI MmMapViewOfSection(IN PVOID SectionObject, IN PEPROCESS Process, IN OUT PVOID *BaseAddress, IN ULONG_PTR ZeroBits, IN SIZE_T CommitSize, IN OUT PLARGE_INTEGER SectionOffset OPTIONAL, IN OUT PSIZE_T ViewSize, IN SECTION_INHERIT InheritDisposition, IN ULONG AllocationType, IN ULONG Protect)
Definition: section.c:3996
ULONG_PTR SIZE_T
Definition: typedefs.h:80
LONGLONG QuadPart
Definition: typedefs.h:114
static PVOID gpvGdiHdlTblSection
Definition: gdiobj.c:148

Referenced by GdiProcessCreate().

◆ GDIOBJ_AllocateObject()

POBJ NTAPI GDIOBJ_AllocateObject ( UCHAR  objt,
ULONG  cjSize,
FLONG  fl 
)

Definition at line 562 of file gdiobj.c.

563{
564 POBJ pobj;
565
567 {
568 /* Allocate the object from a lookaside list */
569 pobj = ExAllocateFromPagedLookasideList(&gpaLookasideList[objt & 0x1f]);
570 }
571 else
572 {
573 /* Allocate the object from paged pool */
575 }
576
577 if (!pobj) return NULL;
578
579 /* Initialize the object */
580 RtlZeroMemory(pobj, cjSize);
581 pobj->hHmgr = (HGDIOBJ)((ULONG_PTR)objt << 16);
582 pobj->cExclusiveLock = 0;
583 pobj->ulShareCount = 1;
584 pobj->BaseFlags = fl & 0xffff;
585 DBG_INITLOG(&pobj->slhLog);
586 DBG_LOGEVENT(&pobj->slhLog, EVENT_ALLOCATE, 0);
587#if DBG_ENABLE_GDIOBJ_BACKTRACES
588 DbgCaptureStackBackTace(pobj->apvBackTrace, 1, GDI_OBJECT_STACK_LEVELS);
589#endif /* GDI_DEBUG */
590
591 return pobj;
592}
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PagedPool
Definition: env_spec_w32.h:308
#define DBG_LOGEVENT(pslh, type, val)
Definition: gdidebug.h:109
#define DBG_INITLOG(pslh)
Definition: gdidebug.h:110
ULONG NTAPI DbgCaptureStackBackTace(_Out_writes_(cFramesToCapture) PVOID *ppvFrames, _In_ ULONG cFramesToSkip, _In_ ULONG cFramesToCapture)
@ BASEFLAG_LOOKASIDE
Definition: gdiobj.h:58
#define GDI_OBJECT_STACK_LEVELS
Definition: gdiobj.h:8
HGDIOBJ hHmgr
Definition: gdiobj.h:40
USHORT BaseFlags
Definition: gdiobj.h:46
USHORT cExclusiveLock
Definition: gdiobj.h:45
ULONG ulShareCount
Definition: gdiobj.h:42
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
static PPAGED_LOOKASIDE_LIST gpaLookasideList
Definition: gdiobj.c:153
#define GDIOBJ_POOL_TAG(type)
Definition: gdiobj.c:134
_In_ ULONG cjSize
Definition: winddi.h:3634
void * HGDIOBJ
Definition: windef.h:252

Referenced by DC_AllocDcWithHandle(), GDIOBJ_AllocObjWithHandle(), IntSysCreateRectpRgn(), NtGdiCreateClientObj(), PALETTE_AllocPalette(), and REGION_AllocRgnWithHandle().

◆ GDIOBJ_AllocObjWithHandle()

POBJ NTAPI GDIOBJ_AllocObjWithHandle ( ULONG  ObjectType,
ULONG  cjSize 
)

Definition at line 1522 of file gdiobj.c.

1523{
1524 POBJ pobj;
1525 FLONG fl = 0;
1526 UCHAR objt = (ObjectType >> 16) & 0xFF;
1527
1528 if ((objt == GDIObjType_DC_TYPE && cjSize == sizeof(DC)) ||
1529 (objt == GDIObjType_PAL_TYPE && cjSize == sizeof(PALETTE)) ||
1530 (objt == GDIObjType_RGN_TYPE && cjSize == sizeof(REGION)) ||
1531 (objt == GDIObjType_SURF_TYPE && cjSize == sizeof(SURFACE)) ||
1532 (objt == GDIObjType_PATH_TYPE && cjSize == sizeof(PATH)))
1533 {
1535 }
1536
1537 pobj = GDIOBJ_AllocateObject(objt, cjSize, fl);
1538 if (!pobj)
1539 {
1540 return NULL;
1541 }
1542
1544 {
1545 GDIOBJ_vFreeObject(pobj);
1546 return NULL;
1547 }
1548 return pobj;
1549}
ObjectType
Definition: metafile.c:81
unsigned long FLONG
Definition: ntbasedef.h:366
#define GDI_OBJ_HMGR_POWNED
Definition: ntgdihdl.h:117
@ GDIObjType_PAL_TYPE
Definition: ntgdityp.h:128
@ GDIObjType_DC_TYPE
Definition: ntgdityp.h:121
@ GDIObjType_PATH_TYPE
Definition: ntgdityp.h:127
@ GDIObjType_RGN_TYPE
Definition: ntgdityp.h:124
@ GDIObjType_SURF_TYPE
Definition: ntgdityp.h:125
struct _PATH PATH
struct _REGION REGION
Definition: polytest.cpp:41
struct _SURFACE SURFACE
VOID NTAPI GDIOBJ_vFreeObject(POBJ pobj)
Definition: gdiobj.c:596
HGDIOBJ NTAPI GDIOBJ_hInsertObject(POBJ pobj, ULONG ulOwner)
Definition: gdiobj.c:912
POBJ NTAPI GDIOBJ_AllocateObject(UCHAR objt, ULONG cjSize, FLONG fl)
Definition: gdiobj.c:562
struct _PALETTE PALETTE
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by NtGdiCreateServerMetaFile(), PEN_AllocExtPenWithHandle(), PEN_AllocPenWithHandle(), and SURFACE_AllocSurface().

◆ GDIOBJ_bLockMultipleObjects()

BOOL NTAPI GDIOBJ_bLockMultipleObjects ( IN ULONG  ulCount,
IN HGDIOBJ ahObj,
OUT PGDIOBJ apObj,
IN UCHAR  objt 
)

Definition at line 1031 of file gdiobj.c.

1036{
1037 UINT auiIndices[3] = {0, 1, 2};
1038 UINT i, j, tmp;
1039
1040 ASSERT(ulCount <= 3);
1041
1042 /* Sort the handles */
1043 for (i = 0; i < ulCount - 1; i++)
1044 {
1045 for (j = i + 1; j < ulCount; j++)
1046 {
1047 if ((ULONG_PTR)ahObj[auiIndices[i]] <
1048 (ULONG_PTR)ahObj[auiIndices[j]])
1049 {
1050 tmp = auiIndices[i];
1051 auiIndices[i] = auiIndices[j];
1052 auiIndices[j] = tmp;
1053 }
1054 }
1055 }
1056
1057 /* Lock the objects in safe order */
1058 for (i = 0; i < ulCount; i++)
1059 {
1060 /* Skip NULL handles */
1061 if (ahObj[auiIndices[i]] == NULL)
1062 {
1063 apObj[auiIndices[i]] = NULL;
1064 continue;
1065 }
1066
1067 /* Lock the object */
1068 apObj[auiIndices[i]] = GDIOBJ_LockObject(ahObj[auiIndices[i]], objt);
1069
1070 /* Check for failure */
1071 if (apObj[auiIndices[i]] == NULL)
1072 {
1073 /* Cleanup */
1074 while (i--)
1075 {
1076 if (apObj[auiIndices[i]])
1077 GDIOBJ_vUnlockObject(apObj[auiIndices[i]]);
1078 }
1079 return FALSE;
1080 }
1081 }
1082
1083 return TRUE;
1084}
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
unsigned int UINT
Definition: ndis.h:50
PGDIOBJ NTAPI GDIOBJ_LockObject(HGDIOBJ hobj, UCHAR objt)
Definition: gdiobj.c:826
VOID NTAPI GDIOBJ_vUnlockObject(POBJ pobj)
Definition: gdiobj.c:880

Referenced by GreStretchBltMask(), NtGdiAlphaBlend(), NtGdiCombineRgn(), NtGdiEqualRgn(), NtGdiMaskBlt(), and NtGdiTransparentBlt().

◆ GDIOBJ_ConvertFromStockObj()

BOOL NTAPI GDIOBJ_ConvertFromStockObj ( HGDIOBJ phObj)

Definition at line 1489 of file gdiobj.c.

1490{
1491 PENTRY pentry;
1492 POBJ pobj;
1493
1494 /* Reference the handle entry */
1495 pentry = ENTRY_ReferenceEntryByHandle(*phObj, 0);
1496 if (!pentry)
1497 {
1498 DPRINT1("GDIOBJ: Requested handle 0x%p is not valid.\n", *phObj);
1499 return FALSE;
1500 }
1501
1502 /* Update the entry */
1503 pentry->FullUnique &= ~GDI_ENTRY_STOCK_MASK;
1505
1506 /* Get the pointer to the BASEOBJECT */
1507 pobj = pentry->einfo.pobj;
1508
1509 /* Calculate the new handle */
1510 pobj->hHmgr = (HGDIOBJ)((ULONG_PTR)pobj->hHmgr & ~GDI_HANDLE_STOCK_MASK);
1511
1512 /* Return the new handle */
1513 *phObj = pobj->hHmgr;
1514
1515 /* Dereference the handle */
1517
1518 return TRUE;
1519}
VOID NTAPI GDIOBJ_vDereferenceObject(POBJ pobj)
Definition: gdiobj.c:631
static PENTRY ENTRY_ReferenceEntryByHandle(HGDIOBJ hobj, FLONG fl)
Definition: gdiobj.c:478

Referenced by NtGdiClearBitmapAttributes(), and NtGdiClearBrushAttributes().

◆ GDIOBJ_ConvertToStockObj()

BOOL NTAPI GDIOBJ_ConvertToStockObj ( HGDIOBJ phObj)

Definition at line 1455 of file gdiobj.c.

1456{
1457 PENTRY pentry;
1458 POBJ pobj;
1459
1460 /* Reference the handle entry */
1461 pentry = ENTRY_ReferenceEntryByHandle(*phObj, 0);
1462 if (!pentry)
1463 {
1464 DPRINT1("GDIOBJ: Requested handle 0x%p is not valid.\n", *phObj);
1465 return FALSE;
1466 }
1467
1468 /* Update the entry */
1470 pentry->ObjectOwner.ulObj = 0;
1471
1472 /* Get the pointer to the BASEOBJECT */
1473 pobj = pentry->einfo.pobj;
1474
1475 /* Calculate the new handle */
1477
1478 /* Return the new handle */
1479 *phObj = pobj->hHmgr;
1480
1481 /* Dereference the handle */
1483
1484 return TRUE;
1485}
#define GDI_HANDLE_STOCK_MASK
Definition: gdi.h:19
#define GDI_ENTRY_STOCK_MASK
Definition: ntgdihdl.h:33

Referenced by CreateStockObjects(), CreateSysColorObjects(), NtGdiSetBitmapAttributes(), and NtGdiSetBrushAttributes().

◆ GDIOBJ_hInsertObject()

HGDIOBJ NTAPI GDIOBJ_hInsertObject ( POBJ  pobj,
ULONG  ulOwner 
)

Definition at line 912 of file gdiobj.c.

915{
916 PENTRY pentry;
917 UCHAR objt;
918
919 /* Must have no handle and only one reference */
920 ASSERT(GDI_HANDLE_GET_INDEX(pobj->hHmgr) == 0);
921 ASSERT(pobj->cExclusiveLock == 0);
922 ASSERT(pobj->ulShareCount == 1);
923
924 /* Get a free handle entry */
925 pentry = ENTRY_pentPopFreeEntry();
926 if (!pentry)
927 {
928 DPRINT1("GDIOBJ: Could not get a free entry.\n");
929 return NULL;
930 }
931
932 /* Make the object exclusively locked */
936 pobj->cExclusiveLock = 1;
939
940 /* Get object type from the hHmgr field */
941 objt = ((ULONG_PTR)pobj->hHmgr >> 16) & 0xff;
943
944 /* Check if current process is requested owner */
945 if (ulOwner == GDI_OBJ_HMGR_POWNED)
946 {
947 /* Increment the process handle count */
949
950 /* Use Process id */
952 }
953
954 /* Insert the object into the handle table */
955 pobj->hHmgr = ENTRY_hInsertObject(pentry, pobj, objt, ulOwner);
956
957 /* Return the handle */
958 DPRINT("GDIOBJ: Created handle: %p\n", pobj->hHmgr);
959 DBG_LOGEVENT(&pobj->slhLog, EVENT_CREATE_HANDLE, 0);
960 return pobj->hHmgr;
961}
#define HandleToUlong(h)
Definition: basetsd.h:79
#define ExInitializePushLock
Definition: ex.h:1013
FORCEINLINE VOID ExAcquirePushLockExclusive(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1036
PsGetCurrentThreadId
Definition: CrNtStubs.h:8
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
DWORD dwThreadId
Definition: gdiobj.h:43
EX_PUSH_LOCK pushlock
Definition: gdiobj.h:47
static PENTRY ENTRY_pentPopFreeEntry(VOID)
Definition: gdiobj.c:382
FORCEINLINE void INCREASE_THREAD_LOCK_COUNT(_In_ HANDLE hobj)
Definition: gdiobj.c:63
static HGDIOBJ ENTRY_hInsertObject(PENTRY pentry, POBJ pobj, UCHAR objt, ULONG ulOwner)
Definition: gdiobj.c:539
FORCEINLINE VOID IncrementCurrentProcessGdiHandleCount(void)
Definition: gdiobj.c:332

Referenced by DC_AllocDcWithHandle(), EngCreatePalette(), GDIOBJ_AllocObjWithHandle(), BASEOBJECT::hInsertObject(), NtGdiCreateClientObj(), PALETTE_AllocPalWithHandle(), and REGION_AllocRgnWithHandle().

◆ GDIOBJ_LockObject()

PGDIOBJ NTAPI GDIOBJ_LockObject ( HGDIOBJ  hobj,
UCHAR  objt 
)

Definition at line 826 of file gdiobj.c.

829{
830 PENTRY pentry;
831 POBJ pobj;
833
834 /* Check if the handle type matches */
836 if ((((ULONG_PTR)hobj >> 16) & 0x1f) != objt)
837 {
838 DPRINT("Wrong object type: hobj=0x%p, objt=0x%x\n", hobj, objt);
839 return NULL;
840 }
841
842 /* Make sure lock order is correct */
843 ASSERT_LOCK_ORDER(objt);
844
845 /* Reference the handle entry */
846 pentry = ENTRY_ReferenceEntryByHandle(hobj, 0);
847 if (!pentry)
848 {
849 DPRINT("GDIOBJ: Requested handle 0x%p is not valid.\n", hobj);
850 return NULL;
851 }
852
853 /* Get the pointer to the BASEOBJECT */
854 pobj = pentry->einfo.pobj;
855
856 /* Check if we already own the lock */
858 if (pobj->dwThreadId != dwThreadId)
859 {
860 /* Disable APCs and acquire the push lock */
863
864 /* Set us as lock owner */
865 ASSERT(pobj->dwThreadId == 0);
866 pobj->dwThreadId = dwThreadId;
867 }
868
869 /* Increase lock count */
870 pobj->cExclusiveLock++;
872 DBG_LOGEVENT(&pobj->slhLog, EVENT_LOCK, 0);
873
874 /* Return the object */
875 return pobj;
876}
DWORD dwThreadId
Definition: fdebug.c:31
#define ASSERT_LOCK_ORDER(hobj)
Definition: gdiobj.c:124
#define ASSERT_EXCLUSIVE_OBJECT_TYPE(objt)
Definition: gdiobj.c:126

Referenced by DC_LockDc(), GDIOBJ_bLockMultipleObjects(), NtGdiGetServerMetaFileBits(), and REGION_LockRgn().

◆ GDIOBJ_pvGetObjectAttr()

PVOID NTAPI GDIOBJ_pvGetObjectAttr ( POBJ  pobj)

Definition at line 1088 of file gdiobj.c.

1089{
1090 ULONG ulIndex = GDI_HANDLE_GET_INDEX(pobj->hHmgr);
1091 return gpentHmgr[ulIndex].pUser;
1092}

◆ GDIOBJ_ReferenceObjectByHandle()

POBJ NTAPI GDIOBJ_ReferenceObjectByHandle ( HGDIOBJ  hobj,
UCHAR  objt 
)

Definition at line 691 of file gdiobj.c.

694{
695 PENTRY pentry;
696 POBJ pobj;
697
698 /* Check if the handle type matches */
700 if ((((ULONG_PTR)hobj >> 16) & 0x1f) != objt)
701 {
702 DPRINT("GDIOBJ: Wrong type. handle=%p, type=%x\n", hobj, objt);
703 return NULL;
704 }
705
706 /* Reference the handle entry */
707 pentry = ENTRY_ReferenceEntryByHandle(hobj, 0);
708 if (!pentry)
709 {
710 DPRINT("GDIOBJ: Requested handle 0x%p is not valid.\n", hobj);
711 return NULL;
712 }
713
714 /* Get the pointer to the BASEOBJECT */
715 pobj = pentry->einfo.pobj;
716
717 /* Check if the object is exclusively locked */
718 if (pobj->cExclusiveLock != 0)
719 {
720 DPRINT1("GDIOBJ: Cannot reference object %p with exclusive lock.\n", hobj);
722 DBG_DUMP_EVENT_LIST(&pobj->slhLog);
723 return NULL;
724 }
725
726 DBG_LOGEVENT(&pobj->slhLog, EVENT_REFERENCE, gpaulRefCount[pentry - gpentHmgr]);
727
728 /* All is well, return the object */
729 return pobj;
730}
#define ASSERT_SHARED_OBJECT_TYPE(objt)
Definition: gdiobj.c:125

Referenced by GDIOBJ_ShareLockObj(), GreGetObject(), and PEN_ShareLockPen().

◆ GDIOBJ_ShareLockObj()

PGDIOBJ NTAPI GDIOBJ_ShareLockObj ( HGDIOBJ  hObj,
DWORD  ExpectedType 
)

Definition at line 1443 of file gdiobj.c.

1444{
1445 if (ExpectedType == GDI_OBJECT_TYPE_DONTCARE)
1446 ExpectedType = GDI_HANDLE_GET_TYPE(hObj);
1447 return GDIOBJ_ReferenceObjectByHandle(hObj, (ExpectedType >> 16) & 0x1f);
1448}
#define GDI_OBJECT_TYPE_DONTCARE
Definition: gdi.h:64
#define GDI_HANDLE_GET_TYPE(h)
Definition: gdi.h:31
POBJ NTAPI GDIOBJ_ReferenceObjectByHandle(HGDIOBJ hobj, UCHAR objt)
Definition: gdiobj.c:691

Referenced by BASEOBJECT::LockShared().

◆ GDIOBJ_TryLockObject()

PGDIOBJ NTAPI GDIOBJ_TryLockObject ( HGDIOBJ  hobj,
UCHAR  objt 
)

Definition at line 757 of file gdiobj.c.

760{
761 PENTRY pentry;
762 POBJ pobj;
764
765 /* Check if the handle type matches */
767 if ((((ULONG_PTR)hobj >> 16) & 0x1f) != objt)
768 {
769 DPRINT("Wrong object type: hobj=0x%p, objt=0x%x\n", hobj, objt);
770 return NULL;
771 }
772
773 /* Make sure lock order is correct */
774 ASSERT_LOCK_ORDER(objt);
775
776 /* Reference the handle entry */
777 pentry = ENTRY_ReferenceEntryByHandle(hobj, 0);
778 if (!pentry)
779 {
780 DPRINT("GDIOBJ: Requested handle 0x%p is not valid.\n", hobj);
781 return NULL;
782 }
783
784 /* Get the pointer to the BASEOBJECT */
785 pobj = pentry->einfo.pobj;
786
787 /* Check if we already own the lock */
789 if (pobj->dwThreadId != dwThreadId)
790 {
791 /* Disable APCs and try acquiring the push lock */
794 {
795 ULONG cRefs, ulIndex;
796 /* Already owned. Clean up and leave. */
798
799 /* Calculate the index */
800 ulIndex = GDI_HANDLE_GET_INDEX(pobj->hHmgr);
801
802 /* Decrement reference count */
803 ASSERT((gpaulRefCount[ulIndex] & REF_MASK_COUNT) > 0);
804 cRefs = InterlockedDecrement((LONG*)&gpaulRefCount[ulIndex]);
805 ASSERT(cRefs & REF_MASK_VALID);
806
807 return NULL;
808 }
809
810 /* Set us as lock owner */
811 ASSERT(pobj->dwThreadId == 0);
812 pobj->dwThreadId = dwThreadId;
813 }
814
815 /* Increase lock count */
816 pobj->cExclusiveLock++;
818 DBG_LOGEVENT(&pobj->slhLog, EVENT_LOCK, 0);
819
820 /* Return the object */
821 return pobj;
822}
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
#define ASSERT_TRYLOCK_OBJECT_TYPE(objt)
Definition: gdiobj.c:127
FORCEINLINE BOOLEAN ExTryAcquirePushLockExclusive(PEX_PUSH_LOCK PushLock)
Definition: misc.h:104

Referenced by DRIVEROBJ_TryLockObject().

◆ GDIOBJ_vCleanup()

static VOID NTAPI GDIOBJ_vCleanup ( PVOID  ObjectBody)
static

Definition at line 238 of file gdiobj.c.

239{
240 /* Nothing to do */
241}

◆ GDIOBJ_vDeleteObject()

VOID NTAPI GDIOBJ_vDeleteObject ( POBJ  pobj)

Definition at line 1111 of file gdiobj.c.

1112{
1113 ULONG ulIndex;
1114
1115 /* Set the object's delete flag */
1117 DBG_LOGEVENT(&pobj->slhLog, EVENT_DELETE, 0);
1118
1119 /* Get the handle index */
1120 ulIndex = GDI_HANDLE_GET_INDEX(pobj->hHmgr);
1121 if (ulIndex)
1122 {
1123 /* Reset the handle valid bit */
1125
1126 /* Check if the object is exclusively locked */
1127 if (pobj->cExclusiveLock != 0)
1128 {
1129 /* Reset lock owner and lock count */
1130 pobj->dwThreadId = 0;
1131 pobj->cExclusiveLock = 0;
1132
1133 /* Release the pushlock and reenable APCs */
1137 }
1138 }
1139
1140 /* Dereference the object (will take care of deletion) */
1142}
FORCEINLINE VOID ExReleasePushLockExclusive(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1252
@ BASEFLAG_READY_TO_DIE
Definition: gdiobj.h:61
#define InterlockedOr16
Definition: interlocked.h:239
#define InterlockedAnd
Definition: interlocked.h:62
short SHORT
Definition: pedump.c:59
FORCEINLINE void DECREASE_THREAD_LOCK_COUNT(_In_ HANDLE hobj)
Definition: gdiobj.c:79

Referenced by EngDeleteDriverObj(), EngDeletePalette(), EngDeletePath(), EngDeleteSurface(), GDI_CleanupForProcess(), GreDeleteObject(), IntEngMaskBlt(), IntGdiExtCreatePen(), NtGdiCreateBitmap(), NtGdiCreatePaletteInternal(), NtGdiCreateServerMetaFile(), NtGdiGetPixel(), PATH_Delete(), REGION_AllocRgnWithHandle(), REGION_Delete(), SURFACE_AllocSurface(), and UserDrawIconEx().

◆ GDIOBJ_vDereferenceObject()

VOID NTAPI GDIOBJ_vDereferenceObject ( POBJ  pobj)

Definition at line 631 of file gdiobj.c.

632{
633 ULONG cRefs, ulIndex;
634
635 /* Calculate the index */
636 ulIndex = GDI_HANDLE_GET_INDEX(pobj->hHmgr);
637
638 /* Check if the object has a handle */
639 if (ulIndex)
640 {
641 /* Decrement reference count */
642 if ((gpaulRefCount[ulIndex] & REF_MASK_COUNT) == 0)
643 {
644 DBG_DUMP_EVENT_LIST(&pobj->slhLog);
645 }
646 ASSERT((gpaulRefCount[ulIndex] & REF_MASK_COUNT) > 0);
647 cRefs = InterlockedDecrement((LONG*)&gpaulRefCount[ulIndex]);
648 DBG_LOGEVENT(&pobj->slhLog, EVENT_DEREFERENCE, cRefs);
649
650 /* Check if we reached 0 and handle bit is not set */
651 if ((cRefs & REF_MASK_INUSE) == 0)
652 {
653 /* Make sure it's ok to delete the object */
655
656 /* Check if the handle was process owned */
657 if (gpentHmgr[ulIndex].ObjectOwner.ulObj != GDI_OBJ_HMGR_PUBLIC &&
659 {
660 /* Decrement the process handle count */
661 ASSERT(gpentHmgr[ulIndex].ObjectOwner.ulObj ==
664 }
665
666 /* Push entry to the free list */
668
669 /* Free the object */
670 GDIOBJ_vFreeObject(pobj);
671 }
672 }
673 else
674 {
675 /* Decrement the objects reference count */
676 ASSERT(pobj->ulShareCount > 0);
677 cRefs = InterlockedDecrement((LONG*)&pobj->ulShareCount);
678 DBG_LOGEVENT(&pobj->slhLog, EVENT_DEREFERENCE, cRefs);
679
680 /* Check if we reached 0 */
681 if (cRefs == 0)
682 {
683 /* Free the object */
684 GDIOBJ_vFreeObject(pobj);
685 }
686 }
687}
#define GDI_OBJ_HMGR_NONE
Definition: ntgdihdl.h:118
static VOID ENTRY_vPushFreeEntry(PENTRY pentFree)
Definition: gdiobj.c:439
FORCEINLINE VOID DecrementCurrentProcessGdiHandleCount(void)
Definition: gdiobj.c:340

Referenced by GDIOBJ_ConvertFromStockObj(), GDIOBJ_ConvertToStockObj(), GDIOBJ_ReferenceObjectByHandle(), GDIOBJ_vDeleteObject(), GreDeleteObject(), GreGetObject(), GreIsHandleValid(), GreSetObjectOwnerEx(), NtGdiSetColorSpace(), SURFACE_vSetPalette(), and BASEOBJECT::vUnlock().

◆ GDIOBJ_vFreeObject()

VOID NTAPI GDIOBJ_vFreeObject ( POBJ  pobj)

Definition at line 596 of file gdiobj.c.

597{
598 UCHAR objt;
599
600 DBG_CLEANUP_EVENT_LIST(&pobj->slhLog);
601
602 /* Get the object type */
603 objt = ((ULONG_PTR)pobj->hHmgr >> 16) & 0x1f;
604
605 /* Check if we have a delete procedure (for C++ based objects) */
606 if (apfnDelete[objt] != NULL)
607 {
608 /* Invoke the delete procedure */
609 apfnDelete[objt](pobj);
610 }
611 else
612 {
613 /* Call the cleanup procedure */
614 NT_ASSERT(apfnCleanup[objt]);
615 apfnCleanup[objt](pobj);
616
617 /* Check if the object is allocated from a lookaside list */
618 if (pobj->BaseFlags & BASEFLAG_LOOKASIDE)
619 {
620 ExFreeToPagedLookasideList(&gpaLookasideList[objt], pobj);
621 }
622 else
623 {
625 }
626 }
627}
#define DBG_CLEANUP_EVENT_LIST(pslh)
Definition: gdidebug.h:112
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
static const GDICLEANUPPROC apfnCleanup[]
Definition: gdiobj.c:159
static const GDIOBJDELETEPROC apfnDelete[]
Definition: gdiobj.c:197

Referenced by DC_AllocDcWithHandle(), EngCreatePalette(), GDIOBJ_AllocObjWithHandle(), GDIOBJ_vDereferenceObject(), NtGdiCreateClientObj(), PALETTE_AllocPalWithHandle(), and REGION_AllocRgnWithHandle().

◆ GDIOBJ_vReferenceObjectByPointer()

VOID NTAPI GDIOBJ_vReferenceObjectByPointer ( POBJ  pobj)

Definition at line 734 of file gdiobj.c.

735{
736 ULONG cRefs;
737
738 /* Check if the object has a handle */
739 if (GDI_HANDLE_GET_INDEX(pobj->hHmgr))
740 {
741 /* Increase the handle's reference count */
742 ULONG ulIndex = GDI_HANDLE_GET_INDEX(pobj->hHmgr);
743 ASSERT((gpaulRefCount[ulIndex] & REF_MASK_COUNT) > 0);
744 cRefs = InterlockedIncrement((LONG*)&gpaulRefCount[ulIndex]);
745 }
746 else
747 {
748 /* Increase the object's reference count */
749 cRefs = InterlockedIncrement((LONG*)&pobj->ulShareCount);
750 }
751
752 DBG_LOGEVENT(&pobj->slhLog, EVENT_REFERENCE, cRefs);
753}

Referenced by DC_vCopyState(), DC_vSelectFillBrush(), DC_vSelectLineBrush(), DC_vSelectPalette(), DC_vSelectSurface(), EBRUSHOBJ_vInit(), InitPaletteImpl(), PDEVOBJ_pSurface(), SURFACE_ShareLockByPointer(), and SURFACE_vSetPalette().

◆ GDIOBJ_vSetObjectAttr()

VOID NTAPI GDIOBJ_vSetObjectAttr ( POBJ  pobj,
PVOID  pvObjAttr 
)

Definition at line 1096 of file gdiobj.c.

1097{
1098 ULONG ulIndex;
1099
1100 ASSERT(pobj->hHmgr);
1101
1102 /* Get the handle index */
1103 ulIndex = GDI_HANDLE_GET_INDEX(pobj->hHmgr);
1104
1105 /* Set pointer to the usermode attribute */
1106 gpentHmgr[ulIndex].pUser = pvObjAttr;
1107}

Referenced by DC_bAllocDcAttr(), DC_vFreeDcAttr(), IntGdiSetRegionOwner(), REGION_bAllocRgnAttr(), and BASEOBJECT::vSetObjectAttr().

◆ GDIOBJ_vSetObjectOwner()

VOID NTAPI GDIOBJ_vSetObjectOwner ( POBJ  pobj,
ULONG  ulNewOwner 
)

Definition at line 965 of file gdiobj.c.

968{
969 PENTRY pentry;
970 ULONG ulOldOwner;
971
972 /* This is a ugly HACK, needed to fix IntGdiSetDCOwnerEx */
973 if (GDI_HANDLE_IS_STOCKOBJ(pobj->hHmgr))
974 {
975 DPRINT("Trying to set ownership of stock object %p to %lx\n", pobj->hHmgr, ulNewOwner);
976 return;
977 }
978
979 /* Get the handle entry */
981 pentry = &gpentHmgr[GDI_HANDLE_GET_INDEX(pobj->hHmgr)];
982
983 /* Check if the new owner is the same as the old one */
984 ulOldOwner = pentry->ObjectOwner.ulObj;
985 if (ulOldOwner == ulNewOwner)
986 {
987 /* Nothing to do */
988 return;
989 }
990
991 /* Is the current process requested? */
992 if (ulNewOwner == GDI_OBJ_HMGR_POWNED)
993 {
994 /* Use process id */
995 ulNewOwner = HandleToUlong(PsGetCurrentProcessId());
996 }
997
998 // HACK
999 if (ulNewOwner == GDI_OBJ_HMGR_NONE)
1000 ulNewOwner = GDI_OBJ_HMGR_PUBLIC;
1001
1002 /* Was the object process owned? */
1003 if ((ulOldOwner != GDI_OBJ_HMGR_PUBLIC) &&
1004 (ulOldOwner != GDI_OBJ_HMGR_NONE))
1005 {
1006 /* Decrement the previous owners handle count */
1007 DecrementGdiHandleCount(ulOldOwner);
1008 }
1009
1010 /* Is the new owner a process? */
1011 if ((ulNewOwner != GDI_OBJ_HMGR_PUBLIC) &&
1012 (ulNewOwner != GDI_OBJ_HMGR_NONE))
1013 {
1014 /* Increment the new owners handle count */
1015 IncrementGdiHandleCount(ulNewOwner);
1016 }
1017 else
1018 {
1019 /* Make sure we don't leak user mode memory */
1020 NT_ASSERT(pentry->pUser == NULL);
1021 }
1022
1023 /* Set new owner */
1024 pentry->ObjectOwner.ulObj = ulNewOwner;
1025 DBG_LOGEVENT(&pobj->slhLog, EVENT_SET_OWNER, 0);
1026}
#define GDI_HANDLE_IS_STOCKOBJ(h)
Definition: gdi.h:37
static VOID IncrementGdiHandleCount(ULONG ulProcessId)
Definition: gdiobj.c:348
static VOID DecrementGdiHandleCount(ULONG ulProcessId)
Definition: gdiobj.c:365

Referenced by DC_vSetOwner(), EngCreateBitmap(), EngCreateDeviceBitmap(), EngCreateDeviceSurface(), GreSetObjectOwnerEx(), NtGdiCreateServerMetaFile(), and NtGdiSaveDC().

◆ GDIOBJ_vUnlockObject()

VOID NTAPI GDIOBJ_vUnlockObject ( POBJ  pobj)

Definition at line 880 of file gdiobj.c.

881{
882 ULONG cRefs, ulIndex;
883 ASSERT(pobj->cExclusiveLock > 0);
884
885 /* Decrease lock count */
886 pobj->cExclusiveLock--;
888 DBG_LOGEVENT(&pobj->slhLog, EVENT_UNLOCK, 0);
889
890 /* Check if this was the last lock */
891 if (pobj->cExclusiveLock == 0)
892 {
893 /* Reset lock owner */
894 pobj->dwThreadId = 0;
895
896 /* Release the pushlock and reenable APCs */
899 }
900
901 /* Calculate the index */
902 ulIndex = GDI_HANDLE_GET_INDEX(pobj->hHmgr);
903
904 /* Decrement reference count */
905 ASSERT((gpaulRefCount[ulIndex] & REF_MASK_COUNT) > 0);
906 cRefs = InterlockedDecrement((LONG*)&gpaulRefCount[ulIndex]);
907 ASSERT(cRefs & REF_MASK_VALID);
908}

Referenced by DC_UnlockDc(), GDIOBJ_bLockMultipleObjects(), GreStretchBltMask(), NtGdiAlphaBlend(), NtGdiCreateClientObj(), NtGdiCreateServerMetaFile(), NtGdiGetServerMetaFileBits(), NtGdiTransparentBlt(), PATH_CreatePath(), REGION_UnlockRgn(), and BASEOBJECT::vUnlock().

◆ GetBrushAttrPool()

PGDI_POOL GetBrushAttrPool ( VOID  )

HACK!

Definition at line 1646 of file gdiobj.c.

1647{
1648 PPROCESSINFO ppi;
1649
1651 NT_ASSERT(ppi != NULL);
1652
1653 return ppi->pPoolBrushAttr;
1654}
struct _GDI_POOL * pPoolBrushAttr
Definition: win32.h:292

◆ GreDeleteObject()

BOOL NTAPI GreDeleteObject ( HGDIOBJ  hobj)

Definition at line 1158 of file gdiobj.c.

1159{
1160 PENTRY pentry;
1161
1162 /* Check for stock objects */
1163 if (GDI_HANDLE_IS_STOCKOBJ(hobj))
1164 {
1165 DPRINT1("GreDeleteObject: Cannot delete stock object %p.\n", hobj);
1166 return FALSE;
1167 }
1168
1169 /* Reference the handle entry */
1170 pentry = ENTRY_ReferenceEntryByHandle(hobj, 0);
1171 if (!pentry)
1172 {
1173 DPRINT1("GreDeleteObject: Trying to delete invalid object %p\n", hobj);
1174 return FALSE;
1175 }
1176
1177 /* Check for public owner */
1178 if (pentry->ObjectOwner.ulObj == GDI_OBJ_HMGR_PUBLIC)
1179 {
1180 DPRINT1("GreDeleteObject: Trying to delete global object %p\n", hobj);
1182 return FALSE;
1183 }
1184
1185 /* Delete the object */
1187 return TRUE;
1188}

Referenced by BITMAP_CopyBitmap(), co_IntDrawCaret(), co_IntPaintWindows(), co_UserExcludeUpdateRgn(), co_UserFreeWindow(), co_UserGetUpdateRgn(), co_WinPosSetWindowPos(), CreateBrushInternal(), DC_vRestoreDC(), DceDeleteClipRgn(), DceFreeDCE(), DefWndDoSizeMove(), DIB_CreateDIBSection(), DrawTextExWorker(), ForceNCPaintErase(), FreeCurIconObject(), GdiFlushUserBatch(), GreGetDIBitsInternal(), IntBeginPaint(), IntCreateDIBitmap(), IntDefWindowProc(), IntDestroyMonitorObject(), IntEndDesktopGraphics(), IntFreeElementData(), IntGdiCreateMaskFromRLE(), IntGdiDeleteColorSpace(), IntGdiDeleteDC(), IntGetNCUpdateRgn(), IntInvalidateWindows(), IntPaintDesktop(), IntSetDIBits(), IntUpdateLayeredWindowI(), MENU_DrawPopupGlyph(), MenuInit(), NC_HandleNCActivate(), NtGdiDeleteClientObj(), NtGdiDeleteObjectApp(), NtGdiExtCreateRegion(), NtGdiFrameRgn(), NtGdiStretchDIBitsInternal(), PaintSuspendedWindow(), REGION_XorRegion(), SelectWindowRgn(), SnapWindow(), SpiSetWallpaper(), TEXT_DrawUnderscore(), UITOOLS95_DFC_ButtonCheckRadio(), UITOOLS95_DrawFrameCaption(), UITOOLS95_DrawFrameMenu(), UITOOLS95_DrawFrameScroll(), UserDrawCaptionText(), UserGetDCEx(), UserUpdateMonitorSize(), and BRUSH::~BRUSH().

◆ GreGetObject()

INT NTAPI GreGetObject ( IN HGDIOBJ  hobj,
IN INT  cbCount,
OUT PVOID  pvBuffer 
)

Definition at line 1264 of file gdiobj.c.

1268{
1269 PVOID pvObj;
1270 UCHAR objt;
1271 INT iResult = 0;
1272
1273 /* Verify object type */
1274 objt = ((ULONG_PTR)hobj >> 16) & 0x1f;
1275 if (objt != GDIObjType_BRUSH_TYPE &&
1276 objt != GDIObjType_SURF_TYPE &&
1277 objt != GDIObjType_LFONT_TYPE &&
1278 objt != GDIObjType_PAL_TYPE)
1279 {
1280 DPRINT1("GreGetObject: Invalid object type\n");
1281 return 0;
1282 }
1283
1284 pvObj = GDIOBJ_ReferenceObjectByHandle(hobj, objt);
1285 if (!pvObj)
1286 {
1287 DPRINT("GreGetObject: Could not lock object\n");
1288 return 0;
1289 }
1290
1291 switch (GDI_HANDLE_GET_TYPE(hobj))
1292 {
1295 iResult = PEN_GetObject(pvObj, cbCount, pvBuffer);
1296 break;
1297
1299 iResult = BRUSH_GetObject(pvObj, cbCount, pvBuffer);
1300 break;
1301
1303 iResult = BITMAP_GetObject(pvObj, cbCount, pvBuffer);
1304 break;
1305
1307 iResult = FontGetObject(pvObj, cbCount, pvBuffer);
1308 break;
1309
1311 iResult = PALETTE_GetObject(pvObj, cbCount, pvBuffer);
1312 break;
1313
1314 default:
1315 DPRINT1("GDI object type of 0x%p not implemented\n", hobj);
1316 break;
1317 }
1318
1320 return iResult;
1321}
INT APIENTRY BITMAP_GetObject(SURFACE *psurf, INT Count, LPVOID buffer)
Definition: bitmaps.c:771
INT FASTCALL BRUSH_GetObject(PBRUSH pbr, INT cjBuffer, LPLOGBRUSH plbBuffer)
Definition: brush.cpp:271
@ GDILoObjType_LO_FONT_TYPE
Definition: gdi_private.h:37
@ GDILoObjType_LO_PALETTE_TYPE
Definition: gdi_private.h:36
@ GDILoObjType_LO_BRUSH_TYPE
Definition: gdi_private.h:33
@ GDILoObjType_LO_BITMAP_TYPE
Definition: gdi_private.h:35
@ GDILoObjType_LO_EXTPEN_TYPE
Definition: gdi_private.h:45
@ GDILoObjType_LO_PEN_TYPE
Definition: gdi_private.h:44
static int cbCount
Definition: fiber.c:42
@ GDIObjType_LFONT_TYPE
Definition: ntgdityp.h:130
@ GDIObjType_BRUSH_TYPE
Definition: ntgdityp.h:136
int32_t INT
Definition: typedefs.h:58
ULONG FASTCALL FontGetObject(PTEXTOBJ plfont, ULONG cjBuffer, PVOID pvBuffer)
Definition: font.c:293
INT FASTCALL PALETTE_GetObject(PPALETTE ppal, INT cbCount, LPLOGBRUSH lpBuffer)
Definition: palette.c:247
INT APIENTRY PEN_GetObject(PBRUSH pbrushPen, INT cbCount, PLOGPEN pBuffer)
Definition: pen.c:290

Referenced by IntTMWFixUp(), IntUpdateLayeredWindowI(), MENU_DrawBitmapItem(), MENU_GetBitmapItemSize(), NtGdiExtGetObjectW(), and PATH_WidenPathEx().

◆ GreGetObjectOwner()

ULONG NTAPI GreGetObjectOwner ( HGDIOBJ  hobj)

Definition at line 1192 of file gdiobj.c.

1193{
1194 ULONG ulIndex, ulOwner;
1195
1196 /* Get the handle index */
1197 ulIndex = GDI_HANDLE_GET_INDEX(hobj);
1198
1199 /* Check if the handle is valid */
1200 if (ulIndex >= GDI_HANDLE_COUNT ||
1201 gpentHmgr[ulIndex].Objt == GDIObjType_DEF_TYPE ||
1202 ((ULONG_PTR)hobj >> 16) != gpentHmgr[ulIndex].FullUnique)
1203 {
1204 DPRINT1("GreGetObjectOwner: invalid handle 0x%p.\n", hobj);
1206 }
1207
1208 /* Get the object owner */
1209 ulOwner = gpentHmgr[ulIndex].ObjectOwner.ulObj;
1210
1211 if (ulOwner == HandleToUlong(PsGetCurrentProcessId()))
1212 return GDI_OBJ_HMGR_POWNED;
1213
1214 if (ulOwner == GDI_OBJ_HMGR_PUBLIC)
1215 return GDI_OBJ_HMGR_PUBLIC;
1216
1218}
#define GDI_OBJ_HMGR_RESTRICTED
Definition: ntgdihdl.h:119

Referenced by DceFreeDCE(), GreSetBitmapOwner(), NtGdiDeleteObjectApp(), REGION_UnlockRgn(), and REGION_vSyncRegion().

◆ GreIsHandleValid()

◆ GreSetObjectOwner()

BOOL NTAPI GreSetObjectOwner ( HGDIOBJ  hobj,
ULONG  ulOwner 
)

◆ GreSetObjectOwnerEx()

BOOL NTAPI GreSetObjectOwnerEx ( HGDIOBJ  hobj,
ULONG  ulOwner,
ULONG  Flags 
)

Definition at line 1222 of file gdiobj.c.

1226{
1227 PENTRY pentry;
1228
1229 /* Check for stock objects */
1230 if (GDI_HANDLE_IS_STOCKOBJ(hobj))
1231 {
1232 DPRINT("GreSetObjectOwner: Got stock object %p\n", hobj);
1233 return FALSE;
1234 }
1235
1236 /* Reference the handle entry */
1237 pentry = ENTRY_ReferenceEntryByHandle(hobj, Flags);
1238 if (!pentry)
1239 {
1240 DPRINT("GreSetObjectOwner: Invalid handle 0x%p.\n", hobj);
1241 return FALSE;
1242 }
1243
1244 /* Call internal function */
1245 GDIOBJ_vSetObjectOwner(pentry->einfo.pobj, ulOwner);
1246
1247 /* Dereference the object */
1249
1250 return TRUE;
1251}
VOID NTAPI GDIOBJ_vSetObjectOwner(POBJ pobj, ULONG ulNewOwner)
Definition: gdiobj.c:965
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170

Referenced by GreSetObjectOwner(), and NtUserConsoleControl().

◆ INCREASE_THREAD_LOCK_COUNT()

FORCEINLINE void INCREASE_THREAD_LOCK_COUNT ( _In_ HANDLE  hobj)

Definition at line 63 of file gdiobj.c.

65{
68 if (pti)
69 {
70#if DBG
71 pti->acExclusiveLockCount[((ULONG_PTR)hobj >> 16) & 0x1f]++;
72#endif
73 pti->cExclusiveLocks++;
74 }
75}

Referenced by GDIOBJ_hInsertObject(), GDIOBJ_LockObject(), and GDIOBJ_TryLockObject().

◆ IncrementCurrentProcessGdiHandleCount()

FORCEINLINE VOID IncrementCurrentProcessGdiHandleCount ( void  )

Definition at line 332 of file gdiobj.c.

333{
335 if (ppi) InterlockedIncrement((LONG*)&ppi->GDIHandleCount);
336}

Referenced by GDIOBJ_hInsertObject().

◆ IncrementGdiHandleCount()

static VOID IncrementGdiHandleCount ( ULONG  ulProcessId)
inlinestatic

Definition at line 348 of file gdiobj.c.

349{
350 PEPROCESS pep;
351 PPROCESSINFO ppi;
353
354 Status = PsLookupProcessByProcessId(ULongToHandle(ulProcessId), &pep);
357
358 ppi = PsGetProcessWin32Process(pep);
359 if (ppi) InterlockedIncrement((LONG*)&ppi->GDIHandleCount);
361}

Referenced by GDIOBJ_vSetObjectOwner().

◆ InitGdiHandleTable()

NTSTATUS NTAPI InitGdiHandleTable ( void  )

Definition at line 259 of file gdiobj.c.

260{
262 LARGE_INTEGER liSize;
263 PVOID pvSection;
264 SIZE_T cjViewSize = 0;
265
266 /* Create a section for the shared handle table */
267 liSize.QuadPart = sizeof(GDI_HANDLE_TABLE); // GDI_HANDLE_COUNT * sizeof(ENTRY);
270 NULL,
271 &liSize,
273 SEC_COMMIT | 0x1,
274 NULL,
275 NULL);
276 if (!NT_SUCCESS(status))
277 {
278 DPRINT1("INITGDI: Could not allocate a GDI handle table.\n");
279 return status;
280 }
281
282 /* Map the section in session space */
284 (PVOID*)&gpentHmgr,
285 &cjViewSize);
286 if (!NT_SUCCESS(status))
287 {
288 DPRINT1("INITGDI: Failed to map handle table section\n");
290 return status;
291 }
292
293 /* Allocate memory for the reference counter table */
294 gpaulRefCount = EngAllocSectionMem(&pvSection,
296 GDI_HANDLE_COUNT * sizeof(ULONG),
297 'frHG');
298 if (!gpaulRefCount)
299 {
300 DPRINT1("INITGDI: Failed to allocate reference table.\n");
303 }
304
305 gulFirstFree = 0;
307
309
310 /* Initialize the lookaside lists */
315 return STATUS_NO_MEMORY;
316
326
327 return STATUS_SUCCESS;
328}
NTSTATUS NTAPI MmMapViewInSessionSpace(IN PVOID Section, OUT PVOID *MappedBase, IN OUT PSIZE_T ViewSize)
Definition: section.c:3054
Definition: brush.hpp:16
#define NonPagedPool
Definition: env_spec_w32.h:307
#define SEC_COMMIT
Definition: mmtypes.h:100
#define PAGE_READWRITE
Definition: nt_native.h:1304
#define SECTION_ALL_ACCESS
Definition: nt_native.h:1293
@ GDIObjType_ICMLCS_TYPE
Definition: ntgdityp.h:129
@ GDIObjTypeTotal
Definition: ntgdityp.h:152
@ GDIObjType_CLIENTOBJ_TYPE
Definition: ntgdityp.h:126
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define FL_ZERO_MEMORY
Definition: polytest.cpp:58
NTSTATUS NTAPI MmCreateSection(OUT PVOID *Section, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN PLARGE_INTEGER MaximumSize, IN ULONG SectionPageProtection, IN ULONG AllocationAttributes, IN HANDLE FileHandle OPTIONAL, IN PFILE_OBJECT FileObject OPTIONAL)
Definition: section.c:4620
#define STATUS_SUCCESS
Definition: shellext.h:65
Definition: text.h:60
Definition: path.h:35
Definition: region.h:8
Definition: ps.c:97
void * PVOID
Definition: typedefs.h:50
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
static VOID InitLookasideList(UCHAR objt, ULONG cjSize)
Definition: gdiobj.c:245
PGDI_HANDLE_TABLE GdiHandleTable
Definition: gdiobj.c:1440
#define TAG_GDIHNDTBLE
Definition: tags.h:16
struct LOOKASIDE_ALIGN _PAGED_LOOKASIDE_LIST PAGED_LOOKASIDE_LIST

Referenced by DriverEntry().

◆ InitLookasideList()

static VOID InitLookasideList ( UCHAR  objt,
ULONG  cjSize 
)
static

Definition at line 245 of file gdiobj.c.

246{
248 NULL,
249 NULL,
250 0,
251 cjSize,
252 GDITAG_HMGR_LOOKASIDE_START + (objt << 24),
253 0);
254}
VOID NTAPI ExInitializePagedLookasideList(IN PPAGED_LOOKASIDE_LIST Lookaside, IN PALLOCATE_FUNCTION Allocate OPTIONAL, IN PFREE_FUNCTION Free OPTIONAL, IN ULONG Flags, IN SIZE_T Size, IN ULONG Tag, IN USHORT Depth)
Definition: lookas.c:270
#define GDITAG_HMGR_LOOKASIDE_START
Definition: tags.h:131

Referenced by InitGdiHandleTable().

◆ InterlockedReadUlong()

FORCEINLINE ULONG InterlockedReadUlong ( _In_ _Interlocked_operand_ ULONG volatile Source)

Definition at line 55 of file gdiobj.c.

57{
58 return *Source;
59}
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3169

Referenced by ENTRY_pentPopFreeEntry(), and ENTRY_vPushFreeEntry().

◆ NtGdiCreateClientObj()

W32KAPI HANDLE APIENTRY NtGdiCreateClientObj ( IN ULONG  ulType)

Definition at line 1376 of file gdiobj.c.

1378{
1379 POBJ pObject;
1380 HANDLE handle;
1381
1382 /* Check if ulType is valid */
1386 {
1387 DPRINT1("NtGdiCreateClientObj: Invalid object type 0x%lx.\n", ulType);
1388 return NULL;
1389 }
1390
1391 /* Allocate a new object */
1393 sizeof(CLIENTOBJ),
1395 if (!pObject)
1396 {
1397 DPRINT1("NtGdiCreateClientObj: Could not allocate a clientobj.\n");
1398 return NULL;
1399 }
1400
1401 /* Set the real object type */
1403
1404 /* Create a handle */
1406 if (!handle)
1407 {
1408 DPRINT1("NtGdiCreateClientObj: Could not create a handle.\n");
1410 return NULL;
1411 }
1412
1413 /* Unlock it */
1415
1416 return handle;
1417}
#define UlongToHandle(ul)
Definition: basetsd.h:97
FxObject * pObject
@ GDILoObjType_LO_CLIENTOBJ_TYPE
Definition: gdi_private.h:40
@ GDILoObjType_LO_METAFILE_TYPE
Definition: gdi_private.h:48
@ GDILoObjType_LO_METADC16_TYPE
Definition: gdi_private.h:49
@ GDILoObjType_LO_METAFILE16_TYPE
Definition: gdi_private.h:47
_In_z_ PCWSTR _In_ ULONG ulType
Definition: ntuser.h:43

◆ NtGdiDeleteClientObj()

W32KAPI BOOL APIENTRY NtGdiDeleteClientObj ( IN HANDLE  hobj)

Definition at line 1422 of file gdiobj.c.

1424{
1425 /* We first need to get the real type from the handle */
1427
1428 /* Check if it's really a CLIENTOBJ */
1430 {
1431 /* FIXME: SetLastError? */
1432 return FALSE;
1433 }
1434
1435 return GreDeleteObject(hobj);
1436}
#define GDI_HANDLE_BASETYPE_MASK
Definition: gdi.h:18
BOOL NTAPI GreDeleteObject(HGDIOBJ hobj)
Definition: gdiobj.c:1158

◆ NtGdiExtGetObjectW()

W32KAPI INT APIENTRY NtGdiExtGetObjectW ( IN HANDLE  hobj,
IN INT  cjBufferSize,
OUT LPVOID  lpBuffer 
)

Definition at line 1326 of file gdiobj.c.

1330{
1331 UINT iResult, cjMaxSize;
1332 union
1333 {
1334 BITMAP bitmap;
1335 DIBSECTION dibsection;
1336 LOGPEN logpen;
1337 LOGBRUSH logbrush;
1338 LOGFONTW logfontw;
1339 EXTLOGFONTW extlogfontw;
1340 ENUMLOGFONTEXDVW enumlogfontexdvw;
1341 } object;
1342
1343 /* Normalize to the largest supported object size */
1344 cjMaxSize = min((UINT)cjBufferSize, sizeof(object));
1345
1346 /* Now do the actual call */
1347 iResult = GreGetObject(hobj, cjMaxSize, lpBuffer ? &object : NULL);
1348
1349 /* Check if we have a buffer and data */
1350 if ((lpBuffer != NULL) && (iResult != 0))
1351 {
1352 /* Enter SEH for buffer transfer */
1353 _SEH2_TRY
1354 {
1355 /* Probe the buffer and copy it */
1356 cjMaxSize = min(cjMaxSize, iResult);
1357 ProbeForWrite(lpBuffer, cjMaxSize, sizeof(WORD));
1358 RtlCopyMemory(lpBuffer, &object, cjMaxSize);
1359 }
1361 {
1362 /* Clear the return value.
1363 * Do *NOT* set last error here! */
1364 iResult = 0;
1365 }
1366 _SEH2_END;
1367 }
1368
1369 /* Return the count */
1370 return iResult;
1371}
static TAGREF LPCWSTR LPDWORD LPVOID lpBuffer
Definition: db.cpp:175
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
unsigned short WORD
Definition: ntddk_ex.h:93
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define min(a, b)
Definition: monoChain.cc:55
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
Definition: bl.h:1331
Definition: uimain.c:89
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
INT NTAPI GreGetObject(IN HGDIOBJ hobj, IN INT cbCount, OUT PVOID pvBuffer)
Definition: gdiobj.c:1264

Referenced by GetFontObjectA(), and GetObjectW().

Variable Documentation

◆ apfnCleanup

const GDICLEANUPPROC apfnCleanup[]
static

Definition at line 159 of file gdiobj.c.

Referenced by GDIOBJ_vFreeObject().

◆ apfnDelete

const GDIOBJDELETEPROC apfnDelete[]
static

Definition at line 197 of file gdiobj.c.

Referenced by GDIOBJ_vFreeObject().

◆ GdiHandleTable

PGDI_HANDLE_TABLE GdiHandleTable = NULL

Definition at line 1440 of file gdiobj.c.

Referenced by InitGdiHandleTable().

◆ gpaLookasideList

PPAGED_LOOKASIDE_LIST gpaLookasideList
static

◆ gpaulRefCount

◆ gpentHmgr

◆ gpvGdiHdlTblSection

PVOID gpvGdiHdlTblSection = NULL
static

Definition at line 148 of file gdiobj.c.

Referenced by GDI_MapHandleTable(), and InitGdiHandleTable().

◆ gulFirstFree

volatile ULONG gulFirstFree

Definition at line 151 of file gdiobj.c.

Referenced by ENTRY_pentPopFreeEntry(), ENTRY_vPushFreeEntry(), and InitGdiHandleTable().

◆ gulFirstUnused