diff --git a/core/os/os2/user.odin b/core/os/os2/user.odin index 51ee60b1a..83dc564ac 100644 --- a/core/os/os2/user.odin +++ b/core/os/os2/user.odin @@ -1,6 +1,7 @@ package os2 import "base:runtime" +@(require) import win32 "core:sys/windows" @(require_results) user_cache_dir :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error) { @@ -8,10 +9,8 @@ user_cache_dir :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error #partial switch ODIN_OS { case .Windows: - dir = get_env("LocalAppData", temp_allocator) - if dir != "" { - dir = clone_string(dir, allocator) or_return - } + guid := win32.FOLDERID_LocalAppData + return _get_known_folder_path(&guid, allocator) case .Darwin: dir = get_env("HOME", temp_allocator) if dir != "" { @@ -39,10 +38,8 @@ user_config_dir :: proc(allocator: runtime.Allocator) -> (dir: string, err: Erro #partial switch ODIN_OS { case .Windows: - dir = get_env("AppData", temp_allocator) - if dir != "" { - dir = clone_string(dir, allocator) or_return - } + guid := win32.FOLDERID_RoamingAppData + return _get_known_folder_path(&guid, allocator) case .Darwin: dir = get_env("HOME", temp_allocator) if dir != "" { @@ -66,14 +63,15 @@ user_config_dir :: proc(allocator: runtime.Allocator) -> (dir: string, err: Erro @(require_results) user_home_dir :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error) { - env := "HOME" #partial switch ODIN_OS { case .Windows: - env = "USERPROFILE" - } - if v := get_env(env, allocator); v != "" { - return v, nil + guid := win32.FOLDERID_Profile + return _get_known_folder_path(&guid, allocator) + case: + if v := get_env("HOME", allocator); v != "" { + return v, nil + } + } return "", .Invalid_Path -} - +} \ No newline at end of file diff --git a/core/os/os2/user_windows.odin b/core/os/os2/user_windows.odin new file mode 100644 index 000000000..6aef6cb4a --- /dev/null +++ b/core/os/os2/user_windows.odin @@ -0,0 +1,20 @@ +package os2 + +import "base:runtime" +@(require) import win32 "core:sys/windows" + +@(require_results) +_get_known_folder_path :: proc(rfid: win32.REFKNOWNFOLDERID, allocator: runtime.Allocator) -> (dir: string, err: Error) { + // https://learn.microsoft.com/en-us/windows/win32/api/shlobj_core/nf-shlobj_core-shgetknownfolderpath + // See also `known_folders.odin` in `core:sys/windows` for the GUIDs. + path_w: win32.LPWSTR + res := win32.SHGetKnownFolderPath(rfid, 0, nil, &path_w) + defer win32.CoTaskMemFree(path_w) + + if res != 0 { + return "", .Invalid_Path + } + + dir, _ = win32.wstring_to_utf8(path_w, -1, allocator) + return +} \ No newline at end of file