Currentlly Ole32 Imports these non-Win32api functions:
From GDI32.dll - CloseMetaFile16
From Kernel32.dll - FreeLibrary16, GetCurrentTask, GetModuleHandle16, GetProcAddress16
GlobalAlloc16, GlobalFree16, GlobalLock16, GlobalReAlloc16, GlobalSize16, GlobalUnlock16
K32WOWCallback16Ex, K32WOWGlobalAllocLock16, K32WOWGlobalUnlockFree16
LoadLibrary16, LockResource16, MapLS, UnMapLS
Anywhere here is the first patch that removes a few of these imports if --disable-win16 is passed to configure. I still have a lot to go and this may need some cleanup/review from a OLE guru on Linux but it builds for me without warnings or errors under Mingw.
Changelog: Seperate Win16 and Win32 Ole support in memlockbytes.
--- /dev/null Thu May 15 10:26:38 2003 +++ memlockbytes16.c Thu May 15 10:20:00 2003 @@ -0,0 +1,1082 @@ +#include "config.h" + +#include <assert.h> +#include <string.h> + +#define NONAMELESSUNION +#define NONAMELESSSTRUCT +#include "windef.h" +#include "wine/winbase16.h" +#include "objbase.h" +#include "ole2.h" +#include "winbase.h" +#include "winerror.h" + +#include "ifs.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(ole); + +/****************************************************************************** + * HGLOBALLockBytesImpl definition. + * + * This class imlements the ILockBytes inteface and represents a byte array + * object supported by an HGLOBAL pointer. + */ +struct HGLOBALLockBytesImpl +{ + /* + * Needs to be the first item in the stuct + * since we want to cast this in an ILockBytes pointer + */ + ICOM_VFIELD(ILockBytes); + + /* + * Reference count + */ + ULONG ref; + + /* + * Support for the LockBytes object + */ + HGLOBAL supportHandle; + + /* + * This flag is TRUE if the HGLOBAL is destroyed when the object + * is finally released. + */ + BOOL deleteOnRelease; + + /* + * Helper variable that contains the size of the byte array + */ + ULARGE_INTEGER byteArraySize; +}; + +typedef struct HGLOBALLockBytesImpl HGLOBALLockBytesImpl; + +/* + * Method definition for the HGLOBALLockBytesImpl class. + */ +HGLOBALLockBytesImpl* HGLOBALLockBytesImpl_Construct( + HGLOBAL hGlobal, + BOOL fDeleteOnRelease); + +void HGLOBALLockBytesImpl_Destroy(HGLOBALLockBytesImpl* This); + +HRESULT WINAPI HGLOBALLockBytesImpl_QueryInterface( + ILockBytes* iface, + REFIID riid, /* [in] */ + void** ppvObject); /* [iid_is][out] */ + +ULONG WINAPI HGLOBALLockBytesImpl_AddRef( + ILockBytes* iface); + +ULONG WINAPI HGLOBALLockBytesImpl_Release( + ILockBytes* iface); + +HRESULT WINAPI HGLOBALLockBytesImpl_ReadAt( + ILockBytes* iface, + ULARGE_INTEGER ulOffset, /* [in] */ + void* pv, /* [length_is][size_is][out] */ + ULONG cb, /* [in] */ + ULONG* pcbRead); /* [out] */ + +HRESULT WINAPI HGLOBALLockBytesImpl_WriteAt( + ILockBytes* iface, + ULARGE_INTEGER ulOffset, /* [in] */ + const void* pv, /* [size_is][in] */ + ULONG cb, /* [in] */ + ULONG* pcbWritten); /* [out] */ + +HRESULT WINAPI HGLOBALLockBytesImpl_Flush( + ILockBytes* iface); + +HRESULT WINAPI HGLOBALLockBytesImpl_SetSize( + ILockBytes* iface, + ULARGE_INTEGER libNewSize); /* [in] */ + +HRESULT WINAPI HGLOBALLockBytesImpl_LockRegion( + ILockBytes* iface, + ULARGE_INTEGER libOffset, /* [in] */ + ULARGE_INTEGER cb, /* [in] */ + DWORD dwLockType); /* [in] */ + +HRESULT WINAPI HGLOBALLockBytesImpl_UnlockRegion( + ILockBytes* iface, + ULARGE_INTEGER libOffset, /* [in] */ + ULARGE_INTEGER cb, /* [in] */ + DWORD dwLockType); /* [in] */ + +HRESULT WINAPI HGLOBALLockBytesImpl_Stat( + ILockBytes* iface, + STATSTG* pstatstg, /* [out] */ + DWORD grfStatFlag); /* [in] */ + +/* + * Virtual function table for the HGLOBALLockBytesImpl class. + */ +static ICOM_VTABLE(ILockBytes) HGLOBALLockBytesImpl_Vtbl = +{ + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + HGLOBALLockBytesImpl_QueryInterface, + HGLOBALLockBytesImpl_AddRef, + HGLOBALLockBytesImpl_Release, + HGLOBALLockBytesImpl_ReadAt, + HGLOBALLockBytesImpl_WriteAt, + HGLOBALLockBytesImpl_Flush, + HGLOBALLockBytesImpl_SetSize, + HGLOBALLockBytesImpl_LockRegion, + HGLOBALLockBytesImpl_UnlockRegion, + HGLOBALLockBytesImpl_Stat, +}; + +/****************************************************************************** + * + * HGLOBALLockBytesImpl implementation + * + */ + +/****************************************************************************** + * This is the constructor for the HGLOBALLockBytesImpl class. + * + * Params: + * hGlobal - Handle that will support the stream. can be NULL. + * fDeleteOnRelease - Flag set to TRUE if the HGLOBAL will be released + * when the IStream object is destroyed. + */ +HGLOBALLockBytesImpl* HGLOBALLockBytesImpl_Construct(HGLOBAL hGlobal, + BOOL fDeleteOnRelease) +{ + HGLOBALLockBytesImpl* newLockBytes; + newLockBytes = HeapAlloc(GetProcessHeap(), 0, sizeof(HGLOBALLockBytesImpl)); + + if (newLockBytes!=0) + { + /* + * Set up the virtual function table and reference count. + */ + newLockBytes->lpVtbl = &HGLOBALLockBytesImpl_Vtbl; + newLockBytes->ref = 0; + + /* + * Initialize the support. + */ + newLockBytes->supportHandle = hGlobal; + newLockBytes->deleteOnRelease = fDeleteOnRelease; + + /* + * This method will allocate a handle if one is not supplied. + */ + if (newLockBytes->supportHandle == 0) + { + newLockBytes->supportHandle = GlobalAlloc(GMEM_MOVEABLE | + GMEM_NODISCARD, + 0); + } + + /* + * Initialize the size of the array to the size of the handle. + */ + newLockBytes->byteArraySize.s.HighPart = 0; + newLockBytes->byteArraySize.s.LowPart = GlobalSize( + newLockBytes->supportHandle); + } + + return newLockBytes; +} + +/****************************************************************************** + * This is the destructor of the HGLOBALStreamImpl class. + * + * This method will clean-up all the resources used-up by the given + * HGLOBALLockBytesImpl class. The pointer passed-in to this function will be + * freed and will not be valid anymore. + */ +void HGLOBALLockBytesImpl_Destroy(HGLOBALLockBytesImpl* This) +{ + /* + * Release the HGlobal if the constructor asked for that. + */ + if (This->deleteOnRelease) + { + GlobalFree(This->supportHandle); + This->supportHandle = 0; + } + + /* + * Finally, free the memory used-up by the class. + */ + HeapFree(GetProcessHeap(), 0, This); +} + +/****************************************************************************** + * This implements the IUnknown method QueryInterface for this + * class + */ +HRESULT WINAPI HGLOBALLockBytesImpl_QueryInterface( + ILockBytes* iface, + REFIID riid, /* [in] */ + void** ppvObject) /* [iid_is][out] */ +{ + HGLOBALLockBytesImpl* const This=(HGLOBALLockBytesImpl*)iface; + + /* + * Perform a sanity check on the parameters. + */ + if (ppvObject==0) + return E_INVALIDARG; + + /* + * Initialize the return parameter. + */ + *ppvObject = 0; + + /* + * Compare the riid with the interface IDs implemented by this object. + */ + if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0) + { + *ppvObject = (ILockBytes*)This; + } + else if (memcmp(&IID_ILockBytes, riid, sizeof(IID_ILockBytes)) == 0) + { + *ppvObject = (ILockBytes*)This; + } + + /* + * Check that we obtained an interface. + */ + if ((*ppvObject)==0) + return E_NOINTERFACE; + + /* + * Query Interface always increases the reference count by one when it is + * successful + */ + HGLOBALLockBytesImpl_AddRef(iface); + + return S_OK; +} + +/****************************************************************************** + * This implements the IUnknown method AddRef for this + * class + */ +ULONG WINAPI HGLOBALLockBytesImpl_AddRef(ILockBytes* iface) +{ + HGLOBALLockBytesImpl* const This=(HGLOBALLockBytesImpl*)iface; + + This->ref++; + + return This->ref; +} + +/****************************************************************************** + * This implements the IUnknown method Release for this + * class + */ +ULONG WINAPI HGLOBALLockBytesImpl_Release(ILockBytes* iface) +{ + HGLOBALLockBytesImpl* const This=(HGLOBALLockBytesImpl*)iface; + + ULONG newRef; + + This->ref--; + + newRef = This->ref; + + /* + * If the reference count goes down to 0, perform suicide. + */ + if (newRef==0) + { + HGLOBALLockBytesImpl_Destroy(This); + } + + return newRef; +} + +/****************************************************************************** + * This method is part of the ILockBytes interface. + * + * It reads a block of information from the byte array at the specified + * offset. + * + * See the documentation of ILockBytes for more info. + */ +HRESULT WINAPI HGLOBALLockBytesImpl_ReadAt( + ILockBytes* iface, + ULARGE_INTEGER ulOffset, /* [in] */ + void* pv, /* [length_is][size_is][out] */ + ULONG cb, /* [in] */ + ULONG* pcbRead) /* [out] */ +{ + HGLOBALLockBytesImpl* const This=(HGLOBALLockBytesImpl*)iface; + + void* supportBuffer; + ULONG bytesReadBuffer = 0; + ULONG bytesToReadFromBuffer; + + /* + * If the caller is not interested in the number of bytes read, + * we use another buffer to avoid "if" statements in the code. + */ + if (pcbRead == 0) + pcbRead = &bytesReadBuffer; + + /* + * Make sure the offset is valid. + */ + if (ulOffset.s.LowPart > This->byteArraySize.s.LowPart) + return E_FAIL; + + /* + * Using the known size of the array, calculate the number of bytes + * to read. + */ + bytesToReadFromBuffer = min(This->byteArraySize.s.LowPart - + ulOffset.s.LowPart, cb); + + /* + * Lock the buffer in position and copy the data. + */ + supportBuffer = GlobalLock(This->supportHandle); + + memcpy(pv, + (char *) supportBuffer + ulOffset.s.LowPart, + bytesToReadFromBuffer); + + /* + * Return the number of bytes read. + */ + *pcbRead = bytesToReadFromBuffer; + + /* + * Cleanup + */ + GlobalUnlock(This->supportHandle); + + /* + * The function returns S_OK if the specified number of bytes were read + * or the end of the array was reached. + * It returns STG_E_READFAULT if the number of bytes to read does not equal + * the number of bytes actually read. + */ + if(*pcbRead == cb) + return S_OK; + + return STG_E_READFAULT; +} + +/****************************************************************************** + * This method is part of the ILockBytes interface. + * + * It writes the specified bytes at the specified offset. + * position. If the array is too small, it will be resized. + * + * See the documentation of ILockBytes for more info. + */ +HRESULT WINAPI HGLOBALLockBytesImpl_WriteAt( + ILockBytes* iface, + ULARGE_INTEGER ulOffset, /* [in] */ + const void* pv, /* [size_is][in] */ + ULONG cb, /* [in] */ + ULONG* pcbWritten) /* [out] */ +{ + HGLOBALLockBytesImpl* const This=(HGLOBALLockBytesImpl*)iface; + + void* supportBuffer; + ULARGE_INTEGER newSize; + ULONG bytesWritten = 0; + + /* + * If the caller is not interested in the number of bytes written, + * we use another buffer to avoid "if" statements in the code. + */ + if (pcbWritten == 0) + pcbWritten = &bytesWritten; + + if (cb == 0) + { + return S_OK; + } + else + { + newSize.s.HighPart = 0; + newSize.s.LowPart = ulOffset.s.LowPart + cb; + } + + /* + * Verify if we need to grow the stream + */ + if (newSize.s.LowPart > This->byteArraySize.s.LowPart) + { + /* grow stream */ + if (HGLOBALLockBytesImpl_SetSize(iface, newSize) == STG_E_MEDIUMFULL) + return STG_E_MEDIUMFULL; + } + + /* + * Lock the buffer in position and copy the data. + */ + supportBuffer = GlobalLock(This->supportHandle); + + memcpy((char *) supportBuffer + ulOffset.s.LowPart, pv, cb); + + /* + * Return the number of bytes written. + */ + *pcbWritten = cb; + + /* + * Cleanup + */ + GlobalUnlock(This->supportHandle); + + return S_OK; +} + +/****************************************************************************** + * This method is part of the ILockBytes interface. + * + * See the documentation of ILockBytes for more info. + */ +HRESULT WINAPI HGLOBALLockBytesImpl_Flush(ILockBytes* iface) +{ + return S_OK; +} + +/****************************************************************************** + * This method is part of the ILockBytes interface. + * + * It will change the size of the byte array. + * + * See the documentation of ILockBytes for more info. + */ +HRESULT WINAPI HGLOBALLockBytesImpl_SetSize( + ILockBytes* iface, + ULARGE_INTEGER libNewSize) /* [in] */ +{ + HGLOBALLockBytesImpl* const This=(HGLOBALLockBytesImpl*)iface; + + /* + * As documented. + */ + if (libNewSize.s.HighPart != 0) + return STG_E_INVALIDFUNCTION; + + if (This->byteArraySize.s.LowPart == libNewSize.s.LowPart) + return S_OK; + + /* + * Re allocate the HGlobal to fit the new size of the stream. + */ + This->supportHandle = GlobalReAlloc(This->supportHandle, + libNewSize.s.LowPart, + 0); + + if (This->supportHandle == 0) + return STG_E_MEDIUMFULL; + + This->byteArraySize.s.LowPart = libNewSize.s.LowPart; + + return S_OK; +} + +/****************************************************************************** + * This method is part of the ILockBytes interface. + * + * The global memory implementation of ILockBytes does not support locking. + * + * See the documentation of ILockBytes for more info. + */ +HRESULT WINAPI HGLOBALLockBytesImpl_LockRegion( + ILockBytes* iface, + ULARGE_INTEGER libOffset, /* [in] */ + ULARGE_INTEGER cb, /* [in] */ + DWORD dwLockType) /* [in] */ +{ + return STG_E_INVALIDFUNCTION; +} + +/****************************************************************************** + * This method is part of the ILockBytes interface. + * + * The global memory implementation of ILockBytes does not support locking. + * + * See the documentation of ILockBytes for more info. + */ +HRESULT WINAPI HGLOBALLockBytesImpl_UnlockRegion( + ILockBytes* iface, + ULARGE_INTEGER libOffset, /* [in] */ + ULARGE_INTEGER cb, /* [in] */ + DWORD dwLockType) /* [in] */ +{ + return STG_E_INVALIDFUNCTION; +} + +/****************************************************************************** + * This method is part of the ILockBytes interface. + * + * This method returns information about the current + * byte array object. + * + * See the documentation of ILockBytes for more info. + */ +HRESULT WINAPI HGLOBALLockBytesImpl_Stat( + ILockBytes* iface, + STATSTG* pstatstg, /* [out] */ + DWORD grfStatFlag) /* [in] */ +{ + HGLOBALLockBytesImpl* const This=(HGLOBALLockBytesImpl*)iface; + + memset(pstatstg, 0, sizeof(STATSTG)); + + pstatstg->pwcsName = NULL; + pstatstg->type = STGTY_LOCKBYTES; + pstatstg->cbSize = This->byteArraySize; + + return S_OK; +} + +/****************************************************************************** + * HGLOBALLockBytesImpl16 definition. + * + * This class imlements the ILockBytes inteface and represents a byte array + * object supported by an HGLOBAL pointer. + */ +struct HGLOBALLockBytesImpl16 +{ + /* + * Needs to be the first item in the stuct + * since we want to cast this in an ILockBytes pointer + */ + ICOM_VFIELD(ILockBytes16); + ULONG ref; + + /* + * Support for the LockBytes object + */ + HGLOBAL16 supportHandle; + + /* + * This flag is TRUE if the HGLOBAL is destroyed when the object + * is finally released. + */ + BOOL deleteOnRelease; + /* + * Helper variable that contains the size of the byte array + */ + ULARGE_INTEGER byteArraySize; +}; + +typedef struct HGLOBALLockBytesImpl16 HGLOBALLockBytesImpl16; + +HGLOBALLockBytesImpl16* HGLOBALLockBytesImpl16_Construct( + HGLOBAL16 hGlobal, + BOOL16 fDeleteOnRelease); + +void HGLOBALLockBytesImpl16_Destroy(HGLOBALLockBytesImpl16* This); + +HRESULT WINAPI HGLOBALLockBytesImpl16_QueryInterface( + ILockBytes16* iface, + REFIID riid, /* [in] */ + void** ppvObject); /* [iid_is][out] */ + +ULONG WINAPI HGLOBALLockBytesImpl16_AddRef( + ILockBytes16* iface); + +ULONG WINAPI HGLOBALLockBytesImpl16_Release( + ILockBytes16* iface); + +HRESULT WINAPI HGLOBALLockBytesImpl16_ReadAt( + ILockBytes16* iface, + ULARGE_INTEGER ulOffset, /* [in] */ + void* pv, /* [length_is][size_is][out] */ + ULONG cb, /* [in] */ + ULONG* pcbRead); /* [out] */ + +HRESULT WINAPI HGLOBALLockBytesImpl16_WriteAt( + ILockBytes16* iface, + ULARGE_INTEGER ulOffset, /* [in] */ + const void* pv, /* [size_is][in] */ + ULONG cb, /* [in] */ + ULONG* pcbWritten); /* [out] */ + +HRESULT WINAPI HGLOBALLockBytesImpl16_Flush( + ILockBytes16* iface); + +HRESULT WINAPI HGLOBALLockBytesImpl16_SetSize( + ILockBytes16* iface, + ULARGE_INTEGER libNewSize); /* [in] */ + +HRESULT WINAPI HGLOBALLockBytesImpl16_LockRegion( + ILockBytes16* iface, + ULARGE_INTEGER libOffset, /* [in] */ + ULARGE_INTEGER cb, /* [in] */ + DWORD dwLockType); /* [in] */ + +HRESULT WINAPI HGLOBALLockBytesImpl16_UnlockRegion( + ILockBytes16* iface, + ULARGE_INTEGER libOffset, /* [in] */ + ULARGE_INTEGER cb, /* [in] */ + DWORD dwLockType); /* [in] */ + +HRESULT WINAPI HGLOBALLockBytesImpl16_Stat( + ILockBytes16* iface, + STATSTG16* pstatstg, /* [out] */ + DWORD grfStatFlag); /* [in] */ + +/****************************************************************************** + * + * HGLOBALLockBytesImpl16 implementation + * + */ + +/****************************************************************************** + * This is the constructor for the HGLOBALLockBytesImpl16 class. + * + * Params: + * hGlobal - Handle that will support the stream. can be NULL. + * fDeleteOnRelease - Flag set to TRUE if the HGLOBAL16 will be released + * when the IStream object is destroyed. + */ +HGLOBALLockBytesImpl16* +HGLOBALLockBytesImpl16_Construct(HGLOBAL16 hGlobal, + BOOL16 fDeleteOnRelease) +{ + HGLOBALLockBytesImpl16* newLockBytes; + + static ICOM_VTABLE(ILockBytes16) vt16; + static SEGPTR msegvt16; + HMODULE16 hcomp = GetModuleHandle16("OLE2"); + + + TRACE("(%x,%d)\n",hGlobal,fDeleteOnRelease); + newLockBytes = HeapAlloc(GetProcessHeap(), 0, sizeof(HGLOBALLockBytesImpl16)); + if (newLockBytes == NULL) + return NULL; + + /* + * Set up the virtual function table and reference count. + */ + if (!msegvt16) + { +#define VTENT(x) vt16.x = (void*)GetProcAddress16(hcomp,"HGLOBALLockBytesImpl16_"#x);assert(vt16.x) + VTENT(QueryInterface); + VTENT(AddRef); + VTENT(Release); + VTENT(ReadAt); + VTENT(WriteAt); + VTENT(Flush); + VTENT(SetSize); + VTENT(LockRegion); + VTENT(UnlockRegion); +#undef VTENT + msegvt16 = MapLS( &vt16 ); + } + newLockBytes->lpVtbl = (ICOM_VTABLE(ILockBytes16)*)msegvt16; + newLockBytes->ref = 0; + /* + * Initialize the support. + */ + newLockBytes->supportHandle = hGlobal; + newLockBytes->deleteOnRelease = fDeleteOnRelease; + + /* + * This method will allocate a handle if one is not supplied. + */ + if (newLockBytes->supportHandle == 0) + newLockBytes->supportHandle = GlobalAlloc16(GMEM_MOVEABLE | GMEM_NODISCARD, 0); + + /* + * Initialize the size of the array to the size of the handle. + */ + newLockBytes->byteArraySize.s.HighPart = 0; + newLockBytes->byteArraySize.s.LowPart = GlobalSize16( + newLockBytes->supportHandle); + + return (HGLOBALLockBytesImpl16*)MapLS(newLockBytes); +} + +/****************************************************************************** + * This is the destructor of the HGLOBALStreamImpl class. + * + * This method will clean-up all the resources used-up by the given + * HGLOBALLockBytesImpl16 class. The pointer passed-in to this function will be + * freed and will not be valid anymore. + */ +void HGLOBALLockBytesImpl16_Destroy(HGLOBALLockBytesImpl16* This) +{ + TRACE("()\n"); + /* + * Release the HGlobal if the constructor asked for that. + */ + if (This->deleteOnRelease) + { + GlobalFree16(This->supportHandle); + This->supportHandle = 0; + } + + /* + * Finally, free the memory used-up by the class. + */ + HeapFree(GetProcessHeap(), 0, This); +} + +/****************************************************************************** + * This implements the IUnknown method QueryInterface for this + * class + */ +HRESULT WINAPI HGLOBALLockBytesImpl16_QueryInterface( + ILockBytes16* iface, /* [in] SEGPTR */ + REFIID riid, /* [in] */ + void** ppvObject) /* [iid_is][out] (ptr to SEGPTR!) */ +{ + HGLOBALLockBytesImpl16* const This=(HGLOBALLockBytesImpl16*)MapSL((SEGPTR)iface); + + TRACE("(%p,%s,%p)\n",iface,debugstr_guid(riid),ppvObject); + /* + * Perform a sanity check on the parameters. + */ + if (ppvObject==0) + return E_INVALIDARG; + + /* + * Initialize the return parameter. + */ + *ppvObject = 0; + /* + * Compare the riid with the interface IDs implemented by this object. + */ + if ( !memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) || + !memcmp(&IID_ILockBytes, riid, sizeof(IID_ILockBytes)) + ) + *ppvObject = (void*)iface; + + /* + * Check that we obtained an interface. + */ + if ((*ppvObject)==0) + return E_NOINTERFACE; + + /* + * Query Interface always increases the reference count by one when it is + * successful + */ + HGLOBALLockBytesImpl16_AddRef((ILockBytes16*)This); + + return S_OK; +} + +/****************************************************************************** + * This implements the IUnknown method AddRef for this + * class + */ +ULONG WINAPI HGLOBALLockBytesImpl16_AddRef(ILockBytes16* iface) +{ + HGLOBALLockBytesImpl16* const This=(HGLOBALLockBytesImpl16*)iface; + + TRACE("(%p)\n",This); + + This->ref++; + + return This->ref; +} + +/****************************************************************************** + * This implements the IUnknown method Release for this + * class + */ +ULONG WINAPI HGLOBALLockBytesImpl16_Release(ILockBytes16* iface) +{ + HGLOBALLockBytesImpl16* const This=(HGLOBALLockBytesImpl16*)iface; + + ULONG newRef; + TRACE("(%p)\n",This); + + This->ref--; + + newRef = This->ref; + + /* + * If the reference count goes down to 0, perform suicide. + */ + if (newRef==0) + HGLOBALLockBytesImpl16_Destroy(This); + return newRef; +} + +/****************************************************************************** + * This method is part of the ILockBytes interface. + * + * It reads a block of information from the byte array at the specified + * offset. + * + * See the documentation of ILockBytes for more info. + */ +HRESULT WINAPI HGLOBALLockBytesImpl16_ReadAt( + ILockBytes16* iface, + ULARGE_INTEGER ulOffset, /* [in] */ + void* pv, /* [length_is][size_is][out] */ + ULONG cb, /* [in] */ + ULONG* pcbRead) /* [out] */ +{ + HGLOBALLockBytesImpl16* const This=(HGLOBALLockBytesImpl16*)iface; + + void* supportBuffer; + ULONG bytesReadBuffer = 0; + ULONG bytesToReadFromBuffer; + + TRACE("(%p,%ld,%p,%ld,%p)\n",This,ulOffset.s.LowPart,pv,cb,pcbRead); + /* + * If the caller is not interested in the number of bytes read, + * we use another buffer to avoid "if" statements in the code. + */ + if (pcbRead == 0) + pcbRead = &bytesReadBuffer; + + /* + * Make sure the offset is valid. + */ + if (ulOffset.s.LowPart > This->byteArraySize.s.LowPart) + return E_FAIL; + + /* + * Using the known size of the array, calculate the number of bytes + * to read. + */ + bytesToReadFromBuffer = min(This->byteArraySize.s.LowPart - + ulOffset.s.LowPart, cb); + + /* + * Lock the buffer in position and copy the data. + */ + supportBuffer = GlobalLock16(This->supportHandle); + + memcpy(pv, + (char *) supportBuffer + ulOffset.s.LowPart, + bytesToReadFromBuffer); + + /* + * Return the number of bytes read. + */ + *pcbRead = bytesToReadFromBuffer; + + /* + * Cleanup + */ + GlobalUnlock16(This->supportHandle); + + /* + * The function returns S_OK if the specified number of bytes were read + * or the end of the array was reached. + * It returns STG_E_READFAULT if the number of bytes to read does not equal + * the number of bytes actually read. + */ + if(*pcbRead == cb) + return S_OK; + + return STG_E_READFAULT; +} + +/****************************************************************************** + * This method is part of the ILockBytes interface. + * + * It writes the specified bytes at the specified offset. + * position. If the array is too small, it will be resized. + * + * See the documentation of ILockBytes for more info. + */ +HRESULT WINAPI HGLOBALLockBytesImpl16_WriteAt( + ILockBytes16* iface, + ULARGE_INTEGER ulOffset, /* [in] */ + const void* pv, /* [size_is][in] */ + ULONG cb, /* [in] */ + ULONG* pcbWritten) /* [out] */ +{ + HGLOBALLockBytesImpl16* const This=(HGLOBALLockBytesImpl16*)iface; + + void* supportBuffer; + ULARGE_INTEGER newSize; + ULONG bytesWritten = 0; + + TRACE("(%p,%ld,%p,%ld,%p)\n",This,ulOffset.s.LowPart,pv,cb,pcbWritten); + /* + * If the caller is not interested in the number of bytes written, + * we use another buffer to avoid "if" statements in the code. + */ + if (pcbWritten == 0) + pcbWritten = &bytesWritten; + + if (cb == 0) + return S_OK; + + newSize.s.HighPart = 0; + newSize.s.LowPart = ulOffset.s.LowPart + cb; + + /* + * Verify if we need to grow the stream + */ + if (newSize.s.LowPart > This->byteArraySize.s.LowPart) + { + /* grow stream */ + if (HGLOBALLockBytesImpl16_SetSize(iface, newSize) == STG_E_MEDIUMFULL) + return STG_E_MEDIUMFULL; + } + + /* + * Lock the buffer in position and copy the data. + */ + supportBuffer = GlobalLock16(This->supportHandle); + + memcpy((char *) supportBuffer + ulOffset.s.LowPart, pv, cb); + + /* + * Return the number of bytes written. + */ + *pcbWritten = cb; + + /* + * Cleanup + */ + GlobalUnlock16(This->supportHandle); + + return S_OK; +} + +/****************************************************************************** + * This method is part of the ILockBytes interface. + * + * See the documentation of ILockBytes for more info. + */ +HRESULT WINAPI HGLOBALLockBytesImpl16_Flush(ILockBytes16* iface) +{ + TRACE("(%p)\n",iface); + return S_OK; +} + +/****************************************************************************** + * This method is part of the ILockBytes interface. + * + * It will change the size of the byte array. + * + * See the documentation of ILockBytes for more info. + */ +HRESULT WINAPI HGLOBALLockBytesImpl16_SetSize( + ILockBytes16* iface, + ULARGE_INTEGER libNewSize) /* [in] */ +{ + HGLOBALLockBytesImpl16* const This=(HGLOBALLockBytesImpl16*)iface; + + TRACE("(%p,%ld)\n",This,libNewSize.s.LowPart); + /* + * As documented. + */ + if (libNewSize.s.HighPart != 0) + return STG_E_INVALIDFUNCTION; + + if (This->byteArraySize.s.LowPart == libNewSize.s.LowPart) + return S_OK; + + /* + * Re allocate the HGlobal to fit the new size of the stream. + */ + This->supportHandle = GlobalReAlloc16(This->supportHandle, + libNewSize.s.LowPart, + 0); + + if (This->supportHandle == 0) + return STG_E_MEDIUMFULL; + + This->byteArraySize.s.LowPart = libNewSize.s.LowPart; + + return S_OK; +} + +/****************************************************************************** + * This method is part of the ILockBytes interface. + * + * The global memory implementation of ILockBytes does not support locking. + * + * See the documentation of ILockBytes for more info. + */ +HRESULT WINAPI HGLOBALLockBytesImpl16_LockRegion( + ILockBytes16* iface, + ULARGE_INTEGER libOffset, /* [in] */ + ULARGE_INTEGER cb, /* [in] */ + DWORD dwLockType) /* [in] */ +{ + return STG_E_INVALIDFUNCTION; +} + +/****************************************************************************** + * This method is part of the ILockBytes interface. + * + * The global memory implementation of ILockBytes does not support locking. + * + * See the documentation of ILockBytes for more info. + */ +HRESULT WINAPI HGLOBALLockBytesImpl16_UnlockRegion( + ILockBytes16* iface, + ULARGE_INTEGER libOffset, /* [in] */ + ULARGE_INTEGER cb, /* [in] */ + DWORD dwLockType) /* [in] */ +{ + return STG_E_INVALIDFUNCTION; +} + +/****************************************************************************** + * This method is part of the ILockBytes interface. + * + * This method returns information about the current + * byte array object. + * + * See the documentation of ILockBytes for more info. + */ +HRESULT WINAPI HGLOBALLockBytesImpl16_Stat( + ILockBytes16*iface, + STATSTG16* pstatstg, /* [out] */ + DWORD grfStatFlag) /* [in] */ +{ + HGLOBALLockBytesImpl16* const This=(HGLOBALLockBytesImpl16*)iface; + + memset(pstatstg, 0, sizeof(STATSTG16)); + + pstatstg->pwcsName = NULL; + pstatstg->type = STGTY_LOCKBYTES; + pstatstg->cbSize = This->byteArraySize; + + return S_OK; +} + +/****************************************************************************** + * CreateILockBytesOnHGlobal [OLE2.54] + * + * Creates an ILockBytes interface for a HGLOBAL handle. + * + * Params: + * hGlobal the global handle (16bit) + * fDeleteOnRelease delete handle on release. + * ppLkbyt pointer to ILockBytes interface. + * + * Returns: + * Staddard OLE error return codes. + * + */ +HRESULT WINAPI CreateILockBytesOnHGlobal16(HGLOBAL16 hGlobal, + BOOL16 fDeleteOnRelease, + /*SEGPTR**/ LPLOCKBYTES16* ppLkbyt) +{ + HGLOBALLockBytesImpl16* newLockBytes; /* SEGPTR */ + + newLockBytes = HGLOBALLockBytesImpl16_Construct(hGlobal, fDeleteOnRelease); + + if (newLockBytes != NULL) + return HGLOBALLockBytesImpl16_QueryInterface((ILockBytes16*)newLockBytes, + &IID_ILockBytes, + (void**)ppLkbyt); + return E_OUTOFMEMORY; +} Index: Makefile.in =================================================================== RCS file: /home/wine/wine/dlls/ole32/Makefile.in,v retrieving revision 1.29 diff -u -r1.29 Makefile.in --- Makefile.in 28 Mar 2003 19:33:04 -0000 1.29 +++ Makefile.in 15 May 2003 14:24:34 -0000 @@ -45,7 +45,9 @@ storage.c \ storage32.c -C_SRCS16 = ole2nls.c +C_SRCS16 = ole2nls.c \ + memlockbytes16.c + RC_SRCS = ole32res.rc version.rc Index: memlockbytes.c =================================================================== RCS file: /home/wine/wine/dlls/ole32/memlockbytes.c,v retrieving revision 1.11 diff -u -r1.11 memlockbytes.c --- memlockbytes.c 10 Apr 2003 18:17:35 -0000 1.11 +++ memlockbytes.c 15 May 2003 14:22:40 -0000 @@ -215,951 +215,3 @@ return S_OK; } -/****************************************************************************** - * - * HGLOBALLockBytesImpl implementation - * - */ - -/****************************************************************************** - * This is the constructor for the HGLOBALLockBytesImpl class. - * - * Params: - * hGlobal - Handle that will support the stream. can be NULL. - * fDeleteOnRelease - Flag set to TRUE if the HGLOBAL will be released - * when the IStream object is destroyed. - */ -HGLOBALLockBytesImpl* HGLOBALLockBytesImpl_Construct(HGLOBAL hGlobal, - BOOL fDeleteOnRelease) -{ - HGLOBALLockBytesImpl* newLockBytes; - newLockBytes = HeapAlloc(GetProcessHeap(), 0, sizeof(HGLOBALLockBytesImpl)); - - if (newLockBytes!=0) - { - /* - * Set up the virtual function table and reference count. - */ - newLockBytes->lpVtbl = &HGLOBALLockBytesImpl_Vtbl; - newLockBytes->ref = 0; - - /* - * Initialize the support. - */ - newLockBytes->supportHandle = hGlobal; - newLockBytes->deleteOnRelease = fDeleteOnRelease; - - /* - * This method will allocate a handle if one is not supplied. - */ - if (newLockBytes->supportHandle == 0) - { - newLockBytes->supportHandle = GlobalAlloc(GMEM_MOVEABLE | - GMEM_NODISCARD, - 0); - } - - /* - * Initialize the size of the array to the size of the handle. - */ - newLockBytes->byteArraySize.s.HighPart = 0; - newLockBytes->byteArraySize.s.LowPart = GlobalSize( - newLockBytes->supportHandle); - } - - return newLockBytes; -} - -/****************************************************************************** - * This is the destructor of the HGLOBALStreamImpl class. - * - * This method will clean-up all the resources used-up by the given - * HGLOBALLockBytesImpl class. The pointer passed-in to this function will be - * freed and will not be valid anymore. - */ -void HGLOBALLockBytesImpl_Destroy(HGLOBALLockBytesImpl* This) -{ - /* - * Release the HGlobal if the constructor asked for that. - */ - if (This->deleteOnRelease) - { - GlobalFree(This->supportHandle); - This->supportHandle = 0; - } - - /* - * Finally, free the memory used-up by the class. - */ - HeapFree(GetProcessHeap(), 0, This); -} - -/****************************************************************************** - * This implements the IUnknown method QueryInterface for this - * class - */ -HRESULT WINAPI HGLOBALLockBytesImpl_QueryInterface( - ILockBytes* iface, - REFIID riid, /* [in] */ - void** ppvObject) /* [iid_is][out] */ -{ - HGLOBALLockBytesImpl* const This=(HGLOBALLockBytesImpl*)iface; - - /* - * Perform a sanity check on the parameters. - */ - if (ppvObject==0) - return E_INVALIDARG; - - /* - * Initialize the return parameter. - */ - *ppvObject = 0; - - /* - * Compare the riid with the interface IDs implemented by this object. - */ - if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0) - { - *ppvObject = (ILockBytes*)This; - } - else if (memcmp(&IID_ILockBytes, riid, sizeof(IID_ILockBytes)) == 0) - { - *ppvObject = (ILockBytes*)This; - } - - /* - * Check that we obtained an interface. - */ - if ((*ppvObject)==0) - return E_NOINTERFACE; - - /* - * Query Interface always increases the reference count by one when it is - * successful - */ - HGLOBALLockBytesImpl_AddRef(iface); - - return S_OK; -} - -/****************************************************************************** - * This implements the IUnknown method AddRef for this - * class - */ -ULONG WINAPI HGLOBALLockBytesImpl_AddRef(ILockBytes* iface) -{ - HGLOBALLockBytesImpl* const This=(HGLOBALLockBytesImpl*)iface; - - This->ref++; - - return This->ref; -} - -/****************************************************************************** - * This implements the IUnknown method Release for this - * class - */ -ULONG WINAPI HGLOBALLockBytesImpl_Release(ILockBytes* iface) -{ - HGLOBALLockBytesImpl* const This=(HGLOBALLockBytesImpl*)iface; - - ULONG newRef; - - This->ref--; - - newRef = This->ref; - - /* - * If the reference count goes down to 0, perform suicide. - */ - if (newRef==0) - { - HGLOBALLockBytesImpl_Destroy(This); - } - - return newRef; -} - -/****************************************************************************** - * This method is part of the ILockBytes interface. - * - * It reads a block of information from the byte array at the specified - * offset. - * - * See the documentation of ILockBytes for more info. - */ -HRESULT WINAPI HGLOBALLockBytesImpl_ReadAt( - ILockBytes* iface, - ULARGE_INTEGER ulOffset, /* [in] */ - void* pv, /* [length_is][size_is][out] */ - ULONG cb, /* [in] */ - ULONG* pcbRead) /* [out] */ -{ - HGLOBALLockBytesImpl* const This=(HGLOBALLockBytesImpl*)iface; - - void* supportBuffer; - ULONG bytesReadBuffer = 0; - ULONG bytesToReadFromBuffer; - - /* - * If the caller is not interested in the number of bytes read, - * we use another buffer to avoid "if" statements in the code. - */ - if (pcbRead == 0) - pcbRead = &bytesReadBuffer; - - /* - * Make sure the offset is valid. - */ - if (ulOffset.s.LowPart > This->byteArraySize.s.LowPart) - return E_FAIL; - - /* - * Using the known size of the array, calculate the number of bytes - * to read. - */ - bytesToReadFromBuffer = min(This->byteArraySize.s.LowPart - - ulOffset.s.LowPart, cb); - - /* - * Lock the buffer in position and copy the data. - */ - supportBuffer = GlobalLock(This->supportHandle); - - memcpy(pv, - (char *) supportBuffer + ulOffset.s.LowPart, - bytesToReadFromBuffer); - - /* - * Return the number of bytes read. - */ - *pcbRead = bytesToReadFromBuffer; - - /* - * Cleanup - */ - GlobalUnlock(This->supportHandle); - - /* - * The function returns S_OK if the specified number of bytes were read - * or the end of the array was reached. - * It returns STG_E_READFAULT if the number of bytes to read does not equal - * the number of bytes actually read. - */ - if(*pcbRead == cb) - return S_OK; - - return STG_E_READFAULT; -} - -/****************************************************************************** - * This method is part of the ILockBytes interface. - * - * It writes the specified bytes at the specified offset. - * position. If the array is too small, it will be resized. - * - * See the documentation of ILockBytes for more info. - */ -HRESULT WINAPI HGLOBALLockBytesImpl_WriteAt( - ILockBytes* iface, - ULARGE_INTEGER ulOffset, /* [in] */ - const void* pv, /* [size_is][in] */ - ULONG cb, /* [in] */ - ULONG* pcbWritten) /* [out] */ -{ - HGLOBALLockBytesImpl* const This=(HGLOBALLockBytesImpl*)iface; - - void* supportBuffer; - ULARGE_INTEGER newSize; - ULONG bytesWritten = 0; - - /* - * If the caller is not interested in the number of bytes written, - * we use another buffer to avoid "if" statements in the code. - */ - if (pcbWritten == 0) - pcbWritten = &bytesWritten; - - if (cb == 0) - { - return S_OK; - } - else - { - newSize.s.HighPart = 0; - newSize.s.LowPart = ulOffset.s.LowPart + cb; - } - - /* - * Verify if we need to grow the stream - */ - if (newSize.s.LowPart > This->byteArraySize.s.LowPart) - { - /* grow stream */ - if (HGLOBALLockBytesImpl_SetSize(iface, newSize) == STG_E_MEDIUMFULL) - return STG_E_MEDIUMFULL; - } - - /* - * Lock the buffer in position and copy the data. - */ - supportBuffer = GlobalLock(This->supportHandle); - - memcpy((char *) supportBuffer + ulOffset.s.LowPart, pv, cb); - - /* - * Return the number of bytes written. - */ - *pcbWritten = cb; - - /* - * Cleanup - */ - GlobalUnlock(This->supportHandle); - - return S_OK; -} - -/****************************************************************************** - * This method is part of the ILockBytes interface. - * - * See the documentation of ILockBytes for more info. - */ -HRESULT WINAPI HGLOBALLockBytesImpl_Flush(ILockBytes* iface) -{ - return S_OK; -} - -/****************************************************************************** - * This method is part of the ILockBytes interface. - * - * It will change the size of the byte array. - * - * See the documentation of ILockBytes for more info. - */ -HRESULT WINAPI HGLOBALLockBytesImpl_SetSize( - ILockBytes* iface, - ULARGE_INTEGER libNewSize) /* [in] */ -{ - HGLOBALLockBytesImpl* const This=(HGLOBALLockBytesImpl*)iface; - - /* - * As documented. - */ - if (libNewSize.s.HighPart != 0) - return STG_E_INVALIDFUNCTION; - - if (This->byteArraySize.s.LowPart == libNewSize.s.LowPart) - return S_OK; - - /* - * Re allocate the HGlobal to fit the new size of the stream. - */ - This->supportHandle = GlobalReAlloc(This->supportHandle, - libNewSize.s.LowPart, - 0); - - if (This->supportHandle == 0) - return STG_E_MEDIUMFULL; - - This->byteArraySize.s.LowPart = libNewSize.s.LowPart; - - return S_OK; -} - -/****************************************************************************** - * This method is part of the ILockBytes interface. - * - * The global memory implementation of ILockBytes does not support locking. - * - * See the documentation of ILockBytes for more info. - */ -HRESULT WINAPI HGLOBALLockBytesImpl_LockRegion( - ILockBytes* iface, - ULARGE_INTEGER libOffset, /* [in] */ - ULARGE_INTEGER cb, /* [in] */ - DWORD dwLockType) /* [in] */ -{ - return STG_E_INVALIDFUNCTION; -} - -/****************************************************************************** - * This method is part of the ILockBytes interface. - * - * The global memory implementation of ILockBytes does not support locking. - * - * See the documentation of ILockBytes for more info. - */ -HRESULT WINAPI HGLOBALLockBytesImpl_UnlockRegion( - ILockBytes* iface, - ULARGE_INTEGER libOffset, /* [in] */ - ULARGE_INTEGER cb, /* [in] */ - DWORD dwLockType) /* [in] */ -{ - return STG_E_INVALIDFUNCTION; -} - -/****************************************************************************** - * This method is part of the ILockBytes interface. - * - * This method returns information about the current - * byte array object. - * - * See the documentation of ILockBytes for more info. - */ -HRESULT WINAPI HGLOBALLockBytesImpl_Stat( - ILockBytes* iface, - STATSTG* pstatstg, /* [out] */ - DWORD grfStatFlag) /* [in] */ -{ - HGLOBALLockBytesImpl* const This=(HGLOBALLockBytesImpl*)iface; - - memset(pstatstg, 0, sizeof(STATSTG)); - - pstatstg->pwcsName = NULL; - pstatstg->type = STGTY_LOCKBYTES; - pstatstg->cbSize = This->byteArraySize; - - return S_OK; -} - -/****************************************************************************** - * HGLOBALLockBytesImpl16 definition. - * - * This class imlements the ILockBytes inteface and represents a byte array - * object supported by an HGLOBAL pointer. - */ -struct HGLOBALLockBytesImpl16 -{ - /* - * Needs to be the first item in the stuct - * since we want to cast this in an ILockBytes pointer - */ - ICOM_VFIELD(ILockBytes16); - ULONG ref; - - /* - * Support for the LockBytes object - */ - HGLOBAL16 supportHandle; - - /* - * This flag is TRUE if the HGLOBAL is destroyed when the object - * is finally released. - */ - BOOL deleteOnRelease; - /* - * Helper variable that contains the size of the byte array - */ - ULARGE_INTEGER byteArraySize; -}; - -typedef struct HGLOBALLockBytesImpl16 HGLOBALLockBytesImpl16; - -HGLOBALLockBytesImpl16* HGLOBALLockBytesImpl16_Construct( - HGLOBAL16 hGlobal, - BOOL16 fDeleteOnRelease); - -void HGLOBALLockBytesImpl16_Destroy(HGLOBALLockBytesImpl16* This); - -HRESULT WINAPI HGLOBALLockBytesImpl16_QueryInterface( - ILockBytes16* iface, - REFIID riid, /* [in] */ - void** ppvObject); /* [iid_is][out] */ - -ULONG WINAPI HGLOBALLockBytesImpl16_AddRef( - ILockBytes16* iface); - -ULONG WINAPI HGLOBALLockBytesImpl16_Release( - ILockBytes16* iface); - -HRESULT WINAPI HGLOBALLockBytesImpl16_ReadAt( - ILockBytes16* iface, - ULARGE_INTEGER ulOffset, /* [in] */ - void* pv, /* [length_is][size_is][out] */ - ULONG cb, /* [in] */ - ULONG* pcbRead); /* [out] */ - -HRESULT WINAPI HGLOBALLockBytesImpl16_WriteAt( - ILockBytes16* iface, - ULARGE_INTEGER ulOffset, /* [in] */ - const void* pv, /* [size_is][in] */ - ULONG cb, /* [in] */ - ULONG* pcbWritten); /* [out] */ - -HRESULT WINAPI HGLOBALLockBytesImpl16_Flush( - ILockBytes16* iface); - -HRESULT WINAPI HGLOBALLockBytesImpl16_SetSize( - ILockBytes16* iface, - ULARGE_INTEGER libNewSize); /* [in] */ - -HRESULT WINAPI HGLOBALLockBytesImpl16_LockRegion( - ILockBytes16* iface, - ULARGE_INTEGER libOffset, /* [in] */ - ULARGE_INTEGER cb, /* [in] */ - DWORD dwLockType); /* [in] */ - -HRESULT WINAPI HGLOBALLockBytesImpl16_UnlockRegion( - ILockBytes16* iface, - ULARGE_INTEGER libOffset, /* [in] */ - ULARGE_INTEGER cb, /* [in] */ - DWORD dwLockType); /* [in] */ - -HRESULT WINAPI HGLOBALLockBytesImpl16_Stat( - ILockBytes16* iface, - STATSTG16* pstatstg, /* [out] */ - DWORD grfStatFlag); /* [in] */ - -/****************************************************************************** - * - * HGLOBALLockBytesImpl16 implementation - * - */ - -/****************************************************************************** - * This is the constructor for the HGLOBALLockBytesImpl16 class. - * - * Params: - * hGlobal - Handle that will support the stream. can be NULL. - * fDeleteOnRelease - Flag set to TRUE if the HGLOBAL16 will be released - * when the IStream object is destroyed. - */ -HGLOBALLockBytesImpl16* -HGLOBALLockBytesImpl16_Construct(HGLOBAL16 hGlobal, - BOOL16 fDeleteOnRelease) -{ - HGLOBALLockBytesImpl16* newLockBytes; - - static ICOM_VTABLE(ILockBytes16) vt16; - static SEGPTR msegvt16; - HMODULE16 hcomp = GetModuleHandle16("OLE2"); - - - TRACE("(%x,%d)\n",hGlobal,fDeleteOnRelease); - newLockBytes = HeapAlloc(GetProcessHeap(), 0, sizeof(HGLOBALLockBytesImpl16)); - if (newLockBytes == NULL) - return NULL; - - /* - * Set up the virtual function table and reference count. - */ - if (!msegvt16) - { -#define VTENT(x) vt16.x = (void*)GetProcAddress16(hcomp,"HGLOBALLockBytesImpl16_"#x);assert(vt16.x) - VTENT(QueryInterface); - VTENT(AddRef); - VTENT(Release); - VTENT(ReadAt); - VTENT(WriteAt); - VTENT(Flush); - VTENT(SetSize); - VTENT(LockRegion); - VTENT(UnlockRegion); -#undef VTENT - msegvt16 = MapLS( &vt16 ); - } - newLockBytes->lpVtbl = (ICOM_VTABLE(ILockBytes16)*)msegvt16; - newLockBytes->ref = 0; - /* - * Initialize the support. - */ - newLockBytes->supportHandle = hGlobal; - newLockBytes->deleteOnRelease = fDeleteOnRelease; - - /* - * This method will allocate a handle if one is not supplied. - */ - if (newLockBytes->supportHandle == 0) - newLockBytes->supportHandle = GlobalAlloc16(GMEM_MOVEABLE | GMEM_NODISCARD, 0); - - /* - * Initialize the size of the array to the size of the handle. - */ - newLockBytes->byteArraySize.s.HighPart = 0; - newLockBytes->byteArraySize.s.LowPart = GlobalSize16( - newLockBytes->supportHandle); - - return (HGLOBALLockBytesImpl16*)MapLS(newLockBytes); -} - -/****************************************************************************** - * This is the destructor of the HGLOBALStreamImpl class. - * - * This method will clean-up all the resources used-up by the given - * HGLOBALLockBytesImpl16 class. The pointer passed-in to this function will be - * freed and will not be valid anymore. - */ -void HGLOBALLockBytesImpl16_Destroy(HGLOBALLockBytesImpl16* This) -{ - TRACE("()\n"); - /* - * Release the HGlobal if the constructor asked for that. - */ - if (This->deleteOnRelease) - { - GlobalFree16(This->supportHandle); - This->supportHandle = 0; - } - - /* - * Finally, free the memory used-up by the class. - */ - HeapFree(GetProcessHeap(), 0, This); -} - -/****************************************************************************** - * This implements the IUnknown method QueryInterface for this - * class - */ -HRESULT WINAPI HGLOBALLockBytesImpl16_QueryInterface( - ILockBytes16* iface, /* [in] SEGPTR */ - REFIID riid, /* [in] */ - void** ppvObject) /* [iid_is][out] (ptr to SEGPTR!) */ -{ - HGLOBALLockBytesImpl16* const This=(HGLOBALLockBytesImpl16*)MapSL((SEGPTR)iface); - - TRACE("(%p,%s,%p)\n",iface,debugstr_guid(riid),ppvObject); - /* - * Perform a sanity check on the parameters. - */ - if (ppvObject==0) - return E_INVALIDARG; - - /* - * Initialize the return parameter. - */ - *ppvObject = 0; - /* - * Compare the riid with the interface IDs implemented by this object. - */ - if ( !memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) || - !memcmp(&IID_ILockBytes, riid, sizeof(IID_ILockBytes)) - ) - *ppvObject = (void*)iface; - - /* - * Check that we obtained an interface. - */ - if ((*ppvObject)==0) - return E_NOINTERFACE; - - /* - * Query Interface always increases the reference count by one when it is - * successful - */ - HGLOBALLockBytesImpl16_AddRef((ILockBytes16*)This); - - return S_OK; -} - -/****************************************************************************** - * This implements the IUnknown method AddRef for this - * class - */ -ULONG WINAPI HGLOBALLockBytesImpl16_AddRef(ILockBytes16* iface) -{ - HGLOBALLockBytesImpl16* const This=(HGLOBALLockBytesImpl16*)iface; - - TRACE("(%p)\n",This); - - This->ref++; - - return This->ref; -} - -/****************************************************************************** - * This implements the IUnknown method Release for this - * class - */ -ULONG WINAPI HGLOBALLockBytesImpl16_Release(ILockBytes16* iface) -{ - HGLOBALLockBytesImpl16* const This=(HGLOBALLockBytesImpl16*)iface; - - ULONG newRef; - TRACE("(%p)\n",This); - - This->ref--; - - newRef = This->ref; - - /* - * If the reference count goes down to 0, perform suicide. - */ - if (newRef==0) - HGLOBALLockBytesImpl16_Destroy(This); - return newRef; -} - -/****************************************************************************** - * This method is part of the ILockBytes interface. - * - * It reads a block of information from the byte array at the specified - * offset. - * - * See the documentation of ILockBytes for more info. - */ -HRESULT WINAPI HGLOBALLockBytesImpl16_ReadAt( - ILockBytes16* iface, - ULARGE_INTEGER ulOffset, /* [in] */ - void* pv, /* [length_is][size_is][out] */ - ULONG cb, /* [in] */ - ULONG* pcbRead) /* [out] */ -{ - HGLOBALLockBytesImpl16* const This=(HGLOBALLockBytesImpl16*)iface; - - void* supportBuffer; - ULONG bytesReadBuffer = 0; - ULONG bytesToReadFromBuffer; - - TRACE("(%p,%ld,%p,%ld,%p)\n",This,ulOffset.s.LowPart,pv,cb,pcbRead); - /* - * If the caller is not interested in the number of bytes read, - * we use another buffer to avoid "if" statements in the code. - */ - if (pcbRead == 0) - pcbRead = &bytesReadBuffer; - - /* - * Make sure the offset is valid. - */ - if (ulOffset.s.LowPart > This->byteArraySize.s.LowPart) - return E_FAIL; - - /* - * Using the known size of the array, calculate the number of bytes - * to read. - */ - bytesToReadFromBuffer = min(This->byteArraySize.s.LowPart - - ulOffset.s.LowPart, cb); - - /* - * Lock the buffer in position and copy the data. - */ - supportBuffer = GlobalLock16(This->supportHandle); - - memcpy(pv, - (char *) supportBuffer + ulOffset.s.LowPart, - bytesToReadFromBuffer); - - /* - * Return the number of bytes read. - */ - *pcbRead = bytesToReadFromBuffer; - - /* - * Cleanup - */ - GlobalUnlock16(This->supportHandle); - - /* - * The function returns S_OK if the specified number of bytes were read - * or the end of the array was reached. - * It returns STG_E_READFAULT if the number of bytes to read does not equal - * the number of bytes actually read. - */ - if(*pcbRead == cb) - return S_OK; - - return STG_E_READFAULT; -} - -/****************************************************************************** - * This method is part of the ILockBytes interface. - * - * It writes the specified bytes at the specified offset. - * position. If the array is too small, it will be resized. - * - * See the documentation of ILockBytes for more info. - */ -HRESULT WINAPI HGLOBALLockBytesImpl16_WriteAt( - ILockBytes16* iface, - ULARGE_INTEGER ulOffset, /* [in] */ - const void* pv, /* [size_is][in] */ - ULONG cb, /* [in] */ - ULONG* pcbWritten) /* [out] */ -{ - HGLOBALLockBytesImpl16* const This=(HGLOBALLockBytesImpl16*)iface; - - void* supportBuffer; - ULARGE_INTEGER newSize; - ULONG bytesWritten = 0; - - TRACE("(%p,%ld,%p,%ld,%p)\n",This,ulOffset.s.LowPart,pv,cb,pcbWritten); - /* - * If the caller is not interested in the number of bytes written, - * we use another buffer to avoid "if" statements in the code. - */ - if (pcbWritten == 0) - pcbWritten = &bytesWritten; - - if (cb == 0) - return S_OK; - - newSize.s.HighPart = 0; - newSize.s.LowPart = ulOffset.s.LowPart + cb; - - /* - * Verify if we need to grow the stream - */ - if (newSize.s.LowPart > This->byteArraySize.s.LowPart) - { - /* grow stream */ - if (HGLOBALLockBytesImpl16_SetSize(iface, newSize) == STG_E_MEDIUMFULL) - return STG_E_MEDIUMFULL; - } - - /* - * Lock the buffer in position and copy the data. - */ - supportBuffer = GlobalLock16(This->supportHandle); - - memcpy((char *) supportBuffer + ulOffset.s.LowPart, pv, cb); - - /* - * Return the number of bytes written. - */ - *pcbWritten = cb; - - /* - * Cleanup - */ - GlobalUnlock16(This->supportHandle); - - return S_OK; -} - -/****************************************************************************** - * This method is part of the ILockBytes interface. - * - * See the documentation of ILockBytes for more info. - */ -HRESULT WINAPI HGLOBALLockBytesImpl16_Flush(ILockBytes16* iface) -{ - TRACE("(%p)\n",iface); - return S_OK; -} - -/****************************************************************************** - * This method is part of the ILockBytes interface. - * - * It will change the size of the byte array. - * - * See the documentation of ILockBytes for more info. - */ -HRESULT WINAPI HGLOBALLockBytesImpl16_SetSize( - ILockBytes16* iface, - ULARGE_INTEGER libNewSize) /* [in] */ -{ - HGLOBALLockBytesImpl16* const This=(HGLOBALLockBytesImpl16*)iface; - - TRACE("(%p,%ld)\n",This,libNewSize.s.LowPart); - /* - * As documented. - */ - if (libNewSize.s.HighPart != 0) - return STG_E_INVALIDFUNCTION; - - if (This->byteArraySize.s.LowPart == libNewSize.s.LowPart) - return S_OK; - - /* - * Re allocate the HGlobal to fit the new size of the stream. - */ - This->supportHandle = GlobalReAlloc16(This->supportHandle, - libNewSize.s.LowPart, - 0); - - if (This->supportHandle == 0) - return STG_E_MEDIUMFULL; - - This->byteArraySize.s.LowPart = libNewSize.s.LowPart; - - return S_OK; -} - -/****************************************************************************** - * This method is part of the ILockBytes interface. - * - * The global memory implementation of ILockBytes does not support locking. - * - * See the documentation of ILockBytes for more info. - */ -HRESULT WINAPI HGLOBALLockBytesImpl16_LockRegion( - ILockBytes16* iface, - ULARGE_INTEGER libOffset, /* [in] */ - ULARGE_INTEGER cb, /* [in] */ - DWORD dwLockType) /* [in] */ -{ - return STG_E_INVALIDFUNCTION; -} - -/****************************************************************************** - * This method is part of the ILockBytes interface. - * - * The global memory implementation of ILockBytes does not support locking. - * - * See the documentation of ILockBytes for more info. - */ -HRESULT WINAPI HGLOBALLockBytesImpl16_UnlockRegion( - ILockBytes16* iface, - ULARGE_INTEGER libOffset, /* [in] */ - ULARGE_INTEGER cb, /* [in] */ - DWORD dwLockType) /* [in] */ -{ - return STG_E_INVALIDFUNCTION; -} - -/****************************************************************************** - * This method is part of the ILockBytes interface. - * - * This method returns information about the current - * byte array object. - * - * See the documentation of ILockBytes for more info. - */ -HRESULT WINAPI HGLOBALLockBytesImpl16_Stat( - ILockBytes16*iface, - STATSTG16* pstatstg, /* [out] */ - DWORD grfStatFlag) /* [in] */ -{ - HGLOBALLockBytesImpl16* const This=(HGLOBALLockBytesImpl16*)iface; - - memset(pstatstg, 0, sizeof(STATSTG16)); - - pstatstg->pwcsName = NULL; - pstatstg->type = STGTY_LOCKBYTES; - pstatstg->cbSize = This->byteArraySize; - - return S_OK; -} - -/****************************************************************************** - * CreateILockBytesOnHGlobal [OLE2.54] - * - * Creates an ILockBytes interface for a HGLOBAL handle. - * - * Params: - * hGlobal the global handle (16bit) - * fDeleteOnRelease delete handle on release. - * ppLkbyt pointer to ILockBytes interface. - * - * Returns: - * Staddard OLE error return codes. - * - */ -HRESULT WINAPI CreateILockBytesOnHGlobal16(HGLOBAL16 hGlobal, - BOOL16 fDeleteOnRelease, - /*SEGPTR**/ LPLOCKBYTES16* ppLkbyt) -{ - HGLOBALLockBytesImpl16* newLockBytes; /* SEGPTR */ - - newLockBytes = HGLOBALLockBytesImpl16_Construct(hGlobal, fDeleteOnRelease); - - if (newLockBytes != NULL) - return HGLOBALLockBytesImpl16_QueryInterface((ILockBytes16*)newLockBytes, - &IID_ILockBytes, - (void**)ppLkbyt); - return E_OUTOFMEMORY; -}