From 469352e72aaac8015e543564101a849324352d83 Mon Sep 17 00:00:00 2001 From: Anthony Date: Thu, 7 Apr 2022 03:39:26 +1200 Subject: [PATCH 1/2] Better support for UNC paths Fix launching demos when the title was loaded from a UNC path e.g. MechAssault with quantum redshift demo We use GetFinalPathNameByHandle, which returns a "root local device" path beginning with '\\?\' For UNC paths, this looks like '\\?\UNC\bla' - but this path was not handled correctly. Before, '\\?\' was immediately stripped from the beginning of the path, resulting in an invalid relative path e.g 'UNC\bla' - causing errors. Now, we don't strip anything from the path, and accept it as-is. In some related code, we also need to use the '\' character instead of '/' since '/' is not the path separator on Windows and is not valid to add to a path beginning with '\\?\'. Info about paths windows paths https://googleprojectzero.blogspot.com/2016/02/the-definitive-guide-on-win32-to-nt.html --- src/core/kernel/init/CxbxKrnl.cpp | 4 ++-- src/core/kernel/support/EmuFile.cpp | 5 ----- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/core/kernel/init/CxbxKrnl.cpp b/src/core/kernel/init/CxbxKrnl.cpp index e50b22f43..2ccb83883 100644 --- a/src/core/kernel/init/CxbxKrnl.cpp +++ b/src/core/kernel/init/CxbxKrnl.cpp @@ -613,7 +613,7 @@ static bool CxbxrKrnlXbeSystemSelector(int BootFlags, unsigned& reserved_systems // Get title path : std::string xbePath; cli_config::GetValue(cli_config::load, &xbePath); - xbePath = std::filesystem::absolute(std::filesystem::path(xbePath)).string(); + xbePath = std::filesystem::absolute(xbePath).string(); // NOTE: This is a safety to clean the file path for any malicious file path attempt. // Might want to move this into a utility function. @@ -630,7 +630,7 @@ static bool CxbxrKrnlXbeSystemSelector(int BootFlags, unsigned& reserved_systems // Once clean up process is done, proceed set to global variable string. strncpy(szFilePath_Xbe, xbePath.c_str(), xbox::max_path - 1); - std::replace(xbePath.begin(), xbePath.end(), ';', '/'); + std::replace(xbePath.begin(), xbePath.end(), ';', '\\'); // Load Xbe (this one will reside above WinMain's virtual_memory_placeholder) std::filesystem::path xbeDirectory = std::filesystem::path(xbePath).parent_path(); diff --git a/src/core/kernel/support/EmuFile.cpp b/src/core/kernel/support/EmuFile.cpp index 87523d37a..4bab36358 100644 --- a/src/core/kernel/support/EmuFile.cpp +++ b/src/core/kernel/support/EmuFile.cpp @@ -799,11 +799,6 @@ std::string CxbxConvertXboxToHostPath(const std::string_view XboxDevicePath) char directoryPathBuffer[MAX_PATH]; GetFinalPathNameByHandle(rootDirectoryHandle, directoryPathBuffer, MAX_PATH, VOLUME_NAME_DOS); XbePath = directoryPathBuffer + std::string("\\") + XbePath; - - // Trim \\?\ from the output string, as we want the raw DOS path, not NT path - // We can do this always because GetFinalPathNameByHandle ALWAYS returns this format - // Without exception - XbePath.erase(0, 4); } return XbePath; From 2a3656bf24a1b4472cf3842dc1f7d2125f3c68f4 Mon Sep 17 00:00:00 2001 From: Anthony Date: Mon, 11 Apr 2022 20:24:39 +1200 Subject: [PATCH 2/2] Some comments on the "mount point" --- src/core/kernel/init/CxbxKrnl.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/core/kernel/init/CxbxKrnl.cpp b/src/core/kernel/init/CxbxKrnl.cpp index 2ccb83883..ee3b485ca 100644 --- a/src/core/kernel/init/CxbxKrnl.cpp +++ b/src/core/kernel/init/CxbxKrnl.cpp @@ -100,7 +100,11 @@ Xbe::Certificate *g_pCertificate = NULL; char szFilePath_CxbxReloaded_Exe[MAX_PATH] = { 0 }; std::string g_DataFilePath; char szFilePath_EEPROM_bin[MAX_PATH] = { 0 }; -char szFilePath_Xbe[xbox::max_path*2] = { 0 }; // NOTE: LAUNCH_DATA_HEADER's szLaunchPath is xbox::max_path*2 = 520 +// Hybrid host/xbox path to the xbe. +// A semicolon in the path indicates the Xbox mount point. +// Replacing the ';' with '\' gives a regular host path. +// NOTE: LAUNCH_DATA_HEADER's szLaunchPath is xbox::max_path*2 = 520 +char szFilePath_Xbe[xbox::max_path*2] = { 0 }; Xbe* CxbxKrnl_Xbe = NULL; bool g_bIsChihiro = false; @@ -630,6 +634,7 @@ static bool CxbxrKrnlXbeSystemSelector(int BootFlags, unsigned& reserved_systems // Once clean up process is done, proceed set to global variable string. strncpy(szFilePath_Xbe, xbePath.c_str(), xbox::max_path - 1); + // Convert to host path by replacing special mount point character if present std::replace(xbePath.begin(), xbePath.end(), ';', '\\'); // Load Xbe (this one will reside above WinMain's virtual_memory_placeholder) std::filesystem::path xbeDirectory = std::filesystem::path(xbePath).parent_path();