Reactos
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
30MEM_FRAME_ALLOC_DESC FrameList[MY_HEAP_MAX_FRAMES];
31#ifdef MEM_LOCK_BY_SPINLOCK
32KSPIN_LOCK FrameLock;
33KIRQL oldIrql;
34#define LockMemoryManager() KeAcquireSpinLock(&FrameLock, &oldIrql)
35#define UnlockMemoryManager() KeReleaseSpinLock(&FrameLock, oldIrql)
36__inline
37NTSTATUS
38InitLockMemoryManager() {
39 KeInitializeSpinLock(&FrameLock);
40 return STATUS_SUCCESS;
41}
42#define DeinitLockMemoryManager() {NOTHING;}
43#else //MEM_LOCK_BY_SPINLOCK
44ERESOURCE 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
50ULONG FrameCount;
51ULONG LastFrame;
52BOOLEAN MyMemInitialized = FALSE;
53
54#define MyAllocIsFrameFree(FrameList, i) \
55 (!(FrameList[i].LastUsed || FrameList[i].FirstFree))
56
57#ifdef UDF_DBG
58ULONG MemTotalAllocated;
59PCHAR BreakAddr;
60
61VOID
62MyAllocDumpDescr(
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 UDFPrint(("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 UDFPrint(("src %x \t line %d \t", Allocs[i].Src, Allocs[i].Line));
73#endif
74#ifdef MY_HEAP_TRACK_REF
75 UDFPrint(("%s%s", Used ? " " : "-", Allocs[i].Tag ? Allocs[i].Tag : ""));
76#endif
77 UDFPrint(("\n"));
78}
79
80//#define CHECK_ALLOC_FRAMES
81
82#define DUMP_MEM_FRAMES
83
84#ifdef DUMP_MEM_FRAMES
85ULONG MyDumpMem = FALSE;
86#endif //DUMP_MEM_FRAMES
87
88#define DUMP_MEM_FRAMES2
89
90//#ifdef CHECK_ALLOC_FRAMES
91VOID
92MyAllocDumpFrame(
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 UDFPrint(("Dumping frame %x\n",Frame));
107 UDFPrint(("FirstFree %x LastUsed %x ", FrameList[Frame].FirstFree, FrameList[Frame].LastUsed));
108 UDFPrint(("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 UDFPrint(("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 UDFPrint(("src %x \t line %d \t", Allocs[i].Src, Allocs[i].Line));
115#endif
116#ifdef MY_HEAP_TRACK_REF
117 UDFPrint(("%s%s", Used ? " " : "-", Allocs[i].Tag ? Allocs[i].Tag : ""));
118#endif
119 UDFPrint(("\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 UDFPrint((" Wasted %x bytes from %x\n", MY_HEAP_FRAME_SIZE - k, MY_HEAP_FRAME_SIZE));
128} // end MyAllocDumpFrame()
129
130VOID
131MyAllocDumpFrames(
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 UDFPrint(("\n"));
144
145 for(i=0;i<MY_HEAP_MAX_FRAMES; i++) {
146 if(FrameList[i].Frame) {
147 UDFPrint(("Addr %x ", FrameList[i].Frame));
148 UDFPrint(("Type %x\n" , FrameList[i].Type));
149 }
150 }
151
152} // end MyAllocDumpFrame()
153
154VOID
155MyAllocCheck(
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 UDFPrint(("ERROR! Memory block aliasing\n"));
170 UDFPrint(("block %x, frame %x\n", i, Frame));
171 UDFPrint(("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
193PCHAR
194#ifndef MY_HEAP_TRACK_OWNERS
195__fastcall
196#endif
197MyAllocatePoolInFrame(
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// UDFPrint(( "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
309LONG
310__fastcall
311MyFindMemDescByAddr(
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// UDFPrint(("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) ) {
332FIF_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
351VOID
352__fastcall
353MyFreePoolInFrame(
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 UDFPrint(("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
434BOOLEAN
435__fastcall
436MyResizePoolInFrame(
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 UDFPrint(("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
545VOID
546__fastcall
547MyAllocInitFrame(
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 UDFPrint(("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 UDFPrint(("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
584VOID
585__fastcall
586MyAllocFreeFrame(
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
609PCHAR
610#ifndef MY_HEAP_TRACK_OWNERS
611__fastcall
612#endif
613MyAllocatePool(
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// UDFPrint(("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// UDFPrint(("ERROR !!! Allocating in examined block\n"));
654// UDFPrint(("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// UDFPrint(("ERROR !!! Allocating in examined block\n"));
687// UDFPrint(("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
705LONG
706__fastcall
707MyFindFrameByAddr(
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
725VOID
726__fastcall
727MyFreePool(
728 PCHAR addr
729 )
730{
731 LONG i;
732
733// UDFPrint(("MemFrames: %x\n",FrameCount));
734
735 LockMemoryManager();
736 i = MyFindFrameByAddr(addr);
737 if(i < 0) {
738 UnlockMemoryManager();
739 UDFPrint(("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// UDFPrint(("Deallocating in examined block\n"));
748// UDFPrint(("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
768ULONG
769#ifndef MY_HEAP_TRACK_OWNERS
770__fastcall
771#endif
772MyReallocPool(
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// UDFPrint(("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 UDFPrint(("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
813MyAllocCheck(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
852LONG
853MyFindMemDescByRangeInFrame(
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// UDFPrint(("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) ) {
880FIF_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
899LONG
900MyFindMemBaseByAddr(
901 PCHAR addr
902 )
903{
904 ULONG Frame, Base, i;
905
906 LockMemoryManager();
907 Frame = MyFindFrameByAddr(addr);
908 if(Frame < 0) {
909 UnlockMemoryManager();
910 UDFPrint(("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
921BOOLEAN
922MyAllocInit(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
933VOID
934MyAllocRelease(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