Глава – 10
ВОССТАНОВЛЕНИЕ ДАННЫХ С ПОВРЕЖДЕННОЙ ДИСКЕТЫ
Восстановление данных с поврежденной дискеты
Дискета — один из самых ненадежных источников хранения данных. Если вы пойдете в любую организацию, которая использует компьютерные системы, и спросите ее сотрудников о проблемах, вызванных дискетами, вы очень часто услышите, что проблема заключается в том, что у сотрудника организации были некоторые важные данные на его дискете, и теперь дискета не читается компьютером, и на экране появляется сообщение, похожее на:
«Невозможно прочитать диск»
«Плохая дорожка 0»
«Неверный диск или емкость»
«Диск не отформатирован. Вы хотите отформатировать его сейчас?»
Это повседневная проблема для организаций, которые используют компьютерные системы и дискеты. Проблема становится критической, когда вы узнаете, что не было сделано резервной копии или резервная копия недоступна для данных, которые, кажется, потеряны на поврежденном дискете.
Самая большая проблема возникает, когда вы делаете резервную копию критически важной информации на дискете, восстанавливаете диски антивирусной программы для преодоления вирусной атаки или загрузочные записи или другие резервные копии (возможно, есть несколько вариантов) на дискете, и когда вы хотите повторно использовать резервную копию с дискеты, возникает ошибка чтения.
В таком случае вы рискуете потерять важную информацию и данные, а в некоторых случаях, когда вы чувствуете нехватку резервных копий и программ восстановления для загрузочной информации вашего компьютера, программ спасения от вирусных атак и т. д., вы можете понести большую потерю данных в виде сбоя ОС из-за отсутствия информации, хранящейся на дискете, которая в данный момент не может быть прочитана компьютером.
В таких случаях наиболее важным требованием становится восстановление данных с дискеты, которую ваша компьютерная система признала неисправной.
Почему дискета не читается
Наиболее распространенной проблемой, из-за которой дискета выдает подобные сообщения об ошибках, является повреждение загрузочной записи DOS (DBR) дискеты, которая помогает компьютеру узнать логическую идентификацию дискеты.
DBR — это небольшая программа , хранящаяся на дорожке 0, головке 0 и секторе 1 и содержащая важную информацию о дискете, такую как:
- Количество байтов на сектор
- Сектор на кластер
- Количество FAT
- Максимальное количество корневых каталогов и т.д.
Поскольку у дискеты нет логической системы разделов, то на дискете нет MBR. Первый сектор дискеты содержит DBR. Это также является основным отличием при сравнении логической структуры жесткого диска с дискетой.
Когда мы считываем информацию загрузочного сектора дискеты с помощью любой программы редактирования дисков, она отобразит информацию, подобную той, что представлена на рисунке ниже.
На следующем рисунке показаны 512 байт информации DBR дискеты объемом 1,44 МБ и размером 3½ дюйма.

Если эта информация каким-либо образом повреждена или становится нечитаемой, дискета вызывает такие сообщения об ошибках чтения. Это может быть связано с физическим или логическим повреждением первого сектора диска.
Логическое повреждение включает в себя случаи, когда информация первого сектора дискеты изменена, имеется какой-либо логически поврежденный сектор или DBR дискеты поврежден по какой-либо другой причине.
Физическое повреждение, как предполагается, происходит в случае, если на первом секторе дискеты есть физические плохие сектора (то есть сектор 1 физически поврежден). Проблема становится более серьезной, когда вы обнаруживаете, что на дискете есть более одного плохого сектора на дорожке 0.
Как восстановиться
Поскольку мы узнали обе причины повреждения, я надеюсь, теперь вы можете понять проблему. Не так уж сложно восстановить данные после логического повреждения, однако восстановление после физического повреждения требует немного больше усилий.
Метод – 1
Сохраните загрузочный образ любой новой дискеты.
If the problem is logical, now we understand that how can we recover the data. What we need to do is just to get the appropriate Boot record from another floppy of same size and capacity and to paste it to the first sector of the unreadable floppy. Though the problem was created due to the bad boot record, it should work now.
There are two steps involved in this procedure by following which we are recovering our data from an unreadable floppy:
- Making the image of DOS Boot Record of a good floppy
- Pasting the boot image to the first sector of unreadable floppy
Making the image of DOS Boot Record of a good floppy
To store the image of boot record of fresh floppy, the program must do the following three tasks:
- Read exactly first 512 bytes of the good floppy
- Check for the successful read operation (Most important)
- Store these 512 bytes to the specified filename and destination path
The sector of floppy is 512 bytes and it is necessary to copy the exact image of the sector. It is most important and necessary step in case of any type of operations applied on floppy to check whether the operation was successful or not.
There may be any initialization problem even with the good and fresh floppy disk. That is why in most of the cases when the operation is performed on floppy disks, first of all initialization of floppy disks is performed in the programming with the reset disk operation (Function 00 H of INT 13H).
If Even after initialization the recently inserted floppy disk or changed floppy disk causes any reading error you are advised to run the program again, most probably it may work this time.
The following program is to perform these specified tasks. Let us see how it proceeds:
/* Store The Boot Image to a file from a Fresh Floppy Disk */
#include <bios.h>
#include <stdio.h>
int main(void)
{
struct diskinfo_t dinfo;
union REGS regs;
int result;
int count=0, i;
char fname[80];
static char dbuf[512];
FILE *fp;
dinfo.drive = 0x00; /* drive number for A: */
dinfo.head = 0; /* disk head number */
dinfo.track = 0; /* track number */
dinfo.sector = 1; /* sector number */
dinfo.nsectors = 1; /* sector count */
dinfo.buffer = dbuf; /* data buffer */
clrscr();
gotoxy(10,3);cprintf("Enter The File Name And Path To
Store Boot Image");
gotoxy(5,5);
gets(fname);
fp=fopen(fname,"wb");
if((fp=fopen(fname,"wb"))==NULL)
{
highvideo();
gotoxy(10,10);cprintf("File Could Not Be created");
getch();
exit(0);
}
gotoxy(10,9);
cprintf("Attempting to read from Floppy disk drive :\n");
/// Initialize the Disk System \\\
for(i=0; i<3; i++)
{
regs.h.ah = 0x00; /* Reset Disk System */
regs.h.dl = 0x00; /* Floppy Disk a: */
int86(0x13, ®s, ®s);
}
result = _bios_disk(_DISK_READ, &dinfo);
if ((result & 0xff00) == 0)
{
while(count<512)
{
fprintf(fp,"%c",dbuf[count] & 0xff );
count++;
}
fclose(fp);
gotoxy(10,14);cprintf("Disk read from Floppy disk drive
: successful.\n");
}
else
{
gotoxy(10,14);
cprintf("Cannot read drive A, status = 0x%02x\n", result);
switch(result)
{
case 0x00:
cprintf("\n\n STATUS: No Error!!");
break;
case 0x01:
cprintf("\n\n STATUS: Bad command");
break;
case 0x02:
cprintf("\n\n STATUS: Address mark not found");
break;
case 0x03:
cprintf("\n\n STATUS: Attempt to write to write-protected disk");
break;
case 0x04:
cprintf("\n\n STATUS: Sector not found");
break;
case 0x06:
cprintf("\n\n STATUS: Disk changed since last operation");
break;
case 0x08:
cprintf("\n\n STATUS: Direct memory access (DMA) overrun");
break;
case 0x09:
cprintf("\n\n STATUS: Attempt to perform DMA across 64K boundary");
break;
case 0x0C:
cprintf("\n\n STATUS: Media type not found");
break;
case 0x10:
cprintf("\n\n STATUS: Bad CRC/ECC on disk read");
break;
case 0x20:
cprintf("\n\n STATUS: Controller has failed");
break;
case 0x31:
cprintf("\n\n STATUS: No media in drive (IBM/MS INT 13H extensions)");
break;
case 0x32:
cprintf("\n\n STATUS: Incorrect drive type stored in CMOS (Compaq)");
break;
case 0x40:
cprintf("\n\n STATUS: Seek operation failed");
break;
case 0x80:
cprintf("\n\n STATUS: Attachment failed to respond(Disk Timed-out)");
break;
case 0xB0:
cprintf("\n\n STATUS: Volume not locked in drive (INT 13H extensions)");
break;
case 0xB1:
cprintf("\n\n STATUS: Volume locked in drive (INT 13H extensions)");
break;
case 0xB2:
cprintf("\n\n STATUS: Volume not removable (INT 13H extensions)");
break;
case 0xB3:
cprintf("\n\n STATUS: Volume in use (INT 13H extensions)");
break;
case 0xB4:
cprintf("\n\n STATUS: Lock count exceeded (INT 13H extensions)");
break;
case 0xB5:
cprintf("\n\n STATUS: Valid eject request failed (INT 13H extensions)");
break;
default: cprintf("\n\n STATUS: UNKNOWN Status CODE For Floppy Errors");
}
}
return 0;
}
Comments on Program coding:
In the program coding given earlier, basically we are proceeding to perform the following tasks step by step:
- dinfo points to the diskinfo_t structure that contains the information of parameters required by the operation performed by the _bios_disk function.
- Since we want to read first sector of the disk therefore the location of the sector will be as follows:
Parameter |
What it means |
dinfo.drive = 0x00 |
It indicates the drive 0 that is floppy disk drive (a:) |
dinfo.head = 0 |
It points to head number 0 |
dinfo.track = 0 |
It points to track 0 |
dinfo.sector = 1 |
First sector of the floppy that is sector 1 |
dinfo.sector = 1 |
Number of sectors to consider for read operation = 1 |
dinfo.buffer = dbuf |
Data buffer for the operation |
- Open a file stream of user given file name and path to store the boot image information of exact 512 bytes. The file name and path is stored in the character array fname.
- Initialize the disk system using the interrupt 13H (function 00h) where regs.h.ah = 0x00 points to the function 00 H and regs.h.dl = 0x00 is used for a: floppy. And int86(0x13, ®s, ®s) invokes MS-DOS interrupt service INT 13 H.
- _bios_disk(_DISK_READ, &dinfo) reads the specified sector of the floppy disk.
- The status returned is stored in result that is used to display the message for successful operation or to display an error message on the screen if any error occurs.

Pasting the boot image to the first sector of unreadable floppy
For pasting the boot image from the file to the first sector of the unreadable floppy we have to perform the following three main tasks in our program:
- Read exact 512 bytes information of boot record of fresh floppy from previously saved file.
- Write this information to the first sector of the floppy which is currently unreadable.
- Check for the successful completion of write operation (Most Important).
As the sector of floppy is 512 bytes and it is necessary to paste the exact boot image to the sector. It is most important and necessary step in case of any type of operations applied on floppy to check whether the operation was successful or not.
There may be any initialization problem with the floppy disk during the operation therefore you must initialize the disk by resetting the disk system(using function 00H of INT 13H).
If Even after initialization the recently inserted floppy disk or changed floppy disk causes any reading error you are advised to run the program again, most probably it may work this time.
The following program is to perform these specified tasks. Let us see how it proceeds:
/* Load Boot Image to the unreadable Floppy */
#include <bios.h>
#include <stdio.h>
int main(void)
{
struct diskinfo_t dinfo;
union REGS regs;
int result;
int count=0, i;
char fname[80];
char dbuf[512];
FILE *fp;
clrscr();
gotoxy(5,3);cprintf("Enter The File Name And Path, In Which Boot image of Floppy Is Stored");
gotoxy(5,5);
gets(fname);
fp=fopen(fname,"rb");
if((fp=fopen(fname,"rb"))==NULL)
{
highvideo();
gotoxy(10,10);cprintf("File Could Not Be Opened");
getch();
exit(0);
}
gotoxy(10,9);
cprintf("Attempting to Recover Floppy disk drive :\n");
/// Initialize the Disk System \\\
for(i=0; i<3; i++)
{
regs.h.ah = 0x00; /* Reset Disk System */
regs.h.dl = 0x00; /* Floppy Disk a: */
int86(0x13, ®s, ®s);
}
while(count<512)
{
fscanf(fp,"%c",&dbuf[count]);
count++;
}
dinfo.drive = 0x00; /* drive number for A: */
dinfo.head = 0; /* disk head number */
dinfo.track = 0; /* track number */
dinfo.sector = 1; /* sector number */
dinfo.nsectors = 1; /* sector count */
dinfo.buffer = dbuf; /* data buffer */
result = _bios_disk(_DISK_WRITE, &dinfo);
if ((result & 0xff00) == 0)
{
fclose(fp);
gotoxy(10,14);cprintf("Successful!!! I Hope Floppy May
Work Now.\n");
}
else
{
gotoxy(10,14);
cprintf("Cannot read drive A, status = 0x%02x\n",result);
gotoxy(10,16);
switch(result)
{
case 0x00:
cprintf("\n\n STATUS: No Error!!");
break;
case 0x01:
cprintf("\n\n STATUS: Bad command");
break;
case 0x02:
cprintf("\n\n STATUS: Address mark not found");
break;
case 0x03:
cprintf("\n\n STATUS: Attempt to write to write-protected disk");
break;
case 0x04:
cprintf("\n\n STATUS: Sector not found");
break;
case 0x06:
cprintf("\n\n STATUS: Disk changed since last operation");
break;
case 0x08:
cprintf("\n\n STATUS: Direct memory access (DMA) overrun");
break;
case 0x09:
cprintf("\n\n STATUS: Attempt to perform DMA across 64K boundary");
break;
case 0x0C:
cprintf("\n\n STATUS: Media type not found");
break;
case 0x10:
cprintf("\n\n STATUS: Bad CRC/ECC on disk read");
break;
case 0x20:
cprintf("\n\n STATUS: Controller has failed");
break;
case 0x31:
cprintf("\n\n STATUS: No media in drive (IBM/MS INT 13H extensions)");
break;
case 0x32:
cprintf("\n\n STATUS: Incorrect drive type stored in CMOS (Compaq)");
break;
case 0x40:
cprintf("\n\n STATUS: Seek operation failed");
break;
case 0x80:
cprintf("\n\n STATUS: Attachment failed to respond(Disk Timed-out)");
break;
case 0xB0:
cprintf("\n\n STATUS: Volume not locked in drive (INT 13H extensions)");
break;
case 0xB1:
cprintf("\n\n STATUS: Volume locked in drive (INT 13H extensions)");
break;
case 0xB2:
cprintf("\n\n STATUS: Volume not removable (INT 13H extensions)");
break;
case 0xB3:
cprintf("\n\n STATUS: Volume in use (INT 13H extensions)");
break;
case 0xB4:
cprintf("\n\n STATUS: Lock count exceeded (INT 13H extensions)");
break;
case 0xB5:
cprintf("\n\n STATUS: Valid eject request failed (INT 13H extensions)");
break;
default: cprintf("\n\n STATUS: UNKNOWN Status CODE For Floppy Errors");
}
}
return 0;
}
Comments on Program coding:
In the program coding given earlier, basically we are proceeding to perform the following tasks step by step:
- dinfo points to the diskinfo_t structure that contains the information of parameters required by the operation performed by the _bios_disk function.
- As we are going to write the information on the first sector of the disk therefore the location of the sector will be as follows:
- Open the file in which the boot image information of 512 bytes of a fresh floppy was stored by the previous program. The file name and path is stored in the character array fname.
- Initialize the disk system using the interrupt 13H (function 00h) where regs.h.ah = 0x00 points to the function 00 H and regs.h.dl = 0x00 is used for a: floppy. And int86(0x13, ®s, ®s) invokes MS-DOS interrupt service INT 13 H.
- _bios_disk(_DISK_WRITE, &dinfo) writes the boot information from the specified file to the first (specified) sector of the floppy disk.
- The status returned is stored in result that is used to display the message for successful operation or to display an error message on the screen if any error occurs.
Parameter |
What it means |
dinfo.drive = 0x00 |
It indicates the drive 0 that is floppy disk drive (a:) |
dinfo.head = 0 |
It points to head number 0 |
dinfo.track = 0 |
It points to track 0 |
dinfo.sector = 1 |
First sector of the floppy that is sector 1 |
dinfo.sector = 1 |
Number of sectors to consider for write operation = 1 |
dinfo.buffer = dbuf |
Data buffer for the operation |
Let us do it with single program
I hope, now you have understood the concept behind such type of data recovery from the floppy disk. After this let us imagine a single program which gives the same results that we got with the help of previously discussed two programs.
We were doing the following tasks with the recently discussed programs:
- Store the Boot information from a good floppy disk to a file
- Paste this information to the first sector of the currently unreadable floppy The file which we were using to store the boot image was working as intermediate bridge to connect the operations of both the program. But if we define this boot information in our program coding itself, we need not to create a file as well as we need not to read the boot information of the floppy from the file.
In our next program we are telling our program about what it has to write in the first sector of the unreadable floppy disk and thus we are able to avoid two different programs to do the same task and we can recover our data in the same way as before from the new single program.
The program thus becomes simple with less coding and we are able to reduce the probability of occurrence of file read, write or creation errors. We are doing the following four important tasks in this program:
Don’t think the program difficult to write and understand by seeing the 512 bytes hexadecimal information of dbuf[512]. Later, We’ll discuss the easy way to write this information for your program coding.
- Define the DOS boot record information in hexadecimal system to be written in the first sector of currently unreadable floppy.
- Reset the disk system to initialize the floppy disk (INT 13H, Function 00H).
- Write the DOS Boot Record to the first sector of floppy
- Check for the successful completion of operation and error, if occurred.
Let us examine the program:
/* Single Program to load Default Boot Image To Unreadable Floppy Disk */
#include <bios.h>
#include <stdio.h>
int main(void)
{
struct diskinfo_t dinfo;
union REGS regs:
int result, i;
/* Boot Image to Be Loaded in the Floppy Disk Drive */
static char dbuf[512]=
{
0xEB,0x3E,0x90,0x2B,0x29,0x6E, 0x70,0x32,0x49,0x48,0x43,0x0,0x2 ,0x1 ,0x1 ,0x0,
0x2,0xE0,0x0,0x40,0xB,0xF0,0x9,0x0,0x12, 0x0 ,0x2 ,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x29, 0x24,0x3B,0xDB, 0x16,0x4E, 0x4F, 0x20, 0x4E,0x41,0x4D,0x45,
0x20, 0x20, 0x20,0x20,0x46,0x41, 0x54,0x31, 0x32,0x20,0x20, 0x20,0xF1,0x7D, 0xFA,
0x33, 0xC9,0x8E,0xD1, 0xBC,0xFC,0x7B, 0x16,0x7 ,0xBD,0x78,0x0 ,0xC5,0x76,0x0,
0x1E,0x56,0x16,0x55, 0xBF,0x22,0x5 ,0x89,0x7E,0x0 ,0x89,0x4E,0x2 ,0xB1,0xB,0xFC,
0xF3,0xA4,0x6 ,0x1F,0xBD,0x0,0x7C ,0xC6,0x45,0xFE,0xF,0x8B, 0x46,0x18,0x88,0x45,
0xF9,0xFB,0x38,0x66, 0x24,0x7C,0x4,0xCD,0x13, 0x72,0x3C,0x8A,
0x46,0x10,0x98,0xF7,
0x66,0x16,0x3, 0x46,0x1C,0x13,0x56, 0x1E,0x3 ,0x46,0xE,0x13,
0xD1,0x50,0x52,0x89,
0x46,0xFC,0x89, 0x56,0xFE,0xB8,0x20,0x0, 0x8B,0x76,0x11,0xF7,
0xE6,0x8B,0x5E,0xB ,
0x3 ,0xC3,0x48,0xF7,0xF3,0x1,0x46,0xFC, 0x11,0x4E,0xFE,0x5A,
0x58,0xBB,0x0 ,0x7 ,
0x8B,0xFB,0xB1,0x1, 0xE8,0x94,0x0 ,0x72,0x47,0x38,0x2D,0x74, 0x19,0xB1,0xB,0x56,
0x8B,0x76,0x3E, 0xF3,0xA6,0x5E,0x74,0x4A,0x4E, 0x74,0xB,0x3 , 0xF9,0x83, 0xC7, 0x15,
0x3B, 0xFB,0x72,0xE5,0xEB,0xD7,0x2B, 0xC9,0xB8,0xD8, 0x7D, 0x87, 0x46, 0x3E,0x3C,
0xD8,0x75,0x99, 0xBE,0x80,0x7D,0xAC, 0x98,0x3,0xF0,0xAC,0x84 ,0xC0,0x74,0x17,0x3C,
0xFF,0x74,0x9 ,0xB4,0xE ,0xBB,0x7 ,0x0,0xCD,0x10,0xEB, 0xEE,0xBE,0x83,0x7D, 0xEB,
0xE5, 0xBE, 0x81,0x7D, 0xEB,0xE0, 0x33,0xC0,0xCD,0x16,0x5E,0x1F,0x8F,0x4 ,0x8F,0x44,
0x2,0xCD, 0x19,0xBE,0x82,0x7D,0x8B,0x7D,0xF, 0x83,0xFF,0x2,0 x72,0xC8, 0x8B,0xC7,0x48,
0x48,0x8A,0x4E,0xD,0xF7,0xE1,0x3 ,0x46,0xFC, 0x13,0x56,0xFE,0xBB,0x0 ,0x7 ,0x53,0xB1,0x4 ,
0xE8,0x16,0x0, 0x5B,0x72,0xC8, 0x81,0x3F,0x4D,0x5A, 0x75,0xA7,0x81,0xBF, 0x0,0x2 ,0x42,0x4A,
0x75,0x9F,0xEA,0x0 ,0x2 ,0x70,0x0,0x50,0x52, 0x51, 0x91, 0x92, 0x33, 0xD2,0xF7,0x76,0x18,0x91,
0xF7,0x76, 0x18,0x42, 0x87, 0xCA, 0xF7, 0x76,0x1A,0x8A,0xF2,0x8A,0x56, 0x24,0x8A,0xE8,
0xD0, 0xCC,0xD0,0xCC,0xA, 0xCC,0xB8,0x1,0x2, 0xCD,0x13,0x59,0x5A, 0x58, 0x72,0x9,0x40,
0x75,0x1,0x42,0x3, 0x5E,0xB,0xE2,0xCC,0xC3,0x3 ,0x18 ,0x1 ,0x27,0xD ,0xA,0x49, 0x6E,
0x76,0x61,0x6C,0x69,0x64,0x20, 0x73, 0x79, 0x73, 0x74, 0x65,0x6D,0x20,0x64,0x69,0x73,
0x6B,0xFF,0xD ,0xA,0x44,0x69, 0x73,0x6B,0x20, 0x49,0x2F, 0x4F,0x20, 0x65,0x72, 0x72,0x6F,
0x72,0xFF,0xD ,0xA,0x52, 0x65,0x70,0x6C,0x61,0x63, 0x65,0x20,
0x74,0x68, 0x65, 0x20,
0x64, 0x69,0x73, 0x6B,0x2C,0x20,0x61, 0x6E,0x64,0x20,0x74, 0x68, 0x65, 0x6E, 0x20,0x70,
0x72,0x65, 0x73,0x73, 0x20,0x61, 0x6E,0x79,0x20,0x6B,0x65,0x79,0xD,0xA, 0x0,0x49,0x4F,
0x20,0x20,0x20,0x20, 0x20,0x20,0x53,0x59,0x53,0x4D, 0x53, 0x44, 0x4F, 0x53,0x20,0x20,
0x20,0x53, 0x59,0x53, 0x80,0x1,0x0 ,0x57,0x49, 0x4E,0x42, 0x4F,0x4F,0x54,0x20,0x53, 0x59
,0x53,0x0,0x0,0x55,0xAA};
clrscr();
dinfo.drive = 0x00; /* drive number for A: */
dinfo.head = 0; /* disk head number */
dinfo.track = 0; /* track number */
dinfo.sector = 1; /* sector number */
dinfo.nsectors = 1; /* sector count */
dinfo.buffer = dbuf; /* data buffer */
gotoxy(10,9);
cprintf("Attempting to read from Floppy disk drive :\n");
/// Initialize the Disk System \\\
for(i=0; i<3; i++)
{
regs.h.ah = 0x00; /* Reset Disk System */
regs.h.dl = 0x00; /* Floppy Disk a: */
int86(0x13, ®s, ®s);
}
result = _bios_disk(_DISK_WRITE, &dinfo);
if ((result & 0xff00) == 0)
{
gotoxy(10,14);
cprintf("Disk Write Status :successful.\n");
}
else
{
gotoxy(10,14);
cprintf("Cannot read drive A, status = 0x%02x\n",
result);
gotoxy(10,16);
switch(result)
{
case 0x00:
cprintf("\n\n STATUS: No Error!!");
break;
case 0x01:
cprintf("\n\n STATUS: Bad command");
break;
case 0x02:
cprintf("\n\n STATUS: Address mark not found");
break;
case 0x03:
cprintf("\n\n STATUS: Attempt to write to write-
protected disk");
break;
case 0x04:
cprintf("\n\n STATUS: Sector not found");
break;
case 0x06:
cprintf("\n\n STATUS: Disk changed since last operation");
break;
case 0x08:
cprintf("\n\n STATUS: Direct memory access (DMA) overrun");
break;
case 0x09:
cprintf("\n\n STATUS: Attempt to perform DMA across 64K boundary");
break;
case 0x0C:
cprintf("\n\n STATUS: Media type not found");
break;
case 0x10:
cprintf("\n\n STATUS: Bad CRC/ECC on disk read");
break;
case 0x20:
cprintf("\n\n STATUS: Controller has failed");
break;
case 0x31:
cprintf("\n\n STATUS: No media in drive (IBM/MS INT 13H extensions)");
break;
case 0x32:
cprintf("\n\n STATUS: Incorrect drive type stored in CMOS (Compaq)");
break;
case 0x40:
cprintf("\n\n STATUS: Seek operation failed");
break;
case 0x80:
cprintf("\n\n STATUS: Attachment failed to respond(Disk Timed-out)");
break;
case 0xB0:
cprintf("\n\n STATUS: Volume not locked in drive (INT 13H extensions)");
break;
case 0xB1:
cprintf("\n\n STATUS: Volume locked in drive (INT 13H extensions)");
break;
case 0xB2:
cprintf("\n\n STATUS: Volume not removable (INT 13H extensions)");
break;
case 0xB3:
cprintf("\n\n STATUS: Volume in use (INT 13 extensions)");
break;
case 0xB4:
cprintf("\n\n STATUS: Lock count exceeded (INT 13H extensions)");
break;
case 0xB5:
cprintf("\n\n STATUS: Valid eject request failed (INT 13H extensions)");
break;
default: cprintf("\n\n STATUS: UNKNOWN Status CODE For Floppy Errors");
}
}
return 0;
}
In this program coding, basically we are proceeding to perform the following these tasks step by step:
- Static character data buffer dbuf[512] is provided the information of 512 bytes in hexadecimal system, which is to be written in the first sector of unreadable floppy. dbuf[512] tells the computer during the operation that what information is to be written in the first sector of floppy. (See the Next Program)
- dinfo points to the diskinfo_t structure that contains the information of parameters required by the operation performed by the _bios_disk function.
- As we are going to write the information on the first sector of the disk therefore the location of the sector will be as follows:
Parameter |
What it means |
dinfo.drive = 0x00 |
It indicates the drive 0 that is floppy disk drive (a:) |
dinfo.head = 0 |
It points to head number 0 |
dinfo.track = 0 |
It points to track 0 |
dinfo.sector = 1 |
First sector of the floppy that is sector 1 |
dinfo.sector = 1 |
Number of sectors to consider for write operation = 1 |
dinfo.buffer = dbuf |
Data buffer for the operation |
- Initialize the disk system using the interrupt 13H (function 00h) where regs.h.ah = 0x00 points to the function 00 H and regs.h.dl = 0x00 is used for a: floppy. And int86(0x13, ®s, ®s) invokes MS-DOS interrupt service INT 13 H.
- _bios_disk(_DISK_WRITE, &dinfo) writes the boot information from the specified file to the first (specified) sector of the floppy disk.
The status returned is stored in result that is used to display the message for successful operation or to display an error message on the screen if any error occurs.
Storing the boot Image in HEXADECIMAL Characters to use in our previous Program
It will be a very difficult job to write all 512 the characters of floppy’s DOS Boot Record manually in hexadecimal system without any error in the program we recently discussed. If we can write it accurately even than it will be a difficult and time taking task to do this. Let us use some tricky mind to store the data for data buffer dbuf[512] in a file.
We know that in C programming the hexadecimal characters are represented with 0x such that if hexadecimal character is A9 H, we shall write this in our C program as 0xA9. Our next program is doing the same. It will store the data that we need to write in our previous program, as the data of data buffer dbuf[512].
What you have to do is just to take a fresh and new floppy to make the image of its DBR and copy the output of this program from the destination file specified and paste this data in your program. Do some formatting if required. Let us see how it works:
/* Program to make the boot Image of the Floppy Disk In HEX Character */
#include <bios.h>
#include <stdio.h>
int main(void)
{
struct diskinfo_t dinfo;
union REGS regs;
int result,i;
int count=0;
char fname[80];
static char dbuf[512];
FILE *fp;
dinfo.drive = 0x00; /* drive number for A: */
dinfo.head = 0; /* disk head number */
dinfo.track = 0; /* track number */
dinfo.sector = 1; /* sector number */
dinfo.nsectors = 1; /* sector count */
dinfo.buffer = dbuf; /* data buffer */
clrscr();
gotoxy(10,3);cprintf("Enter The File Name And Path To
Store The Boot Image in HEX System");
gotoxy(5,5);
gets(fname);
fp=fopen(fname,"wb");
if((fp=fopen(fname,"wb"))==NULL)
{
highvideo();
gotoxy(10,10);cprintf("File Could Not Be created");
getch();
exit(0);
}
/// Initialize the Disk System \\\
for(i=0; i<3; i++)
{
regs.h.ah = 0x00; /* Reset Disk System */
regs.h.dl = 0x00; /* Floppy Disk a: */
int86(0x13, ®s, ®s);
}
gotoxy(10,9); cprintf("Attempting to read from Floppy
disk drive :\n");
result = _bios_disk(_DISK_READ, &dinfo);
if ((result & 0xff00) == 0)
{
gotoxy(10,14);
cprintf("Disk read from Floppy disk drive :
successful.\n");
while(count<512)
{
fprintf(fp,"0x%X, ",dbuf[count] & 0xff );
count++;
}
fclose(fp);
}
else
{
gotoxy(10,14);
cprintf("Cannot read drive A, status = 0x%02x\n",
result);
}
return 0;
}
Comments on coding of the program:
Thus the data is stored in the specified file. Just copy the data to your program and do some required formatting. You should never forget the following tips through out the procedure:
- Make it sure that the operation of the program was successful and the data which has been stored in the destination file is the appropriate.
- You should check the operation through out for occurrence of expected errors.
- You must initialize the Floppy disk in, with the program before reading its boot sector. You may use function 00H of INT 13H for this purpose.
Method – 2
What to do if Method – 1 doesn’t work?
If the Method – 1 does not work and the unreadable disk is not allowing the program to re-write the boot information on its first sector you should try this second method. The reason behind the failure of First Method may be the physical corruption of first sector of the floppy disk.
In this second method we are going to copy all the data of the surface of the unreadable Floppy to a single file temporarily and then we shall paste this image directly on the surface of the another good disk.
The procedure involves the following two important steps:
- Sector-by-Sector Copy all the data of the surface of floppy’s media to a single file temporarily.
- Paste the data previously stored in file, to a new fresh floppy as it is, on the same sectors.
Copy all the data of media surface to a single file
To store all the data of the surface of media of floppy, the program must do the following three tasks:
- Initialize the disk properly with the help of function 00H of INT 13H.
- Read the Sector-by-Sector information of the surface and store to a single file.
- Check for the successful read operation (Most important)
It is very common to have any initialization problem with a floppy disk which leads many unsuccessful read messages. That is why the disk must be initialized before the read write operation with the help of programming.
It is most important and necessary step in case of any type of operations applied on floppy to check whether the operation was successful or not.
If Even after initialization the recently inserted floppy disk or changed floppy disk causes any reading error you are advised to run the program again, most probably it may work this time.
The following program is to perform these specified tasks. Let us see how it proceeds:
/* Program to store the data of physical surface of the floppy disk to a file */
#include <bios.h>
#include <stdio.h>
void main(void)
{
int head,track;
union REGS regs;
int result,i,sector;
char filename[80];
struct diskinfo_t dinfo;
static char dbuf[512];
FILE *tt;
clrscr();
printf("\n Enter The Name of file with Path to store The
Data Temporarily\n");
gets(filename);
if((tt=fopen(filename,"wb"))==NULL)
{
printf("Could Not Create The File,
Press any Key To EXIT");
getch();
exit(0);
}
printf("\n Initializing Floppy Disk System...\n");
/// Initialize the Disk System \\\
for(i=0; i<3; i++)
{
regs.h.ah = 0x00; /* Reset Disk System */
regs.h.dl = 0x00; /* Floppy Disk a: */
int86(0x13, ®s, ®s);
}
for(track=0;track<=79;track++)
{
for(head=0;head<=1;head++)
{
for(sector=1;sector<=18;sector++)
{
dinfo.drive = 0; /* drive number for A: */
dinfo.head = head; /* disk head number */
dinfo.track = track; /* track number */
dinfo.sector = sector; /* sector number */
dinfo.nsectors = 1; /* sector count */
dinfo.buffer = dbuf; /* data buffer */
result = _bios_disk(_DISK_READ, &dinfo);
if ((result & 0xff00) == 0)
{
for(i=0;i<512;i++)
fprintf(tt,"%c",dbuf[i] & 0xff);
}
else
{
printf("Cannot read drive A, status =
0x%02x\t%d\t%d\t%d\n", result,head,track,sector);
}
printf("Reading Track= %d Head= %d Sector= %d\n",
track,head,sector);
}
}
}
}
Comments on Program coding:
In the program coding given earlier, basically we are proceeding to perform the following tasks step by step:
- Character array filename[80] stores the user defined path and file name of the file in which we are going to store the data temporarily.
- dinfo points to the diskinfo_t structure that contains the information of parameters required by the operation performed by the _bios_disk function.
- Initialize the disk system using the interrupt 13H (function 00h) where regs.h.ah = 0x00 points to the function 00 H and regs.h.dl = 0x00 is used for a: floppy. And int86(0x13, ®s, ®s) invokes MS-DOS interrupt service INT 13 H.
- As we are going to read all the information of the surface of disk, The parameters of _bios_disk will be as follows:
Parameter |
What it means |
dinfo.drive = 0x00 |
It indicates the drive 0 that is floppy disk drive (a:) |
dinfo.head = head |
It points to head number 0 and 1 as floppy has two sides(two heads) |
dinfo.track = track |
It points to track 0 to 79 as there are 80 tracks on each side of floppy. |
dinfo.sector = sector |
It points to sector 1 to 18 as there are 18 sectors in each track. |
dinfo.sector = 1 |
Number of sectors to consider for read operation = 1 |
dinfo.buffer = dbuf |
Data buffer for the operation |
- _bios_disk(_DISK_READ, &dinfo) reads the data from the physical surface of floppy disk from the sector specified by dinfo.
- The status returned is stored in result that is used to display the message for successful operation or to display an error message on the screen if any error occurs.
Always remember that the size of the file that holds the image of the floppy disk’s data must be exact 1,474,560 bytes because the floppy has 80 tracks (0 to 79), 2 sides or heads (head 0 and head 1), each track has 18 sectors on it and each sector holds the 512 bytes of data, thus
Total bytes = (Number of tracks) * (Number of Heads) *
(Number of Sectors per Track) * 512
= 80*2*18*512
= 1,474,560 Bytes
Thus, if there is any error in reading at any sector of the floppy disk, it will change the size of the file from 1,474,560 Bytes, which will make the entire information completely or partially of no use for the destination disk on which we are going to write the disk image sector by sector from this file.
This is so because the Computer reads the information of any file on the surface of the media of the floppy disk within the sector range as it has been allocated in its allocation unit. Now if the sectors of the data of the files are changed, the complete file information is changed.
Thinking for the solution of sector(s) reading error
It is possible with the bad or unreadable floppy that it may have such bad area on its surface that we may not be able to read the information from the surface of the disk.
In this condition the information of this sector(s) will we skipped and the image of the floppy will be distorted even for the other sectors as the size of the image file in this case differs from 1,474,560 Bytes.
To maintain the size of the image file and to paste the rest of the information on the exact sector locations on the destination disk, we write some other information on behalf of the original data of 512 bytes and in this way, we’ll be capable to save the rest of the information however the recovery in such case may be the partial recovery.
If your system also fails to read the first sector of the source floppy, after pasting the image to the destination floppy you should run the program described before, to rewrite the DOS Boot Record of the floppy.
Let us see how we can do it by programming:
#include <bios.h>
#include <stdio.h>
void main(void)
{
int head,track;
union REGS regs;
int result,i,sector;
char filename[80];
struct diskinfo_t dinfo;
static char dbuf[512];
/*Information of 512 Bytes to fill space of Bad Sector */
/// I used 512 zeros to fill the space of 512 bytes \\\
static char dbuf2[512] =
"00000000000000000000000000000000" "00000000000000000000000000000000" "00000000000000000000000000000000" "00000000000000000000000000000000" "00000000000000000000000000000000" "00000000000000000000000000000000" "00000000000000000000000000000000" "00000000000000000000000000000000" "00000000000000000000000000000000" "00000000000000000000000000000000" "00000000000000000000000000000000" "00000000000000000000000000000000" "00000000000000000000000000000000" "00000000000000000000000000000000" "00000000000000000000000000000000" "00000000000000000000000000000000";
FILE *tt;
clrscr();
printf("\n Enter The Name of file with Path to store The
Data Temporarily\n");
gets(filename);
if((tt=fopen(filename,"wb"))==NULL)
{
printf("Could Not Create The File, Press any Key To
EXIT");
getch();
exit(0);
}
printf("\n Initializing Floppy Disk System...\n");
/// Initialize the Disk System \\\
for(i=0; i<3; i++)
{
regs.h.ah = 0x00; /* Reset Disk System */
regs.h.dl = 0x00; /* Floppy Disk a: */
int86(0x13, ®s, ®s);
}
for(track=0;track<=79;track++)
{
for(head=0;head<=1;head++)
{
for(sector=1;sector<=18;sector++)
{
dinfo.drive = 0; /* drive number for A: */
dinfo.head = head; /* disk head number */
dinfo.track = track; /* track number */
dinfo.sector = sector; /* sector number */
dinfo.nsectors = 1; /* sector count */
dinfo.buffer = dbuf; /* data buffer */
result = _bios_disk(_DISK_READ, &dinfo);
if ((result & 0xff00) == 0)
{
for(i=0;i<512;i++)
fprintf(tt,"%c",dbuf[i] & 0xff);
}
else
{
printf("Cannot read drive A, status =
0x%02x\t%d\t%d\t%d\n", result, head, track, sector);
/* If Sector is not Readable, occupy 512 bytes by dbuf2 */
fwrite(dbuf2,512,1,tt);
}
printf("Reading Track= %d Head= %d Sector= %d\n",
track, head, sector);
}
}
}
}
Comments on Program coding:
In the coding of the program, every step is same as in previous program except the data buffer dbuf2[512], which we are using to handle the error generated by bad sector during the Disk reading operation and to maintain the size of the image file.
By doing this, we are filling the space of the information, which we failed to read from the bad sector and now we are writing the pseudo information of 512 bytes so that we may maintain the accuracy of disk image.
Paste the Data from the file to the physical surface of fresh floppy:
In this step, we paste the data stored in the file by the previous program, to the physical surface of the fresh floppy, sector by sector in the same way by which we copied it to the file.
The program proceeds with the following main steps:
- Open the file in which we stored the surface data of the unreadable floppy temporarily.
- Initialize the disk system properly by the resetting function 00H of INT 13H.
- Write the information on the sectors of the fresh floppy from the file.
- Display the write status simultaneously to find or avoid the occurrence of errors.
The program source code has been given below. Let us examine how it works:
/* Program to write the data on the sectors of the surface of fresh floppy from the file, created by the previous program */
#include <bios.h>
#include <stdio.h>
void main(void)
{
int head,track;
union REGS regs;
int result,i,sector;
int count =0;
char filename[80];
struct diskinfo_t dinfo;
static char dbuf[512];
FILE *fp;
clrscr();
printf("\n Enter The Name of file with Path to store The
Data Temporarily\n");
gets(filename);
if((fp=fopen(filename,"rb"))==NULL)
{
printf("Could Not Create The File, Press any Key To
EXIT");
getch();
exit(1);
}
/// Initialize the Disk System \\\
for(i=0; i<3; i++)
{
regs.h.ah = 0x00; /* Reset Disk System */
regs.h.dl = 0x00; /* Floppy Disk a: */
int86(0x13, ®s, ®s);
}
for(track=0;track<=79;track++)
{
for(head=0;head<=1;head++)
{
for(sector=1;sector<=18;sector++)
{
count =0;
while(count<512 )
{
fscanf(fp,"%c",&dbuf[count]);
count++;
}
dinfo.drive = 0x00; /* drive number for A: */
dinfo.head = head; /* disk head number */
dinfo.track = track; /* track number */
dinfo.sector = sector;/* sector number */
dinfo.nsectors = 1; /* sector count */
dinfo.buffer = dbuf; /* data buffer */
result= _bios_disk(_DISK_WRITE, &dinfo);
if ((result & 0xff00) == 0)
printf("Successful write on Track = %d, Head = %d,
Sector = %d.\n", track, head, sector);
else
printf("Cannot read drive A, status = 0x%02x\n",
result);
}
}
}
}
Comments on Program coding:
In the program coding given earlier, basically we are proceeding to perform the following tasks step by step:
- Character array filename[80] holds the path and file name of the file in which we stored the data of the surface of unreadable floppy temporarily.
- dinfo points to the diskinfo_t structure that contains the information of parameters required by the operation performed by the _bios_disk function.
- Initialize the disk system using the interrupt 13H (function 00h) where regs.h.ah = 0x00 points to the function 00 H and regs.h.dl = 0x00 is used for a: floppy. And int86(0x13, ®s, ®s) invokes MS-DOS interrupt service INT 13 H.
- As we are going to write the information directly to sectors of the surface of disk, The parameters of _bios_disk will be as follows:
Parameter |
What it means |
dinfo.drive = 0x00 |
It indicates the drive 0 that is floppy disk drive (a:) |
dinfo.head = head |
It points to head number 0 and 1 as floppy has two sides(two heads) |
dinfo.track = track |
It points to track 0 to 79 as there are 80 tracks on each side of floppy. |
dinfo.sector = sector |
It points to sector 1 to 18 as there are 18 sectors in each track. |
dinfo.sector = 1 |
Number of sectors to consider for write operation = 1 |
dinfo.buffer = dbuf |
Data buffer for the operation |
- _bios_disk(_DISK_WRITE, &dinfo) writes the data on the sectors of the physical surface of floppy disk, specified by dinfo.
- The status returned is stored in result that is used to display the message for successful operation or to display an error message on the screen if any error occurs.
If after the Method – 2 your new floppy does not work, you may further apply Method – 1 on your new floppy, which you used as destination disk during the Method – 2.
Not only this but also the number of hits and trials may vary depending upon the corruption of the disk. But you need not to worry if even after you are not getting the satisfactory results.
You can try file by file recovery or can try many more tips which you will learn in the next. Here we shall implement the idea of collecting the file information from Root Directories, in our programming to recover the data.
Thinking for Logical Recovery for Deleted or lost Data:
All the previous cases we discussed in this chapter for recovery, were to recover the data in such cases where we were expecting that only the DBR is corrupted and the sectors in track 0, having FAT1, FAT2 and Root directories are readable.
But if the problem is due to the corruption of FAT or the data has been deleted from the disk or you want to recover the data directly by reading its information from the Root directory, we need to read the information such as, Filename, starting cluster, size of the file, Attribute etc. from its Root directory entry.
As we have already discussed about Root Directory in earlier chapters that there is the information of 32 Bytes for each file or directory. These 32 Bytes are divided as follows:
Number of Bytes |
Information Description |
8 Bytes |
Filename |
3 Bytes |
Extension |
1 Byte |
Attribute |
10 Bytes |
Reserved |
2 Bytes |
Time, Created or Last Updated |
2 Bytes |
Date, Created or Last Updated |
2 Bytes |
Starting Cluster |
4 Bytes |
File Size |
We recover the data by reading the information of the file(s) from the Root Directory and then integrate the file to the destination path and recover the file. Our next program performs the following steps to recover the data:
- Read the Root Directory entries and Display them on the screen with all information such as File/Directory name, Extension of the File, Starting cluster size of the files in Bytes.
- Read the Files and Directories information in the Subdirectories and display them if required.
- Confirm the File name to be recovered and continue recovery.
- Calculate the CHS (Cylinder, Head, and Sector) info for the Specified file to be recovered.
- Integrate the data of the file from the data area of the disk and save the recovered file to the specified destination file name in specified path.
This Program does not care if the boot information of the floppy is readable or not. Therefore you can recover even deleted data from the corrupted floppy disk too. Let us see the coding of the program:
/* Program to recover the data from the Floppy disk by Reading file information from the Root Directory */
#include<stdio.h>
#include<bios.h>
#include<dos.h>
void main()
{
void Display_Information(unsigned int,unsigned int,
unsigned int);
unsigned int track=0,head=1,sector=2;
Display_Information(track,head,sector);
} /*End of main */
void Display_Information(unsigned int track,
unsigned int head,
unsigned int sector)
{
void recover(unsigned int *,unsigned int);
char buf[512]; // Buffer of 512 Bytes
char ch;
struct diskinfo_t finfo; //Structure, Used by _bios_disk
unsigned int result,i,j, count=0; /* Unsigned Integers
Defined */
unsigned int file_no; /* Unsigned Integer
for File Number */
struct
{
unsigned int name[8],ext[3]; /* File Name for DOS in 8.3
(Eight Dot Three) Format */
unsigned int attribute; // File/Directory Attribute
unsigned int start; // Starting Cluster of the File
long unsigned int size; // Size of the File in Bytes
}root[32]; /* 32 Bytes Information of
File/Directory in Root
Directory */
clrscr();
do
{
file_no=0;
finfo.drive = 0x00; /* drive number for A: */
finfo.head = head; /* disk head number */
finfo.track = track; /* track number */
finfo.sector= sector; /* sector number */
finfo.nsectors=1; /* sector count */
finfo.buffer = buf; /* data buffer */
result = _bios_disk(_DISK_READ, &finfo); /* Read the
Sector */
if( (result & 0xff00) != 0) /* If Read Error, Display
Error Message and Exit*/
{
printf("Read error");
getch();
exit(0); // Go Back to DOS
}
/// Information Display Screen Format \\\
clrscr();
gotoxy(9,1);
cprintf("DISPLAY CYLN: %u, HEAD: %u, SECTOR: %u",
track, head, sector);
gotoxy(9,2);
cprintf("FNO NAME EXT ATTRIBUTE START SIZE");
gotoxy(7,3);
cprintf("--------------------------------------------");
/* One Sector At a time. Every File/DIR entry Takes 32 Byte */
for(i=0;i<512;i+=32)
{
for(j=0;j<8;j++)
{
/// Find The File/Dir Name \\\
root[file_no].name[j]=buf[j+i];
}
for(j=8;j<11;j++)
{
/// Find the Extension \\\
root[file_no].ext[j-8]=buf[i+j];
}
j=11;
root[file_no].attribute=buf[i+j]; /// Attribute
/// Starting Cluster \\\
root[file_no].start=(0xff & buf[27+i])*16*16 + (0xff & buf[26+i]);
/// Calculate the Size \\\
root[file_no].size =(long unsigned int)(0xff &
buf[31+i])*16*16*16*16*16*16*16*16;
root[file_no].size+=(long unsigned int)(0xff &
buf[30+i])*16*16*16*16;
root[file_no].size+=(long unsigned int)(0xff &
buf[29+i])*16*16;
root[file_no].size+=(long unsigned int)(0xff &
buf[28+i]);
if((root[file_no].start == 0) ||
(root[file_no].attribute == 15))
continue;
else
{
gotoxy(8,i/32+4);
cprintf("%2u",file_no); /* Display File
Number */
for(j=0;j<8;j++)
{
gotoxy(14+j,i/32+4);
cprintf("%c",root[file_no].name[j]); /* Display File
Name */
}
for(j=0;j<3;j++)
{
gotoxy(26+j,i/32+4);
cprintf("%c",root[file_no].ext[j]); /* Display
Extension */
}
gotoxy(30,i/32+4);
cprintf("%u",root[file_no].attribute); /* Display
Attribute */
if(root[file_no].attribute==16)
{
gotoxy(33,i/32+4);
cprintf("<DIR>"); /* Display if Directory Attribute */
}
else
{
gotoxy(33,i/32+4);
cprintf("<FILE>"); /* The Entry is of a file */
}
gotoxy(44,i/32+4);
cprintf("%-5u", root[file_no].start); /* Display
Starting Cluster */
gotoxy(58,i/32+4);
cprintf("%-10lu", root[file_no].size); /* size of the
File */
}
file_no++;
}
gotoxy(10,
cprintf("Press 'M' : To see list of more files &quo
gotoxy(10,
cprintf("Press 'R' :To recover a file from the above
list&quo
ch=getc
Remember that the file name starting with s (E5H) represents that the file has been deleted and therefore the first character of the filename has been replaced with s (See the root directory description in the earlier chapters ).
And the output of the program is displayed like this:
DISPLAY CYLN: 0, HEAD: 1, SECTOR: 2
FNO NAME EXT ATTRIBUTE START SIZE
--------------------------------------------------------------------------
0 WE 32 <FILE> 15 1800
1 s2_INFO C 32 <FILE> 5 4700
2 THELP CFG 32 <FILE> 2 22
3 THELP COM 32 <FILE> 3 11072
4 TIMEIT CPP 32 <FILE> 39 1186
5 TOUCH COM 32 <FILE> 42 5124
6 TRY1 CPP 32 <FILE> 53 1581
7 TURBOC CFG 32 <FILE> 57 30
8 AA CPP 32 <FILE> 58 260
9 ABC CPP 32 <FILE> 59 1036
10 ASSIGN1 CPP 32 <FILE> 62 4257
11 CH24_2 CPP 32 <FILE> 71 834
12 sBSDISK1 C 32 <FILE> 73 911
13 sH24_25 C 32 <FILE> 75 594
14 sBSDISK C 32 <FILE> 77 840
Press 'M' : To see list of more files
Press 'R' :To recover a file from the above list R
|
DISPLAY CYLN: 0, HEAD: 1, SECTOR: 2
FNO NAME EXT ATTRIBUTE START SIZE
----------------------------------------------------------------------------
0 WE 32 <FILE> 15 1800
1 s2_INFO C 32 <FILE> 5 4700
2 THELP CFG 32 <FILE> 2 22
3 THELP COM 32 <FILE> 3 11072
4 TIMEIT CPP 32 <FILE> 39 1186
5 TOUCH COM 32 <FILE> 42 5124
6 TRY1 CPP 32 <FILE> 53 1581
7 TURBOC CFG 32 <FILE> 57 30
8 AA CPP 32 <FILE> 58 260
9 ABC CPP 32 <FILE> 59 1036
10 ASSIGN1 CPP 32 <FILE> 62 4257
11 CH24_2 CPP 32 <FILE> 71 834
12 sBSDISK1 C 32 <FILE> 73 911
13 sH24_25 C 32 <FILE> 75 594
14 sBSDISK C 32 <FILE> 77 840
Enter FNO. of the file you want to recover 1
You want to recover _2_INFO .C
Cylinder = 1, Head = 0, Sector = 1 Integrating........
Enter Path and Filename to recover the file: c:\windows\desktop\H2_INFO.C
Recovery Done !!!
|
Comments on coding:
The function Display_Information is to read the file and directory information and from the root directory. In the Structure we are reading the 32 bytes information for every file or directory with root[32].
The unsigned integer arrays name[8] and ext[3] are for File or Directory name for DOS in 8.3 (Eight Dot Three) Format. Similarly one byte is for attribute and two bytes for starting cluster. long unsigned int size; is to store the size of the file of four bytes.
The _bios_disk function reads the sector, specified by the structure finfo and the status of the operation is stored in result.
From the every information of 512 bytes read by the _bios_disk function, till the root directory area ends, we collect the information of the files and directories stored in the disk and display them on the screen.
The integer file_no is stores the number of the file or directory in the list, starting from 0. Generally the size of root directory is of 14 sectors and root directory generally starts from Cylinder =0, Head = 0 and Sector =2 in case of 1.44MB and 3½ floppy disk.
If user gives the character ‘M’ or ‘m’ as input, the information of next sector is displayed if the choice by user is ‘R’ or ‘r’ the recovery functions are called. The coding of the function recover() has been given below:
/* Function To Start Recovery for The Specified File */
void recover(unsigned int *root,unsigned int len)
{
void clear_the_line(unsigned int r); /* Function to Clear a Row on the Screen */
/* Function to Integrate The Specified File */
void integrate(long unsigned int,unsigned int,
unsigned int,unsigned int);
unsigned int file_no,i;
char ch;
unsigned int *loc;
unsigned int cylinder,head,sector;
unsigned int start;
long unsigned int size;
clear_the_line(21); /* Clear The Row Number 21 */
clear_the_line(22); /* Clear The Row Number 22 */
clear_the_line(23); /* Clear The Row Number 23 */
clear_the_line(24); /* Clear The Row Number 24 */
gotoxy(10,21);
cprintf("Enter FNO. of the file you want to recover");
scanf("%u",&file_no); /* Get the File No. to be
Recovered */
loc=(root+(len*file_no/2));
/* Confirm the file Name to be recovered */
gotoxy(10,22);
cprintf("You want to recover");
for(i=0;i<8;i++)
{
gotoxy(30+i,22);
cprintf("%c",*(loc+i)); /* File name */
}
gotoxy(38,22);
cprintf(".");
for(i=0;i<3;i++)
{
gotoxy(39+i,22);
cprintf("%c",*(loc+8+i)); /* File Extension */
}
start=*(loc+12);
/// Sorry, You Selected a Directory \\\
if(*(loc+11)==16)
{
gotoxy(5,23);
cprintf("Is A directory. Do you want to see the
contents of this directory Y/N");
ch=getch();
if(ch==27)
main();
if(ch=='y' || ch=='Y')
{
/* Calculate Geomatry */
calculate(start,&cylinder,&head,§or);
/* Display Directory Contents */
Display_Information (cylinder,head,sector);
}
else
/* Ask for A file again and Continue Recovery */
recover(root,len);
}
else
{
size=*(loc+13);
/* Calculate for CHS info */
calculate(start,&cylinder,&head,§or);
/* Integrate The File */
integrate(size,cylinder,head,sector);
}
}
Comments on coding:
The function recover() is to get the user input to start the recovery. The file number given as input by the user to recover the file, is stored in file_no.
If the entered number is for the Directory entry, Display_Information() shows the contents of that directory, else The file name and extension of file number file_no is displayed on the screen to confirm the file to be recovered.
To recover the specified file, the functions calculate() and integrate() are called within the function. The coding of the function calculate() has been given below:
/* Function To calculate the CHS Geomatry For The Recovery */
void calculate(unsigned int start,unsigned int *cylinder,
unsigned int *head,unsigned int *sector)
{
unsigned int temp;
*cylinder=0;
*head=1;
*sector=14;
if(start<5)
*sector=14+start;
else
{
temp= (start-4)/18;
if(temp>0)
{
if(temp%2==0)
*head=0;
else
*head=1;
*cylinder+=1+temp/2;
}
else
{
*head=0;
*cylinder=1;
}
*sector=(start-4)%18;
}
/// Display The CHS of The File to Be Recovered \\\
gotoxy(10,23);
cprintf("Cylinder = %u, Head = %u, Sector = %u",
*cylinder,*head,*sector);
}
Comments on coding:
The function calculate() is to calculate the Cylinder, Head and Sector information for the file to be recovered. After calculation the Cylinder, Head and Sector numbers are displayed on the screen.
The coding for the function integrate() has been given below:
/* Integrate File and Save the Recovered File To the Specified Path and File name */
void integrate(long unsigned int size,
unsigned int cylinder,
unsigned int head,
unsigned int sector)
{
void clear_the_line(unsigned int);
/* Function to Verify The Sector for Errors */
int verify_the_sector(unsigned int, unsigned int,
unsigned int);
int status;
char buf[512],*Filename_with_path;
struct diskinfo_t dinfo;
unsigned int result;
FILE *fp;
unsigned int left,i;
unsigned int sec;
/* Enter The Destination Path and File Name to Save the Recovered file */
gotoxy(2,24);
cprintf("Enter Path and Filename to recover the file: ");
fflush(stdin);
gets(Filename_with_path);
fp=fopen(Filename_with_path,"wb");
/* If Error Occured Display Error Message and get input Path and File Name Again */
if(fp==NULL)
{
gotoxy(5,25);
cprintf("Error in opening the file");
getch();
clear_the_line(24);
gotoxy(0,25);
cprintf(" ");
integrate(size,cylinder,head,sector); /* Enter the
Destination Again */
}
/* If Everything is all right, Integrate and write */
gotoxy(50,23);
cprintf("Integrating........");
left= size%512;
sec = size/512;
sec++;
while(sec>0)
{
dinfo.drive = 0x00; /* drive number for A: */
dinfo.head = head; /* disk head number */
dinfo.track = cylinder; /* track number */
dinfo.sector= sector; /* sector number */
dinfo.nsectors=1; /* sector count */
dinfo.buffer = buf; /* data buffer */
result = _bios_disk(_DISK_READ, &dinfo);
/* If there is Error While Reading any Sector */
if( (result & 0xff00) != 0)
{
gotoxy(5,25);
cprintf("read error Cylinder %u, Head %u, Sector %u",
cylinder, head, sector);
}
else
{
if(sec==1)
{
for(i=0;i<left;i++)
fputc(buf[i],fp); /* Write The Integrated
Information to the File */
}
else
{
fwrite(buf,512,1,fp);
}
Comments on coding:
The function integrate() is the actual module of performing the recovery of the user specified file, in this recovery program.
The file name with the destination path to store the recovered file is stored in the character pointer *Filename_with_path. If there is any error in opening the destination file, error message is displayed and user is prompt again to enter the destination.
The function _bios_disk(_DISK_READ, &dinfo); reads the data of the file from the data area of the disk sector by sector, specified by the structure dinfo and stored in the data buffer buf. This data of 512 bytes is written to the destination file. This is repeated until the complete file is integrated.
The function status=verify_the_sector (cylinder,head,sector); verifies the sector to be read. If the status = 10, it represents a bad (0xA) sector. The coding of the function has been given below:
/// Verify the Sector. (No Data is Transferred here) \\\
int verify_the_sector(unsigned int c,unsigned int h,unsigned int s)
{
int status;
char *buf;
union REGS in, out;
struct SREGS sg;
in.h.ah = 0x04; /* Function Number */
in.h.al = 1; /* Number of Sectors to Verify*/
in.h.dl = 0x00; /* Номер диска для A: */
in.h.ch = c; /* Номер цилиндра */
in.h.dh = h; /* Номер головы */
in.h.cl = s; /* Номер сектора */
in.x.bx = FP_OFF(buf);/* Смещение */
sg.es = FP_SEG(buf); /* Сегмент */
int86x(0x13,&in,&out,&sg); /* Вызов функции 4H
из INT 13H */
если(out.x.cflag)
{
статус=out.h.ah;
}
возврат(статус);
}
Комментарии по кодированию:
Функция verify_the_sector() проверяет сектор, который будет прочитан функцией _bios_disk(), и возвращает статус операции. Функция использует INT 13H и функцию 4H для проверки сектора.
*buf — буфер данных, 0x04 — номер функции, указанный in.h.ah = 0x04; а in.h.al = 1; указывает на необходимость проверки одного сектора за раз. in.h.dl = 0x00; используется для номера дисковода для гибких дисков A:, c,h и s — номера цилиндра, головки и сектора .
Функция int86x() используется для вызова INT 13H (функция 4H) со значениями сегментного регистра . Статус операции возвращается целочисленным статусом.
Функция clear_the_line() очищает указанную строку на экране. Кодировка функции следующая:
/* Функция очистки строки на экране для указанного номера строки */
void clear_the_line(строка беззнакового целого числа)
{
столбец беззнакового целого числа;
/* В строке 80 столбцов */
для(столбец=1;столбец<=80;столбец++)
{
gotoxy(столбец,строка);
cprintf(" "); /* Очистить с помощью " " */
}
}
Комментарии по кодированию:
Функция используется для очистки указанной строки на экране . Функция вызывается с номером строки, которую необходимо очистить с экрана.