@@ -53,3 +53,178 @@ pub async fn symlink_file<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> io:
5353 let dst = dst. as_ref ( ) . to_owned ( ) ;
5454 spawn_blocking ( move || std:: os:: windows:: fs:: symlink_file ( & src, & dst) ) . await
5555}
56+
57+ cfg_not_docs ! {
58+ pub use std:: os:: windows:: fs:: { OpenOptionsExt } ;
59+ }
60+
61+ cfg_docs ! {
62+ /// Windows-specific extensions to `OpenOptions`.
63+ pub trait OpenOptionsExt {
64+ /// Overrides the `dwDesiredAccess` argument to the call to [`CreateFile`]
65+ /// with the specified value.
66+ ///
67+ /// This will override the `read`, `write`, and `append` flags on the
68+ /// `OpenOptions` structure. This method provides fine-grained control over
69+ /// the permissions to read, write and append data, attributes (like hidden
70+ /// and system), and extended attributes.
71+ ///
72+ /// # Examples
73+ ///
74+ /// ```no_run
75+ /// use async_std::fs::OpenOptions;
76+ /// use async_std::os::windows::prelude::*;
77+ ///
78+ /// // Open without read and write permission, for example if you only need
79+ /// // to call `stat` on the file
80+ /// let file = OpenOptions::new().access_mode(0).open("foo.txt").await?;
81+ /// ```
82+ ///
83+ /// [`CreateFile`]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea
84+ fn access_mode( & mut self , access: u32 ) -> & mut Self ;
85+
86+ /// Overrides the `dwShareMode` argument to the call to [`CreateFile`] with
87+ /// the specified value.
88+ ///
89+ /// By default `share_mode` is set to
90+ /// `FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE`. This allows
91+ /// other processes to read, write, and delete/rename the same file
92+ /// while it is open. Removing any of the flags will prevent other
93+ /// processes from performing the corresponding operation until the file
94+ /// handle is closed.
95+ ///
96+ /// # Examples
97+ ///
98+ /// ```no_run
99+ /// use async_std::fs::OpenOptions;
100+ /// use async_std::os::windows::prelude::*;
101+ ///
102+ /// // Do not allow others to read or modify this file while we have it open
103+ /// // for writing.
104+ /// let file = OpenOptions::new()
105+ /// .write(true)
106+ /// .share_mode(0)
107+ /// .open("foo.txt")
108+ /// .await?;
109+ /// ```
110+ ///
111+ /// [`CreateFile`]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea
112+ #[ stable( feature = "open_options_ext" , since = "1.10.0" ) ]
113+ fn share_mode( & mut self , val: u32 ) -> & mut Self ;
114+
115+ /// Sets extra flags for the `dwFileFlags` argument to the call to
116+ /// [`CreateFile2`] to the specified value (or combines it with
117+ /// `attributes` and `security_qos_flags` to set the `dwFlagsAndAttributes`
118+ /// for [`CreateFile`]).
119+ ///
120+ /// Custom flags can only set flags, not remove flags set by Rust's options.
121+ /// This option overwrites any previously set custom flags.
122+ ///
123+ /// # Examples
124+ ///
125+ /// ```no_run
126+ /// # #[cfg(for_demonstration_only)]
127+ /// extern crate winapi;
128+ /// # mod winapi { pub const FILE_FLAG_DELETE_ON_CLOSE: u32 = 0x04000000; }
129+ ///
130+ /// use async_std::fs::OpenOptions;
131+ /// use async_std::os::windows::prelude::*;
132+ ///
133+ /// let file = OpenOptions::new()
134+ /// .create(true)
135+ /// .write(true)
136+ /// .custom_flags(winapi::FILE_FLAG_DELETE_ON_CLOSE)
137+ /// .open("foo.txt")
138+ /// .await?;
139+ /// ```
140+ ///
141+ /// [`CreateFile`]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea
142+ /// [`CreateFile2`]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfile2
143+ #[ stable( feature = "open_options_ext" , since = "1.10.0" ) ]
144+ fn custom_flags( & mut self , flags: u32 ) -> & mut Self ;
145+
146+ /// Sets the `dwFileAttributes` argument to the call to [`CreateFile2`] to
147+ /// the specified value (or combines it with `custom_flags` and
148+ /// `security_qos_flags` to set the `dwFlagsAndAttributes` for
149+ /// [`CreateFile`]).
150+ ///
151+ /// If a _new_ file is created because it does not yet exist and
152+ /// `.create(true)` or `.create_new(true)` are specified, the new file is
153+ /// given the attributes declared with `.attributes()`.
154+ ///
155+ /// If an _existing_ file is opened with `.create(true).truncate(true)`, its
156+ /// existing attributes are preserved and combined with the ones declared
157+ /// with `.attributes()`.
158+ ///
159+ /// In all other cases the attributes get ignored.
160+ ///
161+ /// # Examples
162+ ///
163+ /// ```no_run
164+ /// # #[cfg(for_demonstration_only)]
165+ /// extern crate winapi;
166+ /// # mod winapi { pub const FILE_ATTRIBUTE_HIDDEN: u32 = 2; }
167+ ///
168+ /// use async_std::fs::OpenOptions;
169+ /// use async_std::os::windows::prelude::*;
170+ ///
171+ /// let file = OpenOptions::new()
172+ /// .write(true)
173+ /// .create(true)
174+ /// .attributes(winapi::FILE_ATTRIBUTE_HIDDEN)
175+ /// .open("foo.txt")
176+ /// .await?;
177+ /// ```
178+ ///
179+ /// [`CreateFile`]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea
180+ /// [`CreateFile2`]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfile2
181+ #[ stable( feature = "open_options_ext" , since = "1.10.0" ) ]
182+ fn attributes( & mut self , val: u32 ) -> & mut Self ;
183+
184+ /// Sets the `dwSecurityQosFlags` argument to the call to [`CreateFile2`] to
185+ /// the specified value (or combines it with `custom_flags` and `attributes`
186+ /// to set the `dwFlagsAndAttributes` for [`CreateFile`]).
187+ ///
188+ /// By default `security_qos_flags` is not set. It should be specified when
189+ /// opening a named pipe, to control to which degree a server process can
190+ /// act on behalf of a client process (security impersonation level).
191+ ///
192+ /// When `security_qos_flags` is not set, a malicious program can gain the
193+ /// elevated privileges of a privileged Rust process when it allows opening
194+ /// user-specified paths, by tricking it into opening a named pipe. So
195+ /// arguably `security_qos_flags` should also be set when opening arbitrary
196+ /// paths. However the bits can then conflict with other flags, specifically
197+ /// `FILE_FLAG_OPEN_NO_RECALL`.
198+ ///
199+ /// For information about possible values, see [Impersonation Levels] on the
200+ /// Windows Dev Center site. The `SECURITY_SQOS_PRESENT` flag is set
201+ /// automatically when using this method.
202+
203+ /// # Examples
204+ ///
205+ /// ```no_run
206+ /// # #[cfg(for_demonstration_only)]
207+ /// extern crate winapi;
208+ /// # mod winapi { pub const SECURITY_IDENTIFICATION: u32 = 0; }
209+ /// use async_std::fs::OpenOptions;
210+ /// use async_std::os::windows::prelude::*;
211+ ///
212+ /// let file = OpenOptions::new()
213+ /// .write(true)
214+ /// .create(true)
215+ ///
216+ /// // Sets the flag value to `SecurityIdentification`.
217+ /// .security_qos_flags(winapi::SECURITY_IDENTIFICATION)
218+ ///
219+ /// .open(r"\\.\pipe\MyPipe")
220+ /// .await?;
221+ /// ```
222+ ///
223+ /// [`CreateFile`]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea
224+ /// [`CreateFile2`]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfile2
225+ /// [Impersonation Levels]:
226+ /// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ne-winnt-security_impersonation_level
227+ #[ stable( feature = "open_options_ext" , since = "1.10.0" ) ]
228+ fn security_qos_flags( & mut self , flags: u32 ) -> & mut Self ;
229+ }
230+ }
0 commit comments