123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653 |
- #include "StdAfx.h"
- #include "NeroImpl.h"
- CDialog* CNeroImpl::m_pDailog = NULL;
- IdleCallback CNeroImpl::m_pIdelCallback = NULL;
- UserDialog CNeroImpl::m_pUserDialog = NULL;
- ProgressCallback CNeroImpl::m_pProgressCallback = NULL;
- ProgressCallback CNeroImpl::m_pSubTaskProgressCallback = NULL;
- AbortedCallback CNeroImpl::m_pAbortedCallback = NULL;
- AddLogLine CNeroImpl::m_pAddLogLine = NULL;
- SetPhaseCallback CNeroImpl::m_pSetPhaseCallback = NULL;
- DisableAbortCallback CNeroImpl::m_pDisableAbortCallback = NULL;
- SetMajorPhaseCallback CNeroImpl::m_pSetMajorPhaseCallback = NULL;
- WriteIOCallback CNeroImpl::m_pWriteIOCallback = NULL;
- ReadIOCallback CNeroImpl::m_pReadIOCallback = NULL;
- EOFCallback CNeroImpl::m_pEOFCallback = NULL;
- ErrorCallback CNeroImpl::m_pErrorCallback = NULL;
- CNeroImpl::CNeroImpl(void) :m_nRef(0)
- , m_pNeroDeviceInfos(NULL)
- , m_bInited(false)
- {
- }
- CNeroImpl::~CNeroImpl(void)
- {
- if (m_pNeroDeviceInfos)
- {
- NeroFreeMem(m_pNeroDeviceInfos);
- }
- NeroClearErrors();
- NeroDone();
- NeroAPIGlueDone();
- }
- ULONG CNeroImpl::AddRef()
- {
- InterlockedIncrement(&m_nRef);
- return m_nRef;
- }
- ULONG CNeroImpl::Release()
- {
- LONG ulRefCount = InterlockedDecrement(&m_nRef);
- //如果为0,删除对象;
- if (m_nRef == 0)
- {
- delete this;
- }
- return ulRefCount;
- }
- HRESULT CNeroImpl::QueryInterface(REFIID riid, __RPC__deref_out void **ppvObject)
- {
- if (!ppvObject)
- return E_INVALIDARG;
- *ppvObject = NULL;
- if (riid == IID_IUnknown || riid == IID_IBurndisc)
- {
- *ppvObject = (LPVOID)this;
- AddRef();
- return NOERROR;
- }
- return E_NOINTERFACE;
- }
- bool CNeroImpl::Initialize()
- {
- // 加载Nero的库;
- if (!NeroAPIGlueConnect(NULL)) {
- m_strLastError = _T("连接NeroSDK失败!");
- return false;
- }
- // 获取Nero库版本信息;
- WORD ver1, ver2, ver3, ver4;
- if (!NeroGetAPIVersionEx(&ver1, &ver2, &ver3, &ver4, NULL)) {
- m_strLastError = _T("获取Nero Version失败!");
- return false;
- }
- // 初始化Nero环境(参数固定);
- strcpy_s(m_pcNeroFilesPath, 128, "NeroFiles");
- strcpy_s(m_pcVendor, 128, "nero");
- strcpy_s(m_pcSoftware, 128, "Nero - Burning Rom");
- strcpy_s(m_pcLanguageFile, 128, "Nero.txt");
- m_NeroSettings.nstNeroFilesPath = m_pcNeroFilesPath;
- m_NeroSettings.nstVendor = m_pcVendor;
- m_NeroSettings.nstIdle.ncCallbackFunction = CNeroImpl::m_pIdelCallback;
- m_NeroSettings.nstIdle.ncUserData = CNeroImpl::m_pDailog;
- m_NeroSettings.nstSoftware = m_pcSoftware;
- m_NeroSettings.nstUserDialog.ncCallbackFunction = CNeroImpl::m_pUserDialog;
- m_NeroSettings.nstUserDialog.ncUserData = CNeroImpl::m_pDailog;
- m_NeroSettings.nstLanguageFile = m_pcLanguageFile;
- // 初始化;
- NEROAPI_INIT_ERROR Err = NeroInit(&m_NeroSettings, NULL);
- switch (Err)
- {
- case NEROAPI_INIT_OK:
- m_strLastError = _T("初始化Nero成功!");
- break;
- case NEROAPI_INIT_INVALID_ARGS:
- m_strLastError = _T("NeroInit() : invalid args");
- break;
- case NEROAPI_INIT_INVALID_SERIAL_NUM:
- m_strLastError = _T("NeroInit() : invalid serial number");
- break;
- case NEROAPI_INIT_DEMOVERSION_EXPIRED:
- m_strLastError = _T("NeroInit() : demo version has expired");
- break;
- case NEROAPI_INIT_CANNOT_LOCK:
- m_strLastError = _T("NeroInit() : cannot lock");
- break;
- case NEROAPI_INIT_UNSPECIFIED_ERROR:
- m_strLastError = _T("NeroInit() : unspecified error");
- break;
- default:
- break;
- }
- m_NeroProgress.npProgressCallback = m_pProgressCallback;
- m_NeroProgress.npAbortedCallback = m_pAbortedCallback;
- m_NeroProgress.npAddLogLineCallback = m_pAddLogLine;
- m_NeroProgress.npSetPhaseCallback = m_pSetPhaseCallback;
- m_NeroProgress.npUserData = this;
- m_NeroProgress.npDisableAbortCallback = m_pDisableAbortCallback;
- m_NeroProgress.npSetMajorPhaseCallback = m_pSetMajorPhaseCallback;
- m_NeroProgress.npSubTaskProgressCallback = m_pSubTaskProgressCallback;
- return m_bInited = (Err == NEROAPI_INIT_OK ? true : false);
- }
- int CNeroImpl::GetAvailableDrives()
- {
- if (!m_bInited)
- return 0;
- // 清除之前的;
- m_vtDevInfo.clear();
- if (m_pNeroDeviceInfos)
- NeroFreeMem(m_pNeroDeviceInfos);
- // 参数一没什么意义,可以填MEDIA_NONE,MEDIA_CD或MEDIA_DVD_ANY;
- m_pNeroDeviceInfos = NeroGetAvailableDrivesEx(MEDIA_NONE, NULL);
- // 遍历设备;
- if (m_pNeroDeviceInfos)
- {
- char szDevName[MAX_PATH] = { 0 };
- for (int i = 0; i < m_pNeroDeviceInfos->nsdisNumDevInfos; i++)
- {
- if (strcmp(m_pNeroDeviceInfos->nsdisDevInfos[i].nsdiHostAdapterName, "Virtual") != 0)
- {
- DeviceInfo devinfo;
- devinfo.nIndex = i;
- sprintf_s(szDevName, "%c:\\%s", m_pNeroDeviceInfos->nsdisDevInfos[i].nsdiDriveLetter, m_pNeroDeviceInfos->nsdisDevInfos[i].nsdiDeviceName);
- #ifdef UNICODE
- int nLen = strlen(szDevName);
- devinfo.strDevName.append((TCHAR*)(convert("GBK", "UCS-2LE", szDevName, nLen).c_str()), nLen);
- #else
- devinfo.strDevName = szDevName;
- #endif
- devinfo.pDevInfo = &m_pNeroDeviceInfos->nsdisDevInfos[i];
- m_vtDevInfo.push_back(devinfo);
- }
- }
- }
- return m_pNeroDeviceInfos ? m_pNeroDeviceInfos->nsdisNumDevInfos : 0;
- }
- void* CNeroImpl::GetDeivceInfo(int nIndex)
- {
- if (m_vtDevInfo.size() == 0 || nIndex > m_vtDevInfo.size())
- return NULL;
- return &m_vtDevInfo.at(nIndex);
- }
- void* CNeroImpl::GetDeivceInfo(const TCHAR *pszDevName)
- {
- for (vector<DeviceInfo>::iterator it = m_vtDevInfo.begin(); it != m_vtDevInfo.end(); it++)
- {
- if (_tcscmp(pszDevName, it->strDevName.c_str()) == 0)
- {
- return &(*it);//或return &m_vtDevInfo.at(it - m_vtDevInfo.begin());
- }
- }
- return NULL;
- }
- void CNeroImpl::AddFiles2Disc(TString strFatherNode, vector<TString> &vtfiles)
- {
- bool IsNullPath = false;
- NERO_ISO_ITEM* pHeadItem = NULL;
- NERO_ISO_ITEM* pNextItem = NULL;
- if (strFatherNode.size() == 0)
- {//所有文件,都加到根目录下;
- IsNullPath = true;
- pHeadItem = m_BurnItem.FindLastItemInSibling(m_BurnItem.GetHeadItem());
- if (pHeadItem == NULL)
- pHeadItem = m_BurnItem.GetVirtualItem();
- }
- else
- {
- pHeadItem = m_BurnItem.FindPathItem(strFatherNode);
- if (!pHeadItem)
- {// 新添根结点;
- pHeadItem = m_BurnItem.AddPath(strFatherNode);
- pHeadItem->isDirectory = TRUE;
- }
- else
- {
- // 找到尾结点;
- pNextItem = m_BurnItem.FindLastItemInSibling(pHeadItem->subDirFirstItem);
- }
- }
- if (pHeadItem)
- {
- if (!IsNullPath)
- {
- for (vector<TString>::iterator it = vtfiles.begin(); it != vtfiles.end(); it++)
- {
- if (pHeadItem->subDirFirstItem)
- pNextItem = m_BurnItem.AddFile2SiblingItem(pNextItem, *it);
- else
- pNextItem = m_BurnItem.AddFile2Path(pHeadItem, *it);
- if (!pNextItem) break;
- }
- }
- else
- {
- for (vector<TString>::iterator it = vtfiles.begin(); it != vtfiles.end(); it++)
- {
- pHeadItem = m_BurnItem.AddFile2SiblingItem(pHeadItem, *it);
- if (!pHeadItem) break;
- }
- }
- }
- }
- void CNeroImpl::AddFolder2Disc(IN CONST TString& folder, NERO_ISO_ITEM* pFolderItem)
- {
- TString path = folder;
- if (path.size() > 0 && _T('\\') != path[path.size() - 1])
- path.append(_T("\\"));
- TString file = _T("*");
- TString s = path + file;
- WIN32_FIND_DATA fileinfo = { 0 };
- HANDLE handle = FindFirstFile(s.c_str(), &fileinfo);
- NERO_ISO_ITEM* pNextItem = NULL;
- if (NULL != handle && INVALID_HANDLE_VALUE != handle)
- {
- do
- {
- // 检查是否超过最大数;
- //if (checklimit()) break;
- // '.'和 '..'的系统文件去除;
- if (_T('.') != fileinfo.cFileName[0])
- {
- if ((FILE_ATTRIBUTE_DIRECTORY & fileinfo.dwFileAttributes) == FILE_ATTRIBUTE_DIRECTORY) // 目录;
- {
- pNextItem = m_BurnItem.FindPathInSibling(pFolderItem->subDirFirstItem, TString(fileinfo.cFileName));
- if (pNextItem == NULL)
- AddFolder2Disc(path + fileinfo.cFileName, m_BurnItem.AddPath2Path(pFolderItem, fileinfo.cFileName));
- else
- AddFolder2Disc(path + fileinfo.cFileName, pNextItem);
- }
- else
- {
- //if (!checklimit())
- if (pFolderItem->subDirFirstItem == NULL)
- pNextItem = m_BurnItem.AddFile2Path(pFolderItem, path + fileinfo.cFileName);
- else
- {
- if (pNextItem == NULL)
- pNextItem = m_BurnItem.FindLastItemInSibling(pFolderItem->subDirFirstItem);
- pNextItem = m_BurnItem.AddFile2SiblingItem(pNextItem, path + fileinfo.cFileName);
- }
- }
- }
- } while (FindNextFile(handle, &fileinfo));
- FindClose(handle);
- }
- }
- void CNeroImpl::AddFolder2Disc(TString strFatherNode, TString strFolder)
- {
- m_BurnItem.InitVituralItem();
- NERO_ISO_ITEM* pFolderItem = NULL;
- if (strFatherNode.size() == 0)
- {//所有文件,都加到根目录下;
- strFatherNode = strFolder;
- if (strFolder[strFolder.size() - 1] == _T('\\'))
- strFatherNode = strFolder.substr(0, strFolder.size() - 1);
- strFatherNode = strFatherNode.substr(strFatherNode.find_last_of('\\') + 1);
- }
- pFolderItem = m_BurnItem.FindPathItem(strFatherNode);
- if (!pFolderItem)
- {// 新添根结点;
- pFolderItem = m_BurnItem.AddPath(strFatherNode);
- }
- if (pFolderItem == NULL)
- return;
- pFolderItem->isDirectory = TRUE;
- AddFolder2Disc(strFolder, pFolderItem);
- }
- bool CNeroImpl::BurnMedia(int nIndex, TString strArtist, TString strTitle)
- {
- // 使用第一个设备来刻录;;
- NERO_SCSI_DEVICE_INFO* nsdiDevice = &m_pNeroDeviceInfos->nsdisDevInfos[0];
- // 打开设备;
- NERO_DEVICEHANDLE hDevice = NeroOpenDevice(nsdiDevice);
- if (!hDevice)
- {
- AfxMessageBox(_T("刻录设备不能打开, 请与系统管理员联系!"), MB_ICONSTOP);
- return false;
- }
- // 读取CD或DVD媒体信息;
- NERO_CD_INFO* pNeroCDInfo = NeroGetCDInfo(hDevice, NGCDI_READ_CD_TEXT | NGCDI_READ_ISRC);
- if (pNeroCDInfo == NULL)
- {
- NeroCloseDevice(hDevice);
- AfxMessageBox(_T("获取光盘失败, 请与系统管理员联系!"), MB_ICONSTOP);
- return false;
- }
- // 光盘不可写;
- if (!pNeroCDInfo->ncdiIsWriteable)
- {
- NeroCloseDevice(hDevice);
- AfxMessageBox(_T("光盘不可写, 请更换新的光盘!"), MB_ICONSTOP);
- return false;
- }
- #if 0
- // 光盘文件系统格式(但是,好像没有用, 估计是SDK版本太老);
- // pNeroCDInfo->ncdiTrackInfos[0].ntiFSType; // NTFST_UDF DVD格式刻录; NTFST_CDRFS CD格式刻录;
- if (m_bDvd && pNeroCDInfo->ncdiTrackInfos[0].ntiFSType == NTFST_CDRFS)
- {
- AfxMessageBox(_T("所选DVD格式刻录,但光盘文件系统是CD格式,请更换DVD文件系统(UDF或新)的光盘!"), MB_ICONSTOP);
- NeroWorkError = true;
- return;
- }
- if (!m_bDvd && pNeroCDInfo->ncdiTrackInfos[0].ntiFSType == NTFST_UDF)
- {
- AfxMessageBox(_T("所选DVD格式刻录,但光盘文件系统是CD格式,请更换DVD文件系统(UDF或新)的光盘!"), MB_ICONSTOP);
- NeroWorkError = true;
- return;
- }
- #endif
- // 设置写CD参数 ;
- NERO_WRITE_CD writeCD;
- memset(&writeCD, 0, sizeof(writeCD));
- writeCD.nwcdpCDStamp = NULL;
- writeCD.nwcdArtist = NULL;
- writeCD.nwcdTitle = NULL;
- writeCD.nwcdCDExtra = FALSE;
- writeCD.nwcdNumTracks = 0;
- // writeCD.nwcdMediaType = m_bDvd ? MEDIA_DVD_ANY : MEDIA_CD; // 这里不是按光盘的媒体类型来赋值;
- writeCD.nwcdMediaType = pNeroCDInfo->ncdiMediaType;
- if (true)
- {// 追加方式刻录;
- NERO_IMPORT_DATA_TRACK_INFO nidtInfo;
- NERO_IMPORT_DATA_TRACK_RESULT nidtResult;
- // Prepare the struct.
- //TString csUserMsg = "";
- memset(&nidtInfo, 0, sizeof(nidtInfo));
- nidtInfo.nidtiSize = sizeof(nidtInfo);
- void* pCDStamp = NULL;
- NERO_ISO_ITEM* pniiItem = NULL;
- pniiItem = NeroImportDataTrack(hDevice, pNeroCDInfo->ncdiNumTracks - 1, &pCDStamp, &nidtInfo, 0, &nidtResult, NULL);
- // If there is a volume name after import, print it out.
- if (nidtInfo.nidtipVolumeName != NULL)
- {
- //csUserMsg.Format("Imported volume name: %s", nidtInfo.nidtipVolumeName);
- //AppendString(csUserMsg);
- NeroFreeMem(nidtInfo.nidtipVolumeName);
- }
- // If there was an error during import, let the user know about it.
- if ((nidtResult != NIDTR_NO_ERROR) || (pniiItem == NULL))
- {
- static LPCSTR errors[] = { "an unknown error","a generic error","a drive error","a read error","a filesystem error","an invalid track number" };
- if (nidtResult > NIDTR_INVALID_TRACKNUMBER)
- nidtResult = NIDTR_NO_ERROR;
- // 释放资源;
- if (pCDStamp != NULL)
- NeroFreeCDStamp(pCDStamp), pCDStamp = NULL;
- NeroFreeMem(pNeroCDInfo);
- NeroCloseDevice(hDevice);
- m_BurnItem.RemoveAllItem();
- return false;
- //csUserMsg.Format("There was %s while importing the track!", errors[nidtResult]);
- //AppendString(csUserMsg);
- }
- else if (m_BurnItem.GetHeadItem() != NULL)
- {
- if (MergeIsoTracks(&m_BurnItem.GetVirtualItem()->subDirFirstItem, pniiItem)) // Merge the new track with the existing one.
- writeCD.nwcdpCDStamp = pCDStamp;
- else
- {
- //AppendString("There was an error while merging tracks!");
- if (pCDStamp != NULL)
- NeroFreeCDStamp(pCDStamp), pCDStamp = NULL;
- }
- }
- }
- #ifdef UNICODE
- writeCD.nwcdIsoTrack = NeroCreateIsoTrackEx(m_BurnItem.GetHeadItem(),
- convert("UCS-2LE", "gb2312", (const char*)strTitle.c_str(), strTitle.size() * sizeof(TCHAR)).c_str(),
- NCITEF_USE_JOLIET | NCITEF_CREATE_ISO_FS);
- #else
- writeCD.nwcdIsoTrack = NeroCreateIsoTrackEx(m_BurnItem.GetHeadItem(), strTitle.c_str(), NCITEF_USE_JOLIET | NCITEF_CREATE_ISO_FS);
- #endif
- // 以追回的方式刻录(NBF_CLOSE_SESSION) : 使用MEDIA_DVD_ANY 或 MEDIA_CD时, NERO_CD_FORMAT固定为NERO_ISO_AUDIO_MEDIA;
- int iRes = NeroBurn(hDevice, NERO_ISO_AUDIO_MEDIA, &writeCD, NBF_WRITE | NBF_CLOSE_SESSION, 0/*Maximum*/, &m_NeroProgress);
- // 释放媒体资源;
- NeroFreeMem(pNeroCDInfo);
- // free memory that was allocated for the track
- if (writeCD.nwcdIsoTrack != NULL)
- NeroFreeIsoTrack(writeCD.nwcdIsoTrack);
- NeroCloseDevice(hDevice);
- m_BurnItem.RemoveAllItem();
- // Free the NERO_WRITE_CD struct too
- if (writeCD.nwcdpCDStamp != NULL)
- NeroFreeCDStamp(writeCD.nwcdpCDStamp), writeCD.nwcdpCDStamp = NULL;
- char* pszLog = NeroGetErrorLog();
- switch (iRes)
- {
- case NEROAPI_BURN_OK:
- AfxMessageBox(_T("刻录成功!"), MB_ICONINFORMATION);
- break;
- case NEROAPI_BURN_UNKNOWN_CD_FORMAT:
- AfxMessageBox(_T("刻录失败:无效刻录盘格式!"), MB_ICONSTOP);
- break;
- case NEROAPI_BURN_INVALID_DRIVE:
- AfxMessageBox(_T("刻录失败:驱动器无效!"), MB_ICONSTOP);
- break;
- case NEROAPI_BURN_FAILED:
- AfxMessageBox(_T("刻录失败!"), MB_ICONSTOP);
- break;
- case NEROAPI_BURN_FUNCTION_NOT_ALLOWED:
- case NEROAPI_BURN_DRIVE_NOT_ALLOWED:
- AfxMessageBox(_T("刻录失败:刻录驱动未安装正确!"), MB_ICONSTOP);
- break;
- default:
- AfxMessageBox(_T("刻录失败:未知错误!"), MB_ICONSTOP);
- break;
- }
- NeroFreeMem(pszLog);
- return true;
- }
- void CNeroImpl::EraseMedia(int nIndex)
- {
- ASSERT(nIndex);
- if (nIndex > m_pNeroDeviceInfos->nsdisNumDevInfos)
- return;
- NERO_SCSI_DEVICE_INFO *pDevInfo = &m_pNeroDeviceInfos->nsdisDevInfos[nIndex];
- NERO_DEVICEHANDLE hNeroDevice = NeroOpenDevice(pDevInfo);
- //NEROAPI_CDRW_ERASE_MODE mode = bEraseEntire ? NEROAPI_ERASE_ENTIRE : NEROAPI_ERASE_QUICK;
- NEROAPI_CDRW_ERASE_MODE mode = NEROAPI_ERASE_ENTIRE;
- int time = NeroGetCDRWErasingTime(hNeroDevice, mode);
- if (time == -1)
- m_strLastError = _T("No CD inserted");
- else if (time == -2)
- m_strLastError = _T("This CD recorder doesn't support CDRW");
- else if (time == -3)
- m_strLastError = _T("This media is not rewritable");
- int err = NeroEraseCDRW(hNeroDevice, mode);
- if (err)
- m_strLastError = _T("Error erasing the CDRW");
- NeroCloseDevice(hNeroDevice);
- }
- bool CNeroImpl::SetWriteSpeed(ULONG nIndex)
- {
- return false;
- }
- void CNeroImpl::NeroCallback(void * pDailog, IdleCallback pIdleCallback, UserDialog pUserDialog, ProgressCallback pProgressCallback, ProgressCallback pSubTaskProgressCallback, AbortedCallback pAbortedCallback, AddLogLine pAddLogLine, SetPhaseCallback pSetPhaseCallback, DisableAbortCallback pDisableAbortCallback, SetMajorPhaseCallback pSetMajorPhaseCallback, WriteIOCallback pWriteIOCallback, ReadIOCallback pReadIOCallback, EOFCallback pEOFCallback, ErrorCallback pErrorCallback)
- {
- CNeroImpl::m_pDailog = (CDialog*)pDailog;
- CNeroImpl::m_pIdelCallback = pIdleCallback;
- CNeroImpl::m_pUserDialog = pUserDialog;
- CNeroImpl::m_pProgressCallback = pProgressCallback;
- CNeroImpl::m_pSubTaskProgressCallback = pSubTaskProgressCallback;
- CNeroImpl::m_pAbortedCallback = pAbortedCallback;
- CNeroImpl::m_pAddLogLine = pAddLogLine;
- CNeroImpl::m_pSetPhaseCallback = pSetPhaseCallback;
- CNeroImpl::m_pDisableAbortCallback = pDisableAbortCallback;
- CNeroImpl::m_pSetMajorPhaseCallback = pSetMajorPhaseCallback;
- CNeroImpl::m_pWriteIOCallback = pWriteIOCallback;
- CNeroImpl::m_pReadIOCallback = pReadIOCallback;
- CNeroImpl::m_pEOFCallback = pEOFCallback;
- CNeroImpl::m_pErrorCallback = pErrorCallback;
- }
- inline LPCSTR GetFilename(const NERO_ISO_ITEM* pItem)
- {
- return (pItem->longFileName != NULL) ? pItem->longFileName : pItem->fileName;
- }
- // The following function performs a merge operation between two iso item trees.
- // The second tree is added onto the first one and the extra items are deleted.
- // As we do not allow to add directories in our file list we do not make recursive
- // calls of this method.
- BOOL CNeroImpl::MergeIsoTracks(NERO_ISO_ITEM** ppniiTarget, NERO_ISO_ITEM* pniiToAdd)
- {
- BOOL bResult = ((ppniiTarget != NULL) && (*ppniiTarget != NULL) && (pniiToAdd != NULL));
- // Two loops. Outer loops the first tree, the inner loops the second tree.
- for (; bResult && (*ppniiTarget != NULL); ppniiTarget = &(*ppniiTarget)->nextItem)
- {
- for (NERO_ISO_ITEM** ppniiToAddLocal = &pniiToAdd; *ppniiToAddLocal != NULL; )
- {
- // Compare entry names...
- if (0 == _stricmp(GetFilename(*ppniiTarget), GetFilename(*ppniiToAddLocal)))
- {
- // If there is a file name conflict between iso items that belong to imported sessions
- // always replace the old files in terms of modification times.
- time_t timeTarget = mktime(&(*ppniiTarget)->entryTime);
- if (timeTarget == (time_t)-1)
- {
- HANDLE hFile = NULL; // handle to file
- FILETIME ftCreationTime; // creation time
- FILETIME ftLastAccessTime; // last access time
- FILETIME ftLastWriteTime; // last write time
- hFile = CreateFileA((*ppniiTarget)->longSourceFilePath, // open the file to get handle
- GENERIC_READ, // open for reading
- FILE_SHARE_READ, // share for reading
- NULL, // no security
- OPEN_EXISTING, // existing file only
- FILE_ATTRIBUTE_NORMAL, // normal file
- NULL); // no attr. template
- if (hFile == INVALID_HANDLE_VALUE)
- {
- CStringA csMsg;
- csMsg.Format("Could not open file: %s.", (*ppniiTarget)->longSourceFilePath);
- //AppendString(csMsg); // show error
- }
- else if (GetFileTime(hFile, &ftCreationTime, &ftLastAccessTime, &ftLastWriteTime))
- timeTarget = CTime(ftLastWriteTime).GetTime();
- if (hFile != INVALID_HANDLE_VALUE)
- CloseHandle(hFile), hFile = NULL;
- }
- time_t timeToAdd = mktime(&(*ppniiToAddLocal)->entryTime);
- // If we have to replace one item, we will now switch places of items in the first and second tree.
- // Since one of the items has to be deleted eventually, this operation will
- // essentially keep the item from the second tree and delete the item from the first tree.
- if (timeTarget < timeToAdd)
- {
- NERO_ISO_ITEM* pniiTmpItem = *ppniiToAddLocal;
- *ppniiToAddLocal = *ppniiTarget;
- *ppniiTarget = pniiTmpItem;
- pniiTmpItem = (*ppniiToAddLocal)->nextItem;
- (*ppniiToAddLocal)->nextItem = (*ppniiTarget)->nextItem;
- (*ppniiTarget)->nextItem = pniiTmpItem;
- }
- // Remove the item from the second tree.
- NERO_ISO_ITEM* pniiTmpItem = *ppniiToAddLocal;
- *ppniiToAddLocal = pniiTmpItem->nextItem;
- pniiTmpItem->nextItem = NULL;
- DeleteIsoItemTree(pniiTmpItem);
- }
- else // No match, advance to the next item.
- ppniiToAddLocal = &(*ppniiToAddLocal)->nextItem;
- }
- }
- // Attach whatever is left of the new tree to the main tree.
- *ppniiTarget = pniiToAdd;
- // Returning true means, everything is fine, continue.
- return bResult;
- }
- // This function deletes the iso tree recursively.
- void CNeroImpl::DeleteIsoItemTree(NERO_ISO_ITEM* pniiItem)
- {
- // First free our own long filename strings, then free the whole tree.
- FreeOurOwnResources(pniiItem);
- NeroFreeIsoItemTree(pniiItem);
- }
- void CNeroImpl::FreeOurOwnResources(NERO_ISO_ITEM* pniiItem)
- {
- // Step through the tree until the ISO item tree pointer becomes NULL
- while (pniiItem != NULL)
- {
- NERO_ISO_ITEM* pniiNextItem = pniiItem->nextItem;
- // We have encountered another ISO item tree; recurse another level.
- if (pniiItem->isDirectory)
- FreeOurOwnResources(pniiItem->subDirFirstItem);
- if (!pniiItem->isReference)
- {
- if (pniiItem->longFileName != NULL)
- free((void*)pniiItem->longFileName), pniiItem->longFileName = NULL;
- if (pniiItem->longSourceFilePath != NULL)
- free((void*)pniiItem->longSourceFilePath), pniiItem->longSourceFilePath = NULL;
- }
- pniiItem = pniiNextItem;
- }
- }
|