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

319 lines
8.2 KiB
C++

//+--------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1996.
//
// File: mem.cxx
//
// Contents: IMalloc interface implementations
// Note that these functions do little more than
// the normal delete and new. They are provided
// so that existing code can be ported to the ref.
// impl. easily.
//
//---------------------------------------------------------------
#ifndef __MEM__C__
#define __MEM__C__
#include "exphead.cxx"
#include "h/mem.hxx"
#include "memory.h"
#include "h/dfexcept.hxx"
static CAllocator theAllocator; // global allocator
//+--------------------------------------------------------------
//
// Function: CoGetMalloc, public
//
// Synopsis: Retrieves a pointer to the default OLE task memory
// allocator (which supports the system implementation
// of the IMalloc interface) so applications can call
// its methods to manage memory.
//
// Arguments: [dwMemContext] - Indicates if memory is private or shared
// [ppMalloc] - Receives pointer to memory allocator on return
//
// Returns: Appropriate status code
//
// Modifies: [ppMalloc]
//
//---------------------------------------------------------------
STDAPI
CoGetMalloc( DWORD dwMemContext, LPMALLOC * ppMalloc )
{
if (FAILED(ValidatePtrBuffer(ppMalloc))
|| dwMemContext != 1)
return ResultFromScode(E_INVALIDARG);
else
{
*ppMalloc = &theAllocator;
return S_OK;
}
}
//+--------------------------------------------------------------
//
// Function: CoTaskMemAlloc, public
//
// Synopsis: Allocates a block of task memory in the same way
// that IMalloc::Alloc does.
//
// Arguments: [cb] - Size in bytes of memory block to be allocated
//
// Returns: Allocated memory block
// Indicates memory block allocated successfully.
// NULL
// Indicates insufficient memory available.
//
// Modifies: [ppMalloc]
//
//---------------------------------------------------------------
STDAPI_(LPVOID)
CoTaskMemAlloc( ULONG cb )
{
return theAllocator.Alloc(cb);
}
//+--------------------------------------------------------------
//
// Function: CoTaskMemFree, public
//
// Synopsis: Frees a block of task memory previously allocated
// through a call to the CoTaskMemAlloc or
// CoTaskMemRealloc function.
//
// Arguments: [pv] - Points to memory block to be freed
//
// Modifies: nothing
//
//---------------------------------------------------------------
STDAPI_(void)
CoTaskMemFree( void* pv )
{
theAllocator.Free(pv);
}
//+--------------------------------------------------------------
//
// Function: CoTaskMemRealloc, public
//
// Synopsis: Changes the size of a previously allocated block
// of task memory.
//
// Arguments: [pv] - Points to memory block to be reallocated
// [cb] - Size in bytes of block to be reallocated
//
// Returns: Reallocated memory block
// Indicates memory block successfully reallocated.
// NULL
// Indicates insufficient memory or cb is zero
// and pv is not NULL.
//
// Modifies: nothing
//
//---------------------------------------------------------------
STDAPI_(LPVOID)
CoTaskMemRealloc( LPVOID pv, ULONG cb )
{
return theAllocator.Realloc(pv, cb);
}
//+---------------------------------------------------------------------------
//
// Member: CAllocator::QueryInterface, public
//
// Synopsis: Standard QI
//
// Arguments: [iid] - Interface ID
// [ppvObj] - Object return
//
// Returns: Appropriate status code
//
//
//----------------------------------------------------------------------------
STDMETHODIMP CAllocator::QueryInterface(REFIID iid, void **ppvObj)
{
SCODE sc;
if (IsEqualIID(iid, IID_IMalloc) || IsEqualIID(iid, IID_IUnknown))
{
*ppvObj = (IMalloc *) this;
//CAllocator::AddRef();
}
else
sc = E_NOINTERFACE;
return ResultFromScode(sc);
}
//+---------------------------------------------------------------------------
//
// Member: CAllocator::AddRef, public
//
// Synopsis: Add reference
//
//
//----------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CAllocator::AddRef(void)
{
//return ++_cRefs;
return 1; // return a dummy value
}
//+---------------------------------------------------------------------------
//
// Member: CAllocator::Release, public
//
// Synopsis: Release
//
//
//----------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CAllocator::Release(void)
{
return 0; // return a dummy value
}
//+---------------------------------------------------------------------------
//
// Member: CAllocator::Alloc, public
//
// Synopsis: Allocate memory
//
// Arguments: [cb] -- Number of bytes to allocate
//
// Returns: Pointer to block, NULL if failure
//
//----------------------------------------------------------------------------
STDMETHODIMP_(void *) CAllocator::Alloc ( ULONG cb )
{
// make sure the retuned value is 8 byte aligned
return (void *) new LONGLONG[ (cb+7)/sizeof(LONGLONG) ];
}
//+---------------------------------------------------------------------------
//
// Member: CAllocator::Realloc, public
//
// Synopsis: Resize the block given
//
// Arguments: [pv] -- Pointer to block to realloc
// [cb] -- New size for block
//
// Returns: Pointer to new block, NULL if failure
//
// Note: The current implementation will copy cb # of
// bytes to the new block, even if the old block
// has size smaller then cb.
// ==> potential problems esp if pv is at a
// memory boundary.
//----------------------------------------------------------------------------
STDMETHODIMP_(void *)
CAllocator::Realloc( void *pv, ULONG cb )
{
void* pvNew=NULL;
if (!pv)
pvNew = Alloc(cb);
else
{
// make sure the new pointer is 8-byte aligned
pvNew = (void *) (new LONGLONG [(cb+7)/sizeof(LONGLONG)]);
if (pvNew)
{
memcpy(pvNew, pv, cb);
delete[] pv;
}
}
return pvNew;
}
//+---------------------------------------------------------------------------
//
// Member: CSmAllocator::Free, public
//
// Synopsis: Free a memory block
//
// Arguments: [pv] -- Pointer to block to free
//
// Returns: void
//
//----------------------------------------------------------------------------
STDMETHODIMP_(void) CAllocator::Free(void *pv)
{
delete[] pv;
}
//+---------------------------------------------------------------------------
//
// Member: CAllocator::GetSize, public
//
// Synopsis: Return the size of the given block
//
// Arguments: [pv] -- Block to get size of
//
// Returns: (should) Size of block pointer to by
// (now) 0
//----------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CAllocator::GetSize(void * pv)
{
UNREFERENCED_PARM(pv);
return 0;
}
//+---------------------------------------------------------------------------
//
// Member: CAllocator::DidAlloc, public
//
// Synopsis: Return '1' if this heap allocated pointer at pv
//
// Arguments: [pv] -- Pointer to block
//
// Returns: '1' == This heap allocated block.
// '0' == This heap did not allocate block.
// '-1' == Could not determine if this heap allocated block.
//
//----------------------------------------------------------------------------
STDMETHODIMP_(int) CAllocator::DidAlloc(void FAR * pv)
{
UNREFERENCED_PARM(pv);
return -1;
}
//+---------------------------------------------------------------------------
//
// Member: CAllocator::HeapMinimize, public
//
// Synopsis: Minimize the heap
//
// Arguments: None.
//
// Returns: void.
//
//----------------------------------------------------------------------------
STDMETHODIMP_(void) CAllocator::HeapMinimize(void)
{
// do nothing;
return;
}
#endif // __MEM__C__