PowerPoint can save by appending to the stream. An edit adds new top-level records, a persist directory and a user edit atom, and leaves the old records where they are. So the stream holds both current and out-of-date records, and a reader finds the current ones by following references, not by reading from the start.
UserEditAtom
Record type 0x0FF5, recVer 0, recInstance 0, recLen 0x1C or 0x20.
| Offset | Size | Field | Meaning |
|---|---|---|---|
| 8 | 4 | lastSlideIdRef | The last slide viewed, for the newest edit; otherwise ignored. |
| 12 | 2 | version | A build number; should be 0 and is ignored. |
| 14 | 1 | minorVersion | 0. |
| 15 | 1 | majorVersion | 3. |
| 16 | 4 | offsetLastEdit | The offset of the previous UserEditAtom, less than this record’s. Zero means there is none. |
| 20 | 4 | offsetPersistDirectory | The offset of this edit’s PersistDirectoryAtom. |
| 24 | 4 | docPersistIdRef | The persist id of the DocumentContainer. Always 1. |
| 28 | 4 | persistIdSeed | Greater than or equal to every persist id in the file. |
| 32 | 2 | lastView | The view last used: 1 slide, 2 slide master, 3 notes, 7 outline, 8 slide sorter, 11 slide show, and others. |
| 34 | 2 | unused | Ignored. |
| 36 | 4 | encryptSessionPersistIdRef | Optional: the persist id of the CryptSession10Container of an encrypted file. |
PersistDirectoryAtom
Record type 0x1772. Its body is a list of PersistDirectoryEntry structures:
0persistId the first id, the low 20 bits of a 32-bit value20 bits0cPersist how many offsets follow, the high 12 bits12 bits4rgPersistOffset one 32-bit stream offset for each id, persistId, persistId + 1, …4 bytes each
A persist id is a number that stands for a top-level record: slides, the document container and so on refer to each other by it, not by offset, so an edit can move a record and only change the directory.
Finding the live records
- Read the CurrentUserAtom and go to
offsetToCurrentEditin the PowerPoint Document stream. - Read the UserEditAtom there. Go to its
offsetPersistDirectoryand read that PersistDirectoryAtom. - Go to
offsetLastEditand repeat, until it is zero. - Build the directory from the oldest edit forward, so that a newer edit’s offset for an id replaces an older one.
- Look up
docPersistIdRefin the directory: that is the DocumentContainer. - Every record the presentation refers to by persist id is found through the directory the same way.
Records that nothing reaches this way are dead: leftovers from earlier saves. Their contents are not specified and must be ignored.