Changeset 14104 in vbox for trunk/src/VBox
- Timestamp:
- Nov 11, 2008 7:16:32 PM (16 years ago)
- Location:
- trunk/src/VBox/HostServices/GuestProperties
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostServices/GuestProperties/service.cpp
r14011 r14104 60 60 #include <string> 61 61 #include <list> 62 #include <vector>63 62 64 63 namespace guestProp { … … 112 111 /** The function that was requested */ 113 112 uint32_t mFunction; 114 /** The number of parameters */ 115 uint32_t mcParms; 116 /** The parameters themselves */ 113 /** The call parameters */ 117 114 VBOXHGCMSVCPARM *mParms; 115 /** The default return value, used for passing warnings */ 116 int mRc; 118 117 119 118 /** The standard constructor */ 120 GuestCall() : mFunction(0) , mcParms(0){}119 GuestCall() : mFunction(0) {} 121 120 /** The normal contructor */ 122 121 GuestCall(VBOXHGCMCALLHANDLE aHandle, uint32_t aFunction, 123 uint32_t acParms, VBOXHGCMSVCPARM aParms[])124 : mHandle(aHandle), mFunction(aFunction), m cParms(acParms),125 mParms(aParms) {}122 VBOXHGCMSVCPARM aParms[], int aRc) 123 : mHandle(aHandle), mFunction(aFunction), mParms(aParms), 124 mRc(aRc) {} 126 125 }; 127 typedef std:: vector <GuestCall> CallVector;126 typedef std::list <GuestCall> CallList; 128 127 /** The list of outstanding guest notification calls */ 129 Call VectormGuestWaiters;128 CallList mGuestWaiters; 130 129 /** @todo we should have classes for thread and request handler thread */ 131 130 /** Queue of outstanding property change notifications */ … … 238 237 int enumProps(uint32_t cParms, VBOXHGCMSVCPARM paParms[]); 239 238 int getNotification(VBOXHGCMCALLHANDLE callHandle, uint32_t cParms, 240 VBOXHGCMSVCPARM paParms[], bool canWait); 239 VBOXHGCMSVCPARM paParms[]); 240 int getOldNotification(const char *pszPattern, uint64_t u64Timestamp, 241 Property *pProp); 242 int getNotificationWriteOut(VBOXHGCMSVCPARM paParms[], Property prop); 241 243 void doNotifications(const char *pszProperty, uint64_t u64Timestamp); 242 244 static DECLCALLBACK(int) reqNotify(PFNHGCMSVCEXT pfnCallback, … … 439 441 char *pchBuf; 440 442 uint32_t cchName, cchBuf; 441 size_t cchFlags, cchBufActual;443 uint32_t cchFlags, cchBufActual; 442 444 char szFlags[MAX_FLAGS_LEN]; 443 uint32_t fFlags;444 445 445 446 /* … … 734 735 char szFlags[MAX_FLAGS_LEN]; 735 736 char szTimestamp[256]; 736 size_t cchTimestamp;737 uint32_t cchTimestamp; 737 738 buffer += it->mName; 738 739 buffer += '\0'; … … 768 769 769 770 /** 771 * Get the next property change notification from the queue of saved 772 * notification based on the timestamp of the last notification seen. 773 * Notifications will only be reported if the property name matches the 774 * pattern given. 775 * 776 * @returns iprt status value 777 * @returns VWRN_NOT_FOUND if the last notification was not found in the queue 778 * @param pszPatterns the patterns to match the property name against 779 * @param u64Timestamp the timestamp of the last notification 780 * @param pProp where to return the property found. If none is 781 * found this will be set to nil. 782 * @thread HGCM 783 */ 784 int Service::getOldNotification(const char *pszPatterns, uint64_t u64Timestamp, 785 Property *pProp) 786 { 787 AssertPtrReturn(pszPatterns, VERR_INVALID_POINTER); 788 AssertReturn(u64Timestamp != 0, VERR_INVALID_PARAMETER); /* Zero means wait for a new notification. */ 789 AssertPtrReturn(pProp, VERR_INVALID_POINTER); 790 int rc = VINF_SUCCESS; 791 bool warn = false; 792 793 /* We count backwards, as the guest should normally be querying the 794 * most recent events. */ 795 PropertyList::reverse_iterator it = mGuestNotifications.rbegin(); 796 for (; it->mTimestamp != u64Timestamp && it != mGuestNotifications.rend(); 797 ++it) {} 798 /* Warn if the timestamp was not found. */ 799 if (it->mTimestamp != u64Timestamp) 800 warn = true; 801 /* Now look for an event matching the patterns supplied. The base() 802 * member conveniently points to the following element. */ 803 PropertyList::iterator base = it.base(); 804 for (; pszPatterns[0] != '\0' 805 && !RTStrSimplePatternMultiMatch(pszPatterns, RTSTR_MAX, 806 base->mName.c_str(), RTSTR_MAX, 807 NULL) 808 && base != mGuestNotifications.end(); ++base) {} 809 if (RT_SUCCESS(rc) && base != mGuestNotifications.end()) 810 *pProp = *base; 811 else if (RT_SUCCESS(rc)) 812 *pProp = Property(); 813 if (warn) 814 rc = VWRN_NOT_FOUND; 815 return rc; 816 } 817 818 int Service::getNotificationWriteOut(VBOXHGCMSVCPARM paParms[], Property prop) 819 { 820 int rc = VINF_SUCCESS; 821 /* Format the data to write to the buffer. */ 822 std::string buffer; 823 uint64_t u64Timestamp; 824 char *pchBuf; 825 uint32_t cchBuf; 826 rc = paParms[2].getPointer((void **) &pchBuf, &cchBuf); 827 if (RT_SUCCESS(rc)) 828 { 829 char szFlags[MAX_FLAGS_LEN]; 830 rc = writeFlags(prop.mFlags, szFlags); 831 if (RT_SUCCESS(rc)) 832 { 833 buffer += prop.mName; 834 buffer += '\0'; 835 buffer += prop.mValue; 836 buffer += '\0'; 837 buffer += szFlags; 838 buffer += '\0'; 839 u64Timestamp = prop.mTimestamp; 840 } 841 } 842 /* Write out the data. */ 843 if (RT_SUCCESS(rc)) 844 { 845 paParms[1].setUInt64(u64Timestamp); 846 paParms[3].setUInt32(buffer.size()); 847 if (buffer.size() <= cchBuf) 848 buffer.copy(pchBuf, cchBuf); 849 else 850 rc = VERR_BUFFER_OVERFLOW; 851 } 852 return rc; 853 } 854 855 /** 770 856 * Get the next guest notification. 771 857 * … … 773 859 * @param cParms the number of HGCM parameters supplied 774 860 * @param paParms the array of HGCM parameters 775 * @param canWait can this request be enqueued776 861 * @thread HGCM 777 * @throws can throw std::bad_alloc if canWait==true862 * @throws can throw std::bad_alloc 778 863 */ 779 864 int Service::getNotification(VBOXHGCMCALLHANDLE callHandle, uint32_t cParms, 780 VBOXHGCMSVCPARM paParms[] , bool canWait)781 { 782 int rc = VINF_SUCCESS; 783 char *p chBuf;784 uint32_t cch Buf = 0;865 VBOXHGCMSVCPARM paParms[]) 866 { 867 int rc = VINF_SUCCESS; 868 char *pszPatterns, *pchBuf; 869 uint32_t cchPatterns = 0, cchBuf = 0; 785 870 uint64_t u64Timestamp; 786 bool warn = false;787 871 788 872 /* … … 790 874 */ 791 875 LogFlowThisFunc(("\n")); 792 if ( (cParms != 3) /* Hardcoded value as the next lines depend on it. */ 793 || RT_FAILURE(paParms[0].getUInt64 (&u64Timestamp)) /* timestamp */ 794 || RT_FAILURE(paParms[1].getPointer ((void **) &pchBuf, &cchBuf)) /* return buffer */ 876 if ( (cParms != 4) /* Hardcoded value as the next lines depend on it. */ 877 || RT_FAILURE(paParms[0].getPointer ((void **) &pszPatterns, &cchPatterns)) /* patterns */ 878 || pszPatterns[cchPatterns - 1] != '\0' /* The patterns string must be zero-terminated */ 879 || RT_FAILURE(paParms[1].getUInt64 (&u64Timestamp)) /* timestamp */ 880 || RT_FAILURE(paParms[2].getPointer ((void **) &pchBuf, &cchBuf)) /* return buffer */ 795 881 || cchBuf < 1 796 882 ) … … 800 886 * Find the change to notify of. 801 887 */ 802 Property next; 803 /* Return the oldest notification if no timestamp was specified. */ 804 if (RT_SUCCESS(rc) && !mGuestNotifications.empty() && u64Timestamp == 0) 805 next = mGuestNotifications.front(); 806 /* Only search if the guest hasn't seen the most recent notification. */ 807 else if ( RT_SUCCESS(rc) 808 && !mGuestNotifications.empty() 809 && mGuestNotifications.back().mTimestamp != u64Timestamp) 810 { 811 /* We count backwards, as the guest should normally be querying the 812 * most recent events. */ 813 PropertyList::reverse_iterator it = mGuestNotifications.rbegin(); 814 for ( ; it != mGuestNotifications.rend() 815 && it->mTimestamp != u64Timestamp; 816 ++it 817 ) {} 818 /* Warn if the timestamp was not found. */ 819 if (it == mGuestNotifications.rend()) 820 warn = true; 821 /* This is a reverse iterator, so --it goes up the list. */ 822 --it; 823 next = *it; 824 } 825 826 /* 827 * Format the data to write to the buffer. 828 */ 829 std::string buffer; 830 if (RT_SUCCESS(rc)) 831 { 832 char szFlags[MAX_FLAGS_LEN]; 833 rc = writeFlags(next.mFlags, szFlags); 834 if (RT_SUCCESS(rc)) 835 { 836 buffer += next.mName; 837 buffer += '\0'; 838 buffer += next.mValue; 839 buffer += '\0'; 840 buffer += szFlags; 841 buffer += '\0'; 842 u64Timestamp = next.mTimestamp; 843 } 844 } 845 846 /* 847 * Write out the data or add the caller to the notification list if there 848 * is no notification available. 849 */ 888 Property prop; 850 889 if (RT_SUCCESS(rc) && u64Timestamp != 0) 851 { 852 paParms[0].setUInt64(u64Timestamp); 853 paParms[2].setUInt32(buffer.size()); 854 if (RT_SUCCESS(rc) && buffer.size() <= cchBuf) 855 buffer.copy(pchBuf, cchBuf); 856 else if (RT_SUCCESS(rc)) 857 rc = VERR_BUFFER_OVERFLOW; 858 if (RT_SUCCESS(rc) && warn) 859 rc = VWRN_NOT_FOUND; 860 } 861 else if (RT_SUCCESS(rc) && canWait) 862 { 863 mGuestWaiters.push_back(GuestCall(callHandle, GET_NOTIFICATION, cParms, 864 paParms)); 890 rc = getOldNotification(pszPatterns, u64Timestamp, &prop); 891 if ( (RT_SUCCESS(rc) && u64Timestamp == 0) 892 || (RT_SUCCESS(rc) && prop.mName.size() == 1) /* Empty name -> not found */ 893 ) 894 { 895 mGuestWaiters.push_back(GuestCall(callHandle, GET_NOTIFICATION, 896 paParms, rc)); 865 897 rc = VINF_HGCM_ASYNC_EXECUTE; 866 898 } 867 else if (RT_SUCCESS(rc)) 868 { 869 AssertFailed(); 870 rc = VERR_INTERNAL_ERROR; 899 else 900 { 901 int rc2 = getNotificationWriteOut(paParms, prop); 902 if (RT_FAILURE(rc2)) 903 rc = rc2; 871 904 } 872 905 return rc; … … 885 918 void Service::doNotifications(const char *pszProperty, uint64_t u64Timestamp) 886 919 { 887 char szFlags[MAX_FLAGS_LEN];888 920 char *pszName = NULL, *pszValue = NULL, *pszFlags = NULL; 889 921 int rc = VINF_SUCCESS; … … 898 930 * Try to find the property. 899 931 */ 900 Property List::const_iterator it;932 Property prop; 901 933 bool found = false; 902 934 if (RT_SUCCESS(rc)) 903 for (it = mProperties.begin(); it != mProperties.end(); ++it) 935 for (PropertyList::const_iterator it = mProperties.begin(); 936 !found && it != mProperties.end(); ++it) 904 937 if (it->mName.compare(pszProperty) == 0) 905 938 { 906 939 found = true; 907 break;940 prop = *it; 908 941 } 909 942 … … 914 947 { 915 948 #ifndef VBOX_GUEST_PROP_TEST_NOTHREAD 949 char szFlags[MAX_FLAGS_LEN]; 916 950 /* Send out a host notification */ 917 rc = writeFlags( it->mFlags, szFlags);951 rc = writeFlags(prop.mFlags, szFlags); 918 952 if (RT_SUCCESS(rc)) 919 953 rc = RTStrDupEx(&pszName, pszProperty); 920 954 if (RT_SUCCESS(rc)) 921 rc = RTStrDupEx(&pszValue, it->mValue.c_str());955 rc = RTStrDupEx(&pszValue, prop.mValue.c_str()); 922 956 if (RT_SUCCESS(rc)) 923 957 rc = RTStrDupEx(&pszFlags, szFlags); … … 932 966 if (found) 933 967 { 934 /* Add the change to the queue for guest notifications and release935 * waiters */968 /* Release waiters if applicable and add the change to the queue for 969 * guest notifications */ 936 970 if (RT_SUCCESS(rc)) 937 971 { 938 972 try 939 973 { 940 mGuestNotifications.push_back(*it);941 while (mGuestWaiters.size() > 0)974 for (CallList::iterator it = mGuestWaiters.begin(); 975 it != mGuestWaiters.end(); ++it) 942 976 { 943 GuestCall call = mGuestWaiters.back(); 944 int rc2 = getNotification(call.mHandle, call.mcParms, 945 call.mParms, false); 946 mpHelpers->pfnCallComplete (call.mHandle, rc2); 947 mGuestWaiters.pop_back(); 977 const char *pszPatterns; 978 uint32_t cchPatterns; 979 it->mParms[0].getPointer((void **) &pszPatterns, &cchPatterns); 980 if ( pszPatterns[0] == '\0' 981 || RTStrSimplePatternMultiMatch(pszPatterns, RTSTR_MAX, 982 pszProperty, RTSTR_MAX, 983 NULL)) 984 { 985 GuestCall call = mGuestWaiters.back(); 986 int rc2 = getNotificationWriteOut(call.mParms, prop); 987 if (RT_SUCCESS(rc2)) 988 rc2 = call.mRc; 989 mpHelpers->pfnCallComplete (call.mHandle, rc2); 990 it = mGuestWaiters.erase(it); 991 } 948 992 } 993 mGuestNotifications.push_back(prop); 949 994 } 950 995 catch (std::bad_alloc) … … 1081 1126 case GET_NOTIFICATION: 1082 1127 LogFlowFunc(("GET_NOTIFICATION\n")); 1083 rc = getNotification(callHandle, cParms, paParms , true);1128 rc = getNotification(callHandle, cParms, paParms); 1084 1129 break; 1085 1130 -
trunk/src/VBox/HostServices/GuestProperties/testcase/Makefile.kmk
r13916 r14104 34 34 tstGuestPropSvc_SOURCES = tstGuestPropSvc.cpp ../service.cpp 35 35 tstGuestPropSvc_LIBS = $(LIB_RUNTIME) 36 # For now! 37 tstGuestPropSvc_CXXFLAGS.win = -EHsc 36 38 37 39 # Set this in LocalConfig.kmk if you are working on the guest property service -
trunk/src/VBox/HostServices/GuestProperties/testcase/tstGuestPropSvc.cpp
r13971 r14104 241 241 242 242 /** Result string sizes for zeroth enumeration test */ 243 static const size_t cchEnumResult0[] =243 static const uint32_t cchEnumResult0[] = 244 244 { 245 245 sizeof("test/name/\0test/value/\0""0\0"), … … 254 254 * the - 1 at the end is because of the hidden zero terminator 255 255 */ 256 static const size_t cchEnumBuffer0 =256 static const uint32_t cchEnumBuffer0 = 257 257 sizeof("test/name/\0test/value/\0""0\0\0" 258 258 "test name\0test value\0""999\0TRANSIENT, READONLY\0" … … 269 269 270 270 /** Result string sizes for first and second enumeration test */ 271 static const size_t cchEnumResult1[] =271 static const uint32_t cchEnumResult1[] = 272 272 { 273 273 sizeof("TEST NAME\0TEST VALUE\0""999999\0RDONLYHOST"), … … 280 280 * the - 1 at the end is because of the hidden zero terminator 281 281 */ 282 static const size_t cchEnumBuffer1 =282 static const uint32_t cchEnumBuffer1 = 283 283 sizeof("TEST NAME\0TEST VALUE\0""999999\0RDONLYHOST\0" 284 284 "/test/name\0/test/value\0""999999999999\0RDONLYGUEST\0\0\0\0\0") - 1; … … 289 289 const char *pcszPatterns; 290 290 /** The size of the pattern string */ 291 const size_t cchPatterns;291 const uint32_t cchPatterns; 292 292 /** The expected enumeration output strings */ 293 293 const char **ppcchResult; 294 294 /** The size of the output strings */ 295 const size_t *pcchResult;295 const uint32_t *pcchResult; 296 296 /** The size of the buffer needed for the enumeration */ 297 const size_t cchBuffer;297 const uint32_t cchBuffer; 298 298 } 299 299 enumStrings[] = … … 693 693 VBOXHGCMCALLHANDLE_TYPEDEF callHandle = { VINF_SUCCESS }; 694 694 char chBuffer[MAX_NAME_LEN + MAX_VALUE_LEN + MAX_FLAGS_LEN]; 695 static char szPattern[] = ""; 695 696 696 697 RTPrintf("Testing the GET_NOTIFICATION call.\n"); 697 uint64_t u64Timestamp = 0;698 uint64_t u64Timestamp; 698 699 uint32_t u32Size = 0; 699 VBOXHGCMSVCPARM paParms[ 3];700 VBOXHGCMSVCPARM paParms[4]; 700 701 701 702 /* Test "buffer too small" */ 702 paParms[0].setUInt64 (u64Timestamp); 703 paParms[1].setPointer ((void *) chBuffer, getNotifications[0].cchBuffer - 1); 703 u64Timestamp = 1; 704 paParms[0].setPointer ((void *) szPattern, sizeof(szPattern)); 705 paParms[1].setUInt64 (u64Timestamp); 706 paParms[2].setPointer ((void *) chBuffer, getNotifications[0].cchBuffer - 1); 704 707 pTable->pfnCall(pTable->pvService, &callHandle, 0, NULL, 705 GET_NOTIFICATION, 3, paParms);708 GET_NOTIFICATION, 4, paParms); 706 709 if ( callHandle.rc != VERR_BUFFER_OVERFLOW 707 || RT_FAILURE(paParms[ 2].getUInt32 (&u32Size))710 || RT_FAILURE(paParms[3].getUInt32 (&u32Size)) 708 711 || u32Size != getNotifications[0].cchBuffer 709 712 ) … … 714 717 } 715 718 716 /* Test successful notification queries */ 719 /* Test successful notification queries. Start with an unknown timestamp 720 * to get the oldest available notification. */ 721 u64Timestamp = 1; 717 722 for (unsigned i = 0; RT_SUCCESS(rc) && (getNotifications[i].pchBuffer != NULL); 718 723 ++i) 719 724 { 720 paParms[0].setUInt64 (u64Timestamp); 721 paParms[1].setPointer ((void *) chBuffer, sizeof(chBuffer)); 725 paParms[0].setPointer ((void *) szPattern, sizeof(szPattern)); 726 paParms[1].setUInt64 (u64Timestamp); 727 paParms[2].setPointer ((void *) chBuffer, sizeof(chBuffer)); 722 728 pTable->pfnCall(pTable->pvService, &callHandle, 0, NULL, 723 GET_NOTIFICATION, 3, paParms);729 GET_NOTIFICATION, 4, paParms); 724 730 if ( RT_FAILURE(callHandle.rc) 725 || RT_FAILURE(paParms[0].getUInt64 (&u64Timestamp)) 726 || RT_FAILURE(paParms[2].getUInt32 (&u32Size)) 731 || (i == 0 && callHandle.rc != VWRN_NOT_FOUND) 732 || RT_FAILURE(paParms[1].getUInt64 (&u64Timestamp)) 733 || RT_FAILURE(paParms[3].getUInt32 (&u32Size)) 727 734 || u32Size != getNotifications[i].cchBuffer 728 735 || memcmp(chBuffer, getNotifications[i].pchBuffer, u32Size) != 0 … … 734 741 } 735 742 } 736 737 /* Test a query with an unknown timestamp */738 paParms[0].setUInt64 (1);739 paParms[1].setPointer ((void *) chBuffer, sizeof(chBuffer));740 if (RT_SUCCESS(rc))741 pTable->pfnCall(pTable->pvService, &callHandle, 0, NULL,742 GET_NOTIFICATION, 3, paParms);743 if ( RT_SUCCESS(rc)744 && ( callHandle.rc != VWRN_NOT_FOUND745 || RT_FAILURE(callHandle.rc)746 || RT_FAILURE(paParms[0].getUInt64 (&u64Timestamp))747 || RT_FAILURE(paParms[2].getUInt32 (&u32Size))748 || u32Size != getNotifications[0].cchBuffer749 || memcmp(chBuffer, getNotifications[0].pchBuffer, u32Size) != 0750 )751 )752 {753 RTPrintf("Problem getting notification for property '%s' with unknown timestamp, rc=%Rrc.\n",754 getNotifications[0].pchBuffer, callHandle.rc);755 rc = VERR_UNRESOLVED_ERROR;756 }757 743 return rc; 758 744 } 759 745 760 /** 761 * Test the GET_NOTIFICATION function when no notifications are available. 746 /** Paramters for the asynchronous guest notification call */ 747 struct asyncNotification_ 748 { 749 /** Call parameters */ 750 VBOXHGCMSVCPARM aParms[4]; 751 /** Result buffer */ 752 char chBuffer[MAX_NAME_LEN + MAX_VALUE_LEN + MAX_FLAGS_LEN]; 753 /** Return value */ 754 VBOXHGCMCALLHANDLE_TYPEDEF callHandle; 755 } asyncNotification; 756 757 /** 758 * Set up the test for the asynchronous GET_NOTIFICATION function. 762 759 * @returns iprt status value to indicate whether the test went as expected. 763 760 * @note prints its own diagnostic information to stdout. 764 761 */ 765 int testNoNotifications(VBOXHGCMSVCFNTABLE *pTable, VBOXHGCMCALLHANDLE_TYPEDEF *callHandle, 766 VBOXHGCMSVCPARM *paParms, char *pchBuffer, size_t cchBuffer) 762 int setupAsyncNotification(VBOXHGCMSVCFNTABLE *pTable) 767 763 { 768 764 int rc = VINF_SUCCESS; … … 771 767 uint64_t u64Timestamp = 0; 772 768 uint32_t u32Size = 0; 773 774 paParms[0].setUInt64 (u64Timestamp); 775 paParms[1].setPointer ((void *) pchBuffer, cchBuffer); 776 callHandle->rc = VINF_HGCM_ASYNC_EXECUTE; 777 pTable->pfnCall(pTable->pvService, callHandle, 0, NULL, 778 GET_NOTIFICATION, 3, paParms); 779 if (callHandle->rc != VINF_HGCM_ASYNC_EXECUTE) 780 { 781 RTPrintf("GET_NOTIFICATION call completed when new notifications should be available.\n"); 769 static char szPattern[] = ""; 770 771 asyncNotification.aParms[0].setPointer ((void *) szPattern, sizeof(szPattern)); 772 asyncNotification.aParms[1].setUInt64 (u64Timestamp); 773 asyncNotification.aParms[2].setPointer ((void *) asyncNotification.chBuffer, 774 sizeof(asyncNotification.chBuffer)); 775 asyncNotification.callHandle.rc = VINF_HGCM_ASYNC_EXECUTE; 776 pTable->pfnCall(pTable->pvService, &asyncNotification.callHandle, 0, NULL, 777 GET_NOTIFICATION, 4, asyncNotification.aParms); 778 if (RT_FAILURE(asyncNotification.callHandle.rc)) 779 { 780 RTPrintf("GET_NOTIFICATION call failed, rc=%Rrc.\n", asyncNotification.callHandle.rc); 781 rc = VERR_UNRESOLVED_ERROR; 782 } 783 else if (asyncNotification.callHandle.rc != VINF_HGCM_ASYNC_EXECUTE) 784 { 785 RTPrintf("GET_NOTIFICATION call completed when no new notifications should be available.\n"); 786 rc = VERR_UNRESOLVED_ERROR; 787 } 788 return rc; 789 } 790 791 /** 792 * Test the asynchronous GET_NOTIFICATION function. 793 * @returns iprt status value to indicate whether the test went as expected. 794 * @note prints its own diagnostic information to stdout. 795 */ 796 int testAsyncNotification(VBOXHGCMSVCFNTABLE *pTable) 797 { 798 int rc = VINF_SUCCESS; 799 uint64_t u64Timestamp; 800 uint32_t u32Size; 801 if ( asyncNotification.callHandle.rc != VINF_SUCCESS 802 || RT_FAILURE(asyncNotification.aParms[1].getUInt64 (&u64Timestamp)) 803 || RT_FAILURE(asyncNotification.aParms[3].getUInt32 (&u32Size)) 804 || u32Size != getNotifications[0].cchBuffer 805 || memcmp(asyncNotification.chBuffer, getNotifications[0].pchBuffer, u32Size) != 0 806 ) 807 { 808 RTPrintf("Asynchronous GET_NOTIFICATION call did not complete as expected, rc=%Rrc\n", 809 asyncNotification.callHandle.rc); 782 810 rc = VERR_UNRESOLVED_ERROR; 783 811 } … … 789 817 VBOXHGCMSVCFNTABLE svcTable; 790 818 VBOXHGCMSVCHELPERS svcHelpers; 791 /* Paramters for the asynchronous guest notification call */792 VBOXHGCMSVCPARM aParm[3];793 char chBuffer[MAX_NAME_LEN + MAX_VALUE_LEN + MAX_FLAGS_LEN];794 VBOXHGCMCALLHANDLE_TYPEDEF callHandleStruct;795 819 796 820 initTable(&svcTable, &svcHelpers); … … 808 832 if (RT_FAILURE(testEnumPropsHost(&svcTable))) 809 833 return 1; 810 /* Asynchronous notification call */ 811 if (RT_FAILURE(testNoNotifications(&svcTable, &callHandleStruct, aParm, 812 chBuffer, sizeof(chBuffer)))) 834 /* Set up the asynchronous notification test */ 835 if (RT_FAILURE(setupAsyncNotification(&svcTable))) 813 836 return 1; 814 837 if (RT_FAILURE(testSetProp(&svcTable))) … … 816 839 RTPrintf("Checking the data returned by the asynchronous notification call.\n"); 817 840 /* Our previous notification call should have completed by now. */ 818 uint64_t u64Timestamp; 819 uint32_t u32Size; 820 if ( callHandleStruct.rc != VINF_SUCCESS 821 || RT_FAILURE(aParm[0].getUInt64 (&u64Timestamp)) 822 || RT_FAILURE(aParm[2].getUInt32 (&u32Size)) 823 || u32Size != getNotifications[0].cchBuffer 824 || memcmp(chBuffer, getNotifications[0].pchBuffer, u32Size) != 0 825 ) 826 { 827 RTPrintf("Asynchronous GET_NOTIFICATION call did not complete as expected, rc=%Rrc\n", 828 callHandleStruct.rc); 829 return 1; 830 } 841 if (RT_FAILURE(testAsyncNotification(&svcTable))) 842 return 1; 831 843 if (RT_FAILURE(testDelProp(&svcTable))) 832 844 return 1;
Note:
See TracChangeset
for help on using the changeset viewer.