diff --git a/SafeExamBrowser.Browser/BrowserApplicationController.cs b/SafeExamBrowser.Browser/BrowserApplicationController.cs
index fc6e54c8..063c9f59 100644
--- a/SafeExamBrowser.Browser/BrowserApplicationController.cs
+++ b/SafeExamBrowser.Browser/BrowserApplicationController.cs
@@ -69,6 +69,11 @@ namespace SafeExamBrowser.Browser
this.button.Clicked += Button_OnClick;
}
+ public void Start()
+ {
+ CreateNewInstance();
+ }
+
public void Terminate()
{
foreach (var instance in instances)
diff --git a/SafeExamBrowser.Client/ClientController.cs b/SafeExamBrowser.Client/ClientController.cs
index 3478a4a8..a1675a2c 100644
--- a/SafeExamBrowser.Client/ClientController.cs
+++ b/SafeExamBrowser.Client/ClientController.cs
@@ -105,6 +105,7 @@ namespace SafeExamBrowser.Client
if (success)
{
RegisterEvents();
+ StartBrowser();
var communication = runtime.InformClientReady();
@@ -182,6 +183,12 @@ namespace SafeExamBrowser.Client
windowMonitor.WindowChanged -= WindowMonitor_WindowChanged;
}
+ private void StartBrowser()
+ {
+ logger.Info("Starting browser application...");
+ Browser.Start();
+ }
+
private void DisplayMonitor_DisplaySettingsChanged()
{
logger.Info("Reinitializing working area...");
diff --git a/SafeExamBrowser.Configuration/Compression/GZipCompressor.cs b/SafeExamBrowser.Configuration/Compression/GZipCompressor.cs
new file mode 100644
index 00000000..43d09b93
--- /dev/null
+++ b/SafeExamBrowser.Configuration/Compression/GZipCompressor.cs
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2018 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.IO;
+using System.IO.Compression;
+using SafeExamBrowser.Contracts.Configuration;
+using SafeExamBrowser.Contracts.Logging;
+
+namespace SafeExamBrowser.Configuration.Compression
+{
+ ///
+ /// Data compression using the GNU-Zip format (see https://en.wikipedia.org/wiki/Gzip).
+ ///
+ public class GZipCompressor : IDataCompressor
+ {
+ private const int ID1 = 0x1F;
+ private const int ID2 = 0x8B;
+ private const int CM = 8;
+ private const int FOOTER_LENGTH = 8;
+ private const int HEADER_LENGTH = 10;
+
+ private ILogger logger;
+
+ public GZipCompressor(ILogger logger)
+ {
+ this.logger = logger;
+ }
+
+ public Stream Compress(Stream data)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Stream Decompress(Stream data)
+ {
+ var decompressed = new MemoryStream();
+
+ logger.Debug($"Starting decompression of '{data}' with {data.Length / 1000.0} KB data...");
+ data.Seek(0, SeekOrigin.Begin);
+
+ using (var stream = new GZipStream(data, CompressionMode.Decompress))
+ {
+ var buffer = new byte[4096];
+ var bytesRead = 0;
+
+ do
+ {
+ bytesRead = stream.Read(buffer, 0, buffer.Length);
+ decompressed.Write(buffer, 0, bytesRead);
+ } while (bytesRead > 0);
+ }
+
+ logger.Debug($"Successfully decompressed {decompressed.Length / 1000.0} KB data into '{decompressed}'.");
+
+ return decompressed;
+ }
+
+ ///
+ /// All gzip-compressed data has a 10-byte header and 8-byte footer. The header starts with two magic numbers (ID1 and ID2) and
+ /// the used compression method (CM), which normally denotes the DEFLATE algorithm. See https://tools.ietf.org/html/rfc1952 for
+ /// the original data format specification.
+ ///
+ public bool IsCompressed(Stream data)
+ {
+ try
+ {
+ var longEnough = data.Length > HEADER_LENGTH + FOOTER_LENGTH;
+
+ data.Seek(0, SeekOrigin.Begin);
+
+ if (longEnough)
+ {
+ var id1 = data.ReadByte();
+ var id2 = data.ReadByte();
+ var cm = data.ReadByte();
+ var compressed = id1 == ID1 && id2 == ID2 && cm == CM;
+
+ logger.Debug($"'{data}' is {(compressed ? string.Empty : "not ")}a gzip-compressed stream.");
+
+ return compressed;
+ }
+
+ logger.Debug($"'{data}' is not long enough ({data.Length} bytes) to be a gzip-compressed stream.");
+ }
+ catch (Exception e)
+ {
+ logger.Error($"Failed to check whether '{data}' with {data.Length / 1000.0} KB data is a gzip-compressed stream!", e);
+ }
+
+ return false;
+ }
+
+ public byte[] Peek(Stream data, int count)
+ {
+ logger.Debug($"Peeking {count} bytes from '{data}'...");
+ data.Seek(0, SeekOrigin.Begin);
+
+ using (var stream = new GZipStream(data, CompressionMode.Decompress))
+ using (var decompressed = new MemoryStream())
+ {
+ var buffer = new byte[count];
+ var bytesRead = stream.Read(buffer, 0, buffer.Length);
+
+ decompressed.Write(buffer, 0, bytesRead);
+
+ return decompressed.ToArray();
+ }
+ }
+ }
+}
diff --git a/SafeExamBrowser.Configuration/ConfigurationRepository.cs b/SafeExamBrowser.Configuration/ConfigurationRepository.cs
index 4d615f65..141be2c6 100644
--- a/SafeExamBrowser.Configuration/ConfigurationRepository.cs
+++ b/SafeExamBrowser.Configuration/ConfigurationRepository.cs
@@ -9,7 +9,6 @@
using System;
using System.Collections.Generic;
using System.IO;
-using System.IO.Compression;
using System.Linq;
using SafeExamBrowser.Contracts.Configuration;
using SafeExamBrowser.Contracts.Configuration.Settings;
@@ -133,12 +132,15 @@ namespace SafeExamBrowser.Configuration
{
var status = TryLoadData(resource, out Stream data);
- switch (status)
+ using (data)
{
- case LoadStatus.LoadWithBrowser:
- return HandleBrowserResource(resource, out settings);
- case LoadStatus.Success:
- return TryParseData(data, out settings, adminPassword, settingsPassword);
+ switch (status)
+ {
+ case LoadStatus.LoadWithBrowser:
+ return HandleBrowserResource(resource, out settings);
+ case LoadStatus.Success:
+ return TryParseData(data, out settings, adminPassword, settingsPassword);
+ }
}
return status;
@@ -201,32 +203,6 @@ namespace SafeExamBrowser.Configuration
return LoadStatus.Success;
}
- private byte[] Decompress(byte[] bytes)
- {
- try
- {
- var buffer = new byte[4096];
-
- using (var stream = new GZipStream(new MemoryStream(bytes), CompressionMode.Decompress))
- using (var decompressed = new MemoryStream())
- {
- var bytesRead = 0;
-
- do
- {
- bytesRead = stream.Read(buffer, 0, buffer.Length);
- decompressed.Write(buffer, 0, bytesRead);
- } while (bytesRead > 0);
-
- return decompressed.ToArray();
- }
- }
- catch (InvalidDataException)
- {
- return bytes;
- }
- }
-
private void UpdateAppConfig()
{
appConfig.ClientId = Guid.NewGuid();
diff --git a/SafeExamBrowser.Configuration/DataFormats/BinaryFormat.cs b/SafeExamBrowser.Configuration/DataFormats/BinaryFormat.cs
new file mode 100644
index 00000000..ecbb1e3a
--- /dev/null
+++ b/SafeExamBrowser.Configuration/DataFormats/BinaryFormat.cs
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2018 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.IO;
+using System.Text;
+using SafeExamBrowser.Contracts.Configuration;
+using SafeExamBrowser.Contracts.Configuration.Settings;
+using SafeExamBrowser.Contracts.Logging;
+
+namespace SafeExamBrowser.Configuration.DataFormats
+{
+ public class BinaryFormat : IDataFormat
+ {
+ private const int PREFIX_LENGTH = 4;
+
+ private IDataCompressor compressor;
+ private ILogger logger;
+
+ public BinaryFormat(IDataCompressor compressor, ILogger logger)
+ {
+ this.compressor = compressor;
+ this.logger = logger;
+ }
+
+ public bool CanParse(Stream data)
+ {
+ try
+ {
+ var longEnough = data.Length > PREFIX_LENGTH;
+
+ if (longEnough)
+ {
+ var prefix = ParsePrefix(data);
+ var success = TryDetermineFormat(prefix, out DataFormat format);
+
+ logger.Debug($"'{data}' starting with '{prefix}' does {(success ? string.Empty : "not ")}match the binary format.");
+
+ return success;
+ }
+
+ logger.Debug($"'{data}' is not long enough ({data.Length} bytes) to match the binary format.");
+ }
+ catch (Exception e)
+ {
+ logger.Error($"Failed to determine whether '{data}' with {data.Length / 1000.0} KB data matches the binary format!", e);
+ }
+
+ return false;
+ }
+
+ public LoadStatus TryParse(Stream data, out Settings settings, string adminPassword = null, string settingsPassword = null)
+ {
+ settings = new Settings();
+ settings.Browser.AllowAddressBar = true;
+ settings.Browser.StartUrl = "www.duckduckgo.com";
+ settings.Browser.AllowConfigurationDownloads = true;
+
+ return LoadStatus.Success;
+ }
+
+ private string ParsePrefix(Stream data)
+ {
+ var prefixData = new byte[PREFIX_LENGTH];
+
+ if (compressor.IsCompressed(data))
+ {
+ prefixData = compressor.Peek(data, PREFIX_LENGTH);
+ }
+ else
+ {
+ data.Seek(0, SeekOrigin.Begin);
+ data.Read(prefixData, 0, PREFIX_LENGTH);
+ }
+
+ return Encoding.UTF8.GetString(prefixData);
+ }
+
+ private bool TryDetermineFormat(string prefix, out DataFormat format)
+ {
+ format = default(DataFormat);
+
+ switch (prefix)
+ {
+ case "pswd":
+ format = DataFormat.Password;
+ return true;
+ case "pwcc":
+ format = DataFormat.PasswordForConfigureClient;
+ return true;
+ case "plnd":
+ format = DataFormat.PlainData;
+ return true;
+ case "pkhs":
+ format = DataFormat.PublicKeyHash;
+ return true;
+ case "phsk":
+ format = DataFormat.PublicKeyHashWithSymmetricKey;
+ return true;
+ }
+
+ return false;
+ }
+
+ private enum DataFormat
+ {
+ Password = 1,
+ PasswordForConfigureClient,
+ PlainData,
+ PublicKeyHash,
+ PublicKeyHashWithSymmetricKey
+ }
+ }
+}
diff --git a/SafeExamBrowser.Configuration/DataFormats/DefaultFormat.cs b/SafeExamBrowser.Configuration/DataFormats/DefaultFormat.cs
deleted file mode 100644
index 44826da7..00000000
--- a/SafeExamBrowser.Configuration/DataFormats/DefaultFormat.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2018 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.IO;
-using SafeExamBrowser.Contracts.Configuration;
-using SafeExamBrowser.Contracts.Configuration.Settings;
-using SafeExamBrowser.Contracts.Logging;
-
-namespace SafeExamBrowser.Configuration.DataFormats
-{
- public class DefaultFormat : IDataFormat
- {
- private ILogger logger;
-
- public DefaultFormat(ILogger logger)
- {
- this.logger = logger;
- }
-
- public bool CanParse(Stream data)
- {
- return false;
- }
-
- public LoadStatus TryParse(Stream data, out Settings settings, string adminPassword = null, string settingsPassword = null)
- {
- throw new System.NotImplementedException();
- }
- }
-}
diff --git a/SafeExamBrowser.Configuration/ResourceLoaders/FileResourceLoader.cs b/SafeExamBrowser.Configuration/ResourceLoaders/FileResourceLoader.cs
index b731a554..177514e5 100644
--- a/SafeExamBrowser.Configuration/ResourceLoaders/FileResourceLoader.cs
+++ b/SafeExamBrowser.Configuration/ResourceLoaders/FileResourceLoader.cs
@@ -24,7 +24,7 @@ namespace SafeExamBrowser.Configuration.ResourceLoaders
public bool CanLoad(Uri resource)
{
- var exists = resource.IsFile && File.Exists(resource.AbsolutePath);
+ var exists = resource.IsFile && File.Exists(resource.LocalPath);
if (exists)
{
@@ -41,8 +41,8 @@ namespace SafeExamBrowser.Configuration.ResourceLoaders
public LoadStatus TryLoad(Uri resource, out Stream data)
{
logger.Debug($"Loading data from '{resource}'...");
- data = new FileStream(resource.AbsolutePath, FileMode.Open, FileAccess.Read);
- logger.Debug($"Created {data} for {data.Length / 1000.0} KB data in '{resource}'.");
+ data = new FileStream(resource.LocalPath, FileMode.Open, FileAccess.Read);
+ logger.Debug($"Created '{data}' for {data.Length / 1000.0} KB data in '{resource}'.");
return LoadStatus.Success;
}
diff --git a/SafeExamBrowser.Configuration/ResourceLoaders/NetworkResourceLoader.cs b/SafeExamBrowser.Configuration/ResourceLoaders/NetworkResourceLoader.cs
index e5e3351c..20a544fa 100644
--- a/SafeExamBrowser.Configuration/ResourceLoaders/NetworkResourceLoader.cs
+++ b/SafeExamBrowser.Configuration/ResourceLoaders/NetworkResourceLoader.cs
@@ -23,6 +23,9 @@ namespace SafeExamBrowser.Configuration.ResourceLoaders
private AppConfig appConfig;
private ILogger logger;
+ ///
+ /// See https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types.
+ ///
private string[] SupportedContentTypes => new[]
{
MediaTypeNames.Application.Octet,
@@ -77,7 +80,7 @@ namespace SafeExamBrowser.Configuration.ResourceLoaders
logger.Debug($"Trying to extract response data...");
data = Extract(response.Content);
- logger.Debug($"Created {data} for {data.Length / 1000.0} KB data of response body.");
+ logger.Debug($"Created '{data}' for {data.Length / 1000.0} KB data of response body.");
return LoadStatus.Success;
}
@@ -137,6 +140,9 @@ namespace SafeExamBrowser.Configuration.ResourceLoaders
return LoadStatus.LoadWithBrowser;
}
+ ///
+ /// See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type.
+ ///
private bool HasHtmlContent(HttpResponseMessage response)
{
return response.Content.Headers.ContentType.MediaType == MediaTypeNames.Text.Html;
diff --git a/SafeExamBrowser.Configuration/SafeExamBrowser.Configuration.csproj b/SafeExamBrowser.Configuration/SafeExamBrowser.Configuration.csproj
index 17427d29..aa22a3c4 100644
--- a/SafeExamBrowser.Configuration/SafeExamBrowser.Configuration.csproj
+++ b/SafeExamBrowser.Configuration/SafeExamBrowser.Configuration.csproj
@@ -53,7 +53,8 @@
-
+
+
diff --git a/SafeExamBrowser.Contracts/Configuration/IDataCompressor.cs b/SafeExamBrowser.Contracts/Configuration/IDataCompressor.cs
new file mode 100644
index 00000000..b3767c65
--- /dev/null
+++ b/SafeExamBrowser.Contracts/Configuration/IDataCompressor.cs
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2018 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.IO;
+
+namespace SafeExamBrowser.Contracts.Configuration
+{
+ ///
+ /// Defines the functionality for data compression and decompression.
+ ///
+ public interface IDataCompressor
+ {
+ ///
+ /// Compresses the data from the given stream.
+ ///
+ Stream Compress(Stream data);
+
+ ///
+ /// Decompresses the data from the given stream.
+ ///
+ Stream Decompress(Stream data);
+
+ ///
+ /// Indicates whether the given stream holds compressed data.
+ ///
+ bool IsCompressed(Stream data);
+
+ ///
+ /// Decompresses the specified number of bytes from the beginning of the given stream.
+ ///
+ byte[] Peek(Stream data, int count);
+ }
+}
diff --git a/SafeExamBrowser.Contracts/Configuration/Settings/Settings.cs b/SafeExamBrowser.Contracts/Configuration/Settings/Settings.cs
index f6d00873..3d7ab19b 100644
--- a/SafeExamBrowser.Contracts/Configuration/Settings/Settings.cs
+++ b/SafeExamBrowser.Contracts/Configuration/Settings/Settings.cs
@@ -57,6 +57,10 @@ namespace SafeExamBrowser.Contracts.Configuration.Settings
Keyboard = new KeyboardSettings();
Mouse = new MouseSettings();
Taskbar = new TaskbarSettings();
+
+ // TODO: For version 3.0 alpha only, remove for final release!
+ ServicePolicy = ServicePolicy.Optional;
+ Taskbar.AllowApplicationLog = true;
}
}
}
diff --git a/SafeExamBrowser.Contracts/Core/IApplicationController.cs b/SafeExamBrowser.Contracts/Core/IApplicationController.cs
index e8e9eff0..12d9fc20 100644
--- a/SafeExamBrowser.Contracts/Core/IApplicationController.cs
+++ b/SafeExamBrowser.Contracts/Core/IApplicationController.cs
@@ -25,6 +25,11 @@ namespace SafeExamBrowser.Contracts.Core
///
void RegisterApplicationButton(IApplicationButton button);
+ ///
+ /// Starts the execution of the application.
+ ///
+ void Start();
+
///
/// Performs any termination work, e.g. releasing of used resources.
///
diff --git a/SafeExamBrowser.Contracts/SafeExamBrowser.Contracts.csproj b/SafeExamBrowser.Contracts/SafeExamBrowser.Contracts.csproj
index e2819818..ec08d424 100644
--- a/SafeExamBrowser.Contracts/SafeExamBrowser.Contracts.csproj
+++ b/SafeExamBrowser.Contracts/SafeExamBrowser.Contracts.csproj
@@ -53,6 +53,7 @@
+
diff --git a/SafeExamBrowser.Runtime.UnitTests/Operations/ConfigurationOperationTests.cs b/SafeExamBrowser.Runtime.UnitTests/Operations/ConfigurationOperationTests.cs
index 57281a9a..58d17b7f 100644
--- a/SafeExamBrowser.Runtime.UnitTests/Operations/ConfigurationOperationTests.cs
+++ b/SafeExamBrowser.Runtime.UnitTests/Operations/ConfigurationOperationTests.cs
@@ -381,7 +381,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
var location = Path.GetDirectoryName(GetType().Assembly.Location);
var resource = new Uri(Path.Combine(location, nameof(Operations), "SettingsDummy.txt"));
- sessionContext.ReconfigurationFilePath = resource.AbsolutePath;
+ sessionContext.ReconfigurationFilePath = resource.LocalPath;
repository.Setup(r => r.TryLoadSettings(It.Is(u => u.Equals(resource)), out settings, null, null)).Returns(LoadStatus.Success);
sut = new ConfigurationOperation(null, repository.Object, logger.Object, sessionContext);
@@ -408,7 +408,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
repository.Verify(r => r.TryLoadSettings(It.Is(u => u.Equals(resource)), out settings, null, null), Times.Never);
Assert.AreEqual(OperationResult.Failed, result);
- sessionContext.ReconfigurationFilePath = resource.AbsolutePath;
+ sessionContext.ReconfigurationFilePath = resource.LocalPath;
result = sut.Repeat();
repository.Verify(r => r.TryLoadSettings(It.Is(u => u.Equals(resource)), out settings, null, null), Times.Never);
diff --git a/SafeExamBrowser.Runtime/CompositionRoot.cs b/SafeExamBrowser.Runtime/CompositionRoot.cs
index 1f9639be..195d0ede 100644
--- a/SafeExamBrowser.Runtime/CompositionRoot.cs
+++ b/SafeExamBrowser.Runtime/CompositionRoot.cs
@@ -13,6 +13,7 @@ using System.Reflection;
using SafeExamBrowser.Communication.Hosts;
using SafeExamBrowser.Communication.Proxies;
using SafeExamBrowser.Configuration;
+using SafeExamBrowser.Configuration.Compression;
using SafeExamBrowser.Configuration.DataFormats;
using SafeExamBrowser.Configuration.ResourceLoaders;
using SafeExamBrowser.Contracts.Configuration;
@@ -112,12 +113,13 @@ namespace SafeExamBrowser.Runtime
var programCopyright = executable.GetCustomAttribute().Copyright;
var programTitle = executable.GetCustomAttribute().Title;
var programVersion = executable.GetCustomAttribute().InformationalVersion;
- var moduleLogger = new ModuleLogger(logger, nameof(ConfigurationRepository));
+ var compressor = new GZipCompressor(new ModuleLogger(logger, nameof(GZipCompressor)));
+ var repositoryLogger = new ModuleLogger(logger, nameof(ConfigurationRepository));
- configuration = new ConfigurationRepository(moduleLogger, executable.Location, programCopyright, programTitle, programVersion);
+ configuration = new ConfigurationRepository(repositoryLogger, executable.Location, programCopyright, programTitle, programVersion);
appConfig = configuration.InitializeAppConfig();
- configuration.Register(new DefaultFormat(new ModuleLogger(logger, nameof(DefaultFormat))));
+ configuration.Register(new BinaryFormat(compressor, new ModuleLogger(logger, nameof(BinaryFormat))));
configuration.Register(new XmlFormat(new ModuleLogger(logger, nameof(XmlFormat))));
configuration.Register(new FileResourceLoader(new ModuleLogger(logger, nameof(FileResourceLoader))));
configuration.Register(new NetworkResourceLoader(appConfig, new ModuleLogger(logger, nameof(NetworkResourceLoader))));
diff --git a/SafeExamBrowser.Runtime/Operations/ConfigurationOperation.cs b/SafeExamBrowser.Runtime/Operations/ConfigurationOperation.cs
index 208fd308..858f1bf0 100644
--- a/SafeExamBrowser.Runtime/Operations/ConfigurationOperation.cs
+++ b/SafeExamBrowser.Runtime/Operations/ConfigurationOperation.cs
@@ -44,22 +44,22 @@ namespace SafeExamBrowser.Runtime.Operations
logger.Info("Initializing application configuration...");
StatusChanged?.Invoke(TextKey.OperationStatus_InitializeConfiguration);
+ var result = OperationResult.Failed;
var isValidUri = TryInitializeSettingsUri(out Uri uri);
if (isValidUri)
{
- var result = LoadSettings(uri);
-
+ result = LoadSettings(uri);
HandleClientConfiguration(ref result, uri);
- LogOperationResult(result);
-
- return result;
+ }
+ else
+ {
+ result = LoadDefaultSettings();
}
- logger.Info("No valid configuration resource specified nor found in PROGRAMDATA or APPDATA - loading default settings...");
- Context.Next.Settings = configuration.LoadDefaultSettings();
+ LogOperationResult(result);
- return OperationResult.Success;
+ return result;
}
public override OperationResult Repeat()
@@ -67,20 +67,21 @@ namespace SafeExamBrowser.Runtime.Operations
logger.Info("Initializing new application configuration...");
StatusChanged?.Invoke(TextKey.OperationStatus_InitializeConfiguration);
+ var result = OperationResult.Failed;
var isValidUri = TryValidateSettingsUri(Context.ReconfigurationFilePath, out Uri uri);
if (isValidUri)
{
- var result = LoadSettings(uri);
-
- LogOperationResult(result);
-
- return result;
+ result = LoadSettings(uri);
+ }
+ else
+ {
+ logger.Warn($"The resource specified for reconfiguration does not exist or is not valid!");
}
- logger.Warn($"The resource specified for reconfiguration does not exist or is not valid!");
+ LogOperationResult(result);
- return OperationResult.Failed;
+ return result;
}
public override OperationResult Revert()
@@ -88,6 +89,14 @@ namespace SafeExamBrowser.Runtime.Operations
return OperationResult.Success;
}
+ private OperationResult LoadDefaultSettings()
+ {
+ logger.Info("No valid configuration resource specified nor found in PROGRAMDATA or APPDATA - loading default settings...");
+ Context.Next.Settings = configuration.LoadDefaultSettings();
+
+ return OperationResult.Success;
+ }
+
private OperationResult LoadSettings(Uri uri)
{
var adminPassword = default(string);