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