mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-20 03:23:23 +08:00
[+] dia get type
[+] dia get location [+] dia print to string git-svn-id: https://pykd.svn.codeplex.com/svn@69841 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
parent
479f2745f6
commit
f241ea851b
@ -3,7 +3,6 @@
|
|||||||
#include <dbgeng.h>
|
#include <dbgeng.h>
|
||||||
|
|
||||||
#include <dia2.h>
|
#include <dia2.h>
|
||||||
#include <cvconst.h>
|
|
||||||
|
|
||||||
#include "module.h"
|
#include "module.h"
|
||||||
#include "diawrapper.h"
|
#include "diawrapper.h"
|
||||||
@ -98,13 +97,19 @@ BOOST_PYTHON_MODULE( pykd )
|
|||||||
"Retrieves the children of the symbol" )
|
"Retrieves the children of the symbol" )
|
||||||
.def( "size", &pyDia::Symbol::getSize,
|
.def( "size", &pyDia::Symbol::getSize,
|
||||||
"Retrieves the number of bits or bytes of memory used by the object represented by this symbol" )
|
"Retrieves the number of bits or bytes of memory used by the object represented by this symbol" )
|
||||||
//.def( "getName", &pyDia::Symbol::getName,
|
.def( "name", &pyDia::Symbol::getName,
|
||||||
// "Retrieves the name of the symbol" )
|
"Retrieves the name of the symbol" )
|
||||||
//.def( "getType", &pyDia::Symbol::getType,
|
.def( "type", &pyDia::Symbol::getType,
|
||||||
// "Retrieves the symbol that represents the type for this symbol" )
|
"Retrieves the symbol that represents the type for this symbol" )
|
||||||
.def( "getSymTag", &pyDia::Symbol::getSymTag,
|
.def( "rva", &pyDia::Symbol::getRva,
|
||||||
|
"Retrieves the relative virtual address (RVA) of the location")
|
||||||
|
.def( "symTag", &pyDia::Symbol::getSymTag,
|
||||||
"Retrieves the symbol type classifier: SymTagXxx" )
|
"Retrieves the symbol type classifier: SymTagXxx" )
|
||||||
//__str__ &pyDia::Symbol::print
|
.def( "locType", &pyDia::Symbol::getLocType,
|
||||||
|
"Retrieves the location type of a data symbol: LocIsXxx" )
|
||||||
|
.def( "value", &pyDia::Symbol::getValue,
|
||||||
|
"Retrieves the value of a constant")
|
||||||
|
.def( "__str__", &pyDia::Symbol::print)
|
||||||
.def("__getattr__", &pyDia::Symbol::getChildByName)
|
.def("__getattr__", &pyDia::Symbol::getChildByName)
|
||||||
.def("__len__", &pyDia::Symbol::getChildCount )
|
.def("__len__", &pyDia::Symbol::getChildCount )
|
||||||
.def("__getitem__", &pyDia::Symbol::getChildByIndex);
|
.def("__getitem__", &pyDia::Symbol::getChildByIndex);
|
||||||
@ -156,6 +161,19 @@ BOOST_PYTHON_MODULE( pykd )
|
|||||||
DEF_PY_CONST_ULONG(nsRegularExpression);
|
DEF_PY_CONST_ULONG(nsRegularExpression);
|
||||||
DEF_PY_CONST_ULONG(nsCaseInRegularExpression);
|
DEF_PY_CONST_ULONG(nsCaseInRegularExpression);
|
||||||
|
|
||||||
|
// location type
|
||||||
|
DEF_PY_CONST_ULONG(LocIsNull);
|
||||||
|
DEF_PY_CONST_ULONG(LocIsStatic);
|
||||||
|
DEF_PY_CONST_ULONG(LocIsTLS);
|
||||||
|
DEF_PY_CONST_ULONG(LocIsRegRel);
|
||||||
|
DEF_PY_CONST_ULONG(LocIsThisRel);
|
||||||
|
DEF_PY_CONST_ULONG(LocIsEnregistered);
|
||||||
|
DEF_PY_CONST_ULONG(LocIsBitField);
|
||||||
|
DEF_PY_CONST_ULONG(LocIsSlot);
|
||||||
|
DEF_PY_CONST_ULONG(LocIsIlRel);
|
||||||
|
DEF_PY_CONST_ULONG(LocInMetaData);
|
||||||
|
DEF_PY_CONST_ULONG(LocIsConstant);
|
||||||
|
|
||||||
// exception:
|
// exception:
|
||||||
// base exception
|
// base exception
|
||||||
python::class_<DbgException> dbgExceptionClass( "BaseException",
|
python::class_<DbgException> dbgExceptionClass( "BaseException",
|
||||||
|
@ -1,28 +1,77 @@
|
|||||||
|
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
|
|
||||||
#include <strstream>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "diawrapper.h"
|
#include "diawrapper.h"
|
||||||
|
#include "utils.h"
|
||||||
using namespace pykd;
|
|
||||||
|
|
||||||
namespace pyDia {
|
namespace pyDia {
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
PyObject *Exception::diaExceptTypeObject = NULL;
|
PyObject *Exception::diaExceptTypeObject = NULL;
|
||||||
|
|
||||||
const std::string Exception::descPrefix("pyDia: ");
|
const std::string Exception::descPrefix("pyDia: ");
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const char *Symbol::symTagName[SymTagMax] = {
|
||||||
|
"Null",
|
||||||
|
"Exe",
|
||||||
|
"Compiland",
|
||||||
|
"CompilandDetails",
|
||||||
|
"CompilandEnv",
|
||||||
|
"Function",
|
||||||
|
"Block",
|
||||||
|
"Data",
|
||||||
|
"Annotation",
|
||||||
|
"Label",
|
||||||
|
"PublicSymbol",
|
||||||
|
"UDT",
|
||||||
|
"Enum",
|
||||||
|
"FunctionType",
|
||||||
|
"PointerType",
|
||||||
|
"ArrayType",
|
||||||
|
"BaseType",
|
||||||
|
"Typedef",
|
||||||
|
"BaseClass",
|
||||||
|
"Friend",
|
||||||
|
"FunctionArgType",
|
||||||
|
"FuncDebugStart",
|
||||||
|
"FuncDebugEnd",
|
||||||
|
"UsingNamespace",
|
||||||
|
"VTableShape",
|
||||||
|
"VTable",
|
||||||
|
"Custom",
|
||||||
|
"Thunk",
|
||||||
|
"CustomType",
|
||||||
|
"ManagedType",
|
||||||
|
"Dimension"
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *Symbol::locTypeName[LocTypeMax] = {
|
||||||
|
"Null",
|
||||||
|
"Static",
|
||||||
|
"TLS",
|
||||||
|
"RegRel",
|
||||||
|
"ThisRel",
|
||||||
|
"Enregistered",
|
||||||
|
"BitField",
|
||||||
|
"Slot",
|
||||||
|
"IlRel",
|
||||||
|
"InMetaData",
|
||||||
|
"Constant"
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
std::string Exception::makeFullDesc(const std::string &desc, HRESULT hres)
|
std::string Exception::makeFullDesc(const std::string &desc, HRESULT hres)
|
||||||
{
|
{
|
||||||
std::strstream res;
|
std::stringstream sstream;
|
||||||
res << descPrefix << desc << " failed" << std::endl;
|
sstream << descPrefix << desc << " failed" << std::endl;
|
||||||
res << "Return value is 0x" << std::hex << hres;
|
sstream << "Return value is 0x" << std::hex << hres;
|
||||||
|
|
||||||
PCHAR errMessage = NULL;
|
PCHAR errMessage = NULL;
|
||||||
FormatMessageA(
|
FormatMessageA(
|
||||||
@ -35,16 +84,16 @@ std::string Exception::makeFullDesc(const std::string &desc, HRESULT hres)
|
|||||||
NULL);
|
NULL);
|
||||||
if (errMessage)
|
if (errMessage)
|
||||||
{
|
{
|
||||||
res << ":" << std::endl;
|
sstream << ": " << std::endl;
|
||||||
res << errMessage;
|
sstream << errMessage;
|
||||||
LocalFree(errMessage);
|
LocalFree(errMessage);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
res << std::endl;
|
sstream << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
return res.str();
|
return sstream.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -56,25 +105,6 @@ void Exception::exceptionTranslate( const Exception &e )
|
|||||||
PyErr_SetObject( diaExceptTypeObject, pyExcept.ptr() );
|
PyErr_SetObject( diaExceptTypeObject, pyExcept.ptr() );
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Convert to OLESTR helper
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
class toOleStr {
|
|
||||||
public:
|
|
||||||
toOleStr(const std::string &sz)
|
|
||||||
{
|
|
||||||
m_buf.resize( sz.size() + 1, L'\0' );
|
|
||||||
::MultiByteToWideChar( CP_ACP, 0, sz.c_str(), sz.size(), &m_buf[0], m_buf.size() );
|
|
||||||
}
|
|
||||||
|
|
||||||
operator const OLECHAR *() const {
|
|
||||||
return m_buf.empty() ? NULL : &m_buf[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::vector<OLECHAR> m_buf;
|
|
||||||
};
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
python::list Symbol::findChildrenImpl(
|
python::list Symbol::findChildrenImpl(
|
||||||
@ -85,19 +115,19 @@ python::list Symbol::findChildrenImpl(
|
|||||||
{
|
{
|
||||||
throwIfNull(__FUNCTION__);
|
throwIfNull(__FUNCTION__);
|
||||||
|
|
||||||
CComPtr< IDiaEnumSymbols > symbols;
|
DiaEnumSymbolsPtr symbols;
|
||||||
HRESULT hres =
|
HRESULT hres =
|
||||||
m_symbol->findChildren(
|
m_symbol->findChildren(
|
||||||
static_cast<enum SymTagEnum>(symTag),
|
static_cast<enum SymTagEnum>(symTag),
|
||||||
toOleStr(name),
|
toWStr(name),
|
||||||
nameCmpFlags,
|
nameCmpFlags,
|
||||||
&symbols);
|
&symbols);
|
||||||
if (FAILED(hres))
|
if (S_OK != hres)
|
||||||
throw Exception("Get list of children", hres);
|
throw Exception("Call IDiaSymbol::findChildren", hres);
|
||||||
|
|
||||||
python::list childList;
|
python::list childList;
|
||||||
|
|
||||||
CComPtr< IDiaSymbol > child;
|
DiaSymbolPtr child;
|
||||||
ULONG celt;
|
ULONG celt;
|
||||||
while ( SUCCEEDED(symbols->Next(1, &child, &celt)) && (celt == 1) )
|
while ( SUCCEEDED(symbols->Next(1, &child, &celt)) && (celt == 1) )
|
||||||
childList.append( Symbol(child) );
|
childList.append( Symbol(child) );
|
||||||
@ -113,57 +143,162 @@ ULONGLONG Symbol::getSize()
|
|||||||
|
|
||||||
ULONGLONG retValue;
|
ULONGLONG retValue;
|
||||||
HRESULT hres = m_symbol->get_length(&retValue);
|
HRESULT hres = m_symbol->get_length(&retValue);
|
||||||
if (FAILED(hres))
|
if (S_OK != hres)
|
||||||
throw Exception("Get length", hres);
|
throw Exception("Call IDiaSymbol::get_length", hres);
|
||||||
|
|
||||||
return retValue;
|
return retValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
std::string Symbol::getName()
|
||||||
|
{
|
||||||
|
throwIfNull(__FUNCTION__);
|
||||||
|
|
||||||
|
autoBstr bstrName;
|
||||||
|
HRESULT hres = m_symbol->get_name(&bstrName);
|
||||||
|
if (S_OK != hres)
|
||||||
|
throw Exception("Call IDiaSymbol::get_name", hres);
|
||||||
|
|
||||||
|
return bstrName.asStr();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
python::object Symbol::getType()
|
||||||
|
{
|
||||||
|
throwIfNull(__FUNCTION__);
|
||||||
|
|
||||||
|
DiaSymbolPtr _type;
|
||||||
|
HRESULT hres = m_symbol->get_type(&_type);
|
||||||
|
if (S_OK != hres)
|
||||||
|
throw Exception("Call IDiaSymbol::get_type", hres);
|
||||||
|
|
||||||
|
return python::object( Symbol(_type) );
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ULONG Symbol::getSymTag()
|
ULONG Symbol::getSymTag()
|
||||||
{
|
{
|
||||||
throwIfNull(__FUNCTION__);
|
throwIfNull(__FUNCTION__);
|
||||||
|
|
||||||
DWORD retValue;
|
DWORD retValue;
|
||||||
HRESULT hres = m_symbol->get_symTag(&retValue);
|
HRESULT hres = m_symbol->get_symTag(&retValue);
|
||||||
if (FAILED(hres))
|
if (S_OK != hres)
|
||||||
throw Exception("Get symbol type", hres);
|
throw Exception("Call IDiaSymbol::get_symTag", hres);
|
||||||
|
|
||||||
return retValue;
|
return retValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ULONG Symbol::getRva()
|
||||||
|
{
|
||||||
|
throwIfNull(__FUNCTION__);
|
||||||
|
|
||||||
|
DWORD retValue;
|
||||||
|
HRESULT hres = m_symbol->get_relativeVirtualAddress(&retValue);
|
||||||
|
if (S_OK != hres)
|
||||||
|
throw Exception("Call IDiaSymbol::get_relativeVirtualAddress", hres);
|
||||||
|
|
||||||
|
return retValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ULONG Symbol::getLocType()
|
||||||
|
{
|
||||||
|
throwIfNull(__FUNCTION__);
|
||||||
|
|
||||||
|
DWORD retValue;
|
||||||
|
HRESULT hres = m_symbol->get_locationType(&retValue);
|
||||||
|
if (S_OK != hres)
|
||||||
|
throw Exception("Call IDiaSymbol::get_locationType", hres);
|
||||||
|
|
||||||
|
return retValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
python::object Symbol::getValue()
|
||||||
|
{
|
||||||
|
throwIfNull(__FUNCTION__);
|
||||||
|
|
||||||
|
VARIANT variant = { VT_EMPTY };
|
||||||
|
HRESULT hres = m_symbol->get_value(&variant);
|
||||||
|
if (S_OK != hres)
|
||||||
|
throw Exception("Call IDiaSymbol::get_value", hres);
|
||||||
|
|
||||||
|
switch (variant.vt)
|
||||||
|
{
|
||||||
|
case VT_I1:
|
||||||
|
case VT_UI1:
|
||||||
|
return python::object( static_cast<ULONG>(variant.bVal) );
|
||||||
|
|
||||||
|
case VT_BOOL:
|
||||||
|
return python::object( static_cast<bool>(!!variant.iVal) );
|
||||||
|
|
||||||
|
case VT_I2:
|
||||||
|
case VT_UI2:
|
||||||
|
return python::object( static_cast<ULONG>(variant.iVal) );
|
||||||
|
|
||||||
|
case VT_I4:
|
||||||
|
case VT_UI4:
|
||||||
|
case VT_INT:
|
||||||
|
case VT_UINT:
|
||||||
|
case VT_ERROR:
|
||||||
|
case VT_HRESULT:
|
||||||
|
return python::object( variant.lVal );
|
||||||
|
|
||||||
|
case VT_I8:
|
||||||
|
case VT_UI8:
|
||||||
|
return python::object( variant.llVal );
|
||||||
|
|
||||||
|
case VT_R4:
|
||||||
|
return python::object( variant.fltVal );
|
||||||
|
|
||||||
|
case VT_R8:
|
||||||
|
return python::object( variant.dblVal );
|
||||||
|
|
||||||
|
case VT_BSTR:
|
||||||
|
return python::object( autoBstr::asStr(variant.bstrVal).c_str() );
|
||||||
|
|
||||||
|
}
|
||||||
|
throw Exception("Unknown value type");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
python::object Symbol::getChildByName(const std::string &_name)
|
python::object Symbol::getChildByName(const std::string &_name)
|
||||||
{
|
{
|
||||||
throwIfNull(__FUNCTION__);
|
throwIfNull(__FUNCTION__);
|
||||||
|
|
||||||
CComPtr< IDiaEnumSymbols > symbols;
|
DiaEnumSymbolsPtr symbols;
|
||||||
HRESULT hres =
|
HRESULT hres =
|
||||||
m_symbol->findChildren(
|
m_symbol->findChildren(
|
||||||
SymTagNull,
|
SymTagNull,
|
||||||
toOleStr(_name),
|
toWStr(_name),
|
||||||
nsCaseSensitive,
|
nsCaseSensitive,
|
||||||
&symbols);
|
&symbols);
|
||||||
if (FAILED(hres))
|
if (S_OK != hres)
|
||||||
throw Exception("Get child by name", hres);
|
throw Exception("Call IDiaSymbol::findChildren", hres);
|
||||||
|
|
||||||
LONG count;
|
LONG count;
|
||||||
hres = symbols->get_Count(&count);
|
hres = symbols->get_Count(&count);
|
||||||
if (FAILED(hres))
|
if (S_OK != hres)
|
||||||
throw Exception("Get count of children", hres);
|
throw Exception("Call IDiaEnumSymbols::get_Count", hres);
|
||||||
|
|
||||||
if (!count)
|
if (!count)
|
||||||
throw Exception(_name + " not found as children");
|
throw Exception(_name + " not found");
|
||||||
|
|
||||||
if (count != 1)
|
if (count != 1)
|
||||||
throw Exception(_name + " is not unique");
|
throw Exception(_name + " is not unique");
|
||||||
|
|
||||||
CComPtr< IDiaSymbol > child;
|
DiaSymbolPtr child;
|
||||||
hres = symbols->Item(0, &child);
|
hres = symbols->Item(0, &child);
|
||||||
if (FAILED(hres))
|
if (S_OK != hres)
|
||||||
throw Exception("Build child object", hres);
|
throw Exception("Call IDiaEnumSymbols::Item", hres);
|
||||||
|
|
||||||
return python::object( Symbol(child) );
|
return python::object( Symbol(child) );
|
||||||
}
|
}
|
||||||
@ -174,20 +309,20 @@ ULONG Symbol::getChildCount()
|
|||||||
{
|
{
|
||||||
throwIfNull(__FUNCTION__);
|
throwIfNull(__FUNCTION__);
|
||||||
|
|
||||||
CComPtr< IDiaEnumSymbols > symbols;
|
DiaEnumSymbolsPtr symbols;
|
||||||
HRESULT hres =
|
HRESULT hres =
|
||||||
m_symbol->findChildren(
|
m_symbol->findChildren(
|
||||||
SymTagNull,
|
SymTagNull,
|
||||||
NULL,
|
NULL,
|
||||||
nsCaseSensitive,
|
nsCaseSensitive,
|
||||||
&symbols);
|
&symbols);
|
||||||
if (FAILED(hres))
|
if (S_OK != hres)
|
||||||
throw Exception("Get child count", hres);
|
throw Exception("Call IDiaSymbol::findChildren", hres);
|
||||||
|
|
||||||
LONG count;
|
LONG count;
|
||||||
hres = symbols->get_Count(&count);
|
hres = symbols->get_Count(&count);
|
||||||
if (FAILED(hres))
|
if (S_OK != hres)
|
||||||
throw Exception("Get count of count", hres);
|
throw Exception("Call IDiaEnumSymbols::get_Count", hres);
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
@ -198,38 +333,135 @@ python::object Symbol::getChildByIndex(ULONG _index)
|
|||||||
{
|
{
|
||||||
throwIfNull(__FUNCTION__);
|
throwIfNull(__FUNCTION__);
|
||||||
|
|
||||||
CComPtr< IDiaEnumSymbols > symbols;
|
DiaEnumSymbolsPtr symbols;
|
||||||
HRESULT hres =
|
HRESULT hres =
|
||||||
m_symbol->findChildren(
|
m_symbol->findChildren(
|
||||||
SymTagNull,
|
SymTagNull,
|
||||||
NULL,
|
NULL,
|
||||||
nsCaseSensitive,
|
nsCaseSensitive,
|
||||||
&symbols);
|
&symbols);
|
||||||
if (FAILED(hres))
|
if (S_OK != hres)
|
||||||
throw Exception("Get child by index", hres);
|
throw Exception("Call IDiaSymbol::findChildren", hres);
|
||||||
|
|
||||||
LONG count;
|
LONG count;
|
||||||
hres = symbols->get_Count(&count);
|
hres = symbols->get_Count(&count);
|
||||||
if (FAILED(hres))
|
if (S_OK != hres)
|
||||||
throw Exception("Get count of children", hres);
|
throw Exception("Call IDiaEnumSymbols::get_Count", hres);
|
||||||
|
|
||||||
if (LONG(_index) >= count)
|
if (LONG(_index) >= count)
|
||||||
throw Exception("Attempt to access non-existing element: index overflow");
|
throw Exception("Attempt to access non-existing element by index");
|
||||||
|
|
||||||
CComPtr< IDiaSymbol > child;
|
DiaSymbolPtr child;
|
||||||
hres = symbols->Item(_index, &child);
|
hres = symbols->Item(_index, &child);
|
||||||
if (FAILED(hres))
|
if (S_OK != hres)
|
||||||
throw Exception("Build child object", hres);
|
throw Exception("Call IDiaEnumSymbols::Item", hres);
|
||||||
|
|
||||||
return python::object( Symbol(child) );
|
return python::object( Symbol(child) );
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
std::string Symbol::print()
|
||||||
|
{
|
||||||
|
std::stringstream sstream;
|
||||||
|
if (m_symbol)
|
||||||
|
{
|
||||||
|
DWORD dwValue;
|
||||||
|
autoBstr bstrValue;
|
||||||
|
VARIANT vtValue = { VT_EMPTY };
|
||||||
|
|
||||||
|
sstream << "symTag: ";
|
||||||
|
HRESULT hres = m_symbol->get_symTag(&dwValue);
|
||||||
|
if ((S_OK == hres) && dwValue < _countof(symTagName))
|
||||||
|
sstream << symTagName[dwValue];
|
||||||
|
else
|
||||||
|
sstream << "<unknown>";
|
||||||
|
sstream << ", ";
|
||||||
|
|
||||||
|
hres = m_symbol->get_name(&bstrValue);
|
||||||
|
if (S_OK == hres)
|
||||||
|
sstream << "\"" << bstrValue.asStr().c_str() << "\"";
|
||||||
|
else
|
||||||
|
sstream << "<no-name>";
|
||||||
|
bstrValue.free();
|
||||||
|
|
||||||
|
hres = m_symbol->get_locationType(&dwValue);
|
||||||
|
if ((S_OK == hres) && dwValue < _countof(locTypeName))
|
||||||
|
{
|
||||||
|
sstream << std::endl;
|
||||||
|
sstream << "Location: " << locTypeName[dwValue];
|
||||||
|
if (dwValue == LocIsStatic)
|
||||||
|
{
|
||||||
|
hres = m_symbol->get_relativeVirtualAddress(&dwValue);
|
||||||
|
if (S_OK == hres)
|
||||||
|
sstream << ", RVA: 0x" << std::hex << dwValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hres = m_symbol->get_value(&vtValue);
|
||||||
|
if (S_OK == hres)
|
||||||
|
{
|
||||||
|
switch (vtValue.vt)
|
||||||
|
{
|
||||||
|
case VT_I1:
|
||||||
|
case VT_UI1:
|
||||||
|
sstream << std::endl << "Value is ";
|
||||||
|
sstream << std::hex << "0x" << vtValue.bVal;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VT_BOOL:
|
||||||
|
sstream << std::endl << "Value is ";
|
||||||
|
sstream << vtValue.iVal ? "True" : "False";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VT_I2:
|
||||||
|
case VT_UI2:
|
||||||
|
sstream << std::endl << "Value is ";
|
||||||
|
sstream << std::hex << "0x" << vtValue.iVal;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VT_I4:
|
||||||
|
case VT_UI4:
|
||||||
|
case VT_INT:
|
||||||
|
case VT_UINT:
|
||||||
|
case VT_ERROR:
|
||||||
|
case VT_HRESULT:
|
||||||
|
sstream << std::endl << "Value is ";
|
||||||
|
sstream << std::hex << "0x" << vtValue.lVal;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VT_I8:
|
||||||
|
case VT_UI8:
|
||||||
|
sstream << std::endl << "Value is ";
|
||||||
|
sstream << std::hex << "0x" << vtValue.llVal;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VT_R4:
|
||||||
|
sstream << std::endl << "Value is ";
|
||||||
|
sstream << vtValue.fltVal;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VT_R8:
|
||||||
|
sstream << std::endl << "Value is ";
|
||||||
|
sstream << vtValue.dblVal;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VT_BSTR:
|
||||||
|
sstream << std::endl << "Value is ";
|
||||||
|
sstream << "\"" << autoBstr::asStr(vtValue.bstrVal).c_str() << "\"";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sstream.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
GlobalScope::GlobalScope(
|
GlobalScope::GlobalScope(
|
||||||
__inout CComPtr< IDiaDataSource > &_scope,
|
__inout DiaDataSourcePtr &_scope,
|
||||||
__inout CComPtr< IDiaSession > &_session,
|
__inout DiaSessionPtr &_session,
|
||||||
__inout CComPtr< IDiaSymbol > &_globalScope
|
__inout DiaSymbolPtr &_globalScope
|
||||||
) : Symbol(_globalScope)
|
) : Symbol(_globalScope)
|
||||||
, m_source( _scope.Detach() )
|
, m_source( _scope.Detach() )
|
||||||
, m_session( _session.Detach() )
|
, m_session( _session.Detach() )
|
||||||
@ -240,26 +472,26 @@ GlobalScope::GlobalScope(
|
|||||||
|
|
||||||
python::object GlobalScope::openPdb(const std::string &filePath)
|
python::object GlobalScope::openPdb(const std::string &filePath)
|
||||||
{
|
{
|
||||||
CComPtr< IDiaDataSource > _scope;
|
DiaDataSourcePtr _scope;
|
||||||
|
|
||||||
HRESULT hres =
|
HRESULT hres =
|
||||||
_scope.CoCreateInstance(__uuidof(DiaSource), NULL, CLSCTX_INPROC_SERVER);
|
_scope.CoCreateInstance(__uuidof(DiaSource), NULL, CLSCTX_INPROC_SERVER);
|
||||||
if ( FAILED(hres) )
|
if ( S_OK != hres )
|
||||||
throw Exception("Create scope instance", hres);
|
throw Exception("Call ::CoCreateInstance", hres);
|
||||||
|
|
||||||
hres = _scope->loadDataFromPdb( toOleStr(filePath) );
|
hres = _scope->loadDataFromPdb( toWStr(filePath) );
|
||||||
if ( FAILED(hres) )
|
if ( S_OK != hres )
|
||||||
throw Exception("Load pdb file", hres);
|
throw Exception("Call IDiaDataSource::loadDataFromPdb", hres);
|
||||||
|
|
||||||
CComPtr< IDiaSession > _session;
|
DiaSessionPtr _session;
|
||||||
hres = _scope->openSession(&_session);
|
hres = _scope->openSession(&_session);
|
||||||
if ( FAILED(hres) )
|
if ( S_OK != hres )
|
||||||
throw Exception("Open session for querying symbols", hres);
|
throw Exception("Call IDiaDataSource::openSession", hres);
|
||||||
|
|
||||||
CComPtr< IDiaSymbol > _globalScope;
|
DiaSymbolPtr _globalScope;
|
||||||
hres = _session->get_globalScope(&_globalScope);
|
hres = _session->get_globalScope(&_globalScope);
|
||||||
if ( FAILED(hres) )
|
if ( S_OK != hres )
|
||||||
throw Exception("Retrieves a reference to the global scope", hres);
|
throw Exception("Call IDiaSymbol::get_globalScope", hres);
|
||||||
|
|
||||||
return python::object(GlobalScope(_scope, _session, _globalScope));
|
return python::object(GlobalScope(_scope, _session, _globalScope));
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,16 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <cvconst.h>
|
||||||
#include "dbgexcept.h"
|
#include "dbgexcept.h"
|
||||||
|
|
||||||
namespace pyDia {
|
namespace pyDia {
|
||||||
|
|
||||||
|
typedef CComPtr< IDiaSymbol > DiaSymbolPtr;
|
||||||
|
typedef CComPtr< IDiaEnumSymbols > DiaEnumSymbolsPtr;
|
||||||
|
typedef CComPtr< IDiaDataSource > DiaDataSourcePtr;
|
||||||
|
typedef CComPtr< IDiaSession > DiaSessionPtr;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// DIA Exceptions
|
// DIA Exceptions
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -63,13 +70,18 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
ULONGLONG getSize();
|
ULONGLONG getSize();
|
||||||
|
std::string getName();
|
||||||
|
python::object getType();
|
||||||
ULONG getSymTag();
|
ULONG getSymTag();
|
||||||
|
ULONG getRva();
|
||||||
|
ULONG getLocType();
|
||||||
|
python::object getValue();
|
||||||
|
|
||||||
python::object getChildByName(const std::string &_name);
|
python::object getChildByName(const std::string &_name);
|
||||||
ULONG getChildCount();
|
ULONG getChildCount();
|
||||||
python::object getChildByIndex(ULONG _index);
|
python::object getChildByIndex(ULONG _index);
|
||||||
|
|
||||||
|
std::string print();
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
void throwIfNull(const char *desc)
|
void throwIfNull(const char *desc)
|
||||||
@ -78,11 +90,14 @@ protected:
|
|||||||
throw Exception(std::string(desc) + " failed, object not preinitialized");
|
throw Exception(std::string(desc) + " failed, object not preinitialized");
|
||||||
}
|
}
|
||||||
|
|
||||||
Symbol(__inout CComPtr< IDiaSymbol > &_symbol) {
|
Symbol(__inout DiaSymbolPtr &_symbol) {
|
||||||
m_symbol = _symbol.Detach();
|
m_symbol = _symbol.Detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
CComPtr< IDiaSymbol > m_symbol;
|
static const char *symTagName[SymTagMax];
|
||||||
|
static const char *locTypeName[LocTypeMax];
|
||||||
|
|
||||||
|
DiaSymbolPtr m_symbol;
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -98,13 +113,13 @@ public:
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
GlobalScope(
|
GlobalScope(
|
||||||
__inout CComPtr< IDiaDataSource > &_scope,
|
__inout DiaDataSourcePtr &_scope,
|
||||||
__inout CComPtr< IDiaSession > &_session,
|
__inout DiaSessionPtr &_session,
|
||||||
__inout CComPtr< IDiaSymbol > &_globalScope
|
__inout DiaSymbolPtr &_globalScope
|
||||||
);
|
);
|
||||||
|
|
||||||
CComPtr< IDiaDataSource > m_source;
|
DiaDataSourcePtr m_source;
|
||||||
CComPtr< IDiaSession > m_session;
|
DiaSessionPtr m_session;
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -439,6 +439,10 @@
|
|||||||
RelativePath=".\stdafx.h"
|
RelativePath=".\stdafx.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\utils.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
Name="Resource Files"
|
Name="Resource Files"
|
||||||
|
78
pykd/utils.h
Normal file
78
pykd/utils.h
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// std::string -> const WCHAR *
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
class toWStr {
|
||||||
|
public:
|
||||||
|
toWStr(const std::string &sz)
|
||||||
|
{
|
||||||
|
m_buf.resize( sz.size() + 1, L'\0' );
|
||||||
|
::MultiByteToWideChar( CP_ACP, 0, sz.c_str(), sz.size(), &m_buf[0], m_buf.size() );
|
||||||
|
}
|
||||||
|
|
||||||
|
operator const WCHAR *() const {
|
||||||
|
return m_buf.empty() ? NULL : &m_buf[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<WCHAR> m_buf;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// BSTR wrapper
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
class autoBstr {
|
||||||
|
public:
|
||||||
|
autoBstr() : m_bstr(NULL) {}
|
||||||
|
~autoBstr() {
|
||||||
|
free();
|
||||||
|
}
|
||||||
|
|
||||||
|
void free()
|
||||||
|
{
|
||||||
|
if (m_bstr)
|
||||||
|
{
|
||||||
|
SysFreeString(m_bstr);
|
||||||
|
m_bstr = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BSTR *operator &() {
|
||||||
|
return &m_bstr;
|
||||||
|
}
|
||||||
|
operator BSTR() const {
|
||||||
|
return m_bstr;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string asStr() const
|
||||||
|
{
|
||||||
|
return asStr(m_bstr);
|
||||||
|
}
|
||||||
|
static std::string asStr(BSTR bstr)
|
||||||
|
{
|
||||||
|
if (!bstr)
|
||||||
|
return "";
|
||||||
|
|
||||||
|
const int chars = static_cast<int>( wcslen(bstr) );
|
||||||
|
if (!chars)
|
||||||
|
return "";
|
||||||
|
|
||||||
|
std::string ret;
|
||||||
|
ret.resize(chars + 1, '\0');
|
||||||
|
::WideCharToMultiByte(
|
||||||
|
CP_ACP,
|
||||||
|
0,
|
||||||
|
bstr,
|
||||||
|
chars,
|
||||||
|
&ret[0],
|
||||||
|
ret.size(),
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
BSTR m_bstr;
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user