home *** CD-ROM | disk | FTP | other *** search
- /*
- NULLSEG.C -- Reports on task's NULL segment
-
- From Chapter 5 of "Undocumented Windows" (Addison-Wesley 1992)
- by Andrew Schulman, Dave Maxey and Matt Pietrek
-
- Build using: WINIOBC NULLSEG HANDLES (for Borland C++ v3.00)
- WINIOMS NULLSEG HANDLES (for Microsoft C/SDK)
-
- Changed from version in book: for 3.0, have to convert hInstance
- to a valid selector
- */
-
- #include <windows.h>
- #include <stdlib.h>
- #include <dos.h>
- #include "winio.h"
- #include "handles.h"
-
- typedef struct {
- WORD wMustBeZero;
- DWORD dwOldSSSP;
- WORD pLocalHeap;
- WORD pAtomTable;
- WORD pStackTop;
- WORD pStackMin;
- WORD pStackBottom;
- } INSTDATA;
-
- extern DWORD FAR PASCAL GetSelectorLimit(WORD sel);
-
- BOOL IsValidNULLSegment(HANDLE h);
- BOOL IsValidLocalHeap(BYTE far *fp);
- WORD HandleToSel(HANDLE h);
- int Kernel1632(void);
- int axtoi(char *s);
-
- main(int argc, char *argv[])
- {
- INSTDATA far *lpInstData;
- BYTE far *lpLocalHeap;
- HANDLE hModule, hDGroup;
-
- winio_about("NULLSEG"
- "\nReports on task or DLL's NULL segment"
- "\nUsage: NULLSEG 0x[taskid] -or- NULLSEG [modname]"
- "\n\nFrom Chapter 5 of"
- "\n\"Undocumented Windows\" (Addison-Wesley, 1992)"
- "\nby Andrew Schulman, David Maxey and Matt Pietrek"
- );
-
- if (argv[1][0] == '0' && argv[1][1] == 'x')
- {
- // assume that hex number on command line is a task
- hDGroup = HINSTANCE_FROM_HTASK(HandleToSel(axtoi(argv[1])));
- hModule = 0; // GetModuleDgroup() not appropriate for tasks
- // because a task can have more than one instance
- // and therefore more than one corresponding DGROUP
- // (for tasks GetModuleDgroup() isn't a true function)
- }
- else if (argc < 2)
- {
- hDGroup = __hInst;
- hModule = GetCurrentModule();
- }
- else
- {
- char *modname = argv[1] ;
- if (! (hModule = GetModuleHandle(modname)))
- fail("Can't locate %s", modname);
- if (! (hDGroup = GetModuleDgroup(hModule)))
- fail("Can't locate %s's DGROUP", modname);
- }
-
- // oops, forgot to do this in version in book!
- hDGroup = HandleToSel(hDGroup);
-
- if (! IsValidNULLSegment(hDGroup))
- fail("Doesn't have a NULL segment");
-
- lpInstData = MK_FP(hDGroup, 0);
-
- // fields starts off holding _rsrvptrs (5) from compiler
- if (lpInstData->dwOldSSSP != 5)
- printf("dwOldSSSP = %Fp\n", lpInstData->dwOldSSSP);
-
- if (lpInstData->pLocalHeap)
- {
- lpLocalHeap = MK_FP(hDGroup, lpInstData->pLocalHeap);
- printf("pLocalHeap = %Fp\n", lpLocalHeap);
- if (! IsValidLocalHeap(lpLocalHeap))
- printf("Not a valid local heap!\n");
- }
- else
- printf("No local heap\n");
-
- if (lpInstData->pAtomTable)
- {
- // for Atom Table structure, see ATOMWALK.C, WINEXP.H
- WORD far *lpAtomTable = MK_FP(hDGroup, lpInstData->pAtomTable);
- printf("pAtomTable = %Fp (%u atoms)\n", lpAtomTable, *lpAtomTable);
- }
- else
- printf("No atom table\n");
-
- printf("pStackTop = %04x\n", lpInstData->pStackTop);
- printf("pStackMin = %04x\n", lpInstData->pStackMin);
- printf("pStackBottom = %04x\n", lpInstData->pStackBottom);
- if (hModule && IsModuleDLL(hModule))
- {
- if (lpInstData->pStackTop || lpInstData->pStackBottom ||
- lpInstData->pStackMin)
- printf("Error - DLLs don't have stacks!\n");
- else
- printf("DLL - no stack\n");
- }
- else
- {
- printf("Stack used = %04x\n",
- lpInstData->pStackBottom - lpInstData->pStackMin);
- printf("Stack size = %04x\n",
- lpInstData->pStackBottom - lpInstData->pStackTop);
- }
-
- return 0;
- }
-
- BOOL IsValidNULLSegment(HANDLE h)
- {
- INSTDATA far *lpInstData;
-
- if (! verr(h))
- return FALSE;
- if (GetSelectorLimit(h) < 16)
- return FALSE;
- lpInstData = MK_FP(h, 0);
- if (lpInstData->wMustBeZero != 0)
- return FALSE;
- if (lpInstData->pLocalHeap == 0)
- return TRUE; // it's ok to not have a local heap!
- return IsValidLocalHeap(MK_FP(h, lpInstData->pLocalHeap));
- }
-
- int axtoi(char *s)
- {
- if (s[0]=='0' && s[1]=='x')
- {
- int ret;
- sscanf(s+2, "%x", &ret);
- return ret;
- }
- else
- return atoi(s);
- }
-
-