From dbb9782404f90b9e4a50419468d9cde3efa44f66 Mon Sep 17 00:00:00 2001
From: "SND\\kernelnet_cp"
 <SND\kernelnet_cp@9b283d60-5439-405e-af05-b73fd8c4d996>
Date: Mon, 26 Sep 2011 08:46:32 +0000
Subject: [PATCH] [[0.1.x] updated : module class integrated with Dia

git-svn-id: https://pykd.svn.codeplex.com/svn@70036 9b283d60-5439-405e-af05-b73fd8c4d996
---
 pykd/dbgext.cpp            | 21 ++++++++++-------
 pykd/module.cpp            | 47 ++++++++++++++++++++++++++++++++++----
 pykd/module.h              | 24 +++++++++++++++----
 test/scripts/diatest.py    |  6 +++++
 test/scripts/moduletest.py | 43 ++++++++++++++++++++--------------
 5 files changed, 107 insertions(+), 34 deletions(-)

diff --git a/pykd/dbgext.cpp b/pykd/dbgext.cpp
index ba51150..cc2d941 100644
--- a/pykd/dbgext.cpp
+++ b/pykd/dbgext.cpp
@@ -116,19 +116,24 @@ BOOST_PYTHON_MODULE( pykd )
         "Return instance of the Module class which posseses specified address" );
 
     python::class_<pykd::Module>("module", "Class representing executable module", python::no_init )
-         .def("begin", &pykd::Module::getBase,
+        .def("begin", &pykd::Module::getBase,
              "Return start address of the module" )
-         .def("end", &pykd::Module::getEnd,
+        .def("end", &pykd::Module::getEnd,
              "Return end address of the module" )
-         .def("size", &pykd::Module::getSize,
+        .def("size", &pykd::Module::getSize,
               "Return size of the module" )
-         .def("name", &pykd::Module::getName,
-             "Return name of the module" )       
-         .def("pdb", &pykd::Module::getPdbName,
+        .def("name", &pykd::Module::getName,
+             "Return name of the module" )      
+        .def("image", &pykd::Module::getImageName,
+             "Return name of the image of the module" )
+        .def("pdb", &pykd::Module::getPdbName,
              "Return the full path to the module's pdb file ( symbol information )" )
-         .def("reload", &pykd::Module::reloadSymbols,
-            "(Re)load symbols for the module" );
+        .def("reload", &pykd::Module::reloadSymbols,
+            "(Re)load symbols for the module" )
+        .def("symbols", &pykd::Module::getSymbols,
+            "Return list of all symbols of the module" );
 
+        
     python::def( "diaLoadPdb", &pyDia::GlobalScope::loadPdb, 
         "Open pdb file for quering debug symbols. Return DiaSymbol of global scope");
 
diff --git a/pykd/module.cpp b/pykd/module.cpp
index c5739bb..5f48876 100644
--- a/pykd/module.cpp
+++ b/pykd/module.cpp
@@ -36,6 +36,21 @@ Module::Module( IDebugClient5 *client, const std::string& moduleName ) : DbgObje
          throw DbgException( "IDebugSymbol::GetModuleParameters  failed" );    
 
     m_size = moduleParam.Size;
+
+    char imageName[0x100];
+
+    hres = m_symbols->GetModuleNameString( 
+        DEBUG_MODNAME_IMAGE,
+        DEBUG_ANY_ID,
+        m_base,
+        imageName,
+        sizeof( imageName ),
+        NULL );
+
+    if ( FAILED( hres ) )
+        throw DbgException( "IDebugSymbol::GetModuleNameString failed" );
+
+    m_imageName = std::string( imageName );
 }
 
 ///////////////////////////////////////////////////////////////////////////////////
@@ -66,6 +81,21 @@ Module::Module( IDebugClient5 *client, ULONG64 offset ) : DbgObject( client )
 
     m_name = std::string( moduleName );
 
+    char imageName[0x100];
+
+    hres = m_symbols->GetModuleNameString( 
+        DEBUG_MODNAME_IMAGE,
+        DEBUG_ANY_ID,
+        m_base,
+        imageName,
+        sizeof( imageName ),
+        NULL );
+
+    if ( FAILED( hres ) )
+        throw DbgException( "IDebugSymbol::GetModuleNameString failed" );
+
+    m_imageName = std::string( imageName );
+
     DEBUG_MODULE_PARAMETERS     moduleParam = { 0 };
     hres = m_symbols->GetModuleParameters( 1, &m_base, 0, &moduleParam );
     if ( FAILED( hres ) )
@@ -76,7 +106,7 @@ Module::Module( IDebugClient5 *client, ULONG64 offset ) : DbgObject( client )
 
 ///////////////////////////////////////////////////////////////////////////////////
 
-std::wstring
+std::string
 Module::getPdbName()
 {
     HRESULT         hres;
@@ -97,7 +127,10 @@ Module::getPdbName()
     if ( FAILED( hres ) )
         throw DbgException( "IDebugAdvanced2::GetSymbolInformation failed" );
 
-    return std::wstring( moduleInfo.LoadedPdbName );
+    char  pdbName[ 256 ];                
+    WideCharToMultiByte( CP_ACP, 0, moduleInfo.LoadedPdbName, 256, pdbName, 256, NULL, NULL );
+
+    return std::string( pdbName );
 }
 
 ///////////////////////////////////////////////////////////////////////////////////
@@ -107,10 +140,14 @@ Module::reloadSymbols()
 {
     HRESULT     hres;
 
-    hres = m_symbols->Reload( "/f" );
-    if ( FAILED( hres ) )
-        throw DbgException("IDebugSymbols::Reload failed" );           
+    std::string  param = "/f ";
+    param += m_imageName;
 
+    hres = m_symbols->Reload( param.c_str() );
+    if ( FAILED( hres ) )
+        throw DbgException("IDebugSymbols::Reload failed" );
+
+    m_dia = pyDia::GlobalScope::loadPdb( getPdbName() );
 }
 
 ///////////////////////////////////////////////////////////////////////////////////
diff --git a/pykd/module.h b/pykd/module.h
index e571c88..514a231 100644
--- a/pykd/module.h
+++ b/pykd/module.h
@@ -3,6 +3,7 @@
 #include <string>
 
 #include "dbgobj.h"
+#include "diawrapper.h"
 
 namespace pykd {
 
@@ -20,6 +21,10 @@ public:
         return m_name;
     }
 
+    std::string getImageName() {
+        return m_imageName;
+    }
+
     ULONG64  getBase() {
         return m_base;
     }
@@ -32,17 +37,28 @@ public:
         return m_size;
     }
 
-    std::wstring
+    std::string
     getPdbName();
 
     void
     reloadSymbols();
 
+    python::list
+    getSymbols() {
+        if ( !m_dia )
+            m_dia = pyDia::GlobalScope::loadPdb( getPdbName() );
+
+        return m_dia->findChildrenEx( SymTagNull, "*", nsRegularExpression );
+    }
+
 private:
 
-    std::string     m_name;
-    ULONG64         m_base;
-    ULONG           m_size;
+    std::string             m_name;
+    std::string             m_imageName;
+    ULONG64                 m_base;
+    ULONG                   m_size;
+    pyDia::GlobalScopePtr   m_dia;
+
 
 };
 
diff --git a/test/scripts/diatest.py b/test/scripts/diatest.py
index ce3a16d..8b932f4 100644
--- a/test/scripts/diatest.py
+++ b/test/scripts/diatest.py
@@ -7,6 +7,12 @@ import target
 import pykd
 
 class DiaTest( unittest.TestCase ):
+
+    def testCtor(self):
+        """ DiaSymbol can not be created direct """
+        try: pykd.DiaSymbol()
+        except RuntimeError: pass
+
     def testFind(self):
         try:
             gScope = pykd.diaLoadPdb( str(target.module.pdb()) )
diff --git a/test/scripts/moduletest.py b/test/scripts/moduletest.py
index 3780ede..79cc3d2 100644
--- a/test/scripts/moduletest.py
+++ b/test/scripts/moduletest.py
@@ -9,34 +9,43 @@ import pykd
 class ModuleTest( unittest.TestCase ):
     
     def testCtor( self ):
-         self.assertRaises( RuntimeError, pykd.module )
+        " module class can not be created direct """
+        try: pykd.module()
+        except RuntimeError: pass         
          
     def testName( self ):
-         self.assertEqual( target.moduleName, target.module.name() )
+        self.assertEqual( target.moduleName, target.module.name() )
          
     def testSize( self ):
-         self.assertNotEqual( 0, target.module.size() )
+        self.assertNotEqual( 0, target.module.size() )
          
     def testBegin( self ):
-         self.assertNotEqual( 0, target.module.begin() )
+        self.assertNotEqual( 0, target.module.begin() )
              
     def testEnd( self ):
-         self.assertEqual( target.module.size(), target.module.end() - target.module.begin() )
+        self.assertEqual( target.module.size(), target.module.end() - target.module.begin() )
          
     def testPdb( self ):
-         self.assertNotEqual( "", target.module.pdb() );
+        self.assertNotEqual( "", target.module.pdb() )
          
+    def testImage( self ):
+        self.assertEqual( target.module.name() + ".exe", target.module.image() )
+
     def testFindModule( self ):
     
-         try: pykd.findModule( target.module.begin() - 0x10 )
-         except pykd.BaseException: pass
-         #self.assertRaises( pykd.BaseException, pykd.findModule, target.module.begin() - 0x10 ) 
-          
-         self.assertNotEqual( None, pykd.findModule( target.module.begin() ) )
-         self.assertNotEqual( None, pykd.findModule( target.module.begin() + 0x10) )
-         
-         try: pykd.findModule( target.module.end() )
-         except pykd.BaseException: pass
+        try: pykd.findModule( target.module.begin() - 0x10 )
+        except pykd.BaseException: pass
+        #self.assertRaises( pykd.BaseException, pykd.findModule, target.module.begin() - 0x10 ) 
+
+        self.assertNotEqual( None, pykd.findModule( target.module.begin() ) )
+        self.assertNotEqual( None, pykd.findModule( target.module.begin() + 0x10) )
+
+        try: pykd.findModule( target.module.end() )
+        except pykd.BaseException: pass
  
-         try: pykd.findModule( target.module.end() + 0x10)
-         except pykd.BaseException: pass
+        try: pykd.findModule( target.module.end() + 0x10)
+        except pykd.BaseException: pass
+
+    def testSymbols( self ):
+        syms = target.module.symbols()
+        self.assertNotEqual( 0, len( syms ) )