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

/******************************************************************************
Copyright (c) 1999 Microsoft Corporation
Module Name:
HelpCenterExternal.cpp
Abstract:
This file contains the implementation of the class exposed as the "pchealth" object.
Revision History:
Ghim-Sim Chua (gschua) 07/23/99
created
Davide Massarenti (dmassare) 07/25/99
modified
Kalyani Narlanka (KalyaniN) 03/15/01
Moved Incident and Encryption Objects from HelpService to HelpCtr to improve Perf.
******************************************************************************/
#include "stdafx.h"
#include "rdshost_i.c"
#include "safrdm_i.c"
#include "rassistance.h"
#include "rassistance_i.c"
#include "rcbdyctl.h"
#include "rcbdyctl_i.c"
#include <time.h>
#include <mshtmcid.h>
#include <userenv.h>
/////////////////////////////////////////////////////////////////////////////
static const MPC::StringToBitField s_arrMessageBoxMap[] =
{
{ L"OK" , MB_TYPEMASK, MB_OK , -1 },
{ L"OKCANCEL" , MB_TYPEMASK, MB_OKCANCEL , -1 },
{ L"ABORTRETRYIGNORE" , MB_TYPEMASK, MB_ABORTRETRYIGNORE , -1 },
{ L"YESNOCANCEL" , MB_TYPEMASK, MB_YESNOCANCEL , -1 },
{ L"YESNO" , MB_TYPEMASK, MB_YESNO , -1 },
{ L"RETRYCANCEL" , MB_TYPEMASK, MB_RETRYCANCEL , -1 },
{ L"CANCELTRYCONTINUE", MB_TYPEMASK, MB_CANCELTRYCONTINUE, -1 },
{ L"ICONHAND" , MB_ICONMASK, MB_ICONHAND , -1 },
{ L"ICONQUESTION" , MB_ICONMASK, MB_ICONQUESTION , -1 },
{ L"ICONEXCLAMATION" , MB_ICONMASK, MB_ICONEXCLAMATION , -1 },
{ L"ICONASTERISK" , MB_ICONMASK, MB_ICONASTERISK , -1 },
{ L"USERICON" , MB_ICONMASK, MB_USERICON , -1 },
{ L"ICONWARNING" , MB_ICONMASK, MB_ICONWARNING , -1 },
{ L"ICONERROR" , MB_ICONMASK, MB_ICONERROR , -1 },
{ L"ICONINFORMATION" , MB_ICONMASK, MB_ICONINFORMATION , -1 },
{ L"ICONSTOP" , MB_ICONMASK, MB_ICONSTOP , -1 },
{ L"DEFBUTTON1" , MB_MODEMASK, MB_DEFBUTTON1 , -1 },
{ L"DEFBUTTON2" , MB_MODEMASK, MB_DEFBUTTON2 , -1 },
{ L"DEFBUTTON3" , MB_MODEMASK, MB_DEFBUTTON3 , -1 },
{ L"DEFBUTTON4" , MB_MODEMASK, MB_DEFBUTTON4 , -1 },
{ L"APPLMODAL" , MB_MODEMASK, MB_APPLMODAL , -1 },
{ L"SYSTEMMODAL" , MB_MODEMASK, MB_SYSTEMMODAL , -1 },
{ L"TASKMODAL" , MB_MODEMASK, MB_TASKMODAL , -1 },
{ L"HELP" , MB_MODEMASK, MB_HELP , -1 },
{ NULL }
};
static const CComBSTR s_bstrFunc_GlobalContextMenu( L"GlobalContextMenu" );
static const CComBSTR s_bstrFunc_BuildTree ( L"debug_BuildTree" );
/////////////////////////////////////////////////////////////////////////////
CPCHSecurityHandle::CPCHSecurityHandle()
{
m_ext = NULL; // CPCHHelpCenterExternal* m_ext;
m_object = NULL; // IDispatch* m_object;
}
void CPCHSecurityHandle::Initialize( /*[in]*/ CPCHHelpCenterExternal* ext, /*[in] */ IDispatch* object )
{
m_ext = ext;
m_object = object;
}
void CPCHSecurityHandle::Passivate()
{
m_ext = NULL;
m_object = NULL;
}
HRESULT CPCHSecurityHandle::ForwardInvokeEx( /*[in] */ DISPID id ,
/*[in] */ LCID lcid ,
/*[in] */ WORD wFlags ,
/*[in] */ DISPPARAMS* pdp ,
/*[out]*/ VARIANT* pvarRes ,
/*[out]*/ EXCEPINFO* pei ,
/*[in] */ IServiceProvider* pspCaller )
{
return m_ext ? m_ext->SetTLSAndInvoke( m_object, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller ) : E_ACCESSDENIED;
}
HRESULT CPCHSecurityHandle::IsTrusted()
{
return m_ext ? m_ext->IsTrusted() : E_ACCESSDENIED;
}
HRESULT CPCHSecurityHandle::IsSystem()
{
return m_ext ? m_ext->IsSystem() : E_ACCESSDENIED;
}
/////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CPCHHelpCenterExternal::get_HelpSession( /*[out, retval]*/ IPCHHelpSession* *pVal )
{
__HCP_BEGIN_PROPERTY_GET("CPCHHelpCenterExternal::get_HelpSession",hr,pVal);
INTERNETSECURITY__CHECK_TRUST();
if(HelpSession())
{
__MPC_EXIT_IF_METHOD_FAILS(hr, HelpSession()->QueryInterface( IID_IPCHHelpSession, (void**)pVal ));
}
__HCP_END_PROPERTY(hr);
}
STDMETHODIMP CPCHHelpCenterExternal::get_Channels( /*[out, retval]*/ ISAFReg* *pVal )
{
__HCP_BEGIN_PROPERTY_GET("CPCHHelpCenterExternal::get_Channels",hr,pVal);
if(!m_Utility) __MPC_SET_ERROR_AND_EXIT(hr, E_ACCESSDENIED);
INTERNETSECURITY__CHECK_TRUST();
__MPC_EXIT_IF_METHOD_FAILS(hr, m_Utility->get_Channels( pVal ));
__HCP_END_PROPERTY(hr);
}
STDMETHODIMP CPCHHelpCenterExternal::get_UserSettings( /*[out, retval]*/ IPCHUserSettings2* *pVal )
{
__HCP_BEGIN_PROPERTY_GET("CPCHHelpCenterExternal::get_UserSettings",hr,pVal);
if(!m_UserSettings) __MPC_SET_ERROR_AND_EXIT(hr, E_ACCESSDENIED);
//
// We don't check trust at this stage, it's the object's responsibility to protect each one of its methods.
// This is because "pchealth.UserSettings" exposes read-only properties that could be accessed from untrusted pages.
//
__MPC_EXIT_IF_METHOD_FAILS(hr, m_UserSettings->QueryInterface( IID_IPCHUserSettings2, (void**)pVal ));
__HCP_END_PROPERTY(hr);
}
STDMETHODIMP CPCHHelpCenterExternal::get_Security( /*[out, retval]*/ IPCHSecurity* *pVal )
{
__HCP_BEGIN_PROPERTY_GET("CPCHHelpCenterExternal::get_Security",hr,pVal);
if(!m_Utility) __MPC_SET_ERROR_AND_EXIT(hr, E_ACCESSDENIED);
INTERNETSECURITY__CHECK_TRUST();
__MPC_EXIT_IF_METHOD_FAILS(hr, m_Utility->get_Security( pVal ));
__HCP_END_PROPERTY(hr);
}
STDMETHODIMP CPCHHelpCenterExternal::get_Connectivity( /*[out, retval]*/ IPCHConnectivity* *pVal )
{
__HCP_BEGIN_PROPERTY_GET("CPCHHelpCenterExternal::get_Connectivity",hr,pVal);
CComPtr<CPCHConnectivity> pC;
INTERNETSECURITY__CHECK_TRUST();
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &pC ));
__MPC_EXIT_IF_METHOD_FAILS(hr, pC->ConnectToParent( this ));
__MPC_EXIT_IF_METHOD_FAILS(hr, pC.QueryInterface( pVal ));
__HCP_END_PROPERTY(hr);
}
STDMETHODIMP CPCHHelpCenterExternal::get_Database( /*[out, retval]*/ IPCHTaxonomyDatabase* *pVal )
{
__HCP_BEGIN_PROPERTY_GET("CPCHHelpCenterExternal::get_Database",hr,pVal);
INTERNETSECURITY__CHECK_TRUST();
if(!m_Utility) __MPC_SET_ERROR_AND_EXIT(hr, E_ACCESSDENIED);
__MPC_EXIT_IF_METHOD_FAILS(hr, m_Utility->get_Database( pVal ));
__HCP_END_PROPERTY(hr);
}
STDMETHODIMP CPCHHelpCenterExternal::get_TextHelpers( /*[out, retval]*/ IPCHTextHelpers* *pVal )
{
__HCP_BEGIN_PROPERTY_GET("CPCHHelpCenterExternal::get_TextHelpers",hr,pVal);
if(!m_TextHelpers)
{
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &m_TextHelpers ));
}
__MPC_EXIT_IF_METHOD_FAILS(hr, m_TextHelpers.QueryInterface( pVal ));
__HCP_END_PROPERTY(hr);
}
/////////////////////////////////////////////////////////////////////////////
HRESULT CPCHHelpCenterExternal::get_UI_Panel( /*[out, retval]*/ IUnknown* *pVal, /*[in]*/ HscPanel id )
{
__HCP_BEGIN_PROPERTY_GET("CPCHHelpCenterExternal::get_UI_Panel",hr,pVal);
INTERNETSECURITY__CHECK_SYSTEM();
__MPC_EXIT_IF_METHOD_FAILS(hr, GetPanel( id, (IMarsPanel**)pVal, true ));
__HCP_END_PROPERTY(hr);
}
HRESULT CPCHHelpCenterExternal::get_WEB_Panel( /*[out, retval]*/ IUnknown* *pVal, /*[in]*/ HscPanel id )
{
__HCP_BEGIN_PROPERTY_GET("CPCHHelpCenterExternal::get_WEB_Panel",hr,pVal);
CComPtr<IMarsPanel> panel;
CComPtr<IWebBrowser2> wb;
INTERNETSECURITY__CHECK_SYSTEM();
__MPC_EXIT_IF_METHOD_FAILS(hr, GetPanel( id, &panel, true ));
switch(id)
{
case HSCPANEL_CONTEXT : wb = m_panel_CONTEXT_WebBrowser ; break;
case HSCPANEL_CONTENTS: wb = m_panel_CONTENTS_WebBrowser; break;
case HSCPANEL_HHWINDOW: wb = m_panel_HHWINDOW_WebBrowser; break;
}
*pVal = wb.Detach();
__HCP_END_PROPERTY(hr);
}
STDMETHODIMP CPCHHelpCenterExternal::get_UI_NavBar ( /*[out, retval]*/ IUnknown* *pVal ) { return get_UI_Panel( pVal, HSCPANEL_NAVBAR ); }
STDMETHODIMP CPCHHelpCenterExternal::get_UI_MiniNavBar( /*[out, retval]*/ IUnknown* *pVal ) { return get_UI_Panel( pVal, HSCPANEL_MININAVBAR ); }
STDMETHODIMP CPCHHelpCenterExternal::get_UI_Context ( /*[out, retval]*/ IUnknown* *pVal ) { return get_UI_Panel( pVal, HSCPANEL_CONTEXT ); }
STDMETHODIMP CPCHHelpCenterExternal::get_UI_Contents ( /*[out, retval]*/ IUnknown* *pVal ) { return get_UI_Panel( pVal, HSCPANEL_CONTENTS ); }
STDMETHODIMP CPCHHelpCenterExternal::get_UI_HHWindow ( /*[out, retval]*/ IUnknown* *pVal ) { return get_UI_Panel( pVal, HSCPANEL_HHWINDOW ); }
STDMETHODIMP CPCHHelpCenterExternal::get_WEB_Context ( /*[out, retval]*/ IUnknown* *pVal ) { return get_WEB_Panel( pVal, HSCPANEL_CONTEXT ); }
STDMETHODIMP CPCHHelpCenterExternal::get_WEB_Contents( /*[out, retval]*/ IUnknown* *pVal ) { return get_WEB_Panel( pVal, HSCPANEL_CONTENTS ); }
STDMETHODIMP CPCHHelpCenterExternal::get_WEB_HHWindow( /*[out, retval]*/ IUnknown* *pVal ) { return get_WEB_Panel( pVal, HSCPANEL_HHWINDOW ); }
STDMETHODIMP CPCHHelpCenterExternal::get_ExtraArgument( /*[out, retval]*/ BSTR *pVal )
{
__HCP_BEGIN_PROPERTY_GET("CPCHHelpCenterExternal::get_ExtraArgument",hr,pVal);
INTERNETSECURITY__CHECK_TRUST();
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::GetBSTR( m_bstrExtraArgument, pVal ));
__HCP_END_PROPERTY(hr);
}
STDMETHODIMP CPCHHelpCenterExternal::get_HelpViewer( /*[out, retval]*/ IUnknown* *pVal )
{
__HCP_BEGIN_PROPERTY_GET("CPCHHelpCenterExternal::get_HelpViewer",hr,pVal);
INTERNETSECURITY__CHECK_TRUST();
MPC::CopyTo( (IPCHHelpViewerWrapper*)m_panel_HHWINDOW_Wrapper, pVal );
__HCP_END_PROPERTY(hr);
}
STDMETHODIMP CPCHHelpCenterExternal::RegisterEvents( /*[in]*/ BSTR id ,
/*[in]*/ long pri ,
/*[in]*/ IDispatch* function ,
/*[out,retval]*/ long *cookie )
{
__HCP_FUNC_ENTRY( "CPCHHelpCenterExternal::RegisterEvents" );
HRESULT hr;
__MPC_PARAMCHECK_BEGIN(hr)
__MPC_PARAMCHECK_STRING_NOT_EMPTY(id);
__MPC_PARAMCHECK_POINTER_AND_SET(cookie,0);
__MPC_PARAMCHECK_END();
INTERNETSECURITY__CHECK_TRUST();
hr = m_Events.RegisterEvents( id, pri, function, cookie );
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
STDMETHODIMP CPCHHelpCenterExternal::UnregisterEvents( /*[in]*/ long cookie )
{
__HCP_FUNC_ENTRY( "CPCHHelpCenterExternal::UnregisterEvents" );
HRESULT hr;
INTERNETSECURITY__CHECK_TRUST();
hr = m_Events.UnregisterEvents( cookie );
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
/////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CPCHHelpCenterExternal::CreateObject_SearchEngineMgr( /*[out, retval]*/ IPCHSEManager* *ppSE )
{
__HCP_BEGIN_PROPERTY_GET("CPCHHelpCenterExternal::CreateObject_SearchEngineMgr",hr,ppSE);
INTERNETSECURITY__CHECK_TRUST();
if(!m_Utility) __MPC_SET_ERROR_AND_EXIT(hr, E_ACCESSDENIED);
__MPC_EXIT_IF_METHOD_FAILS(hr, m_Utility->CreateObject_SearchEngineMgr( ppSE ));
__HCP_END_PROPERTY(hr);
}
STDMETHODIMP CPCHHelpCenterExternal::CreateObject_DataCollection( /*[out, retval]*/ ISAFDataCollection* *ppDC )
{
__HCP_BEGIN_PROPERTY_GET("CPCHHelpCenterExternal::CreateObject_DataCollection",hr,ppDC);
INTERNETSECURITY__CHECK_TRUST();
if(!m_Utility) __MPC_SET_ERROR_AND_EXIT(hr, E_ACCESSDENIED);
__MPC_EXIT_IF_METHOD_FAILS(hr, m_Utility->CreateObject_DataCollection( ppDC ));
__HCP_END_PROPERTY(hr);
}
STDMETHODIMP CPCHHelpCenterExternal::CreateObject_Cabinet( /*[out , retval]*/ ISAFCabinet* *ppCB )
{
__HCP_BEGIN_PROPERTY_GET("CPCHHelpCenterExternal::CreateObject_Cabinet",hr,ppCB);
INTERNETSECURITY__CHECK_TRUST();
if(!m_Utility) __MPC_SET_ERROR_AND_EXIT(hr, E_ACCESSDENIED);
__MPC_EXIT_IF_METHOD_FAILS(hr, m_Utility->CreateObject_Cabinet( ppCB ));
__HCP_END_PROPERTY(hr);
}
STDMETHODIMP CPCHHelpCenterExternal::CreateObject_Encryption( /*[out, retval]*/ ISAFEncrypt* *ppEn )
{
__HCP_BEGIN_PROPERTY_GET("CPCHHelpCenterExternal::CreateObject_Encryption",hr,ppEn);
bool fTemporaryProfile = false;
DWORD dwProfileFlags;
INTERNETSECURITY__CHECK_TRUST();
if(::GetProfileType( &dwProfileFlags ))
{
if(( dwProfileFlags & PT_MANDATORY ) ||
((dwProfileFlags & PT_TEMPORARY) && !(dwProfileFlags & PT_ROAMING)) )
{
fTemporaryProfile = true;
}
}
if(fTemporaryProfile)
{
if(!m_Utility) __MPC_SET_ERROR_AND_EXIT(hr, E_ACCESSDENIED);
__MPC_EXIT_IF_METHOD_FAILS(hr, m_Utility->CreateObject_Encryption( ppEn ));
}
else
{
CComPtr<CSAFEncrypt> pEn;
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &pEn ));
__MPC_EXIT_IF_METHOD_FAILS(hr, pEn.QueryInterface( ppEn ));
}
__HCP_END_PROPERTY(hr);
}
STDMETHODIMP CPCHHelpCenterExternal::CreateObject_Channel( /*[in] */ BSTR bstrVendorID ,
/*[in] */ BSTR bstrProductID ,
/*[out, retval]*/ ISAFChannel* *ppCh )
{
__HCP_BEGIN_PROPERTY_GET("CPCHHelpCenterExternal::CreateObject_Channel",hr,ppCh);
INTERNETSECURITY__CHECK_TRUST();
if(!m_Utility) __MPC_SET_ERROR_AND_EXIT(hr, E_ACCESSDENIED);
__MPC_EXIT_IF_METHOD_FAILS(hr, m_Utility->CreateObject_Channel( bstrVendorID, bstrProductID, ppCh ));
__HCP_END_PROPERTY(hr);
}
STDMETHODIMP CPCHHelpCenterExternal::CreateObject_Incident( /*[out, retval]*/ ISAFIncident* *ppIn )
{
__HCP_BEGIN_PROPERTY_GET("CPCHHelpCenterExternal::CreateObject_Incident",hr,ppIn);
CComPtr<CSAFIncident> pIn;
INTERNETSECURITY__CHECK_TRUST();
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &pIn ));
__MPC_EXIT_IF_METHOD_FAILS(hr, pIn.QueryInterface( ppIn ));
__HCP_END_PROPERTY(hr);
}
STDMETHODIMP CPCHHelpCenterExternal::CreateObject_RemoteAssistanceIncident( /* [in] */ BSTR bstrRCTicket,
/* [in] */ long lTimeout,
/* [in] */ BSTR bstrUserName,
/* [in] */ BSTR bstrMessage,
/* [in] */ BSTR bstrPassword,
/* [out,retval] */ ISAFIncident* *ppIn)
{
// This purpose of this method is to hide RemoteDesktopSession object from users.
__HCP_FUNC_ENTRY( "CPCHHelpCenterExternal::CreateObject_RemoteAssistanceIncident" );
HRESULT hr;
CComBSTR pTicket, pUserBlob = "";
CComPtr<ISAFRemoteDesktopSession> pSession;
CComPtr<IDispatch> pDisp;
CComPtr<IDictionary> pMisc;
CComBSTR pEmpty = "";
WCHAR szHeader[12];
time_t ltime;
BOOL bOpenSession = FALSE;
INTERNETSECURITY__CHECK_TRUST();
if(!m_Utility) __MPC_SET_ERROR_AND_EXIT(hr, E_ACCESSDENIED);
// Need to create incident object first.
__MPC_EXIT_IF_METHOD_FAILS(hr, CreateObject_Incident(ppIn));
if (bstrRCTicket != NULL && *bstrRCTicket != L'\0')
{ // open existing session
__MPC_EXIT_IF_METHOD_FAILS(hr, CreateObject_RemoteDesktopSession(0, bstrRCTicket, (BSTR)pEmpty, &pSession));
// Get salem ticket.
__MPC_EXIT_IF_METHOD_FAILS(hr, pSession->get_ConnectParms(&pTicket));
}
else
{ // create new session
if (bstrUserName != NULL && *bstrUserName != L'\0')
{
wsprintf(szHeader, L"%d;FROM=", 5 + wcslen(bstrUserName));
pUserBlob = szHeader;
pUserBlob.Append(bstrUserName);
}
__MPC_EXIT_IF_METHOD_FAILS(hr, CreateObject_RemoteDesktopSession(lTimeout, (BSTR)pEmpty, (BSTR)pUserBlob, &pSession));
// Get salem ticket.
__MPC_EXIT_IF_METHOD_FAILS(hr, pSession->get_ConnectParms(&pTicket));
if (bstrPassword != NULL && *bstrPassword != L'\0')
{
// Use session ID as the base of password challenge.
// Need to create challenge for password.
// Get ISetting of rcbdyctl.dll.
CComPtr<ISAFEncrypt> pEnc;
CComBSTR pString = pTicket;
CComBSTR pPassStub;
// Need to parse and get Session ID
WCHAR *token;
WCHAR *seps = L",";
token = wcstok(pString, seps );
int idx = 0; // Session ID is at [4]
while( token != NULL && ++idx <= 4 )
token = wcstok(NULL, seps);
if (token == NULL)
__MPC_SET_ERROR_AND_EXIT(hr, E_INVALIDARG);
__MPC_EXIT_IF_METHOD_FAILS(hr, CreateObject_Encryption(&pEnc));
__MPC_EXIT_IF_METHOD_FAILS(hr, pEnc->EncryptString(bstrPassword, (BSTR)CComBSTR(token), &pPassStub));
// update user help blob
wsprintf(szHeader, L"%d;PASS=", 5 + pPassStub.Length());
pUserBlob += szHeader;
pUserBlob.Append(pPassStub);
// Update user help blob
__MPC_EXIT_IF_METHOD_FAILS(hr, pSession->put_UserBlob(pUserBlob));
__MPC_EXIT_IF_METHOD_FAILS(hr, (*ppIn)->put_RCTicketEncrypted(VARIANT_TRUE));
}
time(&ltime);
// Initialize incident object with needed properties.
__MPC_EXIT_IF_METHOD_FAILS(hr, (*ppIn)->put_UserName(bstrUserName));
__MPC_EXIT_IF_METHOD_FAILS(hr, (*ppIn)->put_ProblemDescription(bstrMessage));
__MPC_EXIT_IF_METHOD_FAILS(hr, (*ppIn)->get_Misc(&pDisp));
__MPC_EXIT_IF_METHOD_FAILS(hr, pDisp->QueryInterface(IID_IDictionary, (LPVOID*)&pMisc));
__MPC_EXIT_IF_METHOD_FAILS(hr, pMisc->put_Item(&CComVariant("DtStart"), &CComVariant((LONG)ltime)));
__MPC_EXIT_IF_METHOD_FAILS(hr, pMisc->put_Item(&CComVariant("DtLength"), &CComVariant(lTimeout/60))); // convert it to minute
// if (pPassStub.Length())
// __MPC_EXIT_IF_METHOD_FAILS(hr, pMisc->put_Item(&CComVariant("PassStub"), &CComVariant((BSTR)pPassStub)));
}
__MPC_EXIT_IF_METHOD_FAILS(hr, (*ppIn)->put_RCTicket((BSTR)pTicket));
__HCP_FUNC_CLEANUP;
// If it failed, we should release the interfaces.
if (FAILED(hr))
{
if(*ppIn != NULL)
{
(*ppIn)->Release();
(*ppIn) = NULL;
}
if(!pSession == FALSE) // Not empty
pSession->CloseRemoteDesktopSession();
}
__HCP_FUNC_EXIT(hr);
}
////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CPCHHelpCenterExternal::CreateObject_RemoteDesktopSession(
/*[in]*/ long lTimeout ,
/*[in]*/ BSTR bstrConnectionParms ,
/*[in]*/ BSTR bstrUserHelpBlob ,
/*[out, retval]*/ ISAFRemoteDesktopSession* *ppRCS )
{
__HCP_BEGIN_PROPERTY_GET("CPCHHelpCenterExternal::CreateObject_RemoteDesktopSession",hr,ppRCS);
REMOTE_DESKTOP_SHARING_CLASS sharingClass = VIEWDESKTOP_PERMISSION_NOT_REQUIRE;
INTERNETSECURITY__CHECK_TRUST();
if(!m_Utility) __MPC_SET_ERROR_AND_EXIT(hr, E_ACCESSDENIED);
__MPC_EXIT_IF_METHOD_FAILS(hr, m_Utility->CreateObject_RemoteDesktopSession( sharingClass, lTimeout, bstrConnectionParms, bstrUserHelpBlob, ppRCS ));
__HCP_END_PROPERTY(hr);
}
STDMETHODIMP CPCHHelpCenterExternal::ConnectToExpert( /* [in] */ BSTR bstrExpertConnectParm,
/* [in] */ LONG lTimeout,
/* [retval][out] */ LONG *lSafErrorCode)
{
__HCP_BEGIN_PROPERTY_GET("CPCHHelpCenterExternal::ConnectToExpert",hr,lSafErrorCode);
INTERNETSECURITY__CHECK_TRUST();
if(!m_Utility) __MPC_SET_ERROR_AND_EXIT(hr, E_ACCESSDENIED);
__MPC_EXIT_IF_METHOD_FAILS(hr, m_Utility->ConnectToExpert( bstrExpertConnectParm, lTimeout, lSafErrorCode));
__HCP_END_PROPERTY(hr);
}
STDMETHODIMP CPCHHelpCenterExternal::CreateObject_RemoteDesktopManager( /*[out, retval]*/ ISAFRemoteDesktopManager* *ppRDM )
{
__HCP_BEGIN_PROPERTY_GET("CPCHHelpCenterExternal::CreateObject_RemoteDesktopManager",hr,ppRDM);
CComPtr<ISAFRemoteDesktopManager> pSAFRDManager;
INTERNETSECURITY__CHECK_TRUST();
// Instantiate ISAFRemoteDesktopManager.
__MPC_EXIT_IF_METHOD_FAILS(hr, pSAFRDManager.CoCreateInstance( CLSID_SAFRemoteDesktopManager, NULL, CLSCTX_INPROC_SERVER ));
*ppRDM = pSAFRDManager.Detach();
__HCP_END_PROPERTY(hr);
}
STDMETHODIMP CPCHHelpCenterExternal::CreateObject_RemoteDesktopConnection( /*[out, retval]*/ ISAFRemoteDesktopConnection* *ppRDC )
{
__HCP_BEGIN_PROPERTY_GET("CPCHHelpCenterExternal::CreateObject_RemoteDesktopConnection",hr,ppRDC);
INTERNETSECURITY__CHECK_TRUST();
if(!m_Utility) __MPC_SET_ERROR_AND_EXIT(hr, E_ACCESSDENIED);
__MPC_EXIT_IF_METHOD_FAILS(hr, m_Utility->CreateObject_RemoteDesktopConnection( ppRDC ));
__HCP_END_PROPERTY(hr);
}
////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CPCHHelpCenterExternal::CreateObject_ContextMenu( /*[out, retval]*/ IPCHContextMenu* *ppCM )
{
__HCP_BEGIN_PROPERTY_GET("CPCHHelpCenterExternal::CreateObject_ContextMenu",hr,ppCM);
CComPtr<CPCHContextMenu> pObj;
INTERNETSECURITY__CHECK_TRUST();
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &pObj )); pObj->Initialize( this );
__MPC_EXIT_IF_METHOD_FAILS(hr, pObj.QueryInterface( ppCM ));
__HCP_END_PROPERTY(hr);
}
STDMETHODIMP CPCHHelpCenterExternal::CreateObject_PrintEngine( /*[out, retval]*/ IPCHPrintEngine* *ppPE )
{
__HCP_BEGIN_PROPERTY_GET("CPCHHelpCenterExternal::CreateObject_PrintEngine",hr,ppPE);
CComPtr<CPCHPrintEngine> pObj;
INTERNETSECURITY__CHECK_TRUST();
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &pObj ));
__MPC_EXIT_IF_METHOD_FAILS(hr, pObj.QueryInterface( ppPE ));
__HCP_END_PROPERTY(hr);
}
////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CPCHHelpCenterExternal::CreateObject_IntercomClient( /* [out, retval] */ ISAFIntercomClient* *ppI )
{
__HCP_BEGIN_PROPERTY_GET("CPCHHelpCenterExternal::CreateObject_IntercomClient",hr,ppI);
CComPtr<CSAFIntercomClient> pObj;
INTERNETSECURITY__CHECK_TRUST();
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &pObj ));
__MPC_EXIT_IF_METHOD_FAILS(hr, pObj.QueryInterface( ppI ));
__HCP_END_PROPERTY(hr);
}
STDMETHODIMP CPCHHelpCenterExternal::CreateObject_IntercomServer( /* [out, retval] */ ISAFIntercomServer* *ppI )
{
__HCP_BEGIN_PROPERTY_GET("CPCHHelpCenterExternal::CreateObject_IntercomServer",hr,ppI);
CComPtr<CSAFIntercomServer> pObj;
INTERNETSECURITY__CHECK_TRUST();
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &pObj ));
__MPC_EXIT_IF_METHOD_FAILS(hr, pObj.QueryInterface( ppI ));
__HCP_END_PROPERTY(hr);
}
/////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CPCHHelpCenterExternal::OpenFileAsStream( /*[in]*/ BSTR bstrFilename ,
/*[out, retval]*/ IUnknown* *stream )
{
__HCP_FUNC_ENTRY( "CPCHHelpCenterExternal::OpenFileAsStream" );
HRESULT hr;
CComPtr<CPCHScriptableStream> fsStream;
__MPC_PARAMCHECK_BEGIN(hr)
__MPC_PARAMCHECK_STRING_NOT_EMPTY(bstrFilename);
__MPC_PARAMCHECK_POINTER_AND_SET(stream,NULL);
__MPC_PARAMCHECK_END();
INTERNETSECURITY__CHECK_TRUST();
//
// Create a stream for a file.
//
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &fsStream ));
__MPC_EXIT_IF_METHOD_FAILS(hr, fsStream->InitForRead( bstrFilename ));
__MPC_EXIT_IF_METHOD_FAILS(hr, fsStream.QueryInterface( stream ));
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
STDMETHODIMP CPCHHelpCenterExternal::CreateFileAsStream( /*[in]*/ BSTR bstrFilename ,
/*[out, retval]*/ IUnknown* *stream )
{
__HCP_FUNC_ENTRY( "CPCHHelpCenterExternal::OpenFileAsStream" );
HRESULT hr;
CComPtr<CPCHScriptableStream> fsStream;
__MPC_PARAMCHECK_BEGIN(hr)
__MPC_PARAMCHECK_STRING_NOT_EMPTY(bstrFilename);
__MPC_PARAMCHECK_POINTER_AND_SET(stream,NULL);
__MPC_PARAMCHECK_END();
INTERNETSECURITY__CHECK_TRUST();
//
// Create a stream for a file.
//
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &fsStream ));
__MPC_EXIT_IF_METHOD_FAILS(hr, fsStream->InitForWrite( bstrFilename ));
__MPC_EXIT_IF_METHOD_FAILS(hr, fsStream.QueryInterface( stream ));
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
STDMETHODIMP CPCHHelpCenterExternal::CopyStreamToFile( /*[in]*/ BSTR bstrFilename ,
/*[in]*/ IUnknown* stream )
{
__HCP_FUNC_ENTRY( "CPCHHelpCenterExternal::CopyStreamToFile" );
HRESULT hr;
CComPtr<MPC::FileStream> fsStreamDst;
CComPtr<IStream> fsStreamSrc;
LARGE_INTEGER li;
__MPC_PARAMCHECK_BEGIN(hr)
__MPC_PARAMCHECK_STRING_NOT_EMPTY(bstrFilename);
__MPC_PARAMCHECK_NOTNULL(stream);
__MPC_PARAMCHECK_END();
//
// Create a stream for a file.
//
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &fsStreamDst ));
__MPC_EXIT_IF_METHOD_FAILS(hr, fsStreamDst->InitForWrite( bstrFilename ));
//
// Copy the source stream to the file.
//
li.LowPart = 0;
li.HighPart = 0;
__MPC_EXIT_IF_METHOD_FAILS(hr, stream->QueryInterface ( IID_IStream, (void**)&fsStreamSrc ));
__MPC_EXIT_IF_METHOD_FAILS(hr, fsStreamSrc->Seek ( li, STREAM_SEEK_SET, NULL )); // Rewind the stream.
__MPC_EXIT_IF_METHOD_FAILS(hr, fsStreamDst->TransferData( fsStreamSrc, fsStreamDst ));
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
/////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CPCHHelpCenterExternal::NetworkAlive( /*[out, retval]*/ VARIANT_BOOL *pVal )
{
__HCP_FUNC_ENTRY( "CPCHHelpCenterExternal::NetworkAlive" );
HRESULT hr;
CComPtr<IPCHConnectivity> pchc;
INTERNETSECURITY__CHECK_TRUST();
__MPC_EXIT_IF_METHOD_FAILS(hr, get_Connectivity( &pchc ));
__MPC_EXIT_IF_METHOD_FAILS(hr, pchc->NetworkAlive( pVal ));
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
STDMETHODIMP CPCHHelpCenterExternal::DestinationReachable( /*[in] */ BSTR bstrURL ,
/*[out, retval]*/ VARIANT_BOOL *pVal )
{
__HCP_FUNC_ENTRY( "CPCHHelpCenterExternal::DestinationReachable" );
HRESULT hr;
CComPtr<IPCHConnectivity> pchc;
INTERNETSECURITY__CHECK_TRUST();
__MPC_EXIT_IF_METHOD_FAILS(hr, get_Connectivity( &pchc ));
__MPC_EXIT_IF_METHOD_FAILS(hr, pchc->DestinationReachable( bstrURL, pVal ));
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CPCHHelpCenterExternal::FormatError( /*[in ]*/ VARIANT vError ,
/*[out, retval]*/ BSTR *pVal )
{
__HCP_BEGIN_PROPERTY_GET("CPCHHelpCenterExternal::FormatError",hr,pVal);
INTERNETSECURITY__CHECK_TRUST();
if(!m_Utility) __MPC_SET_ERROR_AND_EXIT(hr, E_ACCESSDENIED);
__MPC_EXIT_IF_METHOD_FAILS(hr, m_Utility->FormatError( vError, pVal ));
__HCP_END_PROPERTY(hr);
}
HRESULT CPCHHelpCenterExternal::RegInit( /*[in]*/ BSTR bstrKey ,
/*[in]*/ bool fRead ,
/*[out]*/ MPC::RegKey& rk ,
/*[out]*/ MPC::wstring& strValue )
{
__HCP_FUNC_ENTRY( "CPCHHelpCenterExternal::RegInit" );
HRESULT hr;
HKEY hKeyRoot = HKEY_LOCAL_MACHINE;
MPC::wstring strKey;
LPCWSTR szPtr;
LPCWSTR szPtr2;
__MPC_PARAMCHECK_BEGIN(hr)
__MPC_PARAMCHECK_STRING_NOT_EMPTY(bstrKey);
__MPC_PARAMCHECK_END();
INTERNETSECURITY__CHECK_TRUST();
szPtr = bstrKey;
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::RegKey::ParsePath( szPtr, hKeyRoot, szPtr ));
szPtr2 = wcsrchr( szPtr, '\\' );
if(szPtr2)
{
strKey.assign( szPtr, szPtr2 - szPtr );
strValue = &szPtr2[1];
}
else
{
strKey = szPtr;
}
__MPC_EXIT_IF_METHOD_FAILS(hr, rk.SetRoot( hKeyRoot, fRead ? KEY_READ : KEY_ALL_ACCESS ));
__MPC_EXIT_IF_METHOD_FAILS(hr, rk.Attach ( strKey.c_str() ));
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
STDMETHODIMP CPCHHelpCenterExternal::RegRead( /*[in]*/ BSTR bstrKey, /*[out, retval]*/ VARIANT *pVal )
{
__HCP_FUNC_ENTRY( "CPCHHelpCenterExternal::RegRead" );
HRESULT hr;
MPC::RegKey rk;
MPC::wstring strValue;
bool fFound;
__MPC_PARAMCHECK_BEGIN(hr)
__MPC_PARAMCHECK_NOTNULL(pVal);
__MPC_PARAMCHECK_END();
__MPC_EXIT_IF_METHOD_FAILS(hr, RegInit( bstrKey, /*fRead*/true, rk, strValue ));
__MPC_EXIT_IF_METHOD_FAILS(hr, rk.get_Value( *pVal, fFound, strValue.size() ? strValue.c_str() : NULL ));
if(pVal->vt == (VT_ARRAY | VT_BSTR))
{
// We do the conversion so that JScript code can access the array.
MPC::WStringList lst;
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::ConvertSafeArrayToList( *pVal, lst ));
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::ConvertListToSafeArray( lst, *pVal, VT_VARIANT ));
}
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
STDMETHODIMP CPCHHelpCenterExternal::RegWrite( /*[in]*/ BSTR bstrKey, /*[in]*/ VARIANT newVal, /*[in,optional]*/ VARIANT vKind )
{
__HCP_FUNC_ENTRY( "CPCHHelpCenterExternal::RegWrite" );
HRESULT hr;
MPC::RegKey rk;
MPC::wstring strValue;
CComVariant v( newVal );
bool fExpand = false;
__MPC_EXIT_IF_METHOD_FAILS(hr, RegInit( bstrKey, /*fRead*/false, rk, strValue ));
if(vKind.vt == VT_BSTR && STRINGISPRESENT(vKind.bstrVal))
{
if(!_wcsicmp( vKind.bstrVal, L"REG_DWORD" ))
{
__MPC_EXIT_IF_METHOD_FAILS(hr, v.ChangeType( VT_I4 ));
}
if(!_wcsicmp( vKind.bstrVal, L"REG_SZ" ))
{
__MPC_EXIT_IF_METHOD_FAILS(hr, v.ChangeType( VT_BSTR ));
}
if(!_wcsicmp( vKind.bstrVal, L"REG_EXPAND_SZ" ))
{
fExpand = true;
__MPC_EXIT_IF_METHOD_FAILS(hr, v.ChangeType( VT_BSTR ));
}
if(!_wcsicmp( vKind.bstrVal, L"REG_MULTI_SZ" ))
{
fExpand = true;
__MPC_EXIT_IF_METHOD_FAILS(hr, v.ChangeType( VT_ARRAY | VT_BSTR ));
}
}
__MPC_EXIT_IF_METHOD_FAILS(hr, rk.Create ( ));
__MPC_EXIT_IF_METHOD_FAILS(hr, rk.put_Value( newVal, strValue.size() ? strValue.c_str() : NULL, fExpand ));
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
STDMETHODIMP CPCHHelpCenterExternal::RegDelete( /*[in]*/ BSTR bstrKey )
{
__HCP_FUNC_ENTRY( "CPCHHelpCenterExternal::RegDelete" );
HRESULT hr;
MPC::RegKey rk;
MPC::wstring strValue;
__MPC_EXIT_IF_METHOD_FAILS(hr, RegInit( bstrKey, /*fRead*/false, rk, strValue ));
if(strValue.size())
{
__MPC_EXIT_IF_METHOD_FAILS(hr, rk.del_Value( strValue.c_str() ));
}
else
{
__MPC_EXIT_IF_METHOD_FAILS(hr, rk.Delete( /*fDeep*/false ));
}
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CPCHHelpCenterExternal::Close()
{
__HCP_FUNC_ENTRY( "CPCHHelpCenterExternal::Close" );
HRESULT hr;
HWND hwnd;
INTERNETSECURITY__CHECK_TRUST();
//
// In case we are called really early, give the application some time to initialize properly.
//
MPC::SleepWithMessagePump( 100 );
if((hwnd = Window()) != NULL)
{
::PostMessage( hwnd, WM_CLOSE, 0, 0 );
}
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
STDMETHODIMP CPCHHelpCenterExternal::RefreshUI()
{
__HCP_FUNC_ENTRY( "CPCHHelpCenterExternal::RefreshUI" );
MSG msg;
//
// There is one or more window message available. Dispatch them
//
while(::PeekMessage( &msg, NULL, NULL, NULL, PM_REMOVE ))
{
::TranslateMessage( &msg );
::DispatchMessage ( &msg );
}
__HCP_FUNC_EXIT(S_OK);
}
////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CPCHHelpCenterExternal::Print( /*[in]*/ VARIANT window, /*[in]*/ VARIANT_BOOL fEvent, /*[out, retval]*/ VARIANT_BOOL *pVal )
{
__HCP_FUNC_ENTRY( "CPCHHelpCenterExternal::Print" );
HRESULT hr;
VARIANT_BOOL Cancel;
if(m_fHidden)
{
__MPC_EXIT_IF_METHOD_FAILS(hr, E_ACCESSDENIED);
}
if(fEvent == VARIANT_TRUE)
{
if(SUCCEEDED(m_Events.FireEvent_Print( &Cancel )))
{
if(Cancel == VARIANT_TRUE)
{
__MPC_FUNC_LEAVE;
}
}
}
{
CComQIPtr<IWebBrowser2> wb2;
if(window.vt == VT_DISPATCH)
{
wb2 = window.pdispVal;
}
else
{
wb2.Attach( IsHHWindowVisible() ? HHWindow() : Contents() );
}
if(wb2)
{
(void)wb2->ExecWB( OLECMDID_PRINT, OLECMDEXECOPT_DODEFAULT, NULL, NULL );
}
}
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
////////////////////////////////////////////////////////////////////////////////
static HRESULT local_HighlighDocument( /*[in]*/ IHTMLDocument2* doc ,
/*[in]*/ MPC::WStringList& lst )
{
__HCP_FUNC_ENTRY( "local_HighlighDocument" );
HRESULT hr;
CComPtr<IHTMLElement> elem;
__MPC_EXIT_IF_METHOD_FAILS(hr, doc->get_body( &elem ));
if(elem)
{
CComPtr<IHTMLBodyElement> bodyElement;
CComBSTR bstrCmd ( L"BackColor" );
CComBSTR bstrCmd2 ( L"ForeColor" );
CComVariant vBackColor( (long)::GetSysColor( COLOR_HIGHLIGHT ) );
CComVariant vForeColor( (long)::GetSysColor( COLOR_HIGHLIGHTTEXT ) );
DWORD dwTimeout;
MPC::WStringIterConst it;
__MPC_EXIT_IF_METHOD_FAILS(hr, elem.QueryInterface( &bodyElement ));
dwTimeout = ::GetTickCount() + 6000;
for(it = lst.begin(); it != lst.end(); it++)
{
CComBSTR bstrSearchTerm( it->c_str() );
CComPtr<IHTMLTxtRange> range;
VARIANT_BOOL vbRet;
__MPC_EXIT_IF_METHOD_FAILS(hr, bodyElement->createTextRange( &range ));
while(1)
{
if(FAILED(range->findText( bstrSearchTerm, 1000000, 2, &vbRet )) || vbRet != VARIANT_TRUE) break;
if(FAILED(range->execCommand( bstrCmd2, VARIANT_FALSE, vForeColor, &vbRet )) || vbRet != VARIANT_TRUE) break;
if(FAILED(range->execCommand( bstrCmd , VARIANT_FALSE, vBackColor, &vbRet )) || vbRet != VARIANT_TRUE) break;
if(::GetTickCount() > dwTimeout) break;
if(FAILED(range->collapse( VARIANT_FALSE ))) break;
}
if(::GetTickCount() > dwTimeout) break;
}
}
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
STDMETHODIMP CPCHHelpCenterExternal::HighlightWords( /*[in]*/ VARIANT window, /*[in]*/ VARIANT words )
{
__HCP_FUNC_ENTRY( "CPCHHelpCenterExternal::HighlightWords" );
HRESULT hr;
CComPtr<IHTMLDocument2> doc;
if(window.vt == VT_DISPATCH)
{
if(FAILED(MPC::HTML::IDispatch_To_IHTMLDocument2( doc, window.pdispVal )))
{
doc.Release();
}
}
if(!doc)
{
//
// If the caller didn't specify a window, we'll get the currently displayed window.
//
CComPtr<IWebBrowser2> wb2; wb2.Attach( IsHHWindowVisible() ? HHWindow() : Contents() );
if(wb2)
{
CComPtr<IDispatch> docDisp;
__MPC_EXIT_IF_METHOD_FAILS(hr, wb2->get_Document( &docDisp ));
if(docDisp)
{
__MPC_EXIT_IF_METHOD_FAILS(hr, docDisp.QueryInterface( &doc ));
}
}
}
if(doc)
{
MPC::WStringList lst;
CComPtr<IHTMLFramesCollection2> frames;
if(words.vt == (VT_ARRAY | VT_BSTR ) ||
words.vt == (VT_ARRAY | VT_VARIANT) )
{
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::ConvertSafeArrayToList( words, lst ));
}
else if(words.vt == VT_BSTR)
{
lst.push_back( SAFEWSTR( words.bstrVal ) );
}
(void)local_HighlighDocument( doc, lst );
__MPC_EXIT_IF_METHOD_FAILS(hr, doc->get_frames( &frames ));
if(frames)
{
long len;
__MPC_EXIT_IF_METHOD_FAILS(hr, frames->get_length( &len ));
for(int i=0; i<len; i++)
{
CComVariant vIndex = i;
CComVariant vValue;
__MPC_EXIT_IF_METHOD_FAILS(hr, frames->item( &vIndex, &vValue ));
if(vValue.vt == VT_DISPATCH)
{
CComQIPtr<IHTMLWindow2> fb = vValue.pdispVal;
if(fb)
{
CComPtr<IHTMLDocument2> docSub;
__MPC_EXIT_IF_METHOD_FAILS(hr, fb->get_document( &docSub ));
if(docSub)
{
(void)local_HighlighDocument( docSub, lst );
}
}
}
}
}
}
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CPCHHelpCenterExternal::MessageBox( /*[in]*/ BSTR bstrText, /*[in]*/ BSTR bstrKind, /*[out, retval]*/ BSTR *pVal )
{
__HCP_FUNC_ENTRY( "CPCHHelpCenterExternal::MessageBox" );
HRESULT hr;
MPC::wstring szTitle; MPC::LocalizeString( IDS_MAINWND_TITLE, szTitle );
DWORD dwType = 0;
LPCWSTR szRes;
__MPC_PARAMCHECK_BEGIN(hr)
__MPC_PARAMCHECK_POINTER_AND_SET(pVal,NULL);
__MPC_PARAMCHECK_END();
if(m_fHidden)
{
__MPC_EXIT_IF_METHOD_FAILS(hr, E_ACCESSDENIED);
}
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::ConvertStringToBitField( bstrKind, dwType, s_arrMessageBoxMap ));
if(dwType == 0) dwType = MB_OK;
switch( ::MessageBoxW( m_hwnd, SAFEBSTR( bstrText ), szTitle.c_str(), dwType ) )
{
case IDABORT : szRes = L"ABORT" ; break;
case IDCANCEL : szRes = L"CANCEL" ; break;
case IDCONTINUE: szRes = L"CONTINUE"; break;
case IDIGNORE : szRes = L"IGNORE" ; break;
case IDNO : szRes = L"NO" ; break;
case IDOK : szRes = L"OK" ; break;
case IDRETRY : szRes = L"RETRY" ; break;
case IDTRYAGAIN: szRes = L"TRYAGAIN"; break;
case IDYES : szRes = L"YES" ; break;
default : szRes = L"" ; break;
}
hr = MPC::GetBSTR( szRes, pVal );
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
////////////////////////////////////////
struct SelectFolder_Data
{
BSTR bstrDefault;
BSTR bstrPrefix;
BSTR bstrSuffix;
};
static int CALLBACK SelectFolder_Callback( HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData )
{
SelectFolder_Data* ptr = (SelectFolder_Data*)lpData;
switch(uMsg)
{
case BFFM_INITIALIZED:
if(ptr->bstrDefault)
{
::SendMessageW( hwnd, BFFM_SETSELECTIONW, TRUE, (LPARAM)ptr->bstrDefault );
}
break;
case BFFM_SELCHANGED:
{
BOOL fEnabled = TRUE;
if(ptr->bstrPrefix)
{
}
::SendMessageW( hwnd, BFFM_ENABLEOK, 0, fEnabled );
}
break;
}
return 0;
}
STDMETHODIMP CPCHHelpCenterExternal::SelectFolder( /*[in]*/ BSTR bstrTitle, /*[in]*/ BSTR bstrDefault, /*[out, retval]*/ BSTR *pVal )
{
__HCP_FUNC_ENTRY( "CPCHHelpCenterExternal::SelectFolder" );
HRESULT hr;
LPITEMIDLIST pidl = NULL;
CComPtr<IMalloc> malloc;
SelectFolder_Data data;
BROWSEINFOW bi;
__MPC_PARAMCHECK_BEGIN(hr)
__MPC_PARAMCHECK_POINTER_AND_SET(pVal,NULL);
__MPC_PARAMCHECK_END();
INTERNETSECURITY__CHECK_TRUST();
__MPC_EXIT_IF_METHOD_FAILS(hr, ::SHGetMalloc( &malloc ));
::ZeroMemory( &bi, sizeof( bi ) );
bi.hwndOwner = m_hwnd;
bi.lpszTitle = bstrTitle;
bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_USENEWUI | BIF_STATUSTEXT | BIF_VALIDATE;
bi.lpfn = SelectFolder_Callback;
bi.lParam = (LPARAM)&data;
data.bstrDefault = bstrDefault;
data.bstrPrefix = NULL;
data.bstrSuffix = NULL;
pidl = ::SHBrowseForFolderW( &bi );
if(pidl)
{
WCHAR rgPath[MAX_PATH];
if(::SHGetPathFromIDListW( pidl, rgPath ))
{
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::GetBSTR( rgPath, pVal ));
}
}
hr = S_OK;
__HCP_FUNC_CLEANUP;
if(malloc && pidl) malloc->Free( pidl );
__HCP_FUNC_EXIT(hr);
}
////////////////////////////////////////////////////////////////////////////////
CPCHHelper_IDocHostUIHandler::CPCHHelper_IDocHostUIHandler()
{
m_parent = NULL; CPCHHelpCenterExternal* m_parent;
}
void CPCHHelper_IDocHostUIHandler::Initialize( /*[in]*/ CPCHHelpCenterExternal* parent )
{
m_parent = parent;
}
STDMETHODIMP CPCHHelper_IDocHostUIHandler::QueryService( REFGUID guidService, REFIID riid, void **ppv )
{
HRESULT hr = E_NOINTERFACE;
if(InlineIsEqualGUID( riid, IID_IDocHostUIHandler ))
{
hr = QueryInterface( riid, ppv );
}
return hr;
}
STDMETHODIMP CPCHHelper_IDocHostUIHandler::ShowContextMenu( DWORD dwID, POINT* pptPosition, IUnknown* pCommandTarget, IDispatch* pDispatchObjectHit )
{
if(g_Debug_CONTEXTMENU)
{
if(::GetKeyState( VK_CONTROL ) & 0x8000) return E_NOTIMPL;
}
if(g_Debug_BUILDTREE)
{
if(::GetKeyState( VK_MENU ) & 0x8000)
{
CComVariant vArg( pDispatchObjectHit );
(void)m_parent->CallFunctionOnPanel( HSCPANEL_NAVBAR, NULL, s_bstrFunc_BuildTree, &vArg, 1 );
}
}
//
// Last chance for the scripts to say something...
//
{
CComVariant vArgs[4];
CComVariant vRes;
DWORD dwCmd = -1;
vArgs[3] = (long)dwID;
vArgs[2] = pDispatchObjectHit;
vArgs[1] = (long)pptPosition->x;
vArgs[0] = (long)pptPosition->y;
(void)m_parent->CallFunctionOnPanel( HSCPANEL_NAVBAR, NULL, s_bstrFunc_GlobalContextMenu, vArgs, ARRAYSIZE(vArgs), &vRes );
if(vRes.vt == VT_BSTR && vRes.bstrVal)
{
if(!_wcsicmp( vRes.bstrVal, L"DELEGATE" )) return E_NOTIMPL;
if(!_wcsicmp( vRes.bstrVal, L"SELECTALL" )) dwCmd = OLECMDID_SELECTALL;
if(!_wcsicmp( vRes.bstrVal, L"REFRESH" )) dwCmd = OLECMDID_REFRESH;
if(!_wcsicmp( vRes.bstrVal, L"PROPERTIES" )) dwCmd = OLECMDID_PROPERTIES;
}
if(dwCmd != -1)
{
CComVariant vaIn;
CComVariant vaOut;
switch(dwCmd)
{
case OLECMDID_PROPERTIES: // Trident folks say the In value must be set to the mouse pos
vaIn = MAKELONG(pptPosition->x,pptPosition->y);
break;
}
((IOleCommandTarget*)pCommandTarget)->Exec( NULL, dwCmd, OLECMDEXECOPT_DODEFAULT, &vaIn, &vaOut );
}
}
return S_OK;
}
STDMETHODIMP CPCHHelper_IDocHostUIHandler::GetHostInfo(DOCHOSTUIINFO* pInfo)
{
pInfo->dwFlags = DOCHOSTUIFLAG_NO3DBORDER |
DOCHOSTUIFLAG_ENABLE_FORMS_AUTOCOMPLETE |
DOCHOSTUIFLAG_THEME;
pInfo->dwDoubleClick = DOCHOSTUIDBLCLK_DEFAULT;
return S_OK;
}
STDMETHODIMP CPCHHelper_IDocHostUIHandler::ShowUI(DWORD dwID, IOleInPlaceActiveObject* pActiveObject, IOleCommandTarget* pCommandTarget, IOleInPlaceFrame* pFrame, IOleInPlaceUIWindow* pDoc)
{
return E_NOTIMPL;
}
STDMETHODIMP CPCHHelper_IDocHostUIHandler::HideUI()
{
return E_NOTIMPL;
}
STDMETHODIMP CPCHHelper_IDocHostUIHandler::UpdateUI()
{
return E_NOTIMPL;
}
STDMETHODIMP CPCHHelper_IDocHostUIHandler::EnableModeless(BOOL fEnable)
{
return E_NOTIMPL;
}
STDMETHODIMP CPCHHelper_IDocHostUIHandler::OnDocWindowActivate(BOOL fActivate)
{
return E_NOTIMPL;
}
STDMETHODIMP CPCHHelper_IDocHostUIHandler::OnFrameWindowActivate(BOOL fActivate)
{
return E_NOTIMPL;
}
STDMETHODIMP CPCHHelper_IDocHostUIHandler::ResizeBorder(LPCRECT prcBorder, IOleInPlaceUIWindow* pUIWindow, BOOL fFrameWindow)
{
return E_NOTIMPL;
}
STDMETHODIMP CPCHHelper_IDocHostUIHandler::TranslateAccelerator(LPMSG lpMsg, const GUID* pguidCmdGroup, DWORD nCmdID)
{
bool fCancel = false;
bool fBack = false;
bool fForward = false;
bool fPossibleBack = false;
switch(nCmdID)
{
// case IDM_CONTEXTMENU:
case IDM_GOBACKWARD :
fCancel = true;
fBack = true;
break;
case IDM_GOFORWARD:
fCancel = true;
fForward = true;
break;
}
if(lpMsg->message == WM_KEYDOWN ||
lpMsg->message == WM_KEYUP )
{
switch(lpMsg->wParam)
{
case 'N': // CTRL-N (new window) disabled.
if(::GetKeyState( VK_CONTROL ) & 0x8000)
{
if (!( HIWORD(lpMsg->lParam) & KF_ALTDOWN ))
{
fCancel = true;
}
}
break;
case VK_F5: // We want to disable F5 as a refresh tool.
fCancel = true;
break;
case VK_BACK: // Enable "backspace" directly.
fPossibleBack = true;
break;
}
}
// (weizhao) Changed to go back or forward only on WM_SYSKEYDOWN,
// otherwise would have gone twice on a single key stroke (down & up).
//
// if(lpMsg->message == WM_SYSKEYDOWN ||
// lpMsg->message == WM_SYSKEYUP )
if(lpMsg->message == WM_SYSKEYDOWN)
{
switch(lpMsg->wParam)
{
case VK_LEFT:
fCancel = true;
fBack = true;
break;
case VK_RIGHT:
fCancel = true;
fForward = true;
break;
}
}
////////////////////
if(fPossibleBack || fBack || fForward)
{
if(m_parent)
{
CPCHHelpSession* hs = m_parent->HelpSession();
if(hs)
{
if(fPossibleBack)
{
hs->PossibleBack();
}
if(fBack)
{
if(hs->IsTravelling() == false) (void)hs->Back( 1 );
}
if(fForward)
{
if(hs->IsTravelling() == false) (void)hs->Forward( 1 );
}
}
}
}
if(fCancel == false)
{
fCancel = SUCCEEDED(m_parent->ProcessMessage( lpMsg ));
}
return fCancel ? S_OK : E_NOTIMPL;
}
STDMETHODIMP CPCHHelper_IDocHostUIHandler::GetOptionKeyPath(BSTR* pbstrKey, DWORD dwReserved)
{
if(pbstrKey)
{
static const WCHAR c_options[] = HC_REGISTRY_HELPCTR_IE;
BSTR szBuf = (BSTR)::CoTaskMemAlloc( sizeof(c_options) );
if(szBuf)
{
wcscpy( *pbstrKey = szBuf, c_options );
}
}
return S_OK;
}
STDMETHODIMP CPCHHelper_IDocHostUIHandler::GetDropTarget(IDropTarget* pDropTarget, IDropTarget** ppDropTarget)
{
return E_NOTIMPL;
}
STDMETHODIMP CPCHHelper_IDocHostUIHandler::GetExternal(IDispatch** ppDispatch)
{
return E_NOTIMPL;
}
STDMETHODIMP CPCHHelper_IDocHostUIHandler::TranslateUrl(DWORD dwTranslate, OLECHAR* pchURLIn, OLECHAR** ppchURLOut)
{
return E_NOTIMPL;
}
STDMETHODIMP CPCHHelper_IDocHostUIHandler::FilterDataObject(IDataObject* pDO, IDataObject** ppDORet)
{
return E_NOTIMPL;
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
CPCHContextMenu::CPCHContextMenu()
{
m_parent = NULL; // CPCHHelpCenterExternal* m_parent;
// List m_lstItems;
m_iLastItem = 1; // int m_iLastItem;
}
CPCHContextMenu::~CPCHContextMenu()
{
}
void CPCHContextMenu::Initialize( /*[in]*/ CPCHHelpCenterExternal* parent )
{
m_parent = parent;
}
////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CPCHContextMenu::AddItem( /*[in]*/ BSTR bstrText ,
/*[in]*/ BSTR bstrID ,
/*[in, optional]*/ VARIANT vFlags )
{
__HCP_FUNC_ENTRY( "CPCHContextMenu::AddItem" );
HRESULT hr;
__MPC_PARAMCHECK_BEGIN(hr)
__MPC_PARAMCHECK_STRING_NOT_EMPTY(bstrText);
__MPC_PARAMCHECK_STRING_NOT_EMPTY(bstrID);
__MPC_PARAMCHECK_END();
{
const UINT sAllowedFlags = MF_GRAYED |
MF_CHECKED;
Entry& ent = *(m_lstItems.insert( m_lstItems.end() ));
ent.bstrText = bstrText;
ent.bstrID = bstrID;
ent.iID = m_iLastItem++;
ent.uFlags = (vFlags.vt == VT_I4 ? vFlags.lVal : 0) & sAllowedFlags;
}
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
STDMETHODIMP CPCHContextMenu::AddSeparator()
{
__HCP_FUNC_ENTRY( "CPCHContextMenu::AddSeparator" );
HRESULT hr;
{
Entry& ent = *(m_lstItems.insert( m_lstItems.end() ));
ent.iID = -1;
}
hr = S_OK;
__HCP_FUNC_EXIT(hr);
}
STDMETHODIMP CPCHContextMenu::Display( /*[out,retval]*/ BSTR *pVal )
{
__HCP_FUNC_ENTRY( "CPCHContextMenu::Display" );
HRESULT hr;
HMENU hMenu = NULL;
Iter it;
int iSelected;
POINT pt;
__MPC_PARAMCHECK_BEGIN(hr)
__MPC_PARAMCHECK_POINTER_AND_SET(pVal,NULL);
__MPC_PARAMCHECK_END();
__MPC_EXIT_IF_CALL_RETURNS_NULL(hr, (hMenu = ::CreatePopupMenu()));
//
// Populate menu.
//
for(it = m_lstItems.begin(); it != m_lstItems.end(); it++)
{
Entry& ent = *it;
if(ent.iID < 0)
{
__MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::AppendMenuW( hMenu, MF_SEPARATOR, 0, 0 ));
}
else
{
__MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::AppendMenuW( hMenu, MF_STRING | ent.uFlags, ent.iID, ent.bstrText ));
}
}
::GetCursorPos( &pt );
//
// Find the active panel and its active element. If the cursor is inside its bounding rectangle, display the CM under the cursor.
// Otherwise display the CM at the upper-left corner of the element.
//
{
IMarsWindowOM* shell = m_parent->Shell();
CComPtr<IMarsPanelCollection> coll;
if(shell && SUCCEEDED(shell->get_panels( &coll )) && coll)
{
CComPtr<IMarsPanel> panel;
if(SUCCEEDED(coll->get_activePanel( &panel )) && panel)
{
CComPtr<IDispatch> disp;
if(panel == m_parent->Panel( HSCPANEL_HHWINDOW ))
{
CComPtr<IWebBrowser2> wb2; wb2.Attach( m_parent->HHWindow() );
disp = wb2;
}
else
{
(void)panel->get_content( &disp );
}
if(disp)
{
CComQIPtr<IWebBrowser2> wb2 = disp;
CComQIPtr<IHTMLDocument2> doc2;
if(wb2)
{
disp.Release();
wb2->get_Document( &disp );
}
doc2 = disp;
//
// Look for the inner-most active element.
//
{
CComPtr<IHTMLElement> elem;
while(doc2 && SUCCEEDED(doc2->get_activeElement( &elem )) && elem)
{
//
// This could be a frame.
//
CComPtr<IHTMLFrameBase2> frame;
if(SUCCEEDED(elem.QueryInterface( &frame )))
{
CComPtr<IHTMLWindow2> winsub;
if(SUCCEEDED(frame->get_contentWindow( &winsub )) && winsub)
{
doc2.Release();
elem.Release();
(void)winsub->get_document( &doc2 );
continue;
}
}
break;
}
{
CComQIPtr<IServiceProvider> sp = elem;
if(sp)
{
CComPtr<IAccessible> acc;
if(SUCCEEDED(sp->QueryService( IID_IAccessible, IID_IAccessible, (void**)&acc )))
{
long xLeft;
long yTop;
long cxWidth;
long cyHeight;
VARIANT v;
v.vt = VT_I4;
v.lVal = CHILDID_SELF;
if(SUCCEEDED(acc->accLocation( &xLeft, &yTop, &cxWidth, &cyHeight, v )))
{
if(pt.x < xLeft || pt.x > xLeft + cxWidth ||
pt.y < yTop || pt.y > yTop + cyHeight )
{
DWORD dwDefaultLayout;
if(::GetProcessDefaultLayout( &dwDefaultLayout ) && (dwDefaultLayout & LAYOUT_RTL))
{
pt.x = xLeft + cxWidth;
pt.y = yTop;
}
else
{
pt.x = xLeft;
pt.y = yTop;
}
}
}
}
}
}
}
}
}
}
}
iSelected = ::TrackPopupMenu( hMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD | TPM_NONOTIFY, pt.x, pt.y, 0, m_parent->Window(), NULL );
if(iSelected != 0)
{
for(it = m_lstItems.begin(); it != m_lstItems.end(); it++)
{
Entry& ent = *it;
if(ent.iID == iSelected)
{
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::GetBSTR( ent.bstrID, pVal ));
}
}
}
hr = S_OK;
__HCP_FUNC_CLEANUP;
if(hMenu) ::DestroyMenu( hMenu );
__HCP_FUNC_EXIT(hr);
}