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