@@ -130,7 +130,11 @@ void Diag::Begin ( void )
130
130
{
131
131
std::string szMd5 = fileList[i].szMd5 ;
132
132
std::string szFilename = fileList[i].szFilename ;
133
-
133
+ #ifdef _DEBUG
134
+ // Speed up debugging
135
+ if ( GetAsyncKeyState ( VK_F1 ) )
136
+ break ;
137
+ #endif
134
138
if ( !( CompareFileMD5 ( szMd5, ( GTAPath + szFilename ) ) ) )
135
139
{
136
140
std::cout << " Nonstandard GTA file: " << fileList[i].szFilename << std::endl;
@@ -150,33 +154,53 @@ void Diag::Begin ( void )
150
154
151
155
// gather the most useful system information first
152
156
#ifndef SKIPDXDIAG
153
- DoSystemCommandWithOutput ( " dxdiag /t " );
157
+ DoSystemCommandWithOutput ( std::string ( " dxdiag /t " ) + files[FILE_TEMP], OUTPUT_NONE );
154
158
ProgressBar ( 10 );
155
159
#endif
156
- DoSystemCommandWithOutput ( " tasklist > " );
160
+ DoSystemCommandWithOutput ( " tasklist" );
157
161
ProgressBar ( 20 );
158
162
159
163
// write some of MTA's logs to our log
164
+ Log::WriteDividerToLog ();
160
165
Log::WriteFileToLog ( MTAPath + " \\ MTA\\ core.log" , " core.log" );
161
166
162
167
// 1.4
168
+ Log::WriteDividerToLog ();
163
169
Log::WriteFileToLog ( MTAPath + " \\ MTA\\ logfile.txt" , " logfile.txt" );
170
+ Log::WriteDividerToLog ();
164
171
Log::WriteFileToLog ( MTAPath + " \\ MTA\\ logfile_old.txt" , " logfile_old.txt" );
172
+ Log::WriteDividerToLog ();
165
173
Log::WriteFileToLog ( MTAPath + " \\ MTA\\ CEGUI.log" , " CEGUI.log" );
166
174
// 1.5
175
+ Log::WriteDividerToLog ();
167
176
Log::WriteFileToLog ( MTAPath + " \\ MTA\\ logs\\ logfile.txt" , " logfile.txt" );
177
+ Log::WriteDividerToLog ();
168
178
Log::WriteFileToLog ( MTAPath + " \\ MTA\\ logs\\ logfile.txt.1" , " logfile.txt.1" );
179
+ Log::WriteDividerToLog ();
169
180
Log::WriteFileToLog ( MTAPath + " \\ MTA\\ logs\\ CEGUI.log" , " CEGUI.log" );
170
181
182
+ Log::WriteDividerToLog ();
171
183
Log::WriteFileToLog ( MTAPath + " \\ timings.log" , " timings.log" );
184
+ Log::WriteDividerToLog ();
172
185
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
+ }
174
191
175
192
ProgressBar ( 40 );
176
193
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 );
179
202
QueryWMIC ( " Path" , " Win32_VideoController" , " Get" ); // get some video controller information
203
+ ProgressBar ( 55 );
180
204
181
205
// get directory listing of some folders
182
206
GetDir ( ( MTAPath + " \\ MTA" ) );
@@ -186,13 +210,15 @@ void Diag::Begin ( void )
186
210
ProgressBar ( 60 );
187
211
188
212
// get relevant MD5sum( s)
213
+ Log::WriteDividerToLog ();
189
214
Log::WriteStringToLog ( GetFileMD5 ( GTAPath + " \\ gta_sa.exe" ) );
190
215
Log::WriteStringToLog ( " Value should be: 170b3a9108687b26da2d8901c6948a18 (HOODLUM 1.0)" );
191
216
Log::WriteStringToLog ( " " );
192
217
193
218
ProgressBar ( 80 );
194
219
195
220
// font diagnostics
221
+ Log::WriteDividerToLog ();
196
222
Log::WriteStringToLog ( " Verdana (TrueType) registry value:" , ReadRegKey ( " Verdana (TrueType)" , " SOFTWARE\\ Microsoft\\ Windows NT\\ CurrentVersion\\ Fonts\\ " ) );
197
223
Log::WriteStringToLog ( GetFileMD5 ( systemRoot + " \\ Fonts\\ verdana.ttf" ) );
198
224
Log::WriteStringToLog ( " Value should be: ba34b303291e36596759eb46ad9c51f2 (Win 8) / 6eee3713d2330d93183846f2d34f0976 (Win 7)" );
@@ -508,40 +534,20 @@ void Diag::UpdateDirectX ( void )
508
534
remove ( DXWebSetupPath.c_str () ); // delete the temporary file
509
535
}
510
536
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
-
522
537
void Diag::QueryWMIC ( std::string arg1, std::string arg2, std::string arg3, std::string arg4 )
523
538
{
524
539
std::string WMIC;
525
540
std::stringstream ss; // create a stringstream
526
541
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>
528
543
WMIC = ss.str ();
529
544
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 );
541
546
}
542
547
543
548
void Diag::GetDir ( std::string directory )
544
549
{
550
+ Log::WriteDividerToLog ();
545
551
std::string dirPath;
546
552
std::stringstream ss; // create a stringstream
547
553
@@ -556,3 +562,89 @@ void Diag::GetDir ( std::string directory )
556
562
557
563
Log::WriteFileToLog ( files[FILE_TEMP].c_str (), ( directory + " directory listing" ) ); // write the result to the log file with a description
558
564
}
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
+ }
0 commit comments