home *** CD-ROM | disk | FTP | other *** search
- /*
- MEM.C -- walks DOS MCB chain(s): simple version
- Andrew Schulman and Jim Kyle, July 1990
- */
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <dos.h>
-
- typedef unsigned char BYTE;
- typedef unsigned short WORD;
- typedef unsigned long ULONG;
- typedef void far *FP;
-
- #ifndef MK_FP
- #define MK_FP(seg,ofs) ((FP)(((ULONG)(seg) << 16) | (ofs)))
- #endif
-
- #ifdef __TURBOC__
- #define ASM asm
- #else
- #define ASM _asm
- #endif
-
- #pragma pack(1)
-
- typedef struct {
- BYTE type; /* 'M'=in chain; 'Z'=at end */
- WORD owner; /* PSP of the owner */
- WORD size; /* in 16-byte paragraphs */
- BYTE unused[3];
- BYTE dos4[8];
- } MCB;
-
- void fail(char *s) { puts(s); exit(1); }
-
- MCB far *get_mcb(void)
- {
- ASM mov ah, 52h
- ASM int 21h
- ASM mov dx, es:[bx-2]
- ASM xor ax, ax
- /* in both Microsoft C and Turbo C, far* returned in DX:AX */
- }
-
- mcb_chk(MCB far *mcb)
- {
- for (;;)
- if (mcb->type == 'M')
- mcb = MK_FP(FP_SEG(mcb) + mcb->size + 1, 0);
- else
- return (mcb->type == 'Z');
- }
-
- void display(MCB far *mcb)
- {
- char buf[80];
- sprintf(buf, "%04X %04X %04X (%6lu)",
- FP_SEG(mcb), mcb->owner, mcb->size, (long) mcb->size << 4);
- if (! mcb->owner)
- strcat(buf, " free");
- puts(buf);
- }
-
- void walk(MCB far *mcb)
- {
- printf("Seg Owner Size\n");
- for (;;)
- switch (mcb->type)
- {
- case 'M' : /* Mark : belongs to MCB chain */
- display(mcb);
- mcb = MK_FP(FP_SEG(mcb) + mcb->size + 1, 0);
- break;
- case 'Z' : /* Zbikowski : end of MCB chain */
- display(mcb);
- return;
- default :
- fail("error in MCB chain");
- }
- }
-
- #ifdef TRY_BUG
- main(void)
- {
- unsigned segm;
- ASM mov ah, 48h /* Allocate Memory Block */
- ASM mov bx, 64h /* get 100 paragraphs */
- ASM int 21h
- ASM jc done
- /* ax now holds initial segment of allocated block */
- ASM mov segm, ax
- printf("before: "); display(MK_FP(segm - 1, 0));
-
- ASM mov ax, segm
- ASM mov es, ax /* now resize the block */
- ASM mov ah, 4Ah /* Resize Memory Block */
- ASM mov bx, 0FFFFh /* impossible (at least in real mode!) */
- ASM int 21h
- ASM jnc done /* something seriously wrong if _didn't_ fail! */
- printf("after: "); display(MK_FP(segm - 1, 0));
- done:
- return 0;
- }
- #else
- main(int argc, char *argv[])
- {
- if (argc < 2)
- walk(get_mcb()); /* walk "normal" MCB chain */
- else
- {
- unsigned seg;
- sscanf(argv[1], "%04X", &seg);
- walk(MK_FP(seg, 0)); /* walk arbitrary MCB chain */
- }
-
- if (! mcb_chk(get_mcb()))
- {
- /* maybe do stack backtrace here, or dump registers */
- puts("Error in MCB chain - prepare for halt...");
- getchar();
- }
- else
- puts("MCB chain ok");
-
- return 0;
- }
- #endif
-