std::size_t Win32NamedPipeClientTransport::implWrite(
        const std::vector<ByteBuffer> &byteBuffers)
    {
        // For now, can't go back to sync calls after doing an async call.
        // Limitations with Windows IOCP.
        RCF_ASSERT(!mAsyncMode);

        // Not using overlapped I/O here because it interferes with the
        // server session that might be coupled to this transport.

        const ByteBuffer & byteBuffer = byteBuffers.front();

        DWORD count = 0;
        DWORD dwBytesToWrite = static_cast<DWORD>(byteBuffer.getLength());

        BOOL ok = WriteFile( 
            mhPipe,
            byteBuffer.getPtr(),
            dwBytesToWrite,
            &count,
            NULL);

        DWORD dwErr = GetLastError();

        RCF_VERIFY(ok, Exception(_RcfError_ClientWriteFail(), dwErr));

        // Strangely, WriteFile() sometimes returns 1, but at the same time a much too big value in count.
        RCF_VERIFY(count <= dwBytesToWrite, Exception(_RcfError_ClientWriteFail(), dwErr))(count)(dwBytesToWrite);

        RCF_VERIFY(count > 0, Exception(_RcfError_ClientWriteFail(), dwErr))(count)(dwBytesToWrite);

        onTimedSendCompleted( RCF_MIN(count, dwBytesToWrite), 0);

        return count;
    }
Ejemplo n.º 2
0
    void OverlappedAmi::onCompletion(
        std::size_t index,
        const AsioErrorCode & ec, 
        std::size_t bytesTransferred)
    {
        RecursiveLock lock(mMutex);

        if (mIndex == index && mpTransport)
        {
            ++mIndex;

            if (mpTransport->mAsioTimerPtr)
            {
                mpTransport->mAsioTimerPtr->cancel();
            }

#ifdef BOOST_WINDOWS
            // Do we need to impersonate?
            boost::scoped_ptr<Win32ThreadImpersonator> impersonator;
            HANDLE hImpersonationToken = static_cast<ClientStub *>(mpTransport->mpClientStub)
                ->getWindowsImpersonationToken();
            if (hImpersonationToken != INVALID_HANDLE_VALUE)
            {
                impersonator.reset( new Win32ThreadImpersonator(hImpersonationToken) );
            }
#endif

            if (ec)
            {
                try
                {
                    RCF::Exception e;

                    switch (mOpType)
                    {
                    case Wait:
                        RCF_ASSERT(0);
                        break;

                    case Connect:
                        e = RCF::Exception( _RcfError_ClientConnectFail(), ec.value());
                        break;

                    case Write:
                        e = RCF::Exception( _RcfError_ClientWriteFail(), ec.value());
                        break;

                    case Read:
                        e = RCF::Exception( _RcfError_ClientReadFail(), ec.value());
                        break;

                    default:
                        RCF_ASSERT(0);
                    };

                    mOpType = None;

                    mpTransport->mpClientStub->onError(e);
                }
                catch(const std::exception &e)
                {
                    mpTransport->mpClientStub->onError(e);
                }
                catch(...)
                {
                    RCF::Exception e( _RcfError_NonStdException() );
                    mpTransport->mpClientStub->onError(e);
                }
            }
            else
            {
                mOpType = None;

                try
                {
                    mpTransport->onCompletion( static_cast<int>(bytesTransferred) );
                }
                catch(const std::exception &e)
                {
                    mpTransport->mpClientStub->onError(e);
                }
                catch(...)
                {
                    RCF::Exception e( _RcfError_NonStdException() );
                    mpTransport->mpClientStub->onError(e);
                }
            }

            getTlsAmiNotification().run();
        }

    }