Changeset 13763 in vbox for trunk/src/VBox/HostServices/GuestProperties/testcase/tstGuestPropSvc.cpp
- Timestamp:
- Nov 3, 2008 4:39:22 PM (16 years ago)
- svn:sync-xref-src-repo-rev:
- 38738
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostServices/GuestProperties/testcase/tstGuestPropSvc.cpp
r13759 r13763 2 2 /** @file 3 3 * 4 * Testcase for the guest property service. 4 * Testcase for the guest property service. For now, this only tests 5 * flag conversion. 5 6 */ 6 7 … … 30 31 using namespace guestProp; 31 32 32 extern "C" DECLCALLBACK(DECLEXPORT(int)) VBoxHGCMSvcLoad (VBOXHGCMSVCFNTABLE *ptable);33 34 /** Set a pointer value to an HGCM parameter structure */35 static void VBoxHGCMParmPtrSet (VBOXHGCMSVCPARM *pParm, void *pv, uint32_t cb)36 {37 pParm->type = VBOX_HGCM_SVC_PARM_PTR;38 pParm->u.pointer.addr = pv;39 pParm->u.pointer.size = cb;40 }41 42 /** Extract a uint64_t value from an HGCM parameter structure */43 static int VBoxHGCMParmUInt32Get (VBOXHGCMSVCPARM *pParm, uint32_t *pu32Value)44 {45 if (pParm->type == VBOX_HGCM_SVC_PARM_32BIT)46 {47 *pu32Value = pParm->u.uint32;48 return VINF_SUCCESS;49 }50 51 return VERR_INVALID_PARAMETER;52 }53 54 /** Extract a uint64_t value from an HGCM parameter structure */55 static int VBoxHGCMParmUInt64Get (VBOXHGCMSVCPARM *pParm, uint64_t *pu64Value)56 {57 if (pParm->type == VBOX_HGCM_SVC_PARM_64BIT)58 {59 *pu64Value = pParm->u.uint64;60 return VINF_SUCCESS;61 }62 63 return VERR_INVALID_PARAMETER;64 }65 66 /** Simple call handle structure for the guest call completion callback */67 struct VBOXHGCMCALLHANDLE_TYPEDEF68 {69 /** Where to store the result code */70 int32_t rc;71 };72 73 /** Call completion callback for guest calls. */74 static void callComplete(VBOXHGCMCALLHANDLE callHandle, int32_t rc)75 {76 callHandle->rc = rc;77 }78 79 33 /** 80 * Initialise the HGCM service table as much as we need to start the 81 * service 82 * @param pTable the table to initialise 83 */ 84 void initTable(VBOXHGCMSVCFNTABLE *pTable, VBOXHGCMSVCHELPERS *pHelpers) 85 { 86 pTable->cbSize = sizeof (VBOXHGCMSVCFNTABLE); 87 pTable->u32Version = VBOX_HGCM_SVC_VERSION; 88 pHelpers->pfnCallComplete = callComplete; 89 pTable->pHelpers = pHelpers; 90 } 91 92 /** 93 * A list of valid flag strings for testConvertFlags. The flag conversion 94 * functions should accept these and convert them from string to a flag type 95 * and back without errors. 34 * A list of valid flag strings. The flag conversion functions should accept 35 * these and convert them from string to a flag type and back without errors. 96 36 */ 97 37 struct flagStrings … … 104 44 validFlagStrings[] = 105 45 { 106 { " 46 { "", "" }, 107 47 { "transient, ", "TRANSIENT" }, 108 { " rdOnLyHOST, transIENT , READONLY ", "TRANSIENT, READONLY" }, 109 { " rdonlyguest", "RDONLYGUEST" }, 110 { "rdonlyhost ", "RDONLYHOST" } 48 { " rdOnLyHOST, transIENT , READONLY ", "TRANSIENT, READONLY" } 111 49 }; 112 50 113 /**114 * A list of invalid flag strings for testConvertFlags. The flag conversion115 * functions should reject these.116 */117 const char *invalidFlagStrings[] =118 {119 "RDONLYHOST,,",120 " TRANSIENT READONLY"121 };122 123 /**124 * Test the flag conversion functions.125 * @returns iprt status value to indicate whether the test went as expected.126 * @note prints its own diagnostic information to stdout.127 */128 51 int testConvertFlags() 129 52 { … … 132 55 for (unsigned i = 0; i < RT_ELEMENTS(validFlagStrings) && RT_SUCCESS(rc); ++i) 133 56 { 134 char szFlagBuffer[MAX_FLAGS_LEN * 2];57 char szFlagBuffer[MAX_FLAGS_LEN]; 135 58 uint32_t fFlags; 136 59 rc = validateFlags(validFlagStrings[i].pcszIn, &fFlags); 137 60 if (RT_FAILURE(rc)) 138 RTPrintf("tstGuestPropSvc: FAILURE - Failed to validate flag string '%s'.\n", validFlagStrings[i].pcszIn);61 RTPrintf("tstGuestPropSvc: FAILURE - Failed to validate flag string %s.\n", validFlagStrings[i].pcszIn); 139 62 if (RT_SUCCESS(rc)) 140 63 { 141 64 rc = writeFlags(fFlags, szFlagBuffer); 142 65 if (RT_FAILURE(rc)) 143 RTPrintf("tstGuestPropSvc: FAILURE - Failed to convert flag string '%s'back to a string.\n",66 RTPrintf("tstGuestPropSvc: FAILURE - Failed to convert flag string %s back to a string.\n", 144 67 validFlagStrings[i].pcszIn); 145 68 } 146 69 if (RT_SUCCESS(rc) && (strlen(szFlagBuffer) > MAX_FLAGS_LEN - 1)) 147 70 { 148 RTPrintf("tstGuestPropSvc: FAILURE - String '%s'converts back to a flag string which is too long.\n",71 RTPrintf("tstGuestPropSvc: FAILURE - String %s converts back to a flag string which is too long.\n", 149 72 validFlagStrings[i].pcszIn); 150 73 rc = VERR_TOO_MUCH_DATA; … … 152 75 if (RT_SUCCESS(rc) && (strcmp(szFlagBuffer, validFlagStrings[i].pcszOut) != 0)) 153 76 { 154 RTPrintf("tstGuestPropSvc: FAILURE - String '%s' converts back to '%s' instead of to '%s'\n",77 RTPrintf("tstGuestPropSvc: FAILURE - String %s converts back to %s instead of to %s\n", 155 78 validFlagStrings[i].pcszIn, szFlagBuffer, 156 79 validFlagStrings[i].pcszOut); 157 80 rc = VERR_PARSE_ERROR; 158 }159 }160 if (RT_SUCCESS(rc))161 {162 RTPrintf("Testing rejection of invalid flags strings.\n");163 for (unsigned i = 0; i < RT_ELEMENTS(invalidFlagStrings) && RT_SUCCESS(rc); ++i)164 {165 uint32_t fFlags;166 /* This is required to fail. */167 if (RT_SUCCESS(validateFlags(invalidFlagStrings[i], &fFlags)))168 {169 RTPrintf("String '%s' was incorrectly accepted as a valid flag string.\n",170 invalidFlagStrings[i]);171 rc = VERR_PARSE_ERROR;172 }173 }174 }175 if (RT_SUCCESS(rc))176 {177 char szFlagBuffer[MAX_FLAGS_LEN * 2];178 uint32_t u32BadFlags = ALLFLAGS << 1;179 RTPrintf("Testing rejection of an invalid flags field.\n");180 /* This is required to fail. */181 if (RT_SUCCESS(writeFlags(u32BadFlags, szFlagBuffer)))182 {183 RTPrintf("Flags 0x%x were incorrectly written out as '%.*s'\n",184 u32BadFlags, MAX_FLAGS_LEN, szFlagBuffer);185 rc = VERR_PARSE_ERROR;186 }187 }188 return rc;189 }190 191 /**192 * List of property names for testSetPropsHost.193 */194 const char *apcszNameBlock[] =195 {196 "test/name/",197 "test name",198 "TEST NAME",199 "/test/name",200 NULL201 };202 203 /**204 * List of property values for testSetPropsHost.205 */206 const char *apcszValueBlock[] =207 {208 "test/value/",209 "test value",210 "TEST VALUE",211 "/test/value",212 NULL213 };214 215 /**216 * List of property timestamps for testSetPropsHost.217 */218 uint64_t au64TimestampBlock[] =219 {220 0, 999, 999999, 999999999999, 0221 };222 223 /**224 * List of property flags for testSetPropsHost.225 */226 const char *apcszFlagsBlock[] =227 {228 "",229 "readonly, transient",230 "RDONLYHOST",231 "RdOnlyGuest",232 NULL233 };234 235 /**236 * Test the SET_PROPS_HOST function.237 * @returns iprt status value to indicate whether the test went as expected.238 * @note prints its own diagnostic information to stdout.239 */240 int testSetPropsHost(VBOXHGCMSVCFNTABLE *ptable)241 {242 int rc = VINF_SUCCESS;243 RTPrintf("Testing the SET_PROPS_HOST call.\n");244 if (!VALID_PTR(ptable->pfnHostCall))245 {246 RTPrintf("Invalid pfnHostCall() pointer\n");247 rc = VERR_INVALID_POINTER;248 }249 if (RT_SUCCESS(rc))250 {251 VBOXHGCMSVCPARM paParms[4];252 VBoxHGCMParmPtrSet(&paParms[0], (void *) apcszNameBlock, 0);253 VBoxHGCMParmPtrSet(&paParms[1], (void *) apcszValueBlock, 0);254 VBoxHGCMParmPtrSet(&paParms[2], (void *) au64TimestampBlock, 0);255 VBoxHGCMParmPtrSet(&paParms[3], (void *) apcszFlagsBlock, 0);256 rc = ptable->pfnHostCall(ptable->pvService, SET_PROPS_HOST, 4,257 paParms);258 if (RT_FAILURE(rc))259 RTPrintf("SET_PROPS_HOST call failed with rc=%Rrc\n", rc);260 }261 return rc;262 }263 264 /** Result strings for zeroth enumeration test */265 static const char *pcchEnumResult0[] =266 {267 "test/name/\0test/value/\0""0\0",268 "test name\0test value\0""999\0TRANSIENT, READONLY",269 "TEST NAME\0TEST VALUE\0""999999\0RDONLYHOST",270 "/test/name\0/test/value\0""999999999999\0RDONLYGUEST",271 NULL272 };273 274 /** Result string sizes for zeroth enumeration test */275 static const size_t cchEnumResult0[] =276 {277 sizeof("test/name/\0test/value/\0""0\0"),278 sizeof("test name\0test value\0""999\0TRANSIENT, READONLY"),279 sizeof("TEST NAME\0TEST VALUE\0""999999\0RDONLYHOST"),280 sizeof("/test/name\0/test/value\0""999999999999\0RDONLYGUEST"),281 0282 };283 284 /**285 * The size of the buffer returned by the zeroth enumeration test -286 * the - 1 at the end is because of the hidden zero terminator287 */288 static const size_t cchEnumBuffer0 =289 sizeof("test/name/\0test/value/\0""0\0\0"290 "test name\0test value\0""999\0TRANSIENT, READONLY\0"291 "TEST NAME\0TEST VALUE\0""999999\0RDONLYHOST\0"292 "/test/name\0/test/value\0""999999999999\0RDONLYGUEST\0\0\0\0\0") - 1;293 294 /** Result strings for first and second enumeration test */295 static const char *pcchEnumResult1[] =296 {297 "TEST NAME\0TEST VALUE\0""999999\0RDONLYHOST",298 "/test/name\0/test/value\0""999999999999\0RDONLYGUEST",299 NULL300 };301 302 /** Result string sizes for first and second enumeration test */303 static const size_t cchEnumResult1[] =304 {305 sizeof("TEST NAME\0TEST VALUE\0""999999\0RDONLYHOST"),306 sizeof("/test/name\0/test/value\0""999999999999\0RDONLYGUEST"),307 0308 };309 310 /**311 * The size of the buffer returned by the first enumeration test -312 * the - 1 at the end is because of the hidden zero terminator313 */314 static const size_t cchEnumBuffer1 =315 sizeof("TEST NAME\0TEST VALUE\0""999999\0RDONLYHOST\0"316 "/test/name\0/test/value\0""999999999999\0RDONLYGUEST\0\0\0\0\0") - 1;317 318 static const struct enumStringStruct319 {320 /** The enumeration pattern to test */321 const char *pcszPatterns;322 /** The size of the pattern string */323 const size_t cchPatterns;324 /** The expected enumeration output strings */325 const char **ppcchResult;326 /** The size of the output strings */327 const size_t *pcchResult;328 /** The size of the buffer needed for the enumeration */329 const size_t cchBuffer;330 }331 enumStrings[] =332 {333 {334 "", sizeof(""),335 pcchEnumResult0,336 cchEnumResult0,337 cchEnumBuffer0338 },339 {340 "/*\0?E*", sizeof("/*\0?E*"),341 pcchEnumResult1,342 cchEnumResult1,343 cchEnumBuffer1344 },345 {346 "/*|?E*", sizeof("/*|?E*"),347 pcchEnumResult1,348 cchEnumResult1,349 cchEnumBuffer1350 }351 };352 353 /**354 * Test the ENUM_PROPS_HOST function.355 * @returns iprt status value to indicate whether the test went as expected.356 * @note prints its own diagnostic information to stdout.357 */358 int testEnumPropsHost(VBOXHGCMSVCFNTABLE *ptable)359 {360 int rc = VINF_SUCCESS;361 RTPrintf("Testing the ENUM_PROPS_HOST call.\n");362 if (!VALID_PTR(ptable->pfnHostCall))363 {364 RTPrintf("Invalid pfnHostCall() pointer\n");365 rc = VERR_INVALID_POINTER;366 }367 for (unsigned i = 0; RT_SUCCESS(rc) && i < RT_ELEMENTS(enumStrings);368 ++i)369 {370 char buffer[2048];371 VBOXHGCMSVCPARM paParms[3];372 VBoxHGCMParmPtrSet(&paParms[0],373 (void *) enumStrings[i].pcszPatterns,374 enumStrings[i].cchPatterns);375 VBoxHGCMParmPtrSet(&paParms[1],376 (void *) buffer,377 enumStrings[i].cchBuffer - 1);378 AssertBreakStmt(sizeof(buffer) > enumStrings[i].cchBuffer,379 rc = VERR_INTERNAL_ERROR);380 if (RT_SUCCESS(rc))381 {382 /* This should fail as the buffer is too small. */383 int rc2 = ptable->pfnHostCall(ptable->pvService, ENUM_PROPS_HOST,384 3, paParms);385 if (rc2 != VERR_BUFFER_OVERFLOW)386 {387 RTPrintf("ENUM_PROPS_HOST returned %Rrc instead of VERR_BUFFER_OVERFLOW on too small buffer, pattern number %d\n", rc2, i);388 rc = VERR_BUFFER_OVERFLOW;389 }390 else391 {392 uint32_t cchBufferActual;393 rc = VBoxHGCMParmUInt32Get(&paParms[2], &cchBufferActual);394 if (RT_SUCCESS(rc) && cchBufferActual != enumStrings[i].cchBuffer)395 {396 RTPrintf("ENUM_PROPS_HOST requested a buffer size of %lu instead of %lu for pattern number %d\n", cchBufferActual, enumStrings[i].cchBuffer, i);397 rc = VERR_OUT_OF_RANGE;398 }399 else if (RT_FAILURE(rc))400 RTPrintf("ENUM_PROPS_HOST did not return the required buffer size properly for pattern %d\n", i);401 }402 }403 if (RT_SUCCESS(rc))404 {405 VBoxHGCMParmPtrSet(&paParms[1], (void *) buffer,406 enumStrings[i].cchBuffer);407 rc = ptable->pfnHostCall(ptable->pvService, ENUM_PROPS_HOST,408 3, paParms);409 if (RT_FAILURE(rc))410 RTPrintf("ENUM_PROPS_HOST call failed for pattern %d with rc=%Rrc\n", i, rc);411 else412 /* Look for each of the result strings in the buffer which was returned */413 for (unsigned j = 0; RT_SUCCESS(rc) && enumStrings[i].ppcchResult[j] != NULL;414 ++j)415 {416 bool found = false;417 for (unsigned k = 0; !found && k < enumStrings[i].cchBuffer418 - enumStrings[i].pcchResult[j];419 ++k)420 if (memcmp(buffer + k, enumStrings[i].ppcchResult[j],421 enumStrings[i].pcchResult[j]) == 0)422 found = true;423 if (!found)424 {425 RTPrintf("ENUM_PROPS_HOST did not produce the expected output for pattern %d\n",426 i);427 rc = VERR_UNRESOLVED_ERROR;428 }429 }430 }431 }432 return rc;433 }434 435 /** Array of properties for testing SET_PROP_HOST and _GUEST. */436 static const struct437 {438 /** Property name */439 const char *pcszName;440 /** Property value */441 const char *pcszValue;442 /** Property flags */443 const char *pcszFlags;444 /** Should this be set as the host or the guest? */445 bool isHost;446 /** Should we use SET_PROP or SET_PROP_VALUE? */447 bool useSetProp;448 /** Should this succeed or be rejected with VERR_PERMISSION_DENIED? */449 bool isAllowed;450 }451 setProperties[] =452 {453 { "Red", "Stop!", "transient", false, true, true },454 { "Amber", "Caution!", "", false, false, true },455 { "Green", "Go!", "readonly", true, true, true },456 { "Blue", "What on earth...?", "", true, false, true },457 { "/test/name", "test", "", false, true, false },458 { "TEST NAME", "test", "", true, true, false },459 { "Green", "gone out...", "", false, false, false },460 { "Green", "gone out...", "", true, false, false },461 { NULL, NULL, NULL, false, false, false }462 };463 464 /**465 * Test the SET_PROP, SET_PROP_VALUE, SET_PROP_HOST and SET_PROP_VALUE_HOST466 * functions.467 * @returns iprt status value to indicate whether the test went as expected.468 * @note prints its own diagnostic information to stdout.469 */470 int testSetProp(VBOXHGCMSVCFNTABLE *pTable)471 {472 int rc = VINF_SUCCESS;473 VBOXHGCMCALLHANDLE_TYPEDEF callHandle = { VINF_SUCCESS };474 RTPrintf("Testing the SET_PROP, SET_PROP_VALUE, SET_PROP_HOST and SET_PROP_VALUE_HOST calls.\n");475 for (unsigned i = 0; RT_SUCCESS(rc) && (setProperties[i].pcszName != NULL);476 ++i)477 {478 int command = SET_PROP_VALUE;479 if (setProperties[i].isHost)480 {481 if (setProperties[i].useSetProp)482 command = SET_PROP_HOST;483 else484 command = SET_PROP_VALUE_HOST;485 }486 else if (setProperties[i].useSetProp)487 command = SET_PROP;488 VBOXHGCMSVCPARM paParms[3];489 /* Work around silly constant issues - we ought to allow passing490 * constant strings in the hgcm parameters. */491 char szName[MAX_NAME_LEN] = "";492 char szValue[MAX_VALUE_LEN] = "";493 char szFlags[MAX_FLAGS_LEN] = "";494 strncat(szName, setProperties[i].pcszName, sizeof(szName));495 strncat(szValue, setProperties[i].pcszValue, sizeof(szValue));496 strncat(szFlags, setProperties[i].pcszFlags, sizeof(szFlags));497 VBoxHGCMParmPtrSet(&paParms[0], szName, strlen(szName) + 1);498 VBoxHGCMParmPtrSet(&paParms[1], szValue, strlen(szValue) + 1);499 VBoxHGCMParmPtrSet(&paParms[2], szFlags, strlen(szFlags) + 1);500 if (setProperties[i].isHost)501 callHandle.rc = pTable->pfnHostCall(pTable->pvService, command,502 setProperties[i].useSetProp503 ? 3 : 2, paParms);504 else505 pTable->pfnCall(pTable->pvService, &callHandle, 0, NULL, command,506 setProperties[i].useSetProp ? 3 : 2, paParms);507 if (setProperties[i].isAllowed && RT_FAILURE(callHandle.rc))508 {509 RTPrintf("Setting property '%s' failed with rc=%Rrc.\n",510 setProperties[i].pcszName, callHandle.rc);511 rc = callHandle.rc;512 }513 else if ( !setProperties[i].isAllowed514 && (callHandle.rc != VERR_PERMISSION_DENIED)515 )516 {517 RTPrintf("Setting property '%s' returned %Rrc instead of VERR_PERMISSION_DENIED.\n",518 setProperties[i].pcszName, callHandle.rc);519 rc = VERR_UNRESOLVED_ERROR;520 }521 }522 return rc;523 }524 525 /** Array of properties for testing DEL_PROP_HOST and _GUEST. */526 static const struct527 {528 /** Property name */529 const char *pcszName;530 /** Should this be set as the host or the guest? */531 bool isHost;532 /** Should this succeed or be rejected with VERR_PERMISSION_DENIED? */533 bool isAllowed;534 }535 delProperties[] =536 {537 { "Red", false, true },538 { "Amber", true, true },539 { "Red2", false, true },540 { "Amber2", true, true },541 { "Green", false, false },542 { "Green", true, false },543 { "/test/name", false, false },544 { "TEST NAME", true, false },545 { NULL, false, false }546 };547 548 /**549 * Test the DEL_PROP, and DEL_PROP_HOST functions.550 * @returns iprt status value to indicate whether the test went as expected.551 * @note prints its own diagnostic information to stdout.552 */553 int testDelProp(VBOXHGCMSVCFNTABLE *pTable)554 {555 int rc = VINF_SUCCESS;556 VBOXHGCMCALLHANDLE_TYPEDEF callHandle = { VINF_SUCCESS };557 RTPrintf("Testing the DEL_PROP and DEL_PROP_HOST calls.\n");558 for (unsigned i = 0; RT_SUCCESS(rc) && (delProperties[i].pcszName != NULL);559 ++i)560 {561 int command = DEL_PROP;562 if (delProperties[i].isHost)563 command = DEL_PROP_HOST;564 VBOXHGCMSVCPARM paParms[1];565 /* Work around silly constant issues - we ought to allow passing566 * constant strings in the hgcm parameters. */567 char szName[MAX_NAME_LEN] = "";568 strncat(szName, delProperties[i].pcszName, sizeof(szName));569 VBoxHGCMParmPtrSet(&paParms[0], szName, strlen(szName) + 1);570 if (delProperties[i].isHost)571 callHandle.rc = pTable->pfnHostCall(pTable->pvService, command,572 1, paParms);573 else574 pTable->pfnCall(pTable->pvService, &callHandle, 0, NULL, command,575 1, paParms);576 if (delProperties[i].isAllowed && RT_FAILURE(callHandle.rc))577 {578 RTPrintf("Deleting property '%s' failed with rc=%Rrc.\n",579 delProperties[i].pcszName, callHandle.rc);580 rc = callHandle.rc;581 }582 else if ( !delProperties[i].isAllowed583 && (callHandle.rc != VERR_PERMISSION_DENIED)584 )585 {586 RTPrintf("Deleting property '%s' returned %Rrc instead of VERR_PERMISSION_DENIED.\n",587 delProperties[i].pcszName, callHandle.rc);588 rc = VERR_UNRESOLVED_ERROR;589 }590 }591 return rc;592 }593 594 /** Array of properties for testing GET_PROP_HOST. */595 static const struct596 {597 /** Property name */598 const char *pcszName;599 /** What value/flags pattern do we expect back? */600 const char *pcchValue;601 /** What size should the value/flags array be? */602 uint32_t cchValue;603 /** Should this proeprty exist? */604 bool exists;605 /** Do we expect a particular timestamp? */606 bool hasTimestamp;607 /** What timestamp if any do ex expect? */608 uint64_t u64Timestamp;609 }610 getProperties[] =611 {612 { "test/name/", "test/value/\0", sizeof("test/value/\0"), true, true, 0 },613 { "test name", "test value\0TRANSIENT, READONLY",614 sizeof("test value\0TRANSIENT, READONLY"), true, true, 999 },615 { "TEST NAME", "TEST VALUE\0RDONLYHOST", sizeof("TEST VALUE\0RDONLYHOST"),616 true, true, 999999 },617 { "/test/name", "/test/value\0RDONLYGUEST",618 sizeof("/test/value\0RDONLYGUEST"), true, true, 999999999999 },619 { "Green", "Go!\0READONLY", sizeof("Go!\0READONLY"), true, false, 0 },620 { "Blue", "What on earth...?\0", sizeof("What on earth...?\0"), true,621 false, 0 },622 { "Red", "", 0, false, false, 0 },623 { NULL, NULL, 0, false, false, 0 }624 };625 626 /**627 * Test the GET_PROP_HOST function.628 * @returns iprt status value to indicate whether the test went as expected.629 * @note prints its own diagnostic information to stdout.630 */631 int testGetProp(VBOXHGCMSVCFNTABLE *pTable)632 {633 int rc = VINF_SUCCESS, rc2 = VINF_SUCCESS;634 RTPrintf("Testing the GET_PROP_HOST call.\n");635 for (unsigned i = 0; RT_SUCCESS(rc) && (getProperties[i].pcszName != NULL);636 ++i)637 {638 VBOXHGCMSVCPARM paParms[4];639 /* Work around silly constant issues - we ought to allow passing640 * constant strings in the hgcm parameters. */641 char szName[MAX_NAME_LEN] = "";642 char szBuffer[MAX_VALUE_LEN + MAX_FLAGS_LEN];643 AssertBreakStmt(sizeof(szBuffer) >= getProperties[i].cchValue,644 rc = VERR_INTERNAL_ERROR);645 strncat(szName, getProperties[i].pcszName, sizeof(szName));646 VBoxHGCMParmPtrSet(&paParms[0], szName, strlen(szName) + 1);647 VBoxHGCMParmPtrSet(&paParms[1], szBuffer, sizeof(szBuffer));648 rc2 = pTable->pfnHostCall(pTable->pvService, GET_PROP_HOST, 4,649 paParms);650 if (getProperties[i].exists && RT_FAILURE(rc2))651 {652 RTPrintf("Getting property '%s' failed with rc=%Rrc.\n",653 getProperties[i].pcszName, rc2);654 rc = rc2;655 }656 else if (!getProperties[i].exists && (rc2 != VERR_NOT_FOUND))657 {658 RTPrintf("Getting property '%s' returned %Rrc instead of VERR_NOT_FOUND.\n",659 getProperties[i].pcszName, rc2);660 rc = VERR_UNRESOLVED_ERROR;661 }662 if (RT_SUCCESS(rc) && getProperties[i].exists)663 {664 uint32_t u32ValueLen;665 rc = VBoxHGCMParmUInt32Get(&paParms[3], &u32ValueLen);666 if (RT_FAILURE(rc))667 RTPrintf("Failed to get the size of the output buffer for property '%s'\n",668 getProperties[i].pcszName);669 if ( RT_SUCCESS(rc)670 && (memcmp(szBuffer, getProperties[i].pcchValue,671 getProperties[i].cchValue) != 0)672 )673 {674 RTPrintf("Unexpected result '%.*s' for property '%s', expected '%.*s'.\n",675 u32ValueLen, szBuffer, getProperties[i].pcszName,676 getProperties[i].cchValue, getProperties[i].pcchValue);677 rc = VERR_UNRESOLVED_ERROR;678 }679 if (RT_SUCCESS(rc) && getProperties[i].hasTimestamp)680 {681 uint64_t u64Timestamp;682 rc = VBoxHGCMParmUInt64Get(&paParms[2], &u64Timestamp);683 if (RT_FAILURE(rc))684 RTPrintf("Failed to get the timestamp for property '%s'\n",685 getProperties[i].pcszName);686 if ( RT_SUCCESS(rc)687 && (u64Timestamp != getProperties[i].u64Timestamp)688 )689 {690 RTPrintf("Bad timestamp %llu for property '%s', expected %llu.\n",691 u64Timestamp, getProperties[i].pcszName,692 getProperties[i].u64Timestamp);693 rc = VERR_UNRESOLVED_ERROR;694 }695 }696 81 } 697 82 } … … 701 86 int main(int argc, char **argv) 702 87 { 703 VBOXHGCMSVCFNTABLE svcTable;704 VBOXHGCMSVCHELPERS svcHelpers;705 initTable(&svcTable, &svcHelpers);706 88 RTR3Init(); 707 89 if (RT_FAILURE(testConvertFlags())) 708 return 1;709 /* The function is inside the service, not HGCM. */710 if (RT_FAILURE(VBoxHGCMSvcLoad(&svcTable)))711 {712 RTPrintf("Failed to start HGCM service.\n");713 return 1;714 }715 if (RT_FAILURE(testSetPropsHost(&svcTable)))716 return 1;717 if (RT_FAILURE(testEnumPropsHost(&svcTable)))718 return 1;719 if (RT_FAILURE(testSetProp(&svcTable)))720 return 1;721 if (RT_FAILURE(testDelProp(&svcTable)))722 return 1;723 if (RT_FAILURE(testGetProp(&svcTable)))724 90 return 1; 725 91 RTPrintf("tstGuestPropSvc: SUCCEEDED.\n"); 726 92 return 0; 727 93 } 94
Note:
See TracChangeset
for help on using the changeset viewer.