1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
// Copyright (c) Mike Grier.
//! Owned, marshalable parameter sets for synchronous Win32 namespace calls.
//!
//! Win32's namespace and metadata surface -- opening, querying, closing -- is
//! synchronous-only. A call that blocks on a dead network path blocks the thread
//! that made it, and no overlapped form exists. This crate makes such a call
//! **capturable as a value**: an owned parameter set built on one thread and
//! executed faithfully on another.
//!
//! It schedules nothing. It is the catalogue-plus-faithful-execution layer,
//! testable with no ring, no pool, and no async anywhere near it.
//!
//! # What a request is, and is not
//!
//! A request carries call **parameters**. It does not carry the impersonation
//! token or any other thread-scoped state the call runs under -- that belongs to
//! [`windows-thread-ambient-sys`][ambient], which this crate does not depend on.
//! The two are siblings rather than a stack: a request can be executed with no
//! captured context at all, and a context is useful to work that never opens a
//! file. Whoever owns both pairs them at the submission site.
//!
//! A request also chooses **no delivery model**. An opened handle comes back
//! plain and unassociated, because associating it with a completion port
//! irreversibly forecloses `IoRing` use, and that choice belongs to a layer that
//! knows the handle's destination.
//!
//! [ambient]: https://docs.rs/windows-thread-ambient-sys
//!
//! # Faithful means unaltered
//!
//! An entry reports the raw Win32 outcome. `ERROR_FILE_NOT_FOUND` means a
//! missing directory from an open, an empty directory from a first query, and a
//! genuine failure from a later one; only a consumer can tell those apart, so
//! nothing here normalises or reclassifies.
//!
//! The code is also snapshotted before any cleanup can overwrite it, because
//! `GetLastError` is volatile thread state that a `Drop` or a buffer release
//! will happily clobber. That guarantee is a primitive rather than a rule each
//! entry remembers: see [`outcome`].
//!
//! # A path is copied; a handle is shared
//!
//! Several entries take a handle rather than a path, and a request holds a
//! [`SharedHandle`](win_shared_os_owned_handle::SharedHandle): a share of the
//! caller's handle, not a new one, and a clone of the request shares it again.
//! Nothing in this crate duplicates a handle. The distinction is easy to get
//! backwards: a path is a value and is copied, while a handle is a reference to a
//! kernel object.
//!
//! A request is therefore self-contained with respect to **lifetime** -- the
//! handle stays open while any holder keeps its share, so a request cannot be
//! left naming a handle its originator closed -- and is **not** isolated with
//! respect to **state**. A request names the caller's kernel object, so an
//! enumeration through it continues the caller's rather than starting its own;
//! an independent traversal needs a fresh open. A caller holding only a borrow
//! makes an owned handle itself, visibly, before handing it over.
//!
//! # Scope
//!
//! One entry per Win32 call; a consumer needing two makes two requests and
//! sequences them itself. The round-one entry list is audited from three real
//! consumers rather than chosen by taste, and its omissions are deliberate and
//! written down. Volume and disk operations are not namespace operations and are in
//! `win-volume-sys`, not here. See `DESIGN-NOTES.md` in the crate
//! root.
//!
//! # Example
//!
//! Capture the parameters on the submitting thread, where a failure is still
//! the caller's to see and the process current directory still means what the
//! caller thinks it means, then use them on a worker that saw none of it:
//!
//! ```
//! use std::fs;
//! use std::thread;
//!
//! use windows_namespace_request_sys::{FileType, OpenFile, QueryFileType};
//! use wtf_string::Wtf16String;
//!
//! let path = std::env::temp_dir().join(format!("wnrs-doc-{}.tmp", std::process::id()));
//! fs::write(&path, b"example")?;
//!
//! // Built here, not on the worker: a relative path is fixed to the process
//! // current directory now, which is shared mutable state that any thread can
//! // change in between. This one is absolute, so it is handed over as given.
//! let text = path.to_str().expect("a temporary path is valid UTF-8");
//! let open = OpenFile::new(Wtf16String::from(text))?;
//! assert_eq!(open.win32_path().to_string_lossy(), text);
//!
//! // A handle is shared, not duplicated: the request holds the caller's
//! // handle, so it stays open for the worker however the caller lets go.
//! let query = QueryFileType::new(fs::File::open(&path)?);
//!
//! let kind = thread::spawn(move || query.perform())
//! .join()
//! .expect("the worker did not panic")?;
//!
//! assert_eq!(kind, FileType::DISK);
//! # fs::remove_file(&path)?;
//! # Ok::<(), Box<dyn std::error::Error>>(())
//! ```
pub use ;
pub use ;
pub use ;
pub use ;
pub use QueryFileInformationByHandle;
pub use ;
pub use ;
pub use ;
pub use AlignedBuf;
pub use OpenFile;
pub use ;
pub use ;
pub use ;
pub use ReOpenFile;
pub use ;
/// The owned security descriptor and attributes the requests take: `win-authorization-sys`, where
/// they were moved to and which is where Microsoft Learn files them (*Security and Identity >
/// Authorization*). They are re-exported here at the paths they always had.
pub use win_authorization_sys as security;
/// Compiles the README's examples, so a contract change breaks the build
/// rather than silently teaching the old answer.
;
pub use ;
pub use ;
pub use ;