diff --git a/Utilities/rFile.cpp b/Utilities/rFile.cpp index 5013734cda..5311285f89 100644 --- a/Utilities/rFile.cpp +++ b/Utilities/rFile.cpp @@ -61,6 +61,8 @@ bool truncate_file(const std::string& file, uint64_t length) } #else +#include +#include #include #include #if defined(__APPLE__) || defined(__FreeBSD__) @@ -323,16 +325,11 @@ rfile_t::~rfile_t() #else if (fd != -1) { - close(fd); + ::close(fd); } #endif } -rfile_t::rfile_t(handle_type handle) - : fd(handle) -{ -} - rfile_t::rfile_t(const std::string& filename, u32 mode) #ifdef _WIN32 : fd(INVALID_HANDLE_VALUE) @@ -352,14 +349,29 @@ rfile_t::operator bool() const #endif } +void rfile_t::import(handle_type handle) +{ + this->~rfile_t(); + fd = handle; +} + bool rfile_t::open(const std::string& filename, u32 mode) { this->~rfile_t(); #ifdef _WIN32 DWORD access = 0; - if (mode & o_read) access |= GENERIC_READ; - if (mode & o_write) access |= GENERIC_WRITE; + switch (mode & (o_read | o_write)) + { + case o_read: access |= GENERIC_READ; break; + case o_write: access |= GENERIC_WRITE; break; + case o_read | o_write: access |= GENERIC_READ | GENERIC_WRITE; break; + default: + { + LOG_ERROR(GENERAL, "rfile_t::open(): neither o_read nor o_write specified"); + return false; + } + } DWORD disp = 0; switch (mode & (o_create | o_trunc | o_excl)) @@ -369,25 +381,41 @@ bool rfile_t::open(const std::string& filename, u32 mode) case o_trunc: disp = TRUNCATE_EXISTING; break; case o_create | o_trunc: disp = CREATE_ALWAYS; break; case o_create | o_excl: disp = CREATE_NEW; break; - case o_excl: // ??? - case o_trunc | o_excl: // ??? - case o_create | o_trunc | o_excl: // ??? + } + + if (!disp || (mode & ~(o_read | o_write | o_create | o_trunc | o_excl))) { LOG_ERROR(GENERAL, "rfile_t::open(): unknown mode specified (0x%x)", mode); return false; } - } fd = CreateFileW(ConvertUTF8ToWChar(filename).get(), access, FILE_SHARE_READ, NULL, disp, FILE_ATTRIBUTE_NORMAL, NULL); #else int flags = 0; - if (mode & o_read) flags |= O_READ; - if (mode & o_write) flags |= O_WRITE; + + switch (mode & (o_read | o_write)) + { + case o_read: flags |= O_READ; break; + case o_write: flags |= O_WRITE; break; + case o_read | o_write: flags |= O_RDWR; break; + default: + { + LOG_ERROR(GENERAL, "rfile_t::open(): neither o_read nor o_write specified"); + return false; + } + } + if (mode & o_create) flags |= O_CREAT; if (mode & o_trunc) flags |= O_TRUNC; if (mode & o_excl) flags |= O_EXCL; - fd = open(filename.c_str(), flags, 0666); + if (((mode & o_excl) && (!(mode & o_create) || (mode & o_trunc))) || (mode & ~(o_read | o_write | o_create | o_trunc | o_excl))) + { + LOG_ERROR(GENERAL, "rfile_t::open(): unknown mode specified (0x%x)", mode); + return false; + } + + fd = ::open(filename.c_str(), flags, 0666); #endif return is_opened(); @@ -427,7 +455,7 @@ bool rfile_t::close() return true; } #else - if (!close(fd)) + if (!::close(fd)) { fd = -1; return true; diff --git a/Utilities/rFile.h b/Utilities/rFile.h index 144eac09e2..1f2ec21023 100644 --- a/Utilities/rFile.h +++ b/Utilities/rFile.h @@ -54,7 +54,6 @@ private: public: rfile_t(); ~rfile_t(); - explicit rfile_t(handle_type fd); explicit rfile_t(const std::string& filename, u32 mode = o_read); rfile_t(const rfile_t&) = delete; @@ -65,6 +64,7 @@ public: operator bool() const; + void import(handle_type fd); bool open(const std::string& filename, u32 mode = o_read); bool is_opened() const; bool trunc(u64 size) const; diff --git a/rpcs3/Emu/SysCalls/Modules/cellGame.cpp b/rpcs3/Emu/SysCalls/Modules/cellGame.cpp index d1fe7a9c31..cccc65d902 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGame.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGame.cpp @@ -381,9 +381,9 @@ s32 cellGameCreateGameData(vm::ptr init, vm::ptrtitleId; - contentInfo = "/dev_hdd0/game/" + titleId; - usrdir = "/dev_hdd0/game/" + titleId + "/USRDIR"; + std::string title = init->title; + contentInfo = "/dev_hdd0/game/" + title; + usrdir = "/dev_hdd0/game/" + title + "/USRDIR"; if (!Emu.GetVFS().CreateDir(contentInfo)) { @@ -399,14 +399,11 @@ s32 cellGameCreateGameData(vm::ptr init, vm::ptr path, vm::ptr sb) sys_fs.Warning("sys_fs_stat(path=*0x%x, sb=*0x%x)", path, sb); sys_fs.Warning("*** path = '%s'", path.get_ptr()); - const std::string _path = path.get_ptr(); + std::string local_path; - u32 mode = 0; - s32 uid = 0; - s32 gid = 0; - u64 atime = 0; - u64 mtime = 0; - u64 ctime = 0; - u64 size = 0; + Emu.GetVFS().GetDevice(path.get_ptr(), local_path); - std::string real_path; + FileInfo info; - Emu.GetVFS().GetDevice(_path, real_path); - - int stat_result; -#ifdef _WIN32 - struct _stat64 buf; - stat_result = _stat64(real_path.c_str(), &buf); -#else - struct stat buf; - stat_result = stat(real_path.c_str(), &buf); -#endif - if (stat_result) + if (!get_file_info(local_path, info) || !info.exists) { - sys_fs.Error("sys_fs_stat(): stat('%s') failed -> 0x%x", real_path.c_str(), stat_result); + sys_fs.Error("sys_fs_stat(): '%s' not found or get_file_info() failed", path.get_ptr()); + return CELL_FS_ENOENT; + } + + s32 mode = CELL_FS_S_IRUSR | CELL_FS_S_IRGRP | CELL_FS_S_IROTH; + + if (info.isWritable) + { + mode |= CELL_FS_S_IWUSR | CELL_FS_S_IWGRP | CELL_FS_S_IWOTH; + } + + if (info.isDirectory) + { + mode |= CELL_FS_S_IFDIR; + mode |= CELL_FS_S_IXUSR | CELL_FS_S_IXGRP | CELL_FS_S_IXOTH; // ??? } else { - mode = buf.st_mode; - uid = buf.st_uid; - gid = buf.st_gid; - atime = buf.st_atime; - mtime = buf.st_mtime; - ctime = buf.st_ctime; - size = buf.st_size; + mode |= CELL_FS_S_IFREG; } - sb->mode = - CELL_FS_S_IRUSR | CELL_FS_S_IWUSR | CELL_FS_S_IXUSR | - CELL_FS_S_IRGRP | CELL_FS_S_IWGRP | CELL_FS_S_IXGRP | - CELL_FS_S_IROTH | CELL_FS_S_IWOTH | CELL_FS_S_IXOTH; + sb->uid = 1; // ??? + sb->gid = 1; // ??? + sb->atime = info.atime; + sb->mtime = info.mtime; + sb->ctime = info.ctime; + sb->size = info.size; + sb->blksize = 4096; // ??? - if (sb->mode == mode) - sys_fs.Error("sys_fs_stat(): mode is the same (0x%x)", mode); - - sb->uid = uid; - sb->gid = gid; - sb->atime = atime; - sb->mtime = mtime; - sb->ctime = ctime; - sb->blksize = 4096; - - { - vfsDir dir(_path); - if (dir.IsOpened()) - { - sb->mode |= CELL_FS_S_IFDIR; - return CELL_OK; - } - } - - { - vfsFile f(_path); - if (f.IsOpened()) - { - sb->mode |= CELL_FS_S_IFREG; - sb->size = f.GetSize(); - return CELL_OK; - } - } - - if (sb->size == size && size != 0) - sys_fs.Error("sys_fs_stat(): size is the same (0x%x)", size); - - sys_fs.Warning("sys_fs_stat(): '%s' not found", path.get_ptr()); - return CELL_FS_ENOENT; + return CELL_OK; } s32 sys_fs_fstat(u32 fd, vm::ptr sb) { - sys_fs.Warning("sys_fs_fstat(fd=0x%x, sb=*0x%x)", fd, sb); + sys_fs.Error("sys_fs_fstat(fd=0x%x, sb=*0x%x)", fd, sb); const auto file = Emu.GetIdManager().GetIDData(fd); @@ -319,12 +281,12 @@ s32 sys_fs_fstat(u32 fd, vm::ptr sb) CELL_FS_S_IRGRP | CELL_FS_S_IWGRP | CELL_FS_S_IXGRP | CELL_FS_S_IROTH | CELL_FS_S_IWOTH | CELL_FS_S_IXOTH; - sb->mode |= CELL_FS_S_IFREG; //TODO: dir CELL_FS_S_IFDIR - sb->uid = 0; - sb->gid = 0; - sb->atime = 0; //TODO - sb->mtime = 0; //TODO - sb->ctime = 0; //TODO + sb->mode |= CELL_FS_S_IFREG; + sb->uid = 1; // ??? + sb->gid = 1; // ??? + sb->atime = 0; // TODO + sb->mtime = 0; // TODO + sb->ctime = 0; // TODO sb->size = file->file->GetSize(); sb->blksize = 4096; @@ -520,7 +482,7 @@ s32 sys_fs_ftruncate(u32 fd, u64 size) std::lock_guard lock(file->mutex); - // it's near + // must use rfile_t::trunc() return CELL_OK; } diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index 5462af30d8..5e349058db 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -407,9 +407,7 @@ void Emulator::SavePoints(const std::string& path) void Emulator::LoadPoints(const std::string& path) { - struct stat buf; - if (!stat(path.c_str(), &buf)) - return; + if (!rExists(path)) return; std::ifstream f(path, std::ios::binary); if (!f.is_open()) return;