burn.cpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. /** (c) Nullsoft, Inc. C O N F I D E N T I A L
  2. ** Filename:
  3. ** Project:
  4. ** Description:
  5. ** Author:
  6. ** Created:
  7. **/
  8. #include "main.h"
  9. #include "resource.h"
  10. #include <windows.h>
  11. #include <strsafe.h>
  12. #include <time.h>
  13. #include <math.h>
  14. #include "./api.h"
  15. #include "./wa_ipc.h"
  16. #include "../nu/ns_wc.h"
  17. #include "../nu/AutoWide.h"
  18. #include "../Agave/Language/api_language.h"
  19. #include <api/service/waservicefactory.h>
  20. #ifdef BURN_SUPPORT
  21. #include "../primo/obj_primo.h"
  22. #include "../burnlib/burnlib.h"
  23. #endif
  24. static void code(long* v, long* k)
  25. {
  26. unsigned long y = v[0], z = v[1], sum = 0, delta = 0x9e3779b9, n = 32 ; /* key schedule constant*/
  27. while (n-- > 0)
  28. { /* basic cycle start */
  29. sum += delta;
  30. y += ((z << 4) + k[0]) ^ (z + sum) ^ ((z >> 5) + k[1]);
  31. z += ((y << 4) + k[2]) ^ (y + sum) ^ ((y >> 5) + k[3]); /* end cycle */
  32. }
  33. v[0] = y; v[1] = z;
  34. }
  35. int getRegVer(HWND waWnd)
  36. {
  37. int *x = (int*)malloc(32);
  38. long s[3];
  39. long ss[2] = {(long)GetTickCount64(), (long)((int)x + (int)s)};
  40. long tealike_key[4] = { 31337, 0xf00d, 0xdead, 0xbeef};
  41. free(x);
  42. s[0] = ss[0];
  43. s[1] = ss[1];
  44. s[2] = 0;
  45. SendMessageW(waWnd, WM_WA_IPC, (WPARAM)s, IPC_GETREGISTEREDVERSION);
  46. code(ss, tealike_key);
  47. return (memcmp(s, ss, 8)) ? 0 : s[2];
  48. }
  49. #ifdef BURN_SUPPORT
  50. int burn_start(burnCDStruct *param)
  51. {
  52. char buf[MAX_PATH] = "\"";
  53. STARTUPINFO si = {sizeof(si), };
  54. PROCESS_INFORMATION pi;
  55. GetModuleFileName(NULL, buf + 1, sizeof(buf) - 1);
  56. StringCchCat(buf, MAX_PATH, "\"");
  57. StringCchPrintf(buf + lstrlen(buf), MAX_PATH - lstrlen(buf), " /BURN=%c,\"%s\",%d", param->cdletter, param->playlist_file, param->callback_hwnd);
  58. return (CreateProcess(NULL, buf, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) ? pi.dwProcessId : 0;
  59. }
  60. extern "C"
  61. {
  62. typedef int (*BurnFunction)(const wchar_t*, HWND, DWORD, DWORD, DWORD , const wchar_t*);
  63. }
  64. #define BURNER_OK 0x0000
  65. #define BURNER_FAILED 0x0001
  66. #define BURNER_PRIMOFAILED 0x0FF0
  67. #define BURNER_BADPLAYLISTPATH 0x0FF1
  68. #define BURNER_BADTEMPPATH 0x0FF2
  69. #define BURNER_BADCONFIGPATH 0x0FF3
  70. #define BURNER_BADCOMMANDLINE 0x0FF4
  71. #define BURNER_BADDRIVELETTER 0x0FF5
  72. #define BURNER_EMPTYPLAYLIST 0x0FF6
  73. #define BURNER_DIALOGFAILED 0x0FF7
  74. void ReportError(HWND ownerWnd, int errorCode)
  75. {
  76. wchar_t description[128] = {0};
  77. switch (errorCode)
  78. {
  79. case BURNER_OK: return ;
  80. case BURNER_PRIMOFAILED: getStringW(IDS_BURN_LIBRARY_INIT_FAILED,description,128); break;
  81. case BURNER_BADPLAYLISTPATH: getStringW(IDS_BURN_INVALID_PLAYLIST_PATH,description,128); break;
  82. case BURNER_BADTEMPPATH: getStringW(IDS_BURN_INVALID_TEMP_PATH,description,128); break;
  83. case BURNER_BADCONFIGPATH: getStringW(IDS_BURN_INVALID_CONFIG_PATH,description,128); break;
  84. case BURNER_BADCOMMANDLINE: getStringW(IDS_BURN_INVALID_CMDLINE,description,128); break;
  85. case BURNER_BADDRIVELETTER: getStringW(IDS_BURN_BAD_DRIVE_LETTER,description,128); break;
  86. case BURNER_EMPTYPLAYLIST: getStringW(IDS_BURN_LOAD_FROM_PLAYLIST_FAIL,description,128); break;
  87. case BURNER_DIALOGFAILED: getStringW(IDS_BURN_CREATE_DIALOG_FAIL,description,128); break;
  88. default: getStringW(IDS_BURN_UNKNOWN_ERROR,description,128); break;
  89. }
  90. wchar_t message[1024] = {0};
  91. if (S_OK != StringCchPrintfW(message, 1024, getStringW(IDS_BURN_INIT_ERROR_REASON,NULL,0), description))
  92. {
  93. StringCchCopyW(message, 1024, getStringW(IDS_BURN_INIT_ERROR_UNKNOWN,NULL,0));
  94. }
  95. MessageBoxW(ownerWnd, message, getStringW(IDS_BURN_NULLSOFT_STR,NULL,0), MB_OK | MB_ICONSTOP);
  96. }
  97. unsigned int burn_doBurn(char *cmdline, HWND winampWnd, HINSTANCE winampInstance)
  98. {
  99. // PrimoSDK::Trace(FALSE);
  100. #ifdef _DEBUG
  101. MessageBox(NULL, "Starting burner", "Debug", MB_OK);
  102. #endif
  103. HWND callbackWnd = 0;
  104. DWORD speed = 0;
  105. DWORD cdrom = 0;
  106. DWORD flags = PRIMOSDK_CLOSEDISC;
  107. DWORD errorCode = BURNER_OK;
  108. wchar_t tmppath[4*MAX_PATH] = {0};
  109. wchar_t in_wm[MAX_PATH] = {0};
  110. wchar_t playlist[4096] = {0};
  111. // get temp path
  112. if (BURNER_OK == errorCode && !GetTempPathW(MAX_PATH, tmppath)) errorCode = BURNER_BADTEMPPATH;
  113. if (BURNER_OK == errorCode) //// parse parameters
  114. {
  115. if (lstrlenA(cmdline) < 1) errorCode = BURNER_BADCOMMANDLINE;
  116. if (BURNER_OK == errorCode)
  117. {
  118. // drive letter
  119. CharUpperBuff(cmdline, 1);
  120. cdrom = cmdline[0];
  121. for (int i = 0; i < 2; i++) cmdline = CharNext(cmdline);
  122. if (cdrom < 'A' || cdrom > 'Z') errorCode = BURNER_BADDRIVELETTER;
  123. }
  124. if (BURNER_OK == errorCode)
  125. {
  126. // callback window
  127. char *current = cmdline + lstrlenA(cmdline);
  128. while (current != cmdline && *current != ',') current = CharPrevA(cmdline, current);
  129. callbackWnd = (current != cmdline) ? (HWND)atoi(CharNext(current)) : NULL;
  130. // playlist path
  131. size_t cchLen = current - cmdline;
  132. if (cchLen == 0) errorCode = BURNER_BADPLAYLISTPATH;
  133. if (BURNER_OK == errorCode)
  134. {
  135. if (!MultiByteToWideCharSZ(CP_ACP, 0, cmdline, current - cmdline, playlist, 4096)) errorCode = BURNER_BADPLAYLISTPATH;
  136. else playlist[cchLen] = 0x0000;
  137. }
  138. }
  139. if (BURNER_OK == errorCode)
  140. {
  141. speed = GetPrivateProfileIntW(L"gen_ml_config", L"cdburnspeed", PRIMOSDK_MIN, ML_INI_FILE);
  142. DWORD maxspeed = GetPrivateProfileIntW(L"gen_ml_config", L"cdburnmaxspeed", PRIMOSDK_MIN, ML_INI_FILE);
  143. if (!getRegVer(winampWnd)) speed = PRIMOSDK_MIN;
  144. if (!speed) speed = maxspeed;
  145. if (!speed) speed = PRIMOSDK_MIN;
  146. flags |= (GetPrivateProfileIntW(L"gen_ml_config", L"cdburntestmode", 0, ML_INI_FILE)) ? PRIMOSDK_TEST : PRIMOSDK_WRITE;
  147. flags |= (GetPrivateProfileIntW(L"gen_ml_config", L"cdburnproof", 0, ML_INI_FILE)) ? PRIMOSDK_BURNPROOF : 0;
  148. }
  149. }
  150. if (BURNER_OK != errorCode)
  151. {
  152. if (playlist[0] != 0x0000) DeleteFileW(playlist);
  153. ReportError(callbackWnd, errorCode);
  154. return errorCode;
  155. }
  156. // try in_wm version first
  157. PathCombineW(in_wm, PLUGINDIR, L"in_wm.dll");
  158. BurnFunction burnFunc = NULL;
  159. HMODULE lib = LoadLibraryW(in_wm);
  160. if (lib)
  161. {
  162. burnFunc = (BurnFunction)GetProcAddress(lib, "burn_doBurn");
  163. if (burnFunc)
  164. {
  165. errorCode = burnFunc(playlist, callbackWnd, cdrom, speed, flags, tmppath);
  166. }
  167. }
  168. if (lib) FreeLibrary(lib);
  169. lib = NULL;
  170. if (!burnFunc)
  171. {
  172. InitializeBurningLibrary(WASABI_API_SVC, hMainInstance, winampWnd);
  173. BurnerPlaylist burnPL;
  174. burnPL.Load(playlist);
  175. if (!burnPL.GetCount()) errorCode = BURNER_EMPTYPLAYLIST;
  176. else
  177. {
  178. obj_primo *primo=0;
  179. waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(obj_primo::getServiceGuid());
  180. if (sf) primo = reinterpret_cast<obj_primo *>(sf->getInterface());
  181. if (!primo)
  182. errorCode = BURNER_PRIMOFAILED;
  183. else
  184. {
  185. BurnPlaylistUI burnDlg;
  186. errorCode = burnDlg.Burn(primo, cdrom, speed, flags, &burnPL, tmppath, callbackWnd);
  187. sf->releaseInterface(primo);
  188. }
  189. }
  190. }
  191. DeleteFileW(playlist);
  192. if (BURNER_OK != errorCode) ReportError(callbackWnd, errorCode);
  193. return errorCode;
  194. }
  195. #endif