From cce566b6bd6e676b917bf0e914a86680a6f268c4 Mon Sep 17 00:00:00 2001 From: Jookia Date: Wed, 1 Jul 2026 22:01:59 +1000 Subject: [PATCH] Implement GetFileSizeEx compatibility wrapper Windows before 2000 lacks GetFileSizeEx which Rust relies on. Implement a compatibility function that uses GetFileSize as a backup. --- library/std/src/sys/pal/windows/c.rs | 24 +++++++++++++++++++ .../std/src/sys/pal/windows/c/bindings.txt | 2 ++ .../std/src/sys/pal/windows/c/windows_sys.rs | 2 ++ 3 files changed, 28 insertions(+) diff --git a/library/std/src/sys/pal/windows/c.rs b/library/std/src/sys/pal/windows/c.rs index 5f2557804be22..c9074bb780db7 100644 --- a/library/std/src/sys/pal/windows/c.rs +++ b/library/std/src/sys/pal/windows/c.rs @@ -800,3 +800,27 @@ compat_fn_with_fallback! { rtabort!("unimplemented") } } + +#[cfg(target_family = "rust9x")] +compat_fn_with_fallback! { + pub static KERNEL32: &CStr = c"kernel32" => { load: false, unicows: false }; + // >= 2000 + // https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getfilesizeex + pub fn GetFileSizeEx( + hfile: HANDLE, + lpfilesize: *mut i64 + ) -> BOOL { + if lpfilesize.is_null() { + unsafe { SetLastError(ERROR_INVALID_PARAMETER as u32) }; + return FALSE; + } + let mut high32 = 0; + let low32 = unsafe { GetFileSize(hfile, &mut high32) }; + let full_size: u64 = ((high32 as u64) << 32) | (low32 as u64); + if low32 == INVALID_FILE_SIZE && unsafe { GetLastError() } != NO_ERROR { + FALSE + } else { + TRUE + } + } +} diff --git a/library/std/src/sys/pal/windows/c/bindings.txt b/library/std/src/sys/pal/windows/c/bindings.txt index d48b2a627ac02..7ba816b7f86b8 100644 --- a/library/std/src/sys/pal/windows/c/bindings.txt +++ b/library/std/src/sys/pal/windows/c/bindings.txt @@ -2184,6 +2184,7 @@ GetExitCodeProcess GetFileAttributesW GetFileInformationByHandle GetFileInformationByHandleEx +GetFileSize GetFileSizeEx GetFileType GETFINALPATHNAMEBYHANDLE_FLAGS @@ -2234,6 +2235,7 @@ InitializeProcThreadAttributeList InitOnceBeginInitialize InitOnceComplete INVALID_FILE_ATTRIBUTES +INVALID_FILE_SIZE INVALID_SET_FILE_POINTER INVALID_SOCKET IO_REPARSE_TAG_MOUNT_POINT diff --git a/library/std/src/sys/pal/windows/c/windows_sys.rs b/library/std/src/sys/pal/windows/c/windows_sys.rs index d431043b29521..a3caf3cc69ff9 100644 --- a/library/std/src/sys/pal/windows/c/windows_sys.rs +++ b/library/std/src/sys/pal/windows/c/windows_sys.rs @@ -53,6 +53,7 @@ windows_link::link!("kernel32.dll" "system" fn GetExitCodeProcess(hprocess : HAN windows_link::link!("kernel32.dll" "system" fn GetFileAttributesW(lpfilename : PCWSTR) -> u32); windows_link::link!("kernel32.dll" "system" fn GetFileInformationByHandle(hfile : HANDLE, lpfileinformation : *mut BY_HANDLE_FILE_INFORMATION) -> BOOL); windows_link::link!("kernel32.dll" "system" fn GetFileInformationByHandleEx(hfile : HANDLE, fileinformationclass : FILE_INFO_BY_HANDLE_CLASS, lpfileinformation : *mut core::ffi::c_void, dwbuffersize : u32) -> BOOL); +windows_link::link!("kernel32.dll" "system" fn GetFileSize(hfile : HANDLE, lpfilesize : *mut u64) -> u32); windows_link::link!("kernel32.dll" "system" fn GetFileSizeEx(hfile : HANDLE, lpfilesize : *mut i64) -> BOOL); windows_link::link!("kernel32.dll" "system" fn GetFileType(hfile : HANDLE) -> FILE_TYPE); windows_link::link!("kernel32.dll" "system" fn GetFinalPathNameByHandleW(hfile : HANDLE, lpszfilepath : PWSTR, cchfilepath : u32, dwflags : GETFINALPATHNAMEBYHANDLE_FLAGS) -> u32); @@ -2898,6 +2899,7 @@ impl Default for INIT_ONCE { } pub const INIT_ONCE_INIT_FAILED: u32 = 4u32; pub const INVALID_FILE_ATTRIBUTES: u32 = 4294967295u32; +pub const INVALID_FILE_SIZE: u32 = 4294967295u32; pub const INVALID_SET_FILE_POINTER: u32 = 4294967295u32; pub const INVALID_SOCKET: SOCKET = -1i32 as _; #[repr(C)]