mirror of
https://github.com/Ed94/Odin.git
synced 2026-07-18 08:41:31 -07:00
Use SHFileOperationW for remove_all on Windows
This commit is contained in:
@@ -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})
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user