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
|