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 */