Merge pull request #231 from Exzap/main

FSC: Replace wstring paths with utf8 encoded strings + misc clean up
This commit is contained in:
Exzap
2022-09-10 00:48:20 +02:00
committed by GitHub
26 changed files with 333 additions and 648 deletions
+6 -6
View File
@@ -209,7 +209,7 @@ void InfoLog_TitleLoaded()
fs::path effectiveSavePath = getTitleSavePath();
std::error_code ec;
const bool saveDirExists = fs::exists(effectiveSavePath, ec);
cemuLog_force("Save path: {}{}", _utf8Wrapper(effectiveSavePath), saveDirExists ? "" : " (not present)");
cemuLog_force("Save path: {}{}", _pathToUtf8(effectiveSavePath), saveDirExists ? "" : " (not present)");
// log shader cache name
cemuLog_log(LogType::Force, "Shader cache file: shaderCache/transferable/{:016x}.bin", titleId);
@@ -617,7 +617,7 @@ namespace CafeSystem
sLaunchModeIsStandalone = true;
cemuLog_log(LogType::Force, "Launching executable in standalone mode due to incorrect layout or missing meta files");
fs::path executablePath = path;
std::string dirName = _utf8Wrapper(executablePath.parent_path().filename());
std::string dirName = _pathToUtf8(executablePath.parent_path().filename());
if (boost::iequals(dirName, "code"))
{
// check for content folder
@@ -626,18 +626,18 @@ namespace CafeSystem
if (fs::is_directory(contentPath, ec))
{
// 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(), _pathToUtf8(contentPath), FSC_PRIORITY_BASE);
if (!r)
{
cemuLog_log(LogType::Force, "Failed to mount {}", _utf8Wrapper(contentPath).c_str());
cemuLog_log(LogType::Force, "Failed to mount {}", _pathToUtf8(contentPath));
return STATUS_CODE::UNABLE_TO_MOUNT;
}
}
}
// 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(), _pathToUtf8(executablePath.parent_path()), FSC_PRIORITY_BASE);
std::string internalExecutablePath = "/internal/code/";
internalExecutablePath.append(_utf8Wrapper(executablePath.filename()));
internalExecutablePath.append(_pathToUtf8(executablePath.filename()));
_pathToExecutable = internalExecutablePath;
// since a lot of systems (including save folder location) rely on a TitleId, we derive a placeholder id from the executable hash
auto execData = fsc_extractFile(_pathToExecutable.c_str());
File diff suppressed because it is too large Load Diff
+48 -143
View File
@@ -1,14 +1,15 @@
#include "Cafe/Filesystem/fsc.h"
#include "Cafe/Filesystem/FST/fstUtil.h"
struct FSCMountPathNode
{
std::string path;
std::vector<FSCMountPathNode*> subnodes;
FSCMountPathNode* parent;
// device target and path (if list_subnodes is nullptr)
// device target and path (if subnodes is empty)
fscDeviceC* device{ nullptr };
void* ctx{ nullptr };
std::wstring targetPath;
std::string deviceTargetPath; // the destination base path for the device, utf8
// priority
sint32 priority{};
@@ -24,7 +25,7 @@ struct FSCMountPathNode
}
};
// compare two file or directory names using FS rules
// compare two file or directory names using FSA rules
bool FSA_CompareNodeName(std::string_view a, std::string_view b)
{
if (a.size() != b.size())
@@ -74,25 +75,25 @@ void fsc_reset()
* /vol/content/data -> Map to HostFS
* If overlapping paths with different priority are created, then the higher priority one will be checked first
*/
FSCMountPathNode* fsc_createMountPath(CoreinitFSParsedPath* parsedMountPath, sint32 priority)
FSCMountPathNode* fsc_createMountPath(const FSCPath& mountPath, sint32 priority)
{
cemu_assert(priority >= 0 && priority < FSC_PRIORITY_COUNT);
fscEnter();
FSCMountPathNode* nodeParent = s_fscRootNodePerPrio[priority];
for(sint32 i=0; i<parsedMountPath->numNodes; i++)
for (size_t i=0; i< mountPath.GetNodeCount(); i++)
{
// search for subdirectory
FSCMountPathNode* nodeSub = nullptr; // set if we found a subnode with a matching name, else this is used to store the new nodes
for(auto& nodeItr : nodeParent->subnodes)
for (auto& nodeItr : nodeParent->subnodes)
{
if( coreinitFS_checkNodeName(parsedMountPath, i, nodeItr->path.c_str()) )
if (mountPath.MatchNodeName(i, nodeItr->path))
{
// subnode found
nodeSub = nodeItr;
break;
}
}
if( nodeSub )
if (nodeSub)
{
// traverse subnode
nodeParent = nodeSub;
@@ -100,10 +101,10 @@ FSCMountPathNode* fsc_createMountPath(CoreinitFSParsedPath* parsedMountPath, sin
}
// no matching subnode, add new entry
nodeSub = new FSCMountPathNode(nodeParent);
nodeSub->path = coreinitFS_getNodeName(parsedMountPath, i);
nodeSub->path = mountPath.GetNodeName(i);
nodeSub->priority = priority;
nodeParent->subnodes.emplace_back(nodeSub);
if( i == (parsedMountPath->numNodes-1) )
if (i == (mountPath.GetNodeCount() - 1))
{
// last node
fscLeave();
@@ -114,47 +115,44 @@ FSCMountPathNode* fsc_createMountPath(CoreinitFSParsedPath* parsedMountPath, sin
}
// path is empty or already mounted
fscLeave();
if (parsedMountPath->numNodes == 0)
if (mountPath.GetNodeCount() == 0)
return nodeParent;
return nullptr;
}
// Map a virtual FSC directory to a device and device directory
sint32 fsc_mount(const char* mountPath, const wchar_t* _targetPath, fscDeviceC* fscDevice, void* ctx, sint32 priority)
// Map a virtual FSC directory to a device. targetPath points to the destination base directory within the device
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
std::wstring targetPath(_targetPath);
if (!targetPath.empty() && (targetPath.back() != '/' && targetPath.back() != '\\'))
targetPath.push_back('/');
std::string targetPathWithSlash(targetPath);
if (!targetPathWithSlash.empty() && (targetPathWithSlash.back() != '/' && targetPathWithSlash.back() != '\\'))
targetPathWithSlash.push_back('/');
// parse mount path
CoreinitFSParsedPath parsedMountPath;
coreinitFS_parsePath(&parsedMountPath, mountPath);
FSCPath parsedMountPath(mountPathTmp);
// register path
fscEnter();
FSCMountPathNode* node = fsc_createMountPath(&parsedMountPath, priority);
FSCMountPathNode* node = fsc_createMountPath(parsedMountPath, priority);
if( !node )
{
// 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();
return FSC_STATUS_INVALID_PATH;
}
node->device = fscDevice;
node->ctx = ctx;
node->targetPath = targetPath;
node->deviceTargetPath = targetPathWithSlash;
fscLeave();
return FSC_STATUS_OK;
}
bool fsc_unmount(const char* mountPath, sint32 priority)
bool fsc_unmount(std::string_view mountPath, sint32 priority)
{
CoreinitFSParsedPath parsedMountPath;
coreinitFS_parsePath(&parsedMountPath, mountPath);
std::string _tmp(mountPath);
fscEnter();
FSCMountPathNode* mountPathNode = fsc_lookupPathVirtualNode(mountPath, priority);
FSCMountPathNode* mountPathNode = fsc_lookupPathVirtualNode(_tmp.c_str(), priority);
if (!mountPathNode)
{
fscLeave();
@@ -185,21 +183,19 @@ void fsc_unmountAll()
}
// lookup virtual path and find mounted device and relative device directory
bool fsc_lookupPath(const char* path, std::wstring& devicePathOut, fscDeviceC** fscDeviceOut, void** ctxOut, sint32 priority = FSC_PRIORITY_BASE)
bool fsc_lookupPath(const char* path, std::string& devicePathOut, fscDeviceC** fscDeviceOut, void** ctxOut, sint32 priority = FSC_PRIORITY_BASE)
{
// parse path
CoreinitFSParsedPath parsedPath;
coreinitFS_parsePath(&parsedPath, path);
FSCPath parsedPath(path);
FSCMountPathNode* nodeParent = s_fscRootNodePerPrio[priority];
sint32 i;
size_t i;
fscEnter();
for (i = 0; i < parsedPath.numNodes; i++)
for (i = 0; i < parsedPath.GetNodeCount(); i++)
{
// search for subdirectory
FSCMountPathNode* nodeSub = nullptr;
for(auto& nodeItr : nodeParent->subnodes)
{
if (coreinitFS_checkNodeName(&parsedPath, i, nodeItr->path.c_str()))
{
if (parsedPath.MatchNodeName(i, nodeItr->path))
{
nodeSub = nodeItr;
break;
@@ -213,17 +209,17 @@ bool fsc_lookupPath(const char* path, std::wstring& devicePathOut, fscDeviceC**
// no matching subnode
break;
}
// find deepest device mount point
// if the found node is not a device mount point, then travel back towards the root until we find one
while (nodeParent)
{
if (nodeParent->device)
{
devicePathOut = nodeParent->targetPath;
for (sint32 f = i; f < parsedPath.numNodes; f++)
devicePathOut = nodeParent->deviceTargetPath;
for (size_t f = i; f < parsedPath.GetNodeCount(); f++)
{
const char* nodeName = coreinitFS_getNodeName(&parsedPath, f);
devicePathOut.append(boost::nowide::widen(nodeName));
if (f < (parsedPath.numNodes - 1))
auto nodeName = parsedPath.GetNodeName(f);
devicePathOut.append(nodeName);
if (f < (parsedPath.GetNodeCount() - 1))
devicePathOut.push_back('/');
}
*fscDeviceOut = nodeParent->device;
@@ -241,19 +237,16 @@ bool fsc_lookupPath(const char* path, std::wstring& devicePathOut, fscDeviceC**
// lookup path and find virtual device node
FSCMountPathNode* fsc_lookupPathVirtualNode(const char* path, sint32 priority)
{
// parse path
CoreinitFSParsedPath parsedPath;
coreinitFS_parsePath(&parsedPath, path);
FSCPath parsedPath(path);
FSCMountPathNode* nodeCurrentDir = s_fscRootNodePerPrio[priority];
sint32 i;
fscEnter();
for (i = 0; i < parsedPath.numNodes; i++)
for (size_t i = 0; i < parsedPath.GetNodeCount(); i++)
{
// search for subdirectory
FSCMountPathNode* nodeSub = nullptr;
for (auto& nodeItr : nodeCurrentDir->subnodes)
{
if (coreinitFS_checkNodeName(&parsedPath, i, nodeItr->path.c_str()))
if (parsedPath.MatchNodeName(i, nodeItr->path))
{
nodeSub = nodeItr;
break;
@@ -360,11 +353,9 @@ private:
FSCVirtualFile* fsc_open(const char* path, FSC_ACCESS_FLAG accessFlags, sint32* fscStatus, sint32 maxPriority)
{
cemu_assert_debug(HAS_FLAG(accessFlags, FSC_ACCESS_FLAG::OPEN_FILE) || HAS_FLAG(accessFlags, FSC_ACCESS_FLAG::OPEN_DIR)); // must open either file or directory
FSCVirtualFile* dirList[FSC_PRIORITY_COUNT];
uint8 dirListCount = 0;
std::wstring devicePath;
std::string devicePath;
fscDeviceC* fscDevice = NULL;
*fscStatus = FSC_STATUS_UNDEFINED;
void* ctx;
@@ -455,7 +446,7 @@ bool fsc_createDir(char* path, sint32* fscStatus)
fscDeviceC* fscDevice = NULL;
*fscStatus = FSC_STATUS_UNDEFINED;
void* ctx;
std::wstring devicePath;
std::string devicePath;
fscEnter();
if( fsc_lookupPath(path, devicePath, &fscDevice, &ctx) )
{
@@ -472,8 +463,8 @@ bool fsc_createDir(char* path, sint32* fscStatus)
*/
bool fsc_rename(char* srcPath, char* dstPath, sint32* fscStatus)
{
std::wstring srcDevicePath;
std::wstring dstDevicePath;
std::string srcDevicePath;
std::string dstDevicePath;
void* srcCtx;
void* dstCtx;
fscDeviceC* fscSrcDevice = NULL;
@@ -492,7 +483,7 @@ bool fsc_rename(char* srcPath, char* dstPath, sint32* fscStatus)
*/
bool fsc_remove(char* path, sint32* fscStatus)
{
std::wstring devicePath;
std::string devicePath;
fscDeviceC* fscDevice = NULL;
*fscStatus = FSC_STATUS_UNDEFINED;
void* ctx;
@@ -691,7 +682,7 @@ bool fsc_doesFileExist(const char* path, sint32 maxPriority)
return true;
}
// helper function to check if a folder exists
// helper function to check if a directory exists
bool fsc_doesDirectoryExist(const char* path, sint32 maxPriority)
{
fscDeviceC* fscDevice = nullptr;
@@ -708,93 +699,7 @@ bool fsc_doesDirectoryExist(const char* path, sint32 maxPriority)
return true;
}
void coreinitFS_parsePath(CoreinitFSParsedPath* parsedPath, const char* path)
{
// if the path starts with a '/', skip it
if (*path == '/')
path++;
// init parsedPath struct
memset(parsedPath, 0x00, sizeof(CoreinitFSParsedPath));
// init parsed path data
size_t pathLength = std::min((size_t)640, strlen(path));
memcpy(parsedPath->pathData, path, pathLength);
// start parsing
sint32 offset = 0;
sint32 startOffset = 0;
if (offset < pathLength)
{
parsedPath->nodeOffset[parsedPath->numNodes] = offset;
parsedPath->numNodes++;
}
while (offset < pathLength)
{
if (parsedPath->pathData[offset] == '/' || parsedPath->pathData[offset] == '\\')
{
parsedPath->pathData[offset] = '\0';
offset++;
// double slashes are ignored and instead are handled like a single slash
if (parsedPath->pathData[offset] == '/' || parsedPath->pathData[offset] == '\\')
{
// if we're in the beginning and having a \\ it's a network path
if (offset != 1)
{
parsedPath->pathData[offset] = '\0';
offset++;
}
}
// start new node
if (parsedPath->numNodes < FSC_PARSED_PATH_NODES_MAX)
{
if (offset < pathLength)
{
parsedPath->nodeOffset[parsedPath->numNodes] = offset;
parsedPath->numNodes++;
}
}
continue;
}
offset++;
}
// handle special nodes like '.' or '..'
sint32 nodeIndex = 0;
while (nodeIndex < parsedPath->numNodes)
{
if (coreinitFS_checkNodeName(parsedPath, nodeIndex, ".."))
cemu_assert_suspicious(); // how does Cafe OS handle .. ?
else if (coreinitFS_checkNodeName(parsedPath, nodeIndex, "."))
{
// remove this node and shift back all following nodes by 1
parsedPath->numNodes--;
for (sint32 i = nodeIndex; i < parsedPath->numNodes; i++)
{
parsedPath->nodeOffset[i] = parsedPath->nodeOffset[i + 1];
}
// continue without increasing nodeIndex
continue;
}
nodeIndex++;
}
}
bool coreinitFS_checkNodeName(CoreinitFSParsedPath* parsedPath, sint32 index, const char* name)
{
if (index < 0 || index >= parsedPath->numNodes)
return false;
char* nodeName = parsedPath->pathData + parsedPath->nodeOffset[index];
if (boost::iequals(nodeName, name))
return true;
return false;
}
char* coreinitFS_getNodeName(CoreinitFSParsedPath* parsedPath, sint32 index)
{
if (index < 0 || index >= parsedPath->numNodes)
return nullptr;
return parsedPath->pathData + parsedPath->nodeOffset[index];
}
// Initialize Cemu's virtual filesystem
// initialize Cemu's virtual filesystem
void fsc_init()
{
fsc_reset();
+9 -26
View File
@@ -57,25 +57,25 @@ struct FSCDirEntry
class fscDeviceC
{
public:
virtual FSCVirtualFile* fscDeviceOpenByPath(std::wstring_view path, FSC_ACCESS_FLAG accessFlags, void* ctx, sint32* fscStatus)
virtual FSCVirtualFile* fscDeviceOpenByPath(std::string_view path, FSC_ACCESS_FLAG accessFlags, void* ctx, sint32* fscStatus)
{
cemu_assert_unimplemented();
return nullptr;
}
virtual bool fscDeviceCreateDir(std::wstring_view path, void* ctx, sint32* fscStatus)
virtual bool fscDeviceCreateDir(std::string_view path, void* ctx, sint32* fscStatus)
{
cemu_assert_unimplemented();
return false;
}
virtual bool fscDeviceRemoveFileOrDir(std::wstring_view path, void* ctx, sint32* fscStatus)
virtual bool fscDeviceRemoveFileOrDir(std::string_view path, void* ctx, sint32* fscStatus)
{
cemu_assert_unimplemented();
return false;
}
virtual bool fscDeviceRename(std::wstring_view srcPath, std::wstring_view dstPath, void* ctx, sint32* fscStatus)
virtual bool fscDeviceRename(std::string_view srcPath, std::string_view dstPath, void* ctx, sint32* fscStatus)
{
cemu_assert_unimplemented();
return false;
@@ -161,8 +161,8 @@ struct FSCVirtualFile
#define FSC_PRIORITY_COUNT (4)
void fsc_init();
sint32 fsc_mount(const char* mountPath, const wchar_t* targetPath, fscDeviceC* fscDevice, void* ctx, sint32 priority=0);
bool fsc_unmount(const char* mountPath, sint32 priority);
sint32 fsc_mount(std::string_view mountPath, std::string_view targetPath, fscDeviceC* fscDevice, void* ctx, sint32 priority=0);
bool fsc_unmount(std::string_view mountPath, sint32 priority);
void fsc_unmountAll();
FSCVirtualFile* fsc_open(const char* path, FSC_ACCESS_FLAG accessFlags, sint32* fscStatus, sint32 maxPriority=FSC_PRIORITY_MAX);
@@ -188,32 +188,15 @@ bool fsc_doesFileExist(const char* path, sint32 maxPriority = FSC_PRIORITY_MAX);
bool fsc_doesDirectoryExist(const char* path, sint32 maxPriority = FSC_PRIORITY_MAX);
// 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
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
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
void fscDeviceRedirect_map();
void fscDeviceRedirect_add(std::string_view virtualSourcePath, const fs::path& targetFilePath, sint32 priority);
// Old path parser helper functions
// Replace with FSCPath
#define FSC_PARSED_PATH_NODES_MAX (32)
struct CoreinitFSParsedPath
{
char pathData[640 + 1];
uint16 nodeOffset[FSC_PARSED_PATH_NODES_MAX];
sint32 numNodes;
};
void coreinitFS_parsePath(CoreinitFSParsedPath* parsedPath, const char* path);
bool coreinitFS_checkNodeName(CoreinitFSParsedPath* parsedPath, sint32 index, const char* name);
char* coreinitFS_getNodeName(CoreinitFSParsedPath* parsedPath, sint32 index);
+20 -23
View File
@@ -127,7 +127,7 @@ bool FSCVirtualFile_Host::fscDirNext(FSCDirEntry* dirEntry)
m_dirIterator.reset(new fs::directory_iterator(*m_path));
if (!m_dirIterator)
{
cemuLog_force("Failed to iterate directory: {}", _utf8Wrapper(m_path->generic_u8string()));
cemuLog_force("Failed to iterate directory: {}", _pathToUtf8(*m_path));
return false;
}
}
@@ -175,14 +175,14 @@ FSCVirtualFile* FSCVirtualFile_Host::OpenFile(const fs::path& path, FSC_ACCESS_F
cemu_assert_debug(writeAccessRequested);
fs = FileStream::createFile2(path);
if (!fs)
cemuLog_force("FSC: File create failed for {}", _utf8Wrapper(path));
cemuLog_force("FSC: File create failed for {}", _pathToUtf8(path));
}
}
else if (HAS_FLAG(accessFlags, FSC_ACCESS_FLAG::FILE_ALWAYS_CREATE))
{
fs = FileStream::createFile2(path);
if (!fs)
cemuLog_force("FSC: File create failed for {}", _utf8Wrapper(path));
cemuLog_force("FSC: File create failed for {}", _pathToUtf8(path));
}
else
{
@@ -221,36 +221,36 @@ FSCVirtualFile* FSCVirtualFile_Host::OpenFile(const fs::path& path, FSC_ACCESS_F
class fscDeviceHostFSC : public fscDeviceC
{
public:
FSCVirtualFile* fscDeviceOpenByPath(std::wstring_view path, FSC_ACCESS_FLAG accessFlags, void* ctx, sint32* fscStatus) override
FSCVirtualFile* fscDeviceOpenByPath(std::string_view path, FSC_ACCESS_FLAG accessFlags, void* ctx, sint32* fscStatus) override
{
*fscStatus = FSC_STATUS_OK;
FSCVirtualFile* vf = FSCVirtualFile_Host::OpenFile(path, accessFlags, *fscStatus);
FSCVirtualFile* vf = FSCVirtualFile_Host::OpenFile(_utf8ToPath(path), accessFlags, *fscStatus);
cemu_assert_debug((bool)vf == (*fscStatus == FSC_STATUS_OK));
return vf;
}
bool fscDeviceCreateDir(std::wstring_view path, void* ctx, sint32* fscStatus) override
bool fscDeviceCreateDir(std::string_view path, void* ctx, sint32* fscStatus) override
{
fs::path dirPath(path);
if (fs::exists(path))
fs::path dirPath = _utf8ToPath(path);
if (fs::exists(dirPath))
{
if (!fs::is_directory(dirPath))
cemuLog_force("CreateDir: {} already exists but is not a directory", _utf8Wrapper(dirPath));
cemuLog_force("CreateDir: {} already exists but is not a directory", path);
*fscStatus = FSC_STATUS_ALREADY_EXISTS;
return false;
}
std::error_code ec;
bool r = fs::create_directories(dirPath, ec);
if(!r)
cemuLog_force("CreateDir: Failed to create {}", _utf8Wrapper(dirPath));
if (!r)
cemuLog_force("CreateDir: Failed to create {}", path);
*fscStatus = FSC_STATUS_OK;
return true;
}
bool fscDeviceRemoveFileOrDir(std::wstring_view path, void* ctx, sint32* fscStatus) override
bool fscDeviceRemoveFileOrDir(std::string_view path, void* ctx, sint32* fscStatus) override
{
*fscStatus = FSC_STATUS_OK;
fs::path _path(path);
fs::path _path = _utf8ToPath(path);
std::error_code ec;
if (!fs::exists(_path, ec))
{
@@ -266,11 +266,11 @@ public:
return true;
}
bool fscDeviceRename(std::wstring_view srcPath, std::wstring_view dstPath, void* ctx, sint32* fscStatus) override
bool fscDeviceRename(std::string_view srcPath, std::string_view dstPath, void* ctx, sint32* fscStatus) override
{
*fscStatus = FSC_STATUS_OK;
fs::path _srcPath(srcPath);
fs::path _dstPath(dstPath);
fs::path _srcPath = _utf8ToPath(srcPath);
fs::path _dstPath = _utf8ToPath(dstPath);
std::error_code ec;
if (!fs::exists(_srcPath, ec))
{
@@ -293,14 +293,11 @@ public:
void fscDeviceHostFS_mapBaseDirectories_deprecated()
{
const auto mlc = ActiveSettings::GetMlcPath();
fsc_mount("/cemuBossStorage/", (mlc / "usr/boss/").generic_wstring().c_str(), &fscDeviceHostFSC::instance(), NULL, FSC_PRIORITY_BASE);
fsc_mount("/vol/storage_mlc01/", (mlc / "").generic_wstring().c_str(), &fscDeviceHostFSC::instance(), NULL, FSC_PRIORITY_BASE);
fsc_mount("/cemuBossStorage/", _pathToUtf8(mlc / "usr/boss/"), &fscDeviceHostFSC::instance(), NULL, FSC_PRIORITY_BASE);
fsc_mount("/vol/storage_mlc01/", _pathToUtf8(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);
if (!hostTargetPath.empty() && (hostTargetPath.back() != '/' && hostTargetPath.back() != '\\'))
hostTargetPath.push_back('/');
return fsc_mount(mountPath, hostTargetPath.c_str(), &fscDeviceHostFSC::instance(), nullptr, priority) == FSC_STATUS_OK;
return fsc_mount(mountPath, hostTargetPath, &fscDeviceHostFSC::instance(), nullptr, priority) == FSC_STATUS_OK;
}
+7 -8
View File
@@ -9,31 +9,30 @@ struct RedirectEntry
sint32 priority;
};
FileTree<RedirectEntry, false> redirectTree;
FSAFileTree<RedirectEntry> redirectTree;
void fscDeviceRedirect_add(std::string_view virtualSourcePath, const fs::path& targetFilePath, sint32 priority)
{
std::wstring virtualSourcePathW = boost::nowide::widen(std::string(virtualSourcePath));
// check if source already has a redirection
RedirectEntry* existingEntry;
if (redirectTree.getFile(virtualSourcePathW, existingEntry))
if (redirectTree.getFile(virtualSourcePath, existingEntry))
{
if (existingEntry->priority >= priority)
return; // dont replace entries with equal or higher priority
// unregister existing entry
redirectTree.removeFile(virtualSourcePathW.c_str());
redirectTree.removeFile(virtualSourcePath);
delete existingEntry;
}
RedirectEntry* entry = new RedirectEntry(targetFilePath, priority);
redirectTree.addFile(virtualSourcePathW.c_str(), entry);
redirectTree.addFile(virtualSourcePath, entry);
}
class fscDeviceTypeRedirect : public fscDeviceC
{
FSCVirtualFile* fscDeviceOpenByPath(std::wstring_view pathW, FSC_ACCESS_FLAG accessFlags, void* ctx, sint32* fscStatus) override
FSCVirtualFile* fscDeviceOpenByPath(std::string_view path, FSC_ACCESS_FLAG accessFlags, void* ctx, sint32* fscStatus) override
{
RedirectEntry* redirectionEntry;
if (redirectTree.getFile(pathW, redirectionEntry))
if (redirectTree.getFile(path, redirectionEntry))
return FSCVirtualFile_Host::OpenFile(redirectionEntry->dstPath, accessFlags, *fscStatus);
return nullptr;
}
@@ -52,6 +51,6 @@ void fscDeviceRedirect_map()
{
if (_redirectMapped)
return;
fsc_mount("/", L"/", &fscDeviceTypeRedirect::instance(), nullptr, FSC_PRIORITY_REDIRECT);
fsc_mount("/", "/", &fscDeviceTypeRedirect::instance(), nullptr, FSC_PRIORITY_REDIRECT);
_redirectMapped = true;
}
+4 -9
View File
@@ -119,14 +119,12 @@ private:
class fscDeviceWUAC : public fscDeviceC
{
FSCVirtualFile* fscDeviceOpenByPath(std::wstring_view path, FSC_ACCESS_FLAG accessFlags, void* ctx, sint32* fscStatus) override
FSCVirtualFile* fscDeviceOpenByPath(std::string_view path, FSC_ACCESS_FLAG accessFlags, void* ctx, sint32* fscStatus) override
{
ZArchiveReader* archive = (ZArchiveReader*)ctx;
cemu_assert_debug(!HAS_FLAG(accessFlags, FSC_ACCESS_FLAG::WRITE_PERMISSION)); // writing to WUA is not supported
std::string pathU8 = boost::nowide::narrow(path.data(), path.size());
ZArchiveNodeHandle fileHandle = archive->LookUp(pathU8, true, true);
ZArchiveNodeHandle fileHandle = archive->LookUp(path, true, true);
if (fileHandle == ZARCHIVE_INVALID_NODE)
{
*fscStatus = FSC_STATUS_FILE_NOT_FOUND;
@@ -169,10 +167,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()));
if (!hostTargetPath.empty() && (hostTargetPath.back() != '/' && hostTargetPath.back() != '\\'))
hostTargetPath.push_back('/');
return fsc_mount(mountPath, hostTargetPath.c_str(), &fscDeviceWUAC::instance(), archive, priority) == FSC_STATUS_OK;
return fsc_mount(mountPath, destinationBaseDir, &fscDeviceWUAC::instance(), archive, priority) == FSC_STATUS_OK;
}
+5 -9
View File
@@ -120,16 +120,15 @@ private:
class fscDeviceWUDC : public fscDeviceC
{
FSCVirtualFile* fscDeviceOpenByPath(std::wstring_view path, FSC_ACCESS_FLAG accessFlags, void* ctx, sint32* fscStatus) override
FSCVirtualFile* fscDeviceOpenByPath(std::string_view path, FSC_ACCESS_FLAG accessFlags, void* ctx, sint32* fscStatus) override
{
FSTVolume* mountedVolume = (FSTVolume*)ctx;
cemu_assert_debug(!HAS_FLAG(accessFlags, FSC_ACCESS_FLAG::WRITE_PERMISSION)); // writing to FST is never allowed
std::string pathU8 = boost::nowide::narrow(path.data(), path.size());
if (HAS_FLAG(accessFlags, FSC_ACCESS_FLAG::OPEN_FILE))
{
FSTFileHandle fstFileHandle;
if (mountedVolume->OpenFile(pathU8, fstFileHandle, true))
if (mountedVolume->OpenFile(path, fstFileHandle, true))
{
*fscStatus = FSC_STATUS_OK;
return new FSCDeviceWudFileCtx(mountedVolume, fstFileHandle);
@@ -138,7 +137,7 @@ class fscDeviceWUDC : public fscDeviceC
if (HAS_FLAG(accessFlags, FSC_ACCESS_FLAG::OPEN_DIR))
{
FSTDirectoryIterator dirIterator;
if (mountedVolume->OpenDirectoryIterator(pathU8, dirIterator))
if (mountedVolume->OpenDirectoryIterator(path, dirIterator))
{
*fscStatus = FSC_STATUS_OK;
return new FSCDeviceWudFileCtx(mountedVolume, dirIterator);
@@ -157,10 +156,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()));
if (!hostTargetPath.empty() && (hostTargetPath.back() != '/' && hostTargetPath.back() != '\\'))
hostTargetPath.push_back('/');
return fsc_mount(mountPath, hostTargetPath.c_str(), &fscDeviceWUDC::instance(), mountedVolume, priority) == FSC_STATUS_OK;
return fsc_mount(mountPath, destinationBaseDir, &fscDeviceWUDC::instance(), mountedVolume, priority) == FSC_STATUS_OK;
}
+4 -4
View File
@@ -31,12 +31,12 @@ void GraphicPack2::LoadGraphicPack(fs::path graphicPackPath)
if (!iniParser.NextSection())
{
cemuLog_force("{}: Does not contain any sections", _utf8Wrapper(rulesPath));
cemuLog_force("{}: Does not contain any sections", _pathToUtf8(rulesPath));
return;
}
if (!boost::iequals(iniParser.GetCurrentSectionName(), "Definition"))
{
cemuLog_force("{}: [Definition] must be the first section", _utf8Wrapper(rulesPath));
cemuLog_force("{}: [Definition] must be the first section", _pathToUtf8(rulesPath));
return;
}
@@ -47,7 +47,7 @@ void GraphicPack2::LoadGraphicPack(fs::path graphicPackPath)
auto [ptr, ec] = std::from_chars(option_version->data(), option_version->data() + option_version->size(), versionNum);
if (ec != std::errc{})
{
cemuLog_force("{}: Unable to parse version", _utf8Wrapper(rulesPath));
cemuLog_force("{}: Unable to parse version", _pathToUtf8(rulesPath));
return;
}
@@ -57,7 +57,7 @@ void GraphicPack2::LoadGraphicPack(fs::path graphicPackPath)
return;
}
}
cemuLog_force("{}: Outdated graphic pack", _utf8Wrapper(rulesPath));
cemuLog_force("{}: Outdated graphic pack", _pathToUtf8(rulesPath));
}
void GraphicPack2::LoadAll()
+3 -3
View File
@@ -109,7 +109,7 @@ namespace coreinit
std::error_code ec;
const auto path = ActiveSettings::GetPath("sdcard/");
fs::create_directories(path, ec);
FSCDeviceHostFS_Mount("/vol/external01", path.generic_wstring().c_str() , FSC_PRIORITY_BASE);
FSCDeviceHostFS_Mount("/vol/external01", _pathToUtf8(path), FSC_PRIORITY_BASE);
_sdCard01Mounted = true;
}
@@ -142,7 +142,7 @@ namespace coreinit
std::error_code ec;
const auto path = ActiveSettings::GetPath("sdcard/");
fs::create_directories(path, ec);
if (!FSCDeviceHostFS_Mount(mountPathOut, path.generic_wstring().c_str(), FSC_PRIORITY_BASE))
if (!FSCDeviceHostFS_Mount(mountPathOut, _pathToUtf8(path), FSC_PRIORITY_BASE))
return FS_RESULT::ERR_PLACEHOLDER;
_sdCard01Mounted = true;
}
@@ -150,7 +150,7 @@ namespace coreinit
if (_mlc01Mounted)
return FS_RESULT::ERR_PLACEHOLDER;
if (!FSCDeviceHostFS_Mount(mountPathOut, ActiveSettings::GetMlcPath().generic_wstring().c_str(), FSC_PRIORITY_BASE))
if (!FSCDeviceHostFS_Mount(mountPathOut, _pathToUtf8(ActiveSettings::GetMlcPath()), FSC_PRIORITY_BASE))
return FS_RESULT::ERR_PLACEHOLDER;
_mlc01Mounted = true;
}
+1 -1
View File
@@ -51,7 +51,7 @@ namespace acp
// mount save path
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/", _pathToUtf8(mlc), FSC_PRIORITY_BASE);
nnResult mountResult = BUILD_NN_RESULT(NN_RESULT_LEVEL_SUCCESS, NN_RESULT_MODULE_NN_ACP, 0);
return _ACPConvertResultToACPStatus(&mountResult, "ACPMountSaveDir", 0x60);
}
+2 -2
View File
@@ -66,7 +66,7 @@ void CafeSaveList::RefreshThreadWorker()
{
if(!it_titleHigh.is_directory(ec))
continue;
std::string dirName = _utf8Wrapper(it_titleHigh.path().filename());
std::string dirName = _pathToUtf8(it_titleHigh.path().filename());
if(dirName.empty())
continue;
uint32 titleIdHigh;
@@ -78,7 +78,7 @@ void CafeSaveList::RefreshThreadWorker()
{
if (!it_titleLow.is_directory(ec))
continue;
dirName = _utf8Wrapper(it_titleLow.path().filename());
dirName = _pathToUtf8(it_titleLow.path().filename());
if (dirName.empty())
continue;
uint32 titleIdLow;
+7 -7
View File
@@ -177,12 +177,12 @@ bool TitleInfo::DetectFormat(const fs::path& path, fs::path& pathOut, TitleDataF
std::error_code ec;
if (path.has_extension() && fs::is_regular_file(path, ec))
{
std::string filenameStr = _utf8Wrapper(path.filename());
std::string filenameStr = _pathToUtf8(path.filename());
if (boost::iends_with(filenameStr, ".rpx"))
{
// is in code folder?
fs::path parentPath = path.parent_path();
if (boost::iequals(_utf8Wrapper(parentPath.filename()), "code"))
if (boost::iequals(_pathToUtf8(parentPath.filename()), "code"))
{
parentPath = parentPath.parent_path();
// next to content and meta?
@@ -370,7 +370,7 @@ bool TitleInfo::Mount(std::string_view virtualPath, std::string_view subfolder,
{
fs::path hostFSPath = m_fullPath;
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(), _pathToUtf8(hostFSPath), mountPriority);
cemu_assert_debug(r);
if (!r)
{
@@ -387,7 +387,7 @@ bool TitleInfo::Mount(std::string_view virtualPath, std::string_view subfolder,
}
if (!m_wudVolume)
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);
if (!r)
{
@@ -404,7 +404,7 @@ bool TitleInfo::Mount(std::string_view virtualPath, std::string_view subfolder,
if (!m_zarchive)
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)
{
cemuLog_log(LogType::Force, "Failed to mount {} to {}", virtualPath, subfolder);
@@ -495,7 +495,7 @@ bool TitleInfo::ParseXmlInfo()
if (!m_parsedMetaXml || !m_parsedAppXml || !m_parsedCosXml)
{
if (hasAnyXml)
cemuLog_log(LogType::Force, "Title has missing meta .xml files. Title path: {}", _utf8Wrapper(m_fullPath));
cemuLog_log(LogType::Force, "Title has missing meta .xml files. Title path: {}", _pathToUtf8(m_fullPath));
delete m_parsedMetaXml;
delete m_parsedAppXml;
delete m_parsedCosXml;
@@ -621,7 +621,7 @@ std::string TitleInfo::GetPrintPath() const
if (!m_isValid)
return "invalid";
std::string tmp;
tmp.append(_utf8Wrapper(m_fullPath));
tmp.append(_pathToUtf8(m_fullPath));
switch (m_titleFormat)
{
case TitleDataFormat::HOST_FS:
+13 -13
View File
@@ -79,7 +79,7 @@ void CafeTitleList::LoadCacheFile()
cacheEntry.titleDataFormat = format;
cacheEntry.region = region;
cacheEntry.titleName = name;
cacheEntry.path = _asUtf8(path);
cacheEntry.path = _utf8ToPath(path);
cacheEntry.subPath = sub_path;
cacheEntry.group_id = group_id;
cacheEntry.app_type = app_type;
@@ -120,16 +120,16 @@ void CafeTitleList::StoreCacheFile()
titleInfoNode.append_child("region").append_child(pugi::node_pcdata).set_value(fmt::format("{}", (uint32)info.region).c_str());
titleInfoNode.append_child("name").append_child(pugi::node_pcdata).set_value(info.titleName.c_str());
titleInfoNode.append_child("format").append_child(pugi::node_pcdata).set_value(fmt::format("{}", (uint32)info.titleDataFormat).c_str());
titleInfoNode.append_child("path").append_child(pugi::node_pcdata).set_value(_utf8Wrapper(info.path).c_str());
titleInfoNode.append_child("path").append_child(pugi::node_pcdata).set_value(_pathToUtf8(info.path).c_str());
if(!info.subPath.empty())
titleInfoNode.append_child("sub_path").append_child(pugi::node_pcdata).set_value(_utf8Wrapper(info.subPath).c_str());
titleInfoNode.append_child("sub_path").append_child(pugi::node_pcdata).set_value(_pathToUtf8(info.subPath).c_str());
}
fs::path tmpPath = fs::path(sTLCacheFilePath.parent_path()).append(fmt::format("{}__tmp", _utf8Wrapper(sTLCacheFilePath.filename())));
fs::path tmpPath = fs::path(sTLCacheFilePath.parent_path()).append(fmt::format("{}__tmp", _pathToUtf8(sTLCacheFilePath.filename())));
std::ofstream fileOut(tmpPath, std::ios::out | std::ios::binary | std::ios::trunc);
if (!fileOut.is_open())
{
cemuLog_log(LogType::Force, "Unable to store title list in {}", _utf8Wrapper(tmpPath));
cemuLog_log(LogType::Force, "Unable to store title list in {}", _pathToUtf8(tmpPath));
return;
}
doc.save(fileOut, " ", 1, pugi::xml_encoding::encoding_utf8);
@@ -158,7 +158,7 @@ void CafeTitleList::SetMLCPath(fs::path path)
std::error_code ec;
if (!fs::is_directory(path, ec))
{
cemuLog_log(LogType::Force, "MLC set to invalid path: {}", _utf8Wrapper(path));
cemuLog_log(LogType::Force, "MLC set to invalid path: {}", _pathToUtf8(path));
return;
}
sTLMLCPath = path;
@@ -211,12 +211,12 @@ void _RemoveTitleFromMultimap(TitleInfo* titleInfo)
// in the special case that path points to a WUA file, all contained titles will be added
void CafeTitleList::AddTitleFromPath(fs::path path)
{
if (path.has_extension() && boost::iequals(_utf8Wrapper(path.extension()), ".wua"))
if (path.has_extension() && boost::iequals(_pathToUtf8(path.extension()), ".wua"))
{
ZArchiveReader* zar = ZArchiveReader::OpenFromFile(path);
if (!zar)
{
cemuLog_log(LogType::Force, "Found {} but it is not a valid Wii U archive file", _utf8Wrapper(path));
cemuLog_log(LogType::Force, "Found {} but it is not a valid Wii U archive file", _pathToUtf8(path));
return;
}
// enumerate all contained titles
@@ -233,7 +233,7 @@ void CafeTitleList::AddTitleFromPath(fs::path path)
uint16 parsedVersion;
if (!TitleInfo::ParseWuaTitleFolderName(dirEntry.name, parsedId, parsedVersion))
{
cemuLog_log(LogType::Force, "Invalid title directory in {}: \"{}\"", _utf8Wrapper(path), dirEntry.name);
cemuLog_log(LogType::Force, "Invalid title directory in {}: \"{}\"", _pathToUtf8(path), dirEntry.name);
continue;
}
// valid subdirectory
@@ -351,7 +351,7 @@ void CafeTitleList::ScanGamePath(const fs::path& path)
{
dirsInDirectory.emplace_back(it.path());
std::string dirName = _utf8Wrapper(it.path().filename());
std::string dirName = _pathToUtf8(it.path().filename());
if (boost::iequals(dirName, "content"))
hasContentFolder = true;
else if (boost::iequals(dirName, "code"))
@@ -366,7 +366,7 @@ void CafeTitleList::ScanGamePath(const fs::path& path)
// since checking files is slow, we only do it for known file extensions
if (!it.has_extension())
continue;
if (!_IsKnownFileExtension(_utf8Wrapper(it.extension())))
if (!_IsKnownFileExtension(_pathToUtf8(it.extension())))
continue;
AddTitleFromPath(it);
}
@@ -384,7 +384,7 @@ void CafeTitleList::ScanGamePath(const fs::path& path)
{
for (auto& it : dirsInDirectory)
{
std::string dirName = _utf8Wrapper(it.filename());
std::string dirName = _pathToUtf8(it.filename());
if (!boost::iequals(dirName, "content") &&
!boost::iequals(dirName, "code") &&
!boost::iequals(dirName, "meta"))
@@ -408,7 +408,7 @@ void CafeTitleList::ScanMLCPath(const fs::path& path)
if (!it.is_directory())
continue;
// only scan directories which match the title id naming scheme
std::string dirName = _utf8Wrapper(it.path().filename());
std::string dirName = _pathToUtf8(it.path().filename());
if(dirName.size() != 8)
continue;
bool containsNoHexCharacter = false;
+8 -14
View File
@@ -420,25 +420,19 @@ inline std::string_view _utf8Wrapper(std::u8string_view input)
return v;
}
// returns a std::u8string as std::string, the contents are left as-is
inline std::string _utf8Wrapper(const std::u8string& u8str)
// convert fs::path to utf8 encoded string
inline std::string _pathToUtf8(const fs::path& path)
{
std::string v;
v.resize(u8str.size());
memcpy(v.data(), u8str.data(), u8str.size());
std::u8string strU8 = path.generic_u8string();
std::string v((const char*)strU8.data(), strU8.size());
return v;
}
// get utf8 generic path string directly from std::filesystem::path
inline std::string _utf8Wrapper(const fs::path& path)
// convert utf8 encoded string to fs::path
inline fs::path _utf8ToPath(std::string_view input)
{
return _utf8Wrapper(path.generic_u8string());
}
inline std::u8string_view _asUtf8(std::string_view input)
{
std::basic_string_view<char8_t> v((char8_t*)input.data(), input.size());
return v;
std::basic_string_view<char8_t> v((char8_t*)input.data(), input.size());
return fs::path(v);
}
class RunAtCemuBoot // -> replaces this with direct function calls. Linkers other than MSVC may optimize way object files entirely if they are not referenced from outside. So a source file self-registering using this would be causing issues
+1 -1
View File
@@ -47,7 +47,7 @@ public:
{
cemu_assert_debug(format.empty() || (format[0] != '/' && format[0] != '\\'));
auto tmp = fmt::format(fmt::runtime(format), std::forward<TArgs>(args)...);
return GetMlcPath() / fs::path(_asUtf8(tmp));
return GetMlcPath() / _utf8ToPath(tmp);
}
template <typename ...TArgs>
+1 -1
View File
@@ -417,7 +417,7 @@ void CemuConfig::Save(XMLConfigParser& parser)
for (const auto& game : graphic_pack_entries)
{
auto entry = graphic_pack_parser.set("Entry");
entry.set_attribute("filename",_utf8Wrapper(game.first).c_str());
entry.set_attribute("filename",_pathToUtf8(game.first).c_str());
for(const auto& kv : game.second)
{
// TODO: less hacky pls
+1 -1
View File
@@ -251,7 +251,7 @@ void GameUpdateWindow::ThreadWork()
error_msg << GetSystemErrorMessage(ex);
if(currentDirEntry != fs::directory_entry{})
error_msg << fmt::format("\n{}\n{}",_("Current file:").ToStdString(), _utf8Wrapper(currentDirEntry.path()));
error_msg << fmt::format("\n{}\n{}",_("Current file:").ToStdString(), _pathToUtf8(currentDirEntry.path()));
m_thread_exception = error_msg.str();
m_thread_state = ThreadCanceled;
+1 -1
View File
@@ -1947,7 +1947,7 @@ public:
"/*****************************************************************************/\r\n"
);
delete fs;
wxLaunchDefaultBrowser(wxHelper::FromUtf8(fmt::format("file:{}", _utf8Wrapper(tempPath))));
wxLaunchDefaultBrowser(wxHelper::FromUtf8(fmt::format("file:{}", _pathToUtf8(tempPath))));
});
lineSizer->Add(noticeLink, 0);
lineSizer->Add(new wxStaticText(parent, -1, ")"), 0);
+1 -1
View File
@@ -275,7 +275,7 @@ void MemorySearcherTool::Load()
if (!memSearcherIniContents)
return;
IniParser iniParser(*memSearcherIniContents, _utf8Wrapper(memorySearcherPath));
IniParser iniParser(*memSearcherIniContents, _pathToUtf8(memorySearcherPath));
while (iniParser.NextSection())
{
auto option_description = iniParser.FindOption("description");

Some files were not shown because too many files have changed in this diff Show More