2424#include < iomanip>
2525#include < sstream>
2626#include < codecvt>
27+ #include < fstream>
28+ #include < chrono>
29+ #include < ctime>
2730
2831#include < openssl/evp.h>
2932#include < openssl/md5.h>
3033
3134#include " installer_setup.h"
3235#include " version.h"
3336
37+ class Logger {
38+ public:
39+ static Logger& Instance () {
40+ static Logger instance;
41+ return instance;
42+ }
43+
44+ void Log (const std::string& message) {
45+ if (!ofs.is_open ()) {
46+ return ;
47+ }
48+ const auto now = std::chrono::system_clock::now ();
49+ const auto now_c = std::chrono::system_clock::to_time_t (now);
50+ ofs << std::ctime (&now_c) << " " << message << std::endl;
51+ }
52+
53+ private:
54+ Logger () {
55+ char tempPath[MAX_PATH];
56+ std::filesystem::path logPath;
57+ const auto len = GetTempPath (MAX_PATH, tempPath);
58+ if (len != 0 && len <= MAX_PATH) {
59+ logPath = tempPath;
60+ }
61+ logPath /= " boinc_installer.log" ;
62+ ofs.open (logPath, std::ios::app);
63+ }
64+ ~Logger () {
65+ if (ofs.is_open ()) {
66+ ofs.close ();
67+ }
68+ }
69+ Logger (const Logger&) = delete ;
70+ Logger& operator =(const Logger&) = delete ;
71+
72+ std::ofstream ofs;
73+ };
74+
75+ void Log (const std::string& message) {
76+ Logger::Instance ().Log (message);
77+ }
78+
3479HBITMAP hBitmap = NULL ;
3580
3681void LoadSplashImage (HDC hdc, HWND hwnd) {
@@ -69,25 +114,31 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
69114}
70115
71116std::string computeMD5 (const void * buffer, size_t size) {
117+ Log (" Computing MD5 hash..." );
118+
72119 unsigned char md5Digest[MD5_DIGEST_LENGTH];
73120 auto * mdContext = EVP_MD_CTX_new ();
74121
75122 if (mdContext == nullptr ) {
123+ Log (" Failed to create MD5 context." );
76124 return {};
77125 }
78126
79127 if (EVP_DigestInit_ex (mdContext, EVP_md5 (), nullptr ) != 1 ) {
80128 EVP_MD_CTX_free (mdContext);
129+ Log (" Failed to initialize MD5 context." );
81130 return {};
82131 }
83132
84133 if (EVP_DigestUpdate (mdContext, buffer, size) != 1 ) {
85134 EVP_MD_CTX_free (mdContext);
135+ Log (" Failed to update MD5 context." );
86136 return {};
87137 }
88138
89139 if (EVP_DigestFinal_ex (mdContext, md5Digest, nullptr ) != 1 ) {
90140 EVP_MD_CTX_free (mdContext);
141+ Log (" Failed to finalize MD5 digest." );
91142 return {};
92143 }
93144
@@ -99,38 +150,45 @@ std::string computeMD5(const void* buffer, size_t size) {
99150 static_cast <int >(md5Digest[i]);
100151 }
101152
153+ Log (" MD5 hash computed successfully: " + oss.str ());
102154 return oss.str ();
103155}
104156
105157
106158bool ExtractResourceAndExecute (UINT ResourceID, std::string OutputFileName,
107159 std::string CmdParameters)
108160{
161+ Log (" Extracting resource and executing installer..." );
109162 try {
110163 auto hResource = FindResource (nullptr , MAKEINTRESOURCE (ResourceID),
111164 " BINARY" );
112165 if (hResource == nullptr ) {
166+ Log (" Failed to find resource." );
113167 return false ;
114168 }
115169
116170 auto hFileResource = LoadResource (nullptr , hResource);
117171 if (hFileResource == nullptr ) {
172+ Log (" Failed to load resource." );
118173 return false ;
119174 }
120175
121176 auto lpFile = LockResource (hFileResource);
122177 if (lpFile == nullptr ) {
178+ Log (" Failed to lock resource." );
123179 return false ;
124180 }
125181
126182 const auto dwSize = SizeofResource (nullptr , hResource);
127183 if (dwSize == 0 ) {
184+ Log (" Resource size is zero." );
128185 return false ;
129186 }
130187
131188 char buffer[MAX_PATH];
132189 const auto result = GetWindowsDirectory (buffer, MAX_PATH);
133190 if (result == 0 || result > MAX_PATH) {
191+ Log (" Failed to get Windows directory." );
134192 MessageBox (NULL , " Failed to get the Windows directory!" , " Error" ,
135193 MB_ICONERROR);
136194 return false ;
@@ -140,7 +198,10 @@ bool ExtractResourceAndExecute(UINT ResourceID, std::string OutputFileName,
140198 const auto outputDir = windowsDir / " Downloaded Installations" /
141199 " BOINC" / BOINC_VERSION_STRING / computeMD5 (lpFile, dwSize);
142200 if (!std::filesystem::exists (outputDir)) {
201+ Log (" Creating output directory: " + outputDir.string ());
143202 if (!std::filesystem::create_directories (outputDir)) {
203+ Log (" Failed to create output directory: " +
204+ outputDir.string ());
144205 MessageBox (NULL , " Failed to create output directory!" , " Error" ,
145206 MB_ICONERROR);
146207 return false ;
@@ -153,11 +214,13 @@ bool ExtractResourceAndExecute(UINT ResourceID, std::string OutputFileName,
153214 auto hFilemap = CreateFileMapping (hFile, nullptr , PAGE_READWRITE, 0 ,
154215 dwSize, nullptr );
155216 if (hFilemap == nullptr ) {
217+ Log (" Failed to create file mapping." );
156218 return false ;
157219 }
158220
159221 auto lpBaseAddress = MapViewOfFile (hFilemap, FILE_MAP_WRITE, 0 , 0 , 0 );
160222 if (lpBaseAddress == nullptr ) {
223+ Log (" Failed to map view of file." );
161224 return false ;
162225 }
163226 CopyMemory (lpBaseAddress, lpFile, dwSize);
@@ -170,14 +233,19 @@ bool ExtractResourceAndExecute(UINT ResourceID, std::string OutputFileName,
170233 CmdParameters.c_str (), nullptr ,
171234 CmdParameters == " " ? SW_SHOWNORMAL : SW_HIDE);
172235 if (reinterpret_cast <int >(hInstance) <= 32 ) {
236+ Log (" Failed to execute installer" );
173237 MessageBox (NULL , " Failed to execute the installer!" , " Error" ,
174238 MB_ICONERROR);
175239 return false ;
176240 }
177241
242+ Log (" Installer executed successfully: " +
243+ (outputDir / OutputFileName).string ());
178244 return true ;
179245 }
180246 catch (const std::exception& ex) {
247+ Log (" Exception occurred while extracting resource: " +
248+ std::string (ex.what ()));
181249 MessageBox (NULL , " Failed to extract resource!" , ex.what (),
182250 MB_ICONERROR);
183251 return false ;
0 commit comments