mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-14 18:58:36 +12:00
PKG installer improved
Now it doesn't attempt to delete existing directory and overwrites only existing files. It should fix installing updates.
This commit is contained in:
parent
22497757e9
commit
27cfdc897b
3 changed files with 55 additions and 30 deletions
|
@ -158,13 +158,13 @@ bool LoadEntries(rFile& dec_pkg_f, PKGHeader* m_header, PKGEntry *m_entries)
|
||||||
|
|
||||||
bool UnpackEntry(rFile& dec_pkg_f, const PKGEntry& entry, std::string dir)
|
bool UnpackEntry(rFile& dec_pkg_f, const PKGEntry& entry, std::string dir)
|
||||||
{
|
{
|
||||||
u8 buf[BUF_SIZE];
|
char buf[BUF_SIZE];
|
||||||
|
|
||||||
dec_pkg_f.Seek(entry.name_offset);
|
dec_pkg_f.Seek(entry.name_offset);
|
||||||
dec_pkg_f.Read(buf, entry.name_size);
|
dec_pkg_f.Read(buf, entry.name_size);
|
||||||
buf[entry.name_size] = 0;
|
buf[entry.name_size] = 0;
|
||||||
|
|
||||||
switch (entry.type & (0xff))
|
switch (entry.type.ToBE() >> 24)
|
||||||
{
|
{
|
||||||
case PKG_FILE_ENTRY_NPDRM:
|
case PKG_FILE_ENTRY_NPDRM:
|
||||||
case PKG_FILE_ENTRY_NPDRMEDAT:
|
case PKG_FILE_ENTRY_NPDRMEDAT:
|
||||||
|
@ -172,7 +172,14 @@ bool UnpackEntry(rFile& dec_pkg_f, const PKGEntry& entry, std::string dir)
|
||||||
case PKG_FILE_ENTRY_REGULAR:
|
case PKG_FILE_ENTRY_REGULAR:
|
||||||
{
|
{
|
||||||
rFile out;
|
rFile out;
|
||||||
out.Create(dir + std::string(reinterpret_cast<char *>(buf), entry.name_size));
|
auto path = dir + std::string(buf, entry.name_size);
|
||||||
|
if (rExists(path))
|
||||||
|
{
|
||||||
|
LOG_WARNING(LOADER, "PKG Loader: File is overwritten: %s", path.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (out.Create(path, true /* overwriting */))
|
||||||
|
{
|
||||||
dec_pkg_f.Seek(entry.file_offset);
|
dec_pkg_f.Seek(entry.file_offset);
|
||||||
|
|
||||||
for (u64 size = 0; size < entry.file_size;) {
|
for (u64 size = 0; size < entry.file_size;) {
|
||||||
|
@ -183,16 +190,35 @@ bool UnpackEntry(rFile& dec_pkg_f, const PKGEntry& entry, std::string dir)
|
||||||
out.Write(buf, BUF_SIZE);
|
out.Write(buf, BUF_SIZE);
|
||||||
}
|
}
|
||||||
out.Close();
|
out.Close();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG_ERROR(LOADER, "PKG Loader: Could not create file: %s", path.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
case PKG_FILE_ENTRY_FOLDER:
|
case PKG_FILE_ENTRY_FOLDER:
|
||||||
rMkdir(dir + std::string(reinterpret_cast<char *>(buf), entry.name_size));
|
{
|
||||||
break;
|
auto path = dir + std::string(buf, entry.name_size);
|
||||||
|
if (!rExists(path) && !rMkdir(path))
|
||||||
|
{
|
||||||
|
LOG_ERROR(LOADER, "PKG Loader: Could not create directory: %s", path.c_str());
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
LOG_ERROR(LOADER, "PKG Loader: unknown PKG file entry: 0x%x", entry.type.ToLE());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int Unpack(rFile& pkg_f, std::string src, std::string dst)
|
int Unpack(rFile& pkg_f, std::string src, std::string dst)
|
||||||
{
|
{
|
||||||
PKGHeader* m_header = (PKGHeader*) malloc (sizeof(PKGHeader));
|
PKGHeader* m_header = (PKGHeader*) malloc (sizeof(PKGHeader));
|
||||||
|
|
|
@ -404,8 +404,7 @@ void _se_translator(unsigned int u, EXCEPTION_POINTERS* pExp)
|
||||||
{
|
{
|
||||||
const u64 addr64 = (u64)pExp->ExceptionRecord->ExceptionInformation[1] - (u64)Memory.GetBaseAddr();
|
const u64 addr64 = (u64)pExp->ExceptionRecord->ExceptionInformation[1] - (u64)Memory.GetBaseAddr();
|
||||||
const bool is_writing = pExp->ExceptionRecord->ExceptionInformation[0] != 0;
|
const bool is_writing = pExp->ExceptionRecord->ExceptionInformation[0] != 0;
|
||||||
CPUThread* t = GetCurrentCPUThread();
|
if (u == EXCEPTION_ACCESS_VIOLATION && addr64 < 0x100000000)
|
||||||
if (u == EXCEPTION_ACCESS_VIOLATION && addr64 < 0x100000000 && t)
|
|
||||||
{
|
{
|
||||||
const u32 addr = (u32)addr64;
|
const u32 addr = (u32)addr64;
|
||||||
if (addr >= RAW_SPU_BASE_ADDR && (addr % RAW_SPU_OFFSET) >= RAW_SPU_PROB_OFFSET) // RawSPU MMIO registers
|
if (addr >= RAW_SPU_BASE_ADDR && (addr % RAW_SPU_OFFSET) >= RAW_SPU_PROB_OFFSET) // RawSPU MMIO registers
|
||||||
|
@ -475,8 +474,15 @@ void _se_translator(unsigned int u, EXCEPTION_POINTERS* pExp)
|
||||||
// it's dangerous because destructors won't be executed
|
// it's dangerous because destructors won't be executed
|
||||||
}
|
}
|
||||||
// TODO: allow recovering from a page fault as a feature of PS3 virtual memory
|
// TODO: allow recovering from a page fault as a feature of PS3 virtual memory
|
||||||
throw fmt::Format("Access violation %s location 0x%x (is_alive=%d, last_syscall=0x%llx (%s))",
|
if (CPUThread* t = GetCurrentCPUThread())
|
||||||
is_writing ? "writing" : "reading", (u32)addr, t->IsAlive() ? 1 : 0, t->m_last_syscall, SysCalls::GetHLEFuncName((u32)t->m_last_syscall).c_str());
|
{
|
||||||
|
throw fmt::Format("Access violation %s location 0x%x (is_alive=%d, last_syscall=0x%llx (%s))", is_writing ? "writing" : "reading", (u32)addr,
|
||||||
|
t->IsAlive() ? 1 : 0, t->m_last_syscall, SysCalls::GetHLEFuncName((u32)t->m_last_syscall).c_str());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw fmt::Format("Access violation %s location 0x%x", is_writing ? "writing" : "reading", (u32)addr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// else some fatal error (should crash)
|
// else some fatal error (should crash)
|
||||||
|
@ -504,8 +510,6 @@ void CPUThread::Task()
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
auto old_se_translator = _set_se_translator(_se_translator);
|
auto old_se_translator = _set_se_translator(_se_translator);
|
||||||
#else
|
|
||||||
// TODO: linux version
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
try
|
try
|
||||||
|
@ -558,8 +562,6 @@ void CPUThread::Task()
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
_set_se_translator(old_se_translator);
|
_set_se_translator(old_se_translator);
|
||||||
#else
|
|
||||||
// TODO: linux version
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (trace.size())
|
if (trace.size())
|
||||||
|
|
|
@ -28,16 +28,13 @@ bool PKGLoader::Install(std::string dest)
|
||||||
std::string titleID = std::string(title_id).substr(7, 9);
|
std::string titleID = std::string(title_id).substr(7, 9);
|
||||||
|
|
||||||
if (rExists(dest + titleID)) {
|
if (rExists(dest + titleID)) {
|
||||||
rMessageDialog d_overwrite(NULL, "Another installation was found. Do you want to overwrite it?", "PKG Decrypter / Installer", rYES_NO|rCENTRE);
|
rMessageDialog d_overwrite(NULL, "Another installation found. Do you want to overwrite it?", "PKG Decrypter / Installer", rYES_NO|rCENTRE);
|
||||||
if (d_overwrite.ShowModal() != rID_YES) {
|
if (d_overwrite.ShowModal() != rID_YES) {
|
||||||
LOG_ERROR(LOADER, "PKG Loader: Another installation found in: %s", titleID.c_str());
|
LOG_ERROR(LOADER, "PKG Loader: Another installation found in: %s", titleID.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
} else if (!rMkdir(dest + titleID)) {
|
||||||
rRmdir(dest + titleID);
|
LOG_ERROR(LOADER, "PKG Loader: Could not create the installation directory: %s", titleID.c_str());
|
||||||
}
|
|
||||||
if (!rMkdir(dest + titleID)) {
|
|
||||||
LOG_ERROR(LOADER, "PKG Loader: Could not make the installation directory: %s", titleID.c_str());
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue