tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / extensions / source / activex / so_activex.cxx
bloba4ce480613dcc735d474f480c2251e7aaab68487
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 // so_activex.cpp : Implementation of DLL Exports.
22 // Note: Proxy/Stub Information
23 // To build a separate proxy/stub DLL,
24 // run nmake -f so_activexps.mk in the project directory.
26 #include <stdio.h>
27 #include "StdAfx2.h"
28 #include "resource.h"
29 #include <initguid.h>
30 #include <so_activex.h>
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
42 #include "SOActiveX.h"
44 #include <comphelper\documentconstants.hxx>
45 #include <sal/types.h>
46 #include <exception>
48 CComModule _Module;
50 BEGIN_OBJECT_MAP(ObjectMap)
51 OBJECT_ENTRY(CLSID_SOActiveX, CSOActiveX)
52 #if defined __clang__
53 #pragma clang diagnostic push
54 #pragma clang diagnostic ignored "-Wmissing-field-initializers"
55 #endif
56 END_OBJECT_MAP()
57 #if defined __clang__
58 #pragma clang diagnostic pop
59 #endif
61 #define X64_LIB_NAME L"so_activex_x64.dll"
62 #define X32_LIB_NAME L"so_activex.dll"
64 const REGSAM n64KeyAccess = KEY_ALL_ACCESS | KEY_WOW64_64KEY;
65 const REGSAM n32KeyAccess = KEY_ALL_ACCESS;
67 #ifdef _AMD64_
68 const bool bX64 = true;
69 #define REG_DELETE_KEY_A( key, aPath, nKeyAccess ) RegDeleteKeyExA( key, aPath, nKeyAccess, 0 )
70 #else
71 const bool bX64 = false;
72 #define REG_DELETE_KEY_A( key, aPath, nKeyAccess ) RegDeleteKeyA( key, aPath )
73 #endif
75 // DLL Entry Point
77 extern "C"
78 BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
80 if (dwReason == DLL_PROCESS_ATTACH)
82 _Module.Init(ObjectMap, hInstance, &LIBID_SO_ACTIVEXLib);
83 DisableThreadLibraryCalls(hInstance);
85 else if (dwReason == DLL_PROCESS_DETACH)
86 _Module.Term();
87 return TRUE; // ok
91 // Used to determine whether the DLL can be unloaded by OLE
93 STDAPI DllCanUnloadNow()
95 return (_Module.GetLockCount()==0) ? S_OK : S_FALSE;
99 // Returns a class factory to create an object of the requested type
101 STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
103 return _Module.GetClassObject(rclsid, riid, ppv);
107 // DllRegisterServer - Adds entries to the system registry
109 namespace
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.
114 class Status
116 public:
117 explicit Status(bool bTrow)
118 : m_bThrow(bTrow)
121 // used to check success of an operation, and update the status if it's still ERROR_SUCCESS
122 bool upd(LSTATUS nNewStatus)
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;
130 LSTATUS get() { return m_nStatus; }
131 operator bool() { return m_nStatus == ERROR_SUCCESS; }
133 private:
134 LSTATUS m_nStatus = ERROR_SUCCESS;
135 const bool m_bThrow;
138 class HRegKey
140 public:
141 ~HRegKey()
143 if (m_hkey)
144 RegCloseKey(m_hkey);
146 PHKEY operator&() { return &m_hkey; }
147 operator HKEY() { return m_hkey; }
149 private:
150 HKEY m_hkey = nullptr;
154 // for now database component and chart are always installed
155 #define SUPPORTED_EXT_NUM 30
156 const 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"};
162 const sal_Unicode* const aMimeType[] = {
163 u"application/vnd.stardivision.writer",
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",
173 MIMETYPE_VND_SUN_XML_WRITER_TEMPLATE_ASCII.getStr(),
174 MIMETYPE_VND_SUN_XML_CALC_TEMPLATE_ASCII.getStr(),
175 MIMETYPE_VND_SUN_XML_IMPRESS_TEMPLATE_ASCII.getStr(),
176 MIMETYPE_VND_SUN_XML_DRAW_TEMPLATE_ASCII.getStr(),
178 MIMETYPE_VND_SUN_XML_WRITER_ASCII.getStr(),
179 MIMETYPE_VND_SUN_XML_CALC_ASCII.getStr(),
180 MIMETYPE_VND_SUN_XML_IMPRESS_ASCII.getStr(),
181 MIMETYPE_VND_SUN_XML_DRAW_ASCII.getStr(),
182 MIMETYPE_VND_SUN_XML_WRITER_GLOBAL_ASCII.getStr(),
183 MIMETYPE_VND_SUN_XML_MATH_ASCII.getStr(),
185 MIMETYPE_OASIS_OPENDOCUMENT_TEXT_TEMPLATE_ASCII.getStr(),
186 MIMETYPE_OASIS_OPENDOCUMENT_TEXT_GLOBAL_TEMPLATE_ASCII.getStr(),
187 MIMETYPE_OASIS_OPENDOCUMENT_DRAWING_TEMPLATE_ASCII.getStr(),
188 MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_TEMPLATE_ASCII.getStr(),
189 MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_TEMPLATE_ASCII.getStr(),
190 MIMETYPE_OASIS_OPENDOCUMENT_FORMULA_TEMPLATE_ASCII.getStr(),
192 MIMETYPE_OASIS_OPENDOCUMENT_TEXT_ASCII.getStr(),
193 MIMETYPE_OASIS_OPENDOCUMENT_TEXT_WEB_ASCII.getStr(),
194 MIMETYPE_OASIS_OPENDOCUMENT_TEXT_GLOBAL_ASCII.getStr(),
195 MIMETYPE_OASIS_OPENDOCUMENT_DRAWING_ASCII.getStr(),
196 MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_ASCII.getStr(),
197 MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_ASCII.getStr(),
198 MIMETYPE_OASIS_OPENDOCUMENT_FORMULA_ASCII.getStr() };
200 const 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 };
207 const char* const aClassID = "{67F2A879-82D5-4A6D-8CC5-FFB3C114B69D}";
208 const char* const aTypeLib = "{61FA3F13-8061-4796-B055-3697ED28CB38}";
210 // ISOComWindowPeer interface information
211 const char* const aInterIDWinPeer = "{BF5D10F3-8A10-4A0B-B150-2B6AA2D7E118}";
212 const char* const aProxyStubWinPeer = "{00020424-0000-0000-C000-000000000046}";
214 // ISODispatchInterceptor interface information
215 const char* const aInterIDDispInt = "{9337694C-B27D-4384-95A4-9D8E0EABC9E5}";
216 const char* const aProxyStubDispInt = "{00020424-0000-0000-C000-000000000046}";
218 // ISOActionsApproval interface information
219 const char* const aInterIDActApprove = "{029E9F1E-2B3F-4297-9160-8197DE7ED54F}";
220 const char* const aProxyStubActApprove = "{00020424-0000-0000-C000-000000000046}";
222 // The following prefix is required for HKEY_LOCAL_MACHINE and HKEY_CURRENT_USER ( not for HKEY_CLASSES_ROOT )
223 const char* const aLocalPrefix = "Software\\Classes\\";
225 static 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 )
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)))
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))));
245 return s.get();
248 static 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 )
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)))
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))));
268 return s.get();
271 EXTERN_C __declspec(dllexport) HRESULT STDAPICALLTYPE DllUnregisterServerNative( int nMode, BOOL bForAllUsers, BOOL bFor64Bit );
272 static HRESULT DllRegisterServerNative_Impl( int nMode, bool bForAllUsers, REGSAM nKeyAccess, const wchar_t* pProgramPath, const wchar_t* pLibName )
274 char aSubKey[513];
275 int ind;
276 const char* aPrefix = aLocalPrefix; // bForAllUsers ? "" : aLocalPrefix;
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 );
284 Status s(true); // throw
287 if (pProgramPath && wcslen(pProgramPath) < 1024)
289 wchar_t pActiveXPath[1124];
290 wchar_t pActiveXPath101[1124];
292 swprintf(pActiveXPath, L"%s\\%s", pProgramPath, pLibName);
293 swprintf(pActiveXPath101, L"%s\\%s, 101", pProgramPath, pLibName);
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"));
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"));
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"));
331 s.upd(createKey(hkey, "so_activex.SOActiveX.1", nKeyAccess, "SOActiveX Class"));
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));
340 HRegKey hkey1;
341 s.upd(RegCreateKeyExA(hkey, "TypeLib", 0, nullptr, REG_OPTION_NON_VOLATILE,
342 nKeyAccess, nullptr, &hkey1, nullptr));
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"));
349 HRegKey hkey3;
350 s.upd(RegCreateKeyExA(hkey2, "1.0", 0, nullptr, REG_OPTION_NON_VOLATILE,
351 nKeyAccess, nullptr, &hkey3, nullptr));
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));
359 s.upd(createKey(hkey3, "FLAGS", nKeyAccess, "0"));
360 s.upd(createKey(hkey3, L"HELPDIR", nKeyAccess, pProgramPath));
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"));
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"));
378 s.upd(createKey(hkey1, aInterIDActApprove, nKeyAccess, "ISOActionsApproval"));
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"));
389 s.upd(createKey(hkey1, aInterIDDispInt, nKeyAccess, "ISODispatchInterceptor"));
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"));
403 for (ind = 0; ind < SUPPORTED_EXT_NUM; ind++)
405 if (nForModes[ind] & nMode)
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))));
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++)
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));
432 catch (const std::exception&) {}
434 return HRESULT_FROM_WIN32(s.get());
437 EXTERN_C __declspec(dllexport) HRESULT STDAPICALLTYPE DllRegisterServerNative( int nMode, BOOL bForAllUsers, BOOL bFor64Bit, const wchar_t* pProgramPath )
439 HRESULT hr = S_OK;
440 if ( bFor64Bit )
441 hr = DllRegisterServerNative_Impl( nMode, bForAllUsers, n64KeyAccess, pProgramPath, X64_LIB_NAME );
443 if ( SUCCEEDED( hr ) )
444 hr = DllRegisterServerNative_Impl( nMode, bForAllUsers, n32KeyAccess, pProgramPath, X32_LIB_NAME );
446 return hr;
450 // DllUnregisterServer - Removes entries from the system registry
451 static HRESULT DeleteKeyTree( HKEY hkey, const char* pPath, REGSAM nKeyAccess )
453 char pSubKeyName[256];
454 // first delete the subkeys
455 while (true)
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;
464 // delete the key itself
465 return REG_DELETE_KEY_A( hkey, pPath, nKeyAccess & ( KEY_WOW64_64KEY | KEY_WOW64_32KEY ) );
468 static HRESULT DllUnregisterServerNative_Impl( int nMode, bool bForAllUsers, REGSAM nKeyAccess )
470 char aSubKey[513];
471 const char* aPrefix = aLocalPrefix; // bForAllUsers ? "" : aLocalPrefix;
473 Status s(false); // no throw
474 for( int ind = 0; ind < SUPPORTED_EXT_NUM; ind++ )
476 if( nForModes[ind] & nMode )
478 DWORD nSubKeys = 0, nValues = 0;
479 wsprintfA(aSubKey, "%sMIME\\DataBase\\Content Type\\%ls", aPrefix, aMimeType[ind]);
480 Status s1(false); // no throw
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)))
487 s1.upd(RegDeleteValueA(hkey, "CLSID"));
488 s1.upd(RegQueryInfoKeyA(hkey, nullptr, nullptr, nullptr, &nSubKeys, nullptr,
489 nullptr, &nValues, nullptr, nullptr, nullptr, nullptr));
492 if (s1 && !nSubKeys && !nValues)
493 DeleteKeyTree(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey,
494 nKeyAccess);
495 s.upd(s1.get());
497 wsprintfA(aSubKey, "%s%s", aPrefix, aFileExt[ind]);
498 Status s2(false); // no throw
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)))
505 s2.upd(RegQueryInfoKeyA(hkey, nullptr, nullptr, nullptr, &nSubKeys, nullptr,
506 nullptr, &nValues, nullptr, nullptr, nullptr, nullptr));
509 if (s2 && !nSubKeys && !nValues)
510 DeleteKeyTree(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey,
511 nKeyAccess);
512 s.upd(s2.get());
516 wsprintfA(aSubKey, "%sCLSID\\%s", aPrefix, aClassID);
517 s.upd(DeleteKeyTree(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey,
518 nKeyAccess));
520 wsprintfA(aSubKey, "%sso_activex.SOActiveX", aPrefix);
521 s.upd(DeleteKeyTree(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey,
522 nKeyAccess));
524 wsprintfA(aSubKey, "%sso_activex.SOActiveX.1", aPrefix);
525 s.upd(DeleteKeyTree(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey,
526 nKeyAccess));
528 wsprintfA(aSubKey, "%s\\TypeLib\\%s", aPrefix, aTypeLib);
529 s.upd(DeleteKeyTree(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey,
530 nKeyAccess));
532 wsprintfA(aSubKey, "%s\\Interface\\%s", aPrefix, aInterIDWinPeer);
533 s.upd(DeleteKeyTree(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey,
534 nKeyAccess));
536 wsprintfA(aSubKey, "%s\\Interface\\%s", aPrefix, aInterIDDispInt);
537 s.upd(DeleteKeyTree(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey,
538 nKeyAccess));
540 wsprintfA(aSubKey, "%s\\Interface\\%s", aPrefix, aInterIDActApprove);
541 s.upd(DeleteKeyTree(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey,
542 nKeyAccess));
544 return HRESULT_FROM_WIN32(s.get());
547 STDAPI DllUnregisterServerNative( int nMode, BOOL bForAllUsers, BOOL bFor64Bit )
549 HRESULT hr = DllUnregisterServerNative_Impl( nMode, bForAllUsers, n32KeyAccess );
550 if ( SUCCEEDED( hr ) && bFor64Bit )
551 hr = DllUnregisterServerNative_Impl( nMode, bForAllUsers, n64KeyAccess );
553 return hr;
557 // DllRegisterServerDoc - Adds entries to the system registry
559 #define SUPPORTED_MSEXT_NUM 7
560 const char* const aMSFileExt[] = { ".dot", ".doc", ".xlt", ".xls", ".pot", ".ppt", ".pps" };
561 const 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" };
568 const int nForMSModes[] = { 1, 1, 2, 2, 4, 4, 4 };
570 EXTERN_C __declspec(dllexport) HRESULT STDAPICALLTYPE DllUnregisterServerDoc( int nMode, BOOL bForAllUsers, BOOL bFor64Bit );
571 static HRESULT DllRegisterServerDoc_Impl( int nMode, bool bForAllUsers, REGSAM nKeyAccess )
573 char aSubKey[513];
574 int ind;
575 const char* aPrefix = aLocalPrefix; // bForAllUsers ? "" : aLocalPrefix;
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 );
583 Status s(true); // throw
586 for (ind = 0; ind < SUPPORTED_MSEXT_NUM; ind++)
588 if (nForMSModes[ind] & nMode)
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))));
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]))));
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++)
625 if (nForMSModes[ind] & nMode)
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));
634 catch (const std::exception&) {}
636 return HRESULT_FROM_WIN32(s.get());
639 EXTERN_C __declspec(dllexport) HRESULT STDAPICALLTYPE DllRegisterServerDoc( int nMode, BOOL bForAllUsers, BOOL bFor64Bit )
641 HRESULT hr = S_OK;
642 if ( bFor64Bit )
643 hr = DllRegisterServerDoc_Impl( nMode, bForAllUsers, n64KeyAccess );
645 if ( SUCCEEDED( hr ) )
646 hr = DllRegisterServerDoc_Impl( nMode, bForAllUsers, n32KeyAccess );
648 return hr;
652 // DllUnregisterServerDoc - Removes entries from the system registry
654 static HRESULT DllUnregisterServerDoc_Impl( int nMode, bool bForAllUsers, REGSAM nKeyAccess )
656 char aSubKey[513];
657 const char* aPrefix = aLocalPrefix; // bForAllUsers ? "" : aLocalPrefix;
659 Status s(false); // no throw
660 for (int ind = 0; ind < SUPPORTED_MSEXT_NUM; ind++)
662 if (nForMSModes[ind] & nMode)
664 DWORD nSubKeys = 0, nValues = 0;
665 Status s1(false); // no throw
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)))
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));
679 if (s1 && !nSubKeys && !nValues)
680 DeleteKeyTree(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey,
681 nKeyAccess);
682 s.upd(s1.get());
684 Status s2(false); // no throw
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)))
692 s.upd(RegDeleteValueA(hkey, "Content Type"));
693 s2.upd(RegQueryInfoKeyA(hkey, nullptr, nullptr, nullptr, &nSubKeys, nullptr,
694 nullptr, &nValues, nullptr, nullptr, nullptr, nullptr));
697 if (s2 && !nSubKeys && !nValues)
698 DeleteKeyTree(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey,
699 nKeyAccess);
700 s.upd(s2.get());
704 return HRESULT_FROM_WIN32(s.get());
707 STDAPI DllUnregisterServerDoc( int nMode, BOOL bForAllUsers, BOOL bFor64Bit )
709 HRESULT hr = S_OK;
710 if ( bFor64Bit )
711 hr = DllUnregisterServerDoc_Impl( nMode, bForAllUsers, n64KeyAccess );
713 if ( SUCCEEDED( hr ) )
714 hr = DllUnregisterServerDoc_Impl( nMode, bForAllUsers, n32KeyAccess );
716 return hr;
720 // DllRegisterServer - regsvr32 entry point
722 STDAPI DllRegisterServer()
724 HRESULT aResult = E_FAIL;
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 )
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)
739 *pPathEnd = 0;
740 aResult = DllRegisterServerNative( 31, TRUE, bX64, pProgramPath );
741 if( SUCCEEDED( aResult ) )
742 aResult = DllRegisterServerDoc( 31, TRUE, bX64 );
743 else
745 aResult = DllRegisterServerNative( 31, FALSE, bX64, pProgramPath );
746 if( SUCCEEDED( aResult ) )
747 aResult = DllRegisterServerDoc( 31, FALSE, bX64 );
752 return aResult;
756 // DllUnregisterServer - regsvr32 entry point
758 STDAPI DllUnregisterServer()
760 DllUnregisterServerDoc( 63, FALSE, bX64 );
761 DllUnregisterServerNative( 63, FALSE, bX64 );
762 DllUnregisterServerDoc( 63, TRUE, bX64 );
763 return DllUnregisterServerNative( 63, TRUE, bX64 );
766 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */