ReactOS 0.4.16-dev-1946-g52006dd
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:330
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:75
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
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:3327

Referenced by GDIOBJ_vSetObjectOwner().

◆ ENTRY_hInsertObject()

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

Definition at line 546 of file gdiobj.c.

547{
548 ULONG ulIndex;
549
550 /* Calculate the handle index */
551 ulIndex = pentry - gpentHmgr;
552
553 /* Update the fields in the ENTRY */
554 pentry->einfo.pobj = pobj;
555 pentry->Objt = objt & 0x1f;
556 pentry->FullUnique = (pentry->FullUnique & 0xff00) | objt;
557 pentry->ObjectOwner.ulObj = ulOwner;
558
559 /* Make the handle valid with 1 reference */
560 ASSERT((gpaulRefCount[ulIndex] & REF_MASK_INUSE) == 0);
562
563 /* Return the handle */
564 return (HGDIOBJ)(((ULONG_PTR)pentry->FullUnique << 16) | ulIndex);
565}
#define InterlockedOr
Definition: interlocked.h:239
#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:119
#define DPRINT
Definition: sndvol32.h:73
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;
483
484 /* HACK: This may be a hack but it fixes CORE-5601.
485 * Allow a window that is moving or resizing to have access to all of its child
486 * windows dc's even if the dc belongs to another process i.e. 3D Screensaver */
487 if (pti && pti->TIF_flags & TIF_MOVESIZETRACKING)
489
490 /* Get the handle index and check if its too big */
491 ulIndex = GDI_HANDLE_GET_INDEX(hobj);
492
493 /* Get pointer to the entry */
494 pentry = &gpentHmgr[ulIndex];
495
496 /* Get the current reference count */
497 cOldRefs = gpaulRefCount[ulIndex];
498
499 do
500 {
501 /* Check if the slot is deleted */
502 if ((cOldRefs & REF_MASK_VALID) == 0)
503 {
504 DPRINT("GDIOBJ: Slot is not valid: 0x%lx, hobh=%p\n", cOldRefs, hobj);
505 return NULL;
506 }
507
508 /* Check if the unique value matches */
509 if (pentry->FullUnique != (USHORT)((ULONG_PTR)hobj >> 16))
510 {
511 DPRINT("GDIOBJ: Wrong unique value. Handle: 0x%4x, entry: 0x%4x\n",
512 (USHORT)((ULONG_PTR)hobj >> 16), pentry->FullUnique);
513 return NULL;
514 }
515
516 /* Check if the object owner is this process or public */
517 if (!(fl & GDIOBJFLAG_IGNOREPID) &&
520 {
521 DPRINT("GDIOBJ: Cannot reference foreign handle %p, pentry=%p:%lx.\n",
522 hobj, pentry, pentry->ObjectOwner.ulObj);
523 return NULL;
524 }
525
526 /* Try to atomically increment the reference count */
527 cNewRefs = cOldRefs + 1;
528 cOldRefs = InterlockedCompareExchange((PLONG)&gpaulRefCount[ulIndex],
529 cNewRefs,
530 cOldRefs);
531 }
532 while (cNewRefs != cOldRefs + 1);
533
534 /* Integrity checks */
535 ASSERT((pentry->FullUnique & 0x1f) == pentry->Objt);
536 ASSERT(pentry->einfo.pobj != NULL);
537
538 /* Check if lower 32 bits match, the upper 32 bits are ignored */
539 ASSERT(pentry->einfo.pobj->hHmgr == UlongToPtr(PtrToUlong(hobj)));
540
541 return pentry;
542}
#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 TIF_MOVESIZETRACKING
Definition: ntuser.h:278
#define GDI_OBJ_HMGR_PUBLIC
Definition: ntgdihdl.h:116
HANDLE NTAPI PsGetCurrentProcessId(VOID)
Definition: process.c:1123
unsigned short USHORT
Definition: pedump.c:61
FLONG TIF_flags
Definition: win32.h:95
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:196
@ 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 1595 of file gdiobj.c.

1596{
1597 PENTRY pentry;
1598 ULONG ulIndex;
1600 PPROCESSINFO ppi;
1601
1602 DPRINT("CleanupForProcess prochandle %p Pid %p\n",
1603 Process, Process->UniqueProcessId);
1604
1606
1607 /* Get the current process Id */
1609
1610 /* Loop all handles in the handle table */
1611 for (ulIndex = RESERVE_ENTRIES_COUNT; ulIndex < gulFirstUnused; ulIndex++)
1612 {
1613 pentry = &gpentHmgr[ulIndex];
1614
1615 /* Check if the object is owned by the process */
1616 if (pentry->ObjectOwner.ulObj == dwProcessId)
1617 {
1618 ASSERT(pentry->einfo.pobj->cExclusiveLock == 0);
1619
1620 /* Reference the object and delete it */
1623 }
1624 }
1625
1626#if DBG
1628#endif
1629
1631 DPRINT("Completed cleanup for process %p\n", Process->UniqueProcessId);
1632 if (ppi->GDIHandleCount != 0)
1633 {
1634 DPRINT1("Leaking %d handles!\n", ppi->GDIHandleCount);
1635 ASSERT(FALSE);
1636 }
1637
1638 /* Loop all handles in the handle table */
1639 for (ulIndex = RESERVE_ENTRIES_COUNT; ulIndex < gulFirstUnused; ulIndex++)
1640 {
1641 pentry = &gpentHmgr[ulIndex];
1642
1643 /* Check if the object is owned by the process */
1644 if (pentry->ObjectOwner.ulObj == dwProcessId)
1645 {
1646 DPRINT1("Leaking object. Index=%lx, type=0x%x, refcount=%lx\n",
1647 ulIndex, pentry->Objt, gpaulRefCount[ulIndex]);
1648 DBG_DUMP_EVENT_LIST(&pentry->einfo.pobj->slhLog);
1649 //DBG_CLEANUP_EVENT_LIST(&pentry->einfo.pobj->slhLog);
1650 ASSERT(FALSE);
1651 }
1652 }
1653
1654 return TRUE;
1655}
#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
_In_ DWORD dwProcessId
Definition: shlwapi.h:193
VOID NTAPI GDIOBJ_vDeleteObject(POBJ pobj)
Definition: gdiobj.c:1118
#define PsGetCurrentProcess
Definition: psfuncs.h:17

Referenced by GdiProcessDestroy().

◆ GDI_MapHandleTable()

PVOID NTAPI GDI_MapHandleTable ( PEPROCESS  pProcess)

Definition at line 1565 of file gdiobj.c.

1566{
1567 PVOID pvMappedView = NULL;
1569 LARGE_INTEGER liOffset;
1570 SIZE_T cjViewSize = sizeof(GDI_HANDLE_TABLE);
1571
1572 liOffset.QuadPart = 0;
1573
1575 ASSERT(pProcess != NULL);
1576
1578 pProcess,
1579 &pvMappedView,
1580 0,
1581 0,
1582 &liOffset,
1583 &cjViewSize,
1584 ViewUnmap,
1587
1588 if (!NT_SUCCESS(Status))
1589 return NULL;
1590
1591 return pvMappedView;
1592}
#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:1282
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:4027
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 569 of file gdiobj.c.

570{
571 POBJ pobj;
572
574 {
575 /* Allocate the object from a lookaside list */
576 pobj = ExAllocateFromPagedLookasideList(&gpaLookasideList[objt & 0x1f]);
577 }
578 else
579 {
580 /* Allocate the object from paged pool */
582 }
583
584 if (!pobj) return NULL;
585
586 /* Initialize the object */
587 RtlZeroMemory(pobj, cjSize);
588 pobj->hHmgr = (HGDIOBJ)((ULONG_PTR)objt << 16);
589 pobj->cExclusiveLock = 0;
590 pobj->ulShareCount = 1;
591 pobj->BaseFlags = fl & 0xffff;
592 DBG_INITLOG(&pobj->slhLog);
593 DBG_LOGEVENT(&pobj->slhLog, EVENT_ALLOCATE, 0);
594#if DBG_ENABLE_GDIOBJ_BACKTRACES
595 DbgCaptureStackBackTace(pobj->apvBackTrace, 1, GDI_OBJECT_STACK_LEVELS);
596#endif /* GDI_DEBUG */
597
598 return pobj;
599}
#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:59

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 1535 of file gdiobj.c.

1536{
1537 POBJ pobj;
1538 FLONG fl = 0;
1539 UCHAR objt = (ObjectType >> 16) & 0xFF;
1540
1541 if ((objt == GDIObjType_DC_TYPE && cjSize == sizeof(DC)) ||
1542 (objt == GDIObjType_PAL_TYPE && cjSize == sizeof(PALETTE)) ||
1543 (objt == GDIObjType_RGN_TYPE && cjSize == sizeof(REGION)) ||
1544 (objt == GDIObjType_SURF_TYPE && cjSize == sizeof(SURFACE)) ||
1545 (objt == GDIObjType_PATH_TYPE && cjSize == sizeof(PATH)))
1546 {
1548 }
1549
1550 pobj = GDIOBJ_AllocateObject(objt, cjSize, fl);
1551 if (!pobj)
1552 {
1553 return NULL;
1554 }
1555
1557 {
1558 GDIOBJ_vFreeObject(pobj);
1559 return NULL;
1560 }
1561 return pobj;
1562}
ObjectType
Definition: metafile.c:81
unsigned long FLONG
Definition: ntbasedef.h:378
#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:603
HGDIOBJ NTAPI GDIOBJ_hInsertObject(POBJ pobj, ULONG ulOwner)
Definition: gdiobj.c:919
POBJ NTAPI GDIOBJ_AllocateObject(UCHAR objt, ULONG cjSize, FLONG fl)
Definition: gdiobj.c:569
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 1038 of file gdiobj.c.

1043{
1044 UINT auiIndices[3] = {0, 1, 2};
1045 UINT i, j, tmp;
1046
1047 ASSERT(ulCount <= 3);
1048
1049 /* Sort the handles */
1050 for (i = 0; i < ulCount - 1; i++)
1051 {
1052 for (j = i + 1; j < ulCount; j++)
1053 {
1054 if ((ULONG_PTR)ahObj[auiIndices[i]] <
1055 (ULONG_PTR)ahObj[auiIndices[j]])
1056 {
1057 tmp = auiIndices[i];
1058 auiIndices[i] = auiIndices[j];
1059 auiIndices[j] = tmp;
1060 }
1061 }
1062 }
1063
1064 /* Lock the objects in safe order */
1065 for (i = 0; i < ulCount; i++)
1066 {
1067 /* Skip NULL handles */
1068 if (ahObj[auiIndices[i]] == NULL)
1069 {
1070 apObj[auiIndices[i]] = NULL;
1071 continue;
1072 }
1073
1074 /* Lock the object */
1075 apObj[auiIndices[i]] = GDIOBJ_LockObject(ahObj[auiIndices[i]], objt);
1076
1077 /* Check for failure */
1078 if (apObj[auiIndices[i]] == NULL)
1079 {
1080 /* Cleanup */
1081 while (i--)
1082 {
1083 if (apObj[auiIndices[i]])
1084 GDIOBJ_vUnlockObject(apObj[auiIndices[i]]);
1085 }
1086 return FALSE;
1087 }
1088 }
1089
1090 return TRUE;
1091}
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:833
VOID NTAPI GDIOBJ_vUnlockObject(POBJ pobj)
Definition: gdiobj.c:887

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

◆ GDIOBJ_ConvertFromStockObj()

BOOL NTAPI GDIOBJ_ConvertFromStockObj ( HGDIOBJ phObj)

Definition at line 1502 of file gdiobj.c.

1503{
1504 PENTRY pentry;
1505 POBJ pobj;
1506
1507 /* Reference the handle entry */
1508 pentry = ENTRY_ReferenceEntryByHandle(*phObj, 0);
1509 if (!pentry)
1510 {
1511 DPRINT1("GDIOBJ: Requested handle 0x%p is not valid.\n", *phObj);
1512 return FALSE;
1513 }
1514
1515 /* Update the entry */
1516 pentry->FullUnique &= ~GDI_ENTRY_STOCK_MASK;
1518
1519 /* Get the pointer to the BASEOBJECT */
1520 pobj = pentry->einfo.pobj;
1521
1522 /* Calculate the new handle */
1523 pobj->hHmgr = (HGDIOBJ)((ULONG_PTR)pobj->hHmgr & ~GDI_HANDLE_STOCK_MASK);
1524
1525 /* Return the new handle */
1526 *phObj = pobj->hHmgr;
1527
1528 /* Dereference the handle */
1530
1531 return TRUE;
1532}
VOID NTAPI GDIOBJ_vDereferenceObject(POBJ pobj)
Definition: gdiobj.c:638
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 1468 of file gdiobj.c.

1469{
1470 PENTRY pentry;
1471 POBJ pobj;
1472
1473 /* Reference the handle entry */
1474 pentry = ENTRY_ReferenceEntryByHandle(*phObj, 0);
1475 if (!pentry)
1476 {
1477 DPRINT1("GDIOBJ: Requested handle 0x%p is not valid.\n", *phObj);
1478 return FALSE;
1479 }
1480
1481 /* Update the entry */
1483 pentry->ObjectOwner.ulObj = 0;
1484
1485 /* Get the pointer to the BASEOBJECT */
1486 pobj = pentry->einfo.pobj;
1487
1488 /* Calculate the new handle */
1490
1491 /* Return the new handle */
1492 *phObj = pobj->hHmgr;
1493
1494 /* Dereference the handle */
1496
1497 return TRUE;
1498}
#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 919 of file gdiobj.c.

922{
923 PENTRY pentry;
924 UCHAR objt;
925
926 /* Must have no handle and only one reference */
927 ASSERT(GDI_HANDLE_GET_INDEX(pobj->hHmgr) == 0);
928 ASSERT(pobj->cExclusiveLock == 0);
929 ASSERT(pobj->ulShareCount == 1);
930
931 /* Get a free handle entry */
932 pentry = ENTRY_pentPopFreeEntry();
933 if (!pentry)
934 {
935 DPRINT1("GDIOBJ: Could not get a free entry.\n");
936 return NULL;
937 }
938
939 /* Make the object exclusively locked */
943 pobj->cExclusiveLock = 1;
946
947 /* Get object type from the hHmgr field */
948 objt = ((ULONG_PTR)pobj->hHmgr >> 16) & 0xff;
950
951 /* Check if current process is requested owner */
952 if (ulOwner == GDI_OBJ_HMGR_POWNED)
953 {
954 /* Increment the process handle count */
956
957 /* Use Process id */
959 }
960
961 /* Insert the object into the handle table */
962 pobj->hHmgr = ENTRY_hInsertObject(pentry, pobj, objt, ulOwner);
963
964 /* Return the handle */
965 DPRINT("GDIOBJ: Created handle: %p\n", pobj->hHmgr);
966 DBG_LOGEVENT(&pobj->slhLog, EVENT_CREATE_HANDLE, 0);
967 return pobj->hHmgr;
968}
#define HandleToUlong(h)
Definition: basetsd.h:73
#define ExInitializePushLock
Definition: ex.h:1016
FORCEINLINE VOID ExAcquirePushLockExclusive(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1039
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:546
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 833 of file gdiobj.c.

836{
837 PENTRY pentry;
838 POBJ pobj;
840
841 /* Check if the handle type matches */
843 if ((((ULONG_PTR)hobj >> 16) & 0x1f) != objt)
844 {
845 DPRINT("Wrong object type: hobj=0x%p, objt=0x%x\n", hobj, objt);
846 return NULL;
847 }
848
849 /* Make sure lock order is correct */
850 ASSERT_LOCK_ORDER(objt);
851
852 /* Reference the handle entry */
853 pentry = ENTRY_ReferenceEntryByHandle(hobj, 0);
854 if (!pentry)
855 {
856 DPRINT("GDIOBJ: Requested handle 0x%p is not valid.\n", hobj);
857 return NULL;
858 }
859
860 /* Get the pointer to the BASEOBJECT */
861 pobj = pentry->einfo.pobj;
862
863 /* Check if we already own the lock */
865 if (pobj->dwThreadId != dwThreadId)
866 {
867 /* Disable APCs and acquire the push lock */
870
871 /* Set us as lock owner */
872 ASSERT(pobj->dwThreadId == 0);
873 pobj->dwThreadId = dwThreadId;
874 }
875
876 /* Increase lock count */
877 pobj->cExclusiveLock++;
879 DBG_LOGEVENT(&pobj->slhLog, EVENT_LOCK, 0);
880
881 /* Return the object */
882 return pobj;
883}
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 1095 of file gdiobj.c.

1096{
1097 ULONG ulIndex = GDI_HANDLE_GET_INDEX(pobj->hHmgr);
1098 return gpentHmgr[ulIndex].pUser;
1099}

◆ GDIOBJ_ReferenceObjectByHandle()

POBJ NTAPI GDIOBJ_ReferenceObjectByHandle ( HGDIOBJ  hobj,
UCHAR  objt 
)

Definition at line 698 of file gdiobj.c.

701{
702 PENTRY pentry;
703 POBJ pobj;
704
705 /* Check if the handle type matches */
707 if ((((ULONG_PTR)hobj >> 16) & 0x1f) != objt)
708 {
709 DPRINT("GDIOBJ: Wrong type. handle=%p, type=%x\n", hobj, objt);
710 return NULL;
711 }
712
713 /* Reference the handle entry */
714 pentry = ENTRY_ReferenceEntryByHandle(hobj, 0);
715 if (!pentry)
716 {
717 DPRINT("GDIOBJ: Requested handle 0x%p is not valid.\n", hobj);
718 return NULL;
719 }
720
721 /* Get the pointer to the BASEOBJECT */
722 pobj = pentry->einfo.pobj;
723
724 /* Check if the object is exclusively locked */
725 if (pobj->cExclusiveLock != 0)
726 {
727 DPRINT1("GDIOBJ: Cannot reference object %p with exclusive lock.\n", hobj);
729 DBG_DUMP_EVENT_LIST(&pobj->slhLog);
730 return NULL;
731 }
732
733 DBG_LOGEVENT(&pobj->slhLog, EVENT_REFERENCE, gpaulRefCount[pentry - gpentHmgr]);
734
735 /* All is well, return the object */
736 return pobj;
737}
#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 1456 of file gdiobj.c.

1457{
1458 if (ExpectedType == GDI_OBJECT_TYPE_DONTCARE)
1459 ExpectedType = GDI_HANDLE_GET_TYPE(hObj);
1460 return GDIOBJ_ReferenceObjectByHandle(hObj, (ExpectedType >> 16) & 0x1f);
1461}
#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:698

Referenced by BASEOBJECT::LockShared().

◆ GDIOBJ_TryLockObject()

PGDIOBJ NTAPI GDIOBJ_TryLockObject ( HGDIOBJ  hobj,
UCHAR  objt 
)

Definition at line 764 of file gdiobj.c.

767{
768 PENTRY pentry;
769 POBJ pobj;
771
772 /* Check if the handle type matches */
774 if ((((ULONG_PTR)hobj >> 16) & 0x1f) != objt)
775 {
776 DPRINT("Wrong object type: hobj=0x%p, objt=0x%x\n", hobj, objt);
777 return NULL;
778 }
779
780 /* Make sure lock order is correct */
781 ASSERT_LOCK_ORDER(objt);
782
783 /* Reference the handle entry */
784 pentry = ENTRY_ReferenceEntryByHandle(hobj, 0);
785 if (!pentry)
786 {
787 DPRINT("GDIOBJ: Requested handle 0x%p is not valid.\n", hobj);
788 return NULL;
789 }
790
791 /* Get the pointer to the BASEOBJECT */
792 pobj = pentry->einfo.pobj;
793
794 /* Check if we already own the lock */
796 if (pobj->dwThreadId != dwThreadId)
797 {
798 /* Disable APCs and try acquiring the push lock */
801 {
802 ULONG cRefs, ulIndex;
803 /* Already owned. Clean up and leave. */
805
806 /* Calculate the index */
807 ulIndex = GDI_HANDLE_GET_INDEX(pobj->hHmgr);
808
809 /* Decrement reference count */
810 ASSERT((gpaulRefCount[ulIndex] & REF_MASK_COUNT) > 0);
811 cRefs = InterlockedDecrement((LONG*)&gpaulRefCount[ulIndex]);
812 ASSERT(cRefs & REF_MASK_VALID);
813
814 return NULL;
815 }
816
817 /* Set us as lock owner */
818 ASSERT(pobj->dwThreadId == 0);
819 pobj->dwThreadId = dwThreadId;
820 }
821
822 /* Increase lock count */
823 pobj->cExclusiveLock++;
825 DBG_LOGEVENT(&pobj->slhLog, EVENT_LOCK, 0);
826
827 /* Return the object */
828 return pobj;
829}
#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:117

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 1118 of file gdiobj.c.

1119{
1120 ULONG ulIndex;
1121
1122 /* Set the object's delete flag */
1124 DBG_LOGEVENT(&pobj->slhLog, EVENT_DELETE, 0);
1125
1126 /* Get the handle index */
1127 ulIndex = GDI_HANDLE_GET_INDEX(pobj->hHmgr);
1128 if (ulIndex)
1129 {
1130 /* Reset the handle valid bit */
1132
1133 /* Check if the object is exclusively locked */
1134 if (pobj->cExclusiveLock != 0)
1135 {
1136 /* Reset lock owner and lock count */
1137 pobj->dwThreadId = 0;
1138 pobj->cExclusiveLock = 0;
1139
1140 /* Release the pushlock and reenable APCs */
1144 }
1145 }
1146
1147 /* Dereference the object (will take care of deletion) */
1149}
FORCEINLINE VOID ExReleasePushLockExclusive(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1255
@ BASEFLAG_READY_TO_DIE
Definition: gdiobj.h:61
#define InterlockedOr16
Definition: interlocked.h:254
#define InterlockedAnd
Definition: interlocked.h:77
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 638 of file gdiobj.c.

639{
640 ULONG cRefs, ulIndex;
641
642 /* Calculate the index */
643 ulIndex = GDI_HANDLE_GET_INDEX(pobj->hHmgr);
644
645 /* Check if the object has a handle */
646 if (ulIndex)
647 {
648 /* Decrement reference count */
649 if ((gpaulRefCount[ulIndex] & REF_MASK_COUNT) == 0)
650 {
651 DBG_DUMP_EVENT_LIST(&pobj->slhLog);
652 }
653 ASSERT((gpaulRefCount[ulIndex] & REF_MASK_COUNT) > 0);
654 cRefs = InterlockedDecrement((LONG*)&gpaulRefCount[ulIndex]);
655 DBG_LOGEVENT(&pobj->slhLog, EVENT_DEREFERENCE, cRefs);
656
657 /* Check if we reached 0 and handle bit is not set */
658 if ((cRefs & REF_MASK_INUSE) == 0)
659 {
660 /* Make sure it's ok to delete the object */
662
663 /* Check if the handle was process owned */
664 if (gpentHmgr[ulIndex].ObjectOwner.ulObj != GDI_OBJ_HMGR_PUBLIC &&
666 {
667 /* Decrement the process handle count */
668 ASSERT(gpentHmgr[ulIndex].ObjectOwner.ulObj ==
671 }
672
673 /* Push entry to the free list */
675
676 /* Free the object */
677 GDIOBJ_vFreeObject(pobj);
678 }
679 }
680 else
681 {
682 /* Decrement the objects reference count */
683 ASSERT(pobj->ulShareCount > 0);
684 cRefs = InterlockedDecrement((LONG*)&pobj->ulShareCount);
685 DBG_LOGEVENT(&pobj->slhLog, EVENT_DEREFERENCE, cRefs);
686
687 /* Check if we reached 0 */
688 if (cRefs == 0)
689 {
690 /* Free the object */
691 GDIOBJ_vFreeObject(pobj);
692 }
693 }
694}
#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 603 of file gdiobj.c.

604{
605 UCHAR objt;
606
607 DBG_CLEANUP_EVENT_LIST(&pobj->slhLog);
608
609 /* Get the object type */
610 objt = ((ULONG_PTR)pobj->hHmgr >> 16) & 0x1f;
611
612 /* Check if we have a delete procedure (for C++ based objects) */
613 if (apfnDelete[objt] != NULL)
614 {
615 /* Invoke the delete procedure */
616 apfnDelete[objt](pobj);
617 }
618 else
619 {
620 /* Call the cleanup procedure */
621 NT_ASSERT(apfnCleanup[objt]);
622 apfnCleanup[objt](pobj);
623
624 /* Check if the object is allocated from a lookaside list */
625 if (pobj->BaseFlags & BASEFLAG_LOOKASIDE)
626 {
627 ExFreeToPagedLookasideList(&gpaLookasideList[objt], pobj);
628 }
629 else
630 {
632 }
633 }
634}
#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 741 of file gdiobj.c.

742{
743 ULONG cRefs;
744
745 /* Check if the object has a handle */
746 if (GDI_HANDLE_GET_INDEX(pobj->hHmgr))
747 {
748 /* Increase the handle's reference count */
749 ULONG ulIndex = GDI_HANDLE_GET_INDEX(pobj->hHmgr);
750 ASSERT((gpaulRefCount[ulIndex] & REF_MASK_COUNT) > 0);
751 cRefs = InterlockedIncrement((LONG*)&gpaulRefCount[ulIndex]);
752 }
753 else
754 {
755 /* Increase the object's reference count */
756 cRefs = InterlockedIncrement((LONG*)&pobj->ulShareCount);
757 }
758
759 DBG_LOGEVENT(&pobj->slhLog, EVENT_REFERENCE, cRefs);
760}

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 1103 of file gdiobj.c.

1104{
1105 ULONG ulIndex;
1106
1107 ASSERT(pobj->hHmgr);
1108
1109 /* Get the handle index */
1110 ulIndex = GDI_HANDLE_GET_INDEX(pobj->hHmgr);
1111
1112 /* Set pointer to the usermode attribute */
1113 gpentHmgr[ulIndex].pUser = pvObjAttr;
1114}

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 972 of file gdiobj.c.

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

888{
889 ULONG cRefs, ulIndex;
890 ASSERT(pobj->cExclusiveLock > 0);
891
892 /* Decrease lock count */
893 pobj->cExclusiveLock--;
895 DBG_LOGEVENT(&pobj->slhLog, EVENT_UNLOCK, 0);
896
897 /* Check if this was the last lock */
898 if (pobj->cExclusiveLock == 0)
899 {
900 /* Reset lock owner */
901 pobj->dwThreadId = 0;
902
903 /* Release the pushlock and reenable APCs */
906 }
907
908 /* Calculate the index */
909 ulIndex = GDI_HANDLE_GET_INDEX(pobj->hHmgr);
910
911 /* Decrement reference count */
912 ASSERT((gpaulRefCount[ulIndex] & REF_MASK_COUNT) > 0);
913 cRefs = InterlockedDecrement((LONG*)&gpaulRefCount[ulIndex]);
914 ASSERT(cRefs & REF_MASK_VALID);
915}

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 1659 of file gdiobj.c.

1660{
1661 PPROCESSINFO ppi;
1662
1664 NT_ASSERT(ppi != NULL);
1665
1666 return ppi->pPoolBrushAttr;
1667}
struct _GDI_POOL * pPoolBrushAttr
Definition: win32.h:293

◆ GreDeleteObject()

BOOL NTAPI GreDeleteObject ( HGDIOBJ  hobj)

Definition at line 1165 of file gdiobj.c.

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

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(), IntForceMinimizeWindow(), 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 1277 of file gdiobj.c.

1281{
1282 PVOID pvObj;
1283 UCHAR objt;
1284 INT iResult = 0;
1285
1286 /* Verify object type */
1287 objt = ((ULONG_PTR)hobj >> 16) & 0x1f;
1288 if (objt != GDIObjType_BRUSH_TYPE &&
1289 objt != GDIObjType_SURF_TYPE &&
1290 objt != GDIObjType_LFONT_TYPE &&
1291 objt != GDIObjType_PAL_TYPE)
1292 {
1293 DPRINT1("GreGetObject: Invalid object type\n");
1294 return 0;
1295 }
1296
1297 pvObj = GDIOBJ_ReferenceObjectByHandle(hobj, objt);
1298 if (!pvObj)
1299 {
1300 DPRINT("GreGetObject: Could not lock object\n");
1301 return 0;
1302 }
1303
1304 switch (GDI_HANDLE_GET_TYPE(hobj))
1305 {
1308 iResult = PEN_GetObject(pvObj, cbCount, pvBuffer);
1309 break;
1310
1312 iResult = BRUSH_GetObject(pvObj, cbCount, pvBuffer);
1313 break;
1314
1316 iResult = BITMAP_GetObject(pvObj, cbCount, pvBuffer);
1317 break;
1318
1320 iResult = FontGetObject(pvObj, cbCount, pvBuffer);
1321 break;
1322
1324 iResult = PALETTE_GetObject(pvObj, cbCount, pvBuffer);
1325 break;
1326
1327 default:
1328 DPRINT1("GDI object type of 0x%p not implemented\n", hobj);
1329 break;
1330 }
1331
1333 return iResult;
1334}
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(_Inout_ PTEXTOBJ plfont, _In_ ULONG cjBuffer, _Out_ PVOID pvBuffer)
Definition: font.c:296
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 1199 of file gdiobj.c.

1200{
1201 ULONG ulIndex, ulOwner;
1202
1203 if (hobj == NULL)
1204 {
1205 DPRINT("GreGetObjectOwner: invalid NULL handle\n");
1207 }
1208
1209 /* Get the handle index */
1210 ulIndex = GDI_HANDLE_GET_INDEX(hobj);
1211
1212 /* Check if the handle is valid */
1213 if (ulIndex >= GDI_HANDLE_COUNT ||
1214 gpentHmgr[ulIndex].Objt == GDIObjType_DEF_TYPE ||
1215 ((ULONG_PTR)hobj >> 16) != gpentHmgr[ulIndex].FullUnique)
1216 {
1217 DPRINT1("GreGetObjectOwner: invalid handle 0x%p.\n", hobj);
1219 }
1220
1221 /* Get the object owner */
1222 ulOwner = gpentHmgr[ulIndex].ObjectOwner.ulObj;
1223
1224 if (ulOwner == HandleToUlong(PsGetCurrentProcessId()))
1225 return GDI_OBJ_HMGR_POWNED;
1226
1227 if (ulOwner == GDI_OBJ_HMGR_PUBLIC)
1228 return GDI_OBJ_HMGR_PUBLIC;
1229
1231}
#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 1235 of file gdiobj.c.

1239{
1240 PENTRY pentry;
1241
1242 /* Check for stock objects */
1243 if (GDI_HANDLE_IS_STOCKOBJ(hobj))
1244 {
1245 DPRINT("GreSetObjectOwner: Got stock object %p\n", hobj);
1246 return FALSE;
1247 }
1248
1249 /* Reference the handle entry */
1250 pentry = ENTRY_ReferenceEntryByHandle(hobj, Flags);
1251 if (!pentry)
1252 {
1253 DPRINT("GreSetObjectOwner: Invalid handle 0x%p.\n", hobj);
1254 return FALSE;
1255 }
1256
1257 /* Call internal function */
1258 GDIOBJ_vSetObjectOwner(pentry->einfo.pobj, ulOwner);
1259
1260 /* Dereference the object */
1262
1263 return TRUE;
1264}
VOID NTAPI GDIOBJ_vSetObjectOwner(POBJ pobj, ULONG ulNewOwner)
Definition: gdiobj.c:972
_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:2689
Definition: brush.hpp:16
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define NonPagedPool
Definition: env_spec_w32.h:307
#define SEC_COMMIT
Definition: mmtypes.h:100
#define PAGE_READWRITE
Definition: nt_native.h:1307
#define SECTION_ALL_ACCESS
Definition: nt_native.h:1296
@ GDIObjType_ICMLCS_TYPE
Definition: ntgdityp.h:129
@ GDIObjTypeTotal
Definition: ntgdityp.h:152
@ GDIObjType_CLIENTOBJ_TYPE
Definition: ntgdityp.h:126
#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:4674
#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:1453
#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 1389 of file gdiobj.c.

1391{
1392 POBJ pObject;
1393 HANDLE handle;
1394
1395 /* Check if ulType is valid */
1399 {
1400 DPRINT1("NtGdiCreateClientObj: Invalid object type 0x%lx.\n", ulType);
1401 return NULL;
1402 }
1403
1404 /* Allocate a new object */
1406 sizeof(CLIENTOBJ),
1408 if (!pObject)
1409 {
1410 DPRINT1("NtGdiCreateClientObj: Could not allocate a clientobj.\n");
1411 return NULL;
1412 }
1413
1414 /* Set the real object type */
1416
1417 /* Create a handle */
1419 if (!handle)
1420 {
1421 DPRINT1("NtGdiCreateClientObj: Could not create a handle.\n");
1423 return NULL;
1424 }
1425
1426 /* Unlock it */
1428
1429 return handle;
1430}
#define UlongToHandle(ul)
Definition: basetsd.h:91
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 1435 of file gdiobj.c.

1437{
1438 /* We first need to get the real type from the handle */
1440
1441 /* Check if it's really a CLIENTOBJ */
1443 {
1444 /* FIXME: SetLastError? */
1445 return FALSE;
1446 }
1447
1448 return GreDeleteObject(hobj);
1449}
#define GDI_HANDLE_BASETYPE_MASK
Definition: gdi.h:18
BOOL NTAPI GreDeleteObject(HGDIOBJ hobj)
Definition: gdiobj.c:1165

◆ NtGdiExtGetObjectW()

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

Definition at line 1339 of file gdiobj.c.

1343{
1344 UINT iResult, cjMaxSize;
1345 union
1346 {
1347 BITMAP bitmap;
1348 DIBSECTION dibsection;
1349 LOGPEN logpen;
1350 LOGBRUSH logbrush;
1351 LOGFONTW logfontw;
1352 EXTLOGFONTW extlogfontw;
1353 ENUMLOGFONTEXDVW enumlogfontexdvw;
1354 } object;
1355
1356 /* Normalize to the largest supported object size */
1357 cjMaxSize = min((UINT)cjBufferSize, sizeof(object));
1358
1359 /* Now do the actual call */
1360 iResult = GreGetObject(hobj, cjMaxSize, lpBuffer ? &object : NULL);
1361
1362 /* Check if we have a buffer and data */
1363 if ((lpBuffer != NULL) && (iResult != 0))
1364 {
1365 /* Enter SEH for buffer transfer */
1366 _SEH2_TRY
1367 {
1368 /* Probe the buffer and copy it */
1369 cjMaxSize = min(cjMaxSize, iResult);
1370 ProbeForWrite(lpBuffer, cjMaxSize, sizeof(WORD));
1371 RtlCopyMemory(lpBuffer, &object, cjMaxSize);
1372 }
1374 {
1375 /* Clear the return value.
1376 * Do *NOT* set last error here! */
1377 iResult = 0;
1378 }
1379 _SEH2_END;
1380 }
1381
1382 /* Return the count */
1383 return iResult;
1384}
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
unsigned short WORD
Definition: ntddk_ex.h:93
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
#define min(a, b)
Definition: monoChain.cc:55
_Out_ LPWSTR lpBuffer
Definition: netsh.h:68
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:82
#define _SEH2_END
Definition: pseh2_64.h:171
#define _SEH2_TRY
Definition: pseh2_64.h:71
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:1277

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 1453 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