Festplatte direkt über PB auslesen/beschreiben

Für allgemeine Fragen zur Programmierung mit PureBasic.
real
Beiträge: 468
Registriert: 05.10.2004 14:43

Festplatte direkt über PB auslesen/beschreiben

Beitrag von real »

Hi,

wie kann ich (primär unter Windows) direkten Zugriff auf meinen Festplatten per PureBasic und/oder Asm und/oder Libs/DLLs erlangen? Ich möchte Sektoren direkt lesen/schreiben können.

Dank & Gruß
René
real
Beiträge: 468
Registriert: 05.10.2004 14:43

Re: Festplatte direkt über PB auslesen/beschreiben

Beitrag von real »

Soviel hab ich rausbekommen:

Platten/Partitionen mit

Code: Alles auswählen

CreateFile_("\\\\.\\PhysicalDriveX", #GENERIC_READ | #GENERIC_WRITE, #FILE_SHARE_READ | #FILE_SHARE_WRITE, 0, #OPEN_EXISTING, 0, 0 )
für Zugriffe öffnen und dann mit ReadFile_() bzw. WriteFile_() lesen/schreiben.
Benutzeravatar
mpz
Beiträge: 505
Registriert: 14.06.2005 15:53
Computerausstattung: Win 11 Pro, 48 GB Ram, Intel I7 CPU und RX4070 Grafikkarte, PB (4/5) 6.12LT
Wohnort: Berlin, Tempelhof

Re: Festplatte direkt über PB auslesen/beschreiben

Beitrag von mpz »

Hi real,

vielleicht hilft Dir das folgende Programm weiter. Es kann CD/DVD und andere Medien Sektormäßig auslesen (Festplatten sind nur ausgeklammert worden und müssten sektorspezifisch angepasst werden). Ich benutze es um CD/DVDs zu überprüfen und habe es etwas modernisiert und angepasst. Der Author ist Petr Vavrin und hat den Code im englischen Forum veröffentlicht

Gruß Michael

Code: Alles auswählen


;- Author   : Petr Vavrin (peterb) 
;- Location : Czech Republic 

; Deutsche Version Michael Paulwitz
; Übersetzung
; Verbesserte Fehlerabfrage
; Anzeige ob Sektoren Daten enthalten
; Automatisches Öffnen des Laufwerkes
; Anpassung auf PB 4.40 Beta7

Structure DISK_GEOMETRY 
   Cylinders.q 
   MediaType.l 
   TracksPerCylinder.l 
   SectorsPerTrack.l 
   BytesPerSector.l 
EndStructure 

Structure DISK_GEOMETRY_EX 
  geometry.DISK_GEOMETRY 
  DiskSize.q 
  byte.b[1]; 
EndStructure 

#IOCTL_DISK_BASE        = 7 
#METHOD_BUFFERED        = 0 
#FILE_ANY_ACCESS        = 0 

#FILE_READ_ACCESS       = 1 
#FILE_DEVICE_CD_ROM     = 2 
#IOCTL_CDROM_BASE       = #FILE_DEVICE_CD_ROM 

#boxes                  = 1000 
#box_width              = 7 
#box_height             = 7 
#box_distance           = 2 

#boxes_width            = 290 
#boxes_height           = 290 

#cols                   = #boxes_width / (#box_width + #box_distance) 

Global boxes_left.l 
Global boxes_top.l 
Global boxes_image_background.l = RGB (250, 250, 250) 

Global box_blank_background.l   = RGB (240, 240, 240) 
Global box_blank_outline.l      = RGB (220, 220, 220) 

Global box_set_background.l     = RGB (  0, 255,   0) 
Global box_set_outline.l        = RGB (140, 255, 140) 

Global box_free_background.l     = RGB (  0, 255,   0) 
Global box_free_outline.l        = RGB (100, 255, 100) 

Global box_error_background.l   = RGB (255,   0,   0) 
Global box_error_outline.l      = RGB (255, 100, 100) 

Enumeration 
  #main_window 
  #boxes_gadget 
  #boxes_image 
  #OutputFile 
  #BrowseOutput 
  #Drive_Combo 
  #Start 
  #State 
  #Check_Only 
  #CD_open
  #Disk_Name
  #Disk_Size 
  #Sectors 
  #Actual_Sector 
  #Percents 
  #Error_List 
  #Wrong_Sectors 
  #File 
  #Exit 
EndEnumeration 

Macro IIf (expr, truepart, falsepart) 
  If expr : truepart : Else : falsepart : EndIf 
EndMacro 

Procedure.s GetDriveName (drive$) 
;If drive$="":drive$="c:\":EndIf 
 VName.s = Space(255) 
   FSName.s = Space(255) 
   GetVolumeInformation_(drive$, VName.s, 255, Serial, 0, 0, FSName.s, 255) 

ProcedureReturn VName.s 
EndProcedure 

Procedure make_blank_box () 

  If StartDrawing(ImageOutput(#boxes_image)) 
    For box_number = 0 To #boxes - 1 

      x = #box_distance + ((box_number % #cols) * (#box_width  + #box_distance)) 
      y = #box_distance + ((box_number / #cols) * (#box_height + #box_distance)) 
      
      Box(x,     y,     #box_width,     #box_height,     box_blank_outline) 
      Box(x + 1, y + 1, #box_width - 2, #box_height - 2, box_blank_background) 

    Next 

    StopDrawing() 
    SetGadgetState(#boxes_gadget, ImageID(#boxes_image)) 
  EndIf  

EndProcedure 

Procedure change_box_state (box_number, type.s) 
  
  box_number = box_number - 1 
  
  If StartDrawing(ImageOutput(#boxes_image)) 

    x = #box_distance + ((box_number % #cols) * (#box_width  + #box_distance)) 
    y = #box_distance + ((box_number / #cols) * (#box_height + #box_distance)) 
    
    outline    = RGB (255, 255, 255) 
    background = RGB (255, 255, 255) 
    
    Select type 
      Case "blank" 
        outline    = box_blank_outline 
        background = box_blank_background 

      Case "set" 
        outline    = box_set_outline 
        background = box_set_background 

      Case "free" 
        outline    = box_free_outline 
        background = box_free_background 
        
      Case "error" 
        outline    = box_error_outline 
        background = box_error_background 
      
    EndSelect 
    
    Box(x,     y,     #box_width,     #box_height,     outline) 
    Box(x + 1, y + 1, #box_width - 2, #box_height - 2, background) 

    StopDrawing() 
    SetGadgetState(#boxes_gadget, ImageID(#boxes_image)) 

  EndIf 

EndProcedure 

Procedure.s Make_ISO () 

  make_blank_box () 
;  ClearGadgetItemList( #Error_List ) 
  ClearGadgetItems(#Error_List) 

  drive.s = GetGadgetText ( #Drive_Combo ) 
  return_state.s = "Fehlerfrei beendet" 

  ;If GetDriveType_( drive + "\" ) <> #DRIVE_CDROM 
  If GetDriveType_( drive + "\" ) < 1 ;= #DRIVE_CDROM 
    return_state = "Laufwerk ist kein CD/DVD Laufwerk" 

  Else  

    dg.DISK_GEOMETRY_EX 

    IOCTL_CDROM_GET_DRIVE_GEOMETRY_EX = ((#IOCTL_CDROM_BASE) << 16) | ((#FILE_READ_ACCESS) << 14) | $50 | #METHOD_BUFFERED
    
    Debug Hex(IOCTL_CDROM_GET_DRIVE_GEOMETRY_EX)

    hDevice = CreateFile_("\\.\\" + drive, #GENERIC_READ, #FILE_SHARE_READ | #FILE_SHARE_WRITE, 0, #OPEN_EXISTING, #FILE_ATTRIBUTE_NORMAL, 0) 
    If Not hDevice 
      return_state = "CD/DVD Laufwerk nicht bereit!" 
      
    Else 
      output_file.s = GetGadgetText ( #OutputFile ) 
      
      file_status = #True 
      If GetGadgetState ( #Check_Only ) = 1 
        write = #False 
      Else 
        write = #True 
        
        If Not CreateFile(#File, output_file )
          If output_file
            return_state = "Die Ausgabedatei kann nich erstellt werden!" 
          Else
            return_state = "Keine Ausgabedatei ausgewählt!"           
          EndIf
          file_status = #False         
        EndIf 

      EndIf 

#IOCTL_DISK_GET_DRIVE_GEOMETRY = $00070000

      If file_status = #True 
        DeviceIoControl_(hDevice, IOCTL_CDROM_GET_DRIVE_GEOMETRY_EX, 0, 0, @dg, SizeOf(dg), @bytesret, 0) 
        ;DeviceIoControl_(hDevice, #IOCTL_DISK_GET_DRIVE_GEOMETRY, 0, 0, @dg, SizeOf(dg), @bytesret, 0) 

        Debug "Cylinders: "+Str(dg\geometry\Cylinders)
        Debug "MediaType: "+Str(dg\geometry\MediaType)
        Debug "TracksPerCylinder: "+Str(dg\geometry\TracksPerCylinder)
        Debug "SectorsPerTrack: "+Str(dg\geometry\SectorsPerTrack)
        Debug "Bytes per Sector: "+Str(dg\geometry\BytesPerSector)
        Debug "Gesamtgrösse: "+Str(dg\DiskSize)


        If dg\geometry\BytesPerSector = 0
        
         
          return_state = "Fehlerhafte CD oder CD nicht eingelegt!" 
        Else 
          
          If write = #False 
            SetGadgetText ( #State, "Untersuche ... " ) 
          Else 
            SetGadgetText ( #State, "Kopiere ... " ) 
          EndIf 
            
          sectors.l = (dg\DiskSize / dg\geometry\BytesPerSector) - 1 
          bps.l = dg\geometry\BytesPerSector 
          is_error = #False 
          *pmembuf = AllocateMemory ( bps ) 
          *blank   = AllocateMemory ( bps ) 

          SetGadgetText ( #Disk_Name, GetDriveName (drive + "\") ) 
          SetGadgetText ( #Disk_Size, Str( dg\DiskSize ) + " Bytes" ) 
          SetGadgetText ( #Sectors,   Str( sectors + 1 ) ) 
          SetGadgetText ( #Wrong_Sectors, "0" ) 
  
          For sector = 0 To sectors 
            
            SetGadgetText ( #Actual_Sector,   Str( sector + 1 ) ) 
        
            proz.f = (sector / sectors) * 100 
            position = proz * 10 
    
            SetGadgetText ( #Percents, StrF(proz, 1) + " %" ) 
    
            If ReadFile_(hDevice, *pmembuf, bps, @ret, 0) = 0 
              is_error = #True 
              SetGadgetText (#Wrong_Sectors, Str ( Val ( GetGadgetText ( #Wrong_Sectors ) ) + 1 ) ) 
              
              lerr = GetLastError_() 
              msg$ = Space(4000) 
              nchars.l = FormatMessage_(#FORMAT_MESSAGE_FROM_SYSTEM, 0, lerr, 0, @msg$, 3500, 0)               ;
              AddGadgetItem (#Error_List, -1, GetGadgetText ( #Wrong_Sectors ) + Chr(10) + Str (sector) + Chr(10) + Left(msg$, nchars - 2)) 

              return_state = "beendet, "+GetGadgetText ( #Wrong_Sectors )+" Fehler gefunden" 
              
              If write = #True 
                WriteData(#File, *blank, bps) 
              EndIf 
          
            Else
               
              If write = #True 
                WriteData(#File, *pmembuf, bps) 
              EndIf 
  
            EndIf 
        
            If position <> last_position Or sector = sectors 
                
              If is_error = #True 
                change_box_state ( position, "error") 
              
              Else 

                If CompareMemory(*blank, *pmembuf, bps)
                   change_box_state ( position, "free")
                Else
                   change_box_state ( position, "set")                       
                EndIf
                
              EndIf 
              is_error = #False 
              
            EndIf 
              
            last_position = position 
              
            Repeat 
              Event = WindowEvent() 
              If Event = #PB_Event_Gadget And EventGadget() = #Start 
                return_state = "gestopped" 
                Break 2 
              EndIf 
            Until Not Event 
    
          Next
          
           
          return_state.s = "beendet"          
          
          FreeMemory(*pmembuf) 
          FreeMemory(*blank) 

          If GetGadgetState (#CD_open )
             mciSendString_("set cdaudio door open", "", 0, 0)
          EndIf

  
        EndIf 
        If IsFile(#File) 
          CloseFile(#File) 
        EndIf        
        
      EndIf 
    EndIf 
  EndIf 
  
  ProcedureReturn return_state 

EndProcedure 

If OpenWindow(#main_window, 0, 0, 600, 390, "ISO Maker / CD/DVD Checker", #PB_Window_SystemMenu | #PB_Window_ScreenCentered |#PB_Window_MinimizeGadget)  

  TextGadget        (#PB_Any,            10, 15, 60, 20, "Laufwerk:") 
  ComboBoxGadget    (#Drive_Combo,       85, 10, 40, 20) 

  For c = 65 To 90 
    If GetDriveType_( Chr(c) + ":\" ) > 1 ;= #DRIVE_CDROM 
      AddGadgetItem (#Drive_Combo, -1, Chr(c) + ":") 
    EndIf 
  Next 

  SetGadgetState    (#Drive_Combo, 0) 
  
  CheckBoxGadget    (#Check_Only,        180, 12, 90, 20, "Nur überprüfen")
  CheckBoxGadget    (#CD_open ,          280, 12, 120, 20, "Schacht aut. öffnen")
  
  TextGadget        (#PB_Any,            410, 15, 150, 20, "dt.Vers. M.Paulwitz") 
  ButtonGadget      (#Exit,              510, 10,  80, 20, "Ende", #BS_FLAT ) 
  TextGadget        (#PB_Any,            10,  40,  80, 20, "Ausgabedatei:") 
  StringGadget      (#OutputFile,        85,  37, 415, 20, "", #WS_EX_STATICEDGE | #WS_BORDER) 
  ;StringGadget      (#OutputFile,        80,  35, 420, 20, "", #WS_EX_STATICEDGE | #WS_BORDER) 
  ButtonGadget      (#BrowseOutput,      510, 37,  80, 20, "Suchen", #BS_FLAT ) 
  TextGadget        (#PB_Any,            10,  65,  60, 20, "Status:") 
  TextGadget        (#State,             85,  65, 420, 20, "") 
  ButtonGadget      (#Start,             510, 64,  80, 20, "Start", #BS_FLAT ) 
  
  CreateImage(#boxes_image, #boxes_width, #boxes_height) 
  If StartDrawing(ImageOutput(#boxes_image)) 
    Box(0, 0, #boxes_width, #boxes_width, boxes_image_background) 
    StopDrawing() 
  EndIf 
  
  boxes_left = 10 
  boxes_top  = 90 

  ImageGadget(#boxes_gadget, boxes_left, boxes_top, #boxes_width, #boxes_height, ImageID(#boxes_image)) 

  make_blank_box () 
  
  TextGadget        (#PB_Any,            310,   95,  60, 20, "Disk Name:") 
  TextGadget        (#PB_Any,            310,  120,  60, 20, "Disk Größe:") 
  TextGadget        (#PB_Any,            310,  145,  60, 20, "Sektoren:") 
  TextGadget        (#PB_Any,            310,  170,  75, 20, "Akt. Sektor:") 
  TextGadget        (#PB_Any,            310,  195,  75, 20, "Prozent:") 
  TextGadget        (#PB_Any,            310,  220,  75, 20, "Def. Sektoren:") 
  
  
  
  TextGadget        (#Disk_Name,         390,   95,  200, 20, "") 
  TextGadget        (#Disk_Size,         390,  120,  150, 20, "") 
  TextGadget        (#Sectors,           390,  145,  150, 20, "") 
  TextGadget        (#Actual_Sector,     390,  170,  150, 20, "") 
  TextGadget        (#Percents,          390,  195,  150, 20, "") 
  TextGadget        (#Wrong_Sectors,     390,  220,   75, 20, "0") 

  ListIconGadget    (#Error_List, 310, 245, 280, 135, "Fehler #", 55, #PB_ListIcon_FullRowSelect | #PB_ListIcon_AlwaysShowSelection | #PB_ListIcon_GridLines ) 
  AddGadgetColumn   (#Error_List, 1, "Sektor #", 70): 
  AddGadgetColumn   (#Error_List, 2, "Info #", 150): 

  Repeat 
    Event = WaitWindowEvent() 

    If Event = #PB_Event_Gadget 
  
      If EventGadget() = #BrowseOutput 
        last_path.s = GetPathPart(GetGadgetText(#OutputFile)) 
        
        IIf ( last_path <> "", StandardFile$ = last_path, StandardFile$ = "C:\" ) 
        File$ = SaveFileRequester("Bitte Datei zum speichern wählen", StandardFile$, "ISO (*.iso)|*.iso", 0) 
              
        If File$ 
          If UCase ( GetExtensionPart( File$ ) ) <> "ISO" 
            File$ + ".iso" 
          EndIf 
        
          SetGadgetText( #OutputFile, File$ ) 
        EndIf 
      EndIf 
      
      If EventGadget() = #Start 

        SetGadgetText ( #Start, "Stop" ) 
        DisableGadget ( #OutputFile,    #True ) 
        DisableGadget ( #Drive_Combo,   #True ) 
        DisableGadget ( #Check_Only,    #True ) 
        DisableGadget ( #BrowseOutput,  #True ) 
        SetGadgetText ( #Disk_Name,     " " ) 
        SetGadgetText ( #Disk_Size,     " " ) 
        SetGadgetText ( #Sectors,       " " ) 
        SetGadgetText ( #Wrong_Sectors, " " ) 
        SetGadgetText ( #Actual_Sector, " " ) 
        SetGadgetText ( #Percents,      " " ) 

        state.s = Make_ISO () 

        SetGadgetText ( #Start, "Start" ) 
        DisableGadget ( #Drive_Combo,  #False ) 
        DisableGadget ( #Check_Only,   #False ) 
        
        If GetGadgetState ( #Check_Only ) = 1 
          DisableGadget ( #OutputFile,    #True ) 
          DisableGadget ( #BrowseOutput,  #True ) 
        Else 
          DisableGadget ( #OutputFile,    #False ) 
          DisableGadget ( #BrowseOutput,  #False ) 
        EndIf 
        SetGadgetText ( #State, state ) 

      EndIf 
      
      If EventGadget() = #Check_Only 
        If GetGadgetState ( #Check_Only ) = 1 
          DisableGadget ( #OutputFile,    #True ) 
          DisableGadget ( #BrowseOutput,  #True ) 
        Else 
          DisableGadget ( #OutputFile,    #False ) 
          DisableGadget ( #BrowseOutput,  #False ) 
        EndIf          
      EndIf 
      
      If EventGadget() = #Exit 
        End 
      EndIf 

    EndIf 
      
   Until Event = #PB_Event_CloseWindow 
 EndIf 
End 

Working on :lol: - LibSGD - MP3D Engine - 8)
real
Beiträge: 468
Registriert: 05.10.2004 14:43

Re: Festplatte direkt über PB auslesen/beschreiben

Beitrag von real »

Danke für den Code... :allright:

Hab's gestern/heute nacht auch nach der von mir genannten Methode hinbekommen. Bin dabei ein wenig auf die Nase gefallen, weil ich vor dem Schreiben eines im Speicher geänderten Datenblocks den Filepointer nicht zurückgesetzt und so den Folgeblock anstelle des aktuell überarbeiteten Blocks überschrieben hab.

Dieser Weg funktioniert:
1. CreateFile_() - zum Erlangen des Handles auf das Device
2. ReadFile_() - zum Lesen eines Sektors
3. SetFilePointer_() - zum Zurücksetzen des Filepointers auf die Position vor ReadFile_()
4. WriteFile_() - zum Schreiben eines Sektors
5. CloseFile_() - zum Schließen des Filehandles
Schoppy
Beiträge: 9
Registriert: 28.03.2009 04:41

Re: Festplatte direkt über PB auslesen/beschreiben

Beitrag von Schoppy »

Hi, versuche gerade ähnliches.

Der Code funktioniert mit CDs super.

Ich möchte aber eine Externe HDD auslesen.

Habe:
DeviceIoControl_(hDevice, #IOCTL_DISK_GET_DRIVE_GEOMETRY, 0, 0, @dg, SizeOf(dg), @bytesret, 0)
aktiviert, aber

Debug "Gesamtgrösse: "+Str(dg\DiskSize) ergibt = 0

Folglich beendet er die Schleife.

Muss ich den Code noch wo anders umstellen?

Gruss
Florian
Benutzeravatar
mpz
Beiträge: 505
Registriert: 14.06.2005 15:53
Computerausstattung: Win 11 Pro, 48 GB Ram, Intel I7 CPU und RX4070 Grafikkarte, PB (4/5) 6.12LT
Wohnort: Berlin, Tempelhof

Re: Festplatte direkt über PB auslesen/beschreiben

Beitrag von mpz »

Hi,

ist zwar ein bisschen länger her, aber hier mal meine Anpassung des Isomakers auf 5.73 und Lesen von CD/DVDs und USB Festplatten/Sticks.

Mit dem Programm kann man CD/DVDs auf Lesefehler überprüfen, aber auch Iso Dateien erstellen. Bei großen Medien (z.B. USB Stick 1 GB) dauert es aber ewig, weil immer Sector für Sector gelesen wird. Wer Lust hat kann es ja verschnellern. Dazu muss man vermutlich nur die Lesegroesse verändern und dann richtig aufteilen.

P.S: Ich hoffe es kommt auch das richtige raus. CD Isos funktionieren super

Gruss MPz

Code: Alles auswählen


; Isomaker.pb

;- Author   : Petr Vavrin (peterb) 
;- Location : Czech Republic 

; Deutsche Version Michael Paulwitz
; Übersetzung
; Verbesserte Fehlerabfrage
; Anzeige ob Sektoren Daten enthalten
; Automatisches Öffnen des Laufwerkes
; Anpassung auf PB 5.73
;

Structure DISK_GEOMETRY 
   Cylinders.q 
   MediaType.l 
   TracksPerCylinder.l 
   SectorsPerTrack.l 
   BytesPerSector.l 
EndStructure 

Structure DISK_GEOMETRY_EX 
  geometry.DISK_GEOMETRY 
  DiskSize.q 
  byte.b[1]; 
EndStructure 

#IOCTL_DISK_BASE        = 7 
#METHOD_BUFFERED        = 0 
#FILE_ANY_ACCESS        = 0 

#FILE_READ_ACCESS       = 1 
#FILE_DEVICE_CD_ROM     = 2 
#IOCTL_CDROM_BASE       = #FILE_DEVICE_CD_ROM 

#boxes                  = 1000 
#box_width              = 7 
#box_height             = 7 
#box_distance           = 2 

#boxes_width            = 290 
#boxes_height           = 290 

#cols                   = #boxes_width / (#box_width + #box_distance) 

Global boxes_left.l 
Global boxes_top.l 
Global boxes_image_background.l = RGB (250, 250, 250) 

Global box_blank_background.l   = RGB (240, 240, 240) 
Global box_blank_outline.l      = RGB (220, 220, 220) 

Global box_set_background.l     = RGB (  0, 255,   0) 
Global box_set_outline.l        = RGB (140, 255, 140) 

Global box_free_background.l     = RGB (  0, 255,   0) 
Global box_free_outline.l        = RGB (100, 255, 100) 

Global box_error_background.l   = RGB (255,   0,   0) 
Global box_error_outline.l      = RGB (255, 100, 100) 

Enumeration 
  #main_window 
  #boxes_gadget 
  #boxes_image 
  #OutputFile 
  #BrowseOutput 
  #Drive_Combo 
  #Start 
  #State 
  #Check_Only 
  #CD_open
  #Disk_Name
  #Disk_Size 
  #Sectors 
  #Actual_Sector 
  #Percents 
  #Error_List 
  #Wrong_Sectors 
  #File 
  #Exit 
EndEnumeration 

Macro IIf (expr, truepart, falsepart) 
  If expr : truepart : Else : falsepart : EndIf 
EndMacro 

Procedure.s GetDriveName (drive$) 
;If drive$="":drive$="c:\":EndIf 
 VName.s = Space(255) 
 FSName.s = Space(255) 
 GetVolumeInformation_(drive$, VName.s, 255, Serial, 0, 0, FSName.s, 255) 

ProcedureReturn VName.s 
EndProcedure 

Procedure make_blank_box () 

  If StartDrawing(ImageOutput(#boxes_image)) 
    For box_number = 0 To #boxes - 1 

      x = #box_distance + ((box_number % #cols) * (#box_width  + #box_distance)) 
      y = #box_distance + ((box_number / #cols) * (#box_height + #box_distance)) 
      
      Box(x,     y,     #box_width,     #box_height,     box_blank_outline) 
      Box(x + 1, y + 1, #box_width - 2, #box_height - 2, box_blank_background) 

    Next 

    StopDrawing() 
    SetGadgetState(#boxes_gadget, ImageID(#boxes_image)) 
  EndIf  

EndProcedure 

Procedure change_box_state (box_number, type.s) 
  
  box_number = box_number - 1 
  
  If StartDrawing(ImageOutput(#boxes_image)) 

    x = #box_distance + ((box_number % #cols) * (#box_width  + #box_distance)) 
    y = #box_distance + ((box_number / #cols) * (#box_height + #box_distance)) 
    
    outline    = RGB (255, 255, 255) 
    background = RGB (255, 255, 255) 
    
    Select type 
      Case "blank" 
        outline    = box_blank_outline 
        background = box_blank_background 

      Case "set" 
        outline    = box_set_outline 
        background = box_set_background 

      Case "free" 
        outline    = box_free_outline 
        background = box_free_background 
        
      Case "error" 
        outline    = box_error_outline 
        background = box_error_background 
      
    EndSelect 
    
    Box(x,     y,     #box_width,     #box_height,     outline) 
    Box(x + 1, y + 1, #box_width - 2, #box_height - 2, background) 

    StopDrawing() 
    SetGadgetState(#boxes_gadget, ImageID(#boxes_image)) 

  EndIf 

EndProcedure 

Procedure.s Make_ISO () 

  make_blank_box () 
;  ClearGadgetItemList( #Error_List ) 
  ClearGadgetItems(#Error_List) 

  drive.s = GetGadgetText ( #Drive_Combo ) 
  return_state.s = "Fehlerfrei beendet" 

  ;If GetDriveType_( drive + "\" ) <> #DRIVE_CDROM 
  If GetDriveType_( drive + "\" ) < 1 ;= #DRIVE_CDROM 
    return_state = "Laufwerk ist kein CD/DVD Laufwerk" 

  Else  

    dg.DISK_GEOMETRY_EX 
   
    #IOCTL_DISK_GET_DRIVE_GEOMETRY    = $00070000
    #IOCTL_DISK_GET_DRIVE_GEOMETRY_EX = $000700A0
    #IOCTL_CDROM_GET_DRIVE_GEOMETRY_EX = $00024050 
    
    hDevice = CreateFile_("\\.\\" + drive, #GENERIC_READ, #FILE_SHARE_READ | #FILE_SHARE_WRITE, 0, #OPEN_EXISTING, #FILE_ATTRIBUTE_NORMAL, 0) 
    If Not hDevice 
      return_state = "CD/DVD Laufwerk nicht bereit!" 
    Else 
      output_file.s = GetGadgetText ( #OutputFile ) 
      
      file_status = #True 
      If GetGadgetState ( #Check_Only ) = 1 
        write = #False 
      Else 
        write = #True 
        
        If Not CreateFile(#File, output_file )
          If output_file
            return_state = "Die Ausgabedatei kann nich erstellt werden!" 
          Else
            return_state = "Keine Ausgabedatei ausgewählt!"           
          EndIf
          file_status = #False         
        EndIf 

      EndIf 
      
      If file_status = #True 
        
        ;DeviceIoControl_(hDevice, #IOCTL_CDROM_GET_DRIVE_GEOMETRY_EX, 0, 0, @dg, SizeOf(dg), @bytesret, 0) 
        DeviceIoControl_(hDevice, #IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, 0, 0, @dg, SizeOf(dg), @bytesret, 0) 

        Debug "Cylinders: "+Str(dg\geometry\Cylinders)
        Debug "MediaType: "+Str(dg\geometry\MediaType)
        Debug "TracksPerCylinder: "+Str(dg\geometry\TracksPerCylinder)
        Debug "SectorsPerTrack: "+Str(dg\geometry\SectorsPerTrack)
        Debug "Bytes per Sector: "+Str(dg\geometry\BytesPerSector)
        
        Debug "Gesamtgrösse: "+Str(dg\DiskSize)


        If dg\geometry\BytesPerSector = 0
        
         
          return_state = "Fehlerhafte CD oder CD nicht eingelegt!" 
        Else 
          
          If write = #False 
            SetGadgetText ( #State, "Untersuche ... " ) 
          Else 
            SetGadgetText ( #State, "Kopiere ... " ) 
          EndIf 
            
          sectors.l = (dg\DiskSize / dg\geometry\BytesPerSector) - 1 
          bps.l = dg\geometry\BytesPerSector
          is_error = #False 
          *pmembuf = AllocateMemory ( bps ) 
          *blank   = AllocateMemory ( bps ) 

          SetGadgetText ( #Disk_Name, GetDriveName (drive + "\") ) 
          SetGadgetText ( #Disk_Size, Str( dg\DiskSize ) + " Bytes" ) 
          SetGadgetText ( #Sectors,   Str( sectors + 1 ) ) 
          SetGadgetText ( #Wrong_Sectors, "0" ) 
  
          For sector = 0 To sectors 
            
            SetGadgetText ( #Actual_Sector,   Str( sector + 1 ) ) 
        
            proz.f = (sector / sectors) * 100 
            position = proz * 10 
    
            SetGadgetText ( #Percents, StrF(proz, 1) + " %" ) 
    
            If ReadFile_(hDevice, *pmembuf, bps, @ret, 0) = 0 
              is_error = #True 
              SetGadgetText (#Wrong_Sectors, Str ( Val ( GetGadgetText ( #Wrong_Sectors ) ) + 1 ) ) 
              
              lerr = GetLastError_() 
              msg$ = Space(4000) 
              nchars.l = FormatMessage_(#FORMAT_MESSAGE_FROM_SYSTEM, 0, lerr, 0, @msg$, 3500, 0)               ;
              AddGadgetItem (#Error_List, -1, GetGadgetText ( #Wrong_Sectors ) + Chr(10) + Str (sector) + Chr(10) + Left(msg$, nchars - 2)) 

              return_state = "beendet, "+GetGadgetText ( #Wrong_Sectors )+" Fehler gefunden" 
              
              If write = #True 
                WriteData(#File, *blank, bps) 
              EndIf 
          
            Else
               
              If write = #True 
                WriteData(#File, *pmembuf, bps) 
              EndIf 
  
            EndIf 
        
            If position <> last_position Or sector = sectors 
                
              If is_error = #True 
                change_box_state ( position, "error") 
              
              Else 

                If CompareMemory(*blank, *pmembuf, bps)
                   change_box_state ( position, "free")
                Else
                   change_box_state ( position, "set")                       
                EndIf
                
              EndIf 
              is_error = #False 
              
            EndIf 
              
            last_position = position 
              
            Repeat 
              Event = WindowEvent() 
              If Event = #PB_Event_Gadget And EventGadget() = #Start 
                return_state = "gestopped" 
                Break 2 
              EndIf 
            Until Not Event 
    
          Next
          
           
          return_state.s = "beendet"          
          
          FreeMemory(*pmembuf) 
          FreeMemory(*blank) 

          If GetGadgetState (#CD_open )
             mciSendString_("set cdaudio door open", "", 0, 0)
          EndIf

  
        EndIf 
        If IsFile(#File) 
          CloseFile(#File) 
        EndIf        
        
      EndIf 
    EndIf 
  EndIf 
  
  ProcedureReturn return_state 

EndProcedure 

If OpenWindow(#main_window, 0, 0, 600, 390, "ISO Maker / CD/DVD Checker", #PB_Window_SystemMenu | #PB_Window_ScreenCentered |#PB_Window_MinimizeGadget)  

  TextGadget        (#PB_Any,            10, 15, 60, 20, "Laufwerk:") 
  ComboBoxGadget    (#Drive_Combo,       85, 10, 40, 20) 

  For c = 65 To 90 
    If GetDriveType_( Chr(c) + ":\" ) > 1 ;= #DRIVE_CDROM 
      AddGadgetItem (#Drive_Combo, -1, Chr(c) + ":") 
    EndIf 
  Next 

  SetGadgetState    (#Drive_Combo, 0) 
  
  CheckBoxGadget    (#Check_Only,        180, 12, 90, 20, "Nur überprüfen")
  CheckBoxGadget    (#CD_open ,          280, 12, 120, 20, "Schacht aut. öffnen")
  
  TextGadget        (#PB_Any,            410, 15, 150, 20, "dt.Vers. M.Paulwitz") 
  ButtonGadget      (#Exit,              510, 10,  80, 20, "Ende", #BS_FLAT ) 
  TextGadget        (#PB_Any,            10,  40,  80, 20, "Ausgabedatei:") 
  StringGadget      (#OutputFile,        85,  37, 415, 20, "", #WS_EX_STATICEDGE | #WS_BORDER) 
  ;StringGadget      (#OutputFile,        80,  35, 420, 20, "", #WS_EX_STATICEDGE | #WS_BORDER) 
  ButtonGadget      (#BrowseOutput,      510, 37,  80, 20, "Suchen", #BS_FLAT ) 
  TextGadget        (#PB_Any,            10,  65,  60, 20, "Status:") 
  TextGadget        (#State,             85,  65, 420, 20, "") 
  ButtonGadget      (#Start,             510, 64,  80, 20, "Start", #BS_FLAT ) 
  
  CreateImage(#boxes_image, #boxes_width, #boxes_height) 
  If StartDrawing(ImageOutput(#boxes_image)) 
    Box(0, 0, #boxes_width, #boxes_width, boxes_image_background) 
    StopDrawing() 
  EndIf 
  
  boxes_left = 10 
  boxes_top  = 90 

  ImageGadget(#boxes_gadget, boxes_left, boxes_top, #boxes_width, #boxes_height, ImageID(#boxes_image)) 

  make_blank_box () 
  
  TextGadget        (#PB_Any,            310,   95,  60, 20, "Disk Name:") 
  TextGadget        (#PB_Any,            310,  120,  60, 20, "Disk Größe:") 
  TextGadget        (#PB_Any,            310,  145,  60, 20, "Sektoren:") 
  TextGadget        (#PB_Any,            310,  170,  75, 20, "Akt. Sektor:") 
  TextGadget        (#PB_Any,            310,  195,  75, 20, "Prozent:") 
  TextGadget        (#PB_Any,            310,  220,  75, 20, "Def. Sektoren:") 
  
  
  
  TextGadget        (#Disk_Name,         390,   95,  200, 20, "") 
  TextGadget        (#Disk_Size,         390,  120,  150, 20, "") 
  TextGadget        (#Sectors,           390,  145,  150, 20, "") 
  TextGadget        (#Actual_Sector,     390,  170,  150, 20, "") 
  TextGadget        (#Percents,          390,  195,  150, 20, "") 
  TextGadget        (#Wrong_Sectors,     390,  220,   75, 20, "0") 

  ListIconGadget    (#Error_List, 310, 245, 280, 135, "Fehler #", 55, #PB_ListIcon_FullRowSelect | #PB_ListIcon_AlwaysShowSelection | #PB_ListIcon_GridLines ) 
  AddGadgetColumn   (#Error_List, 1, "Sektor #", 70): 
  AddGadgetColumn   (#Error_List, 2, "Info #", 150): 

  Repeat 
    Event = WaitWindowEvent() 

    If Event = #PB_Event_Gadget 
  
      If EventGadget() = #BrowseOutput 
        last_path.s = GetPathPart(GetGadgetText(#OutputFile)) 
        
        IIf ( last_path <> "", StandardFile$ = last_path, StandardFile$ = "C:\" ) 
        File$ = SaveFileRequester("Bitte Datei zum speichern wählen", StandardFile$, "ISO (*.iso)|*.iso", 0) 
              
        If File$ 
          If UCase ( GetExtensionPart( File$ ) ) <> "ISO" 
            File$ + ".iso" 
          EndIf 
        
          SetGadgetText( #OutputFile, File$ ) 
        EndIf 
      EndIf 
      
      If EventGadget() = #Start 

        SetGadgetText ( #Start, "Stop" ) 
        DisableGadget ( #OutputFile,    #True ) 
        DisableGadget ( #Drive_Combo,   #True ) 
        DisableGadget ( #Check_Only,    #True ) 
        DisableGadget ( #BrowseOutput,  #True ) 
        SetGadgetText ( #Disk_Name,     " " ) 
        SetGadgetText ( #Disk_Size,     " " ) 
        SetGadgetText ( #Sectors,       " " ) 
        SetGadgetText ( #Wrong_Sectors, " " ) 
        SetGadgetText ( #Actual_Sector, " " ) 
        SetGadgetText ( #Percents,      " " ) 

        state.s = Make_ISO () 

        SetGadgetText ( #Start, "Start" ) 
        DisableGadget ( #Drive_Combo,  #False ) 
        DisableGadget ( #Check_Only,   #False ) 
        
        If GetGadgetState ( #Check_Only ) = 1 
          DisableGadget ( #OutputFile,    #True ) 
          DisableGadget ( #BrowseOutput,  #True ) 
        Else 
          DisableGadget ( #OutputFile,    #False ) 
          DisableGadget ( #BrowseOutput,  #False ) 
        EndIf 
        SetGadgetText ( #State, state ) 

      EndIf 
      
      If EventGadget() = #Check_Only 
        If GetGadgetState ( #Check_Only ) = 1 
          DisableGadget ( #OutputFile,    #True ) 
          DisableGadget ( #BrowseOutput,  #True ) 
        Else 
          DisableGadget ( #OutputFile,    #False ) 
          DisableGadget ( #BrowseOutput,  #False ) 
        EndIf          
      EndIf 
      
      If EventGadget() = #Exit 
        End 
      EndIf 

    EndIf 
      
   Until Event = #PB_Event_CloseWindow 
 EndIf 
End 


Working on :lol: - LibSGD - MP3D Engine - 8)
Antworten