windows-nt/Source/XPSP1/NT/multimedia/directx/dinput/dx7/dll/dimem.c
2020-09-26 16:20:57 +08:00

130 lines
3.2 KiB
C

/*****************************************************************************
*
* DIMem.c
*
* Copyright (c) 1996 - 1999 Microsoft Corporation. All Rights Reserved.
*
* Abstract:
*
* Memory management
*
* Contents:
*
* ReallocCbPpv
* AllocCbPpv
* FreePpv
*
*****************************************************************************/
#include "dinputpr.h"
#ifdef NEED_REALLOC
/*****************************************************************************
*
* ReallocCbPpv
*
* Change the size of some zero-initialized memory.
*
* This is the single place where all memory is allocated, resized,
* and freed.
*
* If you realloc from a null pointer, memory is allocated.
* If you realloc to zero-size, memory is freed.
*
* These semantics avoid boundary cases. For example, it is no
* longer a problem trying to realloc something down to zero.
* You don't have to worry about special-casing an alloc of 0 bytes.
*
* If an error is returned, the original pointer is UNCHANGED.
* This saves you from having to the double-switch around a realloc.
*
*****************************************************************************/
STDMETHODIMP EXTERNAL
ReallocCbPpv(UINT cb, PV ppvArg)
{
HRESULT hres;
PPV ppv = ppvArg;
HLOCAL hloc = *ppv;
if (cb) { /* Alloc or realloc */
if (hloc) { /* Realloc */
hloc = LocalReAlloc(hloc, cb,
LMEM_MOVEABLE+LMEM_ZEROINIT);
} else { /* Alloc */
hloc = LocalAlloc(LPTR, cb);
}
hres = hloc ? NOERROR : E_OUTOFMEMORY;
} else { /* Freeing */
if (hloc) {
LocalFree(hloc);
hloc = 0;
hres = NOERROR; /* All gone */
} else {
hres = NOERROR; /* Nothing to free */
}
}
if (SUCCEEDED(hres)) {
*ppv = hloc;
}
return hres;
}
/*****************************************************************************
*
* AllocCbPpv
*
* Simple wrapper that forces *ppvObj = 0 before calling Realloc.
*
*****************************************************************************/
STDMETHODIMP EXTERNAL
AllocCbPpv(UINT cb, PPV ppv)
{
*ppv = 0;
return ReallocCbPpv(cb, ppv);
}
#else
/*****************************************************************************
*
* AllocCbPpv
*
* Allocate memory into the ppv.
*
*****************************************************************************/
STDMETHODIMP EXTERNAL
AllocCbPpv(UINT cb, PPV ppv)
{
HRESULT hres;
*ppv = LocalAlloc(LPTR, cb);
hres = *ppv ? NOERROR : E_OUTOFMEMORY;
return hres;
}
/*****************************************************************************
*
* FreePpv
*
* Free memory from the ppv.
*
*****************************************************************************/
void EXTERNAL
FreePpv(PV ppv)
{
#ifdef _M_IA64
PV pv = (PV)InterlockedExchange64(ppv, 0);
#else
PV pv = (PV)InterlockedExchange(ppv, 0);
#endif
if (pv) {
FreePv(pv);
}
}
#endif