windows-nt/Source/XPSP1/NT/com/ole32/stg/drt/ilb.cxx
2020-09-26 16:20:57 +08:00

423 lines
9.4 KiB
C++

//+-------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1992.
//
// File: ilbmem.cx
//
// Contents: ILockBytes memory implementation
//
// Classes: CMapBytes
//
// History: 06-Nov-92 AlexT Created
//
//--------------------------------------------------------------------------
#include "headers.cxx"
#pragma hdrstop
#include <memory.h>
#include <ilb.hxx>
#if DBG == 1
DECLARE_INFOLEVEL(ol);
#endif
//+-------------------------------------------------------------------------
//
// Member: CMapBytes::CMapBytes, public
//
// Synopsis: constructor
//
// Effects: initialize member variables
//
// Derivation: ILockBytes
//
// History: 06-Nov-92 AlexT Created
//
// Notes: Returns a fully initialized CMapBytes (ref count == 1)
//
//--------------------------------------------------------------------------
CMapBytes::CMapBytes(void)
{
_ulSize = 0;
_pv = 0;
_ulRef = 1;
}
//+-------------------------------------------------------------------------
//
// Member: CMapBytes::QueryInterface, public
//
// Arguments: [riid] - interface id
// [ppvObj] - place holder for interface
//
// Returns: Always fails
//
// Derivation: ILockBytes
//
// History: 06-Nov-92 AlexT Created
//
// Notes: Not used in tests
//
//--------------------------------------------------------------------------
STDMETHODIMP CMapBytes::QueryInterface(REFIID riid, LPVOID FAR* ppvObj)
{
*ppvObj = NULL;
return ResultFromScode(STG_E_INVALIDFUNCTION);
}
//+-------------------------------------------------------------------------
//
// Member: CMapBytes::AddRef, public
//
// Synopsis: add reference
//
// Returns: post reference count
//
// Derivation: ILockBytes
//
// History: 06-Nov-92 AlexT Created
//
//--------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CMapBytes::AddRef(void)
{
AtomicInc(&_ulRef);
return(_ulRef);
}
//+-------------------------------------------------------------------------
//
// Member: CMapBytes::Release, public
//
// Synopsis: release reference
//
// Effects: deletes object when reference count reaches zero
//
// Returns: post reference count
//
// Derivation: ILockBytes
//
// History: 06-Nov-92 AlexT Created
//
//--------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CMapBytes::Release(void)
{
AtomicDec(&_ulRef);
if (_ulRef > 0)
return(_ulRef);
free(_pv);
delete this;
return(0);
}
//+-------------------------------------------------------------------------
//
// Member: CMapBytes::ReadAt
//
// Synopsis: Reads bytes from memory
//
// Arguments: [ulOffset] - byte offset
// [pv] - input buffer
// [cb] - count of bytes to read
// [pcbRead] - count of bytes read
//
// Returns: SCODE
//
// Modifies: pv, pcbRead
//
// Derivation: ILockBytes
//
// History: 30-Oct-92 AlexT Created
//
//--------------------------------------------------------------------------
STDMETHODIMP CMapBytes::ReadAt(ULARGE_INTEGER uliOffset,
VOID HUGEP *pv,
ULONG cb,
ULONG *pcbRead)
{
olAssert(ULIGetHigh(uliOffset) == 0);
ULONG ulOffset = ULIGetLow(uliOffset);
if (ulOffset >= _ulSize)
{
// truncate read
cb = 0;
}
else if (cb > (_ulSize - ulOffset))
{
// truncate range that exceeds size
cb = _ulSize - ulOffset;
}
memcpy(pv, (void*)(((BYTE*)_pv) + ulOffset), (size_t) cb);
*pcbRead = cb;
return NOERROR;
}
//+-------------------------------------------------------------------------
//
// Member: CMapBytes::WriteAt, public
//
// Synopsis: Writes bytes to memory
//
// Effects: May change memory size
//
// Arguments: [uliOffset] - byte offset
// [pv] - output buffer
// [cb] - count of bytes to write
// [pcbWritten] - count of bytes written
//
// Returns: SCODE
//
// Modifies: pcbWritten
//
// Derivation: ILockBytes
//
// History: 06-Nov-92 AlexT Created
//
// Notes: This implementation doesn't write partial buffers.
//
//--------------------------------------------------------------------------
STDMETHODIMP CMapBytes::WriteAt(ULARGE_INTEGER uliOffset,
VOID const HUGEP *pv,
ULONG cb,
ULONG FAR *pcbWritten)
{
olAssert(ULIGetHigh(uliOffset) == 0);
ULONG ulOffset = ULIGetLow(uliOffset);
HRESULT hr;
if (ulOffset + cb > _ulSize)
{
// increase memory buffer to accomodate write
ULARGE_INTEGER uliSize;
ULISetHigh(uliSize, 0);
ULISetLow(uliSize, ulOffset + cb);
hr = SetSize(uliSize);
if (FAILED(DfGetScode(hr)))
{
// don't bother writing partial buffers
*pcbWritten = 0;
return hr;
}
}
memcpy((void *)(((BYTE*)_pv) + ulOffset), pv, (size_t) cb);
*pcbWritten = cb;
return NOERROR;
}
//+-------------------------------------------------------------------------
//
// Member: CMapBytes::Flush, public
//
// Synopsis: flushes memory - not appropriate for this implementation
//
// Effects: none
//
// Returns: SUCCESS_SUCCESS
//
// Derivation: ILockBytes
//
// History: 06-Nov-92 AlexT Created
//
//--------------------------------------------------------------------------
STDMETHODIMP CMapBytes::Flush(void)
{
return NOERROR;
}
//+-------------------------------------------------------------------------
//
// Member: CMapBytes::GetSize, public
//
// Synopsis: gets memory buffer size
//
// Arguments: [pcb] - size place holder
//
// Returns: SUCCESS_SUCCESS
//
// Modifies: pcb
//
// Derivation: ILockBytes
//
// History: 06-Nov-92 AlexT Created
//
//--------------------------------------------------------------------------
STDMETHODIMP CMapBytes::GetSize(ULARGE_INTEGER FAR *pcb)
{
ULISetHigh(*pcb, 0);
ULISetLow(*pcb, _ulSize);
return NOERROR;
}
//+-------------------------------------------------------------------------
//
// Member: CMapBytes::SetSize, public
//
// Synopsis: sets memory buffer size
//
// Effects: may change buffer size
//
// Arguments: [ulicb] - new memory size
//
// Returns: SCODE
//
// Derivation: ILockBytes
//
// Algorithm: realloc the buffer
//
// History: 06-Nov-92 AlexT Created
//
//--------------------------------------------------------------------------
STDMETHODIMP CMapBytes::SetSize(ULARGE_INTEGER ulicb)
{
olAssert(ULIGetHigh(ulicb) == 0);
ULONG cb = ULIGetLow(ulicb);
if (cb == _ulSize)
return NOERROR;
void *pv = realloc(_pv, (size_t) cb);
if ((cb > 0) && (pv == NULL))
{
// Unable to allocate memory
// Leave current memory and size alone
return ResultFromScode(E_OUTOFMEMORY);
}
_pv = pv;
_ulSize = cb;
return NOERROR;
}
//+-------------------------------------------------------------------------
//
// Member: CMapBytes::LockRegion, public
//
// Synopsis: not supported (intentionally)
//
// Effects: asserts if called
//
// Arguments: [libOffset] - lock range offset
// [cb] - lock range size
// [dwLockType] - lock type
//
// Returns: STG_E_INVALIDFUNCTION
//
// Derivation: ILockBytes
//
// History: 06-Nov-92 AlexT Created
//
//--------------------------------------------------------------------------
STDMETHODIMP CMapBytes::LockRegion(ULARGE_INTEGER libOffset,
ULARGE_INTEGER cb,
DWORD dwLockType)
{
olAssert(0 && "Can't lock CMapBytes");
return ResultFromScode(STG_E_INVALIDFUNCTION);
}
//+-------------------------------------------------------------------------
//
// Member: CMapBytes::UnLockRegion, public
//
// Synopsis: not supported (intentionally)
//
// Effects: asserts if called
//
// Arguments: [libOffset] - lock range offset
// [cb] - lock range size
// [dwLockType] - lock type
//
// Returns: STG_E_INVALIDFUNCTION
//
// Derivation: ILockBytes
//
// History: 06-Nov-92 AlexT Created
//
//--------------------------------------------------------------------------
STDMETHODIMP CMapBytes::UnlockRegion(ULARGE_INTEGER libOffset,
ULARGE_INTEGER cb,
DWORD dwLockType)
{
olAssert(0 && "Can't unlock CMapBytes");
return ResultFromScode(STG_E_INVALIDFUNCTION);
}
//+-------------------------------------------------------------------------
//
// Member: CMapBytes::Stat, public
//
// Synopsis: Provide instance information
//
// Arguments: [pstatstg] - status buffer
// [grfStatFlag] - status flags
//
// Returns: SCODE
//
// Modifies: pstatstg
//
// Derivation: ILockBytes
//
// History: 06-Nov-92 AlexT Created
//
// Notes: No time stamps
//
//--------------------------------------------------------------------------
STDMETHODIMP CMapBytes::Stat(STATSTG FAR *pstatstg, DWORD grfStatFlag)
{
memset(pstatstg, 0, sizeof(STATSTG));
if ((grfStatFlag & STATFLAG_NONAME) == 0)
{
static char const abName[] = "Memory";
HRESULT hr;
if (FAILED(DfGetScode(hr = drtMemAlloc(sizeof(abName),
(void **) &pstatstg->pwcsName))))
return hr;
memcpy(pstatstg->pwcsName, abName, sizeof(abName));
}
pstatstg->type = STGTY_LOCKBYTES;
ULISetHigh(pstatstg->cbSize, 0);
ULISetLow(pstatstg->cbSize, _ulSize);
pstatstg->grfMode = STGM_READWRITE | STGM_DIRECT | STGM_SHARE_EXCLUSIVE;
return NOERROR;
}