LibreOffice Module shell (master) 1
spsuppServ.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3* This file is part of the LibreOffice project.
4*
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*/
9
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
20
21#include <memory>
22#include <olectl.h>
23#include <wchar.h>
24#include <spsuppServ.hpp>
26#include <COMOpenDocuments.hpp>
27#include <registrar.hpp>
28
29#include <shlwapi.h> // declaration of DllInstall
30
31namespace
32{
33HANDLE g_hModule;
34
35HMODULE GetHModule() { return static_cast<HMODULE>(g_hModule); }
36} // namespace
37
38ITypeLib* GetTypeLib()
39{
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;
46 ITypeLib* pTypeLib;
47 if (FAILED(LoadTypeLib(szFile, &pTypeLib)))
48 return aITypeLibGuard;
49 aITypeLibGuard.reset(pTypeLib);
50 return aITypeLibGuard;
51 }();
52 return s_aITypeLibGuard.get();
53}
54
55const wchar_t* GetHelperExe()
56{
57 static wchar_t* s_sPath = []() -> wchar_t* {
58 static wchar_t sPath[MAX_PATH];
59 if (GetModuleFileNameW(GetHModule(), sPath, MAX_PATH) == 0)
60 return nullptr;
61 wchar_t* pSlashPos = wcsrchr(sPath, L'\\');
62 if (pSlashPos == nullptr)
63 return nullptr;
64 wcscpy(pSlashPos + 1, L"spsupp_helper.exe");
65 return sPath;
66 }();
67 return s_sPath;
68}
69
70BOOL APIENTRY DllMain( HANDLE hinstDLL,
71 DWORD fdwReason,
72 LPVOID /*lpvReserved*/ )
73{
74 switch (fdwReason)
75 {
76 case DLL_PROCESS_ATTACH:
77 g_hModule = hinstDLL;
78 break;
79
80 case DLL_THREAD_ATTACH:
81 case DLL_THREAD_DETACH:
82 case DLL_PROCESS_DETACH:
83 break;
84 }
85 return TRUE;
86}
87
88namespace {
89 // {F1924D0C-9B35-4A46-BCDE-CFEF2CE67A17}
90 const IID CLSID_spsupp =
91 { 0xf1924d0c, 0x9b35, 0x4a46, { 0xbc, 0xde, 0xcf, 0xef, 0x2c, 0xe6, 0x7a, 0x17 } };
92}
93
94STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppvOut)
95{
96 *ppvOut = nullptr;
97 if (IsEqualIID(rclsid, CLSID_spsupp))
98 {
99 ClassFactory *pCf = new ClassFactory;
100 HRESULT hr = pCf->QueryInterface(riid, ppvOut);
101 pCf->Release();
102 return hr;
103 }
104 return CLASS_E_CLASSNOTAVAILABLE;
105}
106
107STDAPI DllCanUnloadNow(void)
108{
109 if (ClassFactory::GetLockCount() == 0 &&
112 return S_OK;
113 else
114 return S_FALSE;
115}
116
118{
119 ITypeLib* pTypeLib = GetTypeLib();
120 if (!pTypeLib)
121 return ResultFromScode(SELFREG_E_TYPELIB);
122
123 wchar_t szFile[MAX_PATH];
124 if (GetModuleFileNameW(GetHModule(), szFile, MAX_PATH) == 0)
125 return HRESULT_FROM_WIN32(GetLastError());
126
127 HRESULT hr = RegisterTypeLib(pTypeLib, szFile, nullptr);
128 if (FAILED(hr))
129 return hr;
130
131 // Default is v.5
132 return Registrar(CLSID_spsupp)
133 .RegisterObject(LIBID_spsupp, L"LOSPSupport", L"OpenDocuments", { 5, 1, 2, 3, 4 }, szFile);
134}
135
137{
138 ITypeLib* pTypeLib = GetTypeLib();
139 if (!pTypeLib)
140 return ResultFromScode(SELFREG_E_TYPELIB);
141 TLIBATTR* pLibAttr;
142 HRESULT hr = pTypeLib->GetLibAttr(&pLibAttr);
143 if (FAILED(hr))
144 return hr;
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);
148
149 hr = UnRegisterTypeLib(pLibAttr->guid, pLibAttr->wMajorVerNum, pLibAttr->wMinorVerNum, pLibAttr->lcid, pLibAttr->syskind);
150 if (FAILED(hr))
151 return hr;
152
153 return Registrar(CLSID_spsupp)
154 .UnRegisterObject(L"LOSPSupport", L"OpenDocuments", { 1, 2, 3, 4, 5 });
155}
156
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
160STDAPI DllInstall(BOOL bInstall, _In_opt_ PCWSTR pszCmdLine)
161{
162 if (wcscmp(pszCmdLine, L"Substitute_OWSSUPP") == 0)
163 {
164 HRESULT hr;
165 Registrar registrar(CLSID_spsupp);
166 if (bInstall)
167 {
168 // Default is v.5
169 hr = registrar.RegisterProgIDs(L"SharePoint", L"OpenDocuments", { 5, 1, 2, 3, 4 });
170 }
171 else
172 {
173 hr = registrar.UnRegisterProgIDs(L"SharePoint", L"OpenDocuments", { 1, 2, 3, 4, 5 });
174 }
175 return hr;
176 }
177 return E_INVALIDARG;
178}
179
180/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static LONG GetObjectCount()
ULONG STDMETHODCALLTYPE Release() override
static LONG GetObjectCount()
static LONG GetLockCount()
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) override
HRESULT RegisterProgIDs(const wchar_t *sProgram, const wchar_t *sComponent, std::initializer_list< int > aVersions)
Definition: registrar.cxx:224
HRESULT RegisterObject(REFIID riidTypeLib, const wchar_t *sProgram, const wchar_t *sComponent, std::initializer_list< int > aVersions, const wchar_t *Path)
Definition: registrar.cxx:91
HRESULT UnRegisterObject(const wchar_t *sProgram, const wchar_t *sComponent, std::initializer_list< int > aVersions)
Definition: registrar.cxx:170
HRESULT UnRegisterProgIDs(const wchar_t *sProgram, const wchar_t *sComponent, std::initializer_list< int > aVersions)
Definition: registrar.cxx:276
#define TRUE
#define MAX_PATH
void * p
static HINSTANCE g_hModule
Definition: propertyhdl.cxx:40
const wchar_t *typedef BOOL
return hr
STDAPI DllRegisterServer(void)
Definition: spsuppServ.cxx:117
BOOL APIENTRY DllMain(HANDLE hinstDLL, DWORD fdwReason, LPVOID)
Definition: spsuppServ.cxx:70
ITypeLib * GetTypeLib()
Definition: spsuppServ.cxx:38
STDAPI DllUnregisterServer(void)
Definition: spsuppServ.cxx:136
STDAPI DllInstall(BOOL bInstall, _In_opt_ PCWSTR pszCmdLine)
Definition: spsuppServ.cxx:160
const wchar_t * GetHelperExe()
Definition: spsuppServ.cxx:55
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppvOut)
Definition: spsuppServ.cxx:94
STDAPI DllCanUnloadNow(void)
Definition: spsuppServ.cxx:107