예제 #1
0
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;
}
예제 #2
0
파일: accept.c 프로젝트: mingpen/OpenNT
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