[6.3] Windows: Use SHGetKnownFolderPath to compute LocalAppData
#5295
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR targets swiftlang:release/6.3.
On Windows, it's not guaranteed that
USERPROFILEis equivalent to%SYSTEMDRIVE%\Users\%USERNAME%. It is therefore possible thatUserDefaultstries to write to a non-existent location, in which case it will never work. When this happens, all writes silently no-op.This PR uses the Shell API
SHGetKnownFolderPathto programmatically get the location of%LOCALAPPDATA%instead of manually building the path.Explanation:
USERPROFILEis equivalent to%SYSTEMDRIVE%\Users\%USERNAME%. Because of this, building the LocalAppData path using environment variables or string concatenation can result in a path that does not exist, and writes may silently no-op.SHGetKnownFolderPath(&FOLDERID_LocalAppData, ...)to get the correct per-user LocalAppData path.<shlobj_core.h>and useCoTaskMemFreeto free the pointer fromSHGetKnownFolderPath. The change also tightens a fallthrough control flow for_kCFKnownLocationUserCurrentso we do not accidentally fall through when the username lookup succeeded.Scope:
Sources/CoreFoundation/CFKnownLocations.c.CFKnownLocationUserByName) may no longer compute the LocalAppData for a specified user other than the current user; instead it uses the OS API to get the path for the current account. If the intent is to support accessing preferences for other users on Windows, this must be assessed (see Risk section).Issues:
USERPROFILEbeing equivalent to%SYSTEMDRIVE%\Users\%USERNAME%.Original PRs:
Derived from mainline work: "use shgetknownfolderpath instead of hand building the path" and follow-up Windows fixes.
Risk:
LocalAppDatapath for a user other than the current user (e.g., by combiningGetProfilesDirectoryW+ username); the new approach usesSHGetKnownFolderPathwhich returns the path for the effective user context. If the project intends to support preference paths for other users (ByName) on Windows, then that feature may need an explicit approach (e.g., obtaining a path via SID impersonation orGetProfilesDirectoryWfor other users).SHGetKnownFolderPathandFOLDERID_LocalAppDatawhich requires appropriate headers (shlobj_core.h) and linking to Windows libraries (ole32 or shell32 may be required). Verify that the build system provides these for Windows targets.SHGetKnownFolderPathmay fail on older Windows versions; ensure fallback is appropriate if needed (i.e., graceful fallback to prior methods or to a sensible default).SHGetKnownFolderPathcorrectly (usingCoTaskMemFree) — the commit does this.Testing:
Reviewers: