DiscInfo.pas
上传用户:wanyu_2000
上传日期:2021-02-21
资源大小:527k
文件大小:10k
源码类别:

DVD

开发平台:

Delphi

  1. {-----------------------------------------------------------------------------
  2.  Unit Name: DiscInfo
  3.  Author:    Paul Fisher / Andrew Semack
  4.  Purpose:   Class for CD / DVD disk information
  5.  History:
  6. -----------------------------------------------------------------------------}
  7. unit DiscInfo;
  8. interface
  9. uses
  10.   Windows, Classes, SysUtils, SCSIDefs, DeviceTypes, CDDAText, DiskCDDBInfo,
  11.     SCSIUnit, SCSITypes, CovertFuncs, Resources;
  12. type
  13.   TDiscInfo = class
  14.   private
  15.     FLastError: TScsiError;
  16.     FDefaults: TScsiDefaults;
  17.     FInfoRecord: PCDBurnerInfo;
  18.     FDiscLayout: TDiscLayout;
  19.     FCDText: TCDDAText;
  20.     FCDDBQuery: TCDDBQuery;
  21.     FDeviceDiscType: TScsiProfileDeviceDiscTypes;
  22.     FEmptyDisk: Boolean;
  23.     FISAudioDisk : Boolean;
  24.     function GetBurnerInfo: TCDBurnerInfo;
  25.     function GetCDText: TCDDAText;
  26.     function GetDiscType: TScsiProfileDeviceDiscTypes;
  27.     function GetIsErasable: boolean;
  28.     function GetLastTrack: integer;
  29.     function GetTOC: TScsiTOC;
  30.     function GetCDDBInfo: TCDDBQuery;
  31.     function GetLayout: TDiscLayout;
  32.     function GetSessions: TScsiSessionInfo;
  33.     function GetCapacity: integer;
  34.     function GetFormatCapacity: TFormatCapacity;
  35.     function GetISRC(TrackNumber: integer): TScsiISRC;
  36.     function GetSectorType(aLBA: integer): TScsiReadCdSectorType;
  37.     function GetTrackInfo(ATrack: Byte): TTrackInformation;
  38.     function GetDVDescriptor: TScsiDVDLayerDescriptorInfo;
  39.     procedure RefreshDiskLayout;
  40.   protected
  41.     property BurnerInfo: TCDBurnerInfo read GetBurnerInfo;
  42.   public
  43.     constructor Create(InfoRecord: PCDBurnerInfo);
  44.     destructor Destroy; override;
  45.     Procedure RefreshInfo;
  46.     function CDDB_ID: string;
  47.     procedure CreateCUEFile(ISOFileName, CUEFileName: string);
  48.     property IsAudioDisk: boolean read FISAudioDisk;
  49.     property IsErasable: boolean read GetIsErasable;
  50.     property DiscType: TScsiProfileDeviceDiscTypes read GetDiscType;
  51.     property LastTrack: integer read GetLastTrack;
  52.     property TOC: TScsiTOC read GetTOC;
  53.     property DiscLayout: TDiscLayout read GetLayout;
  54.     property Sessions: TScsiSessionInfo read GetSessions;
  55.     property Capacity: integer read GetCapacity;
  56.     property CDText: TCDDAText read GetCDText;
  57.     property CDDBInformation: TCDDBQuery read GetCDDBInfo;
  58.     property FormatCapacity: TFormatCapacity read GetFormatCapacity;
  59.     property SectorType[aLBA: integer]: TScsiReadCdSectorType read
  60.       GetSectorType;
  61.     property ISRC[TrackNumber: integer]: TScsiISRC read GetISRC;
  62.     property TrackInformation[ATrack: Byte]: TTrackInformation read
  63.       GetTrackInfo;
  64.     property DVDescriptor: TScsiDVDLayerDescriptorInfo read GetDVDescriptor;
  65.   end;
  66. implementation
  67. { TDiscInfo }
  68. { TODO : There should be implemenation to detect current inseted disk propertiies }
  69. { TODO : Need to implement cd door close then check for disk : getdisktype}
  70. constructor TDiscInfo.Create(InfoRecord: PCDBurnerInfo);
  71. begin
  72.   FinfoRecord := InfoRecord;
  73.   FDefaults := SCSI_DEF;
  74.   FCDDBQuery := TCDDBQuery.Create;
  75.   FCDText := TCDDAText.Create;
  76.   RefreshInfo;
  77. end;
  78. destructor TDiscInfo.Destroy;
  79. begin
  80.   FCDDBQuery.Free;
  81.   FCDText.Free;
  82. end;
  83. function TDiscInfo.GetBurnerInfo: TCDBurnerInfo;
  84. begin
  85.   Result := FInfoRecord^;
  86. end;
  87. Procedure TDiscInfo.RefreshInfo;
  88. begin
  89.    FDeviceDiscType := GetDiscType;
  90.    FISAudioDisk := False;
  91.    FEmptyDisk := False;
  92.    if (TOC.TrackCount < 1) then FEmptyDisk := True;
  93.    if (ssqfAudioTrack in TOC.Tracks[0].Flags) then FISAudioDisk := True;
  94. End;
  95. function TDiscInfo.GetCapacity: integer;
  96. var
  97.   temp: cardinal;
  98. begin
  99.   FLastError := SCSIreadCapacity(BurnerInfo, temp, fDefaults);
  100.   Result := Temp;
  101. end;
  102. function TDiscInfo.GetDiscType: TScsiProfileDeviceDiscTypes;
  103. begin
  104.   FLastError := SCSIGetDevConfigProfileMedia(BurnerInfo, Result, fDefaults);
  105. end;
  106. function TDiscInfo.GetFormatCapacity: TFormatCapacity;
  107. begin
  108.   FLastError := SCSIReadFormatCapacity(BurnerInfo, Result, fDefaults);
  109. end;
  110. function TDiscInfo.GetIsErasable: boolean;
  111. begin
  112.   Result := False;
  113. end;
  114. function TDiscInfo.GetISRC(TrackNumber: integer): TScsiISRC;
  115. begin
  116.   FLastError := SCSIgetISRC(BurnerInfo, TrackNumber, Result, fDefaults);
  117. end;
  118. function TDiscInfo.GetLastTrack: integer;
  119. begin
  120.   Result := 0;
  121. end;
  122. procedure TDiscInfo.RefreshDiskLayout;
  123. begin
  124.   FLastError := SCSIgetLayoutInfo(BurnerInfo, FDiscLayout, fDefaults);
  125. end;
  126. function TDiscInfo.GetLayout: TDiscLayout;
  127. begin
  128.   Result := FDiscLayout;
  129. end;
  130. function TDiscInfo.GetSectorType(aLBA: integer): TScsiReadCdSectorType;
  131. begin
  132.   FLastError := SCSIreadHeader(BurnerInfo, aLBA, Result, fDefaults);
  133. end;
  134. function TDiscInfo.GetSessions: TScsiSessionInfo;
  135. begin
  136.   FLastError := SCSIgetSessionInfo(BurnerInfo, Result, fDefaults);
  137. end;
  138. function TDiscInfo.GetTOC: TScsiTOC;
  139. begin
  140.   FLastError := SCSIgetTOC(BurnerInfo, Result, fDefaults);
  141. end;
  142. function TDiscInfo.GetTrackInfo(ATrack: Byte): TTrackInformation;
  143. begin
  144.   FLastError := SCSIReadTrackInformation(BurnerInfo, ATrack, Result, fDefaults);
  145. end;
  146. function TDiscInfo.GetDVDescriptor: TScsiDVDLayerDescriptorInfo;
  147. begin
  148.   FLastError := SCSIReadDVDStructure(BurnerInfo, Result, fDefaults);
  149. end;
  150. function TDiscInfo.CDDB_ID: string;
  151. var
  152.   Index, DiskID, TrackID: integer;
  153.   PreTrack1, PreTrack2: Integer;
  154.   PreHex: DWord;
  155. begin
  156.   Result := 'ffffffff';
  157.   TrackID := 0;
  158.   // add up all track sizes
  159.   for Index := 0 to TOC.LastTrack - 1 do
  160.     TrackID := TrackID + CDDB_Sum(LBA2PreCDDB(TOC.Tracks[Index].AbsAddress));
  161.   //size of the disc
  162.   PreTrack1 := LBA2PreCDDB(TOC.Tracks[TOC.LastTrack].AbsAddress);
  163.   PreTrack2 := LBA2PreCDDB(TOC.Tracks[0].AbsAddress);
  164.   DiskID := (PreTrack1 - PreTrack2);
  165.   // Create CDDB ID
  166.   TrackID := (TrackID mod $FF);
  167.   TrackID := TrackID shl 24;
  168.   DiskID := DiskID shl 8;
  169.   PreHex := TrackID or DiskID or (TOC.LastTrack);
  170.   Result := LowerCase(IntToHex(PreHex, 8)); //a70ce90d
  171. end;
  172. function TDiscInfo.GetCDDBInfo: TCDDBQuery;
  173. var
  174.   DBID: string;
  175. begin
  176.   DBID := CDDB_ID;
  177.   FCDDBQuery.ClearCDDB;
  178.   FCDDBQuery.ApplicationName := 'FreeBurner.exe';
  179.   FCDDBQuery.CDDBID := DBID;
  180.   FCDDBQuery.GetCDDBInfo;
  181.   Result := FCDDBQuery;
  182. end;
  183. function TDiscInfo.GetCDText: TCDDAText;
  184. var
  185.   CDTEXT: TCDText;
  186.   Packets, Index: integer;
  187.   Trackname, HoldStr: string;
  188. begin
  189.   Result := nil;
  190.   FLastError := SCSIgetTOCCDText(BurnerInfo, CDTEXT, fDefaults);
  191.   if fLastError = Err_None then
  192.   begin
  193.     for Packets := 0 to 255 do
  194.     begin
  195.       Result := FCDText;
  196.       if CDTEXT.CDText[Packets].idSeq <> Packets then exit;
  197.       if ((CDTEXT.CDText[Packets].idFlg and $30) = 0) then //dont want unicode
  198.       begin
  199.         case CDTEXT.CDText[Packets].idType of
  200.           CD_TEXT_PACK_ALBUM_NAME: if (CDTEXT.CDText[Packets].idTrk = 0) then
  201.             begin
  202.               for Index := 0 to 11 do
  203.                 begin
  204.                   HoldStr := HoldStr + Chr(CDTEXT.CDText[Packets].txt[Index]);
  205.                   if Chr(CDTEXT.CDText[Packets].txt[Index]) = #0 then
  206.                   begin
  207.                      FCDText.Album := HoldStr;
  208.                      HoldStr := '';
  209.                   end;
  210.                 end;
  211.             end
  212.             else
  213.             begin
  214.               for Index := 0 to 11 do
  215.                begin
  216.                   Trackname := Trackname + Chr(CDTEXT.CDText[Packets].txt[Index]);
  217.                   if Chr(CDTEXT.CDText[Packets].txt[Index]) = #0 then
  218.                   begin
  219.                      FCDText.MusicTracks.Add(TrackName);
  220.                      Trackname := '';
  221.                   end;
  222.                end;
  223.             end;
  224.           CD_TEXT_PACK_PERFORMER:
  225.             begin
  226.                for Index := 0 to 11 do
  227.                 begin
  228.                   HoldStr := HoldStr + Chr(CDTEXT.CDText[Packets].txt[Index]);
  229.                   if Chr(CDTEXT.CDText[Packets].txt[Index]) = #0 then
  230.                   begin
  231.                      if (CDTEXT.CDText[Packets].idTrk <> 0) then
  232.                      begin
  233.                         HoldStr := FCDText.MusicTracks[CDTEXT.CDText[Packets].idTrk -1 ] + ' : ' + HoldStr;
  234.                         FCDText.MusicTracks[CDTEXT.CDText[Packets].idTrk -1 ] := HoldStr;
  235.                         HoldStr := '';
  236.                      end
  237.                       else
  238.                        FCDText.Artist := HoldStr;
  239.                   end;
  240.                 end;
  241.             end;
  242.           CD_TEXT_PACK_GENRE: if (CDTEXT.CDText[Packets].idTrk = 0) then
  243.             begin
  244.                for Index := 0 to 11 do
  245.                 begin
  246.                   HoldStr := HoldStr + Chr(CDTEXT.CDText[Packets].txt[Index]);
  247.                   if Chr(CDTEXT.CDText[Packets].txt[Index]) = #0 then
  248.                   begin
  249.                      FCDText.Genre := HoldStr;
  250.                      HoldStr := '';
  251.                   end;
  252.                 end;
  253.             end;
  254.         end; //case
  255.       end;
  256.     end; // end packet loop
  257.   end;
  258. end;
  259. procedure TDiscInfo.CreateCUEFile(ISOFileName, CUEFileName: string);
  260. var
  261.   CueFile: TStringList;
  262.   SectorType: string;
  263.   i, j: integer;
  264.   k, s: string;
  265. begin
  266.   CueFile := TStringList.Create;
  267.   CueFile.Add('FILE "' + ExtractFileName(ISOFileName) + '" BINARY');
  268.   CueFile.Add('');
  269.   RefreshDiskLayout;
  270.   for I := Disclayout.FirstSession to Disclayout.LastSession do
  271.   begin
  272.     k := Format('%02.02d', [I]);
  273.     CueFile.Add(' REM SESSION ' + k +
  274.       '        ; Not supported by all applications');
  275.     for j := Disclayout.Sessions[i].FirstTrack to
  276.       Disclayout.Sessions[i].LastTrack do
  277.     begin
  278.       k := Format('%02.02d', [j]);
  279.       SectorType := Disclayout.Sessions[i].Tracks[j].fTypeStr;
  280.       if SectorType = 'Audio' then
  281.         s := '  TRACK ' + k + ' AUDIO';
  282.       if SectorType = 'Data (Mode 1)' then
  283.         s := '  TRACK ' + k + ' MODE1/2352';
  284.       if SectorType = 'Data (Mode 2)' then
  285.         s := '  TRACK ' + k + ' MODE2/2352';
  286.       CueFile.Add(s);
  287.       CueFile.Add('    INDEX 01 ' + Disclayout.Sessions[i].Tracks[j].StartAddressStr);
  288.       CueFile.Add('    REM MSF: ' + Disclayout.Sessions[i].Tracks[j].StartAddressStr + ' = LBA: ' +
  289.         inttostr(Disclayout.Sessions[i].Tracks[j].StartAddress));
  290.     end;
  291.   end;
  292.   CueFile.Add('');
  293.   CueFile.Add('');
  294.   CueFile.Add(resCueInfo);
  295.   CueFile.Add(resCueWebInfo);
  296.   CueFile.SaveToFile(CUEFileName);
  297.   CueFile.Free;
  298. end;
  299. {
  300. TITLE "How Precious"
  301. PERFORMER "Dino"
  302. SONGWRITER "Enya"
  303. }
  304. end.