#define FETCH_VIRTUAL_CONFIG_DESCRIPTOR
#include "examples.h"
typedef struct _DESCRIPTOR_ITERATOR
{
LONG Remaining;
union
{
PUCHAR Bytes;
PUSB_COMMON_DESCRIPTOR Common;
PUSB_CONFIGURATION_DESCRIPTOR Config;
PUSB_INTERFACE_DESCRIPTOR Interface;
PUSB_ENDPOINT_DESCRIPTOR Endpoint;
} Ptr;
} DESCRIPTOR_ITERATOR, *PDESCRIPTOR_ITERATOR;
BOOL InitDescriptorIterator(PDESCRIPTOR_ITERATOR descIterator, BYTE* configDescriptor, DWORD lengthTransferred);
BOOL NextDescriptor(PDESCRIPTOR_ITERATOR descIterator);
void PrintConfigDescriptor(PUSB_CONFIGURATION_DESCRIPTOR desc);
void PrintInterfaceDescriptor(PUSB_INTERFACE_DESCRIPTOR desc);
void PrintEndpointDescriptor(PUSB_ENDPOINT_DESCRIPTOR desc);
KUSB_DRIVER_API Usb;
BOOL InitDescriptorIterator(PDESCRIPTOR_ITERATOR descIterator, BYTE* configDescriptor, DWORD lengthTransferred)
{
memset(descIterator, 0, sizeof(descIterator));
descIterator->Ptr.Bytes = configDescriptor;
descIterator->Remaining = descIterator->Ptr.Config->wTotalLength;
if (lengthTransferred > sizeof(USB_CONFIGURATION_DESCRIPTOR) && lengthTransferred >= descIterator->Ptr.Config->wTotalLength)
{
if ( descIterator->Ptr.Config->wTotalLength >= sizeof(USB_CONFIGURATION_DESCRIPTOR) + sizeof(USB_INTERFACE_DESCRIPTOR))
return TRUE;
}
SetLastError(ERROR_BAD_LENGTH);
descIterator->Remaining = 0;
return FALSE;
}
BOOL NextDescriptor(PDESCRIPTOR_ITERATOR descIterator)
{
if (descIterator->Remaining >= sizeof(USB_COMMON_DESCRIPTOR) && descIterator->Remaining >= descIterator->Ptr.Common->bLength)
{
descIterator->Remaining -= descIterator->Ptr.Common->bLength;
if (descIterator->Remaining >= sizeof(USB_COMMON_DESCRIPTOR))
{
descIterator->Ptr.Bytes += descIterator->Ptr.Common->bLength;
return TRUE;
}
}
descIterator->Remaining = 0;
SetLastError(ERROR_NO_MORE_ITEMS);
return FALSE;
}
DWORD __cdecl main(int argc, char* argv[])
{
KLST_HANDLE deviceList = NULL; KLST_DEVINFO_HANDLE deviceInfo = NULL; KUSB_HANDLE usbHandle = NULL; DWORD errorCode = ERROR_SUCCESS;
WINUSB_SETUP_PACKET Pkt;
KUSB_SETUP_PACKET* kPkt = (KUSB_SETUP_PACKET*)&Pkt;
BYTE configDescriptorBuffer[4096];
DWORD lengthTransferred;
DESCRIPTOR_ITERATOR descIterator;
if (!Examples_GetTestDevice(&deviceList, &deviceInfo, argc, argv))
return GetLastError();
LibK_LoadDriverAPI(&Usb, deviceInfo->DriverID);
if (!Usb.Init(&usbHandle, deviceInfo))
{
errorCode = GetLastError();
printf("Open device failed. Win32Error=%u (0x%08X)\n", errorCode, errorCode);
goto Done;
}
printf("Device opened successfully!\n");
memset(&Pkt, 0, sizeof(Pkt));
kPkt->BmRequest.Dir = BMREQUEST_DIR_DEVICE_TO_HOST;
kPkt->Request = USB_REQUEST_GET_DESCRIPTOR;
kPkt->ValueHi = USB_DESCRIPTOR_TYPE_CONFIGURATION;
kPkt->ValueLo = 0; kPkt->Length = (USHORT)sizeof(configDescriptorBuffer);
#ifndef FETCH_VIRTUAL_CONFIG_DESCRIPTOR
if (!Usb.ControlTransfer(usbHandle, Pkt, configDescriptorBuffer, sizeof(configDescriptorBuffer), &lengthTransferred, NULL))
{
errorCode = GetLastError();
printf("ControlTransfer failed. Win32Error=%u (0x%08X)\n", errorCode, errorCode);
goto Done;
}
#else
if (!Usb.GetDescriptor(usbHandle, USB_DESCRIPTOR_TYPE_CONFIGURATION, 0, 0, configDescriptorBuffer, sizeof(configDescriptorBuffer), &lengthTransferred))
{
errorCode = GetLastError();
printf("GetDescriptor failed. Win32Error=%u (0x%08X)\n", errorCode, errorCode);
goto Done;
}
#endif
if (!InitDescriptorIterator(&descIterator, configDescriptorBuffer, lengthTransferred))
{
errorCode = GetLastError();
printf("InitDescriptorIterator failed. Win32Error=%u (0x%08X)\n", errorCode, errorCode);
goto Done;
}
PrintConfigDescriptor(descIterator.Ptr.Config);
while(NextDescriptor(&descIterator))
{
switch (descIterator.Ptr.Common->bDescriptorType)
{
case USB_DESCRIPTOR_TYPE_INTERFACE:
PrintInterfaceDescriptor(descIterator.Ptr.Interface);
break;
case USB_DESCRIPTOR_TYPE_ENDPOINT:
PrintEndpointDescriptor(descIterator.Ptr.Endpoint);
break;
}
}
Done:
if (usbHandle) Usb.Free(usbHandle);
LstK_Free(deviceList);
return errorCode;
}
void PrintConfigDescriptor(PUSB_CONFIGURATION_DESCRIPTOR desc)
{
printf("[Config Descriptor]\n");
printf(" bLength :%d\n", desc->bLength);
printf(" bDescriptorType :0x%02X\n", desc->bDescriptorType);
printf(" wTotalLength :%d\n", desc->wTotalLength);
printf(" bNumInterfaces :%d\n", desc->bNumInterfaces);
printf(" bConfigurationValue :%d\n", desc->bConfigurationValue);
printf(" iConfiguration :%d\n", desc->iConfiguration);
printf(" bmAttributes :0x%02X\n", desc->bmAttributes);
printf(" MaxPower :%d\n", desc->MaxPower);
}
void PrintInterfaceDescriptor(PUSB_INTERFACE_DESCRIPTOR desc)
{
printf(" [Interface Descriptor]\n");
printf(" bLength :%d\n", desc->bLength);
printf(" bDescriptorType :0x%02X\n", desc->bDescriptorType);
printf(" bInterfaceNumber :%d\n", desc->bInterfaceNumber);
printf(" bAlternateSetting :%d\n", desc->bAlternateSetting);
printf(" bNumEndpoints :%d\n", desc->bNumEndpoints);
printf(" bInterfaceClass :0x%02X\n", desc->bInterfaceClass);
printf(" bInterfaceSubClass :0x%02X\n", desc->bInterfaceSubClass);
printf(" bInterfaceProtocol :0x%02X\n", desc->bInterfaceProtocol);
printf(" iInterface :%d\n", desc->iInterface);
}
void PrintEndpointDescriptor(PUSB_ENDPOINT_DESCRIPTOR desc)
{
WORD baseMaxPacketSize = desc->wMaxPacketSize & 0x7ff;
WORD packetsPerFrame = ((desc->wMaxPacketSize & 0x1800) >> 11) + 1;
WORD maxPacketSize = baseMaxPacketSize * packetsPerFrame;
printf(" [Endpoint Descriptor]\n");
printf(" bLength :%d\n", desc->bLength);
printf(" bDescriptorType :0x%02X\n", desc->bDescriptorType);
printf(" bEndpointAddress :0x%02X\n", desc->bEndpointAddress);
printf(" bmAttributes :0x%02X\n", desc->bmAttributes);
printf(" wMaxPacketSize :%d", maxPacketSize);
if (packetsPerFrame > 1)
printf(" (%d x %d) [High-Bandwidth]\n", baseMaxPacketSize, packetsPerFrame);
else
printf("\n");
printf(" bInterval :%d\n", desc->bInterval);
}