Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

246 lines
6.4 KiB

/**************************************************************************
* GLOBAL.C
*
* Routines used to walk the global heap.
*
**************************************************************************/
#include "toolpriv.h"
#include <newexe.h>
#include <string.h>
/* GlobalInfo
* Reports information about the state of the global heap,
* specifically, the number of elements that will be returned by
* a global heap walk.
*/
BOOL TOOLHELPAPI GlobalInfo(
GLOBALINFO FAR *lpGlobalInfo)
{
/* Check the structure size and verify proper installation */
if (!wLibInstalled || lpGlobalInfo->dwSize != sizeof (GLOBALINFO))
return FALSE;
/* Get the item counts */
if (wTHFlags & TH_KERNEL_386)
{
lpGlobalInfo->wcItems = Walk386Count(GLOBAL_ALL);
lpGlobalInfo->wcItemsFree = Walk386Count(GLOBAL_FREE);
lpGlobalInfo->wcItemsLRU = Walk386Count(GLOBAL_LRU);
}
else
{
lpGlobalInfo->wcItems = Walk286Count(GLOBAL_ALL);
lpGlobalInfo->wcItemsFree = Walk286Count(GLOBAL_FREE);
lpGlobalInfo->wcItemsLRU = Walk286Count(GLOBAL_LRU);
}
return TRUE;
}
/* GlobalFirst
* Finds the first element in the global heap. This is modified by
* wFlags which modifies which list (GLOBAL_ALL, GLOBAL_FREE,
* GLOBAL_LRU) should be walked
*/
BOOL TOOLHELPAPI GlobalFirst(
GLOBALENTRY FAR *lpGlobal,
WORD wFlags)
{
DWORD dwFirst;
/* Check the structure size and verify proper installation */
if (!wLibInstalled || !lpGlobal ||
lpGlobal->dwSize != sizeof (GLOBALENTRY))
return FALSE;
/* Call the appropriate low-level routine to find the first block */
if (wTHFlags & TH_KERNEL_386)
{
/* Get the first item. Return false if no items in this list */
if (!(dwFirst = Walk386First(wFlags)))
return FALSE;
/* Return information about this first item */
Walk386(dwFirst, lpGlobal, wFlags);
}
else
{
/* Get the first item. Return false if no items in this list */
if (!(dwFirst = Walk286First(wFlags)))
return FALSE;
/* Return information about this first item */
Walk286(dwFirst, lpGlobal, wFlags);
}
/* Guess at the type of the object */
HelperGlobalType(lpGlobal);
return TRUE;
}
/* GlobalNext
* Returns the next item in the chain pointed to by lpGlobal and
* in the list indicated by wFlags (same choices as for GlobalFirst().
*/
BOOL TOOLHELPAPI GlobalNext(
GLOBALENTRY FAR *lpGlobal,
WORD wFlags)
{
DWORD dwNext;
/* Check the structure size and verify proper installation */
if (!wLibInstalled || !lpGlobal ||
lpGlobal->dwSize != sizeof (GLOBALENTRY))
return FALSE;
/* Check to see if we're at the end of the list */
dwNext = wFlags & 3 ? lpGlobal->dwNextAlt : lpGlobal->dwNext;
if (!dwNext)
return FALSE;
/* If we're using the 386 kernel, call the 386 heap walk routine with
* a pointer to the appropriate heap item
* (Note that this depends on GLOBAL_ALL being zero)
*/
if (wTHFlags & TH_KERNEL_386)
Walk386(dwNext, lpGlobal, wFlags);
else
Walk286(dwNext, lpGlobal, wFlags);
/* Guess at the type of the object */
HelperGlobalType(lpGlobal);
return TRUE;
}
/* GlobalEntryHandle
* Used to find information about a global heap entry. Information
* about this entry is returned in the structure.
*/
BOOL TOOLHELPAPI GlobalEntryHandle(
GLOBALENTRY FAR *lpGlobal,
HANDLE hItem)
{
DWORD dwBlock;
/* Check the structure size and verify proper installation */
if (!wLibInstalled || !lpGlobal ||
lpGlobal->dwSize != sizeof (GLOBALENTRY))
return FALSE;
/* Make sure this is a valid block */
if (wTHFlags & TH_KERNEL_386)
{
if (!(dwBlock = Walk386Handle(hItem)))
return FALSE;
}
else
{
if (!(dwBlock = Walk286Handle(hItem)))
return FALSE;
}
/* Return information about this item */
if (wTHFlags & TH_KERNEL_386)
Walk386(dwBlock, lpGlobal, GLOBAL_ALL);
else
Walk286(dwBlock, lpGlobal, GLOBAL_ALL);
/* Guess at the type of the object */
HelperGlobalType(lpGlobal);
return TRUE;
}
/* GlobalEntryModule
* Returns global information about the block with the given module
* handle and segment number.
*/
BOOL TOOLHELPAPI GlobalEntryModule(
GLOBALENTRY FAR *lpGlobal,
HANDLE hModule,
WORD wSeg)
{
struct new_exe FAR *lpNewExe;
struct new_seg1 FAR *lpSeg;
DWORD dwBlock;
/* Check the structure size and verify proper installation */
if (!wLibInstalled || !lpGlobal ||
lpGlobal->dwSize != sizeof (GLOBALENTRY))
return FALSE;
/* Grunge in the module database to find the proper selector. Start
* by first verifying the module database pointer
*/
if (!HelperVerifySeg(hModule, sizeof (struct new_exe)))
return FALSE;
/* Get a pointer to the module database */
lpNewExe = MAKEFARPTR(hModule, 0);
/* Make sure this is a module database */
if (lpNewExe->ne_magic != NEMAGIC)
return FALSE;
/* See if the number requested is past the end of the segment table.
* Note that the first segment is segment 1.
*/
--wSeg;
if (lpNewExe->ne_cseg <= wSeg)
return FALSE;
/* Get a pointer to the segment table */
lpSeg = MAKEFARPTR(hModule, lpNewExe->ne_segtab);
/* Jump to the right spot in the segment table */
lpSeg += wSeg;
/* Make sure this is a valid block and get its arena pointer */
if (wTHFlags & TH_KERNEL_386)
{
if (!(dwBlock = Walk386Handle(lpSeg->ns_handle)))
return FALSE;
}
else
{
if (!(dwBlock = Walk286Handle(lpSeg->ns_handle)))
return FALSE;
}
/* Return information about this item */
if (wTHFlags & TH_KERNEL_386)
Walk386(dwBlock, lpGlobal, GLOBAL_ALL);
else
Walk286(dwBlock, lpGlobal, GLOBAL_ALL);
/* Guess at the type of the object */
HelperGlobalType(lpGlobal);
/* If we've gotten to here, it must be OK */
return TRUE;
}
/* GlobalHandleToSel
* Provides a generic method of converting a handle to a selector.
* This works across Windows versions as well as working when the
* value is already a selector.
*/
WORD TOOLHELPAPI GlobalHandleToSel(
HANDLE hMem)
{
return HelperHandleToSel(hMem);
}