From 9d12b928b89e7223dd32efc04a123daa49c071ee Mon Sep 17 00:00:00 2001 From: hfiref0x Date: Wed, 18 Jun 2025 21:10:41 +0700 Subject: [PATCH] Fix "File not found" completely This update fixes: Issues with "File not found" origin - when user is confused with "File not found" message and it is not clear who is not found - pdb file or MsDia140.dll. Fixes an issue within PDBExtractor->ParseParameters NextArgumentLength calculated as length of CurrentArgument. Fix potential bugs in ref counting in PDBCallback->AddRef, PDBCallback->Release AddRef should increment the reference count and return the new value, not the old one. Release contain potential undefined behavior as it can return member of already deleted object. --- Source/PDB.cpp | 31 ++++++++++++++----------------- Source/PDB.h | 6 +++--- Source/PDBCallback.h | 10 ++++------ Source/PDBExtractor.cpp | 23 ++++++++++++++++++++--- 4 files changed, 41 insertions(+), 29 deletions(-) diff --git a/Source/PDB.cpp b/Source/PDB.cpp index f9c3aa2..0f15807 100644 --- a/Source/PDB.cpp +++ b/Source/PDB.cpp @@ -6,7 +6,6 @@ #include -#include #include ////////////////////////////////////////////////////////////////////////// @@ -18,7 +17,7 @@ class SymbolModuleBase public: SymbolModuleBase(); - BOOL + HRESULT Open( IN const CHAR* Path ); @@ -73,8 +72,7 @@ SymbolModuleBase::LoadDiaViaLoadLibrary() if (!Module) { - Result = HRESULT_FROM_WIN32(GetLastError()); - return Result; + return HRESULT_FROM_WIN32(GetLastError()); } using PDLLGETCLASSOBJECT_ROUTINE = HRESULT(WINAPI*)(REFCLSID, REFIID, LPVOID); @@ -82,8 +80,7 @@ SymbolModuleBase::LoadDiaViaLoadLibrary() if (!DllGetClassObject) { - Result = HRESULT_FROM_WIN32(GetLastError()); - return Result; + return HRESULT_FROM_WIN32(GetLastError()); } CComPtr ClassFactory; @@ -97,7 +94,7 @@ SymbolModuleBase::LoadDiaViaLoadLibrary() return ClassFactory->CreateInstance(nullptr, __uuidof(IDiaDataSource), (void**)& m_DataSource); } -BOOL +HRESULT SymbolModuleBase::Open( IN const CHAR* Path ) @@ -114,7 +111,7 @@ SymbolModuleBase::Open( if (FAILED(Result = LoadDiaViaCoCreateInstance()) && FAILED(Result = LoadDiaViaLoadLibrary())) { - return FALSE; + return Result; } // @@ -190,11 +187,11 @@ SymbolModuleBase::Open( goto Error; } - return TRUE; + return Result; Error: Close(); - return FALSE; + return Result; } VOID @@ -225,7 +222,7 @@ class SymbolModule ~SymbolModule(); - BOOL + HRESULT Open( IN const CHAR* Path ); @@ -368,18 +365,18 @@ SymbolModule::~SymbolModule() Close(); } -BOOL +HRESULT SymbolModule::Open( IN const CHAR* Path ) { - BOOL Result; + HRESULT Result; Result = SymbolModuleBase::Open(Path); - if (Result == FALSE) + if (FAILED(Result)) { - return FALSE; + return Result; } m_GlobalSymbol->get_machineType(&m_MachineType); @@ -390,7 +387,7 @@ SymbolModule::Open( BuildSymbolMap(); - return TRUE; + return S_OK; } BOOL @@ -1062,7 +1059,7 @@ PDB::~PDB() delete m_Impl; } -BOOL +HRESULT PDB::Open( IN const CHAR* Path ) diff --git a/Source/PDB.h b/Source/PDB.h index 48a03ab..dc31a58 100644 --- a/Source/PDB.h +++ b/Source/PDB.h @@ -3,7 +3,7 @@ #include #include - +#include #include #include #include @@ -314,9 +314,9 @@ class PDB // // Opens particular PDB file and parses it. // - // Returns non-zero value on success. + // Returns S_OK value on success. // - BOOL + HRESULT Open( IN const CHAR* Path ); diff --git a/Source/PDBCallback.h b/Source/PDBCallback.h index 471f1ef..3e6eef7 100644 --- a/Source/PDBCallback.h +++ b/Source/PDBCallback.h @@ -11,17 +11,15 @@ class PDBCallback ULONG STDMETHODCALLTYPE AddRef() override { - return m_RefCount++; + return ++m_RefCount; } ULONG STDMETHODCALLTYPE Release() override { - if ((--m_RefCount) == 0) - { + ULONG ref = --m_RefCount; + if (ref == 0) delete this; - } - - return m_RefCount; + return ref; } HRESULT STDMETHODCALLTYPE QueryInterface(REFIID Rid, void **Interface) override diff --git a/Source/PDBExtractor.cpp b/Source/PDBExtractor.cpp index c1de85e..057221b 100644 --- a/Source/PDBExtractor.cpp +++ b/Source/PDBExtractor.cpp @@ -60,6 +60,12 @@ namespace static const char* MESSAGE_FILE_NOT_FOUND = "File not found"; + static const char* MESSAGE_UNKNOWN_OPEN_FILE_ERROR = + "Unknown open file error"; + + static const char* MESSAGE_DLL_NOT_FOUND = + "msdia140.dll not found"; + static const char* MESSAGE_SYMBOL_NOT_FOUND = "Symbol not found"; @@ -201,7 +207,7 @@ PDBExtractor::ParseParameters( : nullptr; size_t NextArgumentLength = NextArgument - ? strlen(CurrentArgument) + ? strlen(NextArgument) : 0; // @@ -410,9 +416,20 @@ PDBExtractor::ParseParameters( void PDBExtractor::OpenPDBFile() { - if (m_PDB.Open(m_Settings.PdbPath.c_str()) == FALSE) + HRESULT Result; + + Result = m_PDB.Open(m_Settings.PdbPath.c_str()); + if (FAILED(Result)) { - throw PDBDumperException(MESSAGE_FILE_NOT_FOUND); + switch (Result) { + case HRESULT_FROM_WIN32(ERROR_MOD_NOT_FOUND): + throw PDBDumperException(MESSAGE_DLL_NOT_FOUND); + case HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND): + case E_PDB_NOT_FOUND: + throw PDBDumperException(MESSAGE_FILE_NOT_FOUND); + default: + throw PDBDumperException(MESSAGE_UNKNOWN_OPEN_FILE_ERROR); + } } }