⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 burner.cpp

📁 利用hpCDE sdk在应用程序中实现把数据写入CD_RW
💻 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 + -