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 WIT_LIB_WIA_H
38 #define WIT_LIB_WIA_H 1
39 
40 #include "types.h"
41 #include "lib-std.h"
42 #include "libwbfs/wiidisc.h"
43 
44 //
45 ///////////////////////////////////////////////////////////////////////////////
46 ///////////////			WIA file layout			///////////////
47 ///////////////////////////////////////////////////////////////////////////////
48 
49 // *** file layout ***
50 //
51 //	+-----------------------+
52 //	| wia_file_head_t	|  data structure will never changed
53 //	+-----------------------+
54 //	| wia_disc_t		|  disc data
55 //	+-----------------------+
56 //	| wia_part_t #0		|  fixed size partition header
57 //	| wia_part_t #1		|  wia_disc_t::n_part elements
58 //	| ...			|   -> data stored in wia_group_t elements
59 //	+-----------------------+
60 //	| data chunks		|  stored in any order
61 //	| ...			|
62 //	+-----------------------+
63 
64 
65 // *** data chunks (any order) ***
66 //
67 //	+-----------------------+
68 //	| compressor data	|  data for compressors (e.g properties)
69 //	| compressed chunks	|
70 //	+-----------------------+
71 
72 
73 // *** compressed chunks (any order) ***
74 //
75 //	+-----------------------+
76 //	| raw data table	|
77 //	| group table		|
78 //	| raw data		|  <- divided in groups (e.g partition .header)
79 //	| partition data	|  <- divided in groups
80 //	+-----------------------+
81 
82 
83 // *** partition data (Wii format) ***
84 //
85 //	+-----------------------+
86 //	| wia_except_list	|  wia_group_t::n_exceptions hash exceptions
87 //	+-----------------------+
88 //	| (compressed) data	|  compression dependent data
89 //	+-----------------------+
90 
91 
92 // *** other data (non partition data) ***
93 //
94 //	+-----------------------+
95 //	| (compressed) data	|  compression dependent data
96 //	+-----------------------+
97 
98 //
99 ///////////////////////////////////////////////////////////////////////////////
100 ///////////////			WIA definitions			///////////////
101 ///////////////////////////////////////////////////////////////////////////////
102 
103 // First a magic is defined to identify a WIA clearly. The magic should never be
104 // a possible Wii ISO image identification. Wii ISO images starts with the ID6.
105 // And so the WIA magic contains one contral character (CTRL-A) within.
106 
107 #define WIA_MAGIC		"WIA\1"
108 #define WIA_MAGIC_SIZE		4
109 
110 //-----------------------------------------------------
111 // Format of version number: AABBCCDD = A.BB | A.BB.CC
112 // If D != 0x00 && D != 0xff => append: 'beta' D
113 //-----------------------------------------------------
114 
115 #define WIA_VERSION			0x01000000  // current writing version
116 #define WIA_VERSION_COMPATIBLE		0x00090000  // down compatible
117 #define WIA_VERSION_READ_COMPATIBLE	0x00080000  // read compatible
118 #define PrintVersionWIA PrintVersion
119 
120 // the minimal size of holes in bytes that will be detected.
121 #define WIA_MIN_HOLE_SIZE	0x400
122 
123 // the maximal supported iso size
124 #define WIA_MAX_SUPPORTED_ISO_SIZE (50ull*GiB)
125 
126 // the minimal chunk size (if ever, multiple of this are supported)
127 #define WIA_BASE_CHUNK_SIZE	WII_GROUP_SIZE
128 #define WIA_DEF_CHUNK_FACTOR	 20
129 #define WIA_MAX_CHUNK_FACTOR	100
130 
131 //
132 ///////////////////////////////////////////////////////////////////////////////
133 ///////////////			struct wia_file_head_t		///////////////
134 ///////////////////////////////////////////////////////////////////////////////
135 
136 typedef struct wia_file_head_t
137 {
138     // This data structure is never changed.
139     // If additional info is needed, others structures will be expanded.
140     // All values are stored in network byte order (big endian)
141 
142     char		magic[WIA_MAGIC_SIZE];	// 0x00: WIA_MAGIC, what else!
143 
144     u32			version;		// 0x04: WIA_VERSION
145     u32			version_compatible;	// 0x08: compatible down to
146 
147     u32			disc_size;		// 0x0c: size of wia_disc_t
148     sha1_hash_t		disc_hash;		// 0x10: hash of wia_disc_t
149 
150     u64			iso_file_size;		// 0x24: size of ISO image
151     u64			wia_file_size;		// 0x2c: size of WIA file
152 
153     sha1_hash_t		file_head_hash;		// 0x34: hash of wia_file_head_t
154 
155 } __attribute__ ((packed)) wia_file_head_t;	// 0x48 = 72 = sizeof(wia_file_head_t)
156 
157 //
158 ///////////////////////////////////////////////////////////////////////////////
159 ///////////////			struct wia_disc_t		///////////////
160 ///////////////////////////////////////////////////////////////////////////////
161 
162 typedef struct wia_disc_t
163 {
164     // All values are stored in network byte order (big endian)
165 
166     //--- base infos
167 
168     u32			disc_type;		// 0x00: wd_disc_type_t
169     u32			compression;		// 0x04: wd_compression_t
170     u32			compr_level;		// 0x08: method dependent compr.level
171 						//       This value is informative only
172     u32			chunk_size;		// 0x0c: used chunk_size, 2 MiB is standard
173 
174     //--- disc header, first 0x80 bytes of source for easy detection
175 
176     u8			dhead[0x80];		// 0x10: 128 bytes of disc header
177 						//	 for a fast data access
178     //--- partition data, direct copy => hash needed
179 
180     u32			n_part;			// 0x90: number or partitions
181     u32			part_t_size;		// 0x94: size of 1 element of wia_part_t
182     u64			part_off;		// 0x98: file offset wia_part_t[n_part]
183     sha1_hash_t		part_hash;		// 0xa0: hash of wia_part_t[n_part]
184 
185     //--- raw data, compressed
186 
187     u32			n_raw_data;		// 0xb4: number of wia_raw_data_t elements
188     u64			raw_data_off;		// 0xb8: offset of wia_raw_data_t[n_raw_data]
189     u32			raw_data_size;		// 0xc0: conpressed size of raw data
190 
191     //--- group header, compressed
192 
193     u32			n_groups;		// 0xc4: number of wia_group_t elements
194     u64			group_off;		// 0xc8: offset of wia_group_t[n_groups]
195     u32			group_size;		// 0xd0: conpressed size of groups
196 
197     //--- compressor dependent data (e.g. LZMA properties)
198 
199     u8			compr_data_len;		// 0xd4: used length of 'compr_data'
200     u8			compr_data[7];		// 0xd5: compressor specific data
201 
202 } __attribute__ ((packed)) wia_disc_t;		// 0xdc = 220 = sizeof(wia_disc_t)
203 
204 //
205 ///////////////////////////////////////////////////////////////////////////////
206 ///////////////		    struct wia_part_data_t		///////////////
207 ///////////////////////////////////////////////////////////////////////////////
208 
209 // Sub structire for wia_part_t
210 
211 typedef struct wia_part_data_t
212 {
213     // All values are stored in network byte order (big endian)
214 
215     u32			first_sector;		// 0x00: first data sector
216     u32			n_sectors;		// 0x04: number of sectors
217 
218     u32			group_index;		// 0x08: index of first wia_group_t
219     u32			n_groups;		// 0x0c: number of wia_group_t elements
220 
221 } __attribute__ ((packed)) wia_part_data_t;	// 0x10 = 16 = sizeof(wia_part_t)
222 
223 //
224 ///////////////////////////////////////////////////////////////////////////////
225 ///////////////			struct wia_part_t		///////////////
226 ///////////////////////////////////////////////////////////////////////////////
227 
228 // This data structure is only used for Wii like partitions but nor for GC.
229 // It supports decrypting and hash removing.
230 
231 typedef struct wia_part_t
232 {
233     // All values are stored in network byte order (big endian)
234 
235     u8			part_key[WII_KEY_SIZE];	// 0x00: partition key => build aes key
236 
237     wia_part_data_t	pd[2];			// 0x10: 2 partition data segments
238 						//   segment 0 is small and defined
239 						//   for managment data (boot .. fst).
240 						//   segment 1 takes the remaining data
241 
242 } __attribute__ ((packed)) wia_part_t;		// 0x30 = 48 = sizeof(wia_part_t)
243 
244 //
245 ///////////////////////////////////////////////////////////////////////////////
246 ///////////////			struct wia_raw_data_t		///////////////
247 ///////////////////////////////////////////////////////////////////////////////
248 
249 typedef struct wia_raw_data_t
250 {
251     // All values are stored in network byte order (big endian)
252 
253     u64			raw_data_off;		// 0x00: disc offset of raw data
254     u64			raw_data_size;		// 0x08: size of raw data
255 
256     u32			group_index;		// 0x10: index of first wia_group_t
257     u32			n_groups;		// 0x14: number of wia_group_t elements
258 
259 } __attribute__ ((packed)) wia_raw_data_t;	// 0x18 = 24 = sizeof(wia_raw_data_t)
260 
261 //
262 ///////////////////////////////////////////////////////////////////////////////
263 ///////////////			struct wia_group_t		///////////////
264 ///////////////////////////////////////////////////////////////////////////////
265 
266 // Each group points to a data segment list. Size of last element is null.
267 // Partition data groups are headed by a hash exeption list (wia_except_list_t).
268 
269 typedef struct wia_group_t
270 {
271     // All values are stored in network byte order (big endian)
272 
273     u32			data_off4;		// 0x00: file offset/4 of data
274     u32			data_size;		// 0x04: file size of data
275 
276 } __attribute__ ((packed)) wia_group_t;		// 0x08 = 8 = sizeof(wia_group_t)
277 
278 //
279 ///////////////////////////////////////////////////////////////////////////////
280 ///////////////			struct wia_exception_t		///////////////
281 ///////////////////////////////////////////////////////////////////////////////
282 
283 typedef struct wia_exception_t
284 {
285     // All values are stored in network byte order (big endian)
286 
287     u16			offset;			// 0x00: sector offset of hash
288     sha1_hash_t		hash;			// 0x02: hash value
289 
290 } __attribute__ ((packed)) wia_exception_t;	// 0x16 = 22 = sizeof(wia_exception_t)
291 
292 //
293 ///////////////////////////////////////////////////////////////////////////////
294 ///////////////			struct wia_except_list_t	///////////////
295 ///////////////////////////////////////////////////////////////////////////////
296 
297 typedef struct wia_except_list_t
298 {
299     u16			n_exceptions;		// 0x00: number of hash exceptions
300     wia_exception_t	exception[0];		// 0x02: hash exceptions
301 
302 } __attribute__ ((packed)) wia_except_list_t;	// 0x02 = 2 = sizeof(wia_except_list_t)
303 
304 //
305 ///////////////////////////////////////////////////////////////////////////////
306 ///////////////			struct wia_segment_t		///////////////
307 ///////////////////////////////////////////////////////////////////////////////
308 
309 typedef struct wia_segment_t
310 {
311     // All values are stored in network byte order (big endian)
312     // Segments are used to reduce the size of uncompressed data (method PURGE)
313     // This is done by eleminatin holes (zeroed areas)
314 
315     u32			offset;			// 0x00: offset relative to group
316     u32			size;			// 0x04: size of 'data'
317     u8			data[0];		// 0x08: data
318 
319 } __attribute__ ((packed)) wia_segment_t;	// 0x08 = 8 = sizeof(wia_segment_t)
320 
321 //
322 ///////////////////////////////////////////////////////////////////////////////
323 ///////////////			struct wia_controller_t		///////////////
324 ///////////////////////////////////////////////////////////////////////////////
325 
326 typedef struct wia_controller_t
327 {
328     wd_disc_t		* wdisc;	// valid if writing
329 
330     wia_file_head_t	fhead;		// header in local endian
331     wia_disc_t		disc;		// disc data
332 
333     wia_part_t		* part;		// NULL or pointer to partition info
334 
335     wia_raw_data_t	* raw_data;	// NULL or pointer to raw data list
336     u32			raw_data_used;	// number of used 'group' elements
337     u32			raw_data_size;	// number of alloced 'group' elements
338     wia_raw_data_t	* growing;	// NULL or pointer to last element of 'raw_data'
339 					// used for writing behind expected file size
340 
341     wia_group_t		* group;	// NULL or pointer to group list
342     u32			group_used;	// number of used 'group' elements
343     u32			group_size;	// number of alloced 'group' elements
344 
345     wd_memmap_t		memmap;		// memory mapping
346 
347     bool		encrypt;	// true: encrypt data if reading
348     bool		is_writing;	// false: read a WIA / true: write a WIA
349     bool		is_valid;	// true: WIA is valid
350 
351     u32			chunk_size;	// chunk size in use
352     u32			chunk_sectors;	// sector per chunk
353     u32			chunk_groups;	// sector groups per chunk
354     u32			memory_usage;	// calculated memory usage (RAM)
355 
356     u64			write_data_off;	// writing file offset for the next data
357 
358 
359     //----- group data cache
360 
361     u8			* gdata;	// group data
362     u32			gdata_size;	// alloced size of 'gdata'
363     u32			gdata_used;	// relevant size of 'gdata'
364     int			gdata_group;	// index of current group, -1:invalid
365     int			gdata_part;	// partition index of current group data
366 
367     aes_key_t		akey;		// akey of 'gdata_part'
368     wd_part_sector_t	empty_sector;	// empty encrypted sector, calced with 'akey'
369 
370 } wia_controller_t;
371 
372 //
373 ///////////////////////////////////////////////////////////////////////////////
374 ///////////////			    interface			///////////////
375 ///////////////////////////////////////////////////////////////////////////////
376 
377 void ResetWIA
378 (
379     wia_controller_t	* wia		// NULL or valid pointer
380 );
381 
382 //-----------------------------------------------------------------------------
383 
384 bool IsWIA
385 (
386     const void		* data,		// data to check
387     size_t		data_size,	// size of data
388     void		* id6_result,	// not NULL: store ID6 (6 bytes without null term)
389     wd_disc_type_t	* disc_type,	// not NULL: store disc type
390     wd_compression_t	* compression	// not NULL: store compression
391 );
392 
393 //-----------------------------------------------------------------------------
394 
395 u32 CalcMemoryUsageWIA
396 (
397     wd_compression_t	compression,	// compression method
398     int			compr_level,	// valid are 1..9 / 0: use default value
399     u32			chunk_size,	// wanted chunk size
400     bool		is_writing	// false: reading mode, true: writing mode
401 );
402 
403 //-----------------------------------------------------------------------------
404 
405 int CalcDefaultSettingsWIA
406 (
407     wd_compression_t	* compression,	// NULL or compression method
408     int			* compr_level,	// NULL or compression level
409     u32			* chunk_size	// NULL or wanted chunk size
410 );
411 
412 //
413 ///////////////////////////////////////////////////////////////////////////////
414 ///////////////			SuperFile_t interface		///////////////
415 ///////////////////////////////////////////////////////////////////////////////
416 // WIA reading support
417 
418 struct SuperFile_t;
419 
420 enumError SetupReadWIA
421 (
422     struct SuperFile_t	* sf		// file to setup
423 );
424 
425 //-----------------------------------------------------------------------------
426 
427 enumError ReadWIA
428 (
429     struct SuperFile_t	* sf,		// source file
430     off_t		off,		// file offset
431     void		* buf,		// destination buffer
432     size_t		count		// number of bytes to read
433 );
434 
435 //-----------------------------------------------------------------------------
436 
437 off_t DataBlockWIA
438 (
439     struct SuperFile_t	* sf,		// source file
440     off_t		off,		// virtual file offset
441     size_t		hint_align,	// if >1: hint for a aligment factor
442     off_t		* block_size	// not null: return block size
443 );
444 
445 //-----------------------------------------------------------------------------
446 // WIA writing support
447 
448 enumError SetupWriteWIA
449 (
450     struct SuperFile_t	* sf,		// file to setup
451     u64			src_file_size	// NULL or source file size
452 );
453 
454 //-----------------------------------------------------------------------------
455 
456 enumError TermWriteWIA
457 (
458     struct SuperFile_t	* sf		// file to terminate
459 );
460 
461 //-----------------------------------------------------------------------------
462 
463 enumError WriteWIA
464 (
465     struct SuperFile_t	* sf,		// destination file
466     off_t		off,		// file offset
467     const void		* buf,		// source buffer
468     size_t		count		// number of bytes to write
469 );
470 
471 //-----------------------------------------------------------------------------
472 
473 enumError WriteSparseWIA
474 (
475     struct SuperFile_t	* sf,		// destination file
476     off_t		off,		// file offset
477     const void		* buf,		// source buffer
478     size_t		count		// number of bytes to write
479 );
480 
481 //-----------------------------------------------------------------------------
482 
483 enumError WriteZeroWIA
484 (
485     struct SuperFile_t	* sf,		// destination file
486     off_t		off,		// file offset
487     size_t		count		// number of bytes to write
488 );
489 
490 //-----------------------------------------------------------------------------
491 
492 enumError FlushWIA
493 (
494     struct SuperFile_t	* sf		// destination file
495 );
496 
497 //
498 ///////////////////////////////////////////////////////////////////////////////
499 ///////////////			endian conversions		///////////////
500 ///////////////////////////////////////////////////////////////////////////////
501 
502 void wia_ntoh_file_head ( wia_file_head_t * dest, const wia_file_head_t * src );
503 void wia_hton_file_head ( wia_file_head_t * dest, const wia_file_head_t * src );
504 
505 void wia_ntoh_disc ( wia_disc_t * dest, const wia_disc_t * src );
506 void wia_hton_disc ( wia_disc_t * dest, const wia_disc_t * src );
507 
508 void wia_ntoh_part ( wia_part_t * dest, const wia_part_t * src );
509 void wia_hton_part ( wia_part_t * dest, const wia_part_t * src );
510 
511 void wia_ntoh_raw_data ( wia_raw_data_t * dest, const wia_raw_data_t * src );
512 void wia_hton_raw_data ( wia_raw_data_t * dest, const wia_raw_data_t * src );
513 
514 //
515 ///////////////////////////////////////////////////////////////////////////////
516 ///////////////			    E N D			///////////////
517 ///////////////////////////////////////////////////////////////////////////////
518 
519 #endif // WIT_LIB_WIA_H
520