Skip to content

Commit

Permalink
Support binary file path (#1)
Browse files Browse the repository at this point in the history
* [ADD] direct export call msdia140.dll
* [MDF] Copy msdia140.dll cmd
* [ADD] Support binary file path
  • Loading branch information
MeeSong authored and wbenny committed Nov 10, 2018
1 parent f8e9e33 commit be7a72f
Show file tree
Hide file tree
Showing 11 changed files with 210 additions and 26 deletions.
Binary file added Library/x64/msdia140.dll
Binary file not shown.
Binary file added Library/x64/symsrv.dll
Binary file not shown.
Binary file added Library/x86/msdia140.dll
Binary file not shown.
Binary file added Library/x86/symsrv.dll
Binary file not shown.
92 changes: 70 additions & 22 deletions Source/PDB.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#include "PDB.h"
#include "PDBCallback.h"

#include <dia2.h> // IDia* interfaces
#include <atlcomcli.h>

#include <cassert>

Expand Down Expand Up @@ -54,7 +56,7 @@ SymbolModuleBase::SymbolModuleBase()
, m_Session(nullptr)
, m_GlobalSymbol(nullptr)
{
HRESULT hr = CoInitialize(NULL);
HRESULT hr = CoInitialize(nullptr);

assert(hr == S_OK);
}
Expand All @@ -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))
{
Expand Down Expand Up @@ -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&
Expand Down Expand Up @@ -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;
}
Expand All @@ -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];

Expand Down Expand Up @@ -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;
}
Expand All @@ -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);
Expand Down Expand Up @@ -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;
}
Expand All @@ -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];

Expand Down Expand Up @@ -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;
}
Expand Down
112 changes: 112 additions & 0 deletions Source/PDBCallback.h
Original file line number Diff line number Diff line change
@@ -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;
}
};
8 changes: 6 additions & 2 deletions Source/PDBExtractor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,10 @@ PDBExtractor::ParseParameters(
std::ios::out
);
}
else
{
m_Settings.PdbHeaderReconstructorSettings.OutputFile = nullptr;
}
break;

case 't':
Expand Down Expand Up @@ -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;
}
}
2 changes: 1 addition & 1 deletion Source/PDBHeaderReconstructor.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ class PDBHeaderReconstructor
OnAnonymousUdtBegin(
UdtKind Kind,
const SYMBOL_UDT_FIELD* FirstUdtField
);
) override;

void
OnAnonymousUdtEnd(
Expand Down
2 changes: 1 addition & 1 deletion Source/UdtFieldDefinition.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ class UdtFieldDefinition
void
SetMemberName(
const CHAR* MemberName
)
) override
{
m_MemberName = MemberName ? MemberName : std::string();
}
Expand Down
17 changes: 17 additions & 0 deletions Source/pdbex.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand All @@ -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>
Expand All @@ -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>
Expand All @@ -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" />
Expand All @@ -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" />
Expand Down
Loading

0 comments on commit be7a72f

Please sign in to comment.