Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

1369 lines
32 KiB

/*++
Copyright (c) 1995 Microsoft Corporation
Module Name:
symbols.c
Abstract:
This function implements a generic simple symbol handler.
Author:
Wesley Witt (wesw) 1-Sep-1994
Environment:
User Mode
--*/
#include "private.h"
#include "symbols.h"
BOOL
IMAGEAPI
SympGetSymNextPrev(
IN HANDLE hProcess,
IN OUT PIMAGEHLP_SYMBOL Symbol,
IN int Direction
);
//
// globals
//
LIST_ENTRY ProcessList;
BOOL SymInitialized;
DWORD SymOptions = SYMOPT_UNDNAME;
BOOL
IMAGEAPI
SymInitialize(
IN HANDLE hProcess,
IN LPSTR UserSearchPath,
IN BOOL InvadeProcess
)
/*++
Routine Description:
This function initializes the symbol handler for
a process. The process is identified by the
process handle passed into this function.
Arguments:
hProcess - Process handle. If InvadeProcess is FALSE
then this can be any unique value that identifies
the process to the symbol handler.
UserSearchPath - Pointer to a string of paths separated by semicolons.
These paths are used to search for symbol files.
The value NULL is acceptable.
InvadeProcess - If this is set to TRUE then the process identified
by the process handle is "invaded" and it's loaded
module list is enumerated. Each module is added
to the symbol handler and symbols are attempted
to be loaded.
Return Value:
TRUE - The symbol handler was successfully initialized.
FALSE - The initialization failed. Call GetLastError to
discover the cause of the failure.
--*/
{
PPROCESS_ENTRY ProcessEntry;
DWORD Status;
__try {
if (!SymInitialized) {
SymInitialized = TRUE;
InitializeListHead( &ProcessList );
}
if (FindProcessEntry( hProcess )) {
return TRUE;
}
ProcessEntry = (PPROCESS_ENTRY) MemAlloc( sizeof(PROCESS_ENTRY) );
if (!ProcessEntry) {
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
return FALSE;
}
ZeroMemory( ProcessEntry, sizeof(PROCESS_ENTRY) );
ProcessEntry->hProcess = hProcess;
InitializeListHead( &ProcessEntry->ModuleList );
InsertTailList( &ProcessList, &ProcessEntry->ListEntry );
if (!SymSetSearchPath( hProcess, UserSearchPath )) {
//
// last error code was set by SymSetSearchPath, so just return
//
SymCleanup( hProcess );
return FALSE;
}
if (InvadeProcess) {
Status = GetProcessModules( hProcess, InternalGetModule, NULL );
if (Status) {
SymCleanup( hProcess );
SetLastError( Status );
return FALSE;
}
}
} __except (EXCEPTION_EXECUTE_HANDLER) {
SetLastError( GetExceptionCode() );
return FALSE;
}
return TRUE;
}
BOOL
IMAGEAPI
SymCleanup(
HANDLE hProcess
)
/*++
Routine Description:
This function cleans up the symbol handler's data structures
for a previously initialized process.
Arguments:
hProcess - Process handle.
Return Value:
TRUE - The symbol handler was successfully cleaned up.
FALSE - The cleanup failed. Call GetLastError to
discover the cause of the failure.
--*/
{
PPROCESS_ENTRY ProcessEntry;
PLIST_ENTRY Next;
PMODULE_ENTRY ModuleEntry;
__try {
ProcessEntry = FindProcessEntry( hProcess );
if (!ProcessEntry) {
SetLastError( ERROR_INVALID_HANDLE );
return FALSE;
}
Next = ProcessEntry->ModuleList.Flink;
if (Next) {
while ((ULONG)Next != (ULONG)&ProcessEntry->ModuleList) {
ModuleEntry = CONTAINING_RECORD( Next, MODULE_ENTRY, ListEntry );
Next = ModuleEntry->ListEntry.Flink;
FreeModuleEntry( ModuleEntry );
}
}
if (ProcessEntry->SymbolSearchPath) {
MemFree( ProcessEntry->SymbolSearchPath );
}
RemoveEntryList( &ProcessEntry->ListEntry );
MemFree( ProcessEntry );
} __except (EXCEPTION_EXECUTE_HANDLER) {
SetLastError( GetExceptionCode() );
return FALSE;
}
return TRUE;
}
DWORD
IMAGEAPI
SymSetOptions(
DWORD UserOptions
)
/*++
Routine Description:
This function changes the symbol handler's option mask.
Arguments:
UserOptions - The new options mask.
Return Value:
The new mask is returned.
--*/
{
SymOptions = UserOptions;
return SymOptions;
}
DWORD
IMAGEAPI
SymGetOptions(
VOID
)
/*++
Routine Description:
This function queries the symbol handler's option mask.
Arguments:
None.
Return Value:
The current options mask is returned.
--*/
{
return SymOptions;
}
BOOL
IMAGEAPI
SymEnumerateModules(
IN HANDLE hProcess,
IN PSYM_ENUMMODULES_CALLBACK EnumModulesCallback,
IN PVOID UserContext
)
/*++
Routine Description:
This function enumerates all of the modules that are currently
loaded into the symbol handler.
Arguments:
hProcess - Process handle, must have been previously registered
with SymInitialize.
EnumModulesCallback - Callback pointer that is called once for each
module that is enumerated. If the enum callback
returns FALSE then the enumeration is terminated.
UserContext - This data is simply passed on to the callback function
and is completly user defined.
Return Value:
TRUE - The modules were successfully enumerated.
FALSE - The enumeration failed. Call GetLastError to
discover the cause of the failure.
--*/
{
PPROCESS_ENTRY ProcessEntry;
PMODULE_ENTRY ModuleEntry;
PLIST_ENTRY Next;
__try {
ProcessEntry = FindProcessEntry( hProcess );
if (!ProcessEntry) {
SetLastError( ERROR_INVALID_HANDLE );
return FALSE;
}
Next = ProcessEntry->ModuleList.Flink;
if (Next) {
while ((ULONG)Next != (ULONG)&ProcessEntry->ModuleList) {
ModuleEntry = CONTAINING_RECORD( Next, MODULE_ENTRY, ListEntry );
Next = ModuleEntry->ListEntry.Flink;
if (!EnumModulesCallback( ModuleEntry->ModuleName, ModuleEntry->BaseOfDll, UserContext )) {
break;
}
}
}
} __except (EXCEPTION_EXECUTE_HANDLER) {
SetLastError( GetExceptionCode() );
return FALSE;
}
return TRUE;
}
BOOL
IMAGEAPI
SymEnumerateSymbols(
IN HANDLE hProcess,
IN ULONG BaseOfDll,
IN PSYM_ENUMSYMBOLS_CALLBACK EnumSymbolsCallback,
IN PVOID UserContext
)
/*++
Routine Description:
This function enumerates all of the symbols contained the module
specified by the BaseOfDll argument.
Arguments:
hProcess - Process handle, must have been previously registered
with SymInitialize
BaseOfDll - Base address of the DLL that symbols are to be
enumerated for
EnumSymbolsCallback - User specified callback routine for enumeration
notification
UserContext - Pass thru variable, this is simply passed thru to the
callback function
Return Value:
TRUE - The symbols were successfully enumerated.
FALSE - The enumeration failed. Call GetLastError to
discover the cause of the failure.
--*/
{
PPROCESS_ENTRY ProcessEntry;
PLIST_ENTRY Next;
PMODULE_ENTRY ModuleEntry;
DWORD i;
PSYMBOL_ENTRY sym;
LPSTR szSymName;
IMAGEHLP_SYMBOL SymExt;
__try {
ProcessEntry = FindProcessEntry( hProcess );
if (!ProcessEntry) {
SetLastError( ERROR_INVALID_HANDLE );
return FALSE;
}
Next = ProcessEntry->ModuleList.Flink;
if (Next) {
while ((ULONG)Next != (ULONG)&ProcessEntry->ModuleList) {
ModuleEntry = CONTAINING_RECORD( Next, MODULE_ENTRY, ListEntry );
Next = ModuleEntry->ListEntry.Flink;
if (ModuleEntry->BaseOfDll == BaseOfDll) {
if (ModuleEntry->Flags & MIF_DEFERRED_LOAD) {
if ((ModuleEntry->Flags & MIF_NO_SYMBOLS) ||
!CompleteDeferredSymbolLoad( hProcess, ModuleEntry )) {
continue;
}
}
if (ModuleEntry->SymType == SymPdb) {
DATASYM32 *dataSym = (DATASYM32*)GSINextSym( ModuleEntry->gsi, NULL );
PIMAGE_SECTION_HEADER sh;
DWORD addr;
ULONG k;
LPSTR SymbolName;
CHAR SymbolLen;
while( dataSym ) {
SymbolName = DataSymNameStart(dataSym);
SymbolLen = DataSymNameLength(dataSym);
for (k=0,addr=0,sh=ModuleEntry->SectionHdrs; k<ModuleEntry->NumSections; k++, sh++) {
if (k+1 == DataSymSeg(dataSym)) {
addr = sh->VirtualAddress + DataSymOffset(dataSym) + ModuleEntry->BaseOfDll;
break;
}
}
if (addr) {
if (SymbolName[0] == '?' && SymbolName[1] == '?' &&
SymbolName[2] == '_' && SymbolName[3] == 'C' ) {
//
// ignore strings
//
} else {
if (SymOptions & SYMOPT_UNDNAME) {
SymUnDNameInternal( ModuleEntry->TmpSym.Name, TMP_SYM_LEN-sizeof(ModuleEntry->TmpSym), SymbolName, SymbolLen);
} else {
ModuleEntry->TmpSym.Name[0] = 0;
strncat( ModuleEntry->TmpSym.Name, SymbolName, TMP_SYM_LEN-sizeof(ModuleEntry->TmpSym) );
}
if (ModuleEntry->cOmapFrom) {
DWORD Bias = 0;
addr = ConvertOmapFromSrc( ModuleEntry, addr, &Bias );
if (addr) {
addr += Bias;
}
}
if (!EnumSymbolsCallback( ModuleEntry->TmpSym.Name, addr, 0, UserContext )) {
break;
}
}
}
dataSym = (DATASYM32*)GSINextSym( ModuleEntry->gsi, (PUCHAR)dataSym );
}
return TRUE;
}
for (i=0; i<ModuleEntry->numsyms; i++) {
sym=&ModuleEntry->symbolTable[i];
ModuleEntry->TmpSym.Name[0] = 0;
strncat( ModuleEntry->TmpSym.Name, sym->Name, TMP_SYM_LEN );
if (!EnumSymbolsCallback( ModuleEntry->TmpSym.Name, sym->Address, sym->Size, UserContext )) {
break;
}
}
break;
}
}
}
} __except (EXCEPTION_EXECUTE_HANDLER) {
SetLastError( GetExceptionCode() );
return FALSE;
}
return TRUE;
}
BOOL
IMAGEAPI
SymGetSymFromAddr(
IN HANDLE hProcess,
IN DWORD Address,
OUT PDWORD Displacement,
OUT PIMAGEHLP_SYMBOL Symbol
)
/*++
Routine Description:
This function finds an entry in the symbol table based on an address.
Arguments:
hProcess - Process handle, must have been previously registered
with SymInitialize.
Address - Address of the desired symbol.
Displacement - This value is set to the offset from the beginning
of the symbol.
Return Value:
Non NULL pointer - The symbol was located.
NULL pointer - The symbol was not found. Call GetLastError to
discover the cause of the failure.
--*/
{
PPROCESS_ENTRY ProcessEntry;
PMODULE_ENTRY mi;
PSYMBOL_ENTRY sym;
__try {
ProcessEntry = FindProcessEntry( hProcess );
if (!ProcessEntry) {
SetLastError( ERROR_INVALID_HANDLE );
return FALSE;
}
mi = GetModuleForPC( ProcessEntry, Address, FALSE );
if (mi == NULL) {
SetLastError( ERROR_MOD_NOT_FOUND );
return FALSE;
}
if ((mi->Flags & MIF_DEFERRED_LOAD) && !(mi->Flags & MIF_NO_SYMBOLS) ) {
if (!CompleteDeferredSymbolLoad( hProcess, mi )) {
SetLastError( ERROR_MOD_NOT_FOUND );
return FALSE;
}
}
sym = GetSymFromAddr( Address, Displacement, mi );
if (!sym) {
SetLastError( ERROR_INVALID_ADDRESS );
return FALSE;
}
symcpy( Symbol, sym );
} __except (EXCEPTION_EXECUTE_HANDLER) {
SetLastError( GetExceptionCode() );
return FALSE;
}
return TRUE;
}
BOOL
IMAGEAPI
SymGetSymFromName(
IN HANDLE hProcess,
IN LPSTR Name,
OUT PIMAGEHLP_SYMBOL Symbol
)
/*++
Routine Description:
This function finds an entry in the symbol table based on a name.
Arguments:
hProcess - Process handle, must have been previously registered
with SymInitialize.
SymName - A string containing the symbol name.
Return Value:
Non NULL pointer - The symbol was located.
NULL pointer - The symbol was not found. Call GetLastError to
discover the cause of the failure.
--*/
{
PSYMBOL_ENTRY sym;
LPSTR p;
PPROCESS_ENTRY ProcessEntry;
PMODULE_ENTRY mi = NULL;
PLIST_ENTRY Next;
__try {
ProcessEntry = FindProcessEntry( hProcess );
if (!ProcessEntry) {
SetLastError( ERROR_INVALID_HANDLE );
return FALSE;
}
p = strchr( Name, '!' );
if (p) {
//
// the caller wants to look in a specific module
//
*p = 0;
Next = ProcessEntry->ModuleList.Flink;
if (Next) {
while ((ULONG)Next != (ULONG)&ProcessEntry->ModuleList) {
mi = CONTAINING_RECORD( Next, MODULE_ENTRY, ListEntry );
Next = mi->ListEntry.Flink;
if ((_stricmp( mi->ModuleName, Name ) == 0) ||
(mi->AliasName[0] && _stricmp( mi->AliasName, Name ) == 0)) {
if ((mi->Flags & MIF_DEFERRED_LOAD) && !(mi->Flags & MIF_NO_SYMBOLS) ) {
if (!CompleteDeferredSymbolLoad( hProcess, mi )) {
break;
}
}
*p = '!';
sym = FindSymbolByName( ProcessEntry, mi, p+1 );
if (sym) {
symcpy( Symbol, sym );
return TRUE;
}
break;
}
}
}
*p = '!';
SetLastError( ERROR_MOD_NOT_FOUND );
return FALSE;
}
Next = ProcessEntry->ModuleList.Flink;
if (!Next) {
SetLastError( ERROR_MOD_NOT_FOUND );
return FALSE;
}
while ((ULONG)Next != (ULONG)&ProcessEntry->ModuleList) {
mi = CONTAINING_RECORD( Next, MODULE_ENTRY, ListEntry );
Next = mi->ListEntry.Flink;
if ((mi->Flags & MIF_DEFERRED_LOAD) && !(mi->Flags & MIF_NO_SYMBOLS) ) {
if (!CompleteDeferredSymbolLoad( hProcess, mi )) {
continue;
}
}
sym = FindSymbolByName( ProcessEntry, mi, Name );
if (sym) {
symcpy( Symbol, sym );
return TRUE;
}
}
SetLastError( ERROR_MOD_NOT_FOUND );
return FALSE;
} __except (EXCEPTION_EXECUTE_HANDLER) {
SetLastError( GetExceptionCode() );
return FALSE;
}
SetLastError( ERROR_INVALID_FUNCTION );
return FALSE;
}
BOOL
IMAGEAPI
SymGetSymNext(
IN HANDLE hProcess,
IN OUT PIMAGEHLP_SYMBOL Symbol
)
/*++
Routine Description:
This function finds the next symbol in the symbol table that falls
sequentially after the symbol passed in.
Arguments:
hProcess - Process handle, must have been previously registered
with SymInitialize.
Symbol - Starting symbol.
Return Value:
Non NULL pointer - The symbol was located.
NULL pointer - The symbol was not found. Call GetLastError to
discover the cause of the failure.
--*/
{
return SympGetSymNextPrev(hProcess, Symbol, 1);
}
BOOL
IMAGEAPI
SymGetSymPrev(
IN HANDLE hProcess,
IN OUT PIMAGEHLP_SYMBOL Symbol
)
/*++
Routine Description:
This function finds the next symbol in the symbol table that falls
sequentially after the symbol passed in.
Arguments:
hProcess - Process handle, must have been previously registered
with SymInitialize.
Symbol - Starting symbol.
Return Value:
Non NULL pointer - The symbol was located.
NULL pointer - The symbol was not found. Call GetLastError to
discover the cause of the failure.
--*/
{
return SympGetSymNextPrev(hProcess, Symbol, -1);
}
BOOL
IMAGEAPI
SympGetSymNextPrev(
IN HANDLE hProcess,
IN OUT PIMAGEHLP_SYMBOL Symbol,
IN int Direction
)
/*++
Routine Description:
Common code for SymGetSymNext and SymGetSymPrev.
Arguments:
hProcess - Process handle, must have been previously registered
with SymInitialize.
Symbol - Starting symbol.
Dir - Supplies direction to search
Return Value:
Non NULL pointer - The symbol was located.
NULL pointer - The symbol was not found. Call GetLastError to
discover the cause of the failure.
--*/
{
PPROCESS_ENTRY ProcessEntry;
PMODULE_ENTRY mi;
PSYMBOL_ENTRY sym;
ULONG Displacement;
__try {
ProcessEntry = FindProcessEntry( hProcess );
if (!ProcessEntry) {
SetLastError( ERROR_INVALID_HANDLE );
return FALSE;
}
mi = GetModuleForPC( ProcessEntry, Symbol->Address, FALSE );
if (mi == NULL) {
SetLastError( ERROR_MOD_NOT_FOUND );
return FALSE;
}
if ((mi->Flags & MIF_DEFERRED_LOAD) && !(mi->Flags & MIF_NO_SYMBOLS) ) {
if (!CompleteDeferredSymbolLoad( hProcess, mi )) {
SetLastError( ERROR_MOD_NOT_FOUND );
return FALSE;
}
}
sym = GetSymFromAddr( Symbol->Address, &Displacement, mi );
if (!sym) {
SetLastError( ERROR_INVALID_ADDRESS );
return FALSE;
}
if (Direction > 0 && sym+1 >= mi->symbolTable+mi->numsyms) {
SetLastError( ERROR_INVALID_ADDRESS );
return FALSE;
} else if (Direction < 0 && sym-1 < mi->symbolTable) {
SetLastError( ERROR_INVALID_ADDRESS );
return FALSE;
}
symcpy( Symbol, sym + Direction );
return TRUE;
} __except (EXCEPTION_EXECUTE_HANDLER) {
SetLastError( GetExceptionCode() );
return FALSE;
}
return FALSE;
}
LPVOID
IMAGEAPI
SymFunctionTableAccess(
HANDLE hProcess,
DWORD AddrBase
)
/*++
Routine Description:
This function finds an entry in the symbol table based on a name.
Arguments:
hProcess - Process handle, must have been previously registered
with SymInitialize.
SymName - A string containing the symbol name.
Return Value:
Non NULL pointer - The symbol was located.
NULL pointer - The symbol was not found. Call GetLastError to
discover the cause of the failure.
--*/
{
PPROCESS_ENTRY ProcessEntry;
PMODULE_ENTRY mi;
PVOID rtf;
__try {
ProcessEntry = FindProcessEntry( hProcess );
if (!ProcessEntry) {
SetLastError( ERROR_INVALID_HANDLE );
return NULL;
}
mi = GetModuleForPC( ProcessEntry, AddrBase, FALSE );
if (mi == NULL) {
SetLastError( ERROR_MOD_NOT_FOUND );
return NULL;
}
if ((mi->Flags & MIF_DEFERRED_LOAD) && !(mi->Flags & MIF_NO_SYMBOLS) ) {
if (!CompleteDeferredSymbolLoad( hProcess, mi )) {
SetLastError( ERROR_MOD_NOT_FOUND );
return NULL;
}
}
if (mi->cOmapTo) {
DWORD SaveAddr = AddrBase;
DWORD Bias = 0;
AddrBase = ConvertOmapToSrc( mi, AddrBase, &Bias );
if (!AddrBase) {
AddrBase = SaveAddr;
}
}
if (mi->pFpoData) {
rtf = SwSearchFpoData( AddrBase - mi->BaseOfDll, mi->pFpoData, mi->dwEntries );
} else {
rtf = LookupFunctionEntry( mi->pExceptionData, mi->dwEntries, AddrBase );
}
if (!rtf) {
SetLastError( ERROR_INVALID_ADDRESS );
return NULL;
}
} __except (EXCEPTION_EXECUTE_HANDLER) {
SetLastError( GetExceptionCode() );
return NULL;
}
return rtf;
}
BOOL
IMAGEAPI
SymGetModuleInfo(
IN HANDLE hProcess,
IN DWORD dwAddr,
OUT PIMAGEHLP_MODULE ModuleInfo
)
{
PPROCESS_ENTRY ProcessEntry;
PMODULE_ENTRY mi;
__try {
ProcessEntry = FindProcessEntry( hProcess );
if (!ProcessEntry) {
return FALSE;
}
mi = GetModuleForPC( ProcessEntry, dwAddr, FALSE );
if (mi == NULL) {
return FALSE;
}
ZeroMemory( ModuleInfo, sizeof(IMAGEHLP_MODULE) );
ModuleInfo->BaseOfImage = mi->BaseOfDll;
ModuleInfo->ImageSize = mi->DllSize;
ModuleInfo->NumSyms = mi->numsyms;
ModuleInfo->CheckSum = mi->CheckSum;
ModuleInfo->TimeDateStamp = mi->TimeDateStamp;
ModuleInfo->SymType = mi->SymType;
strcpy( ModuleInfo->ModuleName, mi->ModuleName );
if (mi->ImageName) {
strcpy( ModuleInfo->ImageName, mi->ImageName );
}
if (mi->LoadedImageName) {
strcpy( ModuleInfo->LoadedImageName, mi->LoadedImageName );
}
} __except (EXCEPTION_EXECUTE_HANDLER) {
SetLastError( GetExceptionCode() );
return FALSE;
}
return TRUE;
}
DWORD
IMAGEAPI
SymGetModuleBase(
IN HANDLE hProcess,
IN DWORD dwAddr
)
{
PPROCESS_ENTRY ProcessEntry;
PMODULE_ENTRY mi;
__try {
ProcessEntry = FindProcessEntry( hProcess );
if (!ProcessEntry) {
return 0;
}
mi = GetModuleForPC( ProcessEntry, dwAddr, FALSE );
if (mi == NULL) {
return 0;
}
} __except (EXCEPTION_EXECUTE_HANDLER) {
SetLastError( GetExceptionCode() );
return FALSE;
}
return mi->BaseOfDll;
}
BOOL
IMAGEAPI
SymUnloadModule(
IN HANDLE hProcess,
IN DWORD BaseOfDll
)
/*++
Routine Description:
Remove the symbols for an image from a process' symbol table.
Arguments:
hProcess - Supplies the token which refers to the process
BaseOfDll - Supplies the offset to the image as supplies by the
LOAD_DLL_DEBUG_EVENT and UNLOAD_DLL_DEBUG_EVENT.
Return Value:
Returns TRUE if the module's symbols were successfully unloaded.
Returns FALSE if the symbol handler does not recognize hProcess or
no image was loaded at the given offset.
--*/
{
PPROCESS_ENTRY ProcessEntry;
PLIST_ENTRY Next;
PMODULE_ENTRY ModuleEntry;
__try {
ProcessEntry = FindProcessEntry( hProcess );
if (!ProcessEntry) {
return FALSE;
}
Next = ProcessEntry->ModuleList.Flink;
if (Next) {
while ((ULONG)Next != (ULONG)&ProcessEntry->ModuleList) {
ModuleEntry = CONTAINING_RECORD( Next, MODULE_ENTRY, ListEntry );
if (ModuleEntry->BaseOfDll == BaseOfDll) {
RemoveEntryList(Next);
FreeModuleEntry(ModuleEntry);
return TRUE;
}
Next = ModuleEntry->ListEntry.Flink;
}
}
} __except (EXCEPTION_EXECUTE_HANDLER) {
SetLastError( GetExceptionCode() );
return FALSE;
}
return FALSE;
}
BOOL
IMAGEAPI
SymLoadModule(
IN HANDLE hProcess,
IN HANDLE hFile,
IN PSTR ImageName,
IN PSTR ModuleName,
IN DWORD BaseOfDll,
IN DWORD DllSize
)
/*++
Routine Description:
Loads the symbols for an image for use by the other Sym functions.
Arguments:
hProcess - Supplies unique process identifier.
ImageName - Supplies the name of the image file.
ModuleName - ???? Supplies the module name that will be returned by
enumeration functions ????
BaseOfDll - Supplies loaded base address of image.
Return Value:
--*/
{
__try {
return InternalLoadModule( hProcess, ImageName, ModuleName, BaseOfDll, DllSize, hFile );
} __except (EXCEPTION_EXECUTE_HANDLER) {
SetLastError( GetExceptionCode() );
return FALSE;
}
}
BOOL
IMAGEAPI
SymUnDName(
IN PIMAGEHLP_SYMBOL sym,
OUT LPSTR UnDecName,
OUT DWORD UnDecNameLength
)
{
__try {
if (SymUnDNameInternal( UnDecName, UnDecNameLength-1, sym->Name, strlen(sym->Name) )) {
return TRUE;
} else {
return FALSE;
}
} __except (EXCEPTION_EXECUTE_HANDLER) {
SetLastError( GetExceptionCode() );
return FALSE;
}
}
BOOL
IMAGEAPI
SymGetSearchPath(
IN HANDLE hProcess,
OUT LPSTR SearchPath,
IN DWORD SearchPathLength
)
/*++
Routine Description:
This function looks up the symbol search path associated with a process.
Arguments:
hProcess - Supplies the token associated with a process.
Return Value:
A pointer to the search path. Returns NULL if the process is not
know to the symbol handler.
--*/
{
PPROCESS_ENTRY ProcessEntry;
__try {
ProcessEntry = FindProcessEntry( hProcess );
if (!ProcessEntry) {
return FALSE;
}
SearchPath[0] = 0;
strncat( SearchPath, ProcessEntry->SymbolSearchPath, SearchPathLength );
} __except (EXCEPTION_EXECUTE_HANDLER) {
SetLastError( GetExceptionCode() );
return FALSE;
}
return TRUE;
}
BOOL
IMAGEAPI
SymSetSearchPath(
HANDLE hProcess,
LPSTR UserSearchPath
)
/*++
Routine Description:
This functions sets the searh path to be used by the symbol loader
for the given process. If UserSearchPath is not supplied, a default
path will be used.
Arguments:
hProcess - Supplies the process token associated with a symbol table.
UserSearchPath - Supplies the new search path to associate with the
process. If this argument is NULL, the following path is generated:
.;%_NT_SYMBOL_PATH%;%_NT_ALTERNATE_SYMBOL_PATH%;%WINDIR%
It is ok if any or all of the environment variables is missing.
Return Value:
A pointer to the new search path. The user should not modify this string.
Returns NULL if the process is not known to the symbol handler.
--*/
{
PPROCESS_ENTRY ProcessEntry;
LPSTR p;
DWORD cbSymPath;
DWORD cb;
__try {
ProcessEntry = FindProcessEntry( hProcess );
if (!ProcessEntry) {
return FALSE;
}
if (ProcessEntry->SymbolSearchPath) {
MemFree(ProcessEntry->SymbolSearchPath);
}
if (UserSearchPath) {
ProcessEntry->SymbolSearchPath = StringDup(UserSearchPath);
} else {
//
// ".;%_NT_SYMBOL_PATH%;%_NT_ALTERNATE_SYMBOL_PATH%;%WINDIR%"
//
cbSymPath = 2; // ".;"
//
// GetEnvironmentVariable returns the size of the string
// INCLUDING the '\0' in this case.
//
cbSymPath += GetEnvironmentVariable( SYMBOL_PATH, NULL, 0 );
cbSymPath += GetEnvironmentVariable( ALTERNATE_SYMBOL_PATH, NULL, 0 );
cbSymPath += GetEnvironmentVariable( WINDIR, NULL, 0 );
p = ProcessEntry->SymbolSearchPath = (LPSTR) MemAlloc( cbSymPath );
if (!p) {
return FALSE;
}
*p++ = '.';
--cbSymPath;
cb = GetEnvironmentVariable(SYMBOL_PATH, p+1, cbSymPath);
if (cb) {
*p = ';';
p += cb+1;
cbSymPath -= cb+1;
}
cb = GetEnvironmentVariable(ALTERNATE_SYMBOL_PATH, p+1, cbSymPath);
if (cb) {
*p = ';';
p += cb+1;
cbSymPath -= cb+1;
}
cb = GetEnvironmentVariable(WINDIR, p+1, cbSymPath);
if (cb) {
*p = ';';
p += cb+1;
}
*p = 0;
}
} __except (EXCEPTION_EXECUTE_HANDLER) {
SetLastError( GetExceptionCode() );
return FALSE;
}
return TRUE;
}
BOOL
IMAGEAPI
EnumerateLoadedModules(
IN HANDLE hProcess,
IN PENUMLOADED_MODULES_CALLBACK EnumLoadedModulesCallback,
IN PVOID UserContext
)
{
LOADED_MODULE lm;
__try {
lm.EnumLoadedModulesCallback = EnumLoadedModulesCallback;
lm.Context = UserContext;
GetProcessModules( hProcess, (PINTERNAL_GET_MODULE)LoadedModuleEnumerator, (PVOID)&lm );
} __except (EXCEPTION_EXECUTE_HANDLER) {
SetLastError( GetExceptionCode() );
return FALSE;
}
return TRUE;
}
BOOL
SymRegisterCallback(
IN HANDLE hProcess,
IN PSYMBOL_REGISTERED_CALLBACK CallbackFunction,
IN PVOID UserContext
)
{
PPROCESS_ENTRY ProcessEntry;
__try {
ProcessEntry = FindProcessEntry( hProcess );
if (!ProcessEntry) {
return FALSE;
}
if (!CallbackFunction) {
return FALSE;
}
ProcessEntry->pCallbackFunction = CallbackFunction;
ProcessEntry->CallbackUserContext = UserContext;
} __except (EXCEPTION_EXECUTE_HANDLER) {
SetLastError( GetExceptionCode() );
return FALSE;
}
return TRUE;
}