From 503c8fd74774a90e74a5ca1ca9225a366672f65f Mon Sep 17 00:00:00 2001
From: "SND\\kernelnet_cp"
 <SND\kernelnet_cp@9b283d60-5439-405e-af05-b73fd8c4d996>
Date: Tue, 30 Aug 2016 10:28:02 +0000
Subject: [PATCH] [0.3.x] added : setReg routine ( set a CPU register value by
 its name or its index ) [0.3.x] added : getRegisterName routine ( return
 register name by its index )

git-svn-id: https://pykd.svn.codeplex.com/svn@91031 9b283d60-5439-405e-af05-b73fd8c4d996
---
 pykd/pycpucontext.cpp    | 20 ++++++++++++++++-
 pykd/pycpucontext.h      |  6 ++++-
 pykd/pykdver.h           |  2 +-
 pykd/pymod.cpp           |  6 +++++
 pykd/variant.h           | 33 ++++++++++++++++++---------
 test/scripts/pykdtest.py |  4 ++--
 test/scripts/regtest.py  | 48 ++++++++++++++++++++++++++++++----------
 7 files changed, 91 insertions(+), 28 deletions(-)

diff --git a/pykd/pycpucontext.cpp b/pykd/pycpucontext.cpp
index 7bab7c1..516ddc1 100644
--- a/pykd/pycpucontext.cpp
+++ b/pykd/pycpucontext.cpp
@@ -43,7 +43,25 @@ python::object getRegisterByIndex(unsigned long index)
 
 ///////////////////////////////////////////////////////////////////////////////
 
-std::wstring getRegisterNameByIndex(unsigned long index)
+void setRegisterByName(const std::wstring& name, const python::object& value)
+{
+    AutoRestorePyState  pystate;
+
+    kdlib::setRegisterByName(name, NumVariantAdaptor::convertToVariant(value));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void setRegisterByIndex(unsigned long index, const python::object& value)
+{
+    AutoRestorePyState  pystate;
+
+    kdlib::setRegisterByIndex(index, NumVariantAdaptor::convertToVariant(value));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+std::wstring getRegisterName(unsigned long index)
 {
     AutoRestorePyState  pystate;
     return kdlib::getRegisterName(index);
diff --git a/pykd/pycpucontext.h b/pykd/pycpucontext.h
index a240d9e..34a1726 100644
--- a/pykd/pycpucontext.h
+++ b/pykd/pycpucontext.h
@@ -72,7 +72,11 @@ python::object getRegisterByName( const std::wstring &name );
 
 python::object getRegisterByIndex( unsigned long index );
 
-std::wstring getRegisterNameByIndex(unsigned long index);
+std::wstring getRegisterName(unsigned long index);
+
+void setRegisterByName(const std::wstring& name, const python::object& value);
+
+void setRegisterByIndex(unsigned long index, const python::object& value);
 
 inline unsigned long getNumberRegisters() {
     AutoRestorePyState  pystate;
diff --git a/pykd/pykdver.h b/pykd/pykdver.h
index 7e60eb7..4ceaba0 100644
--- a/pykd/pykdver.h
+++ b/pykd/pykdver.h
@@ -2,7 +2,7 @@
 #define PYKD_VERSION_MAJOR      0
 #define PYKD_VERSION_MINOR      3
 #define PYKD_VERSION_SUBVERSION 1
-#define PYKD_VERSION_BUILDNO    5
+#define PYKD_VERSION_BUILDNO    6
 
 #define __VER_STR2__(x) #x
 #define __VER_STR1__(x) __VER_STR2__(x)
diff --git a/pykd/pymod.cpp b/pykd/pymod.cpp
index 7fbd3fe..e9e3349 100644
--- a/pykd/pymod.cpp
+++ b/pykd/pymod.cpp
@@ -411,8 +411,14 @@ BOOST_PYTHON_MODULE( pykd )
         "Return a CPU regsiter value by the register's name" );
     python::def( "reg", pykd::getRegisterByIndex,
         "Return a CPU register value by the register's number");
+    python::def( "setReg", pykd::setRegisterByName,
+        "Set a CPU register value by its name" );
+    python::def( "setReg", pykd::setRegisterByIndex,
+        "Set a CPU register value by its index" );
     python::def( "getNumberRegisters", pykd::getNumberRegisters,
         "Return a number of CPU registers");
+    python::def( "getRegisterName", pykd::getRegisterName,
+        "Return register name by its index");
     python::def("getIP", pykd::getIP,
         "Return instruction pointer");
     python::def("getSP", pykd::getSP,
diff --git a/pykd/variant.h b/pykd/variant.h
index 3637db3..81f3d27 100644
--- a/pykd/variant.h
+++ b/pykd/variant.h
@@ -13,23 +13,22 @@ class NumVariantAdaptor : public kdlib::NumBehavior
 
 public:
 
-
-    static kdlib::NumBehavior* NumVariantAdaptor::getVariant(const python::object &obj)
-    {
-        NumVariantAdaptor*  var = new NumVariantAdaptor();
+   static kdlib::NumVariant NumVariantAdaptor::convertToVariant( const python::object &obj)
+   {
+        kdlib::NumVariant   var;
 
         if (PyBool_Check(obj.ptr()))
         {
             if (obj.ptr() == Py_True)
-                var->m_variant.setBool(true);
+                var.setBool(true);
             else
-                var->m_variant.setBool(false);
+                var.setBool(false);
             return var;
         }
 
         if (PyFloat_Check(obj.ptr()))
         {
-            var->m_variant.setDouble(PyFloat_AsDouble(obj.ptr()));
+            var.setDouble(PyFloat_AsDouble(obj.ptr()));
             return var;
         }
 
@@ -37,7 +36,7 @@ public:
 
         if (PyInt_CheckExact(obj.ptr()))
         {
-            var->m_variant.setLong(PyLong_AsLong(obj.ptr()));
+            var.setLong(PyLong_AsLong(obj.ptr()));
             return var;
         }
 #endif
@@ -47,19 +46,19 @@ public:
             if (_PyLong_NumBits(obj.ptr()) > 64)
                 throw pykd::OverflowException("int too big to convert");
 
-            var->m_variant.setULongLong(PyLong_AsUnsignedLongLong(obj.ptr()));
+            var.setULongLong(PyLong_AsUnsignedLongLong(obj.ptr()));
         }
         else
         {
             if (_PyLong_NumBits(obj.ptr()) > 63)
                 throw pykd::OverflowException("int too big to convert");
 
-            var->m_variant.setLongLong(PyLong_AsLongLong(obj.ptr()));
+            var.setLongLong(PyLong_AsLongLong(obj.ptr()));
         }
 
 
         return var;
-    }
+   }
 
    static python::object NumVariantAdaptor::convertToPython( kdlib::NumVariant& var )
    {
@@ -102,6 +101,18 @@ public:
         return python::object( var.asInt() );
    }
 
+
+    static kdlib::NumBehavior* NumVariantAdaptor::getVariant(const python::object &obj)
+    {
+        NumVariantAdaptor*  var = new NumVariantAdaptor();
+
+        var->m_variant = NumVariantAdaptor::convertToVariant(obj);
+
+        return var;
+    }
+
+
+
    static python::object NumVariantAdaptor::convertToPython( kdlib::NumBehavior& num )
    {
         kdlib::NumVariant var = kdlib::NumVariant( num );
diff --git a/test/scripts/pykdtest.py b/test/scripts/pykdtest.py
index 134fa98..810f0ee 100644
--- a/test/scripts/pykdtest.py
+++ b/test/scripts/pykdtest.py
@@ -54,7 +54,7 @@ def getTestSuite( singleName = "" ):
                 unittest.TestLoader().loadTestsFromTestCase( memtest.MemoryTest ),
                 unittest.TestLoader().loadTestsFromTestCase( typeinfo.TypeInfoTest ),
                 unittest.TestLoader().loadTestsFromTestCase( typedvar.TypedVarTest ),
-                #unittest.TestLoader().loadTestsFromTestCase( regtest.CpuRegTest ),
+                unittest.TestLoader().loadTestsFromTestCase( regtest.CpuRegTest ),
                 unittest.TestLoader().loadTestsFromTestCase( customtypestest.CustomTypesTest ),
                 unittest.TestLoader().loadTestsFromTestCase( synsymtest.SynSymTest ),
                 # ^^^
@@ -88,7 +88,7 @@ if __name__ == "__main__":
     target.moduleName = os.path.splitext(os.path.basename(target.appPath))[0]
 
     unittest.TextTestRunner(stream=sys.stdout, verbosity=2).run( getTestSuite() )
-    #unittest.TextTestRunner(stream=sys.stdout, verbosity=2).run( getTestSuite("typedvar.TypedVarTest.testCompare") )
+    #unittest.TextTestRunner(stream=sys.stdout, verbosity=2).run( getTestSuite("regtest.CpuRegTest.testSetRegValue") )
 
     try: input = raw_input
     except NameError: pass
diff --git a/test/scripts/regtest.py b/test/scripts/regtest.py
index 2db26f6..f6fb71d 100644
--- a/test/scripts/regtest.py
+++ b/test/scripts/regtest.py
@@ -4,17 +4,41 @@ import target
 import pykd
 
 class CpuRegTest( unittest.TestCase ):
-    
-    def testCtor(self):
-        currentcpu = pykd.cpu()
-        cpu0 = pykd.cpu(0)
 
-    def testIp(self):
-        currentcpu = pykd.cpu()
-        self.assertNotEqual( 0, currentcpu.ip )
-        self.assertNotEqual( 0, currentcpu.sp )
-        self.assertNotEqual( 0, currentcpu.fp )
+    def testGetRegName(self):
+        self.assertNotEqual(None, pykd.getRegisterName(10))
+
+    def testGetRegValue(self):
+        for regIndex in xrange(pykd.getNumberRegisters()):
+            regName = pykd.getRegisterName(regIndex)
+            try:
+                self.assertEqual( pykd.reg(regIndex), pykd.reg(regName) )
+            except pykd.DbgException:
+                pass  # pass exception unsupported register type
+
+    def testSetRegValue(self):
+
+         oldVal = pykd.reg(2)
+         pykd.setReg(2, 10)
+         self.assertEqual(pykd.reg(2), 10)
+         pykd.setReg( pykd.getRegisterName(2), oldVal )
+         self.assertEqual(pykd.reg(2), oldVal )
+
+
+
+    #def testCtor(self):
+    #    currentcpu = pykd.cpu()
+    #    cpu0 = pykd.cpu(0)
+
+    #def testIp(self):
+    #    currentcpu = pykd.cpu()
+    #    self.assertNotEqual( 0, currentcpu.ip )
+    #    self.assertNotEqual( 0, currentcpu.sp )
+    #    self.assertNotEqual( 0, currentcpu.fp )
+
+    #def testRegEnum(self):
+    #    for r in pykd.cpu():
+    #        pass
+
+
 
-    def testRegEnum(self):
-        for r in pykd.cpu():
-            pass