Skip to content

Commit d772c3d

Browse files
committed
add freeze file times on Windows
1 parent da2544b commit d772c3d

2 files changed

Lines changed: 44 additions & 0 deletions

File tree

library/std/src/os/windows/fs.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,18 @@ pub trait OpenOptionsExt {
305305
/// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ne-winnt-security_impersonation_level
306306
#[stable(feature = "open_options_ext", since = "1.10.0")]
307307
fn security_qos_flags(&mut self, flags: u32) -> &mut Self;
308+
309+
/// If set to `true`, prevent the "last access time" of the file from being changed.
310+
///
311+
/// Default to `false`.
312+
#[unstable(feature = "windows_freeze_file_times", issue = "149715")]
313+
fn freeze_last_access_time(&mut self, freeze: bool) -> &mut Self;
314+
315+
/// If set to `true`, prevent the "last write time" of the file from being changed.
316+
///
317+
/// Default to `false`.
318+
#[unstable(feature = "windows_freeze_file_times", issue = "149715")]
319+
fn freeze_last_write_time(&mut self, freeze: bool) -> &mut Self;
308320
}
309321

310322
#[stable(feature = "open_options_ext", since = "1.10.0")]
@@ -333,6 +345,16 @@ impl OpenOptionsExt for OpenOptions {
333345
self.as_inner_mut().security_qos_flags(flags);
334346
self
335347
}
348+
349+
fn freeze_last_access_time(&mut self, freeze: bool) -> &mut Self {
350+
self.as_inner_mut().freeze_last_access_time(freeze);
351+
self
352+
}
353+
354+
fn freeze_last_write_time(&mut self, freeze: bool) -> &mut Self {
355+
self.as_inner_mut().freeze_last_write_time(freeze);
356+
self
357+
}
336358
}
337359

338360
/// Windows-specific extensions to [`fs::Metadata`].

library/std/src/sys/fs/windows.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ pub struct OpenOptions {
8181
share_mode: u32,
8282
security_qos_flags: u32,
8383
inherit_handle: bool,
84+
freeze_last_access_time: bool,
85+
freeze_last_write_time: bool,
8486
}
8587

8688
#[derive(Clone, PartialEq, Eq, Debug)]
@@ -204,6 +206,8 @@ impl OpenOptions {
204206
attributes: 0,
205207
security_qos_flags: 0,
206208
inherit_handle: false,
209+
freeze_last_access_time: false,
210+
freeze_last_write_time: false,
207211
}
208212
}
209213

@@ -246,6 +250,12 @@ impl OpenOptions {
246250
pub fn inherit_handle(&mut self, inherit: bool) {
247251
self.inherit_handle = inherit;
248252
}
253+
pub fn freeze_last_access_time(&mut self, freeze: bool) {
254+
self.freeze_last_access_time = freeze;
255+
}
256+
pub fn freeze_last_write_time(&mut self, freeze: bool) {
257+
self.freeze_last_write_time = freeze;
258+
}
249259

250260
fn get_access_mode(&self) -> io::Result<u32> {
251261
match (self.read, self.write, self.append, self.access_mode) {
@@ -343,6 +353,18 @@ impl File {
343353
};
344354
let handle = unsafe { HandleOrInvalid::from_raw_handle(handle) };
345355
if let Ok(handle) = OwnedHandle::try_from(handle) {
356+
if opts.freeze_last_access_time || opts.freeze_last_write_time {
357+
let file_time =
358+
c::FILETIME { dwLowDateTime: 0xFFFFFFFF, dwHighDateTime: 0xFFFFFFFF };
359+
cvt(unsafe {
360+
c::SetFileTime(
361+
handle.as_raw_handle(),
362+
core::ptr::null(),
363+
if opts.freeze_last_access_time { &file_time } else { core::ptr::null() },
364+
if opts.freeze_last_write_time { &file_time } else { core::ptr::null() },
365+
)
366+
})?;
367+
}
346368
// Manual truncation. See #115745.
347369
if opts.truncate
348370
&& creation == c::OPEN_ALWAYS

0 commit comments

Comments
 (0)