home *** CD-ROM | disk | FTP | other *** search
- /* 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 <stdio.h>
- #include <exec/types.h>
- #include <exec/exec.h>
- #include <exec/execbase.h>
-
- 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;
- }
-