1#![allow(nonstandard_style)]
4#![cfg_attr(test, allow(dead_code))]
5#![unstable(issue = "none", feature = "windows_c")]
6#![allow(clippy::style)]
7
8use core::ffi::{CStr, c_uint, c_ulong, c_ushort, c_void};
9use core::ptr;
10
11mod windows_sys;
12pub use windows_sys::*;
13
14pub type WCHAR = u16;
15
16pub const INVALID_HANDLE_VALUE: HANDLE = ::core::ptr::without_provenance_mut(-1i32 as _);
17
18pub const EXIT_SUCCESS: u32 = 0;
20pub const EXIT_FAILURE: u32 = 1;
21
22#[cfg(target_vendor = "win7")]
23pub const CONDITION_VARIABLE_INIT: CONDITION_VARIABLE = CONDITION_VARIABLE { Ptr: ptr::null_mut() };
24#[cfg(target_vendor = "win7")]
25pub const SRWLOCK_INIT: SRWLOCK = SRWLOCK { Ptr: ptr::null_mut() };
26#[cfg(not(target_thread_local))]
27pub const INIT_ONCE_STATIC_INIT: INIT_ONCE = INIT_ONCE { Ptr: ptr::null_mut() };
28
29pub const OBJ_DONT_REPARSE: u32 = windows_sys::OBJ_DONT_REPARSE as u32;
31pub const FRS_ERR_SYSVOL_POPULATE_TIMEOUT: u32 =
32 windows_sys::FRS_ERR_SYSVOL_POPULATE_TIMEOUT as u32;
33
34pub fn nt_success(status: NTSTATUS) -> bool {
37 status >= 0
38}
39
40impl UNICODE_STRING {
41 pub fn from_ref(slice: &[u16]) -> Self {
42 let len = size_of_val(slice);
43 Self { Length: len as _, MaximumLength: len as _, Buffer: slice.as_ptr() as _ }
44 }
45}
46
47impl OBJECT_ATTRIBUTES {
48 pub fn with_length() -> Self {
49 Self {
50 Length: size_of::<Self>() as _,
51 RootDirectory: ptr::null_mut(),
52 ObjectName: ptr::null_mut(),
53 Attributes: 0,
54 SecurityDescriptor: ptr::null_mut(),
55 SecurityQualityOfService: ptr::null_mut(),
56 }
57 }
58}
59
60impl IO_STATUS_BLOCK {
61 pub const PENDING: Self =
62 IO_STATUS_BLOCK { Anonymous: IO_STATUS_BLOCK_0 { Status: STATUS_PENDING }, Information: 0 };
63 pub fn status(&self) -> NTSTATUS {
64 unsafe { self.Anonymous.Status }
70 }
71}
72
73#[repr(C)]
76pub struct REPARSE_DATA_BUFFER {
77 pub ReparseTag: c_uint,
78 pub ReparseDataLength: c_ushort,
79 pub Reserved: c_ushort,
80 pub rest: (),
81}
82
83#[repr(C)]
86pub struct SYMBOLIC_LINK_REPARSE_BUFFER {
87 pub SubstituteNameOffset: c_ushort,
88 pub SubstituteNameLength: c_ushort,
89 pub PrintNameOffset: c_ushort,
90 pub PrintNameLength: c_ushort,
91 pub Flags: c_ulong,
92 pub PathBuffer: WCHAR,
93}
94
95#[repr(C)]
96pub struct MOUNT_POINT_REPARSE_BUFFER {
97 pub SubstituteNameOffset: c_ushort,
98 pub SubstituteNameLength: c_ushort,
99 pub PrintNameOffset: c_ushort,
100 pub PrintNameLength: c_ushort,
101 pub PathBuffer: WCHAR,
102}
103
104cfg_if::cfg_if! {
106if #[cfg(not(target_vendor = "uwp"))] {
107 pub const EXCEPTION_CONTINUE_SEARCH: i32 = 0;
108}
109}
110
111#[cfg(not(target_vendor = "win7"))]
113#[cfg_attr(
114 target_arch = "x86",
115 link(name = "bcryptprimitives", kind = "raw-dylib", import_name_type = "undecorated")
116)]
117#[cfg_attr(not(target_arch = "x86"), link(name = "bcryptprimitives", kind = "raw-dylib"))]
118unsafe extern "system" {
119 pub fn ProcessPrng(pbdata: *mut u8, cbdata: usize) -> BOOL;
120}
121
122compat_fn_with_fallback! {
125 pub static KERNEL32: &CStr = c"kernel32";
126
127 pub fn SetThreadDescription(hthread: HANDLE, lpthreaddescription: PCWSTR) -> HRESULT {
130 unsafe { SetLastError(ERROR_CALL_NOT_IMPLEMENTED as u32); E_NOTIMPL }
131 }
132
133 pub fn GetThreadDescription(hthread: HANDLE, lpthreaddescription: *mut PWSTR) -> HRESULT {
136 unsafe { SetLastError(ERROR_CALL_NOT_IMPLEMENTED as u32); E_NOTIMPL }
137 }
138
139 #[cfg(target_vendor = "win7")]
142 pub fn GetSystemTimePreciseAsFileTime(lpsystemtimeasfiletime: *mut FILETIME) -> () {
143 unsafe { GetSystemTimeAsFileTime(lpsystemtimeasfiletime) }
144 }
145
146 pub fn GetTempPath2W(bufferlength: u32, buffer: PWSTR) -> u32 {
149 unsafe { GetTempPathW(bufferlength, buffer) }
150 }
151}
152
153#[cfg(not(target_vendor = "win7"))]
154#[cfg_attr(
156 target_arch = "x86",
157 link(
158 name = "api-ms-win-core-synch-l1-2-0",
159 kind = "raw-dylib",
160 import_name_type = "undecorated"
161 )
162)]
163#[cfg_attr(
164 not(target_arch = "x86"),
165 link(name = "api-ms-win-core-synch-l1-2-0", kind = "raw-dylib")
166)]
167unsafe extern "system" {
168 pub fn WaitOnAddress(
169 address: *const c_void,
170 compareaddress: *const c_void,
171 addresssize: usize,
172 dwmilliseconds: u32,
173 ) -> BOOL;
174 pub fn WakeByAddressSingle(address: *const c_void);
175 pub fn WakeByAddressAll(address: *const c_void);
176}
177
178#[cfg(target_vendor = "win7")]
180compat_fn_optional! {
181 pub fn WaitOnAddress(
182 address: *const c_void,
183 compareaddress: *const c_void,
184 addresssize: usize,
185 dwmilliseconds: u32
186 ) -> BOOL;
187 pub fn WakeByAddressSingle(address: *const c_void);
188}
189
190#[cfg(any(target_vendor = "win7", target_vendor = "uwp"))]
191compat_fn_with_fallback! {
192 pub static NTDLL: &CStr = c"ntdll";
193
194 #[cfg(target_vendor = "win7")]
195 pub fn NtCreateKeyedEvent(
196 KeyedEventHandle: *mut HANDLE,
197 DesiredAccess: u32,
198 ObjectAttributes: *mut c_void,
199 Flags: u32
200 ) -> NTSTATUS {
201 panic!("keyed events not available")
202 }
203 #[cfg(target_vendor = "win7")]
204 pub fn NtReleaseKeyedEvent(
205 EventHandle: HANDLE,
206 Key: *const c_void,
207 Alertable: bool,
208 Timeout: *mut i64
209 ) -> NTSTATUS {
210 panic!("keyed events not available")
211 }
212 #[cfg(target_vendor = "win7")]
213 pub fn NtWaitForKeyedEvent(
214 EventHandle: HANDLE,
215 Key: *const c_void,
216 Alertable: bool,
217 Timeout: *mut i64
218 ) -> NTSTATUS {
219 panic!("keyed events not available")
220 }
221
222 #[cfg(target_vendor = "uwp")]
224 pub fn NtCreateFile(
225 filehandle: *mut HANDLE,
226 desiredaccess: FILE_ACCESS_RIGHTS,
227 objectattributes: *const OBJECT_ATTRIBUTES,
228 iostatusblock: *mut IO_STATUS_BLOCK,
229 allocationsize: *const i64,
230 fileattributes: FILE_FLAGS_AND_ATTRIBUTES,
231 shareaccess: FILE_SHARE_MODE,
232 createdisposition: NTCREATEFILE_CREATE_DISPOSITION,
233 createoptions: NTCREATEFILE_CREATE_OPTIONS,
234 eabuffer: *const c_void,
235 ealength: u32
236 ) -> NTSTATUS {
237 STATUS_NOT_IMPLEMENTED
238 }
239 #[cfg(target_vendor = "uwp")]
240 pub fn NtOpenFile(
241 filehandle: *mut HANDLE,
242 desiredaccess: u32,
243 objectattributes: *const OBJECT_ATTRIBUTES,
244 iostatusblock: *mut IO_STATUS_BLOCK,
245 shareaccess: u32,
246 openoptions: u32
247 ) -> NTSTATUS {
248 STATUS_NOT_IMPLEMENTED
249 }
250 #[cfg(target_vendor = "uwp")]
251 pub fn NtReadFile(
252 filehandle: HANDLE,
253 event: HANDLE,
254 apcroutine: PIO_APC_ROUTINE,
255 apccontext: *const c_void,
256 iostatusblock: *mut IO_STATUS_BLOCK,
257 buffer: *mut c_void,
258 length: u32,
259 byteoffset: *const i64,
260 key: *const u32
261 ) -> NTSTATUS {
262 STATUS_NOT_IMPLEMENTED
263 }
264 #[cfg(target_vendor = "uwp")]
265 pub fn NtWriteFile(
266 filehandle: HANDLE,
267 event: HANDLE,
268 apcroutine: PIO_APC_ROUTINE,
269 apccontext: *const c_void,
270 iostatusblock: *mut IO_STATUS_BLOCK,
271 buffer: *const c_void,
272 length: u32,
273 byteoffset: *const i64,
274 key: *const u32
275 ) -> NTSTATUS {
276 STATUS_NOT_IMPLEMENTED
277 }
278 #[cfg(target_vendor = "uwp")]
279 pub fn RtlNtStatusToDosError(Status: NTSTATUS) -> u32 {
280 Status as u32
281 }
282}