枚举usb设备2

枚举usb设备2

1 列出产商及序列号

思路:在USB手册《Universal Serial Bus Specification Revision 2.0》9.6章节有相关的定义,如设备,配置,接口,终结点等信息。下表为USB设备信息的具体定义:

那最后要如何读取这些信息呢?UEFI已经给我们提供了相应的Protocol,那便是EFI_USB_IO_PROTOCOL。首先使用EFI_USB_IO_PROTOCOL.UsbGetDeviceDescriptor()获取产商和序列号的索引值,再用EFI_USB_IO_PROTOCOL.UsbGetStringDescriptor()取得相应的字符串即可。代码如下:

#include <Uefi.h>
#include <Library/UefiLib.h>
#include <Protocol/BlockIo.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Protocol/DevicePathToText.h>
#include <Protocol/UsbIo.h>
#include <Library/UefiApplicationEntryPoint.h>

#define LANGID_ENGLISH     0x0409

EFI_STATUS
EFIAPI
UsbEnumerate (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{

    EFI_STATUS                         Status;
    EFI_HANDLE                         *UsbDeviceHandle;
    UINTN                              UsbDeviceHandleNumber;
    EFI_DEVICE_PATH_PROTOCOL           *UsbDevicePath;
	EFI_DEVICE_PATH_TO_TEXT_PROTOCOL   *Path2Text;
	UINTN                              Index;

    EFI_USB_IO_PROTOCOL                  *UsbDevice;
    EFI_USB_DEVICE_DESCRIPTOR            DeviceDescriptor;
    CHAR16                               *StrManufacturer;
    CHAR16                               *StrProduct;
CHAR16                               *StrSerialNumber;

/* Get all usb device handles */
    Status = gBS->LocateHandleBuffer (
                ByProtocol,
                &gEfiUsbIoProtocolGuid,
                NULL,
                &UsbDeviceHandleNumber,
                &UsbDeviceHandle
                );
    
    if (EFI_ERROR (Status)) {
        Print (L"Unsupported\n\r");
        return 0;
    }
    /* Get device to text instance to convert device path to string */
    Status = gBS->LocateProtocol (&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **) &Path2Text);
    if (EFI_ERROR(Status)) {
        Print (L"Unsupported\n\r");
        return 0;
    }
    /* List all usb info */
    for (Index = 0; Index < UsbDeviceHandleNumber; Index ++) {
        Print (L"Usb device number: %d\n\r", Index + 1);
        /* Get Usb Io protocol instance */
        Status = gBS->HandleProtocol (UsbDeviceHandle[Index], &gEfiUsbIoProtocolGuid, (VOID **) &UsbDevice);
        Status = UsbDevice->UsbGetDeviceDescriptor (UsbDevice, &DeviceDescriptor);
        if (!EFI_ERROR (Status)) {
            /* Manufacturer */
            StrManufacturer = NULL;
            Status = UsbDevice->UsbGetStringDescriptor (UsbDevice, LANGID_ENGLISH, DeviceDescriptor.StrManufacturer, &StrManufacturer);
            if (!EFI_ERROR (Status)) {
                Print (L"Manufacturer: %s\n\r", StrManufacturer);
            }
            /* Product */
            StrProduct = NULL;
            Status = UsbDevice->UsbGetStringDescriptor (UsbDevice, LANGID_ENGLISH, DeviceDescriptor.StrProduct, &StrProduct);
            if (!EFI_ERROR (Status)) {
                Print (L"Product: %s\n\r", StrProduct);
            }
            /* Serial number */
            StrSerialNumber = NULL;
            Status = UsbDevice->UsbGetStringDescriptor (UsbDevice, LANGID_ENGLISH, DeviceDescriptor.StrSerialNumber, &StrSerialNumber);
            if (!EFI_ERROR (Status)) {
                Print (L"Serial number: %s\n\r", StrSerialNumber);
            }
        }
        /* List device path */
        Status = gBS->HandleProtocol (UsbDeviceHandle[Index], &gEfiDevicePathProtocolGuid, (VOID **) &UsbDevicePath);
        if (!EFI_ERROR (Status)) {
            Print (L"Device Path: %s\n\r", Path2Text->ConvertDevicePathToText(UsbDevicePath, FALSE, TRUE));
        }
        Print (L"\n\r");
    }
    return EFI_SUCCESS;
}

2  最后还有一个问题要解决的,那就是怎么去判断usb设备的类型,如怎么知道某个设备是存储设备,或是键盘鼠标等。此类信息位于USB的Interface Descriptor中。

#include <Uefi.h>
#include <Library/UefiLib.h>
#include <Protocol/BlockIo.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Protocol/DevicePathToText.h>
#include <Protocol/UsbIo.h>
#include <Library/UefiApplicationEntryPoint.h>

#define LANGID_ENGLISH     0x0409

#define USB_INTERFACE_CLASS_UNKNOW       0x00
#define USB_INTERFACE_CLASS_HID            0x03
#define USB_INTERFACE_CLASS_STORAGE        0x08
#define USB_INTERFACE_CLASS_HUB            0x09
#define USB_INTERFACE_CLASS_VENDOR_DEF     0xFF
#define USB_INTERFACE_HID_PROTOCOL_KB      0x01
#define USB_INTERFACE_HID_PROTOCOL_MS      0x02

EFI_STATUS
EFIAPI
UsbEnumerate (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{

    EFI_STATUS                         Status;
    EFI_HANDLE                         *UsbDeviceHandle;
    UINTN                              UsbDeviceHandleNumber;
    EFI_DEVICE_PATH_PROTOCOL           *UsbDevicePath;
	EFI_DEVICE_PATH_TO_TEXT_PROTOCOL   *Path2Text;
	UINTN                              Index;

    EFI_USB_IO_PROTOCOL                  *UsbDevice;
    EFI_USB_DEVICE_DESCRIPTOR            DeviceDescriptor;
    CHAR16                               *StrManufacturer;
    CHAR16                               *StrProduct;
    CHAR16                               *StrSerialNumber;
	
    EFI_USB_INTERFACE_DESCRIPTOR         InterfaceDescriptor;

/* Get all usb device handles */
    Status = gBS->LocateHandleBuffer (
                ByProtocol,
                &gEfiUsbIoProtocolGuid,
                NULL,
                &UsbDeviceHandleNumber,
                &UsbDeviceHandle
                );
    
    if (!EFI_ERROR (Status)) {
        Print (L"Usb device number: %d\n\r", UsbDeviceHandleNumber);
    }
	
	
	/* Get device to text instance to convert device path to string */
    Status = gBS->LocateProtocol (&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **) &Path2Text);
    if (EFI_ERROR(Status)) {
        Print (L"Unsupported\n\r");
        return 0;
    }
	
	
    /* List all usb info */
    for (Index = 0; Index < UsbDeviceHandleNumber; Index ++) {
        
		 Print (L"Usb device number: %d\n\r", Index + 1);
		
		/* Get Usb Io protocol instance */
        Status = gBS->HandleProtocol (UsbDeviceHandle[Index], &gEfiUsbIoProtocolGuid, (VOID **) &UsbDevice);
		
		 /* Get usb device type */
        Status = UsbDevice->UsbGetInterfaceDescriptor (UsbDevice, &InterfaceDescriptor);
		
		      if (!EFI_ERROR (Status)) {
            Print (L"NO.%d\n\r", Index + 1);
            switch (InterfaceDescriptor.InterfaceClass) {
            case USB_INTERFACE_CLASS_UNKNOW:
                Print (L"Type: Unkown\n\r");
                break;
            case USB_INTERFACE_CLASS_HID:
                if (InterfaceDescriptor.InterfaceProtocol == USB_INTERFACE_HID_PROTOCOL_KB) {
                    Print (L"Type: Keyboard\n\r");
                }
                Else if (InterfaceDescriptor.InterfaceProtocol == USB_INTERFACE_HID_PROTOCOL_MS) {
                     Print (L"Type: Mouse\n\r");
                }
                break;
            case USB_INTERFACE_CLASS_STORAGE:
                Print (L"Type: Mass Storage\n\r");
                break;
            case USB_INTERFACE_CLASS_HUB:
                Print (L"Type: Hub\n\r");
                break;
            default:
                Print (L"Type: Unkown\n\r");
                break;
            }
        }
        /* Not a device */
        else continue; 
		
		
		Status = UsbDevice->UsbGetDeviceDescriptor (UsbDevice, &DeviceDescriptor);
		
		if (!EFI_ERROR (Status)) {

            /* Manufacturer */
            StrManufacturer = NULL;
            Status = UsbDevice->UsbGetStringDescriptor (UsbDevice, LANGID_ENGLISH, DeviceDescriptor.StrManufacturer, &StrManufacturer);
            if (!EFI_ERROR (Status)) {
                Print (L"Manufacturer: %s\n\r", StrManufacturer);
            }

            /* Product */
            StrProduct = NULL;
            Status = UsbDevice->UsbGetStringDescriptor (UsbDevice, LANGID_ENGLISH, DeviceDescriptor.StrProduct, &StrProduct);
            if (!EFI_ERROR (Status)) {
                Print (L"Product: %s\n\r", StrProduct);
            }

            /* Serial number */
            StrSerialNumber = NULL;
            Status = UsbDevice->UsbGetStringDescriptor (UsbDevice, LANGID_ENGLISH, DeviceDescriptor.StrSerialNumber, &StrSerialNumber);
            if (!EFI_ERROR (Status)) {
                Print (L"Serial number: %s\n\r", StrSerialNumber);
            }
        }
		
		
		/* List device path */
        Status = gBS->HandleProtocol (UsbDeviceHandle[Index], &gEfiDevicePathProtocolGuid, (VOID **) &UsbDevicePath);
        if (!EFI_ERROR (Status)) {
            Print (L"Device Path: %s\n\r", Path2Text->ConvertDevicePathToText(UsbDevicePath, FALSE, TRUE));
        }
        Print (L"\n\r");
    }

    return EFI_SUCCESS;
}

最后在shell 下面结果:

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值