/dll/win32/msafd/misc/dllmain.c
C | 3025 lines | 2301 code | 424 blank | 300 comment | 367 complexity | 0e9108fd373225420c56433e6347f8f6 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, LGPL-3.0, CC-BY-SA-3.0, AGPL-3.0, GPL-3.0, CPL-1.0
Large files files are truncated, but you can click here to view the full file
- /*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS Ancillary Function Driver DLL
- * FILE: 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>
- #if DBG
- //DWORD DebugTraceLevel = DEBUG_ULTRA;
- DWORD DebugTraceLevel = 0;
- #endif /* DBG */
- HANDLE GlobalHeap;
- WSPUPCALLTABLE 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;
- AFD_DbgPrint(MAX_TRACE, ("Creating Socket, getting TDI Name\n"));
- AFD_DbgPrint(MAX_TRACE, ("AddressFamily (%d) SocketType (%d) Protocol (%d).\n",
- AddressFamily, SocketType, Protocol));
- /* Get Helper Data and Transport */
- Status = SockGetTdiName (&AddressFamily,
- &SocketType,
- &Protocol,
- g,
- dwFlags,
- &TransportName,
- &HelperDLLContext,
- &HelperData,
- &HelperEvents);
- /* Check for error */
- if (Status != NO_ERROR)
- {
- AFD_DbgPrint(MID_TRACE,("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)
- return MsafdReturnWithErrno(STATUS_INSUFFICIENT_RESOURCES, lpErrno, 0, NULL);
- RtlZeroMemory(Socket, sizeof(*Socket));
- Socket->RefCount = 2;
- Socket->Handle = -1;
- Socket->SharedData.Listening = FALSE;
- Socket->SharedData.State = SocketOpen;
- Socket->SharedData.AddressFamily = AddressFamily;
- Socket->SharedData.SocketType = SocketType;
- Socket->SharedData.Protocol = Protocol;
- Socket->HelperContext = HelperDLLContext;
- Socket->HelperData = HelperData;
- Socket->HelperEvents = HelperEvents;
- Socket->LocalAddress = &Socket->WSLocalAddress;
- Socket->SharedData.SizeOfLocalAddress = HelperData->MaxWSAddressLength;
- Socket->RemoteAddress = &Socket->WSRemoteAddress;
- Socket->SharedData.SizeOfRemoteAddress = HelperData->MaxWSAddressLength;
- Socket->SharedData.UseDelayedAcceptance = HelperData->UseDelayedAcceptance;
- Socket->SharedData.CreateFlags = dwFlags;
- Socket->SharedData.CatalogEntryId = lpProtocolInfo->dwCatalogEntryId;
- Socket->SharedData.ServiceFlags1 = lpProtocolInfo->dwServiceFlags1;
- Socket->SharedData.ProviderFlags = lpProtocolInfo->dwProviderFlags;
- Socket->SharedData.GroupID = g;
- Socket->SharedData.GroupType = 0;
- Socket->SharedData.UseSAN = FALSE;
- Socket->SharedData.NonBlocking = FALSE; /* Sockets start blocking */
- Socket->SanData = NULL;
- /* Ask alex about this */
- if( Socket->SharedData.SocketType == SOCK_DGRAM ||
- Socket->SharedData.SocketType == SOCK_RAW )
- {
- AFD_DbgPrint(MID_TRACE,("Connectionless socket\n"));
- Socket->SharedData.ServiceFlags1 |= XP1_CONNECTIONLESS;
- }
- /* 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)
- return MsafdReturnWithErrno(STATUS_INSUFFICIENT_RESOURCES, lpErrno, 0, NULL);
- 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 */
- 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 */
- 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 */
- 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 */
- 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 */
- 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 (Status != STATUS_SUCCESS)
- {
- AFD_DbgPrint(MIN_TRACE, ("Failed to open socket\n"));
- HeapFree(GlobalHeap, 0, Socket);
- return MsafdReturnWithErrno(Status, lpErrno, 0, NULL);
- }
- /* Save Handle */
- Socket->Handle = (SOCKET)Sock;
- /* Save Group Info */
- if (g != 0)
- {
- GetSocketInformation(Socket, AFD_INFO_GROUP_ID_TYPE, NULL, NULL, &GroupData);
- 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);
- GetSocketInformation (Socket,
- AFD_INFO_RECEIVE_WINDOW_SIZE,
- NULL,
- &Socket->SharedData.SizeOfRecvBuffer,
- NULL);
- /* Save in Process Sockets List */
- EnterCriticalSection(&SocketListLock);
- Socket->NextSocket = SocketListHead;
- SocketListHead = Socket;
- LeaveCriticalSection(&SocketListLock);
- /* Create the Socket Context */
- CreateContext(Socket);
- /* Notify Winsock */
- Upcalls.lpWPUModifyIFSHandle(1, (SOCKET)Sock, lpErrno);
- /* Return Socket Handle */
- AFD_DbgPrint(MID_TRACE,("Success %x\n", Sock));
- return (SOCKET)Sock;
- error:
- AFD_DbgPrint(MID_TRACE,("Ending %x\n", Status));
- if( Socket )
- HeapFree(GlobalHeap, 0, Socket);
- if( lpErrno )
- *lpErrno = Status;
- return INVALID_SOCKET;
- }
- 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:
- case STATUS_END_OF_FILE:
- return WSAESHUTDOWN;
- case STATUS_PENDING:
- return WSA_IO_PENDING;
- case STATUS_BUFFER_TOO_SMALL:
- case STATUS_BUFFER_OVERFLOW:
- DbgPrint("MSAFD: STATUS_BUFFER_TOO_SMALL/STATUS_BUFFER_OVERFLOW\n");
- return WSAEMSGSIZE;
- case STATUS_NO_MEMORY:
- case STATUS_INSUFFICIENT_RESOURCES:
- DbgPrint("MSAFD: STATUS_NO_MEMORY/STATUS_INSUFFICIENT_RESOURCES\n");
- return WSAENOBUFS;
- case STATUS_INVALID_CONNECTION:
- DbgPrint("MSAFD: STATUS_INVALID_CONNECTION\n");
- return WSAEAFNOSUPPORT;
- case STATUS_INVALID_ADDRESS:
- DbgPrint("MSAFD: STATUS_INVALID_ADDRESS\n");
- return WSAEADDRNOTAVAIL;
- case STATUS_REMOTE_NOT_LISTENING:
- DbgPrint("MSAFD: STATUS_REMOTE_NOT_LISTENING\n");
- return WSAECONNREFUSED;
- case STATUS_NETWORK_UNREACHABLE:
- DbgPrint("MSAFD: STATUS_NETWORK_UNREACHABLE\n");
- return WSAENETUNREACH;
- case STATUS_INVALID_PARAMETER:
- DbgPrint("MSAFD: STATUS_INVALID_PARAMETER\n");
- return WSAEINVAL;
- case STATUS_CANCELLED:
- DbgPrint("MSAFD: STATUS_CANCELLED\n");
- return WSA_OPERATION_ABORTED;
- case STATUS_ADDRESS_ALREADY_EXISTS:
- DbgPrint("MSAFD: STATUS_ADDRESS_ALREADY_EXISTS\n");
- return WSAEADDRINUSE;
- case STATUS_LOCAL_DISCONNECT:
- DbgPrint("MSAFD: STATUS_LOCAL_DISCONNECT\n");
- return WSAECONNABORTED;
- case STATUS_REMOTE_DISCONNECT:
- DbgPrint("MSAFD: STATUS_REMOTE_DISCONNECT\n");
- return WSAECONNRESET;
- default:
- DbgPrint("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;
- /* Create the Wait Event */
- Status = NtCreateEvent(&SockEvent,
- GENERIC_READ | GENERIC_WRITE,
- NULL,
- 1,
- FALSE);
- if(!NT_SUCCESS(Status))
- return SOCKET_ERROR;
- /* Get the Socket Structure associate to this Socket*/
- Socket = GetSocketStructure(Handle);
- if (!Socket)
- {
- NtClose(SockEvent);
- *lpErrno = WSAENOTSOCK;
- 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;
- NtClose(SockEvent);
- return SOCKET_ERROR;
- }
- }
- /* If a Close is already in Process, give up */
- if (Socket->SharedData.State == SocketClosed)
- {
- NtClose(SockEvent);
- *lpErrno = WSAENOTSOCK;
- return SOCKET_ERROR;
- }
- /* 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))
- {
- /* 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 asyncronous operation is expected
- * and we cannot offer it
- */
- if (Socket->SharedData.NonBlocking)
- {
- NtClose(SockEvent);
- Socket->SharedData.State = OldState;
- *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;
- 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);
- 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;
- /* See below */
- BindData = HeapAlloc(GlobalHeap, 0, 0xA + SocketAddressLength);
- if (!BindData)
- {
- return MsafdReturnWithErrno(STATUS_INSUFFICIENT_RESOURCES, lpErrno, 0, NULL);
- }
- Status = NtCreateEvent(&SockEvent,
- GENERIC_READ | GENERIC_WRITE,
- NULL,
- 1,
- FALSE);
- if (!NT_SUCCESS(Status))
- {
- HeapFree(GlobalHeap, 0, BindData);
- return SOCKET_ERROR;
- }
- /* Get the Socket Structure associate to this Socket*/
- Socket = GetSocketStructure(Handle);
- if (!Socket)
- {
- HeapFree(GlobalHeap, 0, BindData);
- *lpErrno = WSAENOTSOCK;
- return SOCKET_ERROR;
- }
- /* 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));
- /* Get Address Information */
- Socket->HelperData->WSHGetSockaddrType ((PSOCKADDR)SocketAddress,
- SocketAddressLength,
- &SocketInfo);
- /* 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);
- 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)
- {
- *lpErrno = WSAENOTSOCK;
- return SOCKET_ERROR;
- }
- if (Socket->SharedData.Listening)
- return 0;
- Status = NtCreateEvent(&SockEvent,
- GENERIC_READ | GENERIC_WRITE,
- NULL,
- 1,
- FALSE);
- if( !NT_SUCCESS(Status) )
- return -1;
- /* 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 );
- 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;
- LONG OutCount = 0;
- ULONG PollBufferSize;
- PVOID PollBuffer;
- ULONG i, j = 0, x;
- HANDLE SockEvent;
- BOOL HandleCounted;
- LARGE_INTEGER Timeout;
- /* Find out how many sockets we have, and how large the buffer needs
- * to be */
- HandleCount = ( readfds ? readfds->fd_count : 0 ) +
- ( writefds ? writefds->fd_count : 0 ) +
- ( exceptfds ? exceptfds->fd_count : 0 );
- if ( HandleCount == 0 )
- {
- AFD_DbgPrint(MAX_TRACE,("HandleCount: %u. Return SOCKET_ERROR\n",
- HandleCount));
- if (lpErrno) *lpErrno = WSAEINVAL;
- return SOCKET_ERROR;
- }
- PollBufferSize = sizeof(*PollInfo) + ((HandleCount - 1) * sizeof(AFD_HANDLE));
- AFD_DbgPrint(MID_TRACE,("HandleCount: %u BufferSize: %u\n",
- HandleCount, PollBufferSize));
- /* Convert Timeout to NT Format */
- if (timeout == NULL)
- {
- Timeout.u.LowPart = -1;
- Timeout.u.HighPart = 0x7FFFFFFF;
- AFD_DbgPrint(MAX_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;
- }
- AFD_DbgPrint(MAX_TRACE,("Timeout: Orig %d.%06d kernel %d\n",
- timeout->tv_sec, timeout->tv_usec,
- Timeout.u.LowPart));
- }
- Status = NtCreateEvent(&SockEvent,
- GENERIC_READ | GENERIC_WRITE,
- NULL,
- 1,
- FALSE);
- if( !NT_SUCCESS(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;
- if (readfds != NULL) {
- for (i = 0; i < readfds->fd_count; i++, j++)
- {
- PollInfo->Handles[j].Handle = readfds->fd_array[i];
- PollInfo->Handles[j].Events = AFD_EVENT_RECEIVE |
- AFD_EVENT_DISCONNECT |
- AFD_EVENT_ABORT |
- AFD_EVENT_CLOSE |
- AFD_EVENT_ACCEPT;
- }
- }
- if (writefds != NULL)
- {
- for (i = 0; i < writefds->fd_count; i++, j++)
- {
- PollInfo->Handles[j].Handle = writefds->fd_array[i];
- PollInfo->Handles[j].Events = AFD_EVENT_SEND | AFD_EVENT_CONNECT;
- }
- }
- if (exceptfds != NULL)
- {
- for (i = 0; i < exceptfds->fd_count; i++, j++)
- {
- PollInfo->Handles[j].Handle = exceptfds->fd_array[i];
- PollInfo->Handles[j].Events = AFD_EVENT_OOB_RECEIVE | AFD_EVENT_CONNECT_FAIL;
- }
- }
- PollInfo->HandleCount = j;
- 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);
- AFD_DbgPrint(MID_TRACE,("DeviceIoControlFile => %x\n", Status));
- /* Wait for Completition */
- 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++)
- {
- HandleCounted = FALSE;
- for(x = 1; x; x<<=1)
- {
- switch (PollInfo->Handles[i].Events & x)
- {
- case AFD_EVENT_RECEIVE:
- case AFD_EVENT_DISCONNECT:
- case AFD_EVENT_ABORT:
- case AFD_EVENT_ACCEPT:
- case AFD_EVENT_CLOSE:
- AFD_DbgPrint(MID_TRACE,("Event %x on handle %x\n",
- PollInfo->Handles[i].Events,
- PollInfo->Handles[i].Handle));
- if (! HandleCounted)
- {
- OutCount++;
- HandleCounted = TRUE;
- }
- if( readfds )
- FD_SET(PollInfo->Handles[i].Handle, readfds);
- break;
- case AFD_EVENT_SEND:
- case AFD_EVENT_CONNECT:
- AFD_DbgPrint(MID_TRACE,("Event %x on handle %x\n",
- PollInfo->Handles[i].Events,
- PollInfo->Handles[i].Handle));
- if (! HandleCounted)
- {
- OutCount++;
- HandleCounted = TRUE;
- }
- if( writefds )
- FD_SET(PollInfo->Handles[i].Handle, writefds);
- break;
- case AFD_EVENT_OOB_RECEIVE:
- case AFD_EVENT_CONNECT_FAIL:
- AFD_DbgPrint(MID_TRACE,("Event %x on handle %x\n",
- PollInfo->Handles[i].Events,
- PollInfo->Handles[i].Handle));
- if (! HandleCounted)
- {
- OutCount++;
- HandleCounted = TRUE;
- }
- if( exceptfds )
- FD_SET(PollInfo->Handles[i].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;
- }
- AFD_DbgPrint(MID_TRACE,("*lpErrno = %x\n", *lpErrno));
- }
- AFD_DbgPrint(MID_TRACE,("%d events\n", OutCount));
- return OutCount;
- }
- 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;
- WSAPROTOCOL_INFOW ProtocolInfo;
- SOCKET AcceptSocket;
- PSOCKET_INFORMATION AcceptSocketInfo;
- UCHAR ReceiveBuffer[0x1A];
- HANDLE SockEvent;
- Status = NtCreateEvent(&SockEvent,
- GENERIC_READ | GENERIC_WRITE,
- NULL,
- 1,
- FALSE);
- if( !NT_SUCCESS(Status) )
- {
- MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
- return INVALID_SOCKET;
- }
- /* Dynamic Structure...ugh */
- ListenReceiveData = (PAFD_RECEIVED_ACCEPT_DATA)ReceiveBuffer;
- /* Get the Socket Structure associate to this Socket*/
- Socket = GetSocketStructure(Handle);
- if (!Socket)
- {
- NtClose(SockEvent);
- *lpErrno = WSAENOTSOCK;
- return INVALID_SOCKET;
- }
- /* 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 INVALID_SOCKET;
- }
- if (ReadSet.fd_array[0] != Socket->Handle)
- {
- NtClose(SockEvent);
- *lpErrno = WSAEWOULDBLOCK;
- return INVALID_SOCKET;
- }
- /* 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 );
- MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
- return INVALID_SOCKET;
- }
- 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 );
- MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
- return INVALID_SOCKET;
- }
- /* How much data to allocate */
- PendingDataLength = IOSB.Information;
- if (PendingDataLength)
- {
- /* Allocate needed space */
- PendingData = HeapAlloc(GlobalHeap, 0, PendingDataLength);
- if (!PendingData)
- {
- MsafdReturnWithErrno( STATUS_INSUFFICIENT_RESOURCES, lpErrno, 0, NULL );
- return INVALID_SOCKET;
- }
- /* 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 );
- MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
- return INVALID_SOCKET;
- }
- }
- }
- 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)
- {
- MsafdReturnWithErrno(STATUS_INSUFFICIENT_RESOURCES, lpErrno, 0, NULL);
- return INVALID_SOCKET;
- }
- /* 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) {
- MsafdReturnWithErrno( STATUS_INSUFFICIENT_RESOURCES, lpErrno, 0, NULL );
- return INVALID_SOCKET;
- }
- 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))
- {
- MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
- return INVALID_SOCKET;
- }
- if (CallBack == CF_REJECT )
- {
- *lpErrno = WSAECONNREFUSED;
- return INVALID_SOCKET;
- }
- else
- {
- *lpErrno = WSAECONNREFUSED;
- return INVALID_SOCKET;
- }
- }
- }
- /* Create a new Socket */
- ProtocolInfo.dwCatalogEntryId = Socket->SharedData.CatalogEntryId;
- ProtocolInfo.dwServiceFlags1 = Socket->SharedData.ServiceFlags1;
- ProtocolInfo.dwProviderFlags = Socket->SharedData.ProviderFlags;
- AcceptSocket = WSPSocket (Socket->SharedData.AddressFamily,
- Socket->SharedData.SocketType,
- Socket->SharedData.Protocol,
- &ProtocolInfo,
- GroupID,
- Socket->SharedData.CreateFlags,
- lpErrno);
- if (AcceptSocket == INVALID_SOCKET)
- return INVALID_SOCKET;
- /* 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;
- }
- if (!NT_SUCCESS(Status))
- {
- NtClose(SockEvent);
- WSPCloseSocket( AcceptSocket, lpErrno );
- MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
- return INVALID_SOCKET;
- }
- AcceptSocketInfo = GetSocketStructure(AcceptSocket);
- if (!AcceptSocketInfo)
- {
- NtClose(SockEvent);
- WSPCloseSocket( AcceptSocket, lpErrno );
- MsafdReturnWithErrno( STATUS_INVALID_CONNECTION, lpErrno, 0, NULL );
- return INVALID_SOCKET;
- }
- AcceptSocketInfo->SharedData.State = SocketConnected;
- /* Return Address in SOCKADDR FORMAT */
- if( SocketAddress )
- {
- RtlCopyMemory (SocketAddress,
- &ListenReceiveData->Address.Address[0].AddressType,
- sizeof(*RemoteAddress));
- if( SocketAddressLength )
- *SocketAddressLength = ListenReceiveData->Address.Address[0].AddressLength;
- }
- NtClose( SockEvent );
- /* Re-enable Async Event */
- SockReenableAsyncSelectEvent(Socket, FD_ACCEPT);
- AFD_DbgPrint(MID_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 INVALID_SOCKET;
- }
- }
- *lpErrno = 0;
- /* 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;
- Status = NtCreateEvent(&SockEvent,
- GENERIC_READ | GENERIC_WRITE,
- NULL,
- 1,
- FALSE);
- if (!NT_SUCCESS(Status))
- return MsafdReturnWithErrno(Status, lpErrno, 0, NULL);
- AFD_DbgPrint(MID_TRACE,("Called\n"));
- /* Get the Socket Structure associate to this Socket*/
- Socket = GetSocketStructure(Handle);
- if (!Socket)
- {
- NtClose(SockEvent);
- if (lpErrno) *lpErrno = WSAENOTSOCK;
- 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 = SocketAddres…
Large files files are truncated, but you can click here to view the full file