ISOCreator.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. #include "ISOCreator.h"
  2. #include <malloc.h>
  3. #include "../nu/AutoChar.h"
  4. #include "ifc_burner_writecallback.h"
  5. #include <strsafe.h>
  6. ISOCreator::ISOCreator(obj_primo *_primo) : BurnerCommon(_primo)
  7. {
  8. }
  9. ISOCreator::~ISOCreator()
  10. {
  11. if (primo)
  12. primo->CloseImage();
  13. }
  14. int ISOCreator::Open(const wchar_t *volumeName, int format, int media)
  15. {
  16. if (!primo)
  17. return 1;
  18. DWORD units=0xFFFFFFFF;
  19. DWORD ret = primo->NewImageWCS(
  20. &units,
  21. (PWORD)volumeName,
  22. 0, // no track session # needed, I don't think
  23. PRIMOSDK_ORIGDATE | format | media,
  24. 0, // don't think we need a swap file for ISO
  25. 0 // probably don't need a swap location either, we'll see ...
  26. ); // TODO: validate format and media
  27. if (ret != PRIMOSDK_OK)
  28. return 1;
  29. return 0;
  30. }
  31. // TODO: check AddFolderWCS for return values
  32. static void createDirForFileW(obj_primo *primo, const wchar_t *str)
  33. {
  34. const wchar_t *p = str;
  35. if ((p[0] ==L'\\' || p[0] ==L'/') && (p[1] ==L'\\' || p[1] ==L'/'))
  36. {
  37. p += 2;
  38. while (*p && *p !=L'\\' && *p !=L'/') p++;
  39. if (!*p) return ;
  40. p++;
  41. while (*p && *p !=L'\\' && *p !=L'/') p++;
  42. }
  43. else
  44. {
  45. while (*p && *p !=L'\\' && *p !=L'/') p++;
  46. }
  47. while (*p)
  48. {
  49. while (*p !=L'\\' && *p !=L'/' && *p) p = CharNextW(p);
  50. if (*p)
  51. {
  52. size_t copySize = (p-str+1)*sizeof(wchar_t);
  53. wchar_t *copy = (wchar_t *)alloca(copySize);
  54. StringCbCopy(copy, copySize, str);
  55. primo->AddFolderWCS(copy);
  56. p++;
  57. }
  58. }
  59. }
  60. int ISOCreator::AddFile(const wchar_t *source, const wchar_t *destination)
  61. {
  62. createDirForFileW(primo, destination);
  63. DWORD ret = primo->AddFileWCS((PWORD)destination, (PWORD)source);
  64. if (ret != PRIMOSDK_OK)
  65. return 1;
  66. return 0;
  67. }
  68. int ISOCreator::AddFolder(const wchar_t *folder)
  69. {
  70. createDirForFileW(primo, folder);
  71. DWORD ret = primo->AddFolderWCS(folder); // add again in case they didn't terminate with a slash
  72. if (ret != PRIMOSDK_OK)
  73. return 1;
  74. return 0;
  75. }
  76. int ISOCreator::Write(const wchar_t *destination, ifc_burner_writecallback *callback)
  77. {
  78. DWORD size=0;
  79. DWORD ret = primo->SaveImage((PBYTE)(char *)AutoChar(destination), &size);
  80. if (ret != PRIMOSDK_OK)
  81. return 1;
  82. while (1)
  83. {
  84. DWORD cursec = 0, totsec = 0;
  85. ret = primo->RunningStatus(PRIMOSDK_GETSTATUS, &cursec, &totsec);
  86. if (ret == PRIMOSDK_RUNNING)
  87. {
  88. if (callback)
  89. {
  90. int abort = callback->OnStatus(cursec, totsec);
  91. if (abort)
  92. {
  93. ret = primo->RunningStatus(PRIMOSDK_ABORT, 0, 0);
  94. callback = 0; // cheap way to prevent making further callbacks
  95. }
  96. }
  97. WaitForSingleObject(triggerEvent, 500);
  98. }
  99. else if (ret == PRIMOSDK_OK)
  100. {
  101. if (callback)
  102. callback->Finished();
  103. break;
  104. }
  105. else
  106. break;
  107. }
  108. if (ret != PRIMOSDK_OK)
  109. return 1;
  110. return 0;
  111. }
  112. #define CBCLASS ISOCreator
  113. START_DISPATCH;
  114. CB(ISOCREATOR_OPEN, Open)
  115. CB(ISOCREATOR_ADDFILE, AddFile)
  116. CB(ISOCREATOR_ADDFOLDER, AddFolder)
  117. CB(ISOCREATOR_WRITE, Write)
  118. VCB(ISOCREATOR_FORCECALLBACK, ForceCallback)
  119. END_DISPATCH;
  120. #undef CBCLASS