123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321 |
- /** (c) Nullsoft, Inc. C O N F I D E N T I A L
- ** Filename:
- ** Project:
- ** Description:
- ** Author: Ben Allison [email protected]
- ** Created:
- **/
- #include "main.h"
- #include "ApplicationCOM.h"
- #include "../nu/AutoWide.h"
- #include "../nu/AutoChar.h"
- #include "../nu/ns_wc.h"
- #include "api.h"
- #include "../Plugins/General/gen_ml/ml.h"
- #include <api/syscb/callbacks/browsercb.h>
- #include "../Agave/Language/api_language.h"
- HINSTANCE WASABI_API_LNG_HINST;
- HINSTANCE WASABI_API_ORIG_HINST;
- #include <shlwapi.h>
- #include "TempFileCOM.h"
- #include "resource.h"
- #include "JSAPI.h"
- #define CSTR_INVARIANT MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT)
- bool FilterUrl(const wchar_t *url)
- {
- const wchar_t filterNowPlaying[] = L"http://client.winamp.com/nowplaying";
- size_t urlLength, filterLength;
- if (NULL == url)
- return false;
- urlLength = lstrlenW(url);
- filterLength = ARRAYSIZE(filterNowPlaying) - 1;
- if (urlLength >= filterLength &&
- CSTR_EQUAL == CompareStringW(CSTR_INVARIANT, NORM_IGNORECASE,
- url, (int)filterLength, filterNowPlaying, (int)filterLength))
- {
- return true;
- }
- return false;
- }
- void myOpenURL(HWND hwnd, const wchar_t *loc)
- {
- if (loc)
- {
- bool override=false;
- WASABI_API_SYSCB->syscb_issueCallback(SysCallback::BROWSER, BrowserCallback::ONOPENURL, reinterpret_cast<intptr_t>(loc), reinterpret_cast<intptr_t>(&override));
- if (!override && false == FilterUrl(loc))
- ShellExecuteW(hwnd, L"open", loc, NULL, NULL, SW_SHOWNORMAL);
- }
- }
- void myOpenURLWithFallback(HWND hwnd, wchar_t *loc, wchar_t *fallbackLoc)
- {
- bool override=false;
- if (loc)
- {
- WASABI_API_SYSCB->syscb_issueCallback(SysCallback::BROWSER, BrowserCallback::ONOPENURL, reinterpret_cast<intptr_t>(loc), reinterpret_cast<intptr_t>(&override));
- }
- if (!override && false == FilterUrl(loc) && fallbackLoc)
- ShellExecuteW(hwnd, L"open", fallbackLoc, NULL, NULL, SW_SHOWNORMAL);
- }
- enum
- {
- DISP_APPLICATION_IDLE = 777,
- DISP_APPLICATION_GETLANGUAGE,
- DISP_APPLICATION_ISWINAMPPRO,
- DISP_APPLICATION_GETCOUNTRY,
- DISP_APPLICATION_GETLOCALE,
- DISP_APPLICATION_LAUNCHURL,
- DISP_APPLICATION_VERSION,
- DISP_APPLICATION_SPECIALBUILD,
- DISP_APPLICATION_DOWNLOADMEDIA,
- DISP_APPLICATION_CREATETEMPFILE,
- };
- #define CHECK_ID(str, id)\
- if (CSTR_EQUAL == CompareStringW(lcid, NORM_IGNORECASE, rgszNames[i], -1, L##str, -1))\
- { rgdispid[i] = id; continue; }
- HRESULT ApplicationCOM::GetIDsOfNames(REFIID riid, OLECHAR FAR* FAR* rgszNames, unsigned int cNames, LCID lcid, DISPID FAR* rgdispid)
- {
- bool unknowns = false;
- for (unsigned int i = 0;i != cNames;i++)
- {
- CHECK_ID("Idle", DISP_APPLICATION_IDLE)
- CHECK_ID("GetLanguage", DISP_APPLICATION_GETLANGUAGE)
- CHECK_ID("IsWinampPro", DISP_APPLICATION_ISWINAMPPRO)
- CHECK_ID("GetCountry", DISP_APPLICATION_GETCOUNTRY)
- CHECK_ID("GetLocale", DISP_APPLICATION_GETLOCALE)
- CHECK_ID("LaunchURL", DISP_APPLICATION_LAUNCHURL)
- CHECK_ID("Version", DISP_APPLICATION_VERSION)
- CHECK_ID("GetSpecialBuildName", DISP_APPLICATION_SPECIALBUILD)
- CHECK_ID("DownloadMedia", DISP_APPLICATION_DOWNLOADMEDIA)
- CHECK_ID("CreateTempFile", DISP_APPLICATION_CREATETEMPFILE)
- rgdispid[i] = DISPID_UNKNOWN;
- unknowns = true;
- }
- if (unknowns)
- return DISP_E_UNKNOWNNAME;
- else
- return S_OK;
- }
- HRESULT ApplicationCOM::GetTypeInfo(unsigned int itinfo, LCID lcid, ITypeInfo FAR* FAR* pptinfo)
- {
- return E_NOTIMPL;
- }
- HRESULT ApplicationCOM::GetTypeInfoCount(unsigned int FAR * pctinfo)
- {
- return E_NOTIMPL;
- }
- void GetLanguage(wchar_t *language, size_t size)
- {
- StringCchCopyW(language, size, WASABI_API_LNG->GetLanguageIdentifier(LANG_LANG_CODE));
- }
- void GetCountry(wchar_t *language, size_t size)
- {
- // language packs aren't country-specific enough to use them for country info, yet
- int err = GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SISO3166CTRYNAME , language, (int)size);
- if (err == 0) // win95 doesn't support this flag, so we'll check for an error
- lstrcpynW(language, L"US", (int)size); // and default to english
- }
- void CALLBACK OpenURLAPC(ULONG_PTR param)
- {
- wchar_t *url = (wchar_t *)param;
- myOpenURL(NULL, url);
- free(url);
- }
- void GetPathToStore(wchar_t path_to_store[MAX_PATH])
- {
- if (FAILED(SHGetFolderPathW(NULL, CSIDL_MYMUSIC, NULL, SHGFP_TYPE_CURRENT, path_to_store)))
- {
- if (FAILED(SHGetFolderPathW(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, path_to_store)))
- {
- // and if that all fails then do a reasonable default
- GetPrivateProfileStringW(L"gen_ml_config", L"extractpath", L"C:\\My Music", path_to_store, MAX_PATH, ML_INI_FILE);
- }
- // if there's no valid My Music folder (typically win2k) then default to %my_documents%\my music
- else
- {
- PathCombineW(path_to_store, path_to_store, L"My Music");
- }
- }
- }
- static void CALLBACK SendOpenUrl_Callback(HWND hwnd, UINT uMsg, ULONG_PTR dwData, LRESULT lResult)
- {
- if (NULL != dwData)
- free((void*)dwData);
- }
- HRESULT ApplicationCOM::Invoke(DISPID dispid, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS FAR *pdispparams, VARIANT FAR *pvarResult, EXCEPINFO FAR * pexecinfo, unsigned int FAR *puArgErr)
- {
- switch (dispid)
- {
- case DISP_APPLICATION_CREATETEMPFILE:
- {
- IDispatch *tempFile =0;
- if (pdispparams->cArgs == 1)
- tempFile = new TempFileCOM(pdispparams->rgvarg[0].bstrVal);
- else
- tempFile = new TempFileCOM(0);
- VariantInit(pvarResult);
- V_VT(pvarResult) = VT_DISPATCH;
- V_DISPATCH(pvarResult) = tempFile;
- return S_OK;
- }
- case DISP_APPLICATION_DOWNLOADMEDIA:
- {
- const wchar_t *url = pdispparams->rgvarg[0].bstrVal;
- if (url)
- {
- const wchar_t *destFileSpec=PathFindFileNameW(url);
- wchar_t path_to_store[MAX_PATH] = {0};
- GetPathToStore(path_to_store);
- wchar_t destfile[MAX_PATH] = {0};
- wchar_t dlgtitle[256] = {0};
- CreateDirectoryW(path_to_store, NULL);
- PathCombineW(destfile, path_to_store, destFileSpec);
- httpRetrieveFileW(hMainWindow, AutoChar(url), destfile, getStringW(IDS_DOWNLOADING, dlgtitle,256));
- LMDB_FILE_ADD_INFOW fi = {const_cast<wchar_t *>(destfile), -1, -1};
- sendMlIpc(ML_IPC_DB_ADDORUPDATEFILEW, (WPARAM)&fi);
- sendMlIpc(ML_IPC_DB_SYNCDB, 0);
- }
- }
- return S_OK;
- case DISP_APPLICATION_IDLE:
- //Idle();
- return S_OK;
- case DISP_APPLICATION_GETLANGUAGE:
- {
- wchar_t langName[8] = {0};
- GetLanguage(langName, 8);
- BSTR language = SysAllocString(langName);
- VariantInit(pvarResult);
- V_VT(pvarResult) = VT_BSTR;
- V_BSTR(pvarResult) = language;
- return S_OK;
- }
- case DISP_APPLICATION_GETCOUNTRY:
- {
- wchar_t countryName[8] = {0};
- GetCountry(countryName, 8);
- BSTR country = SysAllocString(countryName);
- VariantInit(pvarResult);
- V_VT(pvarResult) = VT_BSTR;
- V_BSTR(pvarResult) = country;
- return S_OK;
- }
- case DISP_APPLICATION_GETLOCALE:
- {
- wchar_t countryName[8] = {0};
- GetCountry(countryName, 8);
- wchar_t langName[8] = {0};
- GetLanguage(langName, 8);
- wchar_t language_country[16] = {0};
- StringCchPrintfW(language_country, 16, L"%s-%s", langName, countryName);
- BSTR languageAndCountryCode = SysAllocString(language_country);
- VariantInit(pvarResult);
- V_VT(pvarResult) = VT_BSTR;
- V_BSTR(pvarResult) = languageAndCountryCode;
- return S_OK;
- }
- case DISP_APPLICATION_ISWINAMPPRO:
- {
- VariantInit(pvarResult);
- V_VT(pvarResult) = VT_BOOL;
- V_BOOL(pvarResult) = VARIANT_TRUE;
- return S_OK;
- }
- case DISP_APPLICATION_LAUNCHURL:
- if (pdispparams->cArgs == 1 || pdispparams->cArgs == 2)
- {
- if (JSAPI_PARAM_OPTIONAL(pdispparams, 2, boolVal, FALSE) == TRUE)
- ShellExecuteW(NULL, L"open", JSAPI_PARAM(pdispparams, 1).bstrVal, NULL, L".", 0);
- else
- {
- LPWSTR url = _wcsdup(JSAPI_PARAM(pdispparams, 1).bstrVal);
- if ( 0 == SendMessageCallback(hMainWindow, WM_WA_IPC, (WPARAM)url, (LPARAM)IPC_OPEN_URL, SendOpenUrl_Callback, (ULONG_PTR)url) &&
- 0 == QueueUserAPC(OpenURLAPC, hMainThread, (ULONG_PTR)url))
- {
- free(url);
- }
- }
-
- return S_OK;
- }
- else
- return DISP_E_BADPARAMCOUNT;
- case DISP_APPLICATION_VERSION:
- {
- AutoWide versionW(APP_VERSION);
- BSTR versionB = SysAllocString(versionW);
- VariantInit(pvarResult);
- V_VT(pvarResult) = VT_BSTR;
- V_BSTR(pvarResult) = versionB;
- return S_OK;
- }
- case DISP_APPLICATION_SPECIALBUILD:
- {
- BSTR special = SysAllocString(SPECIAL_BUILD_NAME);
- VariantInit(pvarResult);
- V_VT(pvarResult) = VT_BSTR;
- V_BSTR(pvarResult) = special;
- return S_OK;
- }
- }
- return DISP_E_MEMBERNOTFOUND;
- }
- STDMETHODIMP ApplicationCOM::QueryInterface(REFIID riid, PVOID *ppvObject)
- {
- if (!ppvObject)
- return E_POINTER;
- else if (IsEqualIID(riid, IID_IDispatch))
- *ppvObject = (IDispatch *)this;
- else if (IsEqualIID(riid, IID_IUnknown))
- *ppvObject = this;
- else
- {
- *ppvObject = NULL;
- return E_NOINTERFACE;
- }
- AddRef();
- return S_OK;
- }
- ULONG ApplicationCOM::AddRef(void)
- {
- return 0;
- }
- ULONG ApplicationCOM::Release(void)
- {
- return 0;
- }
- void ApplicationCOM::Idle()
- {
- WASABI_API_APP->app_messageLoopStep();
- }
|