📄 usbdesc.c
字号:
/* usbdesc.c - Nereid USB Monitor / USB Descriptor * Copyright (C) 2003 Tachibana Eriko * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include <stdio.h>#include <string.h>#include "include/binary.h"#include "include/usbdef.h"#include "usbdesc.h"#include "util.h"/* Functions */static int print_desc_header (void* desc, int len_min, int len_max);static void print_confdesc_sub (ConfDesc* desc);/* 僨僗僋儕僾僞偺撪梕傪昞帵偡傞 */voidprint_descriptor (void* desc){ unsigned char desc_len = ((DevDesc*) desc)->bLength; unsigned char desc_type = ((DevDesc*) desc)->bDescriptorType; switch (desc_type) { /* Standard */ case DES_DEVICE: print_devdesc ((DevDesc*) desc); break; case DES_CONFIGURATION: print_confdesc ((ConfDesc*) desc); break; case DES_STRING: /* print_strdesc ((xxxxDesc*) desc); */ break; case DES_INTERFACE: print_intfdesc ((IntfDesc*) desc); break; case DES_ENDPOINT: print_epdesc ((EpDesc*) desc); break; /* USB2.0 */ case DES_DEVICE_QUALIFIER: print_devquadesc ((DevQuaDesc*) desc); break; case DES_OTHER_SPEED_CONFIGURATION: print_othspconfdesc ((OthSpConfDesc*) desc); break; case DES_INTERFACE_POWER: print_intfpwrdesc ((IntfPwrDesc*) desc); break; /* HID Class */ case DES_HID: print_hiddesc ((HidDesc*) desc); break; case DES_HID_REPORT: /* print_descriptor() 偐傜偺屇傃弌偟偼晄壜 */ break; case DES_HID_PHYSICAL: /* print_descriptor() 偐傜偺屇傃弌偟偼晄壜 */ break; /* HUB Class */ case DES_HUB: print_hubdesc ((HubDesc*) desc); break; default: printf ("枹懳墳偺僨僗僋儕僾僞偱偡(bDescriptorType=0x%02x, bLength=%d)\n", desc_type, desc_len); hexdump (desc, desc_len); printf ("\n"); break; }}/* 僨僶僀僗僨僗僋儕僾僞偺撪梕傪昞帵偡傞 */voidprint_devdesc (DevDesc* devdesc){ int r1, r2; if (print_desc_header (devdesc, sizeof_DevDesc, sizeof_DevDesc) < 0) return; r1 = (devdesc->bcdUSB >> 4 & 0x0f) * 10 + (devdesc->bcdUSB & 0x0f); r2 = (devdesc->bcdUSB >> 12) * 10 + (devdesc->bcdUSB >> 8 & 0x0f); printf ("\t" "bcdUSB ................ 0x%04x (release %d.%02d)\n", read_w (devdesc->bcdUSB), r1, r2); printf ("\t" "bDeviceClass .......... 0x%02x (%s)\n", devdesc->bDeviceClass, device_class_name (devdesc->bDeviceClass)); printf ("\t" "bDeviceSubClass ....... 0x%02x\n", devdesc->bDeviceSubClass); printf ("\t" "bDeviceProtocol ....... 0x%02x%s\n", devdesc->bDeviceProtocol, (devdesc->bDeviceProtocol == 0xff) ? " (vendor-specific)" : ""); printf ("\t" "bMaxPacketSize0 ....... %d\n", devdesc->bMaxPacketSize0); printf ("\t" "idVendor .............. 0x%04x\n", read_w (devdesc->idVendor)); printf ("\t" "idProduct ............. 0x%04x\n", read_w (devdesc->idProduct)); printf ("\t" "bcdDevice ............. 0x%04x\n", read_w (devdesc->bcdDevice)); printf ("\t" "iManufacturer ......... %d\n", devdesc->iManufacturer); printf ("\t" "iProduct .............. %d\n", devdesc->iProduct); printf ("\t" "iSerialNumber ......... %d\n", devdesc->iSerialNumber); printf ("\t" "bNumConfigurations .... %d\n", devdesc->bNumConfigurations);}/* 僐儞僼傿僊儏儗乕僔儑儞僨僗僋儕僾僞偺撪梕傪昞帵偡傞 */voidprint_confdesc (ConfDesc* confdesc){ print_confdesc_sub (confdesc);}/* 僀儞僞乕僼僃僀僗僨僗僋儕僾僞偺撪梕傪昞帵偡傞 */voidprint_intfdesc (IntfDesc* intfdesc){ if (print_desc_header (intfdesc, sizeof_IntfDesc, sizeof_IntfDesc) < 0) return; printf ("\t" "bInterfaceNumber ...... %d\n", intfdesc->bInterfaceNumber); printf ("\t" "bAlternateSetting ..... %d\n", intfdesc->bAlternateSetting); printf ("\t" "bNumEndpoints ......... %d\n", intfdesc->bNumEndpoints); printf ("\t" "bInterfaceClass ....... 0x%02x (%s)\n", intfdesc->bInterfaceClass, interface_class_name (intfdesc->bInterfaceClass)); printf ("\t" "bInterfaceSubClass .... %d\n", intfdesc->bInterfaceSubClass); printf ("\t" "bInterfaceProtocol .... %d%s\n", intfdesc->bInterfaceProtocol, (intfdesc->bInterfaceProtocol == 0xff) ? " (vendor-specific)" : ""); printf ("\t" "iInterface ............ %d\n", intfdesc->iInterface);}/* 僄儞僪億僀儞僩僨僗僋儕僾僞偺撪梕傪昞帵偡傞 */voidprint_epdesc (EpDesc* epdesc){ const char* transfer_type[] = { "Control", "Isochronous", "Bulk", "Inrerrupt" }; const char* dir; if (print_desc_header (epdesc, sizeof_EpDesc, sizeof_EpDesc) < 0) return; dir = (epdesc->bEndpointAddress & 0x0f) ? ((epdesc->bEndpointAddress & (1 << 7)) ? "IN" : "OUT") : "IN/OUT"; /* control endpoint */ printf ("\t" "bEndpointAddress ...... 0x%02x (%s, #%d)\n", epdesc->bEndpointAddress, dir, (epdesc->bEndpointAddress & 0x0f)); printf ("\t" "bmAttributes .......... 0x%02x (%s)\n", epdesc->bmAttributes, transfer_type[epdesc->bmAttributes & 3]); printf ("\t" "wMaxPacketSize ........ %d\n", read_w (epdesc->wMaxPacketSize)); printf ("\t" "bInterval ............. %d", epdesc->bInterval); if (epdesc->bmAttributes & 1) printf (" (%dms)", epdesc->bInterval); printf ("\n");}/* 僨僶僀僗僋僆儕僼傽僀傾僨僗僋儕僾僞偺撪梕傪昞帵偡傞 */voidprint_devquadesc (DevQuaDesc* desc){ int r1, r2; if (print_desc_header (desc, sizeof_DevQuaDesc, sizeof_DevQuaDesc) < 0) return; r1 = (desc->bcdUSB >> 4 & 0x0f) * 10 + (desc->bcdUSB & 0x0f); r2 = (desc->bcdUSB >> 12) * 10 + (desc->bcdUSB >> 8 & 0x0f); printf ("\t" "bcdUSB ................ 0x%04x (release %d.%02d)\n", read_w (desc->bcdUSB), r1, r2); printf ("\t" "bDeviceClass .......... 0x%02x (%s)\n", desc->bDeviceClass, device_class_name (desc->bDeviceClass)); printf ("\t" "bDeviceSubClass ....... 0x%02x\n", desc->bDeviceSubClass); printf ("\t" "bDeviceProtocol ....... 0x%02x%s\n", desc->bDeviceProtocol, (desc->bDeviceProtocol == 0xff) ? " (vendor-specific)" : ""); printf ("\t" "bMaxPacketSize0 ....... %d\n", desc->bMaxPacketSize0); printf ("\t" "bNumConfigurations .... %d\n", desc->bNumConfigurations); printf ("\t" "bReserved ............. 0x%02x\n", desc->bReserved);}/* 暿偺懍搙偺僐儞僼傿僊儏儗乕僔儑儞僨僗僋儕僾僞偺撪梕傪昞帵偡傞 */voidprint_othspconfdesc (OthSpConfDesc* desc){ /* 撪梕偼僐儞僼傿僊儏儗乕僔儑儞僨僗僋儕僾僞偲摨偠 */ print_confdesc_sub ((ConfDesc*) desc);}/* 僀儞僞乕僼僃乕僗揹椡僨僗僋儕僾僞偺撪梕傪昞帵偡傞 */voidprint_intfpwrdesc (IntfPwrDesc* desc){ if (print_desc_header (desc, sizeof_IntfPwrDesc, sizeof_IntfPwrDesc) < 0) return; printf ("\t" "bmFlags ............... 0x%02x\n", desc->bmFlags);}/* HID 僨僗僋儕僾僞偺撪梕傪昞帵偡傞 */voidprint_hiddesc (HidDesc* hiddesc){ int r1, r2, unit_size; int report, padding, i; if (print_desc_header (hiddesc, sizeof_HidDesc, 255) < 0) return; r1 = (hiddesc->bcdHCD >> 4 & 0x0f) * 10 + (hiddesc->bcdHCD & 0x0f); r2 = (hiddesc->bcdHCD >> 12) * 10 + (hiddesc->bcdHCD >> 8 & 0x0f); printf ("\t" "bcdHCD ................ 0x%04x (release %d.%02d)\n", read_w (hiddesc->bcdHCD), r1, r2); printf ("\t" "bCountryCode .......... 0x%02x (%s)\n", hiddesc->bCountryCode, country_code_name (hiddesc->bCountryCode)); printf ("\t" "bNumDescriptors ....... %d\n", hiddesc->bNumDescriptors); unit_size = sizeof (hiddesc->Report[0].bDescriptorType) + sizeof (hiddesc->Report[0].wDescriptorLength); padding = (hiddesc->bLength - sizeof_HidDesc) % unit_size; report = (hiddesc->bLength - sizeof_HidDesc) / unit_size + 1; for (i = 0; i < report; ++i) { printf ("\t" "bDescriptorType ....... 0x%02x (%s)\n", hiddesc->Report[0].bDescriptorType, descriptor_type_name (hiddesc->Report[0].bDescriptorType)); printf ("\t" "wDescriptorLength ..... %d\n", read_w (hiddesc->Report[0].wDescriptorLength)); /* Report[1] 偱嶲徠偱偒側偄偺偱愭摢傪偢傜偟偰層杻壔偡 */ hiddesc = (HidDesc*) ((char*) hiddesc - unit_size); } if (padding != 0) printf ("枛旜偵%d僶僀僩偺敿抂側僨乕僞偑偁傝傑偡.\n", i);}/* HID 儕億乕僩僨僗僋儕僾僞偺撪梕傪昞帵偡傞 */voidprint_hid_reportdesc (HidRepDesc* hidrepdesc, int len){ printf ("[HID Report Descriptor]\n"); hexdump ((unsigned char*) hidrepdesc, len); printf ("\n");}/* HID Physical 僨僗僋儕僾僞偺撪梕傪昞帵偡傞 */voidprint_hid_physicaldesc (HidPhyDesc* hidphydesc, int len){ printf ("[HID Physical Descriptor]\n"); hexdump ((unsigned char*) hidphydesc, len); printf ("\n");}/* HUB 僨僗僋儕僾僞偺撪梕傪昞帵偡傞 */voidprint_hubdesc (HubDesc* hubdesc){ int fixed_size, bytes; if (print_desc_header (hubdesc, sizeof_HubDesc, 255) < 0) return; printf ("\t" "bNbrPorts ............. %0d\n", hubdesc->bNbrPorts); { int w = read_wp ((unsigned short*) hubdesc->wHubCharacteristics); const char* w1 = ((w & 0x0003) == 0x0000) ? "Ganged" : ((w & 0x0003) == 0x0001) ? "Individual port" : "No"; const char* w2 = ((w & 0x0004) == 0x0000) ? "not " : ""; const char* w3 = ((w & 0x0018) == 0x0000) ? "Global" : ((w & 0x0018) == 0x0008) ? "Individual" : "No"; printf ("\t" "wHubCharacteristics ... 0x%04x (%s power switching,\n" "\t\t\t\t\t" "%scompound device, %s Over-current Protection)\n", w, w1, w2, w3); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -