Spice过滤键盘鼠标的另类方法

本实验基于Spice-gtk:https://gitlab.freedesktop.org/spice/spice-gtk

在Spice-GTK中的 usb-device-manager.c 中,当我们热插拔USB设备时就会触发到 spice_usb_device_manager_hotplug_idle_cb 函数

static gboolean spice_usb_device_manager_hotplug_idle_cb(gpointer user_data)
{
    struct hotplug_idle_cb_args *args = user_data;
    SpiceUsbDeviceManager *manager = SPICE_USB_DEVICE_MANAGER(args->manager);

    if (args->added) {
        //添加设备时
        spice_usb_device_manager_add_dev(manager, args->device);
    } else {
        //移除设备时
        spice_usb_device_manager_remove_dev(manager, args->device);
    }

    spice_usb_backend_device_unref(args->device);
    g_object_unref(manager);
    g_free(args);
    return FALSE;
}

下面,跟着添加设备的函数来看一下内部的逻辑

static void spice_usb_device_manager_add_dev(SpiceUsbDeviceManager *manager, SpiceUsbDevice *bdev)
{
    SpiceUsbDeviceManagerPrivate *priv = manager->priv;
    const UsbDeviceInformation *b_info = spice_usb_backend_device_get_info(bdev);
    SpiceUsbDevice *device;

    //首先在设备列表中找到这个设备
    if (spice_usb_device_manager_find_device(manager, b_info->bus, b_info->address)) {
        SPICE_DEBUG("device not added %d:%d %04x:%04x",
                    b_info->bus, b_info->address, b_info->vid, b_info->pid);
        return;
    }

    //对设备的引用加一
    device = spice_usb_device_new(bdev);
    if (!device) {
        return;
    }
    
    //---------在这添加的过滤代码---------
    if (spice_usb_filter_mouse(device)) {
        return;
    }

    g_ptr_array_add(priv->devices, device);

    if (priv->auto_connect) {
        gboolean can_redirect, auto_ok;

        can_redirect = spice_usb_device_manager_can_redirect_device(manager, device, NULL);

        auto_ok = spice_usb_backend_device_check_filter(bdev,
                                                        priv->auto_conn_filter_rules,
                                                        priv->auto_conn_filter_rules_count) == 0;

        if (can_redirect && auto_ok) {
            spice_usb_device_manager_connect_device_async(manager, device, NULL,
                                                          spice_usb_device_manager_auto_connect_cb,
                                                          spice_usb_device_ref(device));
        }
    }

    SPICE_DEBUG("device added %04x:%04x (%p)",
                spice_usb_device_get_vid(device),
                spice_usb_device_get_pid(device),
                device);
    g_signal_emit(manager, signals[DEVICE_ADDED], 0, device);
}

下面的函数为在 spice_usb_device_manager_add_dev 函数中调用的函数 (可以略过)

//对比 bus 和 address 就是命令 lsusb -D /dev/bus/usb/xxx/xxx 的两个参数
//日志:libusb: debug [linux_get_device_address] bus=4 dev=2
//日志:GSpice-DEBUG: 11:12:10.519: usb-device-manager.c:1111 ---->bus:4  address:0x2
static gboolean spice_usb_device_match(SpiceUsbDevice *device, const int bus, const int address)
{
    return (spice_usb_device_get_busnum(device) == bus &&
            spice_usb_device_get_devaddr(device) == address);
}

//遍历设备列表,然后找到匹配bus号和address号的USB设备,并返回
static SpiceUsbDevice*
spice_usb_device_manager_find_device(SpiceUsbDeviceManager *manager, const int bus, const int address)
{
    SpiceUsbDeviceManagerPrivate *priv = manager->priv;
    SpiceUsbDevice *curr, *device = NULL;
    guint i;

    for (i = 0; i < priv->devices->len; i++) {
        curr = g_ptr_array_index(priv->devices, i);
        if (spice_usb_device_match(curr, bus, address)) {
            device = curr;
            break;
        }
    }
    return device;
}

static SpiceUsbDevice *spice_usb_device_new(SpiceUsbDevice *bdev)
{
    g_return_val_if_fail(bdev != NULL, NULL);
    return spice_usb_backend_device_ref(bdev);
}

//这个函数在usb-backend.c中
SpiceUsbDevice *spice_usb_backend_device_ref(SpiceUsbDevice *dev)
{
    LOUD_DEBUG("%s >> %p", __FUNCTION__, dev);
    //原子整数操作 对引用计数加一
    g_atomic_int_inc(&dev->ref_count);
    return dev;
}

添加的函数如下

gboolean spice_usb_filter_mouse(SpiceUsbDevice *device) 
{
#ifdef USE_USBREDIR
    int e = 0;
    char str2[256];
    struct libusb_device_handle *handle = NULL;
    struct libusb_device_descriptor desc;
    
    //描述符的获取
    r = libusb_get_device_descriptor(device, &desc);    
    if (r < 0)    
    {    
        return TRUE;    
    }
    
    e = libusb_open(libdev, &handle);
    if (e < 0)    
    {    
        return TRUE;     
    }  

    e = libusb_get_string_descriptor_ascii(handle, libdesc.iProduct, (unsigned char*) str2, sizeof(str2));
    if(e < 0)    
    {
        return TRUE;    
    }
    SPICE_DEBUG("Product : %s",str2);
    
    if (strstr(str2, "Mouse")!= NULL){
        SPICE_DEBUG("鼠标设备");
        return TRUE;
    }
    else if(strstr(str2, "mouse") != NULL){
        SPICE_DEBUG("鼠标设备");
        return TRUE;
    }else{
        return FALSE
    }
    
    return TRUE;
#endif
    return TRUE;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值