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