UNICODE_STRING DevName;
LARGE_INTEGER GroupData;
INT Status;
+ PSOCK_SHARED_INFO SharedData = NULL;
TRACE("Creating Socket, getting TDI Name - AddressFamily (%d) SocketType (%d) Protocol (%d).\n",
AddressFamily, SocketType, Protocol);
+ if (lpProtocolInfo && lpProtocolInfo->dwServiceFlags3 != 0 && lpProtocolInfo->dwServiceFlags4 != 0)
+ {
+ /* Duplpicating socket from different process */
+ if ((HANDLE)lpProtocolInfo->dwServiceFlags3 == INVALID_HANDLE_VALUE)
+ return WSAEINVAL;
+ if ((HANDLE)lpProtocolInfo->dwServiceFlags4 == INVALID_HANDLE_VALUE)
+ return WSAEINVAL;
+ SharedData = MapViewOfFile((HANDLE)lpProtocolInfo->dwServiceFlags3,
+ FILE_MAP_ALL_ACCESS,
+ 0,
+ 0,
+ sizeof(SOCK_SHARED_INFO));
+ if (!SharedData)
+ return WSAEINVAL;
+ InterlockedIncrement(&SharedData->RefCount);
+ AddressFamily = SharedData->AddressFamily;
+ SocketType = SharedData->SocketType;
+ Protocol = SharedData->Protocol;
+ }
+
if (AddressFamily == AF_UNSPEC && SocketType == 0 && Protocol == 0)
return WSAEINVAL;
/* Set Socket Data */
Socket = HeapAlloc(GlobalHeap, 0, sizeof(*Socket));
if (!Socket)
- return MsafdReturnWithErrno(STATUS_INSUFFICIENT_RESOURCES, lpErrno, 0, NULL);
-
+ {
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto error;
+ }
RtlZeroMemory(Socket, sizeof(*Socket));
- Socket->RefCount = 2;
- Socket->Handle = -1;
- Socket->SharedData.Listening = FALSE;
- Socket->SharedData.State = SocketOpen;
- Socket->SharedData.AddressFamily = AddressFamily;
- Socket->SharedData.SocketType = SocketType;
- Socket->SharedData.Protocol = Protocol;
+ if (SharedData)
+ {
+ Socket->SharedData = SharedData;
+ Socket->SharedDataHandle = (HANDLE)lpProtocolInfo->dwServiceFlags3;
+ Sock = (HANDLE)lpProtocolInfo->dwServiceFlags4;
+ Socket->Handle = (SOCKET)lpProtocolInfo->dwServiceFlags4;
+ }
+ else
+ {
+ Socket->SharedDataHandle = INVALID_HANDLE_VALUE;
+ Socket->SharedData = HeapAlloc(GlobalHeap, 0, sizeof(*Socket->SharedData));
+ if (!Socket->SharedData)
+ {
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto error;
+ }
+ RtlZeroMemory(Socket->SharedData, sizeof(*Socket->SharedData));
+ Socket->SharedData->State = SocketOpen;
+ Socket->SharedData->RefCount = 1L;
+ Socket->SharedData->Listening = FALSE;
+ Socket->SharedData->AddressFamily = AddressFamily;
+ Socket->SharedData->SocketType = SocketType;
+ Socket->SharedData->Protocol = Protocol;
+ Socket->SharedData->SizeOfLocalAddress = HelperData->MaxWSAddressLength;
+ Socket->SharedData->SizeOfRemoteAddress = HelperData->MaxWSAddressLength;
+ Socket->SharedData->UseDelayedAcceptance = HelperData->UseDelayedAcceptance;
+ Socket->SharedData->CreateFlags = dwFlags;
+ Socket->SharedData->ServiceFlags1 = lpProtocolInfo->dwServiceFlags1;
+ Socket->SharedData->ProviderFlags = lpProtocolInfo->dwProviderFlags;
+ Socket->SharedData->UseSAN = FALSE;
+ Socket->SharedData->NonBlocking = FALSE; /* Sockets start blocking */
+
+ /* Ask alex about this */
+ if( Socket->SharedData->SocketType == SOCK_DGRAM ||
+ Socket->SharedData->SocketType == SOCK_RAW )
+ {
+ TRACE("Connectionless socket\n");
+ Socket->SharedData->ServiceFlags1 |= XP1_CONNECTIONLESS;
+ }
+ Socket->Handle = -1;
+ }
+
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.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->LocalAddress = &Socket->SharedData->WSLocalAddress;
+ Socket->RemoteAddress = &Socket->SharedData->WSRemoteAddress;
Socket->SanData = NULL;
RtlCopyMemory(&Socket->ProtocolInfo, lpProtocolInfo, sizeof(Socket->ProtocolInfo));
-
- /* Ask alex about this */
- if( Socket->SharedData.SocketType == SOCK_DGRAM ||
- Socket->SharedData.SocketType == SOCK_RAW )
- {
- TRACE("Connectionless socket\n");
- Socket->SharedData.ServiceFlags1 |= XP1_CONNECTIONLESS;
- }
+ if (SharedData)
+ goto ok;
/* Packet Size */
SizeOfPacket = TransportName.Length + sizeof(AFD_CREATE_PACKET) + sizeof(WCHAR);
/* Set up EA Buffer */
EABuffer = HeapAlloc(GlobalHeap, 0, SizeOfEA);
if (!EABuffer)
- return MsafdReturnWithErrno(STATUS_INSUFFICIENT_RESOURCES, lpErrno, 0, NULL);
+ {
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto error;
+ }
RtlZeroMemory(EABuffer, SizeOfEA);
EABuffer->NextEntryOffset = 0;
AfdPacket->GroupID = g;
/* Set up Endpoint Flags */
- if ((Socket->SharedData.ServiceFlags1 & XP1_CONNECTIONLESS) != 0)
+ if ((Socket->SharedData->ServiceFlags1 & XP1_CONNECTIONLESS) != 0)
{
if ((SocketType != SOCK_DGRAM) && (SocketType != SOCK_RAW))
{
AfdPacket->EndpointFlags |= AFD_ENDPOINT_CONNECTIONLESS;
}
- if ((Socket->SharedData.ServiceFlags1 & XP1_MESSAGE_ORIENTED) != 0)
+ if ((Socket->SharedData->ServiceFlags1 & XP1_MESSAGE_ORIENTED) != 0)
{
if (SocketType == SOCK_STREAM)
{
- if ((Socket->SharedData.ServiceFlags1 & XP1_PSEUDO_STREAM) == 0)
+ if ((Socket->SharedData->ServiceFlags1 & XP1_PSEUDO_STREAM) == 0)
{
/* The Provider doesn't actually support Message Oriented Streams */
goto error;
WSA_FLAG_MULTIPOINT_D_ROOT |
WSA_FLAG_MULTIPOINT_D_LEAF))
{
- if ((Socket->SharedData.ServiceFlags1 & XP1_SUPPORT_MULTIPOINT) == 0)
+ if ((Socket->SharedData->ServiceFlags1 & XP1_SUPPORT_MULTIPOINT) == 0)
{
/* The Provider doesn't actually support Multipoint */
goto error;
if (dwFlags & WSA_FLAG_MULTIPOINT_C_ROOT)
{
- if (((Socket->SharedData.ServiceFlags1 & XP1_MULTIPOINT_CONTROL_PLANE) == 0)
+ 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 */
if (dwFlags & WSA_FLAG_MULTIPOINT_D_ROOT)
{
- if (((Socket->SharedData.ServiceFlags1 & XP1_MULTIPOINT_DATA_PLANE) == 0)
+ 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 */
if (!NT_SUCCESS(Status))
{
ERR("Failed to open socket. Status 0x%08x\n", Status);
-
- HeapFree(GlobalHeap, 0, Socket);
-
- return MsafdReturnWithErrno(Status, lpErrno, 0, NULL);
+ goto error;
}
/* Save Handle */
if (g != 0)
{
GetSocketInformation(Socket, AFD_INFO_GROUP_ID_TYPE, NULL, NULL, &GroupData);
- Socket->SharedData.GroupID = GroupData.u.LowPart;
- Socket->SharedData.GroupType = GroupData.u.HighPart;
+ 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,
+ &Socket->SharedData->SizeOfSendBuffer,
NULL);
GetSocketInformation (Socket,
AFD_INFO_RECEIVE_WINDOW_SIZE,
NULL,
- &Socket->SharedData.SizeOfRecvBuffer,
+ &Socket->SharedData->SizeOfRecvBuffer,
NULL);
+ok:
/* Save in Process Sockets List */
EnterCriticalSection(&SocketListLock);
error:
ERR("Ending %x\n", Status);
+ if( SharedData )
+ {
+ UnmapViewOfFile(SharedData);
+ NtClose((HANDLE)lpProtocolInfo->dwServiceFlags3);
+ }
+ else
+ {
+ if( Socket && Socket->SharedData )
+ HeapFree(GlobalHeap, 0, Socket->SharedData);
+ }
+
if( Socket )
HeapFree(GlobalHeap, 0, Socket);
return INVALID_SOCKET;
}
+
+INT
+WSPAPI
+WSPDuplicateSocket(
+ IN SOCKET Handle,
+ IN DWORD dwProcessId,
+ OUT LPWSAPROTOCOL_INFOW lpProtocolInfo,
+ OUT LPINT lpErrno)
+{
+ HANDLE hProcess, hDuplicatedSharedData, hDuplicatedHandle;
+ PSOCKET_INFORMATION Socket;
+ PSOCK_SHARED_INFO pSharedData, pOldSharedData;
+ BOOL bDuplicated;
+
+ if (Handle == INVALID_SOCKET)
+ return MsafdReturnWithErrno(STATUS_INVALID_PARAMETER, lpErrno, 0, NULL);
+ Socket = GetSocketStructure(Handle);
+ if( !Socket )
+ {
+ if( lpErrno )
+ *lpErrno = WSAENOTSOCK;
+ return SOCKET_ERROR;
+ }
+ if ( !(hProcess = OpenProcess(PROCESS_DUP_HANDLE, FALSE, dwProcessId)) )
+ return MsafdReturnWithErrno(STATUS_INVALID_PARAMETER, lpErrno, 0, NULL);
+
+ /* It is a not yet duplicated socket, so map the memory, copy the SharedData and free heap */
+ if( Socket->SharedDataHandle == INVALID_HANDLE_VALUE )
+ {
+ Socket->SharedDataHandle = CreateFileMapping(INVALID_HANDLE_VALUE,
+ NULL,
+ PAGE_READWRITE | SEC_COMMIT,
+ 0,
+ (sizeof(SOCK_SHARED_INFO) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1),
+ NULL);
+ if( Socket->SharedDataHandle == INVALID_HANDLE_VALUE )
+ return MsafdReturnWithErrno(STATUS_INSUFFICIENT_RESOURCES, lpErrno, 0, NULL);
+ pSharedData = MapViewOfFile(Socket->SharedDataHandle,
+ FILE_MAP_ALL_ACCESS,
+ 0,
+ 0,
+ sizeof(SOCK_SHARED_INFO));
+
+ RtlCopyMemory(pSharedData, Socket->SharedData, sizeof(SOCK_SHARED_INFO));
+ pOldSharedData = Socket->SharedData;
+ Socket->SharedData = pSharedData;
+ HeapFree(GlobalHeap, 0, pOldSharedData);
+ }
+ /* Duplicate the handles for the new process */
+ bDuplicated = DuplicateHandle(GetCurrentProcess(),
+ Socket->SharedDataHandle,
+ hProcess,
+ (LPHANDLE)&hDuplicatedSharedData,
+ 0,
+ FALSE,
+ DUPLICATE_SAME_ACCESS);
+ if (!bDuplicated)
+ {
+ NtClose(hProcess);
+ return MsafdReturnWithErrno(STATUS_ACCESS_DENIED, lpErrno, 0, NULL);
+ }
+ bDuplicated = DuplicateHandle(GetCurrentProcess(),
+ (HANDLE)Socket->Handle,
+ hProcess,
+ (LPHANDLE)&hDuplicatedHandle,
+ 0,
+ FALSE,
+ DUPLICATE_SAME_ACCESS);
+ NtClose(hProcess);
+ if( !bDuplicated )
+ return MsafdReturnWithErrno(STATUS_ACCESS_DENIED, lpErrno, 0, NULL);
+
+
+ if (!lpProtocolInfo)
+ return MsafdReturnWithErrno(STATUS_ACCESS_VIOLATION, lpErrno, 0, NULL);
+
+ RtlCopyMemory(lpProtocolInfo, &Socket->ProtocolInfo, sizeof(*lpProtocolInfo));
+
+ lpProtocolInfo->iAddressFamily = Socket->SharedData->AddressFamily;
+ lpProtocolInfo->iProtocol = Socket->SharedData->Protocol;
+ lpProtocolInfo->iSocketType = Socket->SharedData->SocketType;
+ lpProtocolInfo->dwServiceFlags3 = (DWORD)hDuplicatedSharedData;
+ lpProtocolInfo->dwServiceFlags4 = (DWORD)hDuplicatedHandle;
+
+ if( lpErrno )
+ *lpErrno = NO_ERROR;
+
+ return NO_ERROR;
+}
+
INT
TranslateNtStatusError(NTSTATUS Status)
{
AFD_DISCONNECT_INFO DisconnectInfo;
SOCKET_STATE OldState;
LONG LingerWait = -1;
+ DWORD References;
/* Create the Wait Event */
Status = NtCreateEvent(&SockEvent,
}
/* If a Close is already in Process, give up */
- if (Socket->SharedData.State == SocketClosed)
+ if (Socket->SharedData->State == SocketClosed)
{
WARN("Socket is closing.\n");
NtClose(SockEvent);
*lpErrno = WSAENOTSOCK;
return SOCKET_ERROR;
}
-
/* Set the state to close */
- OldState = Socket->SharedData.State;
- Socket->SharedData.State = SocketClosed;
+ OldState = Socket->SharedData->State;
+ Socket->SharedData->State = SocketClosed;
+
+ /* Decrement reference count on SharedData */
+ References = InterlockedDecrement(&Socket->SharedData->RefCount);
+ if (References)
+ goto ok;
/* 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 SendsInProgress;
ULONG SleepWait;
/* We need to respect the timeout */
SleepWait = 100;
- LingerWait = Socket->SharedData.LingerData.l_linger * 1000;
+ LingerWait = Socket->SharedData->LingerData.l_linger * 1000;
/* Loop until no more sends are pending, within the timeout */
while (LingerWait)
* go on since asyncronous operation is expected
* and we cannot offer it
*/
- if (Socket->SharedData.NonBlocking)
+ if (Socket->SharedData->NonBlocking)
{
WARN("Would block!\n");
NtClose(SockEvent);
- Socket->SharedData.State = OldState;
+ Socket->SharedData->State = OldState;
*lpErrno = WSAEWOULDBLOCK;
return SOCKET_ERROR;
}
DisconnectInfo.Timeout = RtlConvertLongToLargeInteger(0);
DisconnectInfo.DisconnectType = LingerWait < 0 ? AFD_DISCONNECT_SEND : AFD_DISCONNECT_ABORT;
- if (((DisconnectInfo.DisconnectType & AFD_DISCONNECT_SEND) && (!Socket->SharedData.SendShutdown)) ||
- ((DisconnectInfo.DisconnectType & AFD_DISCONNECT_ABORT) && (!Socket->SharedData.ReceiveShutdown)))
+ if (((DisconnectInfo.DisconnectType & AFD_DISCONNECT_SEND) && (!Socket->SharedData->SendShutdown)) ||
+ ((DisconnectInfo.DisconnectType & AFD_DISCONNECT_ABORT) && (!Socket->SharedData->ReceiveShutdown)))
{
/* Send IOCTL */
Status = NtDeviceIoControlFile((HANDLE)Handle,
/* Cleanup Time! */
Socket->HelperContext = NULL;
- Socket->SharedData.AsyncDisabledEvents = -1;
+ Socket->SharedData->AsyncDisabledEvents = -1;
NtClose(Socket->TdiAddressHandle);
Socket->TdiAddressHandle = NULL;
NtClose(Socket->TdiConnectionHandle);
Socket->TdiConnectionHandle = NULL;
-
+ok:
EnterCriticalSection(&SocketListLock);
if (SocketListHead == Socket)
{
NtClose((HANDLE)Handle);
NtClose(SockEvent);
+ if( Socket->SharedDataHandle != INVALID_HANDLE_VALUE )
+ {
+ /* It is a duplicated socket, so unmap the memory */
+ UnmapViewOfFile(Socket->SharedData);
+ NtClose(Socket->SharedDataHandle);
+ Socket->SharedData = NULL;
+ }
+ if( !References && Socket->SharedData )
+ {
+ HeapFree(GlobalHeap, 0, Socket->SharedData);
+ }
HeapFree(GlobalHeap, 0, Socket);
return MsafdReturnWithErrno(Status, lpErrno, 0, NULL);
}
&SocketInfo);
/* Set the Share Type */
- if (Socket->SharedData.ExclusiveAddressUse)
+ if (Socket->SharedData->ExclusiveAddressUse)
{
BindData->ShareType = AFD_SHARE_EXCLUSIVE;
}
{
BindData->ShareType = AFD_SHARE_WILDCARD;
}
- else if (Socket->SharedData.ReuseAddresses)
+ else if (Socket->SharedData->ReuseAddresses)
{
BindData->ShareType = AFD_SHARE_REUSE;
}
&IOSB,
IOCTL_AFD_BIND,
BindData,
- 0xA + Socket->SharedData.SizeOfLocalAddress, /* Can't figure out a way to calculate this in C*/
+ 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 */
+ 0xA + Socket->SharedData->SizeOfLocalAddress); /* Can't figure out a way to calculate this C */
/* Wait for return */
if (Status == STATUS_PENDING)
return MsafdReturnWithErrno ( Status, lpErrno, 0, NULL );
/* Set up Socket Data */
- Socket->SharedData.State = SocketBound;
+ Socket->SharedData->State = SocketBound;
Socket->TdiAddressHandle = (HANDLE)IOSB.Information;
if (Socket->HelperEvents & WSH_NOTIFY_BIND)
return SOCKET_ERROR;
}
- if (Socket->SharedData.Listening)
+ if (Socket->SharedData->Listening)
return 0;
Status = NtCreateEvent(&SockEvent,
/* Set Up Listen Structure */
ListenData.UseSAN = FALSE;
- ListenData.UseDelayedAcceptance = Socket->SharedData.UseDelayedAcceptance;
+ ListenData.UseDelayedAcceptance = Socket->SharedData->UseDelayedAcceptance;
ListenData.Backlog = Backlog;
/* Send IOCTL */
return MsafdReturnWithErrno ( Status, lpErrno, 0, NULL );
/* Set to Listening */
- Socket->SharedData.Listening = TRUE;
+ Socket->SharedData->Listening = TRUE;
if (Socket->HelperEvents & WSH_NOTIFY_LISTEN)
{
if (lpfnCondition != NULL)
{
- if ((Socket->SharedData.ServiceFlags1 & XP1_CONNECT_DATA) != 0)
+ if ((Socket->SharedData->ServiceFlags1 & XP1_CONNECT_DATA) != 0)
{
/* Find out how much data is pending */
PendingAcceptData.SequenceNumber = ListenReceiveData->SequenceNumber;
}
}
- if ((Socket->SharedData.ServiceFlags1 & XP1_QOS_SUPPORTED) != 0)
+ 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;
+ CalleeID.len = Socket->SharedData->SizeOfLocalAddress;
RemoteAddress = HeapAlloc(GlobalHeap, 0, sizeof(*RemoteAddress));
if (!RemoteAddress)
CallerData.len = PendingDataLength;
/* Check if socket supports Conditional Accept */
- if (Socket->SharedData.UseDelayedAcceptance != 0)
+ if (Socket->SharedData->UseDelayedAcceptance != 0)
{
/* Allocate Buffer for Callee Data */
CalleeDataBuffer = HeapAlloc(GlobalHeap, 0, 4096);
if (CallBack == CF_ACCEPT)
{
- if ((Socket->SharedData.ServiceFlags1 & XP1_QOS_SUPPORTED) != 0)
+ if ((Socket->SharedData->ServiceFlags1 & XP1_QOS_SUPPORTED) != 0)
{
/* I don't support this yet */
}
}
/* Create a new Socket */
- AcceptSocket = WSPSocket (Socket->SharedData.AddressFamily,
- Socket->SharedData.SocketType,
- Socket->SharedData.Protocol,
+ AcceptSocket = WSPSocket (Socket->SharedData->AddressFamily,
+ Socket->SharedData->SocketType,
+ Socket->SharedData->Protocol,
&Socket->ProtocolInfo,
GroupID,
- Socket->SharedData.CreateFlags,
+ Socket->SharedData->CreateFlags,
lpErrno);
if (AcceptSocket == INVALID_SOCKET)
return INVALID_SOCKET;
return INVALID_SOCKET;
}
- AcceptSocketInfo->SharedData.State = SocketConnected;
+ AcceptSocketInfo->SharedData->State = SocketConnected;
/* Return Address in SOCKADDR FORMAT */
if( SocketAddress )
}
/* Bind us First */
- if (Socket->SharedData.State == SocketOpen)
+ if (Socket->SharedData->State == SocketOpen)
{
/* Get the Wildcard Address */
BindAddressLength = Socket->HelperData->MaxWSAddressLength;
* 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)
+ if (Socket->SharedData->AsyncEvents & FD_CONNECT)
{
- Socket->SharedData.AsyncDisabledEvents |= FD_CONNECT | FD_WRITE;
+ Socket->SharedData->AsyncDisabledEvents |= FD_CONNECT | FD_WRITE;
}
/* Tell AFD that we want Connection Data back, have it allocate a buffer */
ConnectInfo->Unknown = 0;
/* FIXME: Handle Async Connect */
- if (Socket->SharedData.NonBlocking)
+ if (Socket->SharedData->NonBlocking)
{
ERR("Async Connect UNIMPLEMENTED!\n");
}
if (Status != STATUS_SUCCESS)
goto notify;
- Socket->SharedData.State = SocketConnected;
+ Socket->SharedData->State = SocketConnected;
Socket->TdiConnectionHandle = (HANDLE)IOSB.Information;
/* Get any pending connect data */
{
case SD_RECEIVE:
DisconnectInfo.DisconnectType = AFD_DISCONNECT_RECV;
- Socket->SharedData.ReceiveShutdown = TRUE;
+ Socket->SharedData->ReceiveShutdown = TRUE;
break;
case SD_SEND:
DisconnectInfo.DisconnectType= AFD_DISCONNECT_SEND;
- Socket->SharedData.SendShutdown = TRUE;
+ Socket->SharedData->SendShutdown = TRUE;
break;
case SD_BOTH:
DisconnectInfo.DisconnectType = AFD_DISCONNECT_RECV | AFD_DISCONNECT_SEND;
- Socket->SharedData.ReceiveShutdown = TRUE;
- Socket->SharedData.SendShutdown = TRUE;
+ Socket->SharedData->ReceiveShutdown = TRUE;
+ Socket->SharedData->SendShutdown = TRUE;
break;
}
/* Allocate a buffer for the address */
TdiAddressSize =
- sizeof(TRANSPORT_ADDRESS) + Socket->SharedData.SizeOfLocalAddress;
+ sizeof(TRANSPORT_ADDRESS) + Socket->SharedData->SizeOfLocalAddress;
TdiAddress = HeapAlloc(GlobalHeap, 0, TdiAddressSize);
if ( TdiAddress == NULL )
if (NT_SUCCESS(Status))
{
- if (*NameLength >= Socket->SharedData.SizeOfLocalAddress)
+ if (*NameLength >= Socket->SharedData->SizeOfLocalAddress)
{
Name->sa_family = SocketAddress->Address[0].AddressType;
RtlCopyMemory (Name->sa_data,
SocketAddress->Address[0].Address,
SocketAddress->Address[0].AddressLength);
- *NameLength = Socket->SharedData.SizeOfLocalAddress;
+ *NameLength = Socket->SharedData->SizeOfLocalAddress;
TRACE("NameLength %d Address: %x Port %x\n",
*NameLength, ((struct sockaddr_in *)Name)->sin_addr.s_addr,
((struct sockaddr_in *)Name)->sin_port);
return SOCKET_ERROR;
}
- if (Socket->SharedData.State != SocketConnected)
+ if (Socket->SharedData->State != SocketConnected)
{
NtClose(SockEvent);
*lpErrno = WSAENOTCONN;
}
/* Allocate a buffer for the address */
- TdiAddressSize = sizeof(TRANSPORT_ADDRESS) + Socket->SharedData.SizeOfRemoteAddress;
+ TdiAddressSize = sizeof(TRANSPORT_ADDRESS) + Socket->SharedData->SizeOfRemoteAddress;
SocketAddress = HeapAlloc(GlobalHeap, 0, TdiAddressSize);
if ( SocketAddress == NULL )
if (NT_SUCCESS(Status))
{
- if (*NameLength >= Socket->SharedData.SizeOfRemoteAddress)
+ if (*NameLength >= Socket->SharedData->SizeOfRemoteAddress)
{
Name->sa_family = SocketAddress->Address[0].AddressType;
RtlCopyMemory (Name->sa_data,
SocketAddress->Address[0].Address,
SocketAddress->Address[0].AddressLength);
- *NameLength = Socket->SharedData.SizeOfRemoteAddress;
+ *NameLength = Socket->SharedData->SizeOfRemoteAddress;
TRACE("NameLength %d Address: %x Port %x\n",
*NameLength, ((struct sockaddr_in *)Name)->sin_addr.s_addr,
((struct sockaddr_in *)Name)->sin_port);
return SOCKET_ERROR;
}
NonBlocking = *((PULONG)lpvInBuffer) ? TRUE : FALSE;
- Socket->SharedData.NonBlocking = NonBlocking ? 1 : 0;
+ Socket->SharedData->NonBlocking = NonBlocking ? 1 : 0;
*lpErrno = SetSocketInformation(Socket, AFD_INFO_BLOCKING_MODE, &NonBlocking, NULL, NULL);
if (*lpErrno != NO_ERROR)
return SOCKET_ERROR;
return SOCKET_ERROR;
case SIO_ADDRESS_LIST_QUERY:
- if (cbOutBuffer < (sizeof(SOCKET_ADDRESS_LIST) + sizeof(Socket->WSLocalAddress)) || IS_INTRESOURCE(lpvOutBuffer))
+ if (cbOutBuffer < (sizeof(SOCKET_ADDRESS_LIST) + sizeof(Socket->SharedData->WSLocalAddress)) || IS_INTRESOURCE(lpvOutBuffer))
{
*lpErrno = WSAEINVAL;
return SOCKET_ERROR;
}
*lpcbBytesReturned = sizeof(SOCKET_ADDRESS_LIST) +
- sizeof(Socket->WSLocalAddress);
+ sizeof(Socket->SharedData->WSLocalAddress);
((SOCKET_ADDRESS_LIST*)lpvOutBuffer)->iAddressCount = 1;
- ((SOCKET_ADDRESS_LIST*)lpvOutBuffer)->Address[0].iSockaddrLength = sizeof(Socket->WSLocalAddress);
- ((SOCKET_ADDRESS_LIST*)lpvOutBuffer)->Address[0].lpSockaddr = &Socket->WSLocalAddress;
+ ((SOCKET_ADDRESS_LIST*)lpvOutBuffer)->Address[0].iSockaddrLength = sizeof(Socket->SharedData->WSLocalAddress);
+ ((SOCKET_ADDRESS_LIST*)lpvOutBuffer)->Address[0].lpSockaddr = &Socket->SharedData->WSLocalAddress;
*lpErrno = NO_ERROR;
return NO_ERROR;
switch (OptionName)
{
case SO_TYPE:
- Buffer = &Socket->SharedData.SocketType;
+ Buffer = &Socket->SharedData->SocketType;
BufferSize = sizeof(INT);
break;
case SO_RCVBUF:
- Buffer = &Socket->SharedData.SizeOfRecvBuffer;
+ Buffer = &Socket->SharedData->SizeOfRecvBuffer;
BufferSize = sizeof(INT);
break;
case SO_SNDBUF:
- Buffer = &Socket->SharedData.SizeOfSendBuffer;
+ Buffer = &Socket->SharedData->SizeOfSendBuffer;
BufferSize = sizeof(INT);
break;
case SO_ACCEPTCONN:
- BoolBuffer = Socket->SharedData.Listening;
+ BoolBuffer = Socket->SharedData->Listening;
Buffer = &BoolBuffer;
BufferSize = sizeof(BOOL);
break;
case SO_BROADCAST:
- BoolBuffer = Socket->SharedData.Broadcast;
+ BoolBuffer = Socket->SharedData->Broadcast;
Buffer = &BoolBuffer;
BufferSize = sizeof(BOOL);
break;
case SO_DEBUG:
- BoolBuffer = Socket->SharedData.Debug;
+ BoolBuffer = Socket->SharedData->Debug;
Buffer = &BoolBuffer;
BufferSize = sizeof(BOOL);
break;
case SO_DONTLINGER:
- BoolBuffer = (Socket->SharedData.LingerData.l_onoff == 0);
+ BoolBuffer = (Socket->SharedData->LingerData.l_onoff == 0);
Buffer = &BoolBuffer;
BufferSize = sizeof(BOOL);
break;
case SO_LINGER:
- if (Socket->SharedData.SocketType == SOCK_DGRAM)
+ if (Socket->SharedData->SocketType == SOCK_DGRAM)
{
*lpErrno = WSAENOPROTOOPT;
return SOCKET_ERROR;
}
- Buffer = &Socket->SharedData.LingerData;
+ Buffer = &Socket->SharedData->LingerData;
BufferSize = sizeof(struct linger);
break;
case SO_OOBINLINE:
- BoolBuffer = (Socket->SharedData.OobInline != 0);
+ BoolBuffer = (Socket->SharedData->OobInline != 0);
Buffer = &BoolBuffer;
BufferSize = sizeof(BOOL);
break;
goto SendToHelper;
case SO_CONDITIONAL_ACCEPT:
- BoolBuffer = (Socket->SharedData.UseDelayedAcceptance != 0);
+ BoolBuffer = (Socket->SharedData->UseDelayedAcceptance != 0);
Buffer = &BoolBuffer;
BufferSize = sizeof(BOOL);
break;
case SO_REUSEADDR:
- BoolBuffer = (Socket->SharedData.ReuseAddresses != 0);
+ BoolBuffer = (Socket->SharedData->ReuseAddresses != 0);
Buffer = &BoolBuffer;
BufferSize = sizeof(BOOL);
break;
case SO_EXCLUSIVEADDRUSE:
- BoolBuffer = (Socket->SharedData.ExclusiveAddressUse != 0);
+ BoolBuffer = (Socket->SharedData->ExclusiveAddressUse != 0);
Buffer = &BoolBuffer;
BufferSize = sizeof(BOOL);
break;
BufferSize = sizeof(INT);
break;
case SO_SNDTIMEO:
- Buffer = &Socket->SharedData.SendTimeout;
+ Buffer = &Socket->SharedData->SendTimeout;
BufferSize = sizeof(DWORD);
break;
case SO_RCVTIMEO:
- Buffer = &Socket->SharedData.RecvTimeout;
+ Buffer = &Socket->SharedData->RecvTimeout;
BufferSize = sizeof(DWORD);
break;
case SO_PROTOCOL_INFOW:
*lpErrno = WSAEFAULT;
return SOCKET_ERROR;
}
- Socket->SharedData.Broadcast = (*optval != 0) ? 1 : 0;
+ Socket->SharedData->Broadcast = (*optval != 0) ? 1 : 0;
return 0;
case SO_DONTLINGER:
*lpErrno = WSAEFAULT;
return SOCKET_ERROR;
}
- Socket->SharedData.LingerData.l_onoff = (*optval != 0) ? 0 : 1;
+ Socket->SharedData->LingerData.l_onoff = (*optval != 0) ? 0 : 1;
return 0;
case SO_REUSEADDR:
*lpErrno = WSAEFAULT;
return SOCKET_ERROR;
}
- Socket->SharedData.ReuseAddresses = (*optval != 0) ? 1 : 0;
+ Socket->SharedData->ReuseAddresses = (*optval != 0) ? 1 : 0;
return 0;
case SO_EXCLUSIVEADDRUSE:
*lpErrno = WSAEFAULT;
return SOCKET_ERROR;
}
- Socket->SharedData.ExclusiveAddressUse = (*optval != 0) ? 1 : 0;
+ Socket->SharedData->ExclusiveAddressUse = (*optval != 0) ? 1 : 0;
return 0;
case SO_LINGER:
*lpErrno = WSAEFAULT;
return SOCKET_ERROR;
}
- RtlCopyMemory(&Socket->SharedData.LingerData,
+ RtlCopyMemory(&Socket->SharedData->LingerData,
optval,
sizeof(struct linger));
return 0;
return SOCKET_ERROR;
}
- RtlCopyMemory(&Socket->SharedData.SendTimeout,
+ RtlCopyMemory(&Socket->SharedData->SendTimeout,
optval,
sizeof(DWORD));
return 0;
return SOCKET_ERROR;
}
- RtlCopyMemory(&Socket->SharedData.RecvTimeout,
+ RtlCopyMemory(&Socket->SharedData->RecvTimeout,
optval,
sizeof(DWORD));
return 0;
return -1;
/* Create Context */
- ContextData.SharedData = Socket->SharedData;
+ ContextData.SharedData = *Socket->SharedData;
ContextData.SizeOfHelperData = 0;
RtlCopyMemory (&ContextData.LocalAddress,
Socket->LocalAddress,
- Socket->SharedData.SizeOfLocalAddress);
+ Socket->SharedData->SizeOfLocalAddress);
RtlCopyMemory (&ContextData.RemoteAddress,
Socket->RemoteAddress,
- Socket->SharedData.SizeOfRemoteAddress);
+ Socket->SharedData->SizeOfRemoteAddress);
/* Send IOCTL */
Status = NtDeviceIoControlFile((HANDLE)Socket->Handle,
Socket = AsyncData->ParentSocket;
/* Check if the Sequence Number Changed behind our back */
- if (AsyncData->SequenceNumber != Socket->SharedData.SequenceNumber )
+ if (AsyncData->SequenceNumber != Socket->SharedData->SequenceNumber )
{
return;
}
switch (AsyncData->AsyncSelectInfo.Handles[0].Events & x)
{
case AFD_EVENT_RECEIVE:
- if (0 != (Socket->SharedData.AsyncEvents & FD_READ) &&
- 0 == (Socket->SharedData.AsyncDisabledEvents & FD_READ))
+ if (0 != (Socket->SharedData->AsyncEvents & FD_READ) &&
+ 0 == (Socket->SharedData->AsyncDisabledEvents & FD_READ))
{
/* Make the Notifcation */
- (Upcalls.lpWPUPostMessage)(Socket->SharedData.hWnd,
- Socket->SharedData.wMsg,
+ (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;
+ Socket->SharedData->AsyncDisabledEvents |= FD_READ;
}
break;
case AFD_EVENT_OOB_RECEIVE:
- if (0 != (Socket->SharedData.AsyncEvents & FD_OOB) &&
- 0 == (Socket->SharedData.AsyncDisabledEvents & FD_OOB))
+ if (0 != (Socket->SharedData->AsyncEvents & FD_OOB) &&
+ 0 == (Socket->SharedData->AsyncDisabledEvents & FD_OOB))
{
/* Make the Notifcation */
- (Upcalls.lpWPUPostMessage)(Socket->SharedData.hWnd,
- Socket->SharedData.wMsg,
+ (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;
+ Socket->SharedData->AsyncDisabledEvents |= FD_OOB;
}
break;
case AFD_EVENT_SEND:
- if (0 != (Socket->SharedData.AsyncEvents & FD_WRITE) &&
- 0 == (Socket->SharedData.AsyncDisabledEvents & FD_WRITE))
+ if (0 != (Socket->SharedData->AsyncEvents & FD_WRITE) &&
+ 0 == (Socket->SharedData->AsyncDisabledEvents & FD_WRITE))
{
/* Make the Notifcation */
- (Upcalls.lpWPUPostMessage)(Socket->SharedData.hWnd,
- Socket->SharedData.wMsg,
+ (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;
+ Socket->SharedData->AsyncDisabledEvents |= FD_WRITE;
}
break;
/* FIXME: THIS IS NOT RIGHT!!! HACK HACK HACK! */
case AFD_EVENT_CONNECT:
case AFD_EVENT_CONNECT_FAIL:
- if (0 != (Socket->SharedData.AsyncEvents & FD_CONNECT) &&
- 0 == (Socket->SharedData.AsyncDisabledEvents & FD_CONNECT))
+ if (0 != (Socket->SharedData->AsyncEvents & FD_CONNECT) &&
+ 0 == (Socket->SharedData->AsyncDisabledEvents & FD_CONNECT))
{
/* Make the Notifcation */
- (Upcalls.lpWPUPostMessage)(Socket->SharedData.hWnd,
- Socket->SharedData.wMsg,
+ (Upcalls.lpWPUPostMessage)(Socket->SharedData->hWnd,
+ Socket->SharedData->wMsg,
Socket->Handle,
WSAMAKESELECTREPLY(FD_CONNECT, 0));
/* Disable this event forever; */
- Socket->SharedData.AsyncDisabledEvents |= FD_CONNECT;
+ Socket->SharedData->AsyncDisabledEvents |= FD_CONNECT;
}
break;
case AFD_EVENT_ACCEPT:
- if (0 != (Socket->SharedData.AsyncEvents & FD_ACCEPT) &&
- 0 == (Socket->SharedData.AsyncDisabledEvents & FD_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,
+ (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;
+ 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))
+ if (0 != (Socket->SharedData->AsyncEvents & FD_CLOSE) &&
+ 0 == (Socket->SharedData->AsyncDisabledEvents & FD_CLOSE))
{
/* Make the Notifcation */
- (Upcalls.lpWPUPostMessage)(Socket->SharedData.hWnd,
- Socket->SharedData.wMsg,
+ (Upcalls.lpWPUPostMessage)(Socket->SharedData->hWnd,
+ Socket->SharedData->wMsg,
Socket->Handle,
WSAMAKESELECTREPLY(FD_CLOSE, 0));
/* Disable this event forever; */
- Socket->SharedData.AsyncDisabledEvents |= FD_CLOSE;
+ 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 )
+ if ((Socket->SharedData->AsyncEvents & (~Socket->SharedData->AsyncDisabledEvents)) == 0 )
{
return;
}
AsyncData->AsyncSelectInfo.Handles[0].Events = 0;
/* Remove unwanted events */
- lNetworkEvents = Socket->SharedData.AsyncEvents & (~Socket->SharedData.AsyncDisabledEvents);
+ lNetworkEvents = Socket->SharedData->AsyncEvents & (~Socket->SharedData->AsyncDisabledEvents);
/* Set Events to wait for */
if (lNetworkEvents & FD_READ)
Socket = AsyncData->ParentSocket;
/* If someone closed it, stop the function */
- if (Socket->SharedData.State != SocketClosed)
+ if (Socket->SharedData->State != SocketClosed)
{
/* Check if the Sequence Number changed by now, in which case quit */
- if (AsyncData->SequenceNumber == Socket->SharedData.SequenceNumber)
+ if (AsyncData->SequenceNumber == Socket->SharedData->SequenceNumber)
{
/* Do the actuall select, if needed */
- if ((Socket->SharedData.AsyncEvents & (~Socket->SharedData.AsyncDisabledEvents)))
+ if ((Socket->SharedData->AsyncEvents & (~Socket->SharedData->AsyncDisabledEvents)))
{
SockProcessAsyncSelect(Socket, AsyncData);
FreeContext = FALSE;
PASYNC_DATA AsyncData;
/* Make sure the event is actually disabled */
- if (!(Socket->SharedData.AsyncDisabledEvents & Event))
+ if (!(Socket->SharedData->AsyncDisabledEvents & Event))
{
return;
}
/* Re-enable it */
- Socket->SharedData.AsyncDisabledEvents &= ~Event;
+ 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;
}
SockCreateOrReferenceAsyncThread();
/* Increase the sequence number to stop anything else */
- Socket->SharedData.SequenceNumber++;
+ Socket->SharedData->SequenceNumber++;
/* Set up the Async Data */
AsyncData->ParentSocket = Socket;
- AsyncData->SequenceNumber = Socket->SharedData.SequenceNumber;
+ AsyncData->SequenceNumber = Socket->SharedData->SequenceNumber;
/* Begin Async Select by using I/O Completion */
NtSetIoCompletion(SockAsyncCompletionPort,