Changeset 25306 in vbox for trunk/src/VBox/HostServices/GuestProperties
- Timestamp:
- Dec 10, 2009 4:24:18 PM (15 years ago)
- Location:
- trunk/src/VBox/HostServices/GuestProperties
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostServices/GuestProperties/service.cpp
r25032 r25306 155 155 /** HGCM helper functions. */ 156 156 PVBOXHGCMSVCHELPERS mpHelpers; 157 /** Global flags for the service */ 158 ePropFlags meGlobalFlags; 157 159 /** The property list */ 158 160 PropertyList mProperties; … … 223 225 } 224 226 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 225 243 public: 226 244 explicit Service(PVBOXHGCMSVCHELPERS pHelpers) 227 245 : mpHelpers(pHelpers) 246 , meGlobalFlags(NILFLAG) 228 247 , mPendingDummyReq(NULL) 229 248 , mfExitThread(false) … … 644 663 break; 645 664 } 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); 651 668 652 669 /* … … 721 738 break; 722 739 } 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); 728 743 729 744 /* … … 1292 1307 1293 1308 /* 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 */ 1294 1323 case FLUSH_NOTIFICATIONS_HOST: 1295 1324 LogFlowFunc(("FLUSH_NOTIFICATIONS_HOST\n")); -
trunk/src/VBox/HostServices/GuestProperties/testcase/tstGuestPropSvc.cpp
r16337 r25306 398 398 } 399 399 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 */ 414 int 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 400 451 /** Array of properties for testing SET_PROP_HOST and _GUEST. */ 401 452 static const struct … … 436 487 { 437 488 int rc = VINF_SUCCESS; 438 VBOXHGCMCALLHANDLE_TYPEDEF callHandle = { VINF_SUCCESS };439 489 RTPrintf("Testing the SET_PROP, SET_PROP_VALUE, SET_PROP_HOST and SET_PROP_VALUE_HOST calls.\n"); 440 490 for (unsigned i = 0; RT_SUCCESS(rc) && (setProperties[i].pcszName != NULL); 441 491 ++i) 442 492 { 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 } 469 508 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 */ 523 int 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; 488 542 } 489 543 … … 519 573 { 520 574 int rc = VINF_SUCCESS; 521 VBOXHGCMCALLHANDLE_TYPEDEF callHandle = { VINF_SUCCESS };522 575 RTPrintf("Testing the DEL_PROP and DEL_PROP_HOST calls.\n"); 523 576 for (unsigned i = 0; RT_SUCCESS(rc) && (delProperties[i].pcszName != NULL); 524 577 ++i) 525 578 { 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 } 538 592 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; 555 594 } 556 595 return rc; … … 623 662 RTPrintf("Getting property '%s' returned %Rrc instead of VERR_NOT_FOUND.\n", 624 663 getProperties[i].pcszName, rc2); 625 rc = VERR_ UNRESOLVED_ERROR;664 rc = VERR_IPE_UNEXPECTED_STATUS; 626 665 } 627 666 if (RT_SUCCESS(rc) && getProperties[i].exists) … … 813 852 } 814 853 854 /** Array of properties for testing SET_PROP_HOST and _GUEST with the 855 * READONLYGUEST global flag set. */ 856 static 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 } 871 setPropertiesROGuest[] = 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 */ 891 int 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 */ 915 int 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. */ 952 static 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 } 965 delPropertiesROGuest[] = 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 */ 983 int 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 815 1020 int main(int argc, char **argv) 816 1021 { … … 825 1030 if (RT_FAILURE(VBoxHGCMSvcLoad(&svcTable))) 826 1031 { 827 RTPrintf("Failed to start HGCM service.\n");1032 RTPrintf("Failed to start the HGCM service.\n"); 828 1033 return 1; 829 1034 } … … 847 1052 if (RT_FAILURE(testGetNotification(&svcTable))) 848 1053 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; 849 1063 RTPrintf("tstGuestPropSvc: SUCCEEDED.\n"); 850 1064 return 0;
Note:
See TracChangeset
for help on using the changeset viewer.