home *** CD-ROM | disk | FTP | other *** search
- /*
- LOCAL.C -- Illustrating the local heap information structure
-
- From Chapter 5 of "Undocumented Windows" (Addison-Wesley 1992)
- by Andrew Schulman, Dave Maxey and Matt Pietrek
-
- Build using: WINIOBC LOCAL HANDLES (for Borland C++ v3.00)
- WINIOMS LOCAL HANDLES (for Microsoft C/SDK)
- */
- /* local.c */
-
- #include <windows.h>
- #include <stdlib.h>
- #include <dos.h>
- #include "winio.h"
- #include "handles.h"
-
- #pragma pack(1)
-
- /* Local Heap information structure -- similar to Global
- Heap information structure (Burgermaster). The KRNL286 and
- KRNL386 versions differ only in the size of the "first",
- "last", and "disctotal" fields */
- #define DEFINE_LOCALHEAPINFO_STRUCT(STRUCTNAME, W_OR_DW) \
- typedef struct { \
- WORD check; \
- WORD freeze; \
- WORD items; \
- W_OR_DW first; \
- W_OR_DW last; \
- BYTE numcompact; \
- BYTE disclevel; \
- W_OR_DW disctotal; \
- WORD moveable_tbl; \
- WORD moveable_next; \
- WORD delta; \
- WORD unknown2; \
- WORD unknown3; \
- DWORD notifyfunc; \
- WORD sem; \
- WORD unknown4; \
- WORD unknown5; \
- WORD signature; \
- } STRUCTNAME;
-
- DEFINE_LOCALHEAPINFO_STRUCT(LOCAL_HEAP, WORD);
- DEFINE_LOCALHEAPINFO_STRUCT(LOCAL_HEAP_32, DWORD);
-
- /* Local Arena header is same for KRNL286 and KRNL386 */
- typedef struct {
- WORD prev; // includes USED/FREE in bottom bit
- WORD next;
- } LOCAL_ARENA;
-
- typedef struct {
- WORD handle;
- BYTE flags;
- BYTE lock;
- } MOVEABLE_HANDLE;
-
- BYTE far *MakeLocalHeap(size_t size);
- void show(WORD h, WORD size, WORD prev, WORD next, WORD in_use);
- int axtoi(char *s);
-
- int main(int argc, char *argv[])
- {
- extern WORD __hInst;
- LOCAL_ARENA far *lpla;
- WORD next, last, items, wMoveTab, wMoveNext, wMoveNum;
- WORD seg = HandleToSel((argc < 2) ? __hInst : axtoi(argv[1]));
- WORD heap = *((WORD far *) MK_FP(seg, 6));
- BYTE FAR *lpHeap = MK_FP(seg, heap);
-
- winio_about("LOCAL"
- "\nIllustrating the local heap information structure"
- "\nUsage: LOCAL [seg]"
- "\n\nFrom Chapter 5 of"
- "\n\"Undocumented Windows\" (Addison-Wesley, 1992)"
- "\nby Andrew Schulman, David Maxey and Matt Pietrek"
- );
-
- if (! IsValidLocalHeap(lpHeap))
- fail("Not a valid local heap!");
- printf("Local Heap at %Fp\n", lpHeap);
-
- if (Kernel1632() == 16)
- {
- LOCAL_HEAP far *lplh = lpHeap;
- next = lplh->first;
- last = lplh->last;
- items = lplh->items;
- wMoveTab = lplh->moveable_tbl;
- wMoveNext = lplh->moveable_next;
- }
- else
- {
- LOCAL_HEAP_32 far *lplh32 = lpHeap;
- next = lplh32->first; // truncate to 16 bits
- last = lplh32->last;
- items = lplh32->items;
- wMoveTab = lplh32->moveable_tbl;
- wMoveNext = lplh32->moveable_next;
- }
-
- printf("%d items in heap\n", items);
-
- // show LMEM_FIXED allocations and FREE blocks
- while (last - next)
- {
- lpla = MK_FP(seg, next); // far pointer to arena header
- show(next+4, // handle for this item (skip header)
- lpla->next - (next+4), // size = next - this
- lpla->prev & ~1, // prev (mask off USED/FREE bit)
- lpla->next, // next
- lpla->prev & 1); // IN USE or FREE (bottom bit of prev)
- next = lpla->next;
- }
- lpla = MK_FP(seg, last);
- show(last+4, 0, lpla->prev & ~1, lpla->next, lpla->prev & 1);
-
- // show LMEM_MOVEABLE allocations
- printf("\nMoveable handle table: %04x, next=%04x\n",
- wMoveTab, wMoveNext);
- wMoveNum = *((WORD far *) MK_FP(seg, wMoveTab));
- printf("%u moveable handles\n", wMoveNum);
- if (wMoveNum)
- {
- MOVEABLE_HANDLE far *tab = MK_FP(seg, wMoveTab+2);
- MOVEABLE_HANDLE far *fp;
- int i;
- for (i=0, fp=tab; i<wMoveNum; i++, fp++)
- if (fp->lock != 0xFF)
- printf("%Fp ==> %04x lock=%d\n", fp, fp->handle, fp->lock);
- }
- return 0;
- }
-
- void show(WORD h, WORD size, WORD prev, WORD next, WORD in_use)
- {
- printf("%04x (%04x)\t%04x bytes\tp=%04x n=%04x\t%s\n",
- h, h-4, size, prev, next, (in_use) ? "USE" : "FREE");
- }
-
- int axtoi(char *s)
- {
- if (s[0]=='0' && s[1]=='x')
- {
- int ret;
- sscanf(s+2, "%x", &ret);
- return ret;
- }
- else
- return atoi(s);
- }
-
-