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

Steven Edwards Steven_Ed4153 at yahoo.com
Thu May 15 10:04:53 CDT 2003


Steven Edwards wrote:

> 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.
>
With the right patch this time =)


-------------- next part --------------
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 15:02:05 -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


--- /dev/null	Thu May 15 11:02:20 2003
+++ memlockbytes16.c	Thu May 15 10:58:06 2003
@@ -0,0 +1,580 @@
+/******************************************************************************
+ *
+ * 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);  /* [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: 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:59:29 -0000
@@ -623,543 +623,3 @@
 
   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