diff --git a/rpcs3/Crypto/unpkg.cpp b/rpcs3/Crypto/unpkg.cpp index 5d7846046f..bf9fd0edea 100644 --- a/rpcs3/Crypto/unpkg.cpp +++ b/rpcs3/Crypto/unpkg.cpp @@ -158,24 +158,31 @@ bool LoadEntries(rFile& dec_pkg_f, PKGHeader* m_header, PKGEntry *m_entries) 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.Read(buf, entry.name_size); buf[entry.name_size] = 0; - switch (entry.type & (0xff)) + switch (entry.type.ToBE() >> 24) { - case PKG_FILE_ENTRY_NPDRM: - case PKG_FILE_ENTRY_NPDRMEDAT: - case PKG_FILE_ENTRY_SDAT: - case PKG_FILE_ENTRY_REGULAR: + case PKG_FILE_ENTRY_NPDRM: + case PKG_FILE_ENTRY_NPDRMEDAT: + case PKG_FILE_ENTRY_SDAT: + case PKG_FILE_ENTRY_REGULAR: + { + rFile out; + 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 */)) { - rFile out; - out.Create(dir + std::string(reinterpret_cast(buf), entry.name_size)); dec_pkg_f.Seek(entry.file_offset); - for (u64 size = 0; size < entry.file_size; ) { + for (u64 size = 0; size < entry.file_size;) { size += dec_pkg_f.Read(buf, BUF_SIZE); if (size > entry.file_size) out.Write(buf, BUF_SIZE - (size - entry.file_size)); @@ -183,14 +190,33 @@ bool UnpackEntry(rFile& dec_pkg_f, const PKGEntry& entry, std::string dir) out.Write(buf, BUF_SIZE); } 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: - rMkdir(dir + std::string(reinterpret_cast(buf), entry.name_size)); - break; } - return true; + + case PKG_FILE_ENTRY_FOLDER: + { + 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; + } + + 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) diff --git a/rpcs3/Emu/CPU/CPUThread.cpp b/rpcs3/Emu/CPU/CPUThread.cpp index a810e96b5d..7a5db79e79 100644 --- a/rpcs3/Emu/CPU/CPUThread.cpp +++ b/rpcs3/Emu/CPU/CPUThread.cpp @@ -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 bool is_writing = pExp->ExceptionRecord->ExceptionInformation[0] != 0; - CPUThread* t = GetCurrentCPUThread(); - if (u == EXCEPTION_ACCESS_VIOLATION && addr64 < 0x100000000 && t) + if (u == EXCEPTION_ACCESS_VIOLATION && addr64 < 0x100000000) { const u32 addr = (u32)addr64; if (addr >= RAW_SPU_BASE_ADDR && (addr % RAW_SPU_OFFSET) >= RAW_SPU_PROB_OFFSET) // RawSPU MMIO registers @@ -452,7 +451,7 @@ void _se_translator(unsigned int u, EXCEPTION_POINTERS* pExp) } default: assert(!"Invalid x64_op_t value"); } - + // save x64 reg value (for load operations) if (save_reg) { @@ -475,8 +474,15 @@ void _se_translator(unsigned int u, EXCEPTION_POINTERS* pExp) // it's dangerous because destructors won't be executed } // 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))", - is_writing ? "writing" : "reading", (u32)addr, t->IsAlive() ? 1 : 0, t->m_last_syscall, SysCalls::GetHLEFuncName((u32)t->m_last_syscall).c_str()); + if (CPUThread* t = GetCurrentCPUThread()) + { + 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) @@ -504,8 +510,6 @@ void CPUThread::Task() #ifdef _WIN32 auto old_se_translator = _set_se_translator(_se_translator); -#else - // TODO: linux version #endif try @@ -558,8 +562,6 @@ void CPUThread::Task() #ifdef _WIN32 _set_se_translator(old_se_translator); -#else - // TODO: linux version #endif if (trace.size()) diff --git a/rpcs3/Loader/PKG.cpp b/rpcs3/Loader/PKG.cpp index 71478074d5..022a11085e 100644 --- a/rpcs3/Loader/PKG.cpp +++ b/rpcs3/Loader/PKG.cpp @@ -28,16 +28,13 @@ bool PKGLoader::Install(std::string dest) std::string titleID = std::string(title_id).substr(7, 9); 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) { LOG_ERROR(LOADER, "PKG Loader: Another installation found in: %s", titleID.c_str()); return false; } - - rRmdir(dest + titleID); - } - if (!rMkdir(dest + titleID)) { - LOG_ERROR(LOADER, "PKG Loader: Could not make the installation directory: %s", titleID.c_str()); + } else if (!rMkdir(dest + titleID)) { + LOG_ERROR(LOADER, "PKG Loader: Could not create the installation directory: %s", titleID.c_str()); return false; }