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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
|
/** (c) Nullsoft, Inc. C O N F I D E N T I A L
** Filename:
** Project:
** Description:
** Author:
** Created:
**/
#include "main.h"
#include "resource.h"
#include <windows.h>
#include <strsafe.h>
#include <time.h>
#include <math.h>
#include "./api.h"
#include "./wa_ipc.h"
#include "../nu/ns_wc.h"
#include "../nu/AutoWide.h"
#include "../Agave/Language/api_language.h"
#include <api/service/waservicefactory.h>
#ifdef BURN_SUPPORT
#include "../primo/obj_primo.h"
#include "../burnlib/burnlib.h"
#endif
static void code(long* v, long* k)
{
unsigned long y = v[0], z = v[1], sum = 0, delta = 0x9e3779b9, n = 32 ; /* key schedule constant*/
while (n-- > 0)
{ /* basic cycle start */
sum += delta;
y += ((z << 4) + k[0]) ^ (z + sum) ^ ((z >> 5) + k[1]);
z += ((y << 4) + k[2]) ^ (y + sum) ^ ((y >> 5) + k[3]); /* end cycle */
}
v[0] = y; v[1] = z;
}
int getRegVer(HWND waWnd)
{
int *x = (int*)malloc(32);
long s[3];
long ss[2] = {(long)GetTickCount64(), (long)((int)x + (int)s)};
long tealike_key[4] = { 31337, 0xf00d, 0xdead, 0xbeef};
free(x);
s[0] = ss[0];
s[1] = ss[1];
s[2] = 0;
SendMessageW(waWnd, WM_WA_IPC, (WPARAM)s, IPC_GETREGISTEREDVERSION);
code(ss, tealike_key);
return (memcmp(s, ss, 8)) ? 0 : s[2];
}
#ifdef BURN_SUPPORT
int burn_start(burnCDStruct *param)
{
char buf[MAX_PATH] = "\"";
STARTUPINFO si = {sizeof(si), };
PROCESS_INFORMATION pi;
GetModuleFileName(NULL, buf + 1, sizeof(buf) - 1);
StringCchCat(buf, MAX_PATH, "\"");
StringCchPrintf(buf + lstrlen(buf), MAX_PATH - lstrlen(buf), " /BURN=%c,\"%s\",%d", param->cdletter, param->playlist_file, param->callback_hwnd);
return (CreateProcess(NULL, buf, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) ? pi.dwProcessId : 0;
}
extern "C"
{
typedef int (*BurnFunction)(const wchar_t*, HWND, DWORD, DWORD, DWORD , const wchar_t*);
}
#define BURNER_OK 0x0000
#define BURNER_FAILED 0x0001
#define BURNER_PRIMOFAILED 0x0FF0
#define BURNER_BADPLAYLISTPATH 0x0FF1
#define BURNER_BADTEMPPATH 0x0FF2
#define BURNER_BADCONFIGPATH 0x0FF3
#define BURNER_BADCOMMANDLINE 0x0FF4
#define BURNER_BADDRIVELETTER 0x0FF5
#define BURNER_EMPTYPLAYLIST 0x0FF6
#define BURNER_DIALOGFAILED 0x0FF7
void ReportError(HWND ownerWnd, int errorCode)
{
wchar_t description[128] = {0};
switch (errorCode)
{
case BURNER_OK: return ;
case BURNER_PRIMOFAILED: getStringW(IDS_BURN_LIBRARY_INIT_FAILED,description,128); break;
case BURNER_BADPLAYLISTPATH: getStringW(IDS_BURN_INVALID_PLAYLIST_PATH,description,128); break;
case BURNER_BADTEMPPATH: getStringW(IDS_BURN_INVALID_TEMP_PATH,description,128); break;
case BURNER_BADCONFIGPATH: getStringW(IDS_BURN_INVALID_CONFIG_PATH,description,128); break;
case BURNER_BADCOMMANDLINE: getStringW(IDS_BURN_INVALID_CMDLINE,description,128); break;
case BURNER_BADDRIVELETTER: getStringW(IDS_BURN_BAD_DRIVE_LETTER,description,128); break;
case BURNER_EMPTYPLAYLIST: getStringW(IDS_BURN_LOAD_FROM_PLAYLIST_FAIL,description,128); break;
case BURNER_DIALOGFAILED: getStringW(IDS_BURN_CREATE_DIALOG_FAIL,description,128); break;
default: getStringW(IDS_BURN_UNKNOWN_ERROR,description,128); break;
}
wchar_t message[1024] = {0};
if (S_OK != StringCchPrintfW(message, 1024, getStringW(IDS_BURN_INIT_ERROR_REASON,NULL,0), description))
{
StringCchCopyW(message, 1024, getStringW(IDS_BURN_INIT_ERROR_UNKNOWN,NULL,0));
}
MessageBoxW(ownerWnd, message, getStringW(IDS_BURN_NULLSOFT_STR,NULL,0), MB_OK | MB_ICONSTOP);
}
unsigned int burn_doBurn(char *cmdline, HWND winampWnd, HINSTANCE winampInstance)
{
// PrimoSDK::Trace(FALSE);
#ifdef _DEBUG
MessageBox(NULL, "Starting burner", "Debug", MB_OK);
#endif
HWND callbackWnd = 0;
DWORD speed = 0;
DWORD cdrom = 0;
DWORD flags = PRIMOSDK_CLOSEDISC;
DWORD errorCode = BURNER_OK;
wchar_t tmppath[4*MAX_PATH] = {0};
wchar_t in_wm[MAX_PATH] = {0};
wchar_t playlist[4096] = {0};
// get temp path
if (BURNER_OK == errorCode && !GetTempPathW(MAX_PATH, tmppath)) errorCode = BURNER_BADTEMPPATH;
if (BURNER_OK == errorCode) //// parse parameters
{
if (lstrlenA(cmdline) < 1) errorCode = BURNER_BADCOMMANDLINE;
if (BURNER_OK == errorCode)
{
// drive letter
CharUpperBuff(cmdline, 1);
cdrom = cmdline[0];
for (int i = 0; i < 2; i++) cmdline = CharNext(cmdline);
if (cdrom < 'A' || cdrom > 'Z') errorCode = BURNER_BADDRIVELETTER;
}
if (BURNER_OK == errorCode)
{
// callback window
char *current = cmdline + lstrlenA(cmdline);
while (current != cmdline && *current != ',') current = CharPrevA(cmdline, current);
callbackWnd = (current != cmdline) ? (HWND)atoi(CharNext(current)) : NULL;
// playlist path
size_t cchLen = current - cmdline;
if (cchLen == 0) errorCode = BURNER_BADPLAYLISTPATH;
if (BURNER_OK == errorCode)
{
if (!MultiByteToWideCharSZ(CP_ACP, 0, cmdline, current - cmdline, playlist, 4096)) errorCode = BURNER_BADPLAYLISTPATH;
else playlist[cchLen] = 0x0000;
}
}
if (BURNER_OK == errorCode)
{
speed = GetPrivateProfileIntW(L"gen_ml_config", L"cdburnspeed", PRIMOSDK_MIN, ML_INI_FILE);
DWORD maxspeed = GetPrivateProfileIntW(L"gen_ml_config", L"cdburnmaxspeed", PRIMOSDK_MIN, ML_INI_FILE);
if (!getRegVer(winampWnd)) speed = PRIMOSDK_MIN;
if (!speed) speed = maxspeed;
if (!speed) speed = PRIMOSDK_MIN;
flags |= (GetPrivateProfileIntW(L"gen_ml_config", L"cdburntestmode", 0, ML_INI_FILE)) ? PRIMOSDK_TEST : PRIMOSDK_WRITE;
flags |= (GetPrivateProfileIntW(L"gen_ml_config", L"cdburnproof", 0, ML_INI_FILE)) ? PRIMOSDK_BURNPROOF : 0;
}
}
if (BURNER_OK != errorCode)
{
if (playlist[0] != 0x0000) DeleteFileW(playlist);
ReportError(callbackWnd, errorCode);
return errorCode;
}
// try in_wm version first
PathCombineW(in_wm, PLUGINDIR, L"in_wm.dll");
BurnFunction burnFunc = NULL;
HMODULE lib = LoadLibraryW(in_wm);
if (lib)
{
burnFunc = (BurnFunction)GetProcAddress(lib, "burn_doBurn");
if (burnFunc)
{
errorCode = burnFunc(playlist, callbackWnd, cdrom, speed, flags, tmppath);
}
}
if (lib) FreeLibrary(lib);
lib = NULL;
if (!burnFunc)
{
InitializeBurningLibrary(WASABI_API_SVC, hMainInstance, winampWnd);
BurnerPlaylist burnPL;
burnPL.Load(playlist);
if (!burnPL.GetCount()) errorCode = BURNER_EMPTYPLAYLIST;
else
{
obj_primo *primo=0;
waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(obj_primo::getServiceGuid());
if (sf) primo = reinterpret_cast<obj_primo *>(sf->getInterface());
if (!primo)
errorCode = BURNER_PRIMOFAILED;
else
{
BurnPlaylistUI burnDlg;
errorCode = burnDlg.Burn(primo, cdrom, speed, flags, &burnPL, tmppath, callbackWnd);
sf->releaseInterface(primo);
}
}
}
DeleteFileW(playlist);
if (BURNER_OK != errorCode) ReportError(callbackWnd, errorCode);
return errorCode;
}
#endif
|