TNB Library
TnbImageMastering.h
[詳解]
1#pragma once
13#ifndef __ATLCOM_H__
14 #error TnbImageMastering.h is necessary fot OLE Object.
15#endif
16
17
18
19#include "TnbPointerHandle.h"
20#include "TnbStaticMap.h"
21#include "TnbStrVector.h"
22#include "TnbTickCount.h"
23#include "TnbDynamicFunc.h"
24
25#ifndef _TnbDOXYGEN //Document作成用シンボル
26
27#ifndef __imapi2_h__
28
29#ifndef IID_PPV_ARGS
30 template<typename T> void** IID_PPV_ARGS_Helper(T** pp)
31 { // make sure everyone derives from IUnknown
32 static_cast<IUnknown*>(*pp);
33 return reinterpret_cast<void**>(pp);
34 }
35 #define IID_PPV_ARGS(ppType) __uuidof(**(ppType)), IID_PPV_ARGS_Helper(ppType)
36#endif
37
38#ifndef __RPC__in
39 #define __RPC__in
40 #define __RPC__in_opt
41 #define __RPC__in_ecount_full(X)
42 #define __RPC__out
43 #define __RPC__out_ecount_full(X)
44 #define __RPC__out_ecount_part(X, Y)
45 #define __RPC__deref_out_opt
46 #define __RPC__deref_out_ecount_full_opt(X)
47#endif
48
49#include "sdk/imapi2.h"
50#include "sdk/imapi2error.h"
51#include "sdk/imapi2fs.h"
52#include "sdk/imapi2fserror.h"
53
54#endif //__imapi2_h__
55
56#endif //_TnbDOXYGEN
57
58
59
60//TNB Library
61namespace TNB
62{
63
64
65
129}; //TNB
130
131
132
133#ifndef _TnbDOXYGEN //Document作成用シンボル
134
135#define EXTERN_IMAPI2_GUID(itf,id) EXTERN_GUID(itf, id, 0x7F64, 0x5B0F, 0x8F, 0x00, 0x5D, 0x77, 0xAF, 0xBE, 0x26, 0x1E)
136#define EXTERN_IMAPI2FS_GUID(itf,id) EXTERN_GUID(itf, id, 0x975B, 0x59BE, 0xA9, 0x60, 0x9A, 0x2A, 0x26, 0x28, 0x53, 0xA5)
137
138EXTERN_IMAPI2_GUID(CLSID_MsftDiscMaster2 , 0x2735412E);
139EXTERN_IMAPI2_GUID(CLSID_MsftDiscRecorder2 , 0x2735412D);
140EXTERN_IMAPI2_GUID(CLSID_MsftDiscFormat2Erase , 0x2735412B);
141EXTERN_IMAPI2_GUID(CLSID_MsftDiscFormat2Data , 0x2735412A);
142EXTERN_IMAPI2FS_GUID(CLSID_MsftFileSystemImage , 0x2C941FC5);
143
144EXTERN_IMAPI2_GUID(LIBID_IMAPILib2 , 0x2735412F);
145EXTERN_IMAPI2_GUID(IID_IDiscMaster2 , 0x2735412E);
146EXTERN_IMAPI2_GUID(IID_IDiscRecorder2 , 0x2735412D);
147EXTERN_IMAPI2_GUID(IID_IWriteEngine2 , 0x2735412C);
148EXTERN_IMAPI2_GUID(IID_IDiscFormat2Erase , 0x2735412B);
149EXTERN_IMAPI2_GUID(IID_IDiscFormat2Data , 0x2735412A);
150EXTERN_IMAPI2_GUID(IID_IDiscFormat2TrackAtOnce , 0x27354129);
151EXTERN_IMAPI2_GUID(IID_IDiscFormat2RawCD , 0x27354128);
152EXTERN_IMAPI2_GUID(IID_IWriteSpeedDescriptor , 0x27354123);
153EXTERN_IMAPI2_GUID(IID_IMultisessionSequential , 0x27354122);
154EXTERN_IMAPI2_GUID(IID_DDiscFormat2EraseEvents , 0x2735413A);
155EXTERN_IMAPI2_GUID(IID_DDiscFormat2DataEvents , 0x2735413C);
156EXTERN_IMAPI2_GUID(IID_DDiscMaster2Events , 0x27354131);
157
158EXTERN_IMAPI2FS_GUID(LIBID_IMAPI2FS , 0x2C941FD0);
159EXTERN_IMAPI2FS_GUID(IID_IBootOptions , 0x2C941FCE);
160EXTERN_IMAPI2FS_GUID(IID_IFsiStream , 0x2C941FCD);
161EXTERN_IMAPI2FS_GUID(IID_IFileSystemImageResult , 0x2C941FCC);
162EXTERN_IMAPI2FS_GUID(IID_IProgressItem , 0x2C941FCB);
163EXTERN_IMAPI2FS_GUID(IID_IEnumProgressItems , 0x2C941FCA);
164EXTERN_IMAPI2FS_GUID(IID_IProgressItems , 0x2C941FC9);
165EXTERN_IMAPI2FS_GUID(IID_IFsiDirectoryItem , 0x2C941FC8);
166EXTERN_IMAPI2FS_GUID(IID_IFsiFileItem , 0x2C941FC7);
167EXTERN_IMAPI2FS_GUID(IID_IEnumFsiItems , 0x2C941FC6);
168EXTERN_IMAPI2FS_GUID(IID_IFileSystemImage , 0x2C941FC5);
169EXTERN_IMAPI2FS_GUID(IID_DFileSystemImageEvents , 0x2C941FDF);
170
171// LIB は 'Lib2' か '2FS'
172#define _TnbImageMasterEventSuper(CLS, SID, LIB) \
173 public ::ATL::CComObjectRootEx<::ATL::CComSingleThreadModel>, \
174 public ::ATL::CComCoClass<CLS>, \
175 public ::ATL::IDispatchImpl< IDispatch, &SID, &LIBID_IMAPI##LIB, IMAPI##LIB##_MajorVersion, IMAPI##LIB##_MinorVersion>, \
176 public ::ATL::IDispEventImpl<1, CLS, &SID, &LIBID_IMAPI##LIB, IMAPI##LIB##_MajorVersion, IMAPI##LIB##_MinorVersion>
177
178#define _TnbImageMasterEventMember(CLS) \
179 DECLARE_NOT_AGGREGATABLE(CLS) \
180 BEGIN_COM_MAP(CLS) \
181 COM_INTERFACE_ENTRY(IDispatch) \
182 END_COM_MAP()
183
185struct IImageMasteringWriterListener
186{
187 virtual void OnWriterEvent(IDispatch* pObject, IDispatch* pProgressDisp) = 0;
188};
189
191class CImageMasteringWriterEvent : _TnbImageMasterEventSuper(CImageMasteringWriterEvent, IID_DDiscFormat2DataEvents, Lib2)
192{
193 _TnbImageMasterEventMember(CImageMasteringWriterEvent)
194 BEGIN_SINK_MAP(CImageMasteringWriterEvent)
195 SINK_ENTRY_EX(1, IID_DDiscFormat2DataEvents, DISPID_DDISCFORMAT2DATAEVENTS_UPDATE, &Update)
196 END_SINK_MAP()
197public:
198 STDMETHOD_(VOID, Update)(IDispatch* pObject, IDispatch* pProgressDisp)
199 {
200 m_pListener->OnWriterEvent(pObject, pProgressDisp);
201 }
202 IImageMasteringWriterListener* m_pListener;
203};
204
206struct IImageMasteringEraseListener
207{
208 virtual void OnEraseEvent(IDispatch* pObject, LONG elapsedSeconds, LONG expectedSeconds) = 0;
209};
210
212class CImageMasteringEraseEvent : _TnbImageMasterEventSuper(CImageMasteringEraseEvent, IID_DDiscFormat2EraseEvents, Lib2)
213{
214 _TnbImageMasterEventMember(CImageMasteringEraseEvent)
215 BEGIN_SINK_MAP(CImageMasteringEraseEvent)
216 SINK_ENTRY_EX(1, IID_DDiscFormat2EraseEvents, DISPID_IDISCFORMAT2ERASEEVENTS_UPDATE, &Update)
217 END_SINK_MAP()
218public:
219 STDMETHOD_(VOID, Update)(IDispatch* pObject, LONG elapsedSeconds, LONG expectedSeconds)
220 {
221 m_pListener->OnEraseEvent(pObject, elapsedSeconds, expectedSeconds);
222 }
223 IImageMasteringEraseListener* m_pListener;
224};
225
227struct IImageMasteringFileListener
228{
229 virtual void OnFileEvent(IDispatch* pObject, BSTR currentFile, LONG copiedSectors, LONG totalSectors) = 0;
230};
231
233class CImageMasteringFileEvent : _TnbImageMasterEventSuper(CImageMasteringFileEvent, IID_DFileSystemImageEvents, 2FS)
234{
235 _TnbImageMasterEventMember(CImageMasteringFileEvent)
236 BEGIN_SINK_MAP(CImageMasteringFileEvent)
237 SINK_ENTRY_EX(1, IID_DFileSystemImageEvents, DISPID_DFILESYSTEMIMAGEEVENTS_UPDATE, &Update)
238 END_SINK_MAP()
239public:
240 STDMETHOD_(VOID, Update)(IDispatch* pObject, BSTR currentFile, LONG copiedSectors, LONG totalSectors)
241 {
242 m_pListener->OnFileEvent(pObject, currentFile, copiedSectors, totalSectors);
243 }
244 IImageMasteringFileListener* m_pListener;
245};
246
248struct IImageMasteringListener
249{
250 virtual void OnAddedDevice(IDispatch* pObject, BSTR value);
251 virtual void OnRemovedDevice(IDispatch* pObject, BSTR value);
252};
253
255class CImageMasteringEvent : _TnbImageMasterEventSuper(CImageMasteringEvent, IID_DDiscMaster2Events, Lib2)
256{
257public:
258 _TnbImageMasterEventMember(CImageMasteringEvent)
259 BEGIN_SINK_MAP(CImageMasteringEvent)
260 SINK_ENTRY_EX(1, IID_DDiscMaster2Events, DISPID_DDISCMASTER2EVENTS_DEVICEADDED, &NotifyDeviceAdded )
261 SINK_ENTRY_EX(1, IID_DDiscMaster2Events, DISPID_DDISCMASTER2EVENTS_DEVICEREMOVED, &NotifyDeviceRemoved)
262 END_SINK_MAP()
263public:
264 STDMETHOD_(VOID, NotifyDeviceAdded)(IDispatch* pObject, BSTR value)
265 {
266 m_pListener->OnAddedDevice(pObject, value);
267 }
268 STDMETHOD_(VOID, NotifyDeviceRemoved)(IDispatch* pObject, BSTR value)
269 {
270 m_pListener->OnRemovedDevice(pObject, value);
271 }
272 IImageMasteringListener* m_pListener;
273};
274
276template<typename T> struct TImReleasePointerT
277{
279 void operator()(T P) { P->Release(); }
280};
281
282#endif // _TnbDOXYGEN
283
284
285
286//TNB Library
287namespace TNB
288{
289
290
291
305{
306public:
307
309 CImageMasteringResult(void) : m_lastResult(S_OK)
310 {
311 #ifdef __MSVCPP6__
312 ASSERT( _pModule != NULL );
313 #else
314 if ( _pAtlModule == NULL )
315 {
316 static CAtlMfcModule a;
317 VERIFY( ::OleInitialize(NULL) == S_OK );
318 }
319 #endif
320 }
321
326 HRESULT GetLastResult(void) const
327 {
328 return m_lastResult;
329 }
330
336 {
337 return ToString(m_lastResult);
338 }
339
346 static CStr ToString(HRESULT hr)
347 {
348 CStr s = _T("Unknown");
349 DWORD flag = FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_ALLOCATE_BUFFER;
350 LPVOID lpMsgBuf;
351 LPWSTR lpBuff = reinterpret_cast<LPWSTR>(&lpMsgBuf);
352 DWORD ret = ::FormatMessageW(flag | FORMAT_MESSAGE_FROM_HMODULE
353 , ::GetModuleHandle(_T("imapi2.dll"))
354 , hr, LANG_USER_DEFAULT, lpBuff, 0, NULL);
355 if ( ret == 0 )
356 {
357 _GetLastError("FormatMessage");
358 ret = ::FormatMessageW(flag | FORMAT_MESSAGE_FROM_HMODULE
359 , ::GetModuleHandle(_T("imapi2fs.dll"))
360 , hr, LANG_USER_DEFAULT, lpBuff, 0, NULL);
361 }
362 if (ret == 0)
363 {
364 _GetLastError("FormatMessage");
365 ret = ::FormatMessageW(flag | FORMAT_MESSAGE_FROM_SYSTEM
366 , NULL
367 , hr, LANG_USER_DEFAULT, lpBuff, 0, NULL);
368 }
369 if ( ret == 0 )
370 {
371 _GetLastError("FormatMessage");
372 }
373 else
374 {
375 s = static_cast<LPCWSTR>(lpMsgBuf);
376// s.TrimRight('\n').TrimRight('\r');
377 s.TrimRight(_T("\n\r"));
378 ::LocalFree(lpMsgBuf);
379 }
380 return s;
381 }
382
391 static HRESULT CreateStreamOnFile(LPCTSTR lpszFile, DWORD grfMode, IStream **ppstm)
392 {
393 try
394 {
395 #ifdef _UNICODE
396 typedef HRESULT (WINAPI* P_CSOFW)(LPCWSTR, DWORD, IStream**);
397 CDynamicFuncT<P_CSOFW> func("shlwapi.dll", "SHCreateStreamOnFileW");
398 #else
399 typedef HRESULT (WINAPI* P_CSOFA)(LPCSTR, DWORD, IStream**);
400 CDynamicFuncT<P_CSOFA> func("shlwapi.dll", "SHCreateStreamOnFileA");
401 #endif
402 return func()(lpszFile, grfMode, ppstm);
403 }
404 catch ( CNullPointerException& e )
405 {
406 e.OnCatch();
407 }
408 return E_FAIL;
409 }
410
411protected:
412
420 bool CheckRes(HRESULT hr) const
421 {
422 m_lastResult = hr;
423 if ( SUCCEEDED(hr) )
424 {
425 return true;
426 }
427 TRACE2(" Result =(0x%08X,[%s]\n", hr, ToString(hr));
428 return false;
429 }
430
431private:
432 mutable HRESULT m_lastResult;
433};
434
435
436
453{
454public:
455
458
461
464
467
470
471
472 //-------------------------------------------------------
473
474
491 class CDiscImage : public CImageMasteringResult, CCopyImpossible, IImageMasteringFileListener
492 {
493 public:
494
508 {
510 virtual ~IListener(void) {}
511
519 virtual void OnDiscImageAdded(LPCTSTR file, LONG copiedSectors, LONG totalSectors) = 0;
520 };
521
523 CDiscImage(void) : m_useJoliet(true), m_pListener(NULL), m_pEventSink(NULL), m_pRoot(NULL)
524 {
525 Reset();
526 }
527
530 {
531 m_ReleaseSink();
532 if ( m_pRoot != NULL )
533 {
534 m_pRoot->Release();
535 m_pRoot = NULL;
536 }
537 }
538
546 bool IsValid(void) const
547 {
548 return m_pRoot != NULL;
549 }
550
555 IFileSystemImage* operator->(void) const
556 {
557 return m_hpImage;
558 }
559
566 bool Reset(void)
567 {
568 m_pListener = NULL;
569 m_ReleaseSink();
570 if ( m_pRoot != NULL )
571 {
572 m_pRoot->Release();
573 m_pRoot = NULL;
574 }
575 IFileSystemImage* P = NULL;
576 if ( CheckRes(::CoCreateInstance(CLSID_MsftFileSystemImage, NULL, CLSCTX_ALL, IID_PPV_ARGS(&P))) )
577 {
578 m_hpImage = P;
579 if ( CheckRes(m_hpImage->put_FreeMediaBlocks(0/*infinite*/)) )
580 {
581 CheckRes(m_hpImage->get_Root(&m_pRoot));
582 }
583 }
584 return m_pRoot != NULL;
585 }
586
594 void SetJolietSystem(bool isEnable)
595 {
596 m_useJoliet = isEnable;
597 }
598
605 {
606 m_pListener = P;
607 m_ReleaseSink();
608 if ( P != NULL )
609 {
610 if ( CheckRes(CComObject<CImageMasteringFileEvent>::CreateInstance(&m_pEventSink)) )
611 {
612 m_pEventSink->AddRef();
613 m_pEventSink->m_pListener = this;
614 CheckRes(m_pEventSink->DispEventAdvise(m_hpImage));
615 }
616 }
617 }
618
625 size_t GetSectorSize(bool isXA = false) const
626 {
627 return isXA ? 2336 : 2048;
628 }
629
636 size_t GetSectorsCount(void) const
637 {
638 LONG r;
639 return CheckRes(m_hpImage->get_UsedBlocks(&r)) ? r : 0;
640 }
641
647 size_t GetFileCount(void) const
648 {
649 LONG r;
650 return CheckRes(m_hpImage->get_FileCount(&r)) ? r : 0;
651 }
652
658 size_t GetDirectoryCount(void) const
659 {
660 LONG r;
661 return CheckRes(m_hpImage->get_DirectoryCount(&r)) ? r : 0;
662 }
663
668 CStr GetVolumeName(void) const
669 {
670 CStr r;
671 CComBSTR s;
672 if ( CheckRes(m_hpImage->get_VolumeName(&s)) )
673 {
674 r = s;
675 }
676 return r;
677 }
678
685 bool SetVolumeName(LPCTSTR lpszVolume)
686 {
687 CComBSTR s = lpszVolume;
688 return CheckRes(m_hpImage->put_VolumeName(s));
689 }
690
708 bool AddSourceDirectory(LPCTSTR lpszPath, LPCTSTR lpszImagePath = NULL)
709 {
710 IFsiDirectoryItem* pDir = NULL;
711 CComBSTR name = lpszPath;
712 if ( lpszImagePath == NULL )
713 {
714 return CheckRes(m_pRoot->AddTree(name, false));
715 }
716 HRESULT hr = m_AddDirectory(m_pRoot, lpszImagePath);
717 if ( SUCCEEDED(hr) )
718 {
719 CComBSTR path = lpszImagePath;
720 hr = m_pRoot->get_Item(path, reinterpret_cast<IFsiItem**>(&pDir));
721 if ( SUCCEEDED(hr) && lpszPath != NULL )
722 {
723 hr = pDir->AddTree(name, false);
724 pDir->Release();
725 pDir = NULL;
726 }
727 }
728 return CheckRes(hr);
729 }
730
739 bool AddSourceFile(LPCTSTR lpszName, LPCTSTR lpszImagePath = NULL)
740 {
741 IFsiDirectoryItem* pDir = NULL;
742 if ( lpszImagePath == NULL )
743 {
744 return CheckRes(m_AddFile(m_pRoot, lpszName));
745 }
746 HRESULT hr = m_AddDirectory(m_pRoot, lpszImagePath);
747 if ( SUCCEEDED(hr) )
748 {
749 CComBSTR path = lpszImagePath;
750 hr = m_pRoot->get_Item(path, reinterpret_cast<IFsiItem**>(&pDir));
751 if ( SUCCEEDED(hr) && lpszName != NULL )
752 {
753 hr = m_AddFile(pDir, lpszName);
754 pDir->Release();
755 pDir = NULL;
756 }
757 }
758 return CheckRes(hr);
759 }
760
770 bool RemoveDirectory(LPCTSTR lpszImagePath)
771 {
772 CComBSTR s = lpszImagePath;
773 return CheckRes(m_pRoot->RemoveTree(s));
774 }
775
785 bool RemoveFile(LPCTSTR lpszImageName)
786 {
787 CComBSTR s = lpszImageName;
788 return CheckRes(m_pRoot->Remove(s));
789 }
790
798 bool SetBootImage(LPCTSTR lpszBootFileName)
799 {
800 IBootOptions* pBootOptions = NULL;
801 if ( ! CheckRes(::CoCreateInstance(CLSID_BootOptions, NULL, CLSCTX_ALL, IID_PPV_ARGS(&pBootOptions))) )
802 {
803 return false;
804 }
805 IStream* pBootStream = NULL;
806 HRESULT hr = CreateStreamOnFile(lpszBootFileName
807 , STGM_READ | STGM_SHARE_DENY_WRITE, &pBootStream);
808 if ( SUCCEEDED(hr) )
809 {
810 hr = pBootOptions->AssignBootImage(pBootStream);
811 }
812 if ( SUCCEEDED(hr) )
813 {
814 hr = m_hpImage->put_BootImageOptions(pBootOptions);
815 }
816 if ( pBootStream != NULL )
817 {
818 pBootStream->Release();
819 pBootStream = NULL;
820 }
821 pBootOptions->Release();
822 pBootOptions = NULL;
823 return CheckRes(hr);
824 }
825
834 bool SetWorkingDirestory(LPCTSTR lpszPath)
835 {
836 CComBSTR s = lpszPath;
837 return CheckRes(m_hpImage->put_WorkingDirectory(s));
838 }
839
845 {
848 };
849
860 {
861 return m_EnumFiles(_items, m_pRoot);
862 }
863
874 {
875 IStream* pSrcStream = CreateImageSteam(type);
876 if ( pSrcStream != NULL )
877 {
878 IStream* pDstStream = NULL;
879 HRESULT hr = CreateStreamOnFile(lpszFileName
880 , STGM_WRITE | STGM_CREATE, &pDstStream);
881 if ( SUCCEEDED(hr) )
882 {
883 STATSTG stat = { 0 };
884 hr = pSrcStream->Stat(&stat, STATFLAG_NONAME);
885 if ( SUCCEEDED(hr) )
886 {
887 ULARGE_INTEGER cbRead = {0};
888 ULARGE_INTEGER cbWritten = {0};
889 hr = pSrcStream->CopyTo(pDstStream, stat.cbSize, &cbRead, &cbWritten);
890 }
891 pDstStream->Release();
892 pDstStream = NULL;
893 }
894 pSrcStream->Release();
895 pSrcStream = NULL;
896 return CheckRes(hr);
897 }
898 return false;
899 }
900
909 {
910 HRESULT hr = m_hpImage->put_FileSystemsToCreate(m_ToFileSystem(type));
911 if ( SUCCEEDED(hr) )
912 {
913 IFileSystemImageResult* pResultStream = NULL;
914 hr = m_hpImage->CreateResultImage(&pResultStream);
915 if ( SUCCEEDED(hr) )
916 {
917 IStream* pStream = NULL;
918 hr = pResultStream->get_ImageStream(&pStream);
919 pResultStream->Release();
920 pResultStream = NULL;
921 if ( SUCCEEDED(hr) )
922 {
923 return pStream;
924 }
925 }
926 }
927 VERIFY( ! CheckRes(hr) );
928 return NULL;
929 }
930
931 private:
932 // [取得] ファイルシステム種類取得.
933 FsiFileSystems m_ToFileSystem(IMAPI_MEDIA_PHYSICAL_TYPE type = IMAPI_MEDIA_TYPE_CDR) const
934 {
935 FsiFileSystems f = FsiFileSystemUDF;
936 switch ( type )
937 {
941 if ( m_useJoliet )
942 {
943 f = static_cast<FsiFileSystems>(FsiFileSystemJoliet | FsiFileSystemISO9660);
944 }
945 else
946 {
947 f = FsiFileSystemISO9660;
948 }
949 break;
950 default:
951 break;
952 }
953 return f;
954 }
955 // ディレクトリ追加
956 HRESULT m_AddDirectory(IFsiDirectoryItem* _pDir, LPCTSTR lpszPath)
957 {
958 CStr path = lpszPath;
959// path.TrimLeft('\\').TrimLeft('/').TrimRight('\\').TrimRight('/');
960 path.Trim(_T("\\/"));
961 if ( path.IsEmpty() )
962 {
963 return S_OK;
964 }
965// INT_PTR f = path.ReverseFind('\\');
966// if ( f < 0 )
967// {
968// f = path.ReverseFind('/');
969// }
970 INT_PTR f = path.ReverseFindOneOf(_T("\\/"));
971 if ( f >= 0 )
972 {
973 HRESULT hr = m_AddDirectory(_pDir, path.Left(f));
974 if ( ! SUCCEEDED(hr) )
975 {
976 return hr;
977 }
978 }
979 CComBSTR p = path;
980 return _pDir->AddDirectory(p);
981 }
982 // ファイル追加
983 HRESULT m_AddFile(IFsiDirectoryItem* _pDir, LPCTSTR lpszFileName)
984 {
985 IStream* pStream = NULL;
986 HRESULT hr = CreateStreamOnFile(lpszFileName
987 , STGM_READ | STGM_SHARE_DENY_WRITE, &pStream);
988 if ( SUCCEEDED(hr) )
989 {
990 CStr s = lpszFileName;
991// INT_PTR f = s.ReverseFind(_T("\\"));
992// if ( f < 0 )
993// {
994// f = s.ReverseFind(_T("/"));
995// }
996 INT_PTR f = s.ReverseFindOneOf(_T("\\/"));
997 if ( f >= 0 )
998 {
999 s = s.Mid(f + 1);
1000 }
1001 CComBSTR name = s;
1002 //hr = _pDir->AddFile(name, pStream); //これだと日付が今になってしまう
1003 STATSTG stat = { 0 };
1004 hr = pStream->Stat(&stat, STATFLAG_NONAME);
1005 if ( SUCCEEDED(hr) )
1006 {
1007 IFsiFileItem* I = NULL;
1008 hr = m_hpImage->CreateFileItem(name, &I);
1009 if ( SUCCEEDED(hr) )
1010 {
1011 I->put_Data(pStream);
1012 I->put_CreationTime(COleDateTime(stat.ctime));
1013 I->put_LastAccessedTime(COleDateTime(stat.atime));
1014 I->put_LastModifiedTime(COleDateTime(stat.mtime));
1015 hr = _pDir->Add(I);
1016 I->Release();
1017 I =NULL;
1018 }
1019 }
1020 pStream->Release();
1021 pStream = NULL;
1022 }
1023 return hr;
1024 }
1026 bool m_EnumFiles(CVectorT<TFileItem>& _items, IFsiDirectoryItem* pDirs) const
1027 {
1028 IEnumFsiItems* pItems = NULL;
1029 HRESULT hr = pDirs->get_EnumFsiItems(&pItems);
1030 ULONG celt = 0;
1031 while ( true )
1032 {
1033 IFsiItem* pFI = NULL;
1034 hr = pItems->Next(1, &pFI, &celt);
1035 if ( hr != S_OK )
1036 {
1037 break;
1038 }
1039 if ( pFI != NULL )
1040 {
1041 TFileItem fi;
1042 IFsiDirectoryItem* P = NULL;
1043 fi.isDirectory = SUCCEEDED(pFI->QueryInterface(&P));
1044 CComBSTR s;
1045 pFI->get_FullPath(&s);
1046 fi.name = s;
1047 _items.Add(fi);
1048 if ( P != NULL && ! m_EnumFiles(_items, P) )
1049 {
1050 break;
1051 }
1052 pFI->Release();
1053 pFI = NULL;
1054 }
1055 pItems->Skip(celt);
1056 }
1057 pItems->Release();
1058 pItems = NULL;
1059 return CheckRes(hr);
1060 }
1061 void m_ReleaseSink(void)
1062 {
1063 if ( m_pEventSink != NULL )
1064 {
1065 m_pEventSink->DispEventUnadvise(m_pRoot);
1066 m_pEventSink->Release();
1067 m_pEventSink = NULL;
1068 }
1069 }
1071 virtual void OnFileEvent(IDispatch* object, BSTR currentFile, LONG copiedSectors, LONG totalSectors)
1072 {
1073 if ( m_pListener != NULL )
1074 {
1075 m_pListener->OnDiscImageAdded(CStr(currentFile), copiedSectors, totalSectors);
1076 }
1077 }
1078 bool m_useJoliet;
1079 IFsiDirectoryItem* m_pRoot;
1080 CFileSystemImageHandle m_hpImage;
1081 IListener* m_pListener;
1082 CComObject<CImageMasteringFileEvent>* m_pEventSink;
1083 };
1084
1085
1086 //-------------------------------------------------------------
1087
1088
1106 {
1107 public:
1108
1122 {
1127 {
1128 public:
1133 virtual LONG GetRemainingTime(void) const = 0;
1138 virtual LONG GetElapsedTime(void) const = 0;
1143 virtual LONG GetExpectedTime(void) const = 0;
1148 virtual LONG GetStartLba(void) const = 0;
1153 virtual LONG GetTotalSectorCount(void) const = 0;
1158 virtual LONG GetWrittenLba(void) const = 0;
1163 virtual LONG GetWrittenSector(void) const = 0;
1164 };
1165
1167 virtual ~IListener(void) {}
1168
1174 virtual void OnDriveErrorResult(HRESULT hr) = 0;
1175
1186
1192 virtual void OnDriveEraseEvent(const CProgressData& pd) = 0;
1193 };
1194
1195
1196 //-----------------------------------
1197
1198
1205 CDrive(CDiscRecorderHandle dr, LPCTSTR name)
1206 {
1207 m_Recorder() = dr;
1208 if ( ! m_Recorder().IsNull() )
1209 {
1210 CComBSTR s = name;
1211 if ( ! CheckRes(m_Recorder()->InitializeDiscRecorder(s)) )
1212 {
1213 m_Recorder().Null();
1214 }
1215 m_Writer() = m_CreateDiscFormatData();
1216 if ( m_Writer().IsNull() )
1217 {
1218 m_Recorder().Null();
1219 }
1220 }
1221 }
1222
1230 bool IsValid(void) const
1231 {
1232 return ! m_Recorder().IsNull();
1233 }
1234
1239 IDiscRecorder2* operator->(void)
1240 {
1241 return m_Recorder();
1242 }
1243
1248 void SetListener(IListener* pListener)
1249 {
1250 m_member.pListener = pListener;
1251 }
1252
1262 bool Erase(bool isFull = false)
1263 {
1264 CDiscFormatEraseHandle hpEraser = m_CreateDiscFormatErase();
1265 HRESULT hr = S_OK;
1266 if ( isFull )
1267 {
1268 hr = hpEraser->put_FullErase(VARIANT_TRUE);
1269 }
1270 if ( CheckRes(hr) )
1271 {
1272 CComObject<CImageMasteringEraseEvent>* pEventSink = NULL;
1273 if ( CheckRes(CComObject<CImageMasteringEraseEvent>::CreateInstance(&pEventSink)) )
1274 {
1275 pEventSink->AddRef();
1276 pEventSink->m_pListener = &m_member;
1277 pEventSink->DispEventAdvise(hpEraser);
1278 hr = hpEraser->EraseMedia();
1279 bool r = CheckRes(hr);
1280 pEventSink->DispEventUnadvise(hpEraser);
1281 pEventSink->Release();
1282 pEventSink = NULL;
1283 return r;
1284 }
1285 }
1286 return false;
1287 }
1288
1301 bool Burn(const CDiscImage& discImage, bool isClose = true)
1302 {
1303 IFileSystemImage* pImage = discImage.operator->();
1304 if ( pImage == NULL )
1305 {
1306 return false;
1307 }
1308 LONG changePoint = -1;
1309 bool r = CheckRes(pImage->get_ChangePoint(&changePoint));
1310 IStream* pSrcStream = NULL;
1311 if ( r )
1312 {
1313 pSrcStream = discImage.CreateImageSteam(GetTypeOnDisc());
1314 if ( pSrcStream == NULL )
1315 {
1316 r = CheckRes(discImage.GetLastResult());
1317 ASSERT( ! r );
1318 }
1319 }
1320 r = m_SetCloseDiscMode(isClose);
1321 if ( r )
1322 {
1323 r = m_CheckDvdplusrdl();
1324 }
1325 if ( r && ! IsBlankDisc() && IsAppendableDisc() )
1326 {
1327 r = m_MultiDisp(pImage);
1328 }
1329 if ( r )
1330 {
1331 r = m_Burn(pSrcStream);
1332 }
1333 if ( pSrcStream != NULL )
1334 {
1335 pSrcStream->Release();
1336 pSrcStream = NULL;
1337 }
1338 if ( changePoint >= 0 )
1339 {
1340 pImage->RollbackToChangePoint(changePoint);
1341 }
1342 return r;
1343 }
1344
1356 bool Burn(LPCTSTR lpszFileName, bool isClose = true)
1357 {
1358 if ( m_Writer().IsNull() )
1359 {
1360 return false;
1361 }
1362 if ( ! m_SetCloseDiscMode(isClose) )
1363 {
1364 return false;
1365 }
1366 IStream* pStream = NULL;
1367 HRESULT hr = CreateStreamOnFile(lpszFileName
1368 , STGM_READ | STGM_SHARE_DENY_WRITE, &pStream);
1369 bool r = CheckRes(hr);
1370 if ( r )
1371 {
1372 r = m_Burn(pStream);
1373 }
1374 if ( pStream != NULL )
1375 {
1376 pStream->Release();
1377 pStream = NULL;
1378 }
1379 return r;
1380 }
1381
1387 bool OpenTray(void)
1388 {
1389 return m_Tray(true);
1390 }
1391
1398 bool CloseTray(void)
1399 {
1400 return m_Tray(false);
1401 }
1402
1408 {
1412 };
1413
1419 {
1420 TInformation info;
1421 if ( ! m_Recorder().IsNull() )
1422 {
1423 info.vendorId = m_GetBstrKindString(BstrKind_VendorId);
1424 info.productId = m_GetBstrKindString(BstrKind_ProductId);
1425 info.productRevision= m_GetBstrKindString(BstrKind_ProductRevision);
1426 }
1427 return info;
1428 }
1429
1438 bool EnumerationMountPath(CStrVector& _mountPaths) const
1439 {
1440 _mountPaths.RemoveAll();
1441 SAFEARRAY* pSA = NULL;
1442 if ( ! m_Recorder().IsNull() && CheckRes(m_Recorder()->get_VolumePathNames(&pSA)) )
1443 {
1444 VARIANT* P = static_cast<VARIANT*>(pSA->pvData);
1445 loop ( i, pSA->rgsabound[0].cElements )
1446 {
1447 ASSERT( P[i].vt == VT_BSTR );
1448 _mountPaths.Add(CStr(P[i].bstrVal));
1449 }
1450 ::SafeArrayDestroyData(pSA);
1451 pSA = NULL;
1452 return true;
1453 }
1454 return false;
1455 }
1456
1462 size_t GetSectorSize(void) const
1463 {
1464 return 2048;
1465 }
1466
1475 {
1476 _speeds.RemoveAll();
1477 SAFEARRAY* pSA = NULL;
1478 if ( ! m_Writer().IsNull() && CheckRes(m_Writer()->get_SupportedWriteSpeeds(&pSA)) )
1479 {
1480 VARIANT* P = static_cast<VARIANT*>(pSA->pvData);
1481 loop ( i, pSA->rgsabound[0].cElements )
1482 {
1483 _speeds.Add(static_cast<WORD>(P[i].ulVal));
1484 }
1485 ::SafeArrayDestroyData(pSA);
1486 pSA = NULL;
1487 return true;
1488 }
1489 return false;
1490 }
1491
1503 bool SetWriteSpeed(int speed = -1, bool isPureCAV = false)
1504 {
1505 if ( ! m_Writer().IsNull() )
1506 {
1507 VARIANT_BOOL r = isPureCAV ? VARIANT_TRUE : VARIANT_FALSE;
1508 return CheckRes(m_Writer()->SetWriteSpeed(speed, r));
1509 }
1510 return false;
1511 }
1512
1519 size_t GetTotalSectorsOnDisc(void) const
1520 {
1521 if ( ! m_Writer().IsNull() )
1522 {
1523 LONG l;
1524 if ( CheckRes(m_Writer()->get_TotalSectorsOnMedia(&l)) )
1525 {
1526 return l;
1527 }
1528 }
1529 return 0;
1530 }
1531
1537 size_t GetFreeSectorsOnDisc(void) const
1538 {
1539 if ( ! m_Writer().IsNull() )
1540 {
1541 LONG l;
1542 if ( CheckRes(m_Writer()->get_FreeSectorsOnMedia(&l)) )
1543 {
1544 return l;
1545 }
1546 }
1547 return 0;
1548 }
1549
1558 bool ExistDisc(DWORD time = 0) const
1559 {
1560 if ( ! m_Writer().IsNull() )
1561 {
1562 VARIANT_BOOL isBlank = FALSE;
1563 CTickCount ti;
1564 while ( true )
1565 {
1566 HRESULT hr = m_Writer()->get_MediaHeuristicallyBlank(&isBlank);
1567 if ( hr == E_IMAPI_RECORDER_MEDIA_NO_MEDIA || hr == E_IMAPI_RECORDER_MEDIA_BECOMING_READY )
1568 {
1569 if ( ! ti.IsPassed(time) )
1570 {
1571 ::Sleep(200);
1572 continue;
1573 }
1574 CheckRes(S_OK);
1575 return false;
1576 }
1577 return CheckRes(hr);
1578 }
1579 }
1580 return false;
1581 }
1582
1596 int GetStatusOnDisc(void) const
1597 {
1598 IMAPI_FORMAT2_DATA_MEDIA_STATE s = IMAPI_FORMAT2_DATA_MEDIA_STATE_UNKNOWN;
1599 if ( ! m_Writer().IsNull() )
1600 {
1601 CheckRes(m_Writer()->get_CurrentMediaStatus(&s));
1602 }
1603 return s;
1604 }
1605
1611 {
1612 CStrVector mountPaths;
1613 if ( EnumerationMountPath(mountPaths) )
1614 {
1615 loop ( i, mountPaths.GetSize() )
1616 {
1617 CStr path;
1618 DWORD serialNumber;
1619 DWORD maxLen;
1620 DWORD fileSystemFlags;
1621 bool r = !!::GetVolumeInformation(mountPaths[i], path.GetBuffer(1000), 1000
1622 , &serialNumber, &maxLen, &fileSystemFlags, NULL, 0);
1623 if ( r )
1624 {
1625 path.ReleaseBuffer();
1626 return path;
1627 }
1628 }
1629 }
1630 return _T("");
1631 }
1632
1638 bool IsBlankDisc(void) const
1639 {
1640 if ( ! m_Writer().IsNull() )
1641 {
1642 VARIANT_BOOL isBlank = FALSE;
1643 HRESULT hr = m_Writer()->get_MediaHeuristicallyBlank(&isBlank);
1644 if ( CheckRes(hr) )
1645 {
1646 return !! isBlank;
1647 }
1648 }
1649 return false;
1650 }
1651
1657 bool IsAppendableDisc(void) const
1658 {
1660 }
1661
1664
1672 {
1673 _types.RemoveAll();
1674 SAFEARRAY* pSA = NULL;
1675 if ( ! m_Writer().IsNull() && CheckRes(m_Writer()->get_SupportedMediaTypes(&pSA)) )
1676 {
1677 VARIANT* P = static_cast<VARIANT*>(pSA->pvData);
1678 loop ( i, pSA->rgsabound[0].cElements )
1679 {
1680 ASSERT( P[i].vt == VT_I4 );
1681 IMAPI_MEDIA_PHYSICAL_TYPE t = static_cast<IMAPI_MEDIA_PHYSICAL_TYPE>(P[i].lVal);
1682 _types.Add(t);
1683 }
1684 ::SafeArrayDestroyData(pSA);
1685 pSA = NULL;
1686 return true;
1687 }
1688 return false;
1689 }
1690
1698 {
1700 if ( ! m_Writer().IsNull() )
1701 {
1702 CheckRes(m_Writer()->get_CurrentPhysicalMediaType(&type));
1703 }
1704 return type;
1705 }
1706
1714 {
1716 }
1717
1726 bool ReadMultiSession(CDiscImage& _diskImage) const
1727 {
1728 IFileSystemImage* pImage = _diskImage.operator ->();
1729 bool r = m_MultiDisp(pImage);
1730 CStr s = GetVolumeOnDisc();
1731 if ( ! s.IsEmpty() )
1732 {
1733 _diskImage.SetVolumeName(s);
1734 }
1735 return r;
1736 }
1737
1738 private:
1740 bool m_Burn(IStream* pStream)
1741 {
1742 ASSERT( pStream != NULL );
1743 CComObject<CImageMasteringWriterEvent>* pEventSink = NULL;
1744 HRESULT hr = CComObject<CImageMasteringWriterEvent>::CreateInstance(&pEventSink);
1745 if ( SUCCEEDED(hr) )
1746 {
1747 ASSERT( pEventSink != NULL );
1748 pEventSink->AddRef();
1749 pEventSink->m_pListener = &m_member;
1750 pEventSink->DispEventAdvise(m_Writer());
1751 hr = m_Writer()->Write(pStream);
1752 pEventSink->DispEventUnadvise(m_Writer());
1753 pEventSink->Release();
1754 pEventSink = NULL;
1755 }
1756 return CheckRes(hr);
1757 }
1758 // Close the disc if specified
1759 bool m_SetCloseDiscMode(bool isClose = true)
1760 {
1761 HRESULT hr = m_Writer()->put_ForceMediaToBeClosed(isClose ? VARIANT_TRUE : VARIANT_FALSE);
1762 return CheckRes(hr);
1763 }
1764 // verify the StartAddressOfPreviousSession property
1765 // ALSO -- for DVD+R DL, if from sector zero, set to finalize media
1766 bool m_CheckDvdplusrdl(void)
1767 {
1768 return true;
1769#if 0
1770 LONG value = 0;
1771 HRESULT hr = m_Writer()->get_StartAddressOfPreviousSession(&value);
1772 if ( SUCCEEDED(hr) && value == -1 )
1773 {
1774 hr = m_Writer()->put_ForceMediaToBeClosed(VARIANT_TRUE);
1775 }
1776 return CheckRes(hr);
1777#endif
1778 }
1779 // ImportFileSystem - Import file data from disc
1780 bool m_MultiDisp(IFileSystemImage* pImage) const
1781 {
1782 SAFEARRAY* pSA = NULL;
1783 if ( SUCCEEDED(pImage->get_MultisessionInterfaces(&pSA)) )
1784 {
1785 ULONG l = pSA->rgsabound[0].cElements;
1786 ::SafeArrayDestroyData(pSA);
1787 if ( l > 0 )
1788 {
1789 // セッション登録済み
1790 return true;
1791 }
1792 }
1793 SAFEARRAY* pMultiSession = NULL;
1794 // Get mutlisession interface to set in image
1795 HRESULT hr = m_Writer()->get_MultisessionInterfaces(&pMultiSession);
1796 // Set the multisession interface in the image
1797 if ( SUCCEEDED(hr) )
1798 {
1799 hr = pImage->put_MultisessionInterfaces(pMultiSession);
1800 }
1801 if ( SUCCEEDED(hr) )
1802 {
1803 FsiFileSystems fileSystems;
1804 hr = pImage->ImportFileSystem(&fileSystems);
1805 if ( hr == IMAPI_E_EMPTY_DISC )
1806 {
1807 // Empty Disc は OK
1808 hr = S_OK;
1809 }
1810 }
1811 if ( pMultiSession != NULL )
1812 {
1813 ::SafeArrayDestroy(pMultiSession);
1814 pMultiSession = NULL;
1815 }
1816 return CheckRes(hr);
1817 }
1819 bool m_Tray(bool isOpen)
1820 {
1821 if ( ! m_Recorder().IsNull() )
1822 {
1823 if ( CheckRes(m_Recorder()->DisableMcn()) )
1824 {
1825 bool r = CheckRes(isOpen ? m_Recorder()->EjectMedia() : m_Recorder()->CloseTray());
1826 m_Recorder()->EnableMcn();
1827 return r;
1828 }
1829 }
1830 return false;
1831 }
1833 enum EBstrKind
1834 {
1835 BstrKind_VendorId,
1836 BstrKind_ProductId,
1837 BstrKind_ProductRevision,
1838 BstrKind_ExclusiveAccessOwner,
1839 };
1841 CStr m_GetBstrKindString(EBstrKind k) const
1842 {
1843 CStr s;
1844 if ( ! m_Recorder().IsNull() )
1845 {
1846 CComBSTR str;
1847 HRESULT hr = E_FAIL;
1848 switch ( k )
1849 {
1850 case BstrKind_VendorId:
1851 hr = m_Recorder()->get_VendorId(&str);
1852 break;
1853 case BstrKind_ProductId:
1854 hr = m_Recorder()->get_ProductId(&str);
1855 break;
1856 case BstrKind_ProductRevision:
1857 hr = m_Recorder()->get_ProductRevision(&str);
1858 break;
1859 case BstrKind_ExclusiveAccessOwner:
1860 hr = m_Recorder()->get_ExclusiveAccessOwner(&str);
1861 break;
1862 default:
1863 break;
1864 }
1865 if ( CheckRes(hr) )
1866 {
1867 s = str;
1868 }
1869 }
1870 return s;
1871 }
1872 // PutRecorder 済み DiscFormat 作成
1873 template<typename TYP>
1874 void m_AdjustHandle(TYP& hp) const
1875 {
1876 if ( ! CheckRes(hp->put_Recorder(m_Recorder())) )
1877 {
1878 hp.Null();
1879 }
1880 else
1881 {
1882 CComBSTR s = _T("TnbImageMastering");
1883 if ( ! CheckRes(hp->put_ClientName(s)) )
1884 {
1885 hp.Null();
1886 }
1887 }
1888 }
1889 // PutRecorder 済み DiscFormatData 作成
1890 CDiscFormatDataHandle m_CreateDiscFormatData(void) const
1891 {
1893 if ( ! m_Recorder().IsNull() )
1894 {
1895 IDiscFormat2Data* P = NULL;
1896 if ( CheckRes(::CoCreateInstance(CLSID_MsftDiscFormat2Data, NULL, CLSCTX_ALL, IID_PPV_ARGS(&P))) )
1897 {
1898 hp = P;
1899 m_AdjustHandle(hp);
1900 }
1901 }
1902 return hp;
1903 }
1904 // PutRecorder 済み DiscFormatErase 作成
1905 CDiscFormatEraseHandle m_CreateDiscFormatErase(void) const
1906 {
1908 if ( ! m_Recorder().IsNull() )
1909 {
1910 IDiscFormat2Erase* P = NULL;
1911 if ( CheckRes(::CoCreateInstance(CLSID_MsftDiscFormat2Erase, NULL, CLSCTX_ALL, IID_PPV_ARGS(&P))) )
1912 {
1913 hp = P;
1914 m_AdjustHandle(hp);
1915 }
1916 }
1917 return hp;
1918 }
1919
1920 //----
1921
1922 #ifndef _TnbDOXYGEN //Document作成用シンボル
1923
1925 CDiscRecorderHandle& m_Recorder(void) const
1926 {
1927 return m_member.hpRecorder;
1928 }
1930 CDiscFormatDataHandle& m_Writer(void) const
1931 {
1932 return m_member.hpWriter;
1933 }
1935 class CMyProgressData : public IListener::CProgressData
1936 {
1937 public:
1939 CMyProgressData(void) : m_elapsedTime(0), m_expectedTime(0)
1940 , m_startLba(0), m_sectorCount(0), m_lastWrittenLba(0)
1941 {}
1942 LONG GetRemainingTime(void) const { return m_expectedTime - m_elapsedTime; }
1943 LONG GetElapsedTime(void) const { return m_elapsedTime; }
1944 LONG GetExpectedTime(void) const { return m_expectedTime; }
1945 LONG GetStartLba(void) const { return m_startLba; }
1946 LONG GetTotalSectorCount(void) const { return m_sectorCount; }
1947 LONG GetWrittenLba(void) const { return m_lastWrittenLba; }
1948 LONG GetWrittenSector(void) const { return m_lastWrittenLba - m_startLba; }
1949 //
1950 LONG m_elapsedTime;
1951 LONG m_expectedTime;
1952 LONG m_startLba;
1953 LONG m_sectorCount;
1954 LONG m_lastWrittenLba;
1955 };
1957 struct TMember : IImageMasteringWriterListener, IImageMasteringEraseListener
1958 {
1960 TMember(void) : pListener(NULL)
1961 {}
1962 //書き込みイベント
1963 virtual void OnWriterEvent(IDispatch* pObjectDisp, IDispatch* pProgressDisp)
1964 {
1965 if ( pListener == NULL ) { return; }
1966 IDiscFormat2DataEventArgs* pProgress = NULL;
1967 HRESULT hr = pProgressDisp->QueryInterface(IID_PPV_ARGS(&pProgress));
1968 if ( FAILED(hr) )
1969 {
1970 pListener->OnDriveErrorResult(hr);
1971 return;
1972 }
1974 hr = pProgress->get_CurrentAction(&currentAction);
1975 if ( FAILED(hr) )
1976 {
1977 pListener->OnDriveErrorResult(hr);
1978 return;
1979 }
1980 CMyProgressData pd;
1981 pProgress->get_ElapsedTime(&pd.m_elapsedTime);
1982 pProgress->get_TotalTime(&pd.m_expectedTime);
1983 pProgress->get_StartLba(&pd.m_startLba);
1984 pProgress->get_SectorCount(&pd.m_sectorCount);
1985 pProgress->get_LastWrittenLba(&pd.m_lastWrittenLba);
1986 switch ( currentAction )
1987 {
1990 pd.m_elapsedTime = pd.m_expectedTime;
1991 pd.m_lastWrittenLba = pd.m_startLba + pd.m_sectorCount;
1992 break;
1993 default:
1994 break;
1995 }
1996 if ( ! pListener->OnDriveWriteEvent(pd, currentAction) )
1997 {
1998 hpWriter->CancelWrite();
1999 }
2000 }
2001 //消去イベント
2002 virtual void OnEraseEvent(IDispatch* object, LONG elapsedSeconds, LONG expectedSeconds)
2003 {
2004 if ( pListener != NULL )
2005 {
2006 CMyProgressData pd;
2007 pd.m_elapsedTime = elapsedSeconds;
2008 pd.m_expectedTime = expectedSeconds;
2009 pListener->OnDriveEraseEvent(pd);
2010 }
2011 }
2012 IListener* pListener;
2013 CDiscRecorderHandle hpRecorder;
2014 CDiscFormatDataHandle hpWriter;
2015 };
2016 mutable TMember m_member;
2017
2018 #endif //_TnbDOXYGEN
2019 };
2020
2021
2022 //------------------------------------------------
2023
2024
2027 {
2028 }
2029
2036 bool IsSupported(void) const
2037 {
2038 m_CheckInst();
2039 if ( ! m_hpDiscMaster.IsNull() )
2040 {
2041 VARIANT_BOOL b;
2042 HRESULT hr = m_hpDiscMaster->get_IsSupportedEnvironment(&b);
2043 if ( SUCCEEDED(hr) )
2044 {
2045 return b != 0;
2046 }
2047 }
2048 return false;
2049 }
2050
2056 size_t GetDriveCount(void) const
2057 {
2058 m_CheckInst();
2059 if ( ! m_hpDiscMaster.IsNull() )
2060 {
2061 LONG cnt;
2062 HRESULT hr = m_hpDiscMaster->get_Count(&cnt);
2063 if ( SUCCEEDED(hr) )
2064 {
2065 return cnt;
2066 }
2067 }
2068 return 0;
2069 }
2070
2077 CStr GetDriveName(INDEX index) const
2078 {
2079 CStr s;
2080 if ( GetDriveCount() > index )
2081 {
2082 CComBSTR str;
2083 HRESULT hr = m_hpDiscMaster->get_Item(index, &str);
2084 if ( SUCCEEDED(hr) )
2085 {
2086 s = str;
2087 }
2088 }
2089 return s;
2090 }
2091
2099 CDrive CreateDrive(INDEX index) const
2100 {
2101 IDiscRecorder2* P = NULL;
2102 CheckRes(::CoCreateInstance(CLSID_MsftDiscRecorder2, NULL, CLSCTX_ALL, IID_PPV_ARGS(&P)));
2103 return CDrive(P, GetDriveName(index));
2104 }
2105
2112 {
2114 {
2116 IMAPI_MEDIA_TYPE_CDROM, _T("CD-ROM"),
2117 IMAPI_MEDIA_TYPE_CDR, _T("CD-R"),
2118 IMAPI_MEDIA_TYPE_CDRW, _T("CD-RW"),
2119 IMAPI_MEDIA_TYPE_DVDROM, _T("DVD-ROM"),
2120 IMAPI_MEDIA_TYPE_DVDRAM, _T("DVD-RAM"),
2121 IMAPI_MEDIA_TYPE_DVDPLUSR, _T("DVD+R"),
2122 IMAPI_MEDIA_TYPE_DVDPLUSRW, _T("DVD+RW"),
2124 IMAPI_MEDIA_TYPE_DVDDASHR, _T("DVD-R"),
2125 IMAPI_MEDIA_TYPE_DVDDASHRW, _T("DVD-RW"),
2127 IMAPI_MEDIA_TYPE_DISK, _T("DISK"),
2128 IMAPI_MEDIA_TYPE_DVDPLUSRW_DUALLAYER, _T("DVD+RW DL"),
2129 IMAPI_MEDIA_TYPE_HDDVDROM, _T("HD DVD-ROM"),
2130 IMAPI_MEDIA_TYPE_HDDVDR, _T("HD DVD-R"),
2131 IMAPI_MEDIA_TYPE_HDDVDRAM, _T("HD DVD-RAM"),
2132 IMAPI_MEDIA_TYPE_BDROM, _T("BD-ROM"),
2133 IMAPI_MEDIA_TYPE_BDR, _T("BD-R"),
2134 IMAPI_MEDIA_TYPE_BDRE, _T("BD-RE"),
2135 };
2137 }
2138
2139private:
2140 // インスタンスチェック.
2141 bool m_CheckInst(void) const
2142 {
2143 if ( m_hpDiscMaster.IsNull() )
2144 {
2145 IDiscMaster2* P = NULL;
2146 CheckRes(::CoCreateInstance(CLSID_MsftDiscMaster2, NULL, CLSCTX_ALL, IID_PPV_ARGS(&P)));
2147 m_hpDiscMaster = P;
2148 }
2149 return ! m_hpDiscMaster.IsNull();
2150 }
2151 mutable CDiscMasterHandle m_hpDiscMaster;
2152};
2153
2154
2155
2156}; //TNB
2157
2158
2159
2160#ifdef _TnbDOXYGEN //Document作成用シンボル
2161
2167{
2175};
2176
2182{
2194
2200{
2221};
2222
2223#endif
2224
2225
2226#if 0
2227
2228todo;
2229
2230 When unlocking a recorder, the lock count must reach zero to free
2231 the device for other clients. Calling the IDiscRecorder2::ReleaseExclusiveAccess
2232 method decrements the lock count by one.
2233
2234 An equal number of calls to the AcquireExclusiveAccess and
2235 ReleaseExclusiveAccess methods are needed to free a device.
2236 Should the application exit unexpectedly or crash while holding
2237 the exclusive access, the CDROM.SYS driver will automatically
2238 release these exclusive locks.
2239
2240 If the device is already locked, you can call IDiscRecorder2::get_ExclusiveAccessOwner
2241 to retrieve the name of the client application that currently has exclusive access.
2242
2243todo;
2244
2245 VC++6 、MFC で作成したダイアログ上で、書き込みしている時、
2246 フォーカス移動で、なぞの アクセスバイオレーション発生!
2247
2248#endif
2249
#define loop(VAR, CNT)
loop構文.
Definition: TnbDef.h:343
動的関数管理関係のヘッダ
ポインタハンドル関係のヘッダ
静的簡易マップ管理関係のヘッダ
文字列情報配列管理関係のヘッダ
経過時間管理関係のヘッダ
[ETC] コピー不可能スーパークラス.
Definition: TnbDef.h:599
動的関数管理クラステンプレート
IMAPI2リザルト管理.
static HRESULT CreateStreamOnFile(LPCTSTR lpszFile, DWORD grfMode, IStream **ppstm)
[作成] ファイルストリーム作成.
CStr GetLastResultString(void) const
[取得] リザルト文字列取得.
bool CheckRes(HRESULT hr) const
[設定] リザルトチェック.
HRESULT GetLastResult(void) const
[取得] リザルトコード取得.
static CStr ToString(HRESULT hr)
[変換] リザルト文字列変換.
CImageMasteringResult(void)
コンストラクタ
ディスクイメージ管理.
size_t GetFileCount(void) const
[取得] 登録済みファイル数取得.
void SetJolietSystem(bool isEnable)
[設定] Jolietモード設定.
void SetListener(IListener *P)
[設定]リスナー登録.
bool AddSourceFile(LPCTSTR lpszName, LPCTSTR lpszImagePath=NULL)
[追加] ファイル追加.
size_t GetSectorSize(bool isXA=false) const
[取得] セクタサイズ取得.
bool SetVolumeName(LPCTSTR lpszVolume)
[設定] ボリューム名設定.
bool SetWorkingDirestory(LPCTSTR lpszPath)
[設定] ワークディレクトリ設定.
bool SetBootImage(LPCTSTR lpszBootFileName)
[設定] Bootイメージ設定.
bool RemoveFile(LPCTSTR lpszImageName)
[削除] ファイル削除.
~CDiscImage(void)
デストラクタ
bool AddSourceDirectory(LPCTSTR lpszPath, LPCTSTR lpszImagePath=NULL)
[追加] ディレクトリ追加.
bool IsValid(void) const
[確認] 有効確認.
CDiscImage(void)
コンストラクタ
size_t GetSectorsCount(void) const
[取得] 登録済みセクタ数取得.
IFileSystemImage * operator->(void) const
[取得] FileSystemImageインターフェース取得.
bool EnumerationFiles(CVectorT< TFileItem > &_items) const
[取得] ファイル一覧.
size_t GetDirectoryCount(void) const
[取得] 登録済みディレクトリ数取得
bool CreateImageFile(LPCTSTR lpszFileName, IMAPI_MEDIA_PHYSICAL_TYPE type=IMAPI_MEDIA_TYPE_CDR)
[作成] イメージファイル作成.
IStream * CreateImageSteam(IMAPI_MEDIA_PHYSICAL_TYPE type=IMAPI_MEDIA_TYPE_CDR) const
[作成] イメージストリーム作成.
CStr GetVolumeName(void) const
[取得] ボリューム名取得.
bool RemoveDirectory(LPCTSTR lpszImagePath)
[削除] ディレクトリ削除.
bool Reset(void)
[設定] 初期化.
virtual LONG GetTotalSectorCount(void) const =0
[取得] 全セクタ数.
virtual LONG GetElapsedTime(void) const =0
[取得] 経過時間.
virtual LONG GetWrittenLba(void) const =0
[取得] 書込み LBA 数.
virtual LONG GetStartLba(void) const =0
[取得] 開始 LBA.
virtual LONG GetWrittenSector(void) const =0
[取得] 書込みセクタ数.
virtual LONG GetRemainingTime(void) const =0
[取得] 残り時間.
virtual LONG GetExpectedTime(void) const =0
[取得] 予想全時間.
bool EnumerationMountPath(CStrVector &_mountPaths) const
[取得] マウントパス取得.
IMAPI_MEDIA_PHYSICAL_TYPE GetTypeOnDisc(void) const
[取得] ディスク種類取得.
bool EnumerationSupportWriteSpeeds(CWordVector &_speeds) const
[取得] サポート書き込み速度一覧.
bool ReadMultiSession(CDiscImage &_diskImage) const
[取得] セッション情報取得.
bool OpenTray(void)
[処理] トレイオープン.
IDiscRecorder2 * operator->(void)
[取得] IDiscRecorder2インターフェース取得.
bool CloseTray(void)
[処理] トレイクローズ.
size_t GetSectorSize(void) const
[取得] セクタサイズ取得.
bool Burn(const CDiscImage &discImage, bool isClose=true)
[書込] 書き込み.
bool IsBlankDisc(void) const
[確認] ブランクディスク確認.
CVectorT< IMAPI_MEDIA_PHYSICAL_TYPE > CTypeVector
ディスクタイプ配列型
bool IsValid(void) const
[確認] 有効確認.
bool Burn(LPCTSTR lpszFileName, bool isClose=true)
[書込] イメージファイル書き込み.
size_t GetTotalSectorsOnDisc(void) const
[取得] ディスク全セクタ数取得.
bool ExistDisc(DWORD time=0) const
[確認] ディスク確認.
size_t GetFreeSectorsOnDisc(void) const
[取得] ディスク空きセクタ数取得.
TInformation GetInformation(void) const
[取得] ドライブ情報情報.
void SetListener(IListener *pListener)
[設定] リスナー設定.
bool IsAppendableDisc(void) const
[確認] 追記可能ディスク確認.
CStr GetTypeStringOnDisc(void) const
[取得] ディスク種類名取得.
bool Erase(bool isFull=false)
[消去] 消去.
bool SetWriteSpeed(int speed=-1, bool isPureCAV=false)
[設定] 速度設定.
CDrive(CDiscRecorderHandle dr, LPCTSTR name)
コンストラクタ.
int GetStatusOnDisc(void) const
[取得] ディスク状態取得.
bool EnumerationSupportedDiscTypes(CTypeVector &_types) const
[取得] 対応ディスクタイプ一覧取得.
CStr GetVolumeOnDisc(void) const
[取得] ディスクボリューム名取得.
CDrive CreateDrive(INDEX index) const
[取得] ドライブ管理クラス取得.
CImageMastering(void)
コンストラクタ
size_t GetDriveCount(void) const
[取得] ドライブ数取得.
CStr GetDriveName(INDEX index) const
[取得] ドライブ名取得.
CPointerHandleBaseT< IDiscFormat2Data *, TImReleasePointerT< IDiscFormat2Data * > > CDiscFormatDataHandle
DiscFormatData ハンドル
static CStr ToString(IMAPI_MEDIA_PHYSICAL_TYPE type)
[取得] ディスク種類文字取得.
CPointerHandleBaseT< IDiscRecorder2 *, TImReleasePointerT< IDiscRecorder2 * > > CDiscRecorderHandle
DiscRecorder ハンドル
CPointerHandleBaseT< IFileSystemImage *, TImReleasePointerT< IFileSystemImage * > > CFileSystemImageHandle
FileSystemImage ハンドル
CPointerHandleBaseT< IDiscMaster2 *, TImReleasePointerT< IDiscMaster2 * > > CDiscMasterHandle
DiscMaster ハンドル
bool IsSupported(void) const
[確認] サポート確認.
CPointerHandleBaseT< IDiscFormat2Erase *, TImReleasePointerT< IDiscFormat2Erase * > > CDiscFormatEraseHandle
DiscFormatErase ハンドル
NULLポインタ例外
Definition: TnbException.h:172
ポインタハンドルテンプレートベースクラス
bool IsNull(void) const
[確認] NULLチェック
void Null(void)
[設定] 開放.
静的簡易マップクラス.
Definition: TnbStaticMap.h:52
static VAL Find(const TYP &key, const TYPS &ts, const VAL &def=VAL())
[検索] 値検索
Definition: TnbStaticMap.h:90
INT_PTR ReverseFindOneOf(const TYP *lpsz) const
[確認] 検索(後ろから)
Definition: TnbStr.h:621
bool IsEmpty(void) const
[確認] 空チェック
Definition: TnbStr.h:528
CStrT Left(size_t iSize) const
[作成] 範囲取得.
Definition: TnbStr.h:801
void ReleaseBuffer(void)
[操作] 割り当てたバッファを開放.
Definition: TnbStr.h:954
CStrT & TrimRight(TYP t=' ')
[処理] 末尾から文字をトリム.
Definition: TnbStr.h:990
CStrT & Trim(TYP t=' ')
[処理] 両端から文字をトリム.
Definition: TnbStr.h:1012
CStrT Mid(INDEX iOffset, size_t iSize=INVALID_SIZE) const
[作成] 範囲取得.
Definition: TnbStr.h:766
TYP * GetBuffer(size_t iLength=0)
[操作] 書き込みバッファ要求.
Definition: TnbStr.h:914
経過時間管理クラス
Definition: TnbTickCount.h:57
bool IsPassed(DWORD dwTime) const
[確認] 経過確認.
Definition: TnbTickCount.h:114
void OnCatch(void) const
[表示] 内容表示
Definition: TnbException.h:69
配列型情報管理テンプレート
Definition: TnbVector.h:75
virtual size_t GetSize(void) const
[取得] サイズ取得
Definition: TnbVector.h:368
virtual bool RemoveAll(void)
[削除] 空化
Definition: TnbVector.h:565
virtual INDEX Add(const TYP &t)
[追加] 要素一つ追加.
Definition: TnbVector.h:383
IMAPI_MEDIA_PHYSICAL_TYPE
ディスクタイプ.
IMAPI_FORMAT2_DATA_WRITE_ACTION
書き込みアクション.
IMAPI_FORMAT2_DATA_MEDIA_STATE
ディスク状態.
@ IMAPI_MEDIA_TYPE_BDRE
BD-RE
@ IMAPI_MEDIA_TYPE_DVDPLUSR
DVD+R
@ IMAPI_MEDIA_TYPE_DVDPLUSR_DUALLAYER
DVD+R DL
@ IMAPI_MEDIA_TYPE_DVDDASHRW
DVD-RW
@ IMAPI_MEDIA_TYPE_HDDVDRAM
HD DVD-RAM
@ IMAPI_MEDIA_TYPE_BDROM
BD-ROM
@ IMAPI_MEDIA_TYPE_DISK
DISK
@ IMAPI_MEDIA_TYPE_CDRW
CD-RW
@ IMAPI_MEDIA_TYPE_CDROM
CD-ROM
@ IMAPI_MEDIA_TYPE_UNKNOWN
不明,
@ IMAPI_MEDIA_TYPE_DVDRAM
DVD-RAM
@ IMAPI_MEDIA_TYPE_HDDVDR
HD DVD-R
@ IMAPI_MEDIA_TYPE_HDDVDROM
HD DVD-ROM
@ IMAPI_MEDIA_TYPE_DVDROM
DVD-ROM
@ IMAPI_MEDIA_TYPE_CDR
CD-R
@ IMAPI_MEDIA_TYPE_DVDPLUSRW
DVD+RW
@ IMAPI_MEDIA_TYPE_DVDDASHR
DVD-R
@ IMAPI_MEDIA_TYPE_DVDPLUSRW_DUALLAYER
DVD+RW DL
@ IMAPI_MEDIA_TYPE_DVDDASHR_DUALLAYER
DVD-R DL
@ IMAPI_MEDIA_TYPE_BDR
BD-R
@ IMAPI_FORMAT2_DATA_WRITE_ACTION_VALIDATING_MEDIA
ディスク確認中
@ IMAPI_FORMAT2_DATA_WRITE_ACTION_FORMATTING_MEDIA
ディスクフォーマット中
@ IMAPI_FORMAT2_DATA_WRITE_ACTION_FINALIZATION
ファイナライズ中
@ IMAPI_FORMAT2_DATA_WRITE_ACTION_INITIALIZING_HARDWARE
初期化中
@ IMAPI_FORMAT2_DATA_WRITE_ACTION_WRITING_DATA
データ書き込み中
@ IMAPI_FORMAT2_DATA_WRITE_ACTION_CALIBRATING_POWER
パワー調整中
@ IMAPI_FORMAT2_DATA_WRITE_ACTION_COMPLETED
完了
@ IMAPI_FORMAT2_DATA_MEDIA_STATE_FINALIZED
ファイナライズ済み
@ IMAPI_FORMAT2_DATA_MEDIA_STATE_APPENDABLE
追記可能
@ IMAPI_FORMAT2_DATA_MEDIA_STATE_WRITE_PROTECTED
書き込み禁止
@ IMAPI_FORMAT2_DATA_MEDIA_STATE_FINAL_SESSION
最後のセクション
@ IMAPI_FORMAT2_DATA_MEDIA_STATE_NON_EMPTY_SESSION
セクション有り
@ IMAPI_FORMAT2_DATA_MEDIA_STATE_UNSUPPORTED_MEDIA
未サポートディスク
@ IMAPI_FORMAT2_DATA_MEDIA_STATE_DAMAGED
ダメージ
@ IMAPI_FORMAT2_DATA_MEDIA_STATE_BLANK
ブランク
@ IMAPI_FORMAT2_DATA_MEDIA_STATE_OVERWRITE_ONLY
上書きのみ
@ IMAPI_FORMAT2_DATA_MEDIA_STATE_ERASE_REQUIRED
消去必要あり
TNB::CStrT< TCHAR > CStr
文字列クラス
Definition: TnbStr.h:1785
TNB Library
Definition: TnbDoxyTitle.txt:2
ディスクイメージ管理リスナー.
virtual void OnDiscImageAdded(LPCTSTR file, LONG copiedSectors, LONG totalSectors)=0
[通知] 進捗通知.
virtual ~IListener(void)
デストラクタ
bool isDirectory
ディレクトリフラグ. true ならディレクトリ、 false ならファイル
CStr name
ファイル/ディレクトリ名
ドライブ管理リスナー.
virtual ~IListener(void)
デストラクタ
virtual void OnDriveErrorResult(HRESULT hr)=0
[通知] エラー発生通知.
virtual void OnDriveEraseEvent(const CProgressData &pd)=0
[通知] 消去進捗通知.
virtual bool OnDriveWriteEvent(const CProgressData &pd, IMAPI_FORMAT2_DATA_WRITE_ACTION action)=0
[通知] 書き込み進捗通知.
CStr productRevision
プロダクトリビジョン