From 65fec9134e662741923fbac24e8906df3cfbd566 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 23 Jul 2024 17:30:42 +0100 Subject: [PATCH] Use `SHFileOperationW` for `remove_all` on Windows --- core/os/os2/file_util.odin | 12 ++++++ core/os/os2/file_windows.odin | 3 +- core/os/os2/path_windows.odin | 71 ++++++++--------------------------- 3 files changed, 29 insertions(+), 57 deletions(-) diff --git a/core/os/os2/file_util.odin b/core/os/os2/file_util.odin index ca0e8c940..2011d1cc4 100644 --- a/core/os/os2/file_util.odin +++ b/core/os/os2/file_util.odin @@ -8,6 +8,18 @@ write_string :: proc(f: ^File, s: string) -> (n: int, err: Error) { return write(f, transmute([]byte)s) } +write_strings :: proc(f: ^File, strings: ..string) -> (n: int, err: Error) { + for s in strings { + m: int + m, err = write_string(f, s) + n += m + if err != nil { + return + } + } + return +} + write_byte :: proc(f: ^File, b: byte) -> (n: int, err: Error) { return write(f, []byte{b}) } diff --git a/core/os/os2/file_windows.odin b/core/os/os2/file_windows.odin index a31bd8803..9367e43d8 100644 --- a/core/os/os2/file_windows.odin +++ b/core/os/os2/file_windows.odin @@ -109,11 +109,12 @@ _open_internal :: proc(name: string, flags: File_Flags, perm: int) -> (handle: u case 0: return uintptr(h), nil case: - return 0, Platform_Error(e) + return 0, _get_platform_error() } } } } + h := win32.CreateFileW(path, access, share_mode, &sa, create_mode, attrs, nil) if h == win32.INVALID_HANDLE { return 0, _get_platform_error() diff --git a/core/os/os2/path_windows.odin b/core/os/os2/path_windows.odin index 8fc4ef721..68ce43c13 100644 --- a/core/os/os2/path_windows.odin +++ b/core/os/os2/path_windows.odin @@ -75,72 +75,31 @@ _remove_all :: proc(path: string) -> Error { return nil } - err := remove(path) if err == nil || err == .Not_Exist { return nil } TEMP_ALLOCATOR_GUARD() - dir, serr := stat_do_not_follow_links(path, temp_allocator()) - if serr != nil { - if serr == .Not_Exist || serr == .Invalid_Dir { - return nil - } - return serr - } - if dir.type != .Directory { - return err - } + dir := win32_utf8_to_wstring(path, temp_allocator()) or_return - err = nil - remove_contents: { - f: ^File - f, err = open(path) - if err != nil { - if err == .Not_Exist { - return nil - } - return err - } + empty: [1]u16 - files, read_err := read_all_directory(f, temp_allocator()) - for file in files { - err1 := remove_all(file.fullpath) - if err == nil { - err = err1 - } - } - close(f) - - if read_err == .EOF { - break remove_contents - } - - if err == nil { - err = read_err - } - if len(files) == 0 { - break remove_contents - } + file_op := win32.SHFILEOPSTRUCTW { + nil, + win32.FO_DELETE, + dir, + &empty[0], + win32.FOF_NOCONFIRMATION | win32.FOF_NOERRORUI | win32.FOF_SILENT, + false, + nil, + &empty[0], } - - err1 := remove(path) - if err1 == nil || err1 == .Not_Exist { - return nil + res := win32.SHFileOperationW(&file_op) + if res != 0 { + return _get_platform_error() } - - if ODIN_OS == .Windows && err1 == .Permission_Denied { - if fi, err2 := stat(path, temp_allocator()); err2 == nil { - if err2 = chmod(path, 0o200|fi.mode); err2 == nil { - err1 = remove(path) - } - } - } - if err == nil { - err = err1 - } - return err + return nil } @private cwd_lock: win32.SRWLOCK // zero is initialized