From bf9c08b705725bf35b60fb8a468edbc35ba3cdde Mon Sep 17 00:00:00 2001 From: Divy Srivastava Date: Wed, 17 Jul 2024 19:43:40 -0700 Subject: [PATCH] fix(ext/node): stat.mode on windows (#24434) --- Cargo.lock | 5 ++-- Cargo.toml | 2 +- ext/fs/Cargo.toml | 1 + ext/fs/std_fs.rs | 56 +++++++++++++++++++++++++++++++++++++++++ ext/node/ops/os/cpus.rs | 4 +-- 5 files changed, 63 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 12eb778621..898b559956 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1525,6 +1525,7 @@ dependencies = [ "rayon", "serde", "winapi", + "windows-sys 0.52.0", ] [[package]] @@ -1791,7 +1792,7 @@ dependencies = [ "tokio", "url", "winapi", - "windows-sys 0.48.0", + "windows-sys 0.52.0", "x25519-dalek", "x509-parser", ] @@ -1904,7 +1905,7 @@ dependencies = [ "uuid", "which 4.4.2", "winapi", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index d42395dd47..6c4ca95671 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -211,7 +211,7 @@ nix = "=0.26.2" # windows deps junction = "=0.2.0" winapi = "=0.3.9" -windows-sys = { version = "0.48.0", features = ["Win32_Foundation", "Win32_Media", "Win32_Storage_FileSystem"] } +windows-sys = { version = "0.52.0", features = ["Win32_Foundation", "Win32_Media", "Win32_Storage_FileSystem", "Win32_System_IO", "Win32_System_WindowsProgramming", "Wdk", "Wdk_System", "Wdk_System_SystemInformation", "Win32_System_Pipes", "Wdk_Storage_FileSystem", "Win32_System_Registry"] } winres = "=0.1.12" # NB: the `bench` and `release` profiles must remain EXACTLY the same. diff --git a/ext/fs/Cargo.toml b/ext/fs/Cargo.toml index 05d4164af8..2bd0212cf8 100644 --- a/ext/fs/Cargo.toml +++ b/ext/fs/Cargo.toml @@ -34,4 +34,5 @@ nix.workspace = true [target.'cfg(windows)'.dependencies] winapi = { workspace = true, features = ["winbase"] } +windows-sys.workspace = true junction.workspace = true diff --git a/ext/fs/std_fs.rs b/ext/fs/std_fs.rs index 7fc33a8ad8..3cbd154d59 100644 --- a/ext/fs/std_fs.rs +++ b/ext/fs/std_fs.rs @@ -821,6 +821,29 @@ fn stat_extra( Ok(info.dwVolumeSerialNumber as u64) } + use windows_sys::Wdk::Storage::FileSystem::FILE_ALL_INFORMATION; + + unsafe fn query_file_information( + handle: winapi::shared::ntdef::HANDLE, + ) -> std::io::Result { + use windows_sys::Wdk::Storage::FileSystem::NtQueryInformationFile; + + let mut info = std::mem::MaybeUninit::::zeroed(); + let status = NtQueryInformationFile( + handle as _, + std::ptr::null_mut(), + info.as_mut_ptr() as *mut _, + std::mem::size_of::() as _, + 18, /* FileAllInformation */ + ); + + if status < 0 { + return Err(std::io::Error::last_os_error()); + } + + Ok(info.assume_init()) + } + // SAFETY: winapi calls unsafe { let mut path: Vec<_> = path.as_os_str().encode_wide().collect(); @@ -842,6 +865,39 @@ fn stat_extra( CloseHandle(file_handle); fsstat.dev = result?; + if let Ok(file_info) = query_file_information(file_handle) { + if file_info.BasicInformation.FileAttributes + & winapi::um::winnt::FILE_ATTRIBUTE_REPARSE_POINT + != 0 + { + fsstat.is_symlink = true; + } + + if file_info.BasicInformation.FileAttributes + & winapi::um::winnt::FILE_ATTRIBUTE_DIRECTORY + != 0 + { + fsstat.mode |= libc::S_IFDIR as u32; + fsstat.size = 0; + } else { + fsstat.mode |= libc::S_IFREG as u32; + fsstat.size = file_info.StandardInformation.EndOfFile as u64; + } + + if file_info.BasicInformation.FileAttributes + & winapi::um::winnt::FILE_ATTRIBUTE_READONLY + != 0 + { + fsstat.mode |= + (libc::S_IREAD | (libc::S_IREAD >> 3) | (libc::S_IREAD >> 6)) as u32; + } else { + fsstat.mode |= ((libc::S_IREAD | libc::S_IWRITE) + | ((libc::S_IREAD | libc::S_IWRITE) >> 3) + | ((libc::S_IREAD | libc::S_IWRITE) >> 6)) + as u32; + } + } + Ok(()) } } diff --git a/ext/node/ops/os/cpus.rs b/ext/node/ops/os/cpus.rs index 9de4f1ff3c..7515bae8b1 100644 --- a/ext/node/ops/os/cpus.rs +++ b/ext/node/ops/os/cpus.rs @@ -122,8 +122,8 @@ pub fn cpu_info() -> Option> { #[cfg(target_os = "windows")] pub fn cpu_info() -> Option> { - use windows_sys::Win32::System::WindowsProgramming::NtQuerySystemInformation; - use windows_sys::Win32::System::WindowsProgramming::SystemProcessorPerformanceInformation; + use windows_sys::Wdk::System::SystemInformation::NtQuerySystemInformation; + use windows_sys::Wdk::System::SystemInformation::SystemProcessorPerformanceInformation; use windows_sys::Win32::System::WindowsProgramming::SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION; use std::os::windows::ffi::OsStrExt;