<html> <head> <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title></title> </head> <body bgcolor="#ffffff" marginheight="4" marginwidth="4" leftmargin="4" topmargin="4" alink="#023264" vlink="#023264" link="#525D76" text="#000000"> <table border="0" cellpadding="0" cellspacing="0" width="100%"> <tr> <td align="left" valign="top"><a href="http://jakarta.apache.org/index.html"><img src="images/jakarta-logo.gif" border="0" vspace="0" hspace="0"></a></td><td bgcolor="#ffffff" align="left" valign="top" width="100%"><img src="images/header.gif" align="right" border="0" vspace="0" hspace="0"></td> </tr> <tr> <td colspan="2" height="2" width="100%"> <hr size="1" noshade=""> </td> </tr> </table> <table border="0" cellpadding="0" cellspacing="0" width="100%"> <tr> <td valign="top" width="1%"></td><td nowrap="1" valign="top" width="14%"> <br> <font face="arial,helvetica,sanserif"> <br> <font size="+1" color="#000000">Navigation</font><font size="-1"> <ul> <li> <a href="../index.html"><font size="-1">Main</font></a> </li> <li> <a href="how-to.html"><font size="-1">How To</font></a> </li> <li> <a href="fileformat.html"><font size="-1">File System Documentation</font></a> </li> <li> <a href="usecases.html"><font size="-1">Use Cases</font></a> </li> </ul> </font> <br> <br> </font></td><td align="left" valign="top" width="*"><font size="-2" color="#000000"> <p> <a href="mailto:"></a> </p> </font> <br> <div align="right"> <table cellspacing="0" cellpadding="2" border="0" width="100%"> <tr> <td bgcolor="#525D76"><font color="#ffffff" size="+1"><font face="Arial,sans-serif"><b>POIFS File System Internals</b></font></font></td> </tr> <tr> <td> <br> <div align="right"> <table cellspacing="0" cellpadding="2" border="0" width="99%"> <tr> <td bgcolor="#525D76"><font color="#ffffff" size="+0"><font face="Arial,sans-serif"><b>Introduction</b></font></font></td> </tr> <tr> <td> <br> <p align="justify">POIFS file systems are essentially normal files stored on a Java-compatible platform's native file system. They are typically identified by names ending in a four character extension noting what type of data they contain. For example, a file ending in ".xls" would likely contain spreadsheet data, and a file ending in ".doc" would probably contain a word processing document. POIFS file systems are called "file system", because they contain multiple embedded files in a manner similar to traditional file systems. Along functional lines, it would be more accurate to call these POIFS archives. For the remainder of this document it is referred to as a file system in order to avoid confusion with the "files" it contains.</p> <p align="justify">POIFS file systems are compatible with those document formats used by a well-known software company's popular office productivity suite and programs outputting compatible data. Because the POIFS file system does not provide compression, encryption or any other worthwhile feature, its not a good choice unless you require interoperability with these programs.</p> <p align="justify">The POIFS file system does not encode the documents themselves. For example, if you had a word processor file with the extension ".doc", you would actually have a POIFS file system with a document file archived inside of that file system.</p> </td> </tr> </table> </div> <br> <div align="right"> <table cellspacing="0" cellpadding="2" border="0" width="99%"> <tr> <td bgcolor="#525D76"><font color="#ffffff" size="+0"><font face="Arial,sans-serif"><b>Document Conventions</b></font></font></td> </tr> <tr> <td> <br> <p align="justify">This document utilizes the numeric types as described by the Java Language Specification, which can be found at <a href="http://java.sun.com">http://java.sun.com</a>. In short:</p> <ul> <li>A <b>byte</b> is an 8 bit signed integer ranging from -128 to 127.</li> <li>A <b>short</b> is a 16 bit signed integer ranging from -32768 to 32767</li> <li>An <b>int</b> is a 32 bit signed integer ranging from -2147483648 to 2147483647</li> <li>A <b>long</b> is a 64 bit signed integer ranging from -9.22E18 to 9.22E18.</li> </ul> <p align="justify">The Java Language Specification spells out a number of other types that are not referred to by this document.</p> <p align="justify">Where this document makes references to "endian conversion" it is referring to the byte order of stored numbers. Numbers in "little-endian order" are stored with the <b>least</b> significant byte first. In order to properly read a short, for example, you'd read two bytes and then shift the second byte 8 bits to the left before performing an <code>or</code> operation to it against the first byte. The following code illustrates this method:</p> <div align="center"> <table cellspacing="2" cellpadding="2" border="1"> <tr> <td> <pre> public int getShort (byte[] rec) { return ((rec[1] << 8) | (rec[0] & 0x00ff)); }</pre> </td> </tr> </table> </div> </td> </tr> </table> </div> <br> <div align="right"> <table cellspacing="0" cellpadding="2" border="0" width="99%"> <tr> <td bgcolor="#525D76"><font color="#ffffff" size="+0"><font face="Arial,sans-serif"><b>File System Walkthrough</b></font></font></td> </tr> <tr> <td> <br> <p align="justify">This is a walkthrough of a POIFS file system and how it is put together. It is not intended to give a concise description but to give a "big picture" of the general structure and how it's interpreted.</p> <p align="justify">A POIFS file system begins with a header. This header identifies locations in the file by function and provides a sanity check identifying a file as a POIFS file system.</p> <p align="justify">The first 64 bits of the header compose a <b>magic number identifier.</b> This identifier tells the client software that this is indeed a POIFS file system and that it should be treated as such. This is a "sanity check" to make sure this is a POIFS file system and not some other format. The header also contains an <b>array of block numbers</b>. These block numbers refer to blocks in the file. When these blocks are read together they form the <b>Block Allocation Table</b>. The header also contains a pointer to the first element in the <b>property table</b>, also known as the <b>root element</b>, and a pointer to the <b>small Block Allocation Table (SBAT)</b>.</p> <p align="justify">The <b>block allocation table</b> or <b>BAT</b>, along with the <b>property table</b>, specify which blocks in the file system belong to which files. After the header block, the file system is divided into identically sized blocks of data, numbered from 0 to however many blocks there are in the file system. For each file in the file system, its entry in the property table includes the index of the first block in the array of blocks. Each block's index into the array of blocks is also its index into the BAT, and the integer value stored at that index in the BAT gives the index of the next block in the array (and thus the index of the next BAT value). A special value is stored in the BAT to indicate "end of file".</p> <p align="justify">The <b>property table</b> is essentially the directory storage for the file system. It consists of the name of the file or directory, its <b>start block</b> in both the file system and <b>BAT</b>, and its actual size. The first property in the property table is the <b>root element</b>. It has two purposes: to be a directory entry (the root of the directory tree, to be specific), and to hold the start block for the <b>small block data</b>.</p> <p align="justify">Small block data is a special file that contains the data for small files (less than 4K bytes). It subdivides its blocks into smaller blocks and there is a special small block allocation table that, like the main BAT for larger files, is used to map a small file to its small blocks.</p> </td> </tr> </table> </div> <br> <div align="right"> <table cellspacing="0" cellpadding="2" border="0" width="99%"> <tr> <td bgcolor="#525D76"><font color="#ffffff" size="+0"><font face="Arial,sans-serif"><b>Header Block</b></font></font></td> </tr> <tr> <td> <br> <p align="justify">The POIFS file system begins with a <b>header block</b>. The first 64 bits of the header form a long <b>file type id</b> or <b>magic number identifier</b> of <code>0xE11AB1A1E011CFD0L</code>. This is basically a sanity check. If this isn't the first thing in the header (and consequently the file system) then this is not a POIFS file system and should be read with some other library.</p> <p align="justify">It's important to know the most important parts of the header. These are discussed in the rest of this section.</p> <div align="right"> <table cellspacing="0" cellpadding="2" border="0" width="98%"> <tr> <td bgcolor="#525D76"><font color="#ffffff" size="-1"><font face="Arial,sans-serif"><b>BATs</b></font></font></td> </tr> <tr> <td> <br> <p align="justify">At offset <b>0x2C</b> is an int specifying the number of elements in the <b>BAT array</b>. The array at <b>0x4C</b> an array of ints. This array contains the indices of every block in the Block Allocation Table.</p> </td> </tr> </table> </div> <br> <div align="right"> <table cellspacing="0" cellpadding="2" border="0" width="98%"> <tr> <td bgcolor="#525D76"><font color="#ffffff" size="-1"><font face="Arial,sans-serif"><b>XBATs</b></font></font></td> </tr> <tr> <td> <br> <p align="justify">Very large POIFS archives may have more blocks than can be addressed by the BAT blocks enumerated in the header block. How large? Well, the BAT array in the header can contain up to 109 BAT block indices; each BAT block references up to 128 blocks, and each block is 512 bytes, so we're talking about 109 * 128 * 512 = 6.8MB. That's a pretty respectable document! But, you could have much more data than that, and in today's world of cheap gigabyte drives, why not? So, the BAT may be extended in that event. The integer value at offset <b>0x44</b> of the header is the index of the first <b>extended BAT (XBAT) block</b>. At offset <b>0x48</b> of the header, there is an int value that specifies how many XBAT blocks there are. The XBAT blocks begin at the specified index into the array of blocks making up the POIFS file system, and continue in sequence for the specified count of XBAT blocks.</p> <p align="justify">Each XBAT block contains the indices of up to 128 BAT blocks, so the document size can be expanded by another 8MB for each XBAT block. The BAT blocks indexed by an XBAT block are appended to the end of the list of BAT blocks enumerated in the header block. Thus the BAT blocks enumerated in the header block are BAT blocks 0 through 108, the BAT blocks enumerated in the first XBAT block are BAT blocks 109 through 236, the BAT blocks enumerated in the second XBAT block are BAT blocks 237 through 364, and so on.</p> <p align="justify">Through the use of XBAT blocks, the limit on the overall document size is that imposed by the 4-byte block indices; if the indices are unsigned ints, the maximum file size is 2 terabytes, 1 terabyte if the indices are treated as signed ints. Either way, I have yet to see a disk drive large enough to accommodate such a file on the shelves at the local office supply stores.</p> </td> </tr> </table> </div> <br> <div align="right"> <table cellspacing="0" cellpadding="2" border="0" width="98%"> <tr> <td bgcolor="#525D76"><font color="#ffffff" size="-1"><font face="Arial,sans-serif"><b>SBATs</b></font></font></td> </tr> <tr> <td> <br> <p align="justify">If a file contained in a POIFS archive is smaller than 4096 bytes, it is stored in small blocks. Small blocks are 64 bytes in length and are contained within big blocks, up to 8 to a big block. As the main BAT is used to navigate the array of big blocks, so the <b>small block allocation table</b> is used to navigate the array of small blocks. The SBAT's start block index is found at offset <b>0x3C</b> of the header block, and remaining blocks constituting the SBAT are found by walking the main BAT as if it were an ordinary file in the POIFS file system (this process is described below).</p> </td> </tr> </table> </div> <br> <div align="right"> <table cellspacing="0" cellpadding="2" border="0" width="98%"> <tr> <td bgcolor="#525D76"><font color="#ffffff" size="-1"><font face="Arial,sans-serif"><b>Property Table Start Index</b></font></font></td> </tr> <tr> <td> <br> <p align="justify">An integer at address <b>0x30</b> specifies the start index of the property table. This integer is specified as a <b>"block index"</b>. The Property Table is stored, as is almost everything in a POIFS file system, in big blocks and walked via the BAT. The Property Table is described below.</p> </td> </tr> </table> </div> <br> </td> </tr> </table> </div> <br> <div align="right"> <table cellspacing="0" cellpadding="2" border="0" width="99%"> <tr> <td bgcolor="#525D76"><font color="#ffffff" size="+0"><font face="Arial,sans-serif"><b>Property Table</b></font></font></td> </tr> <tr> <td> <br> <p align="justify">The property table is essentially nothing more than the directory system. Properties are 128 byte records contained within the 512 byte blocks. The first property is always the Root Entry. The following applies to individual properties within a property table:</p> <ul> <li>At offset <b>0x00</b> in the property is the "<b>name</b>". This is stored as an uncompressed 16 bit unicode string. In short every other byte corresponds to an "ASCII" character. The size of this string is stored at offset <b>0x40</b> (<b>string size</b>) as a short.</li> <li>At offset <b>0x42</b> is the <b>property type</b> (byte). The type is 1 for directory, 2 for file or 5 for the Root Entry.</li> <li>At offset <b>0x43</b> is the <b>node color</b> (byte). The color is either 1, (black), or 0, (red). Properties are apparently meant to be arranged in a red-black binary tree, subject to the following rules: <ol> <li>The root of the tree is always black</li> <li>Two consecutive nodes cannot both be red</li> <li>A property is less than another property if its name length is less than the other property's name length</li> <li>If two properties have the same name length, the sort order is determined by the sort order of the properties' names.</li> </ol> </li> <li>At offset <b>0x44</b> is the index (int) of the <b>previous property</b>.</li> <li>At offset <b>0x48</b> is the index (int) of the <b>next property</b>.</li> <li>At offset <b>0x4C</b> is the index (int) of the <b>first directory entry</b>. This is used by directory entries.</li> <li>At offset <b>0x74</b> is an integer giving the <b>start block</b> for the file described by this property. This index corresponds to an index in the array of indices that is the Block Allocation Table (or the Small Block Allocation Table) as well as the index of the first block in the file. This is used by files and the root entry.</li> <li>At offset <b>0x78</b> is an integer giving the total <b>actual size</b> of the file pointed at by this property. If the file size is less than 4096, the file is stored in small blocks and the SBAT is used to walk the small blocks making up the file. If the file size is 4096 or larger, the file is stored in big blocks and the main BAT is used to walk the big blocks making up the file. The exception to this rule is the <b>Root Entry</b>, which, regardless of its size, is <b>always</b> stored in big blocks and the main BAT is used to walk the big blocks making up this special file.</li> </ul> </td> </tr> </table> </div> <br> <div align="right"> <table cellspacing="0" cellpadding="2" border="0" width="99%"> <tr> <td bgcolor="#525D76"><font color="#ffffff" size="+0"><font face="Arial,sans-serif"><b>Root Entry</b></font></font></td> </tr> <tr> <td> <br> <p align="justify">The <b>Root Entry</b> in the <b>Property Table</b> contains the information necessary to read and write small files, which are files less than 4096 bytes long. The start block field of the Root Entry is the start index of the <b>Small Block Array</b>, which is read like any other file in the POIFS file system. Since the SBAT cannot be used without the Small Block Array, the Root Entry MUST be read or written using the <b>Block Allocation Table</b>. The blocks making up the Small Block Array are divided into 64-byte small blocks, up to the size indicated in the Root Entry (which should always be a multiple of 64).</p> </td> </tr> </table> </div> <br> <div align="right"> <table cellspacing="0" cellpadding="2" border="0" width="99%"> <tr> <td bgcolor="#525D76"><font color="#ffffff" size="+0"><font face="Arial,sans-serif"><b>Walking the Nodes of the Property Table</b></font></font></td> </tr> <tr> <td> <br> <p align="justify">The individual properties form a directory tree, with the <b>Root Entry</b> as the directory tree's root, as shown in the accompanying drawing. Note the numbers in parentheses in each node; they represent the node's index in the array of properties. The <b>NEXT_PROP</b>, <b>PREVIOUS_PROP</b>, and <b>CHILD_PROP</b> fields hold these indices, and are used to navigate the tree.</p> <img src="images/PropertySet.jpg"> <p align="justify">Each directory entry (i.e., a property whose type is <b>directory</b> or <b>root entry</b>) uses its <b>CHILD_PROP</b> field to point to one of its subordinate (child) properties. It doesn't seem to matter which of its children it points to. Thus in the previous drawing, the Root Entry's CHILD_PROP field may contain 1, 4, or the index of one of its other children. Similarly, the directory node (index 1) may have, in its CHILD_PROP field, 2, 3, or the index of one of its other children.</p> <p align="justify">The children of a given directory property point to each other in a similar fashion by using their <b>NEXT_PROP</b> and <b>PREVIOUS_PROP</b> fields.</p> <p align="justify">Unused <b>NEXT_PROP</b>, <b>PREVIOUS_PROP</b>, and <b>CHILD_PROP</b> fields contain the marker value of -1. All file properties have a value of -1 for their CHILD_PROP fields for example.</p> </td> </tr> </table> </div> <br> <div align="right"> <table cellspacing="0" cellpadding="2" border="0" width="99%"> <tr> <td bgcolor="#525D76"><font color="#ffffff" size="+0"><font face="Arial,sans-serif"><b>Block Allocation Table</b></font></font></td> </tr> <tr> <td> <br> <p align="justify">The <b>BAT blocks</b> are pointed at by the bat array contained in the header and supplemented, if necessary, by the <b>XBAT blocks</b>. These blocks form a large table of integers. These integers are block numbers. The <b>Block Allocation Table</b> holds chains of integers. These chains are terminated with -2. The elements in these chains refer to blocks in the files. The starting block of a file is NOT specified in the BAT. It is specified by the <b>property</b> for a given file. The elements in this BAT are both the block number (within the file minus the header) <b>and</b> the number of the next BAT element in the chain. This can be thought of as a linked list of blocks. The BAT array contains the links from one block to the next, including the end of chain marker.</p> <p align="justify">Here's an example: Let's assume that the BAT begins as follows:</p> <p align="justify"> <code>BAT[ 0 ] = 2</code> </p> <p align="justify"> <code>BAT[ 1 ] = 5</code> </p> <p align="justify"> <code>BAT[ 2 ] = 3</code> </p> <p align="justify"> <code>BAT[ 3 ] = 4</code> </p> <p align="justify"> <code>BAT[ 4 ] = 6</code> </p> <p align="justify"> <code>BAT[ 5 ] = -2</code> </p> <p align="justify"> <code>BAT[ 6 ] = 7</code> </p> <p align="justify"> <code>BAT[ 7 ] = -2</code> </p> <p align="justify"> <code>...</code> </p> <p align="justify">Now, if we have a file whose Property Table entry says it begins with index 0, we walk the BAT array and see that the file consists of blocks 0 (because the start block is 0), 2 (because BAT[ 0 ] is 2), 3 (BAT[ 2 ] is 3), 4 (BAT[ 3 ] is 4), 6 (BAT[ 4 ] is 6), and 7 (BAT[ 6 ] is 7). It ends at block 7 because BAT[ 7 ] is -2, which is the end of chain marker.</p> <p align="justify">Similarly, a file beginning at index 1 consists of blocks 1 and 5.</p> <p align="justify">Other special numbers in a BAT array are:</p> <ul> <li>-1, which indicates an unused block</li> <li>-3, which indicates a "special" block, such as a block used to make up the Small Block Array, the Property Table, the main BAT, or the SBAT</li> </ul> </td> </tr> </table> </div> <br> <div align="right"> <table cellspacing="0" cellpadding="2" border="0" width="99%"> <tr> <td bgcolor="#525D76"><font color="#ffffff" size="+0"><font face="Arial,sans-serif"><b>File System Structures</b></font></font></td> </tr> <tr> <td> <br> <p align="justify">The following outlines the basic file system structures.</p> <div align="right"> <table cellspacing="0" cellpadding="2" border="0" width="98%"> <tr> <td bgcolor="#525D76"><font color="#ffffff" size="-1"><font face="Arial,sans-serif"><b>Header (block 1) -- 512 (0x200) bytes</b></font></font></td> </tr> <tr> <td> <br> <table width="100%" cellspacing="2" cellpadding="2" border="0"> <tr> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000"><b>Field</b></font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000"><b>Description</b></font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000"><b>Offset</b></font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000"><b>Length</b></font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000"><b>Default value or const</b></font></td> </tr> <tr> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">FILETYPE</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Magic number identifying this as a POIFS file system.</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">0x0000</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Long</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">0xE11AB1A1E011CFD0</font></td> </tr> <tr> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">UK1</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Unknown constant</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">0x0008</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Integer</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">0</font></td> </tr> <tr> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">UK2</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Unknown Constant</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">0x000C</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Integer</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">0</font></td> </tr> <tr> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">UK3</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Unknown Constant</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">0x0014</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Integer</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">0</font></td> </tr> <tr> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">UK4</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Unknown Constant (revision?)</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">0x0018</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Short</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">0x003B</font></td> </tr> <tr> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">UK5</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Unknown Constant (version?)</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">0x001A</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Short</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">0x0003</font></td> </tr> <tr> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">UK6</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Unknown Constant</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">0x001C</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Short</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">-2</font></td> </tr> <tr> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">LOG_2_BIG_BLOCK_SIZE</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Log, base 2, of the big block size</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">0x001E</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Short</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">9 (2 ^ 9 = 512 bytes)</font></td> </tr> <tr> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">LOG_2_SMALL_BLOCK_SIZE</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Log, base 2, of the small block size</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">0x0020</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Integer</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">6 (2 ^ 6 = 64 bytes)</font></td> </tr> <tr> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">UK7</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Unknown Constant</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">0x0024</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Integer</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">0</font></td> </tr> <tr> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">UK8</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Unknown Constant</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">0x0028</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Integer</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">0</font></td> </tr> <tr> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">BAT_COUNT</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Number of elements in the BAT array</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">0x002C</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Integer</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">required</font></td> </tr> <tr> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">PROPERTIES_START</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Block index of the first block of the property table</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">0x0030</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Integer</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">required</font></td> </tr> <tr> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">UK9</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Unknown Constant</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">0x0034</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Integer</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">0</font></td> </tr> <tr> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">UK10</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Unknown Constant</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">0x0038</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Integer</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">0x00001000</font></td> </tr> <tr> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">SBAT_START</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Block index of first big block containing the small block allocation table (SBAT)</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">0x003C</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Integer</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">-2</font></td> </tr> <tr> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">UK11</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Unknown Constant</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">0x0040</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Integer</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">1</font></td> </tr> <tr> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">XBAT_START</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Block index of the first block in the Extended Block Allocation Table (XBAT)</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">0x0044</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Integer</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">-2</font></td> </tr> <tr> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">XBAT_COUNT</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Number of elements in the Extended Block Allocation Table (to be added to the BAT)</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">0x0048</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Integer</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">0</font></td> </tr> <tr> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">BAT_ARRAY</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Array of block indices constituting the Block Allocation Table (BAT)</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">0x004C, 0x0050, 0x0054 ... 0x01FC</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Integer[]</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">-1 for unused elements, at least first element must be filled.</font></td> </tr> <tr> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">N/A</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Header block data not otherwise described in this table</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">N/A</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">N/A</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">-1</font></td> </tr> </table> </td> </tr> </table> </div> <br> <div align="right"> <table cellspacing="0" cellpadding="2" border="0" width="98%"> <tr> <td bgcolor="#525D76"><font color="#ffffff" size="-1"><font face="Arial,sans-serif"><b>Block Allocation Table Block -- 512 (0x200) bytes</b></font></font></td> </tr> <tr> <td> <br> <table width="100%" cellspacing="2" cellpadding="2" border="0"> <tr> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000"><B>Field</B></font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000"><B>Description</B></font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000"><B>Offset</B></font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000"><B>Length</B></font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000"><B>Default value or const</B></font></td> </tr> <tr> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">BAT_ELEMENT</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Any given element in the BAT block</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">0x0000, 0x0004, 0x0008, ... 0x01FC</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Integer</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000"> <ul> <li>-1 = unused</li> <li>-2 = end of chain</li> <li>-3 = special (e.g., BAT block)</li> </ul> <p align="justify">All other values point to the next element in the chain and the next index of a block composing the file.</p> </font></td> </tr> </table> </td> </tr> </table> </div> <br> <div align="right"> <table cellspacing="0" cellpadding="2" border="0" width="98%"> <tr> <td bgcolor="#525D76"><font color="#ffffff" size="-1"><font face="Arial,sans-serif"><b>Property Block -- 512 (0x200) byte block</b></font></font></td> </tr> <tr> <td> <br> <table width="100%" cellspacing="2" cellpadding="2" border="0"> <tr> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000"><B>Field</B></font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000"><B>Description</B></font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000"><B>Offset</B></font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000"><B>Length</B></font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000"><B>Default value or const</B></font></td> </tr> <tr> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Properties[]</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">This block contains the properties.</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">0x0000, 0x0080, 0x0100, 0x0180</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">128 bytes</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">All unused space is set to -1.</font></td> </tr> </table> </td> </tr> </table> </div> <br> <div align="right"> <table cellspacing="0" cellpadding="2" border="0" width="98%"> <tr> <td bgcolor="#525D76"><font color="#ffffff" size="-1"><font face="Arial,sans-serif"><b>Property -- 128 (0x80) byte block</b></font></font></td> </tr> <tr> <td> <br> <table width="100%" cellspacing="2" cellpadding="2" border="0"> <tr> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000"><B>Field</B></font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000"><B>Description</B></font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000"><B>Offset</B></font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000"><B>Length</B></font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000"><B>Default value or const</B></font></td> </tr> <tr> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">NAME</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">A unicode null-terminated uncompressed 16bit string (lose the high bytes) containing the name of the property.</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">0x00, 0x02, 0x04, ... 0x3E</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Short[]</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">0x0000 for unused elements, field required, 32 (0x40) element max</font></td> </tr> <tr> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">NAME_SIZE</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Number of characters in the NAME field</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">0x40</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Short</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Required</font></td> </tr> <tr> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">PROPERTY_TYPE</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Property type (directory, file, or root)</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">0x42</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Byte</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">1 (directory), 2 (file), or 5 (root entry)</font></td> </tr> <tr> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">NODE_COLOR</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Node color</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">0x43</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Byte</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">0 (red) or 1 (black)</font></td> </tr> <tr> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">PREVIOUS_PROP</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Previous property index</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">0x44</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Integer</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">-1</font></td> </tr> <tr> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">NEXT_PROP</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Next property index</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">0x48</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Integer</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">-1</font></td> </tr> <tr> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">CHILD_PROP</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">First child property index</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">0x4c</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Integer</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">-1</font></td> </tr> <tr> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">SECONDS_1</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Seconds component of the created timestamp?</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">0x64</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Integer</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">0</font></td> </tr> <tr> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">DAYS_1</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Days component of the created timestamp?</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">0x68</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Integer</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">0</font></td> </tr> <tr> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">SECONDS_2</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Seconds component of the modified timestamp?</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">0x6C</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Integer</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">0</font></td> </tr> <tr> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">DAYS_2</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Days component of the modified timestamp?</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">0x70</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Integer</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">0</font></td> </tr> <tr> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">START_BLOCK</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Starting block of the file, used as the first block in the file and the pointer to the next block from the BAT</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">0x74</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Integer</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Required</font></td> </tr> <tr> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">SIZE</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Actual size of the file this property points to. (used to truncate the blocks to the real size).</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">0x78</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">Integer</font></td> <td valign="top" bgcolor="#a0ddf0" align="left"><font size="-1" color="#000000">0</font></td> </tr> </table> </td> </tr> </table> </div> <br> </td> </tr> </table> </div> <br> </td> </tr> </table> </div> <br> </td> </tr> </table> <br> <table cellpadding="0" cellspacing="0" border="0" width="100%"> <tr> <td> <hr size="1" noshade=""> </td> </tr> <tr> <td align="center"><font color="#525D76" size="-1" face="arial,helvetica,sanserif"><i> Copyright ©2002 Apache Software Foundation </i></font></td><td width="5%" align="right"><img src="images/cocoon2-small.jpg" align="right" border="0" vspace="0" hspace="0"></td> </tr> </table> </body> </html>