ReactOS  r76032
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)
 
INIT_FUNCTION NTSTATUS NTAPI InitGdiHandleTable (void)
 
FORCEINLINE VOID IncrementCurrentProcessGdiHandleCount (void)
 
FORCEINLINE VOID DecrementCurrentProcessGdiHandleCount (void)
 
FORCEINLINE VOID IncrementGdiHandleCount (ULONG ulProcessId)
 
FORCEINLINE 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, IN 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)
 
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! More...
 

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

#define ASSERT_EXCLUSIVE_OBJECT_TYPE (   objt)

Definition at line 124 of file gdiobj.c.

Referenced by GDIOBJ_LockObject().

#define ASSERT_LOCK_ORDER (   hobj)

Definition at line 122 of file gdiobj.c.

Referenced by GDIOBJ_LockObject(), and GDIOBJ_TryLockObject().

#define ASSERT_SHARED_OBJECT_TYPE (   objt)

Definition at line 123 of file gdiobj.c.

Referenced by GDIOBJ_ReferenceObjectByHandle().

#define ASSERT_TRYLOCK_OBJECT_TYPE (   objt)

Definition at line 125 of file gdiobj.c.

Referenced by GDIOBJ_TryLockObject().

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

Definition at line 132 of file gdiobj.c.

Referenced by GDIOBJ_AllocateObject(), and GDIOBJ_vFreeObject().

#define NDEBUG

Definition at line 50 of file gdiobj.c.

Enumeration Type Documentation

anonymous enum
Enumerator
REF_MASK_REUSE 
REF_INC_REUSE 
REF_MASK_VALID 
REF_MASK_COUNT 
REF_MASK_INUSE 

Definition at line 134 of file gdiobj.c.

135 {
136  REF_MASK_REUSE = 0xff000000,
137  REF_INC_REUSE = 0x01000000,
138  REF_MASK_VALID = 0x00800000,
139  REF_MASK_COUNT = 0x007fffff,
140  REF_MASK_INUSE = 0x00ffffff,
141 };

Function Documentation

FORCEINLINE void DECREASE_THREAD_LOCK_COUNT ( _In_ HANDLE  hobj)

Definition at line 79 of file gdiobj.c.

Referenced by GDIOBJ_vDeleteObject(), and GDIOBJ_vUnlockObject().

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

Definition at line 338 of file gdiobj.c.

Referenced by GDIOBJ_vDereferenceObject().

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

Definition at line 363 of file gdiobj.c.

Referenced by GDIOBJ_vSetObjectOwner().

364 {
365  PEPROCESS pep;
366  PPROCESSINFO ppi;
368 
369  Status = PsLookupProcessByProcessId(ULongToHandle(ulProcessId), &pep);
370  NT_ASSERT(NT_SUCCESS(Status));
371  __analysis_assume(NT_SUCCESS(Status));
372 
373  ppi = PsGetProcessWin32Process(pep);
374  if (ppi) InterlockedDecrement((LONG*)&ppi->GDIHandleCount);
375  if (NT_SUCCESS(Status)) ObDereferenceObject(pep);
376 }
#define ULongToHandle(h)
Definition: basetsd.h:80
PVOID NTAPI PsGetProcessWin32Process(PEPROCESS Process)
Definition: process.c:1193
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:267
long LONG
Definition: pedump.c:60
#define __analysis_assume(expr)
Definition: sal.h:1111
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
NTSTATUS NTAPI PsLookupProcessByProcessId(IN HANDLE ProcessId, OUT PEPROCESS *Process)
Definition: process.c:919
#define InterlockedDecrement
Definition: armddk.h:52
Status
Definition: gdiplustypes.h:24
LONG NTSTATUS
Definition: DriverTester.h:11
#define NT_ASSERT
Definition: rtlfuncs.h:3312
static HGDIOBJ ENTRY_hInsertObject ( PENTRY  pentry,
POBJ  pobj,
UCHAR  objt,
ULONG  ulOwner 
)
static

Definition at line 534 of file gdiobj.c.

Referenced by GDIOBJ_hInsertObject().

535 {
536  ULONG ulIndex;
537 
538  /* Calculate the handle index */
539  ulIndex = pentry - gpentHmgr;
540 
541  /* Update the fields in the ENTRY */
542  pentry->einfo.pobj = pobj;
543  pentry->Objt = objt & 0x1f;
544  pentry->FullUnique = (pentry->FullUnique & 0xff00) | objt;
545  pentry->ObjectOwner.ulObj = ulOwner;
546 
547  /* Make the handle valid with 1 reference */
548  ASSERT((gpaulRefCount[ulIndex] & REF_MASK_INUSE) == 0);
550 
551  /* Return the handle */
552  return (HGDIOBJ)(((ULONG_PTR)pentry->FullUnique << 16) | ulIndex);
553 }
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
UCHAR Objt
Definition: ntgdihdl.h:245
struct _BASEOBJECT * pobj
Definition: ntgdihdl.h:230
union _ENTRY::_EINFO einfo
long LONG
Definition: pedump.c:60
PULONG gpaulRefCount
Definition: gdiobj.c:148
ULONG ulObj
Definition: ntgdihdl.h:241
#define InterlockedOr
Definition: interlocked.h:224
PENTRY gpentHmgr
Definition: gdiobj.c:147
ULONG ulIndex
Definition: symbols.c:92
USHORT FullUnique
Definition: ntgdihdl.h:244
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
union _ENTRY::_OBJECTOWNER ObjectOwner
static PENTRY ENTRY_pentPopFreeEntry ( VOID  )
static

Definition at line 380 of file gdiobj.c.

Referenced by GDIOBJ_hInsertObject().

381 {
382  ULONG iFirst, iNext, iPrev;
383  PENTRY pentFree;
384 
385  DPRINT("Enter InterLockedPopFreeEntry\n");
386 
387  do
388  {
389  /* Get the index and sequence number of the first free entry */
391 
392  /* Check if we have a free entry */
393  if (!(iFirst & GDI_HANDLE_INDEX_MASK))
394  {
395  /* Increment FirstUnused and get the new index */
396  iFirst = InterlockedIncrement((LONG*)&gulFirstUnused) - 1;
397 
398  /* Check if we have unused entries left */
399  if (iFirst >= GDI_HANDLE_COUNT)
400  {
401  DPRINT1("No more GDI handles left!\n");
402 #if DBG_ENABLE_GDIOBJ_BACKTRACES
403  DbgDumpGdiHandleTableWithBT();
404 #endif
406  return 0;
407  }
408 
409  /* Return the old entry */
410  return &gpentHmgr[iFirst];
411  }
412 
413  /* Get a pointer to the first free entry */
414  pentFree = &gpentHmgr[iFirst & GDI_HANDLE_INDEX_MASK];
415 
416  /* Create a new value with an increased sequence number */
417  iNext = GDI_HANDLE_GET_INDEX(pentFree->einfo.hFree);
418  iNext |= (iFirst & ~GDI_HANDLE_INDEX_MASK) + 0x10000;
419 
420  /* Try to exchange the FirstFree value */
422  iNext,
423  iFirst);
424  }
425  while (iPrev != iFirst);
426 
427  /* Sanity check: is entry really free? */
428  ASSERT(((ULONG_PTR)pentFree->einfo.pobj & ~GDI_HANDLE_INDEX_MASK) == 0);
429 
430  return pentFree;
431 }
#define GDI_HANDLE_GET_INDEX(h)
Definition: gdi.h:28
volatile ULONG gulFirstUnused
Definition: gdiobj.c:150
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
#define GDI_HANDLE_INDEX_MASK
Definition: gdi.h:16
#define InterlockedCompareExchange
Definition: interlocked.h:104
struct _BASEOBJECT * pobj
Definition: ntgdihdl.h:230
volatile ULONG gulFirstFree
Definition: gdiobj.c:149
union _ENTRY::_EINFO einfo
uint32_t ULONG_PTR
Definition: typedefs.h:63
long LONG
Definition: pedump.c:60
FORCEINLINE ULONG InterlockedReadUlong(_In_ _Interlocked_operand_ ULONG volatile *Source)
Definition: gdiobj.c:55
void DPRINT(...)
Definition: polytest.cpp:61
#define InterlockedDecrement
Definition: armddk.h:52
PENTRY gpentHmgr
Definition: gdiobj.c:147
HGDIOBJ hFree
Definition: ntgdihdl.h:231
#define InterlockedIncrement
Definition: armddk.h:53
#define GDI_HANDLE_COUNT
Definition: gdi.h:12
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
Definition: ntgdihdl.h:226
static PENTRY ENTRY_ReferenceEntryByHandle ( HGDIOBJ  hobj,
FLONG  fl 
)
static

Definition at line 476 of file gdiobj.c.

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

477 {
478  ULONG ulIndex, cNewRefs, cOldRefs;
479  PENTRY pentry;
480 
481  /* Get the handle index and check if its too big */
482  ulIndex = GDI_HANDLE_GET_INDEX(hobj);
483 
484  /* Get pointer to the entry */
485  pentry = &gpentHmgr[ulIndex];
486 
487  /* Get the current reference count */
488  cOldRefs = gpaulRefCount[ulIndex];
489 
490  do
491  {
492  /* Check if the slot is deleted */
493  if ((cOldRefs & REF_MASK_VALID) == 0)
494  {
495  DPRINT("GDIOBJ: Slot is not valid: 0x%lx, hobh=%p\n", cOldRefs, hobj);
496  return NULL;
497  }
498 
499  /* Check if the unique value matches */
500  if (pentry->FullUnique != (USHORT)((ULONG_PTR)hobj >> 16))
501  {
502  DPRINT("GDIOBJ: Wrong unique value. Handle: 0x%4x, entry: 0x%4x\n",
503  (USHORT)((ULONG_PTR)hobj >> 16), pentry->FullUnique);
504  return NULL;
505  }
506 
507  /* Check if the object owner is this process or public */
508  if (!(fl & GDIOBJFLAG_IGNOREPID) &&
511  {
512  DPRINT("GDIOBJ: Cannot reference foreign handle %p, pentry=%p:%lx.\n",
513  hobj, pentry, pentry->ObjectOwner.ulObj);
514  return NULL;
515  }
516 
517  /* Try to atomically increment the reference count */
518  cNewRefs = cOldRefs + 1;
519  cOldRefs = InterlockedCompareExchange((PLONG)&gpaulRefCount[ulIndex],
520  cNewRefs,
521  cOldRefs);
522  }
523  while (cNewRefs != cOldRefs + 1);
524 
525  /* Integrity checks */
526  ASSERT((pentry->FullUnique & 0x1f) == pentry->Objt);
527  ASSERT(pentry->einfo.pobj && pentry->einfo.pobj->hHmgr == hobj);
528 
529  return pentry;
530 }
#define GDI_HANDLE_GET_INDEX(h)
Definition: gdi.h:28
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
UCHAR Objt
Definition: ntgdihdl.h:245
#define InterlockedCompareExchange
Definition: interlocked.h:104
struct _BASEOBJECT * pobj
Definition: ntgdihdl.h:230
union _ENTRY::_EINFO einfo
uint32_t ULONG_PTR
Definition: typedefs.h:63
_In_ FLONG fl
Definition: winddi.h:1279
PULONG gpaulRefCount
Definition: gdiobj.c:148
smooth NULL
Definition: ftsmooth.c:557
void DPRINT(...)
Definition: polytest.cpp:61
#define PtrToUlong(p)
Definition: basetsd.h:82
ULONG ulObj
Definition: ntgdihdl.h:241
PENTRY gpentHmgr
Definition: gdiobj.c:147
ULONG ulIndex
Definition: symbols.c:92
unsigned short USHORT
Definition: pedump.c:61
USHORT FullUnique
Definition: ntgdihdl.h:244
#define GDI_OBJ_HMGR_PUBLIC
Definition: ntgdihdl.h:116
HANDLE NTAPI PsGetCurrentProcessId(VOID)
Definition: process.c:1123
unsigned int ULONG
Definition: retypes.h:1
union _ENTRY::_OBJECTOWNER ObjectOwner
Definition: ntgdihdl.h:226
signed int * PLONG
Definition: retypes.h:5
static VOID ENTRY_vPushFreeEntry ( PENTRY  pentFree)
static

Definition at line 437 of file gdiobj.c.

Referenced by GDIOBJ_vDereferenceObject().

438 {
439  ULONG iToFree, iFirst, iPrev, idxToFree;
440 
441  DPRINT("Enter ENTRY_vPushFreeEntry\n");
442 
443  idxToFree = pentFree - gpentHmgr;
444  ASSERT((gpaulRefCount[idxToFree] & REF_MASK_INUSE) == 0);
445 
446  /* Initialize entry */
447  pentFree->Objt = GDIObjType_DEF_TYPE;
448  pentFree->ObjectOwner.ulObj = 0;
449  pentFree->pUser = NULL;
450 
451  /* Increase reuse counter in entry and reference counter */
453  pentFree->FullUnique += 0x0100;
454 
455  do
456  {
457  /* Get the current first free index and sequence number */
459 
460  /* Set the einfo.pobj member to the index of the first free entry */
461  pentFree->einfo.pobj = UlongToPtr(iFirst & GDI_HANDLE_INDEX_MASK);
462 
463  /* Combine new index and increased sequence number in iToFree */
464  iToFree = idxToFree | ((iFirst & ~GDI_HANDLE_INDEX_MASK) + 0x10000);
465 
466  /* Try to atomically update the first free entry */
468  iToFree,
469  iFirst);
470  }
471  while (iPrev != iFirst);
472 }
PVOID pUser
Definition: ntgdihdl.h:247
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
UCHAR Objt
Definition: ntgdihdl.h:245
#define GDI_HANDLE_INDEX_MASK
Definition: gdi.h:16
#define InterlockedCompareExchange
Definition: interlocked.h:104
struct _BASEOBJECT * pobj
Definition: ntgdihdl.h:230
volatile ULONG gulFirstFree
Definition: gdiobj.c:149
union _ENTRY::_EINFO einfo
long LONG
Definition: pedump.c:60
FORCEINLINE ULONG InterlockedReadUlong(_In_ _Interlocked_operand_ ULONG volatile *Source)
Definition: gdiobj.c:55
PULONG gpaulRefCount
Definition: gdiobj.c:148
smooth NULL
Definition: ftsmooth.c:557
void DPRINT(...)
Definition: polytest.cpp:61
#define InterlockedExchangeAdd
Definition: interlocked.h:181
#define UlongToPtr(ul)
Definition: basetsd.h:97
ULONG ulObj
Definition: ntgdihdl.h:241
PENTRY gpentHmgr
Definition: gdiobj.c:147
USHORT FullUnique
Definition: ntgdihdl.h:244
unsigned int ULONG
Definition: retypes.h:1
union _ENTRY::_OBJECTOWNER ObjectOwner
BOOL NTAPI GDI_CleanupForProcess ( struct _EPROCESS Process)

Definition at line 1543 of file gdiobj.c.

Referenced by GdiProcessDestroy().

1544 {
1545  PENTRY pentry;
1546  ULONG ulIndex;
1547  DWORD dwProcessId;
1548  PPROCESSINFO ppi;
1549 
1550  DPRINT("CleanupForProcess prochandle %p Pid %p\n",
1551  Process, Process->UniqueProcessId);
1552 
1553  ASSERT(Process == PsGetCurrentProcess());
1554 
1555  /* Get the current process Id */
1556  dwProcessId = PtrToUlong(PsGetCurrentProcessId());
1557 
1558  /* Loop all handles in the handle table */
1559  for (ulIndex = RESERVE_ENTRIES_COUNT; ulIndex < gulFirstUnused; ulIndex++)
1560  {
1561  pentry = &gpentHmgr[ulIndex];
1562 
1563  /* Check if the object is owned by the process */
1564  if (pentry->ObjectOwner.ulObj == dwProcessId)
1565  {
1566  ASSERT(pentry->einfo.pobj->cExclusiveLock == 0);
1567 
1568  /* Reference the object and delete it */
1570  GDIOBJ_vDeleteObject(pentry->einfo.pobj);
1571  }
1572  }
1573 
1574 #if DBG
1576 #endif
1577 
1579  DPRINT("Completed cleanup for process %p\n", Process->UniqueProcessId);
1580  if (ppi->GDIHandleCount != 0)
1581  {
1582  DPRINT1("Leaking %d handles!\n", ppi->GDIHandleCount);
1583  ASSERT(FALSE);
1584  }
1585 
1586  /* Loop all handles in the handle table */
1587  for (ulIndex = RESERVE_ENTRIES_COUNT; ulIndex < gulFirstUnused; ulIndex++)
1588  {
1589  pentry = &gpentHmgr[ulIndex];
1590 
1591  /* Check if the object is owned by the process */
1592  if (pentry->ObjectOwner.ulObj == dwProcessId)
1593  {
1594  DPRINT1("Leaking object. Index=%lx, type=0x%x, refcount=%lx\n",
1595  ulIndex, pentry->Objt, gpaulRefCount[ulIndex]);
1596  DBG_DUMP_EVENT_LIST(&pentry->einfo.pobj->slhLog);
1597  //DBG_CLEANUP_EVENT_LIST(&pentry->einfo.pobj->slhLog);
1598  ASSERT(FALSE);
1599  }
1600  }
1601 
1602  return TRUE;
1603 }
#define TRUE
Definition: types.h:120
volatile ULONG gulFirstUnused
Definition: gdiobj.c:150
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
UCHAR Objt
Definition: ntgdihdl.h:245
struct _BASEOBJECT * pobj
Definition: ntgdihdl.h:230
DWORD DWORD
Definition: winlogon.h:75
HANDLE UniqueProcessId
Definition: pstypes.h:1199
union _ENTRY::_EINFO einfo
#define FALSE
Definition: types.h:117
BOOL NTAPI DbgGdiHTIntegrityCheck(VOID)
long LONG
Definition: pedump.c:60
#define PsGetCurrentProcess
Definition: psfuncs.h:17
PULONG gpaulRefCount
Definition: gdiobj.c:148
void DPRINT(...)
Definition: polytest.cpp:61
#define PtrToUlong(p)
Definition: basetsd.h:82
VOID NTAPI GDIOBJ_vDeleteObject(POBJ pobj)
Definition: gdiobj.c:1106
ULONG ulObj
Definition: ntgdihdl.h:241
#define DBG_DUMP_EVENT_LIST(pslh)
Definition: gdidebug.h:111
PENTRY gpentHmgr
Definition: gdiobj.c:147
static const unsigned RESERVE_ENTRIES_COUNT
Definition: gdiobj.h:11
ULONG ulIndex
Definition: symbols.c:92
#define InterlockedIncrement
Definition: armddk.h:53
HANDLE NTAPI PsGetCurrentProcessId(VOID)
Definition: process.c:1123
PVOID NTAPI PsGetCurrentProcessWin32Process(VOID)
Definition: process.c:1183
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
union _ENTRY::_OBJECTOWNER ObjectOwner
Definition: ntgdihdl.h:226
PVOID NTAPI GDI_MapHandleTable ( PEPROCESS  pProcess)

Definition at line 1513 of file gdiobj.c.

Referenced by GdiProcessCreate().

1514 {
1515  PVOID pvMappedView = NULL;
1516  NTSTATUS Status;
1517  LARGE_INTEGER liOffset;
1518  ULONG cjViewSize = sizeof(GDI_HANDLE_TABLE);
1519 
1520  liOffset.QuadPart = 0;
1521 
1523  ASSERT(pProcess != NULL);
1524 
1526  pProcess,
1527  &pvMappedView,
1528  0,
1529  0,
1530  &liOffset,
1531  &cjViewSize,
1532  ViewUnmap,
1533  SEC_NO_CHANGE,
1534  PAGE_READONLY);
1535 
1536  if (!NT_SUCCESS(Status))
1537  return NULL;
1538 
1539  return pvMappedView;
1540 }
DWORD *typedef PVOID
Definition: winlogon.h:52
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
smooth NULL
Definition: ftsmooth.c:557
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:4491
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
struct _GDI_HANDLE_TABLE GDI_HANDLE_TABLE
static PVOID gpvGdiHdlTblSection
Definition: gdiobj.c:146
Status
Definition: gdiplustypes.h:24
LONG NTSTATUS
Definition: DriverTester.h:11
#define PAGE_READONLY
Definition: compat.h:127
unsigned int ULONG
Definition: retypes.h:1
#define SEC_NO_CHANGE
Definition: mmtypes.h:94
LONGLONG QuadPart
Definition: typedefs.h:112
POBJ NTAPI GDIOBJ_AllocateObject ( UCHAR  objt,
ULONG  cjSize,
FLONG  fl 
)

Definition at line 557 of file gdiobj.c.

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

558 {
559  POBJ pobj;
560 
561  if (fl & BASEFLAG_LOOKASIDE)
562  {
563  /* Allocate the object from a lookaside list */
564  pobj = ExAllocateFromPagedLookasideList(&gpaLookasideList[objt & 0x1f]);
565  }
566  else
567  {
568  /* Allocate the object from paged pool */
570  }
571 
572  if (!pobj) return NULL;
573 
574  /* Initialize the object */
575  RtlZeroMemory(pobj, cjSize);
576  pobj->hHmgr = (HGDIOBJ)((ULONG_PTR)objt << 16);
577  pobj->cExclusiveLock = 0;
578  pobj->ulShareCount = 1;
579  pobj->BaseFlags = fl & 0xffff;
580  DBG_INITLOG(&pobj->slhLog);
581  DBG_LOGEVENT(&pobj->slhLog, EVENT_ALLOCATE, 0);
582 #if DBG_ENABLE_GDIOBJ_BACKTRACES
583  DbgCaptureStackBackTace(pobj->apvBackTrace, 1, GDI_OBJECT_STACK_LEVELS);
584 #endif /* GDI_DEBUG */
585 
586  return pobj;
587 }
ULONG NTAPI DbgCaptureStackBackTace(_Out_writes_(cFramesToCapture) PVOID *ppvFrames, _In_ ULONG cFramesToSkip, _In_ ULONG cFramesToCapture)
ULONG ulShareCount
Definition: gdiobj.h:42
#define DBG_INITLOG(pslh)
Definition: gdidebug.h:110
static PPAGED_LOOKASIDE_LIST gpaLookasideList
Definition: gdiobj.c:151
USHORT cExclusiveLock
Definition: gdiobj.h:45
HGDIOBJ hHmgr
Definition: gdiobj.h:40
USHORT BaseFlags
Definition: gdiobj.h:46
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define GDIOBJ_POOL_TAG(type)
Definition: gdiobj.c:132
_In_ FLONG fl
Definition: winddi.h:1279
#define DBG_LOGEVENT(pslh, type, val)
Definition: gdidebug.h:109
smooth NULL
Definition: ftsmooth.c:557
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define GDI_OBJECT_STACK_LEVELS
Definition: gdiobj.h:8
void * HGDIOBJ
Definition: windef.h:280
_In_ ULONG cjSize
Definition: winddi.h:3634
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
POBJ NTAPI GDIOBJ_AllocObjWithHandle ( ULONG  ObjectType,
ULONG  cjSize 
)

Definition at line 1483 of file gdiobj.c.

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

1484 {
1485  POBJ pobj;
1486  FLONG fl = 0;
1487  UCHAR objt = (ObjectType >> 16) & 0xFF;
1488 
1489  if ((objt == GDIObjType_DC_TYPE && cjSize == sizeof(DC)) ||
1490  (objt == GDIObjType_PAL_TYPE && cjSize == sizeof(PALETTE)) ||
1491  (objt == GDIObjType_RGN_TYPE && cjSize == sizeof(REGION)) ||
1492  (objt == GDIObjType_SURF_TYPE && cjSize == sizeof(SURFACE)) ||
1493  (objt == GDIObjType_PATH_TYPE && cjSize == sizeof(PATH)))
1494  {
1495  fl |= BASEFLAG_LOOKASIDE;
1496  }
1497 
1498  pobj = GDIOBJ_AllocateObject(objt, cjSize, fl);
1499  if (!pobj)
1500  {
1501  return NULL;
1502  }
1503 
1505  {
1506  GDIOBJ_vFreeObject(pobj);
1507  return NULL;
1508  }
1509  return pobj;
1510 }
struct _PALETTE PALETTE
_In_ FLONG fl
Definition: winddi.h:1279
smooth NULL
Definition: ftsmooth.c:557
unsigned long FLONG
Definition: ntbasedef.h:365
Definition: polytest.cpp:40
unsigned char UCHAR
Definition: xmlstorage.h:181
struct _PATH PATH
#define GDI_OBJ_HMGR_POWNED
Definition: ntgdihdl.h:117
struct _REGION REGION
struct _SURFACE SURFACE
_In_ ULONG cjSize
Definition: winddi.h:3634
ObjectType
Definition: metafile.c:278
POBJ NTAPI GDIOBJ_AllocateObject(UCHAR objt, ULONG cjSize, FLONG fl)
Definition: gdiobj.c:557
VOID NTAPI GDIOBJ_vFreeObject(POBJ pobj)
Definition: gdiobj.c:591
HGDIOBJ NTAPI GDIOBJ_hInsertObject(POBJ pobj, ULONG ulOwner)
Definition: gdiobj.c:907
BOOL NTAPI GDIOBJ_bLockMultipleObjects ( IN ULONG  ulCount,
IN HGDIOBJ ahObj,
OUT PGDIOBJ apObj,
IN UCHAR  objt 
)

Definition at line 1026 of file gdiobj.c.

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

1031 {
1032  UINT auiIndices[3] = {0, 1, 2};
1033  UINT i, j, tmp;
1034 
1035  ASSERT(ulCount <= 3);
1036 
1037  /* Sort the handles */
1038  for (i = 0; i < ulCount - 1; i++)
1039  {
1040  for (j = i + 1; j < ulCount; j++)
1041  {
1042  if ((ULONG_PTR)ahObj[auiIndices[i]] <
1043  (ULONG_PTR)ahObj[auiIndices[j]])
1044  {
1045  tmp = auiIndices[i];
1046  auiIndices[i] = auiIndices[j];
1047  auiIndices[j] = tmp;
1048  }
1049  }
1050  }
1051 
1052  /* Lock the objects in safe order */
1053  for (i = 0; i < ulCount; i++)
1054  {
1055  /* Skip NULL handles */
1056  if (ahObj[auiIndices[i]] == NULL)
1057  {
1058  apObj[auiIndices[i]] = NULL;
1059  continue;
1060  }
1061 
1062  /* Lock the object */
1063  apObj[auiIndices[i]] = GDIOBJ_LockObject(ahObj[auiIndices[i]], objt);
1064 
1065  /* Check for failure */
1066  if (apObj[auiIndices[i]] == NULL)
1067  {
1068  /* Cleanup */
1069  while (i--)
1070  {
1071  if (apObj[auiIndices[i]])
1072  GDIOBJ_vUnlockObject(apObj[auiIndices[i]]);
1073  }
1074  return FALSE;
1075  }
1076  }
1077 
1078  return TRUE;
1079 }
PGDIOBJ NTAPI GDIOBJ_LockObject(HGDIOBJ hobj, UCHAR objt)
Definition: gdiobj.c:821
GLenum GLclampf GLint GLenum GLuint GLenum GLenum GLsizei GLenum const GLvoid GLfloat GLfloat GLfloat GLfloat GLclampd GLint 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 GLboolean GLboolean GLboolean GLint GLenum GLsizei const GLvoid GLenum GLint GLenum GLint GLint GLsizei GLint GLenum GLint GLint GLint GLint GLsizei GLenum GLsizei const GLuint GLboolean GLenum GLenum GLint GLsizei GLenum GLsizei GLenum const GLvoid GLboolean const GLboolean GLenum const GLdouble const GLfloat const GLdouble const GLfloat GLenum GLint GLint GLint GLint GLint GLint j
Definition: glfuncs.h:98
#define TRUE
Definition: types.h:120
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
uint32_t ULONG_PTR
Definition: typedefs.h:63
GLenum GLclampf GLint i
Definition: glfuncs.h:14
#define FALSE
Definition: types.h:117
smooth NULL
Definition: ftsmooth.c:557
VOID NTAPI GDIOBJ_vUnlockObject(POBJ pobj)
Definition: gdiobj.c:875
unsigned int UINT
Definition: ndis.h:50
BOOL NTAPI GDIOBJ_ConvertToStockObj ( HGDIOBJ phObj)

Definition at line 1450 of file gdiobj.c.

Referenced by CreateStockObjects(), and CreateSysColorObjects().

1451 {
1452  PENTRY pentry;
1453  POBJ pobj;
1454 
1455  /* Reference the handle entry */
1456  pentry = ENTRY_ReferenceEntryByHandle(*phObj, 0);
1457  if (!pentry)
1458  {
1459  DPRINT1("GDIOBJ: Requested handle 0x%p is not valid.\n", *phObj);
1460  return FALSE;
1461  }
1462 
1463  /* Update the entry */
1464  pentry->FullUnique |= GDI_ENTRY_STOCK_MASK;
1465  pentry->ObjectOwner.ulObj = 0;
1466 
1467  /* Get the pointer to the BASEOBJECT */
1468  pobj = pentry->einfo.pobj;
1469 
1470  /* Calculate the new handle */
1471  pobj->hHmgr = (HGDIOBJ)((ULONG_PTR)pobj->hHmgr | GDI_HANDLE_STOCK_MASK);
1472 
1473  /* Return the new handle */
1474  *phObj = pobj->hHmgr;
1475 
1476  /* Dereference the handle */
1478 
1479  return TRUE;
1480 }
#define TRUE
Definition: types.h:120
struct _BASEOBJECT * pobj
Definition: ntgdihdl.h:230
VOID NTAPI GDIOBJ_vDereferenceObject(POBJ pobj)
Definition: gdiobj.c:626
#define GDI_ENTRY_STOCK_MASK
Definition: ntgdihdl.h:33
HGDIOBJ hHmgr
Definition: gdiobj.h:40
union _ENTRY::_EINFO einfo
uint32_t ULONG_PTR
Definition: typedefs.h:63
static PENTRY ENTRY_ReferenceEntryByHandle(HGDIOBJ hobj, FLONG fl)
Definition: gdiobj.c:476
#define FALSE
Definition: types.h:117
ULONG ulObj
Definition: ntgdihdl.h:241
void * HGDIOBJ
Definition: windef.h:280
USHORT FullUnique
Definition: ntgdihdl.h:244
#define DPRINT1
Definition: precomp.h:8
union _ENTRY::_OBJECTOWNER ObjectOwner
Definition: ntgdihdl.h:226
#define GDI_HANDLE_STOCK_MASK
Definition: gdi.h:19
HGDIOBJ NTAPI GDIOBJ_hInsertObject ( POBJ  pobj,
ULONG  ulOwner 
)

Definition at line 907 of file gdiobj.c.

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

910 {
911  PENTRY pentry;
912  UCHAR objt;
913 
914  /* Must have no handle and only one reference */
915  ASSERT(GDI_HANDLE_GET_INDEX(pobj->hHmgr) == 0);
916  ASSERT(pobj->cExclusiveLock == 0);
917  ASSERT(pobj->ulShareCount == 1);
918 
919  /* Get a free handle entry */
920  pentry = ENTRY_pentPopFreeEntry();
921  if (!pentry)
922  {
923  DPRINT1("GDIOBJ: Could not get a free entry.\n");
924  return NULL;
925  }
926 
927  /* Make the object exclusively locked */
931  pobj->cExclusiveLock = 1;
934 
935  /* Get object type from the hHmgr field */
936  objt = ((ULONG_PTR)pobj->hHmgr >> 16) & 0xff;
937  ASSERT(objt != GDIObjType_DEF_TYPE);
938 
939  /* Check if current process is requested owner */
940  if (ulOwner == GDI_OBJ_HMGR_POWNED)
941  {
942  /* Increment the process handle count */
944 
945  /* Use Process id */
947  }
948 
949  /* Insert the object into the handle table */
950  pobj->hHmgr = ENTRY_hInsertObject(pentry, pobj, objt, ulOwner);
951 
952  /* Return the handle */
953  DPRINT("GDIOBJ: Created handle: %p\n", pobj->hHmgr);
954  DBG_LOGEVENT(&pobj->slhLog, EVENT_CREATE_HANDLE, 0);
955  return pobj->hHmgr;
956 }
#define GDI_HANDLE_GET_INDEX(h)
Definition: gdi.h:28
FORCEINLINE VOID ExAcquirePushLockExclusive(PEX_PUSH_LOCK PushLock)
Definition: ex.h:966
ULONG ulShareCount
Definition: gdiobj.h:42
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
#define HandleToUlong(h)
Definition: basetsd.h:78
DWORD dwThreadId
Definition: gdiobj.h:43
USHORT cExclusiveLock
Definition: gdiobj.h:45
HGDIOBJ hHmgr
Definition: gdiobj.h:40
#define DBG_LOGEVENT(pslh, type, val)
Definition: gdidebug.h:109
smooth NULL
Definition: ftsmooth.c:557
EX_PUSH_LOCK pushlock
Definition: gdiobj.h:47
void DPRINT(...)
Definition: polytest.cpp:61
#define ExInitializePushLock
Definition: ex.h:943
PsGetCurrentThreadId
Definition: CrNtStubs.h:7
#define PtrToUlong(p)
Definition: basetsd.h:82
FORCEINLINE void INCREASE_THREAD_LOCK_COUNT(_In_ HANDLE hobj)
Definition: gdiobj.c:63
static PENTRY ENTRY_pentPopFreeEntry(VOID)
Definition: gdiobj.c:380
FORCEINLINE VOID IncrementCurrentProcessGdiHandleCount(void)
Definition: gdiobj.c:330
unsigned char UCHAR
Definition: xmlstorage.h:181
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
static HGDIOBJ ENTRY_hInsertObject(PENTRY pentry, POBJ pobj, UCHAR objt, ULONG ulOwner)
Definition: gdiobj.c:534
#define GDI_OBJ_HMGR_POWNED
Definition: ntgdihdl.h:117
HANDLE NTAPI PsGetCurrentProcessId(VOID)
Definition: process.c:1123
#define DPRINT1
Definition: precomp.h:8
#define ULONG_PTR
Definition: config.h:101
Definition: ntgdihdl.h:226
PGDIOBJ NTAPI GDIOBJ_LockObject ( HGDIOBJ  hobj,
UCHAR  objt 
)

Definition at line 821 of file gdiobj.c.

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

824 {
825  PENTRY pentry;
826  POBJ pobj;
828 
829  /* Check if the handle type matches */
831  if ((((ULONG_PTR)hobj >> 16) & 0x1f) != objt)
832  {
833  DPRINT("Wrong object type: hobj=0x%p, objt=0x%x\n", hobj, objt);
834  return NULL;
835  }
836 
837  /* Make sure lock order is correct */
838  ASSERT_LOCK_ORDER(objt);
839 
840  /* Reference the handle entry */
841  pentry = ENTRY_ReferenceEntryByHandle(hobj, 0);
842  if (!pentry)
843  {
844  DPRINT("GDIOBJ: Requested handle 0x%p is not valid.\n", hobj);
845  return NULL;
846  }
847 
848  /* Get the pointer to the BASEOBJECT */
849  pobj = pentry->einfo.pobj;
850 
851  /* Check if we already own the lock */
852  dwThreadId = PtrToUlong(PsGetCurrentThreadId());
853  if (pobj->dwThreadId != dwThreadId)
854  {
855  /* Disable APCs and acquire the push lock */
858 
859  /* Set us as lock owner */
860  ASSERT(pobj->dwThreadId == 0);
861  pobj->dwThreadId = dwThreadId;
862  }
863 
864  /* Increase lock count */
865  pobj->cExclusiveLock++;
867  DBG_LOGEVENT(&pobj->slhLog, EVENT_LOCK, 0);
868 
869  /* Return the object */
870  return pobj;
871 }
FORCEINLINE VOID ExAcquirePushLockExclusive(PEX_PUSH_LOCK PushLock)
Definition: ex.h:966
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
struct _BASEOBJECT * pobj
Definition: ntgdihdl.h:230
DWORD dwThreadId
Definition: gdiobj.h:43
USHORT cExclusiveLock
Definition: gdiobj.h:45
DWORD DWORD
Definition: winlogon.h:75
union _ENTRY::_EINFO einfo
uint32_t ULONG_PTR
Definition: typedefs.h:63
static PENTRY ENTRY_ReferenceEntryByHandle(HGDIOBJ hobj, FLONG fl)
Definition: gdiobj.c:476
#define DBG_LOGEVENT(pslh, type, val)
Definition: gdidebug.h:109
smooth NULL
Definition: ftsmooth.c:557
EX_PUSH_LOCK pushlock
Definition: gdiobj.h:47
void DPRINT(...)
Definition: polytest.cpp:61
PsGetCurrentThreadId
Definition: CrNtStubs.h:7
#define PtrToUlong(p)
Definition: basetsd.h:82
FORCEINLINE void INCREASE_THREAD_LOCK_COUNT(_In_ HANDLE hobj)
Definition: gdiobj.c:63
#define ASSERT_LOCK_ORDER(hobj)
Definition: gdiobj.c:122
DWORD dwThreadId
Definition: fdebug.c:31
#define ASSERT_EXCLUSIVE_OBJECT_TYPE(objt)
Definition: gdiobj.c:124
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
Definition: ntgdihdl.h:226
PVOID NTAPI GDIOBJ_pvGetObjectAttr ( POBJ  pobj)

Definition at line 1083 of file gdiobj.c.

1084 {
1086  return gpentHmgr[ulIndex].pUser;
1087 }
#define GDI_HANDLE_GET_INDEX(h)
Definition: gdi.h:28
PVOID pUser
Definition: ntgdihdl.h:247
HGDIOBJ hHmgr
Definition: gdiobj.h:40
PENTRY gpentHmgr
Definition: gdiobj.c:147
ULONG ulIndex
Definition: symbols.c:92
unsigned int ULONG
Definition: retypes.h:1
POBJ NTAPI GDIOBJ_ReferenceObjectByHandle ( HGDIOBJ  hobj,
UCHAR  objt 
)

Definition at line 686 of file gdiobj.c.

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

689 {
690  PENTRY pentry;
691  POBJ pobj;
692 
693  /* Check if the handle type matches */
695  if ((((ULONG_PTR)hobj >> 16) & 0x1f) != objt)
696  {
697  DPRINT("GDIOBJ: Wrong type. handle=%p, type=%x\n", hobj, objt);
698  return NULL;
699  }
700 
701  /* Reference the handle entry */
702  pentry = ENTRY_ReferenceEntryByHandle(hobj, 0);
703  if (!pentry)
704  {
705  DPRINT("GDIOBJ: Requested handle 0x%p is not valid.\n", hobj);
706  return NULL;
707  }
708 
709  /* Get the pointer to the BASEOBJECT */
710  pobj = pentry->einfo.pobj;
711 
712  /* Check if the object is exclusively locked */
713  if (pobj->cExclusiveLock != 0)
714  {
715  DPRINT1("GDIOBJ: Cannot reference object %p with exclusive lock.\n", hobj);
717  DBG_DUMP_EVENT_LIST(&pobj->slhLog);
718  return NULL;
719  }
720 
721  DBG_LOGEVENT(&pobj->slhLog, EVENT_REFERENCE, gpaulRefCount[pentry - gpentHmgr]);
722 
723  /* All is well, return the object */
724  return pobj;
725 }
struct _BASEOBJECT * pobj
Definition: ntgdihdl.h:230
VOID NTAPI GDIOBJ_vDereferenceObject(POBJ pobj)
Definition: gdiobj.c:626
USHORT cExclusiveLock
Definition: gdiobj.h:45
union _ENTRY::_EINFO einfo
uint32_t ULONG_PTR
Definition: typedefs.h:63
static PENTRY ENTRY_ReferenceEntryByHandle(HGDIOBJ hobj, FLONG fl)
Definition: gdiobj.c:476
#define DBG_LOGEVENT(pslh, type, val)
Definition: gdidebug.h:109
PULONG gpaulRefCount
Definition: gdiobj.c:148
smooth NULL
Definition: ftsmooth.c:557
void DPRINT(...)
Definition: polytest.cpp:61
#define ASSERT_SHARED_OBJECT_TYPE(objt)
Definition: gdiobj.c:123
#define DBG_DUMP_EVENT_LIST(pslh)
Definition: gdidebug.h:111
PENTRY gpentHmgr
Definition: gdiobj.c:147
#define DPRINT1
Definition: precomp.h:8
Definition: ntgdihdl.h:226
PGDIOBJ NTAPI GDIOBJ_ShareLockObj ( HGDIOBJ  hObj,
DWORD  ExpectedType 
)

Definition at line 1438 of file gdiobj.c.

Referenced by BASEOBJECT::LockShared().

1439 {
1440  if (ExpectedType == GDI_OBJECT_TYPE_DONTCARE)
1441  ExpectedType = GDI_HANDLE_GET_TYPE(hObj);
1442  return GDIOBJ_ReferenceObjectByHandle(hObj, (ExpectedType >> 16) & 0x1f);
1443 }
POBJ NTAPI GDIOBJ_ReferenceObjectByHandle(HGDIOBJ hobj, UCHAR objt)
Definition: gdiobj.c:686
#define GDI_HANDLE_GET_TYPE(h)
Definition: gdi.h:31
#define GDI_OBJECT_TYPE_DONTCARE
Definition: gdi.h:64
PGDIOBJ NTAPI GDIOBJ_TryLockObject ( HGDIOBJ  hobj,
UCHAR  objt 
)

Definition at line 752 of file gdiobj.c.

Referenced by DRIVEROBJ_TryLockObject().

755 {
756  PENTRY pentry;
757  POBJ pobj;
759 
760  /* Check if the handle type matches */
762  if ((((ULONG_PTR)hobj >> 16) & 0x1f) != objt)
763  {
764  DPRINT("Wrong object type: hobj=0x%p, objt=0x%x\n", hobj, objt);
765  return NULL;
766  }
767 
768  /* Make sure lock order is correct */
769  ASSERT_LOCK_ORDER(objt);
770 
771  /* Reference the handle entry */
772  pentry = ENTRY_ReferenceEntryByHandle(hobj, 0);
773  if (!pentry)
774  {
775  DPRINT("GDIOBJ: Requested handle 0x%p is not valid.\n", hobj);
776  return NULL;
777  }
778 
779  /* Get the pointer to the BASEOBJECT */
780  pobj = pentry->einfo.pobj;
781 
782  /* Check if we already own the lock */
783  dwThreadId = PtrToUlong(PsGetCurrentThreadId());
784  if (pobj->dwThreadId != dwThreadId)
785  {
786  /* Disable APCs and try acquiring the push lock */
789  {
790  ULONG cRefs, ulIndex;
791  /* Already owned. Clean up and leave. */
793 
794  /* Calculate the index */
795  ulIndex = GDI_HANDLE_GET_INDEX(pobj->hHmgr);
796 
797  /* Decrement reference count */
798  ASSERT((gpaulRefCount[ulIndex] & REF_MASK_COUNT) > 0);
799  cRefs = InterlockedDecrement((LONG*)&gpaulRefCount[ulIndex]);
800  ASSERT(cRefs & REF_MASK_VALID);
801 
802  return NULL;
803  }
804 
805  /* Set us as lock owner */
806  ASSERT(pobj->dwThreadId == 0);
807  pobj->dwThreadId = dwThreadId;
808  }
809 
810  /* Increase lock count */
811  pobj->cExclusiveLock++;
813  DBG_LOGEVENT(&pobj->slhLog, EVENT_LOCK, 0);
814 
815  /* Return the object */
816  return pobj;
817 }
#define GDI_HANDLE_GET_INDEX(h)
Definition: gdi.h:28
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
#define ASSERT_TRYLOCK_OBJECT_TYPE(objt)
Definition: gdiobj.c:125
struct _BASEOBJECT * pobj
Definition: ntgdihdl.h:230
DWORD dwThreadId
Definition: gdiobj.h:43
USHORT cExclusiveLock
Definition: gdiobj.h:45
HGDIOBJ hHmgr
Definition: gdiobj.h:40
DWORD DWORD
Definition: winlogon.h:75
union _ENTRY::_EINFO einfo
uint32_t ULONG_PTR
Definition: typedefs.h:63
static PENTRY ENTRY_ReferenceEntryByHandle(HGDIOBJ hobj, FLONG fl)
Definition: gdiobj.c:476
long LONG
Definition: pedump.c:60
#define DBG_LOGEVENT(pslh, type, val)
Definition: gdidebug.h:109
PULONG gpaulRefCount
Definition: gdiobj.c:148
smooth NULL
Definition: ftsmooth.c:557
EX_PUSH_LOCK pushlock
Definition: gdiobj.h:47
void DPRINT(...)
Definition: polytest.cpp:61
PsGetCurrentThreadId
Definition: CrNtStubs.h:7
#define PtrToUlong(p)
Definition: basetsd.h:82
FORCEINLINE void INCREASE_THREAD_LOCK_COUNT(_In_ HANDLE hobj)
Definition: gdiobj.c:63
#define ASSERT_LOCK_ORDER(hobj)
Definition: gdiobj.c:122
DWORD dwThreadId
Definition: fdebug.c:31
#define InterlockedDecrement
Definition: armddk.h:52
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
ULONG ulIndex
Definition: symbols.c:92
#define KeLeaveCriticalRegion()
Definition: ke_x.h:114
unsigned int ULONG
Definition: retypes.h:1
Definition: ntgdihdl.h:226
FORCEINLINE BOOLEAN ExTryAcquirePushLockExclusive(PEX_PUSH_LOCK PushLock)
Definition: misc.h:117
static VOID NTAPI GDIOBJ_vCleanup ( PVOID  ObjectBody)
static

Definition at line 236 of file gdiobj.c.

237 {
238  /* Nothing to do */
239 }
VOID NTAPI GDIOBJ_vDeleteObject ( POBJ  pobj)

Definition at line 1106 of file gdiobj.c.

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

1107 {
1108  ULONG ulIndex;
1109 
1110  /* Set the object's delete flag */
1112  DBG_LOGEVENT(&pobj->slhLog, EVENT_DELETE, 0);
1113 
1114  /* Get the handle index */
1115  ulIndex = GDI_HANDLE_GET_INDEX(pobj->hHmgr);
1116  if (ulIndex)
1117  {
1118  /* Reset the handle valid bit */
1120 
1121  /* Check if the object is exclusively locked */
1122  if (pobj->cExclusiveLock != 0)
1123  {
1124  /* Reset lock owner and lock count */
1125  pobj->dwThreadId = 0;
1126  pobj->cExclusiveLock = 0;
1127 
1128  /* Release the pushlock and reenable APCs */
1132  }
1133  }
1134 
1135  /* Dereference the object (will take care of deletion) */
1137 }
#define GDI_HANDLE_GET_INDEX(h)
Definition: gdi.h:28
#define InterlockedAnd
Definition: interlocked.h:62
DWORD dwThreadId
Definition: gdiobj.h:43
VOID NTAPI GDIOBJ_vDereferenceObject(POBJ pobj)
Definition: gdiobj.c:626
USHORT cExclusiveLock
Definition: gdiobj.h:45
HGDIOBJ hHmgr
Definition: gdiobj.h:40
USHORT BaseFlags
Definition: gdiobj.h:46
long LONG
Definition: pedump.c:60
#define DBG_LOGEVENT(pslh, type, val)
Definition: gdidebug.h:109
short SHORT
Definition: pedump.c:59
FORCEINLINE void DECREASE_THREAD_LOCK_COUNT(_In_ HANDLE hobj)
Definition: gdiobj.c:79
FORCEINLINE VOID ExReleasePushLockExclusive(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1182
PULONG gpaulRefCount
Definition: gdiobj.c:148
EX_PUSH_LOCK pushlock
Definition: gdiobj.h:47
ULONG ulIndex
Definition: symbols.c:92
#define KeLeaveCriticalRegion()
Definition: ke_x.h:114
unsigned int ULONG
Definition: retypes.h:1
#define InterlockedOr16
Definition: interlocked.h:239
VOID NTAPI GDIOBJ_vDereferenceObject ( POBJ  pobj)

Definition at line 626 of file gdiobj.c.

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

627 {
628  ULONG cRefs, ulIndex;
629 
630  /* Calculate the index */
631  ulIndex = GDI_HANDLE_GET_INDEX(pobj->hHmgr);
632 
633  /* Check if the object has a handle */
634  if (ulIndex)
635  {
636  /* Decrement reference count */
637  if ((gpaulRefCount[ulIndex] & REF_MASK_COUNT) == 0)
638  {
639  DBG_DUMP_EVENT_LIST(&pobj->slhLog);
640  }
641  ASSERT((gpaulRefCount[ulIndex] & REF_MASK_COUNT) > 0);
642  cRefs = InterlockedDecrement((LONG*)&gpaulRefCount[ulIndex]);
643  DBG_LOGEVENT(&pobj->slhLog, EVENT_DEREFERENCE, cRefs);
644 
645  /* Check if we reached 0 and handle bit is not set */
646  if ((cRefs & REF_MASK_INUSE) == 0)
647  {
648  /* Make sure it's ok to delete the object */
650 
651  /* Check if the handle was process owned */
652  if (gpentHmgr[ulIndex].ObjectOwner.ulObj != GDI_OBJ_HMGR_PUBLIC &&
654  {
655  /* Decrement the process handle count */
656  ASSERT(gpentHmgr[ulIndex].ObjectOwner.ulObj ==
659  }
660 
661  /* Push entry to the free list */
662  ENTRY_vPushFreeEntry(&gpentHmgr[ulIndex]);
663 
664  /* Free the object */
665  GDIOBJ_vFreeObject(pobj);
666  }
667  }
668  else
669  {
670  /* Decrement the objects reference count */
671  ASSERT(pobj->ulShareCount > 0);
672  cRefs = InterlockedDecrement((LONG*)&pobj->ulShareCount);
673  DBG_LOGEVENT(&pobj->slhLog, EVENT_DEREFERENCE, cRefs);
674 
675  /* Check if we reached 0 */
676  if (cRefs == 0)
677  {
678  /* Free the object */
679  GDIOBJ_vFreeObject(pobj);
680  }
681  }
682 }
#define GDI_HANDLE_GET_INDEX(h)
Definition: gdi.h:28
ULONG ulShareCount
Definition: gdiobj.h:42
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
#define HandleToUlong(h)
Definition: basetsd.h:78
HGDIOBJ hHmgr
Definition: gdiobj.h:40
FORCEINLINE VOID DecrementCurrentProcessGdiHandleCount(void)
Definition: gdiobj.c:338
USHORT BaseFlags
Definition: gdiobj.h:46
static VOID ENTRY_vPushFreeEntry(PENTRY pentFree)
Definition: gdiobj.c:437
long LONG
Definition: pedump.c:60
#define DBG_LOGEVENT(pslh, type, val)
Definition: gdidebug.h:109
PULONG gpaulRefCount
Definition: gdiobj.c:148
ULONG ulObj
Definition: ntgdihdl.h:241
#define DBG_DUMP_EVENT_LIST(pslh)
Definition: gdidebug.h:111
#define InterlockedDecrement
Definition: armddk.h:52
PENTRY gpentHmgr
Definition: gdiobj.c:147
ULONG ulIndex
Definition: symbols.c:92
#define GDI_OBJ_HMGR_PUBLIC
Definition: ntgdihdl.h:116
HANDLE NTAPI PsGetCurrentProcessId(VOID)
Definition: process.c:1123
#define GDI_OBJ_HMGR_NONE
Definition: ntgdihdl.h:118
unsigned int ULONG
Definition: retypes.h:1
union _ENTRY::_OBJECTOWNER ObjectOwner
VOID NTAPI GDIOBJ_vFreeObject(POBJ pobj)
Definition: gdiobj.c:591
VOID NTAPI GDIOBJ_vFreeObject ( POBJ  pobj)

Definition at line 591 of file gdiobj.c.

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

592 {
593  UCHAR objt;
594 
595  DBG_CLEANUP_EVENT_LIST(&pobj->slhLog);
596 
597  /* Get the object type */
598  objt = ((ULONG_PTR)pobj->hHmgr >> 16) & 0x1f;
599 
600  /* Check if we have a delete procedure (for C++ based objects) */
601  if (apfnDelete[objt] != NULL)
602  {
603  /* Invoke the delete procedure */
604  apfnDelete[objt](pobj);
605  }
606  else
607  {
608  /* Call the cleanup procedure */
609  NT_ASSERT(apfnCleanup[objt]);
610  apfnCleanup[objt](pobj);
611 
612  /* Check if the object is allocated from a lookaside list */
613  if (pobj->BaseFlags & BASEFLAG_LOOKASIDE)
614  {
615  ExFreeToPagedLookasideList(&gpaLookasideList[objt], pobj);
616  }
617  else
618  {
619  ExFreePoolWithTag(pobj, GDIOBJ_POOL_TAG(objt));
620  }
621  }
622 }
static PPAGED_LOOKASIDE_LIST gpaLookasideList
Definition: gdiobj.c:151
HGDIOBJ hHmgr
Definition: gdiobj.h:40
USHORT BaseFlags
Definition: gdiobj.h:46
#define GDIOBJ_POOL_TAG(type)
Definition: gdiobj.c:132
smooth NULL
Definition: ftsmooth.c:557
static const GDIOBJDELETEPROC apfnDelete[]
Definition: gdiobj.c:195
unsigned char UCHAR
Definition: xmlstorage.h:181
#define DBG_CLEANUP_EVENT_LIST(pslh)
Definition: gdidebug.h:112
#define ULONG_PTR
Definition: config.h:101
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1097
static const GDICLEANUPPROC apfnCleanup[]
Definition: gdiobj.c:157
#define NT_ASSERT
Definition: rtlfuncs.h:3312
VOID NTAPI GDIOBJ_vReferenceObjectByPointer ( POBJ  pobj)

Definition at line 729 of file gdiobj.c.

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

730 {
731  ULONG cRefs;
732 
733  /* Check if the object has a handle */
734  if (GDI_HANDLE_GET_INDEX(pobj->hHmgr))
735  {
736  /* Increase the handle's reference count */
738  ASSERT((gpaulRefCount[ulIndex] & REF_MASK_COUNT) > 0);
739  cRefs = InterlockedIncrement((LONG*)&gpaulRefCount[ulIndex]);
740  }
741  else
742  {
743  /* Increase the object's reference count */
744  cRefs = InterlockedIncrement((LONG*)&pobj->ulShareCount);
745  }
746 
747  DBG_LOGEVENT(&pobj->slhLog, EVENT_REFERENCE, cRefs);
748 }
#define GDI_HANDLE_GET_INDEX(h)
Definition: gdi.h:28
ULONG ulShareCount
Definition: gdiobj.h:42
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
HGDIOBJ hHmgr
Definition: gdiobj.h:40
long LONG
Definition: pedump.c:60
#define DBG_LOGEVENT(pslh, type, val)
Definition: gdidebug.h:109
PULONG gpaulRefCount
Definition: gdiobj.c:148
ULONG ulIndex
Definition: symbols.c:92
#define InterlockedIncrement
Definition: armddk.h:53
unsigned int ULONG
Definition: retypes.h:1
VOID NTAPI GDIOBJ_vSetObjectAttr ( POBJ  pobj,
PVOID  pvObjAttr 
)

Definition at line 1091 of file gdiobj.c.

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

1092 {
1093  ULONG ulIndex;
1094 
1095  ASSERT(pobj->hHmgr);
1096 
1097  /* Get the handle index */
1098  ulIndex = GDI_HANDLE_GET_INDEX(pobj->hHmgr);
1099 
1100  /* Set pointer to the usermode attribute */
1101  gpentHmgr[ulIndex].pUser = pvObjAttr;
1102 }
#define GDI_HANDLE_GET_INDEX(h)
Definition: gdi.h:28
PVOID pUser
Definition: ntgdihdl.h:247
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
HGDIOBJ hHmgr
Definition: gdiobj.h:40
PENTRY gpentHmgr
Definition: gdiobj.c:147
ULONG ulIndex
Definition: symbols.c:92
unsigned int ULONG
Definition: retypes.h:1
VOID NTAPI GDIOBJ_vSetObjectOwner ( POBJ  pobj,
ULONG  ulNewOwner 
)

Definition at line 960 of file gdiobj.c.

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

963 {
964  PENTRY pentry;
965  ULONG ulOldOwner;
966 
967  /* This is a ugly HACK, needed to fix IntGdiSetDCOwnerEx */
968  if (GDI_HANDLE_IS_STOCKOBJ(pobj->hHmgr))
969  {
970  DPRINT("Trying to set ownership of stock object %p to %lx\n", pobj->hHmgr, ulNewOwner);
971  return;
972  }
973 
974  /* Get the handle entry */
976  pentry = &gpentHmgr[GDI_HANDLE_GET_INDEX(pobj->hHmgr)];
977 
978  /* Check if the new owner is the same as the old one */
979  ulOldOwner = pentry->ObjectOwner.ulObj;
980  if (ulOldOwner == ulNewOwner)
981  {
982  /* Nothing to do */
983  return;
984  }
985 
986  /* Is the current process requested? */
987  if (ulNewOwner == GDI_OBJ_HMGR_POWNED)
988  {
989  /* Use process id */
990  ulNewOwner = HandleToUlong(PsGetCurrentProcessId());
991  }
992 
993  // HACK
994  if (ulNewOwner == GDI_OBJ_HMGR_NONE)
995  ulNewOwner = GDI_OBJ_HMGR_PUBLIC;
996 
997  /* Was the object process owned? */
998  if ((ulOldOwner != GDI_OBJ_HMGR_PUBLIC) &&
999  (ulOldOwner != GDI_OBJ_HMGR_NONE))
1000  {
1001  /* Decrement the previous owners handle count */
1002  DecrementGdiHandleCount(ulOldOwner);
1003  }
1004 
1005  /* Is the new owner a process? */
1006  if ((ulNewOwner != GDI_OBJ_HMGR_PUBLIC) &&
1007  (ulNewOwner != GDI_OBJ_HMGR_NONE))
1008  {
1009  /* Increment the new owners handle count */
1010  IncrementGdiHandleCount(ulNewOwner);
1011  }
1012  else
1013  {
1014  /* Make sure we don't leak user mode memory */
1015  NT_ASSERT(pentry->pUser == NULL);
1016  }
1017 
1018  /* Set new owner */
1019  pentry->ObjectOwner.ulObj = ulNewOwner;
1020  DBG_LOGEVENT(&pobj->slhLog, EVENT_SET_OWNER, 0);
1021 }
#define GDI_HANDLE_GET_INDEX(h)
Definition: gdi.h:28
PVOID pUser
Definition: ntgdihdl.h:247
#define HandleToUlong(h)
Definition: basetsd.h:78
HGDIOBJ hHmgr
Definition: gdiobj.h:40
#define DBG_LOGEVENT(pslh, type, val)
Definition: gdidebug.h:109
smooth NULL
Definition: ftsmooth.c:557
#define GDI_HANDLE_IS_STOCKOBJ(h)
Definition: gdi.h:37
void DPRINT(...)
Definition: polytest.cpp:61
ULONG ulObj
Definition: ntgdihdl.h:241
#define GDI_OBJ_HMGR_POWNED
Definition: ntgdihdl.h:117
PENTRY gpentHmgr
Definition: gdiobj.c:147
#define GDI_OBJ_HMGR_PUBLIC
Definition: ntgdihdl.h:116
HANDLE NTAPI PsGetCurrentProcessId(VOID)
Definition: process.c:1123
FORCEINLINE VOID DecrementGdiHandleCount(ULONG ulProcessId)
Definition: gdiobj.c:363
FORCEINLINE VOID IncrementGdiHandleCount(ULONG ulProcessId)
Definition: gdiobj.c:346
#define GDI_OBJ_HMGR_NONE
Definition: ntgdihdl.h:118
unsigned int ULONG
Definition: retypes.h:1
union _ENTRY::_OBJECTOWNER ObjectOwner
Definition: ntgdihdl.h:226
#define NT_ASSERT
Definition: rtlfuncs.h:3312
VOID NTAPI GDIOBJ_vUnlockObject ( POBJ  pobj)

Definition at line 875 of file gdiobj.c.

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

876 {
877  ULONG cRefs, ulIndex;
878  ASSERT(pobj->cExclusiveLock > 0);
879 
880  /* Decrease lock count */
881  pobj->cExclusiveLock--;
883  DBG_LOGEVENT(&pobj->slhLog, EVENT_UNLOCK, 0);
884 
885  /* Check if this was the last lock */
886  if (pobj->cExclusiveLock == 0)
887  {
888  /* Reset lock owner */
889  pobj->dwThreadId = 0;
890 
891  /* Release the pushlock and reenable APCs */
894  }
895 
896  /* Calculate the index */
897  ulIndex = GDI_HANDLE_GET_INDEX(pobj->hHmgr);
898 
899  /* Decrement reference count */
900  ASSERT((gpaulRefCount[ulIndex] & REF_MASK_COUNT) > 0);
901  cRefs = InterlockedDecrement((LONG*)&gpaulRefCount[ulIndex]);
902  ASSERT(cRefs & REF_MASK_VALID);
903 }
#define GDI_HANDLE_GET_INDEX(h)
Definition: gdi.h:28
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
DWORD dwThreadId
Definition: gdiobj.h:43
USHORT cExclusiveLock
Definition: gdiobj.h:45
HGDIOBJ hHmgr
Definition: gdiobj.h:40
long LONG
Definition: pedump.c:60
#define DBG_LOGEVENT(pslh, type, val)
Definition: gdidebug.h:109
FORCEINLINE void DECREASE_THREAD_LOCK_COUNT(_In_ HANDLE hobj)
Definition: gdiobj.c:79
FORCEINLINE VOID ExReleasePushLockExclusive(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1182
PULONG gpaulRefCount
Definition: gdiobj.c:148
EX_PUSH_LOCK pushlock
Definition: gdiobj.h:47
#define InterlockedDecrement
Definition: armddk.h:52
ULONG ulIndex
Definition: symbols.c:92
#define KeLeaveCriticalRegion()
Definition: ke_x.h:114
unsigned int ULONG
Definition: retypes.h:1
PGDI_POOL GetBrushAttrPool ( VOID  )

HACK!

Definition at line 1607 of file gdiobj.c.

Referenced by BRUSH::bAllocateBrushAttr(), and BRUSH::~BRUSH().

1608 {
1609  PPROCESSINFO ppi;
1610 
1612  NT_ASSERT(ppi != NULL);
1613 
1614  return ppi->pPoolBrushAttr;
1615 }
struct _GDI_POOL * pPoolBrushAttr
Definition: win32.h:283
smooth NULL
Definition: ftsmooth.c:557
PVOID NTAPI PsGetCurrentProcessWin32Process(VOID)
Definition: process.c:1183
#define NT_ASSERT
Definition: rtlfuncs.h:3312
BOOL NTAPI GreDeleteObject ( HGDIOBJ  hobj)

Definition at line 1153 of file gdiobj.c.

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(), FreeCurIconObject(), GdiFlushUserBatch(), GreGetDIBitsInternal(), IntBeginPaint(), 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().

1154 {
1155  PENTRY pentry;
1156 
1157  /* Check for stock objects */
1158  if (GDI_HANDLE_IS_STOCKOBJ(hobj))
1159  {
1160  DPRINT1("GreDeleteObject: Cannot delete stock object %p.\n", hobj);
1161  return FALSE;
1162  }
1163 
1164  /* Reference the handle entry */
1165  pentry = ENTRY_ReferenceEntryByHandle(hobj, 0);
1166  if (!pentry)
1167  {
1168  DPRINT1("GreDeleteObject: Trying to delete invalid object %p\n", hobj);
1169  return FALSE;
1170  }
1171 
1172  /* Check for public owner */
1173  if (pentry->ObjectOwner.ulObj == GDI_OBJ_HMGR_PUBLIC)
1174  {
1175  DPRINT1("GreDeleteObject: Trying to delete global object %p\n", hobj);
1177  return FALSE;
1178  }
1179 
1180  /* Delete the object */
1181  GDIOBJ_vDeleteObject(pentry->einfo.pobj);
1182  return TRUE;
1183 }
#define TRUE
Definition: types.h:120
struct _BASEOBJECT * pobj
Definition: ntgdihdl.h:230
VOID NTAPI GDIOBJ_vDereferenceObject(POBJ pobj)
Definition: gdiobj.c:626
union _ENTRY::_EINFO einfo
static PENTRY ENTRY_ReferenceEntryByHandle(HGDIOBJ hobj, FLONG fl)
Definition: gdiobj.c:476
#define FALSE
Definition: types.h:117
#define GDI_HANDLE_IS_STOCKOBJ(h)
Definition: gdi.h:37
VOID NTAPI GDIOBJ_vDeleteObject(POBJ pobj)
Definition: gdiobj.c:1106
ULONG ulObj
Definition: ntgdihdl.h:241
#define GDI_OBJ_HMGR_PUBLIC
Definition: ntgdihdl.h:116
#define DPRINT1
Definition: precomp.h:8
union _ENTRY::_OBJECTOWNER ObjectOwner
Definition: ntgdihdl.h:226
INT NTAPI GreGetObject ( IN HGDIOBJ  hobj,
IN INT  cbCount,
IN PVOID  pvBuffer 
)

Definition at line 1259 of file gdiobj.c.

Referenced by IntUpdateLayeredWindowI(), MENU_DrawBitmapItem(), MENU_GetBitmapItemSize(), NtGdiExtGetObjectW(), and PATH_WidenPath().

1263 {
1264  PVOID pvObj;
1265  UCHAR objt;
1266  INT iResult = 0;
1267 
1268  /* Verify object type */
1269  objt = ((ULONG_PTR)hobj >> 16) & 0x1f;
1270  if (objt != GDIObjType_BRUSH_TYPE &&
1271  objt != GDIObjType_SURF_TYPE &&
1272  objt != GDIObjType_LFONT_TYPE &&
1273  objt != GDIObjType_PAL_TYPE)
1274  {
1275  DPRINT1("GreGetObject: Invalid object type\n");
1276  return 0;
1277  }
1278 
1279  pvObj = GDIOBJ_ReferenceObjectByHandle(hobj, objt);
1280  if (!pvObj)
1281  {
1282  DPRINT("GreGetObject: Could not lock object\n");
1283  return 0;
1284  }
1285 
1286  switch (GDI_HANDLE_GET_TYPE(hobj))
1287  {
1290  iResult = PEN_GetObject(pvObj, cbCount, pvBuffer);
1291  break;
1292 
1294  iResult = BRUSH_GetObject(pvObj, cbCount, pvBuffer);
1295  break;
1296 
1298  iResult = BITMAP_GetObject(pvObj, cbCount, pvBuffer);
1299  break;
1300 
1302  iResult = FontGetObject(pvObj, cbCount, pvBuffer);
1303  break;
1304 
1306  iResult = PALETTE_GetObject(pvObj, cbCount, pvBuffer);
1307  break;
1308 
1309  default:
1310  DPRINT1("GDI object type of 0x%p not implemented\n", hobj);
1311  break;
1312  }
1313 
1315  return iResult;
1316 }
DWORD *typedef PVOID
Definition: winlogon.h:52
POBJ NTAPI GDIOBJ_ReferenceObjectByHandle(HGDIOBJ hobj, UCHAR objt)
Definition: gdiobj.c:686
static int cbCount
Definition: fiber.c:42
INT APIENTRY BITMAP_GetObject(SURFACE *psurf, INT Count, LPVOID buffer)
Definition: bitmaps.c:732
INT FASTCALL BRUSH_GetObject(PBRUSH pbr, INT cjBuffer, LPLOGBRUSH plbBuffer)
Definition: brush.cpp:260
VOID NTAPI GDIOBJ_vDereferenceObject(POBJ pobj)
Definition: gdiobj.c:626
int32_t INT
Definition: typedefs.h:56
INT FASTCALL PALETTE_GetObject(PPALETTE ppal, INT cbCount, LPLOGBRUSH lpBuffer)
Definition: palette.c:244
void DPRINT(...)
Definition: polytest.cpp:61
#define GDI_HANDLE_GET_TYPE(h)
Definition: gdi.h:31
unsigned char UCHAR
Definition: xmlstorage.h:181
INT APIENTRY PEN_GetObject(PBRUSH pbrushPen, INT cbCount, PLOGPEN pBuffer)
Definition: pen.c:255
#define DPRINT1
Definition: precomp.h:8
ULONG FASTCALL FontGetObject(PTEXTOBJ plfont, ULONG cjBuffer, PVOID pvBuffer)
Definition: font.c:293
#define ULONG_PTR
Definition: config.h:101
ULONG NTAPI GreGetObjectOwner ( HGDIOBJ  hobj)

Definition at line 1187 of file gdiobj.c.

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

1188 {
1189  ULONG ulIndex, ulOwner;
1190 
1191  /* Get the handle index */
1192  ulIndex = GDI_HANDLE_GET_INDEX(hobj);
1193 
1194  /* Check if the handle is valid */
1195  if (ulIndex >= GDI_HANDLE_COUNT ||
1196  gpentHmgr[ulIndex].Objt == GDIObjType_DEF_TYPE ||
1197  ((ULONG_PTR)hobj >> 16) != gpentHmgr[ulIndex].FullUnique)
1198  {
1199  DPRINT1("GreGetObjectOwner: invalid handle 0x%p.\n", hobj);
1200  return GDI_OBJ_HMGR_RESTRICTED;
1201  }
1202 
1203  /* Get the object owner */
1204  ulOwner = gpentHmgr[ulIndex].ObjectOwner.ulObj;
1205 
1206  if (ulOwner == HandleToUlong(PsGetCurrentProcessId()))
1207  return GDI_OBJ_HMGR_POWNED;
1208 
1209  if (ulOwner == GDI_OBJ_HMGR_PUBLIC)
1210  return GDI_OBJ_HMGR_PUBLIC;
1211 
1212  return GDI_OBJ_HMGR_RESTRICTED;
1213 }
#define GDI_HANDLE_GET_INDEX(h)
Definition: gdi.h:28
#define GDI_OBJ_HMGR_RESTRICTED
Definition: ntgdihdl.h:119
#define HandleToUlong(h)
Definition: basetsd.h:78
uint32_t ULONG_PTR
Definition: typedefs.h:63
ULONG ulObj
Definition: ntgdihdl.h:241
#define GDI_OBJ_HMGR_POWNED
Definition: ntgdihdl.h:117
PENTRY gpentHmgr
Definition: gdiobj.c:147
ULONG ulIndex
Definition: symbols.c:92
#define GDI_HANDLE_COUNT
Definition: gdi.h:12
#define GDI_OBJ_HMGR_PUBLIC
Definition: ntgdihdl.h:116
HANDLE NTAPI PsGetCurrentProcessId(VOID)
Definition: process.c:1123
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
union _ENTRY::_OBJECTOWNER ObjectOwner
BOOL NTAPI GreIsHandleValid ( HGDIOBJ  hobj)

Definition at line 1141 of file gdiobj.c.

Referenced by co_IntPaintWindows(), co_UserFreeWindow(), DceFreeDCE(), DceResetActiveDCEs(), GetControlColor(), IntBeginPaint(), IntGdiDeleteDC(), NC_HandleNCActivate(), NtGdiEqualRgn(), NtGdiFlushUserBatch(), NtUserSetWindowRgn(), PaintSuspendedWindow(), UserGetDCEx(), and BRUSH::~BRUSH().

1142 {
1143  PENTRY pentry;
1144 
1145  pentry = ENTRY_ReferenceEntryByHandle(hobj, 0);
1146  if (!pentry) return FALSE;
1148  return TRUE;
1149 }
#define TRUE
Definition: types.h:120
struct _BASEOBJECT * pobj
Definition: ntgdihdl.h:230
VOID NTAPI GDIOBJ_vDereferenceObject(POBJ pobj)
Definition: gdiobj.c:626
union _ENTRY::_EINFO einfo
static PENTRY ENTRY_ReferenceEntryByHandle(HGDIOBJ hobj, FLONG fl)
Definition: gdiobj.c:476
#define FALSE
Definition: types.h:117
Definition: ntgdihdl.h:226
BOOL NTAPI GreSetObjectOwner ( HGDIOBJ  hobj,
ULONG  ulOwner 
)
BOOL NTAPI GreSetObjectOwnerEx ( HGDIOBJ  hobj,
ULONG  ulOwner,
ULONG  Flags 
)

Definition at line 1217 of file gdiobj.c.

Referenced by GreSetObjectOwner(), and NtUserConsoleControl().

1221 {
1222  PENTRY pentry;
1223 
1224  /* Check for stock objects */
1225  if (GDI_HANDLE_IS_STOCKOBJ(hobj))
1226  {
1227  DPRINT("GreSetObjectOwner: Got stock object %p\n", hobj);
1228  return FALSE;
1229  }
1230 
1231  /* Reference the handle entry */
1232  pentry = ENTRY_ReferenceEntryByHandle(hobj, Flags);
1233  if (!pentry)
1234  {
1235  DPRINT("GreSetObjectOwner: Invalid handle 0x%p.\n", hobj);
1236  return FALSE;
1237  }
1238 
1239  /* Call internal function */
1240  GDIOBJ_vSetObjectOwner(pentry->einfo.pobj, ulOwner);
1241 
1242  /* Dereference the object */
1244 
1245  return TRUE;
1246 }
#define TRUE
Definition: types.h:120
struct _BASEOBJECT * pobj
Definition: ntgdihdl.h:230
VOID NTAPI GDIOBJ_vDereferenceObject(POBJ pobj)
Definition: gdiobj.c:626
union _ENTRY::_EINFO einfo
static PENTRY ENTRY_ReferenceEntryByHandle(HGDIOBJ hobj, FLONG fl)
Definition: gdiobj.c:476
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define FALSE
Definition: types.h:117
#define GDI_HANDLE_IS_STOCKOBJ(h)
Definition: gdi.h:37
void DPRINT(...)
Definition: polytest.cpp:61
VOID NTAPI GDIOBJ_vSetObjectOwner(POBJ pobj, ULONG ulNewOwner)
Definition: gdiobj.c:960
Definition: ntgdihdl.h:226
FORCEINLINE void INCREASE_THREAD_LOCK_COUNT ( _In_ HANDLE  hobj)

Definition at line 63 of file gdiobj.c.

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

65 {
68  if (pti)
69  {
70 #if DBG
71  pti->acExclusiveLockCount[((ULONG_PTR)hobj >> 16) & 0x1f]++;
72 #endif
73  pti->cExclusiveLocks++;
74  }
75 }
#define DBG_UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
PVOID NTAPI PsGetCurrentThreadWin32Thread(VOID)
Definition: thread.c:805
ULONG cExclusiveLocks
Definition: win32.h:152
#define ULONG_PTR
Definition: config.h:101
FORCEINLINE VOID IncrementCurrentProcessGdiHandleCount ( void  )

Definition at line 330 of file gdiobj.c.

Referenced by GDIOBJ_hInsertObject().

331 {
333  if (ppi) InterlockedIncrement((LONG*)&ppi->GDIHandleCount);
334 }
long LONG
Definition: pedump.c:60
#define InterlockedIncrement
Definition: armddk.h:53
PVOID NTAPI PsGetCurrentProcessWin32Process(VOID)
Definition: process.c:1183
FORCEINLINE VOID IncrementGdiHandleCount ( ULONG  ulProcessId)

Definition at line 346 of file gdiobj.c.

Referenced by GDIOBJ_vSetObjectOwner().

347 {
348  PEPROCESS pep;
349  PPROCESSINFO ppi;
351 
352  Status = PsLookupProcessByProcessId(ULongToHandle(ulProcessId), &pep);
353  NT_ASSERT(NT_SUCCESS(Status));
354  __analysis_assume(NT_SUCCESS(Status));
355 
356  ppi = PsGetProcessWin32Process(pep);
357  if (ppi) InterlockedIncrement((LONG*)&ppi->GDIHandleCount);
358  if (NT_SUCCESS(Status)) ObDereferenceObject(pep);
359 }
#define ULongToHandle(h)
Definition: basetsd.h:80
PVOID NTAPI PsGetProcessWin32Process(PEPROCESS Process)
Definition: process.c:1193
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:267
long LONG
Definition: pedump.c:60
#define __analysis_assume(expr)
Definition: sal.h:1111
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
NTSTATUS NTAPI PsLookupProcessByProcessId(IN HANDLE ProcessId, OUT PEPROCESS *Process)
Definition: process.c:919
Status
Definition: gdiplustypes.h:24
LONG NTSTATUS
Definition: DriverTester.h:11
#define InterlockedIncrement
Definition: armddk.h:53
#define NT_ASSERT
Definition: rtlfuncs.h:3312
INIT_FUNCTION NTSTATUS NTAPI InitGdiHandleTable ( void  )

Definition at line 257 of file gdiobj.c.

Referenced by DriverEntry().

258 {
260  LARGE_INTEGER liSize;
261  PVOID pvSection;
262  SIZE_T cjViewSize = 0;
263 
264  /* Create a section for the shared handle table */
265  liSize.QuadPart = sizeof(GDI_HANDLE_TABLE); // GDI_HANDLE_COUNT * sizeof(ENTRY);
268  NULL,
269  &liSize,
271  SEC_COMMIT | 0x1,
272  NULL,
273  NULL);
274  if (!NT_SUCCESS(status))
275  {
276  DPRINT1("INITGDI: Could not allocate a GDI handle table.\n");
277  return status;
278  }
279 
280  /* Map the section in session space */
282  (PVOID*)&gpentHmgr,
283  &cjViewSize);
284  if (!NT_SUCCESS(status))
285  {
286  DPRINT1("INITGDI: Failed to map handle table section\n");
288  return status;
289  }
290 
291  /* Allocate memory for the reference counter table */
292  gpaulRefCount = EngAllocSectionMem(&pvSection,
294  GDI_HANDLE_COUNT * sizeof(ULONG),
295  'frHG');
296  if (!gpaulRefCount)
297  {
298  DPRINT1("INITGDI: Failed to allocate reference table.\n");
301  }
302 
303  gulFirstFree = 0;
305 
307 
308  /* Initialize the lookaside lists */
312  if(!gpaLookasideList)
313  return STATUS_NO_MEMORY;
314 
324 
325  return STATUS_SUCCESS;
326 }
DWORD *typedef PVOID
Definition: winlogon.h:52
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
volatile ULONG gulFirstUnused
Definition: gdiobj.c:150
return STATUS_SUCCESS
Definition: btrfs.c:2664
static PPAGED_LOOKASIDE_LIST gpaLookasideList
Definition: gdiobj.c:151
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG x1
Definition: winddi.h:3706
Definition: path.h:27
static VOID InitLookasideList(UCHAR objt, ULONG cjSize)
Definition: gdiobj.c:243
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:267
volatile ULONG gulFirstFree
Definition: gdiobj.c:149
#define SECTION_ALL_ACCESS
Definition: nt_native.h:1293
#define SEC_COMMIT
Definition: mmtypes.h:99
Definition: text.h:59
PULONG gpaulRefCount
Definition: gdiobj.c:148
smooth NULL
Definition: ftsmooth.c:557
PGDI_HANDLE_TABLE GdiHandleTable
Definition: gdiobj.c:1435
Definition: region.h:7
Definition: polytest.cpp:40
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
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:4964
Definition: brush.hpp:15
struct _GDI_HANDLE_TABLE GDI_HANDLE_TABLE
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define FL_ZERO_MEMORY
Definition: polytest.cpp:58
PENTRY gpentHmgr
Definition: gdiobj.c:147
static PVOID gpvGdiHdlTblSection
Definition: gdiobj.c:146
static const unsigned RESERVE_ENTRIES_COUNT
Definition: gdiobj.h:11
#define TAG_GDIHNDTBLE
Definition: tags.h:16
ULONG_PTR SIZE_T
Definition: typedefs.h:78
LONG NTSTATUS
Definition: DriverTester.h:11
struct LOOKASIDE_ALIGN _PAGED_LOOKASIDE_LIST PAGED_LOOKASIDE_LIST
#define GDI_HANDLE_COUNT
Definition: gdi.h:12
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
NTSTATUS NTAPI MmMapViewInSessionSpace(IN PVOID Section, OUT PVOID *MappedBase, IN OUT PSIZE_T ViewSize)
Definition: section.c:2989
static SERVICE_STATUS status
Definition: service.c:26
LONGLONG QuadPart
Definition: typedefs.h:112
#define PAGE_READWRITE
Definition: nt_native.h:1304
static VOID InitLookasideList ( UCHAR  objt,
ULONG  cjSize 
)
static

Definition at line 243 of file gdiobj.c.

Referenced by InitGdiHandleTable().

244 {
246  NULL,
247  NULL,
248  0,
249  cjSize,
250  GDITAG_HMGR_LOOKASIDE_START + (objt << 24),
251  0);
252 }
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:274
#define GDITAG_HMGR_LOOKASIDE_START
Definition: tags.h:130
static PPAGED_LOOKASIDE_LIST gpaLookasideList
Definition: gdiobj.c:151
smooth NULL
Definition: ftsmooth.c:557
_In_ ULONG cjSize
Definition: winddi.h:3634
FORCEINLINE ULONG InterlockedReadUlong ( _In_ _Interlocked_operand_ ULONG volatile Source)

Definition at line 55 of file gdiobj.c.

Referenced by ENTRY_pentPopFreeEntry(), and ENTRY_vPushFreeEntry().

57 {
58  return *Source;
59 }
VOID * Source
Definition: acefiex.h:744
W32KAPI HANDLE APIENTRY NtGdiCreateClientObj ( IN ULONG  ulType)

Definition at line 1371 of file gdiobj.c.

1373 {
1374  POBJ pObject;
1375  HANDLE handle;
1376 
1377  /* Check if ulType is valid */
1381  {
1382  DPRINT1("NtGdiCreateClientObj: Invalid object type 0x%lx.\n", ulType);
1383  return NULL;
1384  }
1385 
1386  /* Allocate a new object */
1388  sizeof(CLIENTOBJ),
1390  if (!pObject)
1391  {
1392  DPRINT1("NtGdiCreateClientObj: Could not allocate a clientobj.\n");
1393  return NULL;
1394  }
1395 
1396  /* Set the real object type */
1398 
1399  /* Create a handle */
1400  handle = GDIOBJ_hInsertObject(pObject, GDI_OBJ_HMGR_POWNED);
1401  if (!handle)
1402  {
1403  DPRINT1("NtGdiCreateClientObj: Could not create a handle.\n");
1404  GDIOBJ_vFreeObject(pObject);
1405  return NULL;
1406  }
1407 
1408  /* Unlock it */
1409  GDIOBJ_vUnlockObject(pObject);
1410 
1411  return handle;
1412 }
namespace GUID const ADDRINFOEXW ADDRINFOEXW struct timeval OVERLAPPED LPLOOKUPSERVICE_COMPLETION_ROUTINE HANDLE * handle
Definition: sock.c:79
HGDIOBJ hHmgr
Definition: gdiobj.h:40
smooth NULL
Definition: ftsmooth.c:557
#define UlongToHandle(ul)
Definition: basetsd.h:96
VOID NTAPI GDIOBJ_vUnlockObject(POBJ pobj)
Definition: gdiobj.c:875
#define GDI_OBJ_HMGR_POWNED
Definition: ntgdihdl.h:117
_In_z_ PCWSTR _In_ ULONG ulType
Definition: misc.h:62
DWORD *typedef HANDLE
Definition: winlogon.h:52
#define DPRINT1
Definition: precomp.h:8
POBJ NTAPI GDIOBJ_AllocateObject(UCHAR objt, ULONG cjSize, FLONG fl)
Definition: gdiobj.c:557
VOID NTAPI GDIOBJ_vFreeObject(POBJ pobj)
Definition: gdiobj.c:591
HGDIOBJ NTAPI GDIOBJ_hInsertObject(POBJ pobj, ULONG ulOwner)
Definition: gdiobj.c:907
W32KAPI BOOL APIENTRY NtGdiDeleteClientObj ( IN HANDLE  hobj)

Definition at line 1417 of file gdiobj.c.

1419 {
1420  /* We first need to get the real type from the handle */
1422 
1423  /* Check if it's really a CLIENTOBJ */
1425  {
1426  /* FIXME: SetLastError? */
1427  return FALSE;
1428  }
1429 
1430  return GreDeleteObject(hobj);
1431 }
BOOL NTAPI GreDeleteObject(HGDIOBJ hobj)
Definition: gdiobj.c:1153
#define GDI_HANDLE_BASETYPE_MASK
Definition: gdi.h:18
#define FALSE
Definition: types.h:117
#define GDI_HANDLE_GET_TYPE(h)
Definition: gdi.h:31
_In_z_ PCWSTR _In_ ULONG ulType
Definition: misc.h:62
unsigned int ULONG
Definition: retypes.h:1
W32KAPI INT APIENTRY NtGdiExtGetObjectW ( IN HANDLE  hobj,
IN INT  cjBufferSize,
OUT LPVOID  lpBuffer 
)

Definition at line 1321 of file gdiobj.c.

Referenced by GetFontObjectA(), and GetObjectW().

1325 {
1326  UINT iResult, cjMaxSize;
1327  union
1328  {
1329  BITMAP bitmap;
1330  DIBSECTION dibsection;
1331  LOGPEN logpen;
1332  LOGBRUSH logbrush;
1333  LOGFONTW logfontw;
1334  EXTLOGFONTW extlogfontw;
1335  ENUMLOGFONTEXDVW enumlogfontexdvw;
1336  } object;
1337 
1338  /* Normalize to the largest supported object size */
1339  cjMaxSize = min((UINT)cjBufferSize, sizeof(object));
1340 
1341  /* Now do the actual call */
1342  iResult = GreGetObject(hobj, cjMaxSize, lpBuffer ? &object : NULL);
1343 
1344  /* Check if we have a buffer and data */
1345  if ((lpBuffer != NULL) && (iResult != 0))
1346  {
1347  /* Enter SEH for buffer transfer */
1348  _SEH2_TRY
1349  {
1350  /* Probe the buffer and copy it */
1351  cjMaxSize = min(cjMaxSize, iResult);
1352  ProbeForWrite(lpBuffer, cjMaxSize, sizeof(WORD));
1353  RtlCopyMemory(lpBuffer, &object, cjMaxSize);
1354  }
1356  {
1357  /* Clear the return value.
1358  * Do *NOT* set last error here! */
1359  iResult = 0;
1360  }
1361  _SEH2_END;
1362  }
1363 
1364  /* Return the count */
1365  return iResult;
1366 }
unsigned short WORD
Definition: ntddk_ex.h:93
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
*nSize LPSTR lpBuffer
Definition: winbase.h:1973
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
#define _SEH2_END
Definition: pseh2_64.h:7
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
smooth NULL
Definition: ftsmooth.c:557
Definition: bl.h:1253
#define _SEH2_TRY
Definition: pseh2_64.h:5
#define min(a, b)
Definition: monoChain.cc:55
unsigned int UINT
Definition: ndis.h:50
static HBITMAP bitmap
Definition: clipboard.c:1621
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
void * object
Definition: jmemsys.h:48
INT NTAPI GreGetObject(IN HGDIOBJ hobj, IN INT cbCount, IN PVOID pvBuffer)
Definition: gdiobj.c:1259

Variable Documentation

const GDICLEANUPPROC apfnCleanup[]
static

Definition at line 157 of file gdiobj.c.

Referenced by GDIOBJ_vFreeObject().

const GDIOBJDELETEPROC apfnDelete[]
static

Definition at line 195 of file gdiobj.c.

Referenced by GDIOBJ_vFreeObject().

PGDI_HANDLE_TABLE GdiHandleTable = NULL

Definition at line 1435 of file gdiobj.c.

Referenced by InitGdiHandleTable().

PPAGED_LOOKASIDE_LIST gpaLookasideList
static

Definition at line 151 of file gdiobj.c.

PULONG gpaulRefCount

Definition at line 148 of file gdiobj.c.

Referenced by KdbCommand_Gdi_dumpht(), and KdbCommand_Gdi_handle().

PENTRY gpentHmgr

Definition at line 147 of file gdiobj.c.

Referenced by ENTRY_hInsertObject(), and ENTRY_vPushFreeEntry().

PVOID gpvGdiHdlTblSection = NULL
static

Definition at line 146 of file gdiobj.c.

volatile ULONG gulFirstFree

Definition at line 149 of file gdiobj.c.

volatile ULONG gulFirstUnused

Definition at line 150 of file gdiobj.c.

Referenced by GDI_CleanupForProcess(), and KdbCommand_Gdi_dumpht().