Skip to content

Commit 60dc9fd

Browse files
committed
CFKnownLocations // Refactor Win32 part aligning to dotNET 10 behavior.
1 parent 14cd1c3 commit 60dc9fd

File tree

1 file changed

+56
-26
lines changed

1 file changed

+56
-26
lines changed

Sources/CoreFoundation/CFKnownLocations.c

Lines changed: 56 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -82,38 +82,68 @@ CFURLRef _Nullable _CFKnownLocationCreatePreferencesURLForUser(CFKnownLocationUs
8282

8383
switch (user) {
8484
case _kCFKnownLocationUserAny: {
85-
DWORD size = 0;
86-
GetAllUsersProfileDirectoryW(NULL, &size);
87-
88-
wchar_t* path = (wchar_t*)malloc(size * sizeof(wchar_t));
89-
GetAllUsersProfileDirectoryW(path, &size);
90-
91-
CFStringRef allUsersPath = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, path, size - 1);
92-
free(path);
93-
94-
location = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, allUsersPath, kCFURLWindowsPathStyle, true);
95-
CFRelease(allUsersPath);
85+
// Try SHGetKnownFolderPath first (preferred method)
86+
wchar_t* path = NULL;
87+
HRESULT hr = SHGetKnownFolderPath(&FOLDERID_ProgramData, 0, NULL, &path);
88+
89+
if (SUCCEEDED(hr) && path != NULL) {
90+
CFStringRef allUsersPath = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, path, wcslen(path));
91+
CoTaskMemFree(path);
92+
93+
location = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, allUsersPath, kCFURLWindowsPathStyle, true);
94+
CFRelease(allUsersPath);
95+
} else {
96+
// Fallback to environment variable
97+
if (path != NULL) {
98+
CoTaskMemFree(path);
99+
}
100+
101+
const char* programData = __CFgetenv("ProgramData");
102+
if (programData == NULL) {
103+
programData = __CFgetenv("ALLUSERSPROFILE");
104+
}
105+
106+
if (programData != NULL) {
107+
CFStringRef envPath = CFStringCreateWithCString(kCFAllocatorSystemDefault, programData, kCFStringEncodingUTF8);
108+
if (envPath != NULL) {
109+
location = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, envPath, kCFURLWindowsPathStyle, true);
110+
CFRelease(envPath);
111+
}
112+
}
113+
}
96114
break;
97115
}
98116
case _kCFKnownLocationUserCurrent:
99-
username = CFGetUserName();
100-
// The above API returns a non-NULL CFStringRef. The failed result is an empty string.
101-
// We need to check for that case and fall through to the next case.
102-
Boolean isEmpty = CFEqual(username, CFSTR(""));
103-
CFRelease(username);
104-
if (!isEmpty) {
105-
break;
106-
}
107-
// fallthrough.
117+
// Leaving this case unhandled (fallthrough) on WinNT.
118+
// Reason (according to `./include/CFKnownLocations.h`):
119+
// The username parameter is ignored for any user constant other than …ByName.
120+
// …ByName with a NULL username is the same as …Current.
108121
case _kCFKnownLocationUserByName: {
122+
// Try SHGetKnownFolderPath first (preferred method)
109123
wchar_t* path = NULL;
110-
SHGetKnownFolderPath(&FOLDERID_LocalAppData, 0, NULL, &path);
124+
HRESULT hr = SHGetKnownFolderPath(&FOLDERID_LocalAppData, 0, NULL, &path);
111125

112-
CFStringRef userPath = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, path, wcslen(path));
113-
CoTaskMemFree(path);
114-
115-
location = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, userPath, kCFURLWindowsPathStyle, true);
116-
CFRelease(userPath);
126+
if (SUCCEEDED(hr) && path != NULL) {
127+
CFStringRef userPath = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, path, wcslen(path));
128+
CoTaskMemFree(path);
129+
130+
location = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, userPath, kCFURLWindowsPathStyle, true);
131+
CFRelease(userPath);
132+
} else {
133+
// Fallback to environment variable
134+
if (path != NULL) {
135+
CoTaskMemFree(path);
136+
}
137+
138+
const char* localAppData = __CFgetenv("LOCALAPPDATA");
139+
if (localAppData != NULL) {
140+
CFStringRef envPath = CFStringCreateWithCString(kCFAllocatorSystemDefault, localAppData, kCFStringEncodingUTF8);
141+
if (envPath != NULL) {
142+
location = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, envPath, kCFURLWindowsPathStyle, true);
143+
CFRelease(envPath);
144+
}
145+
}
146+
}
117147
break;
118148
}
119149
}

0 commit comments

Comments
 (0)