summaryrefslogtreecommitdiffstats
path: root/extensions/source/activex
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
commited5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch)
tree7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /extensions/source/activex
parentInitial commit. (diff)
downloadlibreoffice-upstream/4%7.4.7.tar.xz
libreoffice-upstream/4%7.4.7.zip
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--extensions/source/activex/README.txt33
-rw-r--r--extensions/source/activex/SOActionsApproval.cxx58
-rw-r--r--extensions/source/activex/SOActionsApproval.h105
-rw-r--r--extensions/source/activex/SOActionsApproval.rgs24
-rw-r--r--extensions/source/activex/SOActiveX.cxx1162
-rw-r--r--extensions/source/activex/SOActiveX.h212
-rw-r--r--extensions/source/activex/SOActiveX.rgs33
-rw-r--r--extensions/source/activex/SOComWindowPeer.cxx57
-rw-r--r--extensions/source/activex/SOComWindowPeer.h159
-rw-r--r--extensions/source/activex/SOComWindowPeer.rgs23
-rw-r--r--extensions/source/activex/SODispatchInterceptor.cxx248
-rw-r--r--extensions/source/activex/SODispatchInterceptor.h175
-rw-r--r--extensions/source/activex/SODispatchInterceptor.rgs23
-rw-r--r--extensions/source/activex/StdAfx2.cxx30
-rw-r--r--extensions/source/activex/StdAfx2.h68
-rw-r--r--extensions/source/activex/com_uno_helper.h44
-rw-r--r--extensions/source/activex/example.html43
-rw-r--r--extensions/source/activex/resource.h46
-rw-r--r--extensions/source/activex/so_activex.cxx774
-rw-r--r--extensions/source/activex/so_activex.def13
-rw-r--r--extensions/source/activex/so_activex.idl230
-rw-r--r--extensions/source/activex/so_activex.rc124
22 files changed, 3684 insertions, 0 deletions
diff --git a/extensions/source/activex/README.txt b/extensions/source/activex/README.txt
new file mode 100644
index 000000000..50c209150
--- /dev/null
+++ b/extensions/source/activex/README.txt
@@ -0,0 +1,33 @@
+Description.
+
+The StarOffice ActiveX control shows an example of access to UNO through COM technology.
+It requires a properly installed StarOffice version 6.0/6.1 or OpenOffice 1.0.
+This is a Lite ActiveX control so it can be used only in containers that
+allows to use such controls.
+
+Pressing to any link to staroffice document should activate the control.
+So the document will be opened in ReadOnly mode.
+
+Also it can be activated with an <OBJECT> tag from a html-page.
+Without any parameters for an object tag a new writer document will be
+opened for editing. Possible parameters are
+ src - full URL to the file that should be edited/viewed;
+ it can contain "private:factory/..." URLs to open new documents
+ for edit, for example "private:factory/swriter"
+ readonly - the default value is "true", in case it is set to any other
+ value the document is opened for editing
+
+As any ActiveX control this one should be registered.
+To let MSIE register it itself the "CODEBASE" parameter
+for the "OBJECT" tag should be specified
+with a URL to the library "so_activex.dll".
+The example of registration with "OBJECT" tag is in example.html.
+
+Also it can be done using regsvr32 application.
+To do it please write
+<Path to Windows installation>\System32\regsvr32 so_activex.dll
+
+To unregister the control please use /u option:
+<Path to Windows installation>\system32\regsvr32 so_activex.dll /u
+
+
diff --git a/extensions/source/activex/SOActionsApproval.cxx b/extensions/source/activex/SOActionsApproval.cxx
new file mode 100644
index 000000000..a40921662
--- /dev/null
+++ b/extensions/source/activex/SOActionsApproval.cxx
@@ -0,0 +1,58 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+// SOActionsApproval.cpp : Implementation of CHelpApp and DLL registration.
+
+#include <sal/config.h>
+
+#include <cstddef>
+
+#include "StdAfx2.h"
+
+#include "SOActionsApproval.h"
+#include <sal/macros.h>
+
+#if defined __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
+#endif
+#include <so_activex.h>
+#if defined __clang__
+#pragma clang diagnostic pop
+#endif
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP SOActionsApproval::InterfaceSupportsErrorInfo(REFIID riid)
+{
+ static const IID* arr[] = {
+ &IID_ISOActionsApproval,
+ };
+
+ for (std::size_t i = 0; i < SAL_N_ELEMENTS(arr); i++)
+ {
+#ifdef _MSC_VER
+ if (InlineIsEqualGUID(*arr[i], riid))
+#else
+ if (::ATL::InlineIsEqualGUID(*arr[i], riid))
+#endif
+ return S_OK;
+ }
+ return S_FALSE;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/activex/SOActionsApproval.h b/extensions/source/activex/SOActionsApproval.h
new file mode 100644
index 000000000..2484e7462
--- /dev/null
+++ b/extensions/source/activex/SOActionsApproval.h
@@ -0,0 +1,105 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+// SOActionsApproval.h: Definition of the SOActionsApproval class
+
+#pragma once
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#include "resource.h"
+#include <ExDispID.h>
+#include <ExDisp.h>
+#include <shlguid.h>
+
+#include <atlctl.h>
+
+#if defined __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
+#endif
+#include <so_activex.h>
+#if defined __clang__
+#pragma clang diagnostic pop
+#endif
+
+// SOActionsApproval
+
+class SOActionsApproval :
+ public IDispatchImpl<ISOActionsApproval, &IID_ISOActionsApproval, &LIBID_SO_ACTIVEXLib>,
+ public ISupportErrorInfo,
+ public CComObjectRoot,
+ public CComCoClass<SOActionsApproval,&CLSID_SOActionsApproval>
+{
+public:
+ SOActionsApproval() {}
+ virtual ~SOActionsApproval() {}
+
+BEGIN_COM_MAP(SOActionsApproval)
+ COM_INTERFACE_ENTRY(IDispatch)
+ COM_INTERFACE_ENTRY(ISOActionsApproval)
+ COM_INTERFACE_ENTRY(ISupportErrorInfo)
+#if defined __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Winconsistent-missing-override"
+#endif
+END_COM_MAP()
+#if defined __clang__
+#pragma clang diagnostic pop
+#endif
+DECLARE_NOT_AGGREGATABLE(SOActionsApproval)
+// Remove the comment from the line above if you don't want your object to
+// support aggregation.
+
+DECLARE_REGISTRY_RESOURCEID(IDR_SODOCUMENTEVENTLISTENER)
+
+// ISupportsErrorInfo
+ STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid) override;
+
+// ISOActionsApproval
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE approveAction(
+ /* [in] */ long nActionID,
+ /* [retval][out] */ boolean *pbApproval) override
+ {
+ // only PreventClose is approved
+ USES_CONVERSION;
+ *pbApproval = ( nActionID == 1 );
+
+ return S_OK;
+ }
+
+ virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_Bridge_implementedInterfaces(
+ /* [retval][out] */ SAFEARRAY __RPC_FAR * __RPC_FAR *pVal) override
+ {
+ *pVal = SafeArrayCreateVector( VT_BSTR, 0, 1 );
+
+ if( !*pVal )
+ return E_FAIL;
+
+ LONG ix = 0;
+ CComBSTR aInterface( OLESTR( "com.sun.star.embed.XActionsApproval" ) );
+ SafeArrayPutElement( *pVal, &ix, aInterface );
+
+ return S_OK;
+ }
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/activex/SOActionsApproval.rgs b/extensions/source/activex/SOActionsApproval.rgs
new file mode 100644
index 000000000..543320813
--- /dev/null
+++ b/extensions/source/activex/SOActionsApproval.rgs
@@ -0,0 +1,24 @@
+HKCR
+{
+9F3697AC-7A18-4335-AF0A-65FAC2C35CC1
+ so_activex.SOActionsApproval.1 = s 'SOActionsApproval Class'
+ {
+ CLSID = s '{9F3697AC-7A18-4335-AF0A-65FAC2C35CC1}'
+ }
+ so_activex.SOActionsApproval = s 'SOActionsApproval Class'
+ {
+ CLSID = s '{9F3697AC-7A18-4335-AF0A-65FAC2C35CC1}'
+ }
+ NoRemove CLSID
+ {
+ ForceRemove {9F3697AC-7A18-4335-AF0A-65FAC2C35CC1} = s 'SOActionsApproval Class'
+ {
+ ProgID = s 'so_activex.SOActionsApproval.1'
+ VersionIndependentProgID = s 'so_activex.SOActionsApproval'
+ InprocServer32 = s '%MODULE%'
+ {
+ val ThreadingModel = s 'both'
+ }
+ }
+ }
+}
diff --git a/extensions/source/activex/SOActiveX.cxx b/extensions/source/activex/SOActiveX.cxx
new file mode 100644
index 000000000..88b3ad769
--- /dev/null
+++ b/extensions/source/activex/SOActiveX.cxx
@@ -0,0 +1,1162 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+// SOActiveX.cpp : Implementation of CSOActiveX
+
+#include "StdAfx2.h"
+#include "SOActiveX.h"
+#include "SOComWindowPeer.h"
+#include "SODispatchInterceptor.h"
+#include "SOActionsApproval.h"
+#include "com_uno_helper.h"
+
+#if defined __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
+#endif
+#include <so_activex.h>
+#if defined __clang__
+#pragma clang diagnostic pop
+#endif
+
+#define STAROFFICE_WINDOWCLASS L"SOParentWindow"
+
+
+static void OutputError_Impl( HWND hw, HRESULT ErrorCode )
+{
+ LPWSTR sMessage = nullptr;
+ FormatMessageW(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ nullptr,
+ ErrorCode,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+ reinterpret_cast<LPWSTR>(&sMessage),
+ 0,
+ nullptr
+ );
+ MessageBoxW( hw, sMessage, nullptr, MB_OK | MB_ICONINFORMATION );
+ HeapFree( GetProcessHeap(), 0, sMessage );
+}
+
+HRESULT ExecuteFunc( IDispatch* idispUnoObject,
+ OLECHAR const * sFuncName,
+ CComVariant* params,
+ unsigned int count,
+ CComVariant* pResult )
+{
+ if( !idispUnoObject )
+ return E_FAIL;
+
+ DISPID id;
+ HRESULT hr = idispUnoObject->GetIDsOfNames( IID_NULL, const_cast<OLECHAR **>(&sFuncName), 1, LOCALE_USER_DEFAULT, &id);
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ DISPPARAMS dispparams= { params, nullptr, count, 0};
+
+ // DEBUG
+ EXCEPINFO myInfo;
+ hr = idispUnoObject->Invoke( id, IID_NULL,LOCALE_USER_DEFAULT, DISPATCH_METHOD,
+ &dispparams, pResult, &myInfo, nullptr);
+
+ // for debugging purposes
+ // USES_CONVERSION;
+ // if ( !SUCCEEDED( hr ) )
+ // ::MessageBox( NULL, OLE2A( myInfo.bstrDescription ), OLE2A( myInfo.bstrSource ), MB_OK | MB_ICONINFORMATION );
+
+ return hr;
+}
+
+static HRESULT GetIDispByFunc( IDispatch* idispUnoObject,
+ OLECHAR const * sFuncName,
+ CComVariant* params,
+ unsigned int count,
+ CComPtr<IDispatch>& pdispResult )
+{
+ if( !idispUnoObject )
+ return E_FAIL;
+
+ CComVariant result;
+ HRESULT hr = ExecuteFunc( idispUnoObject, sFuncName, params, count, &result );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ if( result.vt != VT_DISPATCH || result.pdispVal == nullptr )
+ return E_FAIL;
+
+ pdispResult = CComPtr<IDispatch>( result.pdispVal );
+
+ return S_OK;
+}
+
+static HRESULT PutPropertiesToIDisp( IDispatch* pdispObject,
+ OLECHAR const ** sMemberNames,
+ CComVariant* pVariant,
+ unsigned int count )
+{
+ for( unsigned int ind = 0; ind < count; ind++ )
+ {
+ DISPID id;
+ HRESULT hr = pdispObject->GetIDsOfNames( IID_NULL, const_cast<OLECHAR **>(&sMemberNames[ind]), 1, LOCALE_USER_DEFAULT, &id );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ hr = CComDispatchDriver::PutProperty( pdispObject, id, &pVariant[ind] );
+ if( !SUCCEEDED( hr ) ) return hr;
+ }
+
+ return S_OK;
+}
+
+HRESULT GetPropertiesFromIDisp( IDispatch* pdispObject,
+ OLECHAR const ** sMemberNames,
+ CComVariant* pVariant,
+ unsigned int count )
+{
+ for( unsigned int ind = 0; ind < count; ind++ )
+ {
+ DISPID id;
+ HRESULT hr = pdispObject->GetIDsOfNames( IID_NULL, const_cast<OLECHAR **>(&sMemberNames[ind]), 1, LOCALE_USER_DEFAULT, &id );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ hr = CComDispatchDriver::GetProperty( pdispObject, id, &pVariant[ind] );
+ if( !SUCCEEDED( hr ) ) return hr;
+ }
+
+ return S_OK;
+}
+
+// CSOActiveX
+
+CSOActiveX::CSOActiveX()
+: mCookie(0)
+, mCurFileUrl( L"private:factory/swriter" )
+, mbLoad( FALSE )
+, mbViewOnly( TRUE )
+, mParentWin( nullptr )
+, mOffWin( nullptr )
+, mpDispatchInterceptor( nullptr )
+, mnVersion( SO_NOT_DETECTED )
+, mbReadyForActivation( FALSE )
+, mbDrawLocked( false )
+{
+ CLSID const clsFactory = {0x82154420,0x0FBF,0x11d4,{0x83, 0x13,0x00,0x50,0x04,0x52,0x6A,0xB4}};
+ HRESULT hr = CoCreateInstance( clsFactory, nullptr, CLSCTX_ALL, __uuidof(IDispatch), reinterpret_cast<void**>(&mpDispFactory));
+ if( !SUCCEEDED( hr ) )
+ OutputError_Impl( nullptr, hr );
+
+ mPWinClass.style = CS_HREDRAW|CS_VREDRAW;
+ mPWinClass.lpfnWndProc = DefWindowProcW;
+ mPWinClass.cbClsExtra = 0;
+ mPWinClass.cbWndExtra = 0;
+ mPWinClass.hInstance = GetModuleHandleW(nullptr); //myInstance;
+ mPWinClass.hIcon = nullptr;
+ mPWinClass.hCursor = nullptr;
+ mPWinClass.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_BACKGROUND);
+ mPWinClass.lpszMenuName = nullptr;
+ mPWinClass.lpszClassName = STAROFFICE_WINDOWCLASS;
+
+ RegisterClassW(&mPWinClass);
+}
+
+CSOActiveX::~CSOActiveX()
+{
+ Cleanup();
+
+}
+
+HRESULT CSOActiveX::Cleanup()
+{
+ CComVariant dummyResult;
+
+ if( mpDispatchInterceptor )
+ {
+ if( mpDispFrame )
+ {
+ // remove dispatch interceptor
+ CComQIPtr< IDispatch, &IID_IDispatch > pIDispDispInter( mpDispatchInterceptor );
+ CComVariant aVariant( pIDispDispInter );
+ ExecuteFunc( mpDispFrame,
+ L"releaseDispatchProviderInterceptor",
+ &aVariant,
+ 1,
+ &dummyResult );
+ }
+
+ mpDispatchInterceptor->ClearParent();
+ mpDispatchInterceptor->Release();
+ mpDispatchInterceptor = nullptr;
+ }
+
+ mpDispTempFile = CComPtr< IDispatch >();
+ mbReadyForActivation = FALSE;
+
+ if( mpInstanceLocker )
+ {
+ ExecuteFunc( mpInstanceLocker, L"dispose", nullptr, 0, &dummyResult );
+ mpInstanceLocker = CComPtr< IDispatch >();
+ }
+
+ if( mpDispFrame )
+ {
+ bool bCloserActivated = false;
+
+ CComPtr<IDispatch> pDispDocumentCloser;
+ CComVariant aDocCloser( L"com.sun.star.embed.DocumentCloser" );
+ HRESULT hr = GetIDispByFunc( mpDispFactory,
+ L"createInstance",
+ &aDocCloser,
+ 1,
+ pDispDocumentCloser );
+ if ( SUCCEEDED( hr ) && pDispDocumentCloser )
+ {
+ SAFEARRAY* pInitFrame = SafeArrayCreateVector(VT_VARIANT, 0, 1);
+ LONG nInitInd = 0;
+ CComVariant pFrameVariant( mpDispFrame );
+ SafeArrayPutElement( pInitFrame, &nInitInd, &pFrameVariant );
+ CComVariant aVarInitFrame;
+ aVarInitFrame.vt = VT_ARRAY | VT_VARIANT; aVarInitFrame.parray = pInitFrame;
+ hr = ExecuteFunc( pDispDocumentCloser, L"initialize", &aVarInitFrame, 1, &dummyResult );
+ if( SUCCEEDED( hr ) )
+ {
+ // the following call will let the closing happen
+ hr = ExecuteFunc( pDispDocumentCloser, L"dispose", nullptr, 0, &dummyResult );
+ bCloserActivated = SUCCEEDED( hr );
+ }
+ }
+
+ if ( !bCloserActivated )
+ {
+ CComVariant aPropVar;
+ aPropVar.vt = VT_BOOL; aPropVar.boolVal = VARIANT_TRUE;
+ if ( !SUCCEEDED( ExecuteFunc( mpDispFrame, L"close", &aPropVar, 1, &dummyResult ) ) )
+ ExecuteFunc( mpDispFrame, L"dispose", nullptr, 0, &dummyResult );
+ }
+
+ mpDispFrame = CComPtr< IDispatch >();
+ }
+
+ if( ::IsWindow( mOffWin ) )
+ ::DestroyWindow( mOffWin );
+
+ TerminateOffice();
+
+ return S_OK;
+}
+
+HRESULT CSOActiveX::TerminateOffice()
+{
+ // create desktop
+ CComPtr<IDispatch> pdispDesktop;
+ CComVariant aDesktopServiceName( L"com.sun.star.frame.Desktop" );
+
+ HRESULT hr = GetIDispByFunc( mpDispFactory, L"createInstance", &aDesktopServiceName, 1, pdispDesktop );
+ if( !pdispDesktop || !SUCCEEDED( hr ) ) return hr;
+
+ // create tree of frames
+ CComPtr<IDispatch> pdispChildren;
+ hr = GetIDispByFunc( pdispDesktop, L"getFrames", nullptr, 0, pdispChildren );
+ if( !pdispChildren || !SUCCEEDED( hr ) ) return hr;
+
+ CComVariant aFrames;
+ CComVariant nFlag( 4 );
+ hr = ExecuteFunc( pdispChildren, L"queryFrames", &nFlag, 1, &aFrames );
+ if ( SUCCEEDED( hr ) )
+ {
+ if ( ( aFrames.vt == ( VT_ARRAY | VT_DISPATCH ) || aFrames.vt == ( VT_ARRAY | VT_VARIANT ) )
+ && ( !aFrames.parray || (aFrames.parray->cDims == 1 && aFrames.parray->rgsabound[0].cElements == 0) ) )
+ {
+ // there is no frames open
+ // TODO: check whether the frames are hidden if they are open?
+ CComVariant dummyResult;
+ hr = ExecuteFunc( pdispDesktop, L"terminate", nullptr, 0, &dummyResult );
+ }
+ }
+
+ return hr;
+}
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CSOActiveX::InitNew ()
+{
+ mnVersion = GetVersionConnected();
+ mbLoad = TRUE;
+ return S_OK;
+}
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CSOActiveX::Load ( LPSTREAM /*pStm*/ )
+{
+ mnVersion = GetVersionConnected();
+ mbLoad = TRUE;
+
+ // may be later?
+ // for now just ignore
+
+ return S_OK;
+}
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CSOActiveX::Load( LPPROPERTYBAG pPropBag, LPERRORLOG /*pErrorLog*/ )
+{
+ mnVersion = GetVersionConnected();
+
+ IPropertyBag2* pPropBag2;
+ HRESULT hr = pPropBag->QueryInterface( IID_IPropertyBag2, reinterpret_cast<void**>(&pPropBag2) );
+ //ATLASSERT( hr >= 0 );
+
+ if( !SUCCEEDED( hr ) )
+ return hr;
+
+ unsigned long aNum;
+ hr = pPropBag2->CountProperties( &aNum );
+ //ATLASSERT( hr >= 0 );
+ if( !SUCCEEDED( hr ) )
+ return hr;
+
+ PROPBAG2* aPropNames = new PROPBAG2[aNum];
+ unsigned long aReaded;
+
+ hr = pPropBag2->GetPropertyInfo( 0,
+ aNum,
+ aPropNames,
+ &aReaded );
+ //ATLASSERT( hr >= 0 );
+ if( !SUCCEEDED( hr ) )
+ {
+ delete[] aPropNames;
+ return hr;
+ }
+
+ CComVariant* aVal = new CComVariant[aNum];
+ HRESULT* hvs = new HRESULT[aNum];
+ hr = pPropBag2->Read( aNum,
+ aPropNames,
+ nullptr,
+ aVal,
+ hvs );
+ //ATLASSERT( hr >= 0 );
+ if( !SUCCEEDED( hr ) )
+ {
+ delete[] hvs;
+ delete[] aVal;
+ delete[] aPropNames;
+ return hr;
+ }
+
+ for( unsigned long ind = 0; ind < aNum; ind++ )
+ {
+ // all information from the 'object' tag is in strings
+ if (aVal[ind].vt == VT_BSTR && !wcscmp(aPropNames[ind].pstrName, L"src"))
+ {
+ mCurFileUrl.AssignBSTR(aVal[ind].bstrVal);
+ }
+ else if( aVal[ind].vt == VT_BSTR
+ && !wcscmp(aPropNames[ind].pstrName, L"readonly"))
+ {
+ if (!wcscmp(aVal[ind].bstrVal, L"true"))
+ {
+ // the default value
+ mbViewOnly = TRUE;
+ }
+ else
+ {
+ mbViewOnly = FALSE;
+ }
+ }
+ }
+
+ delete[] hvs;
+ delete[] aVal;
+ delete[] aPropNames;
+
+ if( !mpDispFactory )
+ return hr;
+
+ mbReadyForActivation = FALSE;
+ hr = CBindStatusCallback<CSOActiveX>::Download(
+ this, &CSOActiveX::CallbackCreateXInputStream, mCurFileUrl, m_spClientSite, FALSE);
+ if (hr == MK_S_ASYNCHRONOUS)
+ hr = S_OK;
+
+ if ( !SUCCEEDED( hr ) )
+ {
+ // trigger initialization without stream
+ mbLoad = TRUE;
+
+ Invalidate();
+ UpdateWindow();
+ }
+
+ return hr;
+}
+
+HRESULT CSOActiveX::GetUnoStruct( OLECHAR const * sStructName, CComPtr<IDispatch>& pdispResult )
+{
+ CComVariant aComStruct( sStructName );
+ return GetIDispByFunc( mpDispFactory, L"Bridge_GetStruct", &aComStruct, 1, pdispResult );
+}
+
+HRESULT CSOActiveX::GetUrlStruct( OLECHAR const * sUrl, CComPtr<IDispatch>& pdispUrl )
+{
+ HRESULT hr = GetUnoStruct( L"com.sun.star.util.URL", pdispUrl );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ OLECHAR const * sURLMemberName = L"Complete";
+ DISPID nURLID;
+ hr = pdispUrl->GetIDsOfNames( IID_NULL, const_cast<OLECHAR **>(&sURLMemberName), 1, LOCALE_USER_DEFAULT, &nURLID );
+ if( !SUCCEEDED( hr ) ) return hr;
+ CComVariant aComUrl( sUrl );
+ hr = CComDispatchDriver::PutProperty( pdispUrl, nURLID, &aComUrl );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ CComPtr<IDispatch> pdispTransformer;
+ CComVariant aServiceName( L"com.sun.star.util.URLTransformer" );
+ hr = GetIDispByFunc( mpDispFactory,
+ L"createInstance",
+ &aServiceName,
+ 1,
+ pdispTransformer );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ CComVariant dummyResult;
+ CComVariant aParam[2];
+ aParam[1].ppdispVal = &pdispUrl;
+ aParam[1].vt = VT_DISPATCH | VT_BYREF;
+ aParam[0] = CComVariant( L"file:///" );
+
+ hr = ExecuteFunc( pdispTransformer, L"parseSmart", aParam, 2, &dummyResult );
+ if( !SUCCEEDED( hr ) || dummyResult.vt != VT_BOOL || !dummyResult.boolVal ) return hr;
+
+ return S_OK;
+}
+
+HRESULT CSOActiveX::SetLayoutManagerProps()
+{
+ if ( !mpDispFrame )
+ return E_FAIL;
+
+ CComVariant pVarLayoutMgr;
+ OLECHAR const * sLMPropName = L"LayoutManager";
+ HRESULT hr = GetPropertiesFromIDisp( mpDispFrame, &sLMPropName, &pVarLayoutMgr, 1 );
+ if( pVarLayoutMgr.vt != VT_DISPATCH || pVarLayoutMgr.pdispVal == nullptr )
+ return E_FAIL;
+
+ CComPtr<IDispatch> pdispLM( pVarLayoutMgr.pdispVal );
+
+
+ if( !SUCCEEDED( hr ) || !pdispLM )
+ return E_FAIL;
+
+ OLECHAR const * sATName = L"AutomaticToolbars";
+ CComVariant pATProp;
+ pATProp.vt = VT_BOOL; pATProp.boolVal = VARIANT_FALSE ;
+ hr = PutPropertiesToIDisp( pdispLM, &sATName, &pATProp, 1 );
+
+ return hr;
+}
+
+HRESULT CSOActiveX::CreateFrameOldWay( HWND hwnd, int width, int height )
+{
+ if( !mpDispFactory )
+ return E_FAIL;
+
+ // create window handle holder
+ CComPtr< CComObject< SOComWindowPeer > > pPeerToSend = new CComObject<SOComWindowPeer>();
+ pPeerToSend->SetHWNDInternally( hwnd );
+ CComQIPtr< IDispatch, &IID_IDispatch > pIDispToSend( pPeerToSend );
+
+ // create rectangle structure
+ CComPtr<IDispatch> pdispRectangle;
+ HRESULT hr = GetUnoStruct( L"com.sun.star.awt.Rectangle", pdispRectangle );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ OLECHAR const * sRectMemberNames[4] = { L"X",
+ L"Y",
+ L"Width",
+ L"Height" };
+ CComVariant pRectVariant[4];
+ pRectVariant[0] = pRectVariant[1] = pRectVariant[2] = pRectVariant[3] = CComVariant( 0 );
+
+ hr = PutPropertiesToIDisp( pdispRectangle, sRectMemberNames, pRectVariant, 4 );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ // create WindowDescriptor structure
+ CComPtr<IDispatch> pdispWinDescr;
+ hr = GetUnoStruct( L"com.sun.star.awt.WindowDescriptor", pdispWinDescr );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ // fill in descriptor with info
+ OLECHAR const * sDescriptorMemberNames[6] = { L"Type",
+ L"WindowServiceName",
+ L"ParentIndex",
+ L"Parent",
+ L"Bounds",
+ L"WindowAttributes" };
+ CComVariant pDescriptorVar[6];
+ pDescriptorVar[0] = CComVariant( 0 );
+ pDescriptorVar[1] = CComVariant( L"workwindow" );
+ pDescriptorVar[2] = CComVariant( 1 );
+ pDescriptorVar[3] = CComVariant( pIDispToSend );
+ pDescriptorVar[4] = CComVariant( pdispRectangle );
+ pDescriptorVar[5] = CComVariant( 33 );
+ hr = PutPropertiesToIDisp( pdispWinDescr, sDescriptorMemberNames, pDescriptorVar, 6 );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ // create XToolkit instance
+ CComPtr<IDispatch> pdispToolkit;
+ CComVariant aServiceName( L"com.sun.star.awt.Toolkit" );
+ hr = GetIDispByFunc( mpDispFactory, L"createInstance", &aServiceName, 1, pdispToolkit );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ // create window with toolkit
+ CComVariant aWinDescr( pdispWinDescr );
+ hr = GetIDispByFunc( pdispToolkit, L"createWindow", &aWinDescr, 1, mpDispWin );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ // create frame
+ aServiceName = CComVariant( L"com.sun.star.frame.Task" );
+ hr = GetIDispByFunc( mpDispFactory, L"createInstance", &aServiceName, 1, mpDispFrame );
+ if( !SUCCEEDED( hr ) || !mpDispFrame )
+ {
+ // the interface com.sun.star.frame.Task is removed in 6.1
+ // but the interface com.sun.star.frame.Frame has some bugs in 6.0
+ aServiceName = CComVariant( L"com.sun.star.frame.Frame" );
+ hr = GetIDispByFunc( mpDispFactory, L"createInstance", &aServiceName, 1, mpDispFrame );
+ if( !SUCCEEDED( hr ) ) return hr;
+ }
+
+ // initialize frame
+ CComVariant dummyResult;
+ CComVariant aDispWin( mpDispWin );
+ hr = ExecuteFunc( mpDispFrame, L"initialize", &aDispWin, 1, &dummyResult );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ // set some properties to the layout manager, ignore errors for now
+ SetLayoutManagerProps();
+
+ // create desktop
+ CComPtr<IDispatch> pdispDesktop;
+ aServiceName = CComVariant( L"com.sun.star.frame.Desktop" );
+ hr = GetIDispByFunc( mpDispFactory, L"createInstance", &aServiceName, 1, pdispDesktop );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ // create tree of frames
+ CComPtr<IDispatch> pdispChildren;
+ hr = GetIDispByFunc( pdispDesktop, L"getFrames", nullptr, 0, pdispChildren );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ // insert new frame into desktop hierarchy
+ CComVariant aDispFrame( mpDispFrame );
+ hr = ExecuteFunc( pdispChildren, L"append", &aDispFrame, 1, &dummyResult );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ // initialize window
+ CComVariant aTransparent( long(0xFFFFFFFF) );
+ hr = ExecuteFunc( mpDispWin, L"setBackground", &aTransparent, 1, &dummyResult );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ CComVariant aTrue( TRUE );
+ hr = ExecuteFunc( mpDispWin, L"setVisible", &aTrue, 1, &dummyResult );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ CComVariant aPosArgs[5];
+ aPosArgs[4] = CComVariant( 0 );
+ aPosArgs[3] = CComVariant( 0 );
+ aPosArgs[2] = CComVariant( width );
+ aPosArgs[1] = CComVariant( height );
+ aPosArgs[0] = CComVariant( 12 );
+ hr = ExecuteFunc( mpDispWin, L"setPosSize", aPosArgs, 5, &dummyResult );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ // create frame locker if there is such service
+ aServiceName = CComVariant( L"com.sun.star.embed.InstanceLocker" );
+ hr = GetIDispByFunc( mpDispFactory, L"createInstance", &aServiceName, 1, mpInstanceLocker );
+ if( SUCCEEDED( hr ) && mpInstanceLocker )
+ {
+ SAFEARRAY* pInitVals = SafeArrayCreateVector(VT_VARIANT, 0, 3);
+
+ // the first sequence element
+ LONG nInitInd = 0;
+ CComVariant pFrameVariant( mpDispFrame );
+ SafeArrayPutElement( pInitVals, &nInitInd, &pFrameVariant );
+
+ // the second sequence element
+ nInitInd = 1;
+ CComVariant pStrArr( 1 );
+ SafeArrayPutElement( pInitVals, &nInitInd, &pStrArr );
+
+ // the third sequence element
+ nInitInd = 2;
+ CComPtr<IDispatch> pdispValueObj;
+ hr = GetIDispByFunc( mpDispFactory, L"Bridge_GetValueObject", nullptr, 0, pdispValueObj );
+ if( !SUCCEEDED( hr ) || !pdispValueObj ) return hr;
+
+ CComVariant aValueArgs[2];
+ aValueArgs[1] = CComVariant( L"com.sun.star.embed.XActionsApproval" );
+ CComPtr< CComObject< SOActionsApproval > > pApproval( new CComObject<SOActionsApproval>() );
+ aValueArgs[0] = CComVariant ( pApproval );
+
+ hr = ExecuteFunc( pdispValueObj, L"Set", aValueArgs, 2, &dummyResult );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ CComVariant aValueObj( pdispValueObj );
+ SafeArrayPutElement( pInitVals, &nInitInd, &aValueObj );
+
+ // execute initialize()
+ CComVariant aVarInitVals;
+ aVarInitVals.vt = VT_ARRAY | VT_VARIANT; aVarInitVals.parray = pInitVals;
+ hr = ExecuteFunc( mpInstanceLocker, L"initialize", &aVarInitVals, 1, &dummyResult );
+ if( !SUCCEEDED( hr ) ) return hr;
+ }
+
+ return S_OK;
+}
+
+HRESULT CSOActiveX::CallLoadComponentFromURL1PBool( OLECHAR const * sUrl, OLECHAR const * sArgName, BOOL sArgVal )
+{
+ SAFEARRAY* pPropVals = SafeArrayCreateVector(VT_DISPATCH, 0, 1);
+ LONG ix = 0;
+ CComPtr<IDispatch> pdispPropVal;
+ HRESULT hr = GetUnoStruct( L"com.sun.star.beans.PropertyValue", pdispPropVal );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ OLECHAR const * sPropMemberNames[2] = { L"Name", L"Value" };
+ CComVariant pPropVar[2];
+ pPropVar[0] = CComVariant( sArgName );
+ pPropVar[1].vt = VT_BOOL; pPropVar[1].boolVal = sArgVal ? VARIANT_TRUE : VARIANT_FALSE ;
+ hr = PutPropertiesToIDisp( pdispPropVal, sPropMemberNames, pPropVar, 2 );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ SafeArrayPutElement( pPropVals, &ix, pdispPropVal );
+
+ CComVariant aDispArgs[4];
+ aDispArgs[3] = CComVariant( sUrl );
+ aDispArgs[2] = CComVariant( L"_self" );
+ aDispArgs[1] = CComVariant( 0 );
+ // aDispArgs[0] = CComVariant( pPropVals ); such constructor is not defined ??!
+ aDispArgs[0].vt = VT_ARRAY | VT_DISPATCH; aDispArgs[0].parray = pPropVals;
+
+ CComVariant dummyResult;
+ hr = ExecuteFunc( mpDispFrame, L"loadComponentFromURL", aDispArgs, 4, &dummyResult );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ return S_OK;
+}
+
+HRESULT CSOActiveX::CallDispatchMethod( OLECHAR const * sUrl,
+ CComVariant* aArgNames,
+ CComVariant* aArgVals,
+ unsigned int count )
+{
+ CComPtr<IDispatch> pdispURL;
+ HRESULT hr = GetUrlStruct( sUrl, pdispURL );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ CComPtr<IDispatch> pdispXDispatch;
+ CComVariant aArgs[3];
+ aArgs[2] = CComVariant( pdispURL );
+ aArgs[1] = CComVariant( L"" );
+ aArgs[0] = CComVariant( int(0) );
+ hr = GetIDispByFunc( mpDispFrame,
+ L"queryDispatch",
+ aArgs,
+ 3,
+ pdispXDispatch );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ SAFEARRAY* pPropVals = SafeArrayCreateVector(VT_DISPATCH, 0, count);
+ for( LONG ix = 0; ix < static_cast<LONG>(count); ix ++ )
+ {
+ CComPtr<IDispatch> pdispPropVal;
+ hr = GetUnoStruct( L"com.sun.star.beans.PropertyValue", pdispPropVal );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ OLECHAR const * sPropMemberNames[2] = { L"Name", L"Value" };
+ CComVariant pPropVar[2];
+ pPropVar[0] = aArgNames[ix];
+ pPropVar[1] = aArgVals[ix];
+ hr = PutPropertiesToIDisp( pdispPropVal, sPropMemberNames, pPropVar, 2 );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ SafeArrayPutElement( pPropVals, &ix, pdispPropVal );
+ }
+
+ CComVariant aDispArgs[2];
+ aDispArgs[1] = CComVariant( pdispURL );
+ // aDispArgs[0] = CComVariant( pPropVals ); such constructor is not defined ??!
+ aDispArgs[0].vt = VT_ARRAY | VT_DISPATCH; aDispArgs[0].parray = pPropVals;
+
+ CComVariant dummyResult;
+ hr = ExecuteFunc( pdispXDispatch, L"dispatch", aDispArgs, 2, &dummyResult );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ return S_OK;
+}
+
+void CSOActiveX::CallbackCreateXInputStream( CBindStatusCallback<CSOActiveX>* /*pbsc*/, BYTE* pBytes, DWORD dwSize )
+{
+ if ( mbReadyForActivation )
+ return;
+
+ bool bSuccess = false;
+ bool bFinishDownload = false;
+ if ( !pBytes )
+ {
+ // means the download is finished, dwSize contains hresult
+ bFinishDownload = true;
+ if ( SUCCEEDED( dwSize ) )
+ bSuccess = true;
+ }
+ else
+ {
+ HRESULT hr = S_OK;
+
+ if ( !mpDispTempFile )
+ {
+ CComVariant aServiceName( L"com.sun.star.io.TempFile" );
+ hr = GetIDispByFunc( mpDispFactory,
+ L"createInstance",
+ &aServiceName,
+ 1,
+ mpDispTempFile );
+ }
+
+ if( SUCCEEDED( hr ) && mpDispTempFile )
+ {
+ SAFEARRAY* pDataArray = SafeArrayCreateVector(VT_I1, 0, dwSize);
+
+ if ( pDataArray )
+ {
+ hr = SafeArrayLock( pDataArray );
+ if ( SUCCEEDED( hr ) )
+ {
+ for( DWORD ix = 0; ix < dwSize; ix++ )
+ static_cast<BYTE*>(pDataArray->pvData)[ix] = pBytes[ix];
+ hr = SafeArrayUnlock( pDataArray );
+ if ( SUCCEEDED( hr ) )
+ {
+ CComVariant aArgs[1];
+ aArgs[0].vt = VT_ARRAY | VT_I1; aArgs[0].parray = pDataArray;
+ CComVariant dummyResult;
+ hr = ExecuteFunc( mpDispTempFile, L"writeBytes", aArgs, 1, &dummyResult );
+ if( SUCCEEDED( hr ) )
+ bSuccess = true;
+ }
+ }
+ }
+ }
+ }
+
+ if ( !bSuccess )
+ {
+ // the download failed, let StarOffice download
+ bFinishDownload = true;
+ mpDispTempFile = CComPtr< IDispatch >();
+ }
+
+ if ( bFinishDownload )
+ {
+ // trigger the loading now
+ mbLoad = TRUE;
+ mbReadyForActivation = TRUE;
+
+ Invalidate();
+ UpdateWindow();
+ }
+}
+
+HRESULT CSOActiveX::LoadURLToFrame( )
+{
+ CComVariant aArgNames[4] = { L"ReadOnly", L"ViewOnly", L"AsTemplate", L"InputStream" };
+ CComVariant aArgVals[4];
+ unsigned int nCount = 3; // the 4-th argument is used only if the stream can be retrieved
+
+ aArgVals[0].vt = VT_BOOL; aArgVals[0].boolVal = mbViewOnly ? VARIANT_TRUE : VARIANT_FALSE;
+ aArgVals[1].vt = VT_BOOL; aArgVals[1].boolVal = mbViewOnly ? VARIANT_TRUE : VARIANT_FALSE;
+ aArgVals[2].vt = VT_BOOL; aArgVals[2].boolVal = VARIANT_FALSE;
+
+ if ( mpDispTempFile )
+ {
+ aArgVals[3] = CComVariant( mpDispTempFile );
+ nCount = 4;
+ }
+
+ HRESULT hr = CallDispatchMethod( mCurFileUrl, aArgNames, aArgVals, nCount );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ // try to get the model and set the presentation specific property, the setting will fail for other document formats
+ CComPtr<IDispatch> pdispController;
+ hr = GetIDispByFunc( mpDispFrame, L"getController", nullptr, 0, pdispController );
+ if ( SUCCEEDED( hr ) && pdispController )
+ {
+ CComPtr<IDispatch> pdispModel;
+ hr = GetIDispByFunc( pdispController, L"getModel", nullptr, 0, pdispModel );
+ if ( SUCCEEDED( hr ) && pdispModel )
+ {
+ CComPtr<IDispatch> pdispPres;
+ hr = GetIDispByFunc( pdispModel, L"getPresentation", nullptr, 0, pdispPres );
+ if ( SUCCEEDED( hr ) && pdispPres )
+ {
+ // this is a presentation
+ // let the slide show be shown in the document window
+ OLECHAR const * pPropName = L"IsFullScreen";
+ CComVariant pPresProp;
+ pPresProp.vt = VT_BOOL; pPresProp.boolVal = VARIANT_FALSE ;
+ hr = PutPropertiesToIDisp( pdispPres, &pPropName, &pPresProp, 1 );
+
+ // start the slide show
+ if ( SUCCEEDED( hr ) )
+ {
+ CComVariant dummyResult;
+ ExecuteFunc( pdispPres, L"Start", nullptr, 0, &dummyResult );
+ }
+ }
+ }
+ }
+
+ // create dispatch interceptor
+ mpDispatchInterceptor = new CComObject< SODispatchInterceptor >();
+ mpDispatchInterceptor->AddRef();
+ mpDispatchInterceptor->SetParent( this );
+ CComQIPtr< IDispatch, &IID_IDispatch > pIDispDispInter( mpDispatchInterceptor );
+
+ // register dispatch interceptor in the frame
+ CComVariant aDispVariant( pIDispDispInter );
+ CComVariant dummyResult;
+ hr = ExecuteFunc( mpDispFrame,
+ L"registerDispatchProviderInterceptor",
+ &aDispVariant,
+ 1,
+ &dummyResult );
+
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ return S_OK;
+}
+
+SOVersion CSOActiveX::GetVersionConnected()
+{
+ SOVersion bResult = SO_NOT_DETECTED;
+ if( mpDispFactory )
+ {
+ // create ConfigurationProvider instance
+ CComPtr<IDispatch> pdispConfProv;
+ CComVariant aServiceName( L"com.sun.star.configuration.ConfigurationProvider" );
+ HRESULT hr = GetIDispByFunc( mpDispFactory,
+ L"createInstance",
+ &aServiceName,
+ 1,
+ pdispConfProv );
+
+ if( SUCCEEDED( hr ) && pdispConfProv )
+ {
+ CComPtr<IDispatch> pdispConfAccess;
+
+ SAFEARRAY* pInitParams = SafeArrayCreateVector( VT_VARIANT, 0, 1 );
+
+ if( pInitParams )
+ {
+ LONG ix = 0;
+ CComVariant aConfPath( L"org.openoffice.Setup" );
+ SafeArrayPutElement( pInitParams, &ix, &aConfPath );
+
+ CComVariant aArgs[2];
+ aArgs[1] = CComVariant( L"com.sun.star.configuration.ConfigurationAccess" );
+ aArgs[0].vt = VT_ARRAY | VT_VARIANT; aArgs[0].parray = pInitParams;
+
+ hr = GetIDispByFunc( pdispConfProv,
+ L"createInstanceWithArguments",
+ aArgs,
+ 2,
+ pdispConfAccess );
+
+ if( SUCCEEDED( hr ) && pdispConfAccess )
+ {
+ CComVariant aOfficeName;
+
+ CComVariant aProductName( L"Product/ooName" );
+ hr = ExecuteFunc( pdispConfAccess,
+ L"getByHierarchicalName",
+ &aProductName,
+ 1,
+ &aOfficeName );
+
+ if( SUCCEEDED( hr ) && aOfficeName.vt == VT_BSTR )
+ {
+ CComVariant aOfficeVersion;
+
+ CComVariant aProductVersion( L"Product/ooSetupVersion" );
+ hr = ExecuteFunc( pdispConfAccess,
+ L"getByHierarchicalName",
+ &aProductVersion,
+ 1,
+ &aOfficeVersion );
+
+ if( SUCCEEDED( hr ) && aOfficeVersion.vt == VT_BSTR )
+ {
+ if (!wcscmp(aOfficeName.bstrVal, L"StarOffice"))
+ {
+ if (!wcsncmp(aOfficeVersion.bstrVal, L"6.1", 3))
+ bResult = SO_61;
+ else if (!wcsncmp(aOfficeVersion.bstrVal, L"6.0", 3))
+ bResult = SO_60;
+ else if (!wcsncmp(aOfficeVersion.bstrVal, L"5.2", 3))
+ bResult = SO_52;
+ else
+ bResult = SO_UNKNOWN;
+ }
+ else // OpenOffice
+ {
+ if (!wcsncmp(aOfficeVersion.bstrVal, L"1.1", 3))
+ bResult = OO_11;
+ else if (!wcsncmp(aOfficeVersion.bstrVal, L"1.0", 3))
+ bResult = OO_10;
+ else
+ bResult = OO_UNKNOWN;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return bResult;
+}
+
+namespace {
+
+class LockingGuard
+{
+ bool& mbLocked;
+public:
+ explicit LockingGuard( bool& bLocked )
+ : mbLocked( bLocked )
+ {
+ mbLocked = true;
+ }
+
+ ~LockingGuard()
+ {
+ mbLocked = false;
+ }
+};
+
+}
+
+HRESULT CSOActiveX::OnDrawAdvanced( ATL_DRAWINFO& di )
+{
+ // This method is called only in main thread, no need to lock it
+
+ // Get read of reentrance problems
+ if ( mbDrawLocked )
+ return S_OK;
+ LockingGuard aGuard( mbDrawLocked );
+
+ if( m_spInPlaceSite && mCurFileUrl && mbReadyForActivation )
+ {
+ HWND hwnd;
+ HRESULT hr = m_spInPlaceSite->GetWindow( &hwnd );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ if( mParentWin != hwnd || !mOffWin )
+ {
+ if( mpDispFrame )
+ {
+ CComVariant dummyResult;
+ CComVariant aPropVar;
+ aPropVar.vt = VT_BOOL; aPropVar.boolVal = VARIANT_FALSE;
+ (void) ExecuteFunc( mpDispFrame, L"close", &aPropVar, 1, &dummyResult );
+ mpDispFrame = CComPtr<IDispatch>();
+ }
+
+ mParentWin = hwnd;
+ mOffWin = CreateWindowW(
+ STAROFFICE_WINDOWCLASS,
+ L"OfficeContainer",
+ WS_CHILD | WS_CLIPCHILDREN | WS_BORDER,
+ di.prcBounds->left,
+ di.prcBounds->top,
+ di.prcBounds->right - di.prcBounds->left,
+ di.prcBounds->bottom - di.prcBounds->top,
+ mParentWin,
+ nullptr,
+ nullptr,
+ nullptr );
+
+ ::ShowWindow( mOffWin, SW_SHOW );
+ }
+ else
+ {
+ RECT aRect;
+ ::GetWindowRect( mOffWin, &aRect );
+
+ if( aRect.left != di.prcBounds->left || aRect.top != di.prcBounds->top
+ || aRect.right != di.prcBounds->right || aRect.bottom != di.prcBounds->bottom )
+ {
+ // on this state the office window should exist already
+ ::SetWindowPos( mOffWin,
+ HWND_TOP,
+ di.prcBounds->left,
+ di.prcBounds->top,
+ di.prcBounds->right - di.prcBounds->left,
+ di.prcBounds->bottom - di.prcBounds->top,
+ SWP_NOZORDER );
+
+ CComVariant aPosArgs[5];
+ aPosArgs[4] = CComVariant( 0 );
+ aPosArgs[3] = CComVariant( 0 );
+ aPosArgs[2] = CComVariant( int(di.prcBounds->right - di.prcBounds->left) );
+ aPosArgs[1] = CComVariant( int(di.prcBounds->bottom - di.prcBounds->top) );
+ aPosArgs[0] = CComVariant( 12 );
+ CComVariant dummyResult;
+ hr = ExecuteFunc( mpDispWin, L"setPosSize", aPosArgs, 5, &dummyResult );
+ if( !SUCCEEDED( hr ) ) return hr;
+ }
+ }
+
+ if (mnVersion == SO_NOT_DETECTED)
+ {
+ OutputError_Impl( mOffWin, CS_E_INVALID_VERSION );
+ return E_FAIL;
+ }
+
+ if( ! mpDispFrame )
+ {
+ hr = CreateFrameOldWay( mOffWin,
+ di.prcBounds->right - di.prcBounds->left,
+ di.prcBounds->bottom - di.prcBounds->top );
+
+ if( !SUCCEEDED( hr ) )
+ {
+ // if the frame can not be opened do not try any more
+ mbReadyForActivation = FALSE;
+ OutputError_Impl( mOffWin, STG_E_ABNORMALAPIEXIT );
+ return hr;
+ }
+ }
+
+ if( mbLoad )
+ {
+ hr = LoadURLToFrame();
+ mbLoad = FALSE;
+
+ if( !SUCCEEDED( hr ) )
+ {
+ // if the document can not be opened do not try any more
+ mbReadyForActivation = FALSE;
+
+ OutputError_Impl( mOffWin, STG_E_ABNORMALAPIEXIT );
+
+ return hr;
+ }
+ }
+ }
+ else
+ {
+ // activate the fallback
+ CComControl<CSOActiveX>::OnDrawAdvanced( di );
+ }
+
+ return S_OK;
+}
+
+HRESULT CSOActiveX::OnDraw( ATL_DRAWINFO& di )
+{
+ // fallback that is activated by the parent class
+ if ( di.hdcDraw )
+ FillRect( di.hdcDraw, reinterpret_cast<RECT const *>(di.prcBounds), reinterpret_cast<HBRUSH>(COLOR_BACKGROUND) );
+
+ return S_OK;
+}
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CSOActiveX::SetClientSite( IOleClientSite* aClientSite )
+{
+ HRESULT hr = IOleObjectImpl<CSOActiveX>::SetClientSite( aClientSite );
+
+ if( !aClientSite )
+ {
+ //ATLASSERT( mWebBrowser2 );
+ if( mWebBrowser2 )
+ AtlUnadvise( mWebBrowser2, DIID_DWebBrowserEvents2, mCookie );
+ return hr;
+ }
+
+ CComPtr<IOleContainer> aContainer;
+ m_spClientSite->GetContainer( &aContainer );
+// ATLASSERT( aContainer );
+
+ if( SUCCEEDED( hr ) && aContainer )
+ {
+ CComQIPtr<IServiceProvider, &IID_IServiceProvider> aServiceProvider( aContainer );
+ //ATLASSERT( aServiceProvider );
+
+ if( aServiceProvider )
+ {
+ aServiceProvider->QueryService( SID_SInternetExplorer,
+ IID_IWebBrowser,
+ reinterpret_cast<void**>(&mWebBrowser2) );
+// ATLASSERT( mWebBrowser2 );
+ if( mWebBrowser2 )
+ AtlAdvise( mWebBrowser2, GetUnknown(), DIID_DWebBrowserEvents2, &mCookie );
+ }
+ }
+
+ return hr;
+}
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CSOActiveX::Invoke(DISPID dispidMember,
+ REFIID riid,
+ LCID lcid,
+ WORD wFlags,
+ DISPPARAMS* pDispParams,
+ VARIANT* pvarResult,
+ EXCEPINFO* pExcepInfo,
+ UINT* puArgErr)
+{
+ if (riid != IID_NULL)
+ return DISP_E_UNKNOWNINTERFACE;
+
+ if (!pDispParams)
+ return DISP_E_PARAMNOTOPTIONAL;
+
+ if ( dispidMember == DISPID_ONQUIT )
+ Cleanup();
+
+ IDispatchImpl<ISOActiveX, &IID_ISOActiveX,
+ &LIBID_SO_ACTIVEXLib>::Invoke(
+ dispidMember, riid, lcid, wFlags, pDispParams,
+ pvarResult, pExcepInfo, puArgErr);
+
+ return S_OK;
+}
+
+HRESULT CSOActiveX::GetURL( const OLECHAR* url,
+ const OLECHAR* target )
+{
+ CComVariant aEmpty1, aEmpty2, aEmpty3;
+ CComVariant aUrl( url );
+ CComVariant aTarget;
+ if ( target )
+ aTarget = CComVariant( target );
+
+ return mWebBrowser2->Navigate2( &aUrl,
+ &aEmpty1,
+ &aTarget,
+ &aEmpty2,
+ &aEmpty3 );
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/activex/SOActiveX.h b/extensions/source/activex/SOActiveX.h
new file mode 100644
index 000000000..37d983ae9
--- /dev/null
+++ b/extensions/source/activex/SOActiveX.h
@@ -0,0 +1,212 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+// SOActiveX.h : Declaration of the CSOActiveX
+
+#pragma once
+
+#include "resource.h"
+
+#include <ExDispID.h>
+#include <ExDisp.h>
+#include <shlguid.h>
+
+#include <atlctl.h>
+
+#if defined __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
+#endif
+#include <so_activex.h>
+#if defined __clang__
+#pragma clang diagnostic pop
+#endif
+
+class SODispatchInterceptor;
+
+enum SOVersion {
+ SO_NOT_DETECTED = 0,
+ SO_52,
+ SO_60,
+ SO_61,
+ SO_UNKNOWN,
+ OO_10,
+ OO_11,
+ OO_UNKNOWN
+};
+
+
+// CSOActiveX
+class ATL_NO_VTABLE CSOActiveX :
+ public CComObjectRootEx<CComSingleThreadModel>,
+ public IDispatchImpl<ISOActiveX, &IID_ISOActiveX, &LIBID_SO_ACTIVEXLib>,
+ public CComControl<CSOActiveX>,
+ public IPersistStreamInitImpl<CSOActiveX>,
+ public IOleControlImpl<CSOActiveX>,
+ public IOleObjectImpl<CSOActiveX>,
+ public IOleInPlaceActiveObjectImpl<CSOActiveX>,
+ public IViewObjectExImpl<CSOActiveX>,
+ public IOleInPlaceObjectWindowlessImpl<CSOActiveX>,
+// public IConnectionPointContainerImpl<CSOActiveX>,
+ public CComCoClass<CSOActiveX, &CLSID_SOActiveX>,
+// public CProxy_ItryPluginEvents< CSOActiveX >,
+ public IPersistPropertyBagImpl< CSOActiveX >,
+ public IProvideClassInfo2Impl< &CLSID_SOActiveX,
+ &DIID__ISOActiveXEvents,
+ &LIBID_SO_ACTIVEXLib >,
+ public IObjectSafetyImpl< CSOActiveX,
+ INTERFACESAFE_FOR_UNTRUSTED_DATA >
+{
+protected:
+ CComPtr<IWebBrowser2> mWebBrowser2;
+ DWORD mCookie;
+
+ CComPtr<IDispatch> mpDispFactory;
+ CComPtr<IDispatch> mpDispFrame;
+ CComPtr<IDispatch> mpInstanceLocker;
+ CComPtr<IDispatch> mpDispWin;
+ CComBSTR mCurFileUrl;
+ BOOL mbLoad;
+ BOOL mbViewOnly;
+ WNDCLASSW mPWinClass;
+ HWND mParentWin;
+ HWND mOffWin;
+
+ SODispatchInterceptor* mpDispatchInterceptor;
+ SOVersion mnVersion;
+
+ BOOL mbReadyForActivation;
+ CComPtr<IDispatch> mpDispTempFile;
+
+ bool mbDrawLocked;
+
+public:
+ CSOActiveX();
+ ~CSOActiveX() override;
+
+DECLARE_REGISTRY_RESOURCEID(IDR_SOACTIVEX)
+
+DECLARE_PROTECT_FINAL_CONSTRUCT()
+
+BEGIN_COM_MAP(CSOActiveX)
+ COM_INTERFACE_ENTRY(ISOActiveX)
+ COM_INTERFACE_ENTRY(IDispatch)
+ COM_INTERFACE_ENTRY(IViewObjectEx)
+ COM_INTERFACE_ENTRY(IViewObject2)
+ COM_INTERFACE_ENTRY(IViewObject)
+ COM_INTERFACE_ENTRY(IOleInPlaceObjectWindowless)
+ COM_INTERFACE_ENTRY(IOleInPlaceObject)
+ COM_INTERFACE_ENTRY2(IOleWindow, IOleInPlaceObjectWindowless)
+ COM_INTERFACE_ENTRY(IOleInPlaceActiveObject)
+ COM_INTERFACE_ENTRY(IOleControl)
+ COM_INTERFACE_ENTRY(IOleObject)
+ COM_INTERFACE_ENTRY(IPersistStreamInit)
+ COM_INTERFACE_ENTRY2(IPersist, IPersistStreamInit)
+// COM_INTERFACE_ENTRY(IConnectionPointContainer)
+ COM_INTERFACE_ENTRY(IProvideClassInfo)
+ COM_INTERFACE_ENTRY(IProvideClassInfo2)
+ COM_INTERFACE_ENTRY(IPersistPropertyBag)
+ COM_INTERFACE_ENTRY(IObjectSafety)
+#if defined __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Winconsistent-missing-override"
+#endif
+END_COM_MAP()
+#if defined __clang__
+#pragma clang diagnostic pop
+#endif
+
+#if defined __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Winvalid-offsetof"
+ // offset of on non-standard-layout type '_PropMapClass' (aka 'CSOActiveX'),
+ // expanded from macro 'PROP_DATA_ENTRY'
+#endif
+BEGIN_PROP_MAP(CSOActiveX)
+ PROP_DATA_ENTRY("_cx", m_sizeExtent.cx, VT_UI4)
+ PROP_DATA_ENTRY("_cy", m_sizeExtent.cy, VT_UI4)
+ // Example entries
+ // PROP_ENTRY("Property Description", dispid, clsid)
+ // PROP_PAGE(CLSID_StockColorPage)
+END_PROP_MAP()
+#if defined __clang__
+#pragma clang diagnostic pop
+#endif
+
+BEGIN_CONNECTION_POINT_MAP(CSOActiveX)
+END_CONNECTION_POINT_MAP()
+
+#if defined __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Winconsistent-missing-override"
+#endif
+BEGIN_MSG_MAP(CSOActiveX)
+#if defined __clang__
+#pragma clang diagnostic pop
+#endif
+ CHAIN_MSG_MAP(CComControl<CSOActiveX>)
+ DEFAULT_REFLECTION_HANDLER()
+END_MSG_MAP()
+// Handler prototypes:
+// LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
+// LRESULT CommandHandler(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
+// LRESULT NotifyHandler(int idCtrl, LPNMHDR pnmh, BOOL& bHandled);
+
+
+
+// IViewObjectEx
+ static DECLARE_VIEW_STATUS(VIEWSTATUS_SOLIDBKGND | VIEWSTATUS_OPAQUE)
+
+// ISOActiveX
+public:
+
+ STDMETHOD(SetClientSite)( IOleClientSite* aClientSite ) override;
+ STDMETHOD(Invoke)( DISPID dispidMember,
+ REFIID riid,
+ LCID lcid,
+ WORD wFlags,
+ DISPPARAMS* pDispParams,
+ VARIANT* pvarResult,
+ EXCEPINFO* pExcepInfo,
+ UINT* puArgErr) override;
+ STDMETHOD(Load) ( LPPROPERTYBAG pPropBag, LPERRORLOG pErrorLog ) override;
+ STDMETHOD(Load) ( LPSTREAM pStm ) override;
+ STDMETHOD(InitNew) () override;
+ HRESULT OnDrawAdvanced(ATL_DRAWINFO& di) override;
+ HRESULT OnDraw(ATL_DRAWINFO& di) override;
+
+ HRESULT SetLayoutManagerProps();
+ HRESULT CreateFrameOldWay( HWND hwnd, int width, int height );
+ HRESULT GetUnoStruct( OLECHAR const * sStructName, CComPtr<IDispatch>& pdispResult );
+ HRESULT LoadURLToFrame();
+ HRESULT CallDispatchMethod( OLECHAR const * sUrl, CComVariant* sArgNames, CComVariant* sArgVal, unsigned int count );
+ HRESULT CallLoadComponentFromURL1PBool( OLECHAR const * sUrl, OLECHAR const * sArgName, BOOL sArgVal );
+ HRESULT GetUrlStruct( OLECHAR const * sUrl, CComPtr<IDispatch>& pdispUrl );
+ HRESULT Cleanup();
+ HRESULT TerminateOffice();
+ HRESULT GetURL( const OLECHAR* url,
+ const OLECHAR* target );
+
+ void CallbackCreateXInputStream( CBindStatusCallback<CSOActiveX>* pbsc, BYTE* pBytes, DWORD dwSize );
+
+
+ SOVersion GetVersionConnected();
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/activex/SOActiveX.rgs b/extensions/source/activex/SOActiveX.rgs
new file mode 100644
index 000000000..d3814df3b
--- /dev/null
+++ b/extensions/source/activex/SOActiveX.rgs
@@ -0,0 +1,33 @@
+HKCR
+{
+ so_activex.SOActiveX.1 = s 'SOActiveX Class'
+ {
+ CLSID = s '{67F2A879-82D5-4A6D-8CC5-FFB3C114B69D}'
+ }
+ so_activex.SOActiveX = s 'SOActiveX Class'
+ {
+ CLSID = s '{67F2A879-82D5-4A6D-8CC5-FFB3C114B69D}'
+ CurVer = s 'so_activex.SOActiveX.1'
+ }
+ NoRemove CLSID
+ {
+ ForceRemove {67F2A879-82D5-4A6D-8CC5-FFB3C114B69D} = s 'SOActiveX Class'
+ {
+ ProgID = s 'so_activex.SOActiveX.1'
+ VersionIndependentProgID = s 'so_activex.SOActiveX'
+ ForceRemove 'Programmable'
+ InprocServer32 = s '%MODULE%'
+ {
+ val ThreadingModel = s 'Apartment'
+ }
+ ForceRemove 'Control'
+ ForceRemove 'ToolboxBitmap32' = s '%MODULE%, 101'
+ 'MiscStatus' = s '0'
+ {
+ '1' = s '131473'
+ }
+ 'TypeLib' = s '{61FA3F13-8061-4796-B055-3697ED28CB38}'
+ 'Version' = s '1.0'
+ }
+ }
+}
diff --git a/extensions/source/activex/SOComWindowPeer.cxx b/extensions/source/activex/SOComWindowPeer.cxx
new file mode 100644
index 000000000..0a556466d
--- /dev/null
+++ b/extensions/source/activex/SOComWindowPeer.cxx
@@ -0,0 +1,57 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+// SOComWindowPeer.cpp : Implementation of CHelpApp and DLL registration.
+
+#include <sal/config.h>
+
+#include <cstddef>
+
+#include "StdAfx2.h"
+#include "SOComWindowPeer.h"
+#include <sal/macros.h>
+
+#if defined __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
+#endif
+#include <so_activex.h>
+#if defined __clang__
+#pragma clang diagnostic pop
+#endif
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP SOComWindowPeer::InterfaceSupportsErrorInfo(REFIID riid)
+{
+ static const IID* arr[] = {
+ &IID_ISOComWindowPeer,
+ };
+
+ for (std::size_t i = 0; i < SAL_N_ELEMENTS(arr); i++)
+ {
+#ifdef _MSC_VER
+ if (InlineIsEqualGUID(*arr[i], riid))
+#else
+ if (::ATL::InlineIsEqualGUID(*arr[i], riid))
+#endif
+ return S_OK;
+ }
+ return S_FALSE;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/activex/SOComWindowPeer.h b/extensions/source/activex/SOComWindowPeer.h
new file mode 100644
index 000000000..379ca767a
--- /dev/null
+++ b/extensions/source/activex/SOComWindowPeer.h
@@ -0,0 +1,159 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+// SOComWindowPeer.h: Definition of the SOComWindowPeer class
+
+#pragma once
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#include "resource.h"
+#include <ExDispID.h>
+#include <ExDisp.h>
+#include <shlguid.h>
+
+#include <atlctl.h>
+
+#if defined __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
+#endif
+#include <so_activex.h>
+#if defined __clang__
+#pragma clang diagnostic pop
+#endif
+
+// SOComWindowPeer
+
+class SOComWindowPeer :
+ public IDispatchImpl<ISOComWindowPeer, &IID_ISOComWindowPeer, &LIBID_SO_ACTIVEXLib>,
+ public ISupportErrorInfo,
+ public CComObjectRoot,
+ public CComCoClass<SOComWindowPeer,&CLSID_SOComWindowPeer>
+{
+ HWND m_hwnd;
+public:
+ SOComWindowPeer() : m_hwnd( nullptr ) {}
+ virtual ~SOComWindowPeer() { }
+
+BEGIN_COM_MAP(SOComWindowPeer)
+ COM_INTERFACE_ENTRY(IDispatch)
+ COM_INTERFACE_ENTRY(ISOComWindowPeer)
+ COM_INTERFACE_ENTRY(ISupportErrorInfo)
+#if defined __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Winconsistent-missing-override"
+#endif
+END_COM_MAP()
+#if defined __clang__
+#pragma clang diagnostic pop
+#endif
+DECLARE_NOT_AGGREGATABLE(SOComWindowPeer)
+// Remove the comment from the line above if you don't want your object to
+// support aggregation.
+
+DECLARE_REGISTRY_RESOURCEID(IDR_SOCOMWINDOWPEER)
+
+// ISupportsErrorInfo
+ STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid) override;
+
+// ISOComWindowPeer
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE getWindowHandle(
+ /* [in] */ SAFEARRAY __RPC_FAR * /*procId*/,
+ /* [in] */ short /*s*/,
+ /* [retval][out] */ long __RPC_FAR *ret) override
+ {
+ *ret = HandleToLong( m_hwnd );
+ return S_OK;
+ }
+
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE getToolkit(
+ /* [retval][out] */ IDispatch __RPC_FAR *__RPC_FAR *retVal) override
+ {
+ *retVal = nullptr;
+ return S_OK;
+ }
+
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE setPointer(
+ /* [in] */ IDispatch __RPC_FAR* /*xPointer*/) override
+ {
+ return S_OK;
+ }
+
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE setBackground(
+ /* [in] */ int /*nColor*/) override
+ {
+ return S_OK;
+ }
+
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE invalidate(
+ /* [in] */ short /*__MIDL_0015*/) override
+ {
+ return S_OK;
+ }
+
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE invalidateRect(
+ /* [in] */ IDispatch __RPC_FAR* /*aRect*/,
+ /* [in] */ short /*nFlags*/) override
+ {
+ return S_OK;
+ }
+
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE dispose( void) override
+ {
+ return S_OK;
+ }
+
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE addEventListener(
+ /* [in] */ IDispatch __RPC_FAR* /*xListener*/) override
+ {
+ return S_OK;
+ }
+
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE removeEventListener(
+ /* [in] */ IDispatch __RPC_FAR* /*xListener*/) override
+ {
+ return S_OK;
+ }
+
+ virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_Bridge_implementedInterfaces(
+ /* [retval][out] */ SAFEARRAY __RPC_FAR * __RPC_FAR *pVal) override
+ {
+ *pVal = SafeArrayCreateVector( VT_BSTR, 0, 2 );
+
+ if( !*pVal )
+ return E_FAIL;
+
+ LONG ix = 0;
+ CComBSTR aInterface( OLESTR( "com.sun.star.awt.XSystemDependentWindowPeer" ) );
+ SafeArrayPutElement( *pVal, &ix, aInterface );
+
+ ix = 1;
+ aInterface = CComBSTR( OLESTR( "com.sun.star.awt.XWindowPeer" ) );
+ SafeArrayPutElement( *pVal, &ix, aInterface );
+
+ return S_OK;
+ }
+
+ void SetHWNDInternally( HWND hwnd ) { m_hwnd = hwnd; }
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/activex/SOComWindowPeer.rgs b/extensions/source/activex/SOComWindowPeer.rgs
new file mode 100644
index 000000000..42e985a31
--- /dev/null
+++ b/extensions/source/activex/SOComWindowPeer.rgs
@@ -0,0 +1,23 @@
+HKCR
+{
+ so_activex.SOComWindowPeer.1 = s 'SOComWindowPeer Class'
+ {
+ CLSID = s '{EE51BD3E-8BB6-4FB8-B319-F65B1BE3B21D}'
+ }
+ so_activex.SOComWindowPeer = s 'SOComWindowPeer Class'
+ {
+ CLSID = s '{EE51BD3E-8BB6-4FB8-B319-F65B1BE3B21D}'
+ }
+ NoRemove CLSID
+ {
+ ForceRemove {EE51BD3E-8BB6-4FB8-B319-F65B1BE3B21D} = s 'SOComWindowPeer Class'
+ {
+ ProgID = s 'so_activex.SOComWindowPeer.1'
+ VersionIndependentProgID = s 'so_activex.SOComWindowPeer'
+ InprocServer32 = s '%MODULE%'
+ {
+ val ThreadingModel = s 'both'
+ }
+ }
+ }
+}
diff --git a/extensions/source/activex/SODispatchInterceptor.cxx b/extensions/source/activex/SODispatchInterceptor.cxx
new file mode 100644
index 000000000..f40f62635
--- /dev/null
+++ b/extensions/source/activex/SODispatchInterceptor.cxx
@@ -0,0 +1,248 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+// SODispatchInterceptor.cpp : Implementation of CHelpApp and DLL registration.
+
+#include <sal/config.h>
+
+#include <cstddef>
+
+#include <stdio.h>
+#include "StdAfx2.h"
+#include "SOActiveX.h"
+#include "SODispatchInterceptor.h"
+#include "com_uno_helper.h"
+#include <sal/macros.h>
+
+#if defined __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
+#endif
+#include <so_activex.h>
+#if defined __clang__
+#pragma clang diagnostic pop
+#endif
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP SODispatchInterceptor::InterfaceSupportsErrorInfo(REFIID riid)
+{
+ static const IID* arr[] =
+ {
+ &IID_ISODispatchInterceptor,
+ };
+
+ for (std::size_t i=0;i<SAL_N_ELEMENTS(arr);i++)
+ {
+#ifdef _MSC_VER
+ if (InlineIsEqualGUID(*arr[i],riid))
+#else
+ if (::ATL::InlineIsEqualGUID(*arr[i],riid))
+#endif
+ return S_OK;
+ }
+ return S_FALSE;
+}
+
+STDMETHODIMP SODispatchInterceptor::queryDispatch(IDispatch* aURL, BSTR aTargetFrameName,
+ long nSearchFlags, IDispatch** retVal)
+{
+ if ( !aURL || !retVal ) return E_FAIL;
+
+ CComVariant aTargetUrl;
+ OLECHAR const * sURLMemberName = L"Complete";
+ DISPID nURLID;
+ HRESULT hr = aURL->GetIDsOfNames( IID_NULL, const_cast<OLECHAR **>(&sURLMemberName), 1, LOCALE_USER_DEFAULT, &nURLID );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ hr = CComDispatchDriver::GetProperty( aURL, nURLID, &aTargetUrl );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ if( aTargetUrl.vt != VT_BSTR ) return E_FAIL;
+
+ if (!wcsncmp(aTargetUrl.bstrVal, L".uno:OpenHyperlink", 18))
+ {
+ CComQIPtr< IDispatch, &IID_IDispatch > pIDisp( this );
+ if( pIDisp )
+ {
+ this->AddRef();
+ *retVal = pIDisp;
+ }
+ }
+ else
+ {
+ if( !m_xSlave )
+ {
+ *retVal = nullptr;
+ return S_OK;
+ }
+
+ CComVariant aResult;
+ CComVariant aArgs[3];
+ aArgs[0] = CComVariant( nSearchFlags );
+ aArgs[1] = CComVariant( aTargetFrameName );
+ aArgs[2] = CComVariant( aURL );
+
+ hr = ExecuteFunc( m_xSlave, L"queryDispatch", aArgs, 3, &aResult );
+ if( !SUCCEEDED( hr ) || aResult.vt != VT_DISPATCH || aResult.pdispVal == nullptr )
+ {
+ *retVal = nullptr;
+ return S_OK;
+ }
+
+ *retVal = aResult.pdispVal;
+
+ CComQIPtr< IUnknown, &IID_IUnknown > pIUnk( *retVal );
+ if( pIUnk )
+ (*retVal)->AddRef();
+ }
+
+ return S_OK;
+}
+
+STDMETHODIMP SODispatchInterceptor::queryDispatches(SAFEARRAY* aDescripts, SAFEARRAY** retVal)
+{
+ if ( !aDescripts || !retVal || SafeArrayGetDim( aDescripts ) != 1 )
+ return E_FAIL;
+
+ LONG nLB, nUB;
+
+ HRESULT hr = SafeArrayGetLBound( aDescripts, 1, &nLB );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ hr = SafeArrayGetUBound( aDescripts, 1, &nUB );
+ if( !SUCCEEDED( hr ) ) return hr;
+ if( nUB < nLB ) return E_FAIL;
+
+ *retVal = SafeArrayCreateVector( VT_DISPATCH, 0, nUB - nLB );
+
+ for ( LONG ind = nLB; ind <= nUB; ind ++ )
+ {
+ CComPtr<IDispatch> pElem;
+ SafeArrayGetElement( aDescripts, &ind, pElem );
+ if( pElem )
+ {
+ OLECHAR const * pMemberNames[3] = { L"FeatureURL", L"FrameName", L"SearchFlags" };
+ CComVariant pValues[3];
+ hr = GetPropertiesFromIDisp( pElem, pMemberNames, pValues, 3 );
+ if( !SUCCEEDED( hr ) ) return hr;
+ if( pValues[0].vt != VT_DISPATCH || pValues[0].pdispVal == nullptr
+ || pValues[1].vt != VT_BSTR || pValues[2].vt != VT_I4 )
+ return E_FAIL;
+
+ CComPtr<IDispatch> aRes;
+ hr = queryDispatch( pValues[0].pdispVal, pValues[1].bstrVal, pValues[2].lVal, &aRes );
+ SafeArrayPutElement( *retVal, &ind, aRes );
+ }
+ }
+
+ return S_OK;
+}
+
+
+STDMETHODIMP SODispatchInterceptor::dispatch(IDispatch* aURL, SAFEARRAY* aArgs)
+{
+ // get url from aURL
+ OLECHAR const * pUrlName = L"Complete";
+ CComVariant pValue;
+ HRESULT hr = GetPropertiesFromIDisp( aURL, &pUrlName, &pValue, 1 );
+ if( !SUCCEEDED( hr ) ) return hr;
+ if( pValue.vt != VT_BSTR || pValue.bstrVal == nullptr )
+ return E_FAIL;
+
+ if (!wcsncmp(pValue.bstrVal, L".uno:OpenHyperlink", 18))
+ {
+ LONG nLB = 0, nUB = 0;
+ // long nDim = SafeArrayGetDim( aArgs );
+
+ hr = SafeArrayGetLBound( aArgs, 1, &nLB );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ hr = SafeArrayGetUBound( aArgs, 1, &nUB );
+ if( !SUCCEEDED( hr ) ) return hr;
+ if( nUB < nLB ) return E_FAIL;
+
+ for ( LONG ind = nLB; ind <= nUB; ind ++ )
+ {
+ CComVariant pVarElem;
+ SafeArrayGetElement( aArgs, &ind, &pVarElem );
+ if( pVarElem.vt == VT_DISPATCH && pVarElem.pdispVal != nullptr )
+ {
+ OLECHAR const * pMemberNames[2] = { L"Name", L"Value" };
+ CComVariant pValues[2];
+ hr = GetPropertiesFromIDisp( pVarElem.pdispVal, pMemberNames, pValues, 2 );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ if( pValues[0].vt == VT_BSTR && pValues[1].vt == VT_BSTR )
+ {
+ if (!wcsncmp(pValues[0].bstrVal, L"URL", 3))
+ {
+ EnterCriticalSection( &mMutex );
+ if( m_xParentControl )
+ {
+ // call GetUrl to the browser instance
+ m_xParentControl->GetURL( pValues[1].bstrVal, L"_self" );
+ }
+ LeaveCriticalSection( &mMutex );
+
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ return S_OK;
+}
+
+STDMETHODIMP SODispatchInterceptor::addStatusListener(IDispatch* /*xControl*/, IDispatch* /*aURL*/)
+{
+ // not implemented
+ return S_OK;
+}
+
+STDMETHODIMP SODispatchInterceptor::removeStatusListener(IDispatch* /*xControl*/,
+ IDispatch* /*aURL*/)
+{
+ // not implemented
+ return S_OK;
+}
+
+STDMETHODIMP SODispatchInterceptor::getInterceptedURLs(SAFEARRAY** pVal)
+{
+ *pVal = SafeArrayCreateVector( VT_BSTR, 0, 3 );
+
+ if( !*pVal )
+ return E_FAIL;
+
+ LONG ix = 0;
+ CComBSTR aPattern( OLESTR( "ftp://*" ) );
+ SafeArrayPutElement( *pVal, &ix, aPattern );
+
+ ix = 1;
+ aPattern = CComBSTR( OLESTR( "http://*" ) );
+ SafeArrayPutElement( *pVal, &ix, aPattern );
+
+ ix = 2;
+ aPattern = CComBSTR( OLESTR( "file://*" ) );
+ SafeArrayPutElement( *pVal, &ix, aPattern );
+
+ return S_OK;
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/activex/SODispatchInterceptor.h b/extensions/source/activex/SODispatchInterceptor.h
new file mode 100644
index 000000000..3c0604348
--- /dev/null
+++ b/extensions/source/activex/SODispatchInterceptor.h
@@ -0,0 +1,175 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+// SODispatchInterceptor.h: Definition of the SODispatchInterceptor class
+
+#pragma once
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#include "resource.h"
+#include <ExDispID.h>
+#include <ExDisp.h>
+#include <shlguid.h>
+
+#include <atlctl.h>
+
+#include <so_activex.h>
+
+class CSOActiveX;
+
+
+// SODispatchInterceptor
+
+class SODispatchInterceptor :
+ public IDispatchImpl<ISODispatchInterceptor, &IID_ISODispatchInterceptor, &LIBID_SO_ACTIVEXLib>,
+ public ISupportErrorInfo,
+ public CComObjectRoot,
+ public CComCoClass<SODispatchInterceptor,&CLSID_SODispatchInterceptor>
+{
+ CComPtr<IDispatch> m_xMaster;
+ CComPtr<IDispatch> m_xSlave;
+ CSOActiveX* m_xParentControl;
+ CRITICAL_SECTION mMutex;
+public:
+ SODispatchInterceptor() : m_xParentControl( nullptr ) { InitializeCriticalSection(&mMutex); }
+ virtual ~SODispatchInterceptor() { ATLASSERT( !m_xParentControl ); DeleteCriticalSection(&mMutex); }
+
+BEGIN_COM_MAP(SODispatchInterceptor)
+ COM_INTERFACE_ENTRY(IDispatch)
+ COM_INTERFACE_ENTRY(ISODispatchInterceptor)
+ COM_INTERFACE_ENTRY(ISupportErrorInfo)
+#if defined __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Winconsistent-missing-override"
+#endif
+END_COM_MAP()
+#if defined __clang__
+#pragma clang diagnostic pop
+#endif
+DECLARE_NOT_AGGREGATABLE(SODispatchInterceptor)
+// Remove the comment from the line above if you don't want your object to
+// support aggregation.
+
+DECLARE_REGISTRY_RESOURCEID(IDR_SODISPATCHINTERCEPTOR)
+
+ void SetParent( CSOActiveX* pParent )
+ {
+ ATLASSERT( !m_xParentControl );
+ EnterCriticalSection( &mMutex );
+ m_xParentControl = pParent;
+ LeaveCriticalSection( &mMutex );
+ }
+
+ void ClearParent()
+ {
+ EnterCriticalSection( &mMutex );
+ m_xParentControl = nullptr;
+ LeaveCriticalSection( &mMutex );
+ }
+
+// ISupportsErrorInfo
+ STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid) override;
+
+// ISODispatchInterceptor
+
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE getSlaveDispatchProvider(
+ /* [retval][out] */ IDispatch __RPC_FAR *__RPC_FAR *retVal) override
+ {
+ *retVal = m_xSlave;
+ return S_OK;
+ }
+
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE setSlaveDispatchProvider(
+ /* [in] */ IDispatch __RPC_FAR *xNewDispatchProvider) override
+ {
+ m_xSlave = xNewDispatchProvider;
+ return S_OK;
+ }
+
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE getMasterDispatchProvider(
+ /* [retval][out] */ IDispatch __RPC_FAR *__RPC_FAR *retVal) override
+ {
+ *retVal = m_xMaster;
+ return S_OK;
+ }
+
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE setMasterDispatchProvider(
+ /* [in] */ IDispatch __RPC_FAR *xNewSupplier) override
+ {
+ m_xMaster = xNewSupplier;
+ return S_OK;
+ }
+
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE queryDispatch(
+ /* [in] */ IDispatch __RPC_FAR *aURL,
+ /* [in] */ BSTR aTargetFrameName,
+ /* [in] */ long nSearchFlags,
+ /* [retval][out] */ IDispatch __RPC_FAR *__RPC_FAR *retVal) override;
+
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE queryDispatches(
+ /* [in] */ SAFEARRAY __RPC_FAR * aDescripts,
+ /* [retval][out] */ SAFEARRAY __RPC_FAR * __RPC_FAR *retVal) override;
+
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE dispatch(
+ /* [in] */ IDispatch __RPC_FAR *aURL,
+ /* [in] */ SAFEARRAY __RPC_FAR * aArgs) override;
+
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE addStatusListener(
+ /* [in] */ IDispatch __RPC_FAR *xControl,
+ /* [in] */ IDispatch __RPC_FAR *aURL) override;
+
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE removeStatusListener(
+ /* [in] */ IDispatch __RPC_FAR *xControl,
+ /* [in] */ IDispatch __RPC_FAR *aURL) override;
+
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE getInterceptedURLs(
+ /* [retval][out] */ SAFEARRAY __RPC_FAR * __RPC_FAR *pVal) override;
+
+ virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_Bridge_implementedInterfaces(
+ /* [retval][out] */ SAFEARRAY __RPC_FAR * __RPC_FAR *pVal) override
+ {
+ *pVal = SafeArrayCreateVector( VT_BSTR, 0, 4 );
+
+ if( !*pVal )
+ return E_FAIL;
+
+ LONG ix = 0;
+ CComBSTR aInterface( OLESTR( "com.sun.star.frame.XDispatchProviderInterceptor" ) );
+ SafeArrayPutElement( *pVal, &ix, aInterface );
+
+ ix = 1;
+ aInterface = CComBSTR( OLESTR( "com.sun.star.frame.XDispatchProvider" ) );
+ SafeArrayPutElement( *pVal, &ix, aInterface );
+
+ ix = 2;
+ aInterface = CComBSTR( OLESTR( "com.sun.star.frame.XDispatch" ) );
+ SafeArrayPutElement( *pVal, &ix, aInterface );
+
+ ix = 3;
+ aInterface = CComBSTR( OLESTR( "com.sun.star.frame.XInterceptorInfo" ) );
+ SafeArrayPutElement( *pVal, &ix, aInterface );
+
+ return S_OK;
+ }
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/activex/SODispatchInterceptor.rgs b/extensions/source/activex/SODispatchInterceptor.rgs
new file mode 100644
index 000000000..19fe0b5f0
--- /dev/null
+++ b/extensions/source/activex/SODispatchInterceptor.rgs
@@ -0,0 +1,23 @@
+HKCR
+{
+ so_activex.SODispatchInterceptor.1 = s 'SODispatchInterceptor Class'
+ {
+ CLSID = s '{C5D6D568-57DA-4D6C-819A-451CB565E682}'
+ }
+ so_activex.SODispatchInterceptor = s 'SODispatchInterceptor Class'
+ {
+ CLSID = s '{C5D6D568-57DA-4D6C-819A-451CB565E682}'
+ }
+ NoRemove CLSID
+ {
+ ForceRemove {C5D6D568-57DA-4D6C-819A-451CB565E682} = s 'SODispatchInterceptor Class'
+ {
+ ProgID = s 'so_activex.SODispatchInterceptor.1'
+ VersionIndependentProgID = s 'so_activex.SODispatchInterceptor'
+ InprocServer32 = s '%MODULE%'
+ {
+ val ThreadingModel = s 'both'
+ }
+ }
+ }
+}
diff --git a/extensions/source/activex/StdAfx2.cxx b/extensions/source/activex/StdAfx2.cxx
new file mode 100644
index 000000000..c2df5c5c0
--- /dev/null
+++ b/extensions/source/activex/StdAfx2.cxx
@@ -0,0 +1,30 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+// stdafx1.cpp : source file that includes just the standard includes
+// stdafx1.pch will be the pre-compiled header
+// stdafx1.obj will contain the pre-compiled type information
+
+#include "StdAfx2.h"
+
+#ifdef _ATL_STATIC_REGISTRY
+#include <statreg.h>
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/activex/StdAfx2.h b/extensions/source/activex/StdAfx2.h
new file mode 100644
index 000000000..56bd75b8a
--- /dev/null
+++ b/extensions/source/activex/StdAfx2.h
@@ -0,0 +1,68 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+// stdafx1.h : include file for standard system include files,
+// or project specific include files that are used frequently,
+// but are changed infrequently
+
+#pragma once
+
+#define STRICT
+#define _ATL_APARTMENT_THREADED
+#define _ATL_STATIC_REGISTRY
+
+#pragma warning(push)
+// local variable is initialized but not referenced - in atlctl.h
+#pragma warning(disable : 4189)
+#if defined __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wall"
+#pragma clang diagnostic ignored "-Wattributes"
+#pragma clang diagnostic ignored "-Wdelete-incomplete"
+#pragma clang diagnostic ignored "-Wdynamic-class-memaccess"
+#pragma clang diagnostic ignored "-Wint-to-pointer-cast"
+#pragma clang diagnostic ignored "-Winvalid-noreturn"
+#pragma clang diagnostic ignored "-Wmicrosoft"
+#pragma clang diagnostic ignored "-Wmissing-field-initializers"
+#pragma clang diagnostic ignored "-Wnon-pod-varargs"
+#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
+#pragma clang diagnostic ignored "-Wnonportable-include-path"
+#pragma clang diagnostic ignored "-Wsequence-point"
+#pragma clang diagnostic ignored "-Wsign-compare"
+#pragma clang diagnostic ignored "-Wtypename-missing"
+#endif
+
+#define min(a, b) (((a) < (b)) ? (a) : (b))
+#include <atlbase.h>
+
+//You may derive a class from CComModule and use it if you want to override
+//something, but do not change the name of _Module
+extern CComModule _Module;
+#include <atlcom.h>
+#include <atlctl.h>
+
+#if defined __clang__
+#pragma clang diagnostic pop
+#endif
+#pragma warning(pop)
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/activex/com_uno_helper.h b/extensions/source/activex/com_uno_helper.h
new file mode 100644
index 000000000..89aa0a7d1
--- /dev/null
+++ b/extensions/source/activex/com_uno_helper.h
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "StdAfx2.h"
+
+HRESULT ExecuteFunc( IDispatch* idispUnoObject,
+ OLECHAR const * sFuncName,
+ CComVariant* params,
+ unsigned int count,
+ CComVariant* pResult );
+
+HRESULT GetIDispByFunc( IDispatch* idispUnoObject,
+ OLECHAR* sFuncName,
+ CComVariant* params,
+ unsigned int count,
+ CComPtr<IDispatch>& pdispResult );
+
+HRESULT PutPropertiesToIDisp( IDispatch* pdispObject,
+ OLECHAR** sMemberNames,
+ CComVariant* pVariant,
+ unsigned int count );
+
+HRESULT GetPropertiesFromIDisp( IDispatch* pdispObject,
+ OLECHAR const ** sMemberNames,
+ CComVariant* pVariant,
+ unsigned int count );
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/activex/example.html b/extensions/source/activex/example.html
new file mode 100644
index 000000000..96e764c8f
--- /dev/null
+++ b/extensions/source/activex/example.html
@@ -0,0 +1,43 @@
+<!--
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+-->
+<HTML>
+<HEAD>
+<TITLE>Document Title</TITLE>
+</HEAD>
+<BODY>
+
+<center>
+First you should edit the example.html file!!!
+</center>
+<center>
+<!-- Please edit CODEBASE parameter -->
+<!-- In case ActiveX control is already registered the parameter can be removed -->
+<OBJECT CLASSID="clsid:67F2A879-82D5-4A6D-8CC5-FFB3C114B69D" width="500" height="500"
+ CODEBASE="..\..\..\WINexample.out\bin\so_activex.dll">
+<!-- Full URL to a document
+ <PARAM NAME="src" VALUE="file:///d:/example.sxw">
+-->
+<!-- Just view the document, do not edit
+ <PARAM NAME="readonly" VALUE="true">
+-->
+</OBJECT>
+
+</center>
+
+</BODY>
+</HTML>
diff --git a/extensions/source/activex/resource.h b/extensions/source/activex/resource.h
new file mode 100644
index 000000000..b7a77a5c9
--- /dev/null
+++ b/extensions/source/activex/resource.h
@@ -0,0 +1,46 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by so_activex.rc
+
+#define IDS_PROJNAME 100
+#define IDB_SOACTIVEX 101
+#define IDR_SOACTIVEX 102
+#define IDB_SOCOMWINDOWPEER 103
+#define IDR_SOCOMWINDOWPEER 104
+#define IDB_SODISPATCHINTERCEPTOR 105
+#define IDR_SODISPATCHINTERCEPTOR 106
+#define IDB_SODOCUMENTEVENTLISTENER 107
+#define IDR_SODOCUMENTEVENTLISTENER 108
+
+
+// Next default values for new objects
+
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 201
+#define _APS_NEXT_COMMAND_VALUE 32768
+#define _APS_NEXT_CONTROL_VALUE 201
+#define _APS_NEXT_SYMED_VALUE 107
+#endif
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/activex/so_activex.cxx b/extensions/source/activex/so_activex.cxx
new file mode 100644
index 000000000..70682a416
--- /dev/null
+++ b/extensions/source/activex/so_activex.cxx
@@ -0,0 +1,774 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+// so_activex.cpp : Implementation of DLL Exports.
+
+// Note: Proxy/Stub Information
+// To build a separate proxy/stub DLL,
+// run nmake -f so_activexps.mk in the project directory.
+
+#include <stdio.h>
+#include "StdAfx2.h"
+#include "resource.h"
+#include <initguid.h>
+
+#if defined __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
+#endif
+#include <so_activex.h>
+#if defined __clang__
+#pragma clang diagnostic pop
+#endif
+
+#if defined __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wextra-tokens"
+ // "#endif !_MIDL_USE_GUIDDEF_" in midl-generated code
+#endif
+#include <so_activex_i.c>
+#if defined __clang__
+#pragma clang diagnostic pop
+#endif
+
+#include "SOActiveX.h"
+
+#include <comphelper\documentconstants.hxx>
+#include <sal/types.h>
+#include <exception>
+
+CComModule _Module;
+
+BEGIN_OBJECT_MAP(ObjectMap)
+OBJECT_ENTRY(CLSID_SOActiveX, CSOActiveX)
+#if defined __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wmissing-field-initializers"
+#endif
+END_OBJECT_MAP()
+#if defined __clang__
+#pragma clang diagnostic pop
+#endif
+
+#define X64_LIB_NAME L"so_activex_x64.dll"
+#define X32_LIB_NAME L"so_activex.dll"
+
+const REGSAM n64KeyAccess = KEY_ALL_ACCESS | KEY_WOW64_64KEY;
+const REGSAM n32KeyAccess = KEY_ALL_ACCESS;
+
+#ifdef _AMD64_
+const bool bX64 = true;
+#define REG_DELETE_KEY_A( key, aPath, nKeyAccess ) RegDeleteKeyExA( key, aPath, nKeyAccess, 0 )
+#else
+const bool bX64 = false;
+#define REG_DELETE_KEY_A( key, aPath, nKeyAccess ) RegDeleteKeyA( key, aPath )
+#endif
+
+// DLL Entry Point
+
+extern "C"
+BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
+{
+ if (dwReason == DLL_PROCESS_ATTACH)
+ {
+ _Module.Init(ObjectMap, hInstance, &LIBID_SO_ACTIVEXLib);
+ DisableThreadLibraryCalls(hInstance);
+ }
+ else if (dwReason == DLL_PROCESS_DETACH)
+ _Module.Term();
+ return TRUE; // ok
+}
+
+
+// Used to determine whether the DLL can be unloaded by OLE
+
+STDAPI DllCanUnloadNow()
+{
+ return (_Module.GetLockCount()==0) ? S_OK : S_FALSE;
+}
+
+
+// Returns a class factory to create an object of the requested type
+
+STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
+{
+ return _Module.GetClassObject(rclsid, riid, ppv);
+}
+
+
+// DllRegisterServer - Adds entries to the system registry
+
+namespace
+{
+// Wraps an updatable Win32 error; keeps first incoming error.
+// Ctor defines if upd will throw std::exception on error or
+// return false.
+class Status
+{
+public:
+ explicit Status(bool bTrow)
+ : m_bThrow(bTrow)
+ {
+ }
+ // used to check success of an operation, and update the status if it's still ERROR_SUCCESS
+ bool upd(LSTATUS nNewStatus)
+ {
+ if (m_nStatus == ERROR_SUCCESS)
+ m_nStatus = nNewStatus;
+ if (m_bThrow && nNewStatus != ERROR_SUCCESS)
+ throw std::exception();
+ return nNewStatus == ERROR_SUCCESS;
+ };
+ LSTATUS get() { return m_nStatus; }
+ operator bool() { return m_nStatus == ERROR_SUCCESS; }
+
+private:
+ LSTATUS m_nStatus = ERROR_SUCCESS;
+ const bool m_bThrow;
+};
+
+class HRegKey
+{
+public:
+ ~HRegKey()
+ {
+ if (m_hkey)
+ RegCloseKey(m_hkey);
+ }
+ PHKEY operator&() { return &m_hkey; }
+ operator HKEY() { return m_hkey; }
+
+private:
+ HKEY m_hkey = nullptr;
+};
+}
+
+// for now database component and chart are always installed
+#define SUPPORTED_EXT_NUM 30
+const char* const aFileExt[] = { ".vor",
+ ".sds", ".sda", ".sdd", ".sdp", ".sdc", ".sdw", ".smf",
+ ".stw", ".stc", ".sti", ".std",
+ ".sxw", ".sxc", ".sxi", ".sxd", ".sxg", ".sxm",
+ ".ott", ".otg", ".otp", ".ots", ".otf",
+ ".odt", ".oth", ".odm", ".odg", ".odp", ".ods", ".odf"};
+const sal_Unicode* const aMimeType[] = {
+ u"application/vnd.stardivision.writer",
+
+ u"application/vnd.stardivision.chart",
+ u"application/vnd.stardivision.draw",
+ u"application/vnd.stardivision.impress",
+ u"application/vnd.stardivision.impress-packed",
+ u"application/vnd.stardivision.calc",
+ u"application/vnd.stardivision.writer",
+ u"application/vnd.stardivision.math",
+
+ MIMETYPE_VND_SUN_XML_WRITER_TEMPLATE_ASCII.getStr(),
+ MIMETYPE_VND_SUN_XML_CALC_TEMPLATE_ASCII.getStr(),
+ MIMETYPE_VND_SUN_XML_IMPRESS_TEMPLATE_ASCII.getStr(),
+ MIMETYPE_VND_SUN_XML_DRAW_TEMPLATE_ASCII.getStr(),
+
+ MIMETYPE_VND_SUN_XML_WRITER_ASCII.getStr(),
+ MIMETYPE_VND_SUN_XML_CALC_ASCII.getStr(),
+ MIMETYPE_VND_SUN_XML_IMPRESS_ASCII.getStr(),
+ MIMETYPE_VND_SUN_XML_DRAW_ASCII.getStr(),
+ MIMETYPE_VND_SUN_XML_WRITER_GLOBAL_ASCII.getStr(),
+ MIMETYPE_VND_SUN_XML_MATH_ASCII.getStr(),
+
+ MIMETYPE_OASIS_OPENDOCUMENT_TEXT_TEMPLATE_ASCII.getStr(),
+ MIMETYPE_OASIS_OPENDOCUMENT_TEXT_GLOBAL_TEMPLATE_ASCII.getStr(),
+ MIMETYPE_OASIS_OPENDOCUMENT_DRAWING_TEMPLATE_ASCII.getStr(),
+ MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_TEMPLATE_ASCII.getStr(),
+ MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_TEMPLATE_ASCII.getStr(),
+ MIMETYPE_OASIS_OPENDOCUMENT_FORMULA_TEMPLATE_ASCII.getStr(),
+
+ MIMETYPE_OASIS_OPENDOCUMENT_TEXT_ASCII.getStr(),
+ MIMETYPE_OASIS_OPENDOCUMENT_TEXT_WEB_ASCII.getStr(),
+ MIMETYPE_OASIS_OPENDOCUMENT_TEXT_GLOBAL_ASCII.getStr(),
+ MIMETYPE_OASIS_OPENDOCUMENT_DRAWING_ASCII.getStr(),
+ MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_ASCII.getStr(),
+ MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_ASCII.getStr(),
+ MIMETYPE_OASIS_OPENDOCUMENT_FORMULA_ASCII.getStr() };
+
+const int nForModes[] = { 16,
+ 1, 2, 4, 4, 8, 16, 32,
+ 16, 8, 4, 2,
+ 16, 8, 4, 2, 16, 32,
+ 16, 2, 4, 8, 32,
+ 16, 16, 16, 2, 4, 8, 32 };
+
+const char* const aClassID = "{67F2A879-82D5-4A6D-8CC5-FFB3C114B69D}";
+const char* const aTypeLib = "{61FA3F13-8061-4796-B055-3697ED28CB38}";
+
+// ISOComWindowPeer interface information
+const char* const aInterIDWinPeer = "{BF5D10F3-8A10-4A0B-B150-2B6AA2D7E118}";
+const char* const aProxyStubWinPeer = "{00020424-0000-0000-C000-000000000046}";
+
+// ISODispatchInterceptor interface information
+const char* const aInterIDDispInt = "{9337694C-B27D-4384-95A4-9D8E0EABC9E5}";
+const char* const aProxyStubDispInt = "{00020424-0000-0000-C000-000000000046}";
+
+// ISOActionsApproval interface information
+const char* const aInterIDActApprove = "{029E9F1E-2B3F-4297-9160-8197DE7ED54F}";
+const char* const aProxyStubActApprove = "{00020424-0000-0000-C000-000000000046}";
+
+// The following prefix is required for HKEY_LOCAL_MACHINE and HKEY_CURRENT_USER ( not for HKEY_CLASSES_ROOT )
+const char* const aLocalPrefix = "Software\\Classes\\";
+
+static LSTATUS createKey( HKEY hkey,
+ const char* aKeyToCreate,
+ REGSAM nKeyAccess,
+ const char* aValue = nullptr,
+ const char* aChildName = nullptr,
+ const char* aChildValue = nullptr )
+{
+ Status s(false); // no throw
+ HRegKey hkey1;
+ if (s.upd(RegCreateKeyExA(hkey, aKeyToCreate, 0, nullptr, REG_OPTION_NON_VOLATILE, nKeyAccess,
+ nullptr, &hkey1, nullptr)))
+ {
+ if (aValue)
+ s.upd(RegSetValueExA(hkey1, "", 0, REG_SZ, reinterpret_cast<const BYTE*>(aValue),
+ sal::static_int_cast<DWORD>(strlen(aValue))));
+ if (aChildName)
+ s.upd(RegSetValueExA(hkey1, aChildName, 0, REG_SZ,
+ reinterpret_cast<const BYTE*>(aChildValue),
+ sal::static_int_cast<DWORD>(strlen(aChildValue))));
+ }
+ return s.get();
+}
+
+static LSTATUS createKey(HKEY hkey,
+ const wchar_t* aKeyToCreate,
+ REGSAM nKeyAccess,
+ const wchar_t* aValue = nullptr,
+ const wchar_t* aChildName = nullptr,
+ const wchar_t* aChildValue = nullptr )
+{
+ Status s(false); // no throw
+ HRegKey hkey1;
+ if (s.upd(RegCreateKeyExW(hkey, aKeyToCreate, 0, nullptr, REG_OPTION_NON_VOLATILE, nKeyAccess,
+ nullptr, &hkey1, nullptr)))
+ {
+ if (aValue)
+ s.upd(RegSetValueExW(hkey1, L"", 0, REG_SZ, reinterpret_cast<const BYTE*>(aValue),
+ sal::static_int_cast<DWORD>(wcslen(aValue) * sizeof(wchar_t))));
+ if (aChildName)
+ s.upd(RegSetValueExW(
+ hkey1, aChildName, 0, REG_SZ, reinterpret_cast<const BYTE*>(aChildValue),
+ sal::static_int_cast<DWORD>(wcslen(aChildValue) * sizeof(wchar_t))));
+ }
+ return s.get();
+}
+
+EXTERN_C __declspec(dllexport) HRESULT STDAPICALLTYPE DllUnregisterServerNative( int nMode, BOOL bForAllUsers, BOOL bFor64Bit );
+static HRESULT DllRegisterServerNative_Impl( int nMode, bool bForAllUsers, REGSAM nKeyAccess, const wchar_t* pProgramPath, const wchar_t* pLibName )
+{
+ char aSubKey[513];
+ int ind;
+ const char* aPrefix = aLocalPrefix; // bForAllUsers ? "" : aLocalPrefix;
+
+ // In case SO7 is installed for this user he can have local registry entries that will prevent him from
+ // using SO8 ActiveX control. The fix is just to clean up the local entries related to ActiveX control.
+ // Unfortunately it can be done only for the user who installs the office.
+ if ( bForAllUsers )
+ DllUnregisterServerNative( nMode, false, false );
+
+ Status s(true); // throw
+ try
+ {
+ if (pProgramPath && wcslen(pProgramPath) < 1024)
+ {
+ wchar_t pActiveXPath[1124];
+ wchar_t pActiveXPath101[1124];
+
+ swprintf(pActiveXPath, L"%s\\%s", pProgramPath, pLibName);
+ swprintf(pActiveXPath101, L"%s\\%s, 101", pProgramPath, pLibName);
+
+ {
+ wsprintfA(aSubKey, "%sCLSID\\%s", aPrefix, aClassID);
+ HRegKey hkey;
+ s.upd(RegCreateKeyExA(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER,
+ aSubKey, 0, nullptr, REG_OPTION_NON_VOLATILE, nKeyAccess,
+ nullptr, &hkey, nullptr));
+ s.upd(RegSetValueExA(hkey, "", 0, REG_SZ,
+ reinterpret_cast<const BYTE*>("SOActiveX Class"), 17));
+ s.upd(createKey(hkey, "Control", nKeyAccess));
+ s.upd(createKey(hkey, "EnableFullPage", nKeyAccess));
+ s.upd(createKey(hkey, L"InprocServer32", nKeyAccess, pActiveXPath,
+ L"ThreadingModel", L"Apartment"));
+ s.upd(createKey(hkey, "MiscStatus", nKeyAccess, "0"));
+ s.upd(createKey(hkey, "MiscStatus\\1", nKeyAccess, "131473"));
+ s.upd(createKey(hkey, "ProgID", nKeyAccess, "so_activex.SOActiveX.1"));
+ s.upd(createKey(hkey, "Programmable", nKeyAccess));
+ s.upd(createKey(hkey, L"ToolboxBitmap32", nKeyAccess, pActiveXPath101));
+ s.upd(createKey(hkey, "TypeLib", nKeyAccess, aTypeLib));
+ s.upd(createKey(hkey, "Version", nKeyAccess, "1.0"));
+ s.upd(createKey(hkey, "VersionIndependentProgID", nKeyAccess,
+ "so_activex.SOActiveX"));
+ }
+ {
+ HRegKey hkey;
+ s.upd(RegCreateKeyExA(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER,
+ aPrefix, 0, nullptr, REG_OPTION_NON_VOLATILE, nKeyAccess,
+ nullptr, &hkey, nullptr));
+ s.upd(createKey(hkey, "so_activex.SOActiveX", nKeyAccess, "SOActiveX Class"));
+ {
+ HRegKey hkey1;
+ s.upd(RegCreateKeyExA(hkey, "so_activex.SOActiveX", 0, nullptr,
+ REG_OPTION_NON_VOLATILE, nKeyAccess, nullptr, &hkey1,
+ nullptr));
+ s.upd(createKey(hkey1, "CLSID", nKeyAccess, aClassID));
+ s.upd(createKey(hkey1, "CurVer", nKeyAccess, "so_activex.SOActiveX.1"));
+ }
+ s.upd(createKey(hkey, "so_activex.SOActiveX.1", nKeyAccess, "SOActiveX Class"));
+ {
+ HRegKey hkey1;
+ s.upd(RegCreateKeyExA(hkey, "so_activex.SOActiveX.1", 0, nullptr,
+ REG_OPTION_NON_VOLATILE, nKeyAccess, nullptr, &hkey1,
+ nullptr));
+ s.upd(createKey(hkey1, "CLSID", nKeyAccess, aClassID));
+ }
+ {
+ HRegKey hkey1;
+ s.upd(RegCreateKeyExA(hkey, "TypeLib", 0, nullptr, REG_OPTION_NON_VOLATILE,
+ nKeyAccess, nullptr, &hkey1, nullptr));
+ {
+ HRegKey hkey2;
+ s.upd(RegCreateKeyExA(hkey1, aTypeLib, 0, nullptr, REG_OPTION_NON_VOLATILE,
+ nKeyAccess, nullptr, &hkey2, nullptr));
+ s.upd(createKey(hkey2, "1.0", nKeyAccess, "wrap_activex 1.0 Type Library"));
+ {
+ HRegKey hkey3;
+ s.upd(RegCreateKeyExA(hkey2, "1.0", 0, nullptr, REG_OPTION_NON_VOLATILE,
+ nKeyAccess, nullptr, &hkey3, nullptr));
+ {
+ HRegKey hkey4;
+ s.upd(RegCreateKeyExA(hkey3, "0", 0, nullptr,
+ REG_OPTION_NON_VOLATILE, nKeyAccess, nullptr,
+ &hkey4, nullptr));
+ s.upd(createKey(hkey4, L"win32", nKeyAccess, pActiveXPath));
+ }
+ s.upd(createKey(hkey3, "FLAGS", nKeyAccess, "0"));
+ s.upd(createKey(hkey3, L"HELPDIR", nKeyAccess, pProgramPath));
+ }
+ }
+ }
+ {
+ HRegKey hkey1;
+ s.upd(RegCreateKeyExA(hkey, "Interface", 0, nullptr, REG_OPTION_NON_VOLATILE,
+ nKeyAccess, nullptr, &hkey1, nullptr));
+ s.upd(createKey(hkey1, aInterIDWinPeer, nKeyAccess, "ISOComWindowPeer"));
+ {
+ HRegKey hkey2;
+ s.upd(RegCreateKeyExA(hkey1, aInterIDWinPeer, 0, nullptr,
+ REG_OPTION_NON_VOLATILE, nKeyAccess, nullptr, &hkey2,
+ nullptr));
+ s.upd(createKey(hkey2, "ProxyStubClsid", nKeyAccess, aProxyStubWinPeer));
+ s.upd(createKey(hkey2, "ProxyStubClsid32", nKeyAccess, aProxyStubWinPeer));
+ s.upd(createKey(hkey2, "TypeLib", nKeyAccess, aTypeLib, "Version", "1.0"));
+ }
+ s.upd(createKey(hkey1, aInterIDActApprove, nKeyAccess, "ISOActionsApproval"));
+ {
+ HRegKey hkey2;
+ s.upd(RegCreateKeyExA(hkey1, aInterIDActApprove, 0, nullptr,
+ REG_OPTION_NON_VOLATILE, nKeyAccess, nullptr, &hkey2,
+ nullptr));
+ s.upd(createKey(hkey2, "ProxyStubClsid", nKeyAccess, aProxyStubActApprove));
+ s.upd(
+ createKey(hkey2, "ProxyStubClsid32", nKeyAccess, aProxyStubActApprove));
+ s.upd(createKey(hkey2, "TypeLib", nKeyAccess, aTypeLib, "Version", "1.0"));
+ }
+ s.upd(createKey(hkey1, aInterIDDispInt, nKeyAccess, "ISODispatchInterceptor"));
+ {
+ HRegKey hkey2;
+ s.upd(RegCreateKeyExA(hkey1, aInterIDDispInt, 0, nullptr,
+ REG_OPTION_NON_VOLATILE, nKeyAccess, nullptr, &hkey2,
+ nullptr));
+ s.upd(createKey(hkey2, "ProxyStubClsid", nKeyAccess, aProxyStubDispInt));
+ s.upd(createKey(hkey2, "ProxyStubClsid32", nKeyAccess, aProxyStubDispInt));
+ s.upd(createKey(hkey2, "TypeLib", nKeyAccess, aTypeLib, "Version", "1.0"));
+ }
+ }
+ }
+ }
+
+ for (ind = 0; ind < SUPPORTED_EXT_NUM; ind++)
+ {
+ if (nForModes[ind] & nMode)
+ {
+ wsprintfA(aSubKey, "%sMIME\\DataBase\\Content Type\\%ls", aPrefix, aMimeType[ind]);
+ HRegKey hkey;
+ s.upd(RegCreateKeyExA(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER,
+ aSubKey, 0, nullptr, REG_OPTION_NON_VOLATILE, nKeyAccess,
+ nullptr, &hkey, nullptr));
+ s.upd(RegSetValueExA(hkey, "CLSID", 0, REG_SZ,
+ reinterpret_cast<const BYTE*>(aClassID),
+ sal::static_int_cast<DWORD>(strlen(aClassID))));
+ }
+ }
+
+ {
+ wsprintfA(aSubKey, "%sCLSID\\%s", aPrefix, aClassID);
+ HRegKey hkey;
+ s.upd(RegOpenKeyExA(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, 0,
+ nKeyAccess, &hkey));
+ for (ind = 0; ind < SUPPORTED_EXT_NUM; ind++)
+ {
+ wsprintfA(aSubKey, "EnableFullPage\\%s", aFileExt[ind]);
+ HRegKey hkey1;
+ s.upd(RegCreateKeyExA(hkey, aSubKey, 0, nullptr, REG_OPTION_NON_VOLATILE,
+ nKeyAccess, nullptr, &hkey1, nullptr));
+ }
+ }
+ }
+ catch (const std::exception&) {}
+
+ return HRESULT_FROM_WIN32(s.get());
+}
+
+EXTERN_C __declspec(dllexport) HRESULT STDAPICALLTYPE DllRegisterServerNative( int nMode, BOOL bForAllUsers, BOOL bFor64Bit, const wchar_t* pProgramPath )
+{
+ HRESULT hr = S_OK;
+ if ( bFor64Bit )
+ hr = DllRegisterServerNative_Impl( nMode, bForAllUsers, n64KeyAccess, pProgramPath, X64_LIB_NAME );
+
+ if ( SUCCEEDED( hr ) )
+ hr = DllRegisterServerNative_Impl( nMode, bForAllUsers, n32KeyAccess, pProgramPath, X32_LIB_NAME );
+
+ return hr;
+}
+
+
+// DllUnregisterServer - Removes entries from the system registry
+static HRESULT DeleteKeyTree( HKEY hkey, const char* pPath, REGSAM nKeyAccess )
+{
+ char pSubKeyName[256];
+ // first delete the subkeys
+ while (true)
+ {
+ HRegKey hkey1;
+ if (ERROR_SUCCESS != RegOpenKeyExA(hkey, pPath, 0, nKeyAccess, &hkey1)
+ || ERROR_SUCCESS != RegEnumKeyA(hkey1, 0, pSubKeyName, 256)
+ || ERROR_SUCCESS != DeleteKeyTree(hkey1, pSubKeyName, nKeyAccess))
+ break;
+ }
+
+ // delete the key itself
+ return REG_DELETE_KEY_A( hkey, pPath, nKeyAccess & ( KEY_WOW64_64KEY | KEY_WOW64_32KEY ) );
+}
+
+static HRESULT DllUnregisterServerNative_Impl( int nMode, bool bForAllUsers, REGSAM nKeyAccess )
+{
+ char aSubKey[513];
+ const char* aPrefix = aLocalPrefix; // bForAllUsers ? "" : aLocalPrefix;
+
+ Status s(false); // no throw
+ for( int ind = 0; ind < SUPPORTED_EXT_NUM; ind++ )
+ {
+ if( nForModes[ind] & nMode )
+ {
+ DWORD nSubKeys = 0, nValues = 0;
+ wsprintfA(aSubKey, "%sMIME\\DataBase\\Content Type\\%ls", aPrefix, aMimeType[ind]);
+ Status s1(false); // no throw
+ {
+ HRegKey hkey;
+ if (s1.upd(RegCreateKeyExA(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER,
+ aSubKey, 0, nullptr, REG_OPTION_NON_VOLATILE, nKeyAccess,
+ nullptr, &hkey, nullptr)))
+ {
+ s1.upd(RegDeleteValueA(hkey, "CLSID"));
+ s1.upd(RegQueryInfoKeyA(hkey, nullptr, nullptr, nullptr, &nSubKeys, nullptr,
+ nullptr, &nValues, nullptr, nullptr, nullptr, nullptr));
+ }
+ }
+ if (s1 && !nSubKeys && !nValues)
+ DeleteKeyTree(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey,
+ nKeyAccess);
+ s.upd(s1.get());
+
+ wsprintfA(aSubKey, "%s%s", aPrefix, aFileExt[ind]);
+ Status s2(false); // no throw
+ {
+ HRegKey hkey;
+ if (s2.upd(RegCreateKeyExA(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER,
+ aSubKey, 0, nullptr, REG_OPTION_NON_VOLATILE, nKeyAccess,
+ nullptr, &hkey, nullptr)))
+ {
+ s2.upd(RegQueryInfoKeyA(hkey, nullptr, nullptr, nullptr, &nSubKeys, nullptr,
+ nullptr, &nValues, nullptr, nullptr, nullptr, nullptr));
+ }
+ }
+ if (s2 && !nSubKeys && !nValues)
+ DeleteKeyTree(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey,
+ nKeyAccess);
+ s.upd(s2.get());
+ }
+ }
+
+ wsprintfA(aSubKey, "%sCLSID\\%s", aPrefix, aClassID);
+ s.upd(DeleteKeyTree(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey,
+ nKeyAccess));
+
+ wsprintfA(aSubKey, "%sso_activex.SOActiveX", aPrefix);
+ s.upd(DeleteKeyTree(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey,
+ nKeyAccess));
+
+ wsprintfA(aSubKey, "%sso_activex.SOActiveX.1", aPrefix);
+ s.upd(DeleteKeyTree(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey,
+ nKeyAccess));
+
+ wsprintfA(aSubKey, "%s\\TypeLib\\%s", aPrefix, aTypeLib);
+ s.upd(DeleteKeyTree(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey,
+ nKeyAccess));
+
+ wsprintfA(aSubKey, "%s\\Interface\\%s", aPrefix, aInterIDWinPeer);
+ s.upd(DeleteKeyTree(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey,
+ nKeyAccess));
+
+ wsprintfA(aSubKey, "%s\\Interface\\%s", aPrefix, aInterIDDispInt);
+ s.upd(DeleteKeyTree(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey,
+ nKeyAccess));
+
+ wsprintfA(aSubKey, "%s\\Interface\\%s", aPrefix, aInterIDActApprove);
+ s.upd(DeleteKeyTree(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey,
+ nKeyAccess));
+
+ return HRESULT_FROM_WIN32(s.get());
+}
+
+STDAPI DllUnregisterServerNative( int nMode, BOOL bForAllUsers, BOOL bFor64Bit )
+{
+ HRESULT hr = DllUnregisterServerNative_Impl( nMode, bForAllUsers, n32KeyAccess );
+ if ( SUCCEEDED( hr ) && bFor64Bit )
+ hr = DllUnregisterServerNative_Impl( nMode, bForAllUsers, n64KeyAccess );
+
+ return hr;
+}
+
+
+// DllRegisterServerDoc - Adds entries to the system registry
+
+#define SUPPORTED_MSEXT_NUM 7
+const char* const aMSFileExt[] = { ".dot", ".doc", ".xlt", ".xls", ".pot", ".ppt", ".pps" };
+const char* const aMSMimeType[] = { "application/msword",
+ "application/msword",
+ "application/vnd.ms-excel",
+ "application/vnd.ms-excel",
+ "application/vnd.ms-powerpoint",
+ "application/vnd.ms-powerpoint",
+ "application/vnd.ms-powerpoint" };
+const int nForMSModes[] = { 1, 1, 2, 2, 4, 4, 4 };
+
+EXTERN_C __declspec(dllexport) HRESULT STDAPICALLTYPE DllUnregisterServerDoc( int nMode, BOOL bForAllUsers, BOOL bFor64Bit );
+static HRESULT DllRegisterServerDoc_Impl( int nMode, bool bForAllUsers, REGSAM nKeyAccess )
+{
+ char aSubKey[513];
+ int ind;
+ const char* aPrefix = aLocalPrefix; // bForAllUsers ? "" : aLocalPrefix;
+
+ // In case SO7 is installed for this user he can have local registry entries that will prevent him from
+ // using SO8 ActiveX control. The fix is just to clean up the local entries related to ActiveX control.
+ // Unfortunately it can be done only for the user who installs the office.
+ if ( bForAllUsers )
+ DllUnregisterServerDoc( nMode, false, false );
+
+ Status s(true); // throw
+ try
+ {
+ for (ind = 0; ind < SUPPORTED_MSEXT_NUM; ind++)
+ {
+ if (nForMSModes[ind] & nMode)
+ {
+ {
+ wsprintfA(aSubKey, "%sMIME\\DataBase\\Content Type\\%s", aPrefix,
+ aMSMimeType[ind]);
+ HRegKey hkey;
+ s.upd(RegCreateKeyExA(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER,
+ aSubKey, 0, nullptr, REG_OPTION_NON_VOLATILE, nKeyAccess,
+ nullptr, &hkey, nullptr));
+ s.upd(RegSetValueExA(hkey, "Extension", 0, REG_SZ,
+ reinterpret_cast<const BYTE*>(aMSFileExt[ind]),
+ sal::static_int_cast<DWORD>(strlen(aMSFileExt[ind]))));
+ s.upd(RegSetValueExA(hkey, "CLSID", 0, REG_SZ,
+ reinterpret_cast<const BYTE*>(aClassID),
+ sal::static_int_cast<DWORD>(strlen(aClassID))));
+ }
+ {
+ wsprintfA(aSubKey, "%s%s", aPrefix, aMSFileExt[ind]);
+ HRegKey hkey;
+ s.upd(RegCreateKeyExA(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER,
+ aSubKey, 0, nullptr, REG_OPTION_NON_VOLATILE, nKeyAccess,
+ nullptr, &hkey, nullptr));
+ s.upd(RegSetValueExA(hkey, "Content Type", 0, REG_SZ,
+ reinterpret_cast<const BYTE*>(aMSMimeType[ind]),
+ sal::static_int_cast<DWORD>(strlen(aMSMimeType[ind]))));
+ }
+ }
+ }
+
+ wsprintfA(aSubKey, "%sCLSID\\%s", aPrefix, aClassID);
+ HRegKey hkey;
+ s.upd(RegCreateKeyExA(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, 0,
+ nullptr, REG_OPTION_NON_VOLATILE, nKeyAccess, nullptr, &hkey,
+ nullptr));
+ s.upd(createKey(hkey, "EnableFullPage", nKeyAccess));
+ for (ind = 0; ind < SUPPORTED_MSEXT_NUM; ind++)
+ {
+ if (nForMSModes[ind] & nMode)
+ {
+ wsprintfA(aSubKey, "EnableFullPage\\%s", aMSFileExt[ind]);
+ HRegKey hkey1;
+ s.upd(RegCreateKeyExA(hkey, aSubKey, 0, nullptr, REG_OPTION_NON_VOLATILE,
+ nKeyAccess, nullptr, &hkey1, nullptr));
+ }
+ }
+ }
+ catch (const std::exception&) {}
+
+ return HRESULT_FROM_WIN32(s.get());
+}
+
+EXTERN_C __declspec(dllexport) HRESULT STDAPICALLTYPE DllRegisterServerDoc( int nMode, BOOL bForAllUsers, BOOL bFor64Bit )
+{
+ HRESULT hr = S_OK;
+ if ( bFor64Bit )
+ hr = DllRegisterServerDoc_Impl( nMode, bForAllUsers, n64KeyAccess );
+
+ if ( SUCCEEDED( hr ) )
+ hr = DllRegisterServerDoc_Impl( nMode, bForAllUsers, n32KeyAccess );
+
+ return hr;
+}
+
+
+// DllUnregisterServerDoc - Removes entries from the system registry
+
+static HRESULT DllUnregisterServerDoc_Impl( int nMode, bool bForAllUsers, REGSAM nKeyAccess )
+{
+ char aSubKey[513];
+ const char* aPrefix = aLocalPrefix; // bForAllUsers ? "" : aLocalPrefix;
+
+ Status s(false); // no throw
+ for (int ind = 0; ind < SUPPORTED_MSEXT_NUM; ind++)
+ {
+ if (nForMSModes[ind] & nMode)
+ {
+ DWORD nSubKeys = 0, nValues = 0;
+ Status s1(false); // no throw
+ {
+ wsprintfA(aSubKey, "%sMIME\\DataBase\\Content Type\\%s", aPrefix, aMSMimeType[ind]);
+ HRegKey hkey;
+ if (s1.upd(RegCreateKeyExA(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER,
+ aSubKey, 0, nullptr, REG_OPTION_NON_VOLATILE, nKeyAccess,
+ nullptr, &hkey, nullptr)))
+ {
+ s.upd(RegDeleteValueA(hkey, "Extension"));
+ s.upd(RegDeleteValueA(hkey, "CLSID"));
+ s1.upd(RegQueryInfoKeyA(hkey, nullptr, nullptr, nullptr, &nSubKeys, nullptr,
+ nullptr, &nValues, nullptr, nullptr, nullptr, nullptr));
+ }
+ }
+ if (s1 && !nSubKeys && !nValues)
+ DeleteKeyTree(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey,
+ nKeyAccess);
+ s.upd(s1.get());
+
+ Status s2(false); // no throw
+ {
+ wsprintfA(aSubKey, "%s%s", aPrefix, aMSFileExt[ind]);
+ HRegKey hkey;
+ if (s2.upd(RegCreateKeyExA(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER,
+ aSubKey, 0, nullptr, REG_OPTION_NON_VOLATILE, nKeyAccess,
+ nullptr, &hkey, nullptr)))
+ {
+ s.upd(RegDeleteValueA(hkey, "Content Type"));
+ s2.upd(RegQueryInfoKeyA(hkey, nullptr, nullptr, nullptr, &nSubKeys, nullptr,
+ nullptr, &nValues, nullptr, nullptr, nullptr, nullptr));
+ }
+ }
+ if (s2 && !nSubKeys && !nValues)
+ DeleteKeyTree(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey,
+ nKeyAccess);
+ s.upd(s2.get());
+ }
+ }
+
+ return HRESULT_FROM_WIN32(s.get());
+}
+
+STDAPI DllUnregisterServerDoc( int nMode, BOOL bForAllUsers, BOOL bFor64Bit )
+{
+ HRESULT hr = S_OK;
+ if ( bFor64Bit )
+ hr = DllUnregisterServerDoc_Impl( nMode, bForAllUsers, n64KeyAccess );
+
+ if ( SUCCEEDED( hr ) )
+ hr = DllUnregisterServerDoc_Impl( nMode, bForAllUsers, n32KeyAccess );
+
+ return hr;
+}
+
+
+// DllRegisterServer - regsvr32 entry point
+
+STDAPI DllRegisterServer()
+{
+ HRESULT aResult = E_FAIL;
+
+ HMODULE aCurModule{};
+ GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
+ | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
+ reinterpret_cast<LPCWSTR>(&DllRegisterServer), &aCurModule);
+ if( aCurModule )
+ {
+ wchar_t pProgramPath[1024];
+ wchar_t* pPathEnd = nullptr;
+ DWORD nLen = GetModuleFileNameW( aCurModule, pProgramPath, SAL_N_ELEMENTS(pProgramPath) );
+ if ( nLen && nLen < SAL_N_ELEMENTS(pProgramPath) )
+ pPathEnd = wcsrchr(pProgramPath, '\\');
+ if (pPathEnd)
+ {
+ *pPathEnd = 0;
+ aResult = DllRegisterServerNative( 31, TRUE, bX64, pProgramPath );
+ if( SUCCEEDED( aResult ) )
+ aResult = DllRegisterServerDoc( 31, TRUE, bX64 );
+ else
+ {
+ aResult = DllRegisterServerNative( 31, FALSE, bX64, pProgramPath );
+ if( SUCCEEDED( aResult ) )
+ aResult = DllRegisterServerDoc( 31, FALSE, bX64 );
+ }
+ }
+ }
+
+ return aResult;
+}
+
+
+// DllUnregisterServer - regsvr32 entry point
+
+STDAPI DllUnregisterServer()
+{
+ DllUnregisterServerDoc( 63, FALSE, bX64 );
+ DllUnregisterServerNative( 63, FALSE, bX64 );
+ DllUnregisterServerDoc( 63, TRUE, bX64 );
+ return DllUnregisterServerNative( 63, TRUE, bX64 );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/activex/so_activex.def b/extensions/source/activex/so_activex.def
new file mode 100644
index 000000000..9f81e7917
--- /dev/null
+++ b/extensions/source/activex/so_activex.def
@@ -0,0 +1,13 @@
+; iervp.def : Declares the module parameters.
+
+LIBRARY
+
+EXPORTS
+ DllCanUnloadNow PRIVATE
+ DllGetClassObject PRIVATE
+ DllRegisterServer PRIVATE
+ DllUnregisterServer PRIVATE
+ DllRegisterServerNative PRIVATE
+ DllRegisterServerDoc PRIVATE
+ DllUnregisterServerNative PRIVATE
+ DllUnregisterServerDoc PRIVATE
diff --git a/extensions/source/activex/so_activex.idl b/extensions/source/activex/so_activex.idl
new file mode 100644
index 000000000..a84dde219
--- /dev/null
+++ b/extensions/source/activex/so_activex.idl
@@ -0,0 +1,230 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+// so_activex.idl : IDL source for so_activex.dll
+
+
+// This file will be processed by the MIDL tool to
+// produce the type library (so_activex.tlb) and marshalling code.
+
+import "oaidl.idl";
+import "ocidl.idl";
+#include <olectl.h>
+
+
+ [
+ object,
+ uuid(DACF7E3F-626B-4BF9-964B-F4910C843711),
+ dual,
+ helpstring("ISOActiveX Interface"),
+ pointer_default(unique)
+ ]
+ interface ISOActiveX : IDispatch
+ {
+ };
+
+[
+ object,
+ uuid(BF5D10F3-8A10-4A0B-B150-2B6AA2D7E118),
+ dual,
+ helpstring("ISOComWindowPeer Interface"),
+ pointer_default(unique)
+]
+interface ISOComWindowPeer : IDispatch
+{
+ [id(1), helpstring("method getWindowHandle")]
+ HRESULT getWindowHandle( [in] SAFEARRAY(VARIANT) procId,
+ [in] short s,
+ [out,retval] long* ret);
+
+ [id(2), helpstring("method getToolkit")]
+ HRESULT getToolkit( [out,retval] IDispatch** retVal );
+
+ [id(3), helpstring("method setPointer")]
+ HRESULT setPointer( [in] IDispatch* xPointer );
+
+ [id(4), helpstring("method setBackground")]
+ HRESULT setBackground( [in] int nColor );
+
+ [id(5), helpstring("method invalidate")]
+ HRESULT invalidate( [in] short );
+
+ [id(6), helpstring("method invalidateRect")]
+ HRESULT invalidateRect( [in] IDispatch* aRect, [in] short nFlags );
+
+ [id(7), helpstring("method dispose")]
+ HRESULT dispose();
+
+ [id(8), helpstring("method addEventListener")]
+ HRESULT addEventListener( [in] IDispatch* xListener );
+
+ [id(9), helpstring("method removeEventListener")]
+ HRESULT removeEventListener( [in] IDispatch* xListener );
+
+ [propget, id(10), helpstring("property_implementedInterfaces")]
+ HRESULT Bridge_implementedInterfaces([out, retval] SAFEARRAY(BSTR) *pVal);
+};
+
+[
+ object,
+ uuid(9337694C-B27D-4384-95A4-9D8E0EABC9E5),
+ dual,
+ helpstring("ISODispatchInterceptor Interface"),
+ pointer_default(unique)
+]
+interface ISODispatchInterceptor : IDispatch
+{
+//com.sun.star.frame.XDispatchProviderInterceptor
+
+ [id(1), helpstring("method getSlaveDispatchProvider")]
+ HRESULT getSlaveDispatchProvider( [out,retval] IDispatch** retVal );
+
+ [id(2), helpstring("method setSlaveDispatchProvider")]
+ HRESULT setSlaveDispatchProvider( [in] IDispatch* xNewDispatchProvider );
+
+ [id(3), helpstring("method getMasterDispatchProvider")]
+ HRESULT getMasterDispatchProvider( [out,retval] IDispatch** retVal );
+
+ [id(4), helpstring("method setMasterDispatchProvider")]
+ HRESULT setMasterDispatchProvider( [in] IDispatch* xNewSupplier );
+
+// com.sun.star.frame.XDispatchProvider
+
+ [id(5), helpstring("method queryDispatch")]
+ HRESULT queryDispatch( [in] IDispatch* aURL,
+ [in] BSTR aTargetFrameName,
+ [in] long nSearchFlags,
+ [out,retval] IDispatch** retVal );
+
+ [id(6), helpstring("method queryDispatches")]
+ HRESULT queryDispatches( [in] SAFEARRAY(IDispatch*) aDescripts,
+ [out,retval] SAFEARRAY(VARIANT)* retVal );
+
+
+// com.sun.star.frame.XDispatch
+
+ [id(7), helpstring("method dispatch")]
+ HRESULT dispatch( [in] IDispatch* aURL,
+ [in] SAFEARRAY(VARIANT) aArgs );
+
+ [id(8), helpstring("method addStatusListener")]
+ HRESULT addStatusListener( [in] IDispatch* xControl,
+ [in] IDispatch* aURL );
+
+ [id(9), helpstring("method removeStatusListener")]
+ HRESULT removeStatusListener( [in] IDispatch* xControl,
+ [in] IDispatch* aURL );
+
+// com.sun.star.frame.XInterceptorInfo
+
+
+ [id(10), helpstring("method getInterceptedURLs")]
+ HRESULT getInterceptedURLs( [out,retval] SAFEARRAY(BSTR)* pVal );
+
+// the common UNO-COM staff
+ [propget, id(11), helpstring("property_implementedInterfaces")]
+ HRESULT Bridge_implementedInterfaces([out, retval] SAFEARRAY(BSTR) *pVal);
+
+};
+
+
+
+
+[
+ object,
+ uuid(029E9F1E-2B3F-4297-9160-8197DE7ED54F),
+ dual,
+ helpstring("ISOActionsApproval Interface"),
+ pointer_default(unique)
+]
+interface ISOActionsApproval : IDispatch
+{
+//com.sun.star.embed.XActionsApproval
+
+ [id(1), helpstring("method approveAction")]
+ HRESULT approveAction( [in] long aActionID,
+ [out,retval] boolean* pbApproval );
+
+// the common UNO-COM staff
+ [propget, id(2), helpstring("property_implementedInterfaces")]
+ HRESULT Bridge_implementedInterfaces([out, retval] SAFEARRAY(BSTR) *pVal);
+};
+
+
+
+[
+ uuid(61FA3F13-8061-4796-B055-3697ED28CB38),
+ version(1.0),
+ helpstring("so_activex 1.0 Type Library")
+]
+library SO_ACTIVEXLib
+{
+ importlib("stdole32.tlb");
+ importlib("stdole2.tlb");
+
+ [
+ uuid(7F760565-5719-4F04-BA86-112C474B10EA),
+ helpstring("_ISOActiveXEvents Interface")
+ ]
+ dispinterface _ISOActiveXEvents
+ {
+ properties:
+ methods:
+ };
+
+ [
+ uuid(67F2A879-82D5-4A6D-8CC5-FFB3C114B69D),
+ helpstring("SOActiveX Class")
+ ]
+ coclass SOActiveX
+ {
+ [default] interface ISOActiveX;
+ [default, source] dispinterface _ISOActiveXEvents;
+ };
+
+ [
+ uuid(EE51BD3E-8BB6-4FB8-B319-F65B1BE3B21D),
+ helpstring("SOComWindowPeer Class")
+ ]
+ coclass SOComWindowPeer
+ {
+ [default] interface ISOComWindowPeer;
+ };
+
+ [
+ uuid(C5D6D568-57DA-4D6C-819A-451CB565E682),
+ helpstring("SODispatchInterceptor Class")
+ ]
+ coclass SODispatchInterceptor
+ {
+ [default] interface ISODispatchInterceptor;
+ };
+
+ [
+ uuid(9F3697AC-7A18-4335-AF0A-65FAC2C35CC1),
+ helpstring("SOActionsApproval Class")
+ ]
+ coclass SOActionsApproval
+ {
+ [default] interface ISOActionsApproval;
+ };
+
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/activex/so_activex.rc b/extensions/source/activex/so_activex.rc
new file mode 100644
index 000000000..3891fa965
--- /dev/null
+++ b/extensions/source/activex/so_activex.rc
@@ -0,0 +1,124 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+//Microsoft Developer Studio generated resource script.
+
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+
+
+// Generated from the TEXTINCLUDE 2 resource.
+
+#include <winresrc.h>
+#define LB_ADDSTRING (WM_USER+1)
+#define CB_ADDSTRING (WM_USER+3)
+#define IDC_STATIC (-1)
+
+
+#undef APSTUDIO_READONLY_SYMBOLS
+
+
+// Russian resources
+
+//#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+//#ifdef _WIN32
+//LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+//#pragma code_page(1251)
+//#endif //_WIN32
+
+
+
+// Bitmap
+
+
+//IDB_SOACTIVEX BITMAP DISCARDABLE "soacti.bmp"
+
+
+
+
+// REGISTRY
+
+
+IDR_SOACTIVEX REGISTRY DISCARDABLE "SOActiveX.rgs"
+IDR_SOCOMWINDOWPEER REGISTRY DISCARDABLE "SOComWindowPeer.rgs"
+IDR_SODISPATCHINTERCEPTOR REGISTRY DISCARDABLE "SODispatchInterceptor.rgs"
+//#endif // Russian resources
+
+
+
+
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+
+
+// TEXTINCLUDE
+
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""winres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "1 TYPELIB ""so_activex.tlb""\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+
+// String Table
+
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_PROJNAME "so_activex"
+END
+
+#endif // English (U.S.) resources
+
+
+
+
+#ifndef APSTUDIO_INVOKED
+
+
+// Generated from the TEXTINCLUDE 3 resource.
+
+
+1 TYPELIB SO_ACTIVEX_TLB
+
+
+#endif // not APSTUDIO_INVOKED
+