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 OBJECT_ATTRIBUTES {
41 pub fn with_length() -> Self {
42 Self {
43 Length: size_of::<Self>() as _,
44 RootDirectory: ptr::null_mut(),
45 ObjectName: ptr::null_mut(),
46 Attributes: 0,
47 SecurityDescriptor: ptr::null_mut(),
48 SecurityQualityOfService: ptr::null_mut(),
49 }
50 }
51}
52
53impl IO_STATUS_BLOCK {
54 pub const PENDING: Self =
55 IO_STATUS_BLOCK { Anonymous: IO_STATUS_BLOCK_0 { Status: STATUS_PENDING }, Information: 0 };
56 pub fn status(&self) -> NTSTATUS {
57 unsafe { self.Anonymous.Status }
63 }
64}
65
66#[repr(C)]
69pub struct REPARSE_DATA_BUFFER {
70 pub ReparseTag: c_uint,
71 pub ReparseDataLength: c_ushort,
72 pub Reserved: c_ushort,
73 pub rest: (),
74}
75
76#[repr(C)]
79pub struct SYMBOLIC_LINK_REPARSE_BUFFER {
80 pub SubstituteNameOffset: c_ushort,
81 pub SubstituteNameLength: c_ushort,
82 pub PrintNameOffset: c_ushort,
83 pub PrintNameLength: c_ushort,
84 pub Flags: c_ulong,
85 pub PathBuffer: WCHAR,
86}
87
88#[repr(C)]
89pub struct MOUNT_POINT_REPARSE_BUFFER {
90 pub SubstituteNameOffset: c_ushort,
91 pub SubstituteNameLength: c_ushort,
92 pub PrintNameOffset: c_ushort,
93 pub PrintNameLength: c_ushort,
94 pub PathBuffer: WCHAR,
95}
96
97cfg_if::cfg_if! {
99if #[cfg(not(target_vendor = "uwp"))] {
100 pub const EXCEPTION_CONTINUE_SEARCH: i32 = 0;
101}
102}
103
104#[cfg(not(target_vendor = "win7"))]
106#[cfg_attr(
107 target_arch = "x86",
108 link(name = "bcryptprimitives", kind = "raw-dylib", import_name_type = "undecorated")
109)]
110#[cfg_attr(not(target_arch = "x86"), link(name = "bcryptprimitives", kind = "raw-dylib"))]
111unsafe extern "system" {
112 pub fn ProcessPrng(pbdata: *mut u8, cbdata: usize) -> BOOL;
113}
114
115windows_targets::link!("ntdll.dll" "system" fn NtCreateNamedPipeFile(
116 filehandle: *mut HANDLE,
117 desiredaccess: FILE_ACCESS_RIGHTS,
118 objectattributes: *const OBJECT_ATTRIBUTES,
119 iostatusblock: *mut IO_STATUS_BLOCK,
120 shareaccess: FILE_SHARE_MODE,
121 createdisposition: NTCREATEFILE_CREATE_DISPOSITION,
122 createoptions: NTCREATEFILE_CREATE_OPTIONS,
123 namedpipetype: u32,
124 readmode: u32,
125 completionmode: u32,
126 maximuminstances: u32,
127 inboundquota: u32,
128 outboundquota: u32,
129 defaulttimeout: *const u64,
130) -> NTSTATUS);
131
132compat_fn_with_fallback! {
135 pub static KERNEL32: &CStr = c"kernel32";
136
137 pub fn SetThreadDescription(hthread: HANDLE, lpthreaddescription: PCWSTR) -> HRESULT {
140 unsafe { SetLastError(ERROR_CALL_NOT_IMPLEMENTED as u32); E_NOTIMPL }
141 }
142
143 pub fn GetThreadDescription(hthread: HANDLE, lpthreaddescription: *mut PWSTR) -> HRESULT {
146 unsafe { SetLastError(ERROR_CALL_NOT_IMPLEMENTED as u32); E_NOTIMPL }
147 }
148
149 #[cfg(target_vendor = "win7")]
152 pub fn GetSystemTimePreciseAsFileTime(lpsystemtimeasfiletime: *mut FILETIME) -> () {
153 unsafe { GetSystemTimeAsFileTime(lpsystemtimeasfiletime) }
154 }
155
156 pub fn GetTempPath2W(bufferlength: u32, buffer: PWSTR) -> u32 {
159 unsafe { GetTempPathW(bufferlength, buffer) }
160 }
161}
162
163#[cfg(not(target_vendor = "win7"))]
164#[cfg_attr(
166 target_arch = "x86",
167 link(
168 name = "api-ms-win-core-synch-l1-2-0",
169 kind = "raw-dylib",
170 import_name_type = "undecorated"
171 )
172)]
173#[cfg_attr(
174 not(target_arch = "x86"),
175 link(name = "api-ms-win-core-synch-l1-2-0", kind = "raw-dylib")
176)]
177unsafe extern "system" {
178 pub fn WaitOnAddress(
179 address: *const c_void,
180 compareaddress: *const c_void,
181 addresssize: usize,
182 dwmilliseconds: u32,
183 ) -> BOOL;
184 pub fn WakeByAddressSingle(address: *const c_void);
185 pub fn WakeByAddressAll(address: *const c_void);
186}
187
188#[cfg(target_vendor = "win7")]
190compat_fn_optional! {
191 pub fn WaitOnAddress(
192 address: *const c_void,
193 compareaddress: *const c_void,
194 addresssize: usize,
195 dwmilliseconds: u32
196 ) -> BOOL;
197 pub fn WakeByAddressSingle(address: *const c_void);
198}
199
200#[cfg(any(target_vendor = "win7"))]
201compat_fn_with_fallback! {
202 pub static NTDLL: &CStr = c"ntdll";
203
204 #[cfg(target_vendor = "win7")]
205 pub fn NtCreateKeyedEvent(
206 KeyedEventHandle: *mut HANDLE,
207 DesiredAccess: u32,
208 ObjectAttributes: *mut c_void,
209 Flags: u32
210 ) -> NTSTATUS {
211 panic!("keyed events not available")
212 }
213 #[cfg(target_vendor = "win7")]
214 pub fn NtReleaseKeyedEvent(
215 EventHandle: HANDLE,
216 Key: *const c_void,
217 Alertable: bool,
218 Timeout: *mut i64
219 ) -> NTSTATUS {
220 panic!("keyed events not available")
221 }
222 #[cfg(target_vendor = "win7")]
223 pub fn NtWaitForKeyedEvent(
224 EventHandle: HANDLE,
225 Key: *const c_void,
226 Alertable: bool,
227 Timeout: *mut i64
228 ) -> NTSTATUS {
229 panic!("keyed events not available")
230 }
231}
232
233cfg_if::cfg_if! {
234 if #[cfg(target_vendor = "uwp")] {
235 windows_targets::link_raw_dylib!("ntdll.dll" "system" fn NtCreateFile(filehandle : *mut HANDLE, desiredaccess : FILE_ACCESS_RIGHTS, objectattributes : *const OBJECT_ATTRIBUTES, iostatusblock : *mut IO_STATUS_BLOCK, allocationsize : *const i64, fileattributes : FILE_FLAGS_AND_ATTRIBUTES, shareaccess : FILE_SHARE_MODE, createdisposition : NTCREATEFILE_CREATE_DISPOSITION, createoptions : NTCREATEFILE_CREATE_OPTIONS, eabuffer : *const core::ffi::c_void, ealength : u32) -> NTSTATUS);
236 windows_targets::link_raw_dylib!("ntdll.dll" "system" fn NtOpenFile(filehandle : *mut HANDLE, desiredaccess : u32, objectattributes : *const OBJECT_ATTRIBUTES, iostatusblock : *mut IO_STATUS_BLOCK, shareaccess : u32, openoptions : u32) -> NTSTATUS);
237 windows_targets::link_raw_dylib!("ntdll.dll" "system" fn NtReadFile(filehandle : HANDLE, event : HANDLE, apcroutine : PIO_APC_ROUTINE, apccontext : *const core::ffi::c_void, iostatusblock : *mut IO_STATUS_BLOCK, buffer : *mut core::ffi::c_void, length : u32, byteoffset : *const i64, key : *const u32) -> NTSTATUS);
238 windows_targets::link_raw_dylib!("ntdll.dll" "system" fn NtWriteFile(filehandle : HANDLE, event : HANDLE, apcroutine : PIO_APC_ROUTINE, apccontext : *const core::ffi::c_void, iostatusblock : *mut IO_STATUS_BLOCK, buffer : *const core::ffi::c_void, length : u32, byteoffset : *const i64, key : *const u32) -> NTSTATUS);
239 windows_targets::link_raw_dylib!("ntdll.dll" "system" fn RtlNtStatusToDosError(status : NTSTATUS) -> u32);
240 }
241}