/*************************************************************************
 * OLE Automation - SafeArray
 *
 * This file contains the implementation of the SafeArray functions.
 *
 * Copyright 1999 Sylvain St-Germain
 * Copyright 2002-2003 Marcus Meissner
 * Copyright 2003 Jon Griffiths
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */
/* Memory Layout of a SafeArray:
 *
 * -0x10: start of memory.
 * -0x10: GUID for VT_DISPATCH and VT_UNKNOWN safearrays (if FADF_HAVEIID)
 * -0x04: DWORD varianttype; (for all others, except VT_RECORD) (if FADF_HAVEVARTYPE)
 *  -0x4: IRecordInfo* iface;  (if FADF_RECORD, for VT_RECORD (can be NULL))
 *  0x00: SAFEARRAY,
 *  0x10: SAFEARRAYBOUNDS[0...]
 */

#include "config.h"

#include <string.h>
#include <stdarg.h>
#include <stdio.h>

#define COBJMACROS

#include "windef.h"
#include "winerror.h"
#include "winbase.h"
#include "variant.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(variant);

/************************************************************************
 * SafeArray {OLEAUT32}
 *
 * NOTES
 * The SafeArray data type provides the underlying interface for Ole
 * Automations arrays, used for example to represent array types in
 * Visual Basic(tm) and to gather user defined parameters for invocation through
 * an IDispatch interface.
 *
 * Safe arrays provide bounds checking and automatically manage the data
 * types they contain, for example handing reference counting and copying
 * of interface pointers. User defined types can be stored in arrays
 * using the IRecordInfo interface.
 *
 * There are two types of SafeArray, normal and vectors. Normal arrays can have
 * multiple dimensions and the data for the array is allocated separately from
 * the array header. This is the most flexible type of array. Vectors, on the
 * other hand, are fixed in size and consist of a single allocated block, and a
 * single dimension.
 *
 * DATATYPES
 * The following types of data can be stored within a SafeArray.
 * Numeric:
 *|  VT_I1, VT_UI1, VT_I2, VT_UI2, VT_I4, VT_UI4, VT_I8, VT_UI8, VT_INT, VT_UINT,
 *|  VT_R4, VT_R8, VT_CY, VT_DECIMAL
 * Interfaces:
 *|  VT_DISPATCH, VT_UNKNOWN, VT_RECORD
 * Other:
 *|  VT_VARIANT, VT_INT_PTR, VT_UINT_PTR, VT_BOOL, VT_ERROR, VT_DATE, VT_BSTR
 *
 * FUNCTIONS
 *  BstrFromVector()
 *  VectorFromBstr()
 */

/* Undocumented hidden space before the start of a SafeArray descriptor */
#define SAFEARRAY_HIDDEN_SIZE sizeof(GUID)

/* Allocate memory */
static inline LPVOID SAFEARRAY_Malloc(ULONG ulSize)
{
  /* FIXME: Memory should be allocated and freed using a per-thread IMalloc
   *        instance returned from CoGetMalloc().
   */
  return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ulSize);
}

/* Free memory */
static inline BOOL SAFEARRAY_Free(LPVOID lpData)
{
  return HeapFree(GetProcessHeap(), 0, lpData);
}

/* Get the size of a supported VT type (0 means unsupported) */
static DWORD SAFEARRAY_GetVTSize(VARTYPE vt)
{
  switch (vt)
  {
    case VT_I1:
    case VT_UI1:      return sizeof(BYTE);
    case VT_BOOL:
    case VT_I2:
    case VT_UI2:      return sizeof(SHORT);
    case VT_I4:
    case VT_UI4:
    case VT_R4:
    case VT_ERROR:    return sizeof(LONG);
    case VT_R8:
    case VT_I8:
    case VT_UI8:      return sizeof(LONG64);
    case VT_INT:
    case VT_UINT:     return sizeof(INT);
    case VT_INT_PTR:
    case VT_UINT_PTR: return sizeof(UINT_PTR);
    case VT_CY:       return sizeof(CY);
    case VT_DATE:     return sizeof(DATE);
    case VT_BSTR:     return sizeof(BSTR);
    case VT_DISPATCH: return sizeof(LPDISPATCH);
    case VT_VARIANT:  return sizeof(VARIANT);
    case VT_UNKNOWN:  return sizeof(LPUNKNOWN);
    case VT_DECIMAL:  return sizeof(DECIMAL);
    /* Note: Return a non-zero size to indicate vt is valid. The actual size
     * of a UDT is taken from the result of IRecordInfo_GetSize().
     */
    case VT_RECORD:   return 32;
  }
  return 0;
}

/* Set the hidden data for an array */
static inline void SAFEARRAY_SetHiddenDWORD(SAFEARRAY* psa, DWORD dw)
{
  /* Implementation data is stored in the 4 bytes before the header */
  LPDWORD lpDw = (LPDWORD)psa;
  lpDw[-1] = dw;
}

/* Get the hidden data from an array */
static inline DWORD SAFEARRAY_GetHiddenDWORD(SAFEARRAY* psa)
{
  LPDWORD lpDw = (LPDWORD)psa;
  return lpDw[-1];
}

/* Get the number of cells in a SafeArray */
static ULONG SAFEARRAY_GetCellCount(const SAFEARRAY *psa)
{
  const SAFEARRAYBOUND* psab = psa->rgsabound;
  USHORT cCount = psa->cDims;
  ULONG ulNumCells = 1;

  while (cCount--)
  {
    /* This is a valid bordercase. See testcases. -Marcus */
    if (!psab->cElements)
      return 0;
    ulNumCells *= psab->cElements;
    psab++;
  }
  return ulNumCells;
}

/* Allocate a descriptor for an array */
static HRESULT SAFEARRAY_AllocDescriptor(ULONG ulSize, SAFEARRAY **ppsaOut)
{
  *ppsaOut = (SAFEARRAY*)((char*)SAFEARRAY_Malloc(ulSize + SAFEARRAY_HIDDEN_SIZE) + SAFEARRAY_HIDDEN_SIZE);

  if (!*ppsaOut)
    return E_UNEXPECTED;

  return S_OK;
}

/* Set the features of an array */
static void SAFEARRAY_SetFeatures(VARTYPE vt, SAFEARRAY *psa)
{
  /* Set the IID if we have one, otherwise set the type */
  if (vt == VT_DISPATCH)
  {
    psa->fFeatures = FADF_HAVEIID;
    SafeArraySetIID(psa, &IID_IDispatch);
  }
  else if (vt == VT_UNKNOWN)
  {
    psa->fFeatures = FADF_HAVEIID;
    SafeArraySetIID(psa, &IID_IUnknown);
  }
  else if (vt == VT_RECORD)
    psa->fFeatures = FADF_RECORD;
  else
  {
    psa->fFeatures = FADF_HAVEVARTYPE;
    SAFEARRAY_SetHiddenDWORD(psa, vt);
  }
}

/* Create an array */
static SAFEARRAY* SAFEARRAY_Create(VARTYPE vt, UINT cDims, const SAFEARRAYBOUND *rgsabound, ULONG ulSize)
{
  SAFEARRAY *psa = NULL;
  int i;

  if (!rgsabound)
    return NULL;

  if (SUCCEEDED(SafeArrayAllocDescriptorEx(vt, cDims, &psa)))
  {
    switch (vt)
    {
      case VT_BSTR:     psa->fFeatures |= FADF_BSTR; break;
      case VT_UNKNOWN:  psa->fFeatures |= FADF_UNKNOWN; break;
      case VT_DISPATCH: psa->fFeatures |= FADF_DISPATCH; break;
      case VT_VARIANT:  psa->fFeatures |= FADF_VARIANT; break;
    }

    for (i = 0; i < cDims; i++)
      memcpy(psa->rgsabound + i, rgsabound + cDims - 1 - i, sizeof(SAFEARRAYBOUND));

    if (ulSize)
      psa->cbElements = ulSize;

    if (!psa->cbElements || FAILED(SafeArrayAllocData(psa)))
    {
      SafeArrayDestroyDescriptor(psa);
      psa = NULL;
    }
  }
  return psa;
}

/* Create an array as a vector */
static SAFEARRAY* SAFEARRAY_CreateVector(VARTYPE vt, LONG lLbound, ULONG cElements, ULONG ulSize)
{
  SAFEARRAY *psa = NULL;

  if (ulSize || (vt == VT_RECORD))
  {
    /* Allocate the header and data together */
    if (SUCCEEDED(SAFEARRAY_AllocDescriptor(sizeof(SAFEARRAY) + ulSize * cElements, &psa)))
    {
      SAFEARRAY_SetFeatures(vt, psa);

      psa->cDims = 1;
      psa->fFeatures |= FADF_CREATEVECTOR;
      psa->pvData = &psa[1]; /* Data follows the header */
      psa->cbElements = ulSize;
      psa->rgsabound[0].cElements = cElements;
      psa->rgsabound[0].lLbound = lLbound;

      switch (vt)
      {
        case VT_BSTR:     psa->fFeatures |= FADF_BSTR; break;
        case VT_UNKNOWN:  psa->fFeatures |= FADF_UNKNOWN; break;
        case VT_DISPATCH: psa->fFeatures |= FADF_DISPATCH; break;
        case VT_VARIANT:  psa->fFeatures |= FADF_VARIANT; break;
      }
    }
  }
  return psa;
}

/* Free data items in an array */
static HRESULT SAFEARRAY_DestroyData(SAFEARRAY *psa, ULONG ulStartCell)
{
  if (psa->pvData && !(psa->fFeatures & FADF_DATADELETED))
  {
    ULONG ulCellCount = SAFEARRAY_GetCellCount(psa);

    if (ulStartCell > ulCellCount) {
      FIXME("unexpted ulcellcount %d, start %d\n",ulCellCount,ulStartCell);
      return E_UNEXPECTED;
    }

    ulCellCount -= ulStartCell;

    if (psa->fFeatures & (FADF_UNKNOWN|FADF_DISPATCH))
    {
      LPUNKNOWN *lpUnknown = (LPUNKNOWN *)psa->pvData + ulStartCell;

      while(ulCellCount--)
      {
        if (*lpUnknown)
          IUnknown_Release(*lpUnknown);
        lpUnknown++;
      }
    }
    else if (psa->fFeatures & (FADF_RECORD))
    {
      IRecordInfo *lpRecInfo;

      if (SUCCEEDED(SafeArrayGetRecordInfo(psa, &lpRecInfo)))
      {
        PBYTE pRecordData = (PBYTE)psa->pvData;
        while(ulCellCount--)
        {
          IRecordInfo_RecordClear(lpRecInfo, pRecordData);
          pRecordData += psa->cbElements;
        }
        IRecordInfo_Release(lpRecInfo);
      }
    }
    else if (psa->fFeatures & FADF_BSTR)
    {
      BSTR* lpBstr = (BSTR*)psa->pvData + ulStartCell;

      while(ulCellCount--)
      {
        if (*lpBstr)
          SysFreeString(*lpBstr);
        lpBstr++;
      }
    }
    else if (psa->fFeatures & FADF_VARIANT)
    {
      VARIANT* lpVariant = (VARIANT*)psa->pvData + ulStartCell;

      while(ulCellCount--)
      {
        HRESULT hRet = VariantClear(lpVariant);

        if (FAILED(hRet)) FIXME("VariantClear of element failed!\n");
        lpVariant++;
      }
    }
  }
  return S_OK;
}

/* Copy data items from one array to another */
static HRESULT SAFEARRAY_CopyData(SAFEARRAY *psa, SAFEARRAY *dest)
{
  if (!psa->pvData)
    return S_OK;
  else if (!dest->pvData || psa->fFeatures & FADF_DATADELETED)
    return E_INVALIDARG;
  else
  {
    ULONG ulCellCount = SAFEARRAY_GetCellCount(psa);

    dest->fFeatures = (dest->fFeatures & FADF_CREATEVECTOR) |
                      (psa->fFeatures & ~(FADF_CREATEVECTOR|FADF_DATADELETED));

    if (psa->fFeatures & FADF_VARIANT)
    {
      VARIANT* lpVariant = (VARIANT*)psa->pvData;
      VARIANT* lpDest = (VARIANT*)dest->pvData;

      while(ulCellCount--)
      {
        HRESULT hRet;

        hRet = VariantCopy(lpDest, lpVariant);
        if (FAILED(hRet)) FIXME("VariantCopy failed with 0x%x\n", hRet);
        lpVariant++;
        lpDest++;
      }
    }
    else if (psa->fFeatures & FADF_BSTR)
    {
      BSTR* lpBstr = (BSTR*)psa->pvData;
      BSTR* lpDest = (BSTR*)dest->pvData;

      while(ulCellCount--)
      {
        if (*lpBstr)
        {
          *lpDest = SysAllocStringByteLen((char*)*lpBstr, SysStringByteLen(*lpBstr));
          if (!*lpDest)
            return E_OUTOFMEMORY;
        }
        else
          *lpDest = NULL;
        lpBstr++;
        lpDest++;
      }
    }
    else
    {
      /* Copy the data over */
      memcpy(dest->pvData, psa->pvData, ulCellCount * psa->cbElements);

      if (psa->fFeatures & (FADF_UNKNOWN|FADF_DISPATCH))
      {
        LPUNKNOWN *lpUnknown = (LPUNKNOWN *)dest->pvData;

        while(ulCellCount--)
        {
          if (*lpUnknown)
            IUnknown_AddRef(*lpUnknown);
          lpUnknown++;
        }
      }
    }

    if (psa->fFeatures & FADF_RECORD)
    {
      IRecordInfo* pRecInfo = NULL;

      SafeArrayGetRecordInfo(psa, &pRecInfo);
      SafeArraySetRecordInfo(dest, pRecInfo);

      if (pRecInfo)
      {
        /* Release because Get() adds a reference */
        IRecordInfo_Release(pRecInfo);
      }
    }
    else if (psa->fFeatures & FADF_HAVEIID)
    {
      GUID guid;
      SafeArrayGetIID(psa, &guid);
      SafeArraySetIID(dest, &guid);
    }
    else if (psa->fFeatures & FADF_HAVEVARTYPE)
    {
      SAFEARRAY_SetHiddenDWORD(dest, SAFEARRAY_GetHiddenDWORD(psa));
    }
  }
  return S_OK;
}

/*************************************************************************
 *		SafeArrayAllocDescriptor (OLEAUT32.36)
 *
 * Allocate and initialise a descriptor for a SafeArray.
 *
 * PARAMS
 *  cDims   [I] Number of dimensions of the array
 *  ppsaOut [O] Destination for new descriptor
 *
 * RETURNS
 * Success: S_OK. ppsaOut is filled with a newly allocated descriptor.
 * Failure: An HRESULT error code indicating the error.
 *
 * NOTES
 * See SafeArray.
 */
HRESULT WINAPI SafeArrayAllocDescriptor(UINT cDims, SAFEARRAY **ppsaOut)
{
  LONG allocSize;

  TRACE("(%d,%p)\n", cDims, ppsaOut);
  
  if (!cDims || cDims >= 0x10000) /* Maximum 65535 dimensions */
    return E_INVALIDARG;

  if (!ppsaOut)
    return E_POINTER;

  /* We need enough space for the header and its bounds */
  allocSize = sizeof(SAFEARRAY) + sizeof(SAFEARRAYBOUND) * (cDims - 1);

  if (FAILED(SAFEARRAY_AllocDescriptor(allocSize, ppsaOut)))
    return E_UNEXPECTED;

  (*ppsaOut)->cDims = cDims;

  TRACE("(%d): %u bytes allocated for descriptor.\n", cDims, allocSize);
  return S_OK;
}

/*************************************************************************
 *		SafeArrayAllocDescriptorEx (OLEAUT32.41)
 *
 * Allocate and initialise a descriptor for a SafeArray of a given type.
 *
 * PARAMS
 *  vt      [I] The type of items to store in the array
 *  cDims   [I] Number of dimensions of the array
 *  ppsaOut [O] Destination for new descriptor
 *
 * RETURNS
 *  Success: S_OK. ppsaOut is filled with a newly allocated descriptor.
 *  Failure: An HRESULT error code indicating the error.
 *
 * NOTES
 *  - This function does not chack that vt is an allowed VARTYPE.
 *  - Unlike SafeArrayAllocDescriptor(), vt is associated with the array.
 *  See SafeArray.
 */
HRESULT WINAPI SafeArrayAllocDescriptorEx(VARTYPE vt, UINT cDims, SAFEARRAY **ppsaOut)
{
  ULONG cbElements;
  HRESULT hRet = E_UNEXPECTED;

  TRACE("(%d->%s,%d,%p)\n", vt, debugstr_vt(vt), cDims, ppsaOut);
    
  cbElements = SAFEARRAY_GetVTSize(vt);
  if (!cbElements)
    WARN("Creating a descriptor with an invalid VARTYPE!\n");

  hRet = SafeArrayAllocDescriptor(cDims, ppsaOut);

  if (SUCCEEDED(hRet))
  {
    SAFEARRAY_SetFeatures(vt, *ppsaOut);
    (*ppsaOut)->cbElements = cbElements;
  }
  return hRet;
}

/*************************************************************************
 *		SafeArrayAllocData (OLEAUT32.37)
 *
 * Allocate the data area of a SafeArray.
 *
 * PARAMS
 *  psa [I] SafeArray to allocate the data area of.
 *
 * RETURNS
 *  Success: S_OK. The data area is allocated and initialised.
 *  Failure: An HRESULT error code indicating the error.
 *
 * NOTES
 *  See SafeArray.
 */
HRESULT WINAPI SafeArrayAllocData(SAFEARRAY *psa)
{
  HRESULT hRet = E_INVALIDARG;
  
  TRACE("(%p)\n", psa);
  
  if (psa)
  {
    ULONG ulSize = SAFEARRAY_GetCellCount(psa);

    psa->pvData = SAFEARRAY_Malloc(ulSize * psa->cbElements);

    if (psa->pvData)
    {
      hRet = S_OK;
      TRACE("%u bytes allocated for data at %p (%u objects).\n",
            ulSize * psa->cbElements, psa->pvData, ulSize);
    }
    else
      hRet = E_OUTOFMEMORY;
  }
  return hRet;
}

/*************************************************************************
 *		SafeArrayCreate (OLEAUT32.15)
 *
 * Create a new SafeArray.
 *
 * PARAMS
 *  vt        [I] Type to store in the safe array
 *  cDims     [I] Number of array dimensions
 *  rgsabound [I] Bounds of the array dimensions
 *
 * RETURNS
 *  Success: A pointer to a new array object.
 *  Failure: NULL, if any parameter is invalid or memory allocation fails.
 *
 * NOTES
 *  Win32 allows arrays with 0 sized dimensions. This bug is not reproduced
 *  in the Wine implementation.
 *  See SafeArray.
 */
SAFEARRAY* WINAPI SafeArrayCreate(VARTYPE vt, UINT cDims, SAFEARRAYBOUND *rgsabound)
{
  TRACE("(%d->%s,%d,%p)\n", vt, debugstr_vt(vt), cDims, rgsabound);

  if (vt == VT_RECORD)
    return NULL;

  return SAFEARRAY_Create(vt, cDims, rgsabound, 0);
}

/*************************************************************************
 *		SafeArrayCreateEx (OLEAUT32.15)
 *
 * Create a new SafeArray.
 *
 * PARAMS
 *  vt        [I] Type to store in the safe array
 *  cDims     [I] Number of array dimensions
 *  rgsabound [I] Bounds of the array dimensions
 *  pvExtra   [I] Extra data
 *
 * RETURNS
 *  Success: A pointer to a new array object.
 *  Failure: NULL, if any parameter is invalid or memory allocation fails.
 *
 * NOTES
 * See SafeArray.
 */
SAFEARRAY* WINAPI SafeArrayCreateEx(VARTYPE vt, UINT cDims, SAFEARRAYBOUND *rgsabound, LPVOID pvExtra)
{
  ULONG ulSize = 0;
  IRecordInfo* iRecInfo = (IRecordInfo*)pvExtra;
  SAFEARRAY* psa;
 
  TRACE("(%d->%s,%d,%p,%p)\n", vt, debugstr_vt(vt), cDims, rgsabound, pvExtra);
 
  if (vt == VT_RECORD)
  {
    if  (!iRecInfo)
      return NULL;
    IRecordInfo_GetSize(iRecInfo, &ulSize);
  }
  psa = SAFEARRAY_Create(vt, cDims, rgsabound, ulSize);

  if (pvExtra)
  {
    switch(vt)
    {
      case VT_RECORD:
        SafeArraySetRecordInfo(psa, pvExtra);
        break;
      case VT_UNKNOWN:
      case VT_DISPATCH:
        SafeArraySetIID(psa, pvExtra);
        break;
    }
  }
  return psa;
}

/************************************************************************
 *		SafeArrayCreateVector (OLEAUT32.411)
 *
 * Create a one dimensional, contiguous SafeArray.
 *
 * PARAMS
 *  vt        [I] Type to store in the safe array
 *  lLbound   [I] Lower bound of the array
 *  cElements [I] Number of elements in the array
 *
 * RETURNS
 *  Success: A pointer to a new array object.
 *  Failure: NULL, if any parameter is invalid or memory allocation fails.
 *
 * NOTES
 * See SafeArray.
 */
SAFEARRAY* WINAPI SafeArrayCreateVector(VARTYPE vt, LONG lLbound, ULONG cElements)
{
  TRACE("(%d->%s,%d,%d\n", vt, debugstr_vt(vt), lLbound, cElements);
    
  if (vt == VT_RECORD)
    return NULL;

  return SAFEARRAY_CreateVector(vt, lLbound, cElements, SAFEARRAY_GetVTSize(vt));
}

/************************************************************************
 *		SafeArrayCreateVectorEx (OLEAUT32.411)
 *
 * Create a one dimensional, contiguous SafeArray.
 *
 * PARAMS
 *  vt        [I] Type to store in the safe array
 *  lLbound   [I] Lower bound of the array
 *  cElements [I] Number of elements in the array
 *  pvExtra   [I] Extra data
 *
 * RETURNS
 *  Success: A pointer to a new array object.
 *  Failure: NULL, if any parameter is invalid or memory allocation fails.
 *
 * NOTES
 * See SafeArray.
 */
SAFEARRAY* WINAPI SafeArrayCreateVectorEx(VARTYPE vt, LONG lLbound, ULONG cElements, LPVOID pvExtra)
{
  ULONG ulSize;
  IRecordInfo* iRecInfo = (IRecordInfo*)pvExtra;
  SAFEARRAY* psa;

 TRACE("(%d->%s,%d,%d,%p\n", vt, debugstr_vt(vt), lLbound, cElements, pvExtra);
 
  if (vt == VT_RECORD)
  {
    if  (!iRecInfo)
      return NULL;
    IRecordInfo_GetSize(iRecInfo, &ulSize);
  }
  else
    ulSize = SAFEARRAY_GetVTSize(vt);

  psa = SAFEARRAY_CreateVector(vt, lLbound, cElements, ulSize);

  if (pvExtra)
  {
    switch(vt)
    {
      case VT_RECORD:
        SafeArraySetRecordInfo(psa, iRecInfo);
        break;
      case VT_UNKNOWN:
      case VT_DISPATCH:
        SafeArraySetIID(psa, pvExtra);
        break;
    }
  }
  return psa;
}

/*************************************************************************
 *		SafeArrayDestroyDescriptor (OLEAUT32.38)
 *
 * Destroy a SafeArray.
 *
 * PARAMS
 *  psa [I] SafeArray to destroy.
 *
 * RETURNS
 *  Success: S_OK. The resources used by the array are freed.
 *  Failure: An HRESULT error code indicating the error.
 *
 * NOTES
 * See SafeArray.
 */
HRESULT WINAPI SafeArrayDestroyDescriptor(SAFEARRAY *psa)
{
  TRACE("(%p)\n", psa);
    
  if (psa)
  {
    LPVOID lpv = (char*)psa - SAFEARRAY_HIDDEN_SIZE;

    if (psa->cLocks)
      return DISP_E_ARRAYISLOCKED; /* Can't destroy a locked array */

    if (psa->fFeatures & FADF_RECORD)
      SafeArraySetRecordInfo(psa, NULL);

    if (psa->fFeatures & FADF_CREATEVECTOR &&
        !(psa->fFeatures & FADF_DATADELETED))
        SAFEARRAY_DestroyData(psa, 0); /* Data not previously deleted */

    if (!SAFEARRAY_Free(lpv))
      return E_UNEXPECTED;
  }
  return S_OK;
}

/*************************************************************************
 *		SafeArrayLock (OLEAUT32.21)
 *
 * Increment the lock counter of a SafeArray.
 *
 * PARAMS
 *  psa [O] SafeArray to lock
 *
 * RETURNS
 *  Success: S_OK. The array lock is incremented.
 *  Failure: E_INVALIDARG if psa is NULL, or E_UNEXPECTED if too many locks
 *           are held on the array at once.
 *
 * NOTES
 *  In Win32 these locks are not thread safe.
 *  See SafeArray.
 */
HRESULT WINAPI SafeArrayLock(SAFEARRAY *psa)
{
  ULONG ulLocks;

  TRACE("(%p)\n", psa);
    
  if (!psa)
    return E_INVALIDARG;

  ulLocks = InterlockedIncrement( (LONG*) &psa->cLocks);

  if (ulLocks > 0xffff) /* Maximum of 16384 locks at a time */
  {
    WARN("Out of locks!\n");
    InterlockedDecrement( (LONG*) &psa->cLocks);
    return E_UNEXPECTED;
  }
  return S_OK;
}

/*************************************************************************
 *		SafeArrayUnlock (OLEAUT32.22)
 *
 * Decrement the lock counter of a SafeArray.
 *
 * PARAMS
 *  psa [O] SafeArray to unlock
 *
 * RETURNS
 *  Success: S_OK. The array lock is decremented.
 *  Failure: E_INVALIDARG if psa is NULL, or E_UNEXPECTED if no locks are
 *           held on the array.
 *
 * NOTES
 * See SafeArray.
 */
HRESULT WINAPI SafeArrayUnlock(SAFEARRAY *psa)
{
  TRACE("(%p)\n", psa);
  
  if (!psa)
    return E_INVALIDARG;

  if ((LONG)InterlockedDecrement( (LONG*) &psa->cLocks) < 0)
  {
    WARN("Unlocked but no lock held!\n");
    InterlockedIncrement( (LONG*) &psa->cLocks);
    return E_UNEXPECTED;
  }
  return S_OK;
}

/*************************************************************************
 *		SafeArrayPutElement (OLEAUT32.26)
 *
 * Put an item into a SafeArray.
 *
 * PARAMS
 *  psa       [I] SafeArray to insert into
 *  rgIndices [I] Indices to insert at
 *  pvData    [I] Data to insert
 *
 * RETURNS
 *  Success: S_OK. The item is inserted
 *  Failure: An HRESULT error code indicating the error.
 *
 * NOTES
 * See SafeArray.
 */
HRESULT WINAPI SafeArrayPutElement(SAFEARRAY *psa, LONG *rgIndices, void *pvData)
{
  HRESULT hRet;

  TRACE("(%p,%p,%p)\n", psa, rgIndices, pvData);

  if (!psa || !rgIndices)
    return E_INVALIDARG;

  hRet = SafeArrayLock(psa);

  if (SUCCEEDED(hRet))
  {
    PVOID lpvDest;

    hRet = SafeArrayPtrOfIndex(psa, rgIndices, &lpvDest);

    if (SUCCEEDED(hRet))
    {
      if (psa->fFeatures & FADF_VARIANT)
      {
        VARIANT* lpVariant = (VARIANT*)pvData;
        VARIANT* lpDest = (VARIANT*)lpvDest;

        hRet = VariantClear(lpDest);
        if (FAILED(hRet)) FIXME("VariantClear failed with 0x%x\n", hRet);
        hRet = VariantCopy(lpDest, lpVariant);
        if (FAILED(hRet)) FIXME("VariantCopy failed with 0x%x\n", hRet);
      }
      else if (psa->fFeatures & FADF_BSTR)
      {
        BSTR  lpBstr = (BSTR)pvData;
        BSTR* lpDest = (BSTR*)lpvDest;

        if (*lpDest)
         SysFreeString(*lpDest);

        *lpDest = SysAllocStringByteLen((char*)lpBstr, SysStringByteLen(lpBstr));
        if (!*lpDest)
          hRet = E_OUTOFMEMORY;
      }
      else
      {
        if (psa->fFeatures & (FADF_UNKNOWN|FADF_DISPATCH))
        {
          LPUNKNOWN  lpUnknown = (LPUNKNOWN)pvData;
          LPUNKNOWN *lpDest = (LPUNKNOWN *)lpvDest;

          if (lpUnknown)
            IUnknown_AddRef(lpUnknown);
          if (*lpDest)
            IUnknown_Release(*lpDest);
	  *lpDest = lpUnknown;
        } else {
          /* Copy the data over */
          memcpy(lpvDest, pvData, psa->cbElements);
	}
      }
    }
    SafeArrayUnlock(psa);
  }
  return hRet;
}


/*************************************************************************
 *		SafeArrayGetElement (OLEAUT32.25)
 *
 * Get an item from a SafeArray.
 *
 * PARAMS
 *  psa       [I] SafeArray to get from
 *  rgIndices [I] Indices to get from
 *  pvData    [O] Destination for data
 *
 * RETURNS
 *  Success: S_OK. The item data is returned in pvData.
 *  Failure: An HRESULT error code indicating the error.
 *
 * NOTES
 * See SafeArray.
 */
HRESULT WINAPI SafeArrayGetElement(SAFEARRAY *psa, LONG *rgIndices, void *pvData)
{
  HRESULT hRet;

  TRACE("(%p,%p,%p)\n", psa, rgIndices, pvData);
    
  if (!psa || !rgIndices || !pvData)
    return E_INVALIDARG;

  hRet = SafeArrayLock(psa);

  if (SUCCEEDED(hRet))
  {
    PVOID lpvSrc;

    hRet = SafeArrayPtrOfIndex(psa, rgIndices, &lpvSrc);

    if (SUCCEEDED(hRet))
    {
      if (psa->fFeatures & FADF_VARIANT)
      {
        VARIANT* lpVariant = (VARIANT*)lpvSrc;
        VARIANT* lpDest = (VARIANT*)pvData;

        /* The original content of pvData is ignored. */
        V_VT(lpDest) = VT_EMPTY;
        hRet = VariantCopy(lpDest, lpVariant);
	if (FAILED(hRet)) FIXME("VariantCopy failed with 0x%x\n", hRet);
      }
      else if (psa->fFeatures & FADF_BSTR)
      {
        BSTR* lpBstr = (BSTR*)lpvSrc;
        BSTR* lpDest = (BSTR*)pvData;

        if (*lpBstr)
        {
          *lpDest = SysAllocStringByteLen((char*)*lpBstr, SysStringByteLen(*lpBstr));
          if (!*lpBstr)
            hRet = E_OUTOFMEMORY;
        }
        else
          *lpDest = NULL;
      }
      else
      {
        if (psa->fFeatures & (FADF_UNKNOWN|FADF_DISPATCH))
        {
          LPUNKNOWN *lpUnknown = (LPUNKNOWN *)lpvSrc;

          if (*lpUnknown)
            IUnknown_AddRef(*lpUnknown);
        }
        /* Copy the data over */
        memcpy(pvData, lpvSrc, psa->cbElements);
      }
    }
    SafeArrayUnlock(psa);
  }
  return hRet;
}

/*************************************************************************
 *		SafeArrayGetUBound (OLEAUT32.19)
 *
 * Get the upper bound for a given SafeArray dimension
 *
 * PARAMS
 *  psa      [I] Array to get dimension upper bound from
 *  nDim     [I] The dimension number to get the upper bound of
 *  plUbound [O] Destination for the upper bound
 *
 * RETURNS
 *  Success: S_OK. plUbound contains the dimensions upper bound.
 *  Failure: An HRESULT error code indicating the error.
 *
 * NOTES
 * See SafeArray.
 */
HRESULT WINAPI SafeArrayGetUBound(SAFEARRAY *psa, UINT nDim, LONG *plUbound)
{
  TRACE("(%p,%d,%p)\n", psa, nDim, plUbound);
    
  if (!psa || !plUbound)
    return E_INVALIDARG;

  if(!nDim || nDim > psa->cDims)
    return DISP_E_BADINDEX;

  *plUbound = psa->rgsabound[psa->cDims - nDim].lLbound +
              psa->rgsabound[psa->cDims - nDim].cElements - 1;

  return S_OK;
}

/*************************************************************************
 *		SafeArrayGetLBound (OLEAUT32.20)
 *
 * Get the lower bound for a given SafeArray dimension
 *
 * PARAMS
 *  psa      [I] Array to get dimension lower bound from
 *  nDim     [I] The dimension number to get the lowe bound of
 *  plLbound [O] Destination for the lower bound
 *
 * RETURNS
 *  Success: S_OK. plUbound contains the dimensions lower bound.
 *  Failure: An HRESULT error code indicating the error.
 *
 * NOTES
 * See SafeArray.
 */
HRESULT WINAPI SafeArrayGetLBound(SAFEARRAY *psa, UINT nDim, LONG *plLbound)
{
  TRACE("(%p,%d,%p)\n", psa, nDim, plLbound);

  if (!psa || !plLbound)
    return E_INVALIDARG;

  if(!nDim || nDim > psa->cDims)
    return DISP_E_BADINDEX;

  *plLbound = psa->rgsabound[psa->cDims - nDim].lLbound;
  return S_OK;
}

/*************************************************************************
 *		SafeArrayGetDim (OLEAUT32.17)
 *
 * Get the number of dimensions in a SafeArray.
 *
 * PARAMS
 *  psa [I] Array to get the dimensions of
 *
 * RETURNS
 *  The number of array dimensions in psa, or 0 if psa is NULL.
 *
 * NOTES
 * See SafeArray.
 */
UINT WINAPI SafeArrayGetDim(SAFEARRAY *psa)
{
  TRACE("(%p) returning %d\n", psa, psa ? psa->cDims : 0u);  
  return psa ? psa->cDims : 0;
}

/*************************************************************************
 *		SafeArrayGetElemsize (OLEAUT32.18)
 *
 * Get the size of an element in a SafeArray.
 *
 * PARAMS
 *  psa [I] Array to get the element size from
 *
 * RETURNS
 *  The size of a single element in psa, or 0 if psa is NULL.
 *
 * NOTES
 * See SafeArray.
 */
UINT WINAPI SafeArrayGetElemsize(SAFEARRAY *psa)
{
  TRACE("(%p) returning %d\n", psa, psa ? psa->cbElements : 0u);
  return psa ? psa->cbElements : 0;
}

/*************************************************************************
 *		SafeArrayAccessData (OLEAUT32.23)
 *
 * Lock a SafeArray and return a pointer to its data.
 *
 * PARAMS
 *  psa     [I] Array to get the data pointer from
 *  ppvData [O] Destination for the arrays data pointer
 *
 * RETURNS
 *  Success: S_OK. ppvData contains the arrays data pointer, and the array
 *           is locked.
 *  Failure: An HRESULT error code indicating the error.
 *
 * NOTES
 * See SafeArray.
 */
HRESULT WINAPI SafeArrayAccessData(SAFEARRAY *psa, void **ppvData)
{
  TRACE("(%p,%p)\n", psa, ppvData);

  if(!psa || !ppvData)
    return E_INVALIDARG;

  if (SUCCEEDED(SafeArrayLock(psa)))
  {
    *ppvData = psa->pvData;
    return S_OK;
  }
  *ppvData = NULL;
  return E_UNEXPECTED;
}


/*************************************************************************
 *		SafeArrayUnaccessData (OLEAUT32.24)
 *
 * Unlock a SafeArray after accessing its data.
 *
 * PARAMS
 *  psa     [I] Array to unlock
 *
 * RETURNS
 *  Success: S_OK. The array is unlocked.
 *  Failure: An HRESULT error code indicating the error.
 *
 * NOTES
 * See SafeArray.
 */
HRESULT WINAPI SafeArrayUnaccessData(SAFEARRAY *psa)
{
  TRACE("(%p)\n", psa);
  return SafeArrayUnlock(psa);
}

/************************************************************************
 *		SafeArrayPtrOfIndex (OLEAUT32.148)
 *
 * Get the address of an item in a SafeArray.
 *
 * PARAMS
 *  psa       [I] Array to get the items address from
 *  rgIndices [I] Index of the item in the array
 *  ppvData   [O] Destination for item address
 *
 * RETURNS
 *  Success: S_OK. ppvData contains a pointer to the item.
 *  Failure: An HRESULT error code indicating the error.
 *
 * NOTES
 *  This function does not lock the array.
 *
 * NOTES
 * See SafeArray.
 */
HRESULT WINAPI SafeArrayPtrOfIndex(SAFEARRAY *psa, LONG *rgIndices, void **ppvData)
{
  USHORT dim;
  ULONG cell = 0, dimensionSize = 1;
  SAFEARRAYBOUND* psab;
  LONG c1;

  TRACE("(%p,%p,%p)\n", psa, rgIndices, ppvData);
  
  /* The general formula for locating the cell number of an entry in an n
   * dimensional array (where cn = coordinate in dimension dn) is:
   *
   * c1 + c2 * sizeof(d1) + c3 * sizeof(d2) ... + cn * sizeof(c(n-1))
   *
   * We calculate the size of the last dimension at each step through the
   * dimensions to avoid recursing to calculate the last dimensions size.
   */
  if (!psa || !rgIndices || !ppvData)
    return E_INVALIDARG;

  psab = psa->rgsabound + psa->cDims - 1;
  c1 = *rgIndices++;

  if (c1 < psab->lLbound || c1 >= psab->lLbound + (LONG)psab->cElements)
    return DISP_E_BADINDEX; /* Initial index out of bounds */

  for (dim = 1; dim < psa->cDims; dim++)
  {
    dimensionSize *= psab->cElements;

    psab--;

    if (!psab->cElements ||
        *rgIndices < psab->lLbound ||
        *rgIndices >= psab->lLbound + (LONG)psab->cElements)
    return DISP_E_BADINDEX; /* Index out of bounds */

    cell += (*rgIndices - psab->lLbound) * dimensionSize;
    rgIndices++;
  }

  cell += (c1 - psa->rgsabound[psa->cDims - 1].lLbound);

  *ppvData = (char*)psa->pvData + cell * psa->cbElements;
  return S_OK;
}

/************************************************************************
 *		SafeArrayDestroyData (OLEAUT32.39)
 *
 * Destroy the data associated with a SafeArray.
 *
 * PARAMS
 *  psa [I] Array to delete the data from
 *
 * RETURNS
 *  Success: S_OK. All items and the item data are freed.
 *  Failure: An HRESULT error code indicating the error.
 *
 * NOTES
 * See SafeArray.
 */
HRESULT WINAPI SafeArrayDestroyData(SAFEARRAY *psa)
{
  TRACE("(%p)\n", psa);
  
  if (!psa)
    return E_INVALIDARG;

  if (psa->cLocks)
    return DISP_E_ARRAYISLOCKED; /* Can't delete a locked array */

  /* Delete the actual item data */
  if (FAILED(SAFEARRAY_DestroyData(psa, 0)))
    return E_UNEXPECTED;

  if (psa->pvData)
  {
    if (psa->fFeatures & FADF_STATIC)
    {
      ZeroMemory(psa->pvData, SAFEARRAY_GetCellCount(psa) * psa->cbElements);
      return S_OK;
    }
    /* If this is not a vector, free the data memory block */
    if (!(psa->fFeatures & FADF_CREATEVECTOR))
    {
      if (!SAFEARRAY_Free(psa->pvData))
        return E_UNEXPECTED;
      psa->pvData = NULL;
    }
    else
      psa->fFeatures |= FADF_DATADELETED; /* Mark the data deleted */

  }
  return S_OK;
}

/************************************************************************
 *		SafeArrayCopyData (OLEAUT32.412)
 *
 * Copy all data from one SafeArray to another.
 *
 * PARAMS
 *  psaSource [I] Source for copy
 *  psaTarget [O] Destination for copy
 *
 * RETURNS
 *  Success: S_OK. psaTarget contains a copy of psaSource.
 *  Failure: An HRESULT error code indicating the error.
 *
 * NOTES
 *  The two arrays must have the same number of dimensions and elements.
 *
 * NOTES
 * See SafeArray.
 */
HRESULT WINAPI SafeArrayCopyData(SAFEARRAY *psaSource, SAFEARRAY *psaTarget)
{
  int dim;

  TRACE("(%p,%p)\n", psaSource, psaTarget);
  
  if (!psaSource || !psaTarget ||
      psaSource->cDims != psaTarget->cDims ||
      psaSource->cbElements != psaTarget->cbElements)
    return E_INVALIDARG;

  /* Each dimension must be the same size */
  for (dim = psaSource->cDims - 1; dim >= 0 ; dim--)
    if (psaSource->rgsabound[dim].cElements !=
       psaTarget->rgsabound[dim].cElements)
      return E_INVALIDARG;

  if (SUCCEEDED(SAFEARRAY_DestroyData(psaTarget, 0)) &&
      SUCCEEDED(SAFEARRAY_CopyData(psaSource, psaTarget)))
    return S_OK;
  return E_UNEXPECTED;
}

/************************************************************************
 *		SafeArrayDestroy (OLEAUT32.16)
 *
 * Destroy a SafeArray.
 *
 * PARAMS
 *  psa [I] Array to destroy
 *
 * RETURNS
 *  Success: S_OK. All resources used by the array are freed.
 *  Failure: An HRESULT error code indicating the error.
 *
 * NOTES
 * See SafeArray.
 */
HRESULT WINAPI SafeArrayDestroy(SAFEARRAY *psa)
{
  TRACE("(%p)\n", psa);

  if(!psa)
    return S_OK;

  if(psa->cLocks > 0)
    return DISP_E_ARRAYISLOCKED;

  /* Native doesn't check to see if the free succeeds */
  SafeArrayDestroyData(psa);
  SafeArrayDestroyDescriptor(psa);
  return S_OK;
}

/************************************************************************
 *		SafeArrayCopy (OLEAUT32.27)
 *
 * Make a duplicate of a SafeArray.
 *
 * PARAMS
 *  psa     [I] Source for copy
 *  ppsaOut [O] Destination for new copy
 *
 * RETURNS
 *  Success: S_OK. ppsaOut contains a copy of the array.
 *  Failure: An HRESULT error code indicating the error.
 *
 * NOTES
 * See SafeArray.
 */
HRESULT WINAPI SafeArrayCopy(SAFEARRAY *psa, SAFEARRAY **ppsaOut)
{
  HRESULT hRet;

  TRACE("(%p,%p)\n", psa, ppsaOut);

  if (!ppsaOut)
    return E_INVALIDARG;

  *ppsaOut = NULL;

  if (!psa)
    return S_OK; /* Handles copying of NULL arrays */

  if (!psa->cbElements)
  {
    ERR("not copying an array of 0 elements\n");
    return E_INVALIDARG;
  }

  if (psa->fFeatures & (FADF_RECORD|FADF_HAVEIID|FADF_HAVEVARTYPE))
  {
    VARTYPE vt;
    if (FAILED(SafeArrayGetVartype(psa, &vt)))
      hRet = E_UNEXPECTED;
    else
      hRet = SafeArrayAllocDescriptorEx(vt, psa->cDims, ppsaOut);
  }
  else
  {
    hRet = SafeArrayAllocDescriptor(psa->cDims, ppsaOut);
    if (SUCCEEDED(hRet))
    {
      (*ppsaOut)->fFeatures = psa->fFeatures & ~FADF_CREATEVECTOR;
      (*ppsaOut)->cbElements = psa->cbElements;
    }
  }

  if (SUCCEEDED(hRet))
  {
    /* Copy dimension bounds */
    memcpy((*ppsaOut)->rgsabound, psa->rgsabound, psa->cDims * sizeof(SAFEARRAYBOUND));

    (*ppsaOut)->pvData = SAFEARRAY_Malloc(SAFEARRAY_GetCellCount(psa) * psa->cbElements);

    if ((*ppsaOut)->pvData)
    {
      hRet = SAFEARRAY_CopyData(psa, *ppsaOut);
 
      if (SUCCEEDED(hRet))
        return hRet;

      SAFEARRAY_Free((*ppsaOut)->pvData);
    }
    SafeArrayDestroyDescriptor(*ppsaOut);
  }
  *ppsaOut = NULL;
  return hRet;
}

/************************************************************************
 *		SafeArrayRedim (OLEAUT32.40)
 *
 * Changes the characteristics of the last dimension of a SafeArray
 *
 * PARAMS
 *  psa      [I] Array to change
 *  psabound [I] New bound details for the last dimension
 *
 * RETURNS
 *  Success: S_OK. psa is updated to reflect the new bounds.
 *  Failure: An HRESULT error code indicating the error.
 *
 * NOTES
 * See SafeArray.
 */
HRESULT WINAPI SafeArrayRedim(SAFEARRAY *psa, SAFEARRAYBOUND *psabound)
{
  SAFEARRAYBOUND *oldBounds;

  TRACE("(%p,%p)\n", psa, psabound);
  
  if (!psa || psa->fFeatures & FADF_FIXEDSIZE || !psabound)
    return E_INVALIDARG;

  if (psa->cLocks > 0)
    return DISP_E_ARRAYISLOCKED;

  if (FAILED(SafeArrayLock(psa)))
    return E_UNEXPECTED;

  oldBounds = psa->rgsabound;
  oldBounds->lLbound = psabound->lLbound;

  if (psabound->cElements != oldBounds->cElements)
  {
    if (psabound->cElements < oldBounds->cElements)
    {
      /* Shorten the final dimension. */
      ULONG ulStartCell = psabound->cElements *
                          (SAFEARRAY_GetCellCount(psa) / oldBounds->cElements);
      SAFEARRAY_DestroyData(psa, ulStartCell);
    }
    else
    {
      /* Lengthen the final dimension */
      ULONG ulOldSize, ulNewSize;
      PVOID pvNewData;

      ulOldSize = SAFEARRAY_GetCellCount(psa) * psa->cbElements;
      if (ulOldSize)
        ulNewSize = (ulOldSize / oldBounds->cElements) * psabound->cElements;
      else {
	int oldelems = oldBounds->cElements;
	oldBounds->cElements = psabound->cElements;
        ulNewSize = SAFEARRAY_GetCellCount(psa) * psa->cbElements;
	oldBounds->cElements = oldelems;
      }

      if (!(pvNewData = SAFEARRAY_Malloc(ulNewSize)))
      {
        SafeArrayUnlock(psa);
        return E_UNEXPECTED;
      }

      memcpy(pvNewData, psa->pvData, ulOldSize);
      SAFEARRAY_Free(psa->pvData);
      psa->pvData = pvNewData;
    }
    oldBounds->cElements = psabound->cElements;
  }

  SafeArrayUnlock(psa);
  return S_OK;
}

/************************************************************************
 *		SafeArrayGetVartype (OLEAUT32.77)
 *
 * Get the type of the items in a SafeArray.
 *
 * PARAMS
 *  psa [I] Array to get the type from
 *  pvt [O] Destination for the type
 *
 * RETURNS
 *  Success: S_OK. pvt contains the type of the items.
 *  Failure: An HRESULT error code indicating the error.
 *
 * NOTES
 * See SafeArray.
 */
HRESULT WINAPI SafeArrayGetVartype(SAFEARRAY* psa, VARTYPE* pvt)
{
  TRACE("(%p,%p)\n", psa, pvt);

  if (!psa || !pvt)
    return E_INVALIDARG;

  if (psa->fFeatures & FADF_RECORD)
    *pvt = VT_RECORD;
  else if (psa->fFeatures & FADF_HAVEIID)
    *pvt = VT_UNKNOWN;
  else if (psa->fFeatures & FADF_HAVEVARTYPE)
  {
    VARTYPE vt = SAFEARRAY_GetHiddenDWORD(psa);
    *pvt = vt;
  }
  else
    return E_INVALIDARG;

  return S_OK;
}

/************************************************************************
 *		SafeArraySetRecordInfo (OLEAUT32.@)
 *
 * Set the record info for a SafeArray.
 *
 * PARAMS
 *  psa    [I] Array to set the record info for
 *  pRinfo [I] Record info
 *
 * RETURNS
 *  Success: S_OK. The record info is stored with the array.
 *  Failure: An HRESULT error code indicating the error.
 *
 * NOTES
 * See SafeArray.
 */
HRESULT WINAPI SafeArraySetRecordInfo(SAFEARRAY *psa, IRecordInfo *pRinfo)
{
  IRecordInfo** dest = (IRecordInfo**)psa;

  TRACE("(%p,%p)\n", psa, pRinfo);
  
  if (!psa || !(psa->fFeatures & FADF_RECORD))
    return E_INVALIDARG;

  if (pRinfo)
    IRecordInfo_AddRef(pRinfo);

  if (dest[-1])
    IRecordInfo_Release(dest[-1]);

  dest[-1] = pRinfo;
  return S_OK;
}

/************************************************************************
 *		SafeArrayGetRecordInfo (OLEAUT32.@)
 *
 * Get the record info from a SafeArray.
 *
 * PARAMS
 *  psa    [I] Array to get the record info from
 *  pRinfo [O] Destination for the record info
 *
 * RETURNS
 *  Success: S_OK. pRinfo contains the record info, or NULL if there was none.
 *  Failure: An HRESULT error code indicating the error.
 *
 * NOTES
 * See SafeArray.
 */
HRESULT WINAPI SafeArrayGetRecordInfo(SAFEARRAY *psa, IRecordInfo **pRinfo)
{
  IRecordInfo** src = (IRecordInfo**)psa;

  TRACE("(%p,%p)\n", psa, pRinfo);

  if (!psa || !pRinfo || !(psa->fFeatures & FADF_RECORD))
    return E_INVALIDARG;

  *pRinfo = src[-1];

  if (*pRinfo)
    IRecordInfo_AddRef(*pRinfo);
  return S_OK;
}

/************************************************************************
 *		SafeArraySetIID (OLEAUT32.@)
 *
 * Set the IID for a SafeArray.
 *
 * PARAMS
 *  psa  [I] Array to set the IID from
 *  guid [I] IID
 *
 * RETURNS
 *  Success: S_OK. The IID is stored with the array
 *  Failure: An HRESULT error code indicating the error.
 *
 * NOTES
 * See SafeArray.
 */
HRESULT WINAPI SafeArraySetIID(SAFEARRAY *psa, REFGUID guid)
{
  GUID* dest = (GUID*)psa;

  TRACE("(%p,%s)\n", psa, debugstr_guid(guid));

  if (!psa || !guid || !(psa->fFeatures & FADF_HAVEIID))
    return E_INVALIDARG;

  dest[-1] = *guid;
  return S_OK;
}

/************************************************************************
 *		SafeArrayGetIID (OLEAUT32.@)
 *
 * Get the IID from a SafeArray.
 *
 * PARAMS
 *  psa   [I] Array to get the ID from
 *  pGuid [O] Destination for the IID
 *
 * RETURNS
 *  Success: S_OK. pRinfo contains the IID, or NULL if there was none.
 *  Failure: An HRESULT error code indicating the error.
 *
 * NOTES
 * See SafeArray.
 */
HRESULT WINAPI SafeArrayGetIID(SAFEARRAY *psa, GUID *pGuid)
{
  GUID* src = (GUID*)psa;

  TRACE("(%p,%p)\n", psa, pGuid);

  if (!psa || !pGuid || !(psa->fFeatures & FADF_HAVEIID))
    return E_INVALIDARG;

  *pGuid = src[-1];
  return S_OK;
}

/************************************************************************
 *		VectorFromBstr (OLEAUT32.@)
 *
 * Create a SafeArray Vector from the bytes of a BSTR.
 *
 * PARAMS
 *  bstr [I] String to get bytes from
 *  ppsa [O] Destination for the array
 *
 * RETURNS
 *  Success: S_OK. ppsa contains the strings bytes as a VT_UI1 array.
 *  Failure: An HRESULT error code indicating the error.
 *
 * NOTES
 * See SafeArray.
 */
HRESULT WINAPI VectorFromBstr(BSTR bstr, SAFEARRAY **ppsa)
{
  SAFEARRAYBOUND sab;

  TRACE("(%p,%p)\n", bstr, ppsa);
  
  if (!ppsa)
    return E_INVALIDARG;

  sab.lLbound = 0;
  sab.cElements = SysStringByteLen(bstr);

  *ppsa = SAFEARRAY_Create(VT_UI1, 1, &sab, 0);

  if (*ppsa)
  {
    memcpy((*ppsa)->pvData, bstr, sab.cElements);
    return S_OK;
  }
  return E_OUTOFMEMORY;
}

/************************************************************************
 *		BstrFromVector (OLEAUT32.@)
 *
 * Create a BSTR from a SafeArray.
 *
 * PARAMS
 *  psa   [I] Source array
 *  pbstr [O] Destination for output BSTR
 *
 * RETURNS
 *  Success: S_OK. pbstr contains the arrays data.
 *  Failure: An HRESULT error code indicating the error.
 *
 * NOTES
 *  psa must be a 1 dimensional array of a 1 byte type.
 *
 * NOTES
 * See SafeArray.
 */
HRESULT WINAPI BstrFromVector(SAFEARRAY *psa, BSTR *pbstr)
{
  TRACE("(%p,%p)\n", psa, pbstr);

  if (!pbstr)
    return E_INVALIDARG;

  *pbstr = NULL;

  if (!psa || psa->cbElements != 1 || psa->cDims != 1)
    return E_INVALIDARG;

  *pbstr = SysAllocStringByteLen(psa->pvData, psa->rgsabound[0].cElements);
  if (!*pbstr)
    return E_OUTOFMEMORY;
  return S_OK;
}
