格式化后的数据恢复源码(C++)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
/*
// Program: Free Unformat
// Version: 0.8
// Written By: Brian E. Reifsnyder
// Copyright 1999 under the terms of the GNU GPL by Brian E. Reifsnyder
//
// Note: This program is free and is without a warranty of any kind.
//
*/
/*
/////////////////////////////////////////////////////////////////////////////
// INCLUDES
/////////////////////////////////////////////////////////////////////////////
*/
#include
#include
#include
#include
#include
/*
/////////////////////////////////////////////////////////////////////////////
// DEFINES
/////////////////////////////////////////////////////////////////////////////
*/
#define FOUND 1
#define LIST 1
#define TRUE 1
#define FALSE 0
#define NULL 0
#define PERCENTAGE 1
#define PRIMARY 0
#define EXTENDED 1
#define HARD 0
#define FLOPPY 1
#define FAT12 0
#define FAT16 1
#define FAT32 2
/*
/////////////////////////////////////////////////////////////////////////////
// GLOBAL VARIABLES
/////////////////////////////////////////////////////////////////////////////
*/
int list_file_and_directory_names = 0;
int print_output = 0;
int test = 0;
int unformat_without_mirror_file = 0;
long sectors_per_fat;
/* Physical Drive Parameters */
int physical_drive;
int logical_drive;
unsigned long logical_sector_offset;
long total_cylinders;
long total_heads;
long total_sectors;
long floppy_drive_type;
int drive_type;
int media_descriptor;
/* Logical drive information */
long sectors_in_root_dir;
int type_of_fat;
unsigned long number_of_logical_sectors_on_drive;
long number_of_root_directory_entries;
/* Extracted cylinder & sector from partition table */
unsigned long g_cylinder;
unsigned long g_sector;
/* Partition Information */
int numeric_partition_type[24];
unsigned long starting_cylinder[24];
unsigned long starting_head[24];
unsigned long starting_sector[24];
unsigned long ending_cylinder[24];
unsigned long ending_head[24];
unsigned long ending_sector[24];
int relative_sectors_1[24];
int relative_sectors_2[24];
int relative_sectors_3[24];
int relative_sectors_4[24];
int partition_size_1[24];
int partition_size_2[24];
int partition_size_3[24];
int partition_size_4[24];
unsigned long partition_size[24];
int number_of_partitions;
/* "Logical Drive to Format" translation information */
int physical_drive_number;
unsigned long partition_starting_cylinder;
unsigned long partition_starting_head;
unsigned long partition_starting_sector;
unsigned long partition_ending_cylinder;
unsigned long partition_ending_head;
unsigned long partition_ending_sector;
unsigned long drive_maximum_cylinders;
unsigned long drive_maximum_heads;
unsigned long drive_maximum_sectors;
unsigned long total_logical_sectors;
unsigned long total_physical_sectors;
int number_of_sectors_per_cluster;
int partition_on_hard_disk;
/* T
ranslated values from "void Convert_Logical_To_Physical" */
unsigned long translated_head;
unsigned long translated_cylinder;
unsigned long translated_sector;
/* Misc variables */
unsigned long integer1;
unsigned long integer2;
unsigned long integer3;
unsigned long integer4;
/* Buffers */
unsigned char mirror_map[5120];
unsigned char control_buffer[512];
unsigned char sector_buffer[512];
/*
/////////////////////////////////////////////////////////////////////////////
// PROTOTYPES
/////////////////////////////////////////////////////////////////////////////
*/
int Compare_Sector_Buffers();
unsigned long Decimal_Number(unsigned long hex1, unsigned long hex2, unsigned long hex3, unsigned long hex4);
void Copy_Sector_Into_Control_Buffer();
void Display_Help_Screen();
void List_Names();
void Read_Mirror_Map();
void Restore_Partition_Tables(int list);
void Unformat_Drive();
void Verify_Drive_Mirror();
//////////////
void Clear_Sector_Buffer();
void Convert_Huge_To_Integers(unsigned long number);
void Convert_Logical_To_Physical(unsigned long sector);
void Extract_Cylinder_and_Sector(unsigned long hex1, unsigned long hex2);
void Get_Drive_Parameters();
void Get_Physical_Floppy_Drive_Parameters();
void Get_Physical_Hard_Drive_Parameters();
void Read_Partition_Table();
void Read_Physical_Sector(int drive, int head, long cyl, int sector);
void Read_Sector(unsigned long sector);
void Reset_Drive();
void Write_Physical_Sector(int drive, int head, long cyl, int sector);
void Write_Sector(unsigned long sector);
/*
/////////////////////////////////////////////////////////////////////////////
// FUNCTIONS
/////////////////////////////////////////////////////////////////////////////
*/
/* Clear Sector Buffer */
void Clear_Sector_Buffer()
{
long loop=0;
do
{
sector_buffer[loop]=0;
loop++;
}while(loop<512);
}
/* Convert a logical sector to a physical drive location */
void Convert_Logical_To_Physical(unsigned long sector)
{
unsigned long remaining;
if(drive_type==HARD) sector=sector+logical_sector_offset;
translated_cylinder=sector/(total_sectors*(total_heads+1));
remaining=sector % (total_sectors*(total_heads+1));
translated_head=remaining/(total_sectors);
translated_sector=remaining % (total_sectors);
translated_sector++;
}
/* Compare Sector Buffers ///////////// */
int Compare_Sector_Buffers()
{
int answer=0;
int compare=0;
int loop = 0;
do
{
compare=control_buffer[loop]-sector_buffer[loop];
if(compare!=0) answer = 1;
loop++;
} while(loop<512);
return(answer);
}
/* Copy sector into control buffer //// */
void Copy_Sector_Into_Control_Buffer()
{
int loop=0;
do
{
control_buffer[loop]=sector_buffer[loop];
loop++;
} while(loop<=512);
}
/* Convert Hexidecimal Number to a Decimal Number */
unsigned long Decimal_Number(unsigned long hex1, unsigned lo
ng hex2, unsigned long hex3, unsigned long hex4)
{
return((hex1) + (hex2*256) + (hex3*65536) + (hex4*16777216));
}
/* Extract Cylinder & Sector */
void Extract_Cylinder_and_Sector(unsigned long hex1, unsigned long hex2)
{
unsigned long cylinder_and_sector = ( (256*hex2) + hex1 );
g_sector = cylinder_and_sector % 64;
g_cylinder = ( ( (cylinder_and_sector*4) & 768) + (cylinder_and_sector /256) );
}
/* Get Drive Parameters */
/* The physical drive parameters are necessary to allow this program */
/* to bypass the DOS interrupts. */
void Get_Drive_Parameters()
{
int drives_found_flag;
long hard_disk_installed[8];
int increment_heads=FALSE;
int logical_drive_found=FALSE;
int partition_number_of_logical_drive;
int pointer=0;
int possible_logical_drive;
int possible_physical_hard_disk;
int sub_pointer=0;
int result;
/* Brief partition table variables */
long partition_type_table[8][26];
long maximum_partition_assigned[8];
if(drive_type==FLOPPY)
{
physical_drive=logical_drive;
Get_Physical_Floppy_Drive_Parameters();
partition_starting_cylinder=0;
partition_starting_head=0;
partition_starting_sector=1;
partition_ending_cylinder=total_cylinders;
partition_ending_head=total_heads;
partition_ending_sector=total_sectors;
drive_maximum_cylinders=total_cylinders;
drive_maximum_heads=1;
drive_maximum_sectors=total_sectors;
total_logical_sectors=(total_cylinders+1)*(total_heads+1)*total_sectors;
total_physical_sectors=total_logical_sectors;
number_of_sectors_per_cluster=1;
}
else
{
/* Get availability of physical hard drives and */
/* assemble a brief partition table. */
/* Initialize partition_type_table */
pointer=0;
do
{
partition_type_table[0][pointer]=0;
partition_type_table[1][pointer]=0;
partition_type_table[2][pointer]=0;
partition_type_table[3][pointer]=0;
partition_type_table[4][pointer]=0;
partition_type_table[5][pointer]=0;
partition_type_table[6][pointer]=0;
partition_type_table[7][pointer]=0;
pointer++;
}while(pointer<=26);
/* Initialize maximum_partition_assigned */
maximum_partition_assigned[0]=0;
maximum_partition_assigned[1]=0;
maximum_partition_assigned[2]=0;
maximum_partition_assigned[3]=0;
maximum_partition_assigned[4]=0;
maximum_partition_assigned[5]=0;
maximum_partition_assigned[6]=0;
maximum_partition_assigned[7]=0;
pointer=128;
drives_found_flag=FALSE;
do
{
result=biosdisk(2, pointer, 0, 0, 1, 1, sector_buffer);
if(result==0)
{
drives_found_flag=TRUE;
hard_disk_installed[pointer-128]=TRUE;
physical_drive=pointer;
Read_Partition_Table();
sub_pointer=0;
do
{
partition_type_table[pointer-128][sub_po
inter]=numeric_partition_type[sub_pointer];
sub_pointer++;
}while(sub_pointer<=number_of_partitions);
maximum_partition_assigned[pointer-128]=number_of_partitions;
}
else hard_disk_installed[pointer-128]=FALSE;
pointer++;
}while(pointer<136);
/* If there aren't any physical hard drives available, exit program */
if(drives_found_flag==FALSE)
{
printf("\nNo hard disks found...operation terminated.\n");
exit(4);
}
/* Determine on which physical hard drive the logical drive is */
/* and on which partition it is located. */
/* Check on primary partitions */
possible_logical_drive=1;
possible_physical_hard_disk=128;
do
{
if(hard_disk_installed[possible_physical_hard_disk-128]==TRUE)
{
pointer=0;
do
{
if( (partition_type_table[possible_physical_hard_disk-128][pointer]==0x01) || (partition_type_table[possible_physical_hard_disk-128][pointer]==0x04) || (partition_type_table[possible_physical_hard_disk-128][pointer]==0x06) )
{
possible_logical_drive++;
if(logical_drive==possible_logical_drive)
{
physical_drive=possible_physical_hard_disk;
partition_number_of_logical_drive=pointer;
logical_drive_found=TRUE;
}
}
pointer++;
}while(pointer<4);
}
possible_physical_hard_disk++;
}while(possible_physical_hard_disk<136);
/* Check on extended partitions */
possible_physical_hard_disk=128;
if(logical_drive_found==FALSE)
{
do
{
if( (hard_disk_installed[possible_physical_hard_disk-128]==TRUE) && (maximum_partition_assigned[possible_physical_hard_disk-128]>=4) )
{
pointer=4;
do
{
if( (partition_type_table[possible_physical_hard_disk-128][pointer]==0x01) || (partition_type_table[possible_physical_hard_disk-128][pointer]==0x04) || (partition_type_table[possible_physical_hard_disk-128][pointer]==0x06) )
{
possible_logical_drive++;
if(logical_drive==possible_logical_drive)
{
physical_drive=possible_physical_hard_disk;
partition_number_of_logical_drive=pointer;
increment_heads=TRUE;
logical_drive_found=TRUE;
}
}
pointer++;
}while(pointer<=maximum_partition_assigned[possible_physical_hard_disk-128]);
}
possible_physical_hard_disk++;
}while(possible_physical_hard_disk<136);
}
/* Get a full partition table listing for that drive */
if(logical_drive_found==TRUE)
{
Get_Physical_Hard_Drive_Parameters();
Read_Partition_Table();
}
else
{
printf("\nDrive letter entered is out of range...operation terminated.\n");
exit(4);
}
/* Load physical partition information */
partition_starting_cylinder=starting_cylinder[partition_number_of_logical_drive];
partition_starting_head=starting_head[partition_number_of
_logical_drive];
partition_starting_sector=starting_sector[partition_number_of_logical_drive];
partition_ending_cylinder=ending_cylinder[partition_number_of_logical_drive];
partition_ending_head=ending_head[partition_number_of_logical_drive];
partition_ending_sector=ending_sector[partition_number_of_logical_drive];
drive_maximum_cylinders=ending_cylinder[partition_number_of_logical_drive];
drive_maximum_heads=total_heads;
drive_maximum_sectors=total_sectors;
total_logical_sectors=((partition_ending_cylinder-partition_starting_cylinder)+1)*(total_heads+1)*total_sectors;
total_physical_sectors=total_logical_sectors;
logical_sector_offset=((partition_starting_cylinder)*(total_heads+1)*(total_sectors));
if(logical_sector_offset==0) logical_sector_offset=(partition_starting_head)*(total_sectors);
if(increment_heads==TRUE) logical_sector_offset=logical_sector_offset+total_sectors;
/* Compute cluster size */
unsigned long size=(total_logical_sectors*512)/1000000;
/* Sectors per cluster conversion table */
if (size<=32767) number_of_sectors_per_cluster=64;
if (size<=16383) number_of_sectors_per_cluster=32;
if (size<=8191) number_of_sectors_per_cluster=16;
/* May be illegal cluster sizes
if (size<=256) number_of_sectors_per_cluster=8;
if (size<=128) number_of_sectors_per_cluster=4;
*/
}
}
/* Get Physical Floppy Drive Parameters */
void Get_Physical_Floppy_Drive_Parameters()
{
asm{
mov ah, 0x08
mov dl, BYTE PTR physical_drive
int 0x013
mov BYTE PTR total_sectors, cl
mov BYTE PTR total_cylinders, ch
mov BYTE PTR total_heads, dh
mov BYTE PTR floppy_drive_type, bl
}
}
/* Get Physical Hard Drive Parameters */
void Get_Physical_Hard_Drive_Parameters()
{
asm{
mov ah, 0x08
mov dl, BYTE PTR physical_drive
int 0x13
mov bl,cl
and bl,00111111B
mov BYTE PTR total_sectors, bl
mov bl,cl
mov cl,ch
shr bl,1
shr bl,1
shr bl,1
shr bl,1
shr bl,1
shr bl,1
mov ch,bl
mov WORD PTR total_cylinders, cx
mov BYTE PTR total_heads, dh
}
}
/* List File & Directory Names //////// */
void List_Names()
{
int loop=0;
int sub_loop=0;
char file_or_directory [12];
file_or_directory [8] = 46;
do
{
sub_loop = 0;
do
{
file_or_directory[sub_loop]=sector_buffer[(loop+sub_loop)];
sub_loop++;
} while(sub_loop <=7);
sub_loop++;
do
{
file_or_directory[sub_loop]=sector_buffer[(loop+sub_loop-1)];
sub_loop++;
} while(sub_loop <=11);
if( (file_or_directory[0]>=48) && (file_or_directory[0]<=122) )
{
printf("\n%.12s",file_or_directory);
}
loop = loop + 32;
} while(loop <=480);
}
/* Help Routine ////////////////////// */
void Display_Help_Screen()
{
printf("\nUnform
at Version 0.8 Restores a disk that has been formatted.\n\n");
printf("Syntax:\n\n");
printf("UNFORMAT drive: [/J]\n");
printf("UNFORMAT drive: [/U] [/L] [/TEST] [/P]\n");
printf("UNFORMAT /PARTN [/L]\n");
printf("UNFORMAT /?\n\n");
printf(" drive: Drive letter to unformat.\n");
printf(" /J Verifies that the drive mirror files is synchronized with the disk.\n");
printf(" /U * Unformats without using MIRROR files.\n");
printf(" /L Lists all files and directories found, or, when used with the\n");
printf(" /PART switch, displays current partition tables.\n");
printf(" /TEST * Displays information but does not write changes to disk.\n");
printf(" /P * Sends output messages to LPT1.\n");
printf(" /PARTN Restores disk partition tables.\n\n");
printf(" /? Displays this help screen.\n");
printf("This program is copyright 1998 by Brian E. Reifsnyder under the terms of\n");
printf("GNU General Public License and is without warranty of any kind.\n");
printf("\n* Indicates functions not yet available.\n");
}
/* Read Partition Table */
void Read_Partition_Table()
{
long index=0x1be;
int exiting_primary=TRUE;
int extended=FALSE;
int partition_designation=PRIMARY;
int pointer=0;
int record_extended_info_flag=FALSE;
int done_flag=FALSE;
unsigned long extended_cylinder;
unsigned long extended_head;
unsigned long extended_sector;
Read_Physical_Sector(physical_drive,0,0,1);
do{
if(pointer==4) partition_designation=EXTENDED;
if((pointer>=4) && (extended==TRUE))
{
Read_Physical_Sector(physical_drive,extended_head,extended_cylinder,extended_sector);
extended=FALSE;
index=0x1be;
if(exiting_primary==FALSE)
{
pointer--;
}
else
{
exiting_primary=FALSE;
}
}
/* Determine Partition Type */
numeric_partition_type[pointer]=sector_buffer[index+4];
if(sector_buffer[index+4]==0x00)
{
if(partition_designation==EXTENDED)
{
number_of_partitions=pointer;
done_flag=TRUE;
}
}
if(sector_buffer[index+4]==0x05)
{
extended=TRUE;
record_extended_info_flag=TRUE;
}
starting_head[pointer] = sector_buffer[index+1];
ending_head[pointer] = sector_buffer[index+5];
partition_size[pointer]=Decimal_Number(sector_buffer[index+12],sector_buffer[index+13],sector_buffer[index+14],sector_buffer[index+15])/2000;
Extract_Cylinder_and_Sector(sector_buffer[index+2],sector_buffer[index+3]);
starting_cylinder[pointer]=g_cylinder;
starting_sector[pointer]=g_sector;
if((extended==TRUE) && (record_extended_info_flag==TRUE))
{
extended_cylinder=starting_cylinder[pointer];
extended_head=starting_head[pointer];
extended_sector=starting_sector[pointer];
record_extended_info_flag=FALSE;
}
Extract_Cy
linder_and_Sector(sector_buffer[index+6],sector_buffer[index+7]);
ending_cylinder[pointer]=g_cylinder;
ending_sector[pointer]=g_sector;
partition_size_1[pointer]=sector_buffer[index+12];
partition_size_2[pointer]=sector_buffer[index+13];
partition_size_3[pointer]=sector_buffer[index+14];
partition_size_4[pointer]=sector_buffer[index+15];
relative_sectors_1[pointer]=sector_buffer[index+8];
relative_sectors_2[pointer]=sector_buffer[index+9];
relative_sectors_3[pointer]=sector_buffer[index+10];
relative_sectors_4[pointer]=sector_buffer[index+11];
pointer++;
number_of_partitions=pointer-1;
if((extended==FALSE) && (pointer==4))
{
number_of_partitions=4;
done_flag=TRUE;
}
index=index + 16;
} while(done_flag==FALSE);
}
/* Read Physical Sector */
void Read_Physical_Sector(int drive, int head, long cyl, int sector)
{
int result;
result=biosdisk(2, drive, head, cyl, sector, 1, sector_buffer);
if (result!=0)
{
printf("\nRead error...operation terminated.\n");
exit(4);
}
}
/* Read Sector From Disk */
void Read_Sector(unsigned long sector)
{
Convert_Logical_To_Physical(sector);
printf("Cylinder: %5i ",translated_cylinder);
printf("Head: %2i \n",translated_head);
/* printf("Sector: %i \n",translated_sector); */
/* Re-position cursor back to the beginning of the line */
asm{
/* Get current video display mode */
mov ah,0x0f
int 0x10
/* Get cursor position */
mov ah,0x03
int 0x10
/* Set cursor position to beginning of line */
mov ah,0x02
sub dh,1
int 0x10
}
Read_Physical_Sector(physical_drive,translated_head,translated_cylinder,translated_sector);
}
/* Read Mirror Map Into Buffer //////// */
void Read_Mirror_Map()
{
int flag = 0;
long loop;
long mirror_map_pointer;
long index;
long subloop;
long current_sector;
long mirror_map_start_sector;
long source_sector;
long destination_sector;
printf("\n\nSearching for drive mirror...\n");
/*Find "pointer sector" at end of drive */
current_sector=total_logical_sectors-200;
if(current_sector<0)
{
current_sector=0;
}
/*If drive is a floppy drive, change the following: */
if(drive_type==FLOPPY)
{
current_sector=total_logical_sectors-10;
total_logical_sectors--;
}
do
{
Read_Sector(current_sector);
if((65==sector_buffer[4])&&(77==sector_buffer[5])&&(83==sector_buffer[6])&&(69==sector_buffer[7]))
{
mirror_map_start_sector=Decimal_Number(sector_buffer[0],sector_buffer[1],sector_buffer[2],sector_buffer[3]);
flag=FOUND;
}
current_sector++;
} while((current_sector<=total_logical_sectors) || (flag!=FOUND));
loop=0;
if(FOUND==flag)
{
/*Read Mirror Map into buffer */
printf("\n\nLoading drive mirror
...\n");
do
{
Read_Sector(mirror_map_start_sector+loop);
subloop=0;
do
{
mirror_map[subloop+(loop*512)]=sector_buffer[subloop];
subloop++;
}while(subloop<512);
loop++;
}while(loop<=10);
}
else
{
printf("\nThe sector that points to the drive mirror has not been found.\n");
printf("Operation Terminated.\n");
exit(1);
}
}
/* Reset drive controller */
void Reset_Drive()
{
asm{
mov ah,0
mov dl,BYTE PTR physical_drive
int 0x13
mov ah,0
mov dl,BYTE PTR physical_drive
int 0x13
}
}
/* Restore Partition Tables /////////// */
void Restore_Partition_Tables(int list)
{
if(list!=LIST)
{
/* Re-create the partition tables on the hard disks from the
/* a:partnsav.fil. */
/*
Map of the PARTNSAV.FIL for FreeDOS:
(I do not plan on using an MS-DOS compatible file.)
offset:00
FreeDOS partitio
n mirror file
offset:32-127 reserved for future expansion
offset:128(drive#) 129(lb offset) 130(mb offset) 131(lb dest cyl)
132(mb dest cyl) 133(lb dest head) 134(mb dest head) 135(dest sect.)
.
.
.
offset:1024 stored sector
offset:1536 stored sector
offset:2048 stored sector
.
.
.
*/
long index=0;
FILE *file_pointer;
unsigned char partition_table_map[1024];
int drive_number;
unsigned long destination_cylinder;
unsigned long destination_head;
unsigned long destination_sector;
/* Clear partition_table_map[] */
index=0;
do
{
partition_table_map[index]=0;
index++;
}while(index<=1023);
/* Load the map of the PARTNSAV.FIL file */
index=0;
file_pointer=fopen("A:\\PARTNSAV.FIL","rb");
if(file_pointer==NULL)
{
printf("\nError opening \"A:\\PARTNSAV.FIL\"...Operation terminated.\n");
exit(1);
}
/* Read the map from the PARTNSAV.FIL file */
test=fread(&partition_table_map,1024,1,file_pointer);
if(test==0)
{
printf("\nError reading \"A:\\PARTNSAV.FIL\"...Operation terminated.\n");
exit(1);
}
/* Write the partitions to the hard disk(s) */
index=128;
do
{
/* Read the drive number */
drive_number=partition_table_map[index+0];
/* Get the destination cylinder */
destination_cylinder=Decimal_Number(partition_table_map[index+3],partition_table_map[index+4],0,0);
/* Get the destination head */
destination_head=Decimal_Number(partition_table_map[index+5],partition_table_map[index+6],0,0);
/* Get the destination sector */
destination_sector=partition_table_map[index+7];
/* Read the partition sector from the partnsav.fil */
fread(sector_buffer,512,1,file_pointer);
/* Write the partition sector to the hard disk */
Wr
ite_Physical_Sector(drive_number,destination_head,destination_cylinder,destination_sector);
index=index+8;
}while(0!=partition_table_map[index]);
fclose(file_pointer);
}
else
{
/* List all of the partition tables */
printf("\nThis feature is not implemented at this time.\n");
}
exit(0);
}
/* Unformat Drive ///////////////////// */
void Unformat_Drive()
{
int loop;
long mirror_map_pointer;
long index;
long current_sector;
long mirror_map_start_sector;
long source_sector;
long destination_sector;
Read_Mirror_Map();
printf("\n\nUnformatting drive...\n");
/*Re-create the boot sector */
destination_sector=Decimal_Number(mirror_map[84],mirror_map[85],mirror_map[86],mirror_map[87]);
source_sector=Decimal_Number(mirror_map[88],mirror_map[89],mirror_map[90],mirror_map[91]);
Read_Sector(source_sector);
Write_Sector(destination_sector);
/* Get the size of the FAT tables from the boot sector */
Read_Sector(0);
sectors_per_fat=Decimal_Number(sector_buffer[22],sector_buffer[23],0,0);
/*Re-create the FAT tables */
mirror_map_pointer = 92;
index=1;
do
{
destination_sector=Decimal_Number(mirror_map[mirror_map_pointer],mirror_map[(mirror_map_pointer+1)],mirror_map[(mirror_map_pointer+2)],mirror_map[(mirror_map_pointer+3)]);
source_sector=Decimal_Number(mirror_map[(mirror_map_pointer+4)],mirror_map[(mirror_map_pointer+5)],mirror_map[(mirror_map_pointer+6)],mirror_map[(mirror_map_pointer+7)]);
Read_Sector(source_sector);
Write_Sector(destination_sector);
Write_Sector(destination_sector+sectors_per_fat);
mirror_map_pointer=mirror_map_pointer + 8;
index++;
} while(index<=sectors_per_fat);
/*Re-create the Root Directory */
loop=1;
/*If drive is a floppy drive, change the loop for a smaller root dir*/
if(drive_type==FLOPPY) loop=18;
do
{
destination_sector=Decimal_Number(mirror_map[mirror_map_pointer],mirror_map[(mirror_map_pointer+1)],mirror_map[(mirror_map_pointer+2)],mirror_map[(mirror_map_pointer+3)]);
source_sector=Decimal_Number(mirror_map[(mirror_map_pointer+4)],mirror_map[(mirror_map_pointer+5)],mirror_map[(mirror_map_pointer+6)],mirror_map[(mirror_map_pointer+7)]);
Read_Sector(source_sector);
/* If user wants the file and directory names listed, list them. */
if(1==list_file_and_directory_names) List_Names();
Write_Sector(destination_sector);
mirror_map_pointer=mirror_map_pointer + 8;
loop++;
} while(loop<=31);
printf("\n\nUnformat operation complete!\n");
}
/* Verify Drive Mirror //////////////// */
void Verify_Drive_Mirror()
{
long mirrored_sector;
long system_sector;
int loop;
long mirror_map_pointer;
long index;
long current_sector;
long mirror_map_start_sector;
Read_Mirror_Map();
printf("\n\nComparing drive mirror with file system...\n")
;
/*Compare the boot sector */
system_sector=Decimal_Number(mirror_map[84],mirror_map[85],mirror_map[86],mirror_map[87]);
mirrored_sector=Decimal_Number(mirror_map[88],mirror_map[89],mirror_map[90],mirror_map[91]);
Read_Sector(system_sector);
Copy_Sector_Into_Control_Buffer();
Read_Sector(mirrored_sector);
if(Compare_Sector_Buffers()!=0)
{
printf("\n\nVerification failed at boot sector...operation terminated.\n\n");
exit(1);
}
/*Compare the FAT tables */
mirror_map_pointer = 92;
index=1;
do
{
system_sector=Decimal_Number(mirror_map[mirror_map_pointer],mirror_map[(mirror_map_pointer+1)],mirror_map[(mirror_map_pointer+2)],mirror_map[(mirror_map_pointer+3)]);
mirrored_sector=Decimal_Number(mirror_map[(mirror_map_pointer+4)],mirror_map[(mirror_map_pointer+5)],mirror_map[(mirror_map_pointer+6)],mirror_map[(mirror_map_pointer+7)]);
Read_Sector(system_sector);
Copy_Sector_Into_Control_Buffer();
Read_Sector(mirrored_sector);
if(Compare_Sector_Buffers()!=0)
{
printf("\n\nVerification failed on 1st FAT table...operation terminated.\n\n");
exit(1);
}
Read_Sector(system_sector+sectors_per_fat);
if(Compare_Sector_Buffers()!=0)
{
printf("\n\nVerification failed on 2nd FAT table...operation terminated.\n\n");
exit(1);
}
mirror_map_pointer=mirror_map_pointer + 8;
index++;
} while(index<=sectors_per_fat);
/*Compare the Root Directory */
loop=1;
/*If drive is a floppy drive, change the loop for a smaller root dir*/
if( (0==logical_drive) || (1==logical_drive) ) loop=18;
do
{
system_sector=Decimal_Number(mirror_map[mirror_map_pointer],mirror_map[(mirror_map_pointer+1)],mirror_map[(mirror_map_pointer+2)],mirror_map[(mirror_map_pointer+3)]);
mirrored_sector=Decimal_Number(mirror_map[(mirror_map_pointer+4)],mirror_map[(mirror_map_pointer+5)],mirror_map[(mirror_map_pointer+6)],mirror_map[(mirror_map_pointer+7)]);
Read_Sector(system_sector);
Copy_Sector_Into_Control_Buffer();
Read_Sector(mirrored_sector);
if(Compare_Sector_Buffers()!=0)
{
printf("\n\nVerification failed at root directory...operation terminated.\n\n");
exit(1);
}
mirror_map_pointer=mirror_map_pointer + 8;
loop++;
} while(loop<=31);
printf("\n\nMirror image has been verified.\n\n");
exit(0);
}
/* Write Physical Sector */
void Write_Physical_Sector(int drive, int head, long cyl, int sector)
{
int result;
result=biosdisk(3, drive, head, cyl, sector, 1, sector_buffer);
if (result!=0)
{
printf("\nDisk write error...operation terminated.\n");
exit(4);
}
}
/* Write Sector To Disk */
void Write_Sector(unsigned long sector)
{
Convert_Logical_To_Physical(sector);
printf("Cylinder: %5i ",translated_cylinder);
printf("Head: %2i \n",transla
ted_head);
/* printf("Sector: %i \n",translated_sector); */
/* Re-position cursor back to the beginning of the line */
asm{
/* Get current video display mode */
mov ah,0x0f
int 0x10
/* Get cursor position */
mov ah,0x03
int 0x10
/* Set cursor position to beginning of line */
mov ah,0x02
sub dh,1
int 0x10
}
Write_Physical_Sector(physical_drive,translated_head,translated_cylinder,translated_sector);
}
/*
/////////////////////////////////////////////////////////////////////////////
// MAIN ROUTINE
/////////////////////////////////////////////////////////////////////////////
*/
void main(int argc, char *argv[])
{
int true=1;
/* if UNFORMAT is typed without any options */
if(argc==1)
{
Display_Help_Screen();
exit(1);
}
/* if UNFORMAT is typed with more than one option and
// the first option is "/?" or "/PARTN" or "/partn" */
if(argc>=2)
{
/* if "UNFORMAT /?" is entered */
true=strcmp("/?",argv[1]);
if(0==true)
{
Display_Help_Screen();
exit(0);
}
/* if "UNFORMAT /PARTN" or "UNFORMAT /partn" is entered */
if(0==stricmp("/PARTN",argv[1]))
{
if(argc==3)
{
/*if "UNFORMAT /PARTN /L" is entered */
if(0==stricmp("/L",argv[2]))
{
Restore_Partition_Tables(LIST);
exit(0);
}
printf("\nSyntax error, type \"UNFORMAT /?\" for help.\n");
exit(1);
}
else
{
Restore_Partition_Tables(FALSE);
exit(0);
}
}
}
/*if UNFORMAT is typed with a drive letter */
if(argc>=2)
{
char drive_letter[1];
char *input;
logical_drive=argv[1] [0];
if(logical_drive>=97) logical_drive = logical_drive - 97;
if(logical_drive>=65) logical_drive = logical_drive - 65;
if( (logical_drive<0) || (logical_drive> 25) )
{
printf("\nSyntax error, type \"UNFORMAT /?\" for help.\n");
exit(1);
}
drive_letter[0] = logical_drive+65;
drive_letter[1] = 58;
if(logical_drive>=2) drive_type=HARD;
else drive_type=FLOPPY;
Get_Drive_Parameters();
true=1;
true=stricmp("/j",argv[2]);
if(0==true) Verify_Drive_Mirror();
true=0;
if(0==true)
{
if(argc>=3)
{
int switch_to_test = (argc-1);
do
{
true=1;
true=stricmp("/u",argv[switch_to_test]);
if(0==true) unformat_without_mirror_file = 1;
true=1;
true=stricmp("/l",argv[switch_to_test]);
if(0==true) list_file_and_directory_names = 1;
true=1;
true=stricmp("/test",argv[switch_to_test]);
if(0==true) test = 1;
true=1;
true=stricmp("/p",argv[switch_to_test]);
if(0==true) print_output = 1;
switch_to_test--;
} while (switch_to_test>=2);
}
Unformat_Drive();
}
}
}