VirtualBox

Ignore:
Timestamp:
Dec 18, 2012 8:13:37 PM (12 years ago)
Author:
vboxsync
Message:

GuestProperties/service: Misc. sanity checking.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostServices/GuestProperties/service.cpp

    r43697 r44155  
    139139    /** The function that was requested */
    140140    uint32_t mFunction;
     141    /** Number of call parameters. */
     142    uint32_t mParmsCnt;
    141143    /** The call parameters */
    142144    VBOXHGCMSVCPARM *mParms;
     
    145147
    146148    /** The standard constructor */
    147     GuestCall() : u32ClientId(0), mFunction(0) {}
     149    GuestCall(void) : u32ClientId(0), mFunction(0), mParmsCnt(0) {}
    148150    /** The normal constructor */
    149151    GuestCall(uint32_t aClientId, VBOXHGCMCALLHANDLE aHandle, uint32_t aFunction,
    150               VBOXHGCMSVCPARM aParms[], int aRc)
    151               : u32ClientId(aClientId), mHandle(aHandle), mFunction(aFunction), mParms(aParms),
    152                 mRc(aRc) {}
     152              uint32_t aParmsCnt, VBOXHGCMSVCPARM aParms[], int aRc)
     153              : u32ClientId(aClientId), mHandle(aHandle), mFunction(aFunction),
     154                mParmsCnt(aParmsCnt), mParms(aParms), mRc(aRc) {}
    153155};
    154156/** The guest call list type */
     
    171173    /** The number of properties. */
    172174    unsigned mcProperties;
    173     /** The list of property changes for guest notifications */
     175    /** The list of property changes for guest notifications;
     176     *  only used for timestamp tracking in notifications at the moment */
    174177    PropertyList mGuestNotifications;
    175178    /** The list of outstanding guest notification calls */
     
    376379    int getOldNotificationInternal(const char *pszPattern,
    377380                                   uint64_t u64Timestamp, Property *pProp);
    378     int getNotificationWriteOut(VBOXHGCMSVCPARM paParms[], Property prop);
    379     void doNotifications(const char *pszProperty, uint64_t u64Timestamp);
     381    int getNotificationWriteOut(uint32_t cParms, VBOXHGCMSVCPARM paParms[], Property prop);
     382    int doNotifications(const char *pszProperty, uint64_t u64Timestamp);
    380383    int notifyHost(const char *pszName, const char *pszValue,
    381384                   uint64_t u64Timestamp, const char *pszFlags);
     
    702705        else if (mcProperties < MAX_PROPS)
    703706        {
    704             /* Create a new string space record. */
    705             pProp = new Property(pcszName, pcszValue, u64TimeNano, fFlags);
    706             if (pProp)
     707            try
    707708            {
     709                /* Create a new string space record. */
     710                pProp = new Property(pcszName, pcszValue, u64TimeNano, fFlags);
     711                AssertPtr(pProp);
     712
    708713                if (RTStrSpaceInsert(&mhProperties, &pProp->mStrCore))
    709714                    mcProperties++;
     
    712717                    AssertFailed();
    713718                    delete pProp;
    714                     rc = VERR_INTERNAL_ERROR_3;
     719
     720                    rc = VERR_ALREADY_EXISTS;
    715721                }
    716722            }
    717             else
     723            catch (std::bad_alloc)
     724            {
    718725                rc = VERR_NO_MEMORY;
     726            }
    719727        }
    720728        else
     
    722730
    723731        /*
    724          * Send a notification to the host and return.
     732         * Send a notification to the guest and host and return.
    725733         */
    726734        // if (isGuest)  /* Notify the host even for properties that the host
    727735        //                * changed.  Less efficient, but ensures consistency. */
    728             doNotifications(pcszName, u64TimeNano);
    729         Log2(("Set string %s, rc=%Rrc, value=%s\n", pcszName, rc, pcszValue));
    730     }
    731 
    732     LogFlowThisFunc(("rc = %Rrc (%s = %s)\n", rc, pcszName, pcszValue));
     736        int rc2 = doNotifications(pcszName, u64TimeNano);
     737        if (RT_SUCCESS(rc))
     738            rc = rc2;
     739    }
     740
     741    LogFlowThisFunc(("%s=%s, rc=%Rrc\n", pcszName, pcszValue, rc));
    733742    return rc;
    734743}
     
    764773    if (RT_FAILURE(rc))
    765774    {
    766         LogFlowThisFunc(("rc = %Rrc\n", rc));
     775        LogFlowThisFunc(("rc=%Rrc\n", rc));
    767776        return rc;
    768777    }
     
    788797        // if (isGuest)  /* Notify the host even for properties that the host
    789798        //                * changed.  Less efficient, but ensures consistency. */
    790             doNotifications(pcszName, u64Timestamp);
    791     }
    792 
    793     LogFlowThisFunc(("rc = %Rrc (%s)\n", rc, pcszName));
     799        int rc2 = doNotifications(pcszName, u64Timestamp);
     800        if (RT_SUCCESS(rc))
     801            rc = rc2;
     802    }
     803
     804    LogFlowThisFunc(("%s: rc=%Rrc\n", pcszName, rc));
    794805    return rc;
    795806}
     
    968979
    969980/** Helper query used by getNotification */
    970 int Service::getNotificationWriteOut(VBOXHGCMSVCPARM paParms[], Property prop)
    971 {
    972     int rc = VINF_SUCCESS;
     981int Service::getNotificationWriteOut(uint32_t cParms, VBOXHGCMSVCPARM paParms[], Property prop)
     982{
     983    AssertReturn(cParms == 4, VERR_INVALID_PARAMETER); /* Basic sanity checking. */
     984
    973985    /* Format the data to write to the buffer. */
    974986    std::string buffer;
     
    976988    char *pchBuf;
    977989    uint32_t cbBuf;
    978     rc = paParms[2].getBuffer((void **)&pchBuf, &cbBuf);
     990
     991    int rc = paParms[2].getBuffer((void **)&pchBuf, &cbBuf);
    979992    if (RT_SUCCESS(rc))
    980993    {
     
    10151028 * @throws  can throw std::bad_alloc
    10161029 */
    1017 int Service::getNotification(uint32_t u32ClientId, VBOXHGCMCALLHANDLE callHandle, uint32_t cParms,
    1018                              VBOXHGCMSVCPARM paParms[])
     1030int Service::getNotification(uint32_t u32ClientId, VBOXHGCMCALLHANDLE callHandle,
     1031                             uint32_t cParms, VBOXHGCMSVCPARM paParms[])
    10191032{
    10201033    int rc = VINF_SUCCESS;
     
    10351048       )
    10361049        rc = VERR_INVALID_PARAMETER;
     1050
    10371051    if (RT_SUCCESS(rc))
    1038         LogFlow(("    pszPatterns=%s, u64Timestamp=%llu\n", pszPatterns,
    1039                  u64Timestamp));
     1052        LogFlow(("pszPatterns=%s, u64Timestamp=%llu\n", pszPatterns, u64Timestamp));
    10401053
    10411054    /*
     
    10461059    if (RT_SUCCESS(rc) && u64Timestamp != 0)
    10471060        rc = getOldNotification(pszPatterns, u64Timestamp, &prop);
    1048     if (RT_SUCCESS(rc) && prop.isNull())
    1049     {
     1061    if (RT_SUCCESS(rc))
     1062    {
     1063        if (prop.isNull())
     1064        {
     1065            /*
     1066             * Check if the client already had the same request.
     1067             * Complete the old request with an error in this case.
     1068             * Protection against clients, which cancel and resubmits requests.
     1069             */
     1070            CallList::iterator it = mGuestWaiters.begin();
     1071            while (it != mGuestWaiters.end())
     1072            {
     1073                const char *pszPatternsExisting;
     1074                uint32_t cchPatternsExisting;
     1075                int rc3 = it->mParms[0].getString(&pszPatternsExisting, &cchPatternsExisting);
     1076
     1077                if (   RT_SUCCESS(rc3)
     1078                    && u32ClientId == it->u32ClientId
     1079                    && RTStrCmp(pszPatterns, pszPatternsExisting) == 0)
     1080                {
     1081                    /* Complete the old request. */
     1082                    mpHelpers->pfnCallComplete(it->mHandle, VERR_INTERRUPTED);
     1083                    it = mGuestWaiters.erase(it);
     1084                }
     1085                else
     1086                    ++it;
     1087            }
     1088
     1089            mGuestWaiters.push_back(GuestCall(u32ClientId, callHandle, GET_NOTIFICATION,
     1090                                              cParms, paParms, rc));
     1091            rc = VINF_HGCM_ASYNC_EXECUTE;
     1092        }
    10501093        /*
    1051          * Check if the client already had the same request.
    1052          * Complete the old request with an error in this case.
    1053          * Protection against clients, which cancel and resubmits requests.
     1094         * Otherwise reply at once with the enqueued notification we found.
    10541095         */
    1055         CallList::iterator it = mGuestWaiters.begin();
    1056         while (it != mGuestWaiters.end())
    1057         {
    1058             const char *pszPatternsExisting;
    1059             uint32_t cchPatternsExisting;
    1060             int rc3 = it->mParms[0].getString(&pszPatternsExisting, &cchPatternsExisting);
    1061 
    1062             if (   RT_SUCCESS(rc3)
    1063                 && u32ClientId == it->u32ClientId
    1064                 && RTStrCmp(pszPatterns, pszPatternsExisting) == 0)
    1065             {
    1066                 /* Complete the old request. */
    1067                 mpHelpers->pfnCallComplete(it->mHandle, VERR_INTERRUPTED);
    1068                 it = mGuestWaiters.erase(it);
    1069             }
    1070             else
    1071                 ++it;
    1072         }
    1073 
    1074         mGuestWaiters.push_back(GuestCall(u32ClientId, callHandle, GET_NOTIFICATION,
    1075                                           paParms, rc));
    1076         rc = VINF_HGCM_ASYNC_EXECUTE;
    1077     }
    1078     /*
    1079      * Otherwise reply at once with the enqueued notification we found.
    1080      */
    1081     else
    1082     {
    1083         int rc2 = getNotificationWriteOut(paParms, prop);
    1084         if (RT_FAILURE(rc2))
    1085             rc = rc2;
    1086     }
     1096        else
     1097        {
     1098            int rc2 = getNotificationWriteOut(cParms, paParms, prop);
     1099            if (RT_SUCCESS(rc))
     1100                rc = rc2;
     1101        }
     1102    }
     1103
     1104    LogFlowThisFunc(("returning rc=%Rrc\n", rc));
    10871105    return rc;
    10881106}
     
    10971115 * @thread  HGCM service
    10981116 */
    1099 void Service::doNotifications(const char *pszProperty, uint64_t u64Timestamp)
    1100 {
    1101     AssertPtrReturnVoid(pszProperty);
    1102     LogFlowThisFunc (("pszProperty=%s, u64Timestamp=%llu\n", pszProperty, u64Timestamp));
     1117int Service::doNotifications(const char *pszProperty, uint64_t u64Timestamp)
     1118{
     1119    AssertPtrReturn(pszProperty, VERR_INVALID_POINTER);
     1120    LogFlowThisFunc(("pszProperty=%s, u64Timestamp=%llu\n", pszProperty, u64Timestamp));
    11031121    /* Ensure that our timestamp is different to the last one. */
    11041122    if (   !mGuestNotifications.empty()
     
    11221140    }
    11231141
    1124     /* Release waiters if applicable and add the event to the queue for
    1125      * guest notifications */
     1142    /* Release guest waiters if applicable and add the event
     1143     * to the queue for guest notifications */
    11261144    int rc = VINF_SUCCESS;
    11271145    try
     
    11361154            {
    11371155                GuestCall curCall = *it;
    1138                 int rc2 = getNotificationWriteOut(curCall.mParms, prop);
     1156                int rc2 = getNotificationWriteOut(curCall.mParmsCnt, curCall.mParms, prop);
    11391157                if (RT_SUCCESS(rc2))
    11401158                    rc2 = curCall.mRc;
     
    11451163                ++it;
    11461164        }
     1165
    11471166        mGuestNotifications.push_back(prop);
     1167
     1168        /** @todo r=andy This list does not have a purpose but for tracking
     1169          *              the timestamps ...
     1170        if (mGuestNotifications.size() > MAX_GUEST_NOTIFICATIONS)
     1171            mGuestNotifications.pop_front();
    11481172    }
    11491173    catch (std::bad_alloc)
     
    11511175        rc = VERR_NO_MEMORY;
    11521176    }
    1153     if (mGuestNotifications.size() > MAX_GUEST_NOTIFICATIONS)
    1154         mGuestNotifications.pop_front();
    1155 
    1156     /*
    1157      * Host notifications - first case: if the property exists then send its
    1158      * current value
    1159      */
    1160     if (pProp && mpfnHostCallback != NULL)
    1161     {
    1162         char szFlags[MAX_FLAGS_LEN];
    1163         /* Send out a host notification */
    1164         const char *pszValue = prop.mValue.c_str();
    1165         if (RT_SUCCESS(rc))
     1177
     1178    if (   RT_SUCCESS(rc)
     1179        && mpfnHostCallback)
     1180    {
     1181        /*
     1182         * Host notifications - first case: if the property exists then send its
     1183         * current value
     1184         */
     1185        if (pProp)
     1186        {
     1187            char szFlags[MAX_FLAGS_LEN];
     1188            /* Send out a host notification */
     1189            const char *pszValue = prop.mValue.c_str();
    11661190            rc = writeFlags(prop.mFlags, szFlags);
    1167         if (RT_SUCCESS(rc))
    1168             rc = notifyHost(pszProperty, pszValue, u64Timestamp, szFlags);
    1169     }
    1170 
    1171     /*
    1172      * Host notifications - second case: if the property does not exist then
    1173      * send the host an empty value
    1174      */
    1175     if (!pProp && mpfnHostCallback != NULL)
    1176     {
    1177         /* Send out a host notification */
    1178         if (RT_SUCCESS(rc))
     1191            if (RT_SUCCESS(rc))
     1192                rc = notifyHost(pszProperty, pszValue, u64Timestamp, szFlags);
     1193        }
     1194        /*
     1195         * Host notifications - second case: if the property does not exist then
     1196         * send the host an empty value
     1197         */
     1198        else
     1199        {
     1200            /* Send out a host notification */
    11791201            rc = notifyHost(pszProperty, "", u64Timestamp, "");
    1180     }
    1181     LogFlowThisFunc(("returning\n"));
     1202        }
     1203    }
     1204
     1205    LogFlowThisFunc(("returning rc=%Rrc\n", rc));
     1206    return rc;
    11821207}
    11831208
     
    12011226    HostCallbackData.u64Timestamp = u64Timestamp;
    12021227    HostCallbackData.pcszFlags    = pszFlags;
    1203     int rc = mpfnHostCallback (mpvHostData, 0 /*u32Function*/,
    1204                            (void *)(&HostCallbackData),
    1205                            sizeof(HostCallbackData));
    1206     LogFlowFunc (("returning %Rrc\n", rc));
     1228    int rc = mpfnHostCallback(mpvHostData, 0 /*u32Function*/,
     1229                              (void *)(&HostCallbackData),
     1230                              sizeof(HostCallbackData));
     1231    LogFlowFunc(("returning rc=%Rrc\n", rc));
    12071232    return rc;
    12081233}
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