예제 #1
0
    def do_WSARecv(self, handle, allocatedbuffer, size, flags):
        nread = _ffi.new("LPDWORD")
        wsabuff = _ffi.new("WSABUF[1]")
        buffercount = _ffi.new("DWORD[1]", [1])
        pflags = _ffi.new("LPDWORD")
        pflags[0] = flags

        wsabuff[0].len = size
        wsabuff[0].buf = allocatedbuffer

        result = _winsock2.WSARecv(handle, wsabuff, _int2dword(1), nread,
                                   pflags, self.overlapped, _ffi.NULL)
        if result == SOCKET_ERROR:
            self.error = _kernel32.GetLastError()
        else:
            self.error = _winapi.ERROR_SUCCESS

        if self.error == _winapi.ERROR_BROKEN_PIPE:
            mark_as_completed(self.overlapped)
            SetFromWindowsErr(self.error)
        elif self.error in [
                _winapi.ERROR_SUCCESS, _winapi.ERROR_MORE_DATA,
                _winapi.ERROR_IO_PENDING
        ]:
            return None
        else:
            self.type = OverlappedType.TYPE_NOT_STARTED
            SetFromWindowsErr(self.error)
예제 #2
0
    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)
예제 #3
0
    def GetOverlappedResult(self, wait):
        transferred = _ffi.new('DWORD[1]', [0])

        if self.type == OverlappedType.TYPE_NONE:
            return _ffi.NULL

        if self.type == OverlappedType.TYPE_NOT_STARTED:
            return _ffi.NULL

        res = _kernel32.GetOverlappedResult(self.handle, self.overlapped,
                                            transferred, wait != 0)
        if res:
            err = _winapi.ERROR_SUCCESS
        else:
            err = _kernel32.GetLastError()
            self.error = err

        if err != _winapi.ERROR_SUCCESS and err != _winapi.ERROR_MORE_DATA:
            if not (err == _winapi.ERROR_BROKEN_PIPE and (self.type in [
                    OverlappedType.TYPE_READ, OverlappedType.TYPE_READINTO
            ])):
                SetFromWindowsErr(err)

        if self.type == OverlappedType.TYPE_READ:
            return _ffi.unpack(self.read_buffer, transferred[0])
        else:
            return transferred[0]
예제 #4
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)
예제 #5
0
def UnregisterWait(handle):
    handle = _int2handle(handle)

    ret = _kernel32.UnregisterWait(handle)

    if not ret:
        SetFromWindowsErr(0)
예제 #6
0
    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)
예제 #7
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)
예제 #8
0
def UnregisterWaitEx(handle, event):
    waithandle = _int2handle(handle)
    waitevent = _int2handle(event)

    ret = _kernel32.UnregisterWaitEx(waithandle, waitevent)

    if not ret:
        SetFromWindowsErr(0)
예제 #9
0
 def cancel(self):
     result = True
     if self.type == OverlappedType.TYPE_NOT_STARTED or self.type == OverlappedType.TYPE_WAIT_NAMED_PIPE_AND_CONNECT:
         return None
     if not HasOverlappedIoCompleted(self.overlapped[0]):
         ### If we are to support xp we will need to dynamically load the below method
         result = _kernel32.CancelIoEx(self.handle, self.overlapped)
     if (not result
             and _kernel32.GetLastError() != _winapi.ERROR_NOT_FOUND):
         SetFromWindowsErr(0)
예제 #10
0
def CreateIoCompletionPort(handle, existingcompletionport, completionkey,
                           numberofconcurrentthreads):
    completionkey = _int2intptr(completionkey)
    existingcompletionport = _int2handle(existingcompletionport)
    numberofconcurrentthreads = _int2dword(numberofconcurrentthreads)
    handle = _int2handle(handle)
    result = _kernel32.CreateIoCompletionPort(handle, existingcompletionport,
                                              completionkey,
                                              numberofconcurrentthreads)
    if result == _ffi.NULL:
        raise SetFromWindowsErr(0)
    return _handle2int(result)
예제 #11
0
    def do_ReadFile(self, handle, buf, size):
        nread = _ffi.new('DWORD[1]', [0])
        ret = _kernel32.ReadFile(handle, buf, size, nread, self.overlapped)
        if ret:
            err = _winapi.ERROR_SUCCESS
        else:
            err = _kernel32.GetLastError()

        self.error = err

        if err == _winapi.ERROR_BROKEN_PIPE:
            mark_as_completed(self.overlapped)
            SetFromWindowsErr(err)
        elif err in [
                _winapi.ERROR_SUCCESS, _winapi.ERROR_MORE_DATA,
                _winapi.ERROR_IO_PENDING
        ]:
            return None
        else:
            self.type = OverlappedType.TYPE_NOT_STARTED
            SetFromWindowsErr(err)
예제 #12
0
def ConnectPipe(address):
    err = _winapi.ERROR_PIPE_BUSY
    waddress = _ffi.new("wchar_t[]", address)
    handle = _kernel32.CreateFileW(
        waddress, _winapi.GENERIC_READ | _winapi.GENERIC_WRITE, 0, _ffi.NULL,
        _winapi.OPEN_EXISTING, _winapi.FILE_FLAG_OVERLAPPED, _ffi.NULL)
    err = _kernel32.GetLastError()

    if handle == INVALID_HANDLE_VALUE or err == _winapi.ERROR_PIPE_BUSY:
        SetFromWindowsErr(err)

    return _handle2int(handle)
예제 #13
0
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:
        SetFromWindowsErr(0)

    return _handle2int(newwaitobject[0])
예제 #14
0
 def __del__(self):
     bytes = _ffi.new("DWORD[1]", [0])
     olderr = _kernel32.GetLastError()
     hascompletedio = HasOverlappedIoCompleted(self.overlapped[0])
     if not hascompletedio and self.type != OverlappedType.TYPE_NOT_STARTED:
         wait = _kernel32.CancelIoEx(self.handle, self.overlapped)
         ret = self.GetOverlappedResult(wait)
         err = _winapi.ERROR_SUCCESS
         if not ret:
             err = _kernel32.GetLastError()
             self.error = err
         if err != _winapi.ERROR_SUCCESS and \
            err != _winapi.ERROR_NOT_FOUND and \
            err != _winapi.ERROR_OPERATION_ABORTED:
             SetFromWindowsErr(err)
     if self.overlapped[0].hEvent != 0:
         _winapi.CloseHandle(self.overlapped[0].hEvent)
     _winapi.SetLastError(olderr)
예제 #15
0
    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)
예제 #16
0
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:
        SetFromWindowsErr(0)
예제 #17
0
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])))