![]() |
ISO-Image einer CDDA mit CreateFile und ReadFile möglich?
Im Projekt von
![]()
Delphi-Quellcode:
Mit Mode1 CDs funktioniert es problemlos, bei Mode2 CDs (CDDA, VCD, SVCD) bekommt man zwar ein gültiges _FileHandle, jedoch ist beim ersten ReadFile Schluss, weil bytesReaded = 0 ist.
procedure TFormCreateIso.ripDrive(const driveRoot, fileIso: String);
const chunk_size = 4096 * 10; var buffer:PChar; _fileHandle,bytesReaded,Written:LongWord; _totBytes:int64; _r:boolean; fp:file of byte; begin cmrip.Enabled:=false; cmClose.Enabled:=false; cmStop.Enabled:=false; GetMem(buffer,chunk_size); _fileHandle:=CreateFile(PChar('\\.\' + driveRoot),GENERIC_READ,0,nil,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL or FILE_FLAG_SEQUENTIAL_SCAN,0); bytesReaded:=chunk_size; _totBytes:=0; _r:=true; stopRun:=false; try if _fileHandle = INVALID_HANDLE_VALUE then begin raise Exception.Create('Errore opening: ' + '\\.\' + driveRoot); exit; end; AssignFile(fp,fileIso); Rewrite(fp); Written:=chunk_size; while (bytesReaded = chunk_size) and (_r) and (Written = chunk_size) and (not stopRun) do begin _r:=ReadFile(_fileHandle,buffer^,chunk_size,bytesReaded,nil); BlockWrite(fp,buffer^,chunk_size,Written); Inc(_totBytes,bytesReaded); if _totBytes mod (chunk_size * 10) = 0 then begin lblTot.Caption:=IntToStr(_totBytes); Application.ProcessMessages; end; end; finally CloseFile(fp); if _fileHandle <> INVALID_HANDLE_VALUE then CloseHandle(_fileHandle); if buffer <> nil then FreeMem(buffer); cmrip.Enabled:=True; cmClose.Enabled:=True; cmStop.Enabled:=True; end; end; Gibt es eine Möglichkeit, dies anzupassen? Nachtrag: Ich muss mich korrigieren. Bei einer SVCD wird der Datentrack inklusive Struktur gespeichert. |
Re: ISO-Image einer CDDA mit CreateFile und ReadFile möglic
Jetzt habe ich das gefunden:
![]() ![]() |
Re: ISO-Image einer CDDA mit CreateFile und ReadFile möglic
|
Re: ISO-Image einer CDDA mit CreateFile und ReadFile möglic
Für CDDA dürfte es gehen. Bei CD Extra ging Dancemammals Freeburner nicht. Deshalb nehme ich an, dass er für VCD und SVCD auch nicht geht. Der Unterschied liegt ja nur in der Trackreihenfolge. Also CD Extra erst Audio und dann Daten, bei VCD und SVCD erst Daten und dann Video.
isolib_RevToMix.zip kenne ich noch nicht. Müsste man sehen, inwieweit der Freeburner Source übernommen wurde. Danke für den Hinweis. __ Nachtrag: Beim Entpacken von ![]() |
Re: ISO-Image einer CDDA mit CreateFile und ReadFile möglic
Da es eine interne Revision war, welche zusammen gemixt wurde.
|
Re: ISO-Image einer CDDA mit CreateFile und ReadFile möglic
Da die TIsoLib für meine Zwecke wahrscheinlich nicht das richtige ist, habe ich mir den FreeBurner 1.0.0.2 angesehen. Möglicherweise hat Dancemammal die TIsoLib erweitert?
Beim Test Project waren einige Units manuell einzufügen. Vermutlich weil ich die ISO9660-Komponente nicht installiert habe. Dann mussten noch ein paar Uint16 und Uint32 in Word und DWord geändert werden, damit Turbo Delphi das Projekt kompilierte. Die TOC von CDDA und SVCD(2 Daten und ein Video Track) wurden eingelesen. Ein ISO-Image konnte nicht erstellt werden. Leider Ziel nicht erreicht. |
Re: ISO-Image einer CDDA mit CreateFile und ReadFile möglic
Zitat:
|
Re: ISO-Image einer CDDA mit CreateFile und ReadFile möglic
Leider nicht in die Richtung, welche ich brauche.
|
Re: ISO-Image einer CDDA mit CreateFile und ReadFile möglic
Ich habe mir den Freeburner noch einmal angesehen und versucht mit der Testapplication Images von CDs zu ziehen. Die AudioCDs waren leer und beim Zugriff auf DatenCDs fror das System (Win2000) ein.
Ich habe es mit dieser Function versucht:
Delphi-Quellcode:
Dabei habe ich das CDHandle mit der Funktion geholt:
// Sektoren lesen
//============================================================================== function ReadCDAudioSector(cdHandle: THandle; Startsektor, Sektorlesen : Integer; var Data : TRawData; var Fehler : String) : Boolean; var RawReadInfo : RAW_READ_INFO; nb : Cardinal; begin Result := False; RawReadInfo.DiskOffset.QuadPart := Startsektor * CB_CDROMSECTOR; RawReadInfo.TrackMode := CDDA; RawReadInfo.SectorCount := Sektorlesen; nb := 0; if cdHandle <> INVALID_HANDLE_VALUE then Result := DeviceIoControl(cdHandle, IOCTL_CDROM_RAW_READ, @RawReadInfo, SizeOf(RawReadInfo), @Data, Sektorlesen * CB_AUDIO, nb, nil); Fehler := GetLastErrorMsg; end;
Delphi-Quellcode:
Beim Befehl DeviceIOControl erhalte ich immer die Meldung: "Ungültiger Parameter".
function GetDriveHandle(cDrive: Char): THandle;
begin Result := CreateFile(PChar('\\.\'+cDrive+':'), GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); end; Anschliessend habe ich das ausprobiert:
Delphi-Quellcode:
Hier friert das Programm beim DeviceIOControl ein.
function READ_RAW_SECTOR_FROM_CD( hCD : THandle;
HTL : String; var Data : Array of Byte; StartSector : DWord; AnzahlSector : DWord; flags : Byte) : Boolean; const RAW_READ_CMD = $BE; // ATAPI RAW READ PACKET_LEN = 2352; // Sektorlänge SCSI_IOCTL_DATA_IN = 1; IOCTL_SCSI_PASS_THROUGH = $04D004; var srb : SCSI_PASS_THROUGH_DIRECT; nb : Cardinal; Begin Result := False; ZeroMemory(@srb, SizeOf(srb)); ZeroMemory(@Data, SizeOf(Data)); if hCD <> INVALID_HANDLE_VALUE then begin srb.Length := sizeof(SCSI_PASS_THROUGH); srb.PathId := StrToInt(HTL[1]); // SCSI controller ID srb.TargetId := StrToInt(HTL[3]); // target device ID srb.Lun := StrToInt(HTL[5]); // logical unit device ID srb.CdbLength := 12; srb.SenseInfoLength := 0; // SenseInfo srb.DataIn := SCSI_IOCTL_DATA_IN; srb.DataTransferLength := PACKET_LEN * AnzahlSector; srb.TimeOutValue := 200; // TimeOut srb.DataBuffer := @Data; srb.SenseInfoOffset := 0; // SenseInfo // CDB srb.Cdb[0] := RAW_READ_CMD; srb.Cdb[1] := $0; // Format Disk srb.Cdb[2] := HIBYTE(HIWORD(StartSector)); srb.Cdb[3] := LOBYTE(HIWORD(StartSector)); srb.Cdb[4] := HIBYTE(LOWORD(StartSector)); srb.Cdb[5] := LOBYTE(LOWORD(StartSector)); srb.Cdb[6] := LOBYTE(HIWORD(AnzahlSector)); srb.Cdb[7] := LOBYTE(LOWORD(AnzahlSector)); srb.Cdb[8] := HIBYTE(LOWORD(AnzahlSector)); srb.Cdb[9] := flags; srb.Cdb[10] := 0; // Sub-Channel Data Bits srb.Cdb[11] := 0; // reserved Result := DeviceIoControl(hCD, IOCTL_SCSI_PASS_THROUGH, @srb, sizeof(srb), @srb, 0, nb, Nil); end; end; Beide Sourcen habe ich als C im Internet gefunden. |
Re: ISO-Image einer CDDA mit CreateFile und ReadFile möglic
Was passiert wohl, wenn du versuchst eine schreibgeschützte CD mit Schreibrechten zu öffnen :?:
Zitat:
Zum ersten Code (#1): Zitat:
Vielleicht nochmals mit einer passenden Größe versuchen und eventuell ohne FileCache (FILE_FLAG_NO_BUFFERING). FILE_ATTRIBUTE_NORMAL or FILE_FLAG_SEQUENTIAL_SCAN ... hier könnte man es mal ohne FILE_ATTRIBUTE_NORMAL testen ... :zwinker: Zitat:
[add] ansonsten etwas warten ... demnächst werde ich mich "leider" auch mal wieder mit sowas (Datenträger direkt auslesen) befassen müssen -.-'' |
Re: ISO-Image einer CDDA mit CreateFile und ReadFile möglic
Beim Lesen von Blockdevices muss die Leseposition eine Blockgrenze (bzw. der Anfang eines Blocks) sein, mittendrin anfangen zu lesen klappt nicht. Und weil in deiner Funktion oben (function ReadCDAudioSector) am Anfang mit CB_CDROMSECTOR gearbeitet wird, vermute ich mal dass da mit 2048 statt 2352 bzw. 2336 (je nach Trackmode) gerechnet wird - Der Lesezugriff schlägt dann auf die eine oder andere Art fehl. Beim direkten Lesen von USB-Devices muss darüber hinaus noch der Puffer im Speicher auf Speicherseiten aligned sein, so einen passend plazierten Puffer erhaelt man mittels VirtualAlloc. Ich hatte vor geraumer Zeit auch mal mit diesen Sourcen rumgespielt, dann aber irgendwann keine Zeit mehr gehabt, alles hinzubiegen.
|
Re: ISO-Image einer CDDA mit CreateFile und ReadFile möglic
Zitat:
Laut Muetze1 (ich hoffe er war es) könnte das daran liegen, daß zum Auslesen der Speicher in 'nem bestimmten Bereich ganz weit vorn im RAM liegen muß und demnach Windows wohl über 'nen eigenen Zwischenspeicher geht und dann die Daten erst und deinen Speicher rüberkopiert werden, wobei dort egal ist wo dieser Speicher rumliegt. Oder so in etwa ... jedenfalls geht es bei mir auch so, ohne aligned Speicher ... ist schon praktisch, wenn man da z.B. auch einfach etwas aus'm Stack nutzen kann und sich die Resourcenschutzblöcke, samt Speicherreservierung/-freigabe spart. :angel: Aber Schaden kann es ja nie :roll: |
Re: ISO-Image einer CDDA mit CreateFile und ReadFile möglic
Zitat:
Virtualisierungen im Sinne des V86 und Protected Modes gelten für die CPU und den Dingen die darauf ablaufen, der DMA Controller hängt aber ausserhalb der CPU im System und kümmert sich soweit selbstständig um die Datenübertragung kann nur mit physikalischen Adressen - und sein Register ist für diese beschränkt. |
Re: ISO-Image einer CDDA mit CreateFile und ReadFile möglic
Zitat:
Ich schau mal ob ich die Seite in der MSDN wiederfinde. Edit: Hier isses: [msdn]http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/readfile.asp[/msdn] Allerdings hatte ich es etwas anders in Erinnerung, der Puffer muss sector-aligned sein. Da die Pagegröße praktisch immer ein Vielfaches der Sektorgröße ist, erfüllt das Alignment auf Pages den gleichen Zweck :) Zitat:
|
Re: ISO-Image einer CDDA mit CreateFile und ReadFile möglic
@Muetze1: OK, wenn man dat so sieht, dann könnte es hinkommen :wall:
Zitat:
Bei ReadFile/WriteFile und beim DMA-Trasfer ... was an Daten drin stand war eigentlich ganz OK :angel: |
Re: ISO-Image einer CDDA mit CreateFile und ReadFile möglic
Vielleicht hattest Du einfach nur Glück und Deine Puffer waren zufällig halt entsprechend aligned :) Zumindest unter W2K (hab es später nicht mehr auf XP getestet, da ich es für sinnvoller hielt, eine Lösung zu implementieren die unter beiden Systemen funktioniert...) gehts mit krummen Werten definitiv nicht gut. Von mir aus kann ich gerne mal den Source rauswühlen und Samples posten :)
|
Re: ISO-Image einer CDDA mit CreateFile und ReadFile möglic
Entschuldigung für die späte Antwort. Ich war ein paar Wochen auf Montage und hatte keinen Internetzugang.
Zitat:
Zitat:
FILE_FLAG_NO_BUFFERING werde ich mal versuchen, Zitat:
![]() In allen Sourcen, welche ich fand, wurde bei der Positionierung mit der Größe der Nutzdaten von Datensektoren gerechnet. Anschließend wird der Typ des Sektors eingestellt und die tatsächliche Größe der Nutzdaten gelesen. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:56 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz