tempfile_name.cpp (1863B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 #include <optional> 5 #include <rpc.h> 6 #include <string> 7 #include <windows.h> 8 9 static const size_t BUFFER_LEN = MAX_PATH + 1; 10 11 /** 12 * Create a unique tempfile name in a temp directory appropriate 13 * for this user. 14 * @return The temp filename, or std::nullopt on failure 15 */ 16 std::optional<std::wstring> get_tempfile_name() { 17 wchar_t pathBuffer[BUFFER_LEN]; 18 wchar_t filenameBuffer[BUFFER_LEN]; 19 UUID uuid; 20 DWORD pathLen = GetTempPathW(BUFFER_LEN, pathBuffer); 21 if (pathLen > BUFFER_LEN || pathLen == 0) { 22 // Error getting path 23 return std::nullopt; 24 } 25 // Use a UUID as a convenient source of random bits 26 RPC_STATUS uuidStatus = UuidCreate(&uuid); 27 if (uuidStatus != RPC_S_OK && uuidStatus != RPC_S_UUID_LOCAL_ONLY) { 28 // Error creating a unique UUID for the filename 29 return std::nullopt; 30 } 31 32 // Since we're only using the UUID data structure as a source of random bits, 33 // rather than as something that we need to serialize and deserialize as a 34 // UUID, it's best not to leak the internal implementation details out of the 35 // abstraction of the filename. 36 // With that in mind, the following code converts the UUID data structure into 37 // a sequence of hexadecimal digits. 38 ULONG data4msb = 39 *((ULONG*)uuid.Data4); // First 4 bytes of the 8-byte Data4 char array 40 ULONG data4lsb = 41 *((ULONG*)(uuid.Data4 + 42 4)); // Second 4 bytes of the 8-byte Data4 char array 43 if (swprintf_s(filenameBuffer, BUFFER_LEN, L"%sfx%X%X%X%X%X.exe", pathBuffer, 44 uuid.Data1, uuid.Data2, uuid.Data3, data4msb, data4lsb) < 0) { 45 return std::nullopt; 46 } 47 48 return std::wstring(filenameBuffer); 49 }