Вызов библиотеки DbgHelp
Хотя DbgHelp.dll поставляется со всеми версиями Windows, вызывающие клиенты должны рассмотреть возможность использования одной из более последних версий этой библиотеки DLL, как показано в пакете средств отладки для Windows . Дополнительные сведения о распределении DbgHelp см. в разделе "Версии DbgHelp".
При использовании DbgHelp лучше всего установить копию библиотеки из пакета средств отладки для Windows в каталоге приложений логически рядом с программным обеспечением, вызывающим его. Если сервер символов и исходный сервер также необходимы, то оба SymSrv.dll и SrcSrv.dll должны быть установлены в том же каталоге, что и DbgHelp.dll, так как DbgHelp будет вызывать только эти библиотеки DLL, если они совместно используют один и тот же каталог с ним. (Обратите внимание, что DbgHelp не будет вызывать эти два DLL из стандартного пути поиска.) Это помогает предотвратить использование несовпадных библиотек DLL; Аналогичным образом, он также повышает общую безопасность.
Следующий код извлекается из источника DbgHelp. Здесь показано, как DbgHelp загружает только версии SymSrv.dll и SrcSrv.dll из того же каталога, в котором находится DbgHelp.dll.
HINSTANCE ghinst;
// For calculating the size of arrays for safe string functions.
#ifndef cch
#define ccht(Array, EltType) (sizeof(Array) / sizeof(EltType))
#define cch(Array) ccht(Array, (Array)[0])
#endif
//
// LoadLibrary() a DLL, using the same directory as dbghelp.dll.
//
HMODULE
LoadDLL(
__in PCWSTR filename
)
{
WCHAR drive[10] = L"";
WCHAR dir[MAX_PATH + 1] = L"";
WCHAR file[MAX_PATH + 1] = L"";
WCHAR ext[MAX_PATH + 1] = L"";
WCHAR path[MAX_PATH + 1] = L"";
HMODULE hm;
// Chop up 'filename' into its elements.
_wsplitpath_s(filename, drive, cch(drive), dir, cch(dir), file, cch(file), ext, cch(ext));
// If 'filename' contains no path information, then get the path to our module and
// use it to create a fully qualified path to the module we are loading. Then load it.
if (!*drive && !*dir)
{
// ghinst is the HINSTANCE of this module, initialized in DllMain or WinMain
if (GetModuleFileNameW(ghinst, path, MAX_PATH))
{
_wsplitpath_s(path, drive, cch(drive), dir, cch(dir), NULL, 0, NULL, 0);
if (*drive || *dir)
{
swprintf_s(path, cch(path), L"%s%s%s%s", drive, dir, file, ext);
hm = LoadLibrary(path);
if (hm)
return hm;
}
}
}
else
{
// If we wanted to, we could have LoadDLL also support directories being specified
// in 'filename'. We could pass the path here. The result is if no path is specified,
// the module path is used as above, otherwise the path in 'filename' is specified.
// But the standard search logic of LoadLibrary is still avoided.
/*
hm = LoadLibrary(path);
if (hm)
return hm;
*/
}
return 0;
}
После загрузки этих двух библиотек DLL DbgHelp вызывает GetProcAddress , чтобы получить необходимые функции от них.
Как правило, код, вызывающий DbgHelp.dll, гарантирует, что правильная версия загружается путем установки DbgHelp.dll в том же каталоге, что и приложение, инициирующее текущий процесс. Если вызывающий код находится в библиотеке DLL и не имеет доступа к расположению начального процесса, то DbgHelp.dll необходимо установить вместе с вызываемой библиотекой DLL и кодом, похожим на LoadDLL DbgHelp.
См. также