// source file line data structure typedef struct _IMAGEHLP_LINE { DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_LINE) DWORD Key; // internal DWORD LineNumber; // line number in file PCHAR FileName; // full filename DWORD Address; // first instruction of line } IMAGEHLP_LINE, *PIMAGEHLP_LINE; #ifndef SYMOPT_LOAD_LINES #define SYMOPT_LOAD_LINES 0x00000010 #endif // SYMOPT_LOAD_LINES #ifndef SYMOPT_OMAP_FIND_NEAREST #define SYMOPT_OMAP_FIND_NEAREST 0x00000020 #endif // SYMOPT_OMAP_FIND_NEAREST // Typedefs for the new source and line functions. typedef BOOL (__stdcall *PFNSYMGETLINEFROMADDR) ( IN HANDLE hProcess , IN DWORD dwAddr , OUT PDWORD pdwDisplacement , OUT PIMAGEHLP_LINE Line ) ; typedef BOOL (__stdcall *PFNSYMGETLINEFROMNAME) ( IN HANDLE hProcess , IN LPSTR ModuleName , IN LPSTR FileName , IN DWORD dwLineNumber , OUT PLONG plDisplacement, IN OUT PIMAGEHLP_LINE Line ) ; typedef BOOL (__stdcall *PFNSYMGETLINENEXT) ( IN HANDLE hProcess , IN OUT PIMAGEHLP_LINE Line ); typedef BOOL (__stdcall *PFNSYMGETLINEPREV) ( IN HANDLE hProcess , IN OUT PIMAGEHLP_LINE Line ); typedef BOOL (__stdcall *PFNSYMMATCHFILENAME) ( IN LPSTR FileName , IN LPSTR Match , OUT LPSTR * FileNameStop , OUT LPSTR * MatchStop ) ; // The function pointers to the new symbol engine source and line // functions. PFNSYMGETLINEFROMADDR m_pfnSymGetLineFromAddr ; PFNSYMGETLINEFROMNAME m_pfnSymGetLineFromName ; PFNSYMGETLINENEXT m_pfnSymGetLineNext ; PFNSYMGETLINEPREV m_pfnSymGetLinePrev ; PFNSYMMATCHFILENAME m_pfnSymMatchFileName ; VOID SymbolEngineInit ( void ) { HINSTANCE hInstImageHlp = GetModuleHandleA ( "IMAGEHLP.DLL" ) ; m_pfnSymGetLineFromAddr = (PFNSYMGETLINEFROMADDR)GetProcAddress(hInstImageHlp , "SymGetLineFromAddr"); if ( NULL == m_pfnSymGetLineFromAddr ) { m_pfnSymGetLineFromName = NULL ; m_pfnSymGetLineNext = NULL ; m_pfnSymGetLinePrev = NULL ; m_pfnSymMatchFileName = NULL ; } else { m_pfnSymGetLineFromName = (PFNSYMGETLINEFROMNAME)GetProcAddress(hInstImageHlp , "SymGetLineFromName"); m_pfnSymGetLineNext = (PFNSYMGETLINENEXT)GetProcAddress ( hInstImageHlp , "SymGetLineNext" ) ; m_pfnSymGetLinePrev = (PFNSYMGETLINEPREV)GetProcAddress ( hInstImageHlp , "SymGetLinePrev" ) ; m_pfnSymMatchFileName = (PFNSYMMATCHFILENAME)GetProcAddress (hInstImageHlp , "SymMatchFileName"); } } BOOL SymGetLineFromAddr ( IN HANDLE m_hProcess, IN DWORD dwAddr , OUT PDWORD pdwDisplacement , OUT PIMAGEHLP_LINE Line ) { if ( NULL == m_pfnSymGetLineFromAddr ) { return ( FALSE ) ; } // Just return whatever the main function returned. return ( m_pfnSymGetLineFromAddr( m_hProcess , dwAddr , pdwDisplacement , Line ) ) ; } BOOL SymGetLineFromName ( IN HANDLE m_hProcess, IN LPSTR ModuleName , IN LPSTR FileName , IN DWORD dwLineNumber , OUT PLONG plDisplacement , IN OUT PIMAGEHLP_LINE Line ) { if ( NULL == m_pfnSymGetLineFromName ) { return ( FALSE ) ; } return ( m_pfnSymGetLineFromName ( m_hProcess , ModuleName , FileName , dwLineNumber , plDisplacement , Line ) ) ; } BOOL SymGetLineNext ( IN HANDLE m_hProcess,IN OUT PIMAGEHLP_LINE Line ) { if ( NULL == m_pfnSymGetLineNext ) { return ( FALSE ) ; } return ( m_pfnSymGetLineNext ( m_hProcess , Line ) ) ; } BOOL SymGetLinePrev ( IN HANDLE m_hProcess,IN OUT PIMAGEHLP_LINE Line ) { if ( NULL == m_pfnSymGetLinePrev ) { return ( FALSE ) ; } return ( m_pfnSymGetLinePrev ( m_hProcess , Line ) ) ; } // What is this? BOOL SymMatchFileName ( IN LPSTR FileName , IN LPSTR Match , OUT LPSTR * FileNameStop , OUT LPSTR * MatchStop ) { if ( NULL == m_pfnSymMatchFileName ) { return ( FALSE ) ; } return ( m_pfnSymMatchFileName ( FileName , Match , FileNameStop , MatchStop ) ) ; }