#!/usr/bin/perl use strict; use Math::BigInt; sub ntfscluster { my ($start, $end, $device) = @_; my @results; my @out = `ntfscluster -s${start}-${end} $device 2>&1`; for(@out) { next if /^Error reading inode /; push @results, $_ if /^Inode /; print STDERR $_; } return @results; } sub find { my $lf = shift; my $device = shift; my $start_sector = shift; my $end_sector = shift; my $sector_size = shift; my $after_header = 0; my @ranges; open LF,"<$lf" or die("cannot open file: $lf\n"); foreach() { next if /^#/; $after_header=1,next if /^(0x[0-9A-F]+) +([-+?\/])$/ && !$after_header; /^(0x[0-9A-F]+) +(0x[0-9A-F]+) +([-+?\/])$/ or die("cannot parse line: $_\n"); $after_header = 1; my $status = $3; next if ($status eq '+'); my $start = new Math::BigInt($1)->bdiv($sector_size); my $size = new Math::BigInt($2)->bdiv($sector_size); my $end = $start + $size - 1; next if $start > $end_sector; next if $end < $start_sector; $start = $start_sector if $start < $start_sector; $end = $end_sector if $end > $end_sector; $start -= $start_sector; $end -= $start_sector; if ((@ranges > 0) && ($ranges[@ranges-1]->[1] + 1 == $start)) { $ranges[@ranges-1]->[1] = $end; } else { push @ranges, [ $start, $end ]; } } close LF; my @results; #print $_->[0]."-".$_->[1]."\n" for @ranges; #exit; push @results, ntfscluster(@$_, $device) for @ranges; my $prev = ''; @results = grep($_ ne $prev && (($prev) = $_), sort @results); return @results; } die("Usage: $0 log_file device start_sector end_sector [sector_size]\n") if @ARGV < 4; my $lf = $ARGV[0]; my $device = $ARGV[1]; my $start_sector = $ARGV[2]; my $end_sector = $ARGV[3]; my $sector_size = $ARGV[4] || 512; my @results = find($lf, $device, $start_sector, $end_sector, $sector_size); print "\nSCANNING RESULTS:\n\n"; print for @results;