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_WBFS_INTERFACE_H 38 #define WIT_WBFS_INTERFACE_H 1 39 40 #include <stdio.h> 41 42 #include "types.h" 43 #include "lib-sf.h" 44 #include "iso-interface.h" 45 46 // 47 /////////////////////////////////////////////////////////////////////////////// 48 /////////////// some constants /////////////// 49 /////////////////////////////////////////////////////////////////////////////// 50 51 enum 52 { 53 MIN_WBFS_SIZE = 10000000, // minimal WBFS partition size 54 MIN_WBFS_SIZE_MIB = 100, // minimal WBFS partition size 55 MAX_WBFS = 999, // maximal number of WBFS partitions 56 }; 57 58 // 59 /////////////////////////////////////////////////////////////////////////////// 60 /////////////// partitions /////////////// 61 /////////////////////////////////////////////////////////////////////////////// 62 63 typedef enum enumPartMode 64 { 65 PM_UNKNOWN, // not analyzed yet 66 PM_IGNORE, // ignore this entry 67 PM_CANT_READ, // can't read file 68 PM_WRONG_TYPE, // type must be regular or block 69 PM_NO_WBFS_MAGIC, // no WBFS Magic found 70 PM_WBFS_MAGIC_FOUND, // WBFS Magic found, further test needed 71 PM_WBFS_INVALID, // WBFS Magic found, but not a legal WBFS 72 // PM_WBFS_CORRUPTED, // WBFS with errors found 73 PM_WBFS, // WBFS found, no errors detected 74 75 } enumPartMode; 76 77 //----------------------------------------------------------------------------- 78 79 typedef enum enumPartSource 80 { 81 PS_PARAM, // set by --part or by parameter 82 PS_AUTO, // set by scanning because --auto is set 83 PS_AUTO_IGNORE, // like PS_AUTO, but ignore if can't be opened 84 PS_ENV, // set by scanninc env 'WWT_WBFS' 85 86 } enumPartSource; 87 88 //----------------------------------------------------------------------------- 89 90 typedef struct PartitionInfo_t 91 { 92 int part_index; 93 94 ccp path; 95 ccp real_path; 96 enumFileMode filemode; 97 bool is_checked; 98 bool ignore; 99 u32 hss; 100 u64 file_size; 101 u64 disk_usage; 102 u32 wbfs_hss; 103 u32 wbfs_wss; 104 u64 wbfs_size; 105 enumPartMode part_mode; 106 enumPartSource source; 107 108 struct WDiscList_t * wlist; 109 struct PartitionInfo_t * next; 110 111 } PartitionInfo_t; 112 113 //----------------------------------------------------------------------------- 114 115 extern int wbfs_count; 116 117 extern PartitionInfo_t * first_partition_info; 118 extern PartitionInfo_t ** append_partition_info; 119 120 extern int pi_count; 121 extern PartitionInfo_t * pi_list[MAX_WBFS+1]; 122 extern struct WDiscList_t pi_wlist; 123 extern u32 pi_free_mib; 124 125 extern int opt_part; 126 extern int opt_auto; 127 extern int opt_all; 128 129 PartitionInfo_t * CreatePartitionInfo ( ccp path, enumPartSource source ); 130 int AddPartition ( ccp arg, int unused ); 131 int ScanPartitions ( bool all ); 132 void AddEnvPartitions(); 133 enumError AnalyzePartitions ( FILE * outfile, bool non_found_is_ok, bool scan_wbfs ); 134 void ScanPartitionGames(); 135 136 // 137 /////////////////////////////////////////////////////////////////////////////// 138 /////////////// wbfs structs /////////////// 139 /////////////////////////////////////////////////////////////////////////////// 140 141 typedef struct WBFS_t 142 { 143 // handles 144 145 SuperFile_t * sf; // attached super file 146 bool sf_alloced; // true: 'sf' is alloced 147 bool is_growing; // true: wbfs is of type growing 148 bool disc_sf_opened; // true: OpenWDiscSF() opened a disc 149 bool cache_candidate; // true: wbfs is a cache candidate 150 bool is_wbfs_file; // true: is a wbfs file (exact 1 disc at slot #0) 151 wbfs_t * wbfs; // the pure wbfs handle 152 wbfs_disc_t * disc; // the wbfs disc handle 153 int disc_slot; // >=0: last opened slot 154 155 // infos calced by CalcWBFSUsage() 156 157 u32 used_discs; 158 u32 free_discs; 159 u32 total_discs; 160 161 u32 free_blocks; 162 u32 used_mib; 163 u32 free_mib; 164 u32 total_mib; 165 166 } WBFS_t; 167 168 extern bool wbfs_cache_enabled; 169 170 //----------------------------------------------------------------------------- 171 172 typedef struct CheckDisc_t 173 { 174 char id6[7]; // id of the disc 175 char no_blocks; // no valid blocks assigned 176 u16 bl_fbt; // num of blocks marked free in fbt 177 u16 bl_overlap; // num of blocks that overlaps other discs 178 u16 bl_invalid; // num of blocks with invalid blocks 179 u16 err_count; // total count of errors 180 181 char no_iinfo_count; // no inode defined (not a error) 182 183 } CheckDisc_t; 184 185 //----------------------------------------------------------------------------- 186 187 typedef struct CheckWBFS_t 188 { 189 // handles 190 191 WBFS_t * wbfs; // attached WBFS 192 193 // data 194 195 off_t fbt_off; // offset of fbt 196 size_t fbt_size; // size of fbt 197 u32 * cur_fbt; // current free blocks table (1 bit per block) 198 u32 * good_fbt; // calculated free blocks table (1 bit per block) 199 200 u8 * ubl; // used blocks (1 byte per block), copy of fbt 201 u8 * blc; // block usage counter 202 CheckDisc_t * disc; // disc list 203 204 // statistics 205 206 u32 err_fbt_used; // number of wrong used marked blocks 207 u32 err_fbt_free; // number of wrong free marked blocks 208 u32 err_fbt_free_wbfs0; // number of 'err_fbt_free' depend on WBFS v0 209 u32 err_no_blocks; // total num of 'no_blocks' errors 210 u32 err_bl_overlap; // total num of 'bl_overlap' errors 211 u32 err_bl_invalid; // total num of 'bl_invalid' errors 212 u32 err_total; // total of all above 213 214 u32 no_iinfo_count; // total number of missing inode infos (informative) 215 u32 invalid_disc_count; // total number of invalid games 216 217 enumError err; // status: OK | WARNING | WBFS_INVALID 218 219 } CheckWBFS_t; 220 221 /////////////////////////////////////////////////////////////////////////////// 222 223 extern wbfs_balloc_mode_t opt_wbfs_alloc; 224 int ScanOptWbfsAlloc ( ccp arg ); 225 226 // 227 /////////////////////////////////////////////////////////////////////////////// 228 /////////////// Analyze WBFS /////////////// 229 /////////////////////////////////////////////////////////////////////////////// 230 231 typedef enum enumAnalyzeWBFS 232 { 233 AW_NONE, // invalid 234 235 AW_HEADER, // WBFS header found 236 AW_INODES, // Inodes with WBFS info found 237 AW_DISCS, // Discs found 238 AW_CALC, // Calculation 239 AW_OLD_CALC, // Old and buggy calculation 240 241 AW__N, // Number of previous values 242 243 AW_MAX_RECORD = 20 // max number of stored records 244 245 } enumAnalyzeWBFS; 246 247 //----------------------------------------------------------------------------- 248 249 typedef struct AWRecord_t 250 { 251 enumAnalyzeWBFS status; // status of search 252 char title[11]; // short title of record 253 char info[30]; // additional info 254 255 bool magic_found; // true: magic found 256 u8 wbfs_version; // source: wbfs_head::wbfs_version 257 258 u32 hd_sectors; // source: wbfs_head::n_hd_sec 259 u32 hd_sector_size; // source: wbfs_head::hd_sec_sz_s 260 u32 wbfs_sectors; // source: wbfs_t::n_wbfs_sec 261 u32 wbfs_sector_size; // source: wbfs_head::wbfs_sec_sz_s 262 u32 max_disc; // source: wbfs_t::max_disc 263 u32 disc_info_size; // source: wbfs_t::disc_info_sz 264 265 } AWRecord_t; 266 267 //----------------------------------------------------------------------------- 268 269 typedef struct AWData_t 270 { 271 uint n_record; // number of used records 272 AWRecord_t rec[AW_MAX_RECORD]; // results of sub search 273 274 } AWData_t; 275 276 //----------------------------------------------------------------------------- 277 278 int AnalyzeWBFS ( AWData_t * ad, File_t * f ); 279 int PrintAnalyzeWBFS 280 ( 281 FILE * out, // valid output stream 282 int indent, // indent of output 283 AWData_t * awd, // valid pointer 284 int print_calc // 0: suppress calculated values 285 // 1: print calculated values if other values available 286 // 2: print calculated values 287 ); 288 289 // 290 /////////////////////////////////////////////////////////////////////////////// 291 /////////////// ID handling /////////////// 292 /////////////////////////////////////////////////////////////////////////////// 293 294 enumError ScanParamID6 295 ( 296 StringField_t * select_list, // append all results to this list 297 const ParamList_t * param // first param of a list to check 298 ); 299 300 int AppendListID6 // returns number of inserted ids 301 ( 302 StringField_t * id6_list, // append all selected IDs in this list 303 const StringField_t * select_list, // selector list 304 WBFS_t * wbfs // open WBFS file 305 ); 306 307 int AppendWListID6 // returns number of inserted ids 308 ( 309 StringField_t * id6_list, // append all selected IDs in this list 310 const StringField_t * select_list, // selector list 311 WDiscList_t * wlist, // valid list 312 bool add_to_title_db // true: add to title DB if unkown 313 ); 314 315 bool MatchRulesetID 316 ( 317 const StringField_t * select_list, // selector list 318 ccp id // id to compare 319 ); 320 321 bool MatchPatternID // returns TRUE if pattern and id match 322 ( 323 ccp pattern, // pattern, '.' is a wildcard 324 ccp id // id to compare 325 ); 326 327 enumError CheckParamRename ( bool rename_id, bool allow_plus, bool allow_index ); 328 329 // 330 /////////////////////////////////////////////////////////////////////////////// 331 /////////////// discs & wbfs interface /////////////// 332 /////////////////////////////////////////////////////////////////////////////// 333 334 enumError CloseWBFSCache(); 335 336 void InitializeWBFS ( WBFS_t * w ); 337 enumError ResetWBFS ( WBFS_t * w ); 338 enumError OpenParWBFS ( WBFS_t * w, SuperFile_t * sf, bool print_err, wbfs_param_t * par ); 339 enumError SetupWBFS ( WBFS_t * w, SuperFile_t * sf, bool print_err, 340 int sector_size, bool recover ); 341 enumError CreateGrowingWBFS 342 ( WBFS_t * w, SuperFile_t * sf, off_t size, int sector_size ); 343 344 enumError OpenWBFS 345 ( 346 WBFS_t *w, // valid data structure 347 ccp filename, // filename to open 348 bool open_modify, // true: open read+write 349 bool print_err, // true: pprint error messages 350 wbfs_param_t *par // NULL or parameter record 351 ); 352 353 enumError FormatWBFS ( WBFS_t * w, ccp filename, bool print_err, 354 wbfs_param_t * par, int sector_size, bool recover ); 355 enumError RecoverWBFS ( WBFS_t * w, ccp fname, bool testmode ); 356 enumError TruncateWBFS ( WBFS_t * w ); 357 358 enumError CalcWBFSUsage ( WBFS_t * w ); 359 enumError SyncWBFS ( WBFS_t * w, bool force_sync ); 360 enumError ReloadWBFS ( WBFS_t * w ); 361 362 enumError OpenPartWBFS ( WBFS_t * w, struct PartitionInfo_t * info, bool open_modify ); 363 enumError GetFirstWBFS ( WBFS_t * w, struct PartitionInfo_t ** info, bool open_modify ); 364 enumError GetNextWBFS ( WBFS_t * w, struct PartitionInfo_t ** info, bool open_modify ); 365 366 void LogOpenedWBFS 367 ( 368 WBFS_t * w, // valid and opened WBFS 369 int count, // wbfs counter, 1 based 370 // if NULL: neither 'count' nor 'total' are printed 371 int total, // total wbfs count to handle 372 // if NULL: don't print info 373 ccp path // path of sourcefile 374 // if NULL: use 'w->sf->f.fname' (real path) 375 ); 376 377 void LogCloseWBFS 378 ( 379 WBFS_t * w, // valid and opened WBFS 380 int count, // wbfs counter, 1 based 381 // if NULL: neither 'count' nor 'total' are printed 382 int total, // total wbfs count to handle 383 // if NULL: don't print info 384 ccp path // path of sourcefile 385 // if NULL: use 'w->sf->f.fname' (real path) 386 ); 387 388 uint CountWBFS (); 389 uint GetIdWBFS ( WBFS_t * w, IdField_t * idf ); 390 391 enumError DumpWBFS 392 ( 393 WBFS_t * wbfs, // valid WBFS 394 FILE * f, // valid output file 395 int indent, // indention of output 396 ShowMode show_mode, // what should be printed 397 int dump_level, // dump level: 0..3, ignored if show_mode is set 398 int view_invalid_discs, // view invalid discs too 399 CheckWBFS_t * ck // not NULL: dump only discs with errors 400 ); 401 402 extern StringField_t wbfs_part_list; 403 u32 FindWBFSPartitions(); 404 405 //----------------------------------------------------------------------------- 406 407 void InitializeCheckWBFS ( CheckWBFS_t * ck ); 408 void ResetCheckWBFS ( CheckWBFS_t * ck ); 409 enumError CheckWBFS ( CheckWBFS_t * ck, WBFS_t * w, int verbose, FILE * f, int indent ); 410 enumError AutoCheckWBFS ( WBFS_t * w, bool ignore_check, int indent ); 411 412 enumError PrintCheckedWBFS ( CheckWBFS_t * ck, FILE * f, int indent ); 413 414 enumError RepairWBFS 415 ( CheckWBFS_t * ck, int testmode, RepairMode rm, int verbose, FILE * f, int indent ); 416 enumError CheckRepairWBFS 417 ( WBFS_t * w, int testmode, RepairMode rm, int verbose, FILE * f, int indent ); 418 enumError RepairFBT 419 ( WBFS_t * w, int testmode, FILE * f, int indent ); 420 421 // returns true if 'good_ftb' differ from 'cur_ftb' 422 bool CalcFBT ( CheckWBFS_t * ck ); 423 424 //----------------------------------------------------------------------------- 425 426 void InitializeWDiscInfo ( WDiscInfo_t * dinfo ); 427 enumError ResetWDiscInfo ( WDiscInfo_t * dinfo ); 428 enumError GetWDiscInfo ( WBFS_t * w, WDiscInfo_t * dinfo, int disc_index ); 429 enumError GetWDiscInfoBySlot ( WBFS_t * w, WDiscInfo_t * dinfo, u32 disc_slot ); 430 enumError FindWDiscInfo ( WBFS_t * w, WDiscInfo_t * dinfo, ccp id6 ); 431 432 enumError LoadIsoHeader ( WBFS_t * w, wd_header_t * iso_header, wbfs_disc_t * disc ); 433 434 void CalcWDiscInfo ( WDiscInfo_t * winfo, SuperFile_t * sf /* NULL possible */ ); 435 436 enumError DumpWDiscInfo 437 ( WDiscInfo_t * dinfo, wd_header_t * iso_header, FILE * f, int indent ); 438 439 //----------------------------------------------------------------------------- 440 441 WDiscList_t * GenerateWDiscList ( WBFS_t * w, int part_index ); 442 void InitializeWDiscList ( WDiscList_t * wlist ); 443 void ResetWDiscList ( WDiscList_t * wlist ); 444 void FreeWDiscList ( WDiscList_t * wlist ); 445 446 WDiscListItem_t * AppendWDiscList ( WDiscList_t * wlist, WDiscInfo_t * winfo ); 447 void CopyWDiscInfo ( WDiscListItem_t * item, WDiscInfo_t * winfo ); 448 449 void ReverseWDiscList ( WDiscList_t * wlist ); 450 void SortWDiscList ( WDiscList_t * wlist, enum SortMode sort_mode, 451 enum SortMode default_sort_mode, int unique ); 452 453 void PrintSectWDiscListItem ( FILE * out, WDiscListItem_t * witem, ccp def_fname ); 454 455 //----------------------------------------------------------------------------- 456 457 enumError OpenWDiscID6 ( WBFS_t * w, ccp id6 ); 458 enumError OpenWDiscIndex( WBFS_t * w, u32 index ); 459 enumError OpenWDiscSlot ( WBFS_t * w, u32 slot, bool force_open ); 460 enumError OpenWDiscSF ( WBFS_t * w ); 461 enumError CloseWDiscSF ( WBFS_t * w ); 462 enumError CloseWDisc ( WBFS_t * w ); 463 enumError ExistsWDisc ( WBFS_t * w, ccp id6 ); 464 465 wd_header_t * GetWDiscHeader ( WBFS_t * w ); 466 467 enumError AddWDisc ( WBFS_t * w, SuperFile_t * sf, const wd_select_t * psel ); 468 469 enumError RemoveWDisc 470 ( 471 WBFS_t * w, // valid WBFS descriptor 472 ccp id6, // id6 to remove. If NULL: remove 'slot' 473 int slot, // slot index, only used if 'discid==NULL' 474 int free_slot_only // true: do not free blocks 475 ); 476 477 enumError RenameWDisc ( WBFS_t * w, ccp new_id6, ccp new_title, 478 bool change_wbfs_head, bool change_iso_head, int verbose, int testmode ); 479 480 int RenameISOHeader ( void * data, ccp fname, 481 ccp new_id6, ccp new_title, int verbose, int testmode ); 482 483 // 484 /////////////////////////////////////////////////////////////////////////////// 485 /////////////// E N D /////////////// 486 /////////////////////////////////////////////////////////////////////////////// 487 488 #endif // WIT_WBFS_INTERFACE_H 489