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
140
141
142
143
144
145
146
147
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
|