/* * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "vold" #include "Ntfs.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "Utils.h" namespace android { namespace vold { namespace ntfs { static char FSCK_NTFS_PATH[] = "/system/bin/ntfsck"; static char MKNTFS_PATH[] = "/system/bin/mkntfs"; static char LOGWRAP_PATH[] = "/system/bin/logwrapper"; static char MOUNT_PATH[] = "/system/bin/ntfs-3g"; static const int QUICK_CHECK_OK = 0; static const int CHECK_OK = 1; static const int FIXED_OK = 2; static const int MINOR_OK = 3; static const int CHECK_NG = 9; static const int RWXRXRX = 0755; status_t check(const std::string& fsPath) { if (access(FSCK_NTFS_PATH, X_OK)) { SLOGW("Skipping fs checks\n"); return 0; } int rc = 0; do { std::vector cmd; cmd.push_back(LOGWRAP_PATH); cmd.push_back(FSCK_NTFS_PATH); cmd.push_back("-a"); cmd.push_back(fsPath); rc = ForkExecvp(cmd); switch (rc) { case QUICK_CHECK_OK: SLOGI("Filesystem quick check completed OK"); return 0; case CHECK_OK: SLOGI("Filesystem check completed OK"); return 0; case FIXED_OK: SLOGI("Filesystem fixed completed OK"); return 0; case MINOR_OK: SLOGI("Filesystem minor OK"); return 0; case CHECK_NG: SLOGE("Filesystem check failed (not a NTFS filesystem)"); errno = ENODATA; return -1; default: SLOGE("Filesystem check failed (unknown exit code %d)", rc); errno = EIO; return -1; } } while (0); return 0; } status_t doMount(const std::string& fsPath, const std::string& mountPoint, bool ro, bool remount, bool executable, int ownerUid, int ownerGid, int permMask, bool createLost) { int rc; int len; std::string flags; std::string mountData; std::vector cmd; SLOGE("Filesystem doMount NTFS enter... (%s) (%s)", fsPath.c_str(), mountPoint.c_str()); flags = "nodev,nosuid,nodirsync,"; flags += (ro ? "ro," : ""); flags += (remount ? "remount," : ""); // "nls=utf8,uid=%d,gid=%d,fmask=%o,dmask=%o", ownerUid, ownerGid, permMask, permMask mountData = "nls=utf8,uid=" + ((std::ostringstream() << std::dec << ownerUid).str()) + ",gid=" + ((std::ostringstream() << std::dec << ownerGid).str()) + ",fmask=" + ((std::ostringstream() << std::oct << permMask).str()) + ",dmask=" + ((std::ostringstream() << std::oct << permMask).str()); cmd.push_back(LOGWRAP_PATH); cmd.push_back(MOUNT_PATH); cmd.push_back("-o"); cmd.push_back(mountData.c_str()); cmd.push_back(fsPath); cmd.push_back(mountPoint); rc = ForkExecvp(cmd); if (rc) SLOGE("ufsd mount error ! rc = %d", rc); if (rc == 0 && createLost) { std::string lost_path = mountPoint + "/LOST.DIR"; FILE *file = fopen(lost_path.c_str(), "r"); if (file == NULL) { /* * Create a LOST.DIR in the root so we have somewhere to put * lost cluster chains (fsck_msdos doesn't currently do this) */ if (mkdir(lost_path.c_str(), RWXRXRX)) { SLOGE("Unable to create LOST.DIR (%d)", errno); } } else { fclose(file); } } return rc; } status_t format(const std::string& fsPath, unsigned int numSectors) { int rc; std::vector cmd; cmd.push_back(LOGWRAP_PATH); cmd.push_back(MKNTFS_PATH); cmd.push_back("-F"); if (numSectors) { cmd.push_back("-b"); cmd.push_back(((std::ostringstream() << std::dec << numSectors).str())); cmd.push_back(fsPath); } else { cmd.push_back(fsPath); } rc = ForkExecvp(cmd); if (rc == 0 || rc == 1) { SLOGI("Filesystem formatted OK"); return 0; } else { SLOGE("Format failed (unknown exit code %d)", rc); errno = EIO; return -1; } return 0; } } // namespace ntfs } // namespace vold } // namespace android