HRESULT DeserializePropVariantFromString(PCWSTR pszIn, PROPVARIANT *ppropvar)
{
    HRESULT hr = E_FAIL;
    DWORD dwFormatUsed, dwSkip, cbBlob;

    // compute and validate the required buffer size
    if (CryptStringToBinaryW(pszIn, 0, CRYPT_STRING_BASE64, NULL, &cbBlob, &dwSkip, &dwFormatUsed) &&
        dwSkip == 0 &&
        dwFormatUsed == CRYPT_STRING_BASE64)
    {
        // allocate a buffer to hold the serialized binary blob
        hr = E_OUTOFMEMORY;
        BYTE *pbSerialized = (BYTE *)CoTaskMemAlloc(cbBlob);
        if (pbSerialized)
        {
            // convert the string to a serialized binary blob
            hr = E_FAIL;
            if (CryptStringToBinaryW(pszIn, 0, CRYPT_STRING_BASE64, pbSerialized, &cbBlob, &dwSkip, &dwFormatUsed))
            {
                // deserialized the blob back into a PROPVARIANT value
                hr = StgDeserializePropVariant((SERIALIZEDPROPERTYVALUE *)pbSerialized, cbBlob, ppropvar);
            }

            CoTaskMemFree(pbSerialized);
        }
    }

    return hr;
}
// @pymethod <o PyPROPVARIANT>|propsys|StgDeserializePropVariant|Creates a <o PyPROPVARIANT> from a serialized buffer
static PyObject *PyStgDeserializePropVariant(PyObject *self, PyObject *args)
{
	PROPVARIANT pv;
	SERIALIZEDPROPERTYVALUE *pspv;
	ULONG bufsize;
	PyObject *ob;
	HRESULT hr;
	if (!PyArg_ParseTuple(args, "O:StgDeserializePropVariant", &ob))
		return NULL;
	// @pyparm bytes|prop||Buffer or bytes object (or str in Python 2) containing a serialized value
	if (!PyWinObject_AsReadBuffer(ob, (void **)&pspv, &bufsize))
		return NULL;
	PY_INTERFACE_PRECALL;
	hr = StgDeserializePropVariant(pspv, bufsize, &pv);
	PY_INTERFACE_POSTCALL;
	if (FAILED(hr))
		return PyCom_BuildPyException(hr);
	return PyWinObject_FromPROPVARIANT(&pv);
};