blob: daeb5c0131d9710abc0da9c91d567c132b249c63 [file] [log] [blame]
/*
* Copyright (C) 2010 Damjan Jovanovic
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "windef.h"
#include "winbase.h"
#include "winternl.h"
#include "ddk/wdm.h"
#include "ddk/usb.h"
#include "ddk/usbdlib.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(usbd);
PUSB_INTERFACE_DESCRIPTOR WINAPI USBD_ParseConfigurationDescriptorEx(
PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
PVOID StartPosition, LONG InterfaceNumber,
LONG AlternateSetting, LONG InterfaceClass,
LONG InterfaceSubClass, LONG InterfaceProtocol )
{
/* http://blogs.msdn.com/usbcoreblog/archive/2009/12/12/
* what-is-the-right-way-to-validate-and-parse-configuration-descriptors.aspx
*/
PUSB_INTERFACE_DESCRIPTOR interface;
TRACE( "(%p, %p, %d, %d, %d, %d, %d)\n", ConfigurationDescriptor,
StartPosition, InterfaceNumber, AlternateSetting,
InterfaceClass, InterfaceSubClass, InterfaceProtocol );
interface = (PUSB_INTERFACE_DESCRIPTOR) USBD_ParseDescriptors(
ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength,
StartPosition, USB_INTERFACE_DESCRIPTOR_TYPE );
while (interface != NULL)
{
if ((InterfaceNumber == -1 || interface->bInterfaceNumber == InterfaceNumber) &&
(AlternateSetting == -1 || interface->bAlternateSetting == AlternateSetting) &&
(InterfaceClass == -1 || interface->bInterfaceClass == InterfaceClass) &&
(InterfaceSubClass == -1 || interface->bInterfaceSubClass == InterfaceSubClass) &&
(InterfaceProtocol == -1 || interface->bInterfaceProtocol == InterfaceProtocol))
{
return interface;
}
interface = (PUSB_INTERFACE_DESCRIPTOR) USBD_ParseDescriptors(
ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength,
interface + 1, USB_INTERFACE_DESCRIPTOR_TYPE );
}
return NULL;
}
PUSB_COMMON_DESCRIPTOR WINAPI USBD_ParseDescriptors(
PVOID DescriptorBuffer,
ULONG TotalLength,
PVOID StartPosition,
LONG DescriptorType )
{
PUSB_COMMON_DESCRIPTOR common;
TRACE( "(%p, %u, %p, %d)\n", DescriptorBuffer, TotalLength, StartPosition, DescriptorType );
for (common = (PUSB_COMMON_DESCRIPTOR)DescriptorBuffer;
((char*)common) + sizeof(USB_COMMON_DESCRIPTOR) <= ((char*)DescriptorBuffer) + TotalLength;
common = (PUSB_COMMON_DESCRIPTOR)(((char*)common) + common->bLength))
{
if (StartPosition <= (PVOID)common && common->bDescriptorType == DescriptorType)
return common;
}
return NULL;
}
ULONG WINAPI USBD_GetInterfaceLength(
PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor,
PUCHAR BufferEnd )
{
PUSB_COMMON_DESCRIPTOR common;
ULONG total = InterfaceDescriptor->bLength;
TRACE( "(%p, %p)\n", InterfaceDescriptor, BufferEnd );
for (common = (PUSB_COMMON_DESCRIPTOR)(InterfaceDescriptor + 1);
(((PUCHAR)common) + sizeof(USB_COMMON_DESCRIPTOR)) <= BufferEnd &&
common->bDescriptorType != USB_INTERFACE_DESCRIPTOR_TYPE;
common = (PUSB_COMMON_DESCRIPTOR)(((char*)common) + common->bLength))
{
total += common->bLength;
}
return total;
}
NTSTATUS WINAPI DriverEntry( DRIVER_OBJECT *driver, UNICODE_STRING *path )
{
TRACE( "(%p, %s)\n", driver, debugstr_w(path->Buffer) );
return STATUS_SUCCESS;
}