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; }
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(); } }