VirtualBox

Ignore:
Timestamp:
Dec 10, 2009 4:24:18 PM (15 years ago)
Author:
vboxsync
Message:

HostServices/GuestProperties: add global "RDONLYGUEST" flag and clean up the test case

Location:
trunk/src/VBox/HostServices/GuestProperties
Files:
2 edited

Legend:

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

    r25032 r25306  
    155155    /** HGCM helper functions. */
    156156    PVBOXHGCMSVCHELPERS mpHelpers;
     157    /** Global flags for the service */
     158    ePropFlags meGlobalFlags;
    157159    /** The property list */
    158160    PropertyList mProperties;
     
    223225    }
    224226
     227    /**
     228     * Check whether we have permission to change a property.
     229     * @returns VINF_SUCCESS if we do, VERR_PERMISSION_DENIED otherwise
     230     * @param   eFlags   the flags on the property in question
     231     * @param   isGuest  is the guest or the host trying to make the change?
     232     */
     233    int checkPermission(ePropFlags eFlags, bool isGuest)
     234    {
     235        if (   (isGuest && (eFlags & RDONLYGUEST))
     236            || (isGuest && (meGlobalFlags & RDONLYGUEST))
     237            || (!isGuest && (eFlags & RDONLYHOST))
     238           )
     239            return VERR_PERMISSION_DENIED;
     240        return VINF_SUCCESS;
     241    }
     242
    225243public:
    226244    explicit Service(PVBOXHGCMSVCHELPERS pHelpers)
    227245        : mpHelpers(pHelpers)
     246        , meGlobalFlags(NILFLAG)
    228247        , mPendingDummyReq(NULL)
    229248        , mfExitThread(false)
     
    644663                break;
    645664            }
    646     if (RT_SUCCESS(rc) && found)
    647         if (   (isGuest && (it->mFlags & RDONLYGUEST))
    648             || (!isGuest && (it->mFlags & RDONLYHOST))
    649            )
    650             rc = VERR_PERMISSION_DENIED;
     665    if (RT_SUCCESS(rc))
     666        rc = checkPermission(found ? (ePropFlags)it->mFlags : NILFLAG,
     667                             isGuest);
    651668
    652669    /*
     
    721738                break;
    722739            }
    723     if (RT_SUCCESS(rc) && found)
    724         if (   (isGuest && (it->mFlags & RDONLYGUEST))
    725             || (!isGuest && (it->mFlags & RDONLYHOST))
    726            )
    727             rc = VERR_PERMISSION_DENIED;
     740    if (RT_SUCCESS(rc))
     741        rc = checkPermission(found ? (ePropFlags)it->mFlags :
     742                             NILFLAG, isGuest);
    728743
    729744    /*
     
    12921307
    12931308            /* The host wishes to flush all pending notification */
     1309            case SET_GLOBAL_FLAGS_HOST:
     1310                LogFlowFunc(("SET_GLOBAL_FLAGS_HOST\n"));
     1311                if (cParms == 1)
     1312                {
     1313                    uint32_t eFlags;
     1314                    rc = paParms[0].getUInt32(&eFlags);
     1315                    if (RT_SUCCESS(rc))
     1316                        meGlobalFlags = (ePropFlags)eFlags;
     1317                }
     1318                else
     1319                    rc = VERR_INVALID_PARAMETER;
     1320                break;
     1321
     1322            /* The host wishes to flush all pending notification */
    12941323            case FLUSH_NOTIFICATIONS_HOST:
    12951324                LogFlowFunc(("FLUSH_NOTIFICATIONS_HOST\n"));
  • trunk/src/VBox/HostServices/GuestProperties/testcase/tstGuestPropSvc.cpp

    r16337 r25306  
    398398}
    399399
     400/**
     401 * Set a property by calling the service
     402 * @returns the status returned by the call to the service
     403 *
     404 * @param   pTable      the service instance handle
     405 * @param   pcszName    the name of the property to set
     406 * @param   pcszValue   the value to set the property to
     407 * @param   pcszFlags   the flag string to set if one of the SET_PROP[_HOST]
     408 *                      commands is used
     409 * @param   isHost      whether the SET_PROP[_VALUE]_HOST commands should be
     410 *                      used, rather than the guest ones
     411 * @param   useSetProp  whether SET_PROP[_HOST] should be used rather than
     412 *                      SET_PROP_VALUE[_HOST]
     413 */
     414int doSetProperty(VBOXHGCMSVCFNTABLE *pTable, const char *pcszName,
     415                  const char *pcszValue, const char *pcszFlags, bool isHost,
     416                  bool useSetProp)
     417{
     418    VBOXHGCMCALLHANDLE_TYPEDEF callHandle = { VINF_SUCCESS };
     419    int command = SET_PROP_VALUE;
     420    if (isHost)
     421    {
     422        if (useSetProp)
     423            command = SET_PROP_HOST;
     424        else
     425            command = SET_PROP_VALUE_HOST;
     426    }
     427    else if (useSetProp)
     428        command = SET_PROP;
     429    VBOXHGCMSVCPARM paParms[3];
     430    /* Work around silly constant issues - we ought to allow passing
     431     * constant strings in the hgcm parameters. */
     432    char szName[MAX_NAME_LEN];
     433    char szValue[MAX_VALUE_LEN];
     434    char szFlags[MAX_FLAGS_LEN];
     435    RTStrPrintf(szName, sizeof(szName), "%s", pcszName);
     436    RTStrPrintf(szValue, sizeof(szValue), "%s", pcszValue);
     437    RTStrPrintf(szFlags, sizeof(szFlags), "%s", pcszFlags);
     438    paParms[0].setPointer (szName, (uint32_t)strlen(szName) + 1);
     439    paParms[1].setPointer (szValue, (uint32_t)strlen(szValue) + 1);
     440    paParms[2].setPointer (szFlags, (uint32_t)strlen(szFlags) + 1);
     441    if (isHost)
     442        callHandle.rc = pTable->pfnHostCall(pTable->pvService, command,
     443                                            useSetProp ? 3 : 2, paParms);
     444    else
     445        pTable->pfnCall(pTable->pvService, &callHandle, 0, NULL, command,
     446                        useSetProp ? 3 : 2, paParms);
     447    return callHandle.rc;
     448}
     449
     450
    400451/** Array of properties for testing SET_PROP_HOST and _GUEST. */
    401452static const struct
     
    436487{
    437488    int rc = VINF_SUCCESS;
    438     VBOXHGCMCALLHANDLE_TYPEDEF callHandle = { VINF_SUCCESS };
    439489    RTPrintf("Testing the SET_PROP, SET_PROP_VALUE, SET_PROP_HOST and SET_PROP_VALUE_HOST calls.\n");
    440490    for (unsigned i = 0; RT_SUCCESS(rc) && (setProperties[i].pcszName != NULL);
    441491         ++i)
    442492    {
    443         int command = SET_PROP_VALUE;
    444         if (setProperties[i].isHost)
    445         {
    446             if (setProperties[i].useSetProp)
    447                 command = SET_PROP_HOST;
    448             else
    449                 command = SET_PROP_VALUE_HOST;
    450         }
    451         else if (setProperties[i].useSetProp)
    452             command = SET_PROP;
    453         VBOXHGCMSVCPARM paParms[3];
    454         /* Work around silly constant issues - we ought to allow passing
    455          * constant strings in the hgcm parameters. */
    456         char szName[MAX_NAME_LEN];
    457         char szValue[MAX_VALUE_LEN];
    458         char szFlags[MAX_FLAGS_LEN];
    459         RTStrPrintf(szName, sizeof(szName), "%s", setProperties[i].pcszName);
    460         RTStrPrintf(szValue, sizeof(szValue), "%s", setProperties[i].pcszValue);
    461         RTStrPrintf(szFlags, sizeof(szFlags), "%s", setProperties[i].pcszFlags);
    462         paParms[0].setPointer (szName, (uint32_t)strlen(szName) + 1);
    463         paParms[1].setPointer (szValue, (uint32_t)strlen(szValue) + 1);
    464         paParms[2].setPointer (szFlags, (uint32_t)strlen(szFlags) + 1);
    465         if (setProperties[i].isHost)
    466             callHandle.rc = pTable->pfnHostCall(pTable->pvService, command,
    467                                                 setProperties[i].useSetProp
    468                                                     ? 3 : 2, paParms);
     493        rc = doSetProperty(pTable, setProperties[i].pcszName,
     494                           setProperties[i].pcszValue,
     495                           setProperties[i].pcszFlags,
     496                           setProperties[i].isHost,
     497                           setProperties[i].useSetProp);
     498        if (setProperties[i].isAllowed && RT_FAILURE(rc))
     499            RTPrintf("Setting property '%s' failed with rc=%Rrc.\n",
     500                     setProperties[i].pcszName, rc);
     501        else if (   !setProperties[i].isAllowed
     502                 && (rc != VERR_PERMISSION_DENIED))
     503        {
     504            RTPrintf("Setting property '%s' returned %Rrc instead of VERR_PERMISSION_DENIED.\n",
     505                     setProperties[i].pcszName, rc);
     506            rc = VERR_IPE_UNEXPECTED_STATUS;
     507        }
    469508        else
    470             pTable->pfnCall(pTable->pvService, &callHandle, 0, NULL, command,
    471                             setProperties[i].useSetProp ? 3 : 2, paParms);
    472         if (setProperties[i].isAllowed && RT_FAILURE(callHandle.rc))
    473         {
    474             RTPrintf("Setting property '%s' failed with rc=%Rrc.\n",
    475                      setProperties[i].pcszName, callHandle.rc);
    476             rc = callHandle.rc;
    477         }
    478         else if (   !setProperties[i].isAllowed
    479                  && (callHandle.rc != VERR_PERMISSION_DENIED)
    480                 )
    481         {
    482             RTPrintf("Setting property '%s' returned %Rrc instead of VERR_PERMISSION_DENIED.\n",
    483                      setProperties[i].pcszName, callHandle.rc);
    484             rc = VERR_UNRESOLVED_ERROR;
    485         }
    486     }
    487     return rc;
     509            rc = VINF_SUCCESS;
     510    }
     511    return rc;
     512}
     513
     514/**
     515 * Delete a property by calling the service
     516 * @returns the status returned by the call to the service
     517 *
     518 * @param   pTable    the service instance handle
     519 * @param   pcszName  the name of the property to delete
     520 * @param   isHost    whether the DEL_PROP_HOST command should be used, rather
     521 *                    than the guest one
     522 */
     523int doDelProp(VBOXHGCMSVCFNTABLE *pTable, const char *pcszName, bool isHost)
     524{
     525    VBOXHGCMCALLHANDLE_TYPEDEF callHandle = { VINF_SUCCESS };
     526    int command = DEL_PROP;
     527    if (isHost)
     528        command = DEL_PROP_HOST;
     529    VBOXHGCMSVCPARM paParms[1];
     530    /* Work around silly constant issues - we ought to allow passing
     531     * constant strings in the hgcm parameters. */
     532    char szName[MAX_NAME_LEN];
     533    RTStrPrintf(szName, sizeof(szName), "%s", pcszName);
     534    paParms[0].setPointer (szName, (uint32_t)strlen(szName) + 1);
     535    if (isHost)
     536        callHandle.rc = pTable->pfnHostCall(pTable->pvService, command,
     537                                            1, paParms);
     538    else
     539        pTable->pfnCall(pTable->pvService, &callHandle, 0, NULL, command,
     540                        1, paParms);
     541    return callHandle.rc;
    488542}
    489543
     
    519573{
    520574    int rc = VINF_SUCCESS;
    521     VBOXHGCMCALLHANDLE_TYPEDEF callHandle = { VINF_SUCCESS };
    522575    RTPrintf("Testing the DEL_PROP and DEL_PROP_HOST calls.\n");
    523576    for (unsigned i = 0; RT_SUCCESS(rc) && (delProperties[i].pcszName != NULL);
    524577         ++i)
    525578    {
    526         int command = DEL_PROP;
    527         if (delProperties[i].isHost)
    528             command = DEL_PROP_HOST;
    529         VBOXHGCMSVCPARM paParms[1];
    530         /* Work around silly constant issues - we ought to allow passing
    531          * constant strings in the hgcm parameters. */
    532         char szName[MAX_NAME_LEN];
    533         RTStrPrintf(szName, sizeof(szName), "%s", delProperties[i].pcszName);
    534         paParms[0].setPointer (szName, (uint32_t)strlen(szName) + 1);
    535         if (delProperties[i].isHost)
    536             callHandle.rc = pTable->pfnHostCall(pTable->pvService, command,
    537                                                 1, paParms);
     579        rc = doDelProp(pTable, delProperties[i].pcszName,
     580                       delProperties[i].isHost);
     581        if (delProperties[i].isAllowed && RT_FAILURE(rc))
     582            RTPrintf("Deleting property '%s' failed with rc=%Rrc.\n",
     583                     delProperties[i].pcszName, rc);
     584        else if (   !delProperties[i].isAllowed
     585                 && (rc != VERR_PERMISSION_DENIED)
     586                )
     587        {
     588            RTPrintf("Deleting property '%s' returned %Rrc instead of VERR_PERMISSION_DENIED.\n",
     589                     delProperties[i].pcszName, rc);
     590            rc = VERR_IPE_UNEXPECTED_STATUS;
     591        }
    538592        else
    539             pTable->pfnCall(pTable->pvService, &callHandle, 0, NULL, command,
    540                             1, paParms);
    541         if (delProperties[i].isAllowed && RT_FAILURE(callHandle.rc))
    542         {
    543             RTPrintf("Deleting property '%s' failed with rc=%Rrc.\n",
    544                      delProperties[i].pcszName, callHandle.rc);
    545             rc = callHandle.rc;
    546         }
    547         else if (   !delProperties[i].isAllowed
    548                  && (callHandle.rc != VERR_PERMISSION_DENIED)
    549                 )
    550         {
    551             RTPrintf("Deleting property '%s' returned %Rrc instead of VERR_PERMISSION_DENIED.\n",
    552                      delProperties[i].pcszName, callHandle.rc);
    553             rc = VERR_UNRESOLVED_ERROR;
    554         }
     593            rc = VINF_SUCCESS;
    555594    }
    556595    return rc;
     
    623662            RTPrintf("Getting property '%s' returned %Rrc instead of VERR_NOT_FOUND.\n",
    624663                     getProperties[i].pcszName, rc2);
    625             rc = VERR_UNRESOLVED_ERROR;
     664            rc = VERR_IPE_UNEXPECTED_STATUS;
    626665        }
    627666        if (RT_SUCCESS(rc) && getProperties[i].exists)
     
    813852}
    814853
     854/** Array of properties for testing SET_PROP_HOST and _GUEST with the
     855 * READONLYGUEST global flag set. */
     856static const struct
     857{
     858    /** Property name */
     859    const char *pcszName;
     860    /** Property value */
     861    const char *pcszValue;
     862    /** Property flags */
     863    const char *pcszFlags;
     864    /** Should this be set as the host or the guest? */
     865    bool isHost;
     866    /** Should we use SET_PROP or SET_PROP_VALUE? */
     867    bool useSetProp;
     868    /** Should this succeed or be rejected with VERR_PERMISSION_DENIED? */
     869    bool isAllowed;
     870}
     871setPropertiesROGuest[] =
     872{
     873    { "Red", "Stop!", "transient", false, true, false },
     874    { "Amber", "Caution!", "", false, false, false },
     875    { "Green", "Go!", "readonly", true, true, true },
     876    { "Blue", "What on earth...?", "", true, false, true },
     877    { "/test/name", "test", "", false, true, false },
     878    { "TEST NAME", "test", "", true, true, true },
     879    { "Green", "gone out...", "", false, false, false },
     880    { "Green", "gone out...", "", true, false, false },
     881    { NULL, NULL, NULL, false, false, false }
     882};
     883
     884/**
     885 * Set the global flags value by calling the service
     886 * @returns the status returned by the call to the service
     887 *
     888 * @param   pTable  the service instance handle
     889 * @param   eFlags  the flags to set
     890 */
     891int doSetGlobalFlags(VBOXHGCMSVCFNTABLE *pTable, ePropFlags eFlags)
     892{
     893    VBOXHGCMSVCPARM paParm;
     894    paParm.setUInt32(eFlags);
     895    int rc = pTable->pfnHostCall(pTable->pvService, SET_GLOBAL_FLAGS_HOST,
     896                                 1, &paParm);
     897    if (RT_FAILURE(rc))
     898    {
     899        char szFlags[MAX_FLAGS_LEN];
     900        if (RT_FAILURE(writeFlags(eFlags, szFlags)))
     901            RTPrintf("Failed to set the global flags.\n");
     902        else
     903            RTPrintf("Failed to set the global flags \"%s\".\n",
     904                     szFlags);
     905    }
     906    return rc;
     907}
     908
     909/**
     910 * Test the SET_PROP, SET_PROP_VALUE, SET_PROP_HOST and SET_PROP_VALUE_HOST
     911 * functions.
     912 * @returns iprt status value to indicate whether the test went as expected.
     913 * @note    prints its own diagnostic information to stdout.
     914 */
     915int testSetPropROGuest(VBOXHGCMSVCFNTABLE *pTable)
     916{
     917    int rc = VINF_SUCCESS;
     918    RTPrintf("Testing the SET_PROP, SET_PROP_VALUE, SET_PROP_HOST and SET_PROP_VALUE_HOST calls with READONLYGUEST set globally.\n");
     919    rc = VBoxHGCMSvcLoad(pTable);
     920    if (RT_FAILURE(rc))
     921        RTPrintf("Failed to start the HGCM service.\n");
     922    if (RT_SUCCESS(rc))
     923        rc = doSetGlobalFlags(pTable, RDONLYGUEST);
     924    for (unsigned i = 0; RT_SUCCESS(rc) && (setPropertiesROGuest[i].pcszName != NULL);
     925         ++i)
     926    {
     927        rc = doSetProperty(pTable, setPropertiesROGuest[i].pcszName,
     928                           setPropertiesROGuest[i].pcszValue,
     929                           setPropertiesROGuest[i].pcszFlags,
     930                           setPropertiesROGuest[i].isHost,
     931                           setPropertiesROGuest[i].useSetProp);
     932        if (setPropertiesROGuest[i].isAllowed && RT_FAILURE(rc))
     933            RTPrintf("Setting property '%s' failed with rc=%Rrc.\n",
     934                     setPropertiesROGuest[i].pcszName, rc);
     935        else if (   !setPropertiesROGuest[i].isAllowed
     936                 && (rc != VERR_PERMISSION_DENIED))
     937        {
     938            RTPrintf("Setting property '%s' returned %Rrc instead of VERR_PERMISSION_DENIED.\n",
     939                     setPropertiesROGuest[i].pcszName, rc);
     940            rc = VERR_IPE_UNEXPECTED_STATUS;
     941        }
     942        else
     943            rc = VINF_SUCCESS;
     944    }
     945    if (RT_FAILURE(pTable->pfnUnload(pTable->pvService)))
     946        RTPrintf("Failed to unload the HGCM service.\n");
     947    return rc;
     948}
     949
     950/** Array of properties for testing DEL_PROP_HOST and _GUEST with
     951 * READONLYGUEST set globally. */
     952static const struct
     953{
     954    /** Property name */
     955    const char *pcszName;
     956    /** Should this be deleted as the host (or the guest)? */
     957    bool isHost;
     958    /** Should this property be created first?  (As host, obviously) */
     959    bool shouldCreate;
     960    /** And with what flags? */
     961    const char *pcszFlags;
     962    /** Should this succeed or be rejected with VERR_PERMISSION_DENIED? */
     963    bool isAllowed;
     964}
     965delPropertiesROGuest[] =
     966{
     967    { "Red", true, true, "", true },
     968    { "Amber", false, true, "", false },
     969    { "Red2", true, false, "", true },
     970    { "Amber2", false, false, "", false },
     971    { "Red3", true, true, "READONLY", false },
     972    { "Amber3", false, true, "READONLY", false },
     973    { "Red4", true, true, "RDONLYHOST", false },
     974    { "Amber4", false, true, "RDONLYHOST", false },
     975    { NULL, false, false, "", false }
     976};
     977
     978/**
     979 * Test the DEL_PROP, and DEL_PROP_HOST functions.
     980 * @returns iprt status value to indicate whether the test went as expected.
     981 * @note    prints its own diagnostic information to stdout.
     982 */
     983int testDelPropROGuest(VBOXHGCMSVCFNTABLE *pTable)
     984{
     985    int rc = VINF_SUCCESS;
     986    RTPrintf("Testing the DEL_PROP and DEL_PROP_HOST calls with RDONLYGUEST set globally.\n");
     987    rc = VBoxHGCMSvcLoad(pTable);
     988    if (RT_FAILURE(rc))
     989        RTPrintf("Failed to start the HGCM service.\n");
     990    if (RT_SUCCESS(rc))
     991        rc = doSetGlobalFlags(pTable, RDONLYGUEST);
     992    for (unsigned i = 0;    RT_SUCCESS(rc)
     993                         && (delPropertiesROGuest[i].pcszName != NULL); ++i)
     994    {
     995        if (RT_SUCCESS(rc) && delPropertiesROGuest[i].shouldCreate)
     996            rc = doSetProperty(pTable, delPropertiesROGuest[i].pcszName,
     997                               "none", delPropertiesROGuest[i].pcszFlags,
     998                               true, true);
     999        rc = doDelProp(pTable, delPropertiesROGuest[i].pcszName,
     1000                       delPropertiesROGuest[i].isHost);
     1001        if (delPropertiesROGuest[i].isAllowed && RT_FAILURE(rc))
     1002            RTPrintf("Deleting property '%s' failed with rc=%Rrc.\n",
     1003                     delPropertiesROGuest[i].pcszName, rc);
     1004        else if (   !delPropertiesROGuest[i].isAllowed
     1005                 && (rc != VERR_PERMISSION_DENIED)
     1006                )
     1007        {
     1008            RTPrintf("Deleting property '%s' returned %Rrc instead of VERR_PERMISSION_DENIED.\n",
     1009                     delPropertiesROGuest[i].pcszName, rc);
     1010            rc = VERR_IPE_UNEXPECTED_STATUS;
     1011        }
     1012        else
     1013            rc = VINF_SUCCESS;
     1014    }
     1015    if (RT_FAILURE(pTable->pfnUnload(pTable->pvService)))
     1016        RTPrintf("Failed to unload the HGCM service.\n");
     1017    return rc;
     1018}
     1019
    8151020int main(int argc, char **argv)
    8161021{
     
    8251030    if (RT_FAILURE(VBoxHGCMSvcLoad(&svcTable)))
    8261031    {
    827         RTPrintf("Failed to start HGCM service.\n");
     1032        RTPrintf("Failed to start the HGCM service.\n");
    8281033        return 1;
    8291034    }
     
    8471052    if (RT_FAILURE(testGetNotification(&svcTable)))
    8481053        return 1;
     1054    if (RT_FAILURE(svcTable.pfnUnload(svcTable.pvService)))
     1055    {
     1056        RTPrintf("Failed to unload the HGCM service.\n");
     1057        return 1;
     1058    }
     1059    if (RT_FAILURE(testSetPropROGuest(&svcTable)))
     1060        return 1;
     1061    if (RT_FAILURE(testDelPropROGuest(&svcTable)))
     1062        return 1;
    8491063    RTPrintf("tstGuestPropSvc: SUCCEEDED.\n");
    8501064    return 0;
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