PROPVARIANT Helpers #2 - Reading single values

Reading a PROPVARIANT seems innocuous, but it suffers from many of the same dangers as does initializating one of these structures. I highly recommend that you instead use the following helpers to aid your code's readability and reduce your error rate.

If the data is not exactly the right type, these functions attempt to convert the type to what you've asked for. String <-> Integer, and Integer <-> Integer conversions are supported, along with a few others. The conversions should be locale-invariant, so don't depend on the conversions to provide display strings. I'll talk about the details in future posts (... note to self ...)

I've marked the ideal VARTYPE for each function. If the PROPVARIANT is already of that type, a conversion is not necessary.

// Basic types
PSSTDAPI PropVariantToBoolean(REFPROPVARIANT propvarIn, __out BOOL *pfRet); // VT_BOOL
PSSTDAPI PropVariantToInt16(REFPROPVARIANT propvarIn, __out SHORT *piRet); // VT_I2
PSSTDAPI PropVariantToUInt16(REFPROPVARIANT propvarIn, __out USHORT *puiRet); // VT_UI2
PSSTDAPI PropVariantToInt32(REFPROPVARIANT propvarIn, __out LONG *plRet); // VT_I4
PSSTDAPI PropVariantToUInt32(REFPROPVARIANT propvarIn, __out ULONG *pulRet); // VT_UI4
PSSTDAPI PropVariantToInt64(REFPROPVARIANT propvarIn, __out LONGLONG *pllRet); // VT_I8
PSSTDAPI PropVariantToUInt64(REFPROPVARIANT propvarIn, __out ULONGLONG *pullRet);// VT_UI8
PSSTDAPI PropVariantToDouble(REFPROPVARIANT propvarIn, __out DOUBLE *pdblRet); // VT_R8
PSSTDAPI PropVariantToBuffer(REFPROPVARIANT propvar, __out_bcount(cb) void *pv, UINT cb); // VT_VECTOR | VT_UI1

// Strings and things
PSSTDAPI PropVariantToString(REFPROPVARIANT propvar, __out_ecount(cch) PWSTR psz, UINT cch); // VT_LPWSTR or VT_BSTR
HRESULT PropVariantToBSTR(REFPROPVARIANT propvar, __out BSTR *pbstrOut); // VT_LPWSTR or VT_BSTR
HRESULT PropVariantToStringAlloc(REFPROPVARIANT propvar, __out PWSTR *ppszOut); // VT_LPWSTR or VT_BSTR
PSSTDAPI PropVariantToStringVector(REFPROPVARIANT propvar, __out_ecount_part(crgsz, *pcElem) PWSTR *prgsz, ULONG crgsz, __out ULONG *pcElem); // VT_VECTOR | VT_LPWSTR
PSSTDAPI PropVariantToStringVectorAlloc(REFPROPVARIANT propvar, __out_ecount(*pcElem) PWSTR **pprgsz, __out ULONG *pcElem); // VT_VECTOR | VT_LPWSTR

// Other
PSSTDAPI PropVariantToGUID(REFPROPVARIANT propvar, __out GUID *pguid); // VT_GUID
PSSTDAPI PropVariantToStrRet(REFPROPVARIANT propvar, __out STRRET *pstrret); // VT_LPWSTR or VT_BSTR
PSSTDAPI PropVariantToFileTime(REFPROPVARIANT propvar, PSTIME_FLAGS pstfOut, __out FILETIME* pftOut); // VT_FILETIME
HRESULT PropVariantToCLSID(REFPROPVARIANT propvar, __out CLSID *pclsid); // VT_GUID

I briefly want to mention that if given a vector, PropVariantToString() will return a semicolon delimited string. This is different behavior than PropVariantChangeType().

Most of these helpers are declared in propvarutil.h and implemented in propsys.dll.