diff options
author | Jean-Francois Mauguit <jfmauguit@mac.com> | 2024-09-24 09:03:25 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-24 09:03:25 -0400 |
commit | bab614c421ed7ae329d26bf028c4a3b1d2450f5a (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/Winamp/Config.cpp | |
parent | 4bde6044fddf053f31795b9eaccdd2a5a527d21f (diff) | |
parent | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (diff) | |
download | winamp-bab614c421ed7ae329d26bf028c4a3b1d2450f5a.tar.gz |
Merge pull request #5 from WinampDesktop/community
Merge to main
Diffstat (limited to 'Src/Winamp/Config.cpp')
-rw-r--r-- | Src/Winamp/Config.cpp | 1251 |
1 files changed, 1251 insertions, 0 deletions
diff --git a/Src/Winamp/Config.cpp b/Src/Winamp/Config.cpp new file mode 100644 index 00000000..1a5199ad --- /dev/null +++ b/Src/Winamp/Config.cpp @@ -0,0 +1,1251 @@ +/** (c) Nullsoft, Inc. C O N F I D E N T I A L +** Filename: +** Project: +** Description: +** Author: +** Created: +**/ + +#ifndef CONFIG_IMPL +#define CONFIG_IMPL +#endif +#include "Main.h" +#include "config.h" +#include "WinampAttributes.h" +#include "../nu/AutoWide.h" +#include "../nu/AutoChar.h" +#include "../nu/ns_wc.h" +#include "../nu/AutoLock.h" +#include "../nu/AutoCharFn.h" +#include "../Elevator/FileTypeRegistrar.h" +#include "main.hpp" +#include <shobjidl.h> + +#if (_MSC_VER < 1500) +typedef struct tagBIND_OPTS3 : tagBIND_OPTS2 +{ + HWND hwnd; +} BIND_OPTS3, * LPBIND_OPTS3; +#endif +static HRESULT CoCreateInstanceAsAdmin(HWND hwnd, REFCLSID rclsid, REFIID riid, void ** ppv) +{ + BIND_OPTS3 bo; + WCHAR wszCLSID[50] = {0}; + WCHAR wszMonikerName[300] = {0}; + + StringFromGUID2(rclsid, wszCLSID, sizeof(wszCLSID)/sizeof(wszCLSID[0])); + HRESULT hr = StringCchPrintfW(wszMonikerName, sizeof(wszMonikerName)/sizeof(wszMonikerName[0]), L"Elevation:Administrator!new:%s", wszCLSID); + if (FAILED(hr)) + return hr; + memset(&bo, 0, sizeof(bo)); + bo.cbStruct = sizeof(bo); + bo.hwnd = hwnd; + bo.dwClassContext = CLSCTX_LOCAL_SERVER; + return CoGetObject(wszMonikerName, &bo, riid, ppv); +} + +static bool NeedElevation() +{ + return !IsUserAnAdmin(); +} + +static Nullsoft::Utility::LockGuard registrarGuard; +static const GUID ftr_guid = + { 0x3B29AB5C, 0x52CB, 0x4a36, { 0x93,0x14,0xE3,0xFE,0xE0,0xBA,0x74,0x68 } }; +static IFileTypeRegistrar *masterRegistrar; +static FileTypeRegistrar builtIn; +bool usingBuiltIn = false; +int GetRegistrar(IFileTypeRegistrar **registrar, BOOL use_fallback) +{ + Nullsoft::Utility::AutoLock autolock(registrarGuard); + // attempt to re-get an elevated object as needed + // i.e. if user selects no but wants to try again + // then we need to try going elevated again + if (!masterRegistrar || usingBuiltIn) + { +#if 1 // benski> on Vista, we need this object to run out-of-process so it can be elevated to Administrator + // without elevating Winamp itself - see http://msdn2.microsoft.com/en-us/ms679687.aspx + OSVERSIONINFO version = {0}; + version.dwOSVersionInfoSize = sizeof(version); + if (!GetVersionEx(&version)) ZeroMemory(&version, sizeof(OSVERSIONINFO)); + if (version.dwMajorVersion >= 6 && NeedElevation()) // Vista + { + IFileTypeRegistrar *registrar = 0; + HRESULT hr = CoCreateInstanceAsAdmin(0, ftr_guid, __uuidof(IFileTypeRegistrar), (void**)®istrar); + if (SUCCEEDED(hr) && registrar) + { + if (masterRegistrar) masterRegistrar->Release(); + masterRegistrar = registrar; + usingBuiltIn = false; + } + else + { + if (!use_fallback) + { + if (registrar) registrar->Release(); + if (masterRegistrar) masterRegistrar->Release(); + registrar = masterRegistrar = 0; + usingBuiltIn = false; + return 1; + } + } + } +#if 0 + else /* benski> on earlier OS's just for testing purposes, we'll get rid of this totally once the COM stuff is worked out */ + { + CoCreateInstance(ftr_guid, NULL, CLSCTX_LOCAL_SERVER, __uuidof(IFileTypeRegistrar), (void**)&masterRegistrar); + } +#endif +#endif + } + + if (!masterRegistrar) /* wasn't registered? we'll use our internal version (but it won't work well on Vista+) */ + { + masterRegistrar = &builtIn; + usingBuiltIn = true; + } + + if (masterRegistrar) + { + *registrar = masterRegistrar; + masterRegistrar->AddRef(); + return 0; + } + return 1; +} + +void RemoveRegistrar() +{ + Nullsoft::Utility::AutoLock autolock(registrarGuard); + if (masterRegistrar) masterRegistrar->Release(); + masterRegistrar = 0; + usingBuiltIn = false; +} + +int _r_i(char *name, int def) +{ + return GetPrivateProfileIntA(app_name, name, def, INI_FILEA); +} + +#define RI(x) (( config_##x ) = _r_i(#x,( config_##x ))) +#define RI_NP(x) (( x ) = _r_i(#x,( x ))) +#define RB(x) (( config_##x ) = !!_r_i(#x,( config_##x ))) +void _w_i(char *name, intptr_t d) +{ + char str[120] = {0}; + StringCchPrintfA(str, 120, "%d", d); + WritePrivateProfileStringA(app_name, name, str, INI_FILEA); +} +#define WI(x) _w_i(#x,( config_##x )) +#define WI_NP(x) _w_i(#x,( x )) + +void _r_s(char *name, char *data, int mlen) +{ + char utf8_data[2048] = {0}; + wchar_t utf16_data[2048] = {0}; + char buf[2048] = {0}; + StringCchCopyA(buf, 2048, data); + GetPrivateProfileStringA(app_name, name, buf, utf8_data, 2048, INI_FILEA); + MultiByteToWideCharSZ(CP_UTF8, 0, utf8_data, -1, utf16_data, 2048); + WideCharToMultiByteSZ(CP_ACP, 0, utf16_data, -1, data, mlen, 0, 0); +} +#define RS(x) (_r_s(#x,config_##x,sizeof(config_##x))) +#define RS_NP(x) (_r_s(#x,x,sizeof(x))) + +void _r_sW(const char *name, wchar_t *data, int mlen) +{ + char utf8_data[2048] = {0}; + char default_data[2048] = {0}; + WideCharToMultiByteSZ(config_utf8?CP_UTF8:CP_ACP, 0, data, -1, default_data, 2048,0,0); + GetPrivateProfileStringA(app_name, name, default_data, utf8_data, 2048, INI_FILEA); + MultiByteToWideCharSZ(config_utf8?CP_UTF8:CP_ACP, 0, utf8_data, -1, data, mlen); +} +#define RSW(x) (_r_sW(#x,config_##x,sizeof(config_##x)/sizeof(wchar_t))) +#define RSW_NP(x) (_r_sW(#x,x,sizeof(x)/sizeof(wchar_t))) + +void _w_s(char *name, char *data) +{ + WritePrivateProfileStringA(app_name, name, AutoChar(AutoWide(data), CP_UTF8), INI_FILEA); +} +#define WS(x) (_w_s(#x,config_##x)) +#define WS_NP(x) (_w_s(#x,x)) + +void _w_sW(const char *name, const wchar_t *data) +{ + WritePrivateProfileStringA(app_name, name, AutoChar(data, CP_UTF8), INI_FILEA); // TODO: don't want autowide here +} +#define WSW(x) (_w_sW(#x,config_##x)) +#define WSW_NP(x) (_w_sW(#x,x)) + + +void config_write(int i) +{ + config_pilp = PlayList_getPosition(); + //GetCurrentDirectoryW(MAX_PATH, config_cwd); + if (i && plneedsave) + { + // changed 5.64 to only save if there was a change as this can save a + // decent amount of time on closing with a large unmodified playlist. + savem3ufn(M3U_FILE, 0, 1); + savem3ufn(OLD_M3U_FILE, 0, 1); + } + + config_utf8=1; + WI(utf8); + + if (i != 1) // write mostly unused stuff, like proxy, plugin names, etc + { + WS(defext); + WSW(titlefmt); + WI(proxy80); + WS(proxy); + WSW(visplugin_name); + WSW(dspplugin_name); + WI(check_ft_startup); + WI(updated_ft_startup); + WI(visplugin_num); + WI(pe_fontsize); + WI(pe_direction); + WI(visplugin_priority); + WI(visplugin_autoexec); + WI(dspplugin_num); + WI(sticon); + WI(splash); + WI(taskbar); + WI(dropaotfs); + WI(nomwheel); + WI(ascb_new); + WI(ttips); + WI(riol); + WI(minst); + WI(whichicon); + WI(whichicon2); + WI(addtolist); + WI(snap); + WI(snaplen); + WI(parent); + WI(hilite); + WI(disvis); + WI(rofiob); + WI(shownumsinpl); + WI(keeponscreen); + WI(eqdsize); + WI(usecursors); + WI(fixtitles); + WI(priority); + WI(shuffle_morph_rate); + WI(useexttitles); + WI(bifont); + WI(bifont_alt); + WI(dotitlenum); + WI(dotasknum); + WI(plscrollsize); + WI(plmw2xscroll); + WI(inet_mode); + WI(ospb); + WI(embedwnd_freesize); + WI(no_visseh); + } + WI(newverchk); + WI(newverchk2); + WI(newverchk3); + WI(newverchk_rc); + WI(user_consent_join_channels); + // write everything else + { + int config_prefs_last_page = prefs_last_page | (about_lastpage << 8); + WI(prefs_last_page); + prefs_last_page &= 255; + + _w_i("prefs_wx", prefs_rect.left); + _w_i("prefs_wy", prefs_rect.top); + + _w_i("alt3_wx", alt3_rect.left); + _w_i("alt3_wy", alt3_rect.top); + + _w_i("editinfo_wx", editinfo_rect.left); + _w_i("editinfo_wy", editinfo_rect.top); + + _w_i("ctrle_wx", ctrle_rect.left); + _w_i("ctrle_wy", ctrle_rect.top); + + _w_i("about_wx", about_rect.left); + _w_i("about_wy", about_rect.top); + + _w_i("loc_wx", loc_rect.left); + _w_i("loc_wy", loc_rect.top); + + _w_i("time_wx", time_rect.left); + _w_i("time_wy", time_rect.top); + + _w_i("load_wx", load_rect.left); + _w_i("load_wy", load_rect.top); + } + WI(autoload_eq); + WI(playlist_recyclebin); + WI(use_eq); + WI(eq_ws); + WI(wx); + WI(wy); + WI(minimized); + WI(aot); + WI(shuffle); + WI(repeat); + WI(volume); + WI(pan); + WI(easymove); + WI(dsize); + WI(timeleftmode); + WI(autoscrollname); + WI(sa); + WI(safire); + WI(saref); + WI(safalloff); + WI(sa_peaks); + WI(sa_peak_falloff); + WI(eq_wx); + WI(eq_wy); + WI(eq_open); + WI(mw_open); + WI(pe_wx); + WI(pe_wy); + WI(pe_open); + WI(pe_width); + WI(pe_height); + WI(pe_height_ws); + + WI(eq_limiter); + WI(eq_type); + WI(eq_frequencies); + + /* + WI(si_wx); + WI(si_wy); + WI(si_width); + WI(si_height); + WI(si_autoshow); + WI(si_autosize); + WI(si_autohide); + WI(si_open); + */ + + WI(video_wx); + WI(video_wy); + WI(video_open); + WI(video_width); + WI(video_height); + WI(video_ratio1); + WI(video_ratio2); + WI(video_useratio); + WI(windowshade); + WI(preamp); + WI(pilp); + WI(randskin); + WSW(cwd); + WSW(skin); + WS(outname); + WI(pladv); + { + char config_eq_data[256] = {0}; + StringCchPrintfA(config_eq_data, 256, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d", + eq_tab[0], eq_tab[1], eq_tab[2], eq_tab[3], eq_tab[4], + eq_tab[5], eq_tab[6], eq_tab[7], eq_tab[8], eq_tab[9]); + WS(eq_data); + } + WI(video_vsync2); + WI(video_aspectadj); + WI(video_overlays); + WI(video_gdiplus); + WI(video_ddraw); + WI(video_updsize); + WI(video_autoopen); + WI(video_autoclose); + WI(video_noss); + WI(video_logo); + WI(video_osd); + WI(video_yv12); + WI(video_stopclose); + WI(video_auto_fs); + + WI(playback_thread_priority); + WI(audio_bits); + WI(audio_mono); + WI(audio_surround); + WI(audio_dither); + WI(replaygain); + WI(replaygain_mode); + WI(replaygain_source); + WI(replaygain_preferred_only); + _w_i("replaygain_non_rg_gain", (intptr_t)(config_replaygain_non_rg_gain.GetFloat()*1000.0f)); + _w_i("replaygain_preamp", (intptr_t)(config_replaygain_preamp.GetFloat()*1000.0f)); + + // WI(video_contrast); + // WI(video_brightness); + WI(video_fliprgb); + WI(video_remove_fs_on_stop); + WI(wav_do_header); + WI(wav_convert); + WS(wav_ext); + _w_sW("playlist_custom_font", playlist_custom_fontW); + WI(custom_plfont); + WI(no_registry); + WI(last_classic_skin_page); + WI(last_playback_page); + WI(last_fileinfo_page); + WSW(artwork_filter); + WI(zeropadplnum); + WI(wlz_menu); + WI(accessibility_modalbeep); + WI(accessibility_modalflash); + + WI(noml_ratings_prompt); + WI(noml_ratings); + WI(uid_ft); +} + +void config_read(int i) +{ + wchar_t programname[MAX_PATH] = {0}; + GetModuleFileNameW(hMainInstance, programname, MAX_PATH); + // regmimetype(L"interface/x-winamp-skin", programname, L".wsz", 0); // hack cause wa3 is gheeeeeey + + RI(utf8); + RI(eq_ws); + RI(updated_ft_startup); + // fiddle things so if running an existing install then we force restore file assoc off + // when we're running on Vista / Win7+ to resolve complaints from users on those OSes. + // vista + if(config_updated_ft_startup) + { + RI(check_ft_startup); + } + else + { + OSVERSIONINFO version = {0}; + version.dwOSVersionInfoSize = sizeof(version); + if (!GetVersionEx(&version)) ZeroMemory(&version, sizeof(OSVERSIONINFO)); + if (version.dwMajorVersion >= 6) // Vista + { + config_updated_ft_startup = 0; + } + else + { + RI(check_ft_startup); + } + } + config_updated_ft_startup = 1; + + RS(browserbrand); + RI(inet_mode); + RI(pe_fontsize); + RI(pe_direction); + RI(ospb); + RI(visplugin_num); + RI(visplugin_priority); + RI(visplugin_autoexec); + RI(dspplugin_num); + RI(sticon); + RI(splash); + RI(taskbar); + RI(dropaotfs); + RI(nomwheel); + RI(ascb_new); + RI(ttips); + RI(keeponscreen); + RI(riol); + RI(whichicon); + RI(whichicon2); + RI(addtolist); + RI(snap); + RI(snaplen); + RI(parent); + RI(hilite); + RI(disvis); + RI(minst); + RI(eqdsize); + RI(pladv); + RI(bifont); + RI(bifont_alt); + RI(autoload_eq); + RI(playlist_recyclebin); + RI(use_eq); + RI(wx); + RI(wy); + RI(minimized); + RI(aot); + RI(shuffle); + RI(repeat); + RI(volume); + RI(pan); + RI(easymove); + RI(dsize); + RI(timeleftmode); + RI(autoscrollname); + RI(sa); + RI(safire); + RI(saref); + RI(safalloff); + RI(sa_peaks); + RI(sa_peak_falloff); + RI(eq_wx); + RI(eq_wy); + RI(eq_open); + RI(mw_open); + RI(pe_wx); + RI(pe_wy); + RI(pe_open); + RI(pe_width); + RI(pe_height); + RI(pe_height_ws); + + RB(eq_limiter); + RI(eq_type); + RI(eq_frequencies); + /* + RI(si_wx); + RI(si_wy); + RI(si_height); + RI(si_width); + RI(si_autoshow); + RI(si_autosize); + RI(si_autohide); + RI(si_open); + */ + + RI(video_wx); + RI(video_wy); + RI(video_open); + RI(video_width); + RI(video_height); + RI(video_ratio1); + RI(video_ratio2); + RI(video_useratio); + RI(windowshade); + RI(preamp); + RI(pilp); + RI(randskin); + if (!*config_cwd) // don't read if the user has overridden it through paths.ini + RSW(cwd); + RSW(skin); + + RI_NP(prefs_last_page); + about_lastpage = prefs_last_page >> 8; + prefs_last_page &= 255; + + prefs_rect.left = _r_i("prefs_wx", -1); + prefs_rect.top = _r_i("prefs_wy", -1); + + alt3_rect.left = _r_i("alt3_wx", -1); + alt3_rect.top = _r_i("alt3_wy", -1); + + editinfo_rect.left = _r_i("editinfo_wx", -1); + editinfo_rect.top = _r_i("editinfo_wy", -1); + + ctrle_rect.left = _r_i("ctrle_wx", -1); + ctrle_rect.top = _r_i("ctrle_wy", -1); + + about_rect.left = _r_i("about_wx", -1); + about_rect.top = _r_i("about_wy", -1); + + loc_rect.left = _r_i("loc_wx", -1); + loc_rect.top = _r_i("loc_wy", -1); + + time_rect.left = _r_i("time_wx", -1); + time_rect.top = _r_i("time_wy", -1); + + load_rect.left = _r_i("load_wx", -1); + load_rect.top = _r_i("load_wy", -1); + + RI(rofiob); + RI(shownumsinpl); + RS(outname); + RI(usecursors); + RI(fixtitles); + RI(priority); + + if (!_r_i("fixpriority", 0)) + { + if (config_priority > 1) + { + config_priority++; + WI(priority); + } + _w_i("fixpriority", 1); + } + + RI(shuffle_morph_rate); + RI(useexttitles); + RI(newverchk); + RI(newverchk2); + RI(newverchk3); + RI(newverchk_rc); + RI(user_consent_join_channels); + RI(embedwnd_freesize); + RB(video_vsync2); + RI(video_aspectadj); + RB(video_overlays); + RB(video_gdiplus); + RB(video_ddraw); + RI(video_updsize); + RB(video_autoopen); + RB(video_autoclose); + RI(video_noss); + RI(video_logo); + RI(video_osd); + RB(video_yv12); + RI(video_stopclose); + RB(video_auto_fs);//RI(video_auto_fs); plague> changed to RB + RI(dotitlenum); + RI(dotasknum); + RI(plscrollsize); + RI(plmw2xscroll); + RI(playback_thread_priority); + RI(audio_bits); + RB(audio_mono); + RB(audio_surround); + RB(audio_dither); + RB(replaygain); + RI(replaygain_mode); + RI(replaygain_source); + RB(replaygain_preferred_only); + int gain10 = _r_i("replaygain_non_rg_gain", (int)(config_replaygain_non_rg_gain.GetFloat()*1000.0f)); + config_replaygain_non_rg_gain = (float)((float)gain10/1000.0f); + gain10 = _r_i("replaygain_preamp", (int)(config_replaygain_preamp.GetFloat()*1000.0f)); + config_replaygain_preamp = (float)((float)gain10/1000.0f); + + RI(last_classic_skin_page); + RI(last_playback_page); + RI(last_fileinfo_page); + RI(upd_mode); + RSW(artwork_filter); + + RI(noml_ratings_prompt); + RI(noml_ratings); + + RI(jtf_check); + RI(block_img); + + // RI(video_contrast); + // RI(video_brightness); + RI(video_fliprgb); + RI(video_remove_fs_on_stop); + RI(wav_do_header); + RI(wav_convert); + RS(wav_ext); + RI(no_visseh); + _r_sW("playlist_custom_font", playlist_custom_fontW, sizeof(playlist_custom_fontW)/sizeof(*playlist_custom_fontW)); + if (!*playlist_custom_fontW) StringCbCopyW(playlist_custom_fontW, sizeof(playlist_custom_fontW), DEFAULT_FONT); + WideCharToMultiByteSZ(CP_ACP, 0, playlist_custom_fontW, -1, playlist_custom_font, 128, 0, 0); + RI(custom_plfont); + RI(no_registry); + RB(proxy80); + RS(proxy); + RS(defext); + RSW(titlefmt); + RSW(visplugin_name); + RSW(dspplugin_name); + RI(zeropadplnum); + RI(wlz_menu); + RB(accessibility_modalbeep); + RB(accessibility_modalflash); + + { + char eq_data[256] = {0, }; + int x; + char *p = eq_data; + RS_NP(eq_data); + for (x = 0; x < 10; x ++) + { + int b = 0, s = 0; + while (p && *p >= '0' && *p <= '9') + { + s = 1;b = b * 10 + *p++ -'0'; + } + if (!s) break; + p++; + eq_tab[x] = min(63, max(b, 0)); + } + } + + //SetCurrentDirectoryW(config_cwd); + + config_utf8=1; + WI(utf8); + + + if (!i) + { + if (!PathFileExistsW(M3U_FILE)) + { + LoadPlaylistByExtension(OLD_M3U_FILE, L".m3u", 1, 1); + savem3ufn(M3U_FILE, 0, 1); + } + else + LoadPlaylistByExtension(M3U_FILE, L".m3u8", 1, 1); + PlayList_setposition(config_pilp); + } +} + + +int config_isregistered(wchar_t *ext) +{ + wchar_t b[256] = {0}; + DWORD rval = 0, s = sizeof(b); + + if (config_no_registry) return 0; + + if (!ext[0]) return 0; + StringCchPrintfW(b, 256, L".%s", ext); + + OSVERSIONINFO version = {0}; + version.dwOSVersionInfoSize = sizeof(version); + if (!GetVersionEx(&version)) ZeroMemory(&version, sizeof(OSVERSIONINFO)); + + if (IsWin8()) // Windows 8 + { + // QueryAppIsDefault(..) was deprecated in Windows 8 so this is an alternative + // which seems to work though how long it will keep working is currently unknown + IApplicationAssociationRegistration* pAAR = 0; + HRESULT hr = CoCreateInstance(CLSID_ApplicationAssociationRegistration, + NULL, CLSCTX_INPROC, + __uuidof(IApplicationAssociationRegistration), + (void**)&pAAR); + if (SUCCEEDED(hr) && pAAR) + { + LPWSTR app = 0; + /*hr = */pAAR->QueryCurrentDefault(b, + AT_FILEEXTENSION, + AL_EFFECTIVE, + &app); + pAAR->Release(); + + if (IsPlaylistExtension(ext)) + { + if(!lstrcmpiW(WINAMP_PLAYLISTW, app)){ rval = 1; } + } + else if (!_wcsicmp(ext, L"wsz") || !_wcsicmp(ext, L"wal") || !_wcsicmp(ext, L"wpz")) + { + if(!lstrcmpiW(WINAMP_SKINZIPW, app)){ rval = 1; } + } + else if (!_wcsicmp(ext, L"wlz")) + { + if(!lstrcmpiW(WINAMP_LANGZIPW, app)){ rval = 1; } + } + else + { + wchar_t str[64] = {0}; + StringCchPrintfW(str, 64, L"%s%hs", WINAMP_FILEW, b); + if(!lstrcmpiW(str, app)){ rval = 1; } + } + if (app) CoTaskMemFree(app); + } + } + else if (version.dwMajorVersion >= 6) // Vista + { + IApplicationAssociationRegistration* pAAR = NULL; + HRESULT hr = CoCreateInstance(CLSID_ApplicationAssociationRegistration, + NULL, CLSCTX_INPROC, + __uuidof(IApplicationAssociationRegistration), + (void**)&pAAR); + if (SUCCEEDED(hr) && pAAR) + { + BOOL hasExt=FALSE; + hr = pAAR->QueryAppIsDefault(b, + AT_FILEEXTENSION, + AL_EFFECTIVE, + AutoWide(app_name), + &hasExt); + pAAR->Release(); + if (SUCCEEDED(hr)) + { + rval=!!hasExt; + } + } + } + else + { + HKEY key = NULL; + if (RegOpenKeyW(HKEY_CLASSES_ROOT, b, &key) != ERROR_SUCCESS) return 0; + + DWORD vt = 0; + if (RegQueryValueExW(key, NULL, 0, &vt, (LPBYTE)b, &s) == ERROR_SUCCESS) + { + if (vt != REG_SZ || (wcsncmp(b, WINAMP_FILEW, wcslen(WINAMP_FILEW)) && + wcscmp(b, WINAMP_PLAYLISTW) && + wcscmp(b, WINAMP_SKINZIPW) && + wcscmp(b, WINAMP_LANGZIPW))) rval = 0; + else rval = 1; + } + else rval = 0; + RegCloseKey(key); + } + + return rval; +} + +bool allowed_extension(wchar_t *ext) +{ + const wchar_t* blocked[] = {L"exe", L"dll", + L"jpg", L"jpeg", L"gif", L"bmp", + L"png", L"tif", L"tiff"}; + // ensure we block at least 'exe' and 'dll', and images if not disabled + for (size_t i = 0; i < (config_block_img ? ARRAYSIZE(blocked) : 2); i++) + { + if (!_wcsicmp(ext, blocked[i])) return false; + } + return true; +} + +void config_register(wchar_t *ext, int reg) +{ + const wchar_t *which_str = WINAMP_FILEW; + if (config_no_registry) return ; + if (!ext[0]) return ; + if (!allowed_extension(ext)) return ; //windows=gay + + IFileTypeRegistrar *registrar=0; + if (GetRegistrar(®istrar, true) == 0 && registrar) + { + wchar_t family_str[256] = {0}; + + if (IsPlaylistExtension(ext)) + which_str = WINAMP_PLAYLISTW; + else if (!_wcsicmp(ext, L"wsz") || !_wcsicmp(ext, L"wal") || !_wcsicmp(ext, L"wpz")) + which_str = WINAMP_SKINZIPW; + else if (!_wcsicmp(ext, L"wlz")) + which_str = WINAMP_LANGZIPW; + else + { + StringCchPrintfW(family_str, 256, L"%s.%s", WINAMP_FILEW, ext); + + wchar_t family_description[256] = {0}; + if (in_get_extended_fileinfoW(family_str, L"family", family_description, 255) && family_description[0]) + { + which_str=family_str; + if (reg) + config_setup_filetype(family_str, family_description, 0); + } + } + + if (reg && !_wcsicmp(ext, L"asx")) + { + wchar_t programname[MAX_PATH] = {0}; + GetModuleFileNameW(hMainInstance, programname, MAX_PATH); + regmimetype(L"video/x-asx", programname, L".asx", 0); + regmimetype(L"video/asx", programname, L".asx", 0); + regmimetype(L"video/x-ms-asf", programname, L".asx", 0); + } + if (reg && !_wcsicmp(ext, L"wal")) + { + wchar_t programname[MAX_PATH] = {0}; + GetModuleFileNameW(hMainInstance, programname, MAX_PATH); + regmimetype(L"interface/x-winamp3-skin", programname, L".wal", 0); + } + if (reg && !_wcsicmp(ext, L"wsz")) + { + wchar_t programname[MAX_PATH] = {0}; + GetModuleFileNameW(hMainInstance, programname, MAX_PATH); + regmimetype(L"interface/x-winamp-skin", programname, L".wsz", 0); + } + if (reg && !_wcsicmp(ext, L"wlz")) + { + wchar_t programname[MAX_PATH] = {0}; + GetModuleFileNameW(hMainInstance, programname, MAX_PATH); + regmimetype(L"interface/x-winamp-lang", programname, L".wlz", 0); + } + if (reg && !_wcsicmp(ext, L"pls")) + { + wchar_t programname[MAX_PATH] = {0}; + GetModuleFileNameW(hMainInstance, programname, MAX_PATH); + regmimetype(L"audio/x-scpls", programname, L".pls", 0); + regmimetype(L"audio/scpls", programname, L".pls", 0); + } + if (reg && !_wcsicmp(ext, L"wma")) + { + wchar_t programname[MAX_PATH] = {0}; + GetModuleFileNameW(hMainInstance, programname, MAX_PATH); + regmimetype(L"audio/x-ms-wma", programname, L".wma", 1); + regmimetype(L"application/x-msdownload", programname, L".wma", 1); + } + if (reg && !_wcsicmp(ext, L"m3u")) + { + wchar_t programname[MAX_PATH] = {0}; + GetModuleFileNameW(hMainInstance, programname, MAX_PATH); + regmimetype(L"audio/x-mpegurl", programname, L".m3u", 0); + regmimetype(L"audio/mpegurl", programname, L".m3u", 0); + } + if (reg && !_wcsicmp(ext, L"mp3")) + { + wchar_t programname[MAX_PATH] = {0}; + GetModuleFileNameW(hMainInstance, programname, MAX_PATH); + regmimetype(L"audio/x-mpeg", programname, L".mp3", 1); + regmimetype(L"audio/x-mp3", programname, L".mp3", 1); + regmimetype(L"audio/x-mpg", programname, L".mp3", 1); + regmimetype(L"audio/mp3", programname, L".mp3", 1); + regmimetype(L"audio/mpg", programname, L".mp3", 1); + regmimetype(L"audio/mpeg", programname, L".mp3", 1); + } + + wchar_t b[128] = {0}; + StringCchPrintfW(b, 128, L".%s", ext); + CharLowerBuffW(b, ARRAYSIZE(b)); + if (reg) + registrar->RegisterType(b, which_str, AutoWide(app_name)); + else + { + // avoid removing WINAMP_FILEW as this will break some parts + // this will generally happen from 3rd party plugins where + // no %family% will be correctly returned in the relevant + if(_wcsicmp(which_str, WINAMP_FILEW)) + { + registrar->UnregisterType(b, which_str, AutoWide(app_name), IsPlaylistExtension(ext)); + } + } + + registrar->Release(); + } +} + +void regmimetype(const wchar_t *mtype, const wchar_t *programname, const wchar_t *ext, int nsonly) +{ + if (config_no_registry) + return ; + + IFileTypeRegistrar *registrar=0; + if (GetRegistrar(®istrar, true) == 0 && registrar) + { + registrar->RegisterMIMEType(mtype, programname, ext, nsonly); + registrar->Release(); + } +} + +void trimPathW(wchar_t *pathStart) +{ + PathRemoveBlanksW(pathStart); + PathRemoveBackslashW(pathStart); +} + +void config_setinifile(wchar_t *inifile) +{ + lstrcpynW(INI_FILE, inifile, sizeof(INI_FILE) / sizeof(INI_FILE[0])); +} + +void config_setinidir(const wchar_t *inidir) +{ + if (SUCCEEDED(StringCchCopyW(CONFIGDIR, MAX_PATH, inidir))) + trimPathW(CONFIGDIR); + else + CONFIGDIR[0] = 0; +} + +void config_setm3udir(const wchar_t *m3udir) +{ + if (SUCCEEDED(StringCchCopyW(M3UDIR, MAX_PATH, m3udir))) + trimPathW(M3UDIR); + else + M3UDIR[0] = 0; +} + +void config_setm3ubase(const wchar_t *m3ubase) +{ + if (SUCCEEDED(StringCchCopyW(M3UBASE, MAX_PATH, m3ubase))) + trimPathW(M3UBASE); + else + M3UBASE[0] = 0; +} + +void init_config() +{ + GetModuleFileNameW(hMainInstance, PROGDIR, MAX_PATH); + PathRemoveFileSpecW(PROGDIR); + SetEnvironmentVariableW(L"WINAMP_PROGRAM_DIR", PROGDIR); + wchar_t winamp_root[MAX_PATH] = {0}; + StringCchCopyW(winamp_root, MAX_PATH, PROGDIR); + PathStripToRootW(winamp_root); + SetEnvironmentVariableW(L"WINAMP_ROOT_DIR", winamp_root); +} + +void setup_config(void) +{ + if (!CONFIGDIR[0]) + StringCchCopyW(CONFIGDIR, MAX_PATH, PROGDIR); + + if (!M3UDIR[0]) + StringCchCopyW(M3UDIR, MAX_PATH, CONFIGDIR); + + if (!M3UBASE[0]) + StringCchCopyW(M3UBASE, MAX_PATH, M3UDIR); + + CreateDirectoryW(M3UDIR, NULL); + CreateDirectoryW(CONFIGDIR, NULL); + + // basic config files + PathCombineW(OLD_M3U_FILE, M3UDIR, L"Winamp.m3u"); + PathCombineW(M3U_FILE, M3UDIR, L"Winamp.m3u8"); + PathCombineW(BOOKMARKFILE, CONFIGDIR, L"Winamp.bm"); + PathCombineW(BOOKMARKFILE8, CONFIGDIR, L"Winamp.bm8"); + // just make sure if a winamp.bm8 doesn't exist then + // go make one from winamp.bm - implemented for 5.58+ + if(!PathFileExistsW(BOOKMARKFILE8)) + { + CopyFileW(BOOKMARKFILE,BOOKMARKFILE8,FALSE); + } + PathCombineW(EQDIR1, CONFIGDIR, L"Winamp.q1"); + PathCombineW(EQDIR2, CONFIGDIR, L"Winamp.q2"); + wchar_t tempPath[MAX_PATH] = {0}; + GetTempPathW(MAX_PATH, tempPath); + PathCombineW(TEMP_FILE, tempPath, L"Winamp.tmp"); + PathCombineW(DEMOMP3, M3UDIR, L"demo.mp3"); + PathCombineW(JSAPI2_INIFILE, CONFIGDIR, L"jsapisec.ini"); + PathCombineW(ML_INI_FILE, CONFIGDIR, L"Plugins\\gen_ml.ini"); + + // override INI_FILE if specified + if (INI_FILE[0]) + { + if (PathIsFileSpecW(INI_FILE) || PathIsRelativeW(INI_FILE)) + { + wchar_t temp[MAX_PATH] = {0}; + PathCombineW(temp, CONFIGDIR, INI_FILE); + lstrcpynW(INI_FILE, temp, MAX_PATH); + } + } + else + PathCombineW(INI_FILE, CONFIGDIR, L"Winamp.ini"); + + // maintain a ansi version of INI_FILE for some aspects + StringCchCopyA(INI_FILEA, MAX_PATH, AutoCharFn(INI_FILE)); + + RI(utf8); + + // skin and plugin directories + PathCombineW(SKINDIR, PROGDIR, L"Skins"); + PathCombineW(PLUGINDIR, PROGDIR, L"Plugins"); + PathCombineW(SYSPLUGINDIR, PROGDIR, L"System"); + PathCombineW(SKINDIR, PROGDIR, L"Skins"); + PathCombineW(LANGDIR, PROGDIR, L"Lang"); + PathCombineW(VISDIR, PROGDIR, L"Plugins"); + PathCombineW(DSPDIR, PROGDIR, L"Plugins"); + + // override skin/plugin directories from config + { + wchar_t bW[MAX_PATH] = {0}, *pW; + + bW[0]=0; + _r_sW("PluginDir", bW, MAX_PATH); + pW = bW; + while (pW && (*pW == L' ' || *pW == L'\t')) pW++; + if (pW && *pW) + { + StringCchCopyW(PLUGINDIR, MAX_PATH, bW); + } + + ZeroMemory(bW, sizeof(bW)); + _r_sW("DSPDir", bW, MAX_PATH); + pW = bW; + while (pW && (*pW == L' ' || *pW == L'\t')) pW++; + if (pW && *pW) + { + StringCchCopyW(DSPDIR, MAX_PATH, bW); + } + + ZeroMemory(bW, sizeof(bW)); + _r_sW("VISDir", bW, MAX_PATH); + pW = bW; + while (pW && (*pW == L' ' || *pW == L'\t')) pW++; + if (pW && *pW) + { + StringCchCopyW(VISDIR, MAX_PATH, bW); + } + + ZeroMemory(bW, sizeof(bW)); + _r_sW("SkinDir", bW, MAX_PATH); + pW = bW; + while (pW && (*pW == L' ' || *pW == L'\t')) pW++; + if (pW && *pW) + { + StringCchCopyW(SKINDIR, MAX_PATH, bW); + } + + ZeroMemory(bW, sizeof(bW)); + _r_sW("LangDir", bW, MAX_PATH); + pW = bW; + while (pW && (*pW == L' ' || *pW == L'\t')) pW++; + if (pW && *pW) + { + StringCchCopyW(LANGDIR, MAX_PATH, bW); + } + } + + // create a skin temp directory, too + wchar_t buf[MAX_PATH] = {0}; + GetTempPathW(MAX_PATH, buf); + GetTempFileNameW(buf, L"WAS", GetTickCount(), SKINTEMPDIR); + + // create a lang temp directory, too by + // trying to use part of the wlz's name + // so it's easier to see when debugging + // e.g. W<lang>XXXX.tmp otherwise it'll + // revert back to the older WLZXXXX.tmp + config_load_langpack_var(); + if (wcstok(config_langpack, L"-")) + { + wchar_t *p = wcstok(NULL, L"-"); + if (p) + { + wchar_t buf2[4] = {0}; + StringCchPrintfW(buf2, 4, L"W%s", p); + CharUpperBuffW(buf2, 4); + GetTempFileNameW(buf, buf2, GetTickCount(), LANGTEMPDIR); + } + else + { + GetTempFileNameW(buf, L"WLZ", GetTickCount(), LANGTEMPDIR); + } + } + else + { + GetTempFileNameW(buf, L"WLZ", GetTickCount(), LANGTEMPDIR); + } + + RI(minst); +} + +BOOL config_removedircontext(BOOL use_fallback) +{ + if (config_no_registry) + return TRUE; + + IFileTypeRegistrar *registrar=0; + if (GetRegistrar(®istrar, !use_fallback) == 0 && registrar) + { + registrar->RemoveDirectoryContext(WINAMP_PLAYW); + registrar->RemoveDirectoryContext(WINAMP_ENQUEUEW); + registrar->RemoveDirectoryContext(WINAMP_BOOKMARKW); + registrar->Release(); + return TRUE; + } + return FALSE; +} + +int config_iscdplayer(void) +{ + DWORD r = 0, s; + HKEY mp3Key; + char buf[MAX_PATH], buf2[MAX_PATH] = "\"";; + if (!GetModuleFileNameA(hMainInstance, buf2 + 1, sizeof(buf2) - 8)) return 0; + if (RegOpenKeyA(HKEY_CLASSES_ROOT, "AudioCD\\shell\\play\\command", &mp3Key) != ERROR_SUCCESS) return 0; + StringCchCatA(buf2, MAX_PATH, "\" %1"); + s = sizeof(buf); + if (RegQueryValueEx(mp3Key, NULL, 0, NULL, (LPBYTE)buf, &s) == ERROR_SUCCESS) + { + if (!lstrcmpiA(buf, buf2)) r = 1; + } + RegCloseKey(mp3Key); + return r; +} + +BOOL config_regcdplayer(int reg, int mode) +{ + if (config_no_registry) return TRUE; + + IFileTypeRegistrar *registrar=0; + if (GetRegistrar(®istrar, !mode) == 0 && registrar) + { + wchar_t programName[MAX_PATH] = {0}; + if (GetModuleFileNameW(hMainInstance, programName, MAX_PATH)) + { + if (reg) + registrar->RegisterCDPlayer(programName); + else + registrar->UnregisterCDPlayer(programName); + } + registrar->Release(); + return TRUE; + } + return FALSE; +} + +void config_load_langpack_var(void) +{ + RSW(langpack); +} + +void config_save_langpack_var(void) +{ + WSW(langpack); +} + +void config_agent_add(void) +{ + if (config_no_registry) return; + + IFileTypeRegistrar *registrar=0; + if (GetRegistrar(®istrar, true) == 0 && registrar) + { + wchar_t exe_name[MAX_PATH + 2] = {0}; + GetModuleFileNameW(hMainInstance, exe_name, sizeof(exe_name)/sizeof(wchar_t)); + PathRemoveFileSpecW(exe_name); + PathCombineW(exe_name, exe_name, L"winampa.exe"); + PathQuoteSpacesW(exe_name); + + registrar->AddAgent(exe_name); + registrar->Release(); + } + + Lang_LocaliseAgentOnTheFly(TRUE); +} + +void config_agent_remove(void) +{ + if (config_no_registry) return ; + + IFileTypeRegistrar *registrar=0; + if (GetRegistrar(®istrar, true) == 0 && registrar) + { + HWND hwnd = FindWindowW(L"WinampAgentMain", NULL); + if (hwnd) + { + SendMessageW(hwnd, WM_CLOSE, 0, 0); + } + registrar->RemoveAgent(); + registrar->Release(); + } + + Lang_LocaliseAgentOnTheFly(FALSE); +} + +BOOL config_register_capability(wchar_t *ext, int mode) +{ + if (config_no_registry) return TRUE; + + IFileTypeRegistrar *registrar=0; + if (GetRegistrar(®istrar, !mode) == 0 && registrar) + { + WCHAR szApplication[128] = {0}, szExtension[64] = {0}, szProgId[256] = {0}; + size_t required = MultiByteToWideCharSZ(CP_ACP, 0, app_name, -1, NULL, 0); + if (required > ARRAYSIZE(szApplication)) + return TRUE; + + if (0 == MultiByteToWideCharSZ(CP_ACP, 0, app_name, -1, szApplication, ARRAYSIZE(szApplication))) + return TRUE; + + LPWSTR cursor = szProgId; + size_t remaining = ARRAYSIZE(szProgId); + + if (FAILED(StringCchCopyExW(cursor, remaining, WINAMP_FILEW, &cursor, &remaining, 0))) + return TRUE; + + if (FAILED(StringCchCopyExW(cursor, remaining, L".", &cursor, &remaining, 0))) + return TRUE; + + if (FAILED(StringCchCopyExW(cursor, remaining, ext/*szExtension*/, &cursor, &remaining, 0))) + return TRUE; + + //CharLowerW(szExtension); + + registrar->RegisterCapability(szApplication, szProgId, szExtension); + registrar->Release(); + return TRUE; + } + return FALSE; +}
\ No newline at end of file |