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