windows-nt/Source/XPSP1/NT/base/mvdm/wow16/toolhelp/module.c
2020-09-26 16:20:57 +08:00

157 lines
4.3 KiB
C

/*************************************************************************
* MODULE.C
*
* Routines to enumerate the various module headers on the module
* chain.
*
*************************************************************************/
#include "toolpriv.h"
#include <newexe.h>
#include <string.h>
/* ----- Function prototypes ----- */
NOEXPORT BOOL PASCAL ModuleGetInfo(
WORD wModule,
MODULEENTRY FAR *lpModule);
/* ModuleFirst
* Finds the first module in the module list and returns information
* about this module.
*/
BOOL TOOLHELPAPI ModuleFirst(
MODULEENTRY FAR *lpModule)
{
WORD FAR *lpwExeHead;
/* Check the version number and verify proper installation */
if (!wLibInstalled || !lpModule ||
lpModule->dwSize != sizeof (MODULEENTRY))
return FALSE;
/* Get a pointer to the module head */
lpwExeHead = MAKEFARPTR(segKernel, npwExeHead);
/* Use this pointer to get information about this module */
return ModuleGetInfo(*lpwExeHead, lpModule);
}
/* ModuleNext
* Finds the next module in the module list.
*/
BOOL TOOLHELPAPI ModuleNext(
MODULEENTRY FAR *lpModule)
{
/* Check the version number and verify proper installation */
if (!wLibInstalled || !lpModule ||
lpModule->dwSize != sizeof (MODULEENTRY))
return FALSE;
/* Use the next handle to get information about this module */
return ModuleGetInfo(lpModule->wNext, lpModule);
}
/* ModuleFindName
* Finds a module with the given module name and returns information
* about it.
*/
HANDLE TOOLHELPAPI ModuleFindName(
MODULEENTRY FAR *lpModule,
LPCSTR lpstrName)
{
/* Check the version number and verify proper installation */
if (!wLibInstalled || !lpModule || !lpstrName ||
lpModule->dwSize != sizeof (MODULEENTRY))
return NULL;
/* Loop through module chain until we find the name (or maybe we don't) */
if (ModuleFirst(lpModule))
do
{
/* Is this the name? If so, we have the info, so return */
if (!lstrcmp(lpstrName, lpModule->szModule))
return lpModule->hModule;
}
while (ModuleNext(lpModule));
/* If we get here, we didn't find it or there was an error */
return NULL;
}
/* ModuleFindHandle
* Returns information about a module with the given handle.
*/
HANDLE TOOLHELPAPI ModuleFindHandle(
MODULEENTRY FAR *lpModule,
HANDLE hModule)
{
/* Check the version number and verify proper installation */
if (!wLibInstalled || !lpModule || !hModule ||
lpModule->dwSize != sizeof (MODULEENTRY))
return NULL;
/* Use the helper function to find out about this module */
if (!ModuleGetInfo(hModule, lpModule))
return NULL;
return lpModule->hModule;
}
/* ----- Helper functions ----- */
NOEXPORT BOOL PASCAL ModuleGetInfo(
WORD wModule,
MODULEENTRY FAR *lpModule)
{
struct new_exe FAR *lpNewExe;
BYTE FAR *lpb;
/* Verify the segment so we don't GP fault */
if (!HelperVerifySeg(wModule, 2))
return FALSE;
/* Get a pointer to the module database */
lpNewExe = MAKEFARPTR(wModule, 0);
/* Make sure this is a module database */
if (lpNewExe->ne_magic != NEMAGIC)
return FALSE;
/* Get the module name (it's the first name in the resident names
* table
*/
lpb = ((BYTE FAR *)lpNewExe) + lpNewExe->ne_restab;
_fstrncpy(lpModule->szModule, lpb + 1, *lpb);
lpModule->szModule[*lpb] = '\0';
/* Get the EXE file path. A pointer is stored in the same place as
* the high word of the CRC was in the EXE file. (6th word in new_exe)
* This pointer points to the length of a PASCAL string whose first
* eight characters are meaningless to us.
*/
lpb = MAKEFARPTR(wModule, *(((WORD FAR *)lpNewExe) + 5));
_fstrncpy(lpModule->szExePath, lpb + 8, *lpb - 8);
lpModule->szExePath[*lpb - 8] = '\0';
/* Get other information from the EXE Header
* The usage count is stored in the second word of the EXE header
* The handle of the next module in the chain is stored in the
* ne_cbenttab structure member.
*/
lpModule->hModule = wModule;
lpModule->wcUsage = *(((WORD FAR *)lpNewExe) + 1);
lpModule->wNext = lpNewExe->ne_cbenttab;
return TRUE;
}