From 3babfb3deb5a81213f9b64517e1e7db1cf5f9ce0 Mon Sep 17 00:00:00 2001 From: Christophe Grenier Date: Wed, 6 Apr 2011 09:08:26 +0200 Subject: [PATCH] Support for ntfs-3g_ntfsprogs --- compile.sh | 64 ++++++++++++++++++++++++++++++++++++++++++++--- configure.ac | 35 ++++++++++++++++++++++++++ src/ntfs_dir.c | 22 ++++++++++------ src/ntfs_inc.h | 2 +- src/ntfs_io.c | 27 +++++++++++++++++--- src/ntfs_udl.c | 40 ++++++++++++++++++++++++----- src/ntfs_utl.c | 8 +++++- src/ntfs_utl.h | 2 +- src/ntfsp.c | 7 +++++- src/pfree_whole.c | 4 +-- src/photorec.c | 2 +- 11 files changed, 186 insertions(+), 27 deletions(-) diff --git a/compile.sh b/compile.sh index 88a7d1b1..596676b6 100755 --- a/compile.sh +++ b/compile.sh @@ -3,8 +3,7 @@ # ./compile.sh [ i586-pc-msdosdjgpp | i386-pc-cygwin | i386-pc-mingw32 | powerpc-mac-darwin ] # Comment the version definition to not compile the library VER_E2FSPROGS= -VER_PROGSREISERFS=0.3.1-rc8 -VER_NTFSPROGS=2.0.0 +VER_PROGSREISERFS="0.3.1-rc8" VER_LIBEWF=20100226 #VER_LIBEWF=20110312 smp_mflags="-j 2" @@ -13,6 +12,7 @@ prefix=/usr/ if [ "$CC" = "gcc295" ]; then VER_NTFSPROGS= + VER_LIBNTFS3G= fi if [ -z "$1" ]; then @@ -26,12 +26,24 @@ else TESTDISKCC=$crosscompile_target-gcc fi fi +case "$crosscompile_target" in + *-msdosdjgpp|*-cygwin|*-mingw32) + VER_LIBNTFS3G= + VER_NTFSPROGS="2.0.0" + ;; + *) + VER_LIBNTFS3G="2011.3.28-RC" + VER_NTFSPROGS= + ;; +esac prefix=/usr/$crosscompile_target LYNX=links +WGET="wget -N" LIBEXT=$compiledir/e2fsprogs-$VER_E2FSPROGS/lib/ext2fs/libext2fs.a LIBNTFS=$compiledir/ntfsprogs-$VER_NTFSPROGS/libntfs/.libs/libntfs.a +LIBNTFS3G=$compiledir/ntfs-3g_ntfsprogs-$VER_LIBNTFS3G/libntfs-3g/.libs/libntfs-3g.a LIBREISER=$compiledir/progsreiserfs-$VER_PROGSREISERFS/libreiserfs/.libs/libreiserfs.a -LIBEWF=$compiledir/ewf-$VER_NTFSPROGS/libewf/.libs/libewf.a +LIBEWF=$compiledir/ewf-$VER_LIBEWF/libewf/.libs/libewf.a pwd_saved=`pwd` confdir=`(dirname "$0") 2>/dev/null` cd $confdir @@ -131,6 +143,52 @@ then fi fi +if [ "$VER_LIBNTFS3G" != "" ]; +then +CONFIGUREOPT="$CONFIGUREOPT --with-ntfs3g-lib=${PWDSRC}/ntfs-3g_ntfsprogs-${VER_LIBNTFS3G}/libntfs-3g/.libs/ --with-ntfs3g-includes=${PWDSRC}/ntfs-3g_ntfsprogs-${VER_LIBNTFS3G}/include/" +if [ ! -e $compiledir/ntfsprogs-$VER_LIBNTFS3G/configure ]; +then + if [ ! -e ntfs-3g_ntfsprogs-$VER_LIBNTFS3G.tgz ]; + then + $WGET http://tuxera.com/opensource/ntfs-3g_ntfsprogs-$VER_LIBNTFS3G.tgz + fi + if [ -e ntfs-3g_ntfsprogs-$VER_LIBNTFS3G.tgz ]; + then + tar xzf ntfs-3g_ntfsprogs-$VER_LIBNTFS3G.tgz -C $compiledir + fi +fi + +if [ ! -e $compiledir/ntfs-3g_ntfsprogs-$VER_LIBNTFS3G/Makefile ]; +then + if [ -e $compiledir/ntfs-3g_ntfsprogs-$VER_LIBNTFS3G/configure ]; + then +# rm -f $compiledir/Makefile + cd $compiledir/ntfs-3g_ntfsprogs-$VER_LIBNTFS3G + case "$crosscompile_target" in + powerpc-apple-darwin|i686-apple-darwin9) + CC=$TESTDISKCC ./configure --host=$crosscompile_target --prefix=$prefix --disable-default-device-io-ops --disable-crypto --disable-nfconv + ;; + *) + CC=$TESTDISKCC ./configure --host=$crosscompile_target --prefix=$prefix --disable-default-device-io-ops --disable-crypto + ;; + esac +# --disable-default-device-io-ops is need for NT 4 + cd $pwd_saved + fi +fi + +if [ ! -e $VER_LIBNTFS3G ]; +then + if [ -e $compiledir/ntfs-3g_ntfsprogs-$VER_LIBNTFS3G/Makefile ]; + then + cd $compiledir/ntfs-3g_ntfsprogs-$VER_LIBNTFS3G +# make $smp_mflags libs + make $smp_mflags + cd $pwd_saved + fi +fi +fi + if [ "$VER_NTFSPROGS" != "" ]; then CONFIGUREOPT="$CONFIGUREOPT --with-ntfs-lib=${PWDSRC}/ntfsprogs-${VER_NTFSPROGS}/libntfs/.libs/ --with-ntfs-includes=${PWDSRC}/ntfsprogs-${VER_NTFSPROGS}/include/" diff --git a/configure.ac b/configure.ac index 0147bebd..b82119a0 100644 --- a/configure.ac +++ b/configure.ac @@ -92,6 +92,20 @@ AC_ARG_WITH(ntfs-includes, AS_HELP_STRING(--with-ntfs-includes=DIR,location of the ntfs includes files), [CPPFLAGS="${CPPFLAGS} -I${withval}"]) +AC_ARG_WITH([ntfs3g], + AS_HELP_STRING(--without-ntfs3g,disabled use of the ntfs3g library (default is NO)), + [ use_ntfs3g="n" ]) + +AC_ARG_WITH(ntfs3g-lib, + AS_HELP_STRING(--with-ntfs3g-lib=DIR,location of the ntfs3g library), + [ ntfs3g_lib_a="${withval}/libntfs-3g.a" + LDFLAGS="${LDFLAGS} -L${withval}" + ]) + +AC_ARG_WITH(ntfs3g-includes, + AS_HELP_STRING(--with-ntfs3g-includes=DIR,location of the ntfs3g includes files), + [CPPFLAGS="${CPPFLAGS} -I${withval}"]) + AC_ARG_WITH(dal-lib, AS_HELP_STRING(--with-dal-lib=DIR,location of the dal library), [ LDFLAGS="${LDFLAGS} -L${withval}" ]) @@ -384,6 +398,10 @@ AC_CHECK_HEADERS([ntfs/attrib.h ntfs/volume.h],, use_ntfs=no AC_MSG_WARN(Disable use of ntfs library)) +AC_CHECK_HEADERS([ntfs-3g/attrib.h ntfs-3g/volume.h],, + use_ntfs3g=no + AC_MSG_WARN(Disable use of ntfs3g library)) + AC_CHECK_HEADERS([libcarvpath.h],, use_carvpath=no AC_MSG_WARN(Disable use of carvpath library)) @@ -525,6 +543,23 @@ else AC_MSG_WARN(Use of jpeg library disabled) fi +if test -z "${use_ntfs3g}"; then + AC_CHECK_LIB(ntfs-3g,ntfs_device_mount, + [ + AC_DEFINE([HAVE_LIBNTFS3G],1,[Define to 1 if you have the ntfs3g library (-lntfs3g).]) + if test "${ntfs3g_lib_a}" = ""; then + LIBS="-lntfs-3g $LIBS" + else + LIBS="${ntfs3g_lib_a} $LIBS" + fi + use_ntfs=no + ], + AC_MSG_WARN(No ntfs-3g library detected) + ) +else + AC_MSG_WARN(Use of ntfs3g library disabled) +fi + if test -z "${use_ntfs}"; then AC_CHECK_LIB(ntfs,ntfs_device_mount, [ diff --git a/src/ntfs_dir.c b/src/ntfs_dir.c index 02e6727b..60375129 100644 --- a/src/ntfs_dir.c +++ b/src/ntfs_dir.c @@ -63,6 +63,10 @@ #include #endif #endif +#ifdef HAVE_LIBNTFS3G +#include +#include +#endif #include "common.h" #include "intrf.h" @@ -74,7 +78,7 @@ #include "log.h" #include "setdate.h" -#ifdef HAVE_LIBNTFS +#if defined(HAVE_LIBNTFS) || defined(HAVE_LIBNTFS3G) #define MAX_PATH 1024 #define PATH_SEP '/' #define NTFS_DT_DIR 4 @@ -98,7 +102,7 @@ extern struct ntfs_device_operations ntfs_device_testdisk_io_ops; extern int ntfs_readdir(ntfs_inode *dir_ni, s64 *pos, void *dirent, ntfs_filldir_t filldir); -static time_t ntfs2utc (s64 ntfstime); +static time_t td_ntfs2utc (s64 ntfstime); static int ntfs_td_list_entry( struct ntfs_dir_struct *ls, const ntfschar *name, const int name_len, const int name_type, const s64 pos, const MFT_REF mref, const unsigned dt_type); @@ -130,7 +134,7 @@ static int index_get_size(ntfs_inode *inode) } /** - * ntfs2utc - Convert an NTFS time to Unix time + * td_ntfs2utc - Convert an NTFS time to Unix time * @time: An NTFS time in 100ns units since 1601 * * NTFS stores times as the number of 100ns intervals since January 1st 1601 at @@ -138,7 +142,7 @@ static int index_get_size(ntfs_inode *inode) * * Return: n A Unix time (number of seconds since 1970) */ -static time_t ntfs2utc (s64 ntfstime) +static time_t td_ntfs2utc (s64 ntfstime) { return (ntfstime - (NTFS_TIME_OFFSET)) / 10000000; } @@ -259,9 +263,9 @@ static int ntfs_td_list_entry( struct ntfs_dir_struct *ls, const ntfschar *name new_file->stat.st_blocks=(new_file->stat.st_size+new_file->stat.st_blksize-1)/new_file->stat.st_blksize; } #endif - new_file->stat.st_atime=ntfs2utc(sle64_to_cpu(si->last_access_time)); - new_file->stat.st_mtime=ntfs2utc(sle64_to_cpu(si->last_data_change_time)); - new_file->stat.st_ctime=ntfs2utc(sle64_to_cpu(si->creation_time)); + new_file->stat.st_atime=td_ntfs2utc(sle64_to_cpu(si->last_access_time)); + new_file->stat.st_mtime=td_ntfs2utc(sle64_to_cpu(si->last_data_change_time)); + new_file->stat.st_ctime=td_ntfs2utc(sle64_to_cpu(si->creation_time)); new_file->prev=ls->current_file; new_file->next=NULL; /* log_debug("fat: new file %s de=%p size=%u\n",new_file->name,de,de->size); */ @@ -420,7 +424,7 @@ static void dir_partition_ntfs_close(dir_data_t *dir_data) int dir_partition_ntfs_init(disk_t *disk_car, const partition_t *partition, dir_data_t *dir_data, const int verbose) { -#ifdef HAVE_LIBNTFS +#if defined(HAVE_LIBNTFS) || defined(HAVE_LIBNTFS3G) struct ntfs_device *dev; my_data_t *my_data=NULL; ntfs_volume *vol=NULL; @@ -502,6 +506,8 @@ const char*td_ntfs_version(void) #else return "available"; #endif +#elif defined(HAVE_LIBNTFS3G) + return "libntfs-3g"; #else return "none"; #endif diff --git a/src/ntfs_inc.h b/src/ntfs_inc.h index 72e720e7..177b372f 100644 --- a/src/ntfs_inc.h +++ b/src/ntfs_inc.h @@ -19,7 +19,7 @@ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifdef HAVE_LIBNTFS +#if defined(HAVE_LIBNTFS) || defined(HAVE_LIBNTFS3G) struct ntfs_dir_struct { file_data_t *dir_list; file_data_t *current_file; diff --git a/src/ntfs_io.c b/src/ntfs_io.c index fb1be2af..96f30af6 100644 --- a/src/ntfs_io.c +++ b/src/ntfs_io.c @@ -26,7 +26,7 @@ #include #endif -#ifdef HAVE_LIBNTFS +#if defined(HAVE_LIBNTFS) || defined(HAVE_LIBNTFS3G) #ifdef HAVE_STDLIB_H #include #endif @@ -44,7 +44,12 @@ #include #endif #include +#ifdef HAVE_LIBNTFS #include +#endif +#ifdef HAVE_LIBNTFS3G +#include +#endif #include #include "types.h" #include "common.h" @@ -117,6 +122,22 @@ static s64 ntfs_device_testdisk_io_write(struct ntfs_device *dev, const void *bu return count; } +static s64 ntfs_device_testdisk_io_pread(struct ntfs_device *dev, void *buf, + s64 count, s64 offset) +{ + my_data_t *my_data=(my_data_t*)dev->d_private; + return my_data->disk_car->pread(my_data->disk_car, buf, count, + my_data->partition->part_offset + offset); +} + +static s64 ntfs_device_testdisk_io_pwrite(struct ntfs_device *dev, const void *buf, + s64 count, s64 offset) +{ + my_data_t *my_data=(my_data_t*)dev->d_private; + return my_data->disk_car->pwrite(my_data->disk_car, buf, count, + my_data->partition->part_offset + offset); +} + static int ntfs_device_testdisk_io_sync(struct ntfs_device *dev) { my_data_t *my_data=(my_data_t*)dev->d_private; @@ -147,8 +168,8 @@ struct ntfs_device_operations ntfs_device_testdisk_io_ops = { .seek = ntfs_device_testdisk_io_seek, .read = ntfs_device_testdisk_io_read, .write = ntfs_device_testdisk_io_write, - .pread = NULL, - .pwrite = NULL, + .pread = ntfs_device_testdisk_io_pread, + .pwrite = ntfs_device_testdisk_io_pwrite, .sync = ntfs_device_testdisk_io_sync, .stat = ntfs_device_testdisk_io_stat, .ioctl = ntfs_device_testdisk_io_ioctl, diff --git a/src/ntfs_udl.c b/src/ntfs_udl.c index 08267cee..1823ba8a 100644 --- a/src/ntfs_udl.c +++ b/src/ntfs_udl.c @@ -85,6 +85,20 @@ #ifdef HAVE_NTFS_VERSION_H #include #endif +#endif + +#ifdef HAVE_LIBNTFS3G +#include +#include +#include +#include +#include +#include +#include +#include +#endif + +#if defined(HAVE_LIBNTFS) || defined(HAVE_LIBNTFS3G) #ifdef HAVE_ICONV_H #include #endif @@ -151,6 +165,20 @@ struct ufile { char padding[4]; /* Unused: padding to 64 bit. */ }; +/** + * td_ntfs2utc - Convert an NTFS time to Unix time + * @time: An NTFS time in 100ns units since 1601 + * + * NTFS stores times as the number of 100ns intervals since January 1st 1601 at + * 00:00 UTC. This system will not suffer from Y2K problems until ~57000AD. + * + * Return: n A Unix time (number of seconds since 1970) + */ +static time_t td_ntfs2utc (s64 ntfstime) +{ + return (ntfstime - (NTFS_TIME_OFFSET)) / 10000000; +} + static const char *UNKNOWN = "unknown"; static struct options opts; @@ -227,7 +255,7 @@ static FILE_NAME_ATTR* verify_parent(struct filename* name, MFT_RECORD* rec) filename_attr = (FILE_NAME_ATTR*)((char*)attr30 + le16_to_cpu(attr30->value_offset)); /* if name is older than this dir -> can't determine */ - if (ntfs2utc(filename_attr->creation_time) > name->date_c) { + if (td_ntfs2utc(filename_attr->creation_time) > name->date_c) { return NULL; } if (filename_attr->file_name_type != name->name_space) { @@ -388,10 +416,10 @@ static int get_filenames(struct ufile *file, ntfs_volume* vol) name->size_data = sle64_to_cpu(attr->data_size); name->flags = attr->file_attributes; - name->date_c = ntfs2utc(attr->creation_time); - name->date_a = ntfs2utc(attr->last_data_change_time); - name->date_m = ntfs2utc(attr->last_mft_change_time); - name->date_r = ntfs2utc(attr->last_access_time); + name->date_c = td_ntfs2utc(attr->creation_time); + name->date_a = td_ntfs2utc(attr->last_data_change_time); + name->date_m = td_ntfs2utc(attr->last_mft_change_time); + name->date_r = td_ntfs2utc(attr->last_access_time); if (ntfs_ucstombs(name->uname, name->uname_len, &name->name, 0) < 0) { @@ -557,7 +585,7 @@ static struct ufile * read_record(ntfs_volume *vol, long long record) if (attr10) { STANDARD_INFORMATION *si; si = (STANDARD_INFORMATION *) ((char *) attr10 + le16_to_cpu(attr10->value_offset)); - file->date = ntfs2utc(si->last_data_change_time); + file->date = td_ntfs2utc(si->last_data_change_time); } if (attr20 || !attr10) diff --git a/src/ntfs_utl.c b/src/ntfs_utl.c index 23e7b790..e18848c9 100644 --- a/src/ntfs_utl.c +++ b/src/ntfs_utl.c @@ -26,7 +26,7 @@ #ifdef HAVE_CONFIG_H #include #endif -#ifdef HAVE_LIBNTFS +#if defined(HAVE_LIBNTFS) || defined(HAVE_LIBNTFS3G) #include #ifdef HAVE_STDLIB_H #include @@ -50,7 +50,13 @@ #include #include "types.h" +#ifdef HAVE_LIBNTFS #include +#endif +#ifdef HAVE_LIBNTFS3G +#include +#endif + #include "ntfs_utl.h" #include "common.h" #include "log.h" diff --git a/src/ntfs_utl.h b/src/ntfs_utl.h index e02a00a8..e19c9279 100644 --- a/src/ntfs_utl.h +++ b/src/ntfs_utl.h @@ -19,7 +19,7 @@ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifdef HAVE_LIBNTFS +#if defined(HAVE_LIBNTFS) || defined(HAVE_LIBNTFS3G) #ifdef __cplusplus extern "C" { #endif diff --git a/src/ntfsp.c b/src/ntfsp.c index b86310fb..199a5d88 100644 --- a/src/ntfsp.c +++ b/src/ntfsp.c @@ -39,6 +39,11 @@ #include "filegen.h" #ifdef HAVE_LIBNTFS #include +#endif +#ifdef HAVE_LIBNTFS3G +#include +#endif +#if defined(HAVE_LIBNTFS) || defined(HAVE_LIBNTFS3G) #include "ntfsp.h" #endif #include "intrf.h" @@ -49,7 +54,7 @@ #include "log.h" #include "log_part.h" -#ifdef HAVE_LIBNTFS +#if defined(HAVE_LIBNTFS) || defined(HAVE_LIBNTFS3G) #define SIZEOF_BUFFER ((const unsigned int)512) unsigned int ntfs_remove_used_space(disk_t *disk_car,const partition_t *partition, alloc_data_t *list_search_space) diff --git a/src/pfree_whole.c b/src/pfree_whole.c index 0c600eae..1e49cbb8 100644 --- a/src/pfree_whole.c +++ b/src/pfree_whole.c @@ -67,7 +67,7 @@ int ask_mode_ext2(const disk_t *disk_car, const partition_t *partition, unsigned {'W',"Whole","Extract files from whole partition"}, {0,NULL,NULL} }; -#ifdef HAVE_LIBNTFS +#if defined(HAVE_LIBNTFS) || defined(HAVE_LIBNTFS3G) static const struct MenuItem menuNTFS[]= { {'F',"Free", "Scan for file from NTFS unallocated space only"}, @@ -128,7 +128,7 @@ int ask_mode_ext2(const disk_t *disk_car, const partition_t *partition, unsigned else if(partition->upart_type==UP_FAT32) command = wmenuSelect_ext(window, 23, 8, 0, menuFAT32, 11, options, MENU_VERT | MENU_VERT_WARN | MENU_BUTTON, &menu,NULL); -#ifdef HAVE_LIBNTFS +#if defined(HAVE_LIBNTFS) || defined(HAVE_LIBNTFS3G) else if(partition->upart_type==UP_NTFS) command = wmenuSelect_ext(window, 23, 8, 0, menuNTFS, 11, options, MENU_VERT | MENU_VERT_WARN | MENU_BUTTON, &menu,NULL); diff --git a/src/photorec.c b/src/photorec.c index 6d2a30fd..80ec3a5a 100644 --- a/src/photorec.c +++ b/src/photorec.c @@ -393,7 +393,7 @@ unsigned int remove_used_space(disk_t *disk_car, const partition_t *partition, a return fat_remove_used_space(disk_car, partition, list_search_space); else if(partition->upart_type==UP_EXFAT) return exfat_remove_used_space(disk_car, partition, list_search_space); -#ifdef HAVE_LIBNTFS +#if defined(HAVE_LIBNTFS) || defined(HAVE_LIBNTFS3G) else if(partition->upart_type==UP_NTFS) return ntfs_remove_used_space(disk_car, partition, list_search_space); #endif