USBIP解读及源码分析
+ -

USBIP虚拟控制器安装命令过程分析

2021-11-19 12 0

USBIP虚拟控制器其自带的安装命令为:

usbip.exe install -w

可以看到,这是一个明显的自定义命令。这里一个比较有意思的是对命令行进行解析,使用的函数是getopt_long。
在介绍这个命令之前,我们先介绍几个命令行参数的函数。

命令行的长短项之分

命令行分为长项和短项,我们一般使用的是短项,不过LINUX中也有大量的短项参数。

  • 命令行短项:短选项在参数前加一杠”-“,如ls -l
  • 命令行长项:长选项在参数前连续加两杠”—“,如ls —all,—block-size=SIZE

命令行解析函数

命令行解析函数有三个,分别为getopt、getopt_long、getopt_long_only,其函数声名如下:

#include <unistd.h>  
extern char *optarg;  
extern int optind, opterr, optopt;  
#include <getopt.h>

int getopt(int argc, char * const argv[],const char *optstring);  
int getopt_long(int argc, char * const argv[], const char *optstring, const struct option *longopts, int *longindex);  
int getopt_long_only(int argc, char * const argv[], const char *optstring, const struct option *longopts, int *longindex);

更多详见:https://blog.csdn.net/qq_33850438/article/details/80172275

USBIP的第一层命令行解析的命令支持如下结构:

    static const struct option opts[] = {
        { "debug",    no_argument,       NULL, 'd' },
        { "tcp-port", required_argument, NULL, 't' },
        { NULL,       0,                 NULL,  0 }
    };

可以看到,分别是否是DEBUG模式和TCP通讯的端口支持。我们的参数中并未输入,所以会跳出。我们这里重点看一下install的命令行。

install的命令行如下:

        .name  = "install",
        .fn    = usbip_install,
        .help  = "Install usbip vhci driver",
        .usage = usbip_install_usage

对应的执行函数如下:

int
usbip_install(int argc, char *argv[])
{
    if (!parse_opts(argc, argv)) {
        usbip_install_usage();
        return 1;
    }
    if (only_wdm)
        return install_vhci_wdm();
    if (only_ude)
        return install_vhci_ude();
    return install_vhci_both();
}
  • 参数解析失败,打印用法。
  • 是否是wdm,我们是,执行install_vhci_wdm
  • ude,另一种模式。未研究过,后面看一下。

我们继续看install_vhci_wdm函数。
该函数首先检查文件的完整性,需要检查的文件如下:

const char    *fnames[] = { "usbip_vhci.sys", "usbip_vhci.inf", "usbip_vhci.cat", "usbip_root.inf", NULL };

然后进行驱动包的安装:

static drv_info_t    drv_infos[] = {
    { "root", "usbip_root.inf", "Standard.NTamd64", "usbip-win VHCI Root", "USBIPWIN\\root\0", "ROOT\\USBIP\\root", "System" },
    { "vhci(wdm)", "usbip_vhci.inf", "Standard.NTamd64", "usbip-win VHCI", "USBIPWIN\\vhci", NULL, NULL },
    { "vhci(ude)", "usbip_vhci_ude.inf", "Standard.NTamd64", "usbip-win VHCI(ude)", "root\\vhci_ude", "ROOT\\USB\\0000", "USB" },
    { "vhub(wdm)", "usbip_vhub.inf", "Standard.NTamd64", "usbip-win VHCI", "USB\\ROOT_HUB&VID1209&PID8250&REV0000", NULL, NULL }
};

使用install_driver_package进行包的安装,分别是usbip_vhci.inf和usbip_vhub.inf对应的结构体。
然后使用install_vhci安装USB虚拟控制器,执行的是:

{ "root", "usbip_root.inf", "Standard.NTamd64", "usbip-win VHCI Root", "USBIPWIN\\root\0", "ROOT\\USBIP\\root", "System" },

install_driver_package函数内部主要是使用SetupCopyOEMInf来实现的,只不过传递的是inf的全路径。

install_vhci的功能相对install_driver_package多一些,主要功能是:

  • 使用SetupDiOpenDeviceInfo函数判断是否存在。
  • 判断包是否存在,如果在,卸载掉。
  • install_driver_package安装驱动包
  • 使用install_device 创建设备信息并安装根控制器设备

0 篇笔记 写笔记

作者信息
USB中文网
Windows驱动开发,网站开发
好好学习,天天向上。
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

您的支持,是我们前进的动力!