@@ -285,6 +285,45 @@ static bool TerminateFileLockingProcesses(const SString& absolutePath, const SSt
285
285
}
286
286
}
287
287
288
+ /* *
289
+ * @brief Creates a writable directory for any purpose.
290
+ * @param templateRoot The template path to a directory
291
+ * @return A path to a new directory, empty string on error
292
+ */
293
+ static SString CreateWritableDirectory (const SString& templateRoot)
294
+ {
295
+ SString fileName = ExtractFilename (templateRoot);
296
+
297
+ std::vector<SString> candidates{
298
+ MakeUniquePath (templateRoot),
299
+ PathJoin (GetMTATempPath (), " upcache" , fileName),
300
+ };
301
+
302
+ const SString probeName = " probe.file" ;
303
+
304
+ for (const SString& candidate : candidates)
305
+ {
306
+ if (!MkDir (candidate))
307
+ continue ;
308
+
309
+ DirectoryDeleteScope deleteCandidate (candidate);
310
+
311
+ const SString probeFile = PathJoin (candidate, probeName);
312
+
313
+ if (!FileSave (probeFile, probeName))
314
+ continue ;
315
+
316
+ if (FileSize (probeFile) != probeName.size ())
317
+ continue ;
318
+
319
+ FileDelete (probeFile);
320
+ deleteCandidate.Release ();
321
+ return candidate;
322
+ }
323
+
324
+ return {};
325
+ }
326
+
288
327
/* *
289
328
* @brief Retrieves the list of files for the update.
290
329
* @param sourceRoot Path to the directory with update files
@@ -554,11 +593,11 @@ static int RunInstall()
554
593
return 0 ;
555
594
556
595
// Create a backup directory for disaster recovery.
557
- const SString backupRoot = MakeUniquePath (sourceRoot + " _bak_" );
596
+ const SString backupRoot = CreateWritableDirectory (sourceRoot + " _bak_" );
558
597
559
- if (! MkDir ( backupRoot))
598
+ if (backupRoot. empty ( ))
560
599
{
561
- AddReportLog (5055 , SString (" RunInstall: Unable to create backup directory '%s' " , backupRoot. c_str () ));
600
+ AddReportLog (5055 , SStringX (" RunInstall: Unable to create writable backup directory" ));
562
601
return 3 ;
563
602
}
564
603
@@ -859,12 +898,12 @@ SString CheckOnRestartCommand()
859
898
SString strArchivePath, strArchiveName;
860
899
strFile.Split (" \\ " , &strArchivePath, &strArchiveName, -1 );
861
900
862
- SString strTempPath = MakeUniquePath (strArchivePath + " \\ _" + strArchiveName + " _tmp_" );
901
+ const SString sourceRoot = CreateWritableDirectory (strArchivePath + " \\ _" + strArchiveName + " _tmp_" );
863
902
864
- if (! MkDir (strTempPath ))
903
+ if (sourceRoot. empty ( ))
865
904
return " FileError1" ;
866
905
867
- if (!SetCurrentDirectory (strTempPath ))
906
+ if (!SetCurrentDirectory (sourceRoot ))
868
907
return " FileError2" ;
869
908
870
909
// Start progress bar
0 commit comments