aboutsummaryrefslogtreecommitdiff
path: root/Src/Plugins/SDK/burner/DataBurner.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Plugins/SDK/burner/DataBurner.cpp')
-rw-r--r--Src/Plugins/SDK/burner/DataBurner.cpp148
1 files changed, 148 insertions, 0 deletions
diff --git a/Src/Plugins/SDK/burner/DataBurner.cpp b/Src/Plugins/SDK/burner/DataBurner.cpp
new file mode 100644
index 00000000..e5cd579d
--- /dev/null
+++ b/Src/Plugins/SDK/burner/DataBurner.cpp
@@ -0,0 +1,148 @@
+#include "DataBurner.h"
+#include "ifc_burner_writecallback.h"
+#include <malloc.h>
+#include <strsafe.h>
+
+DataBurner::DataBurner(obj_primo *_primo) : BurnerCommon(_primo)
+{
+ driveLetter=0;
+}
+
+DataBurner::~DataBurner()
+{
+ if (primo)
+ primo->CloseImage();
+}
+
+int DataBurner::Open(const wchar_t *volumeName, wchar_t driveLetter, int format)
+{
+ this->driveLetter = driveLetter;
+ if (!primo)
+ return 1;
+
+
+ DWORD units[] = {driveLetter, 0xFFFFFFFF};
+
+
+ // TODO: use PrimoSDK_DiscInfoEx to verify that a disc is available
+
+ // TODO: PrimoSDK_UnitVxBlock after we're done debugging
+ // TODO: PrimoSDK_UnitAIN
+ // TODO: PrimoSDK_UnitLock
+
+ DWORD ret = primo->NewImageWCS(units,
+ (PWORD)volumeName,
+ 0, // no track session # needed, I don't think
+ PRIMOSDK_ORIGDATE | format,
+ 0, // TODO
+ 0 // TODO
+ ); // TODO: validate format
+
+ return 0;
+}
+
+// TODO: check AddFolderWCS for return values
+static void createDirForFileW(obj_primo *primo, const wchar_t *str)
+{
+ const wchar_t *p = str;
+ if ((p[0] ==L'\\' || p[0] ==L'/') && (p[1] ==L'\\' || p[1] ==L'/'))
+ {
+ p += 2;
+ while (*p && *p !=L'\\' && *p !=L'/') p++;
+ if (!*p) return ;
+ p++;
+ while (*p && *p !=L'\\' && *p !=L'/') p++;
+ }
+ else
+ {
+ while (*p && *p !=L'\\' && *p !=L'/') p++;
+ }
+
+ while (*p)
+ {
+ while (*p !=L'\\' && *p !=L'/' && *p) p = CharNextW(p);
+ if (*p)
+ {
+ size_t copySize = (p-str+1)*sizeof(wchar_t);
+ wchar_t *copy = (wchar_t *)alloca(copySize);
+ StringCbCopy(copy, copySize, str);
+ primo->AddFolderWCS(copy);
+ p++;
+ }
+ }
+}
+
+int DataBurner::AddFile(const wchar_t *source, const wchar_t *destination)
+{
+ createDirForFileW(primo, destination);
+ DWORD ret = primo->AddFileWCS((PWORD)destination, (PWORD)source);
+
+ if (ret != PRIMOSDK_OK)
+ return 1;
+
+ return 0;
+}
+
+int DataBurner::AddFolder(const wchar_t *folder)
+{
+ createDirForFileW(primo, folder);
+ DWORD ret = primo->AddFolderWCS(folder); // add again in case they didn't terminate with a slash
+ if (ret != PRIMOSDK_OK)
+ return 1;
+
+ return 0;
+}
+
+int DataBurner::Write(int flags, unsigned int speed, ifc_burner_writecallback *callback)
+{
+ DWORD size=0;
+ DWORD ret = primo->WriteImage(flags, speed, &size);
+ if (ret != PRIMOSDK_OK)
+ return 1;
+
+ while (1)
+ {
+ DWORD cursec = 0, totsec = 0;
+ ret = primo->RunningStatus(PRIMOSDK_GETSTATUS, &cursec, &totsec);
+
+ if (ret == PRIMOSDK_RUNNING)
+ {
+ if (callback)
+ {
+ int abort = callback->OnStatus(cursec, totsec);
+ if (abort)
+ {
+ ret = primo->RunningStatus(PRIMOSDK_ABORT, 0, 0);
+ callback = 0; // cheap way to prevent making further callbacks
+ }
+ }
+ WaitForSingleObject(triggerEvent, 500);
+ }
+ else if (ret == PRIMOSDK_OK)
+ {
+ DWORD unit = driveLetter;
+ ret = primo->UnitStatus(&unit, NULL, NULL, NULL, NULL);
+
+ if (ret == PRIMOSDK_OK && callback)
+ callback->Finished();
+ break;
+ }
+ else
+ break;
+ }
+
+ if (ret != PRIMOSDK_OK)
+ return 1;
+
+ return 0;
+}
+
+#define CBCLASS DataBurner
+START_DISPATCH;
+CB(DATABURNER_OPEN, Open)
+CB(DATABURNER_ADDFILE, AddFile)
+CB(DATABURNER_ADDFOLDER, AddFolder)
+CB(DATABURNER_WRITE, Write)
+VCB(DATABURNER_FORCECALLBACK, ForceCallback)
+END_DISPATCH;
+#undef CBCLASS