VFS::CreatePath fixed, bugfixes

This commit is contained in:
Nekotekina 2015-04-20 18:53:31 +03:00
parent 8c1aa3ee15
commit 56c64c8045
16 changed files with 147 additions and 77 deletions

View File

@ -44,7 +44,7 @@ AutoPause::~AutoPause(void)
//This would be able to create in a GUI window.
void AutoPause::Reload(void)
{
if (rExists("pause.bin"))
if (rIsFile("pause.bin"))
{
m_pause_function.clear();
m_pause_function.reserve(16);

View File

@ -126,6 +126,37 @@ bool get_file_info(const std::string& path, FileInfo& info)
return true;
}
bool rExists(const std::string& path)
{
#ifdef _WIN32
return GetFileAttributesW(ConvertUTF8ToWChar(path).get()) != 0xFFFFFFFF;
#else
struct stat buffer;
return stat(path.c_str(), &buffer) == 0;
#endif
}
bool rIsFile(const std::string& file)
{
#ifdef _WIN32
DWORD attrs;
if ((attrs = GetFileAttributesW(ConvertUTF8ToWChar(file).get())) == INVALID_FILE_ATTRIBUTES)
{
return false;
}
return (attrs & FILE_ATTRIBUTE_DIRECTORY) == 0;
#else
struct stat64 file_info;
if (stat64(file.c_str(), &file_info) < 0)
{
return false;
}
return !S_ISDIR(file_info.st_mode);
#endif
}
bool rIsDir(const std::string& dir)
{
#ifdef _WIN32
@ -147,7 +178,7 @@ bool rIsDir(const std::string& dir)
#endif
}
bool rMkdir(const std::string& dir)
bool rMkDir(const std::string& dir)
{
#ifdef _WIN32
if (!CreateDirectoryW(ConvertUTF8ToWChar(dir).get(), NULL))
@ -162,34 +193,49 @@ bool rMkdir(const std::string& dir)
return true;
}
bool rMkpath(const std::string& path)
bool rMkPath(const std::string& path)
{
size_t start=0, pos;
std::string dir;
bool ret;
size_t start = 0;
while (true) {
if ((pos = path.find_first_of("/\\", start)) == std::string::npos)
while (true)
{
// maybe it could be more optimal if goes from the end recursively
size_t pos = path.find_first_of("/\\", start);
if (pos == std::string::npos)
{
pos = path.length();
dir = path.substr(0,pos++);
start = pos;
if(dir.size() == 0)
continue;
#ifdef _WIN32
if((ret = _mkdir(dir.c_str()) != 0) && errno != EEXIST){
#else
if((ret = mkdir(dir.c_str(), 0777) != 0) && errno != EEXIST){
#endif
return !ret;
}
std::string dir = path.substr(0, pos);
start = ++pos;
if (dir.size() == 0)
{
continue;
}
if (!rIsDir(dir))
{
// if doesn't exist or not a dir
if (!rMkDir(dir))
{
// if creating failed
return false;
}
}
if (pos >= path.length())
return true;
{
break;
}
}
return true;
}
bool rRmdir(const std::string& dir)
bool rRmDir(const std::string& dir)
{
#ifdef _WIN32
if (!RemoveDirectoryW(ConvertUTF8ToWChar(dir).get()))
@ -271,16 +317,6 @@ bool rCopy(const std::string& from, const std::string& to, bool overwrite)
return true;
}
bool rExists(const std::string& file)
{
#ifdef _WIN32
return GetFileAttributesW(ConvertUTF8ToWChar(file).get()) != 0xFFFFFFFF;
#else
struct stat buffer;
return stat(file.c_str(), &buffer) == 0;
#endif
}
bool rRemoveFile(const std::string& file)
{
#ifdef _WIN32
@ -386,6 +422,7 @@ 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_create | o_excl | o_trunc: disp = CREATE_NEW; break;
}
if (!disp || (mode & ~(o_read | o_write | o_create | o_trunc | o_excl)))
@ -414,7 +451,7 @@ bool rfile_t::open(const std::string& filename, u32 mode)
if (mode & o_trunc) flags |= O_TRUNC;
if (mode & o_excl) flags |= O_EXCL;
if (((mode & o_excl) && (!(mode & o_create) || (mode & o_trunc))) || (mode & ~(o_read | o_write | o_create | o_trunc | o_excl)))
if (((mode & o_excl) && !(mode & o_create)) || (mode & ~(o_read | o_write | o_create | o_trunc | o_excl)))
{
LOG_ERROR(GENERAL, "rfile_t::open('%s') failed: unknown mode specified (0x%x)", filename, mode);
return false;

View File

@ -12,13 +12,14 @@ struct FileInfo
};
bool get_file_info(const std::string& path, FileInfo& fileInfo);
bool rExists(const std::string& path);
bool rIsFile(const std::string& file);
bool rIsDir(const std::string& dir);
bool rRmdir(const std::string& dir);
bool rMkdir(const std::string& dir);
bool rMkpath(const std::string& path);
bool rRmDir(const std::string& dir);
bool rMkDir(const std::string& dir);
bool rMkPath(const std::string& path);
bool rRename(const std::string& from, const std::string& to);
bool rCopy(const std::string& from, const std::string& to, bool overwrite);
bool rExists(const std::string& file);
bool rRemoveFile(const std::string& file);
bool rTruncate(const std::string& file, uint64_t length);

View File

@ -186,7 +186,7 @@ bool UnpackEntry(const rfile_t& dec_pkg_f, const PKGEntry& entry, std::string di
{
auto path = dir + std::string(buf, entry.name_size);
if (rExists(path))
if (rIsFile(path))
{
LOG_WARNING(LOADER, "PKG Loader: '%s' is overwritten", path);
}
@ -218,7 +218,7 @@ bool UnpackEntry(const rfile_t& dec_pkg_f, const PKGEntry& entry, std::string di
case PKG_FILE_ENTRY_FOLDER:
{
auto path = dir + std::string(buf, entry.name_size);
if (!rExists(path) && !rMkdir(path))
if (!rIsDir(path) && !rMkPath(path))
{
LOG_ERROR(LOADER, "PKG Loader: Could not create directory: %s", path.c_str());
return false;

View File

@ -1192,7 +1192,7 @@ bool SELFDecrypter::GetKeyFromRap(u8 *content_id, u8 *npdrm_key)
std::string rap_path("dev_hdd0/home/" + pf_str + "/exdata/" + ci_str + ".rap");
// Check if we have a valid RAP file.
if (!rExists(rap_path))
if (!rIsFile(rap_path))
{
LOG_ERROR(LOADER, "This application requires a valid RAP file for decryption!");
return false;

View File

@ -181,6 +181,18 @@ bool VFS::CreateDir(const std::string& ps3_path) const
return false;
}
bool VFS::CreatePath(const std::string& ps3_path) const
{
std::string path;
if (vfsDevice* dev = GetDevice(ps3_path, path))
{
return rMkPath(path);
}
return false;
}
bool VFS::RemoveFile(const std::string& ps3_path) const
{
std::string path;

View File

@ -81,6 +81,7 @@ struct VFS
vfsFileBase* OpenFile(const std::string& ps3_path, u32 mode) const;
vfsDirBase* OpenDir(const std::string& ps3_path) const;
bool CreateDir(const std::string& ps3_path) const;
bool CreatePath(const std::string& ps3_path) const;
bool RemoveFile(const std::string& ps3_path) const;
bool RemoveDir(const std::string& ps3_path) const;
bool ExistsFile(const std::string& ps3_path) const;

View File

@ -42,7 +42,7 @@ bool vfsLocalDir::Open(const std::string& path)
bool vfsLocalDir::Create(const std::string& path)
{
return rMkdir(path);
return rMkDir(path);
}
bool vfsLocalDir::IsExists(const std::string& path) const
@ -57,7 +57,7 @@ bool vfsLocalDir::Rename(const std::string& from, const std::string& to)
bool vfsLocalDir::Remove(const std::string& path)
{
return rRmdir(path);
return rRmDir(path);
}
bool vfsLocalDir::IsOpened() const

View File

@ -50,7 +50,7 @@ bool vfsLocalFile::IsOpened() const
bool vfsLocalFile::Exists(const std::string& path)
{
return rExists(path);
return rIsFile(path);
}
bool vfsLocalFile::Rename(const std::string& from, const std::string& to)

View File

@ -610,10 +610,10 @@ void GLTexture::Save(RSXTexture& tex)
static const std::string& dir_path = "textures";
static const std::string& file_fmt = dir_path + "/" + "tex[%d].png";
if (!rExists(dir_path)) rMkdir(dir_path);
if (!rIsDir(dir_path)) rMkDir(dir_path);
u32 count = 0;
while (rExists(fmt::Format(file_fmt.c_str(), count))) count++;
while (rIsFile(fmt::Format(file_fmt.c_str(), count))) count++;
Save(tex, fmt::Format(file_fmt.c_str(), count));
}

View File

@ -13,8 +13,8 @@
extern Module cellGame;
std::string contentInfo = "";
std::string usrdir = "";
std::string contentInfo;
std::string usrdir;
bool path_set = false;
s32 cellHddGameCheck(PPUThread& CPU, u32 version, vm::ptr<const char> dirName, u32 errDialog, vm::ptr<CellHddGameStatCallback> funcStat, u32 container)
@ -250,7 +250,7 @@ s32 cellGameContentPermit(vm::ptr<char[CELL_GAME_PATH_MAX]> contentInfoPath, vm:
{
cellGame.Warning("cellGameContentPermit(contentInfoPath=*0x%x, usrdirPath=*0x%x)", contentInfoPath, usrdirPath);
if (!contentInfoPath || !usrdirPath)
if (!contentInfoPath && !usrdirPath)
{
return CELL_GAME_ERROR_PARAM;
}
@ -262,6 +262,17 @@ s32 cellGameContentPermit(vm::ptr<char[CELL_GAME_PATH_MAX]> contentInfoPath, vm:
return CELL_GAME_ERROR_FAILURE;
}
if (contentInfo.size() == 9 && usrdir.empty())
{
if (Emu.GetVFS().RenameDir("/dev_hdd0/game/TMP_" + contentInfo, "/dev_hdd0/game/" + contentInfo))
{
cellGame.Success("cellGameContentPermit(): gamedata directory created ('/dev_hdd0/game/%s')", contentInfo);
}
contentInfo = "/dev_hdd0/game/" + contentInfo;
usrdir = contentInfo + "/USRDIR";
}
strcpy_trunc(*contentInfoPath, contentInfo);
strcpy_trunc(*usrdirPath, usrdir);
@ -381,28 +392,31 @@ 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 title = init->title;
contentInfo = "/dev_hdd0/game/" + title;
usrdir = "/dev_hdd0/game/" + title + "/USRDIR";
std::string dir = init->titleId;
std::string tmp_contentInfo = "/dev_hdd0/game/TMP_" + dir;
std::string tmp_usrdir = "/dev_hdd0/game/TMP_" + dir + "/USRDIR";
if (!Emu.GetVFS().CreateDir(contentInfo))
if (!Emu.GetVFS().CreateDir(tmp_contentInfo))
{
cellGame.Error("cellGameCreateGameData(): failed to create content directory ('%s')", contentInfo);
cellGame.Error("cellGameCreateGameData(): failed to create content directory ('%s')", tmp_contentInfo);
return CELL_GAME_ERROR_ACCESS_ERROR; // ???
}
if (!Emu.GetVFS().CreateDir(usrdir))
if (!Emu.GetVFS().CreateDir(tmp_usrdir))
{
cellGame.Error("cellGameCreateGameData(): failed to create USRDIR directory ('%s')", usrdir);
cellGame.Error("cellGameCreateGameData(): failed to create USRDIR directory ('%s')", tmp_usrdir);
return CELL_GAME_ERROR_ACCESS_ERROR; // ???
}
// cellGameContentPermit should then move files in non-temporary location and return their non-temporary displacement
strcpy_trunc(*tmp_contentInfoPath, contentInfo);
strcpy_trunc(*tmp_usrdirPath, usrdir);
strcpy_trunc(*tmp_contentInfoPath, tmp_contentInfo);
strcpy_trunc(*tmp_usrdirPath, tmp_usrdir);
contentInfo = dir;
usrdir.clear();
path_set = true;
cellGame.Success("cellGameCreateGameData(): gamedata directory created ('%s')", contentInfo);
cellGame.Success("cellGameCreateGameData(): temporary gamedata directory created ('%s')", tmp_contentInfo);
// TODO: set initial PARAM.SFO parameters

View File

@ -62,7 +62,7 @@ s32 sys_fs_open(vm::ptr<const char> path, s32 flags, vm::ptr<u32> fd, s32 mode,
if (flags & CELL_FS_O_EXCL)
{
if ((flags & CELL_FS_O_CREAT) && !(flags & CELL_FS_O_TRUNC))
if (flags & CELL_FS_O_CREAT)
{
open_mode |= o_excl;
}
@ -93,6 +93,12 @@ s32 sys_fs_open(vm::ptr<const char> path, s32 flags, vm::ptr<u32> fd, s32 mode,
if (!file || !file->IsOpened())
{
sys_fs.Error("sys_fs_open(): failed to open '%s' (flags=%#o, mode=%#o)", path.get_ptr(), flags, mode);
if (open_mode & o_excl)
{
return CELL_FS_EEXIST; // approximation
}
return CELL_FS_ENOENT;
}
@ -334,7 +340,7 @@ s32 sys_fs_mkdir(vm::ptr<const char> path, s32 mode)
return CELL_FS_EEXIST;
}
if (!Emu.GetVFS().CreateDir(_path))
if (!Emu.GetVFS().CreatePath(_path))
{
return CELL_FS_EIO; // ???
}
@ -384,14 +390,14 @@ s32 sys_fs_rmdir(vm::ptr<const char> path)
std::string _path = path.get_ptr();
if (!Emu.GetVFS().ExistsDir(_path))
{
return CELL_FS_ENOENT;
}
if (!Emu.GetVFS().RemoveDir(_path))
{
if (Emu.GetVFS().ExistsDir(_path))
{
return CELL_FS_EIO; // ???
}
return CELL_FS_ENOENT;
return CELL_FS_EIO; // ???
}
sys_fs.Notice("sys_fs_rmdir(): directory '%s' removed", path.get_ptr());
@ -405,14 +411,14 @@ s32 sys_fs_unlink(vm::ptr<const char> path)
std::string _path = path.get_ptr();
if (!Emu.GetVFS().ExistsFile(_path))
{
return CELL_FS_ENOENT;
}
if (!Emu.GetVFS().RemoveFile(_path))
{
if (Emu.GetVFS().ExistsFile(_path))
{
return CELL_FS_EIO; // ???
}
return CELL_FS_ENOENT;
return CELL_FS_EIO; // ???
}
sys_fs.Notice("sys_fs_unlink(): file '%s' deleted", path.get_ptr());

View File

@ -182,7 +182,7 @@ void Emulator::Load()
{
GetModuleManager().Init();
if (!rExists(m_path)) return;
if (!rIsFile(m_path)) return;
if (IsSelf(m_path))
{
@ -407,7 +407,7 @@ void Emulator::SavePoints(const std::string& path)
void Emulator::LoadPoints(const std::string& path)
{
if (!rExists(path)) return;
if (!rIsFile(path)) return;
std::ifstream f(path, std::ios::binary);
if (!f.is_open())
return;

View File

@ -71,7 +71,7 @@ void AutoPauseManagerDialog::LoadEntries(void)
m_entries.clear();
m_entries.reserve(16);
if (rExists("pause.bin"))
if (rIsFile("pause.bin"))
{
rfile_t list("pause.bin");
//System calls ID and Function calls ID are all u32 iirc.

View File

@ -27,7 +27,7 @@ bool PKGLoader::Install(const rfile_t& pkg_f, std::string dest)
std::string titleID = std::string(title_id).substr(7, 9);
if (rExists(dest + titleID))
if (rIsDir(dest + titleID))
{
if (rMessageDialog(NULL, "Another installation found. Do you want to overwrite it?", "PKG Decrypter / Installer", rYES_NO | rCENTRE).ShowModal() != rID_YES)
{
@ -35,7 +35,7 @@ bool PKGLoader::Install(const rfile_t& pkg_f, std::string dest)
return false;
}
}
else if (!rMkdir(dest + titleID))
else if (!rMkDir(dest + titleID))
{
LOG_ERROR(LOADER, "PKG Loader: Could not create the installation directory: %s", titleID.c_str());
return false;

View File

@ -22,7 +22,6 @@ bool TROPUSRLoader::Load(const std::string& filepath, const std::string& configp
if (m_file)
Close();
// TODO: This seems to be always true... A bug in ExistsFile() ?
if (!Emu.GetVFS().ExistsFile(filepath))
Generate(filepath, configpath);