NHSE/NHSE.Injection/SysBot/USBBot.cs
DESKTOP-SN9KF5O\Strawberry 1fcab7070e Remove Decoder entirely
2026-01-30 03:12:41 +00:00

161 lines
4.5 KiB
C#

using System;
using System.Threading;
using LibUsbDotNet;
using LibUsbDotNet.Main;
using static System.Buffers.Binary.BinaryPrimitives;
namespace NHSE.Injection;
public sealed class USBBot : IRAMReadWriter
{
private UsbDevice? SwDevice;
private UsbEndpointReader? reader;
private UsbEndpointWriter? writer;
public bool Connected { get; private set; }
private readonly Lock _sync = new();
public bool Connect()
{
lock (_sync)
{
// Find and open the usb device.
//SwDevice = UsbDevice.OpenUsbDevice(SwFinder);
foreach (UsbRegistry ur in UsbDevice.AllDevices)
{
if (ur is { Vid: 1406, Pid: 12288 })
SwDevice = ur.Device;
}
//SwDevice = UsbDevice.OpenUsbDevice(MyUsbFinder);
// If the device is open and ready
if (SwDevice == null)
{
throw new Exception("Device Not Found.");
}
if (SwDevice.IsOpen)
SwDevice.Close();
SwDevice.Open();
if (SwDevice is IUsbDevice wholeUsbDevice)
{
// This is a "whole" USB device. Before it can be used,
// the desired configuration and interface must be selected.
// Select config #1
wholeUsbDevice.SetConfiguration(1);
// Claim interface #0.
bool resagain = wholeUsbDevice.ClaimInterface(0);
if (!resagain)
{
wholeUsbDevice.ReleaseInterface(0);
wholeUsbDevice.ClaimInterface(0);
}
}
else
{
Disconnect();
throw new Exception("Device is using WinUSB driver. Use libusbK and create a filter");
}
// open read write endpoints 1.
reader = SwDevice.OpenEndpointReader(ReadEndpointID.Ep01);
writer = SwDevice.OpenEndpointWriter(WriteEndpointID.Ep01);
Connected = true;
return true;
}
}
public void Disconnect()
{
lock (_sync)
{
if (SwDevice is { IsOpen: true })
{
if (SwDevice is IUsbDevice wholeUsbDevice)
wholeUsbDevice.ReleaseInterface(0);
SwDevice.Close();
}
reader?.Dispose();
writer?.Dispose();
Connected = false;
}
}
private int ReadInternal(byte[] buffer)
{
//read size, no error checking yet, should be the required 368 bytes
if (reader == null)
throw new Exception("USB writer is null, you may have disconnected the device during previous function");
var sizeOfReturn = new byte[4];
reader.Read(sizeOfReturn, 5000, out _);
//read stack
reader.Read(buffer, 5000, out var lenVal);
return lenVal;
}
private int SendInternal(byte[] buffer)
{
if (writer == null)
throw new Exception("USB writer is null, you may have disconnected the device during previous function");
uint pack = (uint)buffer.Length + 2;
var lengthBytes = new byte[sizeof(uint)];
WriteUInt32LittleEndian(lengthBytes, pack);
var ec = writer.Write(lengthBytes, 2000, out _);
if (ec != ErrorCode.None)
{
Disconnect();
throw new Exception(UsbDevice.LastErrorString);
}
ec = writer.Write(buffer, 2000, out var l);
if (ec != ErrorCode.None)
{
Disconnect();
throw new Exception(UsbDevice.LastErrorString);
}
return l;
}
public int Read(byte[] buffer)
{
lock (_sync)
{
return ReadInternal(buffer);
}
}
public byte[] ReadBytes(uint offset, int length)
{
lock (_sync)
{
var cmd = SwitchCommand.PeekRaw(offset, length);
SendInternal(cmd);
// give it time to push data back
Thread.Sleep((length / 256) + 100);
var buffer = new byte[length];
_ = ReadInternal(buffer);
return buffer;
}
}
public void WriteBytes(byte[] data, uint offset)
{
lock (_sync)
{
SendInternal(SwitchCommand.PokeRaw(offset, data));
// give it time to push data back
Thread.Sleep((data.Length / 256) + 100);
}
}
}