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
122windows_targets::link!("ntdll.dll" "system" fn NtCreateNamedPipeFile(
123 filehandle: *mut HANDLE,
124 desiredaccess: FILE_ACCESS_RIGHTS,
125 objectattributes: *const OBJECT_ATTRIBUTES,
126 iostatusblock: *mut IO_STATUS_BLOCK,
127 shareaccess: FILE_SHARE_MODE,
128 createdisposition: NTCREATEFILE_CREATE_DISPOSITION,
129 createoptions: NTCREATEFILE_CREATE_OPTIONS,
130 namedpipetype: u32,
131 readmode: u32,
132 completionmode: u32,
133 maximuminstances: u32,
134 inboundquota: u32,
135 outboundquota: u32,
136 defaulttimeout: *const u64,
137) -> NTSTATUS);
138
139compat_fn_with_fallback! {
142 pub static KERNEL32: &CStr = c"kernel32";
143
144 pub fn SetThreadDescription(hthread: HANDLE, lpthreaddescription: PCWSTR) -> HRESULT {
147 unsafe { SetLastError(ERROR_CALL_NOT_IMPLEMENTED as u32); E_NOTIMPL }
148 }
149
150 pub fn GetThreadDescription(hthread: HANDLE, lpthreaddescription: *mut PWSTR) -> HRESULT {
153 unsafe { SetLastError(ERROR_CALL_NOT_IMPLEMENTED as u32); E_NOTIMPL }
154 }
155
156 #[cfg(target_vendor = "win7")]
159 pub fn GetSystemTimePreciseAsFileTime(lpsystemtimeasfiletime: *mut FILETIME) -> () {
160 unsafe { GetSystemTimeAsFileTime(lpsystemtimeasfiletime) }
161 }
162
163 pub fn GetTempPath2W(bufferlength: u32, buffer: PWSTR) -> u32 {
166 unsafe { GetTempPathW(bufferlength, buffer) }
167 }
168}
169
170#[cfg(not(target_vendor = "win7"))]
171#[cfg_attr(
173 target_arch = "x86",
174 link(
175 name = "api-ms-win-core-synch-l1-2-0",
176 kind = "raw-dylib",
177 import_name_type = "undecorated"
178 )
179)]
180#[cfg_attr(
181 not(target_arch = "x86"),
182 link(name = "api-ms-win-core-synch-l1-2-0", kind = "raw-dylib")
183)]
184unsafe extern "system" {
185 pub fn WaitOnAddress(
186 address: *const c_void,
187 compareaddress: *const c_void,
188 addresssize: usize,
189 dwmilliseconds: u32,
190 ) -> BOOL;
191 pub fn WakeByAddressSingle(address: *const c_void);
192 pub fn WakeByAddressAll(address: *const c_void);
193}
194
195#[cfg(target_vendor = "win7")]
197compat_fn_optional! {
198 pub fn WaitOnAddress(
199 address: *const c_void,
200 compareaddress: *const c_void,
201 addresssize: usize,
202 dwmilliseconds: u32
203 ) -> BOOL;
204 pub fn WakeByAddressSingle(address: *const c_void);
205}
206
207#[cfg(any(target_vendor = "win7", target_vendor = "uwp"))]
208compat_fn_with_fallback! {
209 pub static NTDLL: &CStr = c"ntdll";
210
211 #[cfg(target_vendor = "win7")]
212 pub fn NtCreateKeyedEvent(
213 KeyedEventHandle: *mut HANDLE,
214 DesiredAccess: u32,
215 ObjectAttributes: *mut c_void,
216 Flags: u32
217 ) -> NTSTATUS {
218 panic!("keyed events not available")
219 }
220 #[cfg(target_vendor = "win7")]
221 pub fn NtReleaseKeyedEvent(
222 EventHandle: HANDLE,
223 Key: *const c_void,
224 Alertable: bool,
225 Timeout: *mut i64
226 ) -> NTSTATUS {
227 panic!("keyed events not available")
228 }
229 #[cfg(target_vendor = "win7")]
230 pub fn NtWaitForKeyedEvent(
231 EventHandle: HANDLE,
232 Key: *const c_void,
233 Alertable: bool,
234 Timeout: *mut i64
235 ) -> NTSTATUS {
236 panic!("keyed events not available")
237 }
238
239 #[cfg(target_vendor = "uwp")]
241 pub fn NtCreateFile(
242 filehandle: *mut HANDLE,
243 desiredaccess: FILE_ACCESS_RIGHTS,
244 objectattributes: *const OBJECT_ATTRIBUTES,
245 iostatusblock: *mut IO_STATUS_BLOCK,
246 allocationsize: *const i64,
247 fileattributes: FILE_FLAGS_AND_ATTRIBUTES,
248 shareaccess: FILE_SHARE_MODE,
249 createdisposition: NTCREATEFILE_CREATE_DISPOSITION,
250 createoptions: NTCREATEFILE_CREATE_OPTIONS,
251 eabuffer: *const c_void,
252 ealength: u32
253 ) -> NTSTATUS {
254 STATUS_NOT_IMPLEMENTED
255 }
256 #[cfg(target_vendor = "uwp")]
257 pub fn NtOpenFile(
258 filehandle: *mut HANDLE,
259 desiredaccess: u32,
260 objectattributes: *const OBJECT_ATTRIBUTES,
261 iostatusblock: *mut IO_STATUS_BLOCK,
262 shareaccess: u32,
263 openoptions: u32
264 ) -> NTSTATUS {
265 STATUS_NOT_IMPLEMENTED
266 }
267 #[cfg(target_vendor = "uwp")]
268 pub fn NtReadFile(
269 filehandle: HANDLE,
270 event: HANDLE,
271 apcroutine: PIO_APC_ROUTINE,
272 apccontext: *const c_void,
273 iostatusblock: *mut IO_STATUS_BLOCK,
274 buffer: *mut c_void,
275 length: u32,
276 byteoffset: *const i64,
277 key: *const u32
278 ) -> NTSTATUS {
279 STATUS_NOT_IMPLEMENTED
280 }
281 #[cfg(target_vendor = "uwp")]
282 pub fn NtWriteFile(
283 filehandle: HANDLE,
284 event: HANDLE,
285 apcroutine: PIO_APC_ROUTINE,
286 apccontext: *const c_void,
287 iostatusblock: *mut IO_STATUS_BLOCK,
288 buffer: *const c_void,
289 length: u32,
290 byteoffset: *const i64,
291 key: *const u32
292 ) -> NTSTATUS {
293 STATUS_NOT_IMPLEMENTED
294 }
295 #[cfg(target_vendor = "uwp")]
296 pub fn RtlNtStatusToDosError(Status: NTSTATUS) -> u32 {
297 Status as u32
298 }
299}