2008-03-20 09:01:26 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode:nil; c-basic-offset: 2 -*- */
|
2012-05-21 15:12:37 +04:00
|
|
|
/* 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/. */
|
2008-03-20 09:01:26 +03:00
|
|
|
|
2014-05-05 22:24:25 +04:00
|
|
|
#include "nsParentalControlsService.h"
|
2008-03-20 09:01:26 +03:00
|
|
|
#include "nsString.h"
|
|
|
|
#include "nsIArray.h"
|
|
|
|
#include "nsIWidget.h"
|
|
|
|
#include "nsIInterfaceRequestor.h"
|
|
|
|
#include "nsIInterfaceRequestorUtils.h"
|
|
|
|
#include "nsIFile.h"
|
|
|
|
#include "nsILocalFileWin.h"
|
|
|
|
#include "nsArrayUtils.h"
|
|
|
|
#include "nsIXULAppInfo.h"
|
2015-12-17 20:37:47 +03:00
|
|
|
#include "mozilla/UniquePtr.h"
|
2014-11-12 02:17:37 +03:00
|
|
|
#include "mozilla/WindowsVersion.h"
|
|
|
|
|
|
|
|
using namespace mozilla;
|
2008-03-20 09:01:26 +03:00
|
|
|
|
2014-05-05 22:24:25 +04:00
|
|
|
NS_IMPL_ISUPPORTS(nsParentalControlsService, nsIParentalControlsService)
|
2008-03-20 09:01:26 +03:00
|
|
|
|
2014-05-05 22:24:25 +04:00
|
|
|
nsParentalControlsService::nsParentalControlsService()
|
2012-10-04 12:30:42 +04:00
|
|
|
: mEnabled(false), mProvider(0), mPC(nullptr) {
|
2008-03-20 09:01:26 +03:00
|
|
|
HRESULT hr;
|
2013-10-11 00:38:05 +04:00
|
|
|
CoInitialize(nullptr);
|
2018-05-14 04:58:53 +03:00
|
|
|
hr = CoCreateInstance(__uuidof(WindowsParentalControls), nullptr,
|
|
|
|
CLSCTX_INPROC, IID_PPV_ARGS(&mPC));
|
2008-03-20 09:01:26 +03:00
|
|
|
if (FAILED(hr)) return;
|
|
|
|
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<IWPCSettings> wpcs;
|
2013-10-11 00:38:05 +04:00
|
|
|
if (FAILED(mPC->GetUserSettings(nullptr, getter_AddRefs(wpcs)))) {
|
2008-03-20 09:01:26 +03:00
|
|
|
// Not available on this os or not enabled for this user account or we're
|
|
|
|
// running as admin
|
|
|
|
mPC->Release();
|
2012-07-30 18:20:58 +04:00
|
|
|
mPC = nullptr;
|
2008-03-20 09:01:26 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
DWORD settings = 0;
|
|
|
|
wpcs->GetRestrictions(&settings);
|
2014-11-12 02:17:37 +03:00
|
|
|
|
|
|
|
// If we can't determine specifically whether Web Filtering is on/off (i.e.
|
|
|
|
// we're on Windows < 8), then assume it's on unless no restrictions are set.
|
|
|
|
bool enable = IsWin8OrLater() ? settings & WPCFLAG_WEB_FILTERED
|
|
|
|
: settings != WPCFLAG_NO_RESTRICTION;
|
|
|
|
|
|
|
|
if (enable) {
|
2011-10-17 18:59:28 +04:00
|
|
|
mEnabled = true;
|
2008-03-29 10:12:13 +03:00
|
|
|
}
|
2008-03-20 09:01:26 +03:00
|
|
|
}
|
|
|
|
|
2014-05-05 22:24:25 +04:00
|
|
|
nsParentalControlsService::~nsParentalControlsService() {
|
2008-03-20 09:01:26 +03:00
|
|
|
if (mPC) mPC->Release();
|
2008-03-29 10:12:13 +03:00
|
|
|
|
2018-05-14 04:58:53 +03:00
|
|
|
if (mProvider) {
|
|
|
|
EventUnregister(mProvider);
|
|
|
|
}
|
2008-03-20 09:01:26 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2014-05-05 22:24:25 +04:00
|
|
|
nsParentalControlsService::GetParentalControlsEnabled(bool *aResult) {
|
2011-10-17 18:59:28 +04:00
|
|
|
*aResult = false;
|
2008-03-20 09:01:26 +03:00
|
|
|
|
2011-10-17 18:59:28 +04:00
|
|
|
if (mEnabled) *aResult = true;
|
2008-03-20 09:01:26 +03:00
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2014-05-05 22:24:25 +04:00
|
|
|
nsParentalControlsService::GetBlockFileDownloadsEnabled(bool *aResult) {
|
2011-10-17 18:59:28 +04:00
|
|
|
*aResult = false;
|
2008-03-20 09:01:26 +03:00
|
|
|
|
|
|
|
if (!mEnabled) return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<IWPCWebSettings> wpcws;
|
2013-10-11 00:38:05 +04:00
|
|
|
if (SUCCEEDED(mPC->GetWebSettings(nullptr, getter_AddRefs(wpcws)))) {
|
2008-03-20 09:01:26 +03:00
|
|
|
DWORD settings = 0;
|
|
|
|
wpcws->GetSettings(&settings);
|
|
|
|
if (settings == WPCFLAG_WEB_SETTING_DOWNLOADSBLOCKED) *aResult = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2014-05-05 22:24:25 +04:00
|
|
|
nsParentalControlsService::GetLoggingEnabled(bool *aResult) {
|
2011-10-17 18:59:28 +04:00
|
|
|
*aResult = false;
|
2008-03-20 09:01:26 +03:00
|
|
|
|
|
|
|
if (!mEnabled) return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
|
|
|
|
// Check the general purpose logging flag
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<IWPCSettings> wpcs;
|
2013-10-11 00:38:05 +04:00
|
|
|
if (SUCCEEDED(mPC->GetUserSettings(nullptr, getter_AddRefs(wpcs)))) {
|
2008-03-20 09:01:26 +03:00
|
|
|
BOOL enabled = FALSE;
|
|
|
|
wpcs->IsLoggingRequired(&enabled);
|
2011-10-17 18:59:28 +04:00
|
|
|
if (enabled) *aResult = true;
|
2008-03-20 09:01:26 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Post a log event to the system
|
|
|
|
NS_IMETHODIMP
|
2014-05-05 22:24:25 +04:00
|
|
|
nsParentalControlsService::Log(int16_t aEntryType, bool blocked,
|
|
|
|
nsIURI *aSource, nsIFile *aTarget) {
|
2008-03-20 09:01:26 +03:00
|
|
|
if (!mEnabled) return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
|
|
|
|
NS_ENSURE_ARG_POINTER(aSource);
|
|
|
|
|
|
|
|
// Confirm we should be logging
|
2011-09-29 10:19:26 +04:00
|
|
|
bool enabled;
|
2008-03-20 09:01:26 +03:00
|
|
|
GetLoggingEnabled(&enabled);
|
|
|
|
if (!enabled) return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
|
2008-03-29 10:12:13 +03:00
|
|
|
// Register a Vista log event provider associated with the parental controls
|
|
|
|
// channel.
|
2008-03-20 09:01:26 +03:00
|
|
|
if (!mProvider) {
|
2018-05-14 04:58:53 +03:00
|
|
|
if (EventRegister(&WPCPROV, nullptr, nullptr, &mProvider) != ERROR_SUCCESS)
|
2008-03-20 09:01:26 +03:00
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (aEntryType) {
|
|
|
|
case ePCLog_URIVisit:
|
|
|
|
// Not needed, Vista's web content filter handles this for us
|
|
|
|
break;
|
|
|
|
case ePCLog_FileDownload:
|
|
|
|
LogFileDownload(blocked, aSource, aTarget);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Override a single URI
|
|
|
|
NS_IMETHODIMP
|
2014-05-05 22:24:25 +04:00
|
|
|
nsParentalControlsService::RequestURIOverride(
|
|
|
|
nsIURI *aTarget, nsIInterfaceRequestor *aWindowContext, bool *_retval) {
|
2011-10-17 18:59:28 +04:00
|
|
|
*_retval = false;
|
2008-03-20 09:01:26 +03:00
|
|
|
|
|
|
|
if (!mEnabled) return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
|
|
|
|
NS_ENSURE_ARG_POINTER(aTarget);
|
|
|
|
|
2012-09-02 06:35:17 +04:00
|
|
|
nsAutoCString spec;
|
2008-03-20 09:01:26 +03:00
|
|
|
aTarget->GetSpec(spec);
|
|
|
|
if (spec.IsEmpty()) return NS_ERROR_INVALID_ARG;
|
|
|
|
|
2012-07-30 18:20:58 +04:00
|
|
|
HWND hWnd = nullptr;
|
2008-10-02 10:49:45 +04:00
|
|
|
// If we have a native window, use its handle instead
|
2008-03-20 09:01:26 +03:00
|
|
|
nsCOMPtr<nsIWidget> widget(do_GetInterface(aWindowContext));
|
|
|
|
if (widget) hWnd = (HWND)widget->GetNativeData(NS_NATIVE_WINDOW);
|
|
|
|
if (hWnd == nullptr) hWnd = GetDesktopWindow();
|
|
|
|
|
2011-08-30 22:55:14 +04:00
|
|
|
BOOL ret;
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<IWPCWebSettings> wpcws;
|
2013-10-11 00:38:05 +04:00
|
|
|
if (SUCCEEDED(mPC->GetWebSettings(nullptr, getter_AddRefs(wpcws)))) {
|
2008-03-20 09:01:26 +03:00
|
|
|
wpcws->RequestURLOverride(hWnd, NS_ConvertUTF8toUTF16(spec).get(), 0,
|
2013-10-11 00:38:05 +04:00
|
|
|
nullptr, &ret);
|
2011-08-30 22:55:14 +04:00
|
|
|
*_retval = ret;
|
|
|
|
}
|
|
|
|
|
2008-03-20 09:01:26 +03:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Override a web page
|
|
|
|
NS_IMETHODIMP
|
2014-05-05 22:24:25 +04:00
|
|
|
nsParentalControlsService::RequestURIOverrides(
|
|
|
|
nsIArray *aTargets, nsIInterfaceRequestor *aWindowContext, bool *_retval) {
|
2011-10-17 18:59:28 +04:00
|
|
|
*_retval = false;
|
2008-03-20 09:01:26 +03:00
|
|
|
|
|
|
|
if (!mEnabled) return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
|
|
|
|
NS_ENSURE_ARG_POINTER(aTargets);
|
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
uint32_t arrayLength = 0;
|
2008-03-20 09:01:26 +03:00
|
|
|
aTargets->GetLength(&arrayLength);
|
|
|
|
if (!arrayLength) return NS_ERROR_INVALID_ARG;
|
|
|
|
|
|
|
|
if (arrayLength == 1) {
|
|
|
|
nsCOMPtr<nsIURI> uri = do_QueryElementAt(aTargets, 0);
|
|
|
|
if (!uri) return NS_ERROR_INVALID_ARG;
|
|
|
|
return RequestURIOverride(uri, aWindowContext, _retval);
|
|
|
|
}
|
|
|
|
|
2012-07-30 18:20:58 +04:00
|
|
|
HWND hWnd = nullptr;
|
2008-10-02 10:49:45 +04:00
|
|
|
// If we have a native window, use its handle instead
|
2008-03-20 09:01:26 +03:00
|
|
|
nsCOMPtr<nsIWidget> widget(do_GetInterface(aWindowContext));
|
|
|
|
if (widget) hWnd = (HWND)widget->GetNativeData(NS_NATIVE_WINDOW);
|
|
|
|
if (hWnd == nullptr) hWnd = GetDesktopWindow();
|
|
|
|
|
|
|
|
// The first entry should be the root uri
|
2012-09-02 06:35:17 +04:00
|
|
|
nsAutoCString rootSpec;
|
2008-03-20 09:01:26 +03:00
|
|
|
nsCOMPtr<nsIURI> rootURI = do_QueryElementAt(aTargets, 0);
|
|
|
|
if (!rootURI) return NS_ERROR_INVALID_ARG;
|
2017-07-06 15:00:35 +03:00
|
|
|
|
2008-03-20 09:01:26 +03:00
|
|
|
rootURI->GetSpec(rootSpec);
|
|
|
|
if (rootSpec.IsEmpty()) return NS_ERROR_INVALID_ARG;
|
|
|
|
|
|
|
|
// Allocate an array of sub uri
|
2012-08-22 19:56:38 +04:00
|
|
|
int32_t count = arrayLength - 1;
|
2015-12-17 20:37:47 +03:00
|
|
|
auto arrUrls = MakeUnique<LPCWSTR[]>(count);
|
2008-03-20 09:01:26 +03:00
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
uint32_t uriIdx = 0, idx;
|
2008-03-20 09:01:26 +03:00
|
|
|
for (idx = 1; idx < arrayLength; idx++) {
|
|
|
|
nsCOMPtr<nsIURI> uri = do_QueryElementAt(aTargets, idx);
|
|
|
|
if (!uri) continue;
|
|
|
|
|
2012-09-02 06:35:17 +04:00
|
|
|
nsAutoCString subURI;
|
2008-03-20 09:01:26 +03:00
|
|
|
if (NS_FAILED(uri->GetSpec(subURI))) continue;
|
|
|
|
|
|
|
|
arrUrls[uriIdx] = (LPCWSTR)UTF8ToNewUnicode(subURI); // allocation
|
|
|
|
if (!arrUrls[uriIdx]) continue;
|
|
|
|
|
|
|
|
uriIdx++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!uriIdx) return NS_ERROR_INVALID_ARG;
|
2011-08-30 22:55:14 +04:00
|
|
|
|
2017-07-06 15:00:35 +03:00
|
|
|
BOOL ret;
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<IWPCWebSettings> wpcws;
|
2013-10-11 00:38:05 +04:00
|
|
|
if (SUCCEEDED(mPC->GetWebSettings(nullptr, getter_AddRefs(wpcws)))) {
|
2008-03-20 09:01:26 +03:00
|
|
|
wpcws->RequestURLOverride(hWnd, NS_ConvertUTF8toUTF16(rootSpec).get(),
|
2011-08-30 22:55:14 +04:00
|
|
|
uriIdx, (LPCWSTR *)arrUrls.get(), &ret);
|
|
|
|
*_retval = ret;
|
|
|
|
}
|
2008-03-20 09:01:26 +03:00
|
|
|
|
|
|
|
// Free up the allocated strings in our array
|
|
|
|
for (idx = 0; idx < uriIdx; idx++) free((void *)arrUrls[idx]);
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
|
2017-07-06 15:00:35 +03:00
|
|
|
// Sends a file download event to the Vista Event Log
|
2014-05-05 22:24:25 +04:00
|
|
|
void nsParentalControlsService::LogFileDownload(bool blocked, nsIURI *aSource,
|
|
|
|
nsIFile *aTarget) {
|
2012-09-02 06:35:17 +04:00
|
|
|
nsAutoCString curi;
|
2008-03-29 10:12:13 +03:00
|
|
|
|
|
|
|
// Note, EventDataDescCreate is a macro defined in the headers, not a function
|
|
|
|
|
2008-03-20 09:01:26 +03:00
|
|
|
aSource->GetSpec(curi);
|
|
|
|
nsAutoString uri = NS_ConvertUTF8toUTF16(curi);
|
|
|
|
|
|
|
|
// Get the name of the currently running process
|
|
|
|
nsCOMPtr<nsIXULAppInfo> appInfo =
|
|
|
|
do_GetService("@mozilla.org/xre/app-info;1");
|
2012-09-02 06:35:17 +04:00
|
|
|
nsAutoCString asciiAppName;
|
2008-03-20 09:01:26 +03:00
|
|
|
if (appInfo) appInfo->GetName(asciiAppName);
|
|
|
|
nsAutoString appName = NS_ConvertUTF8toUTF16(asciiAppName);
|
|
|
|
|
|
|
|
static const WCHAR fill[] = L"";
|
2017-07-06 15:00:35 +03:00
|
|
|
|
2008-03-20 09:01:26 +03:00
|
|
|
// See wpcevent.h and msdn for event formats
|
|
|
|
EVENT_DATA_DESCRIPTOR eventData[WPC_ARGS_FILEDOWNLOADEVENT_CARGS];
|
|
|
|
DWORD dwBlocked = blocked;
|
|
|
|
|
|
|
|
EventDataDescCreate(&eventData[WPC_ARGS_FILEDOWNLOADEVENT_URL],
|
|
|
|
(const void *)uri.get(),
|
|
|
|
((ULONG)uri.Length() + 1) * sizeof(WCHAR));
|
|
|
|
EventDataDescCreate(&eventData[WPC_ARGS_FILEDOWNLOADEVENT_APPNAME],
|
|
|
|
(const void *)appName.get(),
|
|
|
|
((ULONG)appName.Length() + 1) * sizeof(WCHAR));
|
|
|
|
EventDataDescCreate(&eventData[WPC_ARGS_FILEDOWNLOADEVENT_VERSION],
|
|
|
|
(const void *)fill, sizeof(fill));
|
|
|
|
EventDataDescCreate(&eventData[WPC_ARGS_FILEDOWNLOADEVENT_BLOCKED],
|
|
|
|
(const void *)&dwBlocked, sizeof(dwBlocked));
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2008-03-20 09:01:26 +03:00
|
|
|
nsCOMPtr<nsILocalFileWin> local(do_QueryInterface(aTarget)); // May be null
|
|
|
|
if (local) {
|
|
|
|
nsAutoString path;
|
|
|
|
local->GetCanonicalPath(path);
|
|
|
|
EventDataDescCreate(&eventData[WPC_ARGS_FILEDOWNLOADEVENT_PATH],
|
|
|
|
(const void *)path.get(),
|
|
|
|
((ULONG)path.Length() + 1) * sizeof(WCHAR));
|
|
|
|
} else {
|
|
|
|
EventDataDescCreate(&eventData[WPC_ARGS_FILEDOWNLOADEVENT_PATH],
|
|
|
|
(const void *)fill, sizeof(fill));
|
|
|
|
}
|
|
|
|
|
2018-05-14 04:58:53 +03:00
|
|
|
EventWrite(mProvider, &WPCEVENT_WEB_FILEDOWNLOAD, ARRAYSIZE(eventData),
|
|
|
|
eventData);
|
2008-03-20 09:01:26 +03:00
|
|
|
}
|
|
|
|
|
2014-09-10 02:08:37 +04:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsParentalControlsService::IsAllowed(int16_t aAction, nsIURI *aUri,
|
|
|
|
bool *_retval) {
|
|
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
}
|