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