mirror of
https://github.com/kwsch/NHSE.git
synced 2026-04-21 07:57:25 -05:00
165 lines
5.0 KiB
C#
165 lines
5.0 KiB
C#
using System;
|
|
using System.Threading;
|
|
using LibUsbDotNet;
|
|
using LibUsbDotNet.Main;
|
|
|
|
namespace NHSE.Injection
|
|
{
|
|
public class USBBot : IRAMReadWriter
|
|
{
|
|
private UsbDevice? SwDevice;
|
|
private UsbEndpointReader? reader;
|
|
private UsbEndpointWriter? writer;
|
|
|
|
public bool Connected { get; private set; }
|
|
|
|
private readonly object _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.Vid == 1406 && ur.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 != null)
|
|
{
|
|
if (SwDevice.IsOpen)
|
|
{
|
|
if (SwDevice is IUsbDevice wholeUsbDevice)
|
|
wholeUsbDevice.ReleaseInterface(0);
|
|
SwDevice.Close();
|
|
}
|
|
}
|
|
|
|
reader?.Dispose();
|
|
writer?.Dispose();
|
|
Connected = false;
|
|
}
|
|
}
|
|
|
|
private int ReadInternal(byte[] buffer)
|
|
{
|
|
byte[] sizeOfReturn = new byte[4];
|
|
|
|
//read size, no error checking as of 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");
|
|
|
|
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 ec = writer.Write(BitConverter.GetBytes(pack), 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];
|
|
var _ = ReadInternal(buffer);
|
|
//return Decoder.ConvertHexByteStringToBytes(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);
|
|
}
|
|
}
|
|
}
|
|
}
|