diff options
-rw-r--r-- | dtrans/source/win32/dtobj/FmtFilter.cxx | 11 | ||||
-rw-r--r-- | include/systools/win32/comtools.hxx | 41 | ||||
-rw-r--r-- | shell/source/win32/SysShExec.cxx | 16 |
3 files changed, 46 insertions, 22 deletions
diff --git a/dtrans/source/win32/dtobj/FmtFilter.cxx b/dtrans/source/win32/dtobj/FmtFilter.cxx index 0b60cb51c109..c65512e8a4e9 100644 --- a/dtrans/source/win32/dtobj/FmtFilter.cxx +++ b/dtrans/source/win32/dtobj/FmtFilter.cxx @@ -302,15 +302,12 @@ static std::wstring getShellLinkTarget(const std::wstring& aLnkFile) try { sal::systools::COMReference<IShellLinkW> pIShellLink; - HRESULT hr = CoCreateInstance( - CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_IShellLinkW, reinterpret_cast<LPVOID*>(&pIShellLink)); - if (FAILED(hr)) - return target; + pIShellLink.CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER); - sal::systools::COMReference<IPersistFile> pIPersistFile = - pIShellLink.QueryInterface<IPersistFile>(IID_IPersistFile); + sal::systools::COMReference<IPersistFile> pIPersistFile(pIShellLink, + sal::systools::COM_QUERY_THROW); - hr = pIPersistFile->Load(aLnkFile.c_str(), STGM_READ); + HRESULT hr = pIPersistFile->Load(aLnkFile.c_str(), STGM_READ); if (FAILED(hr)) return target; diff --git a/include/systools/win32/comtools.hxx b/include/systools/win32/comtools.hxx index 8f7ce87e7636..8f2d94027952 100644 --- a/include/systools/win32/comtools.hxx +++ b/include/systools/win32/comtools.hxx @@ -22,6 +22,7 @@ #include <string> #include <stdexcept> +#include <type_traits> #include <objbase.h> namespace sal @@ -48,6 +49,12 @@ namespace systools HRESULT hr_; }; + struct COM_QUERY_TAG {} constexpr COM_QUERY; + struct COM_QUERY_THROW_TAG {} constexpr COM_QUERY_THROW; + template <typename TAG> + constexpr bool is_COM_query_tag + = std::is_same_v<TAG, COM_QUERY_TAG> || std::is_same_v<TAG, COM_QUERY_THROW_TAG>; + /* A simple COM smart pointer template */ template <typename T> class COMReference @@ -64,6 +71,13 @@ namespace systools addRef(); } + // Query from IUnknown*, using COM_QUERY or COM_QUERY_THROW tags + template <typename T2, typename TAG> + COMReference(const COMReference<T2>& p, TAG t) + : COMReference(p.QueryInterface<T>(t)) + { + } + /* Explicitly controllable whether AddRef will be called or not */ COMReference(T* comptr, bool bAddRef) : com_ptr_(comptr) @@ -100,18 +114,30 @@ namespace systools release(); } - template<typename InterfaceType> - COMReference<InterfaceType> QueryInterface(REFIID iid) + template <typename T2, typename TAG, std::enable_if_t<is_COM_query_tag<TAG>, int> = 0> + COMReference<T2> QueryInterface(TAG) const { - COMReference<InterfaceType> ip; + void* ip = nullptr; HRESULT hr = E_FAIL; if (com_ptr_) - hr = com_ptr_->QueryInterface(iid, reinterpret_cast<LPVOID*>(&ip)); + hr = com_ptr_->QueryInterface(__uuidof(T2), &ip); + if constexpr (std::is_same_v<TAG, COM_QUERY_THROW_TAG>) + if (FAILED(hr)) + throw ComError("QueryInterface failed: Interface not supported!", hr); + return { static_cast<T2*>(ip), false }; + } + + COMReference<T>& CoCreateInstance(REFCLSID clsid, IUnknown* pOuter = nullptr, + DWORD nCtx = CLSCTX_ALL) + { + clear(); + HRESULT hr = ::CoCreateInstance(clsid, pOuter, nCtx, __uuidof(T), + reinterpret_cast<void**>(&com_ptr_)); if (FAILED(hr)) - throw ComError("QueryInterface failed: Interface not supported!", hr); + throw ComError("CoCreateInstance failed!", hr); - return ip; + return *this; } T* operator->() const @@ -138,11 +164,10 @@ namespace systools return com_ptr_; } - COMReference<T>& clear() + void clear() { release(); com_ptr_ = NULL; - return *this; } bool is() const diff --git a/shell/source/win32/SysShExec.cxx b/shell/source/win32/SysShExec.cxx index 00384b8bd235..4d9ba43a6cc3 100644 --- a/shell/source/win32/SysShExec.cxx +++ b/shell/source/win32/SysShExec.cxx @@ -361,25 +361,27 @@ void SAL_CALL CSysShExec::execute( const OUString& aCommand, const OUString& aPa break; } sal::systools::COMReference<IShellLinkW> link; - auto e2 = CoCreateInstance( - CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_IShellLinkW, - reinterpret_cast<LPVOID *>(&link)); - if (FAILED(e2)) { + try + { + link.CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER); + } + catch (sal::systools::ComError& e) + { throw css::lang::IllegalArgumentException( ("XSystemShellExecute.execute, CoCreateInstance failed with " - + OUString::number(e2)), + + OUString::number(e.GetHresult())), {}, 0); } sal::systools::COMReference<IPersistFile> file; try { - file = link.QueryInterface<IPersistFile>(IID_IPersistFile); + file = link.QueryInterface<IPersistFile>(sal::systools::COM_QUERY_THROW); } catch(sal::systools::ComError & e3) { throw css::lang::IllegalArgumentException( ("XSystemShellExecute.execute, QueryInterface failed with: " + o3tl::runtimeToOUString(e3.what())), {}, 0); } - e2 = file->Load(path, STGM_READ); + HRESULT e2 = file->Load(path, STGM_READ); if (FAILED(e2)) { throw css::lang::IllegalArgumentException( ("XSystemShellExecute.execute, IPersistFile.Load failed with " |