Physisches Laufwerk als Binärdatei einlesen



  • Bisher habe ich es geschafft, eine Diskette einzulesen und eine Partition von einer USB-SD-Card.
    Die Diskette beginnt mit dem Bootsektor - das funktioniert einwandfrei.
    Ein USB-Stick oder eine USB-Speicher-Card wird jedoch als MBR-Laufwerk eingerichtet (ggf. auch als GPT) und ich kann immer nur eine Partition lesen, diejenige mit dem Laufwerksbuchstaben (auf meiner SD-Card gibt es nur eine Partition, es könnte aber auch mehrere geben).
    Programme, wie Rufus oder Disk2VHD können das Laufwerk incl. MBR usw. lesen.
    So sieht es z.B. bei Rufus aus, wenn ich die SD-Card als VHD lese:

    Es beginnt mit dem Master Boot Record (MBR)

    Datei: CF16MB-CARD.vhd
    
    000000: FA 33 C0 8E  D0 BC 00 7C  8B F4 50 07  50 1F FB FC :.3.....|..P.P...:
                ----------> Start-Programm bis 01B7 des MBR
    
    000010: BF 00 06 B9  00 01 F2 A5  EA 1D 06 00  00 BE BE 07 :................:
    000020: B3 04 80 3C  80 74 0E 80  3C 00 75 1C  83 C6 10 FE :...<.t..<.u.....:
    000030: CB 75 EF CD  18 8B 14 8B  4C 02 8B EE  83 C6 10 FE :.u......L.......:
    000040: CB 74 1A 80  3C 00 74 F4  BE 8B 06 AC  3C 00 74 0B :.t..<.t.....<.t.:
    000050: 56 BB 07 00  B4 0E CD 10  5E EB F0 EB  FE BF 05 00 :V.......^.......:
    000060: BB 00 7C B8  01 02 57 CD  13 5F 73 0C  33 C0 CD 13 :..|...W.._s.3...:
    000070: 4F 75 ED BE  A3 06 EB D3  BE C2 06 BF  FE 7D 81 3D :Ou...........}.=:
    000080: 55 AA 75 C7  8B F5 EA 00  7C 00 00 49  6E 76 61 6C :U.u.....|..Inval:
    000090: 69 64 20 70  61 72 74 69  74 69 6F 6E  20 74 61 62 :id partition tab:
    0000A0: 6C 65 00 45  72 72 6F 72  20 6C 6F 61  64 69 6E 67 :le.Error loading:
    0000B0: 20 6F 70 65  72 61 74 69  6E 67 20 73  79 73 74 65 : operating syste:
    0000C0: 6D 00 4D 69  73 73 69 6E  67 20 6F 70  65 72 61 74 :m.Missing operat:
    0000D0: 69 6E 67 20  73 79 73 74  65 6D 00 00  00 00 00 00 :ing system......:
    0000E0: 00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00 :................:
    0000F0: 00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00 :................:
    000100: 00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00 :................:
    000110: 00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00 :................:
    000120: 00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00 :................:
    000130: 00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00 :................:
    000140: 00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00 :................:
    000150: 00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00 :................:
    000160: 00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00 :................:
    000170: 00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00 :................:
    000180: 00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00 :................:
    000190: 00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00 :................:
    0001A0: 00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00 :................:
    0001B0: 00 00 00 00  00 00 00 00  46 60 03 F1  00 00 80 01 :........F`......:
                                      -----------  ----- ===== ab 01bE = Partition-Tabelle (1)                  
                                      |                  -- ++
    Datenträger-Signatur -------------+                  |  |
                                                         |  +-- CHS-Eintrag 1. Sektor
                                                         +----- 80 Bootfähig / 00 nicht bootfähig
    
    0001C0: 01 00 01 01  60 E8 20 00  00 00 20 7A  00 00 00 00 :....`. ... z....:
            ============================================
            +++++ -- --------- ------------ ------------
            |     |  |         |            |
            |     |  |         |            +-- Anz Sekt der Partition LBA-Methode 31264 = F4 40 00 Bytes
            |     |  |         +--------------- Startsektor LBA-Methode = 20h *200h = 4000h
            |     |  +------------------------- CHS-Eintrag des letzten Sektors
            |     +---------------------------- Typ der Partition 0C = FAT32 mit LBA
            +---------------------------------- CHS-Eintrag 1. Sektor (Fortsetzung)
    
    
    0001D0: 00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00 :................:
    0001E0: 00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00 :................:
    0001F0: 00 00 00 00  00 00 00 00  00 00 00 00  00 00 55 AA :..............U.:
    
    
    000200: FF FF FF FF  FF FF FF FF  FF FF FF FF  FF FF FF FF :................:
    000210: FF FF FF FF  FF FF FF FF  FF FF FF FF  FF FF FF FF :................:
    

    Und ab der Adresse 0x4000 beginnt die erste (einzige) Partition mit dem Boot-Record:

    003FE0: FF FF FF FF  FF FF FF FF  FF FF FF FF  FF FF FF FF :................:
    003FF0: FF FF FF FF  FF FF FF FF  FF FF FF FF  FF FF FF FF :................:
    
    Boot-Sektor Partition 1
    
    004000: EB 34 90 4D  53 44 4F 53  35 2E 30 00  02 08 01 00 :.4.MSDOS5.0.....:
            ================================== ------ -- -----
            ignore                             |      |  |
                                               |      |  +-- Reservierte Sektoren = 1
                                               |      +----- Sektoren per Cluster = 8
                                               +------------ Bytes pro Sektor 200h
    
    004010: 02 00 02 20  7A F8 0C 00  20 00 02 00  20 00 00 00 :... z... ... ...:
            -- ----- ------ -- -----  ----- -----  -----------
            |  |     |      |  |      |     |      ignore
            |  |     |      |  |      |     +--------------- Anzahl Header = 2
            |  |     |      |  |      +--------------------- Sektoren pro Spur = 32
            |  |     |      |  +---------------------------- Sektoren pro FAT = 12 FAT-Len = 1800h
            |  |     |      +------------------------------- ignore
            |  |     +-------------------------------------- Gesamtanzahl Sektoren =  F4 40 00 Bytes
            |  +-------------------------------------------- Max Anzahl Einträge Root-DIR 512 = 4000h Bytes
            +----------------------------------------------- Anzahl FAT = 2
    
    004020: 00 00 00 00  00 00 29 FA  04 00 00 53  41 4E 56 4F :......)....SANVO:
            -----------  ----- -- ------------ ===============
            |            |     |  |            |
            |            |     |  |            +------------ Volume label (11)
            |            |     |  +------------------------- Volume ID
            |            |     +---------------------------- Boot Signatur
            |            +---------------------------------- Ignore
            +----------------------------------------------- Anz. Sektoren bei FAT32
    
    004030: 4C 20 20 20  20 20 46 41  54 31 32 20  20 20 7C 8E :L     FAT12   |.:
            ================== ------------------------- -----
            |                  |                         |
            |                  |                         +-- Rest IGNORE
            |                  +---------------------------- Type z.B. FAT12, FAT16
            +----------------------------------------------- Volume label (11)
    
    004040: C0 8E D8 FB  FC BE 6A 00  81 C6 00 7C  AC 0A C0 74 :......j....|...t:
    004050: 0A B4 0E B7  00 B3 07 CD  10 EB F1 33  C0 CD 16 CD :...........3....:
    004060: 19 BE B3 00  81 C6 00 7C  EB E2 0D 0A  4E 6F 6E 2D :.......|....Non-:
    004070: 53 79 73 74  65 6D 20 64  69 73 6B 20  6F 72 20 64 :System disk or d:
    004080: 69 73 6B 20  65 72 72 6F  72 0D 0A 52  65 70 6C 61 :isk error..Repla:
    004090: 63 65 20 61  6E 64 20 73  74 72 69 6B  65 20 61 6E :ce and strike an:
    0040A0: 79 20 6B 65  79 20 77 68  65 6E 20 72  65 61 64 79 :y key when ready:
    0040B0: 0D 0A 00 0D  0A 44 69 73  6B 20 42 6F  6F 74 20 66 :.....Disk Boot f:
    0040C0: 61 69 6C 75  72 65 0D 0A  00 00 00 00  00 00 00 00 :ailure..........:
    0040D0: 00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00 :................:
    

    So lese ich bisher die Sektoren des jeweiligen Laufwerkes ( A: = Diskette / B: USB-SD-Card )

    
            //============================
            // Für den Diskettenzugriff
            //============================
            [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,
                [MarshalAs(UnmanagedType.U4)] FileAttributes dwFlagsAndAttributes,
                IntPtr template);
    ::::::::::::::
                SafeFileHandle h = new SafeFileHandle(CreateFile(DiskName,     // @"\\.\A:" oder @"\\.\B:"
                                                                 FileAccess.ReadWrite,
                                                                 FileShare.None,
                                                                 new IntPtr(0),
                                                                 FileMode.Open,
                                                                 0,
                                                                 new IntPtr(0)
                                                                ),
                                                       true);
    ::::::::::::::
      Stream fs = new FileStream(h, FileAccess.Read);
      BinaryReader reader = new BinaryReader(fs);
    ::::::::::::::
      EingPu = reader.ReadBytes(512);
    

    Wie muss ich es anstellen, um bei einem USB-Laufwerk nicht lediglich die Partition, die zu dem Buchstaben gehört, sondern das gesamte USB-Laufwerk (analog Rufus) zu lesen ?



  • Da gab es neulich ein Thema in der Entwickler-Ecke: CreateFile für physikalischen Sektoren eines Datenträgers (wenn auch für Delphi, aber der Zugriff auf die WinAPI ist ja ähnlich) - also als Stichwort "\\.\PhysicalDriveX".



  • @Th69 sagte in Physisches Laufwerk als Binärdatei einlesen:

    \.\PhysicalDriveX

    Hallo Th69, wie immer war Dein Hinweis der Weg zur Lösung.
    https://stackoverflow.com/questions/38190/how-do-i-read-a-disk-directly-with-net
    Hier gab es weitere Hinweise auch für C#.
    Ich habe nun bei der DT-Verwaltung nachgesehen und dort erkannt, dass die USB-Card folgende Bezeichnung bekommen muss, der Rest des Programmes konnte so bleiben - alles OK.

     DiskName = @"\\.\PhysicalDrive7";
    

    Weiterhin habe ich in dem von mir genannten Link gelesen, dass das Programm "Als Administrator" ausgeführt werden muss. Andernfalls gibt es einen Fehler. Ich starte also VS2020 "Als Admin" und damit wird auch mein Programm im Test/Debug-Modus "Als Administrator" ausgeführt.
    Bei DiskPart sehe ich die SD-Card auch

    
    Microsoft DiskPart-Version 10.0.19041.964
    
    Copyright (C) Microsoft Corporation.
    Auf Computer: R980
    
    DISKPART> list disk
    
      Datenträger ###  Status         Größe    Frei     Dyn  GPT
      ---------------  -------------  -------  -------  ---  ---
      Datenträger 0    Online         2794 GB  1024 KB        *
      Datenträger 1    Online         1863 GB  1024 KB        *
      Datenträger 2    Online         5589 GB      0 B        *
      Datenträger 3    Online          931 GB  1024 KB        *
      Datenträger 4    Online          931 GB  1024 KB        *
      Datenträger 5    Online          931 GB  1024 KB        *
      Datenträger 7    Online           15 MB      0 B
      Datenträger 8    Kein Medium        0 B      0 B
      Datenträger 9    Kein Medium        0 B      0 B
      Datenträger 10   Kein Medium        0 B      0 B
      Datenträger 11   Kein Medium        0 B      0 B
    
    DISKPART>
    

    Die Karte steckt in einem CardReader und der hat weitere Einsteckplätze, in denen nichts steckt, deshalb werden diese auch aufgelistet mit "0 B".
    Nun habe ich noch zwei Fragen:
    (1) Wie kann ich meinem Programm die Rechte "Als Administrator ausführen" zuweisen
    (2) Wie kann ich erkennen, dass das Laufwerk B: (meine SD-Card) zum Dateträger 7 gehört ?

    Kann man so, wie DiskPart oder die DT-Verwaltung es machen, alle physichen Laufwerke auflisten und davon eines auswählen lassen. Das Disketten-Lw ist bei DiskPart gar nicht dabei, bei der DT-Verwaltung auch nicht.

    BIsher suche ich so nach den Laufwerken:

    Folgende Diskettenlaufwerke gefunden => A:
    
    ~~~~~~~~~~~~~~~~~~~~~~~<Laufwerke>~~~~~~~~~~~~~~~~~~~~~~
    Laufwerk : A:\
      Laufwerkstyp         :	Removable
      Laufwerksbezeichnung :	WIN95DISK
      Datei System         :	FAT
      Verfügbarer freier Speicher : 1.456.640 Bytes
      Speicherkapazität total     : 1.457.664 Bytes 
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Laufwerk : B:\
      Laufwerkstyp         :	Removable
      Laufwerksbezeichnung :	CF16MB-CARD
      Datei System         :	FAT
      Verfügbarer freier Speicher :  7.499.776 Bytes
      Speicherkapazität total     : 15.974.400 Bytes 
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Laufwerk : C:\
      Laufwerkstyp         :	Fixed
      Laufwerksbezeichnung :	C(W) RyWin10 Sam 980 m.2 1TB
      Datei System         :	NTFS
      Verfügbarer freier Speicher :   616.289.288.192 Bytes
      Speicherkapazität total     : 1.000.080.101.376 Bytes 
    

    So suche ich nach Disketten-LWs:

            //===========================================
            // Diskettenlaufwerke ermitteln
            //===========================================
            private void HoleDiskettenLaufwerke() 
            {
                DiskLaufwerke.Clear();
                DiskRecord dr = new DiskRecord();
                DriveInfo[] allDrives = DriveInfo.GetDrives();
                foreach (DriveInfo d in allDrives) 
                {
                    if (d.IsReady) 
                    {
                        if (d.DriveType == DriveType.Removable && 
                            d.DriveFormat == "FAT") // &&  d.TotalSize > 0 && d.TotalSize < 2000000)
                        {
                            dr.dName = d.Name.Substring(0, 1).ToUpper();
                            dr.dLabel = d.VolumeLabel;
                            //dr.dSize = d.TotalSize > 800000 ? 1440 : 720;
                            long Ln = d.TotalSize;
                            if (Ln > 0 && Ln < 800000) 
                            {
                                Ln += 0x1C00;
                            }
                            else if (Ln < 1500000) 
                            {
                                Ln += 0x4200;
                            }
    
                            dr.dSize = (int) (Ln / 1024);
                            dr.dFree = (int) d.TotalFreeSpace;
                            DiskLaufwerke.Add(dr);
                        }
                    }
                }
            } // private void HoleDiskettenLaufwerke() 
    


  • Du kannst bei jeder Anwendung in den Eigenschaften unter "Kompatibilität" den Haken bei "Programm als Administrator ausführen" setzen.

    Für "Laufwerkbuchstabe -> physikalisches Laufwerk" habe ich den C++ Code Opening Physical Disks from Drive letter gefunden (Stichwort: DeviceIoControlmit IOCTL_STORAGE_GET_DEVICE_NUMBER).



  • @Th69
    diese Markierung kenne ich, das gilt aber immer nur in dem Windows, wo der Haken gesetzt ist.
    In dem o.g. Link habe ich so einen Hinweis gefunden, den ich aber nicht umsetzen kann (Manifestdatei)

    Stimmen Sie Marks Antwort zu. Beachten Sie, dass, wenn die Benutzerkontensteuerung aktiviert
    ist (was die Standardeinstellung unter Windows Vista und höher ist), Ihr Programm mit erhöhten
    Rechten (mit Administratorrechten) ausgeführt werden muss. Wenn Ihr Programm nur für wenige
    Benutzer verwendet wird, können Sie den Benutzer auffordern, mit der rechten Maustaste auf die
    ausführbaren Dateien zu klicken und "Als Administrator ausführen" zu wählen. Andernfalls können 
    Sie eine Manifestdatei in das Programm kompilieren und im Manifest angeben, dass das
    Programm mit erhöhten Rechten ausgeführt werden muss (suchen Sie nach
    "requestedExecutionLevel requireAdministrator", um weitere Informationen zu erhalten).
    

    Ich habe nun die Möglichkeit gefunden, alle phys. Drives zu ermitteln und alle Volumes (mit Buchstaben). Wie kann ich die aber zusammenbringen ? Gibt es weitere abrufbare Eigenschaften, wo findet man ein Liste der erlaubten/möglichen Abruf-Strings, wie "Name" und "DeviceID". Evtl. kann man dann darüber erkennen, zu welchem phys.Devive der Volume-Buchstabe gehört.

           private void buZeigeV2_Click(object sender, EventArgs e)
            {
                PutLst("\n\t\tSELECT * FROM Win32_DiskDrive\n");
                ManagementObjectSearcher sDrv = new ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive");
                ManagementObjectCollection coDrv = sDrv.Get();
                foreach (ManagementObject mD in coDrv)
                {
                    string sName     = mD["Name"].ToString();
                    string sDeviceID = mD["DeviceID"].ToString();
                    PutLst("Name=" + sName + ",\tDeviceID=" + sDeviceID);
                }
                PutLst("\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
    
                PutLst("\n\t\tSELECT * FROM Win32_Volume\n");
                ManagementObjectSearcher sVol = new ManagementObjectSearcher("SELECT * FROM Win32_Volume");
                ManagementObjectCollection coVol = sVol.Get();
                foreach (ManagementObject mV in coVol) 
                {
                    string sName     = mV["Name"].ToString();
                    string sDeviceID = mV["DeviceID"].ToString();
                    if (sName.Length < 4) 
                    {
                        PutLst("Name=" + sName + ",\tDeviceID=" + sDeviceID);
                    }
                }
            }
    

    Das Ergebnis sieht bei mir so aus:

    		SELECT * FROM Win32_DiskDrive
    
    Name=\\.\PHYSICALDRIVE1,	DeviceID=\\.\PHYSICALDRIVE1
    Name=\\.\PHYSICALDRIVE4,	DeviceID=\\.\PHYSICALDRIVE4
    Name=\\.\PHYSICALDRIVE0,	DeviceID=\\.\PHYSICALDRIVE0
    Name=\\.\PHYSICALDRIVE10,	DeviceID=\\.\PHYSICALDRIVE10
    Name=\\.\PHYSICALDRIVE2,	DeviceID=\\.\PHYSICALDRIVE2
    Name=\\.\PHYSICALDRIVE3,	DeviceID=\\.\PHYSICALDRIVE3
    Name=\\.\PHYSICALDRIVE7,	DeviceID=\\.\PHYSICALDRIVE7
    Name=\\.\PHYSICALDRIVE9,	DeviceID=\\.\PHYSICALDRIVE9
    Name=\\.\PHYSICALDRIVE5,	DeviceID=\\.\PHYSICALDRIVE5
    Name=\\.\PHYSICALDRIVE11,	DeviceID=\\.\PHYSICALDRIVE11
    Name=\\.\PHYSICALDRIVE8,	DeviceID=\\.\PHYSICALDRIVE8
    
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    
    		SELECT * FROM Win32_Volume
    
    Name=N:\,	DeviceID=\\?\Volume{2fcca544-51c5-4022-9d83-44b139e289de}\
    Name=D:\,	DeviceID=\\?\Volume{01007b91-d250-423a-813d-ac1daf3de249}\
    Name=G:\,	DeviceID=\\?\Volume{26e9a363-bd6b-4d08-b846-6d32f8068003}\
    Name=V:\,	DeviceID=\\?\Volume{018a2911-dd81-4bcb-91a9-37753c58ca07}\
    Name=C:\,	DeviceID=\\?\Volume{d7104ea1-48af-4038-9a5d-4cc85b9dcb7f}\
    Name=U:\,	DeviceID=\\?\Volume{ba1319ad-6b14-4356-bfa2-24e06d089308}\
    Name=W:\,	DeviceID=\\?\Volume{da9cf6c4-0d5d-47a5-b772-d0344b4e4609}\
    Name=B:\,	DeviceID=\\?\Volume{2990d4a8-159c-11ed-8f24-f889d27a29c0}\
    Name=F:\,	DeviceID=\\?\Volume{2990d4a9-159c-11ed-8f24-f889d27a29c0}\
    Name=H:\,	DeviceID=\\?\Volume{2990d4aa-159c-11ed-8f24-f889d27a29c0}\
    Name=I:\,	DeviceID=\\?\Volume{2990d4ab-159c-11ed-8f24-f889d27a29c0}\
    Name=J:\,	DeviceID=\\?\Volume{2990d4ac-159c-11ed-8f24-f889d27a29c0}\
    Name=O:\,	DeviceID=\\?\Volume{e2faf1e2-f2e8-11ec-8dd9-806e6f6e6963}\
    


  • Wie man eine Manifestdatei in ein .NET-Programm einbindet: How do I force my .NET application to run as administrator? (wenn auch in englisch, aber die Bilder sollten trotzdem helfen).
    Beachte aber, daß dann Nicht-Admins immer den UAC-Prompt erhalten.

    Versuche es doch mal mit dem P/Invoke-Aufruf: DeviceIoControl



  • @Th69 ,
    jetzt habe ich eine Lösung gefunden, sicherlich geht es wesentlich eleganter - mir ging es erst einmal um eine funktionierende Lösung

            //============================
            // Für den Diskettenzugriff
            //============================
            [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,
                [MarshalAs(UnmanagedType.U4)] FileAttributes dwFlagsAndAttributes,
                IntPtr template);
    
            [DllImport("Kernel32.dll", SetLastError = true)]
            private static extern bool DeviceIoControl(
                SafeFileHandle hDevice,
                uint dwIoControlCode,
                [In] byte[] InBuffer,
                int nInBufferSize,
                [Out] byte[] OutBuffer,
                int nOutBufferSize,
                out int pBytesReturned,
                IntPtr overlapped );
    
    ::::::::::::::::
    
            //================================================
            // PhysicalDriveN aus Lw-Buchstaben ermitteln
            //================================================
            private string GetPhysDrive(string LwBu) 
            {
                string PhyDrv = "";
                string DiskLwBu = @"\\.\"+LwBu+":";  //   @"\\.\A:";
                SafeFileHandle h = null;
                byte[] oB = new byte[12];
                int bytesReturned = 0;
                devType = devDevice = devPart = 0;
    
                try
                {
                    h = new SafeFileHandle(CreateFile(DiskLwBu, 
                                                      FileAccess.ReadWrite,
                                                      FileShare.None,
                                                      new IntPtr(0),
                                                      FileMode.Open,
                                                      0,
                                                      new IntPtr(0)
                                                     ),
                                           true);
    
                    if (h.IsInvalid)
                    { h.Close(); return ""; } // es gibt kein "PhysicalDriveN"
    
                    if (!DeviceIoControl(h, IOCTL_STORAGE_GET_DEVICE_NUMBER,
                                         null, 0,
                                         oB, oB.Length,
                                         out bytesReturned, IntPtr.Zero))
                    {
                        MessageBox.Show("Fehler bei DeviceIoControl für DiskLwBu = "+ DiskLwBu + 
                                        "\nFehler-Code: " + (Marshal.GetLastWin32Error()).ToString());
                        h.Close(); 
                        return ""; // es gibt kein "PhysicalDriveN"
                    }
    
                    if (bytesReturned != oB.Length)
                    { h.Close(); return ""; } // es gibt kein "PhysicalDriveN"
    
                    devType   = (oB[00]) + (oB[01] << 8) + (oB[02] << 16) + (oB[03] << 24);
                    devDevice = (oB[04]) + (oB[05] << 8) + (oB[06] << 16) + (oB[07] << 24);
                    devPart   = (oB[08]) + (oB[09] << 8) + (oB[10] << 16) + (oB[11] << 24); 
    
                    if (devType == 7 && devDevice > 0 && devPart > 0)
                    {
                        PhyDrv = @"\\.\" + "PhysicalDrive" + devDevice.ToString();
                    }
                }
                catch { PhyDrv = ""; }
    
                return PhyDrv;
            } //  private string GetPhysDrive(string LwBu) 
    
            public int devType   = 0; // Typ 2 = CD , 7 = Disk
            public int devDevice = 0; // Nummer ## für PhysicalDrive##
            public int devPart   = 0; // Partition
    
            public uint IOCTL_STORAGE_GET_DEVICE_NUMBER = 0x2D1080; 
    

    Das Ergebnis sieht folgendermaßen aus, ich habe extra auf den USB-Sticks mehrere Partitionen angelegt, um auch diesen Fall zu haben

    Lw A:        1.440 KB   Partition 0  Label WIN95DISK    PhysLw \\.\A:	
    Lw B:       15.600 KB   Partition 1  Label CF16MB-CARD  PhysLw \\.\PhysicalDrive12	
    Lw E:    3.645.096 KB   Partition 2  Label PART2USB8GB  PhysLw \\.\PhysicalDrive10	
    Lw F:    4.190.756 KB   Partition 1  Label PART1USB8GB  PhysLw \\.\PhysicalDrive10	
    Lw H:        7.140 KB   Partition 3  Label PART3USB8GB  PhysLw \\.\PhysicalDrive10	
    Lw M:      521.808 KB   Partition 1  Label CF1_512MB    PhysLw \\.\PhysicalDrive11	
    Lw P:    7.324.672 KB   Partition 2  Label CF1_PART2    PhysLw \\.\PhysicalDrive11	
    

    Und so sieht die Anzeige von DiskPart aus

    Microsoft DiskPart-Version 10.0.19041.964
    
    Copyright (C) Microsoft Corporation.
    Auf Computer: R980
    
    DISKPART> list disk
    
      Datenträger ###  Status         Größe    Frei     Dyn  GPT
      ---------------  -------------  -------  -------  ---  ---
      Datenträger 0    Online         2794 GB  1024 KB        *
      Datenträger 1    Online         1863 GB  1024 KB        *
      Datenträger 2    Online         5589 GB      0 B        *
      Datenträger 3    Online          931 GB  1024 KB        *
      Datenträger 4    Online          931 GB  1024 KB        *
      Datenträger 5    Online          931 GB  1024 KB        *
      Datenträger 6    Online         3726 GB  1024 KB        *
      Datenträger 7    Online         2794 GB  1024 KB        *
      Datenträger 8    Online         2794 GB  1024 KB        *
      Datenträger 9    Online         3726 GB  1024 KB        *
      Datenträger 10   Online         7680 MB  1024 KB
      Datenträger 11   Online         7680 MB  1024 KB
      Datenträger 12   Online           15 MB      0 B
      Datenträger 13   Kein Medium        0 B      0 B
      Datenträger 14   Kein Medium        0 B      0 B
      Datenträger 15   Kein Medium        0 B      0 B
      Datenträger 16   Kein Medium        0 B      0 B
    
    DISKPART>
    

    Nun kann ich mit dieser Lösung mein eigentliches Programm fertigstellen.
    Es ist toll, dass man letztendlich auch mit .NET und C# (fast) alles machen kann, auch systemnahe Aufgaben.
    Man muss nur wissen, wie es geht...



  • 👍


Anmelden zum Antworten