📄 dvdimage.pas
字号:
'|----------------------------------------------------------|');
//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 + -