def post_to_queue_callback(lpparameter, timerorwaitfired): pdata = _ffi.cast("PostCallbackData*", lpparameter) ret = _kernel32.PostQueuedCompletionStatus(pdata.hCompletionPort, timerorwaitfired, _ffi.cast("ULONG_PTR", 0), pdata.Overlapped) result = False _winapi.free(pdata)
def GetStdHandle(stdhandle): stdhandle = _ffi.cast("DWORD", stdhandle) res = _kernel32.GetStdHandle(stdhandle) if not res: return None else: # note: returns integer, not handle object return int(_ffi.cast("intptr_t", res))
def RegisterWaitWithQueue(object, completionport, ovaddress, miliseconds): data = _ffi.cast('PostCallbackData*', _winapi.malloc(_ffi.sizeof("PostCallbackData"))) newwaitobject = _ffi.new("HANDLE*") data[0].hCompletionPort = _int2handle(completionport) data[0].Overlapped = _int2overlappedptr(ovaddress) ret = _kernel32.RegisterWaitForSingleObject( newwaitobject, _int2handle(object), _ffi.cast("WAITORTIMERCALLBACK", post_to_queue_callback), data, miliseconds, _kernel32.WT_EXECUTEINWAITTHREAD | _kernel32.WT_EXECUTEONLYONCE) if not ret: RaiseFromWindowsErr(0) return _handle2int(newwaitobject[0])
def ConnectEx(self, socket, addressobj): socket = _int2handle(socket) if self.type != OverlappedType.TYPE_NONE: _winapi.raise_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 RaiseFromWindowsErr(0)
def TerminateProcess(handle, exitcode): # CPython: the first argument is expected to be an integer. # The second argument is silently wrapped in a UINT. res = _kernel32.TerminateProcess(_int2handle(handle), _ffi.cast("UINT", exitcode)) if not res: raise _WinError()
def GetStdHandle(stdhandle): stdhandle = _ffi.cast("DWORD", stdhandle) res = _kernel32.GetStdHandle(stdhandle) if not res: return None else: return _handle2int(res)
def BindLocal(socket, family): socket = _int2handle(socket) if family == AF_INET: addr = _ffi.new("struct sockaddr_in*") addr[0].sin_family = AF_INET addr[0].sin_port = 0 addr[0].sin_addr.S_un.S_addr = INADDR_ANY paddr = _ffi.cast("PSOCKADDR", addr) result = _winsock2.bind(socket, paddr, _ffi.sizeof("struct sockaddr_in")) elif family == AF_INET6: addr = _ffi.new("struct sockaddr_in6*") addr.sin6_family = AF_INET6 addr.sin6_port = 0 addr.sin6_addr = in6addr_any[0] result = _winsock2.bind(socket, _ffi.cast("PSOCKADDR", addr), _ffi.sizeof("struct sockaddr_in")) else: raise ValueError() if result == SOCKET_ERROR: RaiseFromWindowsErr(0)
def parse_address(addressobj, address, length): lengthptr = _ffi.new("INT*") lengthptr[0] = length if len(addressobj) == 2: host, port = addressobj address[0].sa_family = AF_INET result = _winsock2.WSAStringToAddressW(host, AF_INET, _ffi.NULL, address, lengthptr) if result < 0: raise _winapi.WinError() _ffi.cast("SOCKADDR_IN*", address)[0].sin_port = _winsock2.htons(port) return address, lengthptr[0] elif len(addressobj) == 4: host, port, flowinfo, scopeid = addressobj address.sa_family = AF_INET6 result = _winsock2.WSAStringToAddressW(host, AF_INET6, _ffi.NULL, address, lengthptr) address.sin6_port = _winsock2.htons(port) address.sin6_flowinfo = flowinfo address.sin6_scopeid = scopeid return address, lengthptr[0] else: return -1
def _handle2int(handle): return int(_ffi.cast("intptr_t", handle))
def _int2handle(val): return _ffi.cast("HANDLE", val)
def __int__(self): return int(_ffi.cast("intptr_t", self.c_handle))
def _int2overlappedptr(val): return _ffi.cast("OVERLAPPED*", val)
def _int2dword(int2cast): return _ffi.cast("DWORD", int2cast)
def _int2intptr(int2cast): return _ffi.cast("ULONG_PTR", int2cast)