From 71a9e9b3cb98348c77fe370eb5643faf47613c61 Mon Sep 17 00:00:00 2001 From: Kirk Steuber Date: Wed, 8 Dec 2021 19:13:01 +0000 Subject: [PATCH] Bug 1732435 - r=nalexander Differential Revision: https://phabricator.services.mozilla.com/D127897 --- toolkit/xre/MultiInstanceLock.cpp | 80 +++++++++++++++++++++++-------- 1 file changed, 61 insertions(+), 19 deletions(-) diff --git a/toolkit/xre/MultiInstanceLock.cpp b/toolkit/xre/MultiInstanceLock.cpp index a04cca08bd3c..9dfacd0cff6d 100644 --- a/toolkit/xre/MultiInstanceLock.cpp +++ b/toolkit/xre/MultiInstanceLock.cpp @@ -12,7 +12,9 @@ #include "nsPromiseFlatString.h" #include "updatedefines.h" // for NS_t* definitions -#ifndef XP_WIN +#ifdef XP_WIN +# include +#else # include # include # include @@ -22,29 +24,69 @@ namespace mozilla { static bool GetLockFileName(const char* nameToken, const char16_t* installPath, nsCString& filePath) { +#ifdef XP_WIN + // On Windows, the lock file is placed at the path + // [updateDirectory]\[nameToken]-[pathHash], so first we need to get the + // update directory path and then append the file name. + + // Note: This will return something like + // C:\ProgramData\Mozilla-1de4eec8-1241-4177-a864-e594e8d1fb38\updates\ + // But we actually are going to want to return the root update directory, + // the grandparent of this directory, which will look something like this: + // C:\ProgramData\Mozilla-1de4eec8-1241-4177-a864-e594e8d1fb38 + mozilla::UniquePtr updateDir; + HRESULT hr = GetCommonUpdateDirectory( + reinterpret_cast(installPath), updateDir); + if (FAILED(hr)) { + return false; + } + + // For the path manipulation that we are about to do, it is important that + // the update directory have no trailing slash. + size_t len = wcslen(updateDir.get()); + if (len == 0) { + return false; + } + if (updateDir.get()[len - 1] == '/' || updateDir.get()[len - 1] == '\\') { + updateDir.get()[len - 1] = '\0'; + } + + wchar_t* hashPtr = PathFindFileNameW(updateDir.get()); + // PathFindFileNameW returns a pointer to the beginning of the string on + // failure. + if (hashPtr == updateDir.get()) { + return false; + } + + // We need to make a copy of the hash before we modify updateDir to get the + // root update dir. + size_t hashSize = wcslen(hashPtr) + 1; + mozilla::UniquePtr hash = mozilla::MakeUnique(hashSize); + errno_t error = wcscpy_s(hash.get(), hashSize, hashPtr); + if (error != 0) { + return false; + } + + // Get the root update dir from the update dir. + BOOL success = PathRemoveFileSpecW(updateDir.get()); + if (!success) { + return false; + } + success = PathRemoveFileSpecW(updateDir.get()); + if (!success) { + return false; + } + + filePath = + nsPrintfCString("%s\\%s-%s", NS_ConvertUTF16toUTF8(updateDir.get()).get(), + nameToken, NS_ConvertUTF16toUTF8(hash.get()).get()); + +#else mozilla::UniquePtr pathHash; if (!GetInstallHash(installPath, pathHash)) { return false; } -#ifdef XP_WIN - // On Windows, the lock file is placed at the path - // ProgramData\[vendor]\[nameToken]-[pathHash], so first we need to get the - // ProgramData path and then append our directory and the file name. - PWSTR programDataPath; - HRESULT hr = SHGetKnownFolderPath(FOLDERID_ProgramData, KF_FLAG_CREATE, - nullptr, &programDataPath); - if (FAILED(hr)) { - return false; - } - mozilla::UniquePtr programDataPathUnique( - programDataPath); - - filePath = nsPrintfCString( - "%s\\%s\\%s-%s", NS_ConvertUTF16toUTF8(programDataPath).get(), - MOZ_APP_VENDOR, nameToken, NS_ConvertUTF16toUTF8(pathHash.get()).get()); - -#else // On POSIX platforms the base path is /tmp/[vendor][nameToken]-[pathHash]. filePath = nsPrintfCString("/tmp/%s%s-%s", MOZ_APP_VENDOR, nameToken, pathHash.get());