Add admin pages to view GD-ROM device report data.

This commit is contained in:
2020-07-18 19:37:46 +01:00
parent 201dbefa7c
commit 6b62580714
7 changed files with 2744 additions and 0 deletions

View File

@@ -109,4 +109,19 @@
<UpToDateCheckInput Remove="Areas\Admin\Shared\_ValidationScriptsPartial.cshtml" />
</ItemGroup>
<ItemGroup>
<Content Update="Areas\Admin\Views\GdRomSwapDiscCapabilities\Delete.cshtml">
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<Content Update="Areas\Admin\Views\GdRomSwapDiscCapabilities\Details.cshtml">
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<Content Update="Areas\Admin\Views\GdRomSwapDiscCapabilities\ViewData.cshtml">
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,391 @@
using System;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using Aaru.CommonTypes.Metadata;
using Aaru.Decoders.CD;
using Aaru.Server.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespace Aaru.Server.Areas.Admin.Controllers
{
[Area("Admin"), Authorize]
public class GdRomSwapDiscCapabilitiesController : Controller
{
readonly AaruServerContext _context;
public GdRomSwapDiscCapabilitiesController(AaruServerContext context) => _context = context;
// GET: Admin/GdRomSwapDiscCapabilities/Details/5
public async Task<IActionResult> Details(int? id)
{
if(id == null)
{
return NotFound();
}
GdRomSwapDiscCapabilities caps =
await _context.GdRomSwapDiscCapabilities.FirstOrDefaultAsync(m => m.Id == id);
if(caps == null)
{
return NotFound();
}
return View(caps);
}
// GET: Admin/GdRomSwapDiscCapabilities/Delete/5
public async Task<IActionResult> Delete(int? id)
{
if(id == null)
{
return NotFound();
}
GdRomSwapDiscCapabilities caps =
await _context.GdRomSwapDiscCapabilities.FirstOrDefaultAsync(m => m.Id == id);
if(caps == null)
{
return NotFound();
}
return View(caps);
}
// 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 RedirectToAction("Index", "Admin");
}
public IActionResult ViewData(int id, string data)
{
if(string.IsNullOrWhiteSpace(data))
return NotFound();
GdRomSwapDiscCapabilities caps = _context.GdRomSwapDiscCapabilities.FirstOrDefault(m => m.Id == id);
if(caps == null)
{
return NotFound();
}
var model = new TestedMediaDataModel
{
TestedMediaId = id, DataName = data
};
byte[] buffer;
var sb = new StringBuilder();
byte[] sector = new byte[2352];
byte[] subq = new byte[16];
byte[] fullsub = new byte[96];
bool audio = true;
bool pq = false;
bool rw = false;
switch(data)
{
case nameof(caps.Lba0Data):
buffer = caps.Lba0Data;
audio = false;
break;
case nameof(caps.Lba0ScrambledData):
buffer = caps.Lba0ScrambledData;
break;
case nameof(caps.Lba44990Data):
buffer = caps.Lba44990Data;
audio = false;
break;
case nameof(caps.Lba44990PqData):
buffer = caps.Lba44990PqData;
audio = false;
pq = true;
break;
case nameof(caps.Lba44990RwData):
buffer = caps.Lba44990RwData;
audio = false;
rw = true;
break;
case nameof(caps.Lba44990AudioData):
buffer = caps.Lba44990AudioData;
break;
case nameof(caps.Lba44990AudioPqData):
buffer = caps.Lba44990AudioPqData;
pq = true;
break;
case nameof(caps.Lba44990AudioRwData):
buffer = caps.Lba44990AudioRwData;
rw = true;
break;
case nameof(caps.Lba45000Data):
buffer = caps.Lba45000Data;
audio = false;
break;
case nameof(caps.Lba45000PqData):
buffer = caps.Lba45000PqData;
audio = false;
pq = true;
break;
case nameof(caps.Lba45000RwData):
buffer = caps.Lba45000RwData;
audio = false;
rw = true;
break;
case nameof(caps.Lba45000AudioData):
buffer = caps.Lba45000AudioData;
break;
case nameof(caps.Lba45000AudioPqData):
buffer = caps.Lba45000AudioPqData;
pq = true;
break;
case nameof(caps.Lba45000AudioRwData):
buffer = caps.Lba45000AudioRwData;
rw = true;
break;
case nameof(caps.Lba50000Data):
buffer = caps.Lba50000Data;
audio = false;
break;
case nameof(caps.Lba50000PqData):
buffer = caps.Lba50000PqData;
audio = false;
pq = true;
break;
case nameof(caps.Lba50000RwData):
buffer = caps.Lba50000RwData;
audio = false;
rw = true;
break;
case nameof(caps.Lba50000AudioData):
buffer = caps.Lba50000AudioData;
break;
case nameof(caps.Lba50000AudioPqData):
buffer = caps.Lba50000AudioPqData;
pq = true;
break;
case nameof(caps.Lba50000AudioRwData):
buffer = caps.Lba50000AudioRwData;
rw = true;
break;
case nameof(caps.Lba100000Data):
buffer = caps.Lba100000Data;
audio = false;
break;
case nameof(caps.Lba100000PqData):
buffer = caps.Lba100000PqData;
audio = false;
pq = true;
break;
case nameof(caps.Lba100000RwData):
buffer = caps.Lba100000RwData;
audio = false;
rw = true;
break;
case nameof(caps.Lba100000AudioData):
buffer = caps.Lba100000AudioData;
break;
case nameof(caps.Lba100000AudioPqData):
buffer = caps.Lba100000AudioPqData;
pq = true;
break;
case nameof(caps.Lba100000AudioRwData):
buffer = caps.Lba100000AudioRwData;
rw = true;
break;
case nameof(caps.Lba400000Data):
buffer = caps.Lba400000Data;
audio = false;
break;
case nameof(caps.Lba400000PqData):
buffer = caps.Lba400000PqData;
audio = false;
pq = true;
break;
case nameof(caps.Lba400000RwData):
buffer = caps.Lba400000RwData;
audio = false;
rw = true;
break;
case nameof(caps.Lba400000AudioData):
buffer = caps.Lba400000AudioData;
break;
case nameof(caps.Lba400000AudioPqData):
buffer = caps.Lba400000AudioPqData;
pq = true;
break;
case nameof(caps.Lba400000AudioRwData):
buffer = caps.Lba400000AudioRwData;
rw = true;
break;
case nameof(caps.Lba450000Data):
buffer = caps.Lba450000Data;
audio = false;
break;
case nameof(caps.Lba450000PqData):
buffer = caps.Lba450000PqData;
audio = false;
pq = true;
break;
case nameof(caps.Lba450000RwData):
buffer = caps.Lba450000RwData;
audio = false;
rw = true;
break;
case nameof(caps.Lba450000AudioData):
buffer = caps.Lba450000AudioData;
break;
case nameof(caps.Lba450000AudioPqData):
buffer = caps.Lba450000AudioPqData;
pq = true;
break;
case nameof(caps.Lba450000AudioRwData):
buffer = caps.Lba450000AudioRwData;
rw = true;
break;
default: return NotFound();
}
if(pq &&
buffer != null &&
buffer.Length % 2368 != 0)
pq = false;
if(rw &&
buffer != null &&
buffer.Length % 2448 != 0)
rw = false;
int blockSize = pq
? 2368
: rw
? 2448
: 2352;
model.RawDataAsHex = PrintHex.ByteArrayToHexArrayString(buffer);
if(model.RawDataAsHex != null)
model.RawDataAsHex = HttpUtility.HtmlEncode(model.RawDataAsHex).Replace("\n", "<br/>");
if(buffer == null)
return View(model);
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);
sb.AppendLine(Sector.Prettify(sector));
}
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/>");
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

@@ -139,6 +139,12 @@
<a asp-controller="Usbs" asp-action="Details" asp-route-id="@Model.Report.USB.Id" target="_blank">USB report</a>
</div>
}
@if(Model.Report.GdRomSwapDiscCapabilitiesId != null)
{
<div>
<a asp-controller="GdRomSwapDiscCapabilities" asp-action="Details" asp-route-id="@Model.Report.GdRomSwapDiscCapabilitiesId" target="_blank">GD-ROM swap-trick capabilities report</a>
</div>
}
@if(Model.Report.FireWire != null)
{
<div>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,29 @@
@model TestedMediaDataModel
@{
ViewBag.Title = $"{Model.DataName} data";
Layout = "_Layout";
}
<h2>Showing data from @Model.DataName for GD-ROM capabilities id @Model.TestedMediaId</h2>
@if(Model.Decoded is null &&
Model.RawDataAsHex is null)
{
<div>No data found</div>
}
@if(Model.RawDataAsHex != null)
{
<h4>Hex dump:</h4>
<div>
<code style="white-space: pre">@Html.Raw(Model.RawDataAsHex)</code>
</div>
}
@if(Model.Decoded != null)
{
<h4>Decoded information:</h4>
<div>
@Html.Raw(Model.Decoded)
</div>
}

View File

@@ -92,6 +92,12 @@
<a asp-controller="Usbs" asp-action="Details" asp-route-id="@Model.Report.USB.Id" target="_blank">USB report</a>
</div>
}
@if(Model.Report.GdRomSwapDiscCapabilitiesId != null)
{
<div>
<a asp-controller="GdRomSwapDiscCapabilities" asp-action="Details" asp-route-id="@Model.Report.GdRomSwapDiscCapabilitiesId" target="_blank">GD-ROM swap-trick capabilities report</a>
</div>
}
@if(Model.Report.FireWire != null)
{
<div>