PATCH - Start seperating 16/32 in Ole and ole32 memlockbytes

Steven Edwards Steven_Ed4153 at yahoo.com
Thu May 15 09:33:19 CDT 2003


I am doing some work trying to seperate Ole* and Ole32 for use in 
ReactOS. Before we can make use of most of the WINE code all of the 
Non-Win32api imported functions are going to need to be compiled out or 
rewitten. I dont need someone to do this for me but I am going to need a 
little hand-holding as I dont want to waste my or anyone elses time.

Currentlly Ole32 Imports these non-Win32api functions:
 From GDI32.dll - CloseMetaFile16
 From Kernel32.dll - FreeLibrary16, GetCurrentTask, GetModuleHandle16, 
GetProcAddress16
GlobalAlloc16, GlobalFree16, GlobalLock16, GlobalReAlloc16, 
GlobalSize16, GlobalUnlock16
K32WOWCallback16Ex, K32WOWGlobalAllocLock16, K32WOWGlobalUnlockFree16
LoadLibrary16, LockResource16, MapLS, UnMapLS

Anywhere here is the first patch that removes a few of these imports if 
--disable-win16 is passed to configure. I still have a lot to go and 
this may need some cleanup/review from a OLE guru on Linux but it builds 
for me without warnings or errors under Mingw.

Changelog: Seperate Win16 and Win32 Ole support in memlockbytes.


-------------- next part --------------
--- /dev/null	Thu May 15 10:26:38 2003
+++ memlockbytes16.c	Thu May 15 10:20:00 2003
@@ -0,0 +1,1082 @@
+#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);
+
+/******************************************************************************
+ * HGLOBALLockBytesImpl definition.
+ *
+ * This class imlements the ILockBytes inteface and represents a byte array
+ * object supported by an HGLOBAL pointer.
+ */
+struct HGLOBALLockBytesImpl
+{
+  /*
+   * Needs to be the first item in the stuct
+   * since we want to cast this in an ILockBytes pointer
+   */
+  ICOM_VFIELD(ILockBytes);
+
+  /*
+   * Reference count
+   */
+  ULONG        ref;
+
+  /*
+   * Support for the LockBytes object
+   */
+  HGLOBAL 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 HGLOBALLockBytesImpl HGLOBALLockBytesImpl;
+
+/*
+ * Method definition for the HGLOBALLockBytesImpl class.
+ */
+HGLOBALLockBytesImpl* HGLOBALLockBytesImpl_Construct(
+    HGLOBAL  hGlobal,
+    BOOL     fDeleteOnRelease);
+
+void HGLOBALLockBytesImpl_Destroy(HGLOBALLockBytesImpl* This);
+
+HRESULT WINAPI HGLOBALLockBytesImpl_QueryInterface(
+    ILockBytes*   iface,
+    REFIID        riid,        /* [in] */
+    void**        ppvObject);  /* [iid_is][out] */
+
+ULONG WINAPI HGLOBALLockBytesImpl_AddRef(
+    ILockBytes*   iface);
+
+ULONG WINAPI HGLOBALLockBytesImpl_Release(
+    ILockBytes*   iface);
+
+HRESULT WINAPI HGLOBALLockBytesImpl_ReadAt(
+    ILockBytes*    iface,
+    ULARGE_INTEGER ulOffset,  /* [in] */
+    void*          pv,        /* [length_is][size_is][out] */
+    ULONG          cb,        /* [in] */
+    ULONG*         pcbRead);  /* [out] */
+
+HRESULT WINAPI HGLOBALLockBytesImpl_WriteAt(
+    ILockBytes*    iface,
+    ULARGE_INTEGER ulOffset,    /* [in] */
+    const void*    pv,          /* [size_is][in] */
+    ULONG          cb,          /* [in] */
+    ULONG*         pcbWritten); /* [out] */
+
+HRESULT WINAPI HGLOBALLockBytesImpl_Flush(
+    ILockBytes*     iface);
+
+HRESULT WINAPI HGLOBALLockBytesImpl_SetSize(
+    ILockBytes*     iface,
+    ULARGE_INTEGER  libNewSize);  /* [in] */
+
+HRESULT WINAPI HGLOBALLockBytesImpl_LockRegion(
+    ILockBytes*    iface,
+    ULARGE_INTEGER libOffset,   /* [in] */
+    ULARGE_INTEGER cb,          /* [in] */
+    DWORD          dwLockType); /* [in] */
+
+HRESULT WINAPI HGLOBALLockBytesImpl_UnlockRegion(
+    ILockBytes*    iface,
+    ULARGE_INTEGER libOffset,   /* [in] */
+    ULARGE_INTEGER cb,          /* [in] */
+    DWORD          dwLockType); /* [in] */
+
+HRESULT WINAPI HGLOBALLockBytesImpl_Stat(
+    ILockBytes*    iface,
+    STATSTG*       pstatstg,     /* [out] */
+    DWORD          grfStatFlag); /* [in]  */
+
+/*
+ * Virtual function table for the HGLOBALLockBytesImpl class.
+ */
+static ICOM_VTABLE(ILockBytes) HGLOBALLockBytesImpl_Vtbl =
+{
+    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+    HGLOBALLockBytesImpl_QueryInterface,
+    HGLOBALLockBytesImpl_AddRef,
+    HGLOBALLockBytesImpl_Release,
+    HGLOBALLockBytesImpl_ReadAt,
+    HGLOBALLockBytesImpl_WriteAt,
+    HGLOBALLockBytesImpl_Flush,
+    HGLOBALLockBytesImpl_SetSize,
+    HGLOBALLockBytesImpl_LockRegion,
+    HGLOBALLockBytesImpl_UnlockRegion,
+    HGLOBALLockBytesImpl_Stat,
+};
+
+/******************************************************************************
+ *
+ * HGLOBALLockBytesImpl implementation
+ *
+ */
+
+/******************************************************************************
+ * This is the constructor for the HGLOBALLockBytesImpl class.
+ *
+ * Params:
+ *    hGlobal          - Handle that will support the stream. can be NULL.
+ *    fDeleteOnRelease - Flag set to TRUE if the HGLOBAL will be released
+ *                       when the IStream object is destroyed.
+ */
+HGLOBALLockBytesImpl* HGLOBALLockBytesImpl_Construct(HGLOBAL hGlobal,
+                                                     BOOL    fDeleteOnRelease)
+{
+  HGLOBALLockBytesImpl* newLockBytes;
+  newLockBytes = HeapAlloc(GetProcessHeap(), 0, sizeof(HGLOBALLockBytesImpl));
+
+  if (newLockBytes!=0)
+  {
+    /*
+     * Set up the virtual function table and reference count.
+     */
+    newLockBytes->lpVtbl = &HGLOBALLockBytesImpl_Vtbl;
+    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 = GlobalAlloc(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  = GlobalSize(
+                                              newLockBytes->supportHandle);
+  }
+
+  return newLockBytes;
+}
+
+/******************************************************************************
+ * This is the destructor of the HGLOBALStreamImpl class.
+ *
+ * This method will clean-up all the resources used-up by the given
+ * HGLOBALLockBytesImpl class. The pointer passed-in to this function will be
+ * freed and will not be valid anymore.
+ */
+void HGLOBALLockBytesImpl_Destroy(HGLOBALLockBytesImpl* This)
+{
+  /*
+   * Release the HGlobal if the constructor asked for that.
+   */
+  if (This->deleteOnRelease)
+  {
+    GlobalFree(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 HGLOBALLockBytesImpl_QueryInterface(
+      ILockBytes*  iface,
+      REFIID       riid,        /* [in] */
+      void**       ppvObject)   /* [iid_is][out] */
+{
+  HGLOBALLockBytesImpl* const This=(HGLOBALLockBytesImpl*)iface;
+
+  /*
+   * 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)) == 0)
+  {
+    *ppvObject = (ILockBytes*)This;
+  }
+  else if (memcmp(&IID_ILockBytes, riid, sizeof(IID_ILockBytes)) == 0)
+  {
+    *ppvObject = (ILockBytes*)This;
+  }
+
+  /*
+   * 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
+   */
+  HGLOBALLockBytesImpl_AddRef(iface);
+
+  return S_OK;
+}
+
+/******************************************************************************
+ * This implements the IUnknown method AddRef for this
+ * class
+ */
+ULONG WINAPI HGLOBALLockBytesImpl_AddRef(ILockBytes* iface)
+{
+  HGLOBALLockBytesImpl* const This=(HGLOBALLockBytesImpl*)iface;
+
+  This->ref++;
+
+  return This->ref;
+}
+
+/******************************************************************************
+ * This implements the IUnknown method Release for this
+ * class
+ */
+ULONG WINAPI HGLOBALLockBytesImpl_Release(ILockBytes* iface)
+{
+  HGLOBALLockBytesImpl* const This=(HGLOBALLockBytesImpl*)iface;
+
+  ULONG newRef;
+
+  This->ref--;
+
+  newRef = This->ref;
+
+  /*
+   * If the reference count goes down to 0, perform suicide.
+   */
+  if (newRef==0)
+  {
+    HGLOBALLockBytesImpl_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 HGLOBALLockBytesImpl_ReadAt(
+      ILockBytes*    iface,
+      ULARGE_INTEGER ulOffset,  /* [in] */
+      void*          pv,        /* [length_is][size_is][out] */
+      ULONG          cb,        /* [in] */
+      ULONG*         pcbRead)   /* [out] */
+{
+  HGLOBALLockBytesImpl* const This=(HGLOBALLockBytesImpl*)iface;
+
+  void* supportBuffer;
+  ULONG bytesReadBuffer = 0;
+  ULONG bytesToReadFromBuffer;
+
+  /*
+   * 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 = GlobalLock(This->supportHandle);
+
+  memcpy(pv,
+         (char *) supportBuffer + ulOffset.s.LowPart,
+         bytesToReadFromBuffer);
+
+  /*
+   * Return the number of bytes read.
+   */
+  *pcbRead = bytesToReadFromBuffer;
+
+  /*
+   * Cleanup
+   */
+  GlobalUnlock(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 HGLOBALLockBytesImpl_WriteAt(
+      ILockBytes*    iface,
+      ULARGE_INTEGER ulOffset,    /* [in] */
+      const void*    pv,          /* [size_is][in] */
+      ULONG          cb,          /* [in] */
+      ULONG*         pcbWritten)  /* [out] */
+{
+  HGLOBALLockBytesImpl* const This=(HGLOBALLockBytesImpl*)iface;
+
+  void*          supportBuffer;
+  ULARGE_INTEGER newSize;
+  ULONG          bytesWritten = 0;
+
+  /*
+   * 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;
+  }
+  else
+  {
+    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 (HGLOBALLockBytesImpl_SetSize(iface, newSize) == STG_E_MEDIUMFULL)
+      return STG_E_MEDIUMFULL;
+  }
+
+  /*
+   * Lock the buffer in position and copy the data.
+   */
+  supportBuffer = GlobalLock(This->supportHandle);
+
+  memcpy((char *) supportBuffer + ulOffset.s.LowPart, pv, cb);
+
+  /*
+   * Return the number of bytes written.
+   */
+  *pcbWritten = cb;
+
+  /*
+   * Cleanup
+   */
+  GlobalUnlock(This->supportHandle);
+
+  return S_OK;
+}
+
+/******************************************************************************
+ * This method is part of the ILockBytes interface.
+ *
+ * See the documentation of ILockBytes for more info.
+ */
+HRESULT WINAPI HGLOBALLockBytesImpl_Flush(ILockBytes* 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 HGLOBALLockBytesImpl_SetSize(
+      ILockBytes*     iface,
+      ULARGE_INTEGER  libNewSize)   /* [in] */
+{
+  HGLOBALLockBytesImpl* const This=(HGLOBALLockBytesImpl*)iface;
+
+  /*
+   * 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 = GlobalReAlloc(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 HGLOBALLockBytesImpl_LockRegion(
+      ILockBytes*    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 HGLOBALLockBytesImpl_UnlockRegion(
+      ILockBytes*    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 HGLOBALLockBytesImpl_Stat(
+      ILockBytes*  iface,
+      STATSTG*     pstatstg,     /* [out] */
+      DWORD        grfStatFlag)  /* [in] */
+{
+  HGLOBALLockBytesImpl* const This=(HGLOBALLockBytesImpl*)iface;
+
+  memset(pstatstg, 0, sizeof(STATSTG));
+
+  pstatstg->pwcsName = NULL;
+  pstatstg->type     = STGTY_LOCKBYTES;
+  pstatstg->cbSize   = This->byteArraySize;
+
+  return S_OK;
+}
+
+/******************************************************************************
+ * 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);  /* [iid_is][out] */
+
+ULONG WINAPI HGLOBALLockBytesImpl16_AddRef(
+    ILockBytes16* iface);
+
+ULONG WINAPI HGLOBALLockBytesImpl16_Release(
+    ILockBytes16* iface);
+
+HRESULT WINAPI HGLOBALLockBytesImpl16_ReadAt(
+    ILockBytes16*  iface,
+    ULARGE_INTEGER ulOffset,  /* [in] */
+    void*          pv,        /* [length_is][size_is][out] */
+    ULONG          cb,        /* [in] */
+    ULONG*         pcbRead);  /* [out] */
+
+HRESULT WINAPI HGLOBALLockBytesImpl16_WriteAt(
+    ILockBytes16*  iface,
+    ULARGE_INTEGER ulOffset,    /* [in] */
+    const void*    pv,          /* [size_is][in] */
+    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)   /* [iid_is][out] (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,        /* [length_is][size_is][out] */
+      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,          /* [size_is][in] */
+      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,
+                                           BOOL16         fDeleteOnRelease,
+                                           /*SEGPTR**/	LPLOCKBYTES16* ppLkbyt)
+{
+  HGLOBALLockBytesImpl16* newLockBytes; /* SEGPTR */
+
+  newLockBytes = HGLOBALLockBytesImpl16_Construct(hGlobal, fDeleteOnRelease);
+
+  if (newLockBytes != NULL)
+    return HGLOBALLockBytesImpl16_QueryInterface((ILockBytes16*)newLockBytes,
+                                   &IID_ILockBytes,
+                                   (void**)ppLkbyt);
+  return E_OUTOFMEMORY;
+}





Index: Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/ole32/Makefile.in,v
retrieving revision 1.29
diff -u -r1.29 Makefile.in
--- Makefile.in    28 Mar 2003 19:33:04 -0000    1.29
+++ Makefile.in    15 May 2003 14:24:34 -0000
@@ -45,7 +45,9 @@
     storage.c \
     storage32.c
 
-C_SRCS16 = ole2nls.c
+C_SRCS16 = ole2nls.c \
+    memlockbytes16.c
+
 
 RC_SRCS = ole32res.rc version.rc
 

Index: memlockbytes.c
===================================================================
RCS file: /home/wine/wine/dlls/ole32/memlockbytes.c,v
retrieving revision 1.11
diff -u -r1.11 memlockbytes.c
--- memlockbytes.c    10 Apr 2003 18:17:35 -0000    1.11
+++ memlockbytes.c    15 May 2003 14:22:40 -0000
@@ -215,951 +215,3 @@
   return S_OK;
 }
 
-/******************************************************************************
- *
- * HGLOBALLockBytesImpl implementation
- *
- */
-
-/******************************************************************************
- * This is the constructor for the HGLOBALLockBytesImpl class.
- *
- * Params:
- *    hGlobal          - Handle that will support the stream. can be NULL.
- *    fDeleteOnRelease - Flag set to TRUE if the HGLOBAL will be released
- *                       when the IStream object is destroyed.
- */
-HGLOBALLockBytesImpl* HGLOBALLockBytesImpl_Construct(HGLOBAL hGlobal,
-                                                     BOOL    fDeleteOnRelease)
-{
-  HGLOBALLockBytesImpl* newLockBytes;
-  newLockBytes = HeapAlloc(GetProcessHeap(), 0, sizeof(HGLOBALLockBytesImpl));
-
-  if (newLockBytes!=0)
-  {
-    /*
-     * Set up the virtual function table and reference count.
-     */
-    newLockBytes->lpVtbl = &HGLOBALLockBytesImpl_Vtbl;
-    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 = GlobalAlloc(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  = GlobalSize(
-                                              newLockBytes->supportHandle);
-  }
-
-  return newLockBytes;
-}
-
-/******************************************************************************
- * This is the destructor of the HGLOBALStreamImpl class.
- *
- * This method will clean-up all the resources used-up by the given
- * HGLOBALLockBytesImpl class. The pointer passed-in to this function will be
- * freed and will not be valid anymore.
- */
-void HGLOBALLockBytesImpl_Destroy(HGLOBALLockBytesImpl* This)
-{
-  /*
-   * Release the HGlobal if the constructor asked for that.
-   */
-  if (This->deleteOnRelease)
-  {
-    GlobalFree(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 HGLOBALLockBytesImpl_QueryInterface(
-      ILockBytes*  iface,
-      REFIID       riid,        /* [in] */
-      void**       ppvObject)   /* [iid_is][out] */
-{
-  HGLOBALLockBytesImpl* const This=(HGLOBALLockBytesImpl*)iface;
-
-  /*
-   * 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)) == 0)
-  {
-    *ppvObject = (ILockBytes*)This;
-  }
-  else if (memcmp(&IID_ILockBytes, riid, sizeof(IID_ILockBytes)) == 0)
-  {
-    *ppvObject = (ILockBytes*)This;
-  }
-
-  /*
-   * 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
-   */
-  HGLOBALLockBytesImpl_AddRef(iface);
-
-  return S_OK;
-}
-
-/******************************************************************************
- * This implements the IUnknown method AddRef for this
- * class
- */
-ULONG WINAPI HGLOBALLockBytesImpl_AddRef(ILockBytes* iface)
-{
-  HGLOBALLockBytesImpl* const This=(HGLOBALLockBytesImpl*)iface;
-
-  This->ref++;
-
-  return This->ref;
-}
-
-/******************************************************************************
- * This implements the IUnknown method Release for this
- * class
- */
-ULONG WINAPI HGLOBALLockBytesImpl_Release(ILockBytes* iface)
-{
-  HGLOBALLockBytesImpl* const This=(HGLOBALLockBytesImpl*)iface;
-
-  ULONG newRef;
-
-  This->ref--;
-
-  newRef = This->ref;
-
-  /*
-   * If the reference count goes down to 0, perform suicide.
-   */
-  if (newRef==0)
-  {
-    HGLOBALLockBytesImpl_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 HGLOBALLockBytesImpl_ReadAt(
-      ILockBytes*    iface,
-      ULARGE_INTEGER ulOffset,  /* [in] */
-      void*          pv,        /* [length_is][size_is][out] */
-      ULONG          cb,        /* [in] */
-      ULONG*         pcbRead)   /* [out] */
-{
-  HGLOBALLockBytesImpl* const This=(HGLOBALLockBytesImpl*)iface;
-
-  void* supportBuffer;
-  ULONG bytesReadBuffer = 0;
-  ULONG bytesToReadFromBuffer;
-
-  /*
-   * 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 = GlobalLock(This->supportHandle);
-
-  memcpy(pv,
-         (char *) supportBuffer + ulOffset.s.LowPart,
-         bytesToReadFromBuffer);
-
-  /*
-   * Return the number of bytes read.
-   */
-  *pcbRead = bytesToReadFromBuffer;
-
-  /*
-   * Cleanup
-   */
-  GlobalUnlock(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 HGLOBALLockBytesImpl_WriteAt(
-      ILockBytes*    iface,
-      ULARGE_INTEGER ulOffset,    /* [in] */
-      const void*    pv,          /* [size_is][in] */
-      ULONG          cb,          /* [in] */
-      ULONG*         pcbWritten)  /* [out] */
-{
-  HGLOBALLockBytesImpl* const This=(HGLOBALLockBytesImpl*)iface;
-
-  void*          supportBuffer;
-  ULARGE_INTEGER newSize;
-  ULONG          bytesWritten = 0;
-
-  /*
-   * 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;
-  }
-  else
-  {
-    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 (HGLOBALLockBytesImpl_SetSize(iface, newSize) == STG_E_MEDIUMFULL)
-      return STG_E_MEDIUMFULL;
-  }
-
-  /*
-   * Lock the buffer in position and copy the data.
-   */
-  supportBuffer = GlobalLock(This->supportHandle);
-
-  memcpy((char *) supportBuffer + ulOffset.s.LowPart, pv, cb);
-
-  /*
-   * Return the number of bytes written.
-   */
-  *pcbWritten = cb;
-
-  /*
-   * Cleanup
-   */
-  GlobalUnlock(This->supportHandle);
-
-  return S_OK;
-}
-
-/******************************************************************************
- * This method is part of the ILockBytes interface.
- *
- * See the documentation of ILockBytes for more info.
- */
-HRESULT WINAPI HGLOBALLockBytesImpl_Flush(ILockBytes* 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 HGLOBALLockBytesImpl_SetSize(
-      ILockBytes*     iface,
-      ULARGE_INTEGER  libNewSize)   /* [in] */
-{
-  HGLOBALLockBytesImpl* const This=(HGLOBALLockBytesImpl*)iface;
-
-  /*
-   * 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 = GlobalReAlloc(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 HGLOBALLockBytesImpl_LockRegion(
-      ILockBytes*    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 HGLOBALLockBytesImpl_UnlockRegion(
-      ILockBytes*    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 HGLOBALLockBytesImpl_Stat(
-      ILockBytes*  iface,
-      STATSTG*     pstatstg,     /* [out] */
-      DWORD        grfStatFlag)  /* [in] */
-{
-  HGLOBALLockBytesImpl* const This=(HGLOBALLockBytesImpl*)iface;
-
-  memset(pstatstg, 0, sizeof(STATSTG));
-
-  pstatstg->pwcsName = NULL;
-  pstatstg->type     = STGTY_LOCKBYTES;
-  pstatstg->cbSize   = This->byteArraySize;
-
-  return S_OK;
-}
-
-/******************************************************************************
- * 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);  /* [iid_is][out] */
-
-ULONG WINAPI HGLOBALLockBytesImpl16_AddRef(
-    ILockBytes16* iface);
-
-ULONG WINAPI HGLOBALLockBytesImpl16_Release(
-    ILockBytes16* iface);
-
-HRESULT WINAPI HGLOBALLockBytesImpl16_ReadAt(
-    ILockBytes16*  iface,
-    ULARGE_INTEGER ulOffset,  /* [in] */
-    void*          pv,        /* [length_is][size_is][out] */
-    ULONG          cb,        /* [in] */
-    ULONG*         pcbRead);  /* [out] */
-
-HRESULT WINAPI HGLOBALLockBytesImpl16_WriteAt(
-    ILockBytes16*  iface,
-    ULARGE_INTEGER ulOffset,    /* [in] */
-    const void*    pv,          /* [size_is][in] */
-    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)   /* [iid_is][out] (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,        /* [length_is][size_is][out] */
-      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,          /* [size_is][in] */
-      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,
-                                           BOOL16         fDeleteOnRelease,
-                                           /*SEGPTR**/    LPLOCKBYTES16* ppLkbyt)
-{
-  HGLOBALLockBytesImpl16* newLockBytes; /* SEGPTR */
-
-  newLockBytes = HGLOBALLockBytesImpl16_Construct(hGlobal, fDeleteOnRelease);
-
-  if (newLockBytes != NULL)
-    return HGLOBALLockBytesImpl16_QueryInterface((ILockBytes16*)newLockBytes,
-                                   &IID_ILockBytes,
-                                   (void**)ppLkbyt);
-  return E_OUTOFMEMORY;
-}


More information about the wine-devel mailing list