Kapitel – 11
Erstellen von Sicherungskopien
Warum brauchen Sie Backups?
„Vorbeugen ist immer besser als Heilen.“ Die Datensicherung ist auch ein wichtiger Teil der Prävention von Datenkatastrophen und kann uns helfen, Festplattenausfälle oder andere Arten von Datenverlust zu überwinden. In diesem Kapitel besprechen wir, wie wir selbst nach schwerwiegenden Festplattenfehlern Daten wiederherstellen können, indem wir einfach zuvor erstellte Sicherungen verwenden.
Die Wiederherstellung mithilfe zuvor gespeicherter Sicherungen ist fast immer zu 100 % möglich. In einigen speziellen Fällen können jedoch unterschiedliche Arten von Festplattenfehlern zu unterschiedlichen Wiederherstellungsergebnissen führen.
Die Wiederherstellung von Daten mithilfe von Backups ist ein relativ einfacher, schneller und zuverlässiger Vorgang, der die besten Ergebnisse liefert. Die Wiederherstellung von Daten ohne Backups hingegen ist komplex, verwirrend und kann viel Zeit in Anspruch nehmen. Und selbst dann haben wir in vielen Fällen Angst, nicht 100 Prozent der Daten zurückzubekommen.
Wann und was zu reservieren ist
Es gibt verschiedene Bereiche auf der Festplatte, die einmalig oder in unterschiedlichen Abständen kopiert werden müssen. Die folgende Tabelle bietet einen Überblick über die Schritte einer vollständigen Sicherung und hilft Ihnen dabei, herauszufinden, wann und was gesichert werden soll:
Was muss reserviert werden |
Wann ist ein Backup erforderlich? |
MBR-Sicherung |
Nach FDISK. MBR wird durch den DOS-Befehl FDISK erstellt. Sie können MBR nach FDISK sichern, jedoch bleibt MBR auch nach dem FORMATIEREN der mit FDISK erstellten Partitionen unverändert. |
DBR-Sicherung |
Erstellen Sie nach dem Formatieren ein DBR-Backup für jede logische Festplatte. |
Sichern Sie FAT-Einträge und Verzeichnisse. |
FAT- und Verzeichniseinträge ändern sich jedes Mal, wenn Sie Dateien oder Verzeichnisse erstellen oder löschen. Daher wird empfohlen, täglich eine Sicherungskopie zu erstellen. |
Benutzerdaten sichern |
Sollte regelmäßig durchgeführt werden. Bei dieser Art der Sicherung wird ein Disk-Image erstellt. Dies ist zwar zeitaufwändig, aber die meisten Unternehmen, die sehr vertrauliche Daten auf ihren Laufwerken haben, investieren ihre Zeit gern in die Erstellung eines Disk-Images, da sie auf diese Weise alle oben beschriebenen Informationen sichern können. |
Darüber hinaus sollten Sie eine Notfall-Bootdiskette für das System erstellen. Sollte es zu einem Unfall mit den Daten auf Ihrer Festplatte kommen, können Sie Ihr System mit dieser Diskette booten und das Laufwerk auf Fehler analysieren.
Sichern des MBR (Master Boot Record) und seiner Verwendung
Der Master Boot Record (MBR), manchmal auch Master Partition Table (MPT) genannt, enthält ein kleines Programm zum Laden und Ausführen der aktiven (oder bootfähigen) Partition von der Festplatte. Der Master Boot Record enthält Informationen zu allen vier primären Partitionen.
Eine ausführliche Erläuterung von MBR finden Sie im Kapitel „Ein logischer Ansatz für Festplatten und Betriebssysteme“, das weiter oben in diesem Buch besprochen wurde.
MBR befindet sich im absoluten Sektor 0 oder anders ausgedrückt im Zylinder 0, Kopf 0 und Sektor 1. Er wird auf der Festplatte durch Ausführen des DOS-Befehls FDISK.EXE erstellt.
Warum eine Sicherung des MBR erstellen:
MBR ermöglicht dem Bootsektor der aktiven Partition, beim Systemstart die Kontrolle zu übernehmen.
Nach dem Power-On Self-Test (POST) lädt das BIOS den MBR (Master Boot Record) von der Festplatte in den Arbeitsspeicher und führt ihn anschließend aus. Zuerst sucht der MBR auf der Festplatte nach einer aktiven Partition, lädt dann den DOS-Bootdatensatz (DBR) in den Speicher und übergibt die Kontrolle an den Bootcode des Betriebssystems. Anschließend lädt der Bootdatensatzcode des Betriebssystems den Rest des Betriebssystems in den Speicher.
Daher können wir sagen, dass die Festplatte praktisch tot ist, wenn der MBR der Festplatte beschädigt ist, und das System überhaupt nicht mehr in der Lage ist, zu booten oder das Betriebssystem auszuführen. In diesem Zustand sind alle auf der Festplatte gespeicherten Daten unzugänglich. Typischerweise werden Fehlermeldungen wie folgt angezeigt:
„Ungültige Partitionstabelle“ „Fehler beim Laden des Betriebssystems“ „Fehlendes Betriebssystem“
Was kann mit einem MBR-Backup wiederhergestellt werden?
Durch die Sicherung des MBR können Sie die oben genannten Fehlermeldungen vermeiden. Mithilfe einer Datensicherung können Sie die folgenden Probleme beheben:
- Fehler beim Laden des Betriebssystems aufgrund eines beschädigten IPL (Initial Program Loader)
- Verlorene primäre Partition(en)
- Beschädigte Partitionsinformationen
- Falsche magische Zahl
Schreiben eines Programms zum Erstellen eines MBR-Backups:
/* Programm zum Erstellen einer MBR-Sicherung */
#include <bios.h>
#include <stdio.h>
int Haupt(void)
{
Struktur diskinfo_t dinfo; /* Struktur für die Speicherung
Informationen zu Festplattenparametern */
Ergebnis int;
Anzahl der Ganzzahlen=0;
char Dateiname[80]; /* Speichert den angegebenen Dateinamen
Benutzer */
static char dbuf[512]; /* Datenpuffer von 512 Bytes */
DATEI *fp;
dinfo.drive = 0x80; /* Laufwerksnummer für die erste Festplatte
Datenträger */
dinfo.head = 0; /* Festplattenkopfnummer */
dinfo.track = 0; /* Titelnummer */
dinfo.sector = 1; /* Sektornummer */
dinfo.nsectors = 1; /* Sektorenanzahl */
dinfo.buffer = dbuf; /* Datenpuffer */
printf("\n Geben Sie den Dateinamen und den Pfad zum Speichern der
Sicherung des MBR \n ");
bekommt(Dateiname);
//Öffnen Sie die Datei zum Speichern des MBR-Backups \\
wenn((fp=fopen(Dateiname,"wb"))==NULL)
{
printf("Datei konnte nicht erstellt werden. Drücken Sie eine beliebige Taste, um
Ausfahrt...");
getch();
Ausfahrt (0);
}
printf("Versuch, vom Festplattenlaufwerk :\n zu lesen");
//// Den angegebenen Festplattensektor lesen \\\\
Ergebnis = _bios_disk(_DISK_READ, &dinfo);
wenn ((Ergebnis & 0xff00) == 0)
{
printf("Disk-Lesevorgang von der Festplatte:
erfolgreich.\n");
/// 512 Bytes MBR in die Datei schreiben \\\\
während(Anzahl<512)
{
fprintf(fp,"%c",dbuf[Anzahl] & 0xff );
zählen++;
}
fschließen(fp);
}
anders
printf("Festplattenlaufwerk kann nicht gelesen werden, Status = 0x%02x\n", Ergebnis);
gebe 0 zurück;
}
Kommentare zur Programmcodierung:
In der zuvor angegebenen Programmcodierung führen wir grundsätzlich die folgenden Aufgaben Schritt für Schritt aus:
- dinfo verweist auf die Struktur diskinfo_t, die die Informationen zu den Parametern enthält, die für den von der Funktion _bios_disk ausgeführten Vorgang erforderlich sind.
- Da wir den ersten Sektor der Festplatte lesen möchten, ist die Position des Sektors wie folgt:
Parameter |
Was es bedeutet |
dinfo.drive = 0x80 |
Es zeigt das physische Laufwerk 80H an , das das erste Festplattenlaufwerk ist. |
dinfo.head = 0 |
Es zeigt auf Kopf Nummer 0 |
dinfo.track = 0 |
Es zeigt auf Spur 0 |
dinfo.sektor = 1 |
Erster Sektor der Diskette, also Sektor 1 |
dinfo.sektor = 1 |
>Anzahl der für den Lesevorgang zu berücksichtigenden Sektoren = 1 |
dinfo.buffer = dbuf |
Datenpuffer für die Operation |
- Öffnen Sie einen Dateistream mit dem vom Benutzer angegebenen Dateinamen und Pfad, um die MBR-Sicherung mit genau 512 Bytes zu speichern. Der Dateiname und der Pfad werden im Zeichenarray „Dateiname“ gespeichert.
- _bios_disk(_DISK_READ, &dinfo) liest den ersten Sektor der Festplatte (80H), angegeben durch dinfo.
- Der zurückgegebene Status wird im Ergebnis gespeichert und dient dazu, die Meldung für den erfolgreichen Vorgang anzuzeigen oder, falls ein Fehler auftritt, eine Fehlermeldung auf dem Bildschirm anzuzeigen.
Programm zum Wiederherstellen des MBR aus einem Backup:
Wenn der MBR auf irgendeine Weise beschädigt ist, hilft das folgende Programm dabei, den MBR wiederherzustellen.
Man sollte immer bedenken, dass die illegale oder unwissende Verwendung dieses Programms Ihre Daten auf der Festplatte zerstören und alle Daten unzugänglich machen kann. Sie sollten sich sicher sein, was Sie tun werden. Andernfalls könnten Sie das Problem noch verkomplizieren.
Programm zum Wiederherstellen des MBR aus einem Backup:
Die Codierung des Programms ist wie folgt:
/* Programm zum Wiederherstellen der MBR-Sicherung aus der Sicherungsdatei */
#include <bios.h>
#include <stdio.h>
int Haupt(void)
{
Struktur diskinfo_t dinfo;
int Ergebnis;
int-Anzahl=0;
char filename[80]; /* Speichert den angegebenen Dateinamen
von Benutzer */
static char dbuf[512]; /* Datenpuffer von 512 Bytes
*/
DATEI *fp;
/* Benutzereingabe für MBR-Sicherungsdateipfad abrufen */
printf("\n Geben Sie den Dateinamen und den Pfad der Sicherungsdatei ein von
MBR \n ");
bekommt(Dateiname);
wenn((fp=fopen(Dateiname,"rb"))==NULL)
{
printf("Sicherungsdatei konnte nicht geöffnet werden. Drücken Sie eine beliebige Taste.
zum Beenden ...");
getch();
Ausgang (1);
}
/* MBR-Daten sollten genau 512 Bytes groß sein */
während(Anzahl<512)
{
fscanf(fp,"%c",&dbuf[Anzahl]);
zählen++;
}
fschließen(fp);
printf("Versuch, auf das Festplattenlaufwerk :\n zu schreiben");
dinfo.drive = 0x80; /* Laufwerksnummer für First
Festplatte */
dinfo.head = 0; /* Festplattenkopfnummer */
dinfo.track = 0; /* Titelnummer */
dinfo.sector = 1; /* Sektornummer */
dinfo.nsectors = 1; /* Sektorenanzahl */
dinfo.buffer = dbuf; /* Datenpuffer */
Ergebnis = _bios_disk(_DISK_WRITE, &dinfo);
wenn ((Ergebnis & 0xff00) == 0)
{
printf("Wiederherstellen der Sicherung des MBR auf der Festplatte
Sektor: erfolgreich.\n");
}
anders
printf("Kann nicht auf Festplatte schreiben, Status =
0x%02x\n", Ergebnis);
gebe 0 zurück;
}
Kommentare zur Programmcodierung:
In der oben angegebenen Programmcodierung führen wir grundsätzlich die folgenden Aufgaben Schritt für Schritt aus:
- dinfo verweist auf die Struktur diskinfo_t, die die Informationen zu den Parametern enthält, die für den von der Funktion _bios_disk ausgeführten Vorgang erforderlich sind.
- Da wir auf den ersten Sektor der Festplatte schreiben möchten, ist die Position des Sektors wie folgt:
Parameter |
Was es bedeutet |
dinfo.drive = 0x80 |
Es zeigt das physische Laufwerk 80H an , das das erste Festplattenlaufwerk ist. |
dinfo.head = 0 |
Es zeigt auf Kopf Nummer 0 |
dinfo.track = 0 |
Es zeigt auf Spur 0 |
dinfo.sektor = 1 |
Erster Sektor der Diskette, also Sektor 1 |
dinfo.sektor = 1 |
Anzahl der für den Lesevorgang zu berücksichtigenden Sektoren = 1 |
dinfo.buffer = dbuf |
Datenpuffer für die Operation |
- Der vom Benutzer angegebene Dateiname und Pfad der MBR-Sicherung wird im Zeichenarray „Dateiname“ gespeichert. Es ist zu beachten, dass die MBR-Informationen genau 512 Bytes lang sein sollten.
- _bios_disk(_DISK_WRITE, &dinfo) schreibt die Daten in den ersten Sektor der Festplatte (80H), angegeben durch dinfo.
- Der zurückgegebene Status wird im Ergebnis gespeichert und dient dazu, die Meldung für den erfolgreichen Vorgang anzuzeigen oder, falls ein Fehler auftritt, eine Fehlermeldung auf dem Bildschirm anzuzeigen.
Sicherung des DBR (DOS Boot Record) und dessen Verwendung
Nach der Partitionstabelle ist der DOS Boot Record (DBR) oder manchmal auch DOS-Bootsektor genannt, die zweitwichtigste Information auf Ihrer Festplatte.
Eine detaillierte Studie zu DBR finden Sie im Kapitel „ Logischer Ansatz für Festplatten und Betriebssysteme “, das weiter oben in diesem Buch besprochen wird.
Der erste logische Sektor jeder DOS-Partition enthält einen DOS Boot Record (DBR) oder DOS-Bootsektor. Die Aufgabe des DBR besteht darin, das Betriebssystem von der Festplatte in den Hauptspeicher des Computers zu laden und dem geladenen Programm die Systemsteuerung zu übertragen.
Der DOS-Boot-Record (DBR) für die erste Partition auf einer Festplatte befindet sich normalerweise im absoluten Sektor 63 (dem 64. Sektor auf dem Festplattenlaufwerk) oder in CHS-Form, d. h. für die meisten Laufwerke können wir sagen, C–H–S = 0–1–1.
Dieser Speicherort kann jedoch je nach SPT (Sektoren pro Spur) des Laufwerks variieren. Beispielsweise befand sich der Boot-Record auf einem alten 245-MB-Laufwerk mit nur 31 SPT im 32. Sektor (Absoluter Sektor 31).
Der DBR wird mit dem FORMAT-Befehl von DOS erstellt, nachdem die Partitionierung mit dem FDISK-Befehl abgeschlossen wurde. Der Sektor, auf dem sich der DBR befindet, wird für DOS zum logischen Sektor 1 dieser bestimmten Partition. Die von DOS verwendete Sektornummer beginnt mit dem physischen Sektor, auf dem sich der DBR befindet.
Der DBR enthält ein kleines Programm, das vom ausführbaren Programm Master Boot Record (MBR) ausgeführt wird. Alle DOS-Partitionen enthalten den Programmcode zum Booten der Maschine, d. h. zum Laden des Betriebssystems, aber nur die Partition erhält die Kontrolle vom Master Boot Record, die im Partitionstabelleneintrag als aktive Partition angegeben ist.
Warum DBR sichern:
Der DBR enthält einige wichtige Informationen zur Festplattengeometrie. Diese Informationen befinden sich im ersten Sektor jeder Partition, beispielsweise:
- Sprungcode + NOP
- OEM-Name und Version
- Bytes pro Sektor
- Sektoren pro Cluster
- Reservierte Sektoren
- Anzahl der FAT-Kopien
- Maximale Anzahl an Stammverzeichniseinträgen (aber nicht verfügbar für FAT32)
- Anzahl der Sektoren in der Partition kleiner als 32 MB (daher nicht für FAT32 verfügbar)
- Mediendeskriptor (F8H für Festplatten)
- Sektoren pro FAT (in älteren FAT-Systemen und nicht verfügbar für FAT32)
- Sektoren pro Spur
- Anzahl der Köpfe
- Anzahl der versteckten Sektoren in der Partition
- Anzahl der Sektoren in der Partition
- Anzahl der Sektoren pro FAT
- FAT-Informationsdeskriptor-Flags
- Version des FAT32-Laufwerks
- Clusternummer des Anfangs des Stammverzeichnisses
- Sektornummer des Dateisystem-Informationssektors
- Sektornummer des Backup-Bootsektors
- Reserviert
- Logische Laufwerksnummer der Partition
- Erweiterte Signatur (29H)
- Seriennummer der Partition
- Volumename der Partition
- FAT-Name
- Ausführbarer Code
- Ausführbarer Marker oder magische Zahl (AAH 55H)
Im Allgemeinen werden folgende Fehlermeldungen auf dem Bildschirm angezeigt:
„Fehler beim Booten der Festplatte“
„Keine Systemfestplatte oder Festplattenfehler“
„Ungültiger Systemdatenträger oder Datenträger-E/A-Fehler“
„Legen Sie die Diskette ein und drücken Sie dann eine beliebige Taste …“
Was kann mit dem Backup von DBR wiederhergestellt werden?
Die Sicherung von DBR kann Ihnen helfen, die oben genannten Fehlermeldungen zu beseitigen. Diese Fehlermeldungen werden auf dem Bildschirm angezeigt, wenn der Benutzer eine bootfähige Diskette mit den oben genannten Programmen in das Diskettenlaufwerk einlegt und eine Taste drückt.
Das Laufwerk sollte zugänglich sein, wenn Sie das System von der bootfähigen Diskette oder CD booten. Obwohl die Festplatte nicht bootfähig ist, sollte dies im Allgemeinen den Zugriff auf die Daten des Laufwerks nicht beeinträchtigen. Nachdem Sie das System mit der bootfähigen Diskette gebootet haben, können Sie auf die Daten zugreifen.
Durch die Wiederherstellung der DBR-Sicherung können Sie die oben genannten aufgetretenen Probleme beheben.
Programme zum Erstellen und Wiederherstellen von DBR-Backups:
Die Programme zum Erstellen und Wiederherstellen von DBR-Backups ähneln stark den Programmen zum Sichern und Wiederherstellen von MBRs.
Wenn Sie beispielsweise Programme zum Erstellen einer Sicherungskopie des DBR des ersten logischen Laufwerks der Festplatte und zu dessen Wiederherstellung schreiben möchten, werden die von der Dinfo-Struktur angegebenen Parameter wie folgt geändert:
Parameter |
Was es bedeutet |
dinfo.drive = 0x80 |
Es zeigt das physische Laufwerk 80H an , das das erste Festplattenlaufwerk ist> |
dinfo.head = 1 |
Es zeigt auf Kopf Nummer 1 |
dinfo.track = 0 |
Es zeigt auf Spur 0 |
dinfo.sektor = 1 |
Erster Sektor der Diskette, also Sektor 1 |
dinfo.sektor = 1 |
Anzahl der für den Lesevorgang zu berücksichtigenden Sektoren = 1 |
dinfo.buffer = dbuf |
Datenpuffer für die Operation |
Hier sehen wir, dass nur der Speicherort des zu lesenden/schreibenden Sektors geändert wird. Hier wird der CHS als 0-1-1 angegeben, da hier der DBR des ersten logischen Laufwerks gespeichert ist.
Vollständige Disk-Imaging
Diese Art der Datensicherung wird heutzutage immer beliebter und wird vor allem von Organisationen bevorzugt, die sehr sensible Daten in ihren Systemen haben. Diese Leute können nicht einmal ein Prozent Datenverlust riskieren.
Solche Organisationen erstellen regelmäßig Backups als vollständige Disk-Images. Das nimmt zwar etwas Zeit in Anspruch, gibt Ihnen aber die Sicherheit, dass Sie nichts verpassen. Aufgrund der zunehmenden Popularität haben Programmierer ihr Bestes getan, um die Disk-Imaging-Software immer schneller zu machen, um den Zeitaufwand für den Imaging-Prozess zu minimieren.
Die Erstellung eines Disk-Imaging ist eine gute Idee, denn Sie können sich in nur wenigen Minuten darauf verlassen, dass Sie ein Backup von allem in Ihrer Tasche haben. Alle Faktoren wie MBR, BDR, FATs und Stammverzeichnisse werden unverändert auf die Zielfestplatte kopiert.
Was wir für die Disk-Imaging-Erstellung benötigen, ist eine identische (oder fast identische) Zielfestplatte wie unsere Quellfestplatte, auf der sich unsere wertvollen Daten befinden. Dabei ist immer zu beachten, dass die Zielfestplatte nicht kleiner sein darf als die Quellfestplatte.
Wenn Sie nach der Erstellung des vollständigen Images das System mit der Zielfestplatte booten, auf der Sie das Disk-Image erstellt haben, erhalten Sie im Allgemeinen alle Daten unverändert.
Schreiben des Programms für die vollständige Datenträgerabbildung
Als nächstes folgt das Programm zur Datenträgerabbildung. Das Programm verwendet die INT 13H-Erweiterungen und kann daher auch große Datenträger unterstützen.
Das Programm erstellt ein Image der ersten physischen Festplatte (0x80) auf der zweiten physischen Festplatte (0x81). Bevor Sie das Backup-Image erstellen, sollten Sie daher bedenken, dass alle Daten auf der Zielfestplatte (0x81) Sektor für Sektor durch die Daten der Quellfestplatte (0x80) überschrieben werden.
Die Codierung des Programms ist wie folgt:
/* Programm zum Erstellen eines Images der ersten Festplatte (0x80) auf der zweiten Festplatte (0x81) */
#include<stdio.h>
#include<dos.h>
#include<conio.h>
/* Von der Funktion getdrivegeometry zu verwendende Struktur unter Verwendung der Erweiterung INT 13H, Funktionsnummer 0x48. */
Strukturgeometrie
{
unsigned int size ; /* (Aufruf) Größe des Puffers */
unsigned int flags ; /* Informationsflags */
unsigned long cyl ; /* Anzahl der physikalischen
Zylinder auf Antrieb */
unsigned long heads ;/* Anzahl der physischen
Köpfe auf Laufwerk */
unsigned long spt ; /* Anzahl der physischen
Sektoren pro Spur */
unsigned long sectores[2] ; /* Gesamtzahl der
Sektoren auf Laufwerk */
unsigned int bps; /* Bytes pro Sektor */
} ;
/* Struktur des Disk-Adresspaketformats, zu verwenden von den Funktionen readabsolutesectors und writeabsolutesectors */
Struktur Diskaddrpacket
{
char packetsize ; /* Größe des Pakets, normalerweise 10H */
char reserviert; /* Reserviert (0) */
int blockcount ; /* Anzahl der zu übertragenden Blöcke */
char far *bufferaddress ; /* zu übertragende Adresse
Puffer */
unsigned long blocknumber[2] ; /* Startabsoluter Wert
Blocknummer */
} ;
///// Funktion zum Abrufen der Antriebsparameter \\\\\
unsigned long getdrivegeometry (int-Laufwerk)
{
Gewerkschaftsreglemente i, o;
Struktur SREGS s;
Strukturgeometrie g = { 26, 0, 0, 0, 0, 0, 0, 0 } ;
ihah = 0x48; /* Funktion Nummer 0x48 von INT 13H
Erweiterungen Siehe die Kommentare
Unten */
ihdl = Laufwerk; /* Laufwerksnummer */
ixsi = FP_OFF ( (void far*)&g ) ;
s.ds = FP_SEG ( (void far*)&g ) ;
/* Rufen Sie die angegebene Funktionsnummer der INT 13H-Erweiterung mit Segmentregisterwerten auf */
int86x (0x13, &i, &o, &s);
printf("\n Kopf = %lu, Sektoren pro Spur = %lu, Zylinder =
%lu\n", g.heads, g.spt, g.cyl);
/* Wenn die Funktion „Laufwerksgeometrie abrufen“ fehlschlägt, Fehlermeldung anzeigen und beenden */
wenn(g.spt==0)
{
printf("\n Die Funktion „Laufwerksgeometrie abrufen“ schlägt fehl …");
printf("\n Erweiterungen werden nicht unterstützt, drücken Sie eine beliebige Taste, um
Ausfahrt...");
getch();
Ausgang (1);
}
return *g.sectors; /* Gibt die Anzahl der Sektoren zurück
auf Laufwerk */
}
////// Beginn des Hauptteils \\\\\\
void main()
{
vorzeichenlose lange Schleife=0, Sektoren_auf_Festplatte1=0, Sektoren_auf_Festplatte2=0;
unsigned char buffer[61440]; /* Datenpuffer von 61440
Bytes zum Lesen/Schreiben von 120 Sektoren mit jeweils 512 Bytes auf einmal, um Zeit zu sparen. */
Zeichenauswahl;
clrscr();
/* Wenn die Gesamtzahl der angeschlossenen Festplatten weniger als zwei beträgt, wird eine Fehlermeldung angezeigt und das Programm wird beendet. */
wenn(((char)peekb(0x0040, 0x0075))<2)
{
printf("\n\n Sie müssen mindestens zwei Festplatten haben
Zum Ausführen an Ihren Computer angeschlossen");
printf("\n Programm. Drücken Sie eine beliebige Taste zum Beenden... ");
getch();
Ausgang (1);
}
/// Parameter der ersten Festplatte abrufen (0x80) \\\
Sektoren_auf_HDD1 = getdrivegeometry (0x80);
printf("Gesamtzahl der Sektoren auf der ersten Festplatte = %lu\n\n",
Sektoren_auf_HDD1);
/// Parameter der zweiten HSrd-Festplatte abrufen (0x81) \\\
Sektoren_auf_HDD2 = getdrivegeometry (0x81);
printf("Gesamtzahl der Sektoren auf der zweiten Festplatte = %lu\n\n",
Sektoren_auf_HDD2);
/// Erst bestätigen, dann fortfahren \\\
printf("\n Alle Daten auf der zweiten Festplatte werden
verloren !!!");
printf("\n Drücken Sie \'Y\' um fortzufahren, sonst eine beliebige Taste um
Ausfahrt... ");
Wahl = getche();
Schalter (Auswahl)
{
Fall 'y':
Fall 'Y':
brechen;
Standard:
Ausfahrt (0);
}
/* Das Ziel darf nicht kleiner sein als die Quelle */
wenn(Sektoren_auf_Festplatte2<Sektoren_auf_Festplatte1)
{
printf("\n\n Zielfestplatte sollte nicht kleiner sein
als Quelldiskette");
printf("\n Zum Beenden eine beliebige Taste drücken...");
getch();
Ausfahrt (0);
}
/* Wenn alles in Ordnung ist, kopieren Sie alle Sektoren der Quellfestplatte auf die Zielfestplatte */
gotoxy(10,15);printf("Absoluter Sektor kopieren: ");
für (Schleife = 0; Schleife < = Sektoren auf Festplatte1; Schleife = Schleife + 120)
{
readabsolutesectors (0x80, Schleife, 120, Puffer);
writeabsolutesectors (0x81, Schleife, 120, Puffer);
gotoxy(36,15); printf("%ld",Schleife);
wenn(kbhit())
{
Ausfahrt (0);
}
}
//// Meldung über den Abschluss anzeigen \\\
printf("\n\n Die Datenträgerabbildung ist nun abgeschlossen. Drücken Sie eine beliebige Taste.
Zum Beenden...");
getch();
}
//// Ende des Hauptteils
Kommentare zur Kodierung:
Bei der Codierung des zuvor angegebenen Programms zur Datenträgerabbildung führen wir die folgenden Aufgaben aus:
- Die Strukturgeometrie wird von der Funktion getdrivegeometry unter Verwendung der Erweiterung INT 13H, Funktionsnummer 0x48, verwendet. Eine detaillierte Beschreibung der Erweiterungen INT 13H finden Sie im Kapitel „Umgang mit großen Festplatten“, das weiter oben in diesem Buch besprochen wurde.
Die Datentypen, die verschiedene Parameter der Festplatte darstellen, haben folgende Bedeutung:
Datentyp |
Größe in Bytes |
Beschreibung |
vorzeichenlose int- Größe |
2 Bytes |
Größe des Puffers |
vorzeichenlose int -Flags |
2 Bytes |
Informationsflaggen |
unsignierter langer Zyl. |
4 Bytes |
Anzahl der physischen Zylinder auf dem Laufwerk |
unsignierte lange Köpfe |
4 Bytes |
Anzahl der physischen Köpfe auf dem Laufwerk |
vorzeichenloses langes spt |
4 Bytes |
Anzahl der physischen Sektoren pro Spur |
unsignierte lange Sektoren[2] |
8 Bytes |
Gesamtzahl der Sektoren auf dem Laufwerk |
vorzeichenlose Ganzzahl bps |
2 Bytes |
Bytes pro Sektor |
- Die Struktur diskaddrpacket wird von den Funktionen readabsolutesectors und writeabsolutesectors verwendet. Das Format des Disk-Adresspakets ist in der folgenden Tabelle angegeben:
Datentyp |
Größe in Bytes |
Beschreibung |
char Paketgröße |
1 Byte |
Paketgröße, im Allgemeinen 10H |
char reserviert |
1 Byte |
Reserviert (0) |
int Blockanzahl |
2 Bytes |
Anzahl der zu übertragenden Blöcke |
char far *Pufferadresse |
4 Bytes |
Adresse zum Transferpuffer |
vorzeichenlose lange Blocknummer[2] |
4 Bytes |
Absolute Anfangssatznummer |
- Die Funktion getdrivegeometry wird verwendet, um die Parameter des angegebenen Laufwerks abzurufen. Die Funktion getdrivegeometry verwendet die Funktionsnummer 0x48 von INT 13H Extensions.
Die Bedeutung der Parameter wird in der folgenden Tabelle beschrieben:
Parameter |
Was es bedeutet |
ihah = 0x48 |
Funktion Nummer 0x48 von INT 13H Erweiterungen |
ihdl = Antrieb |
Laufwerknummer |
ixsi = FP_OFF ( (void weit*)&g ) |
ds:si Adresse zum Puffern der Laufwerksparameter, wie bereits besprochen |
s.ds = FP_SEG ( (void far*)&g ) |
ds:si Adresse zum Puffern der Laufwerksparameter, wie bereits besprochen |
Die Funktion int86x(0x13, &i, &o, &s) ruft den Interrupt 13H mit Segmentregisterwerten auf. Die Funktion getdrivegeometry gibt die Gesamtzahl auf dem Laufwerk zurück.
- In der Funktion main() gibt (char)peekb(0x0040, 0x0075); (die Funktion peekb ist in DOS.H definiert) die Anzahl der an das System angeschlossenen Festplatten zurück.
Die Anzahl der an das System angeschlossenen Festplatten wird durch das Byte dargestellt, das am Speicherplatz 0040H:0075H gespeichert ist (Segment 0040H: Offset 0075H). Wenn die Anzahl der an das System angeschlossenen Festplatten kleiner als zwei ist, zeigt das Programm die Fehlermeldung an und wird beendet.
Sectors_in_HDD1 = getdrivegeometry (0x80); ruft die Parameter der ersten Festplatte (0x80) ab und gibt die Gesamtzahl der Sektoren auf der ersten Festplatte zurück.
Ähnlich verhält es sich mit Sectors_in_HDD2 = getdrivegeometry (0x81); es ruft die Parameter der zweiten Festplatte ab (0x81) und gibt die Gesamtzahl der Sektoren auf der zweiten Festplatte zurück.
Nachdem der Benutzer bestätigt hat, dass mit der Imageerstellung fortgefahren werden soll, überprüfen Sie zunächst, dass die Größe der Quellfestplatte nicht größer sein darf als die Größe der Zielfestplatte. Wenn die Zielfestplatte kleiner ist, zeigen Sie die Fehlermeldung an und beenden Sie das Programm.
Wenn alles richtig läuft, kopieren Sie die Sektoren der Quellfestplatte auf die Zielfestplatte. Hier lesen und schreiben wir 61440 Bytes (120 Sektoren mit jeweils 512 Bytes) gleichzeitig, um den Imaging-Prozess zu beschleunigen.
Wenn Sie mehrere Sektoren gleichzeitig verwenden möchten, sogar über die Grenze von 64 KB hinaus, können Sie dies tun, indem Sie in einem großen Speichermodell einen „großen Zeiger“ verwenden. Das Spezifikationsbeispiel lautet wie folgt:
char riesiges Array[100000L];
- Die Funktion readabsolutesectors (0x80, Schleife, 120, Puffer); liest die 120 Sektoren der ersten Festplatte (0x80), beginnend mit der durch die vorzeichenlose lange Integer-Schleife angegebenen Sektornummer, und speichert die Daten im Datenpuffer.
- Die Funktion writeabsolutesectors (0x81, Schleife, 120, Puffer); schreibt die Daten des Datenpuffers in 120 Sektoren der zweiten Festplatte (0x81), beginnend mit der durch die vorzeichenlose lange Integer-Schleife angegebenen Sektornummer.
Die Kodierung der Funktionen readabsolutesectors ( ) und writeabsolutesectors ( ) ist wie folgt:
//// Funktion zum Lesen absoluter Sektoren \\\\
int readabsolutesectors (int Laufwerk,
vorzeichenlose lange Sektornummer,
int AnzahlSektoren,
void *Puffer )
{
Gewerkschaftsreglemente i, o;
Struktur SREGS s;
Struktur Diskaddrpacket pp;
pp.packetsize = 16; /* Paketgröße = 10H */
pp.reserved = 0 ; /* Reserviert = 0 */
pp.blockcount = numofsectors; /* Anzahl der Sektoren
lesen */
/* für Datenpuffer */
pp.bufferaddress = (char far*) MK_FP ( FP_SEG((void
weit*)Puffer), FP_OFF((void weit*)Puffer));
pp.blocknumber[0] = sectornumber ; /* Sektornummer
lesen */
pp.blocknumber[1] = 0 ; /* Blocknummer */
ihah = 0x42; /* Funktionsnummer*/
ihdl = Laufwerk; /* Physische Laufwerksnummer */
ixsi = FP_OFF ( (void far*)&pp ) ; /* ds:si für
Pufferparameter */
s.ds = FP_SEG ( (void far*)&pp ) ; /* ds:say für
Pufferparameter */
/* Rufe die angegebene Funktion von INT 13H mit Segmentregisterwerten auf */
int86x (0x13, &i, &o, &s);
wenn (oxcflag==1)
return 0; /*Fehler */
anders
return 1; /* Erfolg */
}
//// Funktion zum Schreiben absoluter Sektoren \\\\
int writeabsolutesectors ( int Laufwerk,
vorzeichenlose lange Sektornummer,
int AnzahlSektoren,
void *Puffer )
{
Gewerkschaftsregister i, o;
Struktur SREGS s;
Struktur Diskaddrpacket pp;
pp.Paketgröße = 16; /* Paketgröße = 10H */
pp.reserviert = 0; /* Reserviert = 0 */
pp.blockcount = AnzahlSektoren; /* Anzahl der Sektoren
wird geschrieben */
/* für Datenpuffer */
pp.bufferaddress = (char far*) MK_FP ( FP_SEG((void
weit*)Puffer), FP_OFF((void weit*)Puffer));
pp.blocknumber[0] = sectornumber ;/* Sektornummer
wird geschrieben */
pp.blocknummer[1] = 0; /* Blocknummer = 0 */
ihah = 0x43; /* Funktionsnummer */
ihal = 0x00; /* Flags-Eintrag, siehe
Kommentare */
ihdl = Laufwerk; /* Physische Datenträgernummer*/
/* ds:si für Pufferparameter */
ixsi = FP_OFF ( (void weit*)&pp ) ;
/* ds:si für Pufferparameter */
s.ds = FP_SEG ( (void far*)&pp ) ;
/* Rufen Sie die angegebene INT 13H-Funktion mit den Segmentregisterwerten auf */
int86x (0x13, &i, &o, &s);
wenn (oxcflag == 1)
Rückgabe 0; /* Versagen */
mehr
Rückgabe 1; /* Erfolg */
}
Kodierungskommentare:
Die von beiden Funktionen verwendeten Parameter haben folgende Bedeutung:
Parameter |
Größe in Bytes |
Beschreibung |
pp.Paketgröße = 16; |
1 Byte |
Packungsgröße = 10H |
pp.reserviert = 0; |
1 Byte |
Reserviert = 0 |
pp.blockcount = AnzahlSektoren; |
2 Byte |
Anzahl der zu lesenden Sektoren |
pp.bufferaddress = (char far*) MK_FP ( FP_SEG((void far*)buffer), FP_OFF((void far*)buffer)); |
----- |
für Datenpuffer oder Sendepuffer |
pp.blocknumber[0] = Sektornummer; |
4 Byte |
Zu lesende/schreibende Sektornummer (normalerweise benötigen wir nur diese). Nur einzeln. Kann bis zu 2,1 Terabyte unterstützen. |
pp.block_nummer[1] = 0; |
4 Byte |
Nummer des Blocks. Verwenden Sie es, wenn Sie auf eine Festplatte zugreifen, die größer als 2,1 Terabyte ist. |
ihah = 0x42; oder ihah = 0x43; |
2 Byte |
Funktion Anzahl Nebenstellen INT 13H |
ihal = 0x00 ; |
1 Byte |
Schreibflags werden nur in der Schreibfunktion verwendet, 00H, 01H werden zum Schreiben ohne Überprüfung und 02H zum Schreiben mit Überprüfung verwendet. |
ihdl = Laufwerk; |
2 Byte |
Physische Datenträgernummer |
ixsi = FP_OFF ( (void weit*)&pp ) ; |
------ |
ds:si für Pufferparameter |
s.ds = FP_SEG ( (void far*)&pp ) ; |
------ |
ds:si für Pufferparameter |
int86x (0x13, &i, &o, &s); |
------ |
Rufen Sie die angegebene INT 13H-Funktion mit den Segmentregisterwerten auf |