📄 burner.cpp
字号:
#include "stdafx.h"
#include "Burner.h"
#include "IniFile.h"
#include "TocEntry.h"
#define BLOCKS_AT_ONCE 100
CBurner::CBurner(IDevice12 * pDevice)
{
m_pDevice = pDevice;
}
CBurner::~CBurner(void)
{
}
ISession * CBurner::LoadSessionLayout(LPCTSTR lpIniFilename, LPCTSTR lpDataFilename)
{
CIniFile ini;
ini.Initialize(lpIniFilename);
int nSessions = ini.ReadInt(_T("Sessions"), _T("Disc"));
int nTocEntries = ini.ReadInt(_T("TocEntries"), _T("Disc"));
if (0 == nTocEntries || 0 == nSessions)
return FALSE;
// Get all the entries from the ini file
CTOCEntry * pEntries = new CTOCEntry[nTocEntries];
for (int i = 0; i < nTocEntries; i++)
{
pEntries[i].SetEntryIndex(i);
pEntries[i].Serialize(&ini, FALSE);
}
ISession * ps = hpCDE::CreateSession();
// session must be a RAW session
ps->SetType(ST_RAW);
// Get the first session only, for now
BOOL bSessionNumber = 1;
long lLeadoutLba = 0;
for (int nTrack = 0; nTrack < nTocEntries; nTrack++)
{
CTOCEntry & rt = pEntries[nTrack];
if (bSessionNumber == rt.SessionNumber)
{
// skip 1 to 0x63 which is 1 to 99 tracks
if (rt.POINT > 0x63)
{
ps->SetRawPoint((ERawPoint)rt.POINT, &rt);
// 0xA2 is the lead out
if (rt.POINT == 0xA2)
lLeadoutLba = rt.m_lPLBA;
}
else
{
ITrackEntry * pTrack = NULL;
ps->GetTrack(rt.POINT - 1, &pTrack);
if (!pTrack)
{
// Create a track entry and add it to the session object
pTrack = hpCDE::CreateTrackEntry();
ps->AppendTrack(pTrack);
}
// Determine the type of the track based on the sector data
BYTE pBlockData[CD_RAW_BLOCKSIZE];
HANDLE hData = CreateFile (lpDataFilename, FILE_READ_ACCESS, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
if (INVALID_HANDLE_VALUE == hData)
return FALSE;
SetFilePointer(hData, rt.m_lPLBA * CDDA_BLOCKSIZE, NULL, FILE_BEGIN);
DWORD dwRead;
ReadFile(hData, pBlockData, CDDA_BLOCKSIZE, &dwRead, NULL);
ETrackType tt = m_pDevice->GetTrackType(pBlockData);
pTrack->SetType(tt);
CloseHandle(hData);
pTrack->SetPregapStart(rt.m_lPLBA);
pTrack->SetTrackStart(rt.m_lPLBA);
if (nTrack < nTocEntries - 1 && pEntries[nTrack + 1].POINT < 0x63)
{
// track end is the beginning of next track
pTrack->SetTrackEnd(pEntries[nTrack + 1].m_lPLBA);
pTrack->SetPostgapEnd(pEntries[nTrack + 1].m_lPLBA);
}
else
{
// last track ends at lead out start
pTrack->SetTrackEnd(lLeadoutLba);
pTrack->SetPostgapEnd(lLeadoutLba);
}
pTrack->Release();
}
}
}
delete [] pEntries;
return ps;
}
BOOL CBurner::Burn(ISession * ps, LPCTSTR lpDataFilename, LPCTSTR lpSubFilename)
{
HANDLE hData = CreateFile (lpDataFilename, FILE_READ_ACCESS, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
if (INVALID_HANDLE_VALUE == hData)
return FALSE;
HANDLE hSub = CreateFile (lpSubFilename, FILE_READ_ACCESS, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
if (INVALID_HANDLE_VALUE == hSub)
{
CloseHandle(hData);
return FALSE;
}
// Get session length
DWORD dwTotalBlocks = ps->GetLength();
// Get data file size and verify it is ok
DWORD dwSize = GetFileSize(hData, NULL);
assert(0 == (dwSize % CDDA_BLOCKSIZE));
assert(dwTotalBlocks == dwSize / CDDA_BLOCKSIZE);
// get subchannel file size and verify it is ok
dwSize = GetFileSize(hSub, NULL);
assert(0 == (dwSize % PW_CHANNEL_SIZE));
assert(dwTotalBlocks == dwSize / PW_CHANNEL_SIZE);
// m_pDevice->Erase(TRUE);
// start session
// if (m_pDevice->StartCDSession(FALSE, ps, WRITE_METHOD_FULL_RAW_SAO))
if (m_pDevice->StartCDSession(TRUE, ps, WRITE_METHOD_FULL_RAW_SAO))
{
DWORD dwStartBlock = 0;
while (dwStartBlock < dwTotalBlocks)
{
DWORD dwBlocksAtOnce = min(BLOCKS_AT_ONCE, dwTotalBlocks);
BYTE * pBuf1 = NULL, * pBuf2 = NULL;
DWORD dw1 = 0, dw2 = 0;
if (m_pDevice->WriteLockBuffer(dwBlocksAtOnce, &pBuf1, &dw1, &pBuf2, &dw2))
{
if (dw1)
{
for (DWORD dw = 0; dw < dw1; dw++)
{
DWORD dwRead;
ReadFile(hData, pBuf1 + dw * CD_RAW_BLOCKSIZE, CDDA_BLOCKSIZE, &dwRead, NULL);
ReadFile(hSub, pBuf1 + dw * CD_RAW_BLOCKSIZE + CDDA_BLOCKSIZE, PW_CHANNEL_SIZE, &dwRead, NULL);
}
}
if (dw2)
{
for (DWORD dw = 0; dw < dw2; dw++)
{
DWORD dwRead;
ReadFile(hData, pBuf2 + dw * CD_RAW_BLOCKSIZE, CDDA_BLOCKSIZE, &dwRead, NULL);
ReadFile(hSub, pBuf2 + dw * CD_RAW_BLOCKSIZE + CDDA_BLOCKSIZE, PW_CHANNEL_SIZE, &dwRead, NULL);
}
}
BYTE pBuffer1[CD_RAW_BLOCKSIZE];
memcpy(pBuffer1, pBuf1, CD_RAW_BLOCKSIZE);
m_pDevice->WriteUnlockBuffer(dw1 + dw2);
dwStartBlock += dw1 + dw2;
}
}
m_pDevice->EndCDSession();
}
CloseHandle(hSub);
CloseHandle(hData);
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -