INT WSPAPI WSPAsyncSelect(IN SOCKET Handle, IN HWND hWnd, IN UINT wMsg, IN LONG lEvent, OUT LPINT lpErrno) { PSOCKET_INFORMATION Socket = NULL; PASYNC_DATA AsyncData; BOOLEAN BlockMode; /* Get the Socket Structure associated to this Socket */ Socket = GetSocketStructure(Handle); if (!Socket) { *lpErrno = WSAENOTSOCK; return SOCKET_ERROR; } /* Allocate the Async Data Structure to pass on to the Thread later */ AsyncData = HeapAlloc(GetProcessHeap(), 0, sizeof(*AsyncData)); if (!AsyncData) { MsafdReturnWithErrno( STATUS_INSUFFICIENT_RESOURCES, lpErrno, 0, NULL ); return INVALID_SOCKET; } /* Change the Socket to Non Blocking */ BlockMode = TRUE; SetSocketInformation(Socket, AFD_INFO_BLOCKING_MODE, &BlockMode, NULL, NULL); Socket->SharedData.NonBlocking = TRUE; /* Deactive WSPEventSelect */ if (Socket->SharedData.AsyncEvents) { if (WSPEventSelect(Handle, NULL, 0, lpErrno) == SOCKET_ERROR) { HeapFree(GetProcessHeap(), 0, AsyncData); return SOCKET_ERROR; } } /* Create the Asynch Thread if Needed */ SockCreateOrReferenceAsyncThread(); /* Open a Handle to AFD's Async Helper */ SockGetAsyncSelectHelperAfdHandle(); /* Store Socket Data */ Socket->SharedData.hWnd = hWnd; Socket->SharedData.wMsg = wMsg; Socket->SharedData.AsyncEvents = lEvent; Socket->SharedData.AsyncDisabledEvents = 0; Socket->SharedData.SequenceNumber++; /* Return if there are no more Events */ if ((Socket->SharedData.AsyncEvents & (~Socket->SharedData.AsyncDisabledEvents)) == 0) { HeapFree(GetProcessHeap(), 0, AsyncData); return 0; } /* Set up the Async Data */ AsyncData->ParentSocket = Socket; AsyncData->SequenceNumber = Socket->SharedData.SequenceNumber; /* Begin Async Select by using I/O Completion */ NtSetIoCompletion(SockAsyncCompletionPort, (PVOID)&SockProcessQueuedAsyncSelect, AsyncData, 0, 0); /* Return */ return ERROR_SUCCESS; }
INT SockCoreAccept ( IN PSOCKET_INFORMATION ListenSocket, IN PSOCKET_INFORMATION AcceptSocket ) { INT err; INT result; // // Indicate that the new socket is connected. // AcceptSocket->State = SocketStateConnected; // // Clone the properties of the listening socket to the new socket. // AcceptSocket->LingerInfo = ListenSocket->LingerInfo; AcceptSocket->ReceiveBufferSize = ListenSocket->ReceiveBufferSize; AcceptSocket->SendBufferSize = ListenSocket->SendBufferSize; AcceptSocket->Broadcast = ListenSocket->Broadcast; AcceptSocket->Debug = ListenSocket->Debug; AcceptSocket->OobInline = ListenSocket->OobInline; AcceptSocket->ReuseAddresses = ListenSocket->ReuseAddresses; AcceptSocket->SendTimeout = ListenSocket->SendTimeout; AcceptSocket->ReceiveTimeout = ListenSocket->ReceiveTimeout; // // Set up the new socket to have the same blocking, inline, and // timeout characteristics as the listening socket. // if ( ListenSocket->NonBlocking ) { err = SockSetInformation( AcceptSocket, AFD_NONBLOCKING_MODE, &ListenSocket->NonBlocking, NULL, NULL ); if ( err != NO_ERROR ) { return err; } } AcceptSocket->NonBlocking = ListenSocket->NonBlocking; if ( ListenSocket->OobInline ) { err = SockSetInformation( AcceptSocket, AFD_INLINE_MODE, &ListenSocket->OobInline, NULL, NULL ); if ( err != NO_ERROR ) { return err; } } AcceptSocket->OobInline = ListenSocket->OobInline; // // If the listening socket has been called with WSAAsyncSelect, // set up WSAAsyncSelect on this socket. Otherwise, if the socket // has been called with WSAEventSelect, set up WSAEventSelect on // the socket. // if ( ListenSocket->AsyncSelectlEvent ) { result = WSPAsyncSelect( AcceptSocket->Handle, ListenSocket->AsyncSelecthWnd, ListenSocket->AsyncSelectwMsg, ListenSocket->AsyncSelectlEvent, &err ); if ( result == SOCKET_ERROR ) { return err; } } else if ( ListenSocket->EventSelectlNetworkEvents ) { result = WSPEventSelect( AcceptSocket->Handle, ListenSocket->EventSelectEventObject, ListenSocket->EventSelectlNetworkEvents, &err ); if ( result == SOCKET_ERROR ) { return err; } } // // Clone the helper DLL's context from the listening socket to the // accepted socket. // err = SetHelperDllContext( ListenSocket, AcceptSocket ); if ( err != NO_ERROR ) { err = NO_ERROR; } // // If the application has modified the send or receive buffer sizes, // then set up the buffer sizes on the socket. // err = SockUpdateWindowSizes( AcceptSocket, FALSE ); if ( err != NO_ERROR ) { return err; } // // Remember the changed state of this socket. // err = SockSetHandleContext( AcceptSocket ); if ( err != NO_ERROR ) { return err; } return NO_ERROR; } // SockCoreAccept