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 
18 use libc::{c_char, c_int, c_long, c_uchar, c_ulong, c_ushort, c_void};
19 
20 pub type HANDLE = isize;
21 pub type DWORD = c_ulong;
22 pub type ULONG_PTR = usize;
23 pub type BOOL = c_int;
24 pub type ULONG = c_ulong;
25 pub type PULONG = *mut ULONG;
26 pub type UCHAR = c_uchar;
27 pub type PVOID = *mut c_void;
28 pub type ADDRESS_FAMILY = USHORT;
29 pub type CHAR = c_char;
30 pub type LPOVERLAPPED = *mut OVERLAPPED;
31 pub type LPOVERLAPPED_ENTRY = *mut OVERLAPPED_ENTRY;
32 pub type NTSTATUS = c_long;
33 pub type PWSTR = *mut u16;
34 pub type PUNICODE_STRING = *mut UNICODE_STRING;
35 pub type USHORT = c_ushort;
36 pub type WIN32_ERROR = u32;
37 pub type WSA_ERROR = i32;
38 pub type SOCKET = usize;
39 pub type FILE_SHARE_MODE = u32;
40 pub type NT_CREATE_FILE_DISPOSITION = u32;
41 pub type FILE_ACCESS_FLAGS = u32;
42 pub 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 >;
49 pub 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 
58 pub const AF_INET: ADDRESS_FAMILY = 2;
59 pub const AF_INET6: ADDRESS_FAMILY = 23;
60 
61 pub const FIONBIO: c_long = -2147195266;
62 pub const INVALID_SOCKET: SOCKET = -1 as _;
63 
64 pub const SIO_BASE_HANDLE: u32 = 1207959586;
65 pub const SIO_BSP_HANDLE: u32 = 1207959579;
66 pub const SIO_BSP_HANDLE_POLL: u32 = 1207959581;
67 pub const SIO_BSP_HANDLE_SELECT: u32 = 1207959580;
68 
69 pub const SOCKET_ERROR: i32 = -1;
70 pub const SOCK_DGRAM: u16 = 2u16;
71 
72 pub const INVALID_HANDLE_VALUE: HANDLE = -1i32 as _;
73 pub const STATUS_NOT_FOUND: NTSTATUS = -1073741275;
74 pub const STATUS_PENDING: NTSTATUS = 259;
75 pub const STATUS_SUCCESS: NTSTATUS = 0;
76 pub const STATUS_CANCELLED: NTSTATUS = -1073741536;
77 
78 pub const SOCK_STREAM: u16 = 1u16;
79 pub const SOL_SOCKET: u32 = 65535u32;
80 pub const SO_LINGER: u32 = 128u32;
81 
82 pub const FILE_OPEN: NT_CREATE_FILE_DISPOSITION = 1;
83 pub const FILE_SHARE_READ: FILE_SHARE_MODE = 1;
84 pub const FILE_SHARE_WRITE: FILE_SHARE_MODE = 2;
85 
86 pub const SYNCHRONIZE: FILE_ACCESS_FLAGS = 1048576;
87 pub const FILE_SKIP_SET_EVENT_ON_HANDLE: u32 = 2;
88 
89 pub const ERROR_INVALID_HANDLE: WIN32_ERROR = 6;
90 pub const ERROR_IO_PENDING: WIN32_ERROR = 997;
91 pub const WAIT_TIMEOUT: WIN32_ERROR = 258;
92 
93 macro_rules! impl_clone {
94     ($name: ident) => {
95         impl Clone for $name {
96             fn clone(&self) -> $name {
97                 *self
98             }
99         }
100     };
101 }
102 
103 extern "system" {
CloseHandle(hObject: HANDLE) -> BOOL104     pub fn CloseHandle(hObject: HANDLE) -> BOOL;
105 
CreateIoCompletionPort( FileHandle: HANDLE, ExistingCompletionPort: HANDLE, CompletionKey: ULONG_PTR, NumberOfConcurrentThreads: DWORD, ) -> HANDLE106     pub fn CreateIoCompletionPort(
107         FileHandle: HANDLE,
108         ExistingCompletionPort: HANDLE,
109         CompletionKey: ULONG_PTR,
110         NumberOfConcurrentThreads: DWORD,
111     ) -> HANDLE;
112 
PostQueuedCompletionStatus( CompletionPort: HANDLE, dwNumberOfBytesTransferred: DWORD, dwCompletionKey: ULONG_PTR, lpOverlapped: LPOVERLAPPED, ) -> BOOL113     pub fn PostQueuedCompletionStatus(
114         CompletionPort: HANDLE,
115         dwNumberOfBytesTransferred: DWORD,
116         dwCompletionKey: ULONG_PTR,
117         lpOverlapped: LPOVERLAPPED,
118     ) -> BOOL;
119 
GetQueuedCompletionStatusEx( CompletionPort: HANDLE, lpCompletionPortEntries: LPOVERLAPPED_ENTRY, ulCount: ULONG, ulNumEntriesRemoved: PULONG, dwMilliseconds: DWORD, fAlertable: BOOL, ) -> BOOL120     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 
RtlNtStatusToDosError(status: NTSTATUS) -> u32129     pub fn RtlNtStatusToDosError(status: NTSTATUS) -> u32;
130 
NtCreateFile( FileHandle: *mut HANDLE, DesiredAccess: ULONG, ObjectAttributes: *mut OBJECT_ATTRIBUTES, IoStatusBlock: *mut IO_STATUS_BLOCK, AllocationSize: *mut i64, FileAttributes: ULONG, ShareAccess: FILE_SHARE_MODE, CreateDisposition: NT_CREATE_FILE_DISPOSITION, CreateOptions: ULONG, EaBuffer: PVOID, EaLength: ULONG, ) -> NTSTATUS131     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 
NtDeviceIoControlFile( FileHandle: HANDLE, Event: HANDLE, ApcRoutine: PIO_APC_ROUTINE, ApcContext: PVOID, IoStatusBlock: *mut IO_STATUS_BLOCK, IoControlCode: ULONG, InputBuffer: PVOID, InputBufferLength: ULONG, OutputBuffer: PVOID, OutputBufferLength: ULONG, ) -> NTSTATUS145     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 
SetFileCompletionNotificationModes(FileHandle: HANDLE, Flags: UCHAR) -> BOOL158     pub fn SetFileCompletionNotificationModes(FileHandle: HANDLE, Flags: UCHAR) -> BOOL;
159 
WSAGetLastError() -> WSA_ERROR160     pub fn WSAGetLastError() -> WSA_ERROR;
161 
WSAIoctl( s: SOCKET, dwIoControlCode: u32, lpvInBuffer: *const c_void, cbInBuffer: u32, lpvOutBuffer: *mut c_void, cbOutBuffer: u32, lpcbBytesReturned: *mut u32, lpOverlapped: *mut OVERLAPPED, lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE, ) -> c_int162     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 
bind(s: SOCKET, name: *const SOCKADDR, namelen: c_int) -> c_int174     pub fn bind(s: SOCKET, name: *const SOCKADDR, namelen: c_int) -> c_int;
175 
closesocket(s: SOCKET) -> c_int176     pub fn closesocket(s: SOCKET) -> c_int;
177 
ioctlsocket(s: SOCKET, cmd: c_long, argp: *mut c_ulong) -> c_int178     pub fn ioctlsocket(s: SOCKET, cmd: c_long, argp: *mut c_ulong) -> c_int;
179 
socket(af: c_int, _type: c_int, protocol: c_int) -> SOCKET180     pub fn socket(af: c_int, _type: c_int, protocol: c_int) -> SOCKET;
181 
setsockopt( s: SOCKET, level: c_int, optname: c_int, optval: *const c_char, optlen: c_int, ) -> c_int182     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 
listen(s: SOCKET, backlog: c_int) -> c_int190     pub fn listen(s: SOCKET, backlog: c_int) -> c_int;
191 
connect(s: SOCKET, name: *const SOCKADDR, namelen: c_int) -> c_int192     pub fn connect(s: SOCKET, name: *const SOCKADDR, namelen: c_int) -> c_int;
193 }
194 
195 #[repr(C)]
196 #[derive(Copy)]
197 pub 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)]
206 pub union OVERLAPPED_0 {
207     pub Anonymous: OVERLAPPED_0_0,
208     pub Pointer: *mut c_void,
209 }
210 
211 #[repr(C)]
212 #[derive(Copy)]
213 pub struct OVERLAPPED_0_0 {
214     pub Offset: u32,
215     pub OffsetHigh: u32,
216 }
217 
218 #[repr(C)]
219 #[derive(Copy)]
220 pub 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)]
229 pub struct UNICODE_STRING {
230     pub Length: USHORT,
231     pub MaximumLength: USHORT,
232     pub Buffer: PWSTR,
233 }
234 
235 #[repr(C)]
236 #[derive(Copy)]
237 pub 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)]
248 pub struct IO_STATUS_BLOCK {
249     pub Anonymous: IO_STATUS_BLOCK_0,
250     pub Information: usize,
251 }
252 
253 #[repr(C)]
254 #[derive(Copy)]
255 pub union IO_STATUS_BLOCK_0 {
256     pub Status: NTSTATUS,
257     pub Pointer: *mut c_void,
258 }
259 
260 #[repr(C)]
261 #[derive(Copy)]
262 pub struct SOCKADDR {
263     sa_family: ADDRESS_FAMILY,
264     sa_data: [CHAR; 14],
265 }
266 
267 #[repr(C)]
268 #[derive(Copy)]
269 pub struct IN6_ADDR {
270     pub u: IN6_ADDR_0,
271 }
272 
273 #[repr(C)]
274 #[derive(Copy)]
275 pub union IN6_ADDR_0 {
276     pub Byte: [u8; 16],
277     pub Word: [u16; 8],
278 }
279 
280 #[repr(C)]
281 #[derive(Copy)]
282 pub struct IN_ADDR {
283     pub S_un: IN_ADDR_0,
284 }
285 
286 #[repr(C)]
287 #[derive(Copy)]
288 pub 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)]
296 pub 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)]
305 pub struct IN_ADDR_0_1 {
306     pub s_w1: u16,
307     pub s_w2: u16,
308 }
309 
310 #[repr(C)]
311 #[derive(Copy)]
312 pub 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)]
321 pub 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)]
331 pub 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)]
338 pub struct SCOPE_ID {
339     pub Anonymous: SCOPE_ID_0,
340 }
341 
342 #[repr(C)]
343 #[derive(Copy)]
344 pub union SCOPE_ID_0 {
345     pub Anonymous: SCOPE_ID_0_0,
346     pub Value: u32,
347 }
348 
349 #[repr(C)]
350 #[derive(Copy)]
351 pub struct SCOPE_ID_0_0 {
352     pub _bitfield: u32,
353 }
354 
355 #[repr(C)]
356 #[derive(Copy)]
357 pub struct LINGER {
358     pub l_onoff: u16,
359     pub l_linger: u16,
360 }
361 
362 impl_clone!(OVERLAPPED);
363 impl_clone!(OVERLAPPED_0);
364 impl_clone!(OVERLAPPED_0_0);
365 impl_clone!(OVERLAPPED_ENTRY);
366 impl_clone!(UNICODE_STRING);
367 impl_clone!(OBJECT_ATTRIBUTES);
368 impl_clone!(IO_STATUS_BLOCK);
369 impl_clone!(IO_STATUS_BLOCK_0);
370 impl_clone!(SOCKADDR);
371 impl_clone!(IN6_ADDR);
372 impl_clone!(IN6_ADDR_0);
373 impl_clone!(IN_ADDR);
374 impl_clone!(IN_ADDR_0);
375 impl_clone!(IN_ADDR_0_0);
376 impl_clone!(IN_ADDR_0_1);
377 impl_clone!(SOCKADDR_IN);
378 impl_clone!(SOCKADDR_IN6);
379 impl_clone!(SOCKADDR_IN6_0);
380 impl_clone!(SCOPE_ID);
381 impl_clone!(SCOPE_ID_0);
382 impl_clone!(SCOPE_ID_0_0);
383 impl_clone!(LINGER);
384