Capitolo – 11
Creazione di copie di backup
Perché hai bisogno di backup?
"Prevenire è sempre meglio che curare." Il backup è inoltre una parte importante della prevenzione dei disastri sui dati, poiché può aiutarci a superare guasti del disco o qualsiasi altro tipo di perdita di dati. In questo capitolo parleremo di come è possibile recuperare i dati anche dopo gravi guasti del disco, semplicemente utilizzando i backup eseguiti in precedenza.
Il ripristino tramite backup salvati in precedenza è quasi sempre pari al 100 percento; tuttavia, in alcuni casi specifici, diversi tipi di guasti del disco possono causare differenze nei risultati del ripristino.
Ripristinare i dati tramite backup è un processo piuttosto semplice, veloce e affidabile che può dare i risultati migliori, mentre ripristinare i dati senza backup è complesso, confusionario e può richiedere molto tempo e, anche in questo caso, in molti casi abbiamo paura di non ottenere il 100 percento dei dati.
Quando e cosa prenotare
Ci sono diverse aree sul disco che devono essere copiate una volta o a intervalli diversi. La tabella seguente fornisce una panoramica dei passaggi necessari per un backup completo e aiuta a capire quando e cosa eseguire il backup:
Cosa bisogna riservare |
Quando è necessario il backup? |
Backup MBR |
Dopo FDISK. L'MBR viene creato dal comando DOS FDISK. È possibile eseguire il backup di MBR dopo FDISK, tuttavia anche dopo aver FORMATTATO le partizioni create da FDISK, MBR rimane invariato. |
Backup DBR |
Dopo la formattazione, creare un backup DBR per ciascun disco logico. |
Eseguire il backup delle voci e delle directory FAT. |
Le voci FAT e delle directory cambiano ogni volta che si creano o si eliminano file o directory. Si consiglia pertanto di effettuare una copia di backup ogni giorno. |
Backup dei dati utente |
Dovrebbe essere fatto regolarmente. Questo tipo di backup comporta la creazione di un'immagine del disco. Tuttavia, questa operazione richiede molto tempo, ma la maggior parte delle aziende che conservano dati molto sensibili sui propri dischi preferiscono dedicare il proprio tempo alla creazione di un'immagine del disco, perché in questo modo possono eseguire il backup di tutte le informazioni sopra descritte. |
Inoltre, dovresti creare un disco di avvio di emergenza per il sistema. Se si verifica un incidente con i dati presenti sul disco rigido, sarà possibile avviare il sistema utilizzando questo floppy disk e analizzare l'unità per individuare eventuali errori.
Backup dell'MBR (Master Boot Record) e del suo utilizzo
Il master boot record (MBR), talvolta chiamato anche master partition table (MPT), contiene un piccolo programma per caricare ed eseguire la partizione attiva (o avviabile) dal disco rigido. Il master boot record contiene informazioni su tutte e quattro le partizioni primarie.
Per una discussione dettagliata di MBR, vedere il capitolo "Un approccio logico ai dischi e al sistema operativo" discusso in precedenza in questo libro.
L'MBR si trova nel settore assoluto 0 o possiamo dire nel cilindro 0, nella testina 0 e nel settore 1. Viene creato sul disco rigido eseguendo il comando DOS FDISK.EXE.
Perché effettuare un backup dell'MBR:
MBR consente al settore di avvio della partizione attiva di assumere il controllo all'avvio del sistema.
Dopo il POST (Power-On Self-Test), il BIOS carica l'MBR (Master Boot Record) dal disco rigido nella memoria e poi lo esegue. Innanzitutto, l'MBR controlla il disco rigido per individuare una partizione attiva, quindi carica il record di avvio DOS (DBR) nella memoria e passa il controllo al codice di avvio del sistema operativo; quindi il codice del record di avvio del sistema operativo carica il resto del sistema operativo nella memoria.
Possiamo quindi affermare che se l'MBR del disco è danneggiato, il disco rigido è praticamente morto e il sistema non è più in grado di avviarsi o di eseguire il sistema operativo. In questo stato, tutti i dati memorizzati sul disco rigido diventano inaccessibili. In genere, i messaggi di errore vengono visualizzati come segue:
"Tabella delle partizioni non valida" "Errore durante il caricamento del sistema operativo" "Sistema operativo mancante"
Cosa può essere ripristinato utilizzando un backup MBR?
Eseguire il backup dell'MBR può aiutare a eliminare i messaggi di errore sopra indicati. Utilizzando il backup è possibile risolvere i seguenti problemi:
- Errore durante il caricamento del sistema operativo a causa di un IPL (initial program loader) danneggiato
- Partizione primaria persa(e)
- Informazioni sulla partizione corrotte
- Numero magico sbagliato
Scrittura di un programma per creare un backup MBR:
/* Programma per la creazione di backup MBR */
#include <bios.h>
#include <stdio.h>
int principale(vuoto)
{
struct diskinfo_t dinfo; /* Struttura per l'archiviazione
informazioni sui parametri del disco */
risultato int;
numero di numeri interi=0;
char nomefile[80]; /* Salva il nome del file specificato
Utente */
static char dbuf[512]; /* Buffer dati di 512 byte */
FILE *fp;
dinfo.drive = 0x80; /* numero di unità per il primo disco rigido
Disco */
dinfo.head = 0; /* numero della testina del disco */
dinfo.track = 0; /* numero traccia */
dinfo.sector = 1; /* numero settore */
dinfo.nsectors = 1; /* conteggio settori */
dinfo.buffer = dbuf; /* buffer dati */
printf("\n Inserisci il nome del file e il percorso in cui memorizzare il
Backup dell'MBR \n ");
ottiene(nomefile);
// Apri il file per archiviare il backup MBR \\
if((fp=fopen(nomefile,"wb"))==NULL)
{
printf("Impossibile creare il file, premere un tasto qualsiasi per
Uscita...");
ottenere();
uscita(0);
}
printf("Tentativo di lettura dal disco rigido:\n");
//// Leggere il settore del disco specificato \\\\
risultato = _bios_disk(_DISK_READ, &dinfo);
se ((risultato & 0xff00) == 0)
{
printf("Disco letto dall'unità disco rigido:
riuscito.\n");
/// Scrivi 512 byte di MBR nel file \\\\
mentre(conteggio<512)
{
fprintf(fp,"%c",dbuf[conteggio] & 0xff );
conta++;
}
fclose(fp);
}
altro
printf("Impossibile leggere l'unità disco rigido, stato = 0x%02x\n", risultato);
restituisci 0;
}
Commenti sulla codifica del programma:
Nella codifica del programma fornita in precedenza, sostanzialmente procediamo a svolgere le seguenti attività passo dopo passo:
- dinfo punta alla struttura diskinfo_t che contiene le informazioni dei parametri richiesti dall'operazione eseguita dalla funzione _bios_disk.
- Poiché vogliamo leggere il primo settore del disco, la posizione del settore sarà la seguente:
Parametro |
Cosa significa |
dinfo.unità = 0x80 |
Indica l'unità fisica 80H che è la prima unità disco rigido. |
dinfo.testa = 0 |
Indica la testa numero 0 |
dinfo.traccia = 0 |
Indica la traccia 0 |
dinfo.settore = 1 |
Primo settore del floppy che è il settore 1 |
dinfo.settore = 1 |
>Numero di settori da considerare per l'operazione di lettura = 1 |
dinfo.buffer = dbuf |
Buffer dati per l'operazione |
- Apre un flusso di file di nome file e percorso forniti dall'utente per archiviare il backup di MBR di 512 byte esatti. Il nome file e il percorso sono archiviati nell'array di caratteri filename.
- _bios_disk(_DISK_READ, &dinfo) legge il primo settore del disco rigido (80H), specificato da dinfo.
- Lo stato restituito viene memorizzato nel risultato, che viene utilizzato per visualizzare il messaggio di operazione riuscita o per visualizzare un messaggio di errore sullo schermo se si verifica un errore.
Programma per ripristinare l'MBR dal backup:
Se l'MBR è in qualche modo danneggiato, il programma fornito di seguito aiuta a ripristinarlo.
Bisogna sempre tenere a mente che l'uso illegale o l'uso in mancanza di conoscenza di questo programma può distruggere le informazioni dei dati nel disco rigido e può rendere inaccessibili tutti i dati. Bisogna essere sicuri di cosa si sta per fare. Altrimenti si può complicare ulteriormente il problema.
Programma per ripristinare l'MBR dal backup:
La codifica del programma è la seguente:
/* Programma per ripristinare il backup di MBR dal file di backup */
#include <bios.h>
#include <stdio.h>
int principale(vuoto)
{
struct diskinfo_t dinfo;
int risultato;
int conteggio=0;
char filename[80]; /* Memorizza il nome del file specificato
da Utente */
static char dbuf[512]; /* Buffer dati di 512 byte
*/
FILE *fp;
/* Ottieni l'input dell'utente per il percorso del file di backup MBR */
printf("\n Inserisci il nome del file e il percorso del file di backup di
Italiano:
ottiene(nomefile);
if((fp=fopen(nomefile,"rb"))==NULL)
{
printf("Impossibile aprire il file di backup, premere un tasto qualsiasi
per uscire...");
ottenere();
uscita(1);
}
/* I dati MBR dovrebbero essere di 512 byte esatti */
mentre(conteggio<512)
{
fscanf(fp,"%c",&dbuf[conteggio]);
conta++;
}
fclose(fp);
printf("Tentativo di scrittura sul disco rigido:\n");
dinfo.drive = 0x80; /* numero di unità per First
Disco rigido */
dinfo.head = 0; /* numero della testina del disco */
dinfo.track = 0; /* numero traccia */
dinfo.sector = 1; /* numero settore */
dinfo.nsectors = 1; /* conteggio settori */
dinfo.buffer = dbuf; /* buffer dati */
risultato = _bios_disk(_DISK_WRITE, &dinfo);
se ((risultato & 0xff00) == 0)
{
printf("Ripristino del backup di MBR sul disco
Settore: riuscito.\n");
}
altro
printf("Impossibile scrivere sul disco rigido, stato =
0x%02x\n", risultato);
restituisci 0;
}
Commenti sulla codifica del programma:
Nella codifica del programma sopra indicata, sostanzialmente procediamo ad eseguire le seguenti attività passo dopo passo:
- dinfo punta alla struttura diskinfo_t che contiene le informazioni dei parametri richiesti dall'operazione eseguita dalla funzione _bios_disk.
- Poiché vogliamo scrivere sul primo settore del disco, la posizione del settore sarà la seguente:
Parametro |
Cosa significa |
dinfo.unità = 0x80 |
Indica l'unità fisica 80H che è la prima unità disco rigido. |
dinfo.testa = 0 |
Indica la testa numero 0 |
dinfo.traccia = 0 |
Indica la traccia 0 |
dinfo.settore = 1 |
Primo settore del floppy che è il settore 1 |
dinfo.settore = 1 |
Numero di settori da considerare per l'operazione di lettura = 1 |
dinfo.buffer = dbuf |
Buffer dati per l'operazione |
- Il nome del file e il percorso del Backup di MBR, forniti dall'utente, sono memorizzati nell'array di caratteri filename. Si tenga presente che le informazioni MBR devono essere di 512 byte esatti.
- _bios_disk(_DISK_WRITE, &dinfo) scrive i dati sul primo settore del disco rigido (80H), specificato da dinfo.
- Lo stato restituito viene memorizzato nel risultato, che viene utilizzato per visualizzare il messaggio di operazione riuscita o per visualizzare un messaggio di errore sullo schermo se si verifica un errore.
Backup del DBR (DOS Boot Record) e suo utilizzo
Dopo la tabella delle partizioni, il DOS Boot Record (DBR), talvolta chiamato DOS Boot Sector, è la seconda informazione più importante sul disco rigido.
Per uno studio dettagliato su DBR, fare riferimento al capitolo " Approccio logico ai dischi e al sistema operativo ", discusso in precedenza in questo libro.
Il primo settore logico di ogni partizione DOS conterrà un DOS Boot Record (DBR) o DOS Boot Sector. Il compito del DBR è caricare il sistema operativo dall'unità disco rigido nella memoria principale del computer e dare il controllo del sistema al programma caricato.
Il DOS Boot Record (DBR) per la prima partizione su un disco rigido si trova solitamente nel settore assoluto 63 (il 64° settore dell'unità disco) o nella forma CHS possiamo dire C–H–S = 0–1–1 per la maggior parte delle unità.
Tuttavia questa posizione può variare a seconda degli SPT (settori per traccia) dell'unità. Ad esempio, su una vecchia unità da 245 MB con solo 31 SPT, il Boot Record si trovava sul 32° settore (settore assoluto 31).
Il DBR viene creato dal comando FORMAT del DOS, dopo che il partizionamento è stato eseguito tramite il comando FDISK. Il settore su cui risiede il DBR diventa il settore logico 1 di quella particolare partizione per il DOS. Il numero di settore utilizzato dal DOS inizia dal settore fisico su cui si trova il DBR.
Il DBR contiene un piccolo programma che viene eseguito dal programma eseguibile Master Boot Record (MBR). Tutte le partizioni DOS contengono il codice del programma per avviare la macchina, ovvero caricare il sistema operativo, ma solo quella partizione riceve il controllo dal Master Boot Record, che è specificato come partizione attiva nella voce della tabella delle partizioni.
Perché eseguire il backup di DBR:
Il DBR contiene alcune informazioni importanti sulla geometria del disco. Queste informazioni si trovano nel primo settore di ogni partizione, come:
- Codice di salto + NOP
- Nome e versione OEM
- Byte per settore
- Settori per cluster
- Settori riservati
- Numero di copie di FAT
- Numero massimo di voci della directory radice (ma non disponibile per FAT32)
- Numero di settori in partizioni inferiori a 32 MB (quindi non disponibili per FAT32)
- Descrittore del supporto (F8H per dischi rigidi)
- Settori per FAT (nei vecchi sistemi FAT e non disponibili per FAT32)
- Settori per traccia
- Numero di teste
- Numero di settori nascosti nella partizione
- Numero di settori nella partizione
- Numero di settori per FAT
- Flag descrittivi delle informazioni FAT
- Versione dell'unità FAT32
- Numero di cluster dell'inizio della directory radice
- Numero di settore del settore delle informazioni del file system
- Numero di settore del settore di avvio di backup
- Prenotato
- Numero di unità logica della partizione
- Firma estesa (29H)
- Numero di serie della partizione
- Nome del volume della partizione
- Nome FAT
- Codice eseguibile
- Marcatore eseguibile o numero magico (AAH 55H)
In genere sullo schermo vengono visualizzati i seguenti messaggi di errore:
"Errore di avvio del disco"
“Disco non di sistema o errore del disco”
“Disco di sistema non valido o errore I/O del disco”
“Sostituisci il disco, quindi premi un tasto qualsiasi…”
Cosa si può recuperare con il Backup di DBR?
Il backup di DBR può aiutarti a sbarazzarti dei messaggi di errore di cui sopra. Questi messaggi di errore sullo schermo aspettano che l'utente inserisca un disco avviabile con i programmi sopra menzionati nell'unità floppy e prema un tasto.
L'unità dovrebbe essere accessibile se si avvia il sistema dal floppy o CD avviabile. Sebbene il disco rigido non sia avviabile, in genere ciò non dovrebbe influire sull'accesso ai dati dell'unità disco. Dopo aver avviato il sistema con il disco avviabile, è possibile accedere ai dati.
Ripristinando il backup di DBR è possibile superare i problemi generati, come menzionato sopra.
Programmi per creare e ripristinare backup di DBR:
I programmi per effettuare il backup dei DBR e ripristinarli sono quasi simili ai programmi per il backup e il ripristino dei MBR.
Ad esempio, se si desidera scrivere programmi per effettuare il backup del DBR della prima unità logica del disco e per ripristinarlo, i parametri specificati dalla struttura dinfo verranno modificati come segue:
Parametro |
Cosa significa |
dinfo.unità = 0x80 |
Indica l'unità fisica 80H che è la prima unità disco rigido> |
dinfo.testa = 1 |
Indica la testa numero 1 |
dinfo.traccia = 0 |
Indica la traccia 0 |
dinfo.settore = 1 |
Primo settore del floppy che è il settore 1 |
dinfo.settore = 1 |
Numero di settori da considerare per l'operazione di lettura = 1 |
dinfo.buffer = dbuf |
Buffer dati per l'operazione |
Qui vediamo che è cambiata solo la posizione del settore da leggere/scrivere. Qui il CHS è dato come 0-1-1 poiché il DBR della prima unità logica è memorizzato qui.
Immagine completa del disco
Questo tipo di backup sta diventando sempre più popolare oggigiorno ed è il preferito da organizzazioni che hanno dati molto sensibili nei loro sistemi. Queste persone non possono correre alcun rischio di perdere neanche un singolo percento di dati.
Tali organizzazioni eseguono regolarmente i loro backup come immagine dell'intero disco. Sebbene richieda un po' di tempo, ti dà la certezza che non ti perderai nulla. Grazie alla sua crescente popolarità, i programmatori hanno fatto del loro meglio per rendere il software di imaging del disco sempre più veloce per ridurre al minimo il periodo di tempo impiegato dal processo di imaging.
L'imaging del disco è una buona idea perché spendendo solo qualche decina di minuti puoi avere la tranquillità di avere un backup di tutto in tasca. Tutti i fattori come MBR, BDR, FAT, directory radice vengono copiati sul disco di destinazione così com'è.
Ciò di cui abbiamo bisogno per l'imaging del disco è un disco rigido di destinazione identico (o quasi identico) al nostro disco rigido di origine in cui abbiamo i nostri preziosi dati. Una cosa va sempre tenuta a mente: il disco di destinazione non deve essere più piccolo del disco di origine.
Dopo aver acquisito l'immagine completa, se si avvia il sistema con il disco di destinazione in cui è stata acquisita l'immagine del disco, in genere si otterranno tutti i dati così come sono.
Scrittura del programma per l'imaging completo del disco
Il programma per l'imaging del disco è stato fornito di seguito. Il programma utilizza le estensioni INT 13H, quindi può supportare anche dischi di grandi dimensioni.
Il programma crea l'immagine del primo disco rigido fisico (0x80) sul secondo disco rigido fisico (0x81); pertanto, prima di creare l'immagine di backup, è opportuno tenere presente che tutti i dati nel disco di destinazione (0x81) verranno sovrascritti dai dati del disco di origine (0x80) settore per settore.
Di seguito è riportata la codifica del programma:
/* Programma per creare l'immagine del primo disco rigido (0x80) sul secondo disco rigido (0x81) */
#include<stdio.h>
#include<dos.h>
#include<conio.h>
/* Struttura da utilizzare tramite la funzione getdrivegeometry mediante l'estensione INT 13H, numero funzione 0x48. */
geometria della struttura
{
unsigned int size ; /* (chiamata) dimensione del buffer */
unsigned int flags ; /* Flag informativi */
unsigned long cyl ; /* Numero di dati fisici
Cilindri in trasmissione */
teste lunghe senza segno ;/* Numero di dati fisici
Teste su Drive */
unsigned long spt ; /* Numero di dati fisici
Settori per traccia */
settori lunghi senza segno[2] ; /* Numero totale di
Settori su Drive */
unsigned int bps ; /* Byte per settore */
} ;
/* Struttura del formato del pacchetto di indirizzi del disco, da utilizzare con le funzioni readabsolutesectors e writeabsolutesectors */
struct pacchettodischi
{
char packetsize ; /* Dimensione del pacchetto, generalmente 10H */
char riservato ; /* Riservato (0) */
int blockcount ; /* Numero di blocchi da trasferire */
char far *bufferaddress ; /* indirizzo da trasferire
Respingente */
unsigned long blocknumber[2] ; /* Avvio assoluto
Numero di blocco */
} ;
///// Funzione per ottenere i parametri dell'unità \\\\\
unsigned long getdrivegeometry (int unità)
{
unione REGS i, o ;
costruire SREGS s ;
geometria della struttura g = { 26, 0, 0, 0, 0, 0, 0, 0, 0 } ;
ihah = 0x48 ; /* Funzione numero 0x48 di INT 13H
Estensioni Vedi i commenti
Sotto */
ihdl = unità; /* Numero unità */
ixsi = FP_OFF ( (void far*)&g ) ;
s.ds = FP_SEG ( (void far*)&g ) ;
/* Richiama il numero di funzione specificato dell'estensione INT 13H con valori del registro di segmento */
int86x ( 0x13, &i, &o, &s ) ;
printf("\n Testa = %lu, Settori per traccia = %lu, Cilindro =
%lu\n", g.teste, g.spt, g.cyl);
/* Se la funzione Get Drive Geometry fallisce, visualizza un messaggio di errore ed esci */
se(g.spt==0)
{
printf("\n La funzione Ottieni geometria unità fallisce....");
printf("\n Estensioni non supportate, premere un tasto qualsiasi per
Uscita...");
ottenere();
uscita(1);
}
return *g.sectors; /* Restituisce il numero di settori
su Drive */
}
////// Inizio del principale \\\\\
vuoto principale()
{
ciclo lungo senza segno=0, Settori_in_HDD1=0, Settori_in_HDD2=0;
unsigned char buffer[61440]; /* Buffer dati di 61440
Byte per leggere/scrivere 120 settori da 512 byte alla volta per risparmiare tempo. */
scelta del carattere;
clrscr();
/* Se il numero totale di dischi rigidi collegati è inferiore a due, visualizza un messaggio di errore ed esci. */
se(((char)peekb(0x0040, 0x0075))<2)
{
printf("\n\n Devi avere almeno due dischi rigidi
Collegato al computer per eseguire questo");
printf("\n Programma. Premi un tasto qualsiasi per uscire... ");
ottenere();
uscita(1);
}
/// Ottieni i parametri del primo disco rigido (0x80) \\\
Settori_in_HDD1 = getdrivegeometry (0x80);
printf(" Totale settori nel primo disco rigido = %lu\n\n",
Settori_in_HDD1);
/// Ottieni i parametri del secondo disco Hsrd (0x81) \\\
Settori_in_HDD2 = getdrivegeometry (0x81);
printf(" Totale settori nel secondo disco rigido = %lu\n\n",
Settori_in_HDD2);
/// Prima conferma, poi procedi \\\
printf("\n Tutti i dati nel secondo disco rigido saranno
perduto !!!");
printf("\n Premi \'Y\' per continuare, altrimenti premi un tasto qualsiasi per
Uscita... ");
scelta = getche();
interruttore(scelta)
{
caso 'y':
caso 'Y':
rottura;
predefinito:
uscita(0);
}
/* La destinazione non deve essere inferiore alla sorgente */
se(Settori_in_HDD2<Settori_in_HDD1)
{
printf("\n\n Il disco di destinazione non dovrebbe essere più piccolo
rispetto al disco di origine");
printf("\n Premi un tasto qualsiasi per uscire...");
ottenere();
uscita(0);
}
/* Se tutto è a posto, copia tutti i settori del disco di origine sul disco rigido di destinazione */
gotoxy(10,15);printf("Copia del settore assoluto: ");
for(ciclo=0;ciclo< =Settori_in_HDD1;ciclo=ciclo+120)
{
readabsolutesectors (0x80, ciclo, 120, buffer);
writeabsolutesectors (0x81, ciclo, 120, buffer);
gotoxy(36,15); printf("%ld",ciclo);
se(kbhit())
{
uscita(0);
}
}
//// Mostra il messaggio di completamento \\\
printf("\n\n L'immagine del disco è ora completata, premere un tasto qualsiasi
Per uscire...");
ottenere();
}
//// Fine della parte principale
Commenti sulla codifica:
Nella codifica del programma fornita in precedenza, per l'imaging del disco procediamo eseguendo le seguenti attività:
- La struttura, la geometria è utilizzata dalla funzione getdrivegeometry tramite l'estensione INT 13H, numero funzione 0x48. Per una descrizione dettagliata sulle estensioni INT 13H, fare riferimento al capitolo "Gestione di dischi rigidi di grandi dimensioni", discusso in precedenza in questo libro.
I tipi di dati che rappresentano diversi parametri del disco hanno i seguenti significati:
Tipo di dati |
Dimensione in byte |
Descrizione |
dimensione int senza segno |
2 byte |
Dimensione del buffer |
flag int senza segno |
2 byte |
Bandiere informative |
cilindro lungo non firmato |
4 byte |
Numero di cilindri fisici sull'unità |
teste lunghe senza segno |
4 byte |
Numero di testine fisiche sull'unità |
spt lungo non firmato |
4 byte |
Numero di settori fisici per traccia |
settori lunghi senza segno [2] |
8 byte |
Numero totale di settori sull'unità |
int senza segno bps |
2 byte |
Byte per settore |
- La struttura diskaddrpacket è utilizzata dalle funzioni readabsolutesectors e writeabsolutesectors. Il formato del pacchetto di indirizzi disco è stato fornito nella seguente tabella:
Tipo di dati |
Dimensione in byte |
Descrizione |
char dimensione pacchetto |
1 byte |
Dimensione del pacchetto, generalmente 10H |
carattere riservato |
1 byte |
Riservato (0) |
int conteggio blocchi |
2 byte |
Numero di blocchi da trasferire |
char lontano *indirizzobuffera |
4 byte |
indirizzo a Transfer Buffer |
numero di blocco lungo non firmato [2] |
4 byte |
Numero assoluto di blocco iniziale |
- La funzione getdrivegeometry viene utilizzata per ottenere i parametri del Drive specificato. La funzione getdrivegeometry utilizza il numero di funzione 0x48 di INT 13H Extensions.
Il significato dei parametri è stato descritto nella tabella seguente:
Parametro |
Cosa significa |
ihah = 0x48 |
Numero funzione 0x48 delle estensioni INT 13H |
ihdl = guidare |
Numero di unità |
ixsi = FP_OFF ( (void lontano*)&g ) |
ds:si indirizzo da bufferizzare per i parametri dell'unità come discusso in precedenza |
s.ds = FP_SEG ( (void far*)&g ) |
ds:si indirizzo da bufferizzare per i parametri dell'unità come discusso in precedenza |
La funzione int86x(0x13, &i, &o, &s) richiama l'interrupt 13H con i valori del registro di segmento. La funzione getdrivegeometry restituisce il numero totale sull'unità.
- Nella funzione main(), (char)peekb(0x0040, 0x0075); (la funzione peekb è definita in DOS.H) restituisce il numero di dischi rigidi collegati al sistema.
Il numero di dischi rigidi collegati al sistema è rappresentato dal byte memorizzato nella posizione di memoria 0040H:0075H (Segmento 0040H: Offset 0075H). Se il numero di dischi rigidi collegati al sistema è inferiore a due, il programma mostra il messaggio di errore ed esce.
Sectors_in_HDD1 = getdrivegeometry (0x80); ottiene i parametri del primo disco rigido (0x80) e restituisce il numero totale di settori sul primo disco rigido.
Allo stesso modo Sectors_in_HDD2 = getdrivegeometry (0x81); ottiene i parametri del secondo disco rigido (0x81) e restituisce il numero totale di settori sul secondo disco rigido.
Dopo la conferma da parte dell'utente di continuare con l'imaging, controllare prima la condizione che la dimensione del disco rigido di origine non debba essere maggiore della dimensione del disco rigido di destinazione. Se la destinazione è più piccola, visualizzare il messaggio di errore ed uscire.
Se tutto va bene, copia i settori del disco sorgente sul disco di destinazione. Qui stiamo leggendo e scrivendo 61440 byte (120 settori con ognuno di 512 byte) alla volta per rendere più veloce il processo di imaging.
Se vuoi usare più settori alla volta, anche oltre il limite di 64K, puoi farlo usando "Puntatore enorme" nel modello di memoria grande. L'esempio di specifica è il seguente:
char array enorme[100000L];
- La funzione readabsolutesectors (0x80, loop, 120, buffer); legge i 120 settori del primo disco rigido (0x80), a partire dal numero di settore specificato dal loop unsigned long integer e memorizza i dati nel buffer dati.
- La funzione writeabsolutesectors (0x81, loop, 120, buffer); scrive i dati del buffer dati su 120 settori del secondo disco rigido (0x81), a partire dal numero di settore specificato dal loop unsigned long integer.
Di seguito è riportata la codifica delle funzioni readabsolutesectors() e writeabsolutesectors() :
//// Funzione per leggere i settori assoluti \\\\
int readabsolutesectors ( int unità,
numero di settore lungo senza segno,
int numero di settori,
vuoto *buffer )
{
unione REGS i, o ;
costruire SREGS s ;
struct diskaddrpacket pp ;
pp.packetsize = 16 ; /* dimensione del pacchetto = 10H */
pp.reserved = 0 ; /* Riservato = 0 */
pp.blockcount = numofsectors ; /* Numero di settori
leggere */
/* per buffer dati */
pp.bufferaddress = (char far*) MK_FP ( FP_SEG((void
buffer lontano), FP_OFF((void buffer lontano));
pp.blocknumber[0] = sectornumber ; /* Numero del settore
leggere */
pp.blocknumber[1] = 0 ; /* Numero del blocco */
ihah = 0x42 ; /* Numero funzione*/
ihdl = drive ; /* Numero unità fisica */
ixsi = FP_OFF ( (void far*)&pp ) ; /* ds:si per
buffer Parametri */
s.ds = FP_SEG ( (void far*)&pp ) ; /* ds:dire per
buffer Parametri */
/* Richiama la funzione specificata di INT 13H con i valori del registro di segmento */
int86x ( 0x13, &i, &o, &s ) ;
se (oxcflag==1)
ritorna 0 ; /*fallimento */
altro
ritorna 1 ; /* successo */
}
//// Funzione per scrivere il/i settore/i assoluto/i \\\\
int writeabsolutesectors ( int unità,
numero di settore lungo senza segno,
int numero di settori,
vuoto *buffer )
{
sindacato REGS i, o ;
struttura SREGS s;
struct diskaddrpacket pp ;
dimensionepacchetto pp = 16 ; /* Dimensione pacchetto = 10H */
pp.riservato = 0 ; /* Riservato = 0 */
pp.blockcount = numofsectors ; /* Numero di settori
verrà scritto */
/* per buffer dati */
pp.bufferaddress = (char far*) MK_FP ( FP_SEG((void
buffer lontano), FP_OFF((void buffer lontano));
pp.blocknumber[0] = sectornumber ;/* Numero del settore
verrà scritto */
pp.blocknumber[1] = 0 ; /* Numero blocco = 0 */
ihah = 0x43 ; /* Numero funzione */
ihal = 0x00 ; /* Voce dei flag, vedere
commenti */
ihdl = unità ; /* Numero del disco fisico*/
/* ds:si per i parametri del buffer */
ixsi = FP_OFF ( (void far*)&pp ) ;
/* ds:si per i parametri del buffer */
s.ds = FP_SEG ( (void far*)&pp ) ;
/* Chiama la funzione INT 13H specificata con i valori del registro del segmento */
int86x ( 0x13, &i, &o, &s ) ;
se (oxcflag == 1)
restituisci 0 ; /* fallimento */
Di più
ritorno 1 ; /* successo */
}
Commenti sulla codifica:
I parametri utilizzati da entrambe le funzioni hanno i seguenti significati:
Parametro |
Dimensione in byte |
Descrizione |
dimensionepacchetto pp = 16 ; |
1 byte |
Dimensioni del pacco = 10H |
pp.riservato = 0 ; |
1 byte |
Riservato = 0 |
pp.blockcount = numofsectors ; |
2 byte |
Numero di settori da leggere |
pp.bufferaddress = (char far*) MK_FP ( FP_SEG((void far*)buffer), FP_OFF((void far*)buffer)); |
----- |
per buffer dati o buffer di trasmissione |
pp.blocknumber[0] = sector_number; |
4 byte |
Numero del settore da leggere/scrivere (solitamente ci serve solo questo). Solo separatamente. Può supportare fino a 2,1 terabyte. |
pp.block_number[1] = 0 ; |
4 byte |
Numero di blocco. Utilizzatelo se state accedendo a un disco più grande di 2,1 terabyte. |
ihah = 0x42; oppure ihah = 0x43 ; |
2 byte |
Funzione Numero di estensioni INT 13H |
ihal = 0x00 ; |
1 byte |
I flag di scrittura vengono utilizzati solo nella funzione di scrittura: 00H, 01H vengono utilizzati per la scrittura senza verifica, mentre 02H viene utilizzato per la scrittura con verifica. |
ihdl = unità ; |
2 byte |
Numero del disco fisico |
ixsi = FP_OFF ( (void far*)&pp ) ; |
------ |
ds:si per i parametri del buffer |
s.ds = FP_SEG ( (void far*)&pp ) ; |
------ |
ds:si per i parametri del buffer |
int86x ( 0x13, &i, &o, &s ) ; |
------ |
Chiama la funzione INT 13H specificata con i valori del registro del segmento |