@@ -165,7 +165,7 @@ int CUpdateRunner::ExtractUpdaterAndRun(wchar_t* lpCommandLine, bool useFallback
165
165
PROCESS_INFORMATION pi = { 0 };
166
166
STARTUPINFO si = { 0 };
167
167
CResource zipResource;
168
- wchar_t targetDir[MAX_PATH] = { 0 };
168
+ wchar_t targetDir[MAX_PATH + 1 ] = { 0 };
169
169
wchar_t logFile[MAX_PATH];
170
170
171
171
std::vector<CString> to_delete;
@@ -175,7 +175,7 @@ int CUpdateRunner::ExtractUpdaterAndRun(wchar_t* lpCommandLine, bool useFallback
175
175
DirectoryExists (envSquirrelTemp) &&
176
176
DirectoryIsWritable (envSquirrelTemp) &&
177
177
!PathIsUNCW (envSquirrelTemp)) {
178
- _swprintf_c (targetDir, _countof (targetDir), L" %s" , envSquirrelTemp);
178
+ _swprintf_c (targetDir, _countof (targetDir) - 1 , L" %s" , envSquirrelTemp);
179
179
goto gotADir;
180
180
}
181
181
@@ -191,7 +191,7 @@ int CUpdateRunner::ExtractUpdaterAndRun(wchar_t* lpCommandLine, bool useFallback
191
191
SHGetFolderPath (NULL , CSIDL_COMMON_APPDATA, NULL , SHGFP_TYPE_CURRENT, appDataDir);
192
192
GetUserName (username, &unameSize);
193
193
194
- _swprintf_c (targetDir, _countof (targetDir), L" %s\\ %s" , appDataDir, username);
194
+ _swprintf_c (targetDir, _countof (targetDir) - 1 , L" %s\\ %s" , appDataDir, username);
195
195
196
196
if (!CreateDirectory (targetDir, NULL ) && GetLastError () != ERROR_ALREADY_EXISTS) {
197
197
wchar_t err[4096 ];
@@ -203,7 +203,7 @@ int CUpdateRunner::ExtractUpdaterAndRun(wchar_t* lpCommandLine, bool useFallback
203
203
204
204
gotADir:
205
205
206
- wcscat_s (targetDir, _countof (targetDir), L" \\ SquirrelTemp" );
206
+ wcscat_s (targetDir, _countof (targetDir) - 1 , L" \\ SquirrelTemp" );
207
207
208
208
if (!CreateDirectory (targetDir, NULL ) && GetLastError () != ERROR_ALREADY_EXISTS) {
209
209
wchar_t err[4096 ];
@@ -216,6 +216,35 @@ int CUpdateRunner::ExtractUpdaterAndRun(wchar_t* lpCommandLine, bool useFallback
216
216
goto failedExtract;
217
217
}
218
218
219
+ const char tempDirValues[] = " \0 abcdefghijklmnopqrstuvwxyz" ;
220
+ int tempDirValuesCount = sizeof (tempDirValues) - 1 ;
221
+ bool tempDirCreated = false ;
222
+ for (int i = 1 ; i < (tempDirValuesCount * tempDirValuesCount * tempDirValuesCount * tempDirValuesCount); i++) {
223
+ int c0 = i % tempDirValuesCount;
224
+ int c1 = (i / tempDirValuesCount) % tempDirValuesCount;
225
+ int c2 = (i / (tempDirValuesCount * tempDirValuesCount)) % tempDirValuesCount;
226
+ int c3 = (i / (tempDirValuesCount * tempDirValuesCount * tempDirValuesCount)) % tempDirValuesCount;
227
+
228
+ wchar_t tempDir[MAX_PATH] = { 0 };
229
+ _swprintf_c (tempDir, _countof (tempDir), L" %s\\ temp%c%c%c%c" , targetDir, tempDirValues[c3], tempDirValues[c2], tempDirValues[c1], tempDirValues[c0]);
230
+
231
+ if (CreateDirectory (tempDir, NULL )) {
232
+ _swprintf_c (targetDir, _countof (targetDir) - 1 , L" %s" , tempDir);
233
+ tempDirCreated = true ;
234
+ break ;
235
+ }
236
+ }
237
+ if (!tempDirCreated) {
238
+ wchar_t err[4096 ];
239
+ _swprintf_c (err, _countof (err), L" Unable to write to %s - IT policies may be restricting access to this folder" , targetDir);
240
+
241
+ if (useFallbackDir) {
242
+ DisplayErrorMessage (CString (err), NULL );
243
+ }
244
+
245
+ goto failedExtract;
246
+ }
247
+
219
248
swprintf_s (logFile, L" %s\\ SquirrelSetup.log" , targetDir);
220
249
221
250
if (!zipResource.Load (L" DATA" , IDR_UPDATE_ZIP)) {
@@ -296,6 +325,48 @@ int CUpdateRunner::ExtractUpdaterAndRun(wchar_t* lpCommandLine, bool useFallback
296
325
DeleteFile (to_delete[i]);
297
326
}
298
327
328
+ if (tempDirCreated) {
329
+ // Dump Squirrel-Install.log's content out of temp folder before removal
330
+ wchar_t tempSquirrelInstallLog[MAX_PATH] = { 0 };
331
+ _swprintf_c (tempSquirrelInstallLog, _countof (tempSquirrelInstallLog), L" %s\\ Squirrel-Install.log" , targetDir);
332
+
333
+ wchar_t squirrelInstallLog[MAX_PATH] = { 0 };
334
+ _swprintf_c (squirrelInstallLog, _countof (squirrelInstallLog), L" %s\\ ..\\ Squirrel-Install.log" , targetDir);
335
+
336
+ if (GetFileAttributes (squirrelInstallLog) == INVALID_FILE_ATTRIBUTES) {
337
+ MoveFile (tempSquirrelInstallLog, squirrelInstallLog);
338
+ } else {
339
+ HANDLE hTempSquirrelInstallLog = CreateFile (tempSquirrelInstallLog, GENERIC_READ, 0 , NULL , OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
340
+ HANDLE hSquirrelInstallLog = CreateFile (squirrelInstallLog, FILE_APPEND_DATA | FILE_GENERIC_READ, 0 , NULL , OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
341
+
342
+ if (hTempSquirrelInstallLog != INVALID_HANDLE_VALUE && hSquirrelInstallLog != INVALID_HANDLE_VALUE) {
343
+ DWORD dwBytesRead;
344
+ BYTE copyBuffer[4096 ];
345
+ while (ReadFile (hTempSquirrelInstallLog, copyBuffer, sizeof (copyBuffer), &dwBytesRead, NULL ) && dwBytesRead > 0 ) {
346
+ WriteFile (hSquirrelInstallLog, copyBuffer, dwBytesRead, NULL , NULL );
347
+ }
348
+ }
349
+
350
+ CloseHandle (hTempSquirrelInstallLog);
351
+ CloseHandle (hSquirrelInstallLog);
352
+ }
353
+
354
+ DeleteFile (tempSquirrelInstallLog);
355
+
356
+ // Remove temporary directory. RemoveDirectory fails even if targetDir is empty at this point
357
+ // RemoveDirectory(targetDir);
358
+ SHFILEOPSTRUCT sFileOp ;
359
+ sFileOp .hwnd = NULL ;
360
+ sFileOp .wFunc = FO_DELETE;
361
+ sFileOp .pFrom = targetDir;
362
+ sFileOp .pTo = NULL ;
363
+ sFileOp .fFlags = FOF_NOCONFIRMATION|FOF_SILENT;
364
+ sFileOp .fAnyOperationsAborted = FALSE ;
365
+ sFileOp .lpszProgressTitle = NULL ;
366
+ sFileOp .hNameMappings = NULL ;
367
+ SHFileOperation (&sFileOp );
368
+ }
369
+
299
370
CloseHandle (pi .hProcess );
300
371
CloseHandle (pi .hThread );
301
372
return (int ) dwExitCode;
0 commit comments