From 8ff7ba31420c0b71ea87984c26cd867b4bcb7c90 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