Diskette Sektoren lesen und schreiben
-
Man braucht heute nur sehr selten Disketten. Die meisten PCs haben kein Disketten-Lw mehr. Man kann aber für etwa 10 Euro ein Disk-Lw mit USB Anschluss kaufen und das funktioniert wie ein normales Disketten-Lw.
Wenn ich in einem 32-bit Windows mein altes mit TurboPascal programmiertes Programm laufen lasse, dann funktioniert es dort immer noch wie vor 20 Jahren unter DOS. Im 64-bit Windows kann man es nicht ausführen.
Damals habe ich die Zugriffe über BIOS-Aufrufe gemacht, die ja offensichtlich auch heute in Win10-1903-32 immer noch funktionieren.
Wie müsste man das heute programmieren ?
Hier mal die Funktionen für die Disketten-Zugriffe
{ ------------------------------------------------------------------- --- Einen Sektor verifizieren --- ------------------------------------------------------------------- } Function VerifySektor(LaufwNr,SeiteNr,SpurNr, SektorNr,AnzSekt:Byte):Word; Begin Regs.AH := $04; { Sektor verifyzieren } Regs.DL := LaufwNr; { 0 = Laufwerk A: } Regs.DH := SeiteNr; { Seite 0 } Regs.CH := SpurNr; { Spur } Regs.CL := SektorNr; { Sektor } Regs.AL := AnzSekt; { Anzahl Sektoren = 1 } Intr($13,Regs); if ( ( (Regs.Flags and FCarry) = FCarry ) or (Regs.AH <> 0) ) then VerifySektor := Regs.AH else VerifySektor := 0; End; { Ende - Function VerifySektor } { ------------------------------------------------------------------- --- Einen Sektor lesen ( 512 Bytes ) --- ------------------------------------------------------------------- } Function ReadSektor(LaufwNr,SeiteNr,SpurNr,SektorNr:Byte):Word; Begin Regs.AH := $02; { Sektor lesen } Regs.DL := LaufwNr; { 0 = Laufwerk A: } Regs.DH := SeiteNr; { Seite 0 } Regs.CH := SpurNr; { Spur } Regs.CL := SektorNr; { Sektor } Regs.AL := 1; { Anzahl Sektoren = 1 } Regs.ES := Seg(SektPuff[1]); { ES:BX = Eingabe-Puffer } Regs.BX := Ofs(SektPuff[1]); Intr($13,Regs); if ( ( (Regs.Flags and FCarry) = FCarry ) or (Regs.AH <> 0) ) then ReadSektor := Regs.AH { Fehlercode } else ReadSektor := 0; { ok. } End; { Ende - Function ReadSektor } { ------------------------------------------------------------------- --- Einen Sektor ausgeben ( 512 Bytes ) --- ------------------------------------------------------------------- } Function WriteSektor(LaufwNr,SeiteNr,SpurNr,SektorNr:Byte):Word; Begin Regs.AH := $03; { Sektor schreiben } Regs.DL := LaufwNr; { 0 = Laufwerk A: } Regs.DH := SeiteNr; { Seite 0 } Regs.CH := SpurNr; { Spur } Regs.CL := SektorNr; { Sektor } Regs.AL := 1; { Anzahl Sektoren = 1 } Regs.ES := Seg(SektPuff[1]); { ES:BX = Ausgabe-Puffer } Regs.BX := Ofs(SektPuff[1]); Intr($13,Regs); if ( ( (Regs.Flags and FCarry) = FCarry ) or (Regs.AH <> 0) ) then WriteSektor := Regs.AH { Fehlercode } else WriteSektor := 0; { ok. } End; { Ende - Function WriteSektor } { ------------------------------------------------------------------- --- RESET auf Laufwerk 0=A, 1=B --- ------------------------------------------------------------------- } Function DiskReset(LaufwNr:Byte):Word; Begin Regs.AH := $00; { Reset } Regs.DL := LaufwNr; { 0 = Laufwerk A: } Intr($13,Regs); if ( ( (Regs.Flags and FCarry) = FCarry ) or (Regs.AH <> 0) ) then DiskReset := Regs.AH else DiskReset := 0; End; { Ende - Function DiskReset }
-
datei auf laufwerk a zum lesen bzw. schreiben öffnen und dann über einen ganz normalen dateizugriff. ich weiß jetzt grad nicht, wie man das mit c# macht.
und windows 10 lässt dich ernsthaft noch mit interrupts und ports auf die hardware zugreifen?
-
Benötigst du wirklich eine ".NET"-Lösung?
In der WinAPI gibt es die Funktion DeviceIoControl, s.a. Device Input and Output Control (IOCTL).Für Zugriffe aus dem .NET Framework heraus müßtest du PInvoke verwenden: DeviceIoControl (kernel32).
-
@Wade1234 sagte in Diskette Sektoren lesen und schreiben:
datei auf laufwerk a zum lesen bzw. schreiben öffnen und dann über einen ganz normalen dateizugriff
Damit bekomst du aber nicht den Bootsektor, oder direkt die FAT.
und windows 10 lässt dich ernsthaft noch mit interrupts und ports auf die hardware zugreifen?
Die Interrupts können auch von Windows abgefangen werden und Ports werden hier nicht benutzt.
-
ach so war das gemeint. also grundsätzlich kann man unter windows (als administrator!) soweit ich weiß auch mit createfile auf festplatten bzw. laufwerke an sich zugreifen. aber warum verwendet man dafür eine programmiersprache, die gar nicht dafür gedacht ist?
-
@Wade1234 Watt du nicht alles weisst wofür Dinge gedacht sind. Krass.
-
@hkdd Google mal die Stichworte
Windows open block device
DeviceIoControl
IOCTL_DISK_VERIFYEvtl. auch interessant der Code des "floppy" Driver Samples, dort siehst du welche Funktionen/IOCTLs dieser implementiert: https://github.com/microsoft/Windows-driver-samples/blob/master/storage/sfloppy/src/floppy.c
-
@hustbaer sagte in Diskette Sektoren lesen und schreiben:
@Wade1234 Watt du nicht alles weisst wofür Dinge gedacht sind. Krass.
naja warum muss man dann umständlich die windows api benutzen um auf das laufwerk zuzugreifen? oder funktioniert das doch mit c#?
-
@Wade1234 C# hat mit PInvoke ein sehr mächtiges, einfaches, praktisches Feature um WinAPI Funktionen (bzw. generell native Funktionen) aufzurufen. Macht auf mich nicht greade den Eindruckt dass C# nicht dazu gedacht wäre das dann auch zu tun.
Ob es das ideale Tool dafür ist ist wieder ne andere Frage. Das hängt dann aber auch wieder vom konkreten Fall ab. Wenn man z.B. 5 WinAPI Funktionen und 2-3 WinAPI Datenstrukturen braucht (für die man sich dann den passenden PInvoke Code suchen/schreiben muss), dafür aber 1000+ Zeilen Code schreibt wo man von anderen C# Features profitiert... wieso sollte man dann nicht C# nehmen?
-
Ein ehemaliger Benutzer 5. Juni 2019, 09:36 zuletzt editiert von Ein ehemaliger Benutzer 5. Juni 2019, 09:37
ja sicherlich. aber warum sollte man rohdaten auf eine diskette schreiben, wenn es mit der erzeugung einer datei deutlich einfacher (eine kurze recherche im internet hat 3 zeilen ergeben) geht?
und wenn man schon solche spielereien wie "bootsektor der diskette" betreiben will, dann doch vielleicht lieber die windows api oder noch besser unix mit C.
-
@Wade1234 : Warum? Ein Blockdevice ist auch nur ein dateiartiges Objekt. Mit C# kann man doch hoffentlich genauso Dateien mit beliebigem Inhalt Lesen und Schreiben wie in jeder anderen Sprache auch? Bloß weil da spukige Wörter wie "Bootsektor" in der Beschreibung des logischen(!) Dateiinhaltes vorkommen, macht das doch keinen Unterschied für den technischen Zugriff.
Ebenso für Zugriff auf die Betriebssystem-API. Bloß weil das Funktionen sind, die du nicht so oft benutzt, macht das auch nicht auf magische Weise einen Unterschied für die aufrufende Sprache. Ein Winapi-Call ist ein Winapi-Call, egal ob derIOCTL_DISK_VERIFY
oderCreateWindow
heißt.
-
Danke für Euere Antworten.
Ich habe von meinen Disketten jeweils eine IMG-Datei mit Hilfe eines Programmes, das so etwas kann, gemacht. Da werden die 2880 Sektoren nacheinander gelesen und in eine Datei geschrieben. Die kann man dann mit diesem Commander ähnlich wie eine ZIP-Datei öffnen und auf die Dateien zugreifen. Bei Bedarf kann man diese IMG-Daten wieder auf eine Diskette zurück schreiben. Das ist gerade für bootfähige Disketten wichtig. Bei Disketten, die lediglich Dateien enthalten, wäre das nicht nötig.
Wenn das mein Commander kann , aber auch andere Programme, wie HxD oder RawWriteWin.exe, dann müsste das doch auch mit einem eigenen Programm möglich sein.
-
@Th69 ,
ich habe das Beispiel aus Deinem Link ausprobiert.
https://docs.microsoft.com/de-de/windows/desktop/DevIO/calling-deviceiocontrolDarin gibt es gleich am Anfang die Anweisung
#define wszDrive L"\\\\.\\PhysicalDrive0"
Damit wird aber die erste Festplatte angesprochen.
Was muß man stattdessen benutzen, um das Disketten-Laufwerk anzusprechen.
In der Datenträgerverwaltung wird das Disketten-Laufwerk nicht gelistet, auch nicht von Diskpart bei LIST DISK
-
@SeppJ
ja da hast du wohl recht. aber bei c# würde ich dann sowas wie "blockdevicestream" oder so erwarten und kein umständliches pinvoke auf die winapi. also meiner meinung nach ist c# ein werkzeug, um bequem desktopanwendungen zu entwickeln und nicht um an der hardware herumzuspielen.@hkdd
ja mit deinem eigenen programm ist das grundsätzlich ja auch möglich. die mögliche vorgehensweise mit pinvoke und createfile wurde dir ja auch schon genannt. vielleicht hilft das noch: https://stackoverflow.com/questions/55175218/pinvoke-windowsapi-createfile-from-c-sharpps: unter unix schreibst du übrigens einfach nur "cat /dev/irgendwas > backup.img" zum sichern und "cat backup.img > /dev/irgendwas" zum wiederaufspielen in die shell.
-
@hkdd
funktioniert das diskettenlaufwerk denn überhaupt bzw. wird es im arbeitsplatz (bzw. mittlerweile heißt das ja "dieser pc") angezeigt?
-
Ich habe es einfach mal probiert und es fuktioniert.
Mit der Anweisung#define wszDrive L"\\\\.\\A:"
wird tatsächlich das Disketten-Laufwerk A: angesprochen.
Nun muss ich nur noch herausfinden, wie man der Reihe nach die Sektoren lesen und schreiben kann.Es sei angemerkt, dass das Programm in C++ codiert ist, nicht in C#. Das ist mir eigentlich egal, ich könnte es auch in Delphi schreiben, ich wollte nur wissen, wie man unter Windows 10 diese Aufgabe lösen kann.
Nochmals Dank an @Th69 für den Hinweis.
@Wade1234 ,
ja, es funktioniert einwandfrei und die genannten Programme können IMG erstellen bzw. IMGs auf Disk schreiben. Ich kann auch die Dateien der Diskette lesen. Der Explorer zeigt Laufwerk A: an.
Man kann von Diskette booten (wenn im Bios so eingestellt) usw.
-
@hkdd sagte in Diskette Sektoren lesen und schreiben:
Nun muss ich nur noch herausfinden, wie man der reihe nach die Sektoren lesen und schreiben kann.
Lesen und Schreiben geht einfach mit
ReadFile
undWriteFile
. Die Zugriffe müssen dabei halt Sector-Aligned sein - also immer nur ganze Sektoren lesen/schreiben.DeviceIoControl
brauchst du dann für Sachen wie "verify".
-
@Wade1234 sagte in Diskette Sektoren lesen und schreiben:
also meiner meinung nach ist c# ein werkzeug, um bequem desktopanwendungen zu entwickeln und nicht um an der hardware herumzuspielen.
Also jeder der Server-Anwendungen damit macht macht auch was falsch?
-
@hustbaer ,
kommen da die Sektoren in der richtigen Reihenfolge ?
Bei der BIOS-Programmierung musste man ja wissen, wie viele Sektoren pro Spur, wie viele Spuren,. und auch noch die Seite 0 und 1. Das war für 1,44 GB Disketten ein ganz bestimmtes Muster.
Ich werde es probieren. Ich habe mir extra eine Diskette eingerichtet, auf der die Sektoren mit eindeutigem Inhalt beschrieben sind.
-
kommt auf den server an würde ich sagen. aber ich muss zugeben, dass ich da jetzt nicht so die ahnung von habe, weil ich bei sowas immer direkt mit dem betriebssystem geplaudert habe.