From 610eedc2da262f245502e7c35c1fbb8b438d498c Mon Sep 17 00:00:00 2001 From: Julius Liu Date: Mon, 5 Jun 2023 15:59:29 -0700 Subject: [PATCH] Feat. adding ext that returns change_time for Windows --- library/std/src/os/windows/fs.rs | 11 +++++++++++ library/std/src/sys/pal/windows/fs.rs | 11 +++++++++++ 2 files changed, 22 insertions(+) diff --git a/library/std/src/os/windows/fs.rs b/library/std/src/os/windows/fs.rs index e9d7a13e9d5b2..9180b6433251b 100644 --- a/library/std/src/os/windows/fs.rs +++ b/library/std/src/os/windows/fs.rs @@ -471,6 +471,14 @@ pub trait MetadataExt { /// `fs::metadata` or `File::metadata`, then this will return `Some`. #[unstable(feature = "windows_by_handle", issue = "63010")] fn file_index(&self) -> Option; + + + /// Returns the change time, which is the last time file metadata was changed, such as + /// renames, attributes, etc. + /// + /// This will return `None` if the `Metdata` instance was not created using the FILE_BASIC_INFO type, + #[unstable(feature = "windows_change_time", issue = "121478")] + fn change_time(&self) -> Option; } #[stable(feature = "metadata_ext", since = "1.1.0")] @@ -499,6 +507,9 @@ impl MetadataExt for Metadata { fn file_index(&self) -> Option { self.as_inner().file_index() } + fn change_time(&self) -> Option { + self.as_inner().changed_u64() + } } /// Windows-specific extensions to [`fs::FileType`]. diff --git a/library/std/src/sys/pal/windows/fs.rs b/library/std/src/sys/pal/windows/fs.rs index b82a83ae7a3e8..c409961330661 100644 --- a/library/std/src/sys/pal/windows/fs.rs +++ b/library/std/src/sys/pal/windows/fs.rs @@ -29,6 +29,7 @@ pub struct FileAttr { creation_time: c::FILETIME, last_access_time: c::FILETIME, last_write_time: c::FILETIME, + change_time: Option, file_size: u64, reparse_tag: c::DWORD, volume_serial_number: Option, @@ -375,6 +376,7 @@ impl File { creation_time: info.ftCreationTime, last_access_time: info.ftLastAccessTime, last_write_time: info.ftLastWriteTime, + change_time: None, // Only available in FILE_BASIC_INFO file_size: (info.nFileSizeLow as u64) | ((info.nFileSizeHigh as u64) << 32), reparse_tag, volume_serial_number: Some(info.dwVolumeSerialNumber), @@ -411,6 +413,10 @@ impl File { dwLowDateTime: info.LastWriteTime as c::DWORD, dwHighDateTime: (info.LastWriteTime >> 32) as c::DWORD, }, + change_time: Some(c::FILETIME { + dhLowDateTime: info.ChangeTime as c::DWORD, + dhHighDateTime: (info.ChangeTime >> 32) as c::DWORD, + }), file_size: 0, reparse_tag: 0, volume_serial_number: None, @@ -952,6 +958,10 @@ impl FileAttr { to_u64(&self.creation_time) } + pub fn changed_u64(&self) -> Option { + self.change_time.as_ref().map(|c| to_u64(c)) + } + pub fn volume_serial_number(&self) -> Option { self.volume_serial_number } @@ -971,6 +981,7 @@ impl From for FileAttr { creation_time: wfd.ftCreationTime, last_access_time: wfd.ftLastAccessTime, last_write_time: wfd.ftLastWriteTime, + change_time: None, file_size: ((wfd.nFileSizeHigh as u64) << 32) | (wfd.nFileSizeLow as u64), reparse_tag: if wfd.dwFileAttributes & c::FILE_ATTRIBUTE_REPARSE_POINT != 0 { // reserved unless this is a reparse point