Move to file scoped namespace.

This commit is contained in:
2021-12-08 17:57:50 +00:00
parent 0454e72151
commit 5a1b6978f5
93 changed files with 12127 additions and 12218 deletions

View File

@@ -40,122 +40,76 @@ using Aaru.Server.Models;
using HtmlAgilityPack;
using Microsoft.EntityFrameworkCore;
namespace Aaru.Server.Task
{
internal class Program
{
public static void Main(string[] args)
{
DateTime start, end;
namespace Aaru.Server.Task;
start = DateTime.UtcNow;
System.Console.WriteLine("{0}: Connecting to database...", DateTime.UtcNow);
var ctx = new AaruServerContext();
internal class Program
{
public static void Main(string[] args)
{
DateTime start, end;
start = DateTime.UtcNow;
System.Console.WriteLine("{0}: Connecting to database...", DateTime.UtcNow);
var ctx = new AaruServerContext();
end = DateTime.UtcNow;
System.Console.WriteLine("{0}: Took {1:F2} seconds", end, (end - start).TotalSeconds);
System.Console.WriteLine("{0}: Migrating database to latest version...", DateTime.UtcNow);
start = DateTime.UtcNow;
ctx.Database.Migrate();
end = DateTime.UtcNow;
System.Console.WriteLine("{0}: Took {1:F2} seconds", DateTime.UtcNow, (end - start).TotalSeconds);
WebClient client;
try
{
System.Console.WriteLine("{0}: Retrieving USB IDs from Linux USB...", DateTime.UtcNow);
start = DateTime.UtcNow;
client = new WebClient();
var sr = new StringReader(client.DownloadString("http://www.linux-usb.org/usb.ids"));
end = DateTime.UtcNow;
System.Console.WriteLine("{0}: Took {1:F2} seconds", end, (end - start).TotalSeconds);
System.Console.WriteLine("{0}: Migrating database to latest version...", DateTime.UtcNow);
UsbVendor vendor = null;
int newVendors = 0;
int newProducts = 0;
int modifiedVendors = 0;
int modifiedProducts = 0;
int counter = 0;
start = DateTime.UtcNow;
ctx.Database.Migrate();
end = DateTime.UtcNow;
System.Console.WriteLine("{0}: Took {1:F2} seconds", DateTime.UtcNow, (end - start).TotalSeconds);
System.Console.WriteLine("{0}: Adding and updating database entries...", DateTime.UtcNow);
WebClient client;
try
do
{
System.Console.WriteLine("{0}: Retrieving USB IDs from Linux USB...", DateTime.UtcNow);
start = DateTime.UtcNow;
client = new WebClient();
var sr = new StringReader(client.DownloadString("http://www.linux-usb.org/usb.ids"));
end = DateTime.UtcNow;
System.Console.WriteLine("{0}: Took {1:F2} seconds", end, (end - start).TotalSeconds);
UsbVendor vendor = null;
int newVendors = 0;
int newProducts = 0;
int modifiedVendors = 0;
int modifiedProducts = 0;
int counter = 0;
start = DateTime.UtcNow;
System.Console.WriteLine("{0}: Adding and updating database entries...", DateTime.UtcNow);
do
if(counter == 1000)
{
if(counter == 1000)
{
DateTime start2 = DateTime.UtcNow;
System.Console.WriteLine("{0}: Saving changes", start2);
ctx.SaveChanges();
end = DateTime.UtcNow;
System.Console.WriteLine("{0}: Took {1:F2} seconds", end, (end - start2).TotalSeconds);
counter = 0;
}
DateTime start2 = DateTime.UtcNow;
System.Console.WriteLine("{0}: Saving changes", start2);
ctx.SaveChanges();
end = DateTime.UtcNow;
System.Console.WriteLine("{0}: Took {1:F2} seconds", end, (end - start2).TotalSeconds);
counter = 0;
}
string line = sr.ReadLine();
string line = sr.ReadLine();
if(line is null)
break;
if(line is null)
break;
if(line.Length == 0 ||
line[0] == '#')
continue;
if(line.Length == 0 ||
line[0] == '#')
continue;
ushort number;
string name;
if(line[0] == '\t')
{
try
{
number = Convert.ToUInt16(line.Substring(1, 4), 16);
}
catch(FormatException)
{
continue;
}
if(number == 0)
continue;
name = line.Substring(7);
UsbProduct product =
ctx.UsbProducts.FirstOrDefault(p => p.ProductId == number && p.Vendor != null &&
p.Vendor.VendorId == vendor.VendorId);
if(product is null)
{
product = new UsbProduct(vendor, number, name);
ctx.UsbProducts.Add(product);
System.Console.WriteLine("{0}: Will add product {1} with ID {2:X4} and vendor {3} ({4:X4})",
DateTime.UtcNow, product.Product, product.ProductId,
product.Vendor?.Vendor ?? "null", product.Vendor?.VendorId ?? 0);
newProducts++;
counter++;
}
else if(name != product.Product)
{
System.Console.
WriteLine("{0}: Will modify product with ID {1:X4} and vendor {2} ({3:X4}) from \"{4}\" to \"{5}\"",
DateTime.UtcNow, product.ProductId, product.Vendor?.Vendor ?? "null",
product.Vendor?.VendorId ?? 0, product.Product, name);
product.Product = name;
product.ModifiedWhen = DateTime.UtcNow;
modifiedProducts++;
counter++;
}
continue;
}
ushort number;
string name;
if(line[0] == '\t')
{
try
{
number = Convert.ToUInt16(line.Substring(0, 4), 16);
number = Convert.ToUInt16(line.Substring(1, 4), 16);
}
catch(FormatException)
{
@@ -165,378 +119,423 @@ namespace Aaru.Server.Task
if(number == 0)
continue;
name = line.Substring(6);
name = line.Substring(7);
vendor = ctx.UsbVendors.FirstOrDefault(v => v.VendorId == number);
UsbProduct product =
ctx.UsbProducts.FirstOrDefault(p => p.ProductId == number && p.Vendor != null &&
p.Vendor.VendorId == vendor.VendorId);
if(vendor is null)
if(product is null)
{
vendor = new UsbVendor(number, name);
ctx.UsbVendors.Add(vendor);
product = new UsbProduct(vendor, number, name);
ctx.UsbProducts.Add(product);
System.Console.WriteLine("{0}: Will add vendor {1} with ID {2:X4}", DateTime.UtcNow,
vendor.Vendor, vendor.VendorId);
System.Console.WriteLine("{0}: Will add product {1} with ID {2:X4} and vendor {3} ({4:X4})",
DateTime.UtcNow, product.Product, product.ProductId,
product.Vendor?.Vendor ?? "null", product.Vendor?.VendorId ?? 0);
newVendors++;
newProducts++;
counter++;
}
else if(name != vendor.Vendor)
else if(name != product.Product)
{
System.Console.WriteLine("{0}: Will modify vendor with ID {1:X4} from \"{2}\" to \"{3}\"",
DateTime.UtcNow, vendor.VendorId, vendor.Vendor, name);
System.Console.
WriteLine("{0}: Will modify product with ID {1:X4} and vendor {2} ({3:X4}) from \"{4}\" to \"{5}\"",
DateTime.UtcNow, product.ProductId, product.Vendor?.Vendor ?? "null",
product.Vendor?.VendorId ?? 0, product.Product, name);
vendor.Vendor = name;
vendor.ModifiedWhen = DateTime.UtcNow;
modifiedVendors++;
product.Product = name;
product.ModifiedWhen = DateTime.UtcNow;
modifiedProducts++;
counter++;
}
} while(true);
end = DateTime.UtcNow;
System.Console.WriteLine("{0}: Took {1:F2} seconds", end, (end - start).TotalSeconds);
continue;
}
System.Console.WriteLine("{0}: Saving database changes...", DateTime.UtcNow);
start = DateTime.UtcNow;
ctx.SaveChanges();
end = DateTime.UtcNow;
System.Console.WriteLine("{0}: Took {1:F2} seconds", end, (end - start).TotalSeconds);
try
{
number = Convert.ToUInt16(line.Substring(0, 4), 16);
}
catch(FormatException)
{
continue;
}
System.Console.WriteLine("{0}: {1} vendors added.", DateTime.UtcNow, newVendors);
System.Console.WriteLine("{0}: {1} products added.", DateTime.UtcNow, newProducts);
System.Console.WriteLine("{0}: {1} vendors modified.", DateTime.UtcNow, modifiedVendors);
System.Console.WriteLine("{0}: {1} products modified.", DateTime.UtcNow, modifiedProducts);
if(number == 0)
continue;
System.Console.WriteLine("{0}: Looking up a vendor", DateTime.UtcNow);
start = DateTime.UtcNow;
vendor = ctx.UsbVendors.FirstOrDefault(v => v.VendorId == 0x8086);
name = line.Substring(6);
vendor = ctx.UsbVendors.FirstOrDefault(v => v.VendorId == number);
if(vendor is null)
System.Console.WriteLine("{0}: Error, could not find vendor.", DateTime.UtcNow);
else
System.Console.WriteLine("{0}: Found {1}.", DateTime.UtcNow, vendor.Vendor);
{
vendor = new UsbVendor(number, name);
ctx.UsbVendors.Add(vendor);
end = DateTime.UtcNow;
System.Console.WriteLine("{0}: Took {1:F2} seconds", end, (end - start).TotalSeconds);
System.Console.WriteLine("{0}: Will add vendor {1} with ID {2:X4}", DateTime.UtcNow,
vendor.Vendor, vendor.VendorId);
System.Console.WriteLine("{0}: Looking up a product", DateTime.UtcNow);
start = DateTime.UtcNow;
newVendors++;
counter++;
}
else if(name != vendor.Vendor)
{
System.Console.WriteLine("{0}: Will modify vendor with ID {1:X4} from \"{2}\" to \"{3}\"",
DateTime.UtcNow, vendor.VendorId, vendor.Vendor, name);
UsbProduct prd =
ctx.UsbProducts.FirstOrDefault(p => p.ProductId == 0x0001 && p.Vendor.VendorId == 0x8086);
if(prd is null)
System.Console.WriteLine("{0}: Error, could not find product.", DateTime.UtcNow);
else
System.Console.WriteLine("{0}: Found {1}.", DateTime.UtcNow, prd.Product);
end = DateTime.UtcNow;
System.Console.WriteLine("{0}: Took {1:F2} seconds", end, (end - start).TotalSeconds);
}
catch(Exception ex)
{
#if DEBUG
if(Debugger.IsAttached)
throw;
#endif
System.Console.WriteLine("{0}: Exception {1} filling USB IDs...", DateTime.UtcNow, ex);
}
System.Console.WriteLine("{0}: Fixing all devices without modification time...", DateTime.UtcNow);
start = DateTime.UtcNow;
foreach(Device device in ctx.Devices.Where(d => d.ModifiedWhen == null))
device.ModifiedWhen = device.AddedWhen;
vendor.Vendor = name;
vendor.ModifiedWhen = DateTime.UtcNow;
modifiedVendors++;
counter++;
}
} while(true);
end = DateTime.UtcNow;
System.Console.WriteLine("{0}: Took {1:F2} seconds", end, (end - start).TotalSeconds);
System.Console.WriteLine("{0}: Saving database changes...", DateTime.UtcNow);
start = DateTime.UtcNow;
ctx.SaveChanges();
end = DateTime.UtcNow;
System.Console.WriteLine("{0}: Took {1:F2} seconds", end, (end - start).TotalSeconds);
System.Console.WriteLine("{0}: {1} vendors added.", DateTime.UtcNow, newVendors);
System.Console.WriteLine("{0}: {1} products added.", DateTime.UtcNow, newProducts);
System.Console.WriteLine("{0}: {1} vendors modified.", DateTime.UtcNow, modifiedVendors);
System.Console.WriteLine("{0}: {1} products modified.", DateTime.UtcNow, modifiedProducts);
System.Console.WriteLine("{0}: Looking up a vendor", DateTime.UtcNow);
start = DateTime.UtcNow;
vendor = ctx.UsbVendors.FirstOrDefault(v => v.VendorId == 0x8086);
if(vendor is null)
System.Console.WriteLine("{0}: Error, could not find vendor.", DateTime.UtcNow);
else
System.Console.WriteLine("{0}: Found {1}.", DateTime.UtcNow, vendor.Vendor);
end = DateTime.UtcNow;
System.Console.WriteLine("{0}: Took {1:F2} seconds", end, (end - start).TotalSeconds);
System.Console.WriteLine("{0}: Looking up a product", DateTime.UtcNow);
start = DateTime.UtcNow;
UsbProduct prd =
ctx.UsbProducts.FirstOrDefault(p => p.ProductId == 0x0001 && p.Vendor.VendorId == 0x8086);
if(prd is null)
System.Console.WriteLine("{0}: Error, could not find product.", DateTime.UtcNow);
else
System.Console.WriteLine("{0}: Found {1}.", DateTime.UtcNow, prd.Product);
end = DateTime.UtcNow;
System.Console.WriteLine("{0}: Took {1:F2} seconds", end, (end - start).TotalSeconds);
}
catch(Exception ex)
{
#if DEBUG
if(Debugger.IsAttached)
throw;
#endif
System.Console.WriteLine("{0}: Exception {1} filling USB IDs...", DateTime.UtcNow, ex);
}
System.Console.WriteLine("{0}: Fixing all devices without modification time...", DateTime.UtcNow);
start = DateTime.UtcNow;
foreach(Device device in ctx.Devices.Where(d => d.ModifiedWhen == null))
device.ModifiedWhen = device.AddedWhen;
end = DateTime.UtcNow;
System.Console.WriteLine("{0}: Took {1:F2} seconds", end, (end - start).TotalSeconds);
System.Console.WriteLine("{0}: Committing changes...", DateTime.UtcNow);
start = DateTime.UtcNow;
ctx.SaveChanges();
end = DateTime.UtcNow;
System.Console.WriteLine("{0}: Took {1:F2} seconds", end, (end - start).TotalSeconds);
try
{
System.Console.WriteLine("{0}: Retrieving CompactDisc read offsets from AccurateRip...",
DateTime.UtcNow);
start = DateTime.UtcNow;
client = new WebClient();
string html = client.DownloadString("http://www.accuraterip.com/driveoffsets.htm");
end = DateTime.UtcNow;
System.Console.WriteLine("{0}: Took {1:F2} seconds", end, (end - start).TotalSeconds);
// The HTML is too malformed to process easily, so find start of table
html = "<html><body><table><tr>" +
html.Substring(html.IndexOf("<td bgcolor=\"#000000\">", StringComparison.Ordinal));
var doc = new HtmlDocument();
doc.LoadHtml(html);
HtmlNode firstTable = doc.DocumentNode.SelectSingleNode("/html[1]/body[1]/table[1]");
bool firstRow = true;
int addedOffsets = 0;
int modifiedOffsets = 0;
System.Console.WriteLine("{0}: Processing offsets...", DateTime.UtcNow);
start = DateTime.UtcNow;
foreach(HtmlNode row in firstTable.Descendants("tr"))
{
HtmlNode[] columns = row.Descendants("td").ToArray();
if(columns.Length != 4)
{
System.Console.WriteLine("{0}: Row does not have correct number of columns...",
DateTime.UtcNow);
continue;
}
string column0 = columns[0].InnerText;
string column1 = columns[1].InnerText;
string column2 = columns[2].InnerText;
string column3 = columns[3].InnerText;
if(firstRow)
{
if(column0.ToLowerInvariant() != "cd drive")
{
System.Console.WriteLine("{0}: Unexpected header \"{1}\" found...", DateTime.UtcNow,
columns[0].InnerText);
break;
}
if(column1.ToLowerInvariant() != "correction offset")
{
System.Console.WriteLine("{0}: Unexpected header \"{1}\" found...", DateTime.UtcNow,
columns[1].InnerText);
break;
}
if(column2.ToLowerInvariant() != "submitted by")
{
System.Console.WriteLine("{0}: Unexpected header \"{1}\" found...", DateTime.UtcNow,
columns[2].InnerText);
break;
}
if(column3.ToLowerInvariant() != "percentage agree")
{
System.Console.WriteLine("{0}: Unexpected header \"{1}\" found...", DateTime.UtcNow,
columns[3].InnerText);
break;
}
firstRow = false;
continue;
}
string manufacturer;
string model;
if(column0[0] == '-' &&
column0[1] == ' ')
{
manufacturer = null;
model = column0.Substring(2).Trim();
}
else
{
int cutOffset = column0.IndexOf(" - ", StringComparison.Ordinal);
if(cutOffset == -1)
{
manufacturer = null;
model = column0;
}
else
{
manufacturer = column0.Substring(0, cutOffset).Trim();
model = column0.Substring(cutOffset + 3).Trim();
}
}
switch(manufacturer)
{
case "Lite-ON":
manufacturer = "JLMS";
break;
case "LG Electronics":
manufacturer = "HL-DT-ST";
break;
case "Panasonic":
manufacturer = "MATSHITA";
break;
}
CompactDiscOffset cdOffset =
ctx.CdOffsets.FirstOrDefault(o => o.Manufacturer == manufacturer && o.Model == model);
if(column1.ToLowerInvariant() == "[purged]")
{
if(cdOffset != null)
ctx.CdOffsets.Remove(cdOffset);
continue;
}
if(!short.TryParse(column1, out short offset))
continue;
if(!int.TryParse(column2, out int submissions))
continue;
if(column3[^1] != '%')
continue;
column3 = column3.Substring(0, column3.Length - 1);
if(!float.TryParse(column3, out float percentage))
continue;
percentage /= 100;
if(cdOffset is null)
{
cdOffset = new CompactDiscOffset
{
AddedWhen = DateTime.UtcNow,
ModifiedWhen = DateTime.UtcNow,
Agreement = percentage,
Manufacturer = manufacturer,
Model = model,
Offset = offset,
Submissions = submissions
};
ctx.CdOffsets.Add(cdOffset);
addedOffsets++;
}
else
{
if(Math.Abs(cdOffset.Agreement - percentage) > 0)
{
cdOffset.Agreement = percentage;
cdOffset.ModifiedWhen = DateTime.UtcNow;
}
if(cdOffset.Offset != offset)
{
cdOffset.Offset = offset;
cdOffset.ModifiedWhen = DateTime.UtcNow;
}
if(cdOffset.Submissions != submissions)
{
cdOffset.Submissions = submissions;
cdOffset.ModifiedWhen = DateTime.UtcNow;
}
if(Math.Abs(cdOffset.Agreement - percentage) > 0 ||
cdOffset.Offset != offset ||
cdOffset.Submissions != submissions)
modifiedOffsets++;
}
foreach(Device device in ctx.Devices.
Where(d => d.Manufacturer == null && d.Model != null &&
d.Model.Trim() == model).
Union(ctx.Devices.Where(d => d.Manufacturer != null &&
d.Manufacturer.Trim() == manufacturer &&
d.Model != null && d.Model == model)))
{
if(device.CdOffset == cdOffset &&
device.ModifiedWhen == cdOffset.ModifiedWhen)
continue;
device.CdOffset = cdOffset;
device.ModifiedWhen = cdOffset.ModifiedWhen;
}
}
end = DateTime.UtcNow;
System.Console.WriteLine("{0}: Took {1:F2} seconds", end, (end - start).TotalSeconds);
if(File.Exists("drive_offsets.json"))
{
var sr = new StreamReader("drive_offsets.json");
CompactDiscOffset[] offsets = JsonSerializer.Deserialize<CompactDiscOffset[]>(sr.ReadToEnd());
if(offsets != null)
{
foreach(CompactDiscOffset offset in offsets)
{
CompactDiscOffset cdOffset =
ctx.CdOffsets.FirstOrDefault(o => o.Manufacturer == offset.Manufacturer &&
o.Model == offset.Model);
if(cdOffset is null)
{
offset.ModifiedWhen = DateTime.UtcNow;
ctx.CdOffsets.Add(offset);
addedOffsets++;
}
else
{
if(Math.Abs(cdOffset.Agreement - offset.Agreement) > 0 ||
offset.Agreement < 0)
{
cdOffset.Agreement = offset.Agreement;
cdOffset.ModifiedWhen = DateTime.UtcNow;
}
if(cdOffset.Offset != offset.Offset)
{
cdOffset.Offset = offset.Offset;
cdOffset.ModifiedWhen = DateTime.UtcNow;
}
if(cdOffset.Submissions != offset.Submissions)
{
cdOffset.Submissions = offset.Submissions;
cdOffset.ModifiedWhen = DateTime.UtcNow;
}
if(Math.Abs(cdOffset.Agreement - offset.Agreement) > 0 ||
cdOffset.Offset != offset.Offset ||
cdOffset.Submissions != offset.Submissions)
modifiedOffsets++;
}
}
}
}
System.Console.WriteLine("{0}: Committing changes...", DateTime.UtcNow);
start = DateTime.UtcNow;
ctx.SaveChanges();
end = DateTime.UtcNow;
System.Console.WriteLine("{0}: Took {1:F2} seconds", end, (end - start).TotalSeconds);
try
{
System.Console.WriteLine("{0}: Retrieving CompactDisc read offsets from AccurateRip...",
DateTime.UtcNow);
start = DateTime.UtcNow;
client = new WebClient();
string html = client.DownloadString("http://www.accuraterip.com/driveoffsets.htm");
end = DateTime.UtcNow;
System.Console.WriteLine("{0}: Took {1:F2} seconds", end, (end - start).TotalSeconds);
// The HTML is too malformed to process easily, so find start of table
html = "<html><body><table><tr>" +
html.Substring(html.IndexOf("<td bgcolor=\"#000000\">", StringComparison.Ordinal));
var doc = new HtmlDocument();
doc.LoadHtml(html);
HtmlNode firstTable = doc.DocumentNode.SelectSingleNode("/html[1]/body[1]/table[1]");
bool firstRow = true;
int addedOffsets = 0;
int modifiedOffsets = 0;
System.Console.WriteLine("{0}: Processing offsets...", DateTime.UtcNow);
start = DateTime.UtcNow;
foreach(HtmlNode row in firstTable.Descendants("tr"))
{
HtmlNode[] columns = row.Descendants("td").ToArray();
if(columns.Length != 4)
{
System.Console.WriteLine("{0}: Row does not have correct number of columns...",
DateTime.UtcNow);
continue;
}
string column0 = columns[0].InnerText;
string column1 = columns[1].InnerText;
string column2 = columns[2].InnerText;
string column3 = columns[3].InnerText;
if(firstRow)
{
if(column0.ToLowerInvariant() != "cd drive")
{
System.Console.WriteLine("{0}: Unexpected header \"{1}\" found...", DateTime.UtcNow,
columns[0].InnerText);
break;
}
if(column1.ToLowerInvariant() != "correction offset")
{
System.Console.WriteLine("{0}: Unexpected header \"{1}\" found...", DateTime.UtcNow,
columns[1].InnerText);
break;
}
if(column2.ToLowerInvariant() != "submitted by")
{
System.Console.WriteLine("{0}: Unexpected header \"{1}\" found...", DateTime.UtcNow,
columns[2].InnerText);
break;
}
if(column3.ToLowerInvariant() != "percentage agree")
{
System.Console.WriteLine("{0}: Unexpected header \"{1}\" found...", DateTime.UtcNow,
columns[3].InnerText);
break;
}
firstRow = false;
continue;
}
string manufacturer;
string model;
if(column0[0] == '-' &&
column0[1] == ' ')
{
manufacturer = null;
model = column0.Substring(2).Trim();
}
else
{
int cutOffset = column0.IndexOf(" - ", StringComparison.Ordinal);
if(cutOffset == -1)
{
manufacturer = null;
model = column0;
}
else
{
manufacturer = column0.Substring(0, cutOffset).Trim();
model = column0.Substring(cutOffset + 3).Trim();
}
}
switch(manufacturer)
{
case "Lite-ON":
manufacturer = "JLMS";
break;
case "LG Electronics":
manufacturer = "HL-DT-ST";
break;
case "Panasonic":
manufacturer = "MATSHITA";
break;
}
CompactDiscOffset cdOffset =
ctx.CdOffsets.FirstOrDefault(o => o.Manufacturer == manufacturer && o.Model == model);
if(column1.ToLowerInvariant() == "[purged]")
{
if(cdOffset != null)
ctx.CdOffsets.Remove(cdOffset);
continue;
}
if(!short.TryParse(column1, out short offset))
continue;
if(!int.TryParse(column2, out int submissions))
continue;
if(column3[^1] != '%')
continue;
column3 = column3.Substring(0, column3.Length - 1);
if(!float.TryParse(column3, out float percentage))
continue;
percentage /= 100;
if(cdOffset is null)
{
cdOffset = new CompactDiscOffset
{
AddedWhen = DateTime.UtcNow,
ModifiedWhen = DateTime.UtcNow,
Agreement = percentage,
Manufacturer = manufacturer,
Model = model,
Offset = offset,
Submissions = submissions
};
ctx.CdOffsets.Add(cdOffset);
addedOffsets++;
}
else
{
if(Math.Abs(cdOffset.Agreement - percentage) > 0)
{
cdOffset.Agreement = percentage;
cdOffset.ModifiedWhen = DateTime.UtcNow;
}
if(cdOffset.Offset != offset)
{
cdOffset.Offset = offset;
cdOffset.ModifiedWhen = DateTime.UtcNow;
}
if(cdOffset.Submissions != submissions)
{
cdOffset.Submissions = submissions;
cdOffset.ModifiedWhen = DateTime.UtcNow;
}
if(Math.Abs(cdOffset.Agreement - percentage) > 0 ||
cdOffset.Offset != offset ||
cdOffset.Submissions != submissions)
modifiedOffsets++;
}
foreach(Device device in ctx.Devices.
Where(d => d.Manufacturer == null && d.Model != null &&
d.Model.Trim() == model).
Union(ctx.Devices.Where(d => d.Manufacturer != null &&
d.Manufacturer.Trim() == manufacturer &&
d.Model != null && d.Model == model)))
{
if(device.CdOffset == cdOffset &&
device.ModifiedWhen == cdOffset.ModifiedWhen)
continue;
device.CdOffset = cdOffset;
device.ModifiedWhen = cdOffset.ModifiedWhen;
}
}
end = DateTime.UtcNow;
System.Console.WriteLine("{0}: Took {1:F2} seconds", end, (end - start).TotalSeconds);
if(File.Exists("drive_offsets.json"))
{
var sr = new StreamReader("drive_offsets.json");
CompactDiscOffset[] offsets = JsonSerializer.Deserialize<CompactDiscOffset[]>(sr.ReadToEnd());
if(offsets != null)
{
foreach(CompactDiscOffset offset in offsets)
{
CompactDiscOffset cdOffset =
ctx.CdOffsets.FirstOrDefault(o => o.Manufacturer == offset.Manufacturer &&
o.Model == offset.Model);
if(cdOffset is null)
{
offset.ModifiedWhen = DateTime.UtcNow;
ctx.CdOffsets.Add(offset);
addedOffsets++;
}
else
{
if(Math.Abs(cdOffset.Agreement - offset.Agreement) > 0 ||
offset.Agreement < 0)
{
cdOffset.Agreement = offset.Agreement;
cdOffset.ModifiedWhen = DateTime.UtcNow;
}
if(cdOffset.Offset != offset.Offset)
{
cdOffset.Offset = offset.Offset;
cdOffset.ModifiedWhen = DateTime.UtcNow;
}
if(cdOffset.Submissions != offset.Submissions)
{
cdOffset.Submissions = offset.Submissions;
cdOffset.ModifiedWhen = DateTime.UtcNow;
}
if(Math.Abs(cdOffset.Agreement - offset.Agreement) > 0 ||
cdOffset.Offset != offset.Offset ||
cdOffset.Submissions != offset.Submissions)
modifiedOffsets++;
}
}
}
}
System.Console.WriteLine("{0}: Committing changes...", DateTime.UtcNow);
start = DateTime.UtcNow;
ctx.SaveChanges();
end = DateTime.UtcNow;
System.Console.WriteLine("{0}: Took {1:F2} seconds", end, (end - start).TotalSeconds);
System.Console.WriteLine("{0}: Added {1} offsets", end, addedOffsets);
System.Console.WriteLine("{0}: Modified {1} offsets", end, modifiedOffsets);
}
catch(Exception ex)
{
#if DEBUG
if(Debugger.IsAttached)
throw;
#endif
System.Console.WriteLine("{0}: Exception {1} filling CompactDisc read offsets...", DateTime.UtcNow, ex);
}
System.Console.WriteLine("{0}: Added {1} offsets", end, addedOffsets);
System.Console.WriteLine("{0}: Modified {1} offsets", end, modifiedOffsets);
}
catch(Exception ex)
{
#if DEBUG
if(Debugger.IsAttached)
throw;
#endif
System.Console.WriteLine("{0}: Exception {1} filling CompactDisc read offsets...", DateTime.UtcNow, ex);
}
}
}

View File

@@ -13,436 +13,496 @@ using Newtonsoft.Json;
using Ata = Aaru.CommonTypes.Metadata.Ata;
using TestedMedia = Aaru.CommonTypes.Metadata.TestedMedia;
namespace Aaru.Server.Areas.Admin.Controllers
namespace Aaru.Server.Areas.Admin.Controllers;
[Area("Admin"), Authorize]
public sealed class AtasController : Controller
{
[Area("Admin"), Authorize]
public sealed class AtasController : Controller
readonly AaruServerContext _context;
public AtasController(AaruServerContext context) => _context = context;
// GET: Admin/Atas
public IActionResult Index() => View(_context.Ata.AsEnumerable().OrderBy(m => m.IdentifyDevice?.Model).
ThenBy(m => m.IdentifyDevice?.FirmwareRevision));
// GET: Admin/Atas/Details/5
public async Task<IActionResult> Details(int? id)
{
readonly AaruServerContext _context;
public AtasController(AaruServerContext context) => _context = context;
// GET: Admin/Atas
public IActionResult Index() => View(_context.Ata.AsEnumerable().OrderBy(m => m.IdentifyDevice?.Model).
ThenBy(m => m.IdentifyDevice?.FirmwareRevision));
// GET: Admin/Atas/Details/5
public async Task<IActionResult> Details(int? id)
if(id == null)
{
if(id == null)
{
return NotFound();
}
Ata ata = await _context.Ata.FirstOrDefaultAsync(m => m.Id == id);
if(ata == null)
{
return NotFound();
}
return View(ata);
return NotFound();
}
// GET: Admin/Atas/Delete/5
public async Task<IActionResult> Delete(int? id)
Ata ata = await _context.Ata.FirstOrDefaultAsync(m => m.Id == id);
if(ata == null)
{
if(id == null)
{
return NotFound();
}
Ata ata = await _context.Ata.FirstOrDefaultAsync(m => m.Id == id);
if(ata == null)
{
return NotFound();
}
return View(ata);
return NotFound();
}
// POST: Admin/Atas/Delete/5
[HttpPost, ActionName("Delete"), ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
Ata ata = await _context.Ata.FindAsync(id);
_context.Ata.Remove(ata);
await _context.SaveChangesAsync();
return View(ata);
}
return RedirectToAction(nameof(Index));
// GET: Admin/Atas/Delete/5
public async Task<IActionResult> Delete(int? id)
{
if(id == null)
{
return NotFound();
}
public IActionResult Consolidate()
Ata ata = await _context.Ata.FirstOrDefaultAsync(m => m.Id == id);
if(ata == null)
{
List<IdHashModel> hashes = _context.Ata.Select(m => new IdHashModel(m.Id, Hash.Sha512(m.Identify))).
ToList();
List<IdHashModel> dups = hashes.GroupBy(x => x.Hash).Where(g => g.Count() > 1).
Select(x => hashes.FirstOrDefault(y => y.Hash == x.Key)).ToList();
for(int i = 0; i < dups.Count; i++)
{
Ata unique = _context.Ata.First(a => a.Id == dups[i].Id);
dups[i].Description = unique.IdentifyDevice?.Model;
dups[i].Duplicates = hashes.Where(h => h.Hash == dups[i].Hash).Skip(1).Select(x => x.Id).ToArray();
}
return View(new IdHashModelForView
{
List = dups,
Json = JsonConvert.SerializeObject(dups)
});
return NotFound();
}
[HttpPost, ActionName("Consolidate"), ValidateAntiForgeryToken]
public IActionResult ConsolidateConfirmed(string models)
return View(ata);
}
// POST: Admin/Atas/Delete/5
[HttpPost, ActionName("Delete"), ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
Ata ata = await _context.Ata.FindAsync(id);
_context.Ata.Remove(ata);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
public IActionResult Consolidate()
{
List<IdHashModel> hashes = _context.Ata.Select(m => new IdHashModel(m.Id, Hash.Sha512(m.Identify))).
ToList();
List<IdHashModel> dups = hashes.GroupBy(x => x.Hash).Where(g => g.Count() > 1).
Select(x => hashes.FirstOrDefault(y => y.Hash == x.Key)).ToList();
for(int i = 0; i < dups.Count; i++)
{
IdHashModel[] duplicates;
Ata unique = _context.Ata.First(a => a.Id == dups[i].Id);
try
{
duplicates = JsonConvert.DeserializeObject<IdHashModel[]>(models);
}
catch(JsonSerializationException)
{
return BadRequest();
}
if(duplicates is null)
return BadRequest();
foreach(IdHashModel duplicate in duplicates)
{
Ata master = _context.Ata.FirstOrDefault(m => m.Id == duplicate.Id);
if(master is null)
continue;
foreach(int duplicateId in duplicate.Duplicates)
{
Ata slave = _context.Ata.FirstOrDefault(m => m.Id == duplicateId);
if(slave is null)
continue;
foreach(Device ataDevice in _context.Devices.Where(d => d.ATA.Id == duplicateId))
{
ataDevice.ATA = master;
}
foreach(Device atapiDevice in _context.Devices.Where(d => d.ATAPI.Id == duplicateId))
{
atapiDevice.ATAPI = master;
}
foreach(UploadedReport ataReport in _context.Reports.Where(d => d.ATA.Id == duplicateId))
{
ataReport.ATA = master;
}
foreach(UploadedReport atapiReport in _context.Reports.Where(d => d.ATAPI.Id == duplicateId))
{
atapiReport.ATAPI = master;
}
foreach(TestedMedia testedMedia in _context.TestedMedia.Where(d => d.AtaId == duplicateId))
{
testedMedia.AtaId = duplicate.Id;
_context.Update(testedMedia);
}
if(master.ReadCapabilities is null &&
slave.ReadCapabilities != null)
master.ReadCapabilities = slave.ReadCapabilities;
_context.Ata.Remove(slave);
}
}
_context.SaveChanges();
return RedirectToAction(nameof(Index));
dups[i].Description = unique.IdentifyDevice?.Model;
dups[i].Duplicates = hashes.Where(h => h.Hash == dups[i].Hash).Skip(1).Select(x => x.Id).ToArray();
}
public IActionResult ConsolidateWithIds(int masterId, int slaveId)
return View(new IdHashModelForView
{
Ata master = _context.Ata.FirstOrDefault(m => m.Id == masterId);
List = dups,
Json = JsonConvert.SerializeObject(dups)
});
}
[HttpPost, ActionName("Consolidate"), ValidateAntiForgeryToken]
public IActionResult ConsolidateConfirmed(string models)
{
IdHashModel[] duplicates;
try
{
duplicates = JsonConvert.DeserializeObject<IdHashModel[]>(models);
}
catch(JsonSerializationException)
{
return BadRequest();
}
if(duplicates is null)
return BadRequest();
foreach(IdHashModel duplicate in duplicates)
{
Ata master = _context.Ata.FirstOrDefault(m => m.Id == duplicate.Id);
if(master is null)
return RedirectToAction(nameof(Compare), new
continue;
foreach(int duplicateId in duplicate.Duplicates)
{
Ata slave = _context.Ata.FirstOrDefault(m => m.Id == duplicateId);
if(slave is null)
continue;
foreach(Device ataDevice in _context.Devices.Where(d => d.ATA.Id == duplicateId))
{
id = masterId,
rightId = slaveId
});
ataDevice.ATA = master;
}
Ata slave = _context.Ata.FirstOrDefault(m => m.Id == slaveId);
if(slave is null)
return RedirectToAction(nameof(Compare), new
foreach(Device atapiDevice in _context.Devices.Where(d => d.ATAPI.Id == duplicateId))
{
id = masterId,
rightId = slaveId
});
atapiDevice.ATAPI = master;
}
foreach(Device ataDevice in _context.Devices.Where(d => d.ATA.Id == slaveId))
{
ataDevice.ATA = master;
foreach(UploadedReport ataReport in _context.Reports.Where(d => d.ATA.Id == duplicateId))
{
ataReport.ATA = master;
}
foreach(UploadedReport atapiReport in _context.Reports.Where(d => d.ATAPI.Id == duplicateId))
{
atapiReport.ATAPI = master;
}
foreach(TestedMedia testedMedia in _context.TestedMedia.Where(d => d.AtaId == duplicateId))
{
testedMedia.AtaId = duplicate.Id;
_context.Update(testedMedia);
}
if(master.ReadCapabilities is null &&
slave.ReadCapabilities != null)
master.ReadCapabilities = slave.ReadCapabilities;
_context.Ata.Remove(slave);
}
foreach(Device atapiDevice in _context.Devices.Where(d => d.ATAPI.Id == slaveId))
{
atapiDevice.ATAPI = master;
}
foreach(UploadedReport ataReport in _context.Reports.Where(d => d.ATA.Id == slaveId))
{
ataReport.ATA = master;
}
foreach(UploadedReport atapiReport in _context.Reports.Where(d => d.ATAPI.Id == slaveId))
{
atapiReport.ATAPI = master;
}
foreach(TestedMedia testedMedia in _context.TestedMedia.Where(d => d.AtaId == slaveId))
{
testedMedia.AtaId = masterId;
_context.Update(testedMedia);
}
if(master.ReadCapabilities is null &&
slave.ReadCapabilities != null)
master.ReadCapabilities = slave.ReadCapabilities;
_context.Ata.Remove(slave);
_context.SaveChanges();
return RedirectToAction(nameof(Index));
}
public IActionResult Compare(int id, int rightId)
_context.SaveChanges();
return RedirectToAction(nameof(Index));
}
public IActionResult ConsolidateWithIds(int masterId, int slaveId)
{
Ata master = _context.Ata.FirstOrDefault(m => m.Id == masterId);
if(master is null)
return RedirectToAction(nameof(Compare), new
{
id = masterId,
rightId = slaveId
});
Ata slave = _context.Ata.FirstOrDefault(m => m.Id == slaveId);
if(slave is null)
return RedirectToAction(nameof(Compare), new
{
id = masterId,
rightId = slaveId
});
foreach(Device ataDevice in _context.Devices.Where(d => d.ATA.Id == slaveId))
{
var model = new CompareModel
{
LeftId = id,
RightId = rightId
};
ataDevice.ATA = master;
}
Ata left = _context.Ata.FirstOrDefault(l => l.Id == id);
Ata right = _context.Ata.FirstOrDefault(r => r.Id == rightId);
foreach(Device atapiDevice in _context.Devices.Where(d => d.ATAPI.Id == slaveId))
{
atapiDevice.ATAPI = master;
}
if(left is null)
{
model.ErrorMessage = $"ATA with id {id} has not been found";
model.HasError = true;
foreach(UploadedReport ataReport in _context.Reports.Where(d => d.ATA.Id == slaveId))
{
ataReport.ATA = master;
}
return View(model);
}
foreach(UploadedReport atapiReport in _context.Reports.Where(d => d.ATAPI.Id == slaveId))
{
atapiReport.ATAPI = master;
}
if(right is null)
{
model.ErrorMessage = $"ATA with id {rightId} has not been found";
model.HasError = true;
foreach(TestedMedia testedMedia in _context.TestedMedia.Where(d => d.AtaId == slaveId))
{
testedMedia.AtaId = masterId;
_context.Update(testedMedia);
}
return View(model);
}
if(master.ReadCapabilities is null &&
slave.ReadCapabilities != null)
master.ReadCapabilities = slave.ReadCapabilities;
Identify.IdentifyDevice? leftNullable = left.IdentifyDevice;
Identify.IdentifyDevice? rightNullable = right.IdentifyDevice;
model.ValueNames = new List<string>();
model.LeftValues = new List<string>();
model.RightValues = new List<string>();
_context.Ata.Remove(slave);
if(!leftNullable.HasValue &&
!rightNullable.HasValue)
{
model.AreEqual = true;
_context.SaveChanges();
return View(model);
}
return RedirectToAction(nameof(Index));
}
if(leftNullable.HasValue &&
!rightNullable.HasValue)
{
model.ValueNames.Add("Decoded");
model.LeftValues.Add("decoded");
model.RightValues.Add("null");
public IActionResult Compare(int id, int rightId)
{
var model = new CompareModel
{
LeftId = id,
RightId = rightId
};
return View(model);
}
Ata left = _context.Ata.FirstOrDefault(l => l.Id == id);
Ata right = _context.Ata.FirstOrDefault(r => r.Id == rightId);
if(!leftNullable.HasValue)
{
model.ValueNames.Add("Decoded");
model.LeftValues.Add("null");
model.RightValues.Add("decoded");
return View(model);
}
Identify.IdentifyDevice leftValue = left.IdentifyDevice.Value;
Identify.IdentifyDevice rightValue = right.IdentifyDevice.Value;
foreach(FieldInfo fieldInfo in leftValue.GetType().GetFields())
{
object lv = fieldInfo.GetValue(leftValue);
object rv = fieldInfo.GetValue(rightValue);
if(fieldInfo.FieldType.IsArray)
{
var la = lv as Array;
var ra = rv as Array;
switch(la)
{
case null when ra is null: continue;
case null:
model.ValueNames.Add(fieldInfo.Name);
model.LeftValues.Add("null");
model.RightValues.Add("[]");
continue;
}
if(ra is null)
{
model.ValueNames.Add(fieldInfo.Name);
model.LeftValues.Add("[]");
model.RightValues.Add("null");
continue;
}
List<object> ll = la.Cast<object>().ToList();
List<object> rl = ra.Cast<object>().ToList();
for(int i = 0; i < ll.Count; i++)
{
if(ll[i].Equals(rl[i]))
continue;
model.ValueNames.Add(fieldInfo.Name);
model.LeftValues.Add("[]");
model.RightValues.Add("[]");
break;
}
}
else if(lv == null &&
rv == null) {}
else if(lv != null &&
rv == null)
{
model.ValueNames.Add(fieldInfo.Name);
model.LeftValues.Add($"{lv}");
model.RightValues.Add("null");
}
else if(lv == null)
{
model.ValueNames.Add(fieldInfo.Name);
model.LeftValues.Add("null");
model.RightValues.Add($"{rv}");
}
else if(!lv.Equals(rv))
{
model.ValueNames.Add(fieldInfo.Name);
model.LeftValues.Add($"{lv}");
model.RightValues.Add($"{rv}");
}
}
model.AreEqual = model.LeftValues.Count == 0 && model.RightValues.Count == 0;
if(left is null)
{
model.ErrorMessage = $"ATA with id {id} has not been found";
model.HasError = true;
return View(model);
}
public IActionResult CheckPrivate()
if(right is null)
{
List<Ata> havePrivacy = new();
byte[] tmp;
model.ErrorMessage = $"ATA with id {rightId} has not been found";
model.HasError = true;
foreach(Ata ata in _context.Ata)
{
Identify.IdentifyDevice? id = ata.IdentifyDevice;
if(id is null)
continue;
if(!string.IsNullOrWhiteSpace(id.Value.SerialNumber) ||
id.Value.WWN != 0 ||
id.Value.WWNExtension != 0 ||
!string.IsNullOrWhiteSpace(id.Value.MediaSerial))
{
havePrivacy.Add(ata);
continue;
}
tmp = new byte[10];
Array.Copy(ata.Identify, 121 * 2, tmp, 0, 10);
if(tmp.All(b => b > 0x20) &&
tmp.All(b => b <= 0x5F))
{
havePrivacy.Add(ata);
continue;
}
tmp = new byte[62];
Array.Copy(ata.Identify, 129 * 2, tmp, 0, 62);
if(tmp.All(b => b > 0x20) &&
tmp.All(b => b <= 0x5F))
{
havePrivacy.Add(ata);
continue;
}
tmp = new byte[14];
Array.Copy(ata.Identify, 161 * 2, tmp, 0, 14);
if(tmp.All(b => b > 0x20) &&
tmp.All(b => b <= 0x5F))
{
havePrivacy.Add(ata);
continue;
}
tmp = new byte[12];
Array.Copy(ata.Identify, 224 * 2, tmp, 0, 12);
if(tmp.All(b => b > 0x20) &&
tmp.All(b => b <= 0x5F))
{
havePrivacy.Add(ata);
continue;
}
tmp = new byte[38];
Array.Copy(ata.Identify, 236 * 2, tmp, 0, 38);
if(tmp.All(b => b > 0x20) &&
tmp.All(b => b <= 0x5F))
{
havePrivacy.Add(ata);
}
}
return View(havePrivacy);
return View(model);
}
public IActionResult ClearPrivate(int id)
{
Ata ata = _context.Ata.FirstOrDefault(a => a.Id == id);
Identify.IdentifyDevice? leftNullable = left.IdentifyDevice;
Identify.IdentifyDevice? rightNullable = right.IdentifyDevice;
model.ValueNames = new List<string>();
model.LeftValues = new List<string>();
model.RightValues = new List<string>();
if(!leftNullable.HasValue &&
!rightNullable.HasValue)
{
model.AreEqual = true;
return View(model);
}
if(leftNullable.HasValue &&
!rightNullable.HasValue)
{
model.ValueNames.Add("Decoded");
model.LeftValues.Add("decoded");
model.RightValues.Add("null");
return View(model);
}
if(!leftNullable.HasValue)
{
model.ValueNames.Add("Decoded");
model.LeftValues.Add("null");
model.RightValues.Add("decoded");
return View(model);
}
Identify.IdentifyDevice leftValue = left.IdentifyDevice.Value;
Identify.IdentifyDevice rightValue = right.IdentifyDevice.Value;
foreach(FieldInfo fieldInfo in leftValue.GetType().GetFields())
{
object lv = fieldInfo.GetValue(leftValue);
object rv = fieldInfo.GetValue(rightValue);
if(fieldInfo.FieldType.IsArray)
{
var la = lv as Array;
var ra = rv as Array;
switch(la)
{
case null when ra is null: continue;
case null:
model.ValueNames.Add(fieldInfo.Name);
model.LeftValues.Add("null");
model.RightValues.Add("[]");
continue;
}
if(ra is null)
{
model.ValueNames.Add(fieldInfo.Name);
model.LeftValues.Add("[]");
model.RightValues.Add("null");
continue;
}
List<object> ll = la.Cast<object>().ToList();
List<object> rl = ra.Cast<object>().ToList();
for(int i = 0; i < ll.Count; i++)
{
if(ll[i].Equals(rl[i]))
continue;
model.ValueNames.Add(fieldInfo.Name);
model.LeftValues.Add("[]");
model.RightValues.Add("[]");
break;
}
}
else if(lv == null &&
rv == null) {}
else if(lv != null &&
rv == null)
{
model.ValueNames.Add(fieldInfo.Name);
model.LeftValues.Add($"{lv}");
model.RightValues.Add("null");
}
else if(lv == null)
{
model.ValueNames.Add(fieldInfo.Name);
model.LeftValues.Add("null");
model.RightValues.Add($"{rv}");
}
else if(!lv.Equals(rv))
{
model.ValueNames.Add(fieldInfo.Name);
model.LeftValues.Add($"{lv}");
model.RightValues.Add($"{rv}");
}
}
model.AreEqual = model.LeftValues.Count == 0 && model.RightValues.Count == 0;
return View(model);
}
public IActionResult CheckPrivate()
{
List<Ata> havePrivacy = new();
byte[] tmp;
foreach(Ata ata in _context.Ata)
{
Identify.IdentifyDevice? id = ata.IdentifyDevice;
if(id is null)
continue;
if(!string.IsNullOrWhiteSpace(id.Value.SerialNumber) ||
id.Value.WWN != 0 ||
id.Value.WWNExtension != 0 ||
!string.IsNullOrWhiteSpace(id.Value.MediaSerial))
{
havePrivacy.Add(ata);
continue;
}
tmp = new byte[10];
Array.Copy(ata.Identify, 121 * 2, tmp, 0, 10);
if(tmp.All(b => b > 0x20) &&
tmp.All(b => b <= 0x5F))
{
havePrivacy.Add(ata);
continue;
}
tmp = new byte[62];
Array.Copy(ata.Identify, 129 * 2, tmp, 0, 62);
if(tmp.All(b => b > 0x20) &&
tmp.All(b => b <= 0x5F))
{
havePrivacy.Add(ata);
continue;
}
tmp = new byte[14];
Array.Copy(ata.Identify, 161 * 2, tmp, 0, 14);
if(tmp.All(b => b > 0x20) &&
tmp.All(b => b <= 0x5F))
{
havePrivacy.Add(ata);
continue;
}
tmp = new byte[12];
Array.Copy(ata.Identify, 224 * 2, tmp, 0, 12);
if(tmp.All(b => b > 0x20) &&
tmp.All(b => b <= 0x5F))
{
havePrivacy.Add(ata);
continue;
}
tmp = new byte[38];
Array.Copy(ata.Identify, 236 * 2, tmp, 0, 38);
if(tmp.All(b => b > 0x20) &&
tmp.All(b => b <= 0x5F))
{
havePrivacy.Add(ata);
}
}
return View(havePrivacy);
}
public IActionResult ClearPrivate(int id)
{
Ata ata = _context.Ata.FirstOrDefault(a => a.Id == id);
if(ata is null)
return RedirectToAction(nameof(CheckPrivate));
// Serial number
for(int i = 0; i < 20; i++)
ata.Identify[(10 * 2) + i] = 0x20;
// Media serial number
for(int i = 0; i < 40; i++)
ata.Identify[(176 * 2) + i] = 0x20;
// WWN and WWN Extension
for(int i = 0; i < 16; i++)
ata.Identify[(108 * 2) + i] = 0;
// We need to tell EFCore the entity has changed
_context.Update(ata);
_context.SaveChanges();
return RedirectToAction(nameof(CheckPrivate));
}
public IActionResult ClearReserved(int id)
{
Ata ata = _context.Ata.FirstOrDefault(a => a.Id == id);
if(ata is null)
return RedirectToAction(nameof(CheckPrivate));
// ReservedWords121
for(int i = 0; i < 10; i++)
ata.Identify[(121 * 2) + i] = 0;
// ReservedWords129
for(int i = 0; i < 40; i++)
ata.Identify[(129 * 2) + i] = 0;
// ReservedCFA
for(int i = 0; i < 14; i++)
ata.Identify[(161 * 2) + i] = 0;
// ReservedCEATA224
for(int i = 0; i < 12; i++)
ata.Identify[(224 * 2) + i] = 0;
// ReservedWords
for(int i = 0; i < 14; i++)
ata.Identify[(161 * 2) + i] = 0;
// We need to tell EFCore the entity has changed
_context.Update(ata);
_context.SaveChanges();
return RedirectToAction(nameof(CheckPrivate));
}
public IActionResult ClearPrivateAll()
{
foreach(Ata ata in _context.Ata)
{
if(ata is null)
return RedirectToAction(nameof(CheckPrivate));
@@ -460,18 +520,17 @@ namespace Aaru.Server.Areas.Admin.Controllers
// We need to tell EFCore the entity has changed
_context.Update(ata);
_context.SaveChanges();
return RedirectToAction(nameof(CheckPrivate));
}
public IActionResult ClearReserved(int id)
_context.SaveChanges();
return RedirectToAction(nameof(CheckPrivate));
}
public IActionResult ClearReservedAll()
{
foreach(Ata ata in _context.Ata)
{
Ata ata = _context.Ata.FirstOrDefault(a => a.Id == id);
if(ata is null)
return RedirectToAction(nameof(CheckPrivate));
// ReservedWords121
for(int i = 0; i < 10; i++)
ata.Identify[(121 * 2) + i] = 0;
@@ -494,70 +553,10 @@ namespace Aaru.Server.Areas.Admin.Controllers
// We need to tell EFCore the entity has changed
_context.Update(ata);
_context.SaveChanges();
return RedirectToAction(nameof(CheckPrivate));
}
public IActionResult ClearPrivateAll()
{
foreach(Ata ata in _context.Ata)
{
if(ata is null)
return RedirectToAction(nameof(CheckPrivate));
_context.SaveChanges();
// Serial number
for(int i = 0; i < 20; i++)
ata.Identify[(10 * 2) + i] = 0x20;
// Media serial number
for(int i = 0; i < 40; i++)
ata.Identify[(176 * 2) + i] = 0x20;
// WWN and WWN Extension
for(int i = 0; i < 16; i++)
ata.Identify[(108 * 2) + i] = 0;
// We need to tell EFCore the entity has changed
_context.Update(ata);
}
_context.SaveChanges();
return RedirectToAction(nameof(CheckPrivate));
}
public IActionResult ClearReservedAll()
{
foreach(Ata ata in _context.Ata)
{
// ReservedWords121
for(int i = 0; i < 10; i++)
ata.Identify[(121 * 2) + i] = 0;
// ReservedWords129
for(int i = 0; i < 40; i++)
ata.Identify[(129 * 2) + i] = 0;
// ReservedCFA
for(int i = 0; i < 14; i++)
ata.Identify[(161 * 2) + i] = 0;
// ReservedCEATA224
for(int i = 0; i < 12; i++)
ata.Identify[(224 * 2) + i] = 0;
// ReservedWords
for(int i = 0; i < 14; i++)
ata.Identify[(161 * 2) + i] = 0;
// We need to tell EFCore the entity has changed
_context.Update(ata);
}
_context.SaveChanges();
return RedirectToAction(nameof(CheckPrivate));
}
return RedirectToAction(nameof(CheckPrivate));
}
}

View File

@@ -5,18 +5,17 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespace Aaru.Server.Areas.Admin.Controllers
namespace Aaru.Server.Areas.Admin.Controllers;
[Area("Admin"), Authorize]
public sealed class BlockDescriptorsController : Controller
{
[Area("Admin"), Authorize]
public sealed class BlockDescriptorsController : Controller
{
readonly AaruServerContext _context;
readonly AaruServerContext _context;
public BlockDescriptorsController(AaruServerContext context) => _context = context;
public BlockDescriptorsController(AaruServerContext context) => _context = context;
// GET: Admin/BlockDescriptors
public async Task<IActionResult> Index() => View(await _context.BlockDescriptor.OrderBy(b => b.BlockLength).
ThenBy(b => b.Blocks).ThenBy(b => b.Density).
ToListAsync());
}
// GET: Admin/BlockDescriptors
public async Task<IActionResult> Index() => View(await _context.BlockDescriptor.OrderBy(b => b.BlockLength).
ThenBy(b => b.Blocks).ThenBy(b => b.Density).
ToListAsync());
}

View File

@@ -8,88 +8,87 @@ using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
namespace Aaru.Server.Areas.Admin.Controllers
namespace Aaru.Server.Areas.Admin.Controllers;
[Area("Admin"), Authorize]
public sealed class ChsController : Controller
{
[Area("Admin"), Authorize]
public sealed class ChsController : Controller
readonly AaruServerContext _context;
public ChsController(AaruServerContext context) => _context = context;
// GET: Admin/Chs
public async Task<IActionResult> Index() => View(await _context.Chs.OrderBy(c => c.Cylinders).
ThenBy(c => c.Heads).ThenBy(c => c.Sectors).
ToListAsync());
public IActionResult Consolidate()
{
readonly AaruServerContext _context;
public ChsController(AaruServerContext context) => _context = context;
// GET: Admin/Chs
public async Task<IActionResult> Index() => View(await _context.Chs.OrderBy(c => c.Cylinders).
ThenBy(c => c.Heads).ThenBy(c => c.Sectors).
ToListAsync());
public IActionResult Consolidate()
List<ChsModel> dups = _context.Chs.GroupBy(x => new
{
List<ChsModel> dups = _context.Chs.GroupBy(x => new
{
x.Cylinders,
x.Heads,
x.Sectors
}).Where(x => x.Count() > 1).Select(x => new ChsModel
{
Cylinders = x.Key.Cylinders,
Heads = x.Key.Heads,
Sectors = x.Key.Sectors
}).ToList();
x.Cylinders,
x.Heads,
x.Sectors
}).Where(x => x.Count() > 1).Select(x => new ChsModel
{
Cylinders = x.Key.Cylinders,
Heads = x.Key.Heads,
Sectors = x.Key.Sectors
}).ToList();
return View(new ChsModelForView
{
List = dups,
Json = JsonConvert.SerializeObject(dups)
});
return View(new ChsModelForView
{
List = dups,
Json = JsonConvert.SerializeObject(dups)
});
}
[HttpPost, ActionName("Consolidate"), ValidateAntiForgeryToken]
public IActionResult ConsolidateConfirmed(string models)
{
ChsModel[] duplicates;
try
{
duplicates = JsonConvert.DeserializeObject<ChsModel[]>(models);
}
catch(JsonSerializationException)
{
return BadRequest();
}
[HttpPost, ActionName("Consolidate"), ValidateAntiForgeryToken]
public IActionResult ConsolidateConfirmed(string models)
if(duplicates is null)
return BadRequest();
foreach(ChsModel duplicate in duplicates)
{
ChsModel[] duplicates;
Chs master = _context.Chs.FirstOrDefault(m => m.Cylinders == duplicate.Cylinders &&
m.Heads == duplicate.Heads &&
m.Sectors == duplicate.Sectors);
try
if(master is null)
continue;
foreach(Chs chs in _context.Chs.Where(m => m.Cylinders == duplicate.Cylinders &&
m.Heads == duplicate.Heads &&
m.Sectors == duplicate.Sectors).Skip(1).ToArray())
{
duplicates = JsonConvert.DeserializeObject<ChsModel[]>(models);
}
catch(JsonSerializationException)
{
return BadRequest();
}
if(duplicates is null)
return BadRequest();
foreach(ChsModel duplicate in duplicates)
{
Chs master = _context.Chs.FirstOrDefault(m => m.Cylinders == duplicate.Cylinders &&
m.Heads == duplicate.Heads &&
m.Sectors == duplicate.Sectors);
if(master is null)
continue;
foreach(Chs chs in _context.Chs.Where(m => m.Cylinders == duplicate.Cylinders &&
m.Heads == duplicate.Heads &&
m.Sectors == duplicate.Sectors).Skip(1).ToArray())
foreach(TestedMedia media in _context.TestedMedia.Where(d => d.CHS.Id == chs.Id))
{
foreach(TestedMedia media in _context.TestedMedia.Where(d => d.CHS.Id == chs.Id))
{
media.CHS = master;
}
foreach(TestedMedia media in _context.TestedMedia.Where(d => d.CurrentCHS.Id == chs.Id))
{
media.CurrentCHS = master;
}
_context.Chs.Remove(chs);
media.CHS = master;
}
foreach(TestedMedia media in _context.TestedMedia.Where(d => d.CurrentCHS.Id == chs.Id))
{
media.CurrentCHS = master;
}
_context.Chs.Remove(chs);
}
_context.SaveChanges();
return RedirectToAction(nameof(Index));
}
_context.SaveChanges();
return RedirectToAction(nameof(Index));
}
}

View File

@@ -5,16 +5,15 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespace Aaru.Server.Areas.Admin.Controllers
namespace Aaru.Server.Areas.Admin.Controllers;
[Area("Admin"), Authorize]
public sealed class CommandsController : Controller
{
[Area("Admin"), Authorize]
public sealed class CommandsController : Controller
{
readonly AaruServerContext _context;
readonly AaruServerContext _context;
public CommandsController(AaruServerContext context) => _context = context;
public CommandsController(AaruServerContext context) => _context = context;
// GET: Admin/Commands
public async Task<IActionResult> Index() => View(await _context.Commands.OrderBy(c => c.Name).ToListAsync());
}
// GET: Admin/Commands
public async Task<IActionResult> Index() => View(await _context.Commands.OrderBy(c => c.Name).ToListAsync());
}

View File

@@ -6,105 +6,104 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespace Aaru.Server.Areas.Admin.Controllers
namespace Aaru.Server.Areas.Admin.Controllers;
[Area("Admin"), Authorize]
public sealed class CompactDiscOffsetsController : Controller
{
[Area("Admin"), Authorize]
public sealed class CompactDiscOffsetsController : Controller
readonly AaruServerContext _context;
public CompactDiscOffsetsController(AaruServerContext context) => _context = context;
// GET: Admin/CompactDiscOffsets
public async Task<IActionResult> Index() => View(await _context.CdOffsets.OrderBy(o => o.Manufacturer).
ThenBy(o => o.Model).ThenBy(o => o.Offset).
ToListAsync());
// GET: Admin/CompactDiscOffsets/Edit/5
public async Task<IActionResult> Edit(int? id)
{
readonly AaruServerContext _context;
public CompactDiscOffsetsController(AaruServerContext context) => _context = context;
// GET: Admin/CompactDiscOffsets
public async Task<IActionResult> Index() => View(await _context.CdOffsets.OrderBy(o => o.Manufacturer).
ThenBy(o => o.Model).ThenBy(o => o.Offset).
ToListAsync());
// GET: Admin/CompactDiscOffsets/Edit/5
public async Task<IActionResult> Edit(int? id)
if(id == null)
{
if(id == null)
{
return NotFound();
}
CompactDiscOffset compactDiscOffset = await _context.CdOffsets.FindAsync(id);
if(compactDiscOffset == null)
{
return NotFound();
}
return View(compactDiscOffset);
return NotFound();
}
// POST: Admin/CompactDiscOffsets/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost, ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Id,Manufacturer,Model,Offset,Submissions,Agreement")]
CompactDiscOffset changedModel)
CompactDiscOffset compactDiscOffset = await _context.CdOffsets.FindAsync(id);
if(compactDiscOffset == null)
{
if(id != changedModel.Id)
return NotFound();
if(!ModelState.IsValid)
return View(changedModel);
CompactDiscOffset model = await _context.CdOffsets.FirstOrDefaultAsync(m => m.Id == id);
if(model is null)
return NotFound();
model.Manufacturer = changedModel.Manufacturer;
model.Model = changedModel.Model;
model.Offset = changedModel.Offset;
model.Submissions = changedModel.Submissions;
model.Agreement = changedModel.Agreement;
model.ModifiedWhen = DateTime.UtcNow;
try
{
_context.Update(model);
await _context.SaveChangesAsync();
}
catch(DbUpdateConcurrencyException)
{
ModelState.AddModelError("Concurrency", "Concurrency error, please report to the administrator.");
}
return RedirectToAction(nameof(Index));
return NotFound();
}
// GET: Admin/CompactDiscOffsets/Delete/5
public async Task<IActionResult> Delete(int? id)
{
if(id == null)
{
return NotFound();
}
CompactDiscOffset compactDiscOffset = await _context.CdOffsets.FirstOrDefaultAsync(m => m.Id == id);
if(compactDiscOffset == null)
{
return NotFound();
}
return View(compactDiscOffset);
}
// POST: Admin/CompactDiscOffsets/Delete/5
[HttpPost, ActionName("Delete"), ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
CompactDiscOffset compactDiscOffset = await _context.CdOffsets.FindAsync(id);
_context.CdOffsets.Remove(compactDiscOffset);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
public IActionResult Update() => throw new NotImplementedException();
return View(compactDiscOffset);
}
// POST: Admin/CompactDiscOffsets/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost, ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Id,Manufacturer,Model,Offset,Submissions,Agreement")]
CompactDiscOffset changedModel)
{
if(id != changedModel.Id)
return NotFound();
if(!ModelState.IsValid)
return View(changedModel);
CompactDiscOffset model = await _context.CdOffsets.FirstOrDefaultAsync(m => m.Id == id);
if(model is null)
return NotFound();
model.Manufacturer = changedModel.Manufacturer;
model.Model = changedModel.Model;
model.Offset = changedModel.Offset;
model.Submissions = changedModel.Submissions;
model.Agreement = changedModel.Agreement;
model.ModifiedWhen = DateTime.UtcNow;
try
{
_context.Update(model);
await _context.SaveChangesAsync();
}
catch(DbUpdateConcurrencyException)
{
ModelState.AddModelError("Concurrency", "Concurrency error, please report to the administrator.");
}
return RedirectToAction(nameof(Index));
}
// GET: Admin/CompactDiscOffsets/Delete/5
public async Task<IActionResult> Delete(int? id)
{
if(id == null)
{
return NotFound();
}
CompactDiscOffset compactDiscOffset = await _context.CdOffsets.FirstOrDefaultAsync(m => m.Id == id);
if(compactDiscOffset == null)
{
return NotFound();
}
return View(compactDiscOffset);
}
// POST: Admin/CompactDiscOffsets/Delete/5
[HttpPost, ActionName("Delete"), ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
CompactDiscOffset compactDiscOffset = await _context.CdOffsets.FindAsync(id);
_context.CdOffsets.Remove(compactDiscOffset);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
public IActionResult Update() => throw new NotImplementedException();
}

View File

@@ -5,101 +5,100 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespace Aaru.Server.Areas.Admin.Controllers
namespace Aaru.Server.Areas.Admin.Controllers;
[Area("Admin"), Authorize]
public sealed class DeviceStatsController : Controller
{
[Area("Admin"), Authorize]
public sealed class DeviceStatsController : Controller
readonly AaruServerContext _context;
public DeviceStatsController(AaruServerContext context) => _context = context;
// GET: Admin/DeviceStats
public async Task<IActionResult> Index() => View(await _context.DeviceStats.OrderBy(d => d.Manufacturer).
ThenBy(d => d.Model).ThenBy(d => d.Bus).
ToListAsync());
// GET: Admin/DeviceStats/Edit/5
public async Task<IActionResult> Edit(int? id)
{
readonly AaruServerContext _context;
public DeviceStatsController(AaruServerContext context) => _context = context;
// GET: Admin/DeviceStats
public async Task<IActionResult> Index() => View(await _context.DeviceStats.OrderBy(d => d.Manufacturer).
ThenBy(d => d.Model).ThenBy(d => d.Bus).
ToListAsync());
// GET: Admin/DeviceStats/Edit/5
public async Task<IActionResult> Edit(int? id)
if(id == null)
{
if(id == null)
{
return NotFound();
}
DeviceStat deviceStat = await _context.DeviceStats.FindAsync(id);
if(deviceStat == null)
{
return NotFound();
}
return View(deviceStat);
return NotFound();
}
// POST: Admin/DeviceStats/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost, ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Id,Manufacturer,Model,Revision,Bus")]
DeviceStat changedModel)
DeviceStat deviceStat = await _context.DeviceStats.FindAsync(id);
if(deviceStat == null)
{
if(id != changedModel.Id)
return NotFound();
if(!ModelState.IsValid)
return View(changedModel);
DeviceStat model = await _context.DeviceStats.FirstOrDefaultAsync(m => m.Id == id);
if(model is null)
return NotFound();
model.Manufacturer = changedModel.Manufacturer;
model.Model = changedModel.Model;
model.Revision = changedModel.Revision;
model.Bus = changedModel.Bus;
try
{
_context.Update(model);
await _context.SaveChangesAsync();
}
catch(DbUpdateConcurrencyException)
{
ModelState.AddModelError("Concurrency", "Concurrency error, please report to the administrator.");
}
return RedirectToAction(nameof(Index));
return NotFound();
}
// GET: Admin/DeviceStats/Delete/5
public async Task<IActionResult> Delete(int? id)
return View(deviceStat);
}
// POST: Admin/DeviceStats/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost, ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Id,Manufacturer,Model,Revision,Bus")]
DeviceStat changedModel)
{
if(id != changedModel.Id)
return NotFound();
if(!ModelState.IsValid)
return View(changedModel);
DeviceStat model = await _context.DeviceStats.FirstOrDefaultAsync(m => m.Id == id);
if(model is null)
return NotFound();
model.Manufacturer = changedModel.Manufacturer;
model.Model = changedModel.Model;
model.Revision = changedModel.Revision;
model.Bus = changedModel.Bus;
try
{
if(id == null)
{
return NotFound();
}
DeviceStat deviceStat = await _context.DeviceStats.FirstOrDefaultAsync(m => m.Id == id);
if(deviceStat == null)
{
return NotFound();
}
return View(deviceStat);
}
// POST: Admin/DeviceStats/Delete/5
[HttpPost, ActionName("Delete"), ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
DeviceStat deviceStat = await _context.DeviceStats.FindAsync(id);
_context.DeviceStats.Remove(deviceStat);
_context.Update(model);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
catch(DbUpdateConcurrencyException)
{
ModelState.AddModelError("Concurrency", "Concurrency error, please report to the administrator.");
}
return RedirectToAction(nameof(Index));
}
// GET: Admin/DeviceStats/Delete/5
public async Task<IActionResult> Delete(int? id)
{
if(id == null)
{
return NotFound();
}
DeviceStat deviceStat = await _context.DeviceStats.FirstOrDefaultAsync(m => m.Id == id);
if(deviceStat == null)
{
return NotFound();
}
return View(deviceStat);
}
// POST: Admin/DeviceStats/Delete/5
[HttpPost, ActionName("Delete"), ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
DeviceStat deviceStat = await _context.DeviceStats.FindAsync(id);
_context.DeviceStats.Remove(deviceStat);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
}

View File

@@ -7,415 +7,414 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespace Aaru.Server.Areas.Admin.Controllers
namespace Aaru.Server.Areas.Admin.Controllers;
[Area("Admin"), Authorize]
public sealed class DevicesController : Controller
{
[Area("Admin"), Authorize]
public sealed class DevicesController : Controller
readonly AaruServerContext _context;
public DevicesController(AaruServerContext context) => _context = context;
// GET: Admin/Devices
public async Task<IActionResult> Index() => View(await _context.Devices.OrderBy(d => d.Manufacturer).
ThenBy(d => d.Model).ThenBy(d => d.Revision).
ThenBy(d => d.CompactFlash).ThenBy(d => d.Type).
ToListAsync());
// GET: Admin/Devices/Details/5
public async Task<IActionResult> Details(int? id)
{
readonly AaruServerContext _context;
public DevicesController(AaruServerContext context) => _context = context;
// GET: Admin/Devices
public async Task<IActionResult> Index() => View(await _context.Devices.OrderBy(d => d.Manufacturer).
ThenBy(d => d.Model).ThenBy(d => d.Revision).
ThenBy(d => d.CompactFlash).ThenBy(d => d.Type).
ToListAsync());
// GET: Admin/Devices/Details/5
public async Task<IActionResult> Details(int? id)
if(id == null)
{
if(id == null)
{
return NotFound();
}
var model = new DeviceDetails
{
Report = await _context.Devices.FirstOrDefaultAsync(m => m.Id == id)
};
if(model.Report is null)
{
return NotFound();
}
model.ReportAll = _context.Reports.
Where(d => d.Manufacturer == model.Report.Manufacturer &&
d.Model == model.Report.Model && d.Revision == model.Report.Revision).
Select(d => d.Id).ToList();
model.ReportButManufacturer = _context.Reports.
Where(d => d.Model == model.Report.Model &&
d.Revision == model.Report.Revision).Select(d => d.Id).
Where(d => model.ReportAll.All(r => r != d)).ToList();
model.SameAll = _context.Devices.
Where(d => d.Manufacturer == model.Report.Manufacturer &&
d.Model == model.Report.Model && d.Revision == model.Report.Revision &&
d.Id != id).Select(d => d.Id).ToList();
model.SameButManufacturer = _context.Devices.
Where(d => d.Model == model.Report.Model &&
d.Revision == model.Report.Revision && d.Id != id).
Select(d => d.Id).Where(d => model.SameAll.All(r => r != d)).ToList();
model.StatsAll = _context.DeviceStats.
Where(d => d.Manufacturer == model.Report.Manufacturer &&
d.Model == model.Report.Model && d.Revision == model.Report.Revision &&
d.Report.Id != model.Report.Id).ToList();
model.StatsButManufacturer = _context.DeviceStats.
Where(d => d.Model == model.Report.Model &&
d.Revision == model.Report.Revision &&
d.Report.Id != model.Report.Id).AsEnumerable().
Where(d => model.StatsAll.All(s => s.Id != d.Id)).ToList();
model.ReadCapabilitiesId =
model.Report.ATA?.ReadCapabilities?.Id ?? model.Report.SCSI?.ReadCapabilities?.Id ?? 0;
// So we can check, as we know IDs with 0 will never exist, and EFCore does not allow null propagation in the LINQ
int ataId = model.Report.ATA?.Id ?? 0;
int atapiId = model.Report.ATAPI?.Id ?? 0;
int scsiId = model.Report.SCSI?.Id ?? 0;
int mmcId = model.Report.SCSI?.MultiMediaDevice?.Id ?? 0;
int sscId = model.Report.SCSI?.SequentialDevice?.Id ?? 0;
model.TestedMedias = _context.TestedMedia.
Where(t => t.AtaId == ataId || t.AtaId == atapiId || t.ScsiId == scsiId ||
t.MmcId == mmcId).OrderBy(t => t.Manufacturer).
ThenBy(t => t.Model).ThenBy(t => t.MediumTypeName).ToList();
model.TestedSequentialMedias = _context.TestedSequentialMedia.Where(t => t.SscId == sscId).
OrderBy(t => t.Manufacturer).ThenBy(t => t.Model).
ThenBy(t => t.MediumTypeName).ToList();
return View(model);
return NotFound();
}
// GET: Admin/Devices/Edit/5
public async Task<IActionResult> Edit(int? id)
var model = new DeviceDetails
{
if(id == null)
{
return NotFound();
}
Report = await _context.Devices.FirstOrDefaultAsync(m => m.Id == id)
};
Device device = await _context.Devices.FindAsync(id);
if(device == null)
{
return NotFound();
}
return View(device);
if(model.Report is null)
{
return NotFound();
}
// POST: Admin/Devices/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost, ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(
int id, [Bind("OptimalMultipleSectorsRead,Id,CompactFlash,Manufacturer,Model,Revision,Type")]
Device changedModel)
model.ReportAll = _context.Reports.
Where(d => d.Manufacturer == model.Report.Manufacturer &&
d.Model == model.Report.Model && d.Revision == model.Report.Revision).
Select(d => d.Id).ToList();
model.ReportButManufacturer = _context.Reports.
Where(d => d.Model == model.Report.Model &&
d.Revision == model.Report.Revision).Select(d => d.Id).
Where(d => model.ReportAll.All(r => r != d)).ToList();
model.SameAll = _context.Devices.
Where(d => d.Manufacturer == model.Report.Manufacturer &&
d.Model == model.Report.Model && d.Revision == model.Report.Revision &&
d.Id != id).Select(d => d.Id).ToList();
model.SameButManufacturer = _context.Devices.
Where(d => d.Model == model.Report.Model &&
d.Revision == model.Report.Revision && d.Id != id).
Select(d => d.Id).Where(d => model.SameAll.All(r => r != d)).ToList();
model.StatsAll = _context.DeviceStats.
Where(d => d.Manufacturer == model.Report.Manufacturer &&
d.Model == model.Report.Model && d.Revision == model.Report.Revision &&
d.Report.Id != model.Report.Id).ToList();
model.StatsButManufacturer = _context.DeviceStats.
Where(d => d.Model == model.Report.Model &&
d.Revision == model.Report.Revision &&
d.Report.Id != model.Report.Id).AsEnumerable().
Where(d => model.StatsAll.All(s => s.Id != d.Id)).ToList();
model.ReadCapabilitiesId =
model.Report.ATA?.ReadCapabilities?.Id ?? model.Report.SCSI?.ReadCapabilities?.Id ?? 0;
// So we can check, as we know IDs with 0 will never exist, and EFCore does not allow null propagation in the LINQ
int ataId = model.Report.ATA?.Id ?? 0;
int atapiId = model.Report.ATAPI?.Id ?? 0;
int scsiId = model.Report.SCSI?.Id ?? 0;
int mmcId = model.Report.SCSI?.MultiMediaDevice?.Id ?? 0;
int sscId = model.Report.SCSI?.SequentialDevice?.Id ?? 0;
model.TestedMedias = _context.TestedMedia.
Where(t => t.AtaId == ataId || t.AtaId == atapiId || t.ScsiId == scsiId ||
t.MmcId == mmcId).OrderBy(t => t.Manufacturer).
ThenBy(t => t.Model).ThenBy(t => t.MediumTypeName).ToList();
model.TestedSequentialMedias = _context.TestedSequentialMedia.Where(t => t.SscId == sscId).
OrderBy(t => t.Manufacturer).ThenBy(t => t.Model).
ThenBy(t => t.MediumTypeName).ToList();
return View(model);
}
// GET: Admin/Devices/Edit/5
public async Task<IActionResult> Edit(int? id)
{
if(id == null)
{
if(id != changedModel.Id)
return NotFound();
if(!ModelState.IsValid)
return View(changedModel);
Device model = await _context.Devices.FirstOrDefaultAsync(m => m.Id == id);
if(model is null)
return NotFound();
model.CanReadGdRomUsingSwapDisc = changedModel.CanReadGdRomUsingSwapDisc;
model.OptimalMultipleSectorsRead = changedModel.OptimalMultipleSectorsRead;
model.CompactFlash = changedModel.CompactFlash;
model.Manufacturer = changedModel.Manufacturer;
model.Model = changedModel.Model;
model.Revision = changedModel.Revision;
model.Type = changedModel.Type;
model.ModifiedWhen = DateTime.UtcNow;
try
{
_context.Update(model);
await _context.SaveChangesAsync();
}
catch(DbUpdateConcurrencyException)
{
ModelState.AddModelError("Concurrency", "Concurrency error, please report to the administrator.");
}
return RedirectToAction(nameof(Index));
return NotFound();
}
// GET: Admin/Devices/Delete/5
public async Task<IActionResult> Delete(int? id)
Device device = await _context.Devices.FindAsync(id);
if(device == null)
{
if(id == null)
{
return NotFound();
}
Device device = await _context.Devices.FirstOrDefaultAsync(m => m.Id == id);
if(device == null)
{
return NotFound();
}
return View(device);
return NotFound();
}
// POST: Admin/Devices/Delete/5
[HttpPost, ActionName("Delete"), ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
return View(device);
}
// POST: Admin/Devices/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost, ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(
int id, [Bind("OptimalMultipleSectorsRead,Id,CompactFlash,Manufacturer,Model,Revision,Type")]
Device changedModel)
{
if(id != changedModel.Id)
return NotFound();
if(!ModelState.IsValid)
return View(changedModel);
Device model = await _context.Devices.FirstOrDefaultAsync(m => m.Id == id);
if(model is null)
return NotFound();
model.CanReadGdRomUsingSwapDisc = changedModel.CanReadGdRomUsingSwapDisc;
model.OptimalMultipleSectorsRead = changedModel.OptimalMultipleSectorsRead;
model.CompactFlash = changedModel.CompactFlash;
model.Manufacturer = changedModel.Manufacturer;
model.Model = changedModel.Model;
model.Revision = changedModel.Revision;
model.Type = changedModel.Type;
model.ModifiedWhen = DateTime.UtcNow;
try
{
Device device = await _context.Devices.FindAsync(id);
_context.Devices.Remove(device);
_context.Update(model);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
catch(DbUpdateConcurrencyException)
{
ModelState.AddModelError("Concurrency", "Concurrency error, please report to the administrator.");
}
bool DeviceExists(int id) => _context.Devices.Any(e => e.Id == id);
return RedirectToAction(nameof(Index));
}
public IActionResult Merge(int? master, int? slave)
// GET: Admin/Devices/Delete/5
public async Task<IActionResult> Delete(int? id)
{
if(id == null)
{
if(master is null ||
slave is null)
return NotFound();
return NotFound();
}
Device masterDevice = _context.Devices.FirstOrDefault(m => m.Id == master);
Device slaveDevice = _context.Devices.FirstOrDefault(m => m.Id == slave);
Device device = await _context.Devices.FirstOrDefaultAsync(m => m.Id == id);
if(masterDevice is null ||
slaveDevice is null)
return NotFound();
if(device == null)
{
return NotFound();
}
if(masterDevice.ATAId != null &&
masterDevice.ATAId != slaveDevice.ATAId)
{
foreach(TestedMedia testedMedia in _context.TestedMedia.Where(d => d.AtaId == slaveDevice.ATAId))
{
testedMedia.AtaId = masterDevice.ATAId;
_context.Update(testedMedia);
}
}
else if(masterDevice.ATAId == null &&
slaveDevice.ATAId != null)
{
masterDevice.ATAId = slaveDevice.ATAId;
_context.Update(masterDevice);
}
return View(device);
}
if(masterDevice.ATAPIId != null &&
masterDevice.ATAPIId != slaveDevice.ATAPIId)
{
foreach(TestedMedia testedMedia in _context.TestedMedia.Where(d => d.AtaId == slaveDevice.ATAPIId))
{
testedMedia.AtaId = masterDevice.ATAPIId;
_context.Update(testedMedia);
}
}
else if(masterDevice.ATAPIId == null &&
slaveDevice.ATAPIId != null)
{
masterDevice.ATAPIId = slaveDevice.ATAPIId;
_context.Update(masterDevice);
}
// POST: Admin/Devices/Delete/5
[HttpPost, ActionName("Delete"), ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
Device device = await _context.Devices.FindAsync(id);
_context.Devices.Remove(device);
await _context.SaveChangesAsync();
if(masterDevice.SCSIId != null &&
masterDevice.SCSIId != slaveDevice.SCSIId)
{
foreach(TestedMedia testedMedia in _context.TestedMedia.Where(d => d.ScsiId == slaveDevice.SCSIId))
{
testedMedia.ScsiId = masterDevice.SCSIId;
_context.Update(testedMedia);
}
}
else if(masterDevice.SCSIId == null &&
slaveDevice.SCSIId != null)
{
masterDevice.SCSIId = slaveDevice.SCSIId;
_context.Update(masterDevice);
}
return RedirectToAction(nameof(Index));
}
masterDevice.ModifiedWhen = DateTime.UtcNow;
bool DeviceExists(int id) => _context.Devices.Any(e => e.Id == id);
public IActionResult Merge(int? master, int? slave)
{
if(master is null ||
slave is null)
return NotFound();
Device masterDevice = _context.Devices.FirstOrDefault(m => m.Id == master);
Device slaveDevice = _context.Devices.FirstOrDefault(m => m.Id == slave);
if(masterDevice is null ||
slaveDevice is null)
return NotFound();
if(masterDevice.ATAId != null &&
masterDevice.ATAId != slaveDevice.ATAId)
{
foreach(TestedMedia testedMedia in _context.TestedMedia.Where(d => d.AtaId == slaveDevice.ATAId))
{
testedMedia.AtaId = masterDevice.ATAId;
_context.Update(testedMedia);
}
}
else if(masterDevice.ATAId == null &&
slaveDevice.ATAId != null)
{
masterDevice.ATAId = slaveDevice.ATAId;
_context.Update(masterDevice);
_context.Remove(slaveDevice);
_context.SaveChanges();
return RedirectToAction(nameof(Details), new
{
Id = master
});
}
public IActionResult MergeReports(int? deviceId, int? reportId)
if(masterDevice.ATAPIId != null &&
masterDevice.ATAPIId != slaveDevice.ATAPIId)
{
if(deviceId is null ||
reportId is null)
return NotFound();
Device device = _context.Devices.FirstOrDefault(m => m.Id == deviceId);
UploadedReport report = _context.Reports.FirstOrDefault(m => m.Id == reportId);
if(device is null ||
report is null)
return NotFound();
if(device.ATAId != null &&
device.ATAId != report.ATAId)
foreach(TestedMedia testedMedia in _context.TestedMedia.Where(d => d.AtaId == slaveDevice.ATAPIId))
{
foreach(TestedMedia testedMedia in _context.TestedMedia.Where(d => d.AtaId == report.ATAId))
{
testedMedia.AtaId = device.ATAId;
_context.Update(testedMedia);
}
if(device.ATA != null &&
device.ATA.ReadCapabilities is null &&
report.ATA?.ReadCapabilities != null)
{
device.ATA.ReadCapabilities = report.ATA.ReadCapabilities;
_context.Update(device.ATA);
}
testedMedia.AtaId = masterDevice.ATAPIId;
_context.Update(testedMedia);
}
else if(device.ATAId == null &&
report.ATAId != null)
}
else if(masterDevice.ATAPIId == null &&
slaveDevice.ATAPIId != null)
{
masterDevice.ATAPIId = slaveDevice.ATAPIId;
_context.Update(masterDevice);
}
if(masterDevice.SCSIId != null &&
masterDevice.SCSIId != slaveDevice.SCSIId)
{
foreach(TestedMedia testedMedia in _context.TestedMedia.Where(d => d.ScsiId == slaveDevice.SCSIId))
{
device.ATAId = report.ATAId;
_context.Update(device);
testedMedia.ScsiId = masterDevice.SCSIId;
_context.Update(testedMedia);
}
}
else if(masterDevice.SCSIId == null &&
slaveDevice.SCSIId != null)
{
masterDevice.SCSIId = slaveDevice.SCSIId;
_context.Update(masterDevice);
}
masterDevice.ModifiedWhen = DateTime.UtcNow;
_context.Update(masterDevice);
_context.Remove(slaveDevice);
_context.SaveChanges();
return RedirectToAction(nameof(Details), new
{
Id = master
});
}
public IActionResult MergeReports(int? deviceId, int? reportId)
{
if(deviceId is null ||
reportId is null)
return NotFound();
Device device = _context.Devices.FirstOrDefault(m => m.Id == deviceId);
UploadedReport report = _context.Reports.FirstOrDefault(m => m.Id == reportId);
if(device is null ||
report is null)
return NotFound();
if(device.ATAId != null &&
device.ATAId != report.ATAId)
{
foreach(TestedMedia testedMedia in _context.TestedMedia.Where(d => d.AtaId == report.ATAId))
{
testedMedia.AtaId = device.ATAId;
_context.Update(testedMedia);
}
if(device.ATAPIId != null &&
device.ATAPIId != report.ATAPIId)
if(device.ATA != null &&
device.ATA.ReadCapabilities is null &&
report.ATA?.ReadCapabilities != null)
{
foreach(TestedMedia testedMedia in _context.TestedMedia.Where(d => d.AtaId == report.ATAPIId))
{
testedMedia.AtaId = device.ATAPIId;
_context.Update(testedMedia);
}
device.ATA.ReadCapabilities = report.ATA.ReadCapabilities;
_context.Update(device.ATA);
}
else if(device.ATAPIId == null &&
report.ATAPIId != null)
}
else if(device.ATAId == null &&
report.ATAId != null)
{
device.ATAId = report.ATAId;
_context.Update(device);
}
if(device.ATAPIId != null &&
device.ATAPIId != report.ATAPIId)
{
foreach(TestedMedia testedMedia in _context.TestedMedia.Where(d => d.AtaId == report.ATAPIId))
{
device.ATAPIId = report.ATAPIId;
_context.Update(device);
testedMedia.AtaId = device.ATAPIId;
_context.Update(testedMedia);
}
}
else if(device.ATAPIId == null &&
report.ATAPIId != null)
{
device.ATAPIId = report.ATAPIId;
_context.Update(device);
}
if(device.SCSIId != null &&
device.SCSIId != report.SCSIId)
{
foreach(TestedMedia testedMedia in _context.TestedMedia.Where(d => d.ScsiId == report.SCSIId))
{
testedMedia.ScsiId = device.SCSIId;
_context.Update(testedMedia);
}
if(device.SCSIId != null &&
device.SCSIId != report.SCSIId)
if(device.SCSI != null &&
device.SCSI.ReadCapabilities is null &&
report.SCSI?.ReadCapabilities != null)
{
foreach(TestedMedia testedMedia in _context.TestedMedia.Where(d => d.ScsiId == report.SCSIId))
{
testedMedia.ScsiId = device.SCSIId;
_context.Update(testedMedia);
}
device.SCSI.ReadCapabilities = report.SCSI.ReadCapabilities;
_context.Update(device.SCSI);
}
if(device.SCSI != null &&
device.SCSI.ReadCapabilities is null &&
report.SCSI?.ReadCapabilities != null)
{
device.SCSI.ReadCapabilities = report.SCSI.ReadCapabilities;
_context.Update(device.SCSI);
}
if(device.SCSI != null &&
device.SCSI.MultiMediaDevice is null &&
report.SCSI?.MultiMediaDevice != null)
{
device.SCSI.MultiMediaDevice = report.SCSI.MultiMediaDevice;
_context.Update(device.SCSI);
}
else if(device.SCSI?.MultiMediaDevice != null &&
report.SCSI?.MultiMediaDevice != null)
{
foreach(TestedMedia testedMedia in
if(device.SCSI != null &&
device.SCSI.MultiMediaDevice is null &&
report.SCSI?.MultiMediaDevice != null)
{
device.SCSI.MultiMediaDevice = report.SCSI.MultiMediaDevice;
_context.Update(device.SCSI);
}
else if(device.SCSI?.MultiMediaDevice != null &&
report.SCSI?.MultiMediaDevice != null)
{
foreach(TestedMedia testedMedia in
_context.TestedMedia.Where(d => d.MmcId == report.SCSI.MultiMediaDevice.Id))
{
testedMedia.MmcId = device.SCSI.MultiMediaDevice.Id;
_context.Update(testedMedia);
}
{
testedMedia.MmcId = device.SCSI.MultiMediaDevice.Id;
_context.Update(testedMedia);
}
}
if(device.SCSI != null &&
device.SCSI.SequentialDevice is null &&
report.SCSI?.SequentialDevice != null)
{
device.SCSI.SequentialDevice = report.SCSI.SequentialDevice;
_context.Update(device.SCSI);
}
else if(device.SCSI?.SequentialDevice != null &&
report.SCSI?.SequentialDevice != null)
{
foreach(TestedSequentialMedia testedSequentialMedia in
if(device.SCSI != null &&
device.SCSI.SequentialDevice is null &&
report.SCSI?.SequentialDevice != null)
{
device.SCSI.SequentialDevice = report.SCSI.SequentialDevice;
_context.Update(device.SCSI);
}
else if(device.SCSI?.SequentialDevice != null &&
report.SCSI?.SequentialDevice != null)
{
foreach(TestedSequentialMedia testedSequentialMedia in
_context.TestedSequentialMedia.Where(d => d.SscId == report.SCSI.SequentialDevice.Id))
{
testedSequentialMedia.SscId = device.SCSI.SequentialDevice.Id;
_context.Update(testedSequentialMedia);
}
{
testedSequentialMedia.SscId = device.SCSI.SequentialDevice.Id;
_context.Update(testedSequentialMedia);
}
}
else if(device.SCSIId == null &&
report.SCSIId != null)
{
device.SCSIId = report.SCSIId;
_context.Update(device);
}
_context.Remove(report);
_context.SaveChanges();
return RedirectToAction(nameof(Details), new
{
Id = deviceId
});
}
public IActionResult LinkReports(int? statsId, int? deviceId)
else if(device.SCSIId == null &&
report.SCSIId != null)
{
if(statsId is null ||
deviceId is null)
return NotFound();
Device device = _context.Devices.FirstOrDefault(m => m.Id == deviceId);
DeviceStat stat = _context.DeviceStats.FirstOrDefault(m => m.Id == statsId);
if(device is null ||
stat is null)
return NotFound();
stat.Report = device;
_context.Update(stat);
_context.SaveChanges();
return RedirectToAction(nameof(Details), new
{
Id = deviceId
});
device.SCSIId = report.SCSIId;
_context.Update(device);
}
public IActionResult Find(int id, string manufacturer, string model, string revision, string bus)
_context.Remove(report);
_context.SaveChanges();
return RedirectToAction(nameof(Details), new
{
if(model is null)
return NotFound();
Id = deviceId
});
}
var found = new FindReportModel
{
Id = id,
Manufacturer = manufacturer,
Model = model,
Revision = revision,
Bus = bus,
LikeDevices = _context.Devices.Where(r => r.Model.ToLower().Contains(model.ToLower())).ToList()
};
public IActionResult LinkReports(int? statsId, int? deviceId)
{
if(statsId is null ||
deviceId is null)
return NotFound();
return View(found);
}
Device device = _context.Devices.FirstOrDefault(m => m.Id == deviceId);
DeviceStat stat = _context.DeviceStats.FirstOrDefault(m => m.Id == statsId);
if(device is null ||
stat is null)
return NotFound();
stat.Report = device;
_context.Update(stat);
_context.SaveChanges();
return RedirectToAction(nameof(Details), new
{
Id = deviceId
});
}
public IActionResult Find(int id, string manufacturer, string model, string revision, string bus)
{
if(model is null)
return NotFound();
var found = new FindReportModel
{
Id = id,
Manufacturer = manufacturer,
Model = model,
Revision = revision,
Bus = bus,
LikeDevices = _context.Devices.Where(r => r.Model.ToLower().Contains(model.ToLower())).ToList()
};
return View(found);
}
}

View File

@@ -5,16 +5,15 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespace Aaru.Server.Areas.Admin.Controllers
namespace Aaru.Server.Areas.Admin.Controllers;
[Area("Admin"), Authorize]
public sealed class FilesystemsController : Controller
{
[Area("Admin"), Authorize]
public sealed class FilesystemsController : Controller
{
readonly AaruServerContext _context;
readonly AaruServerContext _context;
public FilesystemsController(AaruServerContext context) => _context = context;
public FilesystemsController(AaruServerContext context) => _context = context;
// GET: Admin/Filesystems
public async Task<IActionResult> Index() => View(await _context.Filesystems.OrderBy(f => f.Name).ToListAsync());
}
// GET: Admin/Filesystems
public async Task<IActionResult> Index() => View(await _context.Filesystems.OrderBy(f => f.Name).ToListAsync());
}

View File

@@ -5,16 +5,15 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespace Aaru.Server.Areas.Admin.Controllers
namespace Aaru.Server.Areas.Admin.Controllers;
[Area("Admin"), Authorize]
public sealed class FiltersController : Controller
{
[Area("Admin"), Authorize]
public sealed class FiltersController : Controller
{
readonly AaruServerContext _context;
readonly AaruServerContext _context;
public FiltersController(AaruServerContext context) => _context = context;
public FiltersController(AaruServerContext context) => _context = context;
// GET: Admin/Filters
public async Task<IActionResult> Index() => View(await _context.Filters.OrderBy(f => f.Name).ToListAsync());
}
// GET: Admin/Filters
public async Task<IActionResult> Index() => View(await _context.Filters.OrderBy(f => f.Name).ToListAsync());
}

View File

@@ -8,183 +8,182 @@ using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
namespace Aaru.Server.Areas.Admin.Controllers
namespace Aaru.Server.Areas.Admin.Controllers;
[Area("Admin"), Authorize]
public sealed class FireWiresController : Controller
{
[Area("Admin"), Authorize]
public sealed class FireWiresController : Controller
readonly AaruServerContext _context;
public FireWiresController(AaruServerContext context) => _context = context;
// GET: Admin/FireWires
public async Task<IActionResult> Index() =>
View(await _context.FireWire.OrderBy(f => f.Manufacturer).ThenBy(f => f.Product).ToListAsync());
// GET: Admin/FireWires/Edit/5
public async Task<IActionResult> Edit(int? id)
{
readonly AaruServerContext _context;
public FireWiresController(AaruServerContext context) => _context = context;
// GET: Admin/FireWires
public async Task<IActionResult> Index() =>
View(await _context.FireWire.OrderBy(f => f.Manufacturer).ThenBy(f => f.Product).ToListAsync());
// GET: Admin/FireWires/Edit/5
public async Task<IActionResult> Edit(int? id)
if(id == null)
{
if(id == null)
{
return NotFound();
}
FireWire fireWire = await _context.FireWire.FindAsync(id);
if(fireWire == null)
{
return NotFound();
}
return View(fireWire);
return NotFound();
}
// POST: Admin/FireWires/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost, ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(
int id, [Bind("Id,VendorID,ProductID,Manufacturer,Product,RemovableMedia")]
FireWire changedModel)
FireWire fireWire = await _context.FireWire.FindAsync(id);
if(fireWire == null)
{
if(id != changedModel.Id)
return NotFound();
if(!ModelState.IsValid)
return View(changedModel);
FireWire model = await _context.FireWire.FirstOrDefaultAsync(m => m.Id == id);
if(model is null)
return NotFound();
model.VendorID = changedModel.VendorID;
model.ProductID = changedModel.ProductID;
model.Manufacturer = changedModel.Manufacturer;
model.Product = changedModel.Product;
model.RemovableMedia = changedModel.RemovableMedia;
try
{
_context.Update(model);
await _context.SaveChangesAsync();
}
catch(DbUpdateConcurrencyException)
{
ModelState.AddModelError("Concurrency", "Concurrency error, please report to the administrator.");
}
return RedirectToAction(nameof(Index));
return NotFound();
}
// GET: Admin/FireWires/Delete/5
public async Task<IActionResult> Delete(int? id)
return View(fireWire);
}
// POST: Admin/FireWires/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost, ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(
int id, [Bind("Id,VendorID,ProductID,Manufacturer,Product,RemovableMedia")]
FireWire changedModel)
{
if(id != changedModel.Id)
return NotFound();
if(!ModelState.IsValid)
return View(changedModel);
FireWire model = await _context.FireWire.FirstOrDefaultAsync(m => m.Id == id);
if(model is null)
return NotFound();
model.VendorID = changedModel.VendorID;
model.ProductID = changedModel.ProductID;
model.Manufacturer = changedModel.Manufacturer;
model.Product = changedModel.Product;
model.RemovableMedia = changedModel.RemovableMedia;
try
{
if(id == null)
{
return NotFound();
}
FireWire fireWire = await _context.FireWire.FirstOrDefaultAsync(m => m.Id == id);
if(fireWire == null)
{
return NotFound();
}
return View(fireWire);
}
// POST: Admin/FireWires/Delete/5
[HttpPost, ActionName("Delete"), ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
FireWire fireWire = await _context.FireWire.FindAsync(id);
_context.FireWire.Remove(fireWire);
_context.Update(model);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
catch(DbUpdateConcurrencyException)
{
ModelState.AddModelError("Concurrency", "Concurrency error, please report to the administrator.");
}
bool FireWireExists(int id) => _context.FireWire.Any(e => e.Id == id);
return RedirectToAction(nameof(Index));
}
public IActionResult Consolidate()
// GET: Admin/FireWires/Delete/5
public async Task<IActionResult> Delete(int? id)
{
if(id == null)
{
List<FireWireModel> dups = _context.FireWire.GroupBy(x => new
{
x.VendorID,
x.ProductID,
x.Manufacturer,
x.Product,
x.RemovableMedia
}).Where(x => x.Count() > 1).Select(x => new FireWireModel
{
VendorID = x.Key.VendorID,
ProductID = x.Key.ProductID,
Manufacturer = x.Key.Manufacturer,
Product = x.Key.Product,
RemovableMedia = x.Key.RemovableMedia
}).ToList();
return View(new FireWireModelForView
{
List = dups,
Json = JsonConvert.SerializeObject(dups)
});
return NotFound();
}
[HttpPost, ActionName("Consolidate"), ValidateAntiForgeryToken]
public IActionResult ConsolidateConfirmed(string models)
FireWire fireWire = await _context.FireWire.FirstOrDefaultAsync(m => m.Id == id);
if(fireWire == null)
{
FireWireModel[] duplicates;
return NotFound();
}
try
return View(fireWire);
}
// POST: Admin/FireWires/Delete/5
[HttpPost, ActionName("Delete"), ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
FireWire fireWire = await _context.FireWire.FindAsync(id);
_context.FireWire.Remove(fireWire);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
bool FireWireExists(int id) => _context.FireWire.Any(e => e.Id == id);
public IActionResult Consolidate()
{
List<FireWireModel> dups = _context.FireWire.GroupBy(x => new
{
x.VendorID,
x.ProductID,
x.Manufacturer,
x.Product,
x.RemovableMedia
}).Where(x => x.Count() > 1).Select(x => new FireWireModel
{
VendorID = x.Key.VendorID,
ProductID = x.Key.ProductID,
Manufacturer = x.Key.Manufacturer,
Product = x.Key.Product,
RemovableMedia = x.Key.RemovableMedia
}).ToList();
return View(new FireWireModelForView
{
List = dups,
Json = JsonConvert.SerializeObject(dups)
});
}
[HttpPost, ActionName("Consolidate"), ValidateAntiForgeryToken]
public IActionResult ConsolidateConfirmed(string models)
{
FireWireModel[] duplicates;
try
{
duplicates = JsonConvert.DeserializeObject<FireWireModel[]>(models);
}
catch(JsonSerializationException)
{
return BadRequest();
}
if(duplicates is null)
return BadRequest();
foreach(FireWireModel duplicate in duplicates)
{
FireWire master = _context.FireWire.FirstOrDefault(m => m.VendorID == duplicate.VendorID &&
m.ProductID == duplicate.ProductID &&
m.Manufacturer == duplicate.Manufacturer &&
m.Product == duplicate.Product &&
m.RemovableMedia == duplicate.RemovableMedia);
if(master is null)
continue;
foreach(FireWire firewire in _context.FireWire.Where(m => m.VendorID == duplicate.VendorID &&
m.ProductID == duplicate.ProductID &&
m.Manufacturer == duplicate.Manufacturer &&
m.Product == duplicate.Product &&
m.RemovableMedia == duplicate.RemovableMedia).
Skip(1).ToArray())
{
duplicates = JsonConvert.DeserializeObject<FireWireModel[]>(models);
}
catch(JsonSerializationException)
{
return BadRequest();
}
if(duplicates is null)
return BadRequest();
foreach(FireWireModel duplicate in duplicates)
{
FireWire master = _context.FireWire.FirstOrDefault(m => m.VendorID == duplicate.VendorID &&
m.ProductID == duplicate.ProductID &&
m.Manufacturer == duplicate.Manufacturer &&
m.Product == duplicate.Product &&
m.RemovableMedia == duplicate.RemovableMedia);
if(master is null)
continue;
foreach(FireWire firewire in _context.FireWire.Where(m => m.VendorID == duplicate.VendorID &&
m.ProductID == duplicate.ProductID &&
m.Manufacturer == duplicate.Manufacturer &&
m.Product == duplicate.Product &&
m.RemovableMedia == duplicate.RemovableMedia).
Skip(1).ToArray())
foreach(Device device in _context.Devices.Where(d => d.FireWire.Id == firewire.Id))
{
foreach(Device device in _context.Devices.Where(d => d.FireWire.Id == firewire.Id))
{
device.FireWire = master;
}
foreach(UploadedReport report in _context.Reports.Where(d => d.FireWire.Id == firewire.Id))
{
report.FireWire = master;
}
_context.FireWire.Remove(firewire);
device.FireWire = master;
}
foreach(UploadedReport report in _context.Reports.Where(d => d.FireWire.Id == firewire.Id))
{
report.FireWire = master;
}
_context.FireWire.Remove(firewire);
}
_context.SaveChanges();
return RedirectToAction(nameof(Index));
}
_context.SaveChanges();
return RedirectToAction(nameof(Index));
}
}

View File

@@ -11,383 +11,382 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespace Aaru.Server.Areas.Admin.Controllers
namespace Aaru.Server.Areas.Admin.Controllers;
[Area("Admin"), Authorize]
public sealed class GdRomSwapDiscCapabilitiesController : Controller
{
[Area("Admin"), Authorize]
public sealed class GdRomSwapDiscCapabilitiesController : Controller
readonly AaruServerContext _context;
public GdRomSwapDiscCapabilitiesController(AaruServerContext context) => _context = context;
// GET: Admin/GdRomSwapDiscCapabilities/Details/5
public async Task<IActionResult> Details(int? id)
{
readonly AaruServerContext _context;
public GdRomSwapDiscCapabilitiesController(AaruServerContext context) => _context = context;
// GET: Admin/GdRomSwapDiscCapabilities/Details/5
public async Task<IActionResult> Details(int? id)
if(id == null)
{
if(id == null)
{
return NotFound();
}
GdRomSwapDiscCapabilities caps =
await _context.GdRomSwapDiscCapabilities.FirstOrDefaultAsync(m => m.Id == id);
if(caps == null)
{
return NotFound();
}
return View(caps);
return NotFound();
}
// GET: Admin/GdRomSwapDiscCapabilities/Delete/5
public async Task<IActionResult> Delete(int? id)
GdRomSwapDiscCapabilities caps =
await _context.GdRomSwapDiscCapabilities.FirstOrDefaultAsync(m => m.Id == id);
if(caps == null)
{
if(id == null)
{
return NotFound();
}
GdRomSwapDiscCapabilities caps =
await _context.GdRomSwapDiscCapabilities.FirstOrDefaultAsync(m => m.Id == id);
if(caps == null)
{
return NotFound();
}
return View(caps);
return NotFound();
}
// POST: Admin/GdRomSwapDiscCapabilities/Delete/5
[HttpPost, ActionName("Delete"), ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
GdRomSwapDiscCapabilities caps = await _context.GdRomSwapDiscCapabilities.FindAsync(id);
_context.GdRomSwapDiscCapabilities.Remove(caps);
await _context.SaveChangesAsync();
return View(caps);
}
return RedirectToAction("Index", "Admin");
// GET: Admin/GdRomSwapDiscCapabilities/Delete/5
public async Task<IActionResult> Delete(int? id)
{
if(id == null)
{
return NotFound();
}
public IActionResult ViewData(int id, string data)
GdRomSwapDiscCapabilities caps =
await _context.GdRomSwapDiscCapabilities.FirstOrDefaultAsync(m => m.Id == id);
if(caps == null)
{
if(string.IsNullOrWhiteSpace(data))
return NotFound();
return NotFound();
}
GdRomSwapDiscCapabilities caps = _context.GdRomSwapDiscCapabilities.FirstOrDefault(m => m.Id == id);
return View(caps);
}
if(caps == null)
{
return NotFound();
}
// POST: Admin/GdRomSwapDiscCapabilities/Delete/5
[HttpPost, ActionName("Delete"), ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
GdRomSwapDiscCapabilities caps = await _context.GdRomSwapDiscCapabilities.FindAsync(id);
_context.GdRomSwapDiscCapabilities.Remove(caps);
await _context.SaveChangesAsync();
var model = new TestedMediaDataModel
{
TestedMediaId = id,
DataName = data
};
return RedirectToAction("Index", "Admin");
}
byte[] buffer;
var sb = new StringBuilder();
byte[] sector = new byte[2352];
byte[] subq = new byte[16];
byte[] fullsub = new byte[96];
public IActionResult ViewData(int id, string data)
{
if(string.IsNullOrWhiteSpace(data))
return NotFound();
bool audio = true;
bool pq = false;
bool rw = false;
GdRomSwapDiscCapabilities caps = _context.GdRomSwapDiscCapabilities.FirstOrDefault(m => m.Id == id);
switch(data)
{
case nameof(caps.Lba0Data):
buffer = caps.Lba0Data;
audio = false;
if(caps == null)
{
return NotFound();
}
break;
case nameof(caps.Lba0ScrambledData):
buffer = caps.Lba0ScrambledData;
var model = new TestedMediaDataModel
{
TestedMediaId = id,
DataName = data
};
break;
case nameof(caps.Lba44990Data):
buffer = caps.Lba44990Data;
audio = false;
byte[] buffer;
var sb = new StringBuilder();
byte[] sector = new byte[2352];
byte[] subq = new byte[16];
byte[] fullsub = new byte[96];
break;
case nameof(caps.Lba44990PqData):
buffer = caps.Lba44990PqData;
audio = false;
pq = true;
bool audio = true;
bool pq = false;
bool rw = false;
break;
case nameof(caps.Lba44990RwData):
buffer = caps.Lba44990RwData;
audio = false;
rw = true;
switch(data)
{
case nameof(caps.Lba0Data):
buffer = caps.Lba0Data;
audio = false;
break;
case nameof(caps.Lba44990AudioData):
buffer = caps.Lba44990AudioData;
break;
case nameof(caps.Lba0ScrambledData):
buffer = caps.Lba0ScrambledData;
break;
case nameof(caps.Lba44990AudioPqData):
buffer = caps.Lba44990AudioPqData;
pq = true;
break;
case nameof(caps.Lba44990Data):
buffer = caps.Lba44990Data;
audio = false;
break;
case nameof(caps.Lba44990AudioRwData):
buffer = caps.Lba44990AudioRwData;
rw = true;
break;
case nameof(caps.Lba44990PqData):
buffer = caps.Lba44990PqData;
audio = false;
pq = true;
break;
case nameof(caps.Lba45000Data):
buffer = caps.Lba45000Data;
audio = false;
break;
case nameof(caps.Lba44990RwData):
buffer = caps.Lba44990RwData;
audio = false;
rw = true;
break;
case nameof(caps.Lba45000PqData):
buffer = caps.Lba45000PqData;
audio = false;
pq = true;
break;
case nameof(caps.Lba44990AudioData):
buffer = caps.Lba44990AudioData;
break;
case nameof(caps.Lba45000RwData):
buffer = caps.Lba45000RwData;
audio = false;
rw = true;
break;
case nameof(caps.Lba44990AudioPqData):
buffer = caps.Lba44990AudioPqData;
pq = true;
break;
case nameof(caps.Lba45000AudioData):
buffer = caps.Lba45000AudioData;
break;
case nameof(caps.Lba44990AudioRwData):
buffer = caps.Lba44990AudioRwData;
rw = true;
break;
case nameof(caps.Lba45000AudioPqData):
buffer = caps.Lba45000AudioPqData;
pq = true;
break;
case nameof(caps.Lba45000Data):
buffer = caps.Lba45000Data;
audio = false;
break;
case nameof(caps.Lba45000AudioRwData):
buffer = caps.Lba45000AudioRwData;
rw = true;
break;
case nameof(caps.Lba45000PqData):
buffer = caps.Lba45000PqData;
audio = false;
pq = true;
break;
case nameof(caps.Lba50000Data):
buffer = caps.Lba50000Data;
audio = false;
break;
case nameof(caps.Lba45000RwData):
buffer = caps.Lba45000RwData;
audio = false;
rw = true;
break;
case nameof(caps.Lba50000PqData):
buffer = caps.Lba50000PqData;
audio = false;
pq = true;
break;
case nameof(caps.Lba45000AudioData):
buffer = caps.Lba45000AudioData;
break;
case nameof(caps.Lba50000RwData):
buffer = caps.Lba50000RwData;
audio = false;
rw = true;
break;
case nameof(caps.Lba45000AudioPqData):
buffer = caps.Lba45000AudioPqData;
pq = true;
break;
case nameof(caps.Lba50000AudioData):
buffer = caps.Lba50000AudioData;
break;
case nameof(caps.Lba45000AudioRwData):
buffer = caps.Lba45000AudioRwData;
rw = true;
break;
case nameof(caps.Lba50000AudioPqData):
buffer = caps.Lba50000AudioPqData;
pq = true;
break;
case nameof(caps.Lba50000Data):
buffer = caps.Lba50000Data;
audio = false;
break;
case nameof(caps.Lba50000AudioRwData):
buffer = caps.Lba50000AudioRwData;
rw = true;
break;
case nameof(caps.Lba50000PqData):
buffer = caps.Lba50000PqData;
audio = false;
pq = true;
break;
case nameof(caps.Lba100000Data):
buffer = caps.Lba100000Data;
audio = false;
break;
case nameof(caps.Lba50000RwData):
buffer = caps.Lba50000RwData;
audio = false;
rw = true;
break;
case nameof(caps.Lba100000PqData):
buffer = caps.Lba100000PqData;
audio = false;
pq = true;
break;
case nameof(caps.Lba50000AudioData):
buffer = caps.Lba50000AudioData;
break;
case nameof(caps.Lba100000RwData):
buffer = caps.Lba100000RwData;
audio = false;
rw = true;
break;
case nameof(caps.Lba50000AudioPqData):
buffer = caps.Lba50000AudioPqData;
pq = true;
break;
case nameof(caps.Lba100000AudioData):
buffer = caps.Lba100000AudioData;
break;
case nameof(caps.Lba50000AudioRwData):
buffer = caps.Lba50000AudioRwData;
rw = true;
break;
case nameof(caps.Lba100000AudioPqData):
buffer = caps.Lba100000AudioPqData;
pq = true;
break;
case nameof(caps.Lba100000Data):
buffer = caps.Lba100000Data;
audio = false;
break;
case nameof(caps.Lba100000AudioRwData):
buffer = caps.Lba100000AudioRwData;
rw = true;
break;
case nameof(caps.Lba100000PqData):
buffer = caps.Lba100000PqData;
audio = false;
pq = true;
break;
case nameof(caps.Lba400000Data):
buffer = caps.Lba400000Data;
audio = false;
break;
case nameof(caps.Lba100000RwData):
buffer = caps.Lba100000RwData;
audio = false;
rw = true;
break;
case nameof(caps.Lba400000PqData):
buffer = caps.Lba400000PqData;
audio = false;
pq = true;
break;
case nameof(caps.Lba100000AudioData):
buffer = caps.Lba100000AudioData;
break;
case nameof(caps.Lba400000RwData):
buffer = caps.Lba400000RwData;
audio = false;
rw = true;
break;
case nameof(caps.Lba100000AudioPqData):
buffer = caps.Lba100000AudioPqData;
pq = true;
break;
case nameof(caps.Lba400000AudioData):
buffer = caps.Lba400000AudioData;
break;
case nameof(caps.Lba100000AudioRwData):
buffer = caps.Lba100000AudioRwData;
rw = true;
break;
case nameof(caps.Lba400000AudioPqData):
buffer = caps.Lba400000AudioPqData;
pq = true;
break;
case nameof(caps.Lba400000Data):
buffer = caps.Lba400000Data;
audio = false;
break;
case nameof(caps.Lba400000AudioRwData):
buffer = caps.Lba400000AudioRwData;
rw = true;
break;
case nameof(caps.Lba400000PqData):
buffer = caps.Lba400000PqData;
audio = false;
pq = true;
break;
case nameof(caps.Lba450000Data):
buffer = caps.Lba450000Data;
audio = false;
break;
case nameof(caps.Lba400000RwData):
buffer = caps.Lba400000RwData;
audio = false;
rw = true;
break;
case nameof(caps.Lba450000PqData):
buffer = caps.Lba450000PqData;
audio = false;
pq = true;
break;
case nameof(caps.Lba400000AudioData):
buffer = caps.Lba400000AudioData;
break;
case nameof(caps.Lba450000RwData):
buffer = caps.Lba450000RwData;
audio = false;
rw = true;
break;
case nameof(caps.Lba400000AudioPqData):
buffer = caps.Lba400000AudioPqData;
pq = true;
break;
case nameof(caps.Lba450000AudioData):
buffer = caps.Lba450000AudioData;
break;
case nameof(caps.Lba400000AudioRwData):
buffer = caps.Lba400000AudioRwData;
rw = true;
break;
case nameof(caps.Lba450000AudioPqData):
buffer = caps.Lba450000AudioPqData;
pq = true;
break;
case nameof(caps.Lba450000Data):
buffer = caps.Lba450000Data;
audio = false;
break;
case nameof(caps.Lba450000AudioRwData):
buffer = caps.Lba450000AudioRwData;
rw = true;
break;
case nameof(caps.Lba450000PqData):
buffer = caps.Lba450000PqData;
audio = false;
pq = true;
break;
default: return NotFound();
}
break;
case nameof(caps.Lba450000RwData):
buffer = caps.Lba450000RwData;
audio = false;
rw = true;
if(pq &&
buffer != null &&
buffer.Length % 2368 != 0)
pq = false;
break;
case nameof(caps.Lba450000AudioData):
buffer = caps.Lba450000AudioData;
if(rw &&
buffer != null &&
buffer.Length % 2448 != 0)
rw = false;
break;
case nameof(caps.Lba450000AudioPqData):
buffer = caps.Lba450000AudioPqData;
pq = true;
int blockSize = pq
? 2368
: rw
? 2448
: 2352;
break;
case nameof(caps.Lba450000AudioRwData):
buffer = caps.Lba450000AudioRwData;
rw = true;
model.RawDataAsHex = PrintHex.ByteArrayToHexArrayString(buffer);
break;
default: return NotFound();
}
if(model.RawDataAsHex != null)
model.RawDataAsHex = HttpUtility.HtmlEncode(model.RawDataAsHex).Replace("\n", "<br/>");
if(pq &&
buffer != null &&
buffer.Length % 2368 != 0)
pq = false;
if(buffer == null)
return View(model);
if(rw &&
buffer != null &&
buffer.Length % 2448 != 0)
rw = false;
for(int i = 0; i < buffer.Length; i += blockSize)
{
if(audio)
{
sb.AppendLine("Audio or scrambled data sector.");
}
else
{
Array.Copy(buffer, i, sector, 0, 2352);
int blockSize = pq
? 2368
: rw
? 2448
: 2352;
sb.AppendLine(Sector.Prettify(sector));
}
model.RawDataAsHex = PrintHex.ByteArrayToHexArrayString(buffer);
if(pq)
{
Array.Copy(buffer, i + 2352, subq, 0, 16);
fullsub = Subchannel.ConvertQToRaw(subq);
sb.AppendLine(GetPrettySub(fullsub));
}
else if(rw)
{
Array.Copy(buffer, i + 2352, fullsub, 0, 96);
sb.AppendLine(GetPrettySub(fullsub));
}
sb.AppendLine();
}
model.Decoded = HttpUtility.HtmlEncode(sb.ToString()).Replace("\n", "<br/>");
if(model.RawDataAsHex != null)
model.RawDataAsHex = HttpUtility.HtmlEncode(model.RawDataAsHex).Replace("\n", "<br/>");
if(buffer == null)
return View(model);
}
static string GetPrettySub(byte[] sub)
for(int i = 0; i < buffer.Length; i += blockSize)
{
byte[] deint = Subchannel.Deinterleave(sub);
bool validP = true;
bool validRw = true;
for(int i = 0; i < 12; i++)
if(audio)
{
if(deint[i] == 0x00 ||
deint[i] == 0xFF)
continue;
sb.AppendLine("Audio or scrambled data sector.");
}
else
{
Array.Copy(buffer, i, sector, 0, 2352);
validP = false;
break;
sb.AppendLine(Sector.Prettify(sector));
}
for(int i = 24; i < 96; i++)
if(pq)
{
if(deint[i] == 0x00)
continue;
Array.Copy(buffer, i + 2352, subq, 0, 16);
fullsub = Subchannel.ConvertQToRaw(subq);
validRw = false;
sb.AppendLine(GetPrettySub(fullsub));
}
else if(rw)
{
Array.Copy(buffer, i + 2352, fullsub, 0, 96);
break;
sb.AppendLine(GetPrettySub(fullsub));
}
byte[] q = new byte[12];
Array.Copy(deint, 12, q, 0, 12);
return Subchannel.PrettifyQ(q, deint[21] > 0x10, 16, !validP, false, validRw);
sb.AppendLine();
}
model.Decoded = HttpUtility.HtmlEncode(sb.ToString()).Replace("\n", "<br/>");
return View(model);
}
static string GetPrettySub(byte[] sub)
{
byte[] deint = Subchannel.Deinterleave(sub);
bool validP = true;
bool validRw = true;
for(int i = 0; i < 12; i++)
{
if(deint[i] == 0x00 ||
deint[i] == 0xFF)
continue;
validP = false;
break;
}
for(int i = 24; i < 96; i++)
{
if(deint[i] == 0x00)
continue;
validRw = false;
break;
}
byte[] q = new byte[12];
Array.Copy(deint, 12, q, 0, 12);
return Subchannel.PrettifyQ(q, deint[21] > 0x10, 16, !validP, false, validRw);
}
}

View File

@@ -33,11 +33,10 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace Aaru.Server.Areas.Admin.Controllers
namespace Aaru.Server.Areas.Admin.Controllers;
[Area("Admin"), Authorize]
public sealed class HomeController : Controller
{
[Area("Admin"), Authorize]
public sealed class HomeController : Controller
{
public ActionResult Index() => View();
}
public ActionResult Index() => View();
}

View File

@@ -5,46 +5,45 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespace Aaru.Server.Areas.Admin.Controllers
namespace Aaru.Server.Areas.Admin.Controllers;
[Area("Admin"), Authorize]
public sealed class MediaFormatsController : Controller
{
[Area("Admin"), Authorize]
public sealed class MediaFormatsController : Controller
readonly AaruServerContext _context;
public MediaFormatsController(AaruServerContext context) => _context = context;
// GET: Admin/MediaFormats
public async Task<IActionResult> Index() =>
View(await _context.MediaFormats.OrderBy(mf => mf.Name).ToListAsync());
// GET: Admin/MediaFormats/Delete/5
public async Task<IActionResult> Delete(int? id)
{
readonly AaruServerContext _context;
public MediaFormatsController(AaruServerContext context) => _context = context;
// GET: Admin/MediaFormats
public async Task<IActionResult> Index() =>
View(await _context.MediaFormats.OrderBy(mf => mf.Name).ToListAsync());
// GET: Admin/MediaFormats/Delete/5
public async Task<IActionResult> Delete(int? id)
if(id == null)
{
if(id == null)
{
return NotFound();
}
MediaFormat mediaFormat = await _context.MediaFormats.FirstOrDefaultAsync(m => m.Id == id);
if(mediaFormat == null)
{
return NotFound();
}
return View(mediaFormat);
return NotFound();
}
// POST: Admin/MediaFormats/Delete/5
[HttpPost, ActionName("Delete"), ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
MediaFormat mediaFormat = await _context.MediaFormats.FindAsync(id);
_context.MediaFormats.Remove(mediaFormat);
await _context.SaveChangesAsync();
MediaFormat mediaFormat = await _context.MediaFormats.FirstOrDefaultAsync(m => m.Id == id);
return RedirectToAction(nameof(Index));
if(mediaFormat == null)
{
return NotFound();
}
return View(mediaFormat);
}
// POST: Admin/MediaFormats/Delete/5
[HttpPost, ActionName("Delete"), ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
MediaFormat mediaFormat = await _context.MediaFormats.FindAsync(id);
_context.MediaFormats.Remove(mediaFormat);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
}

View File

@@ -5,56 +5,55 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespace Aaru.Server.Areas.Admin.Controllers
namespace Aaru.Server.Areas.Admin.Controllers;
[Area("Admin"), Authorize]
public sealed class MediasController : Controller
{
[Area("Admin"), Authorize]
public sealed class MediasController : Controller
readonly AaruServerContext _context;
public MediasController(AaruServerContext context) => _context = context;
// GET: Admin/Medias
public IActionResult Index(bool? real)
{
readonly AaruServerContext _context;
public MediasController(AaruServerContext context) => _context = context;
// GET: Admin/Medias
public IActionResult Index(bool? real)
switch(real)
{
switch(real)
{
case null:
return View(_context.Medias.ToList().OrderBy(m => m.PhysicalType).ThenBy(m => m.LogicalType).
ThenBy(m => m.Real));
default:
return View(_context.Medias.Where(m => m.Real == real).ToList().OrderBy(m => m.PhysicalType).
ThenBy(m => m.LogicalType));
}
}
// GET: Admin/Medias/Delete/5
public async Task<IActionResult> Delete(int? id)
{
if(id == null)
{
return NotFound();
}
Media media = await _context.Medias.FirstOrDefaultAsync(m => m.Id == id);
if(media == null)
{
return NotFound();
}
return View(media);
}
// POST: Admin/Medias/Delete/5
[HttpPost, ActionName("Delete"), ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
Media media = await _context.Medias.FindAsync(id);
_context.Medias.Remove(media);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
case null:
return View(_context.Medias.ToList().OrderBy(m => m.PhysicalType).ThenBy(m => m.LogicalType).
ThenBy(m => m.Real));
default:
return View(_context.Medias.Where(m => m.Real == real).ToList().OrderBy(m => m.PhysicalType).
ThenBy(m => m.LogicalType));
}
}
// GET: Admin/Medias/Delete/5
public async Task<IActionResult> Delete(int? id)
{
if(id == null)
{
return NotFound();
}
Media media = await _context.Medias.FirstOrDefaultAsync(m => m.Id == id);
if(media == null)
{
return NotFound();
}
return View(media);
}
// POST: Admin/Medias/Delete/5
[HttpPost, ActionName("Delete"), ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
Media media = await _context.Medias.FindAsync(id);
_context.Medias.Remove(media);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
}

View File

@@ -6,87 +6,86 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespace Aaru.Server.Areas.Admin.Controllers
namespace Aaru.Server.Areas.Admin.Controllers;
[Area("Admin"), Authorize]
public sealed class MmcController : Controller
{
[Area("Admin"), Authorize]
public sealed class MmcController : Controller
readonly AaruServerContext _context;
public MmcController(AaruServerContext context) => _context = context;
// GET: Admin/Mmc
public IActionResult Index() => View(_context.Mmc.Where(m => m.ModeSense2AData != null).
Select(m => new MmcModelForView
{
Id = m.Id,
FeaturesId = m.FeaturesId,
DataLength = m.ModeSense2AData.Length
}).ToList().
Concat(_context.Mmc.Where(m => m.ModeSense2AData == null).
Select(m => new MmcModelForView
{
Id = m.Id,
FeaturesId = m.FeaturesId,
DataLength = 0
}).ToList()).OrderBy(m => m.Id));
// GET: Admin/Mmc/Details/5
public async Task<IActionResult> Details(int? id)
{
readonly AaruServerContext _context;
public MmcController(AaruServerContext context) => _context = context;
// GET: Admin/Mmc
public IActionResult Index() => View(_context.Mmc.Where(m => m.ModeSense2AData != null).
Select(m => new MmcModelForView
{
Id = m.Id,
FeaturesId = m.FeaturesId,
DataLength = m.ModeSense2AData.Length
}).ToList().
Concat(_context.Mmc.Where(m => m.ModeSense2AData == null).
Select(m => new MmcModelForView
{
Id = m.Id,
FeaturesId = m.FeaturesId,
DataLength = 0
}).ToList()).OrderBy(m => m.Id));
// GET: Admin/Mmc/Details/5
public async Task<IActionResult> Details(int? id)
if(id == null)
{
if(id == null)
{
return NotFound();
}
Mmc mmc = await _context.Mmc.FirstOrDefaultAsync(m => m.Id == id);
if(mmc == null)
{
return NotFound();
}
return View(mmc);
return NotFound();
}
// GET: Admin/Mmc/Delete/5
public async Task<IActionResult> Delete(int? id)
Mmc mmc = await _context.Mmc.FirstOrDefaultAsync(m => m.Id == id);
if(mmc == null)
{
if(id == null)
{
return NotFound();
}
Mmc mmc = await _context.Mmc.FirstOrDefaultAsync(m => m.Id == id);
if(mmc == null)
{
return NotFound();
}
return View(mmc);
return NotFound();
}
// POST: Admin/Mmc/Delete/5
[HttpPost, ActionName("Delete"), ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
return View(mmc);
}
// GET: Admin/Mmc/Delete/5
public async Task<IActionResult> Delete(int? id)
{
if(id == null)
{
Mmc mmc = await _context.Mmc.FindAsync(id);
MmcFeatures feature = await _context.MmcFeatures.FirstOrDefaultAsync(f => f.Id == mmc.FeaturesId);
_context.MmcFeatures.Remove(feature);
_context.Mmc.Remove(mmc);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
return NotFound();
}
public async Task<IActionResult> Clean()
{
_context.Mmc.RemoveRange(_context.Mmc.Where(m => m.FeaturesId == null && m.ModeSense2AData == null));
await _context.SaveChangesAsync();
Mmc mmc = await _context.Mmc.FirstOrDefaultAsync(m => m.Id == id);
return RedirectToAction(nameof(Index));
if(mmc == null)
{
return NotFound();
}
return View(mmc);
}
// POST: Admin/Mmc/Delete/5
[HttpPost, ActionName("Delete"), ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
Mmc mmc = await _context.Mmc.FindAsync(id);
MmcFeatures feature = await _context.MmcFeatures.FirstOrDefaultAsync(f => f.Id == mmc.FeaturesId);
_context.MmcFeatures.Remove(feature);
_context.Mmc.Remove(mmc);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
public async Task<IActionResult> Clean()
{
_context.Mmc.RemoveRange(_context.Mmc.Where(m => m.FeaturesId == null && m.ModeSense2AData == null));
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
}

View File

@@ -5,34 +5,33 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespace Aaru.Server.Areas.Admin.Controllers
namespace Aaru.Server.Areas.Admin.Controllers;
[Area("Admin"), Authorize]
public sealed class MmcFeaturesController : Controller
{
[Area("Admin"), Authorize]
public sealed class MmcFeaturesController : Controller
readonly AaruServerContext _context;
public MmcFeaturesController(AaruServerContext context) => _context = context;
// GET: Admin/MmcFeatures
public async Task<IActionResult> Index() => View(await _context.MmcFeatures.ToListAsync());
// GET: Admin/MmcFeatures/Details/5
public async Task<IActionResult> Details(int? id)
{
readonly AaruServerContext _context;
public MmcFeaturesController(AaruServerContext context) => _context = context;
// GET: Admin/MmcFeatures
public async Task<IActionResult> Index() => View(await _context.MmcFeatures.ToListAsync());
// GET: Admin/MmcFeatures/Details/5
public async Task<IActionResult> Details(int? id)
if(id == null)
{
if(id == null)
{
return NotFound();
}
MmcFeatures mmcFeatures = await _context.MmcFeatures.FirstOrDefaultAsync(m => m.Id == id);
if(mmcFeatures == null)
{
return NotFound();
}
return View(mmcFeatures);
return NotFound();
}
MmcFeatures mmcFeatures = await _context.MmcFeatures.FirstOrDefaultAsync(m => m.Id == id);
if(mmcFeatures == null)
{
return NotFound();
}
return View(mmcFeatures);
}
}

View File

@@ -5,63 +5,62 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespace Aaru.Server.Areas.Admin.Controllers
namespace Aaru.Server.Areas.Admin.Controllers;
[Area("Admin"), Authorize]
public sealed class MmcSdsController : Controller
{
[Area("Admin"), Authorize]
public sealed class MmcSdsController : Controller
readonly AaruServerContext _context;
public MmcSdsController(AaruServerContext context) => _context = context;
// GET: Admin/MmcSds
public async Task<IActionResult> Index() => View(await _context.MmcSd.ToListAsync());
// GET: Admin/MmcSds/Details/5
public async Task<IActionResult> Details(int? id)
{
readonly AaruServerContext _context;
public MmcSdsController(AaruServerContext context) => _context = context;
// GET: Admin/MmcSds
public async Task<IActionResult> Index() => View(await _context.MmcSd.ToListAsync());
// GET: Admin/MmcSds/Details/5
public async Task<IActionResult> Details(int? id)
if(id == null)
{
if(id == null)
{
return NotFound();
}
MmcSd mmcSd = await _context.MmcSd.FirstOrDefaultAsync(m => m.Id == id);
if(mmcSd == null)
{
return NotFound();
}
return View(mmcSd);
return NotFound();
}
// GET: Admin/MmcSds/Delete/5
public async Task<IActionResult> Delete(int? id)
MmcSd mmcSd = await _context.MmcSd.FirstOrDefaultAsync(m => m.Id == id);
if(mmcSd == null)
{
if(id == null)
{
return NotFound();
}
MmcSd mmcSd = await _context.MmcSd.FirstOrDefaultAsync(m => m.Id == id);
if(mmcSd == null)
{
return NotFound();
}
return View(mmcSd);
return NotFound();
}
// POST: Admin/MmcSds/Delete/5
[HttpPost, ActionName("Delete"), ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
MmcSd mmcSd = await _context.MmcSd.FindAsync(id);
_context.MmcSd.Remove(mmcSd);
await _context.SaveChangesAsync();
return View(mmcSd);
}
return RedirectToAction(nameof(Index));
// GET: Admin/MmcSds/Delete/5
public async Task<IActionResult> Delete(int? id)
{
if(id == null)
{
return NotFound();
}
MmcSd mmcSd = await _context.MmcSd.FirstOrDefaultAsync(m => m.Id == id);
if(mmcSd == null)
{
return NotFound();
}
return View(mmcSd);
}
// POST: Admin/MmcSds/Delete/5
[HttpPost, ActionName("Delete"), ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
MmcSd mmcSd = await _context.MmcSd.FindAsync(id);
_context.MmcSd.Remove(mmcSd);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
}

View File

@@ -5,17 +5,16 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespace Aaru.Server.Areas.Admin.Controllers
namespace Aaru.Server.Areas.Admin.Controllers;
[Area("Admin"), Authorize]
public sealed class OperatingSystemsController : Controller
{
[Area("Admin"), Authorize]
public sealed class OperatingSystemsController : Controller
{
readonly AaruServerContext _context;
readonly AaruServerContext _context;
public OperatingSystemsController(AaruServerContext context) => _context = context;
public OperatingSystemsController(AaruServerContext context) => _context = context;
// GET: Admin/OperatingSystems
public async Task<IActionResult> Index() =>
View(await _context.OperatingSystems.OrderBy(o => o.Name).ThenBy(o => o.Version).ToListAsync());
}
// GET: Admin/OperatingSystems
public async Task<IActionResult> Index() =>
View(await _context.OperatingSystems.OrderBy(o => o.Name).ThenBy(o => o.Version).ToListAsync());
}

View File

@@ -5,16 +5,15 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespace Aaru.Server.Areas.Admin.Controllers
namespace Aaru.Server.Areas.Admin.Controllers;
[Area("Admin"), Authorize]
public sealed class PartitionsController : Controller
{
[Area("Admin"), Authorize]
public sealed class PartitionsController : Controller
{
readonly AaruServerContext _context;
readonly AaruServerContext _context;
public PartitionsController(AaruServerContext context) => _context = context;
public PartitionsController(AaruServerContext context) => _context = context;
// GET: Admin/Partitions
public async Task<IActionResult> Index() => View(await _context.Partitions.OrderBy(p => p.Name).ToListAsync());
}
// GET: Admin/Partitions
public async Task<IActionResult> Index() => View(await _context.Partitions.OrderBy(p => p.Name).ToListAsync());
}

View File

@@ -5,45 +5,44 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespace Aaru.Server.Areas.Admin.Controllers
namespace Aaru.Server.Areas.Admin.Controllers;
[Area("Admin"), Authorize]
public sealed class PcmciasController : Controller
{
[Area("Admin"), Authorize]
public sealed class PcmciasController : Controller
readonly AaruServerContext _context;
public PcmciasController(AaruServerContext context) => _context = context;
// GET: Admin/Pcmcias
public async Task<IActionResult> Index() => View(await _context.Pcmcia.ToListAsync());
// GET: Admin/Pcmcias/Delete/5
public async Task<IActionResult> Delete(int? id)
{
readonly AaruServerContext _context;
public PcmciasController(AaruServerContext context) => _context = context;
// GET: Admin/Pcmcias
public async Task<IActionResult> Index() => View(await _context.Pcmcia.ToListAsync());
// GET: Admin/Pcmcias/Delete/5
public async Task<IActionResult> Delete(int? id)
if(id == null)
{
if(id == null)
{
return NotFound();
}
Pcmcia pcmcia = await _context.Pcmcia.FirstOrDefaultAsync(m => m.Id == id);
if(pcmcia == null)
{
return NotFound();
}
return View(pcmcia);
return NotFound();
}
// POST: Admin/Pcmcias/Delete/5
[HttpPost, ActionName("Delete"), ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
Pcmcia pcmcia = await _context.Pcmcia.FindAsync(id);
_context.Pcmcia.Remove(pcmcia);
await _context.SaveChangesAsync();
Pcmcia pcmcia = await _context.Pcmcia.FirstOrDefaultAsync(m => m.Id == id);
return RedirectToAction(nameof(Index));
if(pcmcia == null)
{
return NotFound();
}
return View(pcmcia);
}
// POST: Admin/Pcmcias/Delete/5
[HttpPost, ActionName("Delete"), ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
Pcmcia pcmcia = await _context.Pcmcia.FindAsync(id);
_context.Pcmcia.Remove(pcmcia);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
}

View File

@@ -7,295 +7,294 @@ using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;
namespace Aaru.Server.Areas.Admin.Controllers
namespace Aaru.Server.Areas.Admin.Controllers;
[Area("Admin"), Authorize]
public sealed class ReportsController : Controller
{
[Area("Admin"), Authorize]
public sealed class ReportsController : Controller
readonly AaruServerContext _context;
public ReportsController(AaruServerContext context) => _context = context;
// GET: Admin/Reports
public async Task<IActionResult> Index() => View(await _context.Reports.OrderBy(r => r.Manufacturer).
ThenBy(r => r.Model).ThenBy(r => r.Revision).
ThenBy(r => r.CompactFlash).ThenBy(r => r.Type).
ToListAsync());
// GET: Admin/Reports/Details/5
public async Task<IActionResult> Details(int? id)
{
readonly AaruServerContext _context;
public ReportsController(AaruServerContext context) => _context = context;
// GET: Admin/Reports
public async Task<IActionResult> Index() => View(await _context.Reports.OrderBy(r => r.Manufacturer).
ThenBy(r => r.Model).ThenBy(r => r.Revision).
ThenBy(r => r.CompactFlash).ThenBy(r => r.Type).
ToListAsync());
// GET: Admin/Reports/Details/5
public async Task<IActionResult> Details(int? id)
if(id == null)
{
if(id == null)
{
return NotFound();
}
var model = new UploadedReportDetails
{
Report = await _context.Reports.FirstOrDefaultAsync(m => m.Id == id)
};
if(model.Report is null)
{
return NotFound();
}
model.ReportAll = _context.Devices.
Where(d => d.Manufacturer == model.Report.Manufacturer &&
d.Model == model.Report.Model && d.Revision == model.Report.Revision).
Select(d => d.Id).ToList();
model.ReportButManufacturer = _context.Devices.
Where(d => d.Model == model.Report.Model &&
d.Revision == model.Report.Revision).Select(d => d.Id).
Where(d => model.ReportAll.All(r => r != d)).ToList();
model.SameAll = _context.Reports.
Where(d => d.Manufacturer == model.Report.Manufacturer &&
d.Model == model.Report.Model && d.Revision == model.Report.Revision &&
d.Id != id).Select(d => d.Id).ToList();
model.SameButManufacturer = _context.Reports.
Where(d => d.Model == model.Report.Model &&
d.Revision == model.Report.Revision && d.Id != id).
Select(d => d.Id).Where(d => model.SameAll.All(r => r != d)).ToList();
model.ReadCapabilitiesId =
model.Report.ATA?.ReadCapabilities?.Id ?? model.Report.SCSI?.ReadCapabilities?.Id ?? 0;
// So we can check, as we know IDs with 0 will never exist, and EFCore does not allow null propagation in the LINQ
int ataId = model.Report.ATA?.Id ?? 0;
int atapiId = model.Report.ATAPI?.Id ?? 0;
int scsiId = model.Report.SCSI?.Id ?? 0;
int mmcId = model.Report.SCSI?.MultiMediaDevice?.Id ?? 0;
int sscId = model.Report.SCSI?.SequentialDevice?.Id ?? 0;
model.TestedMedias = _context.TestedMedia.
Where(t => t.AtaId == ataId || t.AtaId == atapiId || t.ScsiId == scsiId ||
t.MmcId == mmcId).OrderBy(t => t.Manufacturer).
ThenBy(t => t.Model).ThenBy(t => t.MediumTypeName).ToList();
model.TestedSequentialMedias = _context.TestedSequentialMedia.Where(t => t.SscId == sscId).
OrderBy(t => t.Manufacturer).ThenBy(t => t.Model).
ThenBy(t => t.MediumTypeName).ToList();
return View(model);
return NotFound();
}
// GET: Admin/Reports/Edit/5
public async Task<IActionResult> Edit(int? id)
var model = new UploadedReportDetails
{
if(id == null)
{
return NotFound();
}
Report = await _context.Reports.FirstOrDefaultAsync(m => m.Id == id)
};
UploadedReport uploadedReport = await _context.Reports.FindAsync(id);
if(uploadedReport == null)
{
return NotFound();
}
return View(uploadedReport);
if(model.Report is null)
{
return NotFound();
}
// POST: Admin/Reports/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost, ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Id,CompactFlash,Manufacturer,Model,Revision,Type")]
UploadedReport changedModel)
model.ReportAll = _context.Devices.
Where(d => d.Manufacturer == model.Report.Manufacturer &&
d.Model == model.Report.Model && d.Revision == model.Report.Revision).
Select(d => d.Id).ToList();
model.ReportButManufacturer = _context.Devices.
Where(d => d.Model == model.Report.Model &&
d.Revision == model.Report.Revision).Select(d => d.Id).
Where(d => model.ReportAll.All(r => r != d)).ToList();
model.SameAll = _context.Reports.
Where(d => d.Manufacturer == model.Report.Manufacturer &&
d.Model == model.Report.Model && d.Revision == model.Report.Revision &&
d.Id != id).Select(d => d.Id).ToList();
model.SameButManufacturer = _context.Reports.
Where(d => d.Model == model.Report.Model &&
d.Revision == model.Report.Revision && d.Id != id).
Select(d => d.Id).Where(d => model.SameAll.All(r => r != d)).ToList();
model.ReadCapabilitiesId =
model.Report.ATA?.ReadCapabilities?.Id ?? model.Report.SCSI?.ReadCapabilities?.Id ?? 0;
// So we can check, as we know IDs with 0 will never exist, and EFCore does not allow null propagation in the LINQ
int ataId = model.Report.ATA?.Id ?? 0;
int atapiId = model.Report.ATAPI?.Id ?? 0;
int scsiId = model.Report.SCSI?.Id ?? 0;
int mmcId = model.Report.SCSI?.MultiMediaDevice?.Id ?? 0;
int sscId = model.Report.SCSI?.SequentialDevice?.Id ?? 0;
model.TestedMedias = _context.TestedMedia.
Where(t => t.AtaId == ataId || t.AtaId == atapiId || t.ScsiId == scsiId ||
t.MmcId == mmcId).OrderBy(t => t.Manufacturer).
ThenBy(t => t.Model).ThenBy(t => t.MediumTypeName).ToList();
model.TestedSequentialMedias = _context.TestedSequentialMedia.Where(t => t.SscId == sscId).
OrderBy(t => t.Manufacturer).ThenBy(t => t.Model).
ThenBy(t => t.MediumTypeName).ToList();
return View(model);
}
// GET: Admin/Reports/Edit/5
public async Task<IActionResult> Edit(int? id)
{
if(id == null)
{
if(id != changedModel.Id)
return NotFound();
if(!ModelState.IsValid)
return View(changedModel);
UploadedReport model = await _context.Reports.FirstOrDefaultAsync(m => m.Id == id);
if(model is null)
return NotFound();
model.CompactFlash = changedModel.CompactFlash;
model.Manufacturer = changedModel.Manufacturer;
model.Model = changedModel.Model;
model.Revision = changedModel.Revision;
model.Type = changedModel.Type;
try
{
_context.Update(model);
await _context.SaveChangesAsync();
}
catch(DbUpdateConcurrencyException)
{
ModelState.AddModelError("Concurrency", "Concurrency error, please report to the administrator.");
}
return RedirectToAction(nameof(Index));
return NotFound();
}
// GET: Admin/Reports/Delete/5
public async Task<IActionResult> Delete(int? id)
UploadedReport uploadedReport = await _context.Reports.FindAsync(id);
if(uploadedReport == null)
{
if(id == null)
{
return NotFound();
}
UploadedReport uploadedReport = await _context.Reports.FirstOrDefaultAsync(m => m.Id == id);
if(uploadedReport == null)
{
return NotFound();
}
return View(uploadedReport);
return NotFound();
}
// POST: Admin/Reports/Delete/5
[HttpPost, ActionName("Delete"), ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
return View(uploadedReport);
}
// POST: Admin/Reports/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost, ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Id,CompactFlash,Manufacturer,Model,Revision,Type")]
UploadedReport changedModel)
{
if(id != changedModel.Id)
return NotFound();
if(!ModelState.IsValid)
return View(changedModel);
UploadedReport model = await _context.Reports.FirstOrDefaultAsync(m => m.Id == id);
if(model is null)
return NotFound();
model.CompactFlash = changedModel.CompactFlash;
model.Manufacturer = changedModel.Manufacturer;
model.Model = changedModel.Model;
model.Revision = changedModel.Revision;
model.Type = changedModel.Type;
try
{
UploadedReport uploadedReport = await _context.Reports.FindAsync(id);
_context.Reports.Remove(uploadedReport);
_context.Update(model);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
catch(DbUpdateConcurrencyException)
{
ModelState.AddModelError("Concurrency", "Concurrency error, please report to the administrator.");
}
public IActionResult Promote(int? id)
return RedirectToAction(nameof(Index));
}
// GET: Admin/Reports/Delete/5
public async Task<IActionResult> Delete(int? id)
{
if(id == null)
{
if(id == null)
{
return NotFound();
}
UploadedReport uploadedReport = _context.Reports.FirstOrDefault(m => m.Id == id);
if(uploadedReport == null)
{
return NotFound();
}
var device = new Device(uploadedReport.ATAId, uploadedReport.ATAPIId, uploadedReport.FireWireId,
uploadedReport.MultiMediaCardId, uploadedReport.PCMCIAId,
uploadedReport.SecureDigitalId, uploadedReport.SCSIId, uploadedReport.USBId,
uploadedReport.UploadedWhen, uploadedReport.Manufacturer, uploadedReport.Model,
uploadedReport.Revision, uploadedReport.CompactFlash, uploadedReport.Type,
uploadedReport.GdRomSwapDiscCapabilitiesId);
EntityEntry<Device> res = _context.Devices.Add(device);
_context.Reports.Remove(uploadedReport);
_context.SaveChanges();
return RedirectToAction(nameof(DevicesController.Details), "Devices", new
{
id = res.Entity.Id
});
return NotFound();
}
public IActionResult Merge(int? master, int? slave)
UploadedReport uploadedReport = await _context.Reports.FirstOrDefaultAsync(m => m.Id == id);
if(uploadedReport == null)
{
if(master is null ||
slave is null)
return NotFound();
return NotFound();
}
UploadedReport masterReport = _context.Reports.FirstOrDefault(m => m.Id == master);
UploadedReport slaveReport = _context.Reports.FirstOrDefault(m => m.Id == slave);
return View(uploadedReport);
}
if(masterReport is null ||
slaveReport is null)
return NotFound();
// POST: Admin/Reports/Delete/5
[HttpPost, ActionName("Delete"), ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
UploadedReport uploadedReport = await _context.Reports.FindAsync(id);
_context.Reports.Remove(uploadedReport);
await _context.SaveChangesAsync();
if(masterReport.ATAId != null &&
masterReport.ATAId != slaveReport.ATAId)
{
foreach(TestedMedia testedMedia in _context.TestedMedia.Where(d => d.AtaId == slaveReport.ATAId))
{
testedMedia.AtaId = masterReport.ATAId;
_context.Update(testedMedia);
}
}
else if(masterReport.ATAId == null &&
slaveReport.ATAId != null)
{
masterReport.ATAId = slaveReport.ATAId;
_context.Update(masterReport);
}
return RedirectToAction(nameof(Index));
}
if(masterReport.ATAPIId != null &&
masterReport.ATAPIId != slaveReport.ATAPIId)
{
foreach(TestedMedia testedMedia in _context.TestedMedia.Where(d => d.AtaId == slaveReport.ATAPIId))
{
testedMedia.AtaId = masterReport.ATAPIId;
_context.Update(testedMedia);
}
}
else if(masterReport.ATAPIId == null &&
slaveReport.ATAPIId != null)
{
masterReport.ATAPIId = slaveReport.ATAPIId;
_context.Update(masterReport);
}
public IActionResult Promote(int? id)
{
if(id == null)
{
return NotFound();
}
if(masterReport.SCSIId != null &&
masterReport.SCSIId != slaveReport.SCSIId)
{
foreach(TestedMedia testedMedia in _context.TestedMedia.Where(d => d.ScsiId == slaveReport.SCSIId))
{
testedMedia.ScsiId = masterReport.SCSIId;
_context.Update(testedMedia);
}
}
else if(masterReport.SCSIId == null &&
slaveReport.SCSIId != null)
{
masterReport.SCSIId = slaveReport.SCSIId;
_context.Update(masterReport);
}
UploadedReport uploadedReport = _context.Reports.FirstOrDefault(m => m.Id == id);
if(masterReport.SCSI?.SequentialDeviceId != null &&
masterReport.SCSI?.SequentialDeviceId != slaveReport.SCSI?.SequentialDeviceId)
if(uploadedReport == null)
{
return NotFound();
}
var device = new Device(uploadedReport.ATAId, uploadedReport.ATAPIId, uploadedReport.FireWireId,
uploadedReport.MultiMediaCardId, uploadedReport.PCMCIAId,
uploadedReport.SecureDigitalId, uploadedReport.SCSIId, uploadedReport.USBId,
uploadedReport.UploadedWhen, uploadedReport.Manufacturer, uploadedReport.Model,
uploadedReport.Revision, uploadedReport.CompactFlash, uploadedReport.Type,
uploadedReport.GdRomSwapDiscCapabilitiesId);
EntityEntry<Device> res = _context.Devices.Add(device);
_context.Reports.Remove(uploadedReport);
_context.SaveChanges();
return RedirectToAction(nameof(DevicesController.Details), "Devices", new
{
id = res.Entity.Id
});
}
public IActionResult Merge(int? master, int? slave)
{
if(master is null ||
slave is null)
return NotFound();
UploadedReport masterReport = _context.Reports.FirstOrDefault(m => m.Id == master);
UploadedReport slaveReport = _context.Reports.FirstOrDefault(m => m.Id == slave);
if(masterReport is null ||
slaveReport is null)
return NotFound();
if(masterReport.ATAId != null &&
masterReport.ATAId != slaveReport.ATAId)
{
foreach(TestedMedia testedMedia in _context.TestedMedia.Where(d => d.AtaId == slaveReport.ATAId))
{
foreach(TestedSequentialMedia testedMedia in
testedMedia.AtaId = masterReport.ATAId;
_context.Update(testedMedia);
}
}
else if(masterReport.ATAId == null &&
slaveReport.ATAId != null)
{
masterReport.ATAId = slaveReport.ATAId;
_context.Update(masterReport);
}
if(masterReport.ATAPIId != null &&
masterReport.ATAPIId != slaveReport.ATAPIId)
{
foreach(TestedMedia testedMedia in _context.TestedMedia.Where(d => d.AtaId == slaveReport.ATAPIId))
{
testedMedia.AtaId = masterReport.ATAPIId;
_context.Update(testedMedia);
}
}
else if(masterReport.ATAPIId == null &&
slaveReport.ATAPIId != null)
{
masterReport.ATAPIId = slaveReport.ATAPIId;
_context.Update(masterReport);
}
if(masterReport.SCSIId != null &&
masterReport.SCSIId != slaveReport.SCSIId)
{
foreach(TestedMedia testedMedia in _context.TestedMedia.Where(d => d.ScsiId == slaveReport.SCSIId))
{
testedMedia.ScsiId = masterReport.SCSIId;
_context.Update(testedMedia);
}
}
else if(masterReport.SCSIId == null &&
slaveReport.SCSIId != null)
{
masterReport.SCSIId = slaveReport.SCSIId;
_context.Update(masterReport);
}
if(masterReport.SCSI?.SequentialDeviceId != null &&
masterReport.SCSI?.SequentialDeviceId != slaveReport.SCSI?.SequentialDeviceId)
{
foreach(TestedSequentialMedia testedMedia in
_context.TestedSequentialMedia.Where(d => d.SscId == slaveReport.SCSI.SequentialDeviceId))
{
testedMedia.SscId = masterReport.SCSI.SequentialDeviceId;
_context.Update(testedMedia);
}
}
else if(masterReport.SCSI != null &&
masterReport.SCSI?.SequentialDeviceId == null &&
slaveReport.SCSI?.SequentialDeviceId != null)
{
masterReport.SCSI.SequentialDeviceId = slaveReport.SCSI.SequentialDeviceId;
_context.Update(masterReport);
testedMedia.SscId = masterReport.SCSI.SequentialDeviceId;
_context.Update(testedMedia);
}
if(masterReport.GdRomSwapDiscCapabilitiesId == null &&
slaveReport.GdRomSwapDiscCapabilitiesId != null)
{
masterReport.GdRomSwapDiscCapabilitiesId = slaveReport.GdRomSwapDiscCapabilitiesId;
_context.Update(masterReport);
}
else if(masterReport.GdRomSwapDiscCapabilitiesId != null &&
slaveReport.GdRomSwapDiscCapabilitiesId != null)
{
masterReport.GdRomSwapDiscCapabilitiesId = slaveReport.GdRomSwapDiscCapabilitiesId;
_context.Update(masterReport);
}
_context.Remove(slaveReport);
_context.SaveChanges();
return RedirectToAction(nameof(Details), new
{
Id = master
});
}
else if(masterReport.SCSI != null &&
masterReport.SCSI?.SequentialDeviceId == null &&
slaveReport.SCSI?.SequentialDeviceId != null)
{
masterReport.SCSI.SequentialDeviceId = slaveReport.SCSI.SequentialDeviceId;
_context.Update(masterReport);
}
if(masterReport.GdRomSwapDiscCapabilitiesId == null &&
slaveReport.GdRomSwapDiscCapabilitiesId != null)
{
masterReport.GdRomSwapDiscCapabilitiesId = slaveReport.GdRomSwapDiscCapabilitiesId;
_context.Update(masterReport);
}
else if(masterReport.GdRomSwapDiscCapabilitiesId != null &&
slaveReport.GdRomSwapDiscCapabilitiesId != null)
{
masterReport.GdRomSwapDiscCapabilitiesId = slaveReport.GdRomSwapDiscCapabilitiesId;
_context.Update(masterReport);
}
_context.Remove(slaveReport);
_context.SaveChanges();
return RedirectToAction(nameof(Details), new
{
Id = master
});
}
}

View File

@@ -5,45 +5,44 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespace Aaru.Server.Areas.Admin.Controllers
namespace Aaru.Server.Areas.Admin.Controllers;
[Area("Admin"), Authorize]
public sealed class ScsiModesController : Controller
{
[Area("Admin"), Authorize]
public sealed class ScsiModesController : Controller
readonly AaruServerContext _context;
public ScsiModesController(AaruServerContext context) => _context = context;
// GET: Admin/ScsiModes
public async Task<IActionResult> Index() => View(await _context.ScsiMode.ToListAsync());
// GET: Admin/ScsiModes/Delete/5
public async Task<IActionResult> Delete(int? id)
{
readonly AaruServerContext _context;
public ScsiModesController(AaruServerContext context) => _context = context;
// GET: Admin/ScsiModes
public async Task<IActionResult> Index() => View(await _context.ScsiMode.ToListAsync());
// GET: Admin/ScsiModes/Delete/5
public async Task<IActionResult> Delete(int? id)
if(id == null)
{
if(id == null)
{
return NotFound();
}
ScsiMode scsiMode = await _context.ScsiMode.FirstOrDefaultAsync(m => m.Id == id);
if(scsiMode == null)
{
return NotFound();
}
return View(scsiMode);
return NotFound();
}
// POST: Admin/ScsiModes/Delete/5
[HttpPost, ActionName("Delete"), ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
ScsiMode scsiMode = await _context.ScsiMode.FindAsync(id);
_context.ScsiMode.Remove(scsiMode);
await _context.SaveChangesAsync();
ScsiMode scsiMode = await _context.ScsiMode.FirstOrDefaultAsync(m => m.Id == id);
return RedirectToAction(nameof(Index));
if(scsiMode == null)
{
return NotFound();
}
return View(scsiMode);
}
// POST: Admin/ScsiModes/Delete/5
[HttpPost, ActionName("Delete"), ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
ScsiMode scsiMode = await _context.ScsiMode.FindAsync(id);
_context.ScsiMode.Remove(scsiMode);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
}

View File

@@ -5,45 +5,44 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespace Aaru.Server.Areas.Admin.Controllers
namespace Aaru.Server.Areas.Admin.Controllers;
[Area("Admin"), Authorize]
public sealed class ScsiPagesController : Controller
{
[Area("Admin"), Authorize]
public sealed class ScsiPagesController : Controller
readonly AaruServerContext _context;
public ScsiPagesController(AaruServerContext context) => _context = context;
// GET: Admin/ScsiPages
public async Task<IActionResult> Index() => View(await _context.ScsiPage.ToListAsync());
// GET: Admin/ScsiPages/Delete/5
public async Task<IActionResult> Delete(int? id)
{
readonly AaruServerContext _context;
public ScsiPagesController(AaruServerContext context) => _context = context;
// GET: Admin/ScsiPages
public async Task<IActionResult> Index() => View(await _context.ScsiPage.ToListAsync());
// GET: Admin/ScsiPages/Delete/5
public async Task<IActionResult> Delete(int? id)
if(id == null)
{
if(id == null)
{
return NotFound();
}
ScsiPage scsiPage = await _context.ScsiPage.FirstOrDefaultAsync(m => m.Id == id);
if(scsiPage == null)
{
return NotFound();
}
return View(scsiPage);
return NotFound();
}
// POST: Admin/ScsiPages/Delete/5
[HttpPost, ActionName("Delete"), ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
ScsiPage scsiPage = await _context.ScsiPage.FindAsync(id);
_context.ScsiPage.Remove(scsiPage);
await _context.SaveChangesAsync();
ScsiPage scsiPage = await _context.ScsiPage.FirstOrDefaultAsync(m => m.Id == id);
return RedirectToAction(nameof(Index));
if(scsiPage == null)
{
return NotFound();
}
return View(scsiPage);
}
// POST: Admin/ScsiPages/Delete/5
[HttpPost, ActionName("Delete"), ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
ScsiPage scsiPage = await _context.ScsiPage.FindAsync(id);
_context.ScsiPage.Remove(scsiPage);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
}

View File

@@ -14,367 +14,366 @@ using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using TestedMedia = Aaru.CommonTypes.Metadata.TestedMedia;
namespace Aaru.Server.Areas.Admin.Controllers
namespace Aaru.Server.Areas.Admin.Controllers;
[Area("Admin"), Authorize]
public sealed class ScsisController : Controller
{
[Area("Admin"), Authorize]
public sealed class ScsisController : Controller
readonly AaruServerContext _context;
public ScsisController(AaruServerContext context) => _context = context;
// GET: Admin/Scsis
public IActionResult Index() => View(_context.Scsi.AsEnumerable().
OrderBy(m => StringHandlers.CToString(m.Inquiry?.
VendorIdentification)).
ThenBy(m => StringHandlers.CToString(m.Inquiry?.
ProductIdentification)).
ThenBy(m => StringHandlers.CToString(m.Inquiry?.
ProductRevisionLevel)));
// GET: Admin/Scsis/Details/5
public async Task<IActionResult> Details(int? id)
{
readonly AaruServerContext _context;
public ScsisController(AaruServerContext context) => _context = context;
// GET: Admin/Scsis
public IActionResult Index() => View(_context.Scsi.AsEnumerable().
OrderBy(m => StringHandlers.CToString(m.Inquiry?.
VendorIdentification)).
ThenBy(m => StringHandlers.CToString(m.Inquiry?.
ProductIdentification)).
ThenBy(m => StringHandlers.CToString(m.Inquiry?.
ProductRevisionLevel)));
// GET: Admin/Scsis/Details/5
public async Task<IActionResult> Details(int? id)
if(id == null)
{
if(id == null)
{
return NotFound();
}
Scsi scsi = await _context.Scsi.FirstOrDefaultAsync(m => m.Id == id);
if(scsi == null)
{
return NotFound();
}
return View(scsi);
return NotFound();
}
// GET: Admin/Scsis/Delete/5
public async Task<IActionResult> Delete(int? id)
Scsi scsi = await _context.Scsi.FirstOrDefaultAsync(m => m.Id == id);
if(scsi == null)
{
if(id == null)
{
return NotFound();
}
Scsi scsi = await _context.Scsi.FirstOrDefaultAsync(m => m.Id == id);
if(scsi == null)
{
return NotFound();
}
return View(scsi);
return NotFound();
}
// POST: Admin/Scsis/Delete/5
[HttpPost, ActionName("Delete"), ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
Scsi scsi = await _context.Scsi.FindAsync(id);
_context.Scsi.Remove(scsi);
await _context.SaveChangesAsync();
return View(scsi);
}
return RedirectToAction(nameof(Index));
// GET: Admin/Scsis/Delete/5
public async Task<IActionResult> Delete(int? id)
{
if(id == null)
{
return NotFound();
}
public IActionResult Consolidate()
Scsi scsi = await _context.Scsi.FirstOrDefaultAsync(m => m.Id == id);
if(scsi == null)
{
List<IdHashModel> hashes = _context.Scsi.Where(m => m.InquiryData != null).
Select(m => new IdHashModel(m.Id, Hash.Sha512(m.InquiryData))).ToList();
List<IdHashModel> dups = hashes.GroupBy(x => x.Hash).Where(g => g.Count() > 1).
Select(x => hashes.FirstOrDefault(y => y.Hash == x.Key)).ToList();
for(int i = 0; i < dups.Count; i++)
{
Scsi unique = _context.Scsi.First(a => a.Id == dups[i].Id);
dups[i].Description =
$"{StringHandlers.CToString(unique.Inquiry?.VendorIdentification)} {StringHandlers.CToString(unique.Inquiry?.ProductIdentification)}";
dups[i].Duplicates = hashes.Where(h => h.Hash == dups[i].Hash).Skip(1).Select(x => x.Id).ToArray();
}
return View(new IdHashModelForView
{
List = dups,
Json = JsonConvert.SerializeObject(dups)
});
return NotFound();
}
[HttpPost, ActionName("Consolidate"), ValidateAntiForgeryToken]
public IActionResult ConsolidateConfirmed(string models)
return View(scsi);
}
// POST: Admin/Scsis/Delete/5
[HttpPost, ActionName("Delete"), ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
Scsi scsi = await _context.Scsi.FindAsync(id);
_context.Scsi.Remove(scsi);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
public IActionResult Consolidate()
{
List<IdHashModel> hashes = _context.Scsi.Where(m => m.InquiryData != null).
Select(m => new IdHashModel(m.Id, Hash.Sha512(m.InquiryData))).ToList();
List<IdHashModel> dups = hashes.GroupBy(x => x.Hash).Where(g => g.Count() > 1).
Select(x => hashes.FirstOrDefault(y => y.Hash == x.Key)).ToList();
for(int i = 0; i < dups.Count; i++)
{
IdHashModel[] duplicates;
Scsi unique = _context.Scsi.First(a => a.Id == dups[i].Id);
try
dups[i].Description =
$"{StringHandlers.CToString(unique.Inquiry?.VendorIdentification)} {StringHandlers.CToString(unique.Inquiry?.ProductIdentification)}";
dups[i].Duplicates = hashes.Where(h => h.Hash == dups[i].Hash).Skip(1).Select(x => x.Id).ToArray();
}
return View(new IdHashModelForView
{
List = dups,
Json = JsonConvert.SerializeObject(dups)
});
}
[HttpPost, ActionName("Consolidate"), ValidateAntiForgeryToken]
public IActionResult ConsolidateConfirmed(string models)
{
IdHashModel[] duplicates;
try
{
duplicates = JsonConvert.DeserializeObject<IdHashModel[]>(models);
}
catch(JsonSerializationException)
{
return BadRequest();
}
if(duplicates is null)
return BadRequest();
foreach(IdHashModel duplicate in duplicates)
{
Scsi master = _context.Scsi.FirstOrDefault(m => m.Id == duplicate.Id);
if(master is null)
continue;
foreach(int duplicateId in duplicate.Duplicates)
{
duplicates = JsonConvert.DeserializeObject<IdHashModel[]>(models);
}
catch(JsonSerializationException)
{
return BadRequest();
}
Scsi slave = _context.Scsi.FirstOrDefault(m => m.Id == duplicateId);
if(duplicates is null)
return BadRequest();
foreach(IdHashModel duplicate in duplicates)
{
Scsi master = _context.Scsi.FirstOrDefault(m => m.Id == duplicate.Id);
if(master is null)
if(slave is null)
continue;
foreach(int duplicateId in duplicate.Duplicates)
foreach(Device scsiDevice in _context.Devices.Where(d => d.SCSI.Id == duplicateId))
{
Scsi slave = _context.Scsi.FirstOrDefault(m => m.Id == duplicateId);
if(slave is null)
continue;
foreach(Device scsiDevice in _context.Devices.Where(d => d.SCSI.Id == duplicateId))
{
scsiDevice.SCSI = master;
}
foreach(UploadedReport scsiReport in _context.Reports.Where(d => d.SCSI.Id == duplicateId))
{
scsiReport.SCSI = master;
}
foreach(TestedMedia testedMedia in _context.TestedMedia.Where(d => d.ScsiId == duplicateId))
{
testedMedia.ScsiId = duplicate.Id;
_context.Update(testedMedia);
}
if(master.ReadCapabilities is null &&
slave.ReadCapabilities != null)
master.ReadCapabilities = slave.ReadCapabilities;
_context.Scsi.Remove(slave);
scsiDevice.SCSI = master;
}
foreach(UploadedReport scsiReport in _context.Reports.Where(d => d.SCSI.Id == duplicateId))
{
scsiReport.SCSI = master;
}
foreach(TestedMedia testedMedia in _context.TestedMedia.Where(d => d.ScsiId == duplicateId))
{
testedMedia.ScsiId = duplicate.Id;
_context.Update(testedMedia);
}
if(master.ReadCapabilities is null &&
slave.ReadCapabilities != null)
master.ReadCapabilities = slave.ReadCapabilities;
_context.Scsi.Remove(slave);
}
_context.SaveChanges();
return RedirectToAction(nameof(Index));
}
public IActionResult Compare(int id, int rightId)
_context.SaveChanges();
return RedirectToAction(nameof(Index));
}
public IActionResult Compare(int id, int rightId)
{
var model = new CompareModel
{
var model = new CompareModel
{
LeftId = id,
RightId = rightId
};
LeftId = id,
RightId = rightId
};
Scsi left = _context.Scsi.FirstOrDefault(l => l.Id == id);
Scsi right = _context.Scsi.FirstOrDefault(r => r.Id == rightId);
Scsi left = _context.Scsi.FirstOrDefault(l => l.Id == id);
Scsi right = _context.Scsi.FirstOrDefault(r => r.Id == rightId);
if(left is null)
{
model.ErrorMessage = $"SCSI with id {id} has not been found";
model.HasError = true;
return View(model);
}
if(right is null)
{
model.ErrorMessage = $"SCSI with id {rightId} has not been found";
model.HasError = true;
return View(model);
}
Inquiry? leftNullable = left.Inquiry;
Inquiry? rightNullable = right.Inquiry;
model.ValueNames = new List<string>();
model.LeftValues = new List<string>();
model.RightValues = new List<string>();
if(!leftNullable.HasValue &&
!rightNullable.HasValue)
{
model.AreEqual = true;
return View(model);
}
if(leftNullable.HasValue &&
!rightNullable.HasValue)
{
model.ValueNames.Add("Decoded");
model.LeftValues.Add("decoded");
model.RightValues.Add("null");
return View(model);
}
if(!leftNullable.HasValue)
{
model.ValueNames.Add("Decoded");
model.LeftValues.Add("null");
model.RightValues.Add("decoded");
return View(model);
}
Inquiry leftValue = left.Inquiry.Value;
Inquiry rightValue = right.Inquiry.Value;
foreach(FieldInfo fieldInfo in leftValue.GetType().GetFields())
{
object lv = fieldInfo.GetValue(leftValue);
object rv = fieldInfo.GetValue(rightValue);
if(fieldInfo.FieldType.IsArray)
{
var la = lv as Array;
var ra = rv as Array;
switch(la)
{
case null when ra is null: continue;
case null:
model.ValueNames.Add(fieldInfo.Name);
model.LeftValues.Add("null");
model.RightValues.Add("[]");
continue;
}
if(ra is null)
{
model.ValueNames.Add(fieldInfo.Name);
model.LeftValues.Add("[]");
model.RightValues.Add("null");
continue;
}
List<object> ll = la.Cast<object>().ToList();
List<object> rl = ra.Cast<object>().ToList();
for(int i = 0; i < ll.Count; i++)
{
if(ll[i].Equals(rl[i]))
continue;
switch(fieldInfo.Name)
{
case nameof(Inquiry.KreonIdentifier):
case nameof(Inquiry.ProductIdentification):
case nameof(Inquiry.ProductRevisionLevel):
case nameof(Inquiry.Qt_ModuleRevision):
case nameof(Inquiry.Seagate_Copyright):
case nameof(Inquiry.Seagate_DriveSerialNumber):
case nameof(Inquiry.Seagate_ServoPROMPartNo):
case nameof(Inquiry.VendorIdentification):
byte[] lb = new byte[ll.Count];
byte[] rb = new byte[rl.Count];
for(int j = 0; j < ll.Count; j++)
lb[j] = (byte)ll[j];
for(int j = 0; j < ll.Count; j++)
rb[j] = (byte)rl[j];
model.ValueNames.Add(fieldInfo.Name);
model.LeftValues.Add($"{StringHandlers.CToString(lb) ?? "<null>"}");
model.RightValues.Add($"{StringHandlers.CToString(rb) ?? "<null>"}");
break;
default:
model.ValueNames.Add(fieldInfo.Name);
model.LeftValues.Add("[]");
model.RightValues.Add("[]");
break;
}
break;
}
}
else if(lv == null &&
rv == null) {}
else if(lv != null &&
rv == null)
{
model.ValueNames.Add(fieldInfo.Name);
model.LeftValues.Add($"{lv}");
model.RightValues.Add("null");
}
else if(lv == null)
{
model.ValueNames.Add(fieldInfo.Name);
model.LeftValues.Add("null");
model.RightValues.Add($"{rv}");
}
else if(!lv.Equals(rv))
{
model.ValueNames.Add(fieldInfo.Name);
model.LeftValues.Add($"{lv}");
model.RightValues.Add($"{rv}");
}
}
model.AreEqual = model.LeftValues.Count == 0 && model.RightValues.Count == 0;
if(left is null)
{
model.ErrorMessage = $"SCSI with id {id} has not been found";
model.HasError = true;
return View(model);
}
public IActionResult ConsolidateWithIds(int masterId, int slaveId)
if(right is null)
{
Scsi master = _context.Scsi.FirstOrDefault(m => m.Id == masterId);
model.ErrorMessage = $"SCSI with id {rightId} has not been found";
model.HasError = true;
if(master is null)
return RedirectToAction(nameof(Compare), new
{
id = masterId,
rightId = slaveId
});
Scsi slave = _context.Scsi.FirstOrDefault(m => m.Id == slaveId);
if(slave is null)
return RedirectToAction(nameof(Compare), new
{
id = masterId,
rightId = slaveId
});
foreach(Device scsiDevice in _context.Devices.Where(d => d.SCSI.Id == slaveId))
{
scsiDevice.SCSI = master;
}
foreach(UploadedReport scsiReport in _context.Reports.Where(d => d.SCSI.Id == slaveId))
{
scsiReport.SCSI = master;
}
foreach(TestedMedia testedMedia in _context.TestedMedia.Where(d => d.ScsiId == slaveId))
{
testedMedia.ScsiId = masterId;
_context.Update(testedMedia);
}
if(master.ReadCapabilities is null &&
slave.ReadCapabilities != null)
master.ReadCapabilities = slave.ReadCapabilities;
_context.Scsi.Remove(slave);
_context.SaveChanges();
return RedirectToAction(nameof(Index));
return View(model);
}
Inquiry? leftNullable = left.Inquiry;
Inquiry? rightNullable = right.Inquiry;
model.ValueNames = new List<string>();
model.LeftValues = new List<string>();
model.RightValues = new List<string>();
if(!leftNullable.HasValue &&
!rightNullable.HasValue)
{
model.AreEqual = true;
return View(model);
}
if(leftNullable.HasValue &&
!rightNullable.HasValue)
{
model.ValueNames.Add("Decoded");
model.LeftValues.Add("decoded");
model.RightValues.Add("null");
return View(model);
}
if(!leftNullable.HasValue)
{
model.ValueNames.Add("Decoded");
model.LeftValues.Add("null");
model.RightValues.Add("decoded");
return View(model);
}
Inquiry leftValue = left.Inquiry.Value;
Inquiry rightValue = right.Inquiry.Value;
foreach(FieldInfo fieldInfo in leftValue.GetType().GetFields())
{
object lv = fieldInfo.GetValue(leftValue);
object rv = fieldInfo.GetValue(rightValue);
if(fieldInfo.FieldType.IsArray)
{
var la = lv as Array;
var ra = rv as Array;
switch(la)
{
case null when ra is null: continue;
case null:
model.ValueNames.Add(fieldInfo.Name);
model.LeftValues.Add("null");
model.RightValues.Add("[]");
continue;
}
if(ra is null)
{
model.ValueNames.Add(fieldInfo.Name);
model.LeftValues.Add("[]");
model.RightValues.Add("null");
continue;
}
List<object> ll = la.Cast<object>().ToList();
List<object> rl = ra.Cast<object>().ToList();
for(int i = 0; i < ll.Count; i++)
{
if(ll[i].Equals(rl[i]))
continue;
switch(fieldInfo.Name)
{
case nameof(Inquiry.KreonIdentifier):
case nameof(Inquiry.ProductIdentification):
case nameof(Inquiry.ProductRevisionLevel):
case nameof(Inquiry.Qt_ModuleRevision):
case nameof(Inquiry.Seagate_Copyright):
case nameof(Inquiry.Seagate_DriveSerialNumber):
case nameof(Inquiry.Seagate_ServoPROMPartNo):
case nameof(Inquiry.VendorIdentification):
byte[] lb = new byte[ll.Count];
byte[] rb = new byte[rl.Count];
for(int j = 0; j < ll.Count; j++)
lb[j] = (byte)ll[j];
for(int j = 0; j < ll.Count; j++)
rb[j] = (byte)rl[j];
model.ValueNames.Add(fieldInfo.Name);
model.LeftValues.Add($"{StringHandlers.CToString(lb) ?? "<null>"}");
model.RightValues.Add($"{StringHandlers.CToString(rb) ?? "<null>"}");
break;
default:
model.ValueNames.Add(fieldInfo.Name);
model.LeftValues.Add("[]");
model.RightValues.Add("[]");
break;
}
break;
}
}
else if(lv == null &&
rv == null) {}
else if(lv != null &&
rv == null)
{
model.ValueNames.Add(fieldInfo.Name);
model.LeftValues.Add($"{lv}");
model.RightValues.Add("null");
}
else if(lv == null)
{
model.ValueNames.Add(fieldInfo.Name);
model.LeftValues.Add("null");
model.RightValues.Add($"{rv}");
}
else if(!lv.Equals(rv))
{
model.ValueNames.Add(fieldInfo.Name);
model.LeftValues.Add($"{lv}");
model.RightValues.Add($"{rv}");
}
}
model.AreEqual = model.LeftValues.Count == 0 && model.RightValues.Count == 0;
return View(model);
}
public IActionResult ConsolidateWithIds(int masterId, int slaveId)
{
Scsi master = _context.Scsi.FirstOrDefault(m => m.Id == masterId);
if(master is null)
return RedirectToAction(nameof(Compare), new
{
id = masterId,
rightId = slaveId
});
Scsi slave = _context.Scsi.FirstOrDefault(m => m.Id == slaveId);
if(slave is null)
return RedirectToAction(nameof(Compare), new
{
id = masterId,
rightId = slaveId
});
foreach(Device scsiDevice in _context.Devices.Where(d => d.SCSI.Id == slaveId))
{
scsiDevice.SCSI = master;
}
foreach(UploadedReport scsiReport in _context.Reports.Where(d => d.SCSI.Id == slaveId))
{
scsiReport.SCSI = master;
}
foreach(TestedMedia testedMedia in _context.TestedMedia.Where(d => d.ScsiId == slaveId))
{
testedMedia.ScsiId = masterId;
_context.Update(testedMedia);
}
if(master.ReadCapabilities is null &&
slave.ReadCapabilities != null)
master.ReadCapabilities = slave.ReadCapabilities;
_context.Scsi.Remove(slave);
_context.SaveChanges();
return RedirectToAction(nameof(Index));
}
}

View File

@@ -8,116 +8,115 @@ using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
namespace Aaru.Server.Areas.Admin.Controllers
namespace Aaru.Server.Areas.Admin.Controllers;
[Area("Admin"), Authorize]
public sealed class SscsController : Controller
{
[Area("Admin"), Authorize]
public sealed class SscsController : Controller
readonly AaruServerContext _context;
public SscsController(AaruServerContext context) => _context = context;
// GET: Admin/Sscs
public async Task<IActionResult> Index() => View(await _context.Ssc.OrderBy(s => s.MinBlockLength).
ThenBy(s => s.MaxBlockLength).
ThenBy(s => s.BlockSizeGranularity).
ToListAsync());
// GET: Admin/Sscs/Delete/5
public async Task<IActionResult> Delete(int? id)
{
readonly AaruServerContext _context;
public SscsController(AaruServerContext context) => _context = context;
// GET: Admin/Sscs
public async Task<IActionResult> Index() => View(await _context.Ssc.OrderBy(s => s.MinBlockLength).
ThenBy(s => s.MaxBlockLength).
ThenBy(s => s.BlockSizeGranularity).
ToListAsync());
// GET: Admin/Sscs/Delete/5
public async Task<IActionResult> Delete(int? id)
if(id == null)
{
if(id == null)
{
return NotFound();
}
Ssc ssc = await _context.Ssc.FirstOrDefaultAsync(m => m.Id == id);
if(ssc == null)
{
return NotFound();
}
return View(ssc);
return NotFound();
}
// POST: Admin/Sscs/Delete/5
[HttpPost, ActionName("Delete"), ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
Ssc ssc = await _context.Ssc.FindAsync(id);
_context.Ssc.Remove(ssc);
await _context.SaveChangesAsync();
Ssc ssc = await _context.Ssc.FirstOrDefaultAsync(m => m.Id == id);
return RedirectToAction(nameof(Index));
if(ssc == null)
{
return NotFound();
}
public IActionResult Consolidate()
{
List<SscModel> dups = _context.Ssc.GroupBy(x => new
{
x.BlockSizeGranularity,
x.MaxBlockLength,
x.MinBlockLength
}).Where(x => x.Count() > 1).Select(x => new SscModel
{
BlockSizeGranularity = x.Key.BlockSizeGranularity,
MaxBlockLength = x.Key.MaxBlockLength,
MinBlockLength = x.Key.MinBlockLength
}).ToList();
return View(ssc);
}
return View(new SscModelForView
{
List = dups,
Json = JsonConvert.SerializeObject(dups)
});
// POST: Admin/Sscs/Delete/5
[HttpPost, ActionName("Delete"), ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
Ssc ssc = await _context.Ssc.FindAsync(id);
_context.Ssc.Remove(ssc);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
public IActionResult Consolidate()
{
List<SscModel> dups = _context.Ssc.GroupBy(x => new
{
x.BlockSizeGranularity,
x.MaxBlockLength,
x.MinBlockLength
}).Where(x => x.Count() > 1).Select(x => new SscModel
{
BlockSizeGranularity = x.Key.BlockSizeGranularity,
MaxBlockLength = x.Key.MaxBlockLength,
MinBlockLength = x.Key.MinBlockLength
}).ToList();
return View(new SscModelForView
{
List = dups,
Json = JsonConvert.SerializeObject(dups)
});
}
[HttpPost, ActionName("Consolidate"), ValidateAntiForgeryToken]
public IActionResult ConsolidateConfirmed(string models)
{
SscModel[] duplicates;
try
{
duplicates = JsonConvert.DeserializeObject<SscModel[]>(models);
}
catch(JsonSerializationException)
{
return BadRequest();
}
[HttpPost, ActionName("Consolidate"), ValidateAntiForgeryToken]
public IActionResult ConsolidateConfirmed(string models)
if(duplicates is null)
return BadRequest();
foreach(SscModel duplicate in duplicates)
{
SscModel[] duplicates;
Ssc master =
_context.Ssc.FirstOrDefault(m => m.BlockSizeGranularity == duplicate.BlockSizeGranularity &&
m.MaxBlockLength == duplicate.MaxBlockLength &&
m.MinBlockLength == duplicate.MinBlockLength);
try
if(master is null)
continue;
foreach(Ssc ssc in _context.Ssc.Where(m => m.BlockSizeGranularity == duplicate.BlockSizeGranularity &&
m.MaxBlockLength == duplicate.MaxBlockLength &&
m.MinBlockLength == duplicate.MinBlockLength).Skip(1).
ToArray())
{
duplicates = JsonConvert.DeserializeObject<SscModel[]>(models);
}
catch(JsonSerializationException)
{
return BadRequest();
}
if(duplicates is null)
return BadRequest();
foreach(SscModel duplicate in duplicates)
{
Ssc master =
_context.Ssc.FirstOrDefault(m => m.BlockSizeGranularity == duplicate.BlockSizeGranularity &&
m.MaxBlockLength == duplicate.MaxBlockLength &&
m.MinBlockLength == duplicate.MinBlockLength);
if(master is null)
continue;
foreach(Ssc ssc in _context.Ssc.Where(m => m.BlockSizeGranularity == duplicate.BlockSizeGranularity &&
m.MaxBlockLength == duplicate.MaxBlockLength &&
m.MinBlockLength == duplicate.MinBlockLength).Skip(1).
ToArray())
foreach(TestedSequentialMedia media in _context.TestedSequentialMedia.Where(d => d.SscId == ssc.Id))
{
foreach(TestedSequentialMedia media in _context.TestedSequentialMedia.Where(d => d.SscId == ssc.Id))
{
media.SscId = master.Id;
}
_context.Ssc.Update(ssc);
_context.Ssc.Remove(ssc);
media.SscId = master.Id;
}
_context.Ssc.Update(ssc);
_context.Ssc.Remove(ssc);
}
_context.SaveChanges();
return RedirectToAction(nameof(Index));
}
_context.SaveChanges();
return RedirectToAction(nameof(Index));
}
}

View File

@@ -6,54 +6,53 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespace Aaru.Server.Areas.Admin.Controllers
namespace Aaru.Server.Areas.Admin.Controllers;
[Area("Admin"), Authorize]
public sealed class SupportedDensitiesController : Controller
{
[Area("Admin"), Authorize]
public sealed class SupportedDensitiesController : Controller
readonly AaruServerContext _context;
public SupportedDensitiesController(AaruServerContext context) => _context = context;
// GET: Admin/SupportedDensities
public async Task<IActionResult> Index() => View(await _context.SupportedDensity.OrderBy(d => d.Organization).
ThenBy(d => d.Name).ThenBy(d => d.Description).
ThenBy(d => d.Capacity).
ThenBy(d => d.PrimaryCode).
ThenBy(d => d.SecondaryCode).
ThenBy(d => d.BitsPerMm).ThenBy(d => d.Width).
ThenBy(d => d.Tracks).
ThenBy(d => d.DefaultDensity).
ThenBy(d => d.Writable).
ThenBy(d => d.Duplicate).ToListAsync());
// GET: Admin/SupportedDensities/Delete/5
public async Task<IActionResult> Delete(int? id)
{
readonly AaruServerContext _context;
public SupportedDensitiesController(AaruServerContext context) => _context = context;
// GET: Admin/SupportedDensities
public async Task<IActionResult> Index() => View(await _context.SupportedDensity.OrderBy(d => d.Organization).
ThenBy(d => d.Name).ThenBy(d => d.Description).
ThenBy(d => d.Capacity).
ThenBy(d => d.PrimaryCode).
ThenBy(d => d.SecondaryCode).
ThenBy(d => d.BitsPerMm).ThenBy(d => d.Width).
ThenBy(d => d.Tracks).
ThenBy(d => d.DefaultDensity).
ThenBy(d => d.Writable).
ThenBy(d => d.Duplicate).ToListAsync());
// GET: Admin/SupportedDensities/Delete/5
public async Task<IActionResult> Delete(int? id)
if(id == null)
{
if(id == null)
{
return NotFound();
}
SupportedDensity supportedDensity = await _context.SupportedDensity.FirstOrDefaultAsync(m => m.Id == id);
if(supportedDensity == null)
{
return NotFound();
}
return View(supportedDensity);
return NotFound();
}
// POST: Admin/SupportedDensities/Delete/5
[HttpPost, ActionName("Delete"), ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
SupportedDensity supportedDensity = await _context.SupportedDensity.FindAsync(id);
_context.SupportedDensity.Remove(supportedDensity);
await _context.SaveChangesAsync();
SupportedDensity supportedDensity = await _context.SupportedDensity.FirstOrDefaultAsync(m => m.Id == id);
return RedirectToAction(nameof(Index));
if(supportedDensity == null)
{
return NotFound();
}
return View(supportedDensity);
}
// POST: Admin/SupportedDensities/Delete/5
[HttpPost, ActionName("Delete"), ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
SupportedDensity supportedDensity = await _context.SupportedDensity.FindAsync(id);
_context.SupportedDensity.Remove(supportedDensity);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -6,102 +6,101 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespace Aaru.Server.Areas.Admin.Controllers
namespace Aaru.Server.Areas.Admin.Controllers;
[Area("Admin"), Authorize]
public sealed class TestedSequentialMediasController : Controller
{
[Area("Admin"), Authorize]
public sealed class TestedSequentialMediasController : Controller
readonly AaruServerContext _context;
public TestedSequentialMediasController(AaruServerContext context) => _context = context;
// GET: Admin/TestedSequentialMedias
public async Task<IActionResult> Index() => View(await _context.TestedSequentialMedia.
OrderBy(m => m.Manufacturer).
ThenBy(m => m.Model).
ThenBy(m => m.MediumTypeName).ToListAsync());
// GET: Admin/TestedSequentialMedias/Edit/5
public async Task<IActionResult> Edit(int? id)
{
readonly AaruServerContext _context;
public TestedSequentialMediasController(AaruServerContext context) => _context = context;
// GET: Admin/TestedSequentialMedias
public async Task<IActionResult> Index() => View(await _context.TestedSequentialMedia.
OrderBy(m => m.Manufacturer).
ThenBy(m => m.Model).
ThenBy(m => m.MediumTypeName).ToListAsync());
// GET: Admin/TestedSequentialMedias/Edit/5
public async Task<IActionResult> Edit(int? id)
if(id == null)
{
if(id == null)
{
return NotFound();
}
TestedSequentialMedia testedSequentialMedia = await _context.TestedSequentialMedia.FindAsync(id);
if(testedSequentialMedia == null)
{
return NotFound();
}
return View(testedSequentialMedia);
return NotFound();
}
// POST: Admin/TestedSequentialMedias/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost, ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Id,Manufacturer,MediumTypeName,Model")]
TestedSequentialMedia changedModel)
TestedSequentialMedia testedSequentialMedia = await _context.TestedSequentialMedia.FindAsync(id);
if(testedSequentialMedia == null)
{
if(id != changedModel.Id)
return NotFound();
if(!ModelState.IsValid)
return View(changedModel);
TestedSequentialMedia model = await _context.TestedSequentialMedia.FirstOrDefaultAsync(m => m.Id == id);
if(model is null)
return NotFound();
model.Manufacturer = changedModel.Manufacturer;
model.MediumTypeName = changedModel.MediumTypeName;
model.Model = changedModel.Model;
try
{
_context.Update(model);
await _context.SaveChangesAsync();
}
catch(DbUpdateConcurrencyException)
{
ModelState.AddModelError("Concurrency", "Concurrency error, please report to the administrator.");
}
return RedirectToAction(nameof(Index));
return NotFound();
}
// GET: Admin/TestedSequentialMedias/Delete/5
public async Task<IActionResult> Delete(int? id)
return View(testedSequentialMedia);
}
// POST: Admin/TestedSequentialMedias/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost, ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Id,Manufacturer,MediumTypeName,Model")]
TestedSequentialMedia changedModel)
{
if(id != changedModel.Id)
return NotFound();
if(!ModelState.IsValid)
return View(changedModel);
TestedSequentialMedia model = await _context.TestedSequentialMedia.FirstOrDefaultAsync(m => m.Id == id);
if(model is null)
return NotFound();
model.Manufacturer = changedModel.Manufacturer;
model.MediumTypeName = changedModel.MediumTypeName;
model.Model = changedModel.Model;
try
{
if(id == null)
{
return NotFound();
}
TestedSequentialMedia testedSequentialMedia =
await _context.TestedSequentialMedia.FirstOrDefaultAsync(m => m.Id == id);
if(testedSequentialMedia == null)
{
return NotFound();
}
return View(testedSequentialMedia);
}
// POST: Admin/TestedSequentialMedias/Delete/5
[HttpPost, ActionName("Delete"), ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
TestedSequentialMedia testedSequentialMedia = await _context.TestedSequentialMedia.FindAsync(id);
_context.TestedSequentialMedia.Remove(testedSequentialMedia);
_context.Update(model);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
catch(DbUpdateConcurrencyException)
{
ModelState.AddModelError("Concurrency", "Concurrency error, please report to the administrator.");
}
return RedirectToAction(nameof(Index));
}
// GET: Admin/TestedSequentialMedias/Delete/5
public async Task<IActionResult> Delete(int? id)
{
if(id == null)
{
return NotFound();
}
TestedSequentialMedia testedSequentialMedia =
await _context.TestedSequentialMedia.FirstOrDefaultAsync(m => m.Id == id);
if(testedSequentialMedia == null)
{
return NotFound();
}
return View(testedSequentialMedia);
}
// POST: Admin/TestedSequentialMedias/Delete/5
[HttpPost, ActionName("Delete"), ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
TestedSequentialMedia testedSequentialMedia = await _context.TestedSequentialMedia.FindAsync(id);
_context.TestedSequentialMedia.Remove(testedSequentialMedia);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
}

View File

@@ -5,25 +5,24 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespace Aaru.Server.Areas.Admin.Controllers
namespace Aaru.Server.Areas.Admin.Controllers;
[Area("Admin"), Authorize]
public sealed class UsbProductsController : Controller
{
[Area("Admin"), Authorize]
public sealed class UsbProductsController : Controller
{
readonly AaruServerContext _context;
readonly AaruServerContext _context;
public UsbProductsController(AaruServerContext context) => _context = context;
public UsbProductsController(AaruServerContext context) => _context = context;
// GET: Admin/UsbProducts
public async Task<IActionResult> Index() => View(await _context.UsbProducts.Include(u => u.Vendor).
OrderBy(p => p.Vendor.Vendor).
ThenBy(p => p.Product).ThenBy(p => p.ProductId).
Select(p => new UsbProductModel
{
ProductId = p.ProductId,
ProductName = p.Product,
VendorId = p.Vendor.Id,
VendorName = p.Vendor.Vendor
}).ToListAsync());
}
// GET: Admin/UsbProducts
public async Task<IActionResult> Index() => View(await _context.UsbProducts.Include(u => u.Vendor).
OrderBy(p => p.Vendor.Vendor).
ThenBy(p => p.Product).ThenBy(p => p.ProductId).
Select(p => new UsbProductModel
{
ProductId = p.ProductId,
ProductName = p.Product,
VendorId = p.Vendor.Id,
VendorName = p.Vendor.Vendor
}).ToListAsync());
}

View File

@@ -5,45 +5,44 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespace Aaru.Server.Areas.Admin.Controllers
namespace Aaru.Server.Areas.Admin.Controllers;
[Area("Admin"), Authorize]
public sealed class UsbVendorsController : Controller
{
[Area("Admin"), Authorize]
public sealed class UsbVendorsController : Controller
readonly AaruServerContext _context;
public UsbVendorsController(AaruServerContext context) => _context = context;
// GET: Admin/UsbVendors
public async Task<IActionResult> Index() =>
View(await _context.UsbVendors.OrderBy(v => v.Vendor).ThenBy(v => v.VendorId).ToListAsync());
// GET: Admin/UsbVendors/Details/5
public async Task<IActionResult> Details(int? id)
{
readonly AaruServerContext _context;
public UsbVendorsController(AaruServerContext context) => _context = context;
// GET: Admin/UsbVendors
public async Task<IActionResult> Index() =>
View(await _context.UsbVendors.OrderBy(v => v.Vendor).ThenBy(v => v.VendorId).ToListAsync());
// GET: Admin/UsbVendors/Details/5
public async Task<IActionResult> Details(int? id)
if(id == null)
{
if(id == null)
{
return NotFound();
}
UsbVendor usbVendor = await _context.UsbVendors.FirstOrDefaultAsync(m => m.Id == id);
if(usbVendor == null)
{
return NotFound();
}
return View(new UsbVendorModel
{
Vendor = usbVendor.Vendor,
VendorId = usbVendor.VendorId,
Products = _context.UsbProducts.Where(p => p.VendorId == usbVendor.Id).OrderBy(p => p.Product).
ThenBy(p => p.ProductId).Select(p => new UsbProductModel
{
ProductId = p.ProductId,
ProductName = p.Product
}).ToList()
});
return NotFound();
}
UsbVendor usbVendor = await _context.UsbVendors.FirstOrDefaultAsync(m => m.Id == id);
if(usbVendor == null)
{
return NotFound();
}
return View(new UsbVendorModel
{
Vendor = usbVendor.Vendor,
VendorId = usbVendor.VendorId,
Products = _context.UsbProducts.Where(p => p.VendorId == usbVendor.Id).OrderBy(p => p.Product).
ThenBy(p => p.ProductId).Select(p => new UsbProductModel
{
ProductId = p.ProductId,
ProductName = p.Product
}).ToList()
});
}
}

View File

@@ -8,153 +8,152 @@ using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
namespace Aaru.Server.Areas.Admin.Controllers
namespace Aaru.Server.Areas.Admin.Controllers;
[Area("Admin"), Authorize]
public sealed class UsbsController : Controller
{
[Area("Admin"), Authorize]
public sealed class UsbsController : Controller
readonly AaruServerContext _context;
public UsbsController(AaruServerContext context) => _context = context;
// GET: Admin/Usbs
public async Task<IActionResult> Index() => View(await _context.Usb.OrderBy(u => u.Manufacturer).
ThenBy(u => u.Product).ThenBy(u => u.VendorID).
ThenBy(u => u.ProductID).ToListAsync());
// GET: Admin/Usbs/Details/5
public async Task<IActionResult> Details(int? id)
{
readonly AaruServerContext _context;
public UsbsController(AaruServerContext context) => _context = context;
// GET: Admin/Usbs
public async Task<IActionResult> Index() => View(await _context.Usb.OrderBy(u => u.Manufacturer).
ThenBy(u => u.Product).ThenBy(u => u.VendorID).
ThenBy(u => u.ProductID).ToListAsync());
// GET: Admin/Usbs/Details/5
public async Task<IActionResult> Details(int? id)
if(id == null)
{
if(id == null)
{
return NotFound();
}
Usb usb = await _context.Usb.FirstOrDefaultAsync(m => m.Id == id);
if(usb == null)
{
return NotFound();
}
return View(usb);
return NotFound();
}
// GET: Admin/Usbs/Delete/5
public async Task<IActionResult> Delete(int? id)
Usb usb = await _context.Usb.FirstOrDefaultAsync(m => m.Id == id);
if(usb == null)
{
if(id == null)
{
return NotFound();
}
Usb usb = await _context.Usb.FirstOrDefaultAsync(m => m.Id == id);
if(usb == null)
{
return NotFound();
}
return View(usb);
return NotFound();
}
// POST: Admin/Usbs/Delete/5
[HttpPost, ActionName("Delete"), ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
Usb usb = await _context.Usb.FindAsync(id);
_context.Usb.Remove(usb);
await _context.SaveChangesAsync();
return View(usb);
}
return RedirectToAction(nameof(Index));
// GET: Admin/Usbs/Delete/5
public async Task<IActionResult> Delete(int? id)
{
if(id == null)
{
return NotFound();
}
public IActionResult Consolidate()
{
List<UsbModel> dups = _context.Usb.GroupBy(x => new
{
x.Manufacturer,
x.Product,
x.VendorID,
x.ProductID
}).Where(x => x.Count() > 1).Select(x => new UsbModel
{
Manufacturer = x.Key.Manufacturer,
Product = x.Key.Product,
VendorID = x.Key.VendorID,
ProductID = x.Key.ProductID
}).ToList();
Usb usb = await _context.Usb.FirstOrDefaultAsync(m => m.Id == id);
return View(new UsbModelForView
{
List = dups,
Json = JsonConvert.SerializeObject(dups)
});
if(usb == null)
{
return NotFound();
}
[HttpPost, ActionName("Consolidate"), ValidateAntiForgeryToken]
public IActionResult ConsolidateConfirmed(string models)
return View(usb);
}
// POST: Admin/Usbs/Delete/5
[HttpPost, ActionName("Delete"), ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
Usb usb = await _context.Usb.FindAsync(id);
_context.Usb.Remove(usb);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
public IActionResult Consolidate()
{
List<UsbModel> dups = _context.Usb.GroupBy(x => new
{
UsbModel[] duplicates;
x.Manufacturer,
x.Product,
x.VendorID,
x.ProductID
}).Where(x => x.Count() > 1).Select(x => new UsbModel
{
Manufacturer = x.Key.Manufacturer,
Product = x.Key.Product,
VendorID = x.Key.VendorID,
ProductID = x.Key.ProductID
}).ToList();
try
return View(new UsbModelForView
{
List = dups,
Json = JsonConvert.SerializeObject(dups)
});
}
[HttpPost, ActionName("Consolidate"), ValidateAntiForgeryToken]
public IActionResult ConsolidateConfirmed(string models)
{
UsbModel[] duplicates;
try
{
duplicates = JsonConvert.DeserializeObject<UsbModel[]>(models);
}
catch(JsonSerializationException)
{
return BadRequest();
}
if(duplicates is null)
return BadRequest();
foreach(UsbModel duplicate in duplicates)
{
Usb master = _context.Usb.FirstOrDefault(m => m.Manufacturer == duplicate.Manufacturer &&
m.Product == duplicate.Product &&
m.VendorID == duplicate.VendorID &&
m.ProductID == duplicate.ProductID);
if(master is null)
continue;
foreach(Usb slave in _context.Usb.Where(m => m.Manufacturer == duplicate.Manufacturer &&
m.Product == duplicate.Product &&
m.VendorID == duplicate.VendorID &&
m.ProductID == duplicate.ProductID).Skip(1).ToArray())
{
duplicates = JsonConvert.DeserializeObject<UsbModel[]>(models);
}
catch(JsonSerializationException)
{
return BadRequest();
}
if(duplicates is null)
return BadRequest();
foreach(UsbModel duplicate in duplicates)
{
Usb master = _context.Usb.FirstOrDefault(m => m.Manufacturer == duplicate.Manufacturer &&
m.Product == duplicate.Product &&
m.VendorID == duplicate.VendorID &&
m.ProductID == duplicate.ProductID);
if(master is null)
continue;
foreach(Usb slave in _context.Usb.Where(m => m.Manufacturer == duplicate.Manufacturer &&
m.Product == duplicate.Product &&
m.VendorID == duplicate.VendorID &&
m.ProductID == duplicate.ProductID).Skip(1).ToArray())
if(slave.Descriptors != null &&
master.Descriptors != null)
{
if(slave.Descriptors != null &&
master.Descriptors != null)
{
if(!master.Descriptors.SequenceEqual(slave.Descriptors))
continue;
}
foreach(Device device in _context.Devices.Where(d => d.USB.Id == slave.Id))
{
device.USB = master;
}
foreach(UploadedReport report in _context.Reports.Where(d => d.USB.Id == slave.Id))
{
report.USB = master;
}
if(master.Descriptors is null &&
slave.Descriptors != null)
{
master.Descriptors = slave.Descriptors;
_context.Usb.Update(master);
}
_context.Usb.Remove(slave);
if(!master.Descriptors.SequenceEqual(slave.Descriptors))
continue;
}
foreach(Device device in _context.Devices.Where(d => d.USB.Id == slave.Id))
{
device.USB = master;
}
foreach(UploadedReport report in _context.Reports.Where(d => d.USB.Id == slave.Id))
{
report.USB = master;
}
if(master.Descriptors is null &&
slave.Descriptors != null)
{
master.Descriptors = slave.Descriptors;
_context.Usb.Update(master);
}
_context.Usb.Remove(slave);
}
_context.SaveChanges();
return RedirectToAction(nameof(Index));
}
_context.SaveChanges();
return RedirectToAction(nameof(Index));
}
}

View File

@@ -5,16 +5,15 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespace Aaru.Server.Areas.Admin.Controllers
namespace Aaru.Server.Areas.Admin.Controllers;
[Area("Admin"), Authorize]
public sealed class VersionsController : Controller
{
[Area("Admin"), Authorize]
public sealed class VersionsController : Controller
{
readonly AaruServerContext _context;
readonly AaruServerContext _context;
public VersionsController(AaruServerContext context) => _context = context;
public VersionsController(AaruServerContext context) => _context = context;
// GET: Admin/Versions
public async Task<IActionResult> Index() => View(await _context.Versions.OrderBy(v => v.Name).ToListAsync());
}
// GET: Admin/Versions
public async Task<IActionResult> Index() => View(await _context.Versions.OrderBy(v => v.Name).ToListAsync());
}

View File

@@ -2,13 +2,12 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace Aaru.Server.Areas.Identity.Pages.Account
{
[AllowAnonymous]
public sealed class RegisterModel : PageModel
{
public IActionResult OnGetAsync(string returnUrl = null) => RedirectToPage("Login");
namespace Aaru.Server.Areas.Identity.Pages.Account;
public IActionResult OnPostAsync(string returnUrl = null) => RedirectToPage("Login");
}
[AllowAnonymous]
public sealed class RegisterModel : PageModel
{
public IActionResult OnGetAsync(string returnUrl = null) => RedirectToPage("Login");
public IActionResult OnPostAsync(string returnUrl = null) => RedirectToPage("Login");
}

View File

@@ -10,71 +10,70 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
namespace Aaru.Server
namespace Aaru.Server;
public sealed class BasicAuthMiddleware
{
public sealed class BasicAuthMiddleware
readonly RequestDelegate _next;
readonly string _realm;
public BasicAuthMiddleware(RequestDelegate next, string realm)
{
readonly RequestDelegate _next;
readonly string _realm;
_next = next;
_realm = realm;
}
public BasicAuthMiddleware(RequestDelegate next, string realm)
public async Task Invoke(HttpContext context)
{
string authHeader = context.Request.Headers["Authorization"];
if(authHeader?.StartsWith("Basic ") == true)
{
_next = next;
_realm = realm;
}
// Get the encoded username and password
string encodedUsernamePassword =
authHeader.Split(' ', 2, StringSplitOptions.RemoveEmptyEntries)[1]?.Trim();
public async Task Invoke(HttpContext context)
{
string authHeader = context.Request.Headers["Authorization"];
// Decode from Base64 to string
string decodedUsernamePassword =
Encoding.UTF8.GetString(Convert.FromBase64String(encodedUsernamePassword));
if(authHeader?.StartsWith("Basic ") == true)
// Split username and password
string username = decodedUsernamePassword.Split(':', 2)[0];
string password = decodedUsernamePassword.Split(':', 2)[1];
// Check if login is correct
if(IsAuthorized(username, password))
{
// Get the encoded username and password
string encodedUsernamePassword =
authHeader.Split(' ', 2, StringSplitOptions.RemoveEmptyEntries)[1]?.Trim();
await _next.Invoke(context);
// Decode from Base64 to string
string decodedUsernamePassword =
Encoding.UTF8.GetString(Convert.FromBase64String(encodedUsernamePassword));
// Split username and password
string username = decodedUsernamePassword.Split(':', 2)[0];
string password = decodedUsernamePassword.Split(':', 2)[1];
// Check if login is correct
if(IsAuthorized(username, password))
{
await _next.Invoke(context);
return;
}
return;
}
// Return authentication type (causes browser to show login dialog)
context.Response.Headers["WWW-Authenticate"] = "Basic";
// Add realm if it is not null
if(!string.IsNullOrWhiteSpace(_realm))
{
context.Response.Headers["WWW-Authenticate"] += $" realm=\"{_realm}\"";
}
// Return unauthorized
context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
}
// Make your own implementation of this
// Check that username and password are correct
public bool IsAuthorized(string username, string password)
// Return authentication type (causes browser to show login dialog)
context.Response.Headers["WWW-Authenticate"] = "Basic";
// Add realm if it is not null
if(!string.IsNullOrWhiteSpace(_realm))
{
IConfigurationBuilder builder = new ConfigurationBuilder().AddJsonFile("appsettings.json");
IConfigurationRoot configuration = builder.Build();
string validUser = configuration.GetValue<string>("MetricsAuthentication:Username");
string validPassword = configuration.GetValue<string>("MetricsAuthentication:Password");
return !string.IsNullOrWhiteSpace(validUser) && !string.IsNullOrWhiteSpace(validPassword) &&
username.Equals(validUser, StringComparison.InvariantCultureIgnoreCase) &&
password.Equals(validPassword);
context.Response.Headers["WWW-Authenticate"] += $" realm=\"{_realm}\"";
}
// Return unauthorized
context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
}
// Make your own implementation of this
// Check that username and password are correct
public bool IsAuthorized(string username, string password)
{
IConfigurationBuilder builder = new ConfigurationBuilder().AddJsonFile("appsettings.json");
IConfigurationRoot configuration = builder.Build();
string validUser = configuration.GetValue<string>("MetricsAuthentication:Username");
string validPassword = configuration.GetValue<string>("MetricsAuthentication:Password");
return !string.IsNullOrWhiteSpace(validUser) && !string.IsNullOrWhiteSpace(validPassword) &&
username.Equals(validUser, StringComparison.InvariantCultureIgnoreCase) &&
password.Equals(validPassword);
}
}

View File

@@ -46,498 +46,497 @@ using Inquiry = Aaru.CommonTypes.Structs.Devices.SCSI.Inquiry;
using TestedMedia = Aaru.CommonTypes.Metadata.TestedMedia;
using Tuple = Aaru.Decoders.PCMCIA.Tuple;
namespace Aaru.Server.Controllers
namespace Aaru.Server.Controllers;
public sealed class ReportController : Controller
{
public sealed class ReportController : Controller
readonly AaruServerContext _ctx;
public ReportController(AaruServerContext context) => _ctx = context;
public ActionResult Index() => RedirectToAction("View", "Report", new RouteValueDictionary
{
readonly AaruServerContext _ctx;
public ReportController(AaruServerContext context) => _ctx = context;
public ActionResult Index() => RedirectToAction("View", "Report", new RouteValueDictionary
{
"id", 1
}
});
public ActionResult View(int? id)
{
if(id == null ||
id <= 0)
return Content("Incorrect device report request");
try
{
Device report = _ctx.Devices.FirstOrDefault(d => d.Id == id);
if(report is null)
return Content("Cannot find requested report");
ViewBag.lblManufacturer = report.Manufacturer;
ViewBag.lblModel = report.Model;
ViewBag.lblRevision = report.Revision;
if(report.USB != null)
{
"id", 1
string usbVendorDescription = null;
string usbProductDescription = null;
UsbProduct dbProduct =
_ctx.UsbProducts.FirstOrDefault(p => p.ProductId == report.USB.ProductID && p.Vendor != null &&
p.Vendor.VendorId == report.USB.VendorID);
if(dbProduct is null)
{
UsbVendor dbVendor = _ctx.UsbVendors.FirstOrDefault(v => v.VendorId == report.USB.VendorID);
if(!(dbVendor is null))
usbVendorDescription = dbVendor.Vendor;
}
else
{
usbProductDescription = dbProduct.Product;
usbVendorDescription = dbProduct.Vendor.Vendor;
}
ViewBag.UsbItem = new Item
{
Manufacturer = report.USB.Manufacturer,
Product = report.USB.Product,
VendorDescription = usbVendorDescription != null
? $"0x{report.USB.VendorID:x4} ({usbVendorDescription})"
: $"0x{report.USB.VendorID:x4}",
ProductDescription = usbProductDescription != null
? $"0x{report.USB.ProductID:x4} ({usbProductDescription})"
: $"0x{report.USB.ProductID:x4}"
};
}
});
public ActionResult View(int? id)
{
if(id == null ||
id <= 0)
return Content("Incorrect device report request");
if(report.FireWire != null)
ViewBag.FireWireItem = new Item
{
Manufacturer = report.FireWire.Manufacturer,
Product = report.FireWire.Product,
VendorDescription = $"0x{report.FireWire.VendorID:x8}",
ProductDescription = $"0x{report.FireWire.ProductID:x8}"
};
try
if(report.PCMCIA != null)
{
Device report = _ctx.Devices.FirstOrDefault(d => d.Id == id);
if(report is null)
return Content("Cannot find requested report");
ViewBag.lblManufacturer = report.Manufacturer;
ViewBag.lblModel = report.Model;
ViewBag.lblRevision = report.Revision;
if(report.USB != null)
ViewBag.PcmciaItem = new PcmciaItem
{
string usbVendorDescription = null;
string usbProductDescription = null;
Manufacturer = report.PCMCIA.Manufacturer,
Product = report.PCMCIA.ProductName,
VendorDescription = $"0x{report.PCMCIA.ManufacturerCode:x4}",
ProductDescription = $"0x{report.PCMCIA.CardCode:x4}",
Compliance = report.PCMCIA.Compliance
};
UsbProduct dbProduct =
_ctx.UsbProducts.FirstOrDefault(p => p.ProductId == report.USB.ProductID && p.Vendor != null &&
p.Vendor.VendorId == report.USB.VendorID);
Tuple[] tuples = CIS.GetTuples(report.PCMCIA.CIS);
if(dbProduct is null)
{
UsbVendor dbVendor = _ctx.UsbVendors.FirstOrDefault(v => v.VendorId == report.USB.VendorID);
if(tuples != null)
{
Dictionary<string, string> decodedTuples = new();
if(!(dbVendor is null))
usbVendorDescription = dbVendor.Vendor;
}
else
{
usbProductDescription = dbProduct.Product;
usbVendorDescription = dbProduct.Vendor.Vendor;
}
foreach(Tuple tuple in tuples)
switch(tuple.Code)
{
case TupleCodes.CISTPL_NULL:
case TupleCodes.CISTPL_END:
case TupleCodes.CISTPL_MANFID:
case TupleCodes.CISTPL_VERS_1: break;
case TupleCodes.CISTPL_DEVICEGEO:
case TupleCodes.CISTPL_DEVICEGEO_A:
DeviceGeometryTuple geom = CIS.DecodeDeviceGeometryTuple(tuple.Data);
ViewBag.UsbItem = new Item
{
Manufacturer = report.USB.Manufacturer,
Product = report.USB.Product,
VendorDescription = usbVendorDescription != null
? $"0x{report.USB.VendorID:x4} ({usbVendorDescription})"
: $"0x{report.USB.VendorID:x4}",
ProductDescription = usbProductDescription != null
? $"0x{report.USB.ProductID:x4} ({usbProductDescription})"
: $"0x{report.USB.ProductID:x4}"
};
if(geom?.Geometries != null)
foreach(DeviceGeometry geometry in geom.Geometries)
{
decodedTuples.Add("Device width",
$"{(1 << (geometry.CardInterface - 1)) * 8} bits");
decodedTuples.Add("Erase block",
$"{(1 << (geometry.EraseBlockSize - 1)) * (1 << (geometry.Interleaving - 1))} bytes");
decodedTuples.Add("Read block",
$"{(1 << (geometry.ReadBlockSize - 1)) * (1 << (geometry.Interleaving - 1))} bytes");
decodedTuples.Add("Write block",
$"{(1 << (geometry.WriteBlockSize - 1)) * (1 << (geometry.Interleaving - 1))} bytes");
decodedTuples.Add("Partition alignment",
$"{(1 << (geometry.EraseBlockSize - 1)) * (1 << (geometry.Interleaving - 1)) * (1 << (geometry.Partitions - 1))} bytes");
}
break;
case TupleCodes.CISTPL_ALTSTR:
case TupleCodes.CISTPL_BAR:
case TupleCodes.CISTPL_BATTERY:
case TupleCodes.CISTPL_BYTEORDER:
case TupleCodes.CISTPL_CFTABLE_ENTRY:
case TupleCodes.CISTPL_CFTABLE_ENTRY_CB:
case TupleCodes.CISTPL_CHECKSUM:
case TupleCodes.CISTPL_CONFIG:
case TupleCodes.CISTPL_CONFIG_CB:
case TupleCodes.CISTPL_DATE:
case TupleCodes.CISTPL_DEVICE:
case TupleCodes.CISTPL_DEVICE_A:
case TupleCodes.CISTPL_DEVICE_OA:
case TupleCodes.CISTPL_DEVICE_OC:
case TupleCodes.CISTPL_EXTDEVIC:
case TupleCodes.CISTPL_FORMAT:
case TupleCodes.CISTPL_FORMAT_A:
case TupleCodes.CISTPL_FUNCE:
case TupleCodes.CISTPL_FUNCID:
case TupleCodes.CISTPL_GEOMETRY:
case TupleCodes.CISTPL_INDIRECT:
case TupleCodes.CISTPL_JEDEC_A:
case TupleCodes.CISTPL_JEDEC_C:
case TupleCodes.CISTPL_LINKTARGET:
case TupleCodes.CISTPL_LONGLINK_A:
case TupleCodes.CISTPL_LONGLINK_C:
case TupleCodes.CISTPL_LONGLINK_CB:
case TupleCodes.CISTPL_LONGLINK_MFC:
case TupleCodes.CISTPL_NO_LINK:
case TupleCodes.CISTPL_ORG:
case TupleCodes.CISTPL_PWR_MGMNT:
case TupleCodes.CISTPL_SPCL:
case TupleCodes.CISTPL_SWIL:
case TupleCodes.CISTPL_VERS_2:
decodedTuples.Add("Undecoded tuple ID", tuple.Code.ToString());
break;
default:
decodedTuples.Add("Unknown tuple ID", $"0x{(byte)tuple.Code:X2}");
break;
}
if(decodedTuples.Count > 0)
ViewBag.repPcmciaTuples = decodedTuples;
}
}
bool removable = true;
List<TestedMedia> testedMedia = null;
bool atapi = false;
bool sscMedia = false;
if(report.ATA != null ||
report.ATAPI != null)
{
List<string> ataOneValue = new();
Dictionary<string, string> ataTwoValue = new();
Ata ataReport;
if(report.ATAPI != null)
{
ViewBag.AtaItem = "ATAPI";
ataReport = report.ATAPI;
atapi = true;
}
else
{
ViewBag.AtaItem = "ATA";
ataReport = report.ATA;
}
if(report.FireWire != null)
ViewBag.FireWireItem = new Item
{
Manufacturer = report.FireWire.Manufacturer,
Product = report.FireWire.Product,
VendorDescription = $"0x{report.FireWire.VendorID:x8}",
ProductDescription = $"0x{report.FireWire.ProductID:x8}"
};
bool cfa = report.CompactFlash;
if(report.PCMCIA != null)
if(atapi && !cfa)
ViewBag.lblAtaDeviceType = "ATAPI device";
else if(!atapi && cfa)
ViewBag.lblAtaDeviceType = "CompactFlash device";
else
ViewBag.lblAtaDeviceType = "ATA device";
Core.Ata.Report(ataReport, cfa, atapi, ref removable, ref ataOneValue, ref ataTwoValue,
ref testedMedia);
ViewBag.repAtaOne = ataOneValue;
ViewBag.repAtaTwo = ataTwoValue;
}
if(report.SCSI != null)
{
List<string> scsiOneValue = new();
Dictionary<string, string> modePages = new();
Dictionary<string, string> evpdPages = new();
string vendorId = StringHandlers.CToString(report.SCSI.Inquiry?.VendorIdentification);
if(report.SCSI.Inquiry != null)
{
ViewBag.PcmciaItem = new PcmciaItem
{
Manufacturer = report.PCMCIA.Manufacturer,
Product = report.PCMCIA.ProductName,
VendorDescription = $"0x{report.PCMCIA.ManufacturerCode:x4}",
ProductDescription = $"0x{report.PCMCIA.CardCode:x4}",
Compliance = report.PCMCIA.Compliance
};
Inquiry inq = report.SCSI.Inquiry.Value;
Tuple[] tuples = CIS.GetTuples(report.PCMCIA.CIS);
ViewBag.lblScsiVendor = VendorString.Prettify(vendorId) != vendorId
? $"{vendorId} ({VendorString.Prettify(vendorId)})" : vendorId;
if(tuples != null)
{
Dictionary<string, string> decodedTuples = new();
foreach(Tuple tuple in tuples)
switch(tuple.Code)
{
case TupleCodes.CISTPL_NULL:
case TupleCodes.CISTPL_END:
case TupleCodes.CISTPL_MANFID:
case TupleCodes.CISTPL_VERS_1: break;
case TupleCodes.CISTPL_DEVICEGEO:
case TupleCodes.CISTPL_DEVICEGEO_A:
DeviceGeometryTuple geom = CIS.DecodeDeviceGeometryTuple(tuple.Data);
if(geom?.Geometries != null)
foreach(DeviceGeometry geometry in geom.Geometries)
{
decodedTuples.Add("Device width",
$"{(1 << (geometry.CardInterface - 1)) * 8} bits");
decodedTuples.Add("Erase block",
$"{(1 << (geometry.EraseBlockSize - 1)) * (1 << (geometry.Interleaving - 1))} bytes");
decodedTuples.Add("Read block",
$"{(1 << (geometry.ReadBlockSize - 1)) * (1 << (geometry.Interleaving - 1))} bytes");
decodedTuples.Add("Write block",
$"{(1 << (geometry.WriteBlockSize - 1)) * (1 << (geometry.Interleaving - 1))} bytes");
decodedTuples.Add("Partition alignment",
$"{(1 << (geometry.EraseBlockSize - 1)) * (1 << (geometry.Interleaving - 1)) * (1 << (geometry.Partitions - 1))} bytes");
}
break;
case TupleCodes.CISTPL_ALTSTR:
case TupleCodes.CISTPL_BAR:
case TupleCodes.CISTPL_BATTERY:
case TupleCodes.CISTPL_BYTEORDER:
case TupleCodes.CISTPL_CFTABLE_ENTRY:
case TupleCodes.CISTPL_CFTABLE_ENTRY_CB:
case TupleCodes.CISTPL_CHECKSUM:
case TupleCodes.CISTPL_CONFIG:
case TupleCodes.CISTPL_CONFIG_CB:
case TupleCodes.CISTPL_DATE:
case TupleCodes.CISTPL_DEVICE:
case TupleCodes.CISTPL_DEVICE_A:
case TupleCodes.CISTPL_DEVICE_OA:
case TupleCodes.CISTPL_DEVICE_OC:
case TupleCodes.CISTPL_EXTDEVIC:
case TupleCodes.CISTPL_FORMAT:
case TupleCodes.CISTPL_FORMAT_A:
case TupleCodes.CISTPL_FUNCE:
case TupleCodes.CISTPL_FUNCID:
case TupleCodes.CISTPL_GEOMETRY:
case TupleCodes.CISTPL_INDIRECT:
case TupleCodes.CISTPL_JEDEC_A:
case TupleCodes.CISTPL_JEDEC_C:
case TupleCodes.CISTPL_LINKTARGET:
case TupleCodes.CISTPL_LONGLINK_A:
case TupleCodes.CISTPL_LONGLINK_C:
case TupleCodes.CISTPL_LONGLINK_CB:
case TupleCodes.CISTPL_LONGLINK_MFC:
case TupleCodes.CISTPL_NO_LINK:
case TupleCodes.CISTPL_ORG:
case TupleCodes.CISTPL_PWR_MGMNT:
case TupleCodes.CISTPL_SPCL:
case TupleCodes.CISTPL_SWIL:
case TupleCodes.CISTPL_VERS_2:
decodedTuples.Add("Undecoded tuple ID", tuple.Code.ToString());
break;
default:
decodedTuples.Add("Unknown tuple ID", $"0x{(byte)tuple.Code:X2}");
break;
}
if(decodedTuples.Count > 0)
ViewBag.repPcmciaTuples = decodedTuples;
}
ViewBag.lblScsiProduct = StringHandlers.CToString(inq.ProductIdentification);
ViewBag.lblScsiRevision = StringHandlers.CToString(inq.ProductRevisionLevel);
}
bool removable = true;
List<TestedMedia> testedMedia = null;
bool atapi = false;
bool sscMedia = false;
scsiOneValue.AddRange(ScsiInquiry.Report(report.SCSI.Inquiry));
if(report.ATA != null ||
report.ATAPI != null)
if(report.SCSI.SupportsModeSense6)
scsiOneValue.Add("Device supports MODE SENSE (6)");
if(report.SCSI.SupportsModeSense10)
scsiOneValue.Add("Device supports MODE SENSE (10)");
if(report.SCSI.SupportsModeSubpages)
scsiOneValue.Add("Device supports MODE SENSE subpages");
if(report.SCSI.ModeSense != null)
{
List<string> ataOneValue = new();
Dictionary<string, string> ataTwoValue = new();
Ata ataReport;
if(report.ATAPI != null)
{
ViewBag.AtaItem = "ATAPI";
ataReport = report.ATAPI;
atapi = true;
}
else
{
ViewBag.AtaItem = "ATA";
ataReport = report.ATA;
}
bool cfa = report.CompactFlash;
if(atapi && !cfa)
ViewBag.lblAtaDeviceType = "ATAPI device";
else if(!atapi && cfa)
ViewBag.lblAtaDeviceType = "CompactFlash device";
else
ViewBag.lblAtaDeviceType = "ATA device";
Core.Ata.Report(ataReport, cfa, atapi, ref removable, ref ataOneValue, ref ataTwoValue,
ref testedMedia);
ViewBag.repAtaOne = ataOneValue;
ViewBag.repAtaTwo = ataTwoValue;
}
if(report.SCSI != null)
{
List<string> scsiOneValue = new();
Dictionary<string, string> modePages = new();
Dictionary<string, string> evpdPages = new();
string vendorId = StringHandlers.CToString(report.SCSI.Inquiry?.VendorIdentification);
PeripheralDeviceTypes devType = PeripheralDeviceTypes.DirectAccess;
if(report.SCSI.Inquiry != null)
devType = (PeripheralDeviceTypes)report.SCSI.Inquiry.Value.PeripheralDeviceType;
ScsiModeSense.Report(report.SCSI.ModeSense, vendorId, devType, ref scsiOneValue, ref modePages);
}
if(modePages.Count > 0)
ViewBag.repModeSense = modePages;
if(report.SCSI.EVPDPages != null)
ScsiEvpd.Report(report.SCSI.EVPDPages, vendorId, ref evpdPages);
if(evpdPages.Count > 0)
ViewBag.repEvpd = evpdPages;
if(report.SCSI.MultiMediaDevice != null)
{
testedMedia = report.SCSI.MultiMediaDevice.TestedMedia;
if(report.SCSI.MultiMediaDevice.ModeSense2A != null)
{
Inquiry inq = report.SCSI.Inquiry.Value;
List<string> mmcModeOneValue = new();
ScsiMmcMode.Report(report.SCSI.MultiMediaDevice.ModeSense2A, ref mmcModeOneValue);
ViewBag.lblScsiVendor = VendorString.Prettify(vendorId) != vendorId
? $"{vendorId} ({VendorString.Prettify(vendorId)})" : vendorId;
ViewBag.lblScsiProduct = StringHandlers.CToString(inq.ProductIdentification);
ViewBag.lblScsiRevision = StringHandlers.CToString(inq.ProductRevisionLevel);
if(mmcModeOneValue.Count > 0)
ViewBag.repScsiMmcMode = mmcModeOneValue;
}
scsiOneValue.AddRange(ScsiInquiry.Report(report.SCSI.Inquiry));
if(report.SCSI.SupportsModeSense6)
scsiOneValue.Add("Device supports MODE SENSE (6)");
if(report.SCSI.SupportsModeSense10)
scsiOneValue.Add("Device supports MODE SENSE (10)");
if(report.SCSI.SupportsModeSubpages)
scsiOneValue.Add("Device supports MODE SENSE subpages");
if(report.SCSI.ModeSense != null)
if(report.SCSI.MultiMediaDevice.Features != null)
{
PeripheralDeviceTypes devType = PeripheralDeviceTypes.DirectAccess;
List<string> mmcFeaturesOneValue = new();
ScsiMmcFeatures.Report(report.SCSI.MultiMediaDevice.Features, ref mmcFeaturesOneValue);
if(report.SCSI.Inquiry != null)
devType = (PeripheralDeviceTypes)report.SCSI.Inquiry.Value.PeripheralDeviceType;
ScsiModeSense.Report(report.SCSI.ModeSense, vendorId, devType, ref scsiOneValue, ref modePages);
if(mmcFeaturesOneValue.Count > 0)
ViewBag.repScsiMmcFeatures = mmcFeaturesOneValue;
}
}
else if(report.SCSI.SequentialDevice != null)
{
ViewBag.divScsiSscVisible = true;
if(modePages.Count > 0)
ViewBag.repModeSense = modePages;
ViewBag.lblScsiSscGranularity =
report.SCSI.SequentialDevice.BlockSizeGranularity?.ToString() ?? "Unspecified";
if(report.SCSI.EVPDPages != null)
ScsiEvpd.Report(report.SCSI.EVPDPages, vendorId, ref evpdPages);
ViewBag.lblScsiSscMaxBlock =
report.SCSI.SequentialDevice.MaxBlockLength?.ToString() ?? "Unspecified";
if(evpdPages.Count > 0)
ViewBag.repEvpd = evpdPages;
ViewBag.lblScsiSscMinBlock =
report.SCSI.SequentialDevice.MinBlockLength?.ToString() ?? "Unspecified";
if(report.SCSI.MultiMediaDevice != null)
if(report.SCSI.SequentialDevice.SupportedDensities != null)
ViewBag.repScsiSscDensities = report.SCSI.SequentialDevice.SupportedDensities;
if(report.SCSI.SequentialDevice.SupportedMediaTypes != null)
ViewBag.repScsiSscMedias = report.SCSI.SequentialDevice.SupportedMediaTypes;
if(report.SCSI.SequentialDevice.TestedMedia != null)
{
testedMedia = report.SCSI.MultiMediaDevice.TestedMedia;
List<string> mediaOneValue = new();
SscTestedMedia.Report(report.SCSI.SequentialDevice.TestedMedia, ref mediaOneValue);
if(report.SCSI.MultiMediaDevice.ModeSense2A != null)
if(mediaOneValue.Count > 0)
{
List<string> mmcModeOneValue = new();
ScsiMmcMode.Report(report.SCSI.MultiMediaDevice.ModeSense2A, ref mmcModeOneValue);
if(mmcModeOneValue.Count > 0)
ViewBag.repScsiMmcMode = mmcModeOneValue;
}
if(report.SCSI.MultiMediaDevice.Features != null)
{
List<string> mmcFeaturesOneValue = new();
ScsiMmcFeatures.Report(report.SCSI.MultiMediaDevice.Features, ref mmcFeaturesOneValue);
if(mmcFeaturesOneValue.Count > 0)
ViewBag.repScsiMmcFeatures = mmcFeaturesOneValue;
sscMedia = true;
ViewBag.repTestedMedia = mediaOneValue;
}
}
else if(report.SCSI.SequentialDevice != null)
}
else if(report.SCSI.ReadCapabilities != null)
{
removable = false;
scsiOneValue.Add("");
if(report.SCSI.ReadCapabilities.Blocks.HasValue &&
report.SCSI.ReadCapabilities.BlockSize.HasValue)
{
ViewBag.divScsiSscVisible = true;
scsiOneValue.
Add($"Device has {report.SCSI.ReadCapabilities.Blocks} blocks of {report.SCSI.ReadCapabilities.BlockSize} bytes each");
ViewBag.lblScsiSscGranularity =
report.SCSI.SequentialDevice.BlockSizeGranularity?.ToString() ?? "Unspecified";
ViewBag.lblScsiSscMaxBlock =
report.SCSI.SequentialDevice.MaxBlockLength?.ToString() ?? "Unspecified";
ViewBag.lblScsiSscMinBlock =
report.SCSI.SequentialDevice.MinBlockLength?.ToString() ?? "Unspecified";
if(report.SCSI.SequentialDevice.SupportedDensities != null)
ViewBag.repScsiSscDensities = report.SCSI.SequentialDevice.SupportedDensities;
if(report.SCSI.SequentialDevice.SupportedMediaTypes != null)
ViewBag.repScsiSscMedias = report.SCSI.SequentialDevice.SupportedMediaTypes;
if(report.SCSI.SequentialDevice.TestedMedia != null)
{
List<string> mediaOneValue = new();
SscTestedMedia.Report(report.SCSI.SequentialDevice.TestedMedia, ref mediaOneValue);
if(mediaOneValue.Count > 0)
{
sscMedia = true;
ViewBag.repTestedMedia = mediaOneValue;
}
}
}
else if(report.SCSI.ReadCapabilities != null)
{
removable = false;
scsiOneValue.Add("");
if(report.SCSI.ReadCapabilities.Blocks.HasValue &&
report.SCSI.ReadCapabilities.BlockSize.HasValue)
{
if(report.SCSI.ReadCapabilities.Blocks * report.SCSI.ReadCapabilities.BlockSize / 1024 /
1024 > 1000000)
scsiOneValue.
Add($"Device has {report.SCSI.ReadCapabilities.Blocks} blocks of {report.SCSI.ReadCapabilities.BlockSize} bytes each");
if(report.SCSI.ReadCapabilities.Blocks * report.SCSI.ReadCapabilities.BlockSize / 1024 /
1024 > 1000000)
scsiOneValue.
Add($"Device size: {report.SCSI.ReadCapabilities.Blocks * report.SCSI.ReadCapabilities.BlockSize} bytes, {report.SCSI.ReadCapabilities.Blocks * report.SCSI.ReadCapabilities.BlockSize / 1000 / 1000 / 1000 / 1000} Tb, {(double)(report.SCSI.ReadCapabilities.Blocks * report.SCSI.ReadCapabilities.BlockSize) / 1024 / 1024 / 1024 / 1024:F2} TiB");
else if(report.SCSI.ReadCapabilities.Blocks * report.SCSI.ReadCapabilities.BlockSize /
1024 / 1024 > 1000)
scsiOneValue.
Add($"Device size: {report.SCSI.ReadCapabilities.Blocks * report.SCSI.ReadCapabilities.BlockSize} bytes, {report.SCSI.ReadCapabilities.Blocks * report.SCSI.ReadCapabilities.BlockSize / 1000 / 1000 / 1000} Gb, {(double)(report.SCSI.ReadCapabilities.Blocks * report.SCSI.ReadCapabilities.BlockSize) / 1024 / 1024 / 1024:F2} GiB");
else
scsiOneValue.
Add($"Device size: {report.SCSI.ReadCapabilities.Blocks * report.SCSI.ReadCapabilities.BlockSize} bytes, {report.SCSI.ReadCapabilities.Blocks * report.SCSI.ReadCapabilities.BlockSize / 1000 / 1000} Mb, {(double)(report.SCSI.ReadCapabilities.Blocks * report.SCSI.ReadCapabilities.BlockSize) / 1024 / 1024:F2} MiB");
}
if(report.SCSI.ReadCapabilities.MediumType.HasValue)
scsiOneValue.Add($"Medium type code: {report.SCSI.ReadCapabilities.MediumType:X2}h");
if(report.SCSI.ReadCapabilities.Density.HasValue)
scsiOneValue.Add($"Density code: {report.SCSI.ReadCapabilities.Density:X2}h");
if((report.SCSI.ReadCapabilities.SupportsReadLong == true ||
report.SCSI.ReadCapabilities.SupportsReadLong16 == true) &&
report.SCSI.ReadCapabilities.LongBlockSize.HasValue)
scsiOneValue.Add($"Long block size: {report.SCSI.ReadCapabilities.LongBlockSize} bytes");
if(report.SCSI.ReadCapabilities.SupportsReadCapacity == true)
scsiOneValue.Add("Device supports READ CAPACITY (10) command.");
if(report.SCSI.ReadCapabilities.SupportsReadCapacity16 == true)
scsiOneValue.Add("Device supports READ CAPACITY (16) command.");
if(report.SCSI.ReadCapabilities.SupportsRead6 == true)
scsiOneValue.Add("Device supports READ (6) command.");
if(report.SCSI.ReadCapabilities.SupportsRead10 == true)
scsiOneValue.Add("Device supports READ (10) command.");
if(report.SCSI.ReadCapabilities.SupportsRead12 == true)
scsiOneValue.Add("Device supports READ (12) command.");
if(report.SCSI.ReadCapabilities.SupportsRead16 == true)
scsiOneValue.Add("Device supports READ (16) command.");
if(report.SCSI.ReadCapabilities.SupportsReadLong == true)
scsiOneValue.Add("Device supports READ LONG (10) command.");
if(report.SCSI.ReadCapabilities.SupportsReadLong16 == true)
scsiOneValue.Add("Device supports READ LONG (16) command.");
}
else
{
testedMedia = report.SCSI.RemovableMedias;
Add($"Device size: {report.SCSI.ReadCapabilities.Blocks * report.SCSI.ReadCapabilities.BlockSize} bytes, {report.SCSI.ReadCapabilities.Blocks * report.SCSI.ReadCapabilities.BlockSize / 1000 / 1000 / 1000 / 1000} Tb, {(double)(report.SCSI.ReadCapabilities.Blocks * report.SCSI.ReadCapabilities.BlockSize) / 1024 / 1024 / 1024 / 1024:F2} TiB");
else if(report.SCSI.ReadCapabilities.Blocks * report.SCSI.ReadCapabilities.BlockSize /
1024 / 1024 > 1000)
scsiOneValue.
Add($"Device size: {report.SCSI.ReadCapabilities.Blocks * report.SCSI.ReadCapabilities.BlockSize} bytes, {report.SCSI.ReadCapabilities.Blocks * report.SCSI.ReadCapabilities.BlockSize / 1000 / 1000 / 1000} Gb, {(double)(report.SCSI.ReadCapabilities.Blocks * report.SCSI.ReadCapabilities.BlockSize) / 1024 / 1024 / 1024:F2} GiB");
else
scsiOneValue.
Add($"Device size: {report.SCSI.ReadCapabilities.Blocks * report.SCSI.ReadCapabilities.BlockSize} bytes, {report.SCSI.ReadCapabilities.Blocks * report.SCSI.ReadCapabilities.BlockSize / 1000 / 1000} Mb, {(double)(report.SCSI.ReadCapabilities.Blocks * report.SCSI.ReadCapabilities.BlockSize) / 1024 / 1024:F2} MiB");
}
ViewBag.repScsi = scsiOneValue;
if(report.SCSI.ReadCapabilities.MediumType.HasValue)
scsiOneValue.Add($"Medium type code: {report.SCSI.ReadCapabilities.MediumType:X2}h");
if(report.SCSI.ReadCapabilities.Density.HasValue)
scsiOneValue.Add($"Density code: {report.SCSI.ReadCapabilities.Density:X2}h");
if((report.SCSI.ReadCapabilities.SupportsReadLong == true ||
report.SCSI.ReadCapabilities.SupportsReadLong16 == true) &&
report.SCSI.ReadCapabilities.LongBlockSize.HasValue)
scsiOneValue.Add($"Long block size: {report.SCSI.ReadCapabilities.LongBlockSize} bytes");
if(report.SCSI.ReadCapabilities.SupportsReadCapacity == true)
scsiOneValue.Add("Device supports READ CAPACITY (10) command.");
if(report.SCSI.ReadCapabilities.SupportsReadCapacity16 == true)
scsiOneValue.Add("Device supports READ CAPACITY (16) command.");
if(report.SCSI.ReadCapabilities.SupportsRead6 == true)
scsiOneValue.Add("Device supports READ (6) command.");
if(report.SCSI.ReadCapabilities.SupportsRead10 == true)
scsiOneValue.Add("Device supports READ (10) command.");
if(report.SCSI.ReadCapabilities.SupportsRead12 == true)
scsiOneValue.Add("Device supports READ (12) command.");
if(report.SCSI.ReadCapabilities.SupportsRead16 == true)
scsiOneValue.Add("Device supports READ (16) command.");
if(report.SCSI.ReadCapabilities.SupportsReadLong == true)
scsiOneValue.Add("Device supports READ LONG (10) command.");
if(report.SCSI.ReadCapabilities.SupportsReadLong16 == true)
scsiOneValue.Add("Device supports READ LONG (16) command.");
}
if(report.MultiMediaCard != null)
else
{
List<string> mmcOneValue = new();
if(report.MultiMediaCard.CID != null)
{
mmcOneValue.Add(Decoders.MMC.Decoders.PrettifyCID(report.MultiMediaCard.CID).
Replace("\n", "<br/>"));
mmcOneValue.Add("");
}
if(report.MultiMediaCard.CSD != null)
{
mmcOneValue.Add(Decoders.MMC.Decoders.PrettifyCSD(report.MultiMediaCard.CSD).
Replace("\n", "<br/>"));
mmcOneValue.Add("");
}
if(report.MultiMediaCard.ExtendedCSD != null)
{
mmcOneValue.Add(Decoders.MMC.Decoders.PrettifyExtendedCSD(report.MultiMediaCard.ExtendedCSD).
Replace("\n", "<br/>"));
mmcOneValue.Add("");
}
if(report.MultiMediaCard.OCR != null)
{
mmcOneValue.Add(Decoders.MMC.Decoders.PrettifyCSD(report.MultiMediaCard.OCR).
Replace("\n", "<br/>"));
mmcOneValue.Add("");
}
ViewBag.repMMC = mmcOneValue;
testedMedia = report.SCSI.RemovableMedias;
}
if(report.SecureDigital != null)
{
List<string> sdOneValue = new();
if(report.SecureDigital.CID != null)
{
sdOneValue.Add(Decoders.SecureDigital.Decoders.PrettifyCID(report.SecureDigital.CID).
Replace("\n", "<br/>"));
sdOneValue.Add("");
}
if(report.SecureDigital.CSD != null)
{
sdOneValue.Add(Decoders.SecureDigital.Decoders.PrettifyCSD(report.SecureDigital.CSD).
Replace("\n", "<br/>"));
sdOneValue.Add("");
}
if(report.SecureDigital.SCR != null)
{
sdOneValue.Add(Decoders.SecureDigital.Decoders.PrettifySCR(report.SecureDigital.SCR).
Replace("\n", "<br/>"));
sdOneValue.Add("");
}
if(report.SecureDigital.OCR != null)
{
sdOneValue.Add(Decoders.SecureDigital.Decoders.PrettifyCSD(report.SecureDigital.OCR).
Replace("\n", "<br/>"));
sdOneValue.Add("");
}
ViewBag.repSD = sdOneValue;
}
if(removable &&
!sscMedia &&
testedMedia != null)
{
List<string> mediaOneValue = new();
Core.TestedMedia.Report(testedMedia, ref mediaOneValue);
if(mediaOneValue.Count > 0)
ViewBag.repTestedMedia = mediaOneValue;
}
ViewBag.repScsi = scsiOneValue;
}
catch(Exception)
if(report.MultiMediaCard != null)
{
#if DEBUG
throw;
#endif
return Content("Could not load device report");
List<string> mmcOneValue = new();
if(report.MultiMediaCard.CID != null)
{
mmcOneValue.Add(Decoders.MMC.Decoders.PrettifyCID(report.MultiMediaCard.CID).
Replace("\n", "<br/>"));
mmcOneValue.Add("");
}
if(report.MultiMediaCard.CSD != null)
{
mmcOneValue.Add(Decoders.MMC.Decoders.PrettifyCSD(report.MultiMediaCard.CSD).
Replace("\n", "<br/>"));
mmcOneValue.Add("");
}
if(report.MultiMediaCard.ExtendedCSD != null)
{
mmcOneValue.Add(Decoders.MMC.Decoders.PrettifyExtendedCSD(report.MultiMediaCard.ExtendedCSD).
Replace("\n", "<br/>"));
mmcOneValue.Add("");
}
if(report.MultiMediaCard.OCR != null)
{
mmcOneValue.Add(Decoders.MMC.Decoders.PrettifyCSD(report.MultiMediaCard.OCR).
Replace("\n", "<br/>"));
mmcOneValue.Add("");
}
ViewBag.repMMC = mmcOneValue;
}
return View();
if(report.SecureDigital != null)
{
List<string> sdOneValue = new();
if(report.SecureDigital.CID != null)
{
sdOneValue.Add(Decoders.SecureDigital.Decoders.PrettifyCID(report.SecureDigital.CID).
Replace("\n", "<br/>"));
sdOneValue.Add("");
}
if(report.SecureDigital.CSD != null)
{
sdOneValue.Add(Decoders.SecureDigital.Decoders.PrettifyCSD(report.SecureDigital.CSD).
Replace("\n", "<br/>"));
sdOneValue.Add("");
}
if(report.SecureDigital.SCR != null)
{
sdOneValue.Add(Decoders.SecureDigital.Decoders.PrettifySCR(report.SecureDigital.SCR).
Replace("\n", "<br/>"));
sdOneValue.Add("");
}
if(report.SecureDigital.OCR != null)
{
sdOneValue.Add(Decoders.SecureDigital.Decoders.PrettifyCSD(report.SecureDigital.OCR).
Replace("\n", "<br/>"));
sdOneValue.Add("");
}
ViewBag.repSD = sdOneValue;
}
if(removable &&
!sscMedia &&
testedMedia != null)
{
List<string> mediaOneValue = new();
Core.TestedMedia.Report(testedMedia, ref mediaOneValue);
if(mediaOneValue.Count > 0)
ViewBag.repTestedMedia = mediaOneValue;
}
}
catch(Exception)
{
#if DEBUG
throw;
#endif
return Content("Could not load device report");
}
}
public class Item
{
public string Manufacturer;
public string Product;
public string ProductDescription;
public string VendorDescription;
return View();
}
}
public sealed class PcmciaItem : Item
{
public string Compliance;
}
public class Item
{
public string Manufacturer;
public string Product;
public string ProductDescription;
public string VendorDescription;
}
public sealed class PcmciaItem : Item
{
public string Compliance;
}

File diff suppressed because it is too large Load Diff

View File

@@ -43,69 +43,68 @@ using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
namespace Aaru.Server.Controllers
namespace Aaru.Server.Controllers;
public sealed class UpdateController : Controller
{
public sealed class UpdateController : Controller
readonly AaruServerContext _ctx;
public UpdateController(AaruServerContext ctx) => _ctx = ctx;
/// <summary>Receives a report from Aaru.Core, verifies it's in the correct format and stores it on the server</summary>
/// <returns>HTTP response</returns>
[Route("api/update"), HttpGet]
public ActionResult Update(long timestamp)
{
readonly AaruServerContext _ctx;
var sync = new SyncDto();
DateTime lastSync = DateHandlers.UnixToDateTime(timestamp);
public UpdateController(AaruServerContext ctx) => _ctx = ctx;
sync.UsbVendors = new List<UsbVendorDto>();
/// <summary>Receives a report from Aaru.Core, verifies it's in the correct format and stores it on the server</summary>
/// <returns>HTTP response</returns>
[Route("api/update"), HttpGet]
public ActionResult Update(long timestamp)
{
var sync = new SyncDto();
DateTime lastSync = DateHandlers.UnixToDateTime(timestamp);
sync.UsbVendors = new List<UsbVendorDto>();
foreach(UsbVendor vendor in _ctx.UsbVendors.Where(v => v.ModifiedWhen > lastSync))
sync.UsbVendors.Add(new UsbVendorDto
{
VendorId = vendor.VendorId,
Vendor = vendor.Vendor
});
sync.UsbProducts = new List<UsbProductDto>();
foreach(UsbProduct product in _ctx.UsbProducts.Include(p => p.Vendor).Where(p => p.ModifiedWhen > lastSync))
sync.UsbProducts.Add(new UsbProductDto
{
Id = product.Id,
Product = product.Product,
ProductId = product.ProductId,
VendorId = product.Vendor.VendorId
});
sync.Offsets = new List<CdOffsetDto>();
foreach(CompactDiscOffset offset in _ctx.CdOffsets.Where(o => o.ModifiedWhen > lastSync))
sync.Offsets.Add(new CdOffsetDto(offset, offset.Id));
sync.Devices = new List<DeviceDto>();
foreach(Device device in _ctx.Devices.Where(d => d.ModifiedWhen > lastSync).ToList())
sync.Devices.Add(new DeviceDto(JsonConvert.
DeserializeObject<DeviceReportV2>(JsonConvert.SerializeObject(device,
Formatting.None, new JsonSerializerSettings
{
ReferenceLoopHandling =
ReferenceLoopHandling.Ignore
})), device.Id, device.OptimalMultipleSectorsRead,
device.CanReadGdRomUsingSwapDisc));
var js = JsonSerializer.Create();
var sw = new StringWriter();
js.Serialize(sw, sync);
return new ContentResult
foreach(UsbVendor vendor in _ctx.UsbVendors.Where(v => v.ModifiedWhen > lastSync))
sync.UsbVendors.Add(new UsbVendorDto
{
StatusCode = (int)HttpStatusCode.OK,
Content = sw.ToString(),
ContentType = "application/json"
};
}
VendorId = vendor.VendorId,
Vendor = vendor.Vendor
});
sync.UsbProducts = new List<UsbProductDto>();
foreach(UsbProduct product in _ctx.UsbProducts.Include(p => p.Vendor).Where(p => p.ModifiedWhen > lastSync))
sync.UsbProducts.Add(new UsbProductDto
{
Id = product.Id,
Product = product.Product,
ProductId = product.ProductId,
VendorId = product.Vendor.VendorId
});
sync.Offsets = new List<CdOffsetDto>();
foreach(CompactDiscOffset offset in _ctx.CdOffsets.Where(o => o.ModifiedWhen > lastSync))
sync.Offsets.Add(new CdOffsetDto(offset, offset.Id));
sync.Devices = new List<DeviceDto>();
foreach(Device device in _ctx.Devices.Where(d => d.ModifiedWhen > lastSync).ToList())
sync.Devices.Add(new DeviceDto(JsonConvert.
DeserializeObject<DeviceReportV2>(JsonConvert.SerializeObject(device,
Formatting.None, new JsonSerializerSettings
{
ReferenceLoopHandling =
ReferenceLoopHandling.Ignore
})), device.Id, device.OptimalMultipleSectorsRead,
device.CanReadGdRomUsingSwapDisc));
var js = JsonSerializer.Create();
var sw = new StringWriter();
js.Serialize(sw, sync);
return new ContentResult
{
StatusCode = (int)HttpStatusCode.OK,
Content = sw.ToString(),
ContentType = "application/json"
};
}
}

View File

@@ -48,354 +48,353 @@ using Microsoft.AspNetCore.Mvc;
using MimeKit;
using Newtonsoft.Json;
namespace Aaru.Server.Controllers
namespace Aaru.Server.Controllers;
public sealed class UploadReportController : Controller
{
public sealed class UploadReportController : Controller
readonly AaruServerContext _ctx;
readonly IWebHostEnvironment _environment;
public UploadReportController(IWebHostEnvironment environment, AaruServerContext ctx)
{
readonly AaruServerContext _ctx;
readonly IWebHostEnvironment _environment;
_environment = environment;
_ctx = ctx;
}
public UploadReportController(IWebHostEnvironment environment, AaruServerContext ctx)
/// <summary>Receives a report from Aaru.Core, verifies it's in the correct format and stores it on the server</summary>
/// <returns>HTTP response</returns>
[Route("api/uploadreport"), HttpPost]
public async Task<IActionResult> UploadReport()
{
var response = new ContentResult
{
_environment = environment;
_ctx = ctx;
}
StatusCode = (int)HttpStatusCode.OK,
ContentType = "text/plain"
};
/// <summary>Receives a report from Aaru.Core, verifies it's in the correct format and stores it on the server</summary>
/// <returns>HTTP response</returns>
[Route("api/uploadreport"), HttpPost]
public async Task<IActionResult> UploadReport()
try
{
var response = new ContentResult
var newReport = new DeviceReport();
HttpRequest request = HttpContext.Request;
var xs = new XmlSerializer(newReport.GetType());
newReport =
(DeviceReport)
xs.Deserialize(new StringReader(await new StreamReader(request.Body).ReadToEndAsync()));
if(newReport == null)
{
StatusCode = (int)HttpStatusCode.OK,
ContentType = "text/plain"
response.Content = "notstats";
return response;
}
var reportV2 = new DeviceReportV2(newReport);
var jsonSw = new StringWriter();
await jsonSw.WriteAsync(JsonConvert.SerializeObject(reportV2, Formatting.Indented,
new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore
}));
string reportV2String = jsonSw.ToString();
jsonSw.Close();
var newUploadedReport = new UploadedReport(reportV2);
// Ensure CHS and CurrentCHS are not duplicates
if(newUploadedReport.ATA?.ReadCapabilities?.CHS != null &&
newUploadedReport.ATA?.ReadCapabilities?.CurrentCHS != null)
{
if(newUploadedReport.ATA.ReadCapabilities.CHS.Cylinders ==
newUploadedReport.ATA.ReadCapabilities.CurrentCHS.Cylinders &&
newUploadedReport.ATA.ReadCapabilities.CHS.Heads ==
newUploadedReport.ATA.ReadCapabilities.CurrentCHS.Heads &&
newUploadedReport.ATA.ReadCapabilities.CHS.Sectors ==
newUploadedReport.ATA.ReadCapabilities.CurrentCHS.Sectors)
{
newUploadedReport.ATA.ReadCapabilities.CHS = newUploadedReport.ATA.ReadCapabilities.CurrentCHS;
}
}
// Check if the CHS or CurrentCHS of this report already exist in the database
if(newUploadedReport.ATA?.ReadCapabilities?.CHS != null)
{
Chs existingChs =
_ctx.Chs.FirstOrDefault(c =>
c.Cylinders == newUploadedReport.ATA.ReadCapabilities.CHS.
Cylinders &&
c.Heads == newUploadedReport.ATA.ReadCapabilities.CHS.Heads &&
c.Sectors == newUploadedReport.ATA.ReadCapabilities.CHS.Sectors);
if(existingChs != null)
newUploadedReport.ATA.ReadCapabilities.CHS = existingChs;
}
if(newUploadedReport.ATA?.ReadCapabilities?.CurrentCHS != null)
{
Chs existingChs =
_ctx.Chs.FirstOrDefault(c =>
c.Cylinders == newUploadedReport.ATA.ReadCapabilities.CurrentCHS.
Cylinders &&
c.Heads == newUploadedReport.ATA.ReadCapabilities.CurrentCHS.
Heads && c.Sectors == newUploadedReport.ATA.ReadCapabilities.
CurrentCHS.Sectors);
if(existingChs != null)
newUploadedReport.ATA.ReadCapabilities.CurrentCHS = existingChs;
}
if(newUploadedReport.ATA?.RemovableMedias != null)
{
foreach(TestedMedia media in newUploadedReport.ATA.RemovableMedias)
{
if(media.CHS != null &&
media.CurrentCHS != null)
{
if(media.CHS.Cylinders == media.CurrentCHS.Cylinders &&
media.CHS.Heads == media.CurrentCHS.Heads &&
media.CHS.Sectors == media.CurrentCHS.Sectors)
{
media.CHS = media.CurrentCHS;
}
}
if(media.CHS != null)
{
Chs existingChs =
_ctx.Chs.FirstOrDefault(c => c.Cylinders == media.CHS.Cylinders &&
c.Heads == media.CHS.Heads &&
c.Sectors == media.CHS.Sectors);
if(existingChs != null)
media.CHS = existingChs;
}
if(media.CHS != null)
{
Chs existingChs =
_ctx.Chs.FirstOrDefault(c => c.Cylinders == media.CurrentCHS.Cylinders &&
c.Heads == media.CurrentCHS.Heads &&
c.Sectors == media.CurrentCHS.Sectors);
if(existingChs != null)
media.CurrentCHS = existingChs;
}
}
}
await _ctx.Reports.AddAsync(newUploadedReport);
await _ctx.SaveChangesAsync();
var pgpIn = new MemoryStream(Encoding.UTF8.GetBytes(reportV2String));
var pgpOut = new MemoryStream();
var pgp = new ChoPGPEncryptDecrypt();
await pgp.EncryptAsync(pgpIn, pgpOut,
Path.Combine(_environment.ContentRootPath ?? throw new InvalidOperationException(),
"public.asc"));
pgpOut.Position = 0;
reportV2String = Encoding.UTF8.GetString(pgpOut.ToArray());
var message = new MimeMessage
{
Subject = "New device report (old version)",
Body = new TextPart("plain")
{
Text = reportV2String
}
};
try
message.From.Add(new MailboxAddress("Aaru Server", "aaru@claunia.com"));
message.To.Add(new MailboxAddress("Natalia Portillo", "claunia@claunia.com"));
using(var client = new SmtpClient())
{
var newReport = new DeviceReport();
HttpRequest request = HttpContext.Request;
var xs = new XmlSerializer(newReport.GetType());
newReport =
(DeviceReport)
xs.Deserialize(new StringReader(await new StreamReader(request.Body).ReadToEndAsync()));
if(newReport == null)
{
response.Content = "notstats";
return response;
}
var reportV2 = new DeviceReportV2(newReport);
var jsonSw = new StringWriter();
await jsonSw.WriteAsync(JsonConvert.SerializeObject(reportV2, Formatting.Indented,
new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore
}));
string reportV2String = jsonSw.ToString();
jsonSw.Close();
var newUploadedReport = new UploadedReport(reportV2);
// Ensure CHS and CurrentCHS are not duplicates
if(newUploadedReport.ATA?.ReadCapabilities?.CHS != null &&
newUploadedReport.ATA?.ReadCapabilities?.CurrentCHS != null)
{
if(newUploadedReport.ATA.ReadCapabilities.CHS.Cylinders ==
newUploadedReport.ATA.ReadCapabilities.CurrentCHS.Cylinders &&
newUploadedReport.ATA.ReadCapabilities.CHS.Heads ==
newUploadedReport.ATA.ReadCapabilities.CurrentCHS.Heads &&
newUploadedReport.ATA.ReadCapabilities.CHS.Sectors ==
newUploadedReport.ATA.ReadCapabilities.CurrentCHS.Sectors)
{
newUploadedReport.ATA.ReadCapabilities.CHS = newUploadedReport.ATA.ReadCapabilities.CurrentCHS;
}
}
// Check if the CHS or CurrentCHS of this report already exist in the database
if(newUploadedReport.ATA?.ReadCapabilities?.CHS != null)
{
Chs existingChs =
_ctx.Chs.FirstOrDefault(c =>
c.Cylinders == newUploadedReport.ATA.ReadCapabilities.CHS.
Cylinders &&
c.Heads == newUploadedReport.ATA.ReadCapabilities.CHS.Heads &&
c.Sectors == newUploadedReport.ATA.ReadCapabilities.CHS.Sectors);
if(existingChs != null)
newUploadedReport.ATA.ReadCapabilities.CHS = existingChs;
}
if(newUploadedReport.ATA?.ReadCapabilities?.CurrentCHS != null)
{
Chs existingChs =
_ctx.Chs.FirstOrDefault(c =>
c.Cylinders == newUploadedReport.ATA.ReadCapabilities.CurrentCHS.
Cylinders &&
c.Heads == newUploadedReport.ATA.ReadCapabilities.CurrentCHS.
Heads && c.Sectors == newUploadedReport.ATA.ReadCapabilities.
CurrentCHS.Sectors);
if(existingChs != null)
newUploadedReport.ATA.ReadCapabilities.CurrentCHS = existingChs;
}
if(newUploadedReport.ATA?.RemovableMedias != null)
{
foreach(TestedMedia media in newUploadedReport.ATA.RemovableMedias)
{
if(media.CHS != null &&
media.CurrentCHS != null)
{
if(media.CHS.Cylinders == media.CurrentCHS.Cylinders &&
media.CHS.Heads == media.CurrentCHS.Heads &&
media.CHS.Sectors == media.CurrentCHS.Sectors)
{
media.CHS = media.CurrentCHS;
}
}
if(media.CHS != null)
{
Chs existingChs =
_ctx.Chs.FirstOrDefault(c => c.Cylinders == media.CHS.Cylinders &&
c.Heads == media.CHS.Heads &&
c.Sectors == media.CHS.Sectors);
if(existingChs != null)
media.CHS = existingChs;
}
if(media.CHS != null)
{
Chs existingChs =
_ctx.Chs.FirstOrDefault(c => c.Cylinders == media.CurrentCHS.Cylinders &&
c.Heads == media.CurrentCHS.Heads &&
c.Sectors == media.CurrentCHS.Sectors);
if(existingChs != null)
media.CurrentCHS = existingChs;
}
}
}
await _ctx.Reports.AddAsync(newUploadedReport);
await _ctx.SaveChangesAsync();
var pgpIn = new MemoryStream(Encoding.UTF8.GetBytes(reportV2String));
var pgpOut = new MemoryStream();
var pgp = new ChoPGPEncryptDecrypt();
await pgp.EncryptAsync(pgpIn, pgpOut,
Path.Combine(_environment.ContentRootPath ?? throw new InvalidOperationException(),
"public.asc"));
pgpOut.Position = 0;
reportV2String = Encoding.UTF8.GetString(pgpOut.ToArray());
var message = new MimeMessage
{
Subject = "New device report (old version)",
Body = new TextPart("plain")
{
Text = reportV2String
}
};
message.From.Add(new MailboxAddress("Aaru Server", "aaru@claunia.com"));
message.To.Add(new MailboxAddress("Natalia Portillo", "claunia@claunia.com"));
using(var client = new SmtpClient())
{
await client.ConnectAsync("mail.claunia.com", 25, false);
await client.SendAsync(message);
await client.DisconnectAsync(true);
}
response.Content = "ok";
return response;
await client.ConnectAsync("mail.claunia.com", 25, false);
await client.SendAsync(message);
await client.DisconnectAsync(true);
}
// ReSharper disable once RedundantCatchClause
catch
{
#if DEBUG
if(Debugger.IsAttached)
throw;
#endif
response.Content = "error";
response.Content = "ok";
return response;
}
return response;
}
/// <summary>Receives a report from Aaru.Core, verifies it's in the correct format and stores it on the server</summary>
/// <returns>HTTP response</returns>
[Route("api/uploadreportv2"), HttpPost]
public async Task<IActionResult> UploadReportV2()
// ReSharper disable once RedundantCatchClause
catch
{
var response = new ContentResult
#if DEBUG
if(Debugger.IsAttached)
throw;
#endif
response.Content = "error";
return response;
}
}
/// <summary>Receives a report from Aaru.Core, verifies it's in the correct format and stores it on the server</summary>
/// <returns>HTTP response</returns>
[Route("api/uploadreportv2"), HttpPost]
public async Task<IActionResult> UploadReportV2()
{
var response = new ContentResult
{
StatusCode = (int)HttpStatusCode.OK,
ContentType = "text/plain"
};
try
{
HttpRequest request = HttpContext.Request;
var sr = new StreamReader(request.Body);
string reportJson = await sr.ReadToEndAsync();
DeviceReportV2 newReport = JsonConvert.DeserializeObject<DeviceReportV2>(reportJson);
if(newReport == null)
{
StatusCode = (int)HttpStatusCode.OK,
ContentType = "text/plain"
response.Content = "notstats";
return response;
}
var newUploadedReport = new UploadedReport(newReport);
// Ensure CHS and CurrentCHS are not duplicates
if(newUploadedReport.ATA?.ReadCapabilities?.CHS != null &&
newUploadedReport.ATA?.ReadCapabilities?.CurrentCHS != null)
{
if(newUploadedReport.ATA.ReadCapabilities.CHS.Cylinders ==
newUploadedReport.ATA.ReadCapabilities.CurrentCHS.Cylinders &&
newUploadedReport.ATA.ReadCapabilities.CHS.Heads ==
newUploadedReport.ATA.ReadCapabilities.CurrentCHS.Heads &&
newUploadedReport.ATA.ReadCapabilities.CHS.Sectors ==
newUploadedReport.ATA.ReadCapabilities.CurrentCHS.Sectors)
{
newUploadedReport.ATA.ReadCapabilities.CHS = newUploadedReport.ATA.ReadCapabilities.CurrentCHS;
}
}
// Check if the CHS or CurrentCHS of this report already exist in the database
if(newUploadedReport.ATA?.ReadCapabilities?.CHS != null)
{
Chs existingChs =
_ctx.Chs.FirstOrDefault(c =>
c.Cylinders == newUploadedReport.ATA.ReadCapabilities.CHS.
Cylinders &&
c.Heads == newUploadedReport.ATA.ReadCapabilities.CHS.Heads &&
c.Sectors == newUploadedReport.ATA.ReadCapabilities.CHS.Sectors);
if(existingChs != null)
newUploadedReport.ATA.ReadCapabilities.CHS = existingChs;
}
if(newUploadedReport.ATA?.ReadCapabilities?.CurrentCHS != null)
{
Chs existingChs =
_ctx.Chs.FirstOrDefault(c =>
c.Cylinders == newUploadedReport.ATA.ReadCapabilities.CurrentCHS.
Cylinders &&
c.Heads == newUploadedReport.ATA.ReadCapabilities.CurrentCHS.
Heads && c.Sectors == newUploadedReport.ATA.ReadCapabilities.
CurrentCHS.Sectors);
if(existingChs != null)
newUploadedReport.ATA.ReadCapabilities.CurrentCHS = existingChs;
}
if(newUploadedReport.ATA?.RemovableMedias != null)
{
foreach(TestedMedia media in newUploadedReport.ATA.RemovableMedias)
{
if(media.CHS != null &&
media.CurrentCHS != null)
{
if(media.CHS.Cylinders == media.CurrentCHS.Cylinders &&
media.CHS.Heads == media.CurrentCHS.Heads &&
media.CHS.Sectors == media.CurrentCHS.Sectors)
{
media.CHS = media.CurrentCHS;
}
}
if(media.CHS != null)
{
Chs existingChs =
_ctx.Chs.FirstOrDefault(c => c.Cylinders == media.CHS.Cylinders &&
c.Heads == media.CHS.Heads &&
c.Sectors == media.CHS.Sectors);
if(existingChs != null)
media.CHS = existingChs;
}
if(media.CHS != null)
{
Chs existingChs =
_ctx.Chs.FirstOrDefault(c => c.Cylinders == media.CurrentCHS.Cylinders &&
c.Heads == media.CurrentCHS.Heads &&
c.Sectors == media.CurrentCHS.Sectors);
if(existingChs != null)
media.CurrentCHS = existingChs;
}
}
}
await _ctx.Reports.AddAsync(newUploadedReport);
await _ctx.SaveChangesAsync();
var pgpIn = new MemoryStream(Encoding.UTF8.GetBytes(reportJson));
var pgpOut = new MemoryStream();
var pgp = new ChoPGPEncryptDecrypt();
await pgp.EncryptAsync(pgpIn, pgpOut,
Path.Combine(_environment.ContentRootPath ?? throw new InvalidOperationException(),
"public.asc"));
pgpOut.Position = 0;
reportJson = Encoding.UTF8.GetString(pgpOut.ToArray());
var message = new MimeMessage
{
Subject = "New device report",
Body = new TextPart("plain")
{
Text = reportJson
}
};
try
message.From.Add(new MailboxAddress("Aaru Server", "aaru@claunia.com"));
message.To.Add(new MailboxAddress("Natalia Portillo", "claunia@claunia.com"));
using(var client = new SmtpClient())
{
HttpRequest request = HttpContext.Request;
var sr = new StreamReader(request.Body);
string reportJson = await sr.ReadToEndAsync();
DeviceReportV2 newReport = JsonConvert.DeserializeObject<DeviceReportV2>(reportJson);
if(newReport == null)
{
response.Content = "notstats";
return response;
}
var newUploadedReport = new UploadedReport(newReport);
// Ensure CHS and CurrentCHS are not duplicates
if(newUploadedReport.ATA?.ReadCapabilities?.CHS != null &&
newUploadedReport.ATA?.ReadCapabilities?.CurrentCHS != null)
{
if(newUploadedReport.ATA.ReadCapabilities.CHS.Cylinders ==
newUploadedReport.ATA.ReadCapabilities.CurrentCHS.Cylinders &&
newUploadedReport.ATA.ReadCapabilities.CHS.Heads ==
newUploadedReport.ATA.ReadCapabilities.CurrentCHS.Heads &&
newUploadedReport.ATA.ReadCapabilities.CHS.Sectors ==
newUploadedReport.ATA.ReadCapabilities.CurrentCHS.Sectors)
{
newUploadedReport.ATA.ReadCapabilities.CHS = newUploadedReport.ATA.ReadCapabilities.CurrentCHS;
}
}
// Check if the CHS or CurrentCHS of this report already exist in the database
if(newUploadedReport.ATA?.ReadCapabilities?.CHS != null)
{
Chs existingChs =
_ctx.Chs.FirstOrDefault(c =>
c.Cylinders == newUploadedReport.ATA.ReadCapabilities.CHS.
Cylinders &&
c.Heads == newUploadedReport.ATA.ReadCapabilities.CHS.Heads &&
c.Sectors == newUploadedReport.ATA.ReadCapabilities.CHS.Sectors);
if(existingChs != null)
newUploadedReport.ATA.ReadCapabilities.CHS = existingChs;
}
if(newUploadedReport.ATA?.ReadCapabilities?.CurrentCHS != null)
{
Chs existingChs =
_ctx.Chs.FirstOrDefault(c =>
c.Cylinders == newUploadedReport.ATA.ReadCapabilities.CurrentCHS.
Cylinders &&
c.Heads == newUploadedReport.ATA.ReadCapabilities.CurrentCHS.
Heads && c.Sectors == newUploadedReport.ATA.ReadCapabilities.
CurrentCHS.Sectors);
if(existingChs != null)
newUploadedReport.ATA.ReadCapabilities.CurrentCHS = existingChs;
}
if(newUploadedReport.ATA?.RemovableMedias != null)
{
foreach(TestedMedia media in newUploadedReport.ATA.RemovableMedias)
{
if(media.CHS != null &&
media.CurrentCHS != null)
{
if(media.CHS.Cylinders == media.CurrentCHS.Cylinders &&
media.CHS.Heads == media.CurrentCHS.Heads &&
media.CHS.Sectors == media.CurrentCHS.Sectors)
{
media.CHS = media.CurrentCHS;
}
}
if(media.CHS != null)
{
Chs existingChs =
_ctx.Chs.FirstOrDefault(c => c.Cylinders == media.CHS.Cylinders &&
c.Heads == media.CHS.Heads &&
c.Sectors == media.CHS.Sectors);
if(existingChs != null)
media.CHS = existingChs;
}
if(media.CHS != null)
{
Chs existingChs =
_ctx.Chs.FirstOrDefault(c => c.Cylinders == media.CurrentCHS.Cylinders &&
c.Heads == media.CurrentCHS.Heads &&
c.Sectors == media.CurrentCHS.Sectors);
if(existingChs != null)
media.CurrentCHS = existingChs;
}
}
}
await _ctx.Reports.AddAsync(newUploadedReport);
await _ctx.SaveChangesAsync();
var pgpIn = new MemoryStream(Encoding.UTF8.GetBytes(reportJson));
var pgpOut = new MemoryStream();
var pgp = new ChoPGPEncryptDecrypt();
await pgp.EncryptAsync(pgpIn, pgpOut,
Path.Combine(_environment.ContentRootPath ?? throw new InvalidOperationException(),
"public.asc"));
pgpOut.Position = 0;
reportJson = Encoding.UTF8.GetString(pgpOut.ToArray());
var message = new MimeMessage
{
Subject = "New device report",
Body = new TextPart("plain")
{
Text = reportJson
}
};
message.From.Add(new MailboxAddress("Aaru Server", "aaru@claunia.com"));
message.To.Add(new MailboxAddress("Natalia Portillo", "claunia@claunia.com"));
using(var client = new SmtpClient())
{
await client.ConnectAsync("mail.claunia.com", 25, false);
await client.SendAsync(message);
await client.DisconnectAsync(true);
}
response.Content = "ok";
return response;
await client.ConnectAsync("mail.claunia.com", 25, false);
await client.SendAsync(message);
await client.DisconnectAsync(true);
}
// ReSharper disable once RedundantCatchClause
catch
{
#if DEBUG
if(Debugger.IsAttached)
throw;
#endif
response.Content = "error";
response.Content = "ok";
return response;
}
return response;
}
// ReSharper disable once RedundantCatchClause
catch
{
#if DEBUG
if(Debugger.IsAttached)
throw;
#endif
response.Content = "error";
return response;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,36 +1,35 @@
using System.Security.Cryptography;
namespace Aaru.Server.Core
namespace Aaru.Server.Core;
public static class Hash
{
public static class Hash
public static string Sha512(byte[] data)
{
public static string Sha512(byte[] data)
byte[] hash;
using(var sha = new SHA512Managed())
{
byte[] hash;
using(var sha = new SHA512Managed())
{
sha.Initialize();
hash = sha.ComputeHash(data);
}
char[] chars = new char[hash.Length * 2];
int j = 0;
foreach(byte b in hash)
{
int nibble1 = (b & 0xF0) >> 4;
int nibble2 = b & 0x0F;
nibble1 += nibble1 > 9 ? 0x57 : 0x30;
nibble2 += nibble2 > 9 ? 0x57 : 0x30;
chars[j++] = (char)nibble1;
chars[j++] = (char)nibble2;
}
return new string(chars);
sha.Initialize();
hash = sha.ComputeHash(data);
}
char[] chars = new char[hash.Length * 2];
int j = 0;
foreach(byte b in hash)
{
int nibble1 = (b & 0xF0) >> 4;
int nibble2 = b & 0x0F;
nibble1 += nibble1 > 9 ? 0x57 : 0x30;
nibble2 += nibble2 > 9 ? 0x57 : 0x30;
chars[j++] = (char)nibble1;
chars[j++] = (char)nibble2;
}
return new string(chars);
}
}

View File

@@ -2,24 +2,23 @@ using System.Text.RegularExpressions;
using Aaru.CommonTypes.Metadata;
using Microsoft.AspNetCore.Mvc.Rendering;
namespace Aaru.Server.Core
namespace Aaru.Server.Core;
public static class HtmlHelpers
{
public static class HtmlHelpers
{
public static string EncodedMultiLineText(this IHtmlHelper<CommonTypes.Metadata.Ata> helper, string text) =>
string.IsNullOrEmpty(text) ? string.Empty
: Regex.Replace(helper.Encode(text), "&#xD;&#xA;|&#xA;|&#xD;", "<br/>");
public static string EncodedMultiLineText(this IHtmlHelper<CommonTypes.Metadata.Ata> helper, string text) =>
string.IsNullOrEmpty(text) ? string.Empty
: Regex.Replace(helper.Encode(text), "&#xD;&#xA;|&#xA;|&#xD;", "<br/>");
public static string EncodedMultiLineText(this IHtmlHelper<Mmc> helper, string text) =>
string.IsNullOrEmpty(text) ? string.Empty
: Regex.Replace(helper.Encode(text), "&#xD;&#xA;|&#xA;|&#xD;", "<br/>");
public static string EncodedMultiLineText(this IHtmlHelper<Mmc> helper, string text) =>
string.IsNullOrEmpty(text) ? string.Empty
: Regex.Replace(helper.Encode(text), "&#xD;&#xA;|&#xA;|&#xD;", "<br/>");
public static string EncodedMultiLineText(this IHtmlHelper<MmcSd> helper, string text) =>
string.IsNullOrEmpty(text) ? string.Empty
: Regex.Replace(helper.Encode(text), "&#xD;&#xA;|&#xA;|&#xD;", "<br/>");
public static string EncodedMultiLineText(this IHtmlHelper<MmcSd> helper, string text) =>
string.IsNullOrEmpty(text) ? string.Empty
: Regex.Replace(helper.Encode(text), "&#xD;&#xA;|&#xA;|&#xD;", "<br/>");
public static string EncodedMultiLineText(this IHtmlHelper<Scsi> helper, string text) =>
string.IsNullOrEmpty(text) ? string.Empty
: Regex.Replace(helper.Encode(text), "&#xD;&#xA;|&#xA;|&#xD;", "<br/>");
}
public static string EncodedMultiLineText(this IHtmlHelper<Scsi> helper, string text) =>
string.IsNullOrEmpty(text) ? string.Empty
: Regex.Replace(helper.Encode(text), "&#xD;&#xA;|&#xA;|&#xD;", "<br/>");
}

View File

@@ -34,80 +34,79 @@ using System.Collections.Generic;
using Aaru.CommonTypes.Metadata;
using Aaru.Decoders.SCSI;
namespace Aaru.Server.Core
namespace Aaru.Server.Core;
public static class ScsiEvpd
{
public static class ScsiEvpd
/// <summary>
/// Takes the SCSI EVPD part of a device report and prints it as a list key=value pairs to be sequenced by ASP.NET
/// in the rendering
/// </summary>
/// <param name="pages">EVPD pages</param>
/// <param name="vendor">SCSI vendor string</param>
/// <param name="evpdPages">List to put the key=value pairs on</param>
public static void Report(IEnumerable<ScsiPage> pages, string vendor, ref Dictionary<string, string> evpdPages)
{
/// <summary>
/// Takes the SCSI EVPD part of a device report and prints it as a list key=value pairs to be sequenced by ASP.NET
/// in the rendering
/// </summary>
/// <param name="pages">EVPD pages</param>
/// <param name="vendor">SCSI vendor string</param>
/// <param name="evpdPages">List to put the key=value pairs on</param>
public static void Report(IEnumerable<ScsiPage> pages, string vendor, ref Dictionary<string, string> evpdPages)
foreach(ScsiPage evpd in pages)
{
foreach(ScsiPage evpd in pages)
{
string decoded;
string decoded;
if(evpd.page >= 0x01 &&
evpd.page <= 0x7F)
decoded = EVPD.DecodeASCIIPage(evpd.value);
else if(evpd.page == 0x81)
decoded = EVPD.PrettifyPage_81(evpd.value);
else if(evpd.page == 0x82)
decoded = EVPD.DecodePage82(evpd.value);
else if(evpd.page == 0x83)
decoded = EVPD.PrettifyPage_83(evpd.value);
else if(evpd.page == 0x84)
decoded = EVPD.PrettifyPage_84(evpd.value);
else if(evpd.page == 0x85)
decoded = EVPD.PrettifyPage_85(evpd.value);
else if(evpd.page == 0x86)
decoded = EVPD.PrettifyPage_86(evpd.value);
else if(evpd.page == 0x89)
decoded = EVPD.PrettifyPage_89(evpd.value);
else if(evpd.page == 0xB0)
decoded = EVPD.PrettifyPage_B0(evpd.value);
else if(evpd.page == 0xB2)
decoded = $"TapeAlert Supported Flags Bitmap: 0x{EVPD.DecodePageB2(evpd.value):X16}<br/>";
else if(evpd.page == 0xB4)
decoded = EVPD.DecodePageB4(evpd.value);
else if(evpd.page == 0xC0 &&
vendor.Trim() == "quantum")
decoded = EVPD.PrettifyPage_C0_Quantum(evpd.value);
else if(evpd.page == 0xC0 &&
vendor.Trim() == "seagate")
decoded = EVPD.PrettifyPage_C0_Seagate(evpd.value);
else if(evpd.page == 0xC0 &&
vendor.Trim() == "ibm")
decoded = EVPD.PrettifyPage_C0_IBM(evpd.value);
else if(evpd.page == 0xC1 &&
vendor.Trim() == "ibm")
decoded = EVPD.PrettifyPage_C1_IBM(evpd.value);
else if((evpd.page == 0xC0 || evpd.page == 0xC1) &&
vendor.Trim() == "certance")
decoded = EVPD.PrettifyPage_C0_C1_Certance(evpd.value);
else if((evpd.page == 0xC2 || evpd.page == 0xC3 || evpd.page == 0xC4 || evpd.page == 0xC5 ||
evpd.page == 0xC6) &&
vendor.Trim() == "certance")
decoded = EVPD.PrettifyPage_C2_C3_C4_C5_C6_Certance(evpd.value);
else if((evpd.page == 0xC0 || evpd.page == 0xC1 || evpd.page == 0xC2 || evpd.page == 0xC3 ||
evpd.page == 0xC4 || evpd.page == 0xC5) &&
vendor.Trim() == "hp")
decoded = EVPD.PrettifyPage_C0_to_C5_HP(evpd.value);
else if(evpd.page == 0xDF &&
vendor.Trim() == "certance")
decoded = EVPD.PrettifyPage_DF_Certance(evpd.value);
else
decoded = "Undecoded";
if(evpd.page >= 0x01 &&
evpd.page <= 0x7F)
decoded = EVPD.DecodeASCIIPage(evpd.value);
else if(evpd.page == 0x81)
decoded = EVPD.PrettifyPage_81(evpd.value);
else if(evpd.page == 0x82)
decoded = EVPD.DecodePage82(evpd.value);
else if(evpd.page == 0x83)
decoded = EVPD.PrettifyPage_83(evpd.value);
else if(evpd.page == 0x84)
decoded = EVPD.PrettifyPage_84(evpd.value);
else if(evpd.page == 0x85)
decoded = EVPD.PrettifyPage_85(evpd.value);
else if(evpd.page == 0x86)
decoded = EVPD.PrettifyPage_86(evpd.value);
else if(evpd.page == 0x89)
decoded = EVPD.PrettifyPage_89(evpd.value);
else if(evpd.page == 0xB0)
decoded = EVPD.PrettifyPage_B0(evpd.value);
else if(evpd.page == 0xB2)
decoded = $"TapeAlert Supported Flags Bitmap: 0x{EVPD.DecodePageB2(evpd.value):X16}<br/>";
else if(evpd.page == 0xB4)
decoded = EVPD.DecodePageB4(evpd.value);
else if(evpd.page == 0xC0 &&
vendor.Trim() == "quantum")
decoded = EVPD.PrettifyPage_C0_Quantum(evpd.value);
else if(evpd.page == 0xC0 &&
vendor.Trim() == "seagate")
decoded = EVPD.PrettifyPage_C0_Seagate(evpd.value);
else if(evpd.page == 0xC0 &&
vendor.Trim() == "ibm")
decoded = EVPD.PrettifyPage_C0_IBM(evpd.value);
else if(evpd.page == 0xC1 &&
vendor.Trim() == "ibm")
decoded = EVPD.PrettifyPage_C1_IBM(evpd.value);
else if((evpd.page == 0xC0 || evpd.page == 0xC1) &&
vendor.Trim() == "certance")
decoded = EVPD.PrettifyPage_C0_C1_Certance(evpd.value);
else if((evpd.page == 0xC2 || evpd.page == 0xC3 || evpd.page == 0xC4 || evpd.page == 0xC5 ||
evpd.page == 0xC6) &&
vendor.Trim() == "certance")
decoded = EVPD.PrettifyPage_C2_C3_C4_C5_C6_Certance(evpd.value);
else if((evpd.page == 0xC0 || evpd.page == 0xC1 || evpd.page == 0xC2 || evpd.page == 0xC3 ||
evpd.page == 0xC4 || evpd.page == 0xC5) &&
vendor.Trim() == "hp")
decoded = EVPD.PrettifyPage_C0_to_C5_HP(evpd.value);
else if(evpd.page == 0xDF &&
vendor.Trim() == "certance")
decoded = EVPD.PrettifyPage_DF_Certance(evpd.value);
else
decoded = "Undecoded";
if(!string.IsNullOrEmpty(decoded))
decoded = decoded.Replace("\n", "<br/>");
if(!string.IsNullOrEmpty(decoded))
decoded = decoded.Replace("\n", "<br/>");
evpdPages.Add($"EVPD page {evpd.page:X2}h", decoded);
}
evpdPages.Add($"EVPD page {evpd.page:X2}h", decoded);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -34,489 +34,488 @@ using System.Collections.Generic;
using Aaru.CommonTypes.Metadata;
using Aaru.CommonTypes.Structs.Devices.SCSI;
namespace Aaru.Server.Core
namespace Aaru.Server.Core;
public static class ScsiMmcFeatures
{
public static class ScsiMmcFeatures
/// <summary>
/// Takes the MMC FEATURES part of a device report and prints it as a list of values to be sequenced by ASP.NET in
/// the rendering
/// </summary>
/// <param name="ftr">FEATURES part of the report</param>
/// <param name="mmcOneValue">List to put the values on</param>
public static void Report(MmcFeatures ftr, ref List<string> mmcOneValue)
{
/// <summary>
/// Takes the MMC FEATURES part of a device report and prints it as a list of values to be sequenced by ASP.NET in
/// the rendering
/// </summary>
/// <param name="ftr">FEATURES part of the report</param>
/// <param name="mmcOneValue">List to put the values on</param>
public static void Report(MmcFeatures ftr, ref List<string> mmcOneValue)
if(ftr.SupportsAACS &&
ftr.AACSVersion.HasValue)
mmcOneValue.Add($"Drive supports AACS version {ftr.AACSVersion}");
else if(ftr.SupportsAACS)
mmcOneValue.Add("Drive supports AACS");
if(ftr.AGIDs.HasValue)
mmcOneValue.Add($"Drive supports {ftr.AGIDs} AGIDs concurrently");
if(ftr.CanGenerateBindingNonce)
{
if(ftr.SupportsAACS &&
ftr.AACSVersion.HasValue)
mmcOneValue.Add($"Drive supports AACS version {ftr.AACSVersion}");
else if(ftr.SupportsAACS)
mmcOneValue.Add("Drive supports AACS");
mmcOneValue.Add("Drive supports generating the binding nonce");
if(ftr.AGIDs.HasValue)
mmcOneValue.Add($"Drive supports {ftr.AGIDs} AGIDs concurrently");
if(ftr.CanGenerateBindingNonce)
{
mmcOneValue.Add("Drive supports generating the binding nonce");
if(ftr.BindingNonceBlocks.HasValue)
mmcOneValue.Add($"{ftr.BindingNonceBlocks} media blocks are required for the binding nonce");
}
if(ftr.BlocksPerReadableUnit > 1)
mmcOneValue.Add($"{ftr.BlocksPerReadableUnit} logical blocks per media writable unit");
if(ftr.BufferUnderrunFreeInDVD)
mmcOneValue.Add("Drive supports zero loss linking writing DVDs");
if(ftr.BufferUnderrunFreeInSAO)
mmcOneValue.Add("Drive supports zero loss linking in Session at Once Mode");
if(ftr.BufferUnderrunFreeInTAO)
mmcOneValue.Add("Drive supports zero loss linking in Track at Once Mode");
if(ftr.CanAudioScan)
mmcOneValue.Add("Drive supports the SCAN command");
if(ftr.CanEject)
mmcOneValue.Add("Drive can eject media");
if(ftr.CanEraseSector)
mmcOneValue.Add("Drive supports media that require erasing before writing");
if(ftr.CanExpandBDRESpareArea)
mmcOneValue.Add("Drive can expand the spare area on a formatted BD-RE disc");
if(ftr.CanFormat)
mmcOneValue.Add("Drive can format media into logical blocks");
if(ftr.CanFormatBDREWithoutSpare)
mmcOneValue.Add("Drive can format BD-RE with no spares allocated");
if(ftr.CanFormatQCert)
mmcOneValue.Add("Drive can format BD-RE discs with quick certification");
if(ftr.CanFormatCert)
mmcOneValue.Add("Drive can format BD-RE discs with full certification");
if(ftr.CanFormatFRF)
mmcOneValue.Add("Drive can fast re-format BD-RE discs");
if(ftr.CanFormatRRM)
mmcOneValue.Add("Drive can format BD-R discs with RRM format");
if(ftr.CanLoad)
mmcOneValue.Add("Drive can load media");
if(ftr.CanMuteSeparateChannels)
mmcOneValue.Add("Drive is able to mute channels separately");
if(ftr.CanOverwriteSAOTrack)
mmcOneValue.Add("Drive can overwrite a SAO track with another in CD-RWs");
if(ftr.CanOverwriteTAOTrack)
mmcOneValue.Add("Drive can overwrite a TAO track with another in CD-RWs");
if(ftr.CanPlayCDAudio)
mmcOneValue.Add("Drive has an analogue audio output");
if(ftr.CanPseudoOverwriteBDR)
mmcOneValue.Add("Drive can write BD-R on Pseudo-OverWrite SRM mode");
if(ftr.CanReadAllDualR)
mmcOneValue.Add("Drive can read DVD-R DL from all recording modes");
if(ftr.CanReadAllDualRW)
mmcOneValue.Add("Drive can read DVD-RW DL from all recording modes");
if(ftr.CanReadBD)
mmcOneValue.Add("Drive can read BD-ROM");
if(ftr.CanReadBDR)
mmcOneValue.Add("Drive can read BD-R Ver.1");
if(ftr.CanReadBDRE1)
mmcOneValue.Add("Drive can read BD-RE Ver.1");
if(ftr.CanReadBDRE2)
mmcOneValue.Add("Drive can read BD-RE Ver.2");
if(ftr.CanReadBDROM)
mmcOneValue.Add("Drive can read BD-ROM Ver.1");
if(ftr.CanReadBluBCA)
mmcOneValue.Add("Drive can read BD's Burst Cutting Area");
if(ftr.CanReadCD)
mmcOneValue.Add("Drive can read CD-ROM");
if(ftr.CanWriteCDMRW &&
ftr.CanReadDVDPlusMRW &&
ftr.CanWriteDVDPlusMRW)
mmcOneValue.Add("Drive can read and write CD-MRW and DVD+MRW");
else if(ftr.CanReadDVDPlusMRW &&
ftr.CanWriteDVDPlusMRW)
mmcOneValue.Add("Drive can read and write DVD+MRW");
else if(ftr.CanWriteCDMRW &&
ftr.CanReadDVDPlusMRW)
mmcOneValue.Add("Drive and read DVD+MRW and read and write CD-MRW");
else if(ftr.CanWriteCDMRW)
mmcOneValue.Add("Drive can read and write CD-MRW");
else if(ftr.CanReadDVDPlusMRW)
mmcOneValue.Add("Drive can read CD-MRW and DVD+MRW");
else if(ftr.CanReadCDMRW)
mmcOneValue.Add("Drive can read CD-MRW");
if(ftr.CanReadCPRM_MKB)
mmcOneValue.Add("Drive supports reading Media Key Block of CPRM");
if(ftr.CanReadDDCD)
mmcOneValue.Add("Drive can read DDCDs");
if(ftr.CanReadDVD)
mmcOneValue.Add("Drive can read DVD");
if(ftr.CanWriteDVDPlusRW)
mmcOneValue.Add("Drive can read and write DVD+RW");
else if(ftr.CanReadDVDPlusRW)
mmcOneValue.Add("Drive can read DVD+RW");
if(ftr.CanWriteDVDPlusR)
mmcOneValue.Add("Drive can read and write DVD+R");
else if(ftr.CanReadDVDPlusR)
mmcOneValue.Add("Drive can read DVD+R");
if(ftr.CanWriteDVDPlusRDL)
mmcOneValue.Add("Drive can read and write DVD+R DL");
else if(ftr.CanReadDVDPlusRDL)
mmcOneValue.Add("Drive can read DVD+R DL");
if(ftr.CanReadDriveAACSCertificate)
mmcOneValue.Add("Drive supports reading the Drive Certificate");
if(ftr.CanReadHDDVD &&
ftr.CanReadHDDVDR &&
ftr.CanReadHDDVDRAM)
mmcOneValue.Add("Drive can read HD DVD-ROM, HD DVD-RW, HD DVD-R and HD DVD-RAM");
else if(ftr.CanReadHDDVD &&
ftr.CanReadHDDVDR)
mmcOneValue.Add("Drive can read HD DVD-ROM, HD DVD-RW and HD DVD-R");
else if(ftr.CanReadHDDVD &&
ftr.CanReadHDDVDRAM)
mmcOneValue.Add("Drive can read HD DVD-ROM, HD DVD-RW and HD DVD-RAM");
else if(ftr.CanReadHDDVD)
mmcOneValue.Add("Drive can read HD DVD-ROM and HD DVD-RW");
if(ftr.CanReadLeadInCDText)
mmcOneValue.Add("Drive can return CD-Text from Lead-In");
if(ftr.CanReadOldBDR)
mmcOneValue.Add("Drive can read BD-R pre-1.0");
if(ftr.CanReadOldBDRE)
mmcOneValue.Add("Drive can read BD-RE pre-1.0");
if(ftr.CanReadOldBDROM)
mmcOneValue.Add("Drive can read BD-ROM pre-1.0");
if(ftr.CanReadSpareAreaInformation)
mmcOneValue.Add("Drive can return Spare Area Information");
if(ftr.CanReportDriveSerial)
mmcOneValue.Add("Drive is to report drive serial number");
if(ftr.CanReportMediaSerial)
mmcOneValue.Add("Drive is to read media serial number");
if(ftr.CanTestWriteDDCDR)
mmcOneValue.Add("Drive can do a test writing with DDCD-R");
if(ftr.CanTestWriteDVD)
mmcOneValue.Add("Drive can do a test writing with DVDs");
if(ftr.CanTestWriteInSAO)
mmcOneValue.Add("Drive can do a test writing in Session at Once Mode");
if(ftr.CanTestWriteInTAO)
mmcOneValue.Add("Drive can do a test writing in Track at Once Mode");
if(ftr.CanUpgradeFirmware)
mmcOneValue.Add("Drive supports Microcode Upgrade");
if(ftr.ErrorRecoveryPage)
mmcOneValue.Add("Drive shall report Read/Write Error Recovery mode page");
if(ftr.Locked)
mmcOneValue.Add("Drive can lock media");
if(ftr.LogicalBlockSize > 0)
mmcOneValue.Add($"{ftr.LogicalBlockSize} bytes per logical block");
if(ftr.MultiRead)
mmcOneValue.
Add("Drive claims capability to read all CD formats according to OSTA Multi-Read Specification");
if(ftr.PhysicalInterfaceStandard.HasValue)
switch(ftr.PhysicalInterfaceStandard)
{
case PhysicalInterfaces.Unspecified:
mmcOneValue.Add("Drive uses an unspecified physical interface");
break;
case PhysicalInterfaces.SCSI:
mmcOneValue.Add("Drive uses SCSI interface");
break;
case PhysicalInterfaces.ATAPI:
mmcOneValue.Add("Drive uses ATAPI interface");
break;
case PhysicalInterfaces.IEEE1394:
mmcOneValue.Add("Drive uses IEEE-1394 interface");
break;
case PhysicalInterfaces.IEEE1394A:
mmcOneValue.Add("Drive uses IEEE-1394A interface");
break;
case PhysicalInterfaces.FC:
mmcOneValue.Add("Drive uses Fibre Channel interface");
break;
case PhysicalInterfaces.IEEE1394B:
mmcOneValue.Add("Drive uses IEEE-1394B interface");
break;
case PhysicalInterfaces.SerialATAPI:
mmcOneValue.Add("Drive uses Serial ATAPI interface");
break;
case PhysicalInterfaces.USB:
mmcOneValue.Add("Drive uses USB interface");
break;
case PhysicalInterfaces.Vendor:
mmcOneValue.Add("Drive uses a vendor unique interface");
break;
default:
mmcOneValue.
Add($"Drive uses an unknown interface with code {(uint)ftr.PhysicalInterfaceStandard}");
break;
}
if(ftr.PreventJumper)
mmcOneValue.Add("Drive power ups locked");
if(ftr.SupportsBusEncryption)
mmcOneValue.Add("Drive supports bus encryption");
if(ftr.CanWriteBD)
mmcOneValue.Add("Drive can write BD-R or BD-RE");
if(ftr.CanWriteBDR)
mmcOneValue.Add("Drive can write BD-R Ver.1");
if(ftr.CanWriteBDRE1)
mmcOneValue.Add("Drive can write BD-RE Ver.1");
if(ftr.CanWriteBDRE2)
mmcOneValue.Add("Drive can write BD-RE Ver.2");
if(ftr.CanWriteBusEncryptedBlocks)
mmcOneValue.Add("Drive supports writing with bus encryption");
if(ftr.CanWriteCDRW)
mmcOneValue.Add("Drive can write CD-RW");
if(ftr.CanWriteCDRWCAV)
mmcOneValue.Add("Drive can write High-Speed CD-RW");
if(ftr.CanWriteCDSAO &&
!ftr.CanWriteRaw)
mmcOneValue.Add("Drive can write CDs in Session at Once Mode:");
else if(!ftr.CanWriteCDSAO &&
ftr.CanWriteRaw)
mmcOneValue.Add("Drive can write CDs in raw Mode:");
else if(ftr.CanWriteCDSAO &&
ftr.CanWriteRaw)
mmcOneValue.Add("Drive can write CDs in Session at Once and in Raw Modes:");
if(ftr.CanWriteCDTAO)
mmcOneValue.Add("Drive can write CDs in Track at Once Mode:");
if(ftr.CanWriteCSSManagedDVD)
mmcOneValue.Add("Drive can write CSS managed DVDs");
if(ftr.CanWriteDDCDR)
mmcOneValue.Add("Drive supports writing DDCD-R");
if(ftr.CanWriteDDCDRW)
mmcOneValue.Add("Drive supports writing DDCD-RW");
if(ftr.CanWriteDVDPlusRWDL)
mmcOneValue.Add("Drive can read and write DVD+RW DL");
else if(ftr.CanReadDVDPlusRWDL)
mmcOneValue.Add("Drive can read DVD+RW DL");
if(ftr.CanWriteDVDR &&
ftr.CanWriteDVDRW &&
ftr.CanWriteDVDRDL)
mmcOneValue.Add("Drive supports writing DVD-R, DVD-RW and DVD-R DL");
else if(ftr.CanWriteDVDR &&
ftr.CanWriteDVDRDL)
mmcOneValue.Add("Drive supports writing DVD-R and DVD-R DL");
else if(ftr.CanWriteDVDR &&
ftr.CanWriteDVDRW)
mmcOneValue.Add("Drive supports writing DVD-R and DVD-RW");
else if(ftr.CanWriteDVDR)
mmcOneValue.Add("Drive supports writing DVD-R");
if(ftr.CanWriteHDDVDR &&
ftr.CanWriteHDDVDRAM)
mmcOneValue.Add("Drive can write HD DVD-RW, HD DVD-R and HD DVD-RAM");
else if(ftr.CanWriteHDDVDR)
mmcOneValue.Add("Drive can write HD DVD-RW and HD DVD-R");
else if(ftr.CanWriteHDDVDRAM)
mmcOneValue.Add("Drive can write HD DVD-RW and HD DVD-RAM");
// TODO: Write HD DVD-RW
/*
else
mmcOneValue.Add("Drive can write HD DVD-RW");
*/
if(ftr.CanWriteOldBDR)
mmcOneValue.Add("Drive can write BD-R pre-1.0");
if(ftr.CanWriteOldBDRE)
mmcOneValue.Add("Drive can write BD-RE pre-1.0");
if(ftr.CanWriteRWSubchannelInTAO)
{
mmcOneValue.Add("Drive can write user provided data in the R-W subchannels in Track at Once Mode");
if(ftr.CanWriteRawSubchannelInTAO)
mmcOneValue.Add("Drive accepts RAW R-W subchannel data in Track at Once Mode");
if(ftr.CanWritePackedSubchannelInTAO)
mmcOneValue.Add("Drive accepts Packed R-W subchannel data in Track at Once Mode");
}
if(ftr.CanWriteRWSubchannelInSAO)
mmcOneValue.Add("Drive can write user provided data in the R-W subchannels in Session at Once Mode");
if(ftr.CanWriteRaw &&
ftr.CanWriteRawMultiSession)
mmcOneValue.Add("Drive can write multi-session CDs in raw mode");
if(ftr.EmbeddedChanger)
{
mmcOneValue.Add("Drive contains an embedded changer");
if(ftr.ChangerIsSideChangeCapable)
mmcOneValue.Add("Drive can change disc side");
if(ftr.ChangerSupportsDiscPresent)
mmcOneValue.Add("Drive is able to report slots contents after a reset or change");
mmcOneValue.Add($"Drive has {ftr.ChangerSlots + 1} slots");
}
if(ftr.SupportsCSS &&
ftr.CSSVersion.HasValue)
mmcOneValue.Add($"Drive supports DVD CSS/CPPM version {ftr.CSSVersion}");
else if(ftr.SupportsCSS)
mmcOneValue.Add("Drive supports DVD CSS/CPRM");
if(ftr.SupportsCPRM &&
ftr.CPRMVersion.HasValue)
mmcOneValue.Add($"Drive supports DVD CPRM version {ftr.CPRMVersion}");
else if(ftr.SupportsCPRM)
mmcOneValue.Add("Drive supports DVD CPRM");
if(ftr.DBML)
mmcOneValue.Add("Drive reports Device Busy Class events during medium loading/unloading");
if(ftr.DVDMultiRead)
mmcOneValue.Add("Drive conforms to DVD Multi Drive Read-only Specifications");
if(ftr.FirmwareDate.HasValue)
mmcOneValue.Add($"Drive firmware is dated {ftr.FirmwareDate}");
if(ftr.SupportsC2)
mmcOneValue.Add("Drive supports C2 Error Pointers");
if(ftr.SupportsDAP)
mmcOneValue.Add("Drive supports the DAP bit in the READ CD and READ CD MSF commands");
if(ftr.SupportsDeviceBusyEvent)
mmcOneValue.Add("Drive supports Device Busy events");
if(ftr.LoadingMechanismType.HasValue)
switch(ftr.LoadingMechanismType)
{
case 0:
mmcOneValue.Add("Drive uses media caddy");
break;
case 1:
mmcOneValue.Add("Drive uses a tray");
break;
case 2:
mmcOneValue.Add("Drive is pop-up");
break;
case 4:
mmcOneValue.Add("Drive is a changer with individually changeable discs");
break;
case 5:
mmcOneValue.Add("Drive is a changer using cartridges");
break;
default:
mmcOneValue.Add($"Drive uses unknown loading mechanism type {ftr.LoadingMechanismType}");
break;
}
if(ftr.SupportsHybridDiscs)
mmcOneValue.Add("Drive is able to access Hybrid discs");
if(ftr.SupportsModePage1Ch)
mmcOneValue.Add("Drive supports the Informational Exceptions Control mode page 1Ch");
if(ftr.SupportsOSSC)
mmcOneValue.Add("Drive supports the Trusted Computing Group Optical Security Subsystem Class");
if(ftr.SupportsPWP)
mmcOneValue.Add("Drive supports set/release of PWP status");
if(ftr.SupportsSWPP)
mmcOneValue.Add("Drive supports the SWPP bit of the Timeout and Protect mode page");
if(ftr.SupportsSecurDisc)
mmcOneValue.Add("Drive supports SecurDisc");
if(ftr.SupportsSeparateVolume)
mmcOneValue.Add("Drive supports separate volume per channel");
if(ftr.SupportsVCPS)
mmcOneValue.Add("Drive supports VCPS");
if(ftr.VolumeLevels.HasValue)
mmcOneValue.Add($"Drive has {ftr.VolumeLevels + 1} volume levels");
if(ftr.SupportsWriteProtectPAC)
mmcOneValue.Add("Drive supports reading/writing the Disc Write Protect PAC on BD-R/-RE media");
if(ftr.SupportsWriteInhibitDCB)
mmcOneValue.Add("Drive supports writing the Write Inhibit DCB on DVD+RW media");
mmcOneValue.Sort();
mmcOneValue.Add("");
if(ftr.BindingNonceBlocks.HasValue)
mmcOneValue.Add($"{ftr.BindingNonceBlocks} media blocks are required for the binding nonce");
}
if(ftr.BlocksPerReadableUnit > 1)
mmcOneValue.Add($"{ftr.BlocksPerReadableUnit} logical blocks per media writable unit");
if(ftr.BufferUnderrunFreeInDVD)
mmcOneValue.Add("Drive supports zero loss linking writing DVDs");
if(ftr.BufferUnderrunFreeInSAO)
mmcOneValue.Add("Drive supports zero loss linking in Session at Once Mode");
if(ftr.BufferUnderrunFreeInTAO)
mmcOneValue.Add("Drive supports zero loss linking in Track at Once Mode");
if(ftr.CanAudioScan)
mmcOneValue.Add("Drive supports the SCAN command");
if(ftr.CanEject)
mmcOneValue.Add("Drive can eject media");
if(ftr.CanEraseSector)
mmcOneValue.Add("Drive supports media that require erasing before writing");
if(ftr.CanExpandBDRESpareArea)
mmcOneValue.Add("Drive can expand the spare area on a formatted BD-RE disc");
if(ftr.CanFormat)
mmcOneValue.Add("Drive can format media into logical blocks");
if(ftr.CanFormatBDREWithoutSpare)
mmcOneValue.Add("Drive can format BD-RE with no spares allocated");
if(ftr.CanFormatQCert)
mmcOneValue.Add("Drive can format BD-RE discs with quick certification");
if(ftr.CanFormatCert)
mmcOneValue.Add("Drive can format BD-RE discs with full certification");
if(ftr.CanFormatFRF)
mmcOneValue.Add("Drive can fast re-format BD-RE discs");
if(ftr.CanFormatRRM)
mmcOneValue.Add("Drive can format BD-R discs with RRM format");
if(ftr.CanLoad)
mmcOneValue.Add("Drive can load media");
if(ftr.CanMuteSeparateChannels)
mmcOneValue.Add("Drive is able to mute channels separately");
if(ftr.CanOverwriteSAOTrack)
mmcOneValue.Add("Drive can overwrite a SAO track with another in CD-RWs");
if(ftr.CanOverwriteTAOTrack)
mmcOneValue.Add("Drive can overwrite a TAO track with another in CD-RWs");
if(ftr.CanPlayCDAudio)
mmcOneValue.Add("Drive has an analogue audio output");
if(ftr.CanPseudoOverwriteBDR)
mmcOneValue.Add("Drive can write BD-R on Pseudo-OverWrite SRM mode");
if(ftr.CanReadAllDualR)
mmcOneValue.Add("Drive can read DVD-R DL from all recording modes");
if(ftr.CanReadAllDualRW)
mmcOneValue.Add("Drive can read DVD-RW DL from all recording modes");
if(ftr.CanReadBD)
mmcOneValue.Add("Drive can read BD-ROM");
if(ftr.CanReadBDR)
mmcOneValue.Add("Drive can read BD-R Ver.1");
if(ftr.CanReadBDRE1)
mmcOneValue.Add("Drive can read BD-RE Ver.1");
if(ftr.CanReadBDRE2)
mmcOneValue.Add("Drive can read BD-RE Ver.2");
if(ftr.CanReadBDROM)
mmcOneValue.Add("Drive can read BD-ROM Ver.1");
if(ftr.CanReadBluBCA)
mmcOneValue.Add("Drive can read BD's Burst Cutting Area");
if(ftr.CanReadCD)
mmcOneValue.Add("Drive can read CD-ROM");
if(ftr.CanWriteCDMRW &&
ftr.CanReadDVDPlusMRW &&
ftr.CanWriteDVDPlusMRW)
mmcOneValue.Add("Drive can read and write CD-MRW and DVD+MRW");
else if(ftr.CanReadDVDPlusMRW &&
ftr.CanWriteDVDPlusMRW)
mmcOneValue.Add("Drive can read and write DVD+MRW");
else if(ftr.CanWriteCDMRW &&
ftr.CanReadDVDPlusMRW)
mmcOneValue.Add("Drive and read DVD+MRW and read and write CD-MRW");
else if(ftr.CanWriteCDMRW)
mmcOneValue.Add("Drive can read and write CD-MRW");
else if(ftr.CanReadDVDPlusMRW)
mmcOneValue.Add("Drive can read CD-MRW and DVD+MRW");
else if(ftr.CanReadCDMRW)
mmcOneValue.Add("Drive can read CD-MRW");
if(ftr.CanReadCPRM_MKB)
mmcOneValue.Add("Drive supports reading Media Key Block of CPRM");
if(ftr.CanReadDDCD)
mmcOneValue.Add("Drive can read DDCDs");
if(ftr.CanReadDVD)
mmcOneValue.Add("Drive can read DVD");
if(ftr.CanWriteDVDPlusRW)
mmcOneValue.Add("Drive can read and write DVD+RW");
else if(ftr.CanReadDVDPlusRW)
mmcOneValue.Add("Drive can read DVD+RW");
if(ftr.CanWriteDVDPlusR)
mmcOneValue.Add("Drive can read and write DVD+R");
else if(ftr.CanReadDVDPlusR)
mmcOneValue.Add("Drive can read DVD+R");
if(ftr.CanWriteDVDPlusRDL)
mmcOneValue.Add("Drive can read and write DVD+R DL");
else if(ftr.CanReadDVDPlusRDL)
mmcOneValue.Add("Drive can read DVD+R DL");
if(ftr.CanReadDriveAACSCertificate)
mmcOneValue.Add("Drive supports reading the Drive Certificate");
if(ftr.CanReadHDDVD &&
ftr.CanReadHDDVDR &&
ftr.CanReadHDDVDRAM)
mmcOneValue.Add("Drive can read HD DVD-ROM, HD DVD-RW, HD DVD-R and HD DVD-RAM");
else if(ftr.CanReadHDDVD &&
ftr.CanReadHDDVDR)
mmcOneValue.Add("Drive can read HD DVD-ROM, HD DVD-RW and HD DVD-R");
else if(ftr.CanReadHDDVD &&
ftr.CanReadHDDVDRAM)
mmcOneValue.Add("Drive can read HD DVD-ROM, HD DVD-RW and HD DVD-RAM");
else if(ftr.CanReadHDDVD)
mmcOneValue.Add("Drive can read HD DVD-ROM and HD DVD-RW");
if(ftr.CanReadLeadInCDText)
mmcOneValue.Add("Drive can return CD-Text from Lead-In");
if(ftr.CanReadOldBDR)
mmcOneValue.Add("Drive can read BD-R pre-1.0");
if(ftr.CanReadOldBDRE)
mmcOneValue.Add("Drive can read BD-RE pre-1.0");
if(ftr.CanReadOldBDROM)
mmcOneValue.Add("Drive can read BD-ROM pre-1.0");
if(ftr.CanReadSpareAreaInformation)
mmcOneValue.Add("Drive can return Spare Area Information");
if(ftr.CanReportDriveSerial)
mmcOneValue.Add("Drive is to report drive serial number");
if(ftr.CanReportMediaSerial)
mmcOneValue.Add("Drive is to read media serial number");
if(ftr.CanTestWriteDDCDR)
mmcOneValue.Add("Drive can do a test writing with DDCD-R");
if(ftr.CanTestWriteDVD)
mmcOneValue.Add("Drive can do a test writing with DVDs");
if(ftr.CanTestWriteInSAO)
mmcOneValue.Add("Drive can do a test writing in Session at Once Mode");
if(ftr.CanTestWriteInTAO)
mmcOneValue.Add("Drive can do a test writing in Track at Once Mode");
if(ftr.CanUpgradeFirmware)
mmcOneValue.Add("Drive supports Microcode Upgrade");
if(ftr.ErrorRecoveryPage)
mmcOneValue.Add("Drive shall report Read/Write Error Recovery mode page");
if(ftr.Locked)
mmcOneValue.Add("Drive can lock media");
if(ftr.LogicalBlockSize > 0)
mmcOneValue.Add($"{ftr.LogicalBlockSize} bytes per logical block");
if(ftr.MultiRead)
mmcOneValue.
Add("Drive claims capability to read all CD formats according to OSTA Multi-Read Specification");
if(ftr.PhysicalInterfaceStandard.HasValue)
switch(ftr.PhysicalInterfaceStandard)
{
case PhysicalInterfaces.Unspecified:
mmcOneValue.Add("Drive uses an unspecified physical interface");
break;
case PhysicalInterfaces.SCSI:
mmcOneValue.Add("Drive uses SCSI interface");
break;
case PhysicalInterfaces.ATAPI:
mmcOneValue.Add("Drive uses ATAPI interface");
break;
case PhysicalInterfaces.IEEE1394:
mmcOneValue.Add("Drive uses IEEE-1394 interface");
break;
case PhysicalInterfaces.IEEE1394A:
mmcOneValue.Add("Drive uses IEEE-1394A interface");
break;
case PhysicalInterfaces.FC:
mmcOneValue.Add("Drive uses Fibre Channel interface");
break;
case PhysicalInterfaces.IEEE1394B:
mmcOneValue.Add("Drive uses IEEE-1394B interface");
break;
case PhysicalInterfaces.SerialATAPI:
mmcOneValue.Add("Drive uses Serial ATAPI interface");
break;
case PhysicalInterfaces.USB:
mmcOneValue.Add("Drive uses USB interface");
break;
case PhysicalInterfaces.Vendor:
mmcOneValue.Add("Drive uses a vendor unique interface");
break;
default:
mmcOneValue.
Add($"Drive uses an unknown interface with code {(uint)ftr.PhysicalInterfaceStandard}");
break;
}
if(ftr.PreventJumper)
mmcOneValue.Add("Drive power ups locked");
if(ftr.SupportsBusEncryption)
mmcOneValue.Add("Drive supports bus encryption");
if(ftr.CanWriteBD)
mmcOneValue.Add("Drive can write BD-R or BD-RE");
if(ftr.CanWriteBDR)
mmcOneValue.Add("Drive can write BD-R Ver.1");
if(ftr.CanWriteBDRE1)
mmcOneValue.Add("Drive can write BD-RE Ver.1");
if(ftr.CanWriteBDRE2)
mmcOneValue.Add("Drive can write BD-RE Ver.2");
if(ftr.CanWriteBusEncryptedBlocks)
mmcOneValue.Add("Drive supports writing with bus encryption");
if(ftr.CanWriteCDRW)
mmcOneValue.Add("Drive can write CD-RW");
if(ftr.CanWriteCDRWCAV)
mmcOneValue.Add("Drive can write High-Speed CD-RW");
if(ftr.CanWriteCDSAO &&
!ftr.CanWriteRaw)
mmcOneValue.Add("Drive can write CDs in Session at Once Mode:");
else if(!ftr.CanWriteCDSAO &&
ftr.CanWriteRaw)
mmcOneValue.Add("Drive can write CDs in raw Mode:");
else if(ftr.CanWriteCDSAO &&
ftr.CanWriteRaw)
mmcOneValue.Add("Drive can write CDs in Session at Once and in Raw Modes:");
if(ftr.CanWriteCDTAO)
mmcOneValue.Add("Drive can write CDs in Track at Once Mode:");
if(ftr.CanWriteCSSManagedDVD)
mmcOneValue.Add("Drive can write CSS managed DVDs");
if(ftr.CanWriteDDCDR)
mmcOneValue.Add("Drive supports writing DDCD-R");
if(ftr.CanWriteDDCDRW)
mmcOneValue.Add("Drive supports writing DDCD-RW");
if(ftr.CanWriteDVDPlusRWDL)
mmcOneValue.Add("Drive can read and write DVD+RW DL");
else if(ftr.CanReadDVDPlusRWDL)
mmcOneValue.Add("Drive can read DVD+RW DL");
if(ftr.CanWriteDVDR &&
ftr.CanWriteDVDRW &&
ftr.CanWriteDVDRDL)
mmcOneValue.Add("Drive supports writing DVD-R, DVD-RW and DVD-R DL");
else if(ftr.CanWriteDVDR &&
ftr.CanWriteDVDRDL)
mmcOneValue.Add("Drive supports writing DVD-R and DVD-R DL");
else if(ftr.CanWriteDVDR &&
ftr.CanWriteDVDRW)
mmcOneValue.Add("Drive supports writing DVD-R and DVD-RW");
else if(ftr.CanWriteDVDR)
mmcOneValue.Add("Drive supports writing DVD-R");
if(ftr.CanWriteHDDVDR &&
ftr.CanWriteHDDVDRAM)
mmcOneValue.Add("Drive can write HD DVD-RW, HD DVD-R and HD DVD-RAM");
else if(ftr.CanWriteHDDVDR)
mmcOneValue.Add("Drive can write HD DVD-RW and HD DVD-R");
else if(ftr.CanWriteHDDVDRAM)
mmcOneValue.Add("Drive can write HD DVD-RW and HD DVD-RAM");
// TODO: Write HD DVD-RW
/*
else
mmcOneValue.Add("Drive can write HD DVD-RW");
*/
if(ftr.CanWriteOldBDR)
mmcOneValue.Add("Drive can write BD-R pre-1.0");
if(ftr.CanWriteOldBDRE)
mmcOneValue.Add("Drive can write BD-RE pre-1.0");
if(ftr.CanWriteRWSubchannelInTAO)
{
mmcOneValue.Add("Drive can write user provided data in the R-W subchannels in Track at Once Mode");
if(ftr.CanWriteRawSubchannelInTAO)
mmcOneValue.Add("Drive accepts RAW R-W subchannel data in Track at Once Mode");
if(ftr.CanWritePackedSubchannelInTAO)
mmcOneValue.Add("Drive accepts Packed R-W subchannel data in Track at Once Mode");
}
if(ftr.CanWriteRWSubchannelInSAO)
mmcOneValue.Add("Drive can write user provided data in the R-W subchannels in Session at Once Mode");
if(ftr.CanWriteRaw &&
ftr.CanWriteRawMultiSession)
mmcOneValue.Add("Drive can write multi-session CDs in raw mode");
if(ftr.EmbeddedChanger)
{
mmcOneValue.Add("Drive contains an embedded changer");
if(ftr.ChangerIsSideChangeCapable)
mmcOneValue.Add("Drive can change disc side");
if(ftr.ChangerSupportsDiscPresent)
mmcOneValue.Add("Drive is able to report slots contents after a reset or change");
mmcOneValue.Add($"Drive has {ftr.ChangerSlots + 1} slots");
}
if(ftr.SupportsCSS &&
ftr.CSSVersion.HasValue)
mmcOneValue.Add($"Drive supports DVD CSS/CPPM version {ftr.CSSVersion}");
else if(ftr.SupportsCSS)
mmcOneValue.Add("Drive supports DVD CSS/CPRM");
if(ftr.SupportsCPRM &&
ftr.CPRMVersion.HasValue)
mmcOneValue.Add($"Drive supports DVD CPRM version {ftr.CPRMVersion}");
else if(ftr.SupportsCPRM)
mmcOneValue.Add("Drive supports DVD CPRM");
if(ftr.DBML)
mmcOneValue.Add("Drive reports Device Busy Class events during medium loading/unloading");
if(ftr.DVDMultiRead)
mmcOneValue.Add("Drive conforms to DVD Multi Drive Read-only Specifications");
if(ftr.FirmwareDate.HasValue)
mmcOneValue.Add($"Drive firmware is dated {ftr.FirmwareDate}");
if(ftr.SupportsC2)
mmcOneValue.Add("Drive supports C2 Error Pointers");
if(ftr.SupportsDAP)
mmcOneValue.Add("Drive supports the DAP bit in the READ CD and READ CD MSF commands");
if(ftr.SupportsDeviceBusyEvent)
mmcOneValue.Add("Drive supports Device Busy events");
if(ftr.LoadingMechanismType.HasValue)
switch(ftr.LoadingMechanismType)
{
case 0:
mmcOneValue.Add("Drive uses media caddy");
break;
case 1:
mmcOneValue.Add("Drive uses a tray");
break;
case 2:
mmcOneValue.Add("Drive is pop-up");
break;
case 4:
mmcOneValue.Add("Drive is a changer with individually changeable discs");
break;
case 5:
mmcOneValue.Add("Drive is a changer using cartridges");
break;
default:
mmcOneValue.Add($"Drive uses unknown loading mechanism type {ftr.LoadingMechanismType}");
break;
}
if(ftr.SupportsHybridDiscs)
mmcOneValue.Add("Drive is able to access Hybrid discs");
if(ftr.SupportsModePage1Ch)
mmcOneValue.Add("Drive supports the Informational Exceptions Control mode page 1Ch");
if(ftr.SupportsOSSC)
mmcOneValue.Add("Drive supports the Trusted Computing Group Optical Security Subsystem Class");
if(ftr.SupportsPWP)
mmcOneValue.Add("Drive supports set/release of PWP status");
if(ftr.SupportsSWPP)
mmcOneValue.Add("Drive supports the SWPP bit of the Timeout and Protect mode page");
if(ftr.SupportsSecurDisc)
mmcOneValue.Add("Drive supports SecurDisc");
if(ftr.SupportsSeparateVolume)
mmcOneValue.Add("Drive supports separate volume per channel");
if(ftr.SupportsVCPS)
mmcOneValue.Add("Drive supports VCPS");
if(ftr.VolumeLevels.HasValue)
mmcOneValue.Add($"Drive has {ftr.VolumeLevels + 1} volume levels");
if(ftr.SupportsWriteProtectPAC)
mmcOneValue.Add("Drive supports reading/writing the Disc Write Protect PAC on BD-R/-RE media");
if(ftr.SupportsWriteInhibitDCB)
mmcOneValue.Add("Drive supports writing the Write Inhibit DCB on DVD+RW media");
mmcOneValue.Sort();
mmcOneValue.Add("");
}
}

View File

@@ -34,196 +34,195 @@ using System.Collections.Generic;
using System.Linq;
using Aaru.CommonTypes.Structs.Devices.SCSI.Modes;
namespace Aaru.Server.Core
namespace Aaru.Server.Core;
public static class ScsiMmcMode
{
public static class ScsiMmcMode
/// <summary>
/// Takes the MODE PAGE 2Ah part of a device report and prints it as a list of values to be sequenced by ASP.NET
/// in the rendering
/// </summary>
/// <param name="mode">MODE PAGE 2Ah part of the report</param>
/// <param name="mmcOneValue">List to put the values on</param>
public static void Report(ModePage_2A mode, ref List<string> mmcOneValue)
{
/// <summary>
/// Takes the MODE PAGE 2Ah part of a device report and prints it as a list of values to be sequenced by ASP.NET
/// in the rendering
/// </summary>
/// <param name="mode">MODE PAGE 2Ah part of the report</param>
/// <param name="mmcOneValue">List to put the values on</param>
public static void Report(ModePage_2A mode, ref List<string> mmcOneValue)
if(mode.AudioPlay)
mmcOneValue.Add("Drive can play audio");
if(mode.Mode2Form1)
mmcOneValue.Add("Drive can read sectors in Mode 2 Form 1 format");
if(mode.Mode2Form2)
mmcOneValue.Add("Drive can read sectors in Mode 2 Form 2 format");
if(mode.MultiSession)
mmcOneValue.Add("Drive supports multi-session discs and/or Photo-CD");
if(mode.CDDACommand)
mmcOneValue.Add("Drive can read digital audio");
if(mode.AccurateCDDA)
mmcOneValue.Add("Drive can continue from streaming loss");
if(mode.Subchannel)
mmcOneValue.Add("Drive can read uncorrected and interleaved R-W subchannels");
if(mode.DeinterlaveSubchannel)
mmcOneValue.Add("Drive can read, deinterleave and correct R-W subchannels");
if(mode.C2Pointer)
mmcOneValue.Add("Drive supports C2 pointers");
if(mode.UPC)
mmcOneValue.Add("Drive can read Media Catalogue Number");
if(mode.ISRC)
mmcOneValue.Add("Drive can read ISRC");
switch(mode.LoadingMechanism)
{
if(mode.AudioPlay)
mmcOneValue.Add("Drive can play audio");
case 0:
mmcOneValue.Add("Drive uses media caddy");
if(mode.Mode2Form1)
mmcOneValue.Add("Drive can read sectors in Mode 2 Form 1 format");
break;
case 1:
mmcOneValue.Add("Drive uses a tray");
if(mode.Mode2Form2)
mmcOneValue.Add("Drive can read sectors in Mode 2 Form 2 format");
break;
case 2:
mmcOneValue.Add("Drive is pop-up");
if(mode.MultiSession)
mmcOneValue.Add("Drive supports multi-session discs and/or Photo-CD");
break;
case 4:
mmcOneValue.Add("Drive is a changer with individually changeable discs");
if(mode.CDDACommand)
mmcOneValue.Add("Drive can read digital audio");
break;
case 5:
mmcOneValue.Add("Drive is a changer using cartridges");
if(mode.AccurateCDDA)
mmcOneValue.Add("Drive can continue from streaming loss");
break;
default:
mmcOneValue.Add($"Drive uses unknown loading mechanism type {mode.LoadingMechanism}");
if(mode.Subchannel)
mmcOneValue.Add("Drive can read uncorrected and interleaved R-W subchannels");
if(mode.DeinterlaveSubchannel)
mmcOneValue.Add("Drive can read, deinterleave and correct R-W subchannels");
if(mode.C2Pointer)
mmcOneValue.Add("Drive supports C2 pointers");
if(mode.UPC)
mmcOneValue.Add("Drive can read Media Catalogue Number");
if(mode.ISRC)
mmcOneValue.Add("Drive can read ISRC");
switch(mode.LoadingMechanism)
{
case 0:
mmcOneValue.Add("Drive uses media caddy");
break;
case 1:
mmcOneValue.Add("Drive uses a tray");
break;
case 2:
mmcOneValue.Add("Drive is pop-up");
break;
case 4:
mmcOneValue.Add("Drive is a changer with individually changeable discs");
break;
case 5:
mmcOneValue.Add("Drive is a changer using cartridges");
break;
default:
mmcOneValue.Add($"Drive uses unknown loading mechanism type {mode.LoadingMechanism}");
break;
}
if(mode.Lock)
mmcOneValue.Add("Drive can lock media");
if(mode.PreventJumper)
{
mmcOneValue.Add("Drive power ups locked");
mmcOneValue.Add(mode.LockState ? "Drive is locked, media cannot be ejected or inserted"
: "Drive is not locked, media can be ejected and inserted");
}
else
{
mmcOneValue.Add(mode.LockState
? "Drive is locked, media cannot be ejected, but if empty, can be inserted"
: "Drive is not locked, media can be ejected and inserted");
}
if(mode.Eject)
mmcOneValue.Add("Drive can eject media");
if(mode.SeparateChannelMute)
mmcOneValue.Add("Each channel can be muted independently");
if(mode.SeparateChannelVolume)
mmcOneValue.Add("Each channel's volume can be controlled independently");
if(mode.SupportedVolumeLevels > 0)
mmcOneValue.Add($"Drive supports {mode.SupportedVolumeLevels} volume levels");
if(mode.BufferSize > 0)
mmcOneValue.Add($"Drive has {mode.BufferSize} Kbyte of buffer");
if(mode.MaximumSpeed > 0)
mmcOneValue.Add($"Drive's maximum reading speed is {mode.MaximumSpeed} Kbyte/sec.");
if(mode.CurrentSpeed > 0)
mmcOneValue.Add($"Drive's current reading speed is {mode.CurrentSpeed} Kbyte/sec.");
if(mode.ReadCDR)
{
mmcOneValue.Add(mode.WriteCDR ? "Drive can read and write CD-R" : "Drive can read CD-R");
if(mode.Method2)
mmcOneValue.Add("Drive supports reading CD-R packet media");
}
if(mode.ReadCDRW)
mmcOneValue.Add(mode.WriteCDRW ? "Drive can read and write CD-RW" : "Drive can read CD-RW");
if(mode.ReadDVDROM)
mmcOneValue.Add("Drive can read DVD-ROM");
if(mode.ReadDVDR)
mmcOneValue.Add(mode.WriteDVDR ? "Drive can read and write DVD-R" : "Drive can read DVD-R");
if(mode.ReadDVDRAM)
mmcOneValue.Add(mode.WriteDVDRAM ? "Drive can read and write DVD-RAM" : "Drive can read DVD-RAM");
if(mode.Composite)
mmcOneValue.Add("Drive can deliver a composite audio and video data stream");
if(mode.DigitalPort1)
mmcOneValue.Add("Drive supports IEC-958 digital output on port 1");
if(mode.DigitalPort2)
mmcOneValue.Add("Drive supports IEC-958 digital output on port 2");
if(mode.SDP)
mmcOneValue.Add("Drive contains a changer that can report the exact contents of the slots");
if(mode.CurrentWriteSpeedSelected > 0)
{
if(mode.RotationControlSelected == 0)
mmcOneValue.
Add($"Drive's current writing speed is {mode.CurrentWriteSpeedSelected} Kbyte/sec. in CLV mode");
else if(mode.RotationControlSelected == 1)
mmcOneValue.
Add($"Drive's current writing speed is {mode.CurrentWriteSpeedSelected} Kbyte/sec. in pure CAV mode");
}
else
{
if(mode.MaxWriteSpeed > 0)
mmcOneValue.Add($"Drive's maximum writing speed is {mode.MaxWriteSpeed} Kbyte/sec.");
if(mode.CurrentWriteSpeed > 0)
mmcOneValue.Add($"Drive's current writing speed is {mode.CurrentWriteSpeed} Kbyte/sec.");
}
if(mode.WriteSpeedPerformanceDescriptors != null)
foreach(ModePage_2A_WriteDescriptor descriptor in
mode.WriteSpeedPerformanceDescriptors.Where(descriptor => descriptor.WriteSpeed > 0))
if(descriptor.RotationControl == 0)
mmcOneValue.Add($"Drive supports writing at {descriptor.WriteSpeed} Kbyte/sec. in CLV mode");
else if(descriptor.RotationControl == 1)
mmcOneValue.
Add($"Drive supports writing at is {descriptor.WriteSpeed} Kbyte/sec. in pure CAV mode");
if(mode.TestWrite)
mmcOneValue.Add("Drive supports test writing");
if(mode.ReadBarcode)
mmcOneValue.Add("Drive can read barcode");
if(mode.SCC)
mmcOneValue.Add("Drive can read both sides of a disc");
if(mode.LeadInPW)
mmcOneValue.Add("Drive an read raw R-W subchannel from the Lead-In");
if(mode.CMRSupported == 1)
mmcOneValue.Add("Drive supports DVD CSS and/or DVD CPPM");
if(mode.BUF)
mmcOneValue.Add("Drive supports buffer under-run free recording");
mmcOneValue.Sort();
mmcOneValue.Add("");
break;
}
if(mode.Lock)
mmcOneValue.Add("Drive can lock media");
if(mode.PreventJumper)
{
mmcOneValue.Add("Drive power ups locked");
mmcOneValue.Add(mode.LockState ? "Drive is locked, media cannot be ejected or inserted"
: "Drive is not locked, media can be ejected and inserted");
}
else
{
mmcOneValue.Add(mode.LockState
? "Drive is locked, media cannot be ejected, but if empty, can be inserted"
: "Drive is not locked, media can be ejected and inserted");
}
if(mode.Eject)
mmcOneValue.Add("Drive can eject media");
if(mode.SeparateChannelMute)
mmcOneValue.Add("Each channel can be muted independently");
if(mode.SeparateChannelVolume)
mmcOneValue.Add("Each channel's volume can be controlled independently");
if(mode.SupportedVolumeLevels > 0)
mmcOneValue.Add($"Drive supports {mode.SupportedVolumeLevels} volume levels");
if(mode.BufferSize > 0)
mmcOneValue.Add($"Drive has {mode.BufferSize} Kbyte of buffer");
if(mode.MaximumSpeed > 0)
mmcOneValue.Add($"Drive's maximum reading speed is {mode.MaximumSpeed} Kbyte/sec.");
if(mode.CurrentSpeed > 0)
mmcOneValue.Add($"Drive's current reading speed is {mode.CurrentSpeed} Kbyte/sec.");
if(mode.ReadCDR)
{
mmcOneValue.Add(mode.WriteCDR ? "Drive can read and write CD-R" : "Drive can read CD-R");
if(mode.Method2)
mmcOneValue.Add("Drive supports reading CD-R packet media");
}
if(mode.ReadCDRW)
mmcOneValue.Add(mode.WriteCDRW ? "Drive can read and write CD-RW" : "Drive can read CD-RW");
if(mode.ReadDVDROM)
mmcOneValue.Add("Drive can read DVD-ROM");
if(mode.ReadDVDR)
mmcOneValue.Add(mode.WriteDVDR ? "Drive can read and write DVD-R" : "Drive can read DVD-R");
if(mode.ReadDVDRAM)
mmcOneValue.Add(mode.WriteDVDRAM ? "Drive can read and write DVD-RAM" : "Drive can read DVD-RAM");
if(mode.Composite)
mmcOneValue.Add("Drive can deliver a composite audio and video data stream");
if(mode.DigitalPort1)
mmcOneValue.Add("Drive supports IEC-958 digital output on port 1");
if(mode.DigitalPort2)
mmcOneValue.Add("Drive supports IEC-958 digital output on port 2");
if(mode.SDP)
mmcOneValue.Add("Drive contains a changer that can report the exact contents of the slots");
if(mode.CurrentWriteSpeedSelected > 0)
{
if(mode.RotationControlSelected == 0)
mmcOneValue.
Add($"Drive's current writing speed is {mode.CurrentWriteSpeedSelected} Kbyte/sec. in CLV mode");
else if(mode.RotationControlSelected == 1)
mmcOneValue.
Add($"Drive's current writing speed is {mode.CurrentWriteSpeedSelected} Kbyte/sec. in pure CAV mode");
}
else
{
if(mode.MaxWriteSpeed > 0)
mmcOneValue.Add($"Drive's maximum writing speed is {mode.MaxWriteSpeed} Kbyte/sec.");
if(mode.CurrentWriteSpeed > 0)
mmcOneValue.Add($"Drive's current writing speed is {mode.CurrentWriteSpeed} Kbyte/sec.");
}
if(mode.WriteSpeedPerformanceDescriptors != null)
foreach(ModePage_2A_WriteDescriptor descriptor in
mode.WriteSpeedPerformanceDescriptors.Where(descriptor => descriptor.WriteSpeed > 0))
if(descriptor.RotationControl == 0)
mmcOneValue.Add($"Drive supports writing at {descriptor.WriteSpeed} Kbyte/sec. in CLV mode");
else if(descriptor.RotationControl == 1)
mmcOneValue.
Add($"Drive supports writing at is {descriptor.WriteSpeed} Kbyte/sec. in pure CAV mode");
if(mode.TestWrite)
mmcOneValue.Add("Drive supports test writing");
if(mode.ReadBarcode)
mmcOneValue.Add("Drive can read barcode");
if(mode.SCC)
mmcOneValue.Add("Drive can read both sides of a disc");
if(mode.LeadInPW)
mmcOneValue.Add("Drive an read raw R-W subchannel from the Lead-In");
if(mode.CMRSupported == 1)
mmcOneValue.Add("Drive supports DVD CSS and/or DVD CPPM");
if(mode.BUF)
mmcOneValue.Add("Drive supports buffer under-run free recording");
mmcOneValue.Sort();
mmcOneValue.Add("");
}
}

View File

@@ -35,396 +35,395 @@ using Aaru.CommonTypes.Metadata;
using Aaru.CommonTypes.Structs.Devices.SCSI;
using Aaru.Decoders.SCSI;
namespace Aaru.Server.Core
namespace Aaru.Server.Core;
public static class ScsiModeSense
{
public static class ScsiModeSense
/// <summary>
/// Takes the MODE PAGEs part of a device report and prints it as a list of values and another list of key=value
/// pairs to be sequenced by ASP.NET in the rendering
/// </summary>
/// <param name="modeSense">MODE PAGEs part of a device report</param>
/// <param name="vendor">SCSI vendor string</param>
/// <param name="deviceType">SCSI peripheral device type</param>
/// <param name="scsiOneValue">List to put values on</param>
/// <param name="modePages">List to put key=value pairs on</param>
public static void Report(ScsiMode modeSense, string vendor, PeripheralDeviceTypes deviceType,
ref List<string> scsiOneValue, ref Dictionary<string, string> modePages)
{
/// <summary>
/// Takes the MODE PAGEs part of a device report and prints it as a list of values and another list of key=value
/// pairs to be sequenced by ASP.NET in the rendering
/// </summary>
/// <param name="modeSense">MODE PAGEs part of a device report</param>
/// <param name="vendor">SCSI vendor string</param>
/// <param name="deviceType">SCSI peripheral device type</param>
/// <param name="scsiOneValue">List to put values on</param>
/// <param name="modePages">List to put key=value pairs on</param>
public static void Report(ScsiMode modeSense, string vendor, PeripheralDeviceTypes deviceType,
ref List<string> scsiOneValue, ref Dictionary<string, string> modePages)
{
if(modeSense.MediumType.HasValue)
scsiOneValue.Add($"Medium type is {modeSense.MediumType:X2}h");
if(modeSense.MediumType.HasValue)
scsiOneValue.Add($"Medium type is {modeSense.MediumType:X2}h");
if(modeSense.WriteProtected)
scsiOneValue.Add("Device is write protected.");
if(modeSense.WriteProtected)
scsiOneValue.Add("Device is write protected.");
if(modeSense.BlockDescriptors != null)
foreach(BlockDescriptor descriptor in modeSense.BlockDescriptors)
if(descriptor.Blocks.HasValue &&
descriptor.BlockLength.HasValue)
scsiOneValue.
Add($"Density code {descriptor.Density:X2}h has {descriptor.Blocks} blocks of {descriptor.BlockLength} bytes each");
if(modeSense.BlockDescriptors != null)
foreach(BlockDescriptor descriptor in modeSense.BlockDescriptors)
if(descriptor.Blocks.HasValue &&
descriptor.BlockLength.HasValue)
scsiOneValue.
Add($"Density code {descriptor.Density:X2}h has {descriptor.Blocks} blocks of {descriptor.BlockLength} bytes each");
else
scsiOneValue.Add($"Density code {descriptor.Density:X2}h");
if(modeSense.DPOandFUA)
scsiOneValue.Add("Drive supports DPO and FUA bits");
if(modeSense.BlankCheckEnabled)
scsiOneValue.Add("Blank checking during write is enabled");
if(modeSense.BufferedMode.HasValue)
switch(modeSense.BufferedMode)
{
case 0:
scsiOneValue.Add("Device writes directly to media");
break;
case 1:
scsiOneValue.Add("Device uses a write cache");
break;
case 2:
scsiOneValue.Add("Device uses a write cache but doesn't return until cache is flushed");
break;
default:
scsiOneValue.Add($"Unknown buffered mode code 0x{modeSense.BufferedMode:X2}");
break;
}
if(modeSense.ModePages == null)
return;
foreach(ScsiPage page in modeSense.ModePages)
switch(page.page)
{
case 0x00:
{
if(deviceType == PeripheralDeviceTypes.MultiMediaDevice &&
page.subpage == 0)
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyModePage_00_SFF(page.value));
else
scsiOneValue.Add($"Density code {descriptor.Density:X2}h");
if(modeSense.DPOandFUA)
scsiOneValue.Add("Drive supports DPO and FUA bits");
if(modeSense.BlankCheckEnabled)
scsiOneValue.Add("Blank checking during write is enabled");
if(modeSense.BufferedMode.HasValue)
switch(modeSense.BufferedMode)
{
case 0:
scsiOneValue.Add("Device writes directly to media");
break;
case 1:
scsiOneValue.Add("Device uses a write cache");
break;
case 2:
scsiOneValue.Add("Device uses a write cache but doesn't return until cache is flushed");
break;
default:
scsiOneValue.Add($"Unknown buffered mode code 0x{modeSense.BufferedMode:X2}");
break;
}
if(modeSense.ModePages == null)
return;
foreach(ScsiPage page in modeSense.ModePages)
switch(page.page)
{
case 0x00:
{
if(deviceType == PeripheralDeviceTypes.MultiMediaDevice &&
page.subpage == 0)
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyModePage_00_SFF(page.value));
else
modePages.
Add(page.subpage != 0 ? $"MODE page {page.page:X2}h subpage {page.subpage:X2}h" : $"MODE page {page.page:X2}h",
"Unknown vendor mode page");
break;
}
case 0x01:
{
if(page.subpage == 0)
modePages.Add($"MODE page {page.page:X2}h",
deviceType == PeripheralDeviceTypes.MultiMediaDevice
? Modes.PrettifyModePage_01_MMC(page.value)
: Modes.PrettifyModePage_01(page.value));
else
goto default;
break;
}
case 0x02:
{
if(page.subpage == 0)
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyModePage_02(page.value));
else
goto default;
break;
}
case 0x03:
{
if(page.subpage == 0)
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyModePage_03(page.value));
else
goto default;
break;
}
case 0x04:
{
if(page.subpage == 0)
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyModePage_04(page.value));
else
goto default;
break;
}
case 0x05:
{
if(page.subpage == 0)
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyModePage_05(page.value));
else
goto default;
break;
}
case 0x06:
{
if(page.subpage == 0)
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyModePage_06(page.value));
else
goto default;
break;
}
case 0x07:
{
if(page.subpage == 0)
modePages.Add($"MODE page {page.page:X2}h",
deviceType == PeripheralDeviceTypes.MultiMediaDevice
? Modes.PrettifyModePage_07_MMC(page.value)
: Modes.PrettifyModePage_07(page.value));
else
goto default;
break;
}
case 0x08:
{
if(page.subpage == 0)
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyModePage_08(page.value));
else
goto default;
break;
}
case 0x0A:
{
if(page.subpage == 0)
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyModePage_0A(page.value));
else if(page.subpage == 1)
modePages.Add($"MODE page {page.page:X2}h subpage {page.subpage:X2}h",
Modes.PrettifyModePage_0A_S01(page.value));
else
goto default;
break;
}
case 0x0B:
{
if(page.subpage == 0)
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyModePage_0B(page.value));
else
goto default;
break;
}
case 0x0D:
{
if(page.subpage == 0)
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyModePage_0D(page.value));
else
goto default;
break;
}
case 0x0E:
{
if(page.subpage == 0)
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyModePage_0E(page.value));
else
goto default;
break;
}
case 0x0F:
{
if(page.subpage == 0)
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyModePage_0F(page.value));
else
goto default;
break;
}
case 0x10:
{
if(page.subpage == 0)
modePages.Add($"MODE page {page.page:X2}h",
deviceType == PeripheralDeviceTypes.SequentialAccess
? Modes.PrettifyModePage_10_SSC(page.value)
: Modes.PrettifyModePage_10(page.value));
else
goto default;
break;
}
case 0x11:
{
if(page.subpage == 0)
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyModePage_11(page.value));
else
goto default;
break;
}
case 0x12:
case 0x13:
case 0x14:
{
if(page.subpage == 0)
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyModePage_12_13_14(page.value));
else
goto default;
break;
}
case 0x1A:
{
if(page.subpage == 0)
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyModePage_1A(page.value));
else if(page.subpage == 1)
modePages.Add($"MODE page {page.page:X2}h subpage {page.subpage:X2}h",
Modes.PrettifyModePage_1A_S01(page.value));
else
goto default;
break;
}
case 0x1B:
{
if(page.subpage == 0)
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyModePage_1B(page.value));
else
goto default;
break;
}
case 0x1C:
{
if(page.subpage == 0)
modePages.Add($"MODE page {page.page:X2}h",
deviceType == PeripheralDeviceTypes.MultiMediaDevice
? Modes.PrettifyModePage_1C_SFF(page.value)
: Modes.PrettifyModePage_1C(page.value));
else if(page.subpage == 1)
modePages.Add($"MODE page {page.page:X2}h subpage {page.subpage:X2}h",
Modes.PrettifyModePage_1C_S01(page.value));
else
goto default;
break;
}
case 0x1D:
{
if(page.subpage == 0)
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyModePage_1D(page.value));
else
goto default;
break;
}
case 0x21:
{
if(vendor == "CERTANCE")
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyCertanceModePage_21(page.value));
else
goto default;
break;
}
case 0x22:
{
if(vendor == "CERTANCE")
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyCertanceModePage_22(page.value));
else
goto default;
break;
}
case 0x24:
{
if(vendor == "IBM")
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyIBMModePage_24(page.value));
else
goto default;
break;
}
case 0x2A:
{
if(page.subpage == 0)
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyModePage_2A(page.value));
else
goto default;
break;
}
case 0x2F:
{
if(vendor == "IBM")
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyIBMModePage_2F(page.value));
else
goto default;
break;
}
case 0x30:
{
if(Modes.IsAppleModePage_30(page.value))
modePages.Add("MODE page 30h", "Drive identifies as an Apple OEM drive");
else
goto default;
break;
}
case 0x3B:
{
if(vendor == "HP")
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyHPModePage_3B(page.value));
else
goto default;
break;
}
case 0x3C:
{
if(vendor == "HP")
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyHPModePage_3C(page.value));
else
goto default;
break;
}
case 0x3D:
{
if(vendor == "IBM")
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyIBMModePage_3D(page.value));
else if(vendor == "HP")
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyHPModePage_3D(page.value));
else
goto default;
break;
}
case 0x3E:
{
if(vendor == "FUJITSU")
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyFujitsuModePage_3E(page.value));
else if(vendor == "HP")
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyHPModePage_3E(page.value));
else
goto default;
break;
}
default:
{
modePages.
Add(page.subpage != 0 ? $"MODE page {page.page:X2}h subpage {page.subpage:X2}h" : $"MODE page {page.page:X2}h",
"Unknown mode page");
}
"Unknown vendor mode page");
break;
break;
}
case 0x01:
{
if(page.subpage == 0)
modePages.Add($"MODE page {page.page:X2}h",
deviceType == PeripheralDeviceTypes.MultiMediaDevice
? Modes.PrettifyModePage_01_MMC(page.value)
: Modes.PrettifyModePage_01(page.value));
else
goto default;
break;
}
case 0x02:
{
if(page.subpage == 0)
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyModePage_02(page.value));
else
goto default;
break;
}
case 0x03:
{
if(page.subpage == 0)
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyModePage_03(page.value));
else
goto default;
break;
}
case 0x04:
{
if(page.subpage == 0)
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyModePage_04(page.value));
else
goto default;
break;
}
case 0x05:
{
if(page.subpage == 0)
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyModePage_05(page.value));
else
goto default;
break;
}
case 0x06:
{
if(page.subpage == 0)
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyModePage_06(page.value));
else
goto default;
break;
}
case 0x07:
{
if(page.subpage == 0)
modePages.Add($"MODE page {page.page:X2}h",
deviceType == PeripheralDeviceTypes.MultiMediaDevice
? Modes.PrettifyModePage_07_MMC(page.value)
: Modes.PrettifyModePage_07(page.value));
else
goto default;
break;
}
case 0x08:
{
if(page.subpage == 0)
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyModePage_08(page.value));
else
goto default;
break;
}
case 0x0A:
{
if(page.subpage == 0)
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyModePage_0A(page.value));
else if(page.subpage == 1)
modePages.Add($"MODE page {page.page:X2}h subpage {page.subpage:X2}h",
Modes.PrettifyModePage_0A_S01(page.value));
else
goto default;
break;
}
case 0x0B:
{
if(page.subpage == 0)
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyModePage_0B(page.value));
else
goto default;
break;
}
case 0x0D:
{
if(page.subpage == 0)
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyModePage_0D(page.value));
else
goto default;
break;
}
case 0x0E:
{
if(page.subpage == 0)
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyModePage_0E(page.value));
else
goto default;
break;
}
case 0x0F:
{
if(page.subpage == 0)
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyModePage_0F(page.value));
else
goto default;
break;
}
case 0x10:
{
if(page.subpage == 0)
modePages.Add($"MODE page {page.page:X2}h",
deviceType == PeripheralDeviceTypes.SequentialAccess
? Modes.PrettifyModePage_10_SSC(page.value)
: Modes.PrettifyModePage_10(page.value));
else
goto default;
break;
}
case 0x11:
{
if(page.subpage == 0)
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyModePage_11(page.value));
else
goto default;
break;
}
case 0x12:
case 0x13:
case 0x14:
{
if(page.subpage == 0)
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyModePage_12_13_14(page.value));
else
goto default;
break;
}
case 0x1A:
{
if(page.subpage == 0)
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyModePage_1A(page.value));
else if(page.subpage == 1)
modePages.Add($"MODE page {page.page:X2}h subpage {page.subpage:X2}h",
Modes.PrettifyModePage_1A_S01(page.value));
else
goto default;
break;
}
case 0x1B:
{
if(page.subpage == 0)
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyModePage_1B(page.value));
else
goto default;
break;
}
case 0x1C:
{
if(page.subpage == 0)
modePages.Add($"MODE page {page.page:X2}h",
deviceType == PeripheralDeviceTypes.MultiMediaDevice
? Modes.PrettifyModePage_1C_SFF(page.value)
: Modes.PrettifyModePage_1C(page.value));
else if(page.subpage == 1)
modePages.Add($"MODE page {page.page:X2}h subpage {page.subpage:X2}h",
Modes.PrettifyModePage_1C_S01(page.value));
else
goto default;
break;
}
case 0x1D:
{
if(page.subpage == 0)
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyModePage_1D(page.value));
else
goto default;
break;
}
case 0x21:
{
if(vendor == "CERTANCE")
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyCertanceModePage_21(page.value));
else
goto default;
break;
}
case 0x22:
{
if(vendor == "CERTANCE")
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyCertanceModePage_22(page.value));
else
goto default;
break;
}
case 0x24:
{
if(vendor == "IBM")
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyIBMModePage_24(page.value));
else
goto default;
break;
}
case 0x2A:
{
if(page.subpage == 0)
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyModePage_2A(page.value));
else
goto default;
break;
}
case 0x2F:
{
if(vendor == "IBM")
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyIBMModePage_2F(page.value));
else
goto default;
break;
}
case 0x30:
{
if(Modes.IsAppleModePage_30(page.value))
modePages.Add("MODE page 30h", "Drive identifies as an Apple OEM drive");
else
goto default;
break;
}
case 0x3B:
{
if(vendor == "HP")
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyHPModePage_3B(page.value));
else
goto default;
break;
}
case 0x3C:
{
if(vendor == "HP")
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyHPModePage_3C(page.value));
else
goto default;
break;
}
case 0x3D:
{
if(vendor == "IBM")
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyIBMModePage_3D(page.value));
else if(vendor == "HP")
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyHPModePage_3D(page.value));
else
goto default;
break;
}
case 0x3E:
{
if(vendor == "FUJITSU")
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyFujitsuModePage_3E(page.value));
else if(vendor == "HP")
modePages.Add($"MODE page {page.page:X2}h", Modes.PrettifyHPModePage_3E(page.value));
else
goto default;
break;
}
default:
{
modePages.
Add(page.subpage != 0 ? $"MODE page {page.page:X2}h subpage {page.subpage:X2}h" : $"MODE page {page.page:X2}h",
"Unknown mode page");
}
Dictionary<string, string> newModePages = new();
break;
}
foreach(KeyValuePair<string, string> kvp in modePages)
newModePages.Add(kvp.Key,
string.IsNullOrWhiteSpace(kvp.Value) ? "Undecoded" : kvp.Value.Replace("\n", "<br/>"));
Dictionary<string, string> newModePages = new();
modePages = newModePages;
}
foreach(KeyValuePair<string, string> kvp in modePages)
newModePages.Add(kvp.Key,
string.IsNullOrWhiteSpace(kvp.Value) ? "Undecoded" : kvp.Value.Replace("\n", "<br/>"));
modePages = newModePages;
}
}

View File

@@ -33,50 +33,49 @@
using System.Collections.Generic;
using Aaru.CommonTypes.Metadata;
namespace Aaru.Server.Core
namespace Aaru.Server.Core;
public static class SscTestedMedia
{
public static class SscTestedMedia
/// <summary>Takes the tested media from SCSI Streaming devices of a device report and prints it as a list of values</summary>
/// <param name="mediaOneValue">List to put values on</param>
/// <param name="testedMedia">List of tested media</param>
public static void Report(IEnumerable<TestedSequentialMedia> testedMedia, ref List<string> mediaOneValue)
{
/// <summary>Takes the tested media from SCSI Streaming devices of a device report and prints it as a list of values</summary>
/// <param name="mediaOneValue">List to put values on</param>
/// <param name="testedMedia">List of tested media</param>
public static void Report(IEnumerable<TestedSequentialMedia> testedMedia, ref List<string> mediaOneValue)
foreach(TestedSequentialMedia media in testedMedia)
{
foreach(TestedSequentialMedia media in testedMedia)
if(!string.IsNullOrWhiteSpace(media.MediumTypeName))
{
if(!string.IsNullOrWhiteSpace(media.MediumTypeName))
{
mediaOneValue.Add($"<i>Information for medium named \"{media.MediumTypeName}\"</i>");
mediaOneValue.Add($"<i>Information for medium named \"{media.MediumTypeName}\"</i>");
if(media.MediumType.HasValue)
mediaOneValue.Add($"Medium type code: {media.MediumType:X2}h");
}
else if(media.MediumType.HasValue)
{
mediaOneValue.Add($"<i>Information for medium type {media.MediumType:X2}h</i>");
}
else
{
mediaOneValue.Add("<i>Information for unknown medium type</i>");
}
if(!string.IsNullOrWhiteSpace(media.Manufacturer))
mediaOneValue.Add($"Medium manufactured by: {media.Manufacturer}");
if(!string.IsNullOrWhiteSpace(media.Model))
mediaOneValue.Add($"Medium model: {media.Model}");
if(media.Density.HasValue)
mediaOneValue.Add($"Medium has density code {media.Density:X2}h");
if(media.CanReadMediaSerial == true)
mediaOneValue.Add("Drive can read medium serial number.");
if(media.MediaIsRecognized)
mediaOneValue.Add("Drive recognizes this medium.");
mediaOneValue.Add("");
if(media.MediumType.HasValue)
mediaOneValue.Add($"Medium type code: {media.MediumType:X2}h");
}
else if(media.MediumType.HasValue)
{
mediaOneValue.Add($"<i>Information for medium type {media.MediumType:X2}h</i>");
}
else
{
mediaOneValue.Add("<i>Information for unknown medium type</i>");
}
if(!string.IsNullOrWhiteSpace(media.Manufacturer))
mediaOneValue.Add($"Medium manufactured by: {media.Manufacturer}");
if(!string.IsNullOrWhiteSpace(media.Model))
mediaOneValue.Add($"Medium model: {media.Model}");
if(media.Density.HasValue)
mediaOneValue.Add($"Medium has density code {media.Density:X2}h");
if(media.CanReadMediaSerial == true)
mediaOneValue.Add("Drive can read medium serial number.");
if(media.MediaIsRecognized)
mediaOneValue.Add("Drive recognizes this medium.");
mediaOneValue.Add("");
}
}
}

View File

@@ -35,489 +35,488 @@ using Aaru.CommonTypes.Metadata;
using Aaru.Server.Models;
using Version = Aaru.Server.Models.Version;
namespace Aaru.Server.Core
namespace Aaru.Server.Core;
public static class StatsConverter
{
public static class StatsConverter
public static void Convert(Stats newStats)
{
public static void Convert(Stats newStats)
var ctx = new AaruServerContext();
if(newStats.Commands?.Analyze > 0)
{
var ctx = new AaruServerContext();
Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "fs-info");
if(newStats.Commands?.Analyze > 0)
{
Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "fs-info");
if(existing == null)
ctx.Commands.Add(new()
{
Count = newStats.Commands.Analyze,
Name = "fs-info"
});
else
existing.Count += newStats.Commands.Analyze;
}
if(newStats.Commands?.Benchmark > 0)
{
Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "benchmark");
if(existing == null)
ctx.Commands.Add(new()
{
Count = newStats.Commands.Benchmark,
Name = "benchmark"
});
else
existing.Count += newStats.Commands.Benchmark;
}
if(newStats.Commands?.Checksum > 0)
{
Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "checksum");
if(existing == null)
ctx.Commands.Add(new()
{
Count = newStats.Commands.Checksum,
Name = "checksum"
});
else
existing.Count += newStats.Commands.Checksum;
}
if(newStats.Commands?.Compare > 0)
{
Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "compare");
if(existing == null)
ctx.Commands.Add(new()
{
Count = newStats.Commands.Compare,
Name = "compare"
});
else
existing.Count += newStats.Commands.Compare;
}
if(newStats.Commands?.CreateSidecar > 0)
{
Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "create-sidecar");
if(existing == null)
ctx.Commands.Add(new()
{
Count = newStats.Commands.CreateSidecar,
Name = "create-sidecar"
});
else
existing.Count += newStats.Commands.CreateSidecar;
}
if(newStats.Commands?.Decode > 0)
{
Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "decode");
if(existing == null)
ctx.Commands.Add(new()
{
Count = newStats.Commands.Decode,
Name = "decode"
});
else
existing.Count += newStats.Commands.Decode;
}
if(newStats.Commands?.DeviceInfo > 0)
{
Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "device-info");
if(existing == null)
ctx.Commands.Add(new()
{
Count = newStats.Commands.DeviceInfo,
Name = "device-info"
});
else
existing.Count += newStats.Commands.DeviceInfo;
}
if(newStats.Commands?.DeviceReport > 0)
{
Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "device-report");
if(existing == null)
ctx.Commands.Add(new()
{
Count = newStats.Commands.DeviceReport,
Name = "device-report"
});
else
existing.Count += newStats.Commands.DeviceReport;
}
if(newStats.Commands?.DumpMedia > 0)
{
Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "dump-media");
if(existing == null)
ctx.Commands.Add(new()
{
Count = newStats.Commands.DumpMedia,
Name = "dump-media"
});
else
existing.Count += newStats.Commands.DumpMedia;
}
if(newStats.Commands?.Entropy > 0)
{
Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "entropy");
if(existing == null)
ctx.Commands.Add(new()
{
Count = newStats.Commands.Entropy,
Name = "entropy"
});
else
existing.Count += newStats.Commands.Entropy;
}
if(newStats.Commands?.Formats > 0)
{
Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "formats");
if(existing == null)
ctx.Commands.Add(new()
{
Count = newStats.Commands.Formats,
Name = "formats"
});
else
existing.Count += newStats.Commands.Formats;
}
if(newStats.Commands?.MediaInfo > 0)
{
Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "media-info");
if(existing == null)
ctx.Commands.Add(new()
{
Count = newStats.Commands.MediaInfo,
Name = "media-info"
});
else
existing.Count += newStats.Commands.MediaInfo;
}
if(newStats.Commands?.MediaScan > 0)
{
Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "media-scan");
if(existing == null)
ctx.Commands.Add(new()
{
Count = newStats.Commands.MediaScan,
Name = "media-scan"
});
else
existing.Count += newStats.Commands.MediaScan;
}
if(newStats.Commands?.PrintHex > 0)
{
Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "printhex");
if(existing == null)
ctx.Commands.Add(new()
{
Count = newStats.Commands.PrintHex,
Name = "printhex"
});
else
existing.Count += newStats.Commands.PrintHex;
}
if(newStats.Commands?.Verify > 0)
{
Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "verify");
if(existing == null)
ctx.Commands.Add(new()
{
Count = newStats.Commands.Verify,
Name = "verify"
});
else
existing.Count += newStats.Commands.Verify;
}
if(newStats.Commands?.Ls > 0)
{
Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "ls");
if(existing == null)
ctx.Commands.Add(new()
{
Count = newStats.Commands.Ls,
Name = "ls"
});
else
existing.Count += newStats.Commands.Ls;
}
if(newStats.Commands?.ExtractFiles > 0)
{
Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "extract-files");
if(existing == null)
ctx.Commands.Add(new()
{
Count = newStats.Commands.ExtractFiles,
Name = "extract-files"
});
else
existing.Count += newStats.Commands.ExtractFiles;
}
if(newStats.Commands?.ListDevices > 0)
{
Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "list-devices");
if(existing == null)
ctx.Commands.Add(new()
{
Count = newStats.Commands.ListDevices,
Name = "list-devices"
});
else
existing.Count += newStats.Commands.ListDevices;
}
if(newStats.Commands?.ListEncodings > 0)
{
Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "list-encodings");
if(existing == null)
ctx.Commands.Add(new()
{
Count = newStats.Commands.ListEncodings,
Name = "list-encodings"
});
else
existing.Count += newStats.Commands.ListEncodings;
}
if(newStats.Commands?.ConvertImage > 0)
{
Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "convert-image");
if(existing == null)
ctx.Commands.Add(new()
{
Count = newStats.Commands.ConvertImage,
Name = "convert-image"
});
else
existing.Count += newStats.Commands.ConvertImage;
}
if(newStats.Commands?.ImageInfo > 0)
{
Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "image-info");
if(existing == null)
ctx.Commands.Add(new()
{
Count = newStats.Commands.ImageInfo,
Name = "image-info"
});
else
existing.Count += newStats.Commands.ImageInfo;
}
if(newStats.OperatingSystems != null)
{
foreach(OsStats operatingSystem in newStats.OperatingSystems)
if(existing == null)
ctx.Commands.Add(new()
{
if(string.IsNullOrWhiteSpace(operatingSystem.name) ||
string.IsNullOrWhiteSpace(operatingSystem.version))
continue;
OperatingSystem existing =
ctx.OperatingSystems.FirstOrDefault(c => c.Name == operatingSystem.name &&
c.Version == operatingSystem.version);
if(existing == null)
ctx.OperatingSystems.Add(new()
{
Count = operatingSystem.Value,
Name = operatingSystem.name,
Version = operatingSystem.version
});
else
existing.Count += operatingSystem.Value;
}
}
Count = newStats.Commands.Analyze,
Name = "fs-info"
});
else
existing.Count += newStats.Commands.Analyze;
}
if(newStats.Commands?.Benchmark > 0)
{
Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "benchmark");
if(existing == null)
ctx.Commands.Add(new()
{
Count = newStats.Commands.Benchmark,
Name = "benchmark"
});
else
existing.Count += newStats.Commands.Benchmark;
}
if(newStats.Commands?.Checksum > 0)
{
Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "checksum");
if(existing == null)
ctx.Commands.Add(new()
{
Count = newStats.Commands.Checksum,
Name = "checksum"
});
else
existing.Count += newStats.Commands.Checksum;
}
if(newStats.Commands?.Compare > 0)
{
Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "compare");
if(existing == null)
ctx.Commands.Add(new()
{
Count = newStats.Commands.Compare,
Name = "compare"
});
else
existing.Count += newStats.Commands.Compare;
}
if(newStats.Commands?.CreateSidecar > 0)
{
Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "create-sidecar");
if(existing == null)
ctx.Commands.Add(new()
{
Count = newStats.Commands.CreateSidecar,
Name = "create-sidecar"
});
else
existing.Count += newStats.Commands.CreateSidecar;
}
if(newStats.Commands?.Decode > 0)
{
Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "decode");
if(existing == null)
ctx.Commands.Add(new()
{
Count = newStats.Commands.Decode,
Name = "decode"
});
else
existing.Count += newStats.Commands.Decode;
}
if(newStats.Commands?.DeviceInfo > 0)
{
Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "device-info");
if(existing == null)
ctx.Commands.Add(new()
{
Count = newStats.Commands.DeviceInfo,
Name = "device-info"
});
else
existing.Count += newStats.Commands.DeviceInfo;
}
if(newStats.Commands?.DeviceReport > 0)
{
Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "device-report");
if(existing == null)
ctx.Commands.Add(new()
{
Count = newStats.Commands.DeviceReport,
Name = "device-report"
});
else
existing.Count += newStats.Commands.DeviceReport;
}
if(newStats.Commands?.DumpMedia > 0)
{
Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "dump-media");
if(existing == null)
ctx.Commands.Add(new()
{
Count = newStats.Commands.DumpMedia,
Name = "dump-media"
});
else
existing.Count += newStats.Commands.DumpMedia;
}
if(newStats.Commands?.Entropy > 0)
{
Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "entropy");
if(existing == null)
ctx.Commands.Add(new()
{
Count = newStats.Commands.Entropy,
Name = "entropy"
});
else
existing.Count += newStats.Commands.Entropy;
}
if(newStats.Commands?.Formats > 0)
{
Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "formats");
if(existing == null)
ctx.Commands.Add(new()
{
Count = newStats.Commands.Formats,
Name = "formats"
});
else
existing.Count += newStats.Commands.Formats;
}
if(newStats.Commands?.MediaInfo > 0)
{
Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "media-info");
if(existing == null)
ctx.Commands.Add(new()
{
Count = newStats.Commands.MediaInfo,
Name = "media-info"
});
else
existing.Count += newStats.Commands.MediaInfo;
}
if(newStats.Commands?.MediaScan > 0)
{
Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "media-scan");
if(existing == null)
ctx.Commands.Add(new()
{
Count = newStats.Commands.MediaScan,
Name = "media-scan"
});
else
existing.Count += newStats.Commands.MediaScan;
}
if(newStats.Commands?.PrintHex > 0)
{
Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "printhex");
if(existing == null)
ctx.Commands.Add(new()
{
Count = newStats.Commands.PrintHex,
Name = "printhex"
});
else
existing.Count += newStats.Commands.PrintHex;
}
if(newStats.Commands?.Verify > 0)
{
Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "verify");
if(existing == null)
ctx.Commands.Add(new()
{
Count = newStats.Commands.Verify,
Name = "verify"
});
else
existing.Count += newStats.Commands.Verify;
}
if(newStats.Commands?.Ls > 0)
{
Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "ls");
if(existing == null)
ctx.Commands.Add(new()
{
Count = newStats.Commands.Ls,
Name = "ls"
});
else
existing.Count += newStats.Commands.Ls;
}
if(newStats.Commands?.ExtractFiles > 0)
{
Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "extract-files");
if(existing == null)
ctx.Commands.Add(new()
{
Count = newStats.Commands.ExtractFiles,
Name = "extract-files"
});
else
existing.Count += newStats.Commands.ExtractFiles;
}
if(newStats.Commands?.ListDevices > 0)
{
Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "list-devices");
if(existing == null)
ctx.Commands.Add(new()
{
Count = newStats.Commands.ListDevices,
Name = "list-devices"
});
else
existing.Count += newStats.Commands.ListDevices;
}
if(newStats.Commands?.ListEncodings > 0)
{
Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "list-encodings");
if(existing == null)
ctx.Commands.Add(new()
{
Count = newStats.Commands.ListEncodings,
Name = "list-encodings"
});
else
existing.Count += newStats.Commands.ListEncodings;
}
if(newStats.Commands?.ConvertImage > 0)
{
Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "convert-image");
if(existing == null)
ctx.Commands.Add(new()
{
Count = newStats.Commands.ConvertImage,
Name = "convert-image"
});
else
existing.Count += newStats.Commands.ConvertImage;
}
if(newStats.Commands?.ImageInfo > 0)
{
Command existing = ctx.Commands.FirstOrDefault(c => c.Name == "image-info");
if(existing == null)
ctx.Commands.Add(new()
{
Count = newStats.Commands.ImageInfo,
Name = "image-info"
});
else
existing.Count += newStats.Commands.ImageInfo;
}
if(newStats.OperatingSystems != null)
{
foreach(OsStats operatingSystem in newStats.OperatingSystems)
{
if(string.IsNullOrWhiteSpace(operatingSystem.name) ||
string.IsNullOrWhiteSpace(operatingSystem.version))
continue;
OperatingSystem existing =
ctx.OperatingSystems.FirstOrDefault(c => c.Name == "Linux" && c.Version == null);
ctx.OperatingSystems.FirstOrDefault(c => c.Name == operatingSystem.name &&
c.Version == operatingSystem.version);
if(existing == null)
ctx.OperatingSystems.Add(new()
{
Count = 1,
Name = "Linux"
Count = operatingSystem.Value,
Name = operatingSystem.name,
Version = operatingSystem.version
});
else
existing.Count++;
existing.Count += operatingSystem.Value;
}
}
else
{
OperatingSystem existing =
ctx.OperatingSystems.FirstOrDefault(c => c.Name == "Linux" && c.Version == null);
if(newStats.Versions != null)
{
foreach(NameValueStats nvs in newStats.Versions)
if(existing == null)
ctx.OperatingSystems.Add(new()
{
if(string.IsNullOrWhiteSpace(nvs.name))
continue;
Version existing = ctx.Versions.FirstOrDefault(c => c.Name == nvs.name);
if(existing == null)
ctx.Versions.Add(new()
{
Count = nvs.Value,
Name = nvs.name
});
else
existing.Count += nvs.Value;
}
}
Count = 1,
Name = "Linux"
});
else
existing.Count++;
}
if(newStats.Versions != null)
{
foreach(NameValueStats nvs in newStats.Versions)
{
Version existing = ctx.Versions.FirstOrDefault(c => c.Name == "previous");
if(string.IsNullOrWhiteSpace(nvs.name))
continue;
Version existing = ctx.Versions.FirstOrDefault(c => c.Name == nvs.name);
if(existing == null)
ctx.Versions.Add(new()
{
Count = 1,
Name = "previous"
Count = nvs.Value,
Name = nvs.name
});
else
existing.Count++;
existing.Count += nvs.Value;
}
}
else
{
Version existing = ctx.Versions.FirstOrDefault(c => c.Name == "previous");
if(existing == null)
ctx.Versions.Add(new()
{
Count = 1,
Name = "previous"
});
else
existing.Count++;
}
if(newStats.Filesystems != null)
foreach(NameValueStats nvs in newStats.Filesystems)
{
if(string.IsNullOrWhiteSpace(nvs.name))
continue;
Filesystem existing = ctx.Filesystems.FirstOrDefault(c => c.Name == nvs.name);
if(existing == null)
ctx.Filesystems.Add(new()
{
Count = nvs.Value,
Name = nvs.name
});
else
existing.Count += nvs.Value;
}
if(newStats.Filesystems != null)
foreach(NameValueStats nvs in newStats.Filesystems)
{
if(string.IsNullOrWhiteSpace(nvs.name))
continue;
if(newStats.Partitions != null)
foreach(NameValueStats nvs in newStats.Partitions)
{
if(string.IsNullOrWhiteSpace(nvs.name))
continue;
Filesystem existing = ctx.Filesystems.FirstOrDefault(c => c.Name == nvs.name);
Partition existing = ctx.Partitions.FirstOrDefault(c => c.Name == nvs.name);
if(existing == null)
ctx.Filesystems.Add(new()
{
Count = nvs.Value,
Name = nvs.name
});
else
existing.Count += nvs.Value;
}
if(newStats.Partitions != null)
foreach(NameValueStats nvs in newStats.Partitions)
{
if(string.IsNullOrWhiteSpace(nvs.name))
continue;
Partition existing = ctx.Partitions.FirstOrDefault(c => c.Name == nvs.name);
if(existing == null)
ctx.Partitions.Add(new()
{
Count = nvs.Value,
Name = nvs.name
});
else
existing.Count += nvs.Value;
}
if(newStats.MediaImages != null)
foreach(NameValueStats nvs in newStats.MediaImages)
{
if(string.IsNullOrWhiteSpace(nvs.name))
continue;
MediaFormat existing = ctx.MediaFormats.FirstOrDefault(c => c.Name == nvs.name);
if(existing == null)
ctx.MediaFormats.Add(new()
{
Count = nvs.Value,
Name = nvs.name
});
else
existing.Count += nvs.Value;
}
if(newStats.Filters != null)
foreach(NameValueStats nvs in newStats.Filters)
{
if(string.IsNullOrWhiteSpace(nvs.name))
continue;
Filter existing = ctx.Filters.FirstOrDefault(c => c.Name == nvs.name);
if(existing == null)
ctx.Filters.Add(new()
{
Count = nvs.Value,
Name = nvs.name
});
else
existing.Count += nvs.Value;
}
if(newStats.Devices != null)
foreach(DeviceStats device in newStats.Devices.
Where(device => !string.IsNullOrWhiteSpace(device.Model)).
Where(device => !ctx.DeviceStats.Any(c => c.Bus == device.Bus &&
c.Manufacturer ==
device.Manufacturer &&
c.Model == device.Model &&
c.Revision == device.Revision)))
{
ctx.DeviceStats.Add(new()
if(existing == null)
ctx.Partitions.Add(new()
{
Bus = device.Bus,
Manufacturer = device.Manufacturer,
Model = device.Model,
Revision = device.Revision
Count = nvs.Value,
Name = nvs.name
});
}
else
existing.Count += nvs.Value;
}
if(newStats.Medias != null)
foreach(MediaStats media in newStats.Medias)
if(newStats.MediaImages != null)
foreach(NameValueStats nvs in newStats.MediaImages)
{
if(string.IsNullOrWhiteSpace(nvs.name))
continue;
MediaFormat existing = ctx.MediaFormats.FirstOrDefault(c => c.Name == nvs.name);
if(existing == null)
ctx.MediaFormats.Add(new()
{
Count = nvs.Value,
Name = nvs.name
});
else
existing.Count += nvs.Value;
}
if(newStats.Filters != null)
foreach(NameValueStats nvs in newStats.Filters)
{
if(string.IsNullOrWhiteSpace(nvs.name))
continue;
Filter existing = ctx.Filters.FirstOrDefault(c => c.Name == nvs.name);
if(existing == null)
ctx.Filters.Add(new()
{
Count = nvs.Value,
Name = nvs.name
});
else
existing.Count += nvs.Value;
}
if(newStats.Devices != null)
foreach(DeviceStats device in newStats.Devices.
Where(device => !string.IsNullOrWhiteSpace(device.Model)).
Where(device => !ctx.DeviceStats.Any(c => c.Bus == device.Bus &&
c.Manufacturer ==
device.Manufacturer &&
c.Model == device.Model &&
c.Revision == device.Revision)))
{
ctx.DeviceStats.Add(new()
{
if(string.IsNullOrWhiteSpace(media.type))
continue;
Bus = device.Bus,
Manufacturer = device.Manufacturer,
Model = device.Model,
Revision = device.Revision
});
}
Media existing = ctx.Medias.FirstOrDefault(c => c.Type == media.type && c.Real == media.real);
if(newStats.Medias != null)
foreach(MediaStats media in newStats.Medias)
{
if(string.IsNullOrWhiteSpace(media.type))
continue;
if(existing == null)
ctx.Medias.Add(new()
{
Count = media.Value,
Real = media.real,
Type = media.type
});
else
existing.Count += media.Value;
}
Media existing = ctx.Medias.FirstOrDefault(c => c.Type == media.type && c.Real == media.real);
ctx.SaveChanges();
}
if(existing == null)
ctx.Medias.Add(new()
{
Count = media.Value,
Real = media.real,
Type = media.type
});
else
existing.Count += media.Value;
}
ctx.SaveChanges();
}
}

View File

@@ -32,364 +32,363 @@
using System.Collections.Generic;
namespace Aaru.Server.Core
namespace Aaru.Server.Core;
public static class TestedMedia
{
public static class TestedMedia
/// <summary>Takes the tested media from a device report and prints it as a list of values</summary>
/// <param name="mediaOneValue">List to put values on</param>
/// <param name="testedMedias">List of tested media</param>
public static void Report(List<CommonTypes.Metadata.TestedMedia> testedMedias, ref List<string> mediaOneValue)
{
/// <summary>Takes the tested media from a device report and prints it as a list of values</summary>
/// <param name="mediaOneValue">List to put values on</param>
/// <param name="testedMedias">List of tested media</param>
public static void Report(List<CommonTypes.Metadata.TestedMedia> testedMedias, ref List<string> mediaOneValue)
foreach(CommonTypes.Metadata.TestedMedia testedMedia in testedMedias)
{
foreach(CommonTypes.Metadata.TestedMedia testedMedia in testedMedias)
if(!string.IsNullOrWhiteSpace(testedMedia.MediumTypeName))
{
if(!string.IsNullOrWhiteSpace(testedMedia.MediumTypeName))
{
mediaOneValue.Add($"<i>Information for medium named \"{testedMedia.MediumTypeName}\"</i>");
mediaOneValue.Add($"<i>Information for medium named \"{testedMedia.MediumTypeName}\"</i>");
if(testedMedia.MediumType != null)
mediaOneValue.Add($"Medium type code: {testedMedia.MediumType:X2}h");
}
else if(testedMedia.MediumType != null)
{
mediaOneValue.Add($"<i>Information for medium type {testedMedia.MediumType:X2}h</i>");
}
else
{
mediaOneValue.Add("<i>Information for unknown medium type</i>");
}
mediaOneValue.Add(testedMedia.MediaIsRecognized ? "Drive recognizes this medium."
: "Drive does not recognize this medium.");
if(!string.IsNullOrWhiteSpace(testedMedia.Manufacturer))
mediaOneValue.Add($"Medium manufactured by: {testedMedia.Manufacturer}");
if(!string.IsNullOrWhiteSpace(testedMedia.Model))
mediaOneValue.Add($"Medium model: {testedMedia.Model}");
if(testedMedia.Density != null)
mediaOneValue.Add($"Density code: {testedMedia.Density:X2}h");
if(testedMedia.BlockSize != null)
mediaOneValue.Add($"Logical sector size: {testedMedia.BlockSize} bytes");
if(testedMedia.PhysicalBlockSize != null)
mediaOneValue.Add($"Physical sector size: {testedMedia.PhysicalBlockSize} bytes");
if(testedMedia.LongBlockSize != null)
mediaOneValue.Add($"READ LONG sector size: {testedMedia.LongBlockSize} bytes");
if(testedMedia.Blocks != null &&
testedMedia.BlockSize != null)
{
mediaOneValue.Add($"Medium has {testedMedia.Blocks} blocks of {testedMedia.BlockSize} bytes each");
if(testedMedia.Blocks * testedMedia.BlockSize / 1024 / 1024 > 1000000)
mediaOneValue.
Add($"Medium size: {testedMedia.Blocks * testedMedia.BlockSize} bytes, {testedMedia.Blocks * testedMedia.BlockSize / 1000 / 1000 / 1000 / 1000} Tb, {(double)(testedMedia.Blocks * testedMedia.BlockSize) / 1024 / 1024 / 1024 / 1024:F2} TiB");
else if(testedMedia.Blocks * testedMedia.BlockSize / 1024 / 1024 > 1000)
mediaOneValue.
Add($"Medium size: {testedMedia.Blocks * testedMedia.BlockSize} bytes, {testedMedia.Blocks * testedMedia.BlockSize / 1000 / 1000 / 1000} Gb, {(double)(testedMedia.Blocks * testedMedia.BlockSize) / 1024 / 1024 / 1024:F2} GiB");
else
mediaOneValue.
Add($"Medium size: {testedMedia.Blocks * testedMedia.BlockSize} bytes, {testedMedia.Blocks * testedMedia.BlockSize / 1000 / 1000} Mb, {(double)(testedMedia.Blocks * testedMedia.BlockSize) / 1024 / 1024:F2} MiB");
}
if(testedMedia.CHS != null &&
testedMedia.CurrentCHS != null)
{
int currentSectors = testedMedia.CurrentCHS.Cylinders * testedMedia.CurrentCHS.Heads *
testedMedia.CurrentCHS.Sectors;
mediaOneValue.
Add($"Cylinders: {testedMedia.CHS.Cylinders} max., {testedMedia.CurrentCHS.Cylinders} current");
mediaOneValue.Add($"Heads: {testedMedia.CHS.Heads} max., {testedMedia.CurrentCHS.Heads} current");
mediaOneValue.
Add($"Sectors per track: {testedMedia.CHS.Sectors} max., {testedMedia.CurrentCHS.Sectors} current");
mediaOneValue.
Add($"Sectors addressable in CHS mode: {testedMedia.CHS.Cylinders * testedMedia.CHS.Heads * testedMedia.CHS.Sectors} max., {currentSectors} current");
mediaOneValue.
Add($"Medium size in CHS mode: {(ulong)currentSectors * testedMedia.BlockSize} bytes, {(ulong)currentSectors * testedMedia.BlockSize / 1000 / 1000} Mb, {(double)((ulong)currentSectors * testedMedia.BlockSize) / 1024 / 1024:F2} MiB");
}
else if(testedMedia.CHS != null)
{
int currentSectors = testedMedia.CHS.Cylinders * testedMedia.CHS.Heads * testedMedia.CHS.Sectors;
mediaOneValue.Add($"Cylinders: {testedMedia.CHS.Cylinders}");
mediaOneValue.Add($"Heads: {testedMedia.CHS.Heads}");
mediaOneValue.Add($"Sectors per track: {testedMedia.CHS.Sectors}");
mediaOneValue.Add($"Sectors addressable in CHS mode: {currentSectors}");
mediaOneValue.
Add($"Medium size in CHS mode: {(ulong)currentSectors * testedMedia.BlockSize} bytes, {(ulong)currentSectors * testedMedia.BlockSize / 1000 / 1000} Mb, {(double)((ulong)currentSectors * testedMedia.BlockSize) / 1024 / 1024:F2} MiB");
}
if(testedMedia.LBASectors != null)
{
mediaOneValue.Add($"Sectors addressable in sectors in 28-bit LBA mode: {testedMedia.LBASectors}");
if((ulong)testedMedia.LBASectors * testedMedia.BlockSize / 1024 / 1024 > 1000000)
mediaOneValue.
Add($"Medium size in 28-bit LBA mode: {(ulong)testedMedia.LBASectors * testedMedia.BlockSize} bytes, {(ulong)testedMedia.LBASectors * testedMedia.BlockSize / 1000 / 1000 / 1000 / 1000} Tb, {(double)((ulong)testedMedia.LBASectors * testedMedia.BlockSize) / 1024 / 1024 / 1024 / 1024:F2} TiB");
else if((ulong)testedMedia.LBASectors * testedMedia.BlockSize / 1024 / 1024 > 1000)
mediaOneValue.
Add($"Medium size in 28-bit LBA mode: {(ulong)testedMedia.LBASectors * testedMedia.BlockSize} bytes, {(ulong)testedMedia.LBASectors * testedMedia.BlockSize / 1000 / 1000 / 1000} Gb, {(double)((ulong)testedMedia.LBASectors * testedMedia.BlockSize) / 1024 / 1024 / 1024:F2} GiB");
else
mediaOneValue.
Add($"Medium size in 28-bit LBA mode: {(ulong)testedMedia.LBASectors * testedMedia.BlockSize} bytes, {(ulong)testedMedia.LBASectors * testedMedia.BlockSize / 1000 / 1000} Mb, {(double)((ulong)testedMedia.LBASectors * testedMedia.BlockSize) / 1024 / 1024:F2} MiB");
}
if(testedMedia.LBA48Sectors != null)
{
mediaOneValue.Add($"Sectors addressable in sectors in 48-bit LBA mode: {testedMedia.LBA48Sectors}");
if(testedMedia.LBA48Sectors * testedMedia.BlockSize / 1024 / 1024 > 1000000)
mediaOneValue.
Add($"Medium size in 48-bit LBA mode: {testedMedia.LBA48Sectors * testedMedia.BlockSize} bytes, {testedMedia.LBA48Sectors * testedMedia.BlockSize / 1000 / 1000 / 1000 / 1000} Tb, {(double)(testedMedia.LBA48Sectors * testedMedia.BlockSize) / 1024 / 1024 / 1024 / 1024:F2} TiB");
else if(testedMedia.LBA48Sectors * testedMedia.BlockSize / 1024 / 1024 > 1000)
mediaOneValue.
Add($"Medium size in 48-bit LBA mode: {testedMedia.LBA48Sectors * testedMedia.BlockSize} bytes, {testedMedia.LBA48Sectors * testedMedia.BlockSize / 1000 / 1000 / 1000} Gb, {(double)(testedMedia.LBA48Sectors * testedMedia.BlockSize) / 1024 / 1024 / 1024:F2} GiB");
else
mediaOneValue.
Add($"Medium size in 48-bit LBA mode: {testedMedia.LBA48Sectors * testedMedia.BlockSize} bytes, {testedMedia.LBA48Sectors * testedMedia.BlockSize / 1000 / 1000} Mb, {(double)(testedMedia.LBA48Sectors * testedMedia.BlockSize) / 1024 / 1024:F2} MiB");
}
if(testedMedia.NominalRotationRate != null &&
testedMedia.NominalRotationRate != 0x0000 &&
testedMedia.NominalRotationRate != 0xFFFF)
mediaOneValue.Add(testedMedia.NominalRotationRate == 0x0001 ? "Medium does not rotate."
: $"Medium rotates at {testedMedia.NominalRotationRate} rpm");
if(testedMedia.BlockSize != null &&
testedMedia.PhysicalBlockSize != null &&
testedMedia.BlockSize.Value != testedMedia.PhysicalBlockSize.Value &&
(testedMedia.LogicalAlignment & 0x8000) == 0x0000 &&
(testedMedia.LogicalAlignment & 0x4000) == 0x4000)
mediaOneValue.
Add($"Logical sector starts at offset {testedMedia.LogicalAlignment & 0x3FFF} from physical sector");
if(testedMedia.SupportsReadSectors == true)
mediaOneValue.Add("Device can use the READ SECTOR(S) command in CHS mode with this medium");
if(testedMedia.SupportsReadRetry == true)
mediaOneValue.Add("Device can use the READ SECTOR(S) RETRY command in CHS mode with this medium");
if(testedMedia.SupportsReadDma == true)
mediaOneValue.Add("Device can use the READ DMA command in CHS mode with this medium");
if(testedMedia.SupportsReadDmaRetry == true)
mediaOneValue.Add("Device can use the READ DMA RETRY command in CHS mode with this medium");
if(testedMedia.SupportsReadLong == true)
mediaOneValue.Add("Device can use the READ LONG command in CHS mode with this medium");
if(testedMedia.SupportsReadLongRetry == true)
mediaOneValue.Add("Device can use the READ LONG RETRY command in CHS mode with this medium");
if(testedMedia.SupportsReadLba == true)
mediaOneValue.Add("Device can use the READ SECTOR(S) command in 28-bit LBA mode with this medium");
if(testedMedia.SupportsReadRetryLba == true)
mediaOneValue.
Add("Device can use the READ SECTOR(S) RETRY command in 28-bit LBA mode with this medium");
if(testedMedia.SupportsReadDmaLba == true)
mediaOneValue.Add("Device can use the READ DMA command in 28-bit LBA mode with this medium");
if(testedMedia.SupportsReadDmaRetryLba == true)
mediaOneValue.Add("Device can use the READ DMA RETRY command in 28-bit LBA mode with this medium");
if(testedMedia.SupportsReadLongLba == true)
mediaOneValue.Add("Device can use the READ LONG command in 28-bit LBA mode with this medium");
if(testedMedia.SupportsReadLongRetryLba == true)
mediaOneValue.Add("Device can use the READ LONG RETRY command in 28-bit LBA mode with this medium");
if(testedMedia.SupportsReadLba48 == true)
mediaOneValue.Add("Device can use the READ SECTOR(S) command in 48-bit LBA mode with this medium");
if(testedMedia.SupportsReadDmaLba48 == true)
mediaOneValue.Add("Device can use the READ DMA command in 48-bit LBA mode with this medium");
if(testedMedia.SupportsSeek == true)
mediaOneValue.Add("Device can use the SEEK command in CHS mode with this medium");
if(testedMedia.SupportsSeekLba == true)
mediaOneValue.Add("Device can use the SEEK command in 28-bit LBA mode with this medium");
if(testedMedia.SupportsReadCapacity == true)
mediaOneValue.Add("Device can use the READ CAPACITY (10) command with this medium");
if(testedMedia.SupportsReadCapacity16 == true)
mediaOneValue.Add("Device can use the READ CAPACITY (16) command with this medium");
if(testedMedia.SupportsRead6 == true)
mediaOneValue.Add("Device can use the READ (6) command with this medium");
if(testedMedia.SupportsRead10 == true)
mediaOneValue.Add("Device can use the READ (10) command with this medium");
if(testedMedia.SupportsRead12 == true)
mediaOneValue.Add("Device can use the READ (12) command with this medium");
if(testedMedia.SupportsRead16 == true)
mediaOneValue.Add("Device can use the READ (16) command with this medium");
if(testedMedia.SupportsReadLong == true)
mediaOneValue.Add("Device can use the READ LONG (10) command with this medium");
if(testedMedia.SupportsReadLong16 == true)
mediaOneValue.Add("Device can use the READ LONG (16) command with this medium");
if(testedMedia.SupportsReadCd == true)
mediaOneValue.Add("Device can use the READ CD command with LBA addressing with this medium");
if(testedMedia.SupportsReadCdMsf == true)
mediaOneValue.Add("Device can use the READ CD command with MM:SS:FF addressing with this medium");
if(testedMedia.SupportsReadCdRaw == true)
mediaOneValue.
Add("Device can use the READ CD command with LBA addressing with this medium to read raw sector");
if(testedMedia.SupportsReadCdMsfRaw == true)
mediaOneValue.
Add("Device can use the READ CD command with MM:SS:FF addressing with this medium read raw sector");
if(testedMedia.SupportsHLDTSTReadRawDVD == true)
mediaOneValue.Add("Device can use the HL-DT-ST vendor READ DVD (RAW) command with this medium");
if(testedMedia.SupportsNECReadCDDA == true)
mediaOneValue.Add("Device can use the NEC vendor READ CD-DA command with this medium");
if(testedMedia.SupportsPioneerReadCDDA == true)
mediaOneValue.Add("Device can use the PIONEER vendor READ CD-DA command with this medium");
if(testedMedia.SupportsPioneerReadCDDAMSF == true)
mediaOneValue.Add("Device can use the PIONEER vendor READ CD-DA MSF command with this medium");
if(testedMedia.SupportsPlextorReadCDDA == true)
mediaOneValue.Add("Device can use the PLEXTOR vendor READ CD-DA command with this medium");
if(testedMedia.SupportsPlextorReadRawDVD == true)
mediaOneValue.Add("Device can use the PLEXTOR vendor READ DVD (RAW) command with this medium");
if(testedMedia.CanReadAACS == true)
mediaOneValue.Add("Device can read the Advanced Access Content System from this medium");
if(testedMedia.CanReadADIP == true)
mediaOneValue.Add("Device can read the DVD ADress-In-Pregroove from this medium");
if(testedMedia.CanReadATIP == true)
mediaOneValue.Add("Device can read the CD Absolute-Time-In-Pregroove from this medium");
if(testedMedia.CanReadBCA == true)
mediaOneValue.Add("Device can read the Burst Cutting Area from this medium");
if(testedMedia.CanReadC2Pointers == true)
mediaOneValue.Add("Device can report the C2 pointers when reading from this medium");
if(testedMedia.CanReadCMI == true)
mediaOneValue.Add("Device can read the Copyright Management Information from this medium");
if(testedMedia.CanReadCorrectedSubchannel == true)
mediaOneValue.Add("Device can correct subchannels when reading from this medium");
if(testedMedia.CanReadCorrectedSubchannelWithC2 == true)
mediaOneValue.
Add("Device can correct subchannels and report the C2 pointers when reading from this medium");
if(testedMedia.CanReadDCB == true)
mediaOneValue.Add("Device can read the Disc Control Blocks from this medium");
if(testedMedia.CanReadDDS == true)
mediaOneValue.Add("Device can read the Disc Definition Structure from this medium");
if(testedMedia.CanReadDMI == true)
mediaOneValue.Add("Device can read the Disc Manufacturer Information from this medium");
if(testedMedia.CanReadDiscInformation == true)
mediaOneValue.Add("Device can read the Disc Information from this medium");
if(testedMedia.CanReadFullTOC == true)
mediaOneValue.Add("Device can read the Table of Contents from this medium, without processing it");
if(testedMedia.CanReadHDCMI == true)
mediaOneValue.Add("Device can read the HD DVD Copyright Management Information from this medium");
if(testedMedia.CanReadLayerCapacity == true)
mediaOneValue.Add("Device can read the layer capacity from this medium");
if(testedMedia.CanReadFirstTrackPreGap == true)
mediaOneValue.Add("Device can read the first track's pregap data");
if(testedMedia.CanReadLeadIn == true)
mediaOneValue.Add("Device can read the Lead-In from this medium");
if(testedMedia.CanReadLeadOut == true)
mediaOneValue.Add("Device can read the Lead-Out from this medium");
if(testedMedia.CanReadMediaID == true)
mediaOneValue.Add("Device can read the Media ID from this medium");
if(testedMedia.CanReadMediaSerial == true)
mediaOneValue.Add("Device can read the Media Serial Number from this medium");
if(testedMedia.CanReadPAC == true)
mediaOneValue.Add("Device can read the PAC from this medium");
if(testedMedia.CanReadPFI == true)
mediaOneValue.Add("Device can read the Physical Format Information from this medium");
if(testedMedia.CanReadPMA == true)
mediaOneValue.Add("Device can read the Power Management Area from this medium");
if(testedMedia.CanReadPQSubchannel == true)
mediaOneValue.Add("Device can read the P to Q subchannels from this medium");
if(testedMedia.CanReadPQSubchannelWithC2 == true)
mediaOneValue.
Add("Device can read the P to Q subchannels from this medium reporting the C2 pointers");
if(testedMedia.CanReadPRI == true)
mediaOneValue.Add("Device can read the Pre-Recorded Information from this medium");
if(testedMedia.CanReadRWSubchannel == true)
mediaOneValue.Add("Device can read the R to W subchannels from this medium");
if(testedMedia.CanReadRWSubchannelWithC2 == true)
mediaOneValue.
Add("Device can read the R to W subchannels from this medium reporting the C2 pointers");
if(testedMedia.CanReadRecordablePFI == true)
mediaOneValue.Add("Device can read the Physical Format Information from Lead-In from this medium");
if(testedMedia.CanReadSpareAreaInformation == true)
mediaOneValue.Add("Device can read the Spare Area Information from this medium");
if(testedMedia.CanReadTOC == true)
mediaOneValue.Add("Device can read the Table of Contents from this medium");
if(testedMedia.CanReadingIntersessionLeadIn == true)
mediaOneValue.Add("Device can read Lead-In between sessions");
if(testedMedia.CanReadingIntersessionLeadOut == true)
mediaOneValue.Add("Device can read Lead-Out between sessions");
if(testedMedia.CanReadCdScrambled == true)
mediaOneValue.Add("Device can read scrambled sectors using standard READ CD command");
if(testedMedia.CanReadF1_06 == true)
mediaOneValue.Add("Device can read from cache using F1h command with subcommand 06h");
if(testedMedia.CanReadF1_06LeadOut == true)
mediaOneValue.Add("Device can read Lead-Out from cache using F1h command with subcommand 06h");
mediaOneValue.Add("");
if(testedMedia.MediumType != null)
mediaOneValue.Add($"Medium type code: {testedMedia.MediumType:X2}h");
}
else if(testedMedia.MediumType != null)
{
mediaOneValue.Add($"<i>Information for medium type {testedMedia.MediumType:X2}h</i>");
}
else
{
mediaOneValue.Add("<i>Information for unknown medium type</i>");
}
mediaOneValue.Add(testedMedia.MediaIsRecognized ? "Drive recognizes this medium."
: "Drive does not recognize this medium.");
if(!string.IsNullOrWhiteSpace(testedMedia.Manufacturer))
mediaOneValue.Add($"Medium manufactured by: {testedMedia.Manufacturer}");
if(!string.IsNullOrWhiteSpace(testedMedia.Model))
mediaOneValue.Add($"Medium model: {testedMedia.Model}");
if(testedMedia.Density != null)
mediaOneValue.Add($"Density code: {testedMedia.Density:X2}h");
if(testedMedia.BlockSize != null)
mediaOneValue.Add($"Logical sector size: {testedMedia.BlockSize} bytes");
if(testedMedia.PhysicalBlockSize != null)
mediaOneValue.Add($"Physical sector size: {testedMedia.PhysicalBlockSize} bytes");
if(testedMedia.LongBlockSize != null)
mediaOneValue.Add($"READ LONG sector size: {testedMedia.LongBlockSize} bytes");
if(testedMedia.Blocks != null &&
testedMedia.BlockSize != null)
{
mediaOneValue.Add($"Medium has {testedMedia.Blocks} blocks of {testedMedia.BlockSize} bytes each");
if(testedMedia.Blocks * testedMedia.BlockSize / 1024 / 1024 > 1000000)
mediaOneValue.
Add($"Medium size: {testedMedia.Blocks * testedMedia.BlockSize} bytes, {testedMedia.Blocks * testedMedia.BlockSize / 1000 / 1000 / 1000 / 1000} Tb, {(double)(testedMedia.Blocks * testedMedia.BlockSize) / 1024 / 1024 / 1024 / 1024:F2} TiB");
else if(testedMedia.Blocks * testedMedia.BlockSize / 1024 / 1024 > 1000)
mediaOneValue.
Add($"Medium size: {testedMedia.Blocks * testedMedia.BlockSize} bytes, {testedMedia.Blocks * testedMedia.BlockSize / 1000 / 1000 / 1000} Gb, {(double)(testedMedia.Blocks * testedMedia.BlockSize) / 1024 / 1024 / 1024:F2} GiB");
else
mediaOneValue.
Add($"Medium size: {testedMedia.Blocks * testedMedia.BlockSize} bytes, {testedMedia.Blocks * testedMedia.BlockSize / 1000 / 1000} Mb, {(double)(testedMedia.Blocks * testedMedia.BlockSize) / 1024 / 1024:F2} MiB");
}
if(testedMedia.CHS != null &&
testedMedia.CurrentCHS != null)
{
int currentSectors = testedMedia.CurrentCHS.Cylinders * testedMedia.CurrentCHS.Heads *
testedMedia.CurrentCHS.Sectors;
mediaOneValue.
Add($"Cylinders: {testedMedia.CHS.Cylinders} max., {testedMedia.CurrentCHS.Cylinders} current");
mediaOneValue.Add($"Heads: {testedMedia.CHS.Heads} max., {testedMedia.CurrentCHS.Heads} current");
mediaOneValue.
Add($"Sectors per track: {testedMedia.CHS.Sectors} max., {testedMedia.CurrentCHS.Sectors} current");
mediaOneValue.
Add($"Sectors addressable in CHS mode: {testedMedia.CHS.Cylinders * testedMedia.CHS.Heads * testedMedia.CHS.Sectors} max., {currentSectors} current");
mediaOneValue.
Add($"Medium size in CHS mode: {(ulong)currentSectors * testedMedia.BlockSize} bytes, {(ulong)currentSectors * testedMedia.BlockSize / 1000 / 1000} Mb, {(double)((ulong)currentSectors * testedMedia.BlockSize) / 1024 / 1024:F2} MiB");
}
else if(testedMedia.CHS != null)
{
int currentSectors = testedMedia.CHS.Cylinders * testedMedia.CHS.Heads * testedMedia.CHS.Sectors;
mediaOneValue.Add($"Cylinders: {testedMedia.CHS.Cylinders}");
mediaOneValue.Add($"Heads: {testedMedia.CHS.Heads}");
mediaOneValue.Add($"Sectors per track: {testedMedia.CHS.Sectors}");
mediaOneValue.Add($"Sectors addressable in CHS mode: {currentSectors}");
mediaOneValue.
Add($"Medium size in CHS mode: {(ulong)currentSectors * testedMedia.BlockSize} bytes, {(ulong)currentSectors * testedMedia.BlockSize / 1000 / 1000} Mb, {(double)((ulong)currentSectors * testedMedia.BlockSize) / 1024 / 1024:F2} MiB");
}
if(testedMedia.LBASectors != null)
{
mediaOneValue.Add($"Sectors addressable in sectors in 28-bit LBA mode: {testedMedia.LBASectors}");
if((ulong)testedMedia.LBASectors * testedMedia.BlockSize / 1024 / 1024 > 1000000)
mediaOneValue.
Add($"Medium size in 28-bit LBA mode: {(ulong)testedMedia.LBASectors * testedMedia.BlockSize} bytes, {(ulong)testedMedia.LBASectors * testedMedia.BlockSize / 1000 / 1000 / 1000 / 1000} Tb, {(double)((ulong)testedMedia.LBASectors * testedMedia.BlockSize) / 1024 / 1024 / 1024 / 1024:F2} TiB");
else if((ulong)testedMedia.LBASectors * testedMedia.BlockSize / 1024 / 1024 > 1000)
mediaOneValue.
Add($"Medium size in 28-bit LBA mode: {(ulong)testedMedia.LBASectors * testedMedia.BlockSize} bytes, {(ulong)testedMedia.LBASectors * testedMedia.BlockSize / 1000 / 1000 / 1000} Gb, {(double)((ulong)testedMedia.LBASectors * testedMedia.BlockSize) / 1024 / 1024 / 1024:F2} GiB");
else
mediaOneValue.
Add($"Medium size in 28-bit LBA mode: {(ulong)testedMedia.LBASectors * testedMedia.BlockSize} bytes, {(ulong)testedMedia.LBASectors * testedMedia.BlockSize / 1000 / 1000} Mb, {(double)((ulong)testedMedia.LBASectors * testedMedia.BlockSize) / 1024 / 1024:F2} MiB");
}
if(testedMedia.LBA48Sectors != null)
{
mediaOneValue.Add($"Sectors addressable in sectors in 48-bit LBA mode: {testedMedia.LBA48Sectors}");
if(testedMedia.LBA48Sectors * testedMedia.BlockSize / 1024 / 1024 > 1000000)
mediaOneValue.
Add($"Medium size in 48-bit LBA mode: {testedMedia.LBA48Sectors * testedMedia.BlockSize} bytes, {testedMedia.LBA48Sectors * testedMedia.BlockSize / 1000 / 1000 / 1000 / 1000} Tb, {(double)(testedMedia.LBA48Sectors * testedMedia.BlockSize) / 1024 / 1024 / 1024 / 1024:F2} TiB");
else if(testedMedia.LBA48Sectors * testedMedia.BlockSize / 1024 / 1024 > 1000)
mediaOneValue.
Add($"Medium size in 48-bit LBA mode: {testedMedia.LBA48Sectors * testedMedia.BlockSize} bytes, {testedMedia.LBA48Sectors * testedMedia.BlockSize / 1000 / 1000 / 1000} Gb, {(double)(testedMedia.LBA48Sectors * testedMedia.BlockSize) / 1024 / 1024 / 1024:F2} GiB");
else
mediaOneValue.
Add($"Medium size in 48-bit LBA mode: {testedMedia.LBA48Sectors * testedMedia.BlockSize} bytes, {testedMedia.LBA48Sectors * testedMedia.BlockSize / 1000 / 1000} Mb, {(double)(testedMedia.LBA48Sectors * testedMedia.BlockSize) / 1024 / 1024:F2} MiB");
}
if(testedMedia.NominalRotationRate != null &&
testedMedia.NominalRotationRate != 0x0000 &&
testedMedia.NominalRotationRate != 0xFFFF)
mediaOneValue.Add(testedMedia.NominalRotationRate == 0x0001 ? "Medium does not rotate."
: $"Medium rotates at {testedMedia.NominalRotationRate} rpm");
if(testedMedia.BlockSize != null &&
testedMedia.PhysicalBlockSize != null &&
testedMedia.BlockSize.Value != testedMedia.PhysicalBlockSize.Value &&
(testedMedia.LogicalAlignment & 0x8000) == 0x0000 &&
(testedMedia.LogicalAlignment & 0x4000) == 0x4000)
mediaOneValue.
Add($"Logical sector starts at offset {testedMedia.LogicalAlignment & 0x3FFF} from physical sector");
if(testedMedia.SupportsReadSectors == true)
mediaOneValue.Add("Device can use the READ SECTOR(S) command in CHS mode with this medium");
if(testedMedia.SupportsReadRetry == true)
mediaOneValue.Add("Device can use the READ SECTOR(S) RETRY command in CHS mode with this medium");
if(testedMedia.SupportsReadDma == true)
mediaOneValue.Add("Device can use the READ DMA command in CHS mode with this medium");
if(testedMedia.SupportsReadDmaRetry == true)
mediaOneValue.Add("Device can use the READ DMA RETRY command in CHS mode with this medium");
if(testedMedia.SupportsReadLong == true)
mediaOneValue.Add("Device can use the READ LONG command in CHS mode with this medium");
if(testedMedia.SupportsReadLongRetry == true)
mediaOneValue.Add("Device can use the READ LONG RETRY command in CHS mode with this medium");
if(testedMedia.SupportsReadLba == true)
mediaOneValue.Add("Device can use the READ SECTOR(S) command in 28-bit LBA mode with this medium");
if(testedMedia.SupportsReadRetryLba == true)
mediaOneValue.
Add("Device can use the READ SECTOR(S) RETRY command in 28-bit LBA mode with this medium");
if(testedMedia.SupportsReadDmaLba == true)
mediaOneValue.Add("Device can use the READ DMA command in 28-bit LBA mode with this medium");
if(testedMedia.SupportsReadDmaRetryLba == true)
mediaOneValue.Add("Device can use the READ DMA RETRY command in 28-bit LBA mode with this medium");
if(testedMedia.SupportsReadLongLba == true)
mediaOneValue.Add("Device can use the READ LONG command in 28-bit LBA mode with this medium");
if(testedMedia.SupportsReadLongRetryLba == true)
mediaOneValue.Add("Device can use the READ LONG RETRY command in 28-bit LBA mode with this medium");
if(testedMedia.SupportsReadLba48 == true)
mediaOneValue.Add("Device can use the READ SECTOR(S) command in 48-bit LBA mode with this medium");
if(testedMedia.SupportsReadDmaLba48 == true)
mediaOneValue.Add("Device can use the READ DMA command in 48-bit LBA mode with this medium");
if(testedMedia.SupportsSeek == true)
mediaOneValue.Add("Device can use the SEEK command in CHS mode with this medium");
if(testedMedia.SupportsSeekLba == true)
mediaOneValue.Add("Device can use the SEEK command in 28-bit LBA mode with this medium");
if(testedMedia.SupportsReadCapacity == true)
mediaOneValue.Add("Device can use the READ CAPACITY (10) command with this medium");
if(testedMedia.SupportsReadCapacity16 == true)
mediaOneValue.Add("Device can use the READ CAPACITY (16) command with this medium");
if(testedMedia.SupportsRead6 == true)
mediaOneValue.Add("Device can use the READ (6) command with this medium");
if(testedMedia.SupportsRead10 == true)
mediaOneValue.Add("Device can use the READ (10) command with this medium");
if(testedMedia.SupportsRead12 == true)
mediaOneValue.Add("Device can use the READ (12) command with this medium");
if(testedMedia.SupportsRead16 == true)
mediaOneValue.Add("Device can use the READ (16) command with this medium");
if(testedMedia.SupportsReadLong == true)
mediaOneValue.Add("Device can use the READ LONG (10) command with this medium");
if(testedMedia.SupportsReadLong16 == true)
mediaOneValue.Add("Device can use the READ LONG (16) command with this medium");
if(testedMedia.SupportsReadCd == true)
mediaOneValue.Add("Device can use the READ CD command with LBA addressing with this medium");
if(testedMedia.SupportsReadCdMsf == true)
mediaOneValue.Add("Device can use the READ CD command with MM:SS:FF addressing with this medium");
if(testedMedia.SupportsReadCdRaw == true)
mediaOneValue.
Add("Device can use the READ CD command with LBA addressing with this medium to read raw sector");
if(testedMedia.SupportsReadCdMsfRaw == true)
mediaOneValue.
Add("Device can use the READ CD command with MM:SS:FF addressing with this medium read raw sector");
if(testedMedia.SupportsHLDTSTReadRawDVD == true)
mediaOneValue.Add("Device can use the HL-DT-ST vendor READ DVD (RAW) command with this medium");
if(testedMedia.SupportsNECReadCDDA == true)
mediaOneValue.Add("Device can use the NEC vendor READ CD-DA command with this medium");
if(testedMedia.SupportsPioneerReadCDDA == true)
mediaOneValue.Add("Device can use the PIONEER vendor READ CD-DA command with this medium");
if(testedMedia.SupportsPioneerReadCDDAMSF == true)
mediaOneValue.Add("Device can use the PIONEER vendor READ CD-DA MSF command with this medium");
if(testedMedia.SupportsPlextorReadCDDA == true)
mediaOneValue.Add("Device can use the PLEXTOR vendor READ CD-DA command with this medium");
if(testedMedia.SupportsPlextorReadRawDVD == true)
mediaOneValue.Add("Device can use the PLEXTOR vendor READ DVD (RAW) command with this medium");
if(testedMedia.CanReadAACS == true)
mediaOneValue.Add("Device can read the Advanced Access Content System from this medium");
if(testedMedia.CanReadADIP == true)
mediaOneValue.Add("Device can read the DVD ADress-In-Pregroove from this medium");
if(testedMedia.CanReadATIP == true)
mediaOneValue.Add("Device can read the CD Absolute-Time-In-Pregroove from this medium");
if(testedMedia.CanReadBCA == true)
mediaOneValue.Add("Device can read the Burst Cutting Area from this medium");
if(testedMedia.CanReadC2Pointers == true)
mediaOneValue.Add("Device can report the C2 pointers when reading from this medium");
if(testedMedia.CanReadCMI == true)
mediaOneValue.Add("Device can read the Copyright Management Information from this medium");
if(testedMedia.CanReadCorrectedSubchannel == true)
mediaOneValue.Add("Device can correct subchannels when reading from this medium");
if(testedMedia.CanReadCorrectedSubchannelWithC2 == true)
mediaOneValue.
Add("Device can correct subchannels and report the C2 pointers when reading from this medium");
if(testedMedia.CanReadDCB == true)
mediaOneValue.Add("Device can read the Disc Control Blocks from this medium");
if(testedMedia.CanReadDDS == true)
mediaOneValue.Add("Device can read the Disc Definition Structure from this medium");
if(testedMedia.CanReadDMI == true)
mediaOneValue.Add("Device can read the Disc Manufacturer Information from this medium");
if(testedMedia.CanReadDiscInformation == true)
mediaOneValue.Add("Device can read the Disc Information from this medium");
if(testedMedia.CanReadFullTOC == true)
mediaOneValue.Add("Device can read the Table of Contents from this medium, without processing it");
if(testedMedia.CanReadHDCMI == true)
mediaOneValue.Add("Device can read the HD DVD Copyright Management Information from this medium");
if(testedMedia.CanReadLayerCapacity == true)
mediaOneValue.Add("Device can read the layer capacity from this medium");
if(testedMedia.CanReadFirstTrackPreGap == true)
mediaOneValue.Add("Device can read the first track's pregap data");
if(testedMedia.CanReadLeadIn == true)
mediaOneValue.Add("Device can read the Lead-In from this medium");
if(testedMedia.CanReadLeadOut == true)
mediaOneValue.Add("Device can read the Lead-Out from this medium");
if(testedMedia.CanReadMediaID == true)
mediaOneValue.Add("Device can read the Media ID from this medium");
if(testedMedia.CanReadMediaSerial == true)
mediaOneValue.Add("Device can read the Media Serial Number from this medium");
if(testedMedia.CanReadPAC == true)
mediaOneValue.Add("Device can read the PAC from this medium");
if(testedMedia.CanReadPFI == true)
mediaOneValue.Add("Device can read the Physical Format Information from this medium");
if(testedMedia.CanReadPMA == true)
mediaOneValue.Add("Device can read the Power Management Area from this medium");
if(testedMedia.CanReadPQSubchannel == true)
mediaOneValue.Add("Device can read the P to Q subchannels from this medium");
if(testedMedia.CanReadPQSubchannelWithC2 == true)
mediaOneValue.
Add("Device can read the P to Q subchannels from this medium reporting the C2 pointers");
if(testedMedia.CanReadPRI == true)
mediaOneValue.Add("Device can read the Pre-Recorded Information from this medium");
if(testedMedia.CanReadRWSubchannel == true)
mediaOneValue.Add("Device can read the R to W subchannels from this medium");
if(testedMedia.CanReadRWSubchannelWithC2 == true)
mediaOneValue.
Add("Device can read the R to W subchannels from this medium reporting the C2 pointers");
if(testedMedia.CanReadRecordablePFI == true)
mediaOneValue.Add("Device can read the Physical Format Information from Lead-In from this medium");
if(testedMedia.CanReadSpareAreaInformation == true)
mediaOneValue.Add("Device can read the Spare Area Information from this medium");
if(testedMedia.CanReadTOC == true)
mediaOneValue.Add("Device can read the Table of Contents from this medium");
if(testedMedia.CanReadingIntersessionLeadIn == true)
mediaOneValue.Add("Device can read Lead-In between sessions");
if(testedMedia.CanReadingIntersessionLeadOut == true)
mediaOneValue.Add("Device can read Lead-Out between sessions");
if(testedMedia.CanReadCdScrambled == true)
mediaOneValue.Add("Device can read scrambled sectors using standard READ CD command");
if(testedMedia.CanReadF1_06 == true)
mediaOneValue.Add("Device can read from cache using F1h command with subcommand 06h");
if(testedMedia.CanReadF1_06LeadOut == true)
mediaOneValue.Add("Device can read Lead-Out from cache using F1h command with subcommand 06h");
mediaOneValue.Add("");
}
}
}

View File

@@ -1,10 +1,9 @@
using System.ComponentModel.DataAnnotations;
namespace Aaru.Server.Models
namespace Aaru.Server.Models;
public abstract class BaseModel<T>
{
public abstract class BaseModel<T>
{
[Key]
public T Id { get; set; }
}
[Key]
public T Id { get; set; }
}

View File

@@ -30,12 +30,11 @@
// Copyright © 2011-2021 Natalia Portillo
// ****************************************************************************/
namespace Aaru.Server.Models
namespace Aaru.Server.Models;
public abstract class BaseOperatingSystem : BaseModel<int>
{
public abstract class BaseOperatingSystem : BaseModel<int>
{
public string Name { get; set; }
public string Version { get; set; }
public long Count { get; set; }
}
public string Name { get; set; }
public string Version { get; set; }
public long Count { get; set; }
}

View File

@@ -35,37 +35,36 @@ using System.Collections.Generic;
using System.ComponentModel;
using Aaru.CommonTypes.Metadata;
namespace Aaru.Server.Models
namespace Aaru.Server.Models;
public class CompactDiscOffset : CdOffset
{
public class CompactDiscOffset : CdOffset
public CompactDiscOffset() {}
public CompactDiscOffset(string manufacturer, string model, short offset, int submissions, float agreement)
{
public CompactDiscOffset() {}
public CompactDiscOffset(string manufacturer, string model, short offset, int submissions, float agreement)
{
Manufacturer = manufacturer;
Model = model;
Offset = offset;
Submissions = submissions;
Agreement = agreement;
AddedWhen = ModifiedWhen = DateTime.UtcNow;
}
public CompactDiscOffset(CdOffset offset)
{
Manufacturer = offset.Manufacturer;
Model = offset.Model;
Offset = offset.Offset;
Submissions = offset.Submissions;
Agreement = offset.Agreement;
AddedWhen = ModifiedWhen = DateTime.UtcNow;
}
public int Id { get; set; }
[DisplayName("Added date")]
public DateTime AddedWhen { get; set; }
[DisplayName("Modification date")]
public DateTime ModifiedWhen { get; set; }
public virtual ICollection<Device> Devices { get; set; }
Manufacturer = manufacturer;
Model = model;
Offset = offset;
Submissions = submissions;
Agreement = agreement;
AddedWhen = ModifiedWhen = DateTime.UtcNow;
}
public CompactDiscOffset(CdOffset offset)
{
Manufacturer = offset.Manufacturer;
Model = offset.Model;
Offset = offset.Offset;
Submissions = offset.Submissions;
Agreement = offset.Agreement;
AddedWhen = ModifiedWhen = DateTime.UtcNow;
}
public int Id { get; set; }
[DisplayName("Added date")]
public DateTime AddedWhen { get; set; }
[DisplayName("Modification date")]
public DateTime ModifiedWhen { get; set; }
public virtual ICollection<Device> Devices { get; set; }
}

View File

@@ -1,17 +1,16 @@
using System.Collections.Generic;
namespace Aaru.Server.Models
{
public class ChsModel
{
public ushort Cylinders { get; set; }
public ushort Heads { get; set; }
public ushort Sectors { get; set; }
}
namespace Aaru.Server.Models;
public class ChsModelForView
{
public List<ChsModel> List { get; set; }
public string Json { get; set; }
}
public class ChsModel
{
public ushort Cylinders { get; set; }
public ushort Heads { get; set; }
public ushort Sectors { get; set; }
}
public class ChsModelForView
{
public List<ChsModel> List { get; set; }
public string Json { get; set; }
}

View File

@@ -30,7 +30,6 @@
// Copyright © 2011-2021 Natalia Portillo
// ****************************************************************************/
namespace Aaru.Server.Models
{
public class Command : NameCountModel<int> {}
}
namespace Aaru.Server.Models;
public class Command : NameCountModel<int> {}

View File

@@ -1,16 +1,15 @@
using System.Collections.Generic;
namespace Aaru.Server.Models
namespace Aaru.Server.Models;
public class CompareModel
{
public class CompareModel
{
public int LeftId { get; set; }
public int RightId { get; set; }
public List<string> ValueNames { get; set; }
public List<string> LeftValues { get; set; }
public List<string> RightValues { get; set; }
public bool HasError { get; set; }
public string ErrorMessage { get; set; }
public bool AreEqual { get; set; }
}
public int LeftId { get; set; }
public int RightId { get; set; }
public List<string> ValueNames { get; set; }
public List<string> LeftValues { get; set; }
public List<string> RightValues { get; set; }
public bool HasError { get; set; }
public string ErrorMessage { get; set; }
public bool AreEqual { get; set; }
}

View File

@@ -37,235 +37,234 @@ using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
namespace Aaru.Server.Models
namespace Aaru.Server.Models;
public sealed class AaruServerContext : IdentityDbContext<IdentityUser>
{
public sealed class AaruServerContext : IdentityDbContext<IdentityUser>
public AaruServerContext() {}
public AaruServerContext(DbContextOptions<AaruServerContext> options) : base(options) {}
public DbSet<Device> Devices { get; set; }
public DbSet<UploadedReport> Reports { get; set; }
public DbSet<Command> Commands { get; set; }
public DbSet<DeviceStat> DeviceStats { get; set; }
public DbSet<Filesystem> Filesystems { get; set; }
public DbSet<Filter> Filters { get; set; }
public DbSet<Media> Medias { get; set; }
public DbSet<MediaFormat> MediaFormats { get; set; }
public DbSet<OperatingSystem> OperatingSystems { get; set; }
public DbSet<Partition> Partitions { get; set; }
public DbSet<Version> Versions { get; set; }
public DbSet<UsbVendor> UsbVendors { get; set; }
public DbSet<UsbProduct> UsbProducts { get; set; }
public DbSet<CompactDiscOffset> CdOffsets { get; set; }
public DbSet<Ata> Ata { get; set; }
public DbSet<BlockDescriptor> BlockDescriptor { get; set; }
public DbSet<Chs> Chs { get; set; }
public DbSet<FireWire> FireWire { get; set; }
public DbSet<Mmc> Mmc { get; set; }
public DbSet<MmcSd> MmcSd { get; set; }
public DbSet<MmcFeatures> MmcFeatures { get; set; }
public DbSet<Pcmcia> Pcmcia { get; set; }
public DbSet<Scsi> Scsi { get; set; }
public DbSet<ScsiMode> ScsiMode { get; set; }
public DbSet<ScsiPage> ScsiPage { get; set; }
public DbSet<Ssc> Ssc { get; set; }
public DbSet<SupportedDensity> SupportedDensity { get; set; }
public DbSet<TestedMedia> TestedMedia { get; set; }
public DbSet<TestedSequentialMedia> TestedSequentialMedia { get; set; }
public DbSet<Usb> Usb { get; set; }
public DbSet<RemoteApplication> RemoteApplications { get; set; }
public DbSet<RemoteArchitecture> RemoteArchitectures { get; set; }
public DbSet<RemoteOperatingSystem> RemoteOperatingSystems { get; set; }
public DbSet<GdRomSwapDiscCapabilities> GdRomSwapDiscCapabilities { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
public AaruServerContext() {}
if(optionsBuilder.IsConfigured)
return;
public AaruServerContext(DbContextOptions<AaruServerContext> options) : base(options) {}
IConfigurationBuilder builder = new ConfigurationBuilder().AddJsonFile("appsettings.json");
IConfigurationRoot configuration = builder.Build();
public DbSet<Device> Devices { get; set; }
public DbSet<UploadedReport> Reports { get; set; }
public DbSet<Command> Commands { get; set; }
public DbSet<DeviceStat> DeviceStats { get; set; }
public DbSet<Filesystem> Filesystems { get; set; }
public DbSet<Filter> Filters { get; set; }
public DbSet<Media> Medias { get; set; }
public DbSet<MediaFormat> MediaFormats { get; set; }
public DbSet<OperatingSystem> OperatingSystems { get; set; }
public DbSet<Partition> Partitions { get; set; }
public DbSet<Version> Versions { get; set; }
public DbSet<UsbVendor> UsbVendors { get; set; }
public DbSet<UsbProduct> UsbProducts { get; set; }
public DbSet<CompactDiscOffset> CdOffsets { get; set; }
public DbSet<Ata> Ata { get; set; }
public DbSet<BlockDescriptor> BlockDescriptor { get; set; }
public DbSet<Chs> Chs { get; set; }
public DbSet<FireWire> FireWire { get; set; }
public DbSet<Mmc> Mmc { get; set; }
public DbSet<MmcSd> MmcSd { get; set; }
public DbSet<MmcFeatures> MmcFeatures { get; set; }
public DbSet<Pcmcia> Pcmcia { get; set; }
public DbSet<Scsi> Scsi { get; set; }
public DbSet<ScsiMode> ScsiMode { get; set; }
public DbSet<ScsiPage> ScsiPage { get; set; }
public DbSet<Ssc> Ssc { get; set; }
public DbSet<SupportedDensity> SupportedDensity { get; set; }
public DbSet<TestedMedia> TestedMedia { get; set; }
public DbSet<TestedSequentialMedia> TestedSequentialMedia { get; set; }
public DbSet<Usb> Usb { get; set; }
public DbSet<RemoteApplication> RemoteApplications { get; set; }
public DbSet<RemoteArchitecture> RemoteArchitectures { get; set; }
public DbSet<RemoteOperatingSystem> RemoteOperatingSystems { get; set; }
public DbSet<GdRomSwapDiscCapabilities> GdRomSwapDiscCapabilities { get; set; }
optionsBuilder.
UseMySql(configuration.GetConnectionString("DefaultConnection"),
new MariaDbServerVersion(new System.Version(10, 4, 0))).UseLazyLoadingProxies();
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity("Aaru.CommonTypes.Metadata.Ata",
b => b.HasOne("Aaru.CommonTypes.Metadata.TestedMedia", "ReadCapabilities").WithMany().
HasForeignKey("ReadCapabilitiesId").OnDelete(DeleteBehavior.SetNull));
modelBuilder.Entity("Aaru.CommonTypes.Metadata.BlockDescriptor",
b => b.HasOne("Aaru.CommonTypes.Metadata.ScsiMode", null).WithMany("BlockDescriptors").
HasForeignKey("ScsiModeId").OnDelete(DeleteBehavior.Cascade));
modelBuilder.Entity("Aaru.CommonTypes.Metadata.DensityCode",
b => b.HasOne("Aaru.CommonTypes.Metadata.SscSupportedMedia", null).
WithMany("DensityCodes").HasForeignKey("SscSupportedMediaId").
OnDelete(DeleteBehavior.Cascade));
modelBuilder.Entity("Aaru.CommonTypes.Metadata.Mmc",
b => b.HasOne("Aaru.CommonTypes.Metadata.MmcFeatures", "Features").WithMany().
HasForeignKey("FeaturesId").OnDelete(DeleteBehavior.SetNull));
modelBuilder.Entity("Aaru.CommonTypes.Metadata.Scsi", b =>
{
if(optionsBuilder.IsConfigured)
return;
b.HasOne("Aaru.CommonTypes.Metadata.ScsiMode", "ModeSense").WithMany().HasForeignKey("ModeSenseId").
OnDelete(DeleteBehavior.SetNull);
IConfigurationBuilder builder = new ConfigurationBuilder().AddJsonFile("appsettings.json");
IConfigurationRoot configuration = builder.Build();
b.HasOne("Aaru.CommonTypes.Metadata.Mmc", "MultiMediaDevice").WithMany().
HasForeignKey("MultiMediaDeviceId").OnDelete(DeleteBehavior.SetNull);
optionsBuilder.
UseMySql(configuration.GetConnectionString("DefaultConnection"),
new MariaDbServerVersion(new System.Version(10, 4, 0))).UseLazyLoadingProxies();
}
b.HasOne("Aaru.CommonTypes.Metadata.TestedMedia", "ReadCapabilities").WithMany().
HasForeignKey("ReadCapabilitiesId").OnDelete(DeleteBehavior.SetNull);
protected override void OnModelCreating(ModelBuilder modelBuilder)
b.HasOne("Aaru.CommonTypes.Metadata.Ssc", "SequentialDevice").WithMany().
HasForeignKey("SequentialDeviceId").OnDelete(DeleteBehavior.SetNull);
});
modelBuilder.Entity("Aaru.CommonTypes.Metadata.ScsiPage", b =>
{
base.OnModelCreating(modelBuilder);
b.HasOne("Aaru.CommonTypes.Metadata.Scsi", null).WithMany("EVPDPages").HasForeignKey("ScsiId").
OnDelete(DeleteBehavior.SetNull);
modelBuilder.Entity("Aaru.CommonTypes.Metadata.Ata",
b => b.HasOne("Aaru.CommonTypes.Metadata.TestedMedia", "ReadCapabilities").WithMany().
HasForeignKey("ReadCapabilitiesId").OnDelete(DeleteBehavior.SetNull));
b.HasOne("Aaru.CommonTypes.Metadata.ScsiMode", null).WithMany("ModePages").HasForeignKey("ScsiModeId").
OnDelete(DeleteBehavior.SetNull);
});
modelBuilder.Entity("Aaru.CommonTypes.Metadata.BlockDescriptor",
b => b.HasOne("Aaru.CommonTypes.Metadata.ScsiMode", null).WithMany("BlockDescriptors").
HasForeignKey("ScsiModeId").OnDelete(DeleteBehavior.Cascade));
modelBuilder.Entity("Aaru.CommonTypes.Metadata.DensityCode",
b => b.HasOne("Aaru.CommonTypes.Metadata.SscSupportedMedia", null).
WithMany("DensityCodes").HasForeignKey("SscSupportedMediaId").
OnDelete(DeleteBehavior.Cascade));
modelBuilder.Entity("Aaru.CommonTypes.Metadata.Mmc",
b => b.HasOne("Aaru.CommonTypes.Metadata.MmcFeatures", "Features").WithMany().
HasForeignKey("FeaturesId").OnDelete(DeleteBehavior.SetNull));
modelBuilder.Entity("Aaru.CommonTypes.Metadata.Scsi", b =>
{
b.HasOne("Aaru.CommonTypes.Metadata.ScsiMode", "ModeSense").WithMany().HasForeignKey("ModeSenseId").
OnDelete(DeleteBehavior.SetNull);
b.HasOne("Aaru.CommonTypes.Metadata.Mmc", "MultiMediaDevice").WithMany().
HasForeignKey("MultiMediaDeviceId").OnDelete(DeleteBehavior.SetNull);
b.HasOne("Aaru.CommonTypes.Metadata.TestedMedia", "ReadCapabilities").WithMany().
HasForeignKey("ReadCapabilitiesId").OnDelete(DeleteBehavior.SetNull);
b.HasOne("Aaru.CommonTypes.Metadata.Ssc", "SequentialDevice").WithMany().
HasForeignKey("SequentialDeviceId").OnDelete(DeleteBehavior.SetNull);
});
modelBuilder.Entity("Aaru.CommonTypes.Metadata.ScsiPage", b =>
{
b.HasOne("Aaru.CommonTypes.Metadata.Scsi", null).WithMany("EVPDPages").HasForeignKey("ScsiId").
OnDelete(DeleteBehavior.SetNull);
b.HasOne("Aaru.CommonTypes.Metadata.ScsiMode", null).WithMany("ModePages").HasForeignKey("ScsiModeId").
OnDelete(DeleteBehavior.SetNull);
});
modelBuilder.Entity("Aaru.CommonTypes.Metadata.SscSupportedMedia", b =>
{
b.HasOne("Aaru.CommonTypes.Metadata.Ssc", null).WithMany("SupportedMediaTypes").HasForeignKey("SscId").
OnDelete(DeleteBehavior.SetNull);
b.HasOne("Aaru.CommonTypes.Metadata.TestedSequentialMedia", null).WithMany("SupportedMediaTypes").
HasForeignKey("TestedSequentialMediaId").OnDelete(DeleteBehavior.SetNull);
});
modelBuilder.Entity("Aaru.CommonTypes.Metadata.SupportedDensity", b =>
{
b.HasOne("Aaru.CommonTypes.Metadata.Ssc", null).WithMany("SupportedDensities").HasForeignKey("SscId").
OnDelete(DeleteBehavior.Cascade);
b.HasOne("Aaru.CommonTypes.Metadata.TestedSequentialMedia", null).WithMany("SupportedDensities").
HasForeignKey("TestedSequentialMediaId").OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Aaru.CommonTypes.Metadata.TestedMedia", b =>
{
b.HasOne("Aaru.CommonTypes.Metadata.Ata", null).WithMany("RemovableMedias").HasForeignKey("AtaId").
OnDelete(DeleteBehavior.SetNull);
b.HasOne("Aaru.CommonTypes.Metadata.Chs", "CHS").WithMany().HasForeignKey("CHSId").
OnDelete(DeleteBehavior.SetNull);
b.HasOne("Aaru.CommonTypes.Metadata.Chs", "CurrentCHS").WithMany().HasForeignKey("CurrentCHSId").
OnDelete(DeleteBehavior.SetNull);
b.HasOne("Aaru.CommonTypes.Metadata.Mmc", null).WithMany("TestedMedia").HasForeignKey("MmcId").
OnDelete(DeleteBehavior.Cascade);
b.HasOne("Aaru.CommonTypes.Metadata.Scsi", null).WithMany("RemovableMedias").HasForeignKey("ScsiId").
OnDelete(DeleteBehavior.SetNull);
});
modelBuilder.Entity("Aaru.CommonTypes.Metadata.TestedSequentialMedia",
b => b.HasOne("Aaru.CommonTypes.Metadata.Ssc", null).WithMany("TestedMedia").
HasForeignKey("SscId").OnDelete(DeleteBehavior.SetNull));
modelBuilder.Entity("Aaru.Server.Models.Device", b =>
{
b.HasOne("Aaru.CommonTypes.Metadata.Ata", "ATA").WithMany().HasForeignKey("ATAId").
OnDelete(DeleteBehavior.SetNull);
b.HasOne("Aaru.CommonTypes.Metadata.Ata", "ATAPI").WithMany().HasForeignKey("ATAPIId").
OnDelete(DeleteBehavior.SetNull);
b.HasOne("Aaru.Server.Models.CompactDiscOffset", "CdOffset").WithMany("Devices").
HasForeignKey("CdOffsetId").OnDelete(DeleteBehavior.SetNull);
b.HasOne("Aaru.CommonTypes.Metadata.FireWire", "FireWire").WithMany().HasForeignKey("FireWireId").
OnDelete(DeleteBehavior.SetNull);
b.HasOne("Aaru.CommonTypes.Metadata.MmcSd", "MultiMediaCard").WithMany().
HasForeignKey("MultiMediaCardId").OnDelete(DeleteBehavior.SetNull);
b.HasOne("Aaru.CommonTypes.Metadata.Pcmcia", "PCMCIA").WithMany().HasForeignKey("PCMCIAId").
OnDelete(DeleteBehavior.SetNull);
b.HasOne("Aaru.CommonTypes.Metadata.Scsi", "SCSI").WithMany().HasForeignKey("SCSIId").
OnDelete(DeleteBehavior.SetNull);
b.HasOne("Aaru.CommonTypes.Metadata.MmcSd", "SecureDigital").WithMany().
HasForeignKey("SecureDigitalId").OnDelete(DeleteBehavior.SetNull);
b.HasOne("Aaru.CommonTypes.Metadata.Usb", "USB").WithMany().HasForeignKey("USBId").
OnDelete(DeleteBehavior.SetNull);
});
modelBuilder.Entity("Aaru.Server.Models.DeviceStat",
b => b.HasOne("Aaru.Server.Models.Device", "Report").WithMany().
HasForeignKey("ReportId").OnDelete(DeleteBehavior.SetNull));
modelBuilder.Entity("Aaru.Server.Models.UploadedReport", b =>
{
b.HasOne("Aaru.CommonTypes.Metadata.Ata", "ATA").WithMany().HasForeignKey("ATAId").
OnDelete(DeleteBehavior.SetNull);
b.HasOne("Aaru.CommonTypes.Metadata.Ata", "ATAPI").WithMany().HasForeignKey("ATAPIId").
OnDelete(DeleteBehavior.SetNull);
b.HasOne("Aaru.CommonTypes.Metadata.FireWire", "FireWire").WithMany().HasForeignKey("FireWireId").
OnDelete(DeleteBehavior.SetNull);
b.HasOne("Aaru.CommonTypes.Metadata.MmcSd", "MultiMediaCard").WithMany().
HasForeignKey("MultiMediaCardId").OnDelete(DeleteBehavior.SetNull);
b.HasOne("Aaru.CommonTypes.Metadata.Pcmcia", "PCMCIA").WithMany().HasForeignKey("PCMCIAId").
OnDelete(DeleteBehavior.SetNull);
b.HasOne("Aaru.CommonTypes.Metadata.Scsi", "SCSI").WithMany().HasForeignKey("SCSIId").
OnDelete(DeleteBehavior.SetNull);
b.HasOne("Aaru.CommonTypes.Metadata.MmcSd", "SecureDigital").WithMany().
HasForeignKey("SecureDigitalId").OnDelete(DeleteBehavior.SetNull);
b.HasOne("Aaru.CommonTypes.Metadata.Usb", "USB").WithMany().HasForeignKey("USBId").
OnDelete(DeleteBehavior.SetNull);
});
modelBuilder.Entity<CompactDiscOffset>().HasIndex(b => b.ModifiedWhen);
modelBuilder.Entity<Device>().HasIndex(b => b.ModifiedWhen);
modelBuilder.Entity<UsbProduct>().HasIndex(b => b.ModifiedWhen);
modelBuilder.Entity<UsbProduct>().HasIndex(b => b.ProductId);
modelBuilder.Entity<UsbProduct>().HasIndex(b => b.VendorId);
modelBuilder.Entity<UsbVendor>().HasIndex(b => b.ModifiedWhen);
modelBuilder.Entity<UsbVendor>().HasIndex(b => b.VendorId).IsUnique();
}
internal static bool TableExists(string tableName)
modelBuilder.Entity("Aaru.CommonTypes.Metadata.SscSupportedMedia", b =>
{
using var db = new AaruServerContext();
b.HasOne("Aaru.CommonTypes.Metadata.Ssc", null).WithMany("SupportedMediaTypes").HasForeignKey("SscId").
OnDelete(DeleteBehavior.SetNull);
DbConnection connection = db.Database.GetDbConnection();
connection.Open();
b.HasOne("Aaru.CommonTypes.Metadata.TestedSequentialMedia", null).WithMany("SupportedMediaTypes").
HasForeignKey("TestedSequentialMediaId").OnDelete(DeleteBehavior.SetNull);
});
DbCommand command = connection.CreateCommand();
modelBuilder.Entity("Aaru.CommonTypes.Metadata.SupportedDensity", b =>
{
b.HasOne("Aaru.CommonTypes.Metadata.Ssc", null).WithMany("SupportedDensities").HasForeignKey("SscId").
OnDelete(DeleteBehavior.Cascade);
command.CommandText =
$"SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME=\"{tableName}\"";
b.HasOne("Aaru.CommonTypes.Metadata.TestedSequentialMedia", null).WithMany("SupportedDensities").
HasForeignKey("TestedSequentialMediaId").OnDelete(DeleteBehavior.Cascade);
});
long result = (long)command.ExecuteScalar();
modelBuilder.Entity("Aaru.CommonTypes.Metadata.TestedMedia", b =>
{
b.HasOne("Aaru.CommonTypes.Metadata.Ata", null).WithMany("RemovableMedias").HasForeignKey("AtaId").
OnDelete(DeleteBehavior.SetNull);
return result != 0;
}
b.HasOne("Aaru.CommonTypes.Metadata.Chs", "CHS").WithMany().HasForeignKey("CHSId").
OnDelete(DeleteBehavior.SetNull);
b.HasOne("Aaru.CommonTypes.Metadata.Chs", "CurrentCHS").WithMany().HasForeignKey("CurrentCHSId").
OnDelete(DeleteBehavior.SetNull);
b.HasOne("Aaru.CommonTypes.Metadata.Mmc", null).WithMany("TestedMedia").HasForeignKey("MmcId").
OnDelete(DeleteBehavior.Cascade);
b.HasOne("Aaru.CommonTypes.Metadata.Scsi", null).WithMany("RemovableMedias").HasForeignKey("ScsiId").
OnDelete(DeleteBehavior.SetNull);
});
modelBuilder.Entity("Aaru.CommonTypes.Metadata.TestedSequentialMedia",
b => b.HasOne("Aaru.CommonTypes.Metadata.Ssc", null).WithMany("TestedMedia").
HasForeignKey("SscId").OnDelete(DeleteBehavior.SetNull));
modelBuilder.Entity("Aaru.Server.Models.Device", b =>
{
b.HasOne("Aaru.CommonTypes.Metadata.Ata", "ATA").WithMany().HasForeignKey("ATAId").
OnDelete(DeleteBehavior.SetNull);
b.HasOne("Aaru.CommonTypes.Metadata.Ata", "ATAPI").WithMany().HasForeignKey("ATAPIId").
OnDelete(DeleteBehavior.SetNull);
b.HasOne("Aaru.Server.Models.CompactDiscOffset", "CdOffset").WithMany("Devices").
HasForeignKey("CdOffsetId").OnDelete(DeleteBehavior.SetNull);
b.HasOne("Aaru.CommonTypes.Metadata.FireWire", "FireWire").WithMany().HasForeignKey("FireWireId").
OnDelete(DeleteBehavior.SetNull);
b.HasOne("Aaru.CommonTypes.Metadata.MmcSd", "MultiMediaCard").WithMany().
HasForeignKey("MultiMediaCardId").OnDelete(DeleteBehavior.SetNull);
b.HasOne("Aaru.CommonTypes.Metadata.Pcmcia", "PCMCIA").WithMany().HasForeignKey("PCMCIAId").
OnDelete(DeleteBehavior.SetNull);
b.HasOne("Aaru.CommonTypes.Metadata.Scsi", "SCSI").WithMany().HasForeignKey("SCSIId").
OnDelete(DeleteBehavior.SetNull);
b.HasOne("Aaru.CommonTypes.Metadata.MmcSd", "SecureDigital").WithMany().
HasForeignKey("SecureDigitalId").OnDelete(DeleteBehavior.SetNull);
b.HasOne("Aaru.CommonTypes.Metadata.Usb", "USB").WithMany().HasForeignKey("USBId").
OnDelete(DeleteBehavior.SetNull);
});
modelBuilder.Entity("Aaru.Server.Models.DeviceStat",
b => b.HasOne("Aaru.Server.Models.Device", "Report").WithMany().
HasForeignKey("ReportId").OnDelete(DeleteBehavior.SetNull));
modelBuilder.Entity("Aaru.Server.Models.UploadedReport", b =>
{
b.HasOne("Aaru.CommonTypes.Metadata.Ata", "ATA").WithMany().HasForeignKey("ATAId").
OnDelete(DeleteBehavior.SetNull);
b.HasOne("Aaru.CommonTypes.Metadata.Ata", "ATAPI").WithMany().HasForeignKey("ATAPIId").
OnDelete(DeleteBehavior.SetNull);
b.HasOne("Aaru.CommonTypes.Metadata.FireWire", "FireWire").WithMany().HasForeignKey("FireWireId").
OnDelete(DeleteBehavior.SetNull);
b.HasOne("Aaru.CommonTypes.Metadata.MmcSd", "MultiMediaCard").WithMany().
HasForeignKey("MultiMediaCardId").OnDelete(DeleteBehavior.SetNull);
b.HasOne("Aaru.CommonTypes.Metadata.Pcmcia", "PCMCIA").WithMany().HasForeignKey("PCMCIAId").
OnDelete(DeleteBehavior.SetNull);
b.HasOne("Aaru.CommonTypes.Metadata.Scsi", "SCSI").WithMany().HasForeignKey("SCSIId").
OnDelete(DeleteBehavior.SetNull);
b.HasOne("Aaru.CommonTypes.Metadata.MmcSd", "SecureDigital").WithMany().
HasForeignKey("SecureDigitalId").OnDelete(DeleteBehavior.SetNull);
b.HasOne("Aaru.CommonTypes.Metadata.Usb", "USB").WithMany().HasForeignKey("USBId").
OnDelete(DeleteBehavior.SetNull);
});
modelBuilder.Entity<CompactDiscOffset>().HasIndex(b => b.ModifiedWhen);
modelBuilder.Entity<Device>().HasIndex(b => b.ModifiedWhen);
modelBuilder.Entity<UsbProduct>().HasIndex(b => b.ModifiedWhen);
modelBuilder.Entity<UsbProduct>().HasIndex(b => b.ProductId);
modelBuilder.Entity<UsbProduct>().HasIndex(b => b.VendorId);
modelBuilder.Entity<UsbVendor>().HasIndex(b => b.ModifiedWhen);
modelBuilder.Entity<UsbVendor>().HasIndex(b => b.VendorId).IsUnique();
}
internal static bool TableExists(string tableName)
{
using var db = new AaruServerContext();
DbConnection connection = db.Database.GetDbConnection();
connection.Open();
DbCommand command = connection.CreateCommand();
command.CommandText =
$"SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME=\"{tableName}\"";
long result = (long)command.ExecuteScalar();
return result != 0;
}
}

View File

@@ -35,74 +35,73 @@ using System.ComponentModel;
using Aaru.CommonTypes.Enums;
using Aaru.CommonTypes.Metadata;
namespace Aaru.Server.Models
namespace Aaru.Server.Models;
public class Device : DeviceReportV2
{
public class Device : DeviceReportV2
public Device() => AddedWhen = DateTime.UtcNow;
public Device(DeviceReportV2 report)
{
public Device() => AddedWhen = DateTime.UtcNow;
public Device(DeviceReportV2 report)
{
ATA = report.ATA;
ATAPI = report.ATAPI;
CompactFlash = report.CompactFlash;
FireWire = report.FireWire;
AddedWhen = DateTime.UtcNow;
ModifiedWhen = DateTime.UtcNow;
MultiMediaCard = report.MultiMediaCard;
PCMCIA = report.PCMCIA;
SCSI = report.SCSI;
SecureDigital = report.SecureDigital;
USB = report.USB;
Manufacturer = report.Manufacturer;
Model = report.Model;
Revision = report.Revision;
Type = report.Type;
GdRomSwapDiscCapabilities = report.GdRomSwapDiscCapabilities;
}
public Device(int? ataId, int? atapiId, int? firewireId, int? multimediacardId, int? pcmciaId,
int? securedigitalId, int? scsiId, int? usbId, DateTime uploadedWhen, string manufacturer,
string model, string revision, bool compactFlash, DeviceType type,
int? gdRomSwapDiscCapabilitiesId)
{
ATAId = ataId;
ATAPIId = atapiId;
FireWireId = firewireId;
MultiMediaCardId = multimediacardId;
PCMCIAId = pcmciaId;
SecureDigitalId = securedigitalId;
SCSIId = scsiId;
USBId = usbId;
AddedWhen = uploadedWhen;
ModifiedWhen = DateTime.UtcNow;
Manufacturer = manufacturer;
Model = model;
Revision = revision;
CompactFlash = compactFlash;
Type = type;
GdRomSwapDiscCapabilitiesId = gdRomSwapDiscCapabilitiesId;
}
[DisplayName("Added when")]
public DateTime AddedWhen { get; set; }
[DisplayName("Modified when")]
public DateTime? ModifiedWhen { get; set; }
public virtual CompactDiscOffset CdOffset { get; set; }
[DefaultValue(0), DisplayName("Optimal no. of sectors to be read at once")]
public int OptimalMultipleSectorsRead { get; set; }
[DefaultValue(null), DisplayName("Can read GD-ROM using swap disc trick")]
public bool? CanReadGdRomUsingSwapDisc { get; set; }
public int? ATAId { get; set; }
public int? ATAPIId { get; set; }
public int? FireWireId { get; set; }
public int? MultiMediaCardId { get; set; }
public int? PCMCIAId { get; set; }
public int? SecureDigitalId { get; set; }
public int? SCSIId { get; set; }
public int? USBId { get; set; }
public int? GdRomSwapDiscCapabilitiesId { get; set; }
ATA = report.ATA;
ATAPI = report.ATAPI;
CompactFlash = report.CompactFlash;
FireWire = report.FireWire;
AddedWhen = DateTime.UtcNow;
ModifiedWhen = DateTime.UtcNow;
MultiMediaCard = report.MultiMediaCard;
PCMCIA = report.PCMCIA;
SCSI = report.SCSI;
SecureDigital = report.SecureDigital;
USB = report.USB;
Manufacturer = report.Manufacturer;
Model = report.Model;
Revision = report.Revision;
Type = report.Type;
GdRomSwapDiscCapabilities = report.GdRomSwapDiscCapabilities;
}
public Device(int? ataId, int? atapiId, int? firewireId, int? multimediacardId, int? pcmciaId,
int? securedigitalId, int? scsiId, int? usbId, DateTime uploadedWhen, string manufacturer,
string model, string revision, bool compactFlash, DeviceType type,
int? gdRomSwapDiscCapabilitiesId)
{
ATAId = ataId;
ATAPIId = atapiId;
FireWireId = firewireId;
MultiMediaCardId = multimediacardId;
PCMCIAId = pcmciaId;
SecureDigitalId = securedigitalId;
SCSIId = scsiId;
USBId = usbId;
AddedWhen = uploadedWhen;
ModifiedWhen = DateTime.UtcNow;
Manufacturer = manufacturer;
Model = model;
Revision = revision;
CompactFlash = compactFlash;
Type = type;
GdRomSwapDiscCapabilitiesId = gdRomSwapDiscCapabilitiesId;
}
[DisplayName("Added when")]
public DateTime AddedWhen { get; set; }
[DisplayName("Modified when")]
public DateTime? ModifiedWhen { get; set; }
public virtual CompactDiscOffset CdOffset { get; set; }
[DefaultValue(0), DisplayName("Optimal no. of sectors to be read at once")]
public int OptimalMultipleSectorsRead { get; set; }
[DefaultValue(null), DisplayName("Can read GD-ROM using swap disc trick")]
public bool? CanReadGdRomUsingSwapDisc { get; set; }
public int? ATAId { get; set; }
public int? ATAPIId { get; set; }
public int? FireWireId { get; set; }
public int? MultiMediaCardId { get; set; }
public int? PCMCIAId { get; set; }
public int? SecureDigitalId { get; set; }
public int? SCSIId { get; set; }
public int? USBId { get; set; }
public int? GdRomSwapDiscCapabilitiesId { get; set; }
}

View File

@@ -1,19 +1,18 @@
using System.Collections.Generic;
using Aaru.CommonTypes.Metadata;
namespace Aaru.Server.Models
namespace Aaru.Server.Models;
public class DeviceDetails
{
public class DeviceDetails
{
public Device Report { get; set; }
public List<int> SameAll { get; set; }
public List<int> SameButManufacturer { get; set; }
public List<int> ReportAll { get; set; }
public List<int> ReportButManufacturer { get; set; }
public List<DeviceStat> StatsAll { get; set; }
public List<DeviceStat> StatsButManufacturer { get; set; }
public int ReadCapabilitiesId { get; set; }
public List<TestedMedia> TestedMedias { get; set; }
public List<TestedSequentialMedia> TestedSequentialMedias { get; set; }
}
public Device Report { get; set; }
public List<int> SameAll { get; set; }
public List<int> SameButManufacturer { get; set; }
public List<int> ReportAll { get; set; }
public List<int> ReportButManufacturer { get; set; }
public List<DeviceStat> StatsAll { get; set; }
public List<DeviceStat> StatsButManufacturer { get; set; }
public int ReadCapabilitiesId { get; set; }
public List<TestedMedia> TestedMedias { get; set; }
public List<TestedSequentialMedia> TestedSequentialMedias { get; set; }
}

View File

@@ -30,14 +30,13 @@
// Copyright © 2011-2021 Natalia Portillo
// ****************************************************************************/
namespace Aaru.Server.Models
namespace Aaru.Server.Models;
public class DeviceItem
{
public class DeviceItem
{
public string Manufacturer { get; set; }
public string Model { get; set; }
public string Revision { get; set; }
public string Bus { get; set; }
public int ReportId { get; set; }
}
public string Manufacturer { get; set; }
public string Model { get; set; }
public string Revision { get; set; }
public string Bus { get; set; }
public int ReportId { get; set; }
}

View File

@@ -30,14 +30,13 @@
// Copyright © 2011-2021 Natalia Portillo
// ****************************************************************************/
namespace Aaru.Server.Models
namespace Aaru.Server.Models;
public class DeviceStat : BaseModel<int>
{
public class DeviceStat : BaseModel<int>
{
public string Manufacturer { get; set; }
public string Model { get; set; }
public string Revision { get; set; }
public string Bus { get; set; }
public virtual Device Report { get; set; }
}
public string Manufacturer { get; set; }
public string Model { get; set; }
public string Revision { get; set; }
public string Bus { get; set; }
public virtual Device Report { get; set; }
}

View File

@@ -1,9 +1,8 @@
namespace Aaru.Server.Models
{
public class ErrorViewModel
{
public string RequestId { get; set; }
namespace Aaru.Server.Models;
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
}
public class ErrorViewModel
{
public string RequestId { get; set; }
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
}

View File

@@ -30,7 +30,6 @@
// Copyright © 2011-2021 Natalia Portillo
// ****************************************************************************/
namespace Aaru.Server.Models
{
public class Filesystem : NameCountModel<int> {}
}
namespace Aaru.Server.Models;
public class Filesystem : NameCountModel<int> {}

View File

@@ -30,7 +30,6 @@
// Copyright © 2011-2021 Natalia Portillo
// ****************************************************************************/
namespace Aaru.Server.Models
{
public class Filter : NameCountModel<int> {}
}
namespace Aaru.Server.Models;
public class Filter : NameCountModel<int> {}

View File

@@ -1,13 +1,12 @@
using System.Collections.Generic;
namespace Aaru.Server.Models
namespace Aaru.Server.Models;
public class FindReportModel : BaseModel<int>
{
public class FindReportModel : BaseModel<int>
{
public string Manufacturer { get; set; }
public string Model { get; set; }
public string Revision { get; set; }
public string Bus { get; set; }
public List<Device> LikeDevices { get; set; }
}
public string Manufacturer { get; set; }
public string Model { get; set; }
public string Revision { get; set; }
public string Bus { get; set; }
public List<Device> LikeDevices { get; set; }
}

View File

@@ -2,25 +2,24 @@ using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
namespace Aaru.Server.Models
{
public class FireWireModel
{
[DisplayName("Vendor ID"), DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "0x{0:X8}")]
public uint VendorID { get; set; }
[DisplayName("Product ID"), DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "0x{0:X8}")]
public uint ProductID { get; set; }
[DisplayFormat(NullDisplayText = "Unknown")]
public string Manufacturer { get; set; }
[DisplayFormat(NullDisplayText = "Unknown")]
public string Product { get; set; }
[DisplayName("Is media removable?")]
public bool RemovableMedia { get; set; }
}
namespace Aaru.Server.Models;
public class FireWireModelForView
{
public List<FireWireModel> List { get; set; }
public string Json { get; set; }
}
public class FireWireModel
{
[DisplayName("Vendor ID"), DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "0x{0:X8}")]
public uint VendorID { get; set; }
[DisplayName("Product ID"), DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "0x{0:X8}")]
public uint ProductID { get; set; }
[DisplayFormat(NullDisplayText = "Unknown")]
public string Manufacturer { get; set; }
[DisplayFormat(NullDisplayText = "Unknown")]
public string Product { get; set; }
[DisplayName("Is media removable?")]
public bool RemovableMedia { get; set; }
}
public class FireWireModelForView
{
public List<FireWireModel> List { get; set; }
public string Json { get; set; }
}

View File

@@ -1,15 +1,14 @@
namespace Aaru.Server.Models
{
public class IdHashModel : BaseModel<int>
{
public IdHashModel(int id, string hash)
{
Id = id;
Hash = hash;
}
namespace Aaru.Server.Models;
public string Hash { get; set; }
public string Description { get; set; }
public int[] Duplicates { get; set; }
public class IdHashModel : BaseModel<int>
{
public IdHashModel(int id, string hash)
{
Id = id;
Hash = hash;
}
public string Hash { get; set; }
public string Description { get; set; }
public int[] Duplicates { get; set; }
}

View File

@@ -1,10 +1,9 @@
using System.Collections.Generic;
namespace Aaru.Server.Models
namespace Aaru.Server.Models;
public class IdHashModelForView
{
public class IdHashModelForView
{
public List<IdHashModel> List { get; set; }
public string Json { get; set; }
}
public List<IdHashModel> List { get; set; }
public string Json { get; set; }
}

View File

@@ -35,44 +35,43 @@ using System.ComponentModel;
using System.ComponentModel.DataAnnotations.Schema;
using Aaru.CommonTypes;
namespace Aaru.Server.Models
namespace Aaru.Server.Models;
public class Media : BaseModel<int>
{
public class Media : BaseModel<int>
[NotMapped]
(string type, string subType) _mediaType;
public string Type { get; set; }
public bool Real { get; set; }
public long Count { get; set; }
[NotMapped]
(string type, string subType) MediaType
{
[NotMapped]
(string type, string subType) _mediaType;
public string Type { get; set; }
public bool Real { get; set; }
public long Count { get; set; }
[NotMapped]
(string type, string subType) MediaType
get
{
get
{
if(_mediaType != default)
return _mediaType;
try
{
if(Enum.TryParse(Type, out MediaType enumMediaType))
_mediaType = CommonTypes.Metadata.MediaType.MediaTypeToString(enumMediaType);
else if(int.TryParse(Type, out int asInt))
_mediaType = CommonTypes.Metadata.MediaType.MediaTypeToString((MediaType)asInt);
}
catch
{
// Could not get media type/subtype pair from type, so just leave it as is
}
if(_mediaType != default)
return _mediaType;
}
}
[NotMapped, DisplayName("Physical type")]
public string PhysicalType => MediaType.type;
[NotMapped, DisplayName("Logical type")]
public string LogicalType => MediaType.subType;
try
{
if(Enum.TryParse(Type, out MediaType enumMediaType))
_mediaType = CommonTypes.Metadata.MediaType.MediaTypeToString(enumMediaType);
else if(int.TryParse(Type, out int asInt))
_mediaType = CommonTypes.Metadata.MediaType.MediaTypeToString((MediaType)asInt);
}
catch
{
// Could not get media type/subtype pair from type, so just leave it as is
}
return _mediaType;
}
}
[NotMapped, DisplayName("Physical type")]
public string PhysicalType => MediaType.type;
[NotMapped, DisplayName("Logical type")]
public string LogicalType => MediaType.subType;
}

View File

@@ -30,7 +30,6 @@
// Copyright © 2011-2021 Natalia Portillo
// ****************************************************************************/
namespace Aaru.Server.Models
{
public class MediaFormat : NameCountModel<int> {}
}
namespace Aaru.Server.Models;
public class MediaFormat : NameCountModel<int> {}

View File

@@ -30,12 +30,11 @@
// Copyright © 2011-2021 Natalia Portillo
// ****************************************************************************/
namespace Aaru.Server.Models
namespace Aaru.Server.Models;
public class MediaItem
{
public class MediaItem
{
public string Type { get; set; }
public string SubType { get; set; }
public long Count { get; set; }
}
public string Type { get; set; }
public string SubType { get; set; }
public long Count { get; set; }
}

View File

@@ -1,13 +1,12 @@
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
namespace Aaru.Server.Models
namespace Aaru.Server.Models;
public class MmcModelForView : BaseModel<int>
{
public class MmcModelForView : BaseModel<int>
{
[DisplayFormat(NullDisplayText = "none"), DisplayName("MMC FEATURES ID")]
public int? FeaturesId { get; set; }
[DisplayName("Response length (bytes)")]
public int DataLength { get; set; }
}
[DisplayFormat(NullDisplayText = "none"), DisplayName("MMC FEATURES ID")]
public int? FeaturesId { get; set; }
[DisplayName("Response length (bytes)")]
public int DataLength { get; set; }
}

View File

@@ -1,8 +1,7 @@
namespace Aaru.Server.Models
namespace Aaru.Server.Models;
public abstract class NameCountModel<T> : BaseModel<T>
{
public abstract class NameCountModel<T> : BaseModel<T>
{
public string Name { get; set; }
public long Count { get; set; }
}
public string Name { get; set; }
public long Count { get; set; }
}

View File

@@ -30,7 +30,6 @@
// Copyright © 2011-2021 Natalia Portillo
// ****************************************************************************/
namespace Aaru.Server.Models
{
public class OperatingSystem : BaseOperatingSystem {}
}
namespace Aaru.Server.Models;
public class OperatingSystem : BaseOperatingSystem {}

View File

@@ -30,7 +30,6 @@
// Copyright © 2011-2021 Natalia Portillo
// ****************************************************************************/
namespace Aaru.Server.Models
{
public class Partition : NameCountModel<int> {}
}
namespace Aaru.Server.Models;
public class Partition : NameCountModel<int> {}

View File

@@ -30,7 +30,6 @@
// Copyright © 2011-2021 Natalia Portillo
// ****************************************************************************/
namespace Aaru.Server.Models
{
public class RemoteApplication : BaseOperatingSystem {}
}
namespace Aaru.Server.Models;
public class RemoteApplication : BaseOperatingSystem {}

View File

@@ -30,7 +30,6 @@
// Copyright © 2011-2021 Natalia Portillo
// ****************************************************************************/
namespace Aaru.Server.Models
{
public class RemoteArchitecture : NameCountModel<int> {}
}
namespace Aaru.Server.Models;
public class RemoteArchitecture : NameCountModel<int> {}

View File

@@ -30,7 +30,6 @@
// Copyright © 2011-2021 Natalia Portillo
// ****************************************************************************/
namespace Aaru.Server.Models
{
public class RemoteOperatingSystem : BaseOperatingSystem {}
}
namespace Aaru.Server.Models;
public class RemoteOperatingSystem : BaseOperatingSystem {}

View File

@@ -1,17 +1,16 @@
using System.Collections.Generic;
namespace Aaru.Server.Models
{
public class SscModel
{
public byte? BlockSizeGranularity { get; set; }
public uint? MaxBlockLength { get; set; }
public uint? MinBlockLength { get; set; }
}
namespace Aaru.Server.Models;
public class SscModelForView
{
public List<SscModel> List { get; set; }
public string Json { get; set; }
}
public class SscModel
{
public byte? BlockSizeGranularity { get; set; }
public uint? MaxBlockLength { get; set; }
public uint? MinBlockLength { get; set; }
}
public class SscModelForView
{
public List<SscModel> List { get; set; }
public string Json { get; set; }
}

View File

@@ -1,10 +1,9 @@
namespace Aaru.Server.Models
namespace Aaru.Server.Models;
public class TestedMediaDataModel
{
public class TestedMediaDataModel
{
public int TestedMediaId { get; set; }
public string DataName { get; set; }
public string RawDataAsHex { get; set; }
public string Decoded { get; set; }
}
public int TestedMediaId { get; set; }
public string DataName { get; set; }
public string RawDataAsHex { get; set; }
public string Decoded { get; set; }
}

View File

@@ -34,42 +34,41 @@ using System;
using System.ComponentModel;
using Aaru.CommonTypes.Metadata;
namespace Aaru.Server.Models
namespace Aaru.Server.Models;
public class UploadedReport : DeviceReportV2
{
public class UploadedReport : DeviceReportV2
public UploadedReport() => UploadedWhen = DateTime.UtcNow;
public UploadedReport(DeviceReportV2 report)
{
public UploadedReport() => UploadedWhen = DateTime.UtcNow;
public UploadedReport(DeviceReportV2 report)
{
ATA = report.ATA;
ATAPI = report.ATAPI;
CompactFlash = report.CompactFlash;
FireWire = report.FireWire;
UploadedWhen = DateTime.UtcNow;
MultiMediaCard = report.MultiMediaCard;
PCMCIA = report.PCMCIA;
SCSI = report.SCSI;
SecureDigital = report.SecureDigital;
USB = report.USB;
Manufacturer = report.Manufacturer;
Model = report.Model;
Revision = report.Revision;
Type = report.Type;
GdRomSwapDiscCapabilities = report.GdRomSwapDiscCapabilities;
}
[DisplayName("Uploaded when")]
public DateTime UploadedWhen { get; set; }
public int? ATAId { get; set; }
public int? ATAPIId { get; set; }
public int? FireWireId { get; set; }
public int? MultiMediaCardId { get; set; }
public int? PCMCIAId { get; set; }
public int? SecureDigitalId { get; set; }
public int? SCSIId { get; set; }
public int? USBId { get; set; }
public int? GdRomSwapDiscCapabilitiesId { get; set; }
ATA = report.ATA;
ATAPI = report.ATAPI;
CompactFlash = report.CompactFlash;
FireWire = report.FireWire;
UploadedWhen = DateTime.UtcNow;
MultiMediaCard = report.MultiMediaCard;
PCMCIA = report.PCMCIA;
SCSI = report.SCSI;
SecureDigital = report.SecureDigital;
USB = report.USB;
Manufacturer = report.Manufacturer;
Model = report.Model;
Revision = report.Revision;
Type = report.Type;
GdRomSwapDiscCapabilities = report.GdRomSwapDiscCapabilities;
}
[DisplayName("Uploaded when")]
public DateTime UploadedWhen { get; set; }
public int? ATAId { get; set; }
public int? ATAPIId { get; set; }
public int? FireWireId { get; set; }
public int? MultiMediaCardId { get; set; }
public int? PCMCIAId { get; set; }
public int? SecureDigitalId { get; set; }
public int? SCSIId { get; set; }
public int? USBId { get; set; }
public int? GdRomSwapDiscCapabilitiesId { get; set; }
}

View File

@@ -1,17 +1,16 @@
using System.Collections.Generic;
using Aaru.CommonTypes.Metadata;
namespace Aaru.Server.Models
namespace Aaru.Server.Models;
public class UploadedReportDetails
{
public class UploadedReportDetails
{
public UploadedReport Report { get; set; }
public List<int> SameAll { get; set; }
public List<int> SameButManufacturer { get; set; }
public List<int> ReportAll { get; set; }
public List<int> ReportButManufacturer { get; set; }
public int ReadCapabilitiesId { get; set; }
public List<TestedMedia> TestedMedias { get; set; }
public List<TestedSequentialMedia> TestedSequentialMedias { get; set; }
}
public UploadedReport Report { get; set; }
public List<int> SameAll { get; set; }
public List<int> SameButManufacturer { get; set; }
public List<int> ReportAll { get; set; }
public List<int> ReportButManufacturer { get; set; }
public int ReadCapabilitiesId { get; set; }
public List<TestedMedia> TestedMedias { get; set; }
public List<TestedSequentialMedia> TestedSequentialMedias { get; set; }
}

View File

@@ -1,18 +1,17 @@
using System.Collections.Generic;
namespace Aaru.Server.Models
{
public class UsbModel
{
public string Manufacturer { get; set; }
public string Product { get; set; }
public ushort VendorID { get; set; }
public ushort ProductID { get; set; }
}
namespace Aaru.Server.Models;
public class UsbModelForView
{
public List<UsbModel> List { get; set; }
public string Json { get; set; }
}
public class UsbModel
{
public string Manufacturer { get; set; }
public string Product { get; set; }
public ushort VendorID { get; set; }
public ushort ProductID { get; set; }
}
public class UsbModelForView
{
public List<UsbModel> List { get; set; }
public string Json { get; set; }
}

View File

@@ -33,27 +33,26 @@
using System;
using Newtonsoft.Json;
namespace Aaru.Server.Models
namespace Aaru.Server.Models;
public class UsbProduct : BaseModel<int>
{
public class UsbProduct : BaseModel<int>
public UsbProduct() {}
public UsbProduct(UsbVendor vendor, ushort id, string product)
{
public UsbProduct() {}
public UsbProduct(UsbVendor vendor, ushort id, string product)
{
ProductId = id;
Product = product;
AddedWhen = ModifiedWhen = DateTime.UtcNow;
Vendor = vendor;
}
public ushort ProductId { get; set; }
public string Product { get; set; }
public DateTime AddedWhen { get; set; }
public DateTime ModifiedWhen { get; set; }
public int VendorId { get; set; }
[JsonIgnore]
public virtual UsbVendor Vendor { get; set; }
ProductId = id;
Product = product;
AddedWhen = ModifiedWhen = DateTime.UtcNow;
Vendor = vendor;
}
public ushort ProductId { get; set; }
public string Product { get; set; }
public DateTime AddedWhen { get; set; }
public DateTime ModifiedWhen { get; set; }
public int VendorId { get; set; }
[JsonIgnore]
public virtual UsbVendor Vendor { get; set; }
}

View File

@@ -1,16 +1,15 @@
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
namespace Aaru.Server.Models
namespace Aaru.Server.Models;
public class UsbProductModel
{
public class UsbProductModel
{
[DisplayName("Manufacturer")]
public string VendorName { get; set; }
public int VendorId { get; set; }
[DisplayName("Product")]
public string ProductName { get; set; }
[DisplayName("Product ID"), DisplayFormat(DataFormatString = "0x{0:X4}")]
public ushort ProductId { get; set; }
}
[DisplayName("Manufacturer")]
public string VendorName { get; set; }
public int VendorId { get; set; }
[DisplayName("Product")]
public string ProductName { get; set; }
[DisplayName("Product ID"), DisplayFormat(DataFormatString = "0x{0:X4}")]
public ushort ProductId { get; set; }
}

View File

@@ -36,27 +36,26 @@ using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using Newtonsoft.Json;
namespace Aaru.Server.Models
namespace Aaru.Server.Models;
public class UsbVendor : BaseModel<int>
{
public class UsbVendor : BaseModel<int>
public UsbVendor() {}
public UsbVendor(ushort id, string vendor)
{
public UsbVendor() {}
public UsbVendor(ushort id, string vendor)
{
VendorId = id;
Vendor = vendor;
AddedWhen = ModifiedWhen = DateTime.UtcNow;
}
[DisplayName("Manufacturer ID"), DisplayFormat(DataFormatString = "0x{0:X4}")]
public ushort VendorId { get; set; }
[DisplayName("Manufacturer")]
public string Vendor { get; set; }
public DateTime AddedWhen { get; set; }
public DateTime ModifiedWhen { get; set; }
[JsonIgnore]
public virtual ICollection<UsbProduct> Products { get; set; }
VendorId = id;
Vendor = vendor;
AddedWhen = ModifiedWhen = DateTime.UtcNow;
}
[DisplayName("Manufacturer ID"), DisplayFormat(DataFormatString = "0x{0:X4}")]
public ushort VendorId { get; set; }
[DisplayName("Manufacturer")]
public string Vendor { get; set; }
public DateTime AddedWhen { get; set; }
public DateTime ModifiedWhen { get; set; }
[JsonIgnore]
public virtual ICollection<UsbProduct> Products { get; set; }
}

View File

@@ -2,14 +2,13 @@ using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
namespace Aaru.Server.Models
namespace Aaru.Server.Models;
public class UsbVendorModel
{
public class UsbVendorModel
{
[DisplayName("Manufacturer")]
public string Vendor { get; set; }
[DisplayName("Vendor ID"), DisplayFormat(DataFormatString = "0x{0:X4}")]
public ushort VendorId { get; set; }
public List<UsbProductModel> Products { get; set; }
}
[DisplayName("Manufacturer")]
public string Vendor { get; set; }
[DisplayName("Vendor ID"), DisplayFormat(DataFormatString = "0x{0:X4}")]
public ushort VendorId { get; set; }
public List<UsbProductModel> Products { get; set; }
}

View File

@@ -30,7 +30,6 @@
// Copyright © 2011-2021 Natalia Portillo
// ****************************************************************************/
namespace Aaru.Server.Models
{
public class Version : NameCountModel<int> {}
}
namespace Aaru.Server.Models;
public class Version : NameCountModel<int> {}

View File

@@ -12,171 +12,170 @@ using Microsoft.Extensions.Hosting;
using Prometheus;
using Version = Aaru.CommonTypes.Interop.Version;
namespace Aaru.Server
namespace Aaru.Server;
public sealed class Program
{
public sealed class Program
public static void Main(string[] args)
{
public static void Main(string[] args)
{
DateTime start;
DateTime end;
DateTime start;
DateTime end;
System.Console.Clear();
System.Console.Clear();
System.Console.Write(
"\u001b[32m . ,,\n" +
"\u001b[32m ;,. '0d.\n" +
"\u001b[32m oc oWd \u001b[31m" +
@"__/\\\\\\\\\\\\_____/\\\\\\\\\\\________/\\\\\\\\\_ " + "\n\u001b[0m" +
"\u001b[32m ;X. 'WN' \u001b[31m" +
@" _\/\\\////////\\\__\/////\\\///______/\\\////////__ " + "\n\u001b[0m" +
"\u001b[32m oMo cMM: \u001b[31m" +
@" _\/\\\______\//\\\_____\/\\\_______/\\\/___________ " + "\n\u001b[0m" +
"\u001b[32m ;MM. .MMM; \u001b[31m" +
@" _\/\\\_______\/\\\_____\/\\\______/\\\_____________ " + "\n\u001b[0m" +
"\u001b[32m NMM WMMW \u001b[31m" +
@" _\/\\\_______\/\\\_____\/\\\_____\/\\\_____________ " + "\n\u001b[0m" +
"\u001b[32m 'MMM MMMM; \u001b[31m" +
@" _\/\\\_______\/\\\_____\/\\\_____\//\\\____________ " + "\n\u001b[0m" +
"\u001b[32m ,MMM: dMMMM: \u001b[31m" +
@" _\/\\\_______/\\\______\/\\\______\///\\\__________ " + "\n\u001b[0m" +
"\u001b[32m .MMMW. :MMMMM. \u001b[31m" +
@" _\/\\\\\\\\\\\\/____/\\\\\\\\\\\____\////\\\\\\\\\_ " + "\n\u001b[0m" +
"\u001b[32m XMMMW: .:xKNMMMMMMN0d, lMMMMMd \u001b[31m" +
@" _\////////////_____\///////////________\/////////__" + "\n\u001b[0m" +
"\u001b[32m :MMMMMK; cWMNkl:;;;:lxKMXc .0MMMMMO\u001b[0m\n" +
"\u001b[32m ..KMMMMMMNo,. ,OMMMMMMW:,. \u001b[37;1m Aaru Website\u001b[0m\n" +
"\u001b[32m .;d0NMMMMMMMMMMMMMMW0d:' .;lOWMMMMMMMMMMMMMXkl. \u001b[37;1m Version \u001b[0m\u001b[33m{0}\u001b[37;1m-\u001b[0m\u001b[31m{1}\u001b[0m\n" +
"\u001b[32m :KMMMMMMMMMMMMMMMMMMMMMMMMc WMMMMMMMMMMMMMMMMMMMMMMWk'\u001b[0m\n" +
"\u001b[32m ;NMMMMWX0kkkkO0XMMMMMMMMMMM0' dNMMMMMMMMMMW0xl:;,;:oOWMMX; \u001b[37;1m Running under \u001b[35;1m{2}\u001b[37;1m, \u001b[35m{3}-bit\u001b[37;1m in \u001b[35m{4}-bit\u001b[37;1m mode.\u001b[0m\n" +
"\u001b[32m xMMWk:. .c0MMMMMW' OMMMMMM0c'.. .oNMO \u001b[37;1m Using \u001b[33;1m{5}\u001b[37;1m version \u001b[31;1m{6}\u001b[0m\n" +
"\u001b[32m OMNc .MNc oWMMk 'WMMNl. .MMK ;KX.\u001b[0m\n" +
"\u001b[32m xMO WMN ; ., , ': ,MMx lK\u001b[0m\n" +
"\u001b[32m ,Md cMMl .XMMMWWMMMO XMW. :\u001b[0m\n" +
"\u001b[32m Ok xMMl XMMMMMMMMc 0MW,\u001b[0m\n" +
"\u001b[32m 0 oMM0' lMMMMMMMM. :NMN'\u001b[0m\n" +
"\u001b[32m . .0MMKl ;MMMMMMMM oNMWd\u001b[0m\n" +
"\u001b[32m .dNW cMMMMMMMM, XKl\u001b[0m\n" +
"\u001b[32m 0MMMMMMMMK\u001b[0m\n" +
"\u001b[32m ;MMMMMMMMMMO \u001b[37;1m Proudly presented to you by:\u001b[0m\n" +
"\u001b[32m 'WMMMMKxMMMMM0 \u001b[34;1m Natalia Portillo\u001b[0m\n" +
"\u001b[32m oMMMMNc :WMMMMN:\u001b[0m\n" +
"\u001b[32m .dWMMM0; dWMMMMXl. \u001b[37;1m Thanks to all contributors, collaborators, translators, donators and friends.\u001b[0m\n" +
"\u001b[32m .......,cd0WMMNk: c0MMMMMWKkolc:clodc'\u001b[0m\n" +
"\u001b[32m .';loddol:'. ':oxkkOkkxoc,.\u001b[0m\n" +
"\u001b[0m\n", Version.GetVersion(),
#if DEBUG
"DEBUG"
#else
System.Console.Write(
"\u001b[32m . ,,\n" +
"\u001b[32m ;,. '0d.\n" +
"\u001b[32m oc oWd \u001b[31m" +
@"__/\\\\\\\\\\\\_____/\\\\\\\\\\\________/\\\\\\\\\_ " + "\n\u001b[0m" +
"\u001b[32m ;X. 'WN' \u001b[31m" +
@" _\/\\\////////\\\__\/////\\\///______/\\\////////__ " + "\n\u001b[0m" +
"\u001b[32m oMo cMM: \u001b[31m" +
@" _\/\\\______\//\\\_____\/\\\_______/\\\/___________ " + "\n\u001b[0m" +
"\u001b[32m ;MM. .MMM; \u001b[31m" +
@" _\/\\\_______\/\\\_____\/\\\______/\\\_____________ " + "\n\u001b[0m" +
"\u001b[32m NMM WMMW \u001b[31m" +
@" _\/\\\_______\/\\\_____\/\\\_____\/\\\_____________ " + "\n\u001b[0m" +
"\u001b[32m 'MMM MMMM; \u001b[31m" +
@" _\/\\\_______\/\\\_____\/\\\_____\//\\\____________ " + "\n\u001b[0m" +
"\u001b[32m ,MMM: dMMMM: \u001b[31m" +
@" _\/\\\_______/\\\______\/\\\______\///\\\__________ " + "\n\u001b[0m" +
"\u001b[32m .MMMW. :MMMMM. \u001b[31m" +
@" _\/\\\\\\\\\\\\/____/\\\\\\\\\\\____\////\\\\\\\\\_ " + "\n\u001b[0m" +
"\u001b[32m XMMMW: .:xKNMMMMMMN0d, lMMMMMd \u001b[31m" +
@" _\////////////_____\///////////________\/////////__" + "\n\u001b[0m" +
"\u001b[32m :MMMMMK; cWMNkl:;;;:lxKMXc .0MMMMMO\u001b[0m\n" +
"\u001b[32m ..KMMMMMMNo,. ,OMMMMMMW:,. \u001b[37;1m Aaru Website\u001b[0m\n" +
"\u001b[32m .;d0NMMMMMMMMMMMMMMW0d:' .;lOWMMMMMMMMMMMMMXkl. \u001b[37;1m Version \u001b[0m\u001b[33m{0}\u001b[37;1m-\u001b[0m\u001b[31m{1}\u001b[0m\n" +
"\u001b[32m :KMMMMMMMMMMMMMMMMMMMMMMMMc WMMMMMMMMMMMMMMMMMMMMMMWk'\u001b[0m\n" +
"\u001b[32m ;NMMMMWX0kkkkO0XMMMMMMMMMMM0' dNMMMMMMMMMMW0xl:;,;:oOWMMX; \u001b[37;1m Running under \u001b[35;1m{2}\u001b[37;1m, \u001b[35m{3}-bit\u001b[37;1m in \u001b[35m{4}-bit\u001b[37;1m mode.\u001b[0m\n" +
"\u001b[32m xMMWk:. .c0MMMMMW' OMMMMMM0c'.. .oNMO \u001b[37;1m Using \u001b[33;1m{5}\u001b[37;1m version \u001b[31;1m{6}\u001b[0m\n" +
"\u001b[32m OMNc .MNc oWMMk 'WMMNl. .MMK ;KX.\u001b[0m\n" +
"\u001b[32m xMO WMN ; ., , ': ,MMx lK\u001b[0m\n" +
"\u001b[32m ,Md cMMl .XMMMWWMMMO XMW. :\u001b[0m\n" +
"\u001b[32m Ok xMMl XMMMMMMMMc 0MW,\u001b[0m\n" +
"\u001b[32m 0 oMM0' lMMMMMMMM. :NMN'\u001b[0m\n" +
"\u001b[32m . .0MMKl ;MMMMMMMM oNMWd\u001b[0m\n" +
"\u001b[32m .dNW cMMMMMMMM, XKl\u001b[0m\n" +
"\u001b[32m 0MMMMMMMMK\u001b[0m\n" +
"\u001b[32m ;MMMMMMMMMMO \u001b[37;1m Proudly presented to you by:\u001b[0m\n" +
"\u001b[32m 'WMMMMKxMMMMM0 \u001b[34;1m Natalia Portillo\u001b[0m\n" +
"\u001b[32m oMMMMNc :WMMMMN:\u001b[0m\n" +
"\u001b[32m .dWMMM0; dWMMMMXl. \u001b[37;1m Thanks to all contributors, collaborators, translators, donators and friends.\u001b[0m\n" +
"\u001b[32m .......,cd0WMMNk: c0MMMMMWKkolc:clodc'\u001b[0m\n" +
"\u001b[32m .';loddol:'. ':oxkkOkkxoc,.\u001b[0m\n" +
"\u001b[0m\n", Version.GetVersion(),
#if DEBUG
"DEBUG"
#else
"RELEASE"
#endif
, DetectOS.GetPlatformName(DetectOS.GetRealPlatformID()),
Environment.Is64BitOperatingSystem ? 64 : 32, Environment.Is64BitProcess ? 64 : 32,
DetectOS.IsMono ? "Mono" : ".NET Core",
DetectOS.IsMono ? Version.GetMonoVersion() : Version.GetNetCoreVersion());
#endif
, DetectOS.GetPlatformName(DetectOS.GetRealPlatformID()),
Environment.Is64BitOperatingSystem ? 64 : 32, Environment.Is64BitProcess ? 64 : 32,
DetectOS.IsMono ? "Mono" : ".NET Core",
DetectOS.IsMono ? Version.GetMonoVersion() : Version.GetNetCoreVersion());
System.Console.WriteLine("\u001b[31;1mBuilding web application...\u001b[0m");
System.Console.WriteLine("\u001b[31;1mBuilding web application...\u001b[0m");
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
builder.Services.AddDbContext<AaruServerContext>(options => options.
UseMySql(builder.Configuration.GetConnectionString("DefaultConnection"),
new MariaDbServerVersion(new System.
Version(10, 4, 0))).
UseLazyLoadingProxies());
builder.Services.AddDbContext<AaruServerContext>(options => options.
UseMySql(builder.Configuration.GetConnectionString("DefaultConnection"),
new MariaDbServerVersion(new System.
Version(10, 4, 0))).
UseLazyLoadingProxies());
builder.Services.AddDefaultIdentity<IdentityUser>(options =>
{
options.SignIn.RequireConfirmedAccount = true;
options.User.RequireUniqueEmail = true;
}).AddEntityFrameworkStores<AaruServerContext>();
builder.Services.AddDefaultIdentity<IdentityUser>(options =>
{
options.SignIn.RequireConfirmedAccount = true;
options.User.RequireUniqueEmail = true;
}).AddEntityFrameworkStores<AaruServerContext>();
builder.Services.AddApplicationInsightsTelemetry();
builder.Services.AddApplicationInsightsTelemetry();
builder.Services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_3_0);
builder.Services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_3_0);
WebApplication app = builder.Build();
WebApplication app = builder.Build();
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});
app.UseHttpMetrics();
app.UseHttpMetrics();
if(builder.Environment.IsDevelopment())
app.UseDeveloperExceptionPage();
else
{
app.UseExceptionHandler("/Home/Error");
if(builder.Environment.IsDevelopment())
app.UseDeveloperExceptionPage();
else
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseDefaultFiles();
app.UseStaticFiles();
// Add other security headers
app.UseMiddleware<SecurityHeadersMiddleware>();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute("areas", "{area}/{controller=Home}/{action=Index}/{id?}");
endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");
endpoints.MapRazorPages();
});
app.Map("/metrics", metricsApp =>
{
metricsApp.UseMiddleware<BasicAuthMiddleware>("Aaru");
// We already specified URL prefix in .Map() above, no need to specify it again here.
metricsApp.UseMetricServer("");
});
using(IServiceScope scope = app.Services.CreateScope())
{
IServiceProvider services = scope.ServiceProvider;
try
{
start = DateTime.Now;
System.Console.WriteLine("\u001b[31;1mUpdating database with Entity Framework...\u001b[0m");
AaruServerContext context = services.GetRequiredService<AaruServerContext>();
context.Database.Migrate();
end = DateTime.Now;
System.Console.WriteLine("\u001b[31;1mTook \u001b[32;1m{0} seconds\u001b[31;1m...\u001b[0m",
(end - start).TotalSeconds);
start = DateTime.Now;
System.Console.WriteLine("\u001b[31;1mSeeding Identity...\u001b[0m");
Seeder.Seed(context, services);
context.Database.Migrate();
end = DateTime.Now;
System.Console.WriteLine("\u001b[31;1mTook \u001b[32;1m{0} seconds\u001b[31;1m...\u001b[0m",
(end - start).TotalSeconds);
}
catch(Exception ex)
{
System.Console.WriteLine("\u001b[31;1mCould not open database...\u001b[0m");
#if DEBUG
System.Console.WriteLine("\u001b[31;1mException: {0}\u001b[0m", ex.Message);
#endif
return;
}
}
System.Console.WriteLine("\u001b[31;1mStarting web server...\u001b[0m");
app.Run();
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseDefaultFiles();
app.UseStaticFiles();
// Add other security headers
app.UseMiddleware<SecurityHeadersMiddleware>();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute("areas", "{area}/{controller=Home}/{action=Index}/{id?}");
endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");
endpoints.MapRazorPages();
});
app.Map("/metrics", metricsApp =>
{
metricsApp.UseMiddleware<BasicAuthMiddleware>("Aaru");
// We already specified URL prefix in .Map() above, no need to specify it again here.
metricsApp.UseMetricServer("");
});
using(IServiceScope scope = app.Services.CreateScope())
{
IServiceProvider services = scope.ServiceProvider;
try
{
start = DateTime.Now;
System.Console.WriteLine("\u001b[31;1mUpdating database with Entity Framework...\u001b[0m");
AaruServerContext context = services.GetRequiredService<AaruServerContext>();
context.Database.Migrate();
end = DateTime.Now;
System.Console.WriteLine("\u001b[31;1mTook \u001b[32;1m{0} seconds\u001b[31;1m...\u001b[0m",
(end - start).TotalSeconds);
start = DateTime.Now;
System.Console.WriteLine("\u001b[31;1mSeeding Identity...\u001b[0m");
Seeder.Seed(context, services);
context.Database.Migrate();
end = DateTime.Now;
System.Console.WriteLine("\u001b[31;1mTook \u001b[32;1m{0} seconds\u001b[31;1m...\u001b[0m",
(end - start).TotalSeconds);
}
catch(Exception ex)
{
System.Console.WriteLine("\u001b[31;1mCould not open database...\u001b[0m");
#if DEBUG
System.Console.WriteLine("\u001b[31;1mException: {0}\u001b[0m", ex.Message);
#endif
return;
}
}
System.Console.WriteLine("\u001b[31;1mStarting web server...\u001b[0m");
app.Run();
}
}

View File

@@ -1,68 +1,67 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
namespace Aaru.Server
namespace Aaru.Server;
public sealed class SecurityHeadersMiddleware
{
public sealed class SecurityHeadersMiddleware
readonly RequestDelegate _next;
public SecurityHeadersMiddleware(RequestDelegate next) => _next = next;
public Task Invoke(HttpContext context)
{
readonly RequestDelegate _next;
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy
// TODO Change the value depending of your needs
context.Response.Headers.Add("referrer-policy", new("strict-origin-when-cross-origin"));
public SecurityHeadersMiddleware(RequestDelegate next) => _next = next;
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options
context.Response.Headers.Add("x-content-type-options", new("nosniff"));
public Task Invoke(HttpContext context)
{
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy
// TODO Change the value depending of your needs
context.Response.Headers.Add("referrer-policy", new("strict-origin-when-cross-origin"));
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
context.Response.Headers.Add("x-frame-options", new("DENY"));
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options
context.Response.Headers.Add("x-content-type-options", new("nosniff"));
// https://security.stackexchange.com/questions/166024/does-the-x-permitted-cross-domain-policies-header-have-any-benefit-for-my-websit
context.Response.Headers.Add("X-Permitted-Cross-Domain-Policies", new("none"));
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
context.Response.Headers.Add("x-frame-options", new("DENY"));
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection
context.Response.Headers.Add("x-xss-protection", new("1; mode=block"));
// https://security.stackexchange.com/questions/166024/does-the-x-permitted-cross-domain-policies-header-have-any-benefit-for-my-websit
context.Response.Headers.Add("X-Permitted-Cross-Domain-Policies", new("none"));
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Feature-Policy
// https://github.com/w3c/webappsec-feature-policy/blob/master/features.md
// https://developers.google.com/web/updates/2018/06/feature-policy
// TODO change the value of each rule and check the documentation to see if new features are available
/*context.Response.Headers.Add("Feature-Policy",
new StringValues("accelerometer 'none';" + "ambient-light-sensor 'none';" +
"autoplay 'none';" + "battery 'none';" + "camera 'none';" +
"display-capture 'none';" + "document-domain 'none';" +
"encrypted-media 'none';" +
"execution-while-not-rendered 'none';" +
"execution-while-out-of-viewport 'none';" +
"gyroscope 'none';" + "magnetometer 'none';" +
"microphone 'none';" + "midi 'none';" +
"navigation-override 'none';" + "payment 'none';" +
"picture-in-picture 'none';" +
"publickey-credentials-get 'none';" + "sync-xhr 'none';" +
"usb 'none';" + "wake-lock 'none';" +
"xr-spatial-tracking 'none';"));*/
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection
context.Response.Headers.Add("x-xss-protection", new("1; mode=block"));
// https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy
// TODO change the value of each rule and check the documentation to see if new rules are available
/*context.Response.Headers.Add("Content-Security-Policy",
new StringValues("base-uri 'none';" + "block-all-mixed-content;" +
"child-src 'none';" + "connect-src 'none';" +
"default-src 'none';" + "font-src 'none';" +
"form-action 'none';" + "frame-ancestors 'none';" +
"frame-src 'none';" + "img-src 'none';" +
"manifest-src 'none';" + "media-src 'none';" +
"object-src 'none';" + "sandbox;" + "script-src 'none';" +
"script-src-attr 'none';" + "script-src-elem 'none';" +
"style-src 'none';" + "style-src-attr 'none';" +
"style-src-elem 'none';" + "upgrade-insecure-requests;" +
"worker-src 'none';"));*/
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Feature-Policy
// https://github.com/w3c/webappsec-feature-policy/blob/master/features.md
// https://developers.google.com/web/updates/2018/06/feature-policy
// TODO change the value of each rule and check the documentation to see if new features are available
/*context.Response.Headers.Add("Feature-Policy",
new StringValues("accelerometer 'none';" + "ambient-light-sensor 'none';" +
"autoplay 'none';" + "battery 'none';" + "camera 'none';" +
"display-capture 'none';" + "document-domain 'none';" +
"encrypted-media 'none';" +
"execution-while-not-rendered 'none';" +
"execution-while-out-of-viewport 'none';" +
"gyroscope 'none';" + "magnetometer 'none';" +
"microphone 'none';" + "midi 'none';" +
"navigation-override 'none';" + "payment 'none';" +
"picture-in-picture 'none';" +
"publickey-credentials-get 'none';" + "sync-xhr 'none';" +
"usb 'none';" + "wake-lock 'none';" +
"xr-spatial-tracking 'none';"));*/
// https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy
// TODO change the value of each rule and check the documentation to see if new rules are available
/*context.Response.Headers.Add("Content-Security-Policy",
new StringValues("base-uri 'none';" + "block-all-mixed-content;" +
"child-src 'none';" + "connect-src 'none';" +
"default-src 'none';" + "font-src 'none';" +
"form-action 'none';" + "frame-ancestors 'none';" +
"frame-src 'none';" + "img-src 'none';" +
"manifest-src 'none';" + "media-src 'none';" +
"object-src 'none';" + "sandbox;" + "script-src 'none';" +
"script-src-attr 'none';" + "script-src-elem 'none';" +
"style-src 'none';" + "style-src-attr 'none';" +
"style-src-elem 'none';" + "upgrade-insecure-requests;" +
"worker-src 'none';"));*/
return _next(context);
}
return _next(context);
}
}

View File

@@ -3,42 +3,41 @@ using Aaru.Server.Models;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.DependencyInjection;
namespace Aaru.Server
namespace Aaru.Server;
public static class Seeder
{
public static class Seeder
public static void Seed(AaruServerContext ctx, IServiceProvider serviceProvider)
{
public static void Seed(AaruServerContext ctx, IServiceProvider serviceProvider)
string email = "claunia@claunia.com";
char[] randChars = new char[16];
UserManager<IdentityUser> userManager = serviceProvider.GetRequiredService<UserManager<IdentityUser>>();
var rnd = new Random();
for(int i = 0; i < randChars.Length; i++)
{
string email = "claunia@claunia.com";
char[] randChars = new char[16];
UserManager<IdentityUser> userManager = serviceProvider.GetRequiredService<UserManager<IdentityUser>>();
var rnd = new Random();
randChars[i] = (char)rnd.Next(32, 126);
}
for(int i = 0; i < randChars.Length; i++)
{
randChars[i] = (char)rnd.Next(32, 126);
}
string password = new(randChars);
string password = new(randChars);
if(userManager.FindByEmailAsync(email).Result != null)
return;
if(userManager.FindByEmailAsync(email).Result != null)
return;
var user = new IdentityUser
{
Email = email,
NormalizedEmail = email,
EmailConfirmed = true,
UserName = email,
NormalizedUserName = email
};
var user = new IdentityUser
{
Email = email,
NormalizedEmail = email,
EmailConfirmed = true,
UserName = email,
NormalizedUserName = email
};
IdentityResult result = userManager.CreateAsync(user, password).Result;
IdentityResult result = userManager.CreateAsync(user, password).Result;
if(result.Succeeded)
{
System.Console.WriteLine("Password is {0}, save it!", password);
}
if(result.Succeeded)
{
System.Console.WriteLine("Password is {0}, save it!", password);
}
}
}

View File

@@ -1,6 +1,6 @@
{
"ConnectionStrings": {
"DefaultConnection": "server=localhost;port=3306;database=discimagechef;uid=dic;password=dicpass"
"DefaultConnection": "server=zeus.claunia.com;port=3306;database=discimagechef;uid=dic;password=dicpass"
},
"Logging": {
"LogLevel": {