Was this page helpful?
Your feedback about this content is important. Let us know what you think.
Additional feedback?
1500 characters remaining
Dia2dump.cpp Source File

Dia2dump.cpp Source File

The source code for Dia2dump.cpp follows.

// dia2dump.cpp : Dump contents of a pdb file using DIA.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//---------------------------------------------------------------
//

#include "stdafx.h"
#include "diacreate.h"
#include "cvconst.h"

void Fatal( const char *msg )
{
   printf( msg );
   printf( "\n" );
   exit( -1 );
}

#ifdef NOCOM

#define freeString LocalFree

#else

#define freeString SysFreeString

#endif

CComPtr<IDiaSession> psession;
CComPtr<IDiaSymbol> pglobal;

void printVariant( VARIANT& v )
{
   switch( v.vt )
   {
 //*   LONGLONG      VT_I8
   case VT_I8:
      printf( "%ld", v.llVal );
      break;
 //*   LONG         VT_I4
   case VT_I4:
      printf( "%d", v.lVal );
      break;
 //*   BYTE         VT_UI1
   case VT_UI1:
      printf( "%d", v.bVal);
      break;
 //*   SHORT         VT_I2
   case VT_I2:
      printf( "%d", v.iVal);
      break;
 //*   CHAR         VT_I1
   case VT_I1:
      printf( "%d", v.cVal);
      break;
 //*   USHORT         VT_UI2
   case VT_UI2:
      printf( "%d", v.uiVal);
      break;
//*   ULONG         VT_UI4
   case VT_UI4:
      printf( "%d", v.ulVal);
      break;
 //*   ULONGLONG         VT_UI8
   case VT_UI8:
      printf( "%ld", v.ullVal);
      break;
 //*   INT         VT_INT
   case VT_INT:
      printf( "%d", v.intVal);
      break;
 //*   UINT         VT_UINT
   case VT_UINT:
      printf( "%d", v.uintVal);
      break;
   default:
      printf( "<Not implemented>" );
      break;
   }
}

void printBound( IDiaSymbol* pBound )
{
   DWORD tag = 0;
   BSTR name;
   DWORD kind;
   pBound->get_symTag( &tag );
   pBound->get_locationType( &kind );
   if ( tag == SymTagData && kind == LocIsConstant ) {
      CComVariant v;
      pBound->get_value( &v );
      printVariant( v );
   } else if ( pBound->get_name( &name ) == S_OK ) {
      printf( "%ws", name );
      freeString( name );
   }
}

void printType( IDiaSymbol* pType )
{
   DWORD tag = 0;
   pType->get_symTag( &tag );
   BSTR name;
   if ( pType->get_name( &name ) == S_OK && name != NULL ) {
      printf( "-%ws", name );
      freeString( name );
   } else if ( tag == SymTagPointerType ) {
      CComPtr<IDiaSymbol> pBaseType;
      if (  pType->get_type( &pBaseType ) == S_OK ) {
         printType( pBaseType );
         printf( "*" );
      } else {
         Fatal( "pointer get_type" );
      }
   } else if ( tag == SymTagBaseType ) {
      ULONGLONG size;
      DWORD bt;
      if ( pType->get_length( &size ) != S_OK )
         Fatal( "Internal error, no Length" );
      if ( pType->get_baseType( &bt ) != S_OK )
         Fatal( "Internal error, no baseType" );
       wprintf( L"(base type=%d, len=%ld)  ", bt, size );
   } else if ( tag == SymTagArrayType ) {
      CComPtr<IDiaSymbol> pBaseType;
      if ( pType->get_type( &pBaseType ) == S_OK ) {
         printType( pBaseType );
      } else {
         Fatal( "array get_type" );
      }
      DWORD rank;
      DWORD celt;
      LONG count;
      CComPtr< IDiaEnumSymbols > pEnum;
      if ( pType->get_rank( &rank ) == S_OK ) {
         if ( pType->findChildren( SymTagDimension, NULL, nsNone, &pEnum ) == S_OK && pEnum != NULL ) {
            CComPtr< IDiaSymbol > pSym;
            while ( pEnum->Next( 1, &pSym, &celt ) == S_OK && celt == 1 ) {
               CComPtr< IDiaSymbol > pBound;
               printf( "[" );
               if ( pSym->get_lowerBound( &pBound ) == S_OK ) {
                  printBound( pBound );
                  printf("..");
               }
               pBound = NULL;
               if ( pSym->get_upperBound( &pBound ) == S_OK ) {
                  printBound( pBound );
               }
               pBound = NULL;
               printf( "]" );
               pSym = NULL;

            }
         } 
      } else if ( pType->findChildren( SymTagCustomType, NULL, nsNone, &pEnum ) == S_OK && pEnum != NULL && SUCCEEDED( pEnum->get_Count( &count ) ) && count > 0 ){
            CComPtr< IDiaSymbol > pSym;
            while ( pEnum->Next( 1, &pSym, &celt ) == S_OK && celt == 1 ) {
               printf( "[" );
               printType( pSym );
               printf( "]" );
               pSym = NULL;
            }
      } else {
         ULONGLONG lenArray;
         ULONGLONG lenElem;
         if ( pType->get_length( &lenArray ) != S_OK
            || pBaseType->get_length( &lenElem ) != S_OK ) {
            Fatal( "No type length." );
         }
         printf( "[%ld]", lenArray/lenElem );
      }
   } else if ( tag == SymTagFunctionType ) {
      printf( "Function Type" );
   } else if ( tag == SymTagCustomType ) {
      printf( "Custom Type: " );
      DWORD id;
      DWORD rec;
      GUID guid;
      if ( pType->get_guid( &guid ) == S_OK ) {
         wchar_t wszGuid[64];
         StringFromGUID2(guid, wszGuid, 64);
         printf( "%ws", wszGuid );
      } else if ( pType->get_oemId( &id ) == S_OK && pType->get_oemSymbolId( &rec ) == S_OK ) {
         printf( "%x:%x", id, rec );
      }
      DWORD len = 0;
      if ( pType->get_types( 0, &len, NULL ) == S_OK && len > 0 ) {
         IDiaSymbol** psyms = new IDiaSymbol*[ len ];
         pType->get_types( len, &len, psyms );
         for ( DWORD i = 0; i < len; ++i ) {
            printf( " <" );
            printType( psyms[i] );
            printf( ">" );
            psyms[i]->Release();
         }
         delete [] psyms;
      }
      len = 0;
      if ( pType->get_dataBytes( 0, &len, NULL ) == S_OK && len > 0 ) {
         BYTE* pdata = new BYTE[ len ];
         pType->get_dataBytes( len, &len, pdata );
         printf( "<data" );
         for ( DWORD i = 0; i < len; ++i ) {
            printf( " %02x", pdata[i] );
         }
         printf( " data>" );
         delete [] pdata;
      }
   } else {
      printf( "No Type.");
   }
}

void dumpFunctionLines( IDiaSymbol* pSymbol, IDiaSession* pSession )
{
   ULONGLONG length = 0;
   DWORD isect = 0;
   DWORD offset = 0;
   pSymbol->get_addressSection( &isect );
   pSymbol->get_addressOffset( &offset );
   pSymbol->get_length( &length );
   if ( isect != 0 && length > 0 ) {
      CComPtr< IDiaEnumLineNumbers > pLines;
      if ( SUCCEEDED( pSession->findLinesByAddr( isect, offset, static_cast<DWORD>( length ), &pLines ) ) ) {
         CComPtr< IDiaLineNumber > pLine;
         DWORD celt;
         bool firstLine = true;
         while ( SUCCEEDED( pLines->Next( 1, &pLine, &celt ) ) && celt == 1 ){
            DWORD offset;
            DWORD seg;
            DWORD linenum;
            CComPtr< IDiaSymbol > pComp;
            CComPtr< IDiaSourceFile > pSrc;
            pLine->get_compiland( &pComp );
            pLine->get_sourceFile( &pSrc );
            pLine->get_addressSection( &seg );
            pLine->get_addressOffset( &offset );
            pLine->get_lineNumber( &linenum );
            printf( "\tline %d at 0x%x:0x%x\n", linenum, seg, offset );
            pLine = NULL;
            if ( firstLine ) {
               // Sanity check.
               CComPtr< IDiaEnumLineNumbers > pLinesByLineNum;
               if ( SUCCEEDED( pSession->findLinesByLinenum( pComp, pSrc, linenum, 0, &pLinesByLineNum ) ) ) {
                  CComPtr< IDiaLineNumber > pLine;
                  DWORD celt;
                  while ( SUCCEEDED( pLinesByLineNum->Next( 1, &pLine, &celt ) ) && celt == 1 ){
                     DWORD offset;
                     DWORD seg;
                     DWORD linenum;
                     pLine->get_addressSection( &seg );
                     pLine->get_addressOffset( &offset );
                     pLine->get_lineNumber( &linenum );
                     printf( "\t\tfound line %d at 0x%x:0x%x\n", linenum, seg, offset );
                     pLine = NULL;
                  }
               }
               firstLine = false;
            }
         }
      }
   }
}

wchar_t* szTags[] = {
   L"",
   L"Executable (Global)",
   L"Compiland", 
   L"CompilandDetails", 
   L"CompilandEnv",
   L"Function", 
   L"Block",
   L"Data",
   L"Unused", 
   L"Label", 
   L"PublicSymbol", 
   L"UDT", 
   L"Enum", 
   L"FunctionType", 
   L"PointerType", 
   L"ArrayType", 
   L"BaseType", 
   L"Typedef", 
   L"BaseClass",
   L"Friend",
   L"FunctionArgType", 
   L"FuncDebugStart", 
   L"FuncDebugEnd",
   L"UsingNamespace", 
   L"VTableShape",
   L"VTable",
   L"Custom",
   L"Thunk",
   L"CustomType",
   L""
};

bool fTagScopes[] = {
   false,
   true,
   true, 
   false, 
   false,
   true, 
   true,
   false,
   false, 
   false, 
   false, 
   false, 
   false, 
   false, 
   false, 
   false, 
   false, 
   false, 
   false,
   false,
   false, 
   false, 
   false,
   false, 
   false,
   false,
   false,
   false,
   false,
   false
};

wchar_t* szDataKinds[] = {
   L"Unknown",
   L"Local",
   L"Static Local",
   L"Parameter",
   L"Object Pointer",
   L"File Static",
   L"Global",
   L"Member",
   L"Static Member",
   L"Constant"
};

wchar_t* symbolTagName( DWORD tag )
{
   if ( tag > SymTagNull && tag < SymTagMax )
      return szTags[ tag ];
   assert( false );
   return L"Error!";
}

bool isScopeSym( DWORD tag )
{
   if ( tag > SymTagNull && tag < SymTagMax )
      return fTagScopes[ tag ];
   assert( false );
   return false;
}

void printScopeName( IDiaSymbol* pscope )
{
   DWORD tag;
   BSTR name;
   if ( pscope->get_symTag( &tag ) != S_OK )
      Fatal( "Internal error, getting SymTag" );
   if ( pscope->get_name( &name ) != S_OK )
      Fatal( "Internal error, getting name" );
   if ( name == NULL ) {
      wprintf( szTags[ tag ] );
      return;
   }
   wprintf( L"%ws (%ws)", name, szTags[ tag ] );
   freeString( name );
}

void PrintNameFromScope( wchar_t* name, IDiaSymbol* pscope, IDiaEnumSymbols* pEnum )
{
   CComPtr< IDiaSymbol> pSym;
   DWORD celt;
   while ( SUCCEEDED( pEnum->Next( 1, &pSym, &celt ) ) && celt == 1 ) {
      DWORD tag;
      BSTR bstr;
      if ( pSym->get_symTag( &tag ) != S_OK )
         Fatal( "Internal error, no SymTag" );
      if ( pSym->get_name( &bstr ) != S_OK )
         Fatal( "Internal error, no name" );
      // Tagtype name found in name or scopeTag.
      wprintf( L"\t%ws %ws found in ", szTags[ tag ], bstr );
      printScopeName( pscope );
      wprintf( L"\n" );
      freeString( bstr );
      pSym = 0;
   }
}

void FindNameInNamespace( wchar_t* name, IDiaSymbol* pnamespace )
{
   wchar_t *buf = NULL;
   BSTR szNamespace;
   pnamespace->get_name( &szNamespace );
   buf = new wchar_t[ wcslen( name ) + wcslen( szNamespace ) + 3];
   wsprintfW( buf, L"%s::%s", szNamespace, name );
   freeString( szNamespace );
   CComPtr< IDiaEnumSymbols > pEnum;
   if ( FAILED( pglobal->findChildren( SymTagNull, name, nsCaseSensitive, &pEnum ) ) )
      Fatal( "Namespace findChildren failed" );
   long cnt = 0;
   if ( pEnum != NULL && SUCCEEDED( pEnum->get_Count(&cnt) ) && cnt > 0 ) {   // Found a name.
      PrintNameFromScope( name, pglobal, pEnum );
   }
   delete [] buf;
}

void FindNameInEnum( wchar_t* name, IDiaSymbol* penumeration )
{
   CComPtr< IDiaEnumSymbols > pEnum;
   if ( FAILED( penumeration->findChildren( SymTagData, name, nsRegularExpression, &pEnum ) ) )
      Fatal( "Enumeration findChildren failed" );
   long cnt = 0;
   if ( pEnum != NULL && SUCCEEDED( pEnum->get_Count(&cnt) ) && cnt > 0 ) {   // Found a name.
      PrintNameFromScope( name, penumeration, pEnum );
   }
}

void FindNameInClass( wchar_t* name, IDiaSymbol* pclass )
{
   CComPtr< IDiaEnumSymbols > pEnum;
   if ( FAILED( pclass->findChildren( SymTagNull, name, nsCaseSensitive, &pEnum ) ) ) 
      Fatal( "Class findChildren failed" );
   long cnt = 0;
   if ( pEnum != NULL && SUCCEEDED( pEnum->get_Count(&cnt) ) && cnt > 0 ) {   // Found a name.
      PrintNameFromScope( name, pclass, pEnum );
   }
   pEnum = 0;
   // Check out the enumerations.
   CComPtr< IDiaSymbol > pSym;
   if ( FAILED( pclass->findChildren( SymTagEnum, NULL, nsNone, &pEnum ) ) ) 
      Fatal( "Class findChildren for enums failed" );
   if ( pEnum != NULL && SUCCEEDED( pEnum->get_Count(&cnt) ) && cnt > 0 ) {   // Found an enum.
      DWORD celt;
      while ( SUCCEEDED( pEnum->Next( 1, &pSym, &celt ) ) && celt == 1 ) {
         FindNameInEnum( name, pSym );
         pSym = 0;
      }
   }
   pEnum = 0;
   // Check out the base classes.
   if ( FAILED( pclass->findChildren( SymTagBaseClass, NULL, nsNone, &pEnum ) ) ) 
      Fatal( "Class findChildren for base classes failed" );
   if ( pEnum != NULL && SUCCEEDED( pEnum->get_Count(&cnt) ) && cnt > 0 ) {   // Found a base class.
      DWORD celt;
      while ( SUCCEEDED( pEnum->Next( 1, &pSym, &celt ) ) && celt == 1 ) {
         CComPtr< IDiaSymbol > pClass;
         if (  pSym->get_type( &pClass ) == S_OK )
            Fatal( "Getting class for a base type failed" );
         if ( pClass )
            FindNameInClass( name, pClass );
         pSym = 0;
      }
   }
}

void FindCppNameInScope( wchar_t* name, IDiaSymbol* pScope )
{
   // while ( scope ) {
      // Scan the scope for a symbol.
      // If any namespaces, then scan for name in namespace.
      // If scope is a member function then 
      //   scan class parent for member with name.
      // scope = scope.parent;
   // }

   wprintf( L"Finding name \"%ws\" in ", name );
   printScopeName( pScope );
   wprintf( L"\n" );

   DWORD celt;
   long cnt = 0;
   CComPtr< IDiaSymbol > pSym;
   CComPtr< IDiaSymbol > pParent;
   CComPtr< IDiaSymbol > pscope;
   for ( pscope = pScope; pscope != NULL; ) {
      CComPtr< IDiaEnumSymbols > pEnum;
      // Local data search
      if ( FAILED( pscope->findChildren( SymTagNull, name, nsCaseSensitive, &pEnum ) ) )
         Fatal( "Local scope findChildren failed" );
      if ( pEnum != NULL && SUCCEEDED( pEnum->get_Count(&cnt) ) && cnt > 0 ) {   // Found a name.
         PrintNameFromScope( name, pscope, pEnum );
      }
      pEnum = 0;
      // Look into any namespaces.
      if ( FAILED( pscope->findChildren( SymTagUsingNamespace, NULL, nsNone, &pEnum ) ) )
         Fatal( "Namespace findChildren failed" );
      if ( pEnum != NULL && SUCCEEDED( pEnum->get_Count(&cnt) ) && cnt > 0 ) {   // Found a namespace.
         while ( SUCCEEDED( pEnum->Next( 1, &pSym, &celt ) ) && celt == 1 ) {
            FindNameInNamespace( name, pSym );
            pSym = 0;
         }
      }
      pEnum = 0;
      // Check if this is a member function.
      DWORD tag = SymTagNull;
      if ( SUCCEEDED( pscope->get_symTag( &tag ) ) 
         && tag == SymTagFunction
         && SUCCEEDED( pscope->get_classParent( &pParent ) )
         && pParent != NULL ) {
         FindNameInClass( name, pParent );
      }
      pParent = NULL;
      // Move to lexical parent.
      if ( SUCCEEDED( pscope->get_lexicalParent( &pParent ) )
         && pParent != NULL ) {
         pscope = pParent;
      } else {
         pscope = NULL;
      }
      pParent = NULL;
   };
}

void dumpLocalVars( DWORD rva )
{
   CComPtr< IDiaSymbol > pBlock;
   if ( FAILED( psession->findSymbolByRVA( rva, SymTagBlock, &pBlock ) ) ) {
      Fatal( "Failed to find symbols by RVA" );
   }
   CComPtr< IDiaSymbol > pscope;
   for ( ; pBlock != NULL; ) {
      CComPtr< IDiaEnumSymbols > pEnum;
      // Local data search
      if ( FAILED( pBlock->findChildren( SymTagNull, NULL, nsNone, &pEnum ) ) )
         Fatal( "Local scope findChildren failed" );
      CComPtr< IDiaSymbol > pSymbol;
      DWORD tag;
      DWORD celt;
      while ( pEnum != NULL && SUCCEEDED( pEnum->Next( 1, &pSymbol, &celt ) ) && celt == 1 ) {
         pSymbol->get_symTag( &tag );
         if ( tag == SymTagData ) {
            BSTR name;
            DWORD kind;
            pSymbol->get_name( &name );
            pSymbol->get_dataKind( &kind );
            if ( name != NULL )
               wprintf( L"\t%s (%s)\n", name, szDataKinds[ kind ] );
         } else if ( tag == SymTagAnnotation ) {
            CComPtr< IDiaEnumSymbols > pValues;
            // Local data search
            wprintf( L"\tAnnotation:\n" );
            if ( FAILED( pSymbol->findChildren( SymTagNull, NULL, nsNone, &pValues ) ) )
               Fatal( "Annotation findChildren failed" );
            pSymbol = NULL;
            while ( pValues != NULL && SUCCEEDED( pValues->Next( 1, &pSymbol, &celt ) ) && celt == 1 ) {
               CComVariant value;
               if ( pSymbol->get_value( &value ) != S_OK )
                  Fatal( "No value for annotation data." );
               wprintf( L"\t\t%ws\n", value.bstrVal );
               pSymbol = NULL;
            }
         }
         pSymbol = NULL;
      }
      pBlock->get_symTag( &tag ); 
      if ( tag == SymTagFunction )   // Stop at function scope.
         break;
      // Move to lexical parent.
      CComPtr< IDiaSymbol > pParent;
      if ( SUCCEEDED( pBlock->get_lexicalParent( &pParent ) )
         && pParent != NULL ) {
         pBlock = pParent;
      } else {
         Fatal( "Finding lexical parent failed." );
      }
   };
}

DWORD PrintNameAddr( IDiaSymbol* pSym )
{
   DWORD rva;
   if ( pSym->get_relativeVirtualAddress( &rva ) != S_OK )
      rva = 0;   // No RVA; must be an absolute value.
   DWORD tag;
   pSym->get_symTag( &tag );
   BSTR name;
   if ( pSym->get_name( &name ) != S_OK )
      printf( "\t0x%08X (%ws) <no name>\n", rva, szTags[ tag ] );
   else {
      printf( "\t0x%08X (%ws) %ws\n", rva, szTags[ tag ], name );
      freeString( name );
   }
   return rva;
}

void      
DumpLex( IDiaSymbol* pscope, int tabs )
{
   HRESULT   hr;

   CComPtr<IDiaEnumSymbols> pSymbols;   
   if ( SUCCEEDED( pscope->findChildren( SymTagNull, NULL, nsNone, &pSymbols ) ) ) {
      CComPtr<IDiaSymbol> pSymbol;
      ULONG celt = 0;
      while ( pSymbols != NULL && SUCCEEDED( hr = pSymbols->Next( 1, &pSymbol, &celt ) ) && celt == 1 ) {
         for ( int i = 0; i < tabs; ++i )
            printf( "\t" );
         BSTR name;
         if ( pSymbol->get_name( &name ) == S_OK && name != NULL ) {
            printf( "%ws", name );
            freeString( name );
         }
         DWORD symTag;
         pSymbol->get_symTag( &symTag );
         printf( " : %ws\n", szTags[ symTag ] );
         switch ( symTag ) {
         case SymTagExe:
            assert( false );
            break;
         case SymTagCompiland:
         case SymTagFunction:
         case SymTagBlock:
            DumpLex( pSymbol, tabs+1 );
            break;
         default:
            break;
         }
         pSymbol = NULL;
      }
   }
}

void      
Dump(
   char *szFilename,
   IDiaDataSource* pSource,
   wchar_t* szLookup
)
{
   HRESULT   hr;
   wchar_t wszFilename[ _MAX_PATH ];
   mbstowcs( wszFilename, szFilename, sizeof( wszFilename ) );
   if ( FAILED( pSource->loadDataFromPdb( wszFilename ) ) ) 
      if ( FAILED( pSource->loadDataForExe( wszFilename, NULL, NULL ) ) ) 
         Fatal( "loadDataFromPdb/Exe" );

   if ( FAILED( pSource->openSession( &psession ) ) ) 
      Fatal( "openSession" );
   if ( FAILED( psession->get_globalScope( &pglobal) ) )
      Fatal( "get_globalScope" );
   DWORD id = 0;
   pglobal->get_symIndexId( &id );
   if ( id == 0 )
      Fatal( "get_indexId" );

   ULONG celt = 0;

   CComPtr<IDiaEnumSymbols> pEnum;
   CComPtr<IDiaSymbol> pSymbol;

   pglobal->findChildren(SymTagUDT,NULL,nsfCaseInsensitive|nsfUndecoratedName,&pEnum);
   while ( SUCCEEDED( hr = pEnum->Next( 1, &pSymbol, &celt ) ) && celt == 1 ) {
      BSTR name;
      if ( pSymbol->get_name( &name ) != S_OK )
         Fatal( "get_name" );
      printf( "Found UDT: %ws\n", name );
      freeString( name );
      ULONGLONG len = 0;
      pSymbol->get_length( &len );
      if ( len == 0 )
         Fatal( "get_length" );
      pSymbol = 0;
   }

   CComPtr<IDiaEnumTables> pTables;
   if ( FAILED( psession->getEnumTables( &pTables ) ) )
      Fatal( "getEnumTables" );
   CComPtr< IDiaTable > pTable;
   while ( SUCCEEDED( hr = pTables->Next( 1, &pTable, &celt ) ) && celt == 1 ) {
      BSTR name;
      if ( pTable->get_name( &name ) != 0 )
         Fatal( "get_name" );
      printf( "Found table: %ws\n", name );
      freeString( name );
      CComPtr<IDiaEnumSymbols> pSymbols;
      CComPtr<IDiaEnumSourceFiles> pSourceFiles;
      CComPtr<IDiaEnumSegments> pSegments;
      CComPtr<IDiaEnumSectionContribs> pSecContribs;
      if ( SUCCEEDED( pTable->QueryInterface( _uuidof( IDiaEnumSymbols ), (void**)&pSymbols ) ) ) {
         CComPtr<IDiaSymbol> pSymbol;
         while ( SUCCEEDED( hr = pSymbols->Next( 1, &pSymbol, &celt ) ) && celt == 1 ) {
            DWORD symIndex;
            pSymbol->get_symIndexId( &symIndex );
            DWORD symTag;
            pSymbol->get_symTag( &symTag );
            if ( pSymbol->get_name( &name ) == S_OK && name != NULL ) {
               printf( "sym name: %ws", name );
               freeString( name );
               if ( symTag == SymTagPublicSymbol ) {
                  pSymbol->get_undecoratedName( &name );
                  printf( " (%ws)", name );
                  freeString( name );
               }
               CComPtr<IDiaSymbol> pType;
               if ( pSymbol->get_type( &pType ) == S_OK ) {
                  printf( " has type " );
                  printType( pType );

                  DWORD id = 0;
                  CComPtr< IDiaSymbol > ptypeSym;
                  pSymbol->get_typeId( &id );
                  if ( FAILED( psession->symbolById( id, &ptypeSym ) ) ||
                     psession->symsAreEquiv( pType, ptypeSym ) != S_OK ) {
                        Fatal( "Sym type equality" );
                  }
               }
               printf( "\n" );
               if ( symTag == SymTagFunction ) {
                  dumpFunctionLines( pSymbol, psession );
                  DWORD loctype;
                  if ( pSymbol->get_locationType( &loctype ) == S_OK && loctype == LocIsStatic ) {
                     DWORD rva;
                     pSymbol->get_relativeVirtualAddress( &rva );
                     if ( rva != 0 ) {
                        dumpLocalVars( rva );

                        CComPtr< IDiaSymbol > pfuncSym;
                        if ( SUCCEEDED( psession->findSymbolByRVA( rva, SymTagNull, &pfuncSym ) ) ) {
                           if ( psession->symsAreEquiv( pfuncSym, pSymbol ) != S_OK ) {
                              BSTR name;
                              DWORD tag;
                              pfuncSym->get_symTag( &tag );
                              pfuncSym->get_name( &name );
                              printf( "\tfound alt symbol: %ws (%ws)\n", name != NULL ? name : L"", szTags[ tag ] );
                              if ( name )
                                 freeString( name );
                           }
                        } else {
                           Fatal( "No function symbol found by rva." );
                        }
                     }
                  }
               } 
            } 
            if ( isScopeSym( symTag ) && szLookup ) {
               FindCppNameInScope( szLookup, pSymbol );
            }
            pSymbol = NULL;
         }
      } else if ( SUCCEEDED( pTable->QueryInterface( _uuidof( IDiaEnumSourceFiles ), (void**)&pSourceFiles ) ) ) {
         CComPtr<IDiaSourceFile> pSourceFile;
         while ( SUCCEEDED( hr = pSourceFiles->Next( 1, &pSourceFile, &celt ) ) && celt == 1 ) {
            pSourceFile->get_fileName( &name );
            if ( name != NULL ) {
               printf( "file name: %ws\n", name );
               freeString( name );
            }
            pSourceFile = NULL;
         }
      } else if ( SUCCEEDED( pTable->QueryInterface( _uuidof( IDiaEnumSegments ), (void**)&pSegments ) ) ) {
         CComPtr<IDiaSegment> pSegment;
         while ( SUCCEEDED( hr = pSegments->Next( 1, &pSegment, &celt ) ) && celt == 1 ) {
            DWORD rva;
            DWORD seg;
            pSegment->get_addressSection( &seg );
            if ( pSegment->get_relativeVirtualAddress( &rva ) == S_OK ) {
               printf( "Segment %i addr: 0x%.8X\n", seg, rva );
               pSegment = NULL;
               CComPtr<IDiaSymbol> pSym;
               if ( psession->findSymbolByRVA( rva, SymTagNull, &pSym ) == S_OK ) {
                  BSTR name = NULL;
                  DWORD tag;
                  pSym->get_symTag( &tag );
                  pSym->get_name( &name );
                  printf( "\tClosest symbol: %ws (%ws)\n", name != NULL ? name : L"", szTags[ tag ] );
                  if ( name )
                     freeString( name );
               }
            } else {
               printf( "Segment %i \n", seg );
               pSegment = NULL;
               CComPtr<IDiaSymbol> pSym;
               if ( SUCCEEDED( psession->findSymbolByAddr( seg, 0, SymTagNull, &pSym ) ) ) {
                  BSTR name;
                  DWORD tag;
                  pSym->get_symTag( &tag );
                  pSym->get_name( &name );
                  printf( "\tClosest symbol: %ws (%ws)\n", name != NULL ? name : L"", szTags[ tag ] );
                  if ( name )
                     freeString( name );
               }
            }
         }
      } else if ( SUCCEEDED( pTable->QueryInterface( _uuidof( IDiaEnumSectionContribs ), (void**)&pSecContribs ) ) ) {
         printf( "SecContribs\n" );
         CComPtr<IDiaSectionContrib> pSecContrib;
         while ( SUCCEEDED( hr = pSecContribs->Next( 1, &pSecContrib, &celt ) ) && celt == 1 ) {
            DWORD rva;
            if ( pSecContrib->get_relativeVirtualAddress( &rva ) == S_OK ) {
               printf( "\taddr: 0x%.8X", rva );
               pSecContrib = NULL;
               CComPtr<IDiaSymbol> pSym;
               if ( psession->findSymbolByRVA( rva, SymTagNull, &pSym ) == S_OK ) {
                  BSTR name = NULL;
                  DWORD tag;
                  pSym->get_symTag( &tag );
                  pSym->get_name( &name );
                  printf( "    symbol: %ws (%ws)\n", name != NULL ? name : L"", szTags[ tag ] );
                  if ( name )
                     freeString( name );
               } else {
                  printf( "<no symbol found?>\n" );
               }
            } else {
               DWORD isect;
               DWORD offset;
               pSecContrib->get_addressSection( &isect );
               pSecContrib->get_addressOffset( &offset );
               printf( "\taddr: 0x%.4X:0x%.8X", isect, offset );
               pSecContrib = NULL;
               CComPtr<IDiaSymbol> pSym;
               if ( SUCCEEDED( psession->findSymbolByAddr( isect, offset, SymTagNull, &pSym ) ) ) {
                  BSTR name;
                  DWORD tag;
                  pSym->get_symTag( &tag );
                  pSym->get_name( &name );
                  printf( "    symbol: %ws (%ws)\n", name != NULL ? name : L"", szTags[ tag ] );
                  if ( name )
                     freeString( name );
               } else {
                  printf( "<no symbol found?>\n" );
               }         
            }
         }
      }

      pTable = NULL;
   }
   CComPtr<IDiaEnumSymbolsByAddr> pEnumByAddr;
   if ( FAILED( psession->getSymbolsByAddr( &pEnumByAddr ) ) )
      Fatal( "getSymbolsByAddr" );
   CComPtr<IDiaSymbol> pSym;
   if ( FAILED( pEnumByAddr->symbolByAddr( 1, 0, &pSym ) ) )
      Fatal( "symbolByAddr" );
   DWORD rvaLast = 0;
   if ( pSym->get_relativeVirtualAddress( &rvaLast ) == S_OK ) {
      pSym = 0;
      if ( FAILED( pEnumByAddr->symbolByRVA( rvaLast, &pSym ) ) )
         Fatal( "symbolByAddr" );
      printf( "Symbols in order\n" );
      do { 
         rvaLast = PrintNameAddr( pSym );
         pSym = 0;
         celt = 0;
         if ( FAILED( hr = pEnumByAddr->Next( 1, &pSym, &celt ) ) ) 
            break;
      } while ( celt == 1 );

      printf( "Symbols in reverse order\n" );
      pSym = 0;
      if ( FAILED( pEnumByAddr->symbolByRVA( rvaLast, &pSym ) ) )
         Fatal( "symbolByRva" );
      printf( "Symbols in order\n" );
      do { 
         rvaLast = PrintNameAddr( pSym );
         pSym = 0;
         celt = 0;
         if ( FAILED( hr = pEnumByAddr->Prev( 1, &pSym, &celt ) ) ) 
            break;
      } while ( celt == 1 );

      if ( FAILED( hr ) )
         Fatal( "Next" );
   }

}

void usage( int argc, char* argv[] )
{
   printf( "usage: %s <pdb-filename>\n", argv[0] );
   exit( -1 );
}

const char* diaPaths[] = {
      "msdia20.dll",
      "..\\bin\\msdia20.dll",
      "..\\..\\bin\\msdia20.dll",
      0
};

int main(int argc, char* argv[])
{

   if ( argc < 2 ) {
      usage(argc, argv);
   }

   HRESULT   hr;
#ifndef NOCOM
   hr = CoInitialize(NULL);
   if (FAILED(hr))
   {
      Fatal("CoInitialize failed\n");
   }
#endif

   {

      CComPtr<IDiaDataSource> pSource;
      // Initialize the COM library.

#ifdef NOCOM

#ifdef NOREG
      hr = NoRegCoCreate( "msdia20.dll", _uuidof( DiaSourceAlt ), _uuidof( IDiaDataSource ), (void **) &pSource );
#else
      hr = NoOleCoCreate( _uuidof( DiaSourceAlt ), _uuidof( IDiaDataSource ), (void **) &pSource );
#endif

#else
      // Obtain access to the provider.
      hr = CoCreateInstance(_uuidof( DiaSource ), NULL, CLSCTX_INPROC_SERVER, 
         _uuidof( IDiaDataSource ), (void **) &pSource);
      if ( hr == REGDB_E_CLASSNOTREG ) {
         for ( int i = 0; FAILED( hr ) && diaPaths[i] != 0; ++i ) {
            hr = NoRegCoCreate( diaPaths[i], _uuidof( DiaSource ), _uuidof( IDiaDataSource ), (void **) &pSource );
         }
      }
#endif
      if (FAILED(hr))
      {   
         Fatal("Could not CoCreate CLSID_DiaSource(Alt). Register msdia20.dll or add its location to your PATH." );
      }
      if ( argc > 2 ) {
         wchar_t name[ 256 ];
         mbstowcs( name, argv[ 2 ], 256 );
         Dump( argv[ 1 ], pSource, name );
         DumpLex( pglobal, 0 );
      } else {
         Dump( argv[ 1 ], pSource, NULL );
      }
   }
   pglobal = 0;
   psession= 0;
#ifndef NOCOM
   CoUninitialize();
#endif
   return 0;
}

Show:
© 2015 Microsoft