diff --git a/pykd/dbgengine.h b/pykd/dbgengine.h index 3fab1e8..8ac16ae 100644 --- a/pykd/dbgengine.h +++ b/pykd/dbgengine.h @@ -101,5 +101,10 @@ std::string getSymbolPath(); void setSymbolPath(const std::string &symPath); void appendSymbolPath(const std::string &symPath); +// Extensions +ULONG64 loadExtension(const std::wstring &extPath ); +void removeExtension( ULONG64 extHandle ); +std::string callExtension( ULONG64 extHandle, const std::wstring command, const std::wstring ¶ms ); + }; diff --git a/pykd/pymod.cpp b/pykd/pymod.cpp index edc0c5b..44c1bdd 100644 --- a/pykd/pymod.cpp +++ b/pykd/pymod.cpp @@ -66,6 +66,17 @@ BOOST_PYTHON_MODULE( pykd ) { python::scope().attr("version") = pykdVersion; + // DbgEng services + python::def( "setSymSrvDir", &setSymSrvDir, + "Set directory of SYMSRV.dll library.\nUsually this is a directory of WinDbg"); + python::def( "loadExt", &loadExtension, + "Load a WinDBG extension. Return handle of the loaded extension" ); + python::def( "removeExt", &removeExtension, + "Unload a WinDBG extension. Parameters: handle returned by loadExt" ); + 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, @@ -248,10 +259,7 @@ BOOST_PYTHON_MODULE( pykd ) "Set current process by address" ); python::def( "setImplicitThread", &setImplicitThread, "Set implicit thread for current process" ); - - python::def( "setSymSrvDir", &setSymSrvDir, - "Set directory of SYMSRV.dll library.\nUsually this is a directory of WinDbg"); - + // symbol path python::def( "getSymbolPath", &getSymbolPath, "Returns current symbol path"); python::def( "setSymbolPath", &setSymbolPath, "Set current symbol path"); diff --git a/pykd/win/dbgeng.cpp b/pykd/win/dbgeng.cpp index b09ecf2..d4b37d7 100644 --- a/pykd/win/dbgeng.cpp +++ b/pykd/win/dbgeng.cpp @@ -1126,16 +1126,60 @@ void setImplicitThread( ULONG64 threadAddr ) { PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate ); - HRESULT hres; + HRESULT hres; threadAddr = addr64(threadAddr); hres = g_dbgEng->system->SetImplicitThreadDataOffset( threadAddr ); if ( FAILED( hres ) ) - throw DbgException( "IDebugSystemObjects2::SetImplicitThreadDataOffset failed" ); + throw DbgException( "IDebugSystemObjects2::SetImplicitThreadDataOffset failed" ); } /////////////////////////////////////////////////////////////////////////////// +ULONG64 loadExtension(const std::wstring &extPath ) +{ + PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate ); + + HRESULT hres; + ULONG64 handle = 0; + + hres = g_dbgEng->control->AddExtensionWide( extPath.c_str(), 0, &handle ); + if ( FAILED( hres ) ) + throw DbgException( "IDebugControl::AddExtension failed" ); + + return handle; +} + +/////////////////////////////////////////////////////////////////////////////// + +void removeExtension( ULONG64 extHandle ) +{ + PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate ); + + g_dbgEng->control->RemoveExtension( extHandle ); +} + +/////////////////////////////////////////////////////////////////////////////// + +std::string callExtension( ULONG64 extHandle, const std::wstring command, const std::wstring ¶ms ) +{ + PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate ); + + HRESULT hres; + + OutputReader outReader( g_dbgEng->client ); + + hres = g_dbgEng->control->CallExtensionWide( extHandle, command.c_str(), params.c_str() ); + + if ( FAILED( hres ) ) + throw DbgException( "IDebugControl::CallExtension failed" ); + + return std::string( outReader.Line() ); +} + +/////////////////////////////////////////////////////////////////////////////// + + } // end pykd namespace