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
31 #include <systools/win32/extended_max_path.hxx>
37 HMODULE
GetHModule() { return static_cast<HMODULE
>(g_hModule
); }
40 ITypeLib
* GetTypeLib()
42 typedef std::unique_ptr
<ITypeLib
, void(*)(IUnknown
* p
)> ITypeLibGuard
;
43 static ITypeLibGuard s_aITypeLibGuard
= [] {
44 ITypeLibGuard
aITypeLibGuard(nullptr, [](IUnknown
* p
) { if (p
) p
->Release(); });
45 wchar_t szFile
[EXTENDED_MAX_PATH
];
46 if (GetModuleFileNameW(GetHModule(), szFile
, std::size(szFile
)) == 0)
47 return aITypeLibGuard
;
49 if (FAILED(LoadTypeLib(szFile
, &pTypeLib
)))
50 return aITypeLibGuard
;
51 aITypeLibGuard
.reset(pTypeLib
);
52 return aITypeLibGuard
;
54 return s_aITypeLibGuard
.get();
57 const wchar_t* GetHelperExe()
59 static wchar_t* s_sPath
= []() -> wchar_t* {
60 static wchar_t sPath
[EXTENDED_MAX_PATH
];
61 if (GetModuleFileNameW(GetHModule(), sPath
, std::size(sPath
)) == 0)
63 wchar_t* pSlashPos
= wcsrchr(sPath
, L
'\\');
64 if (pSlashPos
== nullptr)
66 wcscpy(pSlashPos
+ 1, L
"spsupp_helper.exe");
72 BOOL APIENTRY
DllMain( HANDLE hinstDLL
,
74 LPVOID
/*lpvReserved*/ )
78 case DLL_PROCESS_ATTACH
:
82 case DLL_THREAD_ATTACH
:
83 case DLL_THREAD_DETACH
:
84 case DLL_PROCESS_DETACH
:
91 // {F1924D0C-9B35-4A46-BCDE-CFEF2CE67A17}
92 const IID CLSID_spsupp
=
93 { 0xf1924d0c, 0x9b35, 0x4a46, { 0xbc, 0xde, 0xcf, 0xef, 0x2c, 0xe6, 0x7a, 0x17 } };
96 STDAPI
DllGetClassObject(REFCLSID rclsid
, REFIID riid
, LPVOID
*ppvOut
)
99 if (IsEqualIID(rclsid
, CLSID_spsupp
))
101 ClassFactory
*pCf
= new ClassFactory
;
102 HRESULT hr
= pCf
->QueryInterface(riid
, ppvOut
);
106 return CLASS_E_CLASSNOTAVAILABLE
;
109 STDAPI
DllCanUnloadNow(void)
111 if (ClassFactory::GetLockCount() == 0 &&
112 ClassFactory::GetObjectCount() == 0 &&
113 COMOpenDocuments::GetObjectCount() == 0)
119 STDAPI
DllRegisterServer(void)
121 ITypeLib
* pTypeLib
= GetTypeLib();
123 return ResultFromScode(SELFREG_E_TYPELIB
);
125 wchar_t szFile
[EXTENDED_MAX_PATH
];
126 if (GetModuleFileNameW(GetHModule(), szFile
, std::size(szFile
)) == 0)
127 return HRESULT_FROM_WIN32(GetLastError());
129 HRESULT hr
= RegisterTypeLib(pTypeLib
, szFile
, nullptr);
134 return Registrar(CLSID_spsupp
)
135 .RegisterObject(LIBID_spsupp
, L
"LOSPSupport", L
"OpenDocuments", { 5, 1, 2, 3, 4 }, szFile
);
138 STDAPI
DllUnregisterServer(void)
140 ITypeLib
* pTypeLib
= GetTypeLib();
142 return ResultFromScode(SELFREG_E_TYPELIB
);
144 HRESULT hr
= pTypeLib
->GetLibAttr(&pLibAttr
);
147 auto ReleaseFunc
= [pTypeLib
](TLIBATTR
* p
) { if (p
) pTypeLib
->ReleaseTLibAttr(p
); };
148 typedef std::unique_ptr
<TLIBATTR
, decltype(ReleaseFunc
)> TLIBATTRGuard
;
149 static TLIBATTRGuard
aTLIBATTRGuard(nullptr, ReleaseFunc
);
151 hr
= UnRegisterTypeLib(pLibAttr
->guid
, pLibAttr
->wMajorVerNum
, pLibAttr
->wMinorVerNum
, pLibAttr
->lcid
, pLibAttr
->syskind
);
155 return Registrar(CLSID_spsupp
)
156 .UnRegisterObject(L
"LOSPSupport", L
"OpenDocuments", { 1, 2, 3, 4, 5 });
159 // This is called when regsvr32.exe is called with "/i" flag
160 // pszCmdLine is the string passed to "/i:<string>"
161 // See https://msdn.microsoft.com/library/windows/desktop/bb759846
162 STDAPI
DllInstall(BOOL bInstall
, _In_opt_ PCWSTR pszCmdLine
)
164 if (wcscmp(pszCmdLine
, L
"Substitute_OWSSUPP") == 0)
167 Registrar
registrar(CLSID_spsupp
);
171 hr
= registrar
.RegisterProgIDs(L
"SharePoint", L
"OpenDocuments", { 5, 1, 2, 3, 4 });
175 hr
= registrar
.UnRegisterProgIDs(L
"SharePoint", L
"OpenDocuments", { 1, 2, 3, 4, 5 });
182 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */