mirror of
https://github.com/WinampDesktop/winamp.git
synced 2024-12-28 23:16:06 +00:00
184 lines
4.8 KiB
C++
184 lines
4.8 KiB
C++
#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, ¤t, &total);
|
|
}
|
|
if (WAIT_OBJECT_0 == waitResult)
|
|
{ // aborting
|
|
object->OnNotify(ERASEMEDIUM_CANCELING, PRIMOSDK_OK);
|
|
DWORD test = object->primoSDK->RunningStatus(PRIMOSDK_ABORT, ¤t, &total);
|
|
do
|
|
{
|
|
Sleep(1000);
|
|
object->errorCode = object->primoSDK->RunningStatus(PRIMOSDK_GETSTATUS, ¤t, &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;
|
|
}
|