static int rndis_query_response(USBNetState *s,

                rndis_query_msg_type *buf, unsigned int length)

{

    rndis_query_cmplt_type *resp;

    /* oid_supported_list is the largest data reply */

    uint8_t infobuf[sizeof(oid_supported_list)];

    uint32_t bufoffs, buflen;

    int infobuflen;

    unsigned int resplen;



    bufoffs = le32_to_cpu(buf->InformationBufferOffset) + 8;

    buflen = le32_to_cpu(buf->InformationBufferLength);

    if (bufoffs + buflen > length)

        return USB_RET_STALL;



    infobuflen = ndis_query(s, le32_to_cpu(buf->OID),

                            bufoffs + (uint8_t *) buf, buflen, infobuf,

                            sizeof(infobuf));

    resplen = sizeof(rndis_query_cmplt_type) +

            ((infobuflen < 0) ? 0 : infobuflen);

    resp = rndis_queue_response(s, resplen);

    if (!resp)

        return USB_RET_STALL;



    resp->MessageType = cpu_to_le32(RNDIS_QUERY_CMPLT);

    resp->RequestID = buf->RequestID; /* Still LE in msg buffer */

    resp->MessageLength = cpu_to_le32(resplen);



    if (infobuflen < 0) {

        /* OID not supported */

        resp->Status = cpu_to_le32(RNDIS_STATUS_NOT_SUPPORTED);

        resp->InformationBufferLength = cpu_to_le32(0);

        resp->InformationBufferOffset = cpu_to_le32(0);

        return 0;

    }



    resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS);

    resp->InformationBufferOffset =

            cpu_to_le32(infobuflen ? sizeof(rndis_query_cmplt_type) - 8 : 0);

    resp->InformationBufferLength = cpu_to_le32(infobuflen);

    memcpy(resp + 1, infobuf, infobuflen);



    return 0;

}
