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. //This would be able to create in a GUI window.
void AutoPause::Reload(void) void AutoPause::Reload(void)
{ {
if (rExists("pause.bin")) if (rIsFile("pause.bin"))
{ {
m_pause_function.clear(); m_pause_function.clear();
m_pause_function.reserve(16); m_pause_function.reserve(16);

View File

@ -126,6 +126,37 @@ bool get_file_info(const std::string& path, FileInfo& info)
return true; 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) bool rIsDir(const std::string& dir)
{ {
#ifdef _WIN32 #ifdef _WIN32
@ -147,7 +178,7 @@ bool rIsDir(const std::string& dir)
#endif #endif
} }
bool rMkdir(const std::string& dir) bool rMkDir(const std::string& dir)
{ {
#ifdef _WIN32 #ifdef _WIN32
if (!CreateDirectoryW(ConvertUTF8ToWChar(dir).get(), NULL)) if (!CreateDirectoryW(ConvertUTF8ToWChar(dir).get(), NULL))
@ -162,34 +193,49 @@ bool rMkdir(const std::string& dir)
return true; return true;
} }
bool rMkpath(const std::string& path) bool rMkPath(const std::string& path)
{ {
size_t start=0, pos; size_t start = 0;
std::string dir;
bool ret;
while (true) { while (true)
if ((pos = path.find_first_of("/\\", start)) == std::string::npos) {
// 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(); 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()) if (pos >= path.length())
return true; {
break;
}
} }
return true; return true;
} }
bool rRmdir(const std::string& dir) bool rRmDir(const std::string& dir)
{ {
#ifdef _WIN32 #ifdef _WIN32
if (!RemoveDirectoryW(ConvertUTF8ToWChar(dir).get())) if (!RemoveDirectoryW(ConvertUTF8ToWChar(dir).get()))
@ -271,16 +317,6 @@ bool rCopy(const std::string& from, const std::string& to, bool overwrite)
return true; 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) bool rRemoveFile(const std::string& file)
{ {
#ifdef _WIN32 #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_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_create | o_excl | o_trunc: disp = CREATE_NEW; break;
} }
if (!disp || (mode & ~(o_read | o_write | o_create | o_trunc | o_excl))) 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_trunc) flags |= O_TRUNC;
if (mode & o_excl) flags |= O_EXCL; 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); LOG_ERROR(GENERAL, "rfile_t::open('%s') failed: unknown mode specified (0x%x)", filename, mode);
return false; return false;

View File

@ -12,13 +12,14 @@ struct FileInfo
}; };
bool get_file_info(const std::string& path, FileInfo& 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 rIsDir(const std::string& dir);
bool rRmdir(const std::string& dir); bool rRmDir(const std::string& dir);
bool rMkdir(const std::string& dir); bool rMkDir(const std::string& dir);
bool rMkpath(const std::string& path); bool rMkPath(const std::string& path);
bool rRename(const std::string& from, const std::string& to); bool rRename(const std::string& from, const std::string& to);
bool rCopy(const std::string& from, const std::string& to, bool overwrite); 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 rRemoveFile(const std::string& file);
bool rTruncate(const std::string& file, uint64_t length); 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); auto path = dir + std::string(buf, entry.name_size);
if (rExists(path)) if (rIsFile(path))
{ {
LOG_WARNING(LOADER, "PKG Loader: '%s' is overwritten", 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: case PKG_FILE_ENTRY_FOLDER:
{ {
auto path = dir + std::string(buf, entry.name_size); 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()); LOG_ERROR(LOADER, "PKG Loader: Could not create directory: %s", path.c_str());
return false; 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"); std::string rap_path("dev_hdd0/home/" + pf_str + "/exdata/" + ci_str + ".rap");
// Check if we have a valid RAP file. // 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!"); LOG_ERROR(LOADER, "This application requires a valid RAP file for decryption!");
return false; return false;

View File

@ -181,6 +181,18 @@ bool VFS::CreateDir(const std::string& ps3_path) const
return false; 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 bool VFS::RemoveFile(const std::string& ps3_path) const
{ {
std::string path; std::string path;

View File

@ -81,6 +81,7 @@ struct VFS
vfsFileBase* OpenFile(const std::string& ps3_path, u32 mode) const; vfsFileBase* OpenFile(const std::string& ps3_path, u32 mode) const;
vfsDirBase* OpenDir(const std::string& ps3_path) const; vfsDirBase* OpenDir(const std::string& ps3_path) const;
bool CreateDir(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 RemoveFile(const std::string& ps3_path) const;
bool RemoveDir(const std::string& ps3_path) const; bool RemoveDir(const std::string& ps3_path) const;
bool ExistsFile(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) bool vfsLocalDir::Create(const std::string& path)
{ {
return rMkdir(path); return rMkDir(path);
} }
bool vfsLocalDir::IsExists(const std::string& path) const 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) bool vfsLocalDir::Remove(const std::string& path)
{ {
return rRmdir(path); return rRmDir(path);
} }
bool vfsLocalDir::IsOpened() const bool vfsLocalDir::IsOpened() const

View File

@ -50,7 +50,7 @@ bool vfsLocalFile::IsOpened() const
bool vfsLocalFile::Exists(const std::string& path) bool vfsLocalFile::Exists(const std::string& path)
{ {
return rExists(path); return rIsFile(path);
} }
bool vfsLocalFile::Rename(const std::string& from, const std::string& to) 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& dir_path = "textures";
static const std::string& file_fmt = dir_path + "/" + "tex[%d].png"; 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; 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)); Save(tex, fmt::Format(file_fmt.c_str(), count));
} }

View File

@ -13,8 +13,8 @@
extern Module cellGame; extern Module cellGame;
std::string contentInfo = ""; std::string contentInfo;
std::string usrdir = ""; std::string usrdir;
bool path_set = false; bool path_set = false;
s32 cellHddGameCheck(PPUThread& CPU, u32 version, vm::ptr<const char> dirName, u32 errDialog, vm::ptr<CellHddGameStatCallback> funcStat, u32 container) 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); cellGame.Warning("cellGameContentPermit(contentInfoPath=*0x%x, usrdirPath=*0x%x)", contentInfoPath, usrdirPath);
if (!contentInfoPath || !usrdirPath) if (!contentInfoPath && !usrdirPath)
{ {
return CELL_GAME_ERROR_PARAM; 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; 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(*contentInfoPath, contentInfo);
strcpy_trunc(*usrdirPath, usrdir); 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); cellGame.Error("cellGameCreateGameData(init=*0x%x, tmp_contentInfoPath=*0x%x, tmp_usrdirPath=*0x%x)", init, tmp_contentInfoPath, tmp_usrdirPath);
std::string title = init->title; std::string dir = init->titleId;
contentInfo = "/dev_hdd0/game/" + title; std::string tmp_contentInfo = "/dev_hdd0/game/TMP_" + dir;
usrdir = "/dev_hdd0/game/" + title + "/USRDIR"; 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; // ??? 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; // ??? return CELL_GAME_ERROR_ACCESS_ERROR; // ???
} }
// 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, tmp_contentInfo);
strcpy_trunc(*tmp_usrdirPath, usrdir); strcpy_trunc(*tmp_usrdirPath, tmp_usrdir);
contentInfo = dir;
usrdir.clear();
path_set = true; 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 // 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_EXCL)
{ {
if ((flags & CELL_FS_O_CREAT) && !(flags & CELL_FS_O_TRUNC)) if (flags & CELL_FS_O_CREAT)
{ {
open_mode |= o_excl; 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()) if (!file || !file->IsOpened())
{ {
sys_fs.Error("sys_fs_open(): failed to open '%s' (flags=%#o, mode=%#o)", path.get_ptr(), flags, mode); 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; return CELL_FS_ENOENT;
} }
@ -334,7 +340,7 @@ s32 sys_fs_mkdir(vm::ptr<const char> path, s32 mode)
return CELL_FS_EEXIST; return CELL_FS_EEXIST;
} }
if (!Emu.GetVFS().CreateDir(_path)) if (!Emu.GetVFS().CreatePath(_path))
{ {
return CELL_FS_EIO; // ??? return CELL_FS_EIO; // ???
} }
@ -384,14 +390,14 @@ s32 sys_fs_rmdir(vm::ptr<const char> path)
std::string _path = path.get_ptr(); std::string _path = path.get_ptr();
if (!Emu.GetVFS().ExistsDir(_path))
{
return CELL_FS_ENOENT;
}
if (!Emu.GetVFS().RemoveDir(_path)) if (!Emu.GetVFS().RemoveDir(_path))
{ {
if (Emu.GetVFS().ExistsDir(_path)) return CELL_FS_EIO; // ???
{
return CELL_FS_EIO; // ???
}
return CELL_FS_ENOENT;
} }
sys_fs.Notice("sys_fs_rmdir(): directory '%s' removed", path.get_ptr()); 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(); std::string _path = path.get_ptr();
if (!Emu.GetVFS().ExistsFile(_path))
{
return CELL_FS_ENOENT;
}
if (!Emu.GetVFS().RemoveFile(_path)) if (!Emu.GetVFS().RemoveFile(_path))
{ {
if (Emu.GetVFS().ExistsFile(_path)) return CELL_FS_EIO; // ???
{
return CELL_FS_EIO; // ???
}
return CELL_FS_ENOENT;
} }
sys_fs.Notice("sys_fs_unlink(): file '%s' deleted", path.get_ptr()); sys_fs.Notice("sys_fs_unlink(): file '%s' deleted", path.get_ptr());

View File

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

View File

@ -71,7 +71,7 @@ void AutoPauseManagerDialog::LoadEntries(void)
m_entries.clear(); m_entries.clear();
m_entries.reserve(16); m_entries.reserve(16);
if (rExists("pause.bin")) if (rIsFile("pause.bin"))
{ {
rfile_t list("pause.bin"); rfile_t list("pause.bin");
//System calls ID and Function calls ID are all u32 iirc. //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); 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) 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; 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()); LOG_ERROR(LOADER, "PKG Loader: Could not create the installation directory: %s", titleID.c_str());
return false; return false;

View File

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