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

📄 dvdimage.pas

📁 用于CD/DVD烧录的Delphi源码,包括source和demo
💻 PAS
📖 第 1 页 / 共 4 页
字号:

  for DirIndex := 0 to ADirEntry.DirectoryCount - 1 do // Rescan directories
  begin
    Dir := ADirEntry.Directories[DirIndex];
    Dir.FillISOData(Primary);
    WriteStructureTree(Primary, ISOStream, Dir);
  end;

  Sector := (FImage.Stream.Position div FImage.SectorDataSize);
  Log('Write Root Structure', 'Current Pos After Structure: ' +
    inttostr(FImage.Stream.Position) + ' : ' + inttohex(FImage.Stream.Position, 6)
    + ' : ' + inttostr(Sector));

  Log('SaveImage',
    '|----------------------------------------------------------|');
end;



procedure TDVDImage.WriteUDFRootStructureTree(ISOStream: TImageStreamHandler; ADirEntry: TDirectoryEntry);
var
  DirIndex, FileIndex, Padd: Integer;
  Dir: TDirectoryEntry;
  UDF_FID : UDF_FileIdentifierDescriptor;
  Fil: TFileEntry;
  TempPchar: PChar;
  TempPWideChr: PWideChar;
  PadByte, FileID: Byte;
  FillBlock: array[0..2047] of Byte;
  WideArray: array[0..127] of byte;
  CurrentLBA, StreamPos, PadIndex: Integer;
  DIRRecSize: Integer;
  Sector: Integer;

begin
  PadByte := $00;
  FillChar(FillBlock, 2048, 0);
  FillChar(UDF_FID, sizeof(UDF_FID), 0);

  Log('Write UDF Root Structure', 'Name : ' + ADirEntry.Name);
  UDF_FID.DescriptorTag.TagIdentifier := TAG_IDENT_FID;
  UDF_FID.DescriptorTag.DescriptorVersion := $0020;
  UDF_FID.DescriptorTag.TagChecksum := $00;
  UDF_FID.DescriptorTag.Reserved := $00;
  UDF_FID.DescriptorTag.TagSerialNumber := $0000;
  UDF_FID.DescriptorTag.DescriptorCRC := $0000;
  UDF_FID.DescriptorTag.DescriptorCRCLength := $0000;
  UDF_FID.DescriptorTag.TagLocation := 265;

  UDF_FID.FileVersionNumber := $0001;
  UDF_FID.FileCharacteristics := $0A;
  UDF_FID.LengthOfFileIdentifier := $00;
  UDF_FID.ICB.ExtentLength := $08000000;
  UDF_FID.ICB.ExtentLocation.LogicalBlockNum := $00000020;
  UDF_FID.ICB.ExtentLocation.PartitionReferenceNum := $0000;

  FileID := 0;
  ISOStream.Stream.Write(UDF_FID, sizeof(UDF_FID));
  ISOStream.Stream.Write(FileID, sizeof(FileID)); // write file identifier

  for DirIndex := 0 to ADirEntry.DirectoryCount - 1 do // write directories
  begin
    Dir := ADirEntry.Directories[DirIndex];
    Dir.FillISOData(true);
    UDF_FID.LengthOfFileIdentifier := Dir.ISOData.LengthOfFileIdentifier;

    ISOStream.Stream.Write(UDF_FID, sizeof(UDF_FID));
    TempPchar := pchar(Dir.Name);
    ISOStream.Stream.Write(TempPchar^, UDF_FID.LengthOfFileIdentifier);
    DIRRecSize := sizeof(UDF_FID) + UDF_FID.LengthOfFileIdentifier;
      // get padding size
    if (DIRRecSize mod 2) > 0 then
      FImage.Stream.Write(PadByte, 1);
  end;

  for FileIndex := 0 to ADirEntry.FileCount - 1 do // write files
  begin
    Fil := ADirEntry.Files[FileIndex];
    Fil.FillISOData(true);

    UDF_FID.LengthOfFileIdentifier := Fil.ISOData.LengthOfFileIdentifier;
    ISOStream.Stream.Write(UDF_FID, sizeof(UDF_FID));
    TempPchar := pchar(Fil.Name);
    ISOStream.Stream.Write(TempPchar^, Fil.ISOData.LengthOfFileIdentifier);
    DIRRecSize := sizeof(UDF_FID) + UDF_FID.LengthOfFileIdentifier;
      // get padding size
    if (DIRRecSize mod 2) > 0 then
      FImage.Stream.Write(PadByte, 1);
  end;

  //pad the remainder of the block
  Padd := 2048 - (ISOstream.Stream.Position mod 2048);
  if Padd < 2048 then
    ISOStream.Stream.Write(FillBlock, Padd);

{  for DirIndex := 0 to ADirEntry.DirectoryCount - 1 do // Rescan directories
  begin
    Dir := ADirEntry.Directories[DirIndex];
    Dir.FillISOData(true);
    WriteUDFStructureTree(true, ISOStream, Dir);
  end;}

  Sector := (FImage.Stream.Position div FImage.SectorDataSize);
  Log('Write Root Structure', 'Current Pos After UDF File Structure: ' +
    inttostr(FImage.Stream.Position) + ' : ' + inttohex(FImage.Stream.Position, 6)
    + ' : ' + inttostr(Sector));

  Log('SaveImage',
    '|----------------------------------------------------------|');
end;


procedure TDVDImage.WriteStructureTree(Primary: Boolean; ISOStream:
  TImageStreamHandler; ADirEntry: TDirectoryEntry);
var
  DirIndex, FileIndex, Padd: Integer;
  Dir: TDirectoryEntry;
  RootDir: TDirectoryrecord;
  Fil: TFileEntry;
  TempPchar: PChar;
  TempPWideChr: PWideChar;
  PadByte, FileID: Byte;
  FillBlock: array[0..2047] of Byte;
  WideArray: array[0..127] of byte;
  CurrentLBA, StreamPos, PadIndex: Integer;
  DIRRecSize: Integer;
  Sector: Integer;

begin
  PadByte := $00;
  FillChar(FillBlock, 2048, 0);
  Log('Write Structure', 'Name : ' + ADirEntry.Name);
  // fill in "." and ".." directory sections (i previosly missed)
  RootDir := ADirEntry.ISOData;
  RootDir.LengthOfDirectoryRecord := $22;
  RootDir.LengthOfFileIdentifier := 1;
  RootDir.FileFlags := $02;
  RootDir.VolumeSequenceNumber := BuildBothEndianWord(1);
  RootDir.LocationOfExtent := ADirEntry.ISOData.LocationOfExtent;
  FileID := $00;
  ISOStream.Stream.Write(RootDir, sizeof(TDirectoryrecord));
  ISOStream.Stream.Write(FileID, sizeof(FileID)); // write file identifier

  if (ADirEntry.Parent = nil) then
    RootDir.LocationOfExtent := ADirEntry.RootISOData.LocationOfExtent
  else
  begin
    ADirEntry.Parent.FillISOData(Primary);
    RootDir.LocationOfExtent := ADirEntry.Parent.ISOData.LocationOfExtent;
  end;
  FileID := $01;
  ISOStream.Stream.Write(RootDir, sizeof(TDirectoryrecord));
  ISOStream.Stream.Write(FileID, sizeof(FileID)); // write file identifier
  // done with "." ".."

  for DirIndex := 0 to ADirEntry.DirectoryCount - 1 do // write directories
  begin
    Dir := ADirEntry.Directories[DirIndex];
    Dir.FillISOData(Primary);
    ISOStream.Stream.Write(Dir.ISOData, sizeof(TDirectoryrecord));
    if Primary = True then
    begin
      TempPchar := pchar(Dir.Name);
      ISOStream.Stream.Write(TempPchar^, Dir.ISOData.LengthOfFileIdentifier);
    end
    else
    begin
      TempPWideChr := Dir.GetWideDirName;
      FillChar(WideArray, 128, 0);
      CopyMemory(@WideArray[1], @TempPWideChr[0],
        (Dir.ISOData.LengthOfFileIdentifier) - 1); //makes it big endian wide char
      ISOStream.Stream.Write(WideArray, Dir.ISOData.LengthOfFileIdentifier);
    end;

    DIRRecSize := sizeof(TDirectoryrecord) + Dir.ISOData.LengthOfFileIdentifier;
      // get padding size
    if (DIRRecSize mod 2) > 0 then
      FImage.Stream.Write(PadByte, 1);
  end;

  for FileIndex := 0 to ADirEntry.FileCount - 1 do // write files
  begin
    Fil := ADirEntry.Files[FileIndex];
    Fil.FillISOData(Primary);
    ISOStream.Stream.Write(Fil.ISOData, sizeof(TDirectoryrecord));
    if Primary = True then
    begin
      TempPchar := pchar(Fil.Name);
      ISOStream.Stream.Write(TempPchar^, Fil.ISOData.LengthOfFileIdentifier);
    end
    else
    begin
      TempPWideChr := Fil.GetWideFileName;
      FillChar(WideArray, 128, 0);
      CopyMemory(@WideArray[1], @TempPWideChr[0],
        (Fil.ISOData.LengthOfFileIdentifier) - 1); //makes it big endian wide char
      ISOStream.Stream.Write(WideArray, Fil.ISOData.LengthOfFileIdentifier);
    end;

    DIRRecSize := sizeof(TDirectoryrecord) + Fil.ISOData.LengthOfFileIdentifier;
      // get padding size
    if (DIRRecSize mod 2) > 0 then
      FImage.Stream.Write(PadByte, 1);
  end;

  //pad the remainder of the block
  Padd := 2048 - (ISOstream.Stream.Position mod 2048);
  if Padd < 2048 then
    ISOStream.Stream.Write(FillBlock, Padd);

  for DirIndex := 0 to ADirEntry.DirectoryCount - 1 do // Rescan directories
  begin
    Dir := ADirEntry.Directories[DirIndex];
    WriteStructureTree(Primary, ISOStream, Dir);
  end;

  Sector := (FImage.Stream.Position div FImage.SectorDataSize);
  Log('Write Structure', 'Current Pos After Structure: ' +
    inttostr(FImage.Stream.Position) + ' : ' + inttohex(FImage.Stream.Position, 6)
    + ' : ' + inttostr(Sector));

  Log('SaveImage',
    '|----------------------------------------------------------|');
end;



procedure TDVDImage.WriteFileData(ISOStream: TImageStreamHandler; ADirEntry:
  TDirectoryEntry);
var
  DirIndex, FileIndex, Padd: Integer;
  Dir: TDirectoryEntry;
  Fil: TFileEntry;
  TempPchar: PChar;
  PadByte: Byte;
  FillBlock: array[0..2047] of Byte;
  CDFile: TfileStream;

begin
  PadByte := 0;
  FillChar(FillBlock, 2048, 0);

  for FileIndex := 0 to ADirEntry.FileCount - 1 do // write files
  begin
    Fil := ADirEntry.Files[FileIndex];
    CDFile := TfileStream.Create(Fil.SourceFileName, fmOpenRead);
    CDFile.Seek(0, soFromBeginning);
    ISOStream.Stream.CopyFrom(CDFile, CDFile.Size);
    CDFile.Free;
  end;

  //pad the remainder of the block
  Padd := 2048 - (ISOstream.Stream.Position mod 2048);
  if Padd < 2048 then
    ISOStream.Stream.Write(FillBlock, Padd);

  for DirIndex := 0 to ADirEntry.DirectoryCount - 1 do // Rescan directories
  begin
    Dir := ADirEntry.Directories[DirIndex];
    WriteFileData(ISOStream, Dir);
  end;
end;



procedure TDVDImage.WritePathTableData(ISOStream: TImageStreamHandler;
  CurrentPointer: Integer);
var
  Index: Integer;
  TempPchar, TempPadChar: Pchar;
  PathRec: PPathTableRecord;
  StreamPos: Integer;
  ReverseByte: Cardinal;
  CurrentStreamPointer, PadBytes, Sector: Integer;
begin
  TempPadChar := $00;
  CurrentStreamPointer := CurrentPointer;
  // write out little endian path table sector 257
  for Index := 0 to FTree.PathTableCount - 1 do
  begin
    PathRec := FTree.LittleEndianPathTable.Items[Index];
    Log('SaveImage', 'Write Dir LPath Name: ' + PathRec^.DirectoryIdentifier);
    FImage.Stream.Write(PathRec^.LengthOfDirectoryIdentifier, 1);
      //ISO Path Table L
    FImage.Stream.Write(PathRec^.ExtendedAttributeRecordLength, 1);
    FImage.Stream.Write(PathRec^.LocationOfExtent, 4); 
    FImage.Stream.Write(PathRec^.ParentDirectoryNumber, 2);
    TempPchar := PathRec^.DirectoryIdentifier;
    FImage.Stream.Write(TempPchar^, PathRec^.LengthOfDirectoryIdentifier);
    if (PathRec^.LengthOfDirectoryIdentifier mod 2) > 0 then
      FImage.Stream.Write(TempPadChar, 1);
  end;
        //Fill Up Gap to DVD size sectors sector 257
  PadBytes := (258 * 2048); // get size
  StreamPos := FImage.Stream.Position;
  PadBytes := (PadBytes - StreamPos); // pad number
  for Index := 1 to PadBytes do
          FImage.Stream.Write(TempPadChar, 1); // pad out sectors

  Sector := (FImage.Stream.Position div FImage.SectorDataSize);
  Log('SaveImage', 'Current Pos After LPath Tables: ' +
    inttostr(FImage.Stream.Position) + ' : ' + inttohex(FImage.Stream.Position, 6)
    + ' : ' + inttostr(Sector));

  CurrentStreamPointer := FImage.Stream.Position;
  Log('SaveImage',
    '|----------------------------------------------------------|');
  // write out big endian path table sector 258
  for Index := 0 to FTree.PathTableCount - 1 do
  begin
    PathRec := FTree.LittleEndianPathTable.Items[Index];
    Log('SaveImage', 'Write Dir MPath Name: ' + PathRec^.DirectoryIdentifier);
    FImage.Stream.Write(PathRec^.LengthOfDirectoryIdentifier, 1);
      //ISO Path Table L
    FImage.Stream.Write(PathRec^.ExtendedAttributeRecordLength, 1);
    FImage.Stream.Write(PathRec^.LocationOfExtentM, 4);
    ReverseByte := SwapWord(PathRec^.ParentDirectoryNumber);
      // reverse to big endian
    FImage.Stream.Write(ReverseByte, 2);
    TempPchar := PathRec^.DirectoryIdentifier;
    FImage.Stream.Write(TempPchar^, PathRec^.LengthOfDirectoryIdentifier);
    if (PathRec^.LengthOfDirectoryIdentifier mod 2) > 0 then
      FImage.Stream.Write(TempPadChar, 1); // padding byte
  end;
   //Fill Up Gap to DVD size sectors sector 258
  PadBytes := (259 * 2048); // get size
  StreamPos := FImage.Stream.Position;
  PadBytes := (PadBytes - StreamPos); // pad number
  for Index := 1 to PadBytes do
          FImage.Stream.Write(TempPadChar, 1); // pad out sectors
  Log('SaveImage',
    '|----------------------------------------------------------|');
  // end of path table
end;

procedure TDVDImage.WriteJolietPathTableData(ISOStream: TImageStreamHandler;
  CurrentPointer: Integer);
var
  Index: Integer;
  TempPchar, TempPadChar: Pchar;
  PathRec: PPathTableRecord;
  StreamPos: Integer;
  ReverseByte: Cardinal;
  SectorOffsett: Integer;
  ReverseOffsett: LongWord;
  CurrentStreamPointer, PadBytes, Sector: Integer;
begin
  TempPadChar := $00;
  SectorOffsett := (FTree.JolietOffsett - FTree.DIRStartLBA);

  CurrentStreamPointer := CurrentPointer;
  // write out little endian path table sector 21
  for Index := 0 to FTree.PathTableCount - 1 do
  begin
    PathRec := FTree.LittleEndianPathTable.Items[Index];
    Log('SaveImage', 'Write Dir Joliet LPath Name: ' +
      PathRec^.DirectoryIdentifierM);
    FImage.Stream.Write(PathRec^.LengthOfDirectoryIdentifierM, 1);
      //ISO Path Table L
    FImage.Stream.Write(PathRec^.ExtendedAttributeRecordLength, 1);
    PathRec^.JolietLocationOfExtent := (PathRec^.LocationOfExtent +
      SectorOffsett);
    FImage.Stream.Write(PathRec^.JolietLocationOfExtent, 4);
    FImage.Stream.Write(PathRec^.ParentDirectoryNumber, 2);
    TempPchar := PathRec^.DirectoryIdentifierM;
    FImage.Stream.Write(TempPchar^, PathRec^.LengthOfDirectoryIdentifierM);
    if (PathRec^.LengthOfDirectoryIdentifierM mod 2) > 0 then
      FImage.Stream.Write(TempPadChar, 1);
  end;
  StreamPos := FImage.Stream.Position;
  PadBytes := 2048 - (StreamPos - CurrentStreamPointer); // pad out to 2048
  for Index := 1 to PadBytes do
    FImage.Stream.Write(TempPadChar, 1);
  Sector := (FImage.Stream.Position div FImage.SectorDataSize);
  Log('SaveImage', 'Current Pos After LPath Tables: ' +
    inttostr(FImage.Stream.Position) + ' : ' + inttohex(FImage.Stream.Position, 6)
    + ' : ' + inttostr(Sector));

⌨️ 快捷键说明

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