Skip to content

Commit 16f081e

Browse files
committed
Add write-probing for temporary directories in update installer
1 parent f844e10 commit 16f081e

File tree

1 file changed

+45
-6
lines changed

1 file changed

+45
-6
lines changed

Client/loader/Install.cpp

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,45 @@ static bool TerminateFileLockingProcesses(const SString& absolutePath, const SSt
285285
}
286286
}
287287

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+
288327
/**
289328
* @brief Retrieves the list of files for the update.
290329
* @param sourceRoot Path to the directory with update files
@@ -554,11 +593,11 @@ static int RunInstall()
554593
return 0;
555594

556595
// Create a backup directory for disaster recovery.
557-
const SString backupRoot = MakeUniquePath(sourceRoot + "_bak_");
596+
const SString backupRoot = CreateWritableDirectory(sourceRoot + "_bak_");
558597

559-
if (!MkDir(backupRoot))
598+
if (backupRoot.empty())
560599
{
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"));
562601
return 3;
563602
}
564603

@@ -859,12 +898,12 @@ SString CheckOnRestartCommand()
859898
SString strArchivePath, strArchiveName;
860899
strFile.Split("\\", &strArchivePath, &strArchiveName, -1);
861900

862-
SString strTempPath = MakeUniquePath(strArchivePath + "\\_" + strArchiveName + "_tmp_");
901+
const SString sourceRoot = CreateWritableDirectory(strArchivePath + "\\_" + strArchiveName + "_tmp_");
863902

864-
if (!MkDir(strTempPath))
903+
if (sourceRoot.empty())
865904
return "FileError1";
866905

867-
if (!SetCurrentDirectory(strTempPath))
906+
if (!SetCurrentDirectory(sourceRoot))
868907
return "FileError2";
869908

870909
// Start progress bar

0 commit comments

Comments
 (0)