📄 isoimage.pas
字号:
// 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 + -