QFileSystemEngine/Win: Use GetTempPath2 when available

Because the documentation for GetTempPath nows says apps should call
GetTempPath2.[0]

Starting with Windows 11[1], and recently Windows 10[2],
GetTempPath2 was added. The difference being that elevated
processes are returned a different directory. Usually
'C:\Windows\SystemTemp'.

Currently temporary files of an elevated process may be placed in a
world write-able location. GetTempPath2, by default, but can be
overridden, places it in a directory that's only accessible by SYSTEM
and administrators.

[0] https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettemppathw#remarks
[1] https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettemppath2w
(Minimum supported client - Windows 11 Build 22000)
[2] https://blogs.windows.com/windows-insider/2025/03/13/releasing-windows-10-build-19045-5674-to-the-release-preview-channel/
(This update enables system processes to store temporary files ...)

[ChangeLog][QtCore][Important Behavior Changes] On
Windows, generating temporary directories for processes with elevated
privileges may now return a different path with a stricter
set of permissions. Please consult Microsoft's documentation from when
they made the same change for the .NET framework:
https://support.microsoft.com/en-us/topic/gettemppath-changes-in-windows-february-cumulative-update-preview-4cc631fb-9d97-4118-ab6d-f643cd0a7259

Pick-to: 6.9 6.8 6.5 5.15
Change-Id: I5caf11151fb2f711bbc5599231f140598b3c9d03
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
This commit is contained in:
Mårten Nordheim 2025-03-17 14:22:11 +01:00 committed by Marc Mutz
parent 7afa197a44
commit 69633bcb58

View File

@ -1651,7 +1651,15 @@ QString QFileSystemEngine::tempPath()
{
QString ret;
wchar_t tempPath[MAX_PATH];
const DWORD len = GetTempPath(MAX_PATH, tempPath);
using GetTempPathPrototype = DWORD (WINAPI *)(DWORD, LPWSTR);
// We try to resolve GetTempPath2 and use that, otherwise fall back to GetTempPath:
static GetTempPathPrototype getTempPathW = []() {
const HMODULE kernel32 = GetModuleHandleW(L"kernel32.dll");
if (auto *func = QFunctionPointer(GetProcAddress(kernel32, "GetTempPath2W")))
return GetTempPathPrototype(func);
return GetTempPath;
}();
const DWORD len = getTempPathW(MAX_PATH, tempPath);
if (len) { // GetTempPath() can return short names, expand.
wchar_t longTempPath[MAX_PATH];
const DWORD longLen = GetLongPathName(tempPath, longTempPath, MAX_PATH);