From 69388f032e44274831de8c72c0e3293868b3b334 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Wed, 24 Dec 2014 21:19:59 +0300 Subject: [PATCH] cellFs functions merged --- rpcs3/Emu/SysCalls/Modules/cellGifDec.cpp | 2 +- rpcs3/Emu/SysCalls/Modules/cellJpgDec.cpp | 2 +- rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp | 4 +- rpcs3/Emu/SysCalls/Modules/sys_fs.cpp | 347 ---------------- rpcs3/Emu/SysCalls/SysCalls.cpp | 2 +- .../SysCalls/lv2/{lv2Fs.cpp => cellFs.cpp} | 381 ++++++++++++++++-- rpcs3/Emu/SysCalls/lv2/{lv2Fs.h => cellFs.h} | 0 rpcs3/emucore.vcxproj | 5 +- rpcs3/emucore.vcxproj.filters | 15 +- 9 files changed, 372 insertions(+), 386 deletions(-) delete mode 100644 rpcs3/Emu/SysCalls/Modules/sys_fs.cpp rename rpcs3/Emu/SysCalls/lv2/{lv2Fs.cpp => cellFs.cpp} (61%) rename rpcs3/Emu/SysCalls/lv2/{lv2Fs.h => cellFs.h} (100%) diff --git a/rpcs3/Emu/SysCalls/Modules/cellGifDec.cpp b/rpcs3/Emu/SysCalls/Modules/cellGifDec.cpp index 8f214be1fc..48f52fa422 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGifDec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGifDec.cpp @@ -4,7 +4,7 @@ #include "stblib/stb_image.h" #include "stblib/stb_image.c" // (TODO: Should we put this elsewhere?) -#include "Emu/SysCalls/lv2/lv2Fs.h" +#include "Emu/SysCalls/lv2/cellFs.h" #include "cellGifDec.h" Module *cellGifDec = nullptr; diff --git a/rpcs3/Emu/SysCalls/Modules/cellJpgDec.cpp b/rpcs3/Emu/SysCalls/Modules/cellJpgDec.cpp index d068d229bf..e907298dc8 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellJpgDec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellJpgDec.cpp @@ -3,7 +3,7 @@ #include "Emu/SysCalls/Modules.h" #include "stblib/stb_image.h" -#include "Emu/SysCalls/lv2/lv2Fs.h" +#include "Emu/SysCalls/lv2/cellFs.h" #include "cellJpgDec.h" Module *cellJpgDec = nullptr; diff --git a/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp b/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp index 05e88cd71e..ba05527e58 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp @@ -4,12 +4,14 @@ #include "Emu/SysCalls/Modules.h" #include "stblib/stb_image.h" -#include "Emu/SysCalls/lv2/lv2Fs.h" +#include "Emu/SysCalls/lv2/cellFs.h" #include "cellPngDec.h" #include Module *cellPngDec = nullptr; +#undef PRX_DEBUG + #ifdef PRX_DEBUG #include "prx_libpngdec.h" u32 libpngdec; diff --git a/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp b/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp deleted file mode 100644 index b9b89b5db7..0000000000 --- a/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp +++ /dev/null @@ -1,347 +0,0 @@ -#include "stdafx.h" -#include "Emu/Memory/Memory.h" -#include "Emu/System.h" -#include "Emu/SysCalls/Modules.h" -#include "Emu/SysCalls/Callback.h" -#include "Emu/SysCalls/CB_FUNC.h" - -#include "Emu/FS/VFS.h" -#include "Emu/FS/vfsFileBase.h" -#include "Emu/SysCalls/lv2/lv2Fs.h" - -Module *sys_fs = nullptr; - -bool sdata_check(u32 version, u32 flags, u64 filesizeInput, u64 filesizeTmp) -{ - if (version > 4 || flags & 0x7EFFFFC0){ - printf("ERROR: unknown version"); - return false; - } - - if ((version == 1 && (flags & 0x7FFFFFFE)) || - (version == 2 && (flags & 0x7EFFFFC0))){ - printf("ERROR: unknown or unsupported type"); - return false; - } - - if (filesizeTmp > filesizeInput){ - printf("ERROR: input file size is too short."); - return false; - } - - if (!(flags & 0x80000000)){ - printf("ERROR: cannot extract finalized edata."); - return false; - } - - return true; -} - -int sdata_unpack(const std::string& packed_file, const std::string& unpacked_file) -{ - std::shared_ptr packed_stream(Emu.GetVFS().OpenFile(packed_file, vfsRead)); - std::shared_ptr unpacked_stream(Emu.GetVFS().OpenFile(unpacked_file, vfsWrite)); - - if(!packed_stream || !packed_stream->IsOpened()) - { - sys_fs->Error("'%s' not found! flags: 0x%08x", packed_file.c_str(), vfsRead); - return CELL_ENOENT; - } - - if(!unpacked_stream || !unpacked_stream->IsOpened()) - { - sys_fs->Error("'%s' couldn't be created! flags: 0x%08x", unpacked_file.c_str(), vfsWrite); - return CELL_ENOENT; - } - - char buffer [10200]; - packed_stream->Read(buffer, 256); - u32 format = re32(*(u32*)&buffer[0]); - if (format != 0x4E504400) // "NPD\x00" - { - sys_fs->Error("Illegal format. Expected 0x4E504400, but got 0x%08x", format); - return CELL_EFSSPECIFIC; - } - - u32 version = re32(*(u32*)&buffer[0x04]); - u32 flags = re32(*(u32*)&buffer[0x80]); - u32 blockSize = re32(*(u32*)&buffer[0x84]); - u64 filesizeOutput = re64(*(u64*)&buffer[0x88]); - u64 filesizeInput = packed_stream->GetSize(); - u32 blockCount = (u32)((filesizeOutput + blockSize - 1) / blockSize); - - // SDATA file is compressed - if (flags & 0x1) - { - sys_fs->Warning("cellFsSdataOpen: Compressed SDATA files are not supported yet."); - return CELL_EFSSPECIFIC; - } - - // SDATA file is NOT compressed - else - { - u32 t1 = (flags & 0x20) ? 0x20 : 0x10; - u32 startOffset = (blockCount * t1) + 0x100; - u64 filesizeTmp = (filesizeOutput+0xF)&0xFFFFFFF0 + startOffset; - - if (!sdata_check(version, flags, filesizeInput, filesizeTmp)) - { - sys_fs->Error("cellFsSdataOpen: Wrong header information."); - return CELL_EFSSPECIFIC; - } - - if (flags & 0x20) - packed_stream->Seek(0x100); - else - packed_stream->Seek(startOffset); - - for (u32 i = 0; i < blockCount; i++) - { - if (flags & 0x20) - packed_stream->Seek(packed_stream->Tell() + t1); - - if (!(blockCount-i-1)) - blockSize = (u32)(filesizeOutput - i * blockSize); - - packed_stream->Read(buffer+256, blockSize); - unpacked_stream->Write(buffer+256, blockSize); - } - } - - return CELL_OK; -} - - -int cellFsSdataOpen(vm::ptr path, int flags, vm::ptr> fd, vm::ptr arg, u64 size) -{ - sys_fs->Warning("cellFsSdataOpen(path=\"%s\", flags=0x%x, fd_addr=0x%x, arg_addr=0x%x, size=0x%llx) -> cellFsOpen()", - path.get_ptr(), flags, fd.addr(), arg.addr(), size); - - /*if (flags != CELL_O_RDONLY) - return CELL_EINVAL; - - std::string suffix = path.substr(path.length() - 5, 5); - if (suffix != ".sdat" && suffix != ".SDAT") - return CELL_ENOTSDATA; - - std::string::size_type last_slash = path.rfind('/'); //TODO: use a filesystem library to solve this more robustly - last_slash = last_slash == std::string::npos ? 0 : last_slash+1; - std::string unpacked_path = "/dev_hdd1/"+path.substr(last_slash,path.length()-last_slash)+".unpacked"; - int ret = sdata_unpack(path, unpacked_path); - if (ret) return ret; - - fd = sys_fs->GetNewId(Emu.GetVFS().OpenFile(unpacked_path, vfsRead), TYPE_FS_FILE); - - return CELL_OK;*/ - - return cellFsOpen(path, flags, fd, arg, size); -} - -int cellFsSdataOpenByFd(int mself_fd, int flags, vm::ptr sdata_fd, u64 offset, vm::ptr arg, u64 size) -{ - sys_fs->Todo("cellFsSdataOpenByFd(mself_fd=0x%x, flags=0x%x, sdata_fd_addr=0x%x, offset=0x%llx, arg_addr=0x%x, size=0x%llx) -> cellFsOpen()", - mself_fd, flags, sdata_fd.addr(), offset, arg.addr(), size); - - // TODO: - - return CELL_OK; -} - -std::atomic g_FsAioReadID( 0 ); -std::atomic g_FsAioReadCur( 0 ); -bool aio_init = false; - -void fsAioRead(u32 fd, vm::ptr aio, int xid, vm::ptr xaio, int error, int xid, u64 size)> func) -{ - while (g_FsAioReadCur != xid) - { - std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack - if (Emu.IsStopped()) - { - sys_fs->Warning("fsAioRead() aborted"); - return; - } - } - - u32 error = CELL_OK; - u64 res = 0; - { - LV2_LOCK(0); - - std::shared_ptr orig_file; - if (!sys_fs->CheckId(fd, orig_file)) - { - sys_fs->Error("Wrong fd (%s)", fd); - Emu.Pause(); - return; - } - - u64 nbytes = aio->size; - - vfsStream& file = *(vfsStream*)orig_file.get(); - const u64 old_pos = file.Tell(); - file.Seek((u64)aio->offset); - - // TODO: use code from cellFsRead or something - if (nbytes != (u32)nbytes) - { - error = CELL_ENOMEM; - } - else - { - res = nbytes ? file.Read(aio->buf.get_ptr(), nbytes) : 0; - } - - file.Seek(old_pos); - - sys_fs->Log("*** fsAioRead(fd=%d, offset=0x%llx, buf_addr=0x%x, size=0x%x, error=0x%x, res=0x%x, xid=0x%x [%s])", - fd, (u64)aio->offset, aio->buf.addr(), (u64)aio->size, error, res, xid, orig_file->GetPath().c_str()); - } - - if (func) // start callback thread - { - Emu.GetCallbackManager().Async([func, aio, error, xid, res]() - { - func(aio, error, xid, res); - }); - } - - g_FsAioReadCur++; -} - -int cellFsAioRead(vm::ptr aio, vm::ptr aio_id, vm::ptr xaio, int error, int xid, u64 size)> func) -{ - sys_fs->Warning("cellFsAioRead(aio_addr=0x%x, id_addr=0x%x, func_addr=0x%x)", aio.addr(), aio_id.addr(), func.addr()); - - LV2_LOCK(0); - - if (!aio_init) - { - return CELL_ENXIO; - } - - std::shared_ptr orig_file; - u32 fd = aio->fd; - - if (!sys_fs->CheckId(fd, orig_file)) - { - return CELL_EBADF; - } - - //get a unique id for the callback (may be used by cellFsAioCancel) - const u32 xid = g_FsAioReadID++; - *aio_id = xid; - - { - thread t("fsAioRead", std::bind(fsAioRead, fd, aio, xid, func)); - t.detach(); - } - - return CELL_OK; -} - -int cellFsAioWrite(vm::ptr aio, vm::ptr aio_id, vm::ptr xaio, int error, int xid, u64 size)> func) -{ - sys_fs->Todo("cellFsAioWrite(aio_addr=0x%x, id_addr=0x%x, func_addr=0x%x)", aio.addr(), aio_id.addr(), func.addr()); - - LV2_LOCK(0); - - // TODO: - - return CELL_OK; -} - -int cellFsAioInit(vm::ptr mount_point) -{ - sys_fs->Warning("cellFsAioInit(mount_point_addr=0x%x (%s))", mount_point.addr(), mount_point.get_ptr()); - - LV2_LOCK(0); - - aio_init = true; - return CELL_OK; -} - -int cellFsAioFinish(vm::ptr mount_point) -{ - sys_fs->Warning("cellFsAioFinish(mount_point_addr=0x%x (%s))", mount_point.addr(), mount_point.get_ptr()); - - LV2_LOCK(0); - - aio_init = false; - return CELL_OK; -} - -int cellFsReadWithOffset(u32 fd, u64 offset, vm::ptr buf, u64 buffer_size, vm::ptr> nread) -{ - sys_fs->Warning("cellFsReadWithOffset(fd=%d, offset=0x%llx, buf_addr=0x%x, buffer_size=%lld nread=0x%llx)", - fd, offset, buf.addr(), buffer_size, nread.addr()); - - LV2_LOCK(0); - - int ret; - vm::var> oldPos, newPos; - ret = cellFsLseek(fd, 0, CELL_SEEK_CUR, oldPos); // Save the current position - if (ret) return ret; - ret = cellFsLseek(fd, offset, CELL_SEEK_SET, newPos); // Move to the specified offset - if (ret) return ret; - ret = cellFsRead(fd, buf, buffer_size, nread); // Read the file - if (ret) return ret; - ret = cellFsLseek(fd, oldPos.value(), CELL_SEEK_SET, newPos); // Return to the old position - if (ret) return ret; - - return CELL_OK; -} - -void sys_fs_init(Module *pxThis) -{ - sys_fs = pxThis; - - sys_fs->AddFunc(0x718bf5f8, cellFsOpen); - sys_fs->AddFunc(0xb1840b53, cellFsSdataOpen); - sys_fs->AddFunc(0x6d3bb15b, cellFsSdataOpenByFd); - sys_fs->AddFunc(0x4d5ff8e2, cellFsRead); - sys_fs->AddFunc(0xecdcf2ab, cellFsWrite); - sys_fs->AddFunc(0x2cb51f0d, cellFsClose); - sys_fs->AddFunc(0x3f61245c, cellFsOpendir); - sys_fs->AddFunc(0x5c74903d, cellFsReaddir); - sys_fs->AddFunc(0xff42dcc3, cellFsClosedir); - sys_fs->AddFunc(0x7de6dced, cellFsStat); - sys_fs->AddFunc(0xef3efa34, cellFsFstat); - sys_fs->AddFunc(0xba901fe6, cellFsMkdir); - sys_fs->AddFunc(0xf12eecc8, cellFsRename); - sys_fs->AddFunc(0x99406d0b, cellFsChmod); - sys_fs->AddFunc(0x967a162b, cellFsFsync); - sys_fs->AddFunc(0x2796fdf3, cellFsRmdir); - sys_fs->AddFunc(0x7f4677a8, cellFsUnlink); - sys_fs->AddFunc(0xa397d042, cellFsLseek); - sys_fs->AddFunc(0x0e2939e5, cellFsFtruncate); - sys_fs->AddFunc(0xc9dc3ac5, cellFsTruncate); - sys_fs->AddFunc(0xcb588dba, cellFsFGetBlockSize); - sys_fs->AddFunc(0xc1c507e7, cellFsAioRead); - sys_fs->AddFunc(0x4cef342e, cellFsAioWrite); - sys_fs->AddFunc(0xdb869f20, cellFsAioInit); - sys_fs->AddFunc(0x9f951810, cellFsAioFinish); - sys_fs->AddFunc(0x1a108ab7, cellFsGetBlockSize); - sys_fs->AddFunc(0xaa3b4bcd, cellFsGetFreeSize); - sys_fs->AddFunc(0x0d5b4a14, cellFsReadWithOffset); - sys_fs->AddFunc(0x9b882495, cellFsGetDirectoryEntries); - sys_fs->AddFunc(0x2664c8ae, cellFsStReadInit); - sys_fs->AddFunc(0xd73938df, cellFsStReadFinish); - sys_fs->AddFunc(0xb3afee8b, cellFsStReadGetRingBuf); - sys_fs->AddFunc(0xcf34969c, cellFsStReadGetStatus); - sys_fs->AddFunc(0xbd273a88, cellFsStReadGetRegid); - sys_fs->AddFunc(0x8df28ff9, cellFsStReadStart); - sys_fs->AddFunc(0xf8e5d9a0, cellFsStReadStop); - sys_fs->AddFunc(0x27800c6b, cellFsStRead); - sys_fs->AddFunc(0x190912f6, cellFsStReadGetCurrentAddr); - sys_fs->AddFunc(0x81f33783, cellFsStReadPutCurrentAddr); - sys_fs->AddFunc(0x8f71c5b2, cellFsStReadWait); - sys_fs->AddFunc(0x866f6aec, cellFsStReadWaitCallback); -} - -void sys_fs_load() -{ - g_FsAioReadID = 0; - g_FsAioReadCur = 0; - aio_init = false; -} diff --git a/rpcs3/Emu/SysCalls/SysCalls.cpp b/rpcs3/Emu/SysCalls/SysCalls.cpp index 7f81d0f1a7..3747f3c391 100644 --- a/rpcs3/Emu/SysCalls/SysCalls.cpp +++ b/rpcs3/Emu/SysCalls/SysCalls.cpp @@ -8,7 +8,7 @@ #include "Emu/Memory/atomic_type.h" #include "Utilities/SQueue.h" -#include "lv2/lv2Fs.h" +#include "lv2/cellFs.h" #include "lv2/sleep_queue_type.h" #include "lv2/sys_lwmutex.h" #include "lv2/sys_mutex.h" diff --git a/rpcs3/Emu/SysCalls/lv2/lv2Fs.cpp b/rpcs3/Emu/SysCalls/lv2/cellFs.cpp similarity index 61% rename from rpcs3/Emu/SysCalls/lv2/lv2Fs.cpp rename to rpcs3/Emu/SysCalls/lv2/cellFs.cpp index adc59aa65b..d9be37b585 100644 --- a/rpcs3/Emu/SysCalls/lv2/lv2Fs.cpp +++ b/rpcs3/Emu/SysCalls/lv2/cellFs.cpp @@ -1,15 +1,16 @@ #include "stdafx.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" -//#include "Emu/SysCalls/SysCalls.h" - #include "Emu/SysCalls/Modules.h" +#include "Emu/SysCalls/Callback.h" +#include "Emu/SysCalls/CB_FUNC.h" + #include "Emu/FS/VFS.h" #include "Emu/FS/vfsFile.h" #include "Emu/FS/vfsDir.h" -#include "lv2Fs.h" +#include "cellFs.h" -extern Module *sys_fs; +Module *sys_fs = nullptr; struct FsRingBufferConfig { @@ -100,7 +101,7 @@ s32 cellFsOpen(vm::ptr path, s32 flags, vm::ptr> fd, vm::p return CELL_ENOENT; } - std::shared_ptr stream(Emu.GetVFS().OpenFile(_path, o_mode)); + std::shared_ptr stream((vfsStream*)Emu.GetVFS().OpenFile(_path, o_mode)); if (!stream || !stream->IsOpened()) { @@ -122,7 +123,7 @@ s32 cellFsRead(u32 fd, vm::ptr buf, u64 nbytes, vm::ptr> nread) LV2_LOCK(0); - std::shared_ptr file; + std::shared_ptr file; if (!sys_fs->CheckId(fd, file)) return CELL_ESRCH; @@ -145,7 +146,7 @@ s32 cellFsWrite(u32 fd, vm::ptr buf, u64 nbytes, vm::ptr nwrite LV2_LOCK(0); - std::shared_ptr file; + std::shared_ptr file; if (!sys_fs->CheckId(fd, file)) return CELL_ESRCH; if (nbytes != (u32)nbytes) return CELL_ENOMEM; @@ -275,7 +276,7 @@ s32 cellFsFstat(u32 fd, vm::ptr sb) LV2_LOCK(0); IDType type; - std::shared_ptr file; + std::shared_ptr file; if (!sys_fs->CheckId(fd, file, type) || type != TYPE_FS_FILE) return CELL_ESRCH; @@ -425,7 +426,7 @@ s32 cellFsLseek(u32 fd, s64 offset, u32 whence, vm::ptr> pos) } IDType type; - std::shared_ptr file; + std::shared_ptr file; if (!sys_fs->CheckId(fd, file, type) || type != TYPE_FS_FILE) return CELL_ESRCH; @@ -440,7 +441,7 @@ s32 cellFsFtruncate(u32 fd, u64 size) LV2_LOCK(0); IDType type; - std::shared_ptr file; + std::shared_ptr file; if (!sys_fs->CheckId(fd, file, type) || type != TYPE_FS_FILE) return CELL_ESRCH; @@ -503,7 +504,7 @@ s32 cellFsFGetBlockSize(u32 fd, vm::ptr sector_size, vm::ptr block_siz LV2_LOCK(0); - std::shared_ptr file; + std::shared_ptr file; if (!sys_fs->CheckId(fd, file)) return CELL_ESRCH; @@ -585,7 +586,7 @@ s32 cellFsStReadInit(u32 fd, vm::ptr ringbuf) LV2_LOCK(0); - std::shared_ptr file; + std::shared_ptr file; if (!sys_fs->CheckId(fd, file)) return CELL_ESRCH; @@ -612,7 +613,7 @@ s32 cellFsStReadFinish(u32 fd) LV2_LOCK(0); - std::shared_ptr file; + std::shared_ptr file; if (!sys_fs->CheckId(fd, file)) return CELL_ESRCH; @@ -628,7 +629,7 @@ s32 cellFsStReadGetRingBuf(u32 fd, vm::ptr ringbuf) LV2_LOCK(0); - std::shared_ptr file; + std::shared_ptr file; if (!sys_fs->CheckId(fd, file)) return CELL_ESRCH; @@ -645,7 +646,7 @@ s32 cellFsStReadGetStatus(u32 fd, vm::ptr status) LV2_LOCK(0); - std::shared_ptr file; + std::shared_ptr file; if (!sys_fs->CheckId(fd, file)) return CELL_ESRCH; @@ -660,7 +661,7 @@ s32 cellFsStReadGetRegid(u32 fd, vm::ptr regid) LV2_LOCK(0); - std::shared_ptr file; + std::shared_ptr file; if (!sys_fs->CheckId(fd, file)) return CELL_ESRCH; @@ -675,7 +676,7 @@ s32 cellFsStReadStart(u32 fd, u64 offset, u64 size) LV2_LOCK(0); - std::shared_ptr file; + std::shared_ptr file; if (!sys_fs->CheckId(fd, file)) return CELL_ESRCH; @@ -691,7 +692,7 @@ s32 cellFsStReadStop(u32 fd) LV2_LOCK(0); - std::shared_ptr file; + std::shared_ptr file; if (!sys_fs->CheckId(fd, file)) return CELL_ESRCH; @@ -706,7 +707,7 @@ s32 cellFsStRead(u32 fd, u32 buf_addr, u64 size, vm::ptr rsize) LV2_LOCK(0); - std::shared_ptr file; + std::shared_ptr file; if (!sys_fs->CheckId(fd, file)) return CELL_ESRCH; @@ -727,7 +728,7 @@ s32 cellFsStReadGetCurrentAddr(u32 fd, vm::ptr addr, vm::ptr size) LV2_LOCK(0); - std::shared_ptr file; + std::shared_ptr file; if (!sys_fs->CheckId(fd, file)) return CELL_ESRCH; @@ -740,7 +741,7 @@ s32 cellFsStReadPutCurrentAddr(u32 fd, u32 addr_addr, u64 size) LV2_LOCK(0); - std::shared_ptr file; + std::shared_ptr file; if (!sys_fs->CheckId(fd, file)) return CELL_ESRCH; @@ -753,7 +754,7 @@ s32 cellFsStReadWait(u32 fd, u64 size) LV2_LOCK(0); - std::shared_ptr file; + std::shared_ptr file; if (!sys_fs->CheckId(fd, file)) return CELL_ESRCH; @@ -766,9 +767,343 @@ s32 cellFsStReadWaitCallback(u32 fd, u64 size, vm::ptr file; + std::shared_ptr file; if (!sys_fs->CheckId(fd, file)) return CELL_ESRCH; return CELL_OK; } + +bool sdata_check(u32 version, u32 flags, u64 filesizeInput, u64 filesizeTmp) +{ + if (version > 4 || flags & 0x7EFFFFC0){ + printf("ERROR: unknown version"); + return false; + } + + if ((version == 1 && (flags & 0x7FFFFFFE)) || + (version == 2 && (flags & 0x7EFFFFC0))){ + printf("ERROR: unknown or unsupported type"); + return false; + } + + if (filesizeTmp > filesizeInput){ + printf("ERROR: input file size is too short."); + return false; + } + + if (!(flags & 0x80000000)){ + printf("ERROR: cannot extract finalized edata."); + return false; + } + + return true; +} + +int sdata_unpack(const std::string& packed_file, const std::string& unpacked_file) +{ + std::shared_ptr packed_stream(Emu.GetVFS().OpenFile(packed_file, vfsRead)); + std::shared_ptr unpacked_stream(Emu.GetVFS().OpenFile(unpacked_file, vfsWrite)); + + if (!packed_stream || !packed_stream->IsOpened()) + { + sys_fs->Error("'%s' not found! flags: 0x%08x", packed_file.c_str(), vfsRead); + return CELL_ENOENT; + } + + if (!unpacked_stream || !unpacked_stream->IsOpened()) + { + sys_fs->Error("'%s' couldn't be created! flags: 0x%08x", unpacked_file.c_str(), vfsWrite); + return CELL_ENOENT; + } + + char buffer[10200]; + packed_stream->Read(buffer, 256); + u32 format = re32(*(u32*)&buffer[0]); + if (format != 0x4E504400) // "NPD\x00" + { + sys_fs->Error("Illegal format. Expected 0x4E504400, but got 0x%08x", format); + return CELL_EFSSPECIFIC; + } + + u32 version = re32(*(u32*)&buffer[0x04]); + u32 flags = re32(*(u32*)&buffer[0x80]); + u32 blockSize = re32(*(u32*)&buffer[0x84]); + u64 filesizeOutput = re64(*(u64*)&buffer[0x88]); + u64 filesizeInput = packed_stream->GetSize(); + u32 blockCount = (u32)((filesizeOutput + blockSize - 1) / blockSize); + + // SDATA file is compressed + if (flags & 0x1) + { + sys_fs->Warning("cellFsSdataOpen: Compressed SDATA files are not supported yet."); + return CELL_EFSSPECIFIC; + } + + // SDATA file is NOT compressed + else + { + u32 t1 = (flags & 0x20) ? 0x20 : 0x10; + u32 startOffset = (blockCount * t1) + 0x100; + u64 filesizeTmp = (filesizeOutput + 0xF) & 0xFFFFFFF0 + startOffset; + + if (!sdata_check(version, flags, filesizeInput, filesizeTmp)) + { + sys_fs->Error("cellFsSdataOpen: Wrong header information."); + return CELL_EFSSPECIFIC; + } + + if (flags & 0x20) + packed_stream->Seek(0x100); + else + packed_stream->Seek(startOffset); + + for (u32 i = 0; i < blockCount; i++) + { + if (flags & 0x20) + packed_stream->Seek(packed_stream->Tell() + t1); + + if (!(blockCount - i - 1)) + blockSize = (u32)(filesizeOutput - i * blockSize); + + packed_stream->Read(buffer + 256, blockSize); + unpacked_stream->Write(buffer + 256, blockSize); + } + } + + return CELL_OK; +} + +int cellFsSdataOpen(vm::ptr path, int flags, vm::ptr> fd, vm::ptr arg, u64 size) +{ + sys_fs->Warning("cellFsSdataOpen(path=\"%s\", flags=0x%x, fd_addr=0x%x, arg_addr=0x%x, size=0x%llx) -> cellFsOpen()", + path.get_ptr(), flags, fd.addr(), arg.addr(), size); + + /*if (flags != CELL_O_RDONLY) + return CELL_EINVAL; + + std::string suffix = path.substr(path.length() - 5, 5); + if (suffix != ".sdat" && suffix != ".SDAT") + return CELL_ENOTSDATA; + + std::string::size_type last_slash = path.rfind('/'); //TODO: use a filesystem library to solve this more robustly + last_slash = last_slash == std::string::npos ? 0 : last_slash+1; + std::string unpacked_path = "/dev_hdd1/"+path.substr(last_slash,path.length()-last_slash)+".unpacked"; + int ret = sdata_unpack(path, unpacked_path); + if (ret) return ret; + + fd = sys_fs->GetNewId(Emu.GetVFS().OpenFile(unpacked_path, vfsRead), TYPE_FS_FILE); + + return CELL_OK;*/ + + return cellFsOpen(path, flags, fd, arg, size); +} + +int cellFsSdataOpenByFd(int mself_fd, int flags, vm::ptr sdata_fd, u64 offset, vm::ptr arg, u64 size) +{ + sys_fs->Todo("cellFsSdataOpenByFd(mself_fd=0x%x, flags=0x%x, sdata_fd_addr=0x%x, offset=0x%llx, arg_addr=0x%x, size=0x%llx) -> cellFsOpen()", + mself_fd, flags, sdata_fd.addr(), offset, arg.addr(), size); + + // TODO: + + return CELL_OK; +} + +std::atomic g_FsAioReadID(0); +std::atomic g_FsAioReadCur(0); +bool aio_init = false; + +void fsAioRead(u32 fd, vm::ptr aio, int xid, vm::ptr xaio, int error, int xid, u64 size)> func) +{ + while (g_FsAioReadCur != xid) + { + std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + if (Emu.IsStopped()) + { + sys_fs->Warning("fsAioRead() aborted"); + return; + } + } + + u32 error = CELL_OK; + u64 res = 0; + { + LV2_LOCK(0); + + std::shared_ptr orig_file; + if (!sys_fs->CheckId(fd, orig_file)) + { + sys_fs->Error("Wrong fd (%s)", fd); + Emu.Pause(); + return; + } + + u64 nbytes = aio->size; + + vfsStream& file = *orig_file; + const u64 old_pos = file.Tell(); + file.Seek((u64)aio->offset); + + // TODO: use code from cellFsRead or something + if (nbytes != (u32)nbytes) + { + error = CELL_ENOMEM; + } + else + { + res = nbytes ? file.Read(aio->buf.get_ptr(), nbytes) : 0; + } + + file.Seek(old_pos); + + sys_fs->Log("*** fsAioRead(fd=%d, offset=0x%llx, buf_addr=0x%x, size=0x%x, error=0x%x, res=0x%x, xid=0x%x)", + fd, (u64)aio->offset, aio->buf.addr(), (u64)aio->size, error, res, xid); + } + + if (func) // start callback thread + { + Emu.GetCallbackManager().Async([func, aio, error, xid, res]() + { + func(aio, error, xid, res); + }); + } + + g_FsAioReadCur++; +} + +int cellFsAioRead(vm::ptr aio, vm::ptr aio_id, vm::ptr xaio, int error, int xid, u64 size)> func) +{ + sys_fs->Warning("cellFsAioRead(aio_addr=0x%x, id_addr=0x%x, func_addr=0x%x)", aio.addr(), aio_id.addr(), func.addr()); + + LV2_LOCK(0); + + if (!aio_init) + { + return CELL_ENXIO; + } + + std::shared_ptr orig_file; + u32 fd = aio->fd; + + if (!sys_fs->CheckId(fd, orig_file)) + { + return CELL_EBADF; + } + + //get a unique id for the callback (may be used by cellFsAioCancel) + const u32 xid = g_FsAioReadID++; + *aio_id = xid; + + { + thread t("fsAioRead", std::bind(fsAioRead, fd, aio, xid, func)); + t.detach(); + } + + return CELL_OK; +} + +int cellFsAioWrite(vm::ptr aio, vm::ptr aio_id, vm::ptr xaio, int error, int xid, u64 size)> func) +{ + sys_fs->Todo("cellFsAioWrite(aio_addr=0x%x, id_addr=0x%x, func_addr=0x%x)", aio.addr(), aio_id.addr(), func.addr()); + + LV2_LOCK(0); + + // TODO: + + return CELL_OK; +} + +int cellFsAioInit(vm::ptr mount_point) +{ + sys_fs->Warning("cellFsAioInit(mount_point_addr=0x%x (%s))", mount_point.addr(), mount_point.get_ptr()); + + LV2_LOCK(0); + + aio_init = true; + return CELL_OK; +} + +int cellFsAioFinish(vm::ptr mount_point) +{ + sys_fs->Warning("cellFsAioFinish(mount_point_addr=0x%x (%s))", mount_point.addr(), mount_point.get_ptr()); + + LV2_LOCK(0); + + aio_init = false; + return CELL_OK; +} + +int cellFsReadWithOffset(u32 fd, u64 offset, vm::ptr buf, u64 buffer_size, vm::ptr> nread) +{ + sys_fs->Warning("cellFsReadWithOffset(fd=%d, offset=0x%llx, buf_addr=0x%x, buffer_size=%lld nread=0x%llx)", + fd, offset, buf.addr(), buffer_size, nread.addr()); + + LV2_LOCK(0); + + int ret; + vm::var> oldPos, newPos; + ret = cellFsLseek(fd, 0, CELL_SEEK_CUR, oldPos); // Save the current position + if (ret) return ret; + ret = cellFsLseek(fd, offset, CELL_SEEK_SET, newPos); // Move to the specified offset + if (ret) return ret; + ret = cellFsRead(fd, buf, buffer_size, nread); // Read the file + if (ret) return ret; + ret = cellFsLseek(fd, oldPos.value(), CELL_SEEK_SET, newPos); // Return to the old position + if (ret) return ret; + + return CELL_OK; +} + +void sys_fs_init(Module *pxThis) +{ + sys_fs = pxThis; + + sys_fs->AddFunc(0x718bf5f8, cellFsOpen); + sys_fs->AddFunc(0xb1840b53, cellFsSdataOpen); + sys_fs->AddFunc(0x6d3bb15b, cellFsSdataOpenByFd); + sys_fs->AddFunc(0x4d5ff8e2, cellFsRead); + sys_fs->AddFunc(0xecdcf2ab, cellFsWrite); + sys_fs->AddFunc(0x2cb51f0d, cellFsClose); + sys_fs->AddFunc(0x3f61245c, cellFsOpendir); + sys_fs->AddFunc(0x5c74903d, cellFsReaddir); + sys_fs->AddFunc(0xff42dcc3, cellFsClosedir); + sys_fs->AddFunc(0x7de6dced, cellFsStat); + sys_fs->AddFunc(0xef3efa34, cellFsFstat); + sys_fs->AddFunc(0xba901fe6, cellFsMkdir); + sys_fs->AddFunc(0xf12eecc8, cellFsRename); + sys_fs->AddFunc(0x99406d0b, cellFsChmod); + sys_fs->AddFunc(0x967a162b, cellFsFsync); + sys_fs->AddFunc(0x2796fdf3, cellFsRmdir); + sys_fs->AddFunc(0x7f4677a8, cellFsUnlink); + sys_fs->AddFunc(0xa397d042, cellFsLseek); + sys_fs->AddFunc(0x0e2939e5, cellFsFtruncate); + sys_fs->AddFunc(0xc9dc3ac5, cellFsTruncate); + sys_fs->AddFunc(0xcb588dba, cellFsFGetBlockSize); + sys_fs->AddFunc(0xc1c507e7, cellFsAioRead); + sys_fs->AddFunc(0x4cef342e, cellFsAioWrite); + sys_fs->AddFunc(0xdb869f20, cellFsAioInit); + sys_fs->AddFunc(0x9f951810, cellFsAioFinish); + sys_fs->AddFunc(0x1a108ab7, cellFsGetBlockSize); + sys_fs->AddFunc(0xaa3b4bcd, cellFsGetFreeSize); + sys_fs->AddFunc(0x0d5b4a14, cellFsReadWithOffset); + sys_fs->AddFunc(0x9b882495, cellFsGetDirectoryEntries); + sys_fs->AddFunc(0x2664c8ae, cellFsStReadInit); + sys_fs->AddFunc(0xd73938df, cellFsStReadFinish); + sys_fs->AddFunc(0xb3afee8b, cellFsStReadGetRingBuf); + sys_fs->AddFunc(0xcf34969c, cellFsStReadGetStatus); + sys_fs->AddFunc(0xbd273a88, cellFsStReadGetRegid); + sys_fs->AddFunc(0x8df28ff9, cellFsStReadStart); + sys_fs->AddFunc(0xf8e5d9a0, cellFsStReadStop); + sys_fs->AddFunc(0x27800c6b, cellFsStRead); + sys_fs->AddFunc(0x190912f6, cellFsStReadGetCurrentAddr); + sys_fs->AddFunc(0x81f33783, cellFsStReadPutCurrentAddr); + sys_fs->AddFunc(0x8f71c5b2, cellFsStReadWait); + sys_fs->AddFunc(0x866f6aec, cellFsStReadWaitCallback); +} + +void sys_fs_load() +{ + g_FsAioReadID = 0; + g_FsAioReadCur = 0; + aio_init = false; +} diff --git a/rpcs3/Emu/SysCalls/lv2/lv2Fs.h b/rpcs3/Emu/SysCalls/lv2/cellFs.h similarity index 100% rename from rpcs3/Emu/SysCalls/lv2/lv2Fs.h rename to rpcs3/Emu/SysCalls/lv2/cellFs.h diff --git a/rpcs3/emucore.vcxproj b/rpcs3/emucore.vcxproj index e5dacacccb..80fecdf4f6 100644 --- a/rpcs3/emucore.vcxproj +++ b/rpcs3/emucore.vcxproj @@ -132,7 +132,7 @@ - + @@ -231,7 +231,6 @@ - @@ -382,7 +381,7 @@ - + diff --git a/rpcs3/emucore.vcxproj.filters b/rpcs3/emucore.vcxproj.filters index 40cac8b21b..a680c4e84b 100644 --- a/rpcs3/emucore.vcxproj.filters +++ b/rpcs3/emucore.vcxproj.filters @@ -257,9 +257,6 @@ Emu\SysCalls\Modules - - Emu\SysCalls\Modules - Emu\SysCalls\Modules @@ -545,9 +542,6 @@ Emu\SysCalls\lv2 - - Emu\SysCalls\lv2 - Utilities @@ -656,6 +650,9 @@ Emu\SysCalls + + Emu\SysCalls\lv2 + @@ -1114,9 +1111,6 @@ Emu\SysCalls\lv2 - - Emu\SysCalls\lv2 - Utilities @@ -1264,5 +1258,8 @@ Emu\SysCalls\lv2 + + Emu\SysCalls\lv2 + \ No newline at end of file