# Microsoft Fastfile Package Format #

I encountered Fastfile packages in 2001 while trying to hack Falcom's
*Ys Eternal*. The game included a data.ys file that was an unknown
package. After coming up with an extractor, a mysterious FFCREATE.EXE
came out along with all the graphics.

FFCREATE.EXE was a Fastfile creator made by Microsoft for the
DirectX 5.0 SDK. I believe this file was originally distributed as
source, along with a FASTFILE.H include file for accessing Fastfile
packages as a file system.

If you're interested in Microsoft's code, get your hands on an old MSDN disk.

The question new programmers may ask is, why on Earth would you want
to cram all your resources into one file? Simple: I/O lag.

There are four key reasons to use a package file when making a game.
By having a package file with all resource, only one file handle
is needed for the game. This file handle can be left open at all
times, which offers a speed boost on NTFS system which suffer from
a lag in CreateFile() calls due to checking security.

Package files also conserve disk space. Individual files will always
suck up the minimum cluster size on the hard disk, which can waste
10 to 15 percent of your disk space on even a FAT32 disk: on NTFS
it wastes even more.

OS file systems are also slower than the file system of a package file
because they are designed to search, read, write, rename, append
and delete. Games generally only need to be able to read, except for
writing save files.

Lastly, the data can be organized in the order it's called to speed up
the access of frequently used files.

In today's world of 4GHz processors, these may not be common concerns
for developers. However, in the days of DirectX 5.0 the average user
had 90MHz of power under their hood: lag and load times were
serious problems.

## File Format ##

The Fastfile structure is extremely simple, all values are stored in
little endian order:

<pre>File count + 1 [4 bytes, long]
(file loop)
  File offset [4 bytes, long]
  File name [12 bytes, string (DOS 8.3 filename)]
(end loop)
End offset [4 bytes, long]

The data section is nothing but the contents of all files copied
together in the order listed in the header.

## Proof of Concept ##

Below is a short proof of concept that will extract all the contents
of a Fastfile to a series of files:

<pre class="line-numbers"><code class="language-php">$fd = fopen('result.ff', 'rb');
list($junk, $count) = unpack('l*', fread($fd, 4));
$offset = array();
$filename = array();
for($i=0; $i< $count-1; $i++) {
  list($junk, $offset[$i]) = unpack('l*', fread($fd, 4));
  $filename[$i] = rtrim(fread($fd, 13));
list($junk, $offset[$i]) = unpack('l*', fread($fd, 4));
for($i=0; $i<$count-1; $i++) {
  $fo = fopen($filename[$i], 'w');
  fseek($fd, $offset[$i], SEEK_SET);
  fputs($fo, fread($fd, ($offset[($i+1)]-$offset[$i])));

Copyright (c) 2005 Derrick Sobodash. Some Rights Reserved.

This work is licensed under a CC Attribution-ShareAlike 4.0 International
License (http://creativecommons.org/licenses/by-sa/4.0/).