1 
2 /***************************************************************************
3  *                    __            __ _ ___________                       *
4  *                    \ \          / /| |____   ____|                      *
5  *                     \ \        / / | |    | |                           *
6  *                      \ \  /\  / /  | |    | |                           *
7  *                       \ \/  \/ /   | |    | |                           *
8  *                        \  /\  /    | |    | |                           *
9  *                         \/  \/     |_|    |_|                           *
10  *                                                                         *
11  *                           Wiimms ISO Tools                              *
12  *                         http://wit.wiimm.de/                            *
13  *                                                                         *
14  ***************************************************************************
15  *                                                                         *
16  *   This file is part of the WIT project.                                 *
17  *   Visit http://wit.wiimm.de/ for project details and sources.           *
18  *                                                                         *
19  *   Copyright (c) 2009-2013 by Dirk Clemens <wiimm@wiimm.de>              *
20  *                                                                         *
21  ***************************************************************************
22  *                                                                         *
23  *   This program is free software; you can redistribute it and/or modify  *
24  *   it under the terms of the GNU General Public License as published by  *
25  *   the Free Software Foundation; either version 2 of the License, or     *
26  *   (at your option) any later version.                                   *
27  *                                                                         *
28  *   This program is distributed in the hope that it will be useful,       *
29  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
30  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
31  *   GNU General Public License for more details.                          *
32  *                                                                         *
33  *   See file gpl-2.0.txt or http://www.gnu.org/licenses/gpl-2.0.txt       *
34  *                                                                         *
35  ***************************************************************************/
36 
37 #ifndef FILE_FORMATS_H
38 #define FILE_FORMATS_H
39 
40 // some info urls:
41 //  - http://wiibrew.org/wiki/Wii_Disc
42 //  - http://wiibrew.org/wiki/Ticket
43 //  - http://wiibrew.org/wiki/Tmd_file_structure
44 //  - http://hitmen.c02.at/files/yagcd/yagcd/chap13.html -> GameCube
45 
46 //
47 ///////////////////////////////////////////////////////////////////////////////
48 ///////////////			    setup			///////////////
49 ///////////////////////////////////////////////////////////////////////////////
50 
51 #include "tools.h"
52 
53 int validate_file_format_sizes ( int trace_sizes );
54 
55 //
56 ///////////////////////////////////////////////////////////////////////////////
57 ///////////////			  constants			///////////////
58 ///////////////////////////////////////////////////////////////////////////////
59 
60 enum // some constants
61 {
62     HD_SECTOR_SIZE		=  0x200, // classic HD sector size
63     HD_BLOCK_SIZE		= 0x1000, // good HD block value
64 
65     WII_SECTOR_SIZE_SHIFT	= 15,
66     WII_SECTOR_SIZE		= 1 << WII_SECTOR_SIZE_SHIFT,
67     WII_SECTOR_SIZE4		= WII_SECTOR_SIZE >> 2,
68     WII_SECTORS_PER_MIB		= 1024*1024/WII_SECTOR_SIZE,
69 
70     WII_SECTOR_IV_OFF		= 0x3d0,
71     WII_SECTOR_HASH_SIZE	= 0x400,
72     WII_SECTOR_HASH_SIZE4	= WII_SECTOR_HASH_SIZE >> 2,
73     WII_SECTOR_DATA_SIZE	= WII_SECTOR_SIZE - WII_SECTOR_HASH_SIZE,
74     WII_SECTOR_DATA_SIZE4	= WII_SECTOR_DATA_SIZE >> 2,
75 
76     WII_HASH_SIZE		= 20,
77     WII_H0_DATA_SIZE		= 0x400,
78     WII_H3_SIZE			= 0x18000,
79     WII_N_ELEMENTS_H0		= WII_SECTOR_DATA_SIZE/WII_H0_DATA_SIZE,
80     WII_N_ELEMENTS_H1		= 8,
81     WII_N_ELEMENTS_H2		= 8,
82     WII_N_ELEMENTS_H3		= WII_H3_SIZE/WII_HASH_SIZE,
83     WII_MAX_PART_SECTORS	= WII_N_ELEMENTS_H1
84 				* WII_N_ELEMENTS_H2
85 				* WII_N_ELEMENTS_H3,
86 
87     WII_GROUP_SECTORS		= WII_N_ELEMENTS_H1 * WII_N_ELEMENTS_H2,
88     WII_GROUP_SIZE		= WII_GROUP_SECTORS * WII_SECTOR_SIZE,
89     WII_GROUP_SIZE4		= WII_GROUP_SIZE >> 2,
90     WII_GROUP_HASH_SIZE		= WII_GROUP_SECTORS * WII_SECTOR_HASH_SIZE,
91     WII_GROUP_HASH_SIZE4	= WII_GROUP_HASH_SIZE >> 2,
92     WII_GROUP_DATA_SIZE		= WII_GROUP_SECTORS * WII_SECTOR_DATA_SIZE,
93     WII_GROUP_DATA_SIZE4	= WII_GROUP_DATA_SIZE >> 2,
94 
95     WII_N_HASH_SECTOR		= WII_N_ELEMENTS_H0
96 				+ WII_N_ELEMENTS_H1
97 				+ WII_N_ELEMENTS_H2,
98     WII_N_HASH_GROUP		= WII_N_HASH_SECTOR * WII_GROUP_SECTORS,
99 
100     WII_CERT_ALIGN		= 0x40,		// alignment in Wii certificates
101 
102     WII_TICKET_SIZE		= 0x2a4,
103     WII_TICKET_SIG_OFF		= 0x140, // do SHA1 up to end of ticket
104     WII_TICKET_KEY_OFF		= 0x1bf,
105     WII_TICKET_IV_OFF		= 0x1dc,
106     WII_TICKET_ID4_OFF		= 0x1e0, // offset of ID4
107     WII_TICKET_BRUTE_FORCE_OFF	= 0x24c, // this u32 will be iterated
108 
109     WII_TMD_GOOD_SIZE		= 0x208, // tmd with 1 content (usual)
110     WII_TMD_SIG_OFF		= 0x140, // do SHA1 up to end of tmd
111     WII_TMD_ID4_OFF		= 0x190, // offset of ID4
112     WII_TMD_BRUTE_FORCE_OFF	= 0x19a, // this u32 will be iterated
113     WII_PARTITION_BIN_SIZE	= 0x20000,
114 
115     WII_SECTORS_SINGLE_LAYER	= 143432,
116     WII_SECTORS_DOUBLE_LAYER	= 2 * WII_SECTORS_SINGLE_LAYER,
117     WII_MAX_SECTORS		= WII_SECTORS_DOUBLE_LAYER,
118     WII_MAX_U32_SECTORS		= 0x40000000/WII_SECTOR_SIZE4,
119 
120     WII_MAGIC			= 0x5d1c9ea3,
121     WII_MAGIC_DELETED		= 0x2a44454c,
122     WII_MAGIC_OFF		=       0x18,
123     WII_MAGIC_LEN		=       0x04,
124 
125     WII_MAGIC2			= 0xc3f81a8e,
126     WII_MAGIC2_OFF		=    0x4fffc,
127     WII_MAGIC2_LEN		=       0x04,
128 
129     WII_TITLE_OFF		= 0x20,
130     WII_TITLE_SIZE		= 0x40,
131 
132     WII_KEY_SIZE		=   16,
133     WII_FILE_PATH_SIZE		= 1000,
134 
135     WII_MAX_PTAB		=       4,	// maximal partition tables
136     WII_PTAB_REF_OFF		= 0x40000,	// disc offset of partition table ref
137     WII_PTAB_SECTOR		= WII_PTAB_REF_OFF / WII_SECTOR_SIZE,
138 						// sector index of partition table
139     WII_MAX_PTAB_SIZE		=   0x400,	// maximal size of all ptabs + entries
140     WII_MAX_PARTITIONS		= WII_MAX_PTAB_SIZE / 8 - WII_MAX_PTAB,
141 						// maximal supported partitions
142 
143     WII_REGION_OFF		= 0x4e000,
144     WII_REGION_SIZE		=    0x20,
145 
146     WII_BOOT_OFF		=      0,
147     WII_BI2_OFF			=  0x440,
148     WII_APL_OFF			= 0x2440,
149     WII_BOOT_SIZE		= WII_BI2_OFF - WII_BOOT_OFF,
150     WII_BI2_SIZE		= WII_APL_OFF - WII_BI2_OFF,
151     WII_BI2_REGION_OFF		=   0x18,
152 
153     WII_PART_OFF		=   0x50000,
154     WII_GOOD_DATA_PART_OFF	= 0xf800000,
155 
156     GC_MAGIC			= 0xc2339f3d,
157     GC_MAGIC_OFF		=       0x1c,
158     GC_MAGIC_LEN		=       0x04,
159     GC_DISC_SIZE		= 1459978240,	// standard GameCube disc size
160 
161     GC_MULTIBOOT_PTAB_OFF	=  0x40,
162     GC_MULTIBOOT_PTAB_SIZE	= 0x100 - GC_MULTIBOOT_PTAB_OFF,
163     GC_MULTIBOOT_MAX_PART	= GC_MULTIBOOT_PTAB_SIZE/4,
164     GC_GOOD_PART_ALIGN		= 0x20000,	// alignment (= min off) of GC partitions
165 
166     DOL_N_TEXT_SECTIONS		=     7,
167     DOL_N_DATA_SECTIONS		=    11,
168     DOL_N_SECTIONS		= DOL_N_TEXT_SECTIONS + DOL_N_DATA_SECTIONS,
169     DOL_HEADER_SIZE		= 0x100,
170 
171     WBFS_MAX_SECTORS		= 0x10000,  // max number of sectors
172     WBFS_MIN_SECTOR_SHIFT	=  6,	    // needed for wbfs_calc_size_shift()
173     WBFS_MAX_SECTOR_SHIFT	= 11,	    // needed for wbfs_calc_size_shift()
174     WBFS_MIN_SECTOR_SIZE	= 1 << WBFS_MIN_SECTOR_SHIFT + WII_SECTOR_SIZE_SHIFT,
175     WBFS_MAX_SECTOR_SIZE	= 1 << WBFS_MAX_SECTOR_SHIFT + WII_SECTOR_SIZE_SHIFT,
176 
177     WBFS_INODE_INFO_VERSION	=    1,
178     WBFS_INODE_INFO_HEAD_SIZE	=   12,
179     WBFS_INODE_INFO_CMP_SIZE	=   10,
180     WBFS_INODE_INFO_OFF		= 0x80,
181     WBFS_INODE_INFO_SIZE	= 0x100 - WBFS_INODE_INFO_OFF,
182 
183     LOADER_MAX_FRAGMENTS	= 20000,
184 };
185 
186 #define WII_MAX_DISC_SIZE ((u64)WII_MAX_SECTORS*(u64)WII_SECTOR_SIZE)
187 
188 //
189 ///////////////////////////////////////////////////////////////////////////////
190 ///////////////			enum wd_disc_type_t		///////////////
191 ///////////////////////////////////////////////////////////////////////////////
192 
193 typedef enum wd_disc_type_t
194 {
195     //**********************************************************************
196     //***  never change this values, because they are used in archives!  ***
197     //**********************************************************************
198 
199     WD_DT_UNKNOWN	= 0,	// unknown disc type
200     WD_DT_GAMECUBE,		// GameCube disc
201     WD_DT_WII,			// Wii disc
202 
203     WD_DT__N			// number of defined disc types
204 
205 } wd_disc_type_t;
206 
207 //
208 ///////////////////////////////////////////////////////////////////////////////
209 ///////////////			enum wd_disc_attrib_t		///////////////
210 ///////////////////////////////////////////////////////////////////////////////
211 
212 typedef enum wd_disc_attrib_t
213 {
214     //--- disc type attributes, detected by get_header_disc_type()
215 
216     WD_DA_GAMECUBE	= 1 << WD_DT_GAMECUBE,
217     WD_DA_WII		= 1 << WD_DT_WII,
218 
219 
220     //--- real attributes, detected by get_header_disc_type()
221 
222     WD_DA_GC_MULTIBOOT	= 0x0100,	// gamecube multiboot disc
223     WD_DA_GC_DVD9	= 0x0200,	// gc-mb disc with DVD9 part-tab
224 
225 
226     //--- more real attributes
227 
228     WD_DA_GC_START_PART	= 0x0400,	// gc-mb disc with valid start partition
229 
230 } wd_disc_attrib_t;
231 
232 //
233 ///////////////////////////////////////////////////////////////////////////////
234 ///////////////			enum wd_compression_t		///////////////
235 ///////////////////////////////////////////////////////////////////////////////
236 
237 typedef enum wd_compression_t
238 {
239     //**********************************************************************
240     //***  never change this values, because they are used in archives!  ***
241     //**********************************************************************
242 
243     WD_COMPR_NONE	= 0,	// data is not compressed
244     WD_COMPR_PURGE,		// a WDF like compression: manage holes
245 
246     WD_COMPR_BZIP2,		// use BZIP2 compression
247     WD_COMPR_LZMA,		// use LZMA compression
248     WD_COMPR_LZMA2,		// use LZMA2 compression
249 
250     WD_COMPR__N,		// number of compressions
251 
252     WD_COMPR__FIRST_REAL	= WD_COMPR_BZIP2,	// first real compression
253  #ifdef NO_BZIP2
254     WD_COMPR__FAST		= WD_COMPR_LZMA,	// a fast compression
255  #else
256     WD_COMPR__FAST		= WD_COMPR_BZIP2,	// a fast compression
257  #endif
258     WD_COMPR__GOOD		= WD_COMPR_LZMA,	// a good compression
259     WD_COMPR__BEST		= WD_COMPR_LZMA,	// the best compression
260     WD_COMPR__DEFAULT		= WD_COMPR_LZMA,	// the default compression
261 
262 } wd_compression_t;
263 
264 //-----------------------------------------------------------------------------
265 
266 ccp wd_get_compression_name
267 (
268     wd_compression_t	compr,		// compression method
269     ccp			invalid_result	// return value if 'compr' is invalid
270 );
271 
272 ccp wd_print_compression
273 (
274     char		* buf,		// result buffer
275 					// If NULL, a local circulary static buffer is used
276     size_t		buf_size,	// size of 'buf', ignored if buf==NULL
277     wd_compression_t	compr_method,	// compression method
278     int			compr_level,	// compression level
279     u32			chunk_size,	// compression chunk size, multiple of MiB
280     int			mode		// 1=number, 2=name, 3=number and name
281 );
282 
283 //
284 ///////////////////////////////////////////////////////////////////////////////
285 ///////////////			struct dol_header_t		///////////////
286 ///////////////////////////////////////////////////////////////////////////////
287 
288 typedef struct dol_header_t
289 {
290     /* 0x00 */	u32 sect_off [DOL_N_SECTIONS];	// file offset
291     /* 0x48 */	u32 sect_addr[DOL_N_SECTIONS];	// virtual address
292     /* 0x90 */	u32 sect_size[DOL_N_SECTIONS];	// section size
293     /* 0xd8 */	u32 bss_addr;
294     /* 0xdc */	u32 bss_size;
295     /* 0xe0 */	u32 entry_addr;
296     /* 0xe4 */	u8  padding[DOL_HEADER_SIZE-0xe4];
297 }
298 __attribute__ ((packed)) dol_header_t;
299 
300 void ntoh_dol_header ( dol_header_t * dest, const dol_header_t * src );
301 void hton_dol_header ( dol_header_t * dest, const dol_header_t * src );
302 
303 //-----------------------------------------------------------------------------
304 
305 typedef struct dol_record_t
306 {
307     u32			addr;		// virtual address of data
308     u32			size;		// size of data
309     u32			xsize;		// extended size
310     u32			delta;		// file_offset := 'addr' - 'delta'
311     char		name[4];	// section name
312 }
313 dol_record_t;
314 
315 uint calc_dol_records
316 (
317     dol_record_t	*rec,		// pointer to at least DOL_N_SECTIONS records
318     bool		term_null,	// true: add a NULL record at end of list
319     const dol_header_t	*dol_head	// source DOL header
320 );
321 
322 const dol_record_t * search_dol_record
323 (
324     dol_record_t	*rec,		// pointer to at least records
325     uint		n_rec,		// number of records, set it to DOL_N_SECTIONS
326 					//   if record lsit is NULL termianted
327     u32			addr,		// address to search
328     u32			size		// size of object, if NULL, ignore it
329 );
330 
331 //
332 ///////////////////////////////////////////////////////////////////////////////
333 ///////////////		    struct wbfs_inode_info_t		///////////////
334 ///////////////////////////////////////////////////////////////////////////////
335 
336 typedef struct wbfs_inode_info_t
337 {
338 	// A complete copy of the first WBFS_INODE_INFO_HEAD_SIZE (12) bytes
339 	// of the WBFS header. The first WBFS_INODE_INFO_CMP_SIZE (10)
340 	// bytes can be used to validate the existence of this info block.
341 	// They are also good for recovery.
342 
343 	be32_t magic;		// the magic (char*)"WBFS"
344 	be32_t n_hd_sec;	// total number of hd_sec in this partition
345 	u8  hd_sec_sz_s;	// sector size in this partition
346 	u8  wbfs_sec_sz_s;	// size of a wbfs sec
347 
348 	u8  wbfs_version;	// informative version number
349 	u8  head_padding;
350 
351 	// The version number of this data structure.
352 	// I may be important for future extensions
353 
354 	be32_t info_version;	// == WBFS_INODE_INFO_VERSION
355 
356 	// 64 bit time stamps: They are only informative but nice to have.
357 	//  - itime is ths disc inserting time.
358 	//    If 2 discs uses the same wbfs block a repair function knows
359 	//    which one disc are newer and which is definitly bad.
360 	//  - mtime is a copy of the mtime of the source file.
361 	//    It is also changed if the the ISO-header is modified (renamed).
362 	//    While extrating the mtime of dest file is set by this mtime.
363 	//  - ctime is updated if adding, renaming.
364 	//  - atime can be updated by usb loaders when loading the disc.
365 	//  - dtime is only set for deleted games.
366 
367 	be64_t itime;		// the disc insertion time
368 	be64_t mtime;		// the last modification time (copied from source)
369 	be64_t ctime;		// the last status changed time
370 	be64_t atime;		// the last access time
371 	be64_t dtime;		// the deletion time
372 
373 	// there is enough space for more information like a game load counter
374 	// or other statistics and game settings. This infos can be share across
375 	// usb loaders.
376 
377 	// EXAMPLES:
378 	//	be32_t	load_count;
379 	//	u8	favorite
380 	//	u8	ios
381 
382 	// padding up to WBFS_INODE_INFO_SIZE bytes, always filled with zeros
383 
384 	u8 padding[ WBFS_INODE_INFO_SIZE - WBFS_INODE_INFO_HEAD_SIZE
385 			- 0 /* num of  8 bit parameters */ * sizeof(u8)
386 			- 0 /* num of 16 bit parameters */ * sizeof(be16_t)
387 			- 1 /* num of 32 bit parameters */ * sizeof(be32_t)
388 			- 5 /* num of 64 bit parameters */ * sizeof(be64_t) ];
389 
390 }
391 __attribute__ ((packed)) wbfs_inode_info_t;
392 
393 void ntoh_inode_info ( wbfs_inode_info_t * dest, const wbfs_inode_info_t * src );
394 void hton_inode_info ( wbfs_inode_info_t * dest, const wbfs_inode_info_t * src );
395 
396 //
397 ///////////////////////////////////////////////////////////////////////////////
398 ///////////////			struct wd_header_128_t		///////////////
399 ///////////////////////////////////////////////////////////////////////////////
400 
401 typedef struct wd_header_128_t
402 {
403 	// -> http://www.wiibrew.org/wiki/Wiidisc#Header
404 
405   /* 0x00 */	char	disc_id;
406   /* 0x01 */	char	game_code[2];
407   /* 0x03 */	char	region_code;
408   /* 0x04 */	char	marker_code[2];
409 
410   /* 0x06 */	u8	disc_number;
411   /* 0x07 */	u8	disc_version;
412 
413   /* 0x08 */	u8	audio_streaming;
414   /* 0x09 */	u8	streaming_buffer_size;
415 
416   /* 0x0a */	u8	unknown1[0x0e];
417   /* 0x18 */	u32	wii_magic;		// off=WII_MAGIC_OFF, val=WII_MAGIC
418   /* 0x1c */	u32	gc_magic;		// off=GC_MAGIC_OFF, val=GC_MAGIC
419 
420   /* 0x20 */	char	disc_title[WII_TITLE_SIZE];	// off=WII_TITLE_OFF
421 
422   /* 0x60 */	u8	diable_hash;
423   /* 0x61 */	u8	diable_encryption;
424 
425   /* 0x62 */	u8	padding[0x1e];
426 
427 } __attribute__ ((packed)) wd_header_128_t;
428 
429 //-----------------------------------------------------------------------------
430 
431 void header_128_setup
432 (
433     wd_header_128_t	* dhead,	// valid pointer
434     const void		* id6,		// NULL or pointer to ID
435     ccp			disc_title,	// NULL or pointer to disc title (truncated)
436     bool		is_gc		// true: GameCube setup
437 );
438 
439 //-----------------------------------------------------------------------------
440 
441 wd_disc_type_t get_header_128_disc_type
442 (
443     wd_header_128_t	* dhead,	// valid pointer
444     wd_disc_attrib_t	* attrib	// not NULL: store disc attributes
445 );
446 
447 //
448 ///////////////////////////////////////////////////////////////////////////////
449 ///////////////			struct wd_header_t		///////////////
450 ///////////////////////////////////////////////////////////////////////////////
451 
452 typedef struct wd_header_t
453 {
454 	// -> http://www.wiibrew.org/wiki/Wiidisc#Header
455 
456   /* 0x00 */	char	disc_id;
457   /* 0x01 */	char	game_code[2];
458   /* 0x03 */	char	region_code;
459   /* 0x04 */	char	marker_code[2];
460 
461   /* 0x06 */	u8	disc_number;
462   /* 0x07 */	u8	disc_version;
463 
464   /* 0x08 */	u8	audio_streaming;
465   /* 0x09 */	u8	streaming_buffer_size;
466 
467   /* 0x0a */	u8	unknown1[0x0e];
468   /* 0x18 */	u32	wii_magic;		// off=WII_MAGIC_OFF, val=WII_MAGIC
469   /* 0x1c */	u32	gc_magic;		// off=GC_MAGIC_OFF, val=GC_MAGIC
470 
471   /* 0x20 */	char	disc_title[WII_TITLE_SIZE];	// off=WII_TITLE_OFF
472 
473   /* 0x60 */	u8	diable_hash;
474   /* 0x61 */	u8	diable_encryption;
475 
476   /* 0x62 */	u8	padding[0x1e];
477 
478   /* 0x80 */	wbfs_inode_info_t iinfo;		// off=WBFS_INODE_INFO_OFF
479 
480 } __attribute__ ((packed)) wd_header_t;
481 
482 //-----------------------------------------------------------------------------
483 
484 void header_setup
485 (
486     wd_header_t		* dhead,	// valid pointer
487     const void		* id6,		// NULL or pointer to ID
488     ccp			disc_title,	// NULL or pointer to disc title (truncated)
489     bool		is_gc		// true: GameCube setup
490 );
491 
492 //-----------------------------------------------------------------------------
493 
494 wd_disc_type_t get_header_disc_type
495 (
496     wd_header_t		* dhead,	// valid pointer
497     wd_disc_attrib_t	* attrib	// not NULL: store disc attributes
498 );
499 
500 //
501 ///////////////////////////////////////////////////////////////////////////////
502 ///////////////			struct wd_boot_t		///////////////
503 ///////////////////////////////////////////////////////////////////////////////
504 
505 typedef struct wd_boot_t
506 {
507   /*     0 */	wd_header_t	dhead;
508   /* 0x100 */	u8		unknown1[0x420-sizeof(wd_header_t)];
509   /* 0x420 */	u32		dol_off4;
510   /* 0x424 */	u32		fst_off4;
511   /* 0x428 */	u32		fst_size4;
512   /* 0x42c */	u32		max_fst_size4;  // >= fst_size4 (max of multi discs)
513   /* 0x430 */	u8		unknown2[WII_BOOT_SIZE-0x430];
514 }
515 __attribute__ ((packed)) wd_boot_t;
516 
517 void ntoh_boot ( wd_boot_t * dest, const wd_boot_t * src );
518 void hton_boot ( wd_boot_t * dest, const wd_boot_t * src );
519 
520 //
521 ///////////////////////////////////////////////////////////////////////////////
522 ///////////////			enum wd_age_rating_t		///////////////
523 ///////////////////////////////////////////////////////////////////////////////
524 
525 typedef enum wd_age_rating_t
526 {
527 	WD_AGE_JAPAN,
528 	WD_AGE_USA,
529 	WD_AGE_UNKNOWN,
530 	WD_AGE_EUROPE1,
531 	WD_AGE_EUROPE2,
532 	WD_AGE_EUROPE3,
533 	WD_AGE_EUROPE4,
534 	WD_AGE_EUROPE5,
535 	WD_AGE_EUROPE6,
536 	WD_AGE_KOREA,
537 
538 	WD_AGE__N
539 
540 } wd_age_rating_t;
541 
542 //-----------------------------------------------------------------------------
543 
544 ccp wd_print_age_rating
545 (
546     char		* buf,		// result buffer
547 					// If NULL, a local circulary static buffer is used
548     size_t		buf_size,	// size of 'buf', ignored if buf==NULL
549     u8			* age_rating	// valid buffer of 'WD_AGE__N' bytes
550 );
551 
552 //
553 ///////////////////////////////////////////////////////////////////////////////
554 ///////////////			struct wd_region_t		///////////////
555 ///////////////////////////////////////////////////////////////////////////////
556 
557 typedef struct wd_region_t
558 {
559   /*    0 */	u32	region;
560   /* 0x04 */	u8	padding1[12];
561   /* 0x10 */	u8	age_rating[WD_AGE__N];
562 		u8	padding2[0x10-WD_AGE__N];
563 }
564 __attribute__ ((packed)) wd_region_t;
565 
566 //
567 ///////////////////////////////////////////////////////////////////////////////
568 ///////////////		    struct wd_ptab_info_t		///////////////
569 ///////////////////////////////////////////////////////////////////////////////
570 
571 typedef struct wd_ptab_info_t
572 {
573 	u32 n_part;	// number of partitions in this table
574 	u32 off4;	// offset/4 of partition table relative to disc start
575 }
576 __attribute__ ((packed)) wd_ptab_info_t;
577 
578 //
579 ///////////////////////////////////////////////////////////////////////////////
580 ///////////////		    struct wd_ptab_entry_t		///////////////
581 ///////////////////////////////////////////////////////////////////////////////
582 
583 typedef struct wd_ptab_entry_t
584 {
585 	u32 off4;	// offset/4 of partition relative to disc start
586 	u32 ptype;	// partitions type
587 }
588 __attribute__ ((packed)) wd_ptab_entry_t;
589 
590 //
591 ///////////////////////////////////////////////////////////////////////////////
592 ///////////////			struct wd_ptab_t		///////////////
593 ///////////////////////////////////////////////////////////////////////////////
594 
595 typedef struct wd_ptab_t // example for a good partition table
596 {
597   /*    0 */	wd_ptab_info_t  info[WII_MAX_PTAB];
598   /* 0x20 */	wd_ptab_entry_t	entry[WII_MAX_PARTITIONS];
599 }
600 __attribute__ ((packed)) wd_ptab_t;
601 
602 //
603 ///////////////////////////////////////////////////////////////////////////////
604 ///////////////			struct wd_ticket_t		///////////////
605 ///////////////////////////////////////////////////////////////////////////////
606 
607 typedef struct wd_ticket_t
608 {
609   // --> http://wiibrew.org/wiki/Ticket
610 
611   /* 0x000 */	u32 sig_type;		// signature type (always 0x10001 for RSA-2048)
612   /* 0x004 */	u8  sig[0x100];		// signature by a certificate's key
613   /* 0x104 */	u8  sig_padding[0x3c];	// always 0
614 
615   // the signature calculations starts here (WII_TICKET_SIG_OFF)
616 
617   /* 0x140 */	u8  issuer[0x40]; 	// signature issuer
618   /* 0x180 */	u8  unknown1[0x3f]; 	// always 0, unless it is a VC game
619   /* 0x1bf */	u8  title_key[0x10];	// encrypted title key, offset=WII_TICKET_KEY_OFF
620   /* 0x1cf */	u8  unknown2; 		// ?
621   /* 0x1d0 */	u8  ticket_id[8];	// ticket ID
622   /* 0x1d8 */	u8  console_id[4];	// console ID
623   /* 0x1dc */	u8  title_id[8];	// title ID, offset=WII_TICKET_IV_OFF
624   /* 0x1e4 */	u16 unknown3;		// unknown, mostly 0xFFFF
625   /* 0x1e6 */	u16 n_dlc; 		// amount of bought DLC contents
626   /* 0x1e8 */	u8  unknown4;		// ERROR in http://wiibrew.org/wiki/Ticket
627   /* 0x1e9 */	u8  unknown5[0x08];	// ?
628   /* 0x1f1 */	u8  common_key_index;	// 1=Korean Common key, 0="normal" Common key
629   /* 0x1f2 */	u8  unknown6[0x30]; 	// Is all 0 for non-VC, for VC, all 0 except last byte is 1
630   /* 0x222 */	u8  unknown7[0x20]; 	// always 0xff (?)
631   /* 0x242 */	u8  padding2[2]; 	// always 0
632   /* 0x244 */	u32 enable_time_limit;	// 1=enabled, 0=disabled
633   /* 0x248 */	u32 time_limit;		// seconds (what is the epoch?)
634   /* 0x24c */	u8  fake_sign[0x58];	// padding, always 0 => used for fake signing
635 
636 }
637 __attribute__ ((packed)) wd_ticket_t;
638 
639 //----- encryption helpers
640 
641 extern const char not_encrypted_marker[];
642 
643 void ticket_setup ( wd_ticket_t * ticket, const void * id4 );
644 
645 void ticket_clear_encryption ( wd_ticket_t * ticket, int mark_not_encrypted );
646 bool ticket_is_marked_not_encrypted ( const wd_ticket_t * ticket );
647 u32  ticket_fake_sign ( wd_ticket_t * ticket, u32 ticket_size );
648 bool ticket_is_fake_signed ( const wd_ticket_t * ticket, u32 ticket_size );
649 
650 //
651 ///////////////////////////////////////////////////////////////////////////////
652 ///////////////			struct wd_part_header_t		///////////////
653 ///////////////////////////////////////////////////////////////////////////////
654 
655 typedef struct wd_part_header_t
656 {
657   /* 0x000 */	wd_ticket_t ticket;
658   /* 0x2a4 */	u32 tmd_size;
659   /* 0x2a8 */	u32 tmd_off4;
660   /* 0x2ac */	u32 cert_size;
661   /* 0x2b0 */	u32 cert_off4;
662   /* 0x2b4 */	u32 h3_off4;
663   /* 0x2b8 */	u32 data_off4;
664   /* 0x2bc */	u32 data_size4;
665 }
666 __attribute__ ((packed)) wd_part_header_t;
667 
668 void ntoh_part_header ( wd_part_header_t * dest, const wd_part_header_t * src );
669 void hton_part_header ( wd_part_header_t * dest, const wd_part_header_t * src );
670 
671 //
672 ///////////////////////////////////////////////////////////////////////////////
673 ///////////////		      struct wd_tmd_content_t		///////////////
674 ///////////////////////////////////////////////////////////////////////////////
675 
676 typedef struct wd_tmd_content_t
677 {
678   /* 0x00 */	u32 content_id;
679   /* 0x04 */	u16 index;
680   /* 0x06 */	u16 type;
681   /* 0x08 */	u64 size;
682   /* 0x10 */	u8  hash[WII_HASH_SIZE]; // SHA1 hash
683 }
684 __attribute__ ((packed)) wd_tmd_content_t;
685 
686 //
687 ///////////////////////////////////////////////////////////////////////////////
688 ///////////////			    struct wd_tmd_t		///////////////
689 ///////////////////////////////////////////////////////////////////////////////
690 
691 typedef struct wd_tmd_t
692 {
693   // --> http://wiibrew.org/wiki/Tmd_file_structure
694 
695   /* 0x000 */	u32 sig_type;
696   /* 0x004 */	u8  sig[0x100];
697   /* 0x104 */	u8  sig_padding[0x3c];
698 
699   // the signature calculations starts here (WII_TMD_SIG_OFF)
700 
701   /* 0x140 */	u8  issuer[0x40];
702   /* 0x180 */	u8  version;
703   /* 0x181 */	u8  ca_crl_version;
704   /* 0x182 */	u8  signer_crl_version;
705   /* 0x183 */	u8  padding2;
706   /* 0x184 */	u64 sys_version;	// system version (the ios that the title need)
707   /* 0x18c */	u8  title_id[8];
708   /* 0x194 */	u32 title_type;
709   /* 0x198 */	u16 group_id;
710   /* 0x19a */	u8  fake_sign[0x3e]; 	// padding => place of fake signing
711   /* 0x1d8 */	u32 access_rights;
712   /* 0x1dc */	u16 title_version;
713   /* 0x1de */	u16 n_content;
714   /* 0x1e0 */	u16 boot_index;
715   /* 0x1e2 */	u8  padding3[2];
716   /* 0x1e4 */	wd_tmd_content_t content[0]; // n_contents elements
717 }
718 __attribute__ ((packed)) wd_tmd_t;
719 
720 //----- encryption helpers
721 
722 void tmd_setup ( wd_tmd_t * tmd, u32 tmd_size, const void * id4 );
723 
724 void tmd_clear_encryption ( wd_tmd_t * tmd, int mark_not_encrypted );
725 bool tmd_is_marked_not_encrypted ( const wd_tmd_t * tmd );
726 u32  tmd_fake_sign ( wd_tmd_t * tmd, u32 tmd_size );
727 bool tmd_is_fake_signed ( const wd_tmd_t * tmd, u32 tmd_size );
728 
729 //
730 ///////////////////////////////////////////////////////////////////////////////
731 ///////////////		    struct wd_part_control_t		///////////////
732 ///////////////////////////////////////////////////////////////////////////////
733 
734 typedef struct wd_part_control_t
735 {
736     u8 part_bin[WII_PARTITION_BIN_SIZE]; // this is the real data
737 
738     // this are pointers into part_bin
739 
740     wd_part_header_t	* head;		// pointer to header
741     wd_tmd_t		* tmd;		// pointer to tmd
742     wd_tmd_content_t	* tmd_content;	// NULL or pointer to first tmd content
743     u8			* cert;		// pointer to cert
744     u8			* h3;		// pointer to h3
745 
746     // the following values are informative; format is host endian
747 
748     int is_valid;	// is structure valid
749 
750     u32 head_size;	// always sizeof(wd_part_header_t)
751     u32 tmd_size;	// set by user
752     u32 cert_size;	// set by user
753     u32 h3_size;	// always WII_H3_SIZE
754 
755     u64 data_off;	// = sizeof(part_bin) if cleared
756     u64 data_size;	// set by user
757 }
758 wd_part_control_t; // packing not needed
759 
760 //----- setup
761 
762 // 0:ok, 1:error, sizes to large
763 int clear_part_control
764 	( wd_part_control_t * pc, u32 tmd_size, u32 cert_size, u64 data_size );
765 
766 // 0:ok, 1:error => pc->part_bin must be valid content
767 int setup_part_control ( wd_part_control_t * pc );
768 
769 //----- encryption helpers
770 
771 u32 part_control_fake_sign ( wd_part_control_t * pc, int calc_h4 );
772 int part_control_is_fake_signed ( const wd_part_control_t * pc );
773 
774 //
775 ///////////////////////////////////////////////////////////////////////////////
776 ///////////////			struct wd_part_sector_t		///////////////
777 ///////////////////////////////////////////////////////////////////////////////
778 
779 typedef struct wd_part_sector_t
780 {
781   /* 0x000 */	u8 h0 [WII_N_ELEMENTS_H0][WII_HASH_SIZE];
782   /* 0x26c */	u8 padding0[0x14];
783   /* 0x280 */	u8 h1 [WII_N_ELEMENTS_H1][WII_HASH_SIZE];
784   /* 0x320 */	u8 padding1[0x20];
785   /* 0x340 */	u8 h2 [WII_N_ELEMENTS_H2][WII_HASH_SIZE];
786   /* 0x3e0 */	u8 padding2[0x20];
787 
788   /* 0x400 */	u8 data[WII_N_ELEMENTS_H0][WII_H0_DATA_SIZE];
789 }
790 __attribute__ ((packed)) wd_part_sector_t;
791 
792 //
793 ///////////////////////////////////////////////////////////////////////////////
794 ///////////////			struct wd_fst_item_t		///////////////
795 ///////////////////////////////////////////////////////////////////////////////
796 
797 typedef struct wd_fst_item_t
798 {
799     union
800     {
801 	u8  is_dir;
802 	u32 name_off;	// mask with 0x00ffffff
803     };
804 
805     u32 offset4;
806     u32 size;
807 }
808 __attribute__ ((packed)) wd_fst_item_t;
809 
810 //
811 ///////////////////////////////////////////////////////////////////////////////
812 ///////////////			struct wbfs_head_t		///////////////
813 ///////////////////////////////////////////////////////////////////////////////
814 
815 typedef struct wbfs_head_t
816 {
817  /*    0 */	be32_t	magic;		// the magic (char*)"WBFS"
818 
819     // the 3 main parameters -> they are used to calculate the geometry
820 
821  /* 0x04 */	be32_t	n_hd_sec;	// total number of hd_sec in this partition
822  /* 0x08 */	u8	hd_sec_sz_s;	// sector size in this partition
823  /* 0x09 */	u8	wbfs_sec_sz_s;	// size of a wbfs sec
824 
825     // more parameters
826 
827  /* 0x0a */	u8	wbfs_version;	// informative version number
828  /* 0x0b */	u8	padding;
829  /* 0x0c */	u8	disc_table[0];	// size depends on hd sector size
830 }
831 __attribute__ ((packed)) wbfs_head_t;
832 
833 //
834 ///////////////////////////////////////////////////////////////////////////////
835 ///////////////			struct wbfs_disc_info_t		///////////////
836 ///////////////////////////////////////////////////////////////////////////////
837 
838 typedef struct wbfs_disc_info_t
839 {
840  /*    0 */	u8	dhead[0x100];
841  /* 0x100 */	be16_t	wlba_table[0];	// wbfs_t::n_wbfs_sec_per_disc elements
842 
843 }
844 __attribute__ ((packed)) wbfs_disc_info_t;
845 
846 //
847 ///////////////////////////////////////////////////////////////////////////////
848 ///////////////			wit patch files			///////////////
849 ///////////////////////////////////////////////////////////////////////////////
850 
851 // The data structure of a patch file is designed to allow reading
852 // and writing streams (pipe support, no file seek needed).
853 // The TOC (table of content) is placed at end of file and is only
854 // needed for search and for fast list operations.
855 
856 // file layout:
857 //
858 //	+-----------------------+
859 //	| patch header		|
860 //	+-----------------------+
861 //	| file manipulations	|
862 //	+-----------------------+
863 //	| toc file list		|
864 //	+-----------------------+
865 //	| toc header		|
866 //	+-----------------------+
867 
868 ///////////////////////////////////////////////////////////////////////////////
869 
870 #define WIT_PATCH_MAGIC			"WIT-PATCHER"
871 
872 //-----------------------------------------------------
873 // Format of version number: AABBCCDD = A.BB | A.BB.CC
874 // If D != 0x00 && D != 0xff => append: 'beta' D
875 //-----------------------------------------------------
876 
877 #define WIT_PATCH_VERSION		0x00010000  // current writing version
878 #define WIT_PATCH_COMPATIBLE		0x00010000  // down compatible
879 #define WIT_PATCH_READ_COMPATIBLE	0x00010000  // read compatible
880 
881 extern const char wpat_magic[12];
882 
883 //
884 ///////////////////////////////////////////////////////////////////////////////
885 ///////////////			enum wpat_type_t		///////////////
886 ///////////////////////////////////////////////////////////////////////////////
887 
888 typedef enum wpat_type_t
889 {
890     //--- patch file header
891 
892 	WPAT_HEADER	= 1,	// wpat_header_t
893 
894     //--- data records
895 
896 	WPAT_COMMENT,		// wpat_comment_t
897 	WPAT_DATA,		// wpat_data_t
898 
899     //--- file manipulation records
900 
901 	WPAT_DELETE_FILE,	// wpat_filename_t
902 	WPAT_CREATE_FILE,	// wpat_filename_t	-> wpat_data_t
903 	WPAT_MOVE_FILE,		// wpat_filenames_t
904 	WPAT_COPY_FILE,		// wpat_filenames_t
905 	WPAT_LINK_FILE,		// wpat_filenames_t
906 	WPAT_PATCH_FILE,	// wpat_patch_file_t	-> wpat_data_t
907 
908     //--- masks and flags
909 
910 	WPAT_M_ID	= 0x3f,	// mask of ID bits
911 	WPAT_F_TOC	= 0x40,	// toc marker
912 
913     //--- toc records
914 
915 	WPAT_TOC_HEADER		= WPAT_F_TOC|WPAT_HEADER,	// wpat_toc_header_t
916 	WPAT_TOC_DELETE_FILE	= WPAT_F_TOC|WPAT_DELETE_FILE,	// wpat_toc_file_t
917 	WPAT_TOC_CREATE_FILE	= WPAT_F_TOC|WPAT_CREATE_FILE,	// wpat_toc_file_t
918 	WPAT_TOC_MOVE_FILE	= WPAT_F_TOC|WPAT_MOVE_FILE,	// wpat_toc_file_t
919 	WPAT_TOC_COPY_FILE	= WPAT_F_TOC|WPAT_COPY_FILE,	// wpat_toc_file_t
920 	WPAT_TOC_LINK_FILE	= WPAT_F_TOC|WPAT_LINK_FILE,	// wpat_toc_file_t
921 	WPAT_TOC_PATCH_FILE	= WPAT_F_TOC|WPAT_PATCH_FILE,	// wpat_toc_file_t
922 }
923 __attribute__ ((packed)) wpat_type_t;
924 
925 //-----------------------------------------------------------------------------
926 
927 ccp wpat_get_type_name ( wpat_type_t type, ccp return_if_invalid );
928 
929 //
930 ///////////////////////////////////////////////////////////////////////////////
931 ///////////////			union wpat_size_t		///////////////
932 ///////////////////////////////////////////////////////////////////////////////
933 
934 typedef union wpat_size_t
935 {
936 	wpat_type_t	type;	// type of patch record
937 	u32		size4;	// size of record,
938 				//  -> mask with 0xffffff, multiply with 4
939 }
940 __attribute__ ((packed)) wpat_size_t;
941 
942 //-----------------------------------------------------------------------------
943 
944 u32 wpat_get_size ( wpat_size_t type_size );
945 wpat_size_t wpat_calc_size ( wpat_type_t type, u32 size );
946 
947 //
948 ///////////////////////////////////////////////////////////////////////////////
949 ///////////////			struct wpat_header_t		///////////////
950 ///////////////////////////////////////////////////////////////////////////////
951 
952 typedef struct wpat_header_t
953 {
954     /* 0x00 */	u8		magic[12];	// always 'WIT_PATCH_MAGIC'
955 						// magic is *not* counted in 'type_size'
956 
957     /* 0x0c */	wpat_size_t	type_size;	// type (WPAT_HEADER) and record size
958     /* 0x10 */	u32		version;	// patch file version
959     /* 0x14 */	u32		compatible;	// patch file down compatible to version
960     /* 0x18 */	char		reserved[0];	// reserved for future extensions
961 }
962 __attribute__ ((packed)) wpat_header_t;
963 
964 //
965 ///////////////////////////////////////////////////////////////////////////////
966 ///////////////			struct wpat_comment_t		///////////////
967 ///////////////////////////////////////////////////////////////////////////////
968 
969 typedef struct wpat_comment_t
970 {
971     /* 0x00 */	wpat_size_t	type_size;	// type (WPAT_COMMENT) and record size
972     /* 0x04 */	u8		comment[0];	// comment string
973 }
974 __attribute__ ((packed)) wpat_comment_t;
975 
976 //
977 ///////////////////////////////////////////////////////////////////////////////
978 ///////////////			struct wpat_data_t		///////////////
979 ///////////////////////////////////////////////////////////////////////////////
980 
981 typedef struct wpat_data_t
982 {
983     /* 0x00 */	wpat_size_t	type_size;	// type (WPAT_DATA) and record size
984     /* 0x04 */	u32		file_offset;	// offset in files
985     /* 0x08 */	u32		data_size;	// used length of patch 'data'
986     /* 0x0c */	u8		data[0];	// patch or source data
987 
988 	// - WPAT_PATCH_FILE:
989 	//	patch data is XORed with orig data
990 	//	if >src_size: use cyclic 'src_hash' to XOR
991 	// - WPAT_CRATE_FILE:
992 	//	1:1 source data
993 }
994 __attribute__ ((packed)) wpat_data_t;
995 
996 //
997 ///////////////////////////////////////////////////////////////////////////////
998 ///////////////			struct wpat_filename_t		///////////////
999 ///////////////////////////////////////////////////////////////////////////////
1000 
1001 typedef struct wpat_filename_t
1002 {
1003     /* 0x00 */	wpat_size_t	type_size;	// type and record size
1004     /* 0x04 */	char		fname[0];	// filename, size always multiple of 4
1005 }
1006 __attribute__ ((packed)) wpat_filename_t;
1007 
1008 //
1009 ///////////////////////////////////////////////////////////////////////////////
1010 ///////////////			struct wpat_filenames_t		///////////////
1011 ///////////////////////////////////////////////////////////////////////////////
1012 
1013 typedef struct wpat_filenames_t
1014 {
1015     /* 0x00 */	wpat_size_t	type_size;	// type and record size
1016     /* 0x04 */	u32		src_file_off;	// offset in 'fnames' of source filename
1017     /* 0x08 */	char		fnames[0];	// 2 filenames, size always multiple of 4
1018 						//  -> dest_filname, src_filename
1019 }
1020 __attribute__ ((packed)) wpat_filenames_t;
1021 
1022 //
1023 ///////////////////////////////////////////////////////////////////////////////
1024 ///////////////			struct wpat_patch_file_t	///////////////
1025 ///////////////////////////////////////////////////////////////////////////////
1026 
1027 typedef struct wpat_patch_file_t
1028 {
1029     /* 0x00 */	wpat_size_t	type_size;	// type (WPAT_PATCH_FILE) and record size
1030     /* 0x04 */	u32		src_file_size;	// size of source file, 0=new file
1031     /* 0x08 */	u32		dest_file_size;	// size of destination file
1032     /* 0x0c */	sha1_hash_t	src_hash;	// SHA1 hash of source file
1033     /* 0x20 */	sha1_hash_t	dest_hash;	// SHA1 hash of destination file
1034     /* 0x34 */	char		fname[0];	// filename, size always multiple of 4
1035 }
1036 __attribute__ ((packed)) wpat_patch_file_t;
1037 
1038 //
1039 ///////////////////////////////////////////////////////////////////////////////
1040 ///////////////			struct wpat_toc_header_t	///////////////
1041 ///////////////////////////////////////////////////////////////////////////////
1042 
1043 typedef struct wpat_toc_header_t
1044 {
1045     /* 0x00 */	wpat_size_t	type_size;	// type (WPAT_TOC_HEADER) and record size
1046     /* 0x04 */	u32		entry_offset4;	// file offset/4 of first entry
1047     /* 0x0c */	u32		n_entires;	// number of 'wpat_toc_file_t' entries
1048     /* 0x10 */	u8		magic[12];	// always 'WIT_PATCH_MAGIC'
1049     /* 0x1c */
1050 }
1051 __attribute__ ((packed)) wpat_toc_header_t;
1052 
1053 //
1054 ///////////////////////////////////////////////////////////////////////////////
1055 ///////////////			struct wpat_toc_file_t		///////////////
1056 ///////////////////////////////////////////////////////////////////////////////
1057 
1058 typedef struct wpat_toc_file_t
1059 {
1060     /* 0x00 */	wpat_size_t	type_size;	// type (WPAT_F_TOC set) and record size
1061     /* 0x04 */	u32		item_offset4;	// file offset/4 of file item
1062     /* 0x0c */	char		fname[0];	// filename, size always multiple of 4
1063 						// informative only
1064 }
1065 __attribute__ ((packed)) wpat_toc_file_t;
1066 
1067 //
1068 ///////////////////////////////////////////////////////////////////////////////
1069 ///////////////			consts & vars			///////////////
1070 ///////////////////////////////////////////////////////////////////////////////
1071 
1072 extern const char skeleton_marker[10];
1073 
1074 //
1075 ///////////////////////////////////////////////////////////////////////////////
1076 ///////////////			    E N D			///////////////
1077 ///////////////////////////////////////////////////////////////////////////////
1078 
1079 #endif // FILE_FORMATS_H
1080