LibreOffice Module embedserv (master) 1
dllentry.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <sal/types.h>
21
22#include <stdio.h>
23#include "inprocembobj.h"
24#include <embservconst.h>
25
26#include <olectl.h> // declarations of DllRegisterServer/DllUnregisterServer
27
28static const GUID* guidList[ SUPPORTED_FACTORIES_NUM ] = {
39};
40
41static HINSTANCE g_hInstance = nullptr;
42static ULONG g_nObj = 0;
43static ULONG g_nLock = 0;
44
45
46namespace {
47 void FillCharFromInt( int nValue, wchar_t* pBuf, int nLen )
48 {
49 int nInd = 0;
50 while( nInd < nLen )
51 {
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';
57
58 nInd++;
59 }
60 }
61
62 int GetStringFromClassID( const GUID& guid, wchar_t* pBuf, int nLen )
63 {
64 // is not allowed to insert
65 if ( nLen < 38 )
66 return 0;
67
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'-';
75
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'}';
83
84 return 38;
85 }
86
87 HRESULT WriteLibraryToRegistry( const wchar_t* pLibrary, DWORD nLen )
88 {
89 HRESULT hRes = E_FAIL;
90 if ( pLibrary && nLen )
91 {
92 HKEY hKey = nullptr;
93
94 hRes = S_OK;
95 for ( int nInd = 0; nInd < SUPPORTED_FACTORIES_NUM; nInd++ )
96 {
97 const wchar_t pSubKeyTemplate[] = L"Software\\Classes\\CLSID\\.....................................\\InprocHandler32";
98 wchar_t pSubKey[std::size(pSubKeyTemplate)];
99 wcsncpy(pSubKey, pSubKeyTemplate, std::size(pSubKeyTemplate));
100
101 int nGuidLen = GetStringFromClassID( *guidList[nInd], &pSubKey[23], 38 );
102
103 bool bLocalSuccess = false;
104 if ( nGuidLen == 38 )
105 {
106 if ( ERROR_SUCCESS == RegOpenKeyW( HKEY_LOCAL_MACHINE, pSubKey, &hKey ) )
107 {
108 if ( ERROR_SUCCESS == RegSetValueExW( hKey, L"", 0, REG_SZ, reinterpret_cast<const BYTE*>(pLibrary), nLen*sizeof(wchar_t) ) )
109 bLocalSuccess = true;
110 }
111
112 if ( hKey )
113 {
114 RegCloseKey( hKey );
115 hKey = nullptr;
116 }
117 }
118
119 if ( !bLocalSuccess )
120 hRes = E_FAIL;
121 }
122 }
123
124 return hRes;
125 }
126};
127
128
129// InprocEmbedProvider_Impl declaration
130
131
132namespace inprocserv
133{
134
135namespace {
136
137class InprocEmbedProvider_Impl : public IClassFactory, public InprocCountedObject_Impl
138{
139public:
140
141 explicit InprocEmbedProvider_Impl( const GUID& guid );
142 virtual ~InprocEmbedProvider_Impl();
143
144 /* IUnknown methods */
145 STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObj) override;
146 STDMETHOD_(ULONG, AddRef)() override;
147 STDMETHOD_(ULONG, Release)() override;
148
149 /* IClassFactory methods */
150 STDMETHOD(CreateInstance)(IUnknown* punkOuter, REFIID riid, void** ppv) override;
151 STDMETHOD(LockServer)(BOOL fLock) override;
152
153protected:
154
156 GUID m_guid;
157};
158
159}
160
161}; // namespace inprocserv
162
163
164// Entry points
165
166
167extern "C" BOOL WINAPI DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/ )
168{
169 if (dwReason == DLL_PROCESS_ATTACH)
170 {
171 g_hInstance = hInstance;
172 }
173
174 return TRUE; // ok
175}
176
177
178STDAPI DllGetClassObject( REFCLSID rclsid, REFIID riid, LPVOID* ppv )
179{
180 for( int nInd = 0; nInd < SUPPORTED_FACTORIES_NUM; nInd++ )
181 if ( *guidList[nInd] == rclsid )
182 {
183 if ( !IsEqualIID( riid, IID_IUnknown ) && !IsEqualIID( riid, IID_IClassFactory ) )
184 return E_NOINTERFACE;
185
186 *ppv = new inprocserv::InprocEmbedProvider_Impl( rclsid );
187 static_cast<LPUNKNOWN>(*ppv)->AddRef();
188 return S_OK;
189 }
190
191 return E_FAIL;
192}
193
194
196{
197 if ( !g_nObj && !g_nLock )
198 return S_OK;
199
200 return S_FALSE;
201}
202
203
205{
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);
210 if( aCurModule )
211 {
212 wchar_t aLibPath[1024];
213 DWORD nLen = GetModuleFileNameW( aCurModule, aLibPath, 1019 );
214 if ( nLen && nLen < 1019 )
215 {
216 aLibPath[nLen++] = 0;
217 return WriteLibraryToRegistry( aLibPath, nLen );
218 }
219 }
220
221 return E_FAIL;
222}
223
224
226{
227 return WriteLibraryToRegistry( L"ole32.dll", 10 );
228}
229
230
231// End of entry points
232
233
234namespace inprocserv
235{
236
237
238// InprocCountedObject_Impl implementation
239
240
242{
243 g_nObj++;
244}
245
246
248{
249 g_nObj--;
250}
251
252
253// InprocEmbedProvider_Impl implementation
254
255
256InprocEmbedProvider_Impl::InprocEmbedProvider_Impl( const GUID& guid )
257: m_refCount( 0 )
258, m_guid( guid )
259{
260}
261
262
263InprocEmbedProvider_Impl::~InprocEmbedProvider_Impl()
264{
265}
266
267// IUnknown
268
269COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedProvider_Impl::QueryInterface( REFIID riid, void ** ppv )
270{
271 if(IsEqualIID(riid, IID_IUnknown))
272 {
273 AddRef();
274 *ppv = static_cast<IUnknown*>(this);
275 return S_OK;
276 }
277 else if (IsEqualIID(riid, IID_IClassFactory))
278 {
279 AddRef();
280 *ppv = static_cast<IClassFactory*>(this);
281 return S_OK;
282 }
283
284 *ppv = nullptr;
285 return E_NOINTERFACE;
286}
287
288
289COM_DECLSPEC_NOTHROW STDMETHODIMP_(ULONG) InprocEmbedProvider_Impl::AddRef()
290{
291 return ++m_refCount;
292}
293
294
295COM_DECLSPEC_NOTHROW STDMETHODIMP_(ULONG) InprocEmbedProvider_Impl::Release()
296{
297 sal_Int32 nCount = --m_refCount;
298 if ( nCount == 0 )
299 delete this;
300 return nCount;
301}
302
303
304COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedProvider_Impl::CreateInstance(IUnknown* punkOuter,
305 REFIID riid, void** ppv)
306{
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;
312
313 InprocEmbedDocument_Impl* pEmbedDocument = new InprocEmbedDocument_Impl( m_guid );
314 pEmbedDocument->AddRef();
315 HRESULT hr = pEmbedDocument->QueryInterface( riid, ppv );
316 pEmbedDocument->Release();
317
318 if ( !SUCCEEDED( hr ) )
319 *ppv = nullptr;
320
321 return hr;
322}
323
324
325COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedProvider_Impl::LockServer( BOOL fLock )
326{
327 if ( fLock )
328 g_nLock++;
329 else
330 g_nLock--;
331
332 return S_OK;
333}
334
335}; // namespace inprocserv
336
337/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
int nCount
ULONG m_refCount
Definition: dllentry.cxx:155
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID)
Definition: dllentry.cxx:167
static ULONG g_nLock
Definition: dllentry.cxx:43
GUID m_guid
Definition: dllentry.cxx:156
STDAPI DllRegisterServer()
Definition: dllentry.cxx:204
STDAPI DllCanUnloadNow()
Definition: dllentry.cxx:195
STDAPI DllUnregisterServer()
Definition: dllentry.cxx:225
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
Definition: dllentry.cxx:178
static ULONG g_nObj
Definition: dllentry.cxx:42
static HINSTANCE g_hInstance
Definition: dllentry.cxx:41
static const GUID * guidList[SUPPORTED_FACTORIES_NUM]
Definition: dllentry.cxx:28
#define SUPPORTED_FACTORIES_NUM
Definition: embservconst.h:27
const GUID DECLSPEC_SELECTANY OID_PresentationServer
Definition: embservconst.h:39
const GUID DECLSPEC_SELECTANY OID_MathServer
Definition: embservconst.h:43
const GUID DECLSPEC_SELECTANY OID_DrawingServer
Definition: embservconst.h:35
const GUID DECLSPEC_SELECTANY OID_CalcServer
Definition: embservconst.h:32
const GUID DECLSPEC_SELECTANY OID_MathOASISServer
Definition: embservconst.h:44
const GUID DECLSPEC_SELECTANY OID_WriterTextServer
Definition: embservconst.h:29
const GUID DECLSPEC_SELECTANY OID_WriterOASISTextServer
Definition: embservconst.h:30
const GUID DECLSPEC_SELECTANY OID_CalcOASISServer
Definition: embservconst.h:33
const GUID DECLSPEC_SELECTANY OID_DrawingOASISServer
Definition: embservconst.h:36
const GUID DECLSPEC_SELECTANY OID_PresentationOASISServer
Definition: embservconst.h:41
sal_Int16 nValue
#define TRUE
STDMETHODIMP_(ULONG) OleWrapperAdviseSink
Definition: advisesink.cxx:109
const wchar_t *typedef BOOL
return hr
unsigned char BYTE