added code for importing a wad into a nand

git-svn-id: http://wiiqt.googlecode.com/svn/trunk@21 389f4c8b-5dfe-645f-db0e-df882bc27289
This commit is contained in:
megazig 2010-12-16 20:07:38 +00:00
parent 86c9d73b1e
commit ba948e0e26
8 changed files with 191 additions and 27 deletions

View File

@ -418,6 +418,80 @@ bool NandDump::InstallNusItem( NusJob job )
return true; return true;
} }
bool NandDump::InstallWad( Wad wad )
{
if( !wad.Tid() || wad.content_count() < 3 )
{
qWarning() << "NandDump::InstallNusItem -> invalid item";
return false;
}
if( !uidDirty )
{
uidDirty = uidMap.GetUid( wad.Tid(), false ) == 0;//only flag the uid as dirty if it has to be, this way it is only flushed if needed
}
uidMap.GetUid( wad.Tid() );
QString p = QString( "%1" ).arg( wad.Tid(), 16, 16, QChar( '0' ) );
p.insert( 8 ,"/" );
p.prepend( "/title/" );
QString path = basePath + p + "/content";
if( !QFileInfo( path ).exists() && !QDir().mkpath( path ) )
return false;
path = basePath + p + "/data";
if( !QFileInfo( path ).exists() && !QDir().mkpath( path ) )
return false;
QByteArray ba = wad.getTmd();
if( !InstallTmd( ba, wad.Tid() ) )
return false;
Tmd t( ba );
ba = wad.getTik();
Ticket ti( ba );
if( !InstallTicket( ba, wad.Tid() ) )
{
AbortInstalling( wad.Tid() );
return false;
}
quint32 cnt = qFromBigEndian( t.payload()->num_contents );
if( cnt != wad.content_count() )
{
AbortInstalling( wad.Tid() );
return false;
}
for( quint32 i = 0; i < cnt; i++ )
{
QByteArray decData = wad.Content(i);
if( t.Type( i ) == 0x8001 )
{
if( !InstallSharedContent( decData, t.Hash( i ) ) )
{
AbortInstalling( wad.Tid() );
return false;
}
}
else if( t.Type( i ) == 1 )
{
if( !InstallPrivateContent( decData, wad.Tid(), t.Cid( i ) ) )
{
AbortInstalling( wad.Tid() );
return false;
}
}
else//unknown content type
{
qWarning() << "NandDump::InstallWad -> unknown content type";
AbortInstalling( wad.Tid() );
return false;
}
}
return true;
}
QMap< quint64, quint16 > NandDump::GetInstalledTitles() QMap< quint64, quint16 > NandDump::GetInstalledTitles()
{ {
QMap< quint64, quint16 >ret; QMap< quint64, quint16 >ret;

View File

@ -5,6 +5,7 @@
#include "includes.h" #include "includes.h"
#include "sharedcontentmap.h" #include "sharedcontentmap.h"
#include "uidmap.h" #include "uidmap.h"
#include "wad.h"
struct SaveGame//struct to hold save data struct SaveGame//struct to hold save data
{ {
@ -54,6 +55,10 @@ public:
//returns false if something went wrong //returns false if something went wrong
bool InstallNusItem( NusJob job ); bool InstallNusItem( NusJob job );
//installs a title to the nand dump from a wad
//returns false if something went wrong
bool InstallWad( Wad wad );
//tries to delete a title from the nand dump //tries to delete a title from the nand dump
//deleteData gives the option to just delete the title and leave behind its data //deleteData gives the option to just delete the title and leave behind its data
bool DeleteTitle( quint64 tid, bool deleteData = false ); bool DeleteTitle( quint64 tid, bool deleteData = false );

View File

@ -618,7 +618,7 @@ QMap< quint64, quint16 > NusDownloader::List31j()
//titles.insert( 0x100000025ull, 2070 );//37v2070//3.1u has this one but not 3.1j?? //titles.insert( 0x100000025ull, 2070 );//37v2070//3.1u has this one but not 3.1j??
titles.insert( 0x1000248415941ull, 0x1 );//photo2v1 titles.insert( 0x1000248415941ull, 0x1 );//photo2v1
titles.insert( 0x1000848414B4aull, 0 );//EULA - HAKJ titles.insert( 0x1000848414B4aull, 0 );//EULA - HAKJ
titles.insert( 0x100024841464a, 0x7 ); // forcast v7 HAFJ titles.insert( 0x100024841464aull, 0x7 );// forcast v7 HAFJ
titles.insert( 0x100000101ull, 5 );//miosv5 titles.insert( 0x100000101ull, 5 );//miosv5
titles.insert( 0x1000848414C4aull, 0x2 );//regsel //region select isnt in the paper mario update, but putting it here just to be safe titles.insert( 0x1000848414C4aull, 0x2 );//regsel //region select isnt in the paper mario update, but putting it here just to be safe
titles.insert( 0x1000248414341ull, 0x2 );//nigaoeNRv2 - MII titles.insert( 0x1000248414341ull, 0x2 );//nigaoeNRv2 - MII

View File

@ -18,16 +18,24 @@ Wad::Wad( const QByteArray stuff )
b.open( QIODevice::ReadOnly ); b.open( QIODevice::ReadOnly );
quint32 tmp; quint32 tmp;
b.read( (char*)&tmp, 4 ); if(b.read( (char*)&tmp, 4 ) != 4)
{
b.close();
Err( "Can't read header size" );
return;
}
if( qFromBigEndian( tmp ) != 0x20 ) if( qFromBigEndian( tmp ) != 0x20 )
{ {
b.close(); b.close();
hexdump(stuff, 0, 0x10);
Err( "Bad header size" ); Err( "Bad header size" );
return; return;
} }
b.read( (char*)&tmp, 4 ); b.read( (char*)&tmp, 4 );
tmp = qFromBigEndian( tmp ); tmp = qFromBigEndian( tmp );
if( tmp != 0x49730000 && tmp != 0x69620000 && tmp != 0x426b0000 ) if( tmp != 0x49730000 &&
tmp != 0x69620000 &&
tmp != 0x426b0000 )
{ {
b.close(); b.close();
hexdump( stuff, 0, 0x40 ); hexdump( stuff, 0, 0x40 );
@ -184,6 +192,16 @@ void Wad::SetGlobalCert( const QByteArray &stuff )
globalCert = stuff; globalCert = stuff;
} }
const QByteArray Wad::getTmd()
{
return tmdData;
}
const QByteArray Wad::getTik()
{
return tikData;
}
const QByteArray Wad::Content( quint16 i ) const QByteArray Wad::Content( quint16 i )
{ {
if( tmdData.isEmpty() || tikData.isEmpty() ) if( tmdData.isEmpty() || tikData.isEmpty() )
@ -213,6 +231,11 @@ const QByteArray Wad::Content( quint16 i )
return decData; return decData;
} }
quint32 Wad::content_count()
{
return partsEnc.size();
}
void Wad::Err( QString str ) void Wad::Err( QString str )
{ {
ok = false; ok = false;

View File

@ -51,9 +51,18 @@ public:
//get all the parts of this wad put together in a wad ready for writing to disc or whatever //get all the parts of this wad put together in a wad ready for writing to disc or whatever
const QByteArray Data( quint32 magicWord = 0x49730000, const QByteArray footer = QByteArray() ); const QByteArray Data( quint32 magicWord = 0x49730000, const QByteArray footer = QByteArray() );
//get the tmd for the wad
const QByteArray getTmd();
//get the tik for the wad
const QByteArray getTik();
//get the decrypted data from a content //get the decrypted data from a content
const QByteArray Content( quint16 i ); const QByteArray Content( quint16 i );
//get the number of contents
quint32 content_count();
//get the last error encountered while trying to do something //get the last error encountered while trying to do something
const QString LastError(){ return errStr; } const QString LastError(){ return errStr; }

View File

@ -313,6 +313,52 @@ void MainWindow::on_actionFlush_triggered()
nand.Flush(); nand.Flush();
} }
//nand-dump -> ImportWad
void MainWindow::on_actionImportWad_triggered()
{
if( nand.GetPath() != ui->lineEdit_nandPath->text() &&
!nand.SetPath( ui->lineEdit_nandPath->text() ) )
{
ShowMessage( tr( "<b>Error setting the basepath of the nand to %1</b>" ).arg( QFileInfo( ui->lineEdit_nandPath->text() ).absoluteFilePath() ) );
return;
}
QString fn = QFileDialog::getSaveFileName(this,
tr("Wad files(*.wad)"),
QCoreApplication::applicationDirPath(),
tr("WadFiles (*.wad)"));
if(fn == "") return;
QFile f(fn);
if(!f.open( QIODevice::ReadOnly)) {
ShowMessage( tr( "Error opening %1" ).arg( fn ) );
return;
}
qint64 len = f.size();
char* buffer = new char[len];
qint64 read = f.read(buffer, len);
f.close();
hexdump(buffer, 0x40);
if(read != len) {
ShowMessage( tr( "Error reading %1" ).arg( fn ) );
free(buffer);
return;
}
QByteArray data(buffer, len);
free(buffer);
Wad wad(data);
if( !wad.IsOk() ) {
ShowMessage( tr( "Wad data not ok" ) );;
return;
}
bool ok = nand.InstallWad( wad );
if( ok )
ShowMessage( tr( "Installed %1 title to nand" ).arg( wad.WadName() ) );
else
ShowMessage( tr( "<b>Error %1 title to nand</b>" ).arg( wad.WadName() ) );
}
//save a NUS job to a folder //save a NUS job to a folder
void MainWindow::SaveJobToFolder( NusJob job ) void MainWindow::SaveJobToFolder( NusJob job )
{ {

View File

@ -41,6 +41,7 @@ public slots:
private slots: private slots:
void on_actionFlush_triggered(); void on_actionFlush_triggered();
void on_actionSetting_txt_triggered(); void on_actionSetting_txt_triggered();
void on_actionImportWad_triggered();
void on_pushButton_wad_clicked(); void on_pushButton_wad_clicked();
void on_pushButton_decFolder_clicked(); void on_pushButton_decFolder_clicked();
void on_pushButton_nandPath_clicked(); void on_pushButton_nandPath_clicked();

View File

@ -218,6 +218,7 @@
</property> </property>
<addaction name="actionSetting_txt"/> <addaction name="actionSetting_txt"/>
<addaction name="actionFlush"/> <addaction name="actionFlush"/>
<addaction name="actionImportWad"/>
</widget> </widget>
<addaction name="menuNand_Dump"/> <addaction name="menuNand_Dump"/>
</widget> </widget>
@ -240,6 +241,11 @@
<string>Flush</string> <string>Flush</string>
</property> </property>
</action> </action>
<action name="actionImportWad">
<property name="text">
<string>Import Wad</string>
</property>
</action>
</widget> </widget>
<layoutdefault spacing="6" margin="11"/> <layoutdefault spacing="6" margin="11"/>
<resources/> <resources/>