/*
 * 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++)
        {
            ULONG 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_INTERFACE_DESCRIPTOR WINAPI USBD_ParseConfigurationDescriptor(
        PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, UCHAR InterfaceNumber,
        UCHAR AlternateSetting )
{
    TRACE( "(%p, %u, %u)\n", ConfigurationDescriptor, InterfaceNumber, AlternateSetting );
    return USBD_ParseConfigurationDescriptorEx( ConfigurationDescriptor, ConfigurationDescriptor,
                                                InterfaceNumber, AlternateSetting, -1, -1, -1 );
}

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

USBD_STATUS WINAPI USBD_ValidateConfigurationDescriptor(
        PUSB_CONFIGURATION_DESCRIPTOR descr,
        ULONG length,
        USHORT level,
        PUCHAR *offset,
        ULONG tag )
{
    FIXME( "(%p, %u, %u, %p, %u) partial stub!\n", descr, length, level, offset, tag );

    if (offset) *offset = 0;

    if (!descr ||
        length < sizeof(USB_CONFIGURATION_DESCRIPTOR) ||
        descr->bLength < sizeof(USB_CONFIGURATION_DESCRIPTOR) ||
        descr->wTotalLength < descr->bNumInterfaces * sizeof(USB_CONFIGURATION_DESCRIPTOR)
       ) return USBD_STATUS_ERROR;

    return USBD_STATUS_SUCCESS;
}

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