diff --git a/Common/File/Path.cpp b/Common/File/Path.cpp index 7324118068..d0bda53328 100644 --- a/Common/File/Path.cpp +++ b/Common/File/Path.cpp @@ -307,6 +307,17 @@ Path Path::GetRootVolume() const { std::string path = path_.substr(0, 2); return Path(path); } + // Support UNC and device paths. + if (path_[0] == '/' && path_[1] == '/') { + size_t next = 2; + if ((path_[2] == '.' || path_[2] == '?') && path_[3] == '/') { + // Device path, or "\\.\UNC" path, skip the dot and consider the device the root. + next = 4; + } + + size_t len = path_.find_first_of('/', next); + return Path(path_.substr(0, len)); + } #endif return Path("/"); } diff --git a/Core/System.cpp b/Core/System.cpp index e3952524d6..859ca3f6b7 100644 --- a/Core/System.cpp +++ b/Core/System.cpp @@ -731,6 +731,7 @@ void InitSysDirectories() { File::CreateDir(GetSysDirectory(DIRECTORY_GAME)); File::CreateDir(GetSysDirectory(DIRECTORY_SAVEDATA)); File::CreateDir(GetSysDirectory(DIRECTORY_SAVESTATE)); + File::CreateDir(GetSysDirectory(DIRECTORY_SYSTEM)); if (g_Config.currentDirectory.empty()) { g_Config.currentDirectory = GetSysDirectory(DIRECTORY_GAME); diff --git a/unittest/UnitTest.cpp b/unittest/UnitTest.cpp index fba781084b..ec5a92a845 100644 --- a/unittest/UnitTest.cpp +++ b/unittest/UnitTest.cpp @@ -608,6 +608,10 @@ static bool TestPath() { EXPECT_EQ_STR(Path("C:\\Yo").GetFilename(), std::string("Yo")); EXPECT_EQ_STR(Path("C:\\Yo\\Lo").GetDirectory(), std::string("C:/Yo")); EXPECT_EQ_STR(Path("C:\\Yo\\Lo").GetFilename(), std::string("Lo")); + + EXPECT_EQ_STR(Path(R"(\\host\share\filename)").GetRootVolume().ToString(), std::string("//host")); + EXPECT_EQ_STR(Path(R"(\\?\UNC\share\filename)").GetRootVolume().ToString(), std::string("//?/UNC")); + EXPECT_EQ_STR(Path(R"(\\?\C:\share\filename)").GetRootVolume().ToString(), std::string("//?/C:")); #endif std::string computedPath;