Persistent Storage and Emulation

Chapter 5 described how one server could mark itself to emulate another CLSID using the TreatAs and AutoTreatAs registry keys. In that discussion, emulation was related only to a component's objects and interfaces—that is, its run-time functionality. But what if those objects implement IPersistStorage, IPersistStream[Init], or IPersistFile? In that case, not only must the emulating object match the original's functionality, it must also emulate the original's storage. In other words, the emulating object must be able to read and write the same data formats as the original. This means that the object has knowledge about the original object's persistence model and data structures in order for it to read and write those structures.

When an emulating object overwrites the original object's storage, the object (the CLSID and the persistent data) is said to be permanently converted to the newer CLSID. This means that if emulation were removed, the original object could no longer work with the data in the storage. This process is currently limited to compound document objects and OLE controls that support IPersistStorage. The user interface elements and API functions that deal with conversion are found in OLE Documents. We'll see them in Chapters 17–19. The client and object must cooperate to make conversion work, and the only standards defined for that cooperation are part of OLE Documents.