Có một cái nhìn
- ntfsclone (chỉ sao chép các lĩnh vực đang sử dụng)
- fixntfs.c để sửa lỗi bù thông tin khởi động
IIRC, Trinity Rescue Kit chứa các phần mềm cần thiết cũng như nhiều phần mềm khác (ssh, partimage, fdisk, fdisk, cfdisk, parted, gparted, testdisk, ntfsfix; ntfs-3g, rsync, v.v.).
/*
* fixntfs: change some attributes of an NTFS bootsector
*
* brought to you by Phoenix
* url: www.grhack.gr/phoenix
* mail: phoenix@grhack.gr
* irc: phoenix -> #grhack -> undernet
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
FILE *fd;
FILE *idfd;
struct stat fst;
unsigned char cab[32];
unsigned short log_heads;
unsigned short ntfs_heads;
unsigned short force_heads;
unsigned short ntfs_cab;
unsigned long long sectors;
unsigned long long new_sectors;
log_heads = 0;
ntfs_heads = 0;
force_heads = 0;
ntfs_cab = 0;
if(argc < 2)
{
fprintf(stderr, "Usage:\n\t%s <device> <total_sectors> <force_heads>\n", argv[0]);
exit(0);
}
fprintf(stderr, "Stating file %s... ", argv[1]);
stat(argv[1], &fst);
if(!S_ISBLK(fst.st_mode))
{
fprintf(stderr, "not a block device\n");
exit(-1);
}
fprintf(stderr, "a block device\n");
fprintf(stderr, "Opening device %s rw... ", argv[1]);
fd = fopen(argv[1], "r+");
if(!fd)
{
perror("open device");
exit(-1);
}
fprintf(stderr, "ok\n");
fprintf(stderr, "Checking partition... ");
fseek(fd, 3, SEEK_SET);
if(fread(cab, 1, 4, fd) != 4)
{
perror("read system_id");
exit(-1);
}
cab[5] = 0;
if(strncmp(cab, "NTFS", 4))
{
fprintf(stderr, "%s\n", cab);
exit(-1);
}
fprintf(stderr, "%s\n", cab);
fprintf(stderr, "Reading NTFS bootsector heads... ");
fseek(fd, 0x1a, SEEK_SET);
ntfs_heads = 0;
fread(&ntfs_heads, 1, 2, fd);
fprintf(stderr, "%u\n", ntfs_heads);
fprintf(stderr, "Reading NTFS bootsector sectors... ");
fseek(fd, 0x18, SEEK_SET);
ntfs_cab = 0;
fread(&ntfs_cab, 1, 2, fd);
fprintf(stderr, "%u\n", ntfs_cab);
fprintf(stderr, "Reading NTFS bootsector sectors_per_cluster... ");
fseek(fd, 0x0d, SEEK_SET);
ntfs_cab = 0;
fread(&ntfs_cab, 1, 1, fd);
fprintf(stderr, "%u\n", ntfs_cab);
fprintf(stderr, "Reading NTFS bootsector sectors_size... ");
fseek(fd, 0x0b, SEEK_SET);
ntfs_cab = 0;
fread(&ntfs_cab, 1, 2, fd);
fprintf(stderr, "%u\n", ntfs_cab);
fprintf(stderr, "Reading NTFS bootsector boot_loader_routine_jump... ");
fseek(fd, 0, SEEK_SET);
bzero(cab, sizeof(cab));
fread(cab, 1, 3, fd);
fprintf(stderr, "0x%x 0x%x 0x%x\n", cab[0], cab[1], cab[2]);
fprintf(stderr, "Reading NTFS bootsector total_sectors... ");
fseek(fd, 0x28, SEEK_SET);
sectors = 0;
fread(§ors, 1, 8, fd);
fprintf(stderr, "%Lu\n", sectors);
fprintf(stderr, "Reading device logical heads... ");
sprintf(cab, "/proc/ide/hd%c/geometry", *(strrchr(argv[1],'/') + 3));
idfd = fopen(cab, "r");
if(!idfd)
{
perror(cab);
exit(-1);
}
fscanf(idfd, "%*s %*s\n");
fscanf(idfd, "%*s %s\n", cab);
*(strrchr(cab, '/')) = 0;
log_heads = (unsigned short) atoi(strchr(cab, '/') + 1);
fprintf(stderr, "%u\n", log_heads);
if(argc == 4)
{
force_heads=atoi(argv[3]);
fprintf(stderr, "Forcing heads to %u\n", force_heads);
log_heads=force_heads;
}
if(fclose(fd) == EOF)
{
perror("close device");
exit(-1);
}
if(log_heads != ntfs_heads)
{
fprintf(stderr, "Heads are different... Logical=%u NTFS=%u\n\n"
"Update NTFS bootsector? (y/n) ",
log_heads, ntfs_heads);
if(getc(stdin) == 'y')
{
fd = fopen(argv[1], "r+");
if(!fd)
{
perror("open device");
exit(-1);
}
ntfs_heads = log_heads;
fseek(fd, 0x1a, SEEK_SET);
fwrite(&ntfs_heads, 1, 2, fd);
fprintf(stderr, "\nBootsector updated... Verifying... ");
fclose(fd);
fd = fopen(argv[1], "r");
if(!fd)
{
perror("open device");
exit(-1);
}
fseek(fd, 0x1a, SEEK_SET);
ntfs_heads = 0;
fread(&ntfs_heads, 1, 2, fd);
if(ntfs_heads == log_heads)
{
fprintf(stderr, "ok\n\n");
}
else
{
fprintf(stderr, "error [%u]\n", ntfs_heads);
exit(-1);
}
fclose(fd);
}
else
{
fprintf(stderr, "\nHeads update cancelled...\n");
}
getc(stdin);
}
if(argc >= 3 && atoll(argv[2]))
{
fprintf(stderr, "Update NTFS bootsector total_sectors from %Lu to %Lu? (y/n) ",
sectors, atoll(argv[2]));
if(getc(stdin) == 'y')
{
fd = fopen(argv[1], "r+");
if(!fd)
{
perror("open device");
exit(-1);
}
new_sectors = atoll(argv[2]);
fseek(fd, 0x28, SEEK_SET);
fwrite(&new_sectors, 1, 8, fd);
fprintf(stderr, "\nBootsector updated... Verifying... ");
fclose(fd);
fd = fopen(argv[1], "r");
if(!fd)
{
perror("open device");
exit(-1);
}
fseek(fd, 0x28, SEEK_SET);
sectors = 0;
fread(§ors, 1, 8, fd);
if(sectors == new_sectors)
{
fprintf(stderr, "ok\n\n");
}
else
{
fprintf(stderr, "error [%Lu]\n", sectors);
exit(-1);
}
fclose(fd);
}
else
{
fprintf(stderr, "\nTotal_sectors update cancelled...\n");
}
getc(stdin);
}
return(1);
}