Leaked source code of windows server 2003
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
/*++
Copyright (c) Microsoft Corporation. All rights reserved.
Module Name:
TOOLS.C
Abstract:
This module contains the tools for the helper lib that talks to the generic USB driver
Environment:
Kernel & user mode
Revision History:
Sept-01 : created by Kenneth Ray
--*/
#include <stdlib.h>
#include <wtypes.h>
#include <winioctl.h>
#include <assert.h>
#include <initguid.h>
#include "genusbio.h"
#include "umgusb.h"
PUSB_COMMON_DESCRIPTOR __stdcall GenUSB_ParseDescriptor( IN PVOID DescriptorBuffer, IN ULONG TotalLength, IN PVOID StartPosition, IN LONG DescriptorType ) /*++
Routine Description:
Parses a group of standard USB configuration descriptors (returned from a device) for a specific descriptor type.
Arguments:
DescriptorBuffer - pointer to a block of contiguous USB desscriptors TotalLength - size in bytes of the Descriptor buffer StartPosition - starting position in the buffer to begin parsing, this must point to the begining of a USB descriptor. DescriptorType - USB descritor type to locate.
Return Value:
pointer to a usb descriptor with a DescriptorType field matching the input parameter or NULL if not found.
--*/ { PUCHAR pch; PUCHAR end; PUSB_COMMON_DESCRIPTOR usbDescriptor; PUSB_COMMON_DESCRIPTOR foundUsbDescriptor;
pch = (PUCHAR) StartPosition; end = ((PUCHAR) (DescriptorBuffer)) + TotalLength; foundUsbDescriptor = NULL;
while (pch < end) { // see if we are pointing at the right descriptor
// if not skip over the other junk
usbDescriptor = (PUSB_COMMON_DESCRIPTOR) pch;
if ((0 == DescriptorType) || (usbDescriptor->bDescriptorType == DescriptorType)) { foundUsbDescriptor = usbDescriptor; break; }
// catch the evil case which will keep us looping forever.
if (usbDescriptor->bLength == 0) { break; } pch += usbDescriptor->bLength; } return foundUsbDescriptor; }
PGENUSB_CONFIGURATION_INFORMATION_ARRAY __stdcall GenUSB_ParseDescriptorsToArray( IN PUSB_CONFIGURATION_DESCRIPTOR ConfigDescriptor ) { UCHAR numberInterfaces; UCHAR numberOtherDescriptors; UCHAR numberEndpointDescriptors; ULONG size; PCHAR buffer; PCHAR bufferEnd; PVOID end; PUSB_COMMON_DESCRIPTOR current; PGENUSB_INTERFACE_DESCRIPTOR_ARRAY interfaceArray; PGENUSB_CONFIGURATION_INFORMATION_ARRAY configArray; PUSB_ENDPOINT_DESCRIPTOR * endpointArray; PUSB_COMMON_DESCRIPTOR * otherArray; //
// Create a flat memory structure that will hold this array of arrays
// to descriptors
//
numberInterfaces = 0; numberEndpointDescriptors = 0; numberOtherDescriptors = 0;
//
// Walk the list first to count the number of descriptors in this
// Configuration descriptor.
//
current = (PUSB_COMMON_DESCRIPTOR) ConfigDescriptor; end = (PVOID) ((PCHAR) current + ConfigDescriptor->wTotalLength);
size = 0;
for ( ;(PVOID)current < end; (PUCHAR) current += current->bLength) { current = GenUSB_ParseDescriptor (ConfigDescriptor, ConfigDescriptor->wTotalLength, current, 0); // the very next one.
if (NULL == current) { //
// There's a problem with this config descriptor
// Throw up our hands
//
return NULL; } if (0 == current->bLength) { //
// There's a problem with this config descriptor
// Throw up our hands
//
return NULL; } if (USB_CONFIGURATION_DESCRIPTOR_TYPE == current->bDescriptorType) { // Skip this one.
; } else if (USB_INTERFACE_DESCRIPTOR_TYPE == current->bDescriptorType) { numberInterfaces++; } else if (USB_ENDPOINT_DESCRIPTOR_TYPE == current->bDescriptorType) { numberEndpointDescriptors++; size += ROUND_TO_PTR (current->bLength); } else { numberOtherDescriptors++; size += ROUND_TO_PTR (current->bLength); } } if (0 == numberInterfaces) { //
// There's a problem with this config descriptor
// Throw up our hands
//
return NULL; }
// size now has room for all of the descriptor data, no make room for headers
size += sizeof (GENUSB_CONFIGURATION_INFORMATION_ARRAY) // Global structure
// the interfaces structures
+ (sizeof (GENUSB_INTERFACE_DESCRIPTOR_ARRAY) * numberInterfaces) // array of pointers to the endpoint descriptors
+ (sizeof (PVOID) * numberEndpointDescriptors) // array of pointers to the other descriptors
+ (sizeof (PVOID) * numberOtherDescriptors);
configArray = malloc (size); if (NULL == configArray) { return configArray; } ZeroMemory (configArray, size); bufferEnd = (PCHAR) configArray + size;
//
// Fill in the top array
//
configArray->NumberInterfaces = numberInterfaces; buffer = (PCHAR) configArray + sizeof (GENUSB_CONFIGURATION_INFORMATION_ARRAY) + sizeof (GENUSB_INTERFACE_DESCRIPTOR_ARRAY) * numberInterfaces;
endpointArray = (PUSB_ENDPOINT_DESCRIPTOR *) buffer; buffer += sizeof (PVOID) * numberEndpointDescriptors;
otherArray = (PUSB_COMMON_DESCRIPTOR *) buffer; //
// Walk the array again putting the data into our arrays.
//
current = (PUSB_COMMON_DESCRIPTOR) ConfigDescriptor; numberInterfaces = 0; interfaceArray = NULL; for ( ;(PVOID)current < end; (PUCHAR) current += current->bLength) { current = GenUSB_ParseDescriptor (ConfigDescriptor, ConfigDescriptor->wTotalLength, current, 0); // the very next one.
if (USB_CONFIGURATION_DESCRIPTOR_TYPE == current->bDescriptorType) { // should only get here once
configArray->ConfigurationDescriptor = * (PUSB_CONFIGURATION_DESCRIPTOR) current; } else if (USB_INTERFACE_DESCRIPTOR_TYPE == current->bDescriptorType) { //
// Allocate an interface array
//
interfaceArray = &configArray->Interfaces[numberInterfaces++]; interfaceArray->Interface = *((PUSB_INTERFACE_DESCRIPTOR) current); interfaceArray->NumberEndpointDescriptors = 0; interfaceArray->NumberOtherDescriptors = 0; interfaceArray->EndpointDescriptors = endpointArray; interfaceArray->OtherDescriptors = otherArray;
} else { //
// you must first have an interface descriptor before you
// can have any other type of descriptors.
// So if we get here without interfaceArray set to something
// Then there's a problem with your descriptor and we
// should throw up our hands.
//
if (NULL == interfaceArray) { free (configArray); return NULL; } //
// allocate this one from the end.
//
bufferEnd -= ROUND_TO_PTR(current->bLength); CopyMemory (bufferEnd, current, current->bLength);
if (USB_ENDPOINT_DESCRIPTOR_TYPE == current->bDescriptorType) { *endpointArray = (PUSB_ENDPOINT_DESCRIPTOR) bufferEnd; endpointArray++; interfaceArray->NumberEndpointDescriptors++; } else { *otherArray = (PUSB_COMMON_DESCRIPTOR) bufferEnd; otherArray++; interfaceArray->NumberOtherDescriptors++; } } }
if ((PCHAR) otherArray != bufferEnd) { // shootme.
assert ((PCHAR) otherArray == bufferEnd); free (configArray); return NULL; } else if ((PCHAR)endpointArray != buffer) { // shootme.
assert ((PCHAR)endpointArray != buffer); free (configArray); return NULL; } return configArray; }
void __stdcall GenUSB_FreeConfigurationDescriptorArray ( PGENUSB_CONFIGURATION_INFORMATION_ARRAY ConfigurationArray ) { free (ConfigurationArray); }
|