serviceHost.cpp 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  1. #include "main.h"
  2. #include "./serviceHost.h"
  3. #include "./api__ml_online.h"
  4. #include "./resource.h"
  5. #include "./external.h"
  6. #include "./navigation.h"
  7. #include "./commands.h"
  8. #include "./serviceHelper.h"
  9. #include <ifc_omservice.h>
  10. #include <ifc_omserviceeditor.h>
  11. #include <ifc_omservicecommand.h>
  12. #include <ifc_omstoragehelper.h>
  13. #include <ifc_omstoragehandlerenum.h>
  14. #include <ifc_omfilestorage.h>
  15. #include "../winamp/IWasabiDispatchable.h"
  16. #include "../winamp/JSAPI_Info.h"
  17. #include <shlwapi.h>
  18. #include <strsafe.h>
  19. #define IS_INVALIDISPATCH(__disp) (((IDispatch *)1) == (__disp) || NULL == (__disp))
  20. static ServiceHost *cachedInstance = NULL;
  21. static void CALLBACK StorageHandler_ReadAuth(ifc_omservice *service, LPCWSTR pszKey, LPCWSTR pszValue)
  22. {
  23. INT iVal;
  24. UINT flags = (NULL != pszValue &&
  25. FALSE != StrToIntEx(pszValue, STIF_SUPPORT_HEX, &iVal) &&
  26. 0 != iVal) ?
  27. SVCF_USECLIENTOWEB : 0;
  28. ServiceHelper_SetFlags(service, flags, SVCF_USECLIENTOWEB);
  29. }
  30. static void CALLBACK StorageHandler_ReadBypass(ifc_omservice *service, LPCWSTR pszKey, LPCWSTR pszValue)
  31. {
  32. INT iVal;
  33. UINT flags = (NULL != pszValue &&
  34. FALSE != StrToIntEx(pszValue, STIF_SUPPORT_HEX, &iVal) &&
  35. 0 != iVal) ?
  36. SVCF_PREAUTHORIZED : 0;
  37. ServiceHelper_SetFlags(service, flags, SVCF_PREAUTHORIZED);
  38. }
  39. static void CALLBACK StorageHandler_ReadSubscribed(ifc_omservice *service, LPCWSTR pszKey, LPCWSTR pszValue)
  40. {
  41. INT iVal;
  42. UINT flags = (NULL != pszValue &&
  43. FALSE != StrToIntEx(pszValue, STIF_SUPPORT_HEX, &iVal) &&
  44. 0 != iVal) ?
  45. SVCF_SUBSCRIBED : 0;
  46. flags |= SVCF_AUTOUPGRADE;
  47. ServiceHelper_SetFlags(service, flags, SVCF_SUBSCRIBED | SVCF_AUTOUPGRADE);
  48. }
  49. static const ifc_omstoragehelper::TemplateRecord szStorageExtXml[] =
  50. {
  51. { L"auth", StorageHandler_ReadAuth },
  52. { L"bypass", StorageHandler_ReadBypass },
  53. };
  54. static const ifc_omstoragehelper::TemplateRecord szStorageExtIni[] =
  55. {
  56. { L"subscribed", StorageHandler_ReadSubscribed },
  57. };
  58. ServiceHost::ServiceHost()
  59. : ref(1), storageExtXml(NULL), storageExtIni(NULL)
  60. {
  61. }
  62. ServiceHost::~ServiceHost()
  63. {
  64. if (NULL != storageExtXml)
  65. storageExtXml->Release();
  66. if (NULL != storageExtIni)
  67. storageExtIni->Release();
  68. }
  69. HRESULT ServiceHost::CreateInstance(ServiceHost **instance)
  70. {
  71. if (NULL == instance)
  72. return E_POINTER;
  73. *instance = new ServiceHost();
  74. if (NULL == instance) return E_OUTOFMEMORY;
  75. return S_OK;
  76. }
  77. HRESULT ServiceHost::GetCachedInstance(ServiceHost **instance)
  78. {
  79. if (NULL == instance)
  80. return E_POINTER;
  81. if (NULL == cachedInstance)
  82. {
  83. HRESULT hr = CreateInstance(&cachedInstance);
  84. if (FAILED(hr))
  85. {
  86. *instance = NULL;
  87. return hr;
  88. }
  89. }
  90. cachedInstance->AddRef();
  91. *instance = cachedInstance;
  92. return S_OK;
  93. }
  94. HRESULT ServiceHost::ReleseCache()
  95. {
  96. if (NULL == cachedInstance)
  97. return S_FALSE;
  98. ServiceHost *t = cachedInstance;
  99. cachedInstance = NULL;
  100. t->Release();
  101. return S_OK;
  102. }
  103. size_t ServiceHost::AddRef()
  104. {
  105. return InterlockedIncrement((LONG*)&ref);
  106. }
  107. size_t ServiceHost::Release()
  108. {
  109. if (0 == ref)
  110. return ref;
  111. LONG r = InterlockedDecrement((LONG*)&ref);
  112. if (0 == r)
  113. delete(this);
  114. return r;
  115. }
  116. int ServiceHost::QueryInterface(GUID interface_guid, void **object)
  117. {
  118. if (NULL == object) return E_POINTER;
  119. if (IsEqualIID(interface_guid, IFC_OmServiceHost))
  120. *object = static_cast<ifc_omservicehost*>(this);
  121. else if (IsEqualIID(interface_guid, IFC_OmServiceEvent))
  122. *object = static_cast<ifc_omserviceevent*>(this);
  123. else if (IsEqualIID(interface_guid, IFC_OmStorageExt))
  124. *object = static_cast<ifc_omstorageext*>(this);
  125. else
  126. {
  127. *object = NULL;
  128. return E_NOINTERFACE;
  129. }
  130. if (NULL == *object)
  131. return E_UNEXPECTED;
  132. AddRef();
  133. return S_OK;
  134. }
  135. HRESULT ServiceHost::GetExternal(ifc_omservice *service, IDispatch **ppDispatch)
  136. {
  137. if (NULL == ppDispatch)
  138. return E_POINTER;
  139. if (NULL != *ppDispatch)
  140. {
  141. // try to connect our external
  142. IWasabiDispatchable *pWasabi;
  143. if (SUCCEEDED((*ppDispatch)->QueryInterface(IID_IWasabiDispatchable, (void**)&pWasabi)))
  144. {
  145. JSAPI::ifc_info *pInfo;
  146. if (SUCCEEDED(pWasabi->QueryDispatchable(JSAPI::IID_JSAPI_ifc_info, (Dispatchable**)&pInfo)))
  147. {
  148. ExternalDispatch *pExternal;
  149. if (SUCCEEDED(ExternalDispatch::CreateInstance(&pExternal)))
  150. {
  151. pInfo->AddAPI(pExternal->GetName(), pExternal);
  152. pExternal->Release();
  153. }
  154. pInfo->Release();
  155. }
  156. pWasabi->Release();
  157. }
  158. }
  159. return S_OK;
  160. }
  161. HRESULT ServiceHost::GetBasePath(ifc_omservice *service, LPWSTR pszBuffer, UINT cchBufferMax)
  162. {
  163. if (NULL == pszBuffer)
  164. return E_POINTER;
  165. return StringCchCopy(pszBuffer, cchBufferMax, L".\\Plugins\\ml\\omServices");
  166. }
  167. HRESULT ServiceHost::GetDefaultName(ifc_omservice *service, LPWSTR pszBuffer, UINT cchBufferMax)
  168. {
  169. if (NULL == pszBuffer)
  170. return E_POINTER;
  171. if (NULL == service)
  172. return E_INVALIDARG;
  173. return StringCchPrintf(pszBuffer, cchBufferMax, L"omService_{%010u}.ini", service->GetId());
  174. }
  175. HRESULT ServiceHost::QueryCommandState(ifc_omservice *service, HWND hBrowser, const GUID *commandGroup, UINT commandId)
  176. {
  177. if (NULL == service || NULL == commandGroup)
  178. return E_NOTIMPL;
  179. if (IsEqualGUID(*commandGroup, CMDGROUP_SERVICE))
  180. {
  181. switch(commandId)
  182. {
  183. case SVCCOMMAND_SHOWINFO:
  184. case SVCCOMMAND_REPORT:
  185. case SVCCOMMAND_UNSUBSCRIBE:
  186. case SVCCOMMAND_RATE:
  187. if (S_FALSE == ServiceHelper_IsSpecial(service))
  188. {
  189. return CMDSTATE_ENABLED;
  190. }
  191. return CMDSTATE_UNKNOWN;
  192. case SVCCOMMAND_BLOCKNAV:
  193. {
  194. UINT flags;
  195. if (FAILED(service->GetFlags(&flags)))
  196. flags = 0;
  197. HRESULT state = (0 == (SVCF_VERSIONCHECK & flags)) ?
  198. CMDSTATE_DISABLED : CMDSTATE_ENABLED;
  199. ServiceHelper_UpdateOperationInfo(hBrowser);
  200. return state;
  201. }
  202. break;
  203. }
  204. }
  205. return E_NOTIMPL;
  206. }
  207. HRESULT ServiceHost::ExecuteCommand(ifc_omservice *service, HWND hBrowser, const GUID *commandGroup, UINT commandId, ULONG_PTR commandArg)
  208. {
  209. if (IsEqualGUID(CMDGROUP_SERVICE, *commandGroup))
  210. {
  211. if (S_OK != ServiceHelper_IsSpecial(service))
  212. {
  213. switch(commandId)
  214. {
  215. case SVCCOMMAND_SHOWINFO: Command_ShowServiceInfo(service); return S_OK;
  216. case SVCCOMMAND_REPORT: Command_ReportService(service); return S_OK;
  217. case SVCCOMMAND_UNSUBSCRIBE: Command_UnsubscribeService(service); return S_OK;
  218. case SVCCOMMAND_RATE: Command_SetServiceRating(service, (UINT)commandArg); return S_OK;
  219. }
  220. }
  221. }
  222. return E_NOTIMPL;
  223. }
  224. void ServiceHost::ServiceChange(ifc_omservice *service, UINT nModified)
  225. {
  226. if (NULL == service) return;
  227. Navigation *navigation;
  228. if (SUCCEEDED(Plugin_GetNavigation(&navigation)))
  229. {
  230. navigation->UpdateService(service, nModified);
  231. navigation->Release();
  232. }
  233. }
  234. HRESULT ServiceHost::EnumerateStorageExt(const GUID *storageId, ifc_omstoragehandlerenum **enumerator)
  235. {
  236. if (NULL == storageId)
  237. return E_INVALIDARG;
  238. if (IsEqualGUID(SUID_OmStorageXml, *storageId))
  239. {
  240. if (NULL == storageExtXml)
  241. {
  242. ifc_omstoragehelper *storageHelper;
  243. if (NULL != OMUTILITY && SUCCEEDED(OMUTILITY->GetStorageHelper(&storageHelper)))
  244. {
  245. if (FAILED(storageHelper->CreateEnumerator(szStorageExtXml, ARRAYSIZE(szStorageExtXml), &storageExtXml)))
  246. storageExtXml = NULL;
  247. storageHelper->Release();
  248. }
  249. if (NULL == storageExtXml)
  250. return E_FAIL;
  251. }
  252. *enumerator = storageExtXml;
  253. storageExtXml->AddRef();
  254. return S_OK;
  255. }
  256. else if (IsEqualGUID(SUID_OmStorageIni, *storageId))
  257. {
  258. if (NULL == storageExtIni)
  259. {
  260. ifc_omstoragehelper *storageHelper;
  261. if (NULL != OMUTILITY && SUCCEEDED(OMUTILITY->GetStorageHelper(&storageHelper)))
  262. {
  263. if (FAILED(storageHelper->CreateEnumerator(szStorageExtIni, ARRAYSIZE(szStorageExtIni), &storageExtIni)))
  264. storageExtIni = NULL;
  265. storageHelper->Release();
  266. }
  267. if (NULL == storageExtIni)
  268. return E_FAIL;
  269. }
  270. *enumerator = storageExtIni;
  271. storageExtIni->AddRef();
  272. return S_OK;
  273. }
  274. return E_NOTIMPL;
  275. }
  276. HRESULT ServiceHost::GetUrl(ifc_omservice *service, LPWSTR pszBuffer, UINT cchBufferMax)
  277. {
  278. UINT flags;
  279. if (NULL != service && SUCCEEDED(service->GetFlags(&flags)) &&
  280. 0 != (SVCF_USECLIENTOWEB & flags) && NULL != AGAVE_API_AUTH)
  281. {
  282. LPWSTR pszUrl = Plugin_CopyString(pszBuffer);
  283. if (NULL == pszUrl) return E_OUTOFMEMORY;
  284. HRESULT hr(E_NOTIMPL);
  285. if (0 == AGAVE_API_AUTH->ClientToWeb(GUID_NULL, pszUrl, pszBuffer, cchBufferMax))
  286. hr = S_OK;
  287. Plugin_FreeString(pszUrl);
  288. return hr;
  289. }
  290. return E_NOTIMPL;
  291. }
  292. #define CBCLASS ServiceHost
  293. START_MULTIPATCH;
  294. START_PATCH(MPIID_OMSVCHOST)
  295. M_CB(MPIID_OMSVCHOST, ifc_omservicehost, ADDREF, AddRef);
  296. M_CB(MPIID_OMSVCHOST, ifc_omservicehost, RELEASE, Release);
  297. M_CB(MPIID_OMSVCHOST, ifc_omservicehost, QUERYINTERFACE, QueryInterface);
  298. M_CB(MPIID_OMSVCHOST, ifc_omservicehost, API_GETEXTERNAL, GetExternal);
  299. M_CB(MPIID_OMSVCHOST, ifc_omservicehost, API_GETBASEPATH, GetBasePath);
  300. M_CB(MPIID_OMSVCHOST, ifc_omservicehost, API_GETDEFAULTNAME, GetDefaultName);
  301. M_CB(MPIID_OMSVCHOST, ifc_omservicehost, API_QUERYCOMMANDSTATE, QueryCommandState);
  302. M_CB(MPIID_OMSVCHOST, ifc_omservicehost, API_EXECUTECOMMAND, ExecuteCommand);
  303. M_CB(MPIID_OMSVCHOST, ifc_omservicehost, API_GETURL, GetUrl);
  304. NEXT_PATCH(MPIID_OMSVCEVENT)
  305. M_CB(MPIID_OMSVCEVENT, ifc_omserviceevent, ADDREF, AddRef);
  306. M_CB(MPIID_OMSVCEVENT, ifc_omserviceevent, RELEASE, Release);
  307. M_CB(MPIID_OMSVCEVENT, ifc_omserviceevent, QUERYINTERFACE, QueryInterface);
  308. M_VCB(MPIID_OMSVCEVENT, ifc_omserviceevent, API_SERVICECHANGE, ServiceChange);
  309. NEXT_PATCH(MPIID_OMSTRGEXT)
  310. M_CB(MPIID_OMSTRGEXT, ifc_omstorageext, ADDREF, AddRef);
  311. M_CB(MPIID_OMSTRGEXT, ifc_omstorageext, RELEASE, Release);
  312. M_CB(MPIID_OMSTRGEXT, ifc_omstorageext, QUERYINTERFACE, QueryInterface);
  313. M_CB(MPIID_OMSTRGEXT, ifc_omstorageext, API_ENUMERATE, EnumerateStorageExt);
  314. END_PATCH
  315. END_MULTIPATCH;
  316. #undef CBCLASS