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 Kwiirk * 20 * Copyright (c) 2009-2013 by Dirk Clemens <wiimm@wiimm.de> * 21 * * 22 *************************************************************************** 23 * * 24 * This program is free software; you can redistribute it and/or modify * 25 * it under the terms of the GNU General Public License as published by * 26 * the Free Software Foundation; either version 2 of the License, or * 27 * (at your option) any later version. * 28 * * 29 * This program is distributed in the hope that it will be useful, * 30 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 31 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 32 * GNU General Public License for more details. * 33 * * 34 * See file gpl-2.0.txt or http://www.gnu.org/licenses/gpl-2.0.txt * 35 * * 36 ***************************************************************************/ 37 38 #ifndef LIBWBFS_H 39 #define LIBWBFS_H 40 41 #include "file-formats.h" 42 #include "wiidisc.h" 43 44 #ifdef __cplusplus 45 extern "C" 46 { 47 #endif /* __cplusplus */ 48 49 /////////////////////////////////////////////////////////////////////////////// 50 51 #define WBFS_MAGIC ( 'W'<<24 | 'B'<<16 | 'F'<<8 | 'S' ) 52 #define WBFS_VERSION 1 53 #define WBFS_NO_BLOCK (~(u32)0) 54 55 /////////////////////////////////////////////////////////////////////////////// 56 57 // WBFS first wbfs_sector structure: 58 // 59 // ----------- 60 // | wbfs_head | (hd_sec_sz) 61 // ----------- 62 // | | 63 // | disc_info | 64 // | | 65 // ----------- 66 // | | 67 // | disc_info | 68 // | | 69 // ----------- 70 // | | 71 // | ... | 72 // | | 73 // ----------- 74 // | | 75 // | disc_info | 76 // | | 77 // ----------- 78 // | | 79 // |freeblk_tbl| 80 // | | 81 // ----------- 82 // 83 84 //----------------------------------------------------------------------------- 85 86 // callback definition. Return 1 on fatal error 87 // (callback is supposed to make retries until no hopes..) 88 89 typedef int (*rw_sector_callback_t)(void*fp,u32 lba,u32 count,void*iobuf); 90 typedef void (*progress_callback_t) (u64 done, u64 total, void * callback_data ); 91 92 //----------------------------------------------------------------------------- 93 94 typedef enum wbfs_slot_mode_t 95 { 96 //--- the base info 97 98 WBFS_SLOT_FREE = 0x00, // dics slot is unused 99 WBFS_SLOT_VALID = 0x01, // dics slot is used and disc seems valid 100 WBFS_SLOT_INVALID = 0x02, // dics slot is used but disc is invalid 101 102 //--- some additionally flags 103 104 WBFS_SLOT_F_SHARED = 0x04, // flag: disc is/was sharing a block with other disc 105 WBFS_SLOT_F_FREED = 0x08, // flag: disc is/was using a 'marked free' block 106 107 //--- more values 108 109 WBFS_SLOT__MASK = 0x0f, // mask of all values above 110 WBFS_SLOT__USER = 0x10, // first free bit for extern usage 111 112 } wbfs_slot_mode_t; 113 114 extern char wbfs_slot_mode_info[WBFS_SLOT__MASK+1]; 115 116 //----------------------------------------------------------------------------- 117 118 typedef enum wbfs_balloc_mode_t // block allocation mode 119 { 120 WBFS_BA_AUTO, // let add disc the choice: 121 // for small WBFS partitons (<20G) use WBFS_BA_FIRST 122 // and all for other WBFS partitons use WBFS_BA_NO_FRAG 123 124 WBFS_BA_FIRST, // don't find large blocks and use always the first free block 125 WBFS_BA_AVOID_FRAG, // try to avoid fragments 126 127 WBFS_BA_DEFAULT = WBFS_BA_AUTO 128 129 } wbfs_balloc_mode_t; 130 131 //----------------------------------------------------------------------------- 132 133 typedef struct wbfs_t 134 { 135 wbfs_head_t * head; 136 137 /* hdsectors, the size of the sector provided by the hosting hard drive */ 138 u32 hd_sec_sz; 139 u8 hd_sec_sz_s; // the power of two of the last number 140 u32 n_hd_sec; // the number of hd sector in the wbfs partition 141 142 /* standard wii sector (0x8000 bytes) */ 143 u32 wii_sec_sz; // always WII_SECTOR_SIZE 144 u8 wii_sec_sz_s; // always 15 145 u32 n_wii_sec; 146 u32 n_wii_sec_per_disc; // always WII_MAX_SECTORS 147 148 /* The size of a wbfs sector */ 149 u32 wbfs_sec_sz; 150 u32 wbfs_sec_sz_s; 151 u16 n_wbfs_sec; // this must fit in 16 bit! 152 u16 n_wbfs_sec_per_disc; // size of the lookup table 153 154 u32 part_lba; // the lba of the wbfs header 155 156 /* virtual methods to read write the partition */ 157 rw_sector_callback_t read_hdsector; 158 rw_sector_callback_t write_hdsector; 159 void * callback_data; 160 161 u16 max_disc; // maximal number of possible discs 162 u32 freeblks_lba; // the hd sector of the free blocks table 163 u32 freeblks_lba_count; // number of hd sector used by free blocks table 164 u32 freeblks_size4; // size in u32 of free blocks table 165 u32 freeblks_mask; // mask for last used u32 of freeblks 166 u32 * freeblks; // if not NULL: copy of free blocks table 167 168 u8 * block0; // NULL or copy of wbfs block #0 169 u8 * used_block; // For each WBFS block 1 byte, N='n_wbfs_sec' 170 // 0: unused ==> OK 171 // 1: normal (=single) usage ==> OK 172 // >1: shared by #N discs ==> BAD! 173 // 127: shared by >=127 discs ==> BAD! 174 // >128: reserved for internal usage 175 // 255: header block #0 176 bool used_block_dirty; // true: 'used_block' must be written to disc 177 wbfs_slot_mode_t new_slot_err; // new detected errors 178 wbfs_slot_mode_t all_slot_err; // all detected errros 179 wbfs_balloc_mode_t balloc_mode; // block allocation mode 180 181 u16 disc_info_sz; 182 183 u8 * tmp_buffer; // pre-allocated buffer for unaligned read 184 id6_t *id_list; // list with all disc ids 185 186 bool is_dirty; // if >0: call wbfs_sync() on close 187 u32 n_disc_open; // number of open discs 188 189 } wbfs_t; 190 191 //----------------------------------------------------------------------------- 192 193 typedef struct wbfs_disc_t 194 { 195 wbfs_t * p; 196 wbfs_disc_info_t * header; // pointer to wii header 197 int slot; // disc slot, range= 0 .. wbfs_t::max_disc-1 198 wd_disc_type_t disc_type; // disc type 199 wd_disc_attrib_t disc_attrib; // disc attrib 200 uint disc_blocks; // >0: number of blocks 201 uint n_fragments; // >0: number of fragments 202 bool is_used; // disc is marked as 'used'? 203 bool is_valid; // disc has valid id and magic 204 bool is_deleted; // disc has valid id and deleted_magic 205 bool is_iinfo_valid; // disc has a valid wbfs_inode_info_t 206 bool is_creating; // disc is in creation process 207 bool is_dirty; // if >0: call wbfs_sync_disc_header() on close 208 209 } wbfs_disc_t; 210 211 //----------------------------------------------------------------------------- 212 213 be64_t wbfs_setup_inode_info 214 ( wbfs_t * p, wbfs_inode_info_t * ii, bool is_valid, int is_changed ); 215 216 int wbfs_is_inode_info_valid 217 ( 218 // if valid -> return WBFS_INODE_INFO_VERSION 219 // if invalid -> return 0 220 221 const wbfs_t * p, // NULL or WBFS 222 const wbfs_inode_info_t * ii // NULL or inode pointer 223 ); 224 225 //----------------------------------------------------------------------------- 226 227 typedef struct wbfs_param_t // function parameters 228 { 229 //----- parameters for wbfs_open_partition_param() 230 231 // call back data 232 rw_sector_callback_t read_hdsector; // read sector function 233 rw_sector_callback_t write_hdsector; // write sector function 234 235 // needed parameters 236 u32 hd_sector_size; // HD sector size (0=>512) 237 u32 part_lba; // partition LBA delta 238 int old_wii_sector_calc; // >0 => use old & buggy calculation 239 int force_mode; // >0 => no plausibility tests 240 int reset; // >0 => format disc 241 242 // only used if formatting disc (if reset>0) 243 u32 num_hd_sector; // num of HD sectors 244 int clear_inodes; // >0 => clear inodes 245 int setup_iinfo; // >0 => clear inodes & use iinfo 246 int wbfs_sector_size; // >0 => force wbfs_sec_sz_s 247 248 249 //----- parameters for wbfs_open_partition_param() 250 251 // call back data 252 wd_read_func_t read_src_wii_disc; // read wit sector [obsolete?] 253 progress_callback_t spinner; // progress callback 254 wbfs_balloc_mode_t balloc_mode; // block allocation mode 255 256 257 //----- parameters for wbfs_add_disc_param() 258 259 u64 iso_size; // size of iso image in bytes 260 wd_disc_t *wd_disc; // NULL or the source disc 261 const wd_select_t *psel; // partition selector 262 id6_t wbfs_id6; // not NULL: use this ID for inode 263 264 265 //----- multi use parameters 266 267 // call back data 268 void *callback_data; // used defined data 269 270 // inode info 271 wbfs_inode_info_t iinfo; // additional infos 272 273 274 //----- infos (output of wbfs framework) 275 276 int slot; // >=0: slot of last added disc 277 wbfs_disc_t *open_disc; // NULL or open disc 278 279 } wbfs_param_t; 280 281 //----------------------------------------------------------------------------- 282 283 #ifndef WIT // not used in WiT 284 285 wbfs_t * wbfs_open_partition 286 ( 287 rw_sector_callback_t read_hdsector, 288 rw_sector_callback_t write_hdsector, 289 void * callback_data, 290 int hd_sector_size, 291 int num_hd_sector, 292 u32 part_lba, 293 int reset 294 ); 295 296 #endif 297 298 wbfs_t * wbfs_open_partition_param ( wbfs_param_t * par ); 299 300 int wbfs_calc_size_shift 301 ( u32 hd_sec_sz_s, u32 num_hd_sector, int old_wii_sector_calc ); 302 303 u32 wbfs_calc_sect_size ( u64 total_size, u32 hd_sec_size ); 304 305 void wbfs_calc_geometry 306 ( 307 wbfs_t * p, // pointer to wbfs_t, p->head must be NULL or valid 308 u32 n_hd_sec, // total number of hd_sec in partition 309 u32 hd_sec_sz, // size of a hd/partition sector 310 u32 wbfs_sec_sz // size of a wbfs sector 311 ); 312 313 //----------------------------------------------------------------------------- 314 315 void wbfs_close ( wbfs_t * p ); 316 void wbfs_sync ( wbfs_t * p ); 317 318 wbfs_disc_t * wbfs_open_disc_by_id6 ( wbfs_t * p, u8 * id6 ); 319 wbfs_disc_t * wbfs_open_disc_by_slot ( wbfs_t * p, u32 slot, int force_open ); 320 321 wbfs_disc_t * wbfs_create_disc 322 ( 323 wbfs_t * p, // valid WBFS descriptor 324 const void * disc_header, // NULL or disc header to copy 325 const void * disc_id // NULL or ID6: check non existence 326 // disc_id overwrites the id of disc_header 327 ); 328 329 int wbfs_sync_disc_header ( wbfs_disc_t * d ); 330 void wbfs_close_disc ( wbfs_disc_t * d ); 331 332 wbfs_inode_info_t * wbfs_get_inode_info ( wbfs_t *p, wbfs_disc_info_t *info, int clear_mode ); 333 wbfs_inode_info_t * wbfs_get_disc_inode_info ( wbfs_disc_t * d, int clear_mode ); 334 // clear_mode == 0 : don't clear 335 // clear_mode == 1 : clear if invalid 336 // clear_mode == 2 : clear always 337 338 uint wbfs_get_fragments 339 ( 340 const u16 * wlba_tab, // valid wlba table in network byte order 341 uint tab_length, // length of 'wlba_tab' 342 uint * disc_blocks // not NULL: store number of disc blocks 343 ); 344 345 uint wbfs_get_disc_fragments 346 ( 347 wbfs_disc_t *d, // valid wbfs disc 348 uint * disc_blocks // not NULL: store number of disc blocks 349 ); 350 351 //----------------------------------------------------------------------------- 352 353 int wbfs_rename_disc 354 ( 355 wbfs_disc_t * d, // pointer to an open disc 356 const char * new_id, // if !NULL: take the first 6 chars as ID 357 const char * new_title, // if !NULL: take the first 0x39 chars as title 358 int chg_wbfs_head, // if !0: change ID/title of WBFS header 359 int chg_iso_head // if !0: change ID/title of ISO header 360 ); 361 362 //----------------------------------------------------------------------------- 363 364 int wbfs_touch_disc 365 ( 366 wbfs_disc_t * d, // pointer to an open disc 367 u64 itime, // if != 0: new itime 368 u64 mtime, // if != 0: new mtime 369 u64 ctime, // if != 0: new ctime 370 u64 atime // if != 0: new atime 371 ); 372 373 //----------------------------------------------------------------------------- 374 375 void wbfs_print_block_usage 376 ( 377 FILE * f, // valid output file 378 int indent, // indention of the output 379 const wbfs_t * p, // valid WBFS descriptor 380 bool print_all // false: ignore const lines 381 ); 382 383 //----------------------------------------------------------------------------- 384 385 extern const char wbfs_usage_name_tab[256]; 386 387 void wbfs_print_usage_tab 388 ( 389 FILE * f, // valid output file 390 int indent, // indention of the output 391 const u8 * used_block, // valid pointer to usage table 392 u32 block_used_sz, // size of 'used_block' 393 u32 sector_size, // wbfs sector size 394 bool print_all // false: ignore const lines 395 ); 396 397 //----------------------------------------------------------------------------- 398 399 typedef enum wbfs_check_t 400 { 401 WBFS_CHK_DONE = 0, // finish message 402 403 WBFS_CHK_UNUSED_BLOCK, // block marked used, but is not used [block] 404 WBFS_CHK_MULTIUSED_BLOCK, // block used multiple times [block,count] 405 406 WBFS_CHK_INVALID_BLOCK, // invalid block number [slot,id6,block] 407 WBFS_CHK_FREE_BLOCK_USED, // block marked free but used [slot,id6,block] 408 WBFS_CHK_SHARED_BLOCK, // usage of a shared block by [slot,id6,block,count] 409 410 } wbfs_check_t; 411 412 //----------------------------------------------------------------------------- 413 414 typedef void (*wbfs_check_func) 415 ( 416 wbfs_t * p, // valid WBFS descriptor 417 wbfs_check_t check_mode, // modus 418 int slot, // -1 or related slot index 419 ccp id6, // NULL or pointer to disc ID6 420 int block, // -1 or related block number 421 uint count, // block usage count 422 ccp msg, // clear text message 423 uint msg_len, // strlen(msg) 424 void * param // user defined paramater 425 ); 426 427 //----------------------------------------------------------------------------- 428 429 int wbfs_calc_used_blocks 430 ( 431 wbfs_t * p, // valid WBFS descriptor 432 bool force_reload, // true: definitely reload block #0 433 bool store_block0, // true: don't free block0 434 wbfs_check_func func, // call back function for errors 435 void * param // user defined parameter 436 ); 437 438 //----------------------------------------------------------------------------- 439 440 u32 wbfs_find_free_blocks 441 ( 442 // returns index of first free block or WBFS_NO_BLOCK if not enough blocks free 443 444 wbfs_t * p, // valid WBFS descriptor 445 u32 n_needed // number of needed blocks 446 ); 447 448 //----------------------------------------------------------------------------- 449 450 /*! @return the number of discs inside the paritition */ 451 u32 wbfs_count_discs(wbfs_t*p); 452 453 u32 wbfs_alloc_block 454 ( 455 wbfs_t * p, // valid WBFS descriptor 456 u32 start_block // >0: start search at this block 457 ); 458 459 enumError wbfs_get_disc_info 460 ( 461 wbfs_t * p, // valid wbfs descriptor 462 u32 index, // disc index: 0 .. num_dics-1 463 u8 * header, // header to store data 464 int header_size, // size of 'header' 465 u32 * slot_found, // not NULL: store slot of found disc 466 wd_disc_type_t * disc_type, // not NULL: store disc type 467 wd_disc_attrib_t * disc_attrib, // not NULL: store disc attrib 468 u32 * size4, // not NULL: store 'size>>2' of found disc 469 u32 * n_fragments // number of wbfs fragments 470 ); 471 472 enumError wbfs_get_disc_info_by_slot 473 ( 474 wbfs_t * p, // valid wbfs descriptor 475 u32 slot, // disc index: 0 .. num_dics-1 476 u8 * header, // not NULL: header to store data 477 int header_size, // size of 'header' 478 wd_disc_type_t * disc_type, // not NULL: store disc type 479 wd_disc_attrib_t * disc_attrib, // not NULL: store disc attrib 480 u32 * size4, // not NULL: store 'size>>2' of found disc 481 u32 * n_fragments // number of wbfs fragments 482 ); 483 484 /*! get the number of unuseds block of the partition. 485 to be multiplied by p->wbfs_sec_sz (use 64bit multiplication) to have the number in bytes 486 */ 487 u32 wbfs_get_free_block_count ( wbfs_t * p ); 488 489 /******************* write access ******************/ 490 491 id6_t * wbfs_load_id_list ( wbfs_t * p, int force_reload ); 492 int wbfs_find_slot ( wbfs_t * p, const u8 * disc_id ); 493 494 u32 * wbfs_free_freeblocks ( wbfs_t * p ); 495 u32 * wbfs_load_freeblocks ( wbfs_t * p ); 496 void wbfs_free_block ( wbfs_t * p, u32 bl ); 497 void wbfs_use_block ( wbfs_t * p, u32 bl ); 498 u32 wbfs_find_last_used_block ( wbfs_t * p ); 499 500 /*! add a wii dvd inside the partition 501 @param read_src_wii_disc: a callback to access the wii dvd. offsets are in 32bit, len in bytes! 502 @callback_data: private data passed to the callback 503 @spinner: a pointer to a function that is regulary called to update a progress bar. 504 @sel: selects which partitions to copy. 505 @copy_1_1: makes a 1:1 copy, whenever a game would not use the wii disc format, and some data is hidden outside the filesystem. 506 */ 507 u32 wbfs_add_disc 508 ( 509 wbfs_t * p, 510 wd_read_func_t read_src_wii_disc, 511 void * callback_data, 512 progress_callback_t spinner, 513 const wd_select_t * psel, 514 int copy_1_1 515 ); 516 517 u32 wbfs_add_disc_param ( wbfs_t * p, wbfs_param_t * par ); 518 519 u32 wbfs_add_phantom ( wbfs_t *p, ccp phantom_id, u32 wii_sectors ); 520 521 // remove a disc from partition 522 u32 wbfs_rm_disc 523 ( 524 wbfs_t * p, // valid WBFS descriptor 525 u8 * discid, // id6 to remove. If NULL: remove 'slot' 526 int slot, // slot index, only used if 'discid==NULL' 527 int free_slot_only // true: do not free blocks 528 ); 529 530 /*! trim the file-system to its minimum size 531 This allows to use wbfs as a wiidisc container 532 */ 533 u32 wbfs_trim(wbfs_t*p); 534 535 /* OS specific functions provided by libwbfs_<os>.c */ 536 537 wbfs_t *wbfs_try_open(char *disk, char *partition, int reset); 538 wbfs_t *wbfs_try_open_partition(char *fn, int reset); 539 540 void *wbfs_open_file_for_read(char*filename); 541 void *wbfs_open_file_for_write(char*filename); 542 int wbfs_read_file(void*handle, int len, void *buf); 543 void wbfs_close_file(void *handle); 544 void wbfs_file_reserve_space(void*handle,long long size); 545 void wbfs_file_truncate(void *handle,long long size); 546 int wbfs_read_wii_file(void *_handle, u32 _offset, u32 count, void *buf); 547 int wbfs_write_wii_sector_file(void *_handle, u32 lba, u32 count, void *buf); 548 549 /////////////////////////////////////////////////////////////////////////////// 550 551 #ifdef __cplusplus 552 } 553 #endif /* __cplusplus */ 554 555 #endif // LIBWBFS_H 556