Skip to content

Commit

Permalink
Fix the way known locations are generated on windows
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
darinf authored and compnerd committed Aug 2, 2023
1 parent 9cf3489 commit 8ff7ba3
Showing 1 changed file with 41 additions and 9 deletions.
50 changes: 41 additions & 9 deletions CoreFoundation/Base.subproj/CFKnownLocations.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@

#include <assert.h>

#if TARGET_OS_WIN32
#include <userenv.h>
#endif

CFURLRef _Nullable _CFKnownLocationCreatePreferencesURLForUser(CFKnownLocationUser user, CFStringRef _Nullable username) {
CFURLRef location = NULL;

Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 8ff7ba3

Please sign in to comment.