1b8a62b91Sopenharmony_ciuse crate::io;
2b8a62b91Sopenharmony_ciuse core::mem::MaybeUninit;
3b8a62b91Sopenharmony_ciuse windows_sys::Win32::Networking::WinSock::{WSACleanup, WSAGetLastError, WSAStartup, WSADATA};
4b8a62b91Sopenharmony_ci
5b8a62b91Sopenharmony_ci/// `WSAStartup()`—Initialize process-wide Windows support for sockets.
6b8a62b91Sopenharmony_ci///
7b8a62b91Sopenharmony_ci/// On Windows, it's necessary to initialize the sockets subsystem before
8b8a62b91Sopenharmony_ci/// using sockets APIs. The function performs the necessary initialization.
9b8a62b91Sopenharmony_ci///
10b8a62b91Sopenharmony_ci/// # References
11b8a62b91Sopenharmony_ci///  - [Winsock2]
12b8a62b91Sopenharmony_ci///
13b8a62b91Sopenharmony_ci/// [Winsock2]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsastartup
14b8a62b91Sopenharmony_cipub fn wsa_startup() -> io::Result<WSADATA> {
15b8a62b91Sopenharmony_ci    // Request version 2.2, which has been the latest version since far older
16b8a62b91Sopenharmony_ci    // versions of Windows than we support here. For more information about
17b8a62b91Sopenharmony_ci    // the version, see [here].
18b8a62b91Sopenharmony_ci    //
19b8a62b91Sopenharmony_ci    // [here]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsastartup#remarks
20b8a62b91Sopenharmony_ci    let version = 0x202;
21b8a62b91Sopenharmony_ci    let mut data = MaybeUninit::uninit();
22b8a62b91Sopenharmony_ci    unsafe {
23b8a62b91Sopenharmony_ci        let ret = WSAStartup(version, data.as_mut_ptr());
24b8a62b91Sopenharmony_ci        if ret == 0 {
25b8a62b91Sopenharmony_ci            Ok(data.assume_init())
26b8a62b91Sopenharmony_ci        } else {
27b8a62b91Sopenharmony_ci            Err(io::Errno::from_raw_os_error(WSAGetLastError()))
28b8a62b91Sopenharmony_ci        }
29b8a62b91Sopenharmony_ci    }
30b8a62b91Sopenharmony_ci}
31b8a62b91Sopenharmony_ci
32b8a62b91Sopenharmony_ci/// `WSACleanup()`—Clean up process-wide Windows support for sockets.
33b8a62b91Sopenharmony_ci///
34b8a62b91Sopenharmony_ci/// In a program where `init` is called, if sockets are no longer necessary,
35b8a62b91Sopenharmony_ci/// this function releases associated resources.
36b8a62b91Sopenharmony_ci///
37b8a62b91Sopenharmony_ci/// # References
38b8a62b91Sopenharmony_ci///  - [Winsock2]
39b8a62b91Sopenharmony_ci///
40b8a62b91Sopenharmony_ci/// [Winsock2]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsacleanup
41b8a62b91Sopenharmony_cipub fn wsa_cleanup() -> io::Result<()> {
42b8a62b91Sopenharmony_ci    unsafe {
43b8a62b91Sopenharmony_ci        if WSACleanup() == 0 {
44b8a62b91Sopenharmony_ci            Ok(())
45b8a62b91Sopenharmony_ci        } else {
46b8a62b91Sopenharmony_ci            Err(io::Errno::from_raw_os_error(WSAGetLastError()))
47b8a62b91Sopenharmony_ci        }
48b8a62b91Sopenharmony_ci    }
49b8a62b91Sopenharmony_ci}
50