2010-12-08 08:26:18 +01:00
# ifndef NANDBIN_H
# define NANDBIN_H
# include "includes.h"
2010-12-14 06:58:44 +01:00
# include "blocks0to7.h"
2010-12-15 09:11:56 +01:00
# include "nandspare.h"
2010-12-08 08:26:18 +01:00
struct fst_t
{
2010-12-10 04:50:08 +01:00
quint8 filename [ 0xc ] ;
2010-12-08 08:26:18 +01:00
quint8 attr ;
2010-12-17 00:37:30 +01:00
quint8 wtf ;
2010-12-08 08:26:18 +01:00
quint16 sub ;
quint16 sib ;
quint32 size ;
quint32 uid ;
quint16 gid ;
quint32 x3 ;
2010-12-15 09:11:56 +01:00
quint16 fst_pos ; //not really part of the nand structure, but needed when calculating hmac data
2010-12-08 08:26:18 +01:00
} ;
// class to deal with an encrypted wii nand dump
// basic usage... create an object, set a path, call InitNand. then you can get the detailed list of entries with GetTree()
// extract files with GetFile()
2010-12-17 00:37:30 +01:00
//! so far, all functions for writing to the nand are just dummies. i have only run a few test with them, but now actually used them to write to a nand
//! dont try to use them yet
2010-12-10 04:50:08 +01:00
//once InitNand() is called, you can get the contents of the nand in a nice QTreeWidgetItem* with GetTree()
2010-12-08 08:26:18 +01:00
class NandBin : public QObject
{
Q_OBJECT
public :
2010-12-10 04:50:08 +01:00
//creates a NandBin object. if a path is given, it will call SetPath() on that path. though you cant check the return value
2010-12-08 08:26:18 +01:00
NandBin ( QObject * parent = 0 , const QString & path = QString ( ) ) ;
2010-12-10 04:50:08 +01:00
//destroys this object, and all its used resources ( closes the nand.bin file and deletes the filetree )
2010-12-08 08:26:18 +01:00
~ NandBin ( ) ;
2010-12-10 04:50:08 +01:00
//sets the path of this object to path. returns false if it cannot open an already existing file
//keys.bin should be in this same path if they are to be used
2010-12-08 08:26:18 +01:00
bool SetPath ( const QString & path ) ;
2010-12-08 09:05:23 +01:00
//try to read the filesystem and create a tree from its contents
2010-12-10 04:50:08 +01:00
//this takes care of the stuff like reading the keys, finding teh superblock, and creating the QTreeWidgetItem* tree
2010-12-08 09:05:23 +01:00
//icons given here will be the ones used when asking for that tree
bool InitNand ( QIcon dirs = QIcon ( ) , QIcon files = QIcon ( ) ) ;
2010-12-08 08:26:18 +01:00
//get a root item containing children that are actually entries in the nand dump
//the root itself is just a container to hold them all and can be deleted once its children are taken
2010-12-10 04:50:08 +01:00
//! all returned items are cloned and it is up to you to delete them !
//text is assigned to the items as follows...
// 0 name
// 1 entry #
// 2 size
// 3 uid
// 4 gid
// 5 x3
// 6 mode
// 7 attr
2010-12-08 08:26:18 +01:00
QTreeWidgetItem * GetTree ( ) ;
//extracts an item( and all its children ) to a directory
//this function is BLOCKING and will block the current thread, so if done in the gui thread, it will freeze your GUI till it returns
bool ExtractToDir ( QTreeWidgetItem * item , const QString & path ) ;
//print a little info about the free space
void ShowInfo ( ) ;
//set this to change ":" in names to "-" on etracting.
//theres more illegal characters in FAT, but thes seems to be the only one that happens on the nand FS
void SetFixNamesForFAT ( bool fix = true ) ;
2010-12-10 04:50:08 +01:00
//returns the data that makes up the file of a given entry#
QByteArray GetFile ( quint16 entry ) ;
//get data for a given path
//! this function is slower than the above one, as it first iterates through the QTreeWidgetItems till it finds the right ono
//! and then end up calling the above one anyways.
//the path should be a file, not folder
//returns an empty array on failure
//path should start with "/" and items should be delimited by "/"
//ie... /title/00000001/00000002/data/setting.txt
const QByteArray GetData ( const QString & path ) ;
2010-12-11 11:12:50 +01:00
//returns the fats for this nand.
const QList < quint16 > GetFats ( ) { return fats ; }
//get the fats for a given file
const QList < quint16 > GetFatsForFile ( quint16 i ) ;
2010-12-17 00:37:30 +01:00
//recurse folders and files and get all fats used for them
//! this is probably a more expensive function than you want to use
//! it was added only to aid in checking for bugs and lost clusters
const QList < quint16 > GetFatsForEntry ( quint16 i ) ;
//use the above function to search and display lost clusters
void ShowLostClusters ( ) ;
2010-12-14 06:58:44 +01:00
const Blocks0to7 BootBlocks ( ) { return bootBlocks ; }
const QList < Boot2Info > Boot2Infos ( ) ;
quint8 Boot1Version ( ) ;
2010-12-15 09:11:56 +01:00
QByteArray GetPage ( quint32 pageNo , bool withEcc = false ) ;
2010-12-17 00:37:30 +01:00
//create new entry
//returns the index of the entry on success, or 0 on error
quint16 CreateEntry ( const QString & path , quint32 uid , quint16 gid , quint8 attr , quint8 user_perm , quint8 group_perm , quint8 other_perm ) ;
//delete a file/folder
bool Delete ( const QString & path ) ;
//sets the data for a given file ( overwrites existing data )
bool SetData ( quint16 idx , const QByteArray data ) ;
//overloads the above function
bool SetData ( const QString & path , const QByteArray data ) ;
2010-12-18 22:07:58 +01:00
//write the current changes to the metadata( if you dont do this, then none of the other stuff youve done wont be saved )
bool WriteMetaData ( ) ;
//functions to verify spare data
bool CheckEcc ( quint32 pageNo ) ;
bool CheckHmacData ( quint16 entry ) ;
//verify hmac stuff for a given supercluster
//expects 0x7f00 - 0x7ff0
bool CheckHmacMeta ( quint16 clNo ) ;
2010-12-10 04:50:08 +01:00
2010-12-08 08:26:18 +01:00
private :
QByteArray key ;
qint32 loc_super ;
qint32 loc_fat ;
qint32 loc_fst ;
2010-12-18 22:07:58 +01:00
quint16 currentSuperCluster ;
quint32 superClusterVersion ;
2010-12-08 08:26:18 +01:00
QString extractPath ;
2010-12-10 04:50:08 +01:00
QString nandPath ;
2010-12-08 08:26:18 +01:00
QFile f ;
int type ;
bool fatNames ;
2010-12-08 09:05:23 +01:00
QIcon groupIcon ;
QIcon keyIcon ;
2010-12-08 08:26:18 +01:00
2010-12-15 09:11:56 +01:00
NandSpare spare ; //used to handle the hmac mumbojumbo
2010-12-11 11:12:50 +01:00
//read all the fst and remember them rather than seeking back and forth in the file all the time
// uses ~120KiB RAM
bool fstInited ;
fst_t fsts [ 0x17ff ] ;
//cache the fat to keep from having to look them up repeatedly
// uses ~64KiB
QList < quint16 > fats ;
2010-12-08 08:26:18 +01:00
int GetDumpType ( quint64 fileSize ) ;
bool GetKey ( int type ) ;
2010-12-15 09:11:56 +01:00
QByteArray ReadKeyfile ( QString path , quint8 type ) ; //type 0 for nand key, type 1 for hmac
2010-12-08 08:26:18 +01:00
qint32 FindSuperblock ( ) ;
quint16 GetFAT ( quint16 fat_entry ) ;
fst_t GetFST ( quint16 entry ) ;
QByteArray GetCluster ( quint16 cluster_entry , bool decrypt = true ) ;
QByteArray GetFile ( fst_t fst ) ;
QString FstName ( fst_t fst ) ;
2010-12-08 09:05:23 +01:00
bool ExtractFST ( quint16 entry , const QString & path , bool singleFile = false ) ;
2010-12-08 08:26:18 +01:00
bool ExtractDir ( fst_t fst , QString parent ) ;
bool ExtractFile ( fst_t fst , QString parent ) ;
2010-12-17 00:37:30 +01:00
QTreeWidgetItem * CreateItem ( QTreeWidgetItem * parent , const QString & name , quint32 size , quint16 entry , quint32 uid , quint32 gid , quint32 x3 , quint8 attr , quint8 wtf ) ;
2010-12-08 08:26:18 +01:00
QTreeWidgetItem * root ;
bool AddChildren ( QTreeWidgetItem * parent , quint16 entry ) ;
2010-12-10 04:50:08 +01:00
QTreeWidgetItem * ItemFromPath ( const QString & path ) ;
QTreeWidgetItem * FindItem ( const QString & s , QTreeWidgetItem * parent ) ;
2010-12-08 08:26:18 +01:00
2010-12-14 06:58:44 +01:00
//holds info about boot1 & 2
Blocks0to7 bootBlocks ;
2010-12-15 09:11:56 +01:00
bool WriteCluster ( quint32 pageNo , const QByteArray data , const QByteArray hmac ) ;
bool WriteDecryptedCluster ( quint32 pageNo , const QByteArray data , fst_t fst , quint16 idx ) ;
bool WritePage ( quint32 pageNo , const QByteArray data ) ;
2010-12-17 00:37:30 +01:00
quint16 CreateNode ( const QString & name , quint32 uid , quint16 gid , quint8 attr , quint8 user_perm , quint8 group_perm , quint8 other_perm ) ;
bool DeleteItem ( QTreeWidgetItem * item ) ;
//find a parent entry for a path to be created - "/title/00000001" should give the entry for "/title"
QTreeWidgetItem * GetParent ( const QString & path ) ;
QTreeWidgetItem * ItemFromEntry ( quint16 i , QTreeWidgetItem * parent = NULL ) ;
QTreeWidgetItem * ItemFromEntry ( const QString & i , QTreeWidgetItem * parent = NULL ) ;
2010-12-18 22:07:58 +01:00
2010-12-08 08:26:18 +01:00
signals :
2010-12-10 04:50:08 +01:00
//connect to these to receive messages from this object
2010-12-08 08:26:18 +01:00
void SendError ( QString ) ;
void SendText ( QString ) ;
} ;
# endif // NANDBIN_H