From d4b38e40cb27bd0d8920e02dadf46bb53135980b Mon Sep 17 00:00:00 2001 From: "SND\\EreTIk_cp" Date: Fri, 24 Jan 2014 10:44:17 +0000 Subject: [PATCH] [0.2.x] add getExtensionSearchPath [0.2.x] workitem/12654 fixed git-svn-id: https://pykd.svn.codeplex.com/svn@87131 9b283d60-5439-405e-af05-b73fd8c4d996 --- pykd/dbgengine.h | 1 + pykd/python/pymod.cpp | 5 ++-- pykd/win/dbgeng.cpp | 67 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 2 deletions(-) diff --git a/pykd/dbgengine.h b/pykd/dbgengine.h index 6dfb0f9..94a67f6 100644 --- a/pykd/dbgengine.h +++ b/pykd/dbgengine.h @@ -203,6 +203,7 @@ void setSymbolPath(const std::string &symPath); void appendSymbolPath(const std::string &symPath); // Extensions +std::wstring getExtensionSearchPath(); ULONG64 loadExtension(const std::wstring &extPath ); ULONG64 getExtension(const std::wstring &extPath ); void removeExtension( ULONG64 extHandle ); diff --git a/pykd/python/pymod.cpp b/pykd/python/pymod.cpp index c13ba26..7c3af0b 100644 --- a/pykd/python/pymod.cpp +++ b/pykd/python/pymod.cpp @@ -81,7 +81,9 @@ BOOST_PYTHON_MODULE( pykd ) // DbgEng services python::def( "setSymSrvDir", &setSymSrvDir, - "Set directory of SYMSRV.dll library.\nUsually this is a directory of WinDbg"); + "Set directory of SYMSRV.dll library.\nUsually this is a directory of WinDbg" ); + python::def( "getExtensionSearchPath", &getExtensionSearchPath, + "Return the extension DLL search path" ); python::def( "loadExt", &loadExtension, "Load a WinDBG extension. Return handle of the loaded extension" ); python::def( "getExt", &getExtension, @@ -91,7 +93,6 @@ BOOST_PYTHON_MODULE( pykd ) python::def( "callExt", &callExtension, "Call a WinDBG extension's routine. Parameters: handle returned by loadExt; string command line" ); - // Manage debug target python::def( "startProcess", &startProcess, startProcess_( boost::python::args( "commandline", "debugChildren" ), diff --git a/pykd/win/dbgeng.cpp b/pykd/win/dbgeng.cpp index 3b0f175..b04e616 100644 --- a/pykd/win/dbgeng.cpp +++ b/pykd/win/dbgeng.cpp @@ -1289,6 +1289,48 @@ DebugEngine::DbgEngBind* DebugEngine::operator->() /////////////////////////////////////////////////////////////////////////////// +static std::wstring getExtensionSearchPathImpl() +{ + ULONG chars = MAX_PATH; + for (; ; ) + { + std::vector< wchar_t > rawPath(chars + 1, L'\0'); + HRESULT hres = + g_dbgEng->advanced->Request( + DEBUG_REQUEST_GET_EXTENSION_SEARCH_PATH_WIDE, + NULL, + 0, + &rawPath[0], + chars * sizeof(wchar_t), + NULL); + if (S_OK == hres) + { + std::wstring result = &rawPath[0]; + return result; + } + + if (S_FALSE == hres) + { + // The method was successful. However, the output would not fit in the + // output buffer OutBuffer, so truncated output was returned + chars *= 2; + continue; + } + + throw DbgException( "IDebugAdvanced::Request", hres ); + } +} + +/////////////////////////////////////////////////////////////////////////////// + +std::wstring getExtensionSearchPath() +{ + PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate ); + return getExtensionSearchPathImpl(); +} + +/////////////////////////////////////////////////////////////////////////////// + ULONG64 loadExtension(const std::wstring &extPath ) { PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate ); @@ -1296,10 +1338,35 @@ ULONG64 loadExtension(const std::wstring &extPath ) HRESULT hres; ULONG64 handle = 0; + std::vector< wchar_t > rawPath(MAX_PATH + 1, L'\0'); + DWORD ret = + ::SearchPath( + getExtensionSearchPathImpl().c_str(), + extPath.c_str(), + L".dll", + MAX_PATH, + &rawPath[0], + NULL); + if (!ret) + throw DbgException( "extension not found" ); + + struct _scoped_lib + { + _scoped_lib(const wchar_t *wsz) : m_hmod(::LoadLibrary(wsz)) {} + ~_scoped_lib() { if (m_hmod) ::FreeLibrary(m_hmod);} + HMODULE m_hmod; + } scoped_lib(&rawPath[0]); + if (!scoped_lib.m_hmod) + throw DbgException( "extension not found" ); + hres = g_dbgEng->control->AddExtensionWide( extPath.c_str(), 0, &handle ); if ( FAILED( hres ) ) throw DbgException( "IDebugControl::AddExtension", hres ); + // inderect call of dbgeng!ExtensionInfo::Load + FARPROC dummy = NULL; + g_dbgEng->control->GetExtensionFunctionWide(handle, L"dummy", &dummy); + return handle; }