FSC: Use utf8 for mounting and internal target path

This commit is contained in:
Exzap 2022-09-09 00:18:37 +02:00
parent cf598e38c1
commit 0e0602e8d9
10 changed files with 40 additions and 47 deletions

View File

@ -626,7 +626,7 @@ namespace CafeSystem
if (fs::is_directory(contentPath, ec)) if (fs::is_directory(contentPath, ec))
{ {
// mounting content folder // mounting content folder
bool r = FSCDeviceHostFS_Mount(std::string("/vol/content").c_str(), boost::nowide::widen(_utf8Wrapper(contentPath)).c_str(), FSC_PRIORITY_BASE); bool r = FSCDeviceHostFS_Mount(std::string("/vol/content").c_str(), _utf8Wrapper(contentPath), FSC_PRIORITY_BASE);
if (!r) if (!r)
{ {
cemuLog_log(LogType::Force, "Failed to mount {}", _utf8Wrapper(contentPath).c_str()); cemuLog_log(LogType::Force, "Failed to mount {}", _utf8Wrapper(contentPath).c_str());
@ -635,7 +635,7 @@ namespace CafeSystem
} }
} }
// mount code folder to a virtual temporary path // mount code folder to a virtual temporary path
FSCDeviceHostFS_Mount(std::string("/internal/code/").c_str(), boost::nowide::widen(_utf8Wrapper(executablePath.parent_path())).c_str(), FSC_PRIORITY_BASE); FSCDeviceHostFS_Mount(std::string("/internal/code/").c_str(), _utf8Wrapper(executablePath.parent_path()), FSC_PRIORITY_BASE);
std::string internalExecutablePath = "/internal/code/"; std::string internalExecutablePath = "/internal/code/";
internalExecutablePath.append(_utf8Wrapper(executablePath.filename())); internalExecutablePath.append(_utf8Wrapper(executablePath.filename()));
_pathToExecutable = internalExecutablePath; _pathToExecutable = internalExecutablePath;

View File

@ -5,10 +5,10 @@ struct FSCMountPathNode
std::string path; std::string path;
std::vector<FSCMountPathNode*> subnodes; std::vector<FSCMountPathNode*> subnodes;
FSCMountPathNode* parent; FSCMountPathNode* parent;
// device target and path (if list_subnodes is nullptr) // device target and path (if subnodes is empty)
fscDeviceC* device{ nullptr }; fscDeviceC* device{ nullptr };
void* ctx{ nullptr }; void* ctx{ nullptr };
std::wstring targetPath; std::string deviceTargetPath; // the destination base path for the device, utf8
// priority // priority
sint32 priority{}; sint32 priority{};
@ -119,42 +119,44 @@ FSCMountPathNode* fsc_createMountPath(CoreinitFSParsedPath* parsedMountPath, sin
return nullptr; return nullptr;
} }
// Map a virtual FSC directory to a device and device directory // Map a virtual FSC directory to a device. targetPath points to the destination base directory within the device
sint32 fsc_mount(const char* mountPath, const wchar_t* _targetPath, fscDeviceC* fscDevice, void* ctx, sint32 priority) sint32 fsc_mount(std::string_view mountPath, std::string_view targetPath, fscDeviceC* fscDevice, void* ctx, sint32 priority)
{ {
cemu_assert(fscDevice); // device must not be nullptr cemu_assert(fscDevice);
std::string mountPathTmp(mountPath);
// make sure the target path ends with a slash // make sure the target path ends with a slash
std::wstring targetPath(_targetPath); std::string targetPathWithSlash(targetPath);
if (!targetPath.empty() && (targetPath.back() != '/' && targetPath.back() != '\\')) if (!targetPathWithSlash.empty() && (targetPathWithSlash.back() != '/' && targetPathWithSlash.back() != '\\'))
targetPath.push_back('/'); targetPathWithSlash.push_back('/');
// parse mount path // parse mount path
CoreinitFSParsedPath parsedMountPath; CoreinitFSParsedPath parsedMountPath;
coreinitFS_parsePath(&parsedMountPath, mountPath); coreinitFS_parsePath(&parsedMountPath, mountPathTmp.c_str());
// register path // register path
fscEnter(); fscEnter();
FSCMountPathNode* node = fsc_createMountPath(&parsedMountPath, priority); FSCMountPathNode* node = fsc_createMountPath(&parsedMountPath, priority);
if( !node ) if( !node )
{ {
// path empty, invalid or already used // path empty, invalid or already used
cemuLog_log(LogType::Force, "fsc_mount failed (virtual path: %s)", mountPath); cemuLog_log(LogType::Force, "fsc_mount failed (virtual path: {})", mountPath);
fscLeave(); fscLeave();
return FSC_STATUS_INVALID_PATH; return FSC_STATUS_INVALID_PATH;
} }
node->device = fscDevice; node->device = fscDevice;
node->ctx = ctx; node->ctx = ctx;
node->targetPath = targetPath; node->deviceTargetPath = targetPathWithSlash;
fscLeave(); fscLeave();
return FSC_STATUS_OK; return FSC_STATUS_OK;
} }
bool fsc_unmount(const char* mountPath, sint32 priority) bool fsc_unmount(std::string_view mountPath, sint32 priority)
{ {
std::string _tmp(mountPath);
CoreinitFSParsedPath parsedMountPath; CoreinitFSParsedPath parsedMountPath;
coreinitFS_parsePath(&parsedMountPath, mountPath); coreinitFS_parsePath(&parsedMountPath, _tmp.c_str());
fscEnter(); fscEnter();
FSCMountPathNode* mountPathNode = fsc_lookupPathVirtualNode(mountPath, priority); FSCMountPathNode* mountPathNode = fsc_lookupPathVirtualNode(_tmp.c_str(), priority);
if (!mountPathNode) if (!mountPathNode)
{ {
fscLeave(); fscLeave();
@ -218,7 +220,7 @@ bool fsc_lookupPath(const char* path, std::wstring& devicePathOut, fscDeviceC**
{ {
if (nodeParent->device) if (nodeParent->device)
{ {
devicePathOut = nodeParent->targetPath; devicePathOut = boost::nowide::widen(nodeParent->deviceTargetPath);
for (sint32 f = i; f < parsedPath.numNodes; f++) for (sint32 f = i; f < parsedPath.numNodes; f++)
{ {
const char* nodeName = coreinitFS_getNodeName(&parsedPath, f); const char* nodeName = coreinitFS_getNodeName(&parsedPath, f);

View File

@ -161,8 +161,8 @@ struct FSCVirtualFile
#define FSC_PRIORITY_COUNT (4) #define FSC_PRIORITY_COUNT (4)
void fsc_init(); void fsc_init();
sint32 fsc_mount(const char* mountPath, const wchar_t* targetPath, fscDeviceC* fscDevice, void* ctx, sint32 priority=0); sint32 fsc_mount(std::string_view mountPath, std::string_view targetPath, fscDeviceC* fscDevice, void* ctx, sint32 priority=0);
bool fsc_unmount(const char* mountPath, sint32 priority); bool fsc_unmount(std::string_view mountPath, sint32 priority);
void fsc_unmountAll(); void fsc_unmountAll();
FSCVirtualFile* fsc_open(const char* path, FSC_ACCESS_FLAG accessFlags, sint32* fscStatus, sint32 maxPriority=FSC_PRIORITY_MAX); FSCVirtualFile* fsc_open(const char* path, FSC_ACCESS_FLAG accessFlags, sint32* fscStatus, sint32 maxPriority=FSC_PRIORITY_MAX);
@ -188,14 +188,14 @@ bool fsc_doesFileExist(const char* path, sint32 maxPriority = FSC_PRIORITY_MAX);
bool fsc_doesDirectoryExist(const char* path, sint32 maxPriority = FSC_PRIORITY_MAX); bool fsc_doesDirectoryExist(const char* path, sint32 maxPriority = FSC_PRIORITY_MAX);
// wud device // wud device
bool FSCDeviceWUD_Mount(const char* mountPath, std::string_view destinationBaseDir, class FSTVolume* mountedVolume, sint32 priority); bool FSCDeviceWUD_Mount(std::string_view mountPath, std::string_view destinationBaseDir, class FSTVolume* mountedVolume, sint32 priority);
// wua device // wua device
bool FSCDeviceWUA_Mount(const char* mountPath, std::string_view destinationBaseDir, class ZArchiveReader* archive, sint32 priority); bool FSCDeviceWUA_Mount(std::string_view mountPath, std::string_view destinationBaseDir, class ZArchiveReader* archive, sint32 priority);
// hostFS device // hostFS device
void fscDeviceHostFS_mapBaseDirectories_deprecated(); void fscDeviceHostFS_mapBaseDirectories_deprecated();
bool FSCDeviceHostFS_Mount(const char* mountPath, const wchar_t* hostFSPath, sint32 priority); bool FSCDeviceHostFS_Mount(std::string_view mountPath, std::string_view hostTargetPath, sint32 priority);
// redirect device // redirect device
void fscDeviceRedirect_map(); void fscDeviceRedirect_map();

View File

@ -293,14 +293,11 @@ public:
void fscDeviceHostFS_mapBaseDirectories_deprecated() void fscDeviceHostFS_mapBaseDirectories_deprecated()
{ {
const auto mlc = ActiveSettings::GetMlcPath(); const auto mlc = ActiveSettings::GetMlcPath();
fsc_mount("/cemuBossStorage/", (mlc / "usr/boss/").generic_wstring().c_str(), &fscDeviceHostFSC::instance(), NULL, FSC_PRIORITY_BASE); fsc_mount("/cemuBossStorage/", _utf8Wrapper(mlc / "usr/boss/"), &fscDeviceHostFSC::instance(), NULL, FSC_PRIORITY_BASE);
fsc_mount("/vol/storage_mlc01/", (mlc / "").generic_wstring().c_str(), &fscDeviceHostFSC::instance(), NULL, FSC_PRIORITY_BASE); fsc_mount("/vol/storage_mlc01/", _utf8Wrapper(mlc / ""), &fscDeviceHostFSC::instance(), NULL, FSC_PRIORITY_BASE);
} }
bool FSCDeviceHostFS_Mount(const char* mountPath, const wchar_t* hostFSPath, sint32 priority) bool FSCDeviceHostFS_Mount(std::string_view mountPath, std::string_view hostTargetPath, sint32 priority)
{ {
std::wstring hostTargetPath(hostFSPath); return fsc_mount(mountPath, hostTargetPath, &fscDeviceHostFSC::instance(), nullptr, priority) == FSC_STATUS_OK;
if (!hostTargetPath.empty() && (hostTargetPath.back() != '/' && hostTargetPath.back() != '\\'))
hostTargetPath.push_back('/');
return fsc_mount(mountPath, hostTargetPath.c_str(), &fscDeviceHostFSC::instance(), nullptr, priority) == FSC_STATUS_OK;
} }

View File

@ -52,6 +52,6 @@ void fscDeviceRedirect_map()
{ {
if (_redirectMapped) if (_redirectMapped)
return; return;
fsc_mount("/", L"/", &fscDeviceTypeRedirect::instance(), nullptr, FSC_PRIORITY_REDIRECT); fsc_mount("/", "/", &fscDeviceTypeRedirect::instance(), nullptr, FSC_PRIORITY_REDIRECT);
_redirectMapped = true; _redirectMapped = true;
} }

View File

@ -169,10 +169,7 @@ public:
} }
}; };
bool FSCDeviceWUA_Mount(const char* mountPath, std::string_view destinationBaseDir, ZArchiveReader* archive, sint32 priority) bool FSCDeviceWUA_Mount(std::string_view mountPath, std::string_view destinationBaseDir, ZArchiveReader* archive, sint32 priority)
{ {
std::wstring hostTargetPath(boost::nowide::widen(destinationBaseDir.data(), destinationBaseDir.size())); return fsc_mount(mountPath, destinationBaseDir, &fscDeviceWUAC::instance(), archive, priority) == FSC_STATUS_OK;
if (!hostTargetPath.empty() && (hostTargetPath.back() != '/' && hostTargetPath.back() != '\\'))
hostTargetPath.push_back('/');
return fsc_mount(mountPath, hostTargetPath.c_str(), &fscDeviceWUAC::instance(), archive, priority) == FSC_STATUS_OK;
} }

View File

@ -157,10 +157,7 @@ public:
} }
}; };
bool FSCDeviceWUD_Mount(const char* mountPath, std::string_view destinationBaseDir, FSTVolume* mountedVolume, sint32 priority) bool FSCDeviceWUD_Mount(std::string_view mountPath, std::string_view destinationBaseDir, FSTVolume* mountedVolume, sint32 priority)
{ {
std::wstring hostTargetPath(boost::nowide::widen(destinationBaseDir.data(), destinationBaseDir.size())); return fsc_mount(mountPath, destinationBaseDir, &fscDeviceWUDC::instance(), mountedVolume, priority) == FSC_STATUS_OK;
if (!hostTargetPath.empty() && (hostTargetPath.back() != '/' && hostTargetPath.back() != '\\'))
hostTargetPath.push_back('/');
return fsc_mount(mountPath, hostTargetPath.c_str(), &fscDeviceWUDC::instance(), mountedVolume, priority) == FSC_STATUS_OK;
} }

View File

@ -109,7 +109,7 @@ namespace coreinit
std::error_code ec; std::error_code ec;
const auto path = ActiveSettings::GetPath("sdcard/"); const auto path = ActiveSettings::GetPath("sdcard/");
fs::create_directories(path, ec); fs::create_directories(path, ec);
FSCDeviceHostFS_Mount("/vol/external01", path.generic_wstring().c_str() , FSC_PRIORITY_BASE); FSCDeviceHostFS_Mount("/vol/external01", _utf8Wrapper(path), FSC_PRIORITY_BASE);
_sdCard01Mounted = true; _sdCard01Mounted = true;
} }
@ -142,7 +142,7 @@ namespace coreinit
std::error_code ec; std::error_code ec;
const auto path = ActiveSettings::GetPath("sdcard/"); const auto path = ActiveSettings::GetPath("sdcard/");
fs::create_directories(path, ec); fs::create_directories(path, ec);
if (!FSCDeviceHostFS_Mount(mountPathOut, path.generic_wstring().c_str(), FSC_PRIORITY_BASE)) if (!FSCDeviceHostFS_Mount(mountPathOut, _utf8Wrapper(path), FSC_PRIORITY_BASE))
return FS_RESULT::ERR_PLACEHOLDER; return FS_RESULT::ERR_PLACEHOLDER;
_sdCard01Mounted = true; _sdCard01Mounted = true;
} }
@ -150,7 +150,7 @@ namespace coreinit
if (_mlc01Mounted) if (_mlc01Mounted)
return FS_RESULT::ERR_PLACEHOLDER; return FS_RESULT::ERR_PLACEHOLDER;
if (!FSCDeviceHostFS_Mount(mountPathOut, ActiveSettings::GetMlcPath().generic_wstring().c_str(), FSC_PRIORITY_BASE)) if (!FSCDeviceHostFS_Mount(mountPathOut, _utf8Wrapper(ActiveSettings::GetMlcPath()), FSC_PRIORITY_BASE))
return FS_RESULT::ERR_PLACEHOLDER; return FS_RESULT::ERR_PLACEHOLDER;
_mlc01Mounted = true; _mlc01Mounted = true;
} }

View File

@ -51,7 +51,7 @@ namespace acp
// mount save path // mount save path
const auto mlc = ActiveSettings::GetMlcPath("usr/save/{:08x}/{:08x}/user/", high, low); const auto mlc = ActiveSettings::GetMlcPath("usr/save/{:08x}/{:08x}/user/", high, low);
FSCDeviceHostFS_Mount("/vol/save/", mlc.generic_wstring().c_str(), FSC_PRIORITY_BASE); FSCDeviceHostFS_Mount("/vol/save/", _utf8Wrapper(mlc), FSC_PRIORITY_BASE);
nnResult mountResult = BUILD_NN_RESULT(NN_RESULT_LEVEL_SUCCESS, NN_RESULT_MODULE_NN_ACP, 0); nnResult mountResult = BUILD_NN_RESULT(NN_RESULT_LEVEL_SUCCESS, NN_RESULT_MODULE_NN_ACP, 0);
return _ACPConvertResultToACPStatus(&mountResult, "ACPMountSaveDir", 0x60); return _ACPConvertResultToACPStatus(&mountResult, "ACPMountSaveDir", 0x60);
} }

View File

@ -370,7 +370,7 @@ bool TitleInfo::Mount(std::string_view virtualPath, std::string_view subfolder,
{ {
fs::path hostFSPath = m_fullPath; fs::path hostFSPath = m_fullPath;
hostFSPath.append(subfolder); hostFSPath.append(subfolder);
bool r = FSCDeviceHostFS_Mount(std::string(virtualPath).c_str(), boost::nowide::widen(_utf8Wrapper(hostFSPath)).c_str(), mountPriority); bool r = FSCDeviceHostFS_Mount(std::string(virtualPath).c_str(), _utf8Wrapper(hostFSPath), mountPriority);
cemu_assert_debug(r); cemu_assert_debug(r);
if (!r) if (!r)
{ {
@ -387,7 +387,7 @@ bool TitleInfo::Mount(std::string_view virtualPath, std::string_view subfolder,
} }
if (!m_wudVolume) if (!m_wudVolume)
return false; return false;
bool r = FSCDeviceWUD_Mount(std::string(virtualPath).c_str(), subfolder, m_wudVolume, mountPriority); bool r = FSCDeviceWUD_Mount(virtualPath, subfolder, m_wudVolume, mountPriority);
cemu_assert_debug(r); cemu_assert_debug(r);
if (!r) if (!r)
{ {
@ -404,7 +404,7 @@ bool TitleInfo::Mount(std::string_view virtualPath, std::string_view subfolder,
if (!m_zarchive) if (!m_zarchive)
return false; return false;
} }
bool r = FSCDeviceWUA_Mount(std::string(virtualPath).c_str(), std::string(m_subPath).append("/").append(subfolder), m_zarchive, mountPriority); bool r = FSCDeviceWUA_Mount(virtualPath, std::string(m_subPath).append("/").append(subfolder), m_zarchive, mountPriority);
if (!r) if (!r)
{ {
cemuLog_log(LogType::Force, "Failed to mount {} to {}", virtualPath, subfolder); cemuLog_log(LogType::Force, "Failed to mount {} to {}", virtualPath, subfolder);