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.

This commit is contained in:
O1L 2014-02-06 20:58:42 +04:00
parent 8ba8d35541
commit e0737204fd
3 changed files with 97 additions and 119 deletions

View File

@ -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))

View File

@ -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; i<write_count; i++)
{
pdlg->Update(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;
}

View File

@ -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);