DataBurner.cpp 3.1 KB

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