1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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.
32 #pragma clang diagnostic push
33 #pragma clang diagnostic ignored "-Wnon-virtual-dtor"
35 #include <so_activex.h>
37 #pragma clang diagnostic pop
41 #pragma clang diagnostic push
42 #pragma clang diagnostic ignored "-Wextra-tokens"
43 // "#endif !_MIDL_USE_GUIDDEF_" in midl-generated code
45 #include <so_activex_i.c>
47 #pragma clang diagnostic pop
50 #include "SOActiveX.h"
52 #include <comphelper\documentconstants.hxx>
57 BEGIN_OBJECT_MAP(ObjectMap
)
58 OBJECT_ENTRY(CLSID_SOActiveX
, CSOActiveX
)
60 #pragma clang diagnostic push
61 #pragma clang diagnostic ignored "-Wmissing-field-initializers"
65 #pragma clang diagnostic pop
68 #define X64_LIB_NAME L"so_activex_x64.dll"
69 #define X32_LIB_NAME L"so_activex.dll"
71 // to provide windows xp as build systems for mingw we need to define KEY_WOW64_64KEY
72 // in mingw 3.13 KEY_WOW64_64KEY isn't available < Win2003 systems.
73 // Also defined in setup_native\source\win32\customactions\reg64\reg64.cxx,source\win32\customactions\shellextensions\shellextensions.cxx and
74 // extensions\source\activex\main\so_activex.cpp
75 #ifndef KEY_WOW64_64KEY
76 #define KEY_WOW64_64KEY (0x0100)
78 #ifndef KEY_WOW64_32KEY
79 #define KEY_WOW64_32KEY (0x0200)
82 const REGSAM n64KeyAccess
= KEY_ALL_ACCESS
| KEY_WOW64_64KEY
;
83 const REGSAM n32KeyAccess
= KEY_ALL_ACCESS
;
86 const bool bX64
= true;
87 #define REG_DELETE_KEY_A( key, aPath, nKeyAccess ) RegDeleteKeyExA( key, aPath, nKeyAccess, 0 )
89 const bool bX64
= false;
90 #define REG_DELETE_KEY_A( key, aPath, nKeyAccess ) RegDeleteKeyA( key, aPath )
96 BOOL WINAPI
DllMain(HINSTANCE hInstance
, DWORD dwReason
, LPVOID
/*lpReserved*/)
98 if (dwReason
== DLL_PROCESS_ATTACH
)
100 _Module
.Init(ObjectMap
, hInstance
, &LIBID_SO_ACTIVEXLib
);
101 DisableThreadLibraryCalls(hInstance
);
103 else if (dwReason
== DLL_PROCESS_DETACH
)
109 // Used to determine whether the DLL can be unloaded by OLE
111 STDAPI
DllCanUnloadNow()
113 return (_Module
.GetLockCount()==0) ? S_OK
: S_FALSE
;
117 // Returns a class factory to create an object of the requested type
119 STDAPI
DllGetClassObject(REFCLSID rclsid
, REFIID riid
, LPVOID
* ppv
)
121 return _Module
.GetClassObject(rclsid
, riid
, ppv
);
125 // DllRegisterServer - Adds entries to the system registry
129 // Wraps an updatable Win32 error; keeps first incoming error.
130 // Ctor defines if upd will throw std::exception on error or
135 explicit Status(bool bTrow
)
139 // used to check success of an operation, and update the status if it's still ERROR_SUCCESS
140 bool upd(LSTATUS nNewStatus
)
142 if (m_nStatus
== ERROR_SUCCESS
)
143 m_nStatus
= nNewStatus
;
144 if (m_bThrow
&& nNewStatus
!= ERROR_SUCCESS
)
145 throw std::exception();
146 return nNewStatus
== ERROR_SUCCESS
;
148 LSTATUS
get() { return m_nStatus
; }
149 operator bool() { return m_nStatus
== ERROR_SUCCESS
; }
152 LSTATUS m_nStatus
= ERROR_SUCCESS
;
164 PHKEY
operator&() { return &m_hkey
; }
165 operator HKEY() { return m_hkey
; }
168 HKEY m_hkey
= nullptr;
172 // for now database component and chart are always installed
173 #define SUPPORTED_EXT_NUM 30
174 const char* const aFileExt
[] = { ".vor",
175 ".sds", ".sda", ".sdd", ".sdp", ".sdc", ".sdw", ".smf",
176 ".stw", ".stc", ".sti", ".std",
177 ".sxw", ".sxc", ".sxi", ".sxd", ".sxg", ".sxm",
178 ".ott", ".otg", ".otp", ".ots", ".otf",
179 ".odt", ".oth", ".odm", ".odg", ".odp", ".ods", ".odf"};
180 const char* const aMimeType
[] = {
181 "application/vnd.stardivision.writer",
183 "application/vnd.stardivision.chart",
184 "application/vnd.stardivision.draw",
185 "application/vnd.stardivision.impress",
186 "application/vnd.stardivision.impress-packed",
187 "application/vnd.stardivision.calc",
188 "application/vnd.stardivision.writer",
189 "application/vnd.stardivision.math",
191 MIMETYPE_VND_SUN_XML_WRITER_TEMPLATE_ASCII
,
192 MIMETYPE_VND_SUN_XML_CALC_TEMPLATE_ASCII
,
193 MIMETYPE_VND_SUN_XML_IMPRESS_TEMPLATE_ASCII
,
194 MIMETYPE_VND_SUN_XML_DRAW_TEMPLATE_ASCII
,
196 MIMETYPE_VND_SUN_XML_WRITER_ASCII
,
197 MIMETYPE_VND_SUN_XML_CALC_ASCII
,
198 MIMETYPE_VND_SUN_XML_IMPRESS_ASCII
,
199 MIMETYPE_VND_SUN_XML_DRAW_ASCII
,
200 MIMETYPE_VND_SUN_XML_WRITER_GLOBAL_ASCII
,
201 MIMETYPE_VND_SUN_XML_MATH_ASCII
,
203 MIMETYPE_OASIS_OPENDOCUMENT_TEXT_TEMPLATE_ASCII
,
204 MIMETYPE_OASIS_OPENDOCUMENT_TEXT_GLOBAL_TEMPLATE_ASCII
,
205 MIMETYPE_OASIS_OPENDOCUMENT_DRAWING_TEMPLATE_ASCII
,
206 MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_TEMPLATE_ASCII
,
207 MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_TEMPLATE_ASCII
,
208 MIMETYPE_OASIS_OPENDOCUMENT_FORMULA_TEMPLATE_ASCII
,
210 MIMETYPE_OASIS_OPENDOCUMENT_TEXT_ASCII
,
211 MIMETYPE_OASIS_OPENDOCUMENT_TEXT_WEB_ASCII
,
212 MIMETYPE_OASIS_OPENDOCUMENT_TEXT_GLOBAL_ASCII
,
213 MIMETYPE_OASIS_OPENDOCUMENT_DRAWING_ASCII
,
214 MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_ASCII
,
215 MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_ASCII
,
216 MIMETYPE_OASIS_OPENDOCUMENT_FORMULA_ASCII
};
218 const int nForModes
[] = { 16,
219 1, 2, 4, 4, 8, 16, 32,
223 16, 16, 16, 2, 4, 8, 32 };
225 const char* const aClassID
= "{67F2A879-82D5-4A6D-8CC5-FFB3C114B69D}";
226 const char* const aTypeLib
= "{61FA3F13-8061-4796-B055-3697ED28CB38}";
228 // ISOComWindowPeer interface information
229 const char* const aInterIDWinPeer
= "{BF5D10F3-8A10-4A0B-B150-2B6AA2D7E118}";
230 const char* const aProxyStubWinPeer
= "{00020424-0000-0000-C000-000000000046}";
232 // ISODispatchInterceptor interface information
233 const char* const aInterIDDispInt
= "{9337694C-B27D-4384-95A4-9D8E0EABC9E5}";
234 const char* const aProxyStubDispInt
= "{00020424-0000-0000-C000-000000000046}";
236 // ISOActionsApproval interface information
237 const char* const aInterIDActApprove
= "{029E9F1E-2B3F-4297-9160-8197DE7ED54F}";
238 const char* const aProxyStubActApprove
= "{00020424-0000-0000-C000-000000000046}";
240 // The following prefix is required for HKEY_LOCAL_MACHINE and HKEY_CURRENT_USER ( not for HKEY_CLASSES_ROOT )
241 const char* const aLocalPrefix
= "Software\\Classes\\";
243 static LSTATUS
createKey( HKEY hkey
,
244 const char* aKeyToCreate
,
246 const char* aValue
= nullptr,
247 const char* aChildName
= nullptr,
248 const char* aChildValue
= nullptr )
250 Status
s(false); // no throw
252 if (s
.upd(RegCreateKeyExA(hkey
, aKeyToCreate
, 0, nullptr, REG_OPTION_NON_VOLATILE
, nKeyAccess
,
253 nullptr, &hkey1
, nullptr)))
256 s
.upd(RegSetValueExA(hkey1
, "", 0, REG_SZ
, reinterpret_cast<const BYTE
*>(aValue
),
257 sal::static_int_cast
<DWORD
>(strlen(aValue
))));
259 s
.upd(RegSetValueExA(hkey1
, aChildName
, 0, REG_SZ
,
260 reinterpret_cast<const BYTE
*>(aChildValue
),
261 sal::static_int_cast
<DWORD
>(strlen(aChildValue
))));
266 static LSTATUS
createKey(HKEY hkey
,
267 const wchar_t* aKeyToCreate
,
269 const wchar_t* aValue
= nullptr,
270 const wchar_t* aChildName
= nullptr,
271 const wchar_t* aChildValue
= nullptr )
273 Status
s(false); // no throw
275 if (s
.upd(RegCreateKeyExW(hkey
, aKeyToCreate
, 0, nullptr, REG_OPTION_NON_VOLATILE
, nKeyAccess
,
276 nullptr, &hkey1
, nullptr)))
279 s
.upd(RegSetValueExW(hkey1
, L
"", 0, REG_SZ
, reinterpret_cast<const BYTE
*>(aValue
),
280 sal::static_int_cast
<DWORD
>(wcslen(aValue
) * sizeof(wchar_t))));
282 s
.upd(RegSetValueExW(
283 hkey1
, aChildName
, 0, REG_SZ
, reinterpret_cast<const BYTE
*>(aChildValue
),
284 sal::static_int_cast
<DWORD
>(wcslen(aChildValue
) * sizeof(wchar_t))));
289 EXTERN_C
__declspec(dllexport
) HRESULT STDAPICALLTYPE
DllUnregisterServerNative( int nMode
, BOOL bForAllUsers
, BOOL bFor64Bit
);
290 static HRESULT
DllRegisterServerNative_Impl( int nMode
, BOOL bForAllUsers
, REGSAM nKeyAccess
, const wchar_t* pProgramPath
, const wchar_t* pLibName
)
294 const char* aPrefix
= aLocalPrefix
; // bForAllUsers ? "" : aLocalPrefix;
296 // In case SO7 is installed for this user he can have local registry entries that will prevent him from
297 // using SO8 ActiveX control. The fix is just to clean up the local entries related to ActiveX control.
298 // Unfortunately it can be done only for the user who installs the office.
300 DllUnregisterServerNative( nMode
, false, false );
302 Status
s(true); // throw
305 if (pProgramPath
&& wcslen(pProgramPath
) < 1024)
307 wchar_t pActiveXPath
[1124];
308 wchar_t pActiveXPath101
[1124];
310 swprintf(pActiveXPath
, L
"%s\\%s", pProgramPath
, pLibName
);
311 swprintf(pActiveXPath101
, L
"%s\\%s, 101", pProgramPath
, pLibName
);
314 wsprintfA(aSubKey
, "%sCLSID\\%s", aPrefix
, aClassID
);
316 s
.upd(RegCreateKeyExA(bForAllUsers
? HKEY_LOCAL_MACHINE
: HKEY_CURRENT_USER
,
317 aSubKey
, 0, nullptr, REG_OPTION_NON_VOLATILE
, nKeyAccess
,
318 nullptr, &hkey
, nullptr));
319 s
.upd(RegSetValueExA(hkey
, "", 0, REG_SZ
,
320 reinterpret_cast<const BYTE
*>("SOActiveX Class"), 17));
321 s
.upd(createKey(hkey
, "Control", nKeyAccess
));
322 s
.upd(createKey(hkey
, "EnableFullPage", nKeyAccess
));
323 s
.upd(createKey(hkey
, L
"InprocServer32", nKeyAccess
, pActiveXPath
,
324 L
"ThreadingModel", L
"Apartment"));
325 s
.upd(createKey(hkey
, "MiscStatus", nKeyAccess
, "0"));
326 s
.upd(createKey(hkey
, "MiscStatus\\1", nKeyAccess
, "131473"));
327 s
.upd(createKey(hkey
, "ProgID", nKeyAccess
, "so_activex.SOActiveX.1"));
328 s
.upd(createKey(hkey
, "Programmable", nKeyAccess
));
329 s
.upd(createKey(hkey
, L
"ToolboxBitmap32", nKeyAccess
, pActiveXPath101
));
330 s
.upd(createKey(hkey
, "TypeLib", nKeyAccess
, aTypeLib
));
331 s
.upd(createKey(hkey
, "Version", nKeyAccess
, "1.0"));
332 s
.upd(createKey(hkey
, "VersionIndependentProgID", nKeyAccess
,
333 "so_activex.SOActiveX"));
337 s
.upd(RegCreateKeyExA(bForAllUsers
? HKEY_LOCAL_MACHINE
: HKEY_CURRENT_USER
,
338 aPrefix
, 0, nullptr, REG_OPTION_NON_VOLATILE
, nKeyAccess
,
339 nullptr, &hkey
, nullptr));
340 s
.upd(createKey(hkey
, "so_activex.SOActiveX", nKeyAccess
, "SOActiveX Class"));
343 s
.upd(RegCreateKeyExA(hkey
, "so_activex.SOActiveX", 0, nullptr,
344 REG_OPTION_NON_VOLATILE
, nKeyAccess
, nullptr, &hkey1
,
346 s
.upd(createKey(hkey1
, "CLSID", nKeyAccess
, aClassID
));
347 s
.upd(createKey(hkey1
, "CurVer", nKeyAccess
, "so_activex.SOActiveX.1"));
349 s
.upd(createKey(hkey
, "so_activex.SOActiveX.1", nKeyAccess
, "SOActiveX Class"));
352 s
.upd(RegCreateKeyExA(hkey
, "so_activex.SOActiveX.1", 0, nullptr,
353 REG_OPTION_NON_VOLATILE
, nKeyAccess
, nullptr, &hkey1
,
355 s
.upd(createKey(hkey1
, "CLSID", nKeyAccess
, aClassID
));
359 s
.upd(RegCreateKeyExA(hkey
, "TypeLib", 0, nullptr, REG_OPTION_NON_VOLATILE
,
360 nKeyAccess
, nullptr, &hkey1
, nullptr));
363 s
.upd(RegCreateKeyExA(hkey1
, aTypeLib
, 0, nullptr, REG_OPTION_NON_VOLATILE
,
364 nKeyAccess
, nullptr, &hkey2
, nullptr));
365 s
.upd(createKey(hkey2
, "1.0", nKeyAccess
, "wrap_activex 1.0 Type Library"));
368 s
.upd(RegCreateKeyExA(hkey2
, "1.0", 0, nullptr, REG_OPTION_NON_VOLATILE
,
369 nKeyAccess
, nullptr, &hkey3
, nullptr));
372 s
.upd(RegCreateKeyExA(hkey3
, "0", 0, nullptr,
373 REG_OPTION_NON_VOLATILE
, nKeyAccess
, nullptr,
375 s
.upd(createKey(hkey4
, L
"win32", nKeyAccess
, pActiveXPath
));
377 s
.upd(createKey(hkey3
, "FLAGS", nKeyAccess
, "0"));
378 s
.upd(createKey(hkey3
, L
"HELPDIR", nKeyAccess
, pProgramPath
));
384 s
.upd(RegCreateKeyExA(hkey
, "Interface", 0, nullptr, REG_OPTION_NON_VOLATILE
,
385 nKeyAccess
, nullptr, &hkey1
, nullptr));
386 s
.upd(createKey(hkey1
, aInterIDWinPeer
, nKeyAccess
, "ISOComWindowPeer"));
389 s
.upd(RegCreateKeyExA(hkey1
, aInterIDWinPeer
, 0, nullptr,
390 REG_OPTION_NON_VOLATILE
, nKeyAccess
, nullptr, &hkey2
,
392 s
.upd(createKey(hkey2
, "ProxyStubClsid", nKeyAccess
, aProxyStubWinPeer
));
393 s
.upd(createKey(hkey2
, "ProxyStubClsid32", nKeyAccess
, aProxyStubWinPeer
));
394 s
.upd(createKey(hkey2
, "TypeLib", nKeyAccess
, aTypeLib
, "Version", "1.0"));
396 s
.upd(createKey(hkey1
, aInterIDActApprove
, nKeyAccess
, "ISOActionsApproval"));
399 s
.upd(RegCreateKeyExA(hkey1
, aInterIDActApprove
, 0, nullptr,
400 REG_OPTION_NON_VOLATILE
, nKeyAccess
, nullptr, &hkey2
,
402 s
.upd(createKey(hkey2
, "ProxyStubClsid", nKeyAccess
, aProxyStubActApprove
));
404 createKey(hkey2
, "ProxyStubClsid32", nKeyAccess
, aProxyStubActApprove
));
405 s
.upd(createKey(hkey2
, "TypeLib", nKeyAccess
, aTypeLib
, "Version", "1.0"));
407 s
.upd(createKey(hkey1
, aInterIDDispInt
, nKeyAccess
, "ISODispatchInterceptor"));
410 s
.upd(RegCreateKeyExA(hkey1
, aInterIDDispInt
, 0, nullptr,
411 REG_OPTION_NON_VOLATILE
, nKeyAccess
, nullptr, &hkey2
,
413 s
.upd(createKey(hkey2
, "ProxyStubClsid", nKeyAccess
, aProxyStubDispInt
));
414 s
.upd(createKey(hkey2
, "ProxyStubClsid32", nKeyAccess
, aProxyStubDispInt
));
415 s
.upd(createKey(hkey2
, "TypeLib", nKeyAccess
, aTypeLib
, "Version", "1.0"));
421 for (ind
= 0; ind
< SUPPORTED_EXT_NUM
; ind
++)
423 if (nForModes
[ind
] & nMode
)
425 wsprintfA(aSubKey
, "%sMIME\\DataBase\\Content Type\\%s", aPrefix
, aMimeType
[ind
]);
427 s
.upd(RegCreateKeyExA(bForAllUsers
? HKEY_LOCAL_MACHINE
: HKEY_CURRENT_USER
,
428 aSubKey
, 0, nullptr, REG_OPTION_NON_VOLATILE
, nKeyAccess
,
429 nullptr, &hkey
, nullptr));
430 s
.upd(RegSetValueExA(hkey
, "CLSID", 0, REG_SZ
,
431 reinterpret_cast<const BYTE
*>(aClassID
),
432 sal::static_int_cast
<DWORD
>(strlen(aClassID
))));
437 wsprintfA(aSubKey
, "%sCLSID\\%s", aPrefix
, aClassID
);
439 s
.upd(RegOpenKeyExA(bForAllUsers
? HKEY_LOCAL_MACHINE
: HKEY_CURRENT_USER
, aSubKey
, 0,
441 for (ind
= 0; ind
< SUPPORTED_EXT_NUM
; ind
++)
443 wsprintfA(aSubKey
, "EnableFullPage\\%s", aFileExt
[ind
]);
445 s
.upd(RegCreateKeyExA(hkey
, aSubKey
, 0, nullptr, REG_OPTION_NON_VOLATILE
,
446 nKeyAccess
, nullptr, &hkey1
, nullptr));
450 catch (const std::exception
&) {}
452 return HRESULT_FROM_WIN32(s
.get());
455 EXTERN_C
__declspec(dllexport
) HRESULT STDAPICALLTYPE
DllRegisterServerNative( int nMode
, BOOL bForAllUsers
, BOOL bFor64Bit
, const wchar_t* pProgramPath
)
459 hr
= DllRegisterServerNative_Impl( nMode
, bForAllUsers
, n64KeyAccess
, pProgramPath
, X64_LIB_NAME
);
461 if ( SUCCEEDED( hr
) )
462 hr
= DllRegisterServerNative_Impl( nMode
, bForAllUsers
, n32KeyAccess
, pProgramPath
, X32_LIB_NAME
);
468 // DllUnregisterServer - Removes entries from the system registry
469 static HRESULT
DeleteKeyTree( HKEY hkey
, const char* pPath
, REGSAM nKeyAccess
)
471 char pSubKeyName
[256];
472 // first delete the subkeys
476 if (ERROR_SUCCESS
!= RegOpenKeyExA(hkey
, pPath
, 0, nKeyAccess
, &hkey1
)
477 || ERROR_SUCCESS
!= RegEnumKeyA(hkey1
, 0, pSubKeyName
, 256)
478 || ERROR_SUCCESS
!= DeleteKeyTree(hkey1
, pSubKeyName
, nKeyAccess
))
482 // delete the key itself
483 return REG_DELETE_KEY_A( hkey
, pPath
, nKeyAccess
& ( KEY_WOW64_64KEY
| KEY_WOW64_32KEY
) );
486 static HRESULT
DllUnregisterServerNative_Impl( int nMode
, BOOL bForAllUsers
, REGSAM nKeyAccess
)
489 const char* aPrefix
= aLocalPrefix
; // bForAllUsers ? "" : aLocalPrefix;
491 Status
s(false); // no throw
492 for( int ind
= 0; ind
< SUPPORTED_EXT_NUM
; ind
++ )
494 if( nForModes
[ind
] & nMode
)
496 DWORD nSubKeys
= 0, nValues
= 0;
497 wsprintfA(aSubKey
, "%sMIME\\DataBase\\Content Type\\%s", aPrefix
, aMimeType
[ind
]);
498 Status
s1(false); // no throw
501 if (s1
.upd(RegCreateKeyExA(bForAllUsers
? HKEY_LOCAL_MACHINE
: HKEY_CURRENT_USER
,
502 aSubKey
, 0, nullptr, REG_OPTION_NON_VOLATILE
, nKeyAccess
,
503 nullptr, &hkey
, nullptr)))
505 s1
.upd(RegDeleteValueA(hkey
, "CLSID"));
506 s1
.upd(RegQueryInfoKeyA(hkey
, nullptr, nullptr, nullptr, &nSubKeys
, nullptr,
507 nullptr, &nValues
, nullptr, nullptr, nullptr, nullptr));
510 if (s1
&& !nSubKeys
&& !nValues
)
511 DeleteKeyTree(bForAllUsers
? HKEY_LOCAL_MACHINE
: HKEY_CURRENT_USER
, aSubKey
,
515 wsprintfA(aSubKey
, "%s%s", aPrefix
, aFileExt
[ind
]);
516 Status
s2(false); // no throw
519 if (s2
.upd(RegCreateKeyExA(bForAllUsers
? HKEY_LOCAL_MACHINE
: HKEY_CURRENT_USER
,
520 aSubKey
, 0, nullptr, REG_OPTION_NON_VOLATILE
, nKeyAccess
,
521 nullptr, &hkey
, nullptr)))
523 s2
.upd(RegQueryInfoKeyA(hkey
, nullptr, nullptr, nullptr, &nSubKeys
, nullptr,
524 nullptr, &nValues
, nullptr, nullptr, nullptr, nullptr));
527 if (s2
&& !nSubKeys
&& !nValues
)
528 DeleteKeyTree(bForAllUsers
? HKEY_LOCAL_MACHINE
: HKEY_CURRENT_USER
, aSubKey
,
534 wsprintfA(aSubKey
, "%sCLSID\\%s", aPrefix
, aClassID
);
535 s
.upd(DeleteKeyTree(bForAllUsers
? HKEY_LOCAL_MACHINE
: HKEY_CURRENT_USER
, aSubKey
,
538 wsprintfA(aSubKey
, "%sso_activex.SOActiveX", aPrefix
);
539 s
.upd(DeleteKeyTree(bForAllUsers
? HKEY_LOCAL_MACHINE
: HKEY_CURRENT_USER
, aSubKey
,
542 wsprintfA(aSubKey
, "%sso_activex.SOActiveX.1", aPrefix
);
543 s
.upd(DeleteKeyTree(bForAllUsers
? HKEY_LOCAL_MACHINE
: HKEY_CURRENT_USER
, aSubKey
,
546 wsprintfA(aSubKey
, "%s\\TypeLib\\%s", aPrefix
, aTypeLib
);
547 s
.upd(DeleteKeyTree(bForAllUsers
? HKEY_LOCAL_MACHINE
: HKEY_CURRENT_USER
, aSubKey
,
550 wsprintfA(aSubKey
, "%s\\Interface\\%s", aPrefix
, aInterIDWinPeer
);
551 s
.upd(DeleteKeyTree(bForAllUsers
? HKEY_LOCAL_MACHINE
: HKEY_CURRENT_USER
, aSubKey
,
554 wsprintfA(aSubKey
, "%s\\Interface\\%s", aPrefix
, aInterIDDispInt
);
555 s
.upd(DeleteKeyTree(bForAllUsers
? HKEY_LOCAL_MACHINE
: HKEY_CURRENT_USER
, aSubKey
,
558 wsprintfA(aSubKey
, "%s\\Interface\\%s", aPrefix
, aInterIDActApprove
);
559 s
.upd(DeleteKeyTree(bForAllUsers
? HKEY_LOCAL_MACHINE
: HKEY_CURRENT_USER
, aSubKey
,
562 return HRESULT_FROM_WIN32(s
.get());
565 STDAPI
DllUnregisterServerNative( int nMode
, BOOL bForAllUsers
, BOOL bFor64Bit
)
567 HRESULT hr
= DllUnregisterServerNative_Impl( nMode
, bForAllUsers
, n32KeyAccess
);
568 if ( SUCCEEDED( hr
) && bFor64Bit
)
569 hr
= DllUnregisterServerNative_Impl( nMode
, bForAllUsers
, n64KeyAccess
);
575 // DllRegisterServerDoc - Adds entries to the system registry
577 #define SUPPORTED_MSEXT_NUM 7
578 const char* const aMSFileExt
[] = { ".dot", ".doc", ".xlt", ".xls", ".pot", ".ppt", ".pps" };
579 const char* const aMSMimeType
[] = { "application/msword",
580 "application/msword",
581 "application/vnd.ms-excel",
582 "application/vnd.ms-excel",
583 "application/vnd.ms-powerpoint",
584 "application/vnd.ms-powerpoint",
585 "application/vnd.ms-powerpoint" };
586 const int nForMSModes
[] = { 1, 1, 2, 2, 4, 4, 4 };
588 EXTERN_C
__declspec(dllexport
) HRESULT STDAPICALLTYPE
DllUnregisterServerDoc( int nMode
, BOOL bForAllUsers
, BOOL bFor64Bit
);
589 static HRESULT
DllRegisterServerDoc_Impl( int nMode
, BOOL bForAllUsers
, REGSAM nKeyAccess
)
593 const char* aPrefix
= aLocalPrefix
; // bForAllUsers ? "" : aLocalPrefix;
595 // In case SO7 is installed for this user he can have local registry entries that will prevent him from
596 // using SO8 ActiveX control. The fix is just to clean up the local entries related to ActiveX control.
597 // Unfortunately it can be done only for the user who installs the office.
599 DllUnregisterServerDoc( nMode
, false, false );
601 Status
s(true); // throw
604 for (ind
= 0; ind
< SUPPORTED_MSEXT_NUM
; ind
++)
606 if (nForMSModes
[ind
] & nMode
)
609 wsprintfA(aSubKey
, "%sMIME\\DataBase\\Content Type\\%s", aPrefix
,
612 s
.upd(RegCreateKeyExA(bForAllUsers
? HKEY_LOCAL_MACHINE
: HKEY_CURRENT_USER
,
613 aSubKey
, 0, nullptr, REG_OPTION_NON_VOLATILE
, nKeyAccess
,
614 nullptr, &hkey
, nullptr));
615 s
.upd(RegSetValueExA(hkey
, "Extension", 0, REG_SZ
,
616 reinterpret_cast<const BYTE
*>(aMSFileExt
[ind
]),
617 sal::static_int_cast
<DWORD
>(strlen(aMSFileExt
[ind
]))));
618 s
.upd(RegSetValueExA(hkey
, "CLSID", 0, REG_SZ
,
619 reinterpret_cast<const BYTE
*>(aClassID
),
620 sal::static_int_cast
<DWORD
>(strlen(aClassID
))));
623 wsprintfA(aSubKey
, "%s%s", aPrefix
, aMSFileExt
[ind
]);
625 s
.upd(RegCreateKeyExA(bForAllUsers
? HKEY_LOCAL_MACHINE
: HKEY_CURRENT_USER
,
626 aSubKey
, 0, nullptr, REG_OPTION_NON_VOLATILE
, nKeyAccess
,
627 nullptr, &hkey
, nullptr));
628 s
.upd(RegSetValueExA(hkey
, "Content Type", 0, REG_SZ
,
629 reinterpret_cast<const BYTE
*>(aMSMimeType
[ind
]),
630 sal::static_int_cast
<DWORD
>(strlen(aMSMimeType
[ind
]))));
635 wsprintfA(aSubKey
, "%sCLSID\\%s", aPrefix
, aClassID
);
637 s
.upd(RegCreateKeyExA(bForAllUsers
? HKEY_LOCAL_MACHINE
: HKEY_CURRENT_USER
, aSubKey
, 0,
638 nullptr, REG_OPTION_NON_VOLATILE
, nKeyAccess
, nullptr, &hkey
,
640 s
.upd(createKey(hkey
, "EnableFullPage", nKeyAccess
));
641 for (ind
= 0; ind
< SUPPORTED_MSEXT_NUM
; ind
++)
643 if (nForMSModes
[ind
] & nMode
)
645 wsprintfA(aSubKey
, "EnableFullPage\\%s", aMSFileExt
[ind
]);
647 s
.upd(RegCreateKeyExA(hkey
, aSubKey
, 0, nullptr, REG_OPTION_NON_VOLATILE
,
648 nKeyAccess
, nullptr, &hkey1
, nullptr));
652 catch (const std::exception
&) {}
654 return HRESULT_FROM_WIN32(s
.get());
657 EXTERN_C
__declspec(dllexport
) HRESULT STDAPICALLTYPE
DllRegisterServerDoc( int nMode
, BOOL bForAllUsers
, BOOL bFor64Bit
)
661 hr
= DllRegisterServerDoc_Impl( nMode
, bForAllUsers
, n64KeyAccess
);
663 if ( SUCCEEDED( hr
) )
664 hr
= DllRegisterServerDoc_Impl( nMode
, bForAllUsers
, n32KeyAccess
);
670 // DllUnregisterServerDoc - Removes entries from the system registry
672 static HRESULT
DllUnregisterServerDoc_Impl( int nMode
, BOOL bForAllUsers
, REGSAM nKeyAccess
)
675 const char* aPrefix
= aLocalPrefix
; // bForAllUsers ? "" : aLocalPrefix;
677 Status
s(false); // no throw
678 for (int ind
= 0; ind
< SUPPORTED_MSEXT_NUM
; ind
++)
680 if (nForMSModes
[ind
] & nMode
)
682 DWORD nSubKeys
= 0, nValues
= 0;
683 Status
s1(false); // no throw
685 wsprintfA(aSubKey
, "%sMIME\\DataBase\\Content Type\\%s", aPrefix
, aMSMimeType
[ind
]);
687 if (s1
.upd(RegCreateKeyExA(bForAllUsers
? HKEY_LOCAL_MACHINE
: HKEY_CURRENT_USER
,
688 aSubKey
, 0, nullptr, REG_OPTION_NON_VOLATILE
, nKeyAccess
,
689 nullptr, &hkey
, nullptr)))
691 s
.upd(RegDeleteValueA(hkey
, "Extension"));
692 s
.upd(RegDeleteValueA(hkey
, "CLSID"));
693 s1
.upd(RegQueryInfoKeyA(hkey
, nullptr, nullptr, nullptr, &nSubKeys
, nullptr,
694 nullptr, &nValues
, nullptr, nullptr, nullptr, nullptr));
697 if (s1
&& !nSubKeys
&& !nValues
)
698 DeleteKeyTree(bForAllUsers
? HKEY_LOCAL_MACHINE
: HKEY_CURRENT_USER
, aSubKey
,
702 Status
s2(false); // no throw
704 wsprintfA(aSubKey
, "%s%s", aPrefix
, aMSFileExt
[ind
]);
706 if (s2
.upd(RegCreateKeyExA(bForAllUsers
? HKEY_LOCAL_MACHINE
: HKEY_CURRENT_USER
,
707 aSubKey
, 0, nullptr, REG_OPTION_NON_VOLATILE
, nKeyAccess
,
708 nullptr, &hkey
, nullptr)))
710 s
.upd(RegDeleteValueA(hkey
, "Content Type"));
711 s2
.upd(RegQueryInfoKeyA(hkey
, nullptr, nullptr, nullptr, &nSubKeys
, nullptr,
712 nullptr, &nValues
, nullptr, nullptr, nullptr, nullptr));
715 if (s2
&& !nSubKeys
&& !nValues
)
716 DeleteKeyTree(bForAllUsers
? HKEY_LOCAL_MACHINE
: HKEY_CURRENT_USER
, aSubKey
,
722 return HRESULT_FROM_WIN32(s
.get());
725 STDAPI
DllUnregisterServerDoc( int nMode
, BOOL bForAllUsers
, BOOL bFor64Bit
)
729 hr
= DllUnregisterServerDoc_Impl( nMode
, bForAllUsers
, n64KeyAccess
);
731 if ( SUCCEEDED( hr
) )
732 hr
= DllUnregisterServerDoc_Impl( nMode
, bForAllUsers
, n32KeyAccess
);
738 // DllRegisterServer - regsvr32 entry point
740 STDAPI
DllRegisterServer()
742 HRESULT aResult
= E_FAIL
;
744 HMODULE aCurModule
= GetModuleHandleW( bX64
? X64_LIB_NAME
: X32_LIB_NAME
);
745 DWORD nLibNameLen
= sal::static_int_cast
<DWORD
>(
746 wcslen(bX64
? X64_LIB_NAME
: X32_LIB_NAME
));
750 wchar_t pProgramPath
[1024];
751 DWORD nLen
= GetModuleFileNameW( aCurModule
, pProgramPath
, 1024 );
752 if ( nLen
&& nLen
> nLibNameLen
+ 1 )
754 pProgramPath
[ nLen
- nLibNameLen
- 1 ] = 0;
755 aResult
= DllRegisterServerNative( 31, TRUE
, bX64
, pProgramPath
);
756 if( SUCCEEDED( aResult
) )
757 aResult
= DllRegisterServerDoc( 31, TRUE
, bX64
);
760 aResult
= DllRegisterServerNative( 31, FALSE
, bX64
, pProgramPath
);
761 if( SUCCEEDED( aResult
) )
762 aResult
= DllRegisterServerDoc( 31, FALSE
, bX64
);
771 // DllUnregisterServer - regsvr32 entry point
773 STDAPI
DllUnregisterServer()
775 DllUnregisterServerDoc( 63, FALSE
, bX64
);
776 DllUnregisterServerNative( 63, FALSE
, bX64
);
777 DllUnregisterServerDoc( 63, TRUE
, bX64
);
778 return DllUnregisterServerNative( 63, TRUE
, bX64
);
781 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */