mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-25 07:21:14 +01:00
Merge branch 'wiiSaveExportFixes'
saves like super smash bros brawl, mario kart, etc which use simple copy restriction via the banner file are now able to be imported natively with the wii/wiiU system menu save files which include subdirs are correctly packaged NOTE: saves which include 'nocopy'/'nomove' folders will likely always require homebrew adds feature to export all wii saves
This commit is contained in:
commit
199c4e0d78
@ -191,6 +191,7 @@ EVT_MENU(IDM_NETPLAY, CFrame::OnNetPlay)
|
||||
EVT_MENU(IDM_BROWSE, CFrame::OnBrowse)
|
||||
EVT_MENU(IDM_MEMCARD, CFrame::OnMemcard)
|
||||
EVT_MENU(IDM_IMPORTSAVE, CFrame::OnImportSave)
|
||||
EVT_MENU(IDM_EXPORTALLSAVE, CFrame::OnExportAllSaves)
|
||||
EVT_MENU(IDM_CHEATS, CFrame::OnShow_CheatsWindow)
|
||||
EVT_MENU(IDM_CHANGEDISC, CFrame::OnChangeDisc)
|
||||
EVT_MENU(IDM_MENU_INSTALLWAD, CFrame::OnInstallWAD)
|
||||
|
@ -324,6 +324,7 @@ private:
|
||||
|
||||
void OnMemcard(wxCommandEvent& event); // Misc
|
||||
void OnImportSave(wxCommandEvent& event);
|
||||
void OnExportAllSaves(wxCommandEvent& event);
|
||||
|
||||
void OnNetPlay(wxCommandEvent& event);
|
||||
|
||||
|
@ -190,7 +190,8 @@ void CFrame::CreateMenu()
|
||||
// Tools menu
|
||||
wxMenu* toolsMenu = new wxMenu;
|
||||
toolsMenu->Append(IDM_MEMCARD, _("&Memcard Manager (GC)"));
|
||||
toolsMenu->Append(IDM_IMPORTSAVE, _("Wii Save Import"));
|
||||
toolsMenu->Append(IDM_IMPORTSAVE, _("Import Wii Save"));
|
||||
toolsMenu->Append(IDM_EXPORTALLSAVE, _("Export All Wii Saves"));
|
||||
toolsMenu->Append(IDM_CHEATS, _("&Cheats Manager"));
|
||||
|
||||
toolsMenu->Append(IDM_NETPLAY, _("Start &NetPlay"));
|
||||
@ -1310,6 +1311,11 @@ void CFrame::OnMemcard(wxCommandEvent& WXUNUSED (event))
|
||||
MemcardManager.ShowModal();
|
||||
}
|
||||
|
||||
void CFrame::OnExportAllSaves(wxCommandEvent& WXUNUSED (event))
|
||||
{
|
||||
CWiiSaveCrypted::ExportAllSaves();
|
||||
}
|
||||
|
||||
void CFrame::OnImportSave(wxCommandEvent& WXUNUSED (event))
|
||||
{
|
||||
wxString path = wxFileSelector(_("Select the save file"),
|
||||
@ -1320,9 +1326,7 @@ void CFrame::OnImportSave(wxCommandEvent& WXUNUSED (event))
|
||||
|
||||
if (!path.IsEmpty())
|
||||
{
|
||||
// TODO: Does this actually need to be dynamically allocated for some reason?
|
||||
CWiiSaveCrypted* saveFile = new CWiiSaveCrypted(WxStrToStr(path).c_str());
|
||||
delete saveFile;
|
||||
CWiiSaveCrypted::ImportWiiSave(WxStrToStr(path).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -969,8 +969,7 @@ void CGameListCtrl::OnExportSave(wxCommandEvent& WXUNUSED (event))
|
||||
if (Iso->GetTitleID((u8*)&title))
|
||||
{
|
||||
title = Common::swap64(title);
|
||||
CWiiSaveCrypted* exportSave = new CWiiSaveCrypted("", title);
|
||||
delete exportSave;
|
||||
CWiiSaveCrypted::ExportWiiSave(title);
|
||||
}
|
||||
delete Iso;
|
||||
}
|
||||
|
@ -231,6 +231,7 @@ enum
|
||||
IDM_OPENSAVEFOLDER,
|
||||
IDM_EXPORTSAVE,
|
||||
IDM_IMPORTSAVE,
|
||||
IDM_EXPORTALLSAVE,
|
||||
IDM_SETDEFAULTGCM,
|
||||
IDM_DELETEGCM,
|
||||
IDM_COMPRESSGCM,
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "FileUtil.h"
|
||||
#include "MathUtil.h"
|
||||
#include "NandPaths.h"
|
||||
#include "FileUtil.h"
|
||||
#include <algorithm>
|
||||
|
||||
static Common::replace_v replacements;
|
||||
@ -21,18 +22,63 @@ const u8 MD5_BLANKER[0x10] = {0x0E, 0x65, 0x37, 0x81, 0x99, 0xBE, 0x45, 0x17,
|
||||
0xAB, 0x06, 0xEC, 0x22, 0x45, 0x1A, 0x57, 0x93};
|
||||
const u32 NG_id = 0x0403AC68;
|
||||
|
||||
bool CWiiSaveCrypted::ImportWiiSave(const char* FileName)
|
||||
{
|
||||
CWiiSaveCrypted saveFile(FileName);
|
||||
return saveFile.b_valid;
|
||||
}
|
||||
|
||||
bool CWiiSaveCrypted::ExportWiiSave(u64 TitleID)
|
||||
{
|
||||
CWiiSaveCrypted exportSave("", TitleID);
|
||||
return exportSave.b_valid;
|
||||
}
|
||||
|
||||
void CWiiSaveCrypted::ExportAllSaves()
|
||||
{
|
||||
std::string titleFolder = File::GetUserPath(D_WIIUSER_IDX) + "title";
|
||||
std::vector<u64> titles;
|
||||
u32 pathMask = 0x00010000;
|
||||
for (int i = 0; i < 8; ++i)
|
||||
{
|
||||
File::FSTEntry FST_Temp;
|
||||
std::string folder = StringFromFormat("%s/%08x/", titleFolder.c_str(), pathMask | i);
|
||||
File::ScanDirectoryTree(folder, FST_Temp);
|
||||
|
||||
for (u32 j = 0; j < FST_Temp.children.size(); j++)
|
||||
{
|
||||
if (FST_Temp.children[j].isDirectory)
|
||||
{
|
||||
u32 gameid;
|
||||
if (AsciiToHex(FST_Temp.children[j].virtualName.c_str(), gameid))
|
||||
{
|
||||
std::string bannerPath = StringFromFormat("%s%08x/data/banner.bin", folder.c_str(), gameid);
|
||||
if (File::Exists(bannerPath))
|
||||
{
|
||||
u64 titleID = (((u64)pathMask | i) << 32) | gameid;
|
||||
titles.push_back(titleID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
SuccessAlertT("Found %llx save files", titles.size());
|
||||
for (u32 i = 0; i < titles.size(); ++i)
|
||||
{
|
||||
CWiiSaveCrypted* exportSave = new CWiiSaveCrypted("", titles[i]);
|
||||
delete exportSave;
|
||||
}
|
||||
}
|
||||
CWiiSaveCrypted::CWiiSaveCrypted(const char* FileName, u64 TitleID)
|
||||
: m_TitleID(TitleID)
|
||||
{
|
||||
Common::ReadReplacements(replacements);
|
||||
strcpy(pathData_bin, FileName);
|
||||
encryptedSavePath = std::string(FileName);
|
||||
memcpy(SD_IV, "\x21\x67\x12\xE6\xAA\x1F\x68\x9F\x95\xC5\xA2\x23\x24\xDC\x6A\x98", 0x10);
|
||||
|
||||
if (!TitleID) // Import
|
||||
{
|
||||
AES_set_decrypt_key(SDKey, 128, &m_AES_KEY);
|
||||
do
|
||||
{
|
||||
b_valid = true;
|
||||
ReadHDR();
|
||||
ReadBKHDR();
|
||||
@ -41,13 +87,11 @@ CWiiSaveCrypted::CWiiSaveCrypted(const char* FileName, u64 TitleID)
|
||||
if (b_valid)
|
||||
{
|
||||
SuccessAlertT("Successfully imported save files");
|
||||
b_tryAgain = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
b_tryAgain = AskYesNoT("Import failed, try again?");
|
||||
PanicAlertT("Import failed");
|
||||
}
|
||||
} while(b_tryAgain);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -55,33 +99,29 @@ CWiiSaveCrypted::CWiiSaveCrypted(const char* FileName, u64 TitleID)
|
||||
|
||||
if (getPaths(true))
|
||||
{
|
||||
do
|
||||
b_valid = true;
|
||||
WriteHDR();
|
||||
WriteBKHDR();
|
||||
ExportWiiSaveFiles();
|
||||
do_sig();
|
||||
if (b_valid)
|
||||
{
|
||||
b_valid = true;
|
||||
WriteHDR();
|
||||
WriteBKHDR();
|
||||
ExportWiiSaveFiles();
|
||||
do_sig();
|
||||
if (b_valid)
|
||||
{
|
||||
SuccessAlertT("Successfully exported file to %s", pathData_bin);
|
||||
b_tryAgain = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
b_tryAgain = AskYesNoT("Export failed, try again?");
|
||||
}
|
||||
} while(b_tryAgain);
|
||||
SuccessAlertT("Successfully exported file to %s", encryptedSavePath.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
PanicAlertT("Export failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CWiiSaveCrypted::ReadHDR()
|
||||
{
|
||||
File::IOFile fpData_bin(pathData_bin, "rb");
|
||||
File::IOFile fpData_bin(encryptedSavePath, "rb");
|
||||
if (!fpData_bin)
|
||||
{
|
||||
PanicAlertT("Cannot open %s", pathData_bin);
|
||||
PanicAlertT("Cannot open %s", encryptedSavePath.c_str());
|
||||
b_valid = false;
|
||||
return;
|
||||
}
|
||||
@ -94,16 +134,19 @@ void CWiiSaveCrypted::ReadHDR()
|
||||
fpData_bin.Close();
|
||||
|
||||
AES_cbc_encrypt((const u8*)&_encryptedHeader, (u8*)&_header, HEADER_SZ, &m_AES_KEY, SD_IV, AES_DECRYPT);
|
||||
_bannerSize = Common::swap32(_header.hdr.BannerSize);
|
||||
if ((_bannerSize < FULL_BNR_MIN) || (_bannerSize > FULL_BNR_MAX) ||
|
||||
(((_bannerSize - BNR_SZ) % ICON_SZ) != 0))
|
||||
u32 bannerSize = Common::swap32(_header.hdr.BannerSize);
|
||||
if ((bannerSize < FULL_BNR_MIN) || (bannerSize > FULL_BNR_MAX) ||
|
||||
(((bannerSize - BNR_SZ) % ICON_SZ) != 0))
|
||||
{
|
||||
PanicAlertT("Not a Wii save or read failure for file header size %x", _bannerSize);
|
||||
PanicAlertT("Not a Wii save or read failure for file header size %x", bannerSize);
|
||||
b_valid = false;
|
||||
return;
|
||||
}
|
||||
m_TitleID = Common::swap64(_header.hdr.SaveGameTitle);
|
||||
|
||||
|
||||
u8 md5_file[16],
|
||||
md5_calc[16];
|
||||
memcpy(md5_file, _header.hdr.Md5, 0x10);
|
||||
memcpy(_header.hdr.Md5, MD5_BLANKER, 0x10);
|
||||
md5((u8*)&_header, HEADER_SZ, md5_calc);
|
||||
@ -118,11 +161,12 @@ void CWiiSaveCrypted::ReadHDR()
|
||||
b_valid = false;
|
||||
return;
|
||||
}
|
||||
std::string BannerFilePath = WiiTitlePath + "banner.bin";
|
||||
if (!File::Exists(BannerFilePath) || AskYesNoT("%s already exists, overwrite?", BannerFilePath.c_str()))
|
||||
{
|
||||
INFO_LOG(CONSOLE, "Creating file %s", BannerFilePath.c_str());
|
||||
File::IOFile fpBanner_bin(BannerFilePath, "wb");
|
||||
fpBanner_bin.WriteBytes(_header.BNR, _bannerSize);
|
||||
fpBanner_bin.WriteBytes(_header.BNR, bannerSize);
|
||||
}
|
||||
}
|
||||
|
||||
@ -131,12 +175,13 @@ void CWiiSaveCrypted::WriteHDR()
|
||||
if (!b_valid) return;
|
||||
memset(&_header, 0, HEADER_SZ);
|
||||
|
||||
std::string BannerFilePath = WiiTitlePath + "banner.bin";
|
||||
u32 bannerSize = File::GetSize(BannerFilePath);
|
||||
_header.hdr.BannerSize = Common::swap32(bannerSize);
|
||||
|
||||
_header.hdr.SaveGameTitle = Common::swap64(m_TitleID);
|
||||
memcpy(_header.hdr.Md5, MD5_BLANKER, 0x10);
|
||||
_header.hdr.Permissions = 0x35;
|
||||
_header.hdr.Permissions = 0x3C;
|
||||
|
||||
File::IOFile fpBanner_bin(BannerFilePath, "rb");
|
||||
if (!fpBanner_bin.ReadBytes(_header.BNR, bannerSize))
|
||||
@ -145,16 +190,19 @@ void CWiiSaveCrypted::WriteHDR()
|
||||
b_valid = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// remove nocopy flag
|
||||
_header.BNR[7] &= ~1;
|
||||
|
||||
u8 md5_calc[16];
|
||||
md5((u8*)&_header, HEADER_SZ, md5_calc);
|
||||
memcpy(_header.hdr.Md5, md5_calc, 0x10);
|
||||
|
||||
AES_cbc_encrypt((const unsigned char *)&_header, (u8*)&_encryptedHeader, HEADER_SZ, &m_AES_KEY, SD_IV, AES_ENCRYPT);
|
||||
|
||||
File::IOFile fpData_bin(pathData_bin, "wb");
|
||||
File::IOFile fpData_bin(encryptedSavePath, "wb");
|
||||
if (!fpData_bin.WriteBytes(&_encryptedHeader, HEADER_SZ))
|
||||
{
|
||||
PanicAlertT("Failed to write header for %s", pathData_bin);
|
||||
PanicAlertT("Failed to write header for %s", encryptedSavePath.c_str());
|
||||
b_valid = false;
|
||||
}
|
||||
}
|
||||
@ -165,10 +213,10 @@ void CWiiSaveCrypted::ReadBKHDR()
|
||||
{
|
||||
if (!b_valid) return;
|
||||
|
||||
File::IOFile fpData_bin(pathData_bin, "rb");
|
||||
File::IOFile fpData_bin(encryptedSavePath, "rb");
|
||||
if (!fpData_bin)
|
||||
{
|
||||
PanicAlertT("Cannot open %s", pathData_bin);
|
||||
PanicAlertT("Cannot open %s", encryptedSavePath.c_str());
|
||||
b_valid = false;
|
||||
return;
|
||||
}
|
||||
@ -215,7 +263,7 @@ void CWiiSaveCrypted::WriteBKHDR()
|
||||
bkhdr.totalSize = Common::swap32(_sizeOfFiles + FULL_CERT_SZ);
|
||||
bkhdr.SaveGameTitle = Common::swap64(m_TitleID);
|
||||
|
||||
File::IOFile fpData_bin(pathData_bin, "ab");
|
||||
File::IOFile fpData_bin(encryptedSavePath, "ab");
|
||||
if (!fpData_bin.WriteBytes(&bkhdr, BK_SZ))
|
||||
{
|
||||
PanicAlertT("Failed to write bkhdr");
|
||||
@ -227,10 +275,10 @@ void CWiiSaveCrypted::ImportWiiSaveFiles()
|
||||
{
|
||||
if (!b_valid) return;
|
||||
|
||||
File::IOFile fpData_bin(pathData_bin, "rb");
|
||||
File::IOFile fpData_bin(encryptedSavePath, "rb");
|
||||
if (!fpData_bin)
|
||||
{
|
||||
PanicAlertT("Cannot open %s", pathData_bin);
|
||||
PanicAlertT("Cannot open %s", encryptedSavePath.c_str());
|
||||
b_valid = false;
|
||||
return;
|
||||
}
|
||||
@ -244,11 +292,11 @@ void CWiiSaveCrypted::ImportWiiSaveFiles()
|
||||
{
|
||||
memset(&_tmpFileHDR, 0, FILE_HDR_SZ);
|
||||
memset(IV, 0, 0x10);
|
||||
_fileSize = 0;
|
||||
u32 _fileSize = 0;
|
||||
|
||||
if (!fpData_bin.ReadBytes(&_tmpFileHDR, FILE_HDR_SZ))
|
||||
{
|
||||
PanicAlertT("Failed to write header for file %d", i);
|
||||
PanicAlertT("Failed to read header for file %d", i);
|
||||
b_valid = false;
|
||||
}
|
||||
|
||||
@ -267,14 +315,15 @@ void CWiiSaveCrypted::ImportWiiSaveFiles()
|
||||
}
|
||||
|
||||
std::string fullFilePath = WiiTitlePath + fileName;
|
||||
File::CreateFullPath(fullFilePath);
|
||||
File::CreateFullPath(fullFilePath);
|
||||
if (_tmpFileHDR.type == 1)
|
||||
{
|
||||
_fileSize = Common::swap32(_tmpFileHDR.size);
|
||||
u32 RoundedFileSize = ROUND_UP(_fileSize, BLOCK_SZ);
|
||||
_encryptedData = new u8[RoundedFileSize];
|
||||
_data = new u8[RoundedFileSize];
|
||||
if (!fpData_bin.ReadBytes(_encryptedData, RoundedFileSize))
|
||||
std::vector<u8> _data,_encryptedData;
|
||||
_data.reserve(RoundedFileSize);
|
||||
_encryptedData.reserve(RoundedFileSize);
|
||||
if (!fpData_bin.ReadBytes(&_encryptedData[0], RoundedFileSize))
|
||||
{
|
||||
PanicAlertT("Failed to read data from file %d", i);
|
||||
b_valid = false;
|
||||
@ -283,17 +332,15 @@ void CWiiSaveCrypted::ImportWiiSaveFiles()
|
||||
|
||||
|
||||
memcpy(IV, _tmpFileHDR.IV, 0x10);
|
||||
AES_cbc_encrypt((const unsigned char *)_encryptedData, _data, RoundedFileSize, &m_AES_KEY, IV, AES_DECRYPT);
|
||||
delete []_encryptedData;
|
||||
AES_cbc_encrypt((const unsigned char *)&_encryptedData[0], &_data[0], RoundedFileSize, &m_AES_KEY, IV, AES_DECRYPT);
|
||||
|
||||
if (!File::Exists(fullFilePath) || AskYesNoT("%s already exists, overwrite?", fullFilePath.c_str()))
|
||||
{
|
||||
INFO_LOG(CONSOLE, "Creating file %s", fullFilePath.c_str());
|
||||
|
||||
File::IOFile fpRawSaveFile(fullFilePath, "wb");
|
||||
fpRawSaveFile.WriteBytes(_data, _fileSize);
|
||||
fpRawSaveFile.WriteBytes(&_data[0], _fileSize);
|
||||
}
|
||||
delete []_data;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -303,25 +350,29 @@ void CWiiSaveCrypted::ExportWiiSaveFiles()
|
||||
{
|
||||
if (!b_valid) return;
|
||||
|
||||
u8 *__ENCdata,
|
||||
*__data;
|
||||
|
||||
for(u32 i = 0; i < _numberOfFiles; i++)
|
||||
{
|
||||
FileHDR tmpFileHDR;
|
||||
std::string __name, __ext;
|
||||
memset(&tmpFileHDR, 0, FILE_HDR_SZ);
|
||||
|
||||
_fileSize = File::GetSize(FilesList[i]);
|
||||
_roundedfileSize = ROUND_UP(_fileSize, BLOCK_SZ);
|
||||
|
||||
|
||||
u32 _fileSize = 0;
|
||||
if (File::IsDirectory(FilesList[i]))
|
||||
{
|
||||
tmpFileHDR.type = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
_fileSize = File::GetSize(FilesList[i]);
|
||||
tmpFileHDR.type = 1;
|
||||
}
|
||||
|
||||
u32 _roundedfileSize = ROUND_UP(_fileSize, BLOCK_SZ);
|
||||
tmpFileHDR.magic = Common::swap32(FILE_HDR_MAGIC);
|
||||
tmpFileHDR.size = Common::swap32(_fileSize);
|
||||
tmpFileHDR.Permissions = 0x35;
|
||||
tmpFileHDR.type = File::IsDirectory(FilesList[i]) ? 2 : 1;
|
||||
tmpFileHDR.Permissions = 0x3c;
|
||||
|
||||
SplitPath(FilesList[i], NULL, &__name, &__ext);
|
||||
__name += __ext;
|
||||
__name = FilesList[i].substr(WiiTitlePath.length()+1);
|
||||
|
||||
|
||||
for (Common::replace_v::const_iterator iter = replacements.begin(); iter != replacements.end(); ++iter)
|
||||
@ -341,7 +392,7 @@ void CWiiSaveCrypted::ExportWiiSaveFiles()
|
||||
strncpy((char *)tmpFileHDR.name, __name.c_str(), __name.length());
|
||||
|
||||
{
|
||||
File::IOFile fpData_bin(pathData_bin, "ab");
|
||||
File::IOFile fpData_bin(encryptedSavePath, "ab");
|
||||
fpData_bin.WriteBytes(&tmpFileHDR, FILE_HDR_SZ);
|
||||
}
|
||||
|
||||
@ -359,22 +410,23 @@ void CWiiSaveCrypted::ExportWiiSaveFiles()
|
||||
PanicAlertT("%s failed to open", FilesList[i].c_str());
|
||||
b_valid = false;
|
||||
}
|
||||
__data = new u8[_roundedfileSize];
|
||||
__ENCdata = new u8[_roundedfileSize];
|
||||
memset(__data, 0, _roundedfileSize);
|
||||
if (!fpRawSaveFile.ReadBytes(__data, _fileSize))
|
||||
|
||||
std::vector<u8> _data,_encryptedData;
|
||||
_data.reserve(_roundedfileSize);
|
||||
_encryptedData.reserve(_roundedfileSize);
|
||||
memset(&_data[0], 0, _roundedfileSize);
|
||||
if (!fpRawSaveFile.ReadBytes(&_data[0], _fileSize))
|
||||
{
|
||||
PanicAlertT("Failed to read data from file: %s", FilesList[i].c_str());
|
||||
b_valid = false;
|
||||
}
|
||||
|
||||
AES_cbc_encrypt((const u8*)__data, __ENCdata, _roundedfileSize, &m_AES_KEY, tmpFileHDR.IV, AES_ENCRYPT);
|
||||
AES_cbc_encrypt((const u8*)&_data[0], &_encryptedData[0], _roundedfileSize, &m_AES_KEY, tmpFileHDR.IV, AES_ENCRYPT);
|
||||
|
||||
File::IOFile fpData_bin(pathData_bin, "ab");
|
||||
fpData_bin.WriteBytes(__ENCdata, _roundedfileSize);
|
||||
File::IOFile fpData_bin(encryptedSavePath, "ab");
|
||||
if (!fpData_bin.WriteBytes(&_encryptedData[0], _roundedfileSize))
|
||||
PanicAlertT("Failed to write data to file: %s", encryptedSavePath.c_str());
|
||||
|
||||
delete [] __data;
|
||||
delete [] __ENCdata;
|
||||
|
||||
}
|
||||
}
|
||||
@ -424,7 +476,7 @@ void CWiiSaveCrypted::do_sig()
|
||||
|
||||
data_size = Common::swap32(bkhdr.sizeOfFiles) + 0x80;
|
||||
|
||||
File::IOFile fpData_bin(pathData_bin, "rb");
|
||||
File::IOFile fpData_bin(encryptedSavePath, "rb");
|
||||
if (!fpData_bin)
|
||||
{
|
||||
b_valid = false;
|
||||
@ -443,7 +495,7 @@ void CWiiSaveCrypted::do_sig()
|
||||
sha1(hash, 20, hash);
|
||||
delete []data;
|
||||
|
||||
fpData_bin.Open(pathData_bin, "ab");
|
||||
fpData_bin.Open(encryptedSavePath, "ab");
|
||||
if (!fpData_bin)
|
||||
{
|
||||
b_valid = false;
|
||||
@ -478,7 +530,6 @@ bool CWiiSaveCrypted::getPaths(bool forExport)
|
||||
if (m_TitleID)
|
||||
{
|
||||
WiiTitlePath = Common::GetTitleDataPath(m_TitleID);
|
||||
BannerFilePath = WiiTitlePath + "banner.bin";
|
||||
}
|
||||
|
||||
if (forExport)
|
||||
@ -495,16 +546,16 @@ bool CWiiSaveCrypted::getPaths(bool forExport)
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!File::Exists(BannerFilePath))
|
||||
if(!File::Exists(WiiTitlePath + "banner.bin"))
|
||||
{
|
||||
b_valid = false;
|
||||
PanicAlertT("No banner file found for title %s", GameID);
|
||||
return false;
|
||||
}
|
||||
if (strlen(pathData_bin) == 0)
|
||||
strcpy(pathData_bin, "."); // If no path was passed, use current dir
|
||||
sprintf(pathData_bin, "%s/private/wii/title/%s/data.bin", pathData_bin, GameID);
|
||||
File::CreateFullPath(pathData_bin);
|
||||
if (encryptedSavePath.length() == 0)
|
||||
encryptedSavePath = "."; // If no path was passed, use current dir
|
||||
encryptedSavePath += StringFromFormat("/private/wii/title/%s/data.bin", GameID);
|
||||
File::CreateFullPath(encryptedSavePath);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -535,15 +586,20 @@ void CWiiSaveCrypted::ScanForFiles(std::string savDir, std::vector<std::string>&
|
||||
if (strncmp(FST_Temp.children.at(j).virtualName.c_str(), "banner.bin", 10) != 0)
|
||||
{
|
||||
(*_numFiles)++;
|
||||
*_sizeFiles += FILE_HDR_SZ + ROUND_UP(FST_Temp.children.at(j).size, BLOCK_SZ);
|
||||
|
||||
*_sizeFiles += FILE_HDR_SZ;
|
||||
if (FST_Temp.children.at(j).isDirectory)
|
||||
{
|
||||
if ((FST_Temp.children.at(j).virtualName == "nocopy") || FST_Temp.children.at(j).virtualName == "nomove")
|
||||
{
|
||||
PanicAlert("This save will likely require homebrew tools to copy to a real wii");
|
||||
}
|
||||
|
||||
Directories.push_back(FST_Temp.children.at(j).physicalName);
|
||||
}
|
||||
else
|
||||
{
|
||||
FileList.push_back(FST_Temp.children.at(j).physicalName);
|
||||
*_sizeFiles += ROUND_UP(FST_Temp.children.at(j).size, BLOCK_SZ);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,11 @@
|
||||
class CWiiSaveCrypted
|
||||
{
|
||||
public:
|
||||
bool static ImportWiiSave(const char* FileName);
|
||||
bool static ExportWiiSave(u64 TitleID);
|
||||
void static ExportAllSaves();
|
||||
|
||||
private:
|
||||
CWiiSaveCrypted(const char* FileName, u64 TitleID = 0);
|
||||
~CWiiSaveCrypted();
|
||||
void ReadHDR();
|
||||
@ -30,33 +35,26 @@ public:
|
||||
bool getPaths(bool forExport = false);
|
||||
void ScanForFiles(std::string savDir, std::vector<std::string>&FilesList, u32 *_numFiles, u32 *_sizeFiles);
|
||||
|
||||
private:
|
||||
|
||||
AES_KEY m_AES_KEY;
|
||||
u8 SD_IV[0x10];
|
||||
std::vector<std::string> FilesList;
|
||||
|
||||
char pathData_bin[2048];
|
||||
std::string encryptedSavePath;
|
||||
|
||||
std::string BannerFilePath,
|
||||
WiiTitlePath;
|
||||
|
||||
u8 IV[0x10],
|
||||
*_encryptedData,
|
||||
*_data,
|
||||
md5_file[16],
|
||||
md5_calc[16];
|
||||
|
||||
u32 _bannerSize,
|
||||
u8 IV[0x10];
|
||||
|
||||
u32 //_bannerSize,
|
||||
_numberOfFiles,
|
||||
_sizeOfFiles,
|
||||
_totalSize,
|
||||
_fileSize,
|
||||
_roundedfileSize;
|
||||
_totalSize;
|
||||
|
||||
u64 m_TitleID;
|
||||
|
||||
bool b_valid,
|
||||
b_tryAgain;
|
||||
bool b_valid;
|
||||
|
||||
enum
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user