// /*************************************************************************** // Aaru Data Preservation Suite // ---------------------------------------------------------------------------- // // Filename : Structs.cs // Author(s) : Natalia Portillo // // Component : Aaru Remote. // // --[ Description ] ---------------------------------------------------------- // // Structures for the Aaru Remote protocol. // // --[ License ] -------------------------------------------------------------- // // This library is free software; you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as // published by the Free Software Foundation; either version 2.1 of the // License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, see . // // ---------------------------------------------------------------------------- // Copyright © 2011-2025 Natalia Portillo // ****************************************************************************/ // ReSharper disable MemberCanBeInternal // ReSharper disable MemberCanBePrivate.Global // ReSharper disable FieldCanBeMadeReadOnly.Global // ReSharper disable IdentifierTypo using System.Runtime.InteropServices; using Aaru.CommonTypes.Enums; using Aaru.Decoders.ATA; namespace Aaru.Devices.Remote; /// Header for any Aaru remote packet [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketHeader { /// Unique Aaru packet identifier (primary) public uint remote_id; /// Unique Aaru packet identifier (secondary) public uint packet_id; /// Packet length public uint len; /// Packet version public byte version; /// Unique Aaru packet type identifier public AaruPacketType packetType; /// Spare for expansion (or alignment) [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public readonly byte[] spare; } /// Hello packet, identifies a remote initiator with a responder [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketHello { /// Packet header public AaruPacketHeader hdr; /// Application name [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string application; /// Application version [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] public string version; /// Maximum supported protocol version public byte maxProtocol; /// Spare for expansion (or alignment) [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public readonly byte[] spare; /// Operating system name [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string sysname; /// Operating system version / release [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string release; /// Operating system machine / architecture [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string machine; } /// Request a list of device [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketCommandListDevices { /// Packet header public AaruPacketHeader hdr; } /// Returns the requested list of devices [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public readonly struct AaruPacketResponseListDevices { /// Packet header public readonly AaruPacketHeader hdr; /// How many device descriptors follows this structure in the packet public readonly ushort devices; } /// Sends a request or returns a response that requires no intervention or further processing [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketNop { /// Packet header public AaruPacketHeader hdr; /// Reason code public AaruNopReason reasonCode; /// Spare for expansion (or alignment) [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public readonly byte[] spare; /// Reason name [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string reason; /// Operating system error number public int errno; } /// Requests to open a device [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketCommandOpenDevice { /// Packet header public AaruPacketHeader hdr; /// Device path [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1024)] public string device_path; } /// /// Requests remote to send a command to a SCSI device. This header is followed by the CDB and after it comes the /// buffer. /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketCmdScsi { /// Packet header public AaruPacketHeader hdr; /// Length in bytes of the CDB that follows this structure public uint cdb_len; /// Length in bytes of the buffer that follows the CDB public uint buf_len; /// Direction of SCSI data transfer public int direction; /// Timeout waiting for device to respond to command public uint timeout; } /// /// Returns the response from a command sent to a SCSI device. This structure is followed by the buffer containing /// the REQUEST SENSE response and this is followed by the data buffer. /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketResScsi { /// Packet header public AaruPacketHeader hdr; /// Size the REQUEST SENSE buffer that follows this structure public uint sense_len; /// Length in bytes of the data buffer that follows the sense buffer public uint buf_len; /// Time in milliseconds it took for the device to execute the command public uint duration; /// Set to anything different of zero if there was a SENSE returned public uint sense; /// Set to the remote operating system error number public uint error_no; } /// /// Requests remote to send a command to an ATA device using the CHS command set. This header is followed by the /// data buffer. /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketCmdAtaChs { /// Packet header public AaruPacketHeader hdr; /// Length in bytes of the data buffer public uint buf_len; /// Registers to set in the ATA device public AtaRegistersChs registers; /// ATA protocol code public byte protocol; /// ATA transfer register indicator public byte transferRegister; /// Set to true to transfer blocks, false to transfer bytes [MarshalAs(UnmanagedType.U1)] public bool transferBlocks; /// Spare for expansion (or alignment) public byte spare; /// Timeout waiting for device to respond to command public uint timeout; } /// /// Returns the response from a command sent to an ATA device using the CHS command set. This structure is /// followed by the data buffer. /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketResAtaChs { /// Packet header public AaruPacketHeader hdr; /// Length in bytes of the data buffer public uint buf_len; /// Registers as set back by the ATA device public AtaErrorRegistersChs registers; /// Time in milliseconds it took for the device to execute the command public uint duration; /// Set to anything different of zero if the device set an error condition public uint sense; /// Set to the remote operating system error number public uint error_no; } /// /// Requests remote to send a command to an ATA device using the 28-bit command set. This header is followed by /// the data buffer. /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketCmdAtaLba28 { /// Packet header public AaruPacketHeader hdr; /// Length in bytes of the data buffer public uint buf_len; /// Registers to set in the ATA device public AtaRegistersLba28 registers; /// ATA protocol code public byte protocol; /// ATA transfer register indicator public byte transferRegister; /// Set to true to transfer blocks, false to transfer bytes [MarshalAs(UnmanagedType.U1)] public bool transferBlocks; /// Spare for expansion (or alignment) public byte spare; /// Timeout waiting for device to respond to command public uint timeout; } /// /// Returns the response from a command sent to an ATA device using the 28-bit LBA command set. This structure is /// followed by the data buffer. /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketResAtaLba28 { /// Packet header public AaruPacketHeader hdr; /// Length in bytes of the data buffer public uint buf_len; /// Registers as set back by the ATA device public AtaErrorRegistersLba28 registers; /// Time in milliseconds it took for the device to execute the command public uint duration; /// Set to anything different of zero if the device set an error condition public uint sense; /// Set to the remote operating system error number public uint error_no; } /// /// Requests remote to send a command to an ATA device using the 48-bit command set. This header is followed by /// the data buffer. /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketCmdAtaLba48 { /// Packet header public AaruPacketHeader hdr; /// Length in bytes of the data buffer public uint buf_len; /// Registers to set in the ATA device public AtaRegistersLba48 registers; /// ATA protocol code public byte protocol; /// ATA transfer register indicator public byte transferRegister; /// Set to true to transfer blocks, false to transfer bytes [MarshalAs(UnmanagedType.U1)] public bool transferBlocks; /// Spare for expansion (or alignment) public byte spare; /// Timeout waiting for device to respond to command public uint timeout; } /// /// Returns the response from a command sent to an ATA device using the 48-bit LBA command set. This structure is /// followed by the data buffer. /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketResAtaLba48 { /// Packet header public AaruPacketHeader hdr; /// Length in bytes of the data buffer public uint buf_len; /// Registers as set back by the ATA device public AtaErrorRegistersLba48 registers; /// Time in milliseconds it took for the device to execute the command public uint duration; /// Set to anything different of zero if the device set an error condition public uint sense; /// Set to the remote operating system error number public uint error_no; } /// SecureDigital or MultiMediaCard command description [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruCmdSdhci { /// Command public MmcCommands command; /// Set to true if the command writes to the device, false otherwise [MarshalAs(UnmanagedType.U1)] public bool write; /// Set to true if it is an application command, false otherwise [MarshalAs(UnmanagedType.U1)] public bool application; /// Flags public MmcFlags flags; /// Argument public uint argument; /// Block size public uint block_size; /// Number of blocks to transfer public uint blocks; /// Length in bytes of the data buffer public uint buf_len; /// Timeout waiting for device to respond to command public uint timeout; } /// /// Requests remote to send a command to a SecureDigital or MultiMediaCard device attached using a SDHCI /// controller. This structure is followed by the data buffer. /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketCmdSdhci { /// Packet header public AaruPacketHeader hdr; /// SecureDigital or MultiMediaCard command description public AaruCmdSdhci command; } /// /// Returns the response from a command sent to a SecureDigital or MultiMediaCard device attached to a SDHCI /// controller. This structure is followed by the data buffer. /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruResSdhci { /// Length in bytes of the data buffer public uint buf_len; /// Response registers [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public uint[] response; /// Time in milliseconds it took for the device to execute the command public uint duration; /// Set to anything different of zero if the device set an error condition public uint sense; /// Set to the remote operating system error number public uint error_no; } /// /// Returns the response from a command sent to a SecureDigital or MultiMediaCard device attached to a SDHCI /// controller. This structure is followed by the data buffer. /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketResSdhci { /// Packet header public AaruPacketHeader hdr; /// Response public AaruResSdhci res; } /// Requests the Aaru device type for the opened device [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketCmdGetDeviceType { /// Packet header public AaruPacketHeader hdr; } /// Returns the Aaru device type for the opened device [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketResGetDeviceType { /// Packet header public AaruPacketHeader hdr; /// Aaru's device type public DeviceType device_type; } /// Requests the registers of a SecureDigital or MultiMediaCard attached to an SDHCI controller [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketCmdGetSdhciRegisters { /// Packet header public AaruPacketHeader hdr; } /// Returns the registers of a SecureDigital or MultiMediaCard attached to an SDHCI controller [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketResGetSdhciRegisters { /// Packet header public AaruPacketHeader hdr; /// /// true if the device is attached to an SDHCI controller and the rest of the fields on this packet are /// valid, false otherwise /// [MarshalAs(UnmanagedType.U1)] public bool isSdhci; /// CSD registers [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] csd; /// CID registers [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] cid; /// OCR registers [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public byte[] ocr; /// SCR registers [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] scr; /// Length of the CSD registers public uint csd_len; /// Length of the CID registers public uint cid_len; /// Length of the OCR registers public uint ocr_len; /// Length of the SCR registers public uint scr_len; } /// Requests information about the USB connection of the opened device [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketCmdGetUsbData { /// Packet header public AaruPacketHeader hdr; } /// Returns information about the USB connection of the opened device [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketResGetUsbData { /// Packet header public AaruPacketHeader hdr; /// /// true if the device is attached using USB and the rest of the fields on this packet are valid, /// false otherwise /// [MarshalAs(UnmanagedType.U1)] public bool isUsb; /// Length of the descriptors public ushort descLen; /// Raw USB descriptors [MarshalAs(UnmanagedType.ByValArray, SizeConst = 65536)] public byte[] descriptors; /// USB vendor ID public ushort idVendor; /// USB product ID public ushort idProduct; /// USB manufacturer string [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string manufacturer; /// USB product string [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string product; /// USB serial number string [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string serial; } /// Requests information about the FireWire connection of the opened device [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketCmdGetFireWireData { /// Packet header public AaruPacketHeader hdr; } /// Returns information about the FireWire connection of the opened device [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketResGetFireWireData { /// Packet header public AaruPacketHeader hdr; /// /// true if the device is attached using FireWire and the rest of the fields on this packet are valid, /// false otherwise /// [MarshalAs(UnmanagedType.U1)] public bool isFireWire; /// FireWire model ID public uint idModel; /// FireWire vendor ID public uint idVendor; /// FireWire's device GUID public ulong guid; /// FireWire vendor string [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string vendor; /// FireWire model string [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string model; } /// Requests information about the PCMCIA or CardBus connection of the opened device [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketCmdGetPcmciaData { /// Packet header public AaruPacketHeader hdr; } /// Returns information about the PCMCIA or CardBus connection of the opened device [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketResGetPcmciaData { /// Packet header public AaruPacketHeader hdr; /// /// true if the device is a PCMCIA or CardBus device and the rest of the fields on this packet are valid, /// false otherwise /// [MarshalAs(UnmanagedType.U1)] public bool isPcmcia; /// CIS buffer length public ushort cis_len; /// CIS buffer [MarshalAs(UnmanagedType.ByValArray, SizeConst = 65536)] public byte[] cis; } /// Requests to close the currently opened device [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketCmdClose { /// Packet header public AaruPacketHeader hdr; } /// Requests to know if the remote is running with administrative (aka root) privileges [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketCmdAmIRoot { /// Packet header public AaruPacketHeader hdr; } /// Returns if the remote is running with administrative (aka root) privileges [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketResAmIRoot { /// Packet header public AaruPacketHeader hdr; /// Set to any value different of 0 to indicate the remote is running with administrative (aka root) privileges public uint am_i_root; } /// Initiates a multiple command block with the SDHCI controller the SecureDigital or MultiMediaCard is attached [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketMultiCmdSdhci { /// Packet header public AaruPacketHeader hdr; /// How many commands to queue public ulong cmd_count; } /// Closes and then re-opens the same device [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketCmdReOpen { /// Packet header public AaruPacketHeader hdr; } /// Reads data using operating system buffers [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketCmdOsRead { /// Packet header public AaruPacketHeader hdr; /// Device offset where to read public ulong offset; /// Number of bytes to read public uint length; } /// Returns data read using operating system buffers. This structure is followed by the data buffer. [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct AaruPacketResOsRead { /// Packet header public AaruPacketHeader hdr; /// Set to the remote operating system error number public int errno; /// Time in milliseconds it took for the device to execute the command public uint duration; }