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