added windows support over usbip-win2

This commit is contained in:
2026-02-19 09:04:07 +01:00
parent 4d33063b82
commit e2a97fa774
8 changed files with 313 additions and 51 deletions
+16 -32
View File
@@ -23,7 +23,6 @@ type AttachedDevice struct {
RemoteDevice
TunnelID string `json:"tunnel_id"`
VHCIPort int `json:"vhci_port"`
SocketFD int `json:"socket_fd"`
}
// UseManager handles receiving/using remote USB devices
@@ -184,36 +183,22 @@ func (um *UseManager) DetachDevice(clientID, busID string) error {
}
func (um *UseManager) setupVHCI(clientID, busID string, granted *protocol.DeviceGranted) error {
// Create a socketpair - one end for VHCI, one for our tunnel
fds, err := createSocketPair()
if err != nil {
return fmt.Errorf("creating socketpair: %w", err)
// Look up device info from available list (needed for Windows management phase)
var devInfo *RemoteDevice
um.mu.RLock()
for _, d := range um.available[clientID] {
if d.BusID == busID {
cp := d
devInfo = &cp
break
}
}
um.mu.RUnlock()
vhciFD := fds[0]
tunnelFD := fds[1]
// Find a free VHCI port
port, err := usbip.FindFreePort(granted.Speed)
// Platform-specific VHCI attachment (Linux: socketpair+sysfs, Windows: TCP proxy+usbip.exe)
tunnelConn, vhciPort, err := createVHCIAttachment(um.client.ctx, granted, devInfo)
if err != nil {
closeFDs(fds)
return fmt.Errorf("finding free VHCI port: %w", err)
}
// Attach to VHCI
if err := usbip.AttachDevice(port, vhciFD, granted.DevID, granted.Speed); err != nil {
closeFDs(fds)
return fmt.Errorf("VHCI attach: %w", err)
}
// The VHCI driver now owns vhciFD, so we don't close it
// Create a net.Conn from the tunnel FD
tunnelFile := fdToFile(tunnelFD, "usb-tunnel")
tunnelConn, err := net.FileConn(tunnelFile)
tunnelFile.Close() // FileConn dups the fd
if err != nil {
usbip.DetachDevice(port)
return fmt.Errorf("creating tunnel conn: %w", err)
return fmt.Errorf("VHCI attachment: %w", err)
}
tunnel := &useTunnel{
@@ -233,19 +218,18 @@ func (um *UseManager) setupVHCI(clientID, busID string, granted *protocol.Device
ClientID: clientID,
},
TunnelID: granted.TunnelID,
VHCIPort: port,
SocketFD: vhciFD,
VHCIPort: vhciPort,
}
um.mu.Unlock()
// Start reading from the tunnel socket (VHCI -> relay)
go um.tunnelReadLoop(tunnel)
log.Printf("[use] device %s attached on VHCI port %d", key, port)
log.Printf("[use] device %s attached on VHCI port %d", key, vhciPort)
// Fix permissions on newly created device nodes (e.g. /dev/video*)
// VHCI-created devices don't get normal udev permissions
go fixVHCIDevicePermissions(port)
go fixVHCIDevicePermissions(vhciPort)
return nil
}