Bump version to 6.4-15
[LibreOffice.git] / embedserv / source / inprocserv / dllentry.cxx
bloba79b23b22972eab5a9609e4fc576f0b4ba02cdbf
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
22 #include <stdio.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,
31 &OID_CalcServer,
32 &OID_CalcOASISServer,
33 &OID_DrawingServer,
34 &OID_DrawingOASISServer,
35 &OID_PresentationServer,
36 &OID_PresentationOASISServer,
37 &OID_MathServer,
38 &OID_MathOASISServer
41 static HINSTANCE g_hInstance = nullptr;
42 static ULONG g_nObj = 0;
43 static ULONG g_nLock = 0;
46 namespace {
47 void FillCharFromInt( int nValue, wchar_t* pBuf, int nLen )
49 int nInd = 0;
50 while( nInd < nLen )
52 char nSign = ( nValue / ( 1 << ( ( nLen - nInd - 1 ) * 4 ) ) ) % 16;
53 if ( nSign >= 0 && nSign <= 9 )
54 pBuf[nInd] = nSign + L'0';
55 else if (nSign >= 10)
56 pBuf[nInd] = nSign - 10 + L'a';
58 nInd++;
62 int GetStringFromClassID( const GUID& guid, wchar_t* pBuf, int nLen )
64 // is not allowed to insert
65 if ( nLen < 38 )
66 return 0;
68 pBuf[0] = L'{';
69 FillCharFromInt( guid.Data1, &pBuf[1], 8 );
70 pBuf[9] = L'-';
71 FillCharFromInt( guid.Data2, &pBuf[10], 4 );
72 pBuf[14] = L'-';
73 FillCharFromInt( guid.Data3, &pBuf[15], 4 );
74 pBuf[19] = L'-';
76 int nInd = 0;
77 for ( nInd = 0; nInd < 2 ; nInd++ )
78 FillCharFromInt( guid.Data4[nInd], &pBuf[20 + 2*nInd], 2 );
79 pBuf[24] = L'-';
80 for ( nInd = 2; nInd < 8 ; nInd++ )
81 FillCharFromInt( guid.Data4[nInd], &pBuf[20 + 1 + 2*nInd], 2 );
82 pBuf[37] = L'}';
84 return 38;
87 HRESULT WriteLibraryToRegistry( const wchar_t* pLibrary, DWORD nLen )
89 HRESULT hRes = E_FAIL;
90 if ( pLibrary && nLen )
92 HKEY hKey = nullptr;
94 hRes = S_OK;
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;
112 if ( hKey )
114 RegCloseKey( hKey );
115 hKey = nullptr;
119 if ( !bLocalSuccess )
120 hRes = E_FAIL;
124 return hRes;
129 // InprocEmbedProvider_Impl declaration
132 namespace inprocserv
135 class InprocEmbedProvider_Impl : public IClassFactory, public InprocCountedObject_Impl
137 public:
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;
151 protected:
153 ULONG m_refCount;
154 GUID m_guid;
156 }; // namespace inprocserv
159 // Entry points
162 extern "C" BOOL WINAPI DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/ )
164 if (dwReason == DLL_PROCESS_ATTACH)
166 g_hInstance = hInstance;
169 return TRUE; // ok
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();
183 return S_OK;
186 return E_FAIL;
190 STDAPI DllCanUnloadNow()
192 if ( !g_nObj && !g_nLock )
193 return S_OK;
195 return S_FALSE;
199 STDAPI DllRegisterServer()
201 HMODULE aCurModule = GetModuleHandleW( L"inprocserv.dll" );
202 if( aCurModule )
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 );
213 return E_FAIL;
217 STDAPI DllUnregisterServer()
219 return WriteLibraryToRegistry( L"ole32.dll", 10 );
223 // End of entry points
226 namespace inprocserv
230 // InprocCountedObject_Impl implementation
233 InprocCountedObject_Impl::InprocCountedObject_Impl()
235 g_nObj++;
239 InprocCountedObject_Impl::~InprocCountedObject_Impl()
241 g_nObj--;
245 // InprocEmbedProvider_Impl implementation
248 InprocEmbedProvider_Impl::InprocEmbedProvider_Impl( const GUID& guid )
249 : m_refCount( 0 )
250 , m_guid( guid )
255 InprocEmbedProvider_Impl::~InprocEmbedProvider_Impl()
259 // IUnknown
261 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedProvider_Impl::QueryInterface( REFIID riid, void ** ppv )
263 if(IsEqualIID(riid, IID_IUnknown))
265 AddRef();
266 *ppv = static_cast<IUnknown*>(this);
267 return S_OK;
269 else if (IsEqualIID(riid, IID_IClassFactory))
271 AddRef();
272 *ppv = static_cast<IClassFactory*>(this);
273 return S_OK;
276 *ppv = nullptr;
277 return E_NOINTERFACE;
281 COM_DECLSPEC_NOTHROW STDMETHODIMP_(ULONG) InprocEmbedProvider_Impl::AddRef()
283 return ++m_refCount;
287 COM_DECLSPEC_NOTHROW STDMETHODIMP_(ULONG) InprocEmbedProvider_Impl::Release()
289 sal_Int32 nCount = --m_refCount;
290 if ( nCount == 0 )
291 delete this;
292 return nCount;
296 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedProvider_Impl::CreateInstance(IUnknown FAR* punkOuter,
297 REFIID riid,
298 void FAR* FAR* ppv)
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 ) )
312 *ppv = nullptr;
314 return hr;
318 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedProvider_Impl::LockServer( BOOL fLock )
320 if ( fLock )
321 g_nLock++;
322 else
323 g_nLock--;
325 return S_OK;
328 }; // namespace inprocserv
330 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */