*
*/
-#ifndef __WIN32K_GDIOBJ_H
-#define __WIN32K_GDIOBJ_H
+#pragma once
/* Public GDI Object/Handle definitions */
#include <win32k/ntgdihdl.h>
+#include "win32.h"
typedef struct _GDI_HANDLE_TABLE
{
*/
//////////////////////////////////////////////////////////////////////////////
GDI_TABLE_ENTRY Entries[GDI_HANDLE_COUNT];
- DEVCAPS DevCaps; // Device Capabilities
+ DEVCAPS DevCaps; // Device Capabilities.
FLONG flDeviceUniq; // Device settings uniqueness.
- PVOID pvLangPack; // Lanuage Pack.
+ PVOID pvLangPack; // Language Pack.
CFONT cfPublic[GDI_CFONT_MAX]; // Public Fonts.
- DWORD dwCsbSupported1; // OEM code-page bitfield.
+ DWORD dwCFCount;
//////////////////////////////////////////////////////////////////////////////
PPAGED_LOOKASIDE_LIST LookasideLists;
typedef BOOL (INTERNAL_CALL *GDICLEANUPPROC)(PVOID ObjectBody);
-/*!
- * GDI object header. This is a part of any GDI object
-*/
-typedef struct _GDIOBJHDR
-{
- PETHREAD LockingThread; /* only assigned if a thread is holding the lock! */
- ULONG Locks;
-#ifdef GDI_DEBUG
- const char* createdfile;
- int createdline;
- const char* lockfile;
- int lockline;
-#endif
-} GDIOBJHDR, *PGDIOBJHDR;
-
-//
-// Every GDI Object must have this standard type of header.
-// It's for thread locking.
-// This header is standalone, used only in gdiobj.c.
-//
-typedef struct _GDIOBJEMPTYHDR
+/* Every GDI Object must have this standard type of header.
+ * It's for thread locking. */
+typedef struct _BASEOBJECT
{
HGDIOBJ hHmgr;
- ULONG Count;
- ULONG lucExcLock;
- PW32THREAD Tid;
-} GDIOBJEMPTYHDR, *PGDIOBJEMPTYHDR;
+ ULONG ulShareCount;
+ USHORT cExclusiveLock;
+ USHORT BaseFlags;
+ PTHREADINFO Tid;
+} BASEOBJECT, *POBJ;
-BOOL INTERNAL_CALL GDIOBJ_OwnedByCurrentProcess(PGDI_HANDLE_TABLE HandleTable, HGDIOBJ ObjectHandle);
-void INTERNAL_CALL GDIOBJ_SetOwnership(PGDI_HANDLE_TABLE HandleTable, HGDIOBJ ObjectHandle, PEPROCESS Owner);
-void INTERNAL_CALL GDIOBJ_CopyOwnership(PGDI_HANDLE_TABLE HandleTable, HGDIOBJ CopyFrom, HGDIOBJ CopyTo);
-BOOL INTERNAL_CALL GDIOBJ_ConvertToStockObj(PGDI_HANDLE_TABLE HandleTable, HGDIOBJ *hObj);
-VOID INTERNAL_CALL GDIOBJ_UnlockObjByPtr(PGDI_HANDLE_TABLE HandleTable, PGDIOBJ Object);
+typedef struct _CLIENTOBJ
+{
+ BASEOBJECT BaseObject;
+} CLIENTOBJ, *PCLIENTOBJ;
-#define GDIOBJ_GetObjectType(Handle) \
- GDI_HANDLE_GET_TYPE(Handle)
+enum BASEFLAGS
+{
+ BASEFLAG_LOOKASIDE = 0x80,
+
+ /* ReactOS specific: */
+ BASEFLAG_READY_TO_DIE = 0x1000
+};
+BOOL INTERNAL_CALL GDIOBJ_OwnedByCurrentProcess(HGDIOBJ ObjectHandle);
+BOOL INTERNAL_CALL GDIOBJ_SetOwnership(HGDIOBJ ObjectHandle, PEPROCESS Owner);
+BOOL INTERNAL_CALL GDIOBJ_CopyOwnership(HGDIOBJ CopyFrom, HGDIOBJ CopyTo);
+BOOL INTERNAL_CALL GDIOBJ_ConvertToStockObj(HGDIOBJ *hObj);
+//VOID INTERNAL_CALL GDIOBJ_ShareUnlockObjByPtr(POBJ Object);
BOOL INTERNAL_CALL GDIOBJ_ValidateHandle(HGDIOBJ hObj, ULONG ObjectType);
-HGDIOBJ INTERNAL_CALL GDIOBJ_AllocObj(PGDI_HANDLE_TABLE HandleTable, ULONG ObjectType);
-BOOL INTERNAL_CALL GDIOBJ_FreeObj (PGDI_HANDLE_TABLE HandleTable, HGDIOBJ hObj, DWORD ObjectType);
-PGDIOBJ INTERNAL_CALL GDIOBJ_LockObj (PGDI_HANDLE_TABLE HandleTable, HGDIOBJ hObj, DWORD ObjectType);
-PGDIOBJ INTERNAL_CALL GDIOBJ_ShareLockObj (PGDI_HANDLE_TABLE HandleTable, HGDIOBJ hObj, DWORD ObjectType);
+POBJ INTERNAL_CALL GDIOBJ_AllocObj(UCHAR ObjectType);
+POBJ INTERNAL_CALL GDIOBJ_AllocObjWithHandle(ULONG ObjectType);
+VOID INTERNAL_CALL GDIOBJ_FreeObj (POBJ pObj, UCHAR ObjectType);
+BOOL INTERNAL_CALL GDIOBJ_FreeObjByHandle (HGDIOBJ hObj, DWORD ObjectType);
+PGDIOBJ INTERNAL_CALL GDIOBJ_LockObj (HGDIOBJ hObj, DWORD ObjectType);
+PGDIOBJ INTERNAL_CALL GDIOBJ_ShareLockObj (HGDIOBJ hObj, DWORD ObjectType);
+VOID INTERNAL_CALL GDIOBJ_LockMultipleObjs(ULONG ulCount, IN HGDIOBJ* ahObj, OUT PGDIOBJ* apObj);
PVOID INTERNAL_CALL GDI_MapHandleTable(PSECTION_OBJECT SectionObject, PEPROCESS Process);
+#define GDIOBJ_GetObjectType(Handle) \
+ GDI_HANDLE_GET_TYPE(Handle)
+
#define GDIOBJFLAG_DEFAULT (0x0)
#define GDIOBJFLAG_IGNOREPID (0x1)
#define GDIOBJFLAG_IGNORELOCK (0x2)
-BOOL FASTCALL NtGdiDeleteObject(HGDIOBJ hObject);
-BOOL FASTCALL IsObjectDead(HGDIOBJ);
+BOOL FASTCALL GreDeleteObject(HGDIOBJ hObject);
+BOOL FASTCALL IsObjectDead(HGDIOBJ);
+BOOL FASTCALL IntGdiSetDCOwnerEx( HDC, DWORD, BOOL);
+BOOL FASTCALL IntGdiSetRegionOwner(HRGN,DWORD);
+
+/*!
+ * Release GDI object. Every object locked by GDIOBJ_LockObj() must be unlocked.
+ * You should unlock the object
+ * as soon as you don't need to have access to it's data.
+ * \param Object Object pointer (as returned by GDIOBJ_LockObj).
+ */
+ULONG
+FORCEINLINE
+GDIOBJ_UnlockObjByPtr(POBJ Object)
+{
+ INT cLocks = InterlockedDecrement((PLONG)&Object->cExclusiveLock);
+ ASSERT(cLocks >= 0);
+ return cLocks;
+}
+
+ULONG
+FORCEINLINE
+GDIOBJ_ShareUnlockObjByPtr(POBJ Object)
+{
+ HGDIOBJ hobj = Object->hHmgr;
+ USHORT flags = Object->BaseFlags;
+ INT cLocks = InterlockedDecrement((PLONG)&Object->ulShareCount);
+ ASSERT(cLocks >= 0);
+ if ((flags & BASEFLAG_READY_TO_DIE) && (cLocks == 0))
+ {
+ GDIOBJ_SetOwnership(hobj, PsGetCurrentProcess());
+ GDIOBJ_FreeObjByHandle(hobj, GDI_OBJECT_TYPE_DONTCARE);
+ }
+ return cLocks;
+}
+
+#ifdef GDI_DEBUG
+ULONG FASTCALL GDIOBJ_IncrementShareCount(POBJ Object);
+#else
+ULONG
+FORCEINLINE
+GDIOBJ_IncrementShareCount(POBJ Object)
+{
+ INT cLocks = InterlockedIncrement((PLONG)&Object->ulShareCount);
+ ASSERT(cLocks >= 1);
+ return cLocks;
+}
#endif
+
+INT FASTCALL GreGetObjectOwner(HGDIOBJ, GDIOBJTYPE);
+
+#define GDIOBJ_GetKernelObj(Handle) \
+ ((PGDI_TABLE_ENTRY)&GdiHandleTable->Entries[GDI_HANDLE_GET_INDEX(Handle)])->KernelData