]>
Commit | Line | Data |
---|---|---|
1a4d82fc JJ |
1 | //! C definitions used by libnative that don't belong in liblibc |
2 | ||
b7449926 | 3 | #![allow(nonstandard_style)] |
7453a54e | 4 | #![cfg_attr(test, allow(dead_code))] |
dfeec247 | 5 | #![unstable(issue = "none", feature = "windows_c")] |
4b012472 | 6 | #![allow(clippy::style)] |
1a4d82fc | 7 | |
064997fb | 8 | use crate::ffi::CStr; |
3c0e092e | 9 | use crate::mem; |
49aad941 FG |
10 | pub use crate::os::raw::c_int; |
11 | use crate::os::raw::{c_char, c_long, c_longlong, c_uint, c_ulong, c_ushort, c_void}; | |
12 | use crate::os::windows::io::{AsRawHandle, BorrowedHandle}; | |
532ac7d7 | 13 | use crate::ptr; |
5e7ed085 | 14 | use core::ffi::NonZero_c_ulong; |
532ac7d7 | 15 | |
49aad941 FG |
16 | mod windows_sys; |
17 | pub use windows_sys::*; | |
136023e0 | 18 | |
92a42be0 | 19 | pub type DWORD = c_ulong; |
17df50a5 | 20 | pub type NonZeroDWORD = NonZero_c_ulong; |
92a42be0 | 21 | pub type LARGE_INTEGER = c_longlong; |
fe692bf9 | 22 | #[cfg_attr(target_vendor = "uwp", allow(unused))] |
92a42be0 SL |
23 | pub type LONG = c_long; |
24 | pub type UINT = c_uint; | |
25 | pub type WCHAR = u16; | |
26 | pub type USHORT = c_ushort; | |
27 | pub type SIZE_T = usize; | |
28 | pub type WORD = u16; | |
29 | pub type CHAR = c_char; | |
92a42be0 | 30 | pub type ULONG = c_ulong; |
fc512014 | 31 | pub type ACCESS_MASK = DWORD; |
92a42be0 | 32 | |
9ffffee4 | 33 | pub type LPCVOID = *const c_void; |
92a42be0 SL |
34 | pub type LPHANDLE = *mut HANDLE; |
35 | pub type LPOVERLAPPED = *mut OVERLAPPED; | |
92a42be0 | 36 | pub type LPSECURITY_ATTRIBUTES = *mut SECURITY_ATTRIBUTES; |
92a42be0 SL |
37 | pub type LPVOID = *mut c_void; |
38 | pub type LPWCH = *mut WCHAR; | |
92a42be0 | 39 | pub type LPWSTR = *mut WCHAR; |
92a42be0 | 40 | |
92a42be0 SL |
41 | pub type PLARGE_INTEGER = *mut c_longlong; |
42 | pub type PSRWLOCK = *mut SRWLOCK; | |
43 | ||
92a42be0 SL |
44 | pub type socklen_t = c_int; |
45 | pub type ADDRESS_FAMILY = USHORT; | |
49aad941 FG |
46 | pub use FD_SET as fd_set; |
47 | pub use LINGER as linger; | |
48 | pub use TIMEVAL as timeval; | |
92a42be0 | 49 | |
4b012472 FG |
50 | pub const INVALID_HANDLE_VALUE: HANDLE = ::core::ptr::invalid_mut(-1i32 as _); |
51 | ||
ed00b5ec FG |
52 | // https://learn.microsoft.com/en-us/cpp/c-runtime-library/exit-success-exit-failure?view=msvc-170 |
53 | pub const EXIT_SUCCESS: u32 = 0; | |
54 | pub const EXIT_FAILURE: u32 = 1; | |
55 | ||
49aad941 FG |
56 | pub const CONDITION_VARIABLE_INIT: CONDITION_VARIABLE = CONDITION_VARIABLE { Ptr: ptr::null_mut() }; |
57 | pub const SRWLOCK_INIT: SRWLOCK = SRWLOCK { Ptr: ptr::null_mut() }; | |
58 | pub const INIT_ONCE_STATIC_INIT: INIT_ONCE = INIT_ONCE { Ptr: ptr::null_mut() }; | |
3c0e092e | 59 | |
49aad941 FG |
60 | // Some windows_sys types have different signs than the types we use. |
61 | pub const OBJ_DONT_REPARSE: u32 = windows_sys::OBJ_DONT_REPARSE as u32; | |
62 | pub const FRS_ERR_SYSVOL_POPULATE_TIMEOUT: u32 = | |
63 | windows_sys::FRS_ERR_SYSVOL_POPULATE_TIMEOUT as u32; | |
64 | pub const AF_INET: c_int = windows_sys::AF_INET as c_int; | |
65 | pub const AF_INET6: c_int = windows_sys::AF_INET6 as c_int; | |
94222f64 | 66 | |
54a0048b SL |
67 | #[repr(C)] |
68 | pub struct ip_mreq { | |
69 | pub imr_multiaddr: in_addr, | |
70 | pub imr_interface: in_addr, | |
71 | } | |
72 | ||
73 | #[repr(C)] | |
74 | pub struct ipv6_mreq { | |
75 | pub ipv6mr_multiaddr: in6_addr, | |
76 | pub ipv6mr_interface: c_uint, | |
77 | } | |
92a42be0 | 78 | |
3c0e092e XL |
79 | // Equivalent to the `NT_SUCCESS` C preprocessor macro. |
80 | // See: https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/using-ntstatus-values | |
81 | pub fn nt_success(status: NTSTATUS) -> bool { | |
82 | status >= 0 | |
83 | } | |
fc512014 | 84 | |
3c0e092e XL |
85 | impl UNICODE_STRING { |
86 | pub fn from_ref(slice: &[u16]) -> Self { | |
4b012472 | 87 | let len = mem::size_of_val(slice); |
3c0e092e XL |
88 | Self { Length: len as _, MaximumLength: len as _, Buffer: slice.as_ptr() as _ } |
89 | } | |
90 | } | |
49aad941 | 91 | |
3c0e092e XL |
92 | impl Default for OBJECT_ATTRIBUTES { |
93 | fn default() -> Self { | |
94 | Self { | |
95 | Length: mem::size_of::<Self>() as _, | |
96 | RootDirectory: ptr::null_mut(), | |
97 | ObjectName: ptr::null_mut(), | |
98 | Attributes: 0, | |
99 | SecurityDescriptor: ptr::null_mut(), | |
100 | SecurityQualityOfService: ptr::null_mut(), | |
101 | } | |
102 | } | |
103 | } | |
49aad941 | 104 | |
04454e1e | 105 | impl IO_STATUS_BLOCK { |
49aad941 FG |
106 | pub const PENDING: Self = |
107 | IO_STATUS_BLOCK { Anonymous: IO_STATUS_BLOCK_0 { Status: STATUS_PENDING }, Information: 0 }; | |
04454e1e | 108 | pub fn status(&self) -> NTSTATUS { |
49aad941 FG |
109 | // SAFETY: If `self.Anonymous.Status` was set then this is obviously safe. |
110 | // If `self.Anonymous.Pointer` was set then this is the equivalent to converting | |
04454e1e FG |
111 | // the pointer to an integer, which is also safe. |
112 | // Currently the only safe way to construct `IO_STATUS_BLOCK` outside of | |
113 | // this module is to call the `default` method, which sets the `Status`. | |
49aad941 | 114 | unsafe { self.Anonymous.Status } |
3c0e092e XL |
115 | } |
116 | } | |
117 | ||
f2b60f7d FG |
118 | /// NB: Use carefully! In general using this as a reference is likely to get the |
119 | /// provenance wrong for the `rest` field! | |
9346a6ac AL |
120 | #[repr(C)] |
121 | pub struct REPARSE_DATA_BUFFER { | |
92a42be0 SL |
122 | pub ReparseTag: c_uint, |
123 | pub ReparseDataLength: c_ushort, | |
124 | pub Reserved: c_ushort, | |
9346a6ac AL |
125 | pub rest: (), |
126 | } | |
127 | ||
f2b60f7d FG |
128 | /// NB: Use carefully! In general using this as a reference is likely to get the |
129 | /// provenance wrong for the `PathBuffer` field! | |
9346a6ac AL |
130 | #[repr(C)] |
131 | pub struct SYMBOLIC_LINK_REPARSE_BUFFER { | |
92a42be0 SL |
132 | pub SubstituteNameOffset: c_ushort, |
133 | pub SubstituteNameLength: c_ushort, | |
134 | pub PrintNameOffset: c_ushort, | |
135 | pub PrintNameLength: c_ushort, | |
136 | pub Flags: c_ulong, | |
137 | pub PathBuffer: WCHAR, | |
9346a6ac AL |
138 | } |
139 | ||
7453a54e SL |
140 | #[repr(C)] |
141 | pub struct MOUNT_POINT_REPARSE_BUFFER { | |
142 | pub SubstituteNameOffset: c_ushort, | |
143 | pub SubstituteNameLength: c_ushort, | |
144 | pub PrintNameOffset: c_ushort, | |
145 | pub PrintNameLength: c_ushort, | |
146 | pub PathBuffer: WCHAR, | |
147 | } | |
c1a9b12d SL |
148 | #[repr(C)] |
149 | pub struct REPARSE_MOUNTPOINT_DATA_BUFFER { | |
92a42be0 SL |
150 | pub ReparseTag: DWORD, |
151 | pub ReparseDataLength: DWORD, | |
152 | pub Reserved: WORD, | |
153 | pub ReparseTargetLength: WORD, | |
154 | pub ReparseTargetMaximumLength: WORD, | |
155 | pub Reserved1: WORD, | |
156 | pub ReparseTarget: WCHAR, | |
c1a9b12d SL |
157 | } |
158 | ||
92a42be0 SL |
159 | #[repr(C)] |
160 | pub struct SOCKADDR_STORAGE_LH { | |
161 | pub ss_family: ADDRESS_FAMILY, | |
162 | pub __ss_pad1: [CHAR; 6], | |
163 | pub __ss_align: i64, | |
164 | pub __ss_pad2: [CHAR; 112], | |
165 | } | |
166 | ||
92a42be0 SL |
167 | #[repr(C)] |
168 | #[derive(Copy, Clone)] | |
169 | pub struct sockaddr_in { | |
170 | pub sin_family: ADDRESS_FAMILY, | |
171 | pub sin_port: USHORT, | |
172 | pub sin_addr: in_addr, | |
173 | pub sin_zero: [CHAR; 8], | |
174 | } | |
175 | ||
176 | #[repr(C)] | |
177 | #[derive(Copy, Clone)] | |
178 | pub struct sockaddr_in6 { | |
179 | pub sin6_family: ADDRESS_FAMILY, | |
180 | pub sin6_port: USHORT, | |
181 | pub sin6_flowinfo: c_ulong, | |
182 | pub sin6_addr: in6_addr, | |
183 | pub sin6_scope_id: c_ulong, | |
184 | } | |
185 | ||
186 | #[repr(C)] | |
187 | #[derive(Copy, Clone)] | |
188 | pub struct in_addr { | |
189 | pub s_addr: u32, | |
190 | } | |
191 | ||
192 | #[repr(C)] | |
193 | #[derive(Copy, Clone)] | |
194 | pub struct in6_addr { | |
195 | pub s6_addr: [u8; 16], | |
196 | } | |
197 | ||
17df50a5 | 198 | // Desktop specific functions & types |
416331ca XL |
199 | cfg_if::cfg_if! { |
200 | if #[cfg(not(target_vendor = "uwp"))] { | |
49aad941 | 201 | pub const EXCEPTION_CONTINUE_SEARCH: i32 = 0; |
c1a9b12d | 202 | } |
c295e0f8 XL |
203 | } |
204 | ||
49aad941 FG |
205 | pub unsafe extern "system" fn WriteFileEx( |
206 | hFile: BorrowedHandle<'_>, | |
207 | lpBuffer: *mut ::core::ffi::c_void, | |
208 | nNumberOfBytesToWrite: u32, | |
209 | lpOverlapped: *mut OVERLAPPED, | |
210 | lpCompletionRoutine: LPOVERLAPPED_COMPLETION_ROUTINE, | |
211 | ) -> BOOL { | |
212 | windows_sys::WriteFileEx( | |
213 | hFile.as_raw_handle(), | |
214 | lpBuffer.cast::<u8>(), | |
215 | nNumberOfBytesToWrite, | |
216 | lpOverlapped, | |
217 | lpCompletionRoutine, | |
218 | ) | |
219 | } | |
220 | ||
221 | pub unsafe extern "system" fn ReadFileEx( | |
222 | hFile: BorrowedHandle<'_>, | |
223 | lpBuffer: *mut ::core::ffi::c_void, | |
224 | nNumberOfBytesToRead: u32, | |
225 | lpOverlapped: *mut OVERLAPPED, | |
226 | lpCompletionRoutine: LPOVERLAPPED_COMPLETION_ROUTINE, | |
227 | ) -> BOOL { | |
228 | windows_sys::ReadFileEx( | |
229 | hFile.as_raw_handle(), | |
781aab86 | 230 | lpBuffer.cast::<u8>(), |
49aad941 FG |
231 | nNumberOfBytesToRead, |
232 | lpOverlapped, | |
233 | lpCompletionRoutine, | |
234 | ) | |
235 | } | |
236 | ||
237 | // POSIX compatibility shims. | |
238 | pub unsafe fn recv(socket: SOCKET, buf: *mut c_void, len: c_int, flags: c_int) -> c_int { | |
239 | windows_sys::recv(socket, buf.cast::<u8>(), len, flags) | |
240 | } | |
241 | pub unsafe fn send(socket: SOCKET, buf: *const c_void, len: c_int, flags: c_int) -> c_int { | |
242 | windows_sys::send(socket, buf.cast::<u8>(), len, flags) | |
243 | } | |
244 | pub unsafe fn recvfrom( | |
245 | socket: SOCKET, | |
246 | buf: *mut c_void, | |
247 | len: c_int, | |
248 | flags: c_int, | |
249 | addr: *mut SOCKADDR, | |
250 | addrlen: *mut c_int, | |
251 | ) -> c_int { | |
252 | windows_sys::recvfrom(socket, buf.cast::<u8>(), len, flags, addr, addrlen) | |
253 | } | |
254 | pub unsafe fn sendto( | |
255 | socket: SOCKET, | |
256 | buf: *const c_void, | |
257 | len: c_int, | |
258 | flags: c_int, | |
259 | addr: *const SOCKADDR, | |
260 | addrlen: c_int, | |
261 | ) -> c_int { | |
262 | windows_sys::sendto(socket, buf.cast::<u8>(), len, flags, addr, addrlen) | |
263 | } | |
264 | pub unsafe fn getaddrinfo( | |
265 | node: *const c_char, | |
266 | service: *const c_char, | |
267 | hints: *const ADDRINFOA, | |
268 | res: *mut *mut ADDRINFOA, | |
269 | ) -> c_int { | |
270 | windows_sys::getaddrinfo(node.cast::<u8>(), service.cast::<u8>(), hints, res) | |
271 | } | |
272 | ||
fe692bf9 FG |
273 | cfg_if::cfg_if! { |
274 | if #[cfg(not(target_vendor = "uwp"))] { | |
49aad941 FG |
275 | pub unsafe fn NtReadFile( |
276 | filehandle: BorrowedHandle<'_>, | |
277 | event: HANDLE, | |
278 | apcroutine: PIO_APC_ROUTINE, | |
279 | apccontext: *mut c_void, | |
280 | iostatusblock: &mut IO_STATUS_BLOCK, | |
281 | buffer: *mut crate::mem::MaybeUninit<u8>, | |
282 | length: ULONG, | |
283 | byteoffset: Option<&LARGE_INTEGER>, | |
284 | key: Option<&ULONG>, | |
285 | ) -> NTSTATUS { | |
286 | windows_sys::NtReadFile( | |
287 | filehandle.as_raw_handle(), | |
288 | event, | |
289 | apcroutine, | |
290 | apccontext, | |
291 | iostatusblock, | |
292 | buffer.cast::<c_void>(), | |
293 | length, | |
294 | byteoffset.map(|o| o as *const i64).unwrap_or(ptr::null()), | |
295 | key.map(|k| k as *const u32).unwrap_or(ptr::null()), | |
296 | ) | |
297 | } | |
298 | pub unsafe fn NtWriteFile( | |
299 | filehandle: BorrowedHandle<'_>, | |
300 | event: HANDLE, | |
301 | apcroutine: PIO_APC_ROUTINE, | |
302 | apccontext: *mut c_void, | |
303 | iostatusblock: &mut IO_STATUS_BLOCK, | |
304 | buffer: *const u8, | |
305 | length: ULONG, | |
306 | byteoffset: Option<&LARGE_INTEGER>, | |
307 | key: Option<&ULONG>, | |
308 | ) -> NTSTATUS { | |
309 | windows_sys::NtWriteFile( | |
310 | filehandle.as_raw_handle(), | |
311 | event, | |
312 | apcroutine, | |
313 | apccontext, | |
314 | iostatusblock, | |
315 | buffer.cast::<c_void>(), | |
316 | length, | |
317 | byteoffset.map(|o| o as *const i64).unwrap_or(ptr::null()), | |
318 | key.map(|k| k as *const u32).unwrap_or(ptr::null()), | |
319 | ) | |
353b0b11 | 320 | } |
fe692bf9 FG |
321 | } |
322 | } | |
353b0b11 | 323 | |
ea8adc8c XL |
324 | // Functions that aren't available on every version of Windows that we support, |
325 | // but we still use them and just provide some form of a fallback implementation. | |
064997fb | 326 | compat_fn_with_fallback! { |
4b012472 | 327 | pub static KERNEL32: &CStr = c"kernel32"; |
c1a9b12d | 328 | |
5869c6ff XL |
329 | // >= Win10 1607 |
330 | // https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-setthreaddescription | |
49aad941 | 331 | pub fn SetThreadDescription(hthread: HANDLE, lpthreaddescription: PCWSTR) -> HRESULT { |
ea8adc8c XL |
332 | SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); E_NOTIMPL |
333 | } | |
5869c6ff XL |
334 | |
335 | // >= Win8 / Server 2012 | |
336 | // https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsystemtimepreciseasfiletime | |
49aad941 FG |
337 | pub fn GetSystemTimePreciseAsFileTime(lpsystemtimeasfiletime: *mut FILETIME) -> () { |
338 | GetSystemTimeAsFileTime(lpsystemtimeasfiletime) | |
ba9703b0 | 339 | } |
a2a8927a XL |
340 | |
341 | // >= Win11 / Server 2022 | |
342 | // https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettemppath2a | |
49aad941 FG |
343 | pub fn GetTempPath2W(bufferlength: u32, buffer: PWSTR) -> u32 { |
344 | GetTempPathW(bufferlength, buffer) | |
a2a8927a | 345 | } |
1a4d82fc | 346 | } |
5869c6ff | 347 | |
064997fb | 348 | compat_fn_optional! { |
f2b60f7d | 349 | crate::sys::compat::load_synch_functions(); |
fc512014 | 350 | pub fn WaitOnAddress( |
49aad941 FG |
351 | address: *const ::core::ffi::c_void, |
352 | compareaddress: *const ::core::ffi::c_void, | |
353 | addresssize: usize, | |
354 | dwmilliseconds: u32 | |
355 | ) -> BOOL; | |
356 | pub fn WakeByAddressSingle(address: *const ::core::ffi::c_void); | |
fc512014 XL |
357 | } |
358 | ||
064997fb | 359 | compat_fn_with_fallback! { |
4b012472 | 360 | pub static NTDLL: &CStr = c"ntdll"; |
064997fb | 361 | |
fc512014 XL |
362 | pub fn NtCreateKeyedEvent( |
363 | KeyedEventHandle: LPHANDLE, | |
364 | DesiredAccess: ACCESS_MASK, | |
365 | ObjectAttributes: LPVOID, | |
366 | Flags: ULONG | |
367 | ) -> NTSTATUS { | |
368 | panic!("keyed events not available") | |
369 | } | |
370 | pub fn NtReleaseKeyedEvent( | |
371 | EventHandle: HANDLE, | |
372 | Key: LPVOID, | |
373 | Alertable: BOOLEAN, | |
374 | Timeout: PLARGE_INTEGER | |
375 | ) -> NTSTATUS { | |
376 | panic!("keyed events not available") | |
377 | } | |
378 | pub fn NtWaitForKeyedEvent( | |
379 | EventHandle: HANDLE, | |
380 | Key: LPVOID, | |
381 | Alertable: BOOLEAN, | |
382 | Timeout: PLARGE_INTEGER | |
383 | ) -> NTSTATUS { | |
384 | panic!("keyed events not available") | |
385 | } | |
fe692bf9 FG |
386 | |
387 | // These functions are available on UWP when lazily loaded. They will fail WACK if loaded statically. | |
388 | #[cfg(target_vendor = "uwp")] | |
389 | pub fn NtCreateFile( | |
390 | filehandle: *mut HANDLE, | |
391 | desiredaccess: FILE_ACCESS_RIGHTS, | |
392 | objectattributes: *const OBJECT_ATTRIBUTES, | |
393 | iostatusblock: *mut IO_STATUS_BLOCK, | |
394 | allocationsize: *const i64, | |
395 | fileattributes: FILE_FLAGS_AND_ATTRIBUTES, | |
396 | shareaccess: FILE_SHARE_MODE, | |
397 | createdisposition: NTCREATEFILE_CREATE_DISPOSITION, | |
398 | createoptions: NTCREATEFILE_CREATE_OPTIONS, | |
399 | eabuffer: *const ::core::ffi::c_void, | |
400 | ealength: u32 | |
401 | ) -> NTSTATUS { | |
402 | STATUS_NOT_IMPLEMENTED | |
403 | } | |
404 | #[cfg(target_vendor = "uwp")] | |
405 | pub fn NtReadFile( | |
406 | filehandle: BorrowedHandle<'_>, | |
407 | event: HANDLE, | |
408 | apcroutine: PIO_APC_ROUTINE, | |
409 | apccontext: *mut c_void, | |
410 | iostatusblock: &mut IO_STATUS_BLOCK, | |
411 | buffer: *mut crate::mem::MaybeUninit<u8>, | |
412 | length: ULONG, | |
413 | byteoffset: Option<&LARGE_INTEGER>, | |
414 | key: Option<&ULONG> | |
415 | ) -> NTSTATUS { | |
416 | STATUS_NOT_IMPLEMENTED | |
417 | } | |
418 | #[cfg(target_vendor = "uwp")] | |
419 | pub fn NtWriteFile( | |
420 | filehandle: BorrowedHandle<'_>, | |
421 | event: HANDLE, | |
422 | apcroutine: PIO_APC_ROUTINE, | |
423 | apccontext: *mut c_void, | |
424 | iostatusblock: &mut IO_STATUS_BLOCK, | |
425 | buffer: *const u8, | |
426 | length: ULONG, | |
427 | byteoffset: Option<&LARGE_INTEGER>, | |
428 | key: Option<&ULONG> | |
429 | ) -> NTSTATUS { | |
430 | STATUS_NOT_IMPLEMENTED | |
431 | } | |
432 | #[cfg(target_vendor = "uwp")] | |
433 | pub fn RtlNtStatusToDosError(Status: NTSTATUS) -> u32 { | |
434 | Status as u32 | |
435 | } | |
436 | } | |
437 | ||
438 | // # Arm32 shim | |
439 | // | |
440 | // AddVectoredExceptionHandler and WSAStartup use platform-specific types. | |
441 | // However, Microsoft no longer supports thumbv7a so definitions for those targets | |
442 | // are not included in the win32 metadata. We work around that by defining them here. | |
443 | // | |
444 | // Where possible, these definitions should be kept in sync with https://docs.rs/windows-sys | |
445 | cfg_if::cfg_if! { | |
446 | if #[cfg(not(target_vendor = "uwp"))] { | |
447 | #[link(name = "kernel32")] | |
448 | extern "system" { | |
449 | pub fn AddVectoredExceptionHandler( | |
450 | first: u32, | |
451 | handler: PVECTORED_EXCEPTION_HANDLER, | |
452 | ) -> *mut c_void; | |
453 | } | |
454 | pub type PVECTORED_EXCEPTION_HANDLER = Option< | |
455 | unsafe extern "system" fn(exceptioninfo: *mut EXCEPTION_POINTERS) -> i32, | |
456 | >; | |
457 | #[repr(C)] | |
458 | pub struct EXCEPTION_POINTERS { | |
459 | pub ExceptionRecord: *mut EXCEPTION_RECORD, | |
460 | pub ContextRecord: *mut CONTEXT, | |
461 | } | |
462 | #[cfg(target_arch = "arm")] | |
463 | pub enum CONTEXT {} | |
464 | }} | |
465 | ||
466 | #[link(name = "ws2_32")] | |
467 | extern "system" { | |
468 | pub fn WSAStartup(wversionrequested: u16, lpwsadata: *mut WSADATA) -> i32; | |
469 | } | |
470 | #[cfg(target_arch = "arm")] | |
471 | #[repr(C)] | |
472 | pub struct WSADATA { | |
473 | pub wVersion: u16, | |
474 | pub wHighVersion: u16, | |
475 | pub szDescription: [u8; 257], | |
476 | pub szSystemStatus: [u8; 129], | |
477 | pub iMaxSockets: u16, | |
478 | pub iMaxUdpDg: u16, | |
479 | pub lpVendorInfo: PSTR, | |
fc512014 | 480 | } |