This commit is contained in:
Nekotekina 2015-04-19 19:02:35 +03:00
parent ab405901ee
commit 93ebce4162
5 changed files with 86 additions and 101 deletions

View file

@ -61,6 +61,8 @@ bool truncate_file(const std::string& file, uint64_t length)
} }
#else #else
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h> #include <unistd.h>
#if defined(__APPLE__) || defined(__FreeBSD__) #if defined(__APPLE__) || defined(__FreeBSD__)
@ -323,16 +325,11 @@ rfile_t::~rfile_t()
#else #else
if (fd != -1) if (fd != -1)
{ {
close(fd); ::close(fd);
} }
#endif #endif
} }
rfile_t::rfile_t(handle_type handle)
: fd(handle)
{
}
rfile_t::rfile_t(const std::string& filename, u32 mode) rfile_t::rfile_t(const std::string& filename, u32 mode)
#ifdef _WIN32 #ifdef _WIN32
: fd(INVALID_HANDLE_VALUE) : fd(INVALID_HANDLE_VALUE)
@ -352,14 +349,29 @@ rfile_t::operator bool() const
#endif #endif
} }
void rfile_t::import(handle_type handle)
{
this->~rfile_t();
fd = handle;
}
bool rfile_t::open(const std::string& filename, u32 mode) bool rfile_t::open(const std::string& filename, u32 mode)
{ {
this->~rfile_t(); this->~rfile_t();
#ifdef _WIN32 #ifdef _WIN32
DWORD access = 0; DWORD access = 0;
if (mode & o_read) access |= GENERIC_READ; switch (mode & (o_read | o_write))
if (mode & o_write) access |= GENERIC_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; DWORD disp = 0;
switch (mode & (o_create | o_trunc | o_excl)) 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_trunc: disp = TRUNCATE_EXISTING; break;
case o_create | o_trunc: disp = CREATE_ALWAYS; break; case o_create | o_trunc: disp = CREATE_ALWAYS; break;
case o_create | o_excl: disp = CREATE_NEW; 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); LOG_ERROR(GENERAL, "rfile_t::open(): unknown mode specified (0x%x)", mode);
return false; return false;
} }
}
fd = CreateFileW(ConvertUTF8ToWChar(filename).get(), access, FILE_SHARE_READ, NULL, disp, FILE_ATTRIBUTE_NORMAL, NULL); fd = CreateFileW(ConvertUTF8ToWChar(filename).get(), access, FILE_SHARE_READ, NULL, disp, FILE_ATTRIBUTE_NORMAL, NULL);
#else #else
int flags = 0; 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_create) flags |= O_CREAT;
if (mode & o_trunc) flags |= O_TRUNC; if (mode & o_trunc) flags |= O_TRUNC;
if (mode & o_excl) flags |= O_EXCL; 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 #endif
return is_opened(); return is_opened();
@ -427,7 +455,7 @@ bool rfile_t::close()
return true; return true;
} }
#else #else
if (!close(fd)) if (!::close(fd))
{ {
fd = -1; fd = -1;
return true; return true;

View file

@ -54,7 +54,6 @@ private:
public: public:
rfile_t(); rfile_t();
~rfile_t(); ~rfile_t();
explicit rfile_t(handle_type fd);
explicit rfile_t(const std::string& filename, u32 mode = o_read); explicit rfile_t(const std::string& filename, u32 mode = o_read);
rfile_t(const rfile_t&) = delete; rfile_t(const rfile_t&) = delete;
@ -65,6 +64,7 @@ public:
operator bool() const; operator bool() const;
void import(handle_type fd);
bool open(const std::string& filename, u32 mode = o_read); bool open(const std::string& filename, u32 mode = o_read);
bool is_opened() const; bool is_opened() const;
bool trunc(u64 size) const; bool trunc(u64 size) const;

View file

@ -381,9 +381,9 @@ s32 cellGameCreateGameData(vm::ptr<CellGameSetInitParams> init, vm::ptr<char[CEL
{ {
cellGame.Error("cellGameCreateGameData(init=*0x%x, tmp_contentInfoPath=*0x%x, tmp_usrdirPath=*0x%x)", init, tmp_contentInfoPath, tmp_usrdirPath); cellGame.Error("cellGameCreateGameData(init=*0x%x, tmp_contentInfoPath=*0x%x, tmp_usrdirPath=*0x%x)", init, tmp_contentInfoPath, tmp_usrdirPath);
std::string titleId = init->titleId; std::string title = init->title;
contentInfo = "/dev_hdd0/game/" + titleId; contentInfo = "/dev_hdd0/game/" + title;
usrdir = "/dev_hdd0/game/" + titleId + "/USRDIR"; usrdir = "/dev_hdd0/game/" + title + "/USRDIR";
if (!Emu.GetVFS().CreateDir(contentInfo)) if (!Emu.GetVFS().CreateDir(contentInfo))
{ {
@ -399,14 +399,11 @@ s32 cellGameCreateGameData(vm::ptr<CellGameSetInitParams> init, vm::ptr<char[CEL
// cellGameContentPermit should then move files in non-temporary location and return their non-temporary displacement // cellGameContentPermit should then move files in non-temporary location and return their non-temporary displacement
strcpy_trunc(*tmp_contentInfoPath, contentInfo); strcpy_trunc(*tmp_contentInfoPath, contentInfo);
strcpy_trunc(*tmp_usrdirPath, contentInfo); strcpy_trunc(*tmp_usrdirPath, usrdir);
path_set = true; path_set = true;
cellGame.Success("cellGameCreateGameData(): gamedata directory created ('%s')", contentInfo); cellGame.Success("cellGameCreateGameData(): gamedata directory created ('%s')", contentInfo);
Emu.GetVFS().CopyFile("/dev_bdvd/PS3_GAME/ICON0.PNG", contentInfo + "/ICON0.PNG");
Emu.GetVFS().CopyFile("/dev_bdvd/PS3_GAME/PIC1.PNG", contentInfo + "/PIC1.PNG");
// TODO: set initial PARAM.SFO parameters // TODO: set initial PARAM.SFO parameters
return CELL_OK; return CELL_OK;

View file

@ -225,87 +225,49 @@ s32 sys_fs_stat(vm::ptr<const char> path, vm::ptr<CellFsStat> sb)
sys_fs.Warning("sys_fs_stat(path=*0x%x, sb=*0x%x)", path, sb); sys_fs.Warning("sys_fs_stat(path=*0x%x, sb=*0x%x)", path, sb);
sys_fs.Warning("*** path = '%s'", path.get_ptr()); sys_fs.Warning("*** path = '%s'", path.get_ptr());
const std::string _path = path.get_ptr(); std::string local_path;
u32 mode = 0; Emu.GetVFS().GetDevice(path.get_ptr(), local_path);
s32 uid = 0;
s32 gid = 0;
u64 atime = 0;
u64 mtime = 0;
u64 ctime = 0;
u64 size = 0;
std::string real_path; FileInfo info;
Emu.GetVFS().GetDevice(_path, real_path); if (!get_file_info(local_path, info) || !info.exists)
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)
{ {
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 else
{ {
mode = buf.st_mode; mode |= CELL_FS_S_IFREG;
uid = buf.st_uid;
gid = buf.st_gid;
atime = buf.st_atime;
mtime = buf.st_mtime;
ctime = buf.st_ctime;
size = buf.st_size;
} }
sb->mode = sb->uid = 1; // ???
CELL_FS_S_IRUSR | CELL_FS_S_IWUSR | CELL_FS_S_IXUSR | sb->gid = 1; // ???
CELL_FS_S_IRGRP | CELL_FS_S_IWGRP | CELL_FS_S_IXGRP | sb->atime = info.atime;
CELL_FS_S_IROTH | CELL_FS_S_IWOTH | CELL_FS_S_IXOTH; 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; 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;
}
s32 sys_fs_fstat(u32 fd, vm::ptr<CellFsStat> sb) s32 sys_fs_fstat(u32 fd, vm::ptr<CellFsStat> 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<fs_file_t>(fd); const auto file = Emu.GetIdManager().GetIDData<fs_file_t>(fd);
@ -319,9 +281,9 @@ s32 sys_fs_fstat(u32 fd, vm::ptr<CellFsStat> sb)
CELL_FS_S_IRGRP | CELL_FS_S_IWGRP | CELL_FS_S_IXGRP | CELL_FS_S_IRGRP | CELL_FS_S_IWGRP | CELL_FS_S_IXGRP |
CELL_FS_S_IROTH | CELL_FS_S_IWOTH | CELL_FS_S_IXOTH; 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->mode |= CELL_FS_S_IFREG;
sb->uid = 0; sb->uid = 1; // ???
sb->gid = 0; sb->gid = 1; // ???
sb->atime = 0; // TODO sb->atime = 0; // TODO
sb->mtime = 0; // TODO sb->mtime = 0; // TODO
sb->ctime = 0; // TODO sb->ctime = 0; // TODO
@ -520,7 +482,7 @@ s32 sys_fs_ftruncate(u32 fd, u64 size)
std::lock_guard<std::mutex> lock(file->mutex); std::lock_guard<std::mutex> lock(file->mutex);
// it's near // must use rfile_t::trunc()
return CELL_OK; return CELL_OK;
} }

View file

@ -407,9 +407,7 @@ void Emulator::SavePoints(const std::string& path)
void Emulator::LoadPoints(const std::string& path) void Emulator::LoadPoints(const std::string& path)
{ {
struct stat buf; if (!rExists(path)) return;
if (!stat(path.c_str(), &buf))
return;
std::ifstream f(path, std::ios::binary); std::ifstream f(path, std::ios::binary);
if (!f.is_open()) if (!f.is_open())
return; return;