Winamp.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409
  1. #include "Winamp.h"
  2. #include "../Winamp/JSAPI.h"
  3. #include <mshtmdid.h>
  4. #include <mshtmhst.h>
  5. #include <stdio.h>
  6. #include <shlwapi.h>
  7. #include <malloc.h>
  8. #define BUFFER_LEN 1024
  9. // {294DFA02-5A90-4dc7-872D-1EF54817078D}
  10. static const GUID CLSID_WINAMP_CRAP =
  11. { 0x294dfa02, 0x5a90, 0x4dc7, { 0x87, 0x2d, 0x1e, 0xf5, 0x48, 0x17, 0x7, 0x8d } };
  12. Winamp::Winamp()
  13. {
  14. refCount=1;
  15. webBrowser_=0;
  16. connectionPointContainer=0;
  17. cookie_=0;
  18. document_=0;
  19. client_site = 0;
  20. }
  21. /* other things being asked for:
  22. {00000008-0000-0000-C000-000000000046} (dunno what interface)
  23. HTMLDocument
  24. IOleControl B196B288-BAB4-101A-B69C-00AA00341D07
  25. IClientSecurity
  26. IQuickActivate
  27. IPersistPropertyBag2
  28. IPersistPropertyBag
  29. IPersistStreamInit
  30. IPersistStorage
  31. IViewObjectEx
  32. IViewObject
  33. IActiveScript BB1A2AE1-A4F9-11CF-8F20-00805F2CD064
  34. IOleCommandTarget B722BCCB-4E68-101B-A2BC-00AA00404770
  35. IDispatchEx A6EF9860-C720-11D0-9337-00A0C90DCAA9
  36. CB5BDC81-93C1-11cf-8F20-00805F2CD064
  37. 6D5140D3-7436-11CE-8034-00AA006009FA (dunno what interface)
  38. */
  39. HRESULT Winamp::QueryInterface(REFIID riid, LPVOID FAR *ppvObj)
  40. {
  41. //DebugBreak();
  42. if (!ppvObj)
  43. return E_POINTER;
  44. else if (IsEqualIID(riid, IID_IUnknown))
  45. *ppvObj = /*static_cast<IUnknown *>*/(this);
  46. else if (IsEqualIID(riid, IID_IObjectWithSite))
  47. *ppvObj = static_cast<IObjectWithSite *>(this);
  48. //else if (IsEqualIID(riid, __uuidof(IWinamp)))
  49. //*ppvObj = static_cast<IWinamp *>(this);
  50. else if (IsEqualIID(riid, IID_IDispatch))
  51. *ppvObj = (IDispatch *)this;
  52. else if (IsEqualIID(riid, IID_IOleObject))
  53. *ppvObj = (IOleObject *)this;
  54. else if (IsEqualIID(riid, IID_IPersistStorage))
  55. *ppvObj = (IPersistStorage *)this;
  56. else if (IsEqualIID(riid, IID_IDataObject))
  57. *ppvObj = (IDataObject *)this;
  58. else if (IsEqualIID(riid, IID_IObjectSafety))
  59. *ppvObj = (IObjectSafety *)this;
  60. else
  61. {
  62. LPOLESTR guidstr;
  63. StringFromIID(riid, &guidstr);
  64. //MessageBox(NULL, guidstr, L"queryinterface", MB_OK);
  65. *ppvObj = NULL;
  66. return E_NOINTERFACE;
  67. }
  68. AddRef();
  69. return S_OK;
  70. }
  71. ULONG Winamp::AddRef(void)
  72. {
  73. return ++refCount;
  74. }
  75. ULONG Winamp::Release(void)
  76. {
  77. if (refCount == 0)
  78. return 0;
  79. ULONG retCount=--refCount;
  80. if (refCount == 0)
  81. delete this;
  82. return retCount;
  83. }
  84. #define DISP_TABLE \
  85. CHECK_ID(Test)\
  86. CHECK_ID(getVersion)\
  87. #define CHECK_ID(str) JSAPI_DISP_ENUMIFY(str),
  88. enum {
  89. DISP_TABLE
  90. };
  91. #undef CHECK_ID
  92. #define CHECK_ID(str) if (wcscmp(rgszNames[i], L## #str) == 0) { rgdispid[i] = JSAPI_DISP_ENUMIFY(str); continue; }
  93. HRESULT Winamp::GetIDsOfNames(REFIID riid, OLECHAR FAR* FAR* rgszNames, unsigned int cNames, LCID lcid, DISPID FAR* rgdispid)
  94. {
  95. bool unknowns = false;
  96. for (unsigned int i = 0;i != cNames;i++)
  97. {
  98. DISP_TABLE
  99. rgdispid[i] = DISPID_UNKNOWN;
  100. unknowns = true;
  101. }
  102. if (unknowns)
  103. return DISP_E_UNKNOWNNAME;
  104. else
  105. return S_OK;
  106. }
  107. HRESULT Winamp::GetTypeInfo(unsigned int itinfo, LCID lcid, ITypeInfo FAR* FAR* pptinfo)
  108. {
  109. return E_NOTIMPL;
  110. }
  111. HRESULT Winamp::GetTypeInfoCount(unsigned int FAR * pctinfo)
  112. {
  113. return E_NOTIMPL;
  114. }
  115. #undef CHECK_ID
  116. #define CHECK_ID(str) case JSAPI_DISP_ENUMIFY(str): return str(wFlags, pdispparams, pvarResult, puArgErr);
  117. HRESULT Winamp::Invoke(DISPID dispid, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS FAR *pdispparams, VARIANT FAR *pvarResult, EXCEPINFO FAR * pexecinfo, unsigned int FAR *puArgErr)
  118. {
  119. switch (dispid)
  120. {
  121. DISP_TABLE
  122. }
  123. return DISP_E_MEMBERNOTFOUND;
  124. }
  125. HRESULT Winamp::GetSite(REFIID riid, void** ppvSite)
  126. {
  127. return E_NOINTERFACE;
  128. }
  129. HRESULT Winamp::SetSite(IUnknown* iu)
  130. {/*
  131. if (! (iu->QueryInterface(IID_IWebBrowser2, (void**) &webBrowser_) == S_OK ))
  132. {
  133. return E_FAIL;
  134. }
  135. if (! (iu->QueryInterface(IID_IConnectionPointContainer, (void**) &connectionPointContainer) == S_OK ))
  136. {
  137. return E_FAIL;
  138. // ::MessageBox(0, "xxx", 0, 0);
  139. }
  140. // make sure we\'re getting browser events
  141. IConnectionPoint* spCP;
  142. HRESULT hr = connectionPointContainer->FindConnectionPoint(DIID_DWebBrowserEvents2, &spCP);
  143. if (FAILED(hr))
  144. {
  145. return hr;
  146. }
  147. hr = spCP->Advise(static_cast<IDispatch*>(this), &cookie_);
  148. */
  149. return S_OK;
  150. }
  151. HRESULT Winamp::Test(WORD wFlags, DISPPARAMS FAR *pdispparams, VARIANT FAR *pvarResult, unsigned int FAR *puArgErr)
  152. {
  153. JSAPI_VERIFY_METHOD(wFlags);
  154. JSAPI_VERIFY_PARAMCOUNT(pdispparams, 0);
  155. MessageBoxA(NULL,"test", "IWinamp", MB_OK);
  156. JSAPI_INIT_RESULT(pvarResult, VT_BOOL);
  157. JSAPI_SET_VARIANT(pvarResult, V_BOOL, VARIANT_TRUE);
  158. return S_OK;
  159. }
  160. #if 0
  161. HRESULT Winamp::getVersion(WORD wFlags, DISPPARAMS FAR *pdispparams, VARIANT FAR *pvarResult, unsigned int FAR *puArgErr)
  162. {
  163. JSAPI_VERIFY_METHOD(wFlags);
  164. JSAPI_VERIFY_PARAMCOUNT(pdispparams, 0);
  165. JSAPI_INIT_RESULT(pvarResult, VT_BSTR);
  166. JSAPI_SET_RESULT(pvarResult, bstrVal, SysAllocString(L"7766"));
  167. return S_OK;
  168. }
  169. #endif
  170. HRESULT Winamp::getVersion(WORD wFlags, DISPPARAMS FAR *pdispparams, VARIANT FAR *pvarResult, unsigned int FAR *puArgErr)
  171. {
  172. JSAPI_VERIFY_METHOD(wFlags);
  173. JSAPI_VERIFY_PARAMCOUNT(pdispparams, 0);
  174. wchar_t csVersion[BUFFER_LEN];
  175. ////////////////////////////////
  176. DWORD BufferSize = BUFFER_LEN;
  177. DWORD cbData;
  178. bool keyFound = false;
  179. wchar_t exeName[] = L"\\winamp.exe";
  180. wchar_t fileName[BUFFER_LEN];
  181. csVersion[0]=0;
  182. memset(&fileName[0],'\0',BUFFER_LEN);
  183. wchar_t fileNameTemp[BUFFER_LEN];
  184. HKEY hKey;
  185. cbData = BUFFER_LEN;
  186. // first check the protocol handler registry key, we're looking for
  187. // the winamp:// protocol handler. If we find this, then this is the
  188. // "right" exe for winamp we need to get the version number on
  189. if (RegOpenKeyEx(HKEY_CLASSES_ROOT, TEXT("winamp\\shell\\open\\command"), 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
  190. if ( RegQueryValueEx( hKey,
  191. TEXT(""),
  192. NULL,
  193. NULL,
  194. (LPBYTE) fileNameTemp,
  195. &cbData ) != ERROR_SUCCESS) {
  196. return ERROR_PATH_NOT_FOUND;
  197. }
  198. RegCloseKey (hKey);
  199. if (StrStrW(fileNameTemp,L"winamp.exe")) {
  200. int indexOfFirstQuote = StrCSpnW(fileNameTemp, L"\"");
  201. int indexOfSecondQuote = StrCSpnW(&fileNameTemp[indexOfFirstQuote+1], L"\"");
  202. if (indexOfFirstQuote >= 0) {
  203. keyFound = true;
  204. lstrcpynW(fileName,&fileNameTemp[indexOfFirstQuote+1], indexOfSecondQuote+1);
  205. }
  206. } else {
  207. // some other app (itunes ??) controlling the winamp:// protocol
  208. // return error
  209. return ERROR_PATH_NOT_FOUND;
  210. }
  211. }
  212. if (!keyFound) {
  213. // See if the reg key exists
  214. if (RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Software\\Winamp"), 0, KEY_READ, &hKey) != ERROR_SUCCESS) {
  215. return ERROR_PATH_NOT_FOUND;
  216. }
  217. cbData = BUFFER_LEN;
  218. if ( RegQueryValueEx( hKey,
  219. TEXT(""),
  220. NULL,
  221. NULL,
  222. (LPBYTE) fileName,
  223. &cbData ) != ERROR_SUCCESS) {
  224. return ERROR_PATH_NOT_FOUND;
  225. }
  226. RegCloseKey (hKey);
  227. keyFound = true;
  228. wcscat(fileName,exeName);
  229. }
  230. if (!keyFound) {
  231. return ERROR_PATH_NOT_FOUND;
  232. }
  233. ////////////////////////////////
  234. static TCHAR sBackSlash[] = {'\\','\0'};
  235. DWORD dwVersionDataLen = GetFileVersionInfoSize(fileName, NULL);
  236. if (dwVersionDataLen)
  237. {
  238. char* fvBuf = (char *)alloca(dwVersionDataLen);//new char[dwVersionDataLen];
  239. if (GetFileVersionInfo(fileName, 0, dwVersionDataLen, fvBuf)) {
  240. LPVOID pVal;
  241. UINT nValLen;
  242. if (VerQueryValue(fvBuf, sBackSlash, &pVal, &nValLen)) {
  243. if (nValLen == sizeof(VS_FIXEDFILEINFO)) {
  244. VS_FIXEDFILEINFO* pFixedFileInfo = (VS_FIXEDFILEINFO*)pVal;
  245. //wsprintf(csVersion, L"%d.%d.%d.%d",
  246. // HIWORD(pFixedFileInfo->dwFileVersionMS), LOWORD(pFixedFileInfo->dwFileVersionMS),
  247. // HIWORD(pFixedFileInfo->dwFileVersionLS), LOWORD(pFixedFileInfo->dwFileVersionLS));
  248. wsprintf(csVersion, L"%d.%d%d",
  249. HIWORD(pFixedFileInfo->dwFileVersionMS), LOWORD(pFixedFileInfo->dwFileVersionMS),
  250. HIWORD(pFixedFileInfo->dwFileVersionLS));
  251. }
  252. }
  253. }
  254. }
  255. JSAPI_INIT_RESULT(pvarResult, VT_BSTR);
  256. JSAPI_SET_RESULT(pvarResult, bstrVal, SysAllocString(csVersion));
  257. return S_OK;
  258. }
  259. HRESULT Winamp::SetClientSite(IOleClientSite *pClientSite)
  260. {
  261. // TODO
  262. client_site = pClientSite;
  263. return S_OK;
  264. }
  265. HRESULT Winamp::GetClientSite(IOleClientSite **ppClientSite)
  266. { return E_NOTIMPL; }
  267. HRESULT Winamp::SetHostNames(LPCOLESTR szContainerApp,LPCOLESTR szContainerObj)
  268. { return S_OK; }
  269. HRESULT Winamp::Close(DWORD dwSaveOption)
  270. { return S_OK; }
  271. HRESULT Winamp::SetMoniker(DWORD dwWhichMoniker,IMoniker *pmk)
  272. { return E_NOTIMPL; }
  273. HRESULT Winamp::GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker,IMoniker **ppmk)
  274. { return E_NOTIMPL; }
  275. HRESULT Winamp::InitFromData(IDataObject *pDataObject,BOOL fCreation,DWORD dwReserved)
  276. { return E_NOTIMPL; }
  277. HRESULT Winamp::GetClipboardData(DWORD dwReserved,IDataObject **ppDataObject)
  278. { return E_NOTIMPL; }
  279. HRESULT Winamp::DoVerb(LONG iVerb,LPMSG lpmsg,IOleClientSite *pActiveSite,LONG lindex, HWND hwndParent, LPCRECT lprcPosRect)
  280. { return S_OK; }
  281. HRESULT Winamp::EnumVerbs(IEnumOLEVERB **ppEnumOleVerb)
  282. { return E_NOTIMPL; }
  283. HRESULT Winamp::Update(void)
  284. { return E_NOTIMPL; }
  285. HRESULT Winamp::IsUpToDate(void)
  286. { return E_NOTIMPL; }
  287. HRESULT Winamp::GetUserClassID(CLSID *pClsid)
  288. { return E_NOTIMPL; }
  289. HRESULT Winamp::GetUserType(DWORD dwFormOfType,LPOLESTR *pszUserType)
  290. { return E_NOTIMPL; }
  291. HRESULT Winamp::SetExtent(DWORD dwDrawAspect,SIZEL *psizel)
  292. { return E_NOTIMPL; }
  293. HRESULT Winamp::GetExtent(DWORD dwDrawAspect,SIZEL *psizel)
  294. {
  295. // TODO
  296. return E_NOTIMPL;
  297. }
  298. HRESULT Winamp::Advise(IAdviseSink *pAdvSink,DWORD *pdwConnection)
  299. { return E_NOTIMPL; }
  300. HRESULT Winamp::Unadvise(DWORD dwConnection)
  301. { return E_NOTIMPL; }
  302. HRESULT Winamp::EnumAdvise(IEnumSTATDATA **ppenumAdvise)
  303. { return E_NOTIMPL; }
  304. HRESULT Winamp::GetMiscStatus(DWORD dwAspect,DWORD *pdwStatus)
  305. {
  306. *pdwStatus = OLEMISC_INVISIBLEATRUNTIME;
  307. return S_OK;
  308. }
  309. HRESULT Winamp::SetColorScheme(LOGPALETTE *pLogpal)
  310. { return E_NOTIMPL; }
  311. HRESULT Winamp::GetClassID(CLSID *pClassID)
  312. { *pClassID = CLSID_WINAMP_CRAP; return S_OK; }
  313. HRESULT Winamp::IsDirty(void)
  314. { return E_NOTIMPL; }
  315. HRESULT Winamp::InitNew(IStorage *pStg)
  316. { return E_NOTIMPL; }
  317. HRESULT Winamp::Load(IStorage *pStg)
  318. { return E_NOTIMPL; }
  319. HRESULT Winamp::Save(IStorage *pStgSave, BOOL fSameAsLoad)
  320. { return E_NOTIMPL; }
  321. HRESULT Winamp::SaveCompleted(IStorage *pStgNew)
  322. { return E_NOTIMPL; }
  323. HRESULT Winamp::HandsOffStorage(void)
  324. { return E_NOTIMPL; }
  325. HRESULT Winamp::GetData(FORMATETC *pformatetcIn,STGMEDIUM *pmedium)
  326. { return E_NOTIMPL; }
  327. HRESULT Winamp::GetDataHere(FORMATETC *pformatetc,STGMEDIUM *pmedium)
  328. { return E_NOTIMPL; }
  329. HRESULT Winamp::QueryGetData(FORMATETC *pformatetc)
  330. { return E_NOTIMPL; }
  331. HRESULT Winamp::GetCanonicalFormatEtc(FORMATETC *pformatectIn,FORMATETC *pformatetcOut)
  332. { return E_NOTIMPL; }
  333. HRESULT Winamp::SetData(FORMATETC *pformatetc,STGMEDIUM *pmedium,BOOL fRelease)
  334. { return E_NOTIMPL; }
  335. HRESULT Winamp::EnumFormatEtc(DWORD dwDirection,IEnumFORMATETC **ppenumFormatEtc)
  336. { return E_NOTIMPL; }
  337. HRESULT Winamp::DAdvise(FORMATETC *pformatetc,DWORD advf,IAdviseSink *pAdvSink,DWORD *pdwConnection)
  338. { return E_NOTIMPL; }
  339. HRESULT Winamp::DUnadvise(DWORD dwConnection)
  340. { return E_NOTIMPL; }
  341. HRESULT Winamp::EnumDAdvise(IEnumSTATDATA **ppenumAdvise)
  342. { return E_NOTIMPL; }
  343. HRESULT Winamp::GetInterfaceSafetyOptions(REFIID riid, DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
  344. {
  345. *pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA;
  346. *pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA;
  347. return S_OK;
  348. }
  349. HRESULT Winamp::SetInterfaceSafetyOptions(REFIID riid, DWORD dwOptionSetMask, DWORD dwEnabledOptions)
  350. {
  351. return S_OK;
  352. }