Diskette Sektoren lesen und schreiben



  • @hkdd Google mal die Stichworte

    Windows open block device
    DeviceIoControl
    IOCTL_DISK_VERIFY

    Evtl. 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?



  • 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.


  • Mod

    @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 der IOCTL_DISK_VERIFY oder CreateWindow 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-deviceiocontrol

    Darin 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-sharp

    ps: 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 und WriteFile. 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.



  • @hkdd Ich vermute das sollte gehen. Also vorausgesetzt die Diskette ist im Standard PC Format formatiert.



  • @hustbaer und @alle,
    nun habe ich mit etwas googeln eine ziemlich einfache Lösung gefunden, und auch mit C# realisiert. Das Programm kann derzeit nur die komplette 1,44 MB Diskette in ein Byte-Array einlesen. Da müssen noch Fehlerbehandlungen usw. ergänzt werden. Dieses Array kann als IMG-Datei ausgegeben werden. Und das Kopieren einer derartigen IMG-Datei auf eine Diskette fehlt ebenfalls noch. Mir ging es in erster Linie um den Zugriff auf die physischen Sektoren.
    Ob das auch für Festplatten, DVDs, USB-Sticks usw. geht, habe ich noch nicht probiert.
    Es ist ein Desktop-Programm mit nur einer Button "Diskette A: lesen"

    using System;
    using System.IO;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;
    
    namespace DisketteImg
    {
        public partial class Form1 : Form
        {
            [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
            public static extern IntPtr CreateFile(
                 string fileName,
                 [MarshalAs(UnmanagedType.U4)] FileAccess fileAccess,
                 [MarshalAs(UnmanagedType.U4)] FileShare fileShare,
                 IntPtr securityAttributes,
                 [MarshalAs(UnmanagedType.U4)] FileMode creationDisposition,
                 int flags,
                 IntPtr template);
    
            public byte[] DiskSektoren = new byte[2880*512]; // Eine 1,44MB Disk hat 2880 Sektoren a 512 Bytes
    
            public Form1()
            {
                InitializeComponent();
            }
    
            private void BuDisketteLesen_Click(object sender, EventArgs e)
            {
                string fileName = @"\\.\A:";
                Microsoft.Win32.SafeHandles.SafeFileHandle h = null;
                h = new Microsoft.Win32.SafeHandles.SafeFileHandle(CreateFile(fileName,
                                                                              FileAccess.Read,
                                                                              FileShare.None,
                                                                              new IntPtr(0),
                                                                              FileMode.Open,
                                                                              0,
                                                                              new IntPtr(0)),
                                                                              true);
    
                if (!h.IsInvalid)
                {
                    System.IO.Stream inPutFile = new FileStream(h, FileAccess.Read);
                    inPutFile.Read(DiskSektoren, 0, 2880*512);
                }
    
            }
        }
    }
    
    

  • Mod

    Das hat aber nix mit physischen Sektoren zu tun. Da wird einfach nur die Diskette wie eine 1.44 MB-Datei geöffnet und gelesen. Das ist ziemlich weit weg vom unterliegenden physikalischem Aufbau einer Diskette, und würde beispielsweise genauso gut mit einer passend großen Datei auf der Festplatte funktionieren.



  • @SeppJ ,
    es werden die Sektoren in der richtigen Reihenfolge gelesen.
    Völlig unabhängig davon, ob dort Daten stehen oder nicht.
    Für mich sind das die physischen Sektoren.
    Man könnte sie in ein Array einlesen oder auch aus meinem großen Array derart auslesen, dass man auf Head, Track, und Sektor kommt.
    Natürlich ist das anders, als früher mit dem INT 13h. Der funktioniert ja nicht mehr.
    Aber mein Ziel war es, alle Sektoren einer Diskette zu lesen und als IMG-Datei abzuspeichern und ggf. aus einer IMG-Datei wieder eine Diskette zu erstellen.
    Ich mache das Programm dahin gehend, dass man zunächst etwas lesen muss (Diskette oder IMG-Datei). Die Daten stehen danach im Byte-Array.
    Wenn das erfolgt ist kann man diese Daten entweder auf ein Diskette ausgeben oder in eine IMG-Datei schreiben.
    Man kann also damit auch direkt Disketten kopieren, wenn man nach dem Lesen der Diskette eine leere einschiebt und danach die Daten auf diese ausgibt.

    "würde beispielsweise genauso gut mit einer passend großen Datei auf der Festplatte funktionieren"

    Du meinst damit mit einer Festplatte oder CD oder USB-Stick.
    Es wird ja gerade keine Datei gelesen, sondern ein physischer Datenträger Sektor für Sektor. Es beginnt mit den Bootsektoren...


  • Mod

    Na, wenn du das weißt....


Anmelden zum Antworten