Update git submodules
[LibreOffice.git] / shell / source / win32 / spsupp / spsuppServ.cxx
blob17d0797ed98ee9607c0bcafeeea2e2ee518d2877
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/.
8 */
10 // Include MIDL-generated file
11 #if defined __clang__
12 #pragma clang diagnostic push
13 #pragma clang diagnostic ignored "-Wextra-tokens"
14 // "#endif !_MIDL_USE_GUIDDEF_" in midl-generated code
15 #endif
16 #include <spsupp_i.c>
17 #if defined __clang__
18 #pragma clang diagnostic pop
19 #endif
21 #include <memory>
22 #include <olectl.h>
23 #include <wchar.h>
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>
33 namespace
35 HANDLE g_hModule;
37 HMODULE GetHModule() { return static_cast<HMODULE>(g_hModule); }
38 } // namespace
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;
48 ITypeLib* pTypeLib;
49 if (FAILED(LoadTypeLib(szFile, &pTypeLib)))
50 return aITypeLibGuard;
51 aITypeLibGuard.reset(pTypeLib);
52 return aITypeLibGuard;
53 }();
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)
62 return nullptr;
63 wchar_t* pSlashPos = wcsrchr(sPath, L'\\');
64 if (pSlashPos == nullptr)
65 return nullptr;
66 wcscpy(pSlashPos + 1, L"spsupp_helper.exe");
67 return sPath;
68 }();
69 return s_sPath;
72 BOOL APIENTRY DllMain( HANDLE hinstDLL,
73 DWORD fdwReason,
74 LPVOID /*lpvReserved*/ )
76 switch (fdwReason)
78 case DLL_PROCESS_ATTACH:
79 g_hModule = hinstDLL;
80 break;
82 case DLL_THREAD_ATTACH:
83 case DLL_THREAD_DETACH:
84 case DLL_PROCESS_DETACH:
85 break;
87 return TRUE;
90 namespace {
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)
98 *ppvOut = nullptr;
99 if (IsEqualIID(rclsid, CLSID_spsupp))
101 ClassFactory *pCf = new ClassFactory;
102 HRESULT hr = pCf->QueryInterface(riid, ppvOut);
103 pCf->Release();
104 return hr;
106 return CLASS_E_CLASSNOTAVAILABLE;
109 STDAPI DllCanUnloadNow(void)
111 if (ClassFactory::GetLockCount() == 0 &&
112 ClassFactory::GetObjectCount() == 0 &&
113 COMOpenDocuments::GetObjectCount() == 0)
114 return S_OK;
115 else
116 return S_FALSE;
119 STDAPI DllRegisterServer(void)
121 ITypeLib* pTypeLib = GetTypeLib();
122 if (!pTypeLib)
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);
130 if (FAILED(hr))
131 return hr;
133 // Default is v.5
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();
141 if (!pTypeLib)
142 return ResultFromScode(SELFREG_E_TYPELIB);
143 TLIBATTR* pLibAttr;
144 HRESULT hr = pTypeLib->GetLibAttr(&pLibAttr);
145 if (FAILED(hr))
146 return hr;
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);
152 if (FAILED(hr))
153 return hr;
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)
166 HRESULT hr;
167 Registrar registrar(CLSID_spsupp);
168 if (bInstall)
170 // Default is v.5
171 hr = registrar.RegisterProgIDs(L"SharePoint", L"OpenDocuments", { 5, 1, 2, 3, 4 });
173 else
175 hr = registrar.UnRegisterProgIDs(L"SharePoint", L"OpenDocuments", { 1, 2, 3, 4, 5 });
177 return hr;
179 return E_INVALIDARG;
182 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */