⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iso9660microudfstreamhandler.pas

📁 用于CD/DVD烧录的Delphi源码,包括source和demo
💻 PAS
字号:
{-----------------------------------------------------------------------------
 Unit Name: ISO9660MicroUDFStreamHandler
 Author:    Daniel Mann / Thomas Koos (original class) Dancemammal
 Purpose:   Image File Handler
 History:   Code originally from Daniel Mann / Thomas Koos


-----------------------------------------------------------------------------}


Unit ISO9660MicroUDFStreamHandler;

Interface

Uses
  Classes,CDBufferedStream;

Type
  TISOBookFormat = (ybfAuto, ybfMode1, ybfMode2);
  TISOImageFormat = (ifAuto, ifCompleteSectors, ifOnlyData);

  TImageStreamHandler = Class
  Private
    fISOBookFormat    : TISOBookFormat;
    fImageFormat      : TISOImageFormat;
    fImageOffset      : Cardinal; // e.g. used by Nero Images
    fFileStream       : TCDBufferedStream;
    fCurrentSector    : Cardinal;
    FLastErrorString  : String;
  Protected
    Procedure    DetectImageType; Virtual;
    Function     CalcSectorOffset(Const ASector : Cardinal): Integer; Virtual;
    Function     CalcUserDataOffset: Integer; Virtual;
    Function     GetSectorDataSize: Cardinal; Virtual;
  Public
    Constructor  Create(Const AFileName : String; Const AImageFormat : TISOImageFormat); Overload; Virtual;
    Constructor  Create(Const ANewFileName : String; Const ABookFormat : TISOBookFormat; Const AImageFormat : TISOImageFormat); Overload; Virtual;
    Destructor   Destroy; Override;
    Function     SeekSector(Const ASector : Cardinal; Const AGrow : Boolean = True): Boolean; Virtual;
    Function     ReadSector_Data(Var ABuffer; Const ABufferSize : Integer = -1): Boolean; Virtual;
    Function     ReadSector_Raw (Var ABuffer; Const ABufferSize : Integer = -1): Boolean; Virtual;
    Function     GetLastError : String;
  Published
    Property     ISOBookFormat    : TISOBookFormat         Read  fISOBookFormat;
    Property     ImageFormat      : TISOImageFormat        Read  fImageFormat;
    Property     ImageOffset      : Cardinal               Read  fImageOffset;
    Property     SectorDataSize   : Cardinal               Read  GetSectorDataSize;
    Property     CurrentSector    : Cardinal               Read  fCurrentSector;
    Property     Stream           : TCDBufferedStream      Read  fFileStream;
  End;


Implementation

Uses
  SysUtils; // for FileExists()


Function TImageStreamHandler.GetLastError : String;
begin
   Result := FLastErrorString;
end;


Constructor TImageStreamHandler.Create(Const AFileName: String; Const AImageFormat: TISOImageFormat);
Begin
  Inherited Create;
  If ( Not FileExists(AFileName) ) Then
  begin
     FLastErrorString := 'ISO Image file not found, Creating';
     exit;
  end
  else
  fFileStream := TCDBufferedStream.Create(AFileName,fmOpenRead);
  DetectImageType;
  SeekSector(fCurrentSector);
End;



Constructor TImageStreamHandler.Create(Const ANewFileName : String; Const ABookFormat: TISOBookFormat; Const AImageFormat: TISOImageFormat);
Begin
  Inherited Create;
  If ( ABookFormat = ybfAuto ) Then FLastErrorString := 'ISO Image book format has to be defined!';
  If ( AImageFormat = ifAuto ) Then FLastErrorString := 'Image format has to be defined!';
  fISOBookFormat     := ABookFormat;
  FImageFormat       := AImageFormat;
  FImageOffset       := 0;
  fFileStream := TCDBufferedStream.Create(ANewFileName,fmCreate);
  SeekSector(fCurrentSector);
End;


Destructor TImageStreamHandler.Destroy;
Begin
  If ( Assigned(fFileStream) ) Then FreeAndNil(fFileStream);
  Inherited destroy;
End;

Function TImageStreamHandler.CalcUserDataOffset: Integer;
Begin
  Result := 0;
  Case fImageFormat Of
    ifCompleteSectors  : Result := 16; // 12 bytes SYNC, 4 byte Header
    ifOnlyData         : Result := 0;
    ifAuto             : FLastErrorString := 'can not calculate sector offset with auto values!';
  Else
    FLastErrorString := 'TImageStreamHandler.CalcUserDataOffset(): Implementation error!';
  End;
End;



Function TImageStreamHandler.CalcSectorOffset(Const ASector: Cardinal): Integer;
Begin
  Result := 0;
  Case fImageFormat Of
    ifCompleteSectors : Result := fImageOffset + ASector * 2352;
    ifOnlyData        :
      Begin
        Case fISOBookFormat Of
          ybfMode1 : Result := fImageOffset + ASector * 2048;
          ybfMode2 : Result := fImageOffset + ASector * 2336;
          ybfAuto  : FLastErrorString := ('can not calculate sector with auto settings');
        Else
          FLastErrorString := ('TImageStreamHandler.CalcSectorOffset(): Implementation error!');
        End;
      End;
    ifAuto : FLastErrorString := ('can not calculate sector with auto settings');
  Else
    FLastErrorString := ('TImageStreamHandler.CalcSectorOffset(): Implementation error!');
  End;
End;



Procedure TImageStreamHandler.DetectImageType;
Type
  TCheckBuf = Packed Record
    DeskID : Byte;
    StdID  : Array[0..4] Of Char;
  End;

  TRawCheckBuf = Packed Record
    SYNC   : Array[0..11] of Byte;
    Header_SectMin,
    Header_SectSec,
    Header_SectNo,
    Header_Mode    : Byte;
    Deskriptor : TCheckBuf;
  End;

Var
  Buff    : TCheckBuf;
  RawBuff : TRawCheckBuf;
  Tries   : Boolean;
Begin
  fISOBookFormat := ybfAuto;
  fImageFormat      := ifAuto;
  fImageOffset      := 0;

  If ( Assigned(fFileStream) ) And ( fFileStream.Size > 16*2048 ) Then
  Begin
    For Tries := False To True Do
    Begin
      If ( Tries ) Then // ok, 2nd run, last try: nero .nrg image file
        fImageOffset := 307200;


    // fFileStream.Position := fImageOffset + 16 * 2048;
    // fFileStream.ReadBuffer(Buff, SizeOf(Buff));
    fFileStream.Seek(fImageOffset + 16 * 2048,soFromBeginning);
      fFileStream.ReadBuffer(Buff, SizeOf(Buff));
      If ( String(Buff.StdID) = 'CD001' ) Then
      Begin
        fImageFormat      := ifOnlyData;
        fISOBookFormat    := ybfMode1;
        Break;
      End;

     // fFileStream.Position := fImageOffset + 16 * 2336;
      fFileStream.Seek(fImageOffset + 16 * 2336,soFromBeginning);
      fFileStream.ReadBuffer(Buff, SizeOf(Buff));

      If ( String(Buff.StdID) = 'CD001' ) Then
      Begin
        fImageFormat      := ifOnlyData;
        fISOBookFormat    := ybfMode2;
        Break;
      End;

      //fFileStream.Position := fImageOffset + 16 * 2352;
      fFileStream.Seek(fImageOffset + 16 * 2352,soFromBeginning);
      fFileStream.ReadBuffer(RawBuff, SizeOf(RawBuff));

      If ( String(RawBuff.Deskriptor.StdID) = 'CD001' ) Then
      Begin
        fImageFormat := ifCompleteSectors;
        If ( RawBuff.Header_Mode = 1 ) Then
             fISOBookFormat    := ybfMode1
        Else If ( RawBuff.Header_Mode = 2 ) Then
             fISOBookFormat    := ybfMode2
        Else
          FLastErrorString := ('Unknown ISO Book mode!');
        Break;
      End;
    End;
  End;

  If ( fImageFormat = ifAuto ) Or ( fISOBookFormat = ybfAuto ) Then
    FLastErrorString := ('Unkown Image Format!');
End;



Function TImageStreamHandler.SeekSector(Const ASector: Cardinal; Const AGrow: Boolean): Boolean;
Var
  lFPos : Integer;
Begin
  Result := False;
  If ( Assigned(fFileStream) ) Then
  Begin
    lFPos := CalcSectorOffset(ASector);
    If ( (lFPos + 2048) > fFileStream.Size ) And ( Not AGrow ) Then
      Exit;

    //fFileStream.Position := lFPos;
    fFileStream.Seek(lFPos,soFromBeginning);
    fCurrentSector := ASector;
  End;
End;



Function TImageStreamHandler.ReadSector_Data(Var ABuffer; Const ABufferSize : Integer = -1): Boolean;
Var
  lDataOffset : Integer;
Begin
  Result := False;
  If ( Assigned(FFileStream) ) Then
  Begin
    lDataOffset := CalcUserDataOffset;
    fFileStream.Seek(lDataOffset, soFromCurrent);
    If ( ABufferSize > -1 ) And ( Cardinal(ABufferSize) < GetSectorDataSize ) Then
         FLastErrorString := ('ReadSector_Data(): buffer overflow protection');
    fFileStream.ReadBuffer(ABuffer, GetSectorDataSize);
    SeekSector(fCurrentSector+1);
    Result := True;
  End;
End;




Function TImageStreamHandler.ReadSector_Raw(Var ABuffer; Const ABufferSize : Integer = -1): Boolean;
Begin
  Result := False;

  If ( Assigned(FFileStream) ) Then
  Begin
    If ( ABufferSize > -1 ) And ( ABufferSize < 2352 ) Then
      FLastErrorString := ('ReadSector_Raw(): buffer overflow protection');
    FFileStream.ReadBuffer(ABuffer, 2352);
    Result := True;
  End;
End;



Function TImageStreamHandler.GetSectorDataSize: Cardinal;
Begin
  Result := 0;
  Case fISOBookFormat Of
    ybfMode1 : Result := 2048;
    ybfMode2 : Result := 2336;
  Else
    FLastErrorString := ('can not figure out sector data size on auto type');
  End;
End;


End.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -