summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFredrik Orderud <fredrik.orderud@ge.com>2018-10-07 12:54:09 +0200
committerVolker Hilsheimer <volker.hilsheimer@qt.io>2018-10-19 08:03:57 +0000
commitcf0e85184dbba6b9d5feb106277d323521d18b0c (patch)
tree7d1b3e7b26ce47f6dc975b53b60430e83289c285 /src
parentd20eb95f227a841c3d4c319c2cc146b3caa94f5c (diff)
downloadqtactiveqt-cf0e85184dbba6b9d5feb106277d323521d18b0c.tar.gz
ActiveQt: Make window parenting sandbox compatible
In QAxServerBase, CreateWindow currently fails with ERROR_ACCESS_DENIED if the container is running in a higher integrity process. This is caused by the low integrity process not being permitted to create a child window to the high integrity container window. Add fallback logic to instead create the control window stand-alone, instead of being a child window, and then "re-parent" it from the container afterwards. This is following the same pattern as Google Chrome. Task-number: QTBUG-70983 Change-Id: I76fed85226bf5631343ea7d50b16e03d2d1b5d8c Reviewed-by: Andy Shaw <andy.shaw@qt.io> Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/activeqt/container/qaxwidget.cpp24
-rw-r--r--src/activeqt/control/qaxserverbase.cpp13
2 files changed, 36 insertions, 1 deletions
diff --git a/src/activeqt/container/qaxwidget.cpp b/src/activeqt/container/qaxwidget.cpp
index b25e4b2..a28c64f 100644
--- a/src/activeqt/container/qaxwidget.cpp
+++ b/src/activeqt/container/qaxwidget.cpp
@@ -695,10 +695,32 @@ bool QAxClientSite::activateObject(bool initialized, const QByteArray &data)
RECT rcPos = qaxQRect2Rect(QRect(qaxNativeWidgetPosition(host), qaxToNativeSize(host, sizehint)));
+ const HWND hostWnd = reinterpret_cast<HWND>(host->winId());
m_spOleObject->DoVerb(OLEIVERB_INPLACEACTIVATE, 0, static_cast<IOleClientSite *>(this), 0,
- reinterpret_cast<HWND>(host->winId()),
+ hostWnd,
&rcPos);
+ HWND controlWnd = {};
+ {
+ IOleWindow *oleWindow = nullptr;
+ m_spOleObject->QueryInterface(IID_IOleWindow, reinterpret_cast<void **>(&oleWindow));
+ if (oleWindow) {
+ oleWindow->GetWindow(&controlWnd);
+ oleWindow->Release();
+ }
+ }
+
+ if (controlWnd && !GetParent(controlWnd)) {
+ // re-parent control window
+ // this is necessary if the control is running in a "low integrity" process that isn't
+ // permitted to create a child window with hostWnd as parent
+ int winStyle = GetWindowLongPtr(controlWnd, GWL_STYLE);
+ winStyle &= ~WS_CAPTION; // remove title bar
+ winStyle |= WS_CHILD; // convert to child window
+ SetWindowLongPtr(controlWnd, GWL_STYLE, winStyle);
+ SetParent(controlWnd, hostWnd);
+ }
+
if (!m_spOleControl)
m_spOleObject->QueryInterface(IID_IOleControl, reinterpret_cast<void **>(&m_spOleControl));
if (m_spOleControl) {
diff --git a/src/activeqt/control/qaxserverbase.cpp b/src/activeqt/control/qaxserverbase.cpp
index d11fbeb..4d277b6 100644
--- a/src/activeqt/control/qaxserverbase.cpp
+++ b/src/activeqt/control/qaxserverbase.cpp
@@ -1644,12 +1644,25 @@ HWND QAxServerBase::create(HWND hWndParent, RECT& rcPos)
}
Q_ASSERT(!m_hWnd);
+ // will fail if parent window belongs to a higher integrity level process
HWND hWnd = ::CreateWindow(reinterpret_cast<const wchar_t *>(cn.utf16()), 0,
WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
rcPos.left, rcPos.top, rcPos.right - rcPos.left,
rcPos.bottom - rcPos.top, hWndParent, 0, hInst, this);
// m_hWnd is assigned in reponse to WM_CREATE
if (!hWnd) {
+ DWORD err = GetLastError();
+ if (err == ERROR_ACCESS_DENIED) {
+ // retry without parent window
+ // the window will now need to be re-parented in the container process
+ hWnd = ::CreateWindow(reinterpret_cast<const wchar_t *>(cn.utf16()), 0,
+ WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
+ rcPos.left, rcPos.top, rcPos.right - rcPos.left,
+ rcPos.bottom - rcPos.top, nullptr, 0, hInst, this);
+ }
+ }
+
+ if (!hWnd) {
qErrnoWarning("%s: CreateWindow() failed", __FUNCTION__);
return nullptr;
}