mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-26 15:55:31 +01:00
FatFsUtil: Add ability to provide callbacks for the FatFs code.
This commit is contained in:
parent
dafe2c785a
commit
3182d9178c
@ -33,30 +33,21 @@ enum : u32
|
|||||||
};
|
};
|
||||||
|
|
||||||
static std::mutex s_fatfs_mutex;
|
static std::mutex s_fatfs_mutex;
|
||||||
static File::IOFile* s_image;
|
static Common::FatFsCallbacks* s_callbacks;
|
||||||
static bool s_deterministic;
|
|
||||||
|
|
||||||
extern "C" DSTATUS disk_status(BYTE pdrv)
|
namespace
|
||||||
{
|
{
|
||||||
return 0;
|
int SDCardDiskRead(File::IOFile* image, u8 pdrv, u8* buff, u32 sector, unsigned int count)
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" DSTATUS disk_initialize(BYTE pdrv)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" DRESULT disk_read(BYTE pdrv, BYTE* buff, LBA_t sector, UINT count)
|
|
||||||
{
|
{
|
||||||
const u64 offset = static_cast<u64>(sector) * SECTOR_SIZE;
|
const u64 offset = static_cast<u64>(sector) * SECTOR_SIZE;
|
||||||
if (!s_image->Seek(offset, File::SeekOrigin::Begin))
|
if (!image->Seek(offset, File::SeekOrigin::Begin))
|
||||||
{
|
{
|
||||||
ERROR_LOG_FMT(COMMON, "SD image seek failed (offset={})", offset);
|
ERROR_LOG_FMT(COMMON, "SD image seek failed (offset={})", offset);
|
||||||
return RES_ERROR;
|
return RES_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
const size_t size = static_cast<size_t>(count) * SECTOR_SIZE;
|
const size_t size = static_cast<size_t>(count) * SECTOR_SIZE;
|
||||||
if (!s_image->ReadBytes(buff, size))
|
if (!image->ReadBytes(buff, size))
|
||||||
{
|
{
|
||||||
ERROR_LOG_FMT(COMMON, "SD image read failed (offset={}, size={})", offset, size);
|
ERROR_LOG_FMT(COMMON, "SD image read failed (offset={}, size={})", offset, size);
|
||||||
return RES_ERROR;
|
return RES_ERROR;
|
||||||
@ -65,17 +56,17 @@ extern "C" DRESULT disk_read(BYTE pdrv, BYTE* buff, LBA_t sector, UINT count)
|
|||||||
return RES_OK;
|
return RES_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" DRESULT disk_write(BYTE pdrv, const BYTE* buff, LBA_t sector, UINT count)
|
int SDCardDiskWrite(File::IOFile* image, u8 pdrv, const u8* buff, u32 sector, unsigned int count)
|
||||||
{
|
{
|
||||||
const u64 offset = static_cast<u64>(sector) * SECTOR_SIZE;
|
const u64 offset = static_cast<u64>(sector) * SECTOR_SIZE;
|
||||||
if (!s_image->Seek(offset, File::SeekOrigin::Begin))
|
if (!image->Seek(offset, File::SeekOrigin::Begin))
|
||||||
{
|
{
|
||||||
ERROR_LOG_FMT(COMMON, "SD image seek failed (offset={})", offset);
|
ERROR_LOG_FMT(COMMON, "SD image seek failed (offset={})", offset);
|
||||||
return RES_ERROR;
|
return RES_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
const size_t size = static_cast<size_t>(count) * SECTOR_SIZE;
|
const size_t size = static_cast<size_t>(count) * SECTOR_SIZE;
|
||||||
if (!s_image->WriteBytes(buff, size))
|
if (!image->WriteBytes(buff, size))
|
||||||
{
|
{
|
||||||
ERROR_LOG_FMT(COMMON, "SD image write failed (offset={}, size={})", offset, size);
|
ERROR_LOG_FMT(COMMON, "SD image write failed (offset={}, size={})", offset, size);
|
||||||
return RES_ERROR;
|
return RES_ERROR;
|
||||||
@ -84,14 +75,14 @@ extern "C" DRESULT disk_write(BYTE pdrv, const BYTE* buff, LBA_t sector, UINT co
|
|||||||
return RES_OK;
|
return RES_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void* buff)
|
int SDCardDiskIOCtl(File::IOFile* image, u8 pdrv, u8 cmd, void* buff)
|
||||||
{
|
{
|
||||||
switch (cmd)
|
switch (cmd)
|
||||||
{
|
{
|
||||||
case CTRL_SYNC:
|
case CTRL_SYNC:
|
||||||
return RES_OK;
|
return RES_OK;
|
||||||
case GET_SECTOR_COUNT:
|
case GET_SECTOR_COUNT:
|
||||||
*reinterpret_cast<LBA_t*>(buff) = s_image->GetSize() / SECTOR_SIZE;
|
*reinterpret_cast<LBA_t*>(buff) = image->GetSize() / SECTOR_SIZE;
|
||||||
return RES_OK;
|
return RES_OK;
|
||||||
default:
|
default:
|
||||||
WARN_LOG_FMT(COMMON, "Unexpected SD image ioctl {}", cmd);
|
WARN_LOG_FMT(COMMON, "Unexpected SD image ioctl {}", cmd);
|
||||||
@ -99,11 +90,8 @@ extern "C" DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void* buff)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" DWORD get_fattime(void)
|
u32 GetSystemTimeFAT()
|
||||||
{
|
{
|
||||||
if (s_deterministic)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
const std::time_t time = std::time(nullptr);
|
const std::time_t time = std::time(nullptr);
|
||||||
std::tm tm;
|
std::tm tm;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
@ -121,6 +109,91 @@ extern "C" DWORD get_fattime(void)
|
|||||||
fattime |= std::min(tm.tm_sec, 59) >> 1;
|
fattime |= std::min(tm.tm_sec, 59) >> 1;
|
||||||
return fattime;
|
return fattime;
|
||||||
}
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace Common
|
||||||
|
{
|
||||||
|
FatFsCallbacks::FatFsCallbacks() = default;
|
||||||
|
FatFsCallbacks::~FatFsCallbacks() = default;
|
||||||
|
|
||||||
|
u8 FatFsCallbacks::DiskInitialize(u8 pdrv)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 FatFsCallbacks::DiskStatus(u8 pdrv)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 FatFsCallbacks::GetCurrentTimeFAT()
|
||||||
|
{
|
||||||
|
return GetSystemTimeFAT();
|
||||||
|
}
|
||||||
|
} // namespace Common
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
class SDCardFatFsCallbacks : public Common::FatFsCallbacks
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int DiskRead(u8 pdrv, u8* buff, u32 sector, unsigned int count) override
|
||||||
|
{
|
||||||
|
return SDCardDiskRead(m_image, pdrv, buff, sector, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
int DiskWrite(u8 pdrv, const u8* buff, u32 sector, unsigned int count) override
|
||||||
|
{
|
||||||
|
return SDCardDiskWrite(m_image, pdrv, buff, sector, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
int DiskIOCtl(u8 pdrv, u8 cmd, void* buff) override
|
||||||
|
{
|
||||||
|
return SDCardDiskIOCtl(m_image, pdrv, cmd, buff);
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 GetCurrentTimeFAT() override
|
||||||
|
{
|
||||||
|
if (m_deterministic)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return GetSystemTimeFAT();
|
||||||
|
}
|
||||||
|
|
||||||
|
File::IOFile* m_image;
|
||||||
|
bool m_deterministic;
|
||||||
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
extern "C" DSTATUS disk_status(BYTE pdrv)
|
||||||
|
{
|
||||||
|
return static_cast<DSTATUS>(s_callbacks->DiskStatus(pdrv));
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" DSTATUS disk_initialize(BYTE pdrv)
|
||||||
|
{
|
||||||
|
return static_cast<DSTATUS>(s_callbacks->DiskInitialize(pdrv));
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" DRESULT disk_read(BYTE pdrv, BYTE* buff, LBA_t sector, UINT count)
|
||||||
|
{
|
||||||
|
return static_cast<DRESULT>(s_callbacks->DiskRead(pdrv, buff, sector, count));
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" DRESULT disk_write(BYTE pdrv, const BYTE* buff, LBA_t sector, UINT count)
|
||||||
|
{
|
||||||
|
return static_cast<DRESULT>(s_callbacks->DiskWrite(pdrv, buff, sector, count));
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void* buff)
|
||||||
|
{
|
||||||
|
return static_cast<DRESULT>(s_callbacks->DiskIOCtl(pdrv, cmd, buff));
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" DWORD get_fattime(void)
|
||||||
|
{
|
||||||
|
return static_cast<DWORD>(s_callbacks->GetCurrentTimeFAT());
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" void* ff_memalloc(UINT msize)
|
extern "C" void* ff_memalloc(UINT msize)
|
||||||
{
|
{
|
||||||
@ -435,11 +508,13 @@ bool SyncSDFolderToSDImage(bool deterministic)
|
|||||||
size = AlignUp(size, MAX_CLUSTER_SIZE);
|
size = AlignUp(size, MAX_CLUSTER_SIZE);
|
||||||
|
|
||||||
std::lock_guard lk(s_fatfs_mutex);
|
std::lock_guard lk(s_fatfs_mutex);
|
||||||
|
SDCardFatFsCallbacks callbacks;
|
||||||
|
s_callbacks = &callbacks;
|
||||||
|
Common::ScopeGuard callbacks_guard{[] { s_callbacks = nullptr; }};
|
||||||
|
|
||||||
File::IOFile image;
|
File::IOFile image;
|
||||||
s_image = ℑ
|
callbacks.m_image = ℑ
|
||||||
Common::ScopeGuard image_guard{[] { s_image = nullptr; }};
|
callbacks.m_deterministic = deterministic;
|
||||||
s_deterministic = deterministic;
|
|
||||||
|
|
||||||
const std::string temp_image_path = File::GetTempFilenameForAtomicWrite(image_path);
|
const std::string temp_image_path = File::GetTempFilenameForAtomicWrite(image_path);
|
||||||
if (!image.Open(temp_image_path, "w+b"))
|
if (!image.Open(temp_image_path, "w+b"))
|
||||||
@ -672,17 +747,19 @@ bool SyncSDImageToSDFolder()
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
std::lock_guard lk(s_fatfs_mutex);
|
std::lock_guard lk(s_fatfs_mutex);
|
||||||
|
SDCardFatFsCallbacks callbacks;
|
||||||
|
s_callbacks = &callbacks;
|
||||||
|
Common::ScopeGuard callbacks_guard{[] { s_callbacks = nullptr; }};
|
||||||
|
|
||||||
INFO_LOG_FMT(COMMON, "Starting SD card conversion from file {} to folder {}", image_path,
|
INFO_LOG_FMT(COMMON, "Starting SD card conversion from file {} to folder {}", image_path,
|
||||||
target_dir);
|
target_dir);
|
||||||
|
|
||||||
File::IOFile image;
|
File::IOFile image;
|
||||||
s_image = ℑ
|
callbacks.m_image = ℑ
|
||||||
Common::ScopeGuard image_guard{[] { s_image = nullptr; }};
|
|
||||||
|
|
||||||
// this shouldn't matter since we're not modifying the SD image here, but initialize it to
|
// this shouldn't matter since we're not modifying the SD image here, but initialize it to
|
||||||
// something consistent just in case
|
// something consistent just in case
|
||||||
s_deterministic = true;
|
callbacks.m_deterministic = true;
|
||||||
|
|
||||||
if (!image.Open(image_path, "r+b"))
|
if (!image.Open(image_path, "r+b"))
|
||||||
{
|
{
|
||||||
@ -740,4 +817,12 @@ bool SyncSDImageToSDFolder()
|
|||||||
INFO_LOG_FMT(COMMON, "Successfully unpacked SD image {} to {}", image_path, target_dir);
|
INFO_LOG_FMT(COMMON, "Successfully unpacked SD image {} to {}", image_path, target_dir);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RunInFatFsContext(FatFsCallbacks& callbacks, const std::function<void()>& function)
|
||||||
|
{
|
||||||
|
std::lock_guard lk(s_fatfs_mutex);
|
||||||
|
s_callbacks = &callbacks;
|
||||||
|
Common::ScopeGuard callbacks_guard{[] { s_callbacks = nullptr; }};
|
||||||
|
function();
|
||||||
|
}
|
||||||
} // namespace Common
|
} // namespace Common
|
||||||
|
@ -3,10 +3,28 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
|
|
||||||
namespace Common
|
namespace Common
|
||||||
{
|
{
|
||||||
bool SyncSDFolderToSDImage(bool deterministic);
|
bool SyncSDFolderToSDImage(bool deterministic);
|
||||||
bool SyncSDImageToSDFolder();
|
bool SyncSDImageToSDFolder();
|
||||||
|
|
||||||
|
class FatFsCallbacks
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FatFsCallbacks();
|
||||||
|
virtual ~FatFsCallbacks();
|
||||||
|
|
||||||
|
virtual u8 DiskInitialize(u8 pdrv);
|
||||||
|
virtual u8 DiskStatus(u8 pdrv);
|
||||||
|
virtual int DiskRead(u8 pdrv, u8* buff, u32 sector, unsigned int count) = 0;
|
||||||
|
virtual int DiskWrite(u8 pdrv, const u8* buff, u32 sector, unsigned int count) = 0;
|
||||||
|
virtual int DiskIOCtl(u8 pdrv, u8 cmd, void* buff) = 0;
|
||||||
|
virtual u32 GetCurrentTimeFAT();
|
||||||
|
};
|
||||||
|
|
||||||
|
void RunInFatFsContext(FatFsCallbacks& callbacks, const std::function<void()>& function);
|
||||||
} // namespace Common
|
} // namespace Common
|
||||||
|
Loading…
x
Reference in New Issue
Block a user