From f03c2b7783518f05f7804dfe51adaef4b5e5020e Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 24 Jul 2024 21:45:35 +0100 Subject: [PATCH] General clean up of `os2.read_directory` for Windows --- core/os/os2/dir_windows.odin | 15 ++++++++++++++- core/os/os2/file_windows.odin | 28 ++++++++++++++++++---------- core/os/os2/path_windows.odin | 11 ++++++----- core/os/os2/stat.odin | 4 ++-- core/os/os2/stat_windows.odin | 3 ++- 5 files changed, 42 insertions(+), 19 deletions(-) diff --git a/core/os/os2/dir_windows.odin b/core/os/os2/dir_windows.odin index c767bd3b9..84f320095 100644 --- a/core/os/os2/dir_windows.odin +++ b/core/os/os2/dir_windows.odin @@ -23,10 +23,21 @@ find_data_to_file_info :: proc(base_path: string, d: ^win32.WIN32_FIND_DATAW, al fi.type, fi.mode = _file_type_mode_from_file_attributes(d.dwFileAttributes, nil, d.dwReserved0) - // fi.inode = u128(u64(d.nFileIndexHigh)<<32 + u64(d.nFileIndexLow)) fi.creation_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftCreationTime)) fi.modification_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftLastWriteTime)) fi.access_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftLastAccessTime)) + + + handle := win32.HANDLE(_open_internal(path, {.Read}, 0o666) or_else 0) + defer win32.CloseHandle(handle) + + if file_id_info: win32.FILE_ID_INFO; handle != nil && win32.GetFileInformationByHandleEx(handle, .FileIdInfo, &file_id_info, size_of(file_id_info)) { + #assert(size_of(fi.inode) == size_of(file_id_info.FileId)) + #assert(size_of(fi.inode) == 16) + runtime.mem_copy_non_overlapping(&fi.inode, &file_id_info.FileId, 16) + } + + return } @@ -46,6 +57,8 @@ _read_directory_iterator :: proc(it: ^Read_Directory_Iterator) -> (fi: File_Info return } + TEMP_ALLOCATOR_GUARD() + for !it.impl.no_more_files { err: Error file_info_delete(it.impl.prev_fi, file_allocator()) diff --git a/core/os/os2/file_windows.odin b/core/os/os2/file_windows.odin index 55365c1bd..48a5427f1 100644 --- a/core/os/os2/file_windows.odin +++ b/core/os/os2/file_windows.odin @@ -60,8 +60,9 @@ _open_internal :: proc(name: string, flags: File_Flags, perm: int) -> (handle: u err = .Not_Exist return } + TEMP_ALLOCATOR_GUARD() - path := _fix_long_path(name) or_return + path := _fix_long_path(name, temp_allocator()) or_return access: u32 switch flags & {.Read, .Write} { case {.Read}: access = win32.FILE_GENERIC_READ @@ -457,7 +458,8 @@ _truncate :: proc(f: ^File, size: i64) -> Error { } _remove :: proc(name: string) -> Error { - p := _fix_long_path(name) or_return + TEMP_ALLOCATOR_GUARD() + p := _fix_long_path(name, temp_allocator()) or_return err, err1: Error if !win32.DeleteFileW(p) { err = _get_platform_error() @@ -494,8 +496,9 @@ _remove :: proc(name: string) -> Error { } _rename :: proc(old_path, new_path: string) -> Error { - from := _fix_long_path(old_path) or_return - to := _fix_long_path(new_path) or_return + TEMP_ALLOCATOR_GUARD() + from := _fix_long_path(old_path, temp_allocator()) or_return + to := _fix_long_path(new_path, temp_allocator()) or_return if win32.MoveFileExW(from, to, win32.MOVEFILE_REPLACE_EXISTING) { return nil } @@ -504,8 +507,9 @@ _rename :: proc(old_path, new_path: string) -> Error { } _link :: proc(old_name, new_name: string) -> Error { - o := _fix_long_path(old_name) or_return - n := _fix_long_path(new_name) or_return + TEMP_ALLOCATOR_GUARD() + o := _fix_long_path(old_name, temp_allocator()) or_return + n := _fix_long_path(new_name, temp_allocator()) or_return if win32.CreateHardLinkW(n, o, nil) { return nil } @@ -592,8 +596,10 @@ _read_link :: proc(name: string, allocator: runtime.Allocator) -> (s: string, er @thread_local rdb_buf: [MAXIMUM_REPARSE_DATA_BUFFER_SIZE]byte - p := _fix_long_path(name) or_return - handle := _open_sym_link(p) or_return + TEMP_ALLOCATOR_GUARD() + + p := _fix_long_path(name, temp_allocator()) or_return + handle := _open_sym_link(p) or_return defer win32.CloseHandle(handle) bytes_returned: u32 @@ -667,7 +673,8 @@ _fchown :: proc(f: ^File, uid, gid: int) -> Error { } _chdir :: proc(name: string) -> Error { - p := _fix_long_path(name) or_return + TEMP_ALLOCATOR_GUARD() + p := _fix_long_path(name, temp_allocator()) or_return if !win32.SetCurrentDirectoryW(p) { return _get_platform_error() } @@ -723,7 +730,8 @@ _fchtimes :: proc(f: ^File, atime, mtime: time.Time) -> Error { } _exists :: proc(path: string) -> bool { - wpath, _ := _fix_long_path(path) + TEMP_ALLOCATOR_GUARD() + wpath, _ := _fix_long_path(path, temp_allocator()) attribs := win32.GetFileAttributesW(wpath) return attribs != win32.INVALID_FILE_ATTRIBUTES } diff --git a/core/os/os2/path_windows.odin b/core/os/os2/path_windows.odin index c93c929f2..4aa695ee2 100644 --- a/core/os/os2/path_windows.odin +++ b/core/os/os2/path_windows.odin @@ -13,7 +13,8 @@ _is_path_separator :: proc(c: byte) -> bool { } _mkdir :: proc(name: string, perm: int) -> Error { - if !win32.CreateDirectoryW(_fix_long_path(name) or_return, nil) { + TEMP_ALLOCATOR_GUARD() + if !win32.CreateDirectoryW(_fix_long_path(name, temp_allocator()) or_return, nil) { return _get_platform_error() } return nil @@ -169,13 +170,13 @@ init_long_path_support :: proc() { } @(require_results) -_fix_long_path_slice :: proc(path: string) -> ([]u16, runtime.Allocator_Error) { - return win32_utf8_to_utf16(_fix_long_path_internal(path), temp_allocator()) +_fix_long_path_slice :: proc(path: string, allocator: runtime.Allocator) -> ([]u16, runtime.Allocator_Error) { + return win32_utf8_to_utf16(_fix_long_path_internal(path), allocator) } @(require_results) -_fix_long_path :: proc(path: string) -> (win32.wstring, runtime.Allocator_Error) { - return win32_utf8_to_wstring(_fix_long_path_internal(path), temp_allocator()) +_fix_long_path :: proc(path: string, allocator: runtime.Allocator) -> (win32.wstring, runtime.Allocator_Error) { + return win32_utf8_to_wstring(_fix_long_path_internal(path), allocator) } @(require_results) diff --git a/core/os/os2/stat.odin b/core/os/os2/stat.odin index 5c063e771..b3ca47be3 100644 --- a/core/os/os2/stat.odin +++ b/core/os/os2/stat.odin @@ -12,8 +12,8 @@ File_Info :: struct { name: string, inode: u128, // might be zero if cannot be determined - size: i64, - mode: int, + size: i64 `fmt:"M"`, + mode: int `fmt:"o"`, type: File_Type, creation_time: time.Time, diff --git a/core/os/os2/stat_windows.odin b/core/os/os2/stat_windows.odin index 4d67ddb58..3a3a3b1b4 100644 --- a/core/os/os2/stat_windows.odin +++ b/core/os/os2/stat_windows.odin @@ -67,8 +67,9 @@ internal_stat :: proc(name: string, create_file_attributes: u32, allocator: runt if len(name) == 0 { return {}, .Not_Exist } + TEMP_ALLOCATOR_GUARD() - wname := _fix_long_path(name) or_return + wname := _fix_long_path(name, temp_allocator()) or_return fa: win32.WIN32_FILE_ATTRIBUTE_DATA ok := win32.GetFileAttributesExW(wname, win32.GetFileExInfoStandard, &fa) if ok && fa.dwFileAttributes & win32.FILE_ATTRIBUTE_REPARSE_POINT == 0 {