157 lines
4.3 KiB
C
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;
|
|
}
|
|
|