From 3d4ec0e043e9a683257757d3e84bec6798ff210d Mon Sep 17 00:00:00 2001
From: Andrei Karas <akaras@inbox.ru>
Date: Mon, 15 May 2017 20:10:42 +0300
Subject: Add subdir parameter into mountDir functions.

---
 src/fs/virtfs/direntry.cpp        |   2 +
 src/fs/virtfs/direntry.h          |   5 +-
 src/fs/virtfs/fs.cpp              | 121 +++++++++++++++++++---
 src/fs/virtfs/fs.h                |  29 ++++--
 src/fs/virtfs/fsentry.cpp         |   1 +
 src/fs/virtfs/fsentry.h           |   2 +
 src/fs/virtfs/virtfs1_unittest.cc | 207 ++++++++++++++++++++++----------------
 src/fs/virtfs/zip_unittest.cc     |   8 ++
 src/fs/virtfs/zipentry.cpp        |   2 +
 src/fs/virtfs/zipentry.h          |   1 +
 10 files changed, 268 insertions(+), 110 deletions(-)

(limited to 'src')

diff --git a/src/fs/virtfs/direntry.cpp b/src/fs/virtfs/direntry.cpp
index 2e82182ce..1ce81b97b 100644
--- a/src/fs/virtfs/direntry.cpp
+++ b/src/fs/virtfs/direntry.cpp
@@ -27,11 +27,13 @@ namespace VirtFs
 
 DirEntry::DirEntry(const std::string &userDir0,
                    const std::string &rootDir,
+                   const std::string &subDir0,
                    FsFuncs *restrict const funcs0) :
     FsEntry(FsEntryType::Dir, funcs0),
     userDir(userDir0)
 {
     root = rootDir;
+    subDir = subDir0;
 }
 
 DirEntry::~DirEntry()
diff --git a/src/fs/virtfs/direntry.h b/src/fs/virtfs/direntry.h
index faa33be47..93ee09166 100644
--- a/src/fs/virtfs/direntry.h
+++ b/src/fs/virtfs/direntry.h
@@ -30,9 +30,10 @@ namespace VirtFs
 
 struct DirEntry final : public FsEntry
 {
-    DirEntry(const std::string &userDir,
+    DirEntry(const std::string &userDir0,
              const std::string &rootDir,
-             FsFuncs *restrict const funcs);
+             const std::string &subDir0,
+             FsFuncs *restrict const funcs0);
 
     A_DELETE_COPY(DirEntry)
 
diff --git a/src/fs/virtfs/fs.cpp b/src/fs/virtfs/fs.cpp
index 4b0170788..73cc04c02 100644
--- a/src/fs/virtfs/fs.cpp
+++ b/src/fs/virtfs/fs.cpp
@@ -88,18 +88,23 @@ namespace VirtFs
         return mEntries;
     }
 
-    FsEntry *searchEntryByRootInternal(const std::string &restrict root)
+    FsEntry *searchByRootInternal(const std::string &restrict root,
+                                  const std::string &restrict subDir)
     {
         FOR_EACH (std::vector<FsEntry*>::const_iterator, it, mEntries)
         {
-            if ((*it)->root == root)
+            const FsEntry *const entry = *it;
+            if (entry->root == root &&
+                entry->subDir == subDir)
+            {
                 return *it;
+            }
         }
         return nullptr;
     }
 
-    FsEntry *searchEntryInternal(const std::string &restrict root,
-                                 const FsEntryTypeT type)
+    FsEntry *searchByTypeInternal(const std::string &restrict root,
+                                  const FsEntryTypeT type)
     {
         FOR_EACH (std::vector<FsEntry*>::const_iterator, it, mEntries)
         {
@@ -335,6 +340,7 @@ namespace VirtFs
     }
 
     bool mountDirInternal(const std::string &restrict newDir,
+                          const std::string &restrict subDir,
                           const Append append)
     {
         if (newDir.find(".zip") != std::string::npos)
@@ -345,7 +351,7 @@ namespace VirtFs
         std::string rootDir = newDir;
         if (findLast(rootDir, std::string(dirSeparator)) == false)
             rootDir += dirSeparator;
-        const FsEntry *const entry = searchEntryByRootInternal(rootDir);
+        const FsEntry *const entry = searchByRootInternal(rootDir, subDir);
         if (entry != nullptr)
         {
             reportAlways("VirtFs::mount already exists: %s",
@@ -353,7 +359,7 @@ namespace VirtFs
             return false;
         }
         logger->log("Add virtual directory: " + newDir);
-        addEntry(new DirEntry(newDir, rootDir, FsDir::getFuncs()),
+        addEntry(new DirEntry(newDir, rootDir, subDir, FsDir::getFuncs()),
             append);
         return true;
     }
@@ -368,7 +374,22 @@ namespace VirtFs
                 newDir.c_str());
             return false;
         }
-        return mountDirInternal(newDir, append);
+        return mountDirInternal(newDir, dirSeparator, append);
+    }
+
+    bool mountDir2(std::string newDir,
+                   std::string subDir,
+                   const Append append)
+    {
+        prepareFsPath(newDir);
+        prepareFsPath(subDir);
+        if (Files::existsLocal(newDir) == false)
+        {
+            reportNonTests("VirtFs::mount directory not exists: %s",
+                newDir.c_str());
+            return false;
+        }
+        return mountDirInternal(newDir, subDir, append);
     }
 
     bool mountDirSilent(std::string newDir,
@@ -381,24 +402,54 @@ namespace VirtFs
                 newDir.c_str());
             return false;
         }
-        return mountDirInternal(newDir, append);
+        return mountDirInternal(newDir, dirSeparator, append);
     }
 
-#ifdef UNITTESTS
     bool mountDirSilent2(std::string newDir,
+                         std::string subDir,
                          const Append append)
     {
         prepareFsPath(newDir);
+        prepareFsPath(subDir);
         if (Files::existsLocal(newDir) == false)
         {
             logger->log("VirtFs::mount directory not exists: %s",
                 newDir.c_str());
+            return false;
         }
-        return mountDirInternal(newDir, append);
+        return mountDirInternal(newDir, subDir, append);
+    }
+
+#ifdef UNITTESTS
+    bool mountDirSilentTest(std::string newDir,
+                            const Append append)
+    {
+        prepareFsPath(newDir);
+        if (Files::existsLocal(newDir) == false)
+        {
+            logger->log("VirtFs::mount directory not exists: %s",
+                newDir.c_str());
+        }
+        return mountDirInternal(newDir, dirSeparator,append);
+    }
+
+    bool mountDirSilentTest2(std::string newDir,
+                             std::string subDir,
+                             const Append append)
+    {
+        prepareFsPath(newDir);
+        prepareFsPath(subDir);
+        if (Files::existsLocal(newDir) == false)
+        {
+            logger->log("VirtFs::mount directory not exists: %s",
+                newDir.c_str());
+        }
+        return mountDirInternal(newDir, subDir, append);
     }
 #endif  // UNITTESTS
 
-    bool unmountDirInternal(std::string oldDir)
+    bool unmountDirInternal(std::string oldDir,
+                            const std::string &restrict subDir)
     {
         if (findLast(oldDir, std::string(dirSeparator)) == false)
             oldDir += dirSeparator;
@@ -406,7 +457,8 @@ namespace VirtFs
         {
             FsEntry *const entry = *it;
             if (entry->root == oldDir &&
-                entry->type == FsEntryType::Dir)
+                entry->type == FsEntryType::Dir &&
+                entry->subDir == subDir)
             {
                 DirEntry *const dirEntry = static_cast<DirEntry*>(
                     entry);
@@ -427,7 +479,26 @@ namespace VirtFs
             reportAlways("Called unmount with zip archive");
             return false;
         }
-        if (unmountDirInternal(oldDir) == false)
+        if (unmountDirInternal(oldDir, dirSeparator) == false)
+        {
+            reportAlways("VirtFs::unmountDir not exists: %s",
+                oldDir.c_str());
+            return false;
+        }
+        return true;
+    }
+
+    bool unmountDir2(std::string oldDir,
+                     std::string subDir)
+    {
+        prepareFsPath(oldDir);
+        if (oldDir.find(".zip") != std::string::npos)
+        {
+            reportAlways("Called unmount with zip archive");
+            return false;
+        }
+        prepareFsPath(subDir);
+        if (unmountDirInternal(oldDir, subDir) == false)
         {
             reportAlways("VirtFs::unmountDir not exists: %s",
                 oldDir.c_str());
@@ -444,7 +515,26 @@ namespace VirtFs
             reportAlways("Called unmount with zip archive");
             return false;
         }
-        if (unmountDirInternal(oldDir) == false)
+        if (unmountDirInternal(oldDir, dirSeparator) == false)
+        {
+            logger->log("VirtFs::unmountDir not exists: %s",
+                oldDir.c_str());
+            return false;
+        }
+        return true;
+    }
+
+    bool unmountDirSilent2(std::string oldDir,
+                           std::string subDir)
+    {
+        prepareFsPath(oldDir);
+        if (oldDir.find(".zip") != std::string::npos)
+        {
+            reportAlways("Called unmount with zip archive");
+            return false;
+        }
+        prepareFsPath(subDir);
+        if (unmountDirInternal(oldDir, subDir) == false)
         {
             logger->log("VirtFs::unmountDir not exists: %s",
                 oldDir.c_str());
@@ -469,13 +559,14 @@ namespace VirtFs
                 "zip archive");
             return false;
         }
-        if (searchEntryByRootInternal(newDir) != nullptr)
+        if (searchByRootInternal(newDir, dirSeparator) != nullptr)
         {
             reportAlways("FsZip::mount already exists: %s",
                 newDir.c_str());
             return false;
         }
         ZipEntry *const entry = new ZipEntry(newDir,
+            dirSeparator,
             FsZip::getFuncs());
         if (ZipReader::readArchiveInfo(entry) == false)
         {
diff --git a/src/fs/virtfs/fs.h b/src/fs/virtfs/fs.h
index a6b787d6e..f8950723d 100644
--- a/src/fs/virtfs/fs.h
+++ b/src/fs/virtfs/fs.h
@@ -51,10 +51,20 @@ namespace VirtFs
     bool setWriteDir(const std::string &restrict newDir);
     bool mountDir(std::string newDir,
                   const Append append);
+    bool mountDir2(std::string newDir,
+                   std::string subDir,
+                   const Append append);
     bool mountDirSilent(std::string newDir,
                         const Append append);
+    bool mountDirSilent2(std::string newDir,
+                         std::string subDir,
+                         const Append append);
     bool unmountDir(std::string oldDir);
+    bool unmountDir2(std::string oldDir,
+                     std::string subDir);
     bool unmountDirSilent(std::string oldDir);
+    bool unmountDirSilent2(std::string oldDir,
+                           std::string subDir);
     bool mountZip(std::string newDir,
                   const Append append);
     bool unmountZip(std::string oldDir);
@@ -79,18 +89,23 @@ namespace VirtFs
     int eof(File *restrict const file);
 
     bool mountDirInternal(const std::string &restrict newDir,
+                          const std::string &restrict subDir,
                           const Append append);
-    bool unmountDirInternal(std::string oldDir);
+    bool unmountDirInternal(std::string oldDir,
+                            const std::string &restrict subDir);
     std::vector<FsEntry*> &getEntries();
-    FsEntry *searchEntryByRootInternal(const std::string &restrict
-                                       root);
-    FsEntry *searchEntryInternal(const std::string &restrict root,
-                                 const FsEntryTypeT type);
+    FsEntry *searchByRootInternal(const std::string &restrict root,
+                                  const std::string &restrict subDir);
+    FsEntry *searchByTypeInternal(const std::string &restrict root,
+                                  const FsEntryTypeT type);
     void addEntry(FsEntry *const entry,
                   const Append append);
 #ifdef UNITTESTS
-    bool mountDirSilent2(std::string newDir,
-                         const Append append);
+    bool mountDirSilentTest(std::string newDir,
+                            const Append append);
+    bool mountDirSilentTest2(std::string newDir,
+                             std::string subDir,
+                             const Append append);
 #endif  // UNITTESTS
     const char *loadFile(std::string filename,
                          int &restrict fileSize);
diff --git a/src/fs/virtfs/fsentry.cpp b/src/fs/virtfs/fsentry.cpp
index b1e9ebdc3..7078fdbc4 100644
--- a/src/fs/virtfs/fsentry.cpp
+++ b/src/fs/virtfs/fsentry.cpp
@@ -28,6 +28,7 @@ namespace VirtFs
 FsEntry::FsEntry(const FsEntryTypeT &type0,
                  FsFuncs *restrict const funcs0) :
     root(),
+    subDir(),
     type(type0),
     funcs(funcs0)
 {
diff --git a/src/fs/virtfs/fsentry.h b/src/fs/virtfs/fsentry.h
index 9f6baa239..81568adb7 100644
--- a/src/fs/virtfs/fsentry.h
+++ b/src/fs/virtfs/fsentry.h
@@ -43,6 +43,8 @@ struct FsEntry notfinal
 
     std::string root;
 
+    std::string subDir;
+
     FsEntryTypeT type;
 
     FsFuncs *funcs;
diff --git a/src/fs/virtfs/virtfs1_unittest.cc b/src/fs/virtfs/virtfs1_unittest.cc
index 8a219e3ce..397873d6f 100644
--- a/src/fs/virtfs/virtfs1_unittest.cc
+++ b/src/fs/virtfs/virtfs1_unittest.cc
@@ -39,7 +39,7 @@ TEST_CASE("VirtFs1 getEntries")
 {
     VirtFs::init(".");
     REQUIRE(VirtFs::getEntries().empty());
-    REQUIRE(VirtFs::searchEntryByRootInternal("test") == nullptr);
+    REQUIRE(VirtFs::searchByRootInternal("test", dirSeparator) == nullptr);
     VirtFs::deinit();
 }
 
@@ -57,10 +57,12 @@ TEST_CASE("VirtFs1 mountDir")
     const std::string sep = dirSeparator;
     SECTION("simple 1")
     {
-        REQUIRE(VirtFs::mountDirSilent2("dir1",
+        REQUIRE(VirtFs::mountDirSilentTest("dir1",
             Append_false));
-        REQUIRE(VirtFs::searchEntryByRootInternal("dir1" + sep) != nullptr);
-        REQUIRE(VirtFs::searchEntryByRootInternal("test" + sep) == nullptr);
+        REQUIRE(VirtFs::searchByRootInternal("dir1" + sep, dirSeparator) !=
+            nullptr);
+        REQUIRE(VirtFs::searchByRootInternal("test" + sep, dirSeparator) ==
+            nullptr);
         REQUIRE(VirtFs::getEntries().size() == 1);
         REQUIRE(VirtFs::getEntries()[0]->root == "dir1" + sep);
         REQUIRE(VirtFs::getEntries()[0]->type == FsEntryType::Dir);
@@ -70,10 +72,12 @@ TEST_CASE("VirtFs1 mountDir")
 
     SECTION("simple 2")
     {
-        REQUIRE(VirtFs::mountDirSilent2("dir1/",
+        REQUIRE(VirtFs::mountDirSilentTest("dir1/",
             Append_true));
-        REQUIRE(VirtFs::searchEntryByRootInternal("dir1" + sep) != nullptr);
-        REQUIRE(VirtFs::searchEntryByRootInternal("test" + sep) == nullptr);
+        REQUIRE(VirtFs::searchByRootInternal("dir1" + sep, dirSeparator) !=
+            nullptr);
+        REQUIRE(VirtFs::searchByRootInternal("test" + sep, dirSeparator) ==
+            nullptr);
         REQUIRE(VirtFs::getEntries().size() == 1);
         REQUIRE(VirtFs::getEntries()[0]->root == "dir1" + sep);
         REQUIRE(VirtFs::getEntries()[0]->type == FsEntryType::Dir);
@@ -83,13 +87,16 @@ TEST_CASE("VirtFs1 mountDir")
 
     SECTION("simple 3")
     {
-        REQUIRE(VirtFs::mountDirSilent2("dir1",
+        REQUIRE(VirtFs::mountDirSilentTest("dir1",
             Append_false));
-        REQUIRE(VirtFs::mountDirSilent2("dir2",
+        REQUIRE(VirtFs::mountDirSilentTest("dir2",
             Append_false));
-        REQUIRE(VirtFs::searchEntryByRootInternal("dir1" + sep) != nullptr);
-        REQUIRE(VirtFs::searchEntryByRootInternal("dir2" + sep) != nullptr);
-        REQUIRE(VirtFs::searchEntryByRootInternal("test" + sep) == nullptr);
+        REQUIRE(VirtFs::searchByRootInternal("dir1" + sep, dirSeparator) !=
+            nullptr);
+        REQUIRE(VirtFs::searchByRootInternal("dir2" + sep, dirSeparator) !=
+            nullptr);
+        REQUIRE(VirtFs::searchByRootInternal("test" + sep, dirSeparator) ==
+            nullptr);
         REQUIRE(VirtFs::getEntries().size() == 2);
         REQUIRE(VirtFs::getEntries()[0]->root == "dir2" + sep);
         REQUIRE(VirtFs::getEntries()[1]->root == "dir1" + sep);
@@ -103,13 +110,16 @@ TEST_CASE("VirtFs1 mountDir")
 
     SECTION("simple 4")
     {
-        REQUIRE(VirtFs::mountDirSilent2("dir1\\",
+        REQUIRE(VirtFs::mountDirSilentTest("dir1\\",
             Append_true));
-        REQUIRE(VirtFs::mountDirSilent2("dir2",
+        REQUIRE(VirtFs::mountDirSilentTest("dir2",
             Append_true));
-        REQUIRE(VirtFs::searchEntryByRootInternal("dir1" + sep) != nullptr);
-        REQUIRE(VirtFs::searchEntryByRootInternal("dir2" + sep) != nullptr);
-        REQUIRE(VirtFs::searchEntryByRootInternal("test" + sep) == nullptr);
+        REQUIRE(VirtFs::searchByRootInternal("dir1" + sep, dirSeparator) !=
+            nullptr);
+        REQUIRE(VirtFs::searchByRootInternal("dir2" + sep, dirSeparator) !=
+            nullptr);
+        REQUIRE(VirtFs::searchByRootInternal("test" + sep, dirSeparator) ==
+            nullptr);
         REQUIRE(VirtFs::getEntries().size() == 2);
         REQUIRE(VirtFs::getEntries()[0]->root == "dir1" + sep);
         REQUIRE(VirtFs::getEntries()[1]->root == "dir2" + sep);
@@ -123,17 +133,20 @@ TEST_CASE("VirtFs1 mountDir")
 
     SECTION("simple 5")
     {
-        REQUIRE(VirtFs::mountDirSilent2("dir1",
+        REQUIRE(VirtFs::mountDirSilentTest("dir1",
             Append_true));
-        REQUIRE(VirtFs::mountDirSilent2("dir2",
+        REQUIRE(VirtFs::mountDirSilentTest("dir2",
             Append_true));
-        REQUIRE(VirtFs::mountDirSilent2("dir3/test",
+        REQUIRE(VirtFs::mountDirSilentTest("dir3/test",
             Append_true));
-        REQUIRE(VirtFs::searchEntryByRootInternal("dir1" + sep) != nullptr);
-        REQUIRE(VirtFs::searchEntryByRootInternal("dir2" + sep) != nullptr);
-        REQUIRE(VirtFs::searchEntryByRootInternal(
-            "dir3" + sep + "test" + sep) != nullptr);
-        REQUIRE(VirtFs::searchEntryByRootInternal("test" + sep) == nullptr);
+        REQUIRE(VirtFs::searchByRootInternal("dir1" + sep, dirSeparator) !=
+            nullptr);
+        REQUIRE(VirtFs::searchByRootInternal("dir2" + sep, dirSeparator) !=
+            nullptr);
+        REQUIRE(VirtFs::searchByRootInternal(
+            "dir3" + sep + "test" + sep, dirSeparator) != nullptr);
+        REQUIRE(VirtFs::searchByRootInternal("test" + sep, dirSeparator) ==
+            nullptr);
         REQUIRE(VirtFs::getEntries().size() == 3);
         REQUIRE(VirtFs::getEntries()[0]->root == "dir1" + sep);
         REQUIRE(VirtFs::getEntries()[1]->root == "dir2" + sep);
@@ -151,20 +164,20 @@ TEST_CASE("VirtFs1 mountDir")
 
     SECTION("simple 6")
     {
-        REQUIRE(VirtFs::mountDirSilent2("dir1",
+        REQUIRE(VirtFs::mountDirSilentTest("dir1",
             Append_true));
-        REQUIRE(VirtFs::mountDirSilent2("dir2",
+        REQUIRE(VirtFs::mountDirSilentTest("dir2",
             Append_true));
-        REQUIRE(VirtFs::mountDirSilent2("dir3\\test",
+        REQUIRE(VirtFs::mountDirSilentTest("dir3\\test",
             Append_false));
-        REQUIRE(VirtFs::searchEntryByRootInternal(
-            "dir1" + sep + "") != nullptr);
-        REQUIRE(VirtFs::searchEntryByRootInternal(
-            "dir2" + sep + "") != nullptr);
-        REQUIRE(VirtFs::searchEntryByRootInternal(
-            "dir3" + sep + "test" + sep) != nullptr);
-        REQUIRE(VirtFs::searchEntryByRootInternal(
-            "test" + sep + "") == nullptr);
+        REQUIRE(VirtFs::searchByRootInternal(
+            "dir1" + sep + "", dirSeparator) != nullptr);
+        REQUIRE(VirtFs::searchByRootInternal(
+            "dir2" + sep + "", dirSeparator) != nullptr);
+        REQUIRE(VirtFs::searchByRootInternal(
+            "dir3" + sep + "test" + sep, dirSeparator) != nullptr);
+        REQUIRE(VirtFs::searchByRootInternal(
+            "test" + sep + "", dirSeparator) == nullptr);
         REQUIRE(VirtFs::getEntries().size() == 3);
         REQUIRE(VirtFs::getEntries()[0]->root == "dir3" + sep + "test" + sep);
         REQUIRE(VirtFs::getEntries()[1]->root == "dir1" + sep);
@@ -198,10 +211,12 @@ TEST_CASE("VirtFs1 mountZip")
     {
         REQUIRE(VirtFs::mountZip(prefix + "data/test/test.zip",
             Append_false));
-        REQUIRE(VirtFs::searchEntryByRootInternal(
-            prefix + "data" + sep + "test" + sep + "test.zip") != nullptr);
-        REQUIRE(VirtFs::searchEntryByRootInternal(
-            prefix + "data" + sep + "test" + sep + "test2.zip") == nullptr);
+        REQUIRE(VirtFs::searchByRootInternal(
+            prefix + "data" + sep + "test" + sep + "test.zip", dirSeparator) !=
+            nullptr);
+        REQUIRE(VirtFs::searchByRootInternal(
+            prefix + "data" + sep + "test" + sep + "test2.zip", dirSeparator) ==
+            nullptr);
         REQUIRE(VirtFs::getEntries().size() == 1);
         REQUIRE(VirtFs::getEntries()[0]->root ==
             prefix + "data" + sep + "test" + sep + "test.zip");
@@ -214,10 +229,12 @@ TEST_CASE("VirtFs1 mountZip")
             Append_false));
         REQUIRE(VirtFs::mountZip(prefix + "data/test/test2.zip",
             Append_false));
-        REQUIRE(VirtFs::searchEntryByRootInternal(
-            prefix + "data" + sep + "test" + sep + "test.zip") != nullptr);
-        REQUIRE(VirtFs::searchEntryByRootInternal(
-            prefix + "data" + sep + "test" + sep + "test2.zip") != nullptr);
+        REQUIRE(VirtFs::searchByRootInternal(
+            prefix + "data" + sep + "test" + sep + "test.zip", dirSeparator) !=
+            nullptr);
+        REQUIRE(VirtFs::searchByRootInternal(
+            prefix + "data" + sep + "test" + sep + "test2.zip",
+            dirSeparator) != nullptr);
         REQUIRE(VirtFs::getEntries().size() == 2);
         REQUIRE(VirtFs::getEntries()[0]->root ==
             prefix + "data" + sep + "test" + sep + "test2.zip");
@@ -233,10 +250,12 @@ TEST_CASE("VirtFs1 mountZip")
             Append_true));
         REQUIRE(VirtFs::mountZip(prefix + "data/test/test2.zip",
             Append_true));
-        REQUIRE(VirtFs::searchEntryByRootInternal(
-            prefix + "data" + sep + "test" + sep + "test.zip") != nullptr);
-        REQUIRE(VirtFs::searchEntryByRootInternal(
-            prefix + "data" + sep + "test" + sep + "test2.zip") != nullptr);
+        REQUIRE(VirtFs::searchByRootInternal(
+            prefix + "data" + sep + "test" + sep + "test.zip",
+            dirSeparator) != nullptr);
+        REQUIRE(VirtFs::searchByRootInternal(
+            prefix + "data" + sep + "test" + sep + "test2.zip",
+            dirSeparator) != nullptr);
         REQUIRE(VirtFs::getEntries().size() == 2);
         REQUIRE(VirtFs::getEntries()[0]->root ==
             prefix + "data" + sep + "test" + sep + "test.zip");
@@ -254,12 +273,15 @@ TEST_CASE("VirtFs1 mountZip")
             Append_false));
         REQUIRE(VirtFs::mountZip(prefix + "data/test/test2.zip",
             Append_false));
-        REQUIRE(VirtFs::searchEntryByRootInternal(
-            prefix + "data" + sep + "test" + sep + "test.zip") != nullptr);
-        REQUIRE(VirtFs::searchEntryByRootInternal(
-            prefix + "data" + sep + "test" + sep + "test2.zip") != nullptr);
-        REQUIRE(VirtFs::searchEntryByRootInternal(
-            prefix + "data" + sep + "test" + sep + "") != nullptr);
+        REQUIRE(VirtFs::searchByRootInternal(
+            prefix + "data" + sep + "test" + sep + "test.zip",
+            dirSeparator) != nullptr);
+        REQUIRE(VirtFs::searchByRootInternal(
+            prefix + "data" + sep + "test" + sep + "test2.zip",
+            dirSeparator) != nullptr);
+        REQUIRE(VirtFs::searchByRootInternal(
+            prefix + "data" + sep + "test" + sep + "",
+            dirSeparator) != nullptr);
         REQUIRE(VirtFs::getEntries().size() == 3);
         REQUIRE(VirtFs::getEntries()[0]->root ==
             prefix + "data" + sep + "test" + sep + "test2.zip");
@@ -280,12 +302,15 @@ TEST_CASE("VirtFs1 mountZip")
             Append_false));
         REQUIRE(VirtFs::mountZip(prefix + "data/test/test2.zip",
             Append_true));
-        REQUIRE(VirtFs::searchEntryByRootInternal(
-            prefix + "data" + sep + "test" + sep + "test.zip") != nullptr);
-        REQUIRE(VirtFs::searchEntryByRootInternal(
-            prefix + "data" + sep + "test" + sep + "test2.zip") != nullptr);
-        REQUIRE(VirtFs::searchEntryByRootInternal(
-            prefix + "data" + sep + "test" + sep + "") != nullptr);
+        REQUIRE(VirtFs::searchByRootInternal(
+            prefix + "data" + sep + "test" + sep + "test.zip",
+            dirSeparator) != nullptr);
+        REQUIRE(VirtFs::searchByRootInternal(
+            prefix + "data" + sep + "test" + sep + "test2.zip",
+            dirSeparator) != nullptr);
+        REQUIRE(VirtFs::searchByRootInternal(
+            prefix + "data" + sep + "test" + sep + "",
+            dirSeparator) != nullptr);
         REQUIRE(VirtFs::getEntries().size() == 3);
         REQUIRE(VirtFs::getEntries()[0]->root ==
             prefix + "data" + sep + "test" + sep + "");
@@ -320,7 +345,7 @@ TEST_CASE("VirtFs1 removeFromSearchPath")
 
     SECTION("simple 2")
     {
-        REQUIRE(VirtFs::mountDirSilent2("dir1",
+        REQUIRE(VirtFs::mountDirSilentTest("dir1",
             Append_true));
         REQUIRE_THROWS(VirtFs::unmountDir("dir2"));
         REQUIRE(VirtFs::unmountDir("dir1"));
@@ -328,11 +353,11 @@ TEST_CASE("VirtFs1 removeFromSearchPath")
 
     SECTION("simple 3")
     {
-        REQUIRE(VirtFs::mountDirSilent2("dir1",
+        REQUIRE(VirtFs::mountDirSilentTest("dir1",
             Append_true));
-        REQUIRE(VirtFs::mountDirSilent2("dir2//dir3",
+        REQUIRE(VirtFs::mountDirSilentTest("dir2//dir3",
             Append_true));
-        REQUIRE(VirtFs::mountDirSilent2("dir3",
+        REQUIRE(VirtFs::mountDirSilentTest("dir3",
             Append_false));
         REQUIRE(VirtFs::getEntries().size() == 3);
         REQUIRE_THROWS(VirtFs::unmountDir("dir2"));
@@ -367,7 +392,7 @@ TEST_CASE("VirtFs1 removeFromSearchPath")
 
     SECTION("simple 4")
     {
-        REQUIRE(VirtFs::mountDirSilent2("dir1",
+        REQUIRE(VirtFs::mountDirSilentTest("dir1",
             Append_true));
         REQUIRE(VirtFs::getEntries().size() == 1);
         REQUIRE(VirtFs::getEntries()[0]->root == "dir1" + sep);
@@ -377,7 +402,7 @@ TEST_CASE("VirtFs1 removeFromSearchPath")
         REQUIRE_THROWS(VirtFs::unmountDir("dir2"));
         REQUIRE(VirtFs::unmountDir("dir1"));
         REQUIRE(VirtFs::getEntries().size() == 0);
-        REQUIRE(VirtFs::mountDirSilent2("dir1",
+        REQUIRE(VirtFs::mountDirSilentTest("dir1",
             Append_true));
         REQUIRE(VirtFs::getEntries().size() == 1);
         REQUIRE(VirtFs::getEntries()[0]->root == "dir1" + sep);
@@ -393,10 +418,12 @@ TEST_CASE("VirtFs1 removeFromSearchPath")
         REQUIRE(VirtFs::mountZip(prefix + "data/test/test2.zip",
             Append_true));
 
-        REQUIRE(VirtFs::searchEntryByRootInternal(
-            prefix + "data" + sep + "test" + sep + "test.zip") != nullptr);
-        REQUIRE(VirtFs::searchEntryByRootInternal(
-            prefix + "data" + sep + "test" + sep + "test2.zip") != nullptr);
+        REQUIRE(VirtFs::searchByRootInternal(
+            prefix + "data" + sep + "test" + sep + "test.zip",
+            dirSeparator) != nullptr);
+        REQUIRE(VirtFs::searchByRootInternal(
+            prefix + "data" + sep + "test" + sep + "test2.zip",
+            dirSeparator) != nullptr);
         REQUIRE(VirtFs::getEntries().size() == 2);
         REQUIRE(VirtFs::getEntries()[0]->root ==
             prefix + "data" + sep + "test" + sep + "test.zip");
@@ -406,10 +433,12 @@ TEST_CASE("VirtFs1 removeFromSearchPath")
         REQUIRE(VirtFs::getEntries()[1]->type == FsEntryType::Zip);
 
         VirtFs::unmountZip(prefix + "data/test/test.zip");
-        REQUIRE(VirtFs::searchEntryByRootInternal(
-            prefix + "data" + sep + "test" + sep + "test.zip") == nullptr);
-        REQUIRE(VirtFs::searchEntryByRootInternal(
-            prefix + "data" + sep + "test" + sep + "test2.zip") != nullptr);
+        REQUIRE(VirtFs::searchByRootInternal(
+            prefix + "data" + sep + "test" + sep + "test.zip",
+            dirSeparator) == nullptr);
+        REQUIRE(VirtFs::searchByRootInternal(
+            prefix + "data" + sep + "test" + sep + "test2.zip",
+            dirSeparator) != nullptr);
         REQUIRE(VirtFs::getEntries().size() == 1);
         REQUIRE(VirtFs::getEntries()[0]->root ==
             prefix + "data" + sep + "test" + sep + "test2.zip");
@@ -425,12 +454,15 @@ TEST_CASE("VirtFs1 removeFromSearchPath")
         REQUIRE(VirtFs::mountZip(prefix + "data\\test/test2.zip",
             Append_false));
 
-        REQUIRE(VirtFs::searchEntryByRootInternal(
-            prefix + "data" + sep + "test" + sep + "test.zip") != nullptr);
-        REQUIRE(VirtFs::searchEntryByRootInternal(
-            prefix + "data" + sep + "test" + sep + "test2.zip") != nullptr);
-        REQUIRE(VirtFs::searchEntryByRootInternal(
-            prefix + "data" + sep + "test" + sep + "") != nullptr);
+        REQUIRE(VirtFs::searchByRootInternal(
+            prefix + "data" + sep + "test" + sep + "test.zip",
+            dirSeparator) != nullptr);
+        REQUIRE(VirtFs::searchByRootInternal(
+            prefix + "data" + sep + "test" + sep + "test2.zip",
+            dirSeparator) != nullptr);
+        REQUIRE(VirtFs::searchByRootInternal(
+            prefix + "data" + sep + "test" + sep + "",
+            dirSeparator) != nullptr);
         REQUIRE(VirtFs::getEntries().size() == 3);
         REQUIRE(VirtFs::getEntries()[0]->root ==
             prefix + "data" + sep + "test" + sep + "test2.zip");
@@ -443,12 +475,15 @@ TEST_CASE("VirtFs1 removeFromSearchPath")
         REQUIRE(VirtFs::getEntries()[2]->type == FsEntryType::Zip);
 
         VirtFs::unmountZip(prefix + "data/test/test.zip");
-        REQUIRE(VirtFs::searchEntryByRootInternal(
-            prefix + "data" + sep + "test" + sep + "test.zip") == nullptr);
-        REQUIRE(VirtFs::searchEntryByRootInternal(
-            prefix + "data" + sep + "test" + sep + "test2.zip") != nullptr);
-        REQUIRE(VirtFs::searchEntryByRootInternal(
-            prefix + "data" + sep + "test" + sep + "") != nullptr);
+        REQUIRE(VirtFs::searchByRootInternal(
+            prefix + "data" + sep + "test" + sep + "test.zip",
+            dirSeparator) == nullptr);
+        REQUIRE(VirtFs::searchByRootInternal(
+            prefix + "data" + sep + "test" + sep + "test2.zip",
+            dirSeparator) != nullptr);
+        REQUIRE(VirtFs::searchByRootInternal(
+            prefix + "data" + sep + "test" + sep + "",
+            dirSeparator) != nullptr);
         REQUIRE(VirtFs::getEntries().size() == 2);
         REQUIRE(VirtFs::getEntries()[0]->root ==
             prefix + "data" + sep + "test" + sep + "test2.zip");
diff --git a/src/fs/virtfs/zip_unittest.cc b/src/fs/virtfs/zip_unittest.cc
index e0d468941..09ebdb1f5 100644
--- a/src/fs/virtfs/zip_unittest.cc
+++ b/src/fs/virtfs/zip_unittest.cc
@@ -49,6 +49,7 @@ TEST_CASE("Zip readArchiveInfo")
         name = prefix + "data/test/test.zip";
 
         VirtFs::ZipEntry *const entry = new VirtFs::ZipEntry(name,
+            dirSeparator,
             VirtFs::FsZip::getFuncs());
         std::vector<VirtFs::ZipLocalHeader*> &headers = entry->mHeaders;
 
@@ -70,6 +71,7 @@ TEST_CASE("Zip readArchiveInfo")
         name = prefix + "data/test/test2.zip";
 
         VirtFs::ZipEntry *const entry = new VirtFs::ZipEntry(name,
+            dirSeparator,
             VirtFs::FsZip::getFuncs());
         std::vector<VirtFs::ZipLocalHeader*> &headers = entry->mHeaders;
 
@@ -132,6 +134,7 @@ TEST_CASE("Zip readArchiveInfo")
         name = prefix + "data/test/test3.zip";
 
         VirtFs::ZipEntry *const entry = new VirtFs::ZipEntry(name,
+            dirSeparator,
             VirtFs::FsZip::getFuncs());
         std::vector<VirtFs::ZipLocalHeader*> &headers = entry->mHeaders;
 
@@ -153,6 +156,7 @@ TEST_CASE("Zip readArchiveInfo")
         name = prefix + "data/test/test4.zip";
 
         VirtFs::ZipEntry *const entry = new VirtFs::ZipEntry(name,
+            dirSeparator,
             VirtFs::FsZip::getFuncs());
         std::vector<VirtFs::ZipLocalHeader*> &headers = entry->mHeaders;
 
@@ -184,6 +188,7 @@ TEST_CASE("Zip readCompressedFile")
         name = prefix + "data/test/test2.zip";
 
         VirtFs::ZipEntry *const entry = new VirtFs::ZipEntry(name,
+            dirSeparator,
             VirtFs::FsZip::getFuncs());
         std::vector<VirtFs::ZipLocalHeader*> &headers = entry->mHeaders;
 
@@ -218,6 +223,7 @@ TEST_CASE("Zip readFile")
         name = prefix + "data/test/test.zip";
 
         VirtFs::ZipEntry *const entry = new VirtFs::ZipEntry(name,
+            dirSeparator,
             VirtFs::FsZip::getFuncs());
         std::vector<VirtFs::ZipLocalHeader*> &headers = entry->mHeaders;
 
@@ -242,6 +248,7 @@ TEST_CASE("Zip readFile")
         name = prefix + "data/test/test2.zip";
 
         VirtFs::ZipEntry *const entry = new VirtFs::ZipEntry(name,
+            dirSeparator,
             VirtFs::FsZip::getFuncs());
         std::vector<VirtFs::ZipLocalHeader*> &headers = entry->mHeaders;
 
@@ -273,6 +280,7 @@ TEST_CASE("Zip readFile")
         name = prefix + "data/test/test3.zip";
 
         VirtFs::ZipEntry *const entry = new VirtFs::ZipEntry(name,
+            dirSeparator,
             VirtFs::FsZip::getFuncs());
         std::vector<VirtFs::ZipLocalHeader*> &headers = entry->mHeaders;
 
diff --git a/src/fs/virtfs/zipentry.cpp b/src/fs/virtfs/zipentry.cpp
index e23055db9..d8440833b 100644
--- a/src/fs/virtfs/zipentry.cpp
+++ b/src/fs/virtfs/zipentry.cpp
@@ -30,12 +30,14 @@ namespace VirtFs
 {
 
 ZipEntry::ZipEntry(const std::string &restrict archiveName,
+                   const std::string &subDir0,
                    FsFuncs *restrict const funcs0) :
     FsEntry(FsEntryType::Zip, funcs0),
     mHeaders(),
     mDirs()
 {
     root = archiveName;
+    subDir = subDir0;
 }
 
 ZipEntry::~ZipEntry()
diff --git a/src/fs/virtfs/zipentry.h b/src/fs/virtfs/zipentry.h
index b8e2632b1..5d912f057 100644
--- a/src/fs/virtfs/zipentry.h
+++ b/src/fs/virtfs/zipentry.h
@@ -35,6 +35,7 @@ struct ZipLocalHeader;
 struct ZipEntry final : public FsEntry
 {
     ZipEntry(const std::string &restrict archiveName,
+             const std::string &subDir0,
              FsFuncs *restrict const funcs);
 
     A_DELETE_COPY(ZipEntry)
-- 
cgit v1.2.3-70-g09d2