ESOMod:ZOSFT File Format

The ZOSFT files are actually found within DAT files but are important enough for their file format to be described. They are very similar to the MNF Format with a few minor differences.

Overall Format
The overall ZOSFT file is composed of a short fixed size header, three MNF blocks (type 3), a block of filename data followed by a fixed size footer:

     [ Header (0x13 bytes) ]
     [ Block Type 3 ]
     [ Block Type 3 ]
     [ Block Type 3 ]
     [ Filename Data ]
     [ Footer (5 bytes) ]

Note that all data in the ZOSFT is in little endian bit format.

Header
The ZOSFT file header is almost the same as the MNF file header and is 15 (0x0F) bytes in size:

    byte  FileID[5] = "ZOSFT"
    word  Unknown1 = 0x0006
    dword Unknown2 = 0x00000010
    dword Unknown3 = 0x00000000 (eso) or 0x0000000B (game)
    dword RecordCount

The nature of the unknown values is not known. RecordCount appears to be the same as the RecordCount1b and RecordCount23 values in the first block 3 data header.

Block Data
Following the header are MNF data blocks. In both known ZOSFT files there are three type 3 blocks.

:* Block 1-1
::* Much like the first block in MNFs (value of 0x80XXXXXX followed by zero or more dwords of 0x00... or 0xC0...).
::* The number of 0x80XX... values equals the filename count.
:* Block 1-2
::* Has the same number of 8-byte records as there are filenames at the end of the ZOSFT file. 
::* Data is complex and has no obvious pattern.
:* Block 1-3
::* Has the same number of 4-byte records as there are filenames at the end of the file.
::* Appears to be file indexes.
::* game::ZOSFT has values in roughly consecutive order starting at 1 while eso::ZOSFT is more mixed.
:* Block 2-1
::* Same format as Block 1-1 but different content.
::* The number of 0x80XX... values equals the filename count.
:* Block 2-2
::* Identical in content to Block 1-3.
:* Block 2-3
::* Has 16-byte records equal to the number of filenames with the format:
       dword    Index         // Increase numbers starting at 1
       dword    Offset        // Offset to the filename from the beginning of the table
       dword64  ID            // Complex digits, same as found in Block 1-2 in the same order
:* Block 3-1
::* Same format as Block 1-1 but different content.
::* Number of 0x80XX records equals record size of Block 3-2 divided by 2 (or Block 3-3 size divided by 44)
::* Starting in the Thieves Guild update (2.3.5, update 1.9) this block is empty as identified by the three record counts for the section being all 0.
:* Block 3-2
::* Doesn't exist in game::ZOSFT.
::* May have 2-byte records (same number as Block 3-3) but looks like 4-byte. If 4-byte records it looks like an increasing value.
:* Block 3-3
::* Doesn't exist in game::ZOSFT.
::* Has 44-byte records in the format (a bunch of constant data surrounding two dwords that appear to increase roughly consecutively):
      dword    Constant1 = 0x00020302
      dword    Constant2 = 0x0224F614
      dword    Constant3 = 0x00000000
      dword    Unknown1    
      dword    Unknown2                  
      dword    Constant4 = 0x0224F614
      dword    Constant5 = 0x001B7D04
      dword    Constant6 = 0x013EA3EC
      dword    Constant7 = 0x001B8585
      dword    Constant8 = 0xFA3B35C1
      dword    Constant9 = 0x001B8690

Filename Data
Directly following the block data in the ZOSFT is the filename data. It is simply a 4 byte record size followed by a list of NUL terminated strings:

     dword RecordSize
     byte  Data[RecordSize]

Footer
After the filename data is the ZOSFT file footer which ends the file:

    byte Footer[5] = "ZOSFT"


Notes
:* eso.zosft (Patch Jan/2014)
::* File Hash 0xF969BEE8
::* 68642 filenames
::* Block Size 1.1 = 527364  (/4  = 131841) 
::* Block Size 1.2 = 549136  (/8  = 68642) 
::* Block Size 1.3 = 274568  (/4  = 68642)
::* Block Size 2.1 = 527364  (/4  = 131841) 
::* Block Size 2.2 = 274568  (/4  = 68642)
::* Block Size 2.3 = 1098272 (/16 = 68642)
::* Block Size 3.1 = 263684  (/4  = 65921) 2 * 2 * 65921
::* Block Size 3.2 = 137316  (/2  = 68658) 2 * 2 * 3 * 11443
::* Block Size 3.3 = 1510476 (/22 = 68658) 2 * 2 * 3 * 11 * 11443
:* game.zosft (Patch Jan/2014)
::* File Hash 0xF4FD2ECD
::* 2087 filenames
::* Block Size 1.1 = 16484   (/4  = 4121)
::* Block Size 1.2 = 16696   (/8  = 2087)
::* Block Size 1.3 = 8348    (/4  = 2087)
::* Block Size 2.1 = 16484   (/4  = 4121)
::* Block Size 2.2 = 8348    (/4  = 2087)
::* Block Size 2.3 = 33392   (/16 = 2087)
::* Block Size 3.1 = 4124    (/4  = 1031) 2 * 2 * 1031
::* Block Size 3.2 = 0 (doesn't exist)
::* Block Size 3.3 = 0 (doesn't exist)
:* The Feb/2014 beta patch changes the identifiers for the ZOSFT entries. This confirms that there are no fixed IDs but are somehow identified in the data.
::* Game ZOSFT = File Hash 0xA16BBD50 in game0000.dat
::* Eso ZOSFT = File Hash 0x4C99266E in eso0002.dat