mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-03 12:23:25 +00:00
[WIN32K]
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:
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user