diff --git a/reactos/dll/win32/msafd/misc/dllmain.c b/reactos/dll/win32/msafd/misc/dllmain.c index b1569802d63..dda602f9a54 100644 --- a/reactos/dll/win32/msafd/misc/dllmain.c +++ b/reactos/dll/win32/msafd/misc/dllmain.c @@ -1719,6 +1719,46 @@ WSPAccept(SOCKET Handle, 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, @@ -1741,6 +1781,18 @@ WSPConnect(SOCKET Handle, PSOCKADDR BindAddress; HANDLE SockEvent; int SocketDataLength; + PVOID APCContext = NULL; + PVOID APCFunction = NULL; + + TRACE("Called\n"); + + /* Get the Socket Structure associate to this Socket*/ + Socket = GetSocketStructure(Handle); + if (!Socket) + { + if (lpErrno) *lpErrno = WSAENOTSOCK; + return SOCKET_ERROR; + } Status = NtCreateEvent(&SockEvent, EVENT_ALL_ACCESS, @@ -1751,17 +1803,6 @@ WSPConnect(SOCKET Handle, if (!NT_SUCCESS(Status)) return MsafdReturnWithErrno(Status, lpErrno, 0, NULL); - TRACE("Called\n"); - - /* Get the Socket Structure associate to this Socket*/ - Socket = GetSocketStructure(Handle); - if (!Socket) - { - NtClose(SockEvent); - if (lpErrno) *lpErrno = WSAENOTSOCK; - return SOCKET_ERROR; - } - /* Bind us First */ if (Socket->SharedData->State == SocketOpen) { @@ -1872,14 +1913,22 @@ WSPConnect(SOCKET Handle, /* 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, @@ -1887,12 +1936,20 @@ WSPConnect(SOCKET Handle, 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; diff --git a/reactos/dll/win32/msafd/msafd.h b/reactos/dll/win32/msafd/msafd.h index fcf70062ea4..86d7d6294a8 100644 --- a/reactos/dll/win32/msafd/msafd.h +++ b/reactos/dll/win32/msafd/msafd.h @@ -135,6 +135,12 @@ typedef struct _AFDAPCCONTEXT PSOCKET_INFORMATION lpSocket; } AFDAPCCONTEXT, *PAFDAPCCONTEXT; +typedef struct _AFDCONNECTAPCCONTEXT +{ + PAFD_CONNECT_INFO lpConnectInfo; + PSOCKET_INFORMATION lpSocket; +} AFDCONNECTAPCCONTEXT, *PAFDCONNECTAPCCONTEXT; + SOCKET WSPAPI WSPAccept(