| 938 | // AcceptEx |
| 939 | #[pymethod] |
| 940 | fn AcceptEx( |
| 941 | zelf: &Py<Self>, |
| 942 | listen_socket: isize, |
| 943 | accept_socket: isize, |
| 944 | vm: &VirtualMachine, |
| 945 | ) -> PyResult { |
| 946 | use windows_sys::Win32::Foundation::{ERROR_IO_PENDING, ERROR_SUCCESS}; |
| 947 | use windows_sys::Win32::Networking::WinSock::WSAGetLastError; |
| 948 | |
| 949 | let mut inner = zelf.inner.lock(); |
| 950 | if !matches!(inner.data, OverlappedData::None) { |
| 951 | return Err(vm.new_value_error("operation already attempted")); |
| 952 | } |
| 953 | |
| 954 | // Buffer size: local address + remote address |
| 955 | let size = core::mem::size_of::<SOCKADDR_IN6>() + 16; |
| 956 | let buf = vec![0u8; size * 2]; |
| 957 | let buf = vm.ctx.new_bytes(buf); |
| 958 | |
| 959 | inner.handle = listen_socket as HANDLE; |
| 960 | inner.data = OverlappedData::Accept(buf.clone()); |
| 961 | |
| 962 | let mut bytes_received: u32 = 0; |
| 963 | |
| 964 | type AcceptExFn = unsafe extern "system" fn( |
| 965 | sListenSocket: usize, |
| 966 | sAcceptSocket: usize, |
| 967 | lpOutputBuffer: *mut core::ffi::c_void, |
| 968 | dwReceiveDataLength: u32, |
| 969 | dwLocalAddressLength: u32, |
| 970 | dwRemoteAddressLength: u32, |
| 971 | lpdwBytesReceived: *mut u32, |
| 972 | lpOverlapped: *mut OVERLAPPED, |
| 973 | ) -> i32; |
| 974 | |
| 975 | let accept_ex: AcceptExFn = unsafe { core::mem::transmute(*ACCEPT_EX.get().unwrap()) }; |
| 976 | |
| 977 | let ret = unsafe { |
| 978 | accept_ex( |
| 979 | listen_socket as _, |
| 980 | accept_socket as _, |
| 981 | buf.as_bytes().as_ptr() as *mut _, |
| 982 | 0, |
| 983 | size as u32, |
| 984 | size as u32, |
| 985 | &mut bytes_received, |
| 986 | &mut inner.overlapped, |
| 987 | ) |
| 988 | }; |
| 989 | |
| 990 | let err = if ret != 0 { |
| 991 | ERROR_SUCCESS |
| 992 | } else { |
| 993 | unsafe { WSAGetLastError() as u32 } |
| 994 | }; |
| 995 | inner.error = err; |
| 996 | |
| 997 | match err { |