From 51485bdef6822cf3e2c48420a8fe9fd90b0932b3 Mon Sep 17 00:00:00 2001 From: Steve Kirbach Date: Fri, 28 Jun 2024 11:53:22 -0700 Subject: [PATCH 1/2] use shgetknownfolderpath instead of hand building the path --- .../Base.subproj/CFKnownLocations.c | 62 +++++++------------ 1 file changed, 22 insertions(+), 40 deletions(-) diff --git a/CoreFoundation/Base.subproj/CFKnownLocations.c b/CoreFoundation/Base.subproj/CFKnownLocations.c index c9c9ed44a1..27cafdac2c 100644 --- a/CoreFoundation/Base.subproj/CFKnownLocations.c +++ b/CoreFoundation/Base.subproj/CFKnownLocations.c @@ -1,6 +1,6 @@ /* CFKnownLocations.c Copyright (c) 1999-2017, Apple Inc. and the Swift project authors - + Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information @@ -18,26 +18,27 @@ #if TARGET_OS_WIN32 #include +#include #endif CFURLRef _Nullable _CFKnownLocationCreatePreferencesURLForUser(CFKnownLocationUser user, CFStringRef _Nullable username) { CFURLRef location = NULL; - + #if TARGET_OS_MAC - + /* Building for a Darwin OS. (We use these paths on Swift builds as well, so that we can interoperate a little with Darwin's defaults(1) command and the other system facilities; but you want to use the system version of CF if possible on those platforms, which will talk to cfprefsd(8) and has stronger interprocess consistency guarantees.) - + User: - Any: /Library/Preferences - Current: $HOME/Library/Preferences */ - + switch (user) { case _kCFKnownLocationUserAny: location = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, CFSTR("/Library/Preferences"), kCFURLPOSIXPathStyle, true); break; - + case _kCFKnownLocationUserCurrent: username = NULL; // passthrough to: @@ -45,26 +46,26 @@ CFURLRef _Nullable _CFKnownLocationCreatePreferencesURLForUser(CFKnownLocationUs CFURLRef home = CFCopyHomeDirectoryURLForUser(username); location = CFURLCreateWithFileSystemPathRelativeToBase(kCFAllocatorSystemDefault, CFSTR("/Library/Preferences"), kCFURLPOSIXPathStyle, true, home); CFRelease(home); - + break; } - + } #elif !DEPLOYMENT_RUNTIME_OBJC && !TARGET_OS_WIN32 && !TARGET_OS_ANDROID - + /* Building for an OS that uses the FHS, BSD's hier(7), and/or the XDG specification for paths: - + User: - Any: /usr/local/etc/ - Current: $XDG_CONFIG_PATH (usually: $HOME/.config/). */ - + switch (user) { case _kCFKnownLocationUserAny: location = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, CFSTR("/usr/local/etc"), kCFURLPOSIXPathStyle, true); break; - + case _kCFKnownLocationUserByName: assert(username == NULL); // passthrough to: @@ -72,11 +73,11 @@ CFURLRef _Nullable _CFKnownLocationCreatePreferencesURLForUser(CFKnownLocationUs CFStringRef path = _CFXDGCreateConfigHomePath(); location = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, path, kCFURLPOSIXPathStyle, true); CFRelease(path); - + break; } } - + #elif TARGET_OS_WIN32 switch (user) { @@ -96,30 +97,11 @@ CFURLRef _Nullable _CFKnownLocationCreatePreferencesURLForUser(CFKnownLocationUs } case _kCFKnownLocationUserCurrent: username = CFGetUserName(); - // fallthrough + break; case _kCFKnownLocationUserByName: { - DWORD size = 0; - GetProfilesDirectoryW(NULL, &size); - - wchar_t* path = (wchar_t*)malloc(size * sizeof(wchar_t)); - GetProfilesDirectoryW(path, &size); - - CFStringRef pathRef = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, path, size - 1); - free(path); - - CFURLRef profilesDir = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, pathRef, kCFURLWindowsPathStyle, true); - CFRelease(pathRef); - - CFURLRef usernameDir = CFURLCreateCopyAppendingPathComponent(kCFAllocatorSystemDefault, profilesDir, username, true); - CFURLRef appdataDir = CFURLCreateCopyAppendingPathComponent(kCFAllocatorSystemDefault, usernameDir, CFSTR("AppData"), true); - location = CFURLCreateCopyAppendingPathComponent(kCFAllocatorSystemDefault, appdataDir, CFSTR("Local"), true); - CFRelease(usernameDir); - CFRelease(appdataDir); - - CFRelease(profilesDir); - if (user == _kCFKnownLocationUserCurrent) { - CFRelease(username); - } + wchar_t* path = NULL; + SHGetKnownFolderPath(&FOLDERID_LocalAppData, 0, NULL, &path); + location = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, path, kCFURLWindowsPathStyle, true); break; } } @@ -148,10 +130,10 @@ CFURLRef _Nullable _CFKnownLocationCreatePreferencesURLForUser(CFKnownLocationUs CFRelease(userdir); #else - + #error For this platform, you need to define a preferences path for both 'any user' (i.e. installation-wide preferences) or the current user. - + #endif - + return location; } From f25cc13d661e0fef3197491af65de704d66edcd6 Mon Sep 17 00:00:00 2001 From: Steve Kirbach Date: Fri, 28 Jun 2024 11:53:46 -0700 Subject: [PATCH 2/2] release the path --- CoreFoundation/Base.subproj/CFKnownLocations.c | 1 + 1 file changed, 1 insertion(+) diff --git a/CoreFoundation/Base.subproj/CFKnownLocations.c b/CoreFoundation/Base.subproj/CFKnownLocations.c index 27cafdac2c..6ad4b3bb93 100644 --- a/CoreFoundation/Base.subproj/CFKnownLocations.c +++ b/CoreFoundation/Base.subproj/CFKnownLocations.c @@ -102,6 +102,7 @@ CFURLRef _Nullable _CFKnownLocationCreatePreferencesURLForUser(CFKnownLocationUs wchar_t* path = NULL; SHGetKnownFolderPath(&FOLDERID_LocalAppData, 0, NULL, &path); location = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, path, kCFURLWindowsPathStyle, true); + CoTaskMemFree(path); break; } }