def initiailize_function_ptrs(): ## importing socket ensures that WSAStartup() is called import _socket s = _winsock2.socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) dwBytes = _ffi.new("DWORD[1]", [0]) if s == INVALID_SOCKET: raise _winapi._WinError() result = _winsock2.WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, \ WSAID_ACCEPTEX, _ffi.sizeof(WSAID_ACCEPTEX[0]), _accept_ex, \ _ffi.sizeof(_accept_ex[0]), dwBytes, _ffi.NULL, _ffi.NULL) if result == INVALID_SOCKET: _winsock2.closesocket(s) raise _winapi._WinError() result = _winsock2.WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, \ WSAID_CONNECTEX, _ffi.sizeof(WSAID_CONNECTEX[0]), _connect_ex, \ _ffi.sizeof(_connect_ex[0]), dwBytes, _ffi.NULL, _ffi.NULL) if result == INVALID_SOCKET: _winsock2.closesocket(s) raise _winapi._WinError() result = _winsock2.WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, \ WSAID_DISCONNECTEX, _ffi.sizeof(WSAID_DISCONNECTEX[0]), _disconnect_ex, \ _ffi.sizeof(_disconnect_ex[0]), dwBytes, _ffi.NULL, _ffi.NULL) _winsock2.closesocket(s) if result == INVALID_SOCKET: raise _winapi._WinError()
def ConnectEx(self, socket, addressobj): socket = _int2handle(socket) if self.type != OverlappedType.TYPE_NONE: raise _winapi._WinError() address = _ffi.new("struct sockaddr_in6*") length = _ffi.sizeof("struct sockaddr_in6") address, length = parse_address(addressobj, _ffi.cast("SOCKADDR*", address), length) if length < 0: return None self.type = OverlappedType.TYPE_CONNECT self.handle = socket res = _connect_ex[0](socket, address, length, \ _ffi.NULL, 0, _ffi.NULL, self.overlapped) if res: self.error = _winapi.ERROR_SUCCESS else: self.error = _kernel32.GetLastError() if self.error == _winapi.ERROR_SUCCESS or self.error == _winapi.ERROR_IO_PENDING: return None else: self.type = OverlappedType.TYPE_NOT_STARTED SetFromWindowsErr(0)
def AcceptEx(self, listensocket, acceptsocket): listensocket = _int2handle(listensocket) acceptsocket = _int2handle(acceptsocket) bytesreceived = _ffi.new("DWORD[1]") if self.type != OverlappedType.TYPE_NONE: raise _winapi._WinError() size = _ffi.sizeof("struct sockaddr_in6") + 16 buf = _ffi.new("CHAR[]", size * 2) if not buf: return None self.type = OverlappedType.TYPE_ACCEPT self.handle = listensocket self.read_buffer = buf res = _accept_ex[0](listensocket, acceptsocket, buf, \ 0, size, size, bytesreceived, self.overlapped) if res: self.error = _winapi.ERROR_SUCCESS else: self.error = _kernel32.GetLastError() if self.error == _winapi.ERROR_SUCCESS or self.error == _winapi.ERROR_IO_PENDING: return None else: self.type = OverlappedType.TYPE_NOT_STARTED SetFromWindowsErr(0)
def WriteFile(self, handle, buffer): self.handle = _int2handle(handle) self.write_buffer = buffer written = _ffi.new('DWORD[1]', [0]) # Check if we have already performed some IO if self.type != OverlappedType.TYPE_NONE: raise _winapi._WinError() self.type = OverlappedType.TYPE_WRITE ret = _kernel32.WriteFile(self.handle, self.write_buffer, len(self.write_buffer), written, self.overlapped) if ret: self.error = _winapi.ERROR_SUCCESS else: self.error = _kernel32.GetLastError() if self.error == _winapi.ERROR_SUCCESS or self.error == _winapi.ERROR_IO_PENDING: return None else: self.type = OverlappedType.TYPE_NOT_STARTED SetFromWindowsErr(self.error)
def WSASend(self, handle, bufobj, flags): handle = _int2handle(handle) if self.type != OverlappedType.TYPE_NONE: raise _winapi._WinError() self.write_buffer = bufobj self.type = OverlappedType.TYPE_WRITE self.handle = handle wsabuff = _ffi.new("WSABUF[1]") wsabuff[0].len = len(bufobj) wsabuff[0].buf = _ffi.new("CHAR[]", bufobj) nwritten = _ffi.new("LPDWORD") result = _winsock2.WSASend(handle, wsabuff, _int2dword(1), nwritten, flags, self.overlapped, _ffi.NULL) if result == SOCKET_ERROR: self.error = _kernel32.GetLastError() else: self.error = _winapi.ERROR_SUCCESS if self.error in [_winapi.ERROR_SUCCESS, _winapi.ERROR_IO_PENDING]: return None else: self.type = OverlappedType.TYPE_NOT_STARTED SetFromWindowsErr(self.error)
def WSARecv(self, handle, size, flags): handle = _int2handle(handle) flags = _int2dword(flags) if self.type != OverlappedType.TYPE_NONE: raise _winapi._WinError() self.type = OverlappedType.TYPE_READ self.handle = _int2handle(handle) self.read_buffer = _ffi.new("CHAR[]", max(1, size)) return self.do_WSARecv(handle, self.read_buffer, size, flags)
def __init__(self, event=_ffi.NULL): self.overlapped = _ffi.new('OVERLAPPED[1]') self.handle = _ffi.NULL self.read_buffer = None self.write_buffer = None self.error = 0 self.type = OverlappedType.TYPE_NONE if event == _int2handle(INVALID_HANDLE_VALUE) or not event: event = _kernel32.CreateEventW(NULL, True, False, NULL) if event == _winapi.NULL: raise _winapi._WinError() if event: self.overlapped[0].hEvent = event else: raise _winapi._WinError() if self.overlapped[0].hEvent == _ffi.NULL: raise _winapi._WinError()
def ConnectNamedPipe(self, handle): if self.type != OverlappedType.TYPE_NONE: raise _winapi._WinError() self.type = OverlappedType.TYPE_CONNECT_NAMED_PIPE self.handle = _int2handle(handle) success = _kernel32.ConnectNamedPipe(self.handle, self.overlapped) if success: err = _winapi.ERROR_SUCCESS else: err = _kernel32.GetLastError() self.error = err if err == _winapi.ERROR_IO_PENDING | _winapi.ERROR_SUCCESS: return False elif err == _winapi.ERROR_PIPE_CONNECTED: mark_as_completed(self.overlapped) return True else: SetFromWindowsErr(err)
def GetQueuedCompletionStatus(completionport, milliseconds): numberofbytes = _ffi.new('DWORD[1]', [0]) completionkey = _ffi.new('ULONG**') completionport = _int2handle(completionport) if completionport is None: raise _winapi._WinError() overlapped = _ffi.new("OVERLAPPED**") overlapped[0] = _ffi.NULL result = _kernel32.GetQueuedCompletionStatus(completionport, numberofbytes, completionkey, overlapped, milliseconds) if result: err = _winapi.ERROR_SUCCESS else: err = _kernel32.GetLastError() if overlapped[0] == _ffi.NULL: if err == _winapi.WAIT_TIMEOUT: return None return SetFromWindowsErr(err) return (err, numberofbytes, _handle2int(completionkey[0]), _handle2int(_ffi.addressof(overlapped[0][0])))
def PostQueuedCompletionStatus(completionport, ms): raise _winapi._WinError()
def CreateEvent(eventattributes, manualreset, initialstate, name): event = _kernel32.CreateEventW(NULL, manualreset, initialstate, _Z(name)) event = _handle2int(event) if not event: raise _winapi._WinError() return event
def SetEvent(handle): ret = _kernel32.SetEvent(_int2handle(handle)) if not ret: raise _winapi._WinError()