NeroBurn.cpp 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611
  1. // NeroBurn.cpp: implementation of the CNeroBurn class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. //这个类也是类之间相互引用的一个具体的成功的;例子
  5. #include "stdafx.h"
  6. #include "ylgl.h"
  7. #include "NeroDlg.h"
  8. #include "NeroBurn.h"
  9. #include "SelBrunDevice.h"
  10. #ifdef _DEBUG
  11. #undef THIS_FILE
  12. static char THIS_FILE[]=__FILE__;
  13. #define new DEBUG_NEW
  14. #endif
  15. //////////////////////////////////////////////////////////////////////
  16. // Construction/Destruction
  17. //////////////////////////////////////////////////////////////////////
  18. extern CNeroDlg* pDlg;
  19. CNeroBurn::CNeroBurn()
  20. {
  21. NeroBurnOK=false;
  22. NeroWorkError=false;
  23. #ifdef USE_KERNEL_DLL
  24. m_pRootItem = NULL;
  25. InitRootItem();
  26. #endif
  27. }
  28. CNeroBurn::~CNeroBurn()
  29. {
  30. NeroAPIFree();
  31. for(int i=0; i<m_photoMniiArray.GetSize (); i++)
  32. delete [](m_photoMniiArray.ElementAt (i));
  33. m_photoMniiArray.RemoveAll();
  34. }
  35. BOOL CNeroBurn::NeroAPIInit()
  36. {
  37. DWORD id=FindAppProcessID("imapi.exe");
  38. if(id!=-1)
  39. {
  40. HANDLE ProcessHandle=OpenProcess(PROCESS_ALL_ACCESS,FALSE,id);
  41. if(ProcessHandle)TerminateProcess(ProcessHandle,0);
  42. }
  43. if(!NeroAPIGlueConnect(NULL))
  44. {
  45. AfxMessageBox("刻录驱动未安装, 请与系统管理员联系!", MB_ICONSTOP);
  46. return 0;
  47. }
  48. WORD majhi, majlo, minhi, minlo;
  49. NeroGetAPIVersionEx(&majhi, &majlo, &minhi, &minlo, NULL);
  50. CString strVersion;
  51. strVersion.Format("NeroAPI version %d.%d.%d.%d",
  52. majhi, majlo, minhi, minlo);
  53. #if defined(VC80) || defined(VC70) || defined(VC60)
  54. strcpy(pcNeroFilesPath, "NeroFiles");
  55. strcpy(pcVendor, "nero");
  56. strcpy(pcSoftware, "Nero - Burning Rom");
  57. strcpy(pcLanguageFile, "Nero.txt");
  58. #else
  59. _tcscpy_s(pcNeroFilesPath, 128, _T("NeroFiles"));
  60. _tcscpy_s(pcVendor, 128, _T("nero"));
  61. _tcscpy_s(pcSoftware, 128, _T("Nero - Burning Rom"));
  62. _tcscpy_s(pcLanguageFile, 128, _T("Nero.txt"));
  63. #endif
  64. nsSettings.nstNeroFilesPath = pcNeroFilesPath;
  65. nsSettings.nstVendor = pcVendor;
  66. nsSettings.nstIdle.ncCallbackFunction = (void*)pDlg->IdleCallback;
  67. nsSettings.nstIdle.ncUserData = pDlg;
  68. nsSettings.nstSoftware = pcSoftware;
  69. nsSettings.nstUserDialog.ncCallbackFunction = (void*)pDlg->UserDialog;
  70. nsSettings.nstUserDialog.ncUserData = pDlg;
  71. nsSettings.nstLanguageFile =pcLanguageFile;
  72. // npProgress will be used during the burn process
  73. npProgress.npAbortedCallback = (NERO_ABORTED_CALLBACK)pDlg->AbortedCallback;
  74. npProgress.npAddLogLineCallback = (NERO_ADD_LOG_LINE_CALLBACK)pDlg->AddLogLine;
  75. npProgress.npDisableAbortCallback = NULL;
  76. npProgress.npProgressCallback = (NERO_PROGRESS_CALLBACK)pDlg->ProgressCallback;
  77. npProgress.npSetPhaseCallback = (NERO_SET_PHASE_CALLBACK)pDlg->SetPhaseCallback;
  78. npProgress.npUserData = pDlg;
  79. npProgress.npSetMajorPhaseCallback=NULL;
  80. npProgress.npSubTaskProgressCallback=NULL;
  81. m_pndiDeviceInfos = NULL;
  82. NEROAPI_INIT_ERROR initErr;
  83. initErr = NeroInit(&nsSettings, NULL);
  84. switch (initErr)
  85. {
  86. case NEROAPI_INIT_OK:
  87. break;
  88. case NEROAPI_INIT_INVALID_ARGS:
  89. {
  90. AfxMessageBox("无效的参数, 请与系统管理员联系!", MB_ICONSTOP);
  91. return 0;
  92. }
  93. break;
  94. case NEROAPI_INIT_INVALID_SERIAL_NUM:
  95. {
  96. AfxMessageBox("刻录驱动未正确安装, 请与系统管理员联系!", MB_ICONSTOP);
  97. return 0;
  98. }
  99. break;
  100. default:
  101. {
  102. AfxMessageBox("出现未知错误, 请与系统管理员联系!", MB_ICONSTOP);
  103. return 0;
  104. }
  105. break;
  106. }
  107. // 获取可用的设备;
  108. m_pndiDeviceInfos = NeroGetAvailableDrivesEx(m_bDvd ? MEDIA_DVD_ANY : MEDIA_CD, NULL);
  109. if (!m_pndiDeviceInfos || m_pndiDeviceInfos->nsdisNumDevInfos == 0)
  110. {
  111. AfxMessageBox("未找到可用的刻录设备, 请与系统管理员联系!", MB_ICONSTOP);
  112. return 0;
  113. }
  114. return 1;
  115. }
  116. void CNeroBurn::NeroAPIFree()
  117. {
  118. if (m_pndiDeviceInfos)
  119. {
  120. NeroFreeMem(m_pndiDeviceInfos);
  121. }
  122. NeroClearErrors();
  123. NeroDone();
  124. NeroAPIGlueDone();
  125. return;
  126. }
  127. // 如果pArray的元素有属于str的子目录或子文件, 将pArray的元素保存到array中;
  128. void GetChildArray(CString str, CStringArray *pArray, CStringArray &array)
  129. {
  130. CString temp;
  131. for(int i=0; i<pArray->GetSize(); i++)
  132. {
  133. temp=pArray->ElementAt(i);
  134. // 截取掉最后一层文件夹,保留前面的;
  135. temp=temp.Left(temp.ReverseFind('\\'));
  136. if(temp==str)
  137. {
  138. array.Add (pArray->ElementAt (i));
  139. }
  140. }
  141. }
  142. void GetChildPhotoArray(CString str, CStringArray *pArray, CStringArray &array)
  143. {
  144. CString temp;
  145. for(int i=0; i<pArray->GetSize (); i++)
  146. {
  147. temp=pArray->ElementAt (i);
  148. // 截取掉最后一层文件夹,保留前面的;
  149. temp=temp.Left (temp.ReverseFind ('\\'));
  150. if(temp==str)
  151. {
  152. array.Add (pArray->ElementAt (i));
  153. }
  154. }
  155. }
  156. void CNeroBurn::NeroAPIBurn()
  157. {
  158. #ifdef USE_KERNEL_DLL
  159. DiscBurn();
  160. RemoveRootItem();
  161. return;
  162. #endif
  163. INT i = 0;
  164. // 清空所有NERO_ISO_ITEM元素对象;
  165. for( i=0; i<m_photoMniiArray.GetSize(); i++)
  166. {
  167. delete [](m_photoMniiArray.ElementAt(i));
  168. }
  169. m_photoMniiArray.RemoveAll();
  170. CString str;
  171. // 创建根目录NERO_ISO_ITEM元素;
  172. for(i=0;i<m_DirArray.GetSize ();i++)
  173. {
  174. NERO_ISO_ITEM *pMniiFile=new NERO_ISO_ITEM;
  175. m_photoMniiArray.Add(pMniiFile);
  176. m_nameArray.Add(m_DirArray.ElementAt(i));
  177. }
  178. // 创建完所有根目录NERO_ISO_IMTE元素对象后,设置每个元素isDirectory=TRUE;
  179. for(i=0;i<m_DirArray.GetSize ();i++)
  180. {
  181. NERO_ISO_ITEM *pMniiFile=m_photoMniiArray.ElementAt (i);
  182. str=m_DirRealNameArray.ElementAt (i);
  183. #if defined(VC80) || defined(VC70) || defined(VC60)
  184. strcpy(pMniiFile->fileName,str.Right(str.GetLength()-str.ReverseFind('\\')-1));
  185. strcpy(pMniiFile->sourceFilePath,"c:\\");
  186. #else
  187. _tcscpy_s(pMniiFile->fileName, 252, str.Right(str.GetLength()-str.ReverseFind('\\')-1));
  188. _tcscpy_s(pMniiFile->sourceFilePath, 252, "c:\\");
  189. #endif
  190. pMniiFile->isDirectory=true;
  191. pMniiFile->isReference=false;
  192. pMniiFile->unicodeFileName=NULL;
  193. if(i==m_DirArray.GetSize ()-1)
  194. {
  195. pMniiFile->nextItem=NULL;
  196. }
  197. else
  198. {// nextItem指向同类型的元素指针;
  199. pMniiFile->nextItem=m_photoMniiArray.ElementAt(i+1);
  200. }
  201. //////////////////////////
  202. pMniiFile->subDirFirstItem=NULL;
  203. //////////////////////////
  204. }
  205. // 继续创建根目录以下的文件层和文件;
  206. for(i=0;i<m_DirArray.GetSize ();i++)
  207. {
  208. JoinDir(m_DirArray.ElementAt(i));
  209. }
  210. NERO_WRITE_CD writeCD;
  211. memset(&writeCD,0,sizeof(writeCD));
  212. writeCD.nwcdpCDStamp=NULL;
  213. writeCD.nwcdArtist=NULL;
  214. writeCD.nwcdTitle=NULL;
  215. writeCD.nwcdCDExtra=FALSE;
  216. writeCD.nwcdNumTracks=0;
  217. if(m_bDvd)
  218. {
  219. writeCD.nwcdMediaType = MEDIA_DVD_ANY;
  220. }
  221. NERO_SCSI_DEVICE_INFO* nsdiDevice;
  222. nsdiDevice =(NERO_SCSI_DEVICE_INFO*)&m_pndiDeviceInfos->nsdisDevInfos[0];
  223. m_ndhDeviceHandle = NeroOpenDevice(nsdiDevice);
  224. if (!m_ndhDeviceHandle)
  225. {
  226. AfxMessageBox("刻录设备不能打开, 请与系统管理员联系!", MB_ICONSTOP);
  227. NeroWorkError=true;
  228. }
  229. else
  230. {
  231. CString title=g_title+"("+m_strCustomerInfo;
  232. title+=")客照";
  233. if(m_bDvd)
  234. writeCD.nwcdIsoTrack = NeroCreateIsoTrackEx(\
  235. m_photoMniiArray.ElementAt(0),title,NCITEF_USE_JOLIET|NCITEF_CREATE_ISO_FS);
  236. else
  237. writeCD.nwcdIsoTrack = NeroCreateIsoTrackEx(\
  238. m_photoMniiArray.ElementAt(0),title,NCITEF_USE_JOLIET);
  239. int iRes;
  240. if(m_bDvd)
  241. iRes= NeroBurn(m_ndhDeviceHandle, NERO_ISO_AUDIO_MEDIA, &writeCD,
  242. NBF_WRITE|NBF_CLOSE_SESSION, 10, &npProgress);
  243. else
  244. iRes= NeroBurn(m_ndhDeviceHandle, NERO_ISO_AUDIO_CD, &writeCD,
  245. NBF_WRITE|NBF_CLOSE_SESSION, 0, &npProgress);
  246. //NBF_WRITE|NBF_CLOSE_SESSION
  247. NeroFreeIsoTrack(writeCD.nwcdIsoTrack);
  248. NeroCloseDevice(m_ndhDeviceHandle);
  249. char* Log = NeroGetErrorLog();
  250. switch(iRes)
  251. {
  252. case NEROAPI_BURN_OK:
  253. AfxMessageBox("刻录成功!", MB_ICONINFORMATION);
  254. NeroBurnOK=true;
  255. break;
  256. case NEROAPI_BURN_UNKNOWN_CD_FORMAT:
  257. AfxMessageBox("刻录失败:无效刻录盘格式!", MB_ICONSTOP);
  258. NeroWorkError=true;
  259. //AppendString ("BurnCD() : unknown CD format");
  260. break;
  261. case NEROAPI_BURN_INVALID_DRIVE:
  262. //AppendString ("BurnCD() : invalid drive");
  263. AfxMessageBox("刻录失败:驱动器无效!", MB_ICONSTOP);
  264. NeroWorkError=true;
  265. break;
  266. case NEROAPI_BURN_FAILED:
  267. AfxMessageBox("刻录失败!", MB_ICONSTOP);
  268. NeroWorkError=true;
  269. //AppendString ("BurnCD() : burn failed");
  270. break;
  271. case NEROAPI_BURN_FUNCTION_NOT_ALLOWED:
  272. //AppendString ("BurnCD() : function not allowed");
  273. case NEROAPI_BURN_DRIVE_NOT_ALLOWED:
  274. //AppendString ("BurnCD() : drive not allowed");
  275. AfxMessageBox("刻录失败:刻录驱动未安装正确!", MB_ICONSTOP);
  276. NeroWorkError=true;
  277. break;
  278. default:
  279. AfxMessageBox("刻录失败:未知错误!", MB_ICONSTOP);
  280. NeroWorkError=true;
  281. //AppendString ("BurnCD() : unknown error");
  282. break;
  283. }
  284. }
  285. }
  286. void CNeroBurn::JoinDir(CString dirname)
  287. {
  288. CString str;
  289. if(GetPosFromName(dirname)==-1)
  290. {// 如果目录不在m_DirArray中,要先把根目录加进m_nameArray中;
  291. NERO_ISO_ITEM *pMniiFile=new NERO_ISO_ITEM;
  292. m_photoMniiArray.Add(pMniiFile);
  293. m_nameArray.Add(dirname);
  294. str=dirname;
  295. #if defined(VC80) || defined(VC70) || defined(VC60)
  296. strcpy(pMniiFile->fileName,str.Right(str.GetLength()-str.ReverseFind('\\')-1));
  297. strcpy(pMniiFile->sourceFilePath,"c:\\");
  298. #else
  299. _tcscpy_s(pMniiFile->fileName, 252, str.Right(str.GetLength()-str.ReverseFind('\\')-1));
  300. _tcscpy_s(pMniiFile->sourceFilePath, 252, "c:\\");
  301. #endif
  302. pMniiFile->isDirectory=true;
  303. pMniiFile->isReference=false;
  304. pMniiFile->unicodeFileName=NULL;
  305. pMniiFile->nextItem=NULL;
  306. }
  307. // dirname这个根目录下的子目录;
  308. CStringArray childdirarray;
  309. // 子目录下的相片路径;
  310. CStringArray childphotoarray;
  311. // 将m_pDir中所有dirname的子目录放到childdirarray中;
  312. GetChildArray(dirname, m_pDir, childdirarray);
  313. // 将dirname目录的所有相片路径保存到childphotoarray中;
  314. GetChildPhotoArray(dirname, &(m_pPhotoArray[GetDirPos(dirname)]), childphotoarray);
  315. // 获取dirname这个根目录所有子目录个数;
  316. int dircount=childdirarray.GetSize ();
  317. // 获取dirname这个根目录所有相片张数;
  318. int photocount=childphotoarray.GetSize ();
  319. // oldcount为尾元素索引;
  320. int oldcount=m_photoMniiArray.GetSize();
  321. if( dircount==0 && photocount==0 )
  322. {
  323. NERO_ISO_ITEM *pMniiFile=m_photoMniiArray.ElementAt(GetPosFromName(dirname));
  324. pMniiFile->subDirFirstItem=NULL;
  325. return;
  326. }
  327. // 再添加dircount + photocount 个NERO_ISO_ITEM元素;
  328. int nn = 0;
  329. for( nn=0; nn<dircount+photocount; nn++)
  330. {
  331. NERO_ISO_ITEM *pMniiFile=new NERO_ISO_ITEM;
  332. m_photoMniiArray.Add(pMniiFile);
  333. m_nameArray.Add("");
  334. }
  335. // 设置之前添加的NERO_ISO_ITEM元素中的前dircount个为目录文件;
  336. int realpos=0;
  337. for( nn=0; nn<childdirarray.GetSize (); nn++)
  338. {
  339. str=childdirarray.ElementAt (nn);
  340. NERO_ISO_ITEM *pMniiFile=m_photoMniiArray.ElementAt(realpos+oldcount);
  341. m_nameArray.SetAt(realpos+oldcount, str);
  342. #if defined(VC80) || defined(VC70) || defined(VC60)
  343. strcpy(pMniiFile->fileName,str.Right(str.GetLength()-str.ReverseFind('\\')-1));
  344. strcpy(pMniiFile->sourceFilePath,"c:\\");
  345. #else
  346. _tcscpy_s(pMniiFile->fileName, 252, str.Right(str.GetLength()-str.ReverseFind('\\')-1));
  347. _tcscpy_s(pMniiFile->sourceFilePath, 252, "c:\\");
  348. #endif
  349. pMniiFile->isDirectory=true;
  350. pMniiFile->isReference=false;
  351. pMniiFile->unicodeFileName=NULL;
  352. if(nn==dircount+photocount-1)
  353. {
  354. pMniiFile->nextItem=NULL;
  355. }
  356. else
  357. {
  358. pMniiFile->nextItem=m_photoMniiArray.ElementAt(realpos+oldcount+1);
  359. }
  360. realpos++;
  361. }
  362. // 再设置剩余的photocount个元素为文件元素;
  363. for(int j=0; j<childphotoarray.GetSize(); j++)
  364. {
  365. CString path=childphotoarray.ElementAt(j);
  366. NERO_ISO_ITEM *pMniiFile=m_photoMniiArray.ElementAt(realpos+oldcount);
  367. m_nameArray.SetAt(realpos+oldcount, path);
  368. #if defined(VC80) || defined(VC70) || defined(VC60)
  369. strcpy(pMniiFile->fileName,path.Right(path.GetLength()-path.ReverseFind('\\')-1));
  370. strcpy(pMniiFile->sourceFilePath,path);
  371. #else
  372. _tcscpy_s(pMniiFile->fileName, 252, path.Right(path.GetLength()-path.ReverseFind('\\')-1));
  373. _tcscpy_s(pMniiFile->sourceFilePath, 252, path);
  374. #endif
  375. pMniiFile->isDirectory=false;
  376. pMniiFile->isReference=false;
  377. pMniiFile->unicodeFileName=NULL;
  378. if(j==photocount-1)
  379. pMniiFile->nextItem=NULL;
  380. else
  381. pMniiFile->nextItem=m_photoMniiArray.ElementAt(realpos+oldcount+1);
  382. realpos++;
  383. }
  384. int pos=GetPosFromName(dirname);
  385. NERO_ISO_ITEM *pMniiFile=m_photoMniiArray.ElementAt(pos);
  386. // 设置dirname根元素的NERO_ISO_ITEM的第一个子目录元素指针;
  387. pMniiFile->subDirFirstItem=m_photoMniiArray.ElementAt(oldcount);
  388. for( nn=0; nn<childdirarray.GetSize (); nn++)
  389. {
  390. JoinDir(childdirarray.ElementAt (nn));
  391. }
  392. }
  393. int CNeroBurn::GetDirPos(CString dir)
  394. {
  395. for(int i=0; i<m_pDir->GetSize(); i++)
  396. {
  397. if(dir==m_pDir->ElementAt(i))
  398. return i;
  399. }
  400. return -1;
  401. }
  402. //imapi.exe
  403. int CNeroBurn::GetPosFromName(CString dirname)
  404. {
  405. for(int i=0; i<m_nameArray.GetSize(); i++)
  406. {
  407. if(dirname==m_nameArray.ElementAt(i))
  408. return i;
  409. }
  410. return -1;
  411. }
  412. #ifdef USE_KERNEL_DLL
  413. /************************************************************************/
  414. /*
  415. 函数:InitRootItem
  416. 描述:初始化光盘。
  417. 参数:
  418. 返回:返回光盘根虚拟元素。
  419. 注意:
  420. 示例:
  421. */
  422. /************************************************************************/
  423. NERO_ISO_ITEM* CNeroBurn::InitRootItem()
  424. {
  425. if ( m_pRootItem == NULL )
  426. {
  427. m_pRootItem = new NERO_ISO_ITEM;
  428. ZeroMemory(m_pRootItem, sizeof(NERO_ISO_ITEM));
  429. m_pRootItem->isDirectory = TRUE;
  430. m_pRootItem->longFileName = _strdup(_T("光盘根级虚元素"));
  431. m_pRootItem->isReference = FALSE;
  432. m_pRootItem->unicodeFileName = NULL;
  433. m_pRootItem->nextItem = NULL;
  434. m_pRootItem->subDirFirstItem = NULL;
  435. }
  436. return m_pRootItem;
  437. }
  438. /************************************************************************/
  439. /*
  440. 函数:GetDiscItem
  441. 描述:返回光盘要刻录的第一个元素。
  442. 参数:
  443. 返回:返回光盘要刻录的第一个元素。
  444. 注意:
  445. 示例:
  446. */
  447. /************************************************************************/
  448. NERO_ISO_ITEM* CNeroBurn::GetDiscItem()
  449. {
  450. if ( m_pRootItem == NULL)
  451. {
  452. if ( InitRootItem() == NULL )
  453. {
  454. WriteTextLog(_T("获取光盘根目录失败!"));
  455. return NULL;
  456. }
  457. }
  458. if ( m_pRootItem )
  459. return m_pRootItem->subDirFirstItem;
  460. else
  461. return NULL;
  462. }
  463. /************************************************************************/
  464. /*
  465. 函数:AddSiblingRootItem
  466. 描述:将元素添加到根目录的兄弟链中。
  467. 参数:
  468. pRootItem[IN]:新的根目录兄弟项;
  469. 返回:成功添加返回新项,否则返回NULL;
  470. 注意:。
  471. 示例:
  472. */
  473. /************************************************************************/
  474. NERO_ISO_ITEM* CNeroBurn::AddSiblingRootItem( IN NERO_ISO_ITEM* pRootItem )
  475. {
  476. if ( m_pRootItem == NULL)
  477. {
  478. if ( InitRootItem() == NULL )
  479. {
  480. WriteTextLog(_T("获取光盘根目录失败!"));
  481. return NULL;
  482. }
  483. }
  484. if ( pRootItem == NULL )
  485. return NULL;
  486. if ( m_pRootItem->subDirFirstItem == NULL )
  487. {// 当根元素空时,赋值为第一个值;
  488. m_pRootItem->subDirFirstItem = pRootItem;
  489. }
  490. else
  491. {
  492. NERO_ISO_ITEM* pNextItem = m_pRootItem->subDirFirstItem;
  493. while( pNextItem->nextItem )
  494. pNextItem = pNextItem->nextItem;
  495. pNextItem->nextItem = pRootItem;
  496. }
  497. m_vtItems.push_back(pRootItem);
  498. return pRootItem;
  499. }
  500. /************************************************************************/
  501. /*
  502. 函数:AddSiblingRootItem
  503. 描述:将元素添加到根目录的兄弟链中。
  504. 参数:
  505. strRootName[IN]:新的根目录兄弟项名称;
  506. bIsDirectory[IN]:新的根目录兄弟项类型;
  507. 返回:成功添加返回新项,否则返回NULL
  508. 注意:
  509. 示例:
  510. */
  511. /************************************************************************/
  512. NERO_ISO_ITEM* CNeroBurn::AddSiblingRootItem( IN CString strRootName, IN BOOL bIsDirectory )
  513. {
  514. if ( strRootName.IsEmpty() )
  515. {
  516. WriteTextLog(_T("获取光盘根目录失败!"));
  517. return NULL;
  518. }
  519. if ( m_pRootItem == NULL)
  520. {
  521. if ( InitRootItem() == NULL )
  522. {
  523. WriteTextLog(_T("获取光盘根目录失败!"));
  524. return NULL;
  525. }
  526. }
  527. NERO_ISO_ITEM* pRootItem = new NERO_ISO_ITEM;
  528. ZeroMemory(pRootItem, sizeof(NERO_ISO_ITEM));
  529. if ( !bIsDirectory ){// 根元素是文件;
  530. char path[MAX_PATH];
  531. char* name;
  532. GetFullPathName(strRootName, MAX_PATH, path, &name);
  533. pRootItem->isDirectory = FALSE;
  534. pRootItem->longFileName = _strdup(name);
  535. pRootItem->longSourceFilePath = _strdup(path);
  536. pRootItem->isReference = FALSE;
  537. pRootItem->unicodeFileName = NULL;
  538. pRootItem->nextItem = NULL;
  539. pRootItem->subDirFirstItem = NULL;
  540. }else{ // 根元素是目录;
  541. pRootItem->isDirectory = TRUE;
  542. pRootItem->longFileName = _strdup(strRootName);
  543. pRootItem->isReference = FALSE;
  544. pRootItem->unicodeFileName = NULL;
  545. pRootItem->nextItem = NULL;
  546. pRootItem->subDirFirstItem = NULL;
  547. }
  548. if ( m_pRootItem->subDirFirstItem == NULL )
  549. {
  550. m_pRootItem->subDirFirstItem = pRootItem;
  551. }
  552. else
  553. {
  554. NERO_ISO_ITEM* pNextItem = m_pRootItem->subDirFirstItem;
  555. while( pNextItem->nextItem )
  556. pNextItem = pNextItem->nextItem;
  557. pNextItem->nextItem = pRootItem;
  558. }
  559. m_vtItems.push_back(pRootItem);
  560. return pRootItem;
  561. }
  562. /************************************************************************/
  563. /*
  564. 函数:AddItem2SiblingItem
  565. 描述:添加新元素到指定的兄弟项中;
  566. 参数:
  567. pSiblingItem[IN]: 作为兄弟链的参考兄弟项;
  568. pNewItem[IN]:需要添加兄弟链中的新项;
  569. 返回:
  570. 成功添加返回TRUE,否则返回FALSE;
  571. 注意:
  572. pSiblingItem不指定具体的类型,如果文件类型(isDirectory==FALSE)或目录类型(isDirectory==TRUE).
  573. 示例:
  574. */
  575. /************************************************************************/
  576. NERO_ISO_ITEM* CNeroBurn::AddItem2SiblingItem( IN NERO_ISO_ITEM* pSiblingItem, IN NERO_ISO_ITEM* pNewItem)
  577. {
  578. if ( m_pRootItem == NULL || m_pRootItem->subDirFirstItem == NULL )
  579. {
  580. WriteTextLog(_T("获取光盘根目录失败!"));
  581. OutputDebugString(_T("\nAddItem2SiblingItem:光盘的根项元素空!\n"));
  582. return NULL;
  583. }
  584. if ( pSiblingItem == NULL )
  585. {
  586. WriteTextLog(_T("获取光盘根目录失败!"));
  587. OutputDebugString(_T("\nAddItem2SiblingItem:光盘的兄弟项元素空!\n"));
  588. return NULL;
  589. }
  590. NERO_ISO_ITEM* pNextItem = pSiblingItem;
  591. while(pNextItem->nextItem)
  592. {
  593. pNextItem = pNextItem->nextItem;
  594. }
  595. pNextItem->nextItem = pNewItem;
  596. pNewItem->nextItem = NULL;
  597. m_vtItems.push_back(pNewItem);
  598. return pNewItem;
  599. }
  600. /************************************************************************/
  601. /*
  602. 函数:AddItem2Path
  603. 描述:添加新元素到指定的目录下;
  604. 参数:
  605. strDiscPath[IN]:光盘目录,作为新元素要父目录;
  606. pNewItem[IN]:新元素,将插入到strDiscPath目录下;
  607. 返回:成功添加返回TRUE,否则返回FALS;
  608. 注意:
  609. 示例:
  610. */
  611. /************************************************************************/
  612. NERO_ISO_ITEM* CNeroBurn::AddItem2Path( IN CString strDiscPath, IN NERO_ISO_ITEM* pNewItem)
  613. {
  614. if ( m_pRootItem == NULL || m_pRootItem->subDirFirstItem == NULL)
  615. {
  616. WriteTextLog(_T("获取光盘根目录失败!"));
  617. OutputDebugString(_T("\nAddItem2Path:光盘的根项元素空!\n"));
  618. return NULL;
  619. }
  620. if ( strDiscPath.IsEmpty() )
  621. {
  622. WriteTextLog(_T("获取光盘根目录失败!"));
  623. OutputDebugString(_T("\nAddItem2Path:光盘的兄弟项元素名称空\n"));
  624. return NULL;
  625. }
  626. // 首先查找;
  627. NERO_ISO_ITEM *pTailPathItem = FindPathItem(strDiscPath);
  628. if ( pTailPathItem == NULL )
  629. {
  630. WriteTextLog(_T("获取光盘根目录失败!"));
  631. OutputDebugString(_T("\nAddItem2Path:未找到光盘指定路径元素:"));
  632. OutputDebugString(strDiscPath);
  633. return NULL;
  634. }
  635. pNewItem->nextItem = NULL;
  636. if ( pTailPathItem->subDirFirstItem )
  637. {
  638. NERO_ISO_ITEM* pNextItem = pTailPathItem->subDirFirstItem;
  639. while ( pNextItem->nextItem )
  640. {
  641. pNextItem = pNextItem->nextItem;
  642. }
  643. pNextItem->nextItem = pNewItem;
  644. }
  645. else
  646. {
  647. pTailPathItem->subDirFirstItem = pNewItem;
  648. }
  649. m_vtItems.push_back(pNewItem);
  650. return pNewItem;
  651. }
  652. /************************************************************************/
  653. /*
  654. 函数:AddSiblingPath
  655. 描述:添加新目录到指定的光盘目录的兄弟链尾中;
  656. 参数:
  657. strDiscPath[IN]:光盘目录,作为新元素兄弟链头路径;
  658. strNewPath[IN]:新目录,strDiscPath的兄弟项;
  659. 返回:
  660. 成功返回TRUE,否则返回FALSE;
  661. 注意:
  662. 示例:
  663. */
  664. /************************************************************************/
  665. NERO_ISO_ITEM* CNeroBurn::AddSiblingPath(IN CString strDiscPath, IN CString strNewPath)
  666. {
  667. // 首先查找;
  668. NERO_ISO_ITEM *pTailPathItem = FindPathItem(strDiscPath);
  669. if ( pTailPathItem == NULL )
  670. {
  671. WriteTextLog(_T("获取光盘根目录失败!"));
  672. OutputDebugString(_T("\nAddPath2Path:未找到光盘指定路径元素:"));
  673. OutputDebugString(strDiscPath);
  674. return NULL;
  675. }
  676. NERO_ISO_ITEM* pNewItem = new NERO_ISO_ITEM;
  677. ZeroMemory(pNewItem,sizeof(NERO_ISO_ITEM));
  678. pNewItem->isDirectory = TRUE;
  679. pNewItem->isReference = FALSE;
  680. pNewItem->unicodeFileName = NULL;
  681. pNewItem->longFileName = _strdup(strNewPath);
  682. //sprintf_s(pNewItem->fileName, "%s", strNewPath);
  683. pNewItem->subDirFirstItem = NULL;
  684. pNewItem->nextItem = NULL;
  685. while( pTailPathItem->nextItem )
  686. {
  687. pTailPathItem = pTailPathItem->nextItem;
  688. }
  689. pTailPathItem->nextItem = pNewItem;
  690. m_vtItems.push_back(pNewItem);
  691. return pNewItem;
  692. }
  693. /************************************************************************/
  694. /*
  695. 函数:AddPath
  696. 描述:添加新的目录到光盘目录中,若目录不存在,则重新创建目录元素;
  697. 参数:
  698. strNewPath[IN]:新目录,根目录的新兄弟项;
  699. 返回:
  700. 成功返回TRUE,否则返回FALSE;
  701. 注意:
  702. 示例:
  703. */
  704. /************************************************************************/
  705. NERO_ISO_ITEM* CNeroBurn::AddPath(IN CString strNewPath)
  706. {
  707. INT nIndex = 0;
  708. CString strPath = strNewPath;
  709. strPath.TrimRight(_T('\\'));
  710. strPath += _T("\\");
  711. NERO_ISO_ITEM* pTailPath = NULL;
  712. do
  713. {
  714. nIndex = strPath.ReverseFind(_T('\\'));
  715. if ( nIndex != -1 )
  716. {
  717. strPath = strPath.Left(nIndex);
  718. pTailPath = FindPathItem(strPath);
  719. }
  720. else
  721. {// 最后一个;
  722. pTailPath = FindPathItem(strPath);
  723. }
  724. } while ( !pTailPath && nIndex != -1);
  725. if ( pTailPath == NULL ){// 全新目录;
  726. pTailPath = m_pRootItem;
  727. strNewPath.TrimRight(_T("\\"));
  728. strNewPath += _T("\\");
  729. do
  730. {
  731. nIndex = strNewPath.Find(_T("\\"));
  732. if ( nIndex != -1 )
  733. {
  734. if ( pTailPath == NULL )
  735. {
  736. WriteTextLog(_T("获取光盘根目录失败!"));
  737. OutputDebugString(_T("\n添加目录时出错\n"));
  738. break;
  739. }
  740. pTailPath = AddPath2PathItem(pTailPath, strNewPath.Left(nIndex));
  741. strNewPath = strNewPath.Mid(nIndex + 1);
  742. }
  743. } while ( strNewPath.Find(_T("\\")) != -1 );
  744. }
  745. else
  746. {
  747. if ( strNewPath == strPath )
  748. return pTailPath;
  749. strNewPath.Delete(0, strPath.GetLength()+1);
  750. strNewPath.TrimRight(_T("\\"));
  751. strNewPath += _T("\\");
  752. do {
  753. nIndex = strNewPath.Find(_T("\\"));
  754. if ( nIndex != -1 )
  755. {
  756. if ( pTailPath == NULL )
  757. {
  758. WriteTextLog(_T("获取光盘根目录失败!"));
  759. OutputDebugString(_T("\n添加目录时出错\n"));
  760. break;
  761. }
  762. pTailPath = AddPath2PathItem(pTailPath, strNewPath.Left(nIndex));
  763. strNewPath = strNewPath.Mid(nIndex + 1);
  764. }
  765. } while ( strNewPath.Find(_T("\\")) != -1 );
  766. }
  767. return pTailPath;
  768. }
  769. /************************************************************************/
  770. /*
  771. 函数:AddPath2Path
  772. 描述:添加新目录到指定的光盘目录下;
  773. 参数:
  774. strDiscPath[IN]:光盘目录,作为新元素要父目录;
  775. strNewPath[IN]:新目录,将插入到strDiscPath目录下;
  776. 返回:
  777. 成功返回TRUE,否则返回FALSE;
  778. 注意:
  779. 示例:
  780. */
  781. /************************************************************************/
  782. NERO_ISO_ITEM* CNeroBurn::AddPath2Path(IN CString strDiscPath, IN CString strNewPath)
  783. {
  784. // 首先查找;
  785. NERO_ISO_ITEM *pTailPathItem = FindPathItem(strDiscPath);
  786. if ( pTailPathItem == NULL )
  787. {
  788. WriteTextLog(_T("AddPath2Path:无光盘目录"));
  789. OutputDebugString(_T("\nAddPath2Path:未找到光盘指定路径元素:"));
  790. OutputDebugString(strDiscPath);
  791. return NULL;
  792. }
  793. NERO_ISO_ITEM* pNewItem = new NERO_ISO_ITEM;
  794. ZeroMemory(pNewItem,sizeof(NERO_ISO_ITEM));
  795. pNewItem->isDirectory = TRUE;
  796. pNewItem->isReference = FALSE;
  797. pNewItem->unicodeFileName = NULL;
  798. pNewItem->longFileName = _strdup(strNewPath);
  799. //sprintf_s(pNewItem->fileName, "%s", strNewPath);
  800. pNewItem->subDirFirstItem = NULL;
  801. pNewItem->nextItem = NULL;
  802. if ( pTailPathItem->subDirFirstItem )
  803. {
  804. NERO_ISO_ITEM* pNextItem = pTailPathItem->subDirFirstItem;
  805. while ( pNextItem->nextItem )
  806. {
  807. pNextItem = pNextItem->nextItem;
  808. }
  809. pNextItem->nextItem = pNewItem;
  810. }
  811. else
  812. {
  813. pTailPathItem->subDirFirstItem = pNewItem;
  814. }
  815. m_vtItems.push_back(pNewItem);
  816. return pNewItem;
  817. }
  818. /************************************************************************/
  819. /*
  820. 函数:AddPath2PathItem
  821. 描述:添加新目录到指定的光盘目录下;
  822. 参数:
  823. pPathItem[IN]:光盘目录,作为新元素要父目录;
  824. strNewPath[IN]:新目录,将插入到strDiscPath目录下;
  825. 返回:
  826. 成功返回TRUE,否则返回FALSE;
  827. 注意:
  828. 示例:
  829. */
  830. /************************************************************************/
  831. NERO_ISO_ITEM* CNeroBurn::AddPath2PathItem(IN NERO_ISO_ITEM* pPathItem, IN CString strNewPath )
  832. {
  833. if ( pPathItem == NULL || pPathItem->isDirectory == FALSE )
  834. {
  835. WriteTextLog(_T("AddPath2PathItem:目录元素空或非目录元素!"));
  836. return NULL;
  837. }
  838. NERO_ISO_ITEM* pNewItem = new NERO_ISO_ITEM;
  839. ZeroMemory(pNewItem,sizeof(NERO_ISO_ITEM));
  840. pNewItem->isDirectory = TRUE;
  841. pNewItem->isReference = FALSE;
  842. pNewItem->unicodeFileName = NULL;
  843. pNewItem->longFileName = _strdup(strNewPath);
  844. //sprintf_s(pNewItem->fileName, "%s", strNewPath);
  845. pNewItem->subDirFirstItem = NULL;
  846. pNewItem->nextItem = NULL;
  847. m_vtItems.push_back(pNewItem);
  848. if ( pPathItem->subDirFirstItem == NULL )
  849. return pPathItem->subDirFirstItem = pNewItem;
  850. NERO_ISO_ITEM* pNextItem = pPathItem->subDirFirstItem;
  851. while( pNextItem->nextItem)
  852. {
  853. pNextItem = pNextItem->nextItem;
  854. }
  855. return pNextItem->nextItem = pNewItem;
  856. }
  857. /************************************************************************/
  858. /*
  859. 函数:AddFile2Path
  860. 描述:添加新文件到指定的光盘目录下;
  861. 参数:
  862. strDiscPath[IN]:光盘目录,作为新元素的父目录;
  863. strFileName[IN]:新文件,将插入到strDiscPath目录下;
  864. 返回:
  865. 成功返回TRUE,否则返回FALSE;
  866. 注意:
  867. 示例:
  868. */
  869. /************************************************************************/
  870. NERO_ISO_ITEM* CNeroBurn::AddFile2Path(IN CString strDiscPath, IN CString strFileName)
  871. {
  872. // 首先查找;
  873. NERO_ISO_ITEM *pTailPathItem = FindPathItem(strDiscPath);
  874. if ( pTailPathItem == NULL )
  875. {
  876. pTailPathItem = AddPath(strDiscPath);
  877. if ( pTailPathItem == NULL )
  878. {
  879. WriteTextLog(_T("AddFile2Path:获取目录项尾元素失败!"));
  880. OutputDebugString(_T("\nAddFile2Path:未找到光盘指定路径元素:"));
  881. OutputDebugString(strDiscPath);
  882. return NULL;
  883. }
  884. }
  885. NERO_ISO_ITEM* pNewItem = new NERO_ISO_ITEM;
  886. ZeroMemory(pNewItem, sizeof(NERO_ISO_ITEM));
  887. pNewItem->isDirectory = FALSE;
  888. pNewItem->isReference = FALSE;
  889. pNewItem->unicodeFileName = NULL;
  890. char path[MAX_PATH];
  891. char* name;
  892. GetFullPathName(strFileName, MAX_PATH, path, &name);
  893. pNewItem->longFileName = _strdup(name);
  894. pNewItem->longSourceFilePath = _strdup(path);
  895. //sprintf_s(pNewItem->fileName,"%s", strFileName);
  896. pNewItem->nextItem = NULL;
  897. pNewItem->subDirFirstItem = NULL;
  898. if ( pTailPathItem->subDirFirstItem )
  899. {
  900. NERO_ISO_ITEM* pNextItem = pTailPathItem->subDirFirstItem;
  901. while ( pNextItem->nextItem )
  902. {
  903. pNextItem = pNextItem->nextItem;
  904. }
  905. pNextItem->nextItem = pNewItem;
  906. }
  907. else
  908. {
  909. pTailPathItem->subDirFirstItem = pNewItem;
  910. }
  911. m_vtItems.push_back(pNewItem);
  912. return pNewItem;
  913. }
  914. /************************************************************************/
  915. /*
  916. 函数:AddFile2SiblingItem
  917. 描述:将文件添加到指定的兄弟项中;
  918. 参数:
  919. pSiblingItem[IN]:
  920. strFileName[IN]:
  921. 返回:
  922. 注意:
  923. 示例:
  924. */
  925. /************************************************************************/
  926. NERO_ISO_ITEM* CNeroBurn::AddFile2SiblingItem(IN NERO_ISO_ITEM* pSiblingItem, IN CString strFileName)
  927. {
  928. if (pSiblingItem == NULL)
  929. {
  930. WriteTextLog(_T("AddFile2SiblingItem:树兄弟项空!"));
  931. OutputDebugString(_T("\nAddFile2SiblingItem:树兄弟项出错!\n"));
  932. return NULL;
  933. }
  934. NERO_ISO_ITEM* pNewItem = new NERO_ISO_ITEM;
  935. ZeroMemory(pNewItem, sizeof(NERO_ISO_ITEM));
  936. pNewItem->isDirectory = FALSE;
  937. pNewItem->isReference = FALSE;
  938. char path[MAX_PATH];
  939. char* name;
  940. GetFullPathName(strFileName, MAX_PATH, path, &name);
  941. pNewItem->longFileName = _strdup(name);
  942. pNewItem->longSourceFilePath = _strdup(path);
  943. //sprintf_s(pNewItem->fileName,"%s",strFileName);
  944. pNewItem->nextItem = NULL;
  945. pNewItem->subDirFirstItem = NULL;
  946. NERO_ISO_ITEM* pNextItem = pSiblingItem;
  947. while(pNextItem->nextItem)
  948. {
  949. pNextItem = pNextItem->nextItem;
  950. }
  951. pNextItem->nextItem = pNewItem;
  952. m_vtItems.push_back(pNewItem);
  953. return pNewItem;
  954. }
  955. /************************************************************************/
  956. /*
  957. 函数:FindPathItem
  958. 描述:查找指定的光盘目录,返回目录元素指针对象;
  959. 参数:
  960. strDiscPath[IN]:要查找的光盘目录,格式如下:"光盘根目录\子目录1\子目录2\子目录3";
  961. 返回:
  962. 若存在该光盘目录,则返回该目录元素对象的指针(返回最后一层目录名对应的元素指针),否则返回NULL;
  963. 注意:
  964. 示例:
  965. */
  966. /************************************************************************/
  967. NERO_ISO_ITEM* CNeroBurn::FindPathItem( IN CString strDiscPath )
  968. {
  969. if (strDiscPath.IsEmpty())
  970. {
  971. WriteTextLog(_T("FindPathItem:光盘目录参数空!"));
  972. return NULL;
  973. }
  974. if ( m_pRootItem == NULL || m_pRootItem->subDirFirstItem == NULL)
  975. {
  976. WriteTextLog(_T("FindPathItem:光盘根目录元素空!"));
  977. return NULL;
  978. }
  979. INT nIndex = 0;
  980. CStringArray AryLayerName;
  981. strDiscPath.TrimRight(_T('\\'));
  982. strDiscPath += _T("\\");
  983. do
  984. {
  985. nIndex = strDiscPath.Find(_T("\\"));
  986. if ( nIndex != -1 )
  987. {
  988. AryLayerName.Add(strDiscPath.Left(nIndex));
  989. strDiscPath = strDiscPath.Mid(nIndex+1);
  990. }
  991. } while ( strDiscPath.Find(_T("\\")) != -1 );
  992. NERO_ISO_ITEM *pTailItem = NULL;
  993. NERO_ISO_ITEM *pNextItem = m_pRootItem->subDirFirstItem;
  994. for ( nIndex = 0; nIndex < AryLayerName.GetSize(); nIndex++ )
  995. {
  996. pTailItem = FindPathInSibling(pNextItem, AryLayerName.ElementAt(nIndex));
  997. if ( pTailItem == NULL )
  998. {
  999. break;
  1000. }
  1001. else
  1002. {
  1003. pNextItem = pTailItem->subDirFirstItem;
  1004. }
  1005. }
  1006. if ( (AryLayerName.GetSize() == nIndex) && pTailItem )
  1007. {
  1008. return pTailItem;
  1009. }
  1010. return NULL;
  1011. }
  1012. /************************************************************************/
  1013. /*
  1014. 函数:FindSiblingPath
  1015. 描述:在指定的兄弟链中(以及兄弟链中的子链),从兄弟链头元素开始查找指定目录名的元素指针;
  1016. 参数:
  1017. pSiblingHeadItem[IN]:兄弟链的头元素,作为查找时的开始位置;
  1018. strDiscPath[IN]:要在兄弟链中(以及兄弟链中的子链)查找的目录名(只是单层目录名)。
  1019. 返回:
  1020. 成功在兄弟链中(以及兄弟链中的子链)查找到该目录名元素,返回该元素对象指针;若未查找到,返回NULL;
  1021. 注意:
  1022. 示例:
  1023. */
  1024. /************************************************************************/
  1025. NERO_ISO_ITEM* CNeroBurn::FindPathInSibling( IN NERO_ISO_ITEM* pSiblingHeadItem, IN CString& strDiscPath )
  1026. {
  1027. if ( pSiblingHeadItem == NULL )
  1028. {
  1029. WriteTextLog(_T("FindPathInSibling兄弟结点空!"));
  1030. return NULL;
  1031. }
  1032. BOOL bFind = FALSE;
  1033. NERO_ISO_ITEM* pNextItem = pSiblingHeadItem;
  1034. do {
  1035. if (pNextItem->isDirectory)
  1036. {
  1037. if ( strDiscPath.CompareNoCase(pNextItem->longFileName) == 0 )
  1038. {
  1039. bFind = TRUE;
  1040. break;
  1041. }
  1042. }
  1043. pNextItem = pNextItem->nextItem;
  1044. } while ( pNextItem );
  1045. return bFind ? pNextItem : NULL;
  1046. }
  1047. /************************************************************************/
  1048. /*
  1049. 函数:FindSiblingNextToLast
  1050. 描述:返回兄弟链中的倒数第二个元素或者最后一个;
  1051. 参数:
  1052. pSiblingHeadItem[IN] 兄弟链的头元素;
  1053. 返回:
  1054. 返回兄弟链中的倒数第二个元素或者最后一个;
  1055. 注意:当兄弟链的只有一个元素时,返回的是本身,也是最后一个;
  1056. 示例:
  1057. */
  1058. /************************************************************************/
  1059. NERO_ISO_ITEM* CNeroBurn::FindSiblingNextToLast( IN NERO_ISO_ITEM* pSiblingHeadItem )
  1060. {
  1061. if ( pSiblingHeadItem == NULL || pSiblingHeadItem->nextItem == NULL )
  1062. {
  1063. return pSiblingHeadItem;
  1064. }
  1065. NERO_ISO_ITEM* pSiblingTail = pSiblingHeadItem;
  1066. while ( pSiblingTail->nextItem->nextItem )
  1067. {
  1068. pSiblingTail = pSiblingTail->nextItem;
  1069. }
  1070. return pSiblingTail;
  1071. }
  1072. /************************************************************************/
  1073. /*
  1074. 函数:RemoveRootItem
  1075. 描述:删除整个光盘项;
  1076. 参数:
  1077. 返回:
  1078. 注意:
  1079. 示例:
  1080. */
  1081. /************************************************************************/
  1082. void CNeroBurn::RemoveRootItem()
  1083. {
  1084. RemoveAllItem(m_pRootItem);
  1085. if (m_pRootItem)
  1086. {
  1087. if(m_pRootItem->longFileName != NULL)
  1088. free((void*)m_pRootItem->longFileName), m_pRootItem->longFileName = NULL;
  1089. if(m_pRootItem->longSourceFilePath != NULL)
  1090. free((void*)m_pRootItem->longSourceFilePath), m_pRootItem->longSourceFilePath = NULL;
  1091. delete m_pRootItem;
  1092. m_pRootItem = NULL;
  1093. }
  1094. }
  1095. /************************************************************************/
  1096. /*
  1097. 函数:RemoveAllItem
  1098. 描述:删除指定根结点的全部元素;
  1099. 参数:
  1100. 返回:
  1101. 注意:
  1102. 示例:
  1103. */
  1104. /************************************************************************/
  1105. void CNeroBurn::RemoveAllItem(IN NERO_ISO_ITEM* pRootItem)
  1106. {
  1107. #if 1
  1108. for( vector<NERO_ISO_ITEM*>::iterator it = m_vtItems.begin(); it != m_vtItems.end();)
  1109. {
  1110. NERO_ISO_ITEM *pItem = *it;
  1111. it = m_vtItems.erase(it);
  1112. if(pItem->longFileName != NULL)
  1113. free((void*)pItem->longFileName), pItem->longFileName = NULL;
  1114. if(pItem->longSourceFilePath != NULL)
  1115. free((void*)pItem->longSourceFilePath), pItem->longSourceFilePath = NULL;
  1116. delete pItem;
  1117. pItem = NULL;
  1118. }
  1119. return;
  1120. #else
  1121. if( pRootItem == NULL ){
  1122. WriteTextLog(_T("RemoveChildItem:删除出错!"));
  1123. OutputDebugString(_T("\nRemoveChildItem:删除出错,!\n"));
  1124. return;
  1125. }
  1126. if ( pRootItem->subDirFirstItem == NULL && pRootItem->nextItem == NULL ){// 最后一个元素;
  1127. //OutputDebugString(_T("\nRemoveAllItem:目录元素\n"));
  1128. return;
  1129. }
  1130. NERO_ISO_ITEM* pNext2Last = NULL;
  1131. do {
  1132. // 查找到兄弟链中的倒第二个(或者最后一个);
  1133. pNext2Last = FindSiblingNextToLast(pRootItem->subDirFirstItem);
  1134. NERO_ISO_ITEM* pTailItem = pNext2Last->nextItem;
  1135. if ( pTailItem )
  1136. {// 倒数第二个;
  1137. if (pTailItem->isDirectory)
  1138. {
  1139. RemoveAllItem(pTailItem);
  1140. }
  1141. pNext2Last->nextItem = NULL;
  1142. if(!pTailItem->isReference)
  1143. {
  1144. if(pTailItem->longFileName != NULL)
  1145. free((void*)pTailItem->longFileName), pTailItem->longFileName = NULL;
  1146. if(pTailItem->longSourceFilePath != NULL)
  1147. free((void*)pTailItem->longSourceFilePath), pTailItem->longSourceFilePath = NULL;
  1148. }
  1149. delete pTailItem;
  1150. pTailItem = NULL;
  1151. }
  1152. else
  1153. {// 第一个(也是最后一个);
  1154. if ( pNext2Last->isDirectory )
  1155. {
  1156. RemoveAllItem(pNext2Last);
  1157. }
  1158. if(!pNext2Last->isReference)
  1159. {
  1160. if(pNext2Last->longFileName != NULL)
  1161. free((void*)pNext2Last->longFileName), pNext2Last->longFileName = NULL;
  1162. if(pNext2Last->longSourceFilePath != NULL)
  1163. free((void*)pNext2Last->longSourceFilePath), pNext2Last->longSourceFilePath = NULL;
  1164. }
  1165. delete pNext2Last;
  1166. pNext2Last = NULL;
  1167. pRootItem->subDirFirstItem = NULL;
  1168. }
  1169. }while( pRootItem->subDirFirstItem );
  1170. #endif
  1171. }
  1172. void CNeroBurn::DiscBurn()
  1173. {
  1174. // 使用第一个设备来刻录;;
  1175. NERO_SCSI_DEVICE_INFO* nsdiDevice = &m_pndiDeviceInfos->nsdisDevInfos[0];
  1176. // 打开设备;
  1177. m_ndhDeviceHandle = NeroOpenDevice(nsdiDevice);
  1178. if (!m_ndhDeviceHandle)
  1179. {
  1180. AfxMessageBox(_T("刻录设备不能打开, 请与系统管理员联系!"), MB_ICONSTOP);
  1181. NeroWorkError = true;
  1182. return;
  1183. }
  1184. // 读取CD或DVD媒体信息;
  1185. NERO_CD_INFO* pNeroCDInfo = NeroGetCDInfo(m_ndhDeviceHandle, NGCDI_READ_CD_TEXT | NGCDI_READ_ISRC);
  1186. if ( pNeroCDInfo == NULL )
  1187. {
  1188. AfxMessageBox(_T("获取光盘失败, 请与系统管理员联系!"), MB_ICONSTOP);
  1189. NeroWorkError = true;
  1190. return;
  1191. }
  1192. // 光盘不可写;
  1193. if ( !pNeroCDInfo->ncdiIsWriteable )
  1194. {
  1195. AfxMessageBox(_T("光盘不可写, 请更换新的光盘!"), MB_ICONSTOP);
  1196. NeroWorkError = true;
  1197. return;
  1198. }
  1199. #if 0
  1200. // 光盘文件系统格式(但是,好像没有用, 估计是SDK版本太老);
  1201. // pNeroCDInfo->ncdiTrackInfos[0].ntiFSType; // NTFST_UDF DVD格式刻录; NTFST_CDRFS CD格式刻录;
  1202. if ( m_bDvd && pNeroCDInfo->ncdiTrackInfos[0].ntiFSType == NTFST_CDRFS )
  1203. {
  1204. AfxMessageBox(_T("所选DVD格式刻录,但光盘文件系统是CD格式,请更换DVD文件系统(UDF或新)的光盘!"), MB_ICONSTOP);
  1205. NeroWorkError = true;
  1206. return;
  1207. }
  1208. if ( !m_bDvd && pNeroCDInfo->ncdiTrackInfos[0].ntiFSType == NTFST_UDF )
  1209. {
  1210. AfxMessageBox(_T("所选DVD格式刻录,但光盘文件系统是CD格式,请更换DVD文件系统(UDF或新)的光盘!"), MB_ICONSTOP);
  1211. NeroWorkError = true;
  1212. return;
  1213. }
  1214. #endif
  1215. // 设置写CD参数 ;
  1216. NERO_WRITE_CD writeCD;
  1217. memset(&writeCD,0,sizeof(writeCD));
  1218. writeCD.nwcdpCDStamp = NULL;
  1219. writeCD.nwcdArtist = NULL;
  1220. writeCD.nwcdTitle = NULL;
  1221. writeCD.nwcdCDExtra = FALSE;
  1222. writeCD.nwcdNumTracks = 0;
  1223. // writeCD.nwcdMediaType = m_bDvd ? MEDIA_DVD_ANY : MEDIA_CD; // 这里不是按光盘的媒体类型来赋值;
  1224. writeCD.nwcdMediaType = pNeroCDInfo->ncdiMediaType;
  1225. CString title = g_title+ _T("(") + m_strCustomerInfo;
  1226. title += _T(")客照");
  1227. if ( true )
  1228. {// 追加方式刻录;
  1229. NERO_IMPORT_DATA_TRACK_INFO nidtInfo;
  1230. NERO_IMPORT_DATA_TRACK_RESULT nidtResult;
  1231. // Prepare the struct.
  1232. CString csUserMsg = "";
  1233. memset(&nidtInfo, 0, sizeof(nidtInfo));
  1234. nidtInfo.nidtiSize = sizeof(nidtInfo);
  1235. void* pCDStamp = NULL;
  1236. NERO_ISO_ITEM* pniiItem = NULL;
  1237. pniiItem = NeroImportDataTrack(m_ndhDeviceHandle, pNeroCDInfo->ncdiNumTracks - 1, &pCDStamp, &nidtInfo, 0, &nidtResult, NULL);
  1238. // If there is a volume name after import, print it out.
  1239. if(nidtInfo.nidtipVolumeName != NULL)
  1240. {
  1241. csUserMsg.Format("Imported volume name: %s", nidtInfo.nidtipVolumeName);
  1242. //AppendString(csUserMsg);
  1243. NeroFreeMem (nidtInfo.nidtipVolumeName);
  1244. }
  1245. // If there was an error during import, let the user know about it.
  1246. if((nidtResult != NIDTR_NO_ERROR) || (pniiItem == NULL))
  1247. {
  1248. static LPCSTR errors[] = {"an unknown error","a generic error","a drive error","a read error","a filesystem error","an invalid track number"};
  1249. if (nidtResult > NIDTR_INVALID_TRACKNUMBER)
  1250. nidtResult = NIDTR_NO_ERROR;
  1251. csUserMsg.Format("There was %s while importing the track!", errors[nidtResult]);
  1252. //AppendString(csUserMsg);
  1253. }
  1254. else if(m_pRootItem->subDirFirstItem != NULL)
  1255. {
  1256. if(MergeIsoTracks(&m_pRootItem->subDirFirstItem, pniiItem)) // Merge the new track with the existing one.
  1257. writeCD.nwcdpCDStamp = pCDStamp;
  1258. else
  1259. {
  1260. //AppendString("There was an error while merging tracks!");
  1261. if(pCDStamp != NULL)
  1262. NeroFreeCDStamp(pCDStamp), pCDStamp = NULL;
  1263. }
  1264. }
  1265. }
  1266. writeCD.nwcdIsoTrack = NeroCreateIsoTrackEx(m_pRootItem->subDirFirstItem,title,NCITEF_USE_JOLIET|NCITEF_CREATE_ISO_FS);
  1267. // 以追回的方式刻录 : 使用MEDIA_DVD_ANY 或 MEDIA_CD时, NERO_CD_FORMAT固定为NERO_ISO_AUDIO_MEDIA;
  1268. int iRes = NeroBurn(m_ndhDeviceHandle, NERO_ISO_AUDIO_MEDIA, &writeCD, NBF_WRITE|NBF_CLOSE_SESSION, 0/*Maximum*/, &npProgress);
  1269. // 释放媒体资源;
  1270. NeroFreeMem(pNeroCDInfo);
  1271. // free memory that was allocated for the track
  1272. if(writeCD.nwcdIsoTrack != NULL)
  1273. NeroFreeIsoTrack(writeCD.nwcdIsoTrack);
  1274. // Free the NERO_WRITE_CD struct too
  1275. if(writeCD.nwcdpCDStamp != NULL)
  1276. NeroFreeCDStamp(writeCD.nwcdpCDStamp), writeCD.nwcdpCDStamp = NULL;
  1277. NeroCloseDevice(m_ndhDeviceHandle);
  1278. char* Log = NeroGetErrorLog();
  1279. switch(iRes)
  1280. {
  1281. case NEROAPI_BURN_OK:
  1282. AfxMessageBox(_T("刻录成功!"), MB_ICONINFORMATION);
  1283. NeroBurnOK=true;
  1284. break;
  1285. case NEROAPI_BURN_UNKNOWN_CD_FORMAT:
  1286. AfxMessageBox(_T("刻录失败:无效刻录盘格式!"), MB_ICONSTOP);
  1287. NeroWorkError=true;
  1288. break;
  1289. case NEROAPI_BURN_INVALID_DRIVE:
  1290. AfxMessageBox(_T("刻录失败:驱动器无效!"), MB_ICONSTOP);
  1291. NeroWorkError=true;
  1292. break;
  1293. case NEROAPI_BURN_FAILED:
  1294. AfxMessageBox(_T("刻录失败!"), MB_ICONSTOP);
  1295. NeroWorkError=true;
  1296. break;
  1297. case NEROAPI_BURN_FUNCTION_NOT_ALLOWED:
  1298. case NEROAPI_BURN_DRIVE_NOT_ALLOWED:
  1299. AfxMessageBox(_T("刻录失败:刻录驱动未安装正确!"), MB_ICONSTOP);
  1300. NeroWorkError=true;
  1301. break;
  1302. default:
  1303. AfxMessageBox(_T("刻录失败:未知错误!"), MB_ICONSTOP);
  1304. NeroWorkError=true;
  1305. break;
  1306. }
  1307. }
  1308. inline LPCSTR GetFilename(const NERO_ISO_ITEM* pItem)
  1309. {
  1310. return (pItem->longFileName != NULL)? pItem->longFileName : pItem->fileName;
  1311. }
  1312. // The following function performs a merge operation between two iso item trees.
  1313. // The second tree is added onto the first one and the extra items are deleted.
  1314. // As we do not allow to add directories in our file list we do not make recursive
  1315. // calls of this method.
  1316. BOOL CNeroBurn::MergeIsoTracks(NERO_ISO_ITEM** ppniiTarget, NERO_ISO_ITEM* pniiToAdd)
  1317. {
  1318. BOOL bResult = ((ppniiTarget != NULL) && (*ppniiTarget != NULL) && (pniiToAdd != NULL));
  1319. // Two loops. Outer loops the first tree, the inner loops the second tree.
  1320. for( ; bResult && (*ppniiTarget != NULL); ppniiTarget = &(*ppniiTarget)->nextItem)
  1321. {
  1322. for(NERO_ISO_ITEM** ppniiToAddLocal = &pniiToAdd; *ppniiToAddLocal != NULL; )
  1323. {
  1324. // Compare entry names...
  1325. if(0 == stricmp(GetFilename(*ppniiTarget), GetFilename(*ppniiToAddLocal)))
  1326. {
  1327. // If there is a file name conflict between iso items that belong to imported sessions
  1328. // always replace the old files in terms of modification times.
  1329. time_t timeTarget = mktime(&(*ppniiTarget)->entryTime);
  1330. if(timeTarget == (time_t)-1)
  1331. {
  1332. HANDLE hFile = NULL; // handle to file
  1333. FILETIME ftCreationTime; // creation time
  1334. FILETIME ftLastAccessTime; // last access time
  1335. FILETIME ftLastWriteTime; // last write time
  1336. hFile = CreateFileA((*ppniiTarget)->longSourceFilePath, // open the file to get handle
  1337. GENERIC_READ, // open for reading
  1338. FILE_SHARE_READ, // share for reading
  1339. NULL, // no security
  1340. OPEN_EXISTING, // existing file only
  1341. FILE_ATTRIBUTE_NORMAL, // normal file
  1342. NULL); // no attr. template
  1343. if(hFile == INVALID_HANDLE_VALUE)
  1344. {
  1345. CString csMsg;
  1346. csMsg.Format("Could not open file: %s.", (*ppniiTarget)->longSourceFilePath);
  1347. //AppendString(csMsg); // show error
  1348. }
  1349. else if(GetFileTime(hFile, &ftCreationTime, &ftLastAccessTime, &ftLastWriteTime))
  1350. timeTarget = CTime(ftLastWriteTime).GetTime();
  1351. if(hFile != INVALID_HANDLE_VALUE)
  1352. CloseHandle(hFile), hFile = NULL;
  1353. }
  1354. time_t timeToAdd = mktime(&(*ppniiToAddLocal)->entryTime);
  1355. // If we have to replace one item, we will now switch places of items in the first and second tree.
  1356. // Since one of the items has to be deleted eventually, this operation will
  1357. // essentially keep the item from the second tree and delete the item from the first tree.
  1358. if(timeTarget < timeToAdd)
  1359. {
  1360. NERO_ISO_ITEM* pniiTmpItem = *ppniiToAddLocal;
  1361. *ppniiToAddLocal = *ppniiTarget;
  1362. *ppniiTarget = pniiTmpItem;
  1363. pniiTmpItem = (*ppniiToAddLocal)->nextItem;
  1364. (*ppniiToAddLocal)->nextItem = (*ppniiTarget)->nextItem;
  1365. (*ppniiTarget)->nextItem = pniiTmpItem;
  1366. }
  1367. // Remove the item from the second tree.
  1368. NERO_ISO_ITEM* pniiTmpItem = *ppniiToAddLocal;
  1369. *ppniiToAddLocal = pniiTmpItem->nextItem;
  1370. pniiTmpItem->nextItem = NULL;
  1371. DeleteIsoItemTree(pniiTmpItem);
  1372. }
  1373. else // No match, advance to the next item.
  1374. ppniiToAddLocal = &(*ppniiToAddLocal)->nextItem;
  1375. }
  1376. }
  1377. // Attach whatever is left of the new tree to the main tree.
  1378. *ppniiTarget = pniiToAdd;
  1379. // Returning true means, everything is fine, continue.
  1380. return bResult;
  1381. }
  1382. // This function deletes the iso tree recursively.
  1383. void CNeroBurn::DeleteIsoItemTree(NERO_ISO_ITEM* pniiItem)
  1384. {
  1385. // First free our own long filename strings, then free the whole tree.
  1386. FreeOurOwnResources(pniiItem);
  1387. NeroFreeIsoItemTree(pniiItem);
  1388. }
  1389. void CNeroBurn::FreeOurOwnResources(NERO_ISO_ITEM* pniiItem)
  1390. {
  1391. // Step through the tree until the ISO item tree pointer becomes NULL
  1392. while(pniiItem != NULL)
  1393. {
  1394. NERO_ISO_ITEM* pniiNextItem = pniiItem->nextItem;
  1395. // We have encountered another ISO item tree; recurse another level.
  1396. if(pniiItem->isDirectory)
  1397. FreeOurOwnResources (pniiItem->subDirFirstItem);
  1398. if(!pniiItem->isReference)
  1399. {
  1400. if(pniiItem->longFileName != NULL)
  1401. free((void*)pniiItem->longFileName), pniiItem->longFileName = NULL;
  1402. if(pniiItem->longSourceFilePath != NULL)
  1403. free((void*)pniiItem->longSourceFilePath), pniiItem->longSourceFilePath = NULL;
  1404. }
  1405. pniiItem = pniiNextItem;
  1406. }
  1407. }
  1408. /************************************************************************/
  1409. /* 函数:获取读写速度[3/22/2018 Jeff];
  1410. /* 描述:;
  1411. /* 参数:;
  1412. /* [IN] :;
  1413. /* [OUT] :;
  1414. /* [IN/OUT] :;
  1415. /* 返回:void;
  1416. /* 注意:必须在外部释放NeroFreeMem(pnsiWrite);
  1417. /* 示例:;
  1418. /*
  1419. /* 修改:;
  1420. /* 日期:;
  1421. /* 内容:;
  1422. /************************************************************************/
  1423. NERO_SPEED_INFOS *CNeroBurn::GetAvailableSpeeds(bool IsWriteSpeed /*= true*/)
  1424. {
  1425. // 获取媒体信息;
  1426. NERO_CD_INFO* pNeroCDInfo = NeroGetCDInfo(m_ndhDeviceHandle, NGCDI_READ_CD_TEXT | NGCDI_READ_ISRC);
  1427. if ( pNeroCDInfo == NULL )
  1428. return NULL;
  1429. NERO_SPEED_INFOS *pnsiWrite = NeroGetAvailableSpeeds(m_ndhDeviceHandle,IsWriteSpeed ? ACCESSTYPE_WRITE :ACCESSTYPE_READ, pNeroCDInfo->ncdiMediaType,NULL);
  1430. // 释放媒体资源;
  1431. NeroFreeMem(pNeroCDInfo);
  1432. return pnsiWrite;
  1433. }
  1434. #endif