Мне нужно программно получить список зависимостей DLL. Вот как я пытаюсь решить эту задачу:
BSTR GetDllDependencies(const wchar_t* dllPath)
{
std::wstring dependencies;
struct LibDeleter
{
typedef HMODULE pointer;
void operator()(HMODULE hMod) { FreeLibrary(hMod); }
};
auto hModRaw = LoadLibraryExW(dllPath, NULL, DONT_RESOLVE_DLL_REFERENCES); //(*)nullptr nere
auto hMod = std::unique_ptr<HMODULE, LibDeleter>();
auto imageBase = (DWORD_PTR)hMod.get();
auto header = ImageNtHeader(hMod.get());
auto importRVA = header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
auto importTable = (PIMAGE_IMPORT_DESCRIPTOR)(DWORD_PTR)(importRVA + imageBase);
while (importRVA && importTable->OriginalFirstThunk)
{
auto importedModuleName = (char*)(DWORD_PTR)(importTable->Name + imageBase);
dependencies
.append(importedModuleName, importedModuleName + std::strlen(importedModuleName))
.append(L",");
importTable++;
}
auto result = SysAllocString(dependencies.c_str());
return result;
}
Оно работает. Но, как видите, он загружает DLL в процесс. И тут я столкнулся с проблемой: LoadLibraryEx
возвращает nullptr
, если процесс уже загрузил DLL с таким же именем.
Я не уверен, можно ли загружать две библиотеки DLL с одинаковым именем (но в другом месте) в один и тот же процесс? Я считаю, что да. Тогда почему LoadLibraryEx
возвращает nullptr
? Можно ли как-то получить зависимости DLL без загрузки DLL?
DONT_RESOLVE_DLL_REFERENCES
is устарело и может не поддерживаться во всех версиях Windows, вам нужно будет загрузить вместо этого файл данных. - person Mgetz   schedule 31.07.2017LoadLibraryEx returns nullptr if process already has loaded DLL with the same name
это неправда - person RbMm   schedule 31.07.2017Then why LoadLibraryEx returns nullptr
- тогда почему бы вам не позвонитьGetLastError
илиRtlGetLastNtStatus
? - person RbMm   schedule 31.07.2017