From 6c582490eef6c7c0d2c5495ae13746f18595747f Mon Sep 17 00:00:00 2001
From: "SND\\kernelnet_cp"
 <SND\kernelnet_cp@9b283d60-5439-405e-af05-b73fd8c4d996>
Date: Tue, 16 Oct 2012 06:39:42 +0000
Subject: [PATCH] [0.2.x] added : loadExt, removeExt, callExt routines

git-svn-id: https://pykd.svn.codeplex.com/svn@80241 9b283d60-5439-405e-af05-b73fd8c4d996
---
 pykd/dbgengine.h    |  5 +++++
 pykd/pymod.cpp      | 16 +++++++++++----
 pykd/win/dbgeng.cpp | 48 +++++++++++++++++++++++++++++++++++++++++++--
 3 files changed, 63 insertions(+), 6 deletions(-)

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  &params  );
+
 };
 
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  &params  )
+{
+    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