Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers...
[reactos.git] / reactos / dll / win32 / msafd / misc / dllmain.c
diff --git a/reactos/dll/win32/msafd/misc/dllmain.c b/reactos/dll/win32/msafd/misc/dllmain.c
deleted file mode 100644 (file)
index 45a1d17..0000000
+++ /dev/null
@@ -1,3976 +0,0 @@
-/*
- * COPYRIGHT:   See COPYING in the top level directory
- * PROJECT:     ReactOS Ancillary Function Driver DLL
- * FILE:        dll/win32/msafd/misc/dllmain.c
- * PURPOSE:     DLL entry point
- * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
- *              Alex Ionescu (alex@relsoft.net)
- * REVISIONS:
- *              CSH 01/09-2000 Created
- *              Alex 16/07/2004 - Complete Rewrite
- */
-
-#include <msafd.h>
-
-#include <winuser.h>
-#include <wchar.h>
-
-#include <wine/debug.h>
-WINE_DEFAULT_DEBUG_CHANNEL(msafd);
-
-HANDLE GlobalHeap;
-WSPUPCALLTABLE Upcalls;
-DWORD CatalogEntryId; /* CatalogEntryId for upcalls */
-LPWPUCOMPLETEOVERLAPPEDREQUEST lpWPUCompleteOverlappedRequest;
-PSOCKET_INFORMATION SocketListHead = NULL;
-CRITICAL_SECTION SocketListLock;
-LIST_ENTRY SockHelpersListHead = { NULL, NULL };
-ULONG SockAsyncThreadRefCount;
-HANDLE SockAsyncHelperAfdHandle;
-HANDLE SockAsyncCompletionPort = NULL;
-BOOLEAN SockAsyncSelectCalled;
-
-
-
-/*
- * FUNCTION: Creates a new socket
- * ARGUMENTS:
- *     af             = Address family
- *     type           = Socket type
- *     protocol       = Protocol type
- *     lpProtocolInfo = Pointer to protocol information
- *     g              = Reserved
- *     dwFlags        = Socket flags
- *     lpErrno        = Address of buffer for error information
- * RETURNS:
- *     Created socket, or INVALID_SOCKET if it could not be created
- */
-SOCKET
-WSPAPI
-WSPSocket(int AddressFamily,
-          int SocketType,
-          int Protocol,
-          LPWSAPROTOCOL_INFOW lpProtocolInfo,
-          GROUP g,
-          DWORD dwFlags,
-          LPINT lpErrno)
-{
-    OBJECT_ATTRIBUTES           Object;
-    IO_STATUS_BLOCK             IOSB;
-    USHORT                      SizeOfPacket;
-    ULONG                       SizeOfEA;
-    PAFD_CREATE_PACKET          AfdPacket;
-    HANDLE                      Sock;
-    PSOCKET_INFORMATION         Socket = NULL;
-    PFILE_FULL_EA_INFORMATION   EABuffer = NULL;
-    PHELPER_DATA                HelperData;
-    PVOID                       HelperDLLContext;
-    DWORD                       HelperEvents;
-    UNICODE_STRING              TransportName;
-    UNICODE_STRING              DevName;
-    LARGE_INTEGER               GroupData;
-    INT                         Status;
-    PSOCK_SHARED_INFO           SharedData = NULL;
-
-    TRACE("Creating Socket, getting TDI Name - AddressFamily (%d)  SocketType (%d)  Protocol (%d).\n",
-        AddressFamily, SocketType, Protocol);
-
-    if (lpProtocolInfo && lpProtocolInfo->dwServiceFlags3 != 0 && lpProtocolInfo->dwServiceFlags4 != 0)
-    {
-        /* Duplpicating socket from different process */
-        if ((HANDLE)lpProtocolInfo->dwServiceFlags3 == INVALID_HANDLE_VALUE)
-        {
-            Status = WSAEINVAL;
-            goto error;
-        }
-        if ((HANDLE)lpProtocolInfo->dwServiceFlags4 == INVALID_HANDLE_VALUE)
-        {
-            Status = WSAEINVAL;
-            goto error;
-        }
-        SharedData = MapViewOfFile((HANDLE)lpProtocolInfo->dwServiceFlags3,
-                                   FILE_MAP_ALL_ACCESS,
-                                   0,
-                                   0,
-                                   sizeof(SOCK_SHARED_INFO));
-        if (!SharedData)
-        {
-            Status = WSAEINVAL;
-            goto error;
-        }
-        InterlockedIncrement(&SharedData->RefCount);
-        AddressFamily = SharedData->AddressFamily;
-        SocketType = SharedData->SocketType;
-        Protocol = SharedData->Protocol;
-    }
-
-    if (AddressFamily == AF_UNSPEC && SocketType == 0 && Protocol == 0)
-    {
-        Status = WSAEINVAL;
-        goto error;
-    }
-
-    /* Set the defaults */
-    if (AddressFamily == AF_UNSPEC)
-        AddressFamily = AF_INET;
-
-    if (SocketType == 0)
-    {
-        switch (Protocol)
-        {
-        case IPPROTO_TCP:
-            SocketType = SOCK_STREAM;
-            break;
-        case IPPROTO_UDP:
-            SocketType = SOCK_DGRAM;
-            break;
-        case IPPROTO_RAW:
-            SocketType = SOCK_RAW;
-            break;
-        default:
-            TRACE("Unknown Protocol (%d). We will try SOCK_STREAM.\n", Protocol);
-            SocketType = SOCK_STREAM;
-            break;
-        }
-    }
-
-    if (Protocol == 0)
-    {
-        switch (SocketType)
-        {
-        case SOCK_STREAM:
-            Protocol = IPPROTO_TCP;
-            break;
-        case SOCK_DGRAM:
-            Protocol = IPPROTO_UDP;
-            break;
-        case SOCK_RAW:
-            Protocol = IPPROTO_RAW;
-            break;
-        default:
-            TRACE("Unknown SocketType (%d). We will try IPPROTO_TCP.\n", SocketType);
-            Protocol = IPPROTO_TCP;
-            break;
-        }
-    }
-
-    /* Get Helper Data and Transport */
-    Status = SockGetTdiName (&AddressFamily,
-                             &SocketType,
-                             &Protocol,
-                             g,
-                             dwFlags,
-                             &TransportName,
-                             &HelperDLLContext,
-                             &HelperData,
-                             &HelperEvents);
-
-    /* Check for error */
-    if (Status != NO_ERROR)
-    {
-        ERR("SockGetTdiName: Status %x\n", Status);
-        goto error;
-    }
-
-    /* AFD Device Name */
-    RtlInitUnicodeString(&DevName, L"\\Device\\Afd\\Endpoint");
-
-    /* Set Socket Data */
-    Socket = HeapAlloc(GlobalHeap, 0, sizeof(*Socket));
-    if (!Socket)
-    {
-        Status = WSAENOBUFS;
-        goto error;
-    }
-    RtlZeroMemory(Socket, sizeof(*Socket));
-    if (SharedData)
-    {
-        Socket->SharedData = SharedData;
-        Socket->SharedDataHandle = (HANDLE)lpProtocolInfo->dwServiceFlags3;
-        Sock = (HANDLE)lpProtocolInfo->dwServiceFlags4;
-        Socket->Handle = (SOCKET)lpProtocolInfo->dwServiceFlags4;
-    }
-    else
-    {
-        Socket->SharedDataHandle = INVALID_HANDLE_VALUE;
-        Socket->SharedData = HeapAlloc(GlobalHeap, 0, sizeof(*Socket->SharedData));
-        if (!Socket->SharedData)
-        {
-            Status = WSAENOBUFS;
-            goto error;
-        }
-        RtlZeroMemory(Socket->SharedData, sizeof(*Socket->SharedData));
-        Socket->SharedData->State = SocketOpen;
-        Socket->SharedData->RefCount = 1L;
-        Socket->SharedData->Listening = FALSE;
-        Socket->SharedData->AddressFamily = AddressFamily;
-        Socket->SharedData->SocketType = SocketType;
-        Socket->SharedData->Protocol = Protocol;
-        Socket->SharedData->SizeOfLocalAddress = HelperData->MaxWSAddressLength;
-        Socket->SharedData->SizeOfRemoteAddress = HelperData->MaxWSAddressLength;
-        Socket->SharedData->UseDelayedAcceptance = HelperData->UseDelayedAcceptance;
-        Socket->SharedData->CreateFlags = dwFlags;
-        Socket->SharedData->ServiceFlags1 = lpProtocolInfo->dwServiceFlags1;
-        Socket->SharedData->ProviderFlags = lpProtocolInfo->dwProviderFlags;
-        Socket->SharedData->UseSAN = FALSE;
-        Socket->SharedData->NonBlocking = FALSE; /* Sockets start blocking */
-        Socket->SharedData->RecvTimeout = INFINITE;
-        Socket->SharedData->SendTimeout = INFINITE;
-        Socket->SharedData->OobInline = FALSE;
-
-        /* Ask alex about this */
-        if( Socket->SharedData->SocketType == SOCK_DGRAM ||
-            Socket->SharedData->SocketType == SOCK_RAW )
-        {
-            TRACE("Connectionless socket\n");
-            Socket->SharedData->ServiceFlags1 |= XP1_CONNECTIONLESS;
-        }
-        Socket->Handle = INVALID_SOCKET;
-    }
-
-    Socket->HelperContext = HelperDLLContext;
-    Socket->HelperData = HelperData;
-    Socket->HelperEvents = HelperEvents;
-    Socket->LocalAddress = &Socket->SharedData->WSLocalAddress;
-    Socket->RemoteAddress = &Socket->SharedData->WSRemoteAddress;
-    Socket->SanData = NULL;
-    RtlCopyMemory(&Socket->ProtocolInfo, lpProtocolInfo, sizeof(Socket->ProtocolInfo));
-    if (SharedData)
-        goto ok;
-
-    /* Packet Size */
-    SizeOfPacket = TransportName.Length + sizeof(AFD_CREATE_PACKET) + sizeof(WCHAR);
-
-    /* EA Size */
-    SizeOfEA = SizeOfPacket + sizeof(FILE_FULL_EA_INFORMATION) + AFD_PACKET_COMMAND_LENGTH;
-
-    /* Set up EA Buffer */
-    EABuffer = HeapAlloc(GlobalHeap, 0, SizeOfEA);
-    if (!EABuffer)
-    {
-        Status = WSAENOBUFS;
-        goto error;
-    }
-
-    RtlZeroMemory(EABuffer, SizeOfEA);
-    EABuffer->NextEntryOffset = 0;
-    EABuffer->Flags = 0;
-    EABuffer->EaNameLength = AFD_PACKET_COMMAND_LENGTH;
-    RtlCopyMemory (EABuffer->EaName,
-                   AfdCommand,
-                   AFD_PACKET_COMMAND_LENGTH + 1);
-    EABuffer->EaValueLength = SizeOfPacket;
-
-    /* Set up AFD Packet */
-    AfdPacket = (PAFD_CREATE_PACKET)(EABuffer->EaName + EABuffer->EaNameLength + 1);
-    AfdPacket->SizeOfTransportName = TransportName.Length;
-    RtlCopyMemory (AfdPacket->TransportName,
-                   TransportName.Buffer,
-                   TransportName.Length + sizeof(WCHAR));
-    AfdPacket->GroupID = g;
-
-    /* Set up Endpoint Flags */
-    if ((Socket->SharedData->ServiceFlags1 & XP1_CONNECTIONLESS) != 0)
-    {
-        if ((SocketType != SOCK_DGRAM) && (SocketType != SOCK_RAW))
-        {
-            /* Only RAW or UDP can be Connectionless */
-            Status = WSAEINVAL;
-            goto error;
-        }
-        AfdPacket->EndpointFlags |= AFD_ENDPOINT_CONNECTIONLESS;
-    }
-
-    if ((Socket->SharedData->ServiceFlags1 & XP1_MESSAGE_ORIENTED) != 0)
-    {
-        if (SocketType == SOCK_STREAM)
-        {
-            if ((Socket->SharedData->ServiceFlags1 & XP1_PSEUDO_STREAM) == 0)
-            {
-                /* The Provider doesn't actually support Message Oriented Streams */
-                Status = WSAEINVAL;
-                goto error;
-            }
-        }
-        AfdPacket->EndpointFlags |= AFD_ENDPOINT_MESSAGE_ORIENTED;
-    }
-
-    if (SocketType == SOCK_RAW) AfdPacket->EndpointFlags |= AFD_ENDPOINT_RAW;
-
-    if (dwFlags & (WSA_FLAG_MULTIPOINT_C_ROOT |
-                   WSA_FLAG_MULTIPOINT_C_LEAF |
-                   WSA_FLAG_MULTIPOINT_D_ROOT |
-                   WSA_FLAG_MULTIPOINT_D_LEAF))
-    {
-        if ((Socket->SharedData->ServiceFlags1 & XP1_SUPPORT_MULTIPOINT) == 0)
-        {
-            /* The Provider doesn't actually support Multipoint */
-            Status = WSAEINVAL;
-            goto error;
-        }
-        AfdPacket->EndpointFlags |= AFD_ENDPOINT_MULTIPOINT;
-
-        if (dwFlags & WSA_FLAG_MULTIPOINT_C_ROOT)
-        {
-            if (((Socket->SharedData->ServiceFlags1 & XP1_MULTIPOINT_CONTROL_PLANE) == 0)
-                || ((dwFlags & WSA_FLAG_MULTIPOINT_C_LEAF) != 0))
-            {
-                /* The Provider doesn't support Control Planes, or you already gave a leaf */
-                Status = WSAEINVAL;
-                goto error;
-            }
-            AfdPacket->EndpointFlags |= AFD_ENDPOINT_C_ROOT;
-        }
-
-        if (dwFlags & WSA_FLAG_MULTIPOINT_D_ROOT)
-        {
-            if (((Socket->SharedData->ServiceFlags1 & XP1_MULTIPOINT_DATA_PLANE) == 0)
-                || ((dwFlags & WSA_FLAG_MULTIPOINT_D_LEAF) != 0))
-            {
-                /* The Provider doesn't support Data Planes, or you already gave a leaf */
-                Status = WSAEINVAL;
-                goto error;
-            }
-            AfdPacket->EndpointFlags |= AFD_ENDPOINT_D_ROOT;
-        }
-    }
-
-    /* Set up Object Attributes */
-    InitializeObjectAttributes (&Object,
-                                &DevName,
-                                OBJ_CASE_INSENSITIVE | OBJ_INHERIT,
-                                0,
-                                0);
-
-    /* Create the Socket as asynchronous. That means we have to block
-    ourselves after every call to NtDeviceIoControlFile. This is
-    because the kernel doesn't support overlapping synchronous I/O
-    requests (made from multiple threads) at this time (Sep 2005) */
-    Status = NtCreateFile(&Sock,
-                          GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
-                          &Object,
-                          &IOSB,
-                          NULL,
-                          0,
-                          FILE_SHARE_READ | FILE_SHARE_WRITE,
-                          FILE_OPEN_IF,
-                          0,
-                          EABuffer,
-                          SizeOfEA);
-
-    HeapFree(GlobalHeap, 0, EABuffer);
-
-    if (!NT_SUCCESS(Status))
-    {
-        ERR("Failed to open socket. Status 0x%08x\n", Status);
-        Status = TranslateNtStatusError(Status);
-        goto error;
-    }
-
-    /* Save Handle */
-    Socket->Handle = (SOCKET)Sock;
-
-    /* Save Group Info */
-    if (g != 0)
-    {
-        GetSocketInformation(Socket,
-                             AFD_INFO_GROUP_ID_TYPE,
-                             NULL,
-                             NULL,
-                             &GroupData,
-                             NULL,
-                             NULL);
-        Socket->SharedData->GroupID = GroupData.u.LowPart;
-        Socket->SharedData->GroupType = GroupData.u.HighPart;
-    }
-
-    /* Get Window Sizes and Save them */
-    GetSocketInformation (Socket,
-                          AFD_INFO_SEND_WINDOW_SIZE,
-                          NULL,
-                          &Socket->SharedData->SizeOfSendBuffer,
-                          NULL,
-                          NULL,
-                          NULL);
-
-    GetSocketInformation (Socket,
-                          AFD_INFO_RECEIVE_WINDOW_SIZE,
-                          NULL,
-                          &Socket->SharedData->SizeOfRecvBuffer,
-                          NULL,
-                          NULL,
-                          NULL);
-ok:
-
-    /* Save in Process Sockets List */
-    EnterCriticalSection(&SocketListLock);
-    Socket->NextSocket = SocketListHead;
-    SocketListHead = Socket;
-    LeaveCriticalSection(&SocketListLock);
-
-    /* Create the Socket Context */
-    CreateContext(Socket);
-
-    /* Notify Winsock */
-    Upcalls.lpWPUModifyIFSHandle(Socket->ProtocolInfo.dwCatalogEntryId, (SOCKET)Sock, lpErrno);
-
-    /* Return Socket Handle */
-    TRACE("Success %x\n", Sock);
-
-    return (SOCKET)Sock;
-
-error:
-    ERR("Ending %x\n", Status);
-
-    if( SharedData )
-    {
-        UnmapViewOfFile(SharedData);
-        NtClose((HANDLE)lpProtocolInfo->dwServiceFlags3);
-    }
-    else
-    {
-        if( Socket && Socket->SharedData )
-            HeapFree(GlobalHeap, 0, Socket->SharedData);
-    }
-
-    if( Socket )
-        HeapFree(GlobalHeap, 0, Socket);
-
-    if( EABuffer )
-        HeapFree(GlobalHeap, 0, EABuffer);
-
-    if( lpErrno )
-        *lpErrno = Status;
-
-    return INVALID_SOCKET;
-}
-
-
-INT
-WSPAPI
-WSPDuplicateSocket(
-    IN  SOCKET Handle,
-    IN  DWORD dwProcessId,
-    OUT LPWSAPROTOCOL_INFOW lpProtocolInfo,
-    OUT LPINT lpErrno)
-{
-    HANDLE hProcess, hDuplicatedSharedData, hDuplicatedHandle;
-    PSOCKET_INFORMATION Socket;
-    PSOCK_SHARED_INFO pSharedData, pOldSharedData;
-    BOOL bDuplicated;
-
-    if (Handle == INVALID_SOCKET)
-        return MsafdReturnWithErrno(STATUS_INVALID_PARAMETER, lpErrno, 0, NULL);
-    Socket = GetSocketStructure(Handle);
-    if( !Socket )
-    {
-        if( lpErrno )
-            *lpErrno = WSAENOTSOCK;
-        return SOCKET_ERROR;
-    }
-    if ( !(hProcess = OpenProcess(PROCESS_DUP_HANDLE, FALSE, dwProcessId)) )
-        return MsafdReturnWithErrno(STATUS_INVALID_PARAMETER, lpErrno, 0, NULL);
-
-    /* It is a not yet duplicated socket, so map the memory, copy the SharedData and free heap */
-    if( Socket->SharedDataHandle == INVALID_HANDLE_VALUE )
-    {
-        Socket->SharedDataHandle = CreateFileMapping(INVALID_HANDLE_VALUE,
-                                                     NULL,
-                                                     PAGE_READWRITE | SEC_COMMIT,
-                                                     0,
-                                                     (sizeof(SOCK_SHARED_INFO) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1),
-                                                     NULL);
-        if( Socket->SharedDataHandle == INVALID_HANDLE_VALUE )
-            return MsafdReturnWithErrno(STATUS_INSUFFICIENT_RESOURCES, lpErrno, 0, NULL);
-        pSharedData = MapViewOfFile(Socket->SharedDataHandle,
-                                    FILE_MAP_ALL_ACCESS,
-                                    0,
-                                    0,
-                                    sizeof(SOCK_SHARED_INFO));
-
-        RtlCopyMemory(pSharedData, Socket->SharedData, sizeof(SOCK_SHARED_INFO));
-        pOldSharedData = Socket->SharedData;
-        Socket->SharedData = pSharedData;
-        HeapFree(GlobalHeap, 0, pOldSharedData);
-    }
-    /* Duplicate the handles for the new process */
-    bDuplicated = DuplicateHandle(GetCurrentProcess(),
-                                  Socket->SharedDataHandle,
-                                  hProcess,
-                                  (LPHANDLE)&hDuplicatedSharedData,
-                                  0,
-                                  FALSE,
-                                  DUPLICATE_SAME_ACCESS);
-    if (!bDuplicated)
-    {
-        NtClose(hProcess);
-        return MsafdReturnWithErrno(STATUS_ACCESS_DENIED, lpErrno, 0, NULL);
-    }
-    bDuplicated = DuplicateHandle(GetCurrentProcess(),
-                                  (HANDLE)Socket->Handle,
-                                  hProcess,
-                                  (LPHANDLE)&hDuplicatedHandle,
-                                  0,
-                                  FALSE,
-                                  DUPLICATE_SAME_ACCESS);
-    NtClose(hProcess);
-    if( !bDuplicated )
-        return MsafdReturnWithErrno(STATUS_ACCESS_DENIED, lpErrno, 0, NULL);
-
-
-    if (!lpProtocolInfo)
-        return MsafdReturnWithErrno(STATUS_ACCESS_VIOLATION, lpErrno, 0, NULL);
-
-    RtlCopyMemory(lpProtocolInfo, &Socket->ProtocolInfo, sizeof(*lpProtocolInfo));
-
-    lpProtocolInfo->iAddressFamily = Socket->SharedData->AddressFamily;
-    lpProtocolInfo->iProtocol = Socket->SharedData->Protocol;
-    lpProtocolInfo->iSocketType = Socket->SharedData->SocketType;
-    lpProtocolInfo->dwServiceFlags3 = (DWORD)hDuplicatedSharedData;
-    lpProtocolInfo->dwServiceFlags4 = (DWORD)hDuplicatedHandle;
-
-    if( lpErrno )
-        *lpErrno = NO_ERROR;
-
-    return NO_ERROR;
-}
-
-INT
-TranslateNtStatusError(NTSTATUS Status)
-{
-    switch (Status)
-    {
-       case STATUS_CANT_WAIT:
-          return WSAEWOULDBLOCK;
-
-       case STATUS_TIMEOUT:
-          return WSAETIMEDOUT;
-
-       case STATUS_SUCCESS:
-          return NO_ERROR;
-
-       case STATUS_FILE_CLOSED:
-         return WSAECONNRESET;
-
-       case STATUS_END_OF_FILE:
-          return WSAESHUTDOWN;
-
-       case STATUS_PENDING:
-          return WSA_IO_PENDING;
-
-       case STATUS_BUFFER_TOO_SMALL:
-       case STATUS_BUFFER_OVERFLOW:
-          return WSAEMSGSIZE;
-
-       case STATUS_NO_MEMORY:
-       case STATUS_INSUFFICIENT_RESOURCES:
-          return WSAENOBUFS;
-
-       case STATUS_INVALID_CONNECTION:
-          return WSAENOTCONN;
-
-       case STATUS_PROTOCOL_NOT_SUPPORTED:
-          return WSAEAFNOSUPPORT;
-
-       case STATUS_INVALID_ADDRESS:
-          return WSAEADDRNOTAVAIL;
-
-       case STATUS_REMOTE_NOT_LISTENING:
-       case STATUS_REMOTE_DISCONNECT:
-          return WSAECONNREFUSED;
-
-       case STATUS_NETWORK_UNREACHABLE:
-          return WSAENETUNREACH;
-
-       case STATUS_INVALID_PARAMETER:
-          return WSAEINVAL;
-
-       case STATUS_CANCELLED:
-          return WSA_OPERATION_ABORTED;
-
-       case STATUS_ADDRESS_ALREADY_EXISTS:
-          return WSAEADDRINUSE;
-
-       case STATUS_LOCAL_DISCONNECT:
-          return WSAECONNABORTED;
-
-       case STATUS_ACCESS_VIOLATION:
-          return WSAEFAULT;
-
-       case STATUS_ACCESS_DENIED:
-          return WSAEACCES;
-
-       case STATUS_NOT_IMPLEMENTED:
-          return WSAEOPNOTSUPP;
-
-       default:
-          ERR("MSAFD: Unhandled NTSTATUS value: 0x%x\n", Status);
-          return WSAENETDOWN;
-    }
-}
-
-/*
- * FUNCTION: Closes an open socket
- * ARGUMENTS:
- *     s       = Socket descriptor
- *     lpErrno = Address of buffer for error information
- * RETURNS:
- *     NO_ERROR, or SOCKET_ERROR if the socket could not be closed
- */
-INT
-WSPAPI
-WSPCloseSocket(IN SOCKET Handle,
-               OUT LPINT lpErrno)
-{
-    IO_STATUS_BLOCK IoStatusBlock;
-    PSOCKET_INFORMATION Socket = NULL, CurrentSocket;
-    NTSTATUS Status;
-    HANDLE SockEvent;
-    AFD_DISCONNECT_INFO DisconnectInfo;
-    SOCKET_STATE OldState;
-    LONG LingerWait = -1;
-    DWORD References;
-
-    /* Get the Socket Structure associate to this Socket*/
-    Socket = GetSocketStructure(Handle);
-    if (!Socket)
-    {
-       if (lpErrno) *lpErrno = WSAENOTSOCK;
-       return SOCKET_ERROR;
-    }
-
-    /* Create the Wait Event */
-    Status = NtCreateEvent(&SockEvent,
-                           EVENT_ALL_ACCESS,
-                           NULL,
-                           1,
-                           FALSE);
-
-    if(!NT_SUCCESS(Status))
-    {
-        ERR("NtCreateEvent failed: 0x%08x", Status);
-        return SOCKET_ERROR;
-    }
-
-    if (Socket->HelperEvents & WSH_NOTIFY_CLOSE)
-    {
-        Status = Socket->HelperData->WSHNotify(Socket->HelperContext,
-                                               Socket->Handle,
-                                               Socket->TdiAddressHandle,
-                                               Socket->TdiConnectionHandle,
-                                               WSH_NOTIFY_CLOSE);
-
-        if (Status)
-        {
-            if (lpErrno) *lpErrno = Status;
-            ERR("WSHNotify failed. Error 0x%#x", Status);
-            NtClose(SockEvent);
-            return SOCKET_ERROR;
-        }
-    }
-
-    /* If a Close is already in Process, give up */
-    if (Socket->SharedData->State == SocketClosed)
-    {
-        WARN("Socket is closing.\n");
-        NtClose(SockEvent);
-        if (lpErrno) *lpErrno = WSAENOTSOCK;
-        return SOCKET_ERROR;
-    }
-
-    /* Decrement reference count on SharedData */
-    References = InterlockedDecrement(&Socket->SharedData->RefCount);
-    if (References)
-        goto ok;
-
-    /* Set the state to close */
-    OldState = Socket->SharedData->State;
-    Socket->SharedData->State = SocketClosed;
-
-    /* If SO_LINGER is ON and the Socket is connected, we need to disconnect */
-    /* FIXME: Should we do this on Datagram Sockets too? */
-    if ((OldState == SocketConnected) && (Socket->SharedData->LingerData.l_onoff))
-    {
-        ULONG SendsInProgress;
-        ULONG SleepWait;
-
-        /* We need to respect the timeout */
-        SleepWait = 100;
-        LingerWait = Socket->SharedData->LingerData.l_linger * 1000;
-
-        /* Loop until no more sends are pending, within the timeout */
-        while (LingerWait)
-        {
-            /* Find out how many Sends are in Progress */
-            if (GetSocketInformation(Socket,
-                                     AFD_INFO_SENDS_IN_PROGRESS,
-                                     NULL,
-                                     &SendsInProgress,
-                                     NULL,
-                                     NULL,
-                                     NULL))
-            {
-                /* Bail out if anything but NO_ERROR */
-                LingerWait = 0;
-                break;
-            }
-
-            /* Bail out if no more sends are pending */
-            if (!SendsInProgress)
-            {
-                LingerWait = -1;
-                break;
-            }
-
-            /*
-             * We have to execute a sleep, so it's kind of like
-             * a block. If the socket is Nonblock, we cannot
-             * go on since asynchronous operation is expected
-             * and we cannot offer it
-             */
-            if (Socket->SharedData->NonBlocking)
-            {
-                WARN("Would block!\n");
-                NtClose(SockEvent);
-                Socket->SharedData->State = OldState;
-                if (lpErrno) *lpErrno = WSAEWOULDBLOCK;
-                return SOCKET_ERROR;
-            }
-
-            /* Now we can sleep, and decrement the linger wait */
-            /*
-            * FIXME: It seems Windows does some funky acceleration
-            * since the waiting seems to be longer and longer. I
-            * don't think this improves performance so much, so we
-            * wait a fixed time instead.
-            */
-            Sleep(SleepWait);
-            LingerWait -= SleepWait;
-        }
-    }
-
-    if (OldState == SocketConnected)
-    {
-        if (LingerWait <= 0)
-        {
-            DisconnectInfo.Timeout = RtlConvertLongToLargeInteger(0);
-            DisconnectInfo.DisconnectType = LingerWait < 0 ? AFD_DISCONNECT_SEND : AFD_DISCONNECT_ABORT;
-
-            if (((DisconnectInfo.DisconnectType & AFD_DISCONNECT_SEND) && (!Socket->SharedData->SendShutdown)) ||
-                ((DisconnectInfo.DisconnectType & AFD_DISCONNECT_ABORT) && (!Socket->SharedData->ReceiveShutdown)))
-            {
-                /* Send IOCTL */
-                Status = NtDeviceIoControlFile((HANDLE)Handle,
-                                               SockEvent,
-                                               NULL,
-                                               NULL,
-                                               &IoStatusBlock,
-                                               IOCTL_AFD_DISCONNECT,
-                                               &DisconnectInfo,
-                                               sizeof(DisconnectInfo),
-                                               NULL,
-                                               0);
-
-                /* Wait for return */
-                if (Status == STATUS_PENDING)
-                {
-                    WaitForSingleObject(SockEvent, INFINITE);
-                    Status = IoStatusBlock.Status;
-                }
-            }
-        }
-    }
-
-    /* Cleanup Time! */
-    Socket->HelperContext = NULL;
-    Socket->SharedData->AsyncDisabledEvents = -1;
-    NtClose(Socket->TdiAddressHandle);
-    Socket->TdiAddressHandle = NULL;
-    NtClose(Socket->TdiConnectionHandle);
-    Socket->TdiConnectionHandle = NULL;
-ok:
-    EnterCriticalSection(&SocketListLock);
-    if (SocketListHead == Socket)
-    {
-        SocketListHead = SocketListHead->NextSocket;
-    }
-    else
-    {
-        CurrentSocket = SocketListHead;
-        while (CurrentSocket->NextSocket)
-        {
-            if (CurrentSocket->NextSocket == Socket)
-            {
-                CurrentSocket->NextSocket = CurrentSocket->NextSocket->NextSocket;
-                break;
-            }
-
-            CurrentSocket = CurrentSocket->NextSocket;
-        }
-    }
-    LeaveCriticalSection(&SocketListLock);
-
-    /* Close the handle */
-    NtClose((HANDLE)Handle);
-    NtClose(SockEvent);
-
-    if( Socket->SharedDataHandle != INVALID_HANDLE_VALUE )
-    {
-        /* It is a duplicated socket, so unmap the memory */
-        UnmapViewOfFile(Socket->SharedData);
-        NtClose(Socket->SharedDataHandle);
-        Socket->SharedData = NULL;
-    }
-    if( !References && Socket->SharedData )
-    {
-        HeapFree(GlobalHeap, 0, Socket->SharedData);
-    }
-    HeapFree(GlobalHeap, 0, Socket);
-    return MsafdReturnWithErrno(Status, lpErrno, 0, NULL);
-}
-
-
-/*
- * FUNCTION: Associates a local address with a socket
- * ARGUMENTS:
- *     s       = Socket descriptor
- *     name    = Pointer to local address
- *     namelen = Length of name
- *     lpErrno = Address of buffer for error information
- * RETURNS:
- *     0, or SOCKET_ERROR if the socket could not be bound
- */
-INT
-WSPAPI
-WSPBind(SOCKET Handle,
-        const struct sockaddr *SocketAddress,
-        int SocketAddressLength,
-        LPINT lpErrno)
-{
-    IO_STATUS_BLOCK         IOSB;
-    PAFD_BIND_DATA          BindData;
-    PSOCKET_INFORMATION     Socket = NULL;
-    NTSTATUS                Status;
-    SOCKADDR_INFO           SocketInfo;
-    HANDLE                  SockEvent;
-
-    /* Get the Socket Structure associate to this Socket*/
-    Socket = GetSocketStructure(Handle);
-    if (!Socket)
-    {
-       if (lpErrno) *lpErrno = WSAENOTSOCK;
-       return SOCKET_ERROR;
-    }
-    if (Socket->SharedData->State != SocketOpen)
-    {
-       if (lpErrno) *lpErrno = WSAEINVAL;
-       return SOCKET_ERROR;
-    }
-    if (!SocketAddress || SocketAddressLength < Socket->SharedData->SizeOfLocalAddress)
-    {
-        if (lpErrno) *lpErrno = WSAEINVAL;
-        return SOCKET_ERROR;
-    }
-
-    /* Get Address Information */
-    Socket->HelperData->WSHGetSockaddrType ((PSOCKADDR)SocketAddress,
-                                            SocketAddressLength,
-                                            &SocketInfo);
-
-    if (SocketInfo.AddressInfo == SockaddrAddressInfoBroadcast && !Socket->SharedData->Broadcast)
-    {
-       if (lpErrno) *lpErrno = WSAEADDRNOTAVAIL;
-       return SOCKET_ERROR;
-    }
-
-    Status = NtCreateEvent(&SockEvent,
-                           EVENT_ALL_ACCESS,
-                           NULL,
-                           1,
-                           FALSE);
-
-    if (!NT_SUCCESS(Status))
-    {
-        return SOCKET_ERROR;
-    }
-
-    /* See below */
-    BindData = HeapAlloc(GlobalHeap, 0, 0xA + SocketAddressLength);
-    if (!BindData)
-    {
-        return MsafdReturnWithErrno(STATUS_INSUFFICIENT_RESOURCES, lpErrno, 0, NULL);
-    }
-
-    /* Set up Address in TDI Format */
-    BindData->Address.TAAddressCount = 1;
-    BindData->Address.Address[0].AddressLength = SocketAddressLength - sizeof(SocketAddress->sa_family);
-    BindData->Address.Address[0].AddressType = SocketAddress->sa_family;
-    RtlCopyMemory (BindData->Address.Address[0].Address,
-                   SocketAddress->sa_data,
-                   SocketAddressLength - sizeof(SocketAddress->sa_family));
-
-    /* Set the Share Type */
-    if (Socket->SharedData->ExclusiveAddressUse)
-    {
-        BindData->ShareType = AFD_SHARE_EXCLUSIVE;
-    }
-    else if (SocketInfo.EndpointInfo == SockaddrEndpointInfoWildcard)
-    {
-        BindData->ShareType = AFD_SHARE_WILDCARD;
-    }
-    else if (Socket->SharedData->ReuseAddresses)
-    {
-        BindData->ShareType = AFD_SHARE_REUSE;
-    }
-    else
-    {
-        BindData->ShareType = AFD_SHARE_UNIQUE;
-    }
-
-    /* Send IOCTL */
-    Status = NtDeviceIoControlFile((HANDLE)Socket->Handle,
-                                   SockEvent,
-                                   NULL,
-                                   NULL,
-                                   &IOSB,
-                                   IOCTL_AFD_BIND,
-                                   BindData,
-                                   0xA + Socket->SharedData->SizeOfLocalAddress, /* Can't figure out a way to calculate this in C*/
-                                   BindData,
-                                   0xA + Socket->SharedData->SizeOfLocalAddress); /* Can't figure out a way to calculate this C */
-
-    /* Wait for return */
-    if (Status == STATUS_PENDING)
-    {
-        WaitForSingleObject(SockEvent, INFINITE);
-        Status = IOSB.Status;
-    }
-
-    NtClose( SockEvent );
-    HeapFree(GlobalHeap, 0, BindData);
-
-    Socket->SharedData->SocketLastError = TranslateNtStatusError(Status);
-    if (Status != STATUS_SUCCESS)
-        return MsafdReturnWithErrno ( Status, lpErrno, 0, NULL );
-
-    /* Set up Socket Data */
-    Socket->SharedData->State = SocketBound;
-    Socket->TdiAddressHandle = (HANDLE)IOSB.Information;
-
-    if (Socket->HelperEvents & WSH_NOTIFY_BIND)
-    {
-        Status = Socket->HelperData->WSHNotify(Socket->HelperContext,
-                                               Socket->Handle,
-                                               Socket->TdiAddressHandle,
-                                               Socket->TdiConnectionHandle,
-                                               WSH_NOTIFY_BIND);
-
-        if (Status)
-        {
-            if (lpErrno) *lpErrno = Status;
-            return SOCKET_ERROR;
-        }
-    }
-
-    return MsafdReturnWithErrno ( Status, lpErrno, 0, NULL );
-}
-
-int
-WSPAPI
-WSPListen(SOCKET Handle,
-          int Backlog,
-          LPINT lpErrno)
-{
-    IO_STATUS_BLOCK         IOSB;
-    AFD_LISTEN_DATA         ListenData;
-    PSOCKET_INFORMATION     Socket = NULL;
-    HANDLE                  SockEvent;
-    NTSTATUS                Status;
-
-    /* Get the Socket Structure associate to this Socket*/
-    Socket = GetSocketStructure(Handle);
-    if (!Socket)
-    {
-       if (lpErrno) *lpErrno = WSAENOTSOCK;
-       return SOCKET_ERROR;
-    }
-
-    if (Socket->SharedData->Listening)
-        return NO_ERROR;
-
-    Status = NtCreateEvent(&SockEvent,
-                           EVENT_ALL_ACCESS,
-                           NULL,
-                           1,
-                           FALSE);
-
-    if( !NT_SUCCESS(Status) )
-        return SOCKET_ERROR;
-
-    /* Set Up Listen Structure */
-    ListenData.UseSAN = FALSE;
-    ListenData.UseDelayedAcceptance = Socket->SharedData->UseDelayedAcceptance;
-    ListenData.Backlog = Backlog;
-
-    /* Send IOCTL */
-    Status = NtDeviceIoControlFile((HANDLE)Socket->Handle,
-                                   SockEvent,
-                                   NULL,
-                                   NULL,
-                                   &IOSB,
-                                   IOCTL_AFD_START_LISTEN,
-                                   &ListenData,
-                                   sizeof(ListenData),
-                                   NULL,
-                                   0);
-
-    /* Wait for return */
-    if (Status == STATUS_PENDING)
-    {
-        WaitForSingleObject(SockEvent, INFINITE);
-        Status = IOSB.Status;
-    }
-
-    NtClose( SockEvent );
-
-    Socket->SharedData->SocketLastError = TranslateNtStatusError(Status);
-    if (Status != STATUS_SUCCESS)
-       return MsafdReturnWithErrno ( Status, lpErrno, 0, NULL );
-
-    /* Set to Listening */
-    Socket->SharedData->Listening = TRUE;
-
-    if (Socket->HelperEvents & WSH_NOTIFY_LISTEN)
-    {
-        Status = Socket->HelperData->WSHNotify(Socket->HelperContext,
-                                               Socket->Handle,
-                                               Socket->TdiAddressHandle,
-                                               Socket->TdiConnectionHandle,
-                                               WSH_NOTIFY_LISTEN);
-
-        if (Status)
-        {
-           if (lpErrno) *lpErrno = Status;
-           return SOCKET_ERROR;
-        }
-    }
-
-    return MsafdReturnWithErrno ( Status, lpErrno, 0, NULL );
-}
-
-
-int
-WSPAPI
-WSPSelect(IN int nfds,
-          IN OUT fd_set *readfds OPTIONAL,
-          IN OUT fd_set *writefds OPTIONAL,
-          IN OUT fd_set *exceptfds OPTIONAL,
-          IN const struct timeval *timeout OPTIONAL,
-          OUT LPINT lpErrno)
-{
-    IO_STATUS_BLOCK     IOSB;
-    PAFD_POLL_INFO      PollInfo;
-    NTSTATUS            Status;
-    ULONG               HandleCount;
-    ULONG               PollBufferSize;
-    PVOID               PollBuffer;
-    ULONG               i, j = 0, x;
-    HANDLE              SockEvent;
-    LARGE_INTEGER       Timeout;
-    PSOCKET_INFORMATION Socket;
-    SOCKET              Handle;
-    ULONG               Events;
-    fd_set              selectfds;
-
-    /* Find out how many sockets we have, and how large the buffer needs
-     * to be */
-    FD_ZERO(&selectfds);
-    if (readfds != NULL)
-    {
-        for (i = 0; i < readfds->fd_count; i++)
-        {
-            FD_SET(readfds->fd_array[i], &selectfds);
-        }
-    }
-    if (writefds != NULL)
-    {
-        for (i = 0; i < writefds->fd_count; i++)
-        {
-            FD_SET(writefds->fd_array[i], &selectfds);
-        }
-    }
-    if (exceptfds != NULL)
-    {
-        for (i = 0; i < exceptfds->fd_count; i++)
-        {
-            FD_SET(exceptfds->fd_array[i], &selectfds);
-        }
-    }
-
-    HandleCount = selectfds.fd_count;
-
-    if ( HandleCount == 0 )
-    {
-        WARN("No handles! Returning SOCKET_ERROR\n", HandleCount);
-        if (lpErrno) *lpErrno = WSAEINVAL;
-        return SOCKET_ERROR;
-    }
-
-    PollBufferSize = sizeof(*PollInfo) + ((HandleCount - 1) * sizeof(AFD_HANDLE));
-
-    TRACE("HandleCount: %u BufferSize: %u\n", HandleCount, PollBufferSize);
-
-    /* Convert Timeout to NT Format */
-    if (timeout == NULL)
-    {
-        Timeout.u.LowPart = -1;
-        Timeout.u.HighPart = 0x7FFFFFFF;
-        TRACE("Infinite timeout\n");
-    }
-    else
-    {
-        Timeout = RtlEnlargedIntegerMultiply
-            ((timeout->tv_sec * 1000) + (timeout->tv_usec / 1000), -10000);
-        /* Negative timeouts are illegal.  Since the kernel represents an
-         * incremental timeout as a negative number, we check for a positive
-         * result.
-         */
-        if (Timeout.QuadPart > 0)
-        {
-            if (lpErrno) *lpErrno = WSAEINVAL;
-            return SOCKET_ERROR;
-        }
-        TRACE("Timeout: Orig %d.%06d kernel %d\n",
-                     timeout->tv_sec, timeout->tv_usec,
-                     Timeout.u.LowPart);
-    }
-
-    Status = NtCreateEvent(&SockEvent,
-                           EVENT_ALL_ACCESS,
-                           NULL,
-                           1,
-                           FALSE);
-
-    if(!NT_SUCCESS(Status))
-    {
-        if (lpErrno)
-            *lpErrno = WSAEFAULT;
-
-        ERR("NtCreateEvent failed, 0x%08x\n", Status);
-        return SOCKET_ERROR;
-    }
-
-    /* Allocate */
-    PollBuffer = HeapAlloc(GlobalHeap, 0, PollBufferSize);
-
-    if (!PollBuffer)
-    {
-        if (lpErrno)
-            *lpErrno = WSAEFAULT;
-        NtClose(SockEvent);
-        return SOCKET_ERROR;
-    }
-
-    PollInfo = (PAFD_POLL_INFO)PollBuffer;
-
-    RtlZeroMemory( PollInfo, PollBufferSize );
-
-    /* Number of handles for AFD to Check */
-    PollInfo->Exclusive = FALSE;
-    PollInfo->Timeout = Timeout;
-
-    for (i = 0; i < selectfds.fd_count; i++)
-    {
-        PollInfo->Handles[i].Handle = selectfds.fd_array[i];
-    }
-    if (readfds != NULL) {
-        for (i = 0; i < readfds->fd_count; i++)
-        {
-            for (j = 0; j < HandleCount; j++)
-            {
-                if (PollInfo->Handles[j].Handle == readfds->fd_array[i])
-                    break;
-            }
-            if (j >= HandleCount)
-            {
-                ERR("Error while counting readfds %ld > %ld\n", j, HandleCount);
-                if (lpErrno) *lpErrno = WSAEFAULT;
-                HeapFree(GlobalHeap, 0, PollBuffer);
-                NtClose(SockEvent);
-                return SOCKET_ERROR;
-            }
-            Socket = GetSocketStructure(readfds->fd_array[i]);
-            if (!Socket)
-            {
-                ERR("Invalid socket handle provided in readfds %d\n", readfds->fd_array[i]);
-                if (lpErrno) *lpErrno = WSAENOTSOCK;
-                HeapFree(GlobalHeap, 0, PollBuffer);
-                NtClose(SockEvent);
-                return SOCKET_ERROR;
-            }
-            PollInfo->Handles[j].Events |= AFD_EVENT_RECEIVE |
-                                           AFD_EVENT_DISCONNECT |
-                                           AFD_EVENT_ABORT |
-                                           AFD_EVENT_CLOSE |
-                                           AFD_EVENT_ACCEPT;
-            //if (Socket->SharedData->OobInline != 0)
-            //    PollInfo->Handles[j].Events |= AFD_EVENT_OOB_RECEIVE;
-        }
-    }
-    if (writefds != NULL)
-    {
-        for (i = 0; i < writefds->fd_count; i++)
-        {
-            for (j = 0; j < HandleCount; j++)
-            {
-                if (PollInfo->Handles[j].Handle == writefds->fd_array[i])
-                    break;
-            }
-            if (j >= HandleCount)
-            {
-                ERR("Error while counting writefds %ld > %ld\n", j, HandleCount);
-                if (lpErrno) *lpErrno = WSAEFAULT;
-                HeapFree(GlobalHeap, 0, PollBuffer);
-                NtClose(SockEvent);
-                return SOCKET_ERROR;
-            }
-            Socket = GetSocketStructure(writefds->fd_array[i]);
-            if (!Socket)
-            {
-                ERR("Invalid socket handle provided in writefds %d\n", writefds->fd_array[i]);
-                if (lpErrno) *lpErrno = WSAENOTSOCK;
-                HeapFree(GlobalHeap, 0, PollBuffer);
-                NtClose(SockEvent);
-                return SOCKET_ERROR;
-            }
-            PollInfo->Handles[j].Handle = writefds->fd_array[i];
-            PollInfo->Handles[j].Events |= AFD_EVENT_SEND;
-            if (Socket->SharedData->NonBlocking != 0)
-                PollInfo->Handles[j].Events |= AFD_EVENT_CONNECT;
-        }
-    }
-    if (exceptfds != NULL)
-    {
-        for (i = 0; i < exceptfds->fd_count; i++)
-        {
-            for (j = 0; j < HandleCount; j++)
-            {
-                if (PollInfo->Handles[j].Handle == exceptfds->fd_array[i])
-                    break;
-            }
-            if (j > HandleCount)
-            {
-                ERR("Error while counting exceptfds %ld > %ld\n", j, HandleCount);
-                if (lpErrno) *lpErrno = WSAEFAULT;
-                HeapFree(GlobalHeap, 0, PollBuffer);
-                NtClose(SockEvent);
-                return SOCKET_ERROR;
-            }
-            Socket = GetSocketStructure(exceptfds->fd_array[i]);
-            if (!Socket)
-            {
-                TRACE("Invalid socket handle provided in exceptfds %d\n", exceptfds->fd_array[i]);
-                if (lpErrno) *lpErrno = WSAENOTSOCK;
-                HeapFree(GlobalHeap, 0, PollBuffer);
-                NtClose(SockEvent);
-                return SOCKET_ERROR;
-            }
-            PollInfo->Handles[j].Handle = exceptfds->fd_array[i];
-            if (Socket->SharedData->OobInline == 0)
-                PollInfo->Handles[j].Events |= AFD_EVENT_OOB_RECEIVE;
-            if (Socket->SharedData->NonBlocking != 0)
-                PollInfo->Handles[j].Events |= AFD_EVENT_CONNECT_FAIL;
-        }
-    }
-
-    PollInfo->HandleCount = HandleCount;
-    PollBufferSize = FIELD_OFFSET(AFD_POLL_INFO, Handles) + PollInfo->HandleCount * sizeof(AFD_HANDLE);
-
-    /* Send IOCTL */
-    Status = NtDeviceIoControlFile((HANDLE)PollInfo->Handles[0].Handle,
-                                   SockEvent,
-                                   NULL,
-                                   NULL,
-                                   &IOSB,
-                                   IOCTL_AFD_SELECT,
-                                   PollInfo,
-                                   PollBufferSize,
-                                   PollInfo,
-                                   PollBufferSize);
-
-    TRACE("DeviceIoControlFile => %x\n", Status);
-
-    /* Wait for Completion */
-    if (Status == STATUS_PENDING)
-    {
-        WaitForSingleObject(SockEvent, INFINITE);
-        Status = IOSB.Status;
-    }
-
-    /* Clear the Structures */
-    if( readfds )
-        FD_ZERO(readfds);
-    if( writefds )
-        FD_ZERO(writefds);
-    if( exceptfds )
-        FD_ZERO(exceptfds);
-
-    /* Loop through return structure */
-    HandleCount = PollInfo->HandleCount;
-
-    /* Return in FDSET Format */
-    for (i = 0; i < HandleCount; i++)
-    {
-        Events = PollInfo->Handles[i].Events;
-        Handle = PollInfo->Handles[i].Handle;
-        for(x = 1; x; x<<=1)
-        {
-            Socket = GetSocketStructure(Handle);
-            if (!Socket)
-            {
-                TRACE("Invalid socket handle found %d\n", Handle);
-                if (lpErrno) *lpErrno = WSAENOTSOCK;
-                HeapFree(GlobalHeap, 0, PollBuffer);
-                NtClose(SockEvent);
-                return SOCKET_ERROR;
-            }
-            switch (Events & x)
-            {
-                case AFD_EVENT_RECEIVE:
-                case AFD_EVENT_DISCONNECT:
-                case AFD_EVENT_ABORT:
-                case AFD_EVENT_ACCEPT:
-                case AFD_EVENT_CLOSE:
-                    TRACE("Event %x on handle %x\n",
-                        Events,
-                        Handle);
-                    if ((Events & x) == AFD_EVENT_DISCONNECT || (Events & x) == AFD_EVENT_CLOSE)
-                        Socket->SharedData->SocketLastError = WSAECONNRESET;
-                    if ((Events & x) == AFD_EVENT_ABORT)
-                        Socket->SharedData->SocketLastError = WSAECONNABORTED;
-                    if( readfds )
-                        FD_SET(Handle, readfds);
-                    break;
-                case AFD_EVENT_SEND:
-                    TRACE("Event %x on handle %x\n",
-                        Events,
-                        Handle);
-                    if (writefds)
-                        FD_SET(Handle, writefds);
-                    break;
-                case AFD_EVENT_CONNECT:
-                    TRACE("Event %x on handle %x\n",
-                        Events,
-                        Handle);
-                    if( writefds && Socket->SharedData->NonBlocking != 0 )
-                        FD_SET(Handle, writefds);
-                    break;
-                case AFD_EVENT_OOB_RECEIVE:
-                    TRACE("Event %x on handle %x\n",
-                        Events,
-                        Handle);
-                    if( readfds && Socket->SharedData->OobInline != 0 )
-                        FD_SET(Handle, readfds);
-                    if( exceptfds && Socket->SharedData->OobInline == 0 )
-                        FD_SET(Handle, exceptfds);
-                    break;
-                case AFD_EVENT_CONNECT_FAIL:
-                    TRACE("Event %x on handle %x\n",
-                        Events,
-                        Handle);
-                    if( exceptfds && Socket->SharedData->NonBlocking != 0 )
-                        FD_SET(Handle, exceptfds);
-                    break;
-            }
-        }
-    }
-
-    HeapFree( GlobalHeap, 0, PollBuffer );
-    NtClose( SockEvent );
-
-    if( lpErrno )
-    {
-        switch( IOSB.Status )
-        {
-            case STATUS_SUCCESS:
-            case STATUS_TIMEOUT:
-                *lpErrno = 0;
-                break;
-            default:
-                *lpErrno = WSAEINVAL;
-                break;
-        }
-        TRACE("*lpErrno = %x\n", *lpErrno);
-    }
-
-    HandleCount = (readfds ? readfds->fd_count : 0) +
-                  (writefds && writefds != readfds ? writefds->fd_count : 0) +
-                  (exceptfds && exceptfds != readfds && exceptfds != writefds ? exceptfds->fd_count : 0);
-
-    TRACE("%d events\n", HandleCount);
-
-    return HandleCount;
-}
-
-DWORD
-GetCurrentTimeInSeconds(VOID)
-{
-    SYSTEMTIME st1970 = { 1970, 1, 0, 1, 0, 0, 0, 0 };
-    union
-    {
-        FILETIME ft;
-        ULONGLONG ll;
-    } u1970, Time;
-
-    GetSystemTimeAsFileTime(&Time.ft);
-    SystemTimeToFileTime(&st1970, &u1970.ft);
-    return (DWORD)((Time.ll - u1970.ll) / 10000000ULL);
-}
-
-SOCKET
-WSPAPI
-WSPAccept(SOCKET Handle,
-          struct sockaddr *SocketAddress,
-          int *SocketAddressLength,
-          LPCONDITIONPROC lpfnCondition,
-          DWORD dwCallbackData,
-          LPINT lpErrno)
-{
-    IO_STATUS_BLOCK             IOSB;
-    PAFD_RECEIVED_ACCEPT_DATA   ListenReceiveData;
-    AFD_ACCEPT_DATA             AcceptData;
-    AFD_DEFER_ACCEPT_DATA       DeferData;
-    AFD_PENDING_ACCEPT_DATA     PendingAcceptData;
-    PSOCKET_INFORMATION         Socket = NULL;
-    NTSTATUS                    Status;
-    struct fd_set               ReadSet;
-    struct timeval              Timeout;
-    PVOID                       PendingData = NULL;
-    ULONG                       PendingDataLength = 0;
-    PVOID                       CalleeDataBuffer;
-    WSABUF                      CallerData, CalleeID, CallerID, CalleeData;
-    PSOCKADDR                   RemoteAddress =  NULL;
-    GROUP                       GroupID = 0;
-    ULONG                       CallBack;
-    SOCKET                      AcceptSocket;
-    PSOCKET_INFORMATION         AcceptSocketInfo;
-    UCHAR                       ReceiveBuffer[0x1A];
-    HANDLE                      SockEvent;
-
-    /* Get the Socket Structure associate to this Socket*/
-    Socket = GetSocketStructure(Handle);
-    if (!Socket)
-    {
-       if (lpErrno) *lpErrno = WSAENOTSOCK;
-       return SOCKET_ERROR;
-    }
-    if (!Socket->SharedData->Listening)
-    {
-       if (lpErrno) *lpErrno = WSAEINVAL;
-       return SOCKET_ERROR;
-    }
-    if ((SocketAddress && !SocketAddressLength) ||
-        (SocketAddressLength && !SocketAddress) ||
-        (SocketAddressLength && *SocketAddressLength < sizeof(SOCKADDR)))
-    {
-       if (lpErrno) *lpErrno = WSAEFAULT;
-       return INVALID_SOCKET;
-    }
-
-    Status = NtCreateEvent(&SockEvent,
-                           EVENT_ALL_ACCESS,
-                           NULL,
-                           1,
-                           FALSE);
-
-    if( !NT_SUCCESS(Status) )
-    {
-        return SOCKET_ERROR;
-    }
-
-    /* Dynamic Structure...ugh */
-    ListenReceiveData = (PAFD_RECEIVED_ACCEPT_DATA)ReceiveBuffer;
-
-    /* If this is non-blocking, make sure there's something for us to accept */
-    FD_ZERO(&ReadSet);
-    FD_SET(Socket->Handle, &ReadSet);
-    Timeout.tv_sec=0;
-    Timeout.tv_usec=0;
-
-    if (WSPSelect(0, &ReadSet, NULL, NULL, &Timeout, lpErrno) == SOCKET_ERROR)
-    {
-        NtClose(SockEvent);
-        return SOCKET_ERROR;
-    }
-
-    if (ReadSet.fd_array[0] != Socket->Handle)
-    {
-        NtClose(SockEvent);
-        if (lpErrno) *lpErrno = WSAEWOULDBLOCK;
-        return SOCKET_ERROR;
-    }
-
-    /* Send IOCTL */
-    Status = NtDeviceIoControlFile((HANDLE)Socket->Handle,
-                                   SockEvent,
-                                   NULL,
-                                   NULL,
-                                   &IOSB,
-                                   IOCTL_AFD_WAIT_FOR_LISTEN,
-                                   NULL,
-                                   0,
-                                   ListenReceiveData,
-                                   0xA + sizeof(*ListenReceiveData));
-
-    /* Wait for return */
-    if (Status == STATUS_PENDING)
-    {
-        WaitForSingleObject(SockEvent, INFINITE);
-        Status = IOSB.Status;
-    }
-
-    if (!NT_SUCCESS(Status))
-    {
-        NtClose( SockEvent );
-        return MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
-    }
-
-    if (lpfnCondition != NULL)
-    {
-        if ((Socket->SharedData->ServiceFlags1 & XP1_CONNECT_DATA) != 0)
-        {
-            /* Find out how much data is pending */
-            PendingAcceptData.SequenceNumber = ListenReceiveData->SequenceNumber;
-            PendingAcceptData.ReturnSize = TRUE;
-
-            /* Send IOCTL */
-            Status = NtDeviceIoControlFile((HANDLE)Socket->Handle,
-                                           SockEvent,
-                                           NULL,
-                                           NULL,
-                                           &IOSB,
-                                           IOCTL_AFD_GET_PENDING_CONNECT_DATA,
-                                           &PendingAcceptData,
-                                           sizeof(PendingAcceptData),
-                                           &PendingAcceptData,
-                                           sizeof(PendingAcceptData));
-
-            /* Wait for return */
-            if (Status == STATUS_PENDING)
-            {
-                WaitForSingleObject(SockEvent, INFINITE);
-                Status = IOSB.Status;
-            }
-
-            if (!NT_SUCCESS(Status))
-            {
-                NtClose( SockEvent );
-                return MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
-            }
-
-            /* How much data to allocate */
-            PendingDataLength = IOSB.Information;
-
-            if (PendingDataLength)
-            {
-                /* Allocate needed space */
-                PendingData = HeapAlloc(GlobalHeap, 0, PendingDataLength);
-                if (!PendingData)
-                {
-                    return MsafdReturnWithErrno( STATUS_INSUFFICIENT_RESOURCES, lpErrno, 0, NULL );
-                }
-
-                /* We want the data now */
-                PendingAcceptData.ReturnSize = FALSE;
-
-                /* Send IOCTL */
-                Status = NtDeviceIoControlFile((HANDLE)Socket->Handle,
-                                               SockEvent,
-                                               NULL,
-                                               NULL,
-                                               &IOSB,
-                                               IOCTL_AFD_GET_PENDING_CONNECT_DATA,
-                                               &PendingAcceptData,
-                                               sizeof(PendingAcceptData),
-                                               PendingData,
-                                               PendingDataLength);
-
-                /* Wait for return */
-                if (Status == STATUS_PENDING)
-                {
-                    WaitForSingleObject(SockEvent, INFINITE);
-                    Status = IOSB.Status;
-                }
-
-                if (!NT_SUCCESS(Status))
-                {
-                    NtClose( SockEvent );
-                    return MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
-                }
-            }
-        }
-
-        if ((Socket->SharedData->ServiceFlags1 & XP1_QOS_SUPPORTED) != 0)
-        {
-            /* I don't support this yet */
-        }
-
-        /* Build Callee ID */
-        CalleeID.buf = (PVOID)Socket->LocalAddress;
-        CalleeID.len = Socket->SharedData->SizeOfLocalAddress;
-
-        RemoteAddress = HeapAlloc(GlobalHeap, 0, sizeof(*RemoteAddress));
-        if (!RemoteAddress)
-        {
-            return MsafdReturnWithErrno(STATUS_INSUFFICIENT_RESOURCES, lpErrno, 0, NULL);
-        }
-
-        /* Set up Address in SOCKADDR Format */
-        RtlCopyMemory (RemoteAddress,
-                       &ListenReceiveData->Address.Address[0].AddressType,
-                       sizeof(*RemoteAddress));
-
-        /* Build Caller ID */
-        CallerID.buf = (PVOID)RemoteAddress;
-        CallerID.len = sizeof(*RemoteAddress);
-
-        /* Build Caller Data */
-        CallerData.buf = PendingData;
-        CallerData.len = PendingDataLength;
-
-        /* Check if socket supports Conditional Accept */
-        if (Socket->SharedData->UseDelayedAcceptance != 0)
-        {
-            /* Allocate Buffer for Callee Data */
-            CalleeDataBuffer = HeapAlloc(GlobalHeap, 0, 4096);
-            if (!CalleeDataBuffer) {
-                return MsafdReturnWithErrno( STATUS_INSUFFICIENT_RESOURCES, lpErrno, 0, NULL );
-            }
-            CalleeData.buf = CalleeDataBuffer;
-            CalleeData.len = 4096;
-        }
-        else
-        {
-            /* Nothing */
-            CalleeData.buf = 0;
-            CalleeData.len = 0;
-        }
-
-        /* Call the Condition Function */
-        CallBack = (lpfnCondition)(&CallerID,
-                                   CallerData.buf == NULL ? NULL : &CallerData,
-                                   NULL,
-                                   NULL,
-                                   &CalleeID,
-                                   CalleeData.buf == NULL ? NULL : &CalleeData,
-                                   &GroupID,
-                                   dwCallbackData);
-
-        if (((CallBack == CF_ACCEPT) && GroupID) != 0)
-        {
-            /* TBD: Check for Validity */
-        }
-
-        if (CallBack == CF_ACCEPT)
-        {
-            if ((Socket->SharedData->ServiceFlags1 & XP1_QOS_SUPPORTED) != 0)
-            {
-                /* I don't support this yet */
-            }
-            if (CalleeData.buf)
-            {
-                // SockSetConnectData Sockets(SocketID), IOCTL_AFD_SET_CONNECT_DATA, CalleeData.Buffer, CalleeData.BuffSize, 0
-            }
-        }
-        else
-        {
-            /* Callback rejected. Build Defer Structure */
-            DeferData.SequenceNumber = ListenReceiveData->SequenceNumber;
-            DeferData.RejectConnection = (CallBack == CF_REJECT);
-
-            /* Send IOCTL */
-            Status = NtDeviceIoControlFile((HANDLE)Socket->Handle,
-                                           SockEvent,
-                                           NULL,
-                                           NULL,
-                                           &IOSB,
-                                           IOCTL_AFD_DEFER_ACCEPT,
-                                           &DeferData,
-                                           sizeof(DeferData),
-                                           NULL,
-                                           0);
-
-            /* Wait for return */
-            if (Status == STATUS_PENDING)
-            {
-                WaitForSingleObject(SockEvent, INFINITE);
-                Status = IOSB.Status;
-            }
-
-            NtClose( SockEvent );
-
-            if (!NT_SUCCESS(Status))
-            {
-                return MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
-            }
-
-            if (CallBack == CF_REJECT )
-            {
-                if (lpErrno) *lpErrno = WSAECONNREFUSED;
-                return SOCKET_ERROR;
-            }
-            else
-            {
-                if (lpErrno) *lpErrno = WSAECONNREFUSED;
-                return SOCKET_ERROR;
-            }
-        }
-    }
-
-    /* Create a new Socket */
-    AcceptSocket = WSPSocket (Socket->SharedData->AddressFamily,
-                              Socket->SharedData->SocketType,
-                              Socket->SharedData->Protocol,
-                              &Socket->ProtocolInfo,
-                              GroupID,
-                              Socket->SharedData->CreateFlags,
-                              lpErrno);
-    if (AcceptSocket == INVALID_SOCKET)
-        return SOCKET_ERROR;
-
-    /* Set up the Accept Structure */
-    AcceptData.ListenHandle = (HANDLE)AcceptSocket;
-    AcceptData.SequenceNumber = ListenReceiveData->SequenceNumber;
-
-    /* Send IOCTL to Accept */
-    Status = NtDeviceIoControlFile((HANDLE)Socket->Handle,
-                                   SockEvent,
-                                   NULL,
-                                   NULL,
-                                   &IOSB,
-                                   IOCTL_AFD_ACCEPT,
-                                   &AcceptData,
-                                   sizeof(AcceptData),
-                                   NULL,
-                                   0);
-
-    /* Wait for return */
-    if (Status == STATUS_PENDING)
-    {
-        WaitForSingleObject(SockEvent, INFINITE);
-        Status = IOSB.Status;
-    }
-
-    Socket->SharedData->SocketLastError = TranslateNtStatusError(Status);
-    if (!NT_SUCCESS(Status))
-    {
-        NtClose(SockEvent);
-        WSPCloseSocket( AcceptSocket, lpErrno );
-        return MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
-    }
-
-    AcceptSocketInfo = GetSocketStructure(AcceptSocket);
-    if (!AcceptSocketInfo)
-    {
-        NtClose(SockEvent);
-        WSPCloseSocket( AcceptSocket, lpErrno );
-        return MsafdReturnWithErrno( STATUS_PROTOCOL_NOT_SUPPORTED, lpErrno, 0, NULL );
-    }
-
-    AcceptSocketInfo->SharedData->State = SocketConnected;
-    AcceptSocketInfo->SharedData->ConnectTime = GetCurrentTimeInSeconds();
-
-    /* Return Address in SOCKADDR FORMAT */
-    if( SocketAddress )
-    {
-        RtlCopyMemory (SocketAddress,
-                       &ListenReceiveData->Address.Address[0].AddressType,
-                       sizeof(*RemoteAddress));
-        if( SocketAddressLength )
-            *SocketAddressLength = sizeof(*RemoteAddress);
-    }
-
-    NtClose( SockEvent );
-
-    /* Re-enable Async Event */
-    SockReenableAsyncSelectEvent(Socket, FD_ACCEPT);
-
-    TRACE("Socket %x\n", AcceptSocket);
-
-    if (Status == STATUS_SUCCESS && (Socket->HelperEvents & WSH_NOTIFY_ACCEPT))
-    {
-        Status = Socket->HelperData->WSHNotify(Socket->HelperContext,
-                                               Socket->Handle,
-                                               Socket->TdiAddressHandle,
-                                               Socket->TdiConnectionHandle,
-                                               WSH_NOTIFY_ACCEPT);
-
-        if (Status)
-        {
-            if (lpErrno) *lpErrno = Status;
-            return SOCKET_ERROR;
-        }
-    }
-
-    if (lpErrno) *lpErrno = NO_ERROR;
-
-    /* Return Socket */
-    return AcceptSocket;
-}
-
-int
-WSPAPI
-WSPConnect(SOCKET Handle,
-           const struct sockaddr * SocketAddress,
-           int SocketAddressLength,
-           LPWSABUF lpCallerData,
-           LPWSABUF lpCalleeData,
-           LPQOS lpSQOS,
-           LPQOS lpGQOS,
-           LPINT lpErrno)
-{
-    IO_STATUS_BLOCK         IOSB;
-    PAFD_CONNECT_INFO       ConnectInfo = NULL;
-    PSOCKET_INFORMATION     Socket;
-    NTSTATUS                Status;
-    INT                     Errno;
-    ULONG                   ConnectDataLength;
-    ULONG                   InConnectDataLength;
-    INT                     BindAddressLength;
-    PSOCKADDR               BindAddress;
-    HANDLE                  SockEvent;
-    int                     SocketDataLength;
-
-    TRACE("Called (%lx) %lx:%d\n", Handle, ((const struct sockaddr_in *)SocketAddress)->sin_addr, ((const struct sockaddr_in *)SocketAddress)->sin_port);
-
-    /* Get the Socket Structure associate to this Socket*/
-    Socket = GetSocketStructure(Handle);
-    if (!Socket)
-    {
-        if (lpErrno) *lpErrno = WSAENOTSOCK;
-        return SOCKET_ERROR;
-    }
-
-    Status = NtCreateEvent(&SockEvent,
-                           EVENT_ALL_ACCESS,
-                           NULL,
-                           1,
-                           FALSE);
-
-    if (!NT_SUCCESS(Status))
-        return SOCKET_ERROR;
-
-    /* Bind us First */
-    if (Socket->SharedData->State == SocketOpen)
-    {
-        /* Get the Wildcard Address */
-        BindAddressLength = Socket->HelperData->MaxWSAddressLength;
-        BindAddress = HeapAlloc(GetProcessHeap(), 0, BindAddressLength);
-        if (!BindAddress)
-        {
-            NtClose(SockEvent);
-            return MsafdReturnWithErrno(STATUS_INSUFFICIENT_RESOURCES, lpErrno, 0, NULL);
-        }
-        Socket->HelperData->WSHGetWildcardSockaddr (Socket->HelperContext,
-                                                    BindAddress,
-                                                    &BindAddressLength);
-        /* Bind it */
-        if (WSPBind(Handle, BindAddress, BindAddressLength, lpErrno) == SOCKET_ERROR)
-            return SOCKET_ERROR;
-    }
-
-    /* Set the Connect Data */
-    if (lpCallerData != NULL)
-    {
-        ConnectDataLength = lpCallerData->len;
-        Status = NtDeviceIoControlFile((HANDLE)Handle,
-                                        SockEvent,
-                                        NULL,
-                                        NULL,
-                                        &IOSB,
-                                        IOCTL_AFD_SET_CONNECT_DATA,
-                                        lpCallerData->buf,
-                                        ConnectDataLength,
-                                        NULL,
-                                        0);
-        /* Wait for return */
-        if (Status == STATUS_PENDING)
-        {
-            WaitForSingleObject(SockEvent, INFINITE);
-            Status = IOSB.Status;
-        }
-
-        if (Status != STATUS_SUCCESS)
-            goto notify;
-    }
-
-    /* Calculate the size of SocketAddress->sa_data */
-    SocketDataLength = SocketAddressLength - FIELD_OFFSET(struct sockaddr, sa_data);
-
-    /* Allocate a connection info buffer with SocketDataLength bytes of payload */
-    ConnectInfo = HeapAlloc(GetProcessHeap(), 0,
-                            FIELD_OFFSET(AFD_CONNECT_INFO,
-                                         RemoteAddress.Address[0].Address[SocketDataLength]));
-    if (!ConnectInfo)
-    {
-        Status = STATUS_INSUFFICIENT_RESOURCES;
-        goto notify;
-    }
-
-    /* Set up Address in TDI Format */
-    ConnectInfo->RemoteAddress.TAAddressCount = 1;
-    ConnectInfo->RemoteAddress.Address[0].AddressLength = SocketDataLength;
-    ConnectInfo->RemoteAddress.Address[0].AddressType = SocketAddress->sa_family;
-    RtlCopyMemory(ConnectInfo->RemoteAddress.Address[0].Address,
-                  SocketAddress->sa_data,
-                  SocketDataLength);
-
-    /*
-    * Disable FD_WRITE and FD_CONNECT
-    * The latter fixes a race condition where the FD_CONNECT is re-enabled
-    * at the end of this function right after the Async Thread disables it.
-    * This should only happen at the *next* WSPConnect
-    */
-    if (Socket->SharedData->AsyncEvents & FD_CONNECT)
-    {
-        Socket->SharedData->AsyncDisabledEvents |= FD_CONNECT | FD_WRITE;
-    }
-
-    /* Tell AFD that we want Connection Data back, have it allocate a buffer */
-    if (lpCalleeData != NULL)
-    {
-        InConnectDataLength = lpCalleeData->len;
-        Status = NtDeviceIoControlFile((HANDLE)Handle,
-                                        SockEvent,
-                                        NULL,
-                                        NULL,
-                                        &IOSB,
-                                        IOCTL_AFD_SET_CONNECT_DATA_SIZE,
-                                        &InConnectDataLength,
-                                        sizeof(InConnectDataLength),
-                                        NULL,
-                                        0);
-
-        /* Wait for return */
-        if (Status == STATUS_PENDING)
-        {
-            WaitForSingleObject(SockEvent, INFINITE);
-            Status = IOSB.Status;
-        }
-
-        if (Status != STATUS_SUCCESS)
-            goto notify;
-    }
-
-    /* AFD doesn't seem to care if these are invalid, but let's 0 them anyways */
-    ConnectInfo->Root = 0;
-    ConnectInfo->UseSAN = FALSE;
-    ConnectInfo->Unknown = 0;
-
-    /* FIXME: Handle Async Connect */
-    if (Socket->SharedData->NonBlocking)
-    {
-        ERR("Async Connect UNIMPLEMENTED!\n");
-    }
-
-    /* Send IOCTL */
-    Status = NtDeviceIoControlFile((HANDLE)Handle,
-                                   SockEvent,
-                                   NULL,
-                                   NULL,
-                                   &IOSB,
-                                   IOCTL_AFD_CONNECT,
-                                   ConnectInfo,
-                                   0x22,
-                                   NULL,
-                                   0);
-    /* Wait for return */
-    if (Status == STATUS_PENDING)
-    {
-        WaitForSingleObject(SockEvent, INFINITE);
-        Status = IOSB.Status;
-    }
-
-    Socket->SharedData->SocketLastError = TranslateNtStatusError(Status);
-    if (Status != STATUS_SUCCESS)
-        goto notify;
-
-    Socket->SharedData->State = SocketConnected;
-    Socket->TdiConnectionHandle = (HANDLE)IOSB.Information;
-    Socket->SharedData->ConnectTime = GetCurrentTimeInSeconds();
-
-    /* Get any pending connect data */
-    if (lpCalleeData != NULL)
-    {
-        Status = NtDeviceIoControlFile((HANDLE)Handle,
-                                       SockEvent,
-                                       NULL,
-                                       NULL,
-                                       &IOSB,
-                                       IOCTL_AFD_GET_CONNECT_DATA,
-                                       NULL,
-                                       0,
-                                       lpCalleeData->buf,
-                                       lpCalleeData->len);
-        /* Wait for return */
-        if (Status == STATUS_PENDING)
-        {
-            WaitForSingleObject(SockEvent, INFINITE);
-            Status = IOSB.Status;
-        }
-    }
-
-    TRACE("Ending %lx\n", IOSB.Status);
-
-notify:
-    if (ConnectInfo) HeapFree(GetProcessHeap(), 0, ConnectInfo);
-
-    /* Re-enable Async Event */
-    SockReenableAsyncSelectEvent(Socket, FD_WRITE);
-
-    /* FIXME: THIS IS NOT RIGHT!!! HACK HACK HACK! */
-    SockReenableAsyncSelectEvent(Socket, FD_CONNECT);
-
-    NtClose(SockEvent);
-
-    if (Status == STATUS_SUCCESS && (Socket->HelperEvents & WSH_NOTIFY_CONNECT))
-    {
-        Errno = Socket->HelperData->WSHNotify(Socket->HelperContext,
-                                              Socket->Handle,
-                                              Socket->TdiAddressHandle,
-                                              Socket->TdiConnectionHandle,
-                                              WSH_NOTIFY_CONNECT);
-
-        if (Errno)
-        {
-            if (lpErrno) *lpErrno = Errno;
-            return SOCKET_ERROR;
-        }
-    }
-    else if (Status != STATUS_SUCCESS && (Socket->HelperEvents & WSH_NOTIFY_CONNECT_ERROR))
-    {
-        Errno = Socket->HelperData->WSHNotify(Socket->HelperContext,
-                                              Socket->Handle,
-                                              Socket->TdiAddressHandle,
-                                              Socket->TdiConnectionHandle,
-                                              WSH_NOTIFY_CONNECT_ERROR);
-
-        if (Errno)
-        {
-            if (lpErrno) *lpErrno = Errno;
-            return SOCKET_ERROR;
-        }
-    }
-
-    return MsafdReturnWithErrno(Status, lpErrno, 0, NULL);
-}
-int
-WSPAPI
-WSPShutdown(SOCKET Handle,
-            int HowTo,
-            LPINT lpErrno)
-
-{
-    IO_STATUS_BLOCK         IOSB;
-    AFD_DISCONNECT_INFO     DisconnectInfo;
-    PSOCKET_INFORMATION     Socket = NULL;
-    NTSTATUS                Status;
-    HANDLE                  SockEvent;
-
-    TRACE("Called\n");
-
-    /* Get the Socket Structure associate to this Socket*/
-    Socket = GetSocketStructure(Handle);
-    if (!Socket)
-    {
-       if (lpErrno) *lpErrno = WSAENOTSOCK;
-       return SOCKET_ERROR;
-    }
-
-    Status = NtCreateEvent(&SockEvent,
-                           EVENT_ALL_ACCESS,
-                           NULL,
-                           1,
-                           FALSE);
-
-    if( !NT_SUCCESS(Status) )
-        return SOCKET_ERROR;
-
-    /* Set AFD Disconnect Type */
-    switch (HowTo)
-    {
-        case SD_RECEIVE:
-            DisconnectInfo.DisconnectType = AFD_DISCONNECT_RECV;
-            Socket->SharedData->ReceiveShutdown = TRUE;
-            break;
-        case SD_SEND:
-            DisconnectInfo.DisconnectType= AFD_DISCONNECT_SEND;
-            Socket->SharedData->SendShutdown = TRUE;
-            break;
-        case SD_BOTH:
-            DisconnectInfo.DisconnectType = AFD_DISCONNECT_RECV | AFD_DISCONNECT_SEND;
-            Socket->SharedData->ReceiveShutdown = TRUE;
-            Socket->SharedData->SendShutdown = TRUE;
-            break;
-    }
-
-    DisconnectInfo.Timeout = RtlConvertLongToLargeInteger(-1000000);
-
-    /* Send IOCTL */
-    Status = NtDeviceIoControlFile((HANDLE)Handle,
-                                   SockEvent,
-                                   NULL,
-                                   NULL,
-                                   &IOSB,
-                                   IOCTL_AFD_DISCONNECT,
-                                   &DisconnectInfo,
-                                   sizeof(DisconnectInfo),
-                                   NULL,
-                                   0);
-
-    /* Wait for return */
-    if (Status == STATUS_PENDING)
-    {
-        WaitForSingleObject(SockEvent, INFINITE);
-        Status = IOSB.Status;
-    }
-
-    TRACE("Ending\n");
-
-    NtClose( SockEvent );
-
-    Socket->SharedData->SocketLastError = TranslateNtStatusError(Status);
-    return MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
-}
-
-
-INT
-WSPAPI
-WSPGetSockName(IN SOCKET Handle,
-               OUT LPSOCKADDR Name,
-               IN OUT LPINT NameLength,
-               OUT LPINT lpErrno)
-{
-    IO_STATUS_BLOCK         IOSB;
-    ULONG                   TdiAddressSize;
-    PTDI_ADDRESS_INFO       TdiAddress;
-    PTRANSPORT_ADDRESS      SocketAddress;
-    PSOCKET_INFORMATION     Socket = NULL;
-    NTSTATUS                Status;
-    HANDLE                  SockEvent;
-
-    /* Get the Socket Structure associate to this Socket*/
-    Socket = GetSocketStructure(Handle);
-    if (!Socket)
-    {
-       if (lpErrno) *lpErrno = WSAENOTSOCK;
-       return SOCKET_ERROR;
-    }
-
-    if (!Name || !NameLength)
-    {
-        if (lpErrno) *lpErrno = WSAEFAULT;
-        return SOCKET_ERROR;
-    }
-
-    Status = NtCreateEvent(&SockEvent,
-                           EVENT_ALL_ACCESS,
-                           NULL,
-                           1,
-                           FALSE);
-
-    if( !NT_SUCCESS(Status) )
-        return SOCKET_ERROR;
-
-    /* Allocate a buffer for the address */
-    TdiAddressSize =
-        sizeof(TRANSPORT_ADDRESS) + Socket->SharedData->SizeOfLocalAddress;
-    TdiAddress = HeapAlloc(GlobalHeap, 0, TdiAddressSize);
-
-    if ( TdiAddress == NULL )
-    {
-        NtClose( SockEvent );
-        if (lpErrno) *lpErrno = WSAENOBUFS;
-        return SOCKET_ERROR;
-    }
-
-    SocketAddress = &TdiAddress->Address;
-
-    /* Send IOCTL */
-    Status = NtDeviceIoControlFile((HANDLE)Socket->Handle,
-                                   SockEvent,
-                                   NULL,
-                                   NULL,
-                                   &IOSB,
-                                   IOCTL_AFD_GET_SOCK_NAME,
-                                   NULL,
-                                   0,
-                                   TdiAddress,
-                                   TdiAddressSize);
-
-    /* Wait for return */
-    if (Status == STATUS_PENDING)
-    {
-        WaitForSingleObject(SockEvent, INFINITE);
-        Status = IOSB.Status;
-    }
-
-    NtClose( SockEvent );
-
-    if (NT_SUCCESS(Status))
-    {
-        if (*NameLength >= Socket->SharedData->SizeOfLocalAddress)
-        {
-            Name->sa_family = SocketAddress->Address[0].AddressType;
-            RtlCopyMemory (Name->sa_data,
-                           SocketAddress->Address[0].Address,
-                           SocketAddress->Address[0].AddressLength);
-            *NameLength = Socket->SharedData->SizeOfLocalAddress;
-            TRACE("NameLength %d Address: %x Port %x\n",
-                          *NameLength, ((struct sockaddr_in *)Name)->sin_addr.s_addr,
-                          ((struct sockaddr_in *)Name)->sin_port);
-            HeapFree(GlobalHeap, 0, TdiAddress);
-            return 0;
-        }
-        else
-        {
-            HeapFree(GlobalHeap, 0, TdiAddress);
-            if (lpErrno) *lpErrno = WSAEFAULT;
-            return SOCKET_ERROR;
-        }
-    }
-
-    HeapFree(GlobalHeap, 0, TdiAddress);
-
-    return MsafdReturnWithErrno ( Status, lpErrno, 0, NULL );
-}
-
-
-INT
-WSPAPI
-WSPGetPeerName(IN SOCKET s,
-               OUT LPSOCKADDR Name,
-               IN OUT LPINT NameLength,
-               OUT LPINT lpErrno)
-{
-    IO_STATUS_BLOCK         IOSB;
-    ULONG                   TdiAddressSize;
-    PTRANSPORT_ADDRESS      SocketAddress;
-    PSOCKET_INFORMATION     Socket = NULL;
-    NTSTATUS                Status;
-    HANDLE                  SockEvent;
-
-    /* Get the Socket Structure associate to this Socket*/
-    Socket = GetSocketStructure(s);
-    if (!Socket)
-    {
-        if (lpErrno) *lpErrno = WSAENOTSOCK;
-        return SOCKET_ERROR;
-    }
-
-    if (Socket->SharedData->State != SocketConnected)
-    {
-        if (lpErrno) *lpErrno = WSAENOTCONN;
-        return SOCKET_ERROR;
-    }
-
-    if (!Name || !NameLength)
-    {
-        if (lpErrno) *lpErrno = WSAEFAULT;
-        return SOCKET_ERROR;
-    }
-
-    Status = NtCreateEvent(&SockEvent,
-                           EVENT_ALL_ACCESS,
-                           NULL,
-                           1,
-                           FALSE);
-
-    if( !NT_SUCCESS(Status) )
-        return SOCKET_ERROR;
-
-    /* Allocate a buffer for the address */
-    TdiAddressSize = sizeof(TRANSPORT_ADDRESS) + Socket->SharedData->SizeOfRemoteAddress;
-    SocketAddress = HeapAlloc(GlobalHeap, 0, TdiAddressSize);
-
-    if ( SocketAddress == NULL )
-    {
-        NtClose( SockEvent );
-        if (lpErrno) *lpErrno = WSAENOBUFS;
-        return SOCKET_ERROR;
-    }
-
-    /* Send IOCTL */
-    Status = NtDeviceIoControlFile((HANDLE)Socket->Handle,
-                                   SockEvent,
-                                   NULL,
-                                   NULL,
-                                   &IOSB,
-                                   IOCTL_AFD_GET_PEER_NAME,
-                                   NULL,
-                                   0,
-                                   SocketAddress,
-                                   TdiAddressSize);
-
-    /* Wait for return */
-    if (Status == STATUS_PENDING)
-    {
-        WaitForSingleObject(SockEvent, INFINITE);
-        Status = IOSB.Status;
-    }
-
-    NtClose( SockEvent );
-
-    if (NT_SUCCESS(Status))
-    {
-        if (*NameLength >= Socket->SharedData->SizeOfRemoteAddress)
-        {
-            Name->sa_family = SocketAddress->Address[0].AddressType;
-            RtlCopyMemory (Name->sa_data,
-                           SocketAddress->Address[0].Address,
-                           SocketAddress->Address[0].AddressLength);
-            *NameLength = Socket->SharedData->SizeOfRemoteAddress;
-            TRACE("NameLength %d Address: %x Port %x\n",
-                          *NameLength, ((struct sockaddr_in *)Name)->sin_addr.s_addr,
-                          ((struct sockaddr_in *)Name)->sin_port);
-            HeapFree(GlobalHeap, 0, SocketAddress);
-            return 0;
-        }
-        else
-        {
-            HeapFree(GlobalHeap, 0, SocketAddress);
-            if (lpErrno) *lpErrno = WSAEFAULT;
-            return SOCKET_ERROR;
-        }
-    }
-
-    HeapFree(GlobalHeap, 0, SocketAddress);
-
-    return MsafdReturnWithErrno ( Status, lpErrno, 0, NULL );
-}
-
-INT
-WSPAPI
-WSPIoctl(IN  SOCKET Handle,
-         IN  DWORD dwIoControlCode,
-         IN  LPVOID lpvInBuffer,
-         IN  DWORD cbInBuffer,
-         OUT LPVOID lpvOutBuffer,
-         IN  DWORD cbOutBuffer,
-         OUT LPDWORD lpcbBytesReturned,
-         IN  LPWSAOVERLAPPED lpOverlapped,
-         IN  LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
-         IN  LPWSATHREADID lpThreadId,
-         OUT LPINT lpErrno)
-{
-    PSOCKET_INFORMATION Socket = NULL;
-    BOOL NeedsCompletion = lpOverlapped != NULL;
-    BOOLEAN NonBlocking;
-    INT Errno = NO_ERROR, Ret = SOCKET_ERROR;
-    DWORD cbRet = 0;
-
-    /* Get the Socket Structure associate to this Socket*/
-    Socket = GetSocketStructure(Handle);
-    if (!Socket)
-    {
-        if(lpErrno)
-            *lpErrno = WSAENOTSOCK;
-        return SOCKET_ERROR;
-    }
-
-    if (!lpcbBytesReturned && !lpOverlapped)
-    {
-        if(lpErrno)
-            *lpErrno = WSAEFAULT;
-        return SOCKET_ERROR;
-    }
-
-    switch( dwIoControlCode )
-    {
-        case FIONBIO:
-            if( cbInBuffer < sizeof(INT) || IS_INTRESOURCE(lpvInBuffer) )
-            {
-                Errno = WSAEFAULT;
-                break;
-            }
-            NonBlocking = *((PULONG)lpvInBuffer) ? TRUE : FALSE;
-            /* Don't allow to go in blocking mode if WSPAsyncSelect or WSPEventSelect is pending */
-            if (!NonBlocking)
-            {
-                /* If there is an WSPAsyncSelect pending, fail with WSAEINVAL */
-                if (Socket->SharedData->AsyncEvents & (~Socket->SharedData->AsyncDisabledEvents))
-                {
-                    Errno = WSAEINVAL;
-                    break;
-                }
-                /* If there is an WSPEventSelect pending, fail with WSAEINVAL */
-                if (Socket->NetworkEvents)
-                {
-                    Errno = WSAEINVAL;
-                    break;
-                }
-            }
-            Socket->SharedData->NonBlocking = NonBlocking ? 1 : 0;
-            NeedsCompletion = FALSE;
-            Errno = SetSocketInformation(Socket, AFD_INFO_BLOCKING_MODE, &NonBlocking, NULL, NULL, lpOverlapped, lpCompletionRoutine);
-            if (Errno == NO_ERROR)
-                Ret = NO_ERROR;
-            break;
-        case FIONREAD:
-            if (IS_INTRESOURCE(lpvOutBuffer) || cbOutBuffer == 0)
-            {
-                cbRet = sizeof(ULONG);
-                Errno = WSAEFAULT;
-                break;
-            }
-            if (cbOutBuffer < sizeof(ULONG))
-            {
-                Errno = WSAEINVAL;
-                break;
-            }
-            NeedsCompletion = FALSE;
-            Errno = GetSocketInformation(Socket, AFD_INFO_RECEIVE_CONTENT_SIZE, NULL, (PULONG)lpvOutBuffer, NULL, lpOverlapped, lpCompletionRoutine);
-            if (Errno == NO_ERROR)
-            {
-                cbRet = sizeof(ULONG);
-                Ret = NO_ERROR;
-            }
-            break;
-        case SIOCATMARK:
-            if (IS_INTRESOURCE(lpvOutBuffer) || cbOutBuffer == 0)
-            {
-                cbRet = sizeof(BOOL);
-                Errno = WSAEFAULT;
-                break;
-            }
-            if (cbOutBuffer < sizeof(BOOL))
-            {
-                Errno = WSAEINVAL;
-                break;
-            }
-            if (Socket->SharedData->SocketType != SOCK_STREAM)
-            {
-                Errno = WSAEINVAL;
-                break;
-            }
-
-            /* FIXME: Return false if OOBINLINE is true for now
-               We should MSG_PEEK|MSG_OOB check with driver
-            */
-            *(BOOL*)lpvOutBuffer = !Socket->SharedData->OobInline;
-
-            cbRet = sizeof(BOOL);
-            Errno = NO_ERROR;
-            Ret = NO_ERROR;
-            break;
-        case SIO_GET_EXTENSION_FUNCTION_POINTER:
-            Errno = WSAEINVAL;
-            break;
-        case SIO_ADDRESS_LIST_QUERY:
-            if (IS_INTRESOURCE(lpvOutBuffer) || cbOutBuffer == 0)
-            {
-                cbRet = sizeof(SOCKET_ADDRESS_LIST) + sizeof(Socket->SharedData->WSLocalAddress);
-                Errno = WSAEFAULT;
-                break;
-            }
-            if (cbOutBuffer < sizeof(INT))
-            {
-                Errno = WSAEINVAL;
-                break;
-            }
-
-            cbRet = sizeof(SOCKET_ADDRESS_LIST) + sizeof(Socket->SharedData->WSLocalAddress);
-
-            ((SOCKET_ADDRESS_LIST*)lpvOutBuffer)->iAddressCount = 1;
-
-            if (cbOutBuffer < (sizeof(SOCKET_ADDRESS_LIST) + sizeof(Socket->SharedData->WSLocalAddress)))
-            {
-                Errno = WSAEFAULT;
-                break;
-            }
-
-            ((SOCKET_ADDRESS_LIST*)lpvOutBuffer)->Address[0].iSockaddrLength = sizeof(Socket->SharedData->WSLocalAddress);
-            ((SOCKET_ADDRESS_LIST*)lpvOutBuffer)->Address[0].lpSockaddr = &Socket->SharedData->WSLocalAddress;
-
-            Errno = NO_ERROR;
-            Ret = NO_ERROR;
-            break;
-        default:
-            Errno = Socket->HelperData->WSHIoctl(Socket->HelperContext,
-                                                 Handle,
-                                                 Socket->TdiAddressHandle,
-                                                 Socket->TdiConnectionHandle,
-                                                 dwIoControlCode,
-                                                 lpvInBuffer,
-                                                 cbInBuffer,
-                                                 lpvOutBuffer,
-                                                 cbOutBuffer,
-                                                 &cbRet,
-                                                 lpOverlapped,
-                                                 lpCompletionRoutine,
-                                                 &NeedsCompletion);
-
-            if (Errno == NO_ERROR)
-                Ret = NO_ERROR;
-            break;
-    }
-    if (lpOverlapped && NeedsCompletion)
-    {
-        lpOverlapped->Internal = Errno;
-        lpOverlapped->InternalHigh = cbRet;
-        if (lpCompletionRoutine != NULL)
-        {
-            lpCompletionRoutine(Errno, cbRet, lpOverlapped, 0);
-        }
-        if (lpOverlapped->hEvent)
-            SetEvent(lpOverlapped->hEvent);
-        if (!PostQueuedCompletionStatus((HANDLE)Handle, cbRet, 0, lpOverlapped))
-        {
-            ERR("PostQueuedCompletionStatus failed %d\n", GetLastError());
-        }
-        return NO_ERROR;
-    }
-    if (lpErrno)
-        *lpErrno = Errno;
-    if (lpcbBytesReturned)
-        *lpcbBytesReturned = cbRet;
-    return Ret;
-}
-
-
-INT
-WSPAPI
-WSPGetSockOpt(IN SOCKET Handle,
-              IN INT Level,
-              IN INT OptionName,
-              OUT CHAR FAR* OptionValue,
-              IN OUT LPINT OptionLength,
-              OUT LPINT lpErrno)
-{
-    PSOCKET_INFORMATION Socket = NULL;
-    PVOID Buffer;
-    INT BufferSize;
-    BOOL BoolBuffer;
-    DWORD DwordBuffer;
-    INT Errno;
-
-    TRACE("Called\n");
-
-    /* Get the Socket Structure associate to this Socket*/
-    Socket = GetSocketStructure(Handle);
-    if (Socket == NULL)
-    {
-        if (lpErrno) *lpErrno = WSAENOTSOCK;
-        return SOCKET_ERROR;
-    }
-    if (!OptionLength || !OptionValue)
-    {
-        if (lpErrno) *lpErrno = WSAEFAULT;
-        return SOCKET_ERROR;
-    }
-
-    switch (Level)
-    {
-        case SOL_SOCKET:
-            switch (OptionName)
-            {
-                case SO_TYPE:
-                    Buffer = &Socket->SharedData->SocketType;
-                    BufferSize = sizeof(INT);
-                    break;
-
-                case SO_RCVBUF:
-                    Buffer = &Socket->SharedData->SizeOfRecvBuffer;
-                    BufferSize = sizeof(INT);
-                    break;
-
-                case SO_SNDBUF:
-                    Buffer = &Socket->SharedData->SizeOfSendBuffer;
-                    BufferSize = sizeof(INT);
-                    break;
-
-                case SO_ACCEPTCONN:
-                    BoolBuffer = Socket->SharedData->Listening;
-                    Buffer = &BoolBuffer;
-                    BufferSize = sizeof(BOOL);
-                    break;
-
-                case SO_BROADCAST:
-                    BoolBuffer = Socket->SharedData->Broadcast;
-                    Buffer = &BoolBuffer;
-                    BufferSize = sizeof(BOOL);
-                    break;
-
-                case SO_DEBUG:
-                    BoolBuffer = Socket->SharedData->Debug;
-                    Buffer = &BoolBuffer;
-                    BufferSize = sizeof(BOOL);
-                    break;
-
-                case SO_DONTLINGER:
-                    BoolBuffer = (Socket->SharedData->LingerData.l_onoff == 0);
-                    Buffer = &BoolBuffer;
-                    BufferSize = sizeof(BOOL);
-                    break;
-
-                case SO_LINGER:
-                    if (Socket->SharedData->SocketType == SOCK_DGRAM)
-                    {
-                        if (lpErrno) *lpErrno = WSAENOPROTOOPT;
-                        return SOCKET_ERROR;
-                    }
-                    Buffer = &Socket->SharedData->LingerData;
-                    BufferSize = sizeof(struct linger);
-                    break;
-
-                case SO_OOBINLINE:
-                    BoolBuffer = (Socket->SharedData->OobInline != 0);
-                    Buffer = &BoolBuffer;
-                    BufferSize = sizeof(BOOL);
-                    break;
-
-                case SO_KEEPALIVE:
-                case SO_DONTROUTE:
-                   /* These guys go directly to the helper */
-                   goto SendToHelper;
-
-                case SO_CONDITIONAL_ACCEPT:
-                    BoolBuffer = (Socket->SharedData->UseDelayedAcceptance != 0);
-                    Buffer = &BoolBuffer;
-                    BufferSize = sizeof(BOOL);
-                    break;
-
-                case SO_REUSEADDR:
-                    BoolBuffer = (Socket->SharedData->ReuseAddresses != 0);
-                    Buffer = &BoolBuffer;
-                    BufferSize = sizeof(BOOL);
-                    break;
-
-                case SO_EXCLUSIVEADDRUSE:
-                    BoolBuffer = (Socket->SharedData->ExclusiveAddressUse != 0);
-                    Buffer = &BoolBuffer;
-                    BufferSize = sizeof(BOOL);
-                    break;
-
-                case SO_ERROR:
-                    Buffer = &Socket->SharedData->SocketLastError;
-                    BufferSize = sizeof(INT);
-                    break;
-
-                case SO_CONNECT_TIME:
-                    DwordBuffer = GetCurrentTimeInSeconds() - Socket->SharedData->ConnectTime;
-                    Buffer = &DwordBuffer;
-                    BufferSize = sizeof(DWORD);
-                    break;
-
-                case SO_SNDTIMEO:
-                    Buffer = &Socket->SharedData->SendTimeout;
-                    BufferSize = sizeof(DWORD);
-                    break;
-                case SO_RCVTIMEO:
-                    Buffer = &Socket->SharedData->RecvTimeout;
-                    BufferSize = sizeof(DWORD);
-                    break;
-                case SO_PROTOCOL_INFOW:
-                    Buffer = &Socket->ProtocolInfo;
-                    BufferSize = sizeof(Socket->ProtocolInfo);
-                    break;
-
-                case SO_GROUP_ID:
-                case SO_GROUP_PRIORITY:
-                case SO_MAX_MSG_SIZE:
-
-                default:
-                    DbgPrint("MSAFD: Get unknown optname %x\n", OptionName);
-                    if (lpErrno) *lpErrno = WSAENOPROTOOPT;
-                    return SOCKET_ERROR;
-            }
-
-            if (*OptionLength < BufferSize)
-            {
-                if (lpErrno) *lpErrno = WSAEFAULT;
-                *OptionLength = BufferSize;
-                return SOCKET_ERROR;
-            }
-            RtlCopyMemory(OptionValue, Buffer, BufferSize);
-
-            return 0;
-
-        default:
-            if (lpErrno) *lpErrno = WSAEINVAL;
-            return SOCKET_ERROR;
-    }
-
-SendToHelper:
-    Errno = Socket->HelperData->WSHGetSocketInformation(Socket->HelperContext,
-                                                        Handle,
-                                                        Socket->TdiAddressHandle,
-                                                        Socket->TdiConnectionHandle,
-                                                        Level,
-                                                        OptionName,
-                                                        OptionValue,
-                                                        (LPINT)OptionLength);
-    if (lpErrno) *lpErrno = Errno;
-    return (Errno == NO_ERROR) ? NO_ERROR : SOCKET_ERROR;
-}
-
-INT
-WSPAPI
-WSPSetSockOpt(
-    IN  SOCKET s,
-    IN  INT level,
-    IN  INT optname,
-    IN  CONST CHAR FAR* optval,
-    IN  INT optlen,
-    OUT LPINT lpErrno)
-{
-    PSOCKET_INFORMATION Socket;
-    INT Errno;
-
-    /* Get the Socket Structure associate to this Socket*/
-    Socket = GetSocketStructure(s);
-    if (Socket == NULL)
-    {
-        if (lpErrno) *lpErrno = WSAENOTSOCK;
-        return SOCKET_ERROR;
-    }
-    if (!optval)
-    {
-        if (lpErrno) *lpErrno = WSAEFAULT;
-        return SOCKET_ERROR;
-    }
-
-
-    /* FIXME: We should handle some more cases here */
-    if (level == SOL_SOCKET)
-    {
-        switch (optname)
-        {
-           case SO_BROADCAST:
-              if (optlen < sizeof(BOOL))
-              {
-                  if (lpErrno) *lpErrno = WSAEFAULT;
-                  return SOCKET_ERROR;
-              }
-              Socket->SharedData->Broadcast = (*optval != 0) ? 1 : 0;
-              return NO_ERROR;
-
-           case SO_OOBINLINE:
-              if (optlen < sizeof(BOOL))
-              {
-                  if (lpErrno) *lpErrno = WSAEFAULT;
-                  return SOCKET_ERROR;
-              }
-              Socket->SharedData->OobInline = (*optval != 0) ? 1 : 0;
-              return NO_ERROR;
-
-           case SO_DONTLINGER:
-              if (optlen < sizeof(BOOL))
-              {
-                  if (lpErrno) *lpErrno = WSAEFAULT;
-                  return SOCKET_ERROR;
-              }
-              Socket->SharedData->LingerData.l_onoff = (*optval != 0) ? 0 : 1;
-              return NO_ERROR;
-
-           case SO_REUSEADDR:
-              if (optlen < sizeof(BOOL))
-              {
-                  if (lpErrno) *lpErrno = WSAEFAULT;
-                  return SOCKET_ERROR;
-              }
-              Socket->SharedData->ReuseAddresses = (*optval != 0) ? 1 : 0;
-              return NO_ERROR;
-
-           case SO_EXCLUSIVEADDRUSE:
-              if (optlen < sizeof(BOOL))
-              {
-                  if (lpErrno) *lpErrno = WSAEFAULT;
-                  return SOCKET_ERROR;
-              }
-              Socket->SharedData->ExclusiveAddressUse = (*optval != 0) ? 1 : 0;
-              return NO_ERROR;
-
-           case SO_LINGER:
-              if (optlen < sizeof(struct linger))
-              {
-                  if (lpErrno) *lpErrno = WSAEFAULT;
-                  return SOCKET_ERROR;
-              }
-              RtlCopyMemory(&Socket->SharedData->LingerData,
-                            optval,
-                            sizeof(struct linger));
-              return NO_ERROR;
-
-           case SO_SNDBUF:
-              if (optlen < sizeof(DWORD))
-              {
-                  if (lpErrno) *lpErrno = WSAEFAULT;
-                  return SOCKET_ERROR;
-              }
-
-              /* TODO: The total per-socket buffer space reserved for sends */
-              ERR("Setting send buf to %x is not implemented yet\n", optval);
-              return NO_ERROR;
-
-           case SO_ERROR:
-              if (optlen < sizeof(INT))
-              {
-                  if (lpErrno) *lpErrno = WSAEFAULT;
-                  return SOCKET_ERROR;
-              }
-
-              RtlCopyMemory(&Socket->SharedData->SocketLastError,
-                            optval,
-                            sizeof(INT));
-              return NO_ERROR;
-
-           case SO_SNDTIMEO:
-              if (optlen < sizeof(DWORD))
-              {
-                  if (lpErrno) *lpErrno = WSAEFAULT;
-                  return SOCKET_ERROR;
-              }
-
-              RtlCopyMemory(&Socket->SharedData->SendTimeout,
-                            optval,
-                            sizeof(DWORD));
-              return NO_ERROR;
-
-           case SO_RCVTIMEO:
-              if (optlen < sizeof(DWORD))
-              {
-                  if (lpErrno) *lpErrno = WSAEFAULT;
-                  return SOCKET_ERROR;
-              }
-
-              RtlCopyMemory(&Socket->SharedData->RecvTimeout,
-                            optval,
-                            sizeof(DWORD));
-              return NO_ERROR;
-
-           case SO_KEEPALIVE:
-           case SO_DONTROUTE:
-              /* These go directly to the helper dll */
-              goto SendToHelper;
-
-           default:
-              /* Obviously this is a hack */
-              ERR("MSAFD: Set unknown optname %x\n", optname);
-              return NO_ERROR;
-        }
-    }
-
-SendToHelper:
-    Errno = Socket->HelperData->WSHSetSocketInformation(Socket->HelperContext,
-                                                        s,
-                                                        Socket->TdiAddressHandle,
-                                                        Socket->TdiConnectionHandle,
-                                                        level,
-                                                        optname,
-                                                        (PCHAR)optval,
-                                                        optlen);
-    if (lpErrno) *lpErrno = Errno;
-    return (Errno == NO_ERROR) ? NO_ERROR : SOCKET_ERROR;
-}
-
-/*
- * FUNCTION: Initialize service provider for a client
- * ARGUMENTS:
- *     wVersionRequested = Highest WinSock SPI version that the caller can use
- *     lpWSPData         = Address of WSPDATA structure to initialize
- *     lpProtocolInfo    = Pointer to structure that defines the desired protocol
- *     UpcallTable       = Pointer to upcall table of the WinSock DLL
- *     lpProcTable       = Address of procedure table to initialize
- * RETURNS:
- *     Status of operation
- */
-INT
-WSPAPI
-WSPStartup(IN  WORD wVersionRequested,
-           OUT LPWSPDATA lpWSPData,
-           IN  LPWSAPROTOCOL_INFOW lpProtocolInfo,
-           IN  WSPUPCALLTABLE UpcallTable,
-           OUT LPWSPPROC_TABLE lpProcTable)
-
-{
-    NTSTATUS Status;
-
-    if (((LOBYTE(wVersionRequested) == 2) && (HIBYTE(wVersionRequested) < 2)) ||
-        (LOBYTE(wVersionRequested) < 2))
-    {
-        ERR("WSPStartup NOT SUPPORTED for version 0x%X\n", wVersionRequested);
-        return WSAVERNOTSUPPORTED;
-    }
-    else
-        Status = NO_ERROR;
-    /* FIXME: Enable all cases of WSPStartup status */
-    Upcalls = UpcallTable;
-
-    if (Status == NO_ERROR)
-    {
-        lpProcTable->lpWSPAccept = WSPAccept;
-        lpProcTable->lpWSPAddressToString = WSPAddressToString;
-        lpProcTable->lpWSPAsyncSelect = WSPAsyncSelect;
-        lpProcTable->lpWSPBind = WSPBind;
-        lpProcTable->lpWSPCancelBlockingCall = WSPCancelBlockingCall;
-        lpProcTable->lpWSPCleanup = WSPCleanup;
-        lpProcTable->lpWSPCloseSocket = WSPCloseSocket;
-        lpProcTable->lpWSPConnect = WSPConnect;
-        lpProcTable->lpWSPDuplicateSocket = WSPDuplicateSocket;
-        lpProcTable->lpWSPEnumNetworkEvents = WSPEnumNetworkEvents;
-        lpProcTable->lpWSPEventSelect = WSPEventSelect;
-        lpProcTable->lpWSPGetOverlappedResult = WSPGetOverlappedResult;
-        lpProcTable->lpWSPGetPeerName = WSPGetPeerName;
-        lpProcTable->lpWSPGetSockName = WSPGetSockName;
-        lpProcTable->lpWSPGetSockOpt = WSPGetSockOpt;
-        lpProcTable->lpWSPGetQOSByName = WSPGetQOSByName;
-        lpProcTable->lpWSPIoctl = WSPIoctl;
-        lpProcTable->lpWSPJoinLeaf = WSPJoinLeaf;
-        lpProcTable->lpWSPListen = WSPListen;
-        lpProcTable->lpWSPRecv = WSPRecv;
-        lpProcTable->lpWSPRecvDisconnect = WSPRecvDisconnect;
-        lpProcTable->lpWSPRecvFrom = WSPRecvFrom;
-        lpProcTable->lpWSPSelect = WSPSelect;
-        lpProcTable->lpWSPSend = WSPSend;
-        lpProcTable->lpWSPSendDisconnect = WSPSendDisconnect;
-        lpProcTable->lpWSPSendTo = WSPSendTo;
-        lpProcTable->lpWSPSetSockOpt = WSPSetSockOpt;
-        lpProcTable->lpWSPShutdown = WSPShutdown;
-        lpProcTable->lpWSPSocket = WSPSocket;
-        lpProcTable->lpWSPStringToAddress = WSPStringToAddress;
-        lpWSPData->wVersion     = MAKEWORD(2, 2);
-        lpWSPData->wHighVersion = MAKEWORD(2, 2);
-        /* Save CatalogEntryId for all upcalls */
-        CatalogEntryId = lpProtocolInfo->dwCatalogEntryId;
-    }
-
-    TRACE("Status (%d).\n", Status);
-    return Status;
-}
-
-
-INT
-WSPAPI
-WSPAddressToString(IN LPSOCKADDR lpsaAddress,
-                   IN DWORD dwAddressLength,
-                   IN LPWSAPROTOCOL_INFOW lpProtocolInfo,
-                   OUT LPWSTR lpszAddressString,
-                   IN OUT LPDWORD lpdwAddressStringLength,
-                   OUT LPINT lpErrno)
-{
-    DWORD size;
-    WCHAR buffer[54]; /* 32 digits + 7':' + '[' + '%" + 5 digits + ']:' + 5 digits + '\0' */
-    WCHAR *p;
-
-    if (!lpsaAddress || !lpszAddressString || !lpdwAddressStringLength)
-    {
-        if (lpErrno) *lpErrno = WSAEFAULT;
-        return SOCKET_ERROR;
-    }
-
-    switch (lpsaAddress->sa_family)
-    {
-        case AF_INET:
-            if (dwAddressLength < sizeof(SOCKADDR_IN))
-            {
-                if (lpErrno) *lpErrno = WSAEINVAL;
-                return SOCKET_ERROR;
-            }
-            swprintf(buffer,
-                     L"%u.%u.%u.%u:%u",
-                     (unsigned int)(ntohl(((SOCKADDR_IN *)lpsaAddress)->sin_addr.s_addr) >> 24 & 0xff),
-                     (unsigned int)(ntohl(((SOCKADDR_IN *)lpsaAddress)->sin_addr.s_addr) >> 16 & 0xff),
-                     (unsigned int)(ntohl(((SOCKADDR_IN *)lpsaAddress)->sin_addr.s_addr) >> 8 & 0xff),
-                     (unsigned int)(ntohl(((SOCKADDR_IN *)lpsaAddress)->sin_addr.s_addr) & 0xff),
-                     ntohs(((SOCKADDR_IN *)lpsaAddress)->sin_port));
-
-            p = wcschr(buffer, L':');
-            if (!((SOCKADDR_IN *)lpsaAddress)->sin_port)
-            {
-                *p = 0;
-            }
-            break;
-        default:
-            if (lpErrno) *lpErrno = WSAEINVAL;
-            return SOCKET_ERROR;
-    }
-
-    size = wcslen(buffer) + 1;
-
-    if (*lpdwAddressStringLength < size)
-    {
-        *lpdwAddressStringLength = size;
-        if (lpErrno) *lpErrno = WSAEFAULT;
-        return SOCKET_ERROR;
-    }
-
-    *lpdwAddressStringLength = size;
-    wcscpy(lpszAddressString, buffer);
-    return 0;
-}
-
-INT
-WSPAPI
-WSPStringToAddress(IN LPWSTR AddressString,
-                   IN INT AddressFamily,
-                   IN LPWSAPROTOCOL_INFOW lpProtocolInfo,
-                   OUT LPSOCKADDR lpAddress,
-                   IN OUT LPINT lpAddressLength,
-                   OUT LPINT lpErrno)
-{
-    int numdots = 0;
-    USHORT port;
-    LONG inetaddr = 0, ip_part;
-    LPWSTR *bp = NULL;
-    SOCKADDR_IN *sockaddr;
-
-    if (!lpAddressLength || !lpAddress || !AddressString)
-    {
-        if (lpErrno) *lpErrno = WSAEINVAL;
-        return SOCKET_ERROR;
-    }
-
-    sockaddr = (SOCKADDR_IN *)lpAddress;
-
-    /* Set right address family */
-    if (lpProtocolInfo != NULL)
-    {
-        sockaddr->sin_family = lpProtocolInfo->iAddressFamily;
-    }
-    else
-    {
-        sockaddr->sin_family = AddressFamily;
-    }
-
-    /* Report size */
-    if (AddressFamily == AF_INET)
-    {
-        if (*lpAddressLength < (INT)sizeof(SOCKADDR_IN))
-        {
-            if (lpErrno) *lpErrno = WSAEFAULT;
-        }
-        else
-        {
-            // translate ip string to ip
-
-            /* Get ip number */
-            bp = &AddressString;
-            inetaddr = 0;
-
-            while (*bp < &AddressString[wcslen(AddressString)])
-            {
-                ip_part = wcstol(*bp, bp, 10);
-                /* ip part number should be in range 0-255 */
-                if (ip_part < 0 || ip_part > 255)
-                {
-                    if (lpErrno) *lpErrno = WSAEINVAL;
-                    return SOCKET_ERROR;
-                }
-                inetaddr = (inetaddr << 8) + ip_part;
-                /* we end on string end or port separator */
-                if ((*bp)[0] == 0 || (*bp)[0] == L':')
-                    break;
-                /* ip parts are dot separated. verify it */
-                if ((*bp)[0] != L'.')
-                {
-                    if (lpErrno) *lpErrno = WSAEINVAL;
-                    return SOCKET_ERROR;
-                }
-                /* count the dots */
-                numdots++;
-                /* move over the dot to next ip part */
-                (*bp)++;
-            }
-            
-            /* check dots count */
-            if (numdots != 3)
-            {
-                if (lpErrno) *lpErrno = WSAEINVAL;
-                return SOCKET_ERROR;
-            }
-
-            /* Get port number */
-            if ((*bp)[0] == L':')
-            {
-                /* move over the column to port part */
-                (*bp)++;
-                /* next char should be numeric */
-                if ((*bp)[0] < L'0' || (*bp)[0] > L'9')
-                {
-                    if (lpErrno) *lpErrno = WSAEINVAL;
-                    return SOCKET_ERROR;
-                }
-                port = wcstol(*bp, bp, 10);
-            }
-            else
-            {
-                port = 0;
-            }
-
-            if (lpErrno) *lpErrno = NO_ERROR;
-            /* rest sockaddr.sin_addr.s_addr
-            for we need to be sure it is zero when we come to while */
-            *lpAddressLength = sizeof(*sockaddr);
-            memset(lpAddress, 0, sizeof(*sockaddr));
-            sockaddr->sin_family = AF_INET;
-            sockaddr->sin_addr.s_addr = inetaddr;
-            sockaddr->sin_port = port;
-        }
-    }
-
-    if (lpErrno && !*lpErrno)
-    {
-        return 0;
-    }
-
-    return SOCKET_ERROR;
-}
-
-/*
- * FUNCTION: Cleans up service provider for a client
- * ARGUMENTS:
- *     lpErrno = Address of buffer for error information
- * RETURNS:
- *     0 if successful, or SOCKET_ERROR if not
- */
-INT
-WSPAPI
-WSPCleanup(OUT LPINT lpErrno)
-
-{
-    TRACE("Leaving.\n");
-
-    if (lpErrno) *lpErrno = NO_ERROR;
-
-    return 0;
-}
-
-VOID
-NTAPI
-AfdInfoAPC(PVOID ApcContext,
-    PIO_STATUS_BLOCK IoStatusBlock,
-    ULONG Reserved)
-{
-    PAFDAPCCONTEXT Context = ApcContext;
-
-    Context->lpCompletionRoutine(IoStatusBlock->Status, IoStatusBlock->Information, Context->lpOverlapped, 0);
-    HeapFree(GlobalHeap, 0, ApcContext);
-}
-
-int
-GetSocketInformation(PSOCKET_INFORMATION Socket,
-                     ULONG AfdInformationClass,
-                     PBOOLEAN Boolean OPTIONAL,
-                     PULONG Ulong OPTIONAL,
-                     PLARGE_INTEGER LargeInteger OPTIONAL,
-                     LPWSAOVERLAPPED Overlapped OPTIONAL,
-                     LPWSAOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine OPTIONAL)
-{
-    PIO_STATUS_BLOCK    IOSB;
-    IO_STATUS_BLOCK     DummyIOSB;
-    AFD_INFO            InfoData;
-    NTSTATUS            Status;
-    PAFDAPCCONTEXT      APCContext;
-    PIO_APC_ROUTINE     APCFunction;
-    HANDLE              Event = NULL;
-    HANDLE              SockEvent;
-
-    Status = NtCreateEvent(&SockEvent,
-                           EVENT_ALL_ACCESS,
-                           NULL,
-                           1,
-                           FALSE);
-
-    if( !NT_SUCCESS(Status) )
-        return SOCKET_ERROR;
-
-    /* Set Info Class */
-    InfoData.InformationClass = AfdInformationClass;
-
-    /* Verify if we should use APC */
-    if (Overlapped == NULL)
-    {
-        /* Not using Overlapped structure, so use normal blocking on event */
-        APCContext = NULL;
-        APCFunction = NULL;
-        Event = SockEvent;
-        IOSB = &DummyIOSB;
-    }
-    else
-    {
-        /* Overlapped request for non overlapped opened socket */
-        if ((Socket->SharedData->CreateFlags & SO_SYNCHRONOUS_NONALERT) != 0)
-        {
-            TRACE("Opened without flag WSA_FLAG_OVERLAPPED. Do nothing.\n");
-            return 0;
-        }
-        if (CompletionRoutine == NULL)
-        {
-            /* Using Overlapped Structure, but no Completition Routine, so no need for APC */
-            APCContext = (PAFDAPCCONTEXT)Overlapped;
-            APCFunction = NULL;
-            Event = Overlapped->hEvent;
-        }
-        else
-        {
-            /* Using Overlapped Structure and a Completition Routine, so use an APC */
-            APCFunction = &AfdInfoAPC; // should be a private io completition function inside us
-            APCContext = HeapAlloc(GlobalHeap, 0, sizeof(AFDAPCCONTEXT));
-            if (!APCContext)
-            {
-                ERR("Not enough memory for APC Context\n");
-                return WSAEFAULT;
-            }
-            APCContext->lpCompletionRoutine = CompletionRoutine;
-            APCContext->lpOverlapped = Overlapped;
-            APCContext->lpSocket = Socket;
-        }
-
-        IOSB = (PIO_STATUS_BLOCK)&Overlapped->Internal;
-    }
-
-    IOSB->Status = STATUS_PENDING;
-
-    /* Send IOCTL */
-    Status = NtDeviceIoControlFile((HANDLE)Socket->Handle,
-                                   Event,
-                                   APCFunction,
-                                   APCContext,
-                                   IOSB,
-                                   IOCTL_AFD_GET_INFO,
-                                   &InfoData,
-                                   sizeof(InfoData),
-                                   &InfoData,
-                                   sizeof(InfoData));
-
-    /* Wait for return */
-    if (Status == STATUS_PENDING && Overlapped == NULL)
-    {
-        WaitForSingleObject(SockEvent, INFINITE);
-        Status = IOSB->Status;
-    }
-
-    TRACE("Status %x Information %d\n", Status, IOSB->Information);
-
-    if (Status == STATUS_PENDING)
-    {
-        TRACE("Leaving (Pending)\n");
-        return WSA_IO_PENDING;
-    }
-
-    if (Status != STATUS_SUCCESS)
-        return SOCKET_ERROR;
-
-    /* Return Information */
-    if (Ulong != NULL)
-    {
-        *Ulong = InfoData.Information.Ulong;
-    }
-    if (LargeInteger != NULL)
-    {
-        *LargeInteger = InfoData.Information.LargeInteger;
-    }
-    if (Boolean != NULL)
-    {
-        *Boolean = InfoData.Information.Boolean;
-    }
-
-    NtClose( SockEvent );
-
-    return NO_ERROR;
-
-}
-
-
-int
-SetSocketInformation(PSOCKET_INFORMATION Socket,
-                     ULONG AfdInformationClass,
-                     PBOOLEAN Boolean OPTIONAL,
-                     PULONG Ulong OPTIONAL,
-                     PLARGE_INTEGER LargeInteger OPTIONAL,
-                     LPWSAOVERLAPPED Overlapped OPTIONAL,
-                     LPWSAOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine OPTIONAL)
-{
-    PIO_STATUS_BLOCK    IOSB;
-    IO_STATUS_BLOCK     DummyIOSB;
-    AFD_INFO            InfoData;
-    NTSTATUS            Status;
-    PAFDAPCCONTEXT      APCContext;
-    PIO_APC_ROUTINE     APCFunction;
-    HANDLE              Event = NULL;
-    HANDLE              SockEvent;
-
-    Status = NtCreateEvent(&SockEvent,
-                           EVENT_ALL_ACCESS,
-                           NULL,
-                           1,
-                           FALSE);
-
-    if( !NT_SUCCESS(Status) )
-        return SOCKET_ERROR;
-
-    /* Set Info Class */
-    InfoData.InformationClass = AfdInformationClass;
-
-    /* Set Information */
-    if (Ulong != NULL)
-    {
-        InfoData.Information.Ulong = *Ulong;
-    }
-    if (LargeInteger != NULL)
-    {
-        InfoData.Information.LargeInteger = *LargeInteger;
-    }
-    if (Boolean != NULL)
-    {
-        InfoData.Information.Boolean = *Boolean;
-    }
-
-    /* Verify if we should use APC */
-    if (Overlapped == NULL)
-    {
-        /* Not using Overlapped structure, so use normal blocking on event */
-        APCContext = NULL;
-        APCFunction = NULL;
-        Event = SockEvent;
-        IOSB = &DummyIOSB;
-    }
-    else
-    {
-        /* Overlapped request for non overlapped opened socket */
-        if ((Socket->SharedData->CreateFlags & SO_SYNCHRONOUS_NONALERT) != 0)
-        {
-            TRACE("Opened without flag WSA_FLAG_OVERLAPPED. Do nothing.\n");
-            return 0;
-        }
-        if (CompletionRoutine == NULL)
-        {
-            /* Using Overlapped Structure, but no Completition Routine, so no need for APC */
-            APCContext = (PAFDAPCCONTEXT)Overlapped;
-            APCFunction = NULL;
-            Event = Overlapped->hEvent;
-        }
-        else
-        {
-            /* Using Overlapped Structure and a Completition Routine, so use an APC */
-            APCFunction = &AfdInfoAPC; // should be a private io completition function inside us
-            APCContext = HeapAlloc(GlobalHeap, 0, sizeof(AFDAPCCONTEXT));
-            if (!APCContext)
-            {
-                ERR("Not enough memory for APC Context\n");
-                return WSAEFAULT;
-            }
-            APCContext->lpCompletionRoutine = CompletionRoutine;
-            APCContext->lpOverlapped = Overlapped;
-            APCContext->lpSocket = Socket;
-        }
-
-        IOSB = (PIO_STATUS_BLOCK)&Overlapped->Internal;
-    }
-
-    IOSB->Status = STATUS_PENDING;
-
-    /* Send IOCTL */
-    Status = NtDeviceIoControlFile((HANDLE)Socket->Handle,
-                                   Event,
-                                   APCFunction,
-                                   APCContext,
-                                   IOSB,
-                                   IOCTL_AFD_SET_INFO,
-                                   &InfoData,
-                                   sizeof(InfoData),
-                                   NULL,
-                                   0);
-
-    /* Wait for return */
-    if (Status == STATUS_PENDING && Overlapped == NULL)
-    {
-        WaitForSingleObject(SockEvent, INFINITE);
-        Status = IOSB->Status;
-    }
-
-    NtClose( SockEvent );
-
-    TRACE("Status %x Information %d\n", Status, IOSB->Information);
-
-    if (Status == STATUS_PENDING)
-    {
-        TRACE("Leaving (Pending)\n");
-        return WSA_IO_PENDING;
-    }
-
-    return Status == STATUS_SUCCESS ? NO_ERROR : SOCKET_ERROR;
-
-}
-
-PSOCKET_INFORMATION
-GetSocketStructure(SOCKET Handle)
-{
-    PSOCKET_INFORMATION CurrentSocket;
-
-    EnterCriticalSection(&SocketListLock);
-
-    CurrentSocket = SocketListHead;
-    while (CurrentSocket)
-    {
-        if (CurrentSocket->Handle == Handle)
-        {
-            LeaveCriticalSection(&SocketListLock);
-            return CurrentSocket;
-        }
-
-        CurrentSocket = CurrentSocket->NextSocket;
-    }
-
-    LeaveCriticalSection(&SocketListLock);
-
-    return NULL;
-}
-
-int CreateContext(PSOCKET_INFORMATION Socket)
-{
-    IO_STATUS_BLOCK     IOSB;
-    SOCKET_CONTEXT      ContextData;
-    NTSTATUS            Status;
-    HANDLE              SockEvent;
-
-    Status = NtCreateEvent(&SockEvent,
-                           EVENT_ALL_ACCESS,
-                           NULL,
-                           1,
-                           FALSE);
-
-    if( !NT_SUCCESS(Status) )
-        return SOCKET_ERROR;
-
-    /* Create Context */
-    ContextData.SharedData = *Socket->SharedData;
-    ContextData.SizeOfHelperData = 0;
-    RtlCopyMemory (&ContextData.LocalAddress,
-                   Socket->LocalAddress,
-                   Socket->SharedData->SizeOfLocalAddress);
-    RtlCopyMemory (&ContextData.RemoteAddress,
-                   Socket->RemoteAddress,
-                   Socket->SharedData->SizeOfRemoteAddress);
-
-    /* Send IOCTL */
-    Status = NtDeviceIoControlFile((HANDLE)Socket->Handle,
-                                   SockEvent,
-                                   NULL,
-                                   NULL,
-                                   &IOSB,
-                                   IOCTL_AFD_SET_CONTEXT,
-                                   &ContextData,
-                                   sizeof(ContextData),
-                                   NULL,
-                                   0);
-
-    /* Wait for Completion */
-    if (Status == STATUS_PENDING)
-    {
-        WaitForSingleObject(SockEvent, INFINITE);
-        Status = IOSB.Status;
-    }
-
-    NtClose( SockEvent );
-
-    return Status == STATUS_SUCCESS ? NO_ERROR : SOCKET_ERROR;
-}
-
-BOOLEAN SockCreateOrReferenceAsyncThread(VOID)
-{
-    HANDLE hAsyncThread;
-    DWORD AsyncThreadId;
-    HANDLE AsyncEvent;
-    OBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleFlags;
-    NTSTATUS Status;
-
-    /* Check if the Thread Already Exists */
-    if (SockAsyncThreadRefCount)
-    {
-        ASSERT(SockAsyncCompletionPort);
-        return TRUE;
-    }
-
-    /* Create the Completion Port */
-    if (!SockAsyncCompletionPort)
-    {
-        Status = NtCreateIoCompletion(&SockAsyncCompletionPort,
-                                      IO_COMPLETION_ALL_ACCESS,
-                                      NULL,
-                                      2); // Allow 2 threads only
-        if (!NT_SUCCESS(Status))
-        {
-             ERR("Failed to create completion port: 0x%08x\n", Status);
-             return FALSE;
-        }
-        /* Protect Handle */
-        HandleFlags.ProtectFromClose = TRUE;
-        HandleFlags.Inherit = FALSE;
-        Status = NtSetInformationObject(SockAsyncCompletionPort,
-                                        ObjectHandleFlagInformation,
-                                        &HandleFlags,
-                                        sizeof(HandleFlags));
-    }
-
-    /* Create the Async Event */
-    Status = NtCreateEvent(&AsyncEvent,
-                           EVENT_ALL_ACCESS,
-                           NULL,
-                           NotificationEvent,
-                           FALSE);
-
-    /* Create the Async Thread */
-    hAsyncThread = CreateThread(NULL,
-                                0,
-                                (LPTHREAD_START_ROUTINE)SockAsyncThread,
-                                NULL,
-                                0,
-                                &AsyncThreadId);
-
-    /* Close the Handle */
-    NtClose(hAsyncThread);
-
-    /* Increase the Reference Count */
-    SockAsyncThreadRefCount++;
-    return TRUE;
-}
-
-int SockAsyncThread(PVOID ThreadParam)
-{
-    PVOID AsyncContext;
-    PASYNC_COMPLETION_ROUTINE AsyncCompletionRoutine;
-    IO_STATUS_BLOCK IOSB;
-    NTSTATUS Status;
-
-    /* Make the Thread Higher Priority */
-    SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL);
-
-    /* Do a KQUEUE/WorkItem Style Loop, thanks to IoCompletion Ports */
-    do
-    {
-        Status =  NtRemoveIoCompletion (SockAsyncCompletionPort,
-                                        (PVOID*)&AsyncCompletionRoutine,
-                                        &AsyncContext,
-                                        &IOSB,
-                                        NULL);
-        /* Call the Async Function */
-        if (NT_SUCCESS(Status))
-        {
-            (*AsyncCompletionRoutine)(AsyncContext, &IOSB);
-        }
-        else
-        {
-            /* It Failed, sleep for a second */
-            Sleep(1000);
-        }
-    } while ((Status != STATUS_TIMEOUT));
-
-    /* The Thread has Ended */
-    return 0;
-}
-
-BOOLEAN SockGetAsyncSelectHelperAfdHandle(VOID)
-{
-    UNICODE_STRING AfdHelper;
-    OBJECT_ATTRIBUTES ObjectAttributes;
-    IO_STATUS_BLOCK IoSb;
-    FILE_COMPLETION_INFORMATION CompletionInfo;
-    OBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleFlags;
-
-    /* First, make sure we're not already initialized */
-    if (SockAsyncHelperAfdHandle)
-    {
-        return TRUE;
-    }
-
-    /* Set up Handle Name and Object */
-    RtlInitUnicodeString(&AfdHelper, L"\\Device\\Afd\\AsyncSelectHlp" );
-                         InitializeObjectAttributes(&ObjectAttributes,
-                         &AfdHelper,
-                         OBJ_INHERIT | OBJ_CASE_INSENSITIVE,
-                         NULL,
-                         NULL);
-
-    /* Open the Handle to AFD */
-    NtCreateFile(&SockAsyncHelperAfdHandle,
-                 GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
-                 &ObjectAttributes,
-                 &IoSb,
-                 NULL,
-                 0,
-                 FILE_SHARE_READ | FILE_SHARE_WRITE,
-                 FILE_OPEN_IF,
-                 0,
-                 NULL,
-                 0);
-
-    /*
-     * Now Set up the Completion Port Information
-     * This means that whenever a Poll is finished, the routine will be executed
-     */
-    CompletionInfo.Port = SockAsyncCompletionPort;
-    CompletionInfo.Key = SockAsyncSelectCompletionRoutine;
-    NtSetInformationFile(SockAsyncHelperAfdHandle,
-                         &IoSb,
-                         &CompletionInfo,
-                         sizeof(CompletionInfo),
-                         FileCompletionInformation);
-
-
-    /* Protect the Handle */
-    HandleFlags.ProtectFromClose = TRUE;
-    HandleFlags.Inherit = FALSE;
-    NtSetInformationObject(SockAsyncCompletionPort,
-                           ObjectHandleFlagInformation,
-                           &HandleFlags,
-                           sizeof(HandleFlags));
-
-
-    /* Set this variable to true so that Send/Recv/Accept will know wether to renable disabled events */
-    SockAsyncSelectCalled = TRUE;
-    return TRUE;
-}
-
-VOID SockAsyncSelectCompletionRoutine(PVOID Context, PIO_STATUS_BLOCK IoStatusBlock)
-{
-
-    PASYNC_DATA AsyncData = Context;
-    PSOCKET_INFORMATION Socket;
-    ULONG x;
-
-    /* Get the Socket */
-    Socket = AsyncData->ParentSocket;
-
-    /* Check if the Sequence  Number Changed behind our back */
-    if (AsyncData->SequenceNumber != Socket->SharedData->SequenceNumber )
-    {
-        return;
-    }
-
-    /* Check we were manually called b/c of a failure */
-    if (!NT_SUCCESS(IoStatusBlock->Status))
-    {
-        /* FIXME: Perform Upcall */
-        return;
-    }
-
-    for (x = 1; x; x<<=1)
-    {
-        switch (AsyncData->AsyncSelectInfo.Handles[0].Events & x)
-        {
-            case AFD_EVENT_RECEIVE:
-                if (0 != (Socket->SharedData->AsyncEvents & FD_READ) &&
-                    0 == (Socket->SharedData->AsyncDisabledEvents & FD_READ))
-                {
-                    /* Make the Notification */
-                    (Upcalls.lpWPUPostMessage)(Socket->SharedData->hWnd,
-                                               Socket->SharedData->wMsg,
-                                               Socket->Handle,
-                                               WSAMAKESELECTREPLY(FD_READ, 0));
-                    /* Disable this event until the next read(); */
-                    Socket->SharedData->AsyncDisabledEvents |= FD_READ;
-                }
-            break;
-
-            case AFD_EVENT_OOB_RECEIVE:
-            if (0 != (Socket->SharedData->AsyncEvents & FD_OOB) &&
-                0 == (Socket->SharedData->AsyncDisabledEvents & FD_OOB))
-            {
-                /* Make the Notification */
-                (Upcalls.lpWPUPostMessage)(Socket->SharedData->hWnd,
-                                           Socket->SharedData->wMsg,
-                                           Socket->Handle,
-                                           WSAMAKESELECTREPLY(FD_OOB, 0));
-                /* Disable this event until the next read(); */
-                Socket->SharedData->AsyncDisabledEvents |= FD_OOB;
-            }
-            break;
-
-            case AFD_EVENT_SEND:
-                if (0 != (Socket->SharedData->AsyncEvents & FD_WRITE) &&
-                    0 == (Socket->SharedData->AsyncDisabledEvents & FD_WRITE))
-                {
-                    /* Make the Notification */
-                    (Upcalls.lpWPUPostMessage)(Socket->SharedData->hWnd,
-                                               Socket->SharedData->wMsg,
-                                               Socket->Handle,
-                                               WSAMAKESELECTREPLY(FD_WRITE, 0));
-                    /* Disable this event until the next write(); */
-                    Socket->SharedData->AsyncDisabledEvents |= FD_WRITE;
-                }
-                break;
-
-                /* FIXME: THIS IS NOT RIGHT!!! HACK HACK HACK! */
-            case AFD_EVENT_CONNECT:
-            case AFD_EVENT_CONNECT_FAIL:
-                if (0 != (Socket->SharedData->AsyncEvents & FD_CONNECT) &&
-                    0 == (Socket->SharedData->AsyncDisabledEvents & FD_CONNECT))
-                {
-                    /* Make the Notification */
-                    (Upcalls.lpWPUPostMessage)(Socket->SharedData->hWnd,
-                        Socket->SharedData->wMsg,
-                        Socket->Handle,
-                        WSAMAKESELECTREPLY(FD_CONNECT, 0));
-                    /* Disable this event forever; */
-                    Socket->SharedData->AsyncDisabledEvents |= FD_CONNECT;
-                }
-                break;
-
-            case AFD_EVENT_ACCEPT:
-                if (0 != (Socket->SharedData->AsyncEvents & FD_ACCEPT) &&
-                    0 == (Socket->SharedData->AsyncDisabledEvents & FD_ACCEPT))
-                {
-                    /* Make the Notification */
-                    (Upcalls.lpWPUPostMessage)(Socket->SharedData->hWnd,
-                                               Socket->SharedData->wMsg,
-                                               Socket->Handle,
-                                               WSAMAKESELECTREPLY(FD_ACCEPT, 0));
-                    /* Disable this event until the next accept(); */
-                    Socket->SharedData->AsyncDisabledEvents |= FD_ACCEPT;
-                }
-                break;
-
-            case AFD_EVENT_DISCONNECT:
-            case AFD_EVENT_ABORT:
-            case AFD_EVENT_CLOSE:
-                if (0 != (Socket->SharedData->AsyncEvents & FD_CLOSE) &&
-                    0 == (Socket->SharedData->AsyncDisabledEvents & FD_CLOSE))
-                {
-                    /* Make the Notification */
-                    (Upcalls.lpWPUPostMessage)(Socket->SharedData->hWnd,
-                                               Socket->SharedData->wMsg,
-                                               Socket->Handle,
-                                               WSAMAKESELECTREPLY(FD_CLOSE, 0));
-                    /* Disable this event forever; */
-                    Socket->SharedData->AsyncDisabledEvents |= FD_CLOSE;
-                }
-                 break;
-            /* FIXME: Support QOS */
-        }
-    }
-
-    /* Check if there are any events left for us to check */
-    if ((Socket->SharedData->AsyncEvents & (~Socket->SharedData->AsyncDisabledEvents)) == 0 )
-    {
-        return;
-    }
-
-    /* Keep Polling */
-    SockProcessAsyncSelect(Socket, AsyncData);
-    return;
-}
-
-VOID SockProcessAsyncSelect(PSOCKET_INFORMATION Socket, PASYNC_DATA AsyncData)
-{
-
-    ULONG lNetworkEvents;
-    NTSTATUS Status;
-
-    /* Set up the Async Data Event Info */
-    AsyncData->AsyncSelectInfo.Timeout.HighPart = 0x7FFFFFFF;
-    AsyncData->AsyncSelectInfo.Timeout.LowPart = 0xFFFFFFFF;
-    AsyncData->AsyncSelectInfo.HandleCount = 1;
-    AsyncData->AsyncSelectInfo.Exclusive = TRUE;
-    AsyncData->AsyncSelectInfo.Handles[0].Handle = Socket->Handle;
-    AsyncData->AsyncSelectInfo.Handles[0].Events = 0;
-
-    /* Remove unwanted events */
-    lNetworkEvents = Socket->SharedData->AsyncEvents & (~Socket->SharedData->AsyncDisabledEvents);
-
-    /* Set Events to wait for */
-    if (lNetworkEvents & FD_READ)
-    {
-        AsyncData->AsyncSelectInfo.Handles[0].Events |= AFD_EVENT_RECEIVE;
-    }
-
-    if (lNetworkEvents & FD_WRITE)
-    {
-        AsyncData->AsyncSelectInfo.Handles[0].Events |= AFD_EVENT_SEND;
-    }
-
-    if (lNetworkEvents & FD_OOB)
-    {
-        AsyncData->AsyncSelectInfo.Handles[0].Events |= AFD_EVENT_OOB_RECEIVE;
-    }
-
-    if (lNetworkEvents & FD_ACCEPT)
-    {
-        AsyncData->AsyncSelectInfo.Handles[0].Events |= AFD_EVENT_ACCEPT;
-    }
-
-    /* FIXME: THIS IS NOT RIGHT!!! HACK HACK HACK! */
-    if (lNetworkEvents & FD_CONNECT)
-    {
-        AsyncData->AsyncSelectInfo.Handles[0].Events |= AFD_EVENT_CONNECT | AFD_EVENT_CONNECT_FAIL;
-    }
-
-    if (lNetworkEvents & FD_CLOSE)
-    {
-        AsyncData->AsyncSelectInfo.Handles[0].Events |= AFD_EVENT_DISCONNECT | AFD_EVENT_ABORT | AFD_EVENT_CLOSE;
-    }
-
-    if (lNetworkEvents & FD_QOS)
-    {
-        AsyncData->AsyncSelectInfo.Handles[0].Events |= AFD_EVENT_QOS;
-    }
-
-    if (lNetworkEvents & FD_GROUP_QOS)
-    {
-        AsyncData->AsyncSelectInfo.Handles[0].Events |= AFD_EVENT_GROUP_QOS;
-    }
-
-    /* Send IOCTL */
-    Status = NtDeviceIoControlFile (SockAsyncHelperAfdHandle,
-                                    NULL,
-                                    NULL,
-                                    AsyncData,
-                                    &AsyncData->IoStatusBlock,
-                                    IOCTL_AFD_SELECT,
-                                    &AsyncData->AsyncSelectInfo,
-                                    sizeof(AsyncData->AsyncSelectInfo),
-                                    &AsyncData->AsyncSelectInfo,
-                                    sizeof(AsyncData->AsyncSelectInfo));
-
-    /* I/O Manager Won't call the completion routine, let's do it manually */
-    if (NT_SUCCESS(Status))
-    {
-        return;
-    }
-    else
-    {
-        AsyncData->IoStatusBlock.Status = Status;
-        SockAsyncSelectCompletionRoutine(AsyncData, &AsyncData->IoStatusBlock);
-    }
-}
-
-VOID SockProcessQueuedAsyncSelect(PVOID Context, PIO_STATUS_BLOCK IoStatusBlock)
-{
-    PASYNC_DATA AsyncData = Context;
-    BOOL FreeContext = TRUE;
-    PSOCKET_INFORMATION Socket;
-
-    /* Get the Socket */
-    Socket = AsyncData->ParentSocket;
-
-    /* If someone closed it, stop the function */
-    if (Socket->SharedData->State != SocketClosed)
-    {
-        /* Check if the Sequence Number changed by now, in which case quit */
-        if (AsyncData->SequenceNumber == Socket->SharedData->SequenceNumber)
-        {
-            /* Do the actual select, if needed */
-            if ((Socket->SharedData->AsyncEvents & (~Socket->SharedData->AsyncDisabledEvents)))
-            {
-                SockProcessAsyncSelect(Socket, AsyncData);
-                FreeContext = FALSE;
-            }
-        }
-    }
-
-    /* Free the Context */
-    if (FreeContext)
-    {
-        HeapFree(GetProcessHeap(), 0, AsyncData);
-    }
-
-    return;
-}
-
-VOID
-SockReenableAsyncSelectEvent (IN PSOCKET_INFORMATION Socket,
-                              IN ULONG Event)
-{
-    PASYNC_DATA AsyncData;
-
-    /* Make sure the event is actually disabled */
-    if (!(Socket->SharedData->AsyncDisabledEvents & Event))
-    {
-        return;
-    }
-
-    /* Re-enable it */
-    Socket->SharedData->AsyncDisabledEvents &= ~Event;
-
-    /* Return if no more events are being polled */
-    if ((Socket->SharedData->AsyncEvents & (~Socket->SharedData->AsyncDisabledEvents)) == 0 )
-    {
-        return;
-    }
-
-    /* Wait on new events */
-    AsyncData = HeapAlloc(GetProcessHeap(), 0, sizeof(ASYNC_DATA));
-    if (!AsyncData) return;
-
-    /* Create the Asynch Thread if Needed */
-    SockCreateOrReferenceAsyncThread();
-
-    /* Increase the sequence number to stop anything else */
-    Socket->SharedData->SequenceNumber++;
-
-    /* Set up the Async Data */
-    AsyncData->ParentSocket = Socket;
-    AsyncData->SequenceNumber = Socket->SharedData->SequenceNumber;
-
-    /* Begin Async Select by using I/O Completion */
-    NtSetIoCompletion(SockAsyncCompletionPort,
-                     (PVOID)&SockProcessQueuedAsyncSelect,
-                     AsyncData,
-                     0,
-                     0);
-
-    /* All done */
-    return;
-}
-
-BOOL
-WINAPI
-DllMain(HANDLE hInstDll,
-        ULONG dwReason,
-        PVOID Reserved)
-{
-
-    switch (dwReason)
-    {
-    case DLL_PROCESS_ATTACH:
-
-        TRACE("Loading MSAFD.DLL \n");
-
-        /* Don't need thread attach notifications
-        so disable them to improve performance */
-        DisableThreadLibraryCalls(hInstDll);
-
-        /* List of DLL Helpers */
-        InitializeListHead(&SockHelpersListHead);
-
-        /* Heap to use when allocating */
-        GlobalHeap = GetProcessHeap();
-
-        /* Initialize the lock that protects our socket list */
-        InitializeCriticalSection(&SocketListLock);
-
-        TRACE("MSAFD.DLL has been loaded\n");
-
-        break;
-
-    case DLL_THREAD_ATTACH:
-        break;
-
-    case DLL_THREAD_DETACH:
-        break;
-
-    case DLL_PROCESS_DETACH:
-
-        /* Delete the socket list lock */
-        DeleteCriticalSection(&SocketListLock);
-
-        break;
-    }
-
-    TRACE("DllMain of msafd.dll (leaving)\n");
-
-    return TRUE;
-}
-
-/* EOF */