variant set_group(variant s) { if(variant_is_string(s)) { return variant_from_error("Invalid debug group"); } _SET_DEBUG_GROUP(variant_as_string(s)); return VARIANT_EMPTY(); }
HRESULT WINAPI DISPPARAMS_Eval( DWORD addr, DEBUGHELPER *pH, int nBase, BOOL bUniStrings, char *pResult, size_t maxlen, DWORD reserved ) { DISPPARAMS dparam; DWORDLONG llAddr =GetAddress(pH,addr); if(!ReadMem(pH, llAddr, &dparam) ) return E_FAIL; std::ostringstream os; if( dparam.cArgs == 0 ) { os << "()"; } else if( dparam.cArgs > 20) { os << "(.." << dparam.cArgs << "..)"; } else { VARIANT *vars= new VARIANT[dparam.cArgs]; try { if(!ReadMem(pH, reinterpret_cast<DWORDLONG>( dparam.rgvarg ) , sizeof(VARIANT) * dparam.cArgs, vars ) ) { delete [] vars; return E_FAIL; } bool first = true; os << '('; for( long i = dparam.cArgs-1; i>= 0 ; --i) { std::string ret; if(! variant_as_string(pH, vars[i], &ret) ) { delete [] vars; return false; } if(!first) os << ',' ; first = false; os << ret; } os << ')'; } catch (...){} delete [] vars; } strncpy(pResult, os.str().c_str(), maxlen); pResult[maxlen-1] ='\0'; return S_OK; }
HRESULT WINAPI VARIANT_Eval( DWORD addr, DEBUGHELPER *pH, int nBase, BOOL bUniStrings, char *pResult, size_t maxlen, DWORD reserved ) { VARIANT var; DWORDLONG llAddr =GetAddress(pH,addr); if(!ReadMem(pH, llAddr, &var) ) return E_FAIL; std::string res; if(! variant_as_string(pH, var, &res ) ) return E_FAIL; std::ostringstream os; if(( var.vt & VT_ARRAY ) ==0) // arrays have their own type display. os << vt_as_string(var.vt) << ' '; os << res; strncpy(pResult, os.str().c_str(), maxlen); pResult[maxlen-1] ='\0'; return S_OK; }
bool safearray_as_string(DEBUGHELPER *pH, DWORDLONG llAddr, std::string *ret ) { SAFEARRAY sa; if(!ReadMem(pH, llAddr, &sa) ) return false; std::ostringstream os; VARTYPE vt = VT_UNKNOWN; std::string iid_desc; if(sa.fFeatures & FADF_AUTO) os << "auto "; if(sa.fFeatures & FADF_STATIC) os << "static "; if(sa.fFeatures & FADF_EMBEDDED) os << "embed "; if(sa.fFeatures & FADF_FIXEDSIZE) os << "const "; if(sa.fFeatures & FADF_BSTR) vt = VT_BSTR; if(sa.fFeatures & FADF_UNKNOWN) vt = VT_UNKNOWN; if(sa.fFeatures & FADF_DISPATCH) vt = VT_DISPATCH; if(sa.fFeatures & FADF_VARIANT) vt = VT_VARIANT; if(sa.fFeatures & FADF_RECORD) vt = VT_RECORD; if(sa.fFeatures & FADF_HAVEIID) { IID iid; if(!ReadMem(pH, llAddr-16, &iid) ) return false; iid_desc = get_desc_of(iid); } if(sa.fFeatures & FADF_HAVEVARTYPE) { if(!ReadMem(pH, llAddr-4, &vt) ) return false; } os << desc_from_vartype( vt, iid_desc); SAFEARRAYBOUND *rgsabound = new SAFEARRAYBOUND[ sa.cDims ]; if(!ReadMem( pH, llAddr + offsetof(SAFEARRAY, rgsabound), sizeof(SAFEARRAYBOUND) * sa.cDims, rgsabound ) ) { delete [] rgsabound; return false; } for( USHORT d = 0 ; d < sa.cDims; ++d) { SAFEARRAYBOUND &bound=rgsabound[d]; if( bound.lLbound > 0 ) os << '[' << bound.lLbound << ".." << (bound.lLbound + bound.cElements) << ']'; else os << '[' << bound.cElements << ']'; } delete [] rgsabound; long elements = sa.rgsabound[0].cElements; if( sa.pvData != 0 && sa.cDims == 1 && elements <= 20) { long len = vartype_len(vt); if(len > 0) { VARIANT var; void *dest; if( vt == VT_VARIANT) { dest = &var; } else { var.vt=vt; dest = &(var.bVal); } long source=reinterpret_cast<long>(sa.pvData); os << "={"; for(long i=0; i< elements; ++i) { if( i>0) os << ','; if(!ReadMem( pH, source+(i*len), len ,dest ) ) return false; std::string varstr; if( ! variant_as_string( pH, var,&varstr ) ) return false; os << varstr; } os << "}"; } } *ret = os.str(); return true; }
bool variant_as_string( DEBUGHELPER *pH, const VARIANT &var, std::string *ret ) { if (var.vt & VT_VECTOR) return false; if (var.vt & VT_RESERVED) return false; if (var.vt & VT_ARRAY) return safearray_as_string( pH, reinterpret_cast<DWORDLONG>(var.parray), ret); if (var.vt & VT_BYREF) { // Construct a fake variant with the byref-value in it. VARTYPE vt = var.vt & ~VT_BYREF; long size = vartype_len(vt); VARIANT var2; var2.vt = vt; long source=reinterpret_cast<long>(var.byref); void *dest; if( vt == VT_VARIANT) dest = &var2; else { var2.vt=vt; dest = &(var2.bVal); } if(!ReadMem(pH,source, size, dest)) return false; std::string retval; if( ! variant_as_string( pH, var2, &retval)) return false; retval += "]"; *ret = "[" + retval; return true; } std::ostringstream os; switch (var.vt & VT_TYPEMASK ) { case VT_I2: os << V_I2(&var); break; case VT_I4: os << V_I4(&var); break; //case VT_I8: os << V_I8(&var); break; case VT_R4: os << V_R4(&var); break; case VT_R8: os << V_R8(&var); break; case VT_UNKNOWN: case VT_DISPATCH: os << "0x" << std::hex << (long )V_DISPATCH(&var); break; case VT_BOOL: os << (V_BOOL(&var)==VARIANT_FALSE?"False":"True"); break; case VT_I1: os << "'" << V_I1(&var) << "'" ; break; case VT_UI1: os << "'" << V_UI1(&var) << "'" ; break; case VT_UI2: os << V_UI2(&var); break; case VT_UI4: os << V_UI4(&var); break; case VT_INT: os << V_INT(&var); break; case VT_UINT: os << V_UINT(&var); break; case VT_ERROR: os << "error"; break; case VT_CY: os << (((double)(V_CY(&var).int64))/10000.); break; case VT_DATE: return date_as_string(V_DATE(&var), ret); break; case VT_BSTR: { long pBSTR = reinterpret_cast<long>( V_BSTR(&var) ); // if (!ReadMem(pH, reinterpret_cast<DWORDLONG>( V_BSTR(&var) ), &pBSTR)) return false; std::string ret; if (!bstr_as_string( pH, pBSTR , &ret )) return false; os << ret; }break; case VT_EMPTY: os << '@'; break; case VT_NULL: os << "null"; break; break; default: return false; } *ret = os.str(); return true; }