Replacing unknown exe with opensource
To make the experience fit your profile, pick a username and tell us what interests you.
We found and based on your interests.
extern crate hidapi;
use hidapi::HidApi;
fn main() {
let mut found = false;
match HidApi::new() {
Ok(api) => {
for device in api.device_list() {
if device.vendor_id() == 0x1a86 && device.product_id() == 0xe041 {
found = true;
println!(
"{:04x}:{:04x}, {:?}",
device.vendor_id(), device.product_id(), device.serial_number()
);
match device.open_device(&api){
Ok(hid_device) => {
let data = [0x00, 0x55, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
match hid_device.write(&data) {
Ok(result) => {
eprintln!("write: {}", result);
},
Err(e) => {
eprintln!("write Error: {}", e);
}
}
},
Err(e) => {
eprintln!("Open Error: {}", e);
}
}
}
}
},
Err(e) => {
eprintln!("HIDApi Error: {}", e);
},
}
if !found {
println!("No device found");
}
}
PS C:\Users\Stephen\Documents\GitHub\USBSwitch\Rust> cargo build Finished dev [unoptimized + debuginfo] target(s) in 0.02s PS C:\Users\Stephen\Documents\GitHub\USBSwitch\Rust> .\target\debug\usbshare.exe No device found PS C:\Users\Stephen\Documents\GitHub\USBSwitch\Rust> .\target\debug\usbshare.exe 1a86:e041, None write: 9
That was surprisingly not hard. Sometimes the write fails, but it still switches, I think it switches before/while sending the ACK.
Trying linux.
stephen@AO751h:~/Documents/usbshare/usbshare$ cargo build
Compiling usbshare v0.1.0 (/home/stephen/Documents/usbshare/usbshare)
Finished dev [unoptimized + debuginfo] target(s) in 3.07s
stephen@AO751h:~/Documents/usbshare/usbshare$ ./target/debug/usbshare
1a86:e041, None
Open Error: Failed opening hid device
stephen@AO751h:~/Documents/usbshare/usbshare$ ls -alh /dev/hidraw0
crw-rw-r-- 1 root plugdev 243, 0 Sep 19 21:17 /dev/hidraw0
stephen@AO751h:~/Documents/usbshare/usbshare$ sudo ./target/debug/usbshare
[sudo] password for stephen:
1a86:e041, None
write Error: hidapi error: hid_error is not implemented yet
Sudo works.
Oh, udev again, Rust HID is using "0002:0003:00" instead of "/dev/hidraw#". New udev rules:
#works for pyusb control access, and rust hid SUBSYSTEM=="usb", ATTR{idVendor}=="1a86", ATTR{idProduct}=="e041", MODE="0664", GROUP="plugdev" #works or chrome WebHID KERNEL=="hidraw*", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="e041", MODE="0664", GROUP="plugdev"
stephen@AO751h:~/Documents/usbshare/usbshare$ sudo nano /etc/udev/rules.d/99-hid.rules
stephen@AO751h:~/Documents/usbshare/usbshare$ ./target/debug/usbshare
1a86:e041, None, "0002:0007:00"
Open Error: Failed opening hid device
stephen@AO751h:~/Documents/usbshare/usbshare$ sudo udevadm control --reload-rules
stephen@AO751h:~/Documents/usbshare/usbshare$ sudo udevadm trigger
stephen@AO751h:~/Documents/usbshare/usbshare$ ./target/debug/usbshare
1a86:e041, None, "0002:0007:00"
write Error: hidapi error: hid_error is not implemented yet
Success.
Doesn't work on linux. Udev strikes again. udev helper things:
sudo udevadm control --reload-rules
sudo udevadm trigger
journalctl -f
udevadm monitor --environment
udevadm info -q all -a /sys/devices/pci0000:00/0000:00:1d.0/usb2/2-2
udevadm info -q all -a /dev/hidraw1
sudo udevadm control --log-priority=dubug
run udevadm monitor --environment
and re-plug:
stephen@AO751h:~$ udevadm info -q all -a /dev/hidraw1
Udevadm info starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.
looking at device '/devices/pci0000:00/0000:00:1d.0/usb2/2-2/2-2:1.0/0003:1A86:E041.000E/hidraw/hidraw1':
KERNEL=="hidraw1"
SUBSYSTEM=="hidraw"
DRIVER==""
looking at parent device '/devices/pci0000:00/0000:00:1d.0/usb2/2-2/2-2:1.0/0003:1A86:E041.000E':
KERNELS=="0003:1A86:E041.000E"
SUBSYSTEMS=="hid"
DRIVERS=="hid-generic"
ATTRS{country}=="00"
looking at parent device '/devices/pci0000:00/0000:00:1d.0/usb2/2-2/2-2:1.0':
KERNELS=="2-2:1.0"
SUBSYSTEMS=="usb"
DRIVERS=="usbhid"
ATTRS{authorized}=="1"
ATTRS{bAlternateSetting}==" 0"
ATTRS{bInterfaceClass}=="03"
ATTRS{bInterfaceNumber}=="00"
ATTRS{bInterfaceProtocol}=="00"
ATTRS{bInterfaceSubClass}=="00"
ATTRS{bNumEndpoints}=="01"
ATTRS{supports_autosuspend}=="1"
looking at parent device '/devices/pci0000:00/0000:00:1d.0/usb2/2-2':
KERNELS=="2-2"
SUBSYSTEMS=="usb"
DRIVERS=="usb"
ATTRS{authorized}=="1"
ATTRS{avoid_reset_quirk}=="0"
ATTRS{bConfigurationValue}=="1"
ATTRS{bDeviceClass}=="00"
ATTRS{bDeviceProtocol}=="00"
ATTRS{bDeviceSubClass}=="00"
ATTRS{bMaxPacketSize0}=="8"
ATTRS{bMaxPower}=="100mA"
ATTRS{bNumConfigurations}=="1"
ATTRS{bNumInterfaces}==" 1"
ATTRS{bcdDevice}=="1000"
ATTRS{bmAttributes}=="80"
ATTRS{busnum}=="2"
ATTRS{configuration}==""
ATTRS{devnum}=="12"
ATTRS{devpath}=="2"
ATTRS{idProduct}=="e041"
ATTRS{idVendor}=="1a86"
ATTRS{ltm_capable}=="no"
ATTRS{maxchild}=="0"
ATTRS{quirks}=="0x0"
ATTRS{removable}=="unknown"
ATTRS{rx_lanes}=="1"
ATTRS{speed}=="12"
ATTRS{tx_lanes}=="1"
ATTRS{urbnum}=="14"
ATTRS{version}==" 1.10"
looking at parent device '/devices/pci0000:00/0000:00:1d.0/usb2':
KERNELS=="usb2"
SUBSYSTEMS=="usb"
DRIVERS=="usb"
ATTRS{authorized}=="1"
ATTRS{authorized_default}=="1"
ATTRS{avoid_reset_quirk}=="0"
ATTRS{bConfigurationValue}=="1"
ATTRS{bDeviceClass}=="09"
ATTRS{bDeviceProtocol}=="00"
ATTRS{bDeviceSubClass}=="00"
ATTRS{bMaxPacketSize0}=="64"
ATTRS{bMaxPower}=="0mA"
ATTRS{bNumConfigurations}=="1"
ATTRS{bNumInterfaces}==" 1"
ATTRS{bcdDevice}=="0504"
ATTRS{bmAttributes}=="e0"
ATTRS{busnum}=="2"
ATTRS{configuration}==""
ATTRS{devnum}=="1"
ATTRS{devpath}=="0"
ATTRS{idProduct}=="0001"
ATTRS{idVendor}=="1d6b"
ATTRS{interface_authorized_default}=="1"
ATTRS{ltm_capable}=="no"
ATTRS{manufacturer}=="Linux 5.4.0-77-generic uhci_hcd"
ATTRS{maxchild}=="2"
ATTRS{product}=="UHCI Host Controller"
ATTRS{quirks}=="0x0"
ATTRS{removable}=="unknown"
ATTRS{rx_lanes}=="1"
ATTRS{serial}=="0000:00:1d.0"
ATTRS{speed}=="12"
ATTRS{tx_lanes}=="1"
ATTRS{urbnum}=="207"
ATTRS{version}==" 1.10"
looking at parent device '/devices/pci0000:00/0000:00:1d.0':
KERNELS=="0000:00:1d.0"
SUBSYSTEMS=="pci"
DRIVERS=="uhci_hcd"
ATTRS{ari_enabled}=="0"
ATTRS{broken_parity_status}=="0"
ATTRS{class}=="0x0c0300"
ATTRS{consistent_dma_mask_bits}=="32"
ATTRS{d3cold_allowed}=="0"
ATTRS{device}=="0x8114"
ATTRS{dma_mask_bits}=="32"
ATTRS{driver_override}=="(null)"
ATTRS{enable}=="1"
ATTRS{irq}=="23"
ATTRS{local_cpulist}=="0-1"
ATTRS{local_cpus}=="3"
ATTRS{msi_bus}=="1"
ATTRS{revision}=="0x07"
ATTRS{subsystem_device}=="0x0244"
ATTRS{subsystem_vendor}=="0x1025"
ATTRS{vendor}=="0x8086"
looking at parent device '/devices/pci0000:00':
KERNELS=="pci0000:00"
SUBSYSTEMS==""
DRIVERS==""
...
Read more »
document.addEventListener('DOMContentLoaded', async () => {
let permissionsRequestButton = document.getElementById("switch");
permissionsRequestButton.addEventListener("click", () => {
navigator.hid.requestDevice({
filters: [{ vendorId: 0x1a86, productId: 0xe041 }]
}).then((devices) =>{
devices[0].open().then(() => {
const wValue = new Uint8Array([
0x55, 0x02, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00
]);
devices[0].sendReport(0, wValue).then(() => {
console.log("Sent output report: "+ wValue);
}).catch(err => {
console.log(err + " " + wValue)
})
})
});
});
});
I guess I only really need the one USBHID SET_REPORT
import usb.core
import usb.util
import usb.control
# find our device
dev = usb.core.find(idVendor=0x1a86, idProduct=0xe041)
# was it found?
if dev is None:
raise ValueError('Device not found')
# usb.control.set_configuration(dev, 0)
bmRequestType = usb.util.build_request_type(usb.util.CTRL_OUT, usb.util.CTRL_TYPE_STANDARD, usb.util.CTRL_RECIPIENT_DEVICE) #// should be 0x00
bRequest = 0x09
bConfigurationValue = 1
wIndex = 0
wLength = 0
dev.ctrl_transfer(bmRequestType, bRequest, bConfigurationValue)
dev.ctrl_transfer(bmRequestType, bRequest, bConfigurationValue)
Doesn't work though. PyUSB sent out a message that was 64 long instead of the 36.
Unless that is libusb doing the padding, IDK.
I don't know if the device keys off the length, or if it is missing the other hid messages first.
The mystery exe runs in wine and puts the icon in the panel, but doesn't send off any usb communication though.
I noticed that the last SET_REPORT differed from the previous pile of SET_REPORT
Then55 02 00 00 00 00 00 00
Switching to hid I guess.
libhidapi-hidraw0 won't open the device, and libhidapi-libusb.so.0 won't accept the buffer "ctypes.ArgumentError: argument 2: <type 'exceptions.TypeError'>: wrong type"
import hid
hid.lib
# libhidapi-hidraw0
# hid.HIDException: unable to open device
h = hid.Device(vid, pid)
h.open(vid, pid)
buf = [0]*8
buf[0] = 0x55
buf[1] = 0x01
#libhidapi-libusb.so.0
#ctypes.ArgumentError: argument 2: <type 'exceptions.TypeError'>: wrong type
h.send_feature_report([0x55, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])
h.send_feature_report([0x55, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])
Trying to find a quick way to test writing out a single usb message, I didn't find any test programs.
Nirsoft USBDeview, and microsoft usbview.exe helped see the devices, but that was it.
HIDPyToy didn't help, because I needed to send a non-hid message.
Now I'm looking at webusb, https://wicg.github.io/webusb/#enumdef-usbrequesttype
It won't be useful, but it might be an easy test, and easy to port...? Should look something like:
device = await navigator.usb.requestDevice({
filters: [{
vendorId: device.vendorId,
productId: device.productId
}]
});
await device.open();
await device.controlTransferOut({
requestType: 'standard',
recipient: 'device',
request: 0x09,
value: 0x01,
index: 0x00
})
Device.open -> DOMException: Access denied. Looks like a windows problem.
Ok, trying linux. ... no chrome installed. installing chromium. navigator.usb doesn't exist on chromium 92. Should be in since chrome 61. Maybe it is just stripped out of chromium. Downloading to be a local file worked, oh HTTPS only. DOMException: Access denied. Added udev rule. not fixed. maybe udev didn't work
Maybe I should have checked usb-internals first. It looks like the "Testing Tool Panel" is what I wanted. I'm guessing the error is the same permissions error.
The usb hub has 2 un-connected ports. the 4 CH440G look to be the actual switches. CH9884 doesn't seem to have any data sheets online.
When the port is selected, it connects a generic usb hub. same Vendor/Product as a Monoprice "aquamini".
When the main hub is disconnected, it connects a device to the bus instead:
idVendor: 0x1A86 = Nanjing Qinherg Electronics Co., Ltd.
idProduct: 0xE041
Which I'm guessing is CH9884
The "Drivers" cd was a burned cd rom with USBShare.exe, and an installer, that I assume puts it somewhere and adds it to startup. I didn't run the installer. Running strings on the exe showed some usb.
VID_1A86&PID_E041
VID_1A86&PID_E040
VID_5131&PID_2007
I ran the exe through ghidra, to see if I could find anything, but I didn't find much. the USB identifiers, and some other strings. \(〇_o)/ I don't have the patience for this. I just decided to run the exe, and wireshark it.
Well, it puts a it turns green when connected to the usb hub, and ... well it turns green when not connected too. Turns red, then yellow when switching away.
In yellow state, the program continuously asks (I think it is just connected checks?):
Frame 31356: 44 bytes on wire (352 bits), 44 bytes captured (352 bits) on interface wireshark_extcap2440, id 0
USB URB
[Source: host]
[Destination: 2.4.0]
USBPcap pseudoheader length: 28
IRP ID: 0xffff898c72c27010
IRP USBD_STATUS: USBD_STATUS_SUCCESS (0x00000000)
URB Function: URB_FUNCTION_CLASS_INTERFACE (0x001b)
IRP information: 0x00, Direction: FDO -> PDO
0000 000. = Reserved: 0x00
.... ...0 = Direction: FDO -> PDO (0x0)
URB bus id: 2
Device address: 4
Endpoint: 0x00, Direction: OUT
0... .... = Direction: OUT (0)
.... 0000 = Endpoint number: 0
URB transfer type: URB_CONTROL (0x02)
Packet Data Length: 16
[Response in: 31357]
Control transfer stage: Setup (0)
[bInterfaceClass: HID (0x03)]
Setup Data
bmRequestType: 0x21
0... .... = Direction: Host-to-device
.01. .... = Type: Class (0x1)
...0 0001 = Recipient: Interface (0x01)
bRequest: SET_REPORT (0x09)
wValue: 0x0200
ReportID: 0
ReportType: Output (2)
wIndex: 0
wLength: 8
bRequest: 9
wValue: 0x0200
wIndex: 0 (0x0000)
wLength: 8
Data Fragment: 5501000000000000
In yellow state, "Switch" gets enabled,
Frame 31702: 36 bytes on wire (288 bits), 36 bytes captured (288 bits) on interface wireshark_extcap2440, id 0
USB URB
[Source: host]
[Destination: 2.4.0]
USBPcap pseudoheader length: 28
IRP ID: 0xffff898c81fc6970
IRP USBD_STATUS: USBD_STATUS_SUCCESS (0x00000000)
URB Function: URB_FUNCTION_SELECT_CONFIGURATION (0x0000)
IRP information: 0x00, Direction: FDO -> PDO
0000 000. = Reserved: 0x00
.... ...0 = Direction: FDO -> PDO (0x0)
URB bus id: 2
Device address: 4
Endpoint: 0x00, Direction: OUT
0... .... = Direction: OUT (0)
.... 0000 = Endpoint number: 0
URB transfer type: URB_CONTROL (0x02)
Packet Data Length: 8
[Response in: 31705]
Control transfer stage: Setup (0)
Setup Data
bmRequestType: 0x00
0... .... = Direction: Host-to-device
.00. .... = Type: Standard (0x0)
...0 0000 = Recipient: Device (0x00)
bRequest: SET CONFIGURATION (9)
bConfigurationValue: 1
wIndex: 0 (0x0000)
wLength: 0
So, I guess that is it.
Create an account to leave a comment. Already have an account? Log In.
Never know about this device earlier. It is hard work, to share usb between hosts on the fly.
I am wonder why USB was not designed to work as a bus, like Ethernet.
Become a member to follow this project and never miss any updates
Found this project while also looking for a datasheet for the CH9884 (have the same switcher)
Cool project, definitely gives me some inspiration!