static void DumpTypes(IDiaSession *session) { IDiaSymbol * globalScope = NULL; IDiaEnumSymbols * enumSymbols = NULL; IDiaSymbol * symbol = NULL; HRESULT hr = session->get_globalScope(&globalScope); if (FAILED(hr)) return; AddReportSepLine(); g_report.Append("Types:\n"); DWORD flags = nsfCaseInsensitive|nsfUndecoratedName; // nsNone ? hr = globalScope->findChildren(SymTagUDT, 0, flags, &enumSymbols); if (FAILED(hr)) goto Exit; ULONG celt = 0; for (;;) { hr = enumSymbols->Next(1, &symbol, &celt); if (FAILED(hr) || (celt != 1)) break; DumpType(symbol, 0); symbol->Release(); } Exit: UnkReleaseSafe(enumSymbols); UnkReleaseSafe(globalScope); }
//----------------------------------------------------------------------------- // Name: ParseModules // Object: parse all compilands // Parameters : // in : // out : // return : TRUE on success //----------------------------------------------------------------------------- BOOL CDebugInfos::ParseModules() { HRESULT hr; IDiaEnumSymbols* pEnumSymbols; IDiaEnumSymbols* pEnumChildren; IDiaSymbol* pCompiland; IDiaSymbol* pSymbol; ULONG celt = 0; CModuleInfos* pModuleInfo; BSTR Name; // Retrieve the compilands first if(FAILED(this->pDiaGlobalSymbol->findChildren(SymTagCompiland, NULL, nsNone, &pEnumSymbols))) return FALSE; // for each compiland while(pEnumSymbols->Next(1, &pCompiland, &celt) == S_OK && celt == 1) { // Retrieve the name of the module Name=NULL; pCompiland->get_name(&Name); #if (REMOVE_LINKER_COMPILAND==1) // avoid to display "* Linker *" infos if (Name) { if (wcsicmp(Name,LINKER_COMPILAND_NAME)==0) { SysFreeString(Name); pCompiland->Release(); continue; } } #endif // create module info pModuleInfo=new CModuleInfos(); // add it to modules list this->pLinkListModules->AddItem(pModuleInfo); // assume module name is set if (Name) { #if (defined(UNICODE)||defined(_UNICODE)) pModuleInfo->Name=_tcsdup(Name); #else CAnsiUnicodeConvert::UnicodeToAnsi(Name,&pModuleInfo->Name); #endif SysFreeString(Name); } else pModuleInfo->Name=_tcsdup(_T("")); // Find all the symbols defined in this compiland and get their info if(SUCCEEDED(pCompiland->findChildren(SymTagNull, NULL, nsNone, &pEnumChildren))) { ULONG celt_ = 0; while (pEnumChildren->Next(1, &pSymbol, &celt_) == S_OK && celt_ == 1) { hr=pModuleInfo->Parse(pSymbol); if (FAILED(hr)) this->ReportError(_T("Error parsing module information"),hr); pSymbol->Release(); } pEnumChildren->Release(); } pCompiland->Release(); } pEnumSymbols->Release(); return TRUE; }
//------------------------------------------------------------------------ // pParentSymbol 에서 자식중에 symbolName 인 심볼을 리턴한다. // 찾은 심볼의 Offset값을 리턴한다. // pParentSymbol 은 Data, UDT, TypeDef 타입이어야 한다. //------------------------------------------------------------------------ IDiaSymbol* dia::FindChildSymbol( const std::string &symbolName, IDiaSymbol *pParentSymbol, OUT LONG *pOffset ) // pOffset =NULL { RETV( !pParentSymbol, NULL ); const string name = GetSymbolName(pParentSymbol); //debug용 const wstring searchSymbolName = memmonitor::str2wstr(symbolName).c_str(); // 데이타 심볼이면, 타입 심볼로 교체한다. enum SymTagEnum symTag; HRESULT hr = pParentSymbol->get_symTag((DWORD*)&symTag); bool isNewTypeSymbol = false; IDiaSymbol* pTypeSymbol = NULL; switch (symTag) { case SymTagData: isNewTypeSymbol = true; hr = pParentSymbol->get_type(&pTypeSymbol); break; case SymTagTypedef: { hr = pParentSymbol->get_type(&pTypeSymbol); IDiaSymbol *reval = FindChildSymbol(symbolName, pTypeSymbol, pOffset); if (pTypeSymbol) pTypeSymbol->Release(); return reval; } break; default: { pTypeSymbol = pParentSymbol; } break; } // Enumeration CComPtr<IDiaEnumSymbols> pEnumSymbols; if (FAILED(pTypeSymbol->findChildren(SymTagNull, searchSymbolName.c_str(), nsRegularExpression, &pEnumSymbols))) { if (isNewTypeSymbol) pTypeSymbol->Release(); return NULL; } IDiaSymbol *pFindSymbol; ULONG celt = 0; pEnumSymbols->Next(1, &pFindSymbol, &celt); // 찾았다면 리턴 if (1 == celt) { if (isNewTypeSymbol) pTypeSymbol->Release(); if (pOffset) hr = pFindSymbol->get_offset(pOffset); return pFindSymbol; } // 못찾았다면, 자식 중에서 찾아본다. enum 으로 선언된 값은 이렇게 찾아야함 CComPtr<IDiaEnumSymbols> pAnotherEnumSymbols; if (FAILED(pTypeSymbol->findChildren(SymTagNull, NULL, nsNone, &pAnotherEnumSymbols))) { if (isNewTypeSymbol) pTypeSymbol->Release(); return NULL; } pFindSymbol = NULL; IDiaSymbol* pChildSymbol; celt = 0; while (SUCCEEDED(pAnotherEnumSymbols->Next(1, &pChildSymbol, &celt)) && (celt == 1)) { enum SymTagEnum symTag; pChildSymbol->get_symTag((DWORD*)&symTag); if (SymTagBaseClass == symTag) { LONG childOffset = 0; pFindSymbol = FindChildSymbol( symbolName, pChildSymbol, &childOffset ); if (pFindSymbol) { LONG baseClassOffset = 0; hr = pChildSymbol->get_offset(&baseClassOffset); if (pOffset) *pOffset = baseClassOffset + childOffset; break; } } if (SymTagEnum != symTag) { pChildSymbol->Release(); continue; } CComPtr<IDiaEnumSymbols> pSubEnumSymbols; if (FAILED(pChildSymbol->findChildren(SymTagNull, searchSymbolName.c_str(), nsRegularExpression, &pSubEnumSymbols))) { pChildSymbol->Release(); continue; } celt = 0; pSubEnumSymbols->Next( 1, &pFindSymbol, &celt ); if (1 == celt) { pChildSymbol->Release(); const string name = GetSymbolName(pFindSymbol); //debug용 if (pOffset) *pOffset = 0; // 상수값은 offset이 없다. break; // 찾았으니 종료 } } if (isNewTypeSymbol) pTypeSymbol->Release(); return pFindSymbol; }