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

📄 dvdimage.pas

📁 用于CD/DVD烧录的Delphi源码,包括source和demo
💻 PAS
📖 第 1 页 / 共 4 页
字号:
    '|----------------------------------------------------------|');
    //Fill Up Gap to DVD size sectors sector 257
  PadBytes := (257 * 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


  //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 directory and file tables start with root sector 300 start
  WriteRootStructureTree(True, FImage, FTree.RootDirectory);
  Log('SaveImage', 'Joliet Offsett: ' + inttostr(FTree.JolietOffsett));

  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',
    '|----------------------------------------------------------|');



(* File Set Descriptor (ECMA 167r3 4/14.1) *)
  PopulateUDFFileSetDescriptor(FUDF_FSD,262,FVolID);
  FImage.Stream.Write(FUDF_FSD, sizeof(FUDF_FSD));
  Sector := (FImage.Stream.Position div FImage.SectorDataSize);
  Log('SaveImage', 'File Set Descriptor :' +  inttostr(Sector));
  Log('SaveImage',
    '|----------------------------------------------------------|');
    //Fill Up Gap to DVD size sectors sector 262
  PadBytes := (263 * 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


(* Terminating Descriptor (ECMA 167r3 3/10.9) *)
  PopulateUDFTerminatingDesc(FUDF_TD,263,FVolID);
  FImage.Stream.Write(FUDF_TD, sizeof(FUDF_TD));
  Sector := (FImage.Stream.Position div FImage.SectorDataSize);
  Log('SaveImage', 'Terminating Descriptor  :' +  inttostr(Sector));
  Log('SaveImage',
    '|----------------------------------------------------------|');
      //Fill Up Gap to DVD size sectors sector 263
  PadBytes := (264 * 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



  WriteUDFRootStructureTree(FImage, FTree.RootDirectory);
  CurrentStreamPointer := FImage.Stream.Position;
  Sector := (FImage.Stream.Position div FImage.SectorDataSize);
  Log('SaveImage', 'Current Pos After Write UDF File Data: ' +
    inttostr(FImage.Stream.Position) + ' : ' + inttohex(FImage.Stream.Position, 6)
    + ' : ' + inttostr(Sector));
  Log('SaveImage',
    '|----------------------------------------------------------|');

  //Fill Up Gap to DVD file start 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',
    '|----------------------------------------------------------|');

  PadBytes := (CurrentStreamPointer mod FImage.SectorDataSize); // pad number
  for Index := 1 to PadBytes do
      FImage.Stream.Write(TempPadChar, 1); // pad out sectors


  Sector := (FImage.Stream.Position div FImage.SectorDataSize);
(* Anchor Volume Descriptor Pointer (ECMA 167r3 3/10.2) *)
  PopulateUDFAnchorVolumeDescriptorPointer(FUDF_AVDP,Sector,FVolID);
  FImage.Stream.Write(FUDF_AVDP, sizeof(FUDF_AVDP));
  Sector := (FImage.Stream.Position div FImage.SectorDataSize);
  Log('SaveImage', 'Anchor Volume Descriptor Pointer :' +  inttostr(Sector));
  Log('SaveImage',
    '|----------------------------------------------------------|');
    //Fill Up Gap to DVD size sectors sector 257
  PadBytes := (Sector +1 * 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

  FImage.Free;
  FImage := nil;
  Result := True;
end;





function TDVDImage.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 TDVDImage.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 TDVDImage.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 + -