aboutsummaryrefslogtreecommitdiff
path: root/Src/Winamp/burn.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Winamp/burn.cpp')
-rw-r--r--Src/Winamp/burn.cpp220
1 files changed, 220 insertions, 0 deletions
diff --git a/Src/Winamp/burn.cpp b/Src/Winamp/burn.cpp
new file mode 100644
index 00000000..d1a6cc8d
--- /dev/null
+++ b/Src/Winamp/burn.cpp
@@ -0,0 +1,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 \ No newline at end of file