1 //! C definitions used by libnative that don't belong in liblibc
2 
3 #![allow(nonstandard_style)]
4 #![cfg_attr(test, allow(dead_code))]
5 #![unstable(issue = "none", feature = "windows_c")]
6 
7 use crate::mem;
8 use crate::os::raw::NonZero_c_ulong;
9 use crate::os::raw::{c_char, c_int, c_long, c_longlong, c_uint, c_ulong, c_ushort};
10 use crate::ptr;
11 
12 use libc::{c_void, size_t, wchar_t};
13 
14 #[path = "c/errors.rs"] // c.rs is included from two places so we need to specify this
15 mod errors;
16 pub use errors::*;
17 
18 pub use self::EXCEPTION_DISPOSITION::*;
19 pub use self::FILE_INFO_BY_HANDLE_CLASS::*;
20 
21 pub type DWORD_PTR = ULONG_PTR;
22 pub type DWORD = c_ulong;
23 pub type NonZeroDWORD = NonZero_c_ulong;
24 pub type HANDLE = LPVOID;
25 pub type HINSTANCE = HANDLE;
26 pub type HMODULE = HINSTANCE;
27 pub type HRESULT = LONG;
28 pub type BOOL = c_int;
29 pub type BYTE = u8;
30 pub type BOOLEAN = BYTE;
31 pub type GROUP = c_uint;
32 pub type LARGE_INTEGER = c_longlong;
33 pub type LONG = c_long;
34 pub type UINT = c_uint;
35 pub type WCHAR = u16;
36 pub type USHORT = c_ushort;
37 pub type SIZE_T = usize;
38 pub type WORD = u16;
39 pub type CHAR = c_char;
40 pub type CCHAR = c_char;
41 pub type ULONG_PTR = usize;
42 pub type ULONG = c_ulong;
43 pub type NTSTATUS = LONG;
44 pub type ACCESS_MASK = DWORD;
45 
46 pub type LPBOOL = *mut BOOL;
47 pub type LPBYTE = *mut BYTE;
48 pub type LPCSTR = *const CHAR;
49 pub type LPCWSTR = *const WCHAR;
50 pub type LPDWORD = *mut DWORD;
51 pub type LPHANDLE = *mut HANDLE;
52 pub type LPOVERLAPPED = *mut OVERLAPPED;
53 pub type LPPROCESS_INFORMATION = *mut PROCESS_INFORMATION;
54 pub type LPSECURITY_ATTRIBUTES = *mut SECURITY_ATTRIBUTES;
55 pub type LPSTARTUPINFO = *mut STARTUPINFO;
56 pub type LPVOID = *mut c_void;
57 pub type LPWCH = *mut WCHAR;
58 pub type LPWIN32_FIND_DATAW = *mut WIN32_FIND_DATAW;
59 pub type LPWSADATA = *mut WSADATA;
60 pub type LPWSAPROTOCOL_INFO = *mut WSAPROTOCOL_INFO;
61 pub type LPWSTR = *mut WCHAR;
62 pub type LPFILETIME = *mut FILETIME;
63 pub type LPSYSTEM_INFO = *mut SYSTEM_INFO;
64 pub type LPWSABUF = *mut WSABUF;
65 pub type LPWSAOVERLAPPED = *mut c_void;
66 pub type LPWSAOVERLAPPED_COMPLETION_ROUTINE = *mut c_void;
67 
68 pub type PCONDITION_VARIABLE = *mut CONDITION_VARIABLE;
69 pub type PLARGE_INTEGER = *mut c_longlong;
70 pub type PSRWLOCK = *mut SRWLOCK;
71 
72 pub type SOCKET = crate::os::windows::raw::SOCKET;
73 pub type socklen_t = c_int;
74 pub type ADDRESS_FAMILY = USHORT;
75 
76 pub const TRUE: BOOL = 1;
77 pub const FALSE: BOOL = 0;
78 
79 pub const CSTR_LESS_THAN: c_int = 1;
80 pub const CSTR_EQUAL: c_int = 2;
81 pub const CSTR_GREATER_THAN: c_int = 3;
82 
83 pub const FILE_ATTRIBUTE_READONLY: DWORD = 0x1;
84 pub const FILE_ATTRIBUTE_DIRECTORY: DWORD = 0x10;
85 pub const FILE_ATTRIBUTE_REPARSE_POINT: DWORD = 0x400;
86 
87 pub const FILE_SHARE_DELETE: DWORD = 0x4;
88 pub const FILE_SHARE_READ: DWORD = 0x1;
89 pub const FILE_SHARE_WRITE: DWORD = 0x2;
90 
91 pub const FILE_OPEN_REPARSE_POINT: ULONG = 0x200000;
92 pub const OBJ_DONT_REPARSE: ULONG = 0x1000;
93 
94 pub const CREATE_ALWAYS: DWORD = 2;
95 pub const CREATE_NEW: DWORD = 1;
96 pub const OPEN_ALWAYS: DWORD = 4;
97 pub const OPEN_EXISTING: DWORD = 3;
98 pub const TRUNCATE_EXISTING: DWORD = 5;
99 
100 pub const FILE_LIST_DIRECTORY: DWORD = 0x1;
101 pub const FILE_WRITE_DATA: DWORD = 0x00000002;
102 pub const FILE_APPEND_DATA: DWORD = 0x00000004;
103 pub const FILE_WRITE_EA: DWORD = 0x00000010;
104 pub const FILE_WRITE_ATTRIBUTES: DWORD = 0x00000100;
105 pub const DELETE: DWORD = 0x10000;
106 pub const READ_CONTROL: DWORD = 0x00020000;
107 pub const SYNCHRONIZE: DWORD = 0x00100000;
108 pub const GENERIC_READ: DWORD = 0x80000000;
109 pub const GENERIC_WRITE: DWORD = 0x40000000;
110 pub const STANDARD_RIGHTS_WRITE: DWORD = READ_CONTROL;
111 pub const FILE_GENERIC_WRITE: DWORD = STANDARD_RIGHTS_WRITE
112     | FILE_WRITE_DATA
113     | FILE_WRITE_ATTRIBUTES
114     | FILE_WRITE_EA
115     | FILE_APPEND_DATA
116     | SYNCHRONIZE;
117 
118 pub const FILE_FLAG_OPEN_REPARSE_POINT: DWORD = 0x00200000;
119 pub const FILE_FLAG_BACKUP_SEMANTICS: DWORD = 0x02000000;
120 pub const SECURITY_SQOS_PRESENT: DWORD = 0x00100000;
121 
122 pub const FIONBIO: c_ulong = 0x8004667e;
123 
124 #[repr(C)]
125 #[derive(Copy)]
126 pub struct WIN32_FIND_DATAW {
127     pub dwFileAttributes: DWORD,
128     pub ftCreationTime: FILETIME,
129     pub ftLastAccessTime: FILETIME,
130     pub ftLastWriteTime: FILETIME,
131     pub nFileSizeHigh: DWORD,
132     pub nFileSizeLow: DWORD,
133     pub dwReserved0: DWORD,
134     pub dwReserved1: DWORD,
135     pub cFileName: [wchar_t; 260], // #define MAX_PATH 260
136     pub cAlternateFileName: [wchar_t; 14],
137 }
138 impl Clone for WIN32_FIND_DATAW {
clone(&self) -> Self139     fn clone(&self) -> Self {
140         *self
141     }
142 }
143 
144 pub const WSA_FLAG_OVERLAPPED: DWORD = 0x01;
145 pub const WSA_FLAG_NO_HANDLE_INHERIT: DWORD = 0x80;
146 
147 pub const WSADESCRIPTION_LEN: usize = 256;
148 pub const WSASYS_STATUS_LEN: usize = 128;
149 pub const WSAPROTOCOL_LEN: DWORD = 255;
150 pub const INVALID_SOCKET: SOCKET = !0;
151 
152 pub const MAX_PROTOCOL_CHAIN: DWORD = 7;
153 
154 pub const MAXIMUM_REPARSE_DATA_BUFFER_SIZE: usize = 16 * 1024;
155 pub const FSCTL_GET_REPARSE_POINT: DWORD = 0x900a8;
156 pub const IO_REPARSE_TAG_SYMLINK: DWORD = 0xa000000c;
157 pub const IO_REPARSE_TAG_MOUNT_POINT: DWORD = 0xa0000003;
158 pub const SYMLINK_FLAG_RELATIVE: DWORD = 0x00000001;
159 pub const FSCTL_SET_REPARSE_POINT: DWORD = 0x900a4;
160 
161 pub const SYMBOLIC_LINK_FLAG_DIRECTORY: DWORD = 0x1;
162 pub const SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE: DWORD = 0x2;
163 
164 // Note that these are not actually HANDLEs, just values to pass to GetStdHandle
165 pub const STD_INPUT_HANDLE: DWORD = -10i32 as DWORD;
166 pub const STD_OUTPUT_HANDLE: DWORD = -11i32 as DWORD;
167 pub const STD_ERROR_HANDLE: DWORD = -12i32 as DWORD;
168 
169 pub const PROGRESS_CONTINUE: DWORD = 0;
170 
171 pub const E_NOTIMPL: HRESULT = 0x80004001u32 as HRESULT;
172 
173 pub const INVALID_HANDLE_VALUE: HANDLE = !0 as HANDLE;
174 
175 pub const FACILITY_NT_BIT: DWORD = 0x1000_0000;
176 
177 pub const FORMAT_MESSAGE_FROM_SYSTEM: DWORD = 0x00001000;
178 pub const FORMAT_MESSAGE_FROM_HMODULE: DWORD = 0x00000800;
179 pub const FORMAT_MESSAGE_IGNORE_INSERTS: DWORD = 0x00000200;
180 
181 pub const TLS_OUT_OF_INDEXES: DWORD = 0xFFFFFFFF;
182 
183 pub const DLL_THREAD_DETACH: DWORD = 3;
184 pub const DLL_PROCESS_DETACH: DWORD = 0;
185 
186 pub const INFINITE: DWORD = !0;
187 
188 pub const DUPLICATE_SAME_ACCESS: DWORD = 0x00000002;
189 
190 pub const CONDITION_VARIABLE_INIT: CONDITION_VARIABLE = CONDITION_VARIABLE { ptr: ptr::null_mut() };
191 pub const SRWLOCK_INIT: SRWLOCK = SRWLOCK { ptr: ptr::null_mut() };
192 
193 pub const DETACHED_PROCESS: DWORD = 0x00000008;
194 pub const CREATE_NEW_PROCESS_GROUP: DWORD = 0x00000200;
195 pub const CREATE_UNICODE_ENVIRONMENT: DWORD = 0x00000400;
196 pub const STARTF_USESTDHANDLES: DWORD = 0x00000100;
197 
198 pub const AF_INET: c_int = 2;
199 pub const AF_INET6: c_int = 23;
200 pub const SD_BOTH: c_int = 2;
201 pub const SD_RECEIVE: c_int = 0;
202 pub const SD_SEND: c_int = 1;
203 pub const SOCK_DGRAM: c_int = 2;
204 pub const SOCK_STREAM: c_int = 1;
205 pub const SOCKET_ERROR: c_int = -1;
206 pub const SOL_SOCKET: c_int = 0xffff;
207 pub const SO_LINGER: c_int = 0x0080;
208 pub const SO_RCVTIMEO: c_int = 0x1006;
209 pub const SO_SNDTIMEO: c_int = 0x1005;
210 pub const IPPROTO_IP: c_int = 0;
211 pub const IPPROTO_TCP: c_int = 6;
212 pub const IPPROTO_IPV6: c_int = 41;
213 pub const TCP_NODELAY: c_int = 0x0001;
214 pub const IP_TTL: c_int = 4;
215 pub const IPV6_V6ONLY: c_int = 27;
216 pub const SO_ERROR: c_int = 0x1007;
217 pub const SO_BROADCAST: c_int = 0x0020;
218 pub const IP_MULTICAST_LOOP: c_int = 11;
219 pub const IPV6_MULTICAST_LOOP: c_int = 11;
220 pub const IP_MULTICAST_TTL: c_int = 10;
221 pub const IP_ADD_MEMBERSHIP: c_int = 12;
222 pub const IP_DROP_MEMBERSHIP: c_int = 13;
223 pub const IPV6_ADD_MEMBERSHIP: c_int = 12;
224 pub const IPV6_DROP_MEMBERSHIP: c_int = 13;
225 pub const MSG_PEEK: c_int = 0x2;
226 
227 #[repr(C)]
228 #[derive(Copy, Clone)]
229 pub struct linger {
230     pub l_onoff: c_ushort,
231     pub l_linger: c_ushort,
232 }
233 
234 #[repr(C)]
235 pub struct ip_mreq {
236     pub imr_multiaddr: in_addr,
237     pub imr_interface: in_addr,
238 }
239 
240 #[repr(C)]
241 pub struct ipv6_mreq {
242     pub ipv6mr_multiaddr: in6_addr,
243     pub ipv6mr_interface: c_uint,
244 }
245 
246 pub const VOLUME_NAME_DOS: DWORD = 0x0;
247 pub const MOVEFILE_REPLACE_EXISTING: DWORD = 1;
248 
249 pub const FILE_BEGIN: DWORD = 0;
250 pub const FILE_CURRENT: DWORD = 1;
251 pub const FILE_END: DWORD = 2;
252 
253 pub const WAIT_OBJECT_0: DWORD = 0x00000000;
254 pub const WAIT_TIMEOUT: DWORD = 258;
255 pub const WAIT_FAILED: DWORD = 0xFFFFFFFF;
256 
257 pub const PIPE_ACCESS_INBOUND: DWORD = 0x00000001;
258 pub const PIPE_ACCESS_OUTBOUND: DWORD = 0x00000002;
259 pub const FILE_FLAG_FIRST_PIPE_INSTANCE: DWORD = 0x00080000;
260 pub const FILE_FLAG_OVERLAPPED: DWORD = 0x40000000;
261 pub const PIPE_WAIT: DWORD = 0x00000000;
262 pub const PIPE_TYPE_BYTE: DWORD = 0x00000000;
263 pub const PIPE_REJECT_REMOTE_CLIENTS: DWORD = 0x00000008;
264 pub const PIPE_READMODE_BYTE: DWORD = 0x00000000;
265 
266 pub const FD_SETSIZE: usize = 64;
267 
268 pub const STACK_SIZE_PARAM_IS_A_RESERVATION: DWORD = 0x00010000;
269 
270 pub const STATUS_SUCCESS: NTSTATUS = 0x00000000;
271 pub const STATUS_DELETE_PENDING: NTSTATUS = 0xc0000056_u32 as _;
272 pub const STATUS_INVALID_PARAMETER: NTSTATUS = 0xc000000d_u32 as _;
273 
274 // Equivalent to the `NT_SUCCESS` C preprocessor macro.
275 // See: https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/using-ntstatus-values
nt_success(status: NTSTATUS) -> bool276 pub fn nt_success(status: NTSTATUS) -> bool {
277     status >= 0
278 }
279 
280 pub const BCRYPT_USE_SYSTEM_PREFERRED_RNG: DWORD = 0x00000002;
281 
282 #[repr(C)]
283 pub struct UNICODE_STRING {
284     pub Length: u16,
285     pub MaximumLength: u16,
286     pub Buffer: *mut u16,
287 }
288 impl UNICODE_STRING {
from_ref(slice: &[u16]) -> Self289     pub fn from_ref(slice: &[u16]) -> Self {
290         let len = slice.len() * mem::size_of::<u16>();
291         Self { Length: len as _, MaximumLength: len as _, Buffer: slice.as_ptr() as _ }
292     }
293 }
294 #[repr(C)]
295 pub struct OBJECT_ATTRIBUTES {
296     pub Length: ULONG,
297     pub RootDirectory: HANDLE,
298     pub ObjectName: *const UNICODE_STRING,
299     pub Attributes: ULONG,
300     pub SecurityDescriptor: *mut c_void,
301     pub SecurityQualityOfService: *mut c_void,
302 }
303 impl Default for OBJECT_ATTRIBUTES {
default() -> Self304     fn default() -> Self {
305         Self {
306             Length: mem::size_of::<Self>() as _,
307             RootDirectory: ptr::null_mut(),
308             ObjectName: ptr::null_mut(),
309             Attributes: 0,
310             SecurityDescriptor: ptr::null_mut(),
311             SecurityQualityOfService: ptr::null_mut(),
312         }
313     }
314 }
315 #[repr(C)]
316 pub struct IO_STATUS_BLOCK {
317     pub Pointer: *mut c_void,
318     pub Information: usize,
319 }
320 impl Default for IO_STATUS_BLOCK {
default() -> Self321     fn default() -> Self {
322         Self { Pointer: ptr::null_mut(), Information: 0 }
323     }
324 }
325 
326 #[repr(C)]
327 #[cfg(not(target_pointer_width = "64"))]
328 pub struct WSADATA {
329     pub wVersion: WORD,
330     pub wHighVersion: WORD,
331     pub szDescription: [u8; WSADESCRIPTION_LEN + 1],
332     pub szSystemStatus: [u8; WSASYS_STATUS_LEN + 1],
333     pub iMaxSockets: u16,
334     pub iMaxUdpDg: u16,
335     pub lpVendorInfo: *mut u8,
336 }
337 #[repr(C)]
338 #[cfg(target_pointer_width = "64")]
339 pub struct WSADATA {
340     pub wVersion: WORD,
341     pub wHighVersion: WORD,
342     pub iMaxSockets: u16,
343     pub iMaxUdpDg: u16,
344     pub lpVendorInfo: *mut u8,
345     pub szDescription: [u8; WSADESCRIPTION_LEN + 1],
346     pub szSystemStatus: [u8; WSASYS_STATUS_LEN + 1],
347 }
348 
349 #[derive(Copy, Clone)]
350 #[repr(C)]
351 pub struct WSABUF {
352     pub len: ULONG,
353     pub buf: *mut CHAR,
354 }
355 
356 #[repr(C)]
357 pub struct WSAPROTOCOL_INFO {
358     pub dwServiceFlags1: DWORD,
359     pub dwServiceFlags2: DWORD,
360     pub dwServiceFlags3: DWORD,
361     pub dwServiceFlags4: DWORD,
362     pub dwProviderFlags: DWORD,
363     pub ProviderId: GUID,
364     pub dwCatalogEntryId: DWORD,
365     pub ProtocolChain: WSAPROTOCOLCHAIN,
366     pub iVersion: c_int,
367     pub iAddressFamily: c_int,
368     pub iMaxSockAddr: c_int,
369     pub iMinSockAddr: c_int,
370     pub iSocketType: c_int,
371     pub iProtocol: c_int,
372     pub iProtocolMaxOffset: c_int,
373     pub iNetworkByteOrder: c_int,
374     pub iSecurityScheme: c_int,
375     pub dwMessageSize: DWORD,
376     pub dwProviderReserved: DWORD,
377     pub szProtocol: [u16; (WSAPROTOCOL_LEN as usize) + 1],
378 }
379 
380 #[repr(C)]
381 #[derive(Copy, Clone)]
382 pub struct WIN32_FILE_ATTRIBUTE_DATA {
383     pub dwFileAttributes: DWORD,
384     pub ftCreationTime: FILETIME,
385     pub ftLastAccessTime: FILETIME,
386     pub ftLastWriteTime: FILETIME,
387     pub nFileSizeHigh: DWORD,
388     pub nFileSizeLow: DWORD,
389 }
390 
391 #[repr(C)]
392 #[allow(dead_code)] // we only use some variants
393 pub enum FILE_INFO_BY_HANDLE_CLASS {
394     FileBasicInfo = 0,
395     FileStandardInfo = 1,
396     FileNameInfo = 2,
397     FileRenameInfo = 3,
398     FileDispositionInfo = 4,
399     FileAllocationInfo = 5,
400     FileEndOfFileInfo = 6,
401     FileStreamInfo = 7,
402     FileCompressionInfo = 8,
403     FileAttributeTagInfo = 9,
404     FileIdBothDirectoryInfo = 10,        // 0xA
405     FileIdBothDirectoryRestartInfo = 11, // 0xB
406     FileIoPriorityHintInfo = 12,         // 0xC
407     FileRemoteProtocolInfo = 13,         // 0xD
408     FileFullDirectoryInfo = 14,          // 0xE
409     FileFullDirectoryRestartInfo = 15,   // 0xF
410     FileStorageInfo = 16,                // 0x10
411     FileAlignmentInfo = 17,              // 0x11
412     FileIdInfo = 18,                     // 0x12
413     FileIdExtdDirectoryInfo = 19,        // 0x13
414     FileIdExtdDirectoryRestartInfo = 20, // 0x14
415     FileDispositionInfoEx = 21,          // 0x15, Windows 10 version 1607
416     MaximumFileInfoByHandlesClass,
417 }
418 
419 #[repr(C)]
420 pub struct FILE_DISPOSITION_INFO {
421     pub DeleteFile: BOOLEAN,
422 }
423 
424 pub const FILE_DISPOSITION_DELETE: DWORD = 0x1;
425 pub const FILE_DISPOSITION_POSIX_SEMANTICS: DWORD = 0x2;
426 pub const FILE_DISPOSITION_IGNORE_READONLY_ATTRIBUTE: DWORD = 0x10;
427 
428 #[repr(C)]
429 pub struct FILE_DISPOSITION_INFO_EX {
430     pub Flags: DWORD,
431 }
432 
433 #[repr(C)]
434 #[derive(Default)]
435 pub struct FILE_ID_BOTH_DIR_INFO {
436     pub NextEntryOffset: DWORD,
437     pub FileIndex: DWORD,
438     pub CreationTime: LARGE_INTEGER,
439     pub LastAccessTime: LARGE_INTEGER,
440     pub LastWriteTime: LARGE_INTEGER,
441     pub ChangeTime: LARGE_INTEGER,
442     pub EndOfFile: LARGE_INTEGER,
443     pub AllocationSize: LARGE_INTEGER,
444     pub FileAttributes: DWORD,
445     pub FileNameLength: DWORD,
446     pub EaSize: DWORD,
447     pub ShortNameLength: CCHAR,
448     pub ShortName: [WCHAR; 12],
449     pub FileId: LARGE_INTEGER,
450     pub FileName: [WCHAR; 1],
451 }
452 #[repr(C)]
453 pub struct FILE_BASIC_INFO {
454     pub CreationTime: LARGE_INTEGER,
455     pub LastAccessTime: LARGE_INTEGER,
456     pub LastWriteTime: LARGE_INTEGER,
457     pub ChangeTime: LARGE_INTEGER,
458     pub FileAttributes: DWORD,
459 }
460 
461 #[repr(C)]
462 pub struct FILE_END_OF_FILE_INFO {
463     pub EndOfFile: LARGE_INTEGER,
464 }
465 
466 #[repr(C)]
467 pub struct REPARSE_DATA_BUFFER {
468     pub ReparseTag: c_uint,
469     pub ReparseDataLength: c_ushort,
470     pub Reserved: c_ushort,
471     pub rest: (),
472 }
473 
474 #[repr(C)]
475 pub struct SYMBOLIC_LINK_REPARSE_BUFFER {
476     pub SubstituteNameOffset: c_ushort,
477     pub SubstituteNameLength: c_ushort,
478     pub PrintNameOffset: c_ushort,
479     pub PrintNameLength: c_ushort,
480     pub Flags: c_ulong,
481     pub PathBuffer: WCHAR,
482 }
483 
484 #[repr(C)]
485 pub struct MOUNT_POINT_REPARSE_BUFFER {
486     pub SubstituteNameOffset: c_ushort,
487     pub SubstituteNameLength: c_ushort,
488     pub PrintNameOffset: c_ushort,
489     pub PrintNameLength: c_ushort,
490     pub PathBuffer: WCHAR,
491 }
492 
493 pub type LPPROGRESS_ROUTINE = crate::option::Option<
494     unsafe extern "system" fn(
495         TotalFileSize: LARGE_INTEGER,
496         TotalBytesTransferred: LARGE_INTEGER,
497         StreamSize: LARGE_INTEGER,
498         StreamBytesTransferred: LARGE_INTEGER,
499         dwStreamNumber: DWORD,
500         dwCallbackReason: DWORD,
501         hSourceFile: HANDLE,
502         hDestinationFile: HANDLE,
503         lpData: LPVOID,
504     ) -> DWORD,
505 >;
506 
507 #[repr(C)]
508 pub struct CONDITION_VARIABLE {
509     pub ptr: LPVOID,
510 }
511 #[repr(C)]
512 pub struct SRWLOCK {
513     pub ptr: LPVOID,
514 }
515 #[repr(C)]
516 pub struct CRITICAL_SECTION {
517     CriticalSectionDebug: LPVOID,
518     LockCount: LONG,
519     RecursionCount: LONG,
520     OwningThread: HANDLE,
521     LockSemaphore: HANDLE,
522     SpinCount: ULONG_PTR,
523 }
524 
525 #[repr(C)]
526 pub struct REPARSE_MOUNTPOINT_DATA_BUFFER {
527     pub ReparseTag: DWORD,
528     pub ReparseDataLength: DWORD,
529     pub Reserved: WORD,
530     pub ReparseTargetLength: WORD,
531     pub ReparseTargetMaximumLength: WORD,
532     pub Reserved1: WORD,
533     pub ReparseTarget: WCHAR,
534 }
535 
536 #[repr(C)]
537 pub struct GUID {
538     pub Data1: DWORD,
539     pub Data2: WORD,
540     pub Data3: WORD,
541     pub Data4: [BYTE; 8],
542 }
543 
544 #[repr(C)]
545 pub struct WSAPROTOCOLCHAIN {
546     pub ChainLen: c_int,
547     pub ChainEntries: [DWORD; MAX_PROTOCOL_CHAIN as usize],
548 }
549 
550 #[repr(C)]
551 pub struct SECURITY_ATTRIBUTES {
552     pub nLength: DWORD,
553     pub lpSecurityDescriptor: LPVOID,
554     pub bInheritHandle: BOOL,
555 }
556 
557 #[repr(C)]
558 pub struct PROCESS_INFORMATION {
559     pub hProcess: HANDLE,
560     pub hThread: HANDLE,
561     pub dwProcessId: DWORD,
562     pub dwThreadId: DWORD,
563 }
564 
565 #[repr(C)]
566 pub struct STARTUPINFO {
567     pub cb: DWORD,
568     pub lpReserved: LPWSTR,
569     pub lpDesktop: LPWSTR,
570     pub lpTitle: LPWSTR,
571     pub dwX: DWORD,
572     pub dwY: DWORD,
573     pub dwXSize: DWORD,
574     pub dwYSize: DWORD,
575     pub dwXCountChars: DWORD,
576     pub dwYCountCharts: DWORD,
577     pub dwFillAttribute: DWORD,
578     pub dwFlags: DWORD,
579     pub wShowWindow: WORD,
580     pub cbReserved2: WORD,
581     pub lpReserved2: LPBYTE,
582     pub hStdInput: HANDLE,
583     pub hStdOutput: HANDLE,
584     pub hStdError: HANDLE,
585 }
586 
587 #[repr(C)]
588 pub struct SOCKADDR {
589     pub sa_family: ADDRESS_FAMILY,
590     pub sa_data: [CHAR; 14],
591 }
592 
593 #[repr(C)]
594 #[derive(Copy, Clone)]
595 pub struct FILETIME {
596     pub dwLowDateTime: DWORD,
597     pub dwHighDateTime: DWORD,
598 }
599 
600 #[repr(C)]
601 pub struct SYSTEM_INFO {
602     pub wProcessorArchitecture: WORD,
603     pub wReserved: WORD,
604     pub dwPageSize: DWORD,
605     pub lpMinimumApplicationAddress: LPVOID,
606     pub lpMaximumApplicationAddress: LPVOID,
607     pub dwActiveProcessorMask: DWORD_PTR,
608     pub dwNumberOfProcessors: DWORD,
609     pub dwProcessorType: DWORD,
610     pub dwAllocationGranularity: DWORD,
611     pub wProcessorLevel: WORD,
612     pub wProcessorRevision: WORD,
613 }
614 
615 #[repr(C)]
616 pub struct OVERLAPPED {
617     pub Internal: *mut c_ulong,
618     pub InternalHigh: *mut c_ulong,
619     pub Offset: DWORD,
620     pub OffsetHigh: DWORD,
621     pub hEvent: HANDLE,
622 }
623 
624 #[repr(C)]
625 #[allow(dead_code)] // we only use some variants
626 pub enum ADDRESS_MODE {
627     AddrMode1616,
628     AddrMode1632,
629     AddrModeReal,
630     AddrModeFlat,
631 }
632 
633 #[repr(C)]
634 pub struct SOCKADDR_STORAGE_LH {
635     pub ss_family: ADDRESS_FAMILY,
636     pub __ss_pad1: [CHAR; 6],
637     pub __ss_align: i64,
638     pub __ss_pad2: [CHAR; 112],
639 }
640 
641 #[repr(C)]
642 pub struct ADDRINFOA {
643     pub ai_flags: c_int,
644     pub ai_family: c_int,
645     pub ai_socktype: c_int,
646     pub ai_protocol: c_int,
647     pub ai_addrlen: size_t,
648     pub ai_canonname: *mut c_char,
649     pub ai_addr: *mut SOCKADDR,
650     pub ai_next: *mut ADDRINFOA,
651 }
652 
653 #[repr(C)]
654 #[derive(Copy, Clone)]
655 pub struct sockaddr_in {
656     pub sin_family: ADDRESS_FAMILY,
657     pub sin_port: USHORT,
658     pub sin_addr: in_addr,
659     pub sin_zero: [CHAR; 8],
660 }
661 
662 #[repr(C)]
663 #[derive(Copy, Clone)]
664 pub struct sockaddr_in6 {
665     pub sin6_family: ADDRESS_FAMILY,
666     pub sin6_port: USHORT,
667     pub sin6_flowinfo: c_ulong,
668     pub sin6_addr: in6_addr,
669     pub sin6_scope_id: c_ulong,
670 }
671 
672 #[repr(C)]
673 #[derive(Copy, Clone)]
674 pub struct in_addr {
675     pub s_addr: u32,
676 }
677 
678 #[repr(C)]
679 #[derive(Copy, Clone)]
680 pub struct in6_addr {
681     pub s6_addr: [u8; 16],
682 }
683 
684 #[repr(C)]
685 #[derive(Copy, Clone)]
686 #[allow(dead_code)] // we only use some variants
687 pub enum EXCEPTION_DISPOSITION {
688     ExceptionContinueExecution,
689     ExceptionContinueSearch,
690     ExceptionNestedException,
691     ExceptionCollidedUnwind,
692 }
693 
694 #[repr(C)]
695 #[derive(Copy)]
696 pub struct fd_set {
697     pub fd_count: c_uint,
698     pub fd_array: [SOCKET; FD_SETSIZE],
699 }
700 
701 impl Clone for fd_set {
clone(&self) -> fd_set702     fn clone(&self) -> fd_set {
703         *self
704     }
705 }
706 
707 #[repr(C)]
708 #[derive(Copy, Clone)]
709 pub struct timeval {
710     pub tv_sec: c_long,
711     pub tv_usec: c_long,
712 }
713 
714 // Desktop specific functions & types
715 cfg_if::cfg_if! {
716 if #[cfg(not(target_vendor = "uwp"))] {
717     pub const EXCEPTION_CONTINUE_SEARCH: LONG = 0;
718     pub const EXCEPTION_STACK_OVERFLOW: DWORD = 0xc00000fd;
719     pub const EXCEPTION_MAXIMUM_PARAMETERS: usize = 15;
720 
721     #[repr(C)]
722     pub struct EXCEPTION_RECORD {
723         pub ExceptionCode: DWORD,
724         pub ExceptionFlags: DWORD,
725         pub ExceptionRecord: *mut EXCEPTION_RECORD,
726         pub ExceptionAddress: LPVOID,
727         pub NumberParameters: DWORD,
728         pub ExceptionInformation: [LPVOID; EXCEPTION_MAXIMUM_PARAMETERS],
729     }
730 
731     pub enum CONTEXT {}
732 
733     #[repr(C)]
734     pub struct EXCEPTION_POINTERS {
735         pub ExceptionRecord: *mut EXCEPTION_RECORD,
736         pub ContextRecord: *mut CONTEXT,
737     }
738 
739     pub type PVECTORED_EXCEPTION_HANDLER =
740         extern "system" fn(ExceptionInfo: *mut EXCEPTION_POINTERS) -> LONG;
741 
742     #[repr(C)]
743     #[derive(Copy, Clone)]
744     pub struct CONSOLE_READCONSOLE_CONTROL {
745         pub nLength: ULONG,
746         pub nInitialChars: ULONG,
747         pub dwCtrlWakeupMask: ULONG,
748         pub dwControlKeyState: ULONG,
749     }
750 
751     pub type PCONSOLE_READCONSOLE_CONTROL = *mut CONSOLE_READCONSOLE_CONTROL;
752 
753     #[repr(C)]
754     pub struct BY_HANDLE_FILE_INFORMATION {
755         pub dwFileAttributes: DWORD,
756         pub ftCreationTime: FILETIME,
757         pub ftLastAccessTime: FILETIME,
758         pub ftLastWriteTime: FILETIME,
759         pub dwVolumeSerialNumber: DWORD,
760         pub nFileSizeHigh: DWORD,
761         pub nFileSizeLow: DWORD,
762         pub nNumberOfLinks: DWORD,
763         pub nFileIndexHigh: DWORD,
764         pub nFileIndexLow: DWORD,
765     }
766 
767     pub type LPBY_HANDLE_FILE_INFORMATION = *mut BY_HANDLE_FILE_INFORMATION;
768     pub type LPCVOID = *const c_void;
769 
770     pub const HANDLE_FLAG_INHERIT: DWORD = 0x00000001;
771 
772     pub const TOKEN_READ: DWORD = 0x20008;
773 
774     #[link(name = "advapi32")]
775     extern "system" {
776         // Allowed but unused by UWP
777         pub fn OpenProcessToken(
778             ProcessHandle: HANDLE,
779             DesiredAccess: DWORD,
780             TokenHandle: *mut HANDLE,
781         ) -> BOOL;
782     }
783 
784     #[link(name = "userenv")]
785     extern "system" {
786         // Allowed but unused by UWP
787         pub fn GetUserProfileDirectoryW(
788             hToken: HANDLE,
789             lpProfileDir: LPWSTR,
790             lpcchSize: *mut DWORD,
791         ) -> BOOL;
792     }
793 
794     #[link(name = "kernel32")]
795     extern "system" {
796         // Functions forbidden when targeting UWP
797         pub fn ReadConsoleW(
798             hConsoleInput: HANDLE,
799             lpBuffer: LPVOID,
800             nNumberOfCharsToRead: DWORD,
801             lpNumberOfCharsRead: LPDWORD,
802             pInputControl: PCONSOLE_READCONSOLE_CONTROL,
803         ) -> BOOL;
804 
805         pub fn WriteConsoleW(
806             hConsoleOutput: HANDLE,
807             lpBuffer: LPCVOID,
808             nNumberOfCharsToWrite: DWORD,
809             lpNumberOfCharsWritten: LPDWORD,
810             lpReserved: LPVOID,
811         ) -> BOOL;
812 
813         pub fn GetConsoleMode(hConsoleHandle: HANDLE, lpMode: LPDWORD) -> BOOL;
814         // Allowed but unused by UWP
815         pub fn GetFileInformationByHandle(
816             hFile: HANDLE,
817             lpFileInformation: LPBY_HANDLE_FILE_INFORMATION,
818         ) -> BOOL;
819         pub fn SetHandleInformation(hObject: HANDLE, dwMask: DWORD, dwFlags: DWORD) -> BOOL;
820         pub fn AddVectoredExceptionHandler(
821             FirstHandler: ULONG,
822             VectoredHandler: PVECTORED_EXCEPTION_HANDLER,
823         ) -> LPVOID;
824         pub fn CreateHardLinkW(
825             lpSymlinkFileName: LPCWSTR,
826             lpTargetFileName: LPCWSTR,
827             lpSecurityAttributes: LPSECURITY_ATTRIBUTES,
828         ) -> BOOL;
829         pub fn SetThreadStackGuarantee(_size: *mut c_ulong) -> BOOL;
830         pub fn GetWindowsDirectoryW(lpBuffer: LPWSTR, uSize: UINT) -> UINT;
831     }
832 }
833 }
834 
835 // UWP specific functions & types
836 cfg_if::cfg_if! {
837 if #[cfg(target_vendor = "uwp")] {
838     #[repr(C)]
839     pub struct FILE_STANDARD_INFO {
840         pub AllocationSize: LARGE_INTEGER,
841         pub EndOfFile: LARGE_INTEGER,
842         pub NumberOfLinks: DWORD,
843         pub DeletePending: BOOLEAN,
844         pub Directory: BOOLEAN,
845     }
846 }
847 }
848 
849 // Shared between Desktop & UWP
850 
851 #[link(name = "kernel32")]
852 extern "system" {
GetCurrentProcessId() -> DWORD853     pub fn GetCurrentProcessId() -> DWORD;
InitializeCriticalSection(CriticalSection: *mut CRITICAL_SECTION)854     pub fn InitializeCriticalSection(CriticalSection: *mut CRITICAL_SECTION);
EnterCriticalSection(CriticalSection: *mut CRITICAL_SECTION)855     pub fn EnterCriticalSection(CriticalSection: *mut CRITICAL_SECTION);
TryEnterCriticalSection(CriticalSection: *mut CRITICAL_SECTION) -> BOOL856     pub fn TryEnterCriticalSection(CriticalSection: *mut CRITICAL_SECTION) -> BOOL;
LeaveCriticalSection(CriticalSection: *mut CRITICAL_SECTION)857     pub fn LeaveCriticalSection(CriticalSection: *mut CRITICAL_SECTION);
DeleteCriticalSection(CriticalSection: *mut CRITICAL_SECTION)858     pub fn DeleteCriticalSection(CriticalSection: *mut CRITICAL_SECTION);
859 
GetSystemDirectoryW(lpBuffer: LPWSTR, uSize: UINT) -> UINT860     pub fn GetSystemDirectoryW(lpBuffer: LPWSTR, uSize: UINT) -> UINT;
RemoveDirectoryW(lpPathName: LPCWSTR) -> BOOL861     pub fn RemoveDirectoryW(lpPathName: LPCWSTR) -> BOOL;
SetFileAttributesW(lpFileName: LPCWSTR, dwFileAttributes: DWORD) -> BOOL862     pub fn SetFileAttributesW(lpFileName: LPCWSTR, dwFileAttributes: DWORD) -> BOOL;
SetLastError(dwErrCode: DWORD)863     pub fn SetLastError(dwErrCode: DWORD);
GetCommandLineW() -> LPWSTR864     pub fn GetCommandLineW() -> LPWSTR;
GetTempPathW(nBufferLength: DWORD, lpBuffer: LPCWSTR) -> DWORD865     pub fn GetTempPathW(nBufferLength: DWORD, lpBuffer: LPCWSTR) -> DWORD;
GetCurrentProcess() -> HANDLE866     pub fn GetCurrentProcess() -> HANDLE;
GetCurrentThread() -> HANDLE867     pub fn GetCurrentThread() -> HANDLE;
GetStdHandle(which: DWORD) -> HANDLE868     pub fn GetStdHandle(which: DWORD) -> HANDLE;
ExitProcess(uExitCode: c_uint) -> !869     pub fn ExitProcess(uExitCode: c_uint) -> !;
DeviceIoControl( hDevice: HANDLE, dwIoControlCode: DWORD, lpInBuffer: LPVOID, nInBufferSize: DWORD, lpOutBuffer: LPVOID, nOutBufferSize: DWORD, lpBytesReturned: LPDWORD, lpOverlapped: LPOVERLAPPED, ) -> BOOL870     pub fn DeviceIoControl(
871         hDevice: HANDLE,
872         dwIoControlCode: DWORD,
873         lpInBuffer: LPVOID,
874         nInBufferSize: DWORD,
875         lpOutBuffer: LPVOID,
876         nOutBufferSize: DWORD,
877         lpBytesReturned: LPDWORD,
878         lpOverlapped: LPOVERLAPPED,
879     ) -> BOOL;
CreateThread( lpThreadAttributes: LPSECURITY_ATTRIBUTES, dwStackSize: SIZE_T, lpStartAddress: extern "system" fn(*mut c_void) -> DWORD, lpParameter: LPVOID, dwCreationFlags: DWORD, lpThreadId: LPDWORD, ) -> HANDLE880     pub fn CreateThread(
881         lpThreadAttributes: LPSECURITY_ATTRIBUTES,
882         dwStackSize: SIZE_T,
883         lpStartAddress: extern "system" fn(*mut c_void) -> DWORD,
884         lpParameter: LPVOID,
885         dwCreationFlags: DWORD,
886         lpThreadId: LPDWORD,
887     ) -> HANDLE;
WaitForSingleObject(hHandle: HANDLE, dwMilliseconds: DWORD) -> DWORD888     pub fn WaitForSingleObject(hHandle: HANDLE, dwMilliseconds: DWORD) -> DWORD;
SwitchToThread() -> BOOL889     pub fn SwitchToThread() -> BOOL;
Sleep(dwMilliseconds: DWORD)890     pub fn Sleep(dwMilliseconds: DWORD);
GetProcessId(handle: HANDLE) -> DWORD891     pub fn GetProcessId(handle: HANDLE) -> DWORD;
CopyFileExW( lpExistingFileName: LPCWSTR, lpNewFileName: LPCWSTR, lpProgressRoutine: LPPROGRESS_ROUTINE, lpData: LPVOID, pbCancel: LPBOOL, dwCopyFlags: DWORD, ) -> BOOL892     pub fn CopyFileExW(
893         lpExistingFileName: LPCWSTR,
894         lpNewFileName: LPCWSTR,
895         lpProgressRoutine: LPPROGRESS_ROUTINE,
896         lpData: LPVOID,
897         pbCancel: LPBOOL,
898         dwCopyFlags: DWORD,
899     ) -> BOOL;
FormatMessageW( flags: DWORD, lpSrc: LPVOID, msgId: DWORD, langId: DWORD, buf: LPWSTR, nsize: DWORD, args: *const c_void, ) -> DWORD900     pub fn FormatMessageW(
901         flags: DWORD,
902         lpSrc: LPVOID,
903         msgId: DWORD,
904         langId: DWORD,
905         buf: LPWSTR,
906         nsize: DWORD,
907         args: *const c_void,
908     ) -> DWORD;
TlsAlloc() -> DWORD909     pub fn TlsAlloc() -> DWORD;
TlsGetValue(dwTlsIndex: DWORD) -> LPVOID910     pub fn TlsGetValue(dwTlsIndex: DWORD) -> LPVOID;
TlsSetValue(dwTlsIndex: DWORD, lpTlsvalue: LPVOID) -> BOOL911     pub fn TlsSetValue(dwTlsIndex: DWORD, lpTlsvalue: LPVOID) -> BOOL;
GetLastError() -> DWORD912     pub fn GetLastError() -> DWORD;
QueryPerformanceFrequency(lpFrequency: *mut LARGE_INTEGER) -> BOOL913     pub fn QueryPerformanceFrequency(lpFrequency: *mut LARGE_INTEGER) -> BOOL;
QueryPerformanceCounter(lpPerformanceCount: *mut LARGE_INTEGER) -> BOOL914     pub fn QueryPerformanceCounter(lpPerformanceCount: *mut LARGE_INTEGER) -> BOOL;
GetExitCodeProcess(hProcess: HANDLE, lpExitCode: LPDWORD) -> BOOL915     pub fn GetExitCodeProcess(hProcess: HANDLE, lpExitCode: LPDWORD) -> BOOL;
TerminateProcess(hProcess: HANDLE, uExitCode: UINT) -> BOOL916     pub fn TerminateProcess(hProcess: HANDLE, uExitCode: UINT) -> BOOL;
CreateProcessW( lpApplicationName: LPCWSTR, lpCommandLine: LPWSTR, lpProcessAttributes: LPSECURITY_ATTRIBUTES, lpThreadAttributes: LPSECURITY_ATTRIBUTES, bInheritHandles: BOOL, dwCreationFlags: DWORD, lpEnvironment: LPVOID, lpCurrentDirectory: LPCWSTR, lpStartupInfo: LPSTARTUPINFO, lpProcessInformation: LPPROCESS_INFORMATION, ) -> BOOL917     pub fn CreateProcessW(
918         lpApplicationName: LPCWSTR,
919         lpCommandLine: LPWSTR,
920         lpProcessAttributes: LPSECURITY_ATTRIBUTES,
921         lpThreadAttributes: LPSECURITY_ATTRIBUTES,
922         bInheritHandles: BOOL,
923         dwCreationFlags: DWORD,
924         lpEnvironment: LPVOID,
925         lpCurrentDirectory: LPCWSTR,
926         lpStartupInfo: LPSTARTUPINFO,
927         lpProcessInformation: LPPROCESS_INFORMATION,
928     ) -> BOOL;
GetEnvironmentVariableW(n: LPCWSTR, v: LPWSTR, nsize: DWORD) -> DWORD929     pub fn GetEnvironmentVariableW(n: LPCWSTR, v: LPWSTR, nsize: DWORD) -> DWORD;
SetEnvironmentVariableW(n: LPCWSTR, v: LPCWSTR) -> BOOL930     pub fn SetEnvironmentVariableW(n: LPCWSTR, v: LPCWSTR) -> BOOL;
GetEnvironmentStringsW() -> LPWCH931     pub fn GetEnvironmentStringsW() -> LPWCH;
FreeEnvironmentStringsW(env_ptr: LPWCH) -> BOOL932     pub fn FreeEnvironmentStringsW(env_ptr: LPWCH) -> BOOL;
GetModuleFileNameW(hModule: HMODULE, lpFilename: LPWSTR, nSize: DWORD) -> DWORD933     pub fn GetModuleFileNameW(hModule: HMODULE, lpFilename: LPWSTR, nSize: DWORD) -> DWORD;
CreateDirectoryW( lpPathName: LPCWSTR, lpSecurityAttributes: LPSECURITY_ATTRIBUTES, ) -> BOOL934     pub fn CreateDirectoryW(
935         lpPathName: LPCWSTR,
936         lpSecurityAttributes: LPSECURITY_ATTRIBUTES,
937     ) -> BOOL;
DeleteFileW(lpPathName: LPCWSTR) -> BOOL938     pub fn DeleteFileW(lpPathName: LPCWSTR) -> BOOL;
GetCurrentDirectoryW(nBufferLength: DWORD, lpBuffer: LPWSTR) -> DWORD939     pub fn GetCurrentDirectoryW(nBufferLength: DWORD, lpBuffer: LPWSTR) -> DWORD;
SetCurrentDirectoryW(lpPathName: LPCWSTR) -> BOOL940     pub fn SetCurrentDirectoryW(lpPathName: LPCWSTR) -> BOOL;
DuplicateHandle( hSourceProcessHandle: HANDLE, hSourceHandle: HANDLE, hTargetProcessHandle: HANDLE, lpTargetHandle: LPHANDLE, dwDesiredAccess: DWORD, bInheritHandle: BOOL, dwOptions: DWORD, ) -> BOOL941     pub fn DuplicateHandle(
942         hSourceProcessHandle: HANDLE,
943         hSourceHandle: HANDLE,
944         hTargetProcessHandle: HANDLE,
945         lpTargetHandle: LPHANDLE,
946         dwDesiredAccess: DWORD,
947         bInheritHandle: BOOL,
948         dwOptions: DWORD,
949     ) -> BOOL;
ReadFile( hFile: HANDLE, lpBuffer: LPVOID, nNumberOfBytesToRead: DWORD, lpNumberOfBytesRead: LPDWORD, lpOverlapped: LPOVERLAPPED, ) -> BOOL950     pub fn ReadFile(
951         hFile: HANDLE,
952         lpBuffer: LPVOID,
953         nNumberOfBytesToRead: DWORD,
954         lpNumberOfBytesRead: LPDWORD,
955         lpOverlapped: LPOVERLAPPED,
956     ) -> BOOL;
WriteFile( hFile: HANDLE, lpBuffer: LPVOID, nNumberOfBytesToWrite: DWORD, lpNumberOfBytesWritten: LPDWORD, lpOverlapped: LPOVERLAPPED, ) -> BOOL957     pub fn WriteFile(
958         hFile: HANDLE,
959         lpBuffer: LPVOID,
960         nNumberOfBytesToWrite: DWORD,
961         lpNumberOfBytesWritten: LPDWORD,
962         lpOverlapped: LPOVERLAPPED,
963     ) -> BOOL;
CloseHandle(hObject: HANDLE) -> BOOL964     pub fn CloseHandle(hObject: HANDLE) -> BOOL;
MoveFileExW(lpExistingFileName: LPCWSTR, lpNewFileName: LPCWSTR, dwFlags: DWORD) -> BOOL965     pub fn MoveFileExW(lpExistingFileName: LPCWSTR, lpNewFileName: LPCWSTR, dwFlags: DWORD)
966     -> BOOL;
SetFilePointerEx( hFile: HANDLE, liDistanceToMove: LARGE_INTEGER, lpNewFilePointer: PLARGE_INTEGER, dwMoveMethod: DWORD, ) -> BOOL967     pub fn SetFilePointerEx(
968         hFile: HANDLE,
969         liDistanceToMove: LARGE_INTEGER,
970         lpNewFilePointer: PLARGE_INTEGER,
971         dwMoveMethod: DWORD,
972     ) -> BOOL;
FlushFileBuffers(hFile: HANDLE) -> BOOL973     pub fn FlushFileBuffers(hFile: HANDLE) -> BOOL;
CreateFileW( lpFileName: LPCWSTR, dwDesiredAccess: DWORD, dwShareMode: DWORD, lpSecurityAttributes: LPSECURITY_ATTRIBUTES, dwCreationDisposition: DWORD, dwFlagsAndAttributes: DWORD, hTemplateFile: HANDLE, ) -> HANDLE974     pub fn CreateFileW(
975         lpFileName: LPCWSTR,
976         dwDesiredAccess: DWORD,
977         dwShareMode: DWORD,
978         lpSecurityAttributes: LPSECURITY_ATTRIBUTES,
979         dwCreationDisposition: DWORD,
980         dwFlagsAndAttributes: DWORD,
981         hTemplateFile: HANDLE,
982     ) -> HANDLE;
983 
FindFirstFileW(fileName: LPCWSTR, findFileData: LPWIN32_FIND_DATAW) -> HANDLE984     pub fn FindFirstFileW(fileName: LPCWSTR, findFileData: LPWIN32_FIND_DATAW) -> HANDLE;
FindNextFileW(findFile: HANDLE, findFileData: LPWIN32_FIND_DATAW) -> BOOL985     pub fn FindNextFileW(findFile: HANDLE, findFileData: LPWIN32_FIND_DATAW) -> BOOL;
FindClose(findFile: HANDLE) -> BOOL986     pub fn FindClose(findFile: HANDLE) -> BOOL;
987 
GetProcAddress(handle: HMODULE, name: LPCSTR) -> *mut c_void988     pub fn GetProcAddress(handle: HMODULE, name: LPCSTR) -> *mut c_void;
GetModuleHandleA(lpModuleName: LPCSTR) -> HMODULE989     pub fn GetModuleHandleA(lpModuleName: LPCSTR) -> HMODULE;
GetModuleHandleW(lpModuleName: LPCWSTR) -> HMODULE990     pub fn GetModuleHandleW(lpModuleName: LPCWSTR) -> HMODULE;
991 
GetSystemTimeAsFileTime(lpSystemTimeAsFileTime: LPFILETIME)992     pub fn GetSystemTimeAsFileTime(lpSystemTimeAsFileTime: LPFILETIME);
GetSystemInfo(lpSystemInfo: LPSYSTEM_INFO)993     pub fn GetSystemInfo(lpSystemInfo: LPSYSTEM_INFO);
994 
CreateEventW( lpEventAttributes: LPSECURITY_ATTRIBUTES, bManualReset: BOOL, bInitialState: BOOL, lpName: LPCWSTR, ) -> HANDLE995     pub fn CreateEventW(
996         lpEventAttributes: LPSECURITY_ATTRIBUTES,
997         bManualReset: BOOL,
998         bInitialState: BOOL,
999         lpName: LPCWSTR,
1000     ) -> HANDLE;
WaitForMultipleObjects( nCount: DWORD, lpHandles: *const HANDLE, bWaitAll: BOOL, dwMilliseconds: DWORD, ) -> DWORD1001     pub fn WaitForMultipleObjects(
1002         nCount: DWORD,
1003         lpHandles: *const HANDLE,
1004         bWaitAll: BOOL,
1005         dwMilliseconds: DWORD,
1006     ) -> DWORD;
CreateNamedPipeW( lpName: LPCWSTR, dwOpenMode: DWORD, dwPipeMode: DWORD, nMaxInstances: DWORD, nOutBufferSize: DWORD, nInBufferSize: DWORD, nDefaultTimeOut: DWORD, lpSecurityAttributes: LPSECURITY_ATTRIBUTES, ) -> HANDLE1007     pub fn CreateNamedPipeW(
1008         lpName: LPCWSTR,
1009         dwOpenMode: DWORD,
1010         dwPipeMode: DWORD,
1011         nMaxInstances: DWORD,
1012         nOutBufferSize: DWORD,
1013         nInBufferSize: DWORD,
1014         nDefaultTimeOut: DWORD,
1015         lpSecurityAttributes: LPSECURITY_ATTRIBUTES,
1016     ) -> HANDLE;
CancelIo(handle: HANDLE) -> BOOL1017     pub fn CancelIo(handle: HANDLE) -> BOOL;
GetOverlappedResult( hFile: HANDLE, lpOverlapped: LPOVERLAPPED, lpNumberOfBytesTransferred: LPDWORD, bWait: BOOL, ) -> BOOL1018     pub fn GetOverlappedResult(
1019         hFile: HANDLE,
1020         lpOverlapped: LPOVERLAPPED,
1021         lpNumberOfBytesTransferred: LPDWORD,
1022         bWait: BOOL,
1023     ) -> BOOL;
CreateSymbolicLinkW( lpSymlinkFileName: LPCWSTR, lpTargetFileName: LPCWSTR, dwFlags: DWORD, ) -> BOOLEAN1024     pub fn CreateSymbolicLinkW(
1025         lpSymlinkFileName: LPCWSTR,
1026         lpTargetFileName: LPCWSTR,
1027         dwFlags: DWORD,
1028     ) -> BOOLEAN;
GetFinalPathNameByHandleW( hFile: HANDLE, lpszFilePath: LPCWSTR, cchFilePath: DWORD, dwFlags: DWORD, ) -> DWORD1029     pub fn GetFinalPathNameByHandleW(
1030         hFile: HANDLE,
1031         lpszFilePath: LPCWSTR,
1032         cchFilePath: DWORD,
1033         dwFlags: DWORD,
1034     ) -> DWORD;
GetFileInformationByHandleEx( hFile: HANDLE, fileInfoClass: FILE_INFO_BY_HANDLE_CLASS, lpFileInformation: LPVOID, dwBufferSize: DWORD, ) -> BOOL1035     pub fn GetFileInformationByHandleEx(
1036         hFile: HANDLE,
1037         fileInfoClass: FILE_INFO_BY_HANDLE_CLASS,
1038         lpFileInformation: LPVOID,
1039         dwBufferSize: DWORD,
1040     ) -> BOOL;
SetFileInformationByHandle( hFile: HANDLE, FileInformationClass: FILE_INFO_BY_HANDLE_CLASS, lpFileInformation: LPVOID, dwBufferSize: DWORD, ) -> BOOL1041     pub fn SetFileInformationByHandle(
1042         hFile: HANDLE,
1043         FileInformationClass: FILE_INFO_BY_HANDLE_CLASS,
1044         lpFileInformation: LPVOID,
1045         dwBufferSize: DWORD,
1046     ) -> BOOL;
SleepConditionVariableSRW( ConditionVariable: PCONDITION_VARIABLE, SRWLock: PSRWLOCK, dwMilliseconds: DWORD, Flags: ULONG, ) -> BOOL1047     pub fn SleepConditionVariableSRW(
1048         ConditionVariable: PCONDITION_VARIABLE,
1049         SRWLock: PSRWLOCK,
1050         dwMilliseconds: DWORD,
1051         Flags: ULONG,
1052     ) -> BOOL;
1053 
WakeConditionVariable(ConditionVariable: PCONDITION_VARIABLE)1054     pub fn WakeConditionVariable(ConditionVariable: PCONDITION_VARIABLE);
WakeAllConditionVariable(ConditionVariable: PCONDITION_VARIABLE)1055     pub fn WakeAllConditionVariable(ConditionVariable: PCONDITION_VARIABLE);
1056 
AcquireSRWLockExclusive(SRWLock: PSRWLOCK)1057     pub fn AcquireSRWLockExclusive(SRWLock: PSRWLOCK);
AcquireSRWLockShared(SRWLock: PSRWLOCK)1058     pub fn AcquireSRWLockShared(SRWLock: PSRWLOCK);
ReleaseSRWLockExclusive(SRWLock: PSRWLOCK)1059     pub fn ReleaseSRWLockExclusive(SRWLock: PSRWLOCK);
ReleaseSRWLockShared(SRWLock: PSRWLOCK)1060     pub fn ReleaseSRWLockShared(SRWLock: PSRWLOCK);
TryAcquireSRWLockExclusive(SRWLock: PSRWLOCK) -> BOOLEAN1061     pub fn TryAcquireSRWLockExclusive(SRWLock: PSRWLOCK) -> BOOLEAN;
TryAcquireSRWLockShared(SRWLock: PSRWLOCK) -> BOOLEAN1062     pub fn TryAcquireSRWLockShared(SRWLock: PSRWLOCK) -> BOOLEAN;
1063 
CompareStringOrdinal( lpString1: LPCWSTR, cchCount1: c_int, lpString2: LPCWSTR, cchCount2: c_int, bIgnoreCase: BOOL, ) -> c_int1064     pub fn CompareStringOrdinal(
1065         lpString1: LPCWSTR,
1066         cchCount1: c_int,
1067         lpString2: LPCWSTR,
1068         cchCount2: c_int,
1069         bIgnoreCase: BOOL,
1070     ) -> c_int;
GetFullPathNameW( lpFileName: LPCWSTR, nBufferLength: DWORD, lpBuffer: LPWSTR, lpFilePart: *mut LPWSTR, ) -> DWORD1071     pub fn GetFullPathNameW(
1072         lpFileName: LPCWSTR,
1073         nBufferLength: DWORD,
1074         lpBuffer: LPWSTR,
1075         lpFilePart: *mut LPWSTR,
1076     ) -> DWORD;
1077 }
1078 
1079 #[link(name = "ws2_32")]
1080 extern "system" {
WSAStartup(wVersionRequested: WORD, lpWSAData: LPWSADATA) -> c_int1081     pub fn WSAStartup(wVersionRequested: WORD, lpWSAData: LPWSADATA) -> c_int;
WSACleanup() -> c_int1082     pub fn WSACleanup() -> c_int;
WSAGetLastError() -> c_int1083     pub fn WSAGetLastError() -> c_int;
WSADuplicateSocketW( s: SOCKET, dwProcessId: DWORD, lpProtocolInfo: LPWSAPROTOCOL_INFO, ) -> c_int1084     pub fn WSADuplicateSocketW(
1085         s: SOCKET,
1086         dwProcessId: DWORD,
1087         lpProtocolInfo: LPWSAPROTOCOL_INFO,
1088     ) -> c_int;
WSASend( s: SOCKET, lpBuffers: LPWSABUF, dwBufferCount: DWORD, lpNumberOfBytesSent: LPDWORD, dwFlags: DWORD, lpOverlapped: LPWSAOVERLAPPED, lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE, ) -> c_int1089     pub fn WSASend(
1090         s: SOCKET,
1091         lpBuffers: LPWSABUF,
1092         dwBufferCount: DWORD,
1093         lpNumberOfBytesSent: LPDWORD,
1094         dwFlags: DWORD,
1095         lpOverlapped: LPWSAOVERLAPPED,
1096         lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE,
1097     ) -> c_int;
WSARecv( s: SOCKET, lpBuffers: LPWSABUF, dwBufferCount: DWORD, lpNumberOfBytesRecvd: LPDWORD, lpFlags: LPDWORD, lpOverlapped: LPWSAOVERLAPPED, lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE, ) -> c_int1098     pub fn WSARecv(
1099         s: SOCKET,
1100         lpBuffers: LPWSABUF,
1101         dwBufferCount: DWORD,
1102         lpNumberOfBytesRecvd: LPDWORD,
1103         lpFlags: LPDWORD,
1104         lpOverlapped: LPWSAOVERLAPPED,
1105         lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE,
1106     ) -> c_int;
WSASocketW( af: c_int, kind: c_int, protocol: c_int, lpProtocolInfo: LPWSAPROTOCOL_INFO, g: GROUP, dwFlags: DWORD, ) -> SOCKET1107     pub fn WSASocketW(
1108         af: c_int,
1109         kind: c_int,
1110         protocol: c_int,
1111         lpProtocolInfo: LPWSAPROTOCOL_INFO,
1112         g: GROUP,
1113         dwFlags: DWORD,
1114     ) -> SOCKET;
ioctlsocket(s: SOCKET, cmd: c_long, argp: *mut c_ulong) -> c_int1115     pub fn ioctlsocket(s: SOCKET, cmd: c_long, argp: *mut c_ulong) -> c_int;
closesocket(socket: SOCKET) -> c_int1116     pub fn closesocket(socket: SOCKET) -> c_int;
recv(socket: SOCKET, buf: *mut c_void, len: c_int, flags: c_int) -> c_int1117     pub fn recv(socket: SOCKET, buf: *mut c_void, len: c_int, flags: c_int) -> c_int;
send(socket: SOCKET, buf: *const c_void, len: c_int, flags: c_int) -> c_int1118     pub fn send(socket: SOCKET, buf: *const c_void, len: c_int, flags: c_int) -> c_int;
recvfrom( socket: SOCKET, buf: *mut c_void, len: c_int, flags: c_int, addr: *mut SOCKADDR, addrlen: *mut c_int, ) -> c_int1119     pub fn recvfrom(
1120         socket: SOCKET,
1121         buf: *mut c_void,
1122         len: c_int,
1123         flags: c_int,
1124         addr: *mut SOCKADDR,
1125         addrlen: *mut c_int,
1126     ) -> c_int;
sendto( socket: SOCKET, buf: *const c_void, len: c_int, flags: c_int, addr: *const SOCKADDR, addrlen: c_int, ) -> c_int1127     pub fn sendto(
1128         socket: SOCKET,
1129         buf: *const c_void,
1130         len: c_int,
1131         flags: c_int,
1132         addr: *const SOCKADDR,
1133         addrlen: c_int,
1134     ) -> c_int;
shutdown(socket: SOCKET, how: c_int) -> c_int1135     pub fn shutdown(socket: SOCKET, how: c_int) -> c_int;
accept(socket: SOCKET, address: *mut SOCKADDR, address_len: *mut c_int) -> SOCKET1136     pub fn accept(socket: SOCKET, address: *mut SOCKADDR, address_len: *mut c_int) -> SOCKET;
getsockopt( s: SOCKET, level: c_int, optname: c_int, optval: *mut c_char, optlen: *mut c_int, ) -> c_int1137     pub fn getsockopt(
1138         s: SOCKET,
1139         level: c_int,
1140         optname: c_int,
1141         optval: *mut c_char,
1142         optlen: *mut c_int,
1143     ) -> c_int;
setsockopt( s: SOCKET, level: c_int, optname: c_int, optval: *const c_void, optlen: c_int, ) -> c_int1144     pub fn setsockopt(
1145         s: SOCKET,
1146         level: c_int,
1147         optname: c_int,
1148         optval: *const c_void,
1149         optlen: c_int,
1150     ) -> c_int;
getsockname(socket: SOCKET, address: *mut SOCKADDR, address_len: *mut c_int) -> c_int1151     pub fn getsockname(socket: SOCKET, address: *mut SOCKADDR, address_len: *mut c_int) -> c_int;
getpeername(socket: SOCKET, address: *mut SOCKADDR, address_len: *mut c_int) -> c_int1152     pub fn getpeername(socket: SOCKET, address: *mut SOCKADDR, address_len: *mut c_int) -> c_int;
bind(socket: SOCKET, address: *const SOCKADDR, address_len: socklen_t) -> c_int1153     pub fn bind(socket: SOCKET, address: *const SOCKADDR, address_len: socklen_t) -> c_int;
listen(socket: SOCKET, backlog: c_int) -> c_int1154     pub fn listen(socket: SOCKET, backlog: c_int) -> c_int;
connect(socket: SOCKET, address: *const SOCKADDR, len: c_int) -> c_int1155     pub fn connect(socket: SOCKET, address: *const SOCKADDR, len: c_int) -> c_int;
getaddrinfo( node: *const c_char, service: *const c_char, hints: *const ADDRINFOA, res: *mut *mut ADDRINFOA, ) -> c_int1156     pub fn getaddrinfo(
1157         node: *const c_char,
1158         service: *const c_char,
1159         hints: *const ADDRINFOA,
1160         res: *mut *mut ADDRINFOA,
1161     ) -> c_int;
freeaddrinfo(res: *mut ADDRINFOA)1162     pub fn freeaddrinfo(res: *mut ADDRINFOA);
select( nfds: c_int, readfds: *mut fd_set, writefds: *mut fd_set, exceptfds: *mut fd_set, timeout: *const timeval, ) -> c_int1163     pub fn select(
1164         nfds: c_int,
1165         readfds: *mut fd_set,
1166         writefds: *mut fd_set,
1167         exceptfds: *mut fd_set,
1168         timeout: *const timeval,
1169     ) -> c_int;
1170 }
1171 
1172 #[link(name = "bcrypt")]
1173 extern "system" {
1174     // >= Vista / Server 2008
1175     // https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptgenrandom
BCryptGenRandom( hAlgorithm: LPVOID, pBuffer: *mut u8, cbBuffer: ULONG, dwFlags: ULONG, ) -> NTSTATUS1176     pub fn BCryptGenRandom(
1177         hAlgorithm: LPVOID,
1178         pBuffer: *mut u8,
1179         cbBuffer: ULONG,
1180         dwFlags: ULONG,
1181     ) -> NTSTATUS;
1182 }
1183 
1184 // Functions that aren't available on every version of Windows that we support,
1185 // but we still use them and just provide some form of a fallback implementation.
1186 compat_fn! {
1187     "kernel32":
1188 
1189     // >= Win10 1607
1190     // https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-setthreaddescription
1191     pub fn SetThreadDescription(hThread: HANDLE,
1192                                 lpThreadDescription: LPCWSTR) -> HRESULT {
1193         SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); E_NOTIMPL
1194     }
1195 
1196     // >= Win8 / Server 2012
1197     // https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsystemtimepreciseasfiletime
1198     pub fn GetSystemTimePreciseAsFileTime(lpSystemTimeAsFileTime: LPFILETIME)
1199                                           -> () {
1200         GetSystemTimeAsFileTime(lpSystemTimeAsFileTime)
1201     }
1202 }
1203 
1204 compat_fn! {
1205     "api-ms-win-core-synch-l1-2-0":
1206 
1207     // >= Windows 8 / Server 2012
1208     // https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-waitonaddress
1209     pub fn WaitOnAddress(
1210         Address: LPVOID,
1211         CompareAddress: LPVOID,
1212         AddressSize: SIZE_T,
1213         dwMilliseconds: DWORD
1214     ) -> BOOL {
1215         panic!("WaitOnAddress not available")
1216     }
1217     pub fn WakeByAddressSingle(Address: LPVOID) -> () {
1218         // If this api is unavailable, there cannot be anything waiting, because
1219         // WaitOnAddress would've panicked. So it's fine to do nothing here.
1220     }
1221 }
1222 
1223 compat_fn! {
1224     "ntdll":
1225     pub fn NtOpenFile(
1226         FileHandle: *mut HANDLE,
1227         DesiredAccess: ACCESS_MASK,
1228         ObjectAttributes: *const OBJECT_ATTRIBUTES,
1229         IoStatusBlock: *mut IO_STATUS_BLOCK,
1230         ShareAccess: ULONG,
1231         OpenOptions: ULONG
1232     ) -> NTSTATUS {
1233         panic!("`NtOpenFile` not available");
1234     }
1235     pub fn RtlNtStatusToDosError(
1236         Status: NTSTATUS
1237     ) -> ULONG {
1238         panic!("`RtlNtStatusToDosError` not available");
1239     }
1240     pub fn NtCreateKeyedEvent(
1241         KeyedEventHandle: LPHANDLE,
1242         DesiredAccess: ACCESS_MASK,
1243         ObjectAttributes: LPVOID,
1244         Flags: ULONG
1245     ) -> NTSTATUS {
1246         panic!("keyed events not available")
1247     }
1248     pub fn NtReleaseKeyedEvent(
1249         EventHandle: HANDLE,
1250         Key: LPVOID,
1251         Alertable: BOOLEAN,
1252         Timeout: PLARGE_INTEGER
1253     ) -> NTSTATUS {
1254         panic!("keyed events not available")
1255     }
1256     pub fn NtWaitForKeyedEvent(
1257         EventHandle: HANDLE,
1258         Key: LPVOID,
1259         Alertable: BOOLEAN,
1260         Timeout: PLARGE_INTEGER
1261     ) -> NTSTATUS {
1262         panic!("keyed events not available")
1263     }
1264 }
1265