175 lines
6.0 KiB
C#
175 lines
6.0 KiB
C#
using AquaCubeIT.Service.NetFloppy.Models;
|
|
using Fat16Lib;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.AspNetCore.Mvc.ModelBinding.Binders;
|
|
using System;
|
|
using System.IO;
|
|
using System.Text;
|
|
|
|
namespace AquaCubeIT.Service.NetFloppy.Controllers;
|
|
|
|
[ApiController]
|
|
[Route("[controller]")]
|
|
public class OperationsController : ControllerBase
|
|
{
|
|
private readonly ILogger<OperationsController> _logger;
|
|
private const int DISK_SIZE_MB = 5;
|
|
private const int DISK_SECTOR_SIZE = 512; // 512 bytes/sector
|
|
private const int DISK_SECTOR_COUNT = DISK_SIZE_MB * 1024 * 1024 / DISK_SECTOR_SIZE; // ~2 MB (4000 * 512)
|
|
private const long DISK_BYTE_SIZE = DISK_SECTOR_COUNT * DISK_SECTOR_SIZE;
|
|
|
|
public OperationsController(ILogger<OperationsController> logger)
|
|
{
|
|
_logger = logger;
|
|
}
|
|
|
|
private ErrorResponsePayload GetExceptionPayload(Exception exception)
|
|
{
|
|
return new ErrorResponsePayload() { ErrorNo = 16, Message = exception.Message, Exception = exception };
|
|
}
|
|
|
|
[Authorize(Policy = "MustBeUser")]
|
|
[HttpPost("LoadImage")]
|
|
public async Task<LoadImageResponse> LoadImage(LoadImageRequest request)
|
|
{
|
|
try
|
|
{
|
|
// Check image exists
|
|
|
|
|
|
// Check permissions of user
|
|
|
|
|
|
|
|
// Get image data
|
|
byte[] data = null;
|
|
|
|
if (System.IO.File.Exists("c:\\temp\\test_image1.img"))
|
|
{
|
|
|
|
data = await System.IO.File.ReadAllBytesAsync("c:\\temp\\test_image1.img");
|
|
}
|
|
else
|
|
{
|
|
var img = new Fat16Image(new Fat16ImageOptions
|
|
{
|
|
TotalSizeBytes = DISK_BYTE_SIZE,
|
|
VolumeLabel = "NetFloppy"
|
|
});
|
|
|
|
img.AddFile("README.TXT", Encoding.ASCII.GetBytes("Welcome to NetFloppy\r\n"));
|
|
img.AddFile("FF.CFG", Encoding.ASCII.GetBytes("# FF.CFG - FlashFloppy configuration (served inside FAT by backend)\r\ninterface = ibmpc\r\nhost = acorn\r\nindex-suppression = no\r\n\r\n# Enable speaker / fake disk drive sounds\r\nsound = on\r\nsound-volume = 19\r\n\r\n# Disable display devices\r\ndisplay-type = none\r\n"));
|
|
img.AddFile("TEST.ADF", System.IO.File.ReadAllBytes("TestDisk.adf"));
|
|
|
|
data = img.GetImage();
|
|
img.SaveToFile("c:\\temp\\test_image1.img");
|
|
|
|
}
|
|
|
|
|
|
return new LoadImageResponse() { Success = true, Payload = new LoadImageResponsePayload() { DiskImage = data } };
|
|
}
|
|
catch(Exception e)
|
|
{
|
|
return new LoadImageResponse() { Success = false, Error = GetExceptionPayload(e) };
|
|
}
|
|
}
|
|
|
|
private bool InRange(int lba, int offset, int len)
|
|
{
|
|
|
|
long start = lba * DISK_SECTOR_SIZE + offset;
|
|
long end = start + len;
|
|
return end <= DISK_BYTE_SIZE;
|
|
}
|
|
|
|
//[Authorize(Policy = "MustBeUser")]
|
|
[HttpPost("LoadSector")]
|
|
public async Task<IActionResult> LoadSector(LoadSectorRequest request)
|
|
{
|
|
try
|
|
{
|
|
// Check image exists
|
|
|
|
|
|
// Check permissions of user
|
|
|
|
|
|
|
|
// Get image data
|
|
byte[] data = null;
|
|
|
|
if (System.IO.File.Exists("c:\\temp\\test_image1.img"))
|
|
{
|
|
|
|
data = await System.IO.File.ReadAllBytesAsync("c:\\temp\\test_image1.img");
|
|
}
|
|
else
|
|
{
|
|
var img = new Fat16Image(new Fat16ImageOptions
|
|
{
|
|
TotalSizeBytes = DISK_BYTE_SIZE,
|
|
VolumeLabel = "NetFloppy"
|
|
});
|
|
|
|
img.AddFile("README.TXT", Encoding.ASCII.GetBytes("Welcome to NetFloppy\r\n"));
|
|
img.AddFile("FF.CFG", Encoding.ASCII.GetBytes("# FF.CFG - FlashFloppy configuration (served inside FAT by backend)\r\ninterface = ibmpc\r\nhost = acorn\r\nindex-suppression = no\r\n\r\n# Enable speaker / fake disk drive sounds\r\nsound = on\r\nsound-volume = 19\r\n\r\n# Disable display devices\r\ndisplay-type = none\r\n"));
|
|
img.AddFile("TEST.ADF", System.IO.File.ReadAllBytes("TestDisk.adf"));
|
|
|
|
data = img.GetImage();
|
|
//img.SaveToFile("c:\\temp\\test_image1.img");
|
|
|
|
}
|
|
|
|
if (!this.InRange(request.Payload.Lba, request.Payload.Offset, request.Payload.Length))
|
|
{
|
|
throw new Exception("Invalid Disk Location");
|
|
}
|
|
|
|
var startPosition = (request.Payload.Lba * DISK_SECTOR_SIZE) + request.Payload.Offset;
|
|
var sectorData = data.Skip(startPosition).Take(request.Payload.Length).ToArray();
|
|
|
|
//Response.ContentType = "application/octet-stream";
|
|
//Response.ContentLength = sectorData.Length;
|
|
//await Response.Body.WriteAsync(sectorData,0 , sectorData.Length);
|
|
|
|
return new LoadSectorResponse() { Success = true, Payload = new LoadSectorResponsePayload() { Data = sectorData, Length = sectorData.Length } };
|
|
|
|
//return new EmptyResult();
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
//return new LoadSectorResponse() { Success = false, Error = GetExceptionPayload(e) };
|
|
return BadRequest(e.Message);
|
|
}
|
|
}
|
|
|
|
[Authorize(Policy = "MustBeUser")]
|
|
[HttpPost("SaveImage")]
|
|
public async Task<SaveImageResponse> SaveImage(SaveImageRequest request)
|
|
{
|
|
try
|
|
{
|
|
// Check image exists
|
|
|
|
|
|
// Check permissions of user
|
|
|
|
|
|
|
|
// Get image data
|
|
var data = request.Payload.Data;
|
|
|
|
// Save to file
|
|
await System.IO.File.WriteAllBytesAsync("c:\\temp\\test_image1.img", data);
|
|
|
|
return new SaveImageResponse() { Success = true, Payload = new SaveImageResponsePayload() { BytesSaved = data.Length } };
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
return new SaveImageResponse() { Success = false, Error = GetExceptionPayload(e) };
|
|
}
|
|
}
|
|
}
|