Version 5.2.6.1, tag libreoffice-5.2.6.1
[LibreOffice.git] / embedserv / source / inprocserv / dllentry.cxx
blob4c7baf0afbb814fb646f3217ccf1256ec1cbf678
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 #ifdef __MINGW32__
25 #define INITGUID
26 #define INPROC_DLLPUBLIC SAL_DLLPUBLIC_EXPORT
27 #else
28 #define INPROC_DLLPUBLIC
29 #endif
30 #include <embservconst.h>
32 static const GUID* guidList[ SUPPORTED_FACTORIES_NUM ] = {
33 &OID_WriterTextServer,
34 &OID_WriterOASISTextServer,
35 &OID_CalcServer,
36 &OID_CalcOASISServer,
37 &OID_DrawingServer,
38 &OID_DrawingOASISServer,
39 &OID_PresentationServer,
40 &OID_PresentationOASISServer,
41 &OID_MathServer,
42 &OID_MathOASISServer
45 static HINSTANCE g_hInstance = NULL;
46 static ULONG g_nObj = 0;
47 static ULONG g_nLock = 0;
50 namespace {
51 void FillCharFromInt( int nValue, char* pBuf, int nLen )
53 int nInd = 0;
54 while( nInd < nLen )
56 char nSign = ( nValue / ( 1 << ( ( nLen - nInd - 1 ) * 4 ) ) ) % 16;
57 if ( nSign >= 0 && nSign <= 9 )
58 pBuf[nInd] = nSign + '0';
59 else if ( nSign >= 10 && nSign <= 15 )
60 pBuf[nInd] = nSign - 10 + 'a';
62 nInd++;
66 int GetStringFromClassID( const GUID& guid, char* pBuf, int nLen )
68 // is not allowed to insert
69 if ( nLen < 38 )
70 return 0;
72 pBuf[0] = '{';
73 FillCharFromInt( guid.Data1, &pBuf[1], 8 );
74 pBuf[9] = '-';
75 FillCharFromInt( guid.Data2, &pBuf[10], 4 );
76 pBuf[14] = '-';
77 FillCharFromInt( guid.Data3, &pBuf[15], 4 );
78 pBuf[19] = '-';
80 int nInd = 0;
81 for ( nInd = 0; nInd < 2 ; nInd++ )
82 FillCharFromInt( guid.Data4[nInd], &pBuf[20 + 2*nInd], 2 );
83 pBuf[24] = '-';
84 for ( nInd = 2; nInd < 8 ; nInd++ )
85 FillCharFromInt( guid.Data4[nInd], &pBuf[20 + 1 + 2*nInd], 2 );
86 pBuf[37] = '}';
88 return 38;
91 HRESULT WriteLibraryToRegistry( const char* pLibrary, DWORD nLen )
93 HRESULT hRes = E_FAIL;
94 if ( pLibrary && nLen )
96 HKEY hKey = NULL;
98 hRes = S_OK;
99 for ( int nInd = 0; nInd < SUPPORTED_FACTORIES_NUM; nInd++ )
101 const char pSubKeyTemplate[] = "Software\\Classes\\CLSID\\.....................................\\InprocHandler32";
102 char pSubKey[SAL_N_ELEMENTS(pSubKeyTemplate)];
103 strncpy(pSubKey, pSubKeyTemplate, SAL_N_ELEMENTS(pSubKeyTemplate));
105 int nGuidLen = GetStringFromClassID( *guidList[nInd], &pSubKey[23], 38 );
107 BOOL bLocalSuccess = FALSE;
108 if ( nGuidLen == 38 )
110 if ( ERROR_SUCCESS == RegOpenKey( HKEY_LOCAL_MACHINE, pSubKey, &hKey ) )
112 if ( ERROR_SUCCESS == RegSetValueEx( hKey, "", 0, REG_SZ, (const BYTE*)pLibrary, nLen ) )
113 bLocalSuccess = TRUE;
116 if ( hKey )
118 RegCloseKey( hKey );
119 hKey = NULL;
123 if ( !bLocalSuccess )
124 hRes = E_FAIL;
128 return hRes;
133 // InprocEmbedProvider_Impl declaration
136 namespace inprocserv
139 class InprocEmbedProvider_Impl : public IClassFactory, public InprocCountedObject_Impl
141 public:
143 explicit InprocEmbedProvider_Impl( const GUID& guid );
144 virtual ~InprocEmbedProvider_Impl();
146 /* IUnknown methods */
147 STDMETHOD(QueryInterface)(REFIID riid, LPVOID FAR * ppvObj);
148 STDMETHOD_(ULONG, AddRef)();
149 STDMETHOD_(ULONG, Release)();
151 /* IClassFactory methods */
152 STDMETHOD(CreateInstance)(IUnknown FAR* punkOuter, REFIID riid, void FAR* FAR* ppv);
153 STDMETHOD(LockServer)(int fLock);
155 protected:
157 ULONG m_refCount;
158 GUID m_guid;
160 }; // namespace inprocserv
163 // Entry points
166 extern "C" INPROC_DLLPUBLIC BOOL WINAPI DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/ )
168 if (dwReason == DLL_PROCESS_ATTACH)
170 g_hInstance = hInstance;
172 else if (dwReason == DLL_PROCESS_DETACH)
176 return TRUE; // ok
180 STDAPI INPROC_DLLPUBLIC DllGetClassObject( REFCLSID rclsid, REFIID riid, LPVOID* ppv )
182 for( int nInd = 0; nInd < SUPPORTED_FACTORIES_NUM; nInd++ )
183 if ( *guidList[nInd] == rclsid )
185 if ( !IsEqualIID( riid, IID_IUnknown ) && !IsEqualIID( riid, IID_IClassFactory ) )
186 return E_NOINTERFACE;
188 *ppv = new inprocserv::InprocEmbedProvider_Impl( rclsid );
189 ((LPUNKNOWN)*ppv)->AddRef();
190 return S_OK;
193 return E_FAIL;
197 STDAPI INPROC_DLLPUBLIC DllCanUnloadNow()
199 if ( !g_nObj && !g_nLock )
200 return S_OK;
202 return S_FALSE;
206 STDAPI INPROC_DLLPUBLIC DllRegisterServer()
208 HMODULE aCurModule = GetModuleHandleA( "inprocserv.dll" );
209 if( aCurModule )
211 char aLibPath[1024];
212 DWORD nLen = GetModuleFileNameA( aCurModule, aLibPath, 1019 );
213 if ( nLen && nLen < 1019 )
215 aLibPath[nLen++] = 0;
216 return WriteLibraryToRegistry( aLibPath, nLen );
220 return E_FAIL;
224 STDAPI INPROC_DLLPUBLIC DllUnregisterServer()
226 return WriteLibraryToRegistry( "ole32.dll", 10 );
230 // End of entry points
233 namespace inprocserv
237 // InprocCountedObject_Impl implementation
240 InprocCountedObject_Impl::InprocCountedObject_Impl()
242 g_nObj++;
246 InprocCountedObject_Impl::~InprocCountedObject_Impl()
248 g_nObj--;
252 // InprocEmbedProvider_Impl implementation
255 InprocEmbedProvider_Impl::InprocEmbedProvider_Impl( const GUID& guid )
256 : m_refCount( 0 )
257 , m_guid( guid )
262 InprocEmbedProvider_Impl::~InprocEmbedProvider_Impl()
266 // IUnknown
268 STDMETHODIMP InprocEmbedProvider_Impl::QueryInterface( REFIID riid, void FAR* FAR* ppv )
270 if(IsEqualIID(riid, IID_IUnknown))
272 AddRef();
273 *ppv = (IUnknown*) this;
274 return S_OK;
276 else if (IsEqualIID(riid, IID_IClassFactory))
278 AddRef();
279 *ppv = (IClassFactory*) this;
280 return S_OK;
283 *ppv = NULL;
284 return E_NOINTERFACE;
288 STDMETHODIMP_(ULONG) InprocEmbedProvider_Impl::AddRef()
290 return ++m_refCount;
294 STDMETHODIMP_(ULONG) InprocEmbedProvider_Impl::Release()
296 sal_Int32 nCount = --m_refCount;
297 if ( nCount == 0 )
298 delete this;
299 return nCount;
303 STDMETHODIMP InprocEmbedProvider_Impl::CreateInstance(IUnknown FAR* punkOuter,
304 REFIID riid,
305 void FAR* FAR* ppv)
307 // TODO/LATER: should the aggregation be supported?
308 // if ( punkOuter != NULL && riid != IID_IUnknown )
309 // return E_NOINTERFACE;
310 if ( punkOuter != NULL )
311 return CLASS_E_NOAGGREGATION;
313 InprocEmbedDocument_Impl* pEmbedDocument = new InprocEmbedDocument_Impl( m_guid );
314 pEmbedDocument->AddRef();
315 HRESULT hr = pEmbedDocument->Init();
316 if ( SUCCEEDED( hr ) )
317 hr = pEmbedDocument->QueryInterface( riid, ppv );
318 pEmbedDocument->Release();
320 if ( !SUCCEEDED( hr ) )
321 *ppv = NULL;
323 return hr;
327 STDMETHODIMP InprocEmbedProvider_Impl::LockServer( int fLock )
329 if ( fLock )
330 g_nLock++;
331 else
332 g_nLock--;
334 return S_OK;
337 }; // namespace inprocserv
339 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */