Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions library/std/src/sys/pal/windows/c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
let mut high32 = 0;
let low32 = unsafe { GetFileSize(hfile, &mut high32) };
let full_size: u64 = ((high32 as u64) << 32) | (low32 as u64);
let last_err = unsafe { GetLastError() };
if low32 == INVALID_FILE_SIZE && last_err != NO_ERROR {
return FALSE;
} else {
if !lpfilesize.is_null() {
unsafe { *lpfilesize = full_size as i64; }
}
return TRUE;
}
}
Comment on lines +813 to +825

@cher-nov cher-nov Jul 2, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better call GetLastError() only on INVALID_FILE_SIZE.

Suggested change
let mut high32 = 0;
let low32 = unsafe { GetFileSize(hfile, &mut high32) };
let full_size: u64 = ((high32 as u64) << 32) | (low32 as u64);
let last_err = unsafe { GetLastError() };
if low32 == INVALID_FILE_SIZE && last_err != NO_ERROR {
return FALSE;
} else {
if !lpfilesize.is_null() {
unsafe { *lpfilesize = full_size as i64; }
}
return TRUE;
}
}
let mut high32 = 0;
let low32 = unsafe { GetFileSize(hfile, &mut high32) };
if low32 == INVALID_FILE_SIZE {
let last_err = unsafe { GetLastError() };
if last_err != NO_ERROR { return FALSE; }
}
if !lpfilesize.is_null() {
let full_size: u64 = ((high32 as u64) << 32) | (low32 as u64);
unsafe { *lpfilesize = full_size as i64; }
}
TRUE
}

@cher-nov cher-nov Jul 2, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, worth noting that genuine GetFileSizeEx(, NULL) segfaults (at least on my Windows 7). It still makes sense to return TRUE instead if nothing else has gone wrong (just as ReactOS does, for example), but should we do at least SetLastError(ERROR_INVALID_PARAMETER) in that case? @seritools

}
2 changes: 2 additions & 0 deletions library/std/src/sys/pal/windows/c/bindings.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2184,6 +2184,7 @@ GetExitCodeProcess
GetFileAttributesW
GetFileInformationByHandle
GetFileInformationByHandleEx
GetFileSize
GetFileSizeEx
GetFileType
GETFINALPATHNAMEBYHANDLE_FLAGS
Expand Down Expand Up @@ -2234,6 +2235,7 @@ InitializeProcThreadAttributeList
InitOnceBeginInitialize
InitOnceComplete
INVALID_FILE_ATTRIBUTES
INVALID_FILE_SIZE
INVALID_SET_FILE_POINTER
INVALID_SOCKET
IO_REPARSE_TAG_MOUNT_POINT
Expand Down
2 changes: 2 additions & 0 deletions library/std/src/sys/pal/windows/c/windows_sys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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)]
Expand Down
Loading