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

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