MEMORY.CPP
/*++ 
 
Copyright (c) 1996 Microsoft Corporation 
 
Module Name: 
 
    Memory.cpp 
 
Abstract: 
 
    This module provides all the memory management functions for all Sample 
    provider components 
 
 
Author: 
 
Environment: 
 
    User mode 
 
Revision History : 
 
--*/ 
#include "adssmp.h" 
 
#define WORD_ALIGN_DOWN(addr) ((LPBYTE)((DWORD)addr &= ~1)) 
#define DWORD_ALIGN_UP(size) ((size+3)&~3) 
 
 
LPVOID 
AllocProvMem( 
    DWORD cb 
) 
{ 
    LPDWORD  pMem; 
    DWORD    cbNew ; 
 
#if DBG 
    cb = DWORD_ALIGN_UP(cb); 
 
    cbNew = cb + (sizeof(DWORD) + sizeof(LONGLONG)); 
#else 
    cbNew = cb ; 
#endif 
 
    pMem=(LPDWORD)LocalAlloc(LPTR, cbNew); 
 
 
#if DBG 
 
    if (!pMem) { 
        SetLastError(ERROR_NOT_ENOUGH_MEMORY); 
        return 0; 
    } 
 
    *pMem=cb; 
    *(LPDWORD)((LPBYTE)pMem+cbNew-sizeof(DWORD))=0xdeadfeed; 
    pMem = (LPDWORD) (((LPBYTE)pMem)+sizeof(LONGLONG)); 
#endif 
 
    return (LPVOID)(pMem); 
} 
 
BOOL 
FreeProvMem( 
   LPVOID pMem 
) 
{ 
    LPBYTE   pNewMem; 
 
    pNewMem = (LPBYTE)pMem; 
 
#if DBG 
    DWORD    cb; 
    DWORD    cbNew = 0; 
 
    pNewMem -= sizeof(LONGLONG) ; 
 
    cb = *((LPDWORD)pNewMem); 
    cbNew = cb + sizeof(DWORD) + sizeof(LONGLONG); 
 
    if (*(LPDWORD)(pNewMem + cbNew - sizeof(DWORD)) != 0xdeadbeef) { 
        ADsAssert(!"Freeing memory not allocated by AllocProvMem") ; 
        return FALSE; 
    } 
 
    // fill freed memory with known pattern 
    memset(pMem, 0x5C, cb); 
 
#endif 
 
 
    return(LocalFree((LPVOID)pNewMem) == NULL); 
} 
 
LPVOID 
ReallocProvMem( 
   LPVOID pOldMem, 
   DWORD cbOld, 
   DWORD cbNew 
) 
{ 
    LPVOID pNewMem; 
 
    pNewMem=AllocProvMem(cbNew); 
 
    if (pOldMem && pNewMem) { 
        memcpy(pNewMem, pOldMem, min(cbNew, cbOld)); 
        FreeProvMem(pOldMem); 
    } 
 
    return pNewMem; 
} 
 
 
LPWSTR 
AllocProvStr( 
    LPWSTR pStr 
) 
{ 
   LPWSTR pMem; 
 
   if (!pStr) 
      return 0; 
 
   if (pMem = (LPWSTR)AllocProvMem( wcslen(pStr)*sizeof(WCHAR) + sizeof(WCHAR) )) 
      wcscpy(pMem, pStr); 
 
   return pMem; 
} 
 
BOOL 
FreeProvStr( 
   LPWSTR pStr 
) 
{ 
   return pStr ? FreeProvMem(pStr) 
               : FALSE; 
} 
 
BOOL 
ReallocProvStr( 
   LPWSTR *ppStr, 
   LPWSTR pStr 
) 
{ 
   FreeProvStr(*ppStr); 
   *ppStr=AllocProvStr(pStr); 
 
   return TRUE; 
} 
 
STDAPI 
ProvAllocString(const OLECHAR * pch, BSTR * pBSTR) 
{ 
    HRESULT hr = S_OK; 
 
    ADsAssert(pBSTR); 
    if (!pch) 
    { 
        *pBSTR = NULL; 
        return S_OK; 
    } 
 
    *pBSTR = SysAllocString(pch); 
    hr = (*pBSTR) ? S_OK : E_OUTOFMEMORY; 
    RRETURN(hr); 
}