Skip to content
Merged
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
14 changes: 8 additions & 6 deletions cap-fs-ext/src/open_options_maybe_dir_ext.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
/// Extension trait for `cap_primitives::fs::OpenOptions` which adds
/// `maybe_dir`, a function for controlling whether an open should
/// attempt to succeed on a directory. On Posix-ish platforms, opening
/// a directory always succeeds, but on Windows, opening a directory
/// needs this option.
/// `maybe_dir`, a function for controlling whether an open should attempt to
/// succeed on a directory. On Posix-ish platforms, opening a directory always
/// succeeds, but on Windows, opening a directory needs this option.
pub trait OpenOptionsMaybeDirExt {
/// Sets the option for disabling an error that might be generated
/// by the opened object being a directory.
/// Sets the option for disabling an error that might be generated by the
/// opened object being a directory.
///
/// On some platforms, this may prevent the directory from being deleted
/// or renamed while the handle is open.
fn maybe_dir(&mut self, maybe_dir: bool) -> &mut Self;
}

Expand Down
11 changes: 9 additions & 2 deletions cap-primitives/src/windows/fs/oflags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::fs::{FollowSymlinks, OpenOptions};
use std::fs;
use std::os::windows::fs::OpenOptionsExt;
use windows_sys::Win32::Storage::FileSystem::{
FILE_FLAG_BACKUP_SEMANTICS, FILE_FLAG_OPEN_REPARSE_POINT,
FILE_FLAG_BACKUP_SEMANTICS, FILE_FLAG_OPEN_REPARSE_POINT, FILE_SHARE_DELETE,
};

/// Translate the given `cap_std` into `std` options. Also return a bool
Expand All @@ -24,8 +24,15 @@ pub(in super::super) fn open_options_to_std(opts: &OpenOptions) -> (fs::OpenOpti
opts.ext.custom_flags | FILE_FLAG_OPEN_REPARSE_POINT
}
};
let mut share_mode = opts.ext.share_mode;
if opts.maybe_dir {
custom_flags |= FILE_FLAG_BACKUP_SEMANTICS;

// Only allow `FILE_SHARE_READ` and `FILE_SHARE_WRITE`; this mirrors
// the values in `dir_options()` and is done to prevent directories
// from being deleted or renamed underneath cap-std's sandboxed path
// lookups on Windows.
share_mode &= !FILE_SHARE_DELETE;
}
let mut std_opts = fs::OpenOptions::new();
std_opts
Expand All @@ -35,7 +42,7 @@ pub(in super::super) fn open_options_to_std(opts: &OpenOptions) -> (fs::OpenOpti
.truncate(trunc)
.create(opts.create)
.create_new(opts.create_new)
.share_mode(opts.ext.share_mode)
.share_mode(share_mode)
.custom_flags(custom_flags)
.attributes(opts.ext.attributes);

Expand Down