mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 14:19:46 -06:00
IOS/KD/VFF: Implement reading from VFF
This commit is contained in:

committed by
Admiral H. Curtiss

parent
0d908a83e7
commit
2c3d05423d
@ -616,8 +616,8 @@ NWC24::ErrorCode NetKDRequestDevice::KDDownload(const u16 entry_index,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NWC24::ErrorCode reply = IOS::HLE::NWC24::OpenVFF(m_dl_list.GetVFFPath(entry_index), content_name,
|
NWC24::ErrorCode reply = IOS::HLE::NWC24::WriteToVFF(m_dl_list.GetVFFPath(entry_index),
|
||||||
m_ios.GetFS(), file_data);
|
content_name, m_ios.GetFS(), file_data);
|
||||||
|
|
||||||
if (reply != NWC24::WC24_OK)
|
if (reply != NWC24::WC24_OK)
|
||||||
{
|
{
|
||||||
|
@ -237,6 +237,48 @@ static ErrorCode WriteFile(const std::string& filename, const std::vector<u8>& t
|
|||||||
return WC24_OK;
|
return WC24_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ErrorCode ReadFile(const std::string& filename, std::vector<u8>& out)
|
||||||
|
{
|
||||||
|
FIL src{};
|
||||||
|
const auto open_error_code = f_open(&src, filename.c_str(), FA_READ);
|
||||||
|
if (open_error_code != FR_OK)
|
||||||
|
{
|
||||||
|
ERROR_LOG_FMT(IOS_WC24, "Failed to open file {} in VFF", filename);
|
||||||
|
return WC24_ERR_FILE_OPEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
Common::ScopeGuard vff_close_guard{[&] { f_close(&src); }};
|
||||||
|
|
||||||
|
u32 size = static_cast<u32>(out.size());
|
||||||
|
u32 read_size{};
|
||||||
|
const auto read_error_code = f_read(&src, out.data(), size, &read_size);
|
||||||
|
if (read_error_code != FR_OK)
|
||||||
|
{
|
||||||
|
ERROR_LOG_FMT(IOS_WC24, "Failed to read file {} in VFF: {}", filename,
|
||||||
|
static_cast<u32>(read_error_code));
|
||||||
|
return WC24_ERR_FILE_READ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (read_size != size)
|
||||||
|
{
|
||||||
|
ERROR_LOG_FMT(IOS_WC24, "Failed to read bytes of file {} to VFF ({} != {})", filename,
|
||||||
|
read_size, size);
|
||||||
|
return WC24_ERR_FILE_READ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// As prior operations did not fail, dismiss the guard and handle a potential error with f_close.
|
||||||
|
vff_close_guard.Dismiss();
|
||||||
|
|
||||||
|
const auto close_error_code = f_close(&src);
|
||||||
|
if (close_error_code != FR_OK)
|
||||||
|
{
|
||||||
|
ERROR_LOG_FMT(IOS_WC24, "Failed to close file {} in VFF", filename);
|
||||||
|
return WC24_ERR_FILE_CLOSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return WC24_OK;
|
||||||
|
}
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
class VffFatFsCallbacks : public Common::FatFsCallbacks
|
class VffFatFsCallbacks : public Common::FatFsCallbacks
|
||||||
@ -258,7 +300,7 @@ public:
|
|||||||
};
|
};
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
ErrorCode OpenVFF(const std::string& path, const std::string& filename,
|
ErrorCode WriteToVFF(const std::string& path, const std::string& filename,
|
||||||
const std::shared_ptr<FS::FileSystem>& fs, const std::vector<u8>& data)
|
const std::shared_ptr<FS::FileSystem>& fs, const std::vector<u8>& data)
|
||||||
{
|
{
|
||||||
VffFatFsCallbacks callbacks;
|
VffFatFsCallbacks callbacks;
|
||||||
@ -286,6 +328,8 @@ ErrorCode OpenVFF(const std::string& path, const std::string& filename,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Common::ScopeGuard unmount_guard{[] { f_unmount(""); }};
|
||||||
|
|
||||||
const FRESULT vff_mount_error_code = vff_mount(callbacks.m_vff, &fatfs);
|
const FRESULT vff_mount_error_code = vff_mount(callbacks.m_vff, &fatfs);
|
||||||
if (vff_mount_error_code != FR_OK)
|
if (vff_mount_error_code != FR_OK)
|
||||||
{
|
{
|
||||||
@ -295,8 +339,6 @@ ErrorCode OpenVFF(const std::string& path, const std::string& filename,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::ScopeGuard unmount_guard{[] { f_unmount(""); }};
|
|
||||||
|
|
||||||
const auto write_error_code = WriteFile(filename, data);
|
const auto write_error_code = WriteFile(filename, data);
|
||||||
if (write_error_code != WC24_OK)
|
if (write_error_code != WC24_OK)
|
||||||
{
|
{
|
||||||
@ -312,4 +354,108 @@ ErrorCode OpenVFF(const std::string& path, const std::string& filename,
|
|||||||
|
|
||||||
return return_value;
|
return return_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ErrorCode ReadFromVFF(const std::string& path, const std::string& filename,
|
||||||
|
const std::shared_ptr<FS::FileSystem>& fs, std::vector<u8>& out)
|
||||||
|
{
|
||||||
|
VffFatFsCallbacks callbacks;
|
||||||
|
ErrorCode return_value;
|
||||||
|
Common::RunInFatFsContext(callbacks, [&]() {
|
||||||
|
auto temp = fs->OpenFile(PID_KD, PID_KD, path, FS::Mode::ReadWrite);
|
||||||
|
if (!temp)
|
||||||
|
{
|
||||||
|
ERROR_LOG_FMT(IOS_WC24, "Failed to open VFF at: {}", path);
|
||||||
|
return_value = WC24_ERR_NOT_FOUND;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
callbacks.m_vff = &*temp;
|
||||||
|
|
||||||
|
FATFS fatfs{};
|
||||||
|
const FRESULT fatfs_mount_error_code = f_mount(&fatfs, "", 0);
|
||||||
|
if (fatfs_mount_error_code != FR_OK)
|
||||||
|
{
|
||||||
|
// The VFF is most likely broken.
|
||||||
|
ERROR_LOG_FMT(IOS_WC24, "Failed to mount VFF at: {}", path);
|
||||||
|
return_value = WC24_ERR_BROKEN;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Common::ScopeGuard unmount_guard{[] { f_unmount(""); }};
|
||||||
|
|
||||||
|
const FRESULT vff_mount_error_code = vff_mount(callbacks.m_vff, &fatfs);
|
||||||
|
if (vff_mount_error_code != FR_OK)
|
||||||
|
{
|
||||||
|
// The VFF is most likely broken.
|
||||||
|
ERROR_LOG_FMT(IOS_WC24, "Failed to mount VFF at: {}", path);
|
||||||
|
return_value = WC24_ERR_BROKEN;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ErrorCode read_error_code = ReadFile(filename, out);
|
||||||
|
if (read_error_code != WC24_OK)
|
||||||
|
{
|
||||||
|
return_value = read_error_code;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return_value = WC24_OK;
|
||||||
|
return;
|
||||||
|
});
|
||||||
|
|
||||||
|
return return_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorCode DeleteFileFromVFF(const std::string& path, const std::string& filename,
|
||||||
|
const std::shared_ptr<FS::FileSystem>& fs)
|
||||||
|
{
|
||||||
|
VffFatFsCallbacks callbacks;
|
||||||
|
ErrorCode return_value;
|
||||||
|
Common::RunInFatFsContext(callbacks, [&]() {
|
||||||
|
auto temp = fs->OpenFile(PID_KD, PID_KD, path, FS::Mode::ReadWrite);
|
||||||
|
if (!temp)
|
||||||
|
{
|
||||||
|
ERROR_LOG_FMT(IOS_WC24, "Failed to open VFF at: {}", path);
|
||||||
|
return_value = WC24_ERR_NOT_FOUND;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
callbacks.m_vff = &*temp;
|
||||||
|
|
||||||
|
FATFS fatfs{};
|
||||||
|
const FRESULT fatfs_mount_error_code = f_mount(&fatfs, "", 0);
|
||||||
|
if (fatfs_mount_error_code != FR_OK)
|
||||||
|
{
|
||||||
|
// The VFF is most likely broken.
|
||||||
|
ERROR_LOG_FMT(IOS_WC24, "Failed to mount VFF at: {}", path);
|
||||||
|
return_value = WC24_ERR_BROKEN;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Common::ScopeGuard unmount_guard{[] { f_unmount(""); }};
|
||||||
|
|
||||||
|
const FRESULT vff_mount_error_code = vff_mount(callbacks.m_vff, &fatfs);
|
||||||
|
if (vff_mount_error_code != FR_OK)
|
||||||
|
{
|
||||||
|
// The VFF is most likely broken.
|
||||||
|
ERROR_LOG_FMT(IOS_WC24, "Failed to mount VFF at: {}", path);
|
||||||
|
return_value = WC24_ERR_BROKEN;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const FRESULT unlink_code = f_unlink(filename.c_str());
|
||||||
|
if (unlink_code != FR_OK)
|
||||||
|
{
|
||||||
|
ERROR_LOG_FMT(IOS_WC24, "Failed to delete file {} in VFF at: {} Code: {}", filename, path,
|
||||||
|
static_cast<u32>(unlink_code));
|
||||||
|
return_value = WC24_ERR_BROKEN;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return_value = WC24_OK;
|
||||||
|
return;
|
||||||
|
});
|
||||||
|
|
||||||
|
return return_value;
|
||||||
|
}
|
||||||
} // namespace IOS::HLE::NWC24
|
} // namespace IOS::HLE::NWC24
|
||||||
|
@ -22,8 +22,12 @@ namespace NWC24
|
|||||||
constexpr u16 SECTOR_SIZE = 512;
|
constexpr u16 SECTOR_SIZE = 512;
|
||||||
constexpr u16 VF_LITTLE_ENDIAN = 0xFFFE;
|
constexpr u16 VF_LITTLE_ENDIAN = 0xFFFE;
|
||||||
constexpr u16 VF_BIG_ENDIAN = 0xFEFF;
|
constexpr u16 VF_BIG_ENDIAN = 0xFEFF;
|
||||||
ErrorCode OpenVFF(const std::string& path, const std::string& filename,
|
ErrorCode WriteToVFF(const std::string& path, const std::string& filename,
|
||||||
const std::shared_ptr<FS::FileSystem>& fs, const std::vector<u8>& data);
|
const std::shared_ptr<FS::FileSystem>& fs, const std::vector<u8>& data);
|
||||||
|
ErrorCode ReadFromVFF(const std::string& path, const std::string& filename,
|
||||||
|
const std::shared_ptr<FS::FileSystem>& fs, std::vector<u8>& out);
|
||||||
|
ErrorCode DeleteFileFromVFF(const std::string& path, const std::string& filename,
|
||||||
|
const std::shared_ptr<FS::FileSystem>& fs);
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
struct VFFHeader final
|
struct VFFHeader final
|
||||||
|
Reference in New Issue
Block a user