uint /* 521*/ ShowStruct(DFILE *dfp,uint row,uint rows,uint skip) /* -> dfile node containing stucture.*/ /* screen row. */ /* rows available for display. */ /* # of logical data recs to skip. */ { /* */ uint item; /* */ uint rr; /* */ uint n; /* */ TD_STRUCT *tp; /* 813*/ TD_TYPELIST *typelist; /* 813*/ Trec *namelist; /* */ uint Nitems; /* */ uint mid; /* */ uint sfx; /* */ uchar *cp; /* */ uint baseaddr; /* 112*/ uchar buffer[2*DATALINESPAN]; /* */ uint memberoffs; /* offset of member within structure.*/ uint membertype; /* type of the structure member. */ USHORT MaxLen; /* length of max structure name813529*/ /* */ mid = dfp->mid; /* */ sfx = dfp->sfx; /* */ baseaddr = dfp->baseaddr; /* */ /*****************************************************************************/ /* The first thing we want to do is get a pointer to the base type record. */ /* If the showtype is <= 512, indicating a primitive type, then we will */ /* get a back a NULL. */ /*****************************************************************************/ tp = (TD_STRUCT*)QbasetypeRec(mid, dfp->showtype); /* 813*/ if(!tp || /* cutting through the typedefs. */ tp->RecType != T_STRUCT /* */ ) /* cutting through the typedefs. */ return(FALSE); /*****************************************************************************/ /* Now, we are going to get the number of structure members and quit if we */ /* were told to skip more than the number of structure members. */ /*****************************************************************************/ Nitems = tp->NumMembers; /* 813*/ if( Nitems <= skip ) return(FALSE); /*****************************************************************************/ /* Now, get pointers to the type list and the name list. */ /*****************************************************************************/ typelist = (TD_TYPELIST*)QtypeRec(mid, tp->TypeListIndex); /*813*/ namelist = QtypeRec(mid, tp->NameListIndex); /*813*/ /* */ if( skip ) /* */ dfp = NULL; /* */ /* */ for( rr=0, item=skip+1; /* 813*/ (rr < rows) && /* */ (item <= Nitems); /* */ ++rr, ++item /* */ ) /* */ { /* */ cp = (UCHAR *)QNameList(namelist,NAME,item-1); /* find a member name. 813*/ if(!cp) /* if there is no name then go home. */ break; /* */ /* */ InitDataBuffer( buffer, /* initialize the data buffer, i.e. */ DATALINESPAN, /* clear it, put expression name in */ dfp /* it, put attributes in it, and . */ ); /* and terminate it with \0. */ dfp = NULL; /* kill dfp so we won't write the */ /* expression name again. */ MaxLen = *(USHORT*)cp; /* length of structure name 813529*/ MaxLen = /* limit the length of the name 529*/ (MaxLen < (TAB2-2)) ? MaxLen : (TAB2-2); /* till TAB2 position 529*/ n = sprintf( buffer + STGCOL+1, /* put the member name in the buffer.*/ "%.*s: ", /* 521*/ MaxLen, /* 529*/ cp+sizeof(USHORT) /* 813*/ ); /* */ /* */ /* compute the offset of this member */ /* within the data structure. */ memberoffs = QNameList(namelist,MEMBEROFFSET,item-1); /*813*/ /* find the type of this member. */ membertype = typelist->TypeIndex[item-1]; /*813112*/ /* */ /* */ *(buffer + STGCOL+1 + n) = ' '; /* remove null inserted by buffmt */ /* */ if ( n <= TAB1 ) n = TAB1; /* move to a tab position based */ else n = TAB2; /* on length of member name */ /* */ /* */ /* now format this item in the buffer*/ FormatDataItem( buffer + STGCOL+1 + n,/* starting position for the data. */ baseaddr + memberoffs,/* address of the member to format. */ mid, /* mid containing the data. */ membertype, /* type of the member. */ sfx /* stack frame index if there is one*/ ); /* */ /* */ buffer[ DATALINESPAN-1 ] = 0; /* terminate the data buffer...again.*/ putrc( row + rr, 0, buffer ); /* now display the data line. */ } /* */ /* */ if( rr < rows ) /* now clear the remaining rows. */ ClrScr( row + rr, /* */ row + rows - 1, /* */ vaStgExp /* */ ); /* */ return( TRUE ); /* */ } /* */
// // hwndGV - handle to GridView control // hRoot - root item-handle // type - node in the type-chain // dwOffset - current offset // // returns: size of type // size_w RecurseType(HWND hwndGV, HGRIDITEM hRoot, Type *type, size_w dwOffset, TypeDecl *typeDecl) { GVITEM gvitem = { 0 }; Structure *sptr; size_t i; TCHAR buf[200]; if(type == 0) return 0; size_w dwLength = 0; INUMTYPE switchVal = 0;//1; HWND hwndHV = GetActiveHexView(g_hwndMain); switch(type->ty) { case typeDOSTIME: case typeDOSDATE: case typeFILETIME: case typeTIMET: dwLength = FmtData(hwndGV, hRoot, type, dwOffset, typeDecl); break; case typeCHAR: case typeWCHAR: case typeBYTE: case typeWORD: case typeDWORD: case typeQWORD: case typeFLOAT: case typeDOUBLE: case typeENUM: dwLength = FmtData(hwndGV, hRoot, type, dwOffset, typeDecl); break; case typeUNION: // evaluate the switch_is() ExprNode *switchExpr; if(FindTag(typeDecl->tagList, TOK_SWITCHIS, &switchExpr)) { switchVal = Evaluate(switchExpr); } sptr = type->sptr; for(i = 0; i < sptr->typeDeclList.size(); i++) { TypeDecl *typeDecl = sptr->typeDeclList[i]; ExprNode *caseExpr; size_w tmpLen = 0; if(FindTag(typeDecl->tagList, TOK_CASE, &caseExpr)) { if(Evaluate(caseExpr) == switchVal) tmpLen = InsertTypeGV(hwndGV, hRoot, typeDecl, dwOffset); } else { tmpLen = InsertTypeGV(hwndGV, hRoot, typeDecl, dwOffset); } dwLength = max(dwLength, tmpLen); } break; case typeSTRUCT: sptr = type->sptr; for(i = 0; i < sptr->typeDeclList.size(); i++) { TypeDecl *typeDecl = sptr->typeDeclList[i]; dwLength += InsertTypeGV(hwndGV, hRoot, typeDecl, dwOffset + dwLength); } break; case typeIDENTIFIER: hRoot = InsertIdentifier(hwndGV, hRoot, type, dwOffset, typeDecl); dwLength = RecurseType(hwndGV, hRoot, type->link, dwOffset, typeDecl); break; #if 0 if(fShowFullType) { RenderType(buf, 200, type); gvitem.pszText = buf; } else { _stprintf(buf, TEXT("%hs"), type->sym->name); gvitem.pszText = buf;//type->sym->name; } gvitem.state = 0; if(type->link && type->link->ty != typeARRAY) gvitem.state |= GVIS_EXPANDED; gvitem.iImage = IsStruct(type) ? 1 : 0; if(typeDecl->tagList) gvitem.iImage+=2; gvitem.param = (ULONG_PTR)type;//typeDecl; gvitem.mask = GVIF_PARAM | GVIF_TEXT | GVIF_STATE | GVIF_IMAGE; GridView2_SetItem(hwndGV, hRoot, &gvitem); if(type->link && type->link->ty == typeARRAY) { FormatDataItem(hwndGV, hRoot, type, dwOffset); } if(IsStruct(type)) { gvitem.iSubItem = COLIDX_DATA; gvitem.state = GVIS_READONLY; gvitem.pszText = TEXT("{...}"); gvitem.param = 0; gvitem.mask = GVIF_PARAM | GVIF_TEXT | GVIF_STATE; GridView2_SetItem(hwndGV, hRoot, &gvitem); } if(!fShowFullType) { RenderType(buf, 200, type->link); //_stprintf(buf, TEXT("%hs"), type->sym->name); gvitem.iSubItem = 0;//COLIDX_TYPE; gvitem.state = GVIS_READONLY; gvitem.pszText = buf; gvitem.param = (UINT64)type; gvitem.mask = GVIF_PARAM | GVIF_TEXT | GVIF_STATE; GridView2_SetItem(hwndGV, hRoot, &gvitem); } dwLength = RecurseType(hwndGV, hRoot, type->link, dwOffset, typeDecl); break; #endif case typeTYPEDEF: case typeSIGNED: case typeUNSIGNED: case typeCONST: // return 0; case typePOINTER: dwLength = RecurseType(hwndGV, hRoot, type->link, dwOffset, typeDecl); break; case typeARRAY: Symbol *sym; ExprNode *nameExpr; if(FindTag(typeDecl->tagList, TOK_NAME, &nameExpr)) { if((sym = LookupSymbol(globalTagSymbolList, nameExpr->str)) != 0) { if(sym->type && sym->type->ty == typeENUM) ; else sym = 0; } } else { sym = 0; } UINT64 count; count = 0; Evaluate(GridView_GetParent(hwndGV, hRoot), type->elements, &count, dwOffset, hwndHV, hwndGV); count &= 0xffff; count = min(count,100); for(i = 0; i < count; i++) { HGRIDITEM hItem; TCHAR buf[164]; int len = _stprintf(buf, TEXT("[%d] "), (int)i); if(sym) { Enum *eptr = sym->type->eptr; char *s = 0; for(size_t x = 0; x < eptr->fieldList.size(); x++) { if(i == eptr->fieldList[x]->val) { s = eptr->fieldList[i]->name->name; } } _stprintf(buf + 5, TEXT("- %hs"), s); } gvitem.pszText = buf; gvitem.state = GVIS_READONLY; gvitem.iImage = 0;//rand() % 2; gvitem.param = (ULONG_PTR)type->link; gvitem.iSubItem = COLIDX_NAME; gvitem.mask = GVIF_STATE|GVIF_PARAM|GVIF_TEXT; hItem = GridView2_InsertUniqueChild(hwndGV, hRoot, &gvitem); // used to pass '0' as typeDecl??? why?? because this is an array element we // are recursing through!!!! dwLength += RecurseType(hwndGV, hItem, type->link, dwOffset + dwLength, 0);//typeDecl); } break; default: break; } // add the 'offset' column to all items if(hRoot) { _stprintf(buf, TEXT("%08x"), (DWORD)dwOffset); gvitem.pszText = buf; gvitem.iSubItem = COLIDX_OFFSET; gvitem.state = 0; gvitem.param = dwOffset; gvitem.mask = GVIF_TEXT | GVIF_STATE | GVIF_PARAM; GridView2_SetItem(hwndGV, hRoot, &gvitem); // add the 'comment' column item - only do this for items that aren't array elements if(typeDecl)// && type->ty != typeARRAY) { FILEREF *ref; ref = &typeDecl->postRef; buf[0] = '\0'; FormatWhitespace(ref, buf); gvitem.pszText = buf; gvitem.iSubItem = COLIDX_COMMENT; gvitem.state = 0; gvitem.mask = GVIF_TEXT | GVIF_STATE; GridView2_SetItem(hwndGV, hRoot, &gvitem); } } return dwLength; }
uint /* 521*/ ShowArray( DFILE *dfp, uint row, uint rows, uint skip ) /*112*/ { /**12*/ TD_ARRAY *tp; /* 813*/ uint item; /* array item to display. 112*/ uint rr; /* 112*/ uint n; /* gp integer. 112*/ uint Nitems; /* number of array items. 112*/ uint atomtype; /* type of array items. 112*/ uint atomsize; /* size of an array item. 112*/ uint mid; /* module id for the array var. 112*/ uint sfx; /* stack frame index if auto. 112*/ uint baseaddr; /* user addr where array starts. 112*/ uchar buffer[2*DATALINESPAN]; /* display buffer for array item. 112*/ uchar *cp; /* gp char ptr. 112*/ uint addr; /* gp address. 112*/ /*112*/ mid = dfp->mid; /*112*/ sfx = dfp->sfx; /*112*/ baseaddr = dfp->baseaddr; /*112*/ /*112*/ /****************************************************************************/ /* - get a ptr to the defining type record in $$type seg. 112*/ /* - get the atomic type of the array elements. 112*/ /* - get the size of the atomic type. 112*/ /* - get the number of array items. 112*/ /* - handle any errors in the above steps by simply returning false. 112*/ /* 112*/ /****************************************************************************/ tp = (TD_ARRAY*)QbasetypeRec(mid, dfp->showtype); /*813112*/ if( ( tp == NULL ) || ( tp->RecType != T_ARRAY ) ) /*813112*/ return( FALSE ); /*112*/ /*112*/ atomtype = tp->ElemType; /*813112*/ atomtype = HandleUserDefs(mid,atomtype); /*813*/ /*512*/ if( atomtype == 0 ) /*112*/ return( FALSE ); /*112*/ /*112*/ atomsize = QtypeSize(mid, atomtype); /*112*/ if( atomsize == 0 ) /*112*/ return( FALSE ); /*112*/ /*112*/ Nitems = tp->ByteSize/atomsize; /*813112*/ if( Nitems == 0 ) /*912*/ Nitems = 1; /*912*/ if( Nitems <= skip ) /*112*/ return( FALSE ); /*112*/ /*112*/ /************************************************************************112*/ /* simply show character array bytes as a string. 112*/ /************************************************************************112*/ if( atomtype == TYPE_CHAR || atomtype == TYPE_UCHAR ) /*112*/ { /*112*/ ShowHexBytes(dfp, row, rows, skip); /*112*/ return( TRUE ); /*112*/ } /*112*/ /*112*/ /************************************************************************112*/ /* -we only want to associate the array name with the first element of 112*/ /* the array. We set dfp == null after the first element, or before the 112*/ /* first element if we have scrolled the array name off the screen. 112*/ /* -format each element. 112*/ /* -display in int and hex format. 112*/ /* -truncate long lines. 112*/ /* 112*/ /************************************************************************112*/ if( skip ) /*112*/ dfp = NULL; /*112*/ /*112*/ for( rr=0, item=skip+1; (rr < rows) && (item <= Nitems); ++rr, ++item) /*112*/ { /*112*/ InitDataBuffer( buffer, DATALINESPAN, dfp ); /*112*/ dfp = NULL; /*112*/ n = sprintf( buffer + STGCOL+1, "[%02u] ", item-1 ); /*521*/ /*112*/ *(buffer + STGCOL+1 + n) = ' '; /*112*/ /*112*/ if ( n <= TAB1 ) n = TAB1; /*112*/ else n = TAB2; /*112*/ /*112*/ /*112*/ cp = buffer + STGCOL + 1 + n; /*112*/ addr = baseaddr+atomsize*(item-1); /*112*/ FormatDataItem( cp , addr, mid, atomtype, sfx); /*112*/ buffer[ DATALINESPAN-1 ] = 0; /*112*/ putrc( row + rr, 0, buffer ); /*112*/ } /*112*/ if( rr < rows ) /*112*/ ClrScr( row + rr, row + rows - 1, vaStgExp ); /*112*/ return( TRUE ); /*112*/ } /* end ShowArray(). /*112*/
HGRIDITEM InsertIdentifier(HWND hwndGV, HGRIDITEM hRoot, Type *type, size_w dwOffset, TypeDecl *typeDecl) { TCHAR buf[200]; GVITEM gvitem = { 0 }; HGRIDITEM hItem; if(fShowFullType) { RenderType(buf, 200, type); gvitem.pszText = buf; } else { _stprintf(buf, TEXT("%hs"), type->sym->name); RenderType(buf, 200, type->link); gvitem.pszText = buf;//type->sym->name; } gvitem.state = 0; if(type->link && type->link->ty != typeARRAY) gvitem.state |= GVIS_EXPANDED; gvitem.iImage = IsStruct(type) ? 1 : 0; //gvitem.iImage = isstruct ? 3 : 2; if(typeDecl && typeDecl->tagList) gvitem.iImage+=2; gvitem.param = (ULONG_PTR)type;//typeDecl; gvitem.mask = GVIF_TEXT|GVIF_PARAM |GVIF_STATE | GVIF_IMAGE; hItem = GridView2_InsertUniqueChild(hwndGV, hRoot, &gvitem); if(type->link && type->link->ty == typeARRAY) { FormatDataItem(hwndGV, hItem, type, dwOffset); } if(IsStruct(type)) { gvitem.iSubItem = COLIDX_DATA; gvitem.state = GVIS_READONLY; gvitem.pszText = TEXT("{...}"); gvitem.param = 0; gvitem.mask = GVIF_PARAM | GVIF_TEXT | GVIF_STATE; GridView2_SetItem(hwndGV, hItem, &gvitem); } /*if(!fShowFullType) { RenderType(buf, 200, type->link); //_stprintf(buf, TEXT("%hs"), type->sym->name); gvitem.iSubItem = 0;//COLIDX_TYPE; gvitem.state = GVIS_READONLY; gvitem.pszText = buf; gvitem.param = (UINT64)type; gvitem.mask = GVIF_PARAM | GVIF_TEXT | GVIF_STATE; GridView2_SetItem(hwndGV, hItem, &gvitem); }*/ return hItem; }