CurrentSongCOM.cpp 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. /** (c) Nullsoft, Inc. C O N F I D E N T I A L
  2. ** Filename:
  3. ** Project:
  4. ** Description:
  5. ** Author: Ben Allison [email protected]
  6. ** Created:
  7. **/
  8. #include "Main.h"
  9. #include "CurrentSongCOM.h"
  10. #include "../nu/AutoWide.h"
  11. #include "Browser.h"
  12. #include "JSAPI.h"
  13. #include <malloc.h>
  14. HANDLE DuplicateCurrentThread()
  15. {
  16. HANDLE fakeHandle = GetCurrentThread();
  17. HANDLE copiedHandle = 0;
  18. HANDLE processHandle = GetCurrentProcess();
  19. DuplicateHandle(processHandle, fakeHandle, processHandle, &copiedHandle, 0, FALSE, DUPLICATE_SAME_ACCESS);
  20. return copiedHandle;
  21. }
  22. enum
  23. {
  24. DISP_CURRENTSONG_GETFILENAME = 777,
  25. DISP_CURRENTSONG_GETFILETITLE ,
  26. DISP_CURRENTSONG_GETFILELENGTH,
  27. DISP_CURRENTSONG_GETMETADATA ,
  28. DISP_CURRENTSONG_GETPLAYPOSITION ,
  29. DISP_CURRENTSONG_ISPLAYING ,
  30. DISP_CURRENTSONG_ISSTOPPED ,
  31. DISP_CURRENTSONG_ISPAUSED ,
  32. DISP_CURRENTSONG_PAUSE ,
  33. DISP_CURRENTSONG_RESUME,
  34. DISP_CURRENTSONG_REGISTERMETADATACALLBACK,
  35. DISP_CURRENTSONG_UNREGISTERMETADATACALLBACK,
  36. DISP_CURRENTSONG_REGISTERTITLECHANGECALLBACK,
  37. DISP_CURRENTSONG_UNREGISTERTITLECHANGECALLBACK,
  38. DISP_CURRENTSONG_REFRESHTITLE,
  39. };
  40. #define CHECK_ID(str, id)\
  41. if (CSTR_EQUAL == CompareStringW(lcid, NORM_IGNORECASE, rgszNames[i], -1, L##str, -1))\
  42. { rgdispid[i] = id; continue; }
  43. HRESULT CurrentSongCOM::GetIDsOfNames(REFIID riid, OLECHAR FAR* FAR* rgszNames, unsigned int cNames, LCID lcid, DISPID FAR* rgdispid)
  44. {
  45. UNREFERENCED_PARAMETER(riid);
  46. bool unknowns = false;
  47. for (unsigned int i = 0;i != cNames;i++)
  48. {
  49. CHECK_ID("GetFilename", DISP_CURRENTSONG_GETFILENAME) // July 27, 2005
  50. CHECK_ID("GetFileTitle", DISP_CURRENTSONG_GETFILETITLE) // July 27, 2005
  51. CHECK_ID("GetFileLength", DISP_CURRENTSONG_GETFILELENGTH) // July 27, 2005
  52. CHECK_ID("GetMetadata", DISP_CURRENTSONG_GETMETADATA) // July 27, 2005
  53. CHECK_ID("GetPlayPosition", DISP_CURRENTSONG_GETPLAYPOSITION) // July 27, 2005
  54. CHECK_ID("IsPlaying", DISP_CURRENTSONG_ISPLAYING) // July 27, 2005
  55. CHECK_ID("IsStopped", DISP_CURRENTSONG_ISSTOPPED) // July 27, 2005
  56. CHECK_ID("IsPaused", DISP_CURRENTSONG_ISPAUSED) // July 27, 2005
  57. CHECK_ID("Pause", DISP_CURRENTSONG_PAUSE)
  58. CHECK_ID("Resume", DISP_CURRENTSONG_RESUME)
  59. CHECK_ID("RegisterMetadataCallback", DISP_CURRENTSONG_REGISTERMETADATACALLBACK)
  60. CHECK_ID("UnregisterMetadataCallback", DISP_CURRENTSONG_UNREGISTERMETADATACALLBACK)
  61. CHECK_ID("RegisterTitleChangeCallback", DISP_CURRENTSONG_REGISTERTITLECHANGECALLBACK)
  62. CHECK_ID("UnregisterTitleChangeCallback", DISP_CURRENTSONG_UNREGISTERTITLECHANGECALLBACK)
  63. CHECK_ID("RefreshTitle", DISP_CURRENTSONG_REFRESHTITLE)
  64. rgdispid[i] = DISPID_UNKNOWN;
  65. unknowns = true;
  66. }
  67. if (unknowns)
  68. return DISP_E_UNKNOWNNAME;
  69. else
  70. return S_OK;
  71. }
  72. HRESULT CurrentSongCOM::GetTypeInfo(unsigned int itinfo, LCID lcid, ITypeInfo FAR* FAR* pptinfo)
  73. {
  74. UNREFERENCED_PARAMETER(itinfo);
  75. UNREFERENCED_PARAMETER(lcid);
  76. UNREFERENCED_PARAMETER(pptinfo);
  77. return E_NOTIMPL;
  78. }
  79. HRESULT CurrentSongCOM::GetTypeInfoCount(unsigned int FAR * pctinfo)
  80. {
  81. UNREFERENCED_PARAMETER(pctinfo);
  82. return E_NOTIMPL;
  83. }
  84. HRESULT CurrentSongCOM::Invoke(DISPID dispid, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS FAR *pdispparams, VARIANT FAR *pvarResult, EXCEPINFO FAR * pexecinfo, unsigned int FAR *puArgErr)
  85. {
  86. UNREFERENCED_PARAMETER(riid);
  87. UNREFERENCED_PARAMETER(lcid);
  88. UNREFERENCED_PARAMETER(wFlags);
  89. UNREFERENCED_PARAMETER(pexecinfo);
  90. switch (dispid)
  91. {
  92. case DISP_CURRENTSONG_REFRESHTITLE:
  93. SendMessageW(hMainWindow, WM_WA_IPC, 0, IPC_UPDTITLE);
  94. return S_OK;
  95. case DISP_CURRENTSONG_REGISTERTITLECHANGECALLBACK:
  96. return titleChangeCallbacks.RegisterFromDispParam(pdispparams, 0, puArgErr);
  97. case DISP_CURRENTSONG_UNREGISTERTITLECHANGECALLBACK:
  98. return titleChangeCallbacks.UnregisterFromDispParam(pdispparams, 0, puArgErr);
  99. case DISP_CURRENTSONG_REGISTERMETADATACALLBACK:
  100. return metadataCallbacks.RegisterFromDispParam(pdispparams, 0, puArgErr);
  101. case DISP_CURRENTSONG_UNREGISTERMETADATACALLBACK:
  102. return metadataCallbacks.UnregisterFromDispParam(pdispparams, 0, puArgErr);
  103. case DISP_CURRENTSONG_GETMETADATA:
  104. JSAPI_VERIFY_METHOD(wFlags);
  105. JSAPI_VERIFY_PARAMCOUNT(pdispparams, 1);
  106. JSAPI_VERIFY_PARAMTYPE(pdispparams, 1, VT_BSTR, puArgErr);
  107. JSAPI_INIT_RESULT(pvarResult, VT_BSTR);
  108. {
  109. wchar_t buffer[4096] = {0};
  110. extendedFileInfoStructW info;
  111. info.filename = FileName;
  112. info.metadata = pdispparams->rgvarg[0].bstrVal;
  113. info.ret = buffer;
  114. info.retlen = sizeof(buffer)/sizeof(wchar_t);
  115. if (NULL != info.filename &&
  116. NULL != info.metadata)
  117. {
  118. if (0 == SendMessageW(hMainWindow, WM_WA_IPC, (WPARAM)&info, IPC_GET_EXTENDED_FILE_INFOW_HOOKABLE))
  119. info.ret = NULL;
  120. JSAPI_SET_RESULT(pvarResult, bstrVal, SysAllocString(info.ret));
  121. }
  122. else
  123. JSAPI_EMPTY_RESULT(pvarResult);
  124. return S_OK;
  125. }
  126. break;
  127. case DISP_CURRENTSONG_GETFILENAME:
  128. {
  129. BSTR name = SysAllocString(FileName);
  130. VariantInit(pvarResult);
  131. V_VT(pvarResult) = VT_BSTR;
  132. V_BSTR(pvarResult) = name;
  133. return S_OK;
  134. }
  135. break;
  136. case DISP_CURRENTSONG_GETFILETITLE:
  137. {
  138. BSTR title = SysAllocString(FileTitle);
  139. VariantInit(pvarResult);
  140. V_VT(pvarResult) = VT_BSTR;
  141. V_BSTR(pvarResult) = title;
  142. return S_OK;
  143. }
  144. break;
  145. case DISP_CURRENTSONG_GETFILELENGTH:
  146. VariantInit(pvarResult);
  147. V_VT(pvarResult) = VT_I4;
  148. V_I4(pvarResult) = in_getlength();
  149. return S_OK;
  150. case DISP_CURRENTSONG_GETPLAYPOSITION:
  151. VariantInit(pvarResult);
  152. V_VT(pvarResult) = VT_I4;
  153. V_I4(pvarResult) = in_getouttime();
  154. return S_OK;
  155. case DISP_CURRENTSONG_ISPLAYING:
  156. VariantInit(pvarResult);
  157. V_VT(pvarResult) = VT_BOOL;
  158. V_BOOL(pvarResult) = (0 != playing) ? VARIANT_TRUE : VARIANT_FALSE;
  159. return S_OK;
  160. case DISP_CURRENTSONG_ISSTOPPED:
  161. VariantInit(pvarResult);
  162. V_VT(pvarResult) = VT_BOOL;
  163. V_BOOL(pvarResult) = (0 == playing) ? VARIANT_TRUE : VARIANT_FALSE;
  164. return S_OK;
  165. case DISP_CURRENTSONG_ISPAUSED:
  166. VariantInit(pvarResult);
  167. V_VT(pvarResult) = VT_BOOL;
  168. V_BOOL(pvarResult) = (0 != paused) ? VARIANT_TRUE : VARIANT_FALSE;
  169. return S_OK;
  170. case DISP_CURRENTSONG_PAUSE:
  171. PausePlaying();
  172. return S_OK;
  173. case DISP_CURRENTSONG_RESUME:
  174. UnPausePlaying();
  175. return S_OK;
  176. }
  177. return DISP_E_MEMBERNOTFOUND;
  178. }
  179. STDMETHODIMP CurrentSongCOM::QueryInterface(REFIID riid, PVOID *ppvObject)
  180. {
  181. if (!ppvObject)
  182. return E_POINTER;
  183. else if (IsEqualIID(riid, IID_IDispatch))
  184. *ppvObject = (IDispatch *)this;
  185. else if (IsEqualIID(riid, IID_IUnknown))
  186. *ppvObject = this;
  187. else
  188. {
  189. *ppvObject = NULL;
  190. return E_NOINTERFACE;
  191. }
  192. AddRef();
  193. return S_OK;
  194. }
  195. ULONG CurrentSongCOM::AddRef(void)
  196. {
  197. return 0;
  198. }
  199. ULONG CurrentSongCOM::Release(void)
  200. {
  201. return 0;
  202. }
  203. static void TitleChanged_NotifyCb(IDispatch *dispatch, void *param)
  204. {
  205. UNREFERENCED_PARAMETER(param);
  206. DISPPARAMS params;
  207. unsigned int ret;
  208. if (NULL == dispatch)
  209. return;
  210. params.cArgs = 0;
  211. params.cNamedArgs = 0;
  212. params.rgdispidNamedArgs = 0;
  213. params.rgvarg = 0;
  214. if (!(config_no_visseh&8))
  215. {
  216. try
  217. {
  218. dispatch->Invoke(0, GUID_NULL, 0, DISPATCH_METHOD, &params, 0, 0, &ret);
  219. }
  220. catch (...)
  221. {}
  222. }
  223. else
  224. dispatch->Invoke(0, GUID_NULL, 0, DISPATCH_METHOD, &params, 0, 0, &ret);
  225. }
  226. void CurrentSongCOM::TitleChanged()
  227. {
  228. titleChangeCallbacks.Notify(TitleChanged_NotifyCb, NULL, NULL);
  229. }
  230. static void MetadataChanged_NotifyCb(IDispatch *dispatch, void *param)
  231. {
  232. VARIANT argument;
  233. DISPPARAMS params;
  234. if (NULL == dispatch)
  235. return;
  236. VariantInit(&argument);
  237. V_VT(&argument) = VT_BSTR;
  238. V_BSTR(&argument) = (BSTR)param;
  239. params.cArgs = 1;
  240. params.cNamedArgs = 0;
  241. params.rgdispidNamedArgs = NULL;
  242. params.rgvarg = &argument;
  243. unsigned int ret;
  244. if (!(config_no_visseh&8))
  245. {
  246. try
  247. {
  248. dispatch->Invoke(0, GUID_NULL, 0, DISPATCH_METHOD, &params, 0, 0, &ret);
  249. }
  250. catch (...)
  251. {}
  252. }
  253. else
  254. dispatch->Invoke(0, GUID_NULL, 0, DISPATCH_METHOD, &params, 0, 0, &ret);
  255. }
  256. static void MetadataChanged_FreeCb(void *param)
  257. {
  258. BSTR bstr = (BSTR)param;
  259. SysFreeString(bstr);
  260. }
  261. void CurrentSongCOM::MetadataChanged(char *metadataString)
  262. {
  263. AutoWide wideMetadata(metadataString);
  264. BSTR bstr = SysAllocString(wideMetadata);
  265. metadataCallbacks.Notify(MetadataChanged_NotifyCb, MetadataChanged_FreeCb, bstr);
  266. }