summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dtrans/source/win32/dtobj/FmtFilter.cxx11
-rw-r--r--include/systools/win32/comtools.hxx41
-rw-r--r--shell/source/win32/SysShExec.cxx16
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 "