/*
 * Global memory implementation of ILockBytes.
 *
 * Copyright 1999 Thuy Nguyen
 *
 * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "config.h"

#include <assert.h>
#include <string.h>

#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include "windef.h"
#include "wine/winbase16.h"
#include "objbase.h"
#include "ole2.h"
#include "winbase.h"
#include "winerror.h"

#include "ifs.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(ole);

/******************************************************************************
 * HGLOBALLockBytesImpl16 definition.
 *
 * This class imlements the ILockBytes inteface and represents a byte array
 * object supported by an HGLOBAL pointer.
 */
struct HGLOBALLockBytesImpl16
{
  /*
   * Needs to be the first item in the stuct
   * since we want to cast this in an ILockBytes pointer
   */
  ICOM_VFIELD(ILockBytes16);
  ULONG        ref;

  /*
   * Support for the LockBytes object
   */
  HGLOBAL16 supportHandle;

  /*
   * This flag is TRUE if the HGLOBAL is destroyed when the object
   * is finally released.
   */
  BOOL    deleteOnRelease;
  /*
   * Helper variable that contains the size of the byte array
   */
  ULARGE_INTEGER     byteArraySize;
};

typedef struct HGLOBALLockBytesImpl16 HGLOBALLockBytesImpl16;

HGLOBALLockBytesImpl16* HGLOBALLockBytesImpl16_Construct(
    HGLOBAL16  hGlobal,
    BOOL16     fDeleteOnRelease);

void HGLOBALLockBytesImpl16_Destroy(HGLOBALLockBytesImpl16* This);

HRESULT WINAPI HGLOBALLockBytesImpl16_QueryInterface(
    ILockBytes16* iface,
    REFIID        riid,        /* [in] */
    void**        ppvObject);  /* [out][iid_is] */

ULONG WINAPI HGLOBALLockBytesImpl16_AddRef(
    ILockBytes16* iface);

ULONG WINAPI HGLOBALLockBytesImpl16_Release(
    ILockBytes16* iface);

HRESULT WINAPI HGLOBALLockBytesImpl16_ReadAt(
    ILockBytes16*  iface,
    ULARGE_INTEGER ulOffset,  /* [in] */
    void*          pv,        /* [out][length_is][size_is] */
    ULONG          cb,        /* [in] */
    ULONG*         pcbRead);  /* [out] */

HRESULT WINAPI HGLOBALLockBytesImpl16_WriteAt(
    ILockBytes16*  iface,
    ULARGE_INTEGER ulOffset,    /* [in] */
    const void*    pv,          /* [in][size_is] */
    ULONG          cb,          /* [in] */
    ULONG*         pcbWritten); /* [out] */

HRESULT WINAPI HGLOBALLockBytesImpl16_Flush(
    ILockBytes16*   iface);

HRESULT WINAPI HGLOBALLockBytesImpl16_SetSize(
    ILockBytes16*   iface,
    ULARGE_INTEGER  libNewSize);  /* [in] */

HRESULT WINAPI HGLOBALLockBytesImpl16_LockRegion(
    ILockBytes16*  iface,
    ULARGE_INTEGER libOffset,   /* [in] */
    ULARGE_INTEGER cb,          /* [in] */
    DWORD          dwLockType); /* [in] */

HRESULT WINAPI HGLOBALLockBytesImpl16_UnlockRegion(
    ILockBytes16*  iface,
    ULARGE_INTEGER libOffset,   /* [in] */
    ULARGE_INTEGER cb,          /* [in] */
    DWORD          dwLockType); /* [in] */

HRESULT WINAPI HGLOBALLockBytesImpl16_Stat(
    ILockBytes16*  iface,
    STATSTG16*     pstatstg,     /* [out] */
    DWORD          grfStatFlag); /* [in]  */

/******************************************************************************
 *
 * HGLOBALLockBytesImpl16 implementation
 *
 */

/******************************************************************************
 * This is the constructor for the HGLOBALLockBytesImpl16 class.
 *
 * Params:
 *    hGlobal          - Handle that will support the stream. can be NULL.
 *    fDeleteOnRelease - Flag set to TRUE if the HGLOBAL16 will be released
 *                       when the IStream object is destroyed.
 */
HGLOBALLockBytesImpl16*
HGLOBALLockBytesImpl16_Construct(HGLOBAL16 hGlobal,
				 BOOL16 fDeleteOnRelease)
{
  HGLOBALLockBytesImpl16* newLockBytes;

  static ICOM_VTABLE(ILockBytes16) vt16;
  static SEGPTR msegvt16;
  HMODULE16 hcomp = GetModuleHandle16("OLE2");


  TRACE("(%x,%d)\n",hGlobal,fDeleteOnRelease);
  newLockBytes = HeapAlloc(GetProcessHeap(), 0, sizeof(HGLOBALLockBytesImpl16));
  if (newLockBytes == NULL)
    return NULL;

  /*
   * Set up the virtual function table and reference count.
   */
  if (!msegvt16)
  {
#define VTENT(x) vt16.x = (void*)GetProcAddress16(hcomp,"HGLOBALLockBytesImpl16_"#x);assert(vt16.x)
      VTENT(QueryInterface);
      VTENT(AddRef);
      VTENT(Release);
      VTENT(ReadAt);
      VTENT(WriteAt);
      VTENT(Flush);
      VTENT(SetSize);
      VTENT(LockRegion);
      VTENT(UnlockRegion);
#undef VTENT
      msegvt16 = MapLS( &vt16 );
  }
  newLockBytes->lpVtbl	= (ICOM_VTABLE(ILockBytes16)*)msegvt16;
  newLockBytes->ref	= 0;
  /*
   * Initialize the support.
   */
  newLockBytes->supportHandle = hGlobal;
  newLockBytes->deleteOnRelease = fDeleteOnRelease;

  /*
   * This method will allocate a handle if one is not supplied.
   */
  if (newLockBytes->supportHandle == 0)
    newLockBytes->supportHandle = GlobalAlloc16(GMEM_MOVEABLE | GMEM_NODISCARD, 0);

  /*
   * Initialize the size of the array to the size of the handle.
   */
  newLockBytes->byteArraySize.s.HighPart = 0;
  newLockBytes->byteArraySize.s.LowPart  = GlobalSize16(
					    newLockBytes->supportHandle);

  return (HGLOBALLockBytesImpl16*)MapLS(newLockBytes);
}

/******************************************************************************
 * This is the destructor of the HGLOBALStreamImpl class.
 *
 * This method will clean-up all the resources used-up by the given
 * HGLOBALLockBytesImpl16 class. The pointer passed-in to this function will be
 * freed and will not be valid anymore.
 */
void HGLOBALLockBytesImpl16_Destroy(HGLOBALLockBytesImpl16* This)
{
  TRACE("()\n");
  /*
   * Release the HGlobal if the constructor asked for that.
   */
  if (This->deleteOnRelease)
  {
    GlobalFree16(This->supportHandle);
    This->supportHandle = 0;
  }

  /*
   * Finally, free the memory used-up by the class.
   */
  HeapFree(GetProcessHeap(), 0, This);
}

/******************************************************************************
 * This implements the IUnknown method QueryInterface for this
 * class
 */
HRESULT WINAPI HGLOBALLockBytesImpl16_QueryInterface(
      ILockBytes16*  iface,	/* [in] SEGPTR */
      REFIID       riid,        /* [in] */
      void**       ppvObject)   /* [out][iid_is] (ptr to SEGPTR!) */
{
  HGLOBALLockBytesImpl16* const This=(HGLOBALLockBytesImpl16*)MapSL((SEGPTR)iface);

  TRACE("(%p,%s,%p)\n",iface,debugstr_guid(riid),ppvObject);
  /*
   * Perform a sanity check on the parameters.
   */
  if (ppvObject==0)
    return E_INVALIDARG;

  /*
   * Initialize the return parameter.
   */
  *ppvObject = 0;
  /*
   * Compare the riid with the interface IDs implemented by this object.
   */
  if (	!memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) ||
        !memcmp(&IID_ILockBytes, riid, sizeof(IID_ILockBytes))
  )
    *ppvObject = (void*)iface;

  /*
   * Check that we obtained an interface.
   */
  if ((*ppvObject)==0)
    return E_NOINTERFACE;

  /*
   * Query Interface always increases the reference count by one when it is
   * successful
   */
  HGLOBALLockBytesImpl16_AddRef((ILockBytes16*)This);

  return S_OK;
}

/******************************************************************************
 * This implements the IUnknown method AddRef for this
 * class
 */
ULONG WINAPI HGLOBALLockBytesImpl16_AddRef(ILockBytes16* iface)
{
  HGLOBALLockBytesImpl16* const This=(HGLOBALLockBytesImpl16*)iface;

  TRACE("(%p)\n",This);

  This->ref++;

  return This->ref;
}

/******************************************************************************
 * This implements the IUnknown method Release for this
 * class
 */
ULONG WINAPI HGLOBALLockBytesImpl16_Release(ILockBytes16* iface)
{
  HGLOBALLockBytesImpl16* const This=(HGLOBALLockBytesImpl16*)iface;

  ULONG newRef;
  TRACE("(%p)\n",This);

  This->ref--;

  newRef = This->ref;

  /*
   * If the reference count goes down to 0, perform suicide.
   */
  if (newRef==0)
    HGLOBALLockBytesImpl16_Destroy(This);
  return newRef;
}

/******************************************************************************
 * This method is part of the ILockBytes interface.
 *
 * It reads a block of information from the byte array at the specified
 * offset.
 *
 * See the documentation of ILockBytes for more info.
 */
HRESULT WINAPI HGLOBALLockBytesImpl16_ReadAt(
      ILockBytes16*  iface,
      ULARGE_INTEGER ulOffset,  /* [in] */
      void*          pv,        /* [out][length_is][size_is] */
      ULONG          cb,        /* [in] */
      ULONG*         pcbRead)   /* [out] */
{
  HGLOBALLockBytesImpl16* const This=(HGLOBALLockBytesImpl16*)iface;

  void* supportBuffer;
  ULONG bytesReadBuffer = 0;
  ULONG bytesToReadFromBuffer;

  TRACE("(%p,%ld,%p,%ld,%p)\n",This,ulOffset.s.LowPart,pv,cb,pcbRead);
  /*
   * If the caller is not interested in the number of bytes read,
   * we use another buffer to avoid "if" statements in the code.
   */
  if (pcbRead == 0)
    pcbRead = &bytesReadBuffer;

  /*
   * Make sure the offset is valid.
   */
  if (ulOffset.s.LowPart > This->byteArraySize.s.LowPart)
    return E_FAIL;

  /*
   * Using the known size of the array, calculate the number of bytes
   * to read.
   */
  bytesToReadFromBuffer = min(This->byteArraySize.s.LowPart -
                              ulOffset.s.LowPart, cb);

  /*
   * Lock the buffer in position and copy the data.
   */
  supportBuffer = GlobalLock16(This->supportHandle);

  memcpy(pv,
         (char *) supportBuffer + ulOffset.s.LowPart,
         bytesToReadFromBuffer);

  /*
   * Return the number of bytes read.
   */
  *pcbRead = bytesToReadFromBuffer;

  /*
   * Cleanup
   */
  GlobalUnlock16(This->supportHandle);

  /*
   * The function returns S_OK if the specified number of bytes were read
   * or the end of the array was reached.
   * It returns STG_E_READFAULT if the number of bytes to read does not equal
   * the number of bytes actually read.
   */
  if(*pcbRead == cb)
    return S_OK;

  return STG_E_READFAULT;
}

/******************************************************************************
 * This method is part of the ILockBytes interface.
 *
 * It writes the specified bytes at the specified offset.
 * position. If the array is too small, it will be resized.
 *
 * See the documentation of ILockBytes for more info.
 */
HRESULT WINAPI HGLOBALLockBytesImpl16_WriteAt(
      ILockBytes16*  iface,
      ULARGE_INTEGER ulOffset,    /* [in] */
      const void*    pv,          /* [in][size_is] */
      ULONG          cb,          /* [in] */
      ULONG*         pcbWritten)  /* [out] */
{
  HGLOBALLockBytesImpl16* const This=(HGLOBALLockBytesImpl16*)iface;

  void*          supportBuffer;
  ULARGE_INTEGER newSize;
  ULONG          bytesWritten = 0;

  TRACE("(%p,%ld,%p,%ld,%p)\n",This,ulOffset.s.LowPart,pv,cb,pcbWritten);
  /*
   * If the caller is not interested in the number of bytes written,
   * we use another buffer to avoid "if" statements in the code.
   */
  if (pcbWritten == 0)
    pcbWritten = &bytesWritten;

  if (cb == 0)
    return S_OK;

  newSize.s.HighPart = 0;
  newSize.s.LowPart = ulOffset.s.LowPart + cb;

  /*
   * Verify if we need to grow the stream
   */
  if (newSize.s.LowPart > This->byteArraySize.s.LowPart)
  {
    /* grow stream */
    if (HGLOBALLockBytesImpl16_SetSize(iface, newSize) == STG_E_MEDIUMFULL)
      return STG_E_MEDIUMFULL;
  }

  /*
   * Lock the buffer in position and copy the data.
   */
  supportBuffer = GlobalLock16(This->supportHandle);

  memcpy((char *) supportBuffer + ulOffset.s.LowPart, pv, cb);

  /*
   * Return the number of bytes written.
   */
  *pcbWritten = cb;

  /*
   * Cleanup
   */
  GlobalUnlock16(This->supportHandle);

  return S_OK;
}

/******************************************************************************
 * This method is part of the ILockBytes interface.
 *
 * See the documentation of ILockBytes for more info.
 */
HRESULT WINAPI HGLOBALLockBytesImpl16_Flush(ILockBytes16* iface)
{
  TRACE("(%p)\n",iface);
  return S_OK;
}

/******************************************************************************
 * This method is part of the ILockBytes interface.
 *
 * It will change the size of the byte array.
 *
 * See the documentation of ILockBytes for more info.
 */
HRESULT WINAPI HGLOBALLockBytesImpl16_SetSize(
      ILockBytes16*   iface,
      ULARGE_INTEGER  libNewSize)   /* [in] */
{
  HGLOBALLockBytesImpl16* const This=(HGLOBALLockBytesImpl16*)iface;

  TRACE("(%p,%ld)\n",This,libNewSize.s.LowPart);
  /*
   * As documented.
   */
  if (libNewSize.s.HighPart != 0)
    return STG_E_INVALIDFUNCTION;

  if (This->byteArraySize.s.LowPart == libNewSize.s.LowPart)
    return S_OK;

  /*
   * Re allocate the HGlobal to fit the new size of the stream.
   */
  This->supportHandle = GlobalReAlloc16(This->supportHandle,
                                      libNewSize.s.LowPart,
                                      0);

  if (This->supportHandle == 0)
    return STG_E_MEDIUMFULL;

  This->byteArraySize.s.LowPart = libNewSize.s.LowPart;

  return S_OK;
}

/******************************************************************************
 * This method is part of the ILockBytes interface.
 *
 * The global memory implementation of ILockBytes does not support locking.
 *
 * See the documentation of ILockBytes for more info.
 */
HRESULT WINAPI HGLOBALLockBytesImpl16_LockRegion(
      ILockBytes16*  iface,
      ULARGE_INTEGER libOffset,   /* [in] */
      ULARGE_INTEGER cb,          /* [in] */
      DWORD          dwLockType)  /* [in] */
{
  return STG_E_INVALIDFUNCTION;
}

/******************************************************************************
 * This method is part of the ILockBytes interface.
 *
 * The global memory implementation of ILockBytes does not support locking.
 *
 * See the documentation of ILockBytes for more info.
 */
HRESULT WINAPI HGLOBALLockBytesImpl16_UnlockRegion(
      ILockBytes16*  iface,
      ULARGE_INTEGER libOffset,   /* [in] */
      ULARGE_INTEGER cb,          /* [in] */
      DWORD          dwLockType)  /* [in] */
{
  return STG_E_INVALIDFUNCTION;
}

/******************************************************************************
 * This method is part of the ILockBytes interface.
 *
 * This method returns information about the current
 * byte array object.
 *
 * See the documentation of ILockBytes for more info.
 */
HRESULT WINAPI HGLOBALLockBytesImpl16_Stat(
      ILockBytes16*iface,
      STATSTG16*   pstatstg,     /* [out] */
      DWORD        grfStatFlag)  /* [in] */
{
  HGLOBALLockBytesImpl16* const This=(HGLOBALLockBytesImpl16*)iface;

  memset(pstatstg, 0, sizeof(STATSTG16));

  pstatstg->pwcsName = NULL;
  pstatstg->type     = STGTY_LOCKBYTES;
  pstatstg->cbSize   = This->byteArraySize;

  return S_OK;
}

/******************************************************************************
 *           CreateILockBytesOnHGlobal     [OLE2.54]
 * 
 * Creates an ILockBytes interface for a HGLOBAL handle.
 *
 * Params:
 * 	hGlobal			the global handle (16bit)
 *	fDeleteOnRelease	delete handle on release.
 *	ppLkbyt			pointer to ILockBytes interface.
 *
 * Returns:
 *	Staddard OLE error return codes.
 *
 */
HRESULT WINAPI CreateILockBytesOnHGlobal16(
	HGLOBAL16      hGlobal,          /* [in] */
	BOOL16         fDeleteOnRelease, /* [in] */
	LPLOCKBYTES16 *ppLkbyt)          /* [out] (ptr to SEGPTR!) */
{
  HGLOBALLockBytesImpl16* newLockBytes; /* SEGPTR */

  newLockBytes = HGLOBALLockBytesImpl16_Construct(hGlobal, fDeleteOnRelease);

  if (newLockBytes != NULL)
    return HGLOBALLockBytesImpl16_QueryInterface((ILockBytes16*)newLockBytes,
                                   &IID_ILockBytes,
                                   (void**)ppLkbyt);
  return E_OUTOFMEMORY;
}
