+BOOL
+WSPAPI
+WSPGetOverlappedResult(
+ IN SOCKET Handle,
+ IN LPWSAOVERLAPPED lpOverlapped,
+ OUT LPDWORD lpdwBytes,
+ IN BOOL fWait,
+ OUT LPDWORD lpdwFlags,
+ OUT LPINT lpErrno)
+{
+ PIO_STATUS_BLOCK IOSB;
+ NTSTATUS Status;
+ PSOCKET_INFORMATION Socket;
+
+ TRACE("Called (%x)\n", Handle);
+
+ /* Get the Socket Structure associate to this Socket*/
+ Socket = GetSocketStructure(Handle);
+ if (!Socket)
+ {
+ if(lpErrno)
+ *lpErrno = WSAENOTSOCK;
+ return FALSE;
+ }
+ if (!lpOverlapped || !lpdwBytes || !lpdwFlags)
+ {
+ if (lpErrno)
+ *lpErrno = WSAEFAULT;
+ return FALSE;
+ }
+ IOSB = (PIO_STATUS_BLOCK)&lpOverlapped->Internal;
+ if (!IOSB)
+ {
+ if (lpErrno)
+ *lpErrno = WSAEFAULT;
+ return FALSE;
+ }
+ Status = IOSB->Status;
+
+ /* Wait for completition of overlapped */
+ if (Status == STATUS_PENDING)
+ {
+ /* It's up to the protocol to time out recv. We must wait
+ * until the protocol decides it's had enough.
+ */
+ if (fWait)
+ {
+ WaitForSingleObject(lpOverlapped->hEvent, INFINITE);
+ Status = IOSB->Status;
+ }
+ }
+
+ TRACE("Status %x Information %d\n", Status, IOSB->Information);
+
+ if (Status != STATUS_PENDING)
+ {
+ *lpdwFlags = 0;
+
+ *lpdwBytes = IOSB->Information;
+
+ /* Re-enable Async Event */
+ SockReenableAsyncSelectEvent(Socket, FD_OOB);
+ SockReenableAsyncSelectEvent(Socket, FD_WRITE);
+ SockReenableAsyncSelectEvent(Socket, FD_READ);
+ }
+
+ return Status == STATUS_SUCCESS;
+}
+
+VOID
+NTAPI
+AfdAPC(PVOID ApcContext,
+ PIO_STATUS_BLOCK IoStatusBlock,
+ ULONG Reserved)
+{
+ PAFDAPCCONTEXT Context = ApcContext;
+
+ /* Re-enable Async Event */
+ SockReenableAsyncSelectEvent(Context->lpSocket, FD_OOB);
+ SockReenableAsyncSelectEvent(Context->lpSocket, FD_READ);
+ SockReenableAsyncSelectEvent(Context->lpSocket, FD_WRITE);
+
+ Context->lpCompletionRoutine(IoStatusBlock->Status, IoStatusBlock->Information, Context->lpOverlapped, 0);
+ HeapFree(GlobalHeap, 0, ApcContext);
+}
+