using System.Runtime.InteropServices; using XFESystem.Core; namespace XFESystem.NativeRuntime.Application; internal sealed unsafe class NativeWorkspaceDevice : IWorkspaceBlockDevice { [DllImport("xfe_pal", EntryPoint="xfe_usb_storage_info")] internal static extern ulong Info(uint field); [DllImport("xfe_pal", EntryPoint="xfe_usb_storage_read")] private static extern int ReadNative(ulong lba,uint count,byte* data); [DllImport("xfe_pal", EntryPoint="xfe_usb_storage_write")] private static extern int WriteNative(ulong lba,uint count,byte* data); [DllImport("xfe_pal", EntryPoint="xfe_usb_storage_flush")] private static extern int FlushNative(); [DllImport("xfe_pal", EntryPoint="xfe_usb_storage_allow_workspace")] private static extern int AllowNative(ulong lba,uint count); public ulong SectorCount => Info(3); public void Read(ulong lba,Span destination) { if(destination.Length%512!=0)throw new IOException("USB read must use whole sectors."); while(!destination.IsEmpty) { int count=Math.Min(destination.Length,65536); fixed(byte* data=destination)if(ReadNative(lba,(uint)count/512,data)!=1)throw new IOException("USB sector read failed."); lba+=(uint)count/512;destination=destination[count..]; } } public void Write(ulong lba,ReadOnlySpan source) { if(source.Length%512!=0)throw new IOException("USB write must use whole sectors."); while(!source.IsEmpty) { int count=Math.Min(source.Length,65536); fixed(byte* data=source)if(WriteNative(lba,(uint)count/512,data)!=1)throw new IOException("USB workspace write failed; data was not reported saved."); lba+=(uint)count/512;source=source[count..]; } } public void Flush() { if(FlushNative()!=1)throw new IOException("USB cache synchronization failed."); } public void AllowWorkspace(ulong lba,uint sectors) { if(AllowNative(lba,sectors)!=1)throw new IOException("USB workspace write extent was refused."); } } internal static class NativeWorkspace { public static IWorkspaceBinaryStorage Open() { long end=NativePlatform.Milliseconds()+20000; while(NativeWorkspaceDevice.Info(1)==1&&NativePlatform.Milliseconds()