Changeset 50523 in vbox
- Timestamp:
- Feb 20, 2014 12:00:58 PM (11 years ago)
- Location:
- trunk/src/VBox/Additions/common
- Files:
-
- 3 edited
-
VBoxGuest/VBoxGuest.cpp (modified) (19 diffs)
-
VBoxGuest/VBoxGuestInternal.h (modified) (4 diffs)
-
VBoxGuestLib/VBoxGuestR3LibMisc.cpp (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp
r50391 r50523 66 66 static DECLCALLBACK(int) VBoxGuestHGCMAsyncWaitCallback(VMMDevHGCMRequestHeader *pHdrNonVolatile, void *pvUser, uint32_t u32User); 67 67 #endif 68 #ifdef DEBUG69 static void testSetMouseStatus(void);70 #endif71 static int VBoxGuestCommonIOCtl_SetMouseStatus(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, uint32_t fFeatures);72 68 73 69 static int VBoxGuestCommonGuestCapsAcquire(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, uint32_t fOrMask, uint32_t fNotMask, VBOXGUESTCAPSACQUIRE_FLAGS enmFlags); … … 126 122 *pu32OtherVal = fNotVal; 127 123 return fResult; 124 } 125 126 127 /** 128 * Sets the interrupt filter mask during initialization and termination. 129 * 130 * This will ASSUME that we're the ones in carge over the mask, so 131 * we'll simply clear all bits we don't set. 132 * 133 * @returns VBox status code (ignored). 134 * @param fMask The new mask. 135 */ 136 static int vboxGuestSetFilterMask(uint32_t fMask) 137 { 138 VMMDevCtlGuestFilterMask *pReq; 139 int rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(*pReq), VMMDevReq_CtlGuestFilterMask); 140 if (RT_SUCCESS(rc)) 141 { 142 pReq->u32OrMask = fMask; 143 pReq->u32NotMask = ~fMask; 144 rc = VbglGRPerform(&pReq->header); 145 if (RT_FAILURE(rc)) 146 LogRel(("vboxGuestSetFilterMask: failed with rc=%Rrc\n", rc)); 147 VbglGRFree(&pReq->header); 148 } 149 return rc; 150 } 151 152 153 /** 154 * Sets the guest capabilities to the host. 155 * 156 * This will ASSUME that we're the ones in charge of the mask, so 157 * we'll simply clear all bits we don't set. 158 * 159 * @returns VBox status code. 160 * @param fMask The new mask. 161 */ 162 static int vboxGuestSetCapabilities(uint32_t fMask) 163 { 164 VMMDevReqGuestCapabilities2 *pReq; 165 int rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(*pReq), 166 VMMDevReq_SetGuestCapabilities); 167 if (RT_SUCCESS(rc)) 168 { 169 pReq->u32OrMask = fMask; 170 pReq->u32NotMask = ~fMask; 171 rc = VbglGRPerform(&pReq->header); 172 if (RT_FAILURE(rc)) 173 LogRelFunc(("failed with rc=%Rrc\n", rc)); 174 VbglGRFree(&pReq->header); 175 } 176 return rc; 177 } 178 179 180 /** 181 * Sets the mouse status to the host. 182 * 183 * This will ASSUME that we're the ones in charge of the mask, so 184 * we'll simply clear all bits we don't set. 185 * 186 * @returns VBox status code. 187 * @param fMask The new mask. 188 */ 189 static int vboxGuestSetMouseStatus(uint32_t fMask) 190 { 191 VMMDevReqMouseStatus *pReq; 192 int rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(*pReq), 193 VMMDevReq_SetMouseStatus); 194 if (RT_SUCCESS(rc)) 195 { 196 pReq->mouseFeatures = fMask; 197 pReq->pointerXPos = 0; 198 pReq->pointerYPos = 0; 199 rc = VbglGRPerform(&pReq->header); 200 if (RT_FAILURE(rc)) 201 LogRelFunc(("failed with rc=%Rrc\n", rc)); 202 VbglGRFree(&pReq->header); 203 } 204 return rc; 205 } 206 207 208 /** Host flags to be updated by a given invokation of the 209 * vboxGuestUpdateHostFlags() method. */ 210 enum 211 { 212 HostFlags_FilterMask = 1, 213 HostFlags_Capabilities, 214 HostFlags_MouseStatus, 215 HostFlags_SizeHack = (unsigned)-1 216 }; 217 218 219 /** Check which host flags in a given category are being asserted by some guest 220 * session and assert exactly those on the host which are being asserted by one 221 * or more sessions. pCallingSession is purely for sanity checking and can be 222 * NULL. */ 223 static int vboxGuestUpdateHostFlags(PVBOXGUESTDEVEXT pDevExt, 224 PVBOXGUESTSESSION pSession, 225 unsigned enmFlags) 226 { 227 int rc = VINF_SUCCESS; 228 uint32_t fFilterMask = 0, fCapabilities = 0, fMouseStatus = 0; 229 PVBOXGUESTSESSION pIterator; 230 unsigned cSessions = 0; 231 232 RTSpinlockAcquire(pDevExt->SessionSpinlock); 233 RTListForEach(&pDevExt->SessionList, pIterator, VBOXGUESTSESSION, ListNode) 234 { 235 fFilterMask |= pIterator->fFilterMask; 236 fCapabilities |= pIterator->fCapabilities; 237 fMouseStatus |= pIterator->fMouseStatus; 238 ++cSessions; 239 } 240 if (!cSessions) 241 if (fFilterMask | fCapabilities | fMouseStatus) 242 rc = VERR_INTERNAL_ERROR; 243 if (cSessions == 1 && pSession) 244 if ( fFilterMask != pSession->fFilterMask 245 || fCapabilities != pSession->fCapabilities 246 || fMouseStatus != pSession->fMouseStatus) 247 rc = VERR_INTERNAL_ERROR; 248 if (cSessions > 1 && pSession) 249 if ( ~fFilterMask & pSession->fFilterMask 250 || ~fCapabilities & pSession->fCapabilities 251 || ~fMouseStatus & pSession->fMouseStatus) 252 rc = VERR_INTERNAL_ERROR; 253 if (RT_SUCCESS(rc)) 254 { 255 if (enmFlags & HostFlags_FilterMask) 256 vboxGuestSetFilterMask(fFilterMask | pDevExt->fFixedEvents); 257 if (enmFlags & HostFlags_Capabilities) 258 vboxGuestSetCapabilities(fCapabilities); 259 /* Since VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR is inverted in the session 260 * capabilities we invert it again before sending it to the host. */ 261 fMouseStatus ^= VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR; 262 if (enmFlags & HostFlags_MouseStatus) 263 vboxGuestSetMouseStatus(fMouseStatus); 264 } 265 RTSpinlockReleaseNoInts(pDevExt->SessionSpinlock); 266 return rc; 128 267 } 129 268 … … 332 471 333 472 /** 334 * Sets the interrupt filter mask during initialization and termination.335 *336 * This will ASSUME that we're the ones in carge over the mask, so337 * we'll simply clear all bits we don't set.338 *339 * @returns VBox status code (ignored).340 * @param pDevExt The device extension.341 * @param fMask The new mask.342 */343 static int vboxGuestSetFilterMask(PVBOXGUESTDEVEXT pDevExt, uint32_t fMask)344 {345 VMMDevCtlGuestFilterMask *pReq;346 int rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(*pReq), VMMDevReq_CtlGuestFilterMask);347 if (RT_SUCCESS(rc))348 {349 pReq->u32OrMask = fMask;350 pReq->u32NotMask = ~fMask;351 rc = VbglGRPerform(&pReq->header);352 if (RT_FAILURE(rc))353 LogRel(("vboxGuestSetFilterMask: failed with rc=%Rrc\n", rc));354 VbglGRFree(&pReq->header);355 }356 return rc;357 }358 359 360 /**361 473 * Inflate the balloon by one chunk represented by an R0 memory object. 362 474 * … … 799 911 RTListInit(&pDevExt->WokenUpList); 800 912 RTListInit(&pDevExt->FreeList); 913 RTListInit(&pDevExt->SessionList); 801 914 #ifdef VBOX_WITH_VRDP_SESSION_HANDLING 802 915 pDevExt->fVRDPEnabled = false; … … 812 925 pDevExt->MemBalloon.paMemObj = NULL; 813 926 pDevExt->MemBalloon.pOwner = NULL; 814 for (i = 0; i < RT_ELEMENTS(pDevExt->acMouseFeatureUsage); ++i)815 pDevExt->acMouseFeatureUsage[i] = 0;816 pDevExt->fMouseStatus = 0;817 927 pDevExt->MouseNotifyCallback.pfnNotify = NULL; 818 928 pDevExt->MouseNotifyCallback.pvUser = NULL; … … 883 993 if (RT_SUCCESS(rc)) 884 994 { 885 rc = vboxGuestSetFilterMask( pDevExt,fFixedEvents);995 rc = vboxGuestSetFilterMask(fFixedEvents); 886 996 if (RT_SUCCESS(rc)) 887 997 { … … 890 1000 * graphics driver will re-enable this when it is necessary. 891 1001 */ 892 rc = VBoxGuestSetGuestCapabilities(0, VMMDEV_GUEST_SUPPORTS_GRAPHICS);1002 rc = vboxGuestSetCapabilities(0); 893 1003 if (RT_SUCCESS(rc)) 894 1004 { 895 1005 vboxGuestInitFixateGuestMappings(pDevExt); 896 1006 897 #ifdef DEBUG898 testSetMouseStatus(); /* Other tests? */899 #endif900 901 1007 rc = VBoxGuestReportDriverStatus(true /* Driver is active */); 902 1008 if (RT_FAILURE(rc)) … … 907 1013 } 908 1014 909 LogRel(("VBoxGuestInitDevExt: VBoxGuestSetGuestCapabilities failed, rc=%Rrc\n", rc));1015 LogRel(("VBoxGuestInitDevExt: vboxGuestSetCapabilities failed, rc=%Rrc\n", rc)); 910 1016 } 911 1017 else … … 974 1080 */ 975 1081 vboxGuestTermUnfixGuestMappings(pDevExt); 976 VBoxGuestSetGuestCapabilities(0, UINT32_MAX); /* clears all capabilities */ 977 vboxGuestSetFilterMask(pDevExt, 0); /* filter all events */ 1082 vboxGuestSetCapabilities(0); /* clear all Capabilities */ 1083 vboxGuestSetFilterMask(0); /* filter all events */ 1084 vboxGuestSetMouseStatus(0); /* clear all mouse features */ 978 1085 vboxGuestCloseMemBalloon(pDevExt, (PVBOXGUESTSESSION)NULL); 979 1086 … … 994 1101 VBoxGuestDeleteWaitList(&pDevExt->WokenUpList); 995 1102 VBoxGuestDeleteWaitList(&pDevExt->FreeList); 1103 /** @todo We do not assert that the session list is empty, because probably 1104 * no one would notice. */ 996 1105 997 1106 VbglTerminate(); … … 1032 1141 pSession->R0Process = RTR0ProcHandleSelf(); 1033 1142 pSession->pDevExt = pDevExt; 1143 RTSpinlockAcquire(pDevExt->SessionSpinlock); 1144 RTListAppend(&pDevExt->SessionList, &pSession->ListNode); 1145 RTSpinlockReleaseNoInts(pDevExt->SessionSpinlock); 1034 1146 1035 1147 *ppSession = pSession; … … 1062 1174 pSession->R0Process = NIL_RTR0PROCESS; 1063 1175 pSession->pDevExt = pDevExt; 1176 RTSpinlockAcquire(pDevExt->SessionSpinlock); 1177 RTListAppend(&pDevExt->SessionList, &pSession->ListNode); 1178 RTSpinlockReleaseNoInts(pDevExt->SessionSpinlock); 1064 1179 1065 1180 *ppSession = pSession; … … 1083 1198 pSession, pSession->Process, (int)pSession->Process, (uintptr_t)pSession->R0Process)); /** @todo %RTr0proc */ 1084 1199 1200 RTSpinlockAcquire(pDevExt->SessionSpinlock); 1201 RTListNodeRemove(&pSession->ListNode); 1202 RTSpinlockReleaseNoInts(pDevExt->SessionSpinlock); 1085 1203 VBoxGuestCommonGuestCapsAcquire(pDevExt, pSession, 0, UINT32_MAX, VBOXGUESTCAPSACQUIRE_FLAGS_NONE); 1086 1204 … … 1104 1222 pSession->R0Process = NIL_RTR0PROCESS; 1105 1223 vboxGuestCloseMemBalloon(pDevExt, pSession); 1106 /* Reset any mouse status flags which the session may have set. */ 1107 VBoxGuestCommonIOCtl_SetMouseStatus(pDevExt, pSession, 0); 1224 /* Update the host flags (mouse status etc) not to reflect this session. */ 1225 vboxGuestUpdateHostFlags(pDevExt, NULL, 1226 HostFlags_FilterMask | HostFlags_Capabilities | HostFlags_MouseStatus); 1108 1227 RTMemFree(pSession); 1109 1228 } … … 1826 1945 1827 1946 1828 static int VBoxGuestCommonIOCtl_CtlFilterMask(PVBOXGUESTDEVEXT pDevExt, VBoxGuestFilterMaskInfo *pInfo) 1829 { 1830 VMMDevCtlGuestFilterMask *pReq; 1831 int rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(*pReq), VMMDevReq_CtlGuestFilterMask); 1832 if (RT_FAILURE(rc)) 1833 { 1834 Log(("VBoxGuestCommonIOCtl: CTL_FILTER_MASK: failed to allocate %u (%#x) bytes to cache the request. rc=%Rrc!!\n", 1835 sizeof(*pReq), sizeof(*pReq), rc)); 1836 return rc; 1837 } 1838 1839 pReq->u32OrMask = pInfo->u32OrMask; 1840 pReq->u32NotMask = pInfo->u32NotMask; 1841 pReq->u32NotMask &= ~pDevExt->fFixedEvents; /* don't permit these to be cleared! */ 1842 rc = VbglGRPerform(&pReq->header); 1843 if (RT_FAILURE(rc)) 1844 Log(("VBoxGuestCommonIOCtl: CTL_FILTER_MASK: VbglGRPerform failed, rc=%Rrc!\n", rc)); 1845 1846 VbglGRFree(&pReq->header); 1947 static int VBoxGuestCommonIOCtl_CtlFilterMask(PVBOXGUESTDEVEXT pDevExt, 1948 PVBOXGUESTSESSION pSession, 1949 VBoxGuestFilterMaskInfo *pInfo) 1950 { 1951 int rc; 1952 1953 if ((pInfo->u32OrMask | pInfo->u32NotMask) & ~VMMDEV_EVENT_VALID_EVENT_MASK) 1954 return VERR_INVALID_PARAMETER; 1955 RTSpinlockAcquire(pDevExt->SessionSpinlock); 1956 pSession->fFilterMask |= pInfo->u32OrMask; 1957 pSession->fFilterMask &= ~pInfo->u32NotMask; 1958 rc = vboxGuestUpdateHostFlags(pDevExt, pSession, HostFlags_FilterMask); 1959 RTSpinlockReleaseNoInts(pDevExt->SessionSpinlock); 1960 return rc; 1961 } 1962 1963 1964 static int VBoxGuestCommonIOCtl_SetCapabilities(PVBOXGUESTDEVEXT pDevExt, 1965 PVBOXGUESTSESSION pSession, 1966 VBoxGuestSetCapabilitiesInfo *pInfo) 1967 { 1968 int rc; 1969 1970 if ( (pInfo->u32OrMask | pInfo->u32NotMask) 1971 & ~VMMDEV_GUEST_CAPABILITIES_MASK) 1972 return VERR_INVALID_PARAMETER; 1973 RTSpinlockAcquire(pDevExt->SessionSpinlock); 1974 pSession->fCapabilities |= pInfo->u32OrMask; 1975 pSession->fCapabilities &= ~pInfo->u32NotMask; 1976 rc = vboxGuestUpdateHostFlags(pDevExt, pSession, HostFlags_Capabilities); 1977 RTSpinlockReleaseNoInts(pDevExt->SessionSpinlock); 1978 return rc; 1979 } 1980 1981 1982 /** 1983 * Sets the mouse status features for this session and updates them 1984 * globally. 1985 * 1986 * @returns VBox status code. 1987 * 1988 * @param pDevExt The device extention. 1989 * @param pSession The session. 1990 * @param fFeatures New bitmap of enabled features. 1991 */ 1992 static int vboxGuestCommonIOCtl_SetMouseStatus(PVBOXGUESTDEVEXT pDevExt, 1993 PVBOXGUESTSESSION pSession, 1994 uint32_t fFeatures) 1995 { 1996 int rc; 1997 1998 if (fFeatures & ~VMMDEV_MOUSE_GUEST_MASK) 1999 return VERR_INVALID_PARAMETER; 2000 /* Since this is more of a negative feature we invert it to get the real 2001 * feature (when the guest does not need the host cursor). */ 2002 fFeatures ^= VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR; 2003 RTSpinlockAcquire(pDevExt->SessionSpinlock); 2004 pSession->fMouseStatus = fFeatures; 2005 rc = vboxGuestUpdateHostFlags(pDevExt, pSession, HostFlags_MouseStatus); 2006 RTSpinlockReleaseNoInts(pDevExt->SessionSpinlock); 1847 2007 return rc; 1848 2008 } … … 2339 2499 } 2340 2500 #endif /* VBOX_WITH_VRDP_SESSION_HANDLING */ 2341 2342 #ifdef DEBUG2343 /** Unit test SetMouseStatus instead of really executing the request. */2344 static bool g_test_fSetMouseStatus = false;2345 /** When unit testing SetMouseStatus, the fake RC for the GR to return. */2346 static int g_test_SetMouseStatusGRRC;2347 /** When unit testing SetMouseStatus this will be set to the status passed to2348 * the GR. */2349 static uint32_t g_test_statusSetMouseStatus;2350 #endif2351 2352 static int vboxguestcommonSetMouseStatus(uint32_t fFeatures)2353 {2354 VMMDevReqMouseStatus *pReq;2355 int rc;2356 2357 LogRelFlowFunc(("fFeatures=%u\n", (int) fFeatures));2358 rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(*pReq), VMMDevReq_SetMouseStatus);2359 if (RT_SUCCESS(rc))2360 {2361 pReq->mouseFeatures = fFeatures;2362 pReq->pointerXPos = 0;2363 pReq->pointerYPos = 0;2364 #ifdef DEBUG2365 if (g_test_fSetMouseStatus)2366 {2367 g_test_statusSetMouseStatus = pReq->mouseFeatures;2368 rc = g_test_SetMouseStatusGRRC;2369 }2370 else2371 #endif2372 rc = VbglGRPerform(&pReq->header);2373 VbglGRFree(&pReq->header);2374 }2375 LogRelFlowFunc(("rc=%Rrc\n", rc));2376 return rc;2377 }2378 2379 2380 /**2381 * Sets the mouse status features for this session and updates them2382 * globally. We aim to ensure that if several threads call this in2383 * parallel the most recent status will always end up being set.2384 *2385 * @returns VBox status code.2386 *2387 * @param pDevExt The device extention.2388 * @param pSession The session.2389 * @param fFeatures New bitmap of enabled features.2390 */2391 static int VBoxGuestCommonIOCtl_SetMouseStatus(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, uint32_t fFeatures)2392 {2393 uint32_t fNewDevExtStatus = 0;2394 unsigned i;2395 int rc;2396 /* Exit early if nothing has changed - hack to work around the2397 * Windows Additions not using the common code. */2398 bool fNoAction;2399 2400 RTSpinlockAcquire(pDevExt->SessionSpinlock);2401 2402 /* For all the bits which the guest is allowed to set, check whether the2403 * requested value is different to the current one and adjust the global2404 * usage counter and if appropriate the global state if so. */2405 for (i = 0; i < sizeof(fFeatures) * 8; i++)2406 {2407 if (RT_BIT_32(i) & VMMDEV_MOUSE_GUEST_MASK)2408 {2409 if ( (RT_BIT_32(i) & fFeatures)2410 && !(RT_BIT_32(i) & pSession->fMouseStatus))2411 pDevExt->acMouseFeatureUsage[i]++;2412 else if ( !(RT_BIT_32(i) & fFeatures)2413 && (RT_BIT_32(i) & pSession->fMouseStatus))2414 pDevExt->acMouseFeatureUsage[i]--;2415 }2416 if (pDevExt->acMouseFeatureUsage[i] > 0)2417 fNewDevExtStatus |= RT_BIT_32(i);2418 }2419 2420 pSession->fMouseStatus = fFeatures & VMMDEV_MOUSE_GUEST_MASK;2421 fNoAction = (pDevExt->fMouseStatus == fNewDevExtStatus);2422 pDevExt->fMouseStatus = fNewDevExtStatus;2423 2424 RTSpinlockReleaseNoInts(pDevExt->SessionSpinlock);2425 if (fNoAction)2426 return VINF_SUCCESS;2427 2428 do2429 {2430 fNewDevExtStatus = pDevExt->fMouseStatus;2431 rc = vboxguestcommonSetMouseStatus(fNewDevExtStatus);2432 } while ( RT_SUCCESS(rc)2433 && fNewDevExtStatus != pDevExt->fMouseStatus);2434 2435 return rc;2436 }2437 2438 2439 #ifdef DEBUG2440 /** Unit test for the SET_MOUSE_STATUS IoCtl. Since this is closely tied to2441 * the code in question it probably makes most sense to keep it next to the2442 * code. */2443 static void testSetMouseStatus(void)2444 {2445 uint32_t u32Data;2446 int rc;2447 RTSPINLOCK Spinlock;2448 2449 g_test_fSetMouseStatus = true;2450 rc = RTSpinlockCreate(&Spinlock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "VBoxGuestTest");2451 AssertRCReturnVoid(rc);2452 {2453 VBOXGUESTDEVEXT DevExt = { 0 };2454 VBOXGUESTSESSION Session = { 0 };2455 2456 g_test_statusSetMouseStatus = ~0;2457 g_test_SetMouseStatusGRRC = VINF_SUCCESS;2458 DevExt.SessionSpinlock = Spinlock;2459 u32Data = VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE;2460 rc = VBoxGuestCommonIOCtl(VBOXGUEST_IOCTL_SET_MOUSE_STATUS, &DevExt,2461 &Session, &u32Data, sizeof(u32Data), NULL);2462 AssertRCSuccess(rc);2463 AssertMsg( g_test_statusSetMouseStatus2464 == VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE,2465 ("Actual status: 0x%x\n", g_test_statusSetMouseStatus));2466 DevExt.acMouseFeatureUsage[ASMBitFirstSetU32(VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR) - 1] = 1;2467 rc = VBoxGuestCommonIOCtl(VBOXGUEST_IOCTL_SET_MOUSE_STATUS, &DevExt,2468 &Session, &u32Data, sizeof(u32Data), NULL);2469 AssertRCSuccess(rc);2470 AssertMsg( g_test_statusSetMouseStatus2471 == ( VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE2472 | VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR),2473 ("Actual status: 0x%x\n", g_test_statusSetMouseStatus));2474 u32Data = VMMDEV_MOUSE_HOST_WANTS_ABSOLUTE; /* Can't change this */2475 rc = VBoxGuestCommonIOCtl(VBOXGUEST_IOCTL_SET_MOUSE_STATUS, &DevExt,2476 &Session, &u32Data, sizeof(u32Data), NULL);2477 AssertRCSuccess(rc);2478 AssertMsg( g_test_statusSetMouseStatus2479 == VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR,2480 ("Actual status: 0x%x\n", g_test_statusSetMouseStatus));2481 u32Data = VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR;2482 rc = VBoxGuestCommonIOCtl(VBOXGUEST_IOCTL_SET_MOUSE_STATUS, &DevExt,2483 &Session, &u32Data, sizeof(u32Data), NULL);2484 AssertRCSuccess(rc);2485 AssertMsg( g_test_statusSetMouseStatus2486 == VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR,2487 ("Actual status: 0x%x\n", g_test_statusSetMouseStatus));2488 u32Data = 0;2489 rc = VBoxGuestCommonIOCtl(VBOXGUEST_IOCTL_SET_MOUSE_STATUS, &DevExt,2490 &Session, &u32Data, sizeof(u32Data), NULL);2491 AssertRCSuccess(rc);2492 AssertMsg( g_test_statusSetMouseStatus2493 == VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR,2494 ("Actual status: 0x%x\n", g_test_statusSetMouseStatus));2495 AssertMsg(DevExt.acMouseFeatureUsage[ASMBitFirstSetU32(VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR) - 1] == 1,2496 ("Actual value: %d\n", DevExt.acMouseFeatureUsage[ASMBitFirstSetU32(VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR)]));2497 g_test_SetMouseStatusGRRC = VERR_UNRESOLVED_ERROR;2498 /* This should succeed as the host request should not be made2499 * since nothing has changed. */2500 rc = VBoxGuestCommonIOCtl(VBOXGUEST_IOCTL_SET_MOUSE_STATUS, &DevExt,2501 &Session, &u32Data, sizeof(u32Data), NULL);2502 AssertRCSuccess(rc);2503 /* This should fail with VERR_UNRESOLVED_ERROR as set above. */2504 u32Data = VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE;2505 rc = VBoxGuestCommonIOCtl(VBOXGUEST_IOCTL_SET_MOUSE_STATUS, &DevExt,2506 &Session, &u32Data, sizeof(u32Data), NULL);2507 AssertMsg(rc == VERR_UNRESOLVED_ERROR, ("rc == %Rrc\n", rc));2508 /* Untested paths: out of memory; race setting status to host */2509 }2510 RTSpinlockDestroy(Spinlock);2511 g_test_fSetMouseStatus = false;2512 }2513 #endif2514 2501 2515 2502 … … 2882 2869 2883 2870 case VBOXGUEST_IOCTL_CTL_FILTER_MASK: 2884 CHECKRET_MIN_SIZE("CTL_FILTER_MASK", sizeof(VBoxGuestFilterMaskInfo)); 2885 rc = VBoxGuestCommonIOCtl_CtlFilterMask(pDevExt, (VBoxGuestFilterMaskInfo *)pvData); 2871 CHECKRET_MIN_SIZE("CTL_FILTER_MASK", 2872 sizeof(VBoxGuestFilterMaskInfo)); 2873 rc = VBoxGuestCommonIOCtl_CtlFilterMask(pDevExt, pSession, 2874 (VBoxGuestFilterMaskInfo *)pvData); 2886 2875 break; 2887 2876 … … 2930 2919 case VBOXGUEST_IOCTL_SET_MOUSE_STATUS: 2931 2920 CHECKRET_SIZE("SET_MOUSE_STATUS", sizeof(uint32_t)); 2932 rc = VBoxGuestCommonIOCtl_SetMouseStatus(pDevExt, pSession,2921 rc = vboxGuestCommonIOCtl_SetMouseStatus(pDevExt, pSession, 2933 2922 *(uint32_t *)pvData); 2934 2923 break; … … 2945 2934 rc = VBoxGuestCommonIOCTL_GuestCapsAcquire(pDevExt, pSession, (VBoxGuestCapsAquire*)pvData); 2946 2935 *pcbDataReturned = sizeof(VBoxGuestCapsAquire); 2936 break; 2937 2938 case VBOXGUEST_IOCTL_SET_GUEST_CAPABILITIES: 2939 CHECKRET_MIN_SIZE("SET_GUEST_CAPABILITIES", 2940 sizeof(VBoxGuestSetCapabilitiesInfo)); 2941 rc = VBoxGuestCommonIOCtl_SetCapabilities(pDevExt, pSession, 2942 (VBoxGuestSetCapabilitiesInfo *)pvData); 2947 2943 break; 2948 2944 -
trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuestInternal.h
r50391 r50523 158 158 /** Spinlock various items in the VBOXGUESTSESSION. */ 159 159 RTSPINLOCK SessionSpinlock; 160 /** List of guest sessions (VBOXGUESTSESSION). We currently traverse this 161 * but do not search it, so a list data type should be fine. Use under the 162 * #SessionSpinlock lock. */ 163 RTLISTANCHOR SessionList; 160 164 #ifdef VBOX_WITH_VRDP_SESSION_HANDLING 161 165 bool fVRDPEnabled; … … 166 170 /** Memory balloon information for RTR0MemObjAllocPhysNC(). */ 167 171 VBOXGUESTMEMBALLOON MemBalloon; 168 /** For each mouse status feature the number of sessions which have169 * enabled it. A feature is enabled globally if at least one session has170 * requested it. */171 /** @todo can we programmatically determine the size of the array and172 * still get the following alignment right? */173 uint32_t volatile acMouseFeatureUsage[32];174 /** The mouse feature status matching the counts above. These are updated175 * together inside the session spinlock. */176 uint32_t volatile fMouseStatus;177 172 /** Counter of number of active ISRs. Currently used for safely removing 178 173 * the mouse handler callback. */ … … 204 199 typedef struct VBOXGUESTSESSION 205 200 { 201 /** The list node. */ 202 RTLISTNODE ListNode; 206 203 #if defined(RT_OS_DARWIN) || defined(RT_OS_FREEBSD) || defined(RT_OS_OS2) || defined(RT_OS_SOLARIS) 207 204 /** Pointer to the next session with the same hash. */ … … 230 227 * Used to implement polling. */ 231 228 uint32_t volatile u32MousePosChangedSeq; 229 /** VMMDev events requested. An event type requested in any guest session 230 * will be added to the host filter. 231 * Use under the VBOXGUESTDEVEXT#SessionSpinlock lock. */ 232 uint32_t fFilterMask; 233 /** Capabilities supported. A capability enabled in any guest session will 234 * be enabled for the host. 235 * Use under the VBOXGUESTDEVEXT#SessionSpinlock lock. */ 236 uint32_t fCapabilities; 232 237 /** Mouse features supported. A feature enabled in any guest session will 233 * be enabled for the host. */ 234 uint32_t volatile fMouseStatus; 238 * be enabled for the host. 239 * @note We invert the VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR feature in this 240 * bitmap. The logic of this is that the real feature is when the host 241 * cursor is not needed, and we tell the host it is not needed if any 242 * session explicitly fails to assert it. Storing it inverted simplifies 243 * the checks. 244 * Use under the VBOXGUESTDEVEXT#SessionSpinlock lock. */ 245 uint32_t fMouseStatus; 235 246 #ifdef RT_OS_DARWIN 236 247 /** Pointer to the associated org_virtualbox_VBoxGuestClient object. */ -
trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibMisc.cpp
r48938 r50523 60 60 VBGLR3DECL(int) VbglR3SetGuestCaps(uint32_t fOr, uint32_t fNot) 61 61 { 62 VMMDevReqGuestCapabilities2 Req; 63 64 vmmdevInitRequest(&Req.header, VMMDevReq_SetGuestCapabilities); 65 Req.u32OrMask = fOr; 66 Req.u32NotMask = fNot; 67 int rc = vbglR3GRPerform(&Req.header); 68 #if defined(DEBUG) 69 if (RT_SUCCESS(rc)) 70 LogRel(("Successfully changed guest capabilities: or mask 0x%x, not mask 0x%x.\n", fOr, fNot)); 71 else 72 LogRel(("Failed to change guest capabilities: or mask 0x%x, not mask 0x%x. rc=%Rrc.\n", fOr, fNot, rc)); 73 #endif 74 return rc; 62 VBoxGuestSetCapabilitiesInfo Info; 63 Info.u32OrMask = fOr; 64 Info.u32NotMask = fNot; 65 return vbglR3DoIOCtl(VBOXGUEST_IOCTL_SET_GUEST_CAPABILITIES, &Info, 66 sizeof(Info)); 75 67 } 76 68
Note:
See TracChangeset
for help on using the changeset viewer.

