Skip to content

Commit 0a728ed

Browse files
committed
Added timeout to commands in case of problems.
Updated logging.
1 parent a7eede1 commit 0a728ed

File tree

6 files changed

+155
-42
lines changed

6 files changed

+155
-42
lines changed

MTADiag/Common.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,4 @@
2525
#include <shlobj.h>
2626
#include "Log.h"
2727

28-
#define VERSION "2.7.14"
28+
#define VERSION "2.7.15"

MTADiag/Diag.cpp

Lines changed: 121 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,11 @@ void Diag::Begin ( void )
130130
{
131131
std::string szMd5 = fileList[i].szMd5;
132132
std::string szFilename = fileList[i].szFilename;
133-
133+
#ifdef _DEBUG
134+
// Speed up debugging
135+
if ( GetAsyncKeyState( VK_F1 ) )
136+
break;
137+
#endif
134138
if ( !( CompareFileMD5 ( szMd5, ( GTAPath + szFilename ) ) ) )
135139
{
136140
std::cout << "Nonstandard GTA file: " << fileList[i].szFilename << std::endl;
@@ -150,33 +154,53 @@ void Diag::Begin ( void )
150154

151155
// gather the most useful system information first
152156
#ifndef SKIPDXDIAG
153-
DoSystemCommandWithOutput ( "dxdiag /t " );
157+
DoSystemCommandWithOutput ( std::string( "dxdiag /t " ) + files[FILE_TEMP], OUTPUT_NONE );
154158
ProgressBar ( 10 );
155159
#endif
156-
DoSystemCommandWithOutput ( "tasklist >" );
160+
DoSystemCommandWithOutput ( "tasklist" );
157161
ProgressBar ( 20 );
158162

159163
// write some of MTA's logs to our log
164+
Log::WriteDividerToLog ();
160165
Log::WriteFileToLog ( MTAPath + "\\MTA\\core.log", "core.log" );
161166

162167
// 1.4
168+
Log::WriteDividerToLog ();
163169
Log::WriteFileToLog ( MTAPath + "\\MTA\\logfile.txt", "logfile.txt" );
170+
Log::WriteDividerToLog ();
164171
Log::WriteFileToLog ( MTAPath + "\\MTA\\logfile_old.txt", "logfile_old.txt" );
172+
Log::WriteDividerToLog ();
165173
Log::WriteFileToLog ( MTAPath + "\\MTA\\CEGUI.log", "CEGUI.log" );
166174
// 1.5
175+
Log::WriteDividerToLog ();
167176
Log::WriteFileToLog ( MTAPath + "\\MTA\\logs\\logfile.txt", "logfile.txt" );
177+
Log::WriteDividerToLog ();
168178
Log::WriteFileToLog ( MTAPath + "\\MTA\\logs\\logfile.txt.1", "logfile.txt.1" );
179+
Log::WriteDividerToLog ();
169180
Log::WriteFileToLog ( MTAPath + "\\MTA\\logs\\CEGUI.log", "CEGUI.log" );
170181

182+
Log::WriteDividerToLog ();
171183
Log::WriteFileToLog ( MTAPath + "\\timings.log", "timings.log" );
184+
Log::WriteDividerToLog ();
172185
Log::WriteFileToLog ( MTAPath + "\\mods\\deathmatch\\resources\\benchmark\\output\\bench.log", "bench.log" ); // FPS benchmark log
173-
if ( IsVistaOrNewer() ) { Log::WriteFileToLog ( programData + "\\MTA San Andreas All\\" + MTAShortVersion + "\\report.log", "report.log" ); }
186+
if ( IsVistaOrNewer() )
187+
{
188+
Log::WriteDividerToLog ();
189+
Log::WriteFileToLog ( programData + "\\MTA San Andreas All\\" + MTAShortVersion + "\\report.log", "report.log" );
190+
}
174191

175192
ProgressBar ( 40 );
176193

177-
DoSystemCommandWithOutput ( "ipconfig /all >" ); // get network configuration
178-
if ( IsVistaOrNewer() ) { DoSystemCommandWithOutput ( "wevtutil qe Application /q:\"Event [System [(Level=2)] ] [EventData [(Data='Multi Theft Auto.exe')] ]\" /c:1 /f:text /rd:true >" ); } // might help resolve Visual C++ runtime issues
194+
DoSystemCommandWithOutput ( "ipconfig /all" ); // get network configuration
195+
ProgressBar ( 45 );
196+
if ( IsVistaOrNewer() )
197+
{
198+
// might help resolve Visual C++ runtime issues
199+
DoSystemCommandWithOutput ( "wevtutil qe Application /q:\"Event [System [(Level=2)] ] [EventData [(Data='Multi Theft Auto.exe')] ]\" /c:1 /f:text /rd:true" );
200+
}
201+
ProgressBar ( 50 );
179202
QueryWMIC ( "Path", "Win32_VideoController", "Get" ); // get some video controller information
203+
ProgressBar ( 55 );
180204

181205
// get directory listing of some folders
182206
GetDir ( ( MTAPath + "\\MTA" ) );
@@ -186,13 +210,15 @@ void Diag::Begin ( void )
186210
ProgressBar ( 60 );
187211

188212
// get relevant MD5sum( s)
213+
Log::WriteDividerToLog ();
189214
Log::WriteStringToLog ( GetFileMD5 ( GTAPath + "\\gta_sa.exe" ) );
190215
Log::WriteStringToLog ( "Value should be: 170b3a9108687b26da2d8901c6948a18 (HOODLUM 1.0)" );
191216
Log::WriteStringToLog ( "" );
192217

193218
ProgressBar ( 80 );
194219

195220
// font diagnostics
221+
Log::WriteDividerToLog ();
196222
Log::WriteStringToLog ( "Verdana (TrueType) registry value:", ReadRegKey ( "Verdana (TrueType)", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts\\" ) );
197223
Log::WriteStringToLog ( GetFileMD5 ( systemRoot + "\\Fonts\\verdana.ttf" ) );
198224
Log::WriteStringToLog ( "Value should be: ba34b303291e36596759eb46ad9c51f2 (Win 8) / 6eee3713d2330d93183846f2d34f0976 (Win 7)" );
@@ -508,40 +534,20 @@ void Diag::UpdateDirectX ( void )
508534
remove ( DXWebSetupPath.c_str() ); // delete the temporary file
509535
}
510536

511-
void Diag::DoSystemCommandWithOutput ( std::string command )
512-
{
513-
Log::WriteStringToLog ( "----------------------------------------------------------------------------------" );
514-
int iCommandReturn = system ( ( command + files[FILE_TEMP] ).c_str() ); // do the command
515-
516-
std::stringstream ss;
517-
ss << command << " (returned " << iCommandReturn << ")";
518-
519-
Log::WriteFileToLog ( files[FILE_TEMP], ss.str() ); // write the result to the log file with the passed command argument as a description
520-
}
521-
522537
void Diag::QueryWMIC ( std::string arg1, std::string arg2, std::string arg3, std::string arg4 )
523538
{
524539
std::string WMIC;
525540
std::stringstream ss; // create a stringstream
526541

527-
ss << "wmic " << arg1 << " " << arg2 << " " << arg3 << " " << arg4 << " >" << files[FILE_WMIC_UNI].c_str(); // wmic <arg1> <arg2> <arg3> <arg4>
542+
ss << "wmic " << arg1 << " " << arg2 << " " << arg3 << " " << arg4; // wmic <arg1> <arg2> <arg3> <arg4>
528543
WMIC = ss.str ();
529544

530-
// clear the stringstream
531-
ss.str ("");
532-
ss.clear();
533-
534-
system ( WMIC.c_str() ); // do it
535-
536-
ConvertUnicodeToASCII ( files[FILE_WMIC_UNI], files[FILE_TEMP] ); // convert the Unicode-encoded result to ASCII for proper display in the log file
537-
538-
remove ( files[FILE_WMIC_UNI].c_str() ); // delete the Unicode-encoded log file
539-
540-
Log::WriteFileToLog ( files[FILE_TEMP], ( "WMIC " + arg1 + " " + arg2 + " " + arg3 + " " + arg4 ) ); // write the result to the log file with a description
545+
DoSystemCommandWithOutput ( WMIC, OUTPUT_UNICODE );
541546
}
542547

543548
void Diag::GetDir ( std::string directory )
544549
{
550+
Log::WriteDividerToLog ();
545551
std::string dirPath;
546552
std::stringstream ss; // create a stringstream
547553

@@ -556,3 +562,89 @@ void Diag::GetDir ( std::string directory )
556562

557563
Log::WriteFileToLog ( files[FILE_TEMP].c_str(), ( directory + " directory listing" ) ); // write the result to the log file with a description
558564
}
565+
566+
void Diag::DoSystemCommandWithOutput ( std::string command, int outputType, DWORD maxTimeMs )
567+
{
568+
Log::WriteDividerToLog();
569+
570+
SECURITY_ATTRIBUTES sa;
571+
sa.nLength = sizeof(sa);
572+
sa.lpSecurityDescriptor = NULL;
573+
sa.bInheritHandle = TRUE;
574+
575+
HANDLE h = NULL;
576+
if ( outputType != OUTPUT_NONE )
577+
{
578+
// File for output to be redirected to
579+
h = CreateFile( files[FILE_TEMP].c_str(),
580+
FILE_APPEND_DATA,
581+
FILE_SHARE_WRITE | FILE_SHARE_READ,
582+
&sa,
583+
CREATE_ALWAYS,
584+
FILE_ATTRIBUTE_NORMAL,
585+
NULL );
586+
if ( h == NULL )
587+
{
588+
Log::WriteStringToLog ( "**** DoSystemCommandWithOutput: Error CreateFile FILE_TEMP" );
589+
}
590+
}
591+
592+
PROCESS_INFORMATION pi;
593+
STARTUPINFO si;
594+
BOOL ret = FALSE;
595+
DWORD flags = CREATE_NO_WINDOW;
596+
597+
ZeroMemory( &pi, sizeof(PROCESS_INFORMATION) );
598+
ZeroMemory( &si, sizeof(STARTUPINFO) );
599+
si.cb = sizeof(STARTUPINFO);
600+
si.dwFlags |= STARTF_USESTDHANDLES;
601+
si.hStdInput = NULL;
602+
si.hStdError = h;
603+
si.hStdOutput = h;
604+
605+
ret = CreateProcess( NULL, (LPSTR)command.c_str(), NULL, NULL, TRUE, flags, NULL, NULL, &si, &pi );
606+
607+
std::stringstream ss;
608+
if ( ret == 0 )
609+
{
610+
DWORD dwError = GetLastError ();
611+
ss << command << " - ERROR: Unable to run - CreateProcess error: " << dwError;
612+
}
613+
else
614+
{
615+
// Apply time limit for command to complete
616+
DWORD status = WaitForSingleObject ( pi.hProcess, maxTimeMs );
617+
if ( status == WAIT_TIMEOUT )
618+
{
619+
TerminateProcess ( pi.hProcess, 1 );
620+
ss << command << " - ERROR: Unable to complete - timed out after " << maxTimeMs << " ms";
621+
}
622+
else
623+
if ( status != ERROR_SUCCESS )
624+
{
625+
TerminateProcess ( pi.hProcess, 1 );
626+
ss << command << " - ERROR: Unable to complete - WaitForSingleObject status: " << status;
627+
}
628+
else
629+
{
630+
DWORD dwExitCode = 0xFFFFFFFF;
631+
GetExitCodeProcess( pi.hProcess, &dwExitCode );
632+
ss << command << " (returned " << dwExitCode << ")";
633+
}
634+
CloseHandle( pi.hProcess );
635+
CloseHandle( pi.hThread );
636+
}
637+
638+
CloseHandle( h );
639+
640+
if ( outputType != OUTPUT_UNICODE )
641+
{
642+
Log::WriteFileToLog ( files[FILE_TEMP], ss.str() ); // write the result to the log file with the passed command argument as a description
643+
}
644+
else
645+
{
646+
ConvertUnicodeToASCII ( files[FILE_TEMP], files[FILE_WMIC_UNI] );
647+
Log::WriteFileToLog ( files[FILE_WMIC_UNI], ss.str() );
648+
remove ( files[FILE_WMIC_UNI].c_str() );
649+
}
650+
}

MTADiag/Diag.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,13 @@ enum
5656
FILE_D3DX9_DLL,
5757
};
5858

59+
enum
60+
{
61+
OUTPUT_NONE,
62+
OUTPUT_ANSI,
63+
OUTPUT_UNICODE,
64+
};
65+
5966
namespace Diag {
6067

6168
void Begin ( void );
@@ -78,7 +85,7 @@ namespace Diag {
7885
void UpdateMTA ( void );
7986

8087
// information gathering functions
81-
void DoSystemCommandWithOutput ( std::string command );
88+
void DoSystemCommandWithOutput ( std::string command, int outputType = OUTPUT_ANSI, DWORD maxTimeMs = 20000 );
8289
void GetDir ( std::string directory );
8390
void QueryWMIC ( std::string, std::string = "", std::string = "", std::string = "" );
8491

MTADiag/Log.cpp

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,22 +36,30 @@ bool Log::WriteFileToLog ( std::string filePath, std::string itemName )
3636
return false; // failure!
3737
}
3838

39-
if ( file.peek() == EOF ) { return false; } // this file is somehow already present; failure!
40-
4139
// trim any trailing spaces or ">" from system command piping from the item name
4240
std::string garbage ( " >" );
4341
size_t found;
4442

4543
found = itemName.find_last_not_of ( garbage );
4644
if ( found != std::string::npos ) { itemName.erase ( found + 1 ); }
4745

48-
logfile << itemName // item name
49-
<< ":" // colon
50-
<< std::endl << std::endl // linebreaks
51-
<< file.rdbuf() // file contents
52-
<< std::endl // linebreak
53-
<< std::flush; // clear the buffer
54-
46+
if ( file.peek() != EOF )
47+
{
48+
logfile << itemName // item name
49+
<< ":" // colon
50+
<< std::endl << std::endl // linebreaks
51+
<< file.rdbuf() // file contents
52+
<< std::endl // linebreak
53+
<< std::flush; // clear the buffer
54+
}
55+
else
56+
{
57+
logfile << itemName // item name
58+
<< ":" // colon
59+
<< std::endl << std::endl // linebreaks
60+
<< std::endl // linebreak
61+
<< std::flush; // clear the buffer
62+
}
5563
file.close(); // close the file
5664

5765
return true; // success
@@ -65,4 +73,9 @@ void Log::WriteStringToLog ( std::string string, std::string string2, bool endli
6573

6674
if ( endline ) // add an endline if specified
6775
logfile << std::endl;
68-
}
76+
}
77+
78+
void Log::WriteDividerToLog ( void )
79+
{
80+
Log::WriteStringToLog ( std::string( 120, '-' ) );
81+
}

MTADiag/Log.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ namespace Log {
2323

2424
bool WriteFileToLog ( std::string filePath, std::string itemName );
2525
void WriteStringToLog ( std::string string, std::string string2 = "", bool endline = true );
26+
void WriteDividerToLog ( void );
2627

2728
static std::ofstream logfile;
2829
}

MTADiag/MTADiag.vcxproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,12 +82,12 @@
8282
</ClCompile>
8383
<Link>
8484
<AdditionalDependencies>libcurl.lib;%(AdditionalDependencies)</AdditionalDependencies>
85-
<UACExecutionLevel>AsInvoker</UACExecutionLevel>
8685
<GenerateDebugInformation>true</GenerateDebugInformation>
8786
<SubSystem>Console</SubSystem>
8887
<OptimizeReferences>true</OptimizeReferences>
8988
<EnableCOMDATFolding>true</EnableCOMDATFolding>
9089
<TargetMachine>MachineX86</TargetMachine>
90+
<UACExecutionLevel>RequireAdministrator</UACExecutionLevel>
9191
</Link>
9292
</ItemDefinitionGroup>
9393
<ItemGroup>

0 commit comments

Comments
 (0)