/*++
Copyright (c) 1997-1998 Microsoft Corporation
Module Name:
DISPLAY.C
Abstract:
This source file contains the routines which update the edit control
to display information about the selected USB device.
Environment:
user mode
Revision History:
04-25-97 : created
--*/
//*****************************************************************************
// I N C L U D E S
//*****************************************************************************
#include <windows.h>
#include <basetyps.h>
#include <shlwapi.h>
#include "usbview.h"
#include "usb100.h"
#include "usb200.h"
//*****************************************************************************
// D E F I N E S
//*****************************************************************************
#define BUFFERALLOCINCREMENT 8192
#define BUFFERMINFREESPACE 1024
//*****************************************************************************
// G L O B A L S P R I V A T E T O T H I S F I L E
//*****************************************************************************
// Workspace for text info which is used to update the edit control
TCHAR *TextBuffer;
int TextBufferLen;
int TextBufferPos;
//*****************************************************************************
// L O C A L F U N C T I O N S
//*****************************************************************************
//*****************************************************************************
//
// CreateTextBuffer()
//
//*****************************************************************************
bool CreateTextBuffer() {
// Allocate the buffer
//
TextBuffer = ALLOC(BUFFERALLOCINCREMENT*sizeof(TCHAR));
if (!TextBuffer) {
OOPS();
return false;
}
TextBufferLen = BUFFERALLOCINCREMENT;
// Reset the buffer position and terminate the buffer
//
*TextBuffer = 0;
TextBufferPos = 0;
return true;
}
//*****************************************************************************
//
// DestroyTextBuffer()
//
//*****************************************************************************
void DestroyTextBuffer() {
if (TextBuffer) TextBuffer=FREE(TextBuffer);
}
//*****************************************************************************
//
// ResetTextBuffer()
//
//*****************************************************************************
bool ResetTextBuffer () {
// Fail if the text buffer has not been allocated
//
if (!TextBuffer) {
OOPS();
return false;
}
// Reset the buffer position and terminate the buffer
//
*TextBuffer = 0;
TextBufferPos = 0;
return true;
}
//*****************************************************************************
// Append text to buffer, the template ist 7-bit ONLY!
//*****************************************************************************
void _cdecl AppendTextBuffer(LPCSTR lpFormat,...) {
va_list arglist;
va_start(arglist, lpFormat);
// Make sure we have a healthy amount of space free in the buffer,
// reallocating the buffer if necessary.
//
if (TextBufferLen - TextBufferPos < BUFFERMINFREESPACE) {
TCHAR *TextBufferTmp;
TextBufferTmp = REALLOC(TextBuffer,(TextBufferLen+BUFFERALLOCINCREMENT)*sizeof(TCHAR));
if (TextBufferTmp) {
TextBuffer = TextBufferTmp;
TextBufferLen += BUFFERALLOCINCREMENT;
}else{
// If GlobalReAlloc fails, the original memory is not freed,
// and the original handle and pointer are still valid.
//
OOPS();
return;
}
}
// Add the text to the end of the buffer, updating the buffer position.
#ifdef UNICODE
{
WCHAR t[256];
MultiByteToWideChar(CP_ACP,0,lpFormat,-1,t,elemof(t));
TextBufferPos += wvsprintf(TextBuffer+TextBufferPos,t,arglist);
}
#else
TextBufferPos += wvsprintf(TextBuffer+TextBufferPos,lpFormat,arglist);
#endif
}
// Replace non-printable characters by C typical escape sequences
// Needed for some Chinese vendor and product strings
int EscapeStr(LPCTSTR s, int slen, LPTSTR buf, int buflen) {
int i=0,r=0;
if (slen<0) slen=lstrlen(s);
for (;i<slen;i++) {
TCHAR c=*s++; // fetch character
if (c<0x20) { // non-displayable?
LPCTSTR t=T("\\%c"); // set a default template
switch (c) {
case '\0': c='0'; break; // change characters
case '\a': c='a'; break; // 7
case '\b': c='b'; break; // 8
case '\t': c='t'; break; // 9
case '\r': c='r'; break; // 10
case '\v': c='v'; break; // 11
case '\f': c='f'; break; // 12
case '\n': c='n'; break; // 13
case 27: c='e'; break; // Escape (gcc, not ANSI C)
default: t=T("\\x%02X"); // template for hex output
}
r+=wnsprintf(buf+r,buflen-r,t,c); // append (either version of template)
}else if (buflen-r>1) buf[r++]=c; // append printable character
}
buf[r]=0;
return r;
}
// Append a Unicode string (escaping it) using template <t>
void AppendTextBufferStringW(LPCSTR t, LPCWSTR s, int slen) {
TCHAR s1[256];
#ifdef UNICODE
if (slen<0) slen=lstrlenW(s);
EscapeStr(s,slen,s1,elemof(s1));
#else
char s2[256];
if (slen<0) slen=lstrlenW(s);
slen=WideCharToMultiByte(CP_ACP,0,s,slen,s2,sizeof(s2),NULL,NULL);
EscapeStr(s2,slen,s1,elemof(s1));
#endif
AppendTextBuffer(t,s1);
}
extern void AppendHexDump(const BYTE*data, int len) {
char line[80],*p=line;
int w=0;
while (len) {
p+=wsprintfA(p," %02X",*data++);
len--;
w++;
if (w==16 || !len) {
AppendTextBuffer(ASTR"\r\n",line);
p=line;
w=0;
}
}
}
//*****************************************************************************
// DisplayUnknownDescriptor()
//*****************************************************************************
static void DisplayUnknownDescriptor (const USB_COMMON_DESCRIPTOR*CommonDesc, int len) {
AppendTextBuffer("\r\nUnknown Descriptor:");
if (!len || CommonDesc->bLength!=len) AppendTextBuffer(" Length = %d",len);
if (len>=1) AppendTextBuffer("\r\n bLength: 0x%02X", CommonDesc->bLength);
if (len>=2) AppendTextBuffer("\r\n bDescriptorType: 0x%02X", CommonDesc->bDescriptorType);
AppendTextBuffer("\r\n");
if (len>2) {
if (len>CommonDesc->bLength-2) len=CommonDesc->bLength-2;
AppendHexDump((const BYTE*)(CommonDesc+1),len);
}
}
#if 1
//*****************************************************************************
// DisplayStringDescriptor()
//*****************************************************************************
static void DisplayStringDescriptor(UCHAR Index, PSTRING_DESCRIPTOR_NODE StringDescs) {
for (;StringDescs; StringDescs=StringDescs->Next) {
if (StringDescs->DescriptorIndex == Index) {
const char*p;
AppendTextBuffer("0x%04X: ",StringDescs->LanguageID);
AppendTextBufferStringW("\"%s\"",
StringDescs->StringDescriptor->bString,
(StringDescs->StringDescriptor->bLength-2)>>1);
p = Lookup('L',StringDescs->LanguageID&0x3FF,-1,-1);
if (p) {
const char*q = Lookup('L',StringDescs->LanguageID&0x3FF,StringDescs->LanguageID>>10,-1);
AppendTextBuffer(q?" (" ASTR "," ASTR ")":" (" ASTR ")",p,q);
}
AppendTextBuffer("\r\n");
}
}
}
#else
VOID
DisplayStringDescriptor (
UCHAR Index,
PSTRING_DESCRIPTOR_NODE StringDescs
)
{
UCHAR i;
while (StringDescs)
{
if (StringDescs->DescriptorIndex == Index)
{
AppendTextBuffer("String Descriptor:\r\n");
AppendTextBuffer("LanguageID: 0x%04X\r\n",
StringDescs->LanguageID);
AppendTextBuffer("bLength: 0x%02X\r\n",
StringDescs->StringDescriptor->bLength);
for (i = 0; i < StringDescs->StringDescriptor->bLength-2; i++)
{
AppendTextBuffer("%02X ",
((PUCHAR)StringDescs->StringDescriptor->bString)[i]);
if (i % 16 == 15)
{
AppendTextBuffer("\r\n");
}
}
if (i % 16 != 0)
{
AppendTextBuffer("\r\n");
}
}
StringDescs = StringDescs->Next;
}
}
#endif
//*****************************************************************************
//
// DisplayConfigurationDescriptor()
//
//*****************************************************************************
static void DisplayConfigurationDescriptor (
PUSB_CONFIGURATION_DESCRIPTOR ConfigDesc,
PSTRING_DESCRIPTOR_NODE StringDescs) {
AppendTextBuffer("\r\n"ASTR" Descriptor:\r\n", ConfigDesc->bDescriptorType==7?"Other Speed":"Configuration");
AppendTextBuffer(" wTotalLength: 0x%04X (%d)\r\n", ConfigDesc->wTotalLength,ConfigDesc->wTotalLength);
AppendTextBuffer(" bNumInterfaces: 0x%02X\r\n", ConfigDesc->bNumInterfaces);
AppendTextBuffer(" bConfigurationValue: 0x%02X\r\n", ConfigDesc->bConfigurationValue);
AppendTextBuffer(" iConfiguration: 0x%02X\r\n", ConfigDesc->iConfiguration);
if (ConfigDesc->iConfiguration)
DisplayStringDescriptor(ConfigDesc->iConfiguration, StringDescs);
AppendTextBuffer(" bmAttributes: 0x%02X (",ConfigDesc->bmAttributes);
if (ConfigDesc->bmAttributes & 0x80) AppendTextBuffer("Bus Powered ");
if (ConfigDesc->bmAttributes & 0x40) AppendTextBuffer("Self Powered ");
if (ConfigDesc->bmAttributes & 0x20) AppendTextBuffer("Remote Wakeup");
AppendTextBuffer(")\r\n");
AppendTextBuffer(" MaxPower: 0x%02X (%d mA)\r\n",
ConfigDesc->MaxPower,
ConfigDesc->MaxPower*2);
}
//*****************************************************************************
//
// DisplayInterfaceDescriptor()
//
//*****************************************************************************
static void DisplayInterfaceDescriptor(
PUSB_INTERFACE_DESCRIPTOR InterfaceDesc,
PSTRING_DESCRIPTOR_NODE StringDescs) {
const char *p;
AppendTextBuffer("\r\nInterface Descriptor:\r\n");
AppendTextBuffer(" bInterfaceNumber: 0x%02X\r\n", InterfaceDesc->bInterfaceNumber);
AppendTextBuffer(" bAlternateSetting: 0x%02X\r\n", InterfaceDesc->bAlternateSetting);
AppendTextBuffer(" bNumEndpoints: 0x%02X\r\n", InterfaceDesc->bNumEndpoints);
AppendTextBuffer(" bInterfaceClass: 0x%02X", InterfaceDesc->bInterfaceClass);
p = Lookup('C',InterfaceDesc->bInterfaceClass,-1,-1);
if (!p) switch (InterfaceDesc->bInterfaceClass) {
case USB_DEVICE_CLASS_AUDIO: p = "Audio"; break;
case USB_DEVICE_CLASS_HUMAN_INTERFACE:p = "HID"; break;
case USB_DEVICE_CLASS_HUB: p = "Hub"; break;
}
if (p) AppendTextBuffer(" ("ASTR")",p);
AppendTextBuffer("\r\n");
AppendTextBuffer(" bInterfaceSubClass: 0x%02X", InterfaceDesc->bInterfaceSubClass);
p = Lookup('C',InterfaceDesc->bInterfaceClass,
InterfaceDesc->bInterfaceSubClass,-1);
if (!p) switch (InterfaceDesc->bInterfaceClass) {
case USB_DEVICE_CLASS_AUDIO: switch (InterfaceDesc->bInterfaceSubClass) {
case USB_AUDIO_SUBCLASS_AUDIOCONTROL: p = "Audio Control"; break;
case USB_AUDIO_SUBCLASS_AUDIOSTREAMING: p = "Audio Streaming"; break;
case USB_AUDIO_SUBCLASS_MIDISTREAMING: p = "MIDI Streaming"; break;
}break;
}
if (p) AppendTextBuffer(" ("ASTR")",p);
AppendTextBuffer("\r\n");
AppendTextBuffer(" bInterfaceProtocol: 0x%02X", InterfaceDesc->bInterfaceProtocol);
p = Lookup('C',InterfaceDesc->bInterfaceClass,
InterfaceDesc->bInterfaceSubClass,
InterfaceDesc->bInterfaceProtocol);
if (p) AppendTextBuffer(" ("ASTR")",p);
AppendTextBuffer("\r\n");
AppendTextBuffer(" iInterface: 0x%02X\r\n", InterfaceDesc->iInterface);
if (InterfaceDesc->iInterface)
DisplayStringDescriptor(InterfaceDesc->iInterface,StringDescs);
if (InterfaceDesc->bLength == sizeof(USB_INTERFACE_DESCRIPTOR2)) {
PUSB_INTERFACE_DESCRIPTOR2 interfaceDesc2 = (PUSB_INTERFACE_DESCRIPTOR2)InterfaceDesc;
AppendTextBuffer(" wNumClasses: 0x%04X\r\n", interfaceDesc2->wNumClasses);
}
}
//*****************************************************************************
//
// DisplayEndpointDescriptor()
//
//*****************************************************************************
static void DisplayEndpointDescriptor (PUSB_ENDPOINT_DESCRIPTOR EndpointDesc) {
static const PCTSTR sAttr[4]={
T("Control"),T("Isochronous"),T("Bulk"),T("Interrupt")};
AppendTextBuffer("\r\nEndpoint Descriptor:\r\n");
AppendTextBuffer(" bEndpointAddress: 0x%02X (EP%d%s)\r\n",
EndpointDesc->bEndpointAddress,
EndpointDesc->bEndpointAddress&0x0F,
EndpointDesc->bEndpointAddress&0x80?T("IN"):T("OUT"));
AppendTextBuffer(" Transfer Type:%11s\r\n",
sAttr[EndpointDesc->bmAttributes&0x03]);
AppendTextBuffer(" wMaxPacketSize: 0x%04X (%d)\r\n",
EndpointDesc->wMaxPacketSize,
EndpointDesc->wMaxPacketSize);
if (EndpointDesc->bLength==sizeof(USB_ENDPOINT_DESCRIPTOR)) {
AppendTextBuffer(" bInterval: 0x%02X\r\n",
EndpointDesc->bInterval);
}else{
PUSB_ENDPOINT_DESCRIPTOR2 endpointDesc2;
endpointDesc2 = (PUSB_ENDPOINT_DESCRIPTOR2)EndpointDesc;
AppendTextBuffer(" wInterval: 0x%04X\r\n",
endpointDesc2->wInterval);
AppendTextBuffer(" bSyncAddress: 0x%02X\r\n",
endpointDesc2->bSyncAddress);
}
}
static void DisplayQualifier(const USB_DEVICE_QUALIFIER_DESCRIPTOR*qual) {
AppendTextBuffer("\r\nDevice Qualifier:\r\n");
if (qual->bDescriptorType!=USB_DEVICE_QUALIFIER_DESCRIPTOR_TYPE) OOPS();
if (qual->bLength<sizeof(*qual)) OOPS();
AppendTextBuffer(" USB Spec. Version: 0x%04X\r\n",qual->bcdUSB);
AppendTextBuffer(" bDeviceClass: 0x%02X\r\n",qual->bDeviceClass);
AppendTextBuffer(" bDeviceSubclass: 0x%02X\r\n",qual->bDeviceSubClass);
AppendTextBuffer(" bDeviceProtocol: 0x%02X\r\n",qual->bDeviceProtocol);
AppendTextBuffer(" bMaxPacketSize0: 0x%02X\r\n",qual->bMaxPacketSize0);
AppendTextBuffer(" bNumConfigurations: 0x%02X\r\n",qual->bNumConfigurations);
if (qual->bReserved) {
AppendTextBuffer(" bReserved: 0x%02X\r\n",qual->bReserved);
}
}
static void DisplayPowerDescriptor(const BYTE*p0) {
char *t;
const BYTE *p=p0+2, *e=p0+p0[0];
int i;
switch (p0[1]) {
case 7: t="Configuration"; break;
case 8: t="Interface"; break;
}
AppendTextBuffer("\r\n"ASTR" Power Descriptor:",t);
switch (p0[1]) {
case 7: {
AppendTextBuffer("\r\n SelfPowerConsumedD0: 0x%02X, 0x%02X, 0x%02X",p[0],p[1],p[2]);
AppendTextBuffer("\r\n bPowerSummaryId: 0x%02X",p[3]);
p+=4;
}break;
case 8: {
AppendTextBuffer("\r\n bmCapabilitiesFlags: 0x%02X",*p++);
}break;
}
for (i=1; i<=3; i++) {
if (p>=e) goto exi;
AppendTextBuffer("\r\n bBusPowerSavingD%i: 0x%02X",i,*p++);
AppendTextBuffer("\r\n bSelfPowerSavingD%i: 0x%02X",i,*p++);
}
for (i=1; i<=3; i++) {
if (p>=e) break;
AppendTextBuffer("\r\n TransitionTimeFromD%i: 0x%02X",i,*((USHORT*)p)++);
}
exi:
AppendTextBuffer("\r\n");
}
//*****************************************************************************
// ConfigDesc - The Configuration Descriptor, and associated Interface and
// EndpointDescriptors
//*****************************************************************************
static void DisplayConfigDesc (
PUSB_CONFIGURATION_DESCRIPTOR ConfigDesc,
PSTRING_DESCRIPTOR_NODE StringDescs,
const BYTE**HidDescs
)
{
const BYTE* descEnd; // pointer to end of descriptor
BYTE iface=0; // current interface number
PUSB_COMMON_DESCRIPTOR commonDesc;
UCHAR bInterfaceClass;
UCHAR bInterfaceSubClass;
BOOL displayUnknown;
bInterfaceClass = 0;
descEnd = (PUCHAR)ConfigDesc + ConfigDesc->wTotalLength;
commonDesc = (PUSB_COMMON_DESCRIPTOR)ConfigDesc;
while ((PUCHAR)commonDesc + sizeof(USB_COMMON_DESCRIPTOR) < descEnd &&
(PUCHAR)commonDesc + commonDesc->bLength <= descEnd)
{
displayUnknown = FALSE;
switch (commonDesc->bDescriptorType) {
case USB_CONFIGURATION_DESCRIPTOR_TYPE:
case 7: // OTHER_SPEED_CONFIGURATION
if (commonDesc->bLength != sizeof(USB_CONFIGURATION_DESCRIPTOR))
{
OOPS();
displayUnknown = TRUE;
break;
}
DisplayConfigurationDescriptor((PUSB_CONFIGURATION_DESCRIPTOR)commonDesc,
StringDescs);
break;
case USB_INTERFACE_DESCRIPTOR_TYPE:
if ((commonDesc->bLength != sizeof(USB_INTERFACE_DESCRIPTOR)) &&
(commonDesc->bLength != sizeof(USB_INTERFACE_DESCRIPTOR2)))
{
OOPS();
displayUnknown = TRUE;
break;
}
bInterfaceClass = ((PUSB_INTERFACE_DESCRIPTOR)commonDesc)->bInterfaceClass;
bInterfaceSubClass = ((PUSB_INTERFACE_DESCRIPTOR)commonDesc)->bInterfaceSubClass;
DisplayInterfaceDescriptor((PUSB_INTERFACE_DESCRIPTOR)commonDesc,
StringDescs);
break;
case USB_ENDPOINT_DESCRIPTOR_TYPE:
if ((commonDesc->bLength != sizeof(USB_ENDPOINT_DESCRIPTOR)) &&
(commonDesc->bLength != sizeof(USB_ENDPOINT_DESCRIPTOR2)))
{
OOPS();
displayUnknown = TRUE;
break;
}
DisplayEndpointDescriptor((PUSB_ENDPOINT_DESCRIPTOR)commonDesc);
break;
case USB_HID_DESCRIPTOR_TYPE:
if (commonDesc->bLength < sizeof(USB_HID_DESCRIPTOR))
{
OOPS();
displayUnknown = TRUE;
break;
}
{int i;
if (HidDescs) for (i=0;HidDescs[i];i++) {
if (HidDescs[i][0]==iface) {
DisplayHidDescriptor((PUSB_HID_DESCRIPTOR)commonDesc,HidDescs[i]+1);
goto shown;
}
}
DisplayHidDescriptor((PUSB_HID_DESCRIPTOR)commonDesc,NULL);
shown:;
}break;
case USB_DEVICE_QUALIFIER_DESCRIPTOR_TYPE: {
if (commonDesc->bLength!=sizeof(USB_DEVICE_QUALIFIER_DESCRIPTOR_TYPE)) {
OOPS();
displayUnknown = TRUE;
break;
}
DisplayQualifier((const USB_DEVICE_QUALIFIER_DESCRIPTOR*)commonDesc);
}break;
//case USB_CONFIG_POWER_DESCRIPTOR_TYPE: // 7 - wrong!
case USB_INTERFACE_POWER_DESCRIPTOR_TYPE: // 8
DisplayPowerDescriptor((const BYTE*)commonDesc); break;
default: switch (bInterfaceClass) {
case USB_DEVICE_CLASS_AUDIO:
displayUnknown = !DisplayAudioDescriptor(
(PUSB_AUDIO_COMMON_DESCRIPTOR)commonDesc,
bInterfaceSubClass);
break;
default: displayUnknown = TRUE;
}
}
if (displayUnknown) DisplayUnknownDescriptor(commonDesc,(int)(descEnd-(const BYTE*)commonDesc));
(PUCHAR)commonDesc += commonDesc->bLength;
}
}
//*****************************************************************************
//
// DisplayHubInfo()
//
// HubInfo - Info about the hub.
//
//*****************************************************************************
static void DisplayHubInfo(PUSB_HUB_INFORMATION HubInfo) {
USHORT wHubChar;
const char *p;
p = HubInfo->HubIsBusPowered ? "Bus" : "Self";
AppendTextBuffer("Hub Power: "ASTR" Power\r\n",p);
AppendTextBuffer("Number of Ports: %d\r\n", HubInfo->HubDescriptor.bNumberOfPorts);
wHubChar = HubInfo->HubDescriptor.wHubCharacteristics;
switch (wHubChar & 3) {
case 0: p="Ganged"; break;
case 1: p="Individual"; break;
default:p="None";
}
AppendTextBuffer("Power switching: "ASTR"\r\n",p);
p = wHubChar & 4 ? "Yes" : "No";
AppendTextBuffer("Compound device: "ASTR"\r\n",p);
switch (wHubChar & 0x0018) {
case 0x0000: p="Over-current Protection: Global"; break;
case 0x0008: p="Over-current Protection: Individual"; break;
default: p="No Over-current Protection (Bus Power Only)"; break;
}
AppendTextBuffer(ASTR"\r\n\r\n",p);
}
//*****************************************************************************
//
// GetVendorString()
//
// idVendor - USB Vendor ID
//
// Return Value - Vendor name string associated with idVendor, or NULL if
// no vendor name string is found which is associated with idVendor.
//*****************************************************************************
static const char* GetVendorString (USHORT vid) {
const char *p=Lookup(0,vid,-1,-1);
USHORT i;
if (p) return p;
// The following cast requires unaligned WORD data access (true for x86 and x64)
for(p=USBVendorIDs;i=*((const USHORT*)p)++; p+=lstrlenA(p)+1) {
if (i==vid) return p;
}
return NULL;
}
//*****************************************************************************
//
// DisplayPipeInfo()
//
// NumPipes - Number of pipe for we info should be displayed.
//
// PipeInfo - Info about the pipes.
//
//*****************************************************************************
static void DisplayPipeInfo (
ULONG NumPipes,
USB_PIPE_INFO *PipeInfo) {
ULONG i;
for (i=0; i<NumPipes; i++) {
DisplayEndpointDescriptor(&PipeInfo[i].EndpointDescriptor);
}
}
//*****************************************************************************
//
// DisplayConnectionInfo()
//
// ConnectInfo - Info about the connection.
//
//*****************************************************************************
static void DisplayConnectionInfo (
PUSB_NODE_CONNECTION_INFORMATION_EX ConnectInfo,
PSTRING_DESCRIPTOR_NODE StringDescs
) {
if (ConnectInfo->ConnectionStatus == NoDeviceConnected)
{
AppendTextBuffer("ConnectionStatus: NoDeviceConnected\r\n");
}
else{
const char *p;
AppendTextBuffer("Device Descriptor:\r\n");
AppendTextBuffer(" bcdUSB: 0x%04X\r\n",
ConnectInfo->DeviceDescriptor.bcdUSB);
AppendTextBuffer(" bDeviceClass: 0x%02X", ConnectInfo->DeviceDescriptor.bDeviceClass);
p = Lookup('C', ConnectInfo->DeviceDescriptor.bDeviceClass,-1,-1);
if (p) AppendTextBuffer(" ("ASTR")",p);
AppendTextBuffer("\r\n");
AppendTextBuffer(" bDeviceSubClass: 0x%02X", ConnectInfo->DeviceDescriptor.bDeviceSubClass);
p = Lookup('C',ConnectInfo->DeviceDescriptor.bDeviceClass,
ConnectInfo->DeviceDescriptor.bDeviceSubClass,-1);
if (p) AppendTextBuffer(" ("ASTR")",p);
AppendTextBuffer("\r\n");
AppendTextBuffer(" bDeviceProtocol: 0x%02X", ConnectInfo->DeviceDescriptor.bDeviceProtocol);
p = Lookup('C',ConnectInfo->DeviceDescriptor.bDeviceClass,
ConnectInfo->DeviceDescriptor.bDeviceSubClass,
ConnectInfo->DeviceDescriptor.bDeviceProtocol);
if (p) AppendTextBuffer(" ("ASTR")",p);
AppendTextBuffer("\r\n");
AppendTextBuffer(" bMaxPacketSize0: 0x%02X (%d)\r\n",
ConnectInfo->DeviceDescriptor.bMaxPacketSize0,
ConnectInfo->DeviceDescriptor.bMaxPacketSize0);
AppendTextBuffer(" idVendor: 0x%04X", ConnectInfo->DeviceDescriptor.idVendor);
p = GetVendorString(ConnectInfo->DeviceDescriptor.idVendor);
if (p) AppendTextBuffer(" ("ASTR")",p);
AppendTextBuffer("\r\n");
AppendTextBuffer(" idProduct: 0x%04X", ConnectInfo->DeviceDescriptor.idProduct);
p = Lookup(0, ConnectInfo->DeviceDescriptor.idVendor,
ConnectInfo->DeviceDescriptor.idProduct,-1);
if (p) AppendTextBuffer(" ("ASTR")",p);
AppendTextBuffer("\r\n");
AppendTextBuffer(" bcdDevice: 0x%04X", ConnectInfo->DeviceDescriptor.bcdDevice);
p = Lookup(0, ConnectInfo->DeviceDescriptor.idVendor,
ConnectInfo->DeviceDescriptor.idProduct,
ConnectInfo->DeviceDescriptor.bcdDevice);
if (p) AppendTextBuffer(" ("ASTR")",p);
AppendTextBuffer("\r\n");
AppendTextBuffer(" iManufacturer: 0x%02X\r\n", ConnectInfo->DeviceDescriptor.iManufacturer);
if (ConnectInfo->DeviceDescriptor.iManufacturer)
DisplayStringDescriptor(ConnectInfo->DeviceDescriptor.iManufacturer,StringDescs);
AppendTextBuffer(" iProduct: 0x%02X\r\n", ConnectInfo->DeviceDescriptor.iProduct);
if (ConnectInfo->DeviceDescriptor.iProduct)
DisplayStringDescriptor(ConnectInfo->DeviceDescriptor.iProduct,StringDescs);
AppendTextBuffer(" iSerialNumber: 0x%02X\r\n", ConnectInfo->DeviceDescriptor.iSerialNumber);
if (ConnectInfo->DeviceDescriptor.iSerialNumber)
DisplayStringDescriptor(ConnectInfo->DeviceDescriptor.iSerialNumber,StringDescs);
AppendTextBuffer(" bNumConfigurations: 0x%02X\r\n", ConnectInfo->DeviceDescriptor.bNumConfigurations);
AppendTextBuffer("\r\nConnectionStatus: "ASTR"\r\n", ConnectionStatuses[ConnectInfo->ConnectionStatus]);
AppendTextBuffer("Current Config Value: 0x%02X\r\n", ConnectInfo->CurrentConfigurationValue);
switch (ConnectInfo->Speed) {
case UsbLowSpeed: p="Low"; break;
case UsbFullSpeed: p="Full"; break;
case UsbHighSpeed: p="High"; break;
case 3: p="Super"; break;
default: p="unknown";
}
AppendTextBuffer("Device Bus Speed: "ASTR"\r\n",p);
AppendTextBuffer("Device Address: 0x%02X\r\n", ConnectInfo->DeviceAddress);
AppendTextBuffer("Open Pipes: %2d\r\n", ConnectInfo->NumberOfOpenPipes);
if (ConnectInfo->NumberOfOpenPipes)
DisplayPipeInfo(ConnectInfo->NumberOfOpenPipes,ConnectInfo->PipeList);
}
}
//*****************************************************************************
//
// UpdateEditControl()
//
// hTreeItem - Handle of selected TreeView item for which information should
// be displayed in the edit control.
//
//*****************************************************************************
extern void UpdateEditControl(HWND hEditWnd, HWND hTreeWnd, HTREEITEM hTreeItem) {
TV_ITEM tvi;
PUSBDEVICEINFO info;
// Start with an empty text buffer.
//
if (!ResetTextBuffer()) return;
// Get the name of the TreeView item, along with the a pointer to the
// info we stored about the item in the item's lParam.
//
tvi.mask = TVIF_HANDLE | TVIF_TEXT | TVIF_PARAM;
tvi.hItem = hTreeItem;
tvi.pszText = TextBuffer;
tvi.cchTextMax = TextBufferLen-2; // leave space for "\r\n"
TreeView_GetItem(hTreeWnd,&tvi);
info = (PUSBDEVICEINFO)tvi.lParam;
//
// If we didn't store any info for the item, just display the item's
// name, else display the info we stored for the item.
//
if (info) {
if (!info->ConnectionInfo) {
// Must be Root HUB, external devices have Connection Info
//
AppendTextBuffer("Root Hub: %s\r\n",info->HubName);
DisplayHubInfo(&info->HubInfo->u.HubInformation);
}else{
if (info->HubInfo) {
// Must be external HUB external
//
AppendTextBuffer("External Hub: %s\r\n",info->HubName);
DisplayHubInfo(&info->HubInfo->u.HubInformation);
}else{
// Must be external non-HUB device. Nothing special to
// display here that isn't displayed in connection info
// below.
}
// Display info common to any external device
//
DisplayConnectionInfo(info->ConnectionInfo,
info->StringDescs);
AppendTextBuffer("\r\n****************************\r\n");
if (info->ConfigDesc) {
DisplayConfigDesc((PUSB_CONFIGURATION_DESCRIPTOR)(info->ConfigDesc + 1),
info->StringDescs,info->HidDescs);
}
if (info->DeviceQualifier) {
const USB_COMMON_DESCRIPTOR *p=(void*)(info->DeviceQualifier+1);
if (p->bLength!=sizeof(USB_DEVICE_QUALIFIER_DESCRIPTOR) // 10
|| p->bDescriptorType!=USB_DEVICE_QUALIFIER_DESCRIPTOR_TYPE) { // 6
OOPS();
AppendTextBuffer("\r\n"
"Device Firmware Laxity: \"Get Device Qualifier\" not STALLed!");
DisplayUnknownDescriptor(p,info->DeviceQualifier->SetupPacket.wLength);
}else DisplayQualifier((const USB_DEVICE_QUALIFIER_DESCRIPTOR*)p);
}
if (info->OtherSpeed) {
AppendTextBuffer("\r\n\n"
"****************************\r\n"
"** Other Speed Descriptor **\r\n"
"****************************\r\n");
DisplayConfigDesc((PUSB_CONFIGURATION_DESCRIPTOR)(info->OtherSpeed + 1),NULL,NULL);
}
}
}
// All done formatting text buffer with info, now update the edit
// control with the contents of the text buffer
//
SetWindowText(hEditWnd, TextBuffer);
}
#if 0
//*****************************************************************************
//
// DisplayPowerDescriptor()
//
//*****************************************************************************
PCHAR PowerUnits[] =
{
"0.001 mW",
"0.01 mW",
"0.1 mW",
"1 mW",
"10 mW",
"100 mW",
"1 W"
};
VOID
DisplayPowerDescriptor (
PUSB_POWER_DESCRIPTOR PowerDesc
)
{
UCHAR i;
AppendTextBuffer("\r\nPower Descriptor:\r\n");
AppendTextBuffer("bCapabilitiesFlags: 0x%02X (",
PowerDesc->bCapabilitiesFlags);
if (PowerDesc->bCapabilitiesFlags & USB_SUPPORT_D2_WAKEUP)
{
AppendTextBuffer("WakeD2 ");
}
if (PowerDesc->bCapabilitiesFlags & USB_SUPPORT_D1_WAKEUP)
{
AppendTextBuffer("WakeD1 ");
}
if (PowerDesc->bCapabilitiesFlags & USB_SUPPORT_D3_COMMAND)
{
AppendTextBuffer("D3 ");
}
if (PowerDesc->bCapabilitiesFlags & USB_SUPPORT_D2_COMMAND)
{
AppendTextBuffer("D2 ");
}
if (PowerDesc->bCapabilitiesFlags & USB_SUPPORT_D1_COMMAND)
{
AppendTextBuffer("D1 ");
}
if (PowerDesc->bCapabilitiesFlags & USB_SUPPORT_D0_COMMAND)
{
AppendTextBuffer("D0 ");
}
AppendTextBuffer(")\r\n");
AppendTextBuffer("EventNotification: 0x%04X\r\n",
PowerDesc->EventNotification);
AppendTextBuffer("D1LatencyTime: 0x%04X\r\n",
PowerDesc->D1LatencyTime);
AppendTextBuffer("D2LatencyTime: 0x%04X\r\n",
PowerDesc->D2LatencyTime);
AppendTextBuffer("D3LatencyTime: 0x%04X\r\n",
PowerDesc->D3LatencyTime);
AppendTextBuffer("PowerUnit: 0x%02X (" ASTR ")\r\n",
PowerDesc->PowerUnit,
PowerDesc->PowerUnit < sizeof(PowerUnits)/sizeof(PowerUnits[0])
? PowerUnits[PowerDesc->PowerUnit]
: "?");
AppendTextBuffer("D0PowerConsumption: 0x%04X (%5d)\r\n",
PowerDesc->D0PowerConsumption,
PowerDesc->D0PowerConsumption);
AppendTextBuffer("D1PowerConsumption: 0x%04X (%5d)\r\n",
PowerDesc->D1PowerConsumption,
PowerDesc->D1PowerConsumption);
AppendTextBuffer("D2PowerConsumption: 0x%04X (%5d)\r\n",
PowerDesc->D2PowerConsumption,
PowerDesc->D2PowerConsumption);
}
#endif
Detected encoding: ASCII (7 bit) | 2
|