mirror of
https://github.com/martravi/wiiqt6.git
synced 2024-11-26 14:44:20 +01:00
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:
parent
86c9d73b1e
commit
ba948e0e26
@ -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;
|
||||||
|
@ -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 );
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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; }
|
||||||
|
|
||||||
|
@ -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 )
|
||||||
{
|
{
|
||||||
|
@ -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();
|
||||||
|
@ -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/>
|
||||||
|
Loading…
Reference in New Issue
Block a user