From 4cd736ccd8348aaa68315daf2e982e36dbd1a34e Mon Sep 17 00:00:00 2001 From: Darin Fisher Date: Mon, 31 Jul 2023 08:23:18 -0700 Subject: [PATCH] Fix the way known locations are generated on windows Use GetAllUsersProfileDirectoryW and GetProfilesDirectoryW instead of hardcoding paths. Previously, the known locations were treated as UNC paths, which would typically fail to be read after ~5 second timeout. --- .../Base.subproj/CFKnownLocations.c | 50 +++++++++++++++---- 1 file changed, 41 insertions(+), 9 deletions(-) diff --git a/CoreFoundation/Base.subproj/CFKnownLocations.c b/CoreFoundation/Base.subproj/CFKnownLocations.c index 4ad3fbcd6e..c9c9ed44a1 100644 --- a/CoreFoundation/Base.subproj/CFKnownLocations.c +++ b/CoreFoundation/Base.subproj/CFKnownLocations.c @@ -16,6 +16,10 @@ #include +#if TARGET_OS_WIN32 +#include +#endif + CFURLRef _Nullable _CFKnownLocationCreatePreferencesURLForUser(CFKnownLocationUser user, CFStringRef _Nullable username) { CFURLRef location = NULL; @@ -76,20 +80,48 @@ CFURLRef _Nullable _CFKnownLocationCreatePreferencesURLForUser(CFKnownLocationUs #elif TARGET_OS_WIN32 switch (user) { - case _kCFKnownLocationUserAny: - location = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, CFSTR("\\Users\\All Users\\AppData\\Local"), kCFURLWindowsPathStyle, true); + case _kCFKnownLocationUserAny: { + DWORD size = 0; + GetAllUsersProfileDirectoryW(NULL, &size); + + wchar_t* path = (wchar_t*)malloc(size * sizeof(wchar_t)); + GetAllUsersProfileDirectoryW(path, &size); + + CFStringRef allUsersPath = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, path, size - 1); + free(path); + + location = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, allUsersPath, kCFURLWindowsPathStyle, true); + CFRelease(allUsersPath); break; + } case _kCFKnownLocationUserCurrent: username = CFGetUserName(); // fallthrough - case _kCFKnownLocationUserByName: - const char *user = CFStringGetCStringPtr(username, kCFStringEncodingUTF8); - CFURLRef userdir = CFURLCreateFromFileSystemRepresentation(kCFAllocatorSystemDefault, (const unsigned char *)user, strlen(user), true); - CFURLRef homedir = CFURLCreateWithFileSystemPathRelativeToBase(kCFAllocatorSystemDefault, CFSTR("\\Users"), kCFURLWindowsPathStyle, true, userdir); - location = CFURLCreateWithFileSystemPathRelativeToBase(kCFAllocatorSystemDefault, CFSTR("\\AppData\\Local"), kCFURLWindowsPathStyle, true, homedir); - CFRelease(homedir); - CFRelease(userdir); + 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); + } break; + } } #elif TARGET_OS_ANDROID