aboutsummaryrefslogtreecommitdiff
path: root/Src/Plugins/SDK/burner/ISOCreator.cpp
diff options
context:
space:
mode:
authorJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
committerJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
commit20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch)
tree12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/Plugins/SDK/burner/ISOCreator.cpp
parent537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff)
downloadwinamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz
Initial community commit
Diffstat (limited to 'Src/Plugins/SDK/burner/ISOCreator.cpp')
-rw-r--r--Src/Plugins/SDK/burner/ISOCreator.cpp139
1 files changed, 139 insertions, 0 deletions
diff --git a/Src/Plugins/SDK/burner/ISOCreator.cpp b/Src/Plugins/SDK/burner/ISOCreator.cpp
new file mode 100644
index 00000000..bf8b83f3
--- /dev/null
+++ b/Src/Plugins/SDK/burner/ISOCreator.cpp
@@ -0,0 +1,139 @@
+#include "ISOCreator.h"
+#include <malloc.h>
+#include "../nu/AutoChar.h"
+#include "ifc_burner_writecallback.h"
+#include <strsafe.h>
+
+ISOCreator::ISOCreator(obj_primo *_primo) : BurnerCommon(_primo)
+{
+}
+
+ISOCreator::~ISOCreator()
+{
+ if (primo)
+ primo->CloseImage();
+}
+
+int ISOCreator::Open(const wchar_t *volumeName, int format, int media)
+{
+ if (!primo)
+ return 1;
+
+ DWORD units=0xFFFFFFFF;
+ DWORD ret = primo->NewImageWCS(
+ &units,
+ (PWORD)volumeName,
+ 0, // no track session # needed, I don't think
+ PRIMOSDK_ORIGDATE | format | media,
+ 0, // don't think we need a swap file for ISO
+ 0 // probably don't need a swap location either, we'll see ...
+ ); // TODO: validate format and media
+
+ if (ret != PRIMOSDK_OK)
+ return 1;
+
+ 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 ISOCreator::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 ISOCreator::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 ISOCreator::Write(const wchar_t *destination, ifc_burner_writecallback *callback)
+{
+ DWORD size=0;
+ DWORD ret = primo->SaveImage((PBYTE)(char *)AutoChar(destination), &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)
+ {
+ if (callback)
+ callback->Finished();
+ break;
+ }
+ else
+ break;
+ }
+
+ if (ret != PRIMOSDK_OK)
+ return 1;
+
+ return 0;
+}
+
+#define CBCLASS ISOCreator
+START_DISPATCH;
+CB(ISOCREATOR_OPEN, Open)
+CB(ISOCREATOR_ADDFILE, AddFile)
+CB(ISOCREATOR_ADDFOLDER, AddFolder)
+CB(ISOCREATOR_WRITE, Write)
+VCB(ISOCREATOR_FORCECALLBACK, ForceCallback)
+END_DISPATCH;
+#undef CBCLASS