mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-07 08:08:50 +00: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)
|
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) {
|
write_byte :: proc(f: ^File, b: byte) -> (n: int, err: Error) {
|
||||||
return write(f, []byte{b})
|
return write(f, []byte{b})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -109,11 +109,12 @@ _open_internal :: proc(name: string, flags: File_Flags, perm: int) -> (handle: u
|
|||||||
case 0:
|
case 0:
|
||||||
return uintptr(h), nil
|
return uintptr(h), nil
|
||||||
case:
|
case:
|
||||||
return 0, Platform_Error(e)
|
return 0, _get_platform_error()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
h := win32.CreateFileW(path, access, share_mode, &sa, create_mode, attrs, nil)
|
h := win32.CreateFileW(path, access, share_mode, &sa, create_mode, attrs, nil)
|
||||||
if h == win32.INVALID_HANDLE {
|
if h == win32.INVALID_HANDLE {
|
||||||
return 0, _get_platform_error()
|
return 0, _get_platform_error()
|
||||||
|
|||||||
@@ -75,72 +75,31 @@ _remove_all :: proc(path: string) -> Error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
err := remove(path)
|
err := remove(path)
|
||||||
if err == nil || err == .Not_Exist {
|
if err == nil || err == .Not_Exist {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
TEMP_ALLOCATOR_GUARD()
|
TEMP_ALLOCATOR_GUARD()
|
||||||
dir, serr := stat_do_not_follow_links(path, temp_allocator())
|
dir := win32_utf8_to_wstring(path, temp_allocator()) or_return
|
||||||
if serr != nil {
|
|
||||||
if serr == .Not_Exist || serr == .Invalid_Dir {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return serr
|
|
||||||
}
|
|
||||||
if dir.type != .Directory {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = nil
|
empty: [1]u16
|
||||||
remove_contents: {
|
|
||||||
f: ^File
|
|
||||||
f, err = open(path)
|
|
||||||
if err != nil {
|
|
||||||
if err == .Not_Exist {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
files, read_err := read_all_directory(f, temp_allocator())
|
file_op := win32.SHFILEOPSTRUCTW {
|
||||||
for file in files {
|
nil,
|
||||||
err1 := remove_all(file.fullpath)
|
win32.FO_DELETE,
|
||||||
if err == nil {
|
dir,
|
||||||
err = err1
|
&empty[0],
|
||||||
}
|
win32.FOF_NOCONFIRMATION | win32.FOF_NOERRORUI | win32.FOF_SILENT,
|
||||||
}
|
false,
|
||||||
close(f)
|
nil,
|
||||||
|
&empty[0],
|
||||||
if read_err == .EOF {
|
|
||||||
break remove_contents
|
|
||||||
}
|
|
||||||
|
|
||||||
if err == nil {
|
|
||||||
err = read_err
|
|
||||||
}
|
|
||||||
if len(files) == 0 {
|
|
||||||
break remove_contents
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
res := win32.SHFileOperationW(&file_op)
|
||||||
err1 := remove(path)
|
if res != 0 {
|
||||||
if err1 == nil || err1 == .Not_Exist {
|
return _get_platform_error()
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@private cwd_lock: win32.SRWLOCK // zero is initialized
|
@private cwd_lock: win32.SRWLOCK // zero is initialized
|
||||||
|
|||||||
Reference in New Issue
Block a user