We want to avoid GetTempPath2W since it is only available on Windows 11 and some of the latest versions of Windows 10. The only case that they're different is when running as SYSTEM. Most users won't run the desktop launcher as SYSTEM; for those who do (please don't), we now hold a handle to the file during the execution to prevent renaming or symbolic link issues. This should prevent any theoretical issues that could have happened with GetTempPath2W. Differential Revision: https://phabricator.services.mozilla.com/D272905
50 lines
1.8 KiB
C++
50 lines
1.8 KiB
C++
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
#include <optional>
|
|
#include <rpc.h>
|
|
#include <string>
|
|
#include <windows.h>
|
|
|
|
static const size_t BUFFER_LEN = MAX_PATH + 1;
|
|
|
|
/**
|
|
* Create a unique tempfile name in a temp directory appropriate
|
|
* for this user.
|
|
* @return The temp filename, or std::nullopt on failure
|
|
*/
|
|
std::optional<std::wstring> get_tempfile_name() {
|
|
wchar_t pathBuffer[BUFFER_LEN];
|
|
wchar_t filenameBuffer[BUFFER_LEN];
|
|
UUID uuid;
|
|
DWORD pathLen = GetTempPathW(BUFFER_LEN, pathBuffer);
|
|
if (pathLen > BUFFER_LEN || pathLen == 0) {
|
|
// Error getting path
|
|
return std::nullopt;
|
|
}
|
|
// Use a UUID as a convenient source of random bits
|
|
RPC_STATUS uuidStatus = UuidCreate(&uuid);
|
|
if (uuidStatus != RPC_S_OK && uuidStatus != RPC_S_UUID_LOCAL_ONLY) {
|
|
// Error creating a unique UUID for the filename
|
|
return std::nullopt;
|
|
}
|
|
|
|
// Since we're only using the UUID data structure as a source of random bits,
|
|
// rather than as something that we need to serialize and deserialize as a
|
|
// UUID, it's best not to leak the internal implementation details out of the
|
|
// abstraction of the filename.
|
|
// With that in mind, the following code converts the UUID data structure into
|
|
// a sequence of hexadecimal digits.
|
|
ULONG data4msb =
|
|
*((ULONG*)uuid.Data4); // First 4 bytes of the 8-byte Data4 char array
|
|
ULONG data4lsb =
|
|
*((ULONG*)(uuid.Data4 +
|
|
4)); // Second 4 bytes of the 8-byte Data4 char array
|
|
if (swprintf_s(filenameBuffer, BUFFER_LEN, L"%sfx%X%X%X%X%X.exe", pathBuffer,
|
|
uuid.Data1, uuid.Data2, uuid.Data3, data4msb, data4lsb) < 0) {
|
|
return std::nullopt;
|
|
}
|
|
|
|
return std::wstring(filenameBuffer);
|
|
}
|