[PATCH v2 02/15] propsys: Implement several PropVariantInit*() functions

Jonas Kümmerlin rgcjonas at gmail.com
Sat Jul 18 11:26:41 CDT 2015


This implements most of them and makes the inline ones available
to C code, too (instead of just C++ like before)
---
 dlls/propsys/propsys.spec |  24 +++++------
 dlls/propsys/propvar.c    | 103 ++++++++++++++++++++++++++++++++++++++++++++++
 include/propvarutil.h     |  90 ++++++++++++++++++++++++++++++++++------
 3 files changed, 192 insertions(+), 25 deletions(-)

diff --git a/dlls/propsys/propsys.spec b/dlls/propsys/propsys.spec
index 92b6d7c..100f825 100644
--- a/dlls/propsys/propsys.spec
+++ b/dlls/propsys/propsys.spec
@@ -27,24 +27,24 @@
 @ stdcall -private DllGetClassObject(ptr ptr ptr)
 @ stdcall -private DllRegisterServer()
 @ stdcall -private DllUnregisterServer()
-@ stub InitPropVariantFromBooleanVector
+@ stdcall InitPropVariantFromBooleanVector(ptr long ptr)
 @ stdcall InitPropVariantFromBuffer(ptr long ptr)
-@ stub InitPropVariantFromCLSID
-@ stub InitPropVariantFromDoubleVector
-@ stub InitPropVariantFromFileTime
-@ stub InitPropVariantFromFileTimeVector
+@ stdcall InitPropVariantFromCLSID(ptr ptr)
+@ stdcall InitPropVariantFromDoubleVector(ptr long ptr)
+@ stdcall InitPropVariantFromFileTime(ptr ptr)
+@ stdcall InitPropVariantFromFileTimeVector(ptr long ptr)
 @ stdcall InitPropVariantFromGUIDAsString(ptr ptr)
-@ stub InitPropVariantFromInt16Vector
-@ stub InitPropVariantFromInt32Vector
-@ stub InitPropVariantFromInt64Vector
+@ stdcall InitPropVariantFromInt16Vector(ptr long ptr)
+@ stdcall InitPropVariantFromInt32Vector(ptr long ptr)
+@ stdcall InitPropVariantFromInt64Vector(ptr long ptr)
 @ stub InitPropVariantFromPropVariantVectorElem
 @ stub InitPropVariantFromResource
 @ stub InitPropVariantFromStrRet
 @ stub InitPropVariantFromStringAsVector
-@ stub InitPropVariantFromStringVector
-@ stub InitPropVariantFromUInt16Vector
-@ stub InitPropVariantFromUInt32Vector
-@ stub InitPropVariantFromUInt64Vector
+@ stdcall InitPropVariantFromStringVector(ptr long ptr)
+@ stdcall InitPropVariantFromUInt16Vector(ptr long ptr)
+@ stdcall InitPropVariantFromUInt32Vector(ptr long ptr)
+@ stdcall InitPropVariantFromUInt64Vector(ptr long ptr)
 @ stub InitPropVariantVectorFromPropVariant
 @ stub InitVariantFromBooleanArray
 @ stdcall InitVariantFromBuffer(ptr long ptr)
diff --git a/dlls/propsys/propvar.c b/dlls/propsys/propvar.c
index fd22c9d..1a4d9d1 100644
--- a/dlls/propsys/propvar.c
+++ b/dlls/propsys/propvar.c
@@ -346,6 +346,20 @@ HRESULT WINAPI InitVariantFromGUIDAsString(REFGUID guid, VARIANT *pvar)
     return S_OK;
 }
 
+HRESULT WINAPI InitPropVariantFromCLSID(REFCLSID clsid, PROPVARIANT *ppropvar)
+{
+    TRACE("(%p %p)\n", clsid, ppropvar);
+
+    ppropvar->u.puuid = CoTaskMemAlloc(sizeof(CLSID));
+    if (!ppropvar->u.puuid)
+        return E_OUTOFMEMORY;
+
+    *ppropvar->u.puuid = *clsid;
+    ppropvar->vt = VT_CLSID;
+
+    return S_OK;
+}
+
 HRESULT WINAPI InitPropVariantFromBuffer(const VOID *pv, UINT cb, PROPVARIANT *ppropvar)
 {
     TRACE("(%p %u %p)\n", pv, cb, ppropvar);
@@ -391,6 +405,95 @@ HRESULT WINAPI InitVariantFromBuffer(const VOID *pv, UINT cb, VARIANT *pvar)
     return S_OK;
 }
 
+#define DEFINE_INIT_FROM_VECTOR(ctype, functype, vtype, usuffix) \
+    HRESULT WINAPI InitPropVariantFrom##functype##Vector(const ctype *pval, ULONG cEl, PROPVARIANT *ppropvar) \
+    { \
+        TRACE("(%p %u %p)\n", pval, cEl, ppropvar); \
+        \
+        ppropvar->u.ca##usuffix.pElems = CoTaskMemAlloc(cEl * sizeof(ctype)); \
+        if(!ppropvar->u.ca##usuffix.pElems) \
+            return E_OUTOFMEMORY; \
+        \
+        ppropvar->vt = VT_VECTOR|VT_##vtype; \
+        ppropvar->u.ca##usuffix.cElems = cEl; \
+        memcpy(ppropvar->u.ca##usuffix.pElems, pval, cEl * sizeof(ctype)); \
+        return S_OK; \
+    }
+
+DEFINE_INIT_FROM_VECTOR(SHORT, Int16, I2, i)
+DEFINE_INIT_FROM_VECTOR(USHORT, UInt16, UI2, ui)
+DEFINE_INIT_FROM_VECTOR(LONG, Int32, I4, l)
+DEFINE_INIT_FROM_VECTOR(ULONG, UInt32, UI4, ul)
+DEFINE_INIT_FROM_VECTOR(LONGLONG, Int64, I8, h)
+DEFINE_INIT_FROM_VECTOR(ULONGLONG, UInt64, UI8, uh)
+DEFINE_INIT_FROM_VECTOR(double, Double, R8, dbl)
+DEFINE_INIT_FROM_VECTOR(FILETIME, FileTime, FILETIME, filetime)
+
+#undef DEFINE_INIT_FROM_VECTOR
+
+HRESULT WINAPI InitPropVariantFromBooleanVector(const BOOL *pbool, ULONG cEl, PROPVARIANT *ppropvar)
+{
+    ULONG i;
+    TRACE("(%p %u %p)\n", pbool, cEl, ppropvar);
+
+    ppropvar->u.cabool.pElems = CoTaskMemAlloc(cEl * sizeof(VARIANT_BOOL));
+    if (!ppropvar->u.cabool.pElems)
+        return E_OUTOFMEMORY;
+
+    ppropvar->vt = VT_VECTOR|VT_BOOL;
+    ppropvar->u.cabool.cElems = cEl;
+
+    for (i = 0; i < cEl; ++i)
+    {
+        ppropvar->u.cabool.pElems[i] = pbool[i] ? VARIANT_TRUE : VARIANT_FALSE;
+    }
+
+    return S_OK;
+}
+
+HRESULT WINAPI InitPropVariantFromFileTime(const FILETIME *pft, PROPVARIANT *pprop)
+{
+    TRACE("(%p %p)\n", pft, pprop);
+
+    pprop->vt = VT_FILETIME;
+    pprop->u.filetime = *pft;
+
+    return S_OK;
+}
+
+HRESULT WINAPI InitPropVariantFromStringVector(const WCHAR **pstr, ULONG c, PROPVARIANT *pprop)
+{
+    ULONG i;
+    TRACE("(%p %u %p)\n", pstr, c, pprop);
+
+    pprop->u.calpwstr.pElems = CoTaskMemAlloc(c * sizeof(WCHAR *));
+    if (!pprop->u.calpwstr.pElems)
+        return E_OUTOFMEMORY;
+
+    ZeroMemory(pprop->u.calpwstr.pElems, c * sizeof(WCHAR *));
+
+    pprop->vt = VT_VECTOR|VT_LPWSTR;
+    pprop->u.calpwstr.cElems = c;
+
+    for (i = 0; i < c; ++i)
+    {
+        ULONG len;
+
+        len = lstrlenW(pstr[i]) + 1;
+
+        pprop->u.calpwstr.pElems[i] = CoTaskMemAlloc(len * sizeof(WCHAR));
+        if (!pprop->u.calpwstr.pElems[i])
+        {
+            PropVariantClear(pprop); /* release already allocated memory */
+            return E_OUTOFMEMORY;
+        }
+
+        memcpy(pprop->u.calpwstr.pElems[i], pstr[i], len * sizeof(WCHAR));
+    }
+
+    return S_OK;
+}
+
 static inline DWORD PROPVAR_HexToNum(const WCHAR *hex)
 {
     DWORD ret;
diff --git a/include/propvarutil.h b/include/propvarutil.h
index 4791543..1efa248 100644
--- a/include/propvarutil.h
+++ b/include/propvarutil.h
@@ -21,6 +21,7 @@
 
 #include <shtypes.h>
 #include <shlwapi.h>
+#include <propidl.h>
 
 enum tagPROPVAR_CHANGE_FLAGS
 {
@@ -63,6 +64,7 @@ HRESULT WINAPI PropVariantChangeType(PROPVARIANT *ppropvarDest, REFPROPVARIANT p
                                      PROPVAR_CHANGE_FLAGS flags, VARTYPE vt);
 HRESULT WINAPI InitPropVariantFromGUIDAsString(REFGUID guid, PROPVARIANT *ppropvar);
 HRESULT WINAPI InitVariantFromGUIDAsString(REFGUID guid, VARIANT *pvar);
+HRESULT WINAPI InitPropVariantFromCLSID(REFCLSID clsid, PROPVARIANT *ppropvar);
 HRESULT WINAPI InitPropVariantFromBuffer(const VOID *pv, UINT cb, PROPVARIANT *ppropvar);
 HRESULT WINAPI InitVariantFromBuffer(const VOID *pv, UINT cb, VARIANT *pvar);
 HRESULT WINAPI PropVariantToGUID(const PROPVARIANT *ppropvar, GUID *guid);
@@ -77,42 +79,104 @@ HRESULT WINAPI PropVariantToUInt16(REFPROPVARIANT propvarIn, USHORT *ret);
 HRESULT WINAPI PropVariantToUInt32(REFPROPVARIANT propvarIn, ULONG *ret);
 HRESULT WINAPI PropVariantToUInt64(REFPROPVARIANT propvarIn, ULONGLONG *ret);
 
-#ifdef __cplusplus
-
+#ifdef NO_PROPVAR_INLINES
 HRESULT InitPropVariantFromBoolean(BOOL fVal, PROPVARIANT *ppropvar);
 HRESULT InitPropVariantFromString(PCWSTR psz, PROPVARIANT *ppropvar);
 HRESULT InitPropVariantFromInt64(LONGLONG llVal, PROPVARIANT *ppropvar);
+#endif
 
+HRESULT WINAPI InitPropVariantFromInt16Vector(const SHORT *pv, ULONG c, PROPVARIANT *pprop);
+HRESULT WINAPI InitPropVariantFromUInt16Vector(const USHORT *pv, ULONG c, PROPVARIANT *pprop);
+HRESULT WINAPI InitPropVariantFromInt32Vector(const LONG *pv, ULONG c, PROPVARIANT *pprop);
+HRESULT WINAPI InitPropVariantFromUInt32Vector(const ULONG *pv, ULONG c, PROPVARIANT *pprop);
+HRESULT WINAPI InitPropVariantFromInt64Vector(const LONGLONG *pv, ULONG c, PROPVARIANT *pprop);
+HRESULT WINAPI InitPropVariantFromUInt64Vector(const ULONGLONG *pv, ULONG c, PROPVARIANT *pprop);
+HRESULT WINAPI InitPropVariantFromBooleanVector(const BOOL *pv, ULONG c, PROPVARIANT *pprop);
+HRESULT WINAPI InitPropVariantFromFileTime(const FILETIME *pft, PROPVARIANT *pprop);
+HRESULT WINAPI InitPropVariantFromFileTimeVector(const FILETIME *pv, ULONG c, PROPVARIANT *pprop);
+HRESULT WINAPI InitPropVariantFromStringVector(const WCHAR **pstr, ULONG c, PROPVARIANT *pprop);
+
+/* FIXME: Make this available only if the compiler supports the inline keyword */
 #ifndef NO_PROPVAR_INLINES
 
-inline HRESULT InitPropVariantFromBoolean(BOOL fVal, PROPVARIANT *ppropvar)
+#ifdef NONAMELESSUNION
+# define PROPVARIANT_U(x) (x).u
+#else
+# define PROPVARIANT_U(x) (x)
+#endif
+
+static inline HRESULT InitPropVariantFromInt16(SHORT val, PROPVARIANT *ppropvar)
+{
+    ppropvar->vt = VT_I2;
+    PROPVARIANT_U(*ppropvar).iVal = val;
+    return S_OK;
+}
+
+static inline HRESULT InitPropVariantFromUInt16(USHORT val, PROPVARIANT *ppropvar)
+{
+    ppropvar->vt = VT_UI2;
+    PROPVARIANT_U(*ppropvar).uiVal = val;
+    return S_OK;
+}
+
+static inline HRESULT InitPropVariantFromInt32(LONG val, PROPVARIANT *ppropvar)
+{
+    ppropvar->vt = VT_I4;
+    PROPVARIANT_U(*ppropvar).lVal = val;
+    return S_OK;
+}
+
+static inline HRESULT InitPropVariantFromUInt32(ULONG val, PROPVARIANT *ppropvar)
+{
+    ppropvar->vt = VT_UI4;
+    PROPVARIANT_U(*ppropvar).ulVal = val;
+    return S_OK;
+}
+
+static inline HRESULT InitPropVariantFromBoolean(BOOL fVal, PROPVARIANT *ppropvar)
 {
     ppropvar->vt = VT_BOOL;
-    ppropvar->boolVal = fVal ? VARIANT_TRUE : VARIANT_FALSE;
+    PROPVARIANT_U(*ppropvar).boolVal = fVal ? VARIANT_TRUE : VARIANT_FALSE;
     return S_OK;
 }
 
-inline HRESULT InitPropVariantFromString(PCWSTR psz, PROPVARIANT *ppropvar)
+static inline HRESULT InitPropVariantFromString(PCWSTR psz, PROPVARIANT *ppropvar)
 {
-    HRESULT hres;
+    ULONG len;
 
-    hres = SHStrDupW(psz, &ppropvar->pwszVal);
-    if(SUCCEEDED(hres))
+    len = lstrlenW(psz) + 1;
+    PROPVARIANT_U(*ppropvar).pwszVal = CoTaskMemAlloc(len * sizeof(WCHAR));
+    if (PROPVARIANT_U(*ppropvar).pwszVal)
+    {
         ppropvar->vt = VT_LPWSTR;
+        memcpy(PROPVARIANT_U(*ppropvar).pwszVal, psz, len * sizeof(WCHAR));
+
+        return S_OK;
+    }
     else
+    {
         PropVariantInit(ppropvar);
-
-    return hres;
+        return E_OUTOFMEMORY;
+    }
 }
 
-inline HRESULT InitPropVariantFromInt64(LONGLONG llVal, PROPVARIANT *ppropvar)
+static inline HRESULT InitPropVariantFromInt64(LONGLONG llVal, PROPVARIANT *ppropvar)
 {
     ppropvar->vt = VT_I8;
-    ppropvar->hVal.QuadPart = llVal;
+    PROPVARIANT_U(*ppropvar).hVal.QuadPart = llVal;
     return S_OK;
 }
 
-#endif
+
+static inline HRESULT InitPropVariantFromUInt64(ULONGLONG val, PROPVARIANT *ppropvar)
+{
+    ppropvar->vt = VT_UI8;
+    PROPVARIANT_U(*ppropvar).uhVal.QuadPart = val;
+    return S_OK;
+}
+
+#undef PROPVARIANT_U
+
 #endif
 
 #endif /* __WINE_PROPVARUTIL_H */
-- 
2.4.3




More information about the wine-devel mailing list