eraseMedium.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. #include "./eraseMedium.h"
  2. #include "api.h"
  3. #include <api/service/waservicefactory.h>
  4. EraseMedium::EraseMedium(void)
  5. {
  6. primoSDK=0;
  7. waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(obj_primo::getServiceGuid());
  8. if (sf) primoSDK = reinterpret_cast<obj_primo *>(sf->getInterface());
  9. hThread = NULL;
  10. evntStop = NULL;
  11. evntThreadExit = NULL;
  12. errorCode = PRIMOSDK_OK;
  13. notifyCB = NULL;
  14. }
  15. EraseMedium::~EraseMedium(void)
  16. {
  17. Stop();
  18. waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(obj_primo::getServiceGuid());
  19. if (sf) sf->releaseInterface(primoSDK);
  20. }
  21. DWORD EraseMedium::SetEject(DWORD eject)
  22. {
  23. DWORD tmp = this->eject;
  24. this->eject = eject;
  25. return tmp;
  26. }
  27. DWORD EraseMedium::Start(DWORD drive, DWORD eraseMode, ERASEMEDIUMCALLBACK notifyCB, void *userParam, int block)
  28. {
  29. this->notifyCB = notifyCB;
  30. this->userparam = userParam;
  31. OnNotify(ERASEMEDIUM_READY, PRIMOSDK_OK);
  32. if (hThread)
  33. {
  34. OnNotify(ERASEMEDIUM_ALREADYSTARTED, PRIMOSDK_OK);
  35. return PRIMOSDK_OK;
  36. }
  37. OnNotify(ERASEMEDIUM_INITIALIZING, PRIMOSDK_OK);
  38. if (!primoSDK)
  39. {
  40. OnNotify(ERASEMEDIUM_UNABLEINITPRIMO, PRIMOSDK_NOTLOADED);
  41. return errorCode;
  42. }
  43. // check unit
  44. errorCode = primoSDK->UnitReady(&drive);
  45. if (PRIMOSDK_OK != errorCode)
  46. {
  47. OnNotify(ERASEMEDIUM_DEVICENOTREADY, errorCode);
  48. return errorCode;
  49. }
  50. // check that disc is erasable
  51. DWORD erasable;
  52. errorCode = primoSDK->DiscInfoEx(&drive, 0, NULL, NULL, &erasable, NULL, NULL, NULL);
  53. if (PRIMOSDK_OK != errorCode)
  54. {
  55. OnNotify(ERASEMEDIUM_DISCINFOERROR, errorCode);
  56. return errorCode;
  57. }
  58. if (!erasable)
  59. {
  60. OnNotify(ERASEMEDIUM_DISCNOTERASABLE, PRIMOSDK_OK);
  61. return errorCode;
  62. }
  63. // begin burn
  64. errorCode = BeginBurn(primoSDK, drive, &bs);
  65. if (PRIMOSDK_OK != errorCode)
  66. {
  67. OnNotify(ERASEMEDIUM_BEGINBURNFAILED, errorCode);
  68. return errorCode;
  69. }
  70. // erasing
  71. errorCode = primoSDK->EraseMedium(&bs.drive, eraseMode);
  72. if(PRIMOSDK_OK == errorCode)
  73. {
  74. OnNotify(ERASEMEDIUM_ERASING, PRIMOSDK_OK);
  75. evntStop = CreateEvent(NULL, FALSE, FALSE, NULL);
  76. if (block) errorCode = StatusThread(this);
  77. else
  78. {
  79. DWORD threadID;
  80. hThread = CreateThread(NULL, 0, StatusThread, (LPVOID)this, NULL, &threadID);
  81. }
  82. }
  83. else
  84. {
  85. OnNotify(ERASEMEDIUM_ERASEMEDIUMFAILED, errorCode);
  86. }
  87. return errorCode;
  88. }
  89. void EraseMedium::Stop(void)
  90. {
  91. if (hThread && evntStop)
  92. {
  93. DWORD waitResult;
  94. MSG msg;
  95. if (!evntThreadExit) evntThreadExit = CreateEvent(NULL, FALSE, FALSE, NULL);
  96. SetEvent(evntStop);
  97. while(WAIT_TIMEOUT == (waitResult = WaitForSingleObject(evntThreadExit, 10)))
  98. {
  99. if (!evntStop) break;
  100. while(PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE))
  101. {
  102. TranslateMessage(&msg);
  103. DispatchMessageW(&msg);
  104. }
  105. }
  106. CloseHandle(evntThreadExit);
  107. evntThreadExit = NULL;
  108. }
  109. }
  110. DWORD EraseMedium::OnNotify(DWORD eraseCode, DWORD primoCode)
  111. {
  112. return (notifyCB) ? notifyCB(this, userparam, eraseCode, primoCode) : ERASEMEDIUM_CONTINUE;
  113. }
  114. DWORD WINAPI EraseMedium::StatusThread(void* parameter)
  115. {
  116. EraseMedium *object = (EraseMedium*)parameter;
  117. DWORD current, total, waitResult;
  118. object->errorCode = PRIMOSDK_RUNNING;
  119. while(PRIMOSDK_RUNNING == object->errorCode && WAIT_TIMEOUT == (waitResult = WaitForSingleObject(object->evntStop, 1000)))
  120. {
  121. if (ERASEMEDIUM_STOP == object->OnNotify(ERASEMEDIUM_ERASING, PRIMOSDK_OK)) SetEvent(object->evntStop);
  122. object->errorCode = object->primoSDK->RunningStatus(PRIMOSDK_GETSTATUS, &current, &total);
  123. }
  124. if (WAIT_OBJECT_0 == waitResult)
  125. { // aborting
  126. object->OnNotify(ERASEMEDIUM_CANCELING, PRIMOSDK_OK);
  127. DWORD test = object->primoSDK->RunningStatus(PRIMOSDK_ABORT, &current, &total);
  128. do
  129. {
  130. Sleep(1000);
  131. object->errorCode = object->primoSDK->RunningStatus(PRIMOSDK_GETSTATUS, &current, &total);
  132. }while(PRIMOSDK_RUNNING == object->errorCode);
  133. }
  134. if (PRIMOSDK_OK != object->errorCode && PRIMOSDK_USERABORT != object->errorCode)
  135. {
  136. object->OnNotify(ERASEMEDIUM_ERASEMEDIUMFAILED, object->errorCode);
  137. }
  138. // check unit status
  139. DWORD cmd, sense, asc, ascq;
  140. object->errorCode = object->primoSDK->UnitStatus(&object->bs.drive, &cmd, &sense, &asc, &ascq);
  141. if (object->errorCode != PRIMOSDK_OK)
  142. {
  143. object->OnNotify(ERASEMEDIUM_ERASEMEDIUMFAILED, object->errorCode);
  144. }
  145. // end burn
  146. object->bs.eject = object->eject;
  147. object->OnNotify(ERASEMEDIUM_FINISHING, PRIMOSDK_OK);
  148. DWORD errorCode2 = EndBurn(&object->bs);
  149. if (PRIMOSDK_OK != errorCode2)
  150. {
  151. object->OnNotify(ERASEMEDIUM_ENDBURNFAILED, object->errorCode);
  152. }
  153. if (PRIMOSDK_OK == object->errorCode) object->errorCode = errorCode2;
  154. object->primoSDK->Release();
  155. CloseHandle(object->hThread);
  156. object->hThread = NULL;
  157. CloseHandle(object->evntStop);
  158. object->evntStop = NULL;
  159. object->OnNotify( (PRIMOSDK_USERABORT == object->errorCode) ? ERASEMEDIUM_ABORTED : ERASEMEDIUM_COMPLETED, object->errorCode);
  160. if (object->evntThreadExit) SetEvent(object->evntThreadExit);
  161. return object->errorCode;
  162. }