[PATCH 2/6] ole32: Add a structure to hold memory block information.
Huw Davies
huw at codeweavers.com
Tue Aug 11 06:49:49 CDT 2020
Based on a patch by Dmitry Timoshkov which was based on a suggestion
by Sebastian Lackner.
Signed-off-by: Huw Davies <huw at codeweavers.com>
---
dlls/ole32/hglobalstream.c | 102 ++++++++++++++++++++++---------------
1 file changed, 60 insertions(+), 42 deletions(-)
diff --git a/dlls/ole32/hglobalstream.c b/dlls/ole32/hglobalstream.c
index 6133690d9d1..300119dcc72 100644
--- a/dlls/ole32/hglobalstream.c
+++ b/dlls/ole32/hglobalstream.c
@@ -5,6 +5,7 @@
* for streams contained supported by an HGLOBAL pointer.
*
* Copyright 1999 Francis Beaudet
+ * Copyright 2016 Dmitry Timoshkov
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -42,6 +43,40 @@
WINE_DEFAULT_DEBUG_CHANNEL(storage);
+struct handle_wrapper
+{
+ HGLOBAL hglobal;
+ ULONG size;
+ BOOL delete_on_release;
+};
+
+static void handle_release(struct handle_wrapper *handle)
+{
+ if (handle->delete_on_release) GlobalFree(handle->hglobal);
+ HeapFree(GetProcessHeap(), 0, handle);
+}
+
+static struct handle_wrapper *handle_create(HGLOBAL hglobal, BOOL delete_on_release)
+{
+ struct handle_wrapper *handle;
+
+ handle = HeapAlloc(GetProcessHeap(), 0, sizeof(*handle));
+ if (!handle) return NULL;
+
+ /* allocate a handle if one is not supplied */
+ if (!hglobal) hglobal = GlobalAlloc(GMEM_MOVEABLE | GMEM_NODISCARD | GMEM_SHARE, 0);
+ if (!hglobal)
+ {
+ HeapFree(GetProcessHeap(), 0, handle);
+ return NULL;
+ }
+ handle->hglobal = hglobal;
+ handle->size = GlobalSize(hglobal);
+ handle->delete_on_release = delete_on_release;
+
+ return handle;
+}
+
/****************************************************************************
* HGLOBALStreamImpl definition.
*
@@ -53,14 +88,7 @@ typedef struct
IStream IStream_iface;
LONG ref;
- /* support for the stream */
- HGLOBAL supportHandle;
-
- /* if TRUE the HGLOBAL is destroyed when the stream is finally released */
- BOOL deleteOnRelease;
-
- /* size of the stream */
- ULARGE_INTEGER streamSize;
+ struct handle_wrapper *handle;
/* current position of the cursor */
ULARGE_INTEGER currentPosition;
@@ -112,12 +140,7 @@ static ULONG WINAPI HGLOBALStreamImpl_Release(
if (!ref)
{
- if (This->deleteOnRelease)
- {
- GlobalFree(This->supportHandle);
- This->supportHandle = NULL;
- }
-
+ handle_release(This->handle);
HeapFree(GetProcessHeap(), 0, This);
}
@@ -159,15 +182,15 @@ static HRESULT WINAPI HGLOBALStreamImpl_Read(
* Using the known size of the stream, calculate the number of bytes
* to read from the block chain
*/
- bytesToReadFromBuffer = min( This->streamSize.u.LowPart - This->currentPosition.u.LowPart, cb);
+ bytesToReadFromBuffer = min( This->handle->size - This->currentPosition.u.LowPart, cb);
/*
* Lock the buffer in position and copy the data.
*/
- supportBuffer = GlobalLock(This->supportHandle);
+ supportBuffer = GlobalLock(This->handle->hglobal);
if (!supportBuffer)
{
- WARN("read from invalid hglobal %p\n", This->supportHandle);
+ WARN("read from invalid hglobal %p\n", This->handle->hglobal);
*pcbRead = 0;
return S_OK;
}
@@ -187,7 +210,7 @@ static HRESULT WINAPI HGLOBALStreamImpl_Read(
/*
* Cleanup
*/
- GlobalUnlock(This->supportHandle);
+ GlobalUnlock(This->handle->hglobal);
/*
* Always returns S_OK even if the end of the stream is reached before the
@@ -239,7 +262,7 @@ static HRESULT WINAPI HGLOBALStreamImpl_Write(
/*
* Verify if we need to grow the stream
*/
- if (newSize.u.LowPart > This->streamSize.u.LowPart)
+ if (newSize.u.LowPart > This->handle->size)
{
/* grow stream */
HRESULT hr = IStream_SetSize(iface, newSize);
@@ -253,10 +276,10 @@ static HRESULT WINAPI HGLOBALStreamImpl_Write(
/*
* Lock the buffer in position and copy the data.
*/
- supportBuffer = GlobalLock(This->supportHandle);
+ supportBuffer = GlobalLock(This->handle->hglobal);
if (!supportBuffer)
{
- WARN("write to invalid hglobal %p\n", This->supportHandle);
+ WARN("write to invalid hglobal %p\n", This->handle->hglobal);
return S_OK;
}
@@ -270,7 +293,7 @@ static HRESULT WINAPI HGLOBALStreamImpl_Write(
/*
* Cleanup
*/
- GlobalUnlock(This->supportHandle);
+ GlobalUnlock(This->handle->hglobal);
out:
/*
@@ -316,7 +339,7 @@ static HRESULT WINAPI HGLOBALStreamImpl_Seek(
case STREAM_SEEK_CUR:
break;
case STREAM_SEEK_END:
- newPosition = This->streamSize;
+ newPosition.QuadPart = This->handle->size;
break;
default:
hr = STG_E_SEEKERROR;
@@ -369,19 +392,19 @@ static HRESULT WINAPI HGLOBALStreamImpl_SetSize(
* HighPart is ignored as shown in tests
*/
- if (This->streamSize.u.LowPart == libNewSize.u.LowPart)
+ if (This->handle->size == libNewSize.u.LowPart)
return S_OK;
/*
* Re allocate the HGlobal to fit the new size of the stream.
*/
- supportHandle = GlobalReAlloc(This->supportHandle, libNewSize.u.LowPart, 0);
+ supportHandle = GlobalReAlloc(This->handle->hglobal, libNewSize.u.LowPart, 0);
if (supportHandle == 0)
return E_OUTOFMEMORY;
- This->supportHandle = supportHandle;
- This->streamSize.u.LowPart = libNewSize.u.LowPart;
+ This->handle->hglobal = supportHandle;
+ This->handle->size = libNewSize.u.LowPart;
return S_OK;
}
@@ -531,7 +554,7 @@ static HRESULT WINAPI HGLOBALStreamImpl_Stat(
pstatstg->pwcsName = NULL;
pstatstg->type = STGTY_STREAM;
- pstatstg->cbSize = This->streamSize;
+ pstatstg->cbSize.QuadPart = This->handle->size;
return S_OK;
}
@@ -545,8 +568,8 @@ static HRESULT WINAPI HGLOBALStreamImpl_Clone(
LARGE_INTEGER offset;
HRESULT hr;
- TRACE(" Cloning %p (deleteOnRelease=%d seek position=%ld)\n",iface,This->deleteOnRelease,(long)This->currentPosition.QuadPart);
- hr = CreateStreamOnHGlobal(This->supportHandle, FALSE, ppstm);
+ TRACE(" Cloning %p (deleteOnRelease=%d seek position=%ld)\n",iface,This->handle->delete_on_release,(long)This->currentPosition.QuadPart);
+ hr = CreateStreamOnHGlobal(This->handle->hglobal, FALSE, ppstm);
if(FAILED(hr))
return hr;
offset.QuadPart = (LONGLONG)This->currentPosition.QuadPart;
@@ -591,22 +614,17 @@ HRESULT WINAPI CreateStreamOnHGlobal(
This->IStream_iface.lpVtbl = &HGLOBALStreamImplVtbl;
This->ref = 1;
- /* initialize the support */
- This->supportHandle = hGlobal;
- This->deleteOnRelease = fDeleteOnRelease;
-
- /* allocate a handle if one is not supplied */
- if (!This->supportHandle)
- This->supportHandle = GlobalAlloc(GMEM_MOVEABLE|GMEM_NODISCARD|GMEM_SHARE, 0);
+ This->handle = handle_create(hGlobal, fDeleteOnRelease);
+ if (!This->handle)
+ {
+ HeapFree(GetProcessHeap(), 0, This);
+ return E_OUTOFMEMORY;
+ }
/* start at the beginning */
This->currentPosition.u.HighPart = 0;
This->currentPosition.u.LowPart = 0;
- /* initialize the size of the stream to the size of the handle */
- This->streamSize.u.HighPart = 0;
- This->streamSize.u.LowPart = GlobalSize(This->supportHandle);
-
*ppstm = &This->IStream_iface;
return S_OK;
@@ -628,7 +646,7 @@ HRESULT WINAPI GetHGlobalFromStream(IStream* pstm, HGLOBAL* phglobal)
* Verify that the stream object was created with CreateStreamOnHGlobal.
*/
if (pStream->IStream_iface.lpVtbl == &HGLOBALStreamImplVtbl)
- *phglobal = pStream->supportHandle;
+ *phglobal = pStream->handle->hglobal;
else
{
*phglobal = 0;
--
2.23.0
More information about the wine-devel
mailing list