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

📄 isoimage.pas

📁 用于CD/DVD烧录的Delphi源码,包括source和demo
💻 PAS
📖 第 1 页 / 共 4 页
字号:
    // Log('SaveImage', 'Write ISO Boot Record');

  // write volume set terminator
  FImage.Stream.Write(FVDSTClass, sizeof(FVDSTClass));
    //ISO Volume Set Terminator
  Log('SaveImage', 'Write Volume Set Terminator');

  CurrentStreamPointer := FImage.Stream.Position;
  Sector := (FImage.Stream.Position div FImage.SectorDataSize);
  Log('SaveImage', 'Current Pos After Volume Descriptors: ' +
    inttostr(CurrentStreamPointer) + ' : ' + inttohex(CurrentStreamPointer, 6) +
    ' : ' + inttostr(Sector));
  Log('SaveImage',
    '|----------------------------------------------------------|');

  //write out Primary path table
  WritePathTableData(FImage, CurrentStreamPointer);
  CurrentStreamPointer := FImage.Stream.Position;
  Sector := (FImage.Stream.Position div FImage.SectorDataSize);
  Log('SaveImage', 'Current Pos After Pri Path Tables: ' +
    inttostr(FImage.Stream.Position) + ' : ' + inttohex(FImage.Stream.Position, 6)
    + ' : ' + inttostr(Sector));
  Log('SaveImage',
    '|----------------------------------------------------------|');

  //write out Supplemental path table
  WriteJolietPathTableData(FImage, CurrentStreamPointer);
  CurrentStreamPointer := FImage.Stream.Position;
  Sector := (FImage.Stream.Position div FImage.SectorDataSize);
  Log('SaveImage', 'Current Pos After Sup Path Tables: ' +
    inttostr(FImage.Stream.Position) + ' : ' + inttohex(FImage.Stream.Position, 6)
    + ' : ' + inttostr(Sector));
  Log('SaveImage',
    '|----------------------------------------------------------|');

  // write directory and file tables start with root sector 23 start
  WriteRootStructureTree(True, FImage, FTree.RootDirectory);
  Log('SaveImage', 'Joliet Offsett: ' + inttostr(FTree.JolietOffsett));

  // write Joliet directory and file tables start with FTree.JolietOffsett
  FTree.RefreshPathTables(FTree.JolietOffsett, FileStartBlock);
  FTree.RootDirectory.FillRootISOData(False);
  WriteRootStructureTree(False, FImage, FTree.RootDirectory);

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

  //Fill Up Gap to DVD size sectors
  PadBytes := (FTree.FileStartBlock * 2048); // get size
  CurrentStreamPointer := FImage.Stream.Position; // get current position
  PadBytes := (PadBytes - CurrentStreamPointer); // pad number
  for Index := 1 to PadBytes do
    FImage.Stream.Write(TempPadChar, 1); // pad out sectors
  Log('SaveImage',
    '|----------------------------------------------------------|');

  // load up and write out files data
  WriteFileData(FImage, FTree.RootDirectory);
  CurrentStreamPointer := FImage.Stream.Position;
  Sector := (FImage.Stream.Position div FImage.SectorDataSize);
  Log('SaveImage', 'Current Pos After Write File Data: ' +
    inttostr(FImage.Stream.Position) + ' : ' + inttohex(FImage.Stream.Position, 6)
    + ' : ' + inttostr(Sector));
  Log('SaveImage',
    '|----------------------------------------------------------|');

  FImage.Free;
  Result := True;
end;





function TISOImage.ParseDirectory(const AUsePrimaryVD: Boolean): Boolean;
var
  DirRootSourceRec: TRootDirectoryRecord;
  EndSector: Cardinal;
  DR: PDirectoryRecord;
  SecFileName: string;
  RecordSize: Integer;
  lWorkPtr,
    lBuffer: PByte;
begin
  Result := False;
  //RecordSize := SizeOf(TRootDirectoryRecord);
  RecordSize := SizeOf(TDirectoryRecord);
  if (AUsePrimaryVD) then
  begin
    Log('ParseDirectory', 'Parsing Directory Using Primary Volume Descriptor');
    DirRootSourceRec := fPVDClass.Descriptor.Primary.RootDirectory;
  end
  else
  begin
    Log('ParseDirectory',
      'Parsing Directory Using Supplementary Volume Descriptor...');
    if Assigned(fSVDClass) then
      DirRootSourceRec := fSVDClass.Descriptor.Primary.RootDirectory
    else
    begin
      Log('ParseDirectory', 'No Supplementary Volume Descriptor Found!');
      Log('ParseDirectory', 'Using Primary Volume Descriptor.');
      DirRootSourceRec := fPVDClass.Descriptor.Primary.RootDirectory;
    end;
  end;

  Log('ParseDirectory', 'directory sector ' +
    IntToStr(DirRootSourceRec.LocationOfExtent.LittleEndian));

  EndSector := DirRootSourceRec.LocationOfExtent.LittleEndian +
    (DirRootSourceRec.DataLength.LittleEndian + fImage.SectorDataSize - 1) div
      fImage.SectorDataSize;

  fImage.SeekSector(DirRootSourceRec.LocationOfExtent.LittleEndian);

  GetMem(lBuffer, fImage.SectorDataSize);
  try
    lWorkPtr := lBuffer;
    fImage.ReadSector_Data(lWorkPtr^, fImage.SectorDataSize);

    while (fImage.CurrentSector <= EndSector) do
    begin
      if (fImage.SectorDataSize - (Cardinal(lWorkPtr) - Cardinal(lBuffer))) <
        RecordSize then
      begin
        lWorkPtr := lBuffer;
        fImage.ReadSector_Data(lWorkPtr^, fImage.SectorDataSize);
      end;

      New(DR);
      Move(lWorkPtr^, DR^, RecordSize);
      Inc(lWorkPtr, RecordSize); // move pointer across

      SetLength(SecFileName, DR.LengthOfFileIdentifier);
      Move(lWorkPtr^, SecFileName[1], DR.LengthOfFileIdentifier);
      Inc(lWorkPtr, DR.LengthOfFileIdentifier);

      // padding bytes
      if ((RecordSize + DR.LengthOfFileIdentifier) < DR.LengthOfDirectoryRecord)
        then
        Inc(lWorkPtr, DR.LengthOfDirectoryRecord - RecordSize -
          DR.LengthOfFileIdentifier);

      ParseDirectorySub(FTree.RootDirectory, SecFileName, DR);
    end;
  finally
    FreeMem(lBuffer, fImage.SectorDataSize);
  end;
end;


function TISOImage.ParseDirectorySub(AParentDir: TDirectoryEntry; const
  AFileName: string; var ADirectoryEntry: PDirectoryRecord): Boolean;
var
  EndSector: Cardinal;
  OldPosition: Integer;
  ActDir: TDirectoryEntry;
  FileEntry: TFileEntry;
  DRFileName: string;
  DR: PDirectoryRecord;
  RecordSize: Integer;
  lWorkPtr,
    lBuffer: PByte;
begin
  if (ADirectoryEntry.FileFlags and $2) = $2 then // directory
  begin
    OldPosition := fImage.CurrentSector;
    RecordSize := SizeOf(TDirectoryRecord);
    if (AFileName <> #0) and (AFileName <> #1) then
    begin
      ActDir := TDirectoryEntry.Create(fTree, AParentDir, dsfFromImage);
      ActDir.Name := UnicodeToStr(AFileName);
      ActDir.ISOData := ADirectoryEntry^;
      fImage.SeekSector(ADirectoryEntry.LocationOfExtent.LittleEndian);
      EndSector := ADirectoryEntry.LocationOfExtent.LittleEndian +
        (ADirectoryEntry.DataLength.LittleEndian + fImage.SectorDataSize - 1) div
          fImage.SectorDataSize;

      Dispose(ADirectoryEntry);
      ADirectoryEntry := nil;

      GetMem(lBuffer, fImage.SectorDataSize);
      try
        lWorkPtr := lBuffer;
        fImage.ReadSector_Data(lWorkPtr^, fImage.SectorDataSize);

        while (fImage.CurrentSector <= EndSector) do
        begin
          if (fImage.SectorDataSize - (Cardinal(lWorkPtr) - Cardinal(lBuffer)))
            < RecordSize then
          begin
            lWorkPtr := lBuffer;
            fImage.ReadSector_Data(lWorkPtr^, fImage.SectorDataSize);
          end;

          New(DR);
          Move(lWorkPtr^, DR^, RecordSize);
          Inc(lWorkPtr, RecordSize);

          SetLength(DRFileName, DR.LengthOfFileIdentifier);
          Move(lWorkPtr^, DRFileName[1], DR.LengthOfFileIdentifier);
          Inc(lWorkPtr, DR.LengthOfFileIdentifier);

          // padding bytes
          if ((RecordSize + DR.LengthOfFileIdentifier) <
            DR.LengthOfDirectoryRecord) then
            Inc(lWorkPtr, DR.LengthOfDirectoryRecord - RecordSize -
              DR.LengthOfFileIdentifier);

          ParseDirectorySub(ActDir, DRFileName, DR);
        end;
      finally
        FreeMem(lBuffer, fImage.SectorDataSize);
      end;
    end;

    fImage.SeekSector(OldPosition);
  end
  else
  begin
    if (AFileName <> '') and (ADirectoryEntry.DataLength.LittleEndian > 0) then
    begin
      FileEntry := TFileEntry.Create(AParentDir, dsfFromImage);
      FileEntry.Name := UnicodeToStr(AFileName);
      FileEntry.ISOData := ADirectoryEntry^;
    end;
  end;
  Result := True;
end;

function TISOImage.ParsePathTable(ATreeView: TTreeView): Boolean;
var
  PathTableEntry: TPathTableRecord;
  FileName: string;
  SectorCount: Cardinal;
  Node: TTreeNode;
  PathTabelEntryNumber: Integer;
  lWorkPtr,
    lBuffer: PByte;
  i: Integer;
  IDLength: Integer;

  function FindParent(const AParentPathNumber: Integer): TTreeNode;
  begin
    Result := ATreeView.Items.GetFirstNode;
    while (Integer(Result.Data) <> AParentPathNumber) do
      Result := Result.GetNext;
  end;

begin
  Result := False;

  Log('ParsePathTable', 'path table first sector ' +
    IntToStr(fPVDClass.Descriptor.Primary.LocationOfTypeLPathTable));
  Log('ParsePathTable', 'path table length ' +
    IntToStr(fPVDClass.Descriptor.Primary.PathTableSize.LittleEndian) + ' bytes');

  if (Assigned(ATreeView)) then
    ATreeView.Items.Clear;

  SectorCount := (fPVDClass.Descriptor.Primary.PathTableSize.LittleEndian +
    fImage.SectorDataSize - 1) div fImage.SectorDataSize;

  fImage.SeekSector(fPVDClass.Descriptor.Primary.LocationOfTypeLPathTable);

  GetMem(lBuffer, SectorCount * fImage.SectorDataSize);
  lWorkPtr := lBuffer;
  try
    PathTabelEntryNumber := 0;

    for i := 1 to SectorCount do
    begin
      fImage.ReadSector_Data(lWorkPtr^, fImage.SectorDataSize);
      Inc(lWorkPtr, fImage.SectorDataSize);
    end;

    lWorkPtr := lBuffer;

    repeat
      FillChar(PathTableEntry, sizeof(PathTableEntry), 0);
      Move(lWorkPtr^, PathTableEntry.LengthOfDirectoryIdentifier, 1);
      Inc(lWorkPtr, 1);
      Move(lWorkPtr^, PathTableEntry.ExtendedAttributeRecordLength, 1);
      Inc(lWorkPtr, 1);
      Move(lWorkPtr^, PathTableEntry.LocationOfExtent, 4);
      Inc(lWorkPtr, 4);
      Move(lWorkPtr^, PathTableEntry.ParentDirectoryNumber, 2);
      Inc(lWorkPtr, 2);
      Move(lWorkPtr^, PathTableEntry.DirectoryIdentifier,
        PathTableEntry.LengthOfDirectoryIdentifier);
      Inc(lWorkPtr, PathTableEntry.LengthOfDirectoryIdentifier);

      FileName := PathTableEntry.DirectoryIdentifier;

      if (Odd(PathTableEntry.LengthOfDirectoryIdentifier)) then
        Inc(lWorkPtr, 1);

      Inc(PathTabelEntryNumber);

      if (PathTableEntry.LengthOfDirectoryIdentifier = 1) then
      begin
        if (Assigned(ATreeView)) and (PathTabelEntryNumber = 1) then
        begin
          Node := ATreeView.Items.AddChild(nil, '/');
          Node.Data := Pointer(PathTabelEntryNumber);
        end;
      end
      else
      begin
        if (Assigned(ATreeView)) then
        begin
          Node := ATreeView.Items.AddChild(FindParent(PathTableEntry.ParentDirectoryNumber), FileName);
          Node.Data := Pointer(PathTabelEntryNumber);
        end;
      end;
    until ((Cardinal(lWorkPtr) - Cardinal(lBuffer)) >=
      (fPVDClass.Descriptor.Primary.PathTableSize.LittleEndian - 2));
  finally
    FreeMem(lBuffer, SectorCount * fImage.SectorDataSize);
  end;
end;

end.

⌨️ 快捷键说明

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