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

DVD

开发平台:

Delphi

  1. {-----------------------------------------------------------------------------
  2.  Unit Name: BurnerThread
  3.  Author:    Paul Fisher / Andrew Semack
  4.  Purpose:   main thread to burn TCustomimages (audio / file / iso9660 / DVD /BinCUE)
  5.  History:
  6. -----------------------------------------------------------------------------}
  7. unit BurnerThread;
  8. interface
  9. uses
  10.   Windows, Classes, SCSIDefs, DeviceTypes, CustomImage, FileImage,
  11.   AudioImage, DVDImage, ISOImage, BinCueImage, HandledThread,Resources,
  12.   SysUtils, SCSIUnit, SCSITypes, CDBufferedStream;
  13. type
  14.   TBurnerThread = class(THandledThread)
  15.   private
  16.     FInfoRecord: PCDBurnerInfo;
  17.     FBurnSettings: TBurnSettings;
  18.     FOnCDStatus: TCDStatusEvent;
  19.     FOnCopyStatus: TCopyStatusEvent;
  20.     FOnBufferProgress: TCDBufferProgressEvent;
  21.     FOnFileBufferProgress: TCDFileBufferProgressEvent;
  22.     FOnBufferStatus: TCDBufferStatusEvent;
  23.     FOnWriteStatusEvent: TCDWriteStatusEvent;
  24.     FFileName: string;
  25.     FImage: TCustomImage;
  26.     FLastError: TScsiError;
  27.     FDefaults: TScsiDefaults;
  28.     ISOFilestream: TCDBufferedStream;
  29.     BufferSize: Integer;
  30.     BufferFreeSpace: Integer;
  31.     FCDSpeedType: Integer;
  32.     function SetWriteMode(BurnSettings: TBurnSettings): boolean;
  33.     function WriteData(GLBA: DWORD; SectorCount: WORD;
  34.       Buf: pointer; BufLen: DWORD): boolean;
  35.     function WriteAudio(GLBA, SectorCount: DWORD;
  36.       Buf: pointer; BufLen: DWORD): boolean;
  37.     function SendCueSheet(ATIPBuffer: pointer; ATIPBufferSize : longint): boolean;
  38.     function GetBufferFreeSpace: Integer;
  39.     function GetBufferCapacity: Integer;
  40.     function CloseTrack(TrackNo: Byte): boolean;
  41.     function CloseSession: boolean;
  42.     function SyncCache: boolean;
  43.     function GetBurnerInfo: TCDBurnerInfo;
  44.     procedure WriteImage;
  45.   protected
  46.     function WriteISOToCD(Filename: string): boolean;
  47.     function WriteISOToDVD(Filename: string): boolean;
  48.     function WriteAudioCD(TrackCount: Integer): boolean;
  49.     function WriteDAOImage: boolean;
  50.     procedure Execute; override;
  51.     property BurnerInfo: TCDBurnerInfo read GetBurnerInfo;
  52.   public
  53.     procedure Burn;
  54.     constructor Create(InfoRecord: PCDBurnerInfo; ISOImage: TCustomImage);
  55.     destructor Destroy; override;
  56.   published
  57.     property BurnSettings: TBurnSettings read FBurnSettings write FBurnSettings;
  58.     property CDSpeed: Integer read FCDSpeedType write FCDSpeedType default
  59.       SCDS_MAXSPEED;
  60.     property OnCDStatus: TCDStatusEvent read FOnCDStatus write FOnCDStatus;
  61.     property OnCopyStatus: TCopyStatusEvent read FOnCopyStatus write
  62.       FOnCopyStatus;
  63.     property OnBufferProgress: TCDBufferProgressEvent read FOnBufferProgress
  64.       write FOnBufferProgress;
  65.     property OnFileBufferProgress: TCDFileBufferProgressEvent read
  66.       FOnFileBufferProgress write FOnFileBufferProgress;
  67.     property OnBufferStatus: TCDBufferStatusEvent read FOnBufferStatus write
  68.       FOnBufferStatus;
  69.     property OnWriteStatusEvent: TCDWriteStatusEvent read FOnWriteStatusEvent
  70.       write FOnWriteStatusEvent;
  71.   end;
  72. implementation
  73. uses CovertFuncs;
  74. { TBurnerThread }
  75. procedure TBurnerThread.Burn;
  76. begin
  77.   Resume;
  78. end;
  79. constructor TBurnerThread.Create(InfoRecord: PCDBurnerInfo; ISOImage: TCustomImage);
  80. begin
  81.   inherited Create(True); // Create thread suspended
  82.   Priority := TThreadPriority(tpTimeCritical); // Set Priority Level
  83.   FreeOnTerminate := True; // Thread Free Itself when terminated
  84.   FFileName := '';
  85.   FImage := ISOImage;        // assign tcustomimage
  86.   FInfoRecord := InfoRecord; // CD/DVD Burner
  87. end;
  88. function TBurnerThread.GetBurnerInfo: TCDBurnerInfo;
  89. begin
  90.   Result := FInfoRecord^;
  91. end;
  92. destructor TBurnerThread.Destroy;
  93. begin
  94.   if ISOFilestream <> nil then ISOFilestream.Free;
  95.   inherited;
  96. end;
  97. function TBurnerThread.SetWriteMode(BurnSettings: TBurnSettings): boolean;
  98. begin
  99.   FLastError := SCSISetWriteParameters(BurnerInfo, 0, BurnSettings, fDefaults);
  100.   Result := fLastError = Err_None;
  101. end;
  102. function TBurnerThread.SendCueSheet(ATIPBuffer: pointer; ATIPBufferSize : longint): boolean;
  103. begin
  104.   FLastError := SCSISendCUESheet(BurnerInfo, ATIPBuffer, ATIPBufferSize, fDefaults);
  105.   Result := fLastError = Err_None;
  106. end; 
  107. function TBurnerThread.WriteData(GLBA: DWORD; SectorCount: WORD;
  108.   Buf: pointer; BufLen: DWORD): boolean;
  109. begin
  110.   FLastError := SCSIWrite10(BurnerInfo, GLBA, SectorCount, Buf, BufLen,
  111.     fDefaults);
  112.   Result := fLastError = Err_None;
  113. end;
  114. function TBurnerThread.WriteAudio(GLBA, SectorCount: DWORD;
  115.   Buf: pointer; BufLen: DWORD): boolean;
  116. begin
  117.   fLastError := SCSIWriteCDDA(BurnerInfo, GLBA, SectorCount, csfAudio,
  118.     [cffUserData], Buf, BufLen, fDefaults);
  119.   Result := fLastError = Err_None;
  120. end;
  121. function TBurnerThread.GetBufferFreeSpace: Integer;
  122. var
  123.   BufferInfo: TScsiCDBufferInfo;
  124.   FreeSpace: DWord;
  125. begin
  126.   FillChar(BufferInfo, sizeof(TScsiCDBufferInfo), 0);
  127.   SCSIgetBufferCapacity(BurnerInfo, BufferInfo, fDefaults);
  128.   FreeSpace := BufferInfo.BlankLength;
  129.   FreeSpace := Swap32(FreeSpace);
  130.   Result := FreeSpace;
  131. end;
  132. function TBurnerThread.GetBufferCapacity: Integer;
  133. var
  134.   BufferInfo: TScsiCDBufferInfo;
  135.   BufSpace: DWord;
  136.   FreeSpace: DWord;
  137.   Percent, Divisor: Integer;
  138. begin
  139.   FillChar(BufferInfo, sizeof(TScsiCDBufferInfo), 0);
  140.   SCSIgetBufferCapacity(BurnerInfo, BufferInfo, fDefaults);
  141.   BufSpace := BufferInfo.SizeOfBuffer;
  142.   FreeSpace := BufferInfo.BlankLength;
  143.   BufferSize := Swap32(BufSpace);
  144.   BufferFreeSpace := Swap32(FreeSpace);
  145.   Divisor := (BufferSize div 100);
  146.   Percent := ((BufferSize - BufferFreeSpace) div Divisor);
  147.   if (Percent < 0) then
  148.     Percent := 0;
  149.   if (Percent > 100) then
  150.     Percent := 100;
  151.   Result := Percent;
  152. end;
  153. function TBurnerThread.CloseSession: boolean;
  154. begin
  155.   FLastError := SCSICloseSession(BurnerInfo, fDefaults);
  156.   Result := FLastError = Err_None;
  157. end;
  158. function TBurnerThread.CloseTrack(TrackNo: Byte): boolean;
  159. begin
  160.   FLastError := SCSICloseTrack(BurnerInfo, TrackNo, fDefaults);
  161.   Result := FLastError = Err_None;
  162. end;
  163. function TBurnerThread.SyncCache: boolean;
  164. begin
  165.   FLastError := SCSISYNCCACHE(BurnerInfo, fDefaults);
  166.   Result := FLastError = Err_None;
  167. end;
  168. function TBurnerThread.WriteISOToDVD(Filename: string): boolean;
  169. var
  170.   ISOFilestream: TCDBufferedStream;
  171.   Buf: Pointer;
  172.   BufLen, SectorSize, SectorsToWrite: integer;
  173.   BytesWritten: integer;
  174.   IndexBlock: integer;
  175.   LastBlock: integer;
  176. begin
  177.   if not
  178.     SetWriteMode(FBurnSettings) then
  179.   begin
  180.     if Assigned(FOnCDStatus) then
  181.       FOnCDStatus(resSetDataHardwareFail);
  182.     Result := False;
  183.     exit;
  184.   end
  185.   else if Assigned(FOnCDStatus) then
  186.     FOnCDStatus(resSetDataHardwareOK);
  187.   ISOFilestream := TCDBufferedStream.Create(Filename, fmOpenRead);
  188.   SectorSize := ConvertDataBlock(FBurnSettings.DataBlockType);
  189.   ISOFilestream.SectorSize := SectorSize;
  190.   if not ISOFilestream.ISOSectorSizeOK then
  191.   begin
  192.     if Assigned(FOnCDStatus) then
  193.       FOnCDStatus(resImageSizeError);
  194.     ISOFilestream.free;
  195.     Result := False;
  196.     exit;
  197.   end;
  198. { add dvd ISO Writing settings}
  199.   SCSISetStreamingMode(BurnerInfo, fDefaults);
  200.   SCSISendDVDStructureTimeStamp(BurnerInfo, Now, fDefaults);
  201.   SCSIReserveTrack(BurnerInfo, Cardinal(ISOFilestream.SectorCount), fDefaults);
  202. {dvd settings complete}
  203.   SCSIDeviceReadyTimeOut(BurnerInfo, 30000, 100, fDefaults);
  204.   LastBlock := ISOFilestream.SectorCount;
  205.   IndexBlock := 0;
  206.   BytesWritten := 0;
  207.   SectorsToWrite := 20; // increase to make faster writing ????
  208.   Buf := nil;
  209.   BufLen := (SectorSize * SectorsToWrite); //10 * 4096 40kb at a time
  210.   ReallocMem(Buf, BufLen); // alloc max buf size
  211.   while (BytesWritten < ISOFilestream.Size - 1) do
  212.   begin
  213.     try
  214.       if (SectorsToWrite > ISOFilestream.SectorsLeft) then
  215.         SectorsToWrite := (ISOFilestream.SectorsLeft);
  216.       buflen := (SectorSize * SectorsToWrite);
  217.       BytesWritten := BytesWritten + ISOFilestream.Read(pchar(Buf)^, BufLen);
  218.         // read data from iso
  219.       if not WriteData(IndexBlock, SectorsToWrite, buf, BufLen) then
  220.         // write data to cd
  221.       begin
  222.         if Assigned(FOnCDStatus) then
  223.           FOnCDStatus(resDiskWriteError);
  224.         ISOFilestream.free;
  225.         Result := False;
  226.         exit;
  227.       end;
  228.       inc(IndexBlock, SectorsToWrite);
  229.     finally
  230.       if Assigned(FOnCopyStatus) then
  231.         FOnCopyStatus(IndexBlock, (IndexBlock div ((LastBlock - 1) div 100)));
  232.       if Assigned(FOnWriteStatusEvent) then
  233.         FOnWriteStatusEvent(BytesWritten);
  234.       if Assigned(FOnBufferProgress) then
  235.         FOnBufferProgress(GetBufferCapacity);
  236.       if Assigned(FOnBufferStatus) then
  237.         FOnBufferStatus(BufferSize, BufferFreeSpace);
  238.       if Assigned(FOnFileBufferProgress) then
  239.         FOnFileBufferProgress(ISOFilestream.BufferPercentFull);
  240.     end;
  241.     while (GetBufferFreeSpace < 2448) and (not SCSItestReady(BurnerInfo, fDefaults)) do
  242.     begin
  243.       if Assigned(FOnBufferProgress) then
  244.         FOnBufferProgress(GetBufferCapacity);
  245.         sleep(500);
  246.     end;
  247.   end; {writing for loop}
  248.   ReallocMem(Buf, 0);
  249.   if Assigned(FOnBufferProgress) then
  250.     FOnBufferProgress(GetBufferCapacity);
  251.   if Assigned(FOnCDStatus) then
  252.     FOnCDStatus(resSyncCache);
  253.   if not SyncCache then // Sync the cache buffer
  254.   begin
  255.     if Assigned(FOnCDStatus) then
  256.       FOnCDStatus(resSyncCacheError);
  257.     ISOFilestream.free;
  258.     Result := False;
  259.     exit;
  260.   end;
  261.   if Assigned(FOnCDStatus) then
  262.     FOnCDStatus(resCloseTrack);
  263.   self.CloseTrack(1);
  264.   self.SyncCache;
  265.   if CloseSession = true then
  266.   begin
  267.     if Assigned(FOnCDStatus) then
  268.       FOnCDStatus(resCloseSession);
  269.     self.CloseSession;
  270.     self.SyncCache;
  271.   end;
  272.   if Assigned(FOnBufferProgress) then
  273.     FOnBufferProgress(GetBufferCapacity);
  274.   if Assigned(FOnFileBufferProgress) then
  275.     FOnFileBufferProgress(0);
  276.   ISOFilestream.Free;
  277.   Result := True;
  278.   BufLen := (SectorSize * 20);
  279.   Freemem(Buf, BufLen);
  280.   if Assigned(FOnCDStatus) then
  281.     FOnCDStatus(resFinishISOBurn);
  282.   Self.Terminate;
  283. end;
  284. function TBurnerThread.WriteISOToCD(Filename: string): boolean;
  285. var
  286.   ISOFilestream: TCDBufferedStream;
  287.   Buf: Pointer;
  288.   BufLen, SectorSize, SectorsToWrite: integer;
  289.   BytesWritten: integer;
  290.   IndexBlock: integer;
  291.   LastBlock: integer;
  292. begin
  293.   if (FBurnSettings.DataBlockType = btRAW_DATA_P_Q_SUB) then
  294.     FBurnSettings.TrackMode := tmCDR_MODE_DAO_96
  295.   else
  296.     FBurnSettings.TrackMode := tmCDR_MODE_DATA;
  297.   if not
  298.     SetWriteMode(FBurnSettings) then
  299.   begin
  300.     if Assigned(FOnCDStatus) then
  301.       FOnCDStatus(resSetDataHardwareFail);
  302.     Result := False;
  303.     exit;
  304.   end
  305.   else if Assigned(FOnCDStatus) then
  306.     FOnCDStatus(resSetDataHardwareOK);
  307.   ISOFilestream := TCDBufferedStream.Create(Filename, fmOpenRead);
  308.   SectorSize := ConvertDataBlock(FBurnSettings.DataBlockType);
  309.   ISOFilestream.SectorSize := SectorSize;
  310.   if not ISOFilestream.ISOSectorSizeOK then
  311.   begin
  312.     if Assigned(FOnCDStatus) then
  313.       FOnCDStatus(resImageSizeError);
  314.     ISOFilestream.free;
  315.     Result := False;
  316.     exit;
  317.   end;
  318.   LastBlock := ISOFilestream.SectorCount;
  319.   IndexBlock := 0;
  320.   BytesWritten := 0;
  321.   SectorsToWrite := 40; // increase to make faster writing ????
  322.   Buf := nil;
  323.   BufLen := (SectorSize * SectorsToWrite); //10 * 4096 40kb at a time
  324.   ReallocMem(Buf, BufLen); // alloc max buf size
  325.   while (BytesWritten < ISOFilestream.Size - 1) do
  326.     //  for IndexBlock := 0 to LastBlock - 1 do
  327.   begin
  328.     try
  329.       if (SectorsToWrite > ISOFilestream.SectorsLeft) then
  330.         SectorsToWrite := (ISOFilestream.SectorsLeft);
  331.       buflen := (SectorSize * SectorsToWrite);
  332.       BytesWritten := BytesWritten + ISOFilestream.Read(pchar(Buf)^, BufLen);
  333.         // read data from iso
  334.       if not WriteData(IndexBlock, SectorsToWrite, buf, BufLen) then
  335.         // write data to cd
  336.       begin
  337.         if Assigned(FOnCDStatus) then
  338.           FOnCDStatus(resDiskWriteError);
  339.         ISOFilestream.free;
  340.         Result := False;
  341.         exit;
  342.       end;
  343.       inc(IndexBlock, SectorsToWrite);
  344.     finally
  345.       if Assigned(FOnCopyStatus) then
  346.         FOnCopyStatus(IndexBlock, (IndexBlock div ((LastBlock - 1) div 100)));
  347.       if Assigned(FOnWriteStatusEvent) then
  348.         FOnWriteStatusEvent(BytesWritten);
  349.       if Assigned(FOnBufferProgress) then
  350.         FOnBufferProgress(GetBufferCapacity);
  351.       if Assigned(FOnBufferStatus) then
  352.         FOnBufferStatus(BufferSize, BufferFreeSpace);
  353.       if Assigned(FOnFileBufferProgress) then
  354.         FOnFileBufferProgress(ISOFilestream.BufferPercentFull);
  355.     end;
  356.     while (GetBufferFreeSpace < 2448) do
  357.     begin
  358.       if Assigned(FOnBufferProgress) then
  359.         FOnBufferProgress(GetBufferCapacity);
  360.         sleep(500);
  361.     end;
  362.   end; {writing for loop}
  363.   ReallocMem(Buf, 0);
  364.   if Assigned(FOnBufferProgress) then
  365.     FOnBufferProgress(GetBufferCapacity);
  366.   if Assigned(FOnCDStatus) then
  367.     FOnCDStatus(resSyncCache);
  368.   if not SyncCache then // Sync the cache buffer
  369.   begin
  370.     if Assigned(FOnCDStatus) then
  371.       FOnCDStatus(resSyncCacheError);
  372.     ISOFilestream.free;
  373.     Result := False;
  374.     exit;
  375.   end;
  376.   if Assigned(FOnCDStatus) then
  377.     FOnCDStatus(resCloseTrack);
  378.   self.CloseTrack(1);
  379.   self.SyncCache;
  380.   if CloseSession = true then
  381.   begin
  382.     if Assigned(FOnCDStatus) then
  383.       FOnCDStatus(resCloseSession);
  384.     self.CloseSession;
  385.     self.SyncCache;
  386.   end;
  387.   if Assigned(FOnBufferProgress) then
  388.     FOnBufferProgress(GetBufferCapacity);
  389.   if Assigned(FOnFileBufferProgress) then
  390.     FOnFileBufferProgress(0);
  391.   ISOFilestream.Free;
  392.   Result := True;
  393.   BufLen := (SectorSize * 20);
  394.   Freemem(Buf, BufLen);
  395.   if Assigned(FOnCDStatus) then
  396.     FOnCDStatus(resFinishISOBurn);
  397.   Self.Terminate;
  398. end;
  399. function TBurnerThread.WriteAudioCD(TrackCount: Integer): boolean;
  400. var
  401.   Buf: Pointer;
  402.   BufLen, SectorSize, TempDataSize: integer;
  403.   SectorsToWrite: Integer;
  404.   BytesWritten: integer;
  405.   TrackID: Integer;
  406.   LastTrackLBA: Integer;
  407.   IndexBlock: integer;
  408.   LastBlock: integer;
  409.   CDTracks : TAudioImage;
  410. begin
  411.   LastTrackLBA := 0; // set start point
  412.   BufLen := 0;
  413.   CDTracks := TAudioImage(FImage);
  414.   if not SetWriteMode(FBurnSettings) then
  415.   begin
  416.     if Assigned(FOnCDStatus) then
  417.       FOnCDStatus(resSetAudioHardwareFail);
  418.     Result := False;
  419.     exit;
  420.   end
  421.   else if Assigned(FOnCDStatus) then
  422.     FOnCDStatus(resSetAudioHardwareOK);
  423.   for TrackID := 0 to TrackCount - 1 do //burn all tracks to cd
  424.   begin
  425.     FOnCDStatus('Burning :' + CDTracks.Tracks[TrackID].CDTrack.TrackName);
  426.     SectorSize := ConvertDataBlock(FBurnSettings.DataBlockType);
  427.     CDTracks.Tracks[TrackID].CDTrack.SectorSize := SectorSize;
  428.     LastBlock := (LastTrackLBA + CDTracks.Tracks[TrackID].CDTrack.SectorCount);
  429.     //set data offsett past header
  430.     CDTracks.Tracks[TrackID].CDTrack.Seek(soFromBeginning,
  431.       CDTracks.Tracks[TrackID].CDTrack.DataOffset);
  432.     SectorsToWrite := 20; //copy 20 sectors at a time
  433.     BytesWritten := 0; // No of bytes written to disk
  434.     BufLen := (SectorSize * SectorsToWrite); // big enough for 20 sectors
  435.     Buf := nil;
  436.     ReallocMem(Buf, BufLen);
  437.     IndexBlock := LastTrackLBA;
  438.     while (IndexBlock < LastBlock) do
  439.       //for IndexBlock := LastTrackLBA to LastBlock - 1 do
  440.     begin
  441.       try
  442.         TempDataSize := CDTracks.Tracks[TrackID].CDTrack.DataSize;
  443.         if BufLen > (TempDataSize - BytesWritten) then
  444.         begin
  445.           BufLen := (TempDataSize - BytesWritten);
  446.           SectorsToWrite := (LastBlock - IndexBlock); // find last sector count
  447.         end;
  448.         BytesWritten := BytesWritten +
  449.           CDTracks.Tracks[TrackID].CDTrack.Read(pchar(Buf)^, BufLen);
  450.           //read buffer full
  451.         WriteAudio(IndexBlock, SectorsToWrite, buf, BufLen);
  452.           // write the buffer to cd
  453.         inc(IndexBlock, SectorsToWrite);
  454.       finally
  455.         if Assigned(FOnBufferProgress) then
  456.           FOnBufferProgress(GetBufferCapacity);
  457.         if Assigned(FOnCopyStatus) then
  458.           FOnCopyStatus(IndexBlock, (IndexBlock div ((LastBlock - 1) div 100)));
  459.         if Assigned(FOnWriteStatusEvent) then
  460.           FOnWriteStatusEvent(BytesWritten);
  461.         if Assigned(FOnBufferStatus) then
  462.           FOnBufferStatus(BufferSize, BufferFreeSpace);
  463.       end;
  464.       while (GetBufferFreeSpace < 2448) do
  465.         if Assigned(FOnBufferProgress) then
  466.           FOnBufferProgress(GetBufferCapacity);
  467.     end; //all track data for loop
  468.     if Assigned(FOnCDStatus) then
  469.       FOnCDStatus(resSyncCache);
  470.     SyncCache;
  471.     if Assigned(FOnBufferProgress) then
  472.       FOnBufferProgress(GetBufferCapacity);
  473.     if Assigned(FOnCDStatus) then
  474.       FOnCDStatus(resCloseTrack +
  475.         inttostr(TrackID));
  476.     CloseTrack(TrackID);
  477.     LastTrackLBA := (LastBlock + FBurnSettings.AudioPause + 2);
  478.       // reset LastTrackLBA to Next block to write (Leo-Soft)
  479.   end; // for all tracks loop
  480.   if FBurnSettings.CloseSession = True then
  481.   begin
  482.     if Assigned(FOnCDStatus) then
  483.       FOnCDStatus(resCloseSession);
  484.     CloseSession;
  485.   end;
  486.   if Assigned(FOnBufferProgress) then
  487.     FOnBufferProgress(GetBufferCapacity);
  488.   Freemem(Buf, BufLen);
  489.   if Assigned(FOnCDStatus) then
  490.     FOnCDStatus(resFinishAudioBurn);
  491.   Result := True;
  492.   Self.Terminate;
  493. end;
  494. function TBurnerThread.WriteDAOImage: boolean;
  495. var
  496.   ISOFilestream: TCDBufferedStream;
  497.   Buf: Pointer;
  498.   BufLen, SectorSize, SectorsToWrite: integer;
  499.   BytesWritten: integer;
  500.   IndexBlock: integer;
  501.   LastBlock: integer;
  502.   BINFileName : String;
  503.   ATIPBuffer : Pointer;
  504.   ATIPBufferSize : Longint;
  505. begin
  506.   BINFileName := TBinCueImage(FImage).BINFileName;
  507.   FBurnSettings.TrackMode := TBinCueImage(FImage).TrackMode;
  508.   SectorSize := TBinCueImage(FImage).SectorSize;
  509.   //FImage seems to go out of scope after setwritemode, so set cue sheet first ?????
  510.   ATIPBufferSize := (TBinCueImage(FImage).ATIPCueList.Count + 1) * 8; // no of bytes needed for ATIP CueSheet
  511.   try
  512.     ATIPBuffer := nil;
  513.     ReallocMem(ATIPBuffer, ATIPBufferSize); // alloc max buf size
  514.     Move(TBinCueImage(FImage).ATIPCueList.Cues, ATIPBuffer^, ATIPBufferSize); // move bytes from cue list to buffer
  515.   if not SetWriteMode(FBurnSettings) then
  516.   begin
  517.     if Assigned(FOnCDStatus) then
  518.       FOnCDStatus(resSetDataHardwareFail);
  519.     Result := False;
  520.     exit;
  521.   end
  522.   else if Assigned(FOnCDStatus) then
  523.     FOnCDStatus(resSetDataHardwareOK);
  524.   if not SendCueSheet(ATIPBuffer, ATIPBufferSize) then
  525.   begin
  526.     if Assigned(FOnCDStatus) then
  527.       FOnCDStatus(resCUESheetFailed);
  528.     Result := False;
  529.     exit;
  530.   end
  531.   else if Assigned(FOnCDStatus) then
  532.     FOnCDStatus(resCUESheetSent);
  533.   finally
  534.      freemem(ATIPBuffer,ATIPBufferSize);  // free cue sheet buffer
  535.   end;
  536.   ISOFilestream := TCDBufferedStream.Create(BINFileName, fmOpenRead);
  537.   ISOFilestream.SectorSize := SectorSize;
  538.   if not ISOFilestream.ISOSectorSizeOK then
  539.   begin
  540.     if Assigned(FOnCDStatus) then
  541.       FOnCDStatus(resImageSizeError);
  542.     ISOFilestream.free;
  543.     Result := False;
  544.     exit;
  545.   end;
  546.   LastBlock := ISOFilestream.SectorCount;
  547.   IndexBlock := 0;
  548.   BytesWritten := 0;
  549.   SectorsToWrite := 20; // increase to make faster writing ????
  550.   Buf := nil;
  551.   BufLen := (SectorSize * SectorsToWrite); //20 *  at a time
  552.   ReallocMem(Buf, BufLen); // alloc max buf size
  553.   while (BytesWritten < ISOFilestream.Size - 1) do
  554.     //  for IndexBlock := 0 to LastBlock - 1 do
  555.   begin
  556.     try
  557.       if (SectorsToWrite > ISOFilestream.SectorsLeft) then
  558.         SectorsToWrite := (ISOFilestream.SectorsLeft);
  559.       buflen := (SectorSize * SectorsToWrite);
  560.       BytesWritten := BytesWritten + ISOFilestream.Read(pchar(Buf)^, BufLen);
  561.         // read data from iso
  562.       if not WriteData(IndexBlock, SectorsToWrite, buf, BufLen) then
  563.         // write data to cd
  564.       begin
  565.         if Assigned(FOnCDStatus) then
  566.           FOnCDStatus(resDiskWriteError);
  567.         ISOFilestream.free;
  568.         Result := False;
  569.         exit;
  570.       end;
  571.       inc(IndexBlock, SectorsToWrite);
  572.     finally
  573.       if Assigned(FOnCopyStatus) then
  574.         FOnCopyStatus(IndexBlock, (IndexBlock div ((LastBlock - 1) div 100)));
  575.       if Assigned(FOnWriteStatusEvent) then
  576.         FOnWriteStatusEvent(BytesWritten);
  577.       if Assigned(FOnBufferProgress) then
  578.         FOnBufferProgress(GetBufferCapacity);
  579.       if Assigned(FOnBufferStatus) then
  580.         FOnBufferStatus(BufferSize, BufferFreeSpace);
  581.       if Assigned(FOnFileBufferProgress) then
  582.         FOnFileBufferProgress(ISOFilestream.BufferPercentFull);
  583.     end;
  584.     while (GetBufferFreeSpace < 2448) do
  585.       if Assigned(FOnBufferProgress) then
  586.         FOnBufferProgress(GetBufferCapacity);
  587.   end; {writing for loop}
  588.   ReallocMem(Buf, 0);
  589.   if Assigned(FOnBufferProgress) then
  590.     FOnBufferProgress(GetBufferCapacity);
  591.   if Assigned(FOnCDStatus) then
  592.     FOnCDStatus(resSyncCache);
  593.   if not SyncCache then // Sync the cache buffer
  594.   begin
  595.     if Assigned(FOnCDStatus) then
  596.       FOnCDStatus(resSyncCacheError);
  597.     ISOFilestream.free;
  598.     Result := False;
  599.     exit;
  600.   end;
  601.   if Assigned(FOnCDStatus) then
  602.     FOnCDStatus(resCloseTrack);
  603.   self.CloseTrack(1);
  604.   self.SyncCache;
  605.   if CloseSession = true then
  606.   begin
  607.     if Assigned(FOnCDStatus) then
  608.       FOnCDStatus(resCloseSession);
  609.     self.CloseSession;
  610.     self.SyncCache;
  611.   end;
  612.   if Assigned(FOnBufferProgress) then
  613.     FOnBufferProgress(GetBufferCapacity);
  614.   if Assigned(FOnFileBufferProgress) then
  615.     FOnFileBufferProgress(0);
  616.   ISOFilestream.Free;
  617.   Result := True;
  618.   BufLen := (SectorSize * 20);
  619.   Freemem(Buf, BufLen);
  620.   if Assigned(FOnCDStatus) then
  621.     FOnCDStatus(resFinishISOBurn);
  622.   Self.Terminate;
  623. end;
  624. procedure TBurnerThread.WriteImage;
  625. begin
  626.   if FImage is TFileImage then
  627.   begin
  628.     FFileName := TFileImage(FImage).ISOFileName;
  629.     if TFileImage(FImage).ISOFileSize > 680 then
  630.        WriteISOToDVD(FFileName) else
  631.           WriteISOToCD(FFileName);
  632.   end
  633.   else if FImage is TAudioImage then
  634.   begin
  635.     WriteAudioCD(TAudioImage(FImage).TrackCount);
  636.   end
  637.   else if FImage is TBinCueImage then
  638.   begin
  639.     WriteDAOImage;
  640.   end;
  641. end;
  642. procedure TBurnerThread.Execute;
  643. begin
  644.   try
  645.     WriteImage;
  646.   except
  647.     HandleException;
  648.   end;
  649. end;
  650. end.