License: LGPL
ChangeLog:
- Implement a few more cases in PropVariantClear
- Paritally implement PropVariantCopy
- Implement FreePropVariantArray
Rob
Index: wine/include/objidl.h
===================================================================
RCS file: /home/wine/wine/include/objidl.h,v
retrieving revision 1.14
diff -u -r1.14 objidl.h
--- wine/include/objidl.h 12 Apr 2003 00:09:14 -0000 1.14
+++ wine/include/objidl.h 11 May 2003 23:44:26 -0000
@@ -8042,6 +8042,7 @@
WORD wReserved2;
WORD wReserved3;
union {
+ char cVal;
UCHAR bVal;
short iVal;
USHORT uiVal;
Index: wine/include/objidl.idl
===================================================================
RCS file: /home/wine/wine/include/objidl.idl,v
retrieving revision 1.2
diff -u -r1.2 objidl.idl
--- wine/include/objidl.idl 4 Jan 2003 00:52:20 -0000 1.2
+++ wine/include/objidl.idl 11 May 2003 23:45:15 -0000
@@ -2058,6 +2058,7 @@
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;
Index: wine/dlls/ole32/ole2stubs.c
===================================================================
RCS file: /home/wine/wine/dlls/ole32/ole2stubs.c,v
retrieving revision 1.30
diff -u -r1.30 ole2stubs.c
--- wine/dlls/ole32/ole2stubs.c 11 May 2003 02:40:29 -0000 1.30
+++ wine/dlls/ole32/ole2stubs.c 11 May 2003 23:45:22 -0000
@@ -206,9 +206,29 @@
}
/***********************************************************************
+ * 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 @@
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 @@
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 @@
/***********************************************************************
* 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);
+
+ /* this will deal with most cases */
+ CopyMemory(pvarDest, pvarSrc, sizeof(*pvarDest));
- return E_NOTIMPL;
+ 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;
}
/***********************************************************************