One way to reduce the disc space is to compress the data. But compressing works only for the holes, but not for encrypted data. And random access is very difficult for compressed data. The direct support of holes seems to be much better.
So I decided to create the file format
In early 2010 it was clear, that the internal split file support will never be used. It is more practical to search for the continuation file, if the first opened file is to small to hold the complete WDF. The advantage of this external management is, that joining or splitting can be done at any file positions and does not need a change of the file data.
In September 2012 I thought about a new version of WDF without internal split file support. The new format should also support alignment, so that USB loaders are able to use this format like WBFS files. Because of this thoughts, the behaviour of the tools were changed in October 2012 with release v2.10a: The tools ignore the split members for the validation checks.
In January 2014 I decided to complete the plans of
At the same time, I wrote a WDF library class for C++. Third party projects may use this source code library to implement read access of WDF files. Based on this class, I also developed WDF support for the Dolphin emulator.
With beginning of v2.28a (2014-03-01), the tools will support a full featured WDF version 2 with aligning and some other optimizations. With beginning of v2.30a (2014-11-15), WDF version 2 is the default mode if creating a WDF file.
The following table shows the general layout of a WDF file:
General WDF file layout | |||
---|---|---|---|
Size | Name | Description | |
0x38 | header | The file header with a magic and basic information about the WDF file. | |
* | chunk_table | The chunk tables consist of a magic (8 bytes) and a list with the chunk entries. The magic should be used to validate the beginning of the chunk table.
Only |
|
* | padding | It is possible to add padding data here to force an alignment of the data blocks. | |
* | data | The data blocks. The blocks are referenced by the elements of the chunk list. Unused areas are also possible. | |
* | chunk_table | The chunk tables consist of a magic (8 bytes) and a list with the chunk entries. The magic should be used to validate the beginning of the chunk table.
|
File header of WDFv1 (big endian) | ||||
---|---|---|---|---|
Offset | Size | Type | Name | Description |
0x00 | 8 | char[8] | magic | 8 characters to identify a WDF file.
The string is » |
0x08 | 4 | u32 | version | The WDF version. Always 1 for |
0x0c | 4 | u32 | split_file_id | This member were planned for the split file support.
It should help to find the correct continuation files.
The value is a random number for split files.
Because split support was never implemented,
the value is always 0 and ignored on reading.
Since |
0x10 | 4 | u32 | split_file_index | This member were planned for the split file support.
It contains the zero based split index of the file (always 0).
The value is ignored on reading.
Since |
0x14 | 4 | u32 | split_file_total | This member were planned for the split file support.
It contains the total number of split files (always 1).
The value is ignored on reading.
Since |
0x18 | 8 | u64 | image_size | The total size of the unpacked file (virtual image size). |
0x20 | 8 | u64 | data_size | The size of all used data areas (a statistical value). |
0x28 | 4 | u32 | chunk_split_file | This member were planned for the split file support.
It contains the index of the file, that contains the chunk list (always 0).
The value is ignored on reading.
Since |
0x2c | 4 | u32 | chunk_n | Number of elements in the chunk list. |
0x30 | 8 | u64 | chunk_off | File offset of the magic before the chunk list. All offsets are always relative to the beginning of the file. This is also the end-of-data position. |
0x38 | 56 bytes total |
The chunk list is placed at the end of the file. Directly before the chunk list, a magic is inserted with 8 bytes.
Chunk list element of WDFv1 (big endian) | ||||
---|---|---|---|---|
Offset | Size | Type | Name | Description |
0x00 | 4 | u32 | split_file_index | This member were planned for the split file support.
It is ignored and always 0.
It is removed in |
0x04 | 8 | u64 | file_pos | Virtual offset into the unpacked file. |
0x0c | 8 | u64 | data_off | File offset to the related data block. All offsets are always relative to the beginning of the file. |
0x14 | 8 | u64 | block_size | Size of the data block. |
0x1c | 28 bytes total |
File header of WDFv2 (big endian) | ||||
---|---|---|---|---|
Offset | Size | Type | Name | Description |
0x00 | 8 | char[8] | magic | 8 characters to identify a WDF file.
The string is » |
0x08 | 4 | u32 | version | The WDF version. Always 2 for |
0x0c | 4 | u32 | head_size | The size of this WDF header.
For |
0x10 | 4 | u32 | align_factor | If not NULL, it gives an information about the user wanted alignment of the WDF file on creation time. |
0x14 | 4 | u32 | compatible | This version number is planned for future versions of |
0x18 | 8 | u64 | image_size | The total size of the unpacked file (virtual image size). |
0x20 | 8 | u64 | data_size | The size of all used data areas (a statistical value). |
0x28 | 4 | u32 | reserved | Always 0. |
0x2c | 4 | u32 | chunk_n | Number of elements in the chunk list. |
0x30 | 8 | u64 | chunk_off | File offset of the magic before the chunk list. All offsets are always relative to the beginning of the file. This is also the end-of-data position. |
0x38 | 56 bytes total |
The chunk list is placed at the end of the file. Directly before the chunk list, a magic is inserted with 8 bytes.
The only change since
Chunk list element of WDFv2 (big endian) | ||||
---|---|---|---|---|
Offset | Size | Type | Name | Description |
0x00 | 8 | u64 | file_pos | Virtual offset into the unpacked file. |
0x08 | 8 | u64 | data_off | File offset to the related data block. All offsets are always relative to the beginning of the file. |
0x10 | 8 | u64 | block_size | Size of the data block. |
0x18 | 24 bytes total |
The naming scheme is:
Example with 1000 split files and one mandatory digit.
This is also the preferred naming scheme:
image.wdf image.wdf.1 ... image.wdf.9 image.wdf.10 ... image.wdf.99 image.wdf.100 ... image.wdf.999 image.wdf.1000
Same example with 2 mandatory digits:
image.wdf image.wdf.01 ... image.wdf.99 image.wdf.100 ... image.wdf.999 image.wdf.1000
Same example with 3 mandatory digits:
image.wdf image.wdf.001 ... image.wdf.999 image.wdf.1000
Files lib-wdf.cpp and lib-wdf.h are the source code library. Please use only unmodified versions of these files and write a wrapper around to allow easy updates of the library.
Files example-wdf.cpp contains some examples, how to use the 2 library files files.