From 000374f6348145c3afa4e17cff9fcd175f39463e Mon Sep 17 00:00:00 2001 From: Petr Benes Date: Wed, 19 Jun 2019 23:07:01 +0200 Subject: [PATCH] use CComPtr wherever possible, migrate to c++latest --- Scripts/env.bat | 2 +- Scripts/test.py | 2 +- Source/PDB.cpp | 333 +++++++++++++++--------------- Source/PDB.h | 6 + Source/PDBExtractor.cpp | 4 +- Source/PDBExtractor.h | 2 +- Source/PDBHeaderReconstructor.cpp | 7 +- Source/pdbex.vcxproj | 4 + 8 files changed, 184 insertions(+), 176 deletions(-) diff --git a/Scripts/env.bat b/Scripts/env.bat index 8590f7d..0efb0b0 100644 --- a/Scripts/env.bat +++ b/Scripts/env.bat @@ -1,2 +1,2 @@ @echo off -call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\Tools\VsDevCmd.bat" +call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\Common7\Tools\VsDevCmd.bat" diff --git a/Scripts/test.py b/Scripts/test.py index 37f3312..8b6ec97 100644 --- a/Scripts/test.py +++ b/Scripts/test.py @@ -96,7 +96,7 @@ def test_compile(file_vcxproj, file_c, file_h, platform): 'file_vcxproj' : file_vcxproj, 'configuration' : 'debug', 'platform' : platform, - 'platformtoolset' : 'v141' + 'platformtoolset' : 'v142' } if VERBOSITY_LEVEL >= 1: diff --git a/Source/PDB.cpp b/Source/PDB.cpp index 19c914f..2041fe6 100644 --- a/Source/PDB.cpp +++ b/Source/PDB.cpp @@ -6,20 +6,8 @@ #include -// -// For string converting: -// std::wstring_convert> string_converter -// -// Ref: http://stackoverflow.com/a/18597384 -// -#include -#include #include - -namespace -{ - static std::wstring_convert> string_converter; -} +#include ////////////////////////////////////////////////////////////////////////// // SymbolModuleBase @@ -41,10 +29,17 @@ class SymbolModuleBase BOOL IsOpen() const; + private: + HRESULT + LoadDiaViaCoCreateInstance(); + + HRESULT + LoadDiaViaLoadLibrary(); + protected: - IDiaDataSource* m_DataSource; - IDiaSession* m_Session; - IDiaSymbol* m_GlobalSymbol; + CComPtr m_DataSource; + CComPtr m_Session; + CComPtr m_GlobalSymbol; }; ////////////////////////////////////////////////////////////////////////// @@ -52,138 +47,162 @@ class SymbolModuleBase // SymbolModuleBase::SymbolModuleBase() - : m_DataSource(nullptr) - , m_Session(nullptr) - , m_GlobalSymbol(nullptr) { HRESULT hr = CoInitialize(nullptr); assert(hr == S_OK); } +HRESULT +SymbolModuleBase::LoadDiaViaCoCreateInstance() +{ + return CoCreateInstance( + __uuidof(DiaSource), + nullptr, + CLSCTX_INPROC_SERVER, + __uuidof(IDiaDataSource), + (void**)& m_DataSource + ); +} + +HRESULT +SymbolModuleBase::LoadDiaViaLoadLibrary() +{ + HRESULT Result; + HMODULE Module = LoadLibrary(TEXT("msdia140.dll")); + + if (!Module) + { + Result = HRESULT_FROM_WIN32(GetLastError()); + return FALSE; + } + + using PDLLGETCLASSOBJECT_ROUTINE = HRESULT(WINAPI*)(REFCLSID, REFIID, LPVOID); + auto DllGetClassObject = reinterpret_cast(GetProcAddress(Module, "DllGetClassObject")); + + if (!DllGetClassObject) + { + Result = HRESULT_FROM_WIN32(GetLastError()); + return FALSE; + } + + CComPtr ClassFactory; + Result = DllGetClassObject(__uuidof(DiaSource), __uuidof(IClassFactory), &ClassFactory); + + if (FAILED(Result)) + { + return FALSE; + } + + return ClassFactory->CreateInstance(nullptr, __uuidof(IDiaDataSource), (void**)& m_DataSource); +} + BOOL SymbolModuleBase::Open( IN const CHAR* Path ) { - // - // Obtain access to the provider. - // - - HRESULT HResult = S_OK; + HRESULT Result = S_OK; LPCOLESTR PDBSearchPath = L"srv*.\\Symbols*https://msdl.microsoft.com/download/symbols"; - char FileExt[MAX_PATH] = { 0 }; - - HResult = CoCreateInstance( - __uuidof(DiaSource), - nullptr, - CLSCTX_INPROC_SERVER, - __uuidof(IDiaDataSource), - (void**)&m_DataSource - ); // - // Retry with direct export call. + // Load msdia140.dll. + // First try registered COM class, if it fails, + // do LoadLibrary() directly. // - if (HResult == REGDB_E_CLASSNOTREG) - { - HMODULE HMod = LoadLibrary(TEXT("msdia140.dll")); - - if (!HMod) - { - HResult = HRESULT_FROM_WIN32(GetLastError()); - return FALSE; - } - - using PDLLGETCLASSOBJECT_ROUTINE = HRESULT(WINAPI*)(REFCLSID, REFIID, LPVOID); - auto DllGetClassObject = reinterpret_cast(GetProcAddress(HMod, "DllGetClassObject")); - - if (!DllGetClassObject) - { - HResult = HRESULT_FROM_WIN32(GetLastError()); - return FALSE; - } - - CComPtr 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)) + if (FAILED(Result = LoadDiaViaCoCreateInstance()) && + FAILED(Result = LoadDiaViaLoadLibrary())) { return FALSE; } - _splitpath_s(Path, nullptr, 0, nullptr, 0, nullptr, 0, FileExt, _countof(FileExt)); + // + // Convert Path to WCHAR string. + // - if (_stricmp(FileExt, ".pdb") == 0) + int PathUnicodeLength = MultiByteToWideChar(CP_UTF8, 0, Path, -1, NULL, 0); + auto PathUnicode = std::make_unique(PathUnicodeLength); + MultiByteToWideChar(CP_UTF8, 0, Path, -1, PathUnicode.get(), PathUnicodeLength); + + // + // Parse the file extension. + // + + WCHAR FileExtension[8] = { 0 }; + _wsplitpath_s( + PathUnicode.get(), + nullptr, + 0, + nullptr, + 0, + nullptr, + 0, + FileExtension, + _countof(FileExtension)); + + // + // If PDB file is specified, load it directly. + // Otherwise, try to find the corresponding PDB for + // the specified file (locally / symbol server). + // + + if (_wcsicmp(FileExtension, L".pdb") == 0) { - HResult = m_DataSource->loadDataFromPdb( - string_converter.from_bytes(Path).c_str() - ); + Result = m_DataSource->loadDataFromPdb(PathUnicode.get()); } else { PDBCallback Callback; Callback.AddRef(); - HResult = m_DataSource->loadDataForExe( - string_converter.from_bytes(Path).c_str(), PDBSearchPath, &Callback - ); + Result = m_DataSource->loadDataForExe(PathUnicode.get(), PDBSearchPath, &Callback); } - if (FAILED(HResult)) + // + // Check if PDB is open. + // + + if (FAILED(Result)) { - Close(); - return FALSE; + goto Error; } - HResult = m_DataSource->openSession(&m_Session); + // + // Open DIA session. + // - if (FAILED(HResult)) + Result = m_DataSource->openSession(&m_Session); + + if (FAILED(Result)) { - Close(); - return FALSE; + goto Error; } - HResult = m_Session->get_globalScope(&m_GlobalSymbol); + // + // Get root symbol. + // - if (FAILED(HResult)) + Result = m_Session->get_globalScope(&m_GlobalSymbol); + + if (FAILED(Result)) { - Close(); - return FALSE; + goto Error; } return TRUE; + +Error: + Close(); + return FALSE; } VOID SymbolModuleBase::Close() { - if (m_GlobalSymbol != nullptr) - { - m_GlobalSymbol->Release(); - m_GlobalSymbol = nullptr; - } - - if (m_Session != nullptr) - { - m_Session->Release(); - m_Session = nullptr; - } - - if (m_DataSource != nullptr) - { - m_DataSource->Release(); - m_DataSource = nullptr; - } + m_GlobalSymbol.Release(); + m_Session.Release(); + m_DataSource.Release(); CoUninitialize(); } @@ -440,7 +459,7 @@ SymbolModule::GetSymbolName( CHAR* SymbolNameMb; size_t SymbolNameLength; - SymbolNameLength = SysStringLen(SymbolNameBstr) + 1; + SymbolNameLength = (size_t)SysStringLen(SymbolNameBstr) + 1; SymbolNameMb = new CHAR[SymbolNameLength]; wcstombs(SymbolNameMb, SymbolNameBstr, SymbolNameLength); @@ -506,14 +525,14 @@ SymbolModule::BuildSymbolMapFromEnumerator( IN IDiaEnumSymbols* DiaSymbolEnumerator ) { - IDiaSymbol* DiaChildSymbol; + IDiaSymbol* Result; ULONG FetchedSymbolCount = 0; - while (SUCCEEDED(DiaSymbolEnumerator->Next(1, &DiaChildSymbol, &FetchedSymbolCount)) && (FetchedSymbolCount == 1)) + while (SUCCEEDED(DiaSymbolEnumerator->Next(1, &Result, &FetchedSymbolCount)) && (FetchedSymbolCount == 1)) { - GetSymbol(DiaChildSymbol); + CComPtr DiaChildSymbol(Result); - DiaChildSymbol->Release(); + GetSymbol(DiaChildSymbol); } } @@ -522,11 +541,13 @@ SymbolModule::BuildFunctionSetFromEnumerator( IN IDiaEnumSymbols* DiaSymbolEnumerator ) { - IDiaSymbol* DiaChildSymbol; + IDiaSymbol* Result; ULONG FetchedSymbolCount = 0; - while (SUCCEEDED(DiaSymbolEnumerator->Next(1, &DiaChildSymbol, &FetchedSymbolCount)) && (FetchedSymbolCount == 1)) + while (SUCCEEDED(DiaSymbolEnumerator->Next(1, &Result, &FetchedSymbolCount)) && (FetchedSymbolCount == 1)) { + CComPtr DiaChildSymbol(Result); + BOOL IsFunction; DiaChildSymbol->get_function(&IsFunction); @@ -536,40 +557,34 @@ SymbolModule::BuildFunctionSetFromEnumerator( DWORD DwordResult; DiaChildSymbol->get_symTag(&DwordResult); - auto Tag = static_cast(DwordResult); + // auto Tag = static_cast(DwordResult); - m_FunctionSet.insert(std::string(FunctionName)); + m_FunctionSet.insert(FunctionName); delete[] FunctionName; } - - DiaChildSymbol->Release(); } } VOID SymbolModule::BuildSymbolMap() { - IDiaEnumSymbols* DiaSymbolEnumerator; - - if (SUCCEEDED(m_GlobalSymbol->findChildren(SymTagPublicSymbol, nullptr, nsNone, &DiaSymbolEnumerator))) + if (CComPtr DiaSymbolEnumerator; + SUCCEEDED(m_GlobalSymbol->findChildren(SymTagPublicSymbol, nullptr, nsNone, &DiaSymbolEnumerator))) { BuildFunctionSetFromEnumerator(DiaSymbolEnumerator); } - if (SUCCEEDED(m_GlobalSymbol->findChildren(SymTagEnum, nullptr, nsNone, &DiaSymbolEnumerator))) + if (CComPtr DiaSymbolEnumerator; + SUCCEEDED(m_GlobalSymbol->findChildren(SymTagEnum, nullptr, nsNone, &DiaSymbolEnumerator))) { BuildSymbolMapFromEnumerator(DiaSymbolEnumerator); } - if (SUCCEEDED(m_GlobalSymbol->findChildren(SymTagUDT, nullptr, nsNone, &DiaSymbolEnumerator))) + if (CComPtr DiaSymbolEnumerator; + SUCCEEDED(m_GlobalSymbol->findChildren(SymTagUDT, nullptr, nsNone, &DiaSymbolEnumerator))) { BuildSymbolMapFromEnumerator(DiaSymbolEnumerator); } - - if (DiaSymbolEnumerator) - { - DiaSymbolEnumerator->Release(); - } } const SymbolMap& @@ -603,6 +618,9 @@ SymbolModule::InitSymbol( DiaSymbol->get_symTag(&DwordResult); Symbol->Tag = static_cast(DwordResult); + DiaSymbol->get_dataKind(&DwordResult); + Symbol->DataKind = static_cast(DwordResult); + DiaSymbol->get_baseType(&DwordResult); Symbol->BaseType = static_cast(DwordResult); @@ -649,7 +667,7 @@ SymbolModule::ProcessSymbolEnum( IN SYMBOL* Symbol ) { - IDiaEnumSymbols* DiaSymbolEnumerator; + CComPtr DiaSymbolEnumerator; if (FAILED(DiaSymbol->findChildren(SymTagNull, nullptr, nsNone, &DiaSymbolEnumerator))) { @@ -662,26 +680,24 @@ SymbolModule::ProcessSymbolEnum( Symbol->u.Enum.FieldCount = static_cast(ChildCount); Symbol->u.Enum.Fields = new SYMBOL_ENUM_FIELD[ChildCount]; - IDiaSymbol* DiaChildSymbol; + IDiaSymbol* Result; ULONG FetchedSymbolCount = 0; + DWORD Index = 0; - for (DWORD Index = 0; - SUCCEEDED(DiaSymbolEnumerator->Next(1, &DiaChildSymbol, &FetchedSymbolCount)) && (FetchedSymbolCount == 1); - Index++) + while (SUCCEEDED(DiaSymbolEnumerator->Next(1, &Result, &FetchedSymbolCount)) && (FetchedSymbolCount == 1)) { + CComPtr DiaChildSymbol(Result); + SYMBOL_ENUM_FIELD* EnumValue = &Symbol->u.Enum.Fields[Index]; EnumValue->Parent = Symbol; - EnumValue->Name = GetSymbolName(DiaChildSymbol); VariantInit(&EnumValue->Value); DiaChildSymbol->get_value(&EnumValue->Value); - DiaChildSymbol->Release(); + Index += 1; } - - DiaSymbolEnumerator->Release(); } VOID @@ -690,13 +706,11 @@ SymbolModule::ProcessSymbolTypedef( IN SYMBOL* Symbol ) { - IDiaSymbol* DiaTypedefSymbol; + CComPtr DiaTypedefSymbol; DiaSymbol->get_type(&DiaTypedefSymbol); Symbol->u.Typedef.Type = GetSymbol(DiaTypedefSymbol); - - DiaTypedefSymbol->Release(); } VOID @@ -705,15 +719,13 @@ SymbolModule::ProcessSymbolPointer( IN SYMBOL* Symbol ) { - IDiaSymbol* DiaPointerSymbol; + CComPtr DiaPointerSymbol; DiaSymbol->get_type(&DiaPointerSymbol); DiaSymbol->get_reference(&Symbol->u.Pointer.IsReference); Symbol->u.Pointer.Type = GetSymbol(DiaPointerSymbol); - DiaPointerSymbol->Release(); - if (m_MachineType == 0) { @@ -738,14 +750,12 @@ SymbolModule::ProcessSymbolArray( IN SYMBOL* Symbol ) { - IDiaSymbol* DiaDataTypeSymbol; + CComPtr DiaDataTypeSymbol; DiaSymbol->get_type(&DiaDataTypeSymbol); Symbol->u.Array.ElementType = GetSymbol(DiaDataTypeSymbol); DiaSymbol->get_count(&Symbol->u.Array.ElementCount); - - DiaDataTypeSymbol->Release(); } VOID @@ -767,17 +777,15 @@ SymbolModule::ProcessSymbolFunction( // Return type. // - IDiaSymbol* DiaReturnTypeSymbol; + CComPtr DiaReturnTypeSymbol; DiaSymbol->get_type(&DiaReturnTypeSymbol); Symbol->u.Function.ReturnType = GetSymbol(DiaReturnTypeSymbol); - DiaReturnTypeSymbol->Release(); - // // Arguments. // - IDiaEnumSymbols* DiaSymbolEnumerator; + CComPtr DiaSymbolEnumerator; if (FAILED(DiaSymbol->findChildren(SymTagNull, nullptr, nsNone, &DiaSymbolEnumerator))) { @@ -791,21 +799,20 @@ SymbolModule::ProcessSymbolFunction( Symbol->u.Function.ArgumentCount = static_cast(ChildCount); Symbol->u.Function.Arguments = new SYMBOL*[ChildCount]; - IDiaSymbol* DiaChildSymbol; + IDiaSymbol* Result; ULONG FetchedSymbolCount = 0; + DWORD Index = 0; - for (DWORD Index = 0; - SUCCEEDED(DiaSymbolEnumerator->Next(1, &DiaChildSymbol, &FetchedSymbolCount)) && (FetchedSymbolCount == 1); - Index++) + while (SUCCEEDED(DiaSymbolEnumerator->Next(1, &Result, &FetchedSymbolCount)) && (FetchedSymbolCount == 1)) { + CComPtr DiaChildSymbol(Result); + SYMBOL* Argument; Argument = GetSymbol(DiaChildSymbol); Symbol->u.Function.Arguments[Index] = Argument; - DiaChildSymbol->Release(); + Index += 1; } - - DiaSymbolEnumerator->Release(); } VOID @@ -814,12 +821,10 @@ SymbolModule::ProcessSymbolFunctionArg( IN SYMBOL* Symbol ) { - IDiaSymbol* DiaArgumentTypeSymbol; + CComPtr DiaArgumentTypeSymbol; DiaSymbol->get_type(&DiaArgumentTypeSymbol); Symbol->u.FunctionArg.Type = GetSymbol(DiaArgumentTypeSymbol); - - DiaArgumentTypeSymbol->Release(); } VOID @@ -832,7 +837,7 @@ SymbolModule::ProcessSymbolUdt( DiaSymbol->get_udtKind(&Kind); Symbol->u.Udt.Kind = static_cast(Kind); - IDiaEnumSymbols* DiaSymbolEnumerator; + CComPtr DiaSymbolEnumerator; if (FAILED(DiaSymbol->findChildren(SymTagData, nullptr, nsNone, &DiaSymbolEnumerator))) { @@ -846,13 +851,14 @@ SymbolModule::ProcessSymbolUdt( Symbol->u.Udt.FieldCount = static_cast(ChildCount); Symbol->u.Udt.Fields = new SYMBOL_UDT_FIELD[ChildCount + 1]; - IDiaSymbol* DiaChildSymbol; + IDiaSymbol* Result; ULONG FetchedSymbolCount = 0; + DWORD Index = 0; - for (DWORD Index = 0; - SUCCEEDED(DiaSymbolEnumerator->Next(1, &DiaChildSymbol, &FetchedSymbolCount)) && (FetchedSymbolCount == 1); - Index++) + while (SUCCEEDED(DiaSymbolEnumerator->Next(1, &Result, &FetchedSymbolCount)) && (FetchedSymbolCount == 1)) { + CComPtr DiaChildSymbol(Result); + SYMBOL_UDT_FIELD* Member = &Symbol->u.Udt.Fields[Index]; Member->Name = GetSymbolName(DiaChildSymbol); @@ -868,17 +874,13 @@ SymbolModule::ProcessSymbolUdt( DiaChildSymbol->get_bitPosition(&Member->BitPosition); - IDiaSymbol* MemberTypeDiaSymbol; + CComPtr MemberTypeDiaSymbol; DiaChildSymbol->get_type(&MemberTypeDiaSymbol); Member->Type = GetSymbol(MemberTypeDiaSymbol); - MemberTypeDiaSymbol->Release(); - - DiaChildSymbol->Release(); + Index += 1; } - DiaSymbolEnumerator->Release(); - // // Padding. // @@ -899,7 +901,6 @@ SymbolModule::ProcessSymbolUdt( PaddingSymbolArrayElement->IsVolatile = FALSE; PaddingSymbolArrayElement->Name = nullptr; - SYMBOL* PaddingSymbolArray = new SYMBOL; PaddingSymbolArray->Tag = SymTagArrayType; PaddingSymbolArray->BaseType = btNoType; diff --git a/Source/PDB.h b/Source/PDB.h index 6616b41..48a03ab 100644 --- a/Source/PDB.h +++ b/Source/PDB.h @@ -235,6 +235,12 @@ struct _SYMBOL // enum SymTagEnum Tag; + // + // Data kind. + // Only sef it Tag == SymTagData. + // + enum DataKind DataKind; + // // Base type. // Only set if Tag == SymTagBaseType. diff --git a/Source/PDBExtractor.cpp b/Source/PDBExtractor.cpp index deae990..3f56d44 100644 --- a/Source/PDBExtractor.cpp +++ b/Source/PDBExtractor.cpp @@ -112,7 +112,7 @@ PDBExtractor::Run( Result = EXIT_FAILURE; } - CloseOpenedFiles(); + CloseOpenFiles(); return Result; } @@ -676,7 +676,7 @@ PDBExtractor::DumpAllSymbolsOneByOne() } void -PDBExtractor::CloseOpenedFiles() +PDBExtractor::CloseOpenFiles() { // // We want to free the memory only if the filename was specified, diff --git a/Source/PDBExtractor.h b/Source/PDBExtractor.h index adbbc3a..b69731e 100644 --- a/Source/PDBExtractor.h +++ b/Source/PDBExtractor.h @@ -81,7 +81,7 @@ class PDBExtractor DumpAllSymbolsOneByOne(); void - CloseOpenedFiles(); + CloseOpenFiles(); private: PDB m_PDB; diff --git a/Source/PDBHeaderReconstructor.cpp b/Source/PDBHeaderReconstructor.cpp index 9e8a9e5..184ab2b 100644 --- a/Source/PDBHeaderReconstructor.cpp +++ b/Source/PDBHeaderReconstructor.cpp @@ -1,6 +1,4 @@ #include "PDBHeaderReconstructor.h" - -#pragma once #include "PDBReconstructorBase.h" #include @@ -43,8 +41,7 @@ PDBHeaderReconstructor::GetCorrectedSymbolName( const SYMBOL* Symbol ) const { - auto CorrectedNameIt = m_CorrectedSymbolNames.find(Symbol); - if (CorrectedNameIt == m_CorrectedSymbolNames.end()) + if (!m_CorrectedSymbolNames.contains(Symbol)) { // // Build corrected name: @@ -487,7 +484,7 @@ PDBHeaderReconstructor::Write( ... ) { - char TempBuffer[16 * 1024]; + char TempBuffer[8 * 1024]; va_list ArgPtr; va_start(ArgPtr, Format); diff --git a/Source/pdbex.vcxproj b/Source/pdbex.vcxproj index 8b8ce28..0ed4999 100644 --- a/Source/pdbex.vcxproj +++ b/Source/pdbex.vcxproj @@ -98,6 +98,7 @@ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(VSInstallDir)DIA SDK\include true + stdcpplatest Console @@ -117,6 +118,7 @@ copy "$(SolutionDir)Library\$(PlatformTarget)\symsrv.dll" "$(OutDir)" _DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(VSInstallDir)DIA SDK\include true + stdcpplatest Console @@ -139,6 +141,7 @@ copy "$(SolutionDir)Library\$(PlatformTarget)\symsrv.dll" "$(OutDir)" $(VSInstallDir)DIA SDK\include MultiThreaded true + stdcpplatest Console @@ -163,6 +166,7 @@ copy "$(SolutionDir)Library\$(PlatformTarget)\symsrv.dll" "$(OutDir)" $(VSInstallDir)DIA SDK\include MultiThreaded true + stdcpplatest Console