Difference between revisions of "VFF"

From WiiBrew
Jump to: navigation, search
(Created VFF file format page. Some header text is from cdb.vff page.)
 
(Add link to some old code I had lying around to dump VFF files)
 
(5 intermediate revisions by 3 users not shown)
Line 17: Line 17:
 
| 2
 
| 2
 
| feff
 
| feff
| Byte-order-marker?
+
| Byte-order-marker? (magic value, never checked by code)
 
|-
 
|-
 
| 6
 
| 6
 
| 2
 
| 2
 
| 0100
 
| 0100
| ? (2's complement of previous field ?)
+
| (length field? never checked by code)
 
|-
 
|-
 
| 8
 
| 8
Line 40: Line 40:
 
|}
 
|}
  
Following the header is two FATs, which are FAT16. Each FAT is the size of a sector. The format of the FAT is not regular FAT16, there's unknown flags and values, so it's currently not possible to process cluster chains. Following the FATs is the root [http://en.wikipedia.org/wiki/File_Allocation_Table#Directory_table directory] cluster, 8 sectors long. Following the root cluster is the data "clusters". The data "clusters" have one sector per "cluster". The size of a sector is determined by the following algorithm:
+
Following the header is two FATs, which are FAT12/FAT16 (depending on total volume size). Each FAT size is determined by the below algo. Following the FATs is the root [http://en.wikipedia.org/wiki/File_Allocation_Table#Directory_table directory] cluster, 0x1000 bytes long. Following the root cluster is the data "clusters". The data "clusters" have are 0x200 bytes long each. The size of the FAT is determined by the following algorithm:
u32 base = (filesize / 0x200) - 8;//This algo doesn't work exactly for files over 1MB. To get the correct size, try multiplying the result of this algo with various values.
+
<source lang="c">
u32 sectorsz = base;
+
#define ALIGN_FORWARD(x,align) \
if(base % 0x200)//Should always be executed.
+
        ((typeof(x))((((u32)(x)) + (align) - 1) & (~((align)-1))))
 +
#define CLUSTER_SIZE 0x200
 +
 
 +
u32 WC24_GetVFF_FATSize(u32 filesize)
 
  {
 
  {
      if(base<0x200)
+
    u32 num_clusters = filesize / CLUSTER_SIZE;
      {
+
    u32 fat_bits = 32;
          sectorsz+= (base % 0x200);
+
    if (num_clusters < 0xFFF5) fat_bits = 16;
      }
+
    if (num_clusters < 0xFF5) fat_bits = 12;
      else
+
 
      {
+
    return ALIGN_FORWARD(num_clusters * fat_bits / 8, CLUSTER_SIZE);
          sectorsz++;
 
      }
 
 
  }
 
  }
 +
</source>
 +
 +
Trivial vff filesystem dumper (from marcan's old code stash): [https://mrcn.st/t/vffdump.py]
 +
 +
[[Category:File formats]]

Latest revision as of 11:03, 30 July 2015

VFF is a "virtual FAT filesystem", which is used as a container for primarily WC24 downloaded content, as well as E-Mail storage.

Header

Start Length Typical value Description
0 4 'VFF ' 4-byte magic
4 2 feff Byte-order-marker? (magic value, never checked by code)
6 2 0100 (length field? never checked by code)
8 4 01400000 Total file size
12 2 0020 Size of header
14 18 zeroes padding

Following the header is two FATs, which are FAT12/FAT16 (depending on total volume size). Each FAT size is determined by the below algo. Following the FATs is the root directory cluster, 0x1000 bytes long. Following the root cluster is the data "clusters". The data "clusters" have are 0x200 bytes long each. The size of the FAT is determined by the following algorithm:

#define ALIGN_FORWARD(x,align) \
        ((typeof(x))((((u32)(x)) + (align) - 1) & (~((align)-1))))
#define CLUSTER_SIZE 0x200

u32 WC24_GetVFF_FATSize(u32 filesize)
 {
    u32 num_clusters = filesize / CLUSTER_SIZE;
    u32 fat_bits = 32;
    if (num_clusters < 0xFFF5) fat_bits = 16;
    if (num_clusters < 0xFF5)  fat_bits = 12;

    return ALIGN_FORWARD(num_clusters * fat_bits / 8, CLUSTER_SIZE);
 }

Trivial vff filesystem dumper (from marcan's old code stash): [1]