OLE32: More work on PropVariant*

Robert Shearman R.J.Shearman at warwick.ac.uk
Sun May 11 20:15:02 CDT 2003


License: LGPL
ChangeLog:
- Implement a few more cases in PropVariantClear
- Paritally implement PropVariantCopy
- Implement FreePropVariantArray

Rob
-------------- next part --------------
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;
 }
 
 /***********************************************************************


More information about the wine-patches mailing list