libusb编译使用 检测u盘卸载实例

最近项目用到了libusb,作为小菜鸟,简单总结一下,方便大家使用,其实对usb还是听感兴趣的,下此有机会把usb协议也去拜读一下,然后把usb驱动再学习学习。

libusb编译说明:

1、去官网下载libusb-1.0.23

2、tar -xvf libusb-1.0.23.tar.bz2

3、./configure --disable-udev --build=x86_64 --host=arm-linux --prefix=/home/cjj/mytoy/libusb-out CC=arm-linux-gcc --enable-udev–build自己PC机本地编译环境,–host生成到哪个目录,CC要用到哪个平台上面,注意配置自己交叉编译器

4、编译过程中难免出错,sudo apt-get install libusb-dev,sudo apt-get install libusb-1.0-0-dev, sudo apt-get install autoconf, sudo apt-get install libtool, sudo apt-get install xsltproc这一大串我都不信还报错

5、make && make install
会生成两个目录:一个是头文件,另一个是库,这里我使用的是静态库

cjj@cjj-MyThink:~/mytoy/libusb-debug$ ls include/libusb-1.0/libusb.h 
include/libusb-1.0/libusb.h

cjj@cjj-MyThink:~/mytoy/libusb-debug/lib$ ls
libusb-1.0.a  libusb-1.0.la  libusb-1.0.so  libusb-1.0.so.0  libusb-1.0.so.0.2.0  pkgconfig

编译方式链接本地静态库:

cjj@cjj-MyThink:~/mytoy/libusb-debug$ cat build.sh 
gcc -o usb_test usbtest.c -I./include/libusb-1.0/ -L./lib -lusb-1.0 -lpthread
libusb接口介绍:

此处注释一下原作者的地址,写的不错,这里我引用一下
https://blog.csdn.net/wince_lover/article/details/70337809
本文介绍几个实例中需要用到的:

int libusb_init(libusb_context **ctx);该函数进行libusb的初始化,必须最先调用。ctx通常设置NULL。返回值:0成功,非0 失败
void libusb_exit(libusb_context *ctx);和libusb_init成对使用,释放相应的资源。ctx通常设置NULL
int libusb_has_capability(uint32_t capability);功能说明:判断当前的库是否支持某项功能 参数说明:capability的取值范围在 enum libusb_capability中定义。LIBUSB_CAP_HAS_CAPABILITY libus库的 API是否有效,该项通常总是返回1 LIBUSB_CAP_HAS_HOTPLUG 是否支持热插拔 LIBUSB_CAP_HAS_HID_ACCESS 是否支持访问HID设备,而不需要用户干预
ssize_t LIBUSB_CALL libusb_get_device_list(libusb_context *ctx, libusb_device ***list);获取当前的设备列表, 返回值:0成功,非0 失败
int LIBUSB_CALL libusb_open(libusb_device *dev, libusb_device_handle **handle,dev libusb_device的指针);通过libusb_device的指针打开一个USB设备,并返回设备句柄libusb_device_handle的指针,返回值:0成功,非0 失败
void LIBUSB_CALL libusb_close(libusb_device_handle *dev_handle);函数功能:关闭 libusb_open或者libusb_open_device_with_vid_pid打开的设备 参数说明:dev_handle 调用libusb_open或者libusb_open_device_with_vid_pid返回的设备句柄libusb_device_handle的指针 返回值:无
int LIBUSB_CALL libusb_get_device_descriptor(libusb_device *dev, struct libusb_device_descriptor *desc);函数功能:获取USB设备的设备描述符 参数说明:dev libusb_device的指针,是要读取的设备 desc 设备描述符的指针,用来带回设备描述符的结构 注意:这个函数是将设备描述符的结构拷贝到desc指向的地址
int LIBUSB_CALL libusb_get_config_descriptor(libusb_device *dev, uint8_t config_index, struct libusb_config_descriptor **config);获取指定设备的配置描述符 dev libusb_device的指针,是要读取的设备 config_index 配置描述符的索引(一个USB设备可能有多个配置) config 配置描述符的指针,用来带回设备描述符
int LIBUSB_CALL libusb_kernel_driver_active(libusb_device_handle *dev,int interface_number);确定指定接口的内核驱动程序是否已经激活。如果一个内核驱动程序是激活的,libusb_claim_interface调用的会失败 返回值:1 已经激活,非1 没有激活
int LIBUSB_CALL libusb_detach_kernel_driver(libusb_device_handle *dev,int interface_number);函数功能:卸载指定接口的内核驱动程序。如果一个内核驱动程序是激活的,必须先调用这个函数,再调用libusb_claim_interface 返回值:0 成功,非0失败
int LIBUSB_CALL libusb_attach_kernel_driver(libusb_device_handle *dev, int interface_number);加载指定接口的内核驱动 返回值:0 成功,非0失败

废话不多说,下面实例主要实现的功能是通过libusb去卸载U盘,再加载U盘

#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <pthread.h>
#include <libusb-1.0/libusb.h>  

int get_configuration(libusb_device* dev, struct libusb_config_descriptor *config)
{
    int ret = 0;
    ret = libusb_get_config_descriptor(dev, 0, &config);
    return ret;
}

void usb_handler(void *dev_handler)
{
   libusb_device_handle *dev = (libusb_device_handle *)dev_handler;
   int c = getchar();
   printf("-------getchar is %d------\n", c);
   libusb_attach_kernel_driver(dev, 0);
}

static int KernelDriverDetached  = 0; /* set to 1 kernel driver detached */
static int dump_altsetting(libusb_device_handle *dev, const struct libusb_interface_descriptor *interface)
{
    //  char cls[128], subcls[128], proto[128];
    //  char *ifstr;

    //  get_class_string(cls, sizeof(cls), interface->bInterfaceClass);
    //  get_subclass_string(subcls, sizeof(subcls), interface->bInterfaceClass, interface->bInterfaceSubClass);
    //  get_protocol_string(proto, sizeof(proto), interface->bInterfaceClass, interface->bInterfaceSubClass, interface->bInterfaceProtocol);
    //  ifstr = get_dev_string(dev, interface->iInterface);

    printf("    Interface Descriptor:\n"
            "      bLength             %5u\n"
            "      bDescriptorType     %5u\n"
            "      bInterfaceNumber    %5u\n"
            "      bAlternateSetting   %5u\n"
            "      bNumEndpoints       %5u\n"
            "      bInterfaceClass     %5u\n"
            "      bInterfaceSubClass  %5u\n"
            "      bInterfaceProtocol  %5u\n",
            interface->bLength, interface->bDescriptorType, interface->bInterfaceNumber,
            interface->bAlternateSetting, interface->bNumEndpoints, interface->bInterfaceClass,
            interface->bInterfaceSubClass,interface->bInterfaceProtocol);

        if (interface->bInterfaceClass == 8) {
            fprintf(stdout, "this is a big Mass-storage\n");
            if (libusb_kernel_driver_active(dev, 0) > 0) {
                if (libusb_detach_kernel_driver(dev, 0) == 0) {
                    KernelDriverDetached = 1;
                    fprintf(stdout, "Mass-storage detach success\n");
                    pthread_t pid;
                    pthread_create(&pid, NULL, (void *)usb_handler, (void *)dev); /* 此处从中端获取一个字符,然后去重新挂载U盘 */
                } else {
                    fprintf(stdout, "Mass-storage detach fail\n");
                    return -1;
                }
            }            
        }
    //  free(ifstr);
        return 0;
}

static void dump_interface(libusb_device_handle *dev, const struct libusb_interface *interface)
{
    int i;
    for (i = 0; i < interface->num_altsetting; i++)
        dump_altsetting(dev, &interface->altsetting[i]);
}

static int list_devices(libusb_context *ctx)
{
    libusb_device **list;
    struct libusb_device_descriptor desc; /* device descriptor */
    struct libusb_config_descriptor* conf; /* config descriptor */

    libusb_device_handle *  handle = NULL;
    int config= 0;
    int ret;

    int status;
    ssize_t num_devs, i, j, k;

    status = 1; /* 1 device not found, 0 device found */

    num_devs = libusb_get_device_list(ctx, &list); /* Traverse the current number of USB devices and return the number of devices */
    if (num_devs < 0)
        goto error;

    for (i = 0; i < num_devs; ++i) {
        libusb_device *dev = list[i];
        libusb_open(dev,&handle); /* get the usb-device handle */

        //libusb_get_configuration(handle,&config); /* 之前调试某些平台这里会出现断错误 */

        uint8_t bnum = libusb_get_bus_number(dev);
        uint8_t dnum = libusb_get_device_address(dev);

        libusb_get_device_descriptor(dev, &desc);
        status = 0;
        printf("device:%04x:%04x\n",desc.idVendor,desc.idProduct);
        printf("bDeviceSubClass = %5u\n",desc.bDeviceSubClass);
        printf("bDeviceClass    = %5u\n",desc.bDeviceClass);
        printf("bDeviceProtocol    = %5u\n",desc.bDeviceProtocol);


        for( j = 0; j < desc.bNumConfigurations; ++j) {
            ret = libusb_get_config_descriptor(dev, j, &conf);
            if (ret) {
                fprintf(stderr, "Couldn't get configuration "
                        "descriptor %lu, some information will "
                        "be missing\n", j);
            } else {
                printf("bNumberInterfaces = %5u\n",conf->bNumInterfaces);
                printf("bConfigurationValue = %5u\n",conf->bConfigurationValue);

                for (k = 0 ; k < conf->bNumInterfaces ; k++)
                    dump_interface(handle, &conf->interface[k]);

                libusb_free_config_descriptor(conf);
            }
        }
    }

    libusb_free_device_list(list, 0);
error:
    return status;
}

int main(int argc, char *args[])
{
    int err = 0;
    libusb_context *ctx;

    err = libusb_init(&ctx);
    if (err) {
        fprintf(stderr, "unable to initialize libusb: %i\n", err);
        return EXIT_FAILURE;
    }

    list_devices(ctx);
    while(1)    
        sleep(1);

    return 0;
}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值