CDBurn.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689
  1. // CDBurn.cpp : Defines the class behaviors for the application.
  2. //
  3. #include "stdafx.h"
  4. #include "CDBurn.h"
  5. #ifdef _DEBUG
  6. #define new DEBUG_NEW
  7. #undef THIS_FILE
  8. static char THIS_FILE[] = __FILE__;
  9. #endif
  10. #include "DirObject.h"
  11. #include <direct.h>
  12. // #include <error.h>
  13. /////////////////////////////////////////////////////////////////////////////
  14. // CCDBurnApp
  15. /////////////////////////////////////////////////////////////////////////////
  16. // CCDBurnApp construction
  17. CCDBurnApp::CCDBurnApp()
  18. {
  19. // TODO: add construction code here,
  20. // Place all significant initialization in InitInstance
  21. m_pCurDiscRecorder = NULL;
  22. m_cstrFilePath = _T("E:\\lyfzbin\\Services\\数据备份");
  23. }
  24. CCDBurnApp::~CCDBurnApp()
  25. {
  26. ::CoUninitialize();
  27. }
  28. /////////////////////////////////////////////////////////////////////////////
  29. // The one and only CCDBurnApp object
  30. CCDBurnApp theApp;
  31. #ifndef EEXIST
  32. #define EEXIST 17
  33. #endif
  34. /////////////////////////////////////////////////////////////////////////////
  35. // CCDBurnApp initialization
  36. BOOL CCDBurnApp::InitInstance()
  37. {
  38. HANDLE g_hMutex = NULL; //互斥量 句柄
  39. BOOL bRecFile = FALSE; //刻录文件是否成功
  40. BOOL bNeedToOpenProcess = TRUE;//是否开启子进程
  41. m_bPopupDrivers = TRUE;
  42. ::CoInitializeEx(NULL,COINIT_MULTITHREADED);
  43. m_bLogFile = TRUE;
  44. CString cstrLogFile;
  45. CString strPath;
  46. CTime cTime = CTime::GetCurrentTime();
  47. strPath.Format("C:\\RecDataLog");
  48. if(mkdir(strPath) != 0)
  49. {
  50. DWORD dwErrId = GetLastError();
  51. if(dwErrId != 17 && dwErrId != 183)
  52. {
  53. return FALSE;
  54. }
  55. }
  56. cstrLogFile.Format("%s\\%s.txt",(LPCTSTR)strPath,cTime.Format("%Y%m%d%H%M%S"));
  57. if(!m_cLogFile.Open((LPCTSTR)cstrLogFile
  58. ,CFile::modeCreate|CFile::modeNoTruncate|CFile::modeWrite|CFile::shareDenyNone))
  59. {
  60. m_bLogFile = FALSE;
  61. }
  62. if(InitRecorder())
  63. {
  64. // ReadDisc();
  65. }
  66. else
  67. {
  68. ::AfxMessageBox(_T("没有找到可用光驱"));
  69. PostQuitMessage(0);
  70. }
  71. RecorderFile(m_cstrFilePath,m_cstrCurDriver);
  72. return FALSE;
  73. }
  74. BOOL CCDBurnApp::ReadDisc()
  75. {
  76. CDiscFormatData discFormatData;
  77. if(discFormatData.Initialize(m_pCurDiscRecorder,_T("CDBurn")))
  78. {
  79. }
  80. return true;
  81. }
  82. BOOL CCDBurnApp::InitRecorder()
  83. {
  84. int i ;
  85. CDiscMaster m_discMaster;
  86. CDiscRecorder *pDiscRecorder = NULL;
  87. if(!m_discMaster.Initialize()) // 加载失败,推出程序
  88. {
  89. if(m_bLogFile)
  90. {
  91. m_cLogFile.Write(m_discMaster.GetErrorMessage(),m_discMaster.GetErrorMessage().GetLength());
  92. }
  93. return FALSE;
  94. }
  95. long nDeviceCount = m_discMaster.GetTotalDevices();
  96. for(i = 0 ; i < nDeviceCount ; i++)
  97. {
  98. CString cstrDevID = m_discMaster.GetDeviceUniqueID(i);
  99. if(cstrDevID.IsEmpty())
  100. {
  101. // CString strErr;
  102. // strErr.Format(_T("无法获取设备ID"));
  103. // if(m_bLogFile)
  104. // {
  105. // m_cLogFile.Write(strErr,strErr.GetLength());
  106. // }
  107. continue ;
  108. }
  109. pDiscRecorder = new CDiscRecorder;
  110. if(!pDiscRecorder->Initialize(cstrDevID))
  111. {
  112. // CString strErr ;
  113. // strErr.Format(_T("初始化光驱异常,错误号:0x%x"),pDiscRecorder->GetHresult());
  114. // if(m_bLogFile)
  115. // {
  116. // m_cLogFile.Write(strErr,strErr.GetLength());
  117. // }
  118. delete pDiscRecorder;
  119. continue;
  120. }
  121. CString volumeList;
  122. ULONG totalVolumePaths = pDiscRecorder->GetTotalVolumePaths();
  123. for (ULONG volIndex = 0; volIndex < totalVolumePaths; volIndex++)
  124. {
  125. if (volIndex)
  126. volumeList += _T(",");
  127. volumeList += pDiscRecorder->GetVolumePath(volIndex);
  128. }
  129. CString productId = pDiscRecorder->GetProductID();
  130. CString strName;
  131. strName.Format(_T("%s [%s]"), (LPCTSTR)volumeList, (LPCTSTR)productId);
  132. CDiscFormatData discFormatData ;
  133. if(!discFormatData.Initialize(pDiscRecorder,_T("Burn")))
  134. {
  135. if(m_bLogFile)
  136. {
  137. CString strErr ;
  138. strErr = discFormatData.GetErrorMessage();
  139. m_cLogFile.Write(strErr,strErr.GetLength());
  140. }
  141. delete pDiscRecorder;
  142. continue;
  143. }
  144. if(m_bLogFile)
  145. {
  146. CString strTemp ;
  147. strTemp.Format(_T("找到可用光驱:%s") , strName);
  148. m_cLogFile.Write(strTemp,strTemp.GetLength());
  149. }
  150. pDiscRecorder->m_cstrRecorderName = strName;
  151. m_cstrCurDriver = strName;
  152. m_listDiscRecorder.AddTail(pDiscRecorder);
  153. }
  154. if(m_listDiscRecorder.GetCount() == 0)
  155. {
  156. if(m_bLogFile)
  157. {
  158. CString strErr ;
  159. strErr = _T("没有搜索到光驱");
  160. m_cLogFile.Write(strErr,strErr.GetLength());
  161. }
  162. return FALSE;
  163. }
  164. return TRUE;
  165. }
  166. CString GetMediaStatusErrorCode(long hr)
  167. {
  168. CString m_cstrErr;
  169. switch(hr)
  170. {
  171. case E_INVALIDARG:
  172. m_cstrErr = _T("参数无效");
  173. break;
  174. case E_POINTER:
  175. m_cstrErr = _T("指针无效");
  176. break ;
  177. case E_FAIL:
  178. m_cstrErr = _T("获取状态失败");
  179. break ;
  180. case E_OUTOFMEMORY:
  181. m_cstrErr = _T("内存溢出");
  182. break ;
  183. case E_IMAPI_RECORDER_COMMAND_TIMEOUT:
  184. m_cstrErr = _T("超时");
  185. break ;
  186. case E_IMAPI_RECORDER_INVALID_RESPONSE_FROM_DEVICE:
  187. m_cstrErr = _T("异常或无效数据");
  188. break ;
  189. case E_IMAPI_RECORDER_MEDIA_UPSIDE_DOWN:
  190. m_cstrErr = _T("光盘正反面可能颠倒");
  191. break ;
  192. case E_IMAPI_RECORDER_MEDIA_BECOMING_READY:
  193. m_cstrErr = _T("光驱正在准备,请稍后再继续操作");
  194. break ;
  195. case E_IMAPI_RECORDER_MEDIA_NO_MEDIA:
  196. m_cstrErr = _T("光驱中无光盘或者光驱已弹出");
  197. break ;
  198. case E_IMAPI_RECORDER_MEDIA_FORMAT_IN_PROGRESS:
  199. m_cstrErr = _T("光盘正在格式化");
  200. break;
  201. case E_IMAPI_RECORDER_MEDIA_BUSY:
  202. m_cstrErr = _T("光驱工作时间过长,需要暂停工作");
  203. break ;
  204. case E_IMAPI_LOSS_OF_STREAMING:
  205. m_cstrErr = _T("写操作失败,因为长时间没有提供写入的数据");
  206. break;
  207. case E_IMAPI_RECORDER_MEDIA_INCOMPATIBLE:
  208. m_cstrErr = _T("不兼容或者格式未知");
  209. break ;
  210. case E_IMAPI_RECORDER_DVD_STRUCTURE_NOT_PRESENT:
  211. m_cstrErr = _T("DVD未正常工作,可能是不兼容的媒体格式");
  212. break ;
  213. case E_IMAPI_RECORDER_NO_SUCH_MODE_PAGE:
  214. m_cstrErr = _T("The requested mode page (and type) is not present");
  215. break ;
  216. case E_IMAPI_RECORDER_INVALID_MODE_PARAMETERS:
  217. m_cstrErr = _T("The drive reported that the combination of parameters provided in the mode page for a MODE SELECT command were not supported.");
  218. break ;
  219. case E_IMAPI_RECORDER_MEDIA_WRITE_PROTECTED:
  220. m_cstrErr = _T("光盘已经写保护");
  221. break ;
  222. case E_IMAPI_RECORDER_MEDIA_SPEED_MISMATCH:
  223. m_cstrErr = _T("刻录的速度和光驱的不匹配");
  224. break ;
  225. case ERROR_INVALID_HANDLE:
  226. m_cstrErr = _T("The specified handle is invalid");
  227. break ;
  228. case ERROR_DEV_NOT_EXIST:
  229. m_cstrErr = _T("光驱可能被卸载");
  230. break ;
  231. case E_IMAPI_RECORDER_LOCKED:
  232. m_cstrErr = _T("不能进行并行操作");
  233. break ;
  234. }
  235. CString strTemp;
  236. strTemp.Format(_T("错误号:%x\r\n"),hr);
  237. m_cstrErr += strTemp;
  238. // m_cstrErr.AppendFormat(_T(" 错误号:0x%x"),hr);
  239. return m_cstrErr;
  240. }
  241. CString GetCurrentMediaStatusCode(IMAPI_FORMAT2_DATA_MEDIA_STATE mStates , bool *bWrite)
  242. {
  243. CString strStates;
  244. *bWrite = TRUE;
  245. if(mStates == IMAPI_FORMAT2_DATA_MEDIA_STATE_UNKNOWN)
  246. {
  247. strStates = _T("未知的媒体状态");
  248. *bWrite = false;
  249. }
  250. //if((mStates & IMAPI_FORMAT2_DATA_MEDIA_STATE_INFORMATIONAL_MASK) == IMAPI_FORMAT2_DATA_MEDIA_STATE_INFORMATIONAL_MASK)
  251. //{
  252. // strStates += _T(" 正在读取光盘状态,可能还需要再次调用接口以正确获取状态");
  253. //}
  254. if(((mStates & IMAPI_FORMAT2_DATA_MEDIA_STATE_UNSUPPORTED_MASK) == IMAPI_FORMAT2_DATA_MEDIA_STATE_UNSUPPORTED_MASK) || ((mStates & IMAPI_FORMAT2_DATA_MEDIA_STATE_UNSUPPORTED_MEDIA) == IMAPI_FORMAT2_DATA_MEDIA_STATE_UNSUPPORTED_MEDIA))
  255. {
  256. strStates += _T(" 不支持的媒体状态");
  257. *bWrite = false;
  258. }
  259. if((mStates & IMAPI_FORMAT2_DATA_MEDIA_STATE_OVERWRITE_ONLY) == IMAPI_FORMAT2_DATA_MEDIA_STATE_OVERWRITE_ONLY)
  260. {
  261. strStates += _T(" 写操作可以在光盘已写过的地方,即可以覆盖写");
  262. }
  263. if((mStates & IMAPI_FORMAT2_DATA_MEDIA_STATE_BLANK) == IMAPI_FORMAT2_DATA_MEDIA_STATE_BLANK)
  264. {
  265. strStates += _T(" 光盘是空的或者已经被擦出过");
  266. }
  267. if((mStates & IMAPI_FORMAT2_DATA_MEDIA_STATE_APPENDABLE) == IMAPI_FORMAT2_DATA_MEDIA_STATE_APPENDABLE)
  268. {
  269. strStates += _T(" 光盘可追加写入");
  270. }
  271. if((mStates & IMAPI_FORMAT2_DATA_MEDIA_STATE_FINAL_SESSION) == IMAPI_FORMAT2_DATA_MEDIA_STATE_FINAL_SESSION)
  272. {
  273. strStates += _T(" 光盘可以被刻录一次,以后就不可以往光盘上增加刻录其他数据");
  274. }
  275. if((mStates & IMAPI_FORMAT2_DATA_MEDIA_STATE_DAMAGED) == IMAPI_FORMAT2_DATA_MEDIA_STATE_DAMAGED)
  276. {
  277. strStates += _T(" 接口不可使用此光盘,光盘可能需要其他的工具覆写或者擦出");
  278. *bWrite = false;
  279. }
  280. if((mStates & IMAPI_FORMAT2_DATA_MEDIA_STATE_ERASE_REQUIRED) == IMAPI_FORMAT2_DATA_MEDIA_STATE_ERASE_REQUIRED)
  281. {
  282. strStates += _T(" 光盘需要先擦出再使用,此接口可擦出光盘");
  283. *bWrite = false;
  284. }
  285. if((mStates & IMAPI_FORMAT2_DATA_MEDIA_STATE_NON_EMPTY_SESSION) == IMAPI_FORMAT2_DATA_MEDIA_STATE_NON_EMPTY_SESSION)
  286. {
  287. strStates += _T(" 光盘已经被写过了,不可以再次写入");
  288. *bWrite = false;
  289. }
  290. if((mStates & IMAPI_FORMAT2_DATA_MEDIA_STATE_WRITE_PROTECTED) == IMAPI_FORMAT2_DATA_MEDIA_STATE_WRITE_PROTECTED)
  291. {
  292. strStates += _T(" 光盘或者光驱已经写保护");
  293. *bWrite = false;
  294. }
  295. if((mStates & IMAPI_FORMAT2_DATA_MEDIA_STATE_FINALIZED) == IMAPI_FORMAT2_DATA_MEDIA_STATE_FINALIZED)
  296. {
  297. strStates += _T(" 光盘无法写入(定稿)");
  298. *bWrite = false;
  299. }
  300. strStates += "\r\n";
  301. return strStates;
  302. }
  303. BOOL CCDBurnApp::RecorderFile(CString FileName, CString CurRecorderName)
  304. {
  305. IStream *pFileStream = NULL;
  306. CDiscRecorder *pDiscRecorder = NULL ;
  307. // 遍历选择指定的光盘;
  308. POSITION pos = m_listDiscRecorder.GetHeadPosition();
  309. while(pos)
  310. {
  311. pDiscRecorder = m_listDiscRecorder.GetNext(pos);
  312. if(pDiscRecorder->m_cstrRecorderName == CurRecorderName)
  313. break;
  314. pDiscRecorder = NULL;
  315. }
  316. if(pDiscRecorder == NULL)
  317. {
  318. if(m_bLogFile )
  319. {
  320. CString strErr = _T("程序出现异常,未找到光驱");
  321. m_cLogFile.Write(strErr,strErr.GetLength());
  322. }
  323. return false;
  324. }
  325. // 加载光盘的数据;
  326. CDiscFormatData discFormatData;
  327. if(!discFormatData.Initialize(pDiscRecorder,_T("CDBurn")))
  328. {
  329. if(m_bLogFile)
  330. {
  331. m_cLogFile.Write(discFormatData.GetErrorMessage(),discFormatData.GetErrorMessage().GetLength());
  332. }
  333. return false;
  334. }
  335. bool bWrite;
  336. CString strErr;
  337. CString strStates;
  338. HRESULT hr;
  339. // 光盘的状态;
  340. IMAPI_FORMAT2_DATA_MEDIA_STATE iState = IMAPI_FORMAT2_DATA_MEDIA_STATE_UNKNOWN;
  341. // SAFEARRAY *pSafeArrayModePages = NULL;
  342. // pDiscRecorder->GetInterface()->get_SupportedModePages(&pSafeArrayModePages); // 没有读到任何属性
  343. // 循环获取光盘状态,直到光盘可用为止;
  344. while(TRUE)
  345. {
  346. hr = discFormatData.GetInterface()->get_CurrentMediaStatus( &iState); //
  347. if(!SUCCEEDED(hr))
  348. {
  349. strErr = GetMediaStatusErrorCode(hr);
  350. if(m_bLogFile)
  351. {
  352. m_cLogFile.Write(strErr,strErr.GetLength());
  353. }
  354. if(hr == E_IMAPI_RECORDER_MEDIA_UPSIDE_DOWN || hr == E_IMAPI_RECORDER_MEDIA_BECOMING_READY ||
  355. hr == E_IMAPI_RECORDER_MEDIA_NO_MEDIA || hr == E_IMAPI_RECORDER_MEDIA_FORMAT_IN_PROGRESS)
  356. {
  357. Sleep(10000);
  358. continue; // 此处的异常,可以通过等待以实现以后的继续刻录
  359. }
  360. return false;
  361. //ASSERT(false);
  362. }
  363. else
  364. {
  365. if(iState == IMAPI_FORMAT2_DATA_MEDIA_STATE_UNKNOWN || iState == IMAPI_FORMAT2_DATA_MEDIA_STATE_UNSUPPORTED_MASK ||
  366. iState == IMAPI_FORMAT2_DATA_MEDIA_STATE_UNSUPPORTED_MEDIA || iState == IMAPI_FORMAT2_DATA_MEDIA_STATE_DAMAGED ||
  367. iState == IMAPI_FORMAT2_DATA_MEDIA_STATE_ERASE_REQUIRED || iState == IMAPI_FORMAT2_DATA_MEDIA_STATE_WRITE_PROTECTED ||
  368. iState == IMAPI_FORMAT2_DATA_MEDIA_STATE_FINALIZED || iState == IMAPI_FORMAT2_DATA_MEDIA_STATE_NON_EMPTY_SESSION)
  369. {
  370. strStates = GetCurrentMediaStatusCode(iState,&bWrite);
  371. if(m_bLogFile)
  372. {
  373. m_cLogFile.Write(strStates,strStates.GetLength());
  374. }
  375. return false;
  376. }
  377. if((iState & IMAPI_FORMAT2_DATA_MEDIA_STATE_OVERWRITE_ONLY) == IMAPI_FORMAT2_DATA_MEDIA_STATE_OVERWRITE_ONLY)
  378. {
  379. strStates = _T("光盘已经刻录过\r\n");
  380. if(m_bLogFile)
  381. {
  382. m_cLogFile.Write(strStates,strStates.GetLength());
  383. }
  384. return false;
  385. }
  386. break;
  387. }
  388. }
  389. // 获取光盘支持的媒体格式;
  390. IMAPI_MEDIA_PHYSICAL_TYPE mediaType = IMAPI_MEDIA_TYPE_UNKNOWN;
  391. discFormatData.GetInterface()->get_CurrentPhysicalMediaType(&mediaType); // 光盘的格式
  392. IFileSystemImage* image = NULL;
  393. IFileSystemImageResult* imageResult = NULL;
  394. IFsiDirectoryItem* rootItem = NULL;
  395. CString message;
  396. bool returnVal = false;
  397. // 初始化文件系统;
  398. hr = CoCreateInstance(CLSID_MsftFileSystemImage, NULL, CLSCTX_ALL, __uuidof(IFileSystemImage), (void**)&image);
  399. if (FAILED(hr) || (image == NULL))
  400. {
  401. CString strErr;
  402. strErr = _T("刻录文件创建流时失败");
  403. if(m_bLogFile)
  404. {
  405. m_cLogFile.Write(strErr,strErr.GetLength());
  406. }
  407. return false;
  408. }
  409. // 创建文件系统映像文件;
  410. hr = image->put_FileSystemsToCreate((FsiFileSystems)(FsiFileSystemJoliet|FsiFileSystemISO9660));
  411. if(!SUCCEEDED(hr))
  412. {
  413. CString strErr ;
  414. strErr.Format(_T("Create file system failed! error code : 0x%d"),hr);
  415. if(m_bLogFile)
  416. {
  417. m_cLogFile.Write(strErr,strErr.GetLength());
  418. }
  419. return false;
  420. }
  421. CDirObject fileObj(FileName);
  422. CString strFileName = fileObj.GetName();
  423. // *(char*)strrchr(strFileName.GetBuffer(0),'\.') = '\0';
  424. // image->put_VolumeName(strFileName.AllocSysString()); // 镜像文件名称
  425. // image->ChooseImageDefaultsForMediaType(mediaType);
  426. SAFEARRAY* pSafeArrayMulSession = NULL;
  427. VARIANT_BOOL vbBlank;
  428. IMultisession *pMultisession = NULL;
  429. // 判断光盘是否为空白盘 vbBlank = VARIANT_TRUE则光盘为空白光盘;
  430. discFormatData.GetInterface()->get_MediaHeuristicallyBlank(&vbBlank);
  431. // 创建文件系统文件;
  432. hr = image->put_FileSystemsToCreate((FsiFileSystems)(FsiFileSystemJoliet|FsiFileSystemISO9660));
  433. if(!SUCCEEDED(hr))
  434. {
  435. return FALSE;
  436. }
  437. // 根据光盘的媒体类型来设置文件系统的类型和大小;
  438. image->ChooseImageDefaultsForMediaType(mediaType);
  439. if(vbBlank == VARIANT_TRUE)
  440. {// 空白的光盘;
  441. // image->put_FileSystemsToCreate((FsiFileSystems)(FsiFileSystemJoliet|FsiFileSystemISO9660));
  442. // image->put_VolumeName(pThis->m_volumeLabel.AllocSysString());
  443. BSTR bstrFileName = strFileName.AllocSysString();
  444. // 设置文件系统映像的卷名称;
  445. image->put_VolumeName(bstrFileName);
  446. SysFreeString(bstrFileName);
  447. }
  448. else
  449. {// 不是空白的光盘, 要在上面继刻;
  450. // 存储光盘多会话;
  451. SAFEARRAY *pSafeArrayMulSection = NULL;
  452. // 检索光盘的多会话界面;
  453. HRESULT hrTemp = discFormatData.GetInterface()->get_MultisessionInterfaces(&pSafeArrayMulSection);
  454. if(!SUCCEEDED(hrTemp))
  455. {
  456. return FALSE;
  457. }
  458. long vale = 0;
  459. // 检索下一个可写入操作的位置;
  460. hrTemp = discFormatData.GetInterface()->get_NextWritableAddress(&vale);
  461. if(SUCCEEDED(hrTemp))
  462. {
  463. // 将光盘最后一个会话导入到文件系统中;
  464. hrTemp = image->put_MultisessionInterfaces(pSafeArrayMulSection);
  465. if(!SUCCEEDED(hrTemp))
  466. {
  467. return FALSE;
  468. }
  469. // 设置光盘之前的数据为已使用(这步是否必须?观VB代码,好像没有这步, 说ImportFileSystem会自动导入光盘的数据);
  470. VARIANT *va = NULL ;
  471. SafeArrayAccessData(pSafeArrayMulSection,(VOID**)&va);
  472. if(va)
  473. {
  474. IMultisession *pMultisession = NULL ;
  475. pMultisession = (IMultisession*)va[0].pdispVal;
  476. hr = pMultisession->put_InUse(VARIANT_TRUE);
  477. if(!SUCCEEDED(hr))
  478. {
  479. return FALSE;
  480. }
  481. }
  482. // FsiFileSystems fs;
  483. // hrTemp = image->GetDefaultFileSystemForImport((FsiFileSystems)(FsiFileSystemJoliet|FsiFileSystemISO9660),&fs);
  484. FsiFileSystems filesystem ;
  485. //encounter IMAPI_E_IMPORT_SEEK_FAILURE or IMAPI_E_NO_SUPPORTED_FILE_SYSTEM
  486. // 导入;
  487. hrTemp = image->ImportFileSystem(&filesystem);
  488. if(!SUCCEEDED(hrTemp))
  489. {
  490. SafeArrayDestroy(pSafeArrayMulSection);
  491. return FALSE;
  492. }
  493. }// get_multisession OK
  494. SafeArrayDestroy(pSafeArrayMulSection);
  495. }
  496. #if 1 // 判断光盘是否有足够的空间来刻录;
  497. LONG lFreeSectorOnMedia = 0;
  498. if(SUCCEEDED(hr))
  499. {
  500. hr = discFormatData.GetInterface()->get_FreeSectorsOnMedia(&lFreeSectorOnMedia);
  501. if(SUCCEEDED(hr))
  502. {
  503. hr = image->put_FreeMediaBlocks(lFreeSectorOnMedia);
  504. }
  505. }
  506. // 光盘的每个扇区大小 = 2048 字节;
  507. // image->get_FreeMediaBlocks(&m_nFreeBlock); // 获取光盘的容积
  508. m_ullFree = (ULONGLONG)lFreeSectorOnMedia * 2048 ; // 转换成字节数
  509. ULONGLONG ullFileSize = fileObj.GetSizeOnDisc();
  510. if(ullFileSize > m_ullFree - 1024000) // 文件大小必须要小于光盘近 1M 大小
  511. {
  512. CString strErr;
  513. strErr = _T("文件太大,刻录可能导致光盘损坏,以后无法读取数据");
  514. if(m_bLogFile)
  515. {
  516. m_cLogFile.Write(strErr,strErr.GetLength());
  517. }
  518. return false;
  519. }
  520. #endif
  521. // 到此 光盘有足够空间可以容纳指定的文件
  522. hr = image->get_Root(&rootItem);
  523. if(SUCCEEDED(hr))
  524. {
  525. // IStream* fileStream = fileObj.GetStream();
  526. CString strFilePath = FileName;
  527. hr = rootItem->AddTree(strFilePath.AllocSysString(),VARIANT_TRUE);
  528. if(!SUCCEEDED(hr))
  529. {
  530. // IMAPI_E_IMAGE_SIZE_LIMIT 0xc0aab120
  531. CString strErr;
  532. strErr = _T("Create file to stream failed!");
  533. if(m_bLogFile)
  534. {
  535. m_cLogFile.Write(strErr,strErr.GetLength());
  536. }
  537. return false;
  538. }
  539. hr = image->CreateResultImage(&imageResult);
  540. if(SUCCEEDED(hr))
  541. {
  542. hr = imageResult->get_ImageStream(&pFileStream);
  543. if(!SUCCEEDED(hr))
  544. {
  545. CString strErr;
  546. strErr.Format(_T("Create image stream failed! Error code:0x%d"),hr);
  547. if(m_bLogFile)
  548. {
  549. m_cLogFile.Write(strErr,strErr.GetLength());
  550. }
  551. return false;
  552. }
  553. }
  554. else
  555. {
  556. CString strErr;
  557. strErr.Format(_T("Create image stream failed! Error code:0x%d"),hr);
  558. if(m_bLogFile)
  559. {
  560. m_cLogFile.Write(strErr,strErr.GetLength());
  561. }
  562. return false;
  563. }
  564. }
  565. else
  566. {
  567. if(hr == 0x8007000E)
  568. {
  569. CString strErr = _T("Failed IFileSystemImage->getRoot.Failed to allocate the required memory. ");
  570. }
  571. else if( hr == E_POINTER)
  572. {
  573. CString strErr = _T("Failed IFileSystemImage->getRoot.Pointer is not valid. ");
  574. }
  575. if(m_bLogFile)
  576. {
  577. m_cLogFile.Write(strErr,strErr.GetLength());
  578. }
  579. return false;
  580. }
  581. if(image != NULL)
  582. {
  583. image->Release();
  584. }
  585. if (imageResult != NULL)
  586. {
  587. imageResult->Release();
  588. }
  589. if (rootItem != NULL)
  590. {
  591. rootItem->Release();
  592. }
  593. discFormatData.SetCloseMedia(TRUE);
  594. if(m_bLogFile)
  595. {
  596. CString strLog;
  597. strLog = _T("开始刻录数据 \n");
  598. m_cLogFile.Write(strLog,strLog.GetLength());
  599. }
  600. if(discFormatData.Burn(NULL,pFileStream))
  601. {
  602. if(m_bLogFile)
  603. {
  604. CString strTemp;
  605. strTemp = _T("刻录完成");
  606. m_cLogFile.Write(strTemp,strTemp.GetLength());
  607. }
  608. }
  609. else if(m_bLogFile)
  610. {
  611. m_cLogFile.Write(discFormatData.GetErrorMessage(),discFormatData.GetErrorMessage().GetLength());
  612. AfxMessageBox(_T("刻录失败"));
  613. }
  614. pFileStream->Release();
  615. if(m_bPopupDrivers)
  616. {
  617. pDiscRecorder->EjectMedia();
  618. }
  619. return TRUE;
  620. }