VirtualBox

Changeset 96988 in vbox for trunk/src/VBox/Main


Ignore:
Timestamp:
Oct 4, 2022 8:43:44 PM (2 years ago)
Author:
vboxsync
Message:

Main: streamlined URB processing in remote USB backend

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/src-client/RemoteUSBBackend.cpp

    r96407 r96988  
    11941194    VRDEUSBREQREAPURBBODY *pBody = (VRDEUSBREQREAPURBBODY *)pvBody;
    11951195
     1196    /* 'pvBody' memory buffer can contain multiple URBs. */
    11961197    while (cbBody >= sizeof(VRDEUSBREQREAPURBBODY))
    11971198    {
     
    12121213        /* Verify client's data. */
    12131214        if (   (pBody->flags & ~fu8ReapValidFlags) != 0
    1214             || sizeof(VRDEUSBREQREAPURBBODY) > cbBody
    12151215            || pBody->handle == 0)
    12161216        {
     
    12291229        }
    12301230
    1231         uint32_t cbBodyData = 0; /* Data contained in the URB body structure for input URBs. */
     1231        uint32_t cbBodyData = 0; /* Data contained in the URB body structure for input URBs. i.e. beyond VRDEUSBREQREAPURBBODY. */
    12321232
    12331233        requestDevice(pDevice);
     
    12481248        else
    12491249        {
    1250             LogFlow(("RemoteUSBBackend::reapURB: qurb = %p\n", qurb));
    1251 
    1252             /* Update the URB error field. */
    1253             if (mClientVersion == VRDE_USB_VERSION_1)
     1250            LogFlow(("RemoteUSBBackend::reapURB: qurb = %p, u32Err = %d\n", qurb, qurb->u32Err));
     1251
     1252            /* Update the URB error field, if it does not yet indicate an error. */
     1253            if (qurb->u32Err == VUSBSTATUS_OK)
    12541254            {
    1255                 switch(pBody->error)
     1255                if (mClientVersion == VRDE_USB_VERSION_1)
    12561256                {
    1257                     case VRDE_USB_XFER_OK:    qurb->u32Err = VUSBSTATUS_OK;    break;
    1258                     case VRDE_USB_XFER_STALL: qurb->u32Err = VUSBSTATUS_STALL; break;
    1259                     case VRDE_USB_XFER_DNR:   qurb->u32Err = VUSBSTATUS_DNR;   break;
    1260                     case VRDE_USB_XFER_CRC:   qurb->u32Err = VUSBSTATUS_CRC;   break;
    1261                     default: Log(("RemoteUSBBackend::reapURB: Invalid error %d\n", pBody->error));
    1262                                               qurb->u32Err = VUSBSTATUS_DNR;   break;
     1257                    switch(pBody->error)
     1258                    {
     1259                        case VRDE_USB_XFER_OK:    qurb->u32Err = VUSBSTATUS_OK;    break;
     1260                        case VRDE_USB_XFER_STALL: qurb->u32Err = VUSBSTATUS_STALL; break;
     1261                        case VRDE_USB_XFER_DNR:   qurb->u32Err = VUSBSTATUS_DNR;   break;
     1262                        case VRDE_USB_XFER_CRC:   qurb->u32Err = VUSBSTATUS_CRC;   break;
     1263                        default: Log(("RemoteUSBBackend::reapURB: Invalid error %d\n", pBody->error));
     1264                                                  qurb->u32Err = VUSBSTATUS_DNR;   break;
     1265                    }
     1266                }
     1267                else if (   mClientVersion == VRDE_USB_VERSION_2
     1268                         || mClientVersion == VRDE_USB_VERSION_3)
     1269                {
     1270                    switch(pBody->error)
     1271                    {
     1272                        case VRDE_USB_XFER_OK:    qurb->u32Err = VUSBSTATUS_OK;            break;
     1273                        case VRDE_USB_XFER_STALL: qurb->u32Err = VUSBSTATUS_STALL;         break;
     1274                        case VRDE_USB_XFER_DNR:   qurb->u32Err = VUSBSTATUS_DNR;           break;
     1275                        case VRDE_USB_XFER_CRC:   qurb->u32Err = VUSBSTATUS_CRC;           break;
     1276                        case VRDE_USB_XFER_DO:    qurb->u32Err = VUSBSTATUS_DATA_OVERRUN;  break;
     1277                        case VRDE_USB_XFER_DU:    qurb->u32Err = VUSBSTATUS_DATA_UNDERRUN; break;
     1278
     1279                        /* Unmapped errors. */
     1280                        case VRDE_USB_XFER_BS:
     1281                        case VRDE_USB_XFER_DTM:
     1282                        case VRDE_USB_XFER_PCF:
     1283                        case VRDE_USB_XFER_UPID:
     1284                        case VRDE_USB_XFER_BO:
     1285                        case VRDE_USB_XFER_BU:
     1286                        case VRDE_USB_XFER_ERR:
     1287                        default: Log(("RemoteUSBBackend::reapURB: Invalid error %d\n", pBody->error));
     1288                                                  qurb->u32Err = VUSBSTATUS_DNR;   break;
     1289                    }
     1290                }
     1291                else
     1292                {
     1293                    qurb->u32Err = VUSBSTATUS_DNR;
    12631294                }
    12641295            }
    1265             else if (   mClientVersion == VRDE_USB_VERSION_2
    1266                      || mClientVersion == VRDE_USB_VERSION_3)
     1296
     1297            /* Get the URB data. The URB is completed unless the client tells that this is a fragment of an IN URB. */
     1298            bool fURBCompleted = true;
     1299
     1300            if (qurb->fInput)
    12671301            {
    1268                 switch(pBody->error)
     1302                if (pBody->len <= cbBody - sizeof(VRDEUSBREQREAPURBBODY))
     1303                    cbBodyData = pBody->len; /* VRDE_USB_DIRECTION_IN URBs include some data. */
     1304                else
    12691305                {
    1270                     case VRDE_USB_XFER_OK:    qurb->u32Err = VUSBSTATUS_OK;            break;
    1271                     case VRDE_USB_XFER_STALL: qurb->u32Err = VUSBSTATUS_STALL;         break;
    1272                     case VRDE_USB_XFER_DNR:   qurb->u32Err = VUSBSTATUS_DNR;           break;
    1273                     case VRDE_USB_XFER_CRC:   qurb->u32Err = VUSBSTATUS_CRC;           break;
    1274                     case VRDE_USB_XFER_DO:    qurb->u32Err = VUSBSTATUS_DATA_OVERRUN;  break;
    1275                     case VRDE_USB_XFER_DU:    qurb->u32Err = VUSBSTATUS_DATA_UNDERRUN; break;
    1276 
    1277                     /* Unmapped errors. */
    1278                     case VRDE_USB_XFER_BS:
    1279                     case VRDE_USB_XFER_DTM:
    1280                     case VRDE_USB_XFER_PCF:
    1281                     case VRDE_USB_XFER_UPID:
    1282                     case VRDE_USB_XFER_BO:
    1283                     case VRDE_USB_XFER_BU:
    1284                     case VRDE_USB_XFER_ERR:
    1285                     default: Log(("RemoteUSBBackend::reapURB: Invalid error %d\n", pBody->error));
    1286                                               qurb->u32Err = VUSBSTATUS_DNR;   break;
     1306                    cbBodyData = cbBody - sizeof(VRDEUSBREQREAPURBBODY);
     1307                    qurb->u32Err = VUSBSTATUS_DNR;
     1308                }
     1309
     1310                if (qurb->u32Err == VUSBSTATUS_OK)
     1311                {
     1312                    LogFlow(("RemoteUSBBackend::reapURB: copying data %d bytes\n", pBody->len));
     1313                    if (pBody->len > qurb->u32Len - qurb->u32TransferredLen)
     1314                    {
     1315                        /* Received more data than expected for this URB. If there more fragments follow,
     1316                         * they will be discarded because the URB handle will not be valid anymore.
     1317                         */
     1318                        qurb->u32Err = VUSBSTATUS_DNR;
     1319                        qurb->u32TransferredLen = qurb->u32Len;
     1320                    }
     1321                    else
     1322                    {
     1323                        memcpy ((uint8_t *)qurb->pvData + qurb->u32TransferredLen, &pBody[1], pBody->len);
     1324                        qurb->u32TransferredLen += pBody->len;
     1325                    }
     1326
     1327                    if (   qurb->u32Err == VUSBSTATUS_OK
     1328                        && (pBody->flags & VRDE_USB_REAP_FLAG_FRAGMENT) != 0)
     1329                    {
     1330                        /* If the client sends fragmented packets, accumulate the URB data. */
     1331                        fURBCompleted = false;
     1332                    }
    12871333                }
    12881334            }
    12891335            else
    1290             {
    1291                 qurb->u32Err = VUSBSTATUS_DNR;
    1292             }
    1293 
    1294             /* Get the URB data. */
    1295             bool fURBCompleted = true;
    1296 
    1297             if (qurb->fInput)
    1298             {
    1299                 cbBodyData = pBody->len; /* VRDE_USB_DIRECTION_IN URBs include some data. */
    1300             }
    1301 
    1302             if (   qurb->u32Err == VUSBSTATUS_OK
    1303                 && qurb->fInput)
    1304             {
    1305                 LogFlow(("RemoteUSBBackend::reapURB: copying data %d bytes\n", pBody->len));
    1306 
    1307                 uint32_t u32DataLen = qurb->u32TransferredLen + pBody->len;
    1308 
    1309                 if (u32DataLen > qurb->u32Len)
    1310                 {
    1311                     /* Received more data than expected for this URB. If there more fragments follow,
    1312                      * they will be discarded because the URB handle will not be valid anymore.
    1313                      */
    1314                     qurb->u32Err = VUSBSTATUS_DNR;
    1315                 }
    1316                 else
    1317                 {
    1318                     memcpy ((uint8_t *)qurb->pvData + qurb->u32TransferredLen, &pBody[1], pBody->len);
    1319                 }
    1320 
    1321                 if (   qurb->u32Err == VUSBSTATUS_OK
    1322                     && (pBody->flags & VRDE_USB_REAP_FLAG_FRAGMENT) != 0)
    1323                 {
    1324                     /* If the client sends fragmented packets, accumulate the URB data. */
    1325                     fURBCompleted = false;
    1326                 }
    1327             }
    1328 
    1329             qurb->u32TransferredLen += pBody->len; /* Update the value for all URBs. */
     1336                qurb->u32TransferredLen += pBody->len; /* Update the value for OUT URBs. */
    13301337
    13311338            if (fURBCompleted)
     
    13911398
    13921399        /* There is probably a further URB body. */
    1393         uint32_t cbBodySize = sizeof (VRDEUSBREQREAPURBBODY) + cbBodyData;
    1394 
    1395         if (cbBodySize > cbBody)
     1400        if (cbBodyData > cbBody - sizeof(VRDEUSBREQREAPURBBODY))
    13961401        {
    13971402            vrc = VERR_INVALID_PARAMETER;
     
    13991404        }
    14001405
    1401         pBody = (VRDEUSBREQREAPURBBODY *)((uint8_t *)pBody + cbBodySize);
    1402         cbBody -= cbBodySize;
     1406        cbBody -= sizeof(VRDEUSBREQREAPURBBODY) + cbBodyData;
     1407        pBody = (VRDEUSBREQREAPURBBODY *)((uint8_t *)pBody + sizeof(VRDEUSBREQREAPURBBODY) + cbBodyData);
    14031408    }
    14041409
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette