Implement the Virus Scanner.

This commit is contained in:
Michael 2017-06-29 09:14:39 -04:00
parent 027788fa85
commit e65e99578d
7 changed files with 807 additions and 0 deletions

View file

@ -0,0 +1,302 @@
namespace ShiftOS.WinForms.Applications
{
partial class VirusScanner
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(VirusScanner));
this.pnlsidebar = new System.Windows.Forms.FlowLayoutPanel();
this.btnscanfs = new System.Windows.Forms.Button();
this.btnscanmem = new System.Windows.Forms.Button();
this.btnscanfile = new System.Windows.Forms.Button();
this.btnexit = new System.Windows.Forms.Button();
this.pnlbody = new System.Windows.Forms.Panel();
this.pnlintro = new System.Windows.Forms.Panel();
this.lbintrotext = new System.Windows.Forms.Label();
this.lbintrotitle = new System.Windows.Forms.Label();
this.lbstatus = new System.Windows.Forms.Label();
this.pnlscanner = new System.Windows.Forms.Panel();
this.label2 = new System.Windows.Forms.Label();
this.lbscanstatus = new System.Windows.Forms.Label();
this.pnlsummary = new System.Windows.Forms.Panel();
this.label3 = new System.Windows.Forms.Label();
this.label1 = new System.Windows.Forms.Label();
this.flviruses = new System.Windows.Forms.FlowLayoutPanel();
this.pgscannerprogress = new ShiftOS.WinForms.Controls.ShiftedProgressBar();
this.pnlsidebar.SuspendLayout();
this.pnlbody.SuspendLayout();
this.pnlintro.SuspendLayout();
this.pnlscanner.SuspendLayout();
this.pnlsummary.SuspendLayout();
this.SuspendLayout();
//
// pnlsidebar
//
this.pnlsidebar.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)));
this.pnlsidebar.Controls.Add(this.btnscanfs);
this.pnlsidebar.Controls.Add(this.btnscanmem);
this.pnlsidebar.Controls.Add(this.btnscanfile);
this.pnlsidebar.FlowDirection = System.Windows.Forms.FlowDirection.TopDown;
this.pnlsidebar.Location = new System.Drawing.Point(4, 4);
this.pnlsidebar.Name = "pnlsidebar";
this.pnlsidebar.Size = new System.Drawing.Size(138, 399);
this.pnlsidebar.TabIndex = 0;
//
// btnscanfs
//
this.btnscanfs.Location = new System.Drawing.Point(3, 3);
this.btnscanfs.Name = "btnscanfs";
this.btnscanfs.Size = new System.Drawing.Size(135, 23);
this.btnscanfs.TabIndex = 0;
this.btnscanfs.Text = "Scan filesystem";
this.btnscanfs.UseVisualStyleBackColor = true;
this.btnscanfs.Click += new System.EventHandler(this.btnscanfs_Click);
//
// btnscanmem
//
this.btnscanmem.Location = new System.Drawing.Point(3, 32);
this.btnscanmem.Name = "btnscanmem";
this.btnscanmem.Size = new System.Drawing.Size(135, 23);
this.btnscanmem.TabIndex = 1;
this.btnscanmem.Text = "Scan memory";
this.btnscanmem.UseVisualStyleBackColor = true;
this.btnscanmem.Click += new System.EventHandler(this.btnscanmem_Click);
//
// btnscanfile
//
this.btnscanfile.Location = new System.Drawing.Point(3, 61);
this.btnscanfile.Name = "btnscanfile";
this.btnscanfile.Size = new System.Drawing.Size(135, 23);
this.btnscanfile.TabIndex = 2;
this.btnscanfile.Text = "Scan file";
this.btnscanfile.UseVisualStyleBackColor = true;
this.btnscanfile.Click += new System.EventHandler(this.btnscanfile_Click);
//
// btnexit
//
this.btnexit.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.btnexit.Location = new System.Drawing.Point(7, 409);
this.btnexit.Name = "btnexit";
this.btnexit.Size = new System.Drawing.Size(135, 23);
this.btnexit.TabIndex = 1;
this.btnexit.Text = "Exit";
this.btnexit.UseVisualStyleBackColor = true;
this.btnexit.Click += new System.EventHandler(this.btnexit_Click);
//
// pnlbody
//
this.pnlbody.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.pnlbody.Controls.Add(this.pnlsummary);
this.pnlbody.Controls.Add(this.pnlscanner);
this.pnlbody.Controls.Add(this.pnlintro);
this.pnlbody.Location = new System.Drawing.Point(149, 4);
this.pnlbody.Name = "pnlbody";
this.pnlbody.Size = new System.Drawing.Size(498, 399);
this.pnlbody.TabIndex = 2;
//
// pnlintro
//
this.pnlintro.Controls.Add(this.lbintrotext);
this.pnlintro.Controls.Add(this.lbintrotitle);
this.pnlintro.Dock = System.Windows.Forms.DockStyle.Fill;
this.pnlintro.Location = new System.Drawing.Point(0, 0);
this.pnlintro.Name = "pnlintro";
this.pnlintro.Size = new System.Drawing.Size(498, 399);
this.pnlintro.TabIndex = 0;
//
// lbintrotext
//
this.lbintrotext.Dock = System.Windows.Forms.DockStyle.Fill;
this.lbintrotext.Location = new System.Drawing.Point(0, 33);
this.lbintrotext.Name = "lbintrotext";
this.lbintrotext.Padding = new System.Windows.Forms.Padding(10);
this.lbintrotext.Size = new System.Drawing.Size(498, 366);
this.lbintrotext.TabIndex = 1;
this.lbintrotext.Tag = "";
this.lbintrotext.Text = resources.GetString("lbintrotext.Text");
//
// lbintrotitle
//
this.lbintrotitle.AutoSize = true;
this.lbintrotitle.Dock = System.Windows.Forms.DockStyle.Top;
this.lbintrotitle.Location = new System.Drawing.Point(0, 0);
this.lbintrotitle.Name = "lbintrotitle";
this.lbintrotitle.Padding = new System.Windows.Forms.Padding(10);
this.lbintrotitle.Size = new System.Drawing.Size(93, 33);
this.lbintrotitle.TabIndex = 0;
this.lbintrotitle.Tag = "header3";
this.lbintrotitle.Text = "Virus Scanner";
//
// lbstatus
//
this.lbstatus.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.lbstatus.AutoSize = true;
this.lbstatus.Location = new System.Drawing.Point(152, 410);
this.lbstatus.Name = "lbstatus";
this.lbstatus.Size = new System.Drawing.Size(48, 13);
this.lbstatus.TabIndex = 3;
this.lbstatus.Text = "Grade: 1";
//
// pnlscanner
//
this.pnlscanner.Controls.Add(this.lbscanstatus);
this.pnlscanner.Controls.Add(this.pgscannerprogress);
this.pnlscanner.Controls.Add(this.label2);
this.pnlscanner.Dock = System.Windows.Forms.DockStyle.Fill;
this.pnlscanner.Location = new System.Drawing.Point(0, 0);
this.pnlscanner.Name = "pnlscanner";
this.pnlscanner.Size = new System.Drawing.Size(498, 399);
this.pnlscanner.TabIndex = 2;
//
// label2
//
this.label2.AutoSize = true;
this.label2.Dock = System.Windows.Forms.DockStyle.Top;
this.label2.Location = new System.Drawing.Point(0, 0);
this.label2.Name = "label2";
this.label2.Padding = new System.Windows.Forms.Padding(10);
this.label2.Size = new System.Drawing.Size(81, 33);
this.label2.TabIndex = 0;
this.label2.Tag = "header3";
this.label2.Text = "Scanning...";
//
// lbscanstatus
//
this.lbscanstatus.Dock = System.Windows.Forms.DockStyle.Fill;
this.lbscanstatus.Location = new System.Drawing.Point(0, 33);
this.lbscanstatus.Name = "lbscanstatus";
this.lbscanstatus.Padding = new System.Windows.Forms.Padding(10);
this.lbscanstatus.Size = new System.Drawing.Size(498, 343);
this.lbscanstatus.TabIndex = 2;
this.lbscanstatus.Text = "label1";
//
// pnlsummary
//
this.pnlsummary.Controls.Add(this.flviruses);
this.pnlsummary.Controls.Add(this.label1);
this.pnlsummary.Controls.Add(this.label3);
this.pnlsummary.Dock = System.Windows.Forms.DockStyle.Fill;
this.pnlsummary.Location = new System.Drawing.Point(0, 0);
this.pnlsummary.Name = "pnlsummary";
this.pnlsummary.Size = new System.Drawing.Size(498, 399);
this.pnlsummary.TabIndex = 3;
//
// label3
//
this.label3.AutoSize = true;
this.label3.Dock = System.Windows.Forms.DockStyle.Top;
this.label3.Location = new System.Drawing.Point(0, 0);
this.label3.Name = "label3";
this.label3.Padding = new System.Windows.Forms.Padding(10);
this.label3.Size = new System.Drawing.Size(101, 33);
this.label3.TabIndex = 0;
this.label3.Tag = "header3";
this.label3.Text = "Scan complete.";
//
// label1
//
this.label1.AutoSize = true;
this.label1.Dock = System.Windows.Forms.DockStyle.Top;
this.label1.Location = new System.Drawing.Point(0, 33);
this.label1.Name = "label1";
this.label1.Padding = new System.Windows.Forms.Padding(10);
this.label1.Size = new System.Drawing.Size(184, 33);
this.label1.TabIndex = 2;
this.label1.Text = "Below is a list of all viruses found.";
//
// flviruses
//
this.flviruses.AutoScroll = true;
this.flviruses.Dock = System.Windows.Forms.DockStyle.Fill;
this.flviruses.FlowDirection = System.Windows.Forms.FlowDirection.TopDown;
this.flviruses.Location = new System.Drawing.Point(0, 66);
this.flviruses.Margin = new System.Windows.Forms.Padding(0);
this.flviruses.Name = "flviruses";
this.flviruses.Padding = new System.Windows.Forms.Padding(10);
this.flviruses.Size = new System.Drawing.Size(498, 333);
this.flviruses.TabIndex = 3;
//
// pgscannerprogress
//
this.pgscannerprogress.Dock = System.Windows.Forms.DockStyle.Bottom;
this.pgscannerprogress.Location = new System.Drawing.Point(0, 376);
this.pgscannerprogress.Maximum = 100;
this.pgscannerprogress.Name = "pgscannerprogress";
this.pgscannerprogress.Padding = new System.Windows.Forms.Padding(10);
this.pgscannerprogress.Size = new System.Drawing.Size(498, 23);
this.pgscannerprogress.TabIndex = 1;
this.pgscannerprogress.Text = "shiftedProgressBar1";
this.pgscannerprogress.Value = 0;
//
// VirusScanner
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.lbstatus);
this.Controls.Add(this.pnlbody);
this.Controls.Add(this.btnexit);
this.Controls.Add(this.pnlsidebar);
this.Name = "VirusScanner";
this.Size = new System.Drawing.Size(650, 435);
this.pnlsidebar.ResumeLayout(false);
this.pnlbody.ResumeLayout(false);
this.pnlintro.ResumeLayout(false);
this.pnlintro.PerformLayout();
this.pnlscanner.ResumeLayout(false);
this.pnlscanner.PerformLayout();
this.pnlsummary.ResumeLayout(false);
this.pnlsummary.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.FlowLayoutPanel pnlsidebar;
private System.Windows.Forms.Button btnscanfs;
private System.Windows.Forms.Button btnscanmem;
private System.Windows.Forms.Button btnscanfile;
private System.Windows.Forms.Button btnexit;
private System.Windows.Forms.Panel pnlbody;
private System.Windows.Forms.Panel pnlintro;
private System.Windows.Forms.Label lbintrotext;
private System.Windows.Forms.Label lbintrotitle;
private System.Windows.Forms.Label lbstatus;
private System.Windows.Forms.Panel pnlscanner;
private System.Windows.Forms.Label lbscanstatus;
private Controls.ShiftedProgressBar pgscannerprogress;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Panel pnlsummary;
private System.Windows.Forms.FlowLayoutPanel flviruses;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label3;
}
}

View file

@ -0,0 +1,321 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using ShiftOS.Engine;
using System.Threading;
using Newtonsoft.Json;
namespace ShiftOS.WinForms.Applications
{
[RequiresUpgrade("virus_scanner")]
[WinOpen("virus_scanner")]
[Launcher("Virus Scanner", false, null, "Utilities")]
[DefaultTitle("Virus Scanner")]
public partial class VirusScanner : UserControl, IShiftOSWindow
{
private int grade = 1;
public VirusScanner()
{
InitializeComponent();
}
public void OnLoad()
{
pnlintro.BringToFront();
}
private List<Objects.ViralInfection> FoundViruses = new List<Objects.ViralInfection>();
public void OnSkinLoad()
{
}
public bool OnUnload()
{
return true;
}
public void OnUpgrade()
{
grade = 1;
if (Shiftorium.UpgradeInstalled("virus_scanner_grade_2"))
grade++;
if (Shiftorium.UpgradeInstalled("virus_scanner_grade_3"))
grade++;
if (Shiftorium.UpgradeInstalled("virus_scanner_grade_4"))
grade++;
SetupStatus();
}
public void SetupStatus()
{
lbstatus.Text = $"Grade: {grade}";
}
private string _scanMessage = "We are currently scanning your system. Please wait.";
private int _threatsFound = 0;
public int ThreatsFound
{
get
{
return _threatsFound;
}
set
{
_threatsFound = value;
lbscanstatus.Text = $@"{_scanMessage}
Threats found: {_threatsFound}";
}
}
public string ScannerMessage
{
get
{
return _scanMessage;
}
set
{
_scanMessage = value;
lbscanstatus.Text = $@"{_scanMessage}
Threats found: {_threatsFound}";
}
}
private void btnscanmem_Click(object sender, EventArgs e)
{
ScannerMessage = "We are currently scanning the system memory. Please wait.";
ThreatsFound = 0;
ShowScannerUI();
ScanMemory();
}
public void ScanMemory()
{
pgscannerprogress.Maximum = SaveSystem.CurrentSave.ViralInfections.Count;
var t = new Thread(() =>
{
foreach(var virus in SaveSystem.CurrentSave.ViralInfections)
{
Thread.Sleep(1000);
Desktop.InvokeOnWorkerThread(() =>
{
pgscannerprogress.Value++;
ThreatsFound++;
if(virus.ThreatLevel <= grade)
{
FoundViruses.Add(virus);
}
});
}
Desktop.InvokeOnWorkerThread(() =>
{
SetupSummary();
});
});
t.IsBackground = true;
t.Start();
}
public void SetupSummary()
{
flviruses.Controls.Clear();
if(FoundViruses.Count == 0)
{
var noViruses = new Label();
noViruses.Text = "No threats found.";
noViruses.Tag = "header3";
Tools.ControlManager.SetupControls(noViruses);
noViruses.AutoSize = true;
flviruses.Controls.Add(noViruses);
noViruses.Show();
}
foreach(var virus in FoundViruses)
{
var headerLabel = new Label();
headerLabel.Text = $"virus.th{virus.ThreatLevel}.{virus.ID}";
flviruses.Controls.Add(headerLabel);
headerLabel.Tag = "header3";
headerLabel.MaximumSize = new Size(((flviruses.Width) - flviruses.Padding.Right) - flviruses.Padding.Left, 0);
headerLabel.AutoSize = true;
Tools.ControlManager.SetupControl(headerLabel);
headerLabel.Show();
var descLabel = new Label();
descLabel.MaximumSize = new Size(((flviruses.Width) - flviruses.Padding.Right) - flviruses.Padding.Left, 0);
descLabel.AutoSize = true;
var virusInfo = GetVirusInformation(virus.ID);
descLabel.Text = $@"Real name: {virusInfo.Name}
Description: {virusInfo.Description}";
if(virus is FileViralInfection)
{
descLabel.Text += Environment.NewLine + "File path: " + (virus as FileViralInfection).FilePath;
}
flviruses.Controls.Add(descLabel);
descLabel.Show();
var cleanButton = new Button();
cleanButton.Text = "Disinfect";
cleanButton.AutoSizeMode = AutoSizeMode.GrowAndShrink;
cleanButton.AutoSize = true;
cleanButton.Click += (o, a) =>
{
Disinfect(virus);
};
flviruses.Controls.Add(cleanButton);
Tools.ControlManager.SetupControl(cleanButton);
cleanButton.Show();
}
pnlsummary.BringToFront();
}
public void Disinfect(Objects.ViralInfection virus)
{
if (FoundViruses.Contains(virus))
{
FoundViruses.Remove(virus);
VirusManager.Disinfect(virus.ID);
if(virus is FileViralInfection)
{
var fVirus = virus as FileViralInfection;
if (Objects.ShiftFS.Utils.FileExists(fVirus.FilePath))
{
var headerText = Objects.ShiftFS.Utils.GetHeaderText(fVirus.FilePath);
try
{
var list = JsonConvert.DeserializeObject<List<FileViralInfection>>(headerText);
var hVirus = list.FirstOrDefault(x => x.ID == virus.ID && x.ThreatLevel == virus.ThreatLevel);
list.Remove(hVirus);
Objects.ShiftFS.Utils.SetHeaderText(fVirus.FilePath, JsonConvert.SerializeObject(list));
}
catch
{
}
}
}
}
SetupSummary();
}
public VirusAttribute GetVirusInformation(string id)
{
foreach(var type in ReflectMan.Types.Where(x => x.GetInterfaces().Contains(typeof(IVirus)) && Shiftorium.UpgradeAttributesUnlocked(x)))
{
var attrib = type.GetCustomAttributes(false).FirstOrDefault(x => x is VirusAttribute) as VirusAttribute;
if(attrib != null)
{
if (attrib.ID == id)
return attrib;
}
}
return null;
}
public void ShowScannerUI()
{
pgscannerprogress.Value = 0;
pnlscanner.BringToFront();
}
private int filesScanned = 0;
public void ScanFile(string path)
{
Thread.Sleep(25);
var headerinfo = Objects.ShiftFS.Utils.GetHeaderText(path);
filesScanned++;
Desktop.InvokeOnWorkerThread(() =>
{
ScannerMessage = "Scanning file: " + path + Environment.NewLine + "Files scanned: " + filesScanned.ToString();
});
try
{
var list = JsonConvert.DeserializeObject<List<Objects.ViralInfection>>(headerinfo).Where(x => x.ThreatLevel <= grade);
foreach (var virus in list)
{
Thread.Sleep(50);
Desktop.InvokeOnWorkerThread(() =>
{
ThreatsFound++;
});
FoundViruses.Add(new FileViralInfection
{
ID = virus.ID,
ThreatLevel = virus.ThreatLevel,
FilePath = path
});
}
}
catch { }
}
public void ScanDirectory(string dir)
{
if (Objects.ShiftFS.Utils.DirectoryExists(dir))
{
foreach (var file in Objects.ShiftFS.Utils.GetFiles(dir))
ScanFile(file);
foreach (var subdir in Objects.ShiftFS.Utils.GetDirectories(dir))
ScanDirectory(subdir);
}
}
private void btnscanfile_Click(object sender, EventArgs e)
{
FileSkimmerBackend.GetFile(new[] { "" }, FileOpenerStyle.Open, (path) =>
{
ScanFile(path);
SetupSummary();
});
}
private void btnscanfs_Click(object sender, EventArgs e)
{
filesScanned = 0;
ShowScannerUI();
pgscannerprogress.Hide();
ThreatsFound = 0;
var t = new Thread(() =>
{
foreach(var mount in Objects.ShiftFS.Utils.Mounts)
{
var index = Objects.ShiftFS.Utils.Mounts.IndexOf(mount);
ScanDirectory(index.ToString() + ":");
}
Desktop.InvokeOnWorkerThread(() =>
{
SetupSummary();
});
});
t.Start();
}
private void btnexit_Click(object sender, EventArgs e)
{
AppearanceManager.Close(this);
}
}
public class FileViralInfection : Objects.ViralInfection
{
public string FilePath { get; set; }
}
}

View file

@ -0,0 +1,125 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="lbintrotext.Text" xml:space="preserve">
<value>Virus Scanner is a small utility application that allows you to scan files and the system RAM for viral infections.
To start a scan, click one of the buttons to the left. Wait for the scan to complete, and then we'll list any threats we find. If we find a threat, you can click "Disinfect" to remove the virus from your system.</value>
</data>
</root>

View file

@ -1,4 +1,26 @@
[
//Virus Scanner Grades
{
Name: "Virus Scanner Grade 2",
Description: "Update the Virus Scanner database to include threatlevel 2 viruses.",
Dependencies: "virus_scanner",
Category: "Virus Scanner",
Cost: 75
},
{
Name: "Virus Scanner Grade 3",
Description: "Update the Virus Scanner database to include threatlevel 3 viruses.",
Dependencies: "virus_scanner_grade_2",
Category: "Virus Scanner",
Cost: 150
},
{
Name: "Virus Scanner Grade 4",
Description: "Update the Virus Scanner database to include threatlevel 4 viruses.",
Dependencies: "virus_scanner_grade_3",
Category: "Virus Scanner",
Cost: 225
},
// SCREENSAVER
{
Name: "Screensavers",

View file

@ -281,6 +281,12 @@
<Compile Include="Applications\VideoPlayer.Designer.cs">
<DependentUpon>VideoPlayer.cs</DependentUpon>
</Compile>
<Compile Include="Applications\VirusScanner.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Applications\VirusScanner.Designer.cs">
<DependentUpon>VirusScanner.cs</DependentUpon>
</Compile>
<Compile Include="Applications\WebBrowser.cs">
<SubType>UserControl</SubType>
</Compile>
@ -604,6 +610,9 @@
<EmbeddedResource Include="Applications\VideoPlayer.resx">
<DependentUpon>VideoPlayer.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Applications\VirusScanner.resx">
<DependentUpon>VirusScanner.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Applications\WebBrowser.resx">
<DependentUpon>WebBrowser.cs</DependentUpon>
</EmbeddedResource>

View file

@ -20,6 +20,14 @@ namespace ShiftOS.WinForms
VirusManager.Infect(id, threatlevel);
}
[Command("disinfect", description = "DEBUG: Disinfect the system, removing the specified virus.")]
[RequiresArgument("id")]
public static void Disinfect(Dictionary<string, object> args)
{
var id = args["id"].ToString();
VirusManager.Disinfect(id);
}
}
#endif
}

View file

@ -96,5 +96,25 @@ namespace ShiftOS.Engine
throw new Exception("Cannot create virus.");
}
public static void Disinfect(string id)
{
foreach(var virus in ActiveInfections.ToArray())
{
var type = virus.GetType();
var attrib = type.GetCustomAttributes(false).FirstOrDefault(x => x is VirusAttribute) as VirusAttribute;
if(attrib != null)
{
if (attrib.ID == id)
{
ActiveInfections.Remove(virus);
var inf = SaveSystem.CurrentSave.ViralInfections.FirstOrDefault(x => x.ID == id);
if (inf != null)
SaveSystem.CurrentSave.ViralInfections.Remove(inf);
virus.Disinfect();
}
}
}
}
}
}