1
0

RSSCOM.cpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. #include "main.h"
  2. #include "./rssCOM.h"
  3. #include "./util.h"
  4. #include "api__ml_wire.h"
  5. #include "./cloud.h"
  6. #include "./feedUtil.h"
  7. #include "./defaults.h"
  8. #include "./errors.h"
  9. #include "../winamp/jsapi.h"
  10. #include "./rssCOM.h"
  11. #include <strsafe.h>
  12. extern Cloud cloud;
  13. #define DISPTABLE_CLASS RssCOM
  14. DISPTABLE_BEGIN()
  15. DISPENTRY_ADD(DISPATCH_SUBSCRIBE, L"subscribe", OnSubscribe)
  16. DISPTABLE_END
  17. #undef DISPTABLE_CLASS
  18. RssCOM::RssCOM()
  19. {}
  20. RssCOM::~RssCOM()
  21. {}
  22. HRESULT RssCOM::CreateInstance(RssCOM **instance)
  23. {
  24. if (NULL == instance) return E_POINTER;
  25. *instance = new RssCOM();
  26. if (NULL == *instance) return E_OUTOFMEMORY;
  27. return S_OK;
  28. }
  29. STDMETHODIMP_(ULONG) RssCOM::AddRef(void)
  30. {
  31. return _ref.fetch_add( 1 );
  32. }
  33. STDMETHODIMP_(ULONG) RssCOM::Release(void)
  34. {
  35. if (0 == _ref.load() )
  36. return _ref.load();
  37. LONG r = _ref.fetch_sub( 1 );
  38. if (0 == r)
  39. delete(this);
  40. return r;
  41. }
  42. STDMETHODIMP RssCOM::QueryInterface(REFIID riid, PVOID *ppvObject)
  43. {
  44. if (NULL == ppvObject) return E_POINTER;
  45. if (IsEqualIID(riid, IID_IDispatch))
  46. *ppvObject = static_cast<IDispatch*>(this);
  47. else if (IsEqualIID(riid, IID_IUnknown))
  48. *ppvObject = static_cast<IUnknown*>(this);
  49. else
  50. {
  51. *ppvObject = NULL;
  52. return E_NOINTERFACE;
  53. }
  54. AddRef();
  55. return S_OK;
  56. }
  57. HRESULT RssCOM::OnSubscribe(WORD wFlags, DISPPARAMS FAR *pdispparams, VARIANT FAR *pvarResult, unsigned int FAR *puArgErr)
  58. {
  59. JSAPI_VERIFY_METHOD(wFlags);
  60. JSAPI_VERIFY_PARAMCOUNT(pdispparams, 1);
  61. BSTR url;
  62. JSAPI_GETSTRING(url, pdispparams, 1, puArgErr);
  63. SubscribeUrl(url, pvarResult);
  64. return S_OK;
  65. }
  66. struct SubscribeThreadData
  67. {
  68. LPWSTR url;
  69. };
  70. static LPCWSTR FormatLangString(LPWSTR pszBuffer, INT cchBufferMax, LPWSTR pszFormat, INT cchFormatMax, INT formatId, ...)
  71. {
  72. HRESULT hr;
  73. va_list argList;
  74. va_start(argList, formatId);
  75. if(NULL != WASABI_API_LNGSTRINGW_BUF(formatId, pszFormat, cchFormatMax))
  76. {
  77. hr = StringCchVPrintfExW(pszBuffer, cchBufferMax, NULL, NULL, STRSAFE_IGNORE_NULLS, pszFormat, argList);
  78. }
  79. else
  80. {
  81. hr = E_FAIL;
  82. }
  83. va_end(argList);
  84. return (SUCCEEDED(hr)) ? pszBuffer : NULL;
  85. }
  86. static DWORD WINAPI SubscribeThreadProc(void *param)
  87. {
  88. SubscribeThreadData *data = (SubscribeThreadData *)param;
  89. Channel newFeed;
  90. newFeed.updateTime = updateTime;
  91. newFeed.autoUpdate = autoUpdate;
  92. newFeed.autoDownload = autoDownload;
  93. newFeed.autoDownloadEpisodes = autoDownloadEpisodes;
  94. newFeed.SetURL(data->url);
  95. newFeed.needsRefresh = true;
  96. WCHAR szBuffer1[2048] = {0}, szBuffer2[2048] = {0};
  97. LPCWSTR pszMessage = NULL, pszTitle = NULL;
  98. switch (DownloadFeedInformation(newFeed))
  99. {
  100. case DOWNLOAD_SUCCESS:
  101. {
  102. Nullsoft::Utility::AutoLock lock (channels LOCKNAME("AddURL"));
  103. newFeed.autoDownload = ::autoDownload;
  104. if (channels.AddChannel(newFeed))
  105. cloud.Pulse();
  106. }
  107. break;
  108. case DOWNLOAD_DUPLICATE:
  109. pszMessage = FormatLangString(szBuffer1, ARRAYSIZE(szBuffer1), szBuffer2, ARRAYSIZE(szBuffer2), IDS_ALREADY_SUBSCRIBED, newFeed.title, data->url);
  110. break;
  111. case DOWNLOAD_404:
  112. pszMessage = FormatLangString(szBuffer1, ARRAYSIZE(szBuffer1), szBuffer2, ARRAYSIZE(szBuffer2), IDS_FILE_NOT_FOUND, data->url);
  113. break;
  114. case DOWNLOAD_TIMEOUT:
  115. pszMessage = FormatLangString(szBuffer1, ARRAYSIZE(szBuffer1), szBuffer2, ARRAYSIZE(szBuffer2), IDS_CONNECTION_TIMED_OUT, data->url);
  116. break;
  117. case DOWNLOAD_ERROR_PARSING_XML:
  118. pszMessage = FormatLangString(szBuffer1, ARRAYSIZE(szBuffer1), szBuffer2, ARRAYSIZE(szBuffer2), IDS_ERROR_PARSING_XML, data->url);
  119. break;
  120. case DOWNLOAD_NOTRSS:
  121. pszMessage = FormatLangString(szBuffer1, ARRAYSIZE(szBuffer1), szBuffer2, ARRAYSIZE(szBuffer2), IDS_INVALID_RSS_FEED, data->url);
  122. break;
  123. case DOWNLOAD_CONNECTIONRESET:
  124. pszMessage = FormatLangString(szBuffer1, ARRAYSIZE(szBuffer1), szBuffer2, ARRAYSIZE(szBuffer2), IDS_CONNECTION_RESET, data->url);
  125. break;
  126. case DOWNLOAD_NOHTTP:
  127. pszMessage = WASABI_API_LNGSTRINGW_BUF(IDS_NO_JNETLIB, szBuffer1, ARRAYSIZE(szBuffer1));
  128. pszTitle = WASABI_API_LNGSTRINGW_BUF(IDS_JNETLIB_MISSING, szBuffer2, ARRAYSIZE(szBuffer2));
  129. break;
  130. case DOWNLOAD_NOPARSER:
  131. pszMessage = WASABI_API_LNGSTRINGW_BUF(IDS_NO_EXPAT, szBuffer1, ARRAYSIZE(szBuffer1));
  132. pszTitle = WASABI_API_LNGSTRINGW_BUF(IDS_EXPAT_MISSING, szBuffer2, ARRAYSIZE(szBuffer2));
  133. break;
  134. }
  135. if(NULL != pszMessage)
  136. {
  137. if (NULL == pszTitle)
  138. pszTitle = WASABI_API_LNGSTRINGW_BUF(IDS_ERROR_SUBSCRIBING_TO_PODCAST, szBuffer2, ARRAYSIZE(szBuffer2));
  139. MessageBox(plugin.hwndLibraryParent, pszMessage, pszTitle, MB_ICONERROR | MB_OK);
  140. }
  141. Plugin_FreeString(data->url);
  142. free(data);
  143. return 0;
  144. }
  145. LPCWSTR RssCOM::GetName()
  146. {
  147. return L"Podcast";
  148. }
  149. HRESULT RssCOM::SubscribeUrl(BSTR url, VARIANT FAR *result)
  150. {
  151. HRESULT hr;
  152. SubscribeThreadData *data = (SubscribeThreadData*)malloc(sizeof(SubscribeThreadData));
  153. if (NULL != data)
  154. {
  155. data->url = Plugin_CopyString(url);
  156. DWORD threadId;
  157. HANDLE hThread = CreateThread(NULL, NULL, SubscribeThreadProc, (void*)data, NULL, &threadId);
  158. if (NULL == hThread)
  159. {
  160. DWORD error = GetLastError();
  161. hr = HRESULT_FROM_WIN32(error);
  162. Plugin_FreeString(data->url);
  163. free(data);
  164. }
  165. else
  166. {
  167. CloseHandle(hThread);
  168. hr = S_OK;
  169. }
  170. }
  171. else
  172. hr = E_OUTOFMEMORY;
  173. if (NULL != result)
  174. {
  175. VariantInit(result);
  176. V_VT(result) = VT_BOOL;
  177. V_BOOL(result) = (SUCCEEDED(hr) ? VARIANT_TRUE : VARIANT_FALSE);
  178. }
  179. return hr;
  180. }