SEBWIN-314: Started implementing scaffolding for request filter.

This commit is contained in:
dbuechel 2019-09-06 08:13:27 +02:00
parent db390aebaf
commit b8fd96a10c
42 changed files with 219 additions and 495 deletions

View file

@ -6,7 +6,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
namespace SafeExamBrowser.Browser.Contracts
namespace SafeExamBrowser.Browser.Contracts.Events
{
/// <summary>
/// The event arguments used for all download events.

View file

@ -6,7 +6,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
namespace SafeExamBrowser.Browser.Contracts
namespace SafeExamBrowser.Browser.Contracts.Events
{
/// <summary>
/// Defines the method signature for callbacks to be executed once a download has been finished. Indicates whether the download was

View file

@ -6,7 +6,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
namespace SafeExamBrowser.Browser.Contracts
namespace SafeExamBrowser.Browser.Contracts.Events
{
/// <summary>
/// Event handler used to control (e.g. allow or prohibit) download requests.

View file

@ -6,7 +6,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
namespace SafeExamBrowser.Browser.Contracts
namespace SafeExamBrowser.Browser.Contracts.Events
{
/// <summary>
/// Event handler used to indicate the current progress value of the page load process (from <c>0.0</c> to <c>1.0</c>).

View file

@ -7,6 +7,7 @@
*/
using SafeExamBrowser.Applications.Contracts;
using SafeExamBrowser.Browser.Contracts.Events;
namespace SafeExamBrowser.Browser.Contracts
{

View file

@ -53,11 +53,11 @@
<Reference Include="Microsoft.CSharp" />
</ItemGroup>
<ItemGroup>
<Compile Include="DownloadEventArgs.cs" />
<Compile Include="DownloadFinishedCallback.cs" />
<Compile Include="DownloadRequestedEventHandler.cs" />
<Compile Include="Events\DownloadEventArgs.cs" />
<Compile Include="Events\DownloadFinishedCallback.cs" />
<Compile Include="Events\DownloadRequestedEventHandler.cs" />
<Compile Include="IBrowserApplication.cs" />
<Compile Include="ProgressChangedEventHandler.cs" />
<Compile Include="Events\ProgressChangedEventHandler.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>

View file

@ -14,14 +14,14 @@ using CefSharp.WinForms;
using SafeExamBrowser.Applications.Contracts;
using SafeExamBrowser.Applications.Contracts.Events;
using SafeExamBrowser.Browser.Contracts;
using SafeExamBrowser.Browser.Contracts.Events;
using SafeExamBrowser.Browser.Events;
using SafeExamBrowser.Configuration.Contracts;
using SafeExamBrowser.Core.Contracts;
using SafeExamBrowser.I18n.Contracts;
using SafeExamBrowser.Logging.Contracts;
using SafeExamBrowser.UserInterface.Contracts;
using SafeExamBrowser.UserInterface.Contracts.MessageBox;
using BrowserSettings = SafeExamBrowser.Configuration.Contracts.Settings.BrowserSettings;
using BrowserSettings = SafeExamBrowser.Configuration.Contracts.Settings.Browser.BrowserSettings;
namespace SafeExamBrowser.Browser
{

View file

@ -10,12 +10,11 @@ using System;
using System.Net.Http;
using SafeExamBrowser.Applications.Contracts;
using SafeExamBrowser.Applications.Contracts.Events;
using SafeExamBrowser.Browser.Contracts;
using SafeExamBrowser.Browser.Contracts.Events;
using SafeExamBrowser.Browser.Events;
using SafeExamBrowser.Browser.Handlers;
using SafeExamBrowser.Configuration.Contracts;
using SafeExamBrowser.Configuration.Contracts.Settings;
using SafeExamBrowser.Core.Contracts;
using SafeExamBrowser.Configuration.Contracts.Settings.Browser;
using SafeExamBrowser.I18n.Contracts;
using SafeExamBrowser.Logging.Contracts;
using SafeExamBrowser.UserInterface.Contracts;
@ -84,6 +83,17 @@ namespace SafeExamBrowser.Browser
}
internal void Initialize()
{
InitializeControl();
InitializeWindow();
}
internal void Terminate()
{
window?.Close();
}
private void InitializeControl()
{
var contextMenuHandler = new ContextMenuHandler();
var displayHandler = new DisplayHandler();
@ -91,7 +101,8 @@ namespace SafeExamBrowser.Browser
var downloadHandler = new DownloadHandler(appConfig, settings, downloadLogger);
var keyboardHandler = new KeyboardHandler();
var lifeSpanHandler = new LifeSpanHandler();
var requestHandler = new RequestHandler(appConfig);
var requestLogger = logger.CloneFor($"{nameof(RequestHandler)} {Id}");
var requestHandler = new RequestHandler(appConfig, settings, logger);
displayHandler.FaviconChanged += DisplayHandler_FaviconChanged;
displayHandler.ProgressChanged += DisplayHandler_ProgressChanged;
@ -109,7 +120,10 @@ namespace SafeExamBrowser.Browser
control.Initialize();
logger.Debug("Initialized browser control.");
}
private void InitializeWindow()
{
window = uiFactory.CreateBrowserWindow(control, settings, isMainInstance);
window.Closing += () => Terminated?.Invoke(Id);
window.AddressChanged += Window_AddressChanged;
@ -126,11 +140,6 @@ namespace SafeExamBrowser.Browser
logger.Debug("Initialized browser window.");
}
internal void Terminate()
{
window?.Close();
}
private void Control_AddressChanged(string address)
{
logger.Debug($"Navigated to '{address}'.");

View file

@ -7,17 +7,20 @@
*/
using System;
using SafeExamBrowser.Configuration.Contracts.Settings.Browser;
namespace SafeExamBrowser.Network.Contracts
namespace SafeExamBrowser.Browser.Filters
{
/// <summary>
/// Defines a network request.
/// </summary>
public class Request
internal class RequestFilter
{
/// <summary>
/// The uri of the request.
/// </summary>
public Uri Uri { get; set; }
internal void Load(FilterRule rule)
{
}
internal FilterResult Process(Uri request)
{
return FilterResult.Allow;
}
}
}

View file

@ -10,8 +10,8 @@ using System.Collections.Generic;
using System.Linq;
using CefSharp;
using CefSharp.Structs;
using SafeExamBrowser.Browser.Contracts.Events;
using SafeExamBrowser.Browser.Events;
using SafeExamBrowser.Browser.Contracts;
namespace SafeExamBrowser.Browser.Handlers
{

View file

@ -11,10 +11,10 @@ using System.Collections.Concurrent;
using System.IO;
using System.Threading.Tasks;
using CefSharp;
using SafeExamBrowser.Browser.Contracts;
using SafeExamBrowser.Browser.Contracts.Events;
using SafeExamBrowser.Configuration.Contracts;
using SafeExamBrowser.Logging.Contracts;
using BrowserSettings = SafeExamBrowser.Configuration.Contracts.Settings.BrowserSettings;
using BrowserSettings = SafeExamBrowser.Configuration.Contracts.Settings.Browser.BrowserSettings;
namespace SafeExamBrowser.Browser.Handlers
{

View file

@ -7,19 +7,41 @@
*/
using CefSharp;
using SafeExamBrowser.Browser.Filters;
using SafeExamBrowser.Configuration.Contracts;
using SafeExamBrowser.Logging.Contracts;
using BrowserSettings = SafeExamBrowser.Configuration.Contracts.Settings.Browser.BrowserSettings;
namespace SafeExamBrowser.Browser.Handlers
{
internal class RequestHandler : CefSharp.Handler.RequestHandler
{
private AppConfig appConfig;
private BrowserSettings settings;
private RequestFilter filter;
private ILogger logger;
private ResourceRequestHandler resourceRequestHandler;
internal RequestHandler(AppConfig appConfig)
internal RequestHandler(AppConfig appConfig, BrowserSettings settings, ILogger logger)
{
this.appConfig = appConfig;
this.resourceRequestHandler = new ResourceRequestHandler(appConfig);
this.settings = settings;
this.filter = new RequestFilter();
this.logger = logger;
this.resourceRequestHandler = new ResourceRequestHandler(appConfig, settings, logger);
}
internal void Initiailize()
{
if (settings.FilterMainRequests || settings.FilterContentRequests)
{
foreach (var rule in settings.FilterRules)
{
filter.Load(rule);
}
logger.Debug("Initialized request filter.");
}
}
protected override IResourceRequestHandler GetResourceRequestHandler(IWebBrowser webBrowser, IBrowser browser, IFrame frame, IRequest request, bool isNavigation, bool isDownload, string requestInitiator, ref bool disableDefaultHandling)

View file

@ -10,19 +10,35 @@ using System;
using System.Collections.Specialized;
using CefSharp;
using SafeExamBrowser.Configuration.Contracts;
using SafeExamBrowser.Logging.Contracts;
using BrowserSettings = SafeExamBrowser.Configuration.Contracts.Settings.Browser.BrowserSettings;
namespace SafeExamBrowser.Browser.Handlers
{
internal class ResourceRequestHandler : CefSharp.Handler.ResourceRequestHandler
{
private AppConfig appConfig;
private BrowserSettings settings;
private ILogger logger;
internal ResourceRequestHandler(AppConfig appConfig)
internal ResourceRequestHandler(AppConfig appConfig, BrowserSettings settings, ILogger logger)
{
this.appConfig = appConfig;
this.settings = settings;
this.logger = logger;
}
protected override CefReturnValue OnBeforeResourceLoad(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IRequestCallback callback)
protected override IResourceHandler GetResourceHandler(IWebBrowser webBrowser, IBrowser browser, IFrame frame, IRequest request)
{
if (FilterMainRequest(request) || FilterContentRequest(request))
{
return ResourceHandler.FromString("<html><body>Blocked!</body></html>");
}
return base.GetResourceHandler(webBrowser, browser, frame, request);
}
protected override CefReturnValue OnBeforeResourceLoad(IWebBrowser webBrowser, IBrowser browser, IFrame frame, IRequest request, IRequestCallback callback)
{
// TODO: CEF does not yet support intercepting requests from service workers, thus the user agent must be statically set at browser
// startup for now. Once CEF has full support of service workers, the static user agent should be removed and the method below
@ -36,7 +52,7 @@ namespace SafeExamBrowser.Browser.Handlers
ReplaceCustomScheme(request);
return base.OnBeforeResourceLoad(browserControl, browser, frame, request, callback);
return base.OnBeforeResourceLoad(webBrowser, browser, frame, request, callback);
}
private void AppendCustomUserAgent(IRequest request)
@ -48,6 +64,16 @@ namespace SafeExamBrowser.Browser.Handlers
request.Headers = headers;
}
private bool FilterContentRequest(IRequest request)
{
return settings.FilterContentRequests && request.ResourceType != ResourceType.MainFrame;
}
private bool FilterMainRequest(IRequest request)
{
return settings.FilterMainRequests && request.ResourceType == ResourceType.MainFrame;
}
private bool IsMailtoUrl(string url)
{
return url.StartsWith(Uri.UriSchemeMailto);

View file

@ -71,6 +71,7 @@
<Compile Include="Events\FaviconChangedEventHandler.cs" />
<Compile Include="Events\PopupRequestedEventArgs.cs" />
<Compile Include="Events\PopupRequestedEventHandler.cs" />
<Compile Include="Filters\RequestFilter.cs" />
<Compile Include="Handlers\ContextMenuHandler.cs" />
<Compile Include="BrowserControl.cs">
<SubType>Component</SubType>

View file

@ -10,6 +10,7 @@ using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using SafeExamBrowser.Browser.Contracts;
using SafeExamBrowser.Browser.Contracts.Events;
using SafeExamBrowser.Communication.Contracts.Data;
using SafeExamBrowser.Communication.Contracts.Events;
using SafeExamBrowser.Communication.Contracts.Hosts;
@ -21,7 +22,6 @@ using SafeExamBrowser.Core.Contracts.OperationModel;
using SafeExamBrowser.Core.Contracts.OperationModel.Events;
using SafeExamBrowser.I18n.Contracts;
using SafeExamBrowser.Logging.Contracts;
using SafeExamBrowser.Monitoring.Contracts;
using SafeExamBrowser.Monitoring.Contracts.Display;
using SafeExamBrowser.Monitoring.Contracts.Processes;
using SafeExamBrowser.Monitoring.Contracts.Windows;

View file

@ -9,6 +9,7 @@
using System;
using System.IO;
using SafeExamBrowser.Browser.Contracts;
using SafeExamBrowser.Browser.Contracts.Events;
using SafeExamBrowser.Client.Contracts;
using SafeExamBrowser.Communication.Contracts.Data;
using SafeExamBrowser.Communication.Contracts.Events;

View file

@ -203,7 +203,7 @@ namespace SafeExamBrowser.Client
private IOperation BuildBrowserOperation()
{
var moduleLogger = new ModuleLogger(logger, "BrowserController");
var moduleLogger = new ModuleLogger(logger, nameof(BrowserApplication));
var browser = new BrowserApplication(configuration.AppConfig, configuration.Settings.Browser, messageBox, moduleLogger, text, uiFactory);
var browserInfo = new BrowserApplicationInfo();
var operation = new BrowserOperation(actionCenter, browser, logger, taskbar, uiFactory);

View file

@ -78,13 +78,15 @@
<Compile Include="SessionConfiguration.cs" />
<Compile Include="Settings\ActionCenterSettings.cs" />
<Compile Include="Settings\AudioSettings.cs" />
<Compile Include="Settings\BrowserSettings.cs" />
<Compile Include="Settings\BrowserWindowSettings.cs" />
<Compile Include="Settings\Browser\BrowserSettings.cs" />
<Compile Include="Settings\Browser\BrowserWindowSettings.cs" />
<Compile Include="Settings\Browser\FilterResult.cs" />
<Compile Include="Settings\Browser\FilterRule.cs" />
<Compile Include="Settings\Browser\FilterType.cs" />
<Compile Include="Settings\ConfigurationMode.cs" />
<Compile Include="Settings\KeyboardSettings.cs" />
<Compile Include="Settings\KioskMode.cs" />
<Compile Include="Settings\MouseSettings.cs" />
<Compile Include="Settings\NetworkSettings.cs" />
<Compile Include="Settings\ServicePolicy.cs" />
<Compile Include="Settings\ServiceSettings.cs" />
<Compile Include="Settings\Settings.cs" />
@ -96,10 +98,6 @@
<Project>{64ea30fb-11d4-436a-9c2b-88566285363e}</Project>
<Name>SafeExamBrowser.Logging.Contracts</Name>
</ProjectReference>
<ProjectReference Include="..\SafeExamBrowser.Network.Contracts\SafeExamBrowser.Network.Contracts.csproj">
<Project>{2947da3c-61f3-44be-81cf-d1d5c10aec95}</Project>
<Name>SafeExamBrowser.Network.Contracts</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View file

@ -7,8 +7,9 @@
*/
using System;
using System.Collections.Generic;
namespace SafeExamBrowser.Configuration.Contracts.Settings
namespace SafeExamBrowser.Configuration.Contracts.Settings.Browser
{
/// <summary>
/// Defines all configuration options for the browser engine of the application.
@ -46,6 +47,21 @@ namespace SafeExamBrowser.Configuration.Contracts.Settings
/// </summary>
public string CustomUserAgent { get; set; }
/// <summary>
/// Defines whether all content requests for a web page should be filtered according to the defined <see cref="FilterRules"/>.
/// </summary>
public bool FilterContentRequests { get; set; }
/// <summary>
/// Defines whether the main request for a web page should be filtered according to the defined <see cref="FilterRules"/>.
/// </summary>
public bool FilterMainRequests { get; set; }
/// <summary>
/// Defines all rules to be used to filter web requests.
/// </summary>
public IList<FilterRule> FilterRules { get; set; }
/// <summary>
/// The configuration to be used for the main browser window.
/// </summary>
@ -64,6 +80,7 @@ namespace SafeExamBrowser.Configuration.Contracts.Settings
public BrowserSettings()
{
AdditionalWindowSettings = new BrowserWindowSettings();
FilterRules = new List<FilterRule>();
MainWindowSettings = new BrowserWindowSettings();
}
}

View file

@ -8,7 +8,7 @@
using System;
namespace SafeExamBrowser.Configuration.Contracts.Settings
namespace SafeExamBrowser.Configuration.Contracts.Settings.Browser
{
/// <summary>
/// Defines all configuration options for a window of the browser engine.

View file

@ -6,7 +6,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
namespace SafeExamBrowser.Network.Contracts.Filter
namespace SafeExamBrowser.Configuration.Contracts.Settings.Browser
{
/// <summary>
/// Defines all possible results of a request filter operation.
@ -14,12 +14,12 @@ namespace SafeExamBrowser.Network.Contracts.Filter
public enum FilterResult
{
/// <summary>
/// Indicates that a request should be allowed.
/// Indicates that a request should be allowed if a filter matches.
/// </summary>
Allow,
/// <summary>
/// Indicates that a request should be blocked.
/// Indicates that a request should be blocked if a filter matches.
/// </summary>
Block
}

View file

@ -8,10 +8,10 @@
using System;
namespace SafeExamBrowser.Network.Contracts.Filter
namespace SafeExamBrowser.Configuration.Contracts.Settings.Browser
{
/// <summary>
/// Defines a network filter rule.
/// Defines a request filter rule.
/// </summary>
[Serializable]
public class FilterRule

View file

@ -6,7 +6,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
namespace SafeExamBrowser.Network.Contracts.Filter
namespace SafeExamBrowser.Configuration.Contracts.Settings.Browser
{
/// <summary>
/// Defines all possible request filter types.

View file

@ -1,41 +0,0 @@
/*
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
*
* 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/.
*/
using System;
using System.Collections.Generic;
using SafeExamBrowser.Network.Contracts.Filter;
namespace SafeExamBrowser.Configuration.Contracts.Settings
{
/// <summary>
/// Defines all configuration options for network functionality.
/// </summary>
[Serializable]
public class NetworkSettings
{
/// <summary>
/// Defines whether all content requests for a web page should be filtered according to the defined <see cref="FilterRules"/>.
/// </summary>
public bool FilterContentRequests { get; set; }
/// <summary>
/// Defines whether the main request for a web page should be filtered according to the defined <see cref="FilterRules"/>.
/// </summary>
public bool FilterMainRequests { get; set; }
/// <summary>
/// Defines all rules to be used to filter network requests.
/// </summary>
public IList<FilterRule> FilterRules { get; set; }
public NetworkSettings()
{
FilterRules = new List<FilterRule>();
}
}
}

View file

@ -7,6 +7,7 @@
*/
using System;
using SafeExamBrowser.Configuration.Contracts.Settings.Browser;
using SafeExamBrowser.Logging.Contracts;
namespace SafeExamBrowser.Configuration.Contracts.Settings
@ -67,11 +68,6 @@ namespace SafeExamBrowser.Configuration.Contracts.Settings
/// </summary>
public MouseSettings Mouse { get; set; }
/// <summary>
/// All network-related settings.
/// </summary>
public NetworkSettings Network { get; set; }
/// <summary>
/// The hash code of the quit password.
/// </summary>
@ -99,7 +95,6 @@ namespace SafeExamBrowser.Configuration.Contracts.Settings
Browser = new BrowserSettings();
Keyboard = new KeyboardSettings();
Mouse = new MouseSettings();
Network = new NetworkSettings();
Service = new ServiceSettings();
Taskbar = new TaskbarSettings();
}

View file

@ -8,6 +8,7 @@
using System.Collections.Generic;
using SafeExamBrowser.Configuration.Contracts.Settings;
using SafeExamBrowser.Configuration.Contracts.Settings.Browser;
namespace SafeExamBrowser.Configuration.ConfigurationData
{
@ -104,6 +105,55 @@ namespace SafeExamBrowser.Configuration.ConfigurationData
}
}
private void MapEnableContentRequestFilter(Settings settings, object value)
{
if (value is bool filter)
{
settings.Browser.FilterContentRequests = filter;
}
}
private void MapEnableMainRequestFilter(Settings settings, object value)
{
if (value is bool filter)
{
settings.Browser.FilterMainRequests = filter;
}
}
private void MapUrlFilterRules(Settings settings, object value)
{
const int ALLOW = 1;
if (value is IEnumerable<IDictionary<string, object>> ruleDataList)
{
foreach (var ruleData in ruleDataList)
{
if (ruleData.TryGetValue(Keys.Browser.Filter.RuleIsActive, out var v) && v is bool active && active)
{
var rule = new FilterRule();
if (ruleData.TryGetValue(Keys.Browser.Filter.RuleExpression, out v) && v is string expression)
{
rule.Expression = expression;
}
if (ruleData.TryGetValue(Keys.Browser.Filter.RuleAction, out v) && v is int action)
{
rule.Result = action == ALLOW ? FilterResult.Allow : FilterResult.Block;
}
if (ruleData.TryGetValue(Keys.Browser.Filter.RuleExpressionIsRegex, out v) && v is bool regex)
{
rule.Type = regex ? FilterType.Regex : FilterType.Simplified;
}
settings.Browser.FilterRules.Add(rule);
}
}
}
}
private void MapMainWindowMode(Settings settings, object value)
{
const int FULLSCREEN = 1;

View file

@ -1,66 +0,0 @@
/*
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
*
* 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/.
*/
using System.Collections.Generic;
using SafeExamBrowser.Configuration.Contracts.Settings;
using SafeExamBrowser.Network.Contracts.Filter;
namespace SafeExamBrowser.Configuration.ConfigurationData
{
internal partial class DataMapper
{
private void MapEnableContentRequestFilter(Settings settings, object value)
{
if (value is bool filter)
{
settings.Network.FilterContentRequests = filter;
}
}
private void MapEnableMainRequestFilter(Settings settings, object value)
{
if (value is bool filter)
{
settings.Network.FilterMainRequests = filter;
}
}
private void MapUrlFilterRules(Settings settings, object value)
{
const int ALLOW = 1;
if (value is IEnumerable<IDictionary<string, object>> ruleDataList)
{
foreach (var ruleData in ruleDataList)
{
if (ruleData.TryGetValue(Keys.Network.Filter.RuleIsActive, out var v) && v is bool active && active)
{
var rule = new FilterRule();
if (ruleData.TryGetValue(Keys.Network.Filter.RuleExpression, out v) && v is string expression)
{
rule.Expression = expression;
}
if (ruleData.TryGetValue(Keys.Network.Filter.RuleAction, out v) && v is int action)
{
rule.Result = action == ALLOW ? FilterResult.Allow : FilterResult.Block ;
}
if (ruleData.TryGetValue(Keys.Network.Filter.RuleExpressionIsRegex, out v) && v is bool regex)
{
rule.Type = regex ? FilterType.Regex : FilterType.Simplified;
}
settings.Network.FilterRules.Add(rule);
}
}
}
}
}
}

View file

@ -22,7 +22,6 @@ namespace SafeExamBrowser.Configuration.ConfigurationData
MapConfigurationFileSettings(item.Key, item.Value, settings);
MapGeneralSettings(item.Key, item.Value, settings);
MapInputSettings(item.Key, item.Value, settings);
MapNetworkSettings(item.Key, item.Value, settings);
MapSecuritySettings(item.Key, item.Value, settings);
MapUserInterfaceSettings(item.Key, item.Value, settings);
}
@ -70,18 +69,6 @@ namespace SafeExamBrowser.Configuration.ConfigurationData
case Keys.Browser.MainWindowMode:
MapMainWindowMode(settings, value);
break;
case Keys.Browser.MainWindow.AllowAddressBar:
MapAllowAddressBar(settings, value);
break;
case Keys.Browser.MainWindow.AllowNavigation:
MapAllowNavigation(settings, value);
break;
case Keys.Browser.MainWindow.AllowReload:
MapAllowReload(settings, value);
break;
case Keys.Browser.MainWindow.ShowReloadWarning:
MapShowReloadWarning(settings, value);
break;
case Keys.Browser.AdditionalWindow.AllowAddressBar:
MapAllowAddressBarAdditionalWindow(settings, value);
break;
@ -94,6 +81,27 @@ namespace SafeExamBrowser.Configuration.ConfigurationData
case Keys.Browser.AdditionalWindow.ShowReloadWarning:
MapShowReloadWarningAdditionalWindow(settings, value);
break;
case Keys.Browser.Filter.EnableContentRequestFilter:
MapEnableContentRequestFilter(settings, value);
break;
case Keys.Browser.Filter.EnableMainRequestFilter:
MapEnableMainRequestFilter(settings, value);
break;
case Keys.Browser.Filter.UrlFilterRules:
MapUrlFilterRules(settings, value);
break;
case Keys.Browser.MainWindow.AllowAddressBar:
MapAllowAddressBar(settings, value);
break;
case Keys.Browser.MainWindow.AllowNavigation:
MapAllowNavigation(settings, value);
break;
case Keys.Browser.MainWindow.AllowReload:
MapAllowReload(settings, value);
break;
case Keys.Browser.MainWindow.ShowReloadWarning:
MapShowReloadWarning(settings, value);
break;
}
}
@ -193,22 +201,6 @@ namespace SafeExamBrowser.Configuration.ConfigurationData
}
}
private void MapNetworkSettings(string key, object value, Settings settings)
{
switch (key)
{
case Keys.Network.Filter.EnableContentRequestFilter:
MapEnableContentRequestFilter(settings, value);
break;
case Keys.Network.Filter.EnableMainRequestFilter:
MapEnableMainRequestFilter(settings, value);
break;
case Keys.Network.Filter.UrlFilterRules:
MapUrlFilterRules(settings, value);
break;
}
}
private void MapSecuritySettings(string key, object value, Settings settings)
{
switch (key)

View file

@ -38,6 +38,17 @@ namespace SafeExamBrowser.Configuration.ConfigurationData
internal const string UserAgentModeDesktop = "browserUserAgentWinDesktopMode";
internal const string UserAgentModeMobile = "browserUserAgentWinTouchMode";
internal static class Filter
{
internal const string EnableContentRequestFilter = "URLFilterEnableContentFilter";
internal const string EnableMainRequestFilter = "URLFilterEnable";
internal const string RuleAction = "action";
internal const string RuleIsActive = "active";
internal const string RuleExpression = "expression";
internal const string RuleExpressionIsRegex = "regex";
internal const string UrlFilterRules = "URLFilterRules";
}
internal static class MainWindow
{
internal const string AllowAddressBar = "browserWindowAllowAddressBar";
@ -113,17 +124,6 @@ namespace SafeExamBrowser.Configuration.ConfigurationData
internal const string CertificateType = "type";
internal const string EmbeddedCertificates = "embeddedCertificates";
}
internal static class Filter
{
internal const string EnableContentRequestFilter = "URLFilterEnableContentFilter";
internal const string EnableMainRequestFilter = "URLFilterEnable";
internal const string RuleAction = "action";
internal const string RuleIsActive = "active";
internal const string RuleExpression = "expression";
internal const string RuleExpressionIsRegex = "regex";
internal const string UrlFilterRules = "URLFilterRules";
}
}
internal static class Registry

View file

@ -81,9 +81,6 @@
<Compile Include="ConfigurationData\DataMapper.Input.cs">
<DependentUpon>DataMapper.cs</DependentUpon>
</Compile>
<Compile Include="ConfigurationData\DataMapper.Network.cs">
<DependentUpon>DataMapper.cs</DependentUpon>
</Compile>
<Compile Include="ConfigurationData\DataMapper.UserInterface.cs">
<DependentUpon>DataMapper.cs</DependentUpon>
</Compile>
@ -110,10 +107,6 @@
<Project>{64ea30fb-11d4-436a-9c2b-88566285363e}</Project>
<Name>SafeExamBrowser.Logging.Contracts</Name>
</ProjectReference>
<ProjectReference Include="..\SafeExamBrowser.Network.Contracts\SafeExamBrowser.Network.Contracts.csproj">
<Project>{2947da3c-61f3-44be-81cf-d1d5c10aec95}</Project>
<Name>SafeExamBrowser.Network.Contracts</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View file

@ -1,31 +0,0 @@
/*
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
*
* 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/.
*/
namespace SafeExamBrowser.Network.Contracts.Filter
{
/// <summary>
/// Defines a filter to process network requests.
/// </summary>
public interface IRequestFilter
{
/// <summary>
/// Defines the default result to be returned by <see cref="Process(Request)"/> if no filter rule matches.
/// </summary>
FilterResult Default { set; }
/// <summary>
/// Loads the given <see cref="FilterRule"/> to be used when processing a request.
/// </summary>
void Load(FilterRule rule);
/// <summary>
/// Filters the given request according to the loaded <see cref="FilterRule"/>.
/// </summary>
FilterResult Process(Request request);
}
}

View file

@ -1,33 +0,0 @@
using System.Reflection;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("SafeExamBrowser.Network.Contracts")]
[assembly: AssemblyDescription("Safe Exam Browser")]
[assembly: AssemblyCompany("ETH Zürich")]
[assembly: AssemblyProduct("SafeExamBrowser.Network.Contracts")]
[assembly: AssemblyCopyright("Copyright © 2019 ETH Zürich, Educational Development and Technology (LET)")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("2947da3c-61f3-44be-81cf-d1d5c10aec95")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0.0")]

View file

@ -1,64 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{2947DA3C-61F3-44BE-81CF-D1D5C10AEC95}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>SafeExamBrowser.Network.Contracts</RootNamespace>
<AssemblyName>SafeExamBrowser.Network.Contracts</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x86\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>bin\x86\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="Microsoft.CSharp" />
</ItemGroup>
<ItemGroup>
<Compile Include="Filter\FilterResult.cs" />
<Compile Include="Filter\FilterRule.cs" />
<Compile Include="Filter\FilterType.cs" />
<Compile Include="Filter\IRequestFilter.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Request.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View file

@ -1,29 +0,0 @@
/*
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
*
* 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/.
*/
using System;
using SafeExamBrowser.Network.Contracts;
using SafeExamBrowser.Network.Contracts.Filter;
namespace SafeExamBrowser.Network.Filter
{
public class RequestFilter : IRequestFilter
{
public FilterResult Default { private get; set; }
public void Load(FilterRule rule)
{
throw new NotImplementedException();
}
public FilterResult Process(Request request)
{
throw new NotImplementedException();
}
}
}

View file

@ -1,33 +0,0 @@
using System.Reflection;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("SafeExamBrowser.Network")]
[assembly: AssemblyDescription("Safe Exam Browser")]
[assembly: AssemblyCompany("ETH Zürich")]
[assembly: AssemblyProduct("SafeExamBrowser.Network")]
[assembly: AssemblyCopyright("Copyright © 2019 ETH Zürich, Educational Development and Technology (LET)")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("2da8f505-51be-48c8-b32b-5e753e936dec")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0.0")]

View file

@ -1,67 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{2DA8F505-51BE-48C8-B32B-5E753E936DEC}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>SafeExamBrowser.Network</RootNamespace>
<AssemblyName>SafeExamBrowser.Network</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x86\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>bin\x86\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="Microsoft.CSharp" />
</ItemGroup>
<ItemGroup>
<Compile Include="Filter\RequestFilter.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup />
<ItemGroup>
<ProjectReference Include="..\SafeExamBrowser.Network.Contracts\SafeExamBrowser.Network.Contracts.csproj">
<Project>{2947da3c-61f3-44be-81cf-d1d5c10aec95}</Project>
<Name>SafeExamBrowser.Network.Contracts</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View file

@ -9,7 +9,7 @@
using SafeExamBrowser.Applications.Contracts;
using SafeExamBrowser.Client.Contracts;
using SafeExamBrowser.Configuration.Contracts;
using SafeExamBrowser.Configuration.Contracts.Settings;
using SafeExamBrowser.Configuration.Contracts.Settings.Browser;
using SafeExamBrowser.I18n.Contracts;
using SafeExamBrowser.Logging.Contracts;
using SafeExamBrowser.SystemComponents.Contracts.Audio;

View file

@ -14,7 +14,7 @@ using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using SafeExamBrowser.Configuration.Contracts.Settings;
using SafeExamBrowser.Configuration.Contracts.Settings.Browser;
using SafeExamBrowser.Core.Contracts;
using SafeExamBrowser.I18n.Contracts;
using SafeExamBrowser.UserInterface.Contracts;

View file

@ -13,7 +13,7 @@ using FontAwesome.WPF;
using SafeExamBrowser.Applications.Contracts;
using SafeExamBrowser.Client.Contracts;
using SafeExamBrowser.Configuration.Contracts;
using SafeExamBrowser.Configuration.Contracts.Settings;
using SafeExamBrowser.Configuration.Contracts.Settings.Browser;
using SafeExamBrowser.I18n.Contracts;
using SafeExamBrowser.Logging.Contracts;
using SafeExamBrowser.SystemComponents.Contracts.Audio;

View file

@ -14,7 +14,7 @@ using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using SafeExamBrowser.Configuration.Contracts.Settings;
using SafeExamBrowser.Configuration.Contracts.Settings.Browser;
using SafeExamBrowser.Core.Contracts;
using SafeExamBrowser.I18n.Contracts;
using SafeExamBrowser.UserInterface.Contracts;

View file

@ -13,7 +13,7 @@ using FontAwesome.WPF;
using SafeExamBrowser.Applications.Contracts;
using SafeExamBrowser.Client.Contracts;
using SafeExamBrowser.Configuration.Contracts;
using SafeExamBrowser.Configuration.Contracts.Settings;
using SafeExamBrowser.Configuration.Contracts.Settings.Browser;
using SafeExamBrowser.I18n.Contracts;
using SafeExamBrowser.Logging.Contracts;
using SafeExamBrowser.SystemComponents.Contracts.Audio;

View file

@ -92,8 +92,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SafeExamBrowser.Logging.Con
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SafeExamBrowser.Monitoring.Contracts", "SafeExamBrowser.Monitoring.Contracts\SafeExamBrowser.Monitoring.Contracts.csproj", "{6D563A30-366D-4C35-815B-2C9E6872278B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SafeExamBrowser.Network.Contracts", "SafeExamBrowser.Network.Contracts\SafeExamBrowser.Network.Contracts.csproj", "{2947DA3C-61F3-44BE-81CF-D1D5C10AEC95}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SafeExamBrowser.Runtime.Contracts", "SafeExamBrowser.Runtime.Contracts\SafeExamBrowser.Runtime.Contracts.csproj", "{5D0136B4-6D21-4F99-AE42-3FB7F478AE0A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SafeExamBrowser.Service.Contracts", "SafeExamBrowser.Service.Contracts\SafeExamBrowser.Service.Contracts.csproj", "{5167820F-2BE5-43CF-B1CC-E4874BF83808}"
@ -104,8 +102,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SafeExamBrowser.UserInterfa
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SafeExamBrowser.WindowsApi.Contracts", "SafeExamBrowser.WindowsApi.Contracts\SafeExamBrowser.WindowsApi.Contracts.csproj", "{7016F080-9AA5-41B2-A225-385AD877C171}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SafeExamBrowser.Network", "SafeExamBrowser.Network\SafeExamBrowser.Network.csproj", "{2DA8F505-51BE-48C8-B32B-5E753E936DEC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -420,14 +416,6 @@ Global
{6D563A30-366D-4C35-815B-2C9E6872278B}.Release|Any CPU.Build.0 = Release|Any CPU
{6D563A30-366D-4C35-815B-2C9E6872278B}.Release|x86.ActiveCfg = Release|x86
{6D563A30-366D-4C35-815B-2C9E6872278B}.Release|x86.Build.0 = Release|x86
{2947DA3C-61F3-44BE-81CF-D1D5C10AEC95}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2947DA3C-61F3-44BE-81CF-D1D5C10AEC95}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2947DA3C-61F3-44BE-81CF-D1D5C10AEC95}.Debug|x86.ActiveCfg = Debug|x86
{2947DA3C-61F3-44BE-81CF-D1D5C10AEC95}.Debug|x86.Build.0 = Debug|x86
{2947DA3C-61F3-44BE-81CF-D1D5C10AEC95}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2947DA3C-61F3-44BE-81CF-D1D5C10AEC95}.Release|Any CPU.Build.0 = Release|Any CPU
{2947DA3C-61F3-44BE-81CF-D1D5C10AEC95}.Release|x86.ActiveCfg = Release|x86
{2947DA3C-61F3-44BE-81CF-D1D5C10AEC95}.Release|x86.Build.0 = Release|x86
{5D0136B4-6D21-4F99-AE42-3FB7F478AE0A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5D0136B4-6D21-4F99-AE42-3FB7F478AE0A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5D0136B4-6D21-4F99-AE42-3FB7F478AE0A}.Debug|x86.ActiveCfg = Debug|x86
@ -468,14 +456,6 @@ Global
{7016F080-9AA5-41B2-A225-385AD877C171}.Release|Any CPU.Build.0 = Release|Any CPU
{7016F080-9AA5-41B2-A225-385AD877C171}.Release|x86.ActiveCfg = Release|x86
{7016F080-9AA5-41B2-A225-385AD877C171}.Release|x86.Build.0 = Release|x86
{2DA8F505-51BE-48C8-B32B-5E753E936DEC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2DA8F505-51BE-48C8-B32B-5E753E936DEC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2DA8F505-51BE-48C8-B32B-5E753E936DEC}.Debug|x86.ActiveCfg = Debug|x86
{2DA8F505-51BE-48C8-B32B-5E753E936DEC}.Debug|x86.Build.0 = Debug|x86
{2DA8F505-51BE-48C8-B32B-5E753E936DEC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2DA8F505-51BE-48C8-B32B-5E753E936DEC}.Release|Any CPU.Build.0 = Release|Any CPU
{2DA8F505-51BE-48C8-B32B-5E753E936DEC}.Release|x86.ActiveCfg = Release|x86
{2DA8F505-51BE-48C8-B32B-5E753E936DEC}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE