462 lines
9.5 KiB
C++
462 lines
9.5 KiB
C++
//+-------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1992 - 1993.
|
|
//
|
|
// File: CPKT.CXX
|
|
//
|
|
// Contents: CPkt implementation for RPC/LRPC
|
|
//
|
|
// Functions:
|
|
//
|
|
// History: 30-Mar-94 BobDay Adapted from 16-bit OLE2.0, CPKT.CPP
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
#include <headers.cxx>
|
|
#pragma hdrstop
|
|
|
|
#include <ole2ver.h>
|
|
|
|
#include <ole2sp.h>
|
|
#include "rpc16.hxx"
|
|
#include "comlocal.hxx"
|
|
|
|
//
|
|
// Standard IUnknown method. Not used but need to be supported to comply
|
|
// with the IUnknown.
|
|
//
|
|
|
|
STDMETHODIMP CPkt::QueryInterface(
|
|
REFIID iidInterface,
|
|
void FAR* FAR* ppvObj )
|
|
{
|
|
HRESULT hresult;
|
|
|
|
// Three interfaces supported (each, and extension of the previous):
|
|
// IUnknown, IStream, ICPkt
|
|
|
|
if ( (iidInterface == IID_CPkt ||
|
|
iidInterface == IID_IStream ||
|
|
iidInterface == IID_IUnknown )) {
|
|
|
|
m_refs++; // A pointer to this object is returned
|
|
*ppvObj = this;
|
|
hresult = NOERROR;
|
|
}
|
|
else { // Not accessible or unsupported interface
|
|
*ppvObj = NULL;
|
|
hresult = ResultFromScode(E_NOINTERFACE);
|
|
}
|
|
|
|
return hresult;
|
|
}
|
|
|
|
//
|
|
// Called when CPkt is referenced by an additional pointer.
|
|
//
|
|
|
|
STDMETHODIMP_(ULONG) CPkt::AddRef(void)
|
|
{
|
|
return ++m_refs;
|
|
}
|
|
|
|
//
|
|
// Called when a pointer to this CPkt is discarded
|
|
//
|
|
|
|
STDMETHODIMP_(ULONG) CPkt::Release(void)
|
|
{
|
|
if (--m_refs != 0) // Still used by others
|
|
return m_refs;
|
|
|
|
if (m_rom16.Buffer != NULL)
|
|
{
|
|
TaskFree(m_rom16.Buffer);
|
|
}
|
|
|
|
delete this; // Free storage
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
STDMETHODIMP CPkt::Read(void HUGEP* pb, ULONG cb, ULONG FAR* pcbRead)
|
|
{
|
|
HRESULT hresult = NOERROR;
|
|
ULONG cbRead = cb;
|
|
|
|
|
|
if (pcbRead != NULL)
|
|
{
|
|
*pcbRead = 0;
|
|
}
|
|
|
|
if (cbRead + m_pos > m_rom16.cbBuffer) {
|
|
if (m_pos < m_rom16.cbBuffer)
|
|
{
|
|
cbRead = m_rom16.cbBuffer - m_pos;
|
|
}
|
|
else
|
|
{
|
|
cbRead = 0;
|
|
}
|
|
hresult = ResultFromScode(E_UNSPEC); // PKT (tried to read passed EOS)
|
|
}
|
|
|
|
if ( cbRead != 0 )
|
|
{
|
|
hmemcpy(pb,(LPSTR)m_rom16.Buffer + m_pos, cbRead);
|
|
m_pos += cbRead;
|
|
}
|
|
|
|
if (pcbRead != NULL)
|
|
{
|
|
*pcbRead = cbRead;
|
|
}
|
|
|
|
return hresult;
|
|
}
|
|
|
|
|
|
STDMETHODIMP CPkt::Write(void const HUGEP* pb, ULONG cb, ULONG FAR* pcbWritten)
|
|
{
|
|
HRESULT hresult = NOERROR;
|
|
ULONG cbWritten = cb;
|
|
|
|
|
|
if (pcbWritten != NULL)
|
|
{
|
|
*pcbWritten = 0;
|
|
}
|
|
|
|
if (cbWritten + m_pos > m_rom16.cbBuffer)
|
|
{
|
|
ULARGE_INTEGER ularge_integer;
|
|
|
|
ULISet32(ularge_integer,m_pos+cbWritten);
|
|
|
|
hresult = SetSize(ularge_integer);
|
|
if (hresult != NOERROR)
|
|
{
|
|
return hresult;
|
|
}
|
|
}
|
|
|
|
if ( cbWritten != 0 )
|
|
{
|
|
hmemcpy((LPSTR)m_rom16.Buffer + m_pos,pb, cbWritten);
|
|
m_pos += cbWritten;
|
|
}
|
|
|
|
if (pcbWritten != NULL)
|
|
{
|
|
*pcbWritten = cbWritten;
|
|
}
|
|
|
|
return hresult;
|
|
}
|
|
|
|
STDMETHODIMP CPkt::Seek(LARGE_INTEGER dlibMoveIn, DWORD dwOrigin, ULARGE_INTEGER FAR* plibNewPosition)
|
|
{
|
|
HRESULT hresult = NOERROR;
|
|
LONG dlibMove = dlibMoveIn.LowPart;
|
|
ULONG cbNewPos = dlibMove;
|
|
|
|
|
|
if (plibNewPosition != NULL)
|
|
{
|
|
ULISet32(*plibNewPosition, m_pos);
|
|
}
|
|
|
|
switch(dwOrigin)
|
|
{
|
|
case STREAM_SEEK_SET:
|
|
if (dlibMove >= 0)
|
|
{
|
|
m_pos = dlibMove;
|
|
}
|
|
else
|
|
{
|
|
hresult = ResultFromScode(E_UNSPEC); // PKT (Invalid seek)
|
|
}
|
|
break;
|
|
|
|
case STREAM_SEEK_CUR:
|
|
if (!(dlibMove < 0 && ((ULONG) -dlibMove) > m_pos))
|
|
{
|
|
m_pos += dlibMove;
|
|
}
|
|
else
|
|
{
|
|
hresult = ResultFromScode(E_UNSPEC); // PKT (Invalid seek)
|
|
}
|
|
break;
|
|
|
|
case STREAM_SEEK_END:
|
|
if (!(dlibMove < 0 && ((ULONG) -dlibMove) > m_rom16.cbBuffer))
|
|
{
|
|
m_pos = m_rom16.cbBuffer + dlibMove;
|
|
}
|
|
else
|
|
{
|
|
hresult = ResultFromScode(E_UNSPEC); // PKT (Invalid seek)
|
|
}
|
|
break;
|
|
|
|
default:
|
|
hresult = ResultFromScode(E_UNSPEC); // PKT (Invalid seek mode)
|
|
}
|
|
|
|
if (plibNewPosition != NULL)
|
|
{
|
|
ULISet32(*plibNewPosition,m_pos);
|
|
}
|
|
|
|
return hresult;
|
|
}
|
|
|
|
//
|
|
// Note: if the cpkt data needs to be reallocate extra space
|
|
//
|
|
#define CBEXTRABYTES 128
|
|
|
|
STDMETHODIMP CPkt::SetSize(ULARGE_INTEGER cb)
|
|
{
|
|
HRESULT hresult = NOERROR;
|
|
ULONG ulNewSize;
|
|
|
|
if (m_opd.cbSize && m_opd.cbSize > cb.LowPart) {
|
|
m_rom16.cbBuffer = cb.LowPart;
|
|
goto Exit;
|
|
}
|
|
|
|
if (m_rom16.cbBuffer == cb.LowPart)
|
|
goto Exit;
|
|
|
|
ulNewSize = cb.LowPart + CBEXTRABYTES;
|
|
TaskFree(m_rom16.Buffer);
|
|
m_rom16.Buffer = TaskAlloc(ulNewSize);
|
|
if ( m_rom16.Buffer == NULL )
|
|
{
|
|
m_rom16.cbBuffer = 0;
|
|
m_opd.cbSize = 0;
|
|
hresult = ResultFromScode(S_OOM);
|
|
goto Exit;
|
|
}
|
|
|
|
m_rom16.cbBuffer = cb.LowPart;
|
|
|
|
m_opd.cbSize = ulNewSize;
|
|
|
|
Exit:
|
|
return hresult;
|
|
}
|
|
|
|
|
|
STDMETHODIMP CPkt::CopyTo(IStream FAR *pstm, ULARGE_INTEGER cb,
|
|
ULARGE_INTEGER FAR * pcbRead, ULARGE_INTEGER FAR * pcbWritten)
|
|
{
|
|
return ResultFromScode(E_NOTIMPL);
|
|
}
|
|
|
|
|
|
STDMETHODIMP CPkt::Commit(DWORD grfCommitFlags)
|
|
{
|
|
return ResultFromScode(E_NOTIMPL);
|
|
}
|
|
|
|
|
|
|
|
STDMETHODIMP CPkt::Revert(void)
|
|
{
|
|
return ResultFromScode(E_NOTIMPL);
|
|
}
|
|
|
|
|
|
|
|
STDMETHODIMP CPkt::LockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER, DWORD dwLockType)
|
|
{
|
|
return ResultFromScode(E_NOTIMPL);
|
|
}
|
|
|
|
STDMETHODIMP CPkt::UnlockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
|
|
{
|
|
return ResultFromScode(E_NOTIMPL);
|
|
}
|
|
|
|
|
|
|
|
STDMETHODIMP CPkt::Stat(STATSTG FAR *pstatstg, DWORD statflag)
|
|
{
|
|
return ResultFromScode(E_NOTIMPL);
|
|
}
|
|
|
|
|
|
|
|
STDMETHODIMP CPkt::Clone(THIS_ IStream FAR * FAR *ppstm)
|
|
{
|
|
return ResultFromScode(E_NOTIMPL);
|
|
}
|
|
|
|
//
|
|
// Create untyped CPkt. Used by other create functions (is private)
|
|
//
|
|
|
|
|
|
CPkt FAR* CPkt::Create(IUnknown FAR *pUnk, DWORD cbExt)
|
|
{
|
|
CPkt FAR* pCPkt;
|
|
|
|
pCPkt = new CPkt;
|
|
|
|
if (pCPkt == NULL)
|
|
return NULL;
|
|
|
|
pCPkt->m_rom16.Buffer = TaskAlloc( cbExt );
|
|
if ( pCPkt->m_rom16.Buffer == NULL )
|
|
{
|
|
delete pCPkt;
|
|
return NULL;
|
|
}
|
|
|
|
pCPkt->m_rom16.cbBuffer = cbExt;
|
|
pCPkt->m_opd.cbSize = cbExt;
|
|
|
|
return pCPkt;
|
|
}
|
|
|
|
//
|
|
// CPkt used to make a call
|
|
//
|
|
|
|
CPkt FAR* CPkt::CreateForCall(
|
|
IUnknown FAR *pUnk,
|
|
REFIID iid,
|
|
int iMethod,
|
|
BOOL fSend,
|
|
BOOL fAsync,
|
|
DWORD size )
|
|
{
|
|
CPkt FAR * pCPkt;
|
|
|
|
if (fAsync && fSend) {
|
|
fSend = FALSE;
|
|
//Assert(0,"Async CPkt with fSend == TRUE not implemented");
|
|
//return NULL;
|
|
}
|
|
|
|
pCPkt = CPkt::Create(pUnk, size);
|
|
if (pCPkt == NULL)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
pCPkt->m_opd.iid = iid;
|
|
|
|
pCPkt->m_rom16.iMethod = iMethod;
|
|
pCPkt->m_rom16.rpcFlags = 0;
|
|
|
|
if ( fSend )
|
|
{
|
|
pCPkt->m_rom16.rpcFlags |= RPCFLG_INPUT_SYNCHRONOUS;
|
|
}
|
|
|
|
if ( fAsync )
|
|
{
|
|
pCPkt->m_rom16.rpcFlags |= RPCFLG_ASYNCHRONOUS;
|
|
}
|
|
return pCPkt;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: SetRpcChannelBuffer, public
|
|
//
|
|
// Synopsis: Sets the RpcChannelBuffer to call when CallRpcChannelBuffer
|
|
// is called.
|
|
//
|
|
// Arguments: [prcb] - IRpcChannelBuffer interface
|
|
//
|
|
// Returns: NOERROR always
|
|
//
|
|
// History: 30-Mar-94 BobDay Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
STDMETHODIMP CPkt::SetRpcChannelBuffer(
|
|
CRpcChannelBuffer FAR * prcb )
|
|
{
|
|
m_prcb = prcb;
|
|
|
|
return NOERROR;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: CallRpcChannelBuffer, public
|
|
//
|
|
// Synopsis: Calls the RpcChannelBuffer with the parameters accumulated in
|
|
// the CPkt buffer.
|
|
//
|
|
// Arguments: none
|
|
//
|
|
// Returns: HRESULT for success/failure of call or procedure
|
|
//
|
|
// History: 30-Mar-94 BobDay Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
STDMETHODIMP CPkt::CallRpcChannelBuffer( void )
|
|
{
|
|
HRESULT hresult;
|
|
RPCOLEMESSAGE16 rom16;
|
|
ULONG ulStatus;
|
|
|
|
//
|
|
// Allocate a buffer from the Channel
|
|
//
|
|
memset(&rom16, 0, sizeof(rom16)); // Zero out everything
|
|
|
|
rom16.cbBuffer = m_rom16.cbBuffer; // Tell it how big we want it!
|
|
rom16.rpcFlags = m_rom16.rpcFlags;
|
|
rom16.iMethod = m_rom16.iMethod;
|
|
|
|
hresult = m_prcb->GetBuffer( &rom16, m_opd.iid );
|
|
if ( FAILED(hresult) )
|
|
{
|
|
return hresult;
|
|
}
|
|
|
|
//
|
|
// For speed, we could get away without doing the copy here
|
|
// by passing the buffer to the 32-bit world in the GetBuffer
|
|
// call above.
|
|
//
|
|
hmemcpy( rom16.Buffer, m_rom16.Buffer, m_rom16.cbBuffer );
|
|
|
|
//
|
|
// Call the channel
|
|
//
|
|
ulStatus = 0;
|
|
hresult = m_prcb->SendReceive( &rom16, &ulStatus );
|
|
if ( SUCCEEDED(hresult) )
|
|
{
|
|
ULARGE_INTEGER ularge_integer;
|
|
|
|
hresult = (HRESULT)ulStatus;
|
|
|
|
//
|
|
// Copy the buffer back!
|
|
//
|
|
ULISet32(ularge_integer,rom16.cbBuffer);
|
|
SetSize( ularge_integer ); // Make it big enough!
|
|
|
|
hmemcpy( m_rom16.Buffer, rom16.Buffer, rom16.cbBuffer );
|
|
}
|
|
|
|
//
|
|
// Free up the buffer
|
|
//
|
|
m_prcb->FreeBuffer( &rom16 );
|
|
|
|
return hresult;
|
|
}
|