1
This commit is contained in:
246
utils/mdmpRipper/CMiniDumpObject.cpp
Normal file
246
utils/mdmpRipper/CMiniDumpObject.cpp
Normal file
@ -0,0 +1,246 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
#include <windows.h>
|
||||
#include "tier1/strtools.h"
|
||||
#include <conio.h>
|
||||
#include "utlvector.h"
|
||||
#include <Dbghelp.h>
|
||||
#include "isqlwrapper.h"
|
||||
#include "CMiniDumpObject.h"
|
||||
|
||||
extern ISQLWrapper *g_pSqlWrapper;
|
||||
|
||||
CMiniDumpObject::CMiniDumpObject( const char *pszFilename, CUtlVector<module> *pKnownModuleList )
|
||||
{
|
||||
InitFromFilename( pszFilename, pKnownModuleList );
|
||||
}
|
||||
|
||||
CMiniDumpObject::CMiniDumpObject( HANDLE pMiniDumpHandle, CUtlVector<module> *pKnownModuleList )
|
||||
{
|
||||
InitFromHandle( pMiniDumpHandle, pKnownModuleList );
|
||||
}
|
||||
|
||||
void CMiniDumpObject::Init( HANDLE pszFileMap, CUtlVector<module> *pKnownModuleList )
|
||||
{
|
||||
PMINIDUMP_DIRECTORY miniDumpDir;
|
||||
PVOID pOutput;
|
||||
ULONG ulSize;
|
||||
|
||||
if ( !pszFileMap )
|
||||
return;
|
||||
PVOID pMiniDump = MapViewOfFile( pszFileMap, FILE_MAP_READ, 0, 0, 0 );
|
||||
|
||||
MiniDumpReadDumpStream( pMiniDump, ModuleListStream, &miniDumpDir, &pOutput, &ulSize );
|
||||
|
||||
int numberOfModules = ((int *)pOutput)[0];
|
||||
MINIDUMP_MODULE *pModules = (MINIDUMP_MODULE *)((byte *)pOutput + sizeof(int));
|
||||
|
||||
for ( int i = 0; i < numberOfModules; i++ )
|
||||
{
|
||||
MINIDUMP_MODULE *pCurrentModule = (pModules + i);
|
||||
module *newModule = new module;
|
||||
newModule->key = 0;
|
||||
newModule->knownVersion = false;
|
||||
int offset = pCurrentModule->ModuleNameRva;
|
||||
int nSizeOfName = *(int *)((byte *)pMiniDump + offset);
|
||||
char nameBuf[1024];
|
||||
char *pszName = (char *)(byte *)pMiniDump + offset + sizeof(int);
|
||||
int j = 0;
|
||||
for ( j = 0; j < nSizeOfName/2; j++ )
|
||||
{
|
||||
nameBuf[j] = *(pszName + j*2);
|
||||
}
|
||||
nameBuf[j] = 0;
|
||||
strcpy( newModule->name, nameBuf );
|
||||
newModule->versionInfo = GetVersionStruct(&pCurrentModule->VersionInfo);
|
||||
bool added = false;
|
||||
|
||||
for ( int j = 0; j < pKnownModuleList->Count(); j++ )
|
||||
{
|
||||
if ( !Q_stricmp( strrchr( nameBuf, '\\' )+1, pKnownModuleList->Element( j ).name ) )
|
||||
{
|
||||
newModule->myType = pKnownModuleList->Element( j ).myType;
|
||||
|
||||
if ( newModule->versionInfo == pKnownModuleList->Element(j).versionInfo )
|
||||
{
|
||||
newModule->key = pKnownModuleList->Element( j ).key;
|
||||
newModule->knownVersion = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
newModule->knownVersion = false;
|
||||
}
|
||||
}
|
||||
if ( newModule->knownVersion )
|
||||
break;
|
||||
}
|
||||
switch ( newModule->myType )
|
||||
{
|
||||
case GOOD:
|
||||
m_goodModuleList.AddToTail( *newModule );
|
||||
added = true;
|
||||
break;
|
||||
case BAD:
|
||||
m_badModuleList.AddToTail( *newModule );
|
||||
added = true;
|
||||
break;
|
||||
default:
|
||||
m_unknownModuleList.AddToTail( *newModule );
|
||||
added = true;
|
||||
break;
|
||||
}
|
||||
if ( !added )
|
||||
{
|
||||
newModule->key = 0;
|
||||
newModule->myType = UNKNOWN;
|
||||
m_unknownModuleList.AddToTail( *newModule );
|
||||
}
|
||||
}
|
||||
UnmapViewOfFile( pMiniDump );
|
||||
}
|
||||
|
||||
void CMiniDumpObject::InitFromHandle( HANDLE pMiniDumpHandle, CUtlVector<module> *pKnownModuleList )
|
||||
{
|
||||
if ( INVALID_HANDLE_VALUE != pMiniDumpHandle )
|
||||
{
|
||||
DWORD dwNumRead = 0;
|
||||
char szMdmp[ 5 ] = { 0 };
|
||||
if ( ReadFile( pMiniDumpHandle, (LPVOID)szMdmp, 4, &dwNumRead, NULL ) )
|
||||
{
|
||||
if ( !Q_strcmp( "MDMP", szMdmp ))
|
||||
{
|
||||
HANDLE hFileMap = CreateFileMapping( pMiniDumpHandle, NULL, PAGE_READONLY, 0, 0, NULL );
|
||||
Init( hFileMap, pKnownModuleList );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CMiniDumpObject::InitFromFilename( const char *pszFilename, CUtlVector<module> *pKnownModuleList )
|
||||
{
|
||||
HANDLE hFile = CreateFile(pszFilename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
InitFromHandle( hFile, pKnownModuleList );
|
||||
}
|
||||
|
||||
void CMiniDumpObject::GetVersionString( char *pszOutput, version *pVersionInfo )
|
||||
{
|
||||
char firstHighVer[10];
|
||||
char firstLowVer[10];
|
||||
char secondHighVer[10];
|
||||
char secondLowVer[10];
|
||||
|
||||
int firstHigh = pVersionInfo->v1;
|
||||
int secondHigh = pVersionInfo->v2;
|
||||
int firstLow = pVersionInfo->v3;
|
||||
int secondLow = pVersionInfo->v4;
|
||||
|
||||
itoa( firstHigh, firstHighVer, 10 );
|
||||
itoa( firstLow, firstLowVer, 10 );
|
||||
itoa( secondHigh, secondHighVer, 10 );
|
||||
itoa( secondLow, secondLowVer, 10 );
|
||||
|
||||
strcat( pszOutput, firstHighVer );
|
||||
strcat( pszOutput, "." );
|
||||
strcat( pszOutput, secondHighVer );
|
||||
strcat( pszOutput, "." );
|
||||
strcat( pszOutput, firstLowVer );
|
||||
strcat( pszOutput, "." );
|
||||
strcat( pszOutput, secondLowVer );
|
||||
}
|
||||
|
||||
version CMiniDumpObject::GetVersionStruct( VS_FIXEDFILEINFO *pVersionInfo )
|
||||
{
|
||||
version returnVersion;
|
||||
int highVal = pVersionInfo->dwFileVersionMS;
|
||||
int lowVal = pVersionInfo->dwFileVersionLS;
|
||||
returnVersion.v1 = highVal >> 16;
|
||||
returnVersion.v2 = (highVal << 16)>>16;
|
||||
returnVersion.v3 = lowVal >> 16;
|
||||
returnVersion.v4 = (lowVal << 16)>>16;
|
||||
|
||||
return returnVersion;
|
||||
}
|
||||
|
||||
int CMiniDumpObject::ModuleListToListPanel( vgui::ListPanel *pTokenList, CUtlVector<module> *pModuleList, bool bCumulative, int startingModule)
|
||||
{
|
||||
char keyNameBuf[1024] = "module";
|
||||
char modNumBuf[4] = "";
|
||||
int moduleNumber = startingModule;
|
||||
|
||||
for ( int i = 0; i < pModuleList->Count(); i++ )
|
||||
{
|
||||
char version[20] = "";
|
||||
moduleNumber++;
|
||||
itoa( moduleNumber, modNumBuf, 10 );
|
||||
strcat( keyNameBuf, modNumBuf );
|
||||
module currentModule = pModuleList->Element(i);
|
||||
GetVersionString( version, ¤tModule.versionInfo );
|
||||
bool bRepeat = false;
|
||||
|
||||
if ( bCumulative )
|
||||
{
|
||||
int tokenCount = pTokenList->GetItemCount();
|
||||
for ( int j = 0; j < tokenCount; j++ )
|
||||
{
|
||||
KeyValues *kv = pTokenList->GetItem( j );
|
||||
const char *moduleName = strrchr( kv->GetString( "name" ), '\\' );
|
||||
const char *secondModuleName = strrchr( currentModule.name, '\\' );
|
||||
const char *checksum = kv->GetString( "checksum" );
|
||||
|
||||
if ( !stricmp( moduleName, secondModuleName ) && !strcmp( kv->GetString( "version" ), version ) )
|
||||
{
|
||||
int count = kv->GetInt( "count" );
|
||||
int key = kv->GetInt( "key" );
|
||||
KeyValues *newKv = new KeyValues( keyNameBuf, "name", kv->GetString("name"), "checksum", checksum );
|
||||
newKv->SetString( "version", version );
|
||||
newKv->SetInt( "count", count+1 );
|
||||
newKv->SetInt( "key", key );
|
||||
newKv->SetColor( "cellcolor", kv->GetColor( "cellcolor" ) );
|
||||
pTokenList->RemoveItem( j );
|
||||
pTokenList->AddItem( newKv, j, false, false );
|
||||
bRepeat = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !bRepeat )
|
||||
{
|
||||
KeyValues *kv = new KeyValues( keyNameBuf, "name", currentModule.name);
|
||||
kv->SetString( "version", version );
|
||||
kv->SetInt( "key", currentModule.key );
|
||||
if ( bCumulative )
|
||||
{
|
||||
kv->SetInt( "count", 1 );
|
||||
}
|
||||
int colorValue = 255;
|
||||
if ( !currentModule.knownVersion )
|
||||
colorValue = 155;
|
||||
switch ( currentModule.myType )
|
||||
{
|
||||
case GOOD:
|
||||
kv->SetColor( "cellcolor", Color(0,colorValue,0,255));
|
||||
break;
|
||||
case BAD:
|
||||
kv->SetColor( "cellcolor", Color(colorValue,0,0,255));
|
||||
break;
|
||||
default:
|
||||
kv->SetColor( "cellcolor", Color(255,255,0,255));
|
||||
break;
|
||||
}
|
||||
pTokenList->AddItem( kv, i, false, false );
|
||||
bRepeat = false;
|
||||
}
|
||||
strcpy( keyNameBuf, "module");
|
||||
}
|
||||
return moduleNumber;
|
||||
}
|
||||
|
||||
|
||||
void CMiniDumpObject::PopulateListPanel( vgui::ListPanel *pTokenList, bool bCumulative )
|
||||
{
|
||||
int nextModuleNumber = 0;
|
||||
nextModuleNumber = ModuleListToListPanel( pTokenList, &m_goodModuleList, bCumulative, nextModuleNumber );
|
||||
nextModuleNumber = ModuleListToListPanel( pTokenList, &m_unknownModuleList, bCumulative, nextModuleNumber );
|
||||
nextModuleNumber = ModuleListToListPanel( pTokenList, &m_badModuleList, bCumulative, nextModuleNumber);
|
||||
ModuleListToListPanel( pTokenList, &m_badChecksumList, bCumulative, nextModuleNumber );
|
||||
}
|
Reference in New Issue
Block a user