Add file lock to avoid adding the duplicated registry section by multi-process
[platform/framework/native/appfw.git] / src / io / FIo_FileImpl.cpp
index 6b96261..60e73f9 100644 (file)
@@ -1,5 +1,4 @@
 //
-// Open Service Platform
 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
 //
 // Licensed under the Apache License, Version 2.0 (the License);
@@ -30,6 +29,7 @@
 #include <errno.h>
 #include <new>
 #include <unique_ptr.h>
+#include <fcntl.h>
 
 #include <FBaseSysLog.h>
 #include <FAppPkgPackageInfo.h>
@@ -42,6 +42,7 @@
 #include <FApp_AppInfo.h>
 #include <FAppPkg_PackageInfoImpl.h>
 #include <FSys_EnvironmentImpl.h>
+#include <FBase_NativeError.h>
 
 #include "FIo_FileImpl.h"
 #include "FIo_NormalFile.h"
@@ -50,6 +51,7 @@
 #include "FIo_SecureIoUtil.h"
 #include "FIo_IFileCore.h"
 #include "FIo_FileUtil.h"
+#include "FIo_FileLockImpl.h"
 
 using namespace std;
 using namespace Tizen::Base;
@@ -60,7 +62,6 @@ namespace Tizen { namespace Io
 {
 
 static const int _MAX_PATH_LENGTH = 128;
-static const int _APP_UID = 5000;
 static const size_t _MAX_FILE_OPENMODE_LENGTH = 3;
 static const char _INTERNAL_MOUNT_FLAG[] = "/tmp/osp-compat/mount/internal";
 static const char _EXTERNAL_MOUNT_FLAG[] = "/tmp/osp-compat/mount/external";
@@ -80,7 +81,7 @@ struct _LinkDir
 
 struct _PathInfo
 {
-    char destPath[_MAX_PATH_LENGTH];
+    char pathName[_MAX_PATH_LENGTH];
 };
 
 _FileImpl::_FileImpl(void)
@@ -89,12 +90,17 @@ _FileImpl::_FileImpl(void)
        , __write(false)
        , __truncate(false)
        , __append(false)
+       , __pFileLockImpl(null)
 {
 }
 
 _FileImpl::~_FileImpl(void)
 {
        delete __pCore;
+       if (__pFileLockImpl != null)
+       {
+               __pFileLockImpl->__pFileImpl = null;
+       }
 }
 
 _FileImpl::_FileImpl(const _FileImpl& fileImpl)
@@ -393,6 +399,131 @@ _FileImpl::GetFilePointer(void) const
        return __pCore->GetFilePointer();
 }
 
+FileLock*
+_FileImpl::LockN(FileLockType lockType)
+{
+       SysAssertf(__pCore != null, "Not yet constructed. Construct() should be called before use.\n");
+       return LockN(lockType, FILE_LOCK_MODE_BLOCKING, 0, 0);
+}
+
+FileLock*
+_FileImpl::LockN(FileLockType lockType, int offset, int length)
+{
+       SysAssertf(__pCore != null, "Not yet constructed. Construct() should be called before use.\n");
+       return LockN(lockType, FILE_LOCK_MODE_BLOCKING, offset, length);
+}
+
+FileLock*
+_FileImpl::TryToLockN(FileLockType lockType)
+{
+       SysAssertf(__pCore != null, "Not yet constructed. Construct() should be called before use.\n");
+       return LockN(lockType, FILE_LOCK_MODE_NON_BLOCKING, 0, 0);
+}
+
+FileLock*
+_FileImpl::TryToLockN(FileLockType lockType, int offset, int length)
+{
+       SysAssertf(__pCore != null, "Not yet constructed. Construct() should be called before use.\n");
+       return LockN(lockType, FILE_LOCK_MODE_NON_BLOCKING, offset, length);
+}
+
+FileLock*
+_FileImpl::LockN(FileLockType lockType, _FileLockMode lockMode, int offset, int length)
+{
+       SysAssertf(__pCore != null, "Not yet constructed. Construct() should be called before use.\n");
+       SysTryReturn(NID_IO, offset >= 0, null, E_INVALID_ARG, "[E_INVALID_ARG] The specified offset is negative.");
+       SysTryReturn(NID_IO, length >= 0, null, E_INVALID_ARG, "[E_INVALID_ARG] The specified length is negative.");
+
+       struct flock lock;
+       switch (lockType)
+       {
+       case FILE_LOCK_SHARED:
+               SysTryReturn(NID_IO, __read == true, null, E_INVALID_OPERATION, "[E_INVALID_OPERATION] File is not opened for reading.");
+               lock.l_type = F_RDLCK;
+               break;
+       case FILE_LOCK_EXCLUSIVE:
+               SysTryReturn(NID_IO, __write == true, null, E_INVALID_OPERATION, "[E_INVALID_OPERATION] File is not opened for writing.");
+               lock.l_type = F_WRLCK;
+               break;
+       default:
+               SysLogException(NID_IO, E_INVALID_ARG, "[E_INVALID_ARG] The specified lock type is invalid.");
+               return null;
+       }
+
+       int fd = fileno(this->GetFilePointer());
+       int lockCommand = -1;
+       int ret = -1;
+       switch (lockMode)
+       {
+       case FILE_LOCK_MODE_BLOCKING:
+               lockCommand = F_SETLKW;
+               break;
+       case FILE_LOCK_MODE_NON_BLOCKING:
+       {
+               lockCommand = F_SETLK;
+               break;
+       }
+       default:
+               SysLogException(NID_IO, E_INVALID_ARG, "[E_INVALID_ARG] The specified lock mode is invalid.");
+               return null;
+       }
+
+       lock.l_whence = SEEK_SET;
+       lock.l_start = offset;
+       lock.l_len = length;
+       lock.l_pid = getpid();
+
+       ret = fcntl(fd, lockCommand, &lock);
+       if (ret != 0)
+       {
+               result r = E_SUCCESS;
+               switch (errno)
+               {
+               case ENOLCK:
+                       r = E_MAX_EXCEEDED;
+                       break;
+               case EDEADLK:
+               {
+                       if (lockMode == FILE_LOCK_MODE_BLOCKING)
+                       {
+                               r = E_WOULD_DEADLOCK;
+                       }
+                       else
+                       {
+                               r = E_SYSTEM;
+                       }
+                       break;
+               }
+               case EAGAIN:
+                       // fall through
+               case EACCES:
+                       if (lockMode == FILE_LOCK_MODE_NON_BLOCKING)
+                       {
+                               r = E_OBJECT_LOCKED;
+                               break;
+                       }
+                       // else fall through
+               case EFAULT:
+                       // fall through
+               case EBADF:
+                       r = E_SYSTEM;
+                       break;
+               default:
+                       r = _NativeError::ConvertNativeErrorToResult(errno, true);
+                       break;
+               }
+
+               SysLogException(NID_IO, r, "[%s] Aquiring file lock of type (%d) is failed, errno: %d (%s)", GetErrorMessage(r), lockType, errno, strerror(errno));
+               return null;
+       }
+
+       unique_ptr<FileLock> pFileLock(_FileLockImpl::CreateFileLockInstanceN(this, lockType, lock.l_start, lock.l_len, lock.l_pid));
+       SysTryReturn(NID_IO, pFileLock != null, null, GetLastResult(), "[%s] Propagating to caller....", GetErrorMessage(GetLastResult()));
+       __pFileLockImpl = _FileLockImpl::GetInstance(*pFileLock);
+       SetLastResult(E_SUCCESS);
+       return pFileLock.release();
+}
+
 result
 _FileImpl::Remove(const String& filePath)
 {
@@ -434,22 +565,12 @@ _FileImpl::GetAttributes(const String& filePath, FileAttributes& attribute)
 String
 _FileImpl::GetFileName(const String& filePath)
 {
-       String fileName;
-       SysTryReturn(NID_IO, VerifyFilePathCompatibility(filePath, _AppInfo::IsOspCompat()) == true, fileName, E_INVALID_ARG,
-                       "[E_INVALID_ARG] The length of the specified filePath (%ls) is zero or exceeds system limitations.",
-                       filePath.GetPointer());
-
        return _FileUtil::GetFileName(filePath);
 }
 
 String
 _FileImpl::GetFileExtension(const String& filePath)
 {
-       String extName;
-       SysTryReturn(NID_IO, VerifyFilePathCompatibility(filePath, _AppInfo::IsOspCompat()) == true, extName, E_INVALID_ARG,
-                       "[E_INVALID_ARG] The length of the specified filePath (%ls) is zero or exceeds system limitations.",
-                       filePath.GetPointer());
-
        return _FileUtil::GetFileExtension(filePath);
 }
 
@@ -503,592 +624,6 @@ _FileImpl::VerifyFilePath(const String& filePath, _FilePathType pathType)
 }
 
 bool
-_FileImpl::CleanDirectories(const String& appRootPath, const String& pkgId)
-{
-       char removeCmd[PATH_MAX] = {0, };
-       int ret = 0;
-
-       String ospSharePkgIdPath = _EnvironmentImpl::GetOspCompatSharedPath();
-       ospSharePkgIdPath.Append(L"share/");
-       ospSharePkgIdPath.Append(pkgId);
-
-       String ospShare2PkgIdPath = _EnvironmentImpl::GetOspCompatSharedPath();
-       ospShare2PkgIdPath.Append(L"share2/");
-       ospShare2PkgIdPath.Append(pkgId);
-
-#if 0
-       r = Directory::Remove(ospSharePkgIdPath, true);
-       SysTryReturn(NID_IO, !IsFailed(r), false, E_SYSTEM, "[%s] Failed to remove directory (%ls)",
-                       GetErrorMessage(r), ospSharePkgIdPath.GetPointer());
-
-       r = Directory::Remove(ospShare2PkgIdPath, true);
-       SysTryReturn(NID_IO, !IsFailed(r), false, E_SYSTEM, "[%s] Failed to remove directory (%ls)",
-                       GetErrorMessage(r), ospShare2PkgIdPath.GetPointer());
-#else
-       sprintf(removeCmd, "rm -rf %ls", ospSharePkgIdPath.GetPointer());
-       ret = system(removeCmd);
-       SysTryReturn(NID_IO, ret != -1, false, E_SYSTEM, "Failed to remove directory (%ls)",
-                       ospSharePkgIdPath.GetPointer());
-
-       memset(removeCmd, 0, PATH_MAX);
-
-       sprintf(removeCmd, "rm -rf %ls", ospShare2PkgIdPath.GetPointer());
-       ret = system(removeCmd);
-       SysTryReturn(NID_IO, ret != -1, false, E_SYSTEM, "Failed to remove directory (%ls)",
-                       ospShare2PkgIdPath.GetPointer());
-#endif
-
-       return true;
-}
-
-// This method is called by package installer backend.
-bool
-_FileImpl::PrepareDataCaging(const String& appRootPath, const String& pkgId)
-{
-       int index = 0;
-       char* pCwd = null;
-       bool internalInstalled = true;
-       result r = E_SUCCESS;
-
-       SysLog(NID_IO, "[data_caging] PrepareDataCaging() was called by installer backend, appRootPath: %ls, packageId: %ls",
-                       appRootPath.GetPointer(), pkgId.GetPointer());
-
-       if (CleanDirectories(appRootPath, pkgId) == false)
-       {
-               SysLog(NID_IO, "CleanDirectories() failed.");
-               return false;
-       }
-
-       pCwd = get_current_dir_name();
-       SysTryCatch(NID_IO, pCwd != null, r = E_SYSTEM, E_SYSTEM,
-                          "[E_SYSTEM] get_current_dir_name() was failed, errno: %d (%s).", errno, strerror(errno));
-
-       // Check whether package is installed on internal storage or not
-       r = appRootPath.IndexOf("/opt/storage/sdcard", 0, index);
-       if (r == E_SUCCESS)
-       {
-               internalInstalled = false;
-       }
-       else
-       {
-               internalInstalled = true;
-       }
-
-       umask(0000);
-
-       if (internalInstalled == true)
-       {
-               unique_ptr<char[]> pAppRootPath(_StringConverter::CopyToCharArrayN(appRootPath));
-               SysTryCatch(NID_IO, pAppRootPath != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] The memory is insufficient.");
-
-               SysTryCatch(NID_IO, chdir(pAppRootPath.get()) == 0, r = E_SYSTEM, E_SYSTEM,
-                               "[E_SYSTEM] chdir() was failed (%s), path: %s", strerror(errno), pAppRootPath.get());
-
-               SysTryCatch(NID_IO, CreateOspInternalDirectories(pkgId) == true, r = E_SYSTEM, E_SYSTEM,
-                               "[E_SYSTEM] fail to create OSP Internal directories");
-       }
-       else
-       {
-               String appExRootPath(appRootPath);
-
-               int ret = 0;
-
-               appExRootPath.Append(pkgId);
-               unique_ptr<char[]> pAppExRootPath(_StringConverter::CopyToCharArrayN(appExRootPath));
-               SysTryCatch(NID_IO, pAppExRootPath != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] The memory is insufficient.");
-
-               ret = mkdir(pAppExRootPath.get(), 0705);
-               if (ret == -1 && errno != 17) // EEXIST
-               {
-                       SysLog(NID_IO, "mkdir() failed (%s), path: %s, mode: 0%o",
-                                               strerror(errno), pAppExRootPath.get(), 0705);
-                       goto CATCH;
-               }
-
-               SysTryCatch(NID_IO, chdir(pAppExRootPath.get()) == 0, r = E_SYSTEM, E_SYSTEM,
-                               "[E_SYSTEM] chdir() was failed (%s), path: %s", strerror(errno), pAppExRootPath.get());
-               SysTryCatch(NID_IO, CreateOspExternalDirectories(pkgId) == true, r = E_SYSTEM, E_SYSTEM,
-                               "[E_SYSTEM] fail to create OSP External directories");
-       }
-
-       SysTryCatch(NID_IO, CreateSlpDirectories() == true, r = E_SYSTEM, E_SYSTEM,
-                       "[E_SYSTEM] fail to create SLP directories");
-       SysTryCatch(NID_IO, CreateSymbolicLink() == true, r = E_SYSTEM, E_SYSTEM,
-                       "[E_SYSTEM] Fail to create symbolic link.");
-       SysTryCatch(NID_IO, chdir(pCwd) == 0, r = E_SYSTEM, E_SYSTEM,
-                       "[E_SYSTEM] chdir() was failed (%s), path: %s", strerror(errno), pCwd);
-
-       r = E_SUCCESS;
-       SysLog(NID_IO, "[data_caging] PrepareDataCaging() succeeded.");
-
-       // fall thru
-CATCH:
-       if (pCwd != null)
-       {
-               free(pCwd);
-       }
-
-       umask(0022);
-
-       if (IsFailed(r))
-       {
-               SysLog(NID_IO, "[data_caging] PrepareDataCaging() failed.");
-               return false;
-       }
-
-       return true;
-}
-
-bool
-_FileImpl::FinalizeDataCaging(const String& appRootPath) // for 2.0 app
-{
-       static const struct _PathInfo mountPath[] =
-       {
-               //{ "./bin" },
-               //{ "./boot" },
-               //{ "./cache" },
-               { "./csa" },
-               { "./dev/pts" },
-               { "./dev/shm" },
-               { "./dev" },
-               { "./etc" },
-               { "./lib" },
-               //{ "./lost+found" },
-               { "./media" },
-               { "./mnt" },
-               { "./opt/usr" },
-               { "./opt/var/kdb/db" },
-               { "./opt/storage/sdcard" },
-               { "./opt" },
-               //{ "./packaging" },
-               { "./proc" },
-               { "./sbin" },
-               { "./srv" },
-               { "./sys/kernel/debug" },
-               { "./sys" },
-               { "./tmp" },
-               { "./usr" },
-               { "./var/run" },
-               { "./var" },
-
-               { "./data/Share" },
-               { "./data/Share2" },
-               { "./Share" },
-               { "./Share2" },
-               //{ "./Clipboard" },
-               //{ "./NPKI" },
-               //{ "./System" },
-               //{ "./Tmp" },
-               { "./Media" },
-
-               { "./Storagecard/Media" },
-        { "./ShareExt" },
-        { "./Share2Ext" },
-        { "./HomeExt/Share" },
-        { "./HomeExt/Share2" },
-        { "./HomeExt" }
-       };
-
-       unique_ptr< char[] > pAppRootPath(_StringConverter::CopyToCharArrayN(appRootPath));
-       SysTryReturn(NID_IO, pAppRootPath != null, false, E_OUT_OF_MEMORY,
-                       "[E_OUT_OF_MEMORY] The memory is insufficient.");
-
-       SysTryReturn(NID_IO, chdir(pAppRootPath.get()) == 0, false, E_SYSTEM,
-                       "[E_SYSTEM] chdir() failed (%d, %s), path: %ls", errno, strerror(errno), appRootPath.GetPointer());
-
-       for (int i = 0; i < sizeof(mountPath) / sizeof(struct _PathInfo); ++i)
-       {
-               int ret = umount2(mountPath[i].destPath, MNT_DETACH);
-               SysTryLog(NID_IO, ret == 0, "umount2() errno: %d (%s)", errno, strerror(errno));
-               SysTryReturn(NID_IO, ret == 0 || errno == EINVAL || errno == ENOENT, false, E_SYSTEM,
-                               "[E_SYSTEM] umount2() failed (%d, %s), path: %s", errno, strerror(errno), mountPath[i].destPath);
-       }
-
-       char* pkgId = strrchr(pAppRootPath.get(), '/');
-       char mountFlag[_MAX_PATH_LENGTH] = { 0, };
-       sprintf(mountFlag, "%s/%s", _INTERNAL_MOUNT_FLAG, ++pkgId);
-       int res = unlink(mountFlag);
-       if (res == -1 && errno != ENOENT)
-       {
-               SysLogException(NID_IO, E_SYSTEM, "[E_SYSTEM] Failed to remove mount flag (%s), errno: %d (%s)",
-                               mountFlag, errno, strerror(errno));
-               return false;
-       }
-
-       memset(mountFlag, 0, _MAX_PATH_LENGTH);
-       sprintf(mountFlag, "%s/%s", _EXTERNAL_MOUNT_FLAG, pkgId);
-       res = unlink(mountFlag);
-       if (res == -1 && errno != ENOENT)
-       {
-               SysLogException(NID_IO, E_SYSTEM, "[E_SYSTEM] Failed to remove mount flag (%s), errno: %d (%s)",
-                               mountFlag, errno, strerror(errno));
-               return false;
-       }
-
-       SysLog(NID_IO, "[data_caging] FinalizeDataCaging() succeeded, appRootPath: %ls", appRootPath.GetPointer());
-       return true;
-}
-
-int
-_FileImpl::GetAvailableUid(void)
-{
-       return _APP_UID;
-}
-
-bool
-_FileImpl::CreateOspApplicationDirectories(const String& appRootPath, const String& pkgId) // for 2.1 app
-{
-       struct _OspDir appSubDir[] =
-       {
-               { "./shared\0",                 0755, false },
-               //{ "./shared/data\0",  0755, true },
-               { "./shared/res\0",             0755, false },
-               { "./shared/trusted\0", 0755, true },
-               //{ "./cache\0", 0700, true }
-       };
-       int uid = -1;
-       int ret = 0;
-       unsigned int i = 0;
-       result r = E_SUCCESS;
-
-       SysTryReturn(NID_IO, CleanDirectories(appRootPath, pkgId) == true, false, E_SYSTEM,
-                       "[E_SYSTEM] Failed to clean directories for 2.0 application compatibility.");
-
-       unique_ptr<char[]> pAppRootPath(_StringConverter::CopyToCharArrayN(appRootPath));
-       SysTryReturn(NID_IO, pAppRootPath != null, false, E_SYSTEM, "[E_SYSTEM] The memory is insufficient.");
-
-       SysTryReturn(NID_IO, chdir(pAppRootPath.get()) == 0, false, E_SYSTEM,
-                       "[E_SYSTEM] chdir() failed (%d, %s), path: %s", errno, strerror(errno), pAppRootPath.get());
-
-       uid = GetAvailableUid();
-
-       umask(0000);
-
-       for (i = 0; i < sizeof(appSubDir) / sizeof(struct _OspDir); ++i)
-       {
-               ret = mkdir(appSubDir[i].path, appSubDir[i].mode);
-               if (ret == -1 && errno != 17) // EEXIST
-               {
-                       SysLog(NID_IO, "[E_SYSTEM] mkdir() failed (%d, %s), path: %s, mode: 0%o",
-                                       errno, strerror(errno), appSubDir[i].path, appSubDir[i].mode);
-                       goto CATCH;
-               }
-
-               if (appSubDir[i].appPrivilege)
-               {
-                       ret = chown(appSubDir[i].path, uid, uid);
-                       SysTryCatch(NID_IO, ret == 0, , E_SYSTEM,
-                                       "[E_SYSTEM] chown() failed (%d, %s), path: %s, uid: %d",
-                                       errno, strerror(errno), appSubDir[i].path, uid);
-               }
-       }
-
-       if (access("./shared/data", F_OK) == 0)
-       {
-               SysTryCatch(NID_IO, system("chown -R 5000:5000 ./shared/data") != -1, , E_SYSTEM,
-                               "[E_SYSTEM] chown() failed");
-       }
-       // XXX: Temp code for supporting old share directory.
-       else if (access("./share", F_OK) == 0)
-       {
-               SysTryCatch(NID_IO, system("rm -rf ./shared/data") != -1, , E_SYSTEM,
-                               "[E_SYSTEM] Failed to remove ./shared/data directory");
-               
-               SysTryCatch(NID_IO, rename("./share", "./shared/data") == 0, , E_SYSTEM,
-                               "[E_SYSTEM] Failed to rename share directory (%d, %s)", errno, strerror(errno));
-
-               SysTryCatch(NID_IO, system("chown -R 5000:5000 ./shared/data") != -1, , E_SYSTEM,
-                               "[E_SYSTEM] chown() failed");
-
-               SysTryCatch(NID_IO, chmod("./shared/data", 0755) == 0, , E_SYSTEM, "[E_SYSTEM] chmod() failed");
-       }
-       // XXX-end
-
-       umask(0022);
-
-       SysLog(NID_IO, "_FileImpl::CreateOspApplicationDirectories() succeeded.");
-       return true;
-
-CATCH:
-       umask(0022);
-
-       return false;
-}
-
-bool
-_FileImpl::CreateOspInternalDirectories(const String& pkgId) // for 2.0 app
-{
-       unsigned int i = 0;
-       int ret = 0;
-       int uid = -1;
-       struct _OspDir appSubDir[] =
-       {
-//             { "./data",                     0700, true },   // It is created by installer.
-               { "./shared",           0755, false },
-               { "./data/Share",       0000, true },   // mount from /opt/usr/share/.osp-compat/share/{pkgId}
-               { "./data/Share2",      0000, true },   // mount from /opt/usr/share/.osp-compat/share2/{pkgId}
-               { "./Share",            0000, false },  // mount from /opt/usr/share/.osp-compat/share
-               { "./Share2",           0000, false },  // mount from /opt/usr/share/.osp-compat/share2
-//             { "./Clipboard",        0000, false },
-//             { "./NPKI",                     0000, false },
-//             { "./System",           0000, false },
-//             { "./Tmp",                      0000, false },
-               { "./Media",            0000, false },  // mount from /opt/usr/media
-               { "./Storagecard",      0705, false },
-               { "./Storagecard/Media", 0000, false }, // mount from /opt/storage/sdcard
-       };
-#if 1
-       struct _OspDir mediaDir[] =
-       {
-               { "/opt/usr/media/Images", 0777, false },
-               { "/opt/usr/media/Sounds", 0777, false },
-               { "/opt/usr/media/Videos", 0777, false },
-               //{ "/opt/usr/media/Themes", 0777, false },
-               { "/opt/usr/media/Others", 0777, false }
-       };
-#endif
-       String ospCompatSharedPath = _EnvironmentImpl::GetOspCompatSharedPath();
-       String ospShareAppIdPath(L"share/");
-       String ospShare2AppIdPath(L"share2/");
-       result r = E_SUCCESS;
-
-       r = ospShareAppIdPath.Insert(ospCompatSharedPath, 0);
-       SysTryReturn(NID_IO, !IsFailed(r), false, E_SYSTEM,
-                       "[E_SYSTEM] String::Insert() failed. (error: %s)", GetErrorMessage(r));
-
-       r = ospShare2AppIdPath.Insert(ospCompatSharedPath, 0);
-       SysTryReturn(NID_IO, !IsFailed(r), false, E_SYSTEM,
-                       "[E_SYSTEM] String::Insert() failed. (error: %s)", GetErrorMessage(r));
-
-       uid = GetAvailableUid();
-
-       for (i = 0; i < sizeof(appSubDir) / sizeof(struct _OspDir); i++)
-       {
-               ret = mkdir(appSubDir[i].path, appSubDir[i].mode);
-               if (ret == -1 && errno != 17) // EEXIST
-               {
-                       SysLog(NID_IO, "mkdir() failed (%s), path: %s, mode: 0%o",
-                                               strerror(errno), appSubDir[i].path, appSubDir[i].mode);
-                       return false;
-               }
-               if (appSubDir[i].appPrivilege)
-               {
-                       ret = chown(appSubDir[i].path, uid, uid);
-                       if (ret == -1)
-                       {
-                               SysLog(NID_IO, "chown() failed (%s), path: %s, uid: %d",
-                                                       strerror(errno), appSubDir[i].path, uid);
-                               return false;
-                       }
-               }
-       }
-
-       ospShareAppIdPath.Append(pkgId);
-       unique_ptr<char[]> pOspShareAppIdPath(_StringConverter::CopyToCharArrayN(ospShareAppIdPath));
-       SysTryReturn(NID_IO, pOspShareAppIdPath != null, false, E_SYSTEM, "[E_SYSTEM] The memory is insufficient.");
-       ret = mkdir(pOspShareAppIdPath.get(), 0705);
-       if (ret == -1 && errno != 17) // EEXIST
-       {
-               SysLog(NID_IO, "mkdir() failed (%s), path: %s, mode: 0%o",
-                                       strerror(errno), pOspShareAppIdPath.get(), 0705);
-               return false;
-       }
-       ret = chown(pOspShareAppIdPath.get(), uid, uid);
-       if (ret == -1)
-       {
-               SysLog(NID_IO, "chown() failed (%s), path: %s, uid: %d",
-                                       strerror(errno), pOspShareAppIdPath.get(), uid);
-               return false;
-       }
-
-       ospShare2AppIdPath.Append(pkgId);
-       unique_ptr<char[]> pOspShare2AppIdPath(_StringConverter::CopyToCharArrayN(ospShare2AppIdPath));
-       SysTryReturn(NID_IO, pOspShare2AppIdPath != null, false, E_SYSTEM, "[E_SYSTEM] The memory is insufficient.");
-       ret = mkdir(pOspShare2AppIdPath.get(), 0705);    // TODO: change to 0770
-       if (ret == -1 && errno != 17) // EEXIST
-       {
-               SysLog(NID_IO, "mkdir() failed (%s), path: %s, mode: 0%o",
-                                       strerror(errno), pOspShare2AppIdPath.get(), 0705);
-               return false;
-       }
-       ret = chown(pOspShare2AppIdPath.get(), uid, uid);
-       if (ret == -1)
-       {
-               SysLog(NID_IO, "chown() failed (%s), path: %s, uid: %d",
-                                       strerror(errno), pOspShare2AppIdPath.get(), uid);
-               return false;
-       }
-
-#if 1
-       for (i = 0; i < sizeof(mediaDir) / sizeof(struct _OspDir); ++i)
-       {
-               ret = mkdir(mediaDir[i].path, mediaDir[i].mode);
-               if (ret == -1 && errno != 17) // EEXIST
-               {
-                       SysLog(NID_IO, "mkdir() failed (%s), path: %s, mode: 0%o",
-                                       strerror(errno), mediaDir[i].path, mediaDir[i].mode);
-                       return false;
-               }
-               ret = chown(mediaDir[i].path, 5000, 5000);
-               SysTryReturn(NID_IO, ret == 0, false, E_SYSTEM,
-                               "[E_SYSTEM] chown() failed (%d, %s), path: %s, uid: 5000, gid: 5000",
-                               errno, strerror(errno), mediaDir[i].path);
-       }
-#endif
-
-       // XXX: shared directory is not supported for 2.0 applications
-#if 0
-       if (access("./shared/data", F_OK) == 0)
-       {
-               char copyCmd[256] = { 0, };
-               sprintf(copyCmd, "cp -rf ./shared/data/* /opt/usr/share/.osp-compat/share/%ls/", pkgId.GetPointer());
-               ret = system(copyCmd);
-               SysTryReturn(NID_IO, ret != -1, false, E_SYSTEM, "Failed to copy command (%s)", copyCmd);
-
-               SysTryReturn(NID_IO, system("rm -rf ./shared/data") != -1, false, E_SYSTEM,
-                       "[E_SYSTEM] rmdir() failed, path: ./shared/data");
-
-               char chownCmd[256] = { 0, };
-               sprintf(chownCmd, "chown -R 5000:5000 /opt/usr/share/.osp-compat/share/%ls/", pkgId.GetPointer());
-               SysTryReturn(NID_IO, system(chownCmd) != -1, false, E_SYSTEM, "[E_SYSTEM] chown() failed");
-
-               char symlinkCmd[256] = { 0, };
-               sprintf(symlinkCmd, "ln -s %s ./shared/data", pOspShareAppIdPath.get());
-               SysTryReturn(NID_IO, system(symlinkCmd) != -1, false, E_SYSTEM, "[E_SYSTEM] symlink() failed");
-       }
-#endif
-       char symlinkCmd[256] = { 0, };
-       sprintf(symlinkCmd, "ln -s %s ./shared/data", pOspShareAppIdPath.get());
-       SysTryReturn(NID_IO, system(symlinkCmd) != -1, false, E_SYSTEM, "[E_SYSTEM] symlink() failed");
-
-       return true;
-}
-
-// TODO: Need to test this method.
-bool
-_FileImpl::CreateOspExternalDirectories(const String& pkgId)
-{
-       unsigned int i = 0;
-       int ret = 0;
-       int uid = -1;
-       struct _OspDir appSubDir[] = { // virtual path
-//             { "./data", 0700, true },
-               { "./System", 0000, false },                // mount from /opt/apps/com.samsung.osp/system
-               { "./Storagecard", 0705, false },
-               { "./Storagecard/Media", 0000, false }          // mount from /opt/storage/sdcard
-       };
-#if 0
-       struct _OspDir mediaDir[] = { // physical path
-               { "/opt/usr/media/Images", 0777, false },
-               { "/opt/usr/media/Sounds", 0777, false },
-               { "/opt/usr/media/Videos", 0777, false },
-               //{ "/opt/usr/media/Themes", 0777, false },
-               { "/opt/usr/media/Others", 0777, false }
-       };
-#endif
-
-       for (i = 0; i < sizeof(appSubDir) / sizeof(struct _OspDir); i++)
-       {
-               ret = mkdir(appSubDir[i].path, appSubDir[i].mode);
-               if (ret == -1 && errno != 17) // EEXIST
-               {
-                       SysLog(NID_IO, "mkdir() failed (%s), path: %s, mode: 0%o",
-                                               strerror(errno), appSubDir[i].path, appSubDir[i].mode);
-                       return false;
-               }
-               if (appSubDir[i].appPrivilege)
-               {
-                       ret = chown(appSubDir[i].path, uid, uid);
-                       if (ret == -1)
-                       {
-                               SysLog(NID_IO, "chown() failed (%s), path: %s, uid: %d",
-                                                       strerror(errno), appSubDir[i].path, uid);
-                               return false;
-                       }
-               }
-       }
-
-#if 0
-       for (i = 0; i < sizeof(mediaDir) / sizeof(struct _OspDir); i++)
-       {
-               ret = mkdir(mediaDir[i].path, mediaDir[i].mode);
-               if (ret == -1 && errno != 17) // EEXIST
-               {
-                       SysLog(NID_IO, "mkdir() failed (%s), path: %s, mode: 0%o",
-                                               strerror(errno), mediaDir[i].path, mediaDir[i].mode);
-                       return false;
-               }
-       }
-#endif
-
-       return true;
-}
-
-bool
-_FileImpl::CreateSlpDirectories(void)
-{
-       unsigned int i = 0;
-       int ret = 0;
-       struct _OspDir slpDir[] = { // virtual path
-               //{ "./bin", 0000, false },     // mount from /bin
-               //{ "./boot", 0000,     false },
-               //{ "./cache", 0000, false },
-               { "./csa", 0000, false },
-               { "./dev", 0000, false },
-               { "./etc", 0000, false },
-               { "./lib", 0000, false },
-               //{ "./lost+found",     0000, false },
-               { "./media", 0000, false },
-               { "./mnt", 0000, false },
-               { "./opt", 0000, false },
-               //{ "./packaging", 0000, false },
-               { "./proc", 0000, false },
-               { "./sbin", 0000, false },
-               { "./srv", 0000, false },
-               { "./sys", 0000, false },
-               { "./tmp", 0000, false },
-               { "./usr", 0000, false },
-               { "./var", 0000, false }
-       };
-
-       for (i = 0; i < sizeof(slpDir) / sizeof(struct _OspDir); i++)
-       {
-               ret = mkdir(slpDir[i].path, slpDir[i].mode);
-               if (ret == -1 && errno != 17) // EEXIST
-               {
-                       SysLog(NID_IO, "mkdir() failed (%s), path: %s, mode: 0%o",
-                                               strerror(errno), slpDir[i].path, slpDir[i].mode);
-                       return false;
-               }
-       }
-
-       return true;
-}
-
-bool
-_FileImpl::CreateSymbolicLink(void)
-{
-       struct _LinkDir linkDirList[] = {
-               { "/opt/home",          "./home" },
-               { "/opt/home/root",     "./root" },
-               { "/mnt/mmc",           "./sdcard" }
-       };
-
-       for (unsigned int i = 0; i < sizeof(linkDirList) / sizeof(struct _LinkDir); ++i)
-       {
-               int ret = symlink(linkDirList[i].srcPath, linkDirList[i].destPath);
-               if (ret == -1 && errno != 17) // EEXIST
-               {
-                       SysLog(NID_IO, "Failed to create symbolic link, errno: %d (%s), src path: %s, dest path: %s",
-                                       strerror(errno), linkDirList[i].srcPath, linkDirList[i].destPath);
-                       return false;
-               }
-       }
-
-       return true;
-}
-
-bool
 _FileImpl::VerifyFilePathCompatibility(const String& filePath, bool ospCompat)
 {
        if (ospCompat == true)
@@ -1208,9 +743,11 @@ _FileImpl::ConvertVirtualToPhysicalPath(const String& virtualPath, String& physi
                break;
        case 7:
                physicalPath = Tizen::System::Environment::GetMediaPath();
+               physicalPath.SetLength(physicalPath.GetLength() - 1);
                break;
        case 8:
-               physicalPath = Tizen::System::Environment::GetExternalStoragePath() + L"Media";
+               physicalPath = Tizen::System::Environment::GetExternalStoragePath();
+               physicalPath.SetLength(physicalPath.GetLength() - 1);
                break;
        default:
                SysLog(NID_IO, "[E_INVALID_ARG] The path (%ls) is not matched.",