Something went wrong. Try again.
Reactos
Something went wrong. Try again.
13 kB · 527 lines
C++
at master
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528////////////////////////////////////////////////////////////////////// Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine// All rights reserved// This file was released under the GPLv2 on June 2015.////////////////////////////////////////////////////////////////////#include "udffs.h"#if defined(UDF_DBG) || defined(PRINT_ALWAYS)
//#define TRACK_RESOURCES//#define TRACK_REF_COUNTERS
ULONG ResCounter = 0;ULONG AcqCounter = 0;ULONG UdfTimeStamp = -1;
BOOLEANUDFDebugAcquireResourceSharedLite( IN PERESOURCE Resource, IN BOOLEAN Wait, ULONG BugCheckId, ULONG Line) { ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);#ifdef TRACK_RESOURCES UDFPrint(("Res:Sha:Try:Resource:%x:BugCheckId:%x:Line:%d:ThId:%x\n",Resource, BugCheckId,Line,PsGetCurrentThread()));#endif
BOOLEAN Success;
#ifdef USE_DLD
if (Wait) { DLDAcquireShared(Resource, BugCheckId, Line,FALSE); Success = TRUE; } else { Success = ExAcquireResourceSharedLite(Resource,Wait); }
#else
Success = ExAcquireResourceSharedLite(Resource,Wait);
#endif // USE_DLD
if(Success) {#ifdef TRACK_RESOURCES UDFPrint(("Res:Sha:Ok:Resource:%x:BugCheckId:%x:Line:%d:ThId:%x\n",Resource, BugCheckId,Line,PsGetCurrentThread()));#endif AcqCounter++; return Success; }#ifdef TRACK_RESOURCES UDFPrint(("Res:Sha:Fail:Resource:%x:BugCheckId:%x:Line:%d:ThId:%x\n",Resource, BugCheckId,Line,PsGetCurrentThread()));#endif return FALSE;}
BOOLEANUDFDebugAcquireSharedStarveExclusive( IN PERESOURCE Resource, IN BOOLEAN Wait, ULONG BugCheckId, ULONG Line) { ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);#ifdef TRACK_RESOURCES UDFPrint(("Res:Sha*:Try:Resource:%x:BugCheckId:%x:Line:%d:ThId:%x\n",Resource, BugCheckId,Line,PsGetCurrentThread()));#endif
BOOLEAN Success;
#ifdef USE_DLD
if (Wait) { DLDAcquireShared(Resource, BugCheckId, Line,FALSE); Success = TRUE; } else { Success = ExAcquireResourceSharedLite(Resource,Wait); }
#else
Success = ExAcquireResourceSharedLite(Resource,Wait);
#endif // USE_DLD
if(Success) {#ifdef TRACK_RESOURCES UDFPrint(("Res:Sha*:Ok:Resource:%x:BugCheckId:%x:Line:%d:ThId:%x\n",Resource, BugCheckId,Line,PsGetCurrentThread()));#endif AcqCounter++; return Success; }#ifdef TRACK_RESOURCES UDFPrint(("Res:Sha*:Fail:Resource:%x:BugCheckId:%x:Line:%d:ThId:%x\n",Resource, BugCheckId,Line,PsGetCurrentThread()));#endif return FALSE;}
BOOLEANUDFDebugAcquireResourceExclusiveLite( IN PERESOURCE Resource, IN BOOLEAN Wait, ULONG BugCheckId, ULONG Line) { ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);#ifdef TRACK_RESOURCES UDFPrint(("Res:Exc:Try:Resource:%x:BugCheckId:%x:Line:%d:ThId:%x\n",Resource, BugCheckId,Line,PsGetCurrentThread()));#endif
BOOLEAN Success;
#ifdef USE_DLD
if (Wait) { DLDAcquireExclusive(Resource, BugCheckId, Line); Success = TRUE; } else { Success = ExAcquireResourceExclusiveLite(Resource,Wait); }
#else
Success = ExAcquireResourceExclusiveLite(Resource,Wait);
#endif // USE_DLD
if(Success) {#ifdef TRACK_RESOURCES UDFPrint(("Res:Exc:OK:Resource:%x:BugCheckId:%x:Line:%d:ThId:%x\n",Resource, BugCheckId,Line,PsGetCurrentThread()));#endif AcqCounter++; return Success; }#ifdef TRACK_RESOURCES UDFPrint(("Res:Exc:Fail:Resource:%x:BugCheckId:%x:Line:%d:ThId:%x\n",Resource, BugCheckId,Line,PsGetCurrentThread()));#endif// BrutePoint(); return FALSE;
}
VOIDUDFDebugReleaseResourceForThreadLite( IN PERESOURCE Resource, IN ERESOURCE_THREAD ResourceThreadId, ULONG BugCheckId, ULONG Line ){ ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);#ifdef TRACK_RESOURCES UDFPrint(("Res:Free:Try:Resource:%x:BugCheckId:%x:Line:%d:ThId:%x\n",Resource, BugCheckId,Line,PsGetCurrentThread()));#endif ExReleaseResourceForThreadLite(Resource, ResourceThreadId);#ifdef TRACK_RESOURCES UDFPrint(("Res:Free:Ok:Resource:%x:BugCheckId:%x:Line:%d:ThId:%x\n",Resource, BugCheckId,Line,ResourceThreadId));#endif AcqCounter--;}
VOIDUDFDebugDeleteResource( IN PERESOURCE Resource, IN ERESOURCE_THREAD ResourceThreadId, ULONG BugCheckId, ULONG Line ){ ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);#ifdef TRACK_RESOURCES UDFPrint(("Res:Del:Try:Resource:%x:BugCheckId:%x:Line:%d:ThId:%x\n",Resource, BugCheckId,Line,ResourceThreadId));#endif _SEH2_TRY { ASSERT((*((PULONG)Resource))); ASSERT((*(((PULONG)Resource)+1))); ExDeleteResourceLite(Resource); RtlZeroMemory(Resource, sizeof(ERESOURCE)); } _SEH2_EXCEPT (EXCEPTION_EXECUTE_HANDLER) { BrutePoint(); } _SEH2_END;#ifdef TRACK_RESOURCES UDFPrint(("Res:Del:Ok:Resource:%x:BugCheckId:%x:Line:%d:ThId:%x\n",Resource, BugCheckId,Line,ResourceThreadId));#endif ResCounter--;}
NTSTATUSUDFDebugInitializeResourceLite( IN PERESOURCE Resource, IN ERESOURCE_THREAD ResourceThreadId, ULONG BugCheckId, ULONG Line ){ ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL); NTSTATUS RC;#ifdef TRACK_RESOURCES UDFPrint(("Res:Ini:Try:Resource:%x:BugCheckId:%x:Line:%d:ThId:%x\n",Resource, BugCheckId,Line,ResourceThreadId));#endif ASSERT(!(*((PULONG)Resource))); ASSERT(!(*(((PULONG)Resource)+1))); RC = ExInitializeResourceLite(Resource);#ifdef TRACK_RESOURCES UDFPrint(("Res:Ini:Ok:Resource:%x:BugCheckId:%x:Line:%d:ThId:%x\n",Resource, BugCheckId,Line,ResourceThreadId));#endif if(NT_SUCCESS(RC)) { ResCounter++; } return RC;}
VOIDUDFDebugConvertExclusiveToSharedLite( IN PERESOURCE Resource, IN ERESOURCE_THREAD ResourceThreadId, ULONG BugCheckId, ULONG Line ){ ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);#ifdef TRACK_RESOURCES UDFPrint(("Res:2Sha:Try:Resource:%x:BugCheckId:%x:Line:%d:ThId:%x\n",Resource, BugCheckId,Line,ResourceThreadId));#endif ExConvertExclusiveToSharedLite(Resource);#ifdef TRACK_RESOURCES UDFPrint(("Res:2Sha:Ok:Resource:%x:BugCheckId:%x:Line:%d:ThId:%x\n",Resource, BugCheckId,Line,ResourceThreadId));#endif}
BOOLEANUDFDebugAcquireSharedWaitForExclusive( IN PERESOURCE Resource, IN BOOLEAN Wait, ULONG BugCheckId, ULONG Line) { ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);#ifdef TRACK_RESOURCES UDFPrint(("Res:Sha*:Try:Resource:%x:BugCheckId:%x:Line:%d:ThId:%x\n",Resource, BugCheckId,Line,PsGetCurrentThread()));#endif
BOOLEAN Success;
#ifdef USE_DLD
if (Wait) { DLDAcquireShared(Resource, BugCheckId, Line,TRUE); Success = TRUE; } else { Success = ExAcquireSharedWaitForExclusive(Resource,Wait); }
#else
Success = ExAcquireSharedWaitForExclusive(Resource,Wait);
#endif // USE_DLD
if(Success) {#ifdef TRACK_RESOURCES UDFPrint(("Res:Sha*:OK:Resource:%x:BugCheckId:%x:Line:%d:ThId:%x\n",Resource, BugCheckId,Line,PsGetCurrentThread()));#endif return Success; }#ifdef TRACK_RESOURCES UDFPrint(("Res:Sha*:Fail:Resource:%x:BugCheckId:%x:Line:%d:ThId:%x\n",Resource, BugCheckId,Line,PsGetCurrentThread()));#endif// BrutePoint(); return FALSE;
}
LONGUDFDebugInterlockedIncrement( IN PLONG addr, ULONG BugCheckId, ULONG Line){#ifdef TRACK_REF_COUNTERS LONG a; a = InterlockedIncrement(addr); UDFPrint(("ThId:%x:Ilck:Inc:FileId:%x:Line:%d:Ref:%x:Val:%x:%x\n", PsGetCurrentThread(),BugCheckId,Line,addr,a-1,a)); return a;#else return InterlockedIncrement(addr);#endif}
LONGUDFDebugInterlockedDecrement( IN PLONG addr, ULONG BugCheckId, ULONG Line){#ifdef TRACK_REF_COUNTERS LONG a; a = InterlockedDecrement(addr); UDFPrint(("ThId:%x:Ilck:Dec:FileId:%x:Line:%d:Ref:%x:Val:%x:%x\n", PsGetCurrentThread(),BugCheckId,Line,addr,a+1,a)); return a;#else return InterlockedDecrement(addr);#endif}
LONGUDFDebugInterlockedExchangeAdd( IN PLONG addr, IN LONG i, ULONG BugCheckId, ULONG Line){#ifdef TRACK_REF_COUNTERS LONG a; a = InterlockedExchangeAdd(addr,i); UDFPrint(("ThId:%x:Ilck:Add:FileId:%x:Line:%d:Ref:%x:Val:%x:%x\n", PsGetCurrentThread(),BugCheckId,Line,addr,a,a+i)); return a;#else return InterlockedExchangeAdd(addr,i);#endif}
#define MAX_MEM_DEBUG_DESCRIPTORS 8192
typedef struct _MEM_DESC { ULONG Length; PCHAR Addr;#ifdef TRACK_SYS_ALLOC_CALLERS ULONG SrcId; ULONG SrcLine;#endif //TRACK_SYS_ALLOC_CALLERS POOL_TYPE Type;} MEM_DESC, *PMEM_DESC;
MEM_DESC MemDesc[MAX_MEM_DEBUG_DESCRIPTORS];ULONG cur_max = 0;ULONG AllocCountPaged = 0;ULONG AllocCountNPaged = 0;ULONG MemDescInited = 0;
PVOIDDebugAllocatePool( POOL_TYPE Type, ULONG size#ifdef TRACK_SYS_ALLOC_CALLERS , ULONG SrcId, ULONG SrcLine#endif //TRACK_SYS_ALLOC_CALLERS) { ULONG i;// UDFPrint(("SysAllocated: %x\n",AllocCount)); if(!MemDescInited) { RtlZeroMemory(&MemDesc, sizeof(MemDesc)); MemDescInited = 1; } for (i=0;i<cur_max;i++) { if (MemDesc[i].Addr==NULL) { MemDesc[i].Addr = (PCHAR)ExAllocatePoolWithTag(Type, (size), 'Fnwd'); // dwnF
ASSERT(MemDesc[i].Addr);
if(MemDesc[i].Addr) { if(Type == PagedPool) { AllocCountPaged += (size+7) & ~7; } else { AllocCountNPaged += (size+7) & ~7; } }
MemDesc[i].Length = size; MemDesc[i].Type = Type;#ifdef TRACK_SYS_ALLOC_CALLERS MemDesc[i].SrcId = SrcId; MemDesc[i].SrcLine = SrcLine;#endif //TRACK_SYS_ALLOC_CALLERS return MemDesc[i].Addr; } } if(cur_max == MAX_MEM_DEBUG_DESCRIPTORS) { UDFPrint(("Debug memory descriptor list full\n")); return ExAllocatePoolWithTag(Type, (size) , 'Fnwd'); }
MemDesc[i].Addr = (PCHAR)ExAllocatePoolWithTag(Type, (size) , 'Fnwd');
if(MemDesc[i].Addr) { if(Type == PagedPool) { AllocCountPaged += (size+7) & ~7; } else { AllocCountNPaged += (size+7) & ~7; } }
MemDesc[i].Length = (size);#ifdef TRACK_SYS_ALLOC_CALLERS MemDesc[i].SrcId = SrcId; MemDesc[i].SrcLine = SrcLine;#endif //TRACK_SYS_ALLOC_CALLERS MemDesc[i].Type = Type; cur_max++; return MemDesc[cur_max-1].Addr;
}
VOID DebugFreePool(PVOID addr) { ULONG i;
ASSERT(addr);
for (i=0;i<cur_max;i++) { if (MemDesc[i].Addr == addr) {
if(MemDesc[i].Type == PagedPool) { AllocCountPaged -= (MemDesc[i].Length+7) & ~7; } else { AllocCountNPaged -= (MemDesc[i].Length+7) & ~7; }
MemDesc[i].Addr = NULL; MemDesc[i].Length = 0;#ifdef TRACK_SYS_ALLOC_CALLERS MemDesc[i].SrcId = 0; MemDesc[i].SrcLine = 0;#endif //TRACK_SYS_ALLOC_CALLERS goto not_bug; } } if (i==cur_max && cur_max != MAX_MEM_DEBUG_DESCRIPTORS) { UDFPrint(("Buug! - Deallocating nonallocated block\n")); return; }not_bug:// UDFPrint(("SysAllocated: %x\n",AllocCount)); ExFreePool(addr);}
NTSTATUSUDFWaitForSingleObject( IN PLONG Object, IN PLARGE_INTEGER Timeout OPTIONAL ){ UDFPrint(("UDFWaitForSingleObject\n")); LARGE_INTEGER LocalTimeout; LARGE_INTEGER delay; delay.QuadPart = -(WAIT_FOR_XXX_EMU_DELAY);
if(Timeout && (Timeout->QuadPart)) LocalTimeout = *Timeout; else LocalTimeout.QuadPart = 0x7FFFFFFFFFFFFFFFLL;
UDFPrint(("SignalState %x\n", *Object)); if(!Object) return STATUS_INVALID_PARAMETER; if((*Object)) return STATUS_SUCCESS; while(LocalTimeout.QuadPart>0 && !(*Object) ) { UDFPrint(("SignalState %x\n", *Object)); // Stall for a while. KeDelayExecutionThread(KernelMode, FALSE, &delay); LocalTimeout.QuadPart -= WAIT_FOR_XXX_EMU_DELAY; } return STATUS_SUCCESS;} // end UDFWaitForSingleObject()
NTSTATUSDbgWaitForSingleObject_( IN PVOID Object, IN PLARGE_INTEGER Timeout OPTIONAL ){ PLARGE_INTEGER to; LARGE_INTEGER dto;// LARGE_INTEGER cto; NTSTATUS RC; ULONG c = 20;
dto.QuadPart = -5LL*1000000LL*10LL; // 5 sec// cto.QuadPart = Timeout->QuadPart; if(Timeout) { if(dto.QuadPart > Timeout->QuadPart) { to = Timeout; } else { to = &dto; } } else { to = &dto; }
for(; c--; c) { RC = KeWaitForSingleObject(Object, Executive, KernelMode, FALSE, to); if(RC == STATUS_SUCCESS) break; UDFPrint(("No response ?\n")); if(c<2) BrutePoint(); } return RC;}#endif // UDF_DBG