- Build fixes
[reactos.git] / dll / win32 / mswsock / msafd / socket.c
index 61e491d..02a1c2c 100644 (file)
@@ -797,2400 +797,3 @@ WSPCloseSocket(IN SOCKET Handle,
     return NO_ERROR;
 }
 
-/*
- * COPYRIGHT:   See COPYING in the top level directory
- * PROJECT:     ReactOS Winsock 2 SPI
- * FILE:        lib/mswsock/lib/init.c
- * PURPOSE:     DLL Initialization
- */
-
-/* INCLUDES ******************************************************************/
-#include "msafd.h"
-
-/* DATA **********************************************************************/
-
-/* FUNCTIONS *****************************************************************/
-
-INT
-WSPAPI
-SockSocket(INT AddressFamily, 
-           INT SocketType, 
-           INT Protocol, 
-           LPGUID ProviderId, 
-           GROUP g,
-           DWORD dwFlags,
-           DWORD ProviderFlags,
-           DWORD ServiceFlags,
-           DWORD CatalogEntryId,
-           PSOCKET_INFORMATION *NewSocket)
-{
-    INT ErrorCode;
-    UNICODE_STRING TransportName;
-    PVOID HelperDllContext;
-    PHELPER_DATA HelperData = NULL;
-    DWORD HelperEvents;
-    PFILE_FULL_EA_INFORMATION Ea = NULL;
-    PAFD_CREATE_PACKET AfdPacket;
-    SOCKET Handle = INVALID_SOCKET;
-    PSOCKET_INFORMATION Socket = NULL;
-    BOOLEAN LockInit = FALSE;
-    USHORT SizeOfPacket;
-    DWORD SizeOfEa, SocketLength;
-    OBJECT_ATTRIBUTES ObjectAttributes;
-    UNICODE_STRING DevName;
-    LARGE_INTEGER GroupData;
-    DWORD CreateOptions = 0;
-    IO_STATUS_BLOCK IoStatusBlock;
-    PWAH_HANDLE WahHandle;
-    NTSTATUS Status;
-    CHAR AfdPacketBuffer[96];
-
-    /* Initialize the transport name */
-    RtlInitUnicodeString(&TransportName, NULL);
-
-    /* Get Helper Data and Transport */
-    ErrorCode = SockGetTdiName(&AddressFamily,
-                               &SocketType,
-                               &Protocol,
-                               ProviderId,
-                               g,
-                               dwFlags,
-                               &TransportName,
-                               &HelperDllContext,
-                               &HelperData,
-                               &HelperEvents);
-
-    /* Check for error */
-    if (ErrorCode != NO_ERROR) goto error;
-
-    /* Figure out the socket context structure size */
-    SocketLength = sizeof(*Socket) + (HelperData->MinWSAddressLength * 2);
-
-    /* Allocate a socket */
-    Socket = SockAllocateHeapRoutine(SockPrivateHeap, 0, SocketLength);
-    if (!Socket)
-    {
-        /* Couldn't create it; we need to tell WSH so it can cleanup */
-        if (HelperEvents & WSH_NOTIFY_CLOSE)
-        {
-            HelperData->WSHNotify(HelperDllContext,
-                                  INVALID_SOCKET,
-                                  NULL,
-                                  NULL,
-                                  WSH_NOTIFY_CLOSE);
-        }
-
-        /* Fail and return */
-        ErrorCode = WSAENOBUFS;
-        goto error;
-    }
-
-    /* Initialize it */
-    RtlZeroMemory(Socket, SocketLength);
-    Socket->RefCount = 2;
-    Socket->Handle = INVALID_SOCKET;
-    Socket->SharedData.State = SocketUndefined;
-    Socket->SharedData.AddressFamily = AddressFamily;
-    Socket->SharedData.SocketType = SocketType;
-    Socket->SharedData.Protocol = Protocol;
-    Socket->ProviderId = *ProviderId;
-    Socket->HelperContext = HelperDllContext;
-    Socket->HelperData = HelperData;
-    Socket->HelperEvents = HelperEvents;
-    Socket->LocalAddress = (PVOID)(Socket + 1);
-    Socket->SharedData.SizeOfLocalAddress = HelperData->MaxWSAddressLength;
-    Socket->RemoteAddress = (PVOID)((ULONG_PTR)Socket->LocalAddress +
-                                    HelperData->MaxWSAddressLength);
-    Socket->SharedData.SizeOfRemoteAddress = HelperData->MaxWSAddressLength;
-    Socket->SharedData.UseDelayedAcceptance = HelperData->UseDelayedAcceptance;
-    Socket->SharedData.CreateFlags = dwFlags;
-    Socket->SharedData.CatalogEntryId = CatalogEntryId;
-    Socket->SharedData.ServiceFlags1 = ServiceFlags;
-    Socket->SharedData.ProviderFlags = ProviderFlags;
-    Socket->SharedData.GroupID = g;
-    Socket->SharedData.GroupType = 0;
-    Socket->SharedData.UseSAN = FALSE;
-    Socket->SanData = NULL;
-    Socket->DontUseSan = FALSE;
-
-    /* Initialize the socket lock */
-    InitializeCriticalSection(&Socket->Lock);
-    LockInit = TRUE;
-
-    /* Packet Size */
-    SizeOfPacket = TransportName.Length +  sizeof(*AfdPacket) + sizeof(WCHAR);
-
-    /* EA Size */
-    SizeOfEa = SizeOfPacket +  sizeof(*Ea) + AFD_PACKET_COMMAND_LENGTH;
-
-    /* See if our stack buffer is big enough to hold it */
-    if (SizeOfEa <= sizeof(AfdPacketBuffer))
-    {
-        /* Use our stack */
-        Ea = (PFILE_FULL_EA_INFORMATION)AfdPacketBuffer;
-    }
-    else
-    {
-        /* Allocate from heap */
-        Ea = SockAllocateHeapRoutine(SockPrivateHeap, 0, SizeOfEa);
-        if (!Ea)
-        {
-            /* Fail */
-            ErrorCode = WSAENOBUFS;
-            goto error;
-        }
-    }
-
-    /* Set up EA */
-    Ea->NextEntryOffset = 0;
-    Ea->Flags = 0;
-    Ea->EaNameLength = AFD_PACKET_COMMAND_LENGTH;
-    RtlCopyMemory(Ea->EaName, AfdCommand, AFD_PACKET_COMMAND_LENGTH + 1);
-    Ea->EaValueLength = SizeOfPacket;
-    
-    /* Set up AFD Packet */
-    AfdPacket = (PAFD_CREATE_PACKET)(Ea->EaName + Ea->EaNameLength + 1);
-    AfdPacket->SizeOfTransportName = TransportName.Length;
-    RtlCopyMemory(AfdPacket->TransportName,
-                  TransportName.Buffer, 
-                  TransportName.Length + sizeof(WCHAR));
-    AfdPacket->EndpointFlags = 0;
-
-    /* Set up Endpoint Flags */
-    if ((Socket->SharedData.ServiceFlags1 & XP1_CONNECTIONLESS)) 
-    {
-        /* Check the Socket Type */
-        if ((SocketType != SOCK_DGRAM) && (SocketType != SOCK_RAW)) 
-        {
-            /* Only RAW or UDP can be Connectionless */
-            ErrorCode = WSAEINVAL;
-            goto error;
-        }
-
-        /* Set the flag for AFD */
-        AfdPacket->EndpointFlags |= AFD_ENDPOINT_CONNECTIONLESS;
-    }
-    
-    if ((Socket->SharedData.ServiceFlags1 & XP1_MESSAGE_ORIENTED)) 
-    {
-        /* Check if this is a Stream Socket */
-        if (SocketType == SOCK_STREAM) 
-        {
-            /* Check if we actually support this */
-            if (!(Socket->SharedData.ServiceFlags1 & XP1_PSEUDO_STREAM)) 
-            {
-                /* The Provider doesn't support Message Oriented Streams */
-                ErrorCode = WSAEINVAL;
-                goto error;
-            }
-        }
-
-        /* Set the flag for AFD */
-        AfdPacket->EndpointFlags |= AFD_ENDPOINT_MESSAGE_ORIENTED;
-    }
-
-    /* If this is a Raw Socket, let AFD know */
-    if (SocketType == SOCK_RAW) AfdPacket->EndpointFlags |= AFD_ENDPOINT_RAW;
-
-    /* Check if we are a Multipoint Control/Data Root or Leaf */
-    if (dwFlags & (WSA_FLAG_MULTIPOINT_C_ROOT | 
-                   WSA_FLAG_MULTIPOINT_C_LEAF | 
-                   WSA_FLAG_MULTIPOINT_D_ROOT | 
-                   WSA_FLAG_MULTIPOINT_D_LEAF)) 
-    {
-        /* First make sure we support Multipoint */
-        if (!(Socket->SharedData.ServiceFlags1 & XP1_SUPPORT_MULTIPOINT)) 
-        {
-            /* The Provider doesn't actually support Multipoint */
-            ErrorCode = WSAEINVAL;
-            goto error;
-        }
-
-        /* Set the flag for AFD */
-        AfdPacket->EndpointFlags |= AFD_ENDPOINT_MULTIPOINT;
-
-        /* Check if we are a Control Plane Root */
-        if (dwFlags & WSA_FLAG_MULTIPOINT_C_ROOT) 
-        {    
-            /* Check if we actually support this or if we're already a leaf */
-            if ((!(Socket->SharedData.ServiceFlags1 & 
-                   XP1_MULTIPOINT_CONTROL_PLANE)) ||
-                ((dwFlags & WSA_FLAG_MULTIPOINT_C_LEAF))) 
-            {
-                ErrorCode = WSAEINVAL;
-                goto error;
-            }
-
-            /* Set the flag for AFD */
-            AfdPacket->EndpointFlags |= AFD_ENDPOINT_C_ROOT;
-        }
-
-        /* Check if we a Data Plane Root */
-        if (dwFlags & WSA_FLAG_MULTIPOINT_D_ROOT) 
-        {
-            /* Check if we actually support this or if we're already a leaf */
-            if ((!(Socket->SharedData.ServiceFlags1 & 
-                   XP1_MULTIPOINT_DATA_PLANE)) || 
-                ((dwFlags & WSA_FLAG_MULTIPOINT_D_LEAF))) 
-            {
-                ErrorCode = WSAEINVAL;
-                goto error;
-            }
-
-            /* Set the flag for AFD */
-            AfdPacket->EndpointFlags |= AFD_ENDPOINT_D_ROOT;
-        }
-    }
-
-    /* Set the group ID */
-    AfdPacket->GroupID = g;
-
-    /* Set up Object Attributes */
-    RtlInitUnicodeString(&DevName, L"\\Device\\Afd\\Endpoint");
-    InitializeObjectAttributes(&ObjectAttributes,
-                               &DevName, 
-                               OBJ_CASE_INSENSITIVE | OBJ_INHERIT, 
-                               NULL, 
-                               NULL);
-
-    /* Check if we're not using Overlapped I/O */
-    if (!(dwFlags & WSA_FLAG_OVERLAPPED))
-    {
-        /* Set Synchronous I/O */
-        CreateOptions = FILE_SYNCHRONOUS_IO_NONALERT;
-    }
-
-    /* Acquire the global lock */
-    SockAcquireRwLockShared(&SocketGlobalLock);
-
-    /* Create the Socket */
-    Status = NtCreateFile((PHANDLE)&Handle,
-                          GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
-                          &ObjectAttributes,
-                          &IoStatusBlock,
-                          NULL,
-                          0,
-                          FILE_SHARE_READ | FILE_SHARE_WRITE,
-                          FILE_OPEN_IF,
-                          CreateOptions,
-                          Ea,
-                          SizeOfEa);
-    if (!NT_SUCCESS(Status))
-    {
-        /* Release the lock and fail */
-        SockReleaseRwLockShared(&SocketGlobalLock);
-        ErrorCode = NtStatusToSocketError(Status);
-        goto error;
-    }
-
-    /* Save Handle */
-    Socket->Handle = Handle;
-
-    /* Check if a group was given */
-    if (g != 0) 
-    {
-        /* Get Group Id and Type */
-        ErrorCode = SockGetInformation(Socket,
-                                       AFD_INFO_GROUP_ID_TYPE,
-                                       NULL,
-                                       0,
-                                       NULL,
-                                       NULL,
-                                       &GroupData);
-
-        /* Save them */
-        Socket->SharedData.GroupID = GroupData.u.LowPart;
-        Socket->SharedData.GroupType = GroupData.u.HighPart;
-    }
-
-    /* Check if we need to get the window sizes */
-    if (!SockSendBufferWindow)
-    {
-        /* Get send window size */
-        SockGetInformation(Socket,
-                           AFD_INFO_SEND_WINDOW_SIZE,
-                           NULL,
-                           0,
-                           NULL,
-                           &SockSendBufferWindow, 
-                           NULL);
-
-        /* Get receive window size */
-        SockGetInformation(Socket, 
-                           AFD_INFO_RECEIVE_WINDOW_SIZE, 
-                           NULL,
-                           0,
-                           NULL,
-                           &SockReceiveBufferWindow, 
-                           NULL);
-    }
-
-    /* Save window sizes */
-    Socket->SharedData.SizeOfRecvBuffer = SockReceiveBufferWindow;
-    Socket->SharedData.SizeOfSendBuffer = SockSendBufferWindow;
-
-    /* Insert it into our table */
-    WahHandle = WahInsertHandleContext(SockContextTable, &Socket->WshContext);
-
-    /* We can release the lock now */
-    SockReleaseRwLockShared(&SocketGlobalLock);
-
-    /* Check if the handles don't match for some reason */
-    if (WahHandle != &Socket->WshContext)
-    {
-        /* Do they not match? */
-        if (WahHandle)
-        {
-            /* They don't... someone must've used CloseHandle */
-            SockDereferenceSocket((PSOCKET_INFORMATION)WahHandle);
-
-            /* Use the correct handle now */
-            WahHandle = &Socket->WshContext;
-        }
-        else
-        {
-            /* It's not that they don't match: we don't have one at all! */
-            ErrorCode = WSAENOBUFS;
-            goto error;
-        }
-    }
-
-error:
-    /* Check if we can free the transport name */
-    if ((SocketType == SOCK_RAW) && (TransportName.Buffer))
-    {
-        /* Free it */
-        RtlFreeHeap(RtlGetProcessHeap(), 0, TransportName.Buffer);
-    }
-
-    /* Check if we have the EA from the heap */
-    if ((Ea) && (Ea != (PVOID)AfdPacketBuffer))
-    {
-        /* Free it */
-        RtlFreeHeap(SockPrivateHeap, 0, Ea);
-    }
-
-    /* Check if this is actually success */
-    if (ErrorCode != NO_ERROR)
-    {
-        /* Check if we have a socket by now */
-        if (Socket)
-        {
-            /* Tell the Helper DLL we're closing it */
-            SockNotifyHelperDll(Socket, WSH_NOTIFY_CLOSE);
-
-            /* Close its handle if it's valid */
-            if (Socket->WshContext.Handle != INVALID_HANDLE_VALUE)
-            {
-                NtClose(Socket->WshContext.Handle);
-            }
-
-            /* Delete its lock */
-            if (LockInit) DeleteCriticalSection(&Socket->Lock);
-    
-            /* Remove our socket reference */
-            SockDereferenceSocket(Socket);
-
-            /* Free it */
-            RtlFreeHeap(SockPrivateHeap, 0, Socket);
-        }
-    }
-
-    /* Return Socket and error code */
-    *NewSocket = Socket;
-    return ErrorCode;
-}
-
-INT
-WSPAPI
-SockCloseSocket(IN PSOCKET_INFORMATION Socket)
-{
-    INT ErrorCode;
-    PWINSOCK_TEB_DATA ThreadData = NtCurrentTeb()->WinSockData;
-    IO_STATUS_BLOCK IoStatusBlock;
-    NTSTATUS Status;
-    AFD_DISCONNECT_INFO DisconnectInfo;
-    SOCKET_STATE OldState;
-    ULONG LingerWait;
-    ULONG SendsInProgress;
-    ULONG SleepWait;
-    BOOLEAN ActiveConnect;
-
-    /* Lock the socket */
-    EnterCriticalSection(&Socket->Lock);
-
-    /* If a Close is already in Process... */
-    if (Socket->SharedData.State == SocketClosed)
-    {
-        /* Release lock and fail */
-        LeaveCriticalSection(&Socket->Lock);
-        return WSAENOTSOCK;
-    }
-
-    /* Save the old state and set the new one to closed */
-    OldState = Socket->SharedData.State;
-    Socket->SharedData.State = SocketClosed;
-
-    /* Check if the socket has an active async data */
-    ActiveConnect = (Socket->AsyncData != NULL);
-
-    /* We're done with the socket, release the lock */
-    LeaveCriticalSection(&Socket->Lock);
-    
-    /* 
-     * If SO_LINGER is ON and the Socket was connected or had an active async
-     * connect context, then we'll disconnect it. Note that we won't do this
-     * for connection-less (UDP/RAW) sockets or if a send shutdown is active.
-     */
-    if ((OldState == SocketConnected || ActiveConnect) &&
-        !(Socket->SharedData.SendShutdown) &&
-        !MSAFD_IS_DGRAM_SOCK(Socket) &&
-        (Socket->SharedData.LingerData.l_onoff))
-    {   
-        /* 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 (SockGetInformation(Socket, 
-                                   AFD_INFO_SENDS_IN_PROGRESS,
-                                   NULL,
-                                   0,
-                                   NULL,
-                                   &SendsInProgress,
-                                   NULL))
-            {
-                /* Bail out if anything but NO_ERROR */
-                LingerWait = 0;
-                break;
-            }
-
-            /* Bail out if no more sends are pending */
-            if (!SendsInProgress) 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 asyncronous operation is expected
-             * and we cannot offer it
-             */
-            if (Socket->SharedData.NonBlocking)
-            {
-                /* Acquire the socket lock */
-                EnterCriticalSection(&Socket->Lock);
-
-                /* Restore the socket state */
-                Socket->SharedData.State = OldState;
-
-                /* Release the lock again */
-                LeaveCriticalSection(&Socket->Lock);
-
-                /* Fail with error code */
-                return WSAEWOULDBLOCK;
-            }
-            
-            /* 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;
-        }
-        
-        /*
-         * We have reached the timeout or sends are over.
-         * Disconnect if the timeout has been reached. 
-         */
-        if (LingerWait <= 0)
-        {
-            /* There is no timeout, and this is an abortive disconnect */
-            DisconnectInfo.Timeout = RtlConvertLongToLargeInteger(0);
-            DisconnectInfo.DisconnectType = AFD_DISCONNECT_ABORT;
-            
-            /* Send IOCTL */
-            Status = NtDeviceIoControlFile(Socket->WshContext.Handle,
-                                           ThreadData->EventHandle,
-                                           NULL,
-                                           NULL,
-                                           &IoStatusBlock,
-                                           IOCTL_AFD_DISCONNECT,
-                                           &DisconnectInfo,
-                                           sizeof(DisconnectInfo),
-                                           NULL,
-                                           0);
-            /* Check if the operation is pending */
-            if (Status == STATUS_PENDING)
-            {
-                /* Wait for completion */
-                SockWaitForSingleObject(ThreadData->EventHandle,
-                                        Socket->Handle,
-                                        !Socket->SharedData.LingerData.l_onoff ?
-                                        NO_BLOCKING_HOOK : ALWAYS_BLOCKING_HOOK,
-                                        NO_TIMEOUT);
-
-                /* Get new status */
-                Status = IoStatusBlock.Status;
-            }
-
-            /* We actually accept errors, unless the driver wasn't ready */
-            if (Status == STATUS_DEVICE_NOT_READY)
-            {
-                /* This is the equivalent of a WOULDBLOCK, which we fail */
-                /* Acquire the socket lock */
-                EnterCriticalSection(&Socket->Lock);
-
-                /* Restore the socket state */
-                Socket->SharedData.State = OldState;
-
-                /* Release the lock again */
-                LeaveCriticalSection(&Socket->Lock);
-
-                /* Fail with error code */
-                return WSAEWOULDBLOCK;
-            }
-        }
-    }
-
-    /* Acquire the global lock to protect the handle table */
-    SockAcquireRwLockShared(&SocketGlobalLock);
-
-    /* Protect the socket too */
-    EnterCriticalSection(&Socket->Lock);
-    
-    /* Notify the Helper DLL of Socket Closure */
-    ErrorCode = SockNotifyHelperDll(Socket, WSH_NOTIFY_CLOSE);
-
-    /* Cleanup Time! */
-    Socket->HelperContext = NULL;
-    Socket->SharedData.AsyncDisabledEvents = -1;
-    if (Socket->TdiAddressHandle)
-    {
-        /* Close and forget the handle */
-        NtClose(Socket->TdiAddressHandle);
-        Socket->TdiAddressHandle = NULL;
-    }
-    if (Socket->TdiConnectionHandle)
-    {
-        /* Close and forget the handle */
-        NtClose(Socket->TdiConnectionHandle);
-        Socket->TdiConnectionHandle = NULL;
-    }
-
-    /* Remove the handle from the table */
-    ErrorCode = WahRemoveHandleContext(SockContextTable, &Socket->WshContext);
-    if (ErrorCode == NO_ERROR)
-    {
-        /* Close the socket's handle */
-        NtClose(Socket->WshContext.Handle);
-
-        /* Dereference the socket */
-        SockDereferenceSocket(Socket);
-    }
-    else
-    {
-        /* This isn't a socket anymore, or something */
-        ErrorCode = WSAENOTSOCK;
-    }
-
-    /* Release both locks */
-    LeaveCriticalSection(&Socket->Lock);
-    SockReleaseRwLockShared(&SocketGlobalLock);
-
-    /* Return success */
-    return ErrorCode;
-}
-
-SOCKET
-WSPAPI 
-WSPSocket(INT AddressFamily, 
-          INT SocketType, 
-          INT Protocol, 
-          LPWSAPROTOCOL_INFOW lpProtocolInfo, 
-          GROUP g, 
-          DWORD dwFlags, 
-          LPINT lpErrno)  
-{
-    DWORD CatalogId;
-    SOCKET Handle = INVALID_SOCKET;
-    INT ErrorCode;
-    DWORD ServiceFlags, ProviderFlags;
-    PWINSOCK_TEB_DATA ThreadData;
-    PSOCKET_INFORMATION Socket;
-    GUID ProviderId;
-
-    /* Enter prolog */
-    ErrorCode = SockEnterApiFast(&ThreadData);
-    if (ErrorCode != NO_ERROR)
-    {
-        /* Fail */
-        *lpErrno = ErrorCode;
-        return INVALID_SOCKET;
-    }
-
-    /* Get the catalog ID */
-    CatalogId = lpProtocolInfo->dwCatalogEntryId;
-
-    /* Check if this is a duplication */
-    if(lpProtocolInfo->dwProviderReserved)
-    {
-        /* Get the duplicate handle */
-        Handle = (SOCKET)lpProtocolInfo->dwProviderReserved;
-
-        /* Get our structure for it */
-        Socket = SockFindAndReferenceSocket(Handle, TRUE);
-        if(Socket)
-        {
-            /* Tell Winsock about it */
-            Socket->Handle = SockUpcallTable->lpWPUModifyIFSHandle(CatalogId,
-                                                                   Handle,
-                                                                   &ErrorCode);
-            /* Check if we got an invalid handle back */
-            if(Socket->Handle == INVALID_SOCKET)
-            {
-                /* Restore it for the error path */
-                Socket->Handle = Handle;
-            }
-        }
-        else
-        {
-            /* The duplicate handle is invalid */
-            ErrorCode = WSAEINVAL;
-        }
-
-        /* Fail */
-        goto error;        
-    }
-
-    /* See if the address family should be recovered from the protocl info */
-    if (!AddressFamily || AddressFamily == FROM_PROTOCOL_INFO)
-    {
-        /* Use protocol info data */
-        AddressFamily = lpProtocolInfo->iAddressFamily;
-    }
-
-    /* See if the address family should be recovered from the protocl info */
-    if(!SocketType || SocketType == FROM_PROTOCOL_INFO )
-    {
-        /* Use protocol info data */
-        SocketType = lpProtocolInfo->iSocketType;
-    }
-
-    /* See if the address family should be recovered from the protocl info */
-    if(Protocol == FROM_PROTOCOL_INFO)
-    {
-        /* Use protocol info data */
-        Protocol = lpProtocolInfo->iProtocol;
-    }
-
-    /* Save the service, provider flags and provider ID */
-    ServiceFlags = lpProtocolInfo->dwServiceFlags1;
-    ProviderFlags = lpProtocolInfo->dwProviderFlags;
-    ProviderId = lpProtocolInfo->ProviderId;
-
-    /* Create the actual socket */
-    ErrorCode = SockSocket(AddressFamily,
-                           SocketType,
-                           Protocol,
-                           &ProviderId,
-                           g,
-                           dwFlags,
-                           ProviderFlags,
-                           ServiceFlags,
-                           CatalogId,
-                           &Socket);
-    if (ErrorCode == ERROR_SUCCESS)
-    {
-        /* Acquire the socket lock */
-        EnterCriticalSection(&Socket->Lock);
-
-        /* Set status to opened */
-        Socket->SharedData.State = SocketOpen;
-
-        /* Create the Socket Context */
-        ErrorCode = SockSetHandleContext(Socket);
-        if (ErrorCode != NO_ERROR)
-        {
-            /* Release the lock, close the socket and fail */
-            LeaveCriticalSection(&Socket->Lock);
-            SockCloseSocket(Socket);
-            goto error;
-        }
-
-        /* Notify Winsock */
-        Handle = SockUpcallTable->lpWPUModifyIFSHandle(Socket->SharedData.CatalogEntryId,
-                                                       (SOCKET)Socket->WshContext.Handle,
-                                                       &ErrorCode);
-
-        /* Does Winsock not like it? */
-        if (Handle == INVALID_SOCKET)
-        {
-            /* Release the lock, close the socket and fail */
-            LeaveCriticalSection(&Socket->Lock);
-            SockCloseSocket(Socket);
-            goto error;
-        }
-
-        /* Release the lock */
-        LeaveCriticalSection(&Socket->Lock);
-    }
-    
-error:
-    /* Write return code */
-    *lpErrno = ErrorCode;
-
-    /* Check if we have a socket and dereference it */
-    if (Socket) SockDereferenceSocket(Socket);
-
-    /* Return handle */
-    return Handle;
-}
-
-INT
-WSPAPI
-WSPCloseSocket(IN SOCKET Handle,
-               OUT LPINT lpErrno)
-{
-    INT ErrorCode;
-    PSOCKET_INFORMATION Socket;
-    PWINSOCK_TEB_DATA ThreadData;
-
-    /* Enter prolog */
-    ErrorCode = SockEnterApiFast(&ThreadData);
-    if (ErrorCode != NO_ERROR)
-    {
-        /* Fail */
-        *lpErrno = ErrorCode;
-        return SOCKET_ERROR;
-    }
-
-    /* Get the socket structure */
-    Socket = SockFindAndReferenceSocket(Handle, TRUE);
-    if (!Socket)
-    {
-        /* Fail */
-        *lpErrno = WSAENOTSOCK;
-        return SOCKET_ERROR;
-    }
-
-    /* Close it */
-    ErrorCode = SockCloseSocket(Socket);
-
-    /* Remove the final reference */
-    SockDereferenceSocket(Socket);
-
-    /* Check if we got here by error */
-    if (ErrorCode != NO_ERROR)
-    {
-        /* Fail */
-        *lpErrno = ErrorCode;
-        return SOCKET_ERROR;
-    }
-
-    /* Return success */
-    return NO_ERROR;
-}
-
-/*
- * COPYRIGHT:   See COPYING in the top level directory
- * PROJECT:     ReactOS Winsock 2 SPI
- * FILE:        lib/mswsock/lib/init.c
- * PURPOSE:     DLL Initialization
- */
-
-/* INCLUDES ******************************************************************/
-#include "msafd.h"
-
-/* DATA **********************************************************************/
-
-/* FUNCTIONS *****************************************************************/
-
-INT
-WSPAPI
-SockSocket(INT AddressFamily, 
-           INT SocketType, 
-           INT Protocol, 
-           LPGUID ProviderId, 
-           GROUP g,
-           DWORD dwFlags,
-           DWORD ProviderFlags,
-           DWORD ServiceFlags,
-           DWORD CatalogEntryId,
-           PSOCKET_INFORMATION *NewSocket)
-{
-    INT ErrorCode;
-    UNICODE_STRING TransportName;
-    PVOID HelperDllContext;
-    PHELPER_DATA HelperData = NULL;
-    DWORD HelperEvents;
-    PFILE_FULL_EA_INFORMATION Ea = NULL;
-    PAFD_CREATE_PACKET AfdPacket;
-    SOCKET Handle = INVALID_SOCKET;
-    PSOCKET_INFORMATION Socket = NULL;
-    BOOLEAN LockInit = FALSE;
-    USHORT SizeOfPacket;
-    DWORD SizeOfEa, SocketLength;
-    OBJECT_ATTRIBUTES ObjectAttributes;
-    UNICODE_STRING DevName;
-    LARGE_INTEGER GroupData;
-    DWORD CreateOptions = 0;
-    IO_STATUS_BLOCK IoStatusBlock;
-    PWAH_HANDLE WahHandle;
-    NTSTATUS Status;
-    CHAR AfdPacketBuffer[96];
-
-    /* Initialize the transport name */
-    RtlInitUnicodeString(&TransportName, NULL);
-
-    /* Get Helper Data and Transport */
-    ErrorCode = SockGetTdiName(&AddressFamily,
-                               &SocketType,
-                               &Protocol,
-                               ProviderId,
-                               g,
-                               dwFlags,
-                               &TransportName,
-                               &HelperDllContext,
-                               &HelperData,
-                               &HelperEvents);
-
-    /* Check for error */
-    if (ErrorCode != NO_ERROR) goto error;
-
-    /* Figure out the socket context structure size */
-    SocketLength = sizeof(*Socket) + (HelperData->MinWSAddressLength * 2);
-
-    /* Allocate a socket */
-    Socket = SockAllocateHeapRoutine(SockPrivateHeap, 0, SocketLength);
-    if (!Socket)
-    {
-        /* Couldn't create it; we need to tell WSH so it can cleanup */
-        if (HelperEvents & WSH_NOTIFY_CLOSE)
-        {
-            HelperData->WSHNotify(HelperDllContext,
-                                  INVALID_SOCKET,
-                                  NULL,
-                                  NULL,
-                                  WSH_NOTIFY_CLOSE);
-        }
-
-        /* Fail and return */
-        ErrorCode = WSAENOBUFS;
-        goto error;
-    }
-
-    /* Initialize it */
-    RtlZeroMemory(Socket, SocketLength);
-    Socket->RefCount = 2;
-    Socket->Handle = INVALID_SOCKET;
-    Socket->SharedData.State = SocketUndefined;
-    Socket->SharedData.AddressFamily = AddressFamily;
-    Socket->SharedData.SocketType = SocketType;
-    Socket->SharedData.Protocol = Protocol;
-    Socket->ProviderId = *ProviderId;
-    Socket->HelperContext = HelperDllContext;
-    Socket->HelperData = HelperData;
-    Socket->HelperEvents = HelperEvents;
-    Socket->LocalAddress = (PVOID)(Socket + 1);
-    Socket->SharedData.SizeOfLocalAddress = HelperData->MaxWSAddressLength;
-    Socket->RemoteAddress = (PVOID)((ULONG_PTR)Socket->LocalAddress +
-                                    HelperData->MaxWSAddressLength);
-    Socket->SharedData.SizeOfRemoteAddress = HelperData->MaxWSAddressLength;
-    Socket->SharedData.UseDelayedAcceptance = HelperData->UseDelayedAcceptance;
-    Socket->SharedData.CreateFlags = dwFlags;
-    Socket->SharedData.CatalogEntryId = CatalogEntryId;
-    Socket->SharedData.ServiceFlags1 = ServiceFlags;
-    Socket->SharedData.ProviderFlags = ProviderFlags;
-    Socket->SharedData.GroupID = g;
-    Socket->SharedData.GroupType = 0;
-    Socket->SharedData.UseSAN = FALSE;
-    Socket->SanData = NULL;
-    Socket->DontUseSan = FALSE;
-
-    /* Initialize the socket lock */
-    InitializeCriticalSection(&Socket->Lock);
-    LockInit = TRUE;
-
-    /* Packet Size */
-    SizeOfPacket = TransportName.Length +  sizeof(*AfdPacket) + sizeof(WCHAR);
-
-    /* EA Size */
-    SizeOfEa = SizeOfPacket +  sizeof(*Ea) + AFD_PACKET_COMMAND_LENGTH;
-
-    /* See if our stack buffer is big enough to hold it */
-    if (SizeOfEa <= sizeof(AfdPacketBuffer))
-    {
-        /* Use our stack */
-        Ea = (PFILE_FULL_EA_INFORMATION)AfdPacketBuffer;
-    }
-    else
-    {
-        /* Allocate from heap */
-        Ea = SockAllocateHeapRoutine(SockPrivateHeap, 0, SizeOfEa);
-        if (!Ea)
-        {
-            /* Fail */
-            ErrorCode = WSAENOBUFS;
-            goto error;
-        }
-    }
-
-    /* Set up EA */
-    Ea->NextEntryOffset = 0;
-    Ea->Flags = 0;
-    Ea->EaNameLength = AFD_PACKET_COMMAND_LENGTH;
-    RtlCopyMemory(Ea->EaName, AfdCommand, AFD_PACKET_COMMAND_LENGTH + 1);
-    Ea->EaValueLength = SizeOfPacket;
-    
-    /* Set up AFD Packet */
-    AfdPacket = (PAFD_CREATE_PACKET)(Ea->EaName + Ea->EaNameLength + 1);
-    AfdPacket->SizeOfTransportName = TransportName.Length;
-    RtlCopyMemory(AfdPacket->TransportName,
-                  TransportName.Buffer, 
-                  TransportName.Length + sizeof(WCHAR));
-    AfdPacket->EndpointFlags = 0;
-
-    /* Set up Endpoint Flags */
-    if ((Socket->SharedData.ServiceFlags1 & XP1_CONNECTIONLESS)) 
-    {
-        /* Check the Socket Type */
-        if ((SocketType != SOCK_DGRAM) && (SocketType != SOCK_RAW)) 
-        {
-            /* Only RAW or UDP can be Connectionless */
-            ErrorCode = WSAEINVAL;
-            goto error;
-        }
-
-        /* Set the flag for AFD */
-        AfdPacket->EndpointFlags |= AFD_ENDPOINT_CONNECTIONLESS;
-    }
-    
-    if ((Socket->SharedData.ServiceFlags1 & XP1_MESSAGE_ORIENTED)) 
-    {
-        /* Check if this is a Stream Socket */
-        if (SocketType == SOCK_STREAM) 
-        {
-            /* Check if we actually support this */
-            if (!(Socket->SharedData.ServiceFlags1 & XP1_PSEUDO_STREAM)) 
-            {
-                /* The Provider doesn't support Message Oriented Streams */
-                ErrorCode = WSAEINVAL;
-                goto error;
-            }
-        }
-
-        /* Set the flag for AFD */
-        AfdPacket->EndpointFlags |= AFD_ENDPOINT_MESSAGE_ORIENTED;
-    }
-
-    /* If this is a Raw Socket, let AFD know */
-    if (SocketType == SOCK_RAW) AfdPacket->EndpointFlags |= AFD_ENDPOINT_RAW;
-
-    /* Check if we are a Multipoint Control/Data Root or Leaf */
-    if (dwFlags & (WSA_FLAG_MULTIPOINT_C_ROOT | 
-                   WSA_FLAG_MULTIPOINT_C_LEAF | 
-                   WSA_FLAG_MULTIPOINT_D_ROOT | 
-                   WSA_FLAG_MULTIPOINT_D_LEAF)) 
-    {
-        /* First make sure we support Multipoint */
-        if (!(Socket->SharedData.ServiceFlags1 & XP1_SUPPORT_MULTIPOINT)) 
-        {
-            /* The Provider doesn't actually support Multipoint */
-            ErrorCode = WSAEINVAL;
-            goto error;
-        }
-
-        /* Set the flag for AFD */
-        AfdPacket->EndpointFlags |= AFD_ENDPOINT_MULTIPOINT;
-
-        /* Check if we are a Control Plane Root */
-        if (dwFlags & WSA_FLAG_MULTIPOINT_C_ROOT) 
-        {    
-            /* Check if we actually support this or if we're already a leaf */
-            if ((!(Socket->SharedData.ServiceFlags1 & 
-                   XP1_MULTIPOINT_CONTROL_PLANE)) ||
-                ((dwFlags & WSA_FLAG_MULTIPOINT_C_LEAF))) 
-            {
-                ErrorCode = WSAEINVAL;
-                goto error;
-            }
-
-            /* Set the flag for AFD */
-            AfdPacket->EndpointFlags |= AFD_ENDPOINT_C_ROOT;
-        }
-
-        /* Check if we a Data Plane Root */
-        if (dwFlags & WSA_FLAG_MULTIPOINT_D_ROOT) 
-        {
-            /* Check if we actually support this or if we're already a leaf */
-            if ((!(Socket->SharedData.ServiceFlags1 & 
-                   XP1_MULTIPOINT_DATA_PLANE)) || 
-                ((dwFlags & WSA_FLAG_MULTIPOINT_D_LEAF))) 
-            {
-                ErrorCode = WSAEINVAL;
-                goto error;
-            }
-
-            /* Set the flag for AFD */
-            AfdPacket->EndpointFlags |= AFD_ENDPOINT_D_ROOT;
-        }
-    }
-
-    /* Set the group ID */
-    AfdPacket->GroupID = g;
-
-    /* Set up Object Attributes */
-    RtlInitUnicodeString(&DevName, L"\\Device\\Afd\\Endpoint");
-    InitializeObjectAttributes(&ObjectAttributes,
-                               &DevName, 
-                               OBJ_CASE_INSENSITIVE | OBJ_INHERIT, 
-                               NULL, 
-                               NULL);
-
-    /* Check if we're not using Overlapped I/O */
-    if (!(dwFlags & WSA_FLAG_OVERLAPPED))
-    {
-        /* Set Synchronous I/O */
-        CreateOptions = FILE_SYNCHRONOUS_IO_NONALERT;
-    }
-
-    /* Acquire the global lock */
-    SockAcquireRwLockShared(&SocketGlobalLock);
-
-    /* Create the Socket */
-    Status = NtCreateFile((PHANDLE)&Handle,
-                          GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
-                          &ObjectAttributes,
-                          &IoStatusBlock,
-                          NULL,
-                          0,
-                          FILE_SHARE_READ | FILE_SHARE_WRITE,
-                          FILE_OPEN_IF,
-                          CreateOptions,
-                          Ea,
-                          SizeOfEa);
-    if (!NT_SUCCESS(Status))
-    {
-        /* Release the lock and fail */
-        SockReleaseRwLockShared(&SocketGlobalLock);
-        ErrorCode = NtStatusToSocketError(Status);
-        goto error;
-    }
-
-    /* Save Handle */
-    Socket->Handle = Handle;
-
-    /* Check if a group was given */
-    if (g != 0) 
-    {
-        /* Get Group Id and Type */
-        ErrorCode = SockGetInformation(Socket,
-                                       AFD_INFO_GROUP_ID_TYPE,
-                                       NULL,
-                                       0,
-                                       NULL,
-                                       NULL,
-                                       &GroupData);
-
-        /* Save them */
-        Socket->SharedData.GroupID = GroupData.u.LowPart;
-        Socket->SharedData.GroupType = GroupData.u.HighPart;
-    }
-
-    /* Check if we need to get the window sizes */
-    if (!SockSendBufferWindow)
-    {
-        /* Get send window size */
-        SockGetInformation(Socket,
-                           AFD_INFO_SEND_WINDOW_SIZE,
-                           NULL,
-                           0,
-                           NULL,
-                           &SockSendBufferWindow, 
-                           NULL);
-
-        /* Get receive window size */
-        SockGetInformation(Socket, 
-                           AFD_INFO_RECEIVE_WINDOW_SIZE, 
-                           NULL,
-                           0,
-                           NULL,
-                           &SockReceiveBufferWindow, 
-                           NULL);
-    }
-
-    /* Save window sizes */
-    Socket->SharedData.SizeOfRecvBuffer = SockReceiveBufferWindow;
-    Socket->SharedData.SizeOfSendBuffer = SockSendBufferWindow;
-
-    /* Insert it into our table */
-    WahHandle = WahInsertHandleContext(SockContextTable, &Socket->WshContext);
-
-    /* We can release the lock now */
-    SockReleaseRwLockShared(&SocketGlobalLock);
-
-    /* Check if the handles don't match for some reason */
-    if (WahHandle != &Socket->WshContext)
-    {
-        /* Do they not match? */
-        if (WahHandle)
-        {
-            /* They don't... someone must've used CloseHandle */
-            SockDereferenceSocket((PSOCKET_INFORMATION)WahHandle);
-
-            /* Use the correct handle now */
-            WahHandle = &Socket->WshContext;
-        }
-        else
-        {
-            /* It's not that they don't match: we don't have one at all! */
-            ErrorCode = WSAENOBUFS;
-            goto error;
-        }
-    }
-
-error:
-    /* Check if we can free the transport name */
-    if ((SocketType == SOCK_RAW) && (TransportName.Buffer))
-    {
-        /* Free it */
-        RtlFreeHeap(RtlGetProcessHeap(), 0, TransportName.Buffer);
-    }
-
-    /* Check if we have the EA from the heap */
-    if ((Ea) && (Ea != (PVOID)AfdPacketBuffer))
-    {
-        /* Free it */
-        RtlFreeHeap(SockPrivateHeap, 0, Ea);
-    }
-
-    /* Check if this is actually success */
-    if (ErrorCode != NO_ERROR)
-    {
-        /* Check if we have a socket by now */
-        if (Socket)
-        {
-            /* Tell the Helper DLL we're closing it */
-            SockNotifyHelperDll(Socket, WSH_NOTIFY_CLOSE);
-
-            /* Close its handle if it's valid */
-            if (Socket->WshContext.Handle != INVALID_HANDLE_VALUE)
-            {
-                NtClose(Socket->WshContext.Handle);
-            }
-
-            /* Delete its lock */
-            if (LockInit) DeleteCriticalSection(&Socket->Lock);
-    
-            /* Remove our socket reference */
-            SockDereferenceSocket(Socket);
-
-            /* Free it */
-            RtlFreeHeap(SockPrivateHeap, 0, Socket);
-        }
-    }
-
-    /* Return Socket and error code */
-    *NewSocket = Socket;
-    return ErrorCode;
-}
-
-INT
-WSPAPI
-SockCloseSocket(IN PSOCKET_INFORMATION Socket)
-{
-    INT ErrorCode;
-    PWINSOCK_TEB_DATA ThreadData = NtCurrentTeb()->WinSockData;
-    IO_STATUS_BLOCK IoStatusBlock;
-    NTSTATUS Status;
-    AFD_DISCONNECT_INFO DisconnectInfo;
-    SOCKET_STATE OldState;
-    ULONG LingerWait;
-    ULONG SendsInProgress;
-    ULONG SleepWait;
-    BOOLEAN ActiveConnect;
-
-    /* Lock the socket */
-    EnterCriticalSection(&Socket->Lock);
-
-    /* If a Close is already in Process... */
-    if (Socket->SharedData.State == SocketClosed)
-    {
-        /* Release lock and fail */
-        LeaveCriticalSection(&Socket->Lock);
-        return WSAENOTSOCK;
-    }
-
-    /* Save the old state and set the new one to closed */
-    OldState = Socket->SharedData.State;
-    Socket->SharedData.State = SocketClosed;
-
-    /* Check if the socket has an active async data */
-    ActiveConnect = (Socket->AsyncData != NULL);
-
-    /* We're done with the socket, release the lock */
-    LeaveCriticalSection(&Socket->Lock);
-    
-    /* 
-     * If SO_LINGER is ON and the Socket was connected or had an active async
-     * connect context, then we'll disconnect it. Note that we won't do this
-     * for connection-less (UDP/RAW) sockets or if a send shutdown is active.
-     */
-    if ((OldState == SocketConnected || ActiveConnect) &&
-        !(Socket->SharedData.SendShutdown) &&
-        !MSAFD_IS_DGRAM_SOCK(Socket) &&
-        (Socket->SharedData.LingerData.l_onoff))
-    {   
-        /* 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 (SockGetInformation(Socket, 
-                                   AFD_INFO_SENDS_IN_PROGRESS,
-                                   NULL,
-                                   0,
-                                   NULL,
-                                   &SendsInProgress,
-                                   NULL))
-            {
-                /* Bail out if anything but NO_ERROR */
-                LingerWait = 0;
-                break;
-            }
-
-            /* Bail out if no more sends are pending */
-            if (!SendsInProgress) 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 asyncronous operation is expected
-             * and we cannot offer it
-             */
-            if (Socket->SharedData.NonBlocking)
-            {
-                /* Acquire the socket lock */
-                EnterCriticalSection(&Socket->Lock);
-
-                /* Restore the socket state */
-                Socket->SharedData.State = OldState;
-
-                /* Release the lock again */
-                LeaveCriticalSection(&Socket->Lock);
-
-                /* Fail with error code */
-                return WSAEWOULDBLOCK;
-            }
-            
-            /* 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;
-        }
-        
-        /*
-         * We have reached the timeout or sends are over.
-         * Disconnect if the timeout has been reached. 
-         */
-        if (LingerWait <= 0)
-        {
-            /* There is no timeout, and this is an abortive disconnect */
-            DisconnectInfo.Timeout = RtlConvertLongToLargeInteger(0);
-            DisconnectInfo.DisconnectType = AFD_DISCONNECT_ABORT;
-            
-            /* Send IOCTL */
-            Status = NtDeviceIoControlFile(Socket->WshContext.Handle,
-                                           ThreadData->EventHandle,
-                                           NULL,
-                                           NULL,
-                                           &IoStatusBlock,
-                                           IOCTL_AFD_DISCONNECT,
-                                           &DisconnectInfo,
-                                           sizeof(DisconnectInfo),
-                                           NULL,
-                                           0);
-            /* Check if the operation is pending */
-            if (Status == STATUS_PENDING)
-            {
-                /* Wait for completion */
-                SockWaitForSingleObject(ThreadData->EventHandle,
-                                        Socket->Handle,
-                                        !Socket->SharedData.LingerData.l_onoff ?
-                                        NO_BLOCKING_HOOK : ALWAYS_BLOCKING_HOOK,
-                                        NO_TIMEOUT);
-
-                /* Get new status */
-                Status = IoStatusBlock.Status;
-            }
-
-            /* We actually accept errors, unless the driver wasn't ready */
-            if (Status == STATUS_DEVICE_NOT_READY)
-            {
-                /* This is the equivalent of a WOULDBLOCK, which we fail */
-                /* Acquire the socket lock */
-                EnterCriticalSection(&Socket->Lock);
-
-                /* Restore the socket state */
-                Socket->SharedData.State = OldState;
-
-                /* Release the lock again */
-                LeaveCriticalSection(&Socket->Lock);
-
-                /* Fail with error code */
-                return WSAEWOULDBLOCK;
-            }
-        }
-    }
-
-    /* Acquire the global lock to protect the handle table */
-    SockAcquireRwLockShared(&SocketGlobalLock);
-
-    /* Protect the socket too */
-    EnterCriticalSection(&Socket->Lock);
-    
-    /* Notify the Helper DLL of Socket Closure */
-    ErrorCode = SockNotifyHelperDll(Socket, WSH_NOTIFY_CLOSE);
-
-    /* Cleanup Time! */
-    Socket->HelperContext = NULL;
-    Socket->SharedData.AsyncDisabledEvents = -1;
-    if (Socket->TdiAddressHandle)
-    {
-        /* Close and forget the handle */
-        NtClose(Socket->TdiAddressHandle);
-        Socket->TdiAddressHandle = NULL;
-    }
-    if (Socket->TdiConnectionHandle)
-    {
-        /* Close and forget the handle */
-        NtClose(Socket->TdiConnectionHandle);
-        Socket->TdiConnectionHandle = NULL;
-    }
-
-    /* Remove the handle from the table */
-    ErrorCode = WahRemoveHandleContext(SockContextTable, &Socket->WshContext);
-    if (ErrorCode == NO_ERROR)
-    {
-        /* Close the socket's handle */
-        NtClose(Socket->WshContext.Handle);
-
-        /* Dereference the socket */
-        SockDereferenceSocket(Socket);
-    }
-    else
-    {
-        /* This isn't a socket anymore, or something */
-        ErrorCode = WSAENOTSOCK;
-    }
-
-    /* Release both locks */
-    LeaveCriticalSection(&Socket->Lock);
-    SockReleaseRwLockShared(&SocketGlobalLock);
-
-    /* Return success */
-    return ErrorCode;
-}
-
-SOCKET
-WSPAPI 
-WSPSocket(INT AddressFamily, 
-          INT SocketType, 
-          INT Protocol, 
-          LPWSAPROTOCOL_INFOW lpProtocolInfo, 
-          GROUP g, 
-          DWORD dwFlags, 
-          LPINT lpErrno)  
-{
-    DWORD CatalogId;
-    SOCKET Handle = INVALID_SOCKET;
-    INT ErrorCode;
-    DWORD ServiceFlags, ProviderFlags;
-    PWINSOCK_TEB_DATA ThreadData;
-    PSOCKET_INFORMATION Socket;
-    GUID ProviderId;
-
-    /* Enter prolog */
-    ErrorCode = SockEnterApiFast(&ThreadData);
-    if (ErrorCode != NO_ERROR)
-    {
-        /* Fail */
-        *lpErrno = ErrorCode;
-        return INVALID_SOCKET;
-    }
-
-    /* Get the catalog ID */
-    CatalogId = lpProtocolInfo->dwCatalogEntryId;
-
-    /* Check if this is a duplication */
-    if(lpProtocolInfo->dwProviderReserved)
-    {
-        /* Get the duplicate handle */
-        Handle = (SOCKET)lpProtocolInfo->dwProviderReserved;
-
-        /* Get our structure for it */
-        Socket = SockFindAndReferenceSocket(Handle, TRUE);
-        if(Socket)
-        {
-            /* Tell Winsock about it */
-            Socket->Handle = SockUpcallTable->lpWPUModifyIFSHandle(CatalogId,
-                                                                   Handle,
-                                                                   &ErrorCode);
-            /* Check if we got an invalid handle back */
-            if(Socket->Handle == INVALID_SOCKET)
-            {
-                /* Restore it for the error path */
-                Socket->Handle = Handle;
-            }
-        }
-        else
-        {
-            /* The duplicate handle is invalid */
-            ErrorCode = WSAEINVAL;
-        }
-
-        /* Fail */
-        goto error;        
-    }
-
-    /* See if the address family should be recovered from the protocl info */
-    if (!AddressFamily || AddressFamily == FROM_PROTOCOL_INFO)
-    {
-        /* Use protocol info data */
-        AddressFamily = lpProtocolInfo->iAddressFamily;
-    }
-
-    /* See if the address family should be recovered from the protocl info */
-    if(!SocketType || SocketType == FROM_PROTOCOL_INFO )
-    {
-        /* Use protocol info data */
-        SocketType = lpProtocolInfo->iSocketType;
-    }
-
-    /* See if the address family should be recovered from the protocl info */
-    if(Protocol == FROM_PROTOCOL_INFO)
-    {
-        /* Use protocol info data */
-        Protocol = lpProtocolInfo->iProtocol;
-    }
-
-    /* Save the service, provider flags and provider ID */
-    ServiceFlags = lpProtocolInfo->dwServiceFlags1;
-    ProviderFlags = lpProtocolInfo->dwProviderFlags;
-    ProviderId = lpProtocolInfo->ProviderId;
-
-    /* Create the actual socket */
-    ErrorCode = SockSocket(AddressFamily,
-                           SocketType,
-                           Protocol,
-                           &ProviderId,
-                           g,
-                           dwFlags,
-                           ProviderFlags,
-                           ServiceFlags,
-                           CatalogId,
-                           &Socket);
-    if (ErrorCode == ERROR_SUCCESS)
-    {
-        /* Acquire the socket lock */
-        EnterCriticalSection(&Socket->Lock);
-
-        /* Set status to opened */
-        Socket->SharedData.State = SocketOpen;
-
-        /* Create the Socket Context */
-        ErrorCode = SockSetHandleContext(Socket);
-        if (ErrorCode != NO_ERROR)
-        {
-            /* Release the lock, close the socket and fail */
-            LeaveCriticalSection(&Socket->Lock);
-            SockCloseSocket(Socket);
-            goto error;
-        }
-
-        /* Notify Winsock */
-        Handle = SockUpcallTable->lpWPUModifyIFSHandle(Socket->SharedData.CatalogEntryId,
-                                                       (SOCKET)Socket->WshContext.Handle,
-                                                       &ErrorCode);
-
-        /* Does Winsock not like it? */
-        if (Handle == INVALID_SOCKET)
-        {
-            /* Release the lock, close the socket and fail */
-            LeaveCriticalSection(&Socket->Lock);
-            SockCloseSocket(Socket);
-            goto error;
-        }
-
-        /* Release the lock */
-        LeaveCriticalSection(&Socket->Lock);
-    }
-    
-error:
-    /* Write return code */
-    *lpErrno = ErrorCode;
-
-    /* Check if we have a socket and dereference it */
-    if (Socket) SockDereferenceSocket(Socket);
-
-    /* Return handle */
-    return Handle;
-}
-
-INT
-WSPAPI
-WSPCloseSocket(IN SOCKET Handle,
-               OUT LPINT lpErrno)
-{
-    INT ErrorCode;
-    PSOCKET_INFORMATION Socket;
-    PWINSOCK_TEB_DATA ThreadData;
-
-    /* Enter prolog */
-    ErrorCode = SockEnterApiFast(&ThreadData);
-    if (ErrorCode != NO_ERROR)
-    {
-        /* Fail */
-        *lpErrno = ErrorCode;
-        return SOCKET_ERROR;
-    }
-
-    /* Get the socket structure */
-    Socket = SockFindAndReferenceSocket(Handle, TRUE);
-    if (!Socket)
-    {
-        /* Fail */
-        *lpErrno = WSAENOTSOCK;
-        return SOCKET_ERROR;
-    }
-
-    /* Close it */
-    ErrorCode = SockCloseSocket(Socket);
-
-    /* Remove the final reference */
-    SockDereferenceSocket(Socket);
-
-    /* Check if we got here by error */
-    if (ErrorCode != NO_ERROR)
-    {
-        /* Fail */
-        *lpErrno = ErrorCode;
-        return SOCKET_ERROR;
-    }
-
-    /* Return success */
-    return NO_ERROR;
-}
-
-/*
- * COPYRIGHT:   See COPYING in the top level directory
- * PROJECT:     ReactOS Winsock 2 SPI
- * FILE:        lib/mswsock/lib/init.c
- * PURPOSE:     DLL Initialization
- */
-
-/* INCLUDES ******************************************************************/
-#include "msafd.h"
-
-/* DATA **********************************************************************/
-
-/* FUNCTIONS *****************************************************************/
-
-INT
-WSPAPI
-SockSocket(INT AddressFamily, 
-           INT SocketType, 
-           INT Protocol, 
-           LPGUID ProviderId, 
-           GROUP g,
-           DWORD dwFlags,
-           DWORD ProviderFlags,
-           DWORD ServiceFlags,
-           DWORD CatalogEntryId,
-           PSOCKET_INFORMATION *NewSocket)
-{
-    INT ErrorCode;
-    UNICODE_STRING TransportName;
-    PVOID HelperDllContext;
-    PHELPER_DATA HelperData = NULL;
-    DWORD HelperEvents;
-    PFILE_FULL_EA_INFORMATION Ea = NULL;
-    PAFD_CREATE_PACKET AfdPacket;
-    SOCKET Handle = INVALID_SOCKET;
-    PSOCKET_INFORMATION Socket = NULL;
-    BOOLEAN LockInit = FALSE;
-    USHORT SizeOfPacket;
-    DWORD SizeOfEa, SocketLength;
-    OBJECT_ATTRIBUTES ObjectAttributes;
-    UNICODE_STRING DevName;
-    LARGE_INTEGER GroupData;
-    DWORD CreateOptions = 0;
-    IO_STATUS_BLOCK IoStatusBlock;
-    PWAH_HANDLE WahHandle;
-    NTSTATUS Status;
-    CHAR AfdPacketBuffer[96];
-
-    /* Initialize the transport name */
-    RtlInitUnicodeString(&TransportName, NULL);
-
-    /* Get Helper Data and Transport */
-    ErrorCode = SockGetTdiName(&AddressFamily,
-                               &SocketType,
-                               &Protocol,
-                               ProviderId,
-                               g,
-                               dwFlags,
-                               &TransportName,
-                               &HelperDllContext,
-                               &HelperData,
-                               &HelperEvents);
-
-    /* Check for error */
-    if (ErrorCode != NO_ERROR) goto error;
-
-    /* Figure out the socket context structure size */
-    SocketLength = sizeof(*Socket) + (HelperData->MinWSAddressLength * 2);
-
-    /* Allocate a socket */
-    Socket = SockAllocateHeapRoutine(SockPrivateHeap, 0, SocketLength);
-    if (!Socket)
-    {
-        /* Couldn't create it; we need to tell WSH so it can cleanup */
-        if (HelperEvents & WSH_NOTIFY_CLOSE)
-        {
-            HelperData->WSHNotify(HelperDllContext,
-                                  INVALID_SOCKET,
-                                  NULL,
-                                  NULL,
-                                  WSH_NOTIFY_CLOSE);
-        }
-
-        /* Fail and return */
-        ErrorCode = WSAENOBUFS;
-        goto error;
-    }
-
-    /* Initialize it */
-    RtlZeroMemory(Socket, SocketLength);
-    Socket->RefCount = 2;
-    Socket->Handle = INVALID_SOCKET;
-    Socket->SharedData.State = SocketUndefined;
-    Socket->SharedData.AddressFamily = AddressFamily;
-    Socket->SharedData.SocketType = SocketType;
-    Socket->SharedData.Protocol = Protocol;
-    Socket->ProviderId = *ProviderId;
-    Socket->HelperContext = HelperDllContext;
-    Socket->HelperData = HelperData;
-    Socket->HelperEvents = HelperEvents;
-    Socket->LocalAddress = (PVOID)(Socket + 1);
-    Socket->SharedData.SizeOfLocalAddress = HelperData->MaxWSAddressLength;
-    Socket->RemoteAddress = (PVOID)((ULONG_PTR)Socket->LocalAddress +
-                                    HelperData->MaxWSAddressLength);
-    Socket->SharedData.SizeOfRemoteAddress = HelperData->MaxWSAddressLength;
-    Socket->SharedData.UseDelayedAcceptance = HelperData->UseDelayedAcceptance;
-    Socket->SharedData.CreateFlags = dwFlags;
-    Socket->SharedData.CatalogEntryId = CatalogEntryId;
-    Socket->SharedData.ServiceFlags1 = ServiceFlags;
-    Socket->SharedData.ProviderFlags = ProviderFlags;
-    Socket->SharedData.GroupID = g;
-    Socket->SharedData.GroupType = 0;
-    Socket->SharedData.UseSAN = FALSE;
-    Socket->SanData = NULL;
-    Socket->DontUseSan = FALSE;
-
-    /* Initialize the socket lock */
-    InitializeCriticalSection(&Socket->Lock);
-    LockInit = TRUE;
-
-    /* Packet Size */
-    SizeOfPacket = TransportName.Length +  sizeof(*AfdPacket) + sizeof(WCHAR);
-
-    /* EA Size */
-    SizeOfEa = SizeOfPacket +  sizeof(*Ea) + AFD_PACKET_COMMAND_LENGTH;
-
-    /* See if our stack buffer is big enough to hold it */
-    if (SizeOfEa <= sizeof(AfdPacketBuffer))
-    {
-        /* Use our stack */
-        Ea = (PFILE_FULL_EA_INFORMATION)AfdPacketBuffer;
-    }
-    else
-    {
-        /* Allocate from heap */
-        Ea = SockAllocateHeapRoutine(SockPrivateHeap, 0, SizeOfEa);
-        if (!Ea)
-        {
-            /* Fail */
-            ErrorCode = WSAENOBUFS;
-            goto error;
-        }
-    }
-
-    /* Set up EA */
-    Ea->NextEntryOffset = 0;
-    Ea->Flags = 0;
-    Ea->EaNameLength = AFD_PACKET_COMMAND_LENGTH;
-    RtlCopyMemory(Ea->EaName, AfdCommand, AFD_PACKET_COMMAND_LENGTH + 1);
-    Ea->EaValueLength = SizeOfPacket;
-    
-    /* Set up AFD Packet */
-    AfdPacket = (PAFD_CREATE_PACKET)(Ea->EaName + Ea->EaNameLength + 1);
-    AfdPacket->SizeOfTransportName = TransportName.Length;
-    RtlCopyMemory(AfdPacket->TransportName,
-                  TransportName.Buffer, 
-                  TransportName.Length + sizeof(WCHAR));
-    AfdPacket->EndpointFlags = 0;
-
-    /* Set up Endpoint Flags */
-    if ((Socket->SharedData.ServiceFlags1 & XP1_CONNECTIONLESS)) 
-    {
-        /* Check the Socket Type */
-        if ((SocketType != SOCK_DGRAM) && (SocketType != SOCK_RAW)) 
-        {
-            /* Only RAW or UDP can be Connectionless */
-            ErrorCode = WSAEINVAL;
-            goto error;
-        }
-
-        /* Set the flag for AFD */
-        AfdPacket->EndpointFlags |= AFD_ENDPOINT_CONNECTIONLESS;
-    }
-    
-    if ((Socket->SharedData.ServiceFlags1 & XP1_MESSAGE_ORIENTED)) 
-    {
-        /* Check if this is a Stream Socket */
-        if (SocketType == SOCK_STREAM) 
-        {
-            /* Check if we actually support this */
-            if (!(Socket->SharedData.ServiceFlags1 & XP1_PSEUDO_STREAM)) 
-            {
-                /* The Provider doesn't support Message Oriented Streams */
-                ErrorCode = WSAEINVAL;
-                goto error;
-            }
-        }
-
-        /* Set the flag for AFD */
-        AfdPacket->EndpointFlags |= AFD_ENDPOINT_MESSAGE_ORIENTED;
-    }
-
-    /* If this is a Raw Socket, let AFD know */
-    if (SocketType == SOCK_RAW) AfdPacket->EndpointFlags |= AFD_ENDPOINT_RAW;
-
-    /* Check if we are a Multipoint Control/Data Root or Leaf */
-    if (dwFlags & (WSA_FLAG_MULTIPOINT_C_ROOT | 
-                   WSA_FLAG_MULTIPOINT_C_LEAF | 
-                   WSA_FLAG_MULTIPOINT_D_ROOT | 
-                   WSA_FLAG_MULTIPOINT_D_LEAF)) 
-    {
-        /* First make sure we support Multipoint */
-        if (!(Socket->SharedData.ServiceFlags1 & XP1_SUPPORT_MULTIPOINT)) 
-        {
-            /* The Provider doesn't actually support Multipoint */
-            ErrorCode = WSAEINVAL;
-            goto error;
-        }
-
-        /* Set the flag for AFD */
-        AfdPacket->EndpointFlags |= AFD_ENDPOINT_MULTIPOINT;
-
-        /* Check if we are a Control Plane Root */
-        if (dwFlags & WSA_FLAG_MULTIPOINT_C_ROOT) 
-        {    
-            /* Check if we actually support this or if we're already a leaf */
-            if ((!(Socket->SharedData.ServiceFlags1 & 
-                   XP1_MULTIPOINT_CONTROL_PLANE)) ||
-                ((dwFlags & WSA_FLAG_MULTIPOINT_C_LEAF))) 
-            {
-                ErrorCode = WSAEINVAL;
-                goto error;
-            }
-
-            /* Set the flag for AFD */
-            AfdPacket->EndpointFlags |= AFD_ENDPOINT_C_ROOT;
-        }
-
-        /* Check if we a Data Plane Root */
-        if (dwFlags & WSA_FLAG_MULTIPOINT_D_ROOT) 
-        {
-            /* Check if we actually support this or if we're already a leaf */
-            if ((!(Socket->SharedData.ServiceFlags1 & 
-                   XP1_MULTIPOINT_DATA_PLANE)) || 
-                ((dwFlags & WSA_FLAG_MULTIPOINT_D_LEAF))) 
-            {
-                ErrorCode = WSAEINVAL;
-                goto error;
-            }
-
-            /* Set the flag for AFD */
-            AfdPacket->EndpointFlags |= AFD_ENDPOINT_D_ROOT;
-        }
-    }
-
-    /* Set the group ID */
-    AfdPacket->GroupID = g;
-
-    /* Set up Object Attributes */
-    RtlInitUnicodeString(&DevName, L"\\Device\\Afd\\Endpoint");
-    InitializeObjectAttributes(&ObjectAttributes,
-                               &DevName, 
-                               OBJ_CASE_INSENSITIVE | OBJ_INHERIT, 
-                               NULL, 
-                               NULL);
-
-    /* Check if we're not using Overlapped I/O */
-    if (!(dwFlags & WSA_FLAG_OVERLAPPED))
-    {
-        /* Set Synchronous I/O */
-        CreateOptions = FILE_SYNCHRONOUS_IO_NONALERT;
-    }
-
-    /* Acquire the global lock */
-    SockAcquireRwLockShared(&SocketGlobalLock);
-
-    /* Create the Socket */
-    Status = NtCreateFile((PHANDLE)&Handle,
-                          GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
-                          &ObjectAttributes,
-                          &IoStatusBlock,
-                          NULL,
-                          0,
-                          FILE_SHARE_READ | FILE_SHARE_WRITE,
-                          FILE_OPEN_IF,
-                          CreateOptions,
-                          Ea,
-                          SizeOfEa);
-    if (!NT_SUCCESS(Status))
-    {
-        /* Release the lock and fail */
-        SockReleaseRwLockShared(&SocketGlobalLock);
-        ErrorCode = NtStatusToSocketError(Status);
-        goto error;
-    }
-
-    /* Save Handle */
-    Socket->Handle = Handle;
-
-    /* Check if a group was given */
-    if (g != 0) 
-    {
-        /* Get Group Id and Type */
-        ErrorCode = SockGetInformation(Socket,
-                                       AFD_INFO_GROUP_ID_TYPE,
-                                       NULL,
-                                       0,
-                                       NULL,
-                                       NULL,
-                                       &GroupData);
-
-        /* Save them */
-        Socket->SharedData.GroupID = GroupData.u.LowPart;
-        Socket->SharedData.GroupType = GroupData.u.HighPart;
-    }
-
-    /* Check if we need to get the window sizes */
-    if (!SockSendBufferWindow)
-    {
-        /* Get send window size */
-        SockGetInformation(Socket,
-                           AFD_INFO_SEND_WINDOW_SIZE,
-                           NULL,
-                           0,
-                           NULL,
-                           &SockSendBufferWindow, 
-                           NULL);
-
-        /* Get receive window size */
-        SockGetInformation(Socket, 
-                           AFD_INFO_RECEIVE_WINDOW_SIZE, 
-                           NULL,
-                           0,
-                           NULL,
-                           &SockReceiveBufferWindow, 
-                           NULL);
-    }
-
-    /* Save window sizes */
-    Socket->SharedData.SizeOfRecvBuffer = SockReceiveBufferWindow;
-    Socket->SharedData.SizeOfSendBuffer = SockSendBufferWindow;
-
-    /* Insert it into our table */
-    WahHandle = WahInsertHandleContext(SockContextTable, &Socket->WshContext);
-
-    /* We can release the lock now */
-    SockReleaseRwLockShared(&SocketGlobalLock);
-
-    /* Check if the handles don't match for some reason */
-    if (WahHandle != &Socket->WshContext)
-    {
-        /* Do they not match? */
-        if (WahHandle)
-        {
-            /* They don't... someone must've used CloseHandle */
-            SockDereferenceSocket((PSOCKET_INFORMATION)WahHandle);
-
-            /* Use the correct handle now */
-            WahHandle = &Socket->WshContext;
-        }
-        else
-        {
-            /* It's not that they don't match: we don't have one at all! */
-            ErrorCode = WSAENOBUFS;
-            goto error;
-        }
-    }
-
-error:
-    /* Check if we can free the transport name */
-    if ((SocketType == SOCK_RAW) && (TransportName.Buffer))
-    {
-        /* Free it */
-        RtlFreeHeap(RtlGetProcessHeap(), 0, TransportName.Buffer);
-    }
-
-    /* Check if we have the EA from the heap */
-    if ((Ea) && (Ea != (PVOID)AfdPacketBuffer))
-    {
-        /* Free it */
-        RtlFreeHeap(SockPrivateHeap, 0, Ea);
-    }
-
-    /* Check if this is actually success */
-    if (ErrorCode != NO_ERROR)
-    {
-        /* Check if we have a socket by now */
-        if (Socket)
-        {
-            /* Tell the Helper DLL we're closing it */
-            SockNotifyHelperDll(Socket, WSH_NOTIFY_CLOSE);
-
-            /* Close its handle if it's valid */
-            if (Socket->WshContext.Handle != INVALID_HANDLE_VALUE)
-            {
-                NtClose(Socket->WshContext.Handle);
-            }
-
-            /* Delete its lock */
-            if (LockInit) DeleteCriticalSection(&Socket->Lock);
-    
-            /* Remove our socket reference */
-            SockDereferenceSocket(Socket);
-
-            /* Free it */
-            RtlFreeHeap(SockPrivateHeap, 0, Socket);
-        }
-    }
-
-    /* Return Socket and error code */
-    *NewSocket = Socket;
-    return ErrorCode;
-}
-
-INT
-WSPAPI
-SockCloseSocket(IN PSOCKET_INFORMATION Socket)
-{
-    INT ErrorCode;
-    PWINSOCK_TEB_DATA ThreadData = NtCurrentTeb()->WinSockData;
-    IO_STATUS_BLOCK IoStatusBlock;
-    NTSTATUS Status;
-    AFD_DISCONNECT_INFO DisconnectInfo;
-    SOCKET_STATE OldState;
-    ULONG LingerWait;
-    ULONG SendsInProgress;
-    ULONG SleepWait;
-    BOOLEAN ActiveConnect;
-
-    /* Lock the socket */
-    EnterCriticalSection(&Socket->Lock);
-
-    /* If a Close is already in Process... */
-    if (Socket->SharedData.State == SocketClosed)
-    {
-        /* Release lock and fail */
-        LeaveCriticalSection(&Socket->Lock);
-        return WSAENOTSOCK;
-    }
-
-    /* Save the old state and set the new one to closed */
-    OldState = Socket->SharedData.State;
-    Socket->SharedData.State = SocketClosed;
-
-    /* Check if the socket has an active async data */
-    ActiveConnect = (Socket->AsyncData != NULL);
-
-    /* We're done with the socket, release the lock */
-    LeaveCriticalSection(&Socket->Lock);
-    
-    /* 
-     * If SO_LINGER is ON and the Socket was connected or had an active async
-     * connect context, then we'll disconnect it. Note that we won't do this
-     * for connection-less (UDP/RAW) sockets or if a send shutdown is active.
-     */
-    if ((OldState == SocketConnected || ActiveConnect) &&
-        !(Socket->SharedData.SendShutdown) &&
-        !MSAFD_IS_DGRAM_SOCK(Socket) &&
-        (Socket->SharedData.LingerData.l_onoff))
-    {   
-        /* 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 (SockGetInformation(Socket, 
-                                   AFD_INFO_SENDS_IN_PROGRESS,
-                                   NULL,
-                                   0,
-                                   NULL,
-                                   &SendsInProgress,
-                                   NULL))
-            {
-                /* Bail out if anything but NO_ERROR */
-                LingerWait = 0;
-                break;
-            }
-
-            /* Bail out if no more sends are pending */
-            if (!SendsInProgress) 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 asyncronous operation is expected
-             * and we cannot offer it
-             */
-            if (Socket->SharedData.NonBlocking)
-            {
-                /* Acquire the socket lock */
-                EnterCriticalSection(&Socket->Lock);
-
-                /* Restore the socket state */
-                Socket->SharedData.State = OldState;
-
-                /* Release the lock again */
-                LeaveCriticalSection(&Socket->Lock);
-
-                /* Fail with error code */
-                return WSAEWOULDBLOCK;
-            }
-            
-            /* 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;
-        }
-        
-        /*
-         * We have reached the timeout or sends are over.
-         * Disconnect if the timeout has been reached. 
-         */
-        if (LingerWait <= 0)
-        {
-            /* There is no timeout, and this is an abortive disconnect */
-            DisconnectInfo.Timeout = RtlConvertLongToLargeInteger(0);
-            DisconnectInfo.DisconnectType = AFD_DISCONNECT_ABORT;
-            
-            /* Send IOCTL */
-            Status = NtDeviceIoControlFile(Socket->WshContext.Handle,
-                                           ThreadData->EventHandle,
-                                           NULL,
-                                           NULL,
-                                           &IoStatusBlock,
-                                           IOCTL_AFD_DISCONNECT,
-                                           &DisconnectInfo,
-                                           sizeof(DisconnectInfo),
-                                           NULL,
-                                           0);
-            /* Check if the operation is pending */
-            if (Status == STATUS_PENDING)
-            {
-                /* Wait for completion */
-                SockWaitForSingleObject(ThreadData->EventHandle,
-                                        Socket->Handle,
-                                        !Socket->SharedData.LingerData.l_onoff ?
-                                        NO_BLOCKING_HOOK : ALWAYS_BLOCKING_HOOK,
-                                        NO_TIMEOUT);
-
-                /* Get new status */
-                Status = IoStatusBlock.Status;
-            }
-
-            /* We actually accept errors, unless the driver wasn't ready */
-            if (Status == STATUS_DEVICE_NOT_READY)
-            {
-                /* This is the equivalent of a WOULDBLOCK, which we fail */
-                /* Acquire the socket lock */
-                EnterCriticalSection(&Socket->Lock);
-
-                /* Restore the socket state */
-                Socket->SharedData.State = OldState;
-
-                /* Release the lock again */
-                LeaveCriticalSection(&Socket->Lock);
-
-                /* Fail with error code */
-                return WSAEWOULDBLOCK;
-            }
-        }
-    }
-
-    /* Acquire the global lock to protect the handle table */
-    SockAcquireRwLockShared(&SocketGlobalLock);
-
-    /* Protect the socket too */
-    EnterCriticalSection(&Socket->Lock);
-    
-    /* Notify the Helper DLL of Socket Closure */
-    ErrorCode = SockNotifyHelperDll(Socket, WSH_NOTIFY_CLOSE);
-
-    /* Cleanup Time! */
-    Socket->HelperContext = NULL;
-    Socket->SharedData.AsyncDisabledEvents = -1;
-    if (Socket->TdiAddressHandle)
-    {
-        /* Close and forget the handle */
-        NtClose(Socket->TdiAddressHandle);
-        Socket->TdiAddressHandle = NULL;
-    }
-    if (Socket->TdiConnectionHandle)
-    {
-        /* Close and forget the handle */
-        NtClose(Socket->TdiConnectionHandle);
-        Socket->TdiConnectionHandle = NULL;
-    }
-
-    /* Remove the handle from the table */
-    ErrorCode = WahRemoveHandleContext(SockContextTable, &Socket->WshContext);
-    if (ErrorCode == NO_ERROR)
-    {
-        /* Close the socket's handle */
-        NtClose(Socket->WshContext.Handle);
-
-        /* Dereference the socket */
-        SockDereferenceSocket(Socket);
-    }
-    else
-    {
-        /* This isn't a socket anymore, or something */
-        ErrorCode = WSAENOTSOCK;
-    }
-
-    /* Release both locks */
-    LeaveCriticalSection(&Socket->Lock);
-    SockReleaseRwLockShared(&SocketGlobalLock);
-
-    /* Return success */
-    return ErrorCode;
-}
-
-SOCKET
-WSPAPI 
-WSPSocket(INT AddressFamily, 
-          INT SocketType, 
-          INT Protocol, 
-          LPWSAPROTOCOL_INFOW lpProtocolInfo, 
-          GROUP g, 
-          DWORD dwFlags, 
-          LPINT lpErrno)  
-{
-    DWORD CatalogId;
-    SOCKET Handle = INVALID_SOCKET;
-    INT ErrorCode;
-    DWORD ServiceFlags, ProviderFlags;
-    PWINSOCK_TEB_DATA ThreadData;
-    PSOCKET_INFORMATION Socket;
-    GUID ProviderId;
-
-    /* Enter prolog */
-    ErrorCode = SockEnterApiFast(&ThreadData);
-    if (ErrorCode != NO_ERROR)
-    {
-        /* Fail */
-        *lpErrno = ErrorCode;
-        return INVALID_SOCKET;
-    }
-
-    /* Get the catalog ID */
-    CatalogId = lpProtocolInfo->dwCatalogEntryId;
-
-    /* Check if this is a duplication */
-    if(lpProtocolInfo->dwProviderReserved)
-    {
-        /* Get the duplicate handle */
-        Handle = (SOCKET)lpProtocolInfo->dwProviderReserved;
-
-        /* Get our structure for it */
-        Socket = SockFindAndReferenceSocket(Handle, TRUE);
-        if(Socket)
-        {
-            /* Tell Winsock about it */
-            Socket->Handle = SockUpcallTable->lpWPUModifyIFSHandle(CatalogId,
-                                                                   Handle,
-                                                                   &ErrorCode);
-            /* Check if we got an invalid handle back */
-            if(Socket->Handle == INVALID_SOCKET)
-            {
-                /* Restore it for the error path */
-                Socket->Handle = Handle;
-            }
-        }
-        else
-        {
-            /* The duplicate handle is invalid */
-            ErrorCode = WSAEINVAL;
-        }
-
-        /* Fail */
-        goto error;        
-    }
-
-    /* See if the address family should be recovered from the protocl info */
-    if (!AddressFamily || AddressFamily == FROM_PROTOCOL_INFO)
-    {
-        /* Use protocol info data */
-        AddressFamily = lpProtocolInfo->iAddressFamily;
-    }
-
-    /* See if the address family should be recovered from the protocl info */
-    if(!SocketType || SocketType == FROM_PROTOCOL_INFO )
-    {
-        /* Use protocol info data */
-        SocketType = lpProtocolInfo->iSocketType;
-    }
-
-    /* See if the address family should be recovered from the protocl info */
-    if(Protocol == FROM_PROTOCOL_INFO)
-    {
-        /* Use protocol info data */
-        Protocol = lpProtocolInfo->iProtocol;
-    }
-
-    /* Save the service, provider flags and provider ID */
-    ServiceFlags = lpProtocolInfo->dwServiceFlags1;
-    ProviderFlags = lpProtocolInfo->dwProviderFlags;
-    ProviderId = lpProtocolInfo->ProviderId;
-
-    /* Create the actual socket */
-    ErrorCode = SockSocket(AddressFamily,
-                           SocketType,
-                           Protocol,
-                           &ProviderId,
-                           g,
-                           dwFlags,
-                           ProviderFlags,
-                           ServiceFlags,
-                           CatalogId,
-                           &Socket);
-    if (ErrorCode == ERROR_SUCCESS)
-    {
-        /* Acquire the socket lock */
-        EnterCriticalSection(&Socket->Lock);
-
-        /* Set status to opened */
-        Socket->SharedData.State = SocketOpen;
-
-        /* Create the Socket Context */
-        ErrorCode = SockSetHandleContext(Socket);
-        if (ErrorCode != NO_ERROR)
-        {
-            /* Release the lock, close the socket and fail */
-            LeaveCriticalSection(&Socket->Lock);
-            SockCloseSocket(Socket);
-            goto error;
-        }
-
-        /* Notify Winsock */
-        Handle = SockUpcallTable->lpWPUModifyIFSHandle(Socket->SharedData.CatalogEntryId,
-                                                       (SOCKET)Socket->WshContext.Handle,
-                                                       &ErrorCode);
-
-        /* Does Winsock not like it? */
-        if (Handle == INVALID_SOCKET)
-        {
-            /* Release the lock, close the socket and fail */
-            LeaveCriticalSection(&Socket->Lock);
-            SockCloseSocket(Socket);
-            goto error;
-        }
-
-        /* Release the lock */
-        LeaveCriticalSection(&Socket->Lock);
-    }
-    
-error:
-    /* Write return code */
-    *lpErrno = ErrorCode;
-
-    /* Check if we have a socket and dereference it */
-    if (Socket) SockDereferenceSocket(Socket);
-
-    /* Return handle */
-    return Handle;
-}
-
-INT
-WSPAPI
-WSPCloseSocket(IN SOCKET Handle,
-               OUT LPINT lpErrno)
-{
-    INT ErrorCode;
-    PSOCKET_INFORMATION Socket;
-    PWINSOCK_TEB_DATA ThreadData;
-
-    /* Enter prolog */
-    ErrorCode = SockEnterApiFast(&ThreadData);
-    if (ErrorCode != NO_ERROR)
-    {
-        /* Fail */
-        *lpErrno = ErrorCode;
-        return SOCKET_ERROR;
-    }
-
-    /* Get the socket structure */
-    Socket = SockFindAndReferenceSocket(Handle, TRUE);
-    if (!Socket)
-    {
-        /* Fail */
-        *lpErrno = WSAENOTSOCK;
-        return SOCKET_ERROR;
-    }
-
-    /* Close it */
-    ErrorCode = SockCloseSocket(Socket);
-
-    /* Remove the final reference */
-    SockDereferenceSocket(Socket);
-
-    /* Check if we got here by error */
-    if (ErrorCode != NO_ERROR)
-    {
-        /* Fail */
-        *lpErrno = ErrorCode;
-        return SOCKET_ERROR;
-    }
-
-    /* Return success */
-    return NO_ERROR;
-}
-