home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 10 / 10.iso / l / l430 / 1.ddi / CHAP5.ZIP / LOCAL.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-08  |  4.4 KB  |  156 lines

  1. /*
  2.     LOCAL.C -- Illustrating the local heap information structure
  3.  
  4.     From Chapter 5 of "Undocumented Windows" (Addison-Wesley 1992)
  5.     by Andrew Schulman, Dave Maxey and Matt Pietrek
  6.  
  7.     Build using: WINIOBC LOCAL HANDLES (for Borland C++ v3.00)
  8.                  WINIOMS LOCAL HANDLES (for Microsoft C/SDK)
  9. */
  10. /* local.c */
  11.  
  12. #include <windows.h>
  13. #include <stdlib.h>
  14. #include <dos.h>
  15. #include "winio.h"
  16. #include "handles.h"
  17.  
  18. #pragma pack(1)
  19.  
  20. /* Local Heap information structure -- similar to Global
  21.    Heap information structure (Burgermaster).  The KRNL286 and
  22.    KRNL386 versions differ only in the size of the "first",
  23.    "last", and "disctotal" fields */
  24. #define DEFINE_LOCALHEAPINFO_STRUCT(STRUCTNAME, W_OR_DW) \
  25. typedef struct { \
  26.     WORD check; \
  27.     WORD freeze; \
  28.     WORD items; \
  29.     W_OR_DW first; \
  30.     W_OR_DW last; \
  31.     BYTE numcompact; \
  32.     BYTE disclevel; \
  33.     W_OR_DW disctotal; \
  34.     WORD moveable_tbl; \
  35.     WORD moveable_next; \
  36.     WORD delta; \
  37.     WORD unknown2; \
  38.     WORD unknown3; \
  39.     DWORD notifyfunc; \
  40.     WORD sem; \
  41.     WORD unknown4; \
  42.     WORD unknown5; \
  43.     WORD signature; \
  44. } STRUCTNAME;
  45.  
  46. DEFINE_LOCALHEAPINFO_STRUCT(LOCAL_HEAP, WORD);
  47. DEFINE_LOCALHEAPINFO_STRUCT(LOCAL_HEAP_32, DWORD);
  48.  
  49. /* Local Arena header is same for KRNL286 and KRNL386 */
  50. typedef struct {
  51.     WORD prev;      // includes USED/FREE in bottom bit
  52.     WORD next;
  53.     } LOCAL_ARENA;
  54.     
  55. typedef struct {
  56.     WORD handle;
  57.     BYTE flags;
  58.     BYTE lock;
  59.     } MOVEABLE_HANDLE;
  60.  
  61. BYTE far *MakeLocalHeap(size_t size);
  62. void show(WORD h, WORD size, WORD prev, WORD next, WORD in_use);
  63. int axtoi(char *s);
  64.  
  65. int main(int argc, char *argv[])
  66. {
  67.     extern WORD __hInst;
  68.     LOCAL_ARENA far *lpla;
  69.     WORD next, last, items, wMoveTab, wMoveNext, wMoveNum;
  70.     WORD seg = HandleToSel((argc < 2) ? __hInst : axtoi(argv[1]));
  71.     WORD heap = *((WORD far *) MK_FP(seg, 6));
  72.     BYTE FAR *lpHeap = MK_FP(seg, heap);
  73.     
  74.     winio_about("LOCAL"
  75.         "\nIllustrating the local heap information structure"
  76.         "\nUsage: LOCAL [seg]"
  77.         "\n\nFrom Chapter 5 of"
  78.         "\n\"Undocumented Windows\" (Addison-Wesley, 1992)"
  79.         "\nby Andrew Schulman, David Maxey and Matt Pietrek"
  80.         );
  81.     
  82.     if (! IsValidLocalHeap(lpHeap))
  83.         fail("Not a valid local heap!");
  84.     printf("Local Heap at %Fp\n", lpHeap);
  85.     
  86.     if (Kernel1632() == 16)
  87.     {
  88.         LOCAL_HEAP far *lplh = lpHeap;
  89.         next = lplh->first;
  90.         last = lplh->last;
  91.         items = lplh->items;
  92.         wMoveTab = lplh->moveable_tbl;
  93.         wMoveNext = lplh->moveable_next;
  94.     }
  95.     else
  96.     {
  97.         LOCAL_HEAP_32 far *lplh32 = lpHeap;
  98.         next = lplh32->first;   // truncate to 16 bits
  99.         last = lplh32->last;
  100.         items = lplh32->items;
  101.         wMoveTab = lplh32->moveable_tbl;
  102.         wMoveNext = lplh32->moveable_next;
  103.     }
  104.  
  105.     printf("%d items in heap\n", items);
  106.     
  107.     // show LMEM_FIXED allocations and FREE blocks
  108.     while (last - next)
  109.     {
  110.         lpla = MK_FP(seg, next);    // far pointer to arena header
  111.         show(next+4,                // handle for this item (skip header)
  112.              lpla->next - (next+4), // size = next - this
  113.              lpla->prev & ~1,       // prev (mask off USED/FREE bit)
  114.              lpla->next,            // next
  115.              lpla->prev & 1);       // IN USE or FREE (bottom bit of prev)
  116.         next = lpla->next;
  117.     }
  118.     lpla = MK_FP(seg, last);
  119.     show(last+4, 0, lpla->prev & ~1, lpla->next, lpla->prev & 1);
  120.  
  121.     // show LMEM_MOVEABLE allocations
  122.     printf("\nMoveable handle table: %04x, next=%04x\n", 
  123.         wMoveTab, wMoveNext);
  124.     wMoveNum = *((WORD far *) MK_FP(seg, wMoveTab));
  125.     printf("%u moveable handles\n", wMoveNum);
  126.     if (wMoveNum)
  127.     {
  128.         MOVEABLE_HANDLE far *tab = MK_FP(seg, wMoveTab+2);
  129.         MOVEABLE_HANDLE far *fp;
  130.         int i;
  131.         for (i=0, fp=tab; i<wMoveNum; i++, fp++)
  132.             if (fp->lock != 0xFF)
  133.                 printf("%Fp ==> %04x lock=%d\n", fp, fp->handle, fp->lock);
  134.     }
  135.     return 0;
  136. }
  137.  
  138. void show(WORD h, WORD size, WORD prev, WORD next, WORD in_use)
  139. {
  140.     printf("%04x (%04x)\t%04x bytes\tp=%04x n=%04x\t%s\n",
  141.         h, h-4, size, prev, next, (in_use) ? "USE" : "FREE");
  142. }
  143.         
  144. int axtoi(char *s)
  145. {
  146.     if (s[0]=='0' && s[1]=='x')
  147.     {
  148.         int ret;
  149.         sscanf(s+2, "%x", &ret);
  150.         return ret;
  151.     }
  152.     else
  153.         return atoi(s);
  154. }
  155.  
  156.