int Demarshal( int byte_order, const cMarshalType *type, void *d, const void *b ) { if ( IsSimpleType( type->m_type ) ) return DemarshalSimpleTypes( byte_order, type->m_type, d, b ); int size = 0; unsigned char *data = d; const unsigned char *buffer = b; switch( type->m_type ) { case eMtArray: { int i; for( i = 0; i < type->m_u.m_array.m_size; i++ ) { int s = Demarshal( byte_order, type->m_u.m_array.m_type, data, buffer ); if ( s < 0 ) return -1; data += s; buffer += s; size += s; } } break; case eMtStruct: { int i; for( i = 0; type->m_u.m_struct.m_elements[i].m_type == eMtStructElement; i++ ) { cMarshalType *struct_element = &type->m_u.m_struct.m_elements[i]; assert( struct_element->m_type == eMtStructElement ); cMarshalType *st_type = struct_element->m_u.m_struct_element.m_type; int s = 0; if ( st_type->m_type == eMtUnion ) { // the mod must be before this entry. // this is a limitation of demarshaling of unions assert( st_type->m_u.m_union.m_offset < i ); const cMarshalType *mod = FindUnionModifierType( type, st_type, data ); if ( mod ) { s = Demarshal( byte_order, mod, data + struct_element->m_u.m_struct_element.m_offset, buffer ); if ( s < 0 ) return -1; } else return -1; } else if ( st_type->m_type == eMtVarArray ) { // the array size must be before this entry. // this is a limitation of demarshaling of var arrays assert( st_type->m_u.m_var_array.m_size < i ); tUint32 array_size = FindArraySize( type, st_type, data ); // only simple types can be array elements assert( IsSimpleType( st_type->m_u.m_var_array.m_type->m_type ) ); const unsigned char *bb = buffer; unsigned char *dd = data + struct_element->m_u.m_struct_element.m_offset; tUint32 j; for( j = 0; j < array_size; j++ ) { int si = Demarshal( byte_order, st_type->m_u.m_var_array.m_type, dd, bb ); if ( si < 0 ) return -1; bb += si; dd += si; s += si; } } else { s = Demarshal( byte_order, st_type, data + struct_element->m_u.m_struct_element.m_offset, buffer ); if ( s < 0 ) return -1; } buffer += s; size += s; } } break; case eMtUnion: // unions must me encapsulate in structs assert( 0 ); return -1; case eMtStructElement: case eMtUnionElement: assert( 0 ); return -1; case eMtUserDefined: assert( type->m_u.m_user_defined.m_demarshal ); size = type->m_u.m_user_defined.m_demarshal( byte_order, type, d, b, type->m_u.m_user_defined. m_user_data ); if ( size < 0 ) return -1; break; default: assert( 0 ); return -1; } return size; }
int Demarshal( int byte_order, const cMarshalType *type, void *d, const void *b ) { if ( IsSimpleType( type->m_type ) ) return DemarshalSimpleTypes( byte_order, type->m_type, d, b ); int size = 0; unsigned char *data = d; const unsigned char *buffer = b; switch( type->m_type ) { case eMtArray: { int i; for( i = 0; i < type->m_u.m_array.m_size; i++ ) { int s = Demarshal( byte_order, type->m_u.m_array.m_type, data, buffer ); if ( s < 0 ) { assert( 0 ); return -1; } data += s; buffer += s; size += s; } } break; case eMtStruct: { int i; for( i = 0; type->m_u.m_struct.m_elements[i].m_type == eMtStructElement; i++ ) { cMarshalType *struct_element = &type->m_u.m_struct.m_elements[i]; assert( struct_element->m_type == eMtStructElement ); cMarshalType *st_type = struct_element->m_u.m_struct_element.m_type; int s = 0; if ( st_type->m_type == eMtUnion ) { // the mod must be before this entry. // this is a limitation of demarshaling of unions assert( st_type->m_u.m_union.m_offset < i ); const cMarshalType *mod = FindUnionModifierType( type, st_type, data ); if ( mod ) { s = Demarshal( byte_order, mod, data + struct_element->m_u.m_struct_element.m_offset, buffer ); if ( s < 0 ) { assert( 0 ); return -1; } } else { assert( 0 ); return -1; } } else if ( st_type->m_type == eMtVarArray ) { // the array size must be before this entry. // this is a limitation of demarshaling of var arrays assert( st_type->m_u.m_var_array.m_size < i ); tUint32 array_size = FindArraySize( type, st_type, data ); // only simple types can be array elements //assert( IsSimpleType( st_type->m_u.m_var_array.m_type->m_type ) ); const unsigned char *bb = buffer; const cMarshalType *va_type = st_type->m_u.m_var_array.m_type; // FIXME: This is a hack! I'm assuming the elements in // the variable array are structs. That's because this // is the only instance for which we use var arrays. unsigned char *dd = (unsigned char *)malloc(va_type->m_u.m_struct.m_size*array_size); memset(dd, 0, va_type->m_u.m_struct.m_size*array_size); unsigned char *vardata = data + struct_element->m_u.m_struct_element.m_offset; tUint32 j; memcpy(vardata, &dd, sizeof(void *)); for( j = 0; j < array_size; j++ ) { int si = Demarshal( byte_order, st_type->m_u.m_var_array.m_type, dd, bb ); if ( si < 0 ) { assert( 0 ); return -1; } bb += si; dd += si; s += si; } } else { s = Demarshal( byte_order, st_type, data + struct_element->m_u.m_struct_element.m_offset, buffer ); if ( s < 0 ) { assert( 0 ); return -1; } } buffer += s; size += s; } } break; case eMtUnion: // unions must me encapsulate in structs assert( 0 ); return -1; case eMtStructElement: case eMtUnionElement: assert( 0 ); return -1; case eMtUserDefined: assert( type->m_u.m_user_defined.m_demarshal ); size = type->m_u.m_user_defined.m_demarshal( byte_order, type, d, b, type->m_u.m_user_defined. m_user_data ); if ( size < 0 ) { assert( 0 ); return -1; } break; default: assert( 0 ); return -1; } return size; }
int Marshal( const cMarshalType *type, const void *d, void *b ) { if ( IsSimpleType( type->m_type ) ) return MarshalSimpleTypes( type->m_type, d, b ); int size = 0; const unsigned char *data = d; unsigned char *buffer = b; switch( type->m_type ) { case eMtArray: { int i; //assert( IsSimpleType( type->m_u.m_array.m_type->m_type ) ); for( i = 0; i < type->m_u.m_array.m_size; i++ ) { int s = Marshal( type->m_u.m_array.m_type, data, buffer ); if ( s < 0 ) { assert( 0 ); return -1; } data += s; buffer += s; size += s; } } break; case eMtStruct: { int i; for( i = 0; type->m_u.m_struct.m_elements[i].m_type == eMtStructElement; i++ ) { cMarshalType *struct_element = &type->m_u.m_struct.m_elements[i]; assert( struct_element->m_type == eMtStructElement ); cMarshalType *st_type = struct_element->m_u.m_struct_element.m_type; int s = 0; if ( st_type->m_type == eMtUnion ) { // the mod must be before this entry. // this is a limitation of demarshaling of unions assert( st_type->m_u.m_union.m_offset < i ); const cMarshalType *mod = FindUnionModifierType( type, st_type, data ); if ( mod ) { s = Marshal( mod, data + struct_element->m_u.m_struct_element.m_offset, buffer ); if ( s < 0 ) { assert( 0 ); return -1; } } else { assert( 0 ); return -1; } } else if ( st_type->m_type == eMtVarArray ) { // the array size must be before this entry. // this is a limitation of demarshaling of var arrays assert( st_type->m_u.m_var_array.m_size < i ); int array_size = FindArraySize( type, st_type, data ); // only simple types can be array elements //assert( IsSimpleType( st_type->m_u.m_var_array.m_type->m_type ) ); unsigned char *bb = buffer; const unsigned char *vardata = data + struct_element->m_u.m_struct_element.m_offset; const unsigned char *dd; tUint32 j; memcpy(&dd, vardata, sizeof(void *)); for( j = 0; j < array_size; j++ ) { int si = Marshal( st_type->m_u.m_var_array.m_type, dd, bb ); if ( si < 0 ) { assert( 0 ); return -1; } bb += si; dd += si; s += si; } } else { s = Marshal( st_type, data + struct_element->m_u.m_struct_element.m_offset, buffer ); if ( s < 0 ) { assert( 0 ); return -1; } } buffer += s; size += s; } } break; case eMtUnion: assert( 0 ); return -1; case eMtUserDefined: assert( type->m_u.m_user_defined.m_marshal ); size = type->m_u.m_user_defined.m_marshal( type, d, b, type->m_u.m_user_defined.m_user_data ); break; default: assert( 0 ); return -1; } return size; }
//获取数据成员的信息 //如果成员是数据成员,返回TRUE //否则返回FALSE BOOL GetDataMemberInfo(DWORD memberID, DWORD modBase, DWORD address, const BYTE* pData, std::wostringstream& valueBuilder) { DWORD memberTag; SymGetTypeInfo( GetDebuggeeHandle(), modBase, memberID, TI_GET_SYMTAG, &memberTag); if (memberTag != SymTagData && memberTag != SymTagBaseClass) { return FALSE; } valueBuilder << TEXT(" "); DWORD memberTypeID; SymGetTypeInfo( GetDebuggeeHandle(), modBase, memberID, TI_GET_TYPEID, &memberTypeID); //输出类型 valueBuilder << GetTypeName(memberTypeID, modBase); //输出名称 if (memberTag == SymTagData) { WCHAR* name; SymGetTypeInfo( GetDebuggeeHandle(), modBase, memberID, TI_GET_SYMNAME, &name); valueBuilder << TEXT(" ") << name; LocalFree(name); } else { valueBuilder << TEXT(" <base-class>"); } //输出长度 ULONG64 length; SymGetTypeInfo( GetDebuggeeHandle(), modBase, memberTypeID, TI_GET_LENGTH, &length); valueBuilder << TEXT(" ") << length; //输出地址 DWORD offset; SymGetTypeInfo( GetDebuggeeHandle(), modBase, memberID, TI_GET_OFFSET, &offset); DWORD childAddress = address + offset; valueBuilder << TEXT(" ") << std::hex << std::uppercase << std::setfill(TEXT('0')) << std::setw(8) << childAddress << std::dec; //输出值 if (IsSimpleType(memberTypeID, modBase) == TRUE) { valueBuilder << TEXT(" ") << GetTypeValue( memberTypeID, modBase, childAddress, pData + offset); } return TRUE; }
int Demarshal( int byte_order, const cMarshalType *type, void *d, const void *b ) { if ( IsSimpleType( type->m_type ) ) { return DemarshalSimpleTypes( byte_order, type->m_type, d, b ); } int size = 0; unsigned char *data = d; const unsigned char *buffer = b; switch( type->m_type ) { case eMtArray: { const size_t nelems = type->u.m_array.m_nelements; size_t i; for( i = 0; i < nelems; i++ ) { const cMarshalType *elem = type->u.m_array.m_element; const size_t elem_sizeof = type->u.m_array.m_element_sizeof; int cc = Demarshal( byte_order, elem, data, buffer ); if ( cc < 0 ) { CRIT( "Demarshal: %s[%d]: failure, cc = %d!", type->m_name, i, cc ); return cc; } data += elem_sizeof; buffer += cc; size += cc; } } break; case eMtStruct: { const cMarshalType *elems = &type->u.m_struct.m_elements[0]; size_t i; for( i = 0; elems[i].m_type == eMtStructElement; i++ ) { const cMarshalType *elem = elems[i].u.m_struct_element.m_element; const size_t offset = elems[i].u.m_struct_element.m_offset; int cc = 0; if ( elem->m_type == eMtUnion ) { const size_t mod2_idx = elem->u.m_union.m_mod_idx; if ( mod2_idx >= i ) { // NB: this is a limitation of demarshaling of unions CRIT( "Demarshal: %s:%s: mod field must be before union!", type->m_name, elems[i].m_name ); return -EINVAL; } const size_t mod2 = GetStructElementIntegerValue( type, mod2_idx, data ); const cMarshalType *elem2 = GetUnionElement( elem, mod2 ); if ( !elem2 ) { CRIT( "Demarshal: %s:%s: invalid mod value %u!", type->m_name, elems[i].m_name, (unsigned int)mod2 ); return -EINVAL; } cc = Demarshal( byte_order, elem2, data + offset, buffer ); if ( cc < 0 ) { CRIT( "Demarshal: %s:%s, mod %u: failure, cc = %d!", type->m_name, elems[i].m_name, (unsigned int)mod2, cc ); return cc; } } else if ( elem->m_type == eMtVarArray ) { const size_t nelems2_idx = elem->u.m_var_array.m_nelements_idx; const cMarshalType *elem2 = elem->u.m_var_array.m_element; const size_t elem2_sizeof = elem->u.m_var_array.m_element_sizeof; if ( nelems2_idx >= i ) { // NB: this is a limitation of demarshaling of var arrays CRIT( "Demarshal: %s:%s: nelements field must be before vararray!", type->m_name, elems[i].m_name ); return -EINVAL; } const size_t nelems2 = GetStructElementIntegerValue( type, nelems2_idx, data ); // allocate storage for var array content unsigned char *data2 = g_new0(unsigned char, nelems2 * elem2_sizeof ); // (data + offset ) points to pointer to var array content memcpy(data + offset, &data2, sizeof(void *)); const unsigned char *buffer2 = buffer; size_t i2; for( i2 = 0; i2 < nelems2; i2++ ) { int cc2 = Demarshal( byte_order, elem2, data2, buffer2 ); if ( cc2 < 0 ) { CRIT( "Demarshal: %s:%s[%d]: failure, cc = %d!", type->m_name, elems[i].m_name, i2, cc2 ); return cc2; } data2 += elem2_sizeof; buffer2 += cc2; cc += cc2; } } else { cc = Demarshal( byte_order, elem, data + offset, buffer ); if ( cc < 0 ) { CRIT( "Demarshal: %s:%s: failure, cc = %d!", type->m_name, elems[i].m_name, cc ); return cc; } } buffer += cc; size += cc; } } break; case eMtUserDefined: { tDemarshalFunction demarshaller = type->u.m_user_defined.m_demarshaller; void * user_data = type->u.m_user_defined.m_user_data; size = demarshaller ? demarshaller( byte_order, type, d, b, user_data ) : 0; } break; default: return -ENOSYS; }
int Marshal( const cMarshalType *type, const void *d, void *b ) { if ( IsSimpleType( type->m_type ) ) { return MarshalSimpleType( type->m_type, d, b ); } int size = 0; const unsigned char *data = d; unsigned char *buffer = b; switch( type->m_type ) { case eMtArray: { const size_t nelems = type->u.m_array.m_nelements; size_t i; for( i = 0; i < nelems; i++ ) { const cMarshalType *elem = type->u.m_array.m_element; const size_t elem_sizeof = type->u.m_array.m_element_sizeof; int cc = Marshal( elem, data, buffer ); if ( cc < 0 ) { CRIT( "Marshal: %s[%d]: failure, cc = %d!", type->m_name, i, cc ); return cc; } data += elem_sizeof; buffer += cc; size += cc; } } break; case eMtStruct: { const cMarshalType *elems = &type->u.m_struct.m_elements[0]; size_t i; for( i = 0; elems[i].m_type == eMtStructElement; i++ ) { const cMarshalType *elem = elems[i].u.m_struct_element.m_element; const size_t offset = elems[i].u.m_struct_element.m_offset; int cc = 0; if ( elem->m_type == eMtUnion ) { const size_t mod2_idx = elem->u.m_union.m_mod_idx; const size_t mod2 = GetStructElementIntegerValue( type, mod2_idx, data ); const cMarshalType *elem2 = GetUnionElement( elem, mod2 ); if ( !elem2 ) { CRIT( "Marshal: %s:%s: invalid mod value %u!", type->m_name, elems[i].m_name, (unsigned int)mod2 ); return -EINVAL; } cc = Marshal( elem2, data + offset, buffer ); if ( cc < 0 ) { CRIT( "Marshal: %s:%s, mod %u: failure, cc = %d!", type->m_name, elems[i].m_name, (unsigned int)mod2, cc ); return -EINVAL; } } else if ( elem->m_type == eMtVarArray ) { const size_t nelems2_idx = elem->u.m_var_array.m_nelements_idx; const cMarshalType *elem2 = elem->u.m_var_array.m_element; const size_t elem2_sizeof = elem->u.m_var_array.m_element_sizeof; const size_t nelems2 = GetStructElementIntegerValue( type, nelems2_idx, data ); // (data + offset ) points to pointer to var array content const unsigned char *data2; memcpy(&data2, data + offset, sizeof(void *)); unsigned char *buffer2 = buffer; size_t i2; for( i2 = 0; i2 < nelems2; i2++ ) { int cc2 = Marshal( elem2, data2, buffer2 ); if ( cc2 < 0 ) { CRIT( "Marshal: %s:%s[%d]: failure, cc = %d!", type->m_name, elems[i].m_name, i2, cc2 ); return cc2; } data2 += elem2_sizeof; buffer2 += cc2; cc += cc2; } } else { cc = Marshal( elem, data + offset, buffer ); if ( cc < 0 ) { CRIT( "Marshal: %s:%s: failure, cc = %d!", type->m_name, elems[i].m_name, cc ); return cc; } } buffer += cc; size += cc; } } break; case eMtUserDefined: { tMarshalFunction marshaller = type->u.m_user_defined.m_marshaller; void * user_data = type->u.m_user_defined.m_user_data; size = marshaller ? marshaller( type, d, b, user_data ) : 0; } break; default: return -ENOSYS; } return size; }