From e0737204fd65685123941a4104f4c6fbfdf84fc4 Mon Sep 17 00:00:00 2001 From: O1L Date: Thu, 6 Feb 2014 20:58:42 +0400 Subject: [PATCH 1/2] Use _ftelli64 and _fseeki64 instead ftell and fseek in unpkg, required to unpacking big files (> 4 Gb). Deleted wxMoveDir() (not needed now :P ) and added simple progress bars in unpkg. --- rpcs3/Gui/MainFrame.cpp | 81 ++----------------------- unpkg/unpkg.c | 131 ++++++++++++++++++++++++++++------------ unpkg/unpkg.h | 4 +- 3 files changed, 97 insertions(+), 119 deletions(-) diff --git a/rpcs3/Gui/MainFrame.cpp b/rpcs3/Gui/MainFrame.cpp index 5a032d4cdf..8916b2964e 100644 --- a/rpcs3/Gui/MainFrame.cpp +++ b/rpcs3/Gui/MainFrame.cpp @@ -66,47 +66,6 @@ wxString GetPaneName() return wxString::Format("Pane_%d", pane_num++); } -bool wxMoveDir(wxString sFrom, wxString sTo) -{ - if (sFrom[sFrom.Len() - 1] != '\\' && sFrom[sFrom.Len() - 1] != '/') sFrom += wxFILE_SEP_PATH; - if (sTo[sTo.Len() - 1] != '\\' && sTo[sTo.Len() - 1] != '/') sTo += wxFILE_SEP_PATH; - - if (!::wxDirExists(sFrom)) { - ::wxLogError(wxT("%s does not exist!\r\nCan not copy directory"), sFrom.c_str()); - return false; - } - if (!wxDirExists(sTo)) { - if (!wxFileName::Mkdir(sTo, 0777, wxPATH_MKDIR_FULL)) { - ::wxLogError(wxT("%s could not be created!"), sTo.c_str()); - return false; - } - } - - wxDir fDir(sFrom); - wxString sNext = wxEmptyString; - bool bIsFile = fDir.GetFirst(&sNext); - while (bIsFile) { - const wxString sFileFrom = sFrom + sNext; - const wxString sFileTo = sTo + sNext; - if (::wxDirExists(sFileFrom)) { - wxMoveDir(sFileFrom, sFileTo); - ::wxRmdir(sFileFrom); - } - else { - if (!::wxFileExists(sFileTo)) { - if (!::wxCopyFile(sFileFrom, sFileTo)) { - ::wxLogError(wxT("Could not copy %s to %s !"), sFileFrom.c_str(), sFileTo.c_str()); - return false; - } - } - ::wxRemoveFile(sFileFrom); - } - bIsFile = fDir.GetNext(&sNext); - } - ::wxRmdir(sFrom); - return true; -} - MainFrame::MainFrame() : FrameBase(nullptr, wxID_ANY, "", "MainFrame", wxSize(800, 600)) , m_aui_mgr(this) @@ -267,47 +226,15 @@ void MainFrame::InstallPkg(wxCommandEvent& WXUNUSED(event)) Emu.Stop(); wxString fileName = ctrl.GetPath(); - - { - wxProgressDialog pdlg("Please wait", "Installing PKG...", 0, this, wxPD_APP_MODAL); - pkg_unpack((const char *)fileName.mb_str()); - } + if (!pkg_unpack((const char *)fileName.mb_str())) + ConLog.Error("Could not unpack PKG!"); + else ConLog.Success("PKG: extract done."); if (!wxRemoveFile(ctrl.GetPath()+".dec")) ConLog.Warning("Could not delete the decoded DEC file"); - // Copy the PKG to dev_hdd0 and format the path to be identical to the PS3. - wxString gamePath = "\\dev_hdd0\\game\\"; - pkg_header *header; - pkg_info((const char *)fileName.mb_str(), &header); - - // Get the PKG title ID from the header and format it (should match TITLE ID from PARAM.SFO). - wxString titleID_full (header->title_id); - wxString titleID = titleID_full.SubString(7, 15); - - // Travel to bin folder. - wxSetWorkingDirectory(wxGetCwd() + "\\..\\"); - - // Save the main dir. - wxString mainDir = wxGetCwd(); - - // Set PKG dir. - wxString oldPkgDir = wxT(mainDir + "\\" + titleID_full); - wxString newPkgDir = wxT(mainDir + gamePath + titleID); - - // Move the final folder. - wxMoveDir(oldPkgDir, newPkgDir); - - // Save the title ID. - Emu.SetTitleID(titleID); - - ConLog.Success("PKG: extract done."); - - // Travel to the main dir. - wxSetWorkingDirectory(mainDir); - + //Refresh game list m_game_viewer->Refresh(); - Emu.BootGame(newPkgDir.c_str()); } void MainFrame::BootElf(wxCommandEvent& WXUNUSED(event)) diff --git a/unpkg/unpkg.c b/unpkg/unpkg.c index f406f1c026..39e4e9ab15 100644 --- a/unpkg/unpkg.c +++ b/unpkg/unpkg.c @@ -69,9 +69,9 @@ static int pkg_sanity_check(FILE *f, FILE *g, pkg_header **h_ptr, const char *fn u8 sha_key[0x40]; int i; f= fopen(fname, "rb"); - fseek(f, 0, SEEK_END); - int nlen = ftell(f); - fseek(f, 0, SEEK_SET); + _fseeki64(f, 0, SEEK_END); + int nlen = _ftelli64(f); + _fseeki64(f, 0, SEEK_SET); data = (u8*)malloc(nlen); fread(data, 1, nlen, f); fclose(f); @@ -114,20 +114,31 @@ static int pkg_sanity_check(FILE *f, FILE *g, pkg_header **h_ptr, const char *fn // add hash sha1(data, nlen-0x20, &data[nlen-0x20]); - fwrite(data, 1, nlen, g); + + int write_count = fwrite(data, 1, nlen, g); //fclose(g); // not close the file for continuing - fseek(g, 0, SEEK_END); - tmp = ftell(g); + int max = nlen; + wxProgressDialog* pdlg = new wxProgressDialog("PKG Decrypter / Installer", "Please wait, recrypting...", max, 0, wxPD_AUTO_HIDE | wxPD_APP_MODAL); + + for (i=0; iUpdate(i); + } + + _fseeki64(g, 0, SEEK_END); + tmp = _ftelli64(g); + pdlg->Update(max); + delete pdlg; } break; - + case PKG_RELEASE_TYPE_RELEASE: { ConLog.Warning ("UnPkg: Retail PKG detected."); - fseek(f, 0, SEEK_END); - tmp = ftell(f); + _fseeki64(f, 0, SEEK_END); + tmp = _ftelli64(f); } break; @@ -188,19 +199,19 @@ static void print_pkg_header(pkg_header *header) hash_tostring(qa, header->qa_digest, sizeof(header->qa_digest)); hash_tostring(kl, header->klicensee, sizeof(header->klicensee)); - ConLog.Write("Magic: %x\n", ntohl(header->magic)); - ConLog.Write("Release Type: %x\n", ntohl(header->rel_type) >> 16 & (0xffff)); - ConLog.Write("Platform Type: %x\n", ntohl(header->rel_type) & (0xffff)); - ConLog.Write("Header size: %x\n", ntohl(header->header_size)); - ConLog.Write("Unk1: %x\n", ntohl(header->unk1)); - ConLog.Write("Metadata size: %x\n", ntohl(header->meta_size)); - ConLog.Write("File count: %u\n", ntohl(header->file_count)); - ConLog.Write("Pkg size: %llu\n", ntohll(header->pkg_size)); - ConLog.Write("Data offset: %llx\n", ntohll(header->data_offset)); - ConLog.Write("Data size: %llu\n", ntohll(header->data_size)); - ConLog.Write("TitleID: %s\n", header->title_id); - ConLog.Write("QA Digest: %s\n", qa); - ConLog.Write( "KLicensee: %s\n", kl); + ConLog.Write("Magic: 0x%x", ntohl(header->magic)); + ConLog.Write("Release Type: 0x%x", ntohl(header->rel_type) >> 16 & (0xffff)); + ConLog.Write("Platform Type: 0x%x", ntohl(header->rel_type) & (0xffff)); + ConLog.Write("Header size: 0x%x", ntohl(header->header_size)); + ConLog.Write("Unk1: 0x%x", ntohl(header->unk1)); + ConLog.Write("Metadata size: 0x%x", ntohl(header->meta_size)); + ConLog.Write("File count: %u", ntohl(header->file_count)); + ConLog.Write("Pkg size: %llu", ntohll(header->pkg_size)); + ConLog.Write("Data offset: 0x%llx", ntohll(header->data_offset)); + ConLog.Write("Data size: 0x%llu", ntohll(header->data_size)); + ConLog.Write("TitleID: %s", header->title_id); + ConLog.Write("QA Digest: %s", qa); + ConLog.Write( "KLicensee: %s", kl); } static void *pkg_info(const char *fname, pkg_header **h_ptr) @@ -244,6 +255,9 @@ static void pkg_crypt(const u8 *key, const u8 *kl, FILE *f, u32 l; u64 hi, lo; + int max = len / BUF_SIZE; + wxProgressDialog* pdlg = new wxProgressDialog("PKG Decrypter / Installer", "Please wait, decrypting...", max, 0, wxPD_AUTO_HIDE | wxPD_APP_MODAL); + parts = len / BUF_SIZE; if (len % BUF_SIZE != 0) parts++; @@ -278,18 +292,20 @@ static void pkg_crypt(const u8 *key, const u8 *kl, FILE *f, } fwrite(out_buf, 1, l, out); + pdlg->Update(i); } - + pdlg->Update(max); + delete pdlg; } -static void pkg_unpack_file(pkg_file_entry *fentry, FILE *dec) +static bool pkg_unpack_file(pkg_file_entry *fentry, FILE *dec) { FILE *out = NULL; u64 size; u32 tmp; u8 buf[BUF_SIZE]; - fseek(dec, fentry->name_offset, SEEK_SET); + _fseeki64(dec, fentry->name_offset, SEEK_SET); memset(buf, 0, sizeof(buf)); fread(buf, fentry->name_size, 1, dec); @@ -301,7 +317,7 @@ static void pkg_unpack_file(pkg_file_entry *fentry, FILE *dec) case PKG_FILE_ENTRY_SDAT: case PKG_FILE_ENTRY_REGULAR: out = fopen((char *)buf, "wb"); - fseek(dec, fentry->file_offset, SEEK_SET); + _fseeki64(dec, fentry->file_offset, SEEK_SET); for (size = 0; size < fentry->file_size; ) { size += fread(buf, sizeof(u8), BUF_SIZE, dec); @@ -320,14 +336,18 @@ static void pkg_unpack_file(pkg_file_entry *fentry, FILE *dec) mkdir ((char *)buf); break; } + return true; } static void pkg_unpack_data(u32 file_count, FILE *dec) { + int max = file_count; + wxProgressDialog* pdlg = new wxProgressDialog("PKG Decrypter / Installer", "Please wait, unpacking...", max, 0, wxPD_AUTO_HIDE | wxPD_APP_MODAL); + u32 i; pkg_file_entry *file_table = NULL; - fseek(dec, 0, SEEK_SET); + _fseeki64(dec, 0, SEEK_SET); file_table = (pkg_file_entry *)malloc(sizeof(pkg_file_entry)*file_count); i = fread(file_table, sizeof(pkg_file_entry), file_count, dec); @@ -346,27 +366,40 @@ static void pkg_unpack_data(u32 file_count, FILE *dec) (file_table+i)->file_size = ntohll((file_table+i)->file_size); (file_table+i)->type = ntohl((file_table+i)->type); - pkg_unpack_file(file_table+i, dec); - + if(pkg_unpack_file(file_table+i, dec)) pdlg->Update(i); } free(file_table); + pdlg->Update(max); + delete pdlg; } -static void pkg_unpack(const char *fname) +bool pkg_unpack(const char *fname) { FILE *f, *dec; char *dec_fname; pkg_header *header; - int ret; struct stat sb; - + f = (FILE*) pkg_info(fname, &header); if (f == NULL) - return; + return false; + + // Save the main dir. + wxString mainDir = wxGetCwd(); + + // Set the working directory. + wxSetWorkingDirectory(wxGetCwd() + "\\dev_hdd0\\game\\"); - fseek(f, ntohll(header->data_offset), SEEK_SET); + std::string gamePath = "\\dev_hdd0\\game\\"; + + // Get the PKG title ID from the header and format it (should match TITLE ID from PARAM.SFO). + std::string titleID_full (header->title_id); + std::string titleID = titleID_full.substr(7, 9); + std::string pkgDir = mainDir + gamePath + titleID; + + _fseeki64(f, ntohll(header->data_offset), SEEK_SET); dec_fname = (char*)malloc(strlen(fname)+4); memset(dec_fname, 0, strlen(fname)+4); @@ -377,29 +410,47 @@ static void pkg_unpack(const char *fname) { ConLog.Error("UnPkg: Could not create temp file for decrypted data."); free(header); - return; + return false; } unlink(dec_fname); pkg_crypt(PKG_AES_KEY, header->klicensee, f, ntohll(header->data_size), dec); - fseek(dec, 0, SEEK_SET); + _fseeki64(dec, 0, SEEK_SET); fclose(f); if (stat(header->title_id, &sb) != 0) { - ret = mkdir(header->title_id); - if (ret < 0) + if (mkdir(titleID.c_str()) < 0) { ConLog.Error("UnPkg: Could not mkdir."); + ConLog.Error("UnPkg: Possibly, folder already exists in dev_hdd0\\game : %s", titleID.c_str()); + wxSetWorkingDirectory(mainDir); free(header); - return; + return false; } } - chdir(header->title_id); + chdir(titleID.c_str()); pkg_unpack_data(ntohl(header->file_count), dec); fclose(dec); + + // Save the title ID. + Emu.SetTitleID(titleID); + + // Travel to the main dir. + wxSetWorkingDirectory(mainDir); + + if(Emu.BootGame(pkgDir.c_str())) + { + ConLog.Success("Game: boot done."); + } + else + { + ConLog.Error("Ps3 executable not found in folder (%s)", pkgDir.c_str()); + } + + return true; } \ No newline at end of file diff --git a/unpkg/unpkg.h b/unpkg/unpkg.h index 2f06d4241c..fa8262eb0e 100644 --- a/unpkg/unpkg.h +++ b/unpkg/unpkg.h @@ -164,11 +164,11 @@ static void *pkg_info(const char *fname, pkg_header **h_ptr); static void pkg_crypt(const u8 *key, const u8 *kl, FILE *f, u64 len, FILE *out); -static void pkg_unpack(const char *fname); +bool pkg_unpack(const char *fname); static void pkg_unpack_data(u32 file_count, FILE *dec); -static void pkg_unpack_file(pkg_file_entry *fentry, FILE *dec);; +static bool pkg_unpack_file(pkg_file_entry *fentry, FILE *dec);; static int pkg_pack_data(file_table_tr *ftr, pkg_file_entry *table, int file_count, sha1_context *ctx, FILE *out); From 74426fd4e99802feca2f506e614a80c0e8867da5 Mon Sep 17 00:00:00 2001 From: O1L Date: Thu, 6 Feb 2014 22:34:05 +0400 Subject: [PATCH 2/2] Minor changes --- rpcs3/Gui/MainFrame.cpp | 23 +++++++++++++++++++++ unpkg/unpkg.c | 45 ++++++++++------------------------------- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/rpcs3/Gui/MainFrame.cpp b/rpcs3/Gui/MainFrame.cpp index 8916b2964e..1f3d8f1d9c 100644 --- a/rpcs3/Gui/MainFrame.cpp +++ b/rpcs3/Gui/MainFrame.cpp @@ -233,8 +233,31 @@ void MainFrame::InstallPkg(wxCommandEvent& WXUNUSED(event)) if (!wxRemoveFile(ctrl.GetPath()+".dec")) ConLog.Warning("Could not delete the decoded DEC file"); + pkg_header *header; + pkg_info((const char *)fileName.mb_str(), &header); + + wxString titleID_full (header->title_id); + wxString titleID = titleID_full.SubString(7, 15); + + wxString mainDir = wxGetCwd(); + wxString gamePath = "\\dev_hdd0\\game\\"; + + wxString pkgDir = wxT(mainDir + gamePath + titleID); + + // Save the title ID. + Emu.SetTitleID(titleID); + //Refresh game list m_game_viewer->Refresh(); + + if(Emu.BootGame(pkgDir.c_str())) + { + ConLog.Success("Game: boot done."); + } + else + { + ConLog.Error("Ps3 executable not found in folder (%s)", pkgDir.c_str()); + } } void MainFrame::BootElf(wxCommandEvent& WXUNUSED(event)) diff --git a/unpkg/unpkg.c b/unpkg/unpkg.c index 39e4e9ab15..b5367e1e88 100644 --- a/unpkg/unpkg.c +++ b/unpkg/unpkg.c @@ -65,6 +65,8 @@ static int pkg_sanity_check(FILE *f, FILE *g, pkg_header **h_ptr, const char *fn case PKG_RELEASE_TYPE_DEBUG: { ConLog.Warning ("UnPkg: Debug PKG detected."); + wxProgressDialog pdlg ("PKG Decrypter / Installer", "Please wait, recrypting...", 0, 0, wxPD_AUTO_HIDE | wxPD_APP_MODAL); + u8* data; u8 sha_key[0x40]; int i; @@ -93,6 +95,7 @@ static int pkg_sanity_check(FILE *f, FILE *g, pkg_header **h_ptr, const char *fn u8 hash[0x14]; sha1(sha_crap, 0x40, hash); for(i=0;i<0x10;i++) data[dptr+i] ^= hash[i]; + set_u64(sha_crap+0x38, get_u64(sha_crap+0x38)+1); } @@ -115,21 +118,11 @@ static int pkg_sanity_check(FILE *f, FILE *g, pkg_header **h_ptr, const char *fn // add hash sha1(data, nlen-0x20, &data[nlen-0x20]); - int write_count = fwrite(data, 1, nlen, g); + fwrite(data, 1, nlen, g); //fclose(g); // not close the file for continuing - int max = nlen; - wxProgressDialog* pdlg = new wxProgressDialog("PKG Decrypter / Installer", "Please wait, recrypting...", max, 0, wxPD_AUTO_HIDE | wxPD_APP_MODAL); - - for (i=0; iUpdate(i); - } - _fseeki64(g, 0, SEEK_END); tmp = _ftelli64(g); - pdlg->Update(max); - delete pdlg; } break; @@ -256,8 +249,8 @@ static void pkg_crypt(const u8 *key, const u8 *kl, FILE *f, u64 hi, lo; int max = len / BUF_SIZE; - wxProgressDialog* pdlg = new wxProgressDialog("PKG Decrypter / Installer", "Please wait, decrypting...", max, 0, wxPD_AUTO_HIDE | wxPD_APP_MODAL); - + wxProgressDialog pdlg("PKG Decrypter / Installer", "Please wait, decrypting...", max, 0, wxPD_AUTO_HIDE | wxPD_APP_MODAL); + parts = len / BUF_SIZE; if (len % BUF_SIZE != 0) parts++; @@ -292,10 +285,9 @@ static void pkg_crypt(const u8 *key, const u8 *kl, FILE *f, } fwrite(out_buf, 1, l, out); - pdlg->Update(i); + pdlg.Update(i); } - pdlg->Update(max); - delete pdlg; + pdlg.Update(max); } static bool pkg_unpack_file(pkg_file_entry *fentry, FILE *dec) @@ -342,7 +334,7 @@ static bool pkg_unpack_file(pkg_file_entry *fentry, FILE *dec) static void pkg_unpack_data(u32 file_count, FILE *dec) { int max = file_count; - wxProgressDialog* pdlg = new wxProgressDialog("PKG Decrypter / Installer", "Please wait, unpacking...", max, 0, wxPD_AUTO_HIDE | wxPD_APP_MODAL); + wxProgressDialog pdlg ("PKG Decrypter / Installer", "Please wait, unpacking...", max, 0, wxPD_AUTO_HIDE | wxPD_APP_MODAL); u32 i; pkg_file_entry *file_table = NULL; @@ -366,12 +358,11 @@ static void pkg_unpack_data(u32 file_count, FILE *dec) (file_table+i)->file_size = ntohll((file_table+i)->file_size); (file_table+i)->type = ntohl((file_table+i)->type); - if(pkg_unpack_file(file_table+i, dec)) pdlg->Update(i); + if(pkg_unpack_file(file_table+i, dec)) pdlg.Update(i); } free(file_table); - pdlg->Update(max); - delete pdlg; + pdlg.Update(max); } bool pkg_unpack(const char *fname) @@ -437,20 +428,6 @@ bool pkg_unpack(const char *fname) pkg_unpack_data(ntohl(header->file_count), dec); fclose(dec); - // Save the title ID. - Emu.SetTitleID(titleID); - - // Travel to the main dir. wxSetWorkingDirectory(mainDir); - - if(Emu.BootGame(pkgDir.c_str())) - { - ConLog.Success("Game: boot done."); - } - else - { - ConLog.Error("Ps3 executable not found in folder (%s)", pkgDir.c_str()); - } - return true; } \ No newline at end of file