From 9e3c08db40b8916968b9f30096c7be3f00ce9647 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 21 Apr 2024 13:44:51 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- .../nsis/Contrib/WebBrowser/CustomFunctions.cpp | 75 +++ other-licenses/nsis/Contrib/WebBrowser/Timers.cpp | 59 ++ .../nsis/Contrib/WebBrowser/WebBrowser.cpp | 604 +++++++++++++++++++++ .../nsis/Contrib/WebBrowser/WebBrowser.h | 250 +++++++++ .../nsis/Contrib/WebBrowser/WebBrowser.sln | 25 + .../nsis/Contrib/WebBrowser/WebBrowser.vcxproj | 160 ++++++ other-licenses/nsis/Contrib/WebBrowser/exdll.cpp | 30 + other-licenses/nsis/Contrib/WebBrowser/exdll.h | 76 +++ other-licenses/nsis/Contrib/WebBrowser/main.cpp | 199 +++++++ other-licenses/nsis/Contrib/WebBrowser/resource.h | 5 + other-licenses/nsis/Contrib/WebBrowser/resource.rc | 14 + 11 files changed, 1497 insertions(+) create mode 100644 other-licenses/nsis/Contrib/WebBrowser/CustomFunctions.cpp create mode 100644 other-licenses/nsis/Contrib/WebBrowser/Timers.cpp create mode 100644 other-licenses/nsis/Contrib/WebBrowser/WebBrowser.cpp create mode 100644 other-licenses/nsis/Contrib/WebBrowser/WebBrowser.h create mode 100644 other-licenses/nsis/Contrib/WebBrowser/WebBrowser.sln create mode 100644 other-licenses/nsis/Contrib/WebBrowser/WebBrowser.vcxproj create mode 100644 other-licenses/nsis/Contrib/WebBrowser/exdll.cpp create mode 100644 other-licenses/nsis/Contrib/WebBrowser/exdll.h create mode 100644 other-licenses/nsis/Contrib/WebBrowser/main.cpp create mode 100644 other-licenses/nsis/Contrib/WebBrowser/resource.h create mode 100644 other-licenses/nsis/Contrib/WebBrowser/resource.rc (limited to 'other-licenses/nsis/Contrib/WebBrowser') diff --git a/other-licenses/nsis/Contrib/WebBrowser/CustomFunctions.cpp b/other-licenses/nsis/Contrib/WebBrowser/CustomFunctions.cpp new file mode 100644 index 0000000000..4ad004b841 --- /dev/null +++ b/other-licenses/nsis/Contrib/WebBrowser/CustomFunctions.cpp @@ -0,0 +1,75 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0.If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "WebBrowser.h" +#include "exdll.h" + +extern WebBrowser* gBrowser; +void Init(HWND hWndParent, int string_size, TCHAR* variables, + stack_t** stacktop, extra_parameters* extra); + +static void CustomFunctionWrapper(void* NSISFunctionAddr, VARIANT jsArg, + VARIANT* retVal) { + // Marshal the argument passed to the JavaScript function onto the NSIS stack. + switch (jsArg.vt) { + case VT_BSTR: + pushstring(jsArg.bstrVal); + break; + case VT_I4: { + TCHAR intArgStr[32] = _T(""); + _itot_s(jsArg.intVal, intArgStr, 10); + pushstring(intArgStr); + break; + } + case VT_BOOL: + pushstring(jsArg.boolVal == VARIANT_TRUE ? _T("1") : _T("0")); + break; + default: + // No other argument types supported. + pushstring(_T("")); + break; + } + + // Call the NSIS function. + int rv = g_executeCodeSegment((int)NSISFunctionAddr, nullptr); + + // Retrieve the return value from the NSIS stack. + TCHAR* nsisRetval = + (TCHAR*)HeapAlloc(GetProcessHeap(), 0, g_stringsize * sizeof(TCHAR)); + popstring(nsisRetval); + + // Pass the return value back to JavaScript, if it asked for one. + if (retVal) { + VariantInit(retVal); + retVal->vt = VT_BSTR; + retVal->bstrVal = SysAllocString(nsisRetval); + } + + HeapFree(GetProcessHeap(), 0, nsisRetval); +} + +PLUGINFUNCTION(RegisterCustomFunction) { + if (!gBrowser) { + Init(hWndParent, string_size, variables, stacktop, extra); + } + + TCHAR* funcAddrStr = + (TCHAR*)HeapAlloc(GetProcessHeap(), 0, g_stringsize * sizeof(TCHAR)); + popstring(funcAddrStr); + + TCHAR* funcName = + (TCHAR*)HeapAlloc(GetProcessHeap(), 0, g_stringsize * sizeof(TCHAR)); + popstring(funcName); + + if (gBrowser && funcAddrStr && funcName) { + // Apparently GetFunctionAddress returnes a 1-indexed offset, but + // ExecuteCodeSegment expects a 0-indexed one. Or something. + uintptr_t funcAddr = static_cast(_ttoi64(funcAddrStr)) - 1; + gBrowser->AddCustomFunction(funcName, CustomFunctionWrapper, + (void*)funcAddr); + } + + HeapFree(GetProcessHeap(), 0, funcName); + HeapFree(GetProcessHeap(), 0, funcAddrStr); +} diff --git a/other-licenses/nsis/Contrib/WebBrowser/Timers.cpp b/other-licenses/nsis/Contrib/WebBrowser/Timers.cpp new file mode 100644 index 0000000000..00844b7091 --- /dev/null +++ b/other-licenses/nsis/Contrib/WebBrowser/Timers.cpp @@ -0,0 +1,59 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0.If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include "exdll.h" + +static void APIENTRY TimerCallback(LPVOID NSISFunctionAddr, DWORD, DWORD) { + g_executeCodeSegment((int)NSISFunctionAddr, nullptr); +} + +PLUGINFUNCTION(CreateTimer) { + EXDLL_INIT(); + extra->RegisterPluginCallback(gHInst, NSISPluginCallback); + + TCHAR* funcAddrStr = + (TCHAR*)HeapAlloc(GetProcessHeap(), 0, g_stringsize * sizeof(TCHAR)); + popstring(funcAddrStr); + // Apparently GetFunctionAddress returnes a 1-indexed offset, but + // ExecuteCodeSegment expects a 0-indexed one. Or something. + uintptr_t funcAddr = static_cast(_ttoi64(funcAddrStr)) - 1; + HeapFree(GetProcessHeap(), 0, funcAddrStr); + + TCHAR* intervalStr = + (TCHAR*)HeapAlloc(GetProcessHeap(), 0, g_stringsize * sizeof(TCHAR)); + popstring(intervalStr); + long interval = _ttol(intervalStr); + HeapFree(GetProcessHeap(), 0, intervalStr); + + HANDLE timer = CreateWaitableTimer(nullptr, FALSE, nullptr); + if (!timer) { + return; + } + + // The interval we were passed is in milliseconds, so we need to convert it + // to the 100-nanosecond units that SetWaitableTimer expects. We also need to + // make it negative, because that's what signifies a relative offset from now + // instead of an epoch-based time stamp. + LARGE_INTEGER dueTime; + dueTime.QuadPart = -(interval * 10000); + + SetWaitableTimer(timer, &dueTime, interval, TimerCallback, (void*)funcAddr, + FALSE); + + TCHAR timerStr[32] = _T(""); + _ltot_s((long)timer, timerStr, 10); + pushstring(timerStr); +} + +PLUGINFUNCTION(CancelTimer) { + TCHAR* timerStr = + (TCHAR*)HeapAlloc(GetProcessHeap(), 0, g_stringsize * sizeof(TCHAR)); + popstring(timerStr); + HANDLE timer = reinterpret_cast(_ttoi(timerStr)); + HeapFree(GetProcessHeap(), 0, timerStr); + + CancelWaitableTimer(timer); + CloseHandle(timer); +} diff --git a/other-licenses/nsis/Contrib/WebBrowser/WebBrowser.cpp b/other-licenses/nsis/Contrib/WebBrowser/WebBrowser.cpp new file mode 100644 index 0000000000..59e0a1d881 --- /dev/null +++ b/other-licenses/nsis/Contrib/WebBrowser/WebBrowser.cpp @@ -0,0 +1,604 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0.If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "WebBrowser.h" +#include + +WebBrowser::WebBrowser(HWND _hWndParent) : mHwndParent(_hWndParent) { + // Whatever executed this constructor owns our first reference. + AddRef(); + + HRESULT hr = ::OleCreate(CLSID_WebBrowser, IID_IOleObject, OLERENDER_DRAW, 0, + this, this, (void**)&mOleObject); + if (FAILED(hr)) { + return; + } + + RECT posRect; + ::GetClientRect(mHwndParent, &posRect); + + hr = mOleObject->DoVerb(OLEIVERB_INPLACEACTIVATE, nullptr, this, 0, + mHwndParent, &posRect); + if (FAILED(hr)) { + mOleObject->Release(); + mOleObject = nullptr; + return; + } + + SetRect(posRect); + + hr = mOleObject->QueryInterface(&mWebBrowser2); + if (FAILED(hr)) { + mOleObject->Release(); + mOleObject = nullptr; + return; + } + + mWebBrowser2->put_Silent(VARIANT_TRUE); +} + +WebBrowser::~WebBrowser() { + if (mWebBrowser2) { + mWebBrowser2->Release(); + mWebBrowser2 = nullptr; + } + if (mOleInPlaceActiveObject) { + mOleInPlaceActiveObject->Release(); + mOleInPlaceActiveObject = nullptr; + } + if (mOleInPlaceObject) { + mOleInPlaceObject->Release(); + mOleInPlaceObject = nullptr; + } + if (mOleObject) { + mOleObject->Release(); + mOleObject = nullptr; + } +} + +void WebBrowser::Shutdown() { + if (mOleObject) { + mOleObject->Close(OLECLOSE_NOSAVE); + mOleObject->SetClientSite(nullptr); + } +} + +bool WebBrowser::IsInitialized() { return mOleObject != nullptr; } + +HRESULT WebBrowser::ActiveObjectTranslateAccelerator(bool tab, LPMSG lpmsg) { + if (IsInitialized() && mOleInPlaceActiveObject) { + HRESULT hr = mOleInPlaceActiveObject->TranslateAcceleratorW(lpmsg); + if (hr == S_FALSE && tab) { + // The browser control will give up focus, but it is the only control so + // it would get focus again via IsDialogMessage. This does not result in + // the focus returning to the web page, though, so instead let the + // control process the tab again. + hr = mOleInPlaceActiveObject->TranslateAcceleratorW(lpmsg); + } + return hr; + } else { + return S_FALSE; + } +} + +void WebBrowser::SetRect(const RECT& _rc) { + mRect = _rc; + + if (mOleInPlaceObject) { + mOleInPlaceObject->SetObjectRects(&mRect, &mRect); + } +} + +void WebBrowser::Resize(DWORD width, DWORD height) { + RECT r = mRect; + r.bottom = r.top + height; + r.right = r.left + width; + SetRect(r); +} + +void WebBrowser::Navigate(wchar_t* url) { + if (!IsInitialized()) { + return; + } + + VARIANT flags; + VariantInit(&flags); + flags.vt = VT_I4; + flags.intVal = navNoHistory | navEnforceRestricted | navUntrustedForDownload | + navBlockRedirectsXDomain; + + mWebBrowser2->Navigate(url, &flags, nullptr, nullptr, nullptr); +} + +void WebBrowser::AddCustomFunction(wchar_t* name, CustomFunction function, + void* arg) { + CustomFunctionRecord record = {name, function, arg}; + +// We've disabled exceptions but push_back can throw on an allocation +// failure, so we need to suppress a warning trying to tell us that +// that combination doesn't make any sense. +#pragma warning(suppress : 4530) + mCustomFunctions.push_back(record); +} + +////////////////////////////////////////////////////////////////////////////// +// IUnknown +////////////////////////////////////////////////////////////////////////////// +// This is a standard IUnknown implementation, we don't need anything special. + +HRESULT STDMETHODCALLTYPE WebBrowser::QueryInterface(REFIID riid, + void** ppvObject) { + if (riid == __uuidof(IUnknown)) { + *ppvObject = static_cast(this); + } else if (riid == __uuidof(IOleClientSite)) { + *ppvObject = static_cast(this); + } else if (riid == __uuidof(IOleInPlaceSite)) { + *ppvObject = static_cast(this); + } else if (riid == __uuidof(IDropTarget)) { + *ppvObject = static_cast(this); + } else if (riid == __uuidof(IStorage)) { + *ppvObject = static_cast(this); + } else if (riid == __uuidof(IDocHostUIHandler)) { + *ppvObject = static_cast(this); + } else if (riid == __uuidof(IDocHostShowUI)) { + *ppvObject = static_cast(this); + } else if (riid == __uuidof(IDispatch)) { + *ppvObject = static_cast(this); + } else { + *ppvObject = nullptr; + return E_NOINTERFACE; + } + + AddRef(); + return S_OK; +} + +ULONG STDMETHODCALLTYPE WebBrowser::AddRef() { + return InterlockedIncrement(&mComRefCount); +} + +ULONG STDMETHODCALLTYPE WebBrowser::Release() { + ULONG refCount = InterlockedDecrement(&mComRefCount); + if (refCount == 0) { + delete this; + } + return refCount; +} + +////////////////////////////////////////////////////////////////////////////// +// IOleWindow +////////////////////////////////////////////////////////////////////////////// + +HRESULT STDMETHODCALLTYPE +WebBrowser::GetWindow(__RPC__deref_out_opt HWND* phwnd) { + *phwnd = mHwndParent; + return S_OK; +} + +HRESULT STDMETHODCALLTYPE WebBrowser::ContextSensitiveHelp(BOOL fEnterMode) { + // We don't provide context-sensitive help. + return E_NOTIMPL; +} + +////////////////////////////////////////////////////////////////////////////// +// IOleInPlaceSite +////////////////////////////////////////////////////////////////////////////// + +HRESULT STDMETHODCALLTYPE WebBrowser::CanInPlaceActivate() { + // We always support in-place activation. + return S_OK; +} + +HRESULT STDMETHODCALLTYPE WebBrowser::OnInPlaceActivate() { + OleLockRunning(mOleObject, TRUE, FALSE); + mOleObject->QueryInterface(&mOleInPlaceObject); + mOleInPlaceObject->QueryInterface(&mOleInPlaceActiveObject); + mOleInPlaceObject->SetObjectRects(&mRect, &mRect); + + return S_OK; +} + +HRESULT STDMETHODCALLTYPE WebBrowser::OnUIActivate() { + // Nothing to do before activating the control's UI. + return S_OK; +} + +HRESULT STDMETHODCALLTYPE WebBrowser::GetWindowContext( + __RPC__deref_out_opt IOleInPlaceFrame** ppFrame, + __RPC__deref_out_opt IOleInPlaceUIWindow** ppDoc, + __RPC__out LPRECT lprcPosRect, __RPC__out LPRECT lprcClipRect, + __RPC__inout LPOLEINPLACEFRAMEINFO lpFrameInfo) { + *ppFrame = nullptr; + *ppDoc = nullptr; + *lprcPosRect = mRect; + *lprcClipRect = mRect; + + lpFrameInfo->fMDIApp = false; + lpFrameInfo->hwndFrame = mHwndParent; + lpFrameInfo->haccel = nullptr; + lpFrameInfo->cAccelEntries = 0; + + return S_OK; +} + +HRESULT STDMETHODCALLTYPE WebBrowser::Scroll(SIZE scrollExtant) { + // We should have disabled all scrollbars. + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE WebBrowser::OnUIDeactivate(BOOL fUndoable) { + // Nothing to do after deactivating the control's UI. + return S_OK; +} + +HRESULT STDMETHODCALLTYPE WebBrowser::OnInPlaceDeactivate() { + if (mOleInPlaceObject) { + mOleInPlaceObject->Release(); + mOleInPlaceObject = nullptr; + } + + return S_OK; +} + +// We don't support the concept of undo. +HRESULT STDMETHODCALLTYPE WebBrowser::DiscardUndoState() { return E_NOTIMPL; } + +HRESULT STDMETHODCALLTYPE WebBrowser::DeactivateAndUndo() { return E_NOTIMPL; } + +// We don't support moving or resizing the control. +HRESULT STDMETHODCALLTYPE +WebBrowser::OnPosRectChange(__RPC__in LPCRECT lprcPosRect) { + return E_NOTIMPL; +} + +////////////////////////////////////////////////////////////////////////////// +// IOleClientSite +////////////////////////////////////////////////////////////////////////////// +// We don't need anything that IOleClientSite does, because we're doing OLE +// only in the most basic sense and we don't support linking (or, indeed, +// embedding), but some implementation of this interface is required for +// OleCreate to work, so we have to have a stub version. + +HRESULT STDMETHODCALLTYPE WebBrowser::SaveObject() { return E_NOTIMPL; } + +HRESULT STDMETHODCALLTYPE +WebBrowser::GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker, + __RPC__deref_out_opt IMoniker** ppmk) { + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE +WebBrowser::GetContainer(__RPC__deref_out_opt IOleContainer** ppContainer) { + *ppContainer = nullptr; + return E_NOINTERFACE; +} + +HRESULT STDMETHODCALLTYPE WebBrowser::ShowObject() { return S_OK; } + +HRESULT STDMETHODCALLTYPE WebBrowser::OnShowWindow(BOOL fShow) { return S_OK; } + +HRESULT STDMETHODCALLTYPE WebBrowser::RequestNewObjectLayout() { + return E_NOTIMPL; +} + +////////////////////////////////////////////////////////////////////////////// +// IDropTarget +////////////////////////////////////////////////////////////////////////////// +// This is a stub implementation which blocks all dropping. The main reason we +// want to do that is prevent accidentally dropping something on the control +// and having it navigate, because there's no recovering from that except to +// restart the app, and also it would look ridiculous. There could also be +// security implications though, which we'd rather just avoid engaging with +// altogether if we can. + +HRESULT STDMETHODCALLTYPE +WebBrowser::DragEnter(__RPC__in_opt IDataObject* pDataObj, DWORD grfKeyState, + POINTL pt, __RPC__inout DWORD* pdwEffect) { + *pdwEffect = DROPEFFECT_NONE; + return S_OK; +} + +HRESULT STDMETHODCALLTYPE WebBrowser::DragOver(DWORD grfKeyState, POINTL pt, + __RPC__inout DWORD* pdwEffect) { + *pdwEffect = DROPEFFECT_NONE; + return S_OK; +} + +HRESULT STDMETHODCALLTYPE WebBrowser::DragLeave() { return S_OK; } + +HRESULT STDMETHODCALLTYPE WebBrowser::Drop(__RPC__in_opt IDataObject* pDataObj, + DWORD grfKeyState, POINTL pt, + __RPC__inout DWORD* pdwEffect) { + *pdwEffect = DROPEFFECT_NONE; + return S_OK; +} + +////////////////////////////////////////////////////////////////////////////// +// IStorage +////////////////////////////////////////////////////////////////////////////// +// We don't need anything that IStorage does, but we have to pass some +// implementation of it to OleCreate, so we need to have a stub version. + +HRESULT STDMETHODCALLTYPE WebBrowser::CreateStream( + __RPC__in_string const OLECHAR* pwcsName, DWORD grfMode, DWORD reserved1, + DWORD reserved2, __RPC__deref_out_opt IStream** ppstm) { + *ppstm = nullptr; + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE WebBrowser::OpenStream(const OLECHAR* pwcsName, + void* reserved1, DWORD grfMode, + DWORD reserved2, + IStream** ppstm) { + *ppstm = nullptr; + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE WebBrowser::CreateStorage( + __RPC__in_string const OLECHAR* pwcsName, DWORD grfMode, DWORD reserved1, + DWORD reserved2, __RPC__deref_out_opt IStorage** ppstg) { + *ppstg = nullptr; + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE +WebBrowser::OpenStorage(__RPC__in_opt_string const OLECHAR* pwcsName, + __RPC__in_opt IStorage* pstgPriority, DWORD grfMode, + __RPC__deref_opt_in_opt SNB snbExclude, DWORD reserved, + __RPC__deref_out_opt IStorage** ppstg) { + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE WebBrowser::CopyTo(DWORD ciidExclude, + const IID* rgiidExclude, + __RPC__in_opt SNB snbExclude, + IStorage* pstgDest) { + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE WebBrowser::MoveElementTo( + __RPC__in_string const OLECHAR* pwcsName, __RPC__in_opt IStorage* pstgDest, + __RPC__in_string const OLECHAR* pwcsNewName, DWORD grfFlags) { + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE WebBrowser::Commit(DWORD grfCommitFlags) { + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE WebBrowser::Revert() { return E_NOTIMPL; } + +HRESULT STDMETHODCALLTYPE WebBrowser::EnumElements(DWORD reserved1, + void* reserved2, + DWORD reserved3, + IEnumSTATSTG** ppenum) { + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE +WebBrowser::DestroyElement(__RPC__in_string const OLECHAR* pwcsName) { + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE +WebBrowser::RenameElement(__RPC__in_string const OLECHAR* pwcsOldName, + __RPC__in_string const OLECHAR* pwcsNewName) { + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE WebBrowser::SetElementTimes( + __RPC__in_opt_string const OLECHAR* pwcsName, + __RPC__in_opt const FILETIME* pctime, __RPC__in_opt const FILETIME* patime, + __RPC__in_opt const FILETIME* pmtime) { + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE WebBrowser::SetClass(__RPC__in REFCLSID clsid) { + return S_OK; +} + +HRESULT STDMETHODCALLTYPE WebBrowser::SetStateBits(DWORD grfStateBits, + DWORD grfMask) { + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE WebBrowser::Stat(__RPC__out STATSTG* pstatstg, + DWORD grfStatFlag) { + return E_NOTIMPL; +} + +////////////////////////////////////////////////////////////////////////////// +// IDocHostUIHandler +////////////////////////////////////////////////////////////////////////////// +// Our implementation for this interface is basically all about disabling +// things that we don't want/need. + +HRESULT __stdcall WebBrowser::ShowContextMenu(DWORD dwID, POINT* ppt, + IUnknown* pcmdtReserved, + IDispatch* pdispReserved) { + // Returning S_OK signals that we've handled the request for a context menu + // (which we did, by doing nothing), so the control won't try to open one. + return S_OK; +} + +HRESULT __stdcall WebBrowser::GetHostInfo(DOCHOSTUIINFO* pInfo) { + pInfo->cbSize = sizeof(DOCHOSTUIINFO); + pInfo->dwFlags = + DOCHOSTUIFLAG_DIALOG | DOCHOSTUIFLAG_DISABLE_HELP_MENU | + DOCHOSTUIFLAG_NO3DBORDER | DOCHOSTUIFLAG_SCROLL_NO | + DOCHOSTUIFLAG_OPENNEWWIN | DOCHOSTUIFLAG_OVERRIDEBEHAVIORFACTORY | + DOCHOSTUIFLAG_THEME | DOCHOSTUIFLAG_LOCAL_MACHINE_ACCESS_CHECK | + DOCHOSTUIFLAG_DISABLE_UNTRUSTEDPROTOCOL | DOCHOSTUIFLAG_DPI_AWARE; + pInfo->dwDoubleClick = DOCHOSTUIDBLCLK_DEFAULT; + pInfo->pchHostCss = nullptr; + pInfo->pchHostNS = nullptr; + return S_OK; +} + +HRESULT __stdcall WebBrowser::ShowUI(DWORD dwID, + IOleInPlaceActiveObject* pActiveObject, + IOleCommandTarget* pCommandTarget, + IOleInPlaceFrame* pFrame, + IOleInPlaceUIWindow* pDoc) { + return E_NOTIMPL; +} + +HRESULT __stdcall WebBrowser::HideUI() { return E_NOTIMPL; } + +HRESULT __stdcall WebBrowser::UpdateUI() { return E_NOTIMPL; } + +HRESULT __stdcall WebBrowser::EnableModeless(BOOL fEnable) { return E_NOTIMPL; } + +HRESULT __stdcall WebBrowser::OnDocWindowActivate(BOOL fActivate) { + return E_NOTIMPL; +} + +HRESULT __stdcall WebBrowser::OnFrameWindowActivate(BOOL fActivate) { + return E_NOTIMPL; +} + +HRESULT __stdcall WebBrowser::ResizeBorder(LPCRECT prcBorder, + IOleInPlaceUIWindow* pUIWindow, + BOOL fRameWindow) { + return E_NOTIMPL; +} + +HRESULT __stdcall WebBrowser::TranslateAccelerator(LPMSG lpMsg, + const GUID* pguidCmdGroup, + DWORD nCmdID) { + return S_FALSE; +} + +HRESULT __stdcall WebBrowser::GetOptionKeyPath(LPOLESTR* pchKey, DWORD dw) { + return E_NOTIMPL; +} + +HRESULT __stdcall WebBrowser::GetDropTarget(IDropTarget* pDropTarget, + IDropTarget** ppDropTarget) { + // The IDropTarget implementation that we need is an empty stub, so we'll do + // the easy and convenient thing and just use this object. + return QueryInterface(IID_PPV_ARGS(ppDropTarget)); +} + +HRESULT __stdcall WebBrowser::GetExternal(IDispatch** ppDispatch) { + // This object has to implement IDispatch anyway so that we can use + // DISPID_AMBIENT_DLCONTROL, so we'll make this the external handler also. + return QueryInterface(IID_PPV_ARGS(ppDispatch)); +} + +HRESULT __stdcall WebBrowser::TranslateUrl(DWORD dwTranslate, LPWSTR pchURLIn, + LPWSTR* ppchURLOut) { + *ppchURLOut = nullptr; + return E_NOTIMPL; +} + +HRESULT __stdcall WebBrowser::FilterDataObject(IDataObject* pDO, + IDataObject** ppDORet) { + *ppDORet = nullptr; + return E_NOTIMPL; +} + +////////////////////////////////////////////////////////////////////////////// +// IDocHostShowUI +////////////////////////////////////////////////////////////////////////////// + +HRESULT __stdcall WebBrowser::ShowMessage(HWND hwnd, LPOLESTR lpstrText, + LPOLESTR lpstrCaption, DWORD dwType, + LPOLESTR lpstrHelpFile, + DWORD dwHelpContext, + LRESULT* plResult) { + // Don't allow MSHTML to generate message boxes. + return S_OK; +} + +HRESULT __stdcall WebBrowser::ShowHelp(HWND hwnd, LPOLESTR pszHelpFile, + UINT uCommand, DWORD dwData, + POINT ptMouse, + IDispatch* pDispatchObjectHit) { + // Don't allow MSHTML to show any help. + return S_OK; +} + +////////////////////////////////////////////////////////////////////////////// +// IDispatch +////////////////////////////////////////////////////////////////////////////// + +// We're not using a type library. +HRESULT __stdcall WebBrowser::GetTypeInfoCount(UINT* pctinfo) { + if (pctinfo) { + *pctinfo = 0; + } + return S_OK; +} + +HRESULT __stdcall WebBrowser::GetTypeInfo(UINT iTInfo, LCID lcid, + ITypeInfo** ppTInfo) { + return E_NOTIMPL; +} + +HRESULT __stdcall WebBrowser::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames, + UINT cNames, LCID lcid, + DISPID* rgDispId) { + if (cNames != 1) { + return E_NOTIMPL; + } + + for (size_t i = 0; i < mCustomFunctions.size(); ++i) { + if (mCustomFunctions[i].mName == rgszNames[0]) { + // DISPID values need to be 1-indexed because 0 is reserved + // (DISPID_VALUE). + *rgDispId = i + 1; + return S_OK; + } + } + + *rgDispId = DISPID_UNKNOWN; + return DISP_E_UNKNOWNNAME; +} + +HRESULT __stdcall WebBrowser::Invoke(DISPID dispIdMember, REFIID riid, + LCID lcid, WORD wFlags, + DISPPARAMS* pDispParams, + VARIANT* pVarResult, EXCEPINFO* pExcepInfo, + UINT* puArgErr) { + if (dispIdMember == DISPID_AMBIENT_DLCONTROL && pVarResult) { + VariantClear(pVarResult); + pVarResult->vt = VT_I4; + // As a light security measure, disable a bunch of stuff we don't want + // to be able to run in the web control. + pVarResult->intVal = DLCTL_NO_JAVA | DLCTL_NO_DLACTIVEXCTLS | + DLCTL_NO_RUNACTIVEXCTLS | DLCTL_NO_FRAMEDOWNLOAD | + DLCTL_NO_BEHAVIORS | DLCTL_NO_CLIENTPULL | + DLCTL_NOFRAMES | DLCTL_FORCEOFFLINE | DLCTL_SILENT | + DLCTL_OFFLINE | DLCTL_DLIMAGES; + return S_OK; + } + + // Otherwise this should be one of our custom functions. + // We only support invoking these as methods, not property access. + if ((wFlags & DISPATCH_METHOD) == 0) { + return DISP_E_TYPEMISMATCH; + } + + // Make sure this DISPID is valid in our custom functions list. + // DISPID values are 1-indexed because 0 is reserved (DISPID_VALUE). + DISPID customFunctionIndex = dispIdMember - 1; + if (customFunctionIndex < 0 || + customFunctionIndex >= (DISPID)mCustomFunctions.size()) { + return DISP_E_MEMBERNOTFOUND; + } + + // If the caller passed an argument to this custom function, use it. + // If not, make an empty VARIANT we can pass to it instead. + VARIANT argument; + VariantInit(&argument); + if (pDispParams->cArgs > 0) { + argument = pDispParams->rgvarg[0]; + } + + CustomFunctionRecord foundFunction = mCustomFunctions[customFunctionIndex]; + foundFunction.mFunction(foundFunction.mArg, argument, pVarResult); + + return S_OK; +} diff --git a/other-licenses/nsis/Contrib/WebBrowser/WebBrowser.h b/other-licenses/nsis/Contrib/WebBrowser/WebBrowser.h new file mode 100644 index 0000000000..8bc4800a2e --- /dev/null +++ b/other-licenses/nsis/Contrib/WebBrowser/WebBrowser.h @@ -0,0 +1,250 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0.If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include + +#include +#include + +class WebBrowser final : + /* public IUnknown, */ + /* public IOleWindow, */ + public IOleInPlaceSite, + public IOleClientSite, + public IDropTarget, + public IStorage, + public IDocHostUIHandler, + public IDocHostShowUI, + public IDispatch { + public: + ///////////////////////////////////////////////////////////////////////////// + // Our own methods + ///////////////////////////////////////////////////////////////////////////// + WebBrowser(HWND hWndParent); + ~WebBrowser(); + + WebBrowser(const WebBrowser&) = delete; + WebBrowser& operator=(const WebBrowser&) = delete; + + void Shutdown(); + + bool IsInitialized(); + + HRESULT ActiveObjectTranslateAccelerator(bool tab, LPMSG lpmsg); + void SetRect(const RECT& _rc); + void Resize(DWORD width, DWORD height); + void Navigate(wchar_t* szUrl); + + using CustomFunction = void (*)(void* context, VARIANT parameter, + VARIANT* retVal); + void AddCustomFunction(wchar_t* name, CustomFunction function, void* arg); + + ///////////////////////////////////////////////////////////////////////////// + // Data members + ///////////////////////////////////////////////////////////////////////////// + private: + IOleObject* mOleObject = nullptr; + IOleInPlaceObject* mOleInPlaceObject = nullptr; + IOleInPlaceActiveObject* mOleInPlaceActiveObject = nullptr; + IWebBrowser2* mWebBrowser2 = nullptr; + + LONG mComRefCount = 0; + + RECT mRect = {0, 0, 0, 0}; + + HWND mHwndParent = nullptr; + + struct CustomFunctionRecord { + std::wstring mName; + CustomFunction mFunction; + void* mArg; + }; + std::vector mCustomFunctions; + + ////////////////////////////////////////////////////////////////////////////// + // COM interface methods + ////////////////////////////////////////////////////////////////////////////// + public: + // IUnknown + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, + void** ppvObject) override; + ULONG STDMETHODCALLTYPE AddRef() override; + ULONG STDMETHODCALLTYPE Release() override; + + // IOleWindow + HRESULT STDMETHODCALLTYPE + GetWindow(__RPC__deref_out_opt HWND* phwnd) override; + HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL fEnterMode) override; + + // IOleInPlaceSite + HRESULT STDMETHODCALLTYPE CanInPlaceActivate() override; + HRESULT STDMETHODCALLTYPE OnInPlaceActivate() override; + HRESULT STDMETHODCALLTYPE OnUIActivate() override; + HRESULT STDMETHODCALLTYPE GetWindowContext( + __RPC__deref_out_opt IOleInPlaceFrame** ppFrame, + __RPC__deref_out_opt IOleInPlaceUIWindow** ppDoc, + __RPC__out LPRECT lprcPosRect, __RPC__out LPRECT lprcClipRect, + __RPC__inout LPOLEINPLACEFRAMEINFO lpFrameInfo) override; + HRESULT STDMETHODCALLTYPE Scroll(SIZE scrollExtant) override; + HRESULT STDMETHODCALLTYPE OnUIDeactivate(BOOL fUndoable) override; + HRESULT STDMETHODCALLTYPE OnInPlaceDeactivate() override; + HRESULT STDMETHODCALLTYPE DiscardUndoState() override; + HRESULT STDMETHODCALLTYPE DeactivateAndUndo() override; + HRESULT STDMETHODCALLTYPE + OnPosRectChange(__RPC__in LPCRECT lprcPosRect) override; + + // IOleClientSite + HRESULT STDMETHODCALLTYPE SaveObject() override; + HRESULT STDMETHODCALLTYPE + GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker, + __RPC__deref_out_opt IMoniker** ppmk) override; + HRESULT STDMETHODCALLTYPE + GetContainer(__RPC__deref_out_opt IOleContainer** ppContainer) override; + HRESULT STDMETHODCALLTYPE ShowObject() override; + HRESULT STDMETHODCALLTYPE OnShowWindow(BOOL fShow) override; + HRESULT STDMETHODCALLTYPE RequestNewObjectLayout() override; + + // IDropTarget + HRESULT STDMETHODCALLTYPE DragEnter(__RPC__in_opt IDataObject* pDataObj, + DWORD grfKeyState, POINTL pt, + __RPC__inout DWORD* pdwEffect) override; + HRESULT STDMETHODCALLTYPE DragOver(DWORD grfKeyState, POINTL pt, + __RPC__inout DWORD* pdwEffect) override; + HRESULT STDMETHODCALLTYPE DragLeave() override; + HRESULT STDMETHODCALLTYPE Drop(__RPC__in_opt IDataObject* pDataObj, + DWORD grfKeyState, POINTL pt, + __RPC__inout DWORD* pdwEffect) override; + + // IStorage + HRESULT STDMETHODCALLTYPE CreateStream( + __RPC__in_string const OLECHAR* pwcsName, DWORD grfMode, DWORD reserved1, + DWORD reserved2, __RPC__deref_out_opt IStream** ppstm) override; + HRESULT STDMETHODCALLTYPE OpenStream(const OLECHAR* pwcsName, void* reserved1, + DWORD grfMode, DWORD reserved2, + IStream** ppstm) override; + HRESULT STDMETHODCALLTYPE CreateStorage( + __RPC__in_string const OLECHAR* pwcsName, DWORD grfMode, DWORD reserved1, + DWORD reserved2, __RPC__deref_out_opt IStorage** ppstg) override; + HRESULT STDMETHODCALLTYPE + OpenStorage(__RPC__in_opt_string const OLECHAR* pwcsName, + __RPC__in_opt IStorage* pstgPriority, DWORD grfMode, + __RPC__deref_opt_in_opt SNB snbExclude, DWORD reserved, + __RPC__deref_out_opt IStorage** ppstg) override; + HRESULT STDMETHODCALLTYPE CopyTo(DWORD ciidExclude, const IID* rgiidExclude, + __RPC__in_opt SNB snbExclude, + IStorage* pstgDest) override; + HRESULT STDMETHODCALLTYPE MoveElementTo( + __RPC__in_string const OLECHAR* pwcsName, + __RPC__in_opt IStorage* pstgDest, + __RPC__in_string const OLECHAR* pwcsNewName, DWORD grfFlags) override; + HRESULT STDMETHODCALLTYPE Commit(DWORD grfCommitFlags) override; + HRESULT STDMETHODCALLTYPE Revert(void) override; + HRESULT STDMETHODCALLTYPE EnumElements(DWORD reserved1, void* reserved2, + DWORD reserved3, + IEnumSTATSTG** ppenum) override; + HRESULT STDMETHODCALLTYPE + DestroyElement(__RPC__in_string const OLECHAR* pwcsName) override; + HRESULT STDMETHODCALLTYPE + RenameElement(__RPC__in_string const OLECHAR* pwcsOldName, + __RPC__in_string const OLECHAR* pwcsNewName) override; + HRESULT STDMETHODCALLTYPE + SetElementTimes(__RPC__in_opt_string const OLECHAR* pwcsName, + __RPC__in_opt const FILETIME* pctime, + __RPC__in_opt const FILETIME* patime, + __RPC__in_opt const FILETIME* pmtime) override; + HRESULT STDMETHODCALLTYPE SetClass(__RPC__in REFCLSID clsid) override; + HRESULT STDMETHODCALLTYPE SetStateBits(DWORD grfStateBits, + DWORD grfMask) override; + HRESULT STDMETHODCALLTYPE Stat(__RPC__out STATSTG* pstatstg, + DWORD grfStatFlag) override; + + // IDocHostUIHandler + HRESULT STDMETHODCALLTYPE ShowContextMenu( + _In_ DWORD dwID, _In_ POINT* ppt, _In_ IUnknown* pcmdtReserved, + _In_ IDispatch* pdispReserved) override; + HRESULT STDMETHODCALLTYPE GetHostInfo(_Inout_ DOCHOSTUIINFO* pInfo) override; + HRESULT STDMETHODCALLTYPE ShowUI(_In_ DWORD dwID, + _In_ IOleInPlaceActiveObject* pActiveObject, + _In_ IOleCommandTarget* pCommandTarget, + _In_ IOleInPlaceFrame* pFrame, + _In_ IOleInPlaceUIWindow* pDoc) override; + HRESULT STDMETHODCALLTYPE HideUI() override; + HRESULT STDMETHODCALLTYPE UpdateUI() override; + HRESULT STDMETHODCALLTYPE EnableModeless(BOOL fEnable) override; + HRESULT STDMETHODCALLTYPE OnDocWindowActivate(BOOL fActivate) override; + HRESULT STDMETHODCALLTYPE OnFrameWindowActivate(BOOL fActivate) override; + HRESULT STDMETHODCALLTYPE ResizeBorder(_In_ LPCRECT prcBorder, + _In_ IOleInPlaceUIWindow* pUIWindow, + _In_ BOOL fRameWindow) override; + HRESULT STDMETHODCALLTYPE TranslateAccelerator(LPMSG lpMsg, + const GUID* pguidCmdGroup, + DWORD nCmdID) override; + HRESULT STDMETHODCALLTYPE GetOptionKeyPath(_Out_ LPOLESTR* pchKey, + DWORD dw) override; + HRESULT STDMETHODCALLTYPE + GetDropTarget(_In_ IDropTarget* pDropTarget, + _Outptr_ IDropTarget** ppDropTarget) override; + HRESULT STDMETHODCALLTYPE + GetExternal(_Outptr_result_maybenull_ IDispatch** ppDispatch) override; + HRESULT STDMETHODCALLTYPE TranslateUrl(DWORD dwTranslate, + _In_ LPWSTR pchURLIn, + _Outptr_ LPWSTR* ppchURLOut) override; + HRESULT STDMETHODCALLTYPE + FilterDataObject(_In_ IDataObject* pDO, + _Outptr_result_maybenull_ IDataObject** ppDORet) override; + + // IDocHostShowUI + HRESULT STDMETHODCALLTYPE ShowMessage( + /* [in] */ HWND hwnd, + /* [annotation][in] */ + _In_ LPOLESTR lpstrText, + /* [annotation][in] */ + _In_ LPOLESTR lpstrCaption, + /* [in] */ DWORD dwType, + /* [annotation][in] */ + _In_ LPOLESTR lpstrHelpFile, + /* [in] */ DWORD dwHelpContext, + /* [out] */ LRESULT* plResult) override; + HRESULT STDMETHODCALLTYPE ShowHelp( + /* [in] */ HWND hwnd, + /* [annotation][in] */ + _In_ LPOLESTR pszHelpFile, + /* [in] */ UINT uCommand, + /* [in] */ DWORD dwData, + /* [in] */ POINT ptMouse, + /* [out] */ IDispatch* pDispatchObjectHit) override; + + // IDispatch + HRESULT STDMETHODCALLTYPE GetTypeInfoCount( + /* [out] */ __RPC__out UINT* pctinfo) override; + HRESULT STDMETHODCALLTYPE GetTypeInfo( + /* [in] */ UINT iTInfo, + /* [in] */ LCID lcid, + /* [out] */ __RPC__deref_out_opt ITypeInfo** ppTInfo) override; + HRESULT STDMETHODCALLTYPE GetIDsOfNames( + /* [in] */ __RPC__in REFIID riid, + /* [size_is][in] */ __RPC__in_ecount_full(cNames) LPOLESTR* rgszNames, + /* [range][in] */ __RPC__in_range(0, 16384) UINT cNames, + /* [in] */ LCID lcid, + /* [size_is][out] */ __RPC__out_ecount_full(cNames) DISPID* rgDispId) + override; + /* [local] */ HRESULT STDMETHODCALLTYPE Invoke( + /* [annotation][in] */ + _In_ DISPID dispIdMember, + /* [annotation][in] */ + _In_ REFIID riid, + /* [annotation][in] */ + _In_ LCID lcid, + /* [annotation][in] */ + _In_ WORD wFlags, + /* [annotation][out][in] */ + _In_ DISPPARAMS* pDispParams, + /* [annotation][out] */ + _Out_opt_ VARIANT* pVarResult, + /* [annotation][out] */ + _Out_opt_ EXCEPINFO* pExcepInfo, + /* [annotation][out] */ + _Out_opt_ UINT* puArgErr) override; +}; \ No newline at end of file diff --git a/other-licenses/nsis/Contrib/WebBrowser/WebBrowser.sln b/other-licenses/nsis/Contrib/WebBrowser/WebBrowser.sln new file mode 100644 index 0000000000..8e12b98f5e --- /dev/null +++ b/other-licenses/nsis/Contrib/WebBrowser/WebBrowser.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.28803.452 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WebBrowser", "WebBrowser.vcxproj", "{EF903B79-AD97-45E0-BC6E-4FF846D6A2ED}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x86 = Debug|x86 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {EF903B79-AD97-45E0-BC6E-4FF846D6A2ED}.Debug|x86.ActiveCfg = Debug|Win32 + {EF903B79-AD97-45E0-BC6E-4FF846D6A2ED}.Debug|x86.Build.0 = Debug|Win32 + {EF903B79-AD97-45E0-BC6E-4FF846D6A2ED}.Release|x86.ActiveCfg = Release|Win32 + {EF903B79-AD97-45E0-BC6E-4FF846D6A2ED}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {3A087FCC-55DC-4C48-8A22-A6FFB3247674} + EndGlobalSection +EndGlobal diff --git a/other-licenses/nsis/Contrib/WebBrowser/WebBrowser.vcxproj b/other-licenses/nsis/Contrib/WebBrowser/WebBrowser.vcxproj new file mode 100644 index 0000000000..8d13e050b6 --- /dev/null +++ b/other-licenses/nsis/Contrib/WebBrowser/WebBrowser.vcxproj @@ -0,0 +1,160 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + + + {EF903B79-AD97-45E0-BC6E-4FF846D6A2ED} + 10.0 + + + + DynamicLibrary + v142 + false + Unicode + false + + + DynamicLibrary + v142 + false + Unicode + true + false + + + + + + + + + + + + + + + .\Release\ + .\Release\ + false + + + .\Debug\ + .\Debug\ + true + + + + MultiThreaded + true + MinSpace + true + Level3 + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + Size + None + false + false + false + true + + + true + NDEBUG;%(PreprocessorDefinitions) + .\Release\WebBrowser.tlb + true + Win32 + + + 0x080a + NDEBUG;%(PreprocessorDefinitions) + + + true + .\Release\WebBrowser.bsc + + + true + true + Windows + .\Release\WebBrowser.dll + .\Release\WebBrowser.lib + odbc32.lib;odbccp32.lib;urlmon.lib;%(AdditionalDependencies) + false + true + UseLinkTimeCodeGeneration + true + + + + + + + MultiThreadedDebug + Default + Disabled + true + Level3 + EditAndContinue + WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + EnableFastChecks + false + Default + + + true + _DEBUG;%(PreprocessorDefinitions) + .\Debug\WebBrowser.tlb + true + Win32 + + + 0x080a + _DEBUG;%(PreprocessorDefinitions) + + + true + .\Debug\WebBrowser.bsc + + + true + true + true + Windows + .\Debug\WebBrowser.dll + .\Debug\WebBrowser.lib + odbc32.lib;odbccp32.lib;urlmon.lib;%(AdditionalDependencies) + false + false + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/other-licenses/nsis/Contrib/WebBrowser/exdll.cpp b/other-licenses/nsis/Contrib/WebBrowser/exdll.cpp new file mode 100644 index 0000000000..3cad7307ee --- /dev/null +++ b/other-licenses/nsis/Contrib/WebBrowser/exdll.cpp @@ -0,0 +1,30 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0.If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "exdll.h" + +unsigned int g_stringsize; +stack_t** g_stacktop; +int(__stdcall* g_executeCodeSegment)(int pos, HWND hwndProgress); +HWND g_hwndParent; + +int popstring(TCHAR* str) { + stack_t* th; + if (!g_stacktop || !*g_stacktop) return 1; + th = (*g_stacktop); + lstrcpy(str, th->text); + *g_stacktop = th->next; + GlobalFree((HGLOBAL)th); + return 0; +} + +void pushstring(const TCHAR* str) { + stack_t* th; + if (!g_stacktop) return; + th = (stack_t*)GlobalAlloc(GPTR, + sizeof(stack_t) + (g_stringsize * sizeof(TCHAR))); + lstrcpyn(th->text, str, g_stringsize); + th->next = *g_stacktop; + *g_stacktop = th; +} diff --git a/other-licenses/nsis/Contrib/WebBrowser/exdll.h b/other-licenses/nsis/Contrib/WebBrowser/exdll.h new file mode 100644 index 0000000000..1fa5659641 --- /dev/null +++ b/other-licenses/nsis/Contrib/WebBrowser/exdll.h @@ -0,0 +1,76 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0.If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef _EXDLL_H_ +#define _EXDLL_H_ + +#include +#include + +#define PLUGINFUNCTION(name) \ + extern "C" void __declspec(dllexport) \ + name(HWND hWndParent, int string_size, TCHAR* variables, \ + stack_t** stacktop, extra_parameters* extra) + +#define EXDLL_INIT() \ + { \ + g_stringsize = string_size; \ + g_stacktop = stacktop; \ + g_executeCodeSegment = extra->ExecuteCodeSegment; \ + g_hwndParent = hWndParent; \ + } + +#define WM_NOTIFY_OUTER_NEXT (WM_USER + 0x8) +#define WM_NOTIFY_CUSTOM_READY (WM_USER + 0xd) + +typedef struct _stack_t { + struct _stack_t* next; + TCHAR text[1]; // the real length of this buffer should be string_size +} stack_t; + +extern unsigned int g_stringsize; +extern stack_t** g_stacktop; +extern int(__stdcall* g_executeCodeSegment)(int pos, HWND hwndProgress); +extern HWND g_hwndParent; +extern HINSTANCE gHInst; + +typedef struct { + int autoclose; + int all_user_var; + int exec_error; + int abort; + int exec_reboot; + int reboot_called; + int XXX_cur_insttype; // deprecated + int XXX_insttype_changed; // deprecated + int silent; + int instdir_error; + int rtl; + int errlvl; +} exec_flags; + +// NSIS Plug-In Callback Messages +enum NSPIM { + NSPIM_UNLOAD, // This is the last message a plugin gets, do final cleanup + NSPIM_GUIUNLOAD, // Called after .onGUIEnd +}; + +typedef UINT_PTR (*NSISPLUGINCALLBACK)(enum NSPIM); + +typedef struct { + exec_flags* exec_flags; + int(__stdcall* ExecuteCodeSegment)(int pos, HWND hwndProgress); + void(__stdcall* validate_filename)(LPWSTR); + int(__stdcall* RegisterPluginCallback)( + HMODULE, + NSISPLUGINCALLBACK); // returns 0 on success, 1 if already + // registered and < 0 on errors +} extra_parameters; + +int popstring(TCHAR* str); +void pushstring(const TCHAR* str); + +UINT_PTR __cdecl NSISPluginCallback(NSPIM msg); + +#endif //_EXDLL_H_ diff --git a/other-licenses/nsis/Contrib/WebBrowser/main.cpp b/other-licenses/nsis/Contrib/WebBrowser/main.cpp new file mode 100644 index 0000000000..e0589531ee --- /dev/null +++ b/other-licenses/nsis/Contrib/WebBrowser/main.cpp @@ -0,0 +1,199 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0.If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include "resource.h" +#include "WebBrowser.h" +#include "exdll.h" + +// These variables are global because they're needed by more than one of +// our plugin methods. The expectation is that these are safe because the +// NSIS framework doesn't really support more than one dialog or thread +// at a time, and that means we don't have to either. + +// Instance handle for this DLL +HINSTANCE gHInst = nullptr; +// Parent window proc which we'll need to override and then restore +WNDPROC gWndProcOld = nullptr; +// Handle to the dialog we'll create +HWND gHwnd = nullptr; +// Set to true when our dialog should be destroyed +bool gDone = false; +// Web browser OLE site +WebBrowser* gBrowser = nullptr; + +// Set web browser control feature flags that are configured on a per-process +// basis, not for individual instances of the control. This mainly means +// disabling things that could turn into security holes. +static void ConfigurePerProcessBrowserFeatures() { + // For most of the features we're configuring, setting them to TRUE means + // we're disabling something, but for a few setting them to FALSE disables the + // thing. We don't necessarily care about *every* feature that's in the + // INTERNETFEATURELIST enum, but it seems safer to set them all anyway, to + // make sure we don't miss anything we *do* care about. + struct Feature { + INTERNETFEATURELIST id; + BOOL value; + } features[] = {{FEATURE_OBJECT_CACHING, TRUE}, + {FEATURE_ZONE_ELEVATION, TRUE}, + {FEATURE_MIME_HANDLING, TRUE}, + {FEATURE_MIME_SNIFFING, FALSE}, + {FEATURE_WINDOW_RESTRICTIONS, TRUE}, + {FEATURE_WEBOC_POPUPMANAGEMENT, TRUE}, + {FEATURE_BEHAVIORS, TRUE}, + {FEATURE_DISABLE_MK_PROTOCOL, TRUE}, + // It isn't possible to set FEATURE_LOCALMACHINE_LOCKDOWN + // using the SET_FEATURE_ON_PROCESS mode; see the MSDN page + // on CoInternetSetFeatureEnabled for the explanation. + //{FEATURE_LOCALMACHINE_LOCKDOWN, TRUE}, + {FEATURE_SECURITYBAND, FALSE}, + {FEATURE_RESTRICT_ACTIVEXINSTALL, TRUE}, + {FEATURE_VALIDATE_NAVIGATE_URL, TRUE}, + {FEATURE_RESTRICT_FILEDOWNLOAD, TRUE}, + {FEATURE_ADDON_MANAGEMENT, TRUE}, + {FEATURE_PROTOCOL_LOCKDOWN, TRUE}, + {FEATURE_HTTP_USERNAME_PASSWORD_DISABLE, TRUE}, + {FEATURE_SAFE_BINDTOOBJECT, TRUE}, + {FEATURE_UNC_SAVEDFILECHECK, TRUE}, + {FEATURE_GET_URL_DOM_FILEPATH_UNENCODED, FALSE}, + {FEATURE_TABBED_BROWSING, FALSE}, + {FEATURE_SSLUX, FALSE}, + {FEATURE_DISABLE_NAVIGATION_SOUNDS, TRUE}, + {FEATURE_DISABLE_LEGACY_COMPRESSION, TRUE}, + {FEATURE_FORCE_ADDR_AND_STATUS, FALSE}, + {FEATURE_XMLHTTP, FALSE}, + {FEATURE_DISABLE_TELNET_PROTOCOL, TRUE}, + {FEATURE_FEEDS, FALSE}, + {FEATURE_BLOCK_INPUT_PROMPTS, TRUE}}; + + for (Feature feature : features) { + CoInternetSetFeatureEnabled(feature.id, SET_FEATURE_ON_PROCESS, + feature.value); + } +} + +BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID) { + if (reason == DLL_PROCESS_ATTACH) { + gHInst = instance; + (void)OleInitialize(nullptr); + ConfigurePerProcessBrowserFeatures(); + } + return TRUE; +} + +UINT_PTR __cdecl NSISPluginCallback(NSPIM msg) { + if (msg == NSPIM_UNLOAD) { + OleUninitialize(); + } + return 0; +} + +BOOL CALLBACK ParentWndProc(HWND hwnd, UINT message, WPARAM wParam, + LPARAM lParam) { + BOOL bRes = + CallWindowProc((WNDPROC)gWndProcOld, hwnd, message, wParam, lParam); + if (!bRes && message == WM_NOTIFY_OUTER_NEXT) { + gDone = true; + PostMessage(gHwnd, WM_CLOSE, 0, 0); + } + return bRes; +} + +BOOL CALLBACK DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { + return FALSE; +} + +void Init(HWND hWndParent, int string_size, TCHAR* variables, + stack_t** stacktop, extra_parameters* extra) { + EXDLL_INIT(); + extra->RegisterPluginCallback(gHInst, NSISPluginCallback); + + HWND hwndChild = GetDlgItem(hWndParent, 1018); + if (!hwndChild) { + return; + } + + HWND hwnd = + CreateDialog(gHInst, MAKEINTRESOURCE(IDD_DIALOG1), hWndParent, DlgProc); + if (!hwnd) { + gDone = true; + } else { + gDone = false; + gWndProcOld = + (WNDPROC)SetWindowLong(hWndParent, DWL_DLGPROC, (LONG)ParentWndProc); + + // Tell NSIS to replace its inner dialog with ours. + SendMessage(hWndParent, WM_NOTIFY_CUSTOM_READY, (WPARAM)hwnd, 0); + + // Initialize the browser control. + if (gBrowser) { + gBrowser->Shutdown(); + gBrowser->Release(); + } + gBrowser = new WebBrowser(hwnd); + + if (!gBrowser || !gBrowser->IsInitialized()) { + return; + } + + gHwnd = hwnd; + + // Move our dialog to match the size of the parent. + RECT r; + GetClientRect(hwndChild, &r); + MoveWindow(hwnd, r.left, r.top, r.right - r.left, r.bottom - r.top, FALSE); + gBrowser->SetRect(r); + } +} + +PLUGINFUNCTION(ShowPage) { + if (!gBrowser) { + Init(hWndParent, string_size, variables, stacktop, extra); + } + + if (!gBrowser->IsInitialized()) { + return; + } + + TCHAR* sUrl = + (TCHAR*)HeapAlloc(GetProcessHeap(), 0, g_stringsize * sizeof(TCHAR)); + popstring(sUrl); + + if (gBrowser) { + gBrowser->Navigate(sUrl); + + ShowWindow(gHwnd, SW_SHOWNA); + UpdateWindow(gHwnd); + + while (!gDone) { + // This explicit wait call is needed rather than just a blocking + // GetMessage because we need this thread to be alertable so that our + // timers can wake it up and run their callbacks. + MsgWaitForMultipleObjectsEx(0, nullptr, 100, QS_ALLINPUT, + MWMO_ALERTABLE | MWMO_INPUTAVAILABLE); + MSG msg; + if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) { + bool tab = msg.message == WM_KEYDOWN && msg.wParam == VK_TAB; + + if (gBrowser->ActiveObjectTranslateAccelerator(tab, &msg) != S_OK && + !IsDialogMessage(gHwnd, &msg) && + !IsDialogMessage(g_hwndParent, &msg)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + } + + SetWindowLong(g_hwndParent, DWL_DLGPROC, (LONG)gWndProcOld); + if (gHwnd) { + DestroyWindow(gHwnd); + } + + gBrowser->Shutdown(); + gBrowser->Release(); + gBrowser = nullptr; + } + + HeapFree(GetProcessHeap(), 0, (char*)sUrl); +} diff --git a/other-licenses/nsis/Contrib/WebBrowser/resource.h b/other-licenses/nsis/Contrib/WebBrowser/resource.h new file mode 100644 index 0000000000..6fdee73b5f --- /dev/null +++ b/other-licenses/nsis/Contrib/WebBrowser/resource.h @@ -0,0 +1,5 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0.If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#define IDD_DIALOG1 101 diff --git a/other-licenses/nsis/Contrib/WebBrowser/resource.rc b/other-licenses/nsis/Contrib/WebBrowser/resource.rc new file mode 100644 index 0000000000..0bc4fcc11f --- /dev/null +++ b/other-licenses/nsis/Contrib/WebBrowser/resource.rc @@ -0,0 +1,14 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0.If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "resource.h" +#include "afxres.h" + +// The size of this dialog is a placeholder; +// it's going to get resized to fit its parent. +IDD_DIALOG1 DIALOGEX 0, 0, 1, 1 +STYLE DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS +FONT 8, "MS Shell Dlg" +BEGIN +END -- cgit v1.2.3