PATCH: 16bit ILockBytes, some 16bit stg

Marcus Meissner marcus at jet.franken.de
Sat Jan 4 04:00:07 CST 2003


Hi,

Some 16bit OLE work. My testprogram is MS Access 2.0 during DB open.

The next step required after these is a 16bit storage implementation
which can cope with ILockBytes16. Favorable would be to get rid
of the 16bit storage implementation and just use the 32bit one. :/

Ciao, Marcus

Changelog:
	ole2nls.c is a 16bit only.
	No need to define ICOM macros for 16bit iface IMalloc16.
	Define and implement HGLOBAL_LockBytes16.
	Started on StgOpenStorageOnILockBytes.


Index: Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/ole32/Makefile.in,v
retrieving revision 1.25
diff -u -u -r1.25 Makefile.in
--- Makefile.in	3 Jan 2003 19:12:56 -0000	1.25
+++ Makefile.in	4 Jan 2003 09:51:17 -0000
@@ -32,7 +32,6 @@
 	ole2.c \
 	ole2stubs.c \
 	ole2impl.c \
-	ole2nls.c \
 	ole32_main.c \
 	oleobj.c \
 	oleproxy.c \
@@ -41,6 +40,8 @@
 	stg_stream.c \
 	storage.c \
 	storage32.c
+
+C_SRCS16 = ole2nls.c
 
 RC_SRCS = ole32res.rc
 
Index: ifs.h
===================================================================
RCS file: /home/wine/wine/dlls/ole32/ifs.h,v
retrieving revision 1.5
diff -u -u -r1.5 ifs.h
--- ifs.h	23 Dec 2002 01:39:35 -0000	1.5
+++ ifs.h	4 Jan 2003 09:51:18 -0000
@@ -41,20 +41,30 @@
 ICOM_DEFINE(IMalloc16,IUnknown)
 #undef ICOM_INTERFACE
 
-/*** IUnknown methods ***/
-#define IMalloc16_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b)
-#define IMalloc16_AddRef(p)             ICOM_CALL (AddRef,p)
-#define IMalloc16_Release(p)            ICOM_CALL (Release,p)
-/*** IMalloc16 methods ***/
-#define IMalloc16_Alloc(p,a)      ICOM_CALL1(Alloc,p,a)
-#define IMalloc16_Realloc(p,a,b)  ICOM_CALL2(Realloc,p,a,b)
-#define IMalloc16_Free(p,a)       ICOM_CALL1(Free,p,a)
-#define IMalloc16_GetSize(p,a)    ICOM_CALL1(GetSize,p,a)
-#define IMalloc16_DidAlloc(p,a)   ICOM_CALL1(DidAlloc,p,a)
-#define IMalloc16_HeapMinimize(p) ICOM_CALL (HeapMinimize,p)
-
 /**********************************************************************/
 
 extern LPMALLOC16 IMalloc16_Constructor();
+
+/**********************************************************************/
+
+typedef struct ILockBytes16 *LPLOCKBYTES16, ILockBytes16;
+
+#define ICOM_INTERFACE ILockBytes
+#define ILockBytes16_METHODS \
+	ICOM_METHOD4(HRESULT,ReadAt,       ULARGE_INTEGER,ulOffset, void*,pv, ULONG, cb, ULONG*,pcbRead) \
+	ICOM_METHOD4(HRESULT,WriteAt,      ULARGE_INTEGER,ulOffset, const void*,pv, ULONG,cb, ULONG*,pcbWritten) \
+	ICOM_METHOD (HRESULT,Flush) \
+	ICOM_METHOD1(HRESULT,SetSize,      ULARGE_INTEGER,cb) \
+	ICOM_METHOD3(HRESULT,LockRegion,   ULARGE_INTEGER,libOffset, ULARGE_INTEGER, cb, DWORD,dwLockType) \
+	ICOM_METHOD3(HRESULT,UnlockRegion, ULARGE_INTEGER,libOffset, ULARGE_INTEGER, cb, DWORD,dwLockType) \
+	ICOM_METHOD2(HRESULT,Stat,         STATSTG*,pstatstg, DWORD,grfStatFlag)
+
+#define ILockBytes16_IMETHODS \
+	IUnknown_IMETHODS \
+	ILockBytes16_METHODS
+
+ICOM_DEFINE(ILockBytes16,IUnknown)
+#undef ICOM_INTERFACE
+
 
 #endif /* __WINE_OLE_IFS_H */
Index: memlockbytes.c
===================================================================
RCS file: /home/wine/wine/dlls/ole32/memlockbytes.c,v
retrieving revision 1.8
diff -u -u -r1.8 memlockbytes.c
--- memlockbytes.c	5 Jul 2002 21:19:55 -0000	1.8
+++ memlockbytes.c	4 Jan 2003 09:51:18 -0000
@@ -21,14 +21,18 @@
 
 #include "config.h"
 
+#include <assert.h>
 #include <string.h>
 
 #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);
@@ -617,3 +621,544 @@
 
   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 );
+  }
+  ICOM_VTBL(newLockBytes)	= (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: ole2.spec
===================================================================
RCS file: /home/wine/wine/dlls/ole32/ole2.spec,v
retrieving revision 1.4
diff -u -u -r1.4 ole2.spec
--- ole2.spec	21 Jun 2002 19:15:48 -0000	1.4
+++ ole2.spec	4 Jan 2003 09:51:19 -0000
@@ -51,7 +51,7 @@
 51 stub OLEDUPLICATEDATA
 52 stub OLEGETICONOFFILE
 53 stub OLEGETICONOFCLASS
-54 stub CREATEILOCKBYTESONHGLOBAL
+54 pascal CreateILockBytesOnHGLOBAL(word word ptr) CreateILockBytesOnHGlobal16
 55 stub GETHGLOBALFROMILOCKBYTES
 56 pascal16 OleMetaFilePictFromIconAndLabel(word str str word) OleMetaFilePictFromIconAndLabel16
 57 stub GETCLASSFILE
@@ -144,3 +144,15 @@
 159 stub _IID_IOLECACHE2
 160 stub _IID_IOLECACHECONTROL
 161 stub _IID_IRUNNABLEOBJECT
+
+# WINE MemLockBytes implementation.
+500 cdecl HGLOBALLockBytesImpl16_QueryInterface(segptr ptr ptr) HGLOBALLockBytesImpl16_QueryInterface
+501 cdecl HGLOBALLockBytesImpl16_AddRef(ptr) HGLOBALLockBytesImpl16_AddRef
+502 cdecl HGLOBALLockBytesImpl16_Release(ptr) HGLOBALLockBytesImpl16_Release
+503 cdecl HGLOBALLockBytesImpl16_ReadAt(ptr long long ptr ptr) HGLOBALLockBytesImpl16_ReadAt
+504 cdecl HGLOBALLockBytesImpl16_WriteAt(ptr long long ptr long ptr) HGLOBALLockBytesImpl16_WriteAt
+505 cdecl HGLOBALLockBytesImpl16_Flush(ptr) HGLOBALLockBytesImpl16_Flush
+506 cdecl HGLOBALLockBytesImpl16_SetSize(ptr long long) HGLOBALLockBytesImpl16_SetSize
+507 cdecl HGLOBALLockBytesImpl16_LockRegion(ptr long long long long long) HGLOBALLockBytesImpl16_LockRegion
+508 cdecl HGLOBALLockBytesImpl16_UnlockRegion(ptr long long long long long) HGLOBALLockBytesImpl16_UnlockRegion
+509 cdecl HGLOBALLockBytesImpl16_Stat(ptr ptr long) HGLOBALLockBytesImpl16_Stat
Index: storage.c
===================================================================
RCS file: /home/wine/wine/dlls/ole32/storage.c,v
retrieving revision 1.28
diff -u -u -r1.28 storage.c
--- storage.c	5 Dec 2002 20:33:08 -0000	1.28
+++ storage.c	4 Jan 2003 09:51:19 -0000
@@ -34,10 +34,13 @@
 #include "winternl.h"
 #include "winerror.h"
 #include "wine/winbase16.h"
+#include "wownt32.h"
 #include "wine/unicode.h"
 #include "objbase.h"
 #include "wine/debug.h"
 
+#include "ifs.h"
+
 WINE_DEFAULT_DEBUG_CHANNEL(ole);
 WINE_DECLARE_DEBUG_CHANNEL(relay);
 
@@ -1690,4 +1693,67 @@
 	}
 	return S_OK;
 
+}
+
+/******************************************************************************
+ *              StgIsStorageILockBytes        [STORAGE.6]
+ *
+ * Determines if the ILockBytes contains a storage object.
+ */
+HRESULT WINAPI StgIsStorageILockBytes16(SEGPTR plkbyt)
+{
+  DWORD args[6];
+  HRESULT hres;
+  HANDLE16 hsig;
+  
+  args[0] = (DWORD)plkbyt;	/* iface */
+  args[1] = args[2] = 0;	/* ULARGE_INTEGER offset */
+  args[3] = (DWORD)K32WOWGlobalAllocLock16( 0, 8, &hsig ); /* sig */
+  args[4] = 8;
+  args[5] = 0;
+
+  if (!K32WOWCallback16Ex(
+      (DWORD)((ICOM_VTABLE(ILockBytes16)*)MapSL(
+	  (SEGPTR)ICOM_VTBL(((LPLOCKBYTES16)MapSL(plkbyt))))
+      )->ReadAt,
+      WCB16_PASCAL,
+      6*sizeof(DWORD),
+      (LPVOID)args,
+      (LPDWORD)&hres
+  )) {
+      ERR("CallTo16 ILockBytes16::ReadAt() failed, hres %lx\n",hres);
+      return hres;
+  }
+  if (memcmp(MapSL(args[3]), STORAGE_magic, sizeof(STORAGE_magic)) == 0) {
+    K32WOWGlobalUnlockFree16(args[3]);
+    return S_OK;
+  }
+  K32WOWGlobalUnlockFree16(args[3]);
+  return S_FALSE;
+}
+
+/******************************************************************************
+ *    StgOpenStorageOnILockBytes    [STORAGE.4]
+ */
+HRESULT WINAPI StgOpenStorageOnILockBytes16(
+      ILockBytes16 *plkbyt,
+      IStorage16 *pstgPriority,
+      DWORD grfMode,
+      SNB16 snbExclude,
+      DWORD reserved,
+      IStorage16 **ppstgOpen)
+{
+  IStorage16Impl*	lpstg;
+
+  if ((plkbyt == 0) || (ppstgOpen == 0))
+    return STG_E_INVALIDPOINTER;
+
+  *ppstgOpen = 0;
+
+  _create_istorage16(ppstgOpen);
+  lpstg = MapSL((SEGPTR)*ppstgOpen);
+
+  /* just teach it to use HANDLE instead of ilockbytes :/ */
+
+  return S_OK;
 }
Index: storage.spec
===================================================================
RCS file: /home/wine/wine/dlls/ole32/storage.spec,v
retrieving revision 1.4
diff -u -u -r1.4 storage.spec
--- storage.spec	21 Jun 2002 19:15:48 -0000	1.4
+++ storage.spec	4 Jan 2003 09:51:19 -0000
@@ -4,10 +4,11 @@
 
 1 pascal StgCreateDocFileA(str long long ptr) StgCreateDocFile16
 2 stub StgCreateDocFileOnILockBytes
+# 2 pascal StgCreateDocFileOnILockBytes(ptr long long ptr) StgCreateDocFileOnILockBytes16
 3 pascal StgOpenStorage(str ptr long ptr long ptr) StgOpenStorage16
-4 stub StgOpenStorageOnILockBytes
+4 pascal StgOpenStorageOnILockBytes(ptr ptr long long long ptr) StgOpenStorageOnILockBytes16
 5 pascal StgIsStorageFile(str) StgIsStorageFile16
-6 stub StgIsStorageILockBytes
+6 pascal StgIsStorageILockBytes(segptr) StgIsStorageILockBytes16
 7 stub StgSetTimes
 #8 WEP
 #9 ___EXPORTEDSTUB



More information about the wine-patches mailing list