{
/* Duplpicating socket from different process */
if ((HANDLE)lpProtocolInfo->dwServiceFlags3 == INVALID_HANDLE_VALUE)
- return WSAEINVAL;
+ {
+ Status = WSAEINVAL;
+ goto error;
+ }
if ((HANDLE)lpProtocolInfo->dwServiceFlags4 == INVALID_HANDLE_VALUE)
- return WSAEINVAL;
+ {
+ Status = WSAEINVAL;
+ goto error;
+ }
SharedData = MapViewOfFile((HANDLE)lpProtocolInfo->dwServiceFlags3,
FILE_MAP_ALL_ACCESS,
0,
0,
sizeof(SOCK_SHARED_INFO));
if (!SharedData)
- return WSAEINVAL;
+ {
+ Status = WSAEINVAL;
+ goto error;
+ }
InterlockedIncrement(&SharedData->RefCount);
AddressFamily = SharedData->AddressFamily;
SocketType = SharedData->SocketType;
Protocol = SharedData->Protocol;
}
- if (lpProtocolInfo)
+ if (AddressFamily == AF_UNSPEC && SocketType == 0 && Protocol == 0)
{
- if (lpProtocolInfo->iAddressFamily && AddressFamily <= 0)
- AddressFamily = lpProtocolInfo->iAddressFamily;
- if (lpProtocolInfo->iSocketType && SocketType <= 0)
- SocketType = lpProtocolInfo->iSocketType;
- if (lpProtocolInfo->iProtocol && Protocol <= 0)
- Protocol = lpProtocolInfo->iProtocol;
+ Status = WSAEINVAL;
+ goto error;
}
- /* FIXME: AF_NETDES should be AF_MAX */
- if (AddressFamily < AF_UNSPEC || AddressFamily > AF_NETDES)
- return WSAEINVAL;
-
- if (SocketType < 0 && SocketType > SOCK_SEQPACKET)
- return WSAEINVAL;
-
- if (Protocol < 0 && Protocol > IPPROTO_MAX)
- return WSAEINVAL;
-
- /* when no protocol and socket type are specified the first entry
- * from WSAEnumProtocols that has the flag PFL_MATCHES_PROTOCOL_ZERO
- * is returned */
- if (SocketType == 0 && Protocol == 0 && lpProtocolInfo && (lpProtocolInfo->dwProviderFlags & PFL_MATCHES_PROTOCOL_ZERO) == 0)
- return WSAEINVAL;
-
/* Set the defaults */
+ if (AddressFamily == AF_UNSPEC)
+ AddressFamily = AF_INET;
+
if (SocketType == 0)
{
switch (Protocol)
break;
default:
TRACE("Unknown Protocol (%d). We will try SOCK_STREAM.\n", Protocol);
- return WSAEINVAL;
+ SocketType = SOCK_STREAM;
+ break;
}
}
break;
default:
TRACE("Unknown SocketType (%d). We will try IPPROTO_TCP.\n", SocketType);
- return WSAEINVAL;
+ Protocol = IPPROTO_TCP;
+ break;
}
}
- if (AddressFamily == AF_UNSPEC)
- return WSAEINVAL;
-
/* Get Helper Data and Transport */
Status = SockGetTdiName (&AddressFamily,
&SocketType,
Socket = HeapAlloc(GlobalHeap, 0, sizeof(*Socket));
if (!Socket)
{
- Status = STATUS_INSUFFICIENT_RESOURCES;
+ Status = WSAENOBUFS;
goto error;
}
RtlZeroMemory(Socket, sizeof(*Socket));
Socket->SharedData = HeapAlloc(GlobalHeap, 0, sizeof(*Socket->SharedData));
if (!Socket->SharedData)
{
- Status = STATUS_INSUFFICIENT_RESOURCES;
+ Status = WSAENOBUFS;
goto error;
}
RtlZeroMemory(Socket->SharedData, sizeof(*Socket->SharedData));
Socket->SharedData->ProviderFlags = lpProtocolInfo->dwProviderFlags;
Socket->SharedData->UseSAN = FALSE;
Socket->SharedData->NonBlocking = FALSE; /* Sockets start blocking */
+ Socket->SharedData->RecvTimeout = INFINITE;
+ Socket->SharedData->SendTimeout = INFINITE;
+ Socket->SharedData->OobInline = FALSE;
/* Ask alex about this */
if( Socket->SharedData->SocketType == SOCK_DGRAM ||
TRACE("Connectionless socket\n");
Socket->SharedData->ServiceFlags1 |= XP1_CONNECTIONLESS;
}
- Socket->Handle = -1;
+ Socket->Handle = INVALID_SOCKET;
}
Socket->HelperContext = HelperDLLContext;
EABuffer = HeapAlloc(GlobalHeap, 0, SizeOfEA);
if (!EABuffer)
{
- Status = STATUS_INSUFFICIENT_RESOURCES;
+ Status = WSAENOBUFS;
goto error;
}
if ((SocketType != SOCK_DGRAM) && (SocketType != SOCK_RAW))
{
/* Only RAW or UDP can be Connectionless */
+ Status = WSAEINVAL;
goto error;
}
AfdPacket->EndpointFlags |= AFD_ENDPOINT_CONNECTIONLESS;
if ((Socket->SharedData->ServiceFlags1 & XP1_PSEUDO_STREAM) == 0)
{
/* The Provider doesn't actually support Message Oriented Streams */
+ Status = WSAEINVAL;
goto error;
}
}
if ((Socket->SharedData->ServiceFlags1 & XP1_SUPPORT_MULTIPOINT) == 0)
{
/* The Provider doesn't actually support Multipoint */
+ Status = WSAEINVAL;
goto error;
}
AfdPacket->EndpointFlags |= AFD_ENDPOINT_MULTIPOINT;
|| ((dwFlags & WSA_FLAG_MULTIPOINT_C_LEAF) != 0))
{
/* The Provider doesn't support Control Planes, or you already gave a leaf */
+ Status = WSAEINVAL;
goto error;
}
AfdPacket->EndpointFlags |= AFD_ENDPOINT_C_ROOT;
|| ((dwFlags & WSA_FLAG_MULTIPOINT_D_LEAF) != 0))
{
/* The Provider doesn't support Data Planes, or you already gave a leaf */
+ Status = WSAEINVAL;
goto error;
}
AfdPacket->EndpointFlags |= AFD_ENDPOINT_D_ROOT;
if (!NT_SUCCESS(Status))
{
ERR("Failed to open socket. Status 0x%08x\n", Status);
+ Status = TranslateNtStatusError(Status);
goto error;
}
case STATUS_ACCESS_DENIED:
return WSAEACCES;
+ case STATUS_NOT_IMPLEMENTED:
+ return WSAEOPNOTSUPP;
+
default:
ERR("MSAFD: Unhandled NTSTATUS value: 0x%x\n", Status);
return WSAENETDOWN;
LONG LingerWait = -1;
DWORD References;
+ /* Get the Socket Structure associate to this Socket*/
+ Socket = GetSocketStructure(Handle);
+ if (!Socket)
+ {
+ if (lpErrno) *lpErrno = WSAENOTSOCK;
+ return SOCKET_ERROR;
+ }
+
/* Create the Wait Event */
Status = NtCreateEvent(&SockEvent,
EVENT_ALL_ACCESS,
ERR("NtCreateEvent failed: 0x%08x", Status);
return SOCKET_ERROR;
}
- /* Get the Socket Structure associate to this Socket*/
- Socket = GetSocketStructure(Handle);
- if (!Socket)
- {
- NtClose(SockEvent);
- if (lpErrno) *lpErrno = WSAENOTSOCK;
- return SOCKET_ERROR;
- }
if (Socket->HelperEvents & WSH_NOTIFY_CLOSE)
{
if (lpErrno) *lpErrno = WSAENOTSOCK;
return SOCKET_ERROR;
}
- /* Set the state to close */
- OldState = Socket->SharedData->State;
- Socket->SharedData->State = SocketClosed;
/* Decrement reference count on SharedData */
References = InterlockedDecrement(&Socket->SharedData->RefCount);
if (References)
goto ok;
+ /* 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))
/*
* 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
+ * go on since asynchronous operation is expected
* and we cannot offer it
*/
if (Socket->SharedData->NonBlocking)
SOCKADDR_INFO SocketInfo;
HANDLE SockEvent;
- /* See below */
- BindData = HeapAlloc(GlobalHeap, 0, 0xA + SocketAddressLength);
- if (!BindData)
+ /* Get the Socket Structure associate to this Socket*/
+ Socket = GetSocketStructure(Handle);
+ if (!Socket)
{
- return MsafdReturnWithErrno(STATUS_INSUFFICIENT_RESOURCES, lpErrno, 0, NULL);
+ if (lpErrno) *lpErrno = WSAENOTSOCK;
+ return SOCKET_ERROR;
+ }
+ if (Socket->SharedData->State != SocketOpen)
+ {
+ if (lpErrno) *lpErrno = WSAEINVAL;
+ return SOCKET_ERROR;
+ }
+ if (!SocketAddress || SocketAddressLength < Socket->SharedData->SizeOfLocalAddress)
+ {
+ if (lpErrno) *lpErrno = WSAEINVAL;
+ return SOCKET_ERROR;
+ }
+
+ /* Get Address Information */
+ Socket->HelperData->WSHGetSockaddrType ((PSOCKADDR)SocketAddress,
+ SocketAddressLength,
+ &SocketInfo);
+
+ if (SocketInfo.AddressInfo == SockaddrAddressInfoBroadcast && !Socket->SharedData->Broadcast)
+ {
+ if (lpErrno) *lpErrno = WSAEADDRNOTAVAIL;
+ return SOCKET_ERROR;
}
Status = NtCreateEvent(&SockEvent,
if (!NT_SUCCESS(Status))
{
- HeapFree(GlobalHeap, 0, BindData);
return SOCKET_ERROR;
}
- /* Get the Socket Structure associate to this Socket*/
- Socket = GetSocketStructure(Handle);
- if (!Socket)
+ /* See below */
+ BindData = HeapAlloc(GlobalHeap, 0, 0xA + SocketAddressLength);
+ if (!BindData)
{
- HeapFree(GlobalHeap, 0, BindData);
- *lpErrno = WSAENOTSOCK;
- return SOCKET_ERROR;
+ return MsafdReturnWithErrno(STATUS_INSUFFICIENT_RESOURCES, lpErrno, 0, NULL);
}
/* Set up Address in TDI Format */
SocketAddress->sa_data,
SocketAddressLength - sizeof(SocketAddress->sa_family));
- /* Get Address Information */
- Socket->HelperData->WSHGetSockaddrType ((PSOCKADDR)SocketAddress,
- SocketAddressLength,
- &SocketInfo);
-
/* Set the Share Type */
if (Socket->SharedData->ExclusiveAddressUse)
{
NtClose( SockEvent );
HeapFree(GlobalHeap, 0, BindData);
+ Socket->SharedData->SocketLastError = TranslateNtStatusError(Status);
if (Status != STATUS_SUCCESS)
return MsafdReturnWithErrno ( Status, lpErrno, 0, NULL );
Socket = GetSocketStructure(Handle);
if (!Socket)
{
- *lpErrno = WSAENOTSOCK;
+ if (lpErrno) *lpErrno = WSAENOTSOCK;
return SOCKET_ERROR;
}
if (Socket->SharedData->Listening)
- return 0;
+ return NO_ERROR;
Status = NtCreateEvent(&SockEvent,
EVENT_ALL_ACCESS,
FALSE);
if( !NT_SUCCESS(Status) )
- return -1;
+ return SOCKET_ERROR;
/* Set Up Listen Structure */
ListenData.UseSAN = FALSE;
NtClose( SockEvent );
+ Socket->SharedData->SocketLastError = TranslateNtStatusError(Status);
if (Status != STATUS_SUCCESS)
return MsafdReturnWithErrno ( Status, lpErrno, 0, NULL );
PSOCKET_INFORMATION Socket;
SOCKET Handle;
ULONG Events;
+ fd_set selectfds;
/* Find out how many sockets we have, and how large the buffer needs
* to be */
+ FD_ZERO(&selectfds);
+ if (readfds != NULL)
+ {
+ for (i = 0; i < readfds->fd_count; i++)
+ {
+ FD_SET(readfds->fd_array[i], &selectfds);
+ }
+ }
+ if (writefds != NULL)
+ {
+ for (i = 0; i < writefds->fd_count; i++)
+ {
+ FD_SET(writefds->fd_array[i], &selectfds);
+ }
+ }
+ if (exceptfds != NULL)
+ {
+ for (i = 0; i < exceptfds->fd_count; i++)
+ {
+ FD_SET(exceptfds->fd_array[i], &selectfds);
+ }
+ }
- HandleCount = ( readfds ? readfds->fd_count : 0 ) +
- ( writefds ? writefds->fd_count : 0 ) +
- ( exceptfds ? exceptfds->fd_count : 0 );
+ HandleCount = selectfds.fd_count;
if ( HandleCount == 0 )
{
if (Timeout.QuadPart > 0)
{
if (lpErrno) *lpErrno = WSAEINVAL;
- return SOCKET_ERROR;
+ return SOCKET_ERROR;
}
TRACE("Timeout: Orig %d.%06d kernel %d\n",
timeout->tv_sec, timeout->tv_usec,
PollInfo->Exclusive = FALSE;
PollInfo->Timeout = Timeout;
+ for (i = 0; i < selectfds.fd_count; i++)
+ {
+ PollInfo->Handles[i].Handle = selectfds.fd_array[i];
+ }
if (readfds != NULL) {
- for (i = 0; i < readfds->fd_count; i++, j++)
+ for (i = 0; i < readfds->fd_count; i++)
{
+ for (j = 0; j < HandleCount; j++)
+ {
+ if (PollInfo->Handles[j].Handle == readfds->fd_array[i])
+ break;
+ }
+ if (j >= HandleCount)
+ {
+ ERR("Error while counting readfds %ld > %ld\n", j, HandleCount);
+ if (lpErrno) *lpErrno = WSAEFAULT;
+ HeapFree(GlobalHeap, 0, PollBuffer);
+ NtClose(SockEvent);
+ return SOCKET_ERROR;
+ }
Socket = GetSocketStructure(readfds->fd_array[i]);
if (!Socket)
{
NtClose(SockEvent);
return SOCKET_ERROR;
}
- PollInfo->Handles[j].Handle = readfds->fd_array[i];
- PollInfo->Handles[j].Events = AFD_EVENT_RECEIVE |
- AFD_EVENT_DISCONNECT |
- AFD_EVENT_ABORT |
- AFD_EVENT_CLOSE |
- AFD_EVENT_ACCEPT;
- if (Socket->SharedData->OobInline != 0)
- PollInfo->Handles[j].Events |= AFD_EVENT_OOB_RECEIVE;
+ PollInfo->Handles[j].Events |= AFD_EVENT_RECEIVE |
+ AFD_EVENT_DISCONNECT |
+ AFD_EVENT_ABORT |
+ AFD_EVENT_CLOSE |
+ AFD_EVENT_ACCEPT;
+ //if (Socket->SharedData->OobInline != 0)
+ // PollInfo->Handles[j].Events |= AFD_EVENT_OOB_RECEIVE;
}
}
if (writefds != NULL)
{
- for (i = 0; i < writefds->fd_count; i++, j++)
+ for (i = 0; i < writefds->fd_count; i++)
{
+ for (j = 0; j < HandleCount; j++)
+ {
+ if (PollInfo->Handles[j].Handle == writefds->fd_array[i])
+ break;
+ }
+ if (j >= HandleCount)
+ {
+ ERR("Error while counting writefds %ld > %ld\n", j, HandleCount);
+ if (lpErrno) *lpErrno = WSAEFAULT;
+ HeapFree(GlobalHeap, 0, PollBuffer);
+ NtClose(SockEvent);
+ return SOCKET_ERROR;
+ }
Socket = GetSocketStructure(writefds->fd_array[i]);
if (!Socket)
{
return SOCKET_ERROR;
}
PollInfo->Handles[j].Handle = writefds->fd_array[i];
- PollInfo->Handles[j].Events = AFD_EVENT_SEND;
+ PollInfo->Handles[j].Events |= AFD_EVENT_SEND;
if (Socket->SharedData->NonBlocking != 0)
PollInfo->Handles[j].Events |= AFD_EVENT_CONNECT;
}
}
if (exceptfds != NULL)
{
- for (i = 0; i < exceptfds->fd_count; i++, j++)
+ for (i = 0; i < exceptfds->fd_count; i++)
{
+ for (j = 0; j < HandleCount; j++)
+ {
+ if (PollInfo->Handles[j].Handle == exceptfds->fd_array[i])
+ break;
+ }
+ if (j > HandleCount)
+ {
+ ERR("Error while counting exceptfds %ld > %ld\n", j, HandleCount);
+ if (lpErrno) *lpErrno = WSAEFAULT;
+ HeapFree(GlobalHeap, 0, PollBuffer);
+ NtClose(SockEvent);
+ return SOCKET_ERROR;
+ }
Socket = GetSocketStructure(exceptfds->fd_array[i]);
if (!Socket)
{
return SOCKET_ERROR;
}
PollInfo->Handles[j].Handle = exceptfds->fd_array[i];
- PollInfo->Handles[j].Events = 0;
if (Socket->SharedData->OobInline == 0)
PollInfo->Handles[j].Events |= AFD_EVENT_OOB_RECEIVE;
if (Socket->SharedData->NonBlocking != 0)
PollInfo->Handles[j].Events |= AFD_EVENT_CONNECT_FAIL;
- if (PollInfo->Handles[j].Events == 0)
- {
- TRACE("No events can be checked for exceptfds %d. It is nonblocking and OOB line is disabled. Skipping it.", exceptfds->fd_array[i]);
- j--;
- }
}
}
- PollInfo->HandleCount = j;
+ PollInfo->HandleCount = HandleCount;
PollBufferSize = FIELD_OFFSET(AFD_POLL_INFO, Handles) + PollInfo->HandleCount * sizeof(AFD_HANDLE);
/* Send IOCTL */
TRACE("DeviceIoControlFile => %x\n", Status);
- /* Wait for Completition */
+ /* Wait for Completion */
if (Status == STATUS_PENDING)
{
WaitForSingleObject(SockEvent, INFINITE);
TRACE("Event %x on handle %x\n",
Events,
Handle);
+ if ((Events & x) == AFD_EVENT_DISCONNECT || (Events & x) == AFD_EVENT_CLOSE)
+ Socket->SharedData->SocketLastError = WSAECONNRESET;
+ if ((Events & x) == AFD_EVENT_ABORT)
+ Socket->SharedData->SocketLastError = WSAECONNABORTED;
if( readfds )
FD_SET(Handle, readfds);
break;
return HandleCount;
}
+DWORD
+GetCurrentTimeInSeconds(VOID)
+{
+ SYSTEMTIME st1970 = { 1970, 1, 0, 1, 0, 0, 0, 0 };
+ union
+ {
+ FILETIME ft;
+ ULONGLONG ll;
+ } u1970, Time;
+
+ GetSystemTimeAsFileTime(&Time.ft);
+ SystemTimeToFileTime(&st1970, &u1970.ft);
+ return (DWORD)((Time.ll - u1970.ll) / 10000000ULL);
+}
+
SOCKET
WSPAPI
WSPAccept(SOCKET Handle,
UCHAR ReceiveBuffer[0x1A];
HANDLE SockEvent;
+ /* Get the Socket Structure associate to this Socket*/
+ Socket = GetSocketStructure(Handle);
+ if (!Socket)
+ {
+ if (lpErrno) *lpErrno = WSAENOTSOCK;
+ return SOCKET_ERROR;
+ }
+ if ((SocketAddress && !SocketAddressLength) ||
+ (SocketAddressLength && !SocketAddress) ||
+ (SocketAddressLength && *SocketAddressLength < sizeof(SOCKADDR)))
+ {
+ if (lpErrno) *lpErrno = WSAEFAULT;
+ return INVALID_SOCKET;
+ }
+
Status = NtCreateEvent(&SockEvent,
EVENT_ALL_ACCESS,
NULL,
if( !NT_SUCCESS(Status) )
{
- MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
- return INVALID_SOCKET;
+ return SOCKET_ERROR;
}
/* Dynamic Structure...ugh */
ListenReceiveData = (PAFD_RECEIVED_ACCEPT_DATA)ReceiveBuffer;
- /* Get the Socket Structure associate to this Socket*/
- Socket = GetSocketStructure(Handle);
- if (!Socket)
- {
- NtClose(SockEvent);
- *lpErrno = WSAENOTSOCK;
- return INVALID_SOCKET;
- }
-
/* If this is non-blocking, make sure there's something for us to accept */
FD_ZERO(&ReadSet);
FD_SET(Socket->Handle, &ReadSet);
if (WSPSelect(0, &ReadSet, NULL, NULL, &Timeout, lpErrno) == SOCKET_ERROR)
{
NtClose(SockEvent);
- return INVALID_SOCKET;
+ return SOCKET_ERROR;
}
if (ReadSet.fd_array[0] != Socket->Handle)
{
NtClose(SockEvent);
- *lpErrno = WSAEWOULDBLOCK;
- return INVALID_SOCKET;
+ if (lpErrno) *lpErrno = WSAEWOULDBLOCK;
+ return SOCKET_ERROR;
}
/* Send IOCTL */
if (!NT_SUCCESS(Status))
{
NtClose( SockEvent );
- MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
- return INVALID_SOCKET;
+ return MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
}
if (lpfnCondition != NULL)
if (!NT_SUCCESS(Status))
{
NtClose( SockEvent );
- MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
- return INVALID_SOCKET;
+ return MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
}
/* How much data to allocate */
PendingData = HeapAlloc(GlobalHeap, 0, PendingDataLength);
if (!PendingData)
{
- MsafdReturnWithErrno( STATUS_INSUFFICIENT_RESOURCES, lpErrno, 0, NULL );
- return INVALID_SOCKET;
+ return MsafdReturnWithErrno( STATUS_INSUFFICIENT_RESOURCES, lpErrno, 0, NULL );
}
/* We want the data now */
if (!NT_SUCCESS(Status))
{
NtClose( SockEvent );
- MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
- return INVALID_SOCKET;
+ return MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
}
}
}
RemoteAddress = HeapAlloc(GlobalHeap, 0, sizeof(*RemoteAddress));
if (!RemoteAddress)
{
- MsafdReturnWithErrno(STATUS_INSUFFICIENT_RESOURCES, lpErrno, 0, NULL);
- return INVALID_SOCKET;
+ return MsafdReturnWithErrno(STATUS_INSUFFICIENT_RESOURCES, lpErrno, 0, NULL);
}
/* Set up Address in SOCKADDR Format */
/* Allocate Buffer for Callee Data */
CalleeDataBuffer = HeapAlloc(GlobalHeap, 0, 4096);
if (!CalleeDataBuffer) {
- MsafdReturnWithErrno( STATUS_INSUFFICIENT_RESOURCES, lpErrno, 0, NULL );
- return INVALID_SOCKET;
+ return MsafdReturnWithErrno( STATUS_INSUFFICIENT_RESOURCES, lpErrno, 0, NULL );
}
CalleeData.buf = CalleeDataBuffer;
CalleeData.len = 4096;
if (!NT_SUCCESS(Status))
{
- MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
- return INVALID_SOCKET;
+ return MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
}
if (CallBack == CF_REJECT )
{
- *lpErrno = WSAECONNREFUSED;
- return INVALID_SOCKET;
+ if (lpErrno) *lpErrno = WSAECONNREFUSED;
+ return SOCKET_ERROR;
}
else
{
- *lpErrno = WSAECONNREFUSED;
- return INVALID_SOCKET;
+ if (lpErrno) *lpErrno = WSAECONNREFUSED;
+ return SOCKET_ERROR;
}
}
}
Socket->SharedData->CreateFlags,
lpErrno);
if (AcceptSocket == INVALID_SOCKET)
- return INVALID_SOCKET;
+ return SOCKET_ERROR;
/* Set up the Accept Structure */
AcceptData.ListenHandle = (HANDLE)AcceptSocket;
Status = IOSB.Status;
}
+ Socket->SharedData->SocketLastError = TranslateNtStatusError(Status);
if (!NT_SUCCESS(Status))
{
NtClose(SockEvent);
WSPCloseSocket( AcceptSocket, lpErrno );
- MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
- return INVALID_SOCKET;
+ return MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
}
AcceptSocketInfo = GetSocketStructure(AcceptSocket);
{
NtClose(SockEvent);
WSPCloseSocket( AcceptSocket, lpErrno );
- MsafdReturnWithErrno( STATUS_PROTOCOL_NOT_SUPPORTED, lpErrno, 0, NULL );
- return INVALID_SOCKET;
+ return MsafdReturnWithErrno( STATUS_PROTOCOL_NOT_SUPPORTED, lpErrno, 0, NULL );
}
AcceptSocketInfo->SharedData->State = SocketConnected;
+ AcceptSocketInfo->SharedData->ConnectTime = GetCurrentTimeInSeconds();
/* Return Address in SOCKADDR FORMAT */
if( SocketAddress )
if (Status)
{
if (lpErrno) *lpErrno = Status;
- return INVALID_SOCKET;
+ return SOCKET_ERROR;
}
}
- *lpErrno = 0;
+ if (lpErrno) *lpErrno = NO_ERROR;
/* Return Socket */
return AcceptSocket;
}
-VOID
-NTAPI
-AfdConnectAPC(PVOID ApcContext,
- PIO_STATUS_BLOCK IoStatusBlock,
- ULONG Reserved)
-{
- PAFDCONNECTAPCCONTEXT Context = ApcContext;
-
- if (IoStatusBlock->Status == STATUS_SUCCESS)
- {
- Context->lpSocket->SharedData->State = SocketConnected;
- Context->lpSocket->TdiConnectionHandle = (HANDLE)IoStatusBlock->Information;
- }
-
- if (Context->lpConnectInfo) HeapFree(GetProcessHeap(), 0, Context->lpConnectInfo);
-
- /* Re-enable Async Event */
- SockReenableAsyncSelectEvent(Context->lpSocket, FD_WRITE);
-
- /* FIXME: THIS IS NOT RIGHT!!! HACK HACK HACK! */
- SockReenableAsyncSelectEvent(Context->lpSocket, FD_CONNECT);
-
- if (IoStatusBlock->Status == STATUS_SUCCESS && (Context->lpSocket->HelperEvents & WSH_NOTIFY_CONNECT))
- {
- Context->lpSocket->HelperData->WSHNotify(Context->lpSocket->HelperContext,
- Context->lpSocket->Handle,
- Context->lpSocket->TdiAddressHandle,
- Context->lpSocket->TdiConnectionHandle,
- WSH_NOTIFY_CONNECT);
- }
- else if (IoStatusBlock->Status != STATUS_SUCCESS && (Context->lpSocket->HelperEvents & WSH_NOTIFY_CONNECT_ERROR))
- {
- Context->lpSocket->HelperData->WSHNotify(Context->lpSocket->HelperContext,
- Context->lpSocket->Handle,
- Context->lpSocket->TdiAddressHandle,
- Context->lpSocket->TdiConnectionHandle,
- WSH_NOTIFY_CONNECT_ERROR);
- }
- HeapFree(GlobalHeap, 0, ApcContext);
-}
int
WSPAPI
WSPConnect(SOCKET Handle,
PSOCKADDR BindAddress;
HANDLE SockEvent;
int SocketDataLength;
- PVOID APCContext = NULL;
- PVOID APCFunction = NULL;
- TRACE("Called\n");
+ TRACE("Called (%lx) %lx:%d\n", Handle, ((const struct sockaddr_in *)SocketAddress)->sin_addr, ((const struct sockaddr_in *)SocketAddress)->sin_port);
/* Get the Socket Structure associate to this Socket*/
Socket = GetSocketStructure(Handle);
FALSE);
if (!NT_SUCCESS(Status))
- return MsafdReturnWithErrno(Status, lpErrno, 0, NULL);
+ return SOCKET_ERROR;
/* Bind us First */
if (Socket->SharedData->State == SocketOpen)
/* FIXME: Handle Async Connect */
if (Socket->SharedData->NonBlocking)
{
- APCFunction = &AfdConnectAPC; // should be a private io completition function inside us
- APCContext = HeapAlloc(GlobalHeap, 0, sizeof(AFDCONNECTAPCCONTEXT));
- if (!APCContext)
- {
- ERR("Not enough memory for APC Context\n");
- return MsafdReturnWithErrno(STATUS_INSUFFICIENT_RESOURCES, lpErrno, 0, NULL);
- }
- ((PAFDCONNECTAPCCONTEXT)APCContext)->lpConnectInfo = ConnectInfo;
- ((PAFDCONNECTAPCCONTEXT)APCContext)->lpSocket = Socket;
+ ERR("Async Connect UNIMPLEMENTED!\n");
}
/* Send IOCTL */
Status = NtDeviceIoControlFile((HANDLE)Handle,
SockEvent,
- APCFunction,
- APCContext,
+ NULL,
+ NULL,
&IOSB,
IOCTL_AFD_CONNECT,
ConnectInfo,
NULL,
0);
/* Wait for return */
- if (Status == STATUS_PENDING && !Socket->SharedData->NonBlocking)
+ if (Status == STATUS_PENDING)
{
WaitForSingleObject(SockEvent, INFINITE);
Status = IOSB.Status;
}
- if (Status == STATUS_PENDING)
- {
- TRACE("Leaving (Pending)\n");
- return MsafdReturnWithErrno(STATUS_CANT_WAIT, lpErrno, 0, NULL);
- }
-
- if (APCContext) HeapFree(GetProcessHeap(), 0, APCContext);
-
+ Socket->SharedData->SocketLastError = TranslateNtStatusError(Status);
if (Status != STATUS_SUCCESS)
goto notify;
Socket->SharedData->State = SocketConnected;
Socket->TdiConnectionHandle = (HANDLE)IOSB.Information;
+ Socket->SharedData->ConnectTime = GetCurrentTimeInSeconds();
/* Get any pending connect data */
if (lpCalleeData != NULL)
}
}
- TRACE("Ending\n");
+ TRACE("Ending %lx\n", IOSB.Status);
notify:
if (ConnectInfo) HeapFree(GetProcessHeap(), 0, ConnectInfo);
NTSTATUS Status;
HANDLE SockEvent;
- Status = NtCreateEvent(&SockEvent,
- EVENT_ALL_ACCESS,
- NULL,
- 1,
- FALSE);
-
- if( !NT_SUCCESS(Status) )
- return -1;
-
TRACE("Called\n");
/* Get the Socket Structure associate to this Socket*/
Socket = GetSocketStructure(Handle);
if (!Socket)
{
- NtClose(SockEvent);
- *lpErrno = WSAENOTSOCK;
+ if (lpErrno) *lpErrno = WSAENOTSOCK;
return SOCKET_ERROR;
}
+ Status = NtCreateEvent(&SockEvent,
+ EVENT_ALL_ACCESS,
+ NULL,
+ 1,
+ FALSE);
+
+ if( !NT_SUCCESS(Status) )
+ return SOCKET_ERROR;
+
/* Set AFD Disconnect Type */
switch (HowTo)
{
NtClose( SockEvent );
+ Socket->SharedData->SocketLastError = TranslateNtStatusError(Status);
return MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
}
{
IO_STATUS_BLOCK IOSB;
ULONG TdiAddressSize;
- PTDI_ADDRESS_INFO TdiAddress;
+ PTDI_ADDRESS_INFO TdiAddress;
PTRANSPORT_ADDRESS SocketAddress;
PSOCKET_INFORMATION Socket = NULL;
NTSTATUS Status;
HANDLE SockEvent;
- Status = NtCreateEvent(&SockEvent,
- EVENT_ALL_ACCESS,
- NULL,
- 1,
- FALSE);
-
- if( !NT_SUCCESS(Status) )
- return SOCKET_ERROR;
-
/* Get the Socket Structure associate to this Socket*/
Socket = GetSocketStructure(Handle);
if (!Socket)
{
- NtClose(SockEvent);
- *lpErrno = WSAENOTSOCK;
+ if (lpErrno) *lpErrno = WSAENOTSOCK;
return SOCKET_ERROR;
}
if (!Name || !NameLength)
{
- NtClose(SockEvent);
- *lpErrno = WSAEFAULT;
+ if (lpErrno) *lpErrno = WSAEFAULT;
return SOCKET_ERROR;
}
+ Status = NtCreateEvent(&SockEvent,
+ EVENT_ALL_ACCESS,
+ NULL,
+ 1,
+ FALSE);
+
+ if( !NT_SUCCESS(Status) )
+ return SOCKET_ERROR;
+
/* 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 )
{
NtClose( SockEvent );
- *lpErrno = WSAENOBUFS;
+ if (lpErrno) *lpErrno = WSAENOBUFS;
return SOCKET_ERROR;
}
else
{
HeapFree(GlobalHeap, 0, TdiAddress);
- *lpErrno = WSAEFAULT;
+ if (lpErrno) *lpErrno = WSAEFAULT;
return SOCKET_ERROR;
}
}
NTSTATUS Status;
HANDLE SockEvent;
- Status = NtCreateEvent(&SockEvent,
- EVENT_ALL_ACCESS,
- NULL,
- 1,
- FALSE);
-
- if( !NT_SUCCESS(Status) )
- return SOCKET_ERROR;
-
/* Get the Socket Structure associate to this Socket*/
Socket = GetSocketStructure(s);
if (!Socket)
{
- NtClose(SockEvent);
- *lpErrno = WSAENOTSOCK;
- return SOCKET_ERROR;
+ if (lpErrno) *lpErrno = WSAENOTSOCK;
+ return SOCKET_ERROR;
}
if (Socket->SharedData->State != SocketConnected)
{
- NtClose(SockEvent);
- *lpErrno = WSAENOTCONN;
+ if (lpErrno) *lpErrno = WSAENOTCONN;
return SOCKET_ERROR;
}
if (!Name || !NameLength)
{
- NtClose(SockEvent);
- *lpErrno = WSAEFAULT;
+ if (lpErrno) *lpErrno = WSAEFAULT;
return SOCKET_ERROR;
}
+ Status = NtCreateEvent(&SockEvent,
+ EVENT_ALL_ACCESS,
+ NULL,
+ 1,
+ FALSE);
+
+ if( !NT_SUCCESS(Status) )
+ return SOCKET_ERROR;
+
/* Allocate a buffer for the address */
TdiAddressSize = sizeof(TRANSPORT_ADDRESS) + Socket->SharedData->SizeOfRemoteAddress;
SocketAddress = HeapAlloc(GlobalHeap, 0, TdiAddressSize);
if ( SocketAddress == NULL )
{
NtClose( SockEvent );
- *lpErrno = WSAENOBUFS;
+ if (lpErrno) *lpErrno = WSAENOBUFS;
return SOCKET_ERROR;
}
else
{
HeapFree(GlobalHeap, 0, SocketAddress);
- *lpErrno = WSAEFAULT;
+ if (lpErrno) *lpErrno = WSAEFAULT;
return SOCKET_ERROR;
}
}
OUT LPINT lpErrno)
{
PSOCKET_INFORMATION Socket = NULL;
- BOOLEAN NeedsCompletion = lpOverlapped != NULL;
+ BOOL NeedsCompletion = lpOverlapped != NULL;
BOOLEAN NonBlocking;
INT Errno = NO_ERROR, Ret = SOCKET_ERROR;
DWORD cbRet = 0;
break;
}
NonBlocking = *((PULONG)lpvInBuffer) ? TRUE : FALSE;
+ /* Don't allow to go in blocking mode if WSPAsyncSelect or WSPEventSelect is pending */
+ if (!NonBlocking)
+ {
+ /* If there is an WSPAsyncSelect pending, fail with WSAEINVAL */
+ if (Socket->SharedData->AsyncEvents & (~Socket->SharedData->AsyncDisabledEvents))
+ {
+ Errno = WSAEINVAL;
+ break;
+ }
+ /* If there is an WSPEventSelect pending, fail with WSAEINVAL */
+ if (Socket->NetworkEvents)
+ {
+ Errno = WSAEINVAL;
+ break;
+ }
+ }
Socket->SharedData->NonBlocking = NonBlocking ? 1 : 0;
NeedsCompletion = FALSE;
Errno = SetSocketInformation(Socket, AFD_INFO_BLOCKING_MODE, &NonBlocking, NULL, NULL, lpOverlapped, lpCompletionRoutine);
Errno = WSAEINVAL;
break;
}
+ if (Socket->SharedData->SocketType != SOCK_STREAM)
+ {
+ Errno = WSAEINVAL;
+ break;
+ }
- /* FIXME: Return false for now */
- *(BOOL*)lpvOutBuffer = FALSE;
+ /* FIXME: Return false if OOBINLINE is true for now
+ We should MSG_PEEK|MSG_OOB check with driver
+ */
+ *(BOOL*)lpvOutBuffer = !Socket->SharedData->OobInline;
cbRet = sizeof(BOOL);
Errno = NO_ERROR;
&cbRet,
lpOverlapped,
lpCompletionRoutine,
- (LPBOOL)&NeedsCompletion);
+ &NeedsCompletion);
if (Errno == NO_ERROR)
Ret = NO_ERROR;
PVOID Buffer;
INT BufferSize;
BOOL BoolBuffer;
- INT IntBuffer;
+ DWORD DwordBuffer;
+ INT Errno;
+
+ TRACE("Called\n");
/* Get the Socket Structure associate to this Socket*/
Socket = GetSocketStructure(Handle);
if (Socket == NULL)
{
- *lpErrno = WSAENOTSOCK;
+ if (lpErrno) *lpErrno = WSAENOTSOCK;
+ return SOCKET_ERROR;
+ }
+ if (!OptionLength || !OptionValue)
+ {
+ if (lpErrno) *lpErrno = WSAEFAULT;
return SOCKET_ERROR;
}
-
- TRACE("Called\n");
switch (Level)
{
case SO_LINGER:
if (Socket->SharedData->SocketType == SOCK_DGRAM)
{
- *lpErrno = WSAENOPROTOOPT;
+ if (lpErrno) *lpErrno = WSAENOPROTOOPT;
return SOCKET_ERROR;
}
Buffer = &Socket->SharedData->LingerData;
break;
case SO_ERROR:
- /* HACK: This needs to be properly tracked */
- IntBuffer = 0;
- DbgPrint("MSAFD: Hacked SO_ERROR returning error %d\n", IntBuffer);
-
- Buffer = &IntBuffer;
+ Buffer = &Socket->SharedData->SocketLastError;
BufferSize = sizeof(INT);
break;
+
+ case SO_CONNECT_TIME:
+ DwordBuffer = GetCurrentTimeInSeconds() - Socket->SharedData->ConnectTime;
+ Buffer = &DwordBuffer;
+ BufferSize = sizeof(DWORD);
+ break;
+
case SO_SNDTIMEO:
Buffer = &Socket->SharedData->SendTimeout;
BufferSize = sizeof(DWORD);
default:
DbgPrint("MSAFD: Get unknown optname %x\n", OptionName);
- *lpErrno = WSAENOPROTOOPT;
+ if (lpErrno) *lpErrno = WSAENOPROTOOPT;
return SOCKET_ERROR;
}
if (*OptionLength < BufferSize)
{
- *lpErrno = WSAEFAULT;
+ if (lpErrno) *lpErrno = WSAEFAULT;
*OptionLength = BufferSize;
return SOCKET_ERROR;
}
return 0;
default:
- *lpErrno = WSAEINVAL;
+ if (lpErrno) *lpErrno = WSAEINVAL;
return SOCKET_ERROR;
}
SendToHelper:
- *lpErrno = Socket->HelperData->WSHGetSocketInformation(Socket->HelperContext,
- Handle,
- Socket->TdiAddressHandle,
- Socket->TdiConnectionHandle,
- Level,
- OptionName,
- OptionValue,
- (LPINT)OptionLength);
- return (*lpErrno == 0) ? 0 : SOCKET_ERROR;
+ Errno = Socket->HelperData->WSHGetSocketInformation(Socket->HelperContext,
+ Handle,
+ Socket->TdiAddressHandle,
+ Socket->TdiConnectionHandle,
+ Level,
+ OptionName,
+ OptionValue,
+ (LPINT)OptionLength);
+ if (lpErrno) *lpErrno = Errno;
+ return (Errno == NO_ERROR) ? NO_ERROR : SOCKET_ERROR;
}
INT
OUT LPINT lpErrno)
{
PSOCKET_INFORMATION Socket;
+ INT Errno;
/* Get the Socket Structure associate to this Socket*/
Socket = GetSocketStructure(s);
if (Socket == NULL)
{
- *lpErrno = WSAENOTSOCK;
+ if (lpErrno) *lpErrno = WSAENOTSOCK;
+ return SOCKET_ERROR;
+ }
+ if (!optval)
+ {
+ if (lpErrno) *lpErrno = WSAEFAULT;
return SOCKET_ERROR;
}
case SO_BROADCAST:
if (optlen < sizeof(BOOL))
{
- *lpErrno = WSAEFAULT;
+ if (lpErrno) *lpErrno = WSAEFAULT;
return SOCKET_ERROR;
}
Socket->SharedData->Broadcast = (*optval != 0) ? 1 : 0;
- return 0;
+ return NO_ERROR;
+
+ case SO_OOBINLINE:
+ if (optlen < sizeof(BOOL))
+ {
+ if (lpErrno) *lpErrno = WSAEFAULT;
+ return SOCKET_ERROR;
+ }
+ Socket->SharedData->OobInline = (*optval != 0) ? 1 : 0;
+ return NO_ERROR;
case SO_DONTLINGER:
if (optlen < sizeof(BOOL))
{
- *lpErrno = WSAEFAULT;
+ if (lpErrno) *lpErrno = WSAEFAULT;
return SOCKET_ERROR;
}
Socket->SharedData->LingerData.l_onoff = (*optval != 0) ? 0 : 1;
- return 0;
+ return NO_ERROR;
case SO_REUSEADDR:
if (optlen < sizeof(BOOL))
{
- *lpErrno = WSAEFAULT;
+ if (lpErrno) *lpErrno = WSAEFAULT;
return SOCKET_ERROR;
}
Socket->SharedData->ReuseAddresses = (*optval != 0) ? 1 : 0;
- return 0;
+ return NO_ERROR;
case SO_EXCLUSIVEADDRUSE:
if (optlen < sizeof(BOOL))
{
- *lpErrno = WSAEFAULT;
+ if (lpErrno) *lpErrno = WSAEFAULT;
return SOCKET_ERROR;
}
Socket->SharedData->ExclusiveAddressUse = (*optval != 0) ? 1 : 0;
- return 0;
+ return NO_ERROR;
case SO_LINGER:
if (optlen < sizeof(struct linger))
{
- *lpErrno = WSAEFAULT;
+ if (lpErrno) *lpErrno = WSAEFAULT;
return SOCKET_ERROR;
}
RtlCopyMemory(&Socket->SharedData->LingerData,
optval,
sizeof(struct linger));
- return 0;
+ return NO_ERROR;
case SO_SNDBUF:
if (optlen < sizeof(DWORD))
{
- *lpErrno = WSAEFAULT;
+ if (lpErrno) *lpErrno = WSAEFAULT;
return SOCKET_ERROR;
}
/* TODO: The total per-socket buffer space reserved for sends */
ERR("Setting send buf to %x is not implemented yet\n", optval);
- return 0;
+ return NO_ERROR;
+
+ case SO_ERROR:
+ if (optlen < sizeof(INT))
+ {
+ if (lpErrno) *lpErrno = WSAEFAULT;
+ return SOCKET_ERROR;
+ }
+
+ RtlCopyMemory(&Socket->SharedData->SocketLastError,
+ optval,
+ sizeof(INT));
+ return NO_ERROR;
case SO_SNDTIMEO:
if (optlen < sizeof(DWORD))
{
- *lpErrno = WSAEFAULT;
+ if (lpErrno) *lpErrno = WSAEFAULT;
return SOCKET_ERROR;
}
RtlCopyMemory(&Socket->SharedData->SendTimeout,
optval,
sizeof(DWORD));
- return 0;
+ return NO_ERROR;
case SO_RCVTIMEO:
if (optlen < sizeof(DWORD))
{
- *lpErrno = WSAEFAULT;
+ if (lpErrno) *lpErrno = WSAEFAULT;
return SOCKET_ERROR;
}
RtlCopyMemory(&Socket->SharedData->RecvTimeout,
optval,
sizeof(DWORD));
- return 0;
+ return NO_ERROR;
case SO_KEEPALIVE:
case SO_DONTROUTE:
default:
/* Obviously this is a hack */
ERR("MSAFD: Set unknown optname %x\n", optname);
- return 0;
+ return NO_ERROR;
}
}
SendToHelper:
- *lpErrno = Socket->HelperData->WSHSetSocketInformation(Socket->HelperContext,
- s,
- Socket->TdiAddressHandle,
- Socket->TdiConnectionHandle,
- level,
- optname,
- (PCHAR)optval,
- optlen);
- return (*lpErrno == 0) ? 0 : SOCKET_ERROR;
+ Errno = Socket->HelperData->WSHSetSocketInformation(Socket->HelperContext,
+ s,
+ Socket->TdiAddressHandle,
+ Socket->TdiConnectionHandle,
+ level,
+ optname,
+ (PCHAR)optval,
+ optlen);
+ if (lpErrno) *lpErrno = Errno;
+ return (Errno == NO_ERROR) ? NO_ERROR : SOCKET_ERROR;
}
/*
if (!lpsaAddress || !lpszAddressString || !lpdwAddressStringLength)
{
- *lpErrno = WSAEFAULT;
+ if (lpErrno) *lpErrno = WSAEFAULT;
return SOCKET_ERROR;
}
case AF_INET:
if (dwAddressLength < sizeof(SOCKADDR_IN))
{
- *lpErrno = WSAEINVAL;
+ if (lpErrno) *lpErrno = WSAEINVAL;
return SOCKET_ERROR;
}
swprintf(buffer,
}
break;
default:
- *lpErrno = WSAEINVAL;
+ if (lpErrno) *lpErrno = WSAEINVAL;
return SOCKET_ERROR;
}
if (*lpdwAddressStringLength < size)
{
*lpdwAddressStringLength = size;
- *lpErrno = WSAEFAULT;
+ if (lpErrno) *lpErrno = WSAEFAULT;
return SOCKET_ERROR;
}
IN OUT LPINT lpAddressLength,
OUT LPINT lpErrno)
{
- int pos = 0;
- LONG inetaddr = 0;
+ int numdots = 0;
+ USHORT port;
+ LONG inetaddr = 0, ip_part;
LPWSTR *bp = NULL;
SOCKADDR_IN *sockaddr;
if (!lpAddressLength || !lpAddress || !AddressString)
{
- *lpErrno = WSAEINVAL;
+ if (lpErrno) *lpErrno = WSAEINVAL;
return SOCKET_ERROR;
}
{
if (*lpAddressLength < (INT)sizeof(SOCKADDR_IN))
{
- *lpAddressLength = sizeof(SOCKADDR_IN);
- *lpErrno = WSAEFAULT;
+ if (lpErrno) *lpErrno = WSAEFAULT;
}
else
{
// translate ip string to ip
- /* rest sockaddr.sin_addr.s_addr
- for we need to be sure it is zero when we come to while */
- memset(lpAddress, 0, sizeof(SOCKADDR_IN));
-
- /* Set right adress family */
- sockaddr->sin_family = AF_INET;
-
- /* Get port number */
- pos = wcscspn(AddressString, L":") + 1;
+ /* Get ip number */
+ bp = &AddressString;
+ inetaddr = 0;
- if (pos < (int)wcslen(AddressString))
+ while (*bp < &AddressString[wcslen(AddressString)])
{
- sockaddr->sin_port = wcstol(&AddressString[pos], bp, 10);
+ ip_part = wcstol(*bp, bp, 10);
+ /* ip part number should be in range 0-255 */
+ if (ip_part < 0 || ip_part > 255)
+ {
+ if (lpErrno) *lpErrno = WSAEINVAL;
+ return SOCKET_ERROR;
+ }
+ inetaddr = (inetaddr << 8) + ip_part;
+ /* we end on string end or port separator */
+ if ((*bp)[0] == 0 || (*bp)[0] == L':')
+ break;
+ /* ip parts are dot separated. verify it */
+ if ((*bp)[0] != L'.')
+ {
+ if (lpErrno) *lpErrno = WSAEINVAL;
+ return SOCKET_ERROR;
+ }
+ /* count the dots */
+ numdots++;
+ /* move over the dot to next ip part */
+ (*bp)++;
}
- else
+
+ /* check dots count */
+ if (numdots != 3)
{
- sockaddr->sin_port = 0;
+ if (lpErrno) *lpErrno = WSAEINVAL;
+ return SOCKET_ERROR;
}
- /* Get ip number */
- pos = 0;
- inetaddr = 0;
-
- while (pos < (int)wcslen(AddressString))
+ /* Get port number */
+ if ((*bp)[0] == L':')
{
- inetaddr = (inetaddr << 8) +
- ((UCHAR)wcstol(&AddressString[pos], bp, 10));
-
- pos += wcscspn(&AddressString[pos], L".") + 1;
+ /* move over the column to port part */
+ (*bp)++;
+ /* next char should be numeric */
+ if ((*bp)[0] < L'0' || (*bp)[0] > L'9')
+ {
+ if (lpErrno) *lpErrno = WSAEINVAL;
+ return SOCKET_ERROR;
+ }
+ port = wcstol(*bp, bp, 10);
+ }
+ else
+ {
+ port = 0;
}
- *lpErrno = 0;
+ if (lpErrno) *lpErrno = NO_ERROR;
+ /* rest sockaddr.sin_addr.s_addr
+ for we need to be sure it is zero when we come to while */
+ *lpAddressLength = sizeof(*sockaddr);
+ memset(lpAddress, 0, sizeof(*sockaddr));
+ sockaddr->sin_family = AF_INET;
sockaddr->sin_addr.s_addr = inetaddr;
-
+ sockaddr->sin_port = port;
}
}
- if (!*lpErrno)
+ if (lpErrno && !*lpErrno)
{
return 0;
}
{
TRACE("Leaving.\n");
- *lpErrno = NO_ERROR;
+
+ if (lpErrno) *lpErrno = NO_ERROR;
return 0;
}
IO_STATUS_BLOCK DummyIOSB;
AFD_INFO InfoData;
NTSTATUS Status;
- PVOID APCContext;
+ PAFDAPCCONTEXT APCContext;
PIO_APC_ROUTINE APCFunction;
HANDLE Event = NULL;
HANDLE SockEvent;
FALSE);
if( !NT_SUCCESS(Status) )
- return -1;
+ return SOCKET_ERROR;
/* Set Info Class */
InfoData.InformationClass = AfdInformationClass;
if (CompletionRoutine == NULL)
{
/* Using Overlapped Structure, but no Completition Routine, so no need for APC */
- APCContext = Overlapped;
+ APCContext = (PAFDAPCCONTEXT)Overlapped;
APCFunction = NULL;
Event = Overlapped->hEvent;
}
ERR("Not enough memory for APC Context\n");
return WSAEFAULT;
}
- ((PAFDAPCCONTEXT)APCContext)->lpCompletionRoutine = CompletionRoutine;
- ((PAFDAPCCONTEXT)APCContext)->lpOverlapped = Overlapped;
- ((PAFDAPCCONTEXT)APCContext)->lpSocket = Socket;
+ APCContext->lpCompletionRoutine = CompletionRoutine;
+ APCContext->lpOverlapped = Overlapped;
+ APCContext->lpSocket = Socket;
}
IOSB = (PIO_STATUS_BLOCK)&Overlapped->Internal;
}
if (Status != STATUS_SUCCESS)
- return -1;
+ return SOCKET_ERROR;
/* Return Information */
if (Ulong != NULL)
NtClose( SockEvent );
- return 0;
+ return NO_ERROR;
}
IO_STATUS_BLOCK DummyIOSB;
AFD_INFO InfoData;
NTSTATUS Status;
- PVOID APCContext;
+ PAFDAPCCONTEXT APCContext;
PIO_APC_ROUTINE APCFunction;
HANDLE Event = NULL;
HANDLE SockEvent;
FALSE);
if( !NT_SUCCESS(Status) )
- return -1;
+ return SOCKET_ERROR;
/* Set Info Class */
InfoData.InformationClass = AfdInformationClass;
if (CompletionRoutine == NULL)
{
/* Using Overlapped Structure, but no Completition Routine, so no need for APC */
- APCContext = Overlapped;
+ APCContext = (PAFDAPCCONTEXT)Overlapped;
APCFunction = NULL;
Event = Overlapped->hEvent;
}
ERR("Not enough memory for APC Context\n");
return WSAEFAULT;
}
- ((PAFDAPCCONTEXT)APCContext)->lpCompletionRoutine = CompletionRoutine;
- ((PAFDAPCCONTEXT)APCContext)->lpOverlapped = Overlapped;
- ((PAFDAPCCONTEXT)APCContext)->lpSocket = Socket;
+ APCContext->lpCompletionRoutine = CompletionRoutine;
+ APCContext->lpOverlapped = Overlapped;
+ APCContext->lpSocket = Socket;
}
IOSB = (PIO_STATUS_BLOCK)&Overlapped->Internal;
return WSA_IO_PENDING;
}
- return Status == STATUS_SUCCESS ? 0 : -1;
+ return Status == STATUS_SUCCESS ? NO_ERROR : SOCKET_ERROR;
}
FALSE);
if( !NT_SUCCESS(Status) )
- return -1;
+ return SOCKET_ERROR;
/* Create Context */
ContextData.SharedData = *Socket->SharedData;
NULL,
0);
- /* Wait for Completition */
+ /* Wait for Completion */
if (Status == STATUS_PENDING)
{
WaitForSingleObject(SockEvent, INFINITE);
NtClose( SockEvent );
- return Status == STATUS_SUCCESS ? 0 : -1;
+ return Status == STATUS_SUCCESS ? NO_ERROR : SOCKET_ERROR;
}
BOOLEAN SockCreateOrReferenceAsyncThread(VOID)
FILE_COMPLETION_INFORMATION CompletionInfo;
OBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleFlags;
- /* First, make sure we're not already intialized */
+ /* First, make sure we're not already initialized */
if (SockAsyncHelperAfdHandle)
{
return TRUE;
if (0 != (Socket->SharedData->AsyncEvents & FD_READ) &&
0 == (Socket->SharedData->AsyncDisabledEvents & FD_READ))
{
- /* Make the Notifcation */
+ /* Make the Notification */
(Upcalls.lpWPUPostMessage)(Socket->SharedData->hWnd,
Socket->SharedData->wMsg,
Socket->Handle,
if (0 != (Socket->SharedData->AsyncEvents & FD_OOB) &&
0 == (Socket->SharedData->AsyncDisabledEvents & FD_OOB))
{
- /* Make the Notifcation */
+ /* Make the Notification */
(Upcalls.lpWPUPostMessage)(Socket->SharedData->hWnd,
Socket->SharedData->wMsg,
Socket->Handle,
if (0 != (Socket->SharedData->AsyncEvents & FD_WRITE) &&
0 == (Socket->SharedData->AsyncDisabledEvents & FD_WRITE))
{
- /* Make the Notifcation */
+ /* Make the Notification */
(Upcalls.lpWPUPostMessage)(Socket->SharedData->hWnd,
Socket->SharedData->wMsg,
Socket->Handle,
if (0 != (Socket->SharedData->AsyncEvents & FD_CONNECT) &&
0 == (Socket->SharedData->AsyncDisabledEvents & FD_CONNECT))
{
- /* Make the Notifcation */
+ /* Make the Notification */
(Upcalls.lpWPUPostMessage)(Socket->SharedData->hWnd,
Socket->SharedData->wMsg,
Socket->Handle,
if (0 != (Socket->SharedData->AsyncEvents & FD_ACCEPT) &&
0 == (Socket->SharedData->AsyncDisabledEvents & FD_ACCEPT))
{
- /* Make the Notifcation */
+ /* Make the Notification */
(Upcalls.lpWPUPostMessage)(Socket->SharedData->hWnd,
Socket->SharedData->wMsg,
Socket->Handle,
if (0 != (Socket->SharedData->AsyncEvents & FD_CLOSE) &&
0 == (Socket->SharedData->AsyncDisabledEvents & FD_CLOSE))
{
- /* Make the Notifcation */
+ /* Make the Notification */
(Upcalls.lpWPUPostMessage)(Socket->SharedData->hWnd,
Socket->SharedData->wMsg,
Socket->Handle,
/* Check if the Sequence Number changed by now, in which case quit */
if (AsyncData->SequenceNumber == Socket->SharedData->SequenceNumber)
{
- /* Do the actuall select, if needed */
+ /* Do the actual select, if needed */
if ((Socket->SharedData->AsyncEvents & (~Socket->SharedData->AsyncDisabledEvents)))
{
SockProcessAsyncSelect(Socket, AsyncData);
}
/* EOF */
-
-