LibreOffice Module extensions (master) 1
SODispatchInterceptor.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20// SODispatchInterceptor.cpp : Implementation of CHelpApp and DLL registration.
21
22#include <sal/config.h>
23
24#include <cstddef>
25
26#include <stdio.h>
27#include "StdAfx2.h"
28#include <so_activex.h>
29#include "SOActiveX.h"
31#include "com_uno_helper.h"
32#include <sal/macros.h>
33
34COM_DECLSPEC_NOTHROW STDMETHODIMP SODispatchInterceptor::InterfaceSupportsErrorInfo(REFIID riid)
35{
36 static const IID* arr[] =
37 {
38 &IID_ISODispatchInterceptor,
39 };
40
41 for (auto const &i : arr)
42 {
43 if (InlineIsEqualGUID(*i,riid))
44 return S_OK;
45 }
46 return S_FALSE;
47}
48
49STDMETHODIMP SODispatchInterceptor::queryDispatch(IDispatch* aURL, BSTR aTargetFrameName,
50 long nSearchFlags, IDispatch** retVal)
51{
52 if ( !aURL || !retVal ) return E_FAIL;
53
54 CComVariant aTargetUrl;
55 OLECHAR const * sURLMemberName = L"Complete";
56 DISPID nURLID;
57 HRESULT hr = aURL->GetIDsOfNames( IID_NULL, const_cast<OLECHAR **>(&sURLMemberName), 1, LOCALE_USER_DEFAULT, &nURLID );
58 if( !SUCCEEDED( hr ) ) return hr;
59
60 hr = CComDispatchDriver::GetProperty( aURL, nURLID, &aTargetUrl );
61 if( !SUCCEEDED( hr ) ) return hr;
62
63 if( aTargetUrl.vt != VT_BSTR ) return E_FAIL;
64
65 if (!wcsncmp(aTargetUrl.bstrVal, L".uno:OpenHyperlink", 18))
66 {
67 CComQIPtr< IDispatch, &IID_IDispatch > pIDisp( this );
68 if( pIDisp )
69 {
70 this->AddRef();
71 *retVal = pIDisp;
72 }
73 }
74 else
75 {
76 if( !m_xSlave )
77 {
78 *retVal = nullptr;
79 return S_OK;
80 }
81
82 CComVariant aResult;
83 CComVariant aArgs[3];
84 aArgs[0] = CComVariant( nSearchFlags );
85 aArgs[1] = CComVariant( aTargetFrameName );
86 aArgs[2] = CComVariant( aURL );
87
88 hr = ExecuteFunc( m_xSlave, L"queryDispatch", aArgs, 3, &aResult );
89 if( !SUCCEEDED( hr ) || aResult.vt != VT_DISPATCH || aResult.pdispVal == nullptr )
90 {
91 *retVal = nullptr;
92 return S_OK;
93 }
94
95 *retVal = aResult.pdispVal;
96
97 CComQIPtr< IUnknown, &IID_IUnknown > pIUnk( *retVal );
98 if( pIUnk )
99 (*retVal)->AddRef();
100 }
101
102 return S_OK;
103}
104
105STDMETHODIMP SODispatchInterceptor::queryDispatches(SAFEARRAY* aDescripts, SAFEARRAY** retVal)
106{
107 if ( !aDescripts || !retVal || SafeArrayGetDim( aDescripts ) != 1 )
108 return E_FAIL;
109
110 LONG nLB, nUB;
111
112 HRESULT hr = SafeArrayGetLBound( aDescripts, 1, &nLB );
113 if( !SUCCEEDED( hr ) ) return hr;
114
115 hr = SafeArrayGetUBound( aDescripts, 1, &nUB );
116 if( !SUCCEEDED( hr ) ) return hr;
117 if( nUB < nLB ) return E_FAIL;
118
119 *retVal = SafeArrayCreateVector( VT_DISPATCH, 0, nUB - nLB );
120
121 for ( LONG ind = nLB; ind <= nUB; ind ++ )
122 {
123 CComPtr<IDispatch> pElem;
124 SafeArrayGetElement( aDescripts, &ind, pElem );
125 if( pElem )
126 {
127 OLECHAR const * pMemberNames[3] = { L"FeatureURL", L"FrameName", L"SearchFlags" };
128 CComVariant pValues[3];
129 hr = GetPropertiesFromIDisp( pElem, pMemberNames, pValues, 3 );
130 if( !SUCCEEDED( hr ) ) return hr;
131 if( pValues[0].vt != VT_DISPATCH || pValues[0].pdispVal == nullptr
132 || pValues[1].vt != VT_BSTR || pValues[2].vt != VT_I4 )
133 return E_FAIL;
134
135 CComPtr<IDispatch> aRes;
136 hr = queryDispatch( pValues[0].pdispVal, pValues[1].bstrVal, pValues[2].lVal, &aRes );
137 SafeArrayPutElement( *retVal, &ind, aRes );
138 }
139 }
140
141 return S_OK;
142}
143
144
145STDMETHODIMP SODispatchInterceptor::dispatch(IDispatch* aURL, SAFEARRAY* aArgs)
146{
147 // get url from aURL
148 OLECHAR const * pUrlName = L"Complete";
149 CComVariant pValue;
150 HRESULT hr = GetPropertiesFromIDisp( aURL, &pUrlName, &pValue, 1 );
151 if( !SUCCEEDED( hr ) ) return hr;
152 if( pValue.vt != VT_BSTR || pValue.bstrVal == nullptr )
153 return E_FAIL;
154
155 if (!wcsncmp(pValue.bstrVal, L".uno:OpenHyperlink", 18))
156 {
157 LONG nLB = 0, nUB = 0;
158 // long nDim = SafeArrayGetDim( aArgs );
159
160 hr = SafeArrayGetLBound( aArgs, 1, &nLB );
161 if( !SUCCEEDED( hr ) ) return hr;
162
163 hr = SafeArrayGetUBound( aArgs, 1, &nUB );
164 if( !SUCCEEDED( hr ) ) return hr;
165 if( nUB < nLB ) return E_FAIL;
166
167 for ( LONG ind = nLB; ind <= nUB; ind ++ )
168 {
169 CComVariant pVarElem;
170 SafeArrayGetElement( aArgs, &ind, &pVarElem );
171 if( pVarElem.vt == VT_DISPATCH && pVarElem.pdispVal != nullptr )
172 {
173 OLECHAR const * pMemberNames[2] = { L"Name", L"Value" };
174 CComVariant pValues[2];
175 hr = GetPropertiesFromIDisp( pVarElem.pdispVal, pMemberNames, pValues, 2 );
176 if( !SUCCEEDED( hr ) ) return hr;
177
178 if( pValues[0].vt == VT_BSTR && pValues[1].vt == VT_BSTR )
179 {
180 if (!wcsncmp(pValues[0].bstrVal, L"URL", 3))
181 {
182 EnterCriticalSection( &mMutex );
183 if( m_xParentControl )
184 {
185 // call GetUrl to the browser instance
186 m_xParentControl->GetURL( pValues[1].bstrVal, L"_self" );
187 }
188 LeaveCriticalSection( &mMutex );
189
190 break;
191 }
192 }
193 }
194 }
195 }
196
197 return S_OK;
198}
199
200STDMETHODIMP SODispatchInterceptor::addStatusListener(IDispatch* /*xControl*/, IDispatch* /*aURL*/)
201{
202 // not implemented
203 return S_OK;
204}
205
206STDMETHODIMP SODispatchInterceptor::removeStatusListener(IDispatch* /*xControl*/,
207 IDispatch* /*aURL*/)
208{
209 // not implemented
210 return S_OK;
211}
212
213STDMETHODIMP SODispatchInterceptor::getInterceptedURLs(SAFEARRAY** pVal)
214{
215 *pVal = SafeArrayCreateVector( VT_BSTR, 0, 3 );
216
217 if( !*pVal )
218 return E_FAIL;
219
220 LONG ix = 0;
221 CComBSTR aPattern( OLESTR( "ftp://*" ) );
222 SafeArrayPutElement( *pVal, &ix, aPattern );
223
224 ix = 1;
225 aPattern = CComBSTR( OLESTR( "http://*" ) );
226 SafeArrayPutElement( *pVal, &ix, aPattern );
227
228 ix = 2;
229 aPattern = CComBSTR( OLESTR( "file://*" ) );
230 SafeArrayPutElement( *pVal, &ix, aPattern );
231
232 return S_OK;
233}
234
235
236/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const PropertyValue * pValues
HRESULT GetURL(const OLECHAR *url, const OLECHAR *target)
Definition: SOActiveX.cxx:1137
virtual HRESULT STDMETHODCALLTYPE dispatch(IDispatch __RPC_FAR *aURL, SAFEARRAY __RPC_FAR *aArgs) override
virtual HRESULT STDMETHODCALLTYPE removeStatusListener(IDispatch __RPC_FAR *xControl, IDispatch __RPC_FAR *aURL) override
virtual HRESULT STDMETHODCALLTYPE addStatusListener(IDispatch __RPC_FAR *xControl, IDispatch __RPC_FAR *aURL) override
STDMETHOD() InterfaceSupportsErrorInfo(REFIID riid) override
virtual HRESULT STDMETHODCALLTYPE getInterceptedURLs(SAFEARRAY __RPC_FAR *__RPC_FAR *pVal) override
CComPtr< IDispatch > m_xSlave
virtual HRESULT STDMETHODCALLTYPE queryDispatch(IDispatch __RPC_FAR *aURL, BSTR aTargetFrameName, long nSearchFlags, IDispatch __RPC_FAR *__RPC_FAR *retVal) override
virtual HRESULT STDMETHODCALLTYPE queryDispatches(SAFEARRAY __RPC_FAR *aDescripts, SAFEARRAY __RPC_FAR *__RPC_FAR *retVal) override
HRESULT ExecuteFunc(IDispatch *idispUnoObject, OLECHAR const *sFuncName, CComVariant *params, unsigned int count, CComVariant *pResult)
Definition: SOActiveX.cxx:49
HRESULT GetPropertiesFromIDisp(IDispatch *pdispObject, OLECHAR const **sMemberNames, CComVariant *pVariant, unsigned int count)
Definition: SOActiveX.cxx:116
URL aURL
int i
arr
#define VT_BSTR
#define VT_I4
LONG
return hr
Definition: so_activex.cxx:446