/* MQ.c Memory Quarantine by Fabbian G. Dufoe, III This program walks the memory free list. If it finds memory on the free list which has been identified as defective by MD (Memory Diagnostic) it patches the memory free list so that memory will appear to be already allocated. The memory cannot be recovered until the system is restarted. The program begins by getting a pointer to the system's memory free list. For each entry in the list it compares the starting and ending addresses of the free memory block against the addresses of the defective memory. If a defective memory address falls within the free block MQ changes the entry for the free block so the free block will appear to end just short of the defective address. Then it adds a new entry to the list. The new entry identifies a free block beginning just after the defective address and continuing to the point where the original block ended. This process is repeated for each defective address and for each free block. */ #include #include #include #include struct ExecBase *ExecBase; void main() { ULONG BadAddr[100]; int bytes = 0; int i; int last = 0; struct MemChunk *LastChunk = NULL; struct MemChunk *MemChunk; struct MemHeader *MemHeader; while ((scanf("%8lX\n", &BadAddr[last++]) != EOF) && (last < 100)); last--; if ((ExecBase = (struct ExecBase *) OpenLibrary("exec.library", 0L)) == NULL) exit(20); Forbid(); MemHeader = (struct MemHeader *)ExecBase->MemList.lh_Head; while(MemHeader->mh_Node.ln_Succ) { for (MemChunk = MemHeader->mh_First; MemChunk; MemChunk = MemChunk->mc_Next) { for (i = 0; i < last; i++) { struct MemChunk *NewChunk; ULONG Size1; ULONG Size2; /* If chunk ends before bad address get next chunk. */ if ((ULONG)MemChunk + MemChunk->mc_Bytes - 1 < BadAddr[i]) break; /* If chunk begins after bad address get next address. */ if ((ULONG)MemChunk > BadAddr[i]) continue; /* Bad address falls within chunk. */ Size1 = BadAddr[i] - (ULONG)MemChunk; Size1 = Size1 - Size1 % 8; Size2 = MemChunk->mc_Bytes - Size1 - 8; NewChunk = (struct MemChunk *)((ULONG)MemChunk + Size1 + 8); if (Size2 == 0) MemChunk->mc_Bytes = Size1; else { NewChunk->mc_Next = MemChunk->mc_Next; NewChunk->mc_Bytes = Size2; MemChunk->mc_Next = NewChunk; MemChunk->mc_Bytes = Size1; } if (Size1 == 0) { if (LastChunk == NULL) MemHeader->mh_First = MemChunk->mc_Next; else LastChunk->mc_Next = MemChunk->mc_Next; } MemHeader->mh_Free -= 8; bytes += 8; } LastChunk = MemChunk; } MemHeader = (struct MemHeader *)MemHeader->mh_Node.ln_Succ; } Permit(); printf("MQ: %d bytes quarantined.\n", bytes); return; }