aboutsummaryrefslogtreecommitdiff
path: root/Src/Plugins/SDK/burner/ISOCreator.cpp
blob: bf8b83f347500b5132f2d46050e68810a1f76d81 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
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