Capitolo – 10
Recupero dati da floppy danneggiato
Recupero dati da floppy danneggiato
Il Floppy è una delle fonti più inaffidabili per l'archiviazione dei dati. Se vai da qualsiasi organizzazione che utilizza sistemi informatici e chiedi ai suoi dipendenti i problemi generati dai floppy disk, molto comunemente sentirai il problema che il dipendente dell'organizzazione aveva alcuni dati importanti nel suo floppy e ora il floppy non lo è leggibile dal computer e viene visualizzato un messaggio simile a,
“Impossibile leggere il disco”
“Traccia 0 non valida”
“Unità o capacità non valide”
“Il disco non è formattato. Vuoi formattarlo ora?”
Questo è il problema quotidiano per le organizzazioni che utilizzano sistemi informatici e floppy. Il problema diventa critico quando vieni a sapere che non è stato eseguito alcun backup o backup disponibile per i dati che sembrano essere persi nel floppy disk danneggiato.
Il problema più grande dovrebbe verificarsi quando si esegue il backup nel floppy delle informazioni critiche, i dischi di ripristino del programma antivirus per superare l'attacco del virus o i record di avvio o altri backup (potrebbero esserci diverse possibilità) in un floppy e quando vuoi riutilizzare il backup dal floppy viene visualizzato un errore di lettura.
In tali condizioni stai per perdere le tue informazioni e i tuoi dati importanti o anche in alcuni casi quando senti la mancanza di backup e programma di ripristino per le informazioni di avvio del tuo computer e Salvataggio da attacchi di virus programmi ecc., potresti subire una grossa perdita di dati sotto forma di crash del sistema operativo verificatosi a causa della mancanza di informazioni, memorizzate nel floppy che ora non sono leggibili dal computer.
In questi casi diventa un requisito molto importante recuperare i dati dal floppy che è stato dichiarato danneggiato dal tuo sistema informatico.
Perché il floppy non è leggibile
Il problema più comune che fa sì che un floppy mostri questo tipo di messaggi di errore è la corruzione del suo record di avvio DOS (DBR) del floppy, che aiuta il computer a conoscere l'identificazione logica del floppy.
Il DBR è un piccolo programma memorizzato nella traccia 0, nell'intestazione 0 e nel settore 1 e contenente informazioni importanti sul floppy come:
- Numero di byte per settore
- Settore per cluster
- Numero di FAT
- Numero massimo di directory radice ecc.
Poiché Floppy non ha un sistema di partizione logica, quindi non c'è MBR disponibile nel floppy. Il primo settore di Floppy detiene il DBR. Questa è anche una differenza principale per confrontare la struttura logica del disco rigido con un floppy.
Quando leggiamo le informazioni del settore di avvio di un floppy con l'aiuto di qualsiasi programma di modifica del disco, verranno visualizzate informazioni come nella figura riportata di seguito.
La figura seguente mostra le informazioni di 512 byte del DBR di un 1.44MB, 3½ Floppy da pollici.
Se queste informazioni sono danneggiate in qualsiasi modo o diventano illeggibili, il floppy disk causa tali messaggi di errore di lettura. Potrebbe essere dovuto a un danneggiamento fisico o logico del primo settore del disco.
La Corruzione logica include i casi in cui le informazioni del primo settore del floppy vengono modificate, si verifica un qualsiasi settore logico danneggiato o il DBR del floppy è danneggiato per qualsiasi altro motivo.
La corruzione fisica dovrebbe aver luogo in caso di settori danneggiati fisici (significa che il settore 1 è fisicamente danneggiato) sul primo settore del floppy disk. Il problema diventa più serio quando scopri che il floppy ha più di un settore danneggiato nella traccia 0.
Come recuperare
Dato che abbiamo appreso entrambe le cause della corruzione, spero che ora tu sia in grado di capire il problema. Non è una cosa molto difficile recuperare i dati dal danneggiamento logico, tuttavia il recupero dal danneggiamento fisico richiede sforzi leggermente maggiori.
Metodo – 1
Archivia l'immagine di avvio di qualsiasi nuovo floppy
Se il problema è logico, ora capiamo come possiamo recuperare i dati. Quello che dobbiamo fare è solo ottenere il record di avvio appropriato da un altro floppy della stessa dimensione e capacità e incollarlo nel primo settore del floppy illeggibile. Sebbene il problema sia stato creato a causa del record di avvio errato, ora dovrebbe funzionare.
Ci sono due passaggi coinvolti in questa procedura in seguito ai quali stiamo recuperando i nostri dati da un floppy illeggibile:
- Realizzare l'immagine di DOS Boot Record di un buon floppy
- Incollare l'immagine di avvio nel primo settore del floppy illeggibile
Realizzare l'immagine del Boot Record DOS di un buon floppy
Per memorizzare l'immagine del record di avvio del floppy fresco, il programma deve eseguire le seguenti tre attività:
- Leggi esattamente i primi 512 byte del floppy buono
- Verifica la riuscita dell'operazione di lettura (più importante)
- Memorizza questi 512 byte nel nome file e nel percorso di destinazione specificati
Il settore del floppy è di 512 byte ed è necessario copiare l'immagine esatta del settore. È il passaggio più importante e necessario in caso di qualsiasi tipo di operazione applicata su floppy per verificare se l'operazione è andata a buon fine o meno.
Potrebbero esserci problemi di inizializzazione anche con il disco floppy buono e fresco. Ecco perché nella maggior parte dei casi in cui l'operazione viene eseguita su floppy disk, prima di tutto l'inizializzazione dei floppy disk viene eseguita in programmazione con l'operazione di ripristino del disco (Funzione 00 H di INT 13H).
Se anche dopo l'inizializzazione il floppy disk inserito di recente o il floppy disk modificato causa un qualsiasi errore di lettura, ti consigliamo di eseguire nuovamente il programma, molto probabilmente questa volta potrebbe funzionare.
Il seguente programma serve per eseguire queste attività specificate. Vediamo come procede:
/* Memorizza l'immagine di avvio in un file da un nuovo 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");
/// Inizializza il sistema disco \\\
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;
}
Commenti sulla codifica del programma:
Nella codifica del programma data in precedenza, fondamentalmente stiamo procedendo a eseguire le seguenti attività passo dopo passo:
- dinfo punta alla struttura diskinfo_t che contiene le informazioni sui parametri richiesti dall'operazione eseguita dalla funzione _bios_disk.
- Poiché vogliamo leggere il primo settore del disco, la posizione del settore sarà la seguente:
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 |
- Apri un flusso di file di nome file e percorso dati dall'utente per memorizzare le informazioni sull'immagine di avvio di 512 byte esatti. Il nome e il percorso del file sono memorizzati nell'array di caratteri fname.
- Inizializza il sistema del disco usando l'interrupt 13H (funzione 00h) dove regs.h.ah = 0x00 punta alla funzione 00 H e regs.h.dl = 0x00 è usato per a: floppy. E int86(0x13, ®s, ®s) richiama il servizio di interrupt MS-DOS INT 13 H.
- _bios_disk(_DISK_READ, &dinfo) legge il settore specificato del floppy disk.
- Lo stato restituito viene memorizzato nel risultato utilizzato per visualizzare il messaggio di operazione riuscita o per visualizzare un messaggio di errore sullo schermo in caso di errore.
Incollare l'immagine di avvio nel primo settore del floppy illeggibile
Per incollare l'immagine di avvio dal file nel primo settore del floppy illeggibile dobbiamo eseguire le seguenti tre attività principali nel nostro programma:
- Legge le informazioni esatte di 512 byte del record di avvio del nuovo floppy dal file salvato in precedenza.
- Scrivi queste informazioni nel primo settore del floppy che è attualmente illeggibile.
- Verifica il corretto completamento dell'operazione di scrittura (più importante).
Poiché il settore del floppy è di 512 byte ed è necessario incollare l'esatta immagine di avvio nel settore. È il passaggio più importante e necessario in caso di qualsiasi tipo di operazione applicata su floppy per verificare se l'operazione è andata a buon fine o meno.
Potrebbe esserci qualche problema di inizializzazione del floppy disk durante l'operazione quindi è necessario inizializzare il disco reimpostando il sistema del disco(usando la funzione 00H di INT 13H).
Se anche dopo l'inizializzazione il floppy disk inserito di recente o il floppy disk modificato causa un qualsiasi errore di lettura, ti consigliamo di eseguire nuovamente il programma, molto probabilmente questa volta potrebbe funzionare.
Il seguente programma serve per eseguire queste attività specificate. Vediamo come procede:
/* Carica l'immagine di avvio sul floppy illeggibile */
#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");
/// Inizializza il sistema disco \\\
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;
}
Commenti sulla codifica del programma:
Nella codifica del programma data in precedenza, fondamentalmente stiamo procedendo a eseguire le seguenti attività passo dopo passo:
- dinfo punta alla struttura diskinfo_t che contiene le informazioni sui parametri richiesti dall'operazione eseguita dalla funzione _bios_disk.
- Dato che scriveremo le informazioni sul primo settore del disco, la posizione del settore sarà la seguente:
- Apri il file in cui le informazioni sull'immagine di avvio di 512 byte di un nuovo floppy sono state memorizzate dal programma precedente. Il nome e il percorso del file sono memorizzati nell'array di caratteri fname.
- Inizializza il sistema del disco usando l'interrupt 13H (funzione 00h) dove regs.h.ah = 0x00 punta alla funzione 00 H e regs.h.dl = 0x00 è usato per a: floppy. E int86(0x13, ®s, ®s) richiama il servizio di interrupt MS-DOS INT 13 H.
- _bios_disk(_DISK_WRITE, &dinfo) scrive le informazioni di avvio dal file specificato nel primo settore (specificato) del floppy disk.
- Lo stato restituito viene memorizzato nel risultato utilizzato per visualizzare il messaggio di operazione riuscita o per visualizzare un messaggio di errore sullo schermo in caso di errore.
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 |
Facciamolo con un unico programma
Spero che ora tu abbia compreso il concetto alla base di questo tipo di recupero dati da floppy disk. Dopo questo immaginiamo un singolo programma che dia gli stessi risultati che abbiamo ottenuto con l'aiuto di due programmi precedentemente discussi.
Stavamo svolgendo le seguenti attività con i programmi discussi di recente:
- Memorizza le informazioni di avvio da un buon floppy disk in un file
- Incolla queste informazioni nel primo settore del floppy attualmente illeggibile Il file che stavamo usando per memorizzare l'immagine di avvio fungeva da bridge intermedio per collegare le operazioni di entrambi i programmi. Ma se definiamo queste informazioni di avvio nella codifica del nostro programma stesso, non abbiamo bisogno di creare un file così come non dobbiamo leggere le informazioni di avvio del floppy dal file.
Nel nostro prossimo programma raccontiamo al nostro programma cosa deve scrivere nel primo settore del floppy disk illeggibile e quindi possiamo evitare che due programmi diversi facciano lo stesso compito e possiamo recuperare il nostro dati come prima dal nuovo programma unico.
Il programma diventa così semplice con meno codifica e siamo in grado di ridurre la probabilità che si verifichino errori di lettura, scrittura o creazione di file. Stiamo svolgendo i seguenti quattro compiti importanti in questo programma:
Non pensare che il programma sia difficile da scrivere e da capire vedendo i 512 byte di informazioni esadecimali di dbuf[512]. Successivamente, discuteremo del modo più semplice per scrivere queste informazioni per il tuo programma codifica.
- Definisci le informazioni del record di avvio DOS nel sistema esadecimale da scrivere nel primo settore del floppy attualmente illeggibile.
- Reimposta il sistema del disco per inizializzare il floppy disk (INT 13H, Funzione 00H).
- Scrivi il record di avvio DOS nel primo settore del floppy
- Verifica il corretto completamento dell'operazione e l'errore, se verificatosi.
Esaminiamo il programma:
/* Programma singolo per caricare l'immagine di avvio predefinita su un floppy disk illeggibile */
#include <bios.h>
#include <stdio.h>
int main(void)
{
struct diskinfo_t dinfo;
union REGS regs:
int result, i;
/* Avvia immagine da caricare nell'unità floppy disk */
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");
/// Inizia il sistema del disco \\\
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 questa codifica del programma, fondamentalmente stiamo procedendo a eseguire le seguenti attività passo dopo passo:
- Il buffer di dati a caratteri statici dbuf[512] fornisce l'informazione di 512 byte in sistema esadecimale, che deve essere scritta nel primo settore del floppy illeggibile. dbuf[512] dice al computer durante l'operazione che quali informazioni devono essere scritte nel primo settore del floppy. (Vedi il prossimo programma)
- dinfo punta alla struttura diskinfo_t che contiene le informazioni sui parametri richiesti dall'operazione eseguita dalla funzione _bios_disk.
- Dato che scriveremo le informazioni sul primo settore del disco, la posizione del settore sarà la seguente:
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 |
- Inizializza il sistema del disco usando l'interrupt 13H (funzione 00h) dove regs.h.ah = 0x00 punta alla funzione 00 H e regs.h.dl = 0x00 è usato per a: floppy. E int86(0x13, ®s, ®s) richiama il servizio di interrupt MS-DOS INT 13 H.
- _bios_disk(_DISK_WRITE, &dinfo) scrive le informazioni di avvio dal file specificato nel primo settore (specificato) del floppy disk.
Lo stato restituito viene memorizzato nel risultato utilizzato per visualizzare il messaggio di operazione riuscita o per visualizzare un messaggio di errore sullo schermo in caso di errore.
Memorizzazione dell'immagine di avvio in caratteri ESADECIMAL da utilizzare nel nostro programma precedente
Sarà un lavoro molto difficile scrivere tutti i 512 caratteri del record di avvio DOS del floppy manualmente in sistema esadecimale senza alcun errore nel programma di cui abbiamo discusso di recente. Se riusciamo a scriverlo accuratamente anche allora sarà un compito difficile e che richiede tempo per farlo. Usiamo una mente complicata per memorizzare i dati per il buffer di dati dbuf[512] in un file.
Sappiamo che nella programmazione C i caratteri esadecimali sono rappresentati con 0x in modo tale che se il carattere esadecimale è A9 H, lo scriveremo nel nostro programma C come 0xA9. Il nostro prossimo programma sta facendo lo stesso. Memorizzerà i dati che dobbiamo scrivere nel nostro programma precedente, come i dati del buffer di dati dbuf[512].
Quello che devi fare è solo prendere un nuovo floppy per fare l'immagine del suo DBR e copiare l'output di questo programma dal file di destinazione specificato e incollare questi dati nel tuo programma. Eseguire un po' di formattazione se necessario. Vediamo come funziona:
/* 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);
}
/// Inizia il sistema del disco \\\
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;
}
Commenti sulla codifica del programma:
Così i dati vengono archiviati nel file specificato. Basta copiare i dati sul tuo programma ed eseguire la formattazione richiesta. Non dovresti mai dimenticare i seguenti suggerimenti durante la procedura:
- Assicurati che l'operazione del programma sia andata a buon fine e che i dati che sono stati memorizzati nel file di destinazione siano appropriati.
- Dovresti controllare l'operazione per verificare che non si siano verificati errori previsti.
- Devi inizializzare il floppy disk con il programma prima di leggere il suo settore di avvio. È possibile utilizzare la funzione 00H di INT 13H per questo scopo.
Metodo – 2
Cosa fare se Metodo – 1 non funziona?
Se il metodo – 1 non funziona e il disco illeggibile non consente al programma di riscrivere le informazioni di avvio sul suo primo settore, dovresti provare questo secondo metodo. Il motivo del fallimento di First Method potrebbe essere il danneggiamento fisico del primo settore del floppy disk.
In questo secondo metodo copieremo temporaneamente tutti i dati della superficie del Floppy illeggibile in un unico file e poi incolleremo questa immagine direttamente sulla superficie dell'altro disco buono.
La procedura prevede i seguenti due importanti passaggi:
- Settore per settore Copia temporaneamente tutti i dati della superficie del supporto del floppy in un unico file.
- Incolla i dati precedentemente memorizzati nel file, su un nuovo floppy fresco così com'è, sugli stessi settori.
Copia tutti i dati della superficie multimediale in un unico file
Per memorizzare tutti i dati della superficie del supporto del floppy, il programma deve svolgere le seguenti tre attività:
- Inizializzare correttamente il disco con l'aiuto della funzione 00H di INT 13H.
- Leggi le informazioni settore per settore della superficie e salvale in un unico file.
- Verifica la riuscita dell'operazione di lettura (più importante)
È molto comune avere problemi di inizializzazione con un floppy disk che porta molti messaggi di lettura non riusciti. Ecco perché il disco deve essere inizializzato prima dell'operazione di lettura e scrittura con l'aiuto della programmazione.
È il passaggio più importante e necessario in caso di qualsiasi tipo di operazione applicata su floppy per verificare se l'operazione è andata a buon fine o meno.
Se anche dopo l'inizializzazione il floppy disk inserito di recente o il floppy disk modificato causa un errore di lettura, ti consigliamo di eseguire nuovamente il programma, molto probabilmente questa volta potrebbe funzionare.
Il seguente programma deve eseguire queste attività specificate. Vediamo come procede:
/* Programma per memorizzare i dati della superficie fisica del floppy disk in un 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");
/// Inizia il sistema del disco \\\
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);
}
}
}
}
Commenti sulla codifica del programma:
Nella codifica del programma data in precedenza, fondamentalmente stiamo procedendo a eseguire le seguenti attività passo dopo passo:
- Il nome del file dell'array di caratteri[80] memorizza il percorso definito dall'utente e il nome del file in cui memorizzeremo temporaneamente i dati.
- dinfo punta alla struttura diskinfo_t che contiene le informazioni sui parametri richiesti dall'operazione eseguita dalla funzione _bios_disk.
- Inizializza il sistema del disco usando l'interrupt 13H (funzione 00h) dove regs.h.ah = 0x00 punta alla funzione 00 H e regs.h.dl = 0x00 è usato per a: floppy. E int86(0x13, ®s, ®s) richiama il servizio di interrupt MS-DOS INT 13 H.
- Dato che leggeremo tutte le informazioni sulla superficie del disco, i parametri di _bios_disk saranno i seguenti:
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) legge i dati dalla superficie fisica del floppy disk dal settore specificato da dinfo.
- Lo stato restituito viene memorizzato nel risultato utilizzato per visualizzare il messaggio di operazione riuscita o per visualizzare un messaggio di errore sullo schermo in caso di errore.
Ricorda sempre che la dimensione del file che contiene l'immagine dei dati del floppy disk deve essere esatti di 1.474.560 byte perché il floppy ha 80 tracce (da 0 a 79), 2 lati o testine (testa 0 e testa 1) , ogni traccia ha 18 settori e ogni settore contiene i 512 byte di dati, quindi
Total bytes = (Number of tracks) * (Number of Heads) *
(Number of Sectors per Track) * 512
= 80*2*18*512
= 1,474,560 Bytes
Quindi, se c'è qualche errore nella lettura in qualsiasi settore del floppy disk, cambierà la dimensione del file da 1.474.560 Byte, il che renderà l'intera informazione completamente o parzialmente inutilizzabile per il disco di destinazione su cui scriveremo l'immagine del disco settore per settore da questo file.
Questo è così perché il Computer legge le informazioni di qualsiasi file sulla superficie del supporto del floppy disk all'interno dell'intervallo di settore come è stato allocato nella sua unità di allocazione. Ora se i settori dei dati dei file vengono modificati, vengono modificate le informazioni complete sul file.
Pensando alla soluzione dell'errore di lettura dei settori
È possibile con il floppy danneggiato o illeggibile che abbia un'area così brutta sulla sua superficie che potremmo non essere in grado di leggere le informazioni dalla superficie del disco.
In questa condizione le informazioni di questo/i settore/i verranno saltate e l'immagine del floppy risulterà distorta anche per gli altri settori poiché la dimensione del file immagine in questo caso differisce da 1.474.560 Byte.
Per mantenere la dimensione del file immagine e per incollare il resto delle informazioni sulle posizioni esatte dei settori sul disco di destinazione, scriviamo alcune altre informazioni a nome dei dati originali di 512 byte e in questo modo, noi’ Saremo in grado di salvare il resto delle informazioni, tuttavia il recupero in tal caso potrebbe essere il recupero parziale.
Se il tuo sistema non riesce a leggere anche il primo settore del floppy di origine, dopo aver incollato l'immagine sul floppy di destinazione dovresti eseguire il programma descritto prima, per riscrivere il DOS Boot Record del floppy .
Vediamo come possiamo farlo programmando:
#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];
/*Informazioni di 512 byte per riempire lo spazio del settore danneggiato */
/// Ho usato 512 zeri per riempire lo spazio di 512 byte \\\
carattere statico 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");
/// Inizializza il sistema disco \\\
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);
/* Se il settore non è leggibile, occupa 512 byte per dbuf2 */
fwrite(dbuf2,512,1,tt);
}
printf("Reading Track= %d Head= %d Sector= %d\n",
track, head, sector);
}
}
}
}
Commenti sulla codifica del programma:
Nella codifica del programma, ogni passaggio è lo stesso del programma precedente tranne il buffer di dati dbuf2[512], che stiamo utilizzando per gestire l'errore generato dal settore danneggiato durante l'operazione di lettura del disco > e per mantenere le dimensioni del file immagine.
In questo modo stiamo riempiendo lo spazio delle informazioni, che non siamo riusciti a leggere dal settore danneggiato e ora stiamo scrivendo la pseudo informazione di 512 byte in modo da poter mantenere l'accuratezza dell'immagine del disco.
Incolla i dati dal file sulla superficie fisica del nuovo floppy:
In questo passaggio, incolliamo i dati memorizzati nel file dal programma precedente, sulla superficie fisica del nuovo floppy, settore per settore, nello stesso modo in cui li abbiamo copiati nel file.
Il programma procede con i seguenti passaggi principali:
- Apri temporaneamente il file in cui abbiamo memorizzato i dati di superficie del floppy illeggibile.
- Inizializzare correttamente il sistema del disco tramite la funzione di ripristino 00H di INT 13H.
- Scrivi le informazioni sui settori del floppy fresco dal file.
- Visualizza lo stato di scrittura contemporaneamente per trovare o evitare il verificarsi di errori.
Il codice sorgente del programma è stato fornito di seguito. Esaminiamo come funziona:
/* Programma per scrivere i dati sui settori della superficie del floppy fresco dal file, creato dal programma precedente */
#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);
}
/// Inizializza il sistema disco \\\
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);
}
}
}
}
Commenti sulla codifica del programma:
Nella codifica del programma data in precedenza, fondamentalmente stiamo procedendo a eseguire le seguenti attività passo dopo passo:
- Il nome del file dell'array di caratteri[80] contiene il percorso e il nome del file in cui abbiamo archiviato temporaneamente i dati della superficie del floppy illeggibile.
- dinfo punta alla struttura diskinfo_t che contiene le informazioni sui parametri richiesti dall'operazione eseguita dalla funzione _bios_disk.
- Inizializza il sistema del disco usando l'interrupt 13H (funzione 00h) dove regs.h.ah = 0x00 punta alla funzione 00 H e regs.h.dl = 0x00 è usato per a: floppy. E int86(0x13, ®s, ®s) richiama il servizio di interrupt MS-DOS INT 13 H.
- Dato che scriveremo le informazioni direttamente sui settori della superficie del disco, i parametri di _bios_disk saranno i seguenti:
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) scrive i dati sui settori della superficie fisica del floppy disk, specificati da dinfo.
- Lo stato restituito viene memorizzato nel risultato utilizzato per visualizzare il messaggio di operazione riuscita o per visualizzare un messaggio di errore sullo schermo in caso di errore.
Se dopo il Metodo – 2 il tuo nuovo floppy non funziona, puoi applicare ulteriormente il Metodo – 1 sul tuo nuovo floppy, che hai usato come disco di destinazione durante il Metodo – 2.
Non solo questo, ma anche il numero di accessi e prove può variare a seconda del danneggiamento del disco. Ma non devi preoccuparti se anche dopo non ottieni risultati soddisfacenti.
Puoi provare il recupero file per file o puoi provare molti altri suggerimenti che imparerai in seguito. Qui implementeremo l'idea di raccogliere le informazioni sui file dalle directory principali, nella nostra programmazione per recuperare i dati.
Pensando al recupero logico dei dati cancellati o persi:
Tutti i casi precedenti di cui abbiamo discusso in questo capitolo per il recupero, dovevano recuperare i dati in quei casi in cui ci aspettavamo che solo il DBR fosse danneggiato e i settori nella traccia 0, avendo FAT1, FAT2 e le directory root sono leggibili.
Ma se il problema è dovuto alla corruzione della FAT o i dati sono stati cancellati dal disco oppure vuoi recuperare i dati direttamente leggendone le informazioni dalla directory principale, dobbiamo leggere informazioni quali Nome file, cluster iniziale, dimensione del file , Attributo ecc. dalla sua voce della directory principale.
Come abbiamo già discusso su Root Directory nei capitoli precedenti, ci sono le informazioni di 32 byte per ogni file o directory. Questi 32 byte sono divisi come segue:
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 |
Noi recuperiamo i dati leggendo le informazioni dei file dalla Root Directory, quindi integriamo il file nel percorso di destinazione e recuperiamo il file. Il nostro prossimo programma esegue i seguenti passaggi per recuperare i dati:
- Leggi le voci della directory principale e visualizzale sullo schermo con tutte le informazioni come il nome del file/directory, l'estensione del file, la dimensione del cluster iniziale dei file in byte.
- Leggi le informazioni su File e Directory nelle Sottodirectory e visualizzale se necessario.
- Conferma il nome del file da recuperare e continua il ripristino.
- Calcola le informazioni CHS (Cilindro, Testa e Settore) per il file specificato da recuperare.
- Integra i dati del file dall'area dati del disco e salva il file recuperato nel nome del file di destinazione specificato nel percorso specificato.
A questo programma non interessa se le informazioni di avvio del floppy sono leggibili o meno. Pertanto puoi recuperare anche i dati cancellati dal disco floppy danneggiato. Vediamo la codifica del programma:
/* Programma per recuperare i dati dal floppy disk leggendo le informazioni sui file dalla directory principale */
#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
}
/// Formato dello schermo di visualizzazione delle informazioni \\\
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("--------------------------------------------");
/* Un settore alla volta. Ogni voce File/DIR richiede 32 byte */
for(i=0;i<512;i+=32)
{
for(j=0;j<8;j++)
{
/// Trova il nome del file/della directory \\\
root[file_no].name[j]=buf[j+i];
}
for(j=8;j<11;j++)
{
/// Trova l'estensione \\\
root[file_no].ext[j-8]=buf[i+j];
}
j=11;
root[file_no].attribute=buf[i+j]; /// Attribute
/// Avvio del cluster \\\
root[file_no].start=(0xff & buf[27+i])*16*16 + (0xff & buf[26+i]);
/// Calcola la dimensione \\\
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
Ricorda che il nome del file che inizia con s (E5H) indica che il file è stato eliminato e quindi il primo carattere del nome del file è stato sostituito con s (vedi la descrizione della directory principale nei capitoli precedenti).
E l'output del programma viene visualizzato in questo modo:
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 !!!
|
Commenti sulla codifica:
La funzione Visualizza_Informazioni serve per leggere le informazioni su file e directory e dalla directory principale. Nella struttura stiamo leggendo le informazioni di 32 byte per ogni file o directory con root[32].
Gli array di interi senza segno name[8] ed ext[3] sono per il nome del file o della directory per DOS nel formato 8.3 (otto punti e tre). Allo stesso modo un byte è per l'attributo e due byte per l'avvio del cluster. dimensione int lunga senza segno; è memorizzare la dimensione del file di quattro byte.
La funzione _bios_disk legge il settore, specificato dalla struttura finfo e lo stato dell'operazione viene memorizzato nel risultato.
Da ogni informazione di 512 byte letta dalla funzione _bios_disk, fino al termine dell'area della directory principale, raccogliamo le informazioni dei file e delle directory memorizzate nel disco e visualizzarli sullo schermo.
L'intero file_no memorizza il numero del file o della directory nell'elenco, a partire da 0. Generalmente la dimensione della directory radice è di 14 settori e la directory radice generalmente inizia da Cilindro =0, Head = 0 e Sector =2 in caso di 1.44MB e 3½ floppy disk.
Se l'utente fornisce il carattere ‘M’ o ‘m’ come input, vengono visualizzate le informazioni del settore successivo se la scelta dell'utente è ‘R’ o ‘r’ vengono chiamate le funzioni di ripristino. La codifica della funzione recover() è stata data di seguito:
/* Funzione per avviare il ripristino del file specificato */
void recover(unsigned int *root,unsigned int len)
{
void clear_the_line(unsigned int r); /* Function to Clear a Row on the Screen */
/* Funzione per integrare il file specificato */
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));
/* Conferma il nome del file da recuperare */
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);
/// Spiacenti, hai selezionato una 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);
/* Visualizza i contenuti della directory */
Display_Information (cylinder,head,sector);
}
else
/* Ask for A file again and Continue Recovery */
recover(root,len);
}
else
{
size=*(loc+13);
/* Calcola per informazioni CHS */
calculate(start,&cylinder,&head,§or);
/* Integra il file */
integrate(size,cylinder,head,sector);
}
}
Commenti sulla codifica:
La funzione recover() serve per ottenere l'input dell'utente per avviare il ripristino. Il numero di file dato come input dall'utente per recuperare il file, è memorizzato in file_no.
Se il numero inserito è per la voce Directory, Display_Information() mostra il contenuto di quella directory, altrimenti Il nome file e l'estensione del numero file file_no vengono visualizzati sullo schermo per confermare il file da recuperare.
Per recuperare il file specificato, le funzioni calcola() e integra() vengono chiamate all'interno della funzione. La codifica della funzione calcola() è stata data di seguito:
/* Funzione per calcolare la geomateria CHS per il recupero */
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;
}
/// Mostra il CHS del file da recuperare \\\
gotoxy(10,23);
cprintf("Cylinder = %u, Head = %u, Sector = %u",
*cylinder,*head,*sector);
}
Commenti sulla codifica:
La funzione calcola() serve a calcolare le informazioni su cilindro, testa e settore per il file da recuperare. Dopo il calcolo sullo schermo vengono visualizzati i numeri di Cilindro, Testata e Settore.
La codifica per la funzione integra() è stata data di seguito:
/* Integra il file e salva il file recuperato nel percorso e nel nome del file specificati */
void integrate(long unsigned int size,
unsigned int cylinder,
unsigned int head,
unsigned int sector)
{
void clear_the_line(unsigned int);
/* Funzione per verificare la presenza di errori nel settore */
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;
/* Inserisci il percorso di destinazione e il nome del file per salvare il file recuperato */
gotoxy(2,24);
cprintf("Enter Path and Filename to recover the file: ");
fflush(stdin);
gets(Filename_with_path);
fp=fopen(Filename_with_path,"wb");
/* Se si verifica un errore, mostra il messaggio di errore e ottieni di nuovo il percorso e il nome del file di input */
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 */
}
/* Se tutto va bene, integra e scrivi */
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);
}
Commenti sulla codifica:
La funzione integra() è il modulo effettivo per eseguire il ripristino del file specificato dall'utente, in questo programma di ripristino.
Il nome del file con il percorso di destinazione per memorizzare il file recuperato è memorizzato nel puntatore del carattere *Filename_with_path. Se si verifica un errore nell'apertura del file di destinazione, viene visualizzato un messaggio di errore e all'utente viene nuovamente chiesto di inserire la destinazione.
La funzione _bios_disk(_DISK_READ, &dinfo); legge i dati del file dall'area dati del disco settore per settore, specificati dalla struttura dinfo e memorizzati nel buffer di dati buf . Questi dati di 512 byte vengono scritti nel file di destinazione. Questa operazione viene ripetuta fino a quando il file completo non viene integrato.
La funzione status=verify_the_sector (cilindro,testata,settore); verifica il settore da leggere. Se lo stato = 10, rappresenta un settore danneggiato (0xA). La codifica della funzione è stata data di seguito:
/// Verifica il settore. (Nessun dato viene trasferito qui) \\\
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);
}
Commenti sulla codifica:
La funzione interact_the_sector(), verifica il settore che deve essere letto dalla funzione _bios_disk() e restituisce lo stato dell'operazione. La funzione utilizza INT 13H e la funzione 4H per verificare il settore.
*buf è il buffer di dati, 0x04 è il numero della funzione specificato da in.h.ah = 0x04; e in.h.al = 1; indica di verificare un settore alla volta. in.h.dl = 0x00; viene utilizzato per il numero di unità per unità floppy A:, c,h e s sono numeri Cilindro, Testa e Settore.
La funzione int86x() viene utilizzata per richiamare INT 13H (funzione 4H) con valori di registro di segmento. Lo stato dell'operazione viene restituito dallo stato intero.
La funzione clear_the_line() cancella la riga specificata sullo schermo. La codifica della funzione è la seguente:
/* Funzione per cancellare la riga sullo schermo, per il numero di riga specificato */
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 " " */
}
}
Commenti sulla codifica:
La funzione viene utilizzata per cancellare la riga specificata sullo schermo. La funzione viene richiamata con il numero di riga da cancellare dallo schermo.
Pagina modificata il: 10/03/2022