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/.
10 // Include MIDL-generated file
12 #pragma clang diagnostic push
13 #pragma clang diagnostic ignored "-Wextra-tokens"
14 // "#endif !_MIDL_USE_GUIDDEF_" in midl-generated code
18 #pragma clang diagnostic pop
24 #include <spsuppServ.hpp>
25 #include <spsuppClassFactory.hpp>
26 #include <COMOpenDocuments.hpp>
27 #include <registrar.hpp>
29 #include <shlwapi.h> // declaration of DllInstall
35 HMODULE
GetHModule() { return static_cast<HMODULE
>(g_hModule
); }
38 ITypeLib
* GetTypeLib()
40 typedef std::unique_ptr
<ITypeLib
, void(*)(IUnknown
* p
)> ITypeLibGuard
;
41 static ITypeLibGuard s_aITypeLibGuard
= [] {
42 ITypeLibGuard
aITypeLibGuard(nullptr, [](IUnknown
* p
) { if (p
) p
->Release(); });
43 wchar_t szFile
[MAX_PATH
];
44 if (GetModuleFileNameW(GetHModule(), szFile
, MAX_PATH
) == 0)
45 return aITypeLibGuard
;
47 if (FAILED(LoadTypeLib(szFile
, &pTypeLib
)))
48 return aITypeLibGuard
;
49 aITypeLibGuard
.reset(pTypeLib
);
50 return aITypeLibGuard
;
52 return s_aITypeLibGuard
.get();
55 const wchar_t* GetHelperExe()
57 static wchar_t* s_sPath
= []() -> wchar_t* {
58 static wchar_t sPath
[MAX_PATH
];
59 if (GetModuleFileNameW(GetHModule(), sPath
, MAX_PATH
) == 0)
61 wchar_t* pSlashPos
= wcsrchr(sPath
, L
'\\');
62 if (pSlashPos
== nullptr)
64 wcscpy(pSlashPos
+ 1, L
"spsupp_helper.exe");
70 BOOL APIENTRY
DllMain( HANDLE hinstDLL
,
72 LPVOID
/*lpvReserved*/ )
76 case DLL_PROCESS_ATTACH
:
80 case DLL_THREAD_ATTACH
:
81 case DLL_THREAD_DETACH
:
82 case DLL_PROCESS_DETACH
:
89 // {F1924D0C-9B35-4A46-BCDE-CFEF2CE67A17}
90 const IID CLSID_spsupp
=
91 { 0xf1924d0c, 0x9b35, 0x4a46, { 0xbc, 0xde, 0xcf, 0xef, 0x2c, 0xe6, 0x7a, 0x17 } };
94 STDAPI
DllGetClassObject(REFCLSID rclsid
, REFIID riid
, LPVOID
*ppvOut
)
97 if (IsEqualIID(rclsid
, CLSID_spsupp
))
99 ClassFactory
*pCf
= new ClassFactory
;
100 HRESULT hr
= pCf
->QueryInterface(riid
, ppvOut
);
104 return CLASS_E_CLASSNOTAVAILABLE
;
107 STDAPI
DllCanUnloadNow(void)
109 if (ClassFactory::GetLockCount() == 0 &&
110 ClassFactory::GetObjectCount() == 0 &&
111 COMOpenDocuments::GetObjectCount() == 0)
117 STDAPI
DllRegisterServer(void)
119 ITypeLib
* pTypeLib
= GetTypeLib();
121 return ResultFromScode(SELFREG_E_TYPELIB
);
123 wchar_t szFile
[MAX_PATH
];
124 if (GetModuleFileNameW(GetHModule(), szFile
, MAX_PATH
) == 0)
125 return HRESULT_FROM_WIN32(GetLastError());
127 HRESULT hr
= RegisterTypeLib(pTypeLib
, szFile
, nullptr);
132 return Registrar(CLSID_spsupp
)
133 .RegisterObject(LIBID_spsupp
, L
"LOSPSupport", L
"OpenDocuments", { 5, 1, 2, 3, 4 }, szFile
);
136 STDAPI
DllUnregisterServer(void)
138 ITypeLib
* pTypeLib
= GetTypeLib();
140 return ResultFromScode(SELFREG_E_TYPELIB
);
142 HRESULT hr
= pTypeLib
->GetLibAttr(&pLibAttr
);
145 auto ReleaseFunc
= [pTypeLib
](TLIBATTR
* p
) { if (p
) pTypeLib
->ReleaseTLibAttr(p
); };
146 typedef std::unique_ptr
<TLIBATTR
, decltype(ReleaseFunc
)> TLIBATTRGuard
;
147 static TLIBATTRGuard
aTLIBATTRGuard(nullptr, ReleaseFunc
);
149 hr
= UnRegisterTypeLib(pLibAttr
->guid
, pLibAttr
->wMajorVerNum
, pLibAttr
->wMinorVerNum
, pLibAttr
->lcid
, pLibAttr
->syskind
);
153 return Registrar(CLSID_spsupp
)
154 .UnRegisterObject(L
"LOSPSupport", L
"OpenDocuments", { 1, 2, 3, 4, 5 });
157 // This is called when regsvr32.exe is called with "/i" flag
158 // pszCmdLine is the string passed to "/i:<string>"
159 // See https://msdn.microsoft.com/library/windows/desktop/bb759846
160 STDAPI
DllInstall(BOOL bInstall
, _In_opt_ PCWSTR pszCmdLine
)
162 if (wcscmp(pszCmdLine
, L
"Substitute_OWSSUPP") == 0)
165 Registrar
registrar(CLSID_spsupp
);
169 hr
= registrar
.RegisterProgIDs(L
"SharePoint", L
"OpenDocuments", { 5, 1, 2, 3, 4 });
173 hr
= registrar
.UnRegisterProgIDs(L
"SharePoint", L
"OpenDocuments", { 1, 2, 3, 4, 5 });
180 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */