/*
 * 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);

PURB WINAPI USBD_CreateConfigurationRequest(
        PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, PUSHORT Siz )
{
    URB *urb = NULL;
    USBD_INTERFACE_LIST_ENTRY *interfaceList;
    ULONG interfaceListSize;
    USB_INTERFACE_DESCRIPTOR *interfaceDesc;
    int i;

    TRACE( "(%p, %p)\n", ConfigurationDescriptor, Siz );

    /* http://www.microsoft.com/whdc/archive/usbfaq.mspx
     * claims USBD_CreateConfigurationRequest doesn't support > 1 interface,
     * but is this on Windows 98 only or all versions?
     */

    *Siz = 0;
    interfaceListSize = (ConfigurationDescriptor->bNumInterfaces + 1) * sizeof(USBD_INTERFACE_LIST_ENTRY);
    interfaceList = ExAllocatePool( NonPagedPool, interfaceListSize );
    if (interfaceList)
    {
        RtlZeroMemory( interfaceList,  interfaceListSize );
        interfaceDesc = (PUSB_INTERFACE_DESCRIPTOR) USBD_ParseDescriptors(
            ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength,
            ConfigurationDescriptor, USB_INTERFACE_DESCRIPTOR_TYPE );
        for (i = 0; i < ConfigurationDescriptor->bNumInterfaces && interfaceDesc != NULL; i++)
        {
            interfaceList[i].InterfaceDescriptor = interfaceDesc;
            interfaceDesc = (PUSB_INTERFACE_DESCRIPTOR) USBD_ParseDescriptors(
                ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength,
                interfaceDesc + 1, USB_INTERFACE_DESCRIPTOR_TYPE );
        }
        urb = USBD_CreateConfigurationRequestEx( ConfigurationDescriptor, interfaceList );
        if (urb)
            *Siz = urb->u.UrbHeader.Length;
        ExFreePool( interfaceList );
    }
    return urb;
}

PURB WINAPI USBD_CreateConfigurationRequestEx(
        PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
        PUSBD_INTERFACE_LIST_ENTRY InterfaceList )
{
    URB *urb;
    ULONG size = 0;
    USBD_INTERFACE_LIST_ENTRY *interfaceEntry;
    ULONG interfaceCount = 0;

    TRACE( "(%p, %p)\n", ConfigurationDescriptor, InterfaceList );

    size = sizeof(struct _URB_SELECT_CONFIGURATION);
    for (interfaceEntry = InterfaceList; interfaceEntry->InterfaceDescriptor; interfaceEntry++)
    {
        ++interfaceCount;
        size += (interfaceEntry->InterfaceDescriptor->bNumEndpoints - 1) *
            sizeof(USBD_PIPE_INFORMATION);
    }
    size += (interfaceCount - 1) * sizeof(USBD_INTERFACE_INFORMATION);

    urb = ExAllocatePool( NonPagedPool, size );
    if (urb)
    {
        USBD_INTERFACE_INFORMATION *interfaceInfo;

        RtlZeroMemory( urb, size );
        urb->u.UrbSelectConfiguration.Hdr.Length = size;
        urb->u.UrbSelectConfiguration.Hdr.Function = URB_FUNCTION_SELECT_CONFIGURATION;
        urb->u.UrbSelectConfiguration.ConfigurationDescriptor = ConfigurationDescriptor;
        interfaceInfo = &urb->u.UrbSelectConfiguration.Interface;
        for (interfaceEntry = InterfaceList; interfaceEntry->InterfaceDescriptor; interfaceEntry++)
        {
            int i;
            USB_INTERFACE_DESCRIPTOR *currentInterface;
            USB_ENDPOINT_DESCRIPTOR *endpointDescriptor;
            interfaceInfo->InterfaceNumber = interfaceEntry->InterfaceDescriptor->bInterfaceNumber;
            interfaceInfo->AlternateSetting = interfaceEntry->InterfaceDescriptor->bAlternateSetting;
            interfaceInfo->Class = interfaceEntry->InterfaceDescriptor->bInterfaceClass;
            interfaceInfo->SubClass = interfaceEntry->InterfaceDescriptor->bInterfaceSubClass;
            interfaceInfo->Protocol = interfaceEntry->InterfaceDescriptor->bInterfaceProtocol;
            interfaceInfo->NumberOfPipes = interfaceEntry->InterfaceDescriptor->bNumEndpoints;
            currentInterface = USBD_ParseConfigurationDescriptorEx(
                ConfigurationDescriptor, ConfigurationDescriptor,
                interfaceEntry->InterfaceDescriptor->bInterfaceNumber, -1, -1, -1, -1 );
            endpointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR) USBD_ParseDescriptors(
                ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength,
                currentInterface, USB_ENDPOINT_DESCRIPTOR_TYPE );
            for (i = 0; i < interfaceInfo->NumberOfPipes && endpointDescriptor; i++)
            {
                interfaceInfo->Pipes[i].MaximumPacketSize = endpointDescriptor->wMaxPacketSize;
                interfaceInfo->Pipes[i].EndpointAddress = endpointDescriptor->bEndpointAddress;
                interfaceInfo->Pipes[i].Interval = endpointDescriptor->bInterval;
                switch (endpointDescriptor->bmAttributes & USB_ENDPOINT_TYPE_MASK)
                {
                case USB_ENDPOINT_TYPE_CONTROL:
                    interfaceInfo->Pipes[i].PipeType = UsbdPipeTypeControl;
                    break;
                case USB_ENDPOINT_TYPE_BULK:
                    interfaceInfo->Pipes[i].PipeType = UsbdPipeTypeBulk;
                    break;
                case USB_ENDPOINT_TYPE_INTERRUPT:
                    interfaceInfo->Pipes[i].PipeType = UsbdPipeTypeInterrupt;
                    break;
                case USB_ENDPOINT_TYPE_ISOCHRONOUS:
                    interfaceInfo->Pipes[i].PipeType = UsbdPipeTypeIsochronous;
                    break;
                }
                endpointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR) USBD_ParseDescriptors(
                    ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength,
                    endpointDescriptor + 1, USB_ENDPOINT_DESCRIPTOR_TYPE );
            }
            interfaceInfo->Length = sizeof(USBD_INTERFACE_INFORMATION) +
                (i - 1) * sizeof(USBD_PIPE_INFORMATION);
            interfaceEntry->Interface = interfaceInfo;
            interfaceInfo = (USBD_INTERFACE_INFORMATION*)(((char*)interfaceInfo)+interfaceInfo->Length);
        }
    }
    return urb;
}

VOID WINAPI USBD_GetUSBDIVersion(
        PUSBD_VERSION_INFORMATION VersionInformation )
{
    TRACE( "(%p)\n", VersionInformation );
    /* Emulate Windows 2000 (= 0x300) for now */
    VersionInformation->USBDI_Version = 0x300;
    VersionInformation->Supported_USB_Version = 0x200;
}

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;
}
