Updates from Holger for regex undelete
Fix up code formatting (Logical change 1.693)edge.strict_endians
parent
8bb191b3bc
commit
14cd02ffc1
|
@ -1,8 +1,8 @@
|
|||
/**
|
||||
* ntfsundelete - Part of the Linux-NTFS project.
|
||||
*
|
||||
* Copyright (c) 2002-2004 Richard Russon
|
||||
* Copyright (c) 2004 Holger Ohmacht
|
||||
* Copyright (c) 2002-2005 Richard Russon
|
||||
* Copyright (c) 2004-2005 Holger Ohmacht
|
||||
*
|
||||
* This utility will recover deleted files from an NTFS volume.
|
||||
*
|
||||
|
@ -68,13 +68,17 @@ typedef struct
|
|||
u32 end;
|
||||
} range;
|
||||
|
||||
static range *ranges;
|
||||
static long nr_entries;
|
||||
static short with_regex; /* Flag Regular expression available */
|
||||
static short avoid_duplicate_printing; /* Flag No duplicate printing of file infos */
|
||||
static range *ranges; /* Array containing all Inode-Rages for undelete */
|
||||
static long nr_entries; /* Number of range entries */
|
||||
|
||||
GEN_PRINTF (Eprintf, stderr, NULL, FALSE)
|
||||
GEN_PRINTF (Vprintf, stdout, &opts.verbose, TRUE)
|
||||
GEN_PRINTF (Qprintf, stdout, &opts.quiet, FALSE)
|
||||
|
||||
static int undelete_file (ntfs_volume *vol, long long inode);
|
||||
|
||||
#define _(S) gettext(S)
|
||||
|
||||
/**
|
||||
|
@ -97,43 +101,43 @@ static int parse_inode_arg (void)
|
|||
char *opt_arg_end1;
|
||||
char *opt_arg_end2;
|
||||
|
||||
/* Check whether optarg is available or not */
|
||||
nr_entries = 0;
|
||||
if (optarg == NULL)
|
||||
return (0); /* bailout if no optarg */
|
||||
|
||||
/* init variables */
|
||||
p = strlen (optarg);
|
||||
imax = p;
|
||||
opt_arg_ptr = optarg;
|
||||
opt_arg_end1 = optarg;
|
||||
opt_arg_end2 = &(optarg[p]);
|
||||
nr_entries = 0;
|
||||
|
||||
/* alloc mem for range table */
|
||||
ranges = (range *) malloc ((p + 1) * sizeof (range));
|
||||
if (ranges == NULL)
|
||||
{
|
||||
if (ranges == NULL) {
|
||||
printf ("ERROR: Couldn't alloc mem for parsing inodes!\n");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* loop */
|
||||
while ((opt_arg_end1 != opt_arg_end2) && (p > 0))
|
||||
{
|
||||
while ((opt_arg_end1 != opt_arg_end2) && (p > 0)) {
|
||||
/* Try to get inode */
|
||||
inode = strtoul (opt_arg_ptr, &opt_arg_end1, 0);
|
||||
p--;
|
||||
|
||||
/* invalid char at begin */
|
||||
if ((opt_arg_ptr == opt_arg_end1) || (opt_arg_ptr == opt_arg_end2))
|
||||
{
|
||||
if ((opt_arg_ptr == opt_arg_end1) || (opt_arg_ptr == opt_arg_end2)) {
|
||||
printf ("ERROR: Invalid Number: %s\n", opt_arg_ptr);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* RANGE - Check for range */
|
||||
if (opt_arg_end1[0] == '-')
|
||||
{
|
||||
if (opt_arg_end1[0] == '-') {
|
||||
/* get range end */
|
||||
opt_arg_temp = opt_arg_end1;
|
||||
opt_arg_end1 = & (opt_arg_temp[1]);
|
||||
if (opt_arg_temp >= opt_arg_end2)
|
||||
{
|
||||
if (opt_arg_temp >= opt_arg_end2) {
|
||||
printf ("ERROR: Missing range end!\n");
|
||||
return (-1);
|
||||
}
|
||||
|
@ -141,15 +145,13 @@ static int parse_inode_arg (void)
|
|||
|
||||
/* get count */
|
||||
range_end = strtoul (opt_arg_end1, &opt_arg_temp, 0);
|
||||
if (opt_arg_temp == opt_arg_end1)
|
||||
{
|
||||
if (opt_arg_temp == opt_arg_end1) {
|
||||
printf ("ERROR: Invalid Number: %s\n", opt_arg_temp);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* check for correct values */
|
||||
if (range_begin > range_end)
|
||||
{
|
||||
if (range_begin > range_end) {
|
||||
range_temp = range_end;
|
||||
range_end = range_begin;
|
||||
range_begin = range_temp;
|
||||
|
@ -173,8 +175,7 @@ static int parse_inode_arg (void)
|
|||
|
||||
/* Next inode */
|
||||
opt_arg_ptr = & (opt_arg_end1[1]);
|
||||
if (opt_arg_ptr >= opt_arg_end2)
|
||||
{
|
||||
if (opt_arg_ptr >= opt_arg_end2) {
|
||||
printf ("ERROR: Missing new value at end of input!\n");
|
||||
return (-1);
|
||||
}
|
||||
|
@ -199,8 +200,8 @@ static void version (void)
|
|||
{
|
||||
printf ("\n%s v%s - Recover deleted files from an NTFS Volume.\n\n",
|
||||
EXEC_NAME, VERSION);
|
||||
printf ("Copyright (c)\n");
|
||||
printf (" 2002-2003 Richard Russon\n");
|
||||
printf ("Copyright (c) 2002-2005 Richard Russon\n"
|
||||
"Copyright (c) 2004-2005 Holger Ohmacht\n");
|
||||
printf ("\n%s\n%s%s\n", ntfs_gpl, ntfs_bugs, ntfs_home);
|
||||
}
|
||||
|
||||
|
@ -221,7 +222,8 @@ static void usage (void)
|
|||
" -S range --size range Match files of this size\n"
|
||||
" -t since --time since Last referenced since this time\n"
|
||||
"\n"
|
||||
" -u nums --undelete nums Undelete inodes\n"
|
||||
" -i --interactive Interactive mode\n"
|
||||
" -u [nums] --undelete [nums] Undelete mode: if <nums> specified, so undelete these\n"
|
||||
" -o file --output file Save with this filename\n"
|
||||
" -O --optimistic Undelete in-use clusters as well\n"
|
||||
" -d dir --destination dir Destination directory\n"
|
||||
|
@ -395,13 +397,14 @@ static int parse_time (const char *value, time_t *since)
|
|||
*/
|
||||
static int parse_options (int argc, char *argv[])
|
||||
{
|
||||
static const char *sopt = "-b:Cc:d:fh?m:o:OPp:sS:t:Tu:qvV";
|
||||
static const char *sopt = "-b:Cc:d:fhi?m:o:OPp:sS:t:Tu::qvV";
|
||||
static const struct option lopt[] = {
|
||||
{ "byte", required_argument, NULL, 'b' },
|
||||
{ "case", no_argument, NULL, 'C' },
|
||||
{ "copy", required_argument, NULL, 'c' },
|
||||
{ "destination", required_argument, NULL, 'd' },
|
||||
{ "force", no_argument, NULL, 'f' },
|
||||
{ "interactive", no_argument, NULL, 'i' },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "match", required_argument, NULL, 'm' },
|
||||
{ "output", required_argument, NULL, 'o' },
|
||||
|
@ -412,7 +415,7 @@ static int parse_options (int argc, char *argv[])
|
|||
{ "parent", no_argument, NULL, 'P' },
|
||||
{ "time", required_argument, NULL, 't' },
|
||||
{ "truncate", no_argument, NULL, 'T' },
|
||||
{ "undelete", required_argument, NULL, 'u' },
|
||||
{ "undelete", optional_argument, NULL, 'u' },
|
||||
{ "quiet", no_argument, NULL, 'q' },
|
||||
{ "verbose", no_argument, NULL, 'v' },
|
||||
{ "version", no_argument, NULL, 'V' },
|
||||
|
@ -431,8 +434,7 @@ static int parse_options (int argc, char *argv[])
|
|||
opts.uinode = -1;
|
||||
opts.percent = -1;
|
||||
opts.fillbyte = -1;
|
||||
|
||||
while ((c = getopt_long (argc, argv, sopt, lopt, NULL)) != (char)-1) {
|
||||
while ((c = getopt_long (argc, argv, sopt, lopt, NULL)) != (char)-1) {
|
||||
switch (c) {
|
||||
case 1: /* A non-option argument */
|
||||
if (!opts.device) {
|
||||
|
@ -480,8 +482,12 @@ static int parse_options (int argc, char *argv[])
|
|||
break;
|
||||
case 'm':
|
||||
if (!opts.match) {
|
||||
if (!transform (optarg, &opts.match))
|
||||
if (!transform (optarg, &opts.match)) {
|
||||
err++;
|
||||
} else {
|
||||
/* set regex-flag on true ;) */
|
||||
with_regex= 1;
|
||||
}
|
||||
} else {
|
||||
err++;
|
||||
}
|
||||
|
@ -545,8 +551,7 @@ static int parse_options (int argc, char *argv[])
|
|||
opts.truncate++;
|
||||
break;
|
||||
case 'u':
|
||||
if (opts.mode == MODE_NONE)
|
||||
{
|
||||
if (opts.mode == MODE_NONE) {
|
||||
end = NULL;
|
||||
opts.mode = MODE_UNDELETE;
|
||||
/* parse inodes */
|
||||
|
@ -605,13 +610,13 @@ static int parse_options (int argc, char *argv[])
|
|||
err++;
|
||||
}
|
||||
break;
|
||||
|
||||
case MODE_UNDELETE:
|
||||
if ((opts.percent != -1) || opts.match || opts.match_case ||
|
||||
(opts.size_begin > 0) || (opts.size_end > 0)) {
|
||||
/*if ((opts.percent != -1) || (opts.size_begin > 0) || (opts.size_end > 0)) {
|
||||
Eprintf ("Undelete can only be used with "
|
||||
"--output, --destination, --byte and --truncate.\n");
|
||||
err++;
|
||||
}
|
||||
}*/
|
||||
break;
|
||||
case MODE_COPY:
|
||||
if ((opts.fillbyte != (char)-1) || opts.truncate ||
|
||||
|
@ -730,7 +735,7 @@ static FILE_NAME_ATTR* verify_parent(struct filename* name, MFT_RECORD* rec) {
|
|||
|
||||
ctx = ntfs_attr_get_search_ctx(NULL, rec);
|
||||
if (!ctx) {
|
||||
Eprintf ("Couldn't create a search context.\n");
|
||||
Eprintf ("ERROR: Couldn't create a search context.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -754,15 +759,14 @@ static FILE_NAME_ATTR* verify_parent(struct filename* name, MFT_RECORD* rec) {
|
|||
|
||||
if (filename_attr->file_name_type == name->name_space) {
|
||||
found_same_space = 1;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (filename_attr->file_name_type < lowest_space_name->file_name_type) {
|
||||
lowest_space_name = filename_attr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ntfs_attr_put_search_ctx(ctx);
|
||||
|
||||
return (found_same_space ? filename_attr : lowest_space_name);
|
||||
|
@ -771,9 +775,9 @@ static FILE_NAME_ATTR* verify_parent(struct filename* name, MFT_RECORD* rec) {
|
|||
/**
|
||||
* get_parent_name - Find the name of a file's parent.
|
||||
* @name: the filename whose parent's name to find
|
||||
*
|
||||
*/
|
||||
static void get_parent_name(struct filename* name, ntfs_volume* vol) {
|
||||
static void get_parent_name (struct filename* name, ntfs_volume* vol)
|
||||
{
|
||||
ntfs_attr* mft_data;
|
||||
MFT_RECORD* rec;
|
||||
FILE_NAME_ATTR* filename_attr;
|
||||
|
@ -784,21 +788,19 @@ static void get_parent_name(struct filename* name, ntfs_volume* vol) {
|
|||
|
||||
rec = calloc(1, vol->mft_record_size);
|
||||
if (!rec) {
|
||||
Eprintf ("Couldn't allocate memory in get_parent_name()\n");
|
||||
Eprintf ("ERROR: Couldn't allocate memory in get_parent_name()\n");
|
||||
return;
|
||||
}
|
||||
|
||||
mft_data = ntfs_attr_open(vol->mft_ni, AT_DATA, NULL, 0);
|
||||
if (!mft_data) {
|
||||
Eprintf ("Couldn't open $MFT/$DATA: %s\n", strerror (errno));
|
||||
}
|
||||
else {
|
||||
Eprintf ("ERROR: Couldn't open $MFT/$DATA: %s\n", strerror (errno));
|
||||
} else {
|
||||
inode_num = MREF(name->parent_mref);
|
||||
|
||||
if (ntfs_attr_pread(mft_data, vol->mft_record_size * inode_num, vol->mft_record_size, rec) < 1) {
|
||||
Eprintf ("Couldn't read MFT Record %lld.\n", inode_num);
|
||||
}
|
||||
else {
|
||||
Eprintf ("ERROR: Couldn't read MFT Record %lld.\n", inode_num);
|
||||
} else {
|
||||
if ((filename_attr = verify_parent(name, rec))) {
|
||||
if (ntfs_ucstombs(filename_attr->file_name, filename_attr->file_name_length, &name->parent_name, 0) < 0) {
|
||||
Dprintf ("Couldn't translate filename to current locale.\n");
|
||||
|
@ -860,7 +862,7 @@ static int get_filenames (struct ufile *file, ntfs_volume* vol)
|
|||
|
||||
name = calloc (1, sizeof (*name));
|
||||
if (!name) {
|
||||
Eprintf ("Couldn't allocate memory in get_filenames().\n");
|
||||
Eprintf ("ERROR: Couldn't allocate memory in get_filenames().\n");
|
||||
count = -1;
|
||||
break;
|
||||
}
|
||||
|
@ -879,7 +881,7 @@ static int get_filenames (struct ufile *file, ntfs_volume* vol)
|
|||
|
||||
if (ntfs_ucstombs (name->uname, name->uname_len, &name->name,
|
||||
name->uname_len) < 0) {
|
||||
Dprintf ("Couldn't translate filename to current locale.\n");
|
||||
Dprintf ("ERROR: Couldn't translate filename to current locale.\n");
|
||||
}
|
||||
|
||||
name->parent_name = NULL;
|
||||
|
@ -939,7 +941,7 @@ static int get_data (struct ufile *file, ntfs_volume *vol)
|
|||
while ((rec = find_attribute (AT_DATA, ctx))) {
|
||||
data = calloc (1, sizeof (*data));
|
||||
if (!data) {
|
||||
Eprintf ("Couldn't allocate memory in get_data().\n");
|
||||
Eprintf ("ERROR: Couldn't allocate memory in get_data().\n");
|
||||
count = -1;
|
||||
break;
|
||||
}
|
||||
|
@ -954,7 +956,7 @@ static int get_data (struct ufile *file, ntfs_volume *vol)
|
|||
|
||||
if (ntfs_ucstombs (data->uname, data->uname_len, &data->name,
|
||||
data->uname_len) < 0) {
|
||||
Eprintf ("Cannot translate name into current locale.\n");
|
||||
Eprintf ("ERROR: Cannot translate name into current locale.\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1007,7 +1009,7 @@ static struct ufile * read_record (ntfs_volume *vol, long long record)
|
|||
|
||||
file = calloc (1, sizeof (*file));
|
||||
if (!file) {
|
||||
Eprintf ("Couldn't allocate memory in read_record()\n");
|
||||
Eprintf ("ERROR: Couldn't allocate memory in read_record()\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1017,20 +1019,20 @@ static struct ufile * read_record (ntfs_volume *vol, long long record)
|
|||
|
||||
file->mft = malloc (vol->mft_record_size);
|
||||
if (!file->mft) {
|
||||
Eprintf ("Couldn't allocate memory in read_record()\n");
|
||||
Eprintf ("ERROR: Couldn't allocate memory in read_record()\n");
|
||||
free_file (file);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mft = ntfs_attr_open (vol->mft_ni, AT_DATA, NULL, 0);
|
||||
if (!mft) {
|
||||
Eprintf ("Couldn't open $MFT/$DATA: %s\n", strerror (errno));
|
||||
Eprintf ("ERROR: Couldn't open $MFT/$DATA: %s\n", strerror (errno));
|
||||
free_file (file);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ntfs_attr_mst_pread (mft, vol->mft_record_size * record, 1, vol->mft_record_size, file->mft) < 1) {
|
||||
Eprintf ("Couldn't read MFT Record %lld.\n", record);
|
||||
Eprintf ("ERROR: Couldn't read MFT Record %lld.\n", record);
|
||||
ntfs_attr_close (mft);
|
||||
free_file (file);
|
||||
return NULL;
|
||||
|
@ -1045,8 +1047,7 @@ static struct ufile * read_record (ntfs_volume *vol, long long record)
|
|||
|
||||
Dprintf ("Attributes present: %s %s %s\n", attr10?"0x10":"", attr20?"0x20":"", attr90?"0x90":"");
|
||||
|
||||
if (attr10)
|
||||
{
|
||||
if (attr10) {
|
||||
STANDARD_INFORMATION *si;
|
||||
si = (STANDARD_INFORMATION *) ((char *) attr10 + le16_to_cpu (attr10->value_offset));
|
||||
file->date = ntfs2utc (sle64_to_cpu (si->last_data_change_time));
|
||||
|
@ -1058,10 +1059,10 @@ static struct ufile * read_record (ntfs_volume *vol, long long record)
|
|||
file->directory = 1;
|
||||
|
||||
if (get_filenames (file, vol) < 0) {
|
||||
Eprintf ("Couldn't get filenames.\n");
|
||||
Eprintf ("ERROR: Couldn't get filenames.\n");
|
||||
}
|
||||
if (get_data (file, vol) < 0) {
|
||||
Eprintf ("Couldn't get data streams.\n");
|
||||
Eprintf ("ERROR: Couldn't get data streams.\n");
|
||||
}
|
||||
|
||||
return file;
|
||||
|
@ -1179,7 +1180,7 @@ static int calc_percentage (struct ufile *file, ntfs_volume *vol)
|
|||
}
|
||||
|
||||
if ((clusters_inuse + clusters_free) == 0) {
|
||||
Eprintf ("Unexpected error whilst calculating percentage for inode %lld\n", file->inode);
|
||||
Eprintf ("ERROR: Unexpected error whilst calculating percentage for inode %lld\n", file->inode);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1369,6 +1370,7 @@ static void list_record (struct ufile *file)
|
|||
Qprintf ("%-8lld %c%c%c%c %3d%% %s %9lld %s\n",
|
||||
file->inode, flagd, flagr, flagc, flagx,
|
||||
percent, buffer, size, name);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1533,7 +1535,7 @@ static int set_date (const char *pathname, time_t date)
|
|||
ut.actime = date;
|
||||
ut.modtime = date;
|
||||
if (utime (pathname, &ut)) {
|
||||
Eprintf ("Couldn't set the file's date and time\n");
|
||||
Eprintf ("ERROR: Couldn't set the file's date and time\n");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
|
@ -1570,14 +1572,14 @@ static int scan_disk (ntfs_volume *vol)
|
|||
|
||||
attr = ntfs_attr_open (vol->mft_ni, AT_BITMAP, AT_UNNAMED, 0);
|
||||
if (!attr) {
|
||||
Eprintf ("Couldn't open $MFT/$BITMAP: %s\n", strerror (errno));
|
||||
Eprintf ("ERROR: Couldn't open $MFT/$BITMAP: %s\n", strerror (errno));
|
||||
return -1;
|
||||
}
|
||||
bmpsize = attr->initialized_size;
|
||||
|
||||
buffer = malloc (BUFSIZE);
|
||||
if (!buffer) {
|
||||
Eprintf ("Couldn't allocate memory in scan_disk()\n");
|
||||
Eprintf ("ERROR: Couldn't allocate memory in scan_disk()\n");
|
||||
results = -1;
|
||||
goto out;
|
||||
}
|
||||
|
@ -1588,7 +1590,7 @@ static int scan_disk (ntfs_volume *vol)
|
|||
if (!opts.match_case)
|
||||
flags |= REG_ICASE;
|
||||
if (regcomp (&re, opts.match, flags)) {
|
||||
Eprintf ("Couldn't create a regex.\n");
|
||||
Eprintf ("ERROR: Couldn't create a regex.\n");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
@ -1596,7 +1598,7 @@ static int scan_disk (ntfs_volume *vol)
|
|||
nr_mft_records = vol->mft_na->initialized_size >>
|
||||
vol->mft_record_size_bits;
|
||||
|
||||
Qprintf ("Inode Flags %%age Date Size Filename\n");
|
||||
Qprintf ("Inode Flags %%age Date Size Filename\n");
|
||||
Qprintf ("---------------------------------------------------------------\n");
|
||||
for (i = 0; i < bmpsize; i += BUFSIZE) {
|
||||
long long read_count = min ((bmpsize - i), BUFSIZE);
|
||||
|
@ -1627,14 +1629,22 @@ static int scan_disk (ntfs_volume *vol)
|
|||
goto skip;
|
||||
|
||||
percent = calc_percentage (file, vol);
|
||||
|
||||
if ((opts.percent == -1) || (percent >= opts.percent)) {
|
||||
if (opts.verbose)
|
||||
dump_record (file);
|
||||
else
|
||||
list_record (file);
|
||||
}
|
||||
|
||||
/* Was -u specified with no inode
|
||||
so undelete file by regex */
|
||||
if (opts.mode == MODE_UNDELETE) {
|
||||
if (!undelete_file (vol, file->inode))
|
||||
Vprintf ("ERROR: Failed to undelete "
|
||||
"inode %lli\n!",
|
||||
file->inode);
|
||||
printf ("\n");
|
||||
}
|
||||
}
|
||||
if (((opts.percent == -1) && (percent > 0)) ||
|
||||
((opts.percent > 0) && (percent >= opts.percent))) {
|
||||
results++;
|
||||
|
@ -1696,12 +1706,23 @@ static int undelete_file (ntfs_volume *vol, long long inode)
|
|||
if (!vol)
|
||||
return 0;
|
||||
|
||||
/* try to get record */
|
||||
file = read_record (vol, inode);
|
||||
if (!file || !file->mft) {
|
||||
Eprintf ("Can't read info from mft record %lld.\n", inode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* if flag was not set, print file informations */
|
||||
if (avoid_duplicate_printing == 0) {
|
||||
if (opts.verbose) {
|
||||
dump_record (file);
|
||||
} else {
|
||||
list_record (file);
|
||||
//Qprintf ("\n");
|
||||
}
|
||||
}
|
||||
|
||||
bufsize = vol->cluster_size;
|
||||
buffer = malloc (bufsize);
|
||||
if (!buffer)
|
||||
|
@ -1722,15 +1743,6 @@ static int undelete_file (ntfs_volume *vol, long long inode)
|
|||
goto free;
|
||||
}
|
||||
|
||||
if (opts.verbose) {
|
||||
dump_record (file);
|
||||
} else {
|
||||
Qprintf ("Inode Flags %%age Date Size Filename\n");
|
||||
Qprintf ("---------------------------------------------------------------\n");
|
||||
list_record (file);
|
||||
Qprintf ("\n");
|
||||
}
|
||||
|
||||
if (list_empty (&file->data)) {
|
||||
Qprintf ("File has no data. There is nothing to recover.\n");
|
||||
goto free;
|
||||
|
@ -1986,6 +1998,46 @@ free:
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* handle_undelete
|
||||
* Handles the undelete
|
||||
*/
|
||||
int handle_undelete (ntfs_volume *vol)
|
||||
{
|
||||
int result = 1;
|
||||
int i;
|
||||
unsigned long long inode;
|
||||
|
||||
/* Check whether (an) inode(s) was specified or at least a regex! */
|
||||
if (nr_entries == 0) {
|
||||
if (with_regex == 0) {
|
||||
printf ("ERROR: NO inode(s) AND NO match-regex specified!\n");
|
||||
} else {
|
||||
avoid_duplicate_printing= 1;
|
||||
result = !scan_disk (vol);
|
||||
if (result)
|
||||
Vprintf ("ERROR: Failed to scan device '%s'.\n", opts.device);
|
||||
}
|
||||
} else {
|
||||
/* Normal undelete by specifying inode(s) */
|
||||
Qprintf ("Inode Flags %%age Date Size Filename\n");
|
||||
Qprintf ("---------------------------------------------------------------\n");
|
||||
|
||||
/* loop all given inodes */
|
||||
for (i = 0; i < nr_entries; i++) {
|
||||
for (inode = ranges[i].begin; inode <= ranges[i].end; inode ++) {
|
||||
/* Now undelete file */
|
||||
result = !undelete_file (vol, inode);
|
||||
if (result)
|
||||
Vprintf ("ERROR: Failed to undelete "
|
||||
"inode %lli\n!",
|
||||
inode);
|
||||
}
|
||||
}
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
|
||||
/**
|
||||
* main - Begin here
|
||||
*
|
||||
|
@ -1996,11 +2048,11 @@ free:
|
|||
*/
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
s64 nr_mft_records;
|
||||
ntfs_volume *vol;
|
||||
int result = 1;
|
||||
int i;
|
||||
u32 inode;
|
||||
|
||||
with_regex = 0;
|
||||
avoid_duplicate_printing = 0;
|
||||
|
||||
if (!parse_options (argc, argv))
|
||||
goto free;
|
||||
|
@ -2011,39 +2063,28 @@ int main (int argc, char *argv[])
|
|||
if (!vol)
|
||||
return 1;
|
||||
|
||||
/* handling of the different modes */
|
||||
switch (opts.mode) {
|
||||
/* Scanning */
|
||||
case MODE_SCAN:
|
||||
result = !scan_disk (vol);
|
||||
if (result)
|
||||
Vprintf ("Failed to scan device '%s'.\n", opts.device);
|
||||
Vprintf ("ERROR: Failed to scan device '%s'.\n", opts.device);
|
||||
break;
|
||||
|
||||
/* Undelete-handling */
|
||||
case MODE_UNDELETE:
|
||||
if (nr_entries == 0)
|
||||
{
|
||||
printf ("ERROR: No inode(s) specified!\n");
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < nr_entries; i++)
|
||||
{
|
||||
for (inode = ranges[i].begin; inode <= ranges[i].end; inode ++)
|
||||
{
|
||||
result = !undelete_file (vol, inode);
|
||||
if (result)
|
||||
Vprintf ("ERROR: Failed to undelete "
|
||||
"inode %u\n!",
|
||||
(unsigned int)inode);
|
||||
}
|
||||
}
|
||||
result= handle_undelete (vol);
|
||||
break;
|
||||
case MODE_COPY:
|
||||
nr_mft_records = vol->mft_na->initialized_size >>
|
||||
vol->mft_record_size_bits;
|
||||
|
||||
/* Handling of copy mft */
|
||||
case MODE_COPY:
|
||||
result = !copy_mft (vol, opts.mft_begin, opts.mft_end);
|
||||
if (result)
|
||||
Vprintf ("Failed to read MFT blocks %lld-%lld.\n",
|
||||
opts.mft_begin, min(nr_mft_records, opts.mft_end));
|
||||
Vprintf ("ERROR: Failed to read MFT blocks %lld-%lld.\n",
|
||||
opts.mft_begin,
|
||||
min((vol->mft_na->initialized_size >>
|
||||
vol->mft_record_size_bits) , opts.mft_end));
|
||||
break;
|
||||
default:
|
||||
; /* Cannot happen */
|
||||
|
|
Loading…
Reference in New Issue