30#include <so_activex.h>
33#pragma clang diagnostic push
34#pragma clang diagnostic ignored "-Wextra-tokens"
37#include <so_activex_i.c>
39#pragma clang diagnostic pop
50BEGIN_OBJECT_MAP(ObjectMap)
53#pragma clang diagnostic push
54#pragma clang diagnostic ignored "-Wmissing-field-initializers"
58#pragma clang diagnostic pop
61#define X64_LIB_NAME L"so_activex_x64.dll"
62#define X32_LIB_NAME L"so_activex.dll"
68const bool bX64 =
true;
69#define REG_DELETE_KEY_A( key, aPath, nKeyAccess ) RegDeleteKeyExA( key, aPath, nKeyAccess, 0 )
72#define REG_DELETE_KEY_A( key, aPath, nKeyAccess ) RegDeleteKeyA( key, aPath )
78BOOL WINAPI
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID )
80 if (dwReason == DLL_PROCESS_ATTACH)
82 _Module.Init(ObjectMap, hInstance, &LIBID_SO_ACTIVEXLib);
83 DisableThreadLibraryCalls(hInstance);
85 else if (dwReason == DLL_PROCESS_DETACH)
95 return (
_Module.GetLockCount()==0) ? S_OK : S_FALSE;
103 return _Module.GetClassObject(rclsid, riid, ppv);
117 explicit Status(
bool bTrow)
122 bool upd(LSTATUS nNewStatus)
124 if (m_nStatus == ERROR_SUCCESS)
126 if (m_bThrow && nNewStatus != ERROR_SUCCESS)
127 throw std::exception();
128 return nNewStatus == ERROR_SUCCESS;
131 operator bool() {
return m_nStatus == ERROR_SUCCESS; }
147 operator HKEY() {
return m_hkey; }
150 HKEY m_hkey =
nullptr;
155#define SUPPORTED_EXT_NUM 30
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"};
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",
201 1, 2, 4, 4, 8, 16, 32,
205 16, 16, 16, 2, 4, 8, 32 };
207const char*
const aClassID =
"{67F2A879-82D5-4A6D-8CC5-FFB3C114B69D}";
208const char*
const aTypeLib =
"{61FA3F13-8061-4796-B055-3697ED28CB38}";
226 const char* aKeyToCreate,
228 const char* aValue =
nullptr,
229 const char* aChildName =
nullptr,
230 const char* aChildValue =
nullptr )
234 if (s.upd(RegCreateKeyExA(hkey, aKeyToCreate, 0,
nullptr, REG_OPTION_NON_VOLATILE, nKeyAccess,
235 nullptr, &hkey1,
nullptr)))
238 s.upd(RegSetValueExA(hkey1,
"", 0, REG_SZ,
reinterpret_cast<const BYTE*
>(aValue),
239 sal::static_int_cast<DWORD>(strlen(aValue))));
241 s.upd(RegSetValueExA(hkey1, aChildName, 0, REG_SZ,
242 reinterpret_cast<const BYTE*
>(aChildValue),
243 sal::static_int_cast<DWORD>(strlen(aChildValue))));
249 const wchar_t* aKeyToCreate,
251 const wchar_t* aValue =
nullptr,
252 const wchar_t* aChildName =
nullptr,
253 const wchar_t* aChildValue =
nullptr )
257 if (s.upd(RegCreateKeyExW(hkey, aKeyToCreate, 0,
nullptr, REG_OPTION_NON_VOLATILE, nKeyAccess,
258 nullptr, &hkey1,
nullptr)))
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))));
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))));
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);
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));
313 s.upd(
createKey(hkey,
"Version", nKeyAccess,
"1.0"));
314 s.upd(
createKey(hkey,
"VersionIndependentProgID", nKeyAccess,
315 "so_activex.SOActiveX"));
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"));
325 s.upd(RegCreateKeyExA(hkey,
"so_activex.SOActiveX", 0,
nullptr,
326 REG_OPTION_NON_VOLATILE, nKeyAccess,
nullptr, &hkey1,
329 s.upd(
createKey(hkey1,
"CurVer", nKeyAccess,
"so_activex.SOActiveX.1"));
331 s.upd(
createKey(hkey,
"so_activex.SOActiveX.1", nKeyAccess,
"SOActiveX Class"));
334 s.upd(RegCreateKeyExA(hkey,
"so_activex.SOActiveX.1", 0,
nullptr,
335 REG_OPTION_NON_VOLATILE, nKeyAccess,
nullptr, &hkey1,
341 s.upd(RegCreateKeyExA(hkey,
"TypeLib", 0,
nullptr, REG_OPTION_NON_VOLATILE,
342 nKeyAccess,
nullptr, &hkey1,
nullptr));
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"));
350 s.upd(RegCreateKeyExA(hkey2,
"1.0", 0,
nullptr, REG_OPTION_NON_VOLATILE,
351 nKeyAccess,
nullptr, &hkey3,
nullptr));
354 s.upd(RegCreateKeyExA(hkey3,
"0", 0,
nullptr,
355 REG_OPTION_NON_VOLATILE, nKeyAccess,
nullptr,
357 s.upd(
createKey(hkey4, L
"win32", nKeyAccess, pActiveXPath));
359 s.upd(
createKey(hkey3,
"FLAGS", nKeyAccess,
"0"));
366 s.upd(RegCreateKeyExA(hkey,
"Interface", 0,
nullptr, REG_OPTION_NON_VOLATILE,
367 nKeyAccess,
nullptr, &hkey1,
nullptr));
372 REG_OPTION_NON_VOLATILE, nKeyAccess,
nullptr, &hkey2,
382 REG_OPTION_NON_VOLATILE, nKeyAccess,
nullptr, &hkey2,
393 REG_OPTION_NON_VOLATILE, nKeyAccess,
nullptr, &hkey2,
407 wsprintfA(aSubKey,
"%sMIME\\DataBase\\Content Type\\%ls", aPrefix,
aMimeType[ind]);
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,
414 sal::static_int_cast<DWORD>(strlen(
aClassID))));
419 wsprintfA(aSubKey,
"%sCLSID\\%s", aPrefix,
aClassID);
421 s.upd(RegOpenKeyExA(
bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, 0,
425 wsprintfA(aSubKey,
"EnableFullPage\\%s",
aFileExt[ind]);
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());
443 if ( SUCCEEDED(
hr ) )
451static HRESULT
DeleteKeyTree( HKEY hkey,
const char* pPath, REGSAM nKeyAccess )
453 char pSubKeyName[256];
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))
465 return REG_DELETE_KEY_A( hkey, pPath, nKeyAccess & ( KEY_WOW64_64KEY | KEY_WOW64_32KEY ) );
478 DWORD nSubKeys = 0, nValues = 0;
479 wsprintfA(aSubKey,
"%sMIME\\DataBase\\Content Type\\%ls", aPrefix,
aMimeType[ind]);
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)
497 wsprintfA(aSubKey,
"%s%s", aPrefix,
aFileExt[ind]);
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)
516 wsprintfA(aSubKey,
"%sCLSID\\%s", aPrefix,
aClassID);
520 wsprintfA(aSubKey,
"%sso_activex.SOActiveX", aPrefix);
524 wsprintfA(aSubKey,
"%sso_activex.SOActiveX.1", aPrefix);
528 wsprintfA(aSubKey,
"%s\\TypeLib\\%s", aPrefix,
aTypeLib);
544 return HRESULT_FROM_WIN32(s.get());
559#define SUPPORTED_MSEXT_NUM 7
560const char*
const aMSFileExt[] = {
".dot",
".doc",
".xlt",
".xls",
".pot",
".ppt",
".pps" };
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" };
591 wsprintfA(aSubKey,
"%sMIME\\DataBase\\Content Type\\%s", aPrefix,
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,
599 sal::static_int_cast<DWORD>(strlen(
aMSFileExt[ind]))));
600 s.upd(RegSetValueExA(hkey,
"CLSID", 0, REG_SZ,
602 sal::static_int_cast<DWORD>(strlen(
aClassID))));
605 wsprintfA(aSubKey,
"%s%s", aPrefix,
aMSFileExt[ind]);
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,
612 sal::static_int_cast<DWORD>(strlen(
aMSMimeType[ind]))));
617 wsprintfA(aSubKey,
"%sCLSID\\%s", aPrefix,
aClassID);
619 s.upd(RegCreateKeyExA(
bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, 0,
620 nullptr, REG_OPTION_NON_VOLATILE, nKeyAccess,
nullptr, &hkey,
622 s.upd(
createKey(hkey,
"EnableFullPage", nKeyAccess));
627 wsprintfA(aSubKey,
"EnableFullPage\\%s",
aMSFileExt[ind]);
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());
645 if ( SUCCEEDED(
hr ) )
664 DWORD nSubKeys = 0, nValues = 0;
667 wsprintfA(aSubKey,
"%sMIME\\DataBase\\Content Type\\%s", aPrefix,
aMSMimeType[ind]);
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)
686 wsprintfA(aSubKey,
"%s%s", aPrefix,
aMSFileExt[ind]);
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)
704 return HRESULT_FROM_WIN32(s.get());
713 if ( SUCCEEDED(
hr ) )
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,
733 wchar_t* pPathEnd =
nullptr;
741 if( SUCCEEDED( aResult ) )
742 aResult = DllRegisterServerDoc( 31,
TRUE,
bX64 );
746 if( SUCCEEDED( aResult ) )
747 aResult = DllRegisterServerDoc( 31,
FALSE,
bX64 );
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
#define SAL_N_ELEMENTS(arr)
moOpDF operator&(moOpDF a, moOpDF b)
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
const wchar_t *typedef BOOL
const char *const aInterIDActApprove
const char *const aMSMimeType[]
const char *const aInterIDDispInt
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID)
const REGSAM n64KeyAccess
STDAPI DllUnregisterServerDoc(int nMode, BOOL bForAllUsers, BOOL bFor64Bit)
#define SUPPORTED_EXT_NUM
const char *const aLocalPrefix
const REGSAM n32KeyAccess
STDAPI DllRegisterServer()
const char *const aFileExt[]
const char *const aMSFileExt[]
STDAPI DllUnregisterServer()
static LSTATUS createKey(HKEY hkey, const char *aKeyToCreate, REGSAM nKeyAccess, const char *aValue=nullptr, const char *aChildName=nullptr, const char *aChildValue=nullptr)
EXTERN_C BOOL BOOL const wchar_t * pProgramPath
STDAPI DllUnregisterServerNative(int nMode, BOOL bForAllUsers, BOOL bFor64Bit)
static HRESULT DllRegisterServerDoc_Impl(int nMode, bool bForAllUsers, REGSAM nKeyAccess)
const char *const aClassID
#define SUPPORTED_MSEXT_NUM
static HRESULT DllUnregisterServerNative_Impl(int nMode, bool bForAllUsers, REGSAM nKeyAccess)
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
static HRESULT DeleteKeyTree(HKEY hkey, const char *pPath, REGSAM nKeyAccess)
#define REG_DELETE_KEY_A(key, aPath, nKeyAccess)
static HRESULT DllRegisterServerNative_Impl(int nMode, bool bForAllUsers, REGSAM nKeyAccess, const wchar_t *pProgramPath, const wchar_t *pLibName)
const char *const aProxyStubDispInt
EXTERN_C BOOL BOOL bFor64Bit
const char *const aTypeLib
const char *const aInterIDWinPeer
const sal_Unicode *const aMimeType[]
const char *const aProxyStubActApprove
const char *const aProxyStubWinPeer
EXTERN_C BOOL bForAllUsers
static HRESULT DllUnregisterServerDoc_Impl(int nMode, bool bForAllUsers, REGSAM nKeyAccess)
EXTERN_C __declspec(dllexport) HRESULT STDAPICALLTYPE DllUnregisterServerNative(int nMode