Config.cpp 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251
  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. #ifndef CONFIG_IMPL
  9. #define CONFIG_IMPL
  10. #endif
  11. #include "Main.h"
  12. #include "config.h"
  13. #include "WinampAttributes.h"
  14. #include "../nu/AutoWide.h"
  15. #include "../nu/AutoChar.h"
  16. #include "../nu/ns_wc.h"
  17. #include "../nu/AutoLock.h"
  18. #include "../nu/AutoCharFn.h"
  19. #include "../Elevator/FileTypeRegistrar.h"
  20. #include "main.hpp"
  21. #include <shobjidl.h>
  22. #if (_MSC_VER < 1500)
  23. typedef struct tagBIND_OPTS3 : tagBIND_OPTS2
  24. {
  25. HWND hwnd;
  26. } BIND_OPTS3, * LPBIND_OPTS3;
  27. #endif
  28. static HRESULT CoCreateInstanceAsAdmin(HWND hwnd, REFCLSID rclsid, REFIID riid, void ** ppv)
  29. {
  30. BIND_OPTS3 bo;
  31. WCHAR wszCLSID[50] = {0};
  32. WCHAR wszMonikerName[300] = {0};
  33. StringFromGUID2(rclsid, wszCLSID, sizeof(wszCLSID)/sizeof(wszCLSID[0]));
  34. HRESULT hr = StringCchPrintfW(wszMonikerName, sizeof(wszMonikerName)/sizeof(wszMonikerName[0]), L"Elevation:Administrator!new:%s", wszCLSID);
  35. if (FAILED(hr))
  36. return hr;
  37. memset(&bo, 0, sizeof(bo));
  38. bo.cbStruct = sizeof(bo);
  39. bo.hwnd = hwnd;
  40. bo.dwClassContext = CLSCTX_LOCAL_SERVER;
  41. return CoGetObject(wszMonikerName, &bo, riid, ppv);
  42. }
  43. static bool NeedElevation()
  44. {
  45. return !IsUserAnAdmin();
  46. }
  47. static Nullsoft::Utility::LockGuard registrarGuard;
  48. static const GUID ftr_guid =
  49. { 0x3B29AB5C, 0x52CB, 0x4a36, { 0x93,0x14,0xE3,0xFE,0xE0,0xBA,0x74,0x68 } };
  50. static IFileTypeRegistrar *masterRegistrar;
  51. static FileTypeRegistrar builtIn;
  52. bool usingBuiltIn = false;
  53. int GetRegistrar(IFileTypeRegistrar **registrar, BOOL use_fallback)
  54. {
  55. Nullsoft::Utility::AutoLock autolock(registrarGuard);
  56. // attempt to re-get an elevated object as needed
  57. // i.e. if user selects no but wants to try again
  58. // then we need to try going elevated again
  59. if (!masterRegistrar || usingBuiltIn)
  60. {
  61. #if 1 // benski> on Vista, we need this object to run out-of-process so it can be elevated to Administrator
  62. // without elevating Winamp itself - see http://msdn2.microsoft.com/en-us/ms679687.aspx
  63. OSVERSIONINFO version = {0};
  64. version.dwOSVersionInfoSize = sizeof(version);
  65. if (!GetVersionEx(&version)) ZeroMemory(&version, sizeof(OSVERSIONINFO));
  66. if (version.dwMajorVersion >= 6 && NeedElevation()) // Vista
  67. {
  68. IFileTypeRegistrar *registrar = 0;
  69. HRESULT hr = CoCreateInstanceAsAdmin(0, ftr_guid, __uuidof(IFileTypeRegistrar), (void**)&registrar);
  70. if (SUCCEEDED(hr) && registrar)
  71. {
  72. if (masterRegistrar) masterRegistrar->Release();
  73. masterRegistrar = registrar;
  74. usingBuiltIn = false;
  75. }
  76. else
  77. {
  78. if (!use_fallback)
  79. {
  80. if (registrar) registrar->Release();
  81. if (masterRegistrar) masterRegistrar->Release();
  82. registrar = masterRegistrar = 0;
  83. usingBuiltIn = false;
  84. return 1;
  85. }
  86. }
  87. }
  88. #if 0
  89. else /* benski> on earlier OS's just for testing purposes, we'll get rid of this totally once the COM stuff is worked out */
  90. {
  91. CoCreateInstance(ftr_guid, NULL, CLSCTX_LOCAL_SERVER, __uuidof(IFileTypeRegistrar), (void**)&masterRegistrar);
  92. }
  93. #endif
  94. #endif
  95. }
  96. if (!masterRegistrar) /* wasn't registered? we'll use our internal version (but it won't work well on Vista+) */
  97. {
  98. masterRegistrar = &builtIn;
  99. usingBuiltIn = true;
  100. }
  101. if (masterRegistrar)
  102. {
  103. *registrar = masterRegistrar;
  104. masterRegistrar->AddRef();
  105. return 0;
  106. }
  107. return 1;
  108. }
  109. void RemoveRegistrar()
  110. {
  111. Nullsoft::Utility::AutoLock autolock(registrarGuard);
  112. if (masterRegistrar) masterRegistrar->Release();
  113. masterRegistrar = 0;
  114. usingBuiltIn = false;
  115. }
  116. int _r_i(char *name, int def)
  117. {
  118. return GetPrivateProfileIntA(app_name, name, def, INI_FILEA);
  119. }
  120. #define RI(x) (( config_##x ) = _r_i(#x,( config_##x )))
  121. #define RI_NP(x) (( x ) = _r_i(#x,( x )))
  122. #define RB(x) (( config_##x ) = !!_r_i(#x,( config_##x )))
  123. void _w_i(char *name, intptr_t d)
  124. {
  125. char str[120] = {0};
  126. StringCchPrintfA(str, 120, "%d", d);
  127. WritePrivateProfileStringA(app_name, name, str, INI_FILEA);
  128. }
  129. #define WI(x) _w_i(#x,( config_##x ))
  130. #define WI_NP(x) _w_i(#x,( x ))
  131. void _r_s(char *name, char *data, int mlen)
  132. {
  133. char utf8_data[2048] = {0};
  134. wchar_t utf16_data[2048] = {0};
  135. char buf[2048] = {0};
  136. StringCchCopyA(buf, 2048, data);
  137. GetPrivateProfileStringA(app_name, name, buf, utf8_data, 2048, INI_FILEA);
  138. MultiByteToWideCharSZ(CP_UTF8, 0, utf8_data, -1, utf16_data, 2048);
  139. WideCharToMultiByteSZ(CP_ACP, 0, utf16_data, -1, data, mlen, 0, 0);
  140. }
  141. #define RS(x) (_r_s(#x,config_##x,sizeof(config_##x)))
  142. #define RS_NP(x) (_r_s(#x,x,sizeof(x)))
  143. void _r_sW(const char *name, wchar_t *data, int mlen)
  144. {
  145. char utf8_data[2048] = {0};
  146. char default_data[2048] = {0};
  147. WideCharToMultiByteSZ(config_utf8?CP_UTF8:CP_ACP, 0, data, -1, default_data, 2048,0,0);
  148. GetPrivateProfileStringA(app_name, name, default_data, utf8_data, 2048, INI_FILEA);
  149. MultiByteToWideCharSZ(config_utf8?CP_UTF8:CP_ACP, 0, utf8_data, -1, data, mlen);
  150. }
  151. #define RSW(x) (_r_sW(#x,config_##x,sizeof(config_##x)/sizeof(wchar_t)))
  152. #define RSW_NP(x) (_r_sW(#x,x,sizeof(x)/sizeof(wchar_t)))
  153. void _w_s(char *name, char *data)
  154. {
  155. WritePrivateProfileStringA(app_name, name, AutoChar(AutoWide(data), CP_UTF8), INI_FILEA);
  156. }
  157. #define WS(x) (_w_s(#x,config_##x))
  158. #define WS_NP(x) (_w_s(#x,x))
  159. void _w_sW(const char *name, const wchar_t *data)
  160. {
  161. WritePrivateProfileStringA(app_name, name, AutoChar(data, CP_UTF8), INI_FILEA); // TODO: don't want autowide here
  162. }
  163. #define WSW(x) (_w_sW(#x,config_##x))
  164. #define WSW_NP(x) (_w_sW(#x,x))
  165. void config_write(int i)
  166. {
  167. config_pilp = PlayList_getPosition();
  168. //GetCurrentDirectoryW(MAX_PATH, config_cwd);
  169. if (i && plneedsave)
  170. {
  171. // changed 5.64 to only save if there was a change as this can save a
  172. // decent amount of time on closing with a large unmodified playlist.
  173. savem3ufn(M3U_FILE, 0, 1);
  174. savem3ufn(OLD_M3U_FILE, 0, 1);
  175. }
  176. config_utf8=1;
  177. WI(utf8);
  178. if (i != 1) // write mostly unused stuff, like proxy, plugin names, etc
  179. {
  180. WS(defext);
  181. WSW(titlefmt);
  182. WI(proxy80);
  183. WS(proxy);
  184. WSW(visplugin_name);
  185. WSW(dspplugin_name);
  186. WI(check_ft_startup);
  187. WI(updated_ft_startup);
  188. WI(visplugin_num);
  189. WI(pe_fontsize);
  190. WI(pe_direction);
  191. WI(visplugin_priority);
  192. WI(visplugin_autoexec);
  193. WI(dspplugin_num);
  194. WI(sticon);
  195. WI(splash);
  196. WI(taskbar);
  197. WI(dropaotfs);
  198. WI(nomwheel);
  199. WI(ascb_new);
  200. WI(ttips);
  201. WI(riol);
  202. WI(minst);
  203. WI(whichicon);
  204. WI(whichicon2);
  205. WI(addtolist);
  206. WI(snap);
  207. WI(snaplen);
  208. WI(parent);
  209. WI(hilite);
  210. WI(disvis);
  211. WI(rofiob);
  212. WI(shownumsinpl);
  213. WI(keeponscreen);
  214. WI(eqdsize);
  215. WI(usecursors);
  216. WI(fixtitles);
  217. WI(priority);
  218. WI(shuffle_morph_rate);
  219. WI(useexttitles);
  220. WI(bifont);
  221. WI(bifont_alt);
  222. WI(dotitlenum);
  223. WI(dotasknum);
  224. WI(plscrollsize);
  225. WI(plmw2xscroll);
  226. WI(inet_mode);
  227. WI(ospb);
  228. WI(embedwnd_freesize);
  229. WI(no_visseh);
  230. }
  231. WI(newverchk);
  232. WI(newverchk2);
  233. WI(newverchk3);
  234. WI(newverchk_rc);
  235. WI(user_consent_join_channels);
  236. // write everything else
  237. {
  238. int config_prefs_last_page = prefs_last_page | (about_lastpage << 8);
  239. WI(prefs_last_page);
  240. prefs_last_page &= 255;
  241. _w_i("prefs_wx", prefs_rect.left);
  242. _w_i("prefs_wy", prefs_rect.top);
  243. _w_i("alt3_wx", alt3_rect.left);
  244. _w_i("alt3_wy", alt3_rect.top);
  245. _w_i("editinfo_wx", editinfo_rect.left);
  246. _w_i("editinfo_wy", editinfo_rect.top);
  247. _w_i("ctrle_wx", ctrle_rect.left);
  248. _w_i("ctrle_wy", ctrle_rect.top);
  249. _w_i("about_wx", about_rect.left);
  250. _w_i("about_wy", about_rect.top);
  251. _w_i("loc_wx", loc_rect.left);
  252. _w_i("loc_wy", loc_rect.top);
  253. _w_i("time_wx", time_rect.left);
  254. _w_i("time_wy", time_rect.top);
  255. _w_i("load_wx", load_rect.left);
  256. _w_i("load_wy", load_rect.top);
  257. }
  258. WI(autoload_eq);
  259. WI(playlist_recyclebin);
  260. WI(use_eq);
  261. WI(eq_ws);
  262. WI(wx);
  263. WI(wy);
  264. WI(minimized);
  265. WI(aot);
  266. WI(shuffle);
  267. WI(repeat);
  268. WI(volume);
  269. WI(pan);
  270. WI(easymove);
  271. WI(dsize);
  272. WI(timeleftmode);
  273. WI(autoscrollname);
  274. WI(sa);
  275. WI(safire);
  276. WI(saref);
  277. WI(safalloff);
  278. WI(sa_peaks);
  279. WI(sa_peak_falloff);
  280. WI(eq_wx);
  281. WI(eq_wy);
  282. WI(eq_open);
  283. WI(mw_open);
  284. WI(pe_wx);
  285. WI(pe_wy);
  286. WI(pe_open);
  287. WI(pe_width);
  288. WI(pe_height);
  289. WI(pe_height_ws);
  290. WI(eq_limiter);
  291. WI(eq_type);
  292. WI(eq_frequencies);
  293. /*
  294. WI(si_wx);
  295. WI(si_wy);
  296. WI(si_width);
  297. WI(si_height);
  298. WI(si_autoshow);
  299. WI(si_autosize);
  300. WI(si_autohide);
  301. WI(si_open);
  302. */
  303. WI(video_wx);
  304. WI(video_wy);
  305. WI(video_open);
  306. WI(video_width);
  307. WI(video_height);
  308. WI(video_ratio1);
  309. WI(video_ratio2);
  310. WI(video_useratio);
  311. WI(windowshade);
  312. WI(preamp);
  313. WI(pilp);
  314. WI(randskin);
  315. WSW(cwd);
  316. WSW(skin);
  317. WS(outname);
  318. WI(pladv);
  319. {
  320. char config_eq_data[256] = {0};
  321. StringCchPrintfA(config_eq_data, 256, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
  322. eq_tab[0], eq_tab[1], eq_tab[2], eq_tab[3], eq_tab[4],
  323. eq_tab[5], eq_tab[6], eq_tab[7], eq_tab[8], eq_tab[9]);
  324. WS(eq_data);
  325. }
  326. WI(video_vsync2);
  327. WI(video_aspectadj);
  328. WI(video_overlays);
  329. WI(video_gdiplus);
  330. WI(video_ddraw);
  331. WI(video_updsize);
  332. WI(video_autoopen);
  333. WI(video_autoclose);
  334. WI(video_noss);
  335. WI(video_logo);
  336. WI(video_osd);
  337. WI(video_yv12);
  338. WI(video_stopclose);
  339. WI(video_auto_fs);
  340. WI(playback_thread_priority);
  341. WI(audio_bits);
  342. WI(audio_mono);
  343. WI(audio_surround);
  344. WI(audio_dither);
  345. WI(replaygain);
  346. WI(replaygain_mode);
  347. WI(replaygain_source);
  348. WI(replaygain_preferred_only);
  349. _w_i("replaygain_non_rg_gain", (intptr_t)(config_replaygain_non_rg_gain.GetFloat()*1000.0f));
  350. _w_i("replaygain_preamp", (intptr_t)(config_replaygain_preamp.GetFloat()*1000.0f));
  351. // WI(video_contrast);
  352. // WI(video_brightness);
  353. WI(video_fliprgb);
  354. WI(video_remove_fs_on_stop);
  355. WI(wav_do_header);
  356. WI(wav_convert);
  357. WS(wav_ext);
  358. _w_sW("playlist_custom_font", playlist_custom_fontW);
  359. WI(custom_plfont);
  360. WI(no_registry);
  361. WI(last_classic_skin_page);
  362. WI(last_playback_page);
  363. WI(last_fileinfo_page);
  364. WSW(artwork_filter);
  365. WI(zeropadplnum);
  366. WI(wlz_menu);
  367. WI(accessibility_modalbeep);
  368. WI(accessibility_modalflash);
  369. WI(noml_ratings_prompt);
  370. WI(noml_ratings);
  371. WI(uid_ft);
  372. }
  373. void config_read(int i)
  374. {
  375. wchar_t programname[MAX_PATH] = {0};
  376. GetModuleFileNameW(hMainInstance, programname, MAX_PATH);
  377. // regmimetype(L"interface/x-winamp-skin", programname, L".wsz", 0); // hack cause wa3 is gheeeeeey
  378. RI(utf8);
  379. RI(eq_ws);
  380. RI(updated_ft_startup);
  381. // fiddle things so if running an existing install then we force restore file assoc off
  382. // when we're running on Vista / Win7+ to resolve complaints from users on those OSes.
  383. // vista
  384. if(config_updated_ft_startup)
  385. {
  386. RI(check_ft_startup);
  387. }
  388. else
  389. {
  390. OSVERSIONINFO version = {0};
  391. version.dwOSVersionInfoSize = sizeof(version);
  392. if (!GetVersionEx(&version)) ZeroMemory(&version, sizeof(OSVERSIONINFO));
  393. if (version.dwMajorVersion >= 6) // Vista
  394. {
  395. config_updated_ft_startup = 0;
  396. }
  397. else
  398. {
  399. RI(check_ft_startup);
  400. }
  401. }
  402. config_updated_ft_startup = 1;
  403. RS(browserbrand);
  404. RI(inet_mode);
  405. RI(pe_fontsize);
  406. RI(pe_direction);
  407. RI(ospb);
  408. RI(visplugin_num);
  409. RI(visplugin_priority);
  410. RI(visplugin_autoexec);
  411. RI(dspplugin_num);
  412. RI(sticon);
  413. RI(splash);
  414. RI(taskbar);
  415. RI(dropaotfs);
  416. RI(nomwheel);
  417. RI(ascb_new);
  418. RI(ttips);
  419. RI(keeponscreen);
  420. RI(riol);
  421. RI(whichicon);
  422. RI(whichicon2);
  423. RI(addtolist);
  424. RI(snap);
  425. RI(snaplen);
  426. RI(parent);
  427. RI(hilite);
  428. RI(disvis);
  429. RI(minst);
  430. RI(eqdsize);
  431. RI(pladv);
  432. RI(bifont);
  433. RI(bifont_alt);
  434. RI(autoload_eq);
  435. RI(playlist_recyclebin);
  436. RI(use_eq);
  437. RI(wx);
  438. RI(wy);
  439. RI(minimized);
  440. RI(aot);
  441. RI(shuffle);
  442. RI(repeat);
  443. RI(volume);
  444. RI(pan);
  445. RI(easymove);
  446. RI(dsize);
  447. RI(timeleftmode);
  448. RI(autoscrollname);
  449. RI(sa);
  450. RI(safire);
  451. RI(saref);
  452. RI(safalloff);
  453. RI(sa_peaks);
  454. RI(sa_peak_falloff);
  455. RI(eq_wx);
  456. RI(eq_wy);
  457. RI(eq_open);
  458. RI(mw_open);
  459. RI(pe_wx);
  460. RI(pe_wy);
  461. RI(pe_open);
  462. RI(pe_width);
  463. RI(pe_height);
  464. RI(pe_height_ws);
  465. RB(eq_limiter);
  466. RI(eq_type);
  467. RI(eq_frequencies);
  468. /*
  469. RI(si_wx);
  470. RI(si_wy);
  471. RI(si_height);
  472. RI(si_width);
  473. RI(si_autoshow);
  474. RI(si_autosize);
  475. RI(si_autohide);
  476. RI(si_open);
  477. */
  478. RI(video_wx);
  479. RI(video_wy);
  480. RI(video_open);
  481. RI(video_width);
  482. RI(video_height);
  483. RI(video_ratio1);
  484. RI(video_ratio2);
  485. RI(video_useratio);
  486. RI(windowshade);
  487. RI(preamp);
  488. RI(pilp);
  489. RI(randskin);
  490. if (!*config_cwd) // don't read if the user has overridden it through paths.ini
  491. RSW(cwd);
  492. RSW(skin);
  493. RI_NP(prefs_last_page);
  494. about_lastpage = prefs_last_page >> 8;
  495. prefs_last_page &= 255;
  496. prefs_rect.left = _r_i("prefs_wx", -1);
  497. prefs_rect.top = _r_i("prefs_wy", -1);
  498. alt3_rect.left = _r_i("alt3_wx", -1);
  499. alt3_rect.top = _r_i("alt3_wy", -1);
  500. editinfo_rect.left = _r_i("editinfo_wx", -1);
  501. editinfo_rect.top = _r_i("editinfo_wy", -1);
  502. ctrle_rect.left = _r_i("ctrle_wx", -1);
  503. ctrle_rect.top = _r_i("ctrle_wy", -1);
  504. about_rect.left = _r_i("about_wx", -1);
  505. about_rect.top = _r_i("about_wy", -1);
  506. loc_rect.left = _r_i("loc_wx", -1);
  507. loc_rect.top = _r_i("loc_wy", -1);
  508. time_rect.left = _r_i("time_wx", -1);
  509. time_rect.top = _r_i("time_wy", -1);
  510. load_rect.left = _r_i("load_wx", -1);
  511. load_rect.top = _r_i("load_wy", -1);
  512. RI(rofiob);
  513. RI(shownumsinpl);
  514. RS(outname);
  515. RI(usecursors);
  516. RI(fixtitles);
  517. RI(priority);
  518. if (!_r_i("fixpriority", 0))
  519. {
  520. if (config_priority > 1)
  521. {
  522. config_priority++;
  523. WI(priority);
  524. }
  525. _w_i("fixpriority", 1);
  526. }
  527. RI(shuffle_morph_rate);
  528. RI(useexttitles);
  529. RI(newverchk);
  530. RI(newverchk2);
  531. RI(newverchk3);
  532. RI(newverchk_rc);
  533. RI(user_consent_join_channels);
  534. RI(embedwnd_freesize);
  535. RB(video_vsync2);
  536. RI(video_aspectadj);
  537. RB(video_overlays);
  538. RB(video_gdiplus);
  539. RB(video_ddraw);
  540. RI(video_updsize);
  541. RB(video_autoopen);
  542. RB(video_autoclose);
  543. RI(video_noss);
  544. RI(video_logo);
  545. RI(video_osd);
  546. RB(video_yv12);
  547. RI(video_stopclose);
  548. RB(video_auto_fs);//RI(video_auto_fs); plague> changed to RB
  549. RI(dotitlenum);
  550. RI(dotasknum);
  551. RI(plscrollsize);
  552. RI(plmw2xscroll);
  553. RI(playback_thread_priority);
  554. RI(audio_bits);
  555. RB(audio_mono);
  556. RB(audio_surround);
  557. RB(audio_dither);
  558. RB(replaygain);
  559. RI(replaygain_mode);
  560. RI(replaygain_source);
  561. RB(replaygain_preferred_only);
  562. int gain10 = _r_i("replaygain_non_rg_gain", (int)(config_replaygain_non_rg_gain.GetFloat()*1000.0f));
  563. config_replaygain_non_rg_gain = (float)((float)gain10/1000.0f);
  564. gain10 = _r_i("replaygain_preamp", (int)(config_replaygain_preamp.GetFloat()*1000.0f));
  565. config_replaygain_preamp = (float)((float)gain10/1000.0f);
  566. RI(last_classic_skin_page);
  567. RI(last_playback_page);
  568. RI(last_fileinfo_page);
  569. RI(upd_mode);
  570. RSW(artwork_filter);
  571. RI(noml_ratings_prompt);
  572. RI(noml_ratings);
  573. RI(jtf_check);
  574. RI(block_img);
  575. // RI(video_contrast);
  576. // RI(video_brightness);
  577. RI(video_fliprgb);
  578. RI(video_remove_fs_on_stop);
  579. RI(wav_do_header);
  580. RI(wav_convert);
  581. RS(wav_ext);
  582. RI(no_visseh);
  583. _r_sW("playlist_custom_font", playlist_custom_fontW, sizeof(playlist_custom_fontW)/sizeof(*playlist_custom_fontW));
  584. if (!*playlist_custom_fontW) StringCbCopyW(playlist_custom_fontW, sizeof(playlist_custom_fontW), DEFAULT_FONT);
  585. WideCharToMultiByteSZ(CP_ACP, 0, playlist_custom_fontW, -1, playlist_custom_font, 128, 0, 0);
  586. RI(custom_plfont);
  587. RI(no_registry);
  588. RB(proxy80);
  589. RS(proxy);
  590. RS(defext);
  591. RSW(titlefmt);
  592. RSW(visplugin_name);
  593. RSW(dspplugin_name);
  594. RI(zeropadplnum);
  595. RI(wlz_menu);
  596. RB(accessibility_modalbeep);
  597. RB(accessibility_modalflash);
  598. {
  599. char eq_data[256] = {0, };
  600. int x;
  601. char *p = eq_data;
  602. RS_NP(eq_data);
  603. for (x = 0; x < 10; x ++)
  604. {
  605. int b = 0, s = 0;
  606. while (p && *p >= '0' && *p <= '9')
  607. {
  608. s = 1;b = b * 10 + *p++ -'0';
  609. }
  610. if (!s) break;
  611. p++;
  612. eq_tab[x] = min(63, max(b, 0));
  613. }
  614. }
  615. //SetCurrentDirectoryW(config_cwd);
  616. config_utf8=1;
  617. WI(utf8);
  618. if (!i)
  619. {
  620. if (!PathFileExistsW(M3U_FILE))
  621. {
  622. LoadPlaylistByExtension(OLD_M3U_FILE, L".m3u", 1, 1);
  623. savem3ufn(M3U_FILE, 0, 1);
  624. }
  625. else
  626. LoadPlaylistByExtension(M3U_FILE, L".m3u8", 1, 1);
  627. PlayList_setposition(config_pilp);
  628. }
  629. }
  630. int config_isregistered(wchar_t *ext)
  631. {
  632. wchar_t b[256] = {0};
  633. DWORD rval = 0, s = sizeof(b);
  634. if (config_no_registry) return 0;
  635. if (!ext[0]) return 0;
  636. StringCchPrintfW(b, 256, L".%s", ext);
  637. OSVERSIONINFO version = {0};
  638. version.dwOSVersionInfoSize = sizeof(version);
  639. if (!GetVersionEx(&version)) ZeroMemory(&version, sizeof(OSVERSIONINFO));
  640. if (IsWin8()) // Windows 8
  641. {
  642. // QueryAppIsDefault(..) was deprecated in Windows 8 so this is an alternative
  643. // which seems to work though how long it will keep working is currently unknown
  644. IApplicationAssociationRegistration* pAAR = 0;
  645. HRESULT hr = CoCreateInstance(CLSID_ApplicationAssociationRegistration,
  646. NULL, CLSCTX_INPROC,
  647. __uuidof(IApplicationAssociationRegistration),
  648. (void**)&pAAR);
  649. if (SUCCEEDED(hr) && pAAR)
  650. {
  651. LPWSTR app = 0;
  652. /*hr = */pAAR->QueryCurrentDefault(b,
  653. AT_FILEEXTENSION,
  654. AL_EFFECTIVE,
  655. &app);
  656. pAAR->Release();
  657. if (IsPlaylistExtension(ext))
  658. {
  659. if(!lstrcmpiW(WINAMP_PLAYLISTW, app)){ rval = 1; }
  660. }
  661. else if (!_wcsicmp(ext, L"wsz") || !_wcsicmp(ext, L"wal") || !_wcsicmp(ext, L"wpz"))
  662. {
  663. if(!lstrcmpiW(WINAMP_SKINZIPW, app)){ rval = 1; }
  664. }
  665. else if (!_wcsicmp(ext, L"wlz"))
  666. {
  667. if(!lstrcmpiW(WINAMP_LANGZIPW, app)){ rval = 1; }
  668. }
  669. else
  670. {
  671. wchar_t str[64] = {0};
  672. StringCchPrintfW(str, 64, L"%s%hs", WINAMP_FILEW, b);
  673. if(!lstrcmpiW(str, app)){ rval = 1; }
  674. }
  675. if (app) CoTaskMemFree(app);
  676. }
  677. }
  678. else if (version.dwMajorVersion >= 6) // Vista
  679. {
  680. IApplicationAssociationRegistration* pAAR = NULL;
  681. HRESULT hr = CoCreateInstance(CLSID_ApplicationAssociationRegistration,
  682. NULL, CLSCTX_INPROC,
  683. __uuidof(IApplicationAssociationRegistration),
  684. (void**)&pAAR);
  685. if (SUCCEEDED(hr) && pAAR)
  686. {
  687. BOOL hasExt=FALSE;
  688. hr = pAAR->QueryAppIsDefault(b,
  689. AT_FILEEXTENSION,
  690. AL_EFFECTIVE,
  691. AutoWide(app_name),
  692. &hasExt);
  693. pAAR->Release();
  694. if (SUCCEEDED(hr))
  695. {
  696. rval=!!hasExt;
  697. }
  698. }
  699. }
  700. else
  701. {
  702. HKEY key = NULL;
  703. if (RegOpenKeyW(HKEY_CLASSES_ROOT, b, &key) != ERROR_SUCCESS) return 0;
  704. DWORD vt = 0;
  705. if (RegQueryValueExW(key, NULL, 0, &vt, (LPBYTE)b, &s) == ERROR_SUCCESS)
  706. {
  707. if (vt != REG_SZ || (wcsncmp(b, WINAMP_FILEW, wcslen(WINAMP_FILEW)) &&
  708. wcscmp(b, WINAMP_PLAYLISTW) &&
  709. wcscmp(b, WINAMP_SKINZIPW) &&
  710. wcscmp(b, WINAMP_LANGZIPW))) rval = 0;
  711. else rval = 1;
  712. }
  713. else rval = 0;
  714. RegCloseKey(key);
  715. }
  716. return rval;
  717. }
  718. bool allowed_extension(wchar_t *ext)
  719. {
  720. const wchar_t* blocked[] = {L"exe", L"dll",
  721. L"jpg", L"jpeg", L"gif", L"bmp",
  722. L"png", L"tif", L"tiff"};
  723. // ensure we block at least 'exe' and 'dll', and images if not disabled
  724. for (size_t i = 0; i < (config_block_img ? ARRAYSIZE(blocked) : 2); i++)
  725. {
  726. if (!_wcsicmp(ext, blocked[i])) return false;
  727. }
  728. return true;
  729. }
  730. void config_register(wchar_t *ext, int reg)
  731. {
  732. const wchar_t *which_str = WINAMP_FILEW;
  733. if (config_no_registry) return ;
  734. if (!ext[0]) return ;
  735. if (!allowed_extension(ext)) return ; //windows=gay
  736. IFileTypeRegistrar *registrar=0;
  737. if (GetRegistrar(&registrar, true) == 0 && registrar)
  738. {
  739. wchar_t family_str[256] = {0};
  740. if (IsPlaylistExtension(ext))
  741. which_str = WINAMP_PLAYLISTW;
  742. else if (!_wcsicmp(ext, L"wsz") || !_wcsicmp(ext, L"wal") || !_wcsicmp(ext, L"wpz"))
  743. which_str = WINAMP_SKINZIPW;
  744. else if (!_wcsicmp(ext, L"wlz"))
  745. which_str = WINAMP_LANGZIPW;
  746. else
  747. {
  748. StringCchPrintfW(family_str, 256, L"%s.%s", WINAMP_FILEW, ext);
  749. wchar_t family_description[256] = {0};
  750. if (in_get_extended_fileinfoW(family_str, L"family", family_description, 255) && family_description[0])
  751. {
  752. which_str=family_str;
  753. if (reg)
  754. config_setup_filetype(family_str, family_description, 0);
  755. }
  756. }
  757. if (reg && !_wcsicmp(ext, L"asx"))
  758. {
  759. wchar_t programname[MAX_PATH] = {0};
  760. GetModuleFileNameW(hMainInstance, programname, MAX_PATH);
  761. regmimetype(L"video/x-asx", programname, L".asx", 0);
  762. regmimetype(L"video/asx", programname, L".asx", 0);
  763. regmimetype(L"video/x-ms-asf", programname, L".asx", 0);
  764. }
  765. if (reg && !_wcsicmp(ext, L"wal"))
  766. {
  767. wchar_t programname[MAX_PATH] = {0};
  768. GetModuleFileNameW(hMainInstance, programname, MAX_PATH);
  769. regmimetype(L"interface/x-winamp3-skin", programname, L".wal", 0);
  770. }
  771. if (reg && !_wcsicmp(ext, L"wsz"))
  772. {
  773. wchar_t programname[MAX_PATH] = {0};
  774. GetModuleFileNameW(hMainInstance, programname, MAX_PATH);
  775. regmimetype(L"interface/x-winamp-skin", programname, L".wsz", 0);
  776. }
  777. if (reg && !_wcsicmp(ext, L"wlz"))
  778. {
  779. wchar_t programname[MAX_PATH] = {0};
  780. GetModuleFileNameW(hMainInstance, programname, MAX_PATH);
  781. regmimetype(L"interface/x-winamp-lang", programname, L".wlz", 0);
  782. }
  783. if (reg && !_wcsicmp(ext, L"pls"))
  784. {
  785. wchar_t programname[MAX_PATH] = {0};
  786. GetModuleFileNameW(hMainInstance, programname, MAX_PATH);
  787. regmimetype(L"audio/x-scpls", programname, L".pls", 0);
  788. regmimetype(L"audio/scpls", programname, L".pls", 0);
  789. }
  790. if (reg && !_wcsicmp(ext, L"wma"))
  791. {
  792. wchar_t programname[MAX_PATH] = {0};
  793. GetModuleFileNameW(hMainInstance, programname, MAX_PATH);
  794. regmimetype(L"audio/x-ms-wma", programname, L".wma", 1);
  795. regmimetype(L"application/x-msdownload", programname, L".wma", 1);
  796. }
  797. if (reg && !_wcsicmp(ext, L"m3u"))
  798. {
  799. wchar_t programname[MAX_PATH] = {0};
  800. GetModuleFileNameW(hMainInstance, programname, MAX_PATH);
  801. regmimetype(L"audio/x-mpegurl", programname, L".m3u", 0);
  802. regmimetype(L"audio/mpegurl", programname, L".m3u", 0);
  803. }
  804. if (reg && !_wcsicmp(ext, L"mp3"))
  805. {
  806. wchar_t programname[MAX_PATH] = {0};
  807. GetModuleFileNameW(hMainInstance, programname, MAX_PATH);
  808. regmimetype(L"audio/x-mpeg", programname, L".mp3", 1);
  809. regmimetype(L"audio/x-mp3", programname, L".mp3", 1);
  810. regmimetype(L"audio/x-mpg", programname, L".mp3", 1);
  811. regmimetype(L"audio/mp3", programname, L".mp3", 1);
  812. regmimetype(L"audio/mpg", programname, L".mp3", 1);
  813. regmimetype(L"audio/mpeg", programname, L".mp3", 1);
  814. }
  815. wchar_t b[128] = {0};
  816. StringCchPrintfW(b, 128, L".%s", ext);
  817. CharLowerBuffW(b, ARRAYSIZE(b));
  818. if (reg)
  819. registrar->RegisterType(b, which_str, AutoWide(app_name));
  820. else
  821. {
  822. // avoid removing WINAMP_FILEW as this will break some parts
  823. // this will generally happen from 3rd party plugins where
  824. // no %family% will be correctly returned in the relevant
  825. if(_wcsicmp(which_str, WINAMP_FILEW))
  826. {
  827. registrar->UnregisterType(b, which_str, AutoWide(app_name), IsPlaylistExtension(ext));
  828. }
  829. }
  830. registrar->Release();
  831. }
  832. }
  833. void regmimetype(const wchar_t *mtype, const wchar_t *programname, const wchar_t *ext, int nsonly)
  834. {
  835. if (config_no_registry)
  836. return ;
  837. IFileTypeRegistrar *registrar=0;
  838. if (GetRegistrar(&registrar, true) == 0 && registrar)
  839. {
  840. registrar->RegisterMIMEType(mtype, programname, ext, nsonly);
  841. registrar->Release();
  842. }
  843. }
  844. void trimPathW(wchar_t *pathStart)
  845. {
  846. PathRemoveBlanksW(pathStart);
  847. PathRemoveBackslashW(pathStart);
  848. }
  849. void config_setinifile(wchar_t *inifile)
  850. {
  851. lstrcpynW(INI_FILE, inifile, sizeof(INI_FILE) / sizeof(INI_FILE[0]));
  852. }
  853. void config_setinidir(const wchar_t *inidir)
  854. {
  855. if (SUCCEEDED(StringCchCopyW(CONFIGDIR, MAX_PATH, inidir)))
  856. trimPathW(CONFIGDIR);
  857. else
  858. CONFIGDIR[0] = 0;
  859. }
  860. void config_setm3udir(const wchar_t *m3udir)
  861. {
  862. if (SUCCEEDED(StringCchCopyW(M3UDIR, MAX_PATH, m3udir)))
  863. trimPathW(M3UDIR);
  864. else
  865. M3UDIR[0] = 0;
  866. }
  867. void config_setm3ubase(const wchar_t *m3ubase)
  868. {
  869. if (SUCCEEDED(StringCchCopyW(M3UBASE, MAX_PATH, m3ubase)))
  870. trimPathW(M3UBASE);
  871. else
  872. M3UBASE[0] = 0;
  873. }
  874. void init_config()
  875. {
  876. GetModuleFileNameW(hMainInstance, PROGDIR, MAX_PATH);
  877. PathRemoveFileSpecW(PROGDIR);
  878. SetEnvironmentVariableW(L"WINAMP_PROGRAM_DIR", PROGDIR);
  879. wchar_t winamp_root[MAX_PATH] = {0};
  880. StringCchCopyW(winamp_root, MAX_PATH, PROGDIR);
  881. PathStripToRootW(winamp_root);
  882. SetEnvironmentVariableW(L"WINAMP_ROOT_DIR", winamp_root);
  883. }
  884. void setup_config(void)
  885. {
  886. if (!CONFIGDIR[0])
  887. StringCchCopyW(CONFIGDIR, MAX_PATH, PROGDIR);
  888. if (!M3UDIR[0])
  889. StringCchCopyW(M3UDIR, MAX_PATH, CONFIGDIR);
  890. if (!M3UBASE[0])
  891. StringCchCopyW(M3UBASE, MAX_PATH, M3UDIR);
  892. CreateDirectoryW(M3UDIR, NULL);
  893. CreateDirectoryW(CONFIGDIR, NULL);
  894. // basic config files
  895. PathCombineW(OLD_M3U_FILE, M3UDIR, L"Winamp.m3u");
  896. PathCombineW(M3U_FILE, M3UDIR, L"Winamp.m3u8");
  897. PathCombineW(BOOKMARKFILE, CONFIGDIR, L"Winamp.bm");
  898. PathCombineW(BOOKMARKFILE8, CONFIGDIR, L"Winamp.bm8");
  899. // just make sure if a winamp.bm8 doesn't exist then
  900. // go make one from winamp.bm - implemented for 5.58+
  901. if(!PathFileExistsW(BOOKMARKFILE8))
  902. {
  903. CopyFileW(BOOKMARKFILE,BOOKMARKFILE8,FALSE);
  904. }
  905. PathCombineW(EQDIR1, CONFIGDIR, L"Winamp.q1");
  906. PathCombineW(EQDIR2, CONFIGDIR, L"Winamp.q2");
  907. wchar_t tempPath[MAX_PATH] = {0};
  908. GetTempPathW(MAX_PATH, tempPath);
  909. PathCombineW(TEMP_FILE, tempPath, L"Winamp.tmp");
  910. PathCombineW(DEMOMP3, M3UDIR, L"demo.mp3");
  911. PathCombineW(JSAPI2_INIFILE, CONFIGDIR, L"jsapisec.ini");
  912. PathCombineW(ML_INI_FILE, CONFIGDIR, L"Plugins\\gen_ml.ini");
  913. // override INI_FILE if specified
  914. if (INI_FILE[0])
  915. {
  916. if (PathIsFileSpecW(INI_FILE) || PathIsRelativeW(INI_FILE))
  917. {
  918. wchar_t temp[MAX_PATH] = {0};
  919. PathCombineW(temp, CONFIGDIR, INI_FILE);
  920. lstrcpynW(INI_FILE, temp, MAX_PATH);
  921. }
  922. }
  923. else
  924. PathCombineW(INI_FILE, CONFIGDIR, L"Winamp.ini");
  925. // maintain a ansi version of INI_FILE for some aspects
  926. StringCchCopyA(INI_FILEA, MAX_PATH, AutoCharFn(INI_FILE));
  927. RI(utf8);
  928. // skin and plugin directories
  929. PathCombineW(SKINDIR, PROGDIR, L"Skins");
  930. PathCombineW(PLUGINDIR, PROGDIR, L"Plugins");
  931. PathCombineW(SYSPLUGINDIR, PROGDIR, L"System");
  932. PathCombineW(SKINDIR, PROGDIR, L"Skins");
  933. PathCombineW(LANGDIR, PROGDIR, L"Lang");
  934. PathCombineW(VISDIR, PROGDIR, L"Plugins");
  935. PathCombineW(DSPDIR, PROGDIR, L"Plugins");
  936. // override skin/plugin directories from config
  937. {
  938. wchar_t bW[MAX_PATH] = {0}, *pW;
  939. bW[0]=0;
  940. _r_sW("PluginDir", bW, MAX_PATH);
  941. pW = bW;
  942. while (pW && (*pW == L' ' || *pW == L'\t')) pW++;
  943. if (pW && *pW)
  944. {
  945. StringCchCopyW(PLUGINDIR, MAX_PATH, bW);
  946. }
  947. ZeroMemory(bW, sizeof(bW));
  948. _r_sW("DSPDir", bW, MAX_PATH);
  949. pW = bW;
  950. while (pW && (*pW == L' ' || *pW == L'\t')) pW++;
  951. if (pW && *pW)
  952. {
  953. StringCchCopyW(DSPDIR, MAX_PATH, bW);
  954. }
  955. ZeroMemory(bW, sizeof(bW));
  956. _r_sW("VISDir", bW, MAX_PATH);
  957. pW = bW;
  958. while (pW && (*pW == L' ' || *pW == L'\t')) pW++;
  959. if (pW && *pW)
  960. {
  961. StringCchCopyW(VISDIR, MAX_PATH, bW);
  962. }
  963. ZeroMemory(bW, sizeof(bW));
  964. _r_sW("SkinDir", bW, MAX_PATH);
  965. pW = bW;
  966. while (pW && (*pW == L' ' || *pW == L'\t')) pW++;
  967. if (pW && *pW)
  968. {
  969. StringCchCopyW(SKINDIR, MAX_PATH, bW);
  970. }
  971. ZeroMemory(bW, sizeof(bW));
  972. _r_sW("LangDir", bW, MAX_PATH);
  973. pW = bW;
  974. while (pW && (*pW == L' ' || *pW == L'\t')) pW++;
  975. if (pW && *pW)
  976. {
  977. StringCchCopyW(LANGDIR, MAX_PATH, bW);
  978. }
  979. }
  980. // create a skin temp directory, too
  981. wchar_t buf[MAX_PATH] = {0};
  982. GetTempPathW(MAX_PATH, buf);
  983. GetTempFileNameW(buf, L"WAS", GetTickCount(), SKINTEMPDIR);
  984. // create a lang temp directory, too by
  985. // trying to use part of the wlz's name
  986. // so it's easier to see when debugging
  987. // e.g. W<lang>XXXX.tmp otherwise it'll
  988. // revert back to the older WLZXXXX.tmp
  989. config_load_langpack_var();
  990. if (wcstok(config_langpack, L"-"))
  991. {
  992. wchar_t *p = wcstok(NULL, L"-");
  993. if (p)
  994. {
  995. wchar_t buf2[4] = {0};
  996. StringCchPrintfW(buf2, 4, L"W%s", p);
  997. CharUpperBuffW(buf2, 4);
  998. GetTempFileNameW(buf, buf2, GetTickCount(), LANGTEMPDIR);
  999. }
  1000. else
  1001. {
  1002. GetTempFileNameW(buf, L"WLZ", GetTickCount(), LANGTEMPDIR);
  1003. }
  1004. }
  1005. else
  1006. {
  1007. GetTempFileNameW(buf, L"WLZ", GetTickCount(), LANGTEMPDIR);
  1008. }
  1009. RI(minst);
  1010. }
  1011. BOOL config_removedircontext(BOOL use_fallback)
  1012. {
  1013. if (config_no_registry)
  1014. return TRUE;
  1015. IFileTypeRegistrar *registrar=0;
  1016. if (GetRegistrar(&registrar, !use_fallback) == 0 && registrar)
  1017. {
  1018. registrar->RemoveDirectoryContext(WINAMP_PLAYW);
  1019. registrar->RemoveDirectoryContext(WINAMP_ENQUEUEW);
  1020. registrar->RemoveDirectoryContext(WINAMP_BOOKMARKW);
  1021. registrar->Release();
  1022. return TRUE;
  1023. }
  1024. return FALSE;
  1025. }
  1026. int config_iscdplayer(void)
  1027. {
  1028. DWORD r = 0, s;
  1029. HKEY mp3Key;
  1030. char buf[MAX_PATH], buf2[MAX_PATH] = "\"";;
  1031. if (!GetModuleFileNameA(hMainInstance, buf2 + 1, sizeof(buf2) - 8)) return 0;
  1032. if (RegOpenKeyA(HKEY_CLASSES_ROOT, "AudioCD\\shell\\play\\command", &mp3Key) != ERROR_SUCCESS) return 0;
  1033. StringCchCatA(buf2, MAX_PATH, "\" %1");
  1034. s = sizeof(buf);
  1035. if (RegQueryValueEx(mp3Key, NULL, 0, NULL, (LPBYTE)buf, &s) == ERROR_SUCCESS)
  1036. {
  1037. if (!lstrcmpiA(buf, buf2)) r = 1;
  1038. }
  1039. RegCloseKey(mp3Key);
  1040. return r;
  1041. }
  1042. BOOL config_regcdplayer(int reg, int mode)
  1043. {
  1044. if (config_no_registry) return TRUE;
  1045. IFileTypeRegistrar *registrar=0;
  1046. if (GetRegistrar(&registrar, !mode) == 0 && registrar)
  1047. {
  1048. wchar_t programName[MAX_PATH] = {0};
  1049. if (GetModuleFileNameW(hMainInstance, programName, MAX_PATH))
  1050. {
  1051. if (reg)
  1052. registrar->RegisterCDPlayer(programName);
  1053. else
  1054. registrar->UnregisterCDPlayer(programName);
  1055. }
  1056. registrar->Release();
  1057. return TRUE;
  1058. }
  1059. return FALSE;
  1060. }
  1061. void config_load_langpack_var(void)
  1062. {
  1063. RSW(langpack);
  1064. }
  1065. void config_save_langpack_var(void)
  1066. {
  1067. WSW(langpack);
  1068. }
  1069. void config_agent_add(void)
  1070. {
  1071. if (config_no_registry) return;
  1072. IFileTypeRegistrar *registrar=0;
  1073. if (GetRegistrar(&registrar, true) == 0 && registrar)
  1074. {
  1075. wchar_t exe_name[MAX_PATH + 2] = {0};
  1076. GetModuleFileNameW(hMainInstance, exe_name, sizeof(exe_name)/sizeof(wchar_t));
  1077. PathRemoveFileSpecW(exe_name);
  1078. PathCombineW(exe_name, exe_name, L"winampa.exe");
  1079. PathQuoteSpacesW(exe_name);
  1080. registrar->AddAgent(exe_name);
  1081. registrar->Release();
  1082. }
  1083. Lang_LocaliseAgentOnTheFly(TRUE);
  1084. }
  1085. void config_agent_remove(void)
  1086. {
  1087. if (config_no_registry) return ;
  1088. IFileTypeRegistrar *registrar=0;
  1089. if (GetRegistrar(&registrar, true) == 0 && registrar)
  1090. {
  1091. HWND hwnd = FindWindowW(L"WinampAgentMain", NULL);
  1092. if (hwnd)
  1093. {
  1094. SendMessageW(hwnd, WM_CLOSE, 0, 0);
  1095. }
  1096. registrar->RemoveAgent();
  1097. registrar->Release();
  1098. }
  1099. Lang_LocaliseAgentOnTheFly(FALSE);
  1100. }
  1101. BOOL config_register_capability(wchar_t *ext, int mode)
  1102. {
  1103. if (config_no_registry) return TRUE;
  1104. IFileTypeRegistrar *registrar=0;
  1105. if (GetRegistrar(&registrar, !mode) == 0 && registrar)
  1106. {
  1107. WCHAR szApplication[128] = {0}, szExtension[64] = {0}, szProgId[256] = {0};
  1108. size_t required = MultiByteToWideCharSZ(CP_ACP, 0, app_name, -1, NULL, 0);
  1109. if (required > ARRAYSIZE(szApplication))
  1110. return TRUE;
  1111. if (0 == MultiByteToWideCharSZ(CP_ACP, 0, app_name, -1, szApplication, ARRAYSIZE(szApplication)))
  1112. return TRUE;
  1113. LPWSTR cursor = szProgId;
  1114. size_t remaining = ARRAYSIZE(szProgId);
  1115. if (FAILED(StringCchCopyExW(cursor, remaining, WINAMP_FILEW, &cursor, &remaining, 0)))
  1116. return TRUE;
  1117. if (FAILED(StringCchCopyExW(cursor, remaining, L".", &cursor, &remaining, 0)))
  1118. return TRUE;
  1119. if (FAILED(StringCchCopyExW(cursor, remaining, ext/*szExtension*/, &cursor, &remaining, 0)))
  1120. return TRUE;
  1121. //CharLowerW(szExtension);
  1122. registrar->RegisterCapability(szApplication, szProgId, szExtension);
  1123. registrar->Release();
  1124. return TRUE;
  1125. }
  1126. return FALSE;
  1127. }