2011-02-18 14:35:44 +00:00
|
|
|
#pragma once
|
|
|
|
|
2015-02-20 21:25:10 +00:00
|
|
|
#define GDI_DBG_MAX_BTS 10
|
|
|
|
|
2015-09-09 14:00:43 +00:00
|
|
|
#if DBG && defined(KDBG)
|
2015-02-20 21:25:10 +00:00
|
|
|
#define ASSERT_NOGDILOCKS() GdiDbgAssertNoLocks(__FILE__,__LINE__)
|
|
|
|
#define KeRosDumpStackFrames(Frames, Count) \
|
|
|
|
KdSystemDebugControl('DsoR', (PVOID)Frames, Count, NULL, 0, NULL, KernelMode)
|
|
|
|
#else
|
|
|
|
#define ASSERT_NOGDILOCKS()
|
|
|
|
#define KeRosDumpStackFrames(Frames, Count)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
ULONG
|
|
|
|
NTAPI
|
|
|
|
DbgCaptureStackBackTace(
|
|
|
|
_Out_writes_(cFramesToCapture) PVOID* ppvFrames,
|
|
|
|
_In_ ULONG cFramesToSkip,
|
|
|
|
_In_ ULONG cFramesToCapture);
|
|
|
|
|
|
|
|
BOOL
|
|
|
|
NTAPI
|
|
|
|
DbgGdiHTIntegrityCheck(
|
|
|
|
VOID);
|
|
|
|
|
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
DbgDumpLockedGdiHandles(
|
|
|
|
VOID);
|
|
|
|
|
|
|
|
#if DBG_ENABLE_GDIOBJ_BACKTRACES
|
|
|
|
|
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
DbgDumpGdiHandleTableWithBT(VOID);
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2015-09-09 14:00:43 +00:00
|
|
|
#if defined(KDBG)
|
2015-02-20 21:25:10 +00:00
|
|
|
|
|
|
|
BOOLEAN
|
|
|
|
NTAPI
|
|
|
|
DbgGdiKdbgCliCallback(
|
|
|
|
_In_ PCHAR Command,
|
|
|
|
_In_ ULONG Argc,
|
|
|
|
_In_ PCH Argv[]);
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if DBG_ENABLE_EVENT_LOGGING
|
|
|
|
|
[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
2011-04-28 08:26:46 +00:00
|
|
|
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;
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
2015-02-20 21:25:10 +00:00
|
|
|
VOID
|
2012-10-01 23:06:32 +00:00
|
|
|
NTAPI
|
2015-02-20 21:25:10 +00:00
|
|
|
DbgDumpEventList(
|
|
|
|
_Inout_ PSLIST_HEADER pslh);
|
|
|
|
|
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
DbgLogEvent(
|
|
|
|
_Inout_ PSLIST_HEADER pslh,
|
|
|
|
_In_ LOG_EVENT_TYPE nEventType,
|
|
|
|
_In_ LPARAM lParam);
|
|
|
|
|
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
DbgCleanupEventList(
|
|
|
|
_Inout_ PSLIST_HEADER pslh);
|
|
|
|
|
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
DbgPrintEvent(
|
|
|
|
_Inout_ PLOGENTRY pLogEntry);
|
2012-10-01 23:06:32 +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
2011-04-28 08:26:46 +00:00
|
|
|
#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)
|
2015-02-20 21:25:10 +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
2011-04-28 08:26:46 +00:00
|
|
|
#else
|
2015-02-20 21:25:10 +00:00
|
|
|
|
2013-07-20 12:12:13 +00:00
|
|
|
#define DBG_LOGEVENT(pslh, type, val) ((void)(val))
|
[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
2011-04-28 08:26:46 +00:00
|
|
|
#define DBG_INITLOG(pslh)
|
|
|
|
#define DBG_DUMP_EVENT_LIST(pslh)
|
|
|
|
#define DBG_CLEANUP_EVENT_LIST(pslh)
|
2011-02-19 21:56:43 +00:00
|
|
|
|
2015-02-20 21:25:10 +00:00
|
|
|
#endif
|
2011-02-18 14:35:44 +00:00
|
|
|
|
2011-02-19 21:56:43 +00:00
|
|
|
#if DBG
|
|
|
|
void
|
|
|
|
NTAPI
|
2012-02-06 12:30:59 +00:00
|
|
|
GdiDbgPreServiceHook(ULONG ulSyscallId, PULONG_PTR pulArguments);
|
2011-02-19 21:56:43 +00:00
|
|
|
|
|
|
|
ULONG_PTR
|
|
|
|
NTAPI
|
2012-02-06 12:30:59 +00:00
|
|
|
GdiDbgPostServiceHook(ULONG ulSyscallId, ULONG_PTR ulResult);
|
2011-02-19 21:56:43 +00:00
|
|
|
|
|
|
|
#define ID_Win32PreServiceHook 'WSH0'
|
|
|
|
#define ID_Win32PostServiceHook 'WSH1'
|
|
|
|
|
2015-03-25 22:32:22 +00:00
|
|
|
#ifndef __cplusplus
|
2011-02-19 21:56:43 +00:00
|
|
|
FORCEINLINE void
|
2011-03-05 10:21:07 +00:00
|
|
|
GdiDbgAssertNoLocks(char * pszFile, ULONG nLine)
|
2011-02-19 21:56:43 +00:00
|
|
|
{
|
|
|
|
PTHREADINFO pti = (PTHREADINFO)PsGetCurrentThreadWin32Thread();
|
|
|
|
if (pti && pti->cExclusiveLocks != 0)
|
|
|
|
{
|
2014-09-22 14:33:06 +00:00
|
|
|
ULONG i;
|
2012-07-31 18:40:52 +00:00
|
|
|
DbgPrint("(%s:%lu) There are %lu exclusive locks!\n",
|
2011-02-19 21:56:43 +00:00
|
|
|
pszFile, nLine, pti->cExclusiveLocks);
|
2014-09-22 14:33:06 +00:00
|
|
|
for (i = 0; i < (GDIObjTypeTotal + 1); i++)
|
|
|
|
DbgPrint(" Type %u: %u.\n", i, pti->acExclusiveLockCount[i]);
|
2011-02-19 21:56:43 +00:00
|
|
|
ASSERT(FALSE);
|
|
|
|
}
|
|
|
|
}
|
2015-03-25 22:32:22 +00:00
|
|
|
#endif // __cplusplus
|
2011-02-19 21:56:43 +00:00
|
|
|
#endif
|
|
|
|
|
2015-02-20 21:25:10 +00:00
|
|
|
|