www.pudn.com > NEROSDK5582.ZIP > BurnContext.cpp


/****************************************************************************** 
|* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 
|* ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO 
|* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 
|* PARTICULAR PURPOSE. 
|*  
|* Copyright 1995-2002 Ahead Software AG. All Rights Reserved. 
|*----------------------------------------------------------------------------- 
|* NeroSDK / NeroCmd 
|* 
|* PROGRAM: BurnContext.cpp 
|* 
|* PURPOSE: Central class for CD operations; implementation file 
******************************************************************************/ 
 
 
#include "stdafx.h" 
#include "BurnContext.h" 
 
 
// Set pointers to callback functions 
 
NERO_PROGRESS CBurnContext::s_NeroProgress = 
{ 
	ProgressCallback, 
	AbortedCallback, 
	AddLogLine, 
	SetPhaseCallback, 
	&s_NeroSettings, 
	DisableAbortCallback, 
}; 
 
// NERO_SETTINGS is needed when calling NeroInit() 
 
NERO_SETTINGS CBurnContext::s_NeroSettings = 
{ 
	NULL, 
	"ahead", "Nero - Burning Rom", 
	"Nero.txt", 
	{IdleCallback, &s_NeroSettings}, 
	{UserDialog, &s_NeroSettings} 
}; 
 
 
CBurnContext::CBurnContext () 
{ 
	m_NeroDeviceHandle = NULL; 
	m_NeroDeviceInfos = NULL; 
	m_pCDStamp = NULL; 
	m_NeroCDInfo = NULL; 
	m_bNeroInitialized = false; 
	m_pNeroLastError = NULL; 
 
	// Set Ctrl+C handler. 
 
	SetConsoleCtrlHandler (CtrlHandler, TRUE); 
} 
 
 
CBurnContext::~CBurnContext () 
{ 
	// Let the NeroAPI perform the required cleanup 
 
	if (true == m_bNeroInitialized) 
	{ 
		NeroCloseDevice (m_NeroDeviceHandle); 
		NeroFreeMem (m_NeroDeviceInfos); 
		NeroFreeMem (m_NeroCDInfo); 
		NeroFreeCDStamp (m_pCDStamp); 
		NeroClearErrors (); 
	} 
 
	// Free memory allocated during retrieval of  
	// NeroAPI's last error. No checking against NULL 
	// required, this will be done by free(). 
 
	free(m_pNeroLastError); 
 
	// NeroDone needs to be called before closing the DLL. 
	// This is necessary because some clean-up actions like 
	// stopping threads cannot be done in the close function of the DLL 
 
	NeroDone (); 
} 
 
 
EXITCODE CBurnContext::GetAvailableDrives (void) 
{ 
	// Make sure that NeroGetAvailableDrives has not been called before to prevent multiple  
	// allocation of memory for NERO_SCSI_DEVICE_INFOS. 
 
	_ASSERTE (NULL == m_NeroDeviceInfos); 
 
	// NeroGetAvailableDrives returns a list of available WORM and CDROM devices. 
	// The memory allocated for NERO_SCSI_DEVICE_INFOS must be freed with NeroFreeMem(). 
	// This function returns NULL for errors  
 
	m_NeroDeviceInfos = NeroGetAvailableDrivesEx (MEDIA_CD,NULL); 
 
	if (NULL == m_NeroDeviceInfos) 
	{ 
		GetLastErrorLogLine(); 
		return EXITCODE_ERROR_OBTAINING_AVAILABLE_DRIVES; 
	} 
	else 
	{ 
		return EXITCODE_OK; 
	} 
} 
 
// Opens the NeroCMD error log 
 
bool CBurnContext::OpenLogFile (LPCSTR psLogFilename) 
{ 
	// We use the CErrorLog class. 
	// Open returns true if the error log could be opened. 
 
	return m_ErrorLog.Open (psLogFilename); 
} 
 
 
EXITCODE CBurnContext::NeroLoad (void) 
{ 
	// Finally, initialize NeroAPI. 
 
	if (!TRUE == NeroAPIGlueConnect (NULL)) 
	{ 
		return EXITCODE_NEROAPI_DLL_NOT_FOUND; 
	} 
 
	// Set the flag. 
 
	m_bNeroInitialized = true; 
 
	return EXITCODE_OK; 
} 
 
 
// This function queries the registry for serial number and initializes 
// the NeroAPI. 
 
EXITCODE CBurnContext::InitNeroAPI (void) 
{ 
	// Provide the this-pointer for the UserDialog callback 
 
	s_NeroSettings.nstUserDialog.ncCallbackFunction = UserDialog; 
	s_NeroSettings.nstUserDialog.ncUserData = this; 
 
	// Do the actual initialization and map the return value 
	// into our EXITCODE. 
 
	switch (NeroInit (&s_NeroSettings, NULL)) 
	{ 
		case NEROAPI_INIT_OK: 
			return EXITCODE_OK; 
		 
		case NEROAPI_INIT_INVALID_SERIAL_NUM: 
			return EXITCODE_BAD_SERIAL_NUMBER; 
 
		case NEROAPI_INIT_DEMOVERSION_EXPIRED: 
			return EXITCODE_DEMOVERSION_EXPIRED; 
		 
		case NEROAPI_INIT_UNSPECIFIED_ERROR: 
		case NEROAPI_INIT_INVALID_ARGS: 
		default: 
			return EXITCODE_INTERNAL_ERROR; 
	} 
} 
 
 
// OpenDevice checks if params.m_psDriveName has a matching 
// drive in the list of availabe drives and opens it. 
 
EXITCODE CBurnContext::OpenDevice (const PARAMETERS & params) 
{ 
	if (NULL == params.GetDriveName()) 
	{ 
		// To open a device we must have its name or drive letter. 
 
		return EXITCODE_MISSING_DRIVENAME; 
	} 
 
	// Enumerate drives and find the requested drive among them. 
 
	for (int i = 0; i < (int)(m_NeroDeviceInfos->nsdisNumDevInfos); i++)  
	{ 
		NERO_SCSI_DEVICE_INFO nsdiShort = m_NeroDeviceInfos->nsdisDevInfos[i]; 
 
		// Check if the full device name has been supplied. 
        // stricmp performs a lowercase comparison and returns 0 if the strings are identical. 
 
		bool bFoundDeviceName = false; 
		if (0 == stricmp (params.GetDriveName(), nsdiShort.nsdiDeviceName)) 
		{ 
			bFoundDeviceName = true; 
		} 
 
		// Check if the user supplied drive name is only one character long 
		// and see if it matches the drive letter 
 
		bool bFoundDriveName = false; 
		if (1 == strlen(params.GetDriveName())) 
		{ 
			if (toupper(params.GetDriveName()[0]) == toupper(nsdiShort.nsdiDriveLetter)) 
			{ 
				bFoundDriveName = true; 
			} 
		} 
 
		// If either a device name or drive name was found try to open the device 
 
		if (bFoundDeviceName || bFoundDriveName) 
		{ 
			m_NeroDeviceHandle = NeroOpenDevice (&m_NeroDeviceInfos->nsdisDevInfos[i]); 
			if (NULL == m_NeroDeviceHandle)  
			{ 
				GetLastErrorLogLine(); 
				return EXITCODE_ERROR_OPENNING_DRIVE; 
			} 
 
			// We successfully retrieved a handle. Break the for-loop. 
 
			break; 
		} 
	} 
	 
	// Output a list of available drives and return 
	// an error if the requested device could not be found 
 
	if (NULL == m_NeroDeviceHandle) 
	{ 
		printf ("Drive '%s' not found, available are:\n", params.GetDriveName()); 
		CommandListDrives (params); 
		 
		return EXITCODE_DRIVE_NOT_FOUND; 
	} 
	 
	return EXITCODE_OK; 
} 
 
 
// This function sets the appropriate burn flags according to the user 
// supplied parameters. 
 
DWORD CBurnContext::GetBurnFlags (const PARAMETERS & params) 
{ 
	DWORD dwFlags; 
 
	// Simulation or real mode 
 
	if (true == params.GetUseReal()) 
	{ 
		dwFlags = NBF_WRITE; 
	} 
	else 
	{ 
		dwFlags = NBF_SIMULATE; 
	} 
 
	// DAO (Disc At Once) or TAO (Track At Once) 
	// TAO is default 
 
	if (false == params.GetUseTAO()) 
	{ 
		dwFlags |= NBF_DAO; 
	} 
 
	// Disable Abort 
	// The disable abort callback will be called. 
 
	if (false == params.GetEnableAbort()) 
	{ 
		dwFlags |= NBF_DISABLE_ABORT; 
	} 
 
	// Perform source speed test first 
 
	if (true == params.GetUseSpeedTest()) 
	{ 
		dwFlags |= NBF_SPEED_TEST; 
	} 
 
	// Close session after write, not the whole disc 
 
	if (true == params.GetCloseSession()) 
	{ 
		dwFlags |= NBF_CLOSE_SESSION; 
	} 
 
	// Buffer underrun protection for safer burning 
 
	if (true == params.GetUseUnderRunProt()) 
	{ 
		dwFlags |= NBF_BUF_UNDERRUN_PROT; 
	} 
 
	// Detect non-empty CDRW 
	// The DLG_NON_EMPTY_CDRW user callback will be called when trying 
	// to burn onto a non empty CDRW 
 
	if (true == params.GetDetectNonEmptyCDRW()) 
	{ 
		dwFlags |= NBF_DETECT_NON_EMPTY_CDRW; 
	} 
 
	// Enable CD text writing. 
	// Will be ignored if the drive does not support this feature 
 
	if (true == params.GetUseCDText()) 
	{ 
		dwFlags |= NBF_CD_TEXT; 
	} 
 
	// Do not eject CD at the end of the burn process 
 
	if (true == params.GetDisableEject()) 
	{ 
		dwFlags |= NBF_DISABLE_EJECT; 
	} 
 
	// Verify Filesystem after writing. Works for ISO only 
	 
	if (true == params.GetVerify()) 
	{ 
		dwFlags |= NBF_VERIFY; 
	} 
 
	return dwFlags; 
} 
 
// Copy the first occuring NeroAPI error to a member 
// and keep it until application exits. 
 
void CBurnContext::GetLastErrorLogLine() 
{ 
	// Get a pointer to the last error string 
 
	char* pErr = NeroGetLastError(); 
 
	// Only proceed if there was an error 
	// and no previous error has occured. 
 
	if (NULL != pErr && NULL == m_pNeroLastError) 
	{ 
		// Allocate some memory for the error string 
		// and copy the error message to the CBurnContext class 
		// so we can let NeroAPI free the string immediately. 
		// The allocated memory in CBurnContext will 
		// be freed during destruction. 
 
		size_t iErrSize = strlen(pErr); 
 
		// strlen does not count the terminal NULL, so we 
		// need to allocate iErrSize + 1 bytes. 
 
		m_pNeroLastError = (char*) malloc(iErrSize + 1); 
		strcpy(m_pNeroLastError, pErr); 
		NeroFreeMem(pErr); 
	} 
} 
 
// This function is called to exit with a specific error code. 
 
EXITCODE CBurnContext::Exit(EXITCODE code) 
{ 
	if (code != EXITCODE_OK) 
	{ 
		printf ("\n%s\n", GetTextualExitCode (code)); 
		if (NULL != m_pNeroLastError) 
		{ 
			printf("NeroAPI reports: %s.\n", m_pNeroLastError); 
		} 
	} 
 
	return code; 
} 
 
CBurnContext::CBurnContext(PARAMETERS* params) 
{ 
	// A PARAMETERS reference is required for  
	// the UserDialog callback. 
 
	m_params = params; 
 
	m_NeroDeviceHandle = NULL; 
	m_NeroDeviceInfos = NULL; 
	m_pCDStamp = NULL; 
	m_NeroCDInfo = NULL; 
	m_bNeroInitialized = false; 
	m_pNeroLastError = NULL; 
 
	// Set Ctrl+C handler. 
 
	SetConsoleCtrlHandler (CtrlHandler, TRUE); 
} 
 
// This function prints error log lines 
// that are passed from outside the CBurnContext class 
 
void CBurnContext::PrintLogLine(LPCSTR s) 
{ 
 
	m_ErrorLog.printf ("%s\n", s); 
}