Leaked source code of windows server 2003
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.

1946 lines
54 KiB

  1. /******************************************************************************
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. HelpCenterExternal.cpp
  5. Abstract:
  6. This file contains the implementation of the class exposed as the "pchealth" object.
  7. Revision History:
  8. Ghim-Sim Chua (gschua) 07/23/99
  9. created
  10. Davide Massarenti (dmassare) 07/25/99
  11. modified
  12. Kalyani Narlanka (KalyaniN) 03/15/01
  13. Moved Incident and Encryption Objects from HelpService to HelpCtr to improve Perf.
  14. ******************************************************************************/
  15. #include "stdafx.h"
  16. #include "rdshost_i.c"
  17. #include "safrdm_i.c"
  18. #include "rassistance.h"
  19. #include "rassistance_i.c"
  20. #include "rcbdyctl.h"
  21. #include "rcbdyctl_i.c"
  22. #include <time.h>
  23. #include <mshtmcid.h>
  24. #include <userenv.h>
  25. /////////////////////////////////////////////////////////////////////////////
  26. static const MPC::StringToBitField s_arrMessageBoxMap[] =
  27. {
  28. { L"OK" , MB_TYPEMASK, MB_OK , -1 },
  29. { L"OKCANCEL" , MB_TYPEMASK, MB_OKCANCEL , -1 },
  30. { L"ABORTRETRYIGNORE" , MB_TYPEMASK, MB_ABORTRETRYIGNORE , -1 },
  31. { L"YESNOCANCEL" , MB_TYPEMASK, MB_YESNOCANCEL , -1 },
  32. { L"YESNO" , MB_TYPEMASK, MB_YESNO , -1 },
  33. { L"RETRYCANCEL" , MB_TYPEMASK, MB_RETRYCANCEL , -1 },
  34. { L"CANCELTRYCONTINUE", MB_TYPEMASK, MB_CANCELTRYCONTINUE, -1 },
  35. { L"ICONHAND" , MB_ICONMASK, MB_ICONHAND , -1 },
  36. { L"ICONQUESTION" , MB_ICONMASK, MB_ICONQUESTION , -1 },
  37. { L"ICONEXCLAMATION" , MB_ICONMASK, MB_ICONEXCLAMATION , -1 },
  38. { L"ICONASTERISK" , MB_ICONMASK, MB_ICONASTERISK , -1 },
  39. { L"USERICON" , MB_ICONMASK, MB_USERICON , -1 },
  40. { L"ICONWARNING" , MB_ICONMASK, MB_ICONWARNING , -1 },
  41. { L"ICONERROR" , MB_ICONMASK, MB_ICONERROR , -1 },
  42. { L"ICONINFORMATION" , MB_ICONMASK, MB_ICONINFORMATION , -1 },
  43. { L"ICONSTOP" , MB_ICONMASK, MB_ICONSTOP , -1 },
  44. { L"DEFBUTTON1" , MB_MODEMASK, MB_DEFBUTTON1 , -1 },
  45. { L"DEFBUTTON2" , MB_MODEMASK, MB_DEFBUTTON2 , -1 },
  46. { L"DEFBUTTON3" , MB_MODEMASK, MB_DEFBUTTON3 , -1 },
  47. { L"DEFBUTTON4" , MB_MODEMASK, MB_DEFBUTTON4 , -1 },
  48. { L"APPLMODAL" , MB_MODEMASK, MB_APPLMODAL , -1 },
  49. { L"SYSTEMMODAL" , MB_MODEMASK, MB_SYSTEMMODAL , -1 },
  50. { L"TASKMODAL" , MB_MODEMASK, MB_TASKMODAL , -1 },
  51. { L"HELP" , MB_MODEMASK, MB_HELP , -1 },
  52. { NULL }
  53. };
  54. static const CComBSTR s_bstrFunc_GlobalContextMenu( L"GlobalContextMenu" );
  55. static const CComBSTR s_bstrFunc_BuildTree ( L"debug_BuildTree" );
  56. /////////////////////////////////////////////////////////////////////////////
  57. CPCHSecurityHandle::CPCHSecurityHandle()
  58. {
  59. m_ext = NULL; // CPCHHelpCenterExternal* m_ext;
  60. m_object = NULL; // IDispatch* m_object;
  61. }
  62. void CPCHSecurityHandle::Initialize( /*[in]*/ CPCHHelpCenterExternal* ext, /*[in] */ IDispatch* object )
  63. {
  64. m_ext = ext;
  65. m_object = object;
  66. }
  67. void CPCHSecurityHandle::Passivate()
  68. {
  69. m_ext = NULL;
  70. m_object = NULL;
  71. }
  72. HRESULT CPCHSecurityHandle::ForwardInvokeEx( /*[in] */ DISPID id ,
  73. /*[in] */ LCID lcid ,
  74. /*[in] */ WORD wFlags ,
  75. /*[in] */ DISPPARAMS* pdp ,
  76. /*[out]*/ VARIANT* pvarRes ,
  77. /*[out]*/ EXCEPINFO* pei ,
  78. /*[in] */ IServiceProvider* pspCaller )
  79. {
  80. return m_ext ? m_ext->SetTLSAndInvoke( m_object, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller ) : E_ACCESSDENIED;
  81. }
  82. HRESULT CPCHSecurityHandle::IsTrusted()
  83. {
  84. return m_ext ? m_ext->IsTrusted() : E_ACCESSDENIED;
  85. }
  86. HRESULT CPCHSecurityHandle::IsSystem()
  87. {
  88. return m_ext ? m_ext->IsSystem() : E_ACCESSDENIED;
  89. }
  90. /////////////////////////////////////////////////////////////////////////////
  91. STDMETHODIMP CPCHHelpCenterExternal::get_HelpSession( /*[out, retval]*/ IPCHHelpSession* *pVal )
  92. {
  93. __HCP_BEGIN_PROPERTY_GET("CPCHHelpCenterExternal::get_HelpSession",hr,pVal);
  94. INTERNETSECURITY__CHECK_TRUST();
  95. if(HelpSession())
  96. {
  97. __MPC_EXIT_IF_METHOD_FAILS(hr, HelpSession()->QueryInterface( IID_IPCHHelpSession, (void**)pVal ));
  98. }
  99. __HCP_END_PROPERTY(hr);
  100. }
  101. STDMETHODIMP CPCHHelpCenterExternal::get_Channels( /*[out, retval]*/ ISAFReg* *pVal )
  102. {
  103. __HCP_BEGIN_PROPERTY_GET("CPCHHelpCenterExternal::get_Channels",hr,pVal);
  104. if(!m_Utility) __MPC_SET_ERROR_AND_EXIT(hr, E_ACCESSDENIED);
  105. INTERNETSECURITY__CHECK_TRUST();
  106. __MPC_EXIT_IF_METHOD_FAILS(hr, m_Utility->get_Channels( pVal ));
  107. __HCP_END_PROPERTY(hr);
  108. }
  109. STDMETHODIMP CPCHHelpCenterExternal::get_UserSettings( /*[out, retval]*/ IPCHUserSettings2* *pVal )
  110. {
  111. __HCP_BEGIN_PROPERTY_GET("CPCHHelpCenterExternal::get_UserSettings",hr,pVal);
  112. if(!m_UserSettings) __MPC_SET_ERROR_AND_EXIT(hr, E_ACCESSDENIED);
  113. //
  114. // We don't check trust at this stage, it's the object's responsibility to protect each one of its methods.
  115. // This is because "pchealth.UserSettings" exposes read-only properties that could be accessed from untrusted pages.
  116. //
  117. __MPC_EXIT_IF_METHOD_FAILS(hr, m_UserSettings->QueryInterface( IID_IPCHUserSettings2, (void**)pVal ));
  118. __HCP_END_PROPERTY(hr);
  119. }
  120. STDMETHODIMP CPCHHelpCenterExternal::get_Security( /*[out, retval]*/ IPCHSecurity* *pVal )
  121. {
  122. __HCP_BEGIN_PROPERTY_GET("CPCHHelpCenterExternal::get_Security",hr,pVal);
  123. if(!m_Utility) __MPC_SET_ERROR_AND_EXIT(hr, E_ACCESSDENIED);
  124. INTERNETSECURITY__CHECK_TRUST();
  125. __MPC_EXIT_IF_METHOD_FAILS(hr, m_Utility->get_Security( pVal ));
  126. __HCP_END_PROPERTY(hr);
  127. }
  128. STDMETHODIMP CPCHHelpCenterExternal::get_Connectivity( /*[out, retval]*/ IPCHConnectivity* *pVal )
  129. {
  130. __HCP_BEGIN_PROPERTY_GET("CPCHHelpCenterExternal::get_Connectivity",hr,pVal);
  131. CComPtr<CPCHConnectivity> pC;
  132. INTERNETSECURITY__CHECK_TRUST();
  133. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &pC ));
  134. __MPC_EXIT_IF_METHOD_FAILS(hr, pC->ConnectToParent( this ));
  135. __MPC_EXIT_IF_METHOD_FAILS(hr, pC.QueryInterface( pVal ));
  136. __HCP_END_PROPERTY(hr);
  137. }
  138. STDMETHODIMP CPCHHelpCenterExternal::get_Database( /*[out, retval]*/ IPCHTaxonomyDatabase* *pVal )
  139. {
  140. __HCP_BEGIN_PROPERTY_GET("CPCHHelpCenterExternal::get_Database",hr,pVal);
  141. INTERNETSECURITY__CHECK_TRUST();
  142. if(!m_Utility) __MPC_SET_ERROR_AND_EXIT(hr, E_ACCESSDENIED);
  143. __MPC_EXIT_IF_METHOD_FAILS(hr, m_Utility->get_Database( pVal ));
  144. __HCP_END_PROPERTY(hr);
  145. }
  146. STDMETHODIMP CPCHHelpCenterExternal::get_TextHelpers( /*[out, retval]*/ IPCHTextHelpers* *pVal )
  147. {
  148. __HCP_BEGIN_PROPERTY_GET("CPCHHelpCenterExternal::get_TextHelpers",hr,pVal);
  149. if(!m_TextHelpers)
  150. {
  151. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &m_TextHelpers ));
  152. }
  153. __MPC_EXIT_IF_METHOD_FAILS(hr, m_TextHelpers.QueryInterface( pVal ));
  154. __HCP_END_PROPERTY(hr);
  155. }
  156. /////////////////////////////////////////////////////////////////////////////
  157. HRESULT CPCHHelpCenterExternal::get_UI_Panel( /*[out, retval]*/ IUnknown* *pVal, /*[in]*/ HscPanel id )
  158. {
  159. __HCP_BEGIN_PROPERTY_GET("CPCHHelpCenterExternal::get_UI_Panel",hr,pVal);
  160. INTERNETSECURITY__CHECK_SYSTEM();
  161. __MPC_EXIT_IF_METHOD_FAILS(hr, GetPanel( id, (IMarsPanel**)pVal, true ));
  162. __HCP_END_PROPERTY(hr);
  163. }
  164. HRESULT CPCHHelpCenterExternal::get_WEB_Panel( /*[out, retval]*/ IUnknown* *pVal, /*[in]*/ HscPanel id )
  165. {
  166. __HCP_BEGIN_PROPERTY_GET("CPCHHelpCenterExternal::get_WEB_Panel",hr,pVal);
  167. CComPtr<IMarsPanel> panel;
  168. CComPtr<IWebBrowser2> wb;
  169. INTERNETSECURITY__CHECK_SYSTEM();
  170. __MPC_EXIT_IF_METHOD_FAILS(hr, GetPanel( id, &panel, true ));
  171. switch(id)
  172. {
  173. case HSCPANEL_CONTEXT : wb = m_panel_CONTEXT_WebBrowser ; break;
  174. case HSCPANEL_CONTENTS: wb = m_panel_CONTENTS_WebBrowser; break;
  175. case HSCPANEL_HHWINDOW: wb = m_panel_HHWINDOW_WebBrowser; break;
  176. }
  177. *pVal = wb.Detach();
  178. __HCP_END_PROPERTY(hr);
  179. }
  180. STDMETHODIMP CPCHHelpCenterExternal::get_UI_NavBar ( /*[out, retval]*/ IUnknown* *pVal ) { return get_UI_Panel( pVal, HSCPANEL_NAVBAR ); }
  181. STDMETHODIMP CPCHHelpCenterExternal::get_UI_MiniNavBar( /*[out, retval]*/ IUnknown* *pVal ) { return get_UI_Panel( pVal, HSCPANEL_MININAVBAR ); }
  182. STDMETHODIMP CPCHHelpCenterExternal::get_UI_Context ( /*[out, retval]*/ IUnknown* *pVal ) { return get_UI_Panel( pVal, HSCPANEL_CONTEXT ); }
  183. STDMETHODIMP CPCHHelpCenterExternal::get_UI_Contents ( /*[out, retval]*/ IUnknown* *pVal ) { return get_UI_Panel( pVal, HSCPANEL_CONTENTS ); }
  184. STDMETHODIMP CPCHHelpCenterExternal::get_UI_HHWindow ( /*[out, retval]*/ IUnknown* *pVal ) { return get_UI_Panel( pVal, HSCPANEL_HHWINDOW ); }
  185. STDMETHODIMP CPCHHelpCenterExternal::get_WEB_Context ( /*[out, retval]*/ IUnknown* *pVal ) { return get_WEB_Panel( pVal, HSCPANEL_CONTEXT ); }
  186. STDMETHODIMP CPCHHelpCenterExternal::get_WEB_Contents( /*[out, retval]*/ IUnknown* *pVal ) { return get_WEB_Panel( pVal, HSCPANEL_CONTENTS ); }
  187. STDMETHODIMP CPCHHelpCenterExternal::get_WEB_HHWindow( /*[out, retval]*/ IUnknown* *pVal ) { return get_WEB_Panel( pVal, HSCPANEL_HHWINDOW ); }
  188. STDMETHODIMP CPCHHelpCenterExternal::get_ExtraArgument( /*[out, retval]*/ BSTR *pVal )
  189. {
  190. __HCP_BEGIN_PROPERTY_GET("CPCHHelpCenterExternal::get_ExtraArgument",hr,pVal);
  191. INTERNETSECURITY__CHECK_TRUST();
  192. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::GetBSTR( m_bstrExtraArgument, pVal ));
  193. __HCP_END_PROPERTY(hr);
  194. }
  195. STDMETHODIMP CPCHHelpCenterExternal::get_HelpViewer( /*[out, retval]*/ IUnknown* *pVal )
  196. {
  197. __HCP_BEGIN_PROPERTY_GET("CPCHHelpCenterExternal::get_HelpViewer",hr,pVal);
  198. INTERNETSECURITY__CHECK_TRUST();
  199. MPC::CopyTo( (IPCHHelpViewerWrapper*)m_panel_HHWINDOW_Wrapper, pVal );
  200. __HCP_END_PROPERTY(hr);
  201. }
  202. STDMETHODIMP CPCHHelpCenterExternal::RegisterEvents( /*[in]*/ BSTR id ,
  203. /*[in]*/ long pri ,
  204. /*[in]*/ IDispatch* function ,
  205. /*[out,retval]*/ long *cookie )
  206. {
  207. __HCP_FUNC_ENTRY( "CPCHHelpCenterExternal::RegisterEvents" );
  208. HRESULT hr;
  209. __MPC_PARAMCHECK_BEGIN(hr)
  210. __MPC_PARAMCHECK_STRING_NOT_EMPTY(id);
  211. __MPC_PARAMCHECK_POINTER_AND_SET(cookie,0);
  212. __MPC_PARAMCHECK_END();
  213. INTERNETSECURITY__CHECK_TRUST();
  214. hr = m_Events.RegisterEvents( id, pri, function, cookie );
  215. __HCP_FUNC_CLEANUP;
  216. __HCP_FUNC_EXIT(hr);
  217. }
  218. STDMETHODIMP CPCHHelpCenterExternal::UnregisterEvents( /*[in]*/ long cookie )
  219. {
  220. __HCP_FUNC_ENTRY( "CPCHHelpCenterExternal::UnregisterEvents" );
  221. HRESULT hr;
  222. INTERNETSECURITY__CHECK_TRUST();
  223. hr = m_Events.UnregisterEvents( cookie );
  224. __HCP_FUNC_CLEANUP;
  225. __HCP_FUNC_EXIT(hr);
  226. }
  227. /////////////////////////////////////////////////////////////////////////////
  228. STDMETHODIMP CPCHHelpCenterExternal::CreateObject_SearchEngineMgr( /*[out, retval]*/ IPCHSEManager* *ppSE )
  229. {
  230. __HCP_BEGIN_PROPERTY_GET("CPCHHelpCenterExternal::CreateObject_SearchEngineMgr",hr,ppSE);
  231. INTERNETSECURITY__CHECK_TRUST();
  232. if(!m_Utility) __MPC_SET_ERROR_AND_EXIT(hr, E_ACCESSDENIED);
  233. __MPC_EXIT_IF_METHOD_FAILS(hr, m_Utility->CreateObject_SearchEngineMgr( ppSE ));
  234. __HCP_END_PROPERTY(hr);
  235. }
  236. STDMETHODIMP CPCHHelpCenterExternal::CreateObject_DataCollection( /*[out, retval]*/ ISAFDataCollection* *ppDC )
  237. {
  238. __HCP_BEGIN_PROPERTY_GET("CPCHHelpCenterExternal::CreateObject_DataCollection",hr,ppDC);
  239. INTERNETSECURITY__CHECK_TRUST();
  240. if(!m_Utility) __MPC_SET_ERROR_AND_EXIT(hr, E_ACCESSDENIED);
  241. __MPC_EXIT_IF_METHOD_FAILS(hr, m_Utility->CreateObject_DataCollection( ppDC ));
  242. __HCP_END_PROPERTY(hr);
  243. }
  244. STDMETHODIMP CPCHHelpCenterExternal::CreateObject_Cabinet( /*[out , retval]*/ ISAFCabinet* *ppCB )
  245. {
  246. __HCP_BEGIN_PROPERTY_GET("CPCHHelpCenterExternal::CreateObject_Cabinet",hr,ppCB);
  247. INTERNETSECURITY__CHECK_TRUST();
  248. if(!m_Utility) __MPC_SET_ERROR_AND_EXIT(hr, E_ACCESSDENIED);
  249. __MPC_EXIT_IF_METHOD_FAILS(hr, m_Utility->CreateObject_Cabinet( ppCB ));
  250. __HCP_END_PROPERTY(hr);
  251. }
  252. STDMETHODIMP CPCHHelpCenterExternal::CreateObject_Encryption( /*[out, retval]*/ ISAFEncrypt* *ppEn )
  253. {
  254. __HCP_BEGIN_PROPERTY_GET("CPCHHelpCenterExternal::CreateObject_Encryption",hr,ppEn);
  255. bool fTemporaryProfile = false;
  256. DWORD dwProfileFlags;
  257. INTERNETSECURITY__CHECK_TRUST();
  258. if(::GetProfileType( &dwProfileFlags ))
  259. {
  260. if(( dwProfileFlags & PT_MANDATORY ) ||
  261. ((dwProfileFlags & PT_TEMPORARY) && !(dwProfileFlags & PT_ROAMING)) )
  262. {
  263. fTemporaryProfile = true;
  264. }
  265. }
  266. if(fTemporaryProfile)
  267. {
  268. if(!m_Utility) __MPC_SET_ERROR_AND_EXIT(hr, E_ACCESSDENIED);
  269. __MPC_EXIT_IF_METHOD_FAILS(hr, m_Utility->CreateObject_Encryption( ppEn ));
  270. }
  271. else
  272. {
  273. CComPtr<CSAFEncrypt> pEn;
  274. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &pEn ));
  275. __MPC_EXIT_IF_METHOD_FAILS(hr, pEn.QueryInterface( ppEn ));
  276. }
  277. __HCP_END_PROPERTY(hr);
  278. }
  279. STDMETHODIMP CPCHHelpCenterExternal::CreateObject_Channel( /*[in] */ BSTR bstrVendorID ,
  280. /*[in] */ BSTR bstrProductID ,
  281. /*[out, retval]*/ ISAFChannel* *ppCh )
  282. {
  283. __HCP_BEGIN_PROPERTY_GET("CPCHHelpCenterExternal::CreateObject_Channel",hr,ppCh);
  284. INTERNETSECURITY__CHECK_TRUST();
  285. if(!m_Utility) __MPC_SET_ERROR_AND_EXIT(hr, E_ACCESSDENIED);
  286. __MPC_EXIT_IF_METHOD_FAILS(hr, m_Utility->CreateObject_Channel( bstrVendorID, bstrProductID, ppCh ));
  287. __HCP_END_PROPERTY(hr);
  288. }
  289. STDMETHODIMP CPCHHelpCenterExternal::CreateObject_Incident( /*[out, retval]*/ ISAFIncident* *ppIn )
  290. {
  291. __HCP_BEGIN_PROPERTY_GET("CPCHHelpCenterExternal::CreateObject_Incident",hr,ppIn);
  292. CComPtr<CSAFIncident> pIn;
  293. INTERNETSECURITY__CHECK_TRUST();
  294. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &pIn ));
  295. __MPC_EXIT_IF_METHOD_FAILS(hr, pIn.QueryInterface( ppIn ));
  296. __HCP_END_PROPERTY(hr);
  297. }
  298. STDMETHODIMP CPCHHelpCenterExternal::CreateObject_RemoteAssistanceIncident( /* [in] */ BSTR bstrRCTicket,
  299. /* [in] */ long lTimeout,
  300. /* [in] */ BSTR bstrUserName,
  301. /* [in] */ BSTR bstrMessage,
  302. /* [in] */ BSTR bstrPassword,
  303. /* [out,retval] */ ISAFIncident* *ppIn)
  304. {
  305. // This purpose of this method is to hide RemoteDesktopSession object from users.
  306. __HCP_FUNC_ENTRY( "CPCHHelpCenterExternal::CreateObject_RemoteAssistanceIncident" );
  307. HRESULT hr;
  308. CComBSTR pTicket, pUserBlob = "";
  309. CComPtr<ISAFRemoteDesktopSession> pSession;
  310. CComPtr<IDispatch> pDisp;
  311. CComPtr<IDictionary> pMisc;
  312. CComBSTR pEmpty = "";
  313. WCHAR szHeader[12];
  314. time_t ltime;
  315. BOOL bOpenSession = FALSE;
  316. INTERNETSECURITY__CHECK_TRUST();
  317. if(!m_Utility) __MPC_SET_ERROR_AND_EXIT(hr, E_ACCESSDENIED);
  318. // Need to create incident object first.
  319. __MPC_EXIT_IF_METHOD_FAILS(hr, CreateObject_Incident(ppIn));
  320. if (bstrRCTicket != NULL && *bstrRCTicket != L'\0')
  321. { // open existing session
  322. __MPC_EXIT_IF_METHOD_FAILS(hr, CreateObject_RemoteDesktopSession(0, bstrRCTicket, (BSTR)pEmpty, &pSession));
  323. // Get salem ticket.
  324. __MPC_EXIT_IF_METHOD_FAILS(hr, pSession->get_ConnectParms(&pTicket));
  325. }
  326. else
  327. { // create new session
  328. if (bstrUserName != NULL && *bstrUserName != L'\0')
  329. {
  330. wsprintf(szHeader, L"%d;FROM=", 5 + wcslen(bstrUserName));
  331. pUserBlob = szHeader;
  332. pUserBlob.Append(bstrUserName);
  333. }
  334. __MPC_EXIT_IF_METHOD_FAILS(hr, CreateObject_RemoteDesktopSession(lTimeout, (BSTR)pEmpty, (BSTR)pUserBlob, &pSession));
  335. // Get salem ticket.
  336. __MPC_EXIT_IF_METHOD_FAILS(hr, pSession->get_ConnectParms(&pTicket));
  337. if (bstrPassword != NULL && *bstrPassword != L'\0')
  338. {
  339. // Use session ID as the base of password challenge.
  340. // Need to create challenge for password.
  341. // Get ISetting of rcbdyctl.dll.
  342. CComPtr<ISAFEncrypt> pEnc;
  343. CComBSTR pString = pTicket;
  344. CComBSTR pPassStub;
  345. // Need to parse and get Session ID
  346. WCHAR *token;
  347. WCHAR *seps = L",";
  348. token = wcstok(pString, seps );
  349. int idx = 0; // Session ID is at [4]
  350. while( token != NULL && ++idx <= 4 )
  351. token = wcstok(NULL, seps);
  352. if (token == NULL)
  353. __MPC_SET_ERROR_AND_EXIT(hr, E_INVALIDARG);
  354. __MPC_EXIT_IF_METHOD_FAILS(hr, CreateObject_Encryption(&pEnc));
  355. __MPC_EXIT_IF_METHOD_FAILS(hr, pEnc->EncryptString(bstrPassword, (BSTR)CComBSTR(token), &pPassStub));
  356. // update user help blob
  357. wsprintf(szHeader, L"%d;PASS=", 5 + pPassStub.Length());
  358. pUserBlob += szHeader;
  359. pUserBlob.Append(pPassStub);
  360. // Update user help blob
  361. __MPC_EXIT_IF_METHOD_FAILS(hr, pSession->put_UserBlob(pUserBlob));
  362. __MPC_EXIT_IF_METHOD_FAILS(hr, (*ppIn)->put_RCTicketEncrypted(VARIANT_TRUE));
  363. }
  364. time(&ltime);
  365. // Initialize incident object with needed properties.
  366. __MPC_EXIT_IF_METHOD_FAILS(hr, (*ppIn)->put_UserName(bstrUserName));
  367. __MPC_EXIT_IF_METHOD_FAILS(hr, (*ppIn)->put_ProblemDescription(bstrMessage));
  368. __MPC_EXIT_IF_METHOD_FAILS(hr, (*ppIn)->get_Misc(&pDisp));
  369. __MPC_EXIT_IF_METHOD_FAILS(hr, pDisp->QueryInterface(IID_IDictionary, (LPVOID*)&pMisc));
  370. __MPC_EXIT_IF_METHOD_FAILS(hr, pMisc->put_Item(&CComVariant("DtStart"), &CComVariant((LONG)ltime)));
  371. __MPC_EXIT_IF_METHOD_FAILS(hr, pMisc->put_Item(&CComVariant("DtLength"), &CComVariant(lTimeout/60))); // convert it to minute
  372. // if (pPassStub.Length())
  373. // __MPC_EXIT_IF_METHOD_FAILS(hr, pMisc->put_Item(&CComVariant("PassStub"), &CComVariant((BSTR)pPassStub)));
  374. }
  375. __MPC_EXIT_IF_METHOD_FAILS(hr, (*ppIn)->put_RCTicket((BSTR)pTicket));
  376. __HCP_FUNC_CLEANUP;
  377. // If it failed, we should release the interfaces.
  378. if (FAILED(hr))
  379. {
  380. if(*ppIn != NULL)
  381. {
  382. (*ppIn)->Release();
  383. (*ppIn) = NULL;
  384. }
  385. if(!pSession == FALSE) // Not empty
  386. pSession->CloseRemoteDesktopSession();
  387. }
  388. __HCP_FUNC_EXIT(hr);
  389. }
  390. ////////////////////////////////////////////////////////////////////////////////
  391. STDMETHODIMP CPCHHelpCenterExternal::CreateObject_RemoteDesktopSession(
  392. /*[in]*/ long lTimeout ,
  393. /*[in]*/ BSTR bstrConnectionParms ,
  394. /*[in]*/ BSTR bstrUserHelpBlob ,
  395. /*[out, retval]*/ ISAFRemoteDesktopSession* *ppRCS )
  396. {
  397. __HCP_BEGIN_PROPERTY_GET("CPCHHelpCenterExternal::CreateObject_RemoteDesktopSession",hr,ppRCS);
  398. REMOTE_DESKTOP_SHARING_CLASS sharingClass = VIEWDESKTOP_PERMISSION_NOT_REQUIRE;
  399. INTERNETSECURITY__CHECK_TRUST();
  400. if(!m_Utility) __MPC_SET_ERROR_AND_EXIT(hr, E_ACCESSDENIED);
  401. __MPC_EXIT_IF_METHOD_FAILS(hr, m_Utility->CreateObject_RemoteDesktopSession( sharingClass, lTimeout, bstrConnectionParms, bstrUserHelpBlob, ppRCS ));
  402. __HCP_END_PROPERTY(hr);
  403. }
  404. STDMETHODIMP CPCHHelpCenterExternal::ConnectToExpert( /* [in] */ BSTR bstrExpertConnectParm,
  405. /* [in] */ LONG lTimeout,
  406. /* [retval][out] */ LONG *lSafErrorCode)
  407. {
  408. __HCP_BEGIN_PROPERTY_GET("CPCHHelpCenterExternal::ConnectToExpert",hr,lSafErrorCode);
  409. INTERNETSECURITY__CHECK_TRUST();
  410. if(!m_Utility) __MPC_SET_ERROR_AND_EXIT(hr, E_ACCESSDENIED);
  411. __MPC_EXIT_IF_METHOD_FAILS(hr, m_Utility->ConnectToExpert( bstrExpertConnectParm, lTimeout, lSafErrorCode));
  412. __HCP_END_PROPERTY(hr);
  413. }
  414. STDMETHODIMP CPCHHelpCenterExternal::CreateObject_RemoteDesktopManager( /*[out, retval]*/ ISAFRemoteDesktopManager* *ppRDM )
  415. {
  416. __HCP_BEGIN_PROPERTY_GET("CPCHHelpCenterExternal::CreateObject_RemoteDesktopManager",hr,ppRDM);
  417. CComPtr<ISAFRemoteDesktopManager> pSAFRDManager;
  418. INTERNETSECURITY__CHECK_TRUST();
  419. // Instantiate ISAFRemoteDesktopManager.
  420. __MPC_EXIT_IF_METHOD_FAILS(hr, pSAFRDManager.CoCreateInstance( CLSID_SAFRemoteDesktopManager, NULL, CLSCTX_INPROC_SERVER ));
  421. *ppRDM = pSAFRDManager.Detach();
  422. __HCP_END_PROPERTY(hr);
  423. }
  424. STDMETHODIMP CPCHHelpCenterExternal::CreateObject_RemoteDesktopConnection( /*[out, retval]*/ ISAFRemoteDesktopConnection* *ppRDC )
  425. {
  426. __HCP_BEGIN_PROPERTY_GET("CPCHHelpCenterExternal::CreateObject_RemoteDesktopConnection",hr,ppRDC);
  427. INTERNETSECURITY__CHECK_TRUST();
  428. if(!m_Utility) __MPC_SET_ERROR_AND_EXIT(hr, E_ACCESSDENIED);
  429. __MPC_EXIT_IF_METHOD_FAILS(hr, m_Utility->CreateObject_RemoteDesktopConnection( ppRDC ));
  430. __HCP_END_PROPERTY(hr);
  431. }
  432. ////////////////////////////////////////////////////////////////////////////////
  433. STDMETHODIMP CPCHHelpCenterExternal::CreateObject_ContextMenu( /*[out, retval]*/ IPCHContextMenu* *ppCM )
  434. {
  435. __HCP_BEGIN_PROPERTY_GET("CPCHHelpCenterExternal::CreateObject_ContextMenu",hr,ppCM);
  436. CComPtr<CPCHContextMenu> pObj;
  437. INTERNETSECURITY__CHECK_TRUST();
  438. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &pObj )); pObj->Initialize( this );
  439. __MPC_EXIT_IF_METHOD_FAILS(hr, pObj.QueryInterface( ppCM ));
  440. __HCP_END_PROPERTY(hr);
  441. }
  442. STDMETHODIMP CPCHHelpCenterExternal::CreateObject_PrintEngine( /*[out, retval]*/ IPCHPrintEngine* *ppPE )
  443. {
  444. __HCP_BEGIN_PROPERTY_GET("CPCHHelpCenterExternal::CreateObject_PrintEngine",hr,ppPE);
  445. CComPtr<CPCHPrintEngine> pObj;
  446. INTERNETSECURITY__CHECK_TRUST();
  447. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &pObj ));
  448. __MPC_EXIT_IF_METHOD_FAILS(hr, pObj.QueryInterface( ppPE ));
  449. __HCP_END_PROPERTY(hr);
  450. }
  451. ////////////////////////////////////////////////////////////////////////////////
  452. STDMETHODIMP CPCHHelpCenterExternal::CreateObject_IntercomClient( /* [out, retval] */ ISAFIntercomClient* *ppI )
  453. {
  454. __HCP_BEGIN_PROPERTY_GET("CPCHHelpCenterExternal::CreateObject_IntercomClient",hr,ppI);
  455. CComPtr<CSAFIntercomClient> pObj;
  456. INTERNETSECURITY__CHECK_TRUST();
  457. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &pObj ));
  458. __MPC_EXIT_IF_METHOD_FAILS(hr, pObj.QueryInterface( ppI ));
  459. __HCP_END_PROPERTY(hr);
  460. }
  461. STDMETHODIMP CPCHHelpCenterExternal::CreateObject_IntercomServer( /* [out, retval] */ ISAFIntercomServer* *ppI )
  462. {
  463. __HCP_BEGIN_PROPERTY_GET("CPCHHelpCenterExternal::CreateObject_IntercomServer",hr,ppI);
  464. CComPtr<CSAFIntercomServer> pObj;
  465. INTERNETSECURITY__CHECK_TRUST();
  466. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &pObj ));
  467. __MPC_EXIT_IF_METHOD_FAILS(hr, pObj.QueryInterface( ppI ));
  468. __HCP_END_PROPERTY(hr);
  469. }
  470. /////////////////////////////////////////////////////////////////////////////
  471. STDMETHODIMP CPCHHelpCenterExternal::OpenFileAsStream( /*[in]*/ BSTR bstrFilename ,
  472. /*[out, retval]*/ IUnknown* *stream )
  473. {
  474. __HCP_FUNC_ENTRY( "CPCHHelpCenterExternal::OpenFileAsStream" );
  475. HRESULT hr;
  476. CComPtr<CPCHScriptableStream> fsStream;
  477. __MPC_PARAMCHECK_BEGIN(hr)
  478. __MPC_PARAMCHECK_STRING_NOT_EMPTY(bstrFilename);
  479. __MPC_PARAMCHECK_POINTER_AND_SET(stream,NULL);
  480. __MPC_PARAMCHECK_END();
  481. INTERNETSECURITY__CHECK_TRUST();
  482. //
  483. // Create a stream for a file.
  484. //
  485. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &fsStream ));
  486. __MPC_EXIT_IF_METHOD_FAILS(hr, fsStream->InitForRead( bstrFilename ));
  487. __MPC_EXIT_IF_METHOD_FAILS(hr, fsStream.QueryInterface( stream ));
  488. hr = S_OK;
  489. __HCP_FUNC_CLEANUP;
  490. __HCP_FUNC_EXIT(hr);
  491. }
  492. STDMETHODIMP CPCHHelpCenterExternal::CreateFileAsStream( /*[in]*/ BSTR bstrFilename ,
  493. /*[out, retval]*/ IUnknown* *stream )
  494. {
  495. __HCP_FUNC_ENTRY( "CPCHHelpCenterExternal::OpenFileAsStream" );
  496. HRESULT hr;
  497. CComPtr<CPCHScriptableStream> fsStream;
  498. __MPC_PARAMCHECK_BEGIN(hr)
  499. __MPC_PARAMCHECK_STRING_NOT_EMPTY(bstrFilename);
  500. __MPC_PARAMCHECK_POINTER_AND_SET(stream,NULL);
  501. __MPC_PARAMCHECK_END();
  502. INTERNETSECURITY__CHECK_TRUST();
  503. //
  504. // Create a stream for a file.
  505. //
  506. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &fsStream ));
  507. __MPC_EXIT_IF_METHOD_FAILS(hr, fsStream->InitForWrite( bstrFilename ));
  508. __MPC_EXIT_IF_METHOD_FAILS(hr, fsStream.QueryInterface( stream ));
  509. hr = S_OK;
  510. __HCP_FUNC_CLEANUP;
  511. __HCP_FUNC_EXIT(hr);
  512. }
  513. STDMETHODIMP CPCHHelpCenterExternal::CopyStreamToFile( /*[in]*/ BSTR bstrFilename ,
  514. /*[in]*/ IUnknown* stream )
  515. {
  516. __HCP_FUNC_ENTRY( "CPCHHelpCenterExternal::CopyStreamToFile" );
  517. HRESULT hr;
  518. CComPtr<MPC::FileStream> fsStreamDst;
  519. CComPtr<IStream> fsStreamSrc;
  520. LARGE_INTEGER li;
  521. __MPC_PARAMCHECK_BEGIN(hr)
  522. __MPC_PARAMCHECK_STRING_NOT_EMPTY(bstrFilename);
  523. __MPC_PARAMCHECK_NOTNULL(stream);
  524. __MPC_PARAMCHECK_END();
  525. //
  526. // Create a stream for a file.
  527. //
  528. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &fsStreamDst ));
  529. __MPC_EXIT_IF_METHOD_FAILS(hr, fsStreamDst->InitForWrite( bstrFilename ));
  530. //
  531. // Copy the source stream to the file.
  532. //
  533. li.LowPart = 0;
  534. li.HighPart = 0;
  535. __MPC_EXIT_IF_METHOD_FAILS(hr, stream->QueryInterface ( IID_IStream, (void**)&fsStreamSrc ));
  536. __MPC_EXIT_IF_METHOD_FAILS(hr, fsStreamSrc->Seek ( li, STREAM_SEEK_SET, NULL )); // Rewind the stream.
  537. __MPC_EXIT_IF_METHOD_FAILS(hr, fsStreamDst->TransferData( fsStreamSrc, fsStreamDst ));
  538. hr = S_OK;
  539. __HCP_FUNC_CLEANUP;
  540. __HCP_FUNC_EXIT(hr);
  541. }
  542. /////////////////////////////////////////////////////////////////////////////
  543. STDMETHODIMP CPCHHelpCenterExternal::NetworkAlive( /*[out, retval]*/ VARIANT_BOOL *pVal )
  544. {
  545. __HCP_FUNC_ENTRY( "CPCHHelpCenterExternal::NetworkAlive" );
  546. HRESULT hr;
  547. CComPtr<IPCHConnectivity> pchc;
  548. INTERNETSECURITY__CHECK_TRUST();
  549. __MPC_EXIT_IF_METHOD_FAILS(hr, get_Connectivity( &pchc ));
  550. __MPC_EXIT_IF_METHOD_FAILS(hr, pchc->NetworkAlive( pVal ));
  551. hr = S_OK;
  552. __HCP_FUNC_CLEANUP;
  553. __HCP_FUNC_EXIT(hr);
  554. }
  555. STDMETHODIMP CPCHHelpCenterExternal::DestinationReachable( /*[in] */ BSTR bstrURL ,
  556. /*[out, retval]*/ VARIANT_BOOL *pVal )
  557. {
  558. __HCP_FUNC_ENTRY( "CPCHHelpCenterExternal::DestinationReachable" );
  559. HRESULT hr;
  560. CComPtr<IPCHConnectivity> pchc;
  561. INTERNETSECURITY__CHECK_TRUST();
  562. __MPC_EXIT_IF_METHOD_FAILS(hr, get_Connectivity( &pchc ));
  563. __MPC_EXIT_IF_METHOD_FAILS(hr, pchc->DestinationReachable( bstrURL, pVal ));
  564. hr = S_OK;
  565. __HCP_FUNC_CLEANUP;
  566. __HCP_FUNC_EXIT(hr);
  567. }
  568. ////////////////////////////////////////////////////////////////////////////////
  569. STDMETHODIMP CPCHHelpCenterExternal::FormatError( /*[in ]*/ VARIANT vError ,
  570. /*[out, retval]*/ BSTR *pVal )
  571. {
  572. __HCP_BEGIN_PROPERTY_GET("CPCHHelpCenterExternal::FormatError",hr,pVal);
  573. INTERNETSECURITY__CHECK_TRUST();
  574. if(!m_Utility) __MPC_SET_ERROR_AND_EXIT(hr, E_ACCESSDENIED);
  575. __MPC_EXIT_IF_METHOD_FAILS(hr, m_Utility->FormatError( vError, pVal ));
  576. __HCP_END_PROPERTY(hr);
  577. }
  578. HRESULT CPCHHelpCenterExternal::RegInit( /*[in]*/ BSTR bstrKey ,
  579. /*[in]*/ bool fRead ,
  580. /*[out]*/ MPC::RegKey& rk ,
  581. /*[out]*/ MPC::wstring& strValue )
  582. {
  583. __HCP_FUNC_ENTRY( "CPCHHelpCenterExternal::RegInit" );
  584. HRESULT hr;
  585. HKEY hKeyRoot = HKEY_LOCAL_MACHINE;
  586. MPC::wstring strKey;
  587. LPCWSTR szPtr;
  588. LPCWSTR szPtr2;
  589. __MPC_PARAMCHECK_BEGIN(hr)
  590. __MPC_PARAMCHECK_STRING_NOT_EMPTY(bstrKey);
  591. __MPC_PARAMCHECK_END();
  592. INTERNETSECURITY__CHECK_TRUST();
  593. szPtr = bstrKey;
  594. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::RegKey::ParsePath( szPtr, hKeyRoot, szPtr ));
  595. szPtr2 = wcsrchr( szPtr, '\\' );
  596. if(szPtr2)
  597. {
  598. strKey.assign( szPtr, szPtr2 - szPtr );
  599. strValue = &szPtr2[1];
  600. }
  601. else
  602. {
  603. strKey = szPtr;
  604. }
  605. __MPC_EXIT_IF_METHOD_FAILS(hr, rk.SetRoot( hKeyRoot, fRead ? KEY_READ : KEY_ALL_ACCESS ));
  606. __MPC_EXIT_IF_METHOD_FAILS(hr, rk.Attach ( strKey.c_str() ));
  607. hr = S_OK;
  608. __HCP_FUNC_CLEANUP;
  609. __HCP_FUNC_EXIT(hr);
  610. }
  611. STDMETHODIMP CPCHHelpCenterExternal::RegRead( /*[in]*/ BSTR bstrKey, /*[out, retval]*/ VARIANT *pVal )
  612. {
  613. __HCP_FUNC_ENTRY( "CPCHHelpCenterExternal::RegRead" );
  614. HRESULT hr;
  615. MPC::RegKey rk;
  616. MPC::wstring strValue;
  617. bool fFound;
  618. __MPC_PARAMCHECK_BEGIN(hr)
  619. __MPC_PARAMCHECK_NOTNULL(pVal);
  620. __MPC_PARAMCHECK_END();
  621. __MPC_EXIT_IF_METHOD_FAILS(hr, RegInit( bstrKey, /*fRead*/true, rk, strValue ));
  622. __MPC_EXIT_IF_METHOD_FAILS(hr, rk.get_Value( *pVal, fFound, strValue.size() ? strValue.c_str() : NULL ));
  623. if(pVal->vt == (VT_ARRAY | VT_BSTR))
  624. {
  625. // We do the conversion so that JScript code can access the array.
  626. MPC::WStringList lst;
  627. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::ConvertSafeArrayToList( *pVal, lst ));
  628. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::ConvertListToSafeArray( lst, *pVal, VT_VARIANT ));
  629. }
  630. hr = S_OK;
  631. __HCP_FUNC_CLEANUP;
  632. __HCP_FUNC_EXIT(hr);
  633. }
  634. STDMETHODIMP CPCHHelpCenterExternal::RegWrite( /*[in]*/ BSTR bstrKey, /*[in]*/ VARIANT newVal, /*[in,optional]*/ VARIANT vKind )
  635. {
  636. __HCP_FUNC_ENTRY( "CPCHHelpCenterExternal::RegWrite" );
  637. HRESULT hr;
  638. MPC::RegKey rk;
  639. MPC::wstring strValue;
  640. CComVariant v( newVal );
  641. bool fExpand = false;
  642. __MPC_EXIT_IF_METHOD_FAILS(hr, RegInit( bstrKey, /*fRead*/false, rk, strValue ));
  643. if(vKind.vt == VT_BSTR && STRINGISPRESENT(vKind.bstrVal))
  644. {
  645. if(!_wcsicmp( vKind.bstrVal, L"REG_DWORD" ))
  646. {
  647. __MPC_EXIT_IF_METHOD_FAILS(hr, v.ChangeType( VT_I4 ));
  648. }
  649. if(!_wcsicmp( vKind.bstrVal, L"REG_SZ" ))
  650. {
  651. __MPC_EXIT_IF_METHOD_FAILS(hr, v.ChangeType( VT_BSTR ));
  652. }
  653. if(!_wcsicmp( vKind.bstrVal, L"REG_EXPAND_SZ" ))
  654. {
  655. fExpand = true;
  656. __MPC_EXIT_IF_METHOD_FAILS(hr, v.ChangeType( VT_BSTR ));
  657. }
  658. if(!_wcsicmp( vKind.bstrVal, L"REG_MULTI_SZ" ))
  659. {
  660. fExpand = true;
  661. __MPC_EXIT_IF_METHOD_FAILS(hr, v.ChangeType( VT_ARRAY | VT_BSTR ));
  662. }
  663. }
  664. __MPC_EXIT_IF_METHOD_FAILS(hr, rk.Create ( ));
  665. __MPC_EXIT_IF_METHOD_FAILS(hr, rk.put_Value( newVal, strValue.size() ? strValue.c_str() : NULL, fExpand ));
  666. hr = S_OK;
  667. __HCP_FUNC_CLEANUP;
  668. __HCP_FUNC_EXIT(hr);
  669. }
  670. STDMETHODIMP CPCHHelpCenterExternal::RegDelete( /*[in]*/ BSTR bstrKey )
  671. {
  672. __HCP_FUNC_ENTRY( "CPCHHelpCenterExternal::RegDelete" );
  673. HRESULT hr;
  674. MPC::RegKey rk;
  675. MPC::wstring strValue;
  676. __MPC_EXIT_IF_METHOD_FAILS(hr, RegInit( bstrKey, /*fRead*/false, rk, strValue ));
  677. if(strValue.size())
  678. {
  679. __MPC_EXIT_IF_METHOD_FAILS(hr, rk.del_Value( strValue.c_str() ));
  680. }
  681. else
  682. {
  683. __MPC_EXIT_IF_METHOD_FAILS(hr, rk.Delete( /*fDeep*/false ));
  684. }
  685. hr = S_OK;
  686. __HCP_FUNC_CLEANUP;
  687. __HCP_FUNC_EXIT(hr);
  688. }
  689. ////////////////////////////////////////////////////////////////////////////////
  690. STDMETHODIMP CPCHHelpCenterExternal::Close()
  691. {
  692. __HCP_FUNC_ENTRY( "CPCHHelpCenterExternal::Close" );
  693. HRESULT hr;
  694. HWND hwnd;
  695. INTERNETSECURITY__CHECK_TRUST();
  696. //
  697. // In case we are called really early, give the application some time to initialize properly.
  698. //
  699. MPC::SleepWithMessagePump( 100 );
  700. if((hwnd = Window()) != NULL)
  701. {
  702. ::PostMessage( hwnd, WM_CLOSE, 0, 0 );
  703. }
  704. hr = S_OK;
  705. __HCP_FUNC_CLEANUP;
  706. __HCP_FUNC_EXIT(hr);
  707. }
  708. STDMETHODIMP CPCHHelpCenterExternal::RefreshUI()
  709. {
  710. __HCP_FUNC_ENTRY( "CPCHHelpCenterExternal::RefreshUI" );
  711. MSG msg;
  712. //
  713. // There is one or more window message available. Dispatch them
  714. //
  715. while(::PeekMessage( &msg, NULL, NULL, NULL, PM_REMOVE ))
  716. {
  717. ::TranslateMessage( &msg );
  718. ::DispatchMessage ( &msg );
  719. }
  720. __HCP_FUNC_EXIT(S_OK);
  721. }
  722. ////////////////////////////////////////////////////////////////////////////////
  723. STDMETHODIMP CPCHHelpCenterExternal::Print( /*[in]*/ VARIANT window, /*[in]*/ VARIANT_BOOL fEvent, /*[out, retval]*/ VARIANT_BOOL *pVal )
  724. {
  725. __HCP_FUNC_ENTRY( "CPCHHelpCenterExternal::Print" );
  726. HRESULT hr;
  727. VARIANT_BOOL Cancel;
  728. if(m_fHidden)
  729. {
  730. __MPC_EXIT_IF_METHOD_FAILS(hr, E_ACCESSDENIED);
  731. }
  732. if(fEvent == VARIANT_TRUE)
  733. {
  734. if(SUCCEEDED(m_Events.FireEvent_Print( &Cancel )))
  735. {
  736. if(Cancel == VARIANT_TRUE)
  737. {
  738. __MPC_FUNC_LEAVE;
  739. }
  740. }
  741. }
  742. {
  743. CComQIPtr<IWebBrowser2> wb2;
  744. if(window.vt == VT_DISPATCH)
  745. {
  746. wb2 = window.pdispVal;
  747. }
  748. else
  749. {
  750. wb2.Attach( IsHHWindowVisible() ? HHWindow() : Contents() );
  751. }
  752. if(wb2)
  753. {
  754. (void)wb2->ExecWB( OLECMDID_PRINT, OLECMDEXECOPT_DODEFAULT, NULL, NULL );
  755. }
  756. }
  757. hr = S_OK;
  758. __HCP_FUNC_CLEANUP;
  759. __HCP_FUNC_EXIT(hr);
  760. }
  761. ////////////////////////////////////////////////////////////////////////////////
  762. static HRESULT local_HighlighDocument( /*[in]*/ IHTMLDocument2* doc ,
  763. /*[in]*/ MPC::WStringList& lst )
  764. {
  765. __HCP_FUNC_ENTRY( "local_HighlighDocument" );
  766. HRESULT hr;
  767. CComPtr<IHTMLElement> elem;
  768. __MPC_EXIT_IF_METHOD_FAILS(hr, doc->get_body( &elem ));
  769. if(elem)
  770. {
  771. CComPtr<IHTMLBodyElement> bodyElement;
  772. CComBSTR bstrCmd ( L"BackColor" );
  773. CComBSTR bstrCmd2 ( L"ForeColor" );
  774. CComVariant vBackColor( (long)::GetSysColor( COLOR_HIGHLIGHT ) );
  775. CComVariant vForeColor( (long)::GetSysColor( COLOR_HIGHLIGHTTEXT ) );
  776. DWORD dwTimeout;
  777. MPC::WStringIterConst it;
  778. __MPC_EXIT_IF_METHOD_FAILS(hr, elem.QueryInterface( &bodyElement ));
  779. dwTimeout = ::GetTickCount() + 6000;
  780. for(it = lst.begin(); it != lst.end(); it++)
  781. {
  782. CComBSTR bstrSearchTerm( it->c_str() );
  783. CComPtr<IHTMLTxtRange> range;
  784. VARIANT_BOOL vbRet;
  785. __MPC_EXIT_IF_METHOD_FAILS(hr, bodyElement->createTextRange( &range ));
  786. while(1)
  787. {
  788. if(FAILED(range->findText( bstrSearchTerm, 1000000, 2, &vbRet )) || vbRet != VARIANT_TRUE) break;
  789. if(FAILED(range->execCommand( bstrCmd2, VARIANT_FALSE, vForeColor, &vbRet )) || vbRet != VARIANT_TRUE) break;
  790. if(FAILED(range->execCommand( bstrCmd , VARIANT_FALSE, vBackColor, &vbRet )) || vbRet != VARIANT_TRUE) break;
  791. if(::GetTickCount() > dwTimeout) break;
  792. if(FAILED(range->collapse( VARIANT_FALSE ))) break;
  793. }
  794. if(::GetTickCount() > dwTimeout) break;
  795. }
  796. }
  797. hr = S_OK;
  798. __HCP_FUNC_CLEANUP;
  799. __HCP_FUNC_EXIT(hr);
  800. }
  801. STDMETHODIMP CPCHHelpCenterExternal::HighlightWords( /*[in]*/ VARIANT window, /*[in]*/ VARIANT words )
  802. {
  803. __HCP_FUNC_ENTRY( "CPCHHelpCenterExternal::HighlightWords" );
  804. HRESULT hr;
  805. CComPtr<IHTMLDocument2> doc;
  806. if(window.vt == VT_DISPATCH)
  807. {
  808. if(FAILED(MPC::HTML::IDispatch_To_IHTMLDocument2( doc, window.pdispVal )))
  809. {
  810. doc.Release();
  811. }
  812. }
  813. if(!doc)
  814. {
  815. //
  816. // If the caller didn't specify a window, we'll get the currently displayed window.
  817. //
  818. CComPtr<IWebBrowser2> wb2; wb2.Attach( IsHHWindowVisible() ? HHWindow() : Contents() );
  819. if(wb2)
  820. {
  821. CComPtr<IDispatch> docDisp;
  822. __MPC_EXIT_IF_METHOD_FAILS(hr, wb2->get_Document( &docDisp ));
  823. if(docDisp)
  824. {
  825. __MPC_EXIT_IF_METHOD_FAILS(hr, docDisp.QueryInterface( &doc ));
  826. }
  827. }
  828. }
  829. if(doc)
  830. {
  831. MPC::WStringList lst;
  832. CComPtr<IHTMLFramesCollection2> frames;
  833. if(words.vt == (VT_ARRAY | VT_BSTR ) ||
  834. words.vt == (VT_ARRAY | VT_VARIANT) )
  835. {
  836. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::ConvertSafeArrayToList( words, lst ));
  837. }
  838. else if(words.vt == VT_BSTR)
  839. {
  840. lst.push_back( SAFEWSTR( words.bstrVal ) );
  841. }
  842. (void)local_HighlighDocument( doc, lst );
  843. __MPC_EXIT_IF_METHOD_FAILS(hr, doc->get_frames( &frames ));
  844. if(frames)
  845. {
  846. long len;
  847. __MPC_EXIT_IF_METHOD_FAILS(hr, frames->get_length( &len ));
  848. for(int i=0; i<len; i++)
  849. {
  850. CComVariant vIndex = i;
  851. CComVariant vValue;
  852. __MPC_EXIT_IF_METHOD_FAILS(hr, frames->item( &vIndex, &vValue ));
  853. if(vValue.vt == VT_DISPATCH)
  854. {
  855. CComQIPtr<IHTMLWindow2> fb = vValue.pdispVal;
  856. if(fb)
  857. {
  858. CComPtr<IHTMLDocument2> docSub;
  859. __MPC_EXIT_IF_METHOD_FAILS(hr, fb->get_document( &docSub ));
  860. if(docSub)
  861. {
  862. (void)local_HighlighDocument( docSub, lst );
  863. }
  864. }
  865. }
  866. }
  867. }
  868. }
  869. hr = S_OK;
  870. __HCP_FUNC_CLEANUP;
  871. __HCP_FUNC_EXIT(hr);
  872. }
  873. ////////////////////////////////////////////////////////////////////////////////
  874. STDMETHODIMP CPCHHelpCenterExternal::MessageBox( /*[in]*/ BSTR bstrText, /*[in]*/ BSTR bstrKind, /*[out, retval]*/ BSTR *pVal )
  875. {
  876. __HCP_FUNC_ENTRY( "CPCHHelpCenterExternal::MessageBox" );
  877. HRESULT hr;
  878. MPC::wstring szTitle; MPC::LocalizeString( IDS_MAINWND_TITLE, szTitle );
  879. DWORD dwType = 0;
  880. LPCWSTR szRes;
  881. __MPC_PARAMCHECK_BEGIN(hr)
  882. __MPC_PARAMCHECK_POINTER_AND_SET(pVal,NULL);
  883. __MPC_PARAMCHECK_END();
  884. if(m_fHidden)
  885. {
  886. __MPC_EXIT_IF_METHOD_FAILS(hr, E_ACCESSDENIED);
  887. }
  888. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::ConvertStringToBitField( bstrKind, dwType, s_arrMessageBoxMap ));
  889. if(dwType == 0) dwType = MB_OK;
  890. switch( ::MessageBoxW( m_hwnd, SAFEBSTR( bstrText ), szTitle.c_str(), dwType ) )
  891. {
  892. case IDABORT : szRes = L"ABORT" ; break;
  893. case IDCANCEL : szRes = L"CANCEL" ; break;
  894. case IDCONTINUE: szRes = L"CONTINUE"; break;
  895. case IDIGNORE : szRes = L"IGNORE" ; break;
  896. case IDNO : szRes = L"NO" ; break;
  897. case IDOK : szRes = L"OK" ; break;
  898. case IDRETRY : szRes = L"RETRY" ; break;
  899. case IDTRYAGAIN: szRes = L"TRYAGAIN"; break;
  900. case IDYES : szRes = L"YES" ; break;
  901. default : szRes = L"" ; break;
  902. }
  903. hr = MPC::GetBSTR( szRes, pVal );
  904. __HCP_FUNC_CLEANUP;
  905. __HCP_FUNC_EXIT(hr);
  906. }
  907. ////////////////////////////////////////
  908. struct SelectFolder_Data
  909. {
  910. BSTR bstrDefault;
  911. BSTR bstrPrefix;
  912. BSTR bstrSuffix;
  913. };
  914. static int CALLBACK SelectFolder_Callback( HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData )
  915. {
  916. SelectFolder_Data* ptr = (SelectFolder_Data*)lpData;
  917. switch(uMsg)
  918. {
  919. case BFFM_INITIALIZED:
  920. if(ptr->bstrDefault)
  921. {
  922. ::SendMessageW( hwnd, BFFM_SETSELECTIONW, TRUE, (LPARAM)ptr->bstrDefault );
  923. }
  924. break;
  925. case BFFM_SELCHANGED:
  926. {
  927. BOOL fEnabled = TRUE;
  928. if(ptr->bstrPrefix)
  929. {
  930. }
  931. ::SendMessageW( hwnd, BFFM_ENABLEOK, 0, fEnabled );
  932. }
  933. break;
  934. }
  935. return 0;
  936. }
  937. STDMETHODIMP CPCHHelpCenterExternal::SelectFolder( /*[in]*/ BSTR bstrTitle, /*[in]*/ BSTR bstrDefault, /*[out, retval]*/ BSTR *pVal )
  938. {
  939. __HCP_FUNC_ENTRY( "CPCHHelpCenterExternal::SelectFolder" );
  940. HRESULT hr;
  941. LPITEMIDLIST pidl = NULL;
  942. CComPtr<IMalloc> malloc;
  943. SelectFolder_Data data;
  944. BROWSEINFOW bi;
  945. __MPC_PARAMCHECK_BEGIN(hr)
  946. __MPC_PARAMCHECK_POINTER_AND_SET(pVal,NULL);
  947. __MPC_PARAMCHECK_END();
  948. INTERNETSECURITY__CHECK_TRUST();
  949. __MPC_EXIT_IF_METHOD_FAILS(hr, ::SHGetMalloc( &malloc ));
  950. ::ZeroMemory( &bi, sizeof( bi ) );
  951. bi.hwndOwner = m_hwnd;
  952. bi.lpszTitle = bstrTitle;
  953. bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_USENEWUI | BIF_STATUSTEXT | BIF_VALIDATE;
  954. bi.lpfn = SelectFolder_Callback;
  955. bi.lParam = (LPARAM)&data;
  956. data.bstrDefault = bstrDefault;
  957. data.bstrPrefix = NULL;
  958. data.bstrSuffix = NULL;
  959. pidl = ::SHBrowseForFolderW( &bi );
  960. if(pidl)
  961. {
  962. WCHAR rgPath[MAX_PATH];
  963. if(::SHGetPathFromIDListW( pidl, rgPath ))
  964. {
  965. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::GetBSTR( rgPath, pVal ));
  966. }
  967. }
  968. hr = S_OK;
  969. __HCP_FUNC_CLEANUP;
  970. if(malloc && pidl) malloc->Free( pidl );
  971. __HCP_FUNC_EXIT(hr);
  972. }
  973. ////////////////////////////////////////////////////////////////////////////////
  974. CPCHHelper_IDocHostUIHandler::CPCHHelper_IDocHostUIHandler()
  975. {
  976. m_parent = NULL; CPCHHelpCenterExternal* m_parent;
  977. }
  978. void CPCHHelper_IDocHostUIHandler::Initialize( /*[in]*/ CPCHHelpCenterExternal* parent )
  979. {
  980. m_parent = parent;
  981. }
  982. STDMETHODIMP CPCHHelper_IDocHostUIHandler::QueryService( REFGUID guidService, REFIID riid, void **ppv )
  983. {
  984. HRESULT hr = E_NOINTERFACE;
  985. if(InlineIsEqualGUID( riid, IID_IDocHostUIHandler ))
  986. {
  987. hr = QueryInterface( riid, ppv );
  988. }
  989. return hr;
  990. }
  991. STDMETHODIMP CPCHHelper_IDocHostUIHandler::ShowContextMenu( DWORD dwID, POINT* pptPosition, IUnknown* pCommandTarget, IDispatch* pDispatchObjectHit )
  992. {
  993. if(g_Debug_CONTEXTMENU)
  994. {
  995. if(::GetKeyState( VK_CONTROL ) & 0x8000) return E_NOTIMPL;
  996. }
  997. if(g_Debug_BUILDTREE)
  998. {
  999. if(::GetKeyState( VK_MENU ) & 0x8000)
  1000. {
  1001. CComVariant vArg( pDispatchObjectHit );
  1002. (void)m_parent->CallFunctionOnPanel( HSCPANEL_NAVBAR, NULL, s_bstrFunc_BuildTree, &vArg, 1 );
  1003. }
  1004. }
  1005. //
  1006. // Last chance for the scripts to say something...
  1007. //
  1008. {
  1009. CComVariant vArgs[4];
  1010. CComVariant vRes;
  1011. DWORD dwCmd = -1;
  1012. vArgs[3] = (long)dwID;
  1013. vArgs[2] = pDispatchObjectHit;
  1014. vArgs[1] = (long)pptPosition->x;
  1015. vArgs[0] = (long)pptPosition->y;
  1016. (void)m_parent->CallFunctionOnPanel( HSCPANEL_NAVBAR, NULL, s_bstrFunc_GlobalContextMenu, vArgs, ARRAYSIZE(vArgs), &vRes );
  1017. if(vRes.vt == VT_BSTR && vRes.bstrVal)
  1018. {
  1019. if(!_wcsicmp( vRes.bstrVal, L"DELEGATE" )) return E_NOTIMPL;
  1020. if(!_wcsicmp( vRes.bstrVal, L"SELECTALL" )) dwCmd = OLECMDID_SELECTALL;
  1021. if(!_wcsicmp( vRes.bstrVal, L"REFRESH" )) dwCmd = OLECMDID_REFRESH;
  1022. if(!_wcsicmp( vRes.bstrVal, L"PROPERTIES" )) dwCmd = OLECMDID_PROPERTIES;
  1023. }
  1024. if(dwCmd != -1)
  1025. {
  1026. CComVariant vaIn;
  1027. CComVariant vaOut;
  1028. switch(dwCmd)
  1029. {
  1030. case OLECMDID_PROPERTIES: // Trident folks say the In value must be set to the mouse pos
  1031. vaIn = MAKELONG(pptPosition->x,pptPosition->y);
  1032. break;
  1033. }
  1034. ((IOleCommandTarget*)pCommandTarget)->Exec( NULL, dwCmd, OLECMDEXECOPT_DODEFAULT, &vaIn, &vaOut );
  1035. }
  1036. }
  1037. return S_OK;
  1038. }
  1039. STDMETHODIMP CPCHHelper_IDocHostUIHandler::GetHostInfo(DOCHOSTUIINFO* pInfo)
  1040. {
  1041. pInfo->dwFlags = DOCHOSTUIFLAG_NO3DBORDER |
  1042. DOCHOSTUIFLAG_ENABLE_FORMS_AUTOCOMPLETE |
  1043. DOCHOSTUIFLAG_THEME;
  1044. pInfo->dwDoubleClick = DOCHOSTUIDBLCLK_DEFAULT;
  1045. return S_OK;
  1046. }
  1047. STDMETHODIMP CPCHHelper_IDocHostUIHandler::ShowUI(DWORD dwID, IOleInPlaceActiveObject* pActiveObject, IOleCommandTarget* pCommandTarget, IOleInPlaceFrame* pFrame, IOleInPlaceUIWindow* pDoc)
  1048. {
  1049. return E_NOTIMPL;
  1050. }
  1051. STDMETHODIMP CPCHHelper_IDocHostUIHandler::HideUI()
  1052. {
  1053. return E_NOTIMPL;
  1054. }
  1055. STDMETHODIMP CPCHHelper_IDocHostUIHandler::UpdateUI()
  1056. {
  1057. return E_NOTIMPL;
  1058. }
  1059. STDMETHODIMP CPCHHelper_IDocHostUIHandler::EnableModeless(BOOL fEnable)
  1060. {
  1061. return E_NOTIMPL;
  1062. }
  1063. STDMETHODIMP CPCHHelper_IDocHostUIHandler::OnDocWindowActivate(BOOL fActivate)
  1064. {
  1065. return E_NOTIMPL;
  1066. }
  1067. STDMETHODIMP CPCHHelper_IDocHostUIHandler::OnFrameWindowActivate(BOOL fActivate)
  1068. {
  1069. return E_NOTIMPL;
  1070. }
  1071. STDMETHODIMP CPCHHelper_IDocHostUIHandler::ResizeBorder(LPCRECT prcBorder, IOleInPlaceUIWindow* pUIWindow, BOOL fFrameWindow)
  1072. {
  1073. return E_NOTIMPL;
  1074. }
  1075. STDMETHODIMP CPCHHelper_IDocHostUIHandler::TranslateAccelerator(LPMSG lpMsg, const GUID* pguidCmdGroup, DWORD nCmdID)
  1076. {
  1077. bool fCancel = false;
  1078. bool fBack = false;
  1079. bool fForward = false;
  1080. bool fPossibleBack = false;
  1081. switch(nCmdID)
  1082. {
  1083. // case IDM_CONTEXTMENU:
  1084. case IDM_GOBACKWARD :
  1085. fCancel = true;
  1086. fBack = true;
  1087. break;
  1088. case IDM_GOFORWARD:
  1089. fCancel = true;
  1090. fForward = true;
  1091. break;
  1092. }
  1093. if(lpMsg->message == WM_KEYDOWN ||
  1094. lpMsg->message == WM_KEYUP )
  1095. {
  1096. switch(lpMsg->wParam)
  1097. {
  1098. case 'N': // CTRL-N (new window) disabled.
  1099. if(::GetKeyState( VK_CONTROL ) & 0x8000)
  1100. {
  1101. if (!( HIWORD(lpMsg->lParam) & KF_ALTDOWN ))
  1102. {
  1103. fCancel = true;
  1104. }
  1105. }
  1106. break;
  1107. case VK_F5: // We want to disable F5 as a refresh tool.
  1108. fCancel = true;
  1109. break;
  1110. case VK_BACK: // Enable "backspace" directly.
  1111. fPossibleBack = true;
  1112. break;
  1113. }
  1114. }
  1115. // (weizhao) Changed to go back or forward only on WM_SYSKEYDOWN,
  1116. // otherwise would have gone twice on a single key stroke (down & up).
  1117. //
  1118. // if(lpMsg->message == WM_SYSKEYDOWN ||
  1119. // lpMsg->message == WM_SYSKEYUP )
  1120. if(lpMsg->message == WM_SYSKEYDOWN)
  1121. {
  1122. switch(lpMsg->wParam)
  1123. {
  1124. case VK_LEFT:
  1125. fCancel = true;
  1126. fBack = true;
  1127. break;
  1128. case VK_RIGHT:
  1129. fCancel = true;
  1130. fForward = true;
  1131. break;
  1132. }
  1133. }
  1134. ////////////////////
  1135. if(fPossibleBack || fBack || fForward)
  1136. {
  1137. if(m_parent)
  1138. {
  1139. CPCHHelpSession* hs = m_parent->HelpSession();
  1140. if(hs)
  1141. {
  1142. if(fPossibleBack)
  1143. {
  1144. hs->PossibleBack();
  1145. }
  1146. if(fBack)
  1147. {
  1148. if(hs->IsTravelling() == false) (void)hs->Back( 1 );
  1149. }
  1150. if(fForward)
  1151. {
  1152. if(hs->IsTravelling() == false) (void)hs->Forward( 1 );
  1153. }
  1154. }
  1155. }
  1156. }
  1157. if(fCancel == false)
  1158. {
  1159. fCancel = SUCCEEDED(m_parent->ProcessMessage( lpMsg ));
  1160. }
  1161. return fCancel ? S_OK : E_NOTIMPL;
  1162. }
  1163. STDMETHODIMP CPCHHelper_IDocHostUIHandler::GetOptionKeyPath(BSTR* pbstrKey, DWORD dwReserved)
  1164. {
  1165. if(pbstrKey)
  1166. {
  1167. static const WCHAR c_options[] = HC_REGISTRY_HELPCTR_IE;
  1168. BSTR szBuf = (BSTR)::CoTaskMemAlloc( sizeof(c_options) );
  1169. if(szBuf)
  1170. {
  1171. wcscpy( *pbstrKey = szBuf, c_options );
  1172. }
  1173. }
  1174. return S_OK;
  1175. }
  1176. STDMETHODIMP CPCHHelper_IDocHostUIHandler::GetDropTarget(IDropTarget* pDropTarget, IDropTarget** ppDropTarget)
  1177. {
  1178. return E_NOTIMPL;
  1179. }
  1180. STDMETHODIMP CPCHHelper_IDocHostUIHandler::GetExternal(IDispatch** ppDispatch)
  1181. {
  1182. return E_NOTIMPL;
  1183. }
  1184. STDMETHODIMP CPCHHelper_IDocHostUIHandler::TranslateUrl(DWORD dwTranslate, OLECHAR* pchURLIn, OLECHAR** ppchURLOut)
  1185. {
  1186. return E_NOTIMPL;
  1187. }
  1188. STDMETHODIMP CPCHHelper_IDocHostUIHandler::FilterDataObject(IDataObject* pDO, IDataObject** ppDORet)
  1189. {
  1190. return E_NOTIMPL;
  1191. }
  1192. ////////////////////////////////////////////////////////////////////////////////
  1193. ////////////////////////////////////////////////////////////////////////////////
  1194. ////////////////////////////////////////////////////////////////////////////////
  1195. CPCHContextMenu::CPCHContextMenu()
  1196. {
  1197. m_parent = NULL; // CPCHHelpCenterExternal* m_parent;
  1198. // List m_lstItems;
  1199. m_iLastItem = 1; // int m_iLastItem;
  1200. }
  1201. CPCHContextMenu::~CPCHContextMenu()
  1202. {
  1203. }
  1204. void CPCHContextMenu::Initialize( /*[in]*/ CPCHHelpCenterExternal* parent )
  1205. {
  1206. m_parent = parent;
  1207. }
  1208. ////////////////////////////////////////////////////////////////////////////////
  1209. STDMETHODIMP CPCHContextMenu::AddItem( /*[in]*/ BSTR bstrText ,
  1210. /*[in]*/ BSTR bstrID ,
  1211. /*[in, optional]*/ VARIANT vFlags )
  1212. {
  1213. __HCP_FUNC_ENTRY( "CPCHContextMenu::AddItem" );
  1214. HRESULT hr;
  1215. __MPC_PARAMCHECK_BEGIN(hr)
  1216. __MPC_PARAMCHECK_STRING_NOT_EMPTY(bstrText);
  1217. __MPC_PARAMCHECK_STRING_NOT_EMPTY(bstrID);
  1218. __MPC_PARAMCHECK_END();
  1219. {
  1220. const UINT sAllowedFlags = MF_GRAYED |
  1221. MF_CHECKED;
  1222. Entry& ent = *(m_lstItems.insert( m_lstItems.end() ));
  1223. ent.bstrText = bstrText;
  1224. ent.bstrID = bstrID;
  1225. ent.iID = m_iLastItem++;
  1226. ent.uFlags = (vFlags.vt == VT_I4 ? vFlags.lVal : 0) & sAllowedFlags;
  1227. }
  1228. hr = S_OK;
  1229. __HCP_FUNC_CLEANUP;
  1230. __HCP_FUNC_EXIT(hr);
  1231. }
  1232. STDMETHODIMP CPCHContextMenu::AddSeparator()
  1233. {
  1234. __HCP_FUNC_ENTRY( "CPCHContextMenu::AddSeparator" );
  1235. HRESULT hr;
  1236. {
  1237. Entry& ent = *(m_lstItems.insert( m_lstItems.end() ));
  1238. ent.iID = -1;
  1239. }
  1240. hr = S_OK;
  1241. __HCP_FUNC_EXIT(hr);
  1242. }
  1243. STDMETHODIMP CPCHContextMenu::Display( /*[out,retval]*/ BSTR *pVal )
  1244. {
  1245. __HCP_FUNC_ENTRY( "CPCHContextMenu::Display" );
  1246. HRESULT hr;
  1247. HMENU hMenu = NULL;
  1248. Iter it;
  1249. int iSelected;
  1250. POINT pt;
  1251. __MPC_PARAMCHECK_BEGIN(hr)
  1252. __MPC_PARAMCHECK_POINTER_AND_SET(pVal,NULL);
  1253. __MPC_PARAMCHECK_END();
  1254. __MPC_EXIT_IF_CALL_RETURNS_NULL(hr, (hMenu = ::CreatePopupMenu()));
  1255. //
  1256. // Populate menu.
  1257. //
  1258. for(it = m_lstItems.begin(); it != m_lstItems.end(); it++)
  1259. {
  1260. Entry& ent = *it;
  1261. if(ent.iID < 0)
  1262. {
  1263. __MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::AppendMenuW( hMenu, MF_SEPARATOR, 0, 0 ));
  1264. }
  1265. else
  1266. {
  1267. __MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::AppendMenuW( hMenu, MF_STRING | ent.uFlags, ent.iID, ent.bstrText ));
  1268. }
  1269. }
  1270. ::GetCursorPos( &pt );
  1271. //
  1272. // Find the active panel and its active element. If the cursor is inside its bounding rectangle, display the CM under the cursor.
  1273. // Otherwise display the CM at the upper-left corner of the element.
  1274. //
  1275. {
  1276. IMarsWindowOM* shell = m_parent->Shell();
  1277. CComPtr<IMarsPanelCollection> coll;
  1278. if(shell && SUCCEEDED(shell->get_panels( &coll )) && coll)
  1279. {
  1280. CComPtr<IMarsPanel> panel;
  1281. if(SUCCEEDED(coll->get_activePanel( &panel )) && panel)
  1282. {
  1283. CComPtr<IDispatch> disp;
  1284. if(panel == m_parent->Panel( HSCPANEL_HHWINDOW ))
  1285. {
  1286. CComPtr<IWebBrowser2> wb2; wb2.Attach( m_parent->HHWindow() );
  1287. disp = wb2;
  1288. }
  1289. else
  1290. {
  1291. (void)panel->get_content( &disp );
  1292. }
  1293. if(disp)
  1294. {
  1295. CComQIPtr<IWebBrowser2> wb2 = disp;
  1296. CComQIPtr<IHTMLDocument2> doc2;
  1297. if(wb2)
  1298. {
  1299. disp.Release();
  1300. wb2->get_Document( &disp );
  1301. }
  1302. doc2 = disp;
  1303. //
  1304. // Look for the inner-most active element.
  1305. //
  1306. {
  1307. CComPtr<IHTMLElement> elem;
  1308. while(doc2 && SUCCEEDED(doc2->get_activeElement( &elem )) && elem)
  1309. {
  1310. //
  1311. // This could be a frame.
  1312. //
  1313. CComPtr<IHTMLFrameBase2> frame;
  1314. if(SUCCEEDED(elem.QueryInterface( &frame )))
  1315. {
  1316. CComPtr<IHTMLWindow2> winsub;
  1317. if(SUCCEEDED(frame->get_contentWindow( &winsub )) && winsub)
  1318. {
  1319. doc2.Release();
  1320. elem.Release();
  1321. (void)winsub->get_document( &doc2 );
  1322. continue;
  1323. }
  1324. }
  1325. break;
  1326. }
  1327. {
  1328. CComQIPtr<IServiceProvider> sp = elem;
  1329. if(sp)
  1330. {
  1331. CComPtr<IAccessible> acc;
  1332. if(SUCCEEDED(sp->QueryService( IID_IAccessible, IID_IAccessible, (void**)&acc )))
  1333. {
  1334. long xLeft;
  1335. long yTop;
  1336. long cxWidth;
  1337. long cyHeight;
  1338. VARIANT v;
  1339. v.vt = VT_I4;
  1340. v.lVal = CHILDID_SELF;
  1341. if(SUCCEEDED(acc->accLocation( &xLeft, &yTop, &cxWidth, &cyHeight, v )))
  1342. {
  1343. if(pt.x < xLeft || pt.x > xLeft + cxWidth ||
  1344. pt.y < yTop || pt.y > yTop + cyHeight )
  1345. {
  1346. DWORD dwDefaultLayout;
  1347. if(::GetProcessDefaultLayout( &dwDefaultLayout ) && (dwDefaultLayout & LAYOUT_RTL))
  1348. {
  1349. pt.x = xLeft + cxWidth;
  1350. pt.y = yTop;
  1351. }
  1352. else
  1353. {
  1354. pt.x = xLeft;
  1355. pt.y = yTop;
  1356. }
  1357. }
  1358. }
  1359. }
  1360. }
  1361. }
  1362. }
  1363. }
  1364. }
  1365. }
  1366. }
  1367. iSelected = ::TrackPopupMenu( hMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD | TPM_NONOTIFY, pt.x, pt.y, 0, m_parent->Window(), NULL );
  1368. if(iSelected != 0)
  1369. {
  1370. for(it = m_lstItems.begin(); it != m_lstItems.end(); it++)
  1371. {
  1372. Entry& ent = *it;
  1373. if(ent.iID == iSelected)
  1374. {
  1375. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::GetBSTR( ent.bstrID, pVal ));
  1376. }
  1377. }
  1378. }
  1379. hr = S_OK;
  1380. __HCP_FUNC_CLEANUP;
  1381. if(hMenu) ::DestroyMenu( hMenu );
  1382. __HCP_FUNC_EXIT(hr);
  1383. }