Exemple #1
0
int WSAAPI
WSAEventSelect(
    IN SOCKET s,
    IN WSAEVENT hEventObject,
    IN long lNetworkEvents
    )
/*++
Routine Description:

    Specify an event object to be associated with the supplied set of
    FD_XXX network events.

Arguments:

    s - A descriptor identifying the socket.

    hEventObject - A handle identifying the event object to be
                   associated with the supplied set of FD_XXX network
                   events.

    lNetworkEvents - A bitmask which specifies the combination of
                     FD_XXX network events in which the application
                     has interest.

Returns:
    Zero on success else SOCKET_Error. The error code is stored with
    SetLastError().
--*/
{
    INT                ReturnValue;
    INT                ErrorCode;
    PDPROVIDER         Provider;
    PDSOCKET           Socket;

    ErrorCode = TURBO_PROLOG();

    if (ErrorCode == ERROR_SUCCESS) {
        Socket = DSOCKET::GetCountedDSocketFromSocket(s);
        if(Socket != NULL){
            Provider = Socket->GetDProvider();
            ReturnValue = Provider->WSPEventSelect(
                s,
                hEventObject,
                lNetworkEvents,
                &ErrorCode);
            Socket->DropDSocketReference();
            if (ReturnValue==ERROR_SUCCESS)
                return ReturnValue;
            assert (ErrorCode!=NO_ERROR);
            if (ErrorCode==NO_ERROR)
                ErrorCode = WSASYSCALLFAILURE;
        }
        else {
            ErrorCode = WSAENOTSOCK;
        }
    }

    SetLastError(ErrorCode);
    return SOCKET_ERROR;
} //WSAEventSelect
Exemple #2
0
int WSAAPI
bind(
    IN SOCKET s,
    IN const struct sockaddr FAR *name,
    IN int namelen
)
/*++
Routine Description:

    Associate a local address with a socket.

Arguments:

    s       - A descriptor identifying an unbound socket.

    name    - The address to assign to the socket.

    namelen - The length of the name.

Returns:

    Zero  on  success  else  SOCKET_ERROR.   The  error  code  is  stored  with
    SetLastError().

--*/
{
    INT                ReturnValue;
    PDPROVIDER         Provider;
    INT                ErrorCode;
    PDSOCKET           Socket;

    ErrorCode = TURBO_PROLOG();
    if (ErrorCode==ERROR_SUCCESS)
    {
        Socket = DSOCKET::GetCountedDSocketFromSocket(s);
        if(Socket != NULL) {
            Provider = Socket->GetDProvider();
            ReturnValue = Provider->WSPBind(s,
                                            name,
                                            namelen,
                                            &ErrorCode);
            Socket->DropDSocketReference();
            if (ReturnValue==ERROR_SUCCESS)
                return ReturnValue;
            assert (ErrorCode!=NO_ERROR);
            if (ErrorCode==NO_ERROR)
                ErrorCode = WSASYSCALLFAILURE;
        }
        else {
            ErrorCode = WSAENOTSOCK;
        }
    }

    SetLastError(ErrorCode);
    return SOCKET_ERROR;
}
Exemple #3
0
int WSAAPI
WSARecvDisconnect(
    IN SOCKET s,
    OUT LPWSABUF lpInboundDisconnectData
    )
/*++
Routine Description:

    Terminate  reception  on  a socket, and retrieve the disconnect data if the
    socket is connection-oriented.

Arguments:

    s                       - A descriptor identifying a socket.

    lpInboundDisconnectData - A pointer to the incoming disconnect data.

Returns:

    Zero on success else SOCKET_ERROR. The error code is stored with
    SetErrorCode().

--*/

{
    PDPROCESS           Process;
    PDTHREAD            Thread;
    INT                 ErrorCode;
    PDSOCKET            Socket;

    ErrorCode = PROLOG (&Process,&Thread);
    if (ErrorCode==ERROR_SUCCESS) {

        Socket = DSOCKET::GetCountedDSocketFromSocket(s);
        if(Socket != NULL){
            INT                 ReturnValue;
            PDPROVIDER          Provider;

            Provider = Socket->GetDProvider();
            ReturnValue = Provider->WSPRecvDisconnect(
                s,
                lpInboundDisconnectData,
                &ErrorCode);
            Socket->DropDSocketReference();
            if (ReturnValue==ERROR_SUCCESS)
                return ERROR_SUCCESS;
        }
        else {
            ErrorCode = WSAENOTSOCK;
        }
    }

    SetLastError(ErrorCode);
    return(SOCKET_ERROR);
}
Exemple #4
0
int WSAAPI
getsockname(
    IN SOCKET s,
    OUT struct sockaddr FAR *name,
    OUT int FAR * namelen
)
/*++
Routine Description:

    Get the local name for a socket.

Arguments:

    s       - A descriptor identifying a bound socket.

    name    - Receives the address (name) of the socket.

    namelen - The size of the name buffer.

Returns:

    Zero  on  success  else  SOCKET_ERROR.   The  error  code  is  stored  with
    SetLastError().

--*/
{
    INT                 ReturnValue;
    INT                 ErrorCode;
    PDPROVIDER          Provider;
    PDSOCKET            Socket;

    ErrorCode = TURBO_PROLOG();
    if (ErrorCode == ERROR_SUCCESS) {
        Socket = DSOCKET::GetCountedDSocketFromSocket(s);
        if(Socket != NULL) {
            Provider = Socket->GetDProvider();
            ReturnValue = Provider->WSPGetSockName(s,
                                                   name,
                                                   namelen,
                                                   &ErrorCode);
            Socket->DropDSocketReference();
            if (ReturnValue==ERROR_SUCCESS)
                return ReturnValue;
            assert (ErrorCode!=NO_ERROR);
            if (ErrorCode==NO_ERROR)
                ErrorCode = WSASYSCALLFAILURE;
        }
        else {
            ErrorCode = WSAENOTSOCK;
        }
    }

    SetLastError(ErrorCode);
    return SOCKET_ERROR;
}
INT
DWORKERTHREAD::QueueOverlappedTransmitFile(
    PDSOCKET                            Socket,
    HANDLE                              hFile,
    DWORD                               nNumberOfBytesToWrite,
    DWORD                               nNumberOfBytesPerSend,
    LPWSAOVERLAPPED                     UserOverlappedStruct,
    LPTRANSMIT_FILE_BUFFERS             lpTransmitBuffers,
    DWORD                               dwReserved,
    LPINT                               Errno
    )
{
    INT                       ReturnCode;
    PINTERNALOVERLAPPEDSTRUCT OverlappedStruct;

    ReturnCode = SOCKET_ERROR;
    *Errno = WSAENOBUFS;

    OverlappedStruct =
        gOverlappedManager->AllocateOverlappedStruct();
    if (OverlappedStruct){
        OverlappedStruct->iolOperationType = TRANSMIT_FILE;
        OverlappedStruct->iolSocket = Socket->GetSocketHandle ();
        OverlappedStruct->iolProvider = Socket->GetDProvider();
        OverlappedStruct->iolProviderSocket = Socket->GetProviderSocket ();
        OverlappedStruct->iolUserOverlappedStruct = UserOverlappedStruct;
        OverlappedStruct->iolUserCompletionRoutine = NULL;
        OverlappedStruct->iolFileHandle = hFile;
        OverlappedStruct->iolBytesToWrite = nNumberOfBytesToWrite;
        OverlappedStruct->iolBytesPerSend = nNumberOfBytesPerSend;
        if (lpTransmitBuffers)
            OverlappedStruct->iolTransmitBuffers = *lpTransmitBuffers;
        else
            OverlappedStruct->iolTransmitBuffers.HeadLength =
                OverlappedStruct->iolTransmitBuffers.TailLength = 0;

        OverlappedStruct->iolReserved = dwReserved;
        AddOverlappedOperation(
            Socket,
            OverlappedStruct);

        *Errno = WSA_IO_PENDING;
    } //if
    return(ReturnCode);
}
INT
DWORKERTHREAD::QueueOverlappedAcceptEx(
    PDSOCKET                           ListenSocket,
    PDSOCKET                           AcceptSocket,
    LPVOID                             lpOutputBuffer,
    DWORD                              dwReceiveDataLength,
    DWORD                              dwLocalAddressLength,
    DWORD                              dwRemoteAddressLength,
    LPWSAOVERLAPPED                    UserOverlappedStruct,
    LPINT                              Errno
    ) {
    INT                       ReturnCode;
    PINTERNALOVERLAPPEDSTRUCT OverlappedStruct;

    ReturnCode = SOCKET_ERROR;
    *Errno = WSAENOBUFS;

    OverlappedStruct =
        gOverlappedManager->AllocateOverlappedStruct();
    if (OverlappedStruct){
        OverlappedStruct->iolOperationType = ACCEPT_EX;
        OverlappedStruct->iolSocket = ListenSocket->GetSocketHandle ();
        OverlappedStruct->iolProvider = ListenSocket->GetDProvider();
        OverlappedStruct->iolListenSocket = ListenSocket->GetProviderSocket ();
        OverlappedStruct->iolAcceptSocket = AcceptSocket->GetProviderSocket ();
        OverlappedStruct->iolUserOverlappedStruct = UserOverlappedStruct;
        OverlappedStruct->iolUserCompletionRoutine = NULL;
        OverlappedStruct->iolOutputBuffer = lpOutputBuffer;
        OverlappedStruct->iolOutputBufferLength = dwReceiveDataLength;
        OverlappedStruct->iolLocalAddressLength = dwLocalAddressLength;
        OverlappedStruct->iolRemoteAddressLength = dwRemoteAddressLength;

        AddOverlappedOperation(
            ListenSocket,
            OverlappedStruct);

        *Errno = WSA_IO_PENDING;
    } //if
    return(ReturnCode);
}
Exemple #7
0
int WSAAPI
WSAAsyncSelect(
    IN SOCKET s,
    IN HWND hWnd,
    IN u_int wMsg,
    IN long lEvent
    )
/*++
Routine Description:

    Request event notification for a socket.

Arguments:

    s - A descriptor identifying the socket for which event notification is
        required.

    hWnd - A handle identifying the window which should receive a message when
           a network event occurs.

    wMsg - The message to be received when a network event occurs.

    lEvent - A bitmask which specifies a combination of network events in which
             the application is interested.

Returns:
    The return value is 0 if the application's declaration of interest in the
    network event set was successful.  Otherwise the value SOCKET_ERROR is
    returned, and a specific error number may be retrieved by calling
    WSAGetLastError().
--*/
{
    INT                ReturnValue;
    INT                ErrorCode;
    PDPROVIDER         Provider;
    PDSOCKET           Socket;

    ErrorCode = TURBO_PROLOG();

    if (ErrorCode == ERROR_SUCCESS) {
        Socket = DSOCKET::GetCountedDSocketFromSocket(s);
        if(Socket != NULL){
            Provider = Socket->GetDProvider();
            ReturnValue = Provider->WSPAsyncSelect(
                s,
                hWnd,
                wMsg,
                lEvent,
                &ErrorCode);
            Socket->DropDSocketReference();
            if (ReturnValue==ERROR_SUCCESS)
                return ReturnValue;
            assert (ErrorCode!=NO_ERROR);
            if (ErrorCode==NO_ERROR)
                ErrorCode = WSASYSCALLFAILURE;
        }
        else {
            ErrorCode = WSAENOTSOCK;
        }
    }

    SetLastError(ErrorCode);
    return SOCKET_ERROR;
} //WSAAsyncSelect
Exemple #8
0
int WSAAPI
WSANtohs (
    IN SOCKET s,
    IN u_short netshort,
    OUT u_short FAR * lphostshort
    )
/*++
Routine Description:


Arguments:

Returns:
    Zero on success else SOCKET_ERROR. The error code is stored with
    SetErrorCode().
--*/
{
    PDPROCESS           Process;
    PDTHREAD            Thread;
    PDSOCKET            Socket;
    INT                 ErrorCode;
    INT                 ReturnCode;
    PPROTO_CATALOG_ITEM CatalogEntry;
    LPWSAPROTOCOL_INFOW ProtocolInfo;

    ReturnCode = PROLOG(
        &Process,
        &Thread,
        &ErrorCode);
    if (ERROR_SUCCESS != ReturnCode) {
        SetLastError(ErrorCode);
        return(SOCKET_ERROR);
    } //if

    if( lphostshort == NULL ) {
        SetLastError( WSAEFAULT );
        return(SOCKET_ERROR);
    }

    ErrorCode = DSOCKET::GetCountedDSocketFromSocket(
        s,          // SocketHandle
        & Socket);  // DSocket
    if(ERROR_SUCCESS == ErrorCode){
        CatalogEntry = Socket->GetCatalogItem();
        // This  is  kind  of a special case.  We are done with the DSOCKET
        // object  reference  and  we don't call through to the provider at
        // all.
        Socket->DropDSocketReference();
        ProtocolInfo = CatalogEntry->GetProtocolInfo();

        if (LITTLEENDIAN == ProtocolInfo->iNetworkByteOrder) {
            *lphostshort = netshort;
        } //if
        else {
            *lphostshort = SWAP_SHORT( netshort );
        } //else
    } //if

    if (ErrorCode != ERROR_SUCCESS) {
        SetLastError(ErrorCode);
        ReturnCode = SOCKET_ERROR;
    }

    return(ReturnCode);
}
Exemple #9
0
int WSAAPI
WSANtohl (
    IN SOCKET s,
    IN u_long netlong,
    OUT u_long FAR * lphostlong
    )
/*++
Routine Description:

    Convert a u_long from network byte order to host byte order.

Arguments:
    s - A descriptor identifying a socket.

    netlong - A 32-bit number in network byte order.

    lphostlong - A pointer to a 32-bit number in host byte order.

Returns:
     If no error occurs, WSANtohs() returns 0. Otherwise, a value of
     SOCKET_ERROR is returned.
--*/
{
    PDPROCESS           Process;
    PDTHREAD            Thread;
    PDSOCKET            Socket;
    INT                 ErrorCode;
    INT                 ReturnCode;
    PPROTO_CATALOG_ITEM CatalogEntry;
    LPWSAPROTOCOL_INFOW ProtocolInfo;

    ReturnCode = PROLOG(
        &Process,
        &Thread,
        &ErrorCode);
    if (ERROR_SUCCESS != ReturnCode) {
        SetLastError(ErrorCode);
        return(SOCKET_ERROR);
    } //if

    if( lphostlong == NULL ) {
        SetLastError( WSAEFAULT );
        return(SOCKET_ERROR);
    }

    ErrorCode = DSOCKET::GetCountedDSocketFromSocket(
        s,          // SocketHandle
        & Socket);  // DSocket
    if(ERROR_SUCCESS == ErrorCode){
        CatalogEntry = Socket->GetCatalogItem();
        // This  is  kind  of a special case.  We are done with the DSOCKET
        // object  reference  and  we don't call through to the provider at
        // all.
        Socket->DropDSocketReference();
        ProtocolInfo = CatalogEntry->GetProtocolInfo();

        if (LITTLEENDIAN == ProtocolInfo->iNetworkByteOrder) {
            *lphostlong = netlong;
        } //if
        else {
            *lphostlong = SWAP_LONG( netlong );
        } //else
    } //if

    if (ErrorCode != ERROR_SUCCESS) {
        SetLastError(ErrorCode);
        ReturnCode = SOCKET_ERROR;
    }

    return(ReturnCode);
}
Exemple #10
0
int WSAAPI
getsockopt(
    IN SOCKET s,
    IN int level,
    IN int optname,
    OUT char FAR * optval,
    IN OUT int FAR *optlen
)
/*++
Routine Description:

    Retrieve a socket option.

Arguments:

    s       - A descriptor identifying a socket.

    level   - The  level  at  which the option is defined; the supported levels
              include   SOL_SOCKET   and  IPPROTO_TCP.   (See  annex  for  more
              protocol-specific levels.)

    optname - The socket option for which the value is to be retrieved.

    optval  - A  pointer  to  the  buffer  in which the value for the requested
              option is to be returned.

    optlen  - A pointer to the size of the optval buffer.

Returns:

    Zero  on  success  else  SOCKET_ERROR.   The  error  code  is  stored  with
    SetLastError().

--*/
{
    INT                 ReturnValue;
    PDPROCESS           Process;
    PDTHREAD            Thread;
    INT                 ErrorCode;
    PDPROVIDER          Provider;
    PDSOCKET            Socket;
    WSAPROTOCOL_INFOW   ProtocolInfoW;
    char FAR *          SavedOptionValue = NULL;
    int                 SavedOptionLen = 0;

    ErrorCode = PROLOG(&Process, &Thread);
    if (ErrorCode==ERROR_SUCCESS) {
        //
        // SO_OPENTYPE hack-o-rama.
        //

        if( level == SOL_SOCKET && optname == SO_OPENTYPE ) {
            __try {
                if( optlen == NULL || *optlen < sizeof(INT) ) {
                    SetLastError( WSAEFAULT );
                    return SOCKET_ERROR;
                }

                *((LPINT)optval) = Thread->GetOpenType();
                *optlen = sizeof(INT);
                return ERROR_SUCCESS;
            }
            __except (WS2_EXCEPTION_FILTER()) {
                SetLastError (WSAEFAULT);
                return SOCKET_ERROR;
            }
        }

        Socket = DSOCKET::GetCountedDSocketFromSocket(s);
        if(Socket != NULL) {
            Provider = Socket->GetDProvider();

            //
            // If we managed to lookup the provider from the socket, and the
            // user is asking for the ANSI WSAPROTOCOL_INFOA information,
            // then validate their option length parameter, remember this fact,
            // and map the option name to SO_PROTOCOL_INFOW.
            //

            if( level == SOL_SOCKET &&
                    optname == SO_PROTOCOL_INFOA ) {

                __try {
                    if( optval == NULL ||
                            optlen == NULL ||
                            *optlen < sizeof(WSAPROTOCOL_INFOA) ) {

                        * optlen = sizeof(WSAPROTOCOL_INFOA);
                        Socket->DropDSocketReference();
                        SetLastError (WSAEFAULT);
                        return (SOCKET_ERROR);
                    }


                    SavedOptionLen = *optlen;
                    *optlen = sizeof(WSAPROTOCOL_INFOW);
                    SavedOptionValue = optval;
                    optval = (char FAR *)&ProtocolInfoW;
                    optname = SO_PROTOCOL_INFOW;
                }
                __except (WS2_EXCEPTION_FILTER()) {
                    ErrorCode = WSAEFAULT;
                    Socket->DropDSocketReference();
                    goto ErrorExit;
                }
            }
Exemple #11
0
int WSAAPI
connect(
    IN SOCKET s,
    IN const struct sockaddr FAR *name,
    IN int namelen
)
/*++
Routine Description:

    Establish a connection to a peer.

Arguments:

    s       - A descriptor identifying an unconnected socket.

    name    - The name of the peer to which the socket is to be connected.

    namelen - The length of the name.

Returns:

    Zero  on  success  else  SOCKET_ERROR.   The  error  code  is  stored  with
    SetLastError().

--*/
{

    INT                ReturnValue;
    PDPROCESS          Process;
    PDTHREAD           Thread;
    PDPROVIDER         Provider;
    INT                ErrorCode;
    PDSOCKET           Socket;
    BOOL               RetryConnect;
    INT				   SavedErrorCode;


    ErrorCode = PROLOG(&Process, &Thread);
    if (ErrorCode==ERROR_SUCCESS)
    {
        Socket = DSOCKET::GetCountedDSocketFromSocket(s);
        if(Socket != NULL) {
            Provider = Socket->GetDProvider();
#ifdef RASAUTODIAL
            RetryConnect = FALSE;
retry:
#endif // RASAUTODIAL
            ReturnValue = Provider->WSPConnect(s,
                                               name,
                                               namelen,
                                               NULL,
                                               NULL,
                                               NULL,
                                               NULL,
                                               &ErrorCode);
#ifdef RASAUTODIAL
            if (ReturnValue == SOCKET_ERROR &&
                    (ErrorCode == WSAEHOSTUNREACH || ErrorCode == WSAENETUNREACH))
            {
                if (!RetryConnect) {
                    //
                    // We preserve the original error
                    // so we can return it in case the
                    // second call to WSPConnect() fails
                    // also.
                    //
                    SavedErrorCode = ErrorCode;
                    //
                    // Only one retry per connect attempt.
                    //
                    RetryConnect = TRUE;
                    if (WSAttemptAutodialAddr(name, namelen))
                        goto retry;
                }
                else
                    ErrorCode = SavedErrorCode;
            }
#endif // RASAUTODIAL
            Socket->DropDSocketReference();
            if (ReturnValue==ERROR_SUCCESS)
                return ReturnValue;
            assert (ErrorCode!=NO_ERROR);
            if (ErrorCode==NO_ERROR)
                ErrorCode = WSASYSCALLFAILURE;
        }
        else {
            ErrorCode = WSAENOTSOCK;
        }
    }

    //
    // If this is a 1.x application and the service provider
    // failed the request with WSAEALREADY, map the error code
    // to WSAEINVAL to be consistent with MS's WinSock 1.1
    // implementations.
    //

    if( ErrorCode == WSAEALREADY &&
            Process->GetMajorVersion() == 1 ) {
        ErrorCode = WSAEINVAL;
    }

    SetLastError(ErrorCode);
    return SOCKET_ERROR;
}
INT
DWORKERTHREAD::QueueOverlappedSend(
    PDSOCKET                           Socket,
    LPWSABUF                           UserBuffers,
    DWORD                              UserBufferCount,
    LPDWORD                            UserBytesSent,
    DWORD                              UserFlags,
    LPWSAOVERLAPPED                    UserOverlappedStruct,
    LPWSAOVERLAPPED_COMPLETION_ROUTINE UserCompletionRoutine,
    LPWSATHREADID                      UserThreadId,
    LPINT           Errno
    )
/*++

Routine Description:

    this routine allocates an internal overlapped structure stores its
    arguments in the allocated structure and enqueues the structure for the
    worker thread to complet the I/O operation.

Arguments:

    Socket      - Socket object

    UserBuffers - The pointer to the user buffer(s).

    UserBufferCount - The number of user buffers.

    UserBytesSent - The pointer to the user BytesSent parameter.

    UserFlags - The user flags .

    UserOverlappedStruct - The user overlapped struct pointer.

    UserCompletionRoutine - The user overlapped completion routine.

    UserThreadId - The user thread ID.

    InternalBuffers - A pointer to our internal buffer(s).

    InternalBufferCount - The number of internal buffers.

    Errno - A pointer to the user errno parameter.

Return Value:

    NO_ERROR on success else a valid winsock2 error code.

--*/
{
    INT                       ReturnCode;
    PINTERNALOVERLAPPEDSTRUCT OverlappedStruct;

    ReturnCode = SOCKET_ERROR;
    *Errno = WSAENOBUFS;

    OverlappedStruct =
        gOverlappedManager->AllocateOverlappedStruct();
    if (OverlappedStruct){
        OverlappedStruct->iolOperationType = WSP_SEND;
        OverlappedStruct->iolSocket = Socket->GetSocketHandle ();
        OverlappedStruct->iolProvider = Socket->GetDProvider();
        OverlappedStruct->iolProviderSocket = Socket->GetProviderSocket ();
        OverlappedStruct->iolUserOverlappedStruct = UserOverlappedStruct;
        OverlappedStruct->iolUserCompletionRoutine = UserCompletionRoutine;
        OverlappedStruct->iolUserThreadId = *UserThreadId;
        if (UserBufferCount<=MAX_FAST_BUFS)
            memcpy (OverlappedStruct->iolUserBuffers, UserBuffers,
                        sizeof (WSABUF)*UserBufferCount);
        else {
            OverlappedStruct->iolpUserBuffers = new WSABUF[UserBufferCount];
            if (OverlappedStruct->iolpUserBuffers==NULL) {
                gOverlappedManager->FreeOverlappedStruct (
                        &OverlappedStruct->iolInternalOverlappedStruct);
                return ReturnCode;
            }
            memcpy (OverlappedStruct->iolpUserBuffers, UserBuffers,
                        sizeof (WSABUF)*UserBufferCount);
        }
        OverlappedStruct->iolUserBufferCount = UserBufferCount;
        OverlappedStruct->iolFlags = UserFlags;

        AddOverlappedOperation(
            Socket,
            OverlappedStruct);

        *Errno = WSA_IO_PENDING;

    } //if
    return(ReturnCode);
}
INT
DWORKERTHREAD::QueueOverlappedIoctl(
    PDSOCKET                           Socket,
    DWORD                              dwIoControlCode,
    LPVOID                             lpvInBuffer,
    DWORD                              cbInBuffer,
    LPVOID                             lpvOutBuffer,
    DWORD                              cbOutBuffer,
    LPDWORD                            lpcbBytesReturned,
    LPWSAOVERLAPPED                    UserOverlappedStruct,
    LPWSAOVERLAPPED_COMPLETION_ROUTINE UserCompletionRoutine,
    LPWSATHREADID                      UserThreadId,
    LPINT                              Errno
    )
/*++

Routine Description:

    this routine allocates an internal overlapped structure stores its
    arguments in the allocated structure and enqueues the structure for the
    worker thread to complet the I/O operation.

Arguments:

    Socket      - Socket object

    UserBuffers - The pointer to the user buffer(s).

    UserBufferCount - The number of user buffers.

    UserBytesRecvd - The pointer to the user BytesRecvd parameter.

    UserFlags - A pointer to the user flags argument.

    UserTo - A pointer to the user sockaddr structure.

    UserToLen - The length of the user sockaddr structure.

    UserOverlappedStruct - The user overlapped struct pointer.

    UserCompletionRoutine - The user overlapped completion routine.

    UserThreadId - The user thread ID.

    InternalBuffers - A pointer to our internal buffer(s).

    InternalBufferCount - The number of internal buffers.

    Errno - A pointer to the user errno parameter.

Return Value:

    NO_ERROR on success else a valid winsock2 error code.

--*/
{
    INT                       ReturnCode;
    PINTERNALOVERLAPPEDSTRUCT OverlappedStruct;

    ReturnCode = SOCKET_ERROR;
    *Errno = WSAENOBUFS;

    OverlappedStruct =
        gOverlappedManager->AllocateOverlappedStruct();
    if (OverlappedStruct){
        OverlappedStruct->iolOperationType = WSP_IOCTL;
        OverlappedStruct->iolSocket = Socket->GetSocketHandle ();
        OverlappedStruct->iolProvider = Socket->GetDProvider();
        OverlappedStruct->iolProviderSocket = Socket->GetProviderSocket ();
        OverlappedStruct->iolUserOverlappedStruct = UserOverlappedStruct;
        OverlappedStruct->iolUserCompletionRoutine = UserCompletionRoutine;
        OverlappedStruct->iolUserThreadId = *UserThreadId;
        OverlappedStruct->iolInputBuffer = lpvInBuffer;
        OverlappedStruct->iolInputBufferLength = cbInBuffer;
        OverlappedStruct->iolOutputBuffer = lpvOutBuffer;
        OverlappedStruct->iolOutputBufferLength = cbOutBuffer;
        OverlappedStruct->iolIoControlCode = dwIoControlCode;

        AddOverlappedOperation(
            Socket,
            OverlappedStruct);

        *Errno = WSA_IO_PENDING;
    } //if
    return(ReturnCode);
}
Exemple #14
0
int WSAAPI
recv(
     IN SOCKET s,
     OUT char FAR * buf,
     IN int len,
     IN int flags
     )
/*++
Routine Description:

    Receive data from a socket.

Arguments:

    s     - A descriptor identifying a connected socket.

    buf   - A buffer for the incoming data.

    len   - The length of buf.

    flags - Specifies the way in which the call is made.

Returns:

    The  number  of  bytes  received.   If  the  connection has been gracefully
    closed,  the  return  value  is  0.   Otherwise, a value of SOCKET_ERROR is
    returned, and a specific error code is stored with SetErrorCode().

--*/

{
    INT             ErrorCode;
    PDSOCKET        Socket;
    LPWSATHREADID   ThreadId;


	ErrorCode = TURBO_PROLOG_OVLP(&ThreadId);
    if (ErrorCode==ERROR_SUCCESS)
    {
        Socket = DSOCKET::GetCountedDSocketFromSocket(s);
        if(Socket != NULL){
            INT             ReturnValue;
            PDPROVIDER      Provider;
            DWORD           BytesReceived;
            WSABUF          Buffers;

            Buffers.len = len;
            Buffers.buf = buf;

            Provider = Socket->GetDProvider();
            ReturnValue = Provider->WSPRecv(s,
                              &Buffers,
                              1,
                              &BytesReceived,
                              (LPDWORD)&flags,
                              NULL,                 // lpOverlapped
                              NULL,                 // lpCompletionRoutine
                              ThreadId,
                              &ErrorCode);
            Socket->DropDSocketReference();
            if (ReturnValue==ERROR_SUCCESS) {
                if ((flags & MSG_PARTIAL)==0) {
                    return (INT)BytesReceived;
                }
                ErrorCode = WSAEMSGSIZE;
            }

            assert (ErrorCode!=NO_ERROR);
            if (ErrorCode==NO_ERROR)
                ErrorCode = WSASYSCALLFAILURE;

        }
        else {
            ErrorCode = WSAENOTSOCK;
        }
    }

    SetLastError(ErrorCode);
    return SOCKET_ERROR;
}
Exemple #15
0
int WSAAPI
WSARecvFrom(
    IN SOCKET s,
    OUT LPWSABUF lpBuffers,
    IN DWORD dwBufferCount,
    OUT LPDWORD lpNumberOfBytesRecvd,
    IN OUT LPDWORD lpFlags,
    OUT struct sockaddr FAR *  lpFrom,
    IN OUT LPINT lpFromlen,
    IN LPWSAOVERLAPPED lpOverlapped,
    IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
    )
/*++
Routine Description:

    Receive a datagram and store the source address.

Arguments:

    s                    - A descriptor identifying a socket

    lpBuffers            - A  pointer  to  an array of WSABUF structures.  Each
                           WSABUF  structure contains a pointer to a buffer and
                           the length of the buffer.

    dwBufferCount        - The  number  of  WSABUF  structures in the lpBuffers
                           array.

    lpNumberOfBytesRecvd - A  pointer  to  the number of bytes received by this
                           call if the receive operation completes immediately.

    lpFlags              - A pointer to flags.

    lpFrom               - An  optional pointer to a buffer which will hold the
                           source address upon the completion of the overlapped
                           operation.

    lpFromlen            - A  pointer  to the size of the from buffer, required
                           only if lpFrom is specified.

    lpOverlapped         - A  pointer to a WSAOVERLAPPED structure (ignored for
                           non- overlapped sockets).

    lpCompletionRoutine  - A  pointer to the completion routine called when the
                           receive  operation  has  been completed (ignored for
                           non-overlapped sockets).

Returns:

    Zero  on  success  else  SOCKET_ERROR.   The  error  code  is  stored  with
    SetErrorCode().

--*/

{
    INT                ErrorCode;
    PDSOCKET           Socket;
    LPWSATHREADID      ThreadId;

	ErrorCode = TURBO_PROLOG_OVLP(&ThreadId);
    if (ErrorCode==ERROR_SUCCESS)
    {

        Socket = DSOCKET::GetCountedDSocketFromSocket(s);
        if(Socket != NULL){
            INT             ReturnValue;
            PDPROVIDER      Provider;

            Provider = Socket->GetDProvider();
            ReturnValue = Provider->WSPRecvFrom(s,
                                  lpBuffers,
                                  dwBufferCount,
                                  lpNumberOfBytesRecvd,
                                  lpFlags,
                                  lpFrom,
                                  lpFromlen,
                                  lpOverlapped,
                                  lpCompletionRoutine,
                                  ThreadId,
                                  &ErrorCode);
            Socket->DropDSocketReference();
            if (ReturnValue==ERROR_SUCCESS)
                return ReturnValue;
            assert (ErrorCode!=NO_ERROR);
            if (ErrorCode==NO_ERROR)
                ErrorCode = WSASYSCALLFAILURE;
        }
        else {
            ErrorCode = WSAENOTSOCK;
        }
    }

    SetLastError(ErrorCode);
    return SOCKET_ERROR;
}
Exemple #16
0
int WSAAPI
select (
    IN int nfds,
    IN OUT fd_set FAR *readfds,
    IN OUT fd_set FAR *writefds,
    IN OUT fd_set FAR *exceptfds,
    IN const struct timeval FAR *timeout
    )
/*++
Routine Description:

    Determine the status of one or more sockets, waiting if necessary.

Arguments:

    nfds - This argument is ignored and included only for the sake of
           compatibility.

    readfds - An optional pointer to a set of sockets to be checked
              for readability.

    writefds - An optional pointer to a set of sockets to be checked
               for writability.

    exceptfds - An optional pointer to a set of sockets to be checked
                for errors.

    timeout - The maximum time for select() to wait, or NULL for
              blocking operation.

Returns:
    select() returns the total number of descriptors which are ready
    and contained in the fd_set structures, 0 if the time limit
    expired, or SOCKET_ERROR if an error occurred.  If the return
    value is SOCKET_ERROR, The error code is stored with
    SetLastError().
--*/
{
    INT                ReturnValue;
    INT                ErrorCode;
    PDPROVIDER         Provider;
    PDSOCKET           Socket;
    SOCKET             SocketID;
    BOOL               FoundSocket=FALSE;

    ErrorCode = TURBO_PROLOG();

    if (ErrorCode == ERROR_SUCCESS) {

        __try {
            // Look for a socket in the three fd_sets handed in. The first
            // socket found will be used to select the service provider to
            // service this call
            if (readfds && readfds->fd_count)
                {
                SocketID = readfds->fd_array[0];
                FoundSocket = TRUE;
                } //if

            if (!FoundSocket && writefds && writefds->fd_count )
                {
                SocketID = writefds->fd_array[0];
                FoundSocket = TRUE;
                } //if

            if (!FoundSocket && exceptfds && exceptfds->fd_count )
                {
                SocketID = exceptfds->fd_array[0];
                FoundSocket = TRUE;
                } //if
        }
        __except (WS2_EXCEPTION_FILTER()) {
            ErrorCode = WSAEFAULT;
            goto ReturnError;
        }

        if (FoundSocket) {
            Socket = DSOCKET::GetCountedDSocketFromSocket(SocketID);
            if(Socket != NULL){
                Provider = Socket->GetDProvider();
                ReturnValue = Provider->WSPSelect(
                    nfds,
                    readfds,
                    writefds,
                    exceptfds,
                    timeout,
                    &ErrorCode);
                Socket->DropDSocketReference();
                if (ReturnValue!=SOCKET_ERROR)
                    return ReturnValue;

                assert (ErrorCode!=NO_ERROR);
                if (ErrorCode==NO_ERROR)
                    ErrorCode = WSASYSCALLFAILURE;

            } //if
            else {
                ErrorCode = WSAENOTSOCK;
            }
        } //if
        else {
            ErrorCode = WSAEINVAL;
        } //else
    }
Exemple #17
0
int WSAAPI
WSAHtonl (
    IN SOCKET s,
    IN u_long hostlong,
    OUT u_long FAR * lpnetlong
    )
/*++
Routine Description:

    Convert a u_long from a specified host byte order to network byte
    order.

Arguments:

    s - A descriptor identifying a socket.

    hostlong - A 32-bit number in host byte order.

    lpnetlong - A pointer to a 32-bit number in network byte order.


Returns:
    If no error occurs, WSAHtonl() returns 0. Otherwise, a value of
    SOCKET_ERROR is returned.

--*/
{
    PDSOCKET            Socket;
    INT                 ErrorCode;
    PPROTO_CATALOG_ITEM CatalogEntry;
    LPWSAPROTOCOL_INFOW ProtocolInfo;

    ErrorCode = TURBO_PROLOG();
    if (ErrorCode==ERROR_SUCCESS) {

		if( lpnetlong == NULL ) {
			SetLastError( WSAEFAULT );
			return(SOCKET_ERROR);
		}

		Socket = DSOCKET::GetCountedDSocketFromSocket(s);
		if(Socket != NULL){
			CatalogEntry = Socket->GetCatalogItem();
			ProtocolInfo = CatalogEntry->GetProtocolInfo();

            __try {
			    if (LITTLEENDIAN == ProtocolInfo->iNetworkByteOrder) {
				    *lpnetlong = hostlong;
			    } //if
			    else {
				    *lpnetlong = SWAP_LONG( hostlong );
			    } //else
                ErrorCode = ERROR_SUCCESS;
            }
            __except (WS2_EXCEPTION_FILTER()) {
                ErrorCode = WSAEFAULT;
            }

			Socket->DropDSocketReference();
            if (ErrorCode==ERROR_SUCCESS)
                return ErrorCode;
		} //if
		else
Exemple #18
0
int WSAAPI
WSARecv(
    IN SOCKET s,
    OUT LPWSABUF lpBuffers,
    IN DWORD dwBufferCount,
    OUT LPDWORD lpNumberOfBytesRecvd,
    IN OUT LPDWORD lpFlags,
    IN LPWSAOVERLAPPED lpOverlapped,
    IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
    )
/*++
Routine Description:

    Receive data from a socket.

Arguments:

    s                    - A descriptor identifying a connected socket.

    lpBuffers            - A  pointer  to  an array of WSABUF structures.  Each
                           WSABUF  structure contains a pointer to a buffer and
                           the length of the buffer.

    dwBufferCount        - The  number  of  WSABUF  structures in the lpBuffers
                           array.

    lpNumberOfBytesRecvd - A  pointer  to  the number of bytes received by this
                           call if the receive operation completes immediately.

    lpFlags              - A pointer to flags.

    lpOverlapped         - A  pointer to a WSAOVERLAPPED structure (ignored for
                           non-overlapped sockets).

    lpCompletionRoutine  - A  pointer to the completion routine called when the
                           receive  operation  has  been completed (ignored for
                           non-overlapped sockets).

Returns:

    If  no  error  occurs  and the receive operation has completed immediately,
    WSARecv() returns the number of bytes received.  If the connection has been
    closed,  it returns 0.  Otherwise, a value of SOCKET_ERROR is returned, and
    the  specific  error  code  is  stored with SetErrorCode().  The error code
    WSA_IO_PENDING   indicates   that   the   overlapped   operation  has  been
    successfully  initiated  and  that  completion will be indicated at a later
    time.  Any other error code indicates that the overlapped operation was not
    successfully initiated and no completion indication will occur.

    If  the  MSG_INTERRUPT  flag  is  set,  the  meaning of the return value is
    changed.  A value of zero indicates success and is interpreted as described
    above.   Otherwise,  the return value will directly contain the appropriate
    error  code  as  shown  below.   Note that this is applicable only to Win16
    environments  and only for protocols that have the XP1_INTERRUPT bit set in
    the WSAPROTOCOL_INFO struct.

--*/
{
    INT                 ErrorCode;
    PDSOCKET            Socket;
    LPWSATHREADID       ThreadId;

	ErrorCode = TURBO_PROLOG_OVLP(&ThreadId);
    if (ErrorCode==ERROR_SUCCESS)
    {
        Socket = DSOCKET::GetCountedDSocketFromSocket(s);
        if(Socket != NULL){
            INT                 ReturnValue;
            PDPROVIDER          Provider;

            Provider = Socket->GetDProvider();
            ReturnValue = Provider->WSPRecv(s,
                              lpBuffers,
                              dwBufferCount,
                              lpNumberOfBytesRecvd,
                              lpFlags,
                              lpOverlapped,
                              lpCompletionRoutine,
                              ThreadId,
                              &ErrorCode);
            Socket->DropDSocketReference();
            if (ReturnValue==ERROR_SUCCESS)
                return ReturnValue;
            assert (ErrorCode!=NO_ERROR);
            if (ErrorCode==NO_ERROR)
                ErrorCode = WSASYSCALLFAILURE;

        }
        else {
            ErrorCode = WSAENOTSOCK;
        }
    }

    SetLastError(ErrorCode);
    return SOCKET_ERROR;
}