1 ////////////////////////////////////////////////////////////////////
2 // Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
4 // This file was released under the GPLv2 on June 2015.
5 ////////////////////////////////////////////////////////////////////
7 #if defined(UDF_DBG) || defined(PRINT_ALWAYS)
9 //#define TRACK_RESOURCES
10 //#define TRACK_REF_COUNTERS
14 ULONG UdfTimeStamp
= -1;
17 UDFDebugAcquireResourceSharedLite(
18 IN PERESOURCE Resource
,
23 ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL
);
24 #ifdef TRACK_RESOURCES
25 UDFPrint(("Res:Sha:Try:Resource:%x:BugCheckId:%x:Line:%d:ThId:%x\n",Resource
,
26 BugCheckId
,Line
,PsGetCurrentThread()));
34 DLDAcquireShared(Resource
, BugCheckId
, Line
,FALSE
);
37 Success
= ExAcquireResourceSharedLite(Resource
,Wait
);
42 Success
= ExAcquireResourceSharedLite(Resource
,Wait
);
47 #ifdef TRACK_RESOURCES
48 UDFPrint(("Res:Sha:Ok:Resource:%x:BugCheckId:%x:Line:%d:ThId:%x\n",Resource
,
49 BugCheckId
,Line
,PsGetCurrentThread()));
54 #ifdef TRACK_RESOURCES
55 UDFPrint(("Res:Sha:Fail:Resource:%x:BugCheckId:%x:Line:%d:ThId:%x\n",Resource
,
56 BugCheckId
,Line
,PsGetCurrentThread()));
62 UDFDebugAcquireSharedStarveExclusive(
63 IN PERESOURCE Resource
,
68 ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL
);
69 #ifdef TRACK_RESOURCES
70 UDFPrint(("Res:Sha*:Try:Resource:%x:BugCheckId:%x:Line:%d:ThId:%x\n",Resource
,
71 BugCheckId
,Line
,PsGetCurrentThread()));
79 DLDAcquireShared(Resource
, BugCheckId
, Line
,FALSE
);
82 Success
= ExAcquireResourceSharedLite(Resource
,Wait
);
87 Success
= ExAcquireResourceSharedLite(Resource
,Wait
);
92 #ifdef TRACK_RESOURCES
93 UDFPrint(("Res:Sha*:Ok:Resource:%x:BugCheckId:%x:Line:%d:ThId:%x\n",Resource
,
94 BugCheckId
,Line
,PsGetCurrentThread()));
99 #ifdef TRACK_RESOURCES
100 UDFPrint(("Res:Sha*:Fail:Resource:%x:BugCheckId:%x:Line:%d:ThId:%x\n",Resource
,
101 BugCheckId
,Line
,PsGetCurrentThread()));
107 UDFDebugAcquireResourceExclusiveLite(
108 IN PERESOURCE Resource
,
113 ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL
);
114 #ifdef TRACK_RESOURCES
115 UDFPrint(("Res:Exc:Try:Resource:%x:BugCheckId:%x:Line:%d:ThId:%x\n",Resource
,
116 BugCheckId
,Line
,PsGetCurrentThread()));
125 DLDAcquireExclusive(Resource
, BugCheckId
, Line
);
128 Success
= ExAcquireResourceExclusiveLite(Resource
,Wait
);
133 Success
= ExAcquireResourceExclusiveLite(Resource
,Wait
);
140 #ifdef TRACK_RESOURCES
141 UDFPrint(("Res:Exc:OK:Resource:%x:BugCheckId:%x:Line:%d:ThId:%x\n",Resource
,
142 BugCheckId
,Line
,PsGetCurrentThread()));
147 #ifdef TRACK_RESOURCES
148 UDFPrint(("Res:Exc:Fail:Resource:%x:BugCheckId:%x:Line:%d:ThId:%x\n",Resource
,
149 BugCheckId
,Line
,PsGetCurrentThread()));
157 UDFDebugReleaseResourceForThreadLite(
158 IN PERESOURCE Resource
,
159 IN ERESOURCE_THREAD ResourceThreadId
,
164 ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL
);
165 #ifdef TRACK_RESOURCES
166 UDFPrint(("Res:Free:Try:Resource:%x:BugCheckId:%x:Line:%d:ThId:%x\n",Resource
,
167 BugCheckId
,Line
,PsGetCurrentThread()));
169 ExReleaseResourceForThreadLite(Resource
, ResourceThreadId
);
170 #ifdef TRACK_RESOURCES
171 UDFPrint(("Res:Free:Ok:Resource:%x:BugCheckId:%x:Line:%d:ThId:%x\n",Resource
,
172 BugCheckId
,Line
,ResourceThreadId
));
178 UDFDebugDeleteResource(
179 IN PERESOURCE Resource
,
180 IN ERESOURCE_THREAD ResourceThreadId
,
185 ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL
);
186 #ifdef TRACK_RESOURCES
187 UDFPrint(("Res:Del:Try:Resource:%x:BugCheckId:%x:Line:%d:ThId:%x\n",Resource
,
188 BugCheckId
,Line
,ResourceThreadId
));
191 ASSERT((*((PULONG
)Resource
)));
192 ASSERT((*(((PULONG
)Resource
)+1)));
193 ExDeleteResourceLite(Resource
);
194 RtlZeroMemory(Resource
, sizeof(ERESOURCE
));
195 } _SEH2_EXCEPT (EXCEPTION_EXECUTE_HANDLER
) {
198 #ifdef TRACK_RESOURCES
199 UDFPrint(("Res:Del:Ok:Resource:%x:BugCheckId:%x:Line:%d:ThId:%x\n",Resource
,
200 BugCheckId
,Line
,ResourceThreadId
));
206 UDFDebugInitializeResourceLite(
207 IN PERESOURCE Resource
,
208 IN ERESOURCE_THREAD ResourceThreadId
,
213 ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL
);
215 #ifdef TRACK_RESOURCES
216 UDFPrint(("Res:Ini:Try:Resource:%x:BugCheckId:%x:Line:%d:ThId:%x\n",Resource
,
217 BugCheckId
,Line
,ResourceThreadId
));
219 ASSERT(!(*((PULONG
)Resource
)));
220 ASSERT(!(*(((PULONG
)Resource
)+1)));
221 RC
= ExInitializeResourceLite(Resource
);
222 #ifdef TRACK_RESOURCES
223 UDFPrint(("Res:Ini:Ok:Resource:%x:BugCheckId:%x:Line:%d:ThId:%x\n",Resource
,
224 BugCheckId
,Line
,ResourceThreadId
));
233 UDFDebugConvertExclusiveToSharedLite(
234 IN PERESOURCE Resource
,
235 IN ERESOURCE_THREAD ResourceThreadId
,
240 ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL
);
241 #ifdef TRACK_RESOURCES
242 UDFPrint(("Res:2Sha:Try:Resource:%x:BugCheckId:%x:Line:%d:ThId:%x\n",Resource
,
243 BugCheckId
,Line
,ResourceThreadId
));
245 ExConvertExclusiveToSharedLite(Resource
);
246 #ifdef TRACK_RESOURCES
247 UDFPrint(("Res:2Sha:Ok:Resource:%x:BugCheckId:%x:Line:%d:ThId:%x\n",Resource
,
248 BugCheckId
,Line
,ResourceThreadId
));
253 UDFDebugAcquireSharedWaitForExclusive(
254 IN PERESOURCE Resource
,
259 ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL
);
260 #ifdef TRACK_RESOURCES
261 UDFPrint(("Res:Sha*:Try:Resource:%x:BugCheckId:%x:Line:%d:ThId:%x\n",Resource
,
262 BugCheckId
,Line
,PsGetCurrentThread()));
270 DLDAcquireShared(Resource
, BugCheckId
, Line
,TRUE
);
273 Success
= ExAcquireSharedWaitForExclusive(Resource
,Wait
);
278 Success
= ExAcquireSharedWaitForExclusive(Resource
,Wait
);
284 #ifdef TRACK_RESOURCES
285 UDFPrint(("Res:Sha*:OK:Resource:%x:BugCheckId:%x:Line:%d:ThId:%x\n",Resource
,
286 BugCheckId
,Line
,PsGetCurrentThread()));
290 #ifdef TRACK_RESOURCES
291 UDFPrint(("Res:Sha*:Fail:Resource:%x:BugCheckId:%x:Line:%d:ThId:%x\n",Resource
,
292 BugCheckId
,Line
,PsGetCurrentThread()));
301 UDFDebugInterlockedIncrement(
306 #ifdef TRACK_REF_COUNTERS
308 a
= InterlockedIncrement(addr
);
309 UDFPrint(("ThId:%x:Ilck:Inc:FileId:%x:Line:%d:Ref:%x:Val:%x:%x\n",
310 PsGetCurrentThread(),BugCheckId
,Line
,addr
,a
-1,a
));
313 return InterlockedIncrement(addr
);
318 UDFDebugInterlockedDecrement(
323 #ifdef TRACK_REF_COUNTERS
325 a
= InterlockedDecrement(addr
);
326 UDFPrint(("ThId:%x:Ilck:Dec:FileId:%x:Line:%d:Ref:%x:Val:%x:%x\n",
327 PsGetCurrentThread(),BugCheckId
,Line
,addr
,a
+1,a
));
330 return InterlockedDecrement(addr
);
335 UDFDebugInterlockedExchangeAdd(
341 #ifdef TRACK_REF_COUNTERS
343 a
= InterlockedExchangeAdd(addr
,i
);
344 UDFPrint(("ThId:%x:Ilck:Add:FileId:%x:Line:%d:Ref:%x:Val:%x:%x\n",
345 PsGetCurrentThread(),BugCheckId
,Line
,addr
,a
,a
+i
));
348 return InterlockedExchangeAdd(addr
,i
);
352 #define MAX_MEM_DEBUG_DESCRIPTORS 8192
354 typedef struct _MEM_DESC
{
357 #ifdef TRACK_SYS_ALLOC_CALLERS
360 #endif //TRACK_SYS_ALLOC_CALLERS
362 } MEM_DESC
, *PMEM_DESC
;
365 MEM_DESC MemDesc
[MAX_MEM_DEBUG_DESCRIPTORS
];
367 ULONG AllocCountPaged
= 0;
368 ULONG AllocCountNPaged
= 0;
369 ULONG MemDescInited
= 0;
375 #ifdef TRACK_SYS_ALLOC_CALLERS
378 #endif //TRACK_SYS_ALLOC_CALLERS
381 // UDFPrint(("SysAllocated: %x\n",AllocCount));
383 RtlZeroMemory(&MemDesc
, sizeof(MemDesc
));
386 for (i
=0;i
<cur_max
;i
++) {
387 if (MemDesc
[i
].Addr
==NULL
) {
388 MemDesc
[i
].Addr
= (PCHAR
)ExAllocatePoolWithTag(Type
, (size
), 'Fnwd'); // dwnF
390 ASSERT(MemDesc
[i
].Addr
);
392 if(MemDesc
[i
].Addr
) {
393 if(Type
== PagedPool
) {
394 AllocCountPaged
+= (size
+7) & ~7;
396 AllocCountNPaged
+= (size
+7) & ~7;
400 MemDesc
[i
].Length
= size
;
401 MemDesc
[i
].Type
= Type
;
402 #ifdef TRACK_SYS_ALLOC_CALLERS
403 MemDesc
[i
].SrcId
= SrcId
;
404 MemDesc
[i
].SrcLine
= SrcLine
;
405 #endif //TRACK_SYS_ALLOC_CALLERS
406 return MemDesc
[i
].Addr
;
409 if(cur_max
== MAX_MEM_DEBUG_DESCRIPTORS
) {
410 UDFPrint(("Debug memory descriptor list full\n"));
411 return ExAllocatePoolWithTag(Type
, (size
) , 'Fnwd');
414 MemDesc
[i
].Addr
= (PCHAR
)ExAllocatePoolWithTag(Type
, (size
) , 'Fnwd');
416 if(MemDesc
[i
].Addr
) {
417 if(Type
== PagedPool
) {
418 AllocCountPaged
+= (size
+7) & ~7;
420 AllocCountNPaged
+= (size
+7) & ~7;
424 MemDesc
[i
].Length
= (size
);
425 #ifdef TRACK_SYS_ALLOC_CALLERS
426 MemDesc
[i
].SrcId
= SrcId
;
427 MemDesc
[i
].SrcLine
= SrcLine
;
428 #endif //TRACK_SYS_ALLOC_CALLERS
429 MemDesc
[i
].Type
= Type
;
431 return MemDesc
[cur_max
-1].Addr
;
435 VOID
DebugFreePool(PVOID addr
) {
440 for (i
=0;i
<cur_max
;i
++) {
441 if (MemDesc
[i
].Addr
== addr
) {
443 if(MemDesc
[i
].Type
== PagedPool
) {
444 AllocCountPaged
-= (MemDesc
[i
].Length
+7) & ~7;
446 AllocCountNPaged
-= (MemDesc
[i
].Length
+7) & ~7;
449 MemDesc
[i
].Addr
= NULL
;
450 MemDesc
[i
].Length
= 0;
451 #ifdef TRACK_SYS_ALLOC_CALLERS
452 MemDesc
[i
].SrcId
= 0;
453 MemDesc
[i
].SrcLine
= 0;
454 #endif //TRACK_SYS_ALLOC_CALLERS
458 if (i
==cur_max
&& cur_max
!= MAX_MEM_DEBUG_DESCRIPTORS
) {
459 UDFPrint(("Buug! - Deallocating nonallocated block\n"));
463 // UDFPrint(("SysAllocated: %x\n",AllocCount));
468 UDFWaitForSingleObject(
470 IN PLARGE_INTEGER Timeout OPTIONAL
473 UDFPrint(("UDFWaitForSingleObject\n"));
474 LARGE_INTEGER LocalTimeout
;
476 delay
.QuadPart
= -(WAIT_FOR_XXX_EMU_DELAY
);
478 if(Timeout
&& (Timeout
->QuadPart
)) LocalTimeout
= *Timeout
;
479 else LocalTimeout
.QuadPart
= 0x7FFFFFFFFFFFFFFFLL
;
481 UDFPrint(("SignalState %x\n", *Object
));
482 if(!Object
) return STATUS_INVALID_PARAMETER
;
483 if((*Object
)) return STATUS_SUCCESS
;
484 while(LocalTimeout
.QuadPart
>0 && !(*Object
) ) {
485 UDFPrint(("SignalState %x\n", *Object
));
486 // Stall for a while.
487 KeDelayExecutionThread(KernelMode
, FALSE
, &delay
);
488 LocalTimeout
.QuadPart
-= WAIT_FOR_XXX_EMU_DELAY
;
490 return STATUS_SUCCESS
;
491 } // end UDFWaitForSingleObject()
494 DbgWaitForSingleObject_(
496 IN PLARGE_INTEGER Timeout OPTIONAL
501 // LARGE_INTEGER cto;
505 dto
.QuadPart
= -5LL*1000000LL*10LL; // 5 sec
506 // cto.QuadPart = Timeout->QuadPart;
508 if(dto
.QuadPart
> Timeout
->QuadPart
) {
518 RC
= KeWaitForSingleObject(Object
, Executive
, KernelMode
, FALSE
, to
);
519 if(RC
== STATUS_SUCCESS
)
521 UDFPrint(("No response ?\n"));