📄 dvdimage.pas
字号:
CurrentStreamPointer := FImage.Stream.Position;
Log('SaveImage',
'|----------------------------------------------------------|');
// write out big endian path table sector 22
for Index := 0 to FTree.PathTableCount - 1 do
begin
PathRec := FTree.LittleEndianPathTable.Items[Index];
Log('SaveImage', 'Write Dir Joliet MPath Name: ' +
PathRec^.DirectoryIdentifierM[0]);
FImage.Stream.Write(PathRec^.LengthOfDirectoryIdentifierM, 1);
//ISO Path Table L
FImage.Stream.Write(PathRec^.ExtendedAttributeRecordLength, 1);
PathRec^.JolietLocationOfExtentM :=
SwapDWord(PathRec^.JolietLocationOfExtent);
FImage.Stream.Write(PathRec^.JolietLocationOfExtentM, 4);
ReverseByte := SwapWord(PathRec^.ParentDirectoryNumber);
// reverse to big endian
FImage.Stream.Write(ReverseByte, 2);
TempPchar := PathRec^.DirectoryIdentifierM;
FImage.Stream.Write(TempPchar^, PathRec^.LengthOfDirectoryIdentifierM);
if (PathRec^.LengthOfDirectoryIdentifierM mod 2) > 0 then
FImage.Stream.Write(TempPadChar, 1); // padding byte
end;
StreamPos := FImage.Stream.Position;
PadBytes := 2048 - (StreamPos - CurrentStreamPointer); // pad out to 2048
for Index := 1 to PadBytes do
FImage.Stream.Write(TempPadChar, 1);
Log('SaveImage',
'|----------------------------------------------------------|');
// end of path table
end;
function TDVDImage.SaveDVDImageToDisk: Boolean;
var
StreamPos: Integer;
StartLBA, FileStartBlock: Integer;
TempPchar, TempPadChar: Pchar;
TempString: string;
ReverseByte: Cardinal;
Index: Integer;
PathRec: PPathTableRecord;
CurrentStreamPointer, PadBytes, Sector: Integer;
begin
Result := False;
TempPadChar := $00;
Sector := 0;
StartLBA := 258;
FileStartBlock := 300;
if FFileName = '' then
begin
Log('SaveImage', 'No Filename Entered!');
exit;
end;
FImage := TImageStreamHandler.Create(FFileName, ybfMode1, ifCompleteSectors);
if (FImage.ISOBookFormat = ybfMode1) then
Log('SaveImage', 'DVD Video mode 1')
else if (FImage.ISOBookFormat = ybfMode2) then
Log('SaveImage', 'DVD Video mode 2');
Log('SaveImage', 'User data sector size is ' + IntToStr(FImage.SectorDataSize)
+ ' bytes');
Log('SaveImage', 'Image data offset in image file is ' +
IntToStr(FImage.ImageOffset) + ' bytes');
if (FImage.SectorDataSize <> 2048) then
begin
Log('SaveImage',
'sorry, but sector size other than 2048 bytes are not yet supported...');
Exit;
end;
// Setup Directory tree and path tables (move to 256 for dvd video)
FTree.RefreshPathTables(StartLBA, FileStartBlock);
FTree.SortDirectories;
Log('SaveImage', 'Refresh Path Tables');
// Setup Root Directory tree and Fill Data
FTree.RootDirectory.FillRootISOData(True);
FTree.RootDirectory.SetupRootDirectoryLocationOfExtent(FTree.RootDirectory.StartLBA);
Log('SaveImage', 'Fill Root Directory Data');
// Start writing image data to file
Log('SaveImage',
'|----------------------------------------------------------|');
FImage.Stream.Write(FISOHeader, sizeof(FISOHeader)); //ISO Header 32k
Sector := (FImage.Stream.Position div FImage.SectorDataSize);
Log('SaveImage', 'Write ISO Header : ' + inttostr(Sector));
Log('SaveImage',
'|----------------------------------------------------------|');
//setup primary volume descriptor
FPVDClass.VolumeIdentifier := FVolID;
FPVDClass.VolumeSpaceSize := BuildBothEndianDWord(FTree.FileLBA + FTree.FileBlocks);
FPVDClass.PathTableSize := BuildBothEndianDWord(FTree.PathTableLength);
copymemory(@FPVDClass.Descriptor.Primary.RootDirectory,
@FTree.RootDirectory.RootISOData, sizeof(TRootDirectoryRecord));
FImage.Stream.Write(FPVDClass.Descriptor, sizeof(FPVDClass.Descriptor));
//ISO Primary Volume Descriptor
Sector := (FImage.Stream.Position div FImage.SectorDataSize);
Log('SaveImage', 'Write ISO Primary Volume Descriptor : ' + inttostr(Sector));
Log('SaveImage',
'|----------------------------------------------------------|');
// write volume set terminator
FImage.Stream.Write(FVDSTClass, sizeof(FVDSTClass));
//ISO Volume Set Terminator
Log('SaveImage', 'Write Volume Set Terminator');
Log('SaveImage',
'|----------------------------------------------------------|');
(* UDF Beginning Extended Area Descriptor (ECMA 167r3 2/9.2) *)
FImage.Stream.Write(FUDFBEA01, sizeof(FUDFBEA01));
Sector := (FImage.Stream.Position div FImage.SectorDataSize);
Log('SaveImage', 'Beginning Extended Area Descriptor :' + inttostr(Sector));
Log('SaveImage',
'|----------------------------------------------------------|');
(* UDF NSR Descriptor (ECMA 167r3 3/9.1) *)
FImage.Stream.Write(FUDFNSR02, sizeof(FUDFNSR02));
Sector := (FImage.Stream.Position div FImage.SectorDataSize);
Log('SaveImage', 'NSR Descriptor :' + inttostr(Sector));
Log('SaveImage',
'|----------------------------------------------------------|');
(* UDF Terminating Extended Area Descriptor (ECMA 167r3 2/9.3) *)
FImage.Stream.Write(FUDFTEA01, sizeof(FUDFTEA01));
Sector := (FImage.Stream.Position div FImage.SectorDataSize);
Log('SaveImage', 'Terminating Extended Area Descriptor :' + inttostr(Sector));
Log('SaveImage',
'|----------------------------------------------------------|');
//Fill Up Gap to DVD size sectors sector 32
PadBytes := (32 * 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',
'|----------------------------------------------------------|');
//MICRO UDF VOLUME DESCRIPTORS ????
//PRIMARY FIRST ??
(* Primary Volume Descriptor (ECMA 167r3 3/10.1) *)
PopulateUDFPrimaryVolumeDescriptor(FUDF_PVD,32,FVolID);
FImage.Stream.Write(FUDF_PVD, sizeof(FUDF_PVD));
Sector := (FImage.Stream.Position div FImage.SectorDataSize);
Log('SaveImage', 'UDF Primary Volume Descriptor :' + inttostr(Sector));
Log('SaveImage',
'|----------------------------------------------------------|');
//Fill Up Gap to DVD size sectors sector 32
PadBytes := (33 * 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
(* Implementation Use Volume Descriptor (ECMA 167r3 3/10.4) *)
PopulateUDFImplementationUseVolumeDescriptor(FUDF_IUVD,33,FVolID);
FImage.Stream.Write(FUDF_IUVD, sizeof(FUDF_IUVD));
Sector := (FImage.Stream.Position div FImage.SectorDataSize);
Log('SaveImage', 'UDF Implementation Use Volume Descriptor :' + inttostr(Sector));
Log('SaveImage',
'|----------------------------------------------------------|');
//Fill Up Gap to DVD size sectors sector 33
PadBytes := (34 * 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
(* Partition Descriptor (ECMA 167r3 3/10.5) *)
PopulateUDFPartitionDescriptor(FUDF_PD,34,FVolID);
FImage.Stream.Write(FUDF_PD, sizeof(FUDF_PD));
Sector := (FImage.Stream.Position div FImage.SectorDataSize);
Log('SaveImage', 'UDF Partition Descriptor :' + inttostr(Sector));
Log('SaveImage',
'|----------------------------------------------------------|');
//Fill Up Gap to DVD size sectors sector 34
PadBytes := (35 * 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
(* Logical Volume Descriptor (ECMA 167r3 3/10.6) *)
PopulateUDFlogicalVolDesc(FUDF_LVD,35,FVolID);
FImage.Stream.Write(FUDF_LVD, sizeof(FUDF_LVD));
Sector := (FImage.Stream.Position div FImage.SectorDataSize);
Log('SaveImage', 'Logical Volume Descriptor :' + inttostr(Sector));
Log('SaveImage',
'|----------------------------------------------------------|');
//Fill Up Gap to DVD size sectors sector 35
PadBytes := (36 * 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
(* Unallocated Space Descriptor (ECMA 167r3 3/10.8) *)
PopulateUDFUnallocSpaceDesc(FUDF_USD,36,FVolID);
FImage.Stream.Write(FUDF_USD, sizeof(FUDF_USD));
Sector := (FImage.Stream.Position div FImage.SectorDataSize);
Log('SaveImage', 'Unallocated Space Descriptor :' + inttostr(Sector));
Log('SaveImage',
'|----------------------------------------------------------|');
//Fill Up Gap to DVD size sectors sector 36
PadBytes := (37 * 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,37,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 37
PadBytes := (48 * 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
(* Primary Volume Descriptor (ECMA 167r3 3/10.1) *)
PopulateUDFPrimaryVolumeDescriptor(FUDF_PVD,48,FVolID);
FImage.Stream.Write(FUDF_PVD, sizeof(FUDF_PVD));
Sector := (FImage.Stream.Position div FImage.SectorDataSize);
Log('SaveImage', 'UDF Primary Volume Descriptor :' + inttostr(Sector));
Log('SaveImage',
'|----------------------------------------------------------|');
//Fill Up Gap to DVD size sectors sector 256
PadBytes := (49 * 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
(* Implementation Use Volume Descriptor (ECMA 167r3 3/10.4) *)
PopulateUDFImplementationUseVolumeDescriptor(FUDF_IUVD,49,FVolID);
FImage.Stream.Write(FUDF_IUVD, sizeof(FUDF_IUVD));
Sector := (FImage.Stream.Position div FImage.SectorDataSize);
Log('SaveImage', 'UDF Implementation Use Volume Descriptor :' + inttostr(Sector));
Log('SaveImage',
'|----------------------------------------------------------|');
//Fill Up Gap to DVD size sectors sector 49
PadBytes := (50 * 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
(* Partition Descriptor (ECMA 167r3 3/10.5) *)
PopulateUDFPartitionDescriptor(FUDF_PD,50,FVolID);
FImage.Stream.Write(FUDF_PD, sizeof(FUDF_PD));
Sector := (FImage.Stream.Position div FImage.SectorDataSize);
Log('SaveImage', 'UDF Partition Descriptor :' + inttostr(Sector));
Log('SaveImage',
'|----------------------------------------------------------|');
//Fill Up Gap to DVD size sectors sector 34
PadBytes := (51 * 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
(* Logical Volume Descriptor (ECMA 167r3 3/10.6) *)
PopulateUDFlogicalVolDesc(FUDF_LVD,51,FVolID);
FImage.Stream.Write(FUDF_LVD, sizeof(FUDF_LVD));
Sector := (FImage.Stream.Position div FImage.SectorDataSize);
Log('SaveImage', 'Logical Volume Descriptor :' + inttostr(Sector));
Log('SaveImage',
'|----------------------------------------------------------|');
//Fill Up Gap to DVD size sectors sector 35
PadBytes := (52 * 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
(* Unallocated Space Descriptor (ECMA 167r3 3/10.8) *)
PopulateUDFUnallocSpaceDesc(FUDF_USD,52,FVolID);
FImage.Stream.Write(FUDF_USD, sizeof(FUDF_USD));
Sector := (FImage.Stream.Position div FImage.SectorDataSize);
Log('SaveImage', 'Unallocated Space Descriptor :' + inttostr(Sector));
Log('SaveImage',
'|----------------------------------------------------------|');
//Fill Up Gap to DVD size sectors sector 36
PadBytes := (53 * 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,53,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 37
PadBytes := (64 * 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
{64 - 65}
(* Logical Volume Integrity Descriptor (ECMA 167r3 3/10.10) *)
FTree.ResetAllCounts;
PopulateUDFlogicalVolumeIntegrityDesc(FUDF_LVID,64,FTree.TotalFileCount,FTree.TotalDirCount);
FImage.Stream.Write(FUDF_LVID, sizeof(FUDF_LVID));
Sector := (FImage.Stream.Position div FImage.SectorDataSize);
Log('SaveImage', 'Logical Volume Integrity Descriptor :' + inttostr(Sector));
Log('SaveImage',
'|----------------------------------------------------------|');
//Fill Up Gap to DVD size sectors sector 64
PadBytes := (65 * 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,65,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 256
PadBytes := (256 * 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
(* Anchor Volume Descriptor Pointer (ECMA 167r3 3/10.2) *)
PopulateUDFAnchorVolumeDescriptorPointer(FUDF_AVDP,256,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',
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -