Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

246 lines
7.2 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. #include <windows.h>
  3. #include "tier1/strtools.h"
  4. #include <conio.h>
  5. #include "utlvector.h"
  6. #include <Dbghelp.h>
  7. #include "isqlwrapper.h"
  8. #include "CMiniDumpObject.h"
  9. extern ISQLWrapper *g_pSqlWrapper;
  10. CMiniDumpObject::CMiniDumpObject( const char *pszFilename, CUtlVector<module> *pKnownModuleList )
  11. {
  12. InitFromFilename( pszFilename, pKnownModuleList );
  13. }
  14. CMiniDumpObject::CMiniDumpObject( HANDLE pMiniDumpHandle, CUtlVector<module> *pKnownModuleList )
  15. {
  16. InitFromHandle( pMiniDumpHandle, pKnownModuleList );
  17. }
  18. void CMiniDumpObject::Init( HANDLE pszFileMap, CUtlVector<module> *pKnownModuleList )
  19. {
  20. PMINIDUMP_DIRECTORY miniDumpDir;
  21. PVOID pOutput;
  22. ULONG ulSize;
  23. if ( !pszFileMap )
  24. return;
  25. PVOID pMiniDump = MapViewOfFile( pszFileMap, FILE_MAP_READ, 0, 0, 0 );
  26. MiniDumpReadDumpStream( pMiniDump, ModuleListStream, &miniDumpDir, &pOutput, &ulSize );
  27. int numberOfModules = ((int *)pOutput)[0];
  28. MINIDUMP_MODULE *pModules = (MINIDUMP_MODULE *)((byte *)pOutput + sizeof(int));
  29. for ( int i = 0; i < numberOfModules; i++ )
  30. {
  31. MINIDUMP_MODULE *pCurrentModule = (pModules + i);
  32. module *newModule = new module;
  33. newModule->key = 0;
  34. newModule->knownVersion = false;
  35. int offset = pCurrentModule->ModuleNameRva;
  36. int nSizeOfName = *(int *)((byte *)pMiniDump + offset);
  37. char nameBuf[1024];
  38. char *pszName = (char *)(byte *)pMiniDump + offset + sizeof(int);
  39. int j = 0;
  40. for ( j = 0; j < nSizeOfName/2; j++ )
  41. {
  42. nameBuf[j] = *(pszName + j*2);
  43. }
  44. nameBuf[j] = 0;
  45. strcpy( newModule->name, nameBuf );
  46. newModule->versionInfo = GetVersionStruct(&pCurrentModule->VersionInfo);
  47. bool added = false;
  48. for ( int j = 0; j < pKnownModuleList->Count(); j++ )
  49. {
  50. if ( !Q_stricmp( strrchr( nameBuf, '\\' )+1, pKnownModuleList->Element( j ).name ) )
  51. {
  52. newModule->myType = pKnownModuleList->Element( j ).myType;
  53. if ( newModule->versionInfo == pKnownModuleList->Element(j).versionInfo )
  54. {
  55. newModule->key = pKnownModuleList->Element( j ).key;
  56. newModule->knownVersion = true;
  57. }
  58. else
  59. {
  60. newModule->knownVersion = false;
  61. }
  62. }
  63. if ( newModule->knownVersion )
  64. break;
  65. }
  66. switch ( newModule->myType )
  67. {
  68. case GOOD:
  69. m_goodModuleList.AddToTail( *newModule );
  70. added = true;
  71. break;
  72. case BAD:
  73. m_badModuleList.AddToTail( *newModule );
  74. added = true;
  75. break;
  76. default:
  77. m_unknownModuleList.AddToTail( *newModule );
  78. added = true;
  79. break;
  80. }
  81. if ( !added )
  82. {
  83. newModule->key = 0;
  84. newModule->myType = UNKNOWN;
  85. m_unknownModuleList.AddToTail( *newModule );
  86. }
  87. }
  88. UnmapViewOfFile( pMiniDump );
  89. }
  90. void CMiniDumpObject::InitFromHandle( HANDLE pMiniDumpHandle, CUtlVector<module> *pKnownModuleList )
  91. {
  92. if ( INVALID_HANDLE_VALUE != pMiniDumpHandle )
  93. {
  94. DWORD dwNumRead = 0;
  95. char szMdmp[ 5 ] = { 0 };
  96. if ( ReadFile( pMiniDumpHandle, (LPVOID)szMdmp, 4, &dwNumRead, NULL ) )
  97. {
  98. if ( !Q_strcmp( "MDMP", szMdmp ))
  99. {
  100. HANDLE hFileMap = CreateFileMapping( pMiniDumpHandle, NULL, PAGE_READONLY, 0, 0, NULL );
  101. Init( hFileMap, pKnownModuleList );
  102. }
  103. }
  104. }
  105. }
  106. void CMiniDumpObject::InitFromFilename( const char *pszFilename, CUtlVector<module> *pKnownModuleList )
  107. {
  108. HANDLE hFile = CreateFile(pszFilename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  109. InitFromHandle( hFile, pKnownModuleList );
  110. }
  111. void CMiniDumpObject::GetVersionString( char *pszOutput, version *pVersionInfo )
  112. {
  113. char firstHighVer[10];
  114. char firstLowVer[10];
  115. char secondHighVer[10];
  116. char secondLowVer[10];
  117. int firstHigh = pVersionInfo->v1;
  118. int secondHigh = pVersionInfo->v2;
  119. int firstLow = pVersionInfo->v3;
  120. int secondLow = pVersionInfo->v4;
  121. itoa( firstHigh, firstHighVer, 10 );
  122. itoa( firstLow, firstLowVer, 10 );
  123. itoa( secondHigh, secondHighVer, 10 );
  124. itoa( secondLow, secondLowVer, 10 );
  125. strcat( pszOutput, firstHighVer );
  126. strcat( pszOutput, "." );
  127. strcat( pszOutput, secondHighVer );
  128. strcat( pszOutput, "." );
  129. strcat( pszOutput, firstLowVer );
  130. strcat( pszOutput, "." );
  131. strcat( pszOutput, secondLowVer );
  132. }
  133. version CMiniDumpObject::GetVersionStruct( VS_FIXEDFILEINFO *pVersionInfo )
  134. {
  135. version returnVersion;
  136. int highVal = pVersionInfo->dwFileVersionMS;
  137. int lowVal = pVersionInfo->dwFileVersionLS;
  138. returnVersion.v1 = highVal >> 16;
  139. returnVersion.v2 = (highVal << 16)>>16;
  140. returnVersion.v3 = lowVal >> 16;
  141. returnVersion.v4 = (lowVal << 16)>>16;
  142. return returnVersion;
  143. }
  144. int CMiniDumpObject::ModuleListToListPanel( vgui::ListPanel *pTokenList, CUtlVector<module> *pModuleList, bool bCumulative, int startingModule)
  145. {
  146. char keyNameBuf[1024] = "module";
  147. char modNumBuf[4] = "";
  148. int moduleNumber = startingModule;
  149. for ( int i = 0; i < pModuleList->Count(); i++ )
  150. {
  151. char version[20] = "";
  152. moduleNumber++;
  153. itoa( moduleNumber, modNumBuf, 10 );
  154. strcat( keyNameBuf, modNumBuf );
  155. module currentModule = pModuleList->Element(i);
  156. GetVersionString( version, &currentModule.versionInfo );
  157. bool bRepeat = false;
  158. if ( bCumulative )
  159. {
  160. int tokenCount = pTokenList->GetItemCount();
  161. for ( int j = 0; j < tokenCount; j++ )
  162. {
  163. KeyValues *kv = pTokenList->GetItem( j );
  164. const char *moduleName = strrchr( kv->GetString( "name" ), '\\' );
  165. const char *secondModuleName = strrchr( currentModule.name, '\\' );
  166. const char *checksum = kv->GetString( "checksum" );
  167. if ( !stricmp( moduleName, secondModuleName ) && !strcmp( kv->GetString( "version" ), version ) )
  168. {
  169. int count = kv->GetInt( "count" );
  170. int key = kv->GetInt( "key" );
  171. KeyValues *newKv = new KeyValues( keyNameBuf, "name", kv->GetString("name"), "checksum", checksum );
  172. newKv->SetString( "version", version );
  173. newKv->SetInt( "count", count+1 );
  174. newKv->SetInt( "key", key );
  175. newKv->SetColor( "cellcolor", kv->GetColor( "cellcolor" ) );
  176. pTokenList->RemoveItem( j );
  177. pTokenList->AddItem( newKv, j, false, false );
  178. bRepeat = true;
  179. break;
  180. }
  181. }
  182. }
  183. if ( !bRepeat )
  184. {
  185. KeyValues *kv = new KeyValues( keyNameBuf, "name", currentModule.name);
  186. kv->SetString( "version", version );
  187. kv->SetInt( "key", currentModule.key );
  188. if ( bCumulative )
  189. {
  190. kv->SetInt( "count", 1 );
  191. }
  192. int colorValue = 255;
  193. if ( !currentModule.knownVersion )
  194. colorValue = 155;
  195. switch ( currentModule.myType )
  196. {
  197. case GOOD:
  198. kv->SetColor( "cellcolor", Color(0,colorValue,0,255));
  199. break;
  200. case BAD:
  201. kv->SetColor( "cellcolor", Color(colorValue,0,0,255));
  202. break;
  203. default:
  204. kv->SetColor( "cellcolor", Color(255,255,0,255));
  205. break;
  206. }
  207. pTokenList->AddItem( kv, i, false, false );
  208. bRepeat = false;
  209. }
  210. strcpy( keyNameBuf, "module");
  211. }
  212. return moduleNumber;
  213. }
  214. void CMiniDumpObject::PopulateListPanel( vgui::ListPanel *pTokenList, bool bCumulative )
  215. {
  216. int nextModuleNumber = 0;
  217. nextModuleNumber = ModuleListToListPanel( pTokenList, &m_goodModuleList, bCumulative, nextModuleNumber );
  218. nextModuleNumber = ModuleListToListPanel( pTokenList, &m_unknownModuleList, bCumulative, nextModuleNumber );
  219. nextModuleNumber = ModuleListToListPanel( pTokenList, &m_badModuleList, bCumulative, nextModuleNumber);
  220. ModuleListToListPanel( pTokenList, &m_badChecksumList, bCumulative, nextModuleNumber );
  221. }