about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-07-19 17:06:49 +0200
committerGitHub <noreply@github.com>2024-07-19 17:06:49 +0200
commit45e4e963854873ca09d93bb5d0c14c8d76fa2e2f (patch)
treeb4cce5fa535c0efa6d2f623c41a84cbe451ee715
parent11e57241f166194a328438d9264b68c98a18d51f (diff)
parent35428cff60d4bdb8b2bcc4a55746b5543d4d47f4 (diff)
downloadrust-45e4e963854873ca09d93bb5d0c14c8d76fa2e2f.tar.gz
rust-45e4e963854873ca09d93bb5d0c14c8d76fa2e2f.zip
Rollup merge of #112328 - juliusl:pr/windows-add-change-time, r=ChrisDenton
Feat. adding ext that returns change_time

Addresses #112327
-rw-r--r--library/std/src/os/windows/fs.rs10
-rw-r--r--library/std/src/sys/pal/windows/fs.rs11
2 files changed, 21 insertions, 0 deletions
diff --git a/library/std/src/os/windows/fs.rs b/library/std/src/os/windows/fs.rs
index 27947d91c99..7cac8c39ea8 100644
--- a/library/std/src/os/windows/fs.rs
+++ b/library/std/src/os/windows/fs.rs
@@ -471,6 +471,13 @@ 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<u64>;
+
+    /// Returns the change time, which is the last time file metadata was changed, such as
+    /// renames, attributes, etc
+    ///
+    /// This will return `None` if the `Metadata` instance was not created using the `FILE_BASIC_INFO` type.
+    #[unstable(feature = "windows_change_time", issue = "121478")]
+    fn change_time(&self) -> Option<u64>;
 }
 
 #[stable(feature = "metadata_ext", since = "1.1.0")]
@@ -499,6 +506,9 @@ impl MetadataExt for Metadata {
     fn file_index(&self) -> Option<u64> {
         self.as_inner().file_index()
     }
+    fn change_time(&self) -> Option<u64> {
+        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 48c39392047..15d446786ad 100644
--- a/library/std/src/sys/pal/windows/fs.rs
+++ b/library/std/src/sys/pal/windows/fs.rs
@@ -32,6 +32,7 @@ pub struct FileAttr {
     creation_time: c::FILETIME,
     last_access_time: c::FILETIME,
     last_write_time: c::FILETIME,
+    change_time: Option<c::FILETIME>,
     file_size: u64,
     reparse_tag: u32,
     volume_serial_number: Option<u32>,
@@ -377,6 +378,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),
@@ -413,6 +415,10 @@ impl File {
                     dwLowDateTime: info.LastWriteTime as u32,
                     dwHighDateTime: (info.LastWriteTime >> 32) as u32,
                 },
+                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,
@@ -957,6 +963,10 @@ impl FileAttr {
         to_u64(&self.creation_time)
     }
 
+    pub fn changed_u64(&self) -> Option<u64> {
+        self.change_time.as_ref().map(|c| to_u64(c))
+    }
+
     pub fn volume_serial_number(&self) -> Option<u32> {
         self.volume_serial_number
     }
@@ -976,6 +986,7 @@ impl From<c::WIN32_FIND_DATAW> 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