1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/types.h>
23 #include "inprocembobj.h"
24 #include <embservconst.h>
26 #include <olectl.h> // declarations of DllRegisterServer/DllUnregisterServer
28 static const GUID
* guidList
[ SUPPORTED_FACTORIES_NUM
] = {
29 &OID_WriterTextServer
,
30 &OID_WriterOASISTextServer
,
34 &OID_DrawingOASISServer
,
35 &OID_PresentationServer
,
36 &OID_PresentationOASISServer
,
41 static HINSTANCE g_hInstance
= nullptr;
42 static ULONG g_nObj
= 0;
43 static ULONG g_nLock
= 0;
47 void FillCharFromInt( int nValue
, wchar_t* pBuf
, int nLen
)
52 char nSign
= ( nValue
/ ( 1 << ( ( nLen
- nInd
- 1 ) * 4 ) ) ) % 16;
53 if ( nSign
>= 0 && nSign
<= 9 )
54 pBuf
[nInd
] = nSign
+ L
'0';
56 pBuf
[nInd
] = nSign
- 10 + L
'a';
62 int GetStringFromClassID( const GUID
& guid
, wchar_t* pBuf
, int nLen
)
64 // is not allowed to insert
69 FillCharFromInt( guid
.Data1
, &pBuf
[1], 8 );
71 FillCharFromInt( guid
.Data2
, &pBuf
[10], 4 );
73 FillCharFromInt( guid
.Data3
, &pBuf
[15], 4 );
77 for ( nInd
= 0; nInd
< 2 ; nInd
++ )
78 FillCharFromInt( guid
.Data4
[nInd
], &pBuf
[20 + 2*nInd
], 2 );
80 for ( nInd
= 2; nInd
< 8 ; nInd
++ )
81 FillCharFromInt( guid
.Data4
[nInd
], &pBuf
[20 + 1 + 2*nInd
], 2 );
87 HRESULT
WriteLibraryToRegistry( const wchar_t* pLibrary
, DWORD nLen
)
89 HRESULT hRes
= E_FAIL
;
90 if ( pLibrary
&& nLen
)
95 for ( int nInd
= 0; nInd
< SUPPORTED_FACTORIES_NUM
; nInd
++ )
97 const wchar_t pSubKeyTemplate
[] = L
"Software\\Classes\\CLSID\\.....................................\\InprocHandler32";
98 wchar_t pSubKey
[std::size(pSubKeyTemplate
)];
99 wcsncpy(pSubKey
, pSubKeyTemplate
, std::size(pSubKeyTemplate
));
101 int nGuidLen
= GetStringFromClassID( *guidList
[nInd
], &pSubKey
[23], 38 );
103 bool bLocalSuccess
= false;
104 if ( nGuidLen
== 38 )
106 if ( ERROR_SUCCESS
== RegOpenKeyW( HKEY_LOCAL_MACHINE
, pSubKey
, &hKey
) )
108 if ( ERROR_SUCCESS
== RegSetValueExW( hKey
, L
"", 0, REG_SZ
, reinterpret_cast<const BYTE
*>(pLibrary
), nLen
*sizeof(wchar_t) ) )
109 bLocalSuccess
= true;
119 if ( !bLocalSuccess
)
129 // InprocEmbedProvider_Impl declaration
137 class InprocEmbedProvider_Impl
: public IClassFactory
, public InprocCountedObject_Impl
141 explicit InprocEmbedProvider_Impl( const GUID
& guid
);
142 virtual ~InprocEmbedProvider_Impl();
144 /* IUnknown methods */
145 STDMETHOD(QueryInterface
)(REFIID riid
, void ** ppvObj
) override
;
146 STDMETHOD_(ULONG
, AddRef
)() override
;
147 STDMETHOD_(ULONG
, Release
)() override
;
149 /* IClassFactory methods */
150 STDMETHOD(CreateInstance
)(IUnknown
* punkOuter
, REFIID riid
, void** ppv
) override
;
151 STDMETHOD(LockServer
)(BOOL fLock
) override
;
161 }; // namespace inprocserv
167 extern "C" BOOL WINAPI
DllMain( HINSTANCE hInstance
, DWORD dwReason
, LPVOID
/*lpReserved*/ )
169 if (dwReason
== DLL_PROCESS_ATTACH
)
171 g_hInstance
= hInstance
;
178 STDAPI
DllGetClassObject( REFCLSID rclsid
, REFIID riid
, LPVOID
* ppv
)
180 for( int nInd
= 0; nInd
< SUPPORTED_FACTORIES_NUM
; nInd
++ )
181 if ( *guidList
[nInd
] == rclsid
)
183 if ( !IsEqualIID( riid
, IID_IUnknown
) && !IsEqualIID( riid
, IID_IClassFactory
) )
184 return E_NOINTERFACE
;
186 *ppv
= new inprocserv::InprocEmbedProvider_Impl( rclsid
);
187 static_cast<LPUNKNOWN
>(*ppv
)->AddRef();
195 STDAPI
DllCanUnloadNow()
197 if ( !g_nObj
&& !g_nLock
)
204 STDAPI
DllRegisterServer()
206 HMODULE aCurModule
{};
207 GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
208 | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT
,
209 reinterpret_cast<LPCWSTR
>(&DllRegisterServer
), &aCurModule
);
212 wchar_t aLibPath
[1024];
213 DWORD nLen
= GetModuleFileNameW( aCurModule
, aLibPath
, 1019 );
214 if ( nLen
&& nLen
< 1019 )
216 aLibPath
[nLen
++] = 0;
217 return WriteLibraryToRegistry( aLibPath
, nLen
);
225 STDAPI
DllUnregisterServer()
227 return WriteLibraryToRegistry( L
"ole32.dll", 10 );
231 // End of entry points
238 // InprocCountedObject_Impl implementation
241 InprocCountedObject_Impl::InprocCountedObject_Impl()
247 InprocCountedObject_Impl::~InprocCountedObject_Impl()
253 // InprocEmbedProvider_Impl implementation
256 InprocEmbedProvider_Impl::InprocEmbedProvider_Impl( const GUID
& guid
)
263 InprocEmbedProvider_Impl::~InprocEmbedProvider_Impl()
269 COM_DECLSPEC_NOTHROW STDMETHODIMP
InprocEmbedProvider_Impl::QueryInterface( REFIID riid
, void ** ppv
)
271 if(IsEqualIID(riid
, IID_IUnknown
))
274 *ppv
= static_cast<IUnknown
*>(this);
277 else if (IsEqualIID(riid
, IID_IClassFactory
))
280 *ppv
= static_cast<IClassFactory
*>(this);
285 return E_NOINTERFACE
;
289 COM_DECLSPEC_NOTHROW
STDMETHODIMP_(ULONG
) InprocEmbedProvider_Impl::AddRef()
295 COM_DECLSPEC_NOTHROW
STDMETHODIMP_(ULONG
) InprocEmbedProvider_Impl::Release()
297 sal_Int32 nCount
= --m_refCount
;
304 COM_DECLSPEC_NOTHROW STDMETHODIMP
InprocEmbedProvider_Impl::CreateInstance(IUnknown
* punkOuter
,
305 REFIID riid
, void** ppv
)
307 // TODO/LATER: should the aggregation be supported?
308 // if ( punkOuter != NULL && riid != IID_IUnknown )
309 // return E_NOINTERFACE;
310 if ( punkOuter
!= nullptr )
311 return CLASS_E_NOAGGREGATION
;
313 InprocEmbedDocument_Impl
* pEmbedDocument
= new InprocEmbedDocument_Impl( m_guid
);
314 pEmbedDocument
->AddRef();
315 HRESULT hr
= pEmbedDocument
->QueryInterface( riid
, ppv
);
316 pEmbedDocument
->Release();
318 if ( !SUCCEEDED( hr
) )
325 COM_DECLSPEC_NOTHROW STDMETHODIMP
InprocEmbedProvider_Impl::LockServer( BOOL fLock
)
335 }; // namespace inprocserv
337 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */