ISO9660StreamHandler.pas
上传用户:wanyu_2000
上传日期:2021-02-21
资源大小:527k
文件大小:9k
源码类别:

DVD

开发平台:

Delphi

  1. {-----------------------------------------------------------------------------
  2.  Unit Name: ISO9660StreamHandler
  3.  Author:    Daniel Mann / Thomas Koos (original class) Dancemammal
  4.  Purpose:   Image File Handler
  5.  History:   Code originally from Daniel Mann / Thomas Koos
  6. -----------------------------------------------------------------------------}
  7. Unit ISO9660StreamHandler;
  8. Interface
  9. Uses
  10.   Classes,CDBufferedStream;
  11. Type
  12.   TISOBookFormat = (ybfAuto, ybfMode1, ybfMode2);
  13.   TISOImageFormat = (ifAuto, ifCompleteSectors, ifOnlyData);
  14.   TImageStreamHandler = Class
  15.   Private
  16.     fISOBookFormat    : TISOBookFormat;
  17.     fImageFormat      : TISOImageFormat;
  18.     fImageOffset      : Cardinal; // e.g. used by Nero Images
  19.     fFileStream       : TCDBufferedStream;
  20.     fCurrentSector    : Cardinal;
  21.     FLastErrorString  : String;
  22.   Protected
  23.     Procedure    DetectImageType; Virtual;
  24.     Function     CalcSectorOffset(Const ASector : Cardinal): Integer; Virtual;
  25.     Function     CalcUserDataOffset: Integer; Virtual;
  26.     Function     GetSectorDataSize: Cardinal; Virtual;
  27.   Public
  28.     Constructor  Create(Const AFileName : String; Const AImageFormat : TISOImageFormat); Overload; Virtual;
  29.     Constructor  Create(Const ANewFileName : String; Const ABookFormat : TISOBookFormat; Const AImageFormat : TISOImageFormat); Overload; Virtual;
  30.     Destructor   Destroy; Override;
  31.     Function     SeekSector(Const ASector : Cardinal; Const AGrow : Boolean = True): Boolean; Virtual;
  32.     Function     ReadSector_Data(Var ABuffer; Const ABufferSize : Integer = -1): Boolean; Virtual;
  33.     Function     ReadSector_Raw (Var ABuffer; Const ABufferSize : Integer = -1): Boolean; Virtual;
  34.     Function     GetLastError : String;
  35.   Published
  36.     Property     ISOBookFormat    : TISOBookFormat         Read  fISOBookFormat;
  37.     Property     ImageFormat      : TISOImageFormat        Read  fImageFormat;
  38.     Property     ImageOffset      : Cardinal               Read  fImageOffset;
  39.     Property     SectorDataSize   : Cardinal               Read  GetSectorDataSize;
  40.     Property     CurrentSector    : Cardinal               Read  fCurrentSector;
  41.     Property     Stream           : TCDBufferedStream      Read  fFileStream;
  42.   End;
  43. Implementation
  44. Uses
  45.   SysUtils; // for FileExists()
  46. Function TImageStreamHandler.GetLastError : String;
  47. begin
  48.    Result := FLastErrorString;
  49. end;
  50. Constructor TImageStreamHandler.Create(Const AFileName: String; Const AImageFormat: TISOImageFormat);
  51. Begin
  52.   Inherited Create;
  53.   If ( Not FileExists(AFileName) ) Then
  54.   begin
  55.      FLastErrorString := 'ISO Image file not found, Creating';
  56.      exit;
  57.   end
  58.   else
  59.   fFileStream := TCDBufferedStream.Create(AFileName,fmOpenRead);
  60.   DetectImageType;
  61.   SeekSector(fCurrentSector);
  62. End;
  63. Constructor TImageStreamHandler.Create(Const ANewFileName : String; Const ABookFormat: TISOBookFormat; Const AImageFormat: TISOImageFormat);
  64. Begin
  65.   Inherited Create;
  66.   If ( ABookFormat = ybfAuto ) Then FLastErrorString := 'ISO Image book format has to be defined!';
  67.   If ( AImageFormat = ifAuto ) Then FLastErrorString := 'Image format has to be defined!';
  68.   fISOBookFormat     := ABookFormat;
  69.   FImageFormat       := AImageFormat;
  70.   FImageOffset       := 0;
  71.   fFileStream := TCDBufferedStream.Create(ANewFileName,fmCreate);
  72.   SeekSector(fCurrentSector);
  73. End;
  74. Destructor TImageStreamHandler.Destroy;
  75. Begin
  76.   If ( Assigned(fFileStream) ) Then FreeAndNil(fFileStream);
  77.   Inherited;
  78. End;
  79. Function TImageStreamHandler.CalcUserDataOffset: Integer;
  80. Begin
  81.   Result := 0;
  82.   Case fImageFormat Of
  83.     ifCompleteSectors  : Result := 16; // 12 bytes SYNC, 4 byte Header
  84.     ifOnlyData         : Result := 0;
  85.     ifAuto             : FLastErrorString := 'can not calculate sector offset with auto values!';
  86.   Else
  87.     FLastErrorString := 'TImageStreamHandler.CalcUserDataOffset(): Implementation error!';
  88.   End;
  89. End;
  90. Function TImageStreamHandler.CalcSectorOffset(Const ASector: Cardinal): Integer;
  91. Begin
  92.   Result := 0;
  93.   Case fImageFormat Of
  94.     ifCompleteSectors : Result := fImageOffset + ASector * 2352;
  95.     ifOnlyData        :
  96.       Begin
  97.         Case fISOBookFormat Of
  98.           ybfMode1 : Result := fImageOffset + ASector * 2048;
  99.           ybfMode2 : Result := fImageOffset + ASector * 2336;
  100.           ybfAuto  : FLastErrorString := ('can not calculate sector with auto settings');
  101.         Else
  102.           FLastErrorString := ('TImageStreamHandler.CalcSectorOffset(): Implementation error!');
  103.         End;
  104.       End;
  105.     ifAuto : FLastErrorString := ('can not calculate sector with auto settings');
  106.   Else
  107.     FLastErrorString := ('TImageStreamHandler.CalcSectorOffset(): Implementation error!');
  108.   End;
  109. End;
  110. Procedure TImageStreamHandler.DetectImageType;
  111. Type
  112.   TCheckBuf = Packed Record
  113.     DeskID : Byte;
  114.     StdID  : Array[0..4] Of Char;
  115.   End;
  116.   TRawCheckBuf = Packed Record
  117.     SYNC   : Array[0..11] of Byte;
  118.     Header_SectMin,
  119.     Header_SectSec,
  120.     Header_SectNo,
  121.     Header_Mode    : Byte;
  122.     Deskriptor : TCheckBuf;
  123.   End;
  124. Var
  125.   Buff    : TCheckBuf;
  126.   RawBuff : TRawCheckBuf;
  127.   Tries   : Boolean;
  128. Begin
  129.   fISOBookFormat := ybfAuto;
  130.   fImageFormat      := ifAuto;
  131.   fImageOffset      := 0;
  132.   If ( Assigned(fFileStream) ) And ( fFileStream.Size > 16*2048 ) Then
  133.   Begin
  134.     For Tries := False To True Do
  135.     Begin
  136.       If ( Tries ) Then // ok, 2nd run, last try: nero .nrg image file
  137.         fImageOffset := 307200;
  138.     // fFileStream.Position := fImageOffset + 16 * 2048;
  139.     // fFileStream.ReadBuffer(Buff, SizeOf(Buff));
  140.     fFileStream.Seek(fImageOffset + 16 * 2048,soFromBeginning);
  141.       fFileStream.ReadBuffer(Buff, SizeOf(Buff));
  142.       If ( String(Buff.StdID) = 'CD001' ) Then
  143.       Begin
  144.         fImageFormat      := ifOnlyData;
  145.         fISOBookFormat    := ybfMode1;
  146.         Break;
  147.       End;
  148.      // fFileStream.Position := fImageOffset + 16 * 2336;
  149.       fFileStream.Seek(fImageOffset + 16 * 2336,soFromBeginning);
  150.       fFileStream.ReadBuffer(Buff, SizeOf(Buff));
  151.       If ( String(Buff.StdID) = 'CD001' ) Then
  152.       Begin
  153.         fImageFormat      := ifOnlyData;
  154.         fISOBookFormat    := ybfMode2;
  155.         Break;
  156.       End;
  157.       //fFileStream.Position := fImageOffset + 16 * 2352;
  158.       fFileStream.Seek(fImageOffset + 16 * 2352,soFromBeginning);
  159.       fFileStream.ReadBuffer(RawBuff, SizeOf(RawBuff));
  160.       If ( String(RawBuff.Deskriptor.StdID) = 'CD001' ) Then
  161.       Begin
  162.         fImageFormat := ifCompleteSectors;
  163.         If ( RawBuff.Header_Mode = 1 ) Then
  164.              fISOBookFormat    := ybfMode1
  165.         Else If ( RawBuff.Header_Mode = 2 ) Then
  166.              fISOBookFormat    := ybfMode2
  167.         Else
  168.           FLastErrorString := ('Unknown ISO Book mode!');
  169.         Break;
  170.       End;
  171.     End;
  172.   End;
  173.   If ( fImageFormat = ifAuto ) Or ( fISOBookFormat = ybfAuto ) Then
  174.     FLastErrorString := ('Unkown Image Format!');
  175. End;
  176. Function TImageStreamHandler.SeekSector(Const ASector: Cardinal; Const AGrow: Boolean): Boolean;
  177. Var
  178.   lFPos : Integer;
  179. Begin
  180.   Result := False;
  181.   If ( Assigned(fFileStream) ) Then
  182.   Begin
  183.     lFPos := CalcSectorOffset(ASector);
  184.     If ( (lFPos + 2048) > fFileStream.Size ) And ( Not AGrow ) Then
  185.       Exit;
  186.     //fFileStream.Position := lFPos;
  187.     fFileStream.Seek(lFPos,soFromBeginning);
  188.     fCurrentSector := ASector;
  189.   End;
  190. End;
  191. Function TImageStreamHandler.ReadSector_Data(Var ABuffer; Const ABufferSize : Integer = -1): Boolean;
  192. Var
  193.   lDataOffset : Integer;
  194. Begin
  195.   Result := False;
  196.   If ( Assigned(FFileStream) ) Then
  197.   Begin
  198.     lDataOffset := CalcUserDataOffset;
  199.     fFileStream.Seek(lDataOffset, soFromCurrent);
  200.     If ( ABufferSize > -1 ) And ( Cardinal(ABufferSize) < GetSectorDataSize ) Then
  201.          FLastErrorString := ('ReadSector_Data(): buffer overflow protection');
  202.     fFileStream.ReadBuffer(ABuffer, GetSectorDataSize);
  203.     SeekSector(fCurrentSector+1);
  204.     Result := True;
  205.   End;
  206. End;
  207. Function TImageStreamHandler.ReadSector_Raw(Var ABuffer; Const ABufferSize : Integer = -1): Boolean;
  208. Begin
  209.   Result := False;
  210.   If ( Assigned(FFileStream) ) Then
  211.   Begin
  212.     If ( ABufferSize > -1 ) And ( ABufferSize < 2352 ) Then
  213.       FLastErrorString := ('ReadSector_Raw(): buffer overflow protection');
  214.     FFileStream.ReadBuffer(ABuffer, 2352);
  215.     Result := True;
  216.   End;
  217. End;
  218. Function TImageStreamHandler.GetSectorDataSize: Cardinal;
  219. Begin
  220.   Result := 0;
  221.   Case fISOBookFormat Of
  222.     ybfMode1 : Result := 2048;
  223.     ybfMode2 : Result := 2336;
  224.   Else
  225.     FLastErrorString := ('can not figure out sector data size on auto type');
  226.   End;
  227. End;
  228. End.