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
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#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;

View File

@ -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;

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);
std::string titleId = init->titleId;
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<CellGameSetInitParams> init, vm::ptr<char[CEL
// cellGameContentPermit should then move files in non-temporary location and return their non-temporary displacement
strcpy_trunc(*tmp_contentInfoPath, contentInfo);
strcpy_trunc(*tmp_usrdirPath, contentInfo);
strcpy_trunc(*tmp_usrdirPath, usrdir);
path_set = true;
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
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("*** 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<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);
@ -319,12 +281,12 @@ 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_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<std::mutex> lock(file->mutex);
// it's near
// must use rfile_t::trunc()
return CELL_OK;
}

View File

@ -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;