From 53d48069bad8acd7a8de7e1304e2e3abfbc92647 Mon Sep 17 00:00:00 2001 From: Kamil Hornicek Date: Wed, 14 Jan 2009 14:41:25 +0000 Subject: [PATCH] [FORMATTING] Fix indentation. No code change. svn path=/trunk/; revision=38759 --- reactos/dll/win32/msafd/misc/dllmain.c | 3646 +++++++++++++----------- reactos/dll/win32/msafd/misc/sndrcv.c | 948 +++--- 2 files changed, 2408 insertions(+), 2186 deletions(-) diff --git a/reactos/dll/win32/msafd/misc/dllmain.c b/reactos/dll/win32/msafd/misc/dllmain.c index c27dd0d5784..2cd1ec2a891 100644 --- a/reactos/dll/win32/msafd/misc/dllmain.c +++ b/reactos/dll/win32/msafd/misc/dllmain.c @@ -1,15 +1,15 @@ - /* * 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) + * Alex Ionescu (alex@relsoft.net) * REVISIONS: - * CSH 01/09-2000 Created - * Alex 16/07/2004 - Complete Rewrite + * CSH 01/09-2000 Created + * Alex 16/07/2004 - Complete Rewrite */ + #include #include @@ -30,16 +30,8 @@ HANDLE SockAsyncHelperAfdHandle; HANDLE SockAsyncCompletionPort; BOOLEAN SockAsyncSelectCalled; -SOCKET -WSPAPI -WSPSocket( - int AddressFamily, - int SocketType, - int Protocol, - LPWSAPROTOCOL_INFOW lpProtocolInfo, - GROUP g, - DWORD dwFlags, - LPINT lpErrno) + + /* * FUNCTION: Creates a new socket * ARGUMENTS: @@ -53,248 +45,315 @@ WSPSocket( * 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, PrevSocket = 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; + OBJECT_ATTRIBUTES Object; + IO_STATUS_BLOCK IOSB; + USHORT SizeOfPacket; + ULONG SizeOfEA; + PAFD_CREATE_PACKET AfdPacket; + HANDLE Sock; + PSOCKET_INFORMATION Socket = NULL, PrevSocket = 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)); + 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); + /* 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; - } + /* 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"); + /* AFD Device Name */ + RtlInitUnicodeString(&DevName, L"\\Device\\Afd\\Endpoint"); - /* Set Socket Data */ - Socket = HeapAlloc(GlobalHeap, 0, sizeof(*Socket)); - RtlZeroMemory(Socket, sizeof(*Socket)); - Socket->RefCount = 2; - Socket->Handle = -1; - 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; + /* Set Socket Data */ + Socket = HeapAlloc(GlobalHeap, 0, sizeof(*Socket)); + RtlZeroMemory(Socket, sizeof(*Socket)); + Socket->RefCount = 2; + Socket->Handle = -1; + 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; + /* 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); + 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; } - /* 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); - 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)) { - goto error; /* Only RAW or UDP can be Connectionless */ - } - 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) { - goto error; /* The Provider doesn't actually support Message Oriented Streams */ - } - } - 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) { - goto error; /* The Provider doesn't actually support Multipoint */ - } - 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)) { - goto error; /* The Provider doesn't support Control Planes, or you already gave a leaf */ - } - 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)) { - goto error; /* The Provider doesn't support Data Planes, or you already gave a leaf */ - } - AfdPacket->EndpointFlags |= AFD_ENDPOINT_D_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); + &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) */ - ZwCreateFile(&Sock, - GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, - &Object, - &IOSB, - NULL, - 0, - FILE_SHARE_READ | FILE_SHARE_WRITE, - FILE_OPEN_IF, - 0, - EABuffer, - SizeOfEA); + /* 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) */ + ZwCreateFile(&Sock, + GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, + &Object, + &IOSB, + NULL, + 0, + FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN_IF, + 0, + EABuffer, + SizeOfEA); - /* Save Handle */ - Socket->Handle = (SOCKET)Sock; + /* Save Handle */ + Socket->Handle = (SOCKET)Sock; - /* XXX See if there's a structure we can reuse -- We need to do this - * more properly. */ - PrevSocket = GetSocketStructure( (SOCKET)Sock ); + /* XXX See if there's a structure we can reuse -- We need to do this + * more properly. */ + PrevSocket = GetSocketStructure( (SOCKET)Sock ); - if( PrevSocket ) { - RtlCopyMemory( PrevSocket, Socket, sizeof(*Socket) ); - RtlFreeHeap( GlobalHeap, 0, Socket ); - Socket = PrevSocket; - } + if( PrevSocket ) + { + RtlCopyMemory( PrevSocket, Socket, sizeof(*Socket) ); + RtlFreeHeap( GlobalHeap, 0, Socket ); + Socket = PrevSocket; + } - /* Save Group Info */ - if (g != 0) { - GetSocketInformation(Socket, AFD_INFO_GROUP_ID_TYPE, 0, &GroupData); + /* Save Group Info */ + if (g != 0) + { + GetSocketInformation(Socket, AFD_INFO_GROUP_ID_TYPE, 0, &GroupData); + Socket->SharedData.GroupID = GroupData.u.LowPart; + Socket->SharedData.GroupType = GroupData.u.HighPart; + } - 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, + &Socket->SharedData.SizeOfSendBuffer, + NULL); - /* Get Window Sizes and Save them */ - GetSocketInformation (Socket, - AFD_INFO_SEND_WINDOW_SIZE, - &Socket->SharedData.SizeOfSendBuffer, - NULL); - GetSocketInformation (Socket, - AFD_INFO_RECEIVE_WINDOW_SIZE, - &Socket->SharedData.SizeOfRecvBuffer, - NULL); + GetSocketInformation (Socket, + AFD_INFO_RECEIVE_WINDOW_SIZE, + &Socket->SharedData.SizeOfRecvBuffer, + NULL); - /* Save in Process Sockets List */ - Sockets[SocketCount] = Socket; - SocketCount ++; + /* Save in Process Sockets List */ + Sockets[SocketCount] = Socket; + SocketCount ++; - /* Create the Socket Context */ - CreateContext(Socket); + /* Create the Socket Context */ + CreateContext(Socket); - /* Notify Winsock */ - Upcalls.lpWPUModifyIFSHandle(1, (SOCKET)Sock, lpErrno); + /* Notify Winsock */ + Upcalls.lpWPUModifyIFSHandle(1, (SOCKET)Sock, lpErrno); - /* Return Socket Handle */ - AFD_DbgPrint(MID_TRACE,("Success %x\n", Sock)); - return (SOCKET)Sock; + /* Return Socket Handle */ + AFD_DbgPrint(MID_TRACE,("Success %x\n", Sock)); + + return (SOCKET)Sock; error: - AFD_DbgPrint(MID_TRACE,("Ending %x\n", Status)); + AFD_DbgPrint(MID_TRACE,("Ending %x\n", Status)); - if( lpErrno ) *lpErrno = Status; + if( lpErrno ) + *lpErrno = Status; - return INVALID_SOCKET; + return INVALID_SOCKET; } -DWORD MsafdReturnWithErrno( NTSTATUS Status, LPINT Errno, DWORD Received, - LPDWORD ReturnedBytes ) { - if( ReturnedBytes ) *ReturnedBytes = 0; - if( Errno ) { - switch (Status) { - case STATUS_CANT_WAIT: *Errno = WSAEWOULDBLOCK; break; - case STATUS_TIMEOUT: *Errno = WSAETIMEDOUT; break; +DWORD MsafdReturnWithErrno(NTSTATUS Status, + LPINT Errno, + DWORD Received, + LPDWORD ReturnedBytes) +{ + if( ReturnedBytes ) + *ReturnedBytes = 0; + if( Errno ) + { + switch (Status) + { + case STATUS_CANT_WAIT: + *Errno = WSAEWOULDBLOCK; + break; + case STATUS_TIMEOUT: + *Errno = WSAETIMEDOUT; + break; case STATUS_SUCCESS: /* Return Number of bytes Read */ - if( ReturnedBytes ) *ReturnedBytes = Received; break; - case STATUS_END_OF_FILE: *Errno = WSAESHUTDOWN; break; - case STATUS_PENDING: *Errno = WSA_IO_PENDING; break; - case STATUS_BUFFER_OVERFLOW: DbgPrint("MSAFD: STATUS_BUFFER_TOO_SMALL/STATUS_BUFFER_OVERFLOW\n"); *Errno = WSAEMSGSIZE; break; - case STATUS_NO_MEMORY: /* Fall through to STATUS_INSUFFICIENT_RESOURCES */ - case STATUS_INSUFFICIENT_RESOURCES: DbgPrint("MSAFD: STATUS_NO_MEMORY/STATUS_INSUFFICIENT_RESOURCES\n"); *Errno = WSA_NOT_ENOUGH_MEMORY; break; - case STATUS_INVALID_CONNECTION: DbgPrint("MSAFD: STATUS_INVALID_CONNECTION\n"); *Errno = WSAEAFNOSUPPORT; break; - case STATUS_REMOTE_NOT_LISTENING: DbgPrint("MSAFD: STATUS_REMOTE_NOT_LISTENING\n"); *Errno = WSAECONNRESET; break; - case STATUS_FILE_CLOSED: DbgPrint("MSAFD: STATUS_FILE_CLOSED\n"); *Errno = WSAENOTSOCK; break; - case STATUS_INVALID_PARAMETER: DbgPrint("MSAFD: STATUS_INVALID_PARAMETER\n"); *Errno = WSAEINVAL; break; + if( ReturnedBytes ) + *ReturnedBytes = Received; + break; + case STATUS_END_OF_FILE: + *Errno = WSAESHUTDOWN; + break; + case STATUS_PENDING: + *Errno = WSA_IO_PENDING; + break; + case STATUS_BUFFER_OVERFLOW: + DbgPrint("MSAFD: STATUS_BUFFER_TOO_SMALL/STATUS_BUFFER_OVERFLOW\n"); + *Errno = WSAEMSGSIZE; + break; + case STATUS_NO_MEMORY: /* Fall through to STATUS_INSUFFICIENT_RESOURCES */ + case STATUS_INSUFFICIENT_RESOURCES: + DbgPrint("MSAFD: STATUS_NO_MEMORY/STATUS_INSUFFICIENT_RESOURCES\n"); + *Errno = WSA_NOT_ENOUGH_MEMORY; + break; + case STATUS_INVALID_CONNECTION: + DbgPrint("MSAFD: STATUS_INVALID_CONNECTION\n"); + *Errno = WSAEAFNOSUPPORT; + break; + case STATUS_REMOTE_NOT_LISTENING: + DbgPrint("MSAFD: STATUS_REMOTE_NOT_LISTENING\n"); + *Errno = WSAECONNRESET; + break; + case STATUS_FILE_CLOSED: + DbgPrint("MSAFD: STATUS_FILE_CLOSED\n"); + *Errno = WSAENOTSOCK; + break; + case STATUS_INVALID_PARAMETER: + DbgPrint("MSAFD: STATUS_INVALID_PARAMETER\n"); + *Errno = WSAEINVAL; + break; default: DbgPrint("MSAFD: Error %x is unknown\n", Status); - *Errno = WSAEINVAL; break; + *Errno = WSAEINVAL; + break; } } @@ -302,12 +361,6 @@ DWORD MsafdReturnWithErrno( NTSTATUS Status, LPINT Errno, DWORD Received, return Status == STATUS_SUCCESS ? 0 : SOCKET_ERROR; } - -INT -WSPAPI -WSPCloseSocket( - IN SOCKET Handle, - OUT LPINT lpErrno) /* * FUNCTION: Closes an open socket * ARGUMENTS: @@ -316,6 +369,10 @@ WSPCloseSocket( * 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; @@ -329,15 +386,17 @@ WSPCloseSocket( GENERIC_READ | GENERIC_WRITE, NULL, 1, - FALSE); + FALSE); - if(!NT_SUCCESS(Status)) return SOCKET_ERROR; + if(!NT_SUCCESS(Status)) + return SOCKET_ERROR; /* Get the Socket Structure associate to this Socket*/ Socket = GetSocketStructure(Handle); /* If a Close is already in Process, give up */ - if (Socket->SharedData.State == SocketClosed) { + if (Socket->SharedData.State == SocketClosed) + { *lpErrno = WSAENOTSOCK; return SOCKET_ERROR; } @@ -345,66 +404,69 @@ WSPCloseSocket( /* 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)) { + if ((OldState == SocketConnected) && (Socket->SharedData.LingerData.l_onoff)) + { ULONG LingerWait; 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) { - + while (LingerWait) + { /* Find out how many Sends are in Progress */ - if (GetSocketInformation(Socket, + if (GetSocketInformation(Socket, AFD_INFO_SENDS_IN_PROGRESS, &SendsInProgress, - NULL)) { + NULL)) + { /* Bail out if anything but NO_ERROR */ LingerWait = 0; break; } /* Bail out if no more sends are pending */ - if (!SendsInProgress) break; - + 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) { + if (Socket->SharedData.NonBlocking) + { 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. - */ + * 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) { - + * We have reached the timeout or sends are over. + * Disconnect if the timeout has been reached. + */ + if (LingerWait <= 0) + { DisconnectInfo.Timeout = RtlConvertLongToLargeInteger(0); DisconnectInfo.DisconnectType = AFD_DISCONNECT_ABORT; - + /* Send IOCTL */ Status = NtDeviceIoControlFile((HANDLE)Handle, SockEvent, @@ -416,16 +478,17 @@ WSPCloseSocket( sizeof(DisconnectInfo), NULL, 0); - + /* Wait for return */ - if (Status == STATUS_PENDING) { + if (Status == STATUS_PENDING) + { WaitForSingleObject(SockEvent, INFINITE); - } + } } } - + /* FIXME: We should notify the Helper DLL of WSH_NOTIFY_CLOSE */ - + /* Cleanup Time! */ Socket->HelperContext = NULL; Socket->SharedData.AsyncDisabledEvents = -1; @@ -440,13 +503,7 @@ WSPCloseSocket( return NO_ERROR; } -INT -WSPAPI -WSPBind( - SOCKET Handle, - const struct sockaddr *SocketAddress, - int SocketAddressLength, - LPINT lpErrno) + /* * FUNCTION: Associates a local address with a socket * ARGUMENTS: @@ -457,203 +514,230 @@ WSPBind( * 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; - UCHAR BindBuffer[0x1A]; - SOCKADDR_INFO SocketInfo; - HANDLE SockEvent; + IO_STATUS_BLOCK IOSB; + PAFD_BIND_DATA BindData; + PSOCKET_INFORMATION Socket = NULL; + NTSTATUS Status; + UCHAR BindBuffer[0x1A]; + SOCKADDR_INFO SocketInfo; + HANDLE SockEvent; - Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE, - NULL, 1, FALSE ); + Status = NtCreateEvent(&SockEvent, + GENERIC_READ | GENERIC_WRITE, + NULL, + 1, + FALSE); - if( !NT_SUCCESS(Status) ) return -1; + if( !NT_SUCCESS(Status) ) + return -1; - /* Get the Socket Structure associate to this Socket*/ - Socket = GetSocketStructure(Handle); + /* Get the Socket Structure associate to this Socket*/ + Socket = GetSocketStructure(Handle); - /* Dynamic Structure...ugh */ - BindData = (PAFD_BIND_DATA)BindBuffer; + /* Dynamic Structure...ugh */ + BindData = (PAFD_BIND_DATA)BindBuffer; - /* 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 up Address in TDI Format */ + BindData->Address.TAAddressCount = 1; + BindData->Address.Address[0].AddressLength = SocketAddressLength - sizeof(SocketAddress->sa_family); + BindData->Address.Address[0].AddressType = SocketAddress->sa_family; + RtlCopyMemory (BindData->Address.Address[0].Address, + SocketAddress->sa_data, + SocketAddressLength - sizeof(SocketAddress->sa_family)); - /* Set the Share Type */ - if (Socket->SharedData.ExclusiveAddressUse) { - BindData->ShareType = AFD_SHARE_EXCLUSIVE; - } - else if (SocketInfo.EndpointInfo == SockaddrEndpointInfoWildcard) { - BindData->ShareType = AFD_SHARE_WILDCARD; - } - else if (Socket->SharedData.ReuseAddresses) { - BindData->ShareType = AFD_SHARE_REUSE; - } else { - BindData->ShareType = AFD_SHARE_UNIQUE; - } + /* Get Address Information */ + Socket->HelperData->WSHGetSockaddrType ((PSOCKADDR)SocketAddress, + SocketAddressLength, + &SocketInfo); - /* 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; - } - - /* Set up Socket Data */ - Socket->SharedData.State = SocketBound; - Socket->TdiAddressHandle = (HANDLE)IOSB.Information; + /* 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; + } - NtClose( SockEvent ); + /* 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 */ - return MsafdReturnWithErrno - ( Status, lpErrno, 0, NULL ); + /* Wait for return */ + if (Status == STATUS_PENDING) + { + WaitForSingleObject(SockEvent, INFINITE); + Status = IOSB.Status; + } + + /* Set up Socket Data */ + Socket->SharedData.State = SocketBound; + Socket->TdiAddressHandle = (HANDLE)IOSB.Information; + + NtClose( SockEvent ); + + return MsafdReturnWithErrno ( Status, lpErrno, 0, NULL ); } int WSPAPI -WSPListen( - SOCKET Handle, - int Backlog, - LPINT lpErrno) +WSPListen(SOCKET Handle, + int Backlog, + LPINT lpErrno) { - IO_STATUS_BLOCK IOSB; - AFD_LISTEN_DATA ListenData; - PSOCKET_INFORMATION Socket = NULL; - HANDLE SockEvent; - NTSTATUS Status; + IO_STATUS_BLOCK IOSB; + AFD_LISTEN_DATA ListenData; + PSOCKET_INFORMATION Socket = NULL; + HANDLE SockEvent; + NTSTATUS Status; - Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE, - NULL, 1, FALSE ); + Status = NtCreateEvent(&SockEvent, + GENERIC_READ | GENERIC_WRITE, + NULL, + 1, + FALSE); - if( !NT_SUCCESS(Status) ) return -1; + if( !NT_SUCCESS(Status) ) + return -1; - /* Get the Socket Structure associate to this Socket*/ - Socket = GetSocketStructure(Handle); + /* Get the Socket Structure associate to this Socket*/ + Socket = GetSocketStructure(Handle); - /* Set Up Listen Structure */ - ListenData.UseSAN = FALSE; - ListenData.UseDelayedAcceptance = Socket->SharedData.UseDelayedAcceptance; - ListenData.Backlog = Backlog; + /* 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; - } + /* Send IOCTL */ + Status = NtDeviceIoControlFile((HANDLE)Socket->Handle, + SockEvent, + NULL, + NULL, + &IOSB, + IOCTL_AFD_START_LISTEN, + &ListenData, + sizeof(ListenData), + NULL, + 0); - /* Set to Listening */ - Socket->SharedData.Listening = TRUE; + /* Wait for return */ + if (Status == STATUS_PENDING) + { + WaitForSingleObject(SockEvent, INFINITE); + Status = IOSB.Status; + } - NtClose( SockEvent ); + /* Set to Listening */ + Socket->SharedData.Listening = TRUE; - return MsafdReturnWithErrno - ( Status, lpErrno, 0, NULL ); + NtClose( SockEvent ); + + return MsafdReturnWithErrno ( Status, lpErrno, 0, NULL ); } int -WSPAPI -WSPSelect( - int nfds, - fd_set *readfds, - fd_set *writefds, - fd_set *exceptfds, - struct timeval *timeout, - LPINT lpErrno) +WSPAPI +WSPSelect(int nfds, + fd_set *readfds, + fd_set *writefds, + fd_set *exceptfds, + struct timeval *timeout, + LPINT lpErrno) { - IO_STATUS_BLOCK IOSB; - PAFD_POLL_INFO PollInfo; - NTSTATUS Status; - LONG HandleCount, OutCount = 0; - ULONG PollBufferSize; - PVOID PollBuffer; - ULONG i, j = 0, x; - HANDLE SockEvent; - BOOL HandleCounted; - LARGE_INTEGER Timeout; - + IO_STATUS_BLOCK IOSB; + PAFD_POLL_INFO PollInfo; + NTSTATUS Status; + LONG HandleCount, 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 || nfds != 0 ) HandleCount = nfds * 3; + HandleCount = ( readfds ? readfds->fd_count : 0 ) + + ( writefds ? writefds->fd_count : 0 ) + + ( exceptfds ? exceptfds->fd_count : 0 ); + + if( HandleCount < 0 || nfds != 0 ) + HandleCount = nfds * 3; PollBufferSize = sizeof(*PollInfo) + (HandleCount * sizeof(AFD_HANDLE)); - + AFD_DbgPrint(MID_TRACE,("HandleCount: %d BufferSize: %d\n", - HandleCount, PollBufferSize)); + 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)); + if (timeout == NULL) + { + Timeout.u.LowPart = -1; + Timeout.u.HighPart = 0x7FFFFFFF; + AFD_DbgPrint(MAX_TRACE,("Infinite timeout\n")); } - - Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE, - NULL, 1, FALSE ); - - if( !NT_SUCCESS(Status) ) return SOCKET_ERROR; - + 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; + if (!PollBuffer) + { + if (lpErrno) + *lpErrno = WSAEFAULT; + NtClose(SockEvent); + return SOCKET_ERROR; } PollInfo = (PAFD_POLL_INFO)PollBuffer; @@ -663,115 +747,136 @@ WSPSelect( /* 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_ACCEPT; - } + 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_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 (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; - } + 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 = ((PCHAR)&PollInfo->Handles[j+1]) - ((PCHAR)PollInfo); /* Send IOCTL */ - Status = NtDeviceIoControlFile( (HANDLE)PollInfo->Handles[0].Handle, - SockEvent, - NULL, - NULL, - &IOSB, - IOCTL_AFD_SELECT, - PollInfo, - PollBufferSize, - PollInfo, - PollBufferSize); + 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); + if (Status == STATUS_PENDING) + { + WaitForSingleObject(SockEvent, INFINITE); } - + /* Clear the Structures */ - if( readfds ) FD_ZERO(readfds); - if( writefds ) FD_ZERO(writefds); - if( exceptfds ) FD_ZERO(exceptfds); - + 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; - } - } + /* 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 ) { + if( lpErrno ) + { + switch( IOSB.Status ) + { case STATUS_SUCCESS: - case STATUS_TIMEOUT: *lpErrno = 0; break; - default: *lpErrno = WSAEINVAL; break; + case STATUS_TIMEOUT: + *lpErrno = 0; + break; + default: + *lpErrno = WSAEINVAL; + break; } AFD_DbgPrint(MID_TRACE,("*lpErrno = %x\n", *lpErrno)); } @@ -783,769 +888,811 @@ WSPSelect( SOCKET WSPAPI -WSPAccept( - SOCKET Handle, - struct sockaddr *SocketAddress, - int *SocketAddressLength, - LPCONDITIONPROC lpfnCondition, - DWORD_PTR dwCallbackData, - LPINT lpErrno) +WSPAccept(SOCKET Handle, + struct sockaddr *SocketAddress, + int *SocketAddressLength, + LPCONDITIONPROC lpfnCondition, + DWORD_PTR 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; - UCHAR ReceiveBuffer[0x1A]; - HANDLE SockEvent; + 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; + UCHAR ReceiveBuffer[0x1A]; + HANDLE SockEvent; - Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE, - NULL, 1, FALSE ); + Status = NtCreateEvent(&SockEvent, + GENERIC_READ | GENERIC_WRITE, + NULL, + 1, + FALSE); - if( !NT_SUCCESS(Status) ) { - MsafdReturnWithErrno( Status, lpErrno, 0, NULL ); - return INVALID_SOCKET; - } + if( !NT_SUCCESS(Status) ) + { + MsafdReturnWithErrno( Status, lpErrno, 0, NULL ); + return INVALID_SOCKET; + } - /* Dynamic Structure...ugh */ - ListenReceiveData = (PAFD_RECEIVED_ACCEPT_DATA)ReceiveBuffer; + /* Dynamic Structure...ugh */ + ListenReceiveData = (PAFD_RECEIVED_ACCEPT_DATA)ReceiveBuffer; - /* Get the Socket Structure associate to this Socket*/ - Socket = GetSocketStructure(Handle); + /* Get the Socket Structure associate to this Socket*/ + Socket = GetSocketStructure(Handle); - /* 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 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; - WSPSelect(0, &ReadSet, NULL, NULL, &Timeout, NULL); + WSPSelect(0, &ReadSet, NULL, NULL, &Timeout, NULL); - if (ReadSet.fd_array[0] != Socket->Handle) return 0; + if (ReadSet.fd_array[0] != Socket->Handle) + return 0; - /* 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; - } + /* Send IOCTL */ + Status = NtDeviceIoControlFile((HANDLE)Socket->Handle, + SockEvent, + NULL, + NULL, + &IOSB, + IOCTL_AFD_WAIT_FOR_LISTEN, + NULL, + 0, + ListenReceiveData, + 0xA + sizeof(*ListenReceiveData)); - if (!NT_SUCCESS(Status)) { - NtClose( SockEvent ); - MsafdReturnWithErrno( Status, lpErrno, 0, NULL ); - return INVALID_SOCKET; - } + /* Wait for return */ + if (Status == STATUS_PENDING) + { + WaitForSingleObject(SockEvent, INFINITE); + Status = IOSB.Status; + } - 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; + if (!NT_SUCCESS(Status)) + { + NtClose( SockEvent ); + MsafdReturnWithErrno( Status, lpErrno, 0, NULL ); + return INVALID_SOCKET; + } - /* 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 (lpfnCondition != NULL) + { + if ((Socket->SharedData.ServiceFlags1 & XP1_CONNECT_DATA) != 0) + { + /* Find out how much data is pending */ + PendingAcceptData.SequenceNumber = ListenReceiveData->SequenceNumber; + PendingAcceptData.ReturnSize = TRUE; - if (!NT_SUCCESS(Status)) { - NtClose( SockEvent ); - MsafdReturnWithErrno( Status, lpErrno, 0, NULL ); - return INVALID_SOCKET; - } + /* Send IOCTL */ + Status = NtDeviceIoControlFile((HANDLE)Socket->Handle, + SockEvent, + NULL, + NULL, + &IOSB, + IOCTL_AFD_GET_PENDING_CONNECT_DATA, + &PendingAcceptData, + sizeof(PendingAcceptData), + &PendingAcceptData, + sizeof(PendingAcceptData)); - /* How much data to allocate */ - PendingDataLength = IOSB.Information; + /* Wait for return */ + if (Status == STATUS_PENDING) + { + WaitForSingleObject(SockEvent, INFINITE); + Status = IOSB.Status; + } - if (PendingDataLength) { - /* Allocate needed space */ - PendingData = HeapAlloc(GlobalHeap, 0, PendingDataLength); + if (!NT_SUCCESS(Status)) + { + NtClose( SockEvent ); + MsafdReturnWithErrno( Status, lpErrno, 0, NULL ); + return INVALID_SOCKET; + } - /* We want the data now */ - PendingAcceptData.ReturnSize = FALSE; + /* How much data to allocate */ + PendingDataLength = IOSB.Information; - /* Send IOCTL */ - Status = NtDeviceIoControlFile( (HANDLE)Socket->Handle, - SockEvent, - NULL, - NULL, - &IOSB, - IOCTL_AFD_GET_PENDING_CONNECT_DATA, - &PendingAcceptData, - sizeof(PendingAcceptData), - PendingData, - PendingDataLength); + if (PendingDataLength) + { + /* Allocate needed space */ + PendingData = HeapAlloc(GlobalHeap, 0, PendingDataLength); - /* Wait for return */ - if (Status == STATUS_PENDING) { - WaitForSingleObject(SockEvent, INFINITE); - Status = IOSB.Status; - } + /* We want the data now */ + PendingAcceptData.ReturnSize = FALSE; - if (!NT_SUCCESS(Status)) { - NtClose( SockEvent ); - MsafdReturnWithErrno( Status, lpErrno, 0, NULL ); - return INVALID_SOCKET; - } - } - } + /* Send IOCTL */ + Status = NtDeviceIoControlFile((HANDLE)Socket->Handle, + SockEvent, + NULL, + NULL, + &IOSB, + IOCTL_AFD_GET_PENDING_CONNECT_DATA, + &PendingAcceptData, + sizeof(PendingAcceptData), + PendingData, + PendingDataLength); - 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; + /* Wait for return */ + if (Status == STATUS_PENDING) + { + WaitForSingleObject(SockEvent, INFINITE); + Status = IOSB.Status; + } - /* 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); - 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, - NULL); - - /* Set up the Accept Structure */ - AcceptData.ListenHandle = 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)) { - WSPCloseSocket( AcceptSocket, lpErrno ); - MsafdReturnWithErrno( Status, lpErrno, 0, NULL ); - return INVALID_SOCKET; - } - - /* Return Address in SOCKADDR FORMAT */ - if( SocketAddress ) { - RtlCopyMemory (SocketAddress, - &ListenReceiveData->Address.Address[0].AddressType, - sizeof(*RemoteAddress)); - if( SocketAddressLength ) - *SocketAddressLength = - ListenReceiveData->Address.Address[0].AddressLength; + if (!NT_SUCCESS(Status)) + { + NtClose( SockEvent ); + MsafdReturnWithErrno( Status, lpErrno, 0, NULL ); + return INVALID_SOCKET; + } + } } - NtClose( SockEvent ); - + 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; + + /* 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); + 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, + NULL); + + /* Set up the Accept Structure */ + AcceptData.ListenHandle = 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)) + { + WSPCloseSocket( AcceptSocket, lpErrno ); + MsafdReturnWithErrno( Status, lpErrno, 0, NULL ); + return INVALID_SOCKET; + } + + /* 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)); - + *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) +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; - PSOCKET_INFORMATION Socket = NULL; - NTSTATUS Status; - UCHAR ConnectBuffer[0x22]; - ULONG ConnectDataLength; - ULONG InConnectDataLength; - INT BindAddressLength; - PSOCKADDR BindAddress; - HANDLE SockEvent; + IO_STATUS_BLOCK IOSB; + PAFD_CONNECT_INFO ConnectInfo; + PSOCKET_INFORMATION Socket = NULL; + NTSTATUS Status; + UCHAR ConnectBuffer[0x22]; + ULONG ConnectDataLength; + ULONG InConnectDataLength; + INT BindAddressLength; + PSOCKADDR BindAddress; + HANDLE SockEvent; - Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE, - NULL, 1, FALSE ); + Status = NtCreateEvent(&SockEvent, + GENERIC_READ | GENERIC_WRITE, + NULL, + 1, + FALSE); - if( !NT_SUCCESS(Status) ) return -1; + if( !NT_SUCCESS(Status) ) + return -1; - AFD_DbgPrint(MID_TRACE,("Called\n")); - - /* Get the Socket Structure associate to this Socket*/ - Socket = GetSocketStructure(Handle); - - /* Bind us First */ - if (Socket->SharedData.State == SocketOpen) { - - /* Get the Wildcard Address */ - BindAddressLength = Socket->HelperData->MaxWSAddressLength; - BindAddress = HeapAlloc(GetProcessHeap(), 0, BindAddressLength); - Socket->HelperData->WSHGetWildcardSockaddr (Socket->HelperContext, - BindAddress, - &BindAddressLength); - - /* Bind it */ - WSPBind(Handle, BindAddress, BindAddressLength, NULL); - } - - /* 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; - } - } - - /* Dynamic Structure...ugh */ - ConnectInfo = (PAFD_CONNECT_INFO)ConnectBuffer; - - /* Set up Address in TDI Format */ - ConnectInfo->RemoteAddress.TAAddressCount = 1; - ConnectInfo->RemoteAddress.Address[0].AddressLength = SocketAddressLength - sizeof(SocketAddress->sa_family); - ConnectInfo->RemoteAddress.Address[0].AddressType = SocketAddress->sa_family; - RtlCopyMemory (ConnectInfo->RemoteAddress.Address[0].Address, - SocketAddress->sa_data, - SocketAddressLength - sizeof(SocketAddress->sa_family)); - - /* - * Disable FD_WRITE and FD_CONNECT - * The latter fixes a race condition where the FD_CONNECT is re-enabled - * at the end of this function right after the Async Thread disables it. - * This should only happen at the *next* WSPConnect - */ - if (Socket->SharedData.AsyncEvents & FD_CONNECT) { - Socket->SharedData.AsyncDisabledEvents |= FD_CONNECT | FD_WRITE; - } - - /* Tell AFD that we want Connection Data back, have it allocate a buffer */ - if (lpCalleeData != NULL) { - InConnectDataLength = lpCalleeData->len; - Status = NtDeviceIoControlFile((HANDLE)Handle, - SockEvent, - NULL, - NULL, - &IOSB, - IOCTL_AFD_SET_CONNECT_DATA_SIZE, - &InConnectDataLength, - sizeof(InConnectDataLength), - NULL, - 0); - - /* Wait for return */ - if (Status == STATUS_PENDING) { - WaitForSingleObject(SockEvent, INFINITE); - Status = IOSB.Status; - } - } - - /* AFD doesn't seem to care if these are invalid, but let's 0 them anyways */ - ConnectInfo->Root = 0; - ConnectInfo->UseSAN = FALSE; - ConnectInfo->Unknown = 0; - - /* FIXME: Handle Async Connect */ - if (Socket->SharedData.NonBlocking) { - AFD_DbgPrint(MIN_TRACE, ("Async Connect UNIMPLEMENTED!\n")); - } - - /* Send IOCTL */ - Status = NtDeviceIoControlFile((HANDLE)Handle, - SockEvent, - NULL, - NULL, - &IOSB, - IOCTL_AFD_CONNECT, - ConnectInfo, - 0x22, - NULL, - 0); - /* Wait for return */ - if (Status == STATUS_PENDING) { - WaitForSingleObject(SockEvent, INFINITE); - Status = IOSB.Status; - } - - /* Get any pending connect data */ - if (lpCalleeData != NULL) { - Status = NtDeviceIoControlFile((HANDLE)Handle, - SockEvent, - NULL, - NULL, - &IOSB, - IOCTL_AFD_GET_CONNECT_DATA, - NULL, - 0, - lpCalleeData->buf, - lpCalleeData->len); - /* Wait for return */ - if (Status == STATUS_PENDING) { - WaitForSingleObject(SockEvent, INFINITE); - Status = IOSB.Status; - } - } - - /* Re-enable Async Event */ - SockReenableAsyncSelectEvent(Socket, FD_WRITE); - - /* FIXME: THIS IS NOT RIGHT!!! HACK HACK HACK! */ - SockReenableAsyncSelectEvent(Socket, FD_CONNECT); - - AFD_DbgPrint(MID_TRACE,("Ending\n")); - - NtClose( SockEvent ); - - return MsafdReturnWithErrno( Status, lpErrno, 0, NULL ); -} -int -WSPAPI -WSPShutdown( - SOCKET Handle, - int HowTo, - LPINT lpErrno) - -{ - IO_STATUS_BLOCK IOSB; - AFD_DISCONNECT_INFO DisconnectInfo; - PSOCKET_INFORMATION Socket = NULL; - NTSTATUS Status; - HANDLE SockEvent; - - Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE, - NULL, 1, FALSE ); - - if( !NT_SUCCESS(Status) ) return -1; - - AFD_DbgPrint(MID_TRACE,("Called\n")); - - /* Get the Socket Structure associate to this Socket*/ - Socket = GetSocketStructure(Handle); - - /* Set AFD Disconnect Type */ - switch (HowTo) { - - case SD_RECEIVE: - DisconnectInfo.DisconnectType = AFD_DISCONNECT_RECV; - Socket->SharedData.ReceiveShutdown = TRUE; - break; - - case SD_SEND: - DisconnectInfo.DisconnectType= AFD_DISCONNECT_SEND; - Socket->SharedData.SendShutdown = TRUE; - break; - - case SD_BOTH: - DisconnectInfo.DisconnectType = AFD_DISCONNECT_RECV | AFD_DISCONNECT_SEND; - Socket->SharedData.ReceiveShutdown = TRUE; - Socket->SharedData.SendShutdown = TRUE; - break; - } - - DisconnectInfo.Timeout = RtlConvertLongToLargeInteger(-1); - - /* Send IOCTL */ - Status = NtDeviceIoControlFile((HANDLE)Handle, - SockEvent, - NULL, - NULL, - &IOSB, - IOCTL_AFD_DISCONNECT, - &DisconnectInfo, - sizeof(DisconnectInfo), - NULL, - 0); - - /* Wait for return */ - if (Status == STATUS_PENDING) { - WaitForSingleObject(SockEvent, INFINITE); - Status = IOSB.Status; - } - - AFD_DbgPrint(MID_TRACE,("Ending\n")); - - NtClose( SockEvent ); - - return MsafdReturnWithErrno( Status, lpErrno, 0, NULL ); -} - - -INT -WSPAPI -WSPGetSockName( - IN SOCKET Handle, - OUT LPSOCKADDR Name, - IN OUT LPINT NameLength, - OUT LPINT lpErrno) -{ - IO_STATUS_BLOCK IOSB; - ULONG TdiAddressSize; - PTDI_ADDRESS_INFO TdiAddress; - PTRANSPORT_ADDRESS SocketAddress; - PSOCKET_INFORMATION Socket = NULL; - NTSTATUS Status; - HANDLE SockEvent; - - 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); - - /* Allocate a buffer for the address */ - TdiAddressSize = FIELD_OFFSET(TDI_ADDRESS_INFO, - Address.Address[0].Address) + - Socket->SharedData.SizeOfLocalAddress; - TdiAddress = HeapAlloc(GlobalHeap, 0, TdiAddressSize); - - if ( TdiAddress == NULL ) { - NtClose( SockEvent ); - *lpErrno = WSAENOBUFS; - return SOCKET_ERROR; - } - - SocketAddress = &TdiAddress->Address; - - /* Send IOCTL */ - Status = NtDeviceIoControlFile( (HANDLE)Socket->Handle, - SockEvent, - NULL, - NULL, - &IOSB, - IOCTL_AFD_GET_SOCK_NAME, - NULL, - 0, - TdiAddress, - TdiAddressSize); - - /* Wait for return */ - if (Status == STATUS_PENDING) { - WaitForSingleObject(SockEvent, INFINITE); - Status = IOSB.Status; - } - - NtClose( SockEvent ); - - if (NT_SUCCESS(Status)) { - if (*NameLength >= SocketAddress->Address[0].AddressLength) { - Name->sa_family = SocketAddress->Address[0].AddressType; - RtlCopyMemory (Name->sa_data, - SocketAddress->Address[0].Address, - SocketAddress->Address[0].AddressLength); - *NameLength = 2 + SocketAddress->Address[0].AddressLength; - AFD_DbgPrint - (MID_TRACE, - ("NameLength %d Address: %x Port %x\n", - *NameLength, - ((struct sockaddr_in *)Name)->sin_addr.s_addr, - ((struct sockaddr_in *)Name)->sin_port)); - HeapFree(GlobalHeap, 0, TdiAddress); - return 0; - } else { - HeapFree(GlobalHeap, 0, TdiAddress); - *lpErrno = WSAEFAULT; - return SOCKET_ERROR; - } - } - - return MsafdReturnWithErrno - ( Status, lpErrno, 0, NULL ); -} - - -INT -WSPAPI -WSPGetPeerName( - IN SOCKET s, - OUT LPSOCKADDR Name, - IN OUT LPINT NameLength, - OUT LPINT lpErrno) -{ - IO_STATUS_BLOCK IOSB; - ULONG TdiAddressSize; - PTDI_ADDRESS_INFO TdiAddress; - PTRANSPORT_ADDRESS SocketAddress; - PSOCKET_INFORMATION Socket = NULL; - NTSTATUS Status; - HANDLE SockEvent; - - 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(s); - - /* Allocate a buffer for the address */ - TdiAddressSize = FIELD_OFFSET(TDI_ADDRESS_INFO, - Address.Address[0].Address) + - Socket->SharedData.SizeOfLocalAddress; - TdiAddress = HeapAlloc(GlobalHeap, 0, TdiAddressSize); - - if ( TdiAddress == NULL ) { - NtClose( SockEvent ); - *lpErrno = WSAENOBUFS; - return SOCKET_ERROR; - } - - SocketAddress = &TdiAddress->Address; - - /* Send IOCTL */ - Status = NtDeviceIoControlFile( (HANDLE)Socket->Handle, - SockEvent, - NULL, - NULL, - &IOSB, - IOCTL_AFD_GET_PEER_NAME, - NULL, - 0, - TdiAddress, - TdiAddressSize); - - /* Wait for return */ - if (Status == STATUS_PENDING) { - WaitForSingleObject(SockEvent, INFINITE); - Status = IOSB.Status; - } - - NtClose( SockEvent ); - - if (NT_SUCCESS(Status)) { - if (*NameLength >= SocketAddress->Address[0].AddressLength) { - Name->sa_family = SocketAddress->Address[0].AddressType; - RtlCopyMemory (Name->sa_data, - SocketAddress->Address[0].Address, - SocketAddress->Address[0].AddressLength); - *NameLength = 2 + SocketAddress->Address[0].AddressLength; - AFD_DbgPrint - (MID_TRACE, - ("NameLength %d Address: %s Port %x\n", - *NameLength, - ((struct sockaddr_in *)Name)->sin_addr.s_addr, - ((struct sockaddr_in *)Name)->sin_port)); - HeapFree(GlobalHeap, 0, TdiAddress); - return 0; - } else { - HeapFree(GlobalHeap, 0, TdiAddress); - *lpErrno = WSAEFAULT; - return SOCKET_ERROR; - } - } - - return MsafdReturnWithErrno - ( Status, lpErrno, 0, NULL ); -} - -INT -WSPAPI -WSPIoctl( - IN SOCKET Handle, - IN DWORD dwIoControlCode, - IN LPVOID lpvInBuffer, - IN DWORD cbInBuffer, - OUT LPVOID lpvOutBuffer, - IN DWORD cbOutBuffer, - OUT LPDWORD lpcbBytesReturned, - IN LPWSAOVERLAPPED lpOverlapped, - IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine, - IN LPWSATHREADID lpThreadId, - OUT LPINT lpErrno) -{ - PSOCKET_INFORMATION Socket = NULL; + AFD_DbgPrint(MID_TRACE,("Called\n")); /* Get the Socket Structure associate to this Socket*/ Socket = GetSocketStructure(Handle); - switch( dwIoControlCode ) { - case FIONBIO: - if( cbInBuffer < sizeof(INT) ) return SOCKET_ERROR; - Socket->SharedData.NonBlocking = *((PINT)lpvInBuffer) ? 1 : 0; - AFD_DbgPrint(MID_TRACE,("[%x] Set nonblocking %d\n", - Handle, Socket->SharedData.NonBlocking)); - return 0; + /* Bind us First */ + if (Socket->SharedData.State == SocketOpen) + { + /* Get the Wildcard Address */ + BindAddressLength = Socket->HelperData->MaxWSAddressLength; + BindAddress = HeapAlloc(GetProcessHeap(), 0, BindAddressLength); + Socket->HelperData->WSHGetWildcardSockaddr (Socket->HelperContext, + BindAddress, + &BindAddressLength); + /* Bind it */ + WSPBind(Handle, BindAddress, BindAddressLength, NULL); + } - case FIONREAD: - return GetSocketInformation(Socket, AFD_INFO_RECEIVE_CONTENT_SIZE, (PULONG)lpvOutBuffer, NULL); + /* 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; + } + } - default: - *lpErrno = WSAEINVAL; - return SOCKET_ERROR; + /* Dynamic Structure...ugh */ + ConnectInfo = (PAFD_CONNECT_INFO)ConnectBuffer; + + /* Set up Address in TDI Format */ + ConnectInfo->RemoteAddress.TAAddressCount = 1; + ConnectInfo->RemoteAddress.Address[0].AddressLength = SocketAddressLength - sizeof(SocketAddress->sa_family); + ConnectInfo->RemoteAddress.Address[0].AddressType = SocketAddress->sa_family; + RtlCopyMemory (ConnectInfo->RemoteAddress.Address[0].Address, + SocketAddress->sa_data, + SocketAddressLength - sizeof(SocketAddress->sa_family)); + + /* + * Disable FD_WRITE and FD_CONNECT + * The latter fixes a race condition where the FD_CONNECT is re-enabled + * at the end of this function right after the Async Thread disables it. + * This should only happen at the *next* WSPConnect + */ + if (Socket->SharedData.AsyncEvents & FD_CONNECT) + { + Socket->SharedData.AsyncDisabledEvents |= FD_CONNECT | FD_WRITE; + } + + /* Tell AFD that we want Connection Data back, have it allocate a buffer */ + if (lpCalleeData != NULL) + { + InConnectDataLength = lpCalleeData->len; + Status = NtDeviceIoControlFile((HANDLE)Handle, + SockEvent, + NULL, + NULL, + &IOSB, + IOCTL_AFD_SET_CONNECT_DATA_SIZE, + &InConnectDataLength, + sizeof(InConnectDataLength), + NULL, + 0); + + /* Wait for return */ + if (Status == STATUS_PENDING) + { + WaitForSingleObject(SockEvent, INFINITE); + Status = IOSB.Status; + } + } + + /* AFD doesn't seem to care if these are invalid, but let's 0 them anyways */ + ConnectInfo->Root = 0; + ConnectInfo->UseSAN = FALSE; + ConnectInfo->Unknown = 0; + + /* FIXME: Handle Async Connect */ + if (Socket->SharedData.NonBlocking) + { + AFD_DbgPrint(MIN_TRACE, ("Async Connect UNIMPLEMENTED!\n")); + } + + /* Send IOCTL */ + Status = NtDeviceIoControlFile((HANDLE)Handle, + SockEvent, + NULL, + NULL, + &IOSB, + IOCTL_AFD_CONNECT, + ConnectInfo, + 0x22, + NULL, + 0); + /* Wait for return */ + if (Status == STATUS_PENDING) + { + WaitForSingleObject(SockEvent, INFINITE); + Status = IOSB.Status; + } + + /* Get any pending connect data */ + if (lpCalleeData != NULL) + { + Status = NtDeviceIoControlFile((HANDLE)Handle, + SockEvent, + NULL, + NULL, + &IOSB, + IOCTL_AFD_GET_CONNECT_DATA, + NULL, + 0, + lpCalleeData->buf, + lpCalleeData->len); + /* Wait for return */ + if (Status == STATUS_PENDING) + { + WaitForSingleObject(SockEvent, INFINITE); + Status = IOSB.Status; + } + } + + /* Re-enable Async Event */ + SockReenableAsyncSelectEvent(Socket, FD_WRITE); + + /* FIXME: THIS IS NOT RIGHT!!! HACK HACK HACK! */ + SockReenableAsyncSelectEvent(Socket, FD_CONNECT); + + AFD_DbgPrint(MID_TRACE,("Ending\n")); + + NtClose( SockEvent ); + + return MsafdReturnWithErrno( Status, lpErrno, 0, NULL ); +} +int +WSPAPI +WSPShutdown(SOCKET Handle, + int HowTo, + LPINT lpErrno) + +{ + IO_STATUS_BLOCK IOSB; + AFD_DISCONNECT_INFO DisconnectInfo; + PSOCKET_INFORMATION Socket = NULL; + NTSTATUS Status; + HANDLE SockEvent; + + Status = NtCreateEvent(&SockEvent, + GENERIC_READ | GENERIC_WRITE, + NULL, + 1, + FALSE); + + if( !NT_SUCCESS(Status) ) + return -1; + + AFD_DbgPrint(MID_TRACE,("Called\n")); + + /* Get the Socket Structure associate to this Socket*/ + Socket = GetSocketStructure(Handle); + + /* Set AFD Disconnect Type */ + switch (HowTo) + { + case SD_RECEIVE: + DisconnectInfo.DisconnectType = AFD_DISCONNECT_RECV; + Socket->SharedData.ReceiveShutdown = TRUE; + break; + case SD_SEND: + DisconnectInfo.DisconnectType= AFD_DISCONNECT_SEND; + Socket->SharedData.SendShutdown = TRUE; + break; + case SD_BOTH: + DisconnectInfo.DisconnectType = AFD_DISCONNECT_RECV | AFD_DISCONNECT_SEND; + Socket->SharedData.ReceiveShutdown = TRUE; + Socket->SharedData.SendShutdown = TRUE; + break; + } + + DisconnectInfo.Timeout = RtlConvertLongToLargeInteger(-1); + + /* Send IOCTL */ + Status = NtDeviceIoControlFile((HANDLE)Handle, + SockEvent, + NULL, + NULL, + &IOSB, + IOCTL_AFD_DISCONNECT, + &DisconnectInfo, + sizeof(DisconnectInfo), + NULL, + 0); + + /* Wait for return */ + if (Status == STATUS_PENDING) + { + WaitForSingleObject(SockEvent, INFINITE); + Status = IOSB.Status; + } + + AFD_DbgPrint(MID_TRACE,("Ending\n")); + + NtClose( SockEvent ); + + return MsafdReturnWithErrno( Status, lpErrno, 0, NULL ); +} + + +INT +WSPAPI +WSPGetSockName(IN SOCKET Handle, + OUT LPSOCKADDR Name, + IN OUT LPINT NameLength, + OUT LPINT lpErrno) +{ + IO_STATUS_BLOCK IOSB; + ULONG TdiAddressSize; + PTDI_ADDRESS_INFO TdiAddress; + PTRANSPORT_ADDRESS SocketAddress; + PSOCKET_INFORMATION Socket = NULL; + NTSTATUS Status; + HANDLE SockEvent; + + 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); + + /* Allocate a buffer for the address */ + TdiAddressSize = FIELD_OFFSET(TDI_ADDRESS_INFO, Address.Address[0].Address) + + Socket->SharedData.SizeOfLocalAddress; + + TdiAddress = HeapAlloc(GlobalHeap, 0, TdiAddressSize); + + if ( TdiAddress == NULL ) + { + NtClose( SockEvent ); + *lpErrno = WSAENOBUFS; + return SOCKET_ERROR; + } + + SocketAddress = &TdiAddress->Address; + + /* Send IOCTL */ + Status = NtDeviceIoControlFile((HANDLE)Socket->Handle, + SockEvent, + NULL, + NULL, + &IOSB, + IOCTL_AFD_GET_SOCK_NAME, + NULL, + 0, + TdiAddress, + TdiAddressSize); + + /* Wait for return */ + if (Status == STATUS_PENDING) + { + WaitForSingleObject(SockEvent, INFINITE); + Status = IOSB.Status; + } + + NtClose( SockEvent ); + + if (NT_SUCCESS(Status)) + { + if (*NameLength >= SocketAddress->Address[0].AddressLength) + { + Name->sa_family = SocketAddress->Address[0].AddressType; + RtlCopyMemory (Name->sa_data, + SocketAddress->Address[0].Address, + SocketAddress->Address[0].AddressLength); + *NameLength = 2 + SocketAddress->Address[0].AddressLength; + AFD_DbgPrint (MID_TRACE, ("NameLength %d Address: %x Port %x\n", + *NameLength, ((struct sockaddr_in *)Name)->sin_addr.s_addr, + ((struct sockaddr_in *)Name)->sin_port)); + HeapFree(GlobalHeap, 0, TdiAddress); + return 0; + } + else + { + HeapFree(GlobalHeap, 0, TdiAddress); + *lpErrno = WSAEFAULT; + return SOCKET_ERROR; + } + } + + return MsafdReturnWithErrno ( Status, lpErrno, 0, NULL ); +} + + +INT +WSPAPI +WSPGetPeerName(IN SOCKET s, + OUT LPSOCKADDR Name, + IN OUT LPINT NameLength, + OUT LPINT lpErrno) +{ + IO_STATUS_BLOCK IOSB; + ULONG TdiAddressSize; + PTDI_ADDRESS_INFO TdiAddress; + PTRANSPORT_ADDRESS SocketAddress; + PSOCKET_INFORMATION Socket = NULL; + NTSTATUS Status; + HANDLE SockEvent; + + 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(s); + + /* Allocate a buffer for the address */ + TdiAddressSize = FIELD_OFFSET(TDI_ADDRESS_INFO, Address.Address[0].Address) + + Socket->SharedData.SizeOfLocalAddress; + TdiAddress = HeapAlloc(GlobalHeap, 0, TdiAddressSize); + + if ( TdiAddress == NULL ) + { + NtClose( SockEvent ); + *lpErrno = WSAENOBUFS; + return SOCKET_ERROR; + } + + SocketAddress = &TdiAddress->Address; + + /* Send IOCTL */ + Status = NtDeviceIoControlFile((HANDLE)Socket->Handle, + SockEvent, + NULL, + NULL, + &IOSB, + IOCTL_AFD_GET_PEER_NAME, + NULL, + 0, + TdiAddress, + TdiAddressSize); + + /* Wait for return */ + if (Status == STATUS_PENDING) + { + WaitForSingleObject(SockEvent, INFINITE); + Status = IOSB.Status; + } + + NtClose( SockEvent ); + + if (NT_SUCCESS(Status)) + { + if (*NameLength >= SocketAddress->Address[0].AddressLength) + { + Name->sa_family = SocketAddress->Address[0].AddressType; + RtlCopyMemory (Name->sa_data, + SocketAddress->Address[0].Address, + SocketAddress->Address[0].AddressLength); + *NameLength = 2 + SocketAddress->Address[0].AddressLength; + AFD_DbgPrint (MID_TRACE, ("NameLength %d Address: %s Port %x\n", + *NameLength, ((struct sockaddr_in *)Name)->sin_addr.s_addr, + ((struct sockaddr_in *)Name)->sin_port)); + HeapFree(GlobalHeap, 0, TdiAddress); + return 0; + } + else + { + HeapFree(GlobalHeap, 0, TdiAddress); + *lpErrno = WSAEFAULT; + return SOCKET_ERROR; + } + } + + return MsafdReturnWithErrno ( Status, lpErrno, 0, NULL ); +} + +INT +WSPAPI +WSPIoctl(IN SOCKET Handle, + IN DWORD dwIoControlCode, + IN LPVOID lpvInBuffer, + IN DWORD cbInBuffer, + OUT LPVOID lpvOutBuffer, + IN DWORD cbOutBuffer, + OUT LPDWORD lpcbBytesReturned, + IN LPWSAOVERLAPPED lpOverlapped, + IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine, + IN LPWSATHREADID lpThreadId, + OUT LPINT lpErrno) +{ + PSOCKET_INFORMATION Socket = NULL; + + /* Get the Socket Structure associate to this Socket*/ + Socket = GetSocketStructure(Handle); + + switch( dwIoControlCode ) + { + case FIONBIO: + if( cbInBuffer < sizeof(INT) ) + return SOCKET_ERROR; + Socket->SharedData.NonBlocking = *((PINT)lpvInBuffer) ? 1 : 0; + AFD_DbgPrint(MID_TRACE,("[%x] Set nonblocking %d\n", Handle, Socket->SharedData.NonBlocking)); + return 0; + case FIONREAD: + return GetSocketInformation(Socket, AFD_INFO_RECEIVE_CONTENT_SIZE, (PULONG)lpvOutBuffer, NULL); + default: + *lpErrno = WSAEINVAL; + return SOCKET_ERROR; } } INT WSPAPI -WSPGetSockOpt( - IN SOCKET Handle, - IN INT Level, - IN INT OptionName, - OUT CHAR FAR* OptionValue, - IN OUT LPINT OptionLength, - OUT LPINT lpErrno) +WSPGetSockOpt(IN SOCKET Handle, + IN INT Level, + IN INT OptionName, + OUT CHAR FAR* OptionValue, + IN OUT LPINT OptionLength, + OUT LPINT lpErrno) { PSOCKET_INFORMATION Socket = NULL; PVOID Buffer; @@ -1638,14 +1785,6 @@ WSPGetSockOpt( } -INT -WSPAPI -WSPStartup( - IN WORD wVersionRequested, - OUT LPWSPDATA lpWSPData, - IN LPWSAPROTOCOL_INFOW lpProtocolInfo, - IN WSPUPCALLTABLE UpcallTable, - OUT LPWSPPROC_TABLE lpProcTable) /* * FUNCTION: Initialize service provider for a client * ARGUMENTS: @@ -1657,61 +1796,63 @@ WSPStartup( * RETURNS: * Status of operation */ +INT +WSPAPI +WSPStartup(IN WORD wVersionRequested, + OUT LPWSPDATA lpWSPData, + IN LPWSAPROTOCOL_INFOW lpProtocolInfo, + IN WSPUPCALLTABLE UpcallTable, + OUT LPWSPPROC_TABLE lpProcTable) + { - NTSTATUS Status; + NTSTATUS Status; - AFD_DbgPrint(MAX_TRACE, ("wVersionRequested (0x%X) \n", wVersionRequested)); + AFD_DbgPrint(MAX_TRACE, ("wVersionRequested (0x%X) \n", wVersionRequested)); + Status = NO_ERROR; + Upcalls = UpcallTable; - Status = NO_ERROR; + if (Status == NO_ERROR) + { + lpProcTable->lpWSPAccept = WSPAccept; + lpProcTable->lpWSPAddressToString = WSPAddressToString; + lpProcTable->lpWSPAsyncSelect = WSPAsyncSelect; + lpProcTable->lpWSPBind = WSPBind; + lpProcTable->lpWSPCancelBlockingCall = WSPCancelBlockingCall; + lpProcTable->lpWSPCleanup = WSPCleanup; + lpProcTable->lpWSPCloseSocket = WSPCloseSocket; + lpProcTable->lpWSPConnect = WSPConnect; + lpProcTable->lpWSPDuplicateSocket = WSPDuplicateSocket; + lpProcTable->lpWSPEnumNetworkEvents = WSPEnumNetworkEvents; + lpProcTable->lpWSPEventSelect = WSPEventSelect; + lpProcTable->lpWSPGetOverlappedResult = WSPGetOverlappedResult; + lpProcTable->lpWSPGetPeerName = WSPGetPeerName; + lpProcTable->lpWSPGetSockName = WSPGetSockName; + lpProcTable->lpWSPGetSockOpt = WSPGetSockOpt; + lpProcTable->lpWSPGetQOSByName = WSPGetQOSByName; + lpProcTable->lpWSPIoctl = WSPIoctl; + lpProcTable->lpWSPJoinLeaf = WSPJoinLeaf; + lpProcTable->lpWSPListen = WSPListen; + lpProcTable->lpWSPRecv = WSPRecv; + lpProcTable->lpWSPRecvDisconnect = WSPRecvDisconnect; + lpProcTable->lpWSPRecvFrom = WSPRecvFrom; + lpProcTable->lpWSPSelect = WSPSelect; + lpProcTable->lpWSPSend = WSPSend; + lpProcTable->lpWSPSendDisconnect = WSPSendDisconnect; + lpProcTable->lpWSPSendTo = WSPSendTo; + lpProcTable->lpWSPSetSockOpt = WSPSetSockOpt; + lpProcTable->lpWSPShutdown = WSPShutdown; + lpProcTable->lpWSPSocket = WSPSocket; + lpProcTable->lpWSPStringToAddress = WSPStringToAddress; + lpWSPData->wVersion = MAKEWORD(2, 2); + lpWSPData->wHighVersion = MAKEWORD(2, 2); + } - Upcalls = UpcallTable; + AFD_DbgPrint(MAX_TRACE, ("Status (%d).\n", Status)); - if (Status == NO_ERROR) { - lpProcTable->lpWSPAccept = WSPAccept; - lpProcTable->lpWSPAddressToString = WSPAddressToString; - lpProcTable->lpWSPAsyncSelect = WSPAsyncSelect; - lpProcTable->lpWSPBind = WSPBind; - lpProcTable->lpWSPCancelBlockingCall = WSPCancelBlockingCall; - lpProcTable->lpWSPCleanup = WSPCleanup; - lpProcTable->lpWSPCloseSocket = WSPCloseSocket; - lpProcTable->lpWSPConnect = WSPConnect; - lpProcTable->lpWSPDuplicateSocket = WSPDuplicateSocket; - lpProcTable->lpWSPEnumNetworkEvents = WSPEnumNetworkEvents; - lpProcTable->lpWSPEventSelect = WSPEventSelect; - lpProcTable->lpWSPGetOverlappedResult = WSPGetOverlappedResult; - lpProcTable->lpWSPGetPeerName = WSPGetPeerName; - lpProcTable->lpWSPGetSockName = WSPGetSockName; - lpProcTable->lpWSPGetSockOpt = WSPGetSockOpt; - lpProcTable->lpWSPGetQOSByName = WSPGetQOSByName; - lpProcTable->lpWSPIoctl = WSPIoctl; - lpProcTable->lpWSPJoinLeaf = WSPJoinLeaf; - lpProcTable->lpWSPListen = WSPListen; - lpProcTable->lpWSPRecv = WSPRecv; - lpProcTable->lpWSPRecvDisconnect = WSPRecvDisconnect; - lpProcTable->lpWSPRecvFrom = WSPRecvFrom; - lpProcTable->lpWSPSelect = WSPSelect; - lpProcTable->lpWSPSend = WSPSend; - lpProcTable->lpWSPSendDisconnect = WSPSendDisconnect; - lpProcTable->lpWSPSendTo = WSPSendTo; - lpProcTable->lpWSPSetSockOpt = WSPSetSockOpt; - lpProcTable->lpWSPShutdown = WSPShutdown; - lpProcTable->lpWSPSocket = WSPSocket; - lpProcTable->lpWSPStringToAddress = WSPStringToAddress; - - lpWSPData->wVersion = MAKEWORD(2, 2); - lpWSPData->wHighVersion = MAKEWORD(2, 2); - } - - AFD_DbgPrint(MAX_TRACE, ("Status (%d).\n", Status)); - - return Status; + return Status; } -INT -WSPAPI -WSPCleanup( - OUT LPINT lpErrno) /* * FUNCTION: Cleans up service provider for a client * ARGUMENTS: @@ -1719,257 +1860,279 @@ WSPCleanup( * RETURNS: * 0 if successful, or SOCKET_ERROR if not */ +INT +WSPAPI +WSPCleanup(OUT LPINT lpErrno) + { - AFD_DbgPrint(MAX_TRACE, ("\n")); + AFD_DbgPrint(MAX_TRACE, ("\n")); + AFD_DbgPrint(MAX_TRACE, ("Leaving.\n")); + *lpErrno = NO_ERROR; - - AFD_DbgPrint(MAX_TRACE, ("Leaving.\n")); - - *lpErrno = NO_ERROR; - - return 0; + return 0; } int -GetSocketInformation( - PSOCKET_INFORMATION Socket, - ULONG AfdInformationClass, - PULONG Ulong OPTIONAL, - PLARGE_INTEGER LargeInteger OPTIONAL) +GetSocketInformation(PSOCKET_INFORMATION Socket, + ULONG AfdInformationClass, + PULONG Ulong OPTIONAL, + PLARGE_INTEGER LargeInteger OPTIONAL) { - IO_STATUS_BLOCK IOSB; - AFD_INFO InfoData; - NTSTATUS Status; - HANDLE SockEvent; + IO_STATUS_BLOCK IOSB; + AFD_INFO InfoData; + NTSTATUS Status; + HANDLE SockEvent; - Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE, - NULL, 1, FALSE ); + Status = NtCreateEvent(&SockEvent, + GENERIC_READ | GENERIC_WRITE, + NULL, + 1, + FALSE); - if( !NT_SUCCESS(Status) ) return -1; + if( !NT_SUCCESS(Status) ) + return -1; - /* Set Info Class */ - InfoData.InformationClass = AfdInformationClass; + /* Set Info Class */ + InfoData.InformationClass = AfdInformationClass; - /* Send IOCTL */ - Status = NtDeviceIoControlFile( (HANDLE)Socket->Handle, - SockEvent, - NULL, - NULL, - &IOSB, - IOCTL_AFD_GET_INFO, - &InfoData, - sizeof(InfoData), - &InfoData, - sizeof(InfoData)); + /* Send IOCTL */ + Status = NtDeviceIoControlFile((HANDLE)Socket->Handle, + SockEvent, + NULL, + NULL, + &IOSB, + IOCTL_AFD_GET_INFO, + &InfoData, + sizeof(InfoData), + &InfoData, + sizeof(InfoData)); - /* Wait for return */ - if (Status == STATUS_PENDING) { - WaitForSingleObject(SockEvent, INFINITE); - } + /* Wait for return */ + if (Status == STATUS_PENDING) + { + WaitForSingleObject(SockEvent, INFINITE); + } - /* Return Information */ - *Ulong = InfoData.Information.Ulong; - if (LargeInteger != NULL) { - *LargeInteger = InfoData.Information.LargeInteger; - } + /* Return Information */ + *Ulong = InfoData.Information.Ulong; + if (LargeInteger != NULL) + { + *LargeInteger = InfoData.Information.LargeInteger; + } - NtClose( SockEvent ); + NtClose( SockEvent ); - return 0; + return 0; } int -SetSocketInformation( - PSOCKET_INFORMATION Socket, - ULONG AfdInformationClass, - PULONG Ulong OPTIONAL, - PLARGE_INTEGER LargeInteger OPTIONAL) +SetSocketInformation(PSOCKET_INFORMATION Socket, + ULONG AfdInformationClass, + PULONG Ulong OPTIONAL, + PLARGE_INTEGER LargeInteger OPTIONAL) { - IO_STATUS_BLOCK IOSB; - AFD_INFO InfoData; - NTSTATUS Status; - HANDLE SockEvent; + IO_STATUS_BLOCK IOSB; + AFD_INFO InfoData; + NTSTATUS Status; + HANDLE SockEvent; - Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE, - NULL, 1, FALSE ); + Status = NtCreateEvent(&SockEvent, + GENERIC_READ | GENERIC_WRITE, + NULL, + 1, + FALSE); - if( !NT_SUCCESS(Status) ) return -1; + if( !NT_SUCCESS(Status) ) + return -1; - /* Set Info Class */ - InfoData.InformationClass = AfdInformationClass; + /* Set Info Class */ + InfoData.InformationClass = AfdInformationClass; - /* Set Information */ - InfoData.Information.Ulong = *Ulong; - if (LargeInteger != NULL) { - InfoData.Information.LargeInteger = *LargeInteger; - } + /* Set Information */ + InfoData.Information.Ulong = *Ulong; + if (LargeInteger != NULL) + { + InfoData.Information.LargeInteger = *LargeInteger; + } - AFD_DbgPrint(MID_TRACE,("XXX Info %x (Data %x)\n", - AfdInformationClass, *Ulong)); + AFD_DbgPrint(MID_TRACE,("XXX Info %x (Data %x)\n", + AfdInformationClass, *Ulong)); - /* Send IOCTL */ - Status = NtDeviceIoControlFile( (HANDLE)Socket->Handle, - SockEvent, - NULL, - NULL, - &IOSB, - IOCTL_AFD_GET_INFO, - &InfoData, - sizeof(InfoData), - NULL, - 0); + /* Send IOCTL */ + Status = NtDeviceIoControlFile((HANDLE)Socket->Handle, + SockEvent, + NULL, + NULL, + &IOSB, + IOCTL_AFD_GET_INFO, + &InfoData, + sizeof(InfoData), + NULL, + 0); - /* Wait for return */ - if (Status == STATUS_PENDING) { - WaitForSingleObject(SockEvent, INFINITE); - } + /* Wait for return */ + if (Status == STATUS_PENDING) + { + WaitForSingleObject(SockEvent, INFINITE); + } - NtClose( SockEvent ); + NtClose( SockEvent ); - return 0; + return 0; } -PSOCKET_INFORMATION -GetSocketStructure( - SOCKET Handle) +PSOCKET_INFORMATION +GetSocketStructure(SOCKET Handle) { - ULONG i; + ULONG i; - for (i=0; iHandle == Handle) { - return Sockets[i]; - } - } - return 0; + for (i=0; iHandle == Handle) + { + return Sockets[i]; + } + } + return 0; } int CreateContext(PSOCKET_INFORMATION Socket) { - IO_STATUS_BLOCK IOSB; - SOCKET_CONTEXT ContextData; - NTSTATUS Status; - HANDLE SockEvent; + IO_STATUS_BLOCK IOSB; + SOCKET_CONTEXT ContextData; + NTSTATUS Status; + HANDLE SockEvent; - Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE, - NULL, 1, FALSE ); + Status = NtCreateEvent(&SockEvent, + GENERIC_READ | GENERIC_WRITE, + NULL, + 1, + FALSE); - if( !NT_SUCCESS(Status) ) return -1; + if( !NT_SUCCESS(Status) ) + return -1; - /* Create Context */ - ContextData.SharedData = Socket->SharedData; - ContextData.SizeOfHelperData = 0; - RtlCopyMemory (&ContextData.LocalAddress, - Socket->LocalAddress, - Socket->SharedData.SizeOfLocalAddress); - RtlCopyMemory (&ContextData.RemoteAddress, - Socket->RemoteAddress, - Socket->SharedData.SizeOfRemoteAddress); + /* Create Context */ + ContextData.SharedData = Socket->SharedData; + ContextData.SizeOfHelperData = 0; + RtlCopyMemory (&ContextData.LocalAddress, + Socket->LocalAddress, + Socket->SharedData.SizeOfLocalAddress); + RtlCopyMemory (&ContextData.RemoteAddress, + Socket->RemoteAddress, + Socket->SharedData.SizeOfRemoteAddress); - /* Send IOCTL */ - Status = NtDeviceIoControlFile( (HANDLE)Socket->Handle, - SockEvent, - NULL, - NULL, - &IOSB, - IOCTL_AFD_SET_CONTEXT, - &ContextData, - sizeof(ContextData), - NULL, - 0); + /* Send IOCTL */ + Status = NtDeviceIoControlFile((HANDLE)Socket->Handle, + SockEvent, + NULL, + NULL, + &IOSB, + IOCTL_AFD_SET_CONTEXT, + &ContextData, + sizeof(ContextData), + NULL, + 0); - /* Wait for Completition */ - if (Status == STATUS_PENDING) { - WaitForSingleObject(SockEvent, INFINITE); - } - - NtClose( SockEvent ); + /* Wait for Completition */ + if (Status == STATUS_PENDING) + { + WaitForSingleObject(SockEvent, INFINITE); + } - return 0; + NtClose( SockEvent ); + + return 0; } BOOLEAN SockCreateOrReferenceAsyncThread(VOID) { - HANDLE hAsyncThread; - DWORD AsyncThreadId; - HANDLE AsyncEvent; - OBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleFlags; - NTSTATUS Status; + HANDLE hAsyncThread; + DWORD AsyncThreadId; + HANDLE AsyncEvent; + OBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleFlags; + NTSTATUS Status; - /* Check if the Thread Already Exists */ - if (SockAsyncThreadRefCount) { - return TRUE; - } - - /* Create the Completion Port */ - if (!SockAsyncCompletionPort) { - Status = NtCreateIoCompletion(&SockAsyncCompletionPort, - IO_COMPLETION_ALL_ACCESS, - NULL, - 2); // Allow 2 threads only - - /* Protect Handle */ - HandleFlags.ProtectFromClose = TRUE; - HandleFlags.Inherit = FALSE; - Status = NtSetInformationObject(SockAsyncCompletionPort, - ObjectHandleFlagInformation, - &HandleFlags, - sizeof(HandleFlags)); - } - - /* Create the Async Event */ - Status = NtCreateEvent(&AsyncEvent, - EVENT_ALL_ACCESS, - NULL, - NotificationEvent, - FALSE); - - /* Create the Async Thread */ - hAsyncThread = CreateThread(NULL, - 0, - (LPTHREAD_START_ROUTINE)SockAsyncThread, - NULL, - 0, - &AsyncThreadId); + /* Check if the Thread Already Exists */ + if (SockAsyncThreadRefCount) + { + return TRUE; + } - /* Close the Handle */ - NtClose(hAsyncThread); + /* Create the Completion Port */ + if (!SockAsyncCompletionPort) + { + Status = NtCreateIoCompletion(&SockAsyncCompletionPort, + IO_COMPLETION_ALL_ACCESS, + NULL, + 2); // Allow 2 threads only - /* Increase the Reference Count */ - SockAsyncThreadRefCount++; - return TRUE; + /* Protect Handle */ + HandleFlags.ProtectFromClose = TRUE; + HandleFlags.Inherit = FALSE; + Status = NtSetInformationObject(SockAsyncCompletionPort, + ObjectHandleFlagInformation, + &HandleFlags, + sizeof(HandleFlags)); + } + + /* Create the Async Event */ + Status = NtCreateEvent(&AsyncEvent, + EVENT_ALL_ACCESS, + NULL, + NotificationEvent, + FALSE); + + /* Create the Async Thread */ + hAsyncThread = CreateThread(NULL, + 0, + (LPTHREAD_START_ROUTINE)SockAsyncThread, + NULL, + 0, + &AsyncThreadId); + + /* Close the Handle */ + NtClose(hAsyncThread); + + /* Increase the Reference Count */ + SockAsyncThreadRefCount++; + return TRUE; } int SockAsyncThread(PVOID ThreadParam) { - PVOID AsyncContext; - PASYNC_COMPLETION_ROUTINE AsyncCompletionRoutine; - IO_STATUS_BLOCK IOSB; - NTSTATUS Status; - - /* Make the Thread Higher Priority */ - SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL); - - /* Do a KQUEUE/WorkItem Style Loop, thanks to IoCompletion Ports */ - do { - Status = NtRemoveIoCompletion (SockAsyncCompletionPort, - (PVOID*)&AsyncCompletionRoutine, - &AsyncContext, - &IOSB, - NULL); - - /* Call the Async Function */ - if (NT_SUCCESS(Status)) { - (*AsyncCompletionRoutine)(AsyncContext, &IOSB); - } else { - /* It Failed, sleep for a second */ - Sleep(1000); - } - } while ((Status != STATUS_TIMEOUT)); + PVOID AsyncContext; + PASYNC_COMPLETION_ROUTINE AsyncCompletionRoutine; + IO_STATUS_BLOCK IOSB; + NTSTATUS Status; + + /* Make the Thread Higher Priority */ + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL); + + /* Do a KQUEUE/WorkItem Style Loop, thanks to IoCompletion Ports */ + do + { + Status = NtRemoveIoCompletion (SockAsyncCompletionPort, + (PVOID*)&AsyncCompletionRoutine, + &AsyncContext, + &IOSB, + NULL); + /* Call the Async Function */ + if (NT_SUCCESS(Status)) + { + (*AsyncCompletionRoutine)(AsyncContext, &IOSB); + } + else + { + /* It Failed, sleep for a second */ + Sleep(1000); + } + } while ((Status != STATUS_TIMEOUT)); /* The Thread has Ended */ return 0; @@ -1977,289 +2140,320 @@ int SockAsyncThread(PVOID ThreadParam) BOOLEAN SockGetAsyncSelectHelperAfdHandle(VOID) { - UNICODE_STRING AfdHelper; - OBJECT_ATTRIBUTES ObjectAttributes; - IO_STATUS_BLOCK IoSb; - NTSTATUS Status; - FILE_COMPLETION_INFORMATION CompletionInfo; - OBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleFlags; + UNICODE_STRING AfdHelper; + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoSb; + NTSTATUS Status; + FILE_COMPLETION_INFORMATION CompletionInfo; + OBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleFlags; - /* First, make sure we're not already intialized */ - if (SockAsyncHelperAfdHandle) { - return TRUE; - } + /* First, make sure we're not already intialized */ + if (SockAsyncHelperAfdHandle) + { + return TRUE; + } - /* Set up Handle Name and Object */ - RtlInitUnicodeString(&AfdHelper, L"\\Device\\Afd\\AsyncSelectHlp" ); - InitializeObjectAttributes(&ObjectAttributes, - &AfdHelper, - OBJ_INHERIT | OBJ_CASE_INSENSITIVE, - NULL, - NULL); + /* Set up Handle Name and Object */ + RtlInitUnicodeString(&AfdHelper, L"\\Device\\Afd\\AsyncSelectHlp" ); + InitializeObjectAttributes(&ObjectAttributes, + &AfdHelper, + OBJ_INHERIT | OBJ_CASE_INSENSITIVE, + NULL, + NULL); - /* Open the Handle to AFD */ - Status = NtCreateFile(&SockAsyncHelperAfdHandle, - GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, - &ObjectAttributes, - &IoSb, - NULL, - 0, - FILE_SHARE_READ | FILE_SHARE_WRITE, - FILE_OPEN_IF, - 0, - NULL, - 0); + /* Open the Handle to AFD */ + Status = NtCreateFile(&SockAsyncHelperAfdHandle, + GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, + &ObjectAttributes, + &IoSb, + NULL, + 0, + FILE_SHARE_READ | FILE_SHARE_WRITE, + FILE_OPEN_IF, + 0, + NULL, + 0); - /* - * Now Set up the Completion Port Information - * This means that whenever a Poll is finished, the routine will be executed - */ - CompletionInfo.Port = SockAsyncCompletionPort; - CompletionInfo.Key = SockAsyncSelectCompletionRoutine; - Status = NtSetInformationFile(SockAsyncHelperAfdHandle, - &IoSb, - &CompletionInfo, - sizeof(CompletionInfo), - FileCompletionInformation); - - - /* Protect the Handle */ - HandleFlags.ProtectFromClose = TRUE; - HandleFlags.Inherit = FALSE; - Status = NtSetInformationObject(SockAsyncCompletionPort, - ObjectHandleFlagInformation, - &HandleFlags, - sizeof(HandleFlags)); + /* + * Now Set up the Completion Port Information + * This means that whenever a Poll is finished, the routine will be executed + */ + CompletionInfo.Port = SockAsyncCompletionPort; + CompletionInfo.Key = SockAsyncSelectCompletionRoutine; + Status = NtSetInformationFile(SockAsyncHelperAfdHandle, + &IoSb, + &CompletionInfo, + sizeof(CompletionInfo), + FileCompletionInformation); - /* Set this variable to true so that Send/Recv/Accept will know wether to renable disabled events */ - SockAsyncSelectCalled = TRUE; - return TRUE; + /* Protect the Handle */ + HandleFlags.ProtectFromClose = TRUE; + HandleFlags.Inherit = FALSE; + Status = NtSetInformationObject(SockAsyncCompletionPort, + ObjectHandleFlagInformation, + &HandleFlags, + sizeof(HandleFlags)); + + + /* Set this variable to true so that Send/Recv/Accept will know wether to renable disabled events */ + SockAsyncSelectCalled = TRUE; + return TRUE; } VOID SockAsyncSelectCompletionRoutine(PVOID Context, PIO_STATUS_BLOCK IoStatusBlock) { - PASYNC_DATA AsyncData = Context; - PSOCKET_INFORMATION Socket; - ULONG x; - - /* Get the Socket */ - Socket = AsyncData->ParentSocket; - - /* Check if the Sequence Number Changed behind our back */ - if (AsyncData->SequenceNumber != Socket->SharedData.SequenceNumber ){ - return; - } + PASYNC_DATA AsyncData = Context; + PSOCKET_INFORMATION Socket; + ULONG x; - /* Check we were manually called b/c of a failure */ - if (!NT_SUCCESS(IoStatusBlock->Status)) { - /* FIXME: Perform Upcall */ - return; - } + /* Get the Socket */ + Socket = AsyncData->ParentSocket; - for (x = 1; x; x<<=1) { - switch (AsyncData->AsyncSelectInfo.Handles[0].Events & x) { - case AFD_EVENT_RECEIVE: - if (0 != (Socket->SharedData.AsyncEvents & FD_READ) && 0 == (Socket->SharedData.AsyncDisabledEvents & FD_READ)) { - /* Make the Notifcation */ - (Upcalls.lpWPUPostMessage)(Socket->SharedData.hWnd, - Socket->SharedData.wMsg, - Socket->Handle, - WSAMAKESELECTREPLY(FD_READ, 0)); - /* Disable this event until the next read(); */ - Socket->SharedData.AsyncDisabledEvents |= FD_READ; - } - break; - - case AFD_EVENT_OOB_RECEIVE: - if (0 != (Socket->SharedData.AsyncEvents & FD_OOB) && 0 == (Socket->SharedData.AsyncDisabledEvents & FD_OOB)) { - /* Make the Notifcation */ - (Upcalls.lpWPUPostMessage)(Socket->SharedData.hWnd, - Socket->SharedData.wMsg, - Socket->Handle, - WSAMAKESELECTREPLY(FD_OOB, 0)); - /* Disable this event until the next read(); */ - Socket->SharedData.AsyncDisabledEvents |= FD_OOB; - } - break; - - case AFD_EVENT_SEND: - if (0 != (Socket->SharedData.AsyncEvents & FD_WRITE) && 0 == (Socket->SharedData.AsyncDisabledEvents & FD_WRITE)) { - /* Make the Notifcation */ - (Upcalls.lpWPUPostMessage)(Socket->SharedData.hWnd, - Socket->SharedData.wMsg, - Socket->Handle, - WSAMAKESELECTREPLY(FD_WRITE, 0)); - /* Disable this event until the next write(); */ - Socket->SharedData.AsyncDisabledEvents |= FD_WRITE; - } - break; + /* Check if the Sequence Number Changed behind our back */ + if (AsyncData->SequenceNumber != Socket->SharedData.SequenceNumber ) + { + return; + } - /* FIXME: THIS IS NOT RIGHT!!! HACK HACK HACK! */ - case AFD_EVENT_CONNECT: - if (0 != (Socket->SharedData.AsyncEvents & FD_CONNECT) && 0 == (Socket->SharedData.AsyncDisabledEvents & FD_CONNECT)) { - /* Make the Notifcation */ - (Upcalls.lpWPUPostMessage)(Socket->SharedData.hWnd, - Socket->SharedData.wMsg, - Socket->Handle, - WSAMAKESELECTREPLY(FD_CONNECT, 0)); - /* Disable this event forever; */ - Socket->SharedData.AsyncDisabledEvents |= FD_CONNECT; - } - break; - - case AFD_EVENT_ACCEPT: - if (0 != (Socket->SharedData.AsyncEvents & FD_ACCEPT) && 0 == (Socket->SharedData.AsyncDisabledEvents & FD_ACCEPT)) { - /* Make the Notifcation */ - (Upcalls.lpWPUPostMessage)(Socket->SharedData.hWnd, - Socket->SharedData.wMsg, - Socket->Handle, - WSAMAKESELECTREPLY(FD_ACCEPT, 0)); - /* Disable this event until the next accept(); */ - Socket->SharedData.AsyncDisabledEvents |= FD_ACCEPT; - } - break; + /* Check we were manually called b/c of a failure */ + if (!NT_SUCCESS(IoStatusBlock->Status)) + { + /* FIXME: Perform Upcall */ + return; + } - case AFD_EVENT_DISCONNECT: - case AFD_EVENT_ABORT: - case AFD_EVENT_CLOSE: - if (0 != (Socket->SharedData.AsyncEvents & FD_CLOSE) && 0 == (Socket->SharedData.AsyncDisabledEvents & FD_CLOSE)) { - /* Make the Notifcation */ - (Upcalls.lpWPUPostMessage)(Socket->SharedData.hWnd, - Socket->SharedData.wMsg, - Socket->Handle, - WSAMAKESELECTREPLY(FD_CLOSE, 0)); - /* Disable this event forever; */ - Socket->SharedData.AsyncDisabledEvents |= FD_CLOSE; - } - break; + for (x = 1; x; x<<=1) + { + switch (AsyncData->AsyncSelectInfo.Handles[0].Events & x) + { + case AFD_EVENT_RECEIVE: + if (0 != (Socket->SharedData.AsyncEvents & FD_READ) && + 0 == (Socket->SharedData.AsyncDisabledEvents & FD_READ)) + { + /* Make the Notifcation */ + (Upcalls.lpWPUPostMessage)(Socket->SharedData.hWnd, + Socket->SharedData.wMsg, + Socket->Handle, + WSAMAKESELECTREPLY(FD_READ, 0)); + /* Disable this event until the next read(); */ + Socket->SharedData.AsyncDisabledEvents |= FD_READ; + } + break; - /* FIXME: Support QOS */ - } - } - - /* Check if there are any events left for us to check */ - if ((Socket->SharedData.AsyncEvents & (~Socket->SharedData.AsyncDisabledEvents)) == 0 ) { - return; - } + case AFD_EVENT_OOB_RECEIVE: + if (0 != (Socket->SharedData.AsyncEvents & FD_OOB) && + 0 == (Socket->SharedData.AsyncDisabledEvents & FD_OOB)) + { + /* Make the Notifcation */ + (Upcalls.lpWPUPostMessage)(Socket->SharedData.hWnd, + Socket->SharedData.wMsg, + Socket->Handle, + WSAMAKESELECTREPLY(FD_OOB, 0)); + /* Disable this event until the next read(); */ + Socket->SharedData.AsyncDisabledEvents |= FD_OOB; + } + break; - /* Keep Polling */ - SockProcessAsyncSelect(Socket, AsyncData); - return; + case AFD_EVENT_SEND: + if (0 != (Socket->SharedData.AsyncEvents & FD_WRITE) && + 0 == (Socket->SharedData.AsyncDisabledEvents & FD_WRITE)) + { + /* Make the Notifcation */ + (Upcalls.lpWPUPostMessage)(Socket->SharedData.hWnd, + Socket->SharedData.wMsg, + Socket->Handle, + WSAMAKESELECTREPLY(FD_WRITE, 0)); + /* Disable this event until the next write(); */ + Socket->SharedData.AsyncDisabledEvents |= FD_WRITE; + } + break; + + /* FIXME: THIS IS NOT RIGHT!!! HACK HACK HACK! */ + case AFD_EVENT_CONNECT: + if (0 != (Socket->SharedData.AsyncEvents & FD_CONNECT) && + 0 == (Socket->SharedData.AsyncDisabledEvents & FD_CONNECT)) + { + /* Make the Notifcation */ + (Upcalls.lpWPUPostMessage)(Socket->SharedData.hWnd, + Socket->SharedData.wMsg, + Socket->Handle, + WSAMAKESELECTREPLY(FD_CONNECT, 0)); + /* Disable this event forever; */ + Socket->SharedData.AsyncDisabledEvents |= FD_CONNECT; + } + break; + + case AFD_EVENT_ACCEPT: + if (0 != (Socket->SharedData.AsyncEvents & FD_ACCEPT) && + 0 == (Socket->SharedData.AsyncDisabledEvents & FD_ACCEPT)) + { + /* Make the Notifcation */ + (Upcalls.lpWPUPostMessage)(Socket->SharedData.hWnd, + Socket->SharedData.wMsg, + Socket->Handle, + WSAMAKESELECTREPLY(FD_ACCEPT, 0)); + /* Disable this event until the next accept(); */ + Socket->SharedData.AsyncDisabledEvents |= FD_ACCEPT; + } + break; + + case AFD_EVENT_DISCONNECT: + case AFD_EVENT_ABORT: + case AFD_EVENT_CLOSE: + if (0 != (Socket->SharedData.AsyncEvents & FD_CLOSE) && + 0 == (Socket->SharedData.AsyncDisabledEvents & FD_CLOSE)) + { + /* Make the Notifcation */ + (Upcalls.lpWPUPostMessage)(Socket->SharedData.hWnd, + Socket->SharedData.wMsg, + Socket->Handle, + WSAMAKESELECTREPLY(FD_CLOSE, 0)); + /* Disable this event forever; */ + Socket->SharedData.AsyncDisabledEvents |= FD_CLOSE; + } + break; + /* FIXME: Support QOS */ + } + } + + /* Check if there are any events left for us to check */ + if ((Socket->SharedData.AsyncEvents & (~Socket->SharedData.AsyncDisabledEvents)) == 0 ) + { + return; + } + + /* Keep Polling */ + SockProcessAsyncSelect(Socket, AsyncData); + return; } VOID SockProcessAsyncSelect(PSOCKET_INFORMATION Socket, PASYNC_DATA AsyncData) { - ULONG lNetworkEvents; - NTSTATUS Status; + ULONG lNetworkEvents; + NTSTATUS Status; - /* Set up the Async Data Event Info */ - AsyncData->AsyncSelectInfo.Timeout.HighPart = 0x7FFFFFFF; - AsyncData->AsyncSelectInfo.Timeout.LowPart = 0xFFFFFFFF; - AsyncData->AsyncSelectInfo.HandleCount = 1; - AsyncData->AsyncSelectInfo.Exclusive = TRUE; - AsyncData->AsyncSelectInfo.Handles[0].Handle = Socket->Handle; - AsyncData->AsyncSelectInfo.Handles[0].Events = 0; + /* Set up the Async Data Event Info */ + AsyncData->AsyncSelectInfo.Timeout.HighPart = 0x7FFFFFFF; + AsyncData->AsyncSelectInfo.Timeout.LowPart = 0xFFFFFFFF; + AsyncData->AsyncSelectInfo.HandleCount = 1; + AsyncData->AsyncSelectInfo.Exclusive = TRUE; + AsyncData->AsyncSelectInfo.Handles[0].Handle = Socket->Handle; + AsyncData->AsyncSelectInfo.Handles[0].Events = 0; - /* Remove unwanted events */ - lNetworkEvents = Socket->SharedData.AsyncEvents & (~Socket->SharedData.AsyncDisabledEvents); + /* Remove unwanted events */ + lNetworkEvents = Socket->SharedData.AsyncEvents & (~Socket->SharedData.AsyncDisabledEvents); - /* Set Events to wait for */ - if (lNetworkEvents & FD_READ) { - AsyncData->AsyncSelectInfo.Handles[0].Events |= AFD_EVENT_RECEIVE; - } + /* Set Events to wait for */ + if (lNetworkEvents & FD_READ) + { + AsyncData->AsyncSelectInfo.Handles[0].Events |= AFD_EVENT_RECEIVE; + } - if (lNetworkEvents & FD_WRITE) { - AsyncData->AsyncSelectInfo.Handles[0].Events |= AFD_EVENT_SEND; - } + if (lNetworkEvents & FD_WRITE) + { + AsyncData->AsyncSelectInfo.Handles[0].Events |= AFD_EVENT_SEND; + } - if (lNetworkEvents & FD_OOB) { - AsyncData->AsyncSelectInfo.Handles[0].Events |= AFD_EVENT_OOB_RECEIVE; - } + if (lNetworkEvents & FD_OOB) + { + AsyncData->AsyncSelectInfo.Handles[0].Events |= AFD_EVENT_OOB_RECEIVE; + } - if (lNetworkEvents & FD_ACCEPT) { - AsyncData->AsyncSelectInfo.Handles[0].Events |= AFD_EVENT_ACCEPT; - } + if (lNetworkEvents & FD_ACCEPT) + { + AsyncData->AsyncSelectInfo.Handles[0].Events |= AFD_EVENT_ACCEPT; + } - /* FIXME: THIS IS NOT RIGHT!!! HACK HACK HACK! */ - if (lNetworkEvents & FD_CONNECT) { - AsyncData->AsyncSelectInfo.Handles[0].Events |= AFD_EVENT_CONNECT | AFD_EVENT_CONNECT_FAIL; - } + /* FIXME: THIS IS NOT RIGHT!!! HACK HACK HACK! */ + if (lNetworkEvents & FD_CONNECT) + { + AsyncData->AsyncSelectInfo.Handles[0].Events |= AFD_EVENT_CONNECT | AFD_EVENT_CONNECT_FAIL; + } - if (lNetworkEvents & FD_CLOSE) { - AsyncData->AsyncSelectInfo.Handles[0].Events |= AFD_EVENT_DISCONNECT | AFD_EVENT_ABORT; - } + if (lNetworkEvents & FD_CLOSE) + { + AsyncData->AsyncSelectInfo.Handles[0].Events |= AFD_EVENT_DISCONNECT | AFD_EVENT_ABORT; + } - if (lNetworkEvents & FD_QOS) { - AsyncData->AsyncSelectInfo.Handles[0].Events |= AFD_EVENT_QOS; - } + if (lNetworkEvents & FD_QOS) + { + AsyncData->AsyncSelectInfo.Handles[0].Events |= AFD_EVENT_QOS; + } - if (lNetworkEvents & FD_GROUP_QOS) { - AsyncData->AsyncSelectInfo.Handles[0].Events |= AFD_EVENT_GROUP_QOS; - } - - /* Send IOCTL */ - Status = NtDeviceIoControlFile (SockAsyncHelperAfdHandle, - NULL, - NULL, - AsyncData, - &AsyncData->IoStatusBlock, - IOCTL_AFD_SELECT, - &AsyncData->AsyncSelectInfo, - sizeof(AsyncData->AsyncSelectInfo), - &AsyncData->AsyncSelectInfo, - sizeof(AsyncData->AsyncSelectInfo)); + if (lNetworkEvents & FD_GROUP_QOS) + { + AsyncData->AsyncSelectInfo.Handles[0].Events |= AFD_EVENT_GROUP_QOS; + } - /* I/O Manager Won't call the completion routine, let's do it manually */ - if (NT_SUCCESS(Status)) { - return; - } else { - AsyncData->IoStatusBlock.Status = Status; - SockAsyncSelectCompletionRoutine(AsyncData, &AsyncData->IoStatusBlock); - } + /* Send IOCTL */ + Status = NtDeviceIoControlFile (SockAsyncHelperAfdHandle, + NULL, + NULL, + AsyncData, + &AsyncData->IoStatusBlock, + IOCTL_AFD_SELECT, + &AsyncData->AsyncSelectInfo, + sizeof(AsyncData->AsyncSelectInfo), + &AsyncData->AsyncSelectInfo, + sizeof(AsyncData->AsyncSelectInfo)); + + /* I/O Manager Won't call the completion routine, let's do it manually */ + if (NT_SUCCESS(Status)) + { + return; + } + else + { + AsyncData->IoStatusBlock.Status = Status; + SockAsyncSelectCompletionRoutine(AsyncData, &AsyncData->IoStatusBlock); + } } VOID SockProcessQueuedAsyncSelect(PVOID Context, PIO_STATUS_BLOCK IoStatusBlock) { - PASYNC_DATA AsyncData = Context; - BOOL FreeContext = TRUE; - PSOCKET_INFORMATION Socket; + PASYNC_DATA AsyncData = Context; + BOOL FreeContext = TRUE; + PSOCKET_INFORMATION Socket; - /* Get the Socket */ - Socket = AsyncData->ParentSocket; + /* Get the Socket */ + Socket = AsyncData->ParentSocket; - /* If someone closed it, stop the function */ - if (Socket->SharedData.State != SocketClosed) { - /* Check if the Sequence Number changed by now, in which case quit */ - if (AsyncData->SequenceNumber == Socket->SharedData.SequenceNumber) { - /* Do the actuall select, if needed */ - if ((Socket->SharedData.AsyncEvents & (~Socket->SharedData.AsyncDisabledEvents))) { - SockProcessAsyncSelect(Socket, AsyncData); - FreeContext = FALSE; - } - } - } - - /* Free the Context */ - if (FreeContext) { - HeapFree(GetProcessHeap(), 0, AsyncData); - } + /* If someone closed it, stop the function */ + if (Socket->SharedData.State != SocketClosed) + { + /* Check if the Sequence Number changed by now, in which case quit */ + if (AsyncData->SequenceNumber == Socket->SharedData.SequenceNumber) + { + /* Do the actuall select, if needed */ + if ((Socket->SharedData.AsyncEvents & (~Socket->SharedData.AsyncDisabledEvents))) + { + SockProcessAsyncSelect(Socket, AsyncData); + FreeContext = FALSE; + } + } + } - return; + /* Free the Context */ + if (FreeContext) + { + HeapFree(GetProcessHeap(), 0, AsyncData); + } + + return; } VOID -SockReenableAsyncSelectEvent ( - IN PSOCKET_INFORMATION Socket, - IN ULONG Event - ) +SockReenableAsyncSelectEvent (IN PSOCKET_INFORMATION Socket, + IN ULONG Event) { PASYNC_DATA AsyncData; /* Make sure the event is actually disabled */ - if (!(Socket->SharedData.AsyncDisabledEvents & Event)) { + if (!(Socket->SharedData.AsyncDisabledEvents & Event)) + { return; } @@ -2267,7 +2461,8 @@ SockReenableAsyncSelectEvent ( Socket->SharedData.AsyncDisabledEvents &= ~Event; /* Return if no more events are being polled */ - if ((Socket->SharedData.AsyncEvents & (~Socket->SharedData.AsyncDisabledEvents)) == 0 ) { + if ((Socket->SharedData.AsyncEvents & (~Socket->SharedData.AsyncDisabledEvents)) == 0 ) + { return; } @@ -2279,18 +2474,18 @@ SockReenableAsyncSelectEvent ( /* Increase the sequence number to stop anything else */ Socket->SharedData.SequenceNumber++; - + /* Set up the Async Data */ AsyncData->ParentSocket = Socket; AsyncData->SequenceNumber = Socket->SharedData.SequenceNumber; /* Begin Async Select by using I/O Completion */ NtSetIoCompletion(SockAsyncCompletionPort, - (PVOID)&SockProcessQueuedAsyncSelect, - AsyncData, - 0, - 0); - + (PVOID)&SockProcessQueuedAsyncSelect, + AsyncData, + 0, + 0); + /* All done */ return; } @@ -2301,26 +2496,27 @@ DllMain(HANDLE hInstDll, ULONG dwReason, PVOID Reserved) { - - switch (dwReason) { + + switch (dwReason) + { case DLL_PROCESS_ATTACH: - AFD_DbgPrint(MAX_TRACE, ("Loading MSAFD.DLL \n")); + AFD_DbgPrint(MAX_TRACE, ("Loading MSAFD.DLL \n")); /* Don't need thread attach notifications - so disable them to improve performance */ + so disable them to improve performance */ DisableThreadLibraryCalls(hInstDll); - /* List of DLL Helpers */ + /* List of DLL Helpers */ InitializeListHead(&SockHelpersListHead); - /* Heap to use when allocating */ + /* Heap to use when allocating */ GlobalHeap = GetProcessHeap(); - /* Allocate Heap for 1024 Sockets, can be expanded later */ - Sockets = HeapAlloc(GetProcessHeap(), 0, sizeof(PSOCKET_INFORMATION) * 1024); + /* Allocate Heap for 1024 Sockets, can be expanded later */ + Sockets = HeapAlloc(GetProcessHeap(), 0, sizeof(PSOCKET_INFORMATION) * 1024); - AFD_DbgPrint(MAX_TRACE, ("MSAFD.DLL has been loaded\n")); + AFD_DbgPrint(MAX_TRACE, ("MSAFD.DLL has been loaded\n")); break; diff --git a/reactos/dll/win32/msafd/misc/sndrcv.c b/reactos/dll/win32/msafd/misc/sndrcv.c index 62afc4a8b4c..1bf2d689210 100644 --- a/reactos/dll/win32/msafd/misc/sndrcv.c +++ b/reactos/dll/win32/msafd/misc/sndrcv.c @@ -4,10 +4,10 @@ * FILE: misc/sndrcv.c * PURPOSE: Send/receive routines * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net) - * Alex Ionescu (alex@relsoft.net) + * Alex Ionescu (alex@relsoft.net) * REVISIONS: - * CSH 01/09-2000 Created - * Alex 16/07/2004 - Complete Rewrite + * CSH 01/09-2000 Created + * Alex 16/07/2004 - Complete Rewrite */ #include @@ -16,605 +16,631 @@ INT WSPAPI -WSPAsyncSelect( - IN SOCKET Handle, - IN HWND hWnd, - IN UINT wMsg, - IN LONG lEvent, - OUT LPINT lpErrno) +WSPAsyncSelect(IN SOCKET Handle, + IN HWND hWnd, + IN UINT wMsg, + IN LONG lEvent, + OUT LPINT lpErrno) { - PSOCKET_INFORMATION Socket = NULL; - PASYNC_DATA AsyncData; - NTSTATUS Status; - ULONG BlockMode; + PSOCKET_INFORMATION Socket = NULL; + PASYNC_DATA AsyncData; + NTSTATUS Status; + ULONG BlockMode; - /* Get the Socket Structure associated to this Socket */ - Socket = GetSocketStructure(Handle); + /* Get the Socket Structure associated to this Socket */ + Socket = GetSocketStructure(Handle); - /* Allocate the Async Data Structure to pass on to the Thread later */ - AsyncData = HeapAlloc(GetProcessHeap(), 0, sizeof(*AsyncData)); + /* Allocate the Async Data Structure to pass on to the Thread later */ + AsyncData = HeapAlloc(GetProcessHeap(), 0, sizeof(*AsyncData)); - /* Change the Socket to Non Blocking */ - BlockMode = 1; - SetSocketInformation(Socket, AFD_INFO_BLOCKING_MODE, &BlockMode, NULL); - Socket->SharedData.NonBlocking = TRUE; + /* Change the Socket to Non Blocking */ + BlockMode = 1; + SetSocketInformation(Socket, AFD_INFO_BLOCKING_MODE, &BlockMode, NULL); + Socket->SharedData.NonBlocking = TRUE; - /* Deactive WSPEventSelect */ - if (Socket->SharedData.AsyncEvents) { - WSPEventSelect(Handle, NULL, 0, NULL); - } + /* Deactive WSPEventSelect */ + if (Socket->SharedData.AsyncEvents) + { + WSPEventSelect(Handle, NULL, 0, NULL); + } - /* Create the Asynch Thread if Needed */ - SockCreateOrReferenceAsyncThread(); - - /* Open a Handle to AFD's Async Helper */ - SockGetAsyncSelectHelperAfdHandle(); + /* Create the Asynch Thread if Needed */ + SockCreateOrReferenceAsyncThread(); - /* Store Socket Data */ - Socket->SharedData.hWnd = hWnd; - Socket->SharedData.wMsg = wMsg; - Socket->SharedData.AsyncEvents = lEvent; - Socket->SharedData.AsyncDisabledEvents = 0; - Socket->SharedData.SequenceNumber++; + /* Open a Handle to AFD's Async Helper */ + SockGetAsyncSelectHelperAfdHandle(); + + /* Store Socket Data */ + Socket->SharedData.hWnd = hWnd; + Socket->SharedData.wMsg = wMsg; + Socket->SharedData.AsyncEvents = lEvent; + Socket->SharedData.AsyncDisabledEvents = 0; + Socket->SharedData.SequenceNumber++; /* Return if there are no more Events */ - if ((Socket->SharedData.AsyncEvents & (~Socket->SharedData.AsyncDisabledEvents)) == 0) { - HeapFree(GetProcessHeap(), 0, AsyncData); - return 0; - } + if ((Socket->SharedData.AsyncEvents & (~Socket->SharedData.AsyncDisabledEvents)) == 0) + { + HeapFree(GetProcessHeap(), 0, AsyncData); + return 0; + } - /* Set up the Async Data */ - AsyncData->ParentSocket = Socket; - AsyncData->SequenceNumber = Socket->SharedData.SequenceNumber; + /* Set up the Async Data */ + AsyncData->ParentSocket = Socket; + AsyncData->SequenceNumber = Socket->SharedData.SequenceNumber; - /* Begin Async Select by using I/O Completion */ - Status = NtSetIoCompletion(SockAsyncCompletionPort, - (PVOID)&SockProcessQueuedAsyncSelect, - AsyncData, - 0, - 0); + /* Begin Async Select by using I/O Completion */ + Status = NtSetIoCompletion(SockAsyncCompletionPort, + (PVOID)&SockProcessQueuedAsyncSelect, + AsyncData, + 0, + 0); - /* Return */ - return ERROR_SUCCESS; + /* Return */ + return ERROR_SUCCESS; } int WSPAPI -WSPRecv( - SOCKET Handle, - LPWSABUF lpBuffers, - DWORD dwBufferCount, - LPDWORD lpNumberOfBytesRead, - LPDWORD ReceiveFlags, - LPWSAOVERLAPPED lpOverlapped, - LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine, - LPWSATHREADID lpThreadId, - LPINT lpErrno) +WSPRecv(SOCKET Handle, + LPWSABUF lpBuffers, + DWORD dwBufferCount, + LPDWORD lpNumberOfBytesRead, + LPDWORD ReceiveFlags, + LPWSAOVERLAPPED lpOverlapped, + LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine, + LPWSATHREADID lpThreadId, + LPINT lpErrno) { - PIO_STATUS_BLOCK IOSB; - IO_STATUS_BLOCK DummyIOSB; - AFD_RECV_INFO RecvInfo; - NTSTATUS Status; - PVOID APCContext; - PVOID APCFunction; - HANDLE Event; - HANDLE SockEvent; - PSOCKET_INFORMATION Socket; + PIO_STATUS_BLOCK IOSB; + IO_STATUS_BLOCK DummyIOSB; + AFD_RECV_INFO RecvInfo; + NTSTATUS Status; + PVOID APCContext; + PVOID APCFunction; + HANDLE Event; + HANDLE SockEvent; + PSOCKET_INFORMATION Socket; - AFD_DbgPrint(MID_TRACE,("Called (%x)\n", Handle)); + AFD_DbgPrint(MID_TRACE,("Called (%x)\n", Handle)); - /* Get the Socket Structure associate to this Socket*/ - Socket = GetSocketStructure(Handle); + /* Get the Socket Structure associate to this Socket*/ + Socket = GetSocketStructure(Handle); - Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE, - NULL, 1, FALSE ); + Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE, + NULL, 1, FALSE ); - if( !NT_SUCCESS(Status) ) return -1; + if( !NT_SUCCESS(Status) ) + return -1; /* Set up the Receive Structure */ RecvInfo.BufferArray = (PAFD_WSABUF)lpBuffers; RecvInfo.BufferCount = dwBufferCount; - RecvInfo.TdiFlags = 0; - RecvInfo.AfdFlags = Socket->SharedData.NonBlocking ? AFD_IMMEDIATE : 0; + RecvInfo.TdiFlags = 0; + RecvInfo.AfdFlags = Socket->SharedData.NonBlocking ? AFD_IMMEDIATE : 0; - /* Set the TDI Flags */ - if (*ReceiveFlags == 0) { - RecvInfo.TdiFlags |= TDI_RECEIVE_NORMAL; - - } else { - - if (*ReceiveFlags & MSG_OOB) { - RecvInfo.TdiFlags |= TDI_RECEIVE_EXPEDITED; - } else { - RecvInfo.TdiFlags |= TDI_RECEIVE_NORMAL; - } + /* Set the TDI Flags */ + if (*ReceiveFlags == 0) + { + RecvInfo.TdiFlags |= TDI_RECEIVE_NORMAL; + } + else + { + if (*ReceiveFlags & MSG_OOB) + { + RecvInfo.TdiFlags |= TDI_RECEIVE_EXPEDITED; + } + else + { + RecvInfo.TdiFlags |= TDI_RECEIVE_NORMAL; + } - if (*ReceiveFlags & MSG_PEEK) { - RecvInfo.TdiFlags |= TDI_RECEIVE_PEEK; - } + if (*ReceiveFlags & MSG_PEEK) + { + RecvInfo.TdiFlags |= TDI_RECEIVE_PEEK; + } - if (*ReceiveFlags & MSG_PARTIAL) { - RecvInfo.TdiFlags |= TDI_RECEIVE_NORMAL; - } - } + if (*ReceiveFlags & MSG_PARTIAL) { + RecvInfo.TdiFlags |= TDI_RECEIVE_NORMAL; + } + } - /* Verifiy if we should use APC */ + /* Verifiy if we should use APC */ - if (lpOverlapped == NULL) { + if (lpOverlapped == NULL) + { + /* Not using Overlapped structure, so use normal blocking on event */ + APCContext = NULL; + APCFunction = NULL; + Event = SockEvent; + IOSB = &DummyIOSB; + } + else + { + if (lpCompletionRoutine == NULL) + { + /* Using Overlapped Structure, but no Completition Routine, so no need for APC */ + APCContext = lpOverlapped; + APCFunction = NULL; + Event = lpOverlapped->hEvent; + } + else + { + /* Using Overlapped Structure and a Completition Routine, so use an APC */ + APCFunction = NULL; // should be a private io completition function inside us + APCContext = lpCompletionRoutine; + RecvInfo.AfdFlags = AFD_SKIP_FIO; + } - /* Not using Overlapped structure, so use normal blocking on event */ - APCContext = NULL; - APCFunction = NULL; - Event = SockEvent; - IOSB = &DummyIOSB; + IOSB = (PIO_STATUS_BLOCK)&lpOverlapped->Internal; + RecvInfo.AfdFlags |= AFD_OVERLAPPED; + } - } else { + IOSB->Status = STATUS_PENDING; - if (lpCompletionRoutine == NULL) { + /* Send IOCTL */ + Status = NtDeviceIoControlFile((HANDLE)Handle, + SockEvent, + APCFunction, + APCContext, + IOSB, + IOCTL_AFD_RECV, + &RecvInfo, + sizeof(RecvInfo), + NULL, + 0); - /* Using Overlapped Structure, but no Completition Routine, so no need for APC */ - APCContext = lpOverlapped; - APCFunction = NULL; - Event = lpOverlapped->hEvent; - - } else { - - /* Using Overlapped Structure and a Completition Routine, so use an APC */ - APCFunction = NULL; // should be a private io completition function inside us - APCContext = lpCompletionRoutine; - RecvInfo.AfdFlags = AFD_SKIP_FIO; - } - - IOSB = (PIO_STATUS_BLOCK)&lpOverlapped->Internal; - RecvInfo.AfdFlags |= AFD_OVERLAPPED; - } - - IOSB->Status = STATUS_PENDING; - - /* Send IOCTL */ - Status = NtDeviceIoControlFile((HANDLE)Handle, - SockEvent, - APCFunction, - APCContext, - IOSB, - IOCTL_AFD_RECV, - &RecvInfo, - sizeof(RecvInfo), - NULL, - 0); - - /* Wait for completition of not overlapped */ - if (Status == STATUS_PENDING && lpOverlapped == NULL) { - /* It's up to the protocol to time out recv. We must wait - * until the protocol decides it's had enough. */ - WaitForSingleObject(SockEvent, INFINITE); - Status = IOSB->Status; - } + /* Wait for completition of not overlapped */ + if (Status == STATUS_PENDING && lpOverlapped == NULL) + { + /* It's up to the protocol to time out recv. We must wait + * until the protocol decides it's had enough. + */ + WaitForSingleObject(SockEvent, INFINITE); + Status = IOSB->Status; + } NtClose( SockEvent ); - AFD_DbgPrint(MID_TRACE,("Status %x Information %d\n", - Status, IOSB->Information)); + AFD_DbgPrint(MID_TRACE,("Status %x Information %d\n", Status, IOSB->Information)); /* Return the Flags */ *ReceiveFlags = 0; - switch (Status) { - case STATUS_RECEIVE_EXPEDITED: *ReceiveFlags = MSG_OOB; break; - case STATUS_RECEIVE_PARTIAL_EXPEDITED: - *ReceiveFlags = MSG_PARTIAL | MSG_OOB; break; - case STATUS_RECEIVE_PARTIAL: *ReceiveFlags = MSG_PARTIAL; break; + switch (Status) + { + case STATUS_RECEIVE_EXPEDITED: + *ReceiveFlags = MSG_OOB; + break; + case STATUS_RECEIVE_PARTIAL_EXPEDITED: + *ReceiveFlags = MSG_PARTIAL | MSG_OOB; + break; + case STATUS_RECEIVE_PARTIAL: + *ReceiveFlags = MSG_PARTIAL; + break; } - + /* Re-enable Async Event */ - if (*ReceiveFlags == MSG_OOB) { + if (*ReceiveFlags == MSG_OOB) + { SockReenableAsyncSelectEvent(Socket, FD_OOB); - } else { + } + else + { SockReenableAsyncSelectEvent(Socket, FD_READ); } - return MsafdReturnWithErrno - ( Status, lpErrno, IOSB->Information, lpNumberOfBytesRead ); + return MsafdReturnWithErrno ( Status, lpErrno, IOSB->Information, lpNumberOfBytesRead ); } int WSPAPI -WSPRecvFrom( - SOCKET Handle, - LPWSABUF lpBuffers, - DWORD dwBufferCount, - LPDWORD lpNumberOfBytesRead, - LPDWORD ReceiveFlags, - struct sockaddr *SocketAddress, - int *SocketAddressLength, - LPWSAOVERLAPPED lpOverlapped, - LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine, - LPWSATHREADID lpThreadId, - LPINT lpErrno) +WSPRecvFrom(SOCKET Handle, + LPWSABUF lpBuffers, + DWORD dwBufferCount, + LPDWORD lpNumberOfBytesRead, + LPDWORD ReceiveFlags, + struct sockaddr *SocketAddress, + int *SocketAddressLength, + LPWSAOVERLAPPED lpOverlapped, + LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine, + LPWSATHREADID lpThreadId, + LPINT lpErrno ) { - PIO_STATUS_BLOCK IOSB; - IO_STATUS_BLOCK DummyIOSB; - AFD_RECV_INFO_UDP RecvInfo; - NTSTATUS Status; - PVOID APCContext; - PVOID APCFunction; - HANDLE Event; - HANDLE SockEvent; - PSOCKET_INFORMATION Socket; + PIO_STATUS_BLOCK IOSB; + IO_STATUS_BLOCK DummyIOSB; + AFD_RECV_INFO_UDP RecvInfo; + NTSTATUS Status; + PVOID APCContext; + PVOID APCFunction; + HANDLE Event; + HANDLE SockEvent; + PSOCKET_INFORMATION Socket; - /* Get the Socket Structure associate to this Socket*/ - Socket = GetSocketStructure(Handle); + /* Get the Socket Structure associate to this Socket*/ + Socket = GetSocketStructure(Handle); - Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE, - NULL, 1, FALSE ); + Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE, + NULL, 1, FALSE ); - if( !NT_SUCCESS(Status) ) return -1; + if( !NT_SUCCESS(Status) ) + return -1; /* Set up the Receive Structure */ RecvInfo.BufferArray = (PAFD_WSABUF)lpBuffers; RecvInfo.BufferCount = dwBufferCount; - RecvInfo.TdiFlags = 0; - RecvInfo.AfdFlags = Socket->SharedData.NonBlocking ? AFD_IMMEDIATE : 0; - RecvInfo.AddressLength = SocketAddressLength; - RecvInfo.Address = SocketAddress; + RecvInfo.TdiFlags = 0; + RecvInfo.AfdFlags = Socket->SharedData.NonBlocking ? AFD_IMMEDIATE : 0; + RecvInfo.AddressLength = SocketAddressLength; + RecvInfo.Address = SocketAddress; - /* Set the TDI Flags */ - if (*ReceiveFlags == 0) { - RecvInfo.TdiFlags |= TDI_RECEIVE_NORMAL; - - } else { - - if (*ReceiveFlags & MSG_OOB) { - RecvInfo.TdiFlags |= TDI_RECEIVE_EXPEDITED; - } else { - RecvInfo.TdiFlags |= TDI_RECEIVE_NORMAL; - } + /* Set the TDI Flags */ + if (*ReceiveFlags == 0) + { + RecvInfo.TdiFlags |= TDI_RECEIVE_NORMAL; + } + else + { + if (*ReceiveFlags & MSG_OOB) + { + RecvInfo.TdiFlags |= TDI_RECEIVE_EXPEDITED; + } + else + { + RecvInfo.TdiFlags |= TDI_RECEIVE_NORMAL; + } - if (*ReceiveFlags & MSG_PEEK) { - RecvInfo.TdiFlags |= TDI_RECEIVE_PEEK; - } + if (*ReceiveFlags & MSG_PEEK) + { + RecvInfo.TdiFlags |= TDI_RECEIVE_PEEK; + } - if (*ReceiveFlags & MSG_PARTIAL) { - RecvInfo.TdiFlags |= TDI_RECEIVE_NORMAL; - } - } + if (*ReceiveFlags & MSG_PARTIAL) + { + RecvInfo.TdiFlags |= TDI_RECEIVE_NORMAL; + } + } - /* Verifiy if we should use APC */ + /* Verifiy if we should use APC */ - if (lpOverlapped == NULL) { + if (lpOverlapped == NULL) + { + /* Not using Overlapped structure, so use normal blocking on event */ + APCContext = NULL; + APCFunction = NULL; + Event = SockEvent; + IOSB = &DummyIOSB; + } + else + { + if (lpCompletionRoutine == NULL) + { + /* Using Overlapped Structure, but no Completition Routine, so no need for APC */ + APCContext = lpOverlapped; + APCFunction = NULL; + Event = lpOverlapped->hEvent; + } + else + { + /* Using Overlapped Structure and a Completition Routine, so use an APC */ + APCFunction = NULL; // should be a private io completition function inside us + APCContext = lpCompletionRoutine; + RecvInfo.AfdFlags = AFD_SKIP_FIO; + } - /* Not using Overlapped structure, so use normal blocking on event */ - APCContext = NULL; - APCFunction = NULL; - Event = SockEvent; - IOSB = &DummyIOSB; + IOSB = (PIO_STATUS_BLOCK)&lpOverlapped->Internal; + RecvInfo.AfdFlags |= AFD_OVERLAPPED; + } - } else { + IOSB->Status = STATUS_PENDING; - if (lpCompletionRoutine == NULL) { + /* Send IOCTL */ + Status = NtDeviceIoControlFile((HANDLE)Handle, + SockEvent, + APCFunction, + APCContext, + IOSB, + IOCTL_AFD_RECV_DATAGRAM, + &RecvInfo, + sizeof(RecvInfo), + NULL, + 0); - /* Using Overlapped Structure, but no Completition Routine, so no need for APC */ - APCContext = lpOverlapped; - APCFunction = NULL; - Event = lpOverlapped->hEvent; - - } else { - - /* Using Overlapped Structure and a Completition Routine, so use an APC */ - APCFunction = NULL; // should be a private io completition function inside us - APCContext = lpCompletionRoutine; - RecvInfo.AfdFlags = AFD_SKIP_FIO; - } - - IOSB = (PIO_STATUS_BLOCK)&lpOverlapped->Internal; - RecvInfo.AfdFlags |= AFD_OVERLAPPED; - } - - IOSB->Status = STATUS_PENDING; - - /* Send IOCTL */ - Status = NtDeviceIoControlFile((HANDLE)Handle, - SockEvent, - APCFunction, - APCContext, - IOSB, - IOCTL_AFD_RECV_DATAGRAM, - &RecvInfo, - sizeof(RecvInfo), - NULL, - 0); - - /* Wait for completition of not overlapped */ - if (Status == STATUS_PENDING && lpOverlapped == NULL) { - WaitForSingleObject(SockEvent, INFINITE); // BUGBUG, shouldn wait infintely for receive... - Status = IOSB->Status; - } + /* Wait for completition of not overlapped */ + if (Status == STATUS_PENDING && lpOverlapped == NULL) + { + WaitForSingleObject(SockEvent, INFINITE); // BUGBUG, shouldn wait infintely for receive... + Status = IOSB->Status; + } NtClose( SockEvent ); /* Return the Flags */ *ReceiveFlags = 0; - switch (Status) { - case STATUS_RECEIVE_EXPEDITED: *ReceiveFlags = MSG_OOB; break; - case STATUS_RECEIVE_PARTIAL_EXPEDITED: - *ReceiveFlags = MSG_PARTIAL | MSG_OOB; break; - case STATUS_RECEIVE_PARTIAL: *ReceiveFlags = MSG_PARTIAL; break; + switch (Status) + { + case STATUS_RECEIVE_EXPEDITED: *ReceiveFlags = MSG_OOB; + break; + case STATUS_RECEIVE_PARTIAL_EXPEDITED: + *ReceiveFlags = MSG_PARTIAL | MSG_OOB; + break; + case STATUS_RECEIVE_PARTIAL: + *ReceiveFlags = MSG_PARTIAL; + break; } /* Re-enable Async Event */ SockReenableAsyncSelectEvent(Socket, FD_READ); - - return MsafdReturnWithErrno - ( Status, lpErrno, IOSB->Information, lpNumberOfBytesRead ); + + return MsafdReturnWithErrno ( Status, lpErrno, IOSB->Information, lpNumberOfBytesRead ); } int WSPAPI -WSPSend( - SOCKET Handle, - LPWSABUF lpBuffers, - DWORD dwBufferCount, - LPDWORD lpNumberOfBytesSent, - DWORD iFlags, - LPWSAOVERLAPPED lpOverlapped, - LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine, - LPWSATHREADID lpThreadId, - LPINT lpErrno) +WSPSend(SOCKET Handle, + LPWSABUF lpBuffers, + DWORD dwBufferCount, + LPDWORD lpNumberOfBytesSent, + DWORD iFlags, + LPWSAOVERLAPPED lpOverlapped, + LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine, + LPWSATHREADID lpThreadId, + LPINT lpErrno) { - PIO_STATUS_BLOCK IOSB; - IO_STATUS_BLOCK DummyIOSB; - AFD_SEND_INFO SendInfo; - NTSTATUS Status; - PVOID APCContext; - PVOID APCFunction; - HANDLE Event; - HANDLE SockEvent; - PSOCKET_INFORMATION Socket; + PIO_STATUS_BLOCK IOSB; + IO_STATUS_BLOCK DummyIOSB; + AFD_SEND_INFO SendInfo; + NTSTATUS Status; + PVOID APCContext; + PVOID APCFunction; + HANDLE Event; + HANDLE SockEvent; + PSOCKET_INFORMATION Socket; - /* Get the Socket Structure associate to this Socket*/ - Socket = GetSocketStructure(Handle); + /* Get the Socket Structure associate to this Socket*/ + Socket = GetSocketStructure(Handle); - Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE, - NULL, 1, FALSE ); + Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE, + NULL, 1, FALSE ); - if( !NT_SUCCESS(Status) ) return -1; + if( !NT_SUCCESS(Status) ) + return -1; - AFD_DbgPrint(MID_TRACE,("Called\n")); + AFD_DbgPrint(MID_TRACE,("Called\n")); /* Set up the Send Structure */ SendInfo.BufferArray = (PAFD_WSABUF)lpBuffers; SendInfo.BufferCount = dwBufferCount; - SendInfo.TdiFlags = 0; - SendInfo.AfdFlags = Socket->SharedData.NonBlocking ? AFD_IMMEDIATE : 0; + SendInfo.TdiFlags = 0; + SendInfo.AfdFlags = Socket->SharedData.NonBlocking ? AFD_IMMEDIATE : 0; - /* Set the TDI Flags */ - if (iFlags) { - if (iFlags & MSG_OOB) { - SendInfo.TdiFlags |= TDI_SEND_EXPEDITED; + /* Set the TDI Flags */ + if (iFlags) + { + if (iFlags & MSG_OOB) + { + SendInfo.TdiFlags |= TDI_SEND_EXPEDITED; } - if (iFlags & MSG_PARTIAL) { + if (iFlags & MSG_PARTIAL) + { SendInfo.TdiFlags |= TDI_SEND_PARTIAL; } - } + } - /* Verifiy if we should use APC */ - if (lpOverlapped == NULL) { + /* Verifiy if we should use APC */ + if (lpOverlapped == NULL) + { + /* Not using Overlapped structure, so use normal blocking on event */ + APCContext = NULL; + APCFunction = NULL; + Event = SockEvent; + IOSB = &DummyIOSB; + } + else + { + if (lpCompletionRoutine == NULL) + { + /* Using Overlapped Structure, but no Completition Routine, so no need for APC */ + APCContext = lpOverlapped; + APCFunction = NULL; + Event = lpOverlapped->hEvent; + } + else + { + /* Using Overlapped Structure and a Completition Routine, so use an APC */ + APCFunction = NULL; // should be a private io completition function inside us + APCContext = lpCompletionRoutine; + SendInfo.AfdFlags = AFD_SKIP_FIO; + } - /* Not using Overlapped structure, so use normal blocking on event */ - APCContext = NULL; - APCFunction = NULL; - Event = SockEvent; - IOSB = &DummyIOSB; + IOSB = (PIO_STATUS_BLOCK)&lpOverlapped->Internal; + SendInfo.AfdFlags |= AFD_OVERLAPPED; + } - } else { + IOSB->Status = STATUS_PENDING; - if (lpCompletionRoutine == NULL) { + /* Send IOCTL */ + Status = NtDeviceIoControlFile((HANDLE)Handle, + SockEvent, + APCFunction, + APCContext, + IOSB, + IOCTL_AFD_SEND, + &SendInfo, + sizeof(SendInfo), + NULL, + 0); - /* Using Overlapped Structure, but no Completition Routine, so no need for APC */ - APCContext = lpOverlapped; - APCFunction = NULL; - Event = lpOverlapped->hEvent; - - } else { + /* Wait for completition of not overlapped */ + if (Status == STATUS_PENDING && lpOverlapped == NULL) + { + WaitForSingleObject(SockEvent, INFINITE); // BUGBUG, shouldn wait infintely for send... + Status = IOSB->Status; + } - /* Using Overlapped Structure and a Completition Routine, so use an APC */ - APCFunction = NULL; // should be a private io completition function inside us - APCContext = lpCompletionRoutine; - SendInfo.AfdFlags = AFD_SKIP_FIO; - } + NtClose( SockEvent ); - IOSB = (PIO_STATUS_BLOCK)&lpOverlapped->Internal; - SendInfo.AfdFlags |= AFD_OVERLAPPED; - } + if (Status == STATUS_PENDING) + { + AFD_DbgPrint(MID_TRACE,("Leaving (Pending)\n")); + return WSA_IO_PENDING; + } - IOSB->Status = STATUS_PENDING; - - /* Send IOCTL */ - Status = NtDeviceIoControlFile((HANDLE)Handle, - SockEvent, - APCFunction, - APCContext, - IOSB, - IOCTL_AFD_SEND, - &SendInfo, - sizeof(SendInfo), - NULL, - 0); - - /* Wait for completition of not overlapped */ - if (Status == STATUS_PENDING && lpOverlapped == NULL) { - WaitForSingleObject(SockEvent, INFINITE); // BUGBUG, shouldn wait infintely for send... - Status = IOSB->Status; - } - - NtClose( SockEvent ); - - if (Status == STATUS_PENDING) { - AFD_DbgPrint(MID_TRACE,("Leaving (Pending)\n")); - return WSA_IO_PENDING; - } - - /* Re-enable Async Event */ + /* Re-enable Async Event */ SockReenableAsyncSelectEvent(Socket, FD_WRITE); - - AFD_DbgPrint(MID_TRACE,("Leaving (Success, %d)\n", IOSB->Information)); - return MsafdReturnWithErrno - ( Status, lpErrno, IOSB->Information, lpNumberOfBytesSent ); + AFD_DbgPrint(MID_TRACE,("Leaving (Success, %d)\n", IOSB->Information)); + + return MsafdReturnWithErrno( Status, lpErrno, IOSB->Information, lpNumberOfBytesSent ); } int WSPAPI -WSPSendTo( - SOCKET Handle, - LPWSABUF lpBuffers, - DWORD dwBufferCount, - LPDWORD lpNumberOfBytesSent, - DWORD iFlags, - const struct sockaddr *SocketAddress, - int SocketAddressLength, - LPWSAOVERLAPPED lpOverlapped, - LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine, - LPWSATHREADID lpThreadId, - LPINT lpErrno) +WSPSendTo(SOCKET Handle, + LPWSABUF lpBuffers, + DWORD dwBufferCount, + LPDWORD lpNumberOfBytesSent, + DWORD iFlags, + const struct sockaddr *SocketAddress, + int SocketAddressLength, + LPWSAOVERLAPPED lpOverlapped, + LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine, + LPWSATHREADID lpThreadId, + LPINT lpErrno) { - PIO_STATUS_BLOCK IOSB; - IO_STATUS_BLOCK DummyIOSB; - AFD_SEND_INFO_UDP SendInfo; - NTSTATUS Status; - PVOID APCContext; - PVOID APCFunction; - HANDLE Event; - PTRANSPORT_ADDRESS RemoteAddress; - UCHAR TdiBuffer[0x16]; - PSOCKADDR BindAddress; - INT BindAddressLength; - HANDLE SockEvent; - PSOCKET_INFORMATION Socket; - + PIO_STATUS_BLOCK IOSB; + IO_STATUS_BLOCK DummyIOSB; + AFD_SEND_INFO_UDP SendInfo; + NTSTATUS Status; + PVOID APCContext; + PVOID APCFunction; + HANDLE Event; + PTRANSPORT_ADDRESS RemoteAddress; + UCHAR TdiBuffer[0x16]; + PSOCKADDR BindAddress; + INT BindAddressLength; + HANDLE SockEvent; + PSOCKET_INFORMATION Socket; - /* Get the Socket Structure associate to this Socket*/ - Socket = GetSocketStructure(Handle); - Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE, - NULL, 1, FALSE ); + /* Get the Socket Structure associate to this Socket*/ + Socket = GetSocketStructure(Handle); - if( !NT_SUCCESS(Status) ) return -1; + Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE, + NULL, 1, FALSE ); - /* Bind us First */ - if (Socket->SharedData.State == SocketOpen) { - - /* Get the Wildcard Address */ - BindAddressLength = Socket->HelperData->MaxWSAddressLength; - BindAddress = HeapAlloc(GlobalHeap, 0, BindAddressLength); - Socket->HelperData->WSHGetWildcardSockaddr (Socket->HelperContext, - BindAddress, - &BindAddressLength); + if( !NT_SUCCESS(Status) ) + return -1; - /* Bind it */ - WSPBind(Handle, BindAddress, BindAddressLength, NULL); - } + /* Bind us First */ + if (Socket->SharedData.State == SocketOpen) + { + /* Get the Wildcard Address */ + BindAddressLength = Socket->HelperData->MaxWSAddressLength; + BindAddress = HeapAlloc(GlobalHeap, 0, BindAddressLength); + Socket->HelperData->WSHGetWildcardSockaddr (Socket->HelperContext, + BindAddress, + &BindAddressLength); - /* Set up Address in TDI Format */ - RemoteAddress = (PTRANSPORT_ADDRESS)TdiBuffer; - RemoteAddress->TAAddressCount = 1; - RemoteAddress->Address[0].AddressLength = SocketAddressLength - sizeof(SocketAddress->sa_family); - RtlCopyMemory(&RemoteAddress->Address[0].AddressType, SocketAddress, SocketAddressLength); + /* Bind it */ + WSPBind(Handle, BindAddress, BindAddressLength, NULL); + } - /* Set up Structure */ - SendInfo.BufferArray = (PAFD_WSABUF)lpBuffers; - SendInfo.AfdFlags = Socket->SharedData.NonBlocking ? AFD_IMMEDIATE : 0; - SendInfo.BufferCount = dwBufferCount; - SendInfo.RemoteAddress = RemoteAddress; - SendInfo.SizeOfRemoteAddress = Socket->HelperData->MaxTDIAddressLength; + /* Set up Address in TDI Format */ + RemoteAddress = (PTRANSPORT_ADDRESS)TdiBuffer; + RemoteAddress->TAAddressCount = 1; + RemoteAddress->Address[0].AddressLength = SocketAddressLength - sizeof(SocketAddress->sa_family); + RtlCopyMemory(&RemoteAddress->Address[0].AddressType, SocketAddress, SocketAddressLength); - /* Verifiy if we should use APC */ - if (lpOverlapped == NULL) { + /* Set up Structure */ + SendInfo.BufferArray = (PAFD_WSABUF)lpBuffers; + SendInfo.AfdFlags = Socket->SharedData.NonBlocking ? AFD_IMMEDIATE : 0; + SendInfo.BufferCount = dwBufferCount; + SendInfo.RemoteAddress = RemoteAddress; + SendInfo.SizeOfRemoteAddress = Socket->HelperData->MaxTDIAddressLength; - /* Not using Overlapped structure, so use normal blocking on event */ - APCContext = NULL; - APCFunction = NULL; - Event = SockEvent; - IOSB = &DummyIOSB; + /* Verifiy if we should use APC */ + if (lpOverlapped == NULL) + { + /* Not using Overlapped structure, so use normal blocking on event */ + APCContext = NULL; + APCFunction = NULL; + Event = SockEvent; + IOSB = &DummyIOSB; + } + else + { + if (lpCompletionRoutine == NULL) + { + /* Using Overlapped Structure, but no Completition Routine, so no need for APC */ + APCContext = lpOverlapped; + APCFunction = NULL; + Event = lpOverlapped->hEvent; + } + else + { + /* Using Overlapped Structure and a Completition Routine, so use an APC */ + APCFunction = NULL; // should be a private io completition function inside us + APCContext = lpCompletionRoutine; + SendInfo.AfdFlags = AFD_SKIP_FIO; + } - } else { + IOSB = (PIO_STATUS_BLOCK)&lpOverlapped->Internal; + SendInfo.AfdFlags |= AFD_OVERLAPPED; + } - if (lpCompletionRoutine == NULL) { + /* Send IOCTL */ + Status = NtDeviceIoControlFile((HANDLE)Handle, + SockEvent, + APCFunction, + APCContext, + IOSB, + IOCTL_AFD_SEND_DATAGRAM, + &SendInfo, + sizeof(SendInfo), + NULL, + 0); - /* Using Overlapped Structure, but no Completition Routine, so no need for APC */ - APCContext = lpOverlapped; - APCFunction = NULL; - Event = lpOverlapped->hEvent; - - } else { + /* Wait for completition of not overlapped */ + if (Status == STATUS_PENDING && lpOverlapped == NULL) + { + WaitForSingleObject(SockEvent, INFINITE); // BUGBUG, shouldn wait infintely for send... + Status = IOSB->Status; + } - /* Using Overlapped Structure and a Completition Routine, so use an APC */ - APCFunction = NULL; // should be a private io completition function inside us - APCContext = lpCompletionRoutine; - SendInfo.AfdFlags = AFD_SKIP_FIO; - } + NtClose( SockEvent ); - IOSB = (PIO_STATUS_BLOCK)&lpOverlapped->Internal; - SendInfo.AfdFlags |= AFD_OVERLAPPED; - } - - /* Send IOCTL */ - Status = NtDeviceIoControlFile((HANDLE)Handle, - SockEvent, - APCFunction, - APCContext, - IOSB, - IOCTL_AFD_SEND_DATAGRAM, - &SendInfo, - sizeof(SendInfo), - NULL, - 0); - - /* Wait for completition of not overlapped */ - if (Status == STATUS_PENDING && lpOverlapped == NULL) { - WaitForSingleObject(SockEvent, INFINITE); // BUGBUG, shouldn wait infintely for send... - Status = IOSB->Status; - } - - NtClose( SockEvent ); - - if (Status == STATUS_PENDING) { + if (Status == STATUS_PENDING) return WSA_IO_PENDING; - } - + + /* Re-enable Async Event */ SockReenableAsyncSelectEvent(Socket, FD_WRITE); - return MsafdReturnWithErrno - ( Status, lpErrno, IOSB->Information, lpNumberOfBytesSent ); + return MsafdReturnWithErrno ( Status, lpErrno, IOSB->Information, lpNumberOfBytesSent ); } INT WSPAPI -WSPRecvDisconnect( - IN SOCKET s, - OUT LPWSABUF lpInboundDisconnectData, - OUT LPINT lpErrno) +WSPRecvDisconnect(IN SOCKET s, + OUT LPWSABUF lpInboundDisconnectData, + OUT LPINT lpErrno) { - UNIMPLEMENTED - - return 0; + UNIMPLEMENTED + return 0; } INT WSPAPI -WSPSendDisconnect( - IN SOCKET s, - IN LPWSABUF lpOutboundDisconnectData, - OUT LPINT lpErrno) +WSPSendDisconnect(IN SOCKET s, + IN LPWSABUF lpOutboundDisconnectData, + OUT LPINT lpErrno) { - UNIMPLEMENTED - - return 0; + UNIMPLEMENTED + return 0; } /* EOF */