1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 // SODispatchInterceptor.cpp : Implementation of CHelpApp and DLL registration. 23 24 #include "stdio.h" 25 #include "stdafx2.h" 26 #include "so_activex.h" 27 #include "SOActiveX.h" 28 #include "SODispatchInterceptor.h" 29 #include "com_uno_helper.h" 30 31 ///////////////////////////////////////////////////////////////////////////// 32 // 33 34 STDMETHODIMP SODispatchInterceptor::InterfaceSupportsErrorInfo(REFIID riid) 35 { 36 static const IID* arr[] = 37 { 38 &IID_ISODispatchInterceptor, 39 }; 40 41 for (int i=0;i<sizeof(arr)/sizeof(arr[0]);i++) 42 { 43 #if defined(_MSC_VER) && (_MSC_VER >= 1300) 44 if (InlineIsEqualGUID(*arr[i],riid)) 45 #else 46 if (::ATL::InlineIsEqualGUID(*arr[i],riid)) 47 #endif 48 return S_OK; 49 } 50 return S_FALSE; 51 } 52 53 STDMETHODIMP SODispatchInterceptor::queryDispatch( IDispatch FAR* aURL, 54 BSTR aTargetFrameName, 55 long nSearchFlags, 56 IDispatch FAR* FAR* retVal ) 57 { 58 if ( !aURL || !retVal ) return E_FAIL; 59 60 CComVariant aTargetUrl; 61 OLECHAR* sURLMemberName = L"Complete"; 62 DISPID nURLID; 63 HRESULT hr = aURL->GetIDsOfNames( IID_NULL, &sURLMemberName, 1, LOCALE_USER_DEFAULT, &nURLID ); 64 if( !SUCCEEDED( hr ) ) return hr; 65 66 hr = CComDispatchDriver::GetProperty( aURL, nURLID, &aTargetUrl ); 67 if( !SUCCEEDED( hr ) ) return hr; 68 69 if( aTargetUrl.vt != VT_BSTR ) return E_FAIL; 70 71 USES_CONVERSION; 72 if( !strncmp( OLE2T( aTargetUrl.bstrVal ), ".uno:OpenHyperlink", 18 ) ) 73 { 74 CComQIPtr< IDispatch, &IID_IDispatch > pIDisp( this ); 75 if( pIDisp ) 76 { 77 this->AddRef(); 78 *retVal = pIDisp; 79 } 80 } 81 else 82 { 83 if( !m_xSlave ) 84 { 85 *retVal = NULL; 86 return S_OK; 87 } 88 89 CComVariant aResult; 90 CComVariant aArgs[3]; 91 aArgs[0] = CComVariant( nSearchFlags ); 92 aArgs[1] = CComVariant( aTargetFrameName ); 93 aArgs[2] = CComVariant( aURL ); 94 95 hr = ExecuteFunc( m_xSlave, L"queryDispatch", aArgs, 3, &aResult ); 96 if( !SUCCEEDED( hr ) || aResult.vt != VT_DISPATCH || aResult.pdispVal == NULL ) 97 { 98 *retVal = NULL; 99 return S_OK; 100 } 101 102 *retVal = aResult.pdispVal; 103 104 CComQIPtr< IUnknown, &IID_IUnknown > pIUnk( *retVal ); 105 if( pIUnk ) 106 (*retVal)->AddRef(); 107 } 108 109 return S_OK; 110 } 111 112 STDMETHODIMP SODispatchInterceptor::queryDispatches( SAFEARRAY FAR* aDescripts, SAFEARRAY FAR* FAR* retVal) 113 { 114 if ( !aDescripts || !retVal || SafeArrayGetDim( aDescripts ) != 1 ) 115 return E_FAIL; 116 117 long nLB, nUB; 118 119 HRESULT hr = SafeArrayGetLBound( aDescripts, 1, &nLB ); 120 if( !SUCCEEDED( hr ) ) return hr; 121 122 hr = SafeArrayGetUBound( aDescripts, 1, &nUB ); 123 if( !SUCCEEDED( hr ) ) return hr; 124 if( nUB < nLB ) return E_FAIL; 125 126 *retVal = SafeArrayCreateVector( VT_DISPATCH, 0, nUB - nLB ); 127 128 for ( long ind = nLB; ind <= nUB; ind ++ ) 129 { 130 CComPtr<IDispatch> pElem; 131 SafeArrayGetElement( aDescripts, &ind, pElem ); 132 if( pElem ) 133 { 134 OLECHAR* pMemberNames[3] = { L"FeatureURL", L"FrameName", L"SearchFlags" }; 135 CComVariant pValues[3]; 136 hr = GetPropertiesFromIDisp( pElem, pMemberNames, pValues, 3 ); 137 if( !SUCCEEDED( hr ) ) return hr; 138 if( pValues[0].vt != VT_DISPATCH || pValues[0].pdispVal == NULL 139 || pValues[1].vt != VT_BSTR || pValues[2].vt != VT_I4 ) 140 return E_FAIL; 141 142 CComPtr<IDispatch> aRes; 143 hr = queryDispatch( pValues[0].pdispVal, pValues[1].bstrVal, pValues[2].lVal, &aRes ); 144 SafeArrayPutElement( *retVal, &ind, aRes ); 145 } 146 } 147 148 return S_OK; 149 } 150 151 152 STDMETHODIMP SODispatchInterceptor::dispatch( IDispatch FAR* aURL, SAFEARRAY FAR* aArgs) 153 { 154 // get url from aURL 155 OLECHAR* pUrlName = L"Complete"; 156 CComVariant pValue; 157 HRESULT hr = GetPropertiesFromIDisp( aURL, &pUrlName, &pValue, 1 ); 158 if( !SUCCEEDED( hr ) ) return hr; 159 if( pValue.vt != VT_BSTR || pValue.bstrVal == NULL ) 160 return E_FAIL; 161 162 USES_CONVERSION; 163 if( !strncmp( OLE2T( pValue.bstrVal ), ".uno:OpenHyperlink", 18 ) ) 164 { 165 long nLB = 0, nUB = 0; 166 // long nDim = SafeArrayGetDim( aArgs ); 167 168 hr = SafeArrayGetLBound( aArgs, 1, &nLB ); 169 if( !SUCCEEDED( hr ) ) return hr; 170 171 hr = SafeArrayGetUBound( aArgs, 1, &nUB ); 172 if( !SUCCEEDED( hr ) ) return hr; 173 if( nUB < nLB ) return E_FAIL; 174 175 for ( long ind = nLB; ind <= nUB; ind ++ ) 176 { 177 CComVariant pVarElem; 178 SafeArrayGetElement( aArgs, &ind, &pVarElem ); 179 if( pVarElem.vt == VT_DISPATCH && pVarElem.pdispVal != NULL ) 180 { 181 OLECHAR* pMemberNames[2] = { L"Name", L"Value" }; 182 CComVariant pValues[2]; 183 hr = GetPropertiesFromIDisp( pVarElem.pdispVal, pMemberNames, pValues, 2 ); 184 if( !SUCCEEDED( hr ) ) return hr; 185 186 if( pValues[0].vt == VT_BSTR && pValues[1].vt == VT_BSTR ) 187 { 188 USES_CONVERSION; 189 if( !strncmp( OLE2T( pValues[0].bstrVal ), "URL", 3 ) ) 190 { 191 EnterCriticalSection( &mMutex ); 192 if( m_xParentControl ) 193 { 194 // call GetUrl to the browser instance 195 m_xParentControl->GetURL( pValues[1].bstrVal, L"_self" ); 196 } 197 LeaveCriticalSection( &mMutex ); 198 199 break; 200 } 201 } 202 } 203 } 204 } 205 206 return S_OK; 207 } 208 209 STDMETHODIMP SODispatchInterceptor::addStatusListener( IDispatch FAR* /*xControl*/, IDispatch FAR* /*aURL*/) 210 { 211 // not implemented 212 return S_OK; 213 } 214 215 STDMETHODIMP SODispatchInterceptor::removeStatusListener( IDispatch FAR* /*xControl*/, IDispatch FAR* /*aURL*/) 216 { 217 // not implemented 218 return S_OK; 219 } 220 221 STDMETHODIMP SODispatchInterceptor::getInterceptedURLs( SAFEARRAY FAR* FAR* pVal ) 222 { 223 *pVal = SafeArrayCreateVector( VT_BSTR, 0, 3 ); 224 225 if( !*pVal ) 226 return E_FAIL; 227 228 long ix = 0; 229 CComBSTR aPattern( OLESTR( "ftp://*" ) ); 230 SafeArrayPutElement( *pVal, &ix, aPattern ); 231 232 ix = 1; 233 aPattern = CComBSTR( OLESTR( "http://*" ) ); 234 SafeArrayPutElement( *pVal, &ix, aPattern ); 235 236 ix = 2; 237 aPattern = CComBSTR( OLESTR( "file://*" ) ); 238 SafeArrayPutElement( *pVal, &ix, aPattern ); 239 240 return S_OK; 241 } 242 243 244