NeroISODemo.h 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. /******************************************************************************
  2. |* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  3. |* ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  4. |* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  5. |* PARTICULAR PURPOSE.
  6. |*
  7. |* Copyright 1995-2005 Nero AG. All Rights Reserved.
  8. |*-----------------------------------------------------------------------------
  9. |* NeroSDK / Samples
  10. |*
  11. |* PROGRAM: NeroISODemo.cpp
  12. |*
  13. |* PURPOSE: This demo implementation supports storing of files
  14. |* or complete directory trees in the root directory
  15. |* of an ISO track. Each subdirectory is scanned while
  16. |* the Nero API builds its internal tree, so we don't
  17. |* have to build a tree ourselves.
  18. |*
  19. |* However, the implementation of CNeroIsoHandle becomes
  20. |* very inefficient this way because each handle contains
  21. |* the full path. It would be better for trees with many
  22. |* files to use a tree and construct the full filename
  23. |* from going back in the tree to the root.
  24. ******************************************************************************/
  25. #include "NeroIsoTrack.h"
  26. #include <string>
  27. #include <list>
  28. #include <errno.h>
  29. using namespace std;
  30. #include <sys/types.h>
  31. #include <sys/stat.h>
  32. #include <io.h>
  33. extern void Exit (int ret);
  34. //
  35. // This demo implementation supports storing of files
  36. // or complete directory trees in the root directory
  37. // of an ISO track. Each subdirectory is scanned while
  38. // the Nero API builds its internal tree, so we don't
  39. // have to build a tree ourselves.
  40. //
  41. // However, the implementation of CNeroIsoHandle becomes
  42. // very inefficient this way because each handle contains
  43. // the full path. It would be better for trees with many
  44. // files to use a tree and construct the full filename
  45. // from going back in the tree to the root.
  46. //
  47. //
  48. // Reading is done with ordinary FILEs.
  49. //
  50. class CDemoReadCallback : public CNeroDataCallback
  51. {
  52. FILE *m_pFile;
  53. public:
  54. CDemoReadCallback (string sFullName) // open file
  55. {
  56. m_pFile = fopen (sFullName.c_str (), "rb");
  57. }
  58. ~CDemoReadCallback () // delete file
  59. {
  60. if (m_pFile) {
  61. fclose (m_pFile);
  62. }
  63. }
  64. virtual DWORD IOCallback (BYTE *pBuffer, DWORD dwLen) // read from file
  65. {
  66. int read = 0;
  67. if (m_pFile) {
  68. read = fread (pBuffer, 1, dwLen, m_pFile);
  69. if (read < 0) {
  70. perror ("fread");
  71. }
  72. }
  73. return read;
  74. }
  75. virtual BOOL EOFCallback () { return m_pFile && feof (m_pFile); } // calls map to standard functions directly
  76. virtual BOOL ErrorCallback () {
  77. /* FIXME: no implementation for ferror() in crtdll.
  78. * so no errors occur here :-) */
  79. /*return m_pFile && ferror (m_pFile);*/
  80. return 0;
  81. }
  82. BOOL Okay () { return m_pFile != NULL; } // initialized okay?
  83. };
  84. //
  85. // This callback is created by this handle from the full name
  86. // store in it:
  87. //
  88. class CDemoIsoHandle : public CNeroIsoHandle
  89. {
  90. string m_sFullName;
  91. public:
  92. CDemoIsoHandle (string sFullName) : m_sFullName (sFullName) { }
  93. virtual CNeroIsoHandle *Clone () { return new CDemoIsoHandle (m_sFullName); }
  94. virtual int GetFileName (char *strBuffer, UINT nBufferSize)
  95. {
  96. // you can choose if files are read by Nero API or via callback
  97. #if 1
  98. // directly by API: give the name to the API
  99. if (nBufferSize) {
  100. strncpy (strBuffer, m_sFullName.c_str (), nBufferSize);
  101. strBuffer[nBufferSize - 1] = 0;
  102. }
  103. return m_sFullName.length ();
  104. #else
  105. // via callback: refuse to give away the name
  106. return 0;
  107. #endif
  108. }
  109. CNeroDataCallback *Open ()
  110. {
  111. CDemoReadCallback *pCallback = new CDemoReadCallback (m_sFullName);
  112. // opening it may have failed
  113. if (pCallback && !pCallback->Okay ()) {
  114. delete pCallback;
  115. pCallback = NULL;
  116. }
  117. return pCallback;
  118. }
  119. };
  120. //
  121. // reads the file/directory infos and gives them to the API
  122. //
  123. class CDemoIsoEntry : public CNeroIsoEntry
  124. {
  125. string m_sFullName; // name including full path
  126. string m_sFileName; // the name within the current directory
  127. __int64 m_i64Size; // < 0 for directory, otherwise size of file
  128. time_t fileTime;
  129. public:
  130. CDemoIsoEntry () { m_i64Size = -1; }
  131. CDemoIsoEntry (const char *strFullName) { this->SetName (strFullName); }
  132. void SetName (const char *strFullName) // read infos and remember everything
  133. {
  134. struct _stati64 buf;
  135. if (_stati64 (strFullName,
  136. &buf)) {
  137. perror (strFullName);
  138. Exit (10);
  139. }
  140. m_sFullName = strFullName;
  141. // find last occurance of either "/" or "\"
  142. const char *name = strrchr (strFullName, '/');
  143. const char *tmp = strrchr (strFullName, '\\');
  144. if (!name) {
  145. name = tmp;
  146. } else if (tmp) {
  147. if (tmp > name) {
  148. name = tmp;
  149. }
  150. }
  151. if (!name || !*name) {
  152. name = strFullName;
  153. } else {
  154. name++;
  155. }
  156. m_sFileName = name;
  157. m_i64Size = (buf.st_mode & _S_IFDIR) ? -1 : buf.st_size;
  158. fileTime=buf.st_mtime;
  159. }
  160. virtual CNeroIsoIterator * CreateDirectoryIterator(); // implemented below because we have to define CDemoIsoIterator first
  161. virtual const char * GetName () { return m_sFileName.c_str (); }
  162. virtual __int64 GetLength () { return m_i64Size; }
  163. virtual BOOL GetEntryTime(tm *tm)
  164. {
  165. struct tm *time=localtime(&fileTime);
  166. if (time==NULL)
  167. return FALSE;
  168. else
  169. {
  170. *tm=*time;
  171. return TRUE;
  172. }
  173. }
  174. virtual CNeroIsoHandle * CreateHandle () { return new CDemoIsoHandle (m_sFullName); }
  175. };
  176. //
  177. // Our iterator implements both interfaces and thus returns a pointer
  178. // to itself when asked for the current entry (but only while it really
  179. // has information about a file).
  180. //
  181. class CDemoIsoIterator : public CNeroIsoIterator, public CDemoIsoEntry
  182. {
  183. long m_lHandle; // for searching with findfirst/next/close()
  184. _finddata_t m_FindData; // the result of last call to findfirst/next()
  185. string m_sPath; // the directory we are searching in
  186. BOOL m_bValid; // we currently have valid information
  187. // The information about the current entry are stored in the base
  188. // class CDemoIsoEntry. FindData2Entry() sets them there:
  189. void FindData2Entry ()
  190. {
  191. // skip current and parent directory entries
  192. while (!strcmp (m_FindData.name, ".") || !strcmp (m_FindData.name, "..")) {
  193. this->Next ();
  194. if (!m_bValid) {
  195. // found end of directory, give up
  196. return;
  197. }
  198. }
  199. // build name
  200. string sFullName = m_sPath;
  201. sFullName += "\\";
  202. sFullName += m_FindData.name;
  203. // ask base class to analyze this name
  204. this->SetName (sFullName.c_str ());
  205. // base class would have quit if there was a problem,
  206. // so now we are fine
  207. m_bValid = TRUE;
  208. }
  209. public:
  210. CDemoIsoIterator (const char *strPath) : m_sPath (strPath), m_bValid (FALSE)
  211. {
  212. // start searching this directory for any file
  213. string pattern = strPath;
  214. pattern += "\\*";
  215. m_lHandle = _findfirst (pattern.c_str (), &m_FindData);
  216. if (m_lHandle == -1) {
  217. perror (strPath);
  218. Exit (10);
  219. }
  220. // copy informations for first entry
  221. this->FindData2Entry ();
  222. }
  223. ~CDemoIsoIterator () { _findclose (m_lHandle); }
  224. virtual CNeroIsoEntry *GetCurrentEntry () { return m_bValid ? this : NULL; } // our base class _is_ the current entry if m_bValid is TRUE
  225. virtual void Next ()
  226. {
  227. // invalidate ourself
  228. m_bValid = FALSE;
  229. if (_findnext (m_lHandle, &m_FindData) == -1) {
  230. // quit unless the error indicates the end of the directory
  231. if (errno != ENOENT) {
  232. perror ("findnext");
  233. Exit (10);
  234. }
  235. } else {
  236. // copy new infos
  237. this->FindData2Entry ();
  238. }
  239. }
  240. };
  241. // now that CDemoIsoIterator is defined we can implement this function
  242. CNeroIsoIterator * CDemoIsoEntry::CreateDirectoryIterator()
  243. {
  244. return new CDemoIsoIterator (m_sFullName.c_str ());
  245. };
  246. //
  247. // The root directory is implemented by a seperate class
  248. // which has a list of entries that are traversed by
  249. // a special iterator and also provides the other
  250. // ISO track options.
  251. //
  252. class CDemoIsoTrack : public CNeroIsoTrack
  253. {
  254. string m_sVolumeName; // ISO volume name
  255. typedef list <CDemoIsoEntry> DemoList_t; // type definition for storing them and
  256. DemoList_t m_Entries; // all entries in the root directory themselves
  257. BOOL m_bUseJoliet;
  258. BOOL m_bUseMode2;
  259. BOOL m_bBurnISO;
  260. BOOL m_bBurnUDF;
  261. BOOL m_bReallocDVDVideoFiles;
  262. class CDemoRootIterator : public CNeroIsoIterator // traverses any STL collection of CDemoIsoEntries
  263. {
  264. DemoList_t::iterator m_End; // STL end marker
  265. DemoList_t::iterator m_Current; // STL iterator
  266. public:
  267. CDemoRootIterator (DemoList_t &List) : m_End (List.end ()), m_Current (List.begin ()) { }
  268. virtual CNeroIsoEntry *GetCurrentEntry () { return m_Current != m_End ? &(*m_Current) : NULL; }
  269. virtual void Next () { m_Current++; }
  270. };
  271. public:
  272. CDemoIsoTrack ()
  273. {
  274. m_bUseJoliet = TRUE;
  275. m_bUseMode2 = FALSE;
  276. m_bBurnISO = TRUE;
  277. m_bBurnUDF = FALSE;
  278. m_bReallocDVDVideoFiles = FALSE;
  279. }
  280. // modify settings for ISO track
  281. void SetVolumeName (const char *strVolumeName) { m_sVolumeName = strVolumeName; }
  282. void SetJoliet (BOOL bUseJoliet) { m_bUseJoliet = bUseJoliet; }
  283. void SetMode2 (BOOL bUseMode2) { m_bUseMode2 = bUseMode2; }
  284. void SetISO(BOOL b) { m_bBurnISO = b;}
  285. void SetUDF(BOOL b) { m_bBurnUDF = b;}
  286. void SetReallocDVDVideoFiles(BOOL b) { m_bReallocDVDVideoFiles = b;}
  287. // return settings
  288. virtual const char * GetName () { return m_sVolumeName.c_str (); }
  289. // add a file/directory - the base name is kept in the ISO track,
  290. // but the path is discarded, i.e. "C:\Dir1\Dir2" will be stored
  291. // as ":\Dir2" on the disc.
  292. void AddEntry (const char *strEntryName) { m_Entries.insert (m_Entries.end(), CDemoIsoEntry (strEntryName)); }
  293. // return new iterator
  294. virtual CNeroIsoIterator * CreateDirectoryIterator () { return new CDemoRootIterator (m_Entries); }
  295. virtual DWORD BurnOptions()
  296. {
  297. return (m_bUseJoliet ? NCITEF_USE_JOLIET : 0)
  298. |(m_bUseMode2 ? NCITEF_USE_MODE2 : 0)
  299. |(m_bBurnISO ? NCITEF_CREATE_ISO_FS : 0)
  300. |(m_bBurnUDF ? NCITEF_CREATE_UDF_FS : 0)
  301. |(m_bReallocDVDVideoFiles ? NCITEF_DVDVIDEO_REALLOC : 0);
  302. }
  303. };