Hoofdstuk – 10
Gegevensherstel van beschadigde diskette
Gegevensherstel van beschadigde diskette
De floppy is een van de meest onbetrouwbare bronnen voor gegevensopslag. Als u naar een organisatie gaat die computersystemen gebruikt en aan haar werknemers vraagt naar de problemen die worden veroorzaakt door diskettes, zult u heel vaak het probleem horen dat de werknemer van de organisatie belangrijke gegevens op zijn diskette had staan en dat de diskette nu niet leesbaar door de computer en een bericht wordt weergegeven als,
“Kan de schijf niet lezen”
“Track 0 Slecht”
“Ongeldige schijf of capaciteit”
“De schijf is niet geformatteerd. Wil je het nu formatteren?”
Dit is het dagelijkse probleem voor de organisaties die computersystemen en diskettes gebruiken. Het probleem wordt kritiek wanneer u erachter komt dat er geen back-up is gemaakt of dat er geen back-up beschikbaar is voor de gegevens die verloren lijken te zijn gegaan op de beschadigde diskette.
Het grootste probleem wordt verondersteld te ontstaan wanneer u een back-up maakt op de diskette voor uw kritieke informatie, reddingsschijven van het antivirusprogramma om de virusaanval te overwinnen of opstartrecords of andere back-ups (er kunnen een aantal mogelijkheden zijn) in een diskette en wanneer u de back-up opnieuw wilt gebruiken van de diskette, geeft dit een leesfout.
In een dergelijke toestand staat u op het punt uw belangrijke informatie en gegevens te verliezen of zelfs in sommige gevallen wanneer u het gevoel heeft dat er geen back-ups en een herstelprogramma voor uw computeropstartinformatie en Virusaanvalredding beschikbaar zijn programma's enz., kunt u een groot gegevensverlies lijden in de vorm van een OS-crash als gevolg van het gebrek aan informatie, opgeslagen op de diskette die nu niet door de computer kan worden gelezen.
In dergelijke gevallen wordt het de belangrijkste vereiste om de gegevens te herstellen van de diskette die door uw computersysteem als slecht is verklaard.
Waarom de diskette niet leesbaar is
Het meest voorkomende probleem dat ervoor zorgt dat een diskette dergelijke foutmeldingen vertoont, is de corruptie van zijn DOS-opstartrecord (DBR) van diskette, waardoor de computer de logische identificatie van de diskette weet.
De DBR is een klein programma dat is opgeslagen in track 0, head 0 en sector 1 en dat belangrijke informatie over de diskette bevat, zoals:
- Aantal bytes per sector
- Sector per cluster
- Aantal FAT's
- Maximum aantal hoofdmappen enz.
Aangezien Floppy geen logisch partitiesysteem heeft, is er dus geen MBR beschikbaar op diskette. De eerste sector van Floppy bevat de DBR. Dit is ook een belangrijk verschil om de logische structuur van een harde schijf te vergelijken met een diskette.
Als we de bootsectorinformatie van een diskette lezen met behulp van een schijfbewerkingsprogramma, zal het informatie weergeven zoals in de volgende afbeelding.
De volgende afbeelding toont de 512 Bytes informatie van de DBR van een 1,44 MB, 3½ Inch floppy.
Als deze informatie op een of andere manier beschadigd is of onleesbaar wordt, veroorzaakt de diskette dergelijke leesfoutmeldingen. Het kan te wijten zijn aan fysieke of logische beschadiging van de eerste sector van de schijf.
De Logische corruptie omvat de gevallen waarin de informatie van de eerste sector van de diskette is gewijzigd, er een logische slechte sector of de DBR optreedt van de diskette is om een andere reden beschadigd.
De Fysieke corruptie wordt verondersteld plaats te vinden in het geval van, als er fysieke slechte sectoren zijn (betekent dat sector 1 fysiek beschadigd is) op de eerste sector van de diskette. Het probleem wordt ernstiger als je ontdekt dat de diskette meer dan één slechte sector in track 0 heeft.
Hoe te herstellen
Omdat we beide oorzaken van corruptie hebben geleerd, hoop ik dat je nu in staat bent het probleem te begrijpen. Het is niet erg moeilijk om de gegevens te herstellen van logische beschadiging, maar het herstel van de fysieke beschadiging vereist iets meer inspanning.
Methode – 1
Bewaar de opstartkopie van een nieuwe diskette
Als het probleem logisch is, begrijpen we nu hoe we de gegevens kunnen herstellen. Wat we moeten doen is gewoon het juiste opstartrecord van een andere diskette van dezelfde grootte en capaciteit halen en deze in de eerste sector van de onleesbare diskette plakken. Hoewel het probleem is ontstaan vanwege het slechte opstartrecord, zou het nu moeten werken.
Er zijn twee stappen betrokken bij deze procedure, waarbij we onze gegevens herstellen van een onleesbare diskette:
- Het beeld van DOS Boot Record maken van een goede diskette
- De opstartafbeelding plakken in de eerste sector van de onleesbare diskette
Het beeld van DOS Boot Record maken van een goede diskette
Om de afbeelding van de opstartrecord van een verse diskette op te slaan, moet het programma de volgende drie taken uitvoeren:
- Lees exact de eerste 512 bytes van de goede diskette
- Controleer of de leesbewerking is geslaagd (belangrijkste)
- Sla deze 512 bytes op in de opgegeven bestandsnaam en het bestemmingspad
De sector van de diskette is 512 bytes en het is noodzakelijk om de exacte afbeelding van de sector te kopiëren. Het is de meest belangrijke en noodzakelijke stap in het geval van elk type operatie dat op diskette wordt toegepast om te controleren of de operatie succesvol was of niet.
Er kan een initialisatieprobleem zijn, zelfs met de goede en nieuwe floppydisk. Dat is de reden waarom in de meeste gevallen, wanneer de bewerking op floppydisks wordt uitgevoerd, allereerst de initialisatie van floppydisks wordt uitgevoerd in de programmering met de reset diskbewerking (functie 00 H van INT 13H).
Als zelfs na initialisatie de recent geplaatste floppydisk of gewijzigde floppydisk een leesfout veroorzaakt, wordt u aangeraden het programma opnieuw uit te voeren, hoogstwaarschijnlijk zal het deze keer wel werken.
Het volgende programma is om deze gespecificeerde taken uit te voeren. Laten we eens kijken hoe het verder gaat:
/* Sla de opstartkopie op in een bestand vanaf een nieuwe diskette */
#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");
/// Initialiseer het schijfsysteem \\\
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;
}
Opmerkingen over programmacodering:
In de eerder gegeven programmacodering gaan we in principe stap voor stap verder met het uitvoeren van de volgende taken:
- dinfo verwijst naar de diskinfo_t-structuur die de informatie bevat van parameters die nodig zijn voor de bewerking die wordt uitgevoerd door de functie _bios_disk.
- Aangezien we de eerste sector van de schijf willen lezen, zal de locatie van de sector als volgt zijn:
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 een bestandsstroom met de door de gebruiker opgegeven bestandsnaam en pad om de opstartimage-informatie van exact 512 bytes op te slaan. De bestandsnaam en het pad worden opgeslagen in de tekenreeks fname.
- Initialiseer het schijfsysteem met de interrupt 13H (functie 00h) waarbij regs.h.ah = 0x00 verwijst naar de functie 00 H en regs.h.dl = 0x00 wordt gebruikt voor een: floppy. En int86(0x13, ®s, ®s) roept de MS-DOS-onderbrekingsservice INT 13 H op.
- _bios_disk(_DISK_READ, &dinfo) leest de gespecificeerde sector van de diskette.
- De geretourneerde status wordt opgeslagen in het resultaat dat wordt gebruikt om het bericht voor een succesvolle bewerking weer te geven of om een foutmelding op het scherm weer te geven als er een fout optreedt.
De opstartafbeelding plakken in de eerste sector van de onleesbare diskette
Voor het plakken van de opstart-image van het bestand naar de eerste sector van de onleesbare diskette moeten we de volgende drie hoofdtaken in ons programma uitvoeren:
- Lees exacte 512 bytes informatie van het opstartrecord van een nieuwe diskette van een eerder opgeslagen bestand.
- Schrijf deze informatie naar de eerste sector van de diskette die momenteel onleesbaar is.
- Controleer of de schrijfbewerking met succes is voltooid (belangrijkste).
Omdat de sector van de diskette 512 bytes is en het nodig is om de exacte opstartimage in de sector te plakken. Het is de meest belangrijke en noodzakelijke stap in het geval van elk type operatie dat op diskette wordt toegepast om te controleren of de operatie succesvol was of niet.
Er kan een initialisatieprobleem zijn met de diskette tijdens de operatie, daarom moet u de disk initialiseren door het disksysteem te resetten(met functie 00H van INT 13H).
Als zelfs na initialisatie de recent geplaatste floppydisk of gewijzigde floppydisk een leesfout veroorzaakt, wordt u aangeraden het programma opnieuw uit te voeren, hoogstwaarschijnlijk zal het deze keer wel werken.
Het volgende programma is om deze gespecificeerde taken uit te voeren. Laten we eens kijken hoe het verder gaat:
/* Laad opstartimage naar de onleesbare diskette */
#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");
/// Initialiseer het schijfsysteem \\\
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;
}
Opmerkingen over programmacodering:
In de eerder gegeven programmacodering voeren we in principe de volgende taken stap voor stap uit:
- dinfo verwijst naar de diskinfo_t-structuur die de informatie bevat van parameters die nodig zijn voor de bewerking die wordt uitgevoerd door de functie _bios_disk.
- Omdat we de informatie op de eerste sector van de schijf gaan schrijven, zal de locatie van de sector als volgt zijn:
- Open het bestand waarin de opstartimage-informatie van 512 bytes van een nieuwe diskette is opgeslagen door het vorige programma. De bestandsnaam en het pad worden opgeslagen in de tekenreeks fname.
- Initialiseer het schijfsysteem met de interrupt 13H (functie 00h) waarbij regs.h.ah = 0x00 verwijst naar de functie 00 H en regs.h.dl = 0x00 wordt gebruikt voor een: floppy. En int86(0x13, ®s, ®s) roept de MS-DOS-onderbrekingsservice INT 13 H op.
- _bios_disk(_DISK_WRITE, &dinfo) schrijft de opstartinformatie van het opgegeven bestand naar de eerste (gespecificeerde) sector van de diskette.
- De geretourneerde status wordt opgeslagen in het resultaat dat wordt gebruikt om het bericht voor een succesvolle bewerking weer te geven of om een foutmelding op het scherm weer te geven als er een fout optreedt.
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 |
Laten we het doen met een enkel programma
Ik hoop dat je nu het concept achter een dergelijk type gegevensherstel van de diskette hebt begrepen. Laten we ons hierna een enkel programma voorstellen dat dezelfde resultaten geeft als met behulp van eerder besproken twee programma's.
We deden de volgende taken met de onlangs besproken programma's:
- Bewaar de opstartinformatie van een goede diskette in een bestand
- Plak deze informatie in de eerste sector van de momenteel onleesbare diskette. Het bestand dat we gebruikten om de opstartkopie op te slaan, werkte als tussenbrug om de bewerkingen van beide programma's te verbinden. Maar als we deze opstartinformatie definiëren in onze programmacodering zelf, hoeven we geen bestand aan te maken en hoeven we ook niet de opstartinformatie van de diskette uit het bestand te lezen.
In ons volgende programma vertellen we ons programma wat het moet schrijven in de eerste sector van de onleesbare diskette en zo kunnen we voorkomen dat twee verschillende programma's dezelfde taak uitvoeren en kunnen we onze gegevens op dezelfde manier als voorheen van het nieuwe enkele programma.
Het programma wordt dus eenvoudig met minder codering en we zijn in staat om de kans op het optreden van lees-, schrijf- of aanmaakfouten van bestanden te verkleinen. We doen de volgende vier belangrijke taken in dit programma:
Denk niet dat het programma moeilijk te schrijven en te begrijpen is door de 512 bytes hexadecimale informatie van dbuf[512].Later bespreken we de gemakkelijke manier om deze informatie voor uw programmacodering te schrijven.
- Definieer de DOS-opstartrecord-informatie in het hexadecimale systeem die moet worden geschreven in de eerste sector van de momenteel onleesbare diskette.
- Reset het disksysteem om de diskette te initialiseren (INT 13H, Functie 00H).
- Schrijf het DOS-opstartrecord naar de eerste sector van de diskette
- Controleer of de bewerking met succes is voltooid en eventuele fout is opgetreden.
Laten we het programma eens bekijken:
/* Enkel programma om standaard opstartimage naar onleesbare diskette te laden */
#include <bios.h>
#include <stdio.h>
int main(void)
{
struct diskinfo_t dinfo;
union REGS regs:
int result, i;
/* Boot-image die in de diskettedrive moet worden geladen */
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");
/// Initialiseer het schijfsysteem \\\
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 deze programmacodering gaan we in principe door met het stap voor stap uitvoeren van de volgende taken:
- Statische karakter data buffer dbuf[512] wordt geleverd met de informatie van 512 bytes in een hexadecimaal systeem, dat geschreven moet worden in de eerste sector van onleesbare diskette. dbuf[512] vertelt de computer tijdens de operatie welke informatie in de eerste sector van de diskette moet worden geschreven. (Zie het volgende programma)
- dinfo verwijst naar de diskinfo_t-structuur die de informatie bevat van parameters die nodig zijn voor de bewerking die wordt uitgevoerd door de functie _bios_disk.
- Omdat we de informatie op de eerste sector van de schijf gaan schrijven, zal de locatie van de sector als volgt zijn:
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 |
- Initialiseer het schijfsysteem met de interrupt 13H (functie 00h) waarbij regs.h.ah = 0x00 verwijst naar de functie 00 H en regs.h.dl = 0x00 wordt gebruikt voor een: floppy. En int86(0x13, ®s, ®s) roept de MS-DOS-onderbrekingsservice INT 13 H op.
- _bios_disk(_DISK_WRITE, &dinfo) schrijft de opstartinformatie van het opgegeven bestand naar de eerste (gespecificeerde) sector van de diskette.
De geretourneerde status wordt opgeslagen in het resultaat dat wordt gebruikt om het bericht voor een succesvolle bewerking weer te geven of om een foutmelding op het scherm weer te geven als er een fout optreedt.
De opstartafbeelding opslaan in HEXADECIMALE tekens om te gebruiken in ons vorige programma
Het zal een zeer moeilijke taak zijn om alle 512 karakters van het DOS Boot Record op diskette handmatig in een hexadecimaal systeem te schrijven zonder enige fout in het programma dat we onlangs hebben besproken. Als we het zelfs nauwkeurig kunnen schrijven, zal het een moeilijke en tijdrovende taak zijn om dit te doen. Laten we een lastige geest gebruiken om de gegevens voor gegevensbuffer dbuf[512] in een bestand op te slaan.
We weten dat in C-programmering de hexadecimale tekens worden weergegeven met 0x, zodat als het hexadecimale teken A9 H is, we dit in ons C-programma zullen schrijven als 0xA9. Ons volgende programma doet hetzelfde. Het slaat de gegevens op die we in ons vorige programma moeten schrijven, als de gegevens van gegevensbuffer dbuf[512].
Wat u hoeft te doen is gewoon een verse en nieuwe diskette te nemen om de afbeelding van zijn DBR te maken en de uitvoer van dit programma uit het opgegeven doelbestand te kopiëren en deze gegevens in uw programma te plakken. Voer indien nodig enige opmaak uit. Laten we eens kijken hoe het werkt:
/* Programma om de opstartkopie van de diskette in HEX-teken te maken */
#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);
}
/// Initialiseer het schijfsysteem \\\
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;
}
Opmerkingen over de codering van het programma:
De gegevens worden dus opgeslagen in het opgegeven bestand. Kopieer de gegevens naar uw programma en voer de vereiste opmaak uit. U mag tijdens de procedure de volgende tips nooit vergeten:
- Zorg ervoor dat de werking van het programma succesvol was en dat de gegevens die zijn opgeslagen in het doelbestand de juiste zijn.
- U moet de bewerking controleren op het optreden van verwachte fouten.
- U moet de diskette initialiseren met het programma voordat u de opstartsector leest. U kunt hiervoor functie 00H of INT 13H gebruiken.
Methode – 2
Wat te doen als Methode – 1 werkt niet?
Als de methode – 1 niet werkt en de onleesbare schijf staat het programma niet toe om de opstartinformatie in de eerste sector te herschrijven. Probeer deze tweede methode. De reden achter het mislukken van First Method kan de fysieke beschadiging van de eerste sector van de diskette zijn.
Bij deze tweede methode gaan we alle gegevens van het oppervlak van de onleesbare diskette tijdelijk naar een enkel bestand kopiëren en dan plakken we deze afbeelding direct op het oppervlak van de andere goede schijf.
De procedure omvat de volgende twee belangrijke stappen:
- Sector-voor-Sector Kopieer alle gegevens van het oppervlak van diskettemedia tijdelijk naar een enkel bestand.
- Plak de gegevens die eerder in het bestand waren opgeslagen op een nieuwe, nieuwe diskette zoals deze is, in dezelfde sectoren.
Kopieer alle gegevens van het media-oppervlak naar een enkel bestand
Om alle gegevens van het oppervlak van de diskette op te slaan, moet het programma de volgende drie taken uitvoeren:
- Initialiseer de schijf correct met behulp van functie 00H van INT 13H.
- Lees de sector-voor-sector informatie van het oppervlak en sla op in een enkel bestand.
- Controleer of de leesbewerking is geslaagd (belangrijkste)
Het is heel gewoon dat er een initialisatieprobleem is met een diskette, wat leidt tot veel mislukte leesberichten. Daarom moet de schijf worden geïnitialiseerd vóór de lees-schrijfbewerking met behulp van programmeren.
Het is de belangrijkste en meest noodzakelijke stap in het geval van elk type operatie dat op diskette wordt toegepast om te controleren of de operatie succesvol was of niet.
Als zelfs na initialisatie de recent geplaatste floppydisk of gewijzigde floppydisk een leesfout veroorzaakt, wordt u aangeraden het programma opnieuw uit te voeren, hoogstwaarschijnlijk werkt het deze keer.
Het volgende programma is om deze gespecificeerde taken uit te voeren. Laten we eens kijken hoe het verder gaat:
/* Programma om de gegevens van het fysieke oppervlak van de diskette op te slaan in een bestand */
#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");
/// Initialiseer het schijfsysteem \\\
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);
}
}
}
}
Opmerkingen over programmacodering:
In de eerder gegeven programmacodering voeren we in principe de volgende taken stap voor stap uit:
- Character array filename [80] slaat het door de gebruiker gedefinieerde pad en de bestandsnaam op van het bestand waarin we de gegevens tijdelijk gaan opslaan.
- dinfo verwijst naar de diskinfo_t-structuur die de informatie bevat van parameters die nodig zijn voor de bewerking die wordt uitgevoerd door de functie _bios_disk.
- Initialiseer het schijfsysteem met de interrupt 13H (functie 00h) waarbij regs.h.ah = 0x00 verwijst naar de functie 00 H en regs.h.dl = 0x00 wordt gebruikt voor een: floppy. En int86(0x13, ®s, ®s) roept de MS-DOS-onderbrekingsservice INT 13 H op.
- Terwijl we alle informatie van het oppervlak van de schijf gaan lezen, zullen de parameters van _bios_disk als volgt zijn:
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) lees de gegevens van het fysieke oppervlak van de diskette uit de sector gespecificeerd door dinfo.
- De geretourneerde status wordt opgeslagen in het resultaat dat wordt gebruikt om het bericht voor een succesvolle bewerking weer te geven of om een foutmelding op het scherm weer te geven als er een fout optreedt.
Onthoud altijd dat de grootte van het bestand dat de afbeelding van de diskettegegevens bevat exact 1.474.560 bytes moet zijn, omdat de diskette 80 sporen (0 tot 79), 2 zijden of koppen (kop 0 en kop 1) heeft, elk spoor heeft 18 sectoren en elke sector bevat de 512 bytes aan gegevens, dus
Totaal aantal bytes = (Aantal tracks) * (Aantal Heads) *
(Aantal sectoren per spoor) * 512
= 80*2*18*512
= 1.474.560 Bytes
Dus als er een fout is bij het lezen in een sector van de diskette, zal het de grootte van het bestand veranderen van 1.474.560 Bytes, waardoor de volledige informatie geheel of gedeeltelijk onbruikbaar wordt voor de doeldisk waar we naartoe gaan om de schijfkopie sector voor sector uit dit bestand te schrijven.
Dit is zo omdat de computer de informatie leest van elk bestand op het oppervlak van de media van de diskette binnen het sectorbereik zoals het is toegewezen in zijn toewijzingseenheid. Als nu de sectoren van de gegevens van de bestanden worden gewijzigd, wordt de volledige bestandsinformatie gewijzigd.
Nadenken voor de oplossing van sector(en) leesfout
Het is mogelijk dat de slechte of onleesbare diskette zo'n slecht gebied op het oppervlak heeft dat we de informatie niet van het oppervlak van de schijf kunnen lezen.
In deze toestand zullen we de informatie van deze sector(en) overslaan en het beeld van de diskette zal zelfs voor de andere sectoren vervormd worden, aangezien de grootte van het afbeeldingsbestand in dit geval verschilt van 1.474.560 Bytes.
Om de grootte van het afbeeldingsbestand te behouden en om de rest van de informatie op de exacte sectorlocaties op de doelschijf te plakken, schrijven we wat andere informatie namens de originele gegevens van 512 bytes en op deze manier kunnen we’ zal in staat zijn om de rest van de informatie op te slaan, maar het herstel kan in dat geval het gedeeltelijke herstel zijn.
Als uw systeem er ook niet in slaagt de eerste sector van de brondiskette te lezen, moet u na het plakken van de afbeelding op de doeldiskette het eerder beschreven programma uitvoeren om de DOS Boot Record van de diskette te herschrijven .
Laten we eens kijken hoe we dit kunnen doen door te programmeren:
#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];
/*Informatie van 512 bytes om de ruimte van de slechte sector te vullen */
/// 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");
/// Initialiseer het schijfsysteem \\\
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);
/* Als Sector niet leesbaar is, neem dan 512 bytes in beslag door dbuf2 */
fwrite(dbuf2,512,1,tt);
}
printf("Reading Track= %d Head= %d Sector= %d\n",
track, head, sector);
}
}
}
}
Opmerkingen over programmacodering:
In de codering van het programma is elke stap hetzelfde als in het vorige programma, behalve de gegevensbuffer dbuf2[512], die we gebruiken om de fout af te handelen die wordt gegenereerd door een slechte sector tijdens de Schijfleesbewerking en om de grootte van het afbeeldingsbestand te behouden.
Door dit te doen, vullen we de ruimte van de informatie die we niet konden lezen uit de slechte sector en nu zijn we de pseudo-informatie aan het schrijven van 512 bytes zodat we de nauwkeurigheid van de schijfkopie kunnen behouden.
Plak de gegevens uit het bestand op het fysieke oppervlak van een nieuwe diskette:
In deze stap plakken we de gegevens die door het vorige programma in het bestand zijn opgeslagen, sector voor sector op het fysieke oppervlak van de nieuwe diskette, op dezelfde manier waarop we ze naar het bestand hebben gekopieerd.
Het programma gaat verder met de volgende hoofdstappen:
- Open het bestand waarin we de oppervlaktegegevens van de onleesbare diskette tijdelijk hebben opgeslagen.
- Initialiseer het schijfsysteem correct door de resetfunctie 00H van INT 13H.
- Schrijf de informatie over de sectoren van de nieuwe diskette uit het bestand.
- Geef tegelijkertijd de schrijfstatus weer om fouten te vinden of te voorkomen.
De broncode van het programma is hieronder weergegeven. Laten we eens kijken hoe het werkt:
/* Programma om de gegevens op de sectoren van het oppervlak van een verse diskette uit het bestand te schrijven, gemaakt door het vorige programma */
#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);
}
/// Initialiseer het schijfsysteem \\\
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);
}
}
}
}
Opmerkingen over programmacodering:
In de eerder gegeven programmacodering gaan we in principe stap voor stap verder met het uitvoeren van de volgende taken:
- Character array bestandsnaam [80] bevat het pad en de bestandsnaam van het bestand waarin we de gegevens van het oppervlak van een onleesbare floppy tijdelijk hebben opgeslagen.
- dinfo verwijst naar de diskinfo_t-structuur die de informatie bevat van parameters die nodig zijn voor de bewerking die wordt uitgevoerd door de functie _bios_disk.
- Initialiseer het schijfsysteem met de interrupt 13H (functie 00h) waarbij regs.h.ah = 0x00 verwijst naar de functie 00 H en regs.h.dl = 0x00 wordt gebruikt voor een: floppy. En int86(0x13, ®s, ®s) roept de MS-DOS-onderbrekingsservice INT 13 H op.
- Omdat we de informatie rechtstreeks naar sectoren van het schijfoppervlak gaan schrijven, zullen de parameters van _bios_disk als volgt zijn:
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) schrijft de gegevens op de sectoren van het fysieke oppervlak van de diskette, gespecificeerd door dinfo.
- De geretourneerde status wordt opgeslagen in het resultaat dat wordt gebruikt om het bericht voor een succesvolle bewerking weer te geven of om een foutmelding op het scherm weer te geven als er een fout optreedt.
Als na de methode – 2 uw nieuwe diskette niet werkt, kunt u Methode – 1 op uw nieuwe diskette, die u tijdens de Methode als bestemmingsdiskette gebruikte – 2.
Niet alleen dit, maar ook het aantal hits en pogingen kan variëren, afhankelijk van de beschadiging van de schijf. Maar u hoeft zich geen zorgen te maken als u niet de bevredigende resultaten krijgt.
Je kunt bestand voor bestand herstellen of nog veel meer tips uitproberen die je in de volgende zult leren. Hier zullen we het idee van het verzamelen van de bestandsinformatie uit hoofddirectories implementeren in onze programmering om de gegevens te herstellen.
Denken aan logisch herstel voor verwijderde of verloren gegevens:
Alle eerdere gevallen die we in dit hoofdstuk voor herstel hebben besproken, waren om de gegevens te herstellen in gevallen waarin we verwachtten dat alleen de DBR beschadigd is en de sectoren in track 0, met FAT1, FAT2 en De hoofddirectory's zijn leesbaar.
Maar als het probleem te wijten is aan de corruptie van FAT of als de gegevens zijn verwijderd van de schijf of als u de gegevens rechtstreeks wilt herstellen door de informatie te lezen
uit de hoofdmap moeten we de informatie lezen, zoals Bestandsnaam, startcluster, grootte van het bestand , Attribuut enz. van het Invoer in de hoofdmap.
Zoals we al hebben besproken over Root Directory in eerdere hoofdstukken, is er de informatie van 32 Bytes voor elk bestand of elke directory. Deze 32 bytes zijn als volgt verdeeld:
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 herstel de gegevens door de informatie van de bestanden uit de Root Directory te lezen en vervolgens het bestand te integreren in het doelpad en het bestand te herstellen. Ons volgende programma voert de volgende stappen uit om de gegevens te herstellen:
- Lees de Root Directory-vermeldingen en geef ze op het scherm weer met alle informatie zoals de naam van het bestand/de map, de extensie van het bestand, de beginclustergrootte van de bestanden in bytes.
- Lees de informatie over bestanden en mappen in de submappen en geef ze indien nodig weer.
- Bevestig de bestandsnaam die moet worden hersteld en ga door met herstellen.
- Bereken de CHS-info (cilinder, kop en sector) voor het gespecificeerde bestand dat moet worden hersteld.
- Integreer de gegevens van het bestand uit het gegevensgebied van de schijf en sla het herstelde bestand op in de opgegeven naam van het doelbestand in het opgegeven pad.
Dit Programma maakt het niet uit of de opstartinformatie van de diskette leesbaar is of niet. Daarom kunt u zelfs verwijderde gegevens ook van de beschadigde diskette herstellen. Laten we de codering van het programma eens bekijken:
/* Programma om de gegevens van de diskette te herstellen door bestandsinformatie uit de hoofdmap te lezen */
#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
}
/// Schermindeling informatieweergave \\\
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("--------------------------------------------");
/* Eén sector tegelijk. Elk bestand/DIR-item duurt 32 bytes */
for(i=0;i<512;i+=32)
{
for(j=0;j<8;j++)
{
/// Zoek de bestands-/mapnaam \\\
root[file_no].name[j]=buf[j+i];
}
for(j=8;j<11;j++)
{
/// Zoek de extensie \\\
root[file_no].ext[j-8]=buf[i+j];
}
j=11;
root[file_no].attribute=buf[i+j]; /// Attribute
/// Startcluster \\\
root[file_no].start=(0xff & buf[27+i])*16*16 + (0xff & buf[26+i]);
/// Bereken de grootte \\\
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
Onthoud dat de bestandsnaam die begint met een s (E5H) aangeeft dat het bestand is verwijderd en dat daarom het eerste teken van de bestandsnaam is vervangen door een s (zie de beschrijving van de hoofdmap in de eerdere hoofdstukken).
En de uitvoer van het programma wordt als volgt weergegeven:
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 !!!
|
Opmerkingen over codering:
De functie Display_Information is om de bestands- en directory-informatie te lezen en vanuit de rootdirectory. In de Structuur lezen we de 32 bytes informatie voor elk bestand of elke map met root[32].
De unsigned integer arrays name[8] en ext[3] zijn voor bestands- of directorynaam voor DOS in 8.3 (Eight Dot Three) Format. Evenzo is één byte voor attribuut en twee bytes voor het starten van cluster. lange niet-ondertekende int-maat; is om de grootte van het bestand van vier bytes op te slaan.
De functie _bios_disk leest de sector, gespecificeerd door de structuur finfo en de status van de bewerking wordt opgeslagen in resultaat.
Van alle informatie van 512 bytes die is gelezen door de _bios_disk functie, totdat het hoofdmapgebied eindigt, verzamelen we de informatie van de bestanden en mappen die op de schijf zijn opgeslagen en toon ze op het scherm.
Het gehele getal file_no slaat het nummer van het bestand of de map in de lijst op, beginnend bij 0. Over het algemeen is de grootte van de hoofdmap 14 sectoren en begint de hoofdmap over het algemeen vanaf Cilinder =0, Head = 0 en Sector =2 in het geval van 1.44MB en 3½ diskette.
Als de gebruiker het teken ‘M’ of ‘m’ als invoer wordt de informatie van de volgende sector weergegeven als de keuze door de gebruiker ‘R’ of ‘r’ de herstelfuncties worden aangeroepen. De codering van de functie recover() is hieronder weergegeven:
/* Functie om herstel te starten voor het opgegeven bestand */
void recover(unsigned int *root,unsigned int len)
{
void clear_the_line(unsigned int r); /* Function to Clear a Row on the Screen */
/* Functie om het opgegeven bestand te integreren */
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));
/* Bevestig de bestandsnaam die moet worden hersteld */
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, u heeft een map geselecteerd \\\
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')
{
/* Bereken geometrie */
calculate(start,&cylinder,&head,§or);
/* Directory-inhoud weergeven */
Display_Information (cylinder,head,sector);
}
else
/* Ask for A file again and Continue Recovery */
recover(root,len);
}
else
{
size=*(loc+13);
/* Bereken voor CHS-info */
calculate(start,&cylinder,&head,§or);
/* Integrate The File */
integrate(size,cylinder,head,sector);
}
}
Opmerkingen over codering:
De functie recover() is om de gebruikersinvoer te krijgen om het herstel te starten. Het bestandsnummer dat door de gebruiker is ingevoerd om het bestand te herstellen, wordt opgeslagen in file_no.
Als het ingevoerde nummer voor het Directory-item is, toont Display_Information() de inhoud van die directory, anders wordt de bestandsnaam en extensie van het bestandsnummer file_no op het scherm weergegeven om het te herstellen bestand te bevestigen.
Om het opgegeven bestand te herstellen, worden de functies calculate() en integrate() aangeroepen binnen de functie. De codering van de functie bereken() is hieronder weergegeven:
/* Functie om de CHS-geomatrie voor het herstel te berekenen: */
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;
}
/// Toon de CHS van het te herstellen bestand \\\
gotoxy(10,23);
cprintf("Cylinder = %u, Head = %u, Sector = %u",
*cylinder,*head,*sector);
}
Opmerkingen over codering:
De functie calculate() is om de Cilinder-, Head- en Sector-informatie te berekenen voor het te herstellen bestand. Na berekening worden de cilinder-, kop- en sectornummers op het scherm weergegeven.
De codering voor de functie integratie() is hieronder gegeven:
/* Bestand integreren en het herstelde bestand opslaan naar het opgegeven pad en de bestandsnaam */
void integrate(long unsigned int size,
unsigned int cylinder,
unsigned int head,
unsigned int sector)
{
void clear_the_line(unsigned int);
/* Functie om de sector te controleren op fouten */
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;
/* Voer het bestemmingspad en de bestandsnaam in om het herstelde bestand op te slaan */
gotoxy(2,24);
cprintf("Enter Path and Filename to recover the file: ");
fflush(stdin);
gets(Filename_with_path);
fp=fopen(Filename_with_path,"wb");
/* Als er een fout is opgetreden Geef het foutbericht weer en voer het pad en de bestandsnaam opnieuw in */
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 */
}
/* Als alles in orde is, integreren en schrijven */
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);
}
Opmerkingen over codering:
De functie integrate() is de eigenlijke module voor het uitvoeren van het herstel van het door de gebruiker gespecificeerde bestand, in dit herstelprogramma.
De bestandsnaam met het bestemmingspad om het herstelde bestand op te slaan, wordt opgeslagen in de tekenaanwijzer *Bestandsnaam_met_pad. Als er een fout is opgetreden bij het openen van het doelbestand, wordt een foutmelding weergegeven en wordt de gebruiker opnieuw gevraagd om de bestemming in te voeren.
De functie _bios_disk(_DISK_READ, &dinfo); leest de gegevens van het bestand uit het gegevensgebied van de schijfsector per sector, gespecificeerd door de structuur dinfo en opgeslagen in de gegevensbufferbuf . Deze gegevens van 512 bytes worden naar het doelbestand geschreven. Dit wordt herhaald totdat het volledige bestand is geïntegreerd.
De functie status=verify_the_sector (cilinder,kop,sector); verifieert de sector die moet worden gelezen. Als de status = 10, vertegenwoordigt dit een slechte (0xA) sector. De codering van de functie is hieronder weergegeven:
/// Controleer de sector. (Hier worden geen gegevens overgedragen) \\\
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; /* Drive Number for A: */
in.h.ch = c; /* Cylinder Number */
in.h.dh = h; /* Head Number */
in.h.cl = s; /* Sector Number */
in.x.bx = FP_OFF(buf);/* Offset */
sg.es = FP_SEG(buf); /* Segment */
int86x(0x13,&in,&out,&sg); /* Call the Function 4H
of INT 13H */
if(out.x.cflag)
{
status=out.h.ah;
}
return(status);
}
Opmerkingen over codering:
De functie confirm_the_sector(), verifieert de sector die moet worden gelezen door de functie _bios_disk() en geeft de status van de bewerking terug. De functie gebruikt INT 13H en functie 4H om de sector te verifiëren.
*buf is de gegevensbuffer, 0x04 is het functienummer gespecificeerd door in.h.ah = 0x04; en in.h.al = 1; instrueert om de ene sector tegelijk te verifiëren. in.h.dl = 0x00; wordt gebruikt voor het drivenummer voor diskettestation A:, c,h en s zijn Cilinder-, Head- en Sectornummers.
De functie int86x() wordt gebruikt om INT 13H (functie 4H) aan te roepen met segmentregisterwaarden. De status van de bewerking wordt geretourneerd door de integer-status.
De functie clear_the_line() wist de opgegeven rij op het scherm. De codering van de functie is als volgt:
/* Functie om de lijn op het scherm te wissen, voor opgegeven rijnummer */
void clear_the_line(unsigned int row)
{
unsigned int column;
/* There are 80 Columns in a Row (Line) */
for(column=1;column<=80;column++)
{
gotoxy(column,row);
cprintf(" "); /* Clear With " " */
}
}
Opmerkingen over codering:
De functie wordt gebruikt om de opgegeven rij op het scherm te wissen. De functie wordt aangeroepen met het nummer van de rij, die van het scherm moet worden gewist.
Pagina aangepast op: 14/01/2022