VirtualBox

Changeset 75801 in vbox


Ignore:
Timestamp:
Nov 29, 2018 1:54:46 AM (6 years ago)
Author:
vboxsync
Message:

VBoxGuestControl: Optimizing message handling - part 2. bugref:9313

Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/HostServices/GuestControlSvc.h

    r75798 r75801  
    253253
    254254/**
    255  * The service functions which are called by guest. The numbers may not change,
    256  * so we hardcode them.
     255 * The service functions which are called by guest.
     256 *
     257 * @note The function numbers cannot be changed.  Please use the first non-zero
     258 *       number that's not in use when adding new functions.
     259 *
     260 * @note Remember to update service.cpp when adding new functions/events for
     261 *       Main, as it validates all incoming commands before passing them on.
    257262 */
    258263enum eGuestFn
  • trunk/src/VBox/HostServices/GuestControl/service.cpp

    r75800 r75801  
    20702070
    20712071        /*
    2072          * For all other regular commands we call our hostCallback
    2073          * function. If the current command does not support notifications,
    2074          * notifyHost will return VERR_NOT_SUPPORTED.
     2072         * Stuff the goes to various main objects:
    20752073         */
    2076         default:
     2074        case GUEST_DISCONNECTED:
     2075        case GUEST_MSG_REPLY:
     2076        case GUEST_MSG_PROGRESS_UPDATE:
     2077        case GUEST_SESSION_NOTIFY:
     2078        case GUEST_EXEC_OUTPUT:
     2079        case GUEST_EXEC_STATUS:
     2080        case GUEST_EXEC_INPUT_STATUS:
     2081        case GUEST_EXEC_IO_NOTIFY:
     2082        case GUEST_DIR_NOTIFY:
     2083        case GUEST_FILE_NOTIFY:
    20772084            rc = pThis->hostCallback(idFunction, cParms, paParms);
     2085            Assert(rc != VINF_HGCM_ASYNC_EXECUTE);
    20782086            break;
    20792087
     
    21012109            LogFlowFunc(("[Client %RU32] GUEST_MSG_FILTER_UNSET\n", idClient));
    21022110            rc = VERR_NOT_IMPLEMENTED;
     2111            break;
     2112
     2113        /*
     2114         * Anything else shall return fail with invalid function.
     2115         *
     2116         * Note! We used to return VINF_SUCCESS for these.  See bugref:9313
     2117         *       and Guest::i_notifyCtrlDispatcher().
     2118         */
     2119        default:
     2120            ASSERT_GUEST_MSG_FAILED(("idFunction=%d (%#x)\n", idFunction, idFunction));
     2121            rc = VERR_INVALID_FUNCTION;
    21032122            break;
    21042123    }
  • trunk/src/VBox/Main/src-client/GuestCtrlImpl.cpp

    r75737 r75801  
    4545#include <iprt/path.h>
    4646#include <VBox/vmm/pgm.h>
     47#include <VBox/AssertGuest.h>
    4748
    4849#include <memory>
     
    6768 * @todo
    6869 *
     70 * @todo    r=bird: This code mostly returned VINF_SUCCESS with the comment
     71 *          "Never return any errors back to the guest here." attached to the
     72 *          return locations.  However, there is no explaination for this attitude
     73 *          thowards error handling.   Further, it creates a slight problem since
     74 *          the service would route all function calls it didn't recognize here,
     75 *          thereby making any undefined functions confusingly return VINF_SUCCESS.
     76 *
     77 *          In my humble opinion, if the guest gives us incorrect input it should
     78 *          expect and deal with error statuses.  If there is unimplemented
     79 *          features I expect there to have been sufficient forethought by the
     80 *          coder that these return sensible status codes.
     81 *
     82 *          It would be much appreciated if the esteemed card house builder could
     83 *          please step in and explain this confusing state of affairs.
    6984 */
    7085/* static */
    7186DECLCALLBACK(int) Guest::i_notifyCtrlDispatcher(void    *pvExtension,
    72                                                 uint32_t u32Function,
     87                                                uint32_t idFunction,
    7388                                                void    *pvData,
    7489                                                uint32_t cbData)
     
    8095     * changes to the object state.
    8196     */
    82     Log2Func(("pvExtension=%p, u32Function=%RU32, pvParms=%p, cbParms=%RU32\n",
    83               pvExtension, u32Function, pvData, cbData));
     97    Log2Func(("pvExtension=%p, idFunction=%RU32, pvParms=%p, cbParms=%RU32\n", pvExtension, idFunction, pvData, cbData));
    8498
    8599    ComObjPtr<Guest> pGuest = reinterpret_cast<Guest *>(pvExtension);
    86     Assert(!pGuest.isNull());
     100    AssertReturn(pGuest.isNotNull(), VERR_WRONG_ORDER);
     101
     102    /*
     103     * The data packet should ever be a problem, but check to be sure.
     104     */
     105    AssertMsgReturn(cbData == sizeof(VBOXGUESTCTRLHOSTCALLBACK),
     106                    ("Guest control host callback data has wrong size (expected %zu, got %zu) - buggy host service!\n",
     107                     sizeof(VBOXGUESTCTRLHOSTCALLBACK), cbData), VERR_INVALID_PARAMETER);
     108    PVBOXGUESTCTRLHOSTCALLBACK pSvcCb = (PVBOXGUESTCTRLHOSTCALLBACK)pvData;
     109    AssertPtrReturn(pSvcCb, VERR_INVALID_POINTER);
    87110
    88111    /*
     
    92115     * - Extract the session ID out of the context ID
    93116     * - Dispatch the whole stuff to the appropriate session (if still exists)
     117     *
     118     * At least context ID parameter must always be present.
    94119     */
    95     if (cbData != sizeof(VBOXGUESTCTRLHOSTCALLBACK))
    96     {
    97         AssertMsgFailed(("Guest control host callback data has wrong size (expected %zu, got %zu)\n",
    98                          sizeof(VBOXGUESTCTRLHOSTCALLBACK), cbData));
    99         return VINF_SUCCESS; /* Never return any errors back to the guest here. */
    100     }
    101 
    102     const PVBOXGUESTCTRLHOSTCALLBACK pSvcCb = (PVBOXGUESTCTRLHOSTCALLBACK)pvData;
    103     AssertPtr(pSvcCb);
    104 
    105     if (pSvcCb->mParms) /* At least context ID must be present. */
    106     {
    107         uint32_t uContextID;
    108         int rc = HGCMSvcGetU32(&pSvcCb->mpaParms[0], &uContextID);
    109         AssertMsgRCReturn(rc, ("Unable to extract callback context ID, pvData=%p\n", pSvcCb),
    110                           VINF_SUCCESS /* Never return any errors back to the guest here */);
    111 
    112         VBOXGUESTCTRLHOSTCBCTX ctxCb = { u32Function, uContextID };
    113         rc = pGuest->i_dispatchToSession(&ctxCb, pSvcCb);
    114 
    115         Log2Func(("CID=%RU32, uSession=%RU32, uObject=%RU32, uCount=%RU32, rc=%Rrc\n",
    116                   uContextID,
    117                   VBOX_GUESTCTRL_CONTEXTID_GET_SESSION(uContextID),
    118                   VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(uContextID),
    119                   VBOX_GUESTCTRL_CONTEXTID_GET_COUNT(uContextID), rc));
    120     }
    121 
    122     /* Never return any errors back to the guest here. */
    123     return VINF_SUCCESS;
     120    ASSERT_GUEST_RETURN(pSvcCb->mParms > 0, VERR_WRONG_PARAMETER_COUNT);
     121    ASSERT_GUEST_MSG_RETURN(pSvcCb->mpaParms[0].type == VBOX_HGCM_SVC_PARM_32BIT,
     122                            ("type=%d\n", pSvcCb->mpaParms[0].type), VERR_WRONG_PARAMETER_TYPE);
     123    uint32_t const idContext = pSvcCb->mpaParms[0].u.uint32;
     124
     125    VBOXGUESTCTRLHOSTCBCTX CtxCb = { idFunction, idContext };
     126    int rc = pGuest->i_dispatchToSession(&CtxCb, pSvcCb);
     127
     128    Log2Func(("CID=%#x, idSession=%RU32, uObject=%RU32, uCount=%RU32, rc=%Rrc\n",
     129              idContext, VBOX_GUESTCTRL_CONTEXTID_GET_SESSION(idContext), VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(idContext),
     130              VBOX_GUESTCTRL_CONTEXTID_GET_COUNT(idContext), rc));
     131    return rc;
    124132}
    125133
     
    215223        }
    216224        else
    217             rc = VERR_NOT_FOUND;
     225            rc = VERR_INVALID_FUNCTION;
    218226    }
    219227    else
    220         rc = VERR_NOT_FOUND;
     228        rc = VERR_INVALID_SESSION_ID;
    221229
    222230    LogFlowFuncLeaveRC(rc);
  • trunk/src/VBox/Main/src-client/GuestCtrlPrivate.cpp

    r75798 r75801  
    730730    AssertPtrReturn(pSvcCb, VERR_INVALID_POINTER);
    731731
    732     int vrc = VINF_SUCCESS;
     732    int vrc;
    733733
    734734    try
     
    739739        {
    740740            case GUEST_MSG_PROGRESS_UPDATE:
     741                vrc = VINF_SUCCESS;
    741742                break;
    742743
     
    752753                    vrc = HGCMSvcGetU32(&pSvcCb->mpaParms[idx++], &dataCb.rc);
    753754                    AssertRCReturn(vrc, vrc);
    754                     vrc = HGCMSvcGetPv(&pSvcCb->mpaParms[idx++], &dataCb.pvPayload,
    755                                        &dataCb.cbPayload);
     755                    vrc = HGCMSvcGetPv(&pSvcCb->mpaParms[idx++], &dataCb.pvPayload, &dataCb.cbPayload);
    756756                    AssertRCReturn(vrc, vrc);
    757757
    758                     GuestWaitEventPayload evPayload(dataCb.uType, dataCb.pvPayload, dataCb.cbPayload);
     758                    GuestWaitEventPayload evPayload(dataCb.uType, dataCb.pvPayload, dataCb.cbPayload); /* This bugger throws int. */
    759759                    vrc = signalWaitEventInternal(pCtxCb, dataCb.rc, &evPayload);
    760760                }
  • trunk/src/VBox/Main/src-client/GuestSessionImpl.cpp

    r75798 r75801  
    12301230    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    12311231
    1232     const uint32_t uObjectID = VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(pCtxCb->uContextID);
    1233 
     1232    /*
     1233     * Find the object.
     1234     */
    12341235    int rc = VERR_NOT_FOUND;
    1235 
    1236     SessionObjects::const_iterator itObjs = mData.mObjects.find(uObjectID);
    1237 
    1238     if (itObjs == mData.mObjects.end())
    1239         return rc;
    1240 
    1241     /* Set protocol version so that pSvcCb can be interpreted right. */
    1242     pCtxCb->uProtocol = mData.mProtocolVersion;
    1243 
    1244     switch (itObjs->second.enmType)
    1245     {
    1246         case SESSIONOBJECTTYPE_ANONYMOUS:
    1247             rc = VERR_NOT_SUPPORTED;
    1248             break;
    1249 
    1250         case SESSIONOBJECTTYPE_SESSION:
    1251         {
    1252             alock.release();
    1253 
    1254             rc = i_dispatchToThis(pCtxCb, pSvcCb);
    1255             break;
    1256         }
    1257         case SESSIONOBJECTTYPE_DIRECTORY:
    1258         {
    1259             SessionDirectories::const_iterator itDir = mData.mDirectories.find(uObjectID);
    1260             if (itDir != mData.mDirectories.end())
     1236    const uint32_t idObject = VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(pCtxCb->uContextID);
     1237    SessionObjects::const_iterator itObjs = mData.mObjects.find(idObject);
     1238    if (itObjs != mData.mObjects.end())
     1239    {
     1240        /* Set protocol version so that pSvcCb can be interpreted right. */
     1241        pCtxCb->uProtocol = mData.mProtocolVersion;
     1242
     1243        switch (itObjs->second.enmType)
     1244        {
     1245            case SESSIONOBJECTTYPE_ANONYMOUS:
     1246                rc = VERR_NOT_SUPPORTED;
     1247                break;
     1248
     1249            case SESSIONOBJECTTYPE_SESSION:
    12611250            {
    1262                 ComObjPtr<GuestDirectory> pDirectory(itDir->second);
    1263                 Assert(!pDirectory.isNull());
    1264 
    12651251                alock.release();
    12661252
    1267                 rc = pDirectory->i_callbackDispatcher(pCtxCb, pSvcCb);
     1253                rc = i_dispatchToThis(pCtxCb, pSvcCb);
     1254                break;
    12681255            }
    1269             break;
    1270         }
    1271         case SESSIONOBJECTTYPE_FILE:
    1272         {
    1273             SessionFiles::const_iterator itFile = mData.mFiles.find(uObjectID);
    1274             if (itFile != mData.mFiles.end())
     1256            case SESSIONOBJECTTYPE_DIRECTORY:
    12751257            {
    1276                 ComObjPtr<GuestFile> pFile(itFile->second);
    1277                 Assert(!pFile.isNull());
    1278 
    1279                 alock.release();
    1280 
    1281                 rc = pFile->i_callbackDispatcher(pCtxCb, pSvcCb);
     1258                SessionDirectories::const_iterator itDir = mData.mDirectories.find(idObject);
     1259                if (itDir != mData.mDirectories.end())
     1260                {
     1261                    ComObjPtr<GuestDirectory> pDirectory(itDir->second);
     1262                    Assert(!pDirectory.isNull());
     1263
     1264                    alock.release();
     1265
     1266                    rc = pDirectory->i_callbackDispatcher(pCtxCb, pSvcCb);
     1267                }
     1268                break;
    12821269            }
    1283             break;
    1284         }
    1285         case SESSIONOBJECTTYPE_PROCESS:
    1286         {
    1287             SessionProcesses::const_iterator itProc = mData.mProcesses.find(uObjectID);
    1288             if (itProc != mData.mProcesses.end())
     1270            case SESSIONOBJECTTYPE_FILE:
    12891271            {
    1290                 ComObjPtr<GuestProcess> pProcess(itProc->second);
    1291                 Assert(!pProcess.isNull());
    1292 
    1293                 alock.release();
    1294 
    1295                 rc = pProcess->i_callbackDispatcher(pCtxCb, pSvcCb);
     1272                SessionFiles::const_iterator itFile = mData.mFiles.find(idObject);
     1273                if (itFile != mData.mFiles.end())
     1274                {
     1275                    ComObjPtr<GuestFile> pFile(itFile->second);
     1276                    Assert(!pFile.isNull());
     1277
     1278                    alock.release();
     1279
     1280                    rc = pFile->i_callbackDispatcher(pCtxCb, pSvcCb);
     1281                }
     1282                break;
    12961283            }
    1297             break;
    1298         }
    1299         default:
    1300             AssertFailed();
    1301             break;
     1284            case SESSIONOBJECTTYPE_PROCESS:
     1285            {
     1286                SessionProcesses::const_iterator itProc = mData.mProcesses.find(idObject);
     1287                if (itProc != mData.mProcesses.end())
     1288                {
     1289                    ComObjPtr<GuestProcess> pProcess(itProc->second);
     1290                    Assert(!pProcess.isNull());
     1291
     1292                    alock.release();
     1293
     1294                    rc = pProcess->i_callbackDispatcher(pCtxCb, pSvcCb);
     1295                }
     1296                break;
     1297            }
     1298            default:
     1299                AssertMsgFailed(("%d\n", itObjs->second.enmType));
     1300                rc = VERR_INTERNAL_ERROR_4;
     1301                break;
     1302        }
    13021303    }
    13031304
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