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;
-
- Status = NtCreateEvent(&SockEvent,
- EVENT_ALL_ACCESS,
- NULL,
- 1,
- FALSE);
-
- if (!NT_SUCCESS(Status))
- return MsafdReturnWithErrno(Status, lpErrno, 0, NULL);
+ PVOID APCContext = NULL;
+ PVOID APCFunction = NULL;
TRACE("Called\n");
Socket = GetSocketStructure(Handle);
if (!Socket)
{
- NtClose(SockEvent);
if (lpErrno) *lpErrno = WSAENOTSOCK;
return SOCKET_ERROR;
}
+ Status = NtCreateEvent(&SockEvent,
+ EVENT_ALL_ACCESS,
+ NULL,
+ 1,
+ FALSE);
+
+ if (!NT_SUCCESS(Status))
+ return MsafdReturnWithErrno(Status, lpErrno, 0, NULL);
+
/* Bind us First */
if (Socket->SharedData->State == SocketOpen)
{
/* FIXME: Handle Async Connect */
if (Socket->SharedData->NonBlocking)
{
- ERR("Async Connect UNIMPLEMENTED!\n");
+ 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;
}
/* Send IOCTL */
Status = NtDeviceIoControlFile((HANDLE)Handle,
SockEvent,
- NULL,
- NULL,
+ APCFunction,
+ APCContext,
&IOSB,
IOCTL_AFD_CONNECT,
ConnectInfo,
NULL,
0);
/* Wait for return */
- if (Status == STATUS_PENDING)
+ if (Status == STATUS_PENDING && !Socket->SharedData->NonBlocking)
{
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);
+
if (Status != STATUS_SUCCESS)
goto notify;