mirror of
https://github.com/wbenny/pdbex
synced 2026-06-08 18:13:37 +00:00
Support binary file path (#1)
* [ADD] direct export call msdia140.dll * [MDF] Copy msdia140.dll cmd * [ADD] Support binary file path
This commit is contained in:
committed by
Parallel Xenoexcite
parent
f8e9e33daa
commit
be7a72fe8f
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+70
-22
@@ -1,6 +1,8 @@
|
||||
#include "PDB.h"
|
||||
#include "PDBCallback.h"
|
||||
|
||||
#include <dia2.h> // IDia* interfaces
|
||||
#include <atlcomcli.h>
|
||||
|
||||
#include <cassert>
|
||||
|
||||
@@ -54,7 +56,7 @@ SymbolModuleBase::SymbolModuleBase()
|
||||
, m_Session(nullptr)
|
||||
, m_GlobalSymbol(nullptr)
|
||||
{
|
||||
HRESULT hr = CoInitialize(NULL);
|
||||
HRESULT hr = CoInitialize(nullptr);
|
||||
|
||||
assert(hr == S_OK);
|
||||
}
|
||||
@@ -68,24 +70,69 @@ SymbolModuleBase::Open(
|
||||
// Obtain access to the provider
|
||||
//
|
||||
|
||||
HRESULT HResult;
|
||||
HRESULT HResult = S_OK;
|
||||
auto PDBSearchPath = L"Srv*.\\Symbols*https://msdl.microsoft.com/download/symbols";
|
||||
char FileExt[MAX_PATH] = { 0 };
|
||||
|
||||
HResult = CoCreateInstance(
|
||||
__uuidof(DiaSource),
|
||||
NULL,
|
||||
nullptr,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
__uuidof(IDiaDataSource),
|
||||
(void**)&m_DataSource
|
||||
);
|
||||
|
||||
// Retry with direct export call
|
||||
if (HResult == REGDB_E_CLASSNOTREG)
|
||||
{
|
||||
HMODULE HMod = LoadLibraryW(L"msdia140.dll");
|
||||
|
||||
if (!HMod)
|
||||
{
|
||||
HResult = HRESULT_FROM_WIN32(GetLastError());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
auto DllGetClassObject = reinterpret_cast<BOOL(WINAPI*)(REFCLSID, REFIID, LPVOID)>(GetProcAddress(HMod, "DllGetClassObject"));
|
||||
|
||||
if (!DllGetClassObject)
|
||||
{
|
||||
HResult = HRESULT_FROM_WIN32(GetLastError());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
CComPtr<IClassFactory> ClassFactory;
|
||||
HResult = DllGetClassObject(__uuidof(DiaSource), __uuidof(IClassFactory), &ClassFactory);
|
||||
|
||||
if (FAILED(HResult))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
HResult = ClassFactory->CreateInstance(nullptr, __uuidof(IDiaDataSource), (void**)&m_DataSource);
|
||||
}
|
||||
|
||||
if (FAILED(HResult))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
HResult = m_DataSource->loadDataFromPdb(
|
||||
string_converter.from_bytes(Path).c_str()
|
||||
_splitpath_s(Path, nullptr, 0, nullptr, 0, nullptr, 0, FileExt, _countof(FileExt));
|
||||
|
||||
if (_stricmp(FileExt, ".pdb") == 0)
|
||||
{
|
||||
HResult = m_DataSource->loadDataFromPdb(
|
||||
string_converter.from_bytes(Path).c_str()
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
PDBCallback Callback;
|
||||
Callback.AddRef();
|
||||
|
||||
HResult = m_DataSource->loadDataForExe(
|
||||
string_converter.from_bytes(Path).c_str(), PDBSearchPath, &Callback);
|
||||
}
|
||||
|
||||
if (FAILED(HResult))
|
||||
{
|
||||
@@ -499,16 +546,17 @@ SymbolModule::BuildSymbolMap()
|
||||
{
|
||||
IDiaEnumSymbols* DiaSymbolEnumerator;
|
||||
|
||||
m_GlobalSymbol->findChildren(SymTagPublicSymbol, NULL, nsNone, &DiaSymbolEnumerator);
|
||||
BuildFunctionSetFromEnumerator(DiaSymbolEnumerator);
|
||||
if (SUCCEEDED(m_GlobalSymbol->findChildren(SymTagPublicSymbol, nullptr, nsNone, &DiaSymbolEnumerator)))
|
||||
BuildFunctionSetFromEnumerator(DiaSymbolEnumerator);
|
||||
|
||||
m_GlobalSymbol->findChildren(SymTagEnum, NULL, nsNone, &DiaSymbolEnumerator);
|
||||
BuildSymbolMapFromEnumerator(DiaSymbolEnumerator);
|
||||
if (SUCCEEDED(m_GlobalSymbol->findChildren(SymTagEnum, nullptr, nsNone, &DiaSymbolEnumerator)))
|
||||
BuildSymbolMapFromEnumerator(DiaSymbolEnumerator);
|
||||
|
||||
m_GlobalSymbol->findChildren(SymTagUDT, NULL, nsNone, &DiaSymbolEnumerator);
|
||||
BuildSymbolMapFromEnumerator(DiaSymbolEnumerator);
|
||||
if (SUCCEEDED(m_GlobalSymbol->findChildren(SymTagUDT, nullptr, nsNone, &DiaSymbolEnumerator)))
|
||||
BuildSymbolMapFromEnumerator(DiaSymbolEnumerator);
|
||||
|
||||
DiaSymbolEnumerator->Release();
|
||||
if (DiaSymbolEnumerator)
|
||||
DiaSymbolEnumerator->Release();
|
||||
}
|
||||
|
||||
const SymbolMap&
|
||||
@@ -590,7 +638,7 @@ SymbolModule::ProcessSymbolEnum(
|
||||
{
|
||||
IDiaEnumSymbols* DiaSymbolEnumerator;
|
||||
|
||||
if (FAILED(DiaSymbol->findChildren(SymTagNull, NULL, nsNone, &DiaSymbolEnumerator)))
|
||||
if (FAILED(DiaSymbol->findChildren(SymTagNull, nullptr, nsNone, &DiaSymbolEnumerator)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -605,8 +653,8 @@ SymbolModule::ProcessSymbolEnum(
|
||||
ULONG FetchedSymbolCount = 0;
|
||||
|
||||
for (DWORD Index = 0;
|
||||
SUCCEEDED(DiaSymbolEnumerator->Next(1, &DiaChildSymbol, &FetchedSymbolCount)) && (FetchedSymbolCount == 1);
|
||||
Index++)
|
||||
SUCCEEDED(DiaSymbolEnumerator->Next(1, &DiaChildSymbol, &FetchedSymbolCount)) && (FetchedSymbolCount == 1);
|
||||
Index++)
|
||||
{
|
||||
SYMBOL_ENUM_FIELD* EnumValue = &Symbol->u.Enum.Fields[Index];
|
||||
|
||||
@@ -718,7 +766,7 @@ SymbolModule::ProcessSymbolFunction(
|
||||
|
||||
IDiaEnumSymbols* DiaSymbolEnumerator;
|
||||
|
||||
if (FAILED(DiaSymbol->findChildren(SymTagNull, NULL, nsNone, &DiaSymbolEnumerator)))
|
||||
if (FAILED(DiaSymbol->findChildren(SymTagNull, nullptr, nsNone, &DiaSymbolEnumerator)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -734,8 +782,8 @@ SymbolModule::ProcessSymbolFunction(
|
||||
ULONG FetchedSymbolCount = 0;
|
||||
|
||||
for (DWORD Index = 0;
|
||||
SUCCEEDED(DiaSymbolEnumerator->Next(1, &DiaChildSymbol, &FetchedSymbolCount)) && (FetchedSymbolCount == 1);
|
||||
Index++)
|
||||
SUCCEEDED(DiaSymbolEnumerator->Next(1, &DiaChildSymbol, &FetchedSymbolCount)) && (FetchedSymbolCount == 1);
|
||||
Index++)
|
||||
{
|
||||
SYMBOL* Argument;
|
||||
Argument = GetSymbol(DiaChildSymbol);
|
||||
@@ -773,7 +821,7 @@ SymbolModule::ProcessSymbolUdt(
|
||||
|
||||
IDiaEnumSymbols* DiaSymbolEnumerator;
|
||||
|
||||
if (FAILED(DiaSymbol->findChildren(SymTagData, NULL, nsNone, &DiaSymbolEnumerator)))
|
||||
if (FAILED(DiaSymbol->findChildren(SymTagData, nullptr, nsNone, &DiaSymbolEnumerator)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -789,8 +837,8 @@ SymbolModule::ProcessSymbolUdt(
|
||||
ULONG FetchedSymbolCount = 0;
|
||||
|
||||
for (DWORD Index = 0;
|
||||
SUCCEEDED(DiaSymbolEnumerator->Next(1, &DiaChildSymbol, &FetchedSymbolCount)) && (FetchedSymbolCount == 1);
|
||||
Index++)
|
||||
SUCCEEDED(DiaSymbolEnumerator->Next(1, &DiaChildSymbol, &FetchedSymbolCount)) && (FetchedSymbolCount == 1);
|
||||
Index++)
|
||||
{
|
||||
SYMBOL_UDT_FIELD* Member = &Symbol->u.Udt.Fields[Index];
|
||||
|
||||
@@ -1076,7 +1124,7 @@ PDB::GetBasicTypeString(
|
||||
if (TypeMap[n].BaseType == BaseType)
|
||||
{
|
||||
if (TypeMap[n].Length == Size ||
|
||||
TypeMap[n].Length == 0)
|
||||
TypeMap[n].Length == 0)
|
||||
{
|
||||
return TypeMap[n].TypeString;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
#pragma once
|
||||
|
||||
#include <dia2.h> // IDia* interfaces
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// PDBCallback
|
||||
//
|
||||
|
||||
class PDBCallback : public IDiaLoadCallback2
|
||||
{
|
||||
volatile unsigned long m_RefCount = 0;
|
||||
|
||||
public:
|
||||
|
||||
//IUnknown
|
||||
ULONG STDMETHODCALLTYPE AddRef() override
|
||||
{
|
||||
return m_RefCount++;
|
||||
}
|
||||
ULONG STDMETHODCALLTYPE Release() override
|
||||
{
|
||||
if ((--m_RefCount) == 0)
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
return m_RefCount;
|
||||
}
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID Rid, void **Interface) override
|
||||
{
|
||||
if (Interface == nullptr)
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
if (Rid == __uuidof(IDiaLoadCallback2))
|
||||
{
|
||||
*Interface = (IDiaLoadCallback2 *)this;
|
||||
}
|
||||
else if (Rid == __uuidof(IDiaLoadCallback))
|
||||
{
|
||||
*Interface = (IDiaLoadCallback *)this;
|
||||
}
|
||||
else if (Rid == __uuidof(IUnknown))
|
||||
{
|
||||
*Interface = (IUnknown *)this;
|
||||
}
|
||||
else
|
||||
{
|
||||
*Interface = nullptr;
|
||||
}
|
||||
|
||||
if (*Interface != nullptr)
|
||||
{
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE NotifyDebugDir(
|
||||
BOOL fExecutable,
|
||||
DWORD cbData,
|
||||
BYTE data[]) override // really a const struct _IMAGE_DEBUG_DIRECTORY *
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT STDMETHODCALLTYPE NotifyOpenDBG(
|
||||
LPCOLESTR dbgPath,
|
||||
HRESULT resultCode) override
|
||||
{
|
||||
// wprintf(L"opening %s...\n", dbgPath);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE NotifyOpenPDB(
|
||||
LPCOLESTR pdbPath,
|
||||
HRESULT resultCode) override
|
||||
{
|
||||
// wprintf(L"opening %s...\n", pdbPath);
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT STDMETHODCALLTYPE RestrictRegistryAccess() override
|
||||
{
|
||||
// return hr != S_OK to prevent querying the registry for symbol search paths
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT STDMETHODCALLTYPE RestrictSymbolServerAccess() override
|
||||
{
|
||||
// return hr != S_OK to prevent accessing a symbol server
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT STDMETHODCALLTYPE RestrictOriginalPathAccess() override
|
||||
{
|
||||
// return hr != S_OK to prevent querying the registry for symbol search paths
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT STDMETHODCALLTYPE RestrictReferencePathAccess() override
|
||||
{
|
||||
// return hr != S_OK to prevent accessing a symbol server
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT STDMETHODCALLTYPE RestrictDBGAccess() override
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT STDMETHODCALLTYPE RestrictSystemRootAccess() override
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
};
|
||||
@@ -236,6 +236,10 @@ PDBExtractor::ParseParameters(
|
||||
std::ios::out
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Settings.PdbHeaderReconstructorSettings.OutputFile = nullptr;
|
||||
}
|
||||
break;
|
||||
|
||||
case 't':
|
||||
@@ -681,11 +685,11 @@ PDBExtractor::CloseOpenedFiles()
|
||||
|
||||
if (m_Settings.TestFilename)
|
||||
{
|
||||
delete m_Settings.PdbHeaderReconstructorSettings.TestFile;
|
||||
delete m_Settings.PdbHeaderReconstructorSettings.TestFile;
|
||||
}
|
||||
|
||||
if (m_Settings.OutputFilename)
|
||||
{
|
||||
delete m_Settings.PdbHeaderReconstructorSettings.OutputFile;
|
||||
delete m_Settings.PdbHeaderReconstructorSettings.OutputFile;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,7 +133,7 @@ class PDBHeaderReconstructor
|
||||
OnAnonymousUdtBegin(
|
||||
UdtKind Kind,
|
||||
const SYMBOL_UDT_FIELD* FirstUdtField
|
||||
);
|
||||
) override;
|
||||
|
||||
void
|
||||
OnAnonymousUdtEnd(
|
||||
|
||||
@@ -124,7 +124,7 @@ class UdtFieldDefinition
|
||||
void
|
||||
SetMemberName(
|
||||
const CHAR* MemberName
|
||||
)
|
||||
) override
|
||||
{
|
||||
m_MemberName = MemberName ? MemberName : std::string();
|
||||
}
|
||||
|
||||
@@ -103,6 +103,10 @@
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>copy $(SolutionDir)Library\$(PlatformTarget)\msdia140.dll $(OutDir)
|
||||
copy $(SolutionDir)Library\$(PlatformTarget)\symsrv.dll $(OutDir)</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
@@ -118,6 +122,10 @@
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>copy $(SolutionDir)Library\$(PlatformTarget)\msdia140.dll $(OutDir)
|
||||
copy $(SolutionDir)Library\$(PlatformTarget)\symsrv.dll $(OutDir)</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
@@ -138,6 +146,10 @@
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>copy $(SolutionDir)Library\$(PlatformTarget)\msdia140.dll $(OutDir)
|
||||
copy $(SolutionDir)Library\$(PlatformTarget)\symsrv.dll $(OutDir)</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
@@ -158,6 +170,10 @@
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>copy $(SolutionDir)Library\$(PlatformTarget)\msdia140.dll $(OutDir)
|
||||
copy $(SolutionDir)Library\$(PlatformTarget)\symsrv.dll $(OutDir)</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.cpp" />
|
||||
@@ -167,6 +183,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="PDB.h" />
|
||||
<ClInclude Include="PDBCallback.h" />
|
||||
<ClInclude Include="PDBExtractor.h" />
|
||||
<ClInclude Include="PDBHeaderReconstructor.h" />
|
||||
<ClInclude Include="PDBReconstructorBase.h" />
|
||||
|
||||
@@ -62,6 +62,9 @@
|
||||
<ClInclude Include="PDBSymbolSorterBase.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="PDBCallback.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="PDBSymbolVisitor.inl">
|
||||
|
||||
Reference in New Issue
Block a user