// NeroBurn.cpp: implementation of the CNeroBurn class. // ////////////////////////////////////////////////////////////////////// //这个类也是类之间相互引用的一个具体的成功的;例子 #include "stdafx.h" #include "ylgl.h" #include "NeroDlg.h" #include "NeroBurn.h" #include "SelBrunDevice.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// extern CNeroDlg* pDlg; CNeroBurn::CNeroBurn() { NeroBurnOK=false; NeroWorkError=false; #ifdef USE_KERNEL_DLL m_pRootItem = NULL; InitRootItem(); #endif } CNeroBurn::~CNeroBurn() { NeroAPIFree(); for(int i=0; iIdleCallback; nsSettings.nstIdle.ncUserData = pDlg; nsSettings.nstSoftware = pcSoftware; nsSettings.nstUserDialog.ncCallbackFunction = pDlg->UserDialog; nsSettings.nstUserDialog.ncUserData = pDlg; nsSettings.nstLanguageFile =pcLanguageFile; // npProgress will be used during the burn process npProgress.npAbortedCallback = pDlg->AbortedCallback; npProgress.npAddLogLineCallback = pDlg->AddLogLine; npProgress.npDisableAbortCallback = NULL; npProgress.npProgressCallback = pDlg->ProgressCallback; npProgress.npSetPhaseCallback = pDlg->SetPhaseCallback; npProgress.npUserData = pDlg; npProgress.npSetMajorPhaseCallback=NULL; npProgress.npSubTaskProgressCallback=NULL; pndiDeviceInfos = NULL; NEROAPI_INIT_ERROR initErr; initErr = NeroInit(&nsSettings, NULL); switch (initErr) { case NEROAPI_INIT_OK: //AppendString("Initialization of the NeroAPI successful."); break; case NEROAPI_INIT_INVALID_ARGS: { AfxMessageBox("无效的参数, 请与系统管理员联系!", MB_ICONSTOP); return 0; } break; case NEROAPI_INIT_INVALID_SERIAL_NUM: { AfxMessageBox("刻录驱动未正确安装, 请与系统管理员联系!", MB_ICONSTOP); return 0; } break; default: { AfxMessageBox("出现未知错误, 请与系统管理员联系!", MB_ICONSTOP); return 0; } //AppendString("An error occured. The type of error cannot bedetermined."); break; } pndiDeviceInfos = NeroGetAvailableDrivesEx (MEDIA_CD, NULL); int lgl=1; if (!pndiDeviceInfos) { //AppendString("NeroGetAvailableDrives() returned no available devices."); { AfxMessageBox("未找到可用的刻录设备, 请与系统管理员联系!", MB_ICONSTOP); return 0; } } else { if (pndiDeviceInfos->nsdisNumDevInfos > 0) { //AppendString("Found the following devices:"); for (DWORD dDeviceCounter = 0; dDeviceCounter < pndiDeviceInfos->nsdisNumDevInfos; dDeviceCounter++) { //AppendString(pndiDeviceInfos->nsdisDevInfos[dDeviceCounter].nsdiDeviceName); //int i = m_cbxDevices.AddString(pndiDeviceInfos->nsdisDevInfos[dDeviceCounter].nsdiDeviceName); //m_cbxDevices.SetItemDataPtr(i, &pndiDeviceInfos->nsdisDevInfos[dDeviceCounter]); } //m_cbxDevices.SelectString(-1, pndiDeviceInfos->nsdisDevInfos[0].nsdiDeviceName); } else { //AppendString("The number of available devices is 0."); return 0; } } return 1; } void CNeroBurn::NeroAPIFree() { if (pndiDeviceInfos) { NeroFreeMem(pndiDeviceInfos); } NeroClearErrors(); NeroDone(); NeroAPIGlueDone(); return; } // 如果pArray的元素有属于str的子目录或子文件, 将pArray的元素保存到array中; void GetChildArray(CString str, CStringArray *pArray, CStringArray &array) { CString temp; for(int i=0; iGetSize(); i++) { temp=pArray->ElementAt(i); // 截取掉最后一层文件夹,保留前面的; temp=temp.Left(temp.ReverseFind('\\')); if(temp==str) { array.Add (pArray->ElementAt (i)); } } } void GetChildPhotoArray(CString str, CStringArray *pArray, CStringArray &array) { CString temp; for(int i=0; iGetSize (); i++) { temp=pArray->ElementAt (i); // 截取掉最后一层文件夹,保留前面的; temp=temp.Left (temp.ReverseFind ('\\')); if(temp==str) { array.Add (pArray->ElementAt (i)); } } } void CNeroBurn::NeroAPIBurn() { #ifdef USE_KERNEL_DLL DiscBurn(); RemoveRootItem(); return; #endif INT i = 0; // 清空所有NERO_ISO_ITEM元素对象; for( i=0; ifileName,str.Right(str.GetLength()-str.ReverseFind('\\')-1)); strcpy(pMniiFile->sourceFilePath,"c:\\"); #else _tcscpy_s(pMniiFile->fileName, 252, str.Right(str.GetLength()-str.ReverseFind('\\')-1)); _tcscpy_s(pMniiFile->sourceFilePath, 252, "c:\\"); #endif pMniiFile->isDirectory=true; pMniiFile->isReference=false; pMniiFile->unicodeFileName=NULL; if(i==m_DirArray.GetSize ()-1) { pMniiFile->nextItem=NULL; } else {// nextItem指向同类型的元素指针; pMniiFile->nextItem=m_photoMniiArray.ElementAt(i+1); } ////////////////////////// pMniiFile->subDirFirstItem=NULL; ////////////////////////// } // 继续创建根目录以下的文件层和文件; for(i=0;insdisDevInfos[0]; ndhDeviceHandle = NeroOpenDevice(nsdiDevice); if (!ndhDeviceHandle) { AfxMessageBox("刻录设备不能打开, 请与系统管理员联系!", MB_ICONSTOP); NeroWorkError=true; } else { CString title=g_title+"("+m_strCustomerInfo; title+=")客照"; if(m_bDvd) writeCD.nwcdIsoTrack = NeroCreateIsoTrackEx(\ m_photoMniiArray.ElementAt(0),title,NCITEF_USE_JOLIET|NCITEF_CREATE_ISO_FS); else writeCD.nwcdIsoTrack = NeroCreateIsoTrackEx(\ m_photoMniiArray.ElementAt(0),title,NCITEF_USE_JOLIET); int iRes; if(m_bDvd) iRes= NeroBurn(ndhDeviceHandle, NERO_ISO_AUDIO_MEDIA, &writeCD, NBF_WRITE|NBF_CLOSE_SESSION, 10, &npProgress); else iRes= NeroBurn(ndhDeviceHandle, NERO_ISO_AUDIO_CD, &writeCD, NBF_WRITE|NBF_CLOSE_SESSION, 0, &npProgress); //NBF_WRITE|NBF_CLOSE_SESSION NeroFreeIsoTrack(writeCD.nwcdIsoTrack); NeroCloseDevice(ndhDeviceHandle); char* Log = NeroGetErrorLog(); switch(iRes) { case NEROAPI_BURN_OK: AfxMessageBox("刻录成功!", MB_ICONINFORMATION); NeroBurnOK=true; break; case NEROAPI_BURN_UNKNOWN_CD_FORMAT: AfxMessageBox("刻录失败:无效刻录盘格式!", MB_ICONSTOP); NeroWorkError=true; //AppendString ("BurnCD() : unknown CD format"); break; case NEROAPI_BURN_INVALID_DRIVE: //AppendString ("BurnCD() : invalid drive"); AfxMessageBox("刻录失败:驱动器无效!", MB_ICONSTOP); NeroWorkError=true; break; case NEROAPI_BURN_FAILED: AfxMessageBox("刻录失败!", MB_ICONSTOP); NeroWorkError=true; //AppendString ("BurnCD() : burn failed"); break; case NEROAPI_BURN_FUNCTION_NOT_ALLOWED: //AppendString ("BurnCD() : function not allowed"); case NEROAPI_BURN_DRIVE_NOT_ALLOWED: //AppendString ("BurnCD() : drive not allowed"); AfxMessageBox("刻录失败:刻录驱动未安装正确!", MB_ICONSTOP); NeroWorkError=true; break; default: AfxMessageBox("刻录失败:未知错误!", MB_ICONSTOP); NeroWorkError=true; //AppendString ("BurnCD() : unknown error"); break; } } } void CNeroBurn::JoinDir(CString dirname) { CString str; if(GetPosFromName(dirname)==-1) {// 如果目录不在m_DirArray中,要先把根目录加进m_nameArray中; NERO_ISO_ITEM *pMniiFile=new NERO_ISO_ITEM; m_photoMniiArray.Add(pMniiFile); m_nameArray.Add(dirname); str=dirname; #ifdef VC60 strcpy(pMniiFile->fileName,str.Right(str.GetLength()-str.ReverseFind('\\')-1)); strcpy(pMniiFile->sourceFilePath,"c:\\"); #else _tcscpy_s(pMniiFile->fileName, 252, str.Right(str.GetLength()-str.ReverseFind('\\')-1)); _tcscpy_s(pMniiFile->sourceFilePath, 252, "c:\\"); #endif pMniiFile->isDirectory=true; pMniiFile->isReference=false; pMniiFile->unicodeFileName=NULL; pMniiFile->nextItem=NULL; } // dirname这个根目录下的子目录; CStringArray childdirarray; // 子目录下的相片路径; CStringArray childphotoarray; // 将m_pDir中所有dirname的子目录放到childdirarray中; GetChildArray(dirname, m_pDir, childdirarray); // 将dirname目录的所有相片路径保存到childphotoarray中; GetChildPhotoArray(dirname, &(m_pPhotoArray[GetDirPos(dirname)]), childphotoarray); // 获取dirname这个根目录所有子目录个数; int dircount=childdirarray.GetSize (); // 获取dirname这个根目录所有相片张数; int photocount=childphotoarray.GetSize (); // oldcount为尾元素索引; int oldcount=m_photoMniiArray.GetSize(); if( dircount==0 && photocount==0 ) { NERO_ISO_ITEM *pMniiFile=m_photoMniiArray.ElementAt(GetPosFromName(dirname)); pMniiFile->subDirFirstItem=NULL; return; } // 再添加dircount + photocount 个NERO_ISO_ITEM元素; int nn = 0; for( nn=0; nnfileName,str.Right(str.GetLength()-str.ReverseFind('\\')-1)); strcpy(pMniiFile->sourceFilePath,"c:\\"); #else _tcscpy_s(pMniiFile->fileName, 252, str.Right(str.GetLength()-str.ReverseFind('\\')-1)); _tcscpy_s(pMniiFile->sourceFilePath, 252, "c:\\"); #endif pMniiFile->isDirectory=true; pMniiFile->isReference=false; pMniiFile->unicodeFileName=NULL; if(nn==dircount+photocount-1) { pMniiFile->nextItem=NULL; } else { pMniiFile->nextItem=m_photoMniiArray.ElementAt(realpos+oldcount+1); } realpos++; } // 再设置剩余的photocount个元素为文件元素; for(int j=0; jfileName,path.Right(path.GetLength()-path.ReverseFind('\\')-1)); strcpy(pMniiFile->sourceFilePath,path); #else _tcscpy_s(pMniiFile->fileName, 252, path.Right(path.GetLength()-path.ReverseFind('\\')-1)); _tcscpy_s(pMniiFile->sourceFilePath, 252, path); #endif pMniiFile->isDirectory=false; pMniiFile->isReference=false; pMniiFile->unicodeFileName=NULL; if(j==photocount-1) pMniiFile->nextItem=NULL; else pMniiFile->nextItem=m_photoMniiArray.ElementAt(realpos+oldcount+1); realpos++; } int pos=GetPosFromName(dirname); NERO_ISO_ITEM *pMniiFile=m_photoMniiArray.ElementAt(pos); // 设置dirname根元素的NERO_ISO_ITEM的第一个子目录元素指针; pMniiFile->subDirFirstItem=m_photoMniiArray.ElementAt(oldcount); for( nn=0; nnGetSize(); i++) { if(dir==m_pDir->ElementAt(i)) return i; } return -1; } //imapi.exe int CNeroBurn::GetPosFromName(CString dirname) { for(int i=0; iisDirectory = TRUE; m_pRootItem->longFileName = _strdup(_T("光盘根级虚元素")); m_pRootItem->isReference = FALSE; m_pRootItem->unicodeFileName = NULL; m_pRootItem->nextItem = NULL; m_pRootItem->subDirFirstItem = NULL; } return m_pRootItem; } /************************************************************************/ /* 函数:GetDiscItem 描述:返回光盘要刻录的第一个元素。 参数: 返回:返回光盘要刻录的第一个元素。 注意: 示例: */ /************************************************************************/ NERO_ISO_ITEM* CNeroBurn::GetDiscItem() { if ( m_pRootItem == NULL) { if ( InitRootItem() == NULL ) { WriteTextLog(_T("获取光盘根目录失败!")); return NULL; } } if ( m_pRootItem ) return m_pRootItem->subDirFirstItem; else return NULL; } /************************************************************************/ /* 函数:AddSiblingRootItem 描述:将元素添加到根目录的兄弟链中。 参数: pRootItem[IN]:新的根目录兄弟项; 返回:成功添加返回新项,否则返回NULL; 注意:。 示例: */ /************************************************************************/ NERO_ISO_ITEM* CNeroBurn::AddSiblingRootItem( IN NERO_ISO_ITEM* pRootItem ) { if ( m_pRootItem == NULL) { if ( InitRootItem() == NULL ) { WriteTextLog(_T("获取光盘根目录失败!")); return NULL; } } if ( pRootItem == NULL ) return NULL; if ( m_pRootItem->subDirFirstItem == NULL ) {// 当根元素空时,赋值为第一个值; m_pRootItem->subDirFirstItem = pRootItem; } else { NERO_ISO_ITEM* pNextItem = m_pRootItem->subDirFirstItem; while( pNextItem->nextItem ) pNextItem = pNextItem->nextItem; pNextItem->nextItem = pRootItem; } m_vtItems.push_back(pRootItem); return pRootItem; } /************************************************************************/ /* 函数:AddSiblingRootItem 描述:将元素添加到根目录的兄弟链中。 参数: strRootName[IN]:新的根目录兄弟项名称; bIsDirectory[IN]:新的根目录兄弟项类型; 返回:成功添加返回新项,否则返回NULL 注意: 示例: */ /************************************************************************/ NERO_ISO_ITEM* CNeroBurn::AddSiblingRootItem( IN CString strRootName, IN BOOL bIsDirectory ) { if ( strRootName.IsEmpty() ) { WriteTextLog(_T("获取光盘根目录失败!")); return NULL; } if ( m_pRootItem == NULL) { if ( InitRootItem() == NULL ) { WriteTextLog(_T("获取光盘根目录失败!")); return NULL; } } NERO_ISO_ITEM* pRootItem = new NERO_ISO_ITEM; ZeroMemory(pRootItem, sizeof(NERO_ISO_ITEM)); if ( !bIsDirectory ){// 根元素是文件; char path[MAX_PATH]; char* name; GetFullPathName(strRootName, MAX_PATH, path, &name); pRootItem->isDirectory = FALSE; pRootItem->longFileName = _strdup(name); pRootItem->longSourceFilePath = _strdup(path); pRootItem->isReference = FALSE; pRootItem->unicodeFileName = NULL; pRootItem->nextItem = NULL; pRootItem->subDirFirstItem = NULL; }else{ // 根元素是目录; pRootItem->isDirectory = TRUE; pRootItem->longFileName = _strdup(strRootName); pRootItem->isReference = FALSE; pRootItem->unicodeFileName = NULL; pRootItem->nextItem = NULL; pRootItem->subDirFirstItem = NULL; } if ( m_pRootItem->subDirFirstItem == NULL ) { m_pRootItem->subDirFirstItem = pRootItem; } else { NERO_ISO_ITEM* pNextItem = m_pRootItem->subDirFirstItem; while( pNextItem->nextItem ) pNextItem = pNextItem->nextItem; pNextItem->nextItem = pRootItem; } m_vtItems.push_back(pRootItem); return pRootItem; } /************************************************************************/ /* 函数:AddItem2SiblingItem 描述:添加新元素到指定的兄弟项中; 参数: pSiblingItem[IN]: 作为兄弟链的参考兄弟项; pNewItem[IN]:需要添加兄弟链中的新项; 返回: 成功添加返回TRUE,否则返回FALSE; 注意: pSiblingItem不指定具体的类型,如果文件类型(isDirectory==FALSE)或目录类型(isDirectory==TRUE). 示例: */ /************************************************************************/ NERO_ISO_ITEM* CNeroBurn::AddItem2SiblingItem( IN NERO_ISO_ITEM* pSiblingItem, IN NERO_ISO_ITEM* pNewItem) { if ( m_pRootItem == NULL || m_pRootItem->subDirFirstItem == NULL ) { WriteTextLog(_T("获取光盘根目录失败!")); OutputDebugString(_T("\nAddItem2SiblingItem:光盘的根项元素空!\n")); return NULL; } if ( pSiblingItem == NULL ) { WriteTextLog(_T("获取光盘根目录失败!")); OutputDebugString(_T("\nAddItem2SiblingItem:光盘的兄弟项元素空!\n")); return NULL; } NERO_ISO_ITEM* pNextItem = pSiblingItem; while(pNextItem->nextItem) { pNextItem = pNextItem->nextItem; } pNextItem->nextItem = pNewItem; pNewItem->nextItem = NULL; m_vtItems.push_back(pNewItem); return pNewItem; } /************************************************************************/ /* 函数:AddItem2Path 描述:添加新元素到指定的目录下; 参数: strDiscPath[IN]:光盘目录,作为新元素要父目录; pNewItem[IN]:新元素,将插入到strDiscPath目录下; 返回:成功添加返回TRUE,否则返回FALS; 注意: 示例: */ /************************************************************************/ NERO_ISO_ITEM* CNeroBurn::AddItem2Path( IN CString strDiscPath, IN NERO_ISO_ITEM* pNewItem) { if ( m_pRootItem == NULL || m_pRootItem->subDirFirstItem == NULL) { WriteTextLog(_T("获取光盘根目录失败!")); OutputDebugString(_T("\nAddItem2Path:光盘的根项元素空!\n")); return NULL; } if ( strDiscPath.IsEmpty() ) { WriteTextLog(_T("获取光盘根目录失败!")); OutputDebugString(_T("\nAddItem2Path:光盘的兄弟项元素名称空\n")); return NULL; } // 首先查找; NERO_ISO_ITEM *pTailPathItem = FindPathItem(strDiscPath); if ( pTailPathItem == NULL ) { WriteTextLog(_T("获取光盘根目录失败!")); OutputDebugString(_T("\nAddItem2Path:未找到光盘指定路径元素:")); OutputDebugString(strDiscPath); return NULL; } pNewItem->nextItem = NULL; if ( pTailPathItem->subDirFirstItem ) { NERO_ISO_ITEM* pNextItem = pTailPathItem->subDirFirstItem; while ( pNextItem->nextItem ) { pNextItem = pNextItem->nextItem; } pNextItem->nextItem = pNewItem; } else { pTailPathItem->subDirFirstItem = pNewItem; } m_vtItems.push_back(pNewItem); return pNewItem; } /************************************************************************/ /* 函数:AddSiblingPath 描述:添加新目录到指定的光盘目录的兄弟链尾中; 参数: strDiscPath[IN]:光盘目录,作为新元素兄弟链头路径; strNewPath[IN]:新目录,strDiscPath的兄弟项; 返回: 成功返回TRUE,否则返回FALSE; 注意: 示例: */ /************************************************************************/ NERO_ISO_ITEM* CNeroBurn::AddSiblingPath(IN CString strDiscPath, IN CString strNewPath) { // 首先查找; NERO_ISO_ITEM *pTailPathItem = FindPathItem(strDiscPath); if ( pTailPathItem == NULL ) { WriteTextLog(_T("获取光盘根目录失败!")); OutputDebugString(_T("\nAddPath2Path:未找到光盘指定路径元素:")); OutputDebugString(strDiscPath); return NULL; } NERO_ISO_ITEM* pNewItem = new NERO_ISO_ITEM; ZeroMemory(pNewItem,sizeof(NERO_ISO_ITEM)); pNewItem->isDirectory = TRUE; pNewItem->isReference = FALSE; pNewItem->unicodeFileName = NULL; pNewItem->longFileName = _strdup(strNewPath); //sprintf_s(pNewItem->fileName, "%s", strNewPath); pNewItem->subDirFirstItem = NULL; pNewItem->nextItem = NULL; while( pTailPathItem->nextItem ) { pTailPathItem = pTailPathItem->nextItem; } pTailPathItem->nextItem = pNewItem; m_vtItems.push_back(pNewItem); return pNewItem; } /************************************************************************/ /* 函数:AddPath 描述:添加新的目录到光盘目录中,若目录不存在,则重新创建目录元素; 参数: strNewPath[IN]:新目录,根目录的新兄弟项; 返回: 成功返回TRUE,否则返回FALSE; 注意: 示例: */ /************************************************************************/ NERO_ISO_ITEM* CNeroBurn::AddPath(IN CString strNewPath) { INT nIndex = 0; CString strPath = strNewPath; strPath.TrimRight(_T('\\')); strPath += _T("\\"); NERO_ISO_ITEM* pTailPath = NULL; do { nIndex = strPath.ReverseFind(_T('\\')); if ( nIndex != -1 ) { strPath = strPath.Left(nIndex); pTailPath = FindPathItem(strPath); } else {// 最后一个; pTailPath = FindPathItem(strPath); } } while ( !pTailPath && nIndex != -1); if ( pTailPath == NULL ){// 全新目录; pTailPath = m_pRootItem; strNewPath.TrimRight(_T("\\")); strNewPath += _T("\\"); do { nIndex = strNewPath.Find(_T("\\")); if ( nIndex != -1 ) { if ( pTailPath == NULL ) { WriteTextLog(_T("获取光盘根目录失败!")); OutputDebugString(_T("\n添加目录时出错\n")); break; } pTailPath = AddPath2PathItem(pTailPath, strNewPath.Left(nIndex)); strNewPath = strNewPath.Mid(nIndex + 1); } } while ( strNewPath.Find(_T("\\")) != -1 ); } else { if ( strNewPath == strPath ) return pTailPath; strNewPath.Delete(0, strPath.GetLength()+1); strNewPath.TrimRight(_T("\\")); strNewPath += _T("\\"); do { nIndex = strNewPath.Find(_T("\\")); if ( nIndex != -1 ) { if ( pTailPath == NULL ) { WriteTextLog(_T("获取光盘根目录失败!")); OutputDebugString(_T("\n添加目录时出错\n")); break; } pTailPath = AddPath2PathItem(pTailPath, strNewPath.Left(nIndex)); strNewPath = strNewPath.Mid(nIndex + 1); } } while ( strNewPath.Find(_T("\\")) != -1 ); } return pTailPath; } /************************************************************************/ /* 函数:AddPath2Path 描述:添加新目录到指定的光盘目录下; 参数: strDiscPath[IN]:光盘目录,作为新元素要父目录; strNewPath[IN]:新目录,将插入到strDiscPath目录下; 返回: 成功返回TRUE,否则返回FALSE; 注意: 示例: */ /************************************************************************/ NERO_ISO_ITEM* CNeroBurn::AddPath2Path(IN CString strDiscPath, IN CString strNewPath) { // 首先查找; NERO_ISO_ITEM *pTailPathItem = FindPathItem(strDiscPath); if ( pTailPathItem == NULL ) { WriteTextLog(_T("AddPath2Path:无光盘目录")); OutputDebugString(_T("\nAddPath2Path:未找到光盘指定路径元素:")); OutputDebugString(strDiscPath); return NULL; } NERO_ISO_ITEM* pNewItem = new NERO_ISO_ITEM; ZeroMemory(pNewItem,sizeof(NERO_ISO_ITEM)); pNewItem->isDirectory = TRUE; pNewItem->isReference = FALSE; pNewItem->unicodeFileName = NULL; pNewItem->longFileName = _strdup(strNewPath); //sprintf_s(pNewItem->fileName, "%s", strNewPath); pNewItem->subDirFirstItem = NULL; pNewItem->nextItem = NULL; if ( pTailPathItem->subDirFirstItem ) { NERO_ISO_ITEM* pNextItem = pTailPathItem->subDirFirstItem; while ( pNextItem->nextItem ) { pNextItem = pNextItem->nextItem; } pNextItem->nextItem = pNewItem; } else { pTailPathItem->subDirFirstItem = pNewItem; } m_vtItems.push_back(pNewItem); return pNewItem; } /************************************************************************/ /* 函数:AddPath2PathItem 描述:添加新目录到指定的光盘目录下; 参数: pPathItem[IN]:光盘目录,作为新元素要父目录; strNewPath[IN]:新目录,将插入到strDiscPath目录下; 返回: 成功返回TRUE,否则返回FALSE; 注意: 示例: */ /************************************************************************/ NERO_ISO_ITEM* CNeroBurn::AddPath2PathItem(IN NERO_ISO_ITEM* pPathItem, IN CString strNewPath ) { if ( pPathItem == NULL || pPathItem->isDirectory == FALSE ) { WriteTextLog(_T("AddPath2PathItem:目录元素空或非目录元素!")); return NULL; } NERO_ISO_ITEM* pNewItem = new NERO_ISO_ITEM; ZeroMemory(pNewItem,sizeof(NERO_ISO_ITEM)); pNewItem->isDirectory = TRUE; pNewItem->isReference = FALSE; pNewItem->unicodeFileName = NULL; pNewItem->longFileName = _strdup(strNewPath); //sprintf_s(pNewItem->fileName, "%s", strNewPath); pNewItem->subDirFirstItem = NULL; pNewItem->nextItem = NULL; m_vtItems.push_back(pNewItem); if ( pPathItem->subDirFirstItem == NULL ) return pPathItem->subDirFirstItem = pNewItem; NERO_ISO_ITEM* pNextItem = pPathItem->subDirFirstItem; while( pNextItem->nextItem) { pNextItem = pNextItem->nextItem; } return pNextItem->nextItem = pNewItem; } /************************************************************************/ /* 函数:AddFile2Path 描述:添加新文件到指定的光盘目录下; 参数: strDiscPath[IN]:光盘目录,作为新元素的父目录; strFileName[IN]:新文件,将插入到strDiscPath目录下; 返回: 成功返回TRUE,否则返回FALSE; 注意: 示例: */ /************************************************************************/ NERO_ISO_ITEM* CNeroBurn::AddFile2Path(IN CString strDiscPath, IN CString strFileName) { // 首先查找; NERO_ISO_ITEM *pTailPathItem = FindPathItem(strDiscPath); if ( pTailPathItem == NULL ) { pTailPathItem = AddPath(strDiscPath); if ( pTailPathItem == NULL ) { WriteTextLog(_T("AddFile2Path:获取目录项尾元素失败!")); OutputDebugString(_T("\nAddFile2Path:未找到光盘指定路径元素:")); OutputDebugString(strDiscPath); return NULL; } } NERO_ISO_ITEM* pNewItem = new NERO_ISO_ITEM; ZeroMemory(pNewItem, sizeof(NERO_ISO_ITEM)); pNewItem->isDirectory = FALSE; pNewItem->isReference = FALSE; pNewItem->unicodeFileName = NULL; char path[MAX_PATH]; char* name; GetFullPathName(strFileName, MAX_PATH, path, &name); pNewItem->longFileName = _strdup(name); pNewItem->longSourceFilePath = _strdup(path); //sprintf_s(pNewItem->fileName,"%s", strFileName); pNewItem->nextItem = NULL; pNewItem->subDirFirstItem = NULL; if ( pTailPathItem->subDirFirstItem ) { NERO_ISO_ITEM* pNextItem = pTailPathItem->subDirFirstItem; while ( pNextItem->nextItem ) { pNextItem = pNextItem->nextItem; } pNextItem->nextItem = pNewItem; } else { pTailPathItem->subDirFirstItem = pNewItem; } m_vtItems.push_back(pNewItem); return pNewItem; } /************************************************************************/ /* 函数:AddFile2SiblingItem 描述:将文件添加到指定的兄弟项中; 参数: pSiblingItem[IN]: strFileName[IN]: 返回: 注意: 示例: */ /************************************************************************/ NERO_ISO_ITEM* CNeroBurn::AddFile2SiblingItem(IN NERO_ISO_ITEM* pSiblingItem, IN CString strFileName) { if (pSiblingItem == NULL) { WriteTextLog(_T("AddFile2SiblingItem:树兄弟项空!")); OutputDebugString(_T("\nAddFile2SiblingItem:树兄弟项出错!\n")); return NULL; } NERO_ISO_ITEM* pNewItem = new NERO_ISO_ITEM; ZeroMemory(pNewItem, sizeof(NERO_ISO_ITEM)); pNewItem->isDirectory = FALSE; pNewItem->isReference = FALSE; char path[MAX_PATH]; char* name; GetFullPathName(strFileName, MAX_PATH, path, &name); pNewItem->longFileName = _strdup(name); pNewItem->longSourceFilePath = _strdup(path); //sprintf_s(pNewItem->fileName,"%s",strFileName); pNewItem->nextItem = NULL; pNewItem->subDirFirstItem = NULL; NERO_ISO_ITEM* pNextItem = pSiblingItem; while(pNextItem->nextItem) { pNextItem = pNextItem->nextItem; } pNextItem->nextItem = pNewItem; m_vtItems.push_back(pNewItem); return pNewItem; } /************************************************************************/ /* 函数:FindPathItem 描述:查找指定的光盘目录,返回目录元素指针对象; 参数: strDiscPath[IN]:要查找的光盘目录,格式如下:"光盘根目录\子目录1\子目录2\子目录3"; 返回: 若存在该光盘目录,则返回该目录元素对象的指针(返回最后一层目录名对应的元素指针),否则返回NULL; 注意: 示例: */ /************************************************************************/ NERO_ISO_ITEM* CNeroBurn::FindPathItem( IN CString strDiscPath ) { if (strDiscPath.IsEmpty()) { WriteTextLog(_T("FindPathItem:光盘目录参数空!")); return NULL; } if ( m_pRootItem == NULL || m_pRootItem->subDirFirstItem == NULL) { WriteTextLog(_T("FindPathItem:光盘根目录元素空!")); return NULL; } INT nIndex = 0; CStringArray AryLayerName; strDiscPath.TrimRight(_T('\\')); strDiscPath += _T("\\"); do { nIndex = strDiscPath.Find(_T("\\")); if ( nIndex != -1 ) { AryLayerName.Add(strDiscPath.Left(nIndex)); strDiscPath = strDiscPath.Mid(nIndex+1); } } while ( strDiscPath.Find(_T("\\")) != -1 ); NERO_ISO_ITEM *pTailItem = NULL; NERO_ISO_ITEM *pNextItem = m_pRootItem->subDirFirstItem; for ( nIndex = 0; nIndex < AryLayerName.GetSize(); nIndex++ ) { pTailItem = FindPathInSibling(pNextItem, AryLayerName.ElementAt(nIndex)); if ( pTailItem == NULL ) { break; } else { pNextItem = pTailItem->subDirFirstItem; } } if ( (AryLayerName.GetSize() == nIndex) && pTailItem ) { return pTailItem; } return NULL; } /************************************************************************/ /* 函数:FindSiblingPath 描述:在指定的兄弟链中(以及兄弟链中的子链),从兄弟链头元素开始查找指定目录名的元素指针; 参数: pSiblingHeadItem[IN]:兄弟链的头元素,作为查找时的开始位置; strDiscPath[IN]:要在兄弟链中(以及兄弟链中的子链)查找的目录名(只是单层目录名)。 返回: 成功在兄弟链中(以及兄弟链中的子链)查找到该目录名元素,返回该元素对象指针;若未查找到,返回NULL; 注意: 示例: */ /************************************************************************/ NERO_ISO_ITEM* CNeroBurn::FindPathInSibling( IN NERO_ISO_ITEM* pSiblingHeadItem, IN CString& strDiscPath ) { if ( pSiblingHeadItem == NULL ) { WriteTextLog(_T("FindPathInSibling兄弟结点空!")); return NULL; } BOOL bFind = FALSE; NERO_ISO_ITEM* pNextItem = pSiblingHeadItem; do { if (pNextItem->isDirectory) { if ( strDiscPath.CompareNoCase(pNextItem->longFileName) == 0 ) { bFind = TRUE; break; } } pNextItem = pNextItem->nextItem; } while ( pNextItem ); return bFind ? pNextItem : NULL; } /************************************************************************/ /* 函数:FindSiblingNextToLast 描述:返回兄弟链中的倒数第二个元素或者最后一个; 参数: pSiblingHeadItem[IN] 兄弟链的头元素; 返回: 返回兄弟链中的倒数第二个元素或者最后一个; 注意:当兄弟链的只有一个元素时,返回的是本身,也是最后一个; 示例: */ /************************************************************************/ NERO_ISO_ITEM* CNeroBurn::FindSiblingNextToLast( IN NERO_ISO_ITEM* pSiblingHeadItem ) { if ( pSiblingHeadItem == NULL || pSiblingHeadItem->nextItem == NULL ) { return pSiblingHeadItem; } NERO_ISO_ITEM* pSiblingTail = pSiblingHeadItem; while ( pSiblingTail->nextItem->nextItem ) { pSiblingTail = pSiblingTail->nextItem; } return pSiblingTail; } /************************************************************************/ /* 函数:RemoveRootItem 描述:删除整个光盘项; 参数: 返回: 注意: 示例: */ /************************************************************************/ void CNeroBurn::RemoveRootItem() { RemoveAllItem(m_pRootItem); if (m_pRootItem) { if(m_pRootItem->longFileName != NULL) free((void*)m_pRootItem->longFileName), m_pRootItem->longFileName = NULL; if(m_pRootItem->longSourceFilePath != NULL) free((void*)m_pRootItem->longSourceFilePath), m_pRootItem->longSourceFilePath = NULL; delete m_pRootItem; m_pRootItem = NULL; } } /************************************************************************/ /* 函数:RemoveAllItem 描述:删除指定根结点的全部元素; 参数: 返回: 注意: 示例: */ /************************************************************************/ void CNeroBurn::RemoveAllItem(IN NERO_ISO_ITEM* pRootItem) { #if 1 for( vector::iterator it = m_vtItems.begin(); it != m_vtItems.end();) { NERO_ISO_ITEM *pItem = *it; it = m_vtItems.erase(it); if(pItem->longFileName != NULL) free((void*)pItem->longFileName), pItem->longFileName = NULL; if(pItem->longSourceFilePath != NULL) free((void*)pItem->longSourceFilePath), pItem->longSourceFilePath = NULL; delete pItem; pItem = NULL; } return; #else if( pRootItem == NULL ){ WriteTextLog(_T("RemoveChildItem:删除出错!")); OutputDebugString(_T("\nRemoveChildItem:删除出错,!\n")); return; } if ( pRootItem->subDirFirstItem == NULL && pRootItem->nextItem == NULL ){// 最后一个元素; //OutputDebugString(_T("\nRemoveAllItem:目录元素\n")); return; } NERO_ISO_ITEM* pNext2Last = NULL; do { // 查找到兄弟链中的倒第二个(或者最后一个); pNext2Last = FindSiblingNextToLast(pRootItem->subDirFirstItem); NERO_ISO_ITEM* pTailItem = pNext2Last->nextItem; if ( pTailItem ) {// 倒数第二个; if (pTailItem->isDirectory) { RemoveAllItem(pTailItem); } pNext2Last->nextItem = NULL; if(!pTailItem->isReference) { if(pTailItem->longFileName != NULL) free((void*)pTailItem->longFileName), pTailItem->longFileName = NULL; if(pTailItem->longSourceFilePath != NULL) free((void*)pTailItem->longSourceFilePath), pTailItem->longSourceFilePath = NULL; } delete pTailItem; pTailItem = NULL; } else {// 第一个(也是最后一个); if ( pNext2Last->isDirectory ) { RemoveAllItem(pNext2Last); } if(!pNext2Last->isReference) { if(pNext2Last->longFileName != NULL) free((void*)pNext2Last->longFileName), pNext2Last->longFileName = NULL; if(pNext2Last->longSourceFilePath != NULL) free((void*)pNext2Last->longSourceFilePath), pNext2Last->longSourceFilePath = NULL; } delete pNext2Last; pNext2Last = NULL; pRootItem->subDirFirstItem = NULL; } }while( pRootItem->subDirFirstItem ); #endif } void CNeroBurn::DiscBurn() { NERO_WRITE_CD writeCD; memset(&writeCD,0,sizeof(writeCD)); writeCD.nwcdpCDStamp=NULL; writeCD.nwcdArtist=NULL; writeCD.nwcdTitle=NULL; writeCD.nwcdCDExtra=FALSE; writeCD.nwcdNumTracks=0; if(m_bDvd) { writeCD.nwcdMediaType = MEDIA_DVD_ANY; } NERO_SCSI_DEVICE_INFO* nsdiDevice; nsdiDevice =(NERO_SCSI_DEVICE_INFO*)&pndiDeviceInfos->nsdisDevInfos[0]; ndhDeviceHandle = NeroOpenDevice(nsdiDevice); if (!ndhDeviceHandle) { AfxMessageBox(_T("刻录设备不能打开, 请与系统管理员联系!"), MB_ICONSTOP); NeroWorkError=true; } else { CString title = g_title+ _T("(") + m_strCustomerInfo; title += _T(")客照"); if(m_bDvd) writeCD.nwcdIsoTrack = NeroCreateIsoTrackEx(m_pRootItem->subDirFirstItem,title,NCITEF_USE_JOLIET|NCITEF_CREATE_ISO_FS); else writeCD.nwcdIsoTrack = NeroCreateIsoTrackEx(m_pRootItem->subDirFirstItem,title,NCITEF_USE_JOLIET); int iRes; if(m_bDvd) iRes= NeroBurn(ndhDeviceHandle, NERO_ISO_AUDIO_MEDIA, &writeCD, NBF_WRITE|NBF_CLOSE_SESSION, 10, &npProgress); else iRes= NeroBurn(ndhDeviceHandle, NERO_ISO_AUDIO_CD, &writeCD, NBF_WRITE|NBF_CLOSE_SESSION, 0, &npProgress); NeroFreeIsoTrack(writeCD.nwcdIsoTrack); NeroCloseDevice(ndhDeviceHandle); char* Log = NeroGetErrorLog(); switch(iRes) { case NEROAPI_BURN_OK: AfxMessageBox(_T("刻录成功!"), MB_ICONINFORMATION); NeroBurnOK=true; break; case NEROAPI_BURN_UNKNOWN_CD_FORMAT: AfxMessageBox(_T("刻录失败:无效刻录盘格式!"), MB_ICONSTOP); NeroWorkError=true; //AppendString ("BurnCD() : unknown CD format"); break; case NEROAPI_BURN_INVALID_DRIVE: //AppendString ("BurnCD() : invalid drive"); AfxMessageBox(_T("刻录失败:驱动器无效!"), MB_ICONSTOP); NeroWorkError=true; break; case NEROAPI_BURN_FAILED: AfxMessageBox(_T("刻录失败!"), MB_ICONSTOP); NeroWorkError=true; //AppendString ("BurnCD() : burn failed"); break; case NEROAPI_BURN_FUNCTION_NOT_ALLOWED: //AppendString ("BurnCD() : function not allowed"); case NEROAPI_BURN_DRIVE_NOT_ALLOWED: //AppendString ("BurnCD() : drive not allowed"); AfxMessageBox(_T("刻录失败:刻录驱动未安装正确!"), MB_ICONSTOP); NeroWorkError=true; break; default: AfxMessageBox(_T("刻录失败:未知错误!"), MB_ICONSTOP); NeroWorkError=true; //AppendString ("BurnCD() : unknown error"); break; } } } #endif