Пример #1
0
/**
 * Converts a partition entry to the host endianness.
 *
 * @returns nothing.
 * @param   pPartition    The partition to decode.
 */
static void rtDvmFmtBsdLblDiskLabelDecodePartition(PBsdLabelPartition pPartition)
{
    pPartition->cSectors       = RT_LE2H_U32(pPartition->cSectors);
    pPartition->offSectorStart = RT_LE2H_U32(pPartition->offSectorStart);
    pPartition->cbFsFragment   = RT_LE2H_U32(pPartition->cbFsFragment);
    pPartition->cFsCylPerGroup = RT_LE2H_U16(pPartition->cFsCylPerGroup);
}
Пример #2
0
/**
 * Get and a device descriptor and byteswap it appropriately.
 */
static bool usbProxyGetDeviceDesc(PUSBPROXYDEV pProxyDev, PVUSBDESCDEVICE pOut)
{
    /*
     * Get the descriptor from the device.
     */
    PVUSBDESCDEVICE pIn = (PVUSBDESCDEVICE)GetStdDescSync(pProxyDev, VUSB_DT_DEVICE, 0, 0, VUSB_DT_DEVICE_MIN_LEN);
    if (!pIn)
    {
        Log(("usbProxyGetDeviceDesc: pProxyDev=%s: GetStdDescSync failed\n", pProxyDev->pUsbIns->pszName));
        return false;
    }
    if (pIn->bLength < VUSB_DT_DEVICE_MIN_LEN)
    {
        Log(("usb-proxy: pProxyDev=%s: Corrupted device descriptor. bLength=%d\n", pProxyDev->pUsbIns->pszName, pIn->bLength));
        return false;
    }

    /*
     * Convert it.
     */
    pOut->bLength            = VUSB_DT_DEVICE_MIN_LEN;
    pOut->bDescriptorType    = VUSB_DT_DEVICE;
    pOut->bcdUSB             = RT_LE2H_U16(pIn->bcdUSB);
    pOut->bDeviceClass       = pIn->bDeviceClass;
    pOut->bDeviceSubClass    = pIn->bDeviceSubClass;
    pOut->bDeviceProtocol    = pIn->bDeviceProtocol;
    pOut->bMaxPacketSize0    = pIn->bMaxPacketSize0;
    pOut->idVendor           = RT_LE2H_U16(pIn->idVendor);
    pOut->idProduct          = RT_LE2H_U16(pIn->idProduct);
    pOut->bcdDevice          = RT_LE2H_U16(pIn->bcdDevice);
    pOut->iManufacturer      = pIn->iManufacturer;
    pOut->iProduct           = pIn->iProduct;
    pOut->iSerialNumber      = pIn->iSerialNumber;
    pOut->bNumConfigurations = pIn->bNumConfigurations;

    free_desc(pIn);
    return true;
}
Пример #3
0
/* Synchronously obtain a standard USB descriptor for a device, used in order
 * to grab configuration descriptors when we first add the device
 */
static void *GetStdDescSync(PUSBPROXYDEV pProxyDev, uint8_t iDescType, uint8_t iIdx, uint16_t LangId, uint16_t cbHint)
{
    LogFlow(("GetStdDescSync: pProxyDev=%s\n", pProxyDev->pUsbIns->pszName));
    for (;;)
    {
        /*
         * Setup a MSG URB, queue and reap it.
         */
        int rc = VINF_SUCCESS;
        VUSBURB Urb;
        AssertCompile(RT_SIZEOFMEMB(VUSBURB, abData) >= _4K);
        Urb.u32Magic = VUSBURB_MAGIC;
        Urb.enmState = VUSBURBSTATE_IN_FLIGHT;
        Urb.pszDesc = (char*)"URB sync";
        memset(&Urb.VUsb, 0, sizeof(Urb.VUsb));
        memset(&Urb.Hci, 0, sizeof(Urb.Hci));
        Urb.Dev.pvPrivate = NULL;
        Urb.Dev.pNext = NULL;
        Urb.pUsbIns = pProxyDev->pUsbIns;
        Urb.DstAddress = 0;
        Urb.EndPt = 0;
        Urb.enmType = VUSBXFERTYPE_MSG;
        Urb.enmDir = VUSBDIRECTION_IN;
        Urb.fShortNotOk = false;
        Urb.enmStatus = VUSBSTATUS_INVALID;
        cbHint = RT_MIN(cbHint, sizeof(Urb.abData) - sizeof(VUSBSETUP));
        Urb.cbData = cbHint + sizeof(VUSBSETUP);

        PVUSBSETUP pSetup = (PVUSBSETUP)Urb.abData;
        pSetup->bmRequestType = VUSB_DIR_TO_HOST | VUSB_REQ_STANDARD | VUSB_TO_DEVICE;
        pSetup->bRequest = VUSB_REQ_GET_DESCRIPTOR;
        pSetup->wValue = (iDescType << 8) | iIdx;
        pSetup->wIndex = LangId;
        pSetup->wLength = cbHint;

        rc = pProxyDev->pOps->pfnUrbQueue(pProxyDev, &Urb);
        if (RT_FAILURE(rc))
            break;

        /* Don't wait forever, it's just a simple request that should
           return immediately. Since we're executing in the EMT thread
           it's important not to get stuck here. (Some of the builtin
           iMac devices may not refuse respond for instance.) */
        PVUSBURB pUrbReaped = pProxyDev->pOps->pfnUrbReap(pProxyDev, 10000 /* ms */);
        if (!pUrbReaped)
        {
            rc = pProxyDev->pOps->pfnUrbCancel(pProxyDev, &Urb);
            AssertRC(rc);
            /** @todo: This breaks the comment above... */
            pUrbReaped = pProxyDev->pOps->pfnUrbReap(pProxyDev, RT_INDEFINITE_WAIT);
        }
        if (pUrbReaped != &Urb)
        {
            Log(("GetStdDescSync: pfnUrbReap failed, pUrbReaped=%p\n", pUrbReaped));
            break;
        }

        if (Urb.enmStatus != VUSBSTATUS_OK)
        {
            Log(("GetStdDescSync: Urb.enmStatus=%d\n", Urb.enmStatus));
            break;
        }

        /*
         * Check the length, config descriptors have total_length field
         */
        uint8_t *pbDesc = (uint8_t *)(pSetup + 1);
        uint32_t cbDesc;
        if (iDescType == VUSB_DT_CONFIG)
        {
            if (Urb.cbData < sizeof(VUSBSETUP) + 4)
            {
                Log(("GetStdDescSync: Urb.cbData=%#x (min 4)\n", Urb.cbData));
                break;
            }
            cbDesc = RT_LE2H_U16(((uint16_t *)pbDesc)[1]);
        }
        else
        {
            if (Urb.cbData < sizeof(VUSBSETUP) + 1)
            {
                Log(("GetStdDescSync: Urb.cbData=%#x (min 1)\n", Urb.cbData));
                break;
            }
            cbDesc = ((uint8_t *)pbDesc)[0];
        }

        Log(("GetStdDescSync: got Urb.cbData=%u, cbDesc=%u cbHint=%u\n", Urb.cbData, cbDesc, cbHint));

        if (    Urb.cbData == cbHint + sizeof(VUSBSETUP)
            &&  cbDesc > Urb.cbData - sizeof(VUSBSETUP))
        {
            cbHint = cbDesc;
            if (cbHint > sizeof(Urb.abData))
            {
                AssertMsgFailed(("cbHint=%u\n", cbHint));
                break;
            }
            continue;
        }
        Assert(cbDesc <= Urb.cbData - sizeof(VUSBSETUP));
#ifdef LOG_ENABLED
        vusbUrbTrace(&Urb, "GetStdDescSync", true);
#endif

        /*
         * Fine, we got everything return a heap duplicate of the descriptor.
         */
        return RTMemDup(pbDesc, cbDesc);
    }
    return NULL;
}
Пример #4
0
RTDECL(int)  RTUuidFromUtf16(PRTUUID pUuid, PCRTUTF16 pwszString)
{
    bool fHaveBraces;

    /*
     * Validate parameters.
     */
    AssertPtrReturn(pUuid, VERR_INVALID_PARAMETER);
    AssertPtrReturn(pwszString, VERR_INVALID_PARAMETER);

    fHaveBraces = pwszString[0] == '{';
    pwszString += fHaveBraces;

#define MY_CHECK(expr) do { if (RT_UNLIKELY(!(expr))) return VERR_INVALID_UUID_FORMAT; } while (0)
#define MY_ISXDIGIT(ch) (!((ch) & 0xff00) && g_au8Digits[(ch) & 0xff] != 0xff)
    MY_CHECK(MY_ISXDIGIT(pwszString[ 0]));
    MY_CHECK(MY_ISXDIGIT(pwszString[ 1]));
    MY_CHECK(MY_ISXDIGIT(pwszString[ 2]));
    MY_CHECK(MY_ISXDIGIT(pwszString[ 3]));
    MY_CHECK(MY_ISXDIGIT(pwszString[ 4]));
    MY_CHECK(MY_ISXDIGIT(pwszString[ 5]));
    MY_CHECK(MY_ISXDIGIT(pwszString[ 6]));
    MY_CHECK(MY_ISXDIGIT(pwszString[ 7]));
    MY_CHECK(pwszString[ 8] == '-');
    MY_CHECK(MY_ISXDIGIT(pwszString[ 9]));
    MY_CHECK(MY_ISXDIGIT(pwszString[10]));
    MY_CHECK(MY_ISXDIGIT(pwszString[11]));
    MY_CHECK(MY_ISXDIGIT(pwszString[12]));
    MY_CHECK(pwszString[13] == '-');
    MY_CHECK(MY_ISXDIGIT(pwszString[14]));
    MY_CHECK(MY_ISXDIGIT(pwszString[15]));
    MY_CHECK(MY_ISXDIGIT(pwszString[16]));
    MY_CHECK(MY_ISXDIGIT(pwszString[17]));
    MY_CHECK(pwszString[18] == '-');
    MY_CHECK(MY_ISXDIGIT(pwszString[19]));
    MY_CHECK(MY_ISXDIGIT(pwszString[20]));
    MY_CHECK(MY_ISXDIGIT(pwszString[21]));
    MY_CHECK(MY_ISXDIGIT(pwszString[22]));
    MY_CHECK(pwszString[23] == '-');
    MY_CHECK(MY_ISXDIGIT(pwszString[24]));
    MY_CHECK(MY_ISXDIGIT(pwszString[25]));
    MY_CHECK(MY_ISXDIGIT(pwszString[26]));
    MY_CHECK(MY_ISXDIGIT(pwszString[27]));
    MY_CHECK(MY_ISXDIGIT(pwszString[28]));
    MY_CHECK(MY_ISXDIGIT(pwszString[29]));
    MY_CHECK(MY_ISXDIGIT(pwszString[30]));
    MY_CHECK(MY_ISXDIGIT(pwszString[31]));
    MY_CHECK(MY_ISXDIGIT(pwszString[32]));
    MY_CHECK(MY_ISXDIGIT(pwszString[33]));
    MY_CHECK(MY_ISXDIGIT(pwszString[34]));
    MY_CHECK(MY_ISXDIGIT(pwszString[35]));
    if (fHaveBraces)
        MY_CHECK(pwszString[36] == '}');
    MY_CHECK(!pwszString[36 + fHaveBraces]);
#undef MY_ISXDIGIT
#undef MY_CHECK

    /*
     * Inverse of RTUuidToUtf8 (see above).
     */
#define MY_TONUM(ch) (g_au8Digits[(ch) & 0xff])
    pUuid->Gen.u32TimeLow = RT_LE2H_U32((uint32_t)MY_TONUM(pwszString[ 0]) << 28
                          | (uint32_t)MY_TONUM(pwszString[ 1]) << 24
                          | (uint32_t)MY_TONUM(pwszString[ 2]) << 20
                          | (uint32_t)MY_TONUM(pwszString[ 3]) << 16
                          | (uint32_t)MY_TONUM(pwszString[ 4]) << 12
                          | (uint32_t)MY_TONUM(pwszString[ 5]) <<  8
                          | (uint32_t)MY_TONUM(pwszString[ 6]) <<  4
                          | (uint32_t)MY_TONUM(pwszString[ 7]));
    pUuid->Gen.u16TimeMid = RT_LE2H_U16((uint16_t)MY_TONUM(pwszString[ 9]) << 12
                          | (uint16_t)MY_TONUM(pwszString[10]) << 8
                          | (uint16_t)MY_TONUM(pwszString[11]) << 4
                          | (uint16_t)MY_TONUM(pwszString[12]));
    pUuid->Gen.u16TimeHiAndVersion = RT_LE2H_U16(
                            (uint16_t)MY_TONUM(pwszString[14]) << 12
                          | (uint16_t)MY_TONUM(pwszString[15]) << 8
                          | (uint16_t)MY_TONUM(pwszString[16]) << 4
                          | (uint16_t)MY_TONUM(pwszString[17]));
    pUuid->Gen.u8ClockSeqHiAndReserved =
                            (uint16_t)MY_TONUM(pwszString[19]) << 4
                          | (uint16_t)MY_TONUM(pwszString[20]);
    pUuid->Gen.u8ClockSeqLow =
                            (uint16_t)MY_TONUM(pwszString[21]) << 4
                          | (uint16_t)MY_TONUM(pwszString[22]);
    pUuid->Gen.au8Node[0] = (uint8_t)MY_TONUM(pwszString[24]) << 4
                          | (uint8_t)MY_TONUM(pwszString[25]);
    pUuid->Gen.au8Node[1] = (uint8_t)MY_TONUM(pwszString[26]) << 4
                          | (uint8_t)MY_TONUM(pwszString[27]);
    pUuid->Gen.au8Node[2] = (uint8_t)MY_TONUM(pwszString[28]) << 4
                          | (uint8_t)MY_TONUM(pwszString[29]);
    pUuid->Gen.au8Node[3] = (uint8_t)MY_TONUM(pwszString[30]) << 4
                          | (uint8_t)MY_TONUM(pwszString[31]);
    pUuid->Gen.au8Node[4] = (uint8_t)MY_TONUM(pwszString[32]) << 4
                          | (uint8_t)MY_TONUM(pwszString[33]);
    pUuid->Gen.au8Node[5] = (uint8_t)MY_TONUM(pwszString[34]) << 4
                          | (uint8_t)MY_TONUM(pwszString[35]);
#undef MY_TONUM
    return VINF_SUCCESS;
}
Пример #5
0
/**
 * Converts the on disk BSD label to the host endianness.
 *
 * @returns Whether the given label structure is a valid BSD disklabel.
 * @param   pBsdLabel    Pointer to the BSD disklabel to decode.
 */
static bool rtDvmFmtBsdLblDiskLabelDecode(PBsdLabel pBsdLabel)
{
    pBsdLabel->u32Magic                 = RT_LE2H_U32(pBsdLabel->u32Magic);
    pBsdLabel->u16DriveType             = RT_LE2H_U16(pBsdLabel->u16DriveType);
    pBsdLabel->u16SubType               = RT_LE2H_U16(pBsdLabel->u16SubType);
    pBsdLabel->cbSector                 = RT_LE2H_U32(pBsdLabel->cbSector);
    pBsdLabel->cSectorsPerTrack         = RT_LE2H_U32(pBsdLabel->cSectorsPerTrack);
    pBsdLabel->cTracksPerCylinder       = RT_LE2H_U32(pBsdLabel->cTracksPerCylinder);
    pBsdLabel->cDataCylindersPerUnit    = RT_LE2H_U32(pBsdLabel->cDataCylindersPerUnit);
    pBsdLabel->cDataSectorsPerCylinder  = RT_LE2H_U32(pBsdLabel->cDataSectorsPerCylinder);
    pBsdLabel->cSectorsPerUnit          = RT_LE2H_U32(pBsdLabel->cSectorsPerUnit);
    pBsdLabel->cSpareSectorsPerTrack    = RT_LE2H_U16(pBsdLabel->cSpareSectorsPerTrack);
    pBsdLabel->cSpareSectorsPerCylinder = RT_LE2H_U16(pBsdLabel->cSpareSectorsPerCylinder);
    pBsdLabel->cSpareCylindersPerUnit   = RT_LE2H_U32(pBsdLabel->cSpareCylindersPerUnit);
    pBsdLabel->cRotationsPerMinute      = RT_LE2H_U16(pBsdLabel->cRotationsPerMinute);
    pBsdLabel->uSectorInterleave        = RT_LE2H_U16(pBsdLabel->uSectorInterleave);
    pBsdLabel->uSectorSkewPerTrack      = RT_LE2H_U16(pBsdLabel->uSectorSkewPerTrack);
    pBsdLabel->uSectorSkewPerCylinder   = RT_LE2H_U16(pBsdLabel->uSectorSkewPerCylinder);
    pBsdLabel->usHeadSwitch             = RT_LE2H_U16(pBsdLabel->usHeadSwitch);
    pBsdLabel->usTrackSeek              = RT_LE2H_U16(pBsdLabel->usTrackSeek);
    pBsdLabel->fFlags                   = RT_LE2H_U32(pBsdLabel->fFlags);

    for (unsigned i = 0; i < RT_ELEMENTS(pBsdLabel->au32DriveData); i++)
        pBsdLabel->au32DriveData[i] = RT_LE2H_U32(pBsdLabel->au32DriveData[i]);
    for (unsigned i = 0; i < RT_ELEMENTS(pBsdLabel->au32Reserved); i++)
        pBsdLabel->au32Reserved[i] = RT_LE2H_U32(pBsdLabel->au32Reserved[i]);

    pBsdLabel->u32Magic2                = RT_LE2H_U32(pBsdLabel->u32Magic2);
    pBsdLabel->u16ChkSum                = RT_LE2H_U16(pBsdLabel->u16ChkSum);
    pBsdLabel->cPartitions              = RT_LE2H_U16(pBsdLabel->cPartitions);
    pBsdLabel->cbBootArea               = RT_LE2H_U32(pBsdLabel->cbBootArea);
    pBsdLabel->cbFsSuperBlock           = RT_LE2H_U32(pBsdLabel->cbFsSuperBlock);

    /* Check the magics now. */
    if (   pBsdLabel->u32Magic    != RTDVM_BSDLBL_MAGIC
        || pBsdLabel->u32Magic2   != RTDVM_BSDLBL_MAGIC
        || pBsdLabel->cPartitions != RTDVM_BSDLBL_MAX_PARTITIONS)
        return false;

    /* Convert the partitions array. */
    for (unsigned i = 0; i < RT_ELEMENTS(pBsdLabel->aPartitions); i++)
        rtDvmFmtBsdLblDiskLabelDecodePartition(&pBsdLabel->aPartitions[i]);

    /* Check the checksum now. */
    uint16_t u16ChkSumSaved = pBsdLabel->u16ChkSum;

    pBsdLabel->u16ChkSum = 0;
    if (u16ChkSumSaved != rtDvmFmtBsdLblDiskLabelChkSum(pBsdLabel))
        return false;

    pBsdLabel->u16ChkSum = u16ChkSumSaved;
    return true;
}