c++comstructured-storage

custom structured storage IPropertySetStorage


I'm trying to add a IPropertySetStorage to an existing IStorage file. The properties and their values I plan to write will be custom to my design (I may store a few ints, a few strings, etc). I am not trying to conform to any existing IStorage file type.

The API and its documentation feels targeted at existing file formats. This is custom, and thus (so far) the examples I have found have only been confusing.

Question(s)

On IPropertySetStorage::Create

  1. (param 1) What FMTID do I pass? Can it be all zeros on the data fields? Can I just make it up?
  2. (param 2) Can CLSID be a nullptr? If not, what should it be? Do I need to figure out what values the parent IStorage used?
  3. (param 3) What propset flag would be best? I'm thinking because I'll be storing string, I should use PROPSETFLAG_DEFAULT.
  4. (param 4) The IStorage handle is open for read (I'm running like a plugin to an existing runtime). My best guess right now is to use STGM_DIRECT | STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE. But I've been getting STG_E_INVALIDFLAG

Note, I have not been able to create a new IPropertySetStorage on the IStorage as of yet, but I have successfully created a custom IStream, and read from it on later opens.

Any links to tutorials more relevant to what I'm doing would be wonderfully appreciated.

EDIT Note that my code is called from an existing application, working on existing files. When my code is called, I am passed the file's root IStorage. Here is all of my code with that IStorage base.

rootStg->OpenStorage(name, nullptr, STGM_READ | STGM_SHARE_EXCLUSIVE, nullptr, 0, &spIStg);
spIStg->QueryInterface(IID_IPropertySetStorage, reinterpret_cast<void**>(&pPropSetStg));    

pPropSetStg->Create(
  ::FMTID_UserDefinedProperties, 
  nullptr, 
  PROPSETFLAG_DEFAULT, 
  STGM_CREATE|STGM_READWRITE|STGM_DIRECT|STGM_SHARE_EXCLUSIVE , 
  &pPropStg);

Which, as I pointed out in #4, returns STG_E_INVALIDFLAG.


Solution

  • (Special thanks to @Xearinox)

    As I was pasting all the relevant code, I noticed that I am opening my storage (I first create a child storage to house my parts) in READ mode, not RW (RW on create, but not when it's already there). This caused the create for the prop set to fail.

    // see STGM_READWRITE (fix)
    rootStg->OpenStorage(name, nullptr, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, nullptr, 0, &spIStg);
    spIStg->QueryInterface(IID_IPropertySetStorage, reinterpret_cast<void**>(&pPropSetStg));    
    
    pPropSetStg->Create(
      ::FMTID_UserDefinedProperties, 
      nullptr, 
      PROPSETFLAG_DEFAULT, 
      STGM_CREATE|STGM_READWRITE|STGM_DIRECT|STGM_SHARE_EXCLUSIVE , 
      &pPropStg);