aboutsummaryrefslogtreecommitdiff
path: root/Src/burnlib/eraseMedium.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Src/burnlib/eraseMedium.cpp')
-rw-r--r--Src/burnlib/eraseMedium.cpp183
1 files changed, 183 insertions, 0 deletions
diff --git a/Src/burnlib/eraseMedium.cpp b/Src/burnlib/eraseMedium.cpp
new file mode 100644
index 00000000..1ce2f5f4
--- /dev/null
+++ b/Src/burnlib/eraseMedium.cpp
@@ -0,0 +1,183 @@
+#include "./eraseMedium.h"
+#include "api.h"
+#include <api/service/waservicefactory.h>
+
+EraseMedium::EraseMedium(void)
+{
+ primoSDK=0;
+ waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(obj_primo::getServiceGuid());
+ if (sf) primoSDK = reinterpret_cast<obj_primo *>(sf->getInterface());
+
+ hThread = NULL;
+ evntStop = NULL;
+ evntThreadExit = NULL;
+ errorCode = PRIMOSDK_OK;
+ notifyCB = NULL;
+}
+
+EraseMedium::~EraseMedium(void)
+{
+ Stop();
+
+ waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(obj_primo::getServiceGuid());
+ if (sf) sf->releaseInterface(primoSDK);
+}
+
+DWORD EraseMedium::SetEject(DWORD eject)
+{
+ DWORD tmp = this->eject;
+ this->eject = eject;
+ return tmp;
+}
+
+DWORD EraseMedium::Start(DWORD drive, DWORD eraseMode, ERASEMEDIUMCALLBACK notifyCB, void *userParam, int block)
+{
+ this->notifyCB = notifyCB;
+ this->userparam = userParam;
+ OnNotify(ERASEMEDIUM_READY, PRIMOSDK_OK);
+ if (hThread)
+ {
+ OnNotify(ERASEMEDIUM_ALREADYSTARTED, PRIMOSDK_OK);
+ return PRIMOSDK_OK;
+ }
+
+ OnNotify(ERASEMEDIUM_INITIALIZING, PRIMOSDK_OK);
+
+ if (!primoSDK)
+ {
+ OnNotify(ERASEMEDIUM_UNABLEINITPRIMO, PRIMOSDK_NOTLOADED);
+ return errorCode;
+ }
+
+ // check unit
+ errorCode = primoSDK->UnitReady(&drive);
+ if (PRIMOSDK_OK != errorCode)
+ {
+ OnNotify(ERASEMEDIUM_DEVICENOTREADY, errorCode);
+ return errorCode;
+ }
+
+ // check that disc is erasable
+ DWORD erasable;
+ errorCode = primoSDK->DiscInfoEx(&drive, 0, NULL, NULL, &erasable, NULL, NULL, NULL);
+ if (PRIMOSDK_OK != errorCode)
+ {
+ OnNotify(ERASEMEDIUM_DISCINFOERROR, errorCode);
+ return errorCode;
+ }
+ if (!erasable)
+ {
+ OnNotify(ERASEMEDIUM_DISCNOTERASABLE, PRIMOSDK_OK);
+ return errorCode;
+ }
+
+ // begin burn
+ errorCode = BeginBurn(primoSDK, drive, &bs);
+ if (PRIMOSDK_OK != errorCode)
+ {
+ OnNotify(ERASEMEDIUM_BEGINBURNFAILED, errorCode);
+ return errorCode;
+ }
+
+ // erasing
+ errorCode = primoSDK->EraseMedium(&bs.drive, eraseMode);
+ if(PRIMOSDK_OK == errorCode)
+ {
+ OnNotify(ERASEMEDIUM_ERASING, PRIMOSDK_OK);
+ evntStop = CreateEvent(NULL, FALSE, FALSE, NULL);
+ if (block) errorCode = StatusThread(this);
+ else
+ {
+ DWORD threadID;
+ hThread = CreateThread(NULL, 0, StatusThread, (LPVOID)this, NULL, &threadID);
+ }
+ }
+ else
+ {
+ OnNotify(ERASEMEDIUM_ERASEMEDIUMFAILED, errorCode);
+ }
+ return errorCode;
+
+}
+void EraseMedium::Stop(void)
+{
+
+ if (hThread && evntStop)
+ {
+ DWORD waitResult;
+ MSG msg;
+ if (!evntThreadExit) evntThreadExit = CreateEvent(NULL, FALSE, FALSE, NULL);
+ SetEvent(evntStop);
+
+ while(WAIT_TIMEOUT == (waitResult = WaitForSingleObject(evntThreadExit, 10)))
+ {
+ if (!evntStop) break;
+ while(PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE))
+ {
+ TranslateMessage(&msg);
+ DispatchMessageW(&msg);
+ }
+ }
+ CloseHandle(evntThreadExit);
+ evntThreadExit = NULL;
+ }
+}
+
+
+DWORD EraseMedium::OnNotify(DWORD eraseCode, DWORD primoCode)
+{
+ return (notifyCB) ? notifyCB(this, userparam, eraseCode, primoCode) : ERASEMEDIUM_CONTINUE;
+}
+
+DWORD WINAPI EraseMedium::StatusThread(void* parameter)
+{
+ EraseMedium *object = (EraseMedium*)parameter;
+ DWORD current, total, waitResult;
+ object->errorCode = PRIMOSDK_RUNNING;
+ while(PRIMOSDK_RUNNING == object->errorCode && WAIT_TIMEOUT == (waitResult = WaitForSingleObject(object->evntStop, 1000)))
+ {
+ if (ERASEMEDIUM_STOP == object->OnNotify(ERASEMEDIUM_ERASING, PRIMOSDK_OK)) SetEvent(object->evntStop);
+ object->errorCode = object->primoSDK->RunningStatus(PRIMOSDK_GETSTATUS, &current, &total);
+ }
+ if (WAIT_OBJECT_0 == waitResult)
+ { // aborting
+ object->OnNotify(ERASEMEDIUM_CANCELING, PRIMOSDK_OK);
+ DWORD test = object->primoSDK->RunningStatus(PRIMOSDK_ABORT, &current, &total);
+ do
+ {
+ Sleep(1000);
+ object->errorCode = object->primoSDK->RunningStatus(PRIMOSDK_GETSTATUS, &current, &total);
+ }while(PRIMOSDK_RUNNING == object->errorCode);
+ }
+
+ if (PRIMOSDK_OK != object->errorCode && PRIMOSDK_USERABORT != object->errorCode)
+ {
+ object->OnNotify(ERASEMEDIUM_ERASEMEDIUMFAILED, object->errorCode);
+ }
+ // check unit status
+ DWORD cmd, sense, asc, ascq;
+ object->errorCode = object->primoSDK->UnitStatus(&object->bs.drive, &cmd, &sense, &asc, &ascq);
+ if (object->errorCode != PRIMOSDK_OK)
+ {
+ object->OnNotify(ERASEMEDIUM_ERASEMEDIUMFAILED, object->errorCode);
+ }
+
+ // end burn
+ object->bs.eject = object->eject;
+ object->OnNotify(ERASEMEDIUM_FINISHING, PRIMOSDK_OK);
+ DWORD errorCode2 = EndBurn(&object->bs);
+ if (PRIMOSDK_OK != errorCode2)
+ {
+ object->OnNotify(ERASEMEDIUM_ENDBURNFAILED, object->errorCode);
+ }
+ if (PRIMOSDK_OK == object->errorCode) object->errorCode = errorCode2;
+ object->primoSDK->Release();
+ CloseHandle(object->hThread);
+ object->hThread = NULL;
+ CloseHandle(object->evntStop);
+ object->evntStop = NULL;
+ object->OnNotify( (PRIMOSDK_USERABORT == object->errorCode) ? ERASEMEDIUM_ABORTED : ERASEMEDIUM_COMPLETED, object->errorCode);
+
+ if (object->evntThreadExit) SetEvent(object->evntThreadExit);
+ return object->errorCode;
+}