/shared2/wc24/nwc24dl.bin
One of its primary functions of WiiConnect24 is that various titles can request that it download files over HTTP(S) and store them for titles in NAND -- while the PPC is doing other tasks, or while the console is in standby. This file acts as its download list.
The download system is a joint effort between the running PowerPC title and the KD IOS module. PowerPC titles register entries containing URLs with time information. As long as the entry is enabled, KD will periodically wake up and download content. (It is also possible to download immediately upon request via NWC24iDownloadNowEx.)
Entries are downloaded in order of oldest to newest from the current UTC time. The download frequency (in days) is determined by the dl_freq_days field, but this is typically set to be once every day (0x5a0
, or 1440 minutes). The actual time when entries are downloaded can drift as far as the download interval, which is set to 10 minutes by default.
When entries are downloaded successfully, the If-Modified-Since
header is set to a converted timestamp of the record's last_modified timestamp. The server can then respond with 304 Not Modified, and KD will mark the download as successful.
When a entry is initially written to nwc24dl.bin, it's recommended to immediately invoke NWC24iDownloadNowEx so that KD starts downloading at the intervals specified by the interval fields. Checks for downloads are performed every two minutes. A download interval of one minute can be used to make sure WC24 downloads the content every 2 minutes.
Structure
Header
Start | End | Length | Description |
---|---|---|---|
0x0 | 0x3 | 0x4 | Magic big-endian 0x5763446c ("WcDl"). This magic is never checked past it being set by the System Menu. |
0x4 | 0x7 | 0x4 | Presumably a version number, set to 1 by the System Menu. Similar to the file's magic, it is never checked. |
0x8 | 0x10 | 0x8 | Reserved |
0x10 | 0x12 | 0x2 | The maximum amount of subtask entries, defaulting to 0x20 (or 32). The NWC24 library in both KD and the PowerPC SDK will set this number to 0x20 if it exceeds such. |
0x12 | 0x14 | 0x2 | The amount of reserved entries, always 8. Entries 0 through 7 are typically utilized to download announcements and other first-party contents, such as the Forecast Channel's data. |
0x14 | 0x15 | 0x2 | The maximum entries and records available in this file, always 0x78 (or 120). |
0x16 | 0x7f | 0x6a | Reserved |
0x80 | 0x7ff | 0x780 | An array of 120 records. |
0x800 | 0xf7ff | 0xf000 | An array of 120 entries. |
Record
Every record contains information about requests made on behalf of a record. The index of the entry is equivalent to that of a record.
Start | End | Length | Description |
---|---|---|---|
0x0 | 0x4 | 0x4 | The lower title ID used, set from the corresponding entry. If intended for announcements, the title ID is HAEA. Zero if the record is empty. |
0x4 | 0x7 | 0x4 | A timestamp for when this entry will next be downloaded. |
0x8 | 0xc | 0x4 | A timestamp of the recorded Last-Modified header sent by the server.
|
0xc | 0xd | 0x1 | Record flags, set from the corresponding entry. Values are unknown. |
0xd | 0xf | 0x3 | Padding |
Entry
Start | End | Length | Description |
---|---|---|---|
0x0 | 0x2 | 0x2 | The index of this record. All records present, whether used or not, have an incremental index. The file will fail to parse if it is not incremental. |
0x2 | 0x3 | 0x1 | The entry type of this record. |
0x3 | 0x4 | 0x1 | Record flags. The corresponding record is set to this value upon update. |
0x4 | 0x8 | 0x4 | A bitfield of entry flags. |
0x8 | 0xc | 0x4 | The lower title ID of this entry. |
0xc | 0x14 | 0x8 | The full title ID of this entry. |
0x14 | 0x16 | 0x2 | The group ID for this entry. |
0x16 | 0x18 | 0x2 | Padding. |
0x18 | 0x1a | 0x2 | A signed 16-bit integer holding a max download count, decreased by KD everytime the entry is downloaded. When it reaches 1, the entry is removed from nwc24dl.bin. Values less than 0 are reset to 0. |
0x1a | 0x1c | 0x2 | A count of errors. Set to zero upon a successful download. |
0x1c | 0x1e | 0x2 | The interval this file is downloaded, in minutes. A typical value may be 0x5a0 (1440), or daily.
|
0x1e | 0x20 | 0x2 | Per strings in the Wii Shop Channel, this is a "retry margin". Its value is used when the previous download fails. It is typically larger than the normal interval. |
0x20 | 0x24 | 0x4 | A signed integer holding this entry's WC24 error code. Zero if no error occurred. |
0x24 | 0x25 | 0x1 | A count of the amount this subtask has run. |
0x25 | 0x26 | 0x1 | Unknown. Seemingly a subtask "type". Returns invalid operation if 0. If 1, an operation occurrs against the subtask's bitmask. If 2, 3, or 4, the current timestamp is utilized somehow. If 5, returns success. Otherwise, subtask flags are somehow checked. |
0x26 | 0x27 | 0x1 | A bitfield of subtask flags. |
0x27 | 0x28 | 0x1 | Padding |
0x28 | 0x2c | 0x4 | A bitmask specifying what subtasks are enabled. Only subtasks with set bit numbers can be used. |
0x2c | 0x30 | 0x4 | The download interval from the server. |
0x30 | 0x34 | 0x4 | A timestamp of when this entry was last successfully downloaded. Set to zero when an error occurrs. |
0x34 | 0xb4 | 32*0x4 | An array of 32 timestamps of subtask download times. |
0xb4 | 0x1a0 | 0xec | The download URL of this entry. Note that Nintendo utilizes strlcpy to change this - if updated to be shorter than the previous URL, extraneous bytes can remain. Ensure you read until the null terminator.
|
0x1a0 | 0x1e0 | 0x40 | The filename used when saving to the title's wc24dl.vff. Empty for announcements. |
0x1e0 | 0x1f8 | 0x18 | Padding |
0x1f8 | 0x1fc | 0x4 | Unknown. Appears to be a 32-bit integer, only read. |
0x1fc | 0x1fd | 0x1 | Padding |
0x1fd | 0x1fe | 0x1 | Specifies what index the root CA should be set to. Valid slots are 0, 1, and 2. For more information, see SSL_SETBUILTINROOTCA |
0x1fe | 0x200 | 0x2 | Padding |
Types
Entry Types
Every entry type is a uint8_t.
Value | Description |
---|---|
0x1 | Unknown. Appears to enable subtasks. |
0x2 | Downloads the file to the shared mailbox, wc24recv.mbx. |
0x3 | Downloads content to the title's wc24dl.vff, within its data directory. |
0xff | Denotes an unused entry. |
Entry Flags
Value | Bit | Description |
---|---|---|
0x01 | 1 | Upon download, the client sets X-Wii-Id with the user's 16 digit friend code, prefixed with a w. For example: X-Wii-Id: w1234123412341234
|
0x02 | 2 | Instead of the common KD public RSA key, the key within the title's wc24pubk.mod is utilized. |
0x04 | 3 | The downloaded file is not handled as being in the WC24 container format. The file is additionally not checked for a valid RSA signature. |
0x8 | 4 | Instead of the common KD AES key, the key specified in the title's wc24pubk.mod is utilized. |
0x10 | 5 | During the KD standby loop to check for downloads, this task will be skipped. |
0x80 | 6 | ? |
0x40000000 | 30 | If the entry is within the reserved entries (0 through 7) and X-Wii-Download-Interval is specified, do not error if the interval is above 9900.
|
Subtask Flags
Value | Bit | Description |
---|---|---|
0x01 | 1 | The subtask ID is appended to the downloaded filename. For example, with a name of content.bin and a subtask ID of 21, the filename will be content.bin.21 .
|
0x02 | 2 | The subtask ID is appended to the requested URL. For example, with https://example.com/content.bin and a subtask ID of 21, the URL requested will be https://example.com/content.bin.21 .
|
0x200 | 9 | Unknown. Involves the server's interval. |
0x400 | 10 | Appears to disable the subtask. |
Note that if wc24pubk.mod does not exist within the title's data directory upon time of download, the task is deleted.
The format of the WC24 content header is available here.
Timestamp
All timestamps are in minutes from the standard UNIX epoch. To obtain a typical UNIX timestamp in seconds, multiply the timestamp by 60.
Note that a timestamp must not exceed 0x7C55817F in value. For some values internally, time is based off of the year 1900. To obtain a UNIX timestamp with 1970, Nintendo adds 0x83aa7e80 to the value. As 0x83aa7e80 + 0x7C55817F is 0xFFFFFFFF - overflowing an unsigned 32-bit integer - anything exceeding February 07, 2036 at 06:28:15 UTC will fail.
Exceeding this value will lead to unpredictable results and error codes, such as the Last-Modified
header being set to (failed to convert)
.
See also
#define WC24_SUBTASK_FLAGS_ENABLE BIT(0)//Use subTasks
typedef struct _nwc24dl_header
{
u32 magic;//"WcDl" 0x5763446c
u32 unk4;//0x1
u32 filler[2];
u16 unk10;//0x20
u16 unk12;//0x8
u16 max_entries;//Max num of entries/records that can be stored in nwc24dl.bin, always 0x78.
u8 reserved[0x6a];
} __attribute__((packed)) nwc24dl_header;
typedef struct _nwc24dl_record
{
u32 ID;//Titleid low, except for sysmenu. Zero for empty.
u32 next_dl;//Timestamp for next time to download.
u32 last_modified;//Last dl timestamp. Zero when download failed, with error_code less than zero, except for error [[WiiConnect24#WC24 Errors|107305]].(HTTP 304) This timestamp is the last dl timestamp for when the download succeeded without any error, with HTTP 200 OK.
u8 record_flags;//?
u8 filler[3];
} __attribute__((packed)) nwc24dl_record;
typedef struct _nwc24dl_entry
{
u16 index;//Zero-based.
u8 type;
u8 record_flags; //?
u32 flags; // 0x01 = SEND_USERINFO, 0x02 = USE_MYPUBLICKEY, 0x04 = RAW_CONTENT, 0x08 = USE_MYSECRETKEY, 0x40 = GROUP_WRITABLE
u32 ID;//Titleid low, except for sysmenu.
u64 titleid;
u16 group_id;
u16 unk16;
s16 cnt_nextdl;//Number of downloads for this entry. This is decreased by KD everytime it downloads the entry. When it reaches 0, the entry is removed from the nwc24dl.bin file. Values < 0 are reset to 0.
u16 total_errors;//Zero for no error for the last dl. Unknown for subTasks.
u16 dl_freq_perday; // Download frequency in minutes
u16 dl_freq_on_error; // Download frequency in minutes when the last download failed (usually larger)
s32 error_code;//Zero for no error, negative WC24 error code otherwise.
u8 unk24SubTask;
u8 unk25SubTask;//Must be non zero to use subTasks?
u8 subTaskFlags;
u8 unk27SubTask;
u32 subTaskBitmask;//Bitmask subTask ID enable. Only subTasks with IDs/numbers with matching set bits are used.
u16 unk2cSubTask;
u16 unk2eSubTask;//0x5a0 usually for entries with subTasks? Might be related to dl time?
u32 dl_timestamp;//Last dl timestamp. Zero when download failed, with error_code less than zero.
u32 subTaskTimestamps[32];//Timestamps of last dl time for each subTask?
char url[0xec];
char filename[0x40];//Filename inside wc24dl.vff, without a leading root directory slash. This path can probably can be a path with sub-directories.
u8 unk1e0[0x1d];
u8 NHTTP_RootCA;//Usually zero.
u16 unk1fe;
} __attribute__((packed)) nwc24dl_entry;