Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

603 lines
16 KiB

  1. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  2. //
  3. // oleobj.cpp
  4. //
  5. // IOleObject Implementation. IOleObject is required for for downloading
  6. // cdf files from within the browser.
  7. //
  8. // History:
  9. //
  10. // 6/18/97 edwardp Created.
  11. //
  12. ////////////////////////////////////////////////////////////////////////////////
  13. //
  14. // Includes
  15. //
  16. #include "stdinc.h"
  17. #include "cdfidl.h"
  18. #include "xmlutil.h"
  19. #include "chanapi.h"
  20. #include "chanenum.h"
  21. #include "persist.h"
  22. #include "resource.h"
  23. #include <shguidp.h>
  24. #include <htiface.h> // IID_ITargetEmbedding
  25. #define _SHDOCVW_
  26. #include <shdocvw.h>
  27. #include <mluisupp.h>
  28. STDMETHODIMP CPersist::SetClientSite(IOleClientSite *pIOleClientSite)
  29. {
  30. #ifdef IMP_CLIENTSITE
  31. if (NULL != m_pOleClientSite)
  32. m_pOleClientSite->Release();
  33. m_pOleClientSite = pIOleClientSite;
  34. if (m_pOleClientSite)
  35. m_pOleClientSite->AddRef();
  36. #endif
  37. if (pIOleClientSite && NULL == m_pIWebBrowser2)
  38. {
  39. IOleWindow *pIOleWindow;
  40. HRESULT hr = pIOleClientSite->QueryInterface(IID_IOleWindow,
  41. (void**)&pIOleWindow);
  42. if (SUCCEEDED(hr))
  43. {
  44. ASSERT(NULL != pIOleWindow);
  45. pIOleWindow->GetWindow(&m_hwnd);
  46. pIOleWindow->Release();
  47. }
  48. IServiceProvider* pIServiceProvider;
  49. hr = pIOleClientSite->QueryInterface(IID_IServiceProvider,
  50. (void**)&pIServiceProvider);
  51. if (SUCCEEDED(hr))
  52. {
  53. ASSERT(pIServiceProvider);
  54. IServiceProvider* pIServiceProvider2;
  55. hr = pIServiceProvider->QueryService(SID_STopLevelBrowser,
  56. IID_IServiceProvider,
  57. (void**)&pIServiceProvider2);
  58. if (SUCCEEDED(hr))
  59. {
  60. ASSERT(pIServiceProvider2);
  61. hr = pIServiceProvider2->QueryService(SID_SWebBrowserApp,
  62. IID_IWebBrowser2,
  63. (void**)&m_pIWebBrowser2);
  64. //
  65. // REVIEW: Determine if the current browser is IE
  66. //
  67. // New check if the browser is IE. IE will fail on a QI of
  68. // IWebBrowserApp for ITargetEmbedding. Anyone else hosting
  69. // the browser OC must support this interface.
  70. //
  71. IWebBrowserApp* pIWebBrowserApp;
  72. hr = m_pIWebBrowser2->QueryInterface(IID_IWebBrowserApp,
  73. (void**)&pIWebBrowserApp);
  74. if (SUCCEEDED(hr))
  75. {
  76. ASSERT(pIWebBrowserApp);
  77. ITargetEmbedding* pITargetEmbedding;
  78. hr = pIWebBrowserApp->QueryInterface(IID_ITargetEmbedding,
  79. (void**)&pITargetEmbedding);
  80. if (SUCCEEDED(hr))
  81. {
  82. ASSERT(pITargetEmbedding);
  83. //
  84. // This isn't IE. So release m_IWebBrowser2. IE
  85. // will be CoCreated later if m_IWebBrowser2 == NULL.
  86. //
  87. m_pIWebBrowser2->Release();
  88. m_pIWebBrowser2 = NULL;
  89. pITargetEmbedding->Release();
  90. }
  91. pIWebBrowserApp->Release();
  92. }
  93. pIServiceProvider2->Release();
  94. }
  95. pIServiceProvider->Release();
  96. }
  97. }
  98. return S_OK;
  99. }
  100. STDMETHODIMP CPersist::GetClientSite(IOleClientSite **ppClientSite)
  101. {
  102. #ifdef IMP_CLIENTSITE
  103. ASSERT(ppClientSite);
  104. if (NULL != m_pOleClientSite)
  105. {
  106. *ppClientSite = m_pOleClientSite;
  107. return S_OK;
  108. }
  109. else
  110. return E_UNEXPECTED;
  111. #else
  112. return E_NOTIMPL;
  113. #endif
  114. }
  115. STDMETHODIMP CPersist::SetHostNames(LPCOLESTR szContainerApp,
  116. LPCOLESTR szContainerObj)
  117. {
  118. return E_NOTIMPL;
  119. }
  120. STDMETHODIMP CPersist::Close(DWORD dwSaveOption)
  121. {
  122. return E_NOTIMPL;
  123. }
  124. STDMETHODIMP CPersist::SetMoniker(DWORD dwWhichMoniker, IMoniker *pmk)
  125. {
  126. return E_NOTIMPL;
  127. }
  128. STDMETHODIMP CPersist::GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker,
  129. IMoniker **ppmk)
  130. {
  131. return E_NOTIMPL;
  132. }
  133. STDMETHODIMP CPersist::InitFromData(IDataObject *pDataObject, BOOL fCreation,
  134. DWORD dwReserved)
  135. {
  136. return E_NOTIMPL;
  137. }
  138. STDMETHODIMP CPersist::GetClipboardData(DWORD dwReserved,IDataObject **ppDataObject)
  139. {
  140. return E_NOTIMPL;
  141. }
  142. STDMETHODIMP CPersist::DoVerb(LONG iVerb, LPMSG lpmsg, IOleClientSite *pActiveSite,
  143. LONG lindex, HWND hwndParent, LPCRECT lprcPosRect)
  144. {
  145. HRESULT hr;
  146. if (OLEIVERB_PRIMARY == iVerb)
  147. {
  148. ASSERT(m_pIXMLDocument);
  149. XMLDOCTYPE xdt = XML_GetDocType(m_pIXMLDocument);
  150. switch(xdt)
  151. {
  152. case DOC_CHANNEL:
  153. case DOC_SOFTWAREUPDATE:
  154. // Admins can disallow adding channels and limit
  155. // the number of installed channels.
  156. if (1 /*(dwFlags & STC_CHANNEL)*/ &&
  157. !SHRestricted2W(REST_NoAddingChannels, m_polestrURL, 0) &&
  158. (!SHRestricted2W(REST_MaxChannelCount, NULL, 0) ||
  159. (CountChannels() < SHRestricted2W(REST_MaxChannelCount, NULL, 0))))
  160. {
  161. XML_DownloadLogo(m_pIXMLDocument);
  162. //
  163. // In case the SELF tag is different than the URL get the
  164. // subscribed URL from SubscriptionHelper.
  165. //
  166. BSTR bstrSubscribedURL = NULL;
  167. if (SubscriptionHelper(m_pIXMLDocument, m_hwnd,
  168. SUBSTYPE_CHANNEL,
  169. SUBSACTION_ADDADDITIONALCOMPONENTS,
  170. m_polestrURL, xdt, &bstrSubscribedURL))
  171. {
  172. TCHAR szSubscribedURL[INTERNET_MAX_URL_LENGTH];
  173. if (bstrSubscribedURL &&
  174. SHUnicodeToTChar(bstrSubscribedURL, szSubscribedURL,
  175. ARRAYSIZE(szSubscribedURL)))
  176. {
  177. FILETIME ftLastMod;
  178. URLGetLastModTime(szSubscribedURL, &ftLastMod);
  179. Cache_AddItem(szSubscribedURL, m_pIXMLDocument,
  180. PARSE_NET, ftLastMod, g_dwCacheCount);
  181. }
  182. OpenChannel(bstrSubscribedURL);
  183. hr = S_OK;
  184. }
  185. else
  186. {
  187. hr = S_FALSE;
  188. }
  189. if (bstrSubscribedURL)
  190. SysFreeString(bstrSubscribedURL);
  191. }
  192. else
  193. {
  194. hr = E_ACCESSDENIED;
  195. }
  196. break;
  197. case DOC_DESKTOPCOMPONENT:
  198. #ifndef UNIX
  199. if (m_hwnd && WhichPlatform() != PLATFORM_INTEGRATED)
  200. #else
  201. if (0)
  202. #endif /* UNIX */
  203. {
  204. TCHAR szText[MAX_PATH];
  205. TCHAR szTitle[MAX_PATH];
  206. MLLoadString(IDS_BROWSERONLY_DLG_TEXT, szText,
  207. ARRAYSIZE(szText));
  208. MLLoadString(IDS_BROWSERONLY_DLG_TITLE, szTitle,
  209. ARRAYSIZE(szTitle));
  210. MessageBox(m_hwnd, szText, szTitle, MB_OK);
  211. }
  212. else if (1 /*dwFlags & STC_DESKTOPCOMPONENT*/)
  213. {
  214. COMPONENT Info;
  215. hr = XML_GetDesktopComponentInfo(m_pIXMLDocument, &Info);
  216. if(SUCCEEDED(hr))
  217. {
  218. if(!Info.wszSubscribedURL[0])
  219. {
  220. if(m_polestrURL)
  221. {
  222. StrCpyNW(Info.wszSubscribedURL, m_polestrURL, ARRAYSIZE(Info.wszSubscribedURL));
  223. }
  224. else
  225. {
  226. TraceMsg(TF_GENERAL, "CPersist::DoVerb : COMPONENT::wszSubscribedURL is not set.");
  227. hr = S_FALSE;
  228. }
  229. }
  230. #ifndef UNIX
  231. /* No Active Desktop on Unix */
  232. if (SUCCEEDED(hr))
  233. {
  234. IActiveDesktop* pIActiveDesktop;
  235. hr = CoCreateInstance(CLSID_ActiveDesktop, NULL, CLSCTX_INPROC_SERVER,
  236. IID_IActiveDesktop, (void**)&pIActiveDesktop);
  237. if (SUCCEEDED(hr))
  238. {
  239. ASSERT(pIActiveDesktop);
  240. hr = pIActiveDesktop->AddDesktopItemWithUI(m_hwnd, &Info, DTI_ADDUI_DISPSUBWIZARD);
  241. // Note: Do not call pIActiveDesktop->ApplyChanges() here. AddDesktopItemWithUI() itself creates
  242. // one instance of ActiveDesktop object, adds the component and calls ApplyChanges() for us.
  243. // Calling ApplyChanges() again here causes the second instance US to overwrite with stale data.
  244. // Bug #404153. Fixed by Sankar. 29th May 2001.
  245. pIActiveDesktop->Release();
  246. }
  247. else
  248. {
  249. TraceMsg(TF_GENERAL, "CPersist::DoVerb : CoCreateInstance for CLSID_ActiveDesktop failed.");
  250. }
  251. }
  252. #endif /* !UNIX */
  253. }
  254. if(SUCCEEDED(hr))
  255. {
  256. hr = S_OK;
  257. }
  258. else
  259. {
  260. hr = S_FALSE;
  261. }
  262. }
  263. else
  264. {
  265. hr = E_ACCESSDENIED;
  266. }
  267. break;
  268. case DOC_UNKNOWN:
  269. default:
  270. hr = E_FAIL;
  271. break;
  272. }
  273. }
  274. else
  275. {
  276. hr = E_NOTIMPL;
  277. }
  278. return hr;
  279. }
  280. STDMETHODIMP CPersist::EnumVerbs(IEnumOLEVERB **ppEnumOleVerb)
  281. {
  282. return E_NOTIMPL;
  283. }
  284. STDMETHODIMP CPersist::Update(void)
  285. {
  286. return E_NOTIMPL;
  287. }
  288. STDMETHODIMP CPersist::IsUpToDate(void)
  289. {
  290. return E_NOTIMPL;
  291. }
  292. STDMETHODIMP CPersist::GetUserClassID(CLSID *pClsid)
  293. {
  294. return E_FAIL;
  295. }
  296. STDMETHODIMP CPersist::GetUserType(DWORD dwFormOfType, LPOLESTR *pszUserType)
  297. {
  298. return E_NOTIMPL;
  299. }
  300. STDMETHODIMP CPersist::SetExtent(DWORD dwDrawAspect, SIZEL *psizel)
  301. {
  302. return E_NOTIMPL;
  303. }
  304. STDMETHODIMP CPersist::GetExtent(DWORD dwDrawAspect, SIZEL *psizel)
  305. {
  306. return E_NOTIMPL;
  307. }
  308. STDMETHODIMP CPersist::Advise(IAdviseSink *pAdvSink, DWORD *pdwConnection)
  309. {
  310. return E_NOTIMPL;
  311. }
  312. STDMETHODIMP CPersist::Unadvise(DWORD dwConnection)
  313. {
  314. return E_NOTIMPL;
  315. }
  316. STDMETHODIMP CPersist::EnumAdvise(IEnumSTATDATA **ppenumAdvise)
  317. {
  318. return E_NOTIMPL;
  319. }
  320. STDMETHODIMP CPersist::GetMiscStatus(DWORD dwAspect, DWORD *pdwStatus)
  321. {
  322. return E_NOTIMPL;
  323. }
  324. STDMETHODIMP CPersist::SetColorScheme(LOGPALETTE *pLogpal)
  325. {
  326. return E_NOTIMPL;
  327. }
  328. //
  329. // Helper functions.
  330. //
  331. HRESULT
  332. CPersist::OpenChannel(
  333. LPCWSTR pszSubscribedURL
  334. )
  335. {
  336. ASSERT(m_pIXMLDocument);
  337. HRESULT hr;
  338. if (NULL == m_pIWebBrowser2)
  339. {
  340. hr = CoCreateInstance(CLSID_InternetExplorer, NULL,
  341. CLSCTX_LOCAL_SERVER,
  342. IID_IWebBrowser2,
  343. (void**)&m_pIWebBrowser2);
  344. if (FAILED(hr))
  345. {
  346. return hr;
  347. }
  348. }
  349. //m_pIWebBrowser2->put_TheaterMode(-1); Moved to worker window
  350. //m_pIWebBrowser2->put_Visible(-1);
  351. //ShowChannelPane(m_pIWebBrowser2);
  352. IXMLElement* pIXMLElement;
  353. LONG nIndex;
  354. hr = XML_GetFirstChannelElement(m_pIXMLDocument,
  355. &pIXMLElement, &nIndex);
  356. if (SUCCEEDED(hr))
  357. {
  358. ASSERT(pIXMLElement);
  359. BSTR bstrURL = XML_GetAttribute(pIXMLElement, XML_HREF);
  360. if (bstrURL)
  361. {
  362. VARIANT vNull = {0};
  363. VARIANT vFlags = {0};
  364. //
  365. // check for null string
  366. //
  367. if (*bstrURL != 0)
  368. {
  369. HWND hwnd = CreateNavigationWorkerWindow(m_hwnd,
  370. m_pIWebBrowser2);
  371. if (hwnd)
  372. {
  373. LPOLESTR pszPath = Channel_GetChannelPanePath(
  374. pszSubscribedURL);
  375. if (pszPath)
  376. PostMessage(hwnd, WM_NAVIGATE_PANE, 0, (LPARAM)pszPath);
  377. PostMessage(hwnd, WM_NAVIGATE, 0, (LPARAM)bstrURL);
  378. PostMessage(hwnd, WM_CLOSE, 0, 0);
  379. }
  380. else
  381. {
  382. SysFreeString(bstrURL);
  383. }
  384. }
  385. else
  386. {
  387. SysFreeString(bstrURL);
  388. }
  389. }
  390. pIXMLElement->Release();
  391. }
  392. return hr;
  393. }
  394. HWND
  395. CPersist::CreateNavigationWorkerWindow(
  396. HWND hwndParent,
  397. IWebBrowser2* pIWebBrowser2
  398. )
  399. {
  400. ASSERT(pIWebBrowser2);
  401. HWND hwnd;
  402. static BOOL fRegistered = FALSE;
  403. if (!fRegistered) {
  404. WNDCLASS wc = {0};
  405. wc.lpfnWndProc = NavigateWndProc;
  406. wc.cbWndExtra = SIZEOF(IWebBrowser2*);
  407. wc.hInstance = g_hinst;
  408. wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  409. wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1);
  410. wc.lpszClassName = TEXT("NavigationWorker");
  411. fRegistered = (BOOL)RegisterClass(&wc);
  412. }
  413. hwnd = CreateWindow(TEXT("NavigationWorker"), NULL, WS_CHILD, 0, 0, 0, 0,
  414. hwndParent, (HMENU)0xED, g_hinst, NULL);
  415. if (hwnd) {
  416. ASSERT(sizeof(IWebBrowser2*) == sizeof(LONG));
  417. pIWebBrowser2->AddRef();
  418. SetWindowLongPtr(hwnd, 0, (LRESULT)pIWebBrowser2);
  419. }
  420. return hwnd;
  421. }
  422. LRESULT
  423. CALLBACK
  424. NavigateWndProc(
  425. HWND hwnd,
  426. UINT msg,
  427. WPARAM wParam,
  428. LPARAM lParam
  429. )
  430. {
  431. LRESULT lRet = 0;
  432. IWebBrowser2* pIWebBrowser2;
  433. switch (msg)
  434. {
  435. case WM_NAVIGATE:
  436. ASSERT(lParam);
  437. pIWebBrowser2 = (IWebBrowser2*)GetWindowLongPtr(hwnd, 0);
  438. if (pIWebBrowser2)
  439. {
  440. //pIWebBrowser2->put_TheaterMode(-1);
  441. pIWebBrowser2->put_Visible(-1);
  442. VARIANT varNull = {0};
  443. VARIANT varURL;
  444. varURL.vt = VT_BSTR;
  445. varURL.bstrVal = (BSTR)lParam;
  446. pIWebBrowser2->Navigate2(&varURL, &varNull, &varNull, &varNull,
  447. &varNull);
  448. }
  449. SysFreeString((BSTR)lParam);
  450. break;
  451. case WM_NAVIGATE_PANE:
  452. ASSERT(lParam);
  453. pIWebBrowser2 = (IWebBrowser2*)GetWindowLongPtr(hwnd, 0);
  454. if (pIWebBrowser2)
  455. {
  456. if (SUCCEEDED(ShowChannelPane(pIWebBrowser2)))
  457. NavigateChannelPane(pIWebBrowser2, (LPWSTR)lParam);
  458. }
  459. CoTaskMemFree((LPOLESTR)lParam);
  460. break;
  461. case WM_CLOSE:
  462. DestroyWindow(hwnd);
  463. break;
  464. case WM_DESTROY:
  465. pIWebBrowser2 = (IWebBrowser2*)GetWindowLongPtr(hwnd, 0);
  466. if (pIWebBrowser2)
  467. {
  468. SetWindowLongPtr(hwnd, 0, 0);
  469. pIWebBrowser2->Release();
  470. }
  471. // Fall through
  472. default:
  473. lRet = DefWindowProc(hwnd, msg, wParam, lParam);
  474. break;
  475. }
  476. return lRet;
  477. }