423 lines
9.4 KiB
C++
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;
|
|
}
|