ole32: COM cleanup of IStream based on HGLOBAL.
This commit is contained in:
parent
4d34ea52ad
commit
5f5d5e0c65
|
@ -51,39 +51,28 @@ WINE_DEFAULT_DEBUG_CHANNEL(storage);
|
||||||
* This class implements the IStream interface and represents a stream
|
* This class implements the IStream interface and represents a stream
|
||||||
* supported by an HGLOBAL pointer.
|
* supported by an HGLOBAL pointer.
|
||||||
*/
|
*/
|
||||||
struct HGLOBALStreamImpl
|
typedef struct
|
||||||
{
|
{
|
||||||
const IStreamVtbl *lpVtbl; /* Needs to be the first item in the struct
|
IStream IStream_iface;
|
||||||
* since we want to cast this in an IStream pointer */
|
LONG ref;
|
||||||
|
|
||||||
/*
|
/* support for the stream */
|
||||||
* Reference count
|
|
||||||
*/
|
|
||||||
LONG ref;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Support for the stream
|
|
||||||
*/
|
|
||||||
HGLOBAL supportHandle;
|
HGLOBAL supportHandle;
|
||||||
|
|
||||||
/*
|
/* if TRUE the HGLOBAL is destroyed when the stream is finally released */
|
||||||
* This flag is TRUE if the HGLOBAL is destroyed when the stream
|
BOOL deleteOnRelease;
|
||||||
* is finally released.
|
|
||||||
*/
|
|
||||||
BOOL deleteOnRelease;
|
|
||||||
|
|
||||||
/*
|
/* size of the stream */
|
||||||
* Helper variable that contains the size of the stream
|
ULARGE_INTEGER streamSize;
|
||||||
*/
|
|
||||||
ULARGE_INTEGER streamSize;
|
|
||||||
|
|
||||||
/*
|
/* current position of the cursor */
|
||||||
* This is the current position of the cursor in the stream
|
ULARGE_INTEGER currentPosition;
|
||||||
*/
|
} HGLOBALStreamImpl;
|
||||||
ULARGE_INTEGER currentPosition;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct HGLOBALStreamImpl HGLOBALStreamImpl;
|
static inline HGLOBALStreamImpl *impl_from_IStream(IStream *iface)
|
||||||
|
{
|
||||||
|
return CONTAINING_RECORD(iface, HGLOBALStreamImpl, IStream_iface);
|
||||||
|
}
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* This is the destructor of the HGLOBALStreamImpl class.
|
* This is the destructor of the HGLOBALStreamImpl class.
|
||||||
|
@ -115,10 +104,9 @@ static void HGLOBALStreamImpl_Destroy(HGLOBALStreamImpl* This)
|
||||||
* This implements the IUnknown method AddRef for this
|
* This implements the IUnknown method AddRef for this
|
||||||
* class
|
* class
|
||||||
*/
|
*/
|
||||||
static ULONG WINAPI HGLOBALStreamImpl_AddRef(
|
static ULONG WINAPI HGLOBALStreamImpl_AddRef(IStream* iface)
|
||||||
IStream* iface)
|
|
||||||
{
|
{
|
||||||
HGLOBALStreamImpl* const This=(HGLOBALStreamImpl*)iface;
|
HGLOBALStreamImpl* This = impl_from_IStream(iface);
|
||||||
return InterlockedIncrement(&This->ref);
|
return InterlockedIncrement(&This->ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,7 +119,7 @@ static HRESULT WINAPI HGLOBALStreamImpl_QueryInterface(
|
||||||
REFIID riid, /* [in] */
|
REFIID riid, /* [in] */
|
||||||
void** ppvObject) /* [iid_is][out] */
|
void** ppvObject) /* [iid_is][out] */
|
||||||
{
|
{
|
||||||
HGLOBALStreamImpl* const This=(HGLOBALStreamImpl*)iface;
|
HGLOBALStreamImpl* This = impl_from_IStream(iface);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Perform a sanity check on the parameters.
|
* Perform a sanity check on the parameters.
|
||||||
|
@ -176,20 +164,13 @@ static HRESULT WINAPI HGLOBALStreamImpl_QueryInterface(
|
||||||
static ULONG WINAPI HGLOBALStreamImpl_Release(
|
static ULONG WINAPI HGLOBALStreamImpl_Release(
|
||||||
IStream* iface)
|
IStream* iface)
|
||||||
{
|
{
|
||||||
HGLOBALStreamImpl* const This=(HGLOBALStreamImpl*)iface;
|
HGLOBALStreamImpl* This= impl_from_IStream(iface);
|
||||||
ULONG newRef;
|
ULONG ref = InterlockedDecrement(&This->ref);
|
||||||
|
|
||||||
newRef = InterlockedDecrement(&This->ref);
|
if (!ref)
|
||||||
|
|
||||||
/*
|
|
||||||
* If the reference count goes down to 0, perform suicide.
|
|
||||||
*/
|
|
||||||
if (newRef==0)
|
|
||||||
{
|
|
||||||
HGLOBALStreamImpl_Destroy(This);
|
HGLOBALStreamImpl_Destroy(This);
|
||||||
}
|
|
||||||
|
|
||||||
return newRef;
|
return ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
/***
|
||||||
|
@ -207,7 +188,7 @@ static HRESULT WINAPI HGLOBALStreamImpl_Read(
|
||||||
ULONG cb, /* [in] */
|
ULONG cb, /* [in] */
|
||||||
ULONG* pcbRead) /* [out] */
|
ULONG* pcbRead) /* [out] */
|
||||||
{
|
{
|
||||||
HGLOBALStreamImpl* const This=(HGLOBALStreamImpl*)iface;
|
HGLOBALStreamImpl* This = impl_from_IStream(iface);
|
||||||
|
|
||||||
void* supportBuffer;
|
void* supportBuffer;
|
||||||
ULONG bytesReadBuffer;
|
ULONG bytesReadBuffer;
|
||||||
|
@ -281,7 +262,7 @@ static HRESULT WINAPI HGLOBALStreamImpl_Write(
|
||||||
ULONG cb, /* [in] */
|
ULONG cb, /* [in] */
|
||||||
ULONG* pcbWritten) /* [out] */
|
ULONG* pcbWritten) /* [out] */
|
||||||
{
|
{
|
||||||
HGLOBALStreamImpl* const This=(HGLOBALStreamImpl*)iface;
|
HGLOBALStreamImpl* This = impl_from_IStream(iface);
|
||||||
|
|
||||||
void* supportBuffer;
|
void* supportBuffer;
|
||||||
ULARGE_INTEGER newSize;
|
ULARGE_INTEGER newSize;
|
||||||
|
@ -363,7 +344,7 @@ static HRESULT WINAPI HGLOBALStreamImpl_Seek(
|
||||||
DWORD dwOrigin, /* [in] */
|
DWORD dwOrigin, /* [in] */
|
||||||
ULARGE_INTEGER* plibNewPosition) /* [out] */
|
ULARGE_INTEGER* plibNewPosition) /* [out] */
|
||||||
{
|
{
|
||||||
HGLOBALStreamImpl* const This=(HGLOBALStreamImpl*)iface;
|
HGLOBALStreamImpl* This = impl_from_IStream(iface);
|
||||||
|
|
||||||
ULARGE_INTEGER newPosition = This->currentPosition;
|
ULARGE_INTEGER newPosition = This->currentPosition;
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
|
@ -428,7 +409,7 @@ static HRESULT WINAPI HGLOBALStreamImpl_SetSize(
|
||||||
IStream* iface,
|
IStream* iface,
|
||||||
ULARGE_INTEGER libNewSize) /* [in] */
|
ULARGE_INTEGER libNewSize) /* [in] */
|
||||||
{
|
{
|
||||||
HGLOBALStreamImpl* const This=(HGLOBALStreamImpl*)iface;
|
HGLOBALStreamImpl* This = impl_from_IStream(iface);
|
||||||
HGLOBAL supportHandle;
|
HGLOBAL supportHandle;
|
||||||
|
|
||||||
TRACE("(%p, %d)\n", iface, libNewSize.u.LowPart);
|
TRACE("(%p, %d)\n", iface, libNewSize.u.LowPart);
|
||||||
|
@ -593,7 +574,7 @@ static HRESULT WINAPI HGLOBALStreamImpl_Stat(
|
||||||
STATSTG* pstatstg, /* [out] */
|
STATSTG* pstatstg, /* [out] */
|
||||||
DWORD grfStatFlag) /* [in] */
|
DWORD grfStatFlag) /* [in] */
|
||||||
{
|
{
|
||||||
HGLOBALStreamImpl* const This=(HGLOBALStreamImpl*)iface;
|
HGLOBALStreamImpl* This = impl_from_IStream(iface);
|
||||||
|
|
||||||
memset(pstatstg, 0, sizeof(STATSTG));
|
memset(pstatstg, 0, sizeof(STATSTG));
|
||||||
|
|
||||||
|
@ -608,12 +589,13 @@ static HRESULT WINAPI HGLOBALStreamImpl_Clone(
|
||||||
IStream* iface,
|
IStream* iface,
|
||||||
IStream** ppstm) /* [out] */
|
IStream** ppstm) /* [out] */
|
||||||
{
|
{
|
||||||
|
HGLOBALStreamImpl* This = impl_from_IStream(iface);
|
||||||
ULARGE_INTEGER dummy;
|
ULARGE_INTEGER dummy;
|
||||||
LARGE_INTEGER offset;
|
LARGE_INTEGER offset;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
HGLOBALStreamImpl* const This=(HGLOBALStreamImpl*)iface;
|
|
||||||
TRACE(" Cloning %p (deleteOnRelease=%d seek position=%ld)\n",iface,This->deleteOnRelease,(long)This->currentPosition.QuadPart);
|
TRACE(" Cloning %p (deleteOnRelease=%d seek position=%ld)\n",iface,This->deleteOnRelease,(long)This->currentPosition.QuadPart);
|
||||||
hr=CreateStreamOnHGlobal(This->supportHandle, FALSE, ppstm);
|
hr = CreateStreamOnHGlobal(This->supportHandle, FALSE, ppstm);
|
||||||
if(FAILED(hr))
|
if(FAILED(hr))
|
||||||
return hr;
|
return hr;
|
||||||
offset.QuadPart=(LONGLONG)This->currentPosition.QuadPart;
|
offset.QuadPart=(LONGLONG)This->currentPosition.QuadPart;
|
||||||
|
@ -624,7 +606,7 @@ static HRESULT WINAPI HGLOBALStreamImpl_Clone(
|
||||||
/*
|
/*
|
||||||
* Virtual function table for the HGLOBALStreamImpl class.
|
* Virtual function table for the HGLOBALStreamImpl class.
|
||||||
*/
|
*/
|
||||||
static const IStreamVtbl HGLOBALStreamImpl_Vtbl =
|
static const IStreamVtbl HGLOBALStreamImplVtbl =
|
||||||
{
|
{
|
||||||
HGLOBALStreamImpl_QueryInterface,
|
HGLOBALStreamImpl_QueryInterface,
|
||||||
HGLOBALStreamImpl_AddRef,
|
HGLOBALStreamImpl_AddRef,
|
||||||
|
@ -658,47 +640,43 @@ static HGLOBALStreamImpl* HGLOBALStreamImpl_Construct(
|
||||||
HGLOBAL hGlobal,
|
HGLOBAL hGlobal,
|
||||||
BOOL fDeleteOnRelease)
|
BOOL fDeleteOnRelease)
|
||||||
{
|
{
|
||||||
HGLOBALStreamImpl* newStream;
|
HGLOBALStreamImpl* This;
|
||||||
|
|
||||||
newStream = HeapAlloc(GetProcessHeap(), 0, sizeof(HGLOBALStreamImpl));
|
This = HeapAlloc(GetProcessHeap(), 0, sizeof(HGLOBALStreamImpl));
|
||||||
|
if (This)
|
||||||
if (newStream!=0)
|
|
||||||
{
|
{
|
||||||
/*
|
This->IStream_iface.lpVtbl = &HGLOBALStreamImplVtbl;
|
||||||
* Set-up the virtual function table and reference count.
|
This->ref = 0;
|
||||||
*/
|
|
||||||
newStream->lpVtbl = &HGLOBALStreamImpl_Vtbl;
|
|
||||||
newStream->ref = 0;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize the support.
|
* Initialize the support.
|
||||||
*/
|
*/
|
||||||
newStream->supportHandle = hGlobal;
|
This->supportHandle = hGlobal;
|
||||||
newStream->deleteOnRelease = fDeleteOnRelease;
|
This->deleteOnRelease = fDeleteOnRelease;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This method will allocate a handle if one is not supplied.
|
* This method will allocate a handle if one is not supplied.
|
||||||
*/
|
*/
|
||||||
if (!newStream->supportHandle)
|
if (!This->supportHandle)
|
||||||
{
|
{
|
||||||
newStream->supportHandle = GlobalAlloc(GMEM_MOVEABLE | GMEM_NODISCARD |
|
This->supportHandle = GlobalAlloc(GMEM_MOVEABLE | GMEM_NODISCARD |
|
||||||
GMEM_SHARE, 0);
|
GMEM_SHARE, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Start the stream at the beginning.
|
* Start the stream at the beginning.
|
||||||
*/
|
*/
|
||||||
newStream->currentPosition.u.HighPart = 0;
|
This->currentPosition.u.HighPart = 0;
|
||||||
newStream->currentPosition.u.LowPart = 0;
|
This->currentPosition.u.LowPart = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize the size of the stream to the size of the handle.
|
* Initialize the size of the stream to the size of the handle.
|
||||||
*/
|
*/
|
||||||
newStream->streamSize.u.HighPart = 0;
|
This->streamSize.u.HighPart = 0;
|
||||||
newStream->streamSize.u.LowPart = GlobalSize(newStream->supportHandle);
|
This->streamSize.u.LowPart = GlobalSize(This->supportHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
return newStream;
|
return This;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -743,7 +721,7 @@ HRESULT WINAPI GetHGlobalFromStream(IStream* pstm, HGLOBAL* phglobal)
|
||||||
/*
|
/*
|
||||||
* Verify that the stream object was created with CreateStreamOnHGlobal.
|
* Verify that the stream object was created with CreateStreamOnHGlobal.
|
||||||
*/
|
*/
|
||||||
if (pStream->lpVtbl == &HGLOBALStreamImpl_Vtbl)
|
if (pStream->IStream_iface.lpVtbl == &HGLOBALStreamImplVtbl)
|
||||||
*phglobal = pStream->supportHandle;
|
*phglobal = pStream->supportHandle;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue