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