component.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549
  1. #include "./main.h"
  2. #include "./component.h"
  3. #include "./browserFactory.h"
  4. #include "./serviceFactory.h"
  5. #include "./utilityFactory.h"
  6. #include "./wasabiHelper.h"
  7. #include "./winampHook.h"
  8. #include "./skinHelper.h"
  9. #include "./browserClass.h"
  10. #include "./internetFeatures.h"
  11. #include "./ieVersion.h"
  12. #include <wininet.h>
  13. #include <strsafe.h>
  14. static OmBrowserFactory browserFactory;
  15. static OmServiceFactory serviceFactory;
  16. static OmUtilityFactory utilityFactory;
  17. OmBrowserComponent::OmBrowserComponent()
  18. : wasabiHelper(NULL), winampHook(NULL), skinHelper(NULL), hookCookie(0), internetFeatures(NULL)
  19. {
  20. InitializeCriticalSection(&lock);
  21. }
  22. OmBrowserComponent::~OmBrowserComponent()
  23. {
  24. ReleaseServices();
  25. if (NULL != internetFeatures)
  26. {
  27. delete(internetFeatures);
  28. internetFeatures = NULL;
  29. InternetSetOption(NULL, INTERNET_OPTION_END_BROWSER_SESSION, NULL, 0);
  30. }
  31. DeleteCriticalSection(&lock);
  32. }
  33. size_t OmBrowserComponent::AddRef()
  34. {
  35. return 1;
  36. }
  37. size_t OmBrowserComponent::Release()
  38. {
  39. return 1;
  40. }
  41. int OmBrowserComponent::QueryInterface(GUID interface_guid, void **object)
  42. {
  43. if (NULL == object) return E_POINTER;
  44. if (IsEqualIID(interface_guid, IFC_WinampHook))
  45. *object = static_cast<ifc_winamphook*>(this);
  46. else
  47. {
  48. *object = NULL;
  49. return E_NOINTERFACE;
  50. }
  51. if (NULL == *object)
  52. return E_UNEXPECTED;
  53. AddRef();
  54. return S_OK;
  55. }
  56. void OmBrowserComponent::RegisterServices(api_service *service)
  57. {
  58. EnterCriticalSection(&lock);
  59. if (NULL == wasabiHelper)
  60. WasabiHelper::CreateInstance(service, &wasabiHelper);
  61. aTRACE_LINE("omBrowser Registered");
  62. browserFactory.Register(service);
  63. serviceFactory.Register(service);
  64. utilityFactory.Register(service);
  65. LeaveCriticalSection(&lock);
  66. }
  67. void OmBrowserComponent::ReleaseServices()
  68. {
  69. EnterCriticalSection(&lock);
  70. if (NULL != wasabiHelper)
  71. {
  72. wasabiHelper->Release();
  73. wasabiHelper = NULL;
  74. }
  75. if (NULL != winampHook)
  76. {
  77. winampHook->Release();
  78. winampHook = NULL;
  79. }
  80. if (0 != hookCookie)
  81. {
  82. UnregisterWinampHook(hookCookie);
  83. hookCookie = 0;
  84. }
  85. if (NULL != skinHelper)
  86. {
  87. skinHelper->Release();
  88. skinHelper = NULL;
  89. }
  90. LeaveCriticalSection(&lock);
  91. }
  92. int OmBrowserComponent::RegisterServicesSafeModeOk()
  93. {
  94. return 1;
  95. }
  96. void OmBrowserComponent::DeregisterServices(api_service *service)
  97. {
  98. browserFactory.Unregister(service);
  99. serviceFactory.Unregister(service);
  100. utilityFactory.Unregister(service);
  101. ReleaseServices();
  102. size_t index = unloadCallbacks.size();
  103. while(index--)
  104. {
  105. PLUGINUNLOADCALLBACK callback = unloadCallbacks[index];
  106. if (NULL != callback) callback();
  107. }
  108. unloadCallbacks.clear();
  109. }
  110. HRESULT OmBrowserComponent::InitializeComponent(HWND hwndWinamp)
  111. {
  112. HRESULT hr(S_FALSE);
  113. EnterCriticalSection(&lock);
  114. if(NULL == winampHook)
  115. {
  116. HRESULT hookResult = WinampHook::CreateInstance(hwndWinamp, &winampHook);
  117. if (FAILED(hookResult) && SUCCEEDED(hr)) hr = hookResult;
  118. }
  119. if (SUCCEEDED(hr) && 0 == hookCookie)
  120. {
  121. hr = winampHook->RegisterCallback(this, &hookCookie);
  122. }
  123. if (NULL == skinHelper)
  124. {
  125. HRESULT skinResult = SkinHelper::CreateInstance(hwndWinamp, &skinHelper);
  126. if (FAILED(skinResult) && SUCCEEDED(hr)) hr = skinResult;
  127. }
  128. LeaveCriticalSection(&lock);
  129. return hr;
  130. }
  131. HRESULT OmBrowserComponent::GetWasabiHelper( ifc_wasabihelper **wasabiOut )
  132. {
  133. if ( NULL == wasabiOut ) return E_POINTER;
  134. EnterCriticalSection( &lock );
  135. *wasabiOut = wasabiHelper;
  136. if ( NULL != wasabiHelper )
  137. wasabiHelper->AddRef();
  138. LeaveCriticalSection( &lock );
  139. return ( NULL != *wasabiOut ) ? S_OK : E_NOINTERFACE;
  140. }
  141. HRESULT OmBrowserComponent::GetSkinHelper(ifc_skinhelper **skinOut)
  142. {
  143. if (NULL == skinOut) return E_POINTER;
  144. EnterCriticalSection(&lock);
  145. *skinOut = skinHelper;
  146. if (NULL != skinHelper)
  147. skinHelper->AddRef();
  148. LeaveCriticalSection(&lock);
  149. return (NULL != *skinOut) ? S_OK : E_NOINTERFACE;
  150. }
  151. HRESULT OmBrowserComponent::RegisterWinampHook(ifc_winamphook *hook, UINT *cookieOut)
  152. {
  153. if (NULL == cookieOut) return E_POINTER;
  154. *cookieOut = NULL;
  155. EnterCriticalSection(&lock);
  156. HRESULT hr = (NULL != winampHook) ? winampHook->RegisterCallback(hook, cookieOut) : E_FAIL;
  157. LeaveCriticalSection(&lock);
  158. return hr;
  159. }
  160. HRESULT OmBrowserComponent::UnregisterWinampHook(UINT cookie)
  161. {
  162. EnterCriticalSection(&lock);
  163. HRESULT hr = (NULL != winampHook) ? winampHook->UnregisterCallback(cookie) : E_FAIL;
  164. LeaveCriticalSection(&lock);
  165. return hr;
  166. }
  167. HRESULT OmBrowserComponent::GetWinampWnd(HWND *hwndWinamp)
  168. {
  169. if (NULL == hwndWinamp) return E_POINTER;
  170. EnterCriticalSection(&lock);
  171. *hwndWinamp = (NULL != winampHook) ? winampHook->GetWinamp() : NULL;
  172. LeaveCriticalSection(&lock);
  173. HRESULT hr;
  174. if (NULL == *hwndWinamp)
  175. hr = E_FAIL;
  176. else
  177. hr = S_OK;
  178. return hr;
  179. }
  180. HRESULT OmBrowserComponent::ResetFont(void)
  181. {
  182. if (NULL != skinHelper)
  183. skinHelper->ResetFontCache();
  184. return S_OK;
  185. }
  186. HRESULT OmBrowserComponent::SkinChanged(const wchar_t *skinName)
  187. {
  188. UpdateColors();
  189. return S_OK;
  190. }
  191. HRESULT OmBrowserComponent::SkinColorChange(const wchar_t *colorTheme)
  192. {
  193. UpdateColors();
  194. return S_OK;
  195. }
  196. HRESULT OmBrowserComponent::RegisterUnloadCallback(PLUGINUNLOADCALLBACK callback)
  197. {
  198. if(NULL == callback) return E_INVALIDARG;
  199. unloadCallbacks.push_back(callback);
  200. return S_OK;
  201. }
  202. HRESULT OmBrowserComponent::GetBrowserClass(LPCWSTR pszName, ifc_ombrowserclass **instance)
  203. {
  204. if (NULL == instance) return E_POINTER;
  205. HRESULT hr(S_OK);
  206. ifc_ombrowserclass *browserClass = NULL;
  207. EnterCriticalSection(&lock);
  208. size_t index = browserClasses.size();
  209. while(index--)
  210. {
  211. browserClass = browserClasses[index];
  212. if (S_OK == browserClass->IsEqual(pszName))
  213. {
  214. browserClass->AddRef();
  215. break;
  216. }
  217. }
  218. if (((size_t)-1) == index)
  219. {
  220. hr = OmBrowserClass::CreateInstance(pszName, (OmBrowserClass**)&browserClass);
  221. if (SUCCEEDED(hr) && browserClass != NULL)
  222. {
  223. if (0 == browserClasses.size())
  224. {
  225. SetUserAgent();
  226. SetInternetFeautures();
  227. }
  228. browserClasses.push_back(browserClass);
  229. }
  230. }
  231. *instance = (SUCCEEDED(hr) && browserClass != NULL) ? browserClass : NULL;
  232. LeaveCriticalSection(&lock);
  233. return hr;
  234. }
  235. HRESULT OmBrowserComponent::UnregisterBrowserClass(LPCWSTR pszName)
  236. {
  237. HRESULT hr(S_FALSE);
  238. EnterCriticalSection(&lock);
  239. size_t index = browserClasses.size();
  240. while(index--)
  241. {
  242. ifc_ombrowserclass *browserClass = browserClasses[index];
  243. if (S_OK == browserClass->IsEqual(pszName))
  244. {
  245. browserClasses.erase(browserClasses.begin() + index);
  246. hr = S_OK;
  247. break;
  248. }
  249. }
  250. LeaveCriticalSection(&lock);
  251. return hr;
  252. }
  253. void OmBrowserComponent::UpdateColors()
  254. {
  255. if (NULL != skinHelper)
  256. skinHelper->ResetColorCache();
  257. EnterCriticalSection(&lock);
  258. size_t index = browserClasses.size();
  259. while(index--)
  260. {
  261. browserClasses[index]->UpdateRegColors();
  262. }
  263. LeaveCriticalSection(&lock);
  264. InternetSetOption(NULL, INTERNET_OPTION_SETTINGS_CHANGED, NULL, 0 );
  265. }
  266. typedef struct __INTERNETFEATUREREC
  267. {
  268. INTERNETFEATURELIST entry;
  269. DWORD flags;
  270. BOOL enabled;
  271. } INTERNETFEATUREREC;
  272. void OmBrowserComponent::SetInternetFeautures()
  273. {
  274. const INTERNETFEATUREREC szFeatures[] =
  275. {
  276. { FEATURE_DISABLE_NAVIGATION_SOUNDS, SET_FEATURE_ON_PROCESS, TRUE },
  277. { FEATURE_TABBED_BROWSING, SET_FEATURE_ON_PROCESS, TRUE },
  278. { FEATURE_WINDOW_RESTRICTIONS, SET_FEATURE_ON_PROCESS, FALSE },
  279. { FEATURE_SSLUX, SET_FEATURE_ON_PROCESS, TRUE },
  280. { FEATURE_FORCE_ADDR_AND_STATUS, SET_FEATURE_ON_PROCESS, FALSE },
  281. { FEATURE_BLOCK_INPUT_PROMPTS, SET_FEATURE_ON_PROCESS, FALSE },
  282. { FEATURE_MIME_HANDLING, SET_FEATURE_ON_PROCESS, TRUE },
  283. { FEATURE_LOCALMACHINE_LOCKDOWN, SET_FEATURE_ON_PROCESS, TRUE },
  284. };
  285. EnterCriticalSection(&lock);
  286. if (NULL == internetFeatures)
  287. {
  288. internetFeatures = new InternetFeatures();
  289. if (NULL == internetFeatures)
  290. {
  291. LeaveCriticalSection(&lock);
  292. return;
  293. }
  294. }
  295. UINT modified = 0;
  296. HRESULT hr;
  297. for (INT i = 0; i < ARRAYSIZE(szFeatures); i++)
  298. {
  299. const INTERNETFEATUREREC *rec = &szFeatures[i];
  300. hr = internetFeatures->IsEnabled(rec->entry, rec->flags);
  301. if ((S_OK == hr && FALSE == rec->enabled) || (S_FALSE == hr && FALSE != rec->enabled))
  302. {
  303. if (SUCCEEDED(internetFeatures->SetEnabled(rec->entry, rec->flags, rec->enabled)))
  304. modified++;
  305. }
  306. }
  307. int majorVersion = 0;
  308. if (SUCCEEDED(MSIE_GetVersion(&majorVersion, NULL, NULL, NULL)))
  309. {
  310. unsigned long browserEmulation = 0;
  311. if (8 == majorVersion)
  312. browserEmulation = 8000;
  313. else if (9 == majorVersion)
  314. browserEmulation = 9000;
  315. else if (10 <= majorVersion)
  316. browserEmulation = 10000;
  317. else
  318. browserEmulation = 0;
  319. unsigned long valueAlreadySet = 0;
  320. hr = internetFeatures->GetDWORDFeature(L"FEATURE_BROWSER_EMULATION", TRUE, &valueAlreadySet);
  321. if (FAILED(hr) || valueAlreadySet != browserEmulation)
  322. {
  323. if (0 == browserEmulation)
  324. {
  325. if (0x80070002 /*ERROR_FILE_NOT_FOUND */ != hr)
  326. internetFeatures->DeleteFeature(L"FEATURE_BROWSER_EMULATION", TRUE);
  327. }
  328. else
  329. {
  330. if (SUCCEEDED(internetFeatures->SetDWORDFeature(L"FEATURE_BROWSER_EMULATION", TRUE, browserEmulation)))
  331. modified++;
  332. }
  333. }
  334. }
  335. LeaveCriticalSection(&lock);
  336. if (0 != modified)
  337. InternetSetOption(NULL, INTERNET_OPTION_SETTINGS_CHANGED, NULL, 0 );
  338. }
  339. static HRESULT
  340. Component_PrintWinampUA(char *buffer, size_t bufferMax)
  341. {
  342. char *cursor = buffer;
  343. size_t remaining = bufferMax;
  344. HRESULT hr = StringCchPrintfExA(cursor, remaining,
  345. &cursor, &remaining,
  346. STRSAFE_NULL_ON_FAILURE,
  347. "%S/%d.%d",
  348. OMBROWSER_NAME,
  349. OMBROWSER_VERSION_MAJOR,
  350. OMBROWSER_VERSION_MINOR);
  351. if (SUCCEEDED(hr))
  352. {
  353. ifc_wasabihelper *wasabi = NULL;
  354. if (SUCCEEDED(Plugin_GetWasabiHelper(&wasabi)) && wasabi != NULL)
  355. {
  356. api_application *app = NULL;
  357. if (SUCCEEDED(wasabi->GetApplicationApi(&app)) && app != NULL)
  358. {
  359. char *rollback = cursor;
  360. hr = StringCchPrintfExA(cursor, remaining,
  361. &cursor, &remaining,
  362. STRSAFE_NULL_ON_FAILURE,
  363. " (%S)",
  364. app->main_getVersionString());
  365. if (FAILED(hr))
  366. *rollback = '\0';
  367. app->Release();
  368. }
  369. wasabi->Release();
  370. }
  371. }
  372. if (FAILED(hr))
  373. buffer[0] = '\0';
  374. return hr;
  375. }
  376. BOOL OmBrowserComponent::SetUserAgent(void)
  377. {
  378. unsigned long bufferSize = 0;
  379. HRESULT hr = UrlMkGetSessionOption(URLMON_OPTION_USERAGENT,
  380. NULL,
  381. 0,
  382. &bufferSize,
  383. 0);
  384. if(E_OUTOFMEMORY == hr)
  385. hr = S_OK;
  386. if (FAILED(hr))
  387. return FALSE;
  388. bufferSize += 512;
  389. char *buffer = (char *)calloc(bufferSize, sizeof(char));
  390. if (NULL == buffer)
  391. return FALSE;
  392. unsigned long bufferLength = 0;
  393. hr = UrlMkGetSessionOption(URLMON_OPTION_USERAGENT,
  394. buffer,
  395. bufferSize,
  396. &bufferLength,
  397. 0);
  398. if (E_OUTOFMEMORY == hr
  399. && bufferLength <= bufferSize)
  400. {
  401. hr = S_OK;
  402. }
  403. if (SUCCEEDED(hr))
  404. {
  405. if (bufferLength > 0
  406. && bufferLength < bufferSize)
  407. {
  408. buffer[bufferLength - 1] = ' ';
  409. }
  410. hr = Component_PrintWinampUA(buffer + bufferLength,
  411. bufferSize - bufferLength);
  412. if (FAILED(hr))
  413. {
  414. if (bufferLength > 0)
  415. buffer[bufferLength - 1] = '\0';
  416. }
  417. else
  418. {
  419. bufferLength = lstrlenA(buffer);
  420. hr = UrlMkSetSessionOption(URLMON_OPTION_USERAGENT,
  421. buffer,
  422. bufferLength,
  423. 0);
  424. }
  425. }
  426. free(buffer);
  427. return SUCCEEDED(hr);
  428. }
  429. #define CBCLASS OmBrowserComponent
  430. START_MULTIPATCH;
  431. START_PATCH(MPIID_WA5COMPONENT)
  432. M_CB(MPIID_WA5COMPONENT, ifc_wa5component, ADDREF, AddRef);
  433. M_CB(MPIID_WA5COMPONENT, ifc_wa5component, RELEASE, Release);
  434. M_CB(MPIID_WA5COMPONENT, ifc_wa5component, QUERYINTERFACE, QueryInterface);
  435. M_VCB(MPIID_WA5COMPONENT, ifc_wa5component, API_WA5COMPONENT_REGISTERSERVICES, RegisterServices);
  436. M_CB(MPIID_WA5COMPONENT, ifc_wa5component, 15, RegisterServicesSafeModeOk)
  437. M_VCB(MPIID_WA5COMPONENT, ifc_wa5component, API_WA5COMPONENT_DEREEGISTERSERVICES, DeregisterServices);
  438. NEXT_PATCH(MPIID_WINAMPHOOK)
  439. M_CB(MPIID_WINAMPHOOK, ifc_winamphook, ADDREF, AddRef);
  440. M_CB(MPIID_WINAMPHOOK, ifc_winamphook, RELEASE, Release);
  441. M_CB(MPIID_WINAMPHOOK, ifc_winamphook, QUERYINTERFACE, QueryInterface);
  442. M_CB(MPIID_WINAMPHOOK, ifc_winamphook, API_RESETFONT, ResetFont);
  443. M_CB(MPIID_WINAMPHOOK, ifc_winamphook, API_SKINCHANGED, SkinChanged);
  444. M_CB(MPIID_WINAMPHOOK, ifc_winamphook, API_SKINCOLORCHANGE, SkinColorChange);
  445. END_PATCH
  446. END_MULTIPATCH;
  447. #undef CBCLASS