LibreOffice Module extensions (master) 1
so_activex.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// so_activex.cpp : Implementation of DLL Exports.
21
22// Note: Proxy/Stub Information
23// To build a separate proxy/stub DLL,
24// run nmake -f so_activexps.mk in the project directory.
25
26#include <stdio.h>
27#include "StdAfx2.h"
28#include "resource.h"
29#include <initguid.h>
30#include <so_activex.h>
31
32#if defined __clang__
33#pragma clang diagnostic push
34#pragma clang diagnostic ignored "-Wextra-tokens"
35 // "#endif !_MIDL_USE_GUIDDEF_" in midl-generated code
36#endif
37#include <so_activex_i.c>
38#if defined __clang__
39#pragma clang diagnostic pop
40#endif
41
42#include "SOActiveX.h"
43
45#include <sal/types.h>
46#include <exception>
47
48CComModule _Module;
49
50BEGIN_OBJECT_MAP(ObjectMap)
51OBJECT_ENTRY(CLSID_SOActiveX, CSOActiveX)
52#if defined __clang__
53#pragma clang diagnostic push
54#pragma clang diagnostic ignored "-Wmissing-field-initializers"
55#endif
56END_OBJECT_MAP()
57#if defined __clang__
58#pragma clang diagnostic pop
59#endif
60
61#define X64_LIB_NAME L"so_activex_x64.dll"
62#define X32_LIB_NAME L"so_activex.dll"
63
64const REGSAM n64KeyAccess = KEY_ALL_ACCESS | KEY_WOW64_64KEY;
65const REGSAM n32KeyAccess = KEY_ALL_ACCESS;
66
67#ifdef _AMD64_
68const bool bX64 = true;
69#define REG_DELETE_KEY_A( key, aPath, nKeyAccess ) RegDeleteKeyExA( key, aPath, nKeyAccess, 0 )
70#else
71const bool bX64 = false;
72#define REG_DELETE_KEY_A( key, aPath, nKeyAccess ) RegDeleteKeyA( key, aPath )
73#endif
74
75// DLL Entry Point
76
77extern "C"
78BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
79{
80 if (dwReason == DLL_PROCESS_ATTACH)
81 {
82 _Module.Init(ObjectMap, hInstance, &LIBID_SO_ACTIVEXLib);
83 DisableThreadLibraryCalls(hInstance);
84 }
85 else if (dwReason == DLL_PROCESS_DETACH)
86 _Module.Term();
87 return TRUE; // ok
88}
89
90
91// Used to determine whether the DLL can be unloaded by OLE
92
94{
95 return (_Module.GetLockCount()==0) ? S_OK : S_FALSE;
96}
97
98
99// Returns a class factory to create an object of the requested type
100
101STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
102{
103 return _Module.GetClassObject(rclsid, riid, ppv);
104}
105
106
107// DllRegisterServer - Adds entries to the system registry
108
109namespace
110{
111// Wraps an updatable Win32 error; keeps first incoming error.
112// Ctor defines if upd will throw std::exception on error or
113// return false.
114class Status
115{
116public:
117 explicit Status(bool bTrow)
118 : m_bThrow(bTrow)
119 {
120 }
121 // used to check success of an operation, and update the status if it's still ERROR_SUCCESS
122 bool upd(LSTATUS nNewStatus)
123 {
124 if (m_nStatus == ERROR_SUCCESS)
125 m_nStatus = nNewStatus;
126 if (m_bThrow && nNewStatus != ERROR_SUCCESS)
127 throw std::exception();
128 return nNewStatus == ERROR_SUCCESS;
129 };
130 LSTATUS get() { return m_nStatus; }
131 operator bool() { return m_nStatus == ERROR_SUCCESS; }
132
133private:
134 LSTATUS m_nStatus = ERROR_SUCCESS;
135 const bool m_bThrow;
136};
137
138class HRegKey
139{
140public:
141 ~HRegKey()
142 {
143 if (m_hkey)
144 RegCloseKey(m_hkey);
145 }
146 PHKEY operator&() { return &m_hkey; }
147 operator HKEY() { return m_hkey; }
148
149private:
150 HKEY m_hkey = nullptr;
151};
152}
153
154// for now database component and chart are always installed
155#define SUPPORTED_EXT_NUM 30
156const char* const aFileExt[] = { ".vor",
157 ".sds", ".sda", ".sdd", ".sdp", ".sdc", ".sdw", ".smf",
158 ".stw", ".stc", ".sti", ".std",
159 ".sxw", ".sxc", ".sxi", ".sxd", ".sxg", ".sxm",
160 ".ott", ".otg", ".otp", ".ots", ".otf",
161 ".odt", ".oth", ".odm", ".odg", ".odp", ".ods", ".odf"};
162const sal_Unicode* const aMimeType[] = {
163 u"application/vnd.stardivision.writer",
164
165 u"application/vnd.stardivision.chart",
166 u"application/vnd.stardivision.draw",
167 u"application/vnd.stardivision.impress",
168 u"application/vnd.stardivision.impress-packed",
169 u"application/vnd.stardivision.calc",
170 u"application/vnd.stardivision.writer",
171 u"application/vnd.stardivision.math",
172
177
184
191
199
200const int nForModes[] = { 16,
201 1, 2, 4, 4, 8, 16, 32,
202 16, 8, 4, 2,
203 16, 8, 4, 2, 16, 32,
204 16, 2, 4, 8, 32,
205 16, 16, 16, 2, 4, 8, 32 };
206
207const char* const aClassID = "{67F2A879-82D5-4A6D-8CC5-FFB3C114B69D}";
208const char* const aTypeLib = "{61FA3F13-8061-4796-B055-3697ED28CB38}";
209
210// ISOComWindowPeer interface information
211const char* const aInterIDWinPeer = "{BF5D10F3-8A10-4A0B-B150-2B6AA2D7E118}";
212const char* const aProxyStubWinPeer = "{00020424-0000-0000-C000-000000000046}";
213
214// ISODispatchInterceptor interface information
215const char* const aInterIDDispInt = "{9337694C-B27D-4384-95A4-9D8E0EABC9E5}";
216const char* const aProxyStubDispInt = "{00020424-0000-0000-C000-000000000046}";
217
218// ISOActionsApproval interface information
219const char* const aInterIDActApprove = "{029E9F1E-2B3F-4297-9160-8197DE7ED54F}";
220const char* const aProxyStubActApprove = "{00020424-0000-0000-C000-000000000046}";
221
222// The following prefix is required for HKEY_LOCAL_MACHINE and HKEY_CURRENT_USER ( not for HKEY_CLASSES_ROOT )
223const char* const aLocalPrefix = "Software\\Classes\\";
224
225static LSTATUS createKey( HKEY hkey,
226 const char* aKeyToCreate,
227 REGSAM nKeyAccess,
228 const char* aValue = nullptr,
229 const char* aChildName = nullptr,
230 const char* aChildValue = nullptr )
231{
232 Status s(false); // no throw
233 HRegKey hkey1;
234 if (s.upd(RegCreateKeyExA(hkey, aKeyToCreate, 0, nullptr, REG_OPTION_NON_VOLATILE, nKeyAccess,
235 nullptr, &hkey1, nullptr)))
236 {
237 if (aValue)
238 s.upd(RegSetValueExA(hkey1, "", 0, REG_SZ, reinterpret_cast<const BYTE*>(aValue),
239 sal::static_int_cast<DWORD>(strlen(aValue))));
240 if (aChildName)
241 s.upd(RegSetValueExA(hkey1, aChildName, 0, REG_SZ,
242 reinterpret_cast<const BYTE*>(aChildValue),
243 sal::static_int_cast<DWORD>(strlen(aChildValue))));
244 }
245 return s.get();
246}
247
248static LSTATUS createKey(HKEY hkey,
249 const wchar_t* aKeyToCreate,
250 REGSAM nKeyAccess,
251 const wchar_t* aValue = nullptr,
252 const wchar_t* aChildName = nullptr,
253 const wchar_t* aChildValue = nullptr )
254{
255 Status s(false); // no throw
256 HRegKey hkey1;
257 if (s.upd(RegCreateKeyExW(hkey, aKeyToCreate, 0, nullptr, REG_OPTION_NON_VOLATILE, nKeyAccess,
258 nullptr, &hkey1, nullptr)))
259 {
260 if (aValue)
261 s.upd(RegSetValueExW(hkey1, L"", 0, REG_SZ, reinterpret_cast<const BYTE*>(aValue),
262 sal::static_int_cast<DWORD>(wcslen(aValue) * sizeof(wchar_t))));
263 if (aChildName)
264 s.upd(RegSetValueExW(
265 hkey1, aChildName, 0, REG_SZ, reinterpret_cast<const BYTE*>(aChildValue),
266 sal::static_int_cast<DWORD>(wcslen(aChildValue) * sizeof(wchar_t))));
267 }
268 return s.get();
269}
270
271EXTERN_C __declspec(dllexport) HRESULT STDAPICALLTYPE DllUnregisterServerNative( int nMode, BOOL bForAllUsers, BOOL bFor64Bit );
272static HRESULT DllRegisterServerNative_Impl( int nMode, bool bForAllUsers, REGSAM nKeyAccess, const wchar_t* pProgramPath, const wchar_t* pLibName )
273{
274 char aSubKey[513];
275 int ind;
276 const char* aPrefix = aLocalPrefix; // bForAllUsers ? "" : aLocalPrefix;
277
278 // In case SO7 is installed for this user he can have local registry entries that will prevent him from
279 // using SO8 ActiveX control. The fix is just to clean up the local entries related to ActiveX control.
280 // Unfortunately it can be done only for the user who installs the office.
281 if ( bForAllUsers )
282 DllUnregisterServerNative( nMode, false, false );
283
284 Status s(true); // throw
285 try
286 {
287 if (pProgramPath && wcslen(pProgramPath) < 1024)
288 {
289 wchar_t pActiveXPath[1124];
290 wchar_t pActiveXPath101[1124];
291
292 swprintf(pActiveXPath, L"%s\\%s", pProgramPath, pLibName);
293 swprintf(pActiveXPath101, L"%s\\%s, 101", pProgramPath, pLibName);
294
295 {
296 wsprintfA(aSubKey, "%sCLSID\\%s", aPrefix, aClassID);
297 HRegKey hkey;
298 s.upd(RegCreateKeyExA(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER,
299 aSubKey, 0, nullptr, REG_OPTION_NON_VOLATILE, nKeyAccess,
300 nullptr, &hkey, nullptr));
301 s.upd(RegSetValueExA(hkey, "", 0, REG_SZ,
302 reinterpret_cast<const BYTE*>("SOActiveX Class"), 17));
303 s.upd(createKey(hkey, "Control", nKeyAccess));
304 s.upd(createKey(hkey, "EnableFullPage", nKeyAccess));
305 s.upd(createKey(hkey, L"InprocServer32", nKeyAccess, pActiveXPath,
306 L"ThreadingModel", L"Apartment"));
307 s.upd(createKey(hkey, "MiscStatus", nKeyAccess, "0"));
308 s.upd(createKey(hkey, "MiscStatus\\1", nKeyAccess, "131473"));
309 s.upd(createKey(hkey, "ProgID", nKeyAccess, "so_activex.SOActiveX.1"));
310 s.upd(createKey(hkey, "Programmable", nKeyAccess));
311 s.upd(createKey(hkey, L"ToolboxBitmap32", nKeyAccess, pActiveXPath101));
312 s.upd(createKey(hkey, "TypeLib", nKeyAccess, aTypeLib));
313 s.upd(createKey(hkey, "Version", nKeyAccess, "1.0"));
314 s.upd(createKey(hkey, "VersionIndependentProgID", nKeyAccess,
315 "so_activex.SOActiveX"));
316 }
317 {
318 HRegKey hkey;
319 s.upd(RegCreateKeyExA(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER,
320 aPrefix, 0, nullptr, REG_OPTION_NON_VOLATILE, nKeyAccess,
321 nullptr, &hkey, nullptr));
322 s.upd(createKey(hkey, "so_activex.SOActiveX", nKeyAccess, "SOActiveX Class"));
323 {
324 HRegKey hkey1;
325 s.upd(RegCreateKeyExA(hkey, "so_activex.SOActiveX", 0, nullptr,
326 REG_OPTION_NON_VOLATILE, nKeyAccess, nullptr, &hkey1,
327 nullptr));
328 s.upd(createKey(hkey1, "CLSID", nKeyAccess, aClassID));
329 s.upd(createKey(hkey1, "CurVer", nKeyAccess, "so_activex.SOActiveX.1"));
330 }
331 s.upd(createKey(hkey, "so_activex.SOActiveX.1", nKeyAccess, "SOActiveX Class"));
332 {
333 HRegKey hkey1;
334 s.upd(RegCreateKeyExA(hkey, "so_activex.SOActiveX.1", 0, nullptr,
335 REG_OPTION_NON_VOLATILE, nKeyAccess, nullptr, &hkey1,
336 nullptr));
337 s.upd(createKey(hkey1, "CLSID", nKeyAccess, aClassID));
338 }
339 {
340 HRegKey hkey1;
341 s.upd(RegCreateKeyExA(hkey, "TypeLib", 0, nullptr, REG_OPTION_NON_VOLATILE,
342 nKeyAccess, nullptr, &hkey1, nullptr));
343 {
344 HRegKey hkey2;
345 s.upd(RegCreateKeyExA(hkey1, aTypeLib, 0, nullptr, REG_OPTION_NON_VOLATILE,
346 nKeyAccess, nullptr, &hkey2, nullptr));
347 s.upd(createKey(hkey2, "1.0", nKeyAccess, "wrap_activex 1.0 Type Library"));
348 {
349 HRegKey hkey3;
350 s.upd(RegCreateKeyExA(hkey2, "1.0", 0, nullptr, REG_OPTION_NON_VOLATILE,
351 nKeyAccess, nullptr, &hkey3, nullptr));
352 {
353 HRegKey hkey4;
354 s.upd(RegCreateKeyExA(hkey3, "0", 0, nullptr,
355 REG_OPTION_NON_VOLATILE, nKeyAccess, nullptr,
356 &hkey4, nullptr));
357 s.upd(createKey(hkey4, L"win32", nKeyAccess, pActiveXPath));
358 }
359 s.upd(createKey(hkey3, "FLAGS", nKeyAccess, "0"));
360 s.upd(createKey(hkey3, L"HELPDIR", nKeyAccess, pProgramPath));
361 }
362 }
363 }
364 {
365 HRegKey hkey1;
366 s.upd(RegCreateKeyExA(hkey, "Interface", 0, nullptr, REG_OPTION_NON_VOLATILE,
367 nKeyAccess, nullptr, &hkey1, nullptr));
368 s.upd(createKey(hkey1, aInterIDWinPeer, nKeyAccess, "ISOComWindowPeer"));
369 {
370 HRegKey hkey2;
371 s.upd(RegCreateKeyExA(hkey1, aInterIDWinPeer, 0, nullptr,
372 REG_OPTION_NON_VOLATILE, nKeyAccess, nullptr, &hkey2,
373 nullptr));
374 s.upd(createKey(hkey2, "ProxyStubClsid", nKeyAccess, aProxyStubWinPeer));
375 s.upd(createKey(hkey2, "ProxyStubClsid32", nKeyAccess, aProxyStubWinPeer));
376 s.upd(createKey(hkey2, "TypeLib", nKeyAccess, aTypeLib, "Version", "1.0"));
377 }
378 s.upd(createKey(hkey1, aInterIDActApprove, nKeyAccess, "ISOActionsApproval"));
379 {
380 HRegKey hkey2;
381 s.upd(RegCreateKeyExA(hkey1, aInterIDActApprove, 0, nullptr,
382 REG_OPTION_NON_VOLATILE, nKeyAccess, nullptr, &hkey2,
383 nullptr));
384 s.upd(createKey(hkey2, "ProxyStubClsid", nKeyAccess, aProxyStubActApprove));
385 s.upd(
386 createKey(hkey2, "ProxyStubClsid32", nKeyAccess, aProxyStubActApprove));
387 s.upd(createKey(hkey2, "TypeLib", nKeyAccess, aTypeLib, "Version", "1.0"));
388 }
389 s.upd(createKey(hkey1, aInterIDDispInt, nKeyAccess, "ISODispatchInterceptor"));
390 {
391 HRegKey hkey2;
392 s.upd(RegCreateKeyExA(hkey1, aInterIDDispInt, 0, nullptr,
393 REG_OPTION_NON_VOLATILE, nKeyAccess, nullptr, &hkey2,
394 nullptr));
395 s.upd(createKey(hkey2, "ProxyStubClsid", nKeyAccess, aProxyStubDispInt));
396 s.upd(createKey(hkey2, "ProxyStubClsid32", nKeyAccess, aProxyStubDispInt));
397 s.upd(createKey(hkey2, "TypeLib", nKeyAccess, aTypeLib, "Version", "1.0"));
398 }
399 }
400 }
401 }
402
403 for (ind = 0; ind < SUPPORTED_EXT_NUM; ind++)
404 {
405 if (nForModes[ind] & nMode)
406 {
407 wsprintfA(aSubKey, "%sMIME\\DataBase\\Content Type\\%ls", aPrefix, aMimeType[ind]);
408 HRegKey hkey;
409 s.upd(RegCreateKeyExA(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER,
410 aSubKey, 0, nullptr, REG_OPTION_NON_VOLATILE, nKeyAccess,
411 nullptr, &hkey, nullptr));
412 s.upd(RegSetValueExA(hkey, "CLSID", 0, REG_SZ,
413 reinterpret_cast<const BYTE*>(aClassID),
414 sal::static_int_cast<DWORD>(strlen(aClassID))));
415 }
416 }
417
418 {
419 wsprintfA(aSubKey, "%sCLSID\\%s", aPrefix, aClassID);
420 HRegKey hkey;
421 s.upd(RegOpenKeyExA(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, 0,
422 nKeyAccess, &hkey));
423 for (ind = 0; ind < SUPPORTED_EXT_NUM; ind++)
424 {
425 wsprintfA(aSubKey, "EnableFullPage\\%s", aFileExt[ind]);
426 HRegKey hkey1;
427 s.upd(RegCreateKeyExA(hkey, aSubKey, 0, nullptr, REG_OPTION_NON_VOLATILE,
428 nKeyAccess, nullptr, &hkey1, nullptr));
429 }
430 }
431 }
432 catch (const std::exception&) {}
433
434 return HRESULT_FROM_WIN32(s.get());
435}
436
437EXTERN_C __declspec(dllexport) HRESULT STDAPICALLTYPE DllRegisterServerNative( int nMode, BOOL bForAllUsers, BOOL bFor64Bit, const wchar_t* pProgramPath )
438{
439 HRESULT hr = S_OK;
442
443 if ( SUCCEEDED( hr ) )
445
446 return hr;
447}
448
449
450// DllUnregisterServer - Removes entries from the system registry
451static HRESULT DeleteKeyTree( HKEY hkey, const char* pPath, REGSAM nKeyAccess )
452{
453 char pSubKeyName[256];
454 // first delete the subkeys
455 while (true)
456 {
457 HRegKey hkey1;
458 if (ERROR_SUCCESS != RegOpenKeyExA(hkey, pPath, 0, nKeyAccess, &hkey1)
459 || ERROR_SUCCESS != RegEnumKeyA(hkey1, 0, pSubKeyName, 256)
460 || ERROR_SUCCESS != DeleteKeyTree(hkey1, pSubKeyName, nKeyAccess))
461 break;
462 }
463
464 // delete the key itself
465 return REG_DELETE_KEY_A( hkey, pPath, nKeyAccess & ( KEY_WOW64_64KEY | KEY_WOW64_32KEY ) );
466}
467
468static HRESULT DllUnregisterServerNative_Impl( int nMode, bool bForAllUsers, REGSAM nKeyAccess )
469{
470 char aSubKey[513];
471 const char* aPrefix = aLocalPrefix; // bForAllUsers ? "" : aLocalPrefix;
472
473 Status s(false); // no throw
474 for( int ind = 0; ind < SUPPORTED_EXT_NUM; ind++ )
475 {
476 if( nForModes[ind] & nMode )
477 {
478 DWORD nSubKeys = 0, nValues = 0;
479 wsprintfA(aSubKey, "%sMIME\\DataBase\\Content Type\\%ls", aPrefix, aMimeType[ind]);
480 Status s1(false); // no throw
481 {
482 HRegKey hkey;
483 if (s1.upd(RegCreateKeyExA(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER,
484 aSubKey, 0, nullptr, REG_OPTION_NON_VOLATILE, nKeyAccess,
485 nullptr, &hkey, nullptr)))
486 {
487 s1.upd(RegDeleteValueA(hkey, "CLSID"));
488 s1.upd(RegQueryInfoKeyA(hkey, nullptr, nullptr, nullptr, &nSubKeys, nullptr,
489 nullptr, &nValues, nullptr, nullptr, nullptr, nullptr));
490 }
491 }
492 if (s1 && !nSubKeys && !nValues)
493 DeleteKeyTree(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey,
494 nKeyAccess);
495 s.upd(s1.get());
496
497 wsprintfA(aSubKey, "%s%s", aPrefix, aFileExt[ind]);
498 Status s2(false); // no throw
499 {
500 HRegKey hkey;
501 if (s2.upd(RegCreateKeyExA(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER,
502 aSubKey, 0, nullptr, REG_OPTION_NON_VOLATILE, nKeyAccess,
503 nullptr, &hkey, nullptr)))
504 {
505 s2.upd(RegQueryInfoKeyA(hkey, nullptr, nullptr, nullptr, &nSubKeys, nullptr,
506 nullptr, &nValues, nullptr, nullptr, nullptr, nullptr));
507 }
508 }
509 if (s2 && !nSubKeys && !nValues)
510 DeleteKeyTree(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey,
511 nKeyAccess);
512 s.upd(s2.get());
513 }
514 }
515
516 wsprintfA(aSubKey, "%sCLSID\\%s", aPrefix, aClassID);
517 s.upd(DeleteKeyTree(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey,
518 nKeyAccess));
519
520 wsprintfA(aSubKey, "%sso_activex.SOActiveX", aPrefix);
521 s.upd(DeleteKeyTree(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey,
522 nKeyAccess));
523
524 wsprintfA(aSubKey, "%sso_activex.SOActiveX.1", aPrefix);
525 s.upd(DeleteKeyTree(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey,
526 nKeyAccess));
527
528 wsprintfA(aSubKey, "%s\\TypeLib\\%s", aPrefix, aTypeLib);
529 s.upd(DeleteKeyTree(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey,
530 nKeyAccess));
531
532 wsprintfA(aSubKey, "%s\\Interface\\%s", aPrefix, aInterIDWinPeer);
533 s.upd(DeleteKeyTree(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey,
534 nKeyAccess));
535
536 wsprintfA(aSubKey, "%s\\Interface\\%s", aPrefix, aInterIDDispInt);
537 s.upd(DeleteKeyTree(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey,
538 nKeyAccess));
539
540 wsprintfA(aSubKey, "%s\\Interface\\%s", aPrefix, aInterIDActApprove);
541 s.upd(DeleteKeyTree(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey,
542 nKeyAccess));
543
544 return HRESULT_FROM_WIN32(s.get());
545}
546
548{
550 if ( SUCCEEDED( hr ) && bFor64Bit )
552
553 return hr;
554}
555
556
557// DllRegisterServerDoc - Adds entries to the system registry
558
559#define SUPPORTED_MSEXT_NUM 7
560const char* const aMSFileExt[] = { ".dot", ".doc", ".xlt", ".xls", ".pot", ".ppt", ".pps" };
561const char* const aMSMimeType[] = { "application/msword",
562 "application/msword",
563 "application/vnd.ms-excel",
564 "application/vnd.ms-excel",
565 "application/vnd.ms-powerpoint",
566 "application/vnd.ms-powerpoint",
567 "application/vnd.ms-powerpoint" };
568const int nForMSModes[] = { 1, 1, 2, 2, 4, 4, 4 };
569
570EXTERN_C __declspec(dllexport) HRESULT STDAPICALLTYPE DllUnregisterServerDoc( int nMode, BOOL bForAllUsers, BOOL bFor64Bit );
571static HRESULT DllRegisterServerDoc_Impl( int nMode, bool bForAllUsers, REGSAM nKeyAccess )
572{
573 char aSubKey[513];
574 int ind;
575 const char* aPrefix = aLocalPrefix; // bForAllUsers ? "" : aLocalPrefix;
576
577 // In case SO7 is installed for this user he can have local registry entries that will prevent him from
578 // using SO8 ActiveX control. The fix is just to clean up the local entries related to ActiveX control.
579 // Unfortunately it can be done only for the user who installs the office.
580 if ( bForAllUsers )
581 DllUnregisterServerDoc( nMode, false, false );
582
583 Status s(true); // throw
584 try
585 {
586 for (ind = 0; ind < SUPPORTED_MSEXT_NUM; ind++)
587 {
588 if (nForMSModes[ind] & nMode)
589 {
590 {
591 wsprintfA(aSubKey, "%sMIME\\DataBase\\Content Type\\%s", aPrefix,
592 aMSMimeType[ind]);
593 HRegKey hkey;
594 s.upd(RegCreateKeyExA(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER,
595 aSubKey, 0, nullptr, REG_OPTION_NON_VOLATILE, nKeyAccess,
596 nullptr, &hkey, nullptr));
597 s.upd(RegSetValueExA(hkey, "Extension", 0, REG_SZ,
598 reinterpret_cast<const BYTE*>(aMSFileExt[ind]),
599 sal::static_int_cast<DWORD>(strlen(aMSFileExt[ind]))));
600 s.upd(RegSetValueExA(hkey, "CLSID", 0, REG_SZ,
601 reinterpret_cast<const BYTE*>(aClassID),
602 sal::static_int_cast<DWORD>(strlen(aClassID))));
603 }
604 {
605 wsprintfA(aSubKey, "%s%s", aPrefix, aMSFileExt[ind]);
606 HRegKey hkey;
607 s.upd(RegCreateKeyExA(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER,
608 aSubKey, 0, nullptr, REG_OPTION_NON_VOLATILE, nKeyAccess,
609 nullptr, &hkey, nullptr));
610 s.upd(RegSetValueExA(hkey, "Content Type", 0, REG_SZ,
611 reinterpret_cast<const BYTE*>(aMSMimeType[ind]),
612 sal::static_int_cast<DWORD>(strlen(aMSMimeType[ind]))));
613 }
614 }
615 }
616
617 wsprintfA(aSubKey, "%sCLSID\\%s", aPrefix, aClassID);
618 HRegKey hkey;
619 s.upd(RegCreateKeyExA(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, 0,
620 nullptr, REG_OPTION_NON_VOLATILE, nKeyAccess, nullptr, &hkey,
621 nullptr));
622 s.upd(createKey(hkey, "EnableFullPage", nKeyAccess));
623 for (ind = 0; ind < SUPPORTED_MSEXT_NUM; ind++)
624 {
625 if (nForMSModes[ind] & nMode)
626 {
627 wsprintfA(aSubKey, "EnableFullPage\\%s", aMSFileExt[ind]);
628 HRegKey hkey1;
629 s.upd(RegCreateKeyExA(hkey, aSubKey, 0, nullptr, REG_OPTION_NON_VOLATILE,
630 nKeyAccess, nullptr, &hkey1, nullptr));
631 }
632 }
633 }
634 catch (const std::exception&) {}
635
636 return HRESULT_FROM_WIN32(s.get());
637}
638
639EXTERN_C __declspec(dllexport) HRESULT STDAPICALLTYPE DllRegisterServerDoc( int nMode, BOOL bForAllUsers, BOOL bFor64Bit )
640{
641 HRESULT hr = S_OK;
642 if ( bFor64Bit )
644
645 if ( SUCCEEDED( hr ) )
647
648 return hr;
649}
650
651
652// DllUnregisterServerDoc - Removes entries from the system registry
653
654static HRESULT DllUnregisterServerDoc_Impl( int nMode, bool bForAllUsers, REGSAM nKeyAccess )
655{
656 char aSubKey[513];
657 const char* aPrefix = aLocalPrefix; // bForAllUsers ? "" : aLocalPrefix;
658
659 Status s(false); // no throw
660 for (int ind = 0; ind < SUPPORTED_MSEXT_NUM; ind++)
661 {
662 if (nForMSModes[ind] & nMode)
663 {
664 DWORD nSubKeys = 0, nValues = 0;
665 Status s1(false); // no throw
666 {
667 wsprintfA(aSubKey, "%sMIME\\DataBase\\Content Type\\%s", aPrefix, aMSMimeType[ind]);
668 HRegKey hkey;
669 if (s1.upd(RegCreateKeyExA(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER,
670 aSubKey, 0, nullptr, REG_OPTION_NON_VOLATILE, nKeyAccess,
671 nullptr, &hkey, nullptr)))
672 {
673 s.upd(RegDeleteValueA(hkey, "Extension"));
674 s.upd(RegDeleteValueA(hkey, "CLSID"));
675 s1.upd(RegQueryInfoKeyA(hkey, nullptr, nullptr, nullptr, &nSubKeys, nullptr,
676 nullptr, &nValues, nullptr, nullptr, nullptr, nullptr));
677 }
678 }
679 if (s1 && !nSubKeys && !nValues)
680 DeleteKeyTree(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey,
681 nKeyAccess);
682 s.upd(s1.get());
683
684 Status s2(false); // no throw
685 {
686 wsprintfA(aSubKey, "%s%s", aPrefix, aMSFileExt[ind]);
687 HRegKey hkey;
688 if (s2.upd(RegCreateKeyExA(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER,
689 aSubKey, 0, nullptr, REG_OPTION_NON_VOLATILE, nKeyAccess,
690 nullptr, &hkey, nullptr)))
691 {
692 s.upd(RegDeleteValueA(hkey, "Content Type"));
693 s2.upd(RegQueryInfoKeyA(hkey, nullptr, nullptr, nullptr, &nSubKeys, nullptr,
694 nullptr, &nValues, nullptr, nullptr, nullptr, nullptr));
695 }
696 }
697 if (s2 && !nSubKeys && !nValues)
698 DeleteKeyTree(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey,
699 nKeyAccess);
700 s.upd(s2.get());
701 }
702 }
703
704 return HRESULT_FROM_WIN32(s.get());
705}
706
708{
709 HRESULT hr = S_OK;
710 if ( bFor64Bit )
712
713 if ( SUCCEEDED( hr ) )
715
716 return hr;
717}
718
719
720// DllRegisterServer - regsvr32 entry point
721
723{
724 HRESULT aResult = E_FAIL;
725
726 HMODULE aCurModule{};
727 GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
728 | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
729 reinterpret_cast<LPCWSTR>(&DllRegisterServer), &aCurModule);
730 if( aCurModule )
731 {
732 wchar_t pProgramPath[1024];
733 wchar_t* pPathEnd = nullptr;
734 DWORD nLen = GetModuleFileNameW( aCurModule, pProgramPath, SAL_N_ELEMENTS(pProgramPath) );
735 if ( nLen && nLen < SAL_N_ELEMENTS(pProgramPath) )
736 pPathEnd = wcsrchr(pProgramPath, '\\');
737 if (pPathEnd)
738 {
739 *pPathEnd = 0;
740 aResult = DllRegisterServerNative( 31, TRUE, bX64, pProgramPath );
741 if( SUCCEEDED( aResult ) )
742 aResult = DllRegisterServerDoc( 31, TRUE, bX64 );
743 else
744 {
745 aResult = DllRegisterServerNative( 31, FALSE, bX64, pProgramPath );
746 if( SUCCEEDED( aResult ) )
747 aResult = DllRegisterServerDoc( 31, FALSE, bX64 );
748 }
749 }
750 }
751
752 return aResult;
753}
754
755
756// DllUnregisterServer - regsvr32 entry point
757
759{
763 return DllUnregisterServerNative( 63, TRUE, bX64 );
764}
765
766/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
oslInterlockedCount m_nStatus
constexpr OUStringLiteral MIMETYPE_VND_SUN_XML_WRITER_TEMPLATE_ASCII
constexpr OUStringLiteral MIMETYPE_VND_SUN_XML_DRAW_TEMPLATE_ASCII
constexpr OUStringLiteral MIMETYPE_OASIS_OPENDOCUMENT_TEXT_GLOBAL_TEMPLATE_ASCII
constexpr OUStringLiteral MIMETYPE_VND_SUN_XML_IMPRESS_ASCII
constexpr OUStringLiteral MIMETYPE_OASIS_OPENDOCUMENT_DRAWING_TEMPLATE_ASCII
constexpr OUStringLiteral MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_ASCII
constexpr OUStringLiteral MIMETYPE_VND_SUN_XML_CALC_ASCII
constexpr OUStringLiteral MIMETYPE_OASIS_OPENDOCUMENT_TEXT_ASCII
constexpr OUStringLiteral MIMETYPE_OASIS_OPENDOCUMENT_TEXT_TEMPLATE_ASCII
constexpr OUStringLiteral MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_ASCII
constexpr OUStringLiteral MIMETYPE_OASIS_OPENDOCUMENT_TEXT_GLOBAL_ASCII
constexpr OUStringLiteral MIMETYPE_VND_SUN_XML_IMPRESS_TEMPLATE_ASCII
constexpr OUStringLiteral MIMETYPE_VND_SUN_XML_WRITER_ASCII
constexpr OUStringLiteral MIMETYPE_VND_SUN_XML_WRITER_GLOBAL_ASCII
constexpr OUStringLiteral MIMETYPE_VND_SUN_XML_DRAW_ASCII
constexpr OUStringLiteral MIMETYPE_OASIS_OPENDOCUMENT_FORMULA_ASCII
constexpr OUStringLiteral MIMETYPE_OASIS_OPENDOCUMENT_TEXT_WEB_ASCII
constexpr OUStringLiteral MIMETYPE_VND_SUN_XML_CALC_TEMPLATE_ASCII
constexpr OUStringLiteral MIMETYPE_OASIS_OPENDOCUMENT_DRAWING_ASCII
constexpr OUStringLiteral MIMETYPE_VND_SUN_XML_MATH_ASCII
constexpr OUStringLiteral MIMETYPE_OASIS_OPENDOCUMENT_FORMULA_TEMPLATE_ASCII
constexpr OUStringLiteral MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_TEMPLATE_ASCII
constexpr OUStringLiteral MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_TEMPLATE_ASCII
float u
#define TRUE
#define FALSE
#define SAL_N_ELEMENTS(arr)
moOpDF operator&(moOpDF a, moOpDF b)
Status
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
const wchar_t *typedef BOOL
const char *const aInterIDActApprove
Definition: so_activex.cxx:219
const int nForMSModes[]
Definition: so_activex.cxx:568
const char *const aMSMimeType[]
Definition: so_activex.cxx:561
const char *const aInterIDDispInt
Definition: so_activex.cxx:215
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID)
Definition: so_activex.cxx:78
const REGSAM n64KeyAccess
Definition: so_activex.cxx:64
STDAPI DllUnregisterServerDoc(int nMode, BOOL bForAllUsers, BOOL bFor64Bit)
Definition: so_activex.cxx:707
#define SUPPORTED_EXT_NUM
Definition: so_activex.cxx:155
const char *const aLocalPrefix
Definition: so_activex.cxx:223
const REGSAM n32KeyAccess
Definition: so_activex.cxx:65
STDAPI DllRegisterServer()
Definition: so_activex.cxx:722
const char *const aFileExt[]
Definition: so_activex.cxx:156
STDAPI DllCanUnloadNow()
Definition: so_activex.cxx:93
const char *const aMSFileExt[]
Definition: so_activex.cxx:560
STDAPI DllUnregisterServer()
Definition: so_activex.cxx:758
static LSTATUS createKey(HKEY hkey, const char *aKeyToCreate, REGSAM nKeyAccess, const char *aValue=nullptr, const char *aChildName=nullptr, const char *aChildValue=nullptr)
Definition: so_activex.cxx:225
EXTERN_C BOOL BOOL const wchar_t * pProgramPath
Definition: so_activex.cxx:438
STDAPI DllUnregisterServerNative(int nMode, BOOL bForAllUsers, BOOL bFor64Bit)
Definition: so_activex.cxx:547
static HRESULT DllRegisterServerDoc_Impl(int nMode, bool bForAllUsers, REGSAM nKeyAccess)
Definition: so_activex.cxx:571
const char *const aClassID
Definition: so_activex.cxx:207
#define SUPPORTED_MSEXT_NUM
Definition: so_activex.cxx:559
static HRESULT DllUnregisterServerNative_Impl(int nMode, bool bForAllUsers, REGSAM nKeyAccess)
Definition: so_activex.cxx:468
#define X32_LIB_NAME
Definition: so_activex.cxx:62
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
Definition: so_activex.cxx:101
const bool bX64
Definition: so_activex.cxx:71
static HRESULT DeleteKeyTree(HKEY hkey, const char *pPath, REGSAM nKeyAccess)
Definition: so_activex.cxx:451
const int nForModes[]
Definition: so_activex.cxx:200
#define REG_DELETE_KEY_A(key, aPath, nKeyAccess)
Definition: so_activex.cxx:72
return hr
Definition: so_activex.cxx:446
CComModule _Module
Definition: so_activex.cxx:48
static HRESULT DllRegisterServerNative_Impl(int nMode, bool bForAllUsers, REGSAM nKeyAccess, const wchar_t *pProgramPath, const wchar_t *pLibName)
Definition: so_activex.cxx:272
const char *const aProxyStubDispInt
Definition: so_activex.cxx:216
EXTERN_C BOOL BOOL bFor64Bit
Definition: so_activex.cxx:271
const char *const aTypeLib
Definition: so_activex.cxx:208
const char *const aInterIDWinPeer
Definition: so_activex.cxx:211
const sal_Unicode *const aMimeType[]
Definition: so_activex.cxx:162
const char *const aProxyStubActApprove
Definition: so_activex.cxx:220
const char *const aProxyStubWinPeer
Definition: so_activex.cxx:212
EXTERN_C BOOL bForAllUsers
Definition: so_activex.cxx:271
#define X64_LIB_NAME
Definition: so_activex.cxx:61
static HRESULT DllUnregisterServerDoc_Impl(int nMode, bool bForAllUsers, REGSAM nKeyAccess)
Definition: so_activex.cxx:654
EXTERN_C __declspec(dllexport) HRESULT STDAPICALLTYPE DllUnregisterServerNative(int nMode
sal_uInt16 sal_Unicode
unsigned char BYTE