Game client codebase including: - CharacterActionControl: Character and creature management - GlobalScript: Network, items, skills, quests, utilities - RYLClient: Main client application with GUI and event handlers - Engine: 3D rendering engine (RYLGL) - MemoryManager: Custom memory allocation - Library: Third-party dependencies (DirectX, boost, etc.) - Tools: Development utilities 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
913 lines
22 KiB
C++
913 lines
22 KiB
C++
#include "StdAfx.h"
|
|
#include ".\dumpfileparser.h"
|
|
#include ".\resource.h"
|
|
#include ".\DumpStatisticsDlg.h"
|
|
|
|
struct CompareVectorfVersion
|
|
{
|
|
bool operator () (const CDumpLog* lhs, const CDumpLog* rhs) const
|
|
{
|
|
int cnt = 0;
|
|
if( lhs->fVersion == rhs->fVersion )
|
|
{
|
|
if( (cnt = strcmp( lhs->szFileName, rhs->szFileName ) ) == 0 )
|
|
{
|
|
return (strcmp( lhs->szFaultAddress, rhs->szFaultAddress ) < 0 );
|
|
}
|
|
else
|
|
return ( cnt < 0);
|
|
}
|
|
return lhs->fVersion < rhs->fVersion;
|
|
}
|
|
};
|
|
|
|
|
|
struct CompareVectorFaultAddress
|
|
{
|
|
bool operator () (const LPFAULTLIST lhs, const LPFAULTLIST rhs) const
|
|
{
|
|
if( lhs->dwVersion == rhs->dwVersion )
|
|
{
|
|
return (strcmp( lhs->szFileName, rhs->szFileName ) < 0 );
|
|
}
|
|
return lhs->dwVersion < rhs->dwVersion ;
|
|
|
|
}
|
|
};
|
|
|
|
|
|
CDumpFileParser::CDumpFileParser( CDumpStatisticsDlg* pDlg )
|
|
{
|
|
m_pDlg = pDlg ;
|
|
CWnd* pWnd = m_pDlg->GetDlgItem( IDC_DUMPFILE ) ;
|
|
pWnd->SetWindowText( " " ) ;
|
|
m_pDlg->UpdateData() ;
|
|
m_pDlg->UpdateData( FALSE ) ;
|
|
m_uiDumpSize = 0 ;
|
|
}
|
|
|
|
CDumpFileParser::~CDumpFileParser(void)
|
|
{
|
|
std::vector< LPDUMPDIRECTORYINFO >::iterator iterVer = m_vecDumpDirectoryInfo.begin() ;
|
|
while( iterVer != m_vecDumpDirectoryInfo.end() )
|
|
{
|
|
LPDUMPDIRECTORYINFO lpDumpDirectoryInfo = ( *iterVer ) ;
|
|
std::vector< LPFILENAME >::iterator iterFile = lpDumpDirectoryInfo->vecDumpFileInfo.begin() ; // Vector Date Direcoty
|
|
while( iterFile != lpDumpDirectoryInfo->vecDumpFileInfo.end() )
|
|
{
|
|
if( (*iterFile ) )
|
|
{
|
|
delete ( *iterFile );
|
|
( *iterFile ) = NULL;
|
|
}
|
|
iterFile++;
|
|
}
|
|
lpDumpDirectoryInfo->vecDumpFileInfo.clear() ;
|
|
|
|
if ( ( *iterVer ) )
|
|
{
|
|
delete ( *iterVer ) ;
|
|
( *iterVer ) = NULL ;
|
|
}
|
|
++ iterVer ;
|
|
}
|
|
m_vecDumpDirectoryInfo.clear() ;
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
// 하위 디렉토리를 전부 검색하여 파일을 덤프 파일 목록과 디렉토리 목록을 만든다.
|
|
//----------------------------------------------------------------------------
|
|
VOID
|
|
CDumpFileParser::FindDumpDirectory()
|
|
{
|
|
m_uiDumpSize = 0;
|
|
FindDumpDirectory( m_szCurrentDirectory );
|
|
CWnd* pProgressWnd = m_pDlg->GetDlgItem( IDC_DUMPPROGRESS ) ;
|
|
pProgressWnd->SendMessage( PBM_SETRANGE, 0, MAKELPARAM( 0,m_uiDumpSize ) ) ;
|
|
pProgressWnd->SendMessage( PBM_SETPOS, 0, 0 ) ;
|
|
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
// 해당 디렉토리에서의 파일 찾기
|
|
//----------------------------------------------------------------------------
|
|
VOID
|
|
CDumpFileParser::FindDumpFile( LPDUMPDIRECTORYINFO pDirectoryInfo )
|
|
{
|
|
HANDLE hSrch ;
|
|
WIN32_FIND_DATA wfd ;
|
|
BOOL bResult = TRUE ;
|
|
CHAR szDirectory[ MAX_PATH ] ;
|
|
CHAR szTempDirectory[ MAX_PATH ] ;
|
|
UINT uiDirectoryNum = 0 ;
|
|
|
|
strcpy( szDirectory, pDirectoryInfo->szDirectory ) ;
|
|
strcpy( szTempDirectory, pDirectoryInfo->szDirectory ) ;
|
|
strcat( szDirectory, "\\*.txt" ) ;
|
|
hSrch = FindFirstFile( szDirectory, &wfd ) ;
|
|
|
|
if ( hSrch == INVALID_HANDLE_VALUE )
|
|
{
|
|
return ;
|
|
}
|
|
|
|
while( bResult )
|
|
{
|
|
if ( wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
|
|
{
|
|
if ( !strcmp( wfd.cFileName, "." ) )
|
|
{
|
|
bResult = FindNextFile( hSrch, &wfd ) ;
|
|
continue ;
|
|
}
|
|
|
|
if ( !strcmp( wfd.cFileName, ".." ) )
|
|
{
|
|
bResult = FindNextFile( hSrch, &wfd ) ;
|
|
continue ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
wsprintf( szTempDirectory, "%s\\%s", pDirectoryInfo->szDirectory, wfd.cFileName ) ;
|
|
LPFILENAME lpFileName ;
|
|
lpFileName = new FILENAME ;
|
|
strcpy( lpFileName->szFileName, szTempDirectory ) ;
|
|
pDirectoryInfo->vecDumpFileInfo.push_back( lpFileName ) ;
|
|
m_uiDumpSize += 1;
|
|
}
|
|
bResult = FindNextFile( hSrch, &wfd ) ;
|
|
}
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
// 하위 디렉토리를 전부 검색하여 파일을 덤프 파일 목록과 디렉토리 목록을 만든다.
|
|
//----------------------------------------------------------------------------
|
|
VOID
|
|
CDumpFileParser::FindDumpDirectory( const char* path )
|
|
{
|
|
HANDLE hSrch ;
|
|
WIN32_FIND_DATA wfd ;
|
|
BOOL bResult = TRUE ;
|
|
CHAR szDirectory[ MAX_PATH ] ;
|
|
CHAR szTempDirectory[ MAX_PATH ] ;
|
|
|
|
strcpy( szDirectory, path ) ;
|
|
strcpy( szTempDirectory, path ) ;
|
|
strcat( szDirectory, "\\*.*" ) ;
|
|
hSrch = FindFirstFile( szDirectory, &wfd ) ;
|
|
|
|
if ( hSrch == INVALID_HANDLE_VALUE )
|
|
{
|
|
return ;
|
|
}
|
|
|
|
while( bResult )
|
|
{
|
|
if ( wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
|
|
{
|
|
if ( !strcmp( wfd.cFileName, "." ) )
|
|
{
|
|
bResult = FindNextFile( hSrch, &wfd ) ;
|
|
continue ;
|
|
}
|
|
|
|
if ( !strcmp( wfd.cFileName, ".." ) )
|
|
{
|
|
bResult = FindNextFile( hSrch, &wfd ) ;
|
|
continue ;
|
|
}
|
|
|
|
if ( !strcmp( wfd.cFileName, "sort") ) //sort 디렉토리는 패스
|
|
{
|
|
bResult = FindNextFile( hSrch, &wfd ) ;
|
|
continue;
|
|
}
|
|
|
|
LPDUMPDIRECTORYINFO pDumpDirectory ;
|
|
pDumpDirectory = new DUMPDIRECTORYINFO ;
|
|
wsprintf( szTempDirectory, "%s\\%s", path, wfd.cFileName ) ;
|
|
strcpy( pDumpDirectory->szDirectory, szTempDirectory ) ;
|
|
FindDumpFile( pDumpDirectory );
|
|
m_vecDumpDirectoryInfo.push_back( pDumpDirectory );
|
|
|
|
FindDumpDirectory( szTempDirectory );
|
|
|
|
}
|
|
bResult = FindNextFile( hSrch, &wfd ) ;
|
|
}
|
|
FindClose( hSrch ) ;
|
|
}
|
|
|
|
/*
|
|
//-----------------------------------------------------------------
|
|
// Date디렉토리를 찾는다.
|
|
//-----------------------------------------------------------------
|
|
UINT CDumpFileParser::FindDumpDateDirectory( LPDUMPDIRECTORYINFO lpDumpInfo )
|
|
{
|
|
HANDLE hSrch ;
|
|
WIN32_FIND_DATA wfd ;
|
|
BOOL bResult = TRUE ;
|
|
CHAR szDirectory[ MAX_PATH ] ;
|
|
CHAR szTempDirectory[ MAX_PATH ] ;
|
|
UINT uiDirectoryNum = 0 ;
|
|
|
|
strcpy( szDirectory, lpDumpInfo->szVerDirectory ) ;
|
|
strcpy( szTempDirectory, lpDumpInfo->szVerDirectory ) ;
|
|
strcat( szDirectory, "\\*.*" ) ;
|
|
hSrch = FindFirstFile( szDirectory, &wfd ) ;
|
|
|
|
if ( hSrch == INVALID_HANDLE_VALUE )
|
|
{
|
|
return 0 ;
|
|
}
|
|
|
|
while( bResult )
|
|
{
|
|
if ( wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
|
|
{
|
|
if ( !strcmp( wfd.cFileName, "." ) )
|
|
{
|
|
bResult = FindNextFile( hSrch, &wfd ) ;
|
|
continue ;
|
|
}
|
|
|
|
if ( !strcmp( wfd.cFileName, ".." ) )
|
|
{
|
|
bResult = FindNextFile( hSrch, &wfd ) ;
|
|
continue ;
|
|
}
|
|
wsprintf( szTempDirectory, "%s\\%s", lpDumpInfo, wfd.cFileName ) ;
|
|
LPDUMPFILEINFO lpTmpDumpFileInfo ;
|
|
lpTmpDumpFileInfo = new DUMPFILEINFO ;
|
|
strcpy( lpTmpDumpFileInfo->szDateDirectory, szTempDirectory ) ;
|
|
lpDumpInfo->vecDumpFileInfo.push_back( lpTmpDumpFileInfo ) ;
|
|
lpTmpDumpFileInfo->uiDirectoryNum = FindDumpFile( lpTmpDumpFileInfo ) ;
|
|
m_uiDumpSize += lpTmpDumpFileInfo->uiDirectoryNum ;
|
|
++ uiDirectoryNum ;
|
|
}
|
|
bResult = FindNextFile( hSrch, &wfd ) ;
|
|
}
|
|
|
|
CWnd* pProgressWnd = m_pDlg->GetDlgItem( IDC_DUMPPROGRESS ) ;
|
|
pProgressWnd->SendMessage( PBM_SETRANGE, 0, MAKELPARAM( 0,m_uiDumpSize ) ) ;
|
|
pProgressWnd->SendMessage( PBM_SETPOS, 0, 0 ) ;
|
|
|
|
return uiDirectoryNum ;
|
|
}
|
|
|
|
//-----------------------------------------------------------------
|
|
// Date디렉토리 안의 모든 파일들을 찾는다.
|
|
//-----------------------------------------------------------------
|
|
UINT CDumpFileParser::FindDumpFile( LPDUMPFILEINFO lpDumpFileInfo )
|
|
{
|
|
HANDLE hSrch ;
|
|
WIN32_FIND_DATA wfd ;
|
|
BOOL bResult = TRUE ;
|
|
CHAR szDirectory[ MAX_PATH ] ;
|
|
CHAR szTempDirectory[ MAX_PATH ] ;
|
|
UINT uiDirectoryNum = 0 ;
|
|
|
|
strcpy( szDirectory, lpDumpFileInfo->szDateDirectory ) ;
|
|
strcpy( szTempDirectory, lpDumpFileInfo->szDateDirectory ) ;
|
|
strcat( szDirectory, "\\*.txt" ) ;
|
|
hSrch = FindFirstFile( szDirectory, &wfd ) ;
|
|
|
|
if ( hSrch == INVALID_HANDLE_VALUE )
|
|
{
|
|
return 0 ;
|
|
}
|
|
|
|
while( bResult )
|
|
{
|
|
if ( wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
|
|
{
|
|
if ( !strcmp( wfd.cFileName, "." ) )
|
|
{
|
|
bResult = FindNextFile( hSrch, &wfd ) ;
|
|
continue ;
|
|
}
|
|
|
|
if ( !strcmp( wfd.cFileName, ".." ) )
|
|
{
|
|
bResult = FindNextFile( hSrch, &wfd ) ;
|
|
continue ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
wsprintf( szTempDirectory, "%s\\%s", lpDumpFileInfo->szDateDirectory, wfd.cFileName ) ;
|
|
LPFILENAME lpFileName ;
|
|
lpFileName = new FILENAME ;
|
|
strcpy( lpFileName->szFileName, szTempDirectory ) ;
|
|
lpDumpFileInfo->vecFileName.push_back( lpFileName ) ;
|
|
++ uiDirectoryNum ;
|
|
}
|
|
bResult = FindNextFile( hSrch, &wfd ) ;
|
|
}
|
|
|
|
return uiDirectoryNum ;
|
|
}
|
|
*/
|
|
|
|
//-----------------------------------------------------------------------------------------------
|
|
VOID CDumpFileParser::LoadDumpFile()
|
|
{
|
|
HRESULT hr = S_OK ;
|
|
FILE* pStream = NULL ;
|
|
char strRead[MAX_PATH] ;
|
|
char tempDirectory[MAX_PATH] ;
|
|
int Count = 0 ;
|
|
|
|
::GetCurrentDirectory( MAX_PATH, tempDirectory );
|
|
CProgressCtrl* pProgressWnd = (CProgressCtrl*)(m_pDlg->GetDlgItem( IDC_DUMPPROGRESS ) );
|
|
CWnd* pWnd = m_pDlg->GetDlgItem( IDC_DUMPFILE ) ;
|
|
|
|
|
|
LPDUMPMETADATA lpMetaData ;
|
|
lpMetaData = new DUMPMETADATA ;
|
|
|
|
std::vector< LPDUMPDIRECTORYINFO >::iterator iterVer = m_vecDumpDirectoryInfo.begin() ;
|
|
while( iterVer != m_vecDumpDirectoryInfo.end() )
|
|
{
|
|
LPDUMPDIRECTORYINFO lpDumpDirectoryInfo = ( *iterVer ) ;
|
|
if( ::SetCurrentDirectory( lpDumpDirectoryInfo->szDirectory ) )
|
|
{
|
|
std::vector< LPFILENAME >::iterator iterData = lpDumpDirectoryInfo->vecDumpFileInfo.begin();
|
|
while( iterData != lpDumpDirectoryInfo->vecDumpFileInfo.end() )
|
|
{
|
|
LPFILENAME lpFileName = ( *iterData ) ;
|
|
|
|
static CHAR szTemp[ MAX_PATH ] ;
|
|
sprintf( szTemp, "%s\n", lpFileName ) ;
|
|
|
|
OutputDebugString( szTemp ) ;
|
|
|
|
|
|
pWnd->SetWindowText( szTemp ) ;
|
|
pProgressWnd->SetPos( Count );
|
|
|
|
if ( ( pStream = fopen( lpFileName->szFileName, "rt" ) ) == NULL )
|
|
{
|
|
continue ;
|
|
}
|
|
|
|
lpMetaData->ClearData();
|
|
|
|
strcpy( lpMetaData->szFileName, lpFileName->szFileName );
|
|
while(fgets(strRead, MAX_PATH - 1, pStream))
|
|
{
|
|
strRead[MAX_PATH - 1] = 0;
|
|
if ( FAILED( CheckLine( strRead, lpMetaData ) ) )
|
|
{
|
|
CheckMoreDump( pStream, lpMetaData );
|
|
break ;
|
|
}
|
|
}
|
|
if( CopyFileExt( lpMetaData, lpFileName->szFileName ) )
|
|
{
|
|
m_DumpReport.PushFaultLog ( lpMetaData );
|
|
}
|
|
fclose( pStream );
|
|
|
|
Count++ ;
|
|
iterData++;
|
|
}
|
|
|
|
}
|
|
iterVer++;
|
|
}
|
|
|
|
delete lpMetaData;
|
|
pProgressWnd->SetPos( Count ) ;
|
|
pWnd->SetWindowText( "리포트 파일 생성중" ) ;
|
|
::SetCurrentDirectory( tempDirectory );
|
|
|
|
|
|
m_DumpReport.Write2File( "report.txt" );
|
|
pWnd->SetWindowText( "End" ) ;
|
|
pProgressWnd->SetPos( 0 ) ;
|
|
}
|
|
|
|
|
|
HRESULT CDumpFileParser::CheckLine( CHAR* strLine, LPDUMPMETADATA lpMetaData )
|
|
{
|
|
CHAR seps[] = " ,\t\n[];" ;
|
|
CHAR *token, strCommand[ MAX_PATH ], strName[ MAX_PATH ] ;
|
|
CHAR strTemp[ 256 ];
|
|
strncpy( strTemp, strLine, 256);
|
|
|
|
token = strtok( strLine, seps ) ;
|
|
if ( token )
|
|
{
|
|
strcpy( strCommand, token ) ;
|
|
token = strlwr( strCommand ) ;
|
|
|
|
// 서버 이름
|
|
if (!strcmp(token, "server"))
|
|
{
|
|
BOOL bExcept = FALSE;
|
|
|
|
token = strtok(NULL, seps);
|
|
if (token)
|
|
{
|
|
strncpy( strName, token, sizeof(CHAR)*32 ) ;
|
|
token = strtok( NULL, seps ) ;
|
|
if ( token )
|
|
{
|
|
if (!strcmp(token, "Test"))
|
|
{
|
|
strncpy( lpMetaData->szServerName, "Test Server Version", sizeof(CHAR)*32) ;
|
|
}
|
|
}
|
|
else
|
|
return E_FAIL;
|
|
}
|
|
else
|
|
return E_FAIL;
|
|
return S_OK;
|
|
}
|
|
|
|
// 클라이언트 버전
|
|
if (!strcmp(token, "client"))
|
|
{
|
|
BOOL bExcept = FALSE;
|
|
|
|
token = strtok(NULL, seps);
|
|
if (token)
|
|
{
|
|
token = strtok( NULL, seps ) ;
|
|
token = strtok( NULL, seps ) ;
|
|
if ( token )
|
|
{
|
|
lpMetaData->fVersion = atof( token ) ;
|
|
if( lpMetaData->fVersion > 0 )
|
|
strncpy( lpMetaData->szVersion , token, sizeof(CHAR)*8 );
|
|
else
|
|
{
|
|
strcpy( lpMetaData->szVersion , "0.00" );
|
|
lpMetaData->fVersion = 0;
|
|
}
|
|
|
|
|
|
}
|
|
else
|
|
return E_FAIL;
|
|
}
|
|
else
|
|
return E_FAIL;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
// exception address
|
|
if (!strcmp(token, "exception"))
|
|
{
|
|
BOOL bExcept = FALSE;
|
|
|
|
token = strtok(NULL, seps);
|
|
if (token)
|
|
{
|
|
token = strtok( NULL, seps ) ;
|
|
if ( token )
|
|
{
|
|
memcpy( lpMetaData->byException, token, 8 ) ;
|
|
lpMetaData->byException[ 8 ] = 0;
|
|
}
|
|
else
|
|
return E_FAIL;
|
|
}
|
|
else
|
|
return E_FAIL;
|
|
return S_OK;
|
|
}
|
|
|
|
// Fault address
|
|
if (!strcmp(token, "fault"))
|
|
{
|
|
BOOL bExcept = FALSE;
|
|
|
|
token = strtok(NULL, seps);
|
|
if (token)
|
|
{
|
|
token = strtok( NULL, seps ) ;
|
|
|
|
if ( token )
|
|
{
|
|
memcpy( lpMetaData->byFaultAddress[ lpMetaData->nFaultCnt ], token, 8 ) ;
|
|
lpMetaData->byFaultAddress[ lpMetaData->nFaultCnt ][ 8 ] = 0;
|
|
lpMetaData->nFaultCnt += 1;
|
|
return E_FAIL;
|
|
}
|
|
else
|
|
return E_FAIL;
|
|
}
|
|
else
|
|
return E_FAIL;
|
|
return S_OK;
|
|
}
|
|
|
|
//AvailableVirtualMemory
|
|
if(!strcmp(token, "availablevirtualmemory"))
|
|
{
|
|
token = strtok(NULL, seps);
|
|
if (token)
|
|
{
|
|
token = strtok( NULL, seps ) ;
|
|
if ( token )
|
|
{
|
|
strncpy( lpMetaData->szAvailabelVirtualMemory , token, sizeof(CHAR)*15 );
|
|
}
|
|
}
|
|
return S_OK;
|
|
}
|
|
|
|
if(!strcmp(token, "totalphysicalmemory") )
|
|
{
|
|
|
|
token = strtok(NULL, seps);
|
|
if (token)
|
|
{
|
|
token = strtok( NULL, seps ) ;
|
|
if ( token )
|
|
{
|
|
strncpy( lpMetaData->szTotalPhysicalMemory , token, sizeof(CHAR)*15 );
|
|
}
|
|
}
|
|
return S_OK;
|
|
}
|
|
|
|
if(!strcmp(token, "adapterram") )
|
|
{
|
|
token = strtok(NULL, seps);
|
|
if (token)
|
|
{
|
|
token = strtok( NULL, seps ) ;
|
|
if ( token )
|
|
{
|
|
strncpy( lpMetaData->szAdapterRAM , token, sizeof(CHAR)*15 );
|
|
}
|
|
}
|
|
return S_OK;
|
|
}
|
|
|
|
if(!strcmp(token, "videoprocessor") )
|
|
{
|
|
int lenLeft ;
|
|
int lenPrev ;
|
|
lenPrev = strlen( strLine );
|
|
lenLeft = strlen( strTemp ) - lenPrev;
|
|
if( lenLeft > 7 )
|
|
{
|
|
strncpy( lpMetaData->szVideoProcessor, &strTemp[lenPrev+4], sizeof(CHAR)*(lenLeft-4-3) );
|
|
lpMetaData->szVideoProcessor[ lenLeft-4-3 ] = 0 ;
|
|
}
|
|
return S_OK;
|
|
}
|
|
|
|
//Available Memory
|
|
if(!strcmp(token, "available") )
|
|
{
|
|
token = strtok(NULL, seps);
|
|
if (token)
|
|
{
|
|
token = strtok( NULL, seps ) ;
|
|
if ( token )
|
|
{
|
|
token = strtok(NULL, seps);
|
|
if( token )
|
|
{
|
|
strncpy( lpMetaData->szAvailableMemory, token, sizeof(CHAR)*15 );
|
|
}
|
|
}
|
|
}
|
|
return S_OK;
|
|
}
|
|
}
|
|
|
|
return S_OK ;
|
|
}
|
|
|
|
HRESULT CDumpFileParser::CheckMoreDump( FILE* pFile, LPDUMPMETADATA lpMetaData )
|
|
{
|
|
CHAR strRead[MAX_PATH];
|
|
CHAR seps[] = " ,\t\n" ;
|
|
CHAR *token ;
|
|
|
|
while(fgets(strRead, MAX_PATH - 1, pFile))
|
|
{
|
|
strRead[MAX_PATH - 1] = 0;
|
|
strlwr( strRead );
|
|
if( strstr( strRead, "address" ) )
|
|
{
|
|
if( strstr( strRead, "frame" ) )
|
|
{
|
|
while(fgets(strRead, MAX_PATH - 1, pFile))
|
|
{
|
|
strlwr( strRead );
|
|
if( strstr( strRead, "client.exe" ) )
|
|
{
|
|
token = strtok( strRead, seps ) ;
|
|
if ( token )
|
|
{
|
|
memcpy( lpMetaData->byFaultAddress[ lpMetaData->nFaultCnt ], token, 8 ) ;
|
|
lpMetaData->nFaultCnt += 1;
|
|
if( lpMetaData->nFaultCnt >= 50 ) //갯수 제한.
|
|
{
|
|
return S_OK;
|
|
}
|
|
}
|
|
token = strtok(NULL, seps);
|
|
}
|
|
}
|
|
return S_OK;
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
return S_OK ;
|
|
}
|
|
|
|
|
|
|
|
const char*
|
|
// 해당 덤프하는 디렉토리를 만들고 해당 디렉토리 위치를 리턴한다.
|
|
CDumpFileParser::MakeDirectory( LPDUMPMETADATA lpMetaData, int nCnt )
|
|
{
|
|
static CHAR tempDirectory[ MAX_PATH ];
|
|
CHAR buff[ MAX_PATH ];
|
|
CHAR temp[ MAX_PATH ];
|
|
|
|
if( lpMetaData->nFaultCnt > nCnt )
|
|
{
|
|
::GetCurrentDirectory( MAX_PATH, temp );
|
|
if( !::SetCurrentDirectory( m_szCopyDirectory ) )
|
|
{
|
|
return NULL;
|
|
}
|
|
//sprintf( buff, "%.2f", lpMetaData->fVersion );
|
|
strcpy( buff, lpMetaData->szVersion );
|
|
::CreateDirectory( buff, NULL );
|
|
|
|
sprintf( tempDirectory, "%s\\%s", m_szCopyDirectory, lpMetaData->szVersion );
|
|
if( !::SetCurrentDirectory( tempDirectory) )
|
|
{
|
|
::SetCurrentDirectory( temp );
|
|
return NULL;
|
|
}
|
|
|
|
memset( buff, 0, sizeof( CHAR ) * MAX_PATH );
|
|
strncpy( buff, lpMetaData->byFaultAddress[ nCnt ], sizeof( CHAR ) * 8 );
|
|
::CreateDirectory( buff, NULL );
|
|
|
|
if( !::SetCurrentDirectory( buff ) )
|
|
{
|
|
::SetCurrentDirectory( temp );
|
|
return NULL;
|
|
}
|
|
|
|
::SetCurrentDirectory( temp );
|
|
sprintf( tempDirectory, "%s\\%s\\%s", m_szCopyDirectory, lpMetaData->szVersion, buff ); // 버젼/뻗은 주소
|
|
return tempDirectory ;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
BOOL
|
|
CDumpFileParser::CopyFileExt( LPDUMPMETADATA lpMetaData, LPSTR lpszFileName )
|
|
{
|
|
if( !lpMetaData )
|
|
return FALSE;
|
|
CHAR szDumpDirectory[ MAX_PATH ] ;
|
|
CHAR szTemp[ 9 ] ;
|
|
CHAR filename[ MAX_PATH ];
|
|
|
|
CHAR seps[] = "\\" ;
|
|
CHAR *token;
|
|
|
|
|
|
const char* path;
|
|
memcpy( szTemp, lpMetaData->byFaultAddress[0], 8 ) ;
|
|
szTemp[ 8 ] = 0 ;
|
|
|
|
strcpy( szDumpDirectory, lpszFileName );
|
|
token = strtok( szDumpDirectory, seps ) ;
|
|
while( token )
|
|
{
|
|
strcpy( filename, token );
|
|
token = strtok( NULL, seps );
|
|
}
|
|
|
|
int i ;
|
|
for( i = 0 ; i < lpMetaData->nFaultCnt ; i++ )
|
|
{
|
|
path = MakeDirectory( lpMetaData, i );
|
|
if( !path )
|
|
continue;
|
|
|
|
sprintf( szDumpDirectory, "%s\\%s", path, filename );
|
|
if ( !CopyFile( lpszFileName, szDumpDirectory, FALSE ) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
INT iLen = strlen( lpszFileName ) ;
|
|
lpszFileName[ iLen - 1] = 'p' ;
|
|
lpszFileName[ iLen - 2 ] = 'm' ;
|
|
lpszFileName[ iLen - 3 ] = 'd' ;
|
|
|
|
iLen = strlen( filename ) ;
|
|
filename[ iLen - 1] = 'p' ;
|
|
filename[ iLen - 2 ] = 'm' ;
|
|
filename[ iLen - 3 ] = 'd' ;
|
|
|
|
sprintf( szDumpDirectory, "%s\\%s", path, filename );
|
|
if ( !CopyFile( lpszFileName, szDumpDirectory, FALSE ) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
iLen = strlen( lpszFileName ) ;
|
|
lpszFileName[ iLen - 1] = 't' ;
|
|
lpszFileName[ iLen - 2 ] = 'x' ;
|
|
lpszFileName[ iLen - 3 ] = 't' ;
|
|
|
|
iLen = strlen( filename ) ;
|
|
filename[ iLen - 1] = 't' ;
|
|
filename[ iLen - 2 ] = 'x' ;
|
|
filename[ iLen - 3 ] = 't' ;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
BOOL
|
|
CDumpReport::Write2File( const char* filename )
|
|
{
|
|
FILE* pFile;
|
|
int nCnt;
|
|
std::vector< LPFAULTLIST > vecHotList;
|
|
pFile = fopen( filename, "w" );
|
|
std::sort(vecDumpFile.begin(), vecDumpFile.end(), CompareVectorfVersion());
|
|
std::sort(vecFaultList.begin(), vecFaultList.end(), CompareVectorFaultAddress() );
|
|
if( pFile )
|
|
{
|
|
|
|
fprintf( pFile,"오류주소\t메모리(KB)\t사용가능한메모리(KB)\t비디오램(KB)\t비디오프로세서\t버젼\t파일이름\n");
|
|
std::vector< CDumpLog* >::iterator iterFile;
|
|
for( iterFile = vecDumpFile.begin() ; iterFile !=vecDumpFile.end() ; iterFile++ )
|
|
{
|
|
if( *iterFile )
|
|
{
|
|
(*iterFile)->Print2File( pFile );
|
|
}
|
|
|
|
}
|
|
fprintf( pFile,"--------------------------------------------------------------------------------\n");
|
|
fprintf( pFile,"\n\n\n");
|
|
fprintf( pFile,"--------------------------------------------------------------------------------\n");
|
|
|
|
|
|
|
|
std::vector< LPFAULTLIST >::iterator iterList;
|
|
for( iterList = vecFaultList.begin() ; iterList !=vecFaultList.end() ; iterList++ )
|
|
{
|
|
nCnt = 0;
|
|
for( iterFile = vecDumpFile.begin() ; iterFile !=vecDumpFile.end() ; iterFile++ )
|
|
{
|
|
if( (*iterFile)->fVersion == (*iterList)->dwVersion )
|
|
{
|
|
if( strcmp( (*iterFile)->szFaultAddress, (*iterList)->szFileName ) == 0 )
|
|
{
|
|
nCnt++;
|
|
}
|
|
}
|
|
}
|
|
if( nCnt > 0 )
|
|
{
|
|
fprintf( pFile,"버젼%.2f\t주소:[ %s ] \t%d개\n", (*iterList)->dwVersion, (*iterList)->szFileName, nCnt );
|
|
if( nCnt > 20 )
|
|
vecHotList.push_back( (*iterList) );
|
|
}
|
|
}
|
|
fprintf( pFile,"--------------------------------------------------------------------------------\n");
|
|
fprintf( pFile,"\n\n\n");
|
|
fprintf( pFile,"------------------------Hot----List---------------------------------------------\n");
|
|
for( iterList = vecHotList.begin() ; iterList !=vecHotList.end() ; iterList++ )
|
|
{
|
|
fprintf( pFile,"버젼%.2f\t주소:[ %s ] \n", (*iterList)->dwVersion, (*iterList)->szFileName );
|
|
}
|
|
fprintf( pFile,"\n\n----E-N-D----\n");
|
|
fclose( pFile );
|
|
|
|
vecHotList.clear();
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
VOID
|
|
CDumpReport::PushFaultLog( LPDUMPMETADATA lpMeta )
|
|
{
|
|
std::vector< CDumpLog* >::iterator iterFile;
|
|
for( int i = 0 ; i < lpMeta->nFaultCnt ; i++ )
|
|
{
|
|
bool bExist = false;
|
|
for( iterFile = vecDumpFile.begin(); iterFile != vecDumpFile.end(); iterFile++ )
|
|
{
|
|
if( (*iterFile)->fVersion == lpMeta->fVersion )
|
|
{
|
|
if( strcmp( (*iterFile)->szFileName, lpMeta->szVersion ) == 0 )
|
|
{
|
|
if( strcmp( (*iterFile)->szFaultAddress, lpMeta->byFaultAddress[i]) == 0 )
|
|
{
|
|
bExist = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if( bExist )
|
|
continue;
|
|
|
|
CDumpLog* pLog;
|
|
pLog = new CDumpLog();
|
|
pLog->fVersion = lpMeta->fVersion; // 버전
|
|
strcpy( pLog->szFaultAddress, lpMeta->byFaultAddress[ i ] ); // Fault Address
|
|
strcpy( pLog->szFileName, lpMeta->szFileName ) ; // 파일명
|
|
strcpy( pLog->szVersion, lpMeta->szVersion ) ; // 버전
|
|
strcpy( pLog->szGraphicCard, lpMeta->szVideoProcessor ) ; //그래픽 카드
|
|
pLog->nBaseSystemMemory = 0; //기본 시스템 메모리
|
|
pLog->nUsedSystemMemory = 0; //사용 시스템 메모리
|
|
pLog->nBaseLocalMemory = atoi( lpMeta->szTotalPhysicalMemory ); //기본 Local 메모리
|
|
pLog->nLeftMemory = atoi( lpMeta->szAvailableMemory ); //기본 Local 메모리
|
|
pLog->nBaseAGPMemory = atoi( lpMeta->szAdapterRAM ); //기본 AGP 메모리
|
|
pLog->nBaseAGPMemory = pLog->nBaseAGPMemory / 1024 ;
|
|
pLog->nUsedAGPMemory = 0; //기본 AGP 메모리
|
|
vecDumpFile.push_back( pLog );
|
|
|
|
std::vector< LPFAULTLIST >::iterator iterList;
|
|
bExist = false;
|
|
for( iterList = vecFaultList.begin() ; iterList !=vecFaultList.end() ; iterList++ )
|
|
{
|
|
if( (*iterList)->dwVersion == pLog->fVersion )
|
|
{
|
|
if( strcmp( (*iterList)->szFileName, pLog->szFaultAddress ) == 0 )
|
|
{
|
|
bExist = true ;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if( !bExist )
|
|
{
|
|
LPFAULTLIST pList;
|
|
pList = new FAULTLIST;
|
|
strcpy( pList->szFileName, pLog->szFaultAddress );
|
|
pList->dwVersion = pLog->fVersion;
|
|
vecFaultList.push_back( pList );
|
|
}
|
|
}
|
|
}
|
|
|
|
CDumpReport::~CDumpReport()
|
|
{
|
|
std::vector< CDumpLog* >::iterator iterFile;
|
|
for( iterFile = vecDumpFile.begin() ; iterFile !=vecDumpFile.end() ; iterFile++ )
|
|
{
|
|
if( *iterFile )
|
|
{
|
|
delete (*iterFile);
|
|
(*iterFile) = NULL;
|
|
}
|
|
|
|
}
|
|
vecDumpFile.clear();
|
|
|
|
std::vector< LPFAULTLIST >::iterator iterList;
|
|
for( iterList = vecFaultList.begin() ; iterList !=vecFaultList.end() ; iterList++ )
|
|
{
|
|
if( *iterList )
|
|
{
|
|
delete (*iterList);
|
|
(*iterList) = NULL;
|
|
}
|
|
}
|
|
vecFaultList.clear();
|
|
|
|
}
|
|
|
|
|
|
VOID
|
|
CDumpLog::Print2File( FILE* pFile )
|
|
{
|
|
if( !pFile )
|
|
return;
|
|
fprintf( pFile,"%s\t%d\t%d\t%d\t%s\t%s\t%s\n", szFaultAddress, nBaseLocalMemory, nLeftMemory, nBaseAGPMemory, szGraphicCard, szVersion, szFileName );
|
|
return;
|
|
} |