On my last post I promised to implement a a better way to handle property values - using the raw DBPROP and DBPROPSET structures is a pain, adds unnecessary code and reduces code readability. My approach to solve this problem is very similar to what you can find in the ATL OLE DB Consumer Templates: I defined two classes, each publicly deriving from the OLE DB strucrures and then added some conveninence code.
This class is a very simple wrapper around DBPROP that provides only safe initialization and disposal. It also knos how to make copies of itself. You will see this code in action when a property is added to a property set.
Besides wrapping the DBPROPSET structure, this class adds a few methods to ease the addition of properties to a property set. For instance, setting the file name is now simply:
This makes for less code and especially for more readable code. The AddProperty method is overloaded for booleans, integers and strings (the most common property types) and simply sets all the DBPROP structure values according to the data type (see how the vVariant value is set), and then adds this structure to the existing property set. Property values are set through an instance of CDbProp class because it clears the variant data when it goes out of scope. Also it knows how to make a copy of itself into a DBPROP pointer (the CopyTo method).
Property set memory is managed through the CoTaskMemRealloc and CoTaskMemFree functions. Why didn't I use the new and delete operators? Some OLE DB interface methods will return this type of data back to the client and the client needs to correctly delete it. The provider allocates all its data using the CoTaskMem functions, so our code needs to comply in order to avoid memory leaks. The downside of this design is that we lose the delete  semantics and must implement it ourselves (see CDbPropSet::Clear)...
The second version of the sample code can be downloaded from here.