www.pudn.com > formatrecovery.rar > unformat.cpp
/* // 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; /* Translated 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 long 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_pointer]=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("\nUnformat 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_Cylinder_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 */ Write_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",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 } 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(); } } }