get OLE properties using IFilter C++
See the question and my original answer on StackOverflowThe value is define in the STAT_CHUNK's
attribute
field. It's define as a FULLPROPSPEC
structure, which can be (most of the time) directly related to Windows Property System.
A FULLPROPSPEC can either point to a GUID+id property, or to a custom property defined by its name (ideally, you need to check for psProperty.ulKind
to determine this). Today, most of implementation just don't use the name thing and stick to the GUID (property set) + PROPID (int) definition of a "property".
So for example, this is a sample code that is capable of determining what's the property name and value formatted as a string using PSGetNameFromPropertyKey and IPropertyDescription::FormatForDisplay :
...
if (CHUNK_VALUE == chunk.flags)
{
if (chunk.attribute.psProperty.ulKind == PRSPEC_PROPID)
{
// build a Windows Property System property key
// need propsys.h & propsys.lib
PROPERTYKEY pk;
pk.fmtid = chunk.attribute.guidPropSet;
pk.pid = chunk.attribute.psProperty.propid;
PWSTR name;
if (SUCCEEDED(PSGetNameFromPropertyKey(pk, &name)))
{
wprintf(L" name:'%s'\n", name);
CoTaskMemFree(name);
}
IPropertyDescription *pd;
if (SUCCEEDED(PSGetPropertyDescription(pk, IID_PPV_ARGS(&pd))))
{
PROPVARIANT *pVar;
hr = pFilt->GetValue(&pVar);
if (SUCCEEDED(hr))
{
LPWSTR display;
if (SUCCEEDED(pd->FormatForDisplay(*pVar, PDFF_DEFAULT, &display)))
{
wprintf(L" value:'%s'\n", display);
CoTaskMemFree(display);
}
PropVariantClear(pVar);
}
pd->Release();
}
continue;
} // otherwise it's a string
PROPVARIANT *pVar;
hr = pFilt->GetValue(&pVar);
if (SUCCEEDED(hr))
{
// do something with the value
PropVariantClear(pVar);
}
}