1// Copyright (c) 2023 Huawei Device Co., Ltd. 2// Licensed under the Apache License, Version 2.0 (the "License"); 3// you may not use this file except in compliance with the License. 4// You may obtain a copy of the License at 5// 6// http://www.apache.org/licenses/LICENSE-2.0 7// 8// Unless required by applicable law or agreed to in writing, software 9// distributed under the License is distributed on an "AS IS" BASIS, 10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11// See the License for the specific language governing permissions and 12// limitations under the License. 13 14#![allow(non_camel_case_types)] 15#![allow(non_snake_case)] 16#![allow(clippy::upper_case_acronyms)] 17 18use libc::{c_char, c_int, c_long, c_uchar, c_ulong, c_ushort, c_void}; 19 20pub type HANDLE = isize; 21pub type DWORD = c_ulong; 22pub type ULONG_PTR = usize; 23pub type BOOL = c_int; 24pub type ULONG = c_ulong; 25pub type PULONG = *mut ULONG; 26pub type UCHAR = c_uchar; 27pub type PVOID = *mut c_void; 28pub type ADDRESS_FAMILY = USHORT; 29pub type CHAR = c_char; 30pub type LPOVERLAPPED = *mut OVERLAPPED; 31pub type LPOVERLAPPED_ENTRY = *mut OVERLAPPED_ENTRY; 32pub type NTSTATUS = c_long; 33pub type PWSTR = *mut u16; 34pub type PUNICODE_STRING = *mut UNICODE_STRING; 35pub type USHORT = c_ushort; 36pub type WIN32_ERROR = u32; 37pub type WSA_ERROR = i32; 38pub type SOCKET = usize; 39pub type FILE_SHARE_MODE = u32; 40pub type NT_CREATE_FILE_DISPOSITION = u32; 41pub type FILE_ACCESS_FLAGS = u32; 42pub type PIO_APC_ROUTINE = Option< 43 unsafe extern "system" fn( 44 apcContext: *mut c_void, 45 ioStatusBlock: *mut IO_STATUS_BLOCK, 46 reserved: u32, 47 ) -> (), 48>; 49pub type LPWSAOVERLAPPED_COMPLETION_ROUTINE = Option< 50 unsafe extern "system" fn( 51 dwError: u32, 52 cbTransferred: u32, 53 lpOverlapped: *mut OVERLAPPED, 54 dwFlags: u32, 55 ) -> (), 56>; 57 58pub const AF_INET: ADDRESS_FAMILY = 2; 59pub const AF_INET6: ADDRESS_FAMILY = 23; 60 61pub const FIONBIO: c_long = -2147195266; 62pub const INVALID_SOCKET: SOCKET = -1 as _; 63 64pub const SIO_BASE_HANDLE: u32 = 1207959586; 65pub const SIO_BSP_HANDLE: u32 = 1207959579; 66pub const SIO_BSP_HANDLE_POLL: u32 = 1207959581; 67pub const SIO_BSP_HANDLE_SELECT: u32 = 1207959580; 68 69pub const SOCKET_ERROR: i32 = -1; 70pub const SOCK_DGRAM: u16 = 2u16; 71 72pub const INVALID_HANDLE_VALUE: HANDLE = -1i32 as _; 73pub const STATUS_NOT_FOUND: NTSTATUS = -1073741275; 74pub const STATUS_PENDING: NTSTATUS = 259; 75pub const STATUS_SUCCESS: NTSTATUS = 0; 76pub const STATUS_CANCELLED: NTSTATUS = -1073741536; 77 78pub const SOCK_STREAM: u16 = 1u16; 79pub const SOL_SOCKET: u32 = 65535u32; 80pub const SO_LINGER: u32 = 128u32; 81 82pub const FILE_OPEN: NT_CREATE_FILE_DISPOSITION = 1; 83pub const FILE_SHARE_READ: FILE_SHARE_MODE = 1; 84pub const FILE_SHARE_WRITE: FILE_SHARE_MODE = 2; 85 86pub const SYNCHRONIZE: FILE_ACCESS_FLAGS = 1048576; 87pub const FILE_SKIP_SET_EVENT_ON_HANDLE: u32 = 2; 88 89pub const ERROR_INVALID_HANDLE: WIN32_ERROR = 6; 90pub const ERROR_IO_PENDING: WIN32_ERROR = 997; 91pub const WAIT_TIMEOUT: WIN32_ERROR = 258; 92 93macro_rules! impl_clone { 94 ($name: ident) => { 95 impl Clone for $name { 96 fn clone(&self) -> $name { 97 *self 98 } 99 } 100 }; 101} 102 103extern "system" { 104 pub fn CloseHandle(hObject: HANDLE) -> BOOL; 105 106 pub fn CreateIoCompletionPort( 107 FileHandle: HANDLE, 108 ExistingCompletionPort: HANDLE, 109 CompletionKey: ULONG_PTR, 110 NumberOfConcurrentThreads: DWORD, 111 ) -> HANDLE; 112 113 pub fn PostQueuedCompletionStatus( 114 CompletionPort: HANDLE, 115 dwNumberOfBytesTransferred: DWORD, 116 dwCompletionKey: ULONG_PTR, 117 lpOverlapped: LPOVERLAPPED, 118 ) -> BOOL; 119 120 pub fn GetQueuedCompletionStatusEx( 121 CompletionPort: HANDLE, 122 lpCompletionPortEntries: LPOVERLAPPED_ENTRY, 123 ulCount: ULONG, 124 ulNumEntriesRemoved: PULONG, 125 dwMilliseconds: DWORD, 126 fAlertable: BOOL, 127 ) -> BOOL; 128 129 pub fn RtlNtStatusToDosError(status: NTSTATUS) -> u32; 130 131 pub fn NtCreateFile( 132 FileHandle: *mut HANDLE, 133 DesiredAccess: ULONG, 134 ObjectAttributes: *mut OBJECT_ATTRIBUTES, 135 IoStatusBlock: *mut IO_STATUS_BLOCK, 136 AllocationSize: *mut i64, 137 FileAttributes: ULONG, 138 ShareAccess: FILE_SHARE_MODE, 139 CreateDisposition: NT_CREATE_FILE_DISPOSITION, 140 CreateOptions: ULONG, 141 EaBuffer: PVOID, 142 EaLength: ULONG, 143 ) -> NTSTATUS; 144 145 pub fn NtDeviceIoControlFile( 146 FileHandle: HANDLE, 147 Event: HANDLE, 148 ApcRoutine: PIO_APC_ROUTINE, 149 ApcContext: PVOID, 150 IoStatusBlock: *mut IO_STATUS_BLOCK, 151 IoControlCode: ULONG, 152 InputBuffer: PVOID, 153 InputBufferLength: ULONG, 154 OutputBuffer: PVOID, 155 OutputBufferLength: ULONG, 156 ) -> NTSTATUS; 157 158 pub fn SetFileCompletionNotificationModes(FileHandle: HANDLE, Flags: UCHAR) -> BOOL; 159 160 pub fn WSAGetLastError() -> WSA_ERROR; 161 162 pub fn WSAIoctl( 163 s: SOCKET, 164 dwIoControlCode: u32, 165 lpvInBuffer: *const c_void, 166 cbInBuffer: u32, 167 lpvOutBuffer: *mut c_void, 168 cbOutBuffer: u32, 169 lpcbBytesReturned: *mut u32, 170 lpOverlapped: *mut OVERLAPPED, 171 lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE, 172 ) -> c_int; 173 174 pub fn bind(s: SOCKET, name: *const SOCKADDR, namelen: c_int) -> c_int; 175 176 pub fn closesocket(s: SOCKET) -> c_int; 177 178 pub fn ioctlsocket(s: SOCKET, cmd: c_long, argp: *mut c_ulong) -> c_int; 179 180 pub fn socket(af: c_int, _type: c_int, protocol: c_int) -> SOCKET; 181 182 pub fn setsockopt( 183 s: SOCKET, 184 level: c_int, 185 optname: c_int, 186 optval: *const c_char, 187 optlen: c_int, 188 ) -> c_int; 189 190 pub fn listen(s: SOCKET, backlog: c_int) -> c_int; 191 192 pub fn connect(s: SOCKET, name: *const SOCKADDR, namelen: c_int) -> c_int; 193} 194 195#[repr(C)] 196#[derive(Copy)] 197pub struct OVERLAPPED { 198 pub Internal: ULONG_PTR, 199 pub InternalHigh: ULONG_PTR, 200 pub Anonymous: OVERLAPPED_0, 201 pub hEvent: HANDLE, 202} 203 204#[repr(C)] 205#[derive(Copy)] 206pub union OVERLAPPED_0 { 207 pub Anonymous: OVERLAPPED_0_0, 208 pub Pointer: *mut c_void, 209} 210 211#[repr(C)] 212#[derive(Copy)] 213pub struct OVERLAPPED_0_0 { 214 pub Offset: u32, 215 pub OffsetHigh: u32, 216} 217 218#[repr(C)] 219#[derive(Copy)] 220pub struct OVERLAPPED_ENTRY { 221 pub lpCompletionKey: ULONG_PTR, 222 pub lpOverlapped: LPOVERLAPPED, 223 pub Internal: ULONG_PTR, 224 pub dwNumberOfBytesTransferred: DWORD, 225} 226 227#[repr(C)] 228#[derive(Copy)] 229pub struct UNICODE_STRING { 230 pub Length: USHORT, 231 pub MaximumLength: USHORT, 232 pub Buffer: PWSTR, 233} 234 235#[repr(C)] 236#[derive(Copy)] 237pub struct OBJECT_ATTRIBUTES { 238 pub Length: ULONG, 239 pub RootDirectory: HANDLE, 240 pub ObjectName: PUNICODE_STRING, 241 pub Attributes: ULONG, 242 pub SecurityDescriptor: PVOID, 243 pub SecurityQualityOfService: PVOID, 244} 245 246#[repr(C)] 247#[derive(Copy)] 248pub struct IO_STATUS_BLOCK { 249 pub Anonymous: IO_STATUS_BLOCK_0, 250 pub Information: usize, 251} 252 253#[repr(C)] 254#[derive(Copy)] 255pub union IO_STATUS_BLOCK_0 { 256 pub Status: NTSTATUS, 257 pub Pointer: *mut c_void, 258} 259 260#[repr(C)] 261#[derive(Copy)] 262pub struct SOCKADDR { 263 sa_family: ADDRESS_FAMILY, 264 sa_data: [CHAR; 14], 265} 266 267#[repr(C)] 268#[derive(Copy)] 269pub struct IN6_ADDR { 270 pub u: IN6_ADDR_0, 271} 272 273#[repr(C)] 274#[derive(Copy)] 275pub union IN6_ADDR_0 { 276 pub Byte: [u8; 16], 277 pub Word: [u16; 8], 278} 279 280#[repr(C)] 281#[derive(Copy)] 282pub struct IN_ADDR { 283 pub S_un: IN_ADDR_0, 284} 285 286#[repr(C)] 287#[derive(Copy)] 288pub union IN_ADDR_0 { 289 pub S_un_b: IN_ADDR_0_0, 290 pub S_un_w: IN_ADDR_0_1, 291 pub S_addr: u32, 292} 293 294#[repr(C)] 295#[derive(Copy)] 296pub struct IN_ADDR_0_0 { 297 pub s_b1: u8, 298 pub s_b2: u8, 299 pub s_b3: u8, 300 pub s_b4: u8, 301} 302 303#[repr(C)] 304#[derive(Copy)] 305pub struct IN_ADDR_0_1 { 306 pub s_w1: u16, 307 pub s_w2: u16, 308} 309 310#[repr(C)] 311#[derive(Copy)] 312pub struct SOCKADDR_IN { 313 pub sin_family: ADDRESS_FAMILY, 314 pub sin_port: u16, 315 pub sin_addr: IN_ADDR, 316 pub sin_zero: [CHAR; 8], 317} 318 319#[repr(C)] 320#[derive(Copy)] 321pub struct SOCKADDR_IN6 { 322 pub sin6_family: ADDRESS_FAMILY, 323 pub sin6_port: u16, 324 pub sin6_flowinfo: u32, 325 pub sin6_addr: IN6_ADDR, 326 pub Anonymous: SOCKADDR_IN6_0, 327} 328 329#[repr(C)] 330#[derive(Copy)] 331pub union SOCKADDR_IN6_0 { 332 pub sin6_scope_id: u32, 333 pub sin6_scope_struct: SCOPE_ID, 334} 335 336#[repr(C)] 337#[derive(Copy)] 338pub struct SCOPE_ID { 339 pub Anonymous: SCOPE_ID_0, 340} 341 342#[repr(C)] 343#[derive(Copy)] 344pub union SCOPE_ID_0 { 345 pub Anonymous: SCOPE_ID_0_0, 346 pub Value: u32, 347} 348 349#[repr(C)] 350#[derive(Copy)] 351pub struct SCOPE_ID_0_0 { 352 pub _bitfield: u32, 353} 354 355#[repr(C)] 356#[derive(Copy)] 357pub struct LINGER { 358 pub l_onoff: u16, 359 pub l_linger: u16, 360} 361 362impl_clone!(OVERLAPPED); 363impl_clone!(OVERLAPPED_0); 364impl_clone!(OVERLAPPED_0_0); 365impl_clone!(OVERLAPPED_ENTRY); 366impl_clone!(UNICODE_STRING); 367impl_clone!(OBJECT_ATTRIBUTES); 368impl_clone!(IO_STATUS_BLOCK); 369impl_clone!(IO_STATUS_BLOCK_0); 370impl_clone!(SOCKADDR); 371impl_clone!(IN6_ADDR); 372impl_clone!(IN6_ADDR_0); 373impl_clone!(IN_ADDR); 374impl_clone!(IN_ADDR_0); 375impl_clone!(IN_ADDR_0_0); 376impl_clone!(IN_ADDR_0_1); 377impl_clone!(SOCKADDR_IN); 378impl_clone!(SOCKADDR_IN6); 379impl_clone!(SOCKADDR_IN6_0); 380impl_clone!(SCOPE_ID); 381impl_clone!(SCOPE_ID_0); 382impl_clone!(SCOPE_ID_0_0); 383impl_clone!(LINGER); 384