CyanogenMod 10 修改 Vold 使 Android 自动挂载 NTFS 和 exFAT 格式的 SD 卡


  2572人阅读  评论(4)  收藏  举报
Android NTFS exFAT 自动挂载 源代码

目录(?)[+]

Android 不支持 NTFS 和 exFAT 格式的文件系统,但是 Linux 已经有相应的开源代码了,因此只需将其移植到 Android 上即可。

这里需要下载两份代码,分别是 ntfs-3g 和 exfat。下载地址 ntfs-3g exfat 。

由于 Android 并没有使用完整的 glibc 库,因此需要对源代码进行修改以使代码能被顺利地编译。


代码与编译好的文件都可以在 CSDN 资源里下载:

        CyanogenMod10 ntfs 与 exfat 自动挂载支持


一、修改 ntfs-3g 代码

       关于 ntfs-3g 代码的修改,可以参考 CSDN 上的这篇文章:ntfs-3g移植到android4.0.3方法总结。这里就不在重复叙述了。


二、修改 exfat 代码

        exfat 也是使用了 fuse,但代码量很小。需要修改的地方不多:

        1、fuse/main.c 文件

                大约位于 264 行的 fuse_exfat_statfs 函数,将参数中的 statvfs 改为 statfs,并将其代码中的 sfs->f_namemax 改为 sfs->f_namelen

                将                 

[cpp]  view plain copy
  1. sfs->f_favail = sfs->f_bfree >> ef.sb->spc_bits;  
  2. sfs->f_ffree = sfs->f_bavail;  
                 改为

[cpp]  view plain copy
  1. sfs->f_ffree = sfs->f_bfree >> ef.sb->spc_bits;  

        2、libexfat/io.c 

                大约位于 255 行的 exfat_seek 函数,将里面的 lseek 函数改为 lseek64;

                大约位于 283 行的 exfat_pread 函数,将里面的 pread 函数改为 pread64;

                大约位于 295 行的 exfat_pwrite 函数,将里面的 pwrite 函数改为 pwrite64。

        3、将所有代码文件中的 off_t 类型全部换为 off64_t 类型

                Android 的编译器编译出来的 off_t 类型是4字节的,只有改为 off64_t 才是8字节的。不改的话无法挂载超过 4G 的 SD 卡或 U 盘。


三、提取文件,编写 Android.mk 文件

        这里我将所有的项目都放在了和 vold 同级的 system 目录下

        1、libfuse

                由于 ntfs-3g 和 exfat 都使用了 fuse,因此他们可以共享这个库。

                在 system 目录新建 libfuse 文件夹,并建立子文件夹 src 和 include。将 ntfs-3g 中 libfuse-lite 中的所有文件复制到 libfuse/src 目录中,将 ntfs-3g 中 include/fuse-lite 中的所有文件复制到 libfuse/include 目录中,将 ntfs-3g 中的 config.h 复制到 libfuse 目录。

                修改 libfuse/src/helper.c,在最后添加如下代码(exfat 需要):

[cpp]  view plain copy
  1. int fuse_daemonize(int foreground)  
  2. {  
  3.     int res;  
  4.   
  5.     if (!foreground) {  
  6.         res = daemon(0, 0);  
  7.         if (res == -1) {  
  8.             perror("fuse: failed to daemonize program\n");  
  9.             return -1;  
  10.         }  
  11.     }  
  12.     return 0;  
  13. }  

                在 libfuse 目录编写 Android.mk:

[plain]  view plain copy
  1. LOCAL_PATH:= $(call my-dir)  
  2.   
  3. include $(CLEAR_VARS)  
  4.   
  5. LOCAL_SRC_FILES:= \  
  6.     src/fuse.c \  
  7.     src/fusermount.c \  
  8.     src/fuse_kern_chan.c \  
  9.     src/fuse_loop.c \  
  10.     src/fuse_lowlevel.c \  
  11.     src/fuse_opt.c \  
  12.     src/fuse_session.c \  
  13.     src/fuse_signals.c \  
  14.     src/helper.c \  
  15.     src/mount.c \  
  16.     src/mount_util.c  
  17.   
  18. LOCAL_C_INCLUDES:= $(LOCAL_PATH)/include  
  19. LOCAL_CFLAGS:= -O2 -g -W -Wall -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -DHAVE_CONFIG_H  
  20. LOCAL_MODULE:= libfuse  
  21. LOCAL_MODULE_TAGS:=eng  
  22. LOCAL_SYSTEM_SHARED_LIBRARIES:= libc libcutils  
  23.   
  24. include $(BUILD_STATIC_LIBRARY)  

        2、ntfs-3g

                则里只提取挂载 NTFS 分区的文件。

                在 system 目录新建 ntfs-3g 文件夹,并建立子文件夹 include、libntfs-3g 和 src。将 ntfs-3g 中 include/ntfs-3g 中的所有文件复制到 ntfs-3g/include 目录中,将 ntfs-3g 中 libntfs-3g 中的所有文件复制到 ntfs-3g/libntfs-3g 目录中,将 ntfs-3g 中 src 目录中的 ntfs-3g.c ntfs-3g_common.c ntfs-3g_common.h 复制到 ntfs-3g/src 目录中,将 ntfs-3g 中的 config.h 复制到 ntfs-3g 目录。

                在 ntfs-3g 目录中编写 Android.mk:

[plain]  view plain copy
  1. LOCAL_PATH:= $(call my-dir)  
  2.   
  3. include $(CLEAR_VARS)  
  4.   
  5. LOCAL_SRC_FILES:= \  
  6.     libntfs-3g/acls.c libntfs-3g/attrib.c libntfs-3g/attrlist.c \  
  7.     libntfs-3g/bitmap.c libntfs-3g/bootsect.c libntfs-3g/cache.c \  
  8.     libntfs-3g/collate.c libntfs-3g/compat.c libntfs-3g/compress.c \  
  9.     libntfs-3g/debug.c libntfs-3g/device.c libntfs-3g/dir.c \  
  10.     libntfs-3g/efs.c libntfs-3g/index.c libntfs-3g/inode.c \  
  11.     libntfs-3g/lcnalloc.c libntfs-3g/logfile.c libntfs-3g/logging.c \  
  12.     libntfs-3g/mft.c libntfs-3g/misc.c libntfs-3g/mst.c \  
  13.     libntfs-3g/object_id.c libntfs-3g/realpath.c libntfs-3g/reparse.c \  
  14.     libntfs-3g/runlist.c libntfs-3g/security.c libntfs-3g/unistr.c \  
  15.     libntfs-3g/unix_io.c libntfs-3g/volume.c  
  16.   
  17. LOCAL_C_INCLUDES:= $(LOCAL_PATH)/include system/libfuse/include  
  18. LOCAL_CFLAGS:= -O2 -g -W -Wall -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -DHAVE_CONFIG_H  
  19. LOCAL_MODULE:= libntfs-3g  
  20. LOCAL_MODULE_TAGS:=eng  
  21. LOCAL_SYSTEM_SHARED_LIBRARIES:= libc libcutils  
  22.   
  23. include $(BUILD_STATIC_LIBRARY)  
  24.   
  25. include $(CLEAR_VARS)  
  26.   
  27. LOCAL_SRC_FILES:= \  
  28.     src/ntfs-3g.c src/ntfs-3g_common.c  
  29.   
  30. LOCAL_C_INCLUDES:= $(LOCAL_PATH)/include $(LOCAL_PATH)/src system/libfuse/include  
  31. LOCAL_CFLAGS:= -O2 -g -W -Wall -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -DHAVE_CONFIG_H  
  32. LOCAL_MODULE:= ntfs-3g  
  33. LOCAL_MODULE_TAGS:=eng  
  34. LOCAL_SYSTEM_SHARED_LIBRARIES:= libc  
  35. LOCAL_STATIC_LIBRARIES:= libfuse libntfs-3g  
  36.   
  37. include $(BUILD_EXECUTABLE)  

        3、ntfsfix

                这个是用来在挂载 NTFS 分区前检查错误的。

                在 system 目录下建立 ntfsfix 目录,并建立子目录 src。将 ntfs-3g 中 ntfsprogs 中的 ntfsfix.c sd.c sd.h utils.c utils.h 复制到 ntfsfix/src 目录,将 ntfs-3g 中的 config.h 复制到 ntfsfix 目录。

                在 ntfsfix 目录下建立 Android.mk:

[plain]  view plain copy
  1. LOCAL_PATH:= $(call my-dir)  
  2.   
  3. include $(CLEAR_VARS)  
  4.   
  5. LOCAL_SRC_FILES:= \  
  6.     src/ntfsfix.c \  
  7.     src/utils.c \  
  8.     src/sd.c  
  9.   
  10. LOCAL_C_INCLUDES:= $(LOCAL_PATH)/src system/ntfs-3g/include  
  11. LOCAL_CFLAGS:= -O2 -g -W -Wall -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -DHAVE_CONFIG_H  
  12. LOCAL_MODULE:= ntfsfix  
  13. LOCAL_MODULE_TAGS:=eng  
  14. LOCAL_SYSTEM_SHARED_LIBRARIES:= libc  
  15. LOCAL_STATIC_LIBRARIES:= libntfs-3g libfuse  
  16.   
  17. include $(BUILD_EXECUTABLE)  

        4、mkntfs

                这个是用来格式化分区为 NTFS 格式的。

                在 system 目录下建立 mkntfs 目录,并建立子目录 src。将 ntfs-3g 中 ntfsprogs 中的 attrdef.c attrdef.h boot.c boot.h mkntfs.c sd.c sd.h utils.c utils.h 复制到 mkntfs/src 目录,将 ntfs-3g 中的 config.h 复制到 mkntfs 目录。

                在 mkntfs 目录下建立 Android.mk:

[plain]  view plain copy
  1. LOCAL_PATH:= $(call my-dir)  
  2.   
  3. include $(CLEAR_VARS)  
  4.   
  5. LOCAL_SRC_FILES:= \  
  6.     src/attrdef.c \  
  7.     src/boot.c \  
  8.     src/utils.c \  
  9.     src/mkntfs.c \  
  10.     src/sd.c  
  11.   
  12. LOCAL_C_INCLUDES:= $(LOCAL_PATH)/src system/ntfs-3g/include  
  13. LOCAL_CFLAGS:= -O2 -g -W -Wall -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -DHAVE_CONFIG_H  
  14. LOCAL_MODULE:= mkntfs  
  15. LOCAL_MODULE_TAGS:=eng  
  16. LOCAL_SYSTEM_SHARED_LIBRARIES:= libc  
  17. LOCAL_STATIC_LIBRARIES:= libntfs-3g libfuse  
  18.   
  19. include $(BUILD_EXECUTABLE)  

        5、exfat

                这里只提取挂载 exFAT 分区所需的文件。

                在 system 目录下建立 exfat 目录。将 exfat 源代码中的 fuse 和 libexfat 文件夹复制到 exfat 目录中。

                建立 Android.mk:

[plain]  view plain copy
  1. LOCAL_PATH:= $(call my-dir)  
  2.   
  3. include $(CLEAR_VARS)  
  4.   
  5. LOCAL_SRC_FILES:= \  
  6.     libexfat/cluster.c libexfat/io.c libexfat/log.c \  
  7.     libexfat/lookup.c libexfat/mount.c libexfat/node.c \  
  8.     libexfat/time.c libexfat/utf.c libexfat/utils.c  
  9.   
  10. LOCAL_C_INCLUDES:= $(LOCAL_PATH)/libexfat system/libfuse/include  
  11. LOCAL_CFLAGS:= -O2 -g -W -Wall -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -UUSE_UBLIO  
  12. LOCAL_MODULE:= libexfat  
  13. LOCAL_MODULE_TAGS:=eng  
  14. LOCAL_SYSTEM_SHARED_LIBRARIES:= libc libcutils  
  15.   
  16. include $(BUILD_STATIC_LIBRARY)  
  17.   
  18. include $(CLEAR_VARS)  
  19.   
  20. LOCAL_SRC_FILES:= \  
  21.     fuse/main.c  
  22.   
  23. LOCAL_C_INCLUDES:= $(LOCAL_PATH)/libexfat system/libfuse/include  
  24. LOCAL_CFLAGS:= -O2 -g -W -Wall -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -DUSE_UBLIO  
  25. LOCAL_MODULE:= exfat  
  26. LOCAL_MODULE_TAGS:=eng  
  27. LOCAL_SYSTEM_SHARED_LIBRARIES:= libc  
  28. LOCAL_STATIC_LIBRARIES:= libfuse libexfat  
  29.   
  30. include $(BUILD_EXECUTABLE)  

        6、exfatfsck

                这个是用来在挂载 exFAT 分区前检查错误的。

                在 system 目录建立 exfatfsck 目录,并将 exfat 源代码中 fsck/main.c 复制到 exfatfsck 目录中。

                建立 Android.mk(这里只列出关键的两行):

[plain]  view plain copy
  1. LOCAL_SRC_FILES:= \  
  2.     main.c  
  3.   
  4. LOCAL_C_INCLUDES:= $(LOCAL_PATH)/src system/exfat/libexfat  

        7、mkexfatfs

                这个是用来格式化分区为 exFAT 格式的。

                在 system 目录下建立 mkexfatfs 目录,并建立子目录 src。将 exfat 源代码中 mkfs 目录下的所有文件复制到 mkexfatfs/src 目录中。

                建立 Android.mk(关键部分):

[plain]  view plain copy
  1. LOCAL_SRC_FILES:= \  
  2.     src/cbm.c \  
  3.     src/fat.c \  
  4.     src/main.c \  
  5.     src/mkexfat.c \  
  6.     src/rootdir.c \  
  7.     src/uct.c \  
  8.     src/uctc.c \  
  9.     src/vbr.c  
  10.   
  11. LOCAL_C_INCLUDES:= $(LOCAL_PATH)/src system/exfat/libexfat  


四、修改 vold 代码

        CyanogenMod 的 vold 代码包含了 Ntfs.cpp 和 Ntfs.h,但是需要修改

        1、修改 Ntfs.cpp

                添加全局变量:

[cpp]  view plain copy
  1. static char MOUNT_NTFS_PATH[] = "/system/bin/ntfs-3g";  
  2. static char MKNTFS_PATH[] = "/system/bin/mkntfs";  
  3. static char NTFSFIX_PATH[] = "/system/bin/ntfsfix";  

                check 函数:

[cpp]  view plain copy
  1. int Ntfs::check(const char *fsPath) {  
  2.     bool rw = true;  
  3.     if (access(NTFSFIX_PATH, X_OK)) {  
  4.         SLOGW("Skipping fs checks\n");  
  5.         return 0;  
  6.     }  
  7.   
  8.     int rc = -1;  
  9.     do {  
  10.         const char *args[3];  
  11.         args[0] = NTFSFIX_PATH;  
  12.         args[1] = fsPath;  
  13.         args[2] = NULL;  
  14.   
  15.         rc = logwrap(3, args, 1);  
  16.   
  17.         switch(rc) {  
  18.         case 0:  
  19.             SLOGI("NTFS Filesystem check completed OK.\n");  
  20.             return 0;  
  21.         case 1:  
  22.             SLOGI("NTFS Filesystem check failed.\n");  
  23.             return 0;  
  24.         default:  
  25.             SLOGE("NTFS Filesystem check failed (unknown exit code %d).\n", rc);  
  26.             errno = EIO;  
  27.             return -1;  
  28.         }  
  29.     } while (0);  
  30.   
  31.     return 0;  
  32. }  

                doMount 函数:

[cpp]  view plain copy
  1. int Ntfs::doMount(const char *fsPath, const char *mountPoint,  
  2.                  bool ro, bool remount, bool executable,  
  3.                  int ownerUid, int ownerGid, int permMask, bool createLost) {  
  4.     int rc;  
  5.     unsigned long flags;  
  6.     char mountData[255];  
  7.     char options[255] = {};  
  8.     const char *args[6];  
  9.   
  10.     flags = MS_NODEV | MS_NOSUID | MS_DIRSYNC;  
  11.   
  12.     flags |= (executable ? 0 : MS_NOEXEC);  
  13.     flags |= (ro ? MS_RDONLY : 0);  
  14.     flags |= (remount ? MS_REMOUNT : 0);  
  15.   
  16.     // Testing/security, mount ro up to now  
  17.     flags |= MS_RDONLY;  
  18.       
  19.     /* 
  20.      * Note: This is a temporary hack. If the sampling profiler is enabled, 
  21.      * we make the SD card world-writable so any process can write snapshots. 
  22.      * 
  23.      * TODO: Remove this code once we have a drop box in system_server. 
  24.      */  
  25.     char value[PROPERTY_VALUE_MAX];  
  26.     property_get("persist.sampling_profiler", value, "");  
  27.     if (value[0] == '1') {  
  28.         SLOGW("The SD card is world-writable because the"  
  29.             " 'persist.sampling_profiler' system property is set to '1'.");  
  30.         permMask = 0;  
  31.     }  
  32.   
  33.     sprintf(mountData,  
  34.             "uid=%d,gid=%d,fmask=%o,dmask=%o",  
  35.             ownerUid, ownerGid, permMask, permMask);  
  36.   
  37.     if (!remount) {  
  38.         SLOGI("Trying to use ntfs-3g program to mount %s", fsPath);              
  39.               
  40.         if (ro)  
  41.             snprintf(options, sizeof(options), "ro,%s", mountData);  
  42.         else  
  43.             snprintf(options, sizeof(options), "%s", mountData);  
  44.   
  45.         args[0] = MOUNT_NTFS_PATH;  
  46.         args[1] = "-o";  
  47.         args[2] = options;  
  48.         args[3] = fsPath;  
  49.         args[4] = mountPoint;  
  50.         args[5] = NULL;  
  51.   
  52.         rc = logwrap(6, args, 1);  
  53.   
  54.         if (rc == 0) {  
  55.             SLOGI("ntfs-3g executed successfully.");  
  56.         } else {  
  57.             SLOGE("Failed to execute ntfs-3g.");  
  58.         }  
  59.     } else {  
  60.         rc = mount(fsPath, mountPoint, "fuseblk", flags, mountData);  
  61.     }  
  62.   
  63.     if (rc && errno == EROFS) {  
  64.         SLOGE("%s appears to be a read only filesystem - retrying mount RO", fsPath);  
  65.         flags |= MS_RDONLY;  
  66.         if (!remount) {  
  67.             SLOGI("Trying to use ntfs-3g program to mount %s as read-only", fsPath);  
  68.   
  69.             snprintf(options, sizeof(options), "ro,%s", mountData);  
  70.   
  71.             args[0] = MOUNT_NTFS_PATH;  
  72.             args[1] = "-o";  
  73.             args[2] = options;  
  74.             args[3] = fsPath;  
  75.             args[4] = mountPoint;  
  76.             args[5] = NULL;  
  77.   
  78.             rc = logwrap(6, args, 1);  
  79.   
  80.             if (rc == 0) {  
  81.                 SLOGI("ntfs-3g executed successfully for read-only.");  
  82.             } else {  
  83.                 SLOGE("Failed to execute ntfs-3g for read-only.");  
  84.             }  
  85.         } else {  
  86.             rc = mount(fsPath, mountPoint, "fuseblk", flags, mountData);  
  87.         }  
  88.     }  
  89.   
  90.     return rc;  
  91. }  

                format 函数:

[cpp]  view plain copy
  1. int Ntfs::format(const char *fsPath, unsigned int numSectors) {  
  2.     const char *args[5];  
  3.     char strNumOfSectors[16] = {};     
  4.     int rc;   
  5.   
  6.     args[0] = MKNTFS_PATH;  
  7.     args[1] = "-f";  
  8.     args[2] = fsPath;  
  9.   
  10.     if (numSectors) {  
  11.         snprintf(strNumOfSectors, sizeof(strNumOfSectors), "%u", numSectors);  
  12.         args[3] = strNumOfSectors;  
  13.         args[4] = NULL;  
  14.         rc = logwrap(5, args, 1);  
  15.     } else {  
  16.         args[3] = NULL;  
  17.         rc = logwrap(4, args, 1);  
  18.     }  
  19.   
  20.     if (rc == 0) {  
  21.         SLOGI("Filesystem formatted OK");  
  22.         return 0;  
  23.     } else {  
  24.         SLOGE("Format failed (unknown exit code %d)", rc);  
  25.         errno = EIO;  
  26.         return -1;  
  27.     }  
  28.     return 0;  
  29. }  

        2、添加 ExFat.h 和 ExFat.cpp

                这里请使用 Ntfs.h 和 Ntfs.cpp 作为模板。

                关键代码:

[cpp]  view plain copy
  1. static char MOUNT_EXFAT_PATH[] = "/system/bin/exfat";  
  2. static char MKFS_EXFAT_PATH[] = "/system/bin/mkexfatfs";  
  3. static char FSCK_EXFAT_PATH[] = "/system/bin/exfatfsck";  
  4.   
  5. int ExFat::check(const char *fsPath) {  
  6.     bool rw = true;  
  7.     if (access(FSCK_EXFAT_PATH, X_OK)) {  
  8.         SLOGW("Skipping fs checks\n");  
  9.         return 0;  
  10.     }  
  11.   
  12.     int rc = -1;  
  13.     do {  
  14.         const char *args[3];  
  15.         args[0] = FSCK_EXFAT_PATH;  
  16.         args[1] = fsPath;  
  17.         args[2] = NULL;  
  18.   
  19.         rc = logwrap(3, args, 1);  
  20.   
  21.         switch(rc) {  
  22.         case 0:  
  23.             SLOGI("exFAT Filesystem check completed OK.\n");  
  24.             return 0;  
  25.         case 1:  
  26.             SLOGI("exFAT Filesystem check failed.\n");  
  27.             return 0;  
  28.         default:  
  29.             SLOGE("exFAT Filesystem check failed (unknown exit code %d).\n", rc);  
  30.             errno = EIO;  
  31.             return -1;  
  32.         }  
  33.     } while (0);  
  34.   
  35.     return 0;  
  36. }  
  37.   
  38. int ExFat::doMount(const char *fsPath, const char *mountPoint,  
  39.                  bool ro, bool remount, bool executable,  
  40.                  int ownerUid, int ownerGid, int permMask, bool createLost) {  
  41.     int rc;  
  42.     unsigned long flags;  
  43.     char mountData[255];  
  44.     const char *args[4];  
  45.   
  46.     flags = MS_NODEV | MS_NOSUID | MS_DIRSYNC;  
  47.   
  48.     flags |= (executable ? 0 : MS_NOEXEC);  
  49.     flags |= (ro ? MS_RDONLY : 0);  
  50.     flags |= (remount ? MS_REMOUNT : 0);  
  51.   
  52.     // Testing/security, mount ro up to now  
  53.     flags |= MS_RDONLY;  
  54.       
  55.     sprintf(mountData,  
  56.             "uid=%d,gid=%d,fmask=%o,dmask=%o",  
  57.             ownerUid, ownerGid, permMask, permMask);  
  58.   
  59.     if (!remount) {  
  60.         SLOGI("Trying to use exfat program to mount %s", fsPath);              
  61.               
  62.         args[0] = MOUNT_EXFAT_PATH;  
  63.         args[1] = fsPath;  
  64.         args[2] = mountPoint;  
  65.         args[3] = NULL;  
  66.   
  67.         rc = logwrap(4, args, 1);  
  68.   
  69.         if (rc == 0) {  
  70.             SLOGI("exfat executed successfully.");  
  71.         } else {  
  72.             SLOGE("Failed to execute exfat.");  
  73.         }  
  74.     } else {  
  75.         rc = mount(fsPath, mountPoint, "fuseblk", flags, mountData);  
  76.     }  
  77.   
  78.     return rc;  
  79. }  
  80.   
  81. int ExFat::format(const char *fsPath, unsigned int numSectors) {  
  82.     const char *args[3];  
  83.     char strNumOfSectors[16] = {};     
  84.     int rc;   
  85.   
  86.     args[0] = MKFS_EXFAT_PATH;  
  87.     args[1] = fsPath;  
  88.     args[2] = NULL;  
  89.   
  90.     rc = logwrap(3, args, 1);  
  91.   
  92.     if (rc == 0) {  
  93.         SLOGI("Filesystem formatted OK");  
  94.         return 0;  
  95.     } else {  
  96.         SLOGE("Format failed (unknown exit code %d)", rc);  
  97.         errno = EIO;  
  98.         return -1;  
  99.     }  
  100.     return 0;  
  101. }  

        3、修改 Volume.cpp

                添加 #include "Ntfs.h"

                找到 Volume::mountVol() 函数

                找到 else if (strcmp(fstype, "ntfs") == 0) 部分,在后面添加以下代码:

[cpp]  view plain copy
  1. if (Ntfs::check(devicePath)) {  
  2.     errno = EIO;  
  3.     /* Badness - abort the mount */  
  4.     SLOGE("%s failed FS checks (%s)", devicePath, strerror(errno));  
  5.     setState(Volume::State_Idle);  
  6.     free(fstype);  
  7.     return -1;  
  8. }  

                找到和 if (fstype != NULL)  对应的 else 块,在后面添加以下代码:

[cpp]  view plain copy
  1.       //Check if the filesystem is exFAT  
  2.       FILE *volf = fopen(devicePath, "rb");  
  3.       int bytesRead = 0;  
  4.       if (volf) {  
  5.           char fschar[5];  
  6.           //Read the signature in the PBR  
  7.           fseek(volf, 3, SEEK_SET);  
  8.           bytesRead = fread(fschar, 1, 5, volf);  
  9.           fclose(volf);  
  10.   
  11.           if (bytesRead == 5 && strcmp(fschar, "EXFAT") == 0) {  
  12.   
  13.               if (ExFat::check(devicePath)) {  
  14.     errno = EIO;  
  15.     /* Badness - abort the mount */  
  16.     SLOGE("%s failed FS checks (%s)", devicePath, strerror(errno));  
  17.     setState(Volume::State_Idle);  
  18.     free(fstype);  
  19.     return -1;  
  20. }  
  21.   
  22. if (ExFat::doMount(devicePath, "/mnt/secure/staging"falsefalsefalse,  
  23.         AID_SYSTEM, gid, 0702, true)) {  
  24.     SLOGE("%s failed to mount via exFAT (%s)\n", devicePath, strerror(errno));  
  25.                   continue;  
  26. else {  
  27.                   goto mountSuccess;  
  28.               }  
  29.           }  
  30.       }  

                然后转到 if (fstype != NULL) 的 else 的末尾,在语句块之后,SLOGI("Device %s, target %s mounted @ /mnt/secure/staging", devicePath, getMountpoint()); 之前添加 mountSuccess: 跳转标签。

        4、修改 vold 的 Android.mk

                天际 common_src_files += ExFat.c


五、修改 build/target/product/base.mk

        添加

[plain]  view plain copy
  1. PRODUCT_PACKAGES += \  
  2.     libfuse \  
  3.     ntfs-3g \  
  4.     exfat \  
  5.     mkntfs \  
  6.     ntfsfix \  
  7.     mkexfatfs \  
  8.     exfatfsck  



六、编译

        如果不出意外的话,编译之后就可以直接使用了。

你可能感兴趣的:(CyanogenMod 10 修改 Vold 使 Android 自动挂载 NTFS 和 exFAT 格式的 SD 卡)