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 =)
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;
-}