This example shows how to interpret a hex dump of a simple compound file. The screen shot above
shows the layout of the file and directories. NB for this example the block size has been set to
0x100 (256), usually the block size is 0x800 (2048)
0x00 to 0xFF - The compound file header
The header contains info about the compond file, for instance its on-disk layout.
|
|
0x1234567 |
m_iMagic1 - First of the two magic numbers |
|
|
0x89abcdef |
m_iMagic2 - Secong magic number |
|
|
0x34 |
m_iHeaderSize - Size of the header in bytes |
|
|
0x2 |
m_iVersion - Version of the DLL that created this compound file |
|
|
|
0x1 |
m_iLowVersion - Lowest version of the DLL that can read this file |
|
|
0x1 |
m_iAllocTableIndex - Block index of the allocation table (1 * block size = 0x100) |
|
|
0x2 |
m_iFileTableIndex - Block index of the file table |
|
|
0x3 |
m_iDirTableIndex - Block index of the directory table |
|
|
|
0x4 |
m_iNamesIndex - Block index of the names table |
|
|
0xffffffff |
m_iNextID - Block index to the next block. Not currently used |
|
|
0x268 |
m_iPhysicalPosOfFileTable_FileTableEntry - Position of the file table in the file, this
is a physical position, not a block index. See CompoundFileSys.LoadFromExistingStream |
|
|
0xc8 |
m_iVirtualSizeOfFileTable - Size of the file table. See CompoundFileSys.LoadFromExistingStream |
|
|
|
0x100 |
m_iBlockSize - Block size |
|
0x100 to 0x1FF - The allocation table
Each block in the compound file has a corresponding entry in the allocation table. The allocation table is not a
"map" of the file (e.g. the way MS-DOS FAT tables work). Rather each entry has an ID which is its block index, to
check if a block is empty the allocation table needs to check if the ID has been used by any of the entries.
|
|
0xa1b55b1a |
BlockHeader::m_iMagic - magic number |
|
|
0x6 |
BlockHeader::m_iTotalItems - number of items in the alloc table |
|
|
0xffffffff |
m_iNext - next alloc table block in the chain |
|
|
Each entry in the allocation table has 3 values (m_iID, m_iNext and m_iFlags).
The image above shows a hex dump containing 3 allocation table entries (each with 3 values).
The first entry (m_iID = 5, m_iNext = -1 and m_iFlags = 0x20) if for block 5, which in this example
is the block containing the users text (i.e. the file).
|
|
0x200 to 0x2FF - The file table
Every file in the compound file has a single entry in the file table. Since a file can span
multiple blocks it can have any number of allocation table entries. Each file table entry
has the index of the first allocation table entry, this entry's "m_iNext" value can be
used to build the allocation block chain.
Notice that the file table does not have a "next" value. This is because the file table is
accessed via a FSFilterStream. All tables other than the allocation table use a FSFilterStream.
|
|
0x70123afc |
BlockHeader::m_iMagic - magic number |
|
|
0x06 |
BlockHeader::m_iTotalItems - number of items in the file table |
|
|
Each entry in the allocation table has 8 values. The first entry is shown here.
0x5 |
m_iAllocTblIndex - Fist allocation block entry |
0x3 |
m_iNameID - ID of the files name. See the name table |
0x1 |
m_iDirID - Parent directory |
0xffffffff |
m_iPropID - Property file ID |
0x0 |
m_iCheckSum - File's checksum (not used) |
0xbb |
m_iLength - File's length |
|
|
0x300 to 0x3FF - The directory table
|
|
0x19283746 |
BlockHeader::m_iMagic - magic number |
|
|
0x02 |
BlockHeader::m_iTotalItems - number of items in the dir table |
|
|
Each entry in the dir table has 5 values. The first entry is shown here.
0x2 |
m_iID - This directory's ID |
0x2 |
m_iNameID - ID of the directory's name |
0x1 |
m_iParentID - Parent directory |
0xffffffff |
m_iPropID - Directory's property file |
|
|
0x400 to 0x4FF - The names table
The name IDs refered to above (in the file table and directory table) reference strings stored in
the names table.
|
|
0x64faec70 |
BlockHeader::m_iMagic - magic number |
|
|
0x02 |
BlockHeader::m_iTotalItems - number of items in the names table |
|
The names are stored as length prefixed strings. If you look at the dump you should be able to see the three names
"file 1-2", "dir 1-1" and "dir 1"
0x500 to 0x5FF - The first file (the rtf text)
This is the first, and only file in the example compound file. The user of the compund file has complete contro of what is
stored in a file. The compound file will not prepend or append any data to the file. By using a FSFilterStream the file
will work like any other Stream class.
In this example rich text has been saved in the file.
The entire file
frhed (http://www.tu-darmstadt.de/~rkibria) was used
to create all the hex dumps shown on this page.