Rewrite of the GDI handle manager

- The old handle manager used a completely retarded spinlock in combination with KeDelayExecutionThread() for both exclusive
and shared locks. This is probably the most uneffective algorithm possible. It was also duplicating code everywhere and it was a overall mess It 

is now replaced with a lock-free reference counter for shared locks and a pushlock for exclusive locks. -> Better performance and scalability.
- Allocate user mode object attributes from the new gdi pool. This way, we don't need any caching, since the pool serves as a cache. Its also 

much faster and uses much less memory.
- Allow object allocations of different size, instead of fixed size from a table. This way a single allocation can take care of actual needs.
- Allow allcoating objects without a handle and insert them into the handle table later
- Properly synchronize the process GDIHandleCount. Now gdiview and taskmanager show the correct number of gdi handles.
- Implement a new event tracking system, that is capable of tracking all reverences and locks of objects and pool allocations to help track 

possible leaks
- Make sure that all objects of a process are deleted in cleanup
- Make sure all usermode memory allocations are freed, when cleaning up the process pool.
- Make sure that each object type is using the correct type of lock (either shared or exclusive, not a mixture)
- Fix some object / reference leaks
- Lots of inferface improvements
- Use global variables for certain things instead of members in the mapped gdi handle table
- Make IntSysCreateRectpRgn create a region without a handle
- Fix detection od source and mask use in GreStretchBltMask
- Use GDIOBJ_bLockMultipleObjects in NtGdiCombineRegion to avoid possible deadlocks
- Fix NtGdiAbortPath to reset DCPATH_ACTIVE flag in the dc and only bail out on error, instead of always
- Replace DC_AllocateDcAttr and DC_AllocDcAttr with DC_bAllocDcAttr using the new user mode pool
- Remove DCU_SyncDcAttrtoUser and DCU_SynchDcAttrtoUser. Those functions were unused and didn't do anything useful anyway,
- Replace IntGdiSetDCOwnerEx and DC_SetOwnership with GreSetDCOwner, remove unused NoSetBrush parameter
- Replace GDIOBJ_bValidateHandle and IsObjectDead with GreIsHandleValid
- Chage GDIOBJ_bLockMultipleObjects: pass object type, return a BOOL, whether all objects could be locked, cleanup on failure

svn path=/trunk/; revision=51470
This commit is contained in:
Timo Kreuzer
2011-04-28 08:26:46 +00:00
parent de078e7357
commit 9ff568fd7d
54 changed files with 2322 additions and 2870 deletions
@@ -102,8 +102,9 @@ EngDeleteDriverObj(
/* NOTE: We don't care about the bLocked param, as our handle manager
allows freeing the object, while we hold any number of locks. */
/* Free the object */
return DRIVEROBJ_FreeObjectByHandle(hdo);
/* Delete the object */
GDIOBJ_vDeleteObject(&pedo->baseobj);
return TRUE;
}
@@ -139,10 +140,11 @@ EngUnlockDriverObj(
}
/* Unlock object */
cLocks = DRIVEROBJ_UnlockObject(pedo);
cLocks = pedo->baseobj.cExclusiveLock;
DRIVEROBJ_UnlockObject(pedo);
/* Check if we still hold a lock */
if (cLocks < 1)
if (cLocks < 2)
{
/* Object wasn't locked before, fail. */
return FALSE;
@@ -37,7 +37,7 @@ EBRUSHOBJ_vInit(EBRUSHOBJ *pebo, PBRUSH pbrush, PDC pdc)
ASSERT(pebo->psurfTrg->ppal);
pebo->ppalSurf = pebo->psurfTrg->ppal;
GDIOBJ_IncrementShareCount(&pebo->ppalSurf->BaseObject);
GDIOBJ_vReferenceObjectByPointer(&pebo->ppalSurf->BaseObject);
if (pbrush->flAttrs & GDIBRUSH_IS_NULL)
{
@@ -117,7 +117,7 @@ IntEngWndUpdateClipObj(
{
DPRINT1("Warning: Couldn't lock visible region of window DC\n");
}
REGION_FreeRgnByHandle(hVisRgn);
GreDeleteObject(hVisRgn);
}
else
{
@@ -143,7 +143,6 @@ PDEVOBJ_bEnablePDEV(
ppdev->gdiinfo.ulLogPixelsY = 96;
/* Setup Palette */
GDIOBJ_SetOwnership(ppdev->devinfo.hpalDefault, NULL);
ppdev->ppalSurf = PALETTE_ShareLockPalette(ppdev->devinfo.hpalDefault);
DPRINT("PDEVOBJ_bEnablePDEV - dhpdev = %p\n", ppdev->dhpdev);
@@ -171,7 +170,7 @@ PDEVOBJ_pSurface(
if (ppdev->pSurface)
{
/* Increment reference count */
GDIOBJ_IncrementShareCount(&ppdev->pSurface->BaseObject);
GDIOBJ_vReferenceObjectByPointer(&ppdev->pSurface->BaseObject);
}
else
{
+16 -8
View File
@@ -151,7 +151,7 @@ SURFACE_AllocSurface(
}
/* Allocate a SURFACE object */
psurf = (PSURFACE)GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_BITMAP);
psurf = (PSURFACE)GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_BITMAP, sizeof(SURFACE));
if (psurf)
{
@@ -166,7 +166,7 @@ SURFACE_AllocSurface(
/* Assign a default palette and increment its reference count */
psurf->ppal = appalSurfaceDefault[iFormat];
GDIOBJ_IncrementShareCount(&psurf->ppal->BaseObject);
GDIOBJ_vReferenceObjectByPointer(&psurf->ppal->BaseObject);
}
return psurf;
@@ -285,12 +285,12 @@ EngCreateBitmap(
{
/* Bail out if that failed */
DPRINT1("SURFACE_bSetBitmapBits failed.\n");
SURFACE_FreeSurfaceByHandle(hbmp);
GDIOBJ_vDeleteObject(&psurf->BaseObject);
return NULL;
}
/* Set public ownership */
GDIOBJ_SetOwnership(hbmp, NULL);
GDIOBJ_vSetObjectOwner(&psurf->BaseObject, GDI_OBJ_HMGR_PUBLIC);
/* Unlock the surface and return */
SURFACE_UnlockSurface(psurf);
@@ -324,7 +324,7 @@ EngCreateDeviceBitmap(
hbmp = (HBITMAP)psurf->SurfObj.hsurf;
/* Set public ownership */
GDIOBJ_SetOwnership(hbmp, NULL);
GDIOBJ_vSetObjectOwner(&psurf->BaseObject, GDI_OBJ_HMGR_PUBLIC);
/* Unlock the surface and return */
SURFACE_UnlockSurface(psurf);
@@ -355,7 +355,7 @@ EngCreateDeviceSurface(
hsurf = psurf->SurfObj.hsurf;
/* Set public ownership */
GDIOBJ_SetOwnership(hsurf, NULL);
GDIOBJ_vSetObjectOwner(&psurf->BaseObject, GDI_OBJ_HMGR_PUBLIC);
/* Unlock the surface and return */
SURFACE_UnlockSurface(psurf);
@@ -448,8 +448,16 @@ BOOL
APIENTRY
EngDeleteSurface(IN HSURF hsurf)
{
GDIOBJ_SetOwnership(hsurf, PsGetCurrentProcess());
SURFACE_FreeSurfaceByHandle(hsurf);
PSURFACE psurf;
psurf = SURFACE_ShareLockSurface(hsurf);
if (!psurf)
{
DPRINT1("Could not reference surface to delete\n");
return FALSE;
}
GDIOBJ_vDeleteObject(&psurf->BaseObject);
return TRUE;
}
@@ -89,14 +89,11 @@ typedef struct _EBRUSHOBJ
#define GDIBRUSH_CACHED_IS_SOLID 0x80000000
#define BRUSH_AllocBrush() ((PBRUSH) GDIOBJ_AllocObj(GDIObjType_BRUSH_TYPE))
#define BRUSH_AllocBrushWithHandle() ((PBRUSH) GDIOBJ_AllocObjWithHandle (GDI_OBJECT_TYPE_BRUSH))
#define BRUSH_AllocBrushWithHandle() ((PBRUSH) GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_BRUSH, sizeof(BRUSH)))
#define BRUSH_FreeBrush(pBrush) GDIOBJ_FreeObj((POBJ)pBrush, GDIObjType_BRUSH_TYPE)
#define BRUSH_FreeBrushByHandle(hBrush) GDIOBJ_FreeObjByHandle((HGDIOBJ)hBrush, GDI_OBJECT_TYPE_BRUSH)
#define BRUSH_LockBrush(hBrush) ((PBRUSH)GDIOBJ_LockObj((HGDIOBJ)hBrush, GDI_OBJECT_TYPE_BRUSH))
#define BRUSH_UnlockBrush(pBrush) GDIOBJ_UnlockObjByPtr((POBJ)pBrush)
#define BRUSH_ShareLockBrush(hBrush) ((PBRUSH)GDIOBJ_ShareLockObj((HGDIOBJ)hBrush, GDI_OBJECT_TYPE_BRUSH))
#define BRUSH_ShareUnlockBrush(pBrush) GDIOBJ_ShareUnlockObjByPtr((POBJ)pBrush)
#define BRUSH_ShareUnlockBrush(pBrush) GDIOBJ_vDereferenceObject((POBJ)pBrush)
INT FASTCALL BRUSH_GetObject (PBRUSH GdiObject, INT Count, LPLOGBRUSH Buffer);
BOOL INTERNAL_CALL BRUSH_Cleanup(PVOID ObjectBody);
@@ -18,11 +18,11 @@ typedef struct _COLORSPACE
#define COLORSPACEOBJ_AllocCS() ((PCOLORSPACE) GDIOBJ_AllocObj(GDIObjType_ICMLCS_TYPE))
#define COLORSPACEOBJ_AllocCSWithHandle() ((PCOLORSPACE) GDIOBJ_AllocObjWithHandle (GDI_OBJECT_TYPE_COLORSPACE))
#define COLORSPACEOBJ_AllocCSWithHandle() ((PCOLORSPACE) GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_COLORSPACE, sizeof(COLORSPACE)))
#define COLORSPACEOBJ_FreeCS(pCS) GDIOBJ_FreeObj((POBJ)pCS, GDIObjType_ICMLCS_TYPE)
#define COLORSPACEOBJ_FreeCSByHandle(hCS) GDIOBJ_FreeObjByHandle((HGDIOBJ)hCS, GDI_OBJECT_TYPE_COLORSPACE)
#define COLORSPACEOBJ_LockCS(hCS) ((PCOLORSPACE)GDIOBJ_LockObj((HGDIOBJ)hCS, GDI_OBJECT_TYPE_COLORSPACE))
#define COLORSPACEOBJ_UnlockCS(pCS) GDIOBJ_UnlockObjByPtr((POBJ)pCS)
#define COLORSPACEOBJ_LockCS(hCS) ((PCOLORSPACE)GDIOBJ_LockObject((HGDIOBJ)hCS, GDIObjType_ICMLCS_TYPE))
#define COLORSPACEOBJ_UnlockCS(pCS) GDIOBJ_vUnlockObject((POBJ)pCS)
typedef struct _COLORTRANSFORMOBJ
{
+21 -10
View File
@@ -149,18 +149,13 @@ typedef struct _DC
/* Internal functions *********************************************************/
#define DC_LockDc(hDC) \
((PDC) GDIOBJ_LockObj ((HGDIOBJ) hDC, GDI_OBJECT_TYPE_DC))
#define DC_UnlockDc(pDC) \
GDIOBJ_UnlockObjByPtr ((POBJ)pDC)
extern PDC defaultDCstate;
INIT_FUNCTION NTSTATUS NTAPI InitDcImpl(VOID);
PPDEVOBJ FASTCALL IntEnumHDev(VOID);
PDC NTAPI DC_AllocDcWithHandle(VOID);
VOID FASTCALL DC_InitDC(HDC DCToInit);
VOID FASTCALL DC_AllocateDcAttr(HDC);
BOOL NTAPI DC_bAllocDcAttr(PDC pdc);
VOID FASTCALL DC_FreeDcAttr(HDC);
BOOL INTERNAL_CALL DC_Cleanup(PVOID ObjectBody);
BOOL FASTCALL DC_SetOwnership(HDC hDC, PEPROCESS Owner);
@@ -203,6 +198,22 @@ BOOL FASTCALL IntGdiCleanDC(HDC hDC);
VOID FASTCALL IntvGetDeviceCaps(PPDEVOBJ, PDEVCAPS);
BOOL FASTCALL MakeInfoDC(PDC,BOOL);
BOOL FASTCALL IntSetDefaultRegion(PDC);
BOOL NTAPI GreSetDCOwner(HDC hdc, ULONG ulOwner);
FORCEINLINE
PDC
DC_LockDc(HDC hdc)
{
//if (GDI_HANDLE_GET_TYPE(hdc) != GDILoObjType_LO_DC_TYPE) return NULL; ???
return GDIOBJ_LockObject(hdc, GDIObjType_DC_TYPE);
}
FORCEINLINE
VOID
DC_UnlockDc(PDC pdc)
{
GDIOBJ_vUnlockObject(&pdc->BaseObject);
}
VOID
FORCEINLINE
@@ -215,7 +226,7 @@ DC_vSelectSurface(PDC pdc, PSURFACE psurfNew)
SURFACE_ShareUnlockSurface(psurfOld);
}
if (psurfNew)
GDIOBJ_IncrementShareCount((POBJ)psurfNew);
GDIOBJ_vReferenceObjectByPointer((POBJ)psurfNew);
pdc->dclevel.pSurface = psurfNew;
}
@@ -227,7 +238,7 @@ DC_vSelectFillBrush(PDC pdc, PBRUSH pbrFill)
if (pbrFillOld)
BRUSH_ShareUnlockBrush(pbrFillOld);
if (pbrFill)
GDIOBJ_IncrementShareCount((POBJ)pbrFill);
GDIOBJ_vReferenceObjectByPointer((POBJ)pbrFill);
pdc->dclevel.pbrFill = pbrFill;
}
@@ -239,7 +250,7 @@ DC_vSelectLineBrush(PDC pdc, PBRUSH pbrLine)
if (pbrLineOld)
BRUSH_ShareUnlockBrush(pbrLineOld);
if (pbrLine)
GDIOBJ_IncrementShareCount((POBJ)pbrLine);
GDIOBJ_vReferenceObjectByPointer((POBJ)pbrLine);
pdc->dclevel.pbrLine = pbrLine;
}
@@ -251,7 +262,7 @@ DC_vSelectPalette(PDC pdc, PPALETTE ppal)
if (ppalOld)
PALETTE_ShareUnlockPalette(ppalOld);
if (ppal)
GDIOBJ_IncrementShareCount((POBJ)ppal);
GDIOBJ_vReferenceObjectByPointer((POBJ)ppal);
pdc->dclevel.ppal = ppal;
}
@@ -18,4 +18,4 @@ HPALETTE FASTCALL
BuildDIBPalette (CONST BITMAPINFO *bmi);
BITMAPINFO* FASTCALL DIB_ConvertBitmapInfo(CONST BITMAPINFO* bmi, DWORD Usage);
VOID FASTCALL DIB_FreeConvertedBitmapInfo(BITMAPINFO* converted, BITMAPINFO* orig);
VOID FASTCALL DIB_FreeConvertedBitmapInfo(BITMAPINFO* converted, BITMAPINFO* orig);
@@ -14,7 +14,13 @@ typedef struct _EDRIVEROBJ
BOOL INTERNAL_CALL DRIVEROBJ_Cleanup(PVOID pObject);
#define DRIVEROBJ_AllocObjectWithHandle() ((PEDRIVEROBJ)GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_DRIVEROBJ))
#define DRIVEROBJ_AllocObjectWithHandle() ((PEDRIVEROBJ)GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_DRIVEROBJ, sizeof(DRIVEROBJ)))
#define DRIVEROBJ_FreeObjectByHandle(hdo) GDIOBJ_FreeObjByHandle((HGDIOBJ)hdo, GDI_OBJECT_TYPE_DRIVEROBJ)
#define DRIVEROBJ_LockObject(hdo) ((PEDRIVEROBJ)GDIOBJ_LockObj((HGDIOBJ)hdo, GDI_OBJECT_TYPE_DRIVEROBJ))
#define DRIVEROBJ_UnlockObject(pdo) GDIOBJ_UnlockObjByPtr((POBJ)pdo)
#define DRIVEROBJ_UnlockObject(pdo) GDIOBJ_vUnlockObject((POBJ)pdo)
FORCEINLINE
PEDRIVEROBJ
DRIVEROBJ_LockObject(HDRVOBJ hdo)
{
return GDIOBJ_LockObject(hdo, GDIObjType_DRVOBJ_TYPE);
}
@@ -1,12 +1,51 @@
#pragma once
extern ULONG gulDebugChannels;
typedef enum _LOG_EVENT_TYPE
{
EVENT_ALLOCATE,
EVENT_CREATE_HANDLE,
EVENT_REFERENCE,
EVENT_DEREFERENCE,
EVENT_LOCK,
EVENT_UNLOCK,
EVENT_DELETE,
EVENT_FREE,
EVENT_SET_OWNER,
} LOG_EVENT_TYPE;
#define GDI_STACK_LEVELS 20
extern ULONG_PTR GDIHandleAllocator[GDI_HANDLE_COUNT][GDI_STACK_LEVELS+1];
extern ULONG_PTR GDIHandleLocker[GDI_HANDLE_COUNT][GDI_STACK_LEVELS+1];
extern ULONG_PTR GDIHandleShareLocker[GDI_HANDLE_COUNT][GDI_STACK_LEVELS+1];
extern ULONG_PTR GDIHandleDeleter[GDI_HANDLE_COUNT][GDI_STACK_LEVELS+1];
typedef struct _LOGENTRY
{
SLIST_ENTRY sleLink;
LOG_EVENT_TYPE nEventType;
DWORD dwProcessId;
DWORD dwThreadId;
ULONG ulUnique;
LPARAM lParam;
PVOID apvBackTrace[20];
union
{
ULONG_PTR data1;
} data;
} LOGENTRY, *PLOGENTRY;
#if DBG_ENABLE_EVENT_LOGGING
VOID NTAPI DbgDumpEventList(PSLIST_HEADER pslh);
VOID NTAPI DbgLogEvent(PSLIST_HEADER pslh, EVENT_TYPE nEventType, LPARAM lParam);
VOID NTAPI DbgCleanupEventList(PSLIST_HEADER pslh);
#define DBG_LOGEVENT(pslh, type, val) DbgLogEvent(pslh, type, (ULONG_PTR)val)
#define DBG_INITLOG(pslh) InitializeSListHead(pslh)
#define DBG_DUMP_EVENT_LIST(pslh) DbgDumpEventList(pslh)
#define DBG_CLEANUP_EVENT_LIST(pslh) DbgCleanupEventList(pslh)
#else
#define DBG_LOGEVENT(pslh, type, val)
#define DBG_INITLOG(pslh)
#define DBG_DUMP_EVENT_LIST(pslh)
#define DBG_CLEANUP_EVENT_LIST(pslh)
#endif
extern ULONG gulLogUnique;
extern ULONG gulDebugChannels;
enum _DEBUGCHANNELS
{
@@ -17,73 +56,18 @@ enum _DEBUGCHANNELS
DbgModeSwitch = 16,
};
void IntDumpHandleTable(PGDI_HANDLE_TABLE HandleTable);
ULONG CaptureStackBackTace(PVOID* pFrames, ULONG nFramesToCapture);
BOOL GdiDbgHTIntegrityCheck(VOID);
void GdiDbgDumpLockedHandles(VOID);
VOID NTAPI DbgDumpGdiHandleTable(VOID);
ULONG NTAPI DbgCaptureStackBackTace(PVOID* pFrames, ULONG nFramesToCapture);
BOOL NTAPI DbgGdiHTIntegrityCheck(VOID);
VOID NTAPI DbgDumpLockedGdiHandles(VOID);
#define DBGENABLE(ch) gulDebugChannels |= (ch);
#define DBGDISABLE(ch) gulDebugChannels &= ~(ch);
#define DPRINTCH(ch) if (gulDebugChannels & (ch)) DbgPrint
#ifdef GDI_DEBUG
#define KeRosDumpStackFrames(Frames, Count) KdSystemDebugControl('DsoR', (PVOID)Frames, Count, NULL, 0, NULL, KernelMode)
NTSYSAPI ULONG APIENTRY RtlWalkFrameChain(OUT PVOID *Callers, IN ULONG Count, IN ULONG Flags);
#define IS_HANDLE_VALID(idx) \
((GdiHandleTable->Entries[idx].Type & GDI_ENTRY_BASETYPE_MASK) != 0)
#define GDIDBG_TRACECALLER() \
DPRINT1("-> called from:\n"); \
KeRosDumpStackFrames(NULL, 20);
#define GDIDBG_TRACEALLOCATOR(handle) \
DPRINT1("-> allocated from:\n"); \
KeRosDumpStackFrames(GDIHandleAllocator[GDI_HANDLE_GET_INDEX(handle)], GDI_STACK_LEVELS);
#define GDIDBG_TRACELOCKER(handle) \
DPRINT1("-> locked from:\n"); \
KeRosDumpStackFrames(GDIHandleLocker[GDI_HANDLE_GET_INDEX(handle)], GDI_STACK_LEVELS);
#define GDIDBG_TRACESHARELOCKER(handle) \
DPRINT1("-> locked from:\n"); \
KeRosDumpStackFrames(GDIHandleShareLocker[GDI_HANDLE_GET_INDEX(handle)], GDI_STACK_LEVELS);
#define GDIDBG_TRACEDELETER(handle) \
DPRINT1("-> deleted from:\n"); \
KeRosDumpStackFrames(GDIHandleDeleter[GDI_HANDLE_GET_INDEX(handle)], GDI_STACK_LEVELS);
#define GDIDBG_CAPTUREALLOCATOR(handle) \
CaptureStackBackTace((PVOID*)GDIHandleAllocator[GDI_HANDLE_GET_INDEX(handle)], GDI_STACK_LEVELS);
#define GDIDBG_CAPTURELOCKER(handle) \
CaptureStackBackTace((PVOID*)GDIHandleLocker[GDI_HANDLE_GET_INDEX(handle)], GDI_STACK_LEVELS);
#define GDIDBG_CAPTURESHARELOCKER(handle) \
CaptureStackBackTace((PVOID*)GDIHandleShareLocker[GDI_HANDLE_GET_INDEX(handle)], GDI_STACK_LEVELS);
#define GDIDBG_CAPTUREDELETER(handle) \
CaptureStackBackTace((PVOID*)GDIHandleDeleter[GDI_HANDLE_GET_INDEX(handle)], GDI_STACK_LEVELS);
#define GDIDBG_DUMPHANDLETABLE() \
IntDumpHandleTable(GdiHandleTable)
#define GDIDBG_INITLOOPTRACE() \
ULONG Attempts = 0;
#define GDIDBG_TRACELOOP(Handle, PrevThread, Thread) \
if ((++Attempts % 20) == 0) \
{ \
DPRINT1("[%d] Handle 0x%p Locked by 0x%x (we're 0x%x)\n", Attempts, Handle, PrevThread, Thread); \
}
#else
#define GDIDBG_TRACECALLER()
#define GDIDBG_TRACEALLOCATOR(index)
#define GDIDBG_TRACELOCKER(index)
#define GDIDBG_TRACESHARELOCKER(index)
#define GDIDBG_CAPTUREALLOCATOR(index)
#define GDIDBG_CAPTURELOCKER(index)
#define GDIDBG_CAPTURESHARELOCKER(index)
#define GDIDBG_CAPTUREDELETER(handle)
#define GDIDBG_DUMPHANDLETABLE()
#define GDIDBG_INITLOOPTRACE()
#define GDIDBG_TRACELOOP(Handle, PrevThread, Thread)
#define GDIDBG_TRACEDELETER(handle)
#endif /* GDI_DEBUG */
#if DBG
void
NTAPI
@@ -104,7 +88,6 @@ GdiDbgAssertNoLocks(char * pszFile, ULONG nLine)
{
DbgPrint("(%s:%ld) There are %ld exclusive locks!\n",
pszFile, nLine, pti->cExclusiveLocks);
GdiDbgDumpLockedHandles();
ASSERT(FALSE);
}
}
+121 -103
View File
@@ -9,7 +9,7 @@
#include <win32k/ntgdihdl.h>
#include "win32.h"
/* apparently the first 10 entries are never used in windows as they are empty */
/* The first 10 entries are never used in windows, they are empty */
#define RESERVE_ENTRIES_COUNT 10
typedef struct _GDI_HANDLE_TABLE
@@ -24,11 +24,7 @@ typedef struct _GDI_HANDLE_TABLE
PVOID pvLangPack; // Language Pack.
CFONT cfPublic[GDI_CFONT_MAX]; // Public Fonts.
DWORD dwCFCount;
//////////////////////////////////////////////////////////////////////////////
PPAGED_LOOKASIDE_LIST LookasideLists;
ULONG FirstFree;
ULONG FirstUnused;
} GDI_HANDLE_TABLE, *PGDI_HANDLE_TABLE;
@@ -42,19 +38,19 @@ typedef BOOL (INTERNAL_CALL *GDICLEANUPPROC)(PVOID ObjectBody);
* It's for thread locking. */
typedef struct _BASEOBJECT
{
HGDIOBJ hHmgr;
ULONG ulShareCount;
USHORT cExclusiveLock;
USHORT BaseFlags;
PTHREADINFO Tid;
EX_PUSH_LOCK pushlock;
HGDIOBJ hHmgr;
union {
ULONG ulShareCount; /* For objects without a handle */
DWORD dwThreadId; /* Exclusive lock owner */
};
USHORT cExclusiveLock;
USHORT BaseFlags;
EX_PUSH_LOCK pushlock;
#if DBG_ENABLE_EVENT_LOGGING
SLIST_HEADER slhLog;
#endif
} BASEOBJECT, *POBJ;
typedef struct _CLIENTOBJ
{
BASEOBJECT BaseObject;
} CLIENTOBJ, *PCLIENTOBJ;
enum BASEFLAGS
{
BASEFLAG_LOOKASIDE = 0x80,
@@ -63,103 +59,125 @@ enum BASEFLAGS
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);
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);
typedef struct _CLIENTOBJ
{
BASEOBJECT BaseObject;
} CLIENTOBJ, *PCLIENTOBJ;
PVOID INTERNAL_CALL GDI_MapHandleTable(PEPROCESS Process);
#define GDIOBJFLAG_DEFAULT (0x0)
#define GDIOBJFLAG_IGNOREPID (0x1)
#define GDIOBJFLAG_IGNORELOCK (0x2)
INIT_FUNCTION
NTSTATUS
NTAPI
InitGdiHandleTable(VOID);
#define GDIOBJ_GetObjectType(Handle) \
GDI_HANDLE_GET_TYPE(Handle)
BOOL
NTAPI
GreIsHandleValid(
HGDIOBJ hobj);
#define GDIOBJFLAG_DEFAULT (0x0)
#define GDIOBJFLAG_IGNOREPID (0x1)
#define GDIOBJFLAG_IGNORELOCK (0x2)
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)
{
#if DBG
PTHREADINFO pti = (PTHREADINFO)PsGetCurrentThreadWin32Thread();
if (pti)
{
if (pti->cExclusiveLocks < 1)
{
DbgPrint("cExclusiveLocks = %ld, object: %ld\n",
pti->cExclusiveLocks, Object->cExclusiveLock);
ASSERT(FALSE);
}
pti->cExclusiveLocks--;
}
#endif
INT cLocks = InterlockedDecrement((PLONG)&Object->cExclusiveLock);
ASSERT(cLocks >= 0);
return cLocks;
}
BOOL
NTAPI
GreDeleteObject(
HGDIOBJ hObject);
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))
{
ASSERT(Object->cExclusiveLock == 0);
GDIOBJ_SetOwnership(hobj, PsGetCurrentProcess());
GDIOBJ_FreeObjByHandle(hobj, GDI_OBJECT_TYPE_DONTCARE);
}
return cLocks;
}
NTAPI
GreGetObjectOwner(
HGDIOBJ hobj);
#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
BOOL
NTAPI
GreSetObjectOwner(
HGDIOBJ hobj,
ULONG ulOwner);
INT FASTCALL GreGetObjectOwner(HGDIOBJ, GDIOBJTYPE);
INT
NTAPI
GreGetObject(
IN HGDIOBJ hobj,
IN INT cbCount,
IN PVOID pvBuffer);
POBJ
NTAPI
GDIOBJ_AllocateObject(
UCHAR objt,
ULONG cjSize,
FLONG fl);
VOID
NTAPI
GDIOBJ_vDeleteObject(
POBJ pobj);
POBJ
NTAPI
GDIOBJ_ReferenceObjectByHandle(
HGDIOBJ hobj,
UCHAR objt);
VOID
NTAPI
GDIOBJ_vReferenceObjectByPointer(
POBJ pobj);
VOID
NTAPI
GDIOBJ_vDereferenceObject(
POBJ pobj);
PGDIOBJ
NTAPI
GDIOBJ_LockObject(
HGDIOBJ hobj,
UCHAR objt);
VOID
NTAPI
GDIOBJ_vUnlockObject(
POBJ pobj);
VOID
NTAPI
GDIOBJ_vSetObjectOwner(
POBJ pobj,
ULONG ulOwner);
BOOL
NTAPI
GDIOBJ_bLockMultipleObjects(
ULONG ulCount,
HGDIOBJ* ahObj,
PGDIOBJ* apObj,
UCHAR objt);
HGDIOBJ
NTAPI
GDIOBJ_hInsertObject(
POBJ pobj,
ULONG ulOwner);
VOID
NTAPI
GDIOBJ_vFreeObject(
POBJ pobj);
VOID
NTAPI
GDIOBJ_vSetObjectAttr(
POBJ pobj,
PVOID pvObjAttr);
PVOID
NTAPI
GDIOBJ_pvGetObjectAttr(
POBJ pobj);
BOOL INTERNAL_CALL GDIOBJ_ConvertToStockObj(HGDIOBJ *hObj);
POBJ INTERNAL_CALL GDIOBJ_AllocObjWithHandle(ULONG ObjectType, ULONG cjSize);
PGDIOBJ INTERNAL_CALL GDIOBJ_ShareLockObj(HGDIOBJ hObj, DWORD ObjectType);
PVOID INTERNAL_CALL GDI_MapHandleTable(PEPROCESS Process);
#define GDIOBJ_GetKernelObj(Handle) \
((PGDI_TABLE_ENTRY)&GdiHandleTable->Entries[GDI_HANDLE_GET_INDEX(Handle)])->KernelData
#define GDI_ENTRY_TO_INDEX(ht, e) \
(((ULONG_PTR)(e) - (ULONG_PTR)&((ht)->Entries[0])) / sizeof(GDI_TABLE_ENTRY))
#define GDI_HANDLE_GET_ENTRY(HandleTable, h) \
(&(HandleTable)->Entries[GDI_HANDLE_GET_INDEX((h))])
@@ -77,3 +77,63 @@ RegWriteUserSetting(
VOID FASTCALL
SetLastNtError(
NTSTATUS Status);
typedef struct _GDI_POOL *PGDI_POOL;
PGDI_POOL
NTAPI
GdiPoolCreate(
ULONG cjAllocSize,
ULONG ulTag);
VOID
NTAPI
GdiPoolDestroy(PGDI_POOL pPool);
PVOID
NTAPI
GdiPoolAllocate(
PGDI_POOL pPool);
VOID
NTAPI
GdiPoolFree(
PGDI_POOL pPool,
PVOID pvAlloc);
FORCEINLINE
VOID
ExAcquirePushLockExclusive(PEX_PUSH_LOCK PushLock)
{
/* Try acquiring the lock */
if (InterlockedBitTestAndSet((PLONG)PushLock, EX_PUSH_LOCK_LOCK_V))
{
/* Someone changed it, use the slow path */
ExfAcquirePushLockExclusive(PushLock);
}
}
FORCEINLINE
VOID
ExReleasePushLockExclusive(PEX_PUSH_LOCK PushLock)
{
EX_PUSH_LOCK OldValue;
/* Unlock the pushlock */
OldValue.Value = InterlockedExchangeAddSizeT((PSIZE_T)PushLock,
-(SSIZE_T)EX_PUSH_LOCK_LOCK);
/* Check if anyone is waiting on it and it's not already waking */
if ((OldValue.Waiting) && !(OldValue.Waking))
{
/* Wake it up */
ExfTryToWakePushLock(PushLock);
}
}
FORCEINLINE
VOID
_ExInitializePushLock(PEX_PUSH_LOCK Lock)
{
*(PULONG_PTR)Lock = 0;
}
#define ExInitializePushLock _ExInitializePushLock
@@ -65,13 +65,12 @@ HPALETTE FASTCALL PALETTE_AllocPaletteIndexedRGB(ULONG NumColors,
CONST RGBQUAD *Colors);
#define PALETTE_FreePalette(pPalette) GDIOBJ_FreeObj((POBJ)pPalette, GDIObjType_PAL_TYPE)
#define PALETTE_FreePaletteByHandle(hPalette) GDIOBJ_FreeObjByHandle((HGDIOBJ)hPalette, GDI_OBJECT_TYPE_PALETTE)
#define PALETTE_LockPalette(hPalette) ((PPALETTE)GDIOBJ_LockObj((HGDIOBJ)hPalette, GDI_OBJECT_TYPE_PALETTE))
#define PALETTE_UnlockPalette(pPalette) GDIOBJ_UnlockObjByPtr((POBJ)pPalette)
#define PALETTE_UnlockPalette(pPalette) GDIOBJ_vUnlockObject((POBJ)pPalette)
#define PALETTE_ShareLockPalette(hpal) \
((PPALETTE)GDIOBJ_ShareLockObj((HGDIOBJ)hpal, GDI_OBJECT_TYPE_PALETTE))
#define PALETTE_ShareUnlockPalette(ppal) \
GDIOBJ_ShareUnlockObjByPtr(&ppal->BaseObject)
GDIOBJ_vDereferenceObject(&ppal->BaseObject)
BOOL INTERNAL_CALL PALETTE_Cleanup(PVOID ObjectBody);
INIT_FUNCTION NTSTATUS NTAPI InitPaletteImpl(VOID);
@@ -19,7 +19,7 @@ typedef enum tagGdiPathState
typedef struct _PATH
{
BASEOBJECT BaseObject;
RECTFX rcfxBoundBox;
POINTFX ptfxSubPathStart;
@@ -39,11 +39,11 @@ typedef struct _EPATHOBJ
} EPATHOBJ, *PEPATHOBJ;
#define PATH_AllocPath() ((PPATH) GDIOBJ_AllocObj(GDIObjType_PATH_TYPE))
#define PATH_AllocPathWithHandle() ((PPATH) GDIOBJ_AllocObjWithHandle (GDI_OBJECT_TYPE_PATH))
#define PATH_AllocPathWithHandle() ((PPATH) GDIOBJ_AllocObjWithHandle (GDI_OBJECT_TYPE_PATH, sizeof(PATH)))
#define PATH_FreePath(pPath) GDIOBJ_FreeObj((POBJ)pPath, GDIObjType_PATH_TYPE)
#define PATH_FreeExtPathByHandle(hPath) GDIOBJ_FreeObjByHandle((HGDIOBJ) hPath, GDI_OBJECT_TYPE_PATH)
#define PATH_LockPath(hPath) ((PPATH)GDIOBJ_ShareLockObj((HGDIOBJ)hPath, GDI_OBJECT_TYPE_PATH))
#define PATH_UnlockPath(pPath) GDIOBJ_ShareUnlockObjByPtr((POBJ)pPath)
#define PATH_UnlockPath(pPath) GDIOBJ_vDereferenceObject((POBJ)pPath)
#define PATH_IsPathOpen(dclevel) ( ((dclevel).hPath) && ((dclevel).flPath & DCPATH_ACTIVE) )
@@ -6,7 +6,7 @@
/* Internal interface */
#define PEN_AllocPen() ((HPEN)GDIOBJ_AllocObj(GDIObjType_BRUSH_TYPE))
#define PEN_AllocPenWithHandle() ((PBRUSH)GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_PEN))
#define PEN_AllocPenWithHandle() ((PBRUSH)GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_PEN, sizeof(BRUSH)))
#define PEN_FreePen(pBMObj) GDIOBJ_FreeObj((POBJ) pBMObj, GDIObjType_BRUSH_TYPE)
#define PEN_FreePenByHandle(hBMObj) GDIOBJ_FreeObjByHandle((HGDIOBJ) hBMObj, GDI_OBJECT_TYPE_PEN)
@@ -14,16 +14,16 @@
//#define PEN_LockPen(hBMObj) ((PBRUSH)GDIOBJ_LockObj((HGDIOBJ) hBMObj, GDI_OBJECT_TYPE_PEN))
#define PEN_AllocExtPen() ((PBRUSH)GDIOBJ_AllocObj(GDIObjType_BRUSH_TYPE))
#define PEN_AllocExtPenWithHandle() ((PBRUSH)GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_EXTPEN))
#define PEN_AllocExtPenWithHandle() ((PBRUSH)GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_EXTPEN, sizeof(BRUSH)))
#define PEN_FreeExtPen(pBMObj) GDIOBJ_FreeObj((POBJ) pBMObj, GDIObjType_BRUSH_TYPE)
#define PEN_FreeExtPenByHandle(hBMObj) GDIOBJ_FreeObjByHandle((HGDIOBJ) hBMObj, GDI_OBJECT_TYPE_EXTPEN)
//#define PEN_LockExtPen(hBMObj) ((PBRUSH)GDIOBJ_LockObj((HGDIOBJ) hBMObj, GDI_OBJECT_TYPE_EXTPEN))
#define PEN_UnlockPen(pPenObj) GDIOBJ_UnlockObjByPtr((POBJ)pPenObj)
#define PEN_UnlockPen(pPenObj) GDIOBJ_vUnlockObject((POBJ)pPenObj)
#define PEN_ShareUnlockPen(ppen) GDIOBJ_ShareUnlockObjByPtr((POBJ)ppen)
#define PEN_ShareUnlockPen(ppen) GDIOBJ_vDereferenceObject((POBJ)ppen)
PBRUSH FASTCALL PEN_LockPen(HGDIOBJ);
@@ -11,6 +11,8 @@ typedef struct _ROSRGNDATA
/* Header for all gdi objects in the handle table.
Do not (re)move this. */
BASEOBJECT BaseObject;
PRGN_ATTR prgnattr;
RGN_ATTR rgnattr;
RGNDATAHEADER rdh;
RECTL *Buffer;
@@ -21,8 +23,6 @@ typedef struct _ROSRGNDATA
#define REGION_FreeRgn(pRgn) GDIOBJ_FreeObj((POBJ)pRgn, GDIObjType_RGN_TYPE)
#define REGION_FreeRgnByHandle(hRgn) GDIOBJ_FreeObjByHandle((HGDIOBJ)hRgn, GDI_OBJECT_TYPE_REGION)
#define REGION_LockRgn(hRgn) ((PROSRGNDATA)GDIOBJ_LockObj((HGDIOBJ)hRgn, GDI_OBJECT_TYPE_REGION))
#define REGION_UnlockRgn(pRgn) GDIOBJ_UnlockObjByPtr((POBJ)pRgn)
PROSRGNDATA FASTCALL REGION_AllocRgnWithHandle(INT n);
PROSRGNDATA FASTCALL REGION_AllocUserRgnWithHandle(INT n);
@@ -52,9 +52,28 @@ PROSRGNDATA FASTCALL RGNOBJAPI_Lock(HRGN,PRGN_ATTR *);
VOID FASTCALL RGNOBJAPI_Unlock(PROSRGNDATA);
HRGN FASTCALL IntSysCreateRectRgn(INT,INT,INT,INT);
PROSRGNDATA FASTCALL IntSysCreateRectpRgn(INT,INT,INT,INT);
BOOL FASTCALL IntGdiSetRegionOwner(HRGN,DWORD);
#define IntSysCreateRectRgnIndirect(prc) \
IntSysCreateRectRgn((prc)->left, (prc)->top, (prc)->right, (prc)->bottom)
#define IntSysCreateRectpRgnIndirect(prc) \
IntSysCreateRectpRgn((prc)->left, (prc)->top, (prc)->right, (prc)->bottom)
PROSRGNDATA
FASTCALL
IntSysCreateRectpRgn(INT LeftRect, INT TopRect, INT RightRect, INT BottomRect);
FORCEINLINE
PREGION
REGION_LockRgn(HRGN hrgn)
{
return GDIOBJ_LockObject(hrgn, GDIObjType_RGN_TYPE);
}
FORCEINLINE
VOID
REGION_UnlockRgn(PREGION prgn)
{
GDIOBJ_vUnlockObject(&prgn->BaseObject);
}
@@ -90,19 +90,17 @@ typedef struct _SURFACE
/* Internal interface */
#define SURFACE_AllocSurfaceWithHandle() ((PSURFACE) GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_BITMAP))
#define SURFACE_AllocSurfaceWithHandle() ((PSURFACE) GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_BITMAP, sizeof(SURFACE)))
#define SURFACE_FreeSurface(pBMObj) GDIOBJ_FreeObj((POBJ) pBMObj, GDIObjType_SURF_TYPE)
#define SURFACE_FreeSurfaceByHandle(hBMObj) GDIOBJ_FreeObjByHandle((HGDIOBJ) hBMObj, GDI_OBJECT_TYPE_BITMAP)
/* NOTE: Use shared locks! */
#define SURFACE_LockSurface(hBMObj) \
((PSURFACE) GDIOBJ_LockObj ((HGDIOBJ) hBMObj, GDI_OBJECT_TYPE_BITMAP))
#define SURFACE_ShareLockSurface(hBMObj) \
((PSURFACE) GDIOBJ_ShareLockObj ((HGDIOBJ) hBMObj, GDI_OBJECT_TYPE_BITMAP))
#define SURFACE_UnlockSurface(pBMObj) \
GDIOBJ_UnlockObjByPtr ((POBJ)pBMObj)
GDIOBJ_vUnlockObject ((POBJ)pBMObj)
#define SURFACE_ShareUnlockSurface(pBMObj) \
GDIOBJ_ShareUnlockObjByPtr ((POBJ)pBMObj)
GDIOBJ_vDereferenceObject ((POBJ)pBMObj)
BOOL INTERNAL_CALL SURFACE_Cleanup(PVOID ObjectBody);
@@ -77,11 +77,11 @@ typedef struct
/* Internal interface */
#define TEXTOBJ_AllocText() ((PTEXTOBJ) GDIOBJ_AllocObj(GDIObjType_LFONT_TYPE))
#define TEXTOBJ_AllocTextWithHandle() ((PTEXTOBJ) GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_FONT))
#define TEXTOBJ_AllocTextWithHandle() ((PTEXTOBJ) GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_FONT, sizeof(TEXTOBJ)))
#define TEXTOBJ_FreeText(pBMObj) GDIOBJ_FreeObj((POBJ) pBMObj, GDILoObjType_LO_FONT_TYPE)
#define TEXTOBJ_FreeTextByHandle(hBMObj) GDIOBJ_FreeObj((HGDIOBJ) hBMObj, GDI_OBJECT_TYPE_FONT)
#define TEXTOBJ_LockText(hBMObj) ((PTEXTOBJ) GDIOBJ_LockObj ((HGDIOBJ) hBMObj, GDI_OBJECT_TYPE_FONT))
#define TEXTOBJ_UnlockText(pBMObj) GDIOBJ_UnlockObjByPtr ((POBJ)pBMObj)
#define TEXTOBJ_LockText(hBMObj) ((PTEXTOBJ) GDIOBJ_LockObject((HGDIOBJ) hBMObj, GDIObjType_LFONT_TYPE))
#define TEXTOBJ_UnlockText(pBMObj) GDIOBJ_vUnlockObject ((POBJ)pBMObj)
PTEXTOBJ FASTCALL RealizeFontInit(HFONT);
NTSTATUS FASTCALL TextIntRealizeFont(HFONT,PTEXTOBJ);
@@ -105,6 +105,9 @@ typedef struct _THREADINFO
LIST_ENTRY W32CallbackListHead;
SINGLE_LIST_ENTRY ReferencesList;
ULONG cExclusiveLocks;
#if DBG
USHORT acExclusiveLockCount[GDIObjTypeTotal];
#endif
} THREADINFO;
@@ -186,4 +189,7 @@ typedef struct _PROCESSINFO
LIST_ENTRY DriverObjListHead;
struct _KBL* KeyboardLayout; // THREADINFO only
W32HEAP_USER_MAPPING HeapMappings;
struct _GDI_POOL *pPoolDcAttr;
struct _GDI_POOL *pPoolBrushAttr;
struct _GDI_POOL *pPoolRgnAttr;
} PROCESSINFO;
@@ -18,6 +18,11 @@
#define INIT_FUNCTION
#endif
/* Enable debugging features */
#define GDI_DEBUG 0
#define DBG_ENABLE_EVENT_LOGGING 0
#define DBG_ENABLE_SERVICE_HOOKS 0
/* Internal Win32k Headers */
#include <include/accelerator.h>
#include <include/clipboard.h>
+13 -1
View File
@@ -114,6 +114,14 @@ Win32kProcessCallback(struct _EPROCESS *Process,
Win32Process->peProcess = Process;
/* setup process flags */
Win32Process->W32PF_flags = 0;
/* Create pools for GDI object attributes */
Win32Process->pPoolDcAttr = GdiPoolCreate(sizeof(DC_ATTR), 'acdG');
Win32Process->pPoolBrushAttr = GdiPoolCreate(sizeof(BRUSH_ATTR), 'arbG');
Win32Process->pPoolRgnAttr = GdiPoolCreate(sizeof(RGN_ATTR), 'agrG');
ASSERT(Win32Process->pPoolDcAttr);
ASSERT(Win32Process->pPoolBrushAttr);
ASSERT(Win32Process->pPoolRgnAttr);
}
else
{
@@ -148,6 +156,10 @@ Win32kProcessCallback(struct _EPROCESS *Process,
UserSetProcessWindowStation(NULL);
/* Destroy GDI pools */
GdiPoolDestroy(Win32Process->pPoolDcAttr);
GdiPoolDestroy(Win32Process->pPoolBrushAttr);
GdiPoolDestroy(Win32Process->pPoolRgnAttr);
}
RETURN( STATUS_SUCCESS);
@@ -440,7 +452,7 @@ DriverEntry(
/* Register our per-process and per-thread structures. */
PsEstablishWin32Callouts((PWIN32_CALLOUTS_FPNS)&CalloutData);
#if 0 // DBG
#if 1 // DBG
/* Register service hook callbacks */
KdSystemDebugControl('CsoR', DbgPreServiceHook, ID_Win32PreServiceHook, 0, 0, 0, 0);
KdSystemDebugControl('CsoR', DbgPostServiceHook, ID_Win32PostServiceHook, 0, 0, 0, 0);
@@ -727,7 +727,7 @@ BOOL APIENTRY DxEngSetDCOwner(HGDIOBJ hObject, DWORD OwnerMask)
{
DPRINT1("ReactX Calling : DxEngSetDCOwner \n");
return IntGdiSetDCOwnerEx( hObject, OwnerMask, FALSE);
return GreSetDCOwner(hObject, OwnerMask);
}
/************************************************************************/
@@ -413,13 +413,13 @@ IntDestroyCurIconObject(PCURICON_OBJECT CurIcon, BOOL ProcessCleanup)
/* delete bitmaps */
if (bmpMask)
{
GDIOBJ_SetOwnership(bmpMask, PsGetCurrentProcess());
GreSetObjectOwner(bmpMask, GDI_OBJ_HMGR_POWNED);
GreDeleteObject(bmpMask);
CurIcon->IconInfo.hbmMask = NULL;
}
if (bmpColor)
{
GDIOBJ_SetOwnership(bmpColor, PsGetCurrentProcess());
GreSetObjectOwner(bmpColor, GDI_OBJ_HMGR_POWNED);
GreDeleteObject(bmpColor);
CurIcon->IconInfo.hbmColor = NULL;
}
@@ -934,13 +934,16 @@ NtUserSetCursorContents(
/* Copy new IconInfo field */
CurIcon->IconInfo = IconInfo;
psurfBmp = SURFACE_ShareLockSurface(CurIcon->IconInfo.hbmColor);
if (psurfBmp)
if (CurIcon->IconInfo.hbmColor)
{
psurfBmp = SURFACE_ShareLockSurface(CurIcon->IconInfo.hbmColor);
if (!psurfBmp)
goto done;
CurIcon->Size.cx = psurfBmp->SurfObj.sizlBitmap.cx;
CurIcon->Size.cy = psurfBmp->SurfObj.sizlBitmap.cy;
SURFACE_ShareUnlockSurface(psurfBmp);
GDIOBJ_SetOwnership(CurIcon->IconInfo.hbmColor, NULL);
GreSetObjectOwner(CurIcon->IconInfo.hbmColor, GDI_OBJ_HMGR_PUBLIC);
}
else
{
@@ -953,7 +956,7 @@ NtUserSetCursorContents(
SURFACE_ShareUnlockSurface(psurfBmp);
}
GDIOBJ_SetOwnership(CurIcon->IconInfo.hbmMask, NULL);
GreSetObjectOwner(CurIcon->IconInfo.hbmMask, GDI_OBJ_HMGR_PUBLIC);
Ret = TRUE;
@@ -1017,7 +1020,7 @@ NtUserSetCursorIconData(
CurIcon->Size.cx = psurfBmp->SurfObj.sizlBitmap.cx;
CurIcon->Size.cy = psurfBmp->SurfObj.sizlBitmap.cy;
SURFACE_UnlockSurface(psurfBmp);
GDIOBJ_SetOwnership(GdiHandleTable, CurIcon->IconInfo.hbmMask, NULL);
GreSetObjectOwner(CurIcon->IconInfo.hbmMask, GDI_OBJ_HMGR_PUBLIC);
}
}
if (CurIcon->IconInfo.hbmMask)
@@ -1031,7 +1034,7 @@ NtUserSetCursorIconData(
SURFACE_UnlockSurface(psurfBmp);
}
}
GDIOBJ_SetOwnership(GdiHandleTable, CurIcon->IconInfo.hbmMask, NULL);
GreSetObjectOwner(CurIcon->IconInfo.hbmMask, GDI_OBJ_HMGR_PUBLIC);
}
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
@@ -1121,10 +1124,10 @@ done:
if(Ret)
{
/* This icon is shared now */
GDIOBJ_SetOwnership(CurIcon->IconInfo.hbmMask, NULL);
GreSetObjectOwner(CurIcon->IconInfo.hbmMask, GDI_OBJ_HMGR_PUBLIC);
if(CurIcon->IconInfo.hbmColor)
{
GDIOBJ_SetOwnership(CurIcon->IconInfo.hbmColor, NULL);
GreSetObjectOwner(CurIcon->IconInfo.hbmColor, GDI_OBJ_HMGR_PUBLIC);
}
}
UserDereferenceObject(CurIcon);
@@ -1170,12 +1173,12 @@ UserDrawIconEx(
if (istepIfAniCur)
DPRINT1("NtUserDrawIconEx: istepIfAniCur is not supported!\n");
if (!hbmMask || !IntGdiGetObject(hbmMask, sizeof(BITMAP), (PVOID)&bm))
if (!hbmMask || !GreGetObject(hbmMask, sizeof(BITMAP), (PVOID)&bm))
{
return FALSE;
}
if (hbmColor && !IntGdiGetObject(hbmColor, sizeof(BITMAP), (PVOID)&bmpColor))
if (hbmColor && !GreGetObject(hbmColor, sizeof(BITMAP), (PVOID)&bmpColor))
{
return FALSE;
}
@@ -168,7 +168,7 @@ IntDesktopObjectDelete(PWIN32_DELETEMETHOD_PARAMETERS Parameters)
IntFreeDesktopHeap(Desktop);
}
NTSTATUS NTAPI
NTSTATUS NTAPI
IntDesktopOkToClose(PWIN32_OKAYTOCLOSEMETHOD_PARAMETERS Parameters)
{
PTHREADINFO pti;
@@ -640,7 +640,7 @@ UserRedrawDesktop()
{
PWND Window = NULL;
HRGN hRgn;
Window = UserGetDesktopWindow();
hRgn = IntSysCreateRectRgnIndirect(&Window->rcWindow);
@@ -650,8 +650,8 @@ UserRedrawDesktop()
RDW_ERASE |
RDW_INVALIDATE |
RDW_ALLCHILDREN);
REGION_FreeRgnByHandle(hRgn);
GreDeleteObject(hRgn);
}
@@ -1831,7 +1831,7 @@ IntSetThreadDesktop(IN HDESK hDesktop,
DPRINT("IntSetThreadDesktop() , FOF=%d\n", FreeOnFailure);
MapHeap = (PsGetCurrentProcess() != PsInitialSystemProcess);
W32Thread = PsGetCurrentThreadWin32Thread();
if(hDesktop != NULL)
{
/* Validate the new desktop. */
@@ -1943,7 +1943,7 @@ IntSetThreadDesktop(IN HDESK hDesktop,
ObDereferenceObject(OldDesktop);
}
if (hOldDesktop != NULL)
{
ZwClose(hOldDesktop);
@@ -1965,11 +1965,11 @@ NtUserSetThreadDesktop(HDESK hDesktop)
BOOL ret;
UserEnterExclusive();
ret = IntSetThreadDesktop(hDesktop, FALSE);
UserLeave();
return ret;
}
@@ -667,7 +667,7 @@ IntDispatchMessage(PMSG pMsg)
/* send a WM_NCPAINT and WM_ERASEBKGND if the non-client area is still invalid */
HRGN hrgn = IntSysCreateRectRgn( 0, 0, 0, 0 );
co_UserGetUpdateRgn( Window, hrgn, TRUE );
REGION_FreeRgnByHandle( hrgn );
GreDeleteObject(hrgn);
}
return retval;
@@ -1482,7 +1482,7 @@ co_IntSendMessageWithCallBack( HWND hWnd,
}
IntReferenceMessageQueue(Window->head.pti->MessageQueue);
/* Take reference on this MessageQueue if its a callback. It will be released
/* Take reference on this MessageQueue if its a callback. It will be released
when message is processed or removed from target hwnd MessageQueue */
if (CompletionCallback)
IntReferenceMessageQueue(Win32Thread->MessageQueue);
@@ -175,7 +175,7 @@ IntAttachMonitor(IN PDEVOBJ *pGdiDevice,
}
Monitor->Prev = p;
}
IntUpdateMonitorSize(pGdiDevice);
return STATUS_SUCCESS;
@@ -232,7 +232,7 @@ IntDetachMonitor(IN PDEVOBJ *pGdiDevice)
}
if (Monitor->hrgnMonitor)
REGION_FreeRgnByHandle(Monitor->hrgnMonitor);
GreDeleteObject(Monitor->hrgnMonitor);
IntDestroyMonitorObject(Monitor);
@@ -276,8 +276,8 @@ IntUpdateMonitorSize(IN PDEVOBJ *pGdiDevice)
if (Monitor->hrgnMonitor)
{
GDIOBJ_SetOwnership(Monitor->hrgnMonitor, PsGetCurrentProcess());
REGION_FreeRgnByHandle(Monitor->hrgnMonitor);
GreSetObjectOwner(Monitor->hrgnMonitor, GDI_OBJ_HMGR_POWNED);
GreDeleteObject(Monitor->hrgnMonitor);
}
Monitor->hrgnMonitor = IntSysCreateRectRgnIndirect( &Monitor->rcMonitor );
@@ -413,7 +413,7 @@ IntGetMonitorsFromRect(OPTIONAL IN LPCRECTL pRect,
if (monitorRectList != NULL)
monitorRectList[iCount] = IntersectionRect;
}
/* Increase count of found monitors */
iCount++;
}
@@ -806,7 +806,7 @@ NtUserMonitorFromRect(
return hMonitor;
}
hMonitorList = ExAllocatePoolWithTag(PagedPool,
hMonitorList = ExAllocatePoolWithTag(PagedPool,
sizeof(HMONITOR) * numMonitors,
USERTAG_MONITORRECTS);
if (hMonitorList == NULL)
@@ -157,7 +157,7 @@ IntGetNCUpdateRgn(PWND Window, BOOL Validate)
hRgnWindow = IntCalcWindowRgn(Window, TRUE);
if (hRgnWindow == NULL)
{
REGION_FreeRgnByHandle(hRgnNonClient);
GreDeleteObject(hRgnNonClient);
return HRGN_WINDOW;
}
@@ -165,14 +165,14 @@ IntGetNCUpdateRgn(PWND Window, BOOL Validate)
hRgnWindow, RGN_DIFF);
if (RgnType == ERROR)
{
REGION_FreeRgnByHandle(hRgnWindow);
REGION_FreeRgnByHandle(hRgnNonClient);
GreDeleteObject(hRgnWindow);
GreDeleteObject(hRgnNonClient);
return HRGN_WINDOW;
}
else if (RgnType == NULLREGION)
{
REGION_FreeRgnByHandle(hRgnWindow);
REGION_FreeRgnByHandle(hRgnNonClient);
GreDeleteObject(hRgnWindow);
GreDeleteObject(hRgnNonClient);
return NULL;
}
@@ -187,14 +187,14 @@ IntGetNCUpdateRgn(PWND Window, BOOL Validate)
hRgnWindow, RGN_AND) == NULLREGION)
{
IntGdiSetRegionOwner(Window->hrgnUpdate, GDI_OBJ_HMGR_POWNED);
REGION_FreeRgnByHandle(Window->hrgnUpdate);
GreDeleteObject(Window->hrgnUpdate);
Window->hrgnUpdate = NULL;
if (!(Window->state & WNDS_INTERNALPAINT))
MsqDecPaintCountQueue(Window->head.pti->MessageQueue);
}
}
REGION_FreeRgnByHandle(hRgnWindow);
GreDeleteObject(hRgnWindow);
return hRgnNonClient;
}
@@ -246,7 +246,7 @@ co_IntPaintWindows(PWND Wnd, ULONG Flags, BOOL Recurse)
NULL != TempRegion)
{
/* NOTE: The region can already be deleted! */
GDIOBJ_FreeObjByHandle(TempRegion, GDI_OBJECT_TYPE_REGION | GDI_OBJECT_TYPE_SILENT);
GreDeleteObject(TempRegion);
}
}
@@ -328,7 +328,7 @@ IntInvalidateWindows(PWND Wnd, HRGN hRgn, ULONG Flags)
hRgnClient = IntSysCreateRectRgnIndirect(&Wnd->rcClient);
RgnType = NtGdiCombineRgn(hRgn, hRgn, hRgnClient, RGN_AND);
REGION_FreeRgnByHandle(hRgnClient);
GreDeleteObject(hRgnClient);
}
/*
@@ -341,7 +341,7 @@ IntInvalidateWindows(PWND Wnd, HRGN hRgn, ULONG Flags)
hRgnWindow = IntSysCreateRectRgnIndirect(&Wnd->rcWindow);
RgnType = NtGdiCombineRgn(hRgn, hRgn, hRgnWindow, RGN_AND);
REGION_FreeRgnByHandle(hRgnWindow);
GreDeleteObject(hRgnWindow);
}
else
{
@@ -378,7 +378,7 @@ IntInvalidateWindows(PWND Wnd, HRGN hRgn, ULONG Flags)
hRgn, RGN_OR) == NULLREGION)
{
IntGdiSetRegionOwner(Wnd->hrgnUpdate, GDI_OBJ_HMGR_POWNED);
REGION_FreeRgnByHandle(Wnd->hrgnUpdate);
GreDeleteObject(Wnd->hrgnUpdate);
Wnd->hrgnUpdate = NULL;
}
@@ -398,7 +398,7 @@ IntInvalidateWindows(PWND Wnd, HRGN hRgn, ULONG Flags)
hRgn, RGN_DIFF) == NULLREGION)
{
IntGdiSetRegionOwner(Wnd->hrgnUpdate, GDI_OBJ_HMGR_POWNED);
REGION_FreeRgnByHandle(Wnd->hrgnUpdate);
GreDeleteObject(Wnd->hrgnUpdate);
Wnd->hrgnUpdate = NULL;
}
}
@@ -440,7 +440,7 @@ IntInvalidateWindows(PWND Wnd, HRGN hRgn, ULONG Flags)
HRGN hRgnTemp = IntSysCreateRectRgn(0, 0, 0, 0);
NtGdiCombineRgn(hRgnTemp, hRgn, 0, RGN_COPY);
IntInvalidateWindows(Child, hRgnTemp, Flags);
REGION_FreeRgnByHandle(hRgnTemp);
GreDeleteObject(hRgnTemp);
}
}
@@ -540,7 +540,7 @@ co_UserRedrawWindow(
hRgn = IntSysCreateRectRgn(0, 0, 0, 0);
if (NtGdiCombineRgn(hRgn, UpdateRgn, NULL, RGN_COPY) == NULLREGION)
{
REGION_FreeRgnByHandle(hRgn);
GreDeleteObject(hRgn);
hRgn = NULL;
}
else
@@ -595,7 +595,7 @@ co_UserRedrawWindow(
if (hRgn != NULL)
{
REGION_FreeRgnByHandle(hRgn);
GreDeleteObject(hRgn);
}
DPRINT("co_UserRedrawWindow exit\n");
@@ -825,10 +825,10 @@ NtUserBeginPaint(HWND hWnd, PAINTSTRUCT* UnsafePs)
Window->state &= ~WNDS_SENDNCPAINT;
MsqDecPaintCountQueue(Window->head.pti->MessageQueue);
co_IntSendMessage(hWnd, WM_NCPAINT, (WPARAM)hRgn, 0);
if (hRgn != (HANDLE)1 && hRgn != NULL)
if (hRgn != (HANDLE)1 && hRgn != NULL && GreIsHandleValid(hRgn))
{
/* NOTE: The region can already by deleted! */
GDIOBJ_FreeObjByHandle(hRgn, GDI_OBJECT_TYPE_REGION | GDI_OBJECT_TYPE_SILENT);
GreDeleteObject(hRgn);
}
}
@@ -1230,14 +1230,14 @@ UserScrollDC(
could not be copied, because it was not visible */
if (hrgnUpdate || prcUpdate)
{
HRGN hrgnOwn, hrgnVisible, hrgnTmp;
HRGN hrgnOwn, hrgnTmp;
PREGION prgnTmp;
pDC = DC_LockDc(hDC);
if (!pDC)
{
return FALSE;
}
hrgnVisible = ((PROSRGNDATA)pDC->prgnVis)->BaseObject.hHmgr; // pDC->prgnRao?
/* Begin with the shifted and then clipped scroll rect */
rcDst = rcScroll;
@@ -1262,14 +1262,16 @@ UserScrollDC(
NtGdiCombineRgn(hrgnOwn, hrgnOwn, hrgnTmp, RGN_OR);
/* Substract the part of the dest that was visible in source */
NtGdiCombineRgn(hrgnTmp, hrgnTmp, hrgnVisible, RGN_AND);
prgnTmp = RGNOBJAPI_Lock(hrgnTmp, NULL);
IntGdiCombineRgn(prgnTmp, prgnTmp, pDC->prgnVis, RGN_AND);
RGNOBJAPI_Unlock(prgnTmp);
NtGdiOffsetRgn(hrgnTmp, dx, dy);
Result = NtGdiCombineRgn(hrgnOwn, hrgnOwn, hrgnTmp, RGN_DIFF);
/* DO NOT Unlock DC while messing with prgnVis! */
DC_UnlockDc(pDC);
REGION_FreeRgnByHandle(hrgnTmp);
GreDeleteObject(hrgnTmp);
if (prcUpdate)
{
@@ -1278,7 +1280,7 @@ UserScrollDC(
if (!hrgnUpdate)
{
REGION_FreeRgnByHandle(hrgnOwn);
GreDeleteObject(hrgnOwn);
}
}
else
@@ -1491,9 +1493,9 @@ NtUserScrollWindowEx(
NtGdiOffsetRgn(hrgnTemp, dx, dy);
NtGdiCombineRgn(hrgnTemp, hrgnTemp, hrgnClip, RGN_AND);
co_UserRedrawWindow(Window, NULL, hrgnTemp, RDW_INVALIDATE | RDW_ERASE);
REGION_FreeRgnByHandle(hrgnClip);
GreDeleteObject(hrgnClip);
}
REGION_FreeRgnByHandle(hrgnTemp);
GreDeleteObject(hrgnTemp);
if (flags & SW_SCROLLCHILDREN)
{
@@ -1566,7 +1568,7 @@ NtUserScrollWindowEx(
CLEANUP:
if (hrgnOwn && !hrgnUpdate)
{
REGION_FreeRgnByHandle(hrgnOwn);
GreDeleteObject(hrgnOwn);
}
if (Window)
@@ -647,7 +647,7 @@ SpiSetWallpaper(PVOID pvParam, FLONG fl)
SURFACE_ShareUnlockSurface(psurfBmp);
/* Change the bitmap's ownership */
GDIOBJ_SetOwnership(hbmp, NULL);
GreSetObjectOwner(hbmp, GDI_OBJ_HMGR_PUBLIC);
/* Yes, Windows really loads the current setting from the registry. */
ulTile = SpiLoadInt(KEY_DESKTOP, L"TileWallpaper", 0);
@@ -677,7 +677,7 @@ SpiSetWallpaper(PVOID pvParam, FLONG fl)
if(hOldBitmap != NULL)
{
/* Delete the old wallpaper */
GDIOBJ_SetOwnership(hOldBitmap, PsGetCurrentProcess());
GreSetObjectOwner(hOldBitmap, GDI_OBJ_HMGR_POWNED);
GreDeleteObject(hOldBitmap);
}
+7 -7
View File
@@ -69,25 +69,25 @@ VIS_ComputeVisibleRegion(
CurrentWindow->state & WNDS_DESTROYED )
{
DPRINT1("ATM the Current Window or Parent is dead!\n");
if (VisRgn) REGION_FreeRgnByHandle(VisRgn);
if (VisRgn) GreDeleteObject(VisRgn);
return NULL;
}
if (!(CurrentWindow->style & WS_VISIBLE))
{
if (VisRgn) REGION_FreeRgnByHandle(VisRgn);
if (VisRgn) GreDeleteObject(VisRgn);
return NULL;
}
ClipRgn = IntSysCreateRectRgnIndirect(&CurrentWindow->rcClient);
NtGdiCombineRgn(VisRgn, VisRgn, ClipRgn, RGN_AND);
REGION_FreeRgnByHandle(ClipRgn);
GreDeleteObject(ClipRgn);
if ((PreviousWindow->style & WS_CLIPSIBLINGS) ||
(PreviousWindow == Wnd && ClipSiblings))
{
CurrentSibling = CurrentWindow->spwndChild;
while ( CurrentSibling != NULL &&
while ( CurrentSibling != NULL &&
CurrentSibling != PreviousWindow )
{
if ((CurrentSibling->style & WS_VISIBLE) &&
@@ -102,7 +102,7 @@ VIS_ComputeVisibleRegion(
NtGdiOffsetRgn(ClipRgn, CurrentSibling->rcWindow.left, CurrentSibling->rcWindow.top);
}
NtGdiCombineRgn(VisRgn, VisRgn, ClipRgn, RGN_DIFF);
REGION_FreeRgnByHandle(ClipRgn);
GreDeleteObject(ClipRgn);
}
CurrentSibling = CurrentSibling->spwndNext;
}
@@ -129,7 +129,7 @@ VIS_ComputeVisibleRegion(
NtGdiOffsetRgn(ClipRgn, CurrentWindow->rcWindow.left, CurrentWindow->rcWindow.top);
}
NtGdiCombineRgn(VisRgn, VisRgn, ClipRgn, RGN_DIFF);
REGION_FreeRgnByHandle(ClipRgn);
GreDeleteObject(ClipRgn);
}
CurrentWindow = CurrentWindow->spwndNext;
}
@@ -172,7 +172,7 @@ co_VIS_WindowLayoutChanged(
RDW_ALLCHILDREN);
UserDerefObjectCo(Parent);
}
REGION_FreeRgnByHandle(Temp);
GreDeleteObject(Temp);
}
/* EOF */
+19 -17
View File
@@ -50,6 +50,7 @@ DceCreateDisplayDC(VOID)
if (hDC && !defaultDCstate) // Ultra HAX! Dedicated to GvG!
{ // This is a cheesy way to do this.
PDC dc = DC_LockDc ( hDC );
ASSERT(dc);
defaultDCstate = ExAllocatePoolWithTag(PagedPool, sizeof(DC), TAG_DC);
RtlZeroMemory(defaultDCstate, sizeof(DC));
defaultDCstate->pdcattr = &defaultDCstate->dcattr;
@@ -113,7 +114,7 @@ DceAllocDCE(PWND Window OPTIONAL, DCE_TYPE Type)
else
{
DPRINT("FREE DCATTR!!!! NOT DCE_WINDOW_DC!!!!! hDC-> %x\n", pDce->hDC);
IntGdiSetDCOwnerEx( pDce->hDC, GDI_OBJ_HMGR_NONE, FALSE);
GreSetDCOwner(pDce->hDC, GDI_OBJ_HMGR_NONE);
pDce->ptiOwner = NULL;
}
@@ -179,7 +180,7 @@ DceDeleteClipRgn(DCE* Dce)
}
else if (Dce->hrgnClip != NULL)
{
GDIOBJ_FreeObjByHandle(Dce->hrgnClip, GDI_OBJECT_TYPE_REGION|GDI_OBJECT_TYPE_SILENT);
GreDeleteObject(Dce->hrgnClip);
}
Dce->hrgnClip = NULL;
@@ -225,7 +226,7 @@ DceReleaseDC(DCE* dce, BOOL EndPaint)
}
dce->DCXFlags &= ~DCX_DCEBUSY;
DPRINT("Exit!!!!! DCX_CACHE!!!!!! hDC-> %x \n", dce->hDC);
if (!IntGdiSetDCOwnerEx( dce->hDC, GDI_OBJ_HMGR_NONE, FALSE))
if (!GreSetDCOwner(dce->hDC, GDI_OBJ_HMGR_NONE))
return 0;
dce->ptiOwner = NULL; // Reset ownership.
dce->ppiOwner = NULL;
@@ -308,7 +309,7 @@ noparent:
{
if(hRgnVisible != NULL)
{
REGION_FreeRgnByHandle(hRgnVisible);
GreDeleteObject(hRgnVisible);
}
hRgnVisible = IntSysCreateRectRgn(0, 0, 0, 0);
}
@@ -328,7 +329,7 @@ noparent:
if (hRgnVisible != NULL)
{
REGION_FreeRgnByHandle(hRgnVisible);
GreDeleteObject(hRgnVisible);
}
}
@@ -521,7 +522,7 @@ UserGetDCEx(PWND Wnd OPTIONAL, HANDLE ClipRegion, ULONG Flags)
return(NULL);
}
if (!GDIOBJ_ValidateHandle(Dce->hDC, GDI_OBJECT_TYPE_DC))
if (!GreIsHandleValid(Dce->hDC))
{
DPRINT1("FIXME: Got DCE with invalid hDC! 0x%x\n", Dce->hDC);
Dce->hDC = DceCreateDisplayDC();
@@ -568,7 +569,7 @@ UserGetDCEx(PWND Wnd OPTIONAL, HANDLE ClipRegion, ULONG Flags)
if (Dce->hrgnClip != NULL)
{
DPRINT1("Should not be called!!\n");
GDIOBJ_FreeObjByHandle(Dce->hrgnClip, GDI_OBJECT_TYPE_REGION|GDI_OBJECT_TYPE_SILENT);
GreDeleteObject(Dce->hrgnClip);
Dce->hrgnClip = NULL;
}
Dce->hrgnClip = ClipRegion;
@@ -582,7 +583,7 @@ UserGetDCEx(PWND Wnd OPTIONAL, HANDLE ClipRegion, ULONG Flags)
{
DPRINT("ENTER!!!!!! DCX_CACHE!!!!!! hDC-> %x\n", Dce->hDC);
// Need to set ownership so Sync dcattr will work.
IntGdiSetDCOwnerEx( Dce->hDC, GDI_OBJ_HMGR_POWNED, FALSE);
GreSetDCOwner(Dce->hDC, GDI_OBJ_HMGR_POWNED);
Dce->ptiOwner = GetW32ThreadInfo(); // Set the temp owning
}
@@ -621,13 +622,14 @@ DceFreeDCE(PDCE pdce, BOOLEAN Force)
pdce->DCXFlags |= DCX_INDESTROY;
if (Force && !GDIOBJ_OwnedByCurrentProcess(pdce->hDC))
if (Force &&
GreGetObjectOwner(pdce->hDC) != GDI_OBJ_HMGR_POWNED)
{
DPRINT("Change ownership for DCE! -> %x\n" , pdce);
// Note: Windows sets W32PF_OWNDCCLEANUP and moves on.
if (!IsObjectDead((HGDIOBJ) pdce->hDC))
if (GreIsHandleValid(pdce->hDC))
{
DC_SetOwnership( pdce->hDC, PsGetCurrentProcess());
GreSetDCOwner(pdce->hDC, GDI_OBJ_HMGR_POWNED);
}
else
{
@@ -637,15 +639,15 @@ DceFreeDCE(PDCE pdce, BOOLEAN Force)
}
else
{
if (!GreGetObjectOwner(pdce->hDC, GDIObjType_DC_TYPE))
DC_SetOwnership( pdce->hDC, PsGetCurrentProcess());
if (GreGetObjectOwner(pdce->hDC) == GDI_OBJ_HMGR_PUBLIC)
GreSetDCOwner(pdce->hDC, GDI_OBJ_HMGR_POWNED);
}
if (!Hit) IntGdiDeleteDC(pdce->hDC, TRUE);
if (pdce->hrgnClip && !(pdce->DCXFlags & DCX_KEEPCLIPRGN))
{
GDIOBJ_FreeObjByHandle(pdce->hrgnClip, GDI_OBJECT_TYPE_REGION|GDI_OBJECT_TYPE_SILENT);
GreDeleteObject(pdce->hrgnClip);
pdce->hrgnClip = NULL;
}
@@ -712,7 +714,7 @@ DceFreeWindowDCE(PWND Window)
pDCE->hwndCurrent = 0;
DPRINT("POWNED DCE going Cheap!! DCX_CACHE!! hDC-> %x \n", pDCE->hDC);
if (!IntGdiSetDCOwnerEx( pDCE->hDC, GDI_OBJ_HMGR_NONE, FALSE))
if (!GreSetDCOwner( pDCE->hDC, GDI_OBJ_HMGR_NONE))
{
DPRINT1("Fail Owner Switch hDC-> %x \n", pDCE->hDC);
break;
@@ -837,7 +839,7 @@ DceResetActiveDCEs(PWND Window)
}
pLE = LEDce.Flink;
pDCE = CONTAINING_RECORD(pLE, DCE, List);
if(!pDCE) return; // Another null test!
do
{
if(!pDCE) break;
@@ -859,7 +861,7 @@ DceResetActiveDCEs(PWND Window)
}
}
if (!GDIOBJ_ValidateHandle(pDCE->hDC, GDI_OBJECT_TYPE_DC) ||
if (!GreIsHandleValid(pDCE->hDC) ||
(dc = DC_LockDc(pDCE->hDC)) == NULL)
{
pLE = pDCE->List.Flink;
+16 -15
View File
@@ -1206,7 +1206,7 @@ co_WinPosSetWindowPos(
{
/* Nothing to copy, clean up */
RGNOBJAPI_Unlock(VisRgn);
REGION_FreeRgnByHandle(CopyRgn);
GreDeleteObject(CopyRgn);
CopyRgn = NULL;
}
else if (OldWindowRect.left != NewWindowRect.left ||
@@ -1299,12 +1299,12 @@ co_WinPosSetWindowPos(
RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
}
}
REGION_FreeRgnByHandle(DirtyRgn);
GreDeleteObject(DirtyRgn);
}
if (CopyRgn != NULL)
{
REGION_FreeRgnByHandle(CopyRgn);
GreDeleteObject(CopyRgn);
}
/* Expose what was covered before but not covered anymore */
@@ -1325,13 +1325,13 @@ co_WinPosSetWindowPos(
{
co_VIS_WindowLayoutChanged(Window, ExposedRgn);
}
REGION_FreeRgnByHandle(ExposedRgn);
REGION_FreeRgnByHandle(VisBefore);
GreDeleteObject(ExposedRgn);
GreDeleteObject(VisBefore);
}
if (VisAfter != NULL)
{
REGION_FreeRgnByHandle(VisAfter);
GreDeleteObject(VisAfter);
}
if (!(WinPos.flags & SWP_NOACTIVATE))
@@ -1421,7 +1421,7 @@ co_WinPosShowWindow(PWND Wnd, INT Cmd)
// HRGN VisibleRgn;
ASSERT_REFS_CO(Wnd);
WasVisible = (Wnd->style & WS_VISIBLE) != 0;
switch (Cmd)
@@ -1640,7 +1640,7 @@ co_WinPosSearchChildren(
UserDereferenceObject(ScopeWin);
return NULL;
}
return ScopeWin;
}
@@ -1698,7 +1698,7 @@ IntDeferWindowPos( HDWP hdwp,
SWP_HIDEWINDOW | SWP_FRAMECHANGED))
{
EngSetLastError(ERROR_INVALID_PARAMETER);
return NULL;
return NULL;
}
if (!(pDWP = (PSMWP)UserGetObject(gHandleTable, hdwp, otSMWP)))
@@ -1756,7 +1756,7 @@ IntDeferWindowPos( HDWP hdwp,
pDWP->acvr[pDWP->ccvr].pos.cx = cx;
pDWP->acvr[pDWP->ccvr].pos.cy = cy;
pDWP->acvr[pDWP->ccvr].pos.flags = flags;
pDWP->acvr[pDWP->ccvr].hrgnClip = NULL;
pDWP->acvr[pDWP->ccvr].hrgnClip = NULL;
pDWP->acvr[pDWP->ccvr].hrgnInterMonitor = NULL;
pDWP->ccvr++;
END:
@@ -1917,7 +1917,7 @@ NtUserDeferWindowPos(HDWP WinPosInfo,
if ( WndInsertAfter &&
WndInsertAfter != HWND_BOTTOM &&
WndInsertAfter != HWND_TOPMOST &&
WndInsertAfter != HWND_TOPMOST &&
WndInsertAfter != HWND_NOTOPMOST )
{
pWndIA = UserGetWindowObject(WndInsertAfter);
@@ -1934,7 +1934,7 @@ NtUserDeferWindowPos(HDWP WinPosInfo,
Exit:
DPRINT("Leave NtUserDeferWindowPos, ret=%i\n", Ret);
UserLeave();
return Ret;
return Ret;
}
/*
@@ -1984,7 +1984,7 @@ NtUserSetWindowPos(
if ( hWndInsertAfter &&
hWndInsertAfter != HWND_BOTTOM &&
hWndInsertAfter != HWND_TOPMOST &&
hWndInsertAfter != HWND_TOPMOST &&
hWndInsertAfter != HWND_NOTOPMOST )
{
pWndIA = UserGetWindowObject(hWndInsertAfter);
@@ -2051,7 +2051,7 @@ NtUserSetWindowRgn(
if (hRgn) // The region will be deleted in user32.
{
if (GDIOBJ_ValidateHandle(hRgn, GDI_OBJECT_TYPE_REGION))
if (GreIsHandleValid(hRgn))
{
hrgnCopy = IntSysCreateRectRgn(0, 0, 0, 0);
@@ -2068,6 +2068,7 @@ NtUserSetWindowRgn(
if (Window->hrgnClip)
{
/* Delete no longer needed region handle */
IntGdiSetRegionOwner(Window->hrgnClip, GDI_OBJ_HMGR_POWNED);
GreDeleteObject(Window->hrgnClip);
}
@@ -2198,7 +2199,7 @@ NtUserShowWindow(HWND hWnd, LONG nCmdShow)
EngSetLastError(ERROR_INVALID_PARAMETER);
RETURN(FALSE);
}
UserRefObjectCo(Window, &Ref);
ret = co_WinPosShowWindow(Window, nCmdShow);
UserDerefObjectCo(Window);
@@ -187,7 +187,7 @@ IntWinStaObjectParse(PWIN32_PARSEMETHOD_PARAMETERS Parameters)
return STATUS_OBJECT_TYPE_MISMATCH;
}
NTSTATUS NTAPI
NTSTATUS NTAPI
IntWinstaOkToClose(PWIN32_OKAYTOCLOSEMETHOD_PARAMETERS Parameters)
{
PPROCESSINFO ppi;
@@ -326,15 +326,15 @@ co_IntInitializeDesktopGraphics(VOID)
IntDestroyPrimarySurface();
return FALSE;
}
IntGdiSetDCOwnerEx(ScreenDeviceContext, GDI_OBJ_HMGR_PUBLIC, FALSE);
GreSetDCOwner(ScreenDeviceContext, GDI_OBJ_HMGR_PUBLIC);
/* Setup the cursor */
co_IntLoadDefaultCursors();
hSystemBM = NtGdiCreateCompatibleDC(ScreenDeviceContext);
NtGdiSelectFont( hSystemBM, NtGdiGetStockObject(SYSTEM_FONT));
IntGdiSetDCOwnerEx( hSystemBM, GDI_OBJ_HMGR_PUBLIC, FALSE);
NtGdiSelectFont(hSystemBM, NtGdiGetStockObject(SYSTEM_FONT));
GreSetDCOwner(hSystemBM, GDI_OBJ_HMGR_PUBLIC);
// FIXME! Move these to a update routine.
gpsi->Planes = NtGdiGetDeviceCaps(ScreenDeviceContext, PLANES);
@@ -353,8 +353,8 @@ IntEndDesktopGraphics(VOID)
{
if (NULL != ScreenDeviceContext)
{ // No need to allocate a new dcattr.
DC_SetOwnership(ScreenDeviceContext, PsGetCurrentProcess());
NtGdiDeleteObjectApp(ScreenDeviceContext);
GreSetDCOwner(ScreenDeviceContext, GDI_OBJ_HMGR_POWNED);
GreDeleteObject(ScreenDeviceContext);
ScreenDeviceContext = NULL;
}
IntHideDesktop(IntGetActiveDesktop());
@@ -438,7 +438,7 @@ NtUserCreateWindowStation(
/*
* No existing window station found, try to create new one
*/
/* Capture window station name */
_SEH2_TRY
{
@@ -64,23 +64,19 @@ NtGdiAlphaBlend(
DPRINT("Locking DCs\n");
ahDC[0] = hDCDest;
ahDC[1] = hDCSrc ;
GDIOBJ_LockMultipleObjs(2, ahDC, apObj);
DCDest = apObj[0];
DCSrc = apObj[1];
if ((NULL == DCDest) || (NULL == DCSrc))
if (!GDIOBJ_bLockMultipleObjects(2, ahDC, apObj, GDIObjType_DC_TYPE))
{
DPRINT1("Invalid dc handle (dest=0x%08x, src=0x%08x) passed to NtGdiAlphaBlend\n", hDCDest, hDCSrc);
EngSetLastError(ERROR_INVALID_HANDLE);
if(DCSrc) GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
if(DCDest) GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
return FALSE;
}
DCDest = apObj[0];
DCSrc = apObj[1];
if (DCDest->dctype == DC_TYPE_INFO || DCDest->dctype == DCTYPE_INFO)
{
GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
GDIOBJ_vUnlockObject(&DCSrc->BaseObject);
GDIOBJ_vUnlockObject(&DCDest->BaseObject);
/* Yes, Windows really returns TRUE in this case */
return TRUE;
}
@@ -112,8 +108,8 @@ NtGdiAlphaBlend(
!SourceRect.right ||
!SourceRect.bottom)
{
GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
GDIOBJ_vUnlockObject(&DCSrc->BaseObject);
GDIOBJ_vUnlockObject(&DCDest->BaseObject);
return TRUE;
}
@@ -153,8 +149,8 @@ NtGdiAlphaBlend(
leave :
DPRINT("Finishing blit\n");
DC_vFinishBlit(DCDest, DCSrc);
GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
GDIOBJ_vUnlockObject(&DCSrc->BaseObject);
GDIOBJ_vUnlockObject(&DCDest->BaseObject);
return bResult;
}
@@ -216,23 +212,19 @@ NtGdiTransparentBlt(
DPRINT("Locking DCs\n");
ahDC[0] = hdcDst;
ahDC[1] = hdcSrc ;
GDIOBJ_LockMultipleObjs(2, ahDC, apObj);
DCDest = apObj[0];
DCSrc = apObj[1];
if ((NULL == DCDest) || (NULL == DCSrc))
if (!GDIOBJ_bLockMultipleObjects(2, ahDC, apObj, GDIObjType_DC_TYPE))
{
DPRINT1("Invalid dc handle (dest=0x%08x, src=0x%08x) passed to NtGdiAlphaBlend\n", hdcDst, hdcSrc);
EngSetLastError(ERROR_INVALID_HANDLE);
if(DCSrc) GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
if(DCDest) GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
return FALSE;
}
DCDest = apObj[0];
DCSrc = apObj[1];
if (DCDest->dctype == DC_TYPE_INFO || DCDest->dctype == DCTYPE_INFO)
{
GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
GDIOBJ_vUnlockObject(&DCSrc->BaseObject);
GDIOBJ_vUnlockObject(&DCDest->BaseObject);
/* Yes, Windows really returns TRUE in this case */
return TRUE;
}
@@ -289,8 +281,8 @@ NtGdiTransparentBlt(
done:
DC_vFinishBlit(DCDest, DCSrc);
GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
GDIOBJ_vUnlockObject(&DCDest->BaseObject);
GDIOBJ_vUnlockObject(&DCSrc->BaseObject);
return Ret;
}
@@ -330,11 +322,16 @@ NtGdiMaskBlt(
UsesMask = ROP_USES_MASK(dwRop);
//DPRINT1("dwRop : 0x%08x\n", dwRop);
if (!hdcDest || (UsesSource && !hdcSrc))
{
EngSetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
/* Take care of mask bitmap */
if(hbmMask)
{
psurfMask = SURFACE_LockSurface(hbmMask);
psurfMask = SURFACE_ShareLockSurface(hbmMask);
if(!psurfMask)
{
EngSetLastError(ERROR_INVALID_HANDLE);
@@ -352,14 +349,14 @@ NtGdiMaskBlt(
if(gajBitsPerFormat[psurfMask->SurfObj.iBitmapFormat] != 1)
{
EngSetLastError(ERROR_INVALID_PARAMETER);
SURFACE_UnlockSurface(psurfMask);
SURFACE_ShareUnlockSurface(psurfMask);
return FALSE;
}
}
else if(psurfMask)
{
DPRINT1("Getting Mask bitmap without needing it?\n");
SURFACE_UnlockSurface(psurfMask);
SURFACE_ShareUnlockSurface(psurfMask);
psurfMask = NULL;
}
MaskPoint.x = xMask;
@@ -368,11 +365,17 @@ NtGdiMaskBlt(
/* Take care of source and destination bitmap */
DPRINT("Locking DCs\n");
ahDC[0] = hdcDest;
ahDC[1] = hdcSrc ;
GDIOBJ_LockMultipleObjs(2, ahDC, apObj);
ahDC[1] = UsesSource ? hdcSrc : NULL;
if (!GDIOBJ_bLockMultipleObjects(2, ahDC, apObj, GDIObjType_DC_TYPE))
{
DPRINT1("Invalid dc handle (dest=0x%08x, src=0x%08x) passed to NtGdiAlphaBlend\n", hdcDest, hdcSrc);
EngSetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
DCDest = apObj[0];
DCSrc = apObj[1];
ASSERT(DCDest);
if (NULL == DCDest)
{
if(DCSrc) DC_UnlockDc(DCSrc);
@@ -390,12 +393,7 @@ NtGdiMaskBlt(
if (UsesSource)
{
if (NULL == DCSrc)
{
DC_UnlockDc(DCDest);
DPRINT("Invalid source dc handle (0x%08x) passed to NtGdiBitBlt\n", hdcSrc);
return FALSE;
}
ASSERT(DCSrc);
if (DCSrc->dctype == DC_TYPE_INFO)
{
DC_UnlockDc(DCDest);
@@ -404,12 +402,6 @@ NtGdiMaskBlt(
return TRUE;
}
}
else if(DCSrc)
{
DPRINT("Getting a valid Source handle without using source!!!\n");
DC_UnlockDc(DCSrc);
DCSrc = NULL ;
}
pdcattr = DCDest->pdcattr;
@@ -490,7 +482,7 @@ cleanup:
DC_UnlockDc(DCSrc);
}
DC_UnlockDc(DCDest);
if(psurfMask) SURFACE_UnlockSurface(psurfMask);
if(psurfMask) SURFACE_ShareUnlockSurface(psurfMask);
return Status;
}
@@ -547,9 +539,12 @@ GreStretchBltMask(
EXLATEOBJ exlo;
XLATEOBJ *XlateObj = NULL;
POINTL BrushOrigin;
BOOL UsesSource = ROP_USES_SOURCE(ROP);
BOOL UsesSource;
BOOL UsesMask;
FIXUP_ROP(ROP);
UsesSource = ROP_USES_SOURCE(ROP);
UsesMask = ROP_USES_MASK(ROP);
if (0 == WidthDest || 0 == HeightDest || 0 == WidthSrc || 0 == HeightSrc)
{
@@ -557,56 +552,45 @@ GreStretchBltMask(
return FALSE;
}
DPRINT("Locking DCs\n");
if (!hDCDest || (UsesSource && !hDCSrc) || (UsesMask && !hDCMask))
{
EngSetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
ahDC[0] = hDCDest;
ahDC[1] = hDCSrc ;
ahDC[2] = hDCMask ;
GDIOBJ_LockMultipleObjs(3, ahDC, apObj);
ahDC[1] = UsesSource ? hDCSrc : NULL;
ahDC[2] = UsesMask ? hDCMask : NULL;
if (!GDIOBJ_bLockMultipleObjects(3, ahDC, apObj, GDIObjType_DC_TYPE))
{
DPRINT1("Invalid dc handle (dest=0x%08x, src=0x%08x) passed to NtGdiAlphaBlend\n", hDCDest, hDCSrc);
EngSetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
DCDest = apObj[0];
DCSrc = apObj[1];
DCMask = apObj[2];
if (NULL == DCDest)
{
if(DCSrc) GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
if(DCMask) GDIOBJ_UnlockObjByPtr(&DCMask->BaseObject);
DPRINT("Invalid destination dc handle (0x%08x) passed to NtGdiBitBlt\n", hDCDest);
return FALSE;
}
if (DCDest->dctype == DC_TYPE_INFO)
{
if(DCSrc) GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
if(DCMask) GDIOBJ_UnlockObjByPtr(&DCMask->BaseObject);
GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
if(DCSrc) GDIOBJ_vUnlockObject(&DCSrc->BaseObject);
if(DCMask) GDIOBJ_vUnlockObject(&DCMask->BaseObject);
GDIOBJ_vUnlockObject(&DCDest->BaseObject);
/* Yes, Windows really returns TRUE in this case */
return TRUE;
}
if (UsesSource)
{
if (NULL == DCSrc)
{
GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
if(DCMask) GDIOBJ_UnlockObjByPtr(&DCMask->BaseObject);
DPRINT("Invalid source dc handle (0x%08x) passed to NtGdiBitBlt\n", hDCSrc);
return FALSE;
}
if (DCSrc->dctype == DC_TYPE_INFO)
{
GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
if(DCMask) GDIOBJ_UnlockObjByPtr(&DCMask->BaseObject);
GDIOBJ_vUnlockObject(&DCDest->BaseObject);
GDIOBJ_vUnlockObject(&DCSrc->BaseObject);
if(DCMask) GDIOBJ_vUnlockObject(&DCMask->BaseObject);
/* Yes, Windows really returns TRUE in this case */
return TRUE;
}
}
else if(DCSrc)
{
DPRINT1("Getting a valid Source handle without using source!!!\n");
GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
DCSrc = NULL ;
}
pdcattr = DCDest->pdcattr;
@@ -867,7 +851,7 @@ IntGdiPolyPatBlt(
for (i = 0; i < cRects; i++)
{
pbrush = BRUSH_LockBrush(pRects->hBrush);
pbrush = BRUSH_ShareLockBrush(pRects->hBrush);
if(pbrush != NULL)
{
IntPatBlt(
@@ -878,7 +862,7 @@ IntGdiPolyPatBlt(
pRects->r.bottom,
dwRop,
pbrush);
BRUSH_UnlockBrush(pbrush);
BRUSH_ShareUnlockBrush(pbrush);
}
pRects++;
}
@@ -928,7 +912,7 @@ NtGdiPatBlt(
if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
DC_vUpdateFillBrush(dc);
pbrush = BRUSH_LockBrush(pdcattr->hbrush);
pbrush = BRUSH_ShareLockBrush(pdcattr->hbrush);
if (pbrush == NULL)
{
EngSetLastError(ERROR_INVALID_HANDLE);
@@ -938,7 +922,7 @@ NtGdiPatBlt(
ret = IntPatBlt(dc, XLeft, YLeft, Width, Height, ROP, pbrush);
BRUSH_UnlockBrush(pbrush);
BRUSH_ShareUnlockBrush(pbrush);
DC_UnlockDc(dc);
return ret;
@@ -114,7 +114,7 @@ GreCreateBitmapEx(
if (!pvBits)
{
EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
SURFACE_FreeSurfaceByHandle(hbmp);
GDIOBJ_vDeleteObject(&psurf->BaseObject);
return NULL;
}
DecompressBitmap(sizl, pvCompressedBits, pvBits, lDelta, iFormat);
@@ -133,7 +133,7 @@ GreCreateBitmapEx(
/* Bail out if that failed */
DPRINT1("SURFACE_bSetBitmapBits failed.\n");
EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
SURFACE_FreeSurfaceByHandle(hbmp);
GDIOBJ_vDeleteObject(&psurf->BaseObject);
return NULL;
}
@@ -209,8 +209,7 @@ NtGdiCreateBitmap(
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
SURFACE_UnlockSurface(psurf);
SURFACE_FreeSurfaceByHandle(hbmp);
GDIOBJ_vDeleteObject(&psurf->BaseObject);
_SEH2_YIELD(return NULL;)
}
_SEH2_END
@@ -274,7 +273,7 @@ IntCreateCompatibleBitmap(
ASSERT(psurfBmp);
/* Assign palette */
psurfBmp->ppal = psurf->ppal;
GDIOBJ_IncrementShareCount((POBJ)psurf->ppal);
GDIOBJ_vReferenceObjectByPointer((POBJ)psurf->ppal);
/* Set flags */
psurfBmp->flags = API_BITMAP;
psurfBmp->hdc = NULL; // Fixme
@@ -316,7 +315,7 @@ IntCreateCompatibleBitmap(
return 0;
}
PalGDI = PALETTE_ShareLockPalette(psurf->ppal->BaseObject.hHmgr);
PalGDI = psurf->ppal;
for (Index = 0;
Index < 256 && Index < PalGDI->NumColors;
@@ -327,7 +326,6 @@ IntCreateCompatibleBitmap(
bi->bmiColors[Index].rgbBlue = PalGDI->IndexedColors[Index].peBlue;
bi->bmiColors[Index].rgbReserved = 0;
}
PALETTE_ShareUnlockPalette(PalGDI);
}
Bmp = DIB_CreateDIBSection(Dc,
@@ -873,8 +871,8 @@ BITMAP_CopyBitmap(HBITMAP hBitmap)
if (resBitmap)
{
IntSetBitmapBits(resBitmap, Bitmap->SurfObj.cjBits, Bitmap->SurfObj.pvBits);
GDIOBJ_IncrementShareCount(&Bitmap->ppal->BaseObject);
GDIOBJ_ShareUnlockObjByPtr(&resBitmap->ppal->BaseObject);
GDIOBJ_vReferenceObjectByPointer(&Bitmap->ppal->BaseObject);
GDIOBJ_vDereferenceObject(&resBitmap->ppal->BaseObject);
resBitmap->ppal = Bitmap->ppal;
SURFACE_ShareUnlockSurface(resBitmap);
}
+75 -169
View File
@@ -35,180 +35,80 @@ static const ULONG HatchBrushes[NB_HATCH_STYLES][8] =
{0x7E, 0xBD, 0xDB, 0xE7, 0xE7, 0xDB, 0xBD, 0x7E} /* HS_DIAGCROSS */
};
PVOID
BOOL
FASTCALL
AllocateObjectAttr(VOID)
IntGdiSetBrushOwner(PBRUSH pbr, ULONG ulOwner)
{
PTHREADINFO pti;
PPROCESSINFO ppi;
PVOID pAttr;
PGDI_OBJ_ATTR_FREELIST pGdiObjAttrFreeList;
PGDI_OBJ_ATTR_ENTRY pGdiObjAttrEntry;
int i;
// FIXME:
if (pbr->flAttrs & GDIBRUSH_IS_GLOBAL) return TRUE;
pti = PsGetCurrentThreadWin32Thread();
if (pti->pgdiBrushAttr)
{
pAttr = pti->pgdiBrushAttr; // Get the free one.
pti->pgdiBrushAttr = NULL;
return pAttr;
}
if ((ulOwner == GDI_OBJ_HMGR_PUBLIC) || ulOwner == GDI_OBJ_HMGR_NONE)
{
// Deny user access to User Data.
GDIOBJ_vSetObjectAttr(&pbr->BaseObject, NULL);
// FIXME: deallocate brush attr
}
ppi = PsGetCurrentProcessWin32Process();
if (ulOwner == GDI_OBJ_HMGR_POWNED)
{
// Allow user access to User Data.
GDIOBJ_vSetObjectAttr(&pbr->BaseObject, pbr->pBrushAttr);
// FIXME: allocate brush attr
}
if (!ppi->pBrushAttrList) // If set point is null, allocate new group.
{
pGdiObjAttrEntry = EngAllocUserMem(sizeof(GDI_OBJ_ATTR_ENTRY), 0);
GDIOBJ_vSetObjectOwner(&pbr->BaseObject, ulOwner);
if (!pGdiObjAttrEntry)
{
DPRINT1("Attr Failed User Allocation!\n");
return NULL;
}
DPRINT("AllocObjectAttr User 0x%x\n",pGdiObjAttrEntry);
pGdiObjAttrFreeList = ExAllocatePoolWithTag( PagedPool,
sizeof(GDI_OBJ_ATTR_FREELIST),
GDITAG_BRUSH_FREELIST);
if ( !pGdiObjAttrFreeList )
{
EngFreeUserMem(pGdiObjAttrEntry);
return NULL;
}
RtlZeroMemory(pGdiObjAttrFreeList, sizeof(GDI_OBJ_ATTR_FREELIST));
DPRINT("AllocObjectAttr Ex 0x%x\n",pGdiObjAttrFreeList);
InsertHeadList( &ppi->GDIBrushAttrFreeList, &pGdiObjAttrFreeList->Entry);
pGdiObjAttrFreeList->nEntries = GDIOBJATTRFREE;
// Start at the bottom up and set end of free list point.
ppi->pBrushAttrList = &pGdiObjAttrEntry->Attr[GDIOBJATTRFREE-1];
// Build the free attr list.
for ( i = 0; i < GDIOBJATTRFREE; i++)
{
pGdiObjAttrFreeList->AttrList[i] = &pGdiObjAttrEntry->Attr[i];
}
}
pAttr = ppi->pBrushAttrList;
pGdiObjAttrFreeList = (PGDI_OBJ_ATTR_FREELIST)ppi->GDIBrushAttrFreeList.Flink;
// Free the list when it is full!
if ( pGdiObjAttrFreeList->nEntries-- == 1)
{ // No more free entries, so yank the list.
RemoveEntryList( &pGdiObjAttrFreeList->Entry );
ExFreePoolWithTag( pGdiObjAttrFreeList, GDITAG_BRUSH_FREELIST );
if ( IsListEmpty( &ppi->GDIBrushAttrFreeList ) )
{
ppi->pBrushAttrList = NULL;
return pAttr;
}
pGdiObjAttrFreeList = (PGDI_OBJ_ATTR_FREELIST)ppi->GDIBrushAttrFreeList.Flink;
}
ppi->pBrushAttrList = pGdiObjAttrFreeList->AttrList[pGdiObjAttrFreeList->nEntries-1];
return pAttr;
}
VOID
FASTCALL
FreeObjectAttr(PVOID pAttr)
{
PTHREADINFO pti;
PPROCESSINFO ppi;
PGDI_OBJ_ATTR_FREELIST pGdiObjAttrFreeList;
pti = PsGetCurrentThreadWin32Thread();
if (!pti) return;
if (!pti->pgdiBrushAttr)
{ // If it is null, just cache it for the next time.
pti->pgdiBrushAttr = pAttr;
return;
}
ppi = PsGetCurrentProcessWin32Process();
pGdiObjAttrFreeList = (PGDI_OBJ_ATTR_FREELIST)ppi->GDIBrushAttrFreeList.Flink;
// We add to the list of free entries, so this will grows!
if ( IsListEmpty(&ppi->GDIBrushAttrFreeList) ||
pGdiObjAttrFreeList->nEntries == GDIOBJATTRFREE )
{
pGdiObjAttrFreeList = ExAllocatePoolWithTag( PagedPool,
sizeof(GDI_OBJ_ATTR_FREELIST),
GDITAG_BRUSH_FREELIST);
if ( !pGdiObjAttrFreeList )
{
return;
}
InsertHeadList( &ppi->GDIBrushAttrFreeList, &pGdiObjAttrFreeList->Entry);
pGdiObjAttrFreeList->nEntries = 0;
}
// Up count, save the entry and set end of free list point.
++pGdiObjAttrFreeList->nEntries; // Top Down...
pGdiObjAttrFreeList->AttrList[pGdiObjAttrFreeList->nEntries-1] = pAttr;
ppi->pBrushAttrList = pAttr;
return;
return TRUE;
}
BOOL
FASTCALL
IntGdiSetBrushOwner(PBRUSH pbr, DWORD OwnerMask)
NTAPI
BRUSH_bAllocBrushAttr(PBRUSH pbr)
{
HBRUSH hBR;
PEPROCESS Owner = NULL;
PGDI_TABLE_ENTRY pEntry = NULL;
PPROCESSINFO ppi;
BRUSH_ATTR *pBrushAttr;
if (!pbr) return FALSE;
ppi = PsGetCurrentProcessWin32Process();
ASSERT(ppi);
hBR = pbr->BaseObject.hHmgr;
if (!hBR || (GDI_HANDLE_GET_TYPE(hBR) != GDI_OBJECT_TYPE_BRUSH))
return FALSE;
else
{
INT Index = GDI_HANDLE_GET_INDEX((HGDIOBJ)hBR);
pEntry = &GdiHandleTable->Entries[Index];
}
if (pbr->flAttrs & GDIBRUSH_IS_GLOBAL)
{
GDIOBJ_ShareUnlockObjByPtr((POBJ)pbr);
return TRUE;
}
if ((OwnerMask == GDI_OBJ_HMGR_PUBLIC) || OwnerMask == GDI_OBJ_HMGR_NONE)
{
// Set this Brush to inaccessible mode and to an Owner of NONE.
// if (OwnerMask == GDI_OBJ_HMGR_NONE) Owner = OwnerMask;
if (!GDIOBJ_SetOwnership((HGDIOBJ) hBR, Owner))
pBrushAttr = GdiPoolAllocate(ppi->pPoolDcAttr);
if (!pBrushAttr)
{
DPRINT1("Could not allocate brush attr\n");
return FALSE;
}
// Deny user access to User Data.
pEntry->UserData = NULL; // This hBR is inaccessible!
}
/* Copy the content from the kernel mode dc attr */
pbr->pBrushAttr = pBrushAttr;
*pbr->pBrushAttr = pbr->BrushAttr;
if (OwnerMask == GDI_OBJ_HMGR_POWNED)
{
if (!GDIOBJ_SetOwnership((HGDIOBJ) hBR, PsGetCurrentProcess() ))
return FALSE;
/* Set the object attribute in the handle table */
GDIOBJ_vSetObjectAttr(&pbr->BaseObject, pBrushAttr);
// Allow user access to User Data.
pEntry->UserData = pbr->pBrushAttr;
}
return TRUE;
DPRINT("BRUSH_bAllocBrushAttr: pbr=%p, pbr->pdcattr=%p\n", pbr, pbr->pBrushAttr);
return TRUE;
}
VOID
NTAPI
BRUSH_vFreeBrushAttr(PBRUSH pbr)
{
#if 0
PPROCESSINFO ppi;
if (pbrush->pBrushAttr == &pbrush->BrushAttr) return;
/* Reset the object attribute in the handle table */
GDIOBJ_vSetObjectAttr(&pbr->BaseObject, NULL);
/* Free memory from the process gdi pool */
ppi = PsGetCurrentProcessWin32Process();
ASSERT(ppi);
GdiPoolFree(ppi->pPoolBrushAttr, pbr->pBrushAttr);
#endif
/* Reset to kmode brush attribute */
pbr->pBrushAttr = &pbr->BrushAttr;
}
BOOL
@@ -219,10 +119,16 @@ BRUSH_Cleanup(PVOID ObjectBody)
if (pbrush->flAttrs & (GDIBRUSH_IS_HATCH | GDIBRUSH_IS_BITMAP))
{
ASSERT(pbrush->hbmPattern);
GDIOBJ_SetOwnership(pbrush->hbmPattern, PsGetCurrentProcess());
GreSetObjectOwner(pbrush->hbmPattern, GDI_OBJ_HMGR_POWNED);
GreDeleteObject(pbrush->hbmPattern);
}
/* Check if there is a usermode attribute */
if (pbrush->pBrushAttr != &pbrush->BrushAttr)
{
BRUSH_vFreeBrushAttr(pbrush);
}
/* Free the kmode styles array of EXTPENS */
if (pbrush->pStyle)
{
@@ -339,9 +245,9 @@ IntGdiCreateDIBBrush(
pbrush->hbmPattern = hPattern;
/* FIXME: Fill in the rest of fields!!! */
GDIOBJ_SetOwnership(hPattern, NULL);
GreSetObjectOwner(hPattern, GDI_OBJ_HMGR_PUBLIC);
BRUSH_UnlockBrush(pbrush);
GDIOBJ_vUnlockObject(&pbrush->BaseObject);
return hBrush;
}
@@ -381,9 +287,9 @@ IntGdiCreateHatchBrush(
pbrush->hbmPattern = hPattern;
pbrush->BrushAttr.lbColor = Color & 0xFFFFFF;
GDIOBJ_SetOwnership(hPattern, NULL);
GreSetObjectOwner(hPattern, GDI_OBJ_HMGR_PUBLIC);
BRUSH_UnlockBrush(pbrush);
GDIOBJ_vUnlockObject(&pbrush->BaseObject);
return hBrush;
}
@@ -417,9 +323,9 @@ IntGdiCreatePatternBrush(
pbrush->hbmPattern = hPattern;
/* FIXME: Fill in the rest of fields!!! */
GDIOBJ_SetOwnership(hPattern, NULL);
GreSetObjectOwner(hPattern, GDI_OBJ_HMGR_PUBLIC);
BRUSH_UnlockBrush(pbrush);
GDIOBJ_vUnlockObject(&pbrush->BaseObject);
return hBrush;
}
@@ -445,7 +351,7 @@ IntGdiCreateSolidBrush(
pbrush->BrushAttr.lbColor = Color & 0x00FFFFFF;
/* FIXME: Fill in the rest of fields!!! */
BRUSH_UnlockBrush(pbrush);
GDIOBJ_vUnlockObject(&pbrush->BaseObject);
return hBrush;
}
@@ -466,7 +372,7 @@ IntGdiCreateNullBrush(VOID)
hBrush = pbrush->BaseObject.hHmgr;
pbrush->flAttrs |= GDIBRUSH_IS_NULL;
BRUSH_UnlockBrush(pbrush);
GDIOBJ_vUnlockObject(&pbrush->BaseObject);
return hBrush;
}
@@ -477,12 +383,12 @@ IntGdiSetSolidBrushColor(HBRUSH hBrush, COLORREF Color)
{
PBRUSH pbrush;
pbrush = BRUSH_LockBrush(hBrush);
pbrush = BRUSH_ShareLockBrush(hBrush);
if (pbrush->flAttrs & GDIBRUSH_IS_SOLID)
{
pbrush->BrushAttr.lbColor = Color & 0xFFFFFF;
}
BRUSH_UnlockBrush(pbrush);
BRUSH_ShareUnlockBrush(pbrush);
}
@@ -27,6 +27,7 @@ CLIPPING_UpdateGCRegion(DC* Dc)
{
PROSRGNDATA CombinedRegion;
HRGN hRgnVis;
PREGION prgnClip, prgnGCClip;
// would prefer this, but the rest of the code sucks
// ASSERT(Dc->rosdc.hGCClipRgn);
@@ -37,10 +38,18 @@ CLIPPING_UpdateGCRegion(DC* Dc)
if (Dc->rosdc.hGCClipRgn == NULL)
Dc->rosdc.hGCClipRgn = IntSysCreateRectRgn(0, 0, 0, 0);
prgnGCClip = REGION_LockRgn(Dc->rosdc.hGCClipRgn);
ASSERT(prgnGCClip);
if (Dc->rosdc.hClipRgn == NULL)
NtGdiCombineRgn(Dc->rosdc.hGCClipRgn, hRgnVis, 0, RGN_COPY);
IntGdiCombineRgn(prgnGCClip, Dc->prgnVis, NULL, RGN_COPY);
else
NtGdiCombineRgn(Dc->rosdc.hGCClipRgn, Dc->rosdc.hClipRgn, hRgnVis, RGN_AND);
{
prgnClip = REGION_LockRgn(Dc->rosdc.hClipRgn); // FIXME: locking order, ugh
IntGdiCombineRgn(prgnGCClip, Dc->prgnVis, prgnClip, RGN_AND);
REGION_UnlockRgn(prgnClip);
}
REGION_UnlockRgn(prgnGCClip);
NtGdiOffsetRgn(Dc->rosdc.hGCClipRgn, Dc->ptlDCOrig.x, Dc->ptlDCOrig.y);
@@ -74,6 +83,7 @@ GdiSelectVisRgn(HDC hdc, HRGN hrgn)
{
int retval;
DC *dc;
PREGION prgn;
if (!hrgn)
{
@@ -90,10 +100,12 @@ GdiSelectVisRgn(HDC hdc, HRGN hrgn)
ASSERT (dc->prgnVis != NULL);
retval = NtGdiCombineRgn(dc->prgnVis->BaseObject.hHmgr, hrgn, 0, RGN_COPY);
prgn = RGNOBJAPI_Lock(hrgn, NULL);
retval = prgn ? IntGdiCombineRgn(dc->prgnVis, prgn, NULL, RGN_COPY) : ERROR;
RGNOBJAPI_Unlock(prgn);
if ( retval != ERROR )
{
NtGdiOffsetRgn(dc->prgnVis->BaseObject.hHmgr, -dc->ptlDCOrig.x, -dc->ptlDCOrig.y);
IntGdiOffsetRgn(dc->prgnVis, -dc->ptlDCOrig.x, -dc->ptlDCOrig.y);
CLIPPING_UpdateGCRegion(dc);
}
DC_UnlockDc(dc);
@@ -114,7 +126,7 @@ int FASTCALL GdiExtSelectClipRgn(PDC dc,
{
if (dc->rosdc.hClipRgn != NULL)
{
REGION_FreeRgnByHandle(dc->rosdc.hClipRgn);
GreDeleteObject(dc->rosdc.hClipRgn);
dc->rosdc.hClipRgn = NULL;
}
}
@@ -213,7 +225,7 @@ GdiGetClipBox(HDC hDC, PRECTL rc)
retval = REGION_GetRgnBox(pRgnNew, rc);
REGION_FreeRgnByHandle(pRgnNew->BaseObject.hHmgr);
REGION_Delete(pRgnNew);
DC_UnlockDc(dc);
if(Unlock) REGION_UnlockRgn(pRgn);
@@ -266,7 +278,7 @@ int APIENTRY NtGdiExcludeClipRect(HDC hDC,
{
INT Result;
RECTL Rect;
HRGN NewRgn;
PREGION prgnNew, prgnClip;
PDC dc = DC_LockDc(hDC);
if (!dc)
@@ -282,8 +294,8 @@ int APIENTRY NtGdiExcludeClipRect(HDC hDC,
IntLPtoDP(dc, (LPPOINT)&Rect, 2);
NewRgn = IntSysCreateRectRgnIndirect(&Rect);
if (!NewRgn)
prgnNew = IntSysCreateRectpRgnIndirect(&Rect);
if (!prgnNew)
{
Result = ERROR;
}
@@ -292,14 +304,18 @@ int APIENTRY NtGdiExcludeClipRect(HDC hDC,
if (!dc->rosdc.hClipRgn)
{
dc->rosdc.hClipRgn = IntSysCreateRectRgn(0, 0, 0, 0);
NtGdiCombineRgn(dc->rosdc.hClipRgn, dc->prgnVis->BaseObject.hHmgr, NewRgn, RGN_DIFF);
prgnClip = REGION_LockRgn(dc->rosdc.hClipRgn);
IntGdiCombineRgn(prgnClip, dc->prgnVis, prgnNew, RGN_DIFF);
REGION_UnlockRgn(prgnClip);
Result = SIMPLEREGION;
}
else
{
Result = NtGdiCombineRgn(dc->rosdc.hClipRgn, dc->rosdc.hClipRgn, NewRgn, RGN_DIFF);
prgnClip = REGION_LockRgn(dc->rosdc.hClipRgn);
Result = IntGdiCombineRgn(prgnClip, prgnClip, prgnNew, RGN_DIFF);
REGION_UnlockRgn(prgnClip);
}
REGION_FreeRgnByHandle(NewRgn);
REGION_Delete(prgnNew);
}
if (Result != ERROR)
CLIPPING_UpdateGCRegion(dc);
@@ -349,7 +365,7 @@ int APIENTRY NtGdiIntersectClipRect(HDC hDC,
else
{
Result = NtGdiCombineRgn(dc->rosdc.hClipRgn, dc->rosdc.hClipRgn, NewRgn, RGN_AND);
REGION_FreeRgnByHandle(NewRgn);
GreDeleteObject(NewRgn);
}
if (Result != ERROR)
CLIPPING_UpdateGCRegion(dc);
@@ -476,13 +492,13 @@ IntGdiSetMetaRgn(PDC pDC)
RGN_AND);
if ( Ret )
{
GDIOBJ_ShareUnlockObjByPtr(&pDC->dclevel.prgnMeta->BaseObject);
GDIOBJ_vDereferenceObject(&pDC->dclevel.prgnMeta->BaseObject);
if (!((PROSRGNDATA)pDC->dclevel.prgnMeta)->BaseObject.ulShareCount)
REGION_Delete(pDC->dclevel.prgnMeta);
pDC->dclevel.prgnMeta = TempRgn;
GDIOBJ_ShareUnlockObjByPtr(&pDC->dclevel.prgnClip->BaseObject);
GDIOBJ_vDereferenceObject(&pDC->dclevel.prgnClip->BaseObject);
if (!((PROSRGNDATA)pDC->dclevel.prgnClip)->BaseObject.ulShareCount)
REGION_Delete(pDC->dclevel.prgnClip);
+32 -237
View File
@@ -1,4 +1,4 @@
/*
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PURPOSE: Functions for creation and destruction of DCs
@@ -26,188 +26,39 @@ typedef struct _GDI_DC_ATTR_ENTRY
} GDI_DC_ATTR_ENTRY, *PGDI_DC_ATTR_ENTRY;
PDC_ATTR
FASTCALL
AllocateDcAttr(VOID)
{
PTHREADINFO pti;
PPROCESSINFO ppi;
PDC_ATTR pDc_Attr;
PGDI_DC_ATTR_FREELIST pGdiDcAttrFreeList;
PGDI_DC_ATTR_ENTRY pGdiDcAttrEntry;
int i;
pti = PsGetCurrentThreadWin32Thread();
if (pti->pgdiDcattr)
{
pDc_Attr = pti->pgdiDcattr; // Get the free one.
pti->pgdiDcattr = NULL;
return pDc_Attr;
}
ppi = PsGetCurrentProcessWin32Process();
if (!ppi->pDCAttrList) // If set point is null, allocate new group.
{
pGdiDcAttrEntry = EngAllocUserMem(sizeof(GDI_DC_ATTR_ENTRY), 0);
if (!pGdiDcAttrEntry)
{
DPRINT1("DcAttr Failed User Allocation!\n");
return NULL;
}
DPRINT("AllocDcAttr User 0x%x\n",pGdiDcAttrEntry);
pGdiDcAttrFreeList = ExAllocatePoolWithTag( PagedPool,
sizeof(GDI_DC_ATTR_FREELIST),
GDITAG_DC_FREELIST);
if ( !pGdiDcAttrFreeList )
{
EngFreeUserMem(pGdiDcAttrEntry);
return NULL;
}
RtlZeroMemory(pGdiDcAttrFreeList, sizeof(GDI_DC_ATTR_FREELIST));
DPRINT("AllocDcAttr Ex 0x%x\n",pGdiDcAttrFreeList);
InsertHeadList( &ppi->GDIDcAttrFreeList, &pGdiDcAttrFreeList->Entry);
pGdiDcAttrFreeList->nEntries = GDIDCATTRFREE;
// Start at the bottom up and set end of free list point.
ppi->pDCAttrList = &pGdiDcAttrEntry->Attr[GDIDCATTRFREE-1];
// Build the free attr list.
for ( i = 0; i < GDIDCATTRFREE; i++)
{
pGdiDcAttrFreeList->AttrList[i] = &pGdiDcAttrEntry->Attr[i];
}
}
pDc_Attr = ppi->pDCAttrList;
pGdiDcAttrFreeList = (PGDI_DC_ATTR_FREELIST)ppi->GDIDcAttrFreeList.Flink;
// Free the list when it is full!
if ( pGdiDcAttrFreeList->nEntries-- == 1)
{ // No more free entries, so yank the list.
RemoveEntryList( &pGdiDcAttrFreeList->Entry );
ExFreePoolWithTag( pGdiDcAttrFreeList, GDITAG_DC_FREELIST );
if ( IsListEmpty( &ppi->GDIDcAttrFreeList ) )
{
ppi->pDCAttrList = NULL;
return pDc_Attr;
}
pGdiDcAttrFreeList = (PGDI_DC_ATTR_FREELIST)ppi->GDIDcAttrFreeList.Flink;
}
ppi->pDCAttrList = pGdiDcAttrFreeList->AttrList[pGdiDcAttrFreeList->nEntries-1];
return pDc_Attr;
}
VOID
FASTCALL
FreeDcAttr(PDC_ATTR pDc_Attr)
{
PTHREADINFO pti;
PPROCESSINFO ppi;
PGDI_DC_ATTR_FREELIST pGdiDcAttrFreeList;
pti = PsGetCurrentThreadWin32Thread();
if (!pti) return;
if (!pti->pgdiDcattr)
{ // If it is null, just cache it for the next time.
pti->pgdiDcattr = pDc_Attr;
return;
}
ppi = PsGetCurrentProcessWin32Process();
pGdiDcAttrFreeList = (PGDI_DC_ATTR_FREELIST)ppi->GDIDcAttrFreeList.Flink;
// We add to the list of free entries, so this will grows!
if ( IsListEmpty(&ppi->GDIDcAttrFreeList) ||
pGdiDcAttrFreeList->nEntries == GDIDCATTRFREE )
{
pGdiDcAttrFreeList = ExAllocatePoolWithTag( PagedPool,
sizeof(GDI_DC_ATTR_FREELIST),
GDITAG_DC_FREELIST);
if ( !pGdiDcAttrFreeList )
{
return;
}
InsertHeadList( &ppi->GDIDcAttrFreeList, &pGdiDcAttrFreeList->Entry);
pGdiDcAttrFreeList->nEntries = 0;
}
// Up count, save the entry and set end of free list point.
++pGdiDcAttrFreeList->nEntries; // Top Down...
pGdiDcAttrFreeList->AttrList[pGdiDcAttrFreeList->nEntries-1] = pDc_Attr;
ppi->pDCAttrList = pDc_Attr;
return;
}
BOOL
FASTCALL
DC_AllocDcAttr(PDC pdc)
NTAPI
DC_bAllocDcAttr(PDC pdc)
{
DC_AllocateDcAttr(pdc->BaseObject.hHmgr);
PPROCESSINFO ppi;
PDC_ATTR pdcattr;
ppi = PsGetCurrentProcessWin32Process();
ASSERT(ppi);
pdcattr = GdiPoolAllocate(ppi->pPoolDcAttr);
if (!pdcattr)
{
DPRINT1("Could not allocate DC attr\n");
return FALSE;
}
/* Copy the content from the kernel mode dc attr */
pdc->pdcattr = pdcattr;
*pdc->pdcattr = pdc->dcattr;
/* Set the object attribute in the handle table */
GDIOBJ_vSetObjectAttr(&pdc->BaseObject, pdcattr);
DPRINT("DC_AllocDcAttr: pdc=%p, pdc->pdcattr=%p\n", pdc, pdc->pdcattr);
return TRUE;
}
// CHECK against current head
VOID
FASTCALL
DC_AllocateDcAttr(HDC hDC)
{
PVOID NewMem = NULL;
PDC pDC;
HANDLE Pid = NtCurrentProcess();
ULONG MemSize = sizeof(DC_ATTR); //PAGE_SIZE it will allocate that size
NTSTATUS Status = ZwAllocateVirtualMemory(Pid,
&NewMem,
0,
&MemSize,
MEM_COMMIT|MEM_RESERVE,
PAGE_READWRITE);
{
INT Index = GDI_HANDLE_GET_INDEX((HGDIOBJ)hDC);
PGDI_TABLE_ENTRY Entry = &GdiHandleTable->Entries[Index];
// FIXME: dc could have been deleted!!! use GDIOBJ_InsertUserData
if (NT_SUCCESS(Status))
{
RtlZeroMemory(NewMem, MemSize);
Entry->UserData = NewMem;
DPRINT("DC_ATTR allocated! 0x%x\n",NewMem);
}
else
{
DPRINT("DC_ATTR not allocated!\n");
}
}
pDC = DC_LockDc(hDC);
ASSERT(pDC->pdcattr == &pDC->dcattr);
if(NewMem)
{
pDC->pdcattr = NewMem; // Store pointer
}
DC_UnlockDc(pDC);
}
VOID
NTAPI
DC_vFreeDcAttr(PDC pdc)
{
HANDLE Pid = NtCurrentProcess();
INT Index;
PGDI_TABLE_ENTRY pent;
PPROCESSINFO ppi;
if (pdc->pdcattr == &pdc->dcattr)
{
@@ -215,69 +66,13 @@ DC_vFreeDcAttr(PDC pdc)
return;
}
/* Reset the object attribute in the handle table */
GDIOBJ_vSetObjectAttr(&pdc->BaseObject, NULL);
ppi = PsGetCurrentProcessWin32Process();
ASSERT(ppi);
GdiPoolFree(ppi->pPoolDcAttr, pdc->pdcattr);
/* Reset to kmode dcattr */
pdc->pdcattr = &pdc->dcattr;
Index = GDI_HANDLE_GET_INDEX(pdc->BaseObject.hHmgr);
pent = &GdiHandleTable->Entries[Index];
if(pent->UserData)
{
ULONG MemSize = sizeof(DC_ATTR);
NTSTATUS Status = ZwFreeVirtualMemory(Pid,
&pent->UserData,
&MemSize,
MEM_RELEASE);
if (!NT_SUCCESS(Status))
{
DPRINT1("DC_FreeDC failed to free DC_ATTR 0x%p\n", pent->UserData);
ASSERT(FALSE);
}
pent->UserData = NULL;
}
}
static
VOID
CopytoUserDcAttr(PDC dc, PDC_ATTR pdcattr)
{
dc->dcattr.mxWorldToDevice = dc->dclevel.mxWorldToDevice;
dc->dcattr.mxDeviceToWorld = dc->dclevel.mxDeviceToWorld;
dc->dcattr.mxWorldToPage = dc->dclevel.mxWorldToPage;
_SEH2_TRY
{
ProbeForWrite(pdcattr, sizeof(DC_ATTR), 1);
RtlCopyMemory(pdcattr, &dc->dcattr, sizeof(DC_ATTR));
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
ASSERT(FALSE);
}
_SEH2_END;
}
// FIXME: wtf? 2 functions, where one has a typo in the name????
BOOL
FASTCALL
DCU_SyncDcAttrtoUser(PDC dc)
{
PDC_ATTR pdcattr = dc->pdcattr;
if (pdcattr == &dc->dcattr) return TRUE; // No need to copy self.
ASSERT(pdcattr);
CopytoUserDcAttr( dc, pdcattr);
return TRUE;
}
// LOL! DCU_ Sync hDc Attr to User,,, need it speeled out for you?
BOOL
FASTCALL
DCU_SynchDcAttrtoUser(HDC hDC)
{
BOOL Ret;
PDC pDC = DC_LockDc ( hDC );
if (!pDC) return FALSE;
Ret = DCU_SyncDcAttrtoUser(pDC);
DC_UnlockDc( pDC );
return Ret;
}
+81 -116
View File
@@ -80,7 +80,22 @@ NTAPI
DC_AllocDcWithHandle()
{
PDC pdc;
pdc = (PDC)GDIOBJ_AllocObjWithHandle(GDILoObjType_LO_DC_TYPE);
pdc = (PDC)GDIOBJ_AllocateObject(GDIObjType_DC_TYPE,
sizeof(DC),
BASEFLAG_LOOKASIDE);
if (!pdc)
{
DPRINT1("Could not allocate a DC.\n");
return NULL;
}
if (!GDIOBJ_hInsertObject(&pdc->BaseObject, GDI_OBJ_HMGR_POWNED))
{
DPRINT1("Could not insert DC into handle table.\n");
GDIOBJ_vFreeObject(&pdc->BaseObject);
return NULL;
}
pdc->pdcattr = &pdc->dcattr;
@@ -232,7 +247,6 @@ DC_vInitDc(
/* Allocate a Vis region */
pdc->prgnVis = IntSysCreateRectpRgn(0, 0, pdc->dclevel.sizl.cx, pdc->dclevel.sizl.cy);
ASSERT(pdc->prgnVis);
GDIOBJ_CopyOwnership(pdc->BaseObject.hHmgr, pdc->prgnVis->BaseObject.hHmgr);
/* Setup palette */
pdc->dclevel.hpal = StockObjects[DEFAULT_PALETTE];
@@ -357,9 +371,13 @@ DC_Cleanup(PVOID ObjectBody)
if (pdc->rosdc.hClipRgn)
GreDeleteObject(pdc->rosdc.hClipRgn);
if (pdc->prgnVis)
REGION_FreeRgnByHandle(pdc->prgnVis->BaseObject.hHmgr);
{
REGION_Delete(pdc->prgnVis);
}
if (pdc->rosdc.hGCClipRgn)
{
GreDeleteObject(pdc->rosdc.hGCClipRgn);
}
if (NULL != pdc->rosdc.CombinedClip)
IntEngDeleteClipRegion(pdc->rosdc.CombinedClip);
@@ -373,72 +391,64 @@ DC_Cleanup(PVOID ObjectBody)
return TRUE;
}
BOOL
FASTCALL
DC_SetOwnership(HDC hDC, PEPROCESS Owner)
VOID
NTAPI
DC_vSetOwner(PDC pdc, ULONG ulOwner)
{
INT Index;
PGDI_TABLE_ENTRY Entry;
PDC pDC;
BOOL ret = FALSE;
if (!GDIOBJ_SetOwnership(hDC, Owner))
if (pdc->rosdc.hClipRgn)
{
DPRINT1("GDIOBJ_SetOwnership failed\n");
return FALSE;
IntGdiSetRegionOwner(pdc->rosdc.hClipRgn, ulOwner);
}
pDC = DC_LockDc(hDC);
if (!pDC)
if (pdc->rosdc.hGCClipRgn)
{
DPRINT1("Could not lock DC\n");
return FALSE;
IntGdiSetRegionOwner(pdc->rosdc.hGCClipRgn, ulOwner);
}
/*
System Regions:
These regions do not use attribute sections and when allocated, use
gdiobj level functions.
*/
if (pDC->rosdc.hClipRgn)
{ // FIXME! HAX!!!
Index = GDI_HANDLE_GET_INDEX(pDC->rosdc.hClipRgn);
Entry = &GdiHandleTable->Entries[Index];
if (Entry->UserData) FreeObjectAttr(Entry->UserData);
Entry->UserData = NULL;
//
if (!GDIOBJ_SetOwnership(pDC->rosdc.hClipRgn, Owner)) goto leave;
}
if (pDC->prgnVis)
{ // FIXME! HAX!!!
Index = GDI_HANDLE_GET_INDEX(pDC->prgnVis->BaseObject.hHmgr);
Entry = &GdiHandleTable->Entries[Index];
if (Entry->UserData) FreeObjectAttr(Entry->UserData);
Entry->UserData = NULL;
//
if (!GDIOBJ_SetOwnership(pDC->prgnVis->BaseObject.hHmgr, Owner)) goto leave;
}
if (pDC->rosdc.hGCClipRgn)
{ // FIXME! HAX!!!
Index = GDI_HANDLE_GET_INDEX(pDC->rosdc.hGCClipRgn);
Entry = &GdiHandleTable->Entries[Index];
if (Entry->UserData) FreeObjectAttr(Entry->UserData);
Entry->UserData = NULL;
//
if (!GDIOBJ_SetOwnership(pDC->rosdc.hGCClipRgn, Owner)) goto leave;
}
if (pDC->dclevel.hPath)
if (pdc->dclevel.hPath)
{
if (!GDIOBJ_SetOwnership(pDC->dclevel.hPath, Owner)) goto leave;
GreSetObjectOwner(pdc->dclevel.hPath, ulOwner);
}
ret = TRUE;
leave:
DC_UnlockDc(pDC);
IntGdiSetBrushOwner(pdc->dclevel.pbrFill, ulOwner);
IntGdiSetBrushOwner(pdc->dclevel.pbrLine, ulOwner);
return ret;
/* Allocate or free DC attribute */
if (ulOwner == GDI_OBJ_HMGR_PUBLIC || ulOwner == GDI_OBJ_HMGR_NONE)
{
if (pdc->pdcattr != &pdc->dcattr)
DC_vFreeDcAttr(pdc);
}
else if (ulOwner == GDI_OBJ_HMGR_POWNED)
{
if (pdc->pdcattr == &pdc->dcattr)
DC_bAllocDcAttr(pdc);
}
/* Set the DC's ownership */
GDIOBJ_vSetObjectOwner(&pdc->BaseObject, ulOwner);
}
BOOL
NTAPI
GreSetDCOwner(HDC hdc, ULONG ulOwner)
{
PDC pdc;
pdc = DC_LockDc(hdc);
if (!pdc)
{
DPRINT1("GreSetDCOwner: Could not lock DC\n");
return FALSE;
}
/* Call the internal DC function */
DC_vSetOwner(pdc, ulOwner);
DC_UnlockDc(pdc);
return TRUE;
}
int FASTCALL
CLIPPING_UpdateGCRegion(DC* Dc);
@@ -609,7 +619,7 @@ GreOpenDCW(
/* FIXME: HACK! */
DC_InitHack(pdc);
DC_AllocDcAttr(pdc);
DC_bAllocDcAttr(pdc);
DC_UnlockDc(pdc);
@@ -689,17 +699,17 @@ NtGdiOpenDCW(
/* Call the internal function */
hdc = GreOpenDCW(pustrDevice ? &ustrDevice : NULL,
pdmInit ? &dmInit : NULL,
NULL, // fixme pwszLogAddress
NULL, // FIXME: pwszLogAddress
iType,
bDisplay,
hspool,
NULL, //FIXME: pDriverInfo2
NULL, // FIXME: pDriverInfo2
pUMdhpdev ? &dhpdev : NULL);
/* If we got a HDC and a UM dhpdev is requested,... */
if (hdc && pUMdhpdev)
{
/* Copy dhpdev to caller (FIXME: use dhpdev?? */
/* Copy dhpdev to caller (FIXME: use dhpdev?) */
_SEH2_TRY
{
/* Pointer was already probed */
@@ -772,7 +782,7 @@ NtGdiCreateCompatibleDC(HDC hdc)
DC_InitHack(pdcNew);
/* Allocate a dc attribute */
DC_AllocDcAttr(pdcNew);
DC_bAllocDcAttr(pdcNew);
// HACK!
DC_vSelectSurface(pdcNew, psurfDefaultBitmap);
@@ -825,11 +835,9 @@ IntGdiDeleteDC(HDC hDC, BOOL Force)
DC_UnlockDc(DCToDelete);
if (!IsObjectDead(hDC))
if (GreIsHandleValid(hDC))
{
DC_vFreeDcAttr(DCToDelete); // Plug a leak see bug 6119!
if (!GDIOBJ_FreeObjByHandle(hDC, GDI_OBJECT_TYPE_DC))
if (!GreDeleteObject(hDC))
{
DPRINT1("DC_FreeDC failed\n");
}
@@ -844,25 +852,24 @@ IntGdiDeleteDC(HDC hDC, BOOL Force)
BOOL
APIENTRY
NtGdiDeleteObjectApp(HANDLE DCHandle)
NtGdiDeleteObjectApp(HANDLE hobj)
{
/* Complete all pending operations */
NtGdiFlushUserBatch();
NtGdiFlushUserBatch(); // FIXME: we shouldn't need this
if (GDI_HANDLE_IS_STOCKOBJ(DCHandle)) return TRUE;
if (GDI_HANDLE_IS_STOCKOBJ(hobj)) return TRUE;
if (GDI_HANDLE_GET_TYPE(DCHandle) != GDI_OBJECT_TYPE_DC)
return GreDeleteObject((HGDIOBJ) DCHandle);
if (IsObjectDead((HGDIOBJ)DCHandle)) return TRUE;
if (!GDIOBJ_OwnedByCurrentProcess(DCHandle))
if (GreGetObjectOwner(hobj) != GDI_OBJ_HMGR_POWNED)
{
EngSetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
return IntGdiDeleteDC(DCHandle, FALSE);
if (GDI_HANDLE_GET_TYPE(hobj) != GDI_OBJECT_TYPE_DC)
return GreDeleteObject(hobj);
// FIXME: everything should be callback based
return IntGdiDeleteDC(hobj, FALSE);
}
BOOL
@@ -975,45 +982,3 @@ IntGdiCreateDisplayDC(HDEV hDev, ULONG DcType, BOOL EmptyDC)
return hDC;
}
BOOL
FASTCALL
IntGdiSetDCOwnerEx( HDC hDC, DWORD OwnerMask, BOOL NoSetBrush)
{
PDC pDC;
BOOL Ret = FALSE;
if (!hDC || (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)) return FALSE;
if ((OwnerMask == GDI_OBJ_HMGR_PUBLIC) || OwnerMask == GDI_OBJ_HMGR_NONE)
{
pDC = DC_LockDc ( hDC );
MmCopyFromCaller(&pDC->dcattr, pDC->pdcattr, sizeof(DC_ATTR));
DC_vFreeDcAttr(pDC);
DC_UnlockDc( pDC );
if (!DC_SetOwnership( hDC, NULL )) // This hDC is inaccessible!
return Ret;
}
if (OwnerMask == GDI_OBJ_HMGR_POWNED)
{
pDC = DC_LockDc ( hDC );
ASSERT(pDC->pdcattr == &pDC->dcattr);
DC_UnlockDc( pDC );
if (!DC_SetOwnership( hDC, PsGetCurrentProcess() )) return Ret;
DC_AllocateDcAttr( hDC ); // Allocate new dcattr
DCU_SynchDcAttrtoUser( hDC ); // Copy data from dc to dcattr
}
if ((OwnerMask != GDI_OBJ_HMGR_NONE) && !NoSetBrush)
{
pDC = DC_LockDc ( hDC );
if (IntGdiSetBrushOwner((PBRUSH)pDC->dclevel.pbrFill, OwnerMask))
IntGdiSetBrushOwner((PBRUSH)pDC->dclevel.pbrLine, OwnerMask);
DC_UnlockDc( pDC );
}
return TRUE;
}
@@ -181,7 +181,8 @@ GdiSelectPalette(
if(pdc->dctype == DCTYPE_MEMORY)
{
IntGdiRealizePalette(pdc);
// This didn't work anyway
//IntGdiRealizePalette(hDC);
}
PALETTE_ShareUnlockPalette(ppal);
@@ -364,7 +365,7 @@ NtGdiSelectBitmap(
if (hVisRgn)
{
GdiSelectVisRgn(hdc, hVisRgn);
REGION_FreeRgnByHandle(hVisRgn);
GreDeleteObject(hVisRgn);
}
/* Return the old bitmap handle */
@@ -543,7 +544,12 @@ NtGdiGetRandomRgn(
else if (pdc->dclevel.prgnMeta) hrgnSrc = pdc->dclevel.prgnMeta->BaseObject.hHmgr;
break;
case SYSRGN:
if (pdc->prgnVis) hrgnSrc = pdc->prgnVis->BaseObject.hHmgr;
if (pdc->prgnVis)
{
PREGION prgnDest = REGION_LockRgn(hrgnDest);
ret = IntGdiCombineRgn(prgnDest, pdc->prgnVis, 0, RGN_COPY) == ERROR ? -1 : 1;
REGION_UnlockRgn(prgnDest);
}
break;
default:
hrgnSrc = NULL;
@@ -101,16 +101,12 @@ DC_vRestoreDC(
IN PDC pdc,
INT iSaveLevel)
{
PEPROCESS pepCurrentProcess;
HDC hdcSave;
PDC pdcSave;
ASSERT(iSaveLevel > 0);
DPRINT("DC_vRestoreDC(%p, %ld)\n", pdc->BaseObject.hHmgr, iSaveLevel);
/* Get current process */
pepCurrentProcess = PsGetCurrentProcess();
/* Loop the save levels */
while (pdc->dclevel.lSaveDepth > iSaveLevel)
{
@@ -118,7 +114,7 @@ DC_vRestoreDC(
DPRINT("RestoreDC = %p\n", hdcSave);
/* Set us as the owner */
if (!GDIOBJ_SetOwnership(hdcSave, pepCurrentProcess))
if (!GreSetObjectOwner(hdcSave, GDI_OBJ_HMGR_POWNED))
{
/* Could not get ownership. That's bad! */
DPRINT1("Could not get ownership of saved DC (%p) for hdc %p!\n",
@@ -261,7 +257,7 @@ NtGdiSaveDC(
/* Make it a kernel handle
(FIXME: windows handles this different, see wiki)*/
GDIOBJ_SetOwnership(hdcSave, NULL);
GreSetObjectOwner(hdcSave, GDI_OBJ_HMGR_PUBLIC);
/* Copy the current state */
DC_vCopyState(pdc, pdcSave, TRUE);
@@ -164,7 +164,7 @@ IntSetDIBColorTable(
return 0;
}
PalGDI = PALETTE_ShareLockPalette(psurf->ppal->BaseObject.hHmgr);
PalGDI = psurf->ppal;
for (Index = StartIndex;
Index < StartIndex + Entries && Index < PalGDI->NumColors;
@@ -174,7 +174,6 @@ IntSetDIBColorTable(
PalGDI->IndexedColors[Index].peGreen = Colors[Index - StartIndex].rgbGreen;
PalGDI->IndexedColors[Index].peBlue = Colors[Index - StartIndex].rgbBlue;
}
PALETTE_ShareUnlockPalette(PalGDI);
}
else
Entries = 0;
@@ -559,7 +558,7 @@ Exit:
if (pSourceSurf) EngUnlockSurface(pSourceSurf);
if (hSourceBitmap) EngDeleteSurface((HSURF)hSourceBitmap);
if (hpalDIB) PALETTE_FreePaletteByHandle(hpalDIB);
if (hpalDIB) GreDeleteObject(hpalDIB);
DC_UnlockDc(pDC);
return ret;
@@ -1639,7 +1638,7 @@ cleanup:
if (res)
{
SURFACE_FreeSurfaceByHandle(res);
GreDeleteObject(res);
res = 0;
}
}
@@ -1329,7 +1329,7 @@ IntFillArc( PDC dc,
pdcattr = dc->pdcattr;
pbrush = BRUSH_LockBrush(pdcattr->hbrush);
pbrush = BRUSH_ShareLockBrush(pdcattr->hbrush);
if (!pbrush)
{
DPRINT1("FillArc Fail\n");
@@ -1342,7 +1342,7 @@ IntFillArc( PDC dc,
(dc->dclevel.flPath & DCPATH_CLOCKWISE) ? -Start : -End,
pbrush, Chord);
BRUSH_UnlockBrush(pbrush);
BRUSH_ShareUnlockBrush(pbrush);
return ret;
}
@@ -297,7 +297,7 @@ NtGdiEllipse(
DPRINT("Ellipse 2: XLeft: %d, YLeft: %d, Width: %d, Height: %d\n",
CenterX - RadiusX, CenterY + RadiusY, RadiusX*2, RadiusY*2);
pFillBrushObj = BRUSH_LockBrush(pdcattr->hbrush);
pFillBrushObj = BRUSH_ShareLockBrush(pdcattr->hbrush);
if (NULL == pFillBrushObj)
{
DPRINT1("FillEllipse Fail\n");
@@ -317,7 +317,7 @@ NtGdiEllipse(
RadiusX*2, // Width
RadiusY*2, // Height
&tmpFillBrushObj);
BRUSH_UnlockBrush(pFillBrushObj);
BRUSH_ShareUnlockBrush(pFillBrushObj);
}
if (ret)
@@ -784,7 +784,7 @@ IntRoundRect(
RectBounds.right += dc->ptlDCOrig.x;
RectBounds.bottom += dc->ptlDCOrig.y;
pbrushFill = BRUSH_LockBrush(pdcattr->hbrush);
pbrushFill = BRUSH_ShareLockBrush(pdcattr->hbrush);
if (NULL == pbrushFill)
{
DPRINT1("FillRound Fail\n");
@@ -804,7 +804,7 @@ IntRoundRect(
xCurveDiameter,
yCurveDiameter,
&brushTemp);
BRUSH_UnlockBrush(pbrushFill);
BRUSH_ShareUnlockBrush(pbrushFill);
}
if (ret)
@@ -20,7 +20,7 @@ FASTCALL
DoDeviceSync( SURFOBJ *Surface, PRECTL Rect, FLONG fl)
{
PPDEVOBJ Device = (PDEVOBJ*)Surface->hdev;
// No punting and "Handle to a surface, provided that the surface is device-managed.
// No punting and "Handle to a surface, provided that the surface is device-managed.
// Otherwise, dhsurf is zero".
if (!(Device->flFlags & PDEV_DRIVER_PUNTED_CALL) && (Surface->dhsurf))
{
@@ -42,9 +42,9 @@ VOID
FASTCALL
SynchonizeDriver(FLONG Flags)
{
SURFOBJ *SurfObj;
SURFOBJ *SurfObj;
PPDEVOBJ Device;
if (Flags & GCAPS2_SYNCFLUSH)
Flags = DSS_FLUSH_EVENT;
if (Flags & GCAPS2_SYNCTIMER)
@@ -149,7 +149,7 @@ GdiFlushUserBatch(PDC dc, PGDIBATCHHDR pHdr)
break;
}
return Size;
return Size;
}
/*
@@ -190,7 +190,7 @@ NtGdiFlushUserBatch(VOID)
PCHAR pHdr = (PCHAR)&pTeb->GdiTebBatch.Buffer[0];
PDC pDC = NULL;
if (hDC && !IsObjectDead(hDC))
if (GDI_HANDLE_GET_TYPE(hDC) == GDILoObjType_LO_DC_TYPE && GreIsHandleValid(hDC))
{
pDC = DC_LockDc(hDC);
}
+133 -42
View File
@@ -12,23 +12,14 @@
#define NDEBUG
#include <debug.h>
extern ULONG gulFirstFree;
extern ULONG gulFirstUnused;
ULONG gulDebugChannels = 0;
ULONG gulLogUnique = 0;
#ifdef GDI_DEBUG
ULONG_PTR GDIHandleAllocator[GDI_HANDLE_COUNT][GDI_STACK_LEVELS+1];
ULONG_PTR GDIHandleLocker[GDI_HANDLE_COUNT][GDI_STACK_LEVELS+1];
ULONG_PTR GDIHandleShareLocker[GDI_HANDLE_COUNT][GDI_STACK_LEVELS+1];
ULONG_PTR GDIHandleDeleter[GDI_HANDLE_COUNT][GDI_STACK_LEVELS+1];
struct DbgOpenGDIHandle
{
ULONG idx;
int count;
};
#define MAX_BACKTRACES 1024
static struct DbgOpenGDIHandle AllocatorTable[MAX_BACKTRACES];
#if 0
static
BOOL
CompareBacktraces(ULONG idx1, ULONG idx2)
@@ -50,7 +41,9 @@ CompareBacktraces(ULONG idx1, ULONG idx2)
return TRUE;
}
void IntDumpHandleTable(PGDI_HANDLE_TABLE HandleTable)
VOID
NTAPI
DbgDumpGdiHandleTable(void)
{
static int leak_reported = 0;
int i, j, idx, nTraces = 0;
@@ -139,9 +132,11 @@ void IntDumpHandleTable(PGDI_HANDLE_TABLE HandleTable)
ASSERT(FALSE);
}
#endif
ULONG
CaptureStackBackTace(PVOID* pFrames, ULONG nFramesToCapture)
NTAPI
DbgCaptureStackBackTace(PVOID* pFrames, ULONG nFramesToCapture)
{
ULONG nFrameCount;
@@ -160,7 +155,8 @@ CaptureStackBackTace(PVOID* pFrames, ULONG nFramesToCapture)
}
BOOL
GdiDbgHTIntegrityCheck()
NTAPI
DbgGdiHTIntegrityCheck()
{
ULONG i, nDeleted = 0, nFree = 0, nUsed = 0;
PGDI_TABLE_ENTRY pEntry;
@@ -171,7 +167,7 @@ GdiDbgHTIntegrityCheck()
/* FIXME: check reserved entries */
/* Now go through the deleted objects */
i = GdiHandleTable->FirstFree & 0xffff;
i = gulFirstFree & 0xffff;
while (i)
{
pEntry = &GdiHandleTable->Entries[i];
@@ -208,7 +204,7 @@ GdiDbgHTIntegrityCheck()
i = (ULONG_PTR)pEntry->KernelData & 0xffff;
};
for (i = GdiHandleTable->FirstUnused;
for (i = gulFirstUnused;
i < GDI_HANDLE_COUNT;
i++)
{
@@ -280,40 +276,135 @@ GdiDbgHTIntegrityCheck()
return r;
}
ULONG
FASTCALL
GDIOBJ_IncrementShareCount(POBJ Object)
{
INT cLocks = InterlockedIncrement((PLONG)&Object->ulShareCount);
GDIDBG_CAPTURESHARELOCKER(Object->hHmgr);
ASSERT(cLocks >= 1);
return cLocks;
}
#endif /* GDI_DEBUG */
void
GdiDbgDumpLockedHandles()
VOID
NTAPI
DbgDumpLockedGdiHandles()
{
#if 0
ULONG i;
for (i = RESERVE_ENTRIES_COUNT; i < GDI_HANDLE_COUNT; i++)
{
PGDI_TABLE_ENTRY pEntry = &GdiHandleTable->Entries[i];
PENTRY pentry = &gpentHmgr[i];
if (pEntry->Type & GDI_ENTRY_BASETYPE_MASK)
if (pentry->Objt)
{
BASEOBJECT *pObject = pEntry->KernelData;
if (pObject->cExclusiveLock > 0)
POBJ pobj = pentry->einfo.pobj;
if (pobj->cExclusiveLock > 0)
{
DPRINT1("Locked object: %lx, type = %lx. allocated from:\n",
i, pEntry->Type);
GDIDBG_TRACEALLOCATOR(i);
DPRINT1("Locked from:\n");
GDIDBG_TRACELOCKER(i);
i, pentry->Objt);
DBG_DUMP_EVENT_LIST(&pobj->slhLog);
}
}
}
#endif
}
VOID
NTAPI
DbgLogEvent(PSLIST_HEADER pslh, EVENT_TYPE nEventType, LPARAM lParam)
{
PLOGENTRY pLogEntry;
/* Log a maximum of 100 events */
if (QueryDepthSList(pslh) >= 1000) return;
/* Allocate a logentry */
pLogEntry = EngAllocMem(0, sizeof(LOGENTRY), 'golG');
if (!pLogEntry) return;
/* Set type */
pLogEntry->nEventType = nEventType;
pLogEntry->ulUnique = InterlockedIncrement((LONG*)&gulLogUnique);
pLogEntry->dwProcessId = HandleToUlong(PsGetCurrentProcessId());
pLogEntry->dwThreadId = HandleToUlong(PsGetCurrentThreadId());
pLogEntry->lParam = lParam;
/* Capture a backtrace */
DbgCaptureStackBackTace(pLogEntry->apvBackTrace, 20);
switch (nEventType)
{
case EVENT_ALLOCATE:
case EVENT_CREATE_HANDLE:
case EVENT_REFERENCE:
case EVENT_DEREFERENCE:
case EVENT_LOCK:
case EVENT_UNLOCK:
case EVENT_DELETE:
case EVENT_FREE:
case EVENT_SET_OWNER:
default:
break;
}
/* Push it on the list */
InterlockedPushEntrySList(pslh, &pLogEntry->sleLink);
}
#define REL_ADDR(va) ((ULONG_PTR)va - (ULONG_PTR)&__ImageBase)
VOID
DbgPrintEvent(PLOGENTRY pLogEntry)
{
PSTR pstr;
switch (pLogEntry->nEventType)
{
case EVENT_ALLOCATE: pstr = "Allocate"; break;
case EVENT_CREATE_HANDLE: pstr = "CreatHdl"; break;
case EVENT_REFERENCE: pstr = "Ref"; break;
case EVENT_DEREFERENCE: pstr = "Deref"; break;
case EVENT_LOCK: pstr = "Lock"; break;
case EVENT_UNLOCK: pstr = "Unlock"; break;
case EVENT_DELETE: pstr = "Delete"; break;
case EVENT_FREE: pstr = "Free"; break;
case EVENT_SET_OWNER: pstr = "SetOwner"; break;
default: pstr = "Unknown"; break;
}
DbgPrint("[%ld] %03x:%03x %.8s val=%p <%lx,%lx,%lx,%lx>\n",
pLogEntry->ulUnique,
pLogEntry->dwProcessId,
pLogEntry->dwThreadId,
pstr,
pLogEntry->lParam,
REL_ADDR(pLogEntry->apvBackTrace[2]),
REL_ADDR(pLogEntry->apvBackTrace[3]),
REL_ADDR(pLogEntry->apvBackTrace[4]),
REL_ADDR(pLogEntry->apvBackTrace[5]));
}
VOID
NTAPI
DbgDumpEventList(PSLIST_HEADER pslh)
{
PSLIST_ENTRY psle;
PLOGENTRY pLogEntry;
while ((psle = InterlockedPopEntrySList(pslh)))
{
pLogEntry = CONTAINING_RECORD(psle, LOGENTRY, sleLink);
DbgPrintEvent(pLogEntry);
}
}
VOID
NTAPI
DbgCleanupEventList(PSLIST_HEADER pslh)
{
PSLIST_ENTRY psle;
PLOGENTRY pLogEntry;
while ((psle = InterlockedPopEntrySList(pslh)))
{
pLogEntry = CONTAINING_RECORD(psle, LOGENTRY, sleLink);
EngFreeMem(pLogEntry);
}
}
void
@@ -323,9 +414,9 @@ DbgPreServiceHook(ULONG ulSyscallId, PULONG_PTR pulArguments)
PTHREADINFO pti = (PTHREADINFO)PsGetCurrentThreadWin32Thread();
if (pti && pti->cExclusiveLocks != 0)
{
DbgPrint("FATAL: Win32DbgPreServiceHook(%ld): There are %ld exclusive locks!\n",
DbgPrint("FATAL: Win32DbgPreServiceHook(0x%lx): There are %ld exclusive locks!\n",
ulSyscallId, pti->cExclusiveLocks);
GdiDbgDumpLockedHandles();
DbgDumpLockedGdiHandles();
ASSERT(FALSE);
}
@@ -338,9 +429,9 @@ DbgPostServiceHook(ULONG ulSyscallId, ULONG_PTR ulResult)
PTHREADINFO pti = (PTHREADINFO)PsGetCurrentThreadWin32Thread();
if (pti && pti->cExclusiveLocks != 0)
{
DbgPrint("FATAL: Win32DbgPostServiceHook(%ld): There are %ld exclusive locks!\n",
DbgPrint("FATAL: Win32DbgPostServiceHook(0x%lx): There are %ld exclusive locks!\n",
ulSyscallId, pti->cExclusiveLocks);
GdiDbgDumpLockedHandles();
DbgDumpLockedGdiHandles();
ASSERT(FALSE);
}
return ulResult;
File diff suppressed because it is too large Load Diff
@@ -1,7 +1,7 @@
/*
* PROJECT: ReactOS win32 kernel mode subsystem
* LICENSE: GPL - See COPYING in the top level directory
* FILE: subsystems/win32/win32k/objects/gdiobj.c
* FILE: subsystems/win32/win32k/objects/gdipool.c
* PURPOSE: Static size allocator for user mode object attributes
* PROGRAMMERS: Timo Kreuzer
*/
@@ -34,6 +34,9 @@ typedef struct _GDI_POOL
ULONG cSlotsPerSection;
ULONG cEmptySections;
EX_PUSH_LOCK pushlock; // for pool growth
#if DBG_ENABLE_EVENT_LOGGING
SLIST_HEADER slhLog;
#endif
LIST_ENTRY leInUseList;
LIST_ENTRY leEmptyList;
@@ -95,7 +98,13 @@ GdiPoolDeleteSection(PGDI_POOL pPool, PGDI_POOL_SECTION pSection)
SIZE_T cjSize = 0;
/* Should not have any allocations */
ASSERT(pSection->cAllocCount == 0);
if (pSection->cAllocCount != 0)
{
DPRINT1("There are %ld allocations left, section=%p, pool=%p\n",
pSection->cAllocCount, pSection, pPool);
DBG_DUMP_EVENT_LIST(&pPool->slhLog);
ASSERT(FALSE);
}
/* Release the virtual memory */
status = ZwFreeVirtualMemory(NtCurrentProcess(),
@@ -186,8 +195,11 @@ GdiPoolAllocate(
pSection->ulCommitBitmap |= ulPageBit;
}
/* Increase alloc count and check if section is now busy */
/* Increase alloc count */
pSection->cAllocCount++;
DBG_LOGEVENT(&pPool->slhLog, EVENT_ALLOCATE, pvAlloc);
/* Check if section is now busy */
if (pSection->cAllocCount == pPool->cSlotsPerSection)
{
/* Remove the section from the ready list */
@@ -198,12 +210,11 @@ done:
/* Release the pool lock and enable APCs */
ExReleasePushLockExclusive(&pPool->pushlock);
KeLeaveCriticalRegion();
DPRINT1("GdiPoolallocate: %p\n", pvAlloc);
DPRINT("GdiPoolallocate: %p\n", pvAlloc);
return pvAlloc;
}
VOID
NTAPI
GdiPoolFree(
@@ -211,10 +222,10 @@ GdiPoolFree(
PVOID pvAlloc)
{
PLIST_ENTRY ple;
PGDI_POOL_SECTION pSection;
PGDI_POOL_SECTION pSection = NULL;
ULONG_PTR cjOffset;
ULONG ulIndex;
DPRINT1("GdiPoolFree: %p\n", pvAlloc);
DPRINT("GdiPoolFree: %p\n", pvAlloc);
/* Disable APCs and acquire the pool lock */
KeEnterCriticalRegion();
@@ -243,6 +254,7 @@ DPRINT1("GdiPoolFree: %p\n", pvAlloc);
/* Decrease allocation count */
pSection->cAllocCount--;
DBG_LOGEVENT(&pPool->slhLog, EVENT_FREE, pvAlloc);
/* Check if the section got valid now */
if (pSection->cAllocCount == pPool->cSlotsPerSection - 1)
@@ -274,6 +286,8 @@ DPRINT1("GdiPoolFree: %p\n", pvAlloc);
}
}
DbgPrint("failed to free. pvAlloc=%p, base=%p, size=%lx\n",
pvAlloc, pSection->pvBaseAddress, pPool->cjSectionSize);
ASSERT(FALSE);
// KeBugCheck()
@@ -305,6 +319,7 @@ GdiPoolCreate(
pPool->ulTag = ulTag;
pPool->cjSectionSize = GDI_POOL_ALLOCATION_GRANULARITY;
pPool->cSlotsPerSection = pPool->cjSectionSize / cjAllocSize;
DBG_INITLOG(&pPool->slhLog);
return pPool;
}
@@ -317,20 +332,24 @@ GdiPoolDestroy(PGDI_POOL pPool)
PLIST_ENTRY ple;
/* Loop all empty sections, removing them */
while ((ple = RemoveHeadList(&pPool->leEmptyList)))
while (!IsListEmpty(&pPool->leEmptyList))
{
/* Delete the section */
ple = RemoveHeadList(&pPool->leEmptyList);
pSection = CONTAINING_RECORD(ple, GDI_POOL_SECTION, leInUseLink);
GdiPoolDeleteSection(pPool, pSection);
}
/* Loop all ready sections, removing them */
while ((ple = RemoveHeadList(&pPool->leInUseList)))
while (!IsListEmpty(&pPool->leInUseList))
{
/* Delete the section */
ple = RemoveHeadList(&pPool->leInUseList);
pSection = CONTAINING_RECORD(ple, GDI_POOL_SECTION, leInUseLink);
GdiPoolDeleteSection(pPool, pSection);
}
DBG_CLEANUP_EVENT_LIST(&pPool->slhLog);
EngFreeMem(pPool);
}
@@ -50,9 +50,10 @@ IntGdiDeleteColorSpace(
{
BOOL Ret = FALSE;
if ( hColorSpace != hStockColorSpace )
if ( hColorSpace != hStockColorSpace &&
GDI_HANDLE_GET_TYPE(hColorSpace) == GDILoObjType_LO_ICMLCS_TYPE)
{
Ret = COLORSPACEOBJ_FreeCSByHandle(hColorSpace);
Ret = GreDeleteObject(hColorSpace);
if ( !Ret ) EngSetLastError(ERROR_INVALID_PARAMETER);
}
return Ret;
@@ -216,7 +217,7 @@ NtGdiSetColorSpace(IN HDC hdc,
if (pDC->dclevel.pColorSpace)
{
GDIOBJ_ShareUnlockObjByPtr((POBJ) pDC->dclevel.pColorSpace);
GDIOBJ_vDereferenceObject((POBJ) pDC->dclevel.pColorSpace);
}
pDC->dclevel.pColorSpace = pCS;
@@ -144,27 +144,27 @@ VOID FASTCALL PALETTE_ValidateFlags(PALETTEENTRY* lpPalE, INT size)
lpPalE[i].peFlags = PC_SYS_USED | (lpPalE[i].peFlags & 0x07);
}
HPALETTE
FASTCALL
PALETTE_AllocPalette(ULONG Mode,
PPALETTE
NTAPI
PALETTE_AllocPalette2(ULONG Mode,
ULONG NumColors,
ULONG *Colors,
ULONG Red,
ULONG Green,
ULONG Blue)
{
HPALETTE NewPalette;
PPALETTE PalGDI;
PalGDI = (PPALETTE)GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_PALETTE);
PalGDI = (PPALETTE)GDIOBJ_AllocateObject(GDIObjType_PAL_TYPE,
sizeof(PALETTE),
BASEFLAG_LOOKASIDE);
if (!PalGDI)
{
DPRINT1("Could not allocate a palette.\n");
return NULL;
}
NewPalette = PalGDI->BaseObject.hHmgr;
PalGDI->Self = NewPalette;
PalGDI->Self = PalGDI->BaseObject.hHmgr;
PalGDI->flFlags = Mode;
if (NULL != Colors)
@@ -174,8 +174,7 @@ PALETTE_AllocPalette(ULONG Mode,
TAG_PALETTE);
if (NULL == PalGDI->IndexedColors)
{
PALETTE_UnlockPalette(PalGDI);
PALETTE_FreePaletteByHandle(NewPalette);
GDIOBJ_vDeleteObject(&PalGDI->BaseObject);
return NULL;
}
RtlCopyMemory(PalGDI->IndexedColors, Colors, sizeof(PALETTEENTRY) * NumColors);
@@ -201,9 +200,35 @@ PALETTE_AllocPalette(ULONG Mode,
PalGDI->flFlags |= PAL_RGB;
}
PALETTE_UnlockPalette(PalGDI);
return PalGDI;
}
return NewPalette;
HPALETTE
FASTCALL
PALETTE_AllocPalette(ULONG Mode,
ULONG NumColors,
ULONG *Colors,
ULONG Red,
ULONG Green,
ULONG Blue)
{
PPALETTE ppal;
HPALETTE hpal;
ppal = PALETTE_AllocPalette2(Mode, NumColors, Colors, Red, Green, Blue);
if (!ppal) return NULL;
hpal = GDIOBJ_hInsertObject(&ppal->BaseObject, GDI_OBJ_HMGR_POWNED);
if (!hpal)
{
DPRINT1("Could not insert palette into handle table.\n");
GDIOBJ_vFreeObject(&ppal->BaseObject);
return NULL;
}
PALETTE_UnlockPalette(ppal);
return hpal;
}
HPALETTE
@@ -215,9 +240,19 @@ PALETTE_AllocPaletteIndexedRGB(ULONG NumColors,
PPALETTE PalGDI;
UINT i;
PalGDI = (PPALETTE)GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_PALETTE);
PalGDI = (PPALETTE)GDIOBJ_AllocateObject(GDIObjType_PAL_TYPE,
sizeof(PALETTE),
BASEFLAG_LOOKASIDE);
if (!PalGDI)
{
DPRINT1("Could not allocate a palette.\n");
return NULL;
}
if (!GDIOBJ_hInsertObject(&PalGDI->BaseObject, GDI_OBJ_HMGR_POWNED))
{
DPRINT1("Could not insert palette into handle table.\n");
GDIOBJ_vFreeObject(&PalGDI->BaseObject);
return NULL;
}
@@ -231,8 +266,7 @@ PALETTE_AllocPaletteIndexedRGB(ULONG NumColors,
TAG_PALETTE);
if (NULL == PalGDI->IndexedColors)
{
PALETTE_UnlockPalette(PalGDI);
PALETTE_FreePaletteByHandle(NewPalette);
GDIOBJ_vDeleteObject(&PalGDI->BaseObject);
return NULL;
}
@@ -390,22 +424,29 @@ ColorCorrection(PPALETTE PalGDI, PPALETTEENTRY PaletteEntry, ULONG Colors)
HPALETTE
APIENTRY
EngCreatePalette(
ULONG Mode,
ULONG NumColors,
ULONG *Colors,
ULONG Red,
ULONG Green,
ULONG Blue)
ULONG iMode,
ULONG cColors,
ULONG *pulColors,
ULONG flRed,
ULONG flGreen,
ULONG flBlue)
{
HPALETTE Palette;
PPALETTE ppal;
HPALETTE hpal;
Palette = PALETTE_AllocPalette(Mode, NumColors, Colors, Red, Green, Blue);
if (Palette != NULL)
ppal = PALETTE_AllocPalette2(iMode, cColors, pulColors, flRed, flGreen, flBlue);
if (!ppal) return NULL;
hpal = GDIOBJ_hInsertObject(&ppal->BaseObject, GDI_OBJ_HMGR_PUBLIC);
if (!hpal)
{
GDIOBJ_SetOwnership(Palette, NULL);
DPRINT1("Could not insert palette into handle table.\n");
GDIOBJ_vFreeObject(&ppal->BaseObject);
return NULL;
}
return Palette;
PALETTE_UnlockPalette(ppal);
return hpal;
}
/*
@@ -413,11 +454,16 @@ EngCreatePalette(
*/
BOOL
APIENTRY
EngDeletePalette(IN HPALETTE Palette)
EngDeletePalette(IN HPALETTE hpal)
{
GDIOBJ_SetOwnership(Palette, PsGetCurrentProcess());
PPALETTE ppal;
return PALETTE_FreePaletteByHandle(Palette);
ppal = PALETTE_ShareLockPalette(hpal);
if (!ppal) return FALSE;
GDIOBJ_vDeleteObject(&ppal->BaseObject);
return TRUE;
}
/*
@@ -70,8 +70,7 @@ PATH_Delete(HPATH hPath)
pPath = PATH_LockPath( hPath );
if (!pPath) return FALSE;
PATH_DestroyGdiPath( pPath );
PATH_UnlockPath( pPath );
PATH_FreeExtPathByHandle(hPath);
GDIOBJ_vDeleteObject(&pPath->BaseObject);
return TRUE;
}
@@ -1527,7 +1526,7 @@ PATH_WidenPath(DC *dc)
PATH_FlattenPath(pPath);
size = IntGdiGetObject( pdcattr->hpen, 0, NULL);
size = GreGetObject( pdcattr->hpen, 0, NULL);
if (!size)
{
PATH_UnlockPath( pPath );
@@ -1536,9 +1535,9 @@ PATH_WidenPath(DC *dc)
}
elp = ExAllocatePoolWithTag(PagedPool, size, TAG_PATH);
(VOID) IntGdiGetObject( pdcattr->hpen, size, elp);
GreGetObject(pdcattr->hpen, size, elp);
obj_type = GDIOBJ_GetObjectType(pdcattr->hpen);
obj_type = GDI_HANDLE_GET_TYPE(pdcattr->hpen);
if(obj_type == GDI_OBJECT_TYPE_PEN)
{
penStyle = ((LOGPEN*)elp)->lopnStyle;
@@ -1865,6 +1864,7 @@ PATH_WidenPath(DC *dc)
DPRINT1("Assign path failed\n");
PATH_DestroyGdiPath(pNewPath);
ExFreePoolWithTag(pNewPath, TAG_PATH);
PATH_UnlockPath(pPath);
return ret;
}
@@ -2120,6 +2120,7 @@ NtGdiAbortPath(HDC hDC)
}
pPath = PATH_LockPath(dc->dclevel.hPath);
if (!pPath)
{
DC_UnlockDc(dc);
return FALSE;
@@ -2128,6 +2129,8 @@ NtGdiAbortPath(HDC hDC)
PATH_EmptyPath(pPath);
PATH_UnlockPath(pPath);
dc->dclevel.flPath &= ~DCPATH_ACTIVE;
DC_UnlockDc ( dc );
return TRUE;
}
@@ -2182,7 +2185,7 @@ NtGdiBeginPath( HDC hDC )
DPRINT("BeginPath 2 h 0x%x p 0x%x\n", dc->dclevel.hPath, pPath);
// Path handles are shared. Also due to recursion with in the same thread.
GDIOBJ_UnlockObjByPtr((POBJ)pPath); // Unlock
GDIOBJ_vUnlockObject((POBJ)pPath); // Unlock
pPath = PATH_LockPath(dc->dclevel.hPath); // Share Lock.
/* Make sure that path is empty */
+6 -10
View File
@@ -29,12 +29,12 @@
PBRUSH
FASTCALL
PEN_LockPen(HGDIOBJ hBMObj)
PEN_LockPen(HGDIOBJ hobj)
{
if (GDI_HANDLE_GET_TYPE(hBMObj) == GDI_OBJECT_TYPE_EXTPEN)
return GDIOBJ_LockObj( hBMObj, GDI_OBJECT_TYPE_EXTPEN);
else
return GDIOBJ_LockObj( hBMObj, GDI_OBJECT_TYPE_PEN);
if (GDI_HANDLE_GET_TYPE(hobj) != GDILoObjType_LO_PEN_TYPE &&
GDI_HANDLE_GET_TYPE(hobj) != GDILoObjType_LO_EXTPEN_TYPE) return NULL;
return GDIOBJ_LockObject(hobj, GDIObjType_BRUSH_TYPE);
}
PBRUSH
@@ -189,11 +189,7 @@ IntGdiExtCreatePen(
ExitCleanup:
EngSetLastError(ERROR_INVALID_PARAMETER);
pbrushPen->pStyle = NULL;
PEN_UnlockPen(pbrushPen);
if (bOldStylePen)
PEN_FreePenByHandle(hPen);
else
PEN_FreeExtPenByHandle(hPen);
GDIOBJ_vDeleteObject(&pbrushPen->BaseObject);
return NULL;
}
+185 -119
View File
@@ -2032,9 +2032,19 @@ REGION_AllocRgnWithHandle(INT nReg)
HRGN hReg;
PROSRGNDATA pReg;
pReg = (PROSRGNDATA)GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_REGION);
if(!pReg)
pReg = (PROSRGNDATA)GDIOBJ_AllocateObject(GDIObjType_RGN_TYPE,
sizeof(REGION),
BASEFLAG_LOOKASIDE);
if (!pReg)
{
DPRINT1("Could not allocate a palette.\n");
return NULL;
}
if (!GDIOBJ_hInsertObject(&pReg->BaseObject, GDI_OBJ_HMGR_POWNED))
{
DPRINT1("Could not insert palette into handle table.\n");
GDIOBJ_vFreeObject(&pReg->BaseObject);
return NULL;
}
@@ -2051,8 +2061,8 @@ REGION_AllocRgnWithHandle(INT nReg)
pReg->Buffer = ExAllocatePoolWithTag(PagedPool, nReg * sizeof(RECT), TAG_REGION);
if (!pReg->Buffer)
{
RGNOBJAPI_Unlock(pReg);
GDIOBJ_FreeObjByHandle(hReg, GDI_OBJECT_TYPE_REGION);
DPRINT1("Could not allocate region buffer\n");
GDIOBJ_vDeleteObject(&pReg->BaseObject);
return NULL;
}
}
@@ -2061,10 +2071,36 @@ REGION_AllocRgnWithHandle(INT nReg)
pReg->rdh.dwSize = sizeof(RGNDATAHEADER);
pReg->rdh.nCount = nReg;
pReg->rdh.nRgnSize = nReg * sizeof(RECT);
pReg->prgnattr = &pReg->rgnattr;
return pReg;
}
BOOL
NTAPI
REGION_bAllocRgnAttr(PREGION prgn)
{
PPROCESSINFO ppi;
PRGN_ATTR prgnattr;
ppi = PsGetCurrentProcessWin32Process();
ASSERT(ppi);
prgnattr = GdiPoolAllocate(ppi->pPoolRgnAttr);
if (!prgnattr)
{
DPRINT1("Could not allocate RGN attr\n");
return FALSE;
}
/* Set the object attribute in the handle table */
prgn->prgnattr = prgnattr;
GDIOBJ_vSetObjectAttr(&prgn->BaseObject, prgnattr);
return TRUE;
}
//
// Allocate User Space Region Handle.
//
@@ -2072,34 +2108,31 @@ PROSRGNDATA
FASTCALL
REGION_AllocUserRgnWithHandle(INT nRgn)
{
PROSRGNDATA pRgn;
PGDI_TABLE_ENTRY Entry;
PREGION prgn;
pRgn = REGION_AllocRgnWithHandle(nRgn);
if (pRgn)
prgn = REGION_AllocRgnWithHandle(nRgn);
if (!prgn)
{
Entry = GDI_HANDLE_GET_ENTRY(GdiHandleTable, pRgn->BaseObject.hHmgr);
Entry->UserData = AllocateObjectAttr();
RtlZeroMemory(Entry->UserData, sizeof(RGN_ATTR));
return NULL;
}
return pRgn;
if (!REGION_bAllocRgnAttr(prgn))
{
ASSERT(FALSE);
}
return prgn;
}
PROSRGNDATA
FASTCALL
RGNOBJAPI_Lock(HRGN hRgn, PRGN_ATTR *ppRgn_Attr)
VOID
NTAPI
REGION_vSyncRegion(PREGION pRgn)
{
PGDI_TABLE_ENTRY Entry;
PRGN_ATTR pRgn_Attr;
BOOL Hit = FALSE;
PROSRGNDATA pRgn = NULL;
PRGN_ATTR pRgn_Attr = NULL;
pRgn = REGION_LockRgn(hRgn);
if (pRgn && GDIOBJ_OwnedByCurrentProcess(hRgn))
if (pRgn && pRgn->prgnattr != &pRgn->rgnattr)
{
Entry = GDI_HANDLE_GET_ENTRY(GdiHandleTable, hRgn);
pRgn_Attr = Entry->UserData;
pRgn_Attr = GDIOBJ_pvGetObjectAttr(&pRgn->BaseObject);
if ( pRgn_Attr )
{
@@ -2126,30 +2159,29 @@ RGNOBJAPI_Lock(HRGN hRgn, PRGN_ATTR *ppRgn_Attr)
pRgn_Attr->AttrFlags &= ~ATTR_RGN_DIRTY;
}
}
else
{ // This object is cached an waiting for it's resurrection by the users.
Hit = TRUE;
}
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
}
_SEH2_END;
if (Hit)
{
REGION_UnlockRgn(pRgn);
return NULL;
}
if (ppRgn_Attr)
*ppRgn_Attr = pRgn_Attr;
}
else
{
if (ppRgn_Attr)
*ppRgn_Attr = NULL;
}
}
}
PROSRGNDATA
FASTCALL
RGNOBJAPI_Lock(HRGN hRgn, PRGN_ATTR *ppRgn_Attr)
{
PROSRGNDATA pRgn = NULL;
pRgn = REGION_LockRgn(hRgn);
REGION_vSyncRegion(pRgn);
if (ppRgn_Attr)
*ppRgn_Attr = pRgn->prgnattr;
return pRgn;
}
@@ -2157,13 +2189,11 @@ VOID
FASTCALL
RGNOBJAPI_Unlock(PROSRGNDATA pRgn)
{
PGDI_TABLE_ENTRY Entry;
PRGN_ATTR pRgn_Attr;
if (pRgn && GDIOBJ_OwnedByCurrentProcess(pRgn->BaseObject.hHmgr))
if (pRgn && GreGetObjectOwner(pRgn->BaseObject.hHmgr) == GDI_OBJ_HMGR_POWNED)
{
Entry = GDI_HANDLE_GET_ENTRY(GdiHandleTable, pRgn->BaseObject.hHmgr);
pRgn_Attr = Entry->UserData;
pRgn_Attr = GDIOBJ_pvGetObjectAttr(&pRgn->BaseObject);
if ( pRgn_Attr )
{
@@ -2199,42 +2229,69 @@ PROSRGNDATA
FASTCALL
IntSysCreateRectpRgn(INT LeftRect, INT TopRect, INT RightRect, INT BottomRect)
{
PROSRGNDATA pRgn;
PREGION prgn;
pRgn = (PROSRGNDATA)GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_REGION);
if (!pRgn)
{
return NULL;
}
pRgn->Buffer = &pRgn->rdh.rcBound;
REGION_SetRectRgn(pRgn, LeftRect, TopRect, RightRect, BottomRect);
REGION_UnlockRgn(pRgn);
return pRgn;
/* Allocate a region, witout a handle */
prgn = (PREGION)GDIOBJ_AllocateObject(GDIObjType_RGN_TYPE, sizeof(REGION), 0);
if (!prgn)
{
return NULL;
}
/* Initialize it */
prgn->Buffer = &prgn->rdh.rcBound;
prgn->prgnattr = &prgn->rgnattr;
REGION_SetRectRgn(prgn, LeftRect, TopRect, RightRect, BottomRect);
return prgn;
}
HRGN
FASTCALL
IntSysCreateRectRgn(INT LeftRect, INT TopRect, INT RightRect, INT BottomRect)
{
PROSRGNDATA pRgn = IntSysCreateRectpRgn(LeftRect,TopRect,RightRect,BottomRect);
return (pRgn ? pRgn->BaseObject.hHmgr : NULL);
PREGION prgn;
HRGN hrgn;
/* Allocate a region, witout a handle */
prgn = (PREGION)GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_REGION, sizeof(REGION));
if (!prgn)
{
return NULL;
}
/* Initialize it */
prgn->Buffer = &prgn->rdh.rcBound;
REGION_SetRectRgn(prgn, LeftRect, TopRect, RightRect, BottomRect);
hrgn = prgn->BaseObject.hHmgr;
prgn->prgnattr = &prgn->rgnattr;
REGION_UnlockRgn(prgn);
return hrgn;
}
BOOL INTERNAL_CALL
REGION_Cleanup(PVOID ObjectBody)
{
PROSRGNDATA pRgn = (PROSRGNDATA)ObjectBody;
PPROCESSINFO ppi = PsGetCurrentProcessWin32Process();
ASSERT(ppi);
ASSERT(pRgn->prgnattr);
if (pRgn->prgnattr != &pRgn->rgnattr)
GdiPoolFree(ppi->pPoolRgnAttr, pRgn->prgnattr);
if (pRgn->Buffer && pRgn->Buffer != &pRgn->rdh.rcBound)
ExFreePoolWithTag(pRgn->Buffer, TAG_REGION);
return TRUE;
}
// use REGION_FreeRgnByHandle(hRgn); for systems regions.
VOID FASTCALL
REGION_Delete(PROSRGNDATA pRgn)
{
if ( pRgn == prgnDefault) return;
REGION_FreeRgn(pRgn);
GDIOBJ_vDeleteObject(&pRgn->BaseObject);
}
VOID FASTCALL
@@ -2298,28 +2355,27 @@ BOOL
FASTCALL
IntGdiSetRegionOwner(HRGN hRgn, DWORD OwnerMask)
{
INT Index;
PGDI_TABLE_ENTRY Entry;
/*
System Regions:
These regions do not use attribute sections and when allocated, use gdiobj
level functions.
*/
// FIXME! HAX!!! Remove this once we get everything right!
Index = GDI_HANDLE_GET_INDEX(hRgn);
Entry = &GdiHandleTable->Entries[Index];
if (Entry->UserData) FreeObjectAttr(Entry->UserData);
Entry->UserData = NULL;
//
if ((OwnerMask == GDI_OBJ_HMGR_PUBLIC) || OwnerMask == GDI_OBJ_HMGR_NONE)
{
return GDIOBJ_SetOwnership(hRgn, NULL);
}
if (OwnerMask == GDI_OBJ_HMGR_POWNED)
{
return GDIOBJ_SetOwnership((HGDIOBJ) hRgn, PsGetCurrentProcess() );
}
return FALSE;
PREGION prgn;
PRGN_ATTR prgnattr;
PPROCESSINFO ppi;
prgn = REGION_LockRgn(hRgn);
if (!prgn)
{
return FALSE;
}
prgnattr = GDIOBJ_pvGetObjectAttr(&prgn->BaseObject);
if (prgnattr)
{
GDIOBJ_vSetObjectAttr(&prgn->BaseObject, NULL);
prgn->prgnattr = NULL;
ppi = PsGetCurrentProcessWin32Process();
GdiPoolFree(ppi->pPoolRgnAttr, prgnattr);
}
RGNOBJAPI_Unlock(prgn);
return GreSetObjectOwner(hRgn, OwnerMask);
}
INT
@@ -2366,6 +2422,7 @@ IntGdiCombineRgn(PROSRGNDATA destRgn,
{
DPRINT1("IntGdiCombineRgn requires hSrc2 != NULL for combine mode %d!\n", CombineMode);
EngSetLastError(ERROR_INVALID_HANDLE);
ASSERT(FALSE);
}
}
}
@@ -2447,7 +2504,7 @@ IntGdiPaintRgn(
if (!REGION_LPTODP(dc, tmpVisRgn, hRgn) ||
NtGdiOffsetRgn(tmpVisRgn, dc->ptlDCOrig.x, dc->ptlDCOrig.y) == ERROR)
{
REGION_FreeRgnByHandle(tmpVisRgn);
GreDeleteObject(tmpVisRgn);
return FALSE;
}
@@ -2456,7 +2513,7 @@ IntGdiPaintRgn(
visrgn = RGNOBJAPI_Lock(tmpVisRgn, NULL);
if (visrgn == NULL)
{
REGION_FreeRgnByHandle(tmpVisRgn);
GreDeleteObject(tmpVisRgn);
return FALSE;
}
@@ -2477,7 +2534,7 @@ IntGdiPaintRgn(
0xFFFF);//FIXME:don't know what to put here
RGNOBJAPI_Unlock(visrgn);
REGION_FreeRgnByHandle(tmpVisRgn);
GreDeleteObject(tmpVisRgn);
// Fill the region
return bRet;
@@ -3271,46 +3328,55 @@ IntRectInRegion(
//
INT
APIENTRY
NtGdiCombineRgn(HRGN hDest,
HRGN hSrc1,
HRGN hSrc2,
INT CombineMode)
NtGdiCombineRgn(
IN HRGN hrgnDst,
IN HRGN hrgnSrc1,
IN HRGN hrgnSrc2,
IN INT iMode)
{
INT result = ERROR;
PROSRGNDATA destRgn, src1Rgn, src2Rgn = NULL;
HRGN ahrgn[3];
PREGION aprgn[3];
INT iResult;
if ( CombineMode > RGN_COPY && CombineMode < RGN_AND)
{
EngSetLastError(ERROR_INVALID_PARAMETER);
return ERROR;
}
if (iMode < RGN_AND || iMode > RGN_COPY)
{
EngSetLastError(ERROR_INVALID_PARAMETER);
return ERROR;
}
destRgn = RGNOBJAPI_Lock(hDest, NULL);
if (!destRgn)
{
EngSetLastError(ERROR_INVALID_HANDLE);
return ERROR;
}
if (!hrgnDst || !hrgnSrc1 || (iMode != RGN_COPY && !hrgnSrc2))
{
DPRINT1("NtGdiCombineRgn: %p, %p, %p, %d\n",
hrgnDst, hrgnSrc1, hrgnSrc2, iMode);
EngSetLastError(ERROR_INVALID_PARAMETER);
return ERROR;
}
src1Rgn = RGNOBJAPI_Lock(hSrc1, NULL);
if (!src1Rgn)
{
RGNOBJAPI_Unlock(destRgn);
EngSetLastError(ERROR_INVALID_HANDLE);
return ERROR;
}
/* Lock all regions */
ahrgn[0] = hrgnDst;
ahrgn[1] = hrgnSrc1;
ahrgn[2] = iMode != RGN_COPY ? hrgnSrc2 : NULL;
if (!GDIOBJ_bLockMultipleObjects(3, ahrgn, (PVOID*)aprgn, GDIObjType_RGN_TYPE))
{
DPRINT1("NtGdiCombineRgn: %p, %p, %p, %d\n",
hrgnDst, hrgnSrc1, hrgnSrc2, iMode);
EngSetLastError(ERROR_INVALID_PARAMETER);
return ERROR;
}
if (hSrc2)
src2Rgn = RGNOBJAPI_Lock(hSrc2, NULL);
/* HACK: Sync usermode attributes */
REGION_vSyncRegion(aprgn[0]);
REGION_vSyncRegion(aprgn[1]);
if (aprgn[2]) REGION_vSyncRegion(aprgn[2]);
result = IntGdiCombineRgn( destRgn, src1Rgn, src2Rgn, CombineMode);
/* Call the internal function */
iResult = IntGdiCombineRgn(aprgn[0], aprgn[1], aprgn[2], iMode);
if (src2Rgn)
RGNOBJAPI_Unlock(src2Rgn);
RGNOBJAPI_Unlock(src1Rgn);
RGNOBJAPI_Unlock(destRgn);
return result;
/* Cleanup and return */
REGION_UnlockRgn(aprgn[0]);
REGION_UnlockRgn(aprgn[1]);
if (aprgn[2]) REGION_UnlockRgn(aprgn[2]);
return iResult;
}
HRGN
@@ -3678,13 +3744,13 @@ NtGdiFrameRgn(
}
if (!REGION_CreateFrameRgn(FrameRgn, hRgn, Width, Height))
{
REGION_FreeRgnByHandle(FrameRgn);
GreDeleteObject(FrameRgn);
return FALSE;
}
Ret = NtGdiFillRgn(hDC, FrameRgn, hBrush);
REGION_FreeRgnByHandle(FrameRgn);
GreDeleteObject(FrameRgn);
return Ret;
}
@@ -182,8 +182,9 @@
<file>font.c</file>
<file>freetype.c</file>
<file>gdibatch.c</file>
<file>gdiobj.c</file>
<file>gdidbg.c</file>
<file>gdiobj.c</file>
<file>gdipool.c</file>
<file>icm.c</file>
<file>line.c</file>
<file>metafile.c</file>