/* Save Group Info */
if (g != 0)
{
- GetSocketInformation(Socket, AFD_INFO_GROUP_ID_TYPE, 0, &GroupData);
+ GetSocketInformation(Socket, AFD_INFO_GROUP_ID_TYPE, NULL, NULL, &GroupData);
Socket->SharedData.GroupID = GroupData.u.LowPart;
Socket->SharedData.GroupType = GroupData.u.HighPart;
}
/* Get Window Sizes and Save them */
GetSocketInformation (Socket,
AFD_INFO_SEND_WINDOW_SIZE,
+ NULL,
&Socket->SharedData.SizeOfSendBuffer,
NULL);
GetSocketInformation (Socket,
AFD_INFO_RECEIVE_WINDOW_SIZE,
+ NULL,
&Socket->SharedData.SizeOfRecvBuffer,
NULL);
HANDLE SockEvent;
AFD_DISCONNECT_INFO DisconnectInfo;
SOCKET_STATE OldState;
+ LONG LingerWait = -1;
/* Create the Wait Event */
Status = NtCreateEvent(&SockEvent,
/* FIXME: Should we do this on Datagram Sockets too? */
if ((OldState == SocketConnected) && (Socket->SharedData.LingerData.l_onoff))
{
- ULONG LingerWait;
ULONG SendsInProgress;
ULONG SleepWait;
/* Find out how many Sends are in Progress */
if (GetSocketInformation(Socket,
AFD_INFO_SENDS_IN_PROGRESS,
+ NULL,
&SendsInProgress,
NULL))
{
/* Bail out if no more sends are pending */
if (!SendsInProgress)
+ {
+ LingerWait = -1;
break;
+ }
+
/*
* We have to execute a sleep, so it's kind of like
* a block. If the socket is Nonblock, we cannot
Sleep(SleepWait);
LingerWait -= SleepWait;
}
+ }
- /*
- * We have reached the timeout or sends are over.
- * Disconnect if the timeout has been reached.
- */
+ if (OldState == SocketConnected)
+ {
if (LingerWait <= 0)
{
DisconnectInfo.Timeout = RtlConvertLongToLargeInteger(0);
- DisconnectInfo.DisconnectType = AFD_DISCONNECT_ABORT;
-
- /* Send IOCTL */
- Status = NtDeviceIoControlFile((HANDLE)Handle,
- SockEvent,
- NULL,
- NULL,
- &IoStatusBlock,
- IOCTL_AFD_DISCONNECT,
- &DisconnectInfo,
- sizeof(DisconnectInfo),
- NULL,
- 0);
-
- /* Wait for return */
- if (Status == STATUS_PENDING)
+ DisconnectInfo.DisconnectType = LingerWait < 0 ? AFD_DISCONNECT_SEND : AFD_DISCONNECT_ABORT;
+
+ if (((DisconnectInfo.DisconnectType & AFD_DISCONNECT_SEND) && (!Socket->SharedData.SendShutdown)) ||
+ ((DisconnectInfo.DisconnectType & AFD_DISCONNECT_ABORT) && (!Socket->SharedData.ReceiveShutdown)))
{
- WaitForSingleObject(SockEvent, INFINITE);
- Status = IoStatusBlock.Status;
+ /* Send IOCTL */
+ Status = NtDeviceIoControlFile((HANDLE)Handle,
+ SockEvent,
+ NULL,
+ NULL,
+ &IoStatusBlock,
+ IOCTL_AFD_DISCONNECT,
+ &DisconnectInfo,
+ sizeof(DisconnectInfo),
+ NULL,
+ 0);
+
+ /* Wait for return */
+ if (Status == STATUS_PENDING)
+ {
+ WaitForSingleObject(SockEvent, INFINITE);
+ Status = IoStatusBlock.Status;
+ }
}
}
}
IO_STATUS_BLOCK IOSB;
PAFD_POLL_INFO PollInfo;
NTSTATUS Status;
- LONG HandleCount, OutCount = 0;
+ ULONG HandleCount;
+ LONG OutCount = 0;
ULONG PollBufferSize;
PVOID PollBuffer;
ULONG i, j = 0, x;
if ( HandleCount == 0 )
{
- AFD_DbgPrint(MAX_TRACE,("HandleCount: %d. Return SOCKET_ERROR\n",
+ AFD_DbgPrint(MAX_TRACE,("HandleCount: %u. Return SOCKET_ERROR\n",
HandleCount));
if (lpErrno) *lpErrno = WSAEINVAL;
return SOCKET_ERROR;
PollBufferSize = sizeof(*PollInfo) + ((HandleCount - 1) * sizeof(AFD_HANDLE));
- AFD_DbgPrint(MID_TRACE,("HandleCount: %d BufferSize: %d\n",
+ AFD_DbgPrint(MID_TRACE,("HandleCount: %u BufferSize: %u\n",
HandleCount, PollBufferSize));
/* Convert Timeout to NT Format */
ULONG CallBack;
WSAPROTOCOL_INFOW ProtocolInfo;
SOCKET AcceptSocket;
+ PSOCKET_INFORMATION AcceptSocketInfo;
UCHAR ReceiveBuffer[0x1A];
HANDLE SockEvent;
MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
return INVALID_SOCKET;
}
+
+ AcceptSocketInfo = GetSocketStructure(AcceptSocket);
+ if (!AcceptSocketInfo)
+ {
+ NtClose(SockEvent);
+ WSPCloseSocket( AcceptSocket, lpErrno );
+ MsafdReturnWithErrno( STATUS_INVALID_CONNECTION, lpErrno, 0, NULL );
+ return INVALID_SOCKET;
+ }
+
+ AcceptSocketInfo->SharedData.State = SocketConnected;
/* Return Address in SOCKADDR FORMAT */
if( SocketAddress )
if (Status != STATUS_SUCCESS)
goto notify;
+ Socket->SharedData.State = SocketConnected;
Socket->TdiConnectionHandle = (HANDLE)IOSB.Information;
/* Get any pending connect data */
break;
}
- DisconnectInfo.Timeout = RtlConvertLongToLargeInteger(-1);
+ DisconnectInfo.Timeout = RtlConvertLongToLargeInteger(-1000000);
/* Send IOCTL */
Status = NtDeviceIoControlFile((HANDLE)Handle,
return SOCKET_ERROR;
}
+ if (!Name || !NameLength)
+ {
+ NtClose(SockEvent);
+ *lpErrno = WSAEFAULT;
+ return SOCKET_ERROR;
+ }
+
/* Allocate a buffer for the address */
TdiAddressSize =
sizeof(TRANSPORT_ADDRESS) + Socket->SharedData.SizeOfLocalAddress;
if (NT_SUCCESS(Status))
{
- if (*NameLength >= SocketAddress->Address[0].AddressLength)
+ if (*NameLength >= Socket->SharedData.SizeOfLocalAddress)
{
Name->sa_family = SocketAddress->Address[0].AddressType;
RtlCopyMemory (Name->sa_data,
SocketAddress->Address[0].Address,
SocketAddress->Address[0].AddressLength);
- *NameLength = 2 + SocketAddress->Address[0].AddressLength;
+ *NameLength = Socket->SharedData.SizeOfLocalAddress;
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));
return SOCKET_ERROR;
}
+ if (Socket->SharedData.State != SocketConnected)
+ {
+ NtClose(SockEvent);
+ *lpErrno = WSAENOTCONN;
+ return SOCKET_ERROR;
+ }
+
+ if (!Name || !NameLength)
+ {
+ NtClose(SockEvent);
+ *lpErrno = WSAEFAULT;
+ return SOCKET_ERROR;
+ }
+
/* Allocate a buffer for the address */
- TdiAddressSize = sizeof(TRANSPORT_ADDRESS) + *NameLength;
+ TdiAddressSize = sizeof(TRANSPORT_ADDRESS) + Socket->SharedData.SizeOfRemoteAddress;
SocketAddress = HeapAlloc(GlobalHeap, 0, TdiAddressSize);
if ( SocketAddress == NULL )
if (NT_SUCCESS(Status))
{
- if (*NameLength >= SocketAddress->Address[0].AddressLength)
+ if (*NameLength >= Socket->SharedData.SizeOfRemoteAddress)
{
Name->sa_family = SocketAddress->Address[0].AddressType;
RtlCopyMemory (Name->sa_data,
SocketAddress->Address[0].Address,
SocketAddress->Address[0].AddressLength);
- *NameLength = 2 + SocketAddress->Address[0].AddressLength;
+ *NameLength = Socket->SharedData.SizeOfRemoteAddress;
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));
{
PSOCKET_INFORMATION Socket = NULL;
BOOLEAN NeedsCompletion;
+ BOOLEAN NonBlocking;
/* Get the Socket Structure associate to this Socket*/
Socket = GetSocketStructure(Handle);
*lpErrno = WSAEFAULT;
return SOCKET_ERROR;
}
- Socket->SharedData.NonBlocking = *((PULONG)lpvInBuffer) ? 1 : 0;
- *lpErrno = SetSocketInformation(Socket, AFD_INFO_BLOCKING_MODE, (PULONG)lpvInBuffer, NULL);
+ NonBlocking = *((PULONG)lpvInBuffer) ? TRUE : FALSE;
+ Socket->SharedData.NonBlocking = NonBlocking ? 1 : 0;
+ *lpErrno = SetSocketInformation(Socket, AFD_INFO_BLOCKING_MODE, &NonBlocking, NULL, NULL);
if (*lpErrno != NO_ERROR)
return SOCKET_ERROR;
else
*lpErrno = WSAEFAULT;
return SOCKET_ERROR;
}
- *lpErrno = GetSocketInformation(Socket, AFD_INFO_RECEIVE_CONTENT_SIZE, (PULONG)lpvOutBuffer, NULL);
+ *lpErrno = GetSocketInformation(Socket, AFD_INFO_RECEIVE_CONTENT_SIZE, NULL, (PULONG)lpvOutBuffer, NULL);
if (*lpErrno != NO_ERROR)
return SOCKET_ERROR;
else
*lpcbBytesReturned = sizeof(ULONG);
return NO_ERROR;
}
+ case SIO_GET_EXTENSION_FUNCTION_POINTER:
+ *lpErrno = WSAEINVAL;
+ return SOCKET_ERROR;
default:
*lpErrno = Socket->HelperData->WSHIoctl(Socket->HelperContext,
Handle,
int
GetSocketInformation(PSOCKET_INFORMATION Socket,
ULONG AfdInformationClass,
+ PBOOLEAN Boolean OPTIONAL,
PULONG Ulong OPTIONAL,
PLARGE_INTEGER LargeInteger OPTIONAL)
{
{
*LargeInteger = InfoData.Information.LargeInteger;
}
+ if (Boolean != NULL)
+ {
+ *Boolean = InfoData.Information.Boolean;
+ }
NtClose( SockEvent );
int
SetSocketInformation(PSOCKET_INFORMATION Socket,
- ULONG AfdInformationClass,
+ ULONG AfdInformationClass,
+ PBOOLEAN Boolean OPTIONAL,
PULONG Ulong OPTIONAL,
PLARGE_INTEGER LargeInteger OPTIONAL)
{
{
InfoData.Information.LargeInteger = *LargeInteger;
}
+ if (Boolean != NULL)
+ {
+ InfoData.Information.Boolean = *Boolean;
+ }
AFD_DbgPrint(MID_TRACE,("XXX Info %x (Data %x)\n",
AfdInformationClass, *Ulong));