Fix CompatibilityManager for share2 folder of compat
authorDuyoung Jang <duyoung.jang@samsung.com>
Thu, 1 Aug 2013 02:50:44 +0000 (11:50 +0900)
committerDuyoung Jang <duyoung.jang@samsung.com>
Thu, 1 Aug 2013 02:50:44 +0000 (11:50 +0900)
Change-Id: Ibb3865e8f6b9e4511a123e942325c240ba23c9b8
Signed-off-by: Duyoung Jang <duyoung.jang@samsung.com>
13 files changed:
CMakeLists.txt
inc/InstallerDefs.h [changed mode: 0644->0755]
packaging/osp-installer.spec
src/Context/InstallationContext.cpp
src/Context/InstallationContext.h
src/Installer/DirectoryInstaller.cpp
src/Manager/CompatibilityManager.cpp
src/Manager/CompatibilityManager.h
src/Manager/ConfigurationManager.cpp
src/Manager/PermissionManager.cpp
src/Manager/PermissionManager.h
src/Step/UninstallStep.cpp
src/XmlHandler/ManifestHandler.cpp

index 44dbf66..6e700d7 100755 (executable)
@@ -83,7 +83,7 @@ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fexceptions -fvisibility=hidden")
 SET(CMAKE_CXX_FLAGS "${OSP_DEBUG_FLAGS} ${OSP_OPT_FLAGS} ${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS} ${OSP_COMPILER_FLAGS}")
 
 TARGET_LINK_LIBRARIES(${this_target} "-L/usr/lib/osp -losp-appfw -lxml2 -lpkgmgr_installer -lpkgmgr_parser -lglib-2.0 -lapp2ext -ldl" -Wl,--allow-shlib-undefined)
-TARGET_LINK_LIBRARIES(${this_target} "-L/usr/lib -lcert-svc-vcore -ldpl-efl -lcert-svc -lcapi-system-info -lappcore-common -lpkgmgr-info -lvconf")
+TARGET_LINK_LIBRARIES(${this_target} "-L/usr/lib -lcert-svc-vcore -ldpl-efl -lcert-svc -lcapi-system-info -lappcore-common -lpkgmgr-info -lvconf -lcap")
 
 ADD_SUBDIRECTORY(plugin)
 
old mode 100644 (file)
new mode 100755 (executable)
index ddb7e36..7e18a39
@@ -23,7 +23,7 @@
 
 #include "InstallerUtil.h"
 
-#define OSP_INSTALLER_VERSION "version=[20130731.1]"
+#define OSP_INSTALLER_VERSION "version=[20130801.1]"
 
 #define DIR_BIN                                L"/bin"
 #define DIR_INFO                       L"/info"
@@ -37,7 +37,6 @@
 #define DIR_SHARED_RES         L"/shared/res"
 #define DIR_SHARED_DATA                L"/shared/data"
 #define DIR_SHARED_TRUSTED     L"/shared/trusted"
-#define DIR_VIRTUAL_ROOT               L"/virtual-root"
 
 #define SLP_DIR_BIN                    L"/bin"
 #define SLP_DIR_RES                    L"/res"
@@ -56,6 +55,7 @@
 #define PACKAGE_NAME_RULE_ORG          L"org.tizen.%ls#%s"
 
 #define PACKAGE_NAME_RULE                      L"%ls.%s"
+#define BACKUP_NAME_RULE                       L"_backup"
 
 #define FILE_EXT_INFO                          L"info"
 #define VERSION_INFO_FILE                      L"/info/version.info"
@@ -262,6 +262,7 @@ enum InstallerError
        INSTALLER_ERROR_INTERNAL_STATE = 143,
        INSTALLER_ERROR_DATABASE = 144,
        INSTALLER_ERROR_DRM = 145,
+       INSTALLER_ERROR_BACKUP_FAILED = 146,
 };
 
 enum InstallerOperation
index fabbb3a..868673a 100755 (executable)
@@ -6,6 +6,7 @@ Group:          TO_BE/FILLED_IN
 License:       Apache License, Version 2.0 or Flora
 Source0:       %{name}-%{version}.tar.gz
 BuildRequires:  cmake
+BuildRequires:  libcap-devel
 BuildRequires:  pkgconfig(capi-system-info)
 BuildRequires:  pkgconfig(capi-system-device)
 BuildRequires:  pkgconfig(glib-2.0)
index 0d9669f..9ce1e63 100755 (executable)
@@ -54,7 +54,6 @@ InstallationContext::InstallationContext(void)
 ,__isAppSetting(false)
 ,__isCsc(false)
 ,__isUninstallable(false)
-,__isVirtualRoot(false)
 ,__operation(INSTALLER_OPERATION_INSTALL)
 ,__storage(INSTALLATION_STORAGE_NONE)
 ,__rootCertType(ROOT_CERTIFICATE_NONE)
index b8058cf..8529718 100755 (executable)
@@ -102,7 +102,6 @@ public:
        bool __isAppSetting;
        bool __isCsc;
        bool __isUninstallable;
-       bool __isVirtualRoot;
 
        InstallerOperation __operation;
        InstallationStorage __storage;
@@ -142,6 +141,7 @@ public:
        Tizen::App::PackageId __storeClientId;
        Tizen::Base::String __additionalErrorString;
        Tizen::Base::String __cscInfo;
+       Tizen::Base::String __virtualRootPath;
 
        int __certType;
        void* __pPkgmgrInstaller;
index 3b1ca1a..d0a2b9b 100755 (executable)
@@ -73,7 +73,8 @@ DirectoryInstaller::OnInit(void)
        InstallationContext* pContext = GetContext();
 
        if ((File::IsFileExist(pContext->GetSignatureXmlPath()) == true) &&
-                       (File::IsFileExist(pContext->GetAuthorSignatureXmlPath()) == true))
+                       (File::IsFileExist(pContext->GetAuthorSignatureXmlPath()) == true) &&
+                       (pContext->__isHybridService == false))
        {
                AppLog("[VerifySignature] VerificationMode ON");
                pContext->__isVerificationMode = true;
index fc63da4..2835f2c 100755 (executable)
@@ -59,6 +59,7 @@ struct _PathInfo
 
 
 CompatibilityManager::CompatibilityManager(void)
+:__pContext(null)
 {
 }
 
@@ -67,6 +68,14 @@ CompatibilityManager::~CompatibilityManager(void)
 }
 
 bool
+CompatibilityManager::Construct(InstallationContext* pContext)
+{
+       __pContext = pContext;
+
+       return true;
+}
+
+bool
 CompatibilityManager::PrepareDataCaging(const String& rootPath, const PackageId& packageId)
 {
        bool res = true;
@@ -264,36 +273,34 @@ CompatibilityManager::LinkOspSharePath(const String& rootPath, const PackageId&
 bool
 CompatibilityManager::PrepareVirtualRoot(const Tizen::Base::String& rootPath, const Tizen::App::PackageId& packageId)
 {
+       String virtualRoot = GetVirtualRootPath(rootPath);
+       TryReturn(virtualRoot.IsEmpty() == false, false, "GetVirtualRootPath(%ls) failed.", rootPath.GetPointer());
+
        result r = E_SUCCESS;
        bool res = true;
        int result = 0;
        char* pCwd = null;
-       String destPath = rootPath + DIR_VIRTUAL_ROOT;
-       SmackManager smackManager;
+       String virtualRootPath = rootPath + DIR_DATA + L"/" + virtualRoot;
 
-       std::unique_ptr<char[]> pVirtualRootPath(_StringConverter::CopyToCharArrayN(destPath));
+       std::unique_ptr<char[]> pVirtualRootPath(_StringConverter::CopyToCharArrayN(virtualRootPath));
        TryCatch(pVirtualRootPath != null, res = false, "The memory is insufficient.");
 
        pCwd = get_current_dir_name();
        TryCatch(pCwd != null, res = false, "get_current_dir_name() failed. [errno = %d(%s)]", errno, strerror(errno));
 
        // appRoot/virtual-root
-       if (File::IsFileExist(destPath) == false)
+       if (File::IsFileExist(virtualRootPath) == false)
        {
-               r = Directory::Create(destPath, false);
+               r = Directory::Create(virtualRootPath, true);
                TryCatch(!IsFailed(r), res = false, "Directory::Create() failed");
        }
 
-       InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE, true);
-
        result = chdir(pVirtualRootPath.get());
        TryCatch(result == 0, res = false, "chdir(%s) failed. [errno = %d(%s)]", pVirtualRootPath.get(), errno, strerror(errno));
 
        res = CreateVirtualRootDirectories();
        TryCatch(res == true, , "CreateVirtualRootDirectories() failed.");
 
-       smackManager.SetupPath(packageId, destPath, SMACK_DIR_TYPE_PRIVATE);
-
        res = CreateSymbolicLink();
        TryCatch(res == true, , "CreateSymbolicLink() failed.");
 
@@ -314,9 +321,13 @@ CATCH:
 bool
 CompatibilityManager::FinalizeVirtualRoot(const String& rootPath, const PackageId& packageId)
 {
+       String virtualRootPath = GetVirtualRootPath(rootPath);
+       TryReturn(virtualRootPath.IsEmpty() == false, false, "GetVirtualRootPath(%ls) failed.", rootPath.GetPointer());
+
        int res = 0;
        unsigned int i = 0;
-       String destPath = rootPath + DIR_VIRTUAL_ROOT;
+       String destPath = rootPath + DIR_DATA + L"/" + virtualRootPath;
+
        static const struct _PathInfo mountPath[] =
        {
                        { "./bin" },
@@ -360,6 +371,8 @@ CompatibilityManager::FinalizeVirtualRoot(const String& rootPath, const PackageI
        {
                res = umount2(mountPath[i].destPath, MNT_DETACH);
                TryReturn((res == 0) || (errno == EINVAL) || (errno == ENOENT), false, "umount2() failed. (%d, %s), path = [%s]", errno, strerror(errno), mountPath[i].destPath);
+
+               AppLog("umount2(%s) is succeeded.", mountPath[i].destPath);
        }
 
        std::unique_ptr<char[]> pPackageId(_StringConverter::CopyToCharArrayN(packageId));
@@ -438,6 +451,7 @@ CompatibilityManager::CreateOspInternalDirectories(const String& rootPath, const
        }
 
        SmackManager smackManager;
+       smackManager.Construct(__pContext);
        smackManager.SetupPath(packageId, L"./Storagecard", SMACK_DIR_TYPE_ANY_LABEL, L"_");
 
        ospShareAppIdPath.Append(packageId);
@@ -515,7 +529,6 @@ CompatibilityManager::CreateSlpDirectories(void)
                { "./dev", 0000, false },
                { "./etc", 0000, false },
                { "./lib", 0000, false },
-               { "./media", 0000, false },
                { "./mnt", 0000, false },
                { "./opt", 0000, false },
                { "./proc", 0000, false },
@@ -536,6 +549,10 @@ CompatibilityManager::CreateSlpDirectories(void)
                        AppLog("mkdir() failed (%s), path: %s, mode: 0%o", strerror(errno), slpDir[i].path, slpDir[i].mode);
                        return false;
                }
+               else
+               {
+                       AppLog("Directory[%s, 0%o] is created.", slpDir[i].path, slpDir[i].mode);
+               }
        }
 
        AppLog("[Tizen::Io] CreateSlpDirectories() succeeded.");
@@ -598,8 +615,41 @@ CompatibilityManager::CreateVirtualRootDirectories(void)
                        AppLog("mkdir() failed (%s), path: %s, mode: 0%o", strerror(errno), virtualRootDir[i].path, virtualRootDir[i].mode);
                        return false;
                }
+               else
+               {
+                       AppLog("Directory[%s, 0%o] is created.", virtualRootDir[i].path, virtualRootDir[i].mode);
+               }
        }
 
        AppLog("[Tizen::Io] CreateVirtualRootDirectories() succeeded.");
        return true;
 }
+
+String
+CompatibilityManager::GetVirtualRootPath(const Tizen::Base::String& rootPath)
+{
+       TryReturn(rootPath.IsEmpty() == false, L"", "rootPath is empty.");
+
+       String virtualRootInfoFile;
+       virtualRootInfoFile.Format(1024, L"%ls%ls", rootPath.GetPointer(), VIRTUAL_ROOT_INFO_FILE);
+
+       if (File::IsFileExist(virtualRootInfoFile) == false)
+       {
+               AppLog("virtualRootInfoFile[%ls] is not existed.", virtualRootInfoFile.GetPointer());
+               return L"";
+       }
+
+       result r = E_SUCCESS;
+       File file;
+       String virtualRootPath;
+
+       r = file.Construct(virtualRootInfoFile, L"r");
+       TryReturn(r == E_SUCCESS, L"", "file.Construct() is failed. [%ls]", virtualRootInfoFile.GetPointer());
+
+       r = file.Read(virtualRootPath);
+       TryReturn(r == E_SUCCESS, L"", "file.Read() is failed. [%ls]", virtualRootInfoFile.GetPointer());
+
+       AppLog("virtualRootPath = [%ls]", virtualRootPath.GetPointer());
+
+       return virtualRootPath;
+}
index 2969359..79fac1c 100755 (executable)
@@ -23,6 +23,8 @@
 #ifndef _COMPATIBILITY_MANAGER_H_
 #define _COMPATIBILITY_MANAGER_H_
 
+#include "InstallationContext.h"
+
 /**
        * @class                CompatibilityManager
        * @brief                This class represents the class of CompatibilityManager.
@@ -37,26 +39,30 @@ class CompatibilityManager
 public:
        CompatibilityManager(void);
        virtual ~CompatibilityManager(void);
+       bool Construct(InstallationContext* pContext);
 
-       static bool PrepareDataCaging(const Tizen::Base::String& rootPath, const Tizen::App::PackageId& packageId);
-       static bool FinalizeDataCaging(const Tizen::Base::String& rootPath);
-       static bool CleanDirectories(const Tizen::Base::String& rootPath, const Tizen::App::PackageId& packageId);
+       bool PrepareDataCaging(const Tizen::Base::String& rootPath, const Tizen::App::PackageId& packageId);
+       bool FinalizeDataCaging(const Tizen::Base::String& rootPath);
+       bool CleanDirectories(const Tizen::Base::String& rootPath, const Tizen::App::PackageId& packageId);
 
-       static bool LinkOspSharePath(const Tizen::Base::String& rootPath, const Tizen::App::PackageId& packageId);
+       bool LinkOspSharePath(const Tizen::Base::String& rootPath, const Tizen::App::PackageId& packageId);
 
-       static bool PrepareVirtualRoot(const Tizen::Base::String& rootPath, const Tizen::App::PackageId& packageId);
-       static bool FinalizeVirtualRoot(const Tizen::Base::String& rootPath, const Tizen::App::PackageId& packageId);
+       bool PrepareVirtualRoot(const Tizen::Base::String& rootPath, const Tizen::App::PackageId& packageId);
+       bool FinalizeVirtualRoot(const Tizen::Base::String& rootPath, const Tizen::App::PackageId& packageId);
 
 private:
        CompatibilityManager(const CompatibilityManager& value);
        CompatibilityManager& operator =(const CompatibilityManager& source);
 
-       static bool CreateOspInternalDirectories(const Tizen::Base::String& rootPath, const Tizen::App::PackageId& packageId);
-       static bool CreateSlpDirectories(void);
-       static bool CreateSymbolicLink(void);
-       static bool CreateVirtualRootDirectories(void);
+       bool CreateOspInternalDirectories(const Tizen::Base::String& rootPath, const Tizen::App::PackageId& packageId);
+       bool CreateSlpDirectories(void);
+       bool CreateSymbolicLink(void);
+       bool CreateVirtualRootDirectories(void);
+
+       Tizen::Base::String GetVirtualRootPath(const Tizen::Base::String& rootPath);
 
 private:
+       InstallationContext* __pContext;
 
 }; // CompatibilityManager
 
index 84b44b1..ba37508 100755 (executable)
@@ -79,13 +79,13 @@ ConfigurationManager::CreateFile(InstallationContext* pContext)
                InstallerUtil::CreateInfoFile(compatInfoFile, null);
        }
 
-       if (pContext->__isVirtualRoot == true)
+       if (pContext->__virtualRootPath.IsEmpty() == false)
        {
                AppLog("[VirtualRoot] is detected");
 
                String virtualRootInfoFile;
                virtualRootInfoFile.Format(1024, L"%ls%ls", rootPath.GetPointer(), VIRTUAL_ROOT_INFO_FILE);
-               InstallerUtil::CreateInfoFile(virtualRootInfoFile, null);
+               InstallerUtil::CreateInfoFile(virtualRootInfoFile, &pContext->__virtualRootPath);
        }
 
        String webServicePrivilege(TIZEN_PRIVILEGE_WEB_SERVICE);
@@ -150,7 +150,7 @@ ConfigurationManager::CreateFile(InstallationContext* pContext)
                }
                else if (appType == L"ServiceApp")
                {
-                       if (pContext->__isPreloaded == true || pAppData->__isSystemService == true)
+                       if ((pContext->__isPreloaded == true) && (pAppData->__isSystemService == true))
                        {
                                AppLog("copy system service loader");
                                InstallerUtil::Copy(SYSTEMSERIVCE_LOADER_PATH, binaryPath);
index 40693b3..efd0f3b 100755 (executable)
@@ -21,6 +21,7 @@
 
 #include <stdio.h>
 #include <sys/stat.h>
+#include <sys/capability.h>
 #include <unistd.h>
 #include <unique_ptr.h>
 
@@ -60,6 +61,9 @@ PermissionManager::SetDirectory(InstallationContext* pContext)
        SmackManager smackManager;
        smackManager.Construct(pContext);
 
+       CompatibilityManager compatibilityManager;
+       compatibilityManager.Construct(pContext);
+
        appRootPath = pContext->__rootPath;
        PackageId packageId = pContext->__packageId;
 
@@ -155,6 +159,13 @@ PermissionManager::SetDirectory(InstallationContext* pContext)
                TryReturn(!IsFailed(r), false, "Directory::Create() failed");
        }
        InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE, true);
+
+       // appRoot/data/[virtualRoot]
+       if (pContext->__virtualRootPath.IsEmpty() == false)
+       {
+               res = compatibilityManager.PrepareVirtualRoot(appRootPath, packageId);
+               TryReturn(res == true, false, "[Tizen::Io] compatibilityManager.PrepareVirtualRoot(%ls) failed.", appRootPath.GetPointer());
+       }
        smackManager.SetupPath(packageId, destPath, SMACK_DIR_TYPE_PRIVATE);
 
        String apiVersion = pContext->__apiVersion;
@@ -168,8 +179,8 @@ PermissionManager::SetDirectory(InstallationContext* pContext)
        {
                AppLog("[Tizen::Io] OSP 2.0 application");
 
-               res = CompatibilityManager::PrepareDataCaging(appRootPath, packageId);
-               TryReturn(res == true, false, "[Tizen::Io] CompatibilityManager::PrepareDataCaging() failed.");
+               res = compatibilityManager.PrepareDataCaging(appRootPath, packageId);
+               TryReturn(res == true, false, "[Tizen::Io] compatibilityManager.PrepareDataCaging() failed.");
 
                SetSymLink(pContext);
        }
@@ -177,18 +188,13 @@ PermissionManager::SetDirectory(InstallationContext* pContext)
        {
                AppLog("[Tizen::Io] apiVersion is equal to or greater than Tizen 2.0");
 
-               res = CompatibilityManager::CleanDirectories(appRootPath, packageId);
-               TryReturn(res == true, false, "[Tizen::Io] CompatibilityManager::CleanDirectories() failed.");
+               res = compatibilityManager.CleanDirectories(appRootPath, packageId);
+               TryReturn(res == true, false, "[Tizen::Io] compatibilityManager.CleanDirectories() failed.");
 
-               res = CompatibilityManager::LinkOspSharePath(appRootPath, packageId);
-               TryReturn(res == true, false, "[Tizen::Io] CompatibilityManager::LinkOspSharePath() failed.");
+               res = compatibilityManager.LinkOspSharePath(appRootPath, packageId);
+               TryReturn(res == true, false, "[Tizen::Io] compatibilityManager.LinkOspSharePath() failed.");
        }
 
-       if (pContext->__isVirtualRoot == true)
-       {
-               res = CompatibilityManager::PrepareVirtualRoot(appRootPath, packageId);
-               TryReturn(res == true, false, "[Tizen::Io] CompatibilityManager::PrepareVirtualRoot() failed.");
-       }
        AppLog("------------------------------------------");
 
        return true;
@@ -201,18 +207,25 @@ PermissionManager::SetFile(InstallationContext* pContext)
        String appRootPath = pContext->__rootPath;
 
        IListT<AppData*>* pAppDataList = pContext->__pAppDataList;
-       TryReturn(pAppDataList, false, "pAppDataList is null");
+       TryReturn(pAppDataList, false, "pAppDataList is null.");
 
        for (int i = 0 ; i < pAppDataList->GetCount(); i++)
        {
                AppData* pAppData = null;
                pAppDataList->GetAt(i, pAppData);
-               TryReturn(pAppData, false, "pAppData is null");
+               TryReturn(pAppData, false, "pAppData is null.");
+
+               String loader = appRootPath + DIR_BIN + L"/" + pAppData->__name;
+               if (File::IsFileExist(loader) == true)
+               {
+                       SetFileCapability(loader, pContext);
+               }
 
                // set permission(755) to bin file.
                destPath = appRootPath + DIR_BIN + L"/" + pAppData->__name + L".exe";
                if (File::IsFileExist(destPath) == true)
                {
+                       SetFileCapability(destPath, pContext);
                        InstallerUtil::ChangeMode(destPath, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
                }
        }
@@ -406,6 +419,29 @@ PermissionManager::ApplyPermissionForRds(InstallationContext* pContext)
        return true;
 }
 
+bool
+PermissionManager::SetFileCapability(const String& path, InstallationContext* pContext)
+{
+       TryReturn(path.IsEmpty() == false, false, "path is empty.");
+       TryReturn(pContext, false, "pContext is null.");
+
+       if (pContext->__isPreloaded == true)
+       {
+               AppLog("cap_set_file() is skipped.");
+               return true;
+       }
+
+       std::unique_ptr<char[]> pPath(_StringConverter::CopyToCharArrayN(path));
+       TryReturn(pPath != null, false, "The memory is insufficient.");
+
+       int res = cap_set_file(pPath.get(), cap_from_text("CAP_NET_RAW,CAP_SYS_CHROOT+i"));
+       TryReturn(res == 0, false, "cap_set_file() failed. [res = %d]", res);
+
+       AppLog("cap_set_file(%s, cap_from_text(CAP_NET_RAW,CAP_SYS_CHROOT+i)) called.", pPath.get());
+
+       return true;
+}
+
 #if 0
 bool
 PermissionManager::ApplyPermission(InstallationContext* pContext, const IList* pFileList)
index a906a20..a27def3 100755 (executable)
@@ -48,6 +48,7 @@ public:
 private:
        static bool SetSymLink(InstallationContext* pContext);
   static bool PrepareDataCaging(InstallationContext* pContext);
+  static bool SetFileCapability(const Tizen::Base::String& path, InstallationContext* pContext);
 
 }; // PermissionManager
 
index b5d5a48..510b0f1 100755 (executable)
@@ -236,6 +236,9 @@ UninstallStep::OnStateRemoveDir(void)
        InstallerError error = INSTALLER_ERROR_NONE;
        bool res = true;
 
+       CompatibilityManager compatibilityManager;
+       compatibilityManager.Construct(__pContext);
+
        String rootPath;
        rootPath = __pContext->__rootPath;
        AppLog("rootPath = [%ls]", rootPath.GetPointer());
@@ -246,7 +249,7 @@ UninstallStep::OnStateRemoveDir(void)
        result r = GetLastResult();
        if (r == E_SUCCESS && ospCompat == true)
        {
-               if (CompatibilityManager::FinalizeDataCaging(rootPath) == false)
+               if (compatibilityManager.FinalizeDataCaging(rootPath) == false)
                {
                        AppLog("[Tizen::Io] Failed to unmount directories for 2.0 application, appRootPath: %ls",
                                        rootPath.GetPointer());
@@ -259,13 +262,14 @@ UninstallStep::OnStateRemoveDir(void)
                return INSTALLER_ERROR_UNMOUNT_FAILED;
        }
 
-       CompatibilityManager::CleanDirectories(rootPath, __pContext->__packageId);
+       compatibilityManager.CleanDirectories(rootPath, __pContext->__packageId);
+
 
-       String virtualRoot = rootPath + DIR_VIRTUAL_ROOT;
-       if (File::IsFileExist(virtualRoot) == true)
+       String virtualRootInfoFile = rootPath + VIRTUAL_ROOT_INFO_FILE;
+       if (File::IsFileExist(virtualRootInfoFile) == true)
        {
-               res = CompatibilityManager::FinalizeVirtualRoot(rootPath, __pContext->__packageId);
-               TryReturn(res == true, INSTALLER_ERROR_UNMOUNT_FAILED, "CompatibilityManager::FinalizeVirtualRoot(%ls) failed.", rootPath.GetPointer());
+               res = compatibilityManager.FinalizeVirtualRoot(rootPath, __pContext->__packageId);
+               TryReturn(res == true, INSTALLER_ERROR_UNMOUNT_FAILED, "compatibilityManager.FinalizeVirtualRoot(%ls) failed.", rootPath.GetPointer());
        }
 
        AppLog("Directory::Remove - START");
index 1521c5f..6335cda 100755 (executable)
@@ -635,10 +635,7 @@ ManifestHandler::OnVirtualEnvironmentStartElement()
        char* pVirtualRootPath = pAttr->Find("VirtualRootPath");
        TryReturn(pVirtualRootPath, false, "pVirtualRootPath is null.");
 
-       if (strcasecmp(pVirtualRootPath, "true") == 0)
-       {
-               __pContext->__isVirtualRoot = true;
-       }
+       __pContext->__virtualRootPath = pVirtualRootPath;
 
        AppLog("<VirtualEnvironment VirtualRootPath=\"%s\">", pVirtualRootPath);