43fd593f364888576ec0402e0a473d8ee0992ab8
[reactos.git] / reactos / drivers / filesystems / udfs / Include / mem_tools.cpp
1 ////////////////////////////////////////////////////////////////////
2 // Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
3 // All rights reserved
4 // This file was released under the GPLv2 on June 2015.
5 ////////////////////////////////////////////////////////////////////
6
7 #ifdef MY_USE_INTERNAL_MEMMANAGER
8
9 #ifdef _X86_
10
11 __inline VOID DbgTouch(IN PVOID addr)
12 {
13 __asm {
14 mov eax,addr
15 mov al,[byte ptr eax]
16 }
17 }
18
19 #else // NO X86 optimization , use generic C/C++
20
21 __inline VOID DbgTouch(IN PVOID addr)
22 {
23 UCHAR a = ((PUCHAR)addr)[0];
24 }
25
26 #endif // _X86_
27
28 //MEM_ALLOC_DESC Allocs[MY_HEAP_MAX_BLOCKS];
29
30 MEM_FRAME_ALLOC_DESC FrameList[MY_HEAP_MAX_FRAMES];
31 #ifdef MEM_LOCK_BY_SPINLOCK
32 KSPIN_LOCK FrameLock;
33 KIRQL oldIrql;
34 #define LockMemoryManager() KeAcquireSpinLock(&FrameLock, &oldIrql)
35 #define UnlockMemoryManager() KeReleaseSpinLock(&FrameLock, oldIrql)
36 __inline
37 NTSTATUS
38 InitLockMemoryManager() {
39 KeInitializeSpinLock(&FrameLock);
40 return STATUS_SUCCESS;
41 }
42 #define DeinitLockMemoryManager() {NOTHING;}
43 #else //MEM_LOCK_BY_SPINLOCK
44 ERESOURCE FrameLock;
45 #define LockMemoryManager() ExAcquireResourceExclusiveLite(&FrameLock, TRUE)
46 #define UnlockMemoryManager() ExReleaseResourceForThreadLite(&FrameLock, ExGetCurrentResourceThread())
47 #define InitLockMemoryManager() ExInitializeResourceLite(&FrameLock)
48 #define DeinitLockMemoryManager() ExDeleteResourceLite(&FrameLock)
49 #endif //MEM_LOCK_BY_SPINLOCK
50 ULONG FrameCount;
51 ULONG LastFrame;
52 BOOLEAN MyMemInitialized = FALSE;
53
54 #define MyAllocIsFrameFree(FrameList, i) \
55 (!(FrameList[i].LastUsed || FrameList[i].FirstFree))
56
57 #ifdef UDF_DBG
58 ULONG MemTotalAllocated;
59 PCHAR BreakAddr;
60
61 VOID
62 MyAllocDumpDescr(
63 PMEM_ALLOC_DESC Allocs,
64 ULONG i
65 )
66 {
67 BOOLEAN Used;
68
69 Used = (Allocs[i].Len & MY_HEAP_FLAG_USED) ? TRUE : FALSE;
70 KdPrint(("block %x \t%s addr %x len %x \t", i, Used ? "used" : "free", Allocs[i].Addr, (Allocs[i].Len) & MY_HEAP_FLAG_LEN_MASK));
71 #ifdef MY_HEAP_TRACK_OWNERS
72 KdPrint(("src %x \t line %d \t", Allocs[i].Src, Allocs[i].Line));
73 #endif
74 #ifdef MY_HEAP_TRACK_REF
75 KdPrint(("%s%s", Used ? " " : "-", Allocs[i].Tag ? Allocs[i].Tag : ""));
76 #endif
77 KdPrint(("\n"));
78 }
79
80 //#define CHECK_ALLOC_FRAMES
81
82 #define DUMP_MEM_FRAMES
83
84 #ifdef DUMP_MEM_FRAMES
85 ULONG MyDumpMem = FALSE;
86 #endif //DUMP_MEM_FRAMES
87
88 #define DUMP_MEM_FRAMES2
89
90 //#ifdef CHECK_ALLOC_FRAMES
91 VOID
92 MyAllocDumpFrame(
93 ULONG Frame
94 )
95 {
96 ULONG i;
97 PMEM_ALLOC_DESC Allocs;
98 Allocs = FrameList[Frame].Frame;
99 ULONG k=0;
100 BOOLEAN Used;
101 #ifdef DUMP_MEM_FRAMES
102 if(!MyDumpMem)
103 #endif //DUMP_MEM_FRAMES
104 return;
105
106 KdPrint(("Dumping frame %x\n",Frame));
107 KdPrint(("FirstFree %x LastUsed %x ", FrameList[Frame].FirstFree, FrameList[Frame].LastUsed));
108 KdPrint(("Type %x\n", FrameList[Frame].Type));
109 if(Allocs) {
110 for(i=0;i< (MY_HEAP_MAX_BLOCKS/*-1*/);i++) {
111 Used = (Allocs[i].Len & MY_HEAP_FLAG_USED) ? TRUE : FALSE;
112 KdPrint(("block %x \t%s addr %x len %x \t", i, Used ? "used" : "free", Allocs[i].Addr, (Allocs[i].Len) & MY_HEAP_FLAG_LEN_MASK));
113 #ifdef MY_HEAP_TRACK_OWNERS
114 KdPrint(("src %x \t line %d \t", Allocs[i].Src, Allocs[i].Line));
115 #endif
116 #ifdef MY_HEAP_TRACK_REF
117 KdPrint(("%s%s", Used ? " " : "-", Allocs[i].Tag ? Allocs[i].Tag : ""));
118 #endif
119 KdPrint(("\n"));
120 if(!(Allocs[i].Len) && !(Allocs[i].Addr)) {
121 break;
122 }
123 if(Allocs[i].Len & MY_HEAP_FLAG_USED)
124 k += ((Allocs[i].Len) & MY_HEAP_FLAG_LEN_MASK);
125 }
126 }
127 KdPrint((" Wasted %x bytes from %x\n", MY_HEAP_FRAME_SIZE - k, MY_HEAP_FRAME_SIZE));
128 } // end MyAllocDumpFrame()
129
130 VOID
131 MyAllocDumpFrames(
132 VOID
133 )
134 {
135 ULONG i;
136
137 for(i=0;i<MY_HEAP_MAX_FRAMES; i++) {
138 if(FrameList[i].Frame) {
139 MyAllocDumpFrame(i);
140 }
141 }
142
143 KdPrint(("\n"));
144
145 for(i=0;i<MY_HEAP_MAX_FRAMES; i++) {
146 if(FrameList[i].Frame) {
147 KdPrint(("Addr %x ", FrameList[i].Frame));
148 KdPrint(("Type %x\n" , FrameList[i].Type));
149 }
150 }
151
152 } // end MyAllocDumpFrame()
153
154 VOID
155 MyAllocCheck(
156 ULONG Frame
157 )
158 {
159 ULONG i, j;
160 PMEM_ALLOC_DESC Allocs;
161 Allocs = FrameList[Frame].Frame;
162 ULONG len, addr;
163
164 for(i=0;i< (MY_HEAP_MAX_BLOCKS-1);i++) {
165 len = (Allocs[i].Len & MY_HEAP_FLAG_LEN_MASK);
166 addr = Allocs[i].Addr;
167 if( len != (Allocs[i+1].Addr - addr) ) {
168 if(Allocs[i+1].Addr) {
169 KdPrint(("ERROR! Memory block aliasing\n"));
170 KdPrint(("block %x, frame %x\n", i, Frame));
171 KdPrint(("block descriptor %x\n", &(Allocs[i]) ));
172 BrutePoint();
173 MyAllocDumpFrame(Frame);
174 }
175 }
176 #ifdef MY_HEAP_CHECK_BOUNDS
177 if(*((PULONG)(addr+len+(j*sizeof(ULONG))-MY_HEAP_CHECK_BOUNDS_BSZ)) != 0xBAADF00D) {
178 MyAllocDumpDescr(Allocs, i);
179 }
180 #endif //MY_HEAP_CHECK_BOUNDS
181 }
182 } // end MyAllocCheck()
183
184 //#endif //CHECK_ALLOC_FRAMES
185 #else
186
187 #define MyAllocDumpFrame(a) {}
188 #define MyAllocCheck(a) {}
189 #define MyAllocDumpFrames() {}
190
191 #endif // UDF_DBG
192
193 PCHAR
194 #ifndef MY_HEAP_TRACK_OWNERS
195 __fastcall
196 #endif
197 MyAllocatePoolInFrame(
198 ULONG Frame,
199 ULONG size
200 #ifdef MY_HEAP_TRACK_OWNERS
201 ,USHORT Src,
202 USHORT Line
203 #endif
204 #ifdef MY_HEAP_TRACK_REF
205 ,PCHAR Tag
206 #endif //MY_HEAP_TRACK_REF
207 )
208 {
209 ULONG addr;
210 ULONG i;
211 ULONG min_len;
212 ULONG best_i;
213 PMEM_ALLOC_DESC Allocs;
214 PMEM_ALLOC_DESC Allocs0;
215 ULONG LastUsed, FirstFree;
216 ULONG l;
217
218 #ifdef CHECK_ALLOC_FRAMES
219 MyAllocCheck(Frame);
220 #endif
221
222 if(!size) return NULL;
223 #ifdef MY_HEAP_CHECK_BOUNDS
224 size+=MY_HEAP_CHECK_BOUNDS_BSZ;
225 #endif
226
227 /* if(size == 0x70) {
228 BrutePoint();
229 }*/
230 // lock frame
231 Allocs0 = FrameList[Frame].Frame;
232 if(!Allocs0) return NULL;
233 best_i = MY_HEAP_MAX_BLOCKS;
234 min_len = 0;
235 LastUsed = FrameList[Frame].LastUsed;
236 FirstFree = FrameList[Frame].FirstFree;
237
238 if(LastUsed >= (MY_HEAP_MAX_BLOCKS-1))
239 return NULL;
240
241 for(i=FirstFree, Allocs = &(Allocs0[i]);i<=LastUsed;i++, Allocs++) {
242 if( !((l = Allocs->Len) & MY_HEAP_FLAG_USED) &&
243 ((l &= MY_HEAP_FLAG_LEN_MASK) >= size) ) {
244 // check if minimal
245 // check for first occurence
246 if(l < min_len || !min_len) {
247 min_len = l;
248 best_i = i;
249 }
250 if(l == size)
251 break;
252 }
253 }
254 // not enough resources
255 if(best_i >= MY_HEAP_MAX_BLOCKS) return NULL;
256 // mark as used
257 Allocs = Allocs0+best_i;
258 addr = Allocs->Addr;
259 // create entry for unallocated tail
260 if(Allocs->Len != size) { // this element is always FREE
261 if(Allocs[1].Len) {
262 if(Allocs0[MY_HEAP_MAX_BLOCKS-1].Len) return NULL;
263 /* for(i=MY_HEAP_MAX_BLOCKS-1;i>best_i;i--) {
264 Allocs[i] = Allocs[i-1];
265 }*/
266 RtlMoveMemory(&(Allocs[1]), &(Allocs[0]), (LastUsed-best_i+1)*sizeof(MEM_ALLOC_DESC));
267 }
268 Allocs[1].Addr = Allocs->Addr + size;
269 if(Allocs[1].Len) {
270 Allocs[1].Len -= size;
271 } else {
272 Allocs[1].Len = MY_HEAP_FRAME_SIZE - (addr - Allocs0[0].Addr) - size;
273 }
274 // Allocs[best_i+1].Used = FALSE; // this had been done by prev. ops.
275 FrameList[Frame].LastUsed++;
276 }
277 // update FirstFree pointer
278 if(FirstFree == best_i) {
279 for(i=best_i+1, Allocs++; (i<=LastUsed) && (Allocs->Len & MY_HEAP_FLAG_USED);i++, Allocs++) {
280 // do nothing but scan
281 }
282 FrameList[Frame].FirstFree = i;
283 Allocs = Allocs0+best_i;
284 }
285 Allocs->Len = size | MY_HEAP_FLAG_USED;
286 #ifdef MY_HEAP_TRACK_OWNERS
287 Allocs->Src = Src;
288 Allocs->Line = Line;
289 #endif
290 #ifdef MY_HEAP_TRACK_REF
291 Allocs->Tag = Tag;
292 #endif //MY_HEAP_TRACK_REF
293
294 // KdPrint(( "Mem: Allocated %x at addr %x\n", size, (ULONG)addr ));
295 // this will set IntegrityTag to zero
296 *((PULONG)addr) = 0x00000000;
297 #ifdef MY_HEAP_CHECK_BOUNDS
298 for(i=0; i<MY_HEAP_CHECK_BOUNDS_SZ; i++) {
299 *((PULONG)(addr+size+(i*sizeof(ULONG))-MY_HEAP_CHECK_BOUNDS_BSZ)) = 0xBAADF00D;
300 }
301 #endif //MY_HEAP_CHECK_BOUNDS
302
303 #ifdef UDF_DBG
304 MemTotalAllocated += size;
305 #endif
306 return (PCHAR)addr;
307 } // end MyAllocatePoolInFrame()
308
309 LONG
310 __fastcall
311 MyFindMemDescByAddr(
312 ULONG Frame,
313 PCHAR addr
314 )
315 {
316 ULONG i;
317 ULONG left;
318 ULONG right;
319 PMEM_ALLOC_DESC Allocs;
320
321 Allocs = FrameList[Frame].Frame;
322 // i = FrameList[Frame].LastUsed >> 1;
323 // KdPrint(("Mem: Freeing %x\n", (ULONG)addr)); DEADDA7A
324 // for(i=0;i<MY_HEAP_MAX_BLOCKS;i++) {
325 left = 0;
326 right = FrameList[Frame].LastUsed;
327 if(!right && FrameList[Frame].FirstFree)
328 right = 1;
329 while(left != right) {
330 i = (right + left) >> 1;
331 if( (Allocs[i].Len & MY_HEAP_FLAG_USED) && (Allocs[i].Addr == (ULONG)addr) ) {
332 FIF_Found:
333 return i;
334 }
335 if(right - left == 1) {
336 if( (Allocs[i+1].Len & MY_HEAP_FLAG_USED) && (Allocs[i+1].Addr == (ULONG)addr) ) {
337 i++;
338 goto FIF_Found;
339 }
340 break;
341 }
342 if(Allocs[i].Addr && (Allocs[i].Addr < (ULONG)addr)) {
343 left = i;
344 } else {
345 right = i;
346 }
347 }
348 return -1;
349 } // end MyFindMemDescByAddr()
350
351 VOID
352 __fastcall
353 MyFreePoolInFrame(
354 ULONG Frame,
355 PCHAR addr
356 )
357 {
358 LONG i, j;
359 ULONG pc;
360 ULONG len, len2;
361 PMEM_ALLOC_DESC Allocs;
362
363 Allocs = FrameList[Frame].Frame;
364 pc = 0;
365 i = MyFindMemDescByAddr(Frame, addr);
366 if(i < 0) {
367 KdPrint(("Mem: <<<*** WARNING ***>>> Double deallocation at %x !!! ;( \n", addr));
368 MyAllocDumpFrame(Frame);
369 BrutePoint();
370 return;
371 }
372 Allocs[i].Len &= ~MY_HEAP_FLAG_USED;
373 len = Allocs[i].Len; // USED bit is already cleared
374
375 #ifdef MY_HEAP_CHECK_BOUNDS
376 for(j=0; j<MY_HEAP_CHECK_BOUNDS_SZ; j++) {
377 ASSERT(*((PULONG)(addr+len+(j*sizeof(ULONG))-MY_HEAP_CHECK_BOUNDS_BSZ)) == 0xBAADF00D);
378 if(*((PULONG)(addr+len+(j*sizeof(ULONG))-MY_HEAP_CHECK_BOUNDS_BSZ)) != 0xBAADF00D) {
379 MyAllocDumpDescr(Allocs, i);
380 }
381 }
382 #endif //MY_HEAP_CHECK_BOUNDS
383
384 #ifdef UDF_DBG
385 // this is a marker of deallocated blocks
386 // some structures have DWORD IntegrityTag as a first member
387 // so, if IntegrityTag is equal to 0xDEADDA7A we shall return
388 // a <<<*** BIG ERROR MESSAGE ***>>> when somebody try to use it
389 *((PULONG)addr) = 0xDEADDA7A;
390 MemTotalAllocated -= len;
391 #endif
392 if((i<MY_HEAP_MAX_BLOCKS-1) && !((len2 = Allocs[i+1].Len) & MY_HEAP_FLAG_USED)) {
393 // pack up
394 if((len2 &= MY_HEAP_FLAG_LEN_MASK)) {
395 len += len2;
396 } else {
397 len = MY_HEAP_FRAME_SIZE - (Allocs[i].Addr - Allocs[0].Addr);
398 }
399 pc++;
400 }
401 if((i>0) && !((len2 = Allocs[i-1].Len) & MY_HEAP_FLAG_USED)) {
402 // pack down
403 len += (len2 & MY_HEAP_FLAG_LEN_MASK);
404 pc++;
405 i--;
406 }
407 if(pc) {
408 // pack
409
410 Allocs[i+pc].Addr = Allocs[i].Addr;
411 Allocs[i+pc].Len = len;
412 /* for(;i<MY_HEAP_MAX_BLOCKS-pc;i++) {
413 Allocs[i] = Allocs[i+pc];
414 }*/
415 RtlMoveMemory(&(Allocs[i]), &(Allocs[i+pc]), (MY_HEAP_MAX_BLOCKS-pc-i)*sizeof(MEM_ALLOC_DESC) );
416 /* for(i=MY_HEAP_MAX_BLOCKS-pc;i<MY_HEAP_MAX_BLOCKS;i++) {
417 Allocs[i].Addr =
418 Allocs[i].Len =
419 Allocs[i].Used = 0;
420 }*/
421 RtlZeroMemory(&(Allocs[MY_HEAP_MAX_BLOCKS-pc]), pc*sizeof(MEM_ALLOC_DESC));
422 }
423 if(FrameList[Frame].FirstFree > (ULONG)i)
424 FrameList[Frame].FirstFree = (ULONG)i;
425 //ASSERT(FrameList[Frame].LastUsed >= pc);
426 if(FrameList[Frame].LastUsed < pc) {
427 FrameList[Frame].LastUsed = 0;
428 } else {
429 FrameList[Frame].LastUsed -= pc;
430 }
431 return;
432 } // end MyFreePoolInFrame()
433
434 BOOLEAN
435 __fastcall
436 MyResizePoolInFrame(
437 ULONG Frame,
438 PCHAR addr,
439 ULONG new_len
440 #ifdef MY_HEAP_TRACK_REF
441 ,PCHAR* Tag
442 #endif //MY_HEAP_TRACK_REF
443 )
444 {
445 LONG i, j;
446 ULONG len, len2;
447 PMEM_ALLOC_DESC Allocs;
448
449 if(FrameList[Frame].LastUsed >= (MY_HEAP_MAX_BLOCKS-1))
450 return FALSE;
451 Allocs = FrameList[Frame].Frame;
452 i = MyFindMemDescByAddr(Frame, addr);
453 if(i < 0) {
454 KdPrint(("Mem: <<<*** WARNING ***>>> Double deallocation at %x !!! ;( \n", addr));
455 MyAllocDumpFrame(Frame);
456 BrutePoint();
457 return FALSE;
458 }
459 if(i>=(MY_HEAP_MAX_BLOCKS-2))
460 return FALSE;
461
462 #ifdef MY_HEAP_TRACK_REF
463 *Tag = Allocs[i].Tag;
464 #endif //MY_HEAP_TRACK_REF
465
466 len = (Allocs[i].Len & MY_HEAP_FLAG_LEN_MASK);
467
468 #ifdef MY_HEAP_CHECK_BOUNDS
469 new_len += MY_HEAP_CHECK_BOUNDS_BSZ;
470 for(j=0; j<MY_HEAP_CHECK_BOUNDS_SZ; j++) {
471 ASSERT(*((PULONG)(addr+len+(j*sizeof(ULONG))-MY_HEAP_CHECK_BOUNDS_BSZ)) == 0xBAADF00D);
472 if(*((PULONG)(addr+len+(j*sizeof(ULONG))-MY_HEAP_CHECK_BOUNDS_BSZ)) != 0xBAADF00D) {
473 MyAllocDumpDescr(Allocs, i);
474 }
475 }
476 #endif //MY_HEAP_CHECK_BOUNDS
477
478 if(new_len > len ) {
479 if(Allocs[i+1].Len & MY_HEAP_FLAG_USED)
480 return FALSE;
481 if(len + (Allocs[i+1].Len & MY_HEAP_FLAG_LEN_MASK) < new_len)
482 return FALSE;
483 Allocs[i].Len += (len2 = (new_len - len));
484 Allocs[i+1].Len -= len2;
485 Allocs[i+1].Addr += len2;
486
487 #ifdef MY_HEAP_CHECK_BOUNDS
488 for(j=0; j<MY_HEAP_CHECK_BOUNDS_SZ; j++) {
489 *((PULONG)(addr+new_len+(j*sizeof(ULONG))-MY_HEAP_CHECK_BOUNDS_BSZ)) = 0xBAADF00D;
490 }
491 #endif //MY_HEAP_CHECK_BOUNDS
492
493 if(!Allocs[i+1].Len) {
494 i++;
495 RtlMoveMemory(&(Allocs[i]), &(Allocs[i+1]), (MY_HEAP_MAX_BLOCKS-1-i)*sizeof(MEM_ALLOC_DESC) );
496 RtlZeroMemory(&(Allocs[MY_HEAP_MAX_BLOCKS-1]), sizeof(MEM_ALLOC_DESC));
497 if((ULONG)i<FrameList[Frame].LastUsed)
498 FrameList[Frame].LastUsed--;
499 if(FrameList[Frame].FirstFree == (ULONG)i) {
500 for(;i<MY_HEAP_MAX_BLOCKS;i++) {
501 if(!(Allocs[i].Len & MY_HEAP_FLAG_USED))
502 break;
503 }
504 FrameList[Frame].FirstFree = i;
505 }
506 }
507 #ifdef UDF_DBG
508 MemTotalAllocated += len;
509 #endif
510 } else {
511
512 len2 = len - new_len;
513 if(!len2) return TRUE;
514
515 #ifdef MY_HEAP_CHECK_BOUNDS
516 for(j=0; j<MY_HEAP_CHECK_BOUNDS_SZ; j++) {
517 *((PULONG)(addr+new_len+(j*sizeof(ULONG))-MY_HEAP_CHECK_BOUNDS_BSZ)) = 0xBAADF00D;
518 }
519 #endif //MY_HEAP_CHECK_BOUNDS
520
521 Allocs[i].Len -= len2;
522 if(Allocs[i+1].Len & MY_HEAP_FLAG_USED) {
523 i++;
524 RtlMoveMemory(&(Allocs[i+1]), &(Allocs[i]), (MY_HEAP_MAX_BLOCKS-i-1)*sizeof(MEM_ALLOC_DESC) );
525
526 Allocs[i].Len = len2;
527 Allocs[i].Addr = Allocs[i-1].Addr + new_len;
528
529 if(FrameList[Frame].FirstFree > (ULONG)i)
530 FrameList[Frame].FirstFree = i;
531 FrameList[Frame].LastUsed++;
532
533 } else {
534 Allocs[i+1].Len += len2;
535 Allocs[i+1].Addr -= len2;
536 }
537 #ifdef UDF_DBG
538 MemTotalAllocated -= len2;
539 #endif
540 }
541
542 return TRUE;
543 } // end MyResizePoolInFrame()
544
545 VOID
546 __fastcall
547 MyAllocInitFrame(
548 ULONG Type,
549 ULONG Frame
550 )
551 {
552 PMEM_ALLOC_DESC Allocs;
553
554 Allocs = (PMEM_ALLOC_DESC)DbgAllocatePool(NonPagedPool, sizeof(MEM_ALLOC_DESC)*(MY_HEAP_MAX_BLOCKS+1));
555 if(!Allocs) {
556 KdPrint(("Insufficient resources to allocate frame descriptor\n"));
557 FrameList[Frame].Frame = NULL;
558 MyAllocDumpFrames();
559 BrutePoint();
560 return;
561 }
562 RtlZeroMemory(Allocs, sizeof(MEM_ALLOC_DESC)*(MY_HEAP_MAX_BLOCKS+1));
563 // alloc heap
564 Allocs[0].Addr = (ULONG)DbgAllocatePool((POOL_TYPE)Type, MY_HEAP_FRAME_SIZE);
565 if(!Allocs[0].Addr) {
566 KdPrint(("Insufficient resources to allocate frame\n"));
567 DbgFreePool(Allocs);
568 FrameList[Frame].Frame = NULL;
569 MyAllocDumpFrames();
570 BrutePoint();
571 return;
572 }
573 Allocs[0].Len = MY_HEAP_FRAME_SIZE;
574 // Allocs[0].Used = FALSE;
575 FrameList[Frame].Frame = Allocs;
576 FrameList[Frame].LastUsed =
577 FrameList[Frame].FirstFree = 0;
578 FrameList[Frame].Type = Type;
579 FrameCount++;
580 if(LastFrame < Frame)
581 LastFrame = Frame;
582 } // end MyAllocInitFrame()
583
584 VOID
585 __fastcall
586 MyAllocFreeFrame(
587 ULONG Frame
588 )
589 {
590 // check if already deinitialized
591 if(!FrameList[Frame].Frame) {
592 BrutePoint();
593 return;
594 }
595 DbgFreePool((PVOID)(FrameList[Frame].Frame)[0].Addr);
596 DbgFreePool((PVOID)(FrameList[Frame].Frame));
597 FrameList[Frame].Frame = NULL;
598 FrameCount--;
599 if(LastFrame == Frame) {
600 LONG i;
601 for(i=LastFrame; i>0; i--) {
602 if(FrameList[i].Frame)
603 break;
604 }
605 LastFrame = i;
606 }
607 } // end MyAllocFreeFrame()
608
609 PCHAR
610 #ifndef MY_HEAP_TRACK_OWNERS
611 __fastcall
612 #endif
613 MyAllocatePool(
614 ULONG type,
615 ULONG size
616 #ifdef MY_HEAP_TRACK_OWNERS
617 ,USHORT Src,
618 USHORT Line
619 #endif
620 #ifdef MY_HEAP_TRACK_REF
621 ,PCHAR Tag
622 #endif //MY_HEAP_TRACK_REF
623 )
624 {
625 ULONG i;
626 ULONG addr;
627
628 // KdPrint(("MemFrames: %x\n",FrameCount));
629
630 if(!size || (size > MY_HEAP_FRAME_SIZE)) return NULL;
631
632 #ifdef DUMP_MEM_FRAMES2
633 if(MyDumpMem)
634 MyAllocDumpFrames();
635 #endif
636
637 LockMemoryManager();
638 for(i=0;i<MY_HEAP_MAX_FRAMES; i++) {
639 if( FrameList[i].Frame &&
640 (FrameList[i].Type == type) &&
641 (addr = (ULONG)MyAllocatePoolInFrame(i,size
642 #ifdef MY_HEAP_TRACK_OWNERS
643 ,Src,Line
644 #endif
645 #ifdef MY_HEAP_TRACK_REF
646 ,Tag
647 #endif //MY_HEAP_TRACK_REF
648 )) ) {
649
650 #ifdef UDF_DBG
651 // if(addr >= (ULONG)BreakAddr && addr < sizeof(UDF_FILE_INFO) + (ULONG)BreakAddr) {
652 // if(addr<=(ULONG)BreakAddr && addr+sizeof(UDF_FILE_INFO) > (ULONG)BreakAddr) {
653 // KdPrint(("ERROR !!! Allocating in examined block\n"));
654 // KdPrint(("addr %x\n", addr));
655 // MyAllocDumpFrame(i);
656 // BrutePoint();
657 // }
658 #endif //UDF_DBG
659
660 UnlockMemoryManager();
661 DbgTouch((PVOID)addr);
662 return (PCHAR)addr;
663 }
664 }
665 #ifdef DUMP_MEM_FRAMES2
666 MyAllocDumpFrames();
667 #endif
668 addr = 0;
669 for(i=0;i<MY_HEAP_MAX_FRAMES; i++) {
670 // MyAllocDumpFrame(i);
671 if(!(FrameList[i].Frame)) {
672 MyAllocInitFrame(type, i);
673 if(FrameList[i].Frame &&
674 (addr = (ULONG)MyAllocatePoolInFrame(i,size
675 #ifdef MY_HEAP_TRACK_OWNERS
676 ,Src,Line
677 #endif
678 #ifdef MY_HEAP_TRACK_REF
679 ,Tag
680 #endif //MY_HEAP_TRACK_REF
681 )) ) {
682
683 #ifdef UDF_DBG
684 // if(addr >= (ULONG)BreakAddr && addr < sizeof(UDF_FILE_INFO) + (ULONG)BreakAddr) {
685 // if(addr<=(ULONG)BreakAddr && addr+sizeof(UDF_FILE_INFO) > (ULONG)BreakAddr) {
686 // KdPrint(("ERROR !!! Allocating in examined block\n"));
687 // KdPrint(("addr %x\n", addr));
688 // MyAllocDumpFrame(i);
689 // BrutePoint();
690 // }
691 // } else {
692 // addr = 0;
693 #endif //UDF_DBG
694 }
695 #ifdef DUMP_MEM_FRAMES2
696 MyAllocDumpFrames();
697 #endif
698 break;
699 }
700 }
701 UnlockMemoryManager();
702 return (PCHAR)addr;
703 } // end MyAllocatePool()
704
705 LONG
706 __fastcall
707 MyFindFrameByAddr(
708 PCHAR addr
709 )
710 {
711 ULONG i;
712 // ULONG j;
713 PMEM_ALLOC_DESC Allocs;
714
715 for(i=0;i<=LastFrame; i++) {
716 if( (Allocs = FrameList[i].Frame) &&
717 (Allocs[0].Addr <= (ULONG)addr) &&
718 (Allocs[0].Addr + MY_HEAP_FRAME_SIZE > (ULONG)addr) ) {
719 return i;
720 }
721 }
722 return -1;
723 }
724
725 VOID
726 __fastcall
727 MyFreePool(
728 PCHAR addr
729 )
730 {
731 LONG i;
732
733 // KdPrint(("MemFrames: %x\n",FrameCount));
734
735 LockMemoryManager();
736 i = MyFindFrameByAddr(addr);
737 if(i < 0) {
738 UnlockMemoryManager();
739 KdPrint(("Mem: <<<*** WARNING ***>>> Double deallocation at %x !!! ;( \n", addr));
740 BrutePoint();
741 return;
742 }
743
744 #ifdef UDF_DBG
745 // BreakAddr <= addr < BreakAddr + sizeof(UDF_FILE_INFO)
746 // if((ULONG)addr >= (ULONG)BreakAddr && (ULONG)addr < sizeof(UDF_FILE_INFO) + (ULONG)BreakAddr) {
747 // KdPrint(("Deallocating in examined block\n"));
748 // KdPrint(("addr %x\n", addr));
749 // MyAllocDumpFrame(i);
750 // BrutePoint();
751 // BreakAddr = NULL;
752 // }
753 #endif //UDF_DBG
754
755 MyFreePoolInFrame(i,addr);
756 /* for(j=0;j<MY_HEAP_MAX_BLOCKS; j++) {
757 if((Allocs[j].Len & MY_HEAP_FLAG_USED) || (FrameCount<=1)) {
758 return;
759 }
760 }*/
761 if(MyAllocIsFrameFree(FrameList, i)) {
762 MyAllocFreeFrame(i);
763 }
764 UnlockMemoryManager();
765 return;
766 } // end MyFreePool()
767
768 ULONG
769 #ifndef MY_HEAP_TRACK_OWNERS
770 __fastcall
771 #endif
772 MyReallocPool(
773 IN PCHAR addr,
774 IN ULONG OldLength,
775 OUT PCHAR* NewBuff,
776 IN ULONG NewLength
777 #ifdef MY_HEAP_TRACK_OWNERS
778 ,USHORT Src,
779 USHORT Line
780 #endif
781 )
782 {
783 ULONG i;
784 PCHAR new_buff;
785 #ifdef MY_HEAP_TRACK_REF
786 PCHAR Tag;
787 #endif
788
789 // KdPrint(("MemFrames: %x\n",FrameCount));
790 (*NewBuff) = addr;
791 if(OldLength == NewLength) return OldLength;
792
793 if(!NewLength) {
794 BrutePoint();
795 return 0;
796 }
797
798 LockMemoryManager();
799 i = MyFindFrameByAddr(addr);
800 if(i < 0) {
801 UnlockMemoryManager();
802 KdPrint(("Mem: <<<*** WARNING ***>>> Double deallocation at %x !!! ;( \n", addr));
803 BrutePoint();
804 return 0;
805 }
806
807 if(MyResizePoolInFrame(i,addr,NewLength
808 #ifdef MY_HEAP_TRACK_REF
809 , &Tag
810 #endif
811 )) {
812 #ifdef CHECK_ALLOC_FRAMES
813 MyAllocCheck(i);
814 #endif
815
816 (*NewBuff) = addr;
817 DbgTouch((PVOID)addr);
818 UnlockMemoryManager();
819 return NewLength;
820 }
821
822 new_buff = MyAllocatePool(FrameList[i].Type, MyAlignSize__(NewLength)
823 #ifdef MY_HEAP_TRACK_OWNERS
824 ,Src,Line
825 #endif
826 #ifdef MY_HEAP_TRACK_REF
827 ,Tag
828 #endif //MY_HEAP_TRACK_REF
829 );
830 if(!new_buff) {
831 UnlockMemoryManager();
832 return 0;
833 }
834
835 if(OldLength > NewLength) OldLength = NewLength;
836 RtlCopyMemory(new_buff, addr, OldLength);
837
838 MyFreePoolInFrame(i,addr);
839
840 if(MyAllocIsFrameFree(FrameList, i)) {
841 MyAllocFreeFrame(i);
842 }
843 UnlockMemoryManager();
844
845 DbgTouch((PVOID)new_buff);
846 (*NewBuff) = new_buff;
847 return OldLength;
848
849 } // end MyReallocPool()
850
851 #ifdef UDF_DBG
852 LONG
853 MyFindMemDescByRangeInFrame(
854 ULONG Frame,
855 PCHAR addr
856 )
857 {
858 ULONG i;
859 ULONG left;
860 ULONG right;
861 PMEM_ALLOC_DESC Allocs;
862 ULONG curaddr;
863 ULONG curlen;
864
865 Allocs = FrameList[Frame].Frame;
866 // i = FrameList[Frame].LastUsed >> 1;
867 // KdPrint(("Mem: Freeing %x\n", (ULONG)addr)); DEADDA7A
868 // for(i=0;i<MY_HEAP_MAX_BLOCKS;i++) {
869 left = 0;
870 right = FrameList[Frame].LastUsed;
871 if(!right && FrameList[Frame].FirstFree)
872 right = 1;
873 while(left != right) {
874 i = (right + left) >> 1;
875 curaddr = Allocs[i].Addr;
876 curlen = Allocs[i].Len;
877 if( (curlen & MY_HEAP_FLAG_USED) &&
878 (curaddr <= (ULONG)addr) &&
879 ((curaddr+(curlen & MY_HEAP_FLAG_LEN_MASK)) > (ULONG)addr) ) {
880 FIF_Found:
881 return i;
882 }
883 if(right - left == 1) {
884 if( (Allocs[i+1].Len & MY_HEAP_FLAG_USED) && (Allocs[i+1].Addr == (ULONG)addr) ) {
885 i++;
886 goto FIF_Found;
887 }
888 break;
889 }
890 if(Allocs[i].Addr && (Allocs[i].Addr < (ULONG)addr)) {
891 left = i;
892 } else {
893 right = i;
894 }
895 }
896 return -1;
897 } // end MyFindMemDescByRangeInFrame()
898
899 LONG
900 MyFindMemBaseByAddr(
901 PCHAR addr
902 )
903 {
904 ULONG Frame, Base, i;
905
906 LockMemoryManager();
907 Frame = MyFindFrameByAddr(addr);
908 if(Frame < 0) {
909 UnlockMemoryManager();
910 KdPrint(("Mem: <<<*** WARNING ***>>> Unknown base for %x !!! ;( \n", addr));
911 BrutePoint();
912 return -1;
913 }
914 i = MyFindMemDescByRangeInFrame(Frame, addr);
915 Base = FrameList[Frame].Frame[i].Addr;
916 UnlockMemoryManager();
917 return Base;
918 } // end MyFindMemBaseByAddr()
919 #endif //UDF_DBG
920
921 BOOLEAN
922 MyAllocInit(VOID)
923 {
924 RtlZeroMemory(&FrameList, sizeof(FrameList));
925 if(!OS_SUCCESS(InitLockMemoryManager())) {
926 return FALSE;
927 }
928 MyAllocInitFrame(NonPagedPool, 0);
929 LastFrame = 0;
930 return (MyMemInitialized = TRUE);
931 } // end MyAllocInit()
932
933 VOID
934 MyAllocRelease(VOID)
935 {
936 ULONG i;
937 PMEM_ALLOC_DESC Allocs;
938
939 if(!MyMemInitialized)
940 return;
941 LockMemoryManager();
942 for(i=0;i<MY_HEAP_MAX_FRAMES; i++) {
943 if(Allocs = FrameList[i].Frame) {
944 MyAllocFreeFrame(i);
945 }
946 }
947 RtlZeroMemory(&FrameList, sizeof(FrameList));
948 UnlockMemoryManager();
949 DeinitLockMemoryManager();
950 MyMemInitialized = FALSE;
951 } // end MyAllocRelease()
952
953 #endif //MY_USE_INTERNAL_MEMMANAGER