Rescuing Files From a Corrupted NTFS Partition

Yesterday a friend called and told me that one of his machines had faced a harddrive failure. The disk in question was an IBM Deskstar, ironically referred to as the IBM “Deathstar”. Windows couldn’t do much about it so he brought it to me so I could have a look at it.

Linux has excellent NTFS-support these days so the first thing to do was to try a simple mount, that however, resulted in I/O Errors and several warnings. To locate the exact failure point of the harddrive I started making a raw copy of the partition (the disk had one big 40GiB partition on it) using dd. After 35GiB the I/O Errors were once again present.

None of the Live-CDs I had collected throughout the years had utilities for actually checking or fixing NTFS file system problems, so I stumbled upon the Trinity Rescue Kit in my search for such a thing. The small ISO-image (about 85MiB) contains two different anti-virus utilities and a collection of NTFS file system tools (and a lot more), and was therefore suitable for my needs.

The NTFS related programs on the Live-CD are the following:

  • ntfscat - Like the traditional cat utility but it solely prints out files from NTFS file systems.
  • ntfsclone - A tool for making a clone of a NTFS partition, supports various interesting options.
  • ntfscluster - Locate the owner of any given sector or cluster on an NTFS partition.
  • ntfscp - Overwrite file on an NTFS partition.
  • ntfsfix - Check and fix some common errors, clear the LogFile and make Windows perform a thorough check next time it boots.
  • ntfsinfo- Show some information about an NTFS partition or one of the files or directories within it.
  • ntfslabel - Show, or set, an NTFS partition’s volume label.
  • ntfsls - List information about files in a directory residing on an NTFS partition.
  • ntfsmount - NTFS module for FUSE.
  • ntfsresize - Resize an NTFS partition without losing data.
  • ntfsundelete - Recover deleted files from an NTFS partition.

All of these utilities are part of the ntfsprogs collection.

The first thing to do was trying whether ntfsfix could resolve the issue. It showed me that the partition was flagged as corrupted but it could not alter the flag. Since I knew the disk was about to die anytime soon this didn’t matter. But in some cases this utility will probably make your day.

When I once again mounted the partition, this time using the ntfsmount utility the same I/O Errors showed up all over again, which makes perfect sense by the way, but I had to make sure the errors weren’t the result of a lousy NTFS driver on the previous system.

So basically I had a: damaged partition, flagged in such a way that Windows wouldn’t and couldn’t touch it, I/O Errors on traditional mounting and accessing, and like that wasn’t enough, the disk was about to die.

Although, all was not lost, the ntfsls utility could list portions of the partition’s content for me. And when I located the inode for it and gave that as an argument to the ntfscat utility, it worked. I could read the file the inode-number was referring to.

So the basic idea was to make ntfsls produce a list of files and their inode-number and then loop through it and dump it to a healthy disk using the ntfscat program.

If you’re curious about how ntfsls should be used, have a look at the help screen. The output will be something like:

Digitalkameran/Dag X:
18064 SANY0001.JPG
18065 SANY0002.JPG
18066 SANY0003.JPG
18067 SANY0004.JPG
18068 SANY0005.JPG
18069 SANY0006.JPG
18070 SANY0007.JPG
18071 SANY0008.JPG
18072 SANY0009.JPG
18073 SANY0010.JPG
18074 SANY0011.JPG
18075 SANY0012.JPG

Since many of the files I was asked to rescue were photos from their digital camera with the default naming scheme there were an awful lot of files with the same name. To avoid problems in the rescue loop I decided to dump the files to their own directory based on their inode-number. Which basically meant: my backup path was /backup, therefore, the file in the list named SANY0012.JPG with the inode-number of 18075 would be dumped to /backup/18075/SANY0012.JPG.

I dumped the result of ntfsls to a file using regular redirects (the >). After that I wrote a small script to work on the filelist and do the actual dump.

The script is very short and the code is listed below:

#!/bin/bash
LIST=${1}
cat ${LIST}|grep "[A-Z].[A-Z]"|awk ‘{print "mkdir -p /backup/"$1" && ntfscat -i "$1" /dev/hda1 > /backup/"$1"/"$2}’

NOTE: In my case I only needed to save their photos, all files had uppercase names, hence the [A-Z].[A-Z]. Change this to better sort out possible filenames in your scenario! Also, change the partition (in my case it was /dev/hda1) and the backup path if necessary.

When the script is executed, it prints out the lines from the list and sort out the ones containing possible filenames. When that is done it uses the awk utility to produce the actual command that does the dumping. The command generated will, if executed, make the desired directory (/backup/inode-number) and use ntfscat to dump the file to the backup directory.

If the list produced by the ntfsls program was directed to a file called list.txt and the script is saved as rescue.sh then invoking the following command:

sh rescue.sh list.txt

Would generate the necessary commands for rescuing the files described in the list, something like:

mkdir -p /backup/19933 && ntfscat -i 19933 /dev/hda1 > /backup/19933/SANY0002.JPG
mkdir -p /backup/19934 && ntfscat -i 19934 /dev/hda1 > /backup/19934/SANY0005.JPG
mkdir -p /backup/19935 && ntfscat -i 19935 /dev/hda1 > /backup/19935/SANY0006.JPG
mkdir -p /backup/19936 && ntfscat -i 19936 /dev/hda1 > /backup/19936/SANY0008.JPG
mkdir -p /backup/19937 && ntfscat -i 19937 /dev/hda1 > /backup/19937/SANY0009.JPG
mkdir -p /backup/19938 && ntfscat -i 19938 /dev/hda1 > /backup/19938/SANY0011.JPG
mkdir -p /backup/19939 && ntfscat -i 19939 /dev/hda1 > /backup/19939/SANY0013.JPG
mkdir -p /backup/19940 && ntfscat -i 19940 /dev/hda1 > /backup/19940/SANY0014.JPG
mkdir -p /backup/19941 && ntfscat -i 19941 /dev/hda1 > /backup/19941/SANY0016.JPG

If you feel like actually execute the rescue commands, you should redirect the output to a new script:

sh rescue.sh list.txt > myscript.sh

And then execute myscript.sh and it will do the actual rescue for you.

I managed to save all of his photos this way. Your mileage may vary though (as usual).

Leave a Reply