199 lines
6.6 KiB
C++
199 lines
6.6 KiB
C++
// 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);
|
|
}
|