VFS::TruncateFile() implemented

This commit is contained in:
Nekotekina 2015-04-18 16:38:42 +03:00
parent b1f7543436
commit f2276bb70c
7 changed files with 117 additions and 54 deletions

View file

@ -315,6 +315,18 @@ bool VFS::CopyFile(const std::string& ps3_path_from, const std::string& ps3_path
return false;
}
bool VFS::TruncateFile(const std::string& ps3_path, u64 length) const
{
std::string path;
if (vfsDevice* dev = GetDevice(ps3_path, path))
{
return rTruncate(path, length);
}
return false;
}
vfsDevice* VFS::GetDevice(const std::string& ps3_path, std::string& path) const
{
auto try_get_device = [this, &path](const std::string& ps3_path) -> vfsDevice*

View file

@ -90,6 +90,7 @@ struct VFS
bool RenameFile(const std::string& ps3_path_from, const std::string& ps3_path_to) const;
bool RenameDir(const std::string& ps3_path_from, const std::string& ps3_path_to) const;
bool CopyFile(const std::string& ps3_path_from, const std::string& ps3_path_to, bool overwrite = true) const;
bool TruncateFile(const std::string& ps3_path, u64 length) const;
vfsDevice* GetDevice(const std::string& ps3_path, std::string& path) const;
vfsDevice* GetDeviceLocal(const std::string& local_path, std::string& path) const;

View file

@ -346,18 +346,22 @@ __noinline s32 savedata_op(
save_entry.dirName = dirName.get_ptr();
}
// get save stats
std::string dir_path = base_dir + save_entry.dirName + "/";
std::string sfo_path = dir_path + "PARAM.SFO";
PSFLoader psf;
// Load PARAM.SFO
{
vfsFile f(sfo_path);
psf.Load(f);
}
// Get save stats
{
vm::stackvar<CellSaveDataStatGet> statGet(CPU);
vm::stackvar<CellSaveDataStatSet> statSet(CPU);
vfsFile f(sfo_path);
PSFLoader psf(f);
f.Close();
std::string dir_local_path;
Emu.GetVFS().GetDevice(dir_path, dir_local_path);
@ -416,9 +420,13 @@ __noinline s32 savedata_op(
{
file.fileType = CELL_SAVEDATA_FILETYPE_CONTENT_SND0;
}
else if (psf.GetInteger("*" + entry->name)) // let's put the list of protected files in PARAM.SFO (int param = 1 if protected)
{
file.fileType = CELL_SAVEDATA_FILETYPE_SECUREFILE;
}
else
{
file.fileType = CELL_SAVEDATA_FILETYPE_NORMALFILE; // protected files are not supported
file.fileType = CELL_SAVEDATA_FILETYPE_NORMALFILE;
}
file.size = entry->size;
@ -481,22 +489,12 @@ __noinline s32 savedata_op(
return CELL_SAVEDATA_ERROR_PARAM;
}
}
}
// Create save directory if necessary
if (save_entry.isNew && !Emu.GetVFS().CreateDir(dir_path))
{
// error
}
// Write PARAM.SFO
if (psf)
{
Emu.GetVFS().CreateFile(sfo_path, true);
f.Open(sfo_path, vfsWrite);
psf.Save(f);
f.Close();
}
// Create save directory if necessary
if (save_entry.isNew && !Emu.GetVFS().CreateDir(dir_path))
{
// Let's ignore this error for now
}
// Enter the loop where the save files are read/created/deleted
@ -520,38 +518,38 @@ __noinline s32 savedata_op(
break;
}
std::string filepath = dir_path;
std::string filepath;
switch (const u32 type = fileSet->fileType)
{
case CELL_SAVEDATA_FILETYPE_SECUREFILE:
case CELL_SAVEDATA_FILETYPE_NORMALFILE:
{
filepath += fileSet->fileName.get_ptr();
filepath = fileSet->fileName.get_ptr();
break;
}
case CELL_SAVEDATA_FILETYPE_CONTENT_ICON0:
{
filepath += "ICON0.PNG";
filepath = "ICON0.PNG";
break;
}
case CELL_SAVEDATA_FILETYPE_CONTENT_ICON1:
{
filepath += "ICON1.PAM";
filepath = "ICON1.PAM";
break;
}
case CELL_SAVEDATA_FILETYPE_CONTENT_PIC1:
{
filepath += "PIC1.PNG";
filepath = "PIC1.PNG";
break;
}
case CELL_SAVEDATA_FILETYPE_CONTENT_SND0:
{
filepath += "SND0.AT3";
filepath = "SND0.AT3";
break;
}
@ -562,6 +560,10 @@ __noinline s32 savedata_op(
}
}
psf.SetInteger("*" + filepath, fileSet->fileType.data() == se32(CELL_SAVEDATA_FILETYPE_SECUREFILE));
filepath = dir_path + filepath;
std::unique_ptr<vfsStream> file;
switch (const u32 op = fileSet->fileOperation)
@ -608,6 +610,15 @@ __noinline s32 savedata_op(
}
}
// Write PARAM.SFO
if (psf)
{
Emu.GetVFS().CreateFile(sfo_path, true);
vfsFile f(sfo_path, vfsWrite);
psf.Save(f);
}
return CELL_OK;
}

View file

@ -527,28 +527,16 @@ s32 sys_fs_truncate(vm::ptr<const char> path, u64 size)
sys_fs.Warning("sys_fs_truncate(path=*0x%x, size=0x%llx)", path, size);
sys_fs.Warning("*** path = '%s'", path.get_ptr());
vfsFile f(path.get_ptr(), vfsReadWrite);
if (!f.IsOpened())
const std::string filename = path.get_ptr();
if (!Emu.GetVFS().ExistsFile(filename))
{
sys_fs.Warning("sys_fs_truncate(): '%s' not found", path.get_ptr());
return CELL_FS_ENOENT;
}
u64 initialSize = f.GetSize();
if (initialSize < size)
if (!Emu.GetVFS().TruncateFile(filename, size))
{
u64 last_pos = f.Tell();
f.Seek(0, vfsSeekEnd);
static const char nullbyte = 0;
f.Seek(size - initialSize - 1, vfsSeekCur);
f.Write(&nullbyte, sizeof(char));
f.Seek(last_pos, vfsSeekSet);
}
if (initialSize > size)
{
// (TODO)
return CELL_FS_EIO; // ???
}
return CELL_OK;

View file

@ -41,6 +41,8 @@ class PSFLoader
std::vector<PSFEntry> m_entries;
public:
PSFLoader() = default;
PSFLoader(vfsStream& stream)
{
Load(stream);