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
[SAL_N_ELEMENTS(pSubKeyTemplate
)];
99 wcsncpy(pSubKey
, pSubKeyTemplate
, SAL_N_ELEMENTS(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
135 class InprocEmbedProvider_Impl
: public IClassFactory
, public InprocCountedObject_Impl
139 explicit InprocEmbedProvider_Impl( const GUID
& guid
);
140 virtual ~InprocEmbedProvider_Impl();
142 /* IUnknown methods */
143 STDMETHOD(QueryInterface
)(REFIID riid
, void ** ppvObj
) override
;
144 STDMETHOD_(ULONG
, AddRef
)() override
;
145 STDMETHOD_(ULONG
, Release
)() override
;
147 /* IClassFactory methods */
148 STDMETHOD(CreateInstance
)(IUnknown FAR
* punkOuter
, REFIID riid
, void FAR
* FAR
* ppv
) override
;
149 STDMETHOD(LockServer
)(BOOL fLock
) override
;
156 }; // namespace inprocserv
162 extern "C" BOOL WINAPI
DllMain( HINSTANCE hInstance
, DWORD dwReason
, LPVOID
/*lpReserved*/ )
164 if (dwReason
== DLL_PROCESS_ATTACH
)
166 g_hInstance
= hInstance
;
173 STDAPI
DllGetClassObject( REFCLSID rclsid
, REFIID riid
, LPVOID
* ppv
)
175 for( int nInd
= 0; nInd
< SUPPORTED_FACTORIES_NUM
; nInd
++ )
176 if ( *guidList
[nInd
] == rclsid
)
178 if ( !IsEqualIID( riid
, IID_IUnknown
) && !IsEqualIID( riid
, IID_IClassFactory
) )
179 return E_NOINTERFACE
;
181 *ppv
= new inprocserv::InprocEmbedProvider_Impl( rclsid
);
182 static_cast<LPUNKNOWN
>(*ppv
)->AddRef();
190 STDAPI
DllCanUnloadNow()
192 if ( !g_nObj
&& !g_nLock
)
199 STDAPI
DllRegisterServer()
201 HMODULE aCurModule
= GetModuleHandleW( L
"inprocserv.dll" );
204 wchar_t aLibPath
[1024];
205 DWORD nLen
= GetModuleFileNameW( aCurModule
, aLibPath
, 1019 );
206 if ( nLen
&& nLen
< 1019 )
208 aLibPath
[nLen
++] = 0;
209 return WriteLibraryToRegistry( aLibPath
, nLen
);
217 STDAPI
DllUnregisterServer()
219 return WriteLibraryToRegistry( L
"ole32.dll", 10 );
223 // End of entry points
230 // InprocCountedObject_Impl implementation
233 InprocCountedObject_Impl::InprocCountedObject_Impl()
239 InprocCountedObject_Impl::~InprocCountedObject_Impl()
245 // InprocEmbedProvider_Impl implementation
248 InprocEmbedProvider_Impl::InprocEmbedProvider_Impl( const GUID
& guid
)
255 InprocEmbedProvider_Impl::~InprocEmbedProvider_Impl()
261 COM_DECLSPEC_NOTHROW STDMETHODIMP
InprocEmbedProvider_Impl::QueryInterface( REFIID riid
, void ** ppv
)
263 if(IsEqualIID(riid
, IID_IUnknown
))
266 *ppv
= static_cast<IUnknown
*>(this);
269 else if (IsEqualIID(riid
, IID_IClassFactory
))
272 *ppv
= static_cast<IClassFactory
*>(this);
277 return E_NOINTERFACE
;
281 COM_DECLSPEC_NOTHROW
STDMETHODIMP_(ULONG
) InprocEmbedProvider_Impl::AddRef()
287 COM_DECLSPEC_NOTHROW
STDMETHODIMP_(ULONG
) InprocEmbedProvider_Impl::Release()
289 sal_Int32 nCount
= --m_refCount
;
296 COM_DECLSPEC_NOTHROW STDMETHODIMP
InprocEmbedProvider_Impl::CreateInstance(IUnknown FAR
* punkOuter
,
300 // TODO/LATER: should the aggregation be supported?
301 // if ( punkOuter != NULL && riid != IID_IUnknown )
302 // return E_NOINTERFACE;
303 if ( punkOuter
!= nullptr )
304 return CLASS_E_NOAGGREGATION
;
306 InprocEmbedDocument_Impl
* pEmbedDocument
= new InprocEmbedDocument_Impl( m_guid
);
307 pEmbedDocument
->AddRef();
308 HRESULT hr
= pEmbedDocument
->QueryInterface( riid
, ppv
);
309 pEmbedDocument
->Release();
311 if ( !SUCCEEDED( hr
) )
318 COM_DECLSPEC_NOTHROW STDMETHODIMP
InprocEmbedProvider_Impl::LockServer( BOOL fLock
)
328 }; // namespace inprocserv
330 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */