From 98747abd759816b823a928453e00fb234f829606 Mon Sep 17 00:00:00 2001 From: Robert Shearman Date: Tue, 13 May 2003 00:32:43 +0000 Subject: [PATCH] - Implement a few more cases in PropVariantClear. - Partially implement PropVariantCopy. - Implement FreePropVariantArray. --- dlls/ole32/ole2stubs.c | 229 ++++++++++++++++++++++++++++++++++++++--- include/objidl.h | 1 + include/objidl.idl | 1 + 3 files changed, 215 insertions(+), 16 deletions(-) diff --git a/dlls/ole32/ole2stubs.c b/dlls/ole32/ole2stubs.c index bf681e2e94..0bd668508f 100644 --- a/dlls/ole32/ole2stubs.c +++ b/dlls/ole32/ole2stubs.c @@ -205,10 +205,30 @@ HRESULT WINAPI OleRegEnumFormatEtc ( return E_NOTIMPL; } +/*********************************************************************** + * OLE_FreeClipDataArray [internal] + * + * NOTES: + * frees the data associated with an array of CLIPDATAs + */ +static void OLE_FreeClipDataArray(ULONG count, CLIPDATA * pClipDataArray) +{ + ULONG i; + for (i = 0; i < count; i++) + { + if (pClipDataArray[i].pClipData) + { + CoTaskMemFree(pClipDataArray[i].pClipData); + } + } +} + +HRESULT WINAPI FreePropVariantArray(ULONG,PROPVARIANT*); + /*********************************************************************** * PropVariantClear [OLE32.166] */ -HRESULT WINAPI PropVariantClear(PROPVARIANT * pvar) /* [in/out] FIXME: PROPVARIANT * */ +HRESULT WINAPI PropVariantClear(PROPVARIANT * pvar) /* [in/out] */ { TRACE("(%p)\n", pvar); @@ -217,9 +237,6 @@ HRESULT WINAPI PropVariantClear(PROPVARIANT * pvar) /* [in/out] FIXME: PROPVARIA switch(pvar->vt) { - case VT_BSTR: - CoTaskMemFree(pvar->u.bstrVal); - break; case VT_STREAM: case VT_STREAMED_OBJECT: case VT_STORAGE: @@ -227,21 +244,51 @@ HRESULT WINAPI PropVariantClear(PROPVARIANT * pvar) /* [in/out] FIXME: PROPVARIA IUnknown_Release((LPUNKNOWN)pvar->u.pStream); break; case VT_CLSID: - case VT_CF: case VT_LPSTR: case VT_LPWSTR: + CoTaskMemFree(pvar->u.puuid); /* pick an arbitary typed pointer - we don't care about the type as we are just freeing it */ + break; case VT_BLOB: case VT_BLOB_OBJECT: - FIXME("Don't know what to do for variant type %d\n", pvar->vt); + CoTaskMemFree(pvar->u.blob.pBlobData); + break; + case VT_BSTR: + FIXME("Need to load OLEAUT32 for SysFreeString\n"); + /* SysFreeString(pvar->u.bstrVal); */ + break; + case VT_CF: + if (pvar->u.pclipdata) + { + OLE_FreeClipDataArray(1, pvar->u.pclipdata); + CoTaskMemFree(pvar->u.pclipdata); + } + break; default: - if (pvar->vt && VT_VECTOR) + if (pvar->vt & VT_ARRAY) { - FIXME("Need to recursively destroy elements in vector\n"); + FIXME("Need to call SafeArrayDestroy\n"); /* SafeArrayDestroy(pvar->u.caub); */ } + switch (pvar->vt & VT_VECTOR) + { + case VT_VARIANT: + FreePropVariantArray(pvar->u.capropvar.cElems, pvar->u.capropvar.pElems); + break; + case VT_CF: + OLE_FreeClipDataArray(pvar->u.caclipdata.cElems, pvar->u.caclipdata.pElems); + break; + case VT_BSTR: + case VT_LPSTR: + case VT_LPWSTR: + FIXME("Freeing of vector sub-type not supported yet\n"); + } + if (pvar->vt & VT_VECTOR) + { + CoTaskMemFree(pvar->u.capropvar.pElems); /* pick an arbitary VT_VECTOR structure - they all have the same memory layout */ + } } - ZeroMemory(pvar, sizeof(PROPVARIANT)); + ZeroMemory(pvar, sizeof(*pvar)); return S_OK; } @@ -249,23 +296,173 @@ HRESULT WINAPI PropVariantClear(PROPVARIANT * pvar) /* [in/out] FIXME: PROPVARIA /*********************************************************************** * PropVariantCopy [OLE32.246] */ -HRESULT WINAPI PropVariantCopy(void *pvarDest, /* [out] FIXME: PROPVARIANT * */ - const void *pvarSrc) /* [in] FIXME: const PROPVARIANT * */ +HRESULT WINAPI PropVariantCopy(PROPVARIANT *pvarDest, /* [out] FIXME: PROPVARIANT * */ + const PROPVARIANT *pvarSrc) /* [in] FIXME: const PROPVARIANT * */ { - FIXME("(%p, %p): stub:\n", pvarDest, pvarSrc); + ULONG len; + TRACE("(%p, %p): stub:\n", pvarDest, pvarSrc); - return E_NOTIMPL; + /* this will deal with most cases */ + CopyMemory(pvarDest, pvarSrc, sizeof(*pvarDest)); + + switch(pvarSrc->vt) + { + case VT_STREAM: + case VT_STREAMED_OBJECT: + case VT_STORAGE: + case VT_STORED_OBJECT: + IUnknown_AddRef((LPUNKNOWN)pvarDest->u.pStream); + break; + case VT_CLSID: + pvarDest->u.puuid = CoTaskMemAlloc(sizeof(CLSID)); + CopyMemory(pvarDest->u.puuid, pvarSrc->u.puuid, sizeof(CLSID)); + break; + case VT_LPSTR: + len = strlen(pvarSrc->u.pszVal); + pvarDest->u.pszVal = CoTaskMemAlloc(len); + CopyMemory(pvarDest->u.pszVal, pvarSrc->u.pszVal, len); + break; + case VT_LPWSTR: + len = lstrlenW(pvarSrc->u.pwszVal); + pvarDest->u.pwszVal = CoTaskMemAlloc(len); + CopyMemory(pvarDest->u.pwszVal, pvarSrc->u.pwszVal, len); + break; + case VT_BLOB: + case VT_BLOB_OBJECT: + if (pvarSrc->u.blob.pBlobData) + { + len = pvarSrc->u.blob.cbSize; + pvarDest->u.blob.pBlobData = CoTaskMemAlloc(len); + CopyMemory(pvarDest->u.blob.pBlobData, pvarSrc->u.blob.pBlobData, len); + } + break; + case VT_BSTR: + FIXME("Need to copy BSTR\n"); + break; + case VT_CF: + if (pvarSrc->u.pclipdata) + { + len = pvarSrc->u.pclipdata->cbSize - sizeof(pvarSrc->u.pclipdata->ulClipFmt); + CoTaskMemAlloc(len); + CopyMemory(pvarDest->u.pclipdata->pClipData, pvarSrc->u.pclipdata->pClipData, len); + } + break; + default: + if (pvarSrc->vt & VT_ARRAY) + { + FIXME("Need to call SafeArrayCopy\n"); +/* SafeArrayCopy(...); */ + } + if (pvarSrc->vt & VT_VECTOR) + { + int elemSize; + switch(pvarSrc->vt & VT_VECTOR) + { + case VT_I1: + elemSize = sizeof(pvarSrc->u.cVal); + break; + case VT_UI1: + elemSize = sizeof(pvarSrc->u.bVal); + break; + case VT_I2: + elemSize = sizeof(pvarSrc->u.iVal); + break; + case VT_UI2: + elemSize = sizeof(pvarSrc->u.uiVal); + break; + case VT_BOOL: + elemSize = sizeof(pvarSrc->u.boolVal); + break; + case VT_I4: + elemSize = sizeof(pvarSrc->u.lVal); + break; + case VT_UI4: + elemSize = sizeof(pvarSrc->u.ulVal); + break; + case VT_R4: + elemSize = sizeof(pvarSrc->u.fltVal); + break; + case VT_R8: + elemSize = sizeof(pvarSrc->u.dblVal); + break; + case VT_ERROR: + elemSize = sizeof(pvarSrc->u.scode); + break; + case VT_I8: + elemSize = sizeof(pvarSrc->u.hVal); + break; + case VT_UI8: + elemSize = sizeof(pvarSrc->u.uhVal); + break; + case VT_CY: + elemSize = sizeof(pvarSrc->u.cyVal); + break; + case VT_DATE: + elemSize = sizeof(pvarSrc->u.date); + break; + case VT_FILETIME: + elemSize = sizeof(pvarSrc->u.filetime); + break; + case VT_CLSID: + elemSize = sizeof(*pvarSrc->u.puuid); + break; + case VT_CF: + elemSize = sizeof(*pvarSrc->u.pclipdata); + break; + case VT_BSTR: + case VT_LPSTR: + case VT_LPWSTR: + case VT_VARIANT: + default: + FIXME("Invalid element type: %ul\n", pvarSrc->vt & VT_VECTOR); + return E_INVALIDARG; + } + len = pvarSrc->u.capropvar.cElems; + pvarDest->u.capropvar.pElems = CoTaskMemAlloc(len * elemSize); + if (pvarSrc->vt == (VT_VECTOR | VT_VARIANT)) + { + ULONG i; + for (i = 0; i < len; i++) + PropVariantCopy(&pvarDest->u.capropvar.pElems[i], &pvarSrc->u.capropvar.pElems[i]); + } + else if (pvarSrc->vt == (VT_VECTOR | VT_CF)) + { + FIXME("Copy clipformats\n"); + } + else if (pvarSrc->vt == (VT_VECTOR | VT_BSTR)) + { + FIXME("Copy BSTRs\n"); + } + else if (pvarSrc->vt == (VT_VECTOR | VT_LPSTR)) + { + FIXME("Copy LPSTRs\n"); + } + else if (pvarSrc->vt == (VT_VECTOR | VT_LPSTR)) + { + FIXME("Copy LPWSTRs\n"); + } + else + CopyMemory(pvarDest->u.capropvar.pElems, pvarSrc->u.capropvar.pElems, len * elemSize); + } + } + + return S_OK; } /*********************************************************************** * FreePropVariantArray [OLE32.195] */ HRESULT WINAPI FreePropVariantArray(ULONG cVariants, /* [in] */ - void *rgvars) /* [in/out] FIXME: PROPVARIANT * */ + PROPVARIANT *rgvars) /* [in/out] */ { - FIXME("(%lu, %p): stub:\n", cVariants, rgvars); + ULONG i; + + TRACE("(%lu, %p)\n", cVariants, rgvars); - return E_NOTIMPL; + for(i = 0; i < cVariants; i++) + PropVariantClear(&rgvars[i]); + + return S_OK; } /*********************************************************************** diff --git a/include/objidl.h b/include/objidl.h index 0ff56419f7..ab3af50ca8 100644 --- a/include/objidl.h +++ b/include/objidl.h @@ -8042,6 +8042,7 @@ struct tagPROPVARIANT { WORD wReserved2; WORD wReserved3; union { + char cVal; UCHAR bVal; short iVal; USHORT uiVal; diff --git a/include/objidl.idl b/include/objidl.idl index 084937040c..d920296596 100644 --- a/include/objidl.idl +++ b/include/objidl.idl @@ -2058,6 +2058,7 @@ interface IPropertyStorage : IUnknown WORD wReserved3; [switch_is(vt & 0x1fff)] union { [case(VT_EMPTY, VT_NULL)] ; + [case(VT_I1)] char cVal; [case(VT_UI1)] UCHAR bVal; [case(VT_I2)] short iVal; [case(VT_UI2)] USHORT uiVal; -- 2.32.0.93.g670b81a890