1 // ======================================================================
6 // copyright 2002, sony online entertainment
8 // ======================================================================
10 #include "FirstSwgClientSetup.h"
11 #include "SwgClientSetup.h"
13 #include "ClientMachine.h"
15 #include "DialogContact.h"
16 #include "DialogFinish.h"
17 #include "DialogHardwareInformation.h"
18 #include "DialogMinidump.h"
19 #include "DialogProgress.h"
20 #include "DialogRating.h"
21 #include "DialogStationId.h"
23 #include "SwgClientSetupDlg.h"
24 #include "MessageBox2.h"
27 #include <sys/types.h>
36 static char THIS_FILE
[] = __FILE__
;
39 // ======================================================================
41 namespace SwgClientSetupNamespace
43 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
45 TCHAR
const * const cms_registryFolder
= _T("Software\\Sony Online Entertainment\\StarWarsGalaxies\\SwgClient");
46 TCHAR
const * const cms_sendMinidumpsRegistryKey
= _T("SendCrashLogs");
47 TCHAR
const * const cms_sendHardwareInformationRegistryKey
= _T("SendHardwareInformation");
48 TCHAR
const * const cms_informationCrcRegistryKey
= _T("HardwareInformationCrc");
49 TCHAR
const * const cms_hardwareInformationCrcRegistryKey
= _T("HardwareInformationCrc");
50 TCHAR
const * const cms_lastRatingTimeRegistryKey
= _T("LastRatingTime");
51 TCHAR
const * const cms_machineRequirementsDisplayCountRegistryKey
= _T("MachineRequirementsDisplayCount");
52 TCHAR
const * const cms_applicationName
= _T("SwgClient_r.exe");
53 char const * const cms_fromEmailAddress
= "swgbetatestcrashes@soe.sony.com";
54 char const * const cms_toEmailAddress
= "swgbetatestcrashes@soe.sony.com";
55 TCHAR
const * const cms_fileNameMask
= _T("SwgClient_?.exe-*.*");
56 TCHAR
const * const cms_languageStringJapanese
= _T("ja");
58 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
60 CString
getVersion (CString
const & fileName
)
62 int const start
= fileName
.Find ('-', 0) + 1;
63 int const end
= fileName
.ReverseFind ('-');
65 return fileName
.Mid (start
, end
- start
);
68 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
70 int getMajorVersion (CString
const & fileName
)
72 CString
const version
= getVersion (fileName
);
74 int const end
= version
.Find ('.', 0);
76 return _ttoi (version
.Mid (0, end
));
79 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
81 int getMinorVersion (CString
const & fileName
)
83 CString
const version
= getVersion (fileName
);
85 int const end
= version
.Find ('.', 0);
87 return _ttoi (version
.Mid (end
+ 1, version
.GetLength () - end
));
90 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
92 CString
getSubject (CString
const & fileName
)
94 return "automated crash dump " + fileName
;
97 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
99 CString
getBody (CString
const & fileName
)
104 if (file
.Open (fileName
+ ".txt", CFile::modeRead
| CFile::typeText
))
107 while (file
.ReadString (line
))
111 body
= "automated crash dump\n\nunknown: FATAL 00000000: minidump from options program\n";
116 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
118 CString
getCode (CString
const & fileName
)
123 if (file
.Open (fileName
+ ".txt", CFile::modeRead
| CFile::typeText
))
126 while (file
.ReadString (line
))
128 if (line
.Find (_T("Exception")) != -1 || line
.Find (_T("FATAL")) != -1)
137 if (body
.GetLength () == 0)
143 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
145 CString
getMinidump (CString
const & fileName
)
150 if (file
.Open (fileName
+ ".mdmp", CFile::modeRead
))
151 result
+= fileName
+ ".mdmp";
156 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
158 CString
getLog (CString
const & fileName
)
163 if (file
.Open (fileName
+ ".log", CFile::modeRead
))
164 result
+= fileName
+ ".log";
169 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
171 bool registryKeyExists (TCHAR
const * const key
)
174 regKey
.Open (HKEY_CURRENT_USER
, cms_registryFolder
);
178 return regKey
.QueryValue (value
, key
) == ERROR_SUCCESS
;
180 return regKey
.QueryDWORDValue (key
, value
) == ERROR_SUCCESS
;
184 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
186 DWORD
getRegistryKey (TCHAR
const * const key
)
189 regKey
.Open (HKEY_CURRENT_USER
, cms_registryFolder
);
193 regKey
.QueryValue (value
, key
);
195 regKey
.QueryDWORDValue (key
, value
);
201 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
203 void setRegistryKey (TCHAR
const * const key
, DWORD
const value
)
206 regKey
.Create (HKEY_CURRENT_USER
, cms_registryFolder
);
208 regKey
.SetValue (value
, key
);
210 regKey
.SetDWORDValue (key
, value
);
214 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
216 CString
getStationId (CString
const & commandLine
)
218 int index
= commandLine
.Find (_T("stationId="));
221 index
= commandLine
.Find (_T("="), index
);
222 CString result
= commandLine
.Right (commandLine
.GetLength () - index
- 1);
223 index
= result
.Find (_T(" "));
225 result
= result
.Left (index
);
233 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
235 int getLanguageCode (CString
const & commandLine
)
237 int index
= commandLine
.Find (_T("locale="));
240 index
= commandLine
.Find (_T("="), index
);
241 CString result
= commandLine
.Right (commandLine
.GetLength () - index
- 1);
242 index
= result
.Find (_T(" "));
244 result
= result
.Left (index
);
246 if (wcsncmp(result
, cms_languageStringJapanese
, 2) == 0)
247 return cms_languageCodeJapanese
;
250 return cms_languageCodeEnglish
;
252 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
254 bool hasJumpToLightspeed (CString
const & commandLine
)
256 int index
= commandLine
.Find (_T("gameFeatures="));
259 index
= commandLine
.Find (_T("="), index
);
260 CString result
= commandLine
.Right (commandLine
.GetLength () - index
- 1);
261 index
= result
.Find (_T(" "));
263 result
= result
.Left (index
);
265 int const gameFeatures
= _ttoi(result
);
267 return (gameFeatures
& 16) != 0;
273 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
275 void RemoveFile(char const * fileName
)
277 if (unlink(fileName
) == -1 && errno
== EACCES
)
279 _chmod(fileName
, _S_IREAD
| _S_IWRITE
);
285 using namespace SwgClientSetupNamespace
;
287 // ======================================================================
289 BEGIN_MESSAGE_MAP(SwgClientSetupApp
, CWinApp
)
290 //{{AFX_MSG_MAP(SwgClientSetupApp)
292 ON_COMMAND(ID_HELP
, CWinApp::OnHelp
)
295 // ----------------------------------------------------------------------
297 SwgClientSetupApp::SwgClientSetupApp()
301 // ----------------------------------------------------------------------
303 SwgClientSetupApp theApp
;
305 // ----------------------------------------------------------------------
307 class CCommandLineInfo2
: public CCommandLineInfo
311 CCommandLineInfo2 () :
313 m_numberOfParameters(0),
315 m_debugExitPoll(false)
319 virtual void ParseParam(TCHAR
const * pszParam
, BOOL
/*bFlag*/, BOOL
/*bLast*/)
321 if (wcsstr(pszParam
, _T("locale")) == 0)
322 ++m_numberOfParameters
;
324 if (wcsstr(pszParam
, _T("Station")) != 0)
327 if (wcsstr(pszParam
, _T("sessionId")) != 0)
330 if (wcsstr(pszParam
, _T("stationId")) != 0)
333 if (wcsstr(pszParam
, _T("subscriptionFeatures")) != 0)
336 if (wcsstr(pszParam
, _T("gameFeatures")) != 0)
339 m_debugExitPoll
|= (wcsstr(pszParam
, _T("debugExitPoll")) != 0);
342 bool shouldLaunchSwgClient() const
344 return m_numberOfParameters
> 0;
347 bool looksValid() const
349 return m_numberOfErrors
== 0;
352 bool debugExitPoll() const
354 return m_debugExitPoll
;
359 int m_numberOfParameters
;
360 int m_numberOfErrors
;
361 bool m_debugExitPoll
;
364 // ----------------------------------------------------------------------
366 BOOL
SwgClientSetupApp::InitInstance()
368 MessageBox2::install(cms_registryFolder
);
370 // Initialize MFC controls.
371 AfxEnableControlContainer();
375 Enable3dControls(); // Call this when using MFC in a shared DLL
377 Enable3dControlsStatic(); // Call this when linking to MFC statically
382 // Standard initialization
383 HANDLE semaphore
= CreateSemaphore(NULL
, 0, 1, _T("SwgClientSetupInstanceRunning"));
384 if (GetLastError() == ERROR_ALREADY_EXISTS
)
387 VERIFY(anotherStr
.LoadString(IDS_ANOTHER_INSTANCE
));
388 MessageBox(NULL
, anotherStr
, NULL
, MB_OK
| MB_ICONSTOP
);
389 CloseHandle(semaphore
);
393 detectAndSendMinidumps ();
395 ClientMachine::install ();
397 int const langCode
= getLanguageCode(AfxGetApp()->m_lpCmdLine
);
398 Options::load (langCode
);
401 //-- Set the thread locale in order to use the correct string table
402 if (langCode
== cms_languageCodeJapanese
)
403 SetThreadLocale(MAKELCID(0x0411, SORT_DEFAULT
));
407 SetThreadLocale(MAKELCID(0x0409, SORT_DEFAULT
));
411 CCommandLineInfo2 commandLineInfo
;
412 ParseCommandLine (commandLineInfo
);
414 if (commandLineInfo
.shouldLaunchSwgClient())
416 if (!commandLineInfo
.looksValid())
419 OutputDebugString(CString("SwgClientSetup command line: ") + m_lpCmdLine
+ "\n");
422 VERIFY(message
.LoadString(IDS_INVALIDCOMMANDLINE
));
423 if (MessageBox(NULL
, message
, NULL
, MB_YESNO
| MB_ICONSTOP
) == IDNO
)
426 if (ClientMachine::getDirectXVersionMajor() < 9 || ClientMachine::getDirectXVersionLetter() < 'c')
428 MessageBox2
messageBox(CString("You have DirectX ") + CString(ClientMachine::getDirectXVersion()) + CString(" installed but DirectX 9.0c is currently required to play Star Wars Galaxies. For upgrade information, please see:\n\n\thttp://starwarsgalaxies.station.sony.com/content.jsp?page=Directx%20Upgrade"));
429 messageBox
.setOkayButton("Quit");
430 messageBox
.setCancelButton("");
431 messageBox
.setWebButton("Go to web page", "http://starwarsgalaxies.station.sony.com/content.jsp?page=Directx%20Upgrade");
432 messageBox
.DoModal();
436 unsigned short const vendor
= ClientMachine::getVendorIdentifier ();
437 unsigned short const device
= ClientMachine::getDeviceIdentifier ();
438 int const driverProduct
= ClientMachine::getDeviceDriverProduct();
439 int const driverVersion
= ClientMachine::getDeviceDriverVersion ();
440 int const driverSubversion
= ClientMachine::getDeviceDriverSubversion ();
441 int const driverBuild
= ClientMachine::getDeviceDriverBuild();
443 if (vendor
== 0x10de)
446 if (driverBuild
>= 2700 && driverBuild
< 2800)
448 MessageBox2
messageBox("The application has detected very old NVidia video card drivers that have known issues that will cause a crash.\nPlease upgrade your video drivers. They may be downloaded from:\n\n\thttp://www.nvidia.com.\n\nWould you like to continue running anyway?");
449 messageBox
.setOkayButton("Continue");
450 messageBox
.setCancelButton("Quit");
451 messageBox
.setWebButton("Go to web page", "http://www.nvidia.com");
452 messageBox
.setDoNotShowAgainCheckBox("Do not show this warning again", "NVidia 2700");
453 if (messageBox
.DoModal() == IDCANCEL
)
456 else if ((device
>= 0x0200 && device
<= 0x020F) && driverBuild
== 5216)
458 MessageBox2
messageBox("The application has detected a card/driver combination that has known issues that cause a crash.\nPlease upgrade your video drivers. They may be downloaded from:\n\n\thttp://www.nvidia.com.\n\nWould you like to continue running anyway?");
459 messageBox
.setOkayButton("Continue");
460 messageBox
.setCancelButton("Quit");
461 messageBox
.setWebButton("Go to web page", "http://www.nvidia.com");
462 messageBox
.setDoNotShowAgainCheckBox("Do not show this warning again", "NVidia 5216");
463 if (messageBox
.DoModal() == IDCANCEL
)
467 else if (vendor
== 0x1002)
470 if (driverBuild
<= 6467)
472 MessageBox2
messageBox("The application has detected old ATI video card drivers which have known issues that will cause a crash.\nFor more information, please see:\n\n\thttp://starwarsgalaxies.station.sony.com/content.jsp?page=ATI%20Video%20Card%20Driver\n\nWould you like to continue running anyway?");
473 messageBox
.setOkayButton("Continue");
474 messageBox
.setCancelButton("Quit");
475 messageBox
.setWebButton("Go to web page", "http://starwarsgalaxies.station.sony.com/content.jsp?page=ATI%20Video%20Card%20Driver");
476 messageBox
.setDoNotShowAgainCheckBox("Do not show this warning again", "ATI Catalyst 4.8");
477 if (messageBox
.DoModal() == IDCANCEL
)
482 if (!registryKeyExists (cms_sendHardwareInformationRegistryKey
))
487 detectAndSendHardwareInformation ();
489 bool const displayMessage
=
490 (ClientMachine::getPhysicalMemorySize () < 500) ||
491 (ClientMachine::getCpuSpeed () < 900) ||
492 (ClientMachine::getVideoMemorySize() < 28);
495 int const machineRequirementsDisplayCount
= getRegistryKey(cms_machineRequirementsDisplayCountRegistryKey
);
496 if (machineRequirementsDisplayCount
< 3)
498 CString os
= _T("- Windows 98SE/ME/2000/XP");
499 if (os
== _T("unsupported"))
500 os
+= _T(" (detected unsupported)\n");
505 VERIFY(memory
.LoadString(IDS_512MB_PHYSICAL
));
507 CString memoryDetected
;
508 VERIFY(memoryDetected
.LoadString(IDS_512MB_PHYSICAL_DETECTED
));
509 if (ClientMachine::getPhysicalMemorySize () < 500)
510 memory
.Format (memoryDetected
, ClientMachine::getPhysicalMemorySize ());
513 VERIFY(cpu
.LoadString(IDS_900MHZ_PROCESSOR
));
514 if (ClientMachine::getCpuSpeed () < 900)
516 if (ClientMachine::getCpuSpeed() == 0)
518 CString detectedUnknown
;
519 VERIFY(detectedUnknown
.LoadString(IDS_900MHZ_PROCESSOR_DETECTED_UNKNOWN
));
520 cpu
.Format (detectedUnknown
);
525 VERIFY(detectedCpu
.LoadString(IDS_900MHZ_PROCESSOR_DETECTED
));
526 cpu
.Format (detectedCpu
, ClientMachine::getCpuSpeed ());
531 VERIFY(videoMemory
.LoadString(IDS_32MB_VIDEO_MEMORY
));
532 CString videoMemoryTooSmall
;
533 VERIFY(videoMemoryTooSmall
.LoadString(IDS_32MB_VIDEO_MEMORY_DETECTED
));
534 if (ClientMachine::getVideoMemorySize () < 28)
535 videoMemory
.Format (videoMemoryTooSmall
, ClientMachine::getVideoMemorySize ());
537 CString harshMessage
;
538 VERIFY(harshMessage
.LoadString(IDS_NOT_MINIMUM
));
540 VERIFY(niceMessage
.LoadString(IDS_NICE_MINIMUM
));
541 bool const displayHarshMessage
=
542 (hasJumpToLightspeed(AfxGetApp()->m_lpCmdLine
) && ClientMachine::getPhysicalMemorySize () < 500) ||
543 (!hasJumpToLightspeed(AfxGetApp()->m_lpCmdLine
) && ClientMachine::getPhysicalMemorySize () < 250) ||
544 (ClientMachine::getCpuSpeed () < 900) ||
545 (ClientMachine::getVideoMemorySize() < 28);
547 CString
message(displayHarshMessage
? harshMessage
: niceMessage
);
551 message
+= videoMemory
;
552 CString finalMessageStr
;
553 VERIFY(finalMessageStr
.LoadString(IDS_FINAL_CONFIG
));
554 message
+= finalMessageStr
;
557 VERIFY(noChangeStr
.LoadString(IDS_NO_CHANGE_DETECTED
));
558 if (machineRequirementsDisplayCount
== 2)
559 message
+= noChangeStr
;
561 setRegistryKey(cms_machineRequirementsDisplayCountRegistryKey
, machineRequirementsDisplayCount
+ 1);
563 AfxMessageBox (message
, NULL
, MB_OK
| MB_ICONSTOP
);
567 setRegistryKey(cms_machineRequirementsDisplayCountRegistryKey
, 0);
569 //-- spawn cms_applicationName
571 PROCESS_INFORMATION pi
;
573 ZeroMemory (&si
, sizeof(si
));
575 ZeroMemory (&pi
, sizeof(pi
));
577 TCHAR commandLine
[1024];
578 _stprintf (commandLine
, _T("%s %s"), cms_applicationName
, AfxGetApp()->m_lpCmdLine
);
579 BOOL
const result
= CreateProcess (cms_applicationName
, commandLine
, NULL
, NULL
, FALSE
, 0, NULL
, NULL
, &si
, &pi
);
584 VERIFY(failedStr
.LoadString(IDS_FAILED_START
));
585 error
.Format (failedStr
, cms_applicationName
);
586 AfxMessageBox (error
, NULL
, MB_ICONERROR
| MB_OK
);
591 CloseHandle(semaphore
);
598 if (!ClientMachine::getDirectXSupported ())
601 VERIFY(directXStr
.LoadString(IDS_NO_DIRECTX
));
602 AfxMessageBox (directXStr
);
606 SwgClientSetupDlg dlg
;
608 int nResponse
= dlg
.DoModal();
609 if (nResponse
== IDOK
)
611 if (!Options::save ())
615 VERIFY(cantSaveStr
.LoadString(IDS_CANT_SAVE
));
616 buffer
.Format (cantSaveStr
, Options::getFileName ());
617 AfxMessageBox (buffer
);
620 else if (nResponse
== IDCANCEL
)
625 CloseHandle(semaphore
);
627 // Since the dialog has been closed, return FALSE so that we exit the
628 // application, rather than start the application's message pump.
632 // ======================================================================
634 //int callBlat(int argc, char **argv, char **envp);
636 // ----------------------------------------------------------------------
638 void SwgClientSetupNamespace::sendMail(std::string
const & to
, std::string
const & from
, std::string
const & subject
, std::string
const & body
, std::vector
<std::string
> const & attachments
)
640 int const numAttachments
= attachments
.size();
642 const int static_args
= 13;
644 int argc
= static_args
+ (2 * numAttachments
);
645 char** argv
= new char*[argc
];
647 argv
[argv_value
++] = "-to";
648 argv
[argv_value
++] = const_cast<char*>(to
.c_str());
649 argv
[argv_value
++] = "-subject";
650 argv
[argv_value
++] = const_cast<char*>(subject
.c_str());
651 argv
[argv_value
++] = "-smtphost";
652 argv
[argv_value
++] = "mail.station.sony.com";
653 argv
[argv_value
++] = "-port";
654 argv
[argv_value
++] = "2525";
655 argv
[argv_value
++] = "-f";
656 argv
[argv_value
++] = const_cast<char*>(from
.c_str());
657 argv
[argv_value
++] = "-body";
658 argv
[argv_value
++] = const_cast<char*>(body
.c_str());
660 //iterate through all attachments, building the argv entries for them
661 for(std::vector
<std::string
>::const_iterator i
= attachments
.begin(); i
!= attachments
.end(); ++i
)
663 argv
[argv_value
++] = "-attach";
664 argv
[argv_value
++] = const_cast<char*>(i
->c_str());
667 //this doesn't get used, but make sure to send initialized memory anyway
668 char* envp
= new char[256];
669 memset(envp
, 0, 256);
671 //call into blat to send the mail
672 //callBlat(argc, argv, &envp);
674 //clean up allocated memory
679 // ----------------------------------------------------------------------
681 void SwgClientSetupApp::configure ()
683 bool const oldSendMinidumps
= getSendMinidumps ();
684 bool const oldSendStationId
= Options::getSendStationId ();
685 bool const oldAutomaticallySendHardwareInformation
= getAutomaticallySendHardwareInformation ();
686 bool const oldAllowCustomerContact
= Options::getAllowCustomerContact ();
688 //-- ask to send minidumps
689 DialogMinidump dialogMinidump
;
690 bool cancelled
= dialogMinidump
.DoModal () == IDCANCEL
;
692 //-- if the user did not cancel and they want to send minidumps
695 if (getSendMinidumps ())
697 DialogStationId dialogStationId
;
698 cancelled
= dialogStationId
.DoModal () == IDCANCEL
;
700 //-- if the user did not cancel, ask to send hardware and contact information
703 if (Options::getSendStationId ())
705 DialogHardwareInformation dialogHardwareInformation
;
706 cancelled
= dialogHardwareInformation
.DoModal () == IDCANCEL
;
710 DialogContact dialogContact
;
711 cancelled
= dialogContact
.DoModal () == IDCANCEL
;
716 setAutomaticallySendHardwareInformation (false);
717 Options::setAllowCustomerContact (false);
723 DialogFinish dialogFinish
;
724 dialogFinish
.DoModal ();
729 Options::setSendStationId (false);
730 setAutomaticallySendHardwareInformation (false);
731 Options::setAllowCustomerContact (false);
737 setSendMinidumps (oldSendMinidumps
);
738 Options::setSendStationId (oldSendStationId
);
739 setAutomaticallySendHardwareInformation (oldAutomaticallySendHardwareInformation
);
740 Options::setAllowCustomerContact (oldAllowCustomerContact
);
744 // ----------------------------------------------------------------------
746 void SwgClientSetupApp::detectAndSendMinidumps ()
748 typedef std::vector
<std::wstring
> StringList
;
749 StringList fileNameList
;
751 //-- find all files in the current directory that end in match SwgClient_r.exe-*.mdmp
753 BOOL working
= finder
.FindFile (cms_fileNameMask
);
756 working
= finder
.FindNextFile ();
758 if (!finder
.IsDots () && !finder
.IsDirectory () && finder
.MatchesMask (FILE_ATTRIBUTE_ARCHIVE
))
760 CString fileName
= finder
.GetFileName ();
761 int const index
= fileName
.ReverseFind ('.');
762 fileName
= fileName
.Left (index
);
764 std::wstring
const fileNameString(fileName
);
765 if (std::find (fileNameList
.begin (), fileNameList
.end (), fileNameString
) == fileNameList
.end ())
766 fileNameList
.push_back (fileNameString
);
770 if (!fileNameList
.empty ())
772 bool const sendMinidumps
= getSendMinidumps ();
775 //-- do both the minidump and the
776 DialogProgress
* dlg
= new DialogProgress ();
778 dlg
->SetRange (0, fileNameList
.size ());
783 name
.Format (_T("Sending %i log(s)..."), fileNameList
.size ());
784 dlg
->SetStatus (name
);
786 for (size_t i
= 0; i
< fileNameList
.size (); ++i
)
788 CString
const fileName
= fileNameList
[i
].c_str ();
790 //-- send the minidump
791 std::vector
<std::string
> attachments
;
792 CString
const attachment
= getMinidump (fileName
);
793 if (attachment
.GetLength () != 0)
794 attachments
.push_back(wideToNarrow(attachment
));
795 CString
const attachmentLog
= getLog (fileName
);
796 if(attachmentLog
.GetLength() != 0)
797 attachments
.push_back(wideToNarrow(attachmentLog
));
799 int const majorVersion
= getMajorVersion (fileName
);
800 int const minorVersion
= getMinorVersion (fileName
);
801 if (majorVersion
>= 100000 || (majorVersion
== 0 && minorVersion
>= 100000))
802 sendMail (cms_toEmailAddress
, cms_fromEmailAddress
, wideToNarrow (getSubject (fileName
)), wideToNarrow (getBody (fileName
)), attachments
);
806 if (dlg
->CheckCancelButton ())
814 //-- log the filenames to a file
817 if (outfile
.Open (_T("minidump.log"), CFile::modeCreate
| CFile::modeNoTruncate
| CFile::modeWrite
| CFile::typeText
))
819 //-- seek to the end of the log file
820 outfile
.SeekToEnd ();
822 //-- write the header
825 CTime
const ctime (osTime
);
826 CString
const header
= ctime
.Format(_T("-- %Y-%m-%d %H:%M "));
827 outfile
.WriteString (header
+ (sendMinidumps
? _T("sent") : _T("not sent")) + '\n');
830 for (size_t i
= 0; i
< fileNameList
.size (); ++i
)
832 //-- write the file name and the exception or fatal string
833 CString
const fileName
= fileNameList
[i
].c_str ();
834 outfile
.WriteString (fileName
+ ".txt " + getCode (fileName
) + '\n');
836 std::string
const file1(wideToNarrow(fileName
) + ".txt");
837 std::string
const file2(wideToNarrow(fileName
) + ".mdmp");
838 std::string
const file3(wideToNarrow(fileName
) + ".log");
840 //-- delete the files
841 RemoveFile (file1
.c_str());
842 RemoveFile (file2
.c_str());
843 RemoveFile (file3
.c_str());
846 outfile
.WriteString (_T("\n"));
851 VERIFY(detectedStr
.LoadString(IDS_DETECTED_CRASH
));
852 AfxMessageBox (detectedStr
, NULL
, MB_ICONINFORMATION
| MB_OK
);
856 // ----------------------------------------------------------------------
858 void SwgClientSetupApp::detectAndSendHardwareInformation ()
860 if (getAutomaticallySendHardwareInformation())
862 DWORD
const savedInformationCrc
= getRegistryKey(cms_informationCrcRegistryKey
);
863 CString
const informationString
= ClientMachine::getHardwareInformationString() + Options::getInformationString();
864 DWORD
const informationCrc
= Crc::calculate(wideToNarrow(informationString
).c_str());
865 if (informationCrc
!= savedInformationCrc
)
867 CString
const stationId
= getStationId(AfxGetApp()->m_lpCmdLine
);
869 setRegistryKey(cms_informationCrcRegistryKey
, informationCrc
);
870 CString
const subject
= _T("machine description from ") + stationId
;
871 std::vector
<std::string
> const attachments
;
872 sendMail(cms_toEmailAddress
, cms_fromEmailAddress
, wideToNarrow(subject
), wideToNarrow(informationString
), attachments
);
877 DWORD
const savedHardwareInformationCrc
= getRegistryKey(cms_hardwareInformationCrcRegistryKey
);
878 CString
const hardwareInformationString
= ClientMachine::getHardwareInformationString();
879 DWORD
const hardwareInformationCrc
= Crc::calculate(wideToNarrow(hardwareInformationString
).c_str());
880 if (hardwareInformationCrc
!= savedHardwareInformationCrc
)
882 setRegistryKey(cms_hardwareInformationCrcRegistryKey
, hardwareInformationCrc
);
883 setRegistryKey(cms_machineRequirementsDisplayCountRegistryKey
, 0);
888 // ----------------------------------------------------------------------
890 TCHAR
const * SwgClientSetupApp::getSendMinidumpsString ()
892 CString sendMinidumpsString
;
893 VERIFY(sendMinidumpsString
.LoadString(IDS_PLEASE_SEND_LOG
));
894 return sendMinidumpsString
;
897 // ----------------------------------------------------------------------
899 bool SwgClientSetupApp::getSendMinidumps ()
901 return getRegistryKey (cms_sendMinidumpsRegistryKey
) != 0;
904 // ----------------------------------------------------------------------
906 void SwgClientSetupApp::setSendMinidumps (bool const sendMinidumps
)
908 setRegistryKey (cms_sendMinidumpsRegistryKey
, sendMinidumps
? 1 : 0);
911 // ----------------------------------------------------------------------
913 TCHAR
const * SwgClientSetupApp::getSendStationIdString ()
916 VERIFY(str
.LoadString(IDS_SEND_STATION_ID
));
920 // ----------------------------------------------------------------------
922 TCHAR
const * SwgClientSetupApp::getAutomaticallySendHardwareInformationString ()
925 VERIFY(str
.LoadString(IDS_AUTOMATICALLY_SEND_HARDWARE
));
929 // ----------------------------------------------------------------------
930 bool SwgClientSetupApp::getAutomaticallySendHardwareInformation ()
932 return getRegistryKey (cms_sendHardwareInformationRegistryKey
) != 0;
935 // ----------------------------------------------------------------------
937 void SwgClientSetupApp::setAutomaticallySendHardwareInformation (bool const automaticallySendHardwareInformation
)
939 setRegistryKey (cms_sendHardwareInformationRegistryKey
, automaticallySendHardwareInformation
? 1 : 0);
942 // ----------------------------------------------------------------------
944 TCHAR
const * SwgClientSetupApp::getAllowContactString ()
947 VERIFY(str
.LoadString(IDS_ALLOW_CONTACT
));
951 // ----------------------------------------------------------------------
953 TCHAR
const * SwgClientSetupApp::getThankYouString ()
956 VERIFY(str
.LoadString(IDS_THANK_YOU
));
960 // ======================================================================