summaryrefslogtreecommitdiffstats
path: root/other-licenses/nsis/Contrib/WebBrowser
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
commit6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch)
treea68f146d7fa01f0134297619fbe7e33db084e0aa /other-licenses/nsis/Contrib/WebBrowser
parentInitial commit. (diff)
downloadthunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.tar.xz
thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.zip
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'other-licenses/nsis/Contrib/WebBrowser')
-rw-r--r--other-licenses/nsis/Contrib/WebBrowser/CustomFunctions.cpp75
-rw-r--r--other-licenses/nsis/Contrib/WebBrowser/Timers.cpp59
-rw-r--r--other-licenses/nsis/Contrib/WebBrowser/WebBrowser.cpp604
-rw-r--r--other-licenses/nsis/Contrib/WebBrowser/WebBrowser.h250
-rw-r--r--other-licenses/nsis/Contrib/WebBrowser/WebBrowser.sln25
-rw-r--r--other-licenses/nsis/Contrib/WebBrowser/WebBrowser.vcxproj160
-rw-r--r--other-licenses/nsis/Contrib/WebBrowser/exdll.cpp30
-rw-r--r--other-licenses/nsis/Contrib/WebBrowser/exdll.h76
-rw-r--r--other-licenses/nsis/Contrib/WebBrowser/main.cpp199
-rw-r--r--other-licenses/nsis/Contrib/WebBrowser/resource.h5
-rw-r--r--other-licenses/nsis/Contrib/WebBrowser/resource.rc14
11 files changed, 1497 insertions, 0 deletions
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<uintptr_t>(_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 <windows.h>
+#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<uintptr_t>(_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<HANDLE>(_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 <mshtmdid.h>
+
+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<IOleClientSite*>(this);
+ } else if (riid == __uuidof(IOleClientSite)) {
+ *ppvObject = static_cast<IOleClientSite*>(this);
+ } else if (riid == __uuidof(IOleInPlaceSite)) {
+ *ppvObject = static_cast<IOleInPlaceSite*>(this);
+ } else if (riid == __uuidof(IDropTarget)) {
+ *ppvObject = static_cast<IDropTarget*>(this);
+ } else if (riid == __uuidof(IStorage)) {
+ *ppvObject = static_cast<IStorage*>(this);
+ } else if (riid == __uuidof(IDocHostUIHandler)) {
+ *ppvObject = static_cast<IDocHostUIHandler*>(this);
+ } else if (riid == __uuidof(IDocHostShowUI)) {
+ *ppvObject = static_cast<IDocHostShowUI*>(this);
+ } else if (riid == __uuidof(IDispatch)) {
+ *ppvObject = static_cast<IDispatch*>(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 <exdisp.h>
+#include <mshtmhst.h>
+
+#include <vector>
+#include <string>
+
+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<CustomFunctionRecord> 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 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <SccProjectName />
+ <SccLocalPath />
+ <ProjectGuid>{EF903B79-AD97-45E0-BC6E-4FF846D6A2ED}</ProjectGuid>
+ <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>Unicode</CharacterSet>
+ <SpectreMitigation>false</SpectreMitigation>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>Unicode</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <SpectreMitigation>false</SpectreMitigation>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <OutDir>.\Release\</OutDir>
+ <IntDir>.\Release\</IntDir>
+ <LinkIncremental>false</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <OutDir>.\Debug\</OutDir>
+ <IntDir>.\Debug\</IntDir>
+ <LinkIncremental>true</LinkIncremental>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <StringPooling>true</StringPooling>
+ <Optimization>MinSpace</Optimization>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <WarningLevel>Level3</WarningLevel>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <DebugInformationFormat>None</DebugInformationFormat>
+ <ExceptionHandling>false</ExceptionHandling>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ </ClCompile>
+ <Midl>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <TypeLibraryName>.\Release\WebBrowser.tlb</TypeLibraryName>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ </Midl>
+ <ResourceCompile>
+ <Culture>0x080a</Culture>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Bscmake>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <OutputFile>.\Release\WebBrowser.bsc</OutputFile>
+ </Bscmake>
+ <Link>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <LinkDLL>true</LinkDLL>
+ <SubSystem>Windows</SubSystem>
+ <OutputFile>.\Release\WebBrowser.dll</OutputFile>
+ <ImportLibrary>.\Release\WebBrowser.lib</ImportLibrary>
+ <AdditionalDependencies>odbc32.lib;odbccp32.lib;urlmon.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <OptimizeReferences>true</OptimizeReferences>
+ <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <EntryPointSymbol>
+ </EntryPointSymbol>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <InlineFunctionExpansion>Default</InlineFunctionExpansion>
+ <Optimization>Disabled</Optimization>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <ExceptionHandling>false</ExceptionHandling>
+ <LanguageStandard>Default</LanguageStandard>
+ </ClCompile>
+ <Midl>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <TypeLibraryName>.\Debug\WebBrowser.tlb</TypeLibraryName>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ </Midl>
+ <ResourceCompile>
+ <Culture>0x080a</Culture>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Bscmake>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <OutputFile>.\Debug\WebBrowser.bsc</OutputFile>
+ </Bscmake>
+ <Link>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <LinkDLL>true</LinkDLL>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OutputFile>.\Debug\WebBrowser.dll</OutputFile>
+ <ImportLibrary>.\Debug\WebBrowser.lib</ImportLibrary>
+ <AdditionalDependencies>odbc32.lib;odbccp32.lib;urlmon.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OptimizeReferences>false</OptimizeReferences>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="CustomFunctions.cpp" />
+ <ClCompile Include="exdll.cpp" />
+ <ClCompile Include="main.cpp" />
+ <ClCompile Include="Timers.cpp" />
+ <ClCompile Include="WebBrowser.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="exdll.h" />
+ <ClInclude Include="resource.h" />
+ <ClInclude Include="WebBrowser.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="resource.rc" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ 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 <windows.h>
+#include <tchar.h>
+
+#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 <windows.h>
+#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