Author: andrewjlawrence
Branch: py3.6
Changeset: r96472:fa2f3d6387d6
Date: 2019-04-14 07:30 +0100
http://bitbucket.org/pypy/pypy/changeset/fa2f3d6387d6/

Log:    Merged overlapped into py3.6

diff --git a/lib_pypy/_overlapped.py b/lib_pypy/_overlapped.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/_overlapped.py
@@ -0,0 +1,612 @@
+"""
+Support routines for overlapping io.
+Currently, this extension module is only required when using the
+modules on Windows.
+"""
+
+import sys
+if sys.platform != 'win32':
+    raise ImportError("The '_overlapped' module is only available on Windows")
+
+# Declare external Win32 functions
+
+from _pypy_winbase_cffi import ffi as _ffi
+_kernel32 = _ffi.dlopen('kernel32')
+
+_winsock2 = _ffi.dlopen('Ws2_32')
+
+_mswsock = _ffi.dlopen('Mswsock')
+
+GetVersion = _kernel32.GetVersion
+NULL = _ffi.NULL
+
+from _winapi import INVALID_HANDLE_VALUE, _MAX_PATH , _Z, SetFromWindowsErr
+import _winapi
+
+#
+# Error Codes
+#
+ERROR_IO_PENDING = 997
+ERROR_PIPE_BUSY = 231
+ERROR_NETNAME_DELETED = 64
+
+SOCKET_ERROR = -1
+
+AF_INET = 2
+AF_INET6 = 23  
+
+SOCK_STREAM = 1
+IPPROTO_TCP = 6
+
+INVALID_SOCKET = -1
+
+IOC_OUT = 0x40000000
+IOC_IN = 0x80000000
+IOC_INOUT = IOC_IN | IOC_OUT
+IOC_WS2 = 0x08000000
+
+def _WSAIORW(x, y):
+    return IOC_INOUT | x | y
+
+WSAID_ACCEPTEX  = _ffi.new("GUID[1]")
+WSAID_ACCEPTEX[0].Data1 = 0xb5367df1
+WSAID_ACCEPTEX[0].Data2 = 0xcbac
+WSAID_ACCEPTEX[0].Data3 = 0x11cf
+WSAID_ACCEPTEX[0].Data4 = [0x95,0xca,0x00,0x80,0x5f,0x48,0xa1,0x92]
+
+
+WSAID_CONNECTEX  = _ffi.new("GUID[1]")
+WSAID_CONNECTEX[0].Data1 = 0x25a207b9
+WSAID_CONNECTEX[0].Data2 = 0xddf3
+WSAID_CONNECTEX[0].Data3 = 0x4660
+WSAID_CONNECTEX[0].Data4 = [0x8e,0xe9,0x76,0xe5,0x8c,0x74,0x06,0x3e]
+
+WSAID_DISCONNECTEX  = _ffi.new("GUID[1]")
+WSAID_DISCONNECTEX[0].Data1 = 0x7fda2e11
+WSAID_DISCONNECTEX[0].Data2 = 0x8630
+WSAID_DISCONNECTEX[0].Data3 = 0x436f
+WSAID_DISCONNECTEX[0].Data4 = [0xa0,0x31,0xf5,0x36,0xa6,0xee,0xc1,0x57]
+
+SIO_GET_EXTENSION_FUNCTION_POINTER = _WSAIORW(IOC_WS2,6)
+
+SO_UPDATE_ACCEPT_CONTEXT = 0x700B
+SO_UPDATE_CONNECT_CONTEXT = 0x7010
+INADDR_ANY   = 0x00000000
+in6addr_any = _ffi.new("struct in6_addr[1]")
+
+# Status Codes
+STATUS_PENDING = 0x00000103
+
+
+def _int2intptr(int2cast):
+    return _ffi.cast("ULONG_PTR", int2cast)
+
+def _int2dword(int2cast):
+    return _ffi.cast("DWORD", int2cast)
+
+def _int2handle(val):
+    return _ffi.cast("HANDLE", val)
+
+def _int2overlappedptr(val):
+    return _ffi.cast("OVERLAPPED*", val)
+
+def _handle2int(handle):
+    return int(_ffi.cast("intptr_t", handle))
+
+from enum import Enum
+class OverlappedType(Enum):
+    TYPE_NONE = 0 
+    TYPE_NOT_STARTED = 1
+    TYPE_READ = 2 
+    TYPE_READINTO = 3
+    TYPE_WRITE = 4
+    TYPE_ACCEPT = 5
+    TYPE_CONNECT = 6
+    TYPE_DISCONNECT = 7
+    TYPE_CONNECT_NAMED_PIPE = 8
+    TYPE_WAIT_NAMED_PIPE_AND_CONNECT = 9
+    TYPE_TRANSMIT_FILE = 10
+
+_accept_ex = _ffi.new("AcceptExPtr*")
+_connect_ex = _ffi.new("ConnectExPtr*")
+_disconnect_ex = _ffi.new("DisconnectExPtr*")
+
+
+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()
+
+
+initiailize_function_ptrs()
+
+
+class Overlapped(object):
+    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 __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)
+
+    @property
+    def event(self):
+        return self.overlapped[0].hEvent
+
+    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]
+
+    def getbuffer(self):
+        xxx
+        return None
+
+    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)
+     
+    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 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)
+
+    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 getresult(self, wait=False):
+        return self.GetOverlappedResult(wait)
+    
+    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 ReadFile(self, handle, size):
+        self.type = OverlappedType.TYPE_READ
+        self.handle = _int2handle(handle)
+        self.read_buffer = _ffi.new("CHAR[]", max(1,size))
+        return self.do_ReadFile(self.handle, self.read_buffer, size)
+    
+    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)
+
+    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 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 DisconnectEx(self, socket, flags):
+        xxx
+        return None
+
+    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)
+
+    @property
+    def pending(self):
+        return (not HasOverlappedIoCompleted(self.overlapped[0]) and
+                self.type != OverlappedType.TYPE_NOT_STARTED)
+    
+    @property
+    def address(self):
+        return _handle2int(self.overlapped)
+
+def SetEvent(handle):
+    ret = _kernel32.SetEvent(_int2handle(handle))
+    if not ret:
+       raise _winapi._WinError()
+
+def mark_as_completed(overlapped):
+    overlapped[0].Internal = 0
+    if overlapped[0].hEvent != _ffi.NULL:
+        SetEvent(overlapped[0].hEvent) 
+
+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 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)
+
+def PostQueuedCompletionStatus(completionport, ms):
+    raise _winapi._WinError()
+
+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])))
+
+@_ffi.callback("void(void*, int)")
+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 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])
+
+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)
+
+def UnregisterWaitEx(handle, event):
+    waithandle = _int2handle(handle)
+    waitevent = _int2handle(event)
+    
+    ret = _kernel32.UnregisterWaitEx(waithandle, waitevent)
+     
+    if not ret:
+        SetFromWindowsErr(0)
+
+def UnregisterWait(handle):
+    handle = _int2handle(handle)
+    
+    ret = _kernel32.UnregisterWait(handle)
+    
+    if not ret:
+        SetFromWindowsErr(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)
+
+def HasOverlappedIoCompleted(overlapped):
+    return (overlapped.Internal != STATUS_PENDING)
+
+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
+
+
+
+
+
+
+
diff --git a/lib_pypy/_pypy_winbase_build.py b/lib_pypy/_pypy_winbase_build.py
--- a/lib_pypy/_pypy_winbase_build.py
+++ b/lib_pypy/_pypy_winbase_build.py
@@ -90,7 +90,6 @@
     HANDLE  hEvent;
 } OVERLAPPED, *LPOVERLAPPED;
 
-
 DWORD WINAPI GetVersion(void);
 BOOL WINAPI CreatePipe(PHANDLE, PHANDLE, void *, DWORD);
 HANDLE WINAPI CreateNamedPipeA(LPCSTR, DWORD, DWORD, DWORD, DWORD, DWORD,
@@ -101,16 +100,17 @@
                    DWORD, DWORD, HANDLE);
 HANDLE WINAPI CreateFileW(LPCWSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES,
                    DWORD, DWORD, HANDLE);
+BOOL ReadFile(HANDLE, LPVOID, DWORD, LPDWORD, LPOVERLAPPED);
 BOOL WINAPI SetNamedPipeHandleState(HANDLE, LPDWORD, LPDWORD, LPDWORD);
 BOOL WINAPI ConnectNamedPipe(HANDLE, LPOVERLAPPED);
 HANDLE WINAPI CreateEventA(LPSECURITY_ATTRIBUTES, BOOL, BOOL, LPCSTR);
 HANDLE WINAPI CreateEventW(LPSECURITY_ATTRIBUTES, BOOL, BOOL, LPCWSTR);
-VOID WINAPI SetEvent(HANDLE);
+BOOL WINAPI SetEvent(HANDLE);
+BOOL WINAPI CancelIo(HANDLE);
 BOOL WINAPI CancelIoEx(HANDLE, LPOVERLAPPED);
 BOOL WINAPI CloseHandle(HANDLE);
 DWORD WINAPI GetLastError(VOID);
 BOOL WINAPI GetOverlappedResult(HANDLE, LPOVERLAPPED, LPDWORD, BOOL);
-
 HANDLE WINAPI GetCurrentProcess(void);
 BOOL WINAPI DuplicateHandle(HANDLE, HANDLE, HANDLE, LPHANDLE,
                             DWORD, BOOL, DWORD);
@@ -121,19 +121,171 @@
                            void *, BOOL, DWORD, wchar_t *,
                            wchar_t *, LPSTARTUPINFO, LPPROCESS_INFORMATION);
 DWORD WINAPI WaitForSingleObject(HANDLE, DWORD);
+DWORD WaitForMultipleObjects(DWORD, HANDLE*, BOOL, DWORD);
 BOOL WINAPI GetExitCodeProcess(HANDLE, LPDWORD);
 BOOL WINAPI TerminateProcess(HANDLE, UINT);
 HANDLE WINAPI GetStdHandle(DWORD);
 DWORD WINAPI GetModuleFileNameW(HANDLE, wchar_t *, DWORD);
-
 UINT WINAPI SetErrorMode(UINT);
 #define SEM_FAILCRITICALERRORS     0x0001
 #define SEM_NOGPFAULTERRORBOX      0x0002
 #define SEM_NOALIGNMENTFAULTEXCEPT 0x0004
 #define SEM_NOOPENFILEERRORBOX     0x8000
+
+typedef struct _PostCallbackData {
+    HANDLE hCompletionPort;
+    LPOVERLAPPED Overlapped;
+} PostCallbackData, *LPPostCallbackData;
+
+typedef VOID (WINAPI *WAITORTIMERCALLBACK) (PVOID, BOOL);  
+BOOL WINAPI RegisterWaitForSingleObject(PHANDLE, HANDLE, WAITORTIMERCALLBACK, 
PVOID, ULONG, ULONG);
+
+BOOL WINAPI PostQueuedCompletionStatus(HANDLE,  DWORD, ULONG_PTR, 
LPOVERLAPPED);
+BOOL WINAPI UnregisterWaitEx(HANDLE, HANDLE);
+BOOL WINAPI UnregisterWait(HANDLE);
+
+BOOL WINAPI GetQueuedCompletionStatus(HANDLE, LPDWORD, ULONG**, LPOVERLAPPED*, 
DWORD);
+HANDLE WINAPI CreateIoCompletionPort(HANDLE, HANDLE, ULONG_PTR, DWORD);
+
+BOOL WINAPI WriteFile(HANDLE, LPCVOID, DWORD, LPDWORD, LPOVERLAPPED);
+
+#define WT_EXECUTEINWAITTHREAD 0x00000004
+#define WT_EXECUTEONLYONCE 0x00000008
+
+HANDLE GetProcessHeap();
+LPVOID HeapAlloc(HANDLE, DWORD, SIZE_T);
+BOOL HeapFree(HANDLE, DWORD, LPVOID);
+
 """)
 
-# --------------------
+# -------------------- Win Sock 2 ----------------------
+
+ffi.cdef("""
+typedef struct _WSABUF {
+  ULONG len;
+  CHAR  *buf;
+} WSABUF, *LPWSABUF;
+
+typedef HANDLE SOCKET;
+SOCKET __stdcall socket(int, int, int);
+int closesocket(SOCKET);
+
+
+typedef BOOL (__stdcall * LPFN_DISCONNECTEX) (SOCKET, LPOVERLAPPED, DWORD, 
DWORD);
+typedef VOID (*LPOVERLAPPED_COMPLETION_ROUTINE) (DWORD, DWORD, LPVOID);
+
+int __stdcall WSARecv(SOCKET, LPWSABUF, DWORD, LPDWORD, LPDWORD, LPOVERLAPPED, 
LPOVERLAPPED_COMPLETION_ROUTINE);
+int __stdcall WSASend(SOCKET, LPWSABUF, DWORD, LPDWORD, DWORD, LPOVERLAPPED,  
LPOVERLAPPED_COMPLETION_ROUTINE);
+int __stdcall WSAIoctl(SOCKET, DWORD, LPVOID, DWORD, LPVOID, DWORD, LPDWORD, 
LPOVERLAPPED, LPOVERLAPPED_COMPLETION_ROUTINE);
+
+
+typedef struct _GUID {
+  DWORD Data1;
+  WORD  Data2;
+  WORD  Data3;
+  BYTE  Data4[8];
+} GUID;
+
+typedef USHORT ADDRESS_FAMILY;
+
+typedef struct in6_addr {
+  union {
+    UCHAR  Byte[16];
+    USHORT Word[8];
+  } u;
+} IN6_ADDR, *PIN6_ADDR, *LPIN6_ADDR;
+
+typedef struct {
+  union {
+    struct {
+      ULONG  Zone : 28;
+      ULONG  Level : 4;
+    };
+    ULONG  Value;
+  };
+} SCOPE_ID, *PSCOPE_ID;
+
+typedef struct sockaddr_in6 {
+  ADDRESS_FAMILY sin6_family;
+  USHORT         sin6_port;
+  ULONG          sin6_flowinfo;
+  IN6_ADDR       sin6_addr;
+  union {
+    ULONG    sin6_scope_id;
+    SCOPE_ID sin6_scope_struct;
+  };
+} SOCKADDR_IN6_LH, *PSOCKADDR_IN6_LH, *LPSOCKADDR_IN6_LH;
+
+typedef struct in_addr {
+  union {
+    struct {
+      UCHAR s_b1;
+      UCHAR s_b2;
+      UCHAR s_b3;
+      UCHAR s_b4;
+    } S_un_b;
+    struct {
+      USHORT s_w1;
+      USHORT s_w2;
+    } S_un_w;
+    ULONG S_addr;
+  } S_un;
+} INADDR, *PINADDR;
+
+typedef struct sockaddr_in {
+  SHORT          sin_family;
+  USHORT         sin_port;
+  INADDR         sin_addr;
+  CHAR           sin_zero[8];
+} SOCKADDR_IN, *PSOCKADDR_IN, *LPSOCKADDR_IN;
+
+typedef struct sockaddr {
+    USHORT  sa_family;
+    CHAR    sa_data[14];
+} SOCKADDR, *PSOCKADDR, *LPSOCKADDR;
+
+int bind(SOCKET, const PSOCKADDR, int);
+
+#define MAX_PROTOCOL_CHAIN 7
+
+typedef struct _WSAPROTOCOLCHAIN {
+  int   ChainLen;
+  DWORD ChainEntries[MAX_PROTOCOL_CHAIN];
+} WSAPROTOCOLCHAIN, *LPWSAPROTOCOLCHAIN;
+
+#define WSAPROTOCOL_LEN  255
+
+typedef struct _WSAPROTOCOL_INFOW {
+  DWORD            dwServiceFlags1;
+  DWORD            dwServiceFlags2;
+  DWORD            dwServiceFlags3;
+  DWORD            dwServiceFlags4;
+  DWORD            dwProviderFlags;
+  GUID             ProviderId;
+  DWORD            dwCatalogEntryId;
+  WSAPROTOCOLCHAIN ProtocolChain;
+  int              iVersion;
+  int              iAddressFamily;
+  int              iMaxSockAddr;
+  int              iMinSockAddr;
+  int              iSocketType;
+  int              iProtocol;
+  int              iProtocolMaxOffset;
+  int              iNetworkByteOrder;
+  int              iSecurityScheme;
+  DWORD            dwMessageSize;
+  DWORD            dwProviderReserved;
+  WCHAR            szProtocol[WSAPROTOCOL_LEN + 1];
+} WSAPROTOCOL_INFOW, *LPWSAPROTOCOL_INFOW;
+
+int __stdcall WSAStringToAddressW(LPWSTR, int, LPWSAPROTOCOL_INFOW, 
LPSOCKADDR, int* );
+
+typedef BOOL (WINAPI* AcceptExPtr)(SOCKET, SOCKET, PVOID, DWORD, DWORD, DWORD, 
LPDWORD, LPOVERLAPPED);  
+typedef BOOL (WINAPI *ConnectExPtr)(SOCKET, const PSOCKADDR, int, PVOID, 
DWORD, LPDWORD, LPOVERLAPPED);
+typedef BOOL (WINAPI *DisconnectExPtr)(SOCKET, LPOVERLAPPED, DWORD, DWORD);
+
+USHORT htons(USHORT);
+""")
 
 if __name__ == "__main__":
     ffi.compile()
diff --git a/lib_pypy/_pypy_winbase_cffi.py b/lib_pypy/_pypy_winbase_cffi.py
--- a/lib_pypy/_pypy_winbase_cffi.py
+++ b/lib_pypy/_pypy_winbase_cffi.py
@@ -3,8 +3,8 @@
 
 ffi = _cffi_backend.FFI('_pypy_winbase_cffi',
     _version = 0x2601,
-    _types = 
b'\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x09\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x19\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\xAB\x03\x00\x00\x13\x11\x00\x00\xB0\x03\x00\x00\x15\x11\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x13\x11\x00\x00\x13\x11\x00\x00\xAA\x03\x00\x00\xA8\x03\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x03\x00\x00\x1F\x11\x00\x00\x15\x11\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x11\x00\x00\xA7\x03\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x11\x00\x00\x29\x11\x00\x00\x18\x03\x00\x00\x07\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x11\x00\x00\x08\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x11\x00\x00\x2E\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x11\x00\x00\x2E\x11\x00\x00\x2E\x11\x00\x
 
00\x2E\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x11\x00\x00\x15\x11\x00\x00\x15\x11\x00\x00\x1F\x11\x00\x00\x0A\x01\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x6B\x03\x00\x00\x49\x11\x00\x00\x15\x11\x00\x00\x15\x11\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x49\x11\x00\x00\x49\x11\x00\x00\x1B\x11\x00\x00\x1C\x11\x00\x00\x02\x0F\x00\x00\x0D\x0D\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x33\x0D\x00\x00\x08\x01\x00\x00\x02\x0F\x00\x00\x18\x0D\x00\x00\x15\x11\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x18\x0D\x00\x00\x15\x11\x00\x00\x49\x11\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x18\x0D\x00\x00\x02\x0F\x00\x00\x66\x0D\x00\x00\x06\x01\x00\x00\x00\x0F\x00\x00\x66\x0D\x00\x00\x00\x0F\x00\x00\x66\x0D\x00\x00\x10\x01\x00\x00\x00\x0F\x00\x00\x15\x0D\x00\x00\xA9\x03\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\xAB\x03\x00\x00\x02\x0F\x00\x00\x15\x0D\x00\x00\x6E\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x6B\x03\x00\x00\x02\x0F\x00\x00\x15\x0D\x00\x00\x71\x11\x00\x00\x0
 
A\x01\x00\x00\x0A\x01\x00\x00\x6E\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x15\x11\x00\x00\x02\x0F\x00\x00\x15\x0D\x00\x00\x71\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x6E\x11\x00\x00\x02\x0F\x00\x00\x15\x0D\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x15\x0D\x00\x00\x02\x0F\x00\x00\x15\x0D\x00\x00\x49\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x6E\x11\x00\x00\x02\x0F\x00\x00\x15\x0D\x00\x00\x77\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x6E\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x15\x11\x00\x00\x02\x0F\x00\x00\xB0\x0D\x00\x00\x15\x11\x00\x00\x02\x0F\x00\x00\x04\x09\x00\x00\x02\x09\x00\x00\x05\x09\x00\x00\x03\x09\x00\x00\x02\x01\x00\x00\x01\x09\x00\x00\x00\x09\x00\x00\xAF\x03\x00\x00\x04\x01\x00\x00\x00\x01',
-    _globals = 
(b'\x00\x00\x27\x23CancelIoEx',0,b'\x00\x00\x24\x23CloseHandle',0,b'\x00\x00\x27\x23ConnectNamedPipe',0,b'\x00\x00\x6D\x23CreateEventA',0,b'\x00\x00\x73\x23CreateEventW',0,b'\x00\x00\x79\x23CreateFileA',0,b'\x00\x00\x9B\x23CreateFileW',0,b'\x00\x00\x82\x23CreateNamedPipeA',0,b'\x00\x00\x91\x23CreateNamedPipeW',0,b'\x00\x00\x1E\x23CreatePipe',0,b'\x00\x00\x12\x23CreateProcessA',0,b'\x00\x00\x48\x23CreateProcessW',0,b'\x00\x00\x3F\x23DuplicateHandle',0,b'\x00\x00\x8F\x23GetCurrentProcess',0,b'\x00\x00\x35\x23GetExitCodeProcess',0,b'\x00\x00\x63\x23GetLastError',0,b'\x00\x00\x5E\x23GetModuleFileNameW',0,b'\x00\x00\x2B\x23GetOverlappedResult',0,b'\x00\x00\x8C\x23GetStdHandle',0,b'\x00\x00\x63\x23GetVersion',0,b'\xFF\xFF\xFF\x1FSEM_FAILCRITICALERRORS',1,b'\xFF\xFF\xFF\x1FSEM_NOALIGNMENTFAULTEXCEPT',4,b'\xFF\xFF\xFF\x1FSEM_NOGPFAULTERRORBOX',2,b'\xFF\xFF\xFF\x1FSEM_NOOPENFILEERRORBOX',32768,b'\x00\x00\x57\x23SetErrorMode',0,b'\x00\x00\xA4\x23SetEvent',0,b'\x00\x00\x39\x23Se
 
tNamedPipeHandleState',0,b'\x00\x00\x31\x23TerminateProcess',0,b'\x00\x00\x5A\x23WaitForSingleObject',0,b'\x00\x00\x54\x23_get_osfhandle',0,b'\x00\x00\x10\x23_getch',0,b'\x00\x00\x10\x23_getche',0,b'\x00\x00\x68\x23_getwch',0,b'\x00\x00\x68\x23_getwche',0,b'\x00\x00\x10\x23_kbhit',0,b'\x00\x00\x07\x23_locking',0,b'\x00\x00\x0C\x23_open_osfhandle',0,b'\x00\x00\x00\x23_putch',0,b'\x00\x00\x6A\x23_putwch',0,b'\x00\x00\x03\x23_setmode',0,b'\x00\x00\x00\x23_ungetch',0,b'\x00\x00\x65\x23_ungetwch',0),
-    _struct_unions = 
((b'\x00\x00\x00\xAD\x00\x00\x00\x03$1',b'\x00\x00\xAC\x11DUMMYSTRUCTNAME',b'\x00\x00\x15\x11Pointer'),(b'\x00\x00\x00\xAC\x00\x00\x00\x02$2',b'\x00\x00\x18\x11Offset',b'\x00\x00\x18\x11OffsetHigh'),(b'\x00\x00\x00\xA8\x00\x00\x00\x02$PROCESS_INFORMATION',b'\x00\x00\x15\x11hProcess',b'\x00\x00\x15\x11hThread',b'\x00\x00\x18\x11dwProcessId',b'\x00\x00\x18\x11dwThreadId'),(b'\x00\x00\x00\xAA\x00\x00\x00\x02$STARTUPINFO',b'\x00\x00\x18\x11cb',b'\x00\x00\x13\x11lpReserved',b'\x00\x00\x13\x11lpDesktop',b'\x00\x00\x13\x11lpTitle',b'\x00\x00\x18\x11dwX',b'\x00\x00\x18\x11dwY',b'\x00\x00\x18\x11dwXSize',b'\x00\x00\x18\x11dwYSize',b'\x00\x00\x18\x11dwXCountChars',b'\x00\x00\x18\x11dwYCountChars',b'\x00\x00\x18\x11dwFillAttribute',b'\x00\x00\x18\x11dwFlags',b'\x00\x00\x66\x11wShowWindow',b'\x00\x00\x66\x11cbReserved2',b'\x00\x00\xAE\x11lpReserved2',b'\x00\x00\x15\x11hStdInput',b'\x00\x00\x15\x11hStdOutput',b'\x00\x00\x15\x11hStdError'),(b'\x00\x00\x00\xA7\x00\x00\x00\x02_
 
OVERLAPPED',b'\x00\x00\x18\x11Internal',b'\x00\x00\x18\x11InternalHigh',b'\x00\x00\xAD\x11DUMMYUNIONNAME',b'\x00\x00\x15\x11hEvent'),(b'\x00\x00\x00\xA9\x00\x00\x00\x02_SECURITY_ATTRIBUTES',b'\x00\x00\x18\x11nLength',b'\x00\x00\x15\x11lpSecurityDescriptor',b'\x00\x00\x01\x11bInheritHandle')),
-    _typenames = 
(b'\x00\x00\x00\x29LPOVERLAPPED',b'\x00\x00\x00\x1CLPPROCESS_INFORMATION',b'\x00\x00\x00\x6ELPSECURITY_ATTRIBUTES',b'\x00\x00\x00\x1BLPSTARTUPINFO',b'\x00\x00\x00\xA7OVERLAPPED',b'\x00\x00\x00\xA8PROCESS_INFORMATION',b'\x00\x00\x00\x6EPSECURITY_ATTRIBUTES',b'\x00\x00\x00\xA9SECURITY_ATTRIBUTES',b'\x00\x00\x00\xAASTARTUPINFO',b'\x00\x00\x00\x66wint_t'),
+    _types = 
b'\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x09\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x19\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x01\x68\x03\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x01\x42\x03\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x11\x11\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x1A\x03\x00\x01\x3B\x03\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x01\x4C\x03\x00\x00\x27\x11\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x27\x11\x00\x00\x27\x11\x00\x01\x47\x03\x00\x01\x3C\x03\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x03\x00\x00\x33\x11\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x33\x11\x00\x00\x11\x11\x00\x01\x32\x03\x00\x00\x11\x11\x00\x
 
00\x0A\x01\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x22\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x22\x11\x00\x00\x21\x11\x00\x00\x07\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x22\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x15\x11\x00\x00\x07\x01\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x21\x11\x00\x00\x22\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x01\x48\x03\x00\x00\x0A\x01\x00\x00\x21\x11\x00\x00\x21\x11\x00\x00\x22\x11\x00\x01\x2D\x03\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x5E\x11\x00\x00\x0A\x01\x00\x00\x21\x11\x00\x00\x0A\x01\x00\x00\x22\x11\x00\x00\x63\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x08\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x21\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x21\x11\x00\x00\x21\x03\x00\x00\x22\x03\x00\x00\x0
 
A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x21\x11\x00\x00\x21\x11\x00\x00\x21\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x22\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x21\x11\x00\x00\x22\x11\x00\x00\x63\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x21\x11\x00\x00\x22\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x33\x11\x00\x00\x0A\x01\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x01\x68\x03\x00\x00\x0A\x01\x00\x00\x21\x11\x00\x00\x22\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\xE2\x03\x00\x00\x07\x01\x00\x01\x4B\x03\x00\x00\x15\x11\x00\x00\x01\x03\x00\x00\x02\x0F\x00\x00\x01\x0D
 
\x00\x00\xB3\x11\x00\x00\xB3\x11\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\xB3\x11\x00\x00\xB3\x11\x00\x00\x2F\x11\x00\x00\x30\x11\x00\x00\x02\x0F\x00\x00\x0D\x0D\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x70\x0D\x00\x00\x08\x01\x00\x00\x02\x0F\x00\x00\x1A\x0D\x00\x00\x0A\x01\x00\x00\x33\x11\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x00\x0F\x00\x00\x1A\x0D\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x1A\x0D\x00\x00\x11\x11\x00\x00\xB3\x11\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x1A\x0D\x00\x00\x02\x0F\x00\x00\xDD\x0D\x00\x00\x06\x01\x00\x00\x00\x0F\x00\x00\xDD\x0D\x00\x00\x00\x0F\x00\x00\xDD\x0D\x00\x00\x10\x01\x00\x00\x00\x0F\x00\x00\x11\x0D\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x00\x0F\x00\x00\x11\x0D\x00\x00\x00\x0F\x00\x00\x11\x0D\x00\x01\x41\x03\x00\x00\x07\x01\x00\x00\x07\x01\x00\x01\x4C\x03\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\xEC\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\xE2\x03\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\
 
x00\xEF\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\xEC\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x11\x11\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\xEF\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\xEC\x11\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\xB3\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\xEC\x11\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\xF5\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\xEC\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x11\x11\x00\x00\x02\x0F\x00\x01\x68\x0D\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x11\x11\x00\x00\x00\x0F\x00\x01\x68\x0D\x00\x00\x11\x11\x00\x00\x07\x01\x00\x00\x02\x0F\x00\x00\x
 
0C\x09\x00\x01\x38\x03\x00\x00\x13\x09\x00\x01\x3A\x03\x00\x00\x14\x09\x00\x00\x0D\x09\x00\x00\x09\x09\x00\x01\x3E\x03\x00\x00\x0E\x09\x00\x01\x40\x03\x00\x00\x0A\x09\x00\x00\x0F\x09\x00\x00\x15\x09\x00\x01\x46\x03\x00\x01\x45\x03\x00\x00\x17\x09\x00\x00\x16\x09\x00\x00\x0B\x09\x00\x00\x10\x09\x00\x01\x4A\x03\x00\x00\x11\x09\x00\x00\x12\x09\x00\x00\x02\x01\x00\x01\x4C\x05\x00\x00\x00\x0E\x00\x01\x4C\x05\x00\x00\x00\x08\x00\x00\x4D\x03\x00\x00\x53\x03\x00\x00\x98\x03\x00\x00\x05\x01\x00\x00\x01\x09\x00\x00\x04\x09\x00\x00\x07\x09\x00\x00\x08\x09\x00\x00\x00\x09\x00\x00\x02\x09\x00\x00\x03\x09\x00\x00\x05\x09\x00\x00\x06\x09\x00\x01\x5F\x03\x00\x00\x04\x01\x00\x01\x5F\x05\x00\x00\x00\x10\x00\x01\x5F\x05\x00\x00\x00\x08\x00\x00\x1A\x05\x00\x00\x00\x07\x00\x00\xDD\x05\x00\x00\x00\x08\x00\x00\x00\x01\x00\x00\xE2\x05\x00\x00\x01\x00',
+    _globals = 
(b'\x00\x00\x40\x23CancelIo',0,b'\x00\x00\x43\x23CancelIoEx',0,b'\x00\x00\x40\x23CloseHandle',0,b'\x00\x00\x43\x23ConnectNamedPipe',0,b'\x00\x00\xEB\x23CreateEventA',0,b'\x00\x00\xF1\x23CreateEventW',0,b'\x00\x00\xF7\x23CreateFileA',0,b'\x00\x01\x24\x23CreateFileW',0,b'\x00\x01\x12\x23CreateIoCompletionPort',0,b'\x00\x01\x00\x23CreateNamedPipeA',0,b'\x00\x01\x1A\x23CreateNamedPipeW',0,b'\x00\x00\x32\x23CreatePipe',0,b'\x00\x00\x26\x23CreateProcessA',0,b'\x00\x00\xB9\x23CreateProcessW',0,b'\x00\x00\xA2\x23DuplicateHandle',0,b'\x00\x01\x18\x23GetCurrentProcess',0,b'\x00\x00\x72\x23GetExitCodeProcess',0,b'\x00\x00\xDA\x23GetLastError',0,b'\x00\x00\xD5\x23GetModuleFileNameW',0,b'\x00\x00\x47\x23GetOverlappedResult',0,b'\x00\x00\xE9\x23GetProcessHeap',0,b'\x00\x00\x76\x23GetQueuedCompletionStatus',0,b'\x00\x01\x0F\x23GetStdHandle',0,b'\x00\x00\xDA\x23GetVersion',0,b'\x00\x00\xE4\x23HeapAlloc',0,b'\x00\x00\x18\x23HeapFree',0,b'\xFF\xFF\xFF\x1FMAX_PROTOCOL_CHAIN',7,b'\x00\x0
 
0\x83\x23PostQueuedCompletionStatus',0,b'\x00\x00\x1D\x23ReadFile',0,b'\x00\x00\x38\x23RegisterWaitForSingleObject',0,b'\xFF\xFF\xFF\x1FSEM_FAILCRITICALERRORS',1,b'\xFF\xFF\xFF\x1FSEM_NOALIGNMENTFAULTEXCEPT',4,b'\xFF\xFF\xFF\x1FSEM_NOGPFAULTERRORBOX',2,b'\xFF\xFF\xFF\x1FSEM_NOOPENFILEERRORBOX',32768,b'\x00\x00\xC8\x23SetErrorMode',0,b'\x00\x00\x40\x23SetEvent',0,b'\x00\x00\x7D\x23SetNamedPipeHandleState',0,b'\x00\x00\x6E\x23TerminateProcess',0,b'\x00\x00\x40\x23UnregisterWait',0,b'\x00\x00\x94\x23UnregisterWaitEx',0,b'\x00\x00\x89\x23WSAIoctl',0,b'\xFF\xFF\xFF\x1FWSAPROTOCOL_LEN',255,b'\x00\x00\x5C\x23WSARecv',0,b'\x00\x00\x65\x23WSASend',0,b'\x00\x00\xB2\x23WSAStringToAddressW',0,b'\xFF\xFF\xFF\x1FWT_EXECUTEINWAITTHREAD',4,b'\xFF\xFF\xFF\x1FWT_EXECUTEONLYONCE',8,b'\x00\x00\xCB\x23WaitForMultipleObjects',0,b'\x00\x00\xD1\x23WaitForSingleObject',0,b'\x00\x00\xAB\x23WriteFile',0,b'\x00\x00\xC5\x23_get_osfhandle',0,b'\x00\x00\x24\x23_getch',0,b'\x00\x00\x24\x23_getche',0,b'\x00\x00\xDF
 
\x23_getwch',0,b'\x00\x00\xDF\x23_getwche',0,b'\x00\x00\x24\x23_kbhit',0,b'\x00\x00\x07\x23_locking',0,b'\x00\x00\x0C\x23_open_osfhandle',0,b'\x00\x00\x00\x23_putch',0,b'\x00\x00\xE1\x23_putwch',0,b'\x00\x00\x03\x23_setmode',0,b'\x00\x00\x00\x23_ungetch',0,b'\x00\x00\xDC\x23_ungetwch',0,b'\x00\x00\x13\x23bind',0,b'\x00\x00\x10\x23closesocket',0,b'\x00\x00\xDC\x23htons',0,b'\x00\x01\x0A\x23socket',0),
+    _struct_unions = 
((b'\x00\x00\x01\x59\x00\x00\x00\x03$1',b'\x00\x01\x55\x11DUMMYSTRUCTNAME',b'\x00\x00\x11\x11Pointer'),(b'\x00\x00\x01\x55\x00\x00\x00\x02$2',b'\x00\x00\x1A\x11Offset',b'\x00\x00\x1A\x11OffsetHigh'),(b'\x00\x00\x01\x5A\x00\x00\x00\x03$3',b'\x00\x01\x60\x11Byte',b'\x00\x01\x66\x11Word'),(b'\x00\x00\x01\x5B\x00\x00\x00\x01$4',b'\x00\x01\x56\x11',b'\x00\x00\x1A\x11Value'),(b'\x00\x00\x01\x56\x00\x00\x00\x02$5',b'\x00\x00\x1A\x13\x00\x00\x00\x1CZone',b'\x00\x00\x1A\x13\x00\x00\x00\x04Level'),(b'\x00\x00\x01\x5C\x00\x00\x00\x03$6',b'\x00\x00\x1A\x11sin6_scope_id',b'\x00\x01\x40\x11sin6_scope_struct'),(b'\x00\x00\x01\x5D\x00\x00\x00\x03$7',b'\x00\x01\x57\x11S_un_b',b'\x00\x01\x58\x11S_un_w',b'\x00\x00\x1A\x11S_addr'),(b'\x00\x00\x01\x57\x00\x00\x00\x02$8',b'\x00\x01\x5F\x11s_b1',b'\x00\x01\x5F\x11s_b2',b'\x00\x01\x5F\x11s_b3',b'\x00\x01\x5F\x11s_b4'),(b'\x00\x00\x01\x58\x00\x00\x00\x02$9',b'\x00\x00\xDD\x11s_w1',b'\x00\x00\xDD\x11s_w2'),(b'\x00\x00\x01\x3C\x00\x00\x00
 
\x02$PROCESS_INFORMATION',b'\x00\x00\x11\x11hProcess',b'\x00\x00\x11\x11hThread',b'\x00\x00\x1A\x11dwProcessId',b'\x00\x00\x1A\x11dwThreadId'),(b'\x00\x00\x01\x40\x00\x00\x00\x00$SCOPE_ID',b'\x00\x01\x5B\x11'),(b'\x00\x00\x01\x47\x00\x00\x00\x02$STARTUPINFO',b'\x00\x00\x1A\x11cb',b'\x00\x00\x27\x11lpReserved',b'\x00\x00\x27\x11lpDesktop',b'\x00\x00\x27\x11lpTitle',b'\x00\x00\x1A\x11dwX',b'\x00\x00\x1A\x11dwY',b'\x00\x00\x1A\x11dwXSize',b'\x00\x00\x1A\x11dwYSize',b'\x00\x00\x1A\x11dwXCountChars',b'\x00\x00\x1A\x11dwYCountChars',b'\x00\x00\x1A\x11dwFillAttribute',b'\x00\x00\x1A\x11dwFlags',b'\x00\x00\xDD\x11wShowWindow',b'\x00\x00\xDD\x11cbReserved2',b'\x00\x01\x5E\x11lpReserved2',b'\x00\x00\x11\x11hStdInput',b'\x00\x00\x11\x11hStdOutput',b'\x00\x00\x11\x11hStdError'),(b'\x00\x00\x01\x36\x00\x00\x00\x02_GUID',b'\x00\x00\x1A\x11Data1',b'\x00\x00\xDD\x11Data2',b'\x00\x00\xDD\x11Data3',b'\x00\x01\x62\x11Data4'),(b'\x00\x00\x01\x3B\x00\x00\x00\x02_OVERLAPPED',b'\x00\x00\x1A\x11Internal',b
 
'\x00\x00\x1A\x11InternalHigh',b'\x00\x01\x59\x11DUMMYUNIONNAME',b'\x00\x00\x11\x11hEvent'),(b'\x00\x00\x01\x3E\x00\x00\x00\x02_PostCallbackData',b'\x00\x00\x11\x11hCompletionPort',b'\x00\x00\x22\x11Overlapped'),(b'\x00\x00\x01\x41\x00\x00\x00\x02_SECURITY_ATTRIBUTES',b'\x00\x00\x1A\x11nLength',b'\x00\x00\x11\x11lpSecurityDescriptor',b'\x00\x00\x01\x11bInheritHandle'),(b'\x00\x00\x01\x48\x00\x00\x00\x02_WSABUF',b'\x00\x00\x1A\x11len',b'\x00\x00\x27\x11buf'),(b'\x00\x00\x01\x4A\x00\x00\x00\x02_WSAPROTOCOLCHAIN',b'\x00\x00\x01\x11ChainLen',b'\x00\x01\x64\x11ChainEntries'),(b'\x00\x00\x01\x4B\x00\x00\x00\x02_WSAPROTOCOL_INFOW',b'\x00\x00\x1A\x11dwServiceFlags1',b'\x00\x00\x1A\x11dwServiceFlags2',b'\x00\x00\x1A\x11dwServiceFlags3',b'\x00\x00\x1A\x11dwServiceFlags4',b'\x00\x00\x1A\x11dwProviderFlags',b'\x00\x01\x36\x11ProviderId',b'\x00\x00\x1A\x11dwCatalogEntryId',b'\x00\x01\x4A\x11ProtocolChain',b'\x00\x00\x01\x11iVersion',b'\x00\x00\x01\x11iAddressFamily',b'\x00\x00\x01\x11iMaxSockAdd
 
r',b'\x00\x00\x01\x11iMinSockAddr',b'\x00\x00\x01\x11iSocketType',b'\x00\x00\x01\x11iProtocol',b'\x00\x00\x01\x11iProtocolMaxOffset',b'\x00\x00\x01\x11iNetworkByteOrder',b'\x00\x00\x01\x11iSecurityScheme',b'\x00\x00\x1A\x11dwMessageSize',b'\x00\x00\x1A\x11dwProviderReserved',b'\x00\x01\x69\x11szProtocol'),(b'\x00\x00\x01\x38\x00\x00\x00\x02in6_addr',b'\x00\x01\x5A\x11u'),(b'\x00\x00\x01\x3A\x00\x00\x00\x02in_addr',b'\x00\x01\x5D\x11S_un'),(b'\x00\x00\x01\x42\x00\x00\x00\x02sockaddr',b'\x00\x00\xDD\x11sa_family',b'\x00\x01\x4D\x11sa_data'),(b'\x00\x00\x01\x46\x00\x00\x00\x02sockaddr_in',b'\x00\x01\x54\x11sin_family',b'\x00\x00\xDD\x11sin_port',b'\x00\x01\x3A\x11sin_addr',b'\x00\x01\x4F\x11sin_zero'),(b'\x00\x00\x01\x45\x00\x00\x00\x00sockaddr_in6',b'\x00\x00\xDD\x11sin6_family',b'\x00\x00\xDD\x11sin6_port',b'\x00\x00\x1A\x11sin6_flowinfo',b'\x00\x01\x38\x11sin6_addr',b'\x00\x01\x5C\x11')),
+    _typenames = 
(b'\x00\x00\x00\xDDADDRESS_FAMILY',b'\x00\x00\x01\x53AcceptExPtr',b'\x00\x00\x01\x52ConnectExPtr',b'\x00\x00\x01\x51DisconnectExPtr',b'\x00\x00\x01\x36GUID',b'\x00\x00\x01\x38IN6_ADDR',b'\x00\x00\x01\x3AINADDR',b'\x00\x00\x01\x51LPFN_DISCONNECTEX',b'\x00\x00\x01\x37LPIN6_ADDR',b'\x00\x00\x00\x22LPOVERLAPPED',b'\x00\x00\x00\x63LPOVERLAPPED_COMPLETION_ROUTINE',b'\x00\x00\x00\x30LPPROCESS_INFORMATION',b'\x00\x00\x01\x3DLPPostCallbackData',b'\x00\x00\x00\xECLPSECURITY_ATTRIBUTES',b'\x00\x00\x00\x15LPSOCKADDR',b'\x00\x00\x01\x43LPSOCKADDR_IN',b'\x00\x00\x01\x44LPSOCKADDR_IN6_LH',b'\x00\x00\x00\x2FLPSTARTUPINFO',b'\x00\x00\x00\x5ELPWSABUF',b'\x00\x00\x01\x49LPWSAPROTOCOLCHAIN',b'\x00\x00\x00\xB5LPWSAPROTOCOL_INFOW',b'\x00\x00\x01\x3BOVERLAPPED',b'\x00\x00\x01\x37PIN6_ADDR',b'\x00\x00\x01\x39PINADDR',b'\x00\x00\x01\x3CPROCESS_INFORMATION',b'\x00\x00\x01\x3FPSCOPE_ID',b'\x00\x00\x00\xECPSECURITY_ATTRIBUTES',b'\x00\x00\x00\x15PSOCKADDR',b'\x00\x00\x01\x43PSOCKADDR_IN',b'\x00
 
\x00\x01\x44PSOCKADDR_IN6_LH',b'\x00\x00\x01\x3EPostCallbackData',b'\x00\x00\x01\x40SCOPE_ID',b'\x00\x00\x01\x41SECURITY_ATTRIBUTES',b'\x00\x00\x01\x42SOCKADDR',b'\x00\x00\x01\x46SOCKADDR_IN',b'\x00\x00\x01\x45SOCKADDR_IN6_LH',b'\x00\x00\x00\x11SOCKET',b'\x00\x00\x01\x47STARTUPINFO',b'\x00\x00\x00\x3BWAITORTIMERCALLBACK',b'\x00\x00\x01\x48WSABUF',b'\x00\x00\x01\x4AWSAPROTOCOLCHAIN',b'\x00\x00\x01\x4BWSAPROTOCOL_INFOW',b'\x00\x00\x00\xDDwint_t'),
 )
diff --git a/lib_pypy/_winapi.py b/lib_pypy/_winapi.py
--- a/lib_pypy/_winapi.py
+++ b/lib_pypy/_winapi.py
@@ -17,10 +17,25 @@
 NULL = _ffi.NULL
 
 # Now the _subprocess module implementation
+def _WinError(type=WindowsError):
+    code, message = _ffi.getwinerror()
+    excep = type(None, message, None ,code)
+    raise excep
 
-def _WinError():
-    code, message = _ffi.getwinerror()
-    raise WindowsError(code, message)
+# In CPython this function converts a windows error into a python object
+# Not sure what we should do here.
+def SetFromWindowsErr(err):
+    if err == 0:
+       err = _kernel32.GetLastError()
+
+    if err == ERROR_CONNECTION_REFUSED:
+        type = ConnectionRefusedError
+    elif err == ERROR_CONNECTION_ABORTED:
+        type = ConnectionAbortedError
+    else:
+        type = WindowsError
+
+    return _WinError(type)
 
 def _int2handle(val):
     return _ffi.cast("HANDLE", val)
@@ -32,25 +47,25 @@
 
 def CreatePipe(attributes, size):
     handles = _ffi.new("HANDLE[2]")
-
+    
     res = _kernel32.CreatePipe(handles, handles + 1, NULL, size)
 
     if not res:
-        raise _WinError()
+        SetFromWindowsErr(0)
 
     return _handle2int(handles[0]), _handle2int(handles[1])
 
 def CreateNamedPipe(*args):
     handle = _kernel32.CreateNamedPipeW(*args)
     if handle == INVALID_HANDLE_VALUE:
-        raise _WinError()
-    return handle
+        SetFromWindowsErr(0)
+    return _handle2int(handle)
 
 def CreateFile(*args):
     handle = _kernel32.CreateFileW(*args)
     if handle == INVALID_HANDLE_VALUE:
-        raise _WinError()
-    return handle
+        SetFromWindowsErr(0)
+    return _handle2int(handle)
 
 def SetNamedPipeHandleState(namedpipe, mode, max_collection_count, 
collect_data_timeout):
     d0 = _ffi.new('DWORD[1]', [mode])
@@ -79,20 +94,20 @@
 
     def __del__(self):
         # do this somehow else
-        xxx
         err = _kernel32.GetLastError()
         bytes = _ffi.new('DWORD[1]')
-        o = overlapped[0]
-        if overlapped[0].pending:
+        o = self.overlapped[0]
+        if self.pending:
             if _kernel32.CancelIoEx(o.handle, o.overlapped) & \
                 self.GetOverlappedResult(o.handle, o.overlapped, 
_ffi.addressof(bytes), True):
                 # The operation is no longer pending, nothing to do
                 pass
             else:
-                raise RuntimeError('deleting an overlapped strucwith a pending 
operation not supported')
+                raise RuntimeError('deleting an overlapped struct with a 
pending operation not supported')
 
     @property
     def event(self):
+        xxx
         return None
 
     def GetOverlappedResult(self, wait):
@@ -110,8 +125,8 @@
         else:
             self.pending = 0
             raise _WinError()
-        if self.completed and self.read_buffer:
-            if transferred != len(self.read_buffer):
+        if self.completed and self.readbuffer:
+            if transferred != len(self.readbuffer):
                 raise _WinError()
         return transferred[0], err
 
@@ -125,6 +140,7 @@
 
  
 def ConnectNamedPipe(handle, overlapped=False):
+    handle = _int2handle(handle)
     if overlapped:
         ov = Overlapped(handle)
     else:
@@ -140,10 +156,10 @@
             _kernel32.SetEvent(ov.overlapped[0].hEvent)
         else:
             del ov
-            raise _WinError()
+            SetFromWindowsErr(err)
         return ov
     elif not success:
-        raise _WinError()
+        SetFromWindowsErr(0)
 
 def GetCurrentProcess():
     return _handle2int(_kernel32.GetCurrentProcess())
@@ -217,6 +233,18 @@
 
     return res
 
+def WaitForMultipleObjects(handle_sequence, waitflag, milliseconds):
+    if len(handle_sequence) > MAXIMUM_WAIT_OBJECTS:
+        return None
+    
+    # CPython makes the wait interruptible by ctrl-c. We need to add this in 
at some point
+    res = _kernel32.WaitForMultipleObjects(len(handle_sequence), 
handle_sequence, waitflag, milliseconds)
+
+    if res == WAIT_FAILED:
+        raise _WinError()
+    return int(res)
+
+
 def GetExitCodeProcess(handle):
     # CPython: the first argument is expected to be an integer.
     code = _ffi.new("DWORD[1]")
@@ -260,6 +288,14 @@
         raise _WinError()
     return _ffi.string(buf)
 
+ZERO_MEMORY = 0x00000008
+
+def malloc(size):
+    return _kernel32.HeapAlloc(_kernel32.GetProcessHeap(),ZERO_MEMORY,size)
+
+def free(voidptr):
+    _kernel32.HeapFree(_kernel32.GetProcessHeap(),0, voidptr)
+
 # #define macros from WinBase.h and elsewhere
 STD_INPUT_HANDLE = -10
 STD_OUTPUT_HANDLE = -11
@@ -272,6 +308,7 @@
 WAIT_OBJECT_0 = 0
 WAIT_ABANDONED_0 = 0x80
 WAIT_TIMEOUT = 0x102
+WAIT_FAILED = 0xFFFFFFFF
 CREATE_NEW_CONSOLE = 0x010
 CREATE_NEW_PROCESS_GROUP = 0x200
 CREATE_UNICODE_ENVIRONMENT = 0x400
@@ -281,11 +318,14 @@
 ERROR_SUCCESS           = 0
 ERROR_NETNAME_DELETED   = 64
 ERROR_BROKEN_PIPE       = 109
+ERROR_PIPE_BUSY         = 231 
 ERROR_MORE_DATA         = 234
 ERROR_PIPE_CONNECTED    = 535
 ERROR_OPERATION_ABORTED = 995
 ERROR_IO_INCOMPLETE     = 996
 ERROR_IO_PENDING        = 997
+ERROR_CONNECTION_REFUSED = 1225
+ERROR_CONNECTION_ABORTED = 1236
 
 PIPE_ACCESS_INBOUND = 0x00000001
 PIPE_ACCESS_OUTBOUND = 0x00000002
@@ -299,11 +339,13 @@
 PIPE_ACCEPT_REMOTE_CLIENTS = 0x00000000
 PIPE_REJECT_REMOTE_CLIENTS = 0x00000008
 
+PIPE_UNLIMITED_INSTANCES = 255
+
 GENERIC_READ   =  0x80000000
 GENERIC_WRITE  =  0x40000000
 GENERIC_EXECUTE=  0x20000000
 GENERIC_ALL    =  0x10000000
-INVALID_HANDLE_VALUE = -1
+INVALID_HANDLE_VALUE = _int2handle(-1)
 FILE_FLAG_WRITE_THROUGH       =  0x80000000
 FILE_FLAG_OVERLAPPED          =  0x40000000
 FILE_FLAG_NO_BUFFERING        =  0x20000000
@@ -326,3 +368,5 @@
 OPEN_ALWAYS       = 4
 TRUNCATE_EXISTING = 5
 
+MAXIMUM_WAIT_OBJECTS = 64
+
diff --git a/pypy/doc/whatsnew-pypy3-head.rst b/pypy/doc/whatsnew-pypy3-head.rst
--- a/pypy/doc/whatsnew-pypy3-head.rst
+++ b/pypy/doc/whatsnew-pypy3-head.rst
@@ -8,3 +8,8 @@
 .. branch: zlib-make-py3-go-boom
 
 Complain if you try to copy a flushed zlib decompress on py3
+
+.. branch: winoverlapped
+
+Add support for async (overlapped) IO on Windows.
+
diff --git a/rpython/rlib/rwin32.py b/rpython/rlib/rwin32.py
--- a/rpython/rlib/rwin32.py
+++ b/rpython/rlib/rwin32.py
@@ -261,7 +261,7 @@
                 132: 13, 145: 41, 158: 13, 161: 2, 164: 11, 167: 13, 183: 17,
                 188: 8, 189: 8, 190: 8, 191: 8, 192: 8, 193: 8, 194: 8,
                 195: 8, 196: 8, 197: 8, 198: 8, 199: 8, 200: 8, 201: 8,
-                202: 8, 206: 2, 215: 11, 232: 32, 267: 20, 1816: 12, 1225: 111,
+                202: 8, 206: 2, 215: 11, 232: 32, 267: 20, 1816: 12, 
                 }
         return errors, errno.EINVAL
 
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to