mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-13 02:08:49 +12:00
Win32 FS: Rewrite (fix) vfs::host::rename
This commit is contained in:
parent
22269ca0d7
commit
b8fa6fb4c4
16 changed files with 329 additions and 108 deletions
|
@ -230,33 +230,13 @@ error_code sys_fs_test(ppu_thread& ppu, u32 arg1, u32 arg2, vm::ptr<u32> arg3, u
|
|||
return CELL_OK;
|
||||
}
|
||||
|
||||
lv2_file::open_result_t lv2_file::open(std::string_view vpath, s32 flags, s32 mode, const void* arg, u64 size)
|
||||
lv2_file::open_raw_result_t lv2_file::open_raw(const std::string& local_path, s32 flags, s32 mode, lv2_file_type type, const lv2_fs_mount_point* mp)
|
||||
{
|
||||
if (vpath.empty())
|
||||
{
|
||||
return {CELL_ENOENT};
|
||||
}
|
||||
|
||||
std::string path;
|
||||
const std::string local_path = vfs::get(vpath, nullptr, &path);
|
||||
|
||||
const auto mp = lv2_fs_object::get_mp(path);
|
||||
|
||||
if (vpath.find_first_not_of('/') == umax)
|
||||
{
|
||||
return {CELL_EISDIR, path};
|
||||
}
|
||||
|
||||
if (local_path.empty())
|
||||
{
|
||||
return {CELL_ENOTMOUNTED, path};
|
||||
}
|
||||
|
||||
// TODO: other checks for path
|
||||
|
||||
if (fs::is_dir(local_path))
|
||||
{
|
||||
return {CELL_EISDIR, path};
|
||||
return {CELL_EISDIR};
|
||||
}
|
||||
|
||||
bs_t<fs::open_mode> open_mode{};
|
||||
|
@ -272,7 +252,7 @@ lv2_file::open_result_t lv2_file::open(std::string_view vpath, s32 flags, s32 mo
|
|||
{
|
||||
if (flags & CELL_FS_O_ACCMODE || flags & (CELL_FS_O_CREAT | CELL_FS_O_TRUNC))
|
||||
{
|
||||
return {CELL_EPERM, path};
|
||||
return {CELL_EPERM};
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -326,14 +306,12 @@ lv2_file::open_result_t lv2_file::open(std::string_view vpath, s32 flags, s32 mo
|
|||
|
||||
if (!open_mode)
|
||||
{
|
||||
fmt::throw_exception("lv2_file::open(%s): Invalid or unimplemented flags: %#o" HERE, path, flags);
|
||||
fmt::throw_exception("lv2_file::open_raw(): Invalid or unimplemented flags: %#o" HERE, flags);
|
||||
}
|
||||
|
||||
fs::file file;
|
||||
{
|
||||
std::lock_guard lock(mp->mutex);
|
||||
file.open(local_path, open_mode);
|
||||
}
|
||||
std::lock_guard lock(mp->mutex);
|
||||
|
||||
fs::file file(local_path, open_mode);
|
||||
|
||||
if (!file && open_mode == fs::read && fs::g_tls_error == fs::error::noent)
|
||||
{
|
||||
|
@ -365,7 +343,7 @@ lv2_file::open_result_t lv2_file::open(std::string_view vpath, s32 flags, s32 mo
|
|||
// Failed to create file on read-only FS (file doesn't exist)
|
||||
if (flags & CELL_FS_O_CREAT)
|
||||
{
|
||||
return {CELL_EROFS, path};
|
||||
return {CELL_EROFS};
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -376,11 +354,11 @@ lv2_file::open_result_t lv2_file::open(std::string_view vpath, s32 flags, s32 mo
|
|||
|
||||
switch (auto error = fs::g_tls_error)
|
||||
{
|
||||
case fs::error::noent: return {CELL_ENOENT, path};
|
||||
case fs::error::noent: return {CELL_ENOENT};
|
||||
default: sys_fs.error("lv2_file::open(): unknown error %s", error);
|
||||
}
|
||||
|
||||
return {CELL_EIO, path};
|
||||
return {CELL_EIO};
|
||||
}
|
||||
|
||||
if (mp->flags & lv2_mp_flag::read_only)
|
||||
|
@ -388,27 +366,27 @@ lv2_file::open_result_t lv2_file::open(std::string_view vpath, s32 flags, s32 mo
|
|||
// Failed to create file on read-only FS (file exists)
|
||||
if (flags & CELL_FS_O_CREAT && flags & CELL_FS_O_EXCL)
|
||||
{
|
||||
return {CELL_EEXIST, path};
|
||||
return {CELL_EEXIST};
|
||||
}
|
||||
|
||||
// Failed to truncate file on read-only FS
|
||||
if (flags & CELL_FS_O_TRUNC)
|
||||
{
|
||||
return {CELL_EROFS, path};
|
||||
return {CELL_EROFS};
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & CELL_FS_O_MSELF && !verify_mself(file))
|
||||
{
|
||||
return {CELL_ENOTMSELF, path};
|
||||
return {CELL_ENOTMSELF};
|
||||
}
|
||||
|
||||
if (size == 8)
|
||||
if (type >= lv2_file_type::sdata)
|
||||
{
|
||||
// check for sdata
|
||||
switch (*static_cast<const be_t<u64>*>(arg))
|
||||
switch (type)
|
||||
{
|
||||
case 0x18000000010:
|
||||
case lv2_file_type::sdata:
|
||||
{
|
||||
// check if the file has the NPD header, or else assume its not encrypted
|
||||
u32 magic;
|
||||
|
@ -419,7 +397,7 @@ lv2_file::open_result_t lv2_file::open(std::string_view vpath, s32 flags, s32 mo
|
|||
auto sdata_file = std::make_unique<EDATADecrypter>(std::move(file));
|
||||
if (!sdata_file->ReadHeader())
|
||||
{
|
||||
return {CELL_EFSSPECIFIC, path};
|
||||
return {CELL_EFSSPECIFIC};
|
||||
}
|
||||
|
||||
file.reset(std::move(sdata_file));
|
||||
|
@ -428,7 +406,7 @@ lv2_file::open_result_t lv2_file::open(std::string_view vpath, s32 flags, s32 mo
|
|||
break;
|
||||
}
|
||||
// edata
|
||||
case 0x2:
|
||||
case lv2_file_type::edata:
|
||||
{
|
||||
// check if the file has the NPD header, or else assume its not encrypted
|
||||
u32 magic;
|
||||
|
@ -440,7 +418,7 @@ lv2_file::open_result_t lv2_file::open(std::string_view vpath, s32 flags, s32 mo
|
|||
auto sdata_file = std::make_unique<EDATADecrypter>(std::move(file), edatkeys->devKlic.load(), edatkeys->rifKey.load());
|
||||
if (!sdata_file->ReadHeader())
|
||||
{
|
||||
return {CELL_EFSSPECIFIC, path};
|
||||
return {CELL_EFSSPECIFIC};
|
||||
}
|
||||
|
||||
file.reset(std::move(sdata_file));
|
||||
|
@ -452,7 +430,49 @@ lv2_file::open_result_t lv2_file::open(std::string_view vpath, s32 flags, s32 mo
|
|||
}
|
||||
}
|
||||
|
||||
return {.error = {}, .ppath = path, .file = std::move(file)};
|
||||
return {.error = {}, .file = std::move(file)};
|
||||
}
|
||||
|
||||
lv2_file::open_result_t lv2_file::open(std::string_view vpath, s32 flags, s32 mode, const void* arg, u64 size)
|
||||
{
|
||||
if (vpath.empty())
|
||||
{
|
||||
return {CELL_ENOENT};
|
||||
}
|
||||
|
||||
std::string path;
|
||||
const std::string local_path = vfs::get(vpath, nullptr, &path);
|
||||
|
||||
const auto mp = lv2_fs_object::get_mp(path);
|
||||
|
||||
if (vpath.find_first_not_of('/') == umax)
|
||||
{
|
||||
return {CELL_EISDIR, path};
|
||||
}
|
||||
|
||||
if (local_path.empty())
|
||||
{
|
||||
return {CELL_ENOTMOUNTED, path};
|
||||
}
|
||||
|
||||
|
||||
lv2_file_type type = lv2_file_type::regular;
|
||||
|
||||
if (size == 8)
|
||||
{
|
||||
// see lv2_file::open_raw
|
||||
switch (*static_cast<const be_t<u64>*>(arg))
|
||||
{
|
||||
case 0x18000000010: type = lv2_file_type::sdata; break;
|
||||
case 0x2: type = lv2_file_type::edata; break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
auto [error, file] = open_raw(local_path, flags, mode, type, mp);
|
||||
|
||||
return {.error = error, .ppath = std::move(path), .real_path = std::move(local_path), .file = std::move(file), .type = type};
|
||||
}
|
||||
|
||||
error_code sys_fs_open(ppu_thread& ppu, vm::cptr<char> path, s32 flags, vm::ptr<u32> fd, s32 mode, vm::cptr<void> arg, u64 size)
|
||||
|
@ -464,7 +484,7 @@ error_code sys_fs_open(ppu_thread& ppu, vm::cptr<char> path, s32 flags, vm::ptr<
|
|||
if (!path)
|
||||
return CELL_EFAULT;
|
||||
|
||||
auto [error, ppath, file] = lv2_file::open(path.get_ptr(), flags, mode, arg.get_ptr(), size);
|
||||
auto [error, ppath, real, file, type] = lv2_file::open(path.get_ptr(), flags, mode, arg.get_ptr(), size);
|
||||
|
||||
if (error)
|
||||
{
|
||||
|
@ -476,42 +496,25 @@ error_code sys_fs_open(ppu_thread& ppu, vm::cptr<char> path, s32 flags, vm::ptr<
|
|||
return {error, path};
|
||||
}
|
||||
|
||||
lv2_file_type type = lv2_file_type::regular;
|
||||
|
||||
if (size == 8)
|
||||
if (type >= lv2_file_type::sdata)
|
||||
{
|
||||
// see lv2_file::open
|
||||
switch (vm::read64(arg.addr()))
|
||||
{
|
||||
case 0x18000000010:
|
||||
case 0x2:
|
||||
{
|
||||
type = lv2_file_type::npdrm;
|
||||
sys_fs.warning("sys_fs_open(): NPDRM detected");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
sys_fs.warning("sys_fs_open(): NPDRM detected");
|
||||
|
||||
if (type == lv2_file_type::npdrm)
|
||||
{
|
||||
if (const u32 id = idm::import<lv2_fs_object, lv2_file>([&ppath = ppath, &file = file, mode, flags]() -> std::shared_ptr<lv2_file>
|
||||
if (const u32 id = idm::import<lv2_fs_object, lv2_file>([&ppath = ppath, &file = file, mode, flags, &real = real, &type = type]() -> std::shared_ptr<lv2_file>
|
||||
{
|
||||
if (!g_fxo->get<loaded_npdrm_keys>()->npdrm_fds.try_inc(16))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return std::make_shared<lv2_file>(ppath, std::move(file), mode, flags, lv2_file_type::npdrm);
|
||||
return std::make_shared<lv2_file>(ppath, std::move(file), mode, flags, real, type);
|
||||
}))
|
||||
{
|
||||
*fd = id;
|
||||
return CELL_OK;
|
||||
}
|
||||
}
|
||||
else if (const u32 id = idm::make<lv2_fs_object, lv2_file>(ppath, std::move(file), mode, flags))
|
||||
else if (const u32 id = idm::make<lv2_fs_object, lv2_file>(ppath, std::move(file), mode, flags, real))
|
||||
{
|
||||
*fd = id;
|
||||
return CELL_OK;
|
||||
|
@ -622,7 +625,7 @@ error_code sys_fs_close(ppu_thread& ppu, u32 fd)
|
|||
|
||||
const auto file = idm::withdraw<lv2_fs_object, lv2_file>(fd, [](lv2_file& file)
|
||||
{
|
||||
if (file.type == lv2_file_type::npdrm)
|
||||
if (file.type >= lv2_file_type::sdata)
|
||||
{
|
||||
g_fxo->get<loaded_npdrm_keys>()->npdrm_fds--;
|
||||
}
|
||||
|
@ -674,11 +677,9 @@ error_code sys_fs_opendir(ppu_thread& ppu, vm::cptr<char> path, vm::ptr<u32> fd)
|
|||
return {CELL_ENOTDIR, path};
|
||||
}
|
||||
|
||||
fs::dir dir;
|
||||
{
|
||||
std::lock_guard lock(mp->mutex);
|
||||
dir.open(local_path);
|
||||
}
|
||||
std::lock_guard lock(mp->mutex);
|
||||
|
||||
fs::dir dir(local_path);
|
||||
|
||||
if (!dir)
|
||||
{
|
||||
|
@ -1029,9 +1030,10 @@ error_code sys_fs_rename(ppu_thread& ppu, vm::cptr<char> from, vm::cptr<char> to
|
|||
return CELL_EROFS;
|
||||
}
|
||||
|
||||
std::lock_guard lock(mp->mutex);
|
||||
// Done in vfs::host::rename
|
||||
//std::lock_guard lock(mp->mutex);
|
||||
|
||||
if (!vfs::host::rename(local_from, local_to, false))
|
||||
if (!vfs::host::rename(local_from, local_to, mp, false))
|
||||
{
|
||||
switch (auto error = fs::g_tls_error)
|
||||
{
|
||||
|
@ -1266,6 +1268,8 @@ error_code sys_fs_fcntl(ppu_thread& ppu, u32 fd, u32 op, vm::ptr<void> _arg, u32
|
|||
return CELL_EBADF;
|
||||
}
|
||||
|
||||
std::lock_guard lock(file->mp->mutex);
|
||||
|
||||
auto sdata_file = std::make_unique<EDATADecrypter>(lv2_file::make_view(file, arg->offset));
|
||||
|
||||
if (!sdata_file->ReadHeader())
|
||||
|
@ -1282,7 +1286,7 @@ error_code sys_fs_fcntl(ppu_thread& ppu, u32 fd, u32 op, vm::ptr<void> _arg, u32
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
return std::make_shared<lv2_file>(file, std::move(stream), file.mode, file.flags, lv2_file_type::npdrm);
|
||||
return std::make_shared<lv2_file>(file, std::move(stream), file.mode, file.flags, file.real_path, lv2_file_type::sdata);
|
||||
}))
|
||||
{
|
||||
arg->out_code = CELL_OK;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue