#include "hw/usb.h"
#include "hw/usb/desc.h"

/*
 * Microsoft OS Descriptors
 *
 * Windows tries to fetch some special descriptors with informations
 * specifically for windows.  Presence is indicated using a special
 * string @ index 0xee.  There are two kinds of descriptors:
 *
 * compatid descriptor
 *   Used to bind drivers, if usb class isn't specific enougth.
 *   Used for PTP/MTP for example (both share the same usb class).
 *
 * properties descriptor
 *   Does carry registry entries.  They show up in
 *   HLM\SYSTEM\CurrentControlSet\Enum\USB\<devid>\<serial>\Device Parameters
 *
 * Note that Windows caches the stuff it got in the registry, so when
 * playing with this you have to delete registry subtrees to make
 * windows query the device again:
 *   HLM\SYSTEM\CurrentControlSet\Control\usbflags
 *   HLM\SYSTEM\CurrentControlSet\Enum\USB
 * Windows will complain it can't delete entries on the second one.
 * It has deleted everything it had permissions too, which is enouth
 * as this includes "Device Parameters".
 *
 * http://msdn.microsoft.com/en-us/library/windows/hardware/ff537430.aspx
 *
 */

/* ------------------------------------------------------------------ */

typedef struct msos_compat_hdr {
    uint32_t dwLength;
    uint8_t  bcdVersion_lo;
    uint8_t  bcdVersion_hi;
    uint8_t  wIndex_lo;
    uint8_t  wIndex_hi;
    uint8_t  bCount;
    uint8_t  reserved[7];
} QEMU_PACKED msos_compat_hdr;

typedef struct msos_compat_func {
    uint8_t  bFirstInterfaceNumber;
    uint8_t  reserved_1;
    uint8_t  compatibleId[8];
    uint8_t  subCompatibleId[8];
    uint8_t  reserved_2[6];
} QEMU_PACKED msos_compat_func;

static int usb_desc_msos_compat(const USBDesc *desc, uint8_t *dest)
{
    msos_compat_hdr *hdr = (void *)dest;
    msos_compat_func *func;
    int length = sizeof(*hdr);
    int count = 0;

    func = (void *)(dest + length);
    func->bFirstInterfaceNumber = 0;
    func->reserved_1 = 0x01;
    length += sizeof(*func);
    count++;

    hdr->dwLength      = cpu_to_le32(length);
    hdr->bcdVersion_lo = 0x00;
    hdr->bcdVersion_hi = 0x01;
    hdr->wIndex_lo     = 0x04;
    hdr->wIndex_hi     = 0x00;
    hdr->bCount        = count;
    return length;
}

/* ------------------------------------------------------------------ */

typedef struct msos_prop_hdr {
    uint32_t dwLength;
    uint8_t  bcdVersion_lo;
    uint8_t  bcdVersion_hi;
    uint8_t  wIndex_lo;
    uint8_t  wIndex_hi;
    uint8_t  wCount_lo;
    uint8_t  wCount_hi;
} QEMU_PACKED msos_prop_hdr;

typedef struct msos_prop {
    uint32_t dwLength;
    uint32_t dwPropertyDataType;
    uint8_t  dwPropertyNameLength_lo;
    uint8_t  dwPropertyNameLength_hi;
    uint8_t  bPropertyName[];
} QEMU_PACKED msos_prop;

typedef struct msos_prop_data {
    uint32_t dwPropertyDataLength;
    uint8_t  bPropertyData[];
} QEMU_PACKED msos_prop_data;

typedef enum msos_prop_type {
    MSOS_REG_SZ        = 1,
    MSOS_REG_EXPAND_SZ = 2,
    MSOS_REG_BINARY    = 3,
    MSOS_REG_DWORD_LE  = 4,
    MSOS_REG_DWORD_BE  = 5,
    MSOS_REG_LINK      = 6,
    MSOS_REG_MULTI_SZ  = 7,
} msos_prop_type;

static int usb_desc_msos_prop_name(struct msos_prop *prop,
                                   const wchar_t *name)
{
    int length = wcslen(name) + 1;
    int i;

    prop->dwPropertyNameLength_lo = usb_lo(length*2);
    prop->dwPropertyNameLength_hi = usb_hi(length*2);
    for (i = 0; i < length; i++) {
        prop->bPropertyName[i*2]   = usb_lo(name[i]);
        prop->bPropertyName[i*2+1] = usb_hi(name[i]);
    }
    return length*2;
}

static int usb_desc_msos_prop_str(uint8_t *dest, msos_prop_type type,
                                  const wchar_t *name, const wchar_t *value)
{
    struct msos_prop *prop = (void *)dest;
    struct msos_prop_data *data;
    int length = sizeof(*prop);
    int i, vlen = wcslen(value) + 1;

    prop->dwPropertyDataType = cpu_to_le32(type);
    length += usb_desc_msos_prop_name(prop, name);
    data = (void *)(dest + length);

    data->dwPropertyDataLength = cpu_to_le32(vlen*2);
    length += sizeof(*prop);

    for (i = 0; i < vlen; i++) {
        data->bPropertyData[i*2]   = usb_lo(value[i]);
        data->bPropertyData[i*2+1] = usb_hi(value[i]);
    }
    length += vlen*2;

    prop->dwLength = cpu_to_le32(length);
    return length;
}

static int usb_desc_msos_prop_dword(uint8_t *dest, const wchar_t *name,
                                    uint32_t value)
{
    struct msos_prop *prop = (void *)dest;
    struct msos_prop_data *data;
    int length = sizeof(*prop);

    prop->dwPropertyDataType = cpu_to_le32(MSOS_REG_DWORD_LE);
    length += usb_desc_msos_prop_name(prop, name);
    data = (void *)(dest + length);

    data->dwPropertyDataLength = cpu_to_le32(4);
    data->bPropertyData[0] = (value)       & 0xff;
    data->bPropertyData[1] = (value >>  8) & 0xff;
    data->bPropertyData[2] = (value >> 16) & 0xff;
    data->bPropertyData[3] = (value >> 24) & 0xff;
    length += sizeof(*prop) + 4;

    prop->dwLength = cpu_to_le32(length);
    return length;
}

static int usb_desc_msos_prop(const USBDesc *desc, uint8_t *dest)
{
    msos_prop_hdr *hdr = (void *)dest;
    int length = sizeof(*hdr);
    int count = 0;

    if (desc->msos->Label) {
        /*
         * Given as example in the specs.  Havn't figured yet where
         * this label shows up in the windows gui.
         */
        length += usb_desc_msos_prop_str(dest+length, MSOS_REG_SZ,
                                         L"Label", desc->msos->Label);
        count++;
    }

    if (desc->msos->SelectiveSuspendEnabled) {
        /*
         * Signaling remote wakeup capability in the standard usb
         * descriptors isn't enouth to make windows actually use it.
         * This is the "Yes, we really mean it" registy entry to flip
         * the switch in the windows drivers.
         */
        length += usb_desc_msos_prop_dword(dest+length,
                                           L"SelectiveSuspendEnabled", 1);
        count++;
    }

    hdr->dwLength      = cpu_to_le32(length);
    hdr->bcdVersion_lo = 0x00;
    hdr->bcdVersion_hi = 0x01;
    hdr->wIndex_lo     = 0x05;
    hdr->wIndex_hi     = 0x00;
    hdr->wCount_lo     = usb_lo(count);
    hdr->wCount_hi     = usb_hi(count);
    return length;
}

/* ------------------------------------------------------------------ */

int usb_desc_msos(const USBDesc *desc,  USBPacket *p,
                  int index, uint8_t *dest, size_t len)
{
    void *buf = g_malloc0(4096);
    int length = 0;

    switch (index) {
    case 0x0004:
        length = usb_desc_msos_compat(desc, buf);
        break;
    case 0x0005:
        length = usb_desc_msos_prop(desc, buf);
        break;
    }

    if (length > len) {
        length = len;
    }
    memcpy(dest, buf, length);
    free(buf);

    p->actual_length = length;
    return 0;
}
