home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 10 / 10.iso / l / l440 / 2.ddi / CHAP3 / MEM1.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-09-25  |  3.0 KB  |  129 lines

  1. /* 
  2. MEM.C -- walks DOS MCB chain(s): simple version
  3. Andrew Schulman and Jim Kyle, July 1990
  4. */
  5.  
  6. #include <stdlib.h>
  7. #include <stdio.h>
  8. #include <dos.h>
  9.  
  10. typedef unsigned char BYTE;
  11. typedef unsigned short WORD;
  12. typedef unsigned long ULONG;
  13. typedef void far *FP;
  14.  
  15. #ifndef MK_FP
  16. #define MK_FP(seg,ofs)  ((FP)(((ULONG)(seg) << 16) | (ofs)))
  17. #endif
  18.  
  19. #ifdef __TURBOC__
  20. #define ASM asm
  21. #else
  22. #define ASM _asm
  23. #endif
  24.  
  25. #pragma pack(1)
  26.  
  27. typedef struct {
  28.     BYTE type;          /* 'M'=in chain; 'Z'=at end */
  29.     WORD owner;         /* PSP of the owner */
  30.     WORD size;          /* in 16-byte paragraphs */
  31.     BYTE unused[3];
  32.     BYTE dos4[8];
  33.     } MCB;
  34.  
  35. void fail(char *s) { puts(s); exit(1); }
  36.  
  37. MCB far *get_mcb(void)
  38. {
  39.     ASM mov ah, 52h
  40.     ASM int 21h
  41.     ASM mov dx, es:[bx-2]
  42.     ASM xor ax, ax
  43.     /* in both Microsoft C and Turbo C, far* returned in DX:AX */
  44. }
  45.  
  46. mcb_chk(MCB far *mcb)
  47. {
  48.     for (;;)
  49.         if (mcb->type == 'M')
  50.             mcb = MK_FP(FP_SEG(mcb) + mcb->size + 1, 0);
  51.         else
  52.             return (mcb->type == 'Z');
  53. }
  54.  
  55. void display(MCB far *mcb)
  56. {
  57.     char buf[80];
  58.     sprintf(buf, "%04X    %04X    %04X (%6lu)", 
  59.         FP_SEG(mcb), mcb->owner, mcb->size, (long) mcb->size << 4);
  60.     if (! mcb->owner) 
  61.         strcat(buf, "   free");
  62.     puts(buf);
  63. }
  64.  
  65. void walk(MCB far *mcb)
  66. {
  67.     printf("Seg     Owner   Size\n"); 
  68.     for (;;)
  69.         switch (mcb->type)
  70.         {
  71.             case 'M' : /* Mark : belongs to MCB chain */
  72.                 display(mcb);
  73.                 mcb = MK_FP(FP_SEG(mcb) + mcb->size + 1, 0);
  74.                 break;
  75.             case 'Z' : /* Zbikowski : end of MCB chain */
  76.                 display(mcb);
  77.                 return;
  78.             default :
  79.                 fail("error in MCB chain");
  80.         }
  81. }
  82.  
  83. #ifdef TRY_BUG
  84. main(void)
  85. {
  86.     unsigned segm;
  87.     ASM mov ah, 48h     /* Allocate Memory Block */
  88.     ASM mov bx, 64h     /* get 100 paragraphs */
  89.     ASM int 21h
  90.     ASM jc done
  91.     /* ax now holds initial segment of allocated block */
  92.     ASM mov segm, ax
  93.     printf("before: "); display(MK_FP(segm - 1, 0));
  94.  
  95.     ASM mov ax, segm
  96.     ASM mov es, ax      /* now resize the block */
  97.     ASM mov ah, 4Ah     /* Resize Memory Block */
  98.     ASM mov bx, 0FFFFh  /* impossible (at least in real mode!) */
  99.     ASM int 21h
  100.     ASM jnc done        /* something seriously wrong if _didn't_ fail! */
  101.     printf("after:  "); display(MK_FP(segm - 1, 0));
  102. done:
  103.     return 0;
  104. }
  105. #else
  106. main(int argc, char *argv[])
  107. {
  108.     if (argc < 2)
  109.         walk(get_mcb());            /* walk "normal" MCB chain */
  110.     else
  111.     {
  112.         unsigned seg;
  113.         sscanf(argv[1], "%04X", &seg);
  114.         walk(MK_FP(seg, 0));       /* walk arbitrary MCB chain */
  115.     }
  116.     
  117.     if (! mcb_chk(get_mcb()))
  118.     {
  119.         /* maybe do stack backtrace here, or dump registers */
  120.         puts("Error in MCB chain - prepare for halt...");
  121.         getchar();
  122.     }
  123.     else
  124.         puts("MCB chain ok");
  125.     
  126.     return 0;
  127. }
  128. #endif
  129.