Changeset 75853 in vbox for trunk/src/VBox
- Timestamp:
- Nov 30, 2018 7:26:42 PM (6 years ago)
- Location:
- trunk/src/VBox
- Files:
-
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR3LibGuestCtrl.cpp
r75824 r75853 307 307 308 308 309 310 309 /** 311 310 * Peeks at the next host message, waiting for one to turn up. … … 314 313 * @retval VERR_INTERRUPTED if interrupted. Does the necessary cleanup, so 315 314 * caller just have to repeat this call. 315 * @retval VERR_VM_RESTORED if the VM has been restored (idRestoreCheck). 316 316 * 317 317 * @param idClient The client ID returned by VbglR3GuestCtrlConnect(). … … 319 319 * @param pcParameters Where to store the number of parameters which will 320 320 * be received in a second call to the host. 321 */ 322 VBGLR3DECL(int) VbglR3GuestCtrlMsgPeekWait(uint32_t idClient, uint32_t *pidMsg, uint32_t *pcParameters) 321 * @param pidRestoreCheck Pointer to the VbglR3GetSessionId() variable to use 322 * for the VM restore check. Optional. 323 * 324 * @note Restore check is only performed optimally with a 6.0 host. 325 */ 326 VBGLR3DECL(int) VbglR3GuestCtrlMsgPeekWait(uint32_t idClient, uint32_t *pidMsg, uint32_t *pcParameters, uint64_t *pidRestoreCheck) 323 327 { 324 328 AssertPtrReturn(pidMsg, VERR_INVALID_POINTER); … … 328 332 if (vbglR3GuestCtrlSupportsPeekGetCancel(idClient)) 329 333 { 330 HGCMMsgCmdWaitFor Msg; 331 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient, GUEST_MSG_PEEK_WAIT, 2); 332 VbglHGCMParmUInt32Set(&Msg.msg, 0); 333 VbglHGCMParmUInt32Set(&Msg.num_parms, 0); 334 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg)); 334 struct 335 { 336 VBGLIOCHGCMCALL Hdr; 337 HGCMFunctionParameter idMsg; /* Doubles as restore check on input. */ 338 HGCMFunctionParameter cParameters; 339 } Msg; 340 VBGL_HGCM_HDR_INIT(&Msg.Hdr, idClient, GUEST_MSG_PEEK_WAIT, 2); 341 VbglHGCMParmUInt64Set(&Msg.idMsg, pidRestoreCheck ? *pidRestoreCheck : 0); 342 VbglHGCMParmUInt32Set(&Msg.cParameters, 0); 343 rc = VbglR3HGCMCall(&Msg.Hdr, sizeof(Msg)); 335 344 LogRel(("VbglR3GuestCtrlMsgPeekWait -> %Rrc\n", rc)); 336 345 if (RT_SUCCESS(rc)) 337 346 { 338 AssertMsgReturn( Msg. msg.type == VMMDevHGCMParmType_32bit339 && Msg. num_parms.type == VMMDevHGCMParmType_32bit,340 ("msg.type=%d num_parms.type=%d\n", Msg. msg.type, Msg.num_parms.type),347 AssertMsgReturn( Msg.idMsg.type == VMMDevHGCMParmType_64bit 348 && Msg.cParameters.type == VMMDevHGCMParmType_32bit, 349 ("msg.type=%d num_parms.type=%d\n", Msg.idMsg.type, Msg.cParameters.type), 341 350 VERR_INTERNAL_ERROR_3); 342 351 343 *pidMsg = Msg.msg.u.value32;344 *pcParameters = Msg. num_parms.u.value32;352 *pidMsg = (uint32_t)Msg.idMsg.u.value64; 353 *pcParameters = Msg.cParameters.u.value32; 345 354 return rc; 346 355 } … … 351 360 if (rc == VERR_INTERRUPTED) 352 361 { 353 VBGL_HGCM_HDR_INIT(&Msg. hdr, idClient, GUEST_MSG_CANCEL, 0);354 int rc2 = VbglR3HGCMCall(&Msg. hdr, sizeof(Msg.hdr));362 VBGL_HGCM_HDR_INIT(&Msg.Hdr, idClient, GUEST_MSG_CANCEL, 0); 363 int rc2 = VbglR3HGCMCall(&Msg.Hdr, sizeof(Msg.Hdr)); 355 364 AssertRC(rc2); 356 365 } 366 367 /* 368 * If restored, update pidRestoreCheck. 369 */ 370 if (rc == VERR_VM_RESTORED && pidRestoreCheck) 371 *pidRestoreCheck = Msg.idMsg.u.value64; 357 372 358 373 *pidMsg = UINT32_MAX - 1; … … 363 378 /* 364 379 * Fallback if host < v6.0. 380 * 381 * Note! The restore check isn't perfect. Would require checking afterwards 382 * and stash the result if we were restored during the call. Too much 383 * hazzle for a downgrade scenario. 365 384 */ 385 if (pidRestoreCheck) 386 { 387 uint64_t idRestoreCur = *pidRestoreCheck; 388 rc = VbglR3GetSessionId(&idRestoreCur); 389 if (RT_SUCCESS(rc) && idRestoreCur != *pidRestoreCheck) 390 { 391 *pidRestoreCheck = idRestoreCur; 392 return VERR_VM_RESTORED; 393 } 394 } 395 366 396 rc = vbglR3GuestCtrlMsgWaitFor(idClient, pidMsg, pcParameters); 367 397 if (rc == VERR_TOO_MUCH_DATA) -
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControl.cpp
r75824 r75853 251 251 AssertReturn(pvScratchBuf, VERR_NO_MEMORY); 252 252 253 VBGLR3GUESTCTRLCMDCTX ctxHost = { g_idControlSvcClient, 0 /*idContext*/, 2 /*uProtocol*/, 0 /*cParms*/ };254 255 253 int rc = VINF_SUCCESS; /* (shut up compiler warnings) */ 256 254 int cRetrievalFailed = 0; /* Number of failed message retrievals in a row. */ … … 258 256 { 259 257 VGSvcVerbose(3, "GstCtrl: Waiting for host msg ...\n"); 260 uint32_t idMsg = 0;261 uint32_t cParms= 0;262 rc = VbglR3GuestCtrlMsgPeekWait(g_idControlSvcClient, &idMsg, &c Parms);258 VBGLR3GUESTCTRLCMDCTX ctxHost = { g_idControlSvcClient, 0 /*idContext*/, 2 /*uProtocol*/, 0 /*cParms*/ }; 259 uint32_t idMsg = 0; 260 rc = VbglR3GuestCtrlMsgPeekWait(g_idControlSvcClient, &idMsg, &ctxHost.uNumParms, &g_idControlSession); 263 261 if (RT_SUCCESS(rc)) 264 262 { 265 263 cRetrievalFailed = 0; /* Reset failed retrieval count. */ 266 VGSvcVerbose(4, "idMsg=%RU32 (%s) (%RU32 parms) retrieved\n", idMsg, GstCtrlHostFnName((eHostFn)idMsg), cParms); 267 268 /* 269 * Close all open guest sessions if the VM was restored (all context IDs, 270 * sessions, etc. are now invalid). 271 * 272 * Note! This will suck performance wise if we get a lot of messages thru here. 273 * What about the service returning a HOST_MSG_RESTORED message? 274 */ 275 uint64_t idNewSession = g_idControlSession; 276 int rc2 = VbglR3GetSessionId(&idNewSession); 277 if ( RT_SUCCESS(rc2) 278 && idNewSession != g_idControlSession) 279 { 280 VGSvcVerbose(1, "The VM session ID changed (i.e. restored).\n"); 281 g_idControlSession = idNewSession; 282 rc2 = VGSvcGstCtrlSessionClose(&g_Session); 283 AssertRC(rc2); 284 } 264 VGSvcVerbose(4, "idMsg=%RU32 (%s) (%RU32 parms) retrieved\n", 265 idMsg, GstCtrlHostFnName((eHostFn)idMsg), ctxHost.uNumParms); 285 266 286 267 /* 287 268 * Handle the host message. 288 269 */ 289 ctxHost.uNumParms = cParms;290 270 switch (idMsg) 291 271 { … … 308 288 rc = VbglR3GuestCtrlMsgSkip(g_idControlSvcClient, VERR_NOT_SUPPORTED, idMsg); 309 289 VGSvcVerbose(1, "Skipped unexpected message idMsg=%RU32 (%s), cParms=%RU32 (rc=%Rrc)\n", 310 idMsg, GstCtrlHostFnName((eHostFn)idMsg), c Parms, rc);290 idMsg, GstCtrlHostFnName((eHostFn)idMsg), ctxHost.uNumParms, rc); 311 291 } 312 292 else 313 293 { 314 294 rc = VbglR3GuestCtrlMsgSkipOld(g_idControlSvcClient); 315 VGSvcVerbose(3, "Skipped idMsg=%RU32, cParms=%RU32, rc=%Rrc\n", idMsg, c Parms, rc);295 VGSvcVerbose(3, "Skipped idMsg=%RU32, cParms=%RU32, rc=%Rrc\n", idMsg, ctxHost.uNumParms, rc); 316 296 } 317 297 break; … … 325 305 RTThreadYield(); 326 306 } 307 /* 308 * Handle restore notification from host. All the context IDs (sessions, 309 * files, proceses, etc) are invalidated by a VM restore and must be closed. 310 */ 311 else if (rc == VERR_VM_RESTORED) 312 { 313 VGSvcVerbose(1, "The VM session ID changed (i.e. restored).\n"); 314 int rc2 = VGSvcGstCtrlSessionClose(&g_Session); 315 AssertRC(rc2); 316 } 327 317 else 328 318 { … … 332 322 333 323 /* Check for VM session change. */ 324 /** @todo We don't need to check the host here. */ 334 325 uint64_t idNewSession = g_idControlSession; 335 326 int rc2 = VbglR3GetSessionId(&idNewSession); -
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlSession.cpp
r75824 r75853 1579 1579 VGSvcVerbose(3, "Waiting for host msg ...\n"); 1580 1580 uint32_t uMsg = 0; 1581 rc = VbglR3GuestCtrlMsgPeekWait(idClient, &uMsg, &CtxHost.uNumParms );1581 rc = VbglR3GuestCtrlMsgPeekWait(idClient, &uMsg, &CtxHost.uNumParms, NULL); 1582 1582 if (RT_SUCCESS(rc)) 1583 1583 { -
trunk/src/VBox/Devices/VMMDev/VMMDev.cpp
r75808 r75853 4421 4421 pThis->IHGCMPort.pfnIsCmdRestored = hgcmIsCmdRestored; 4422 4422 pThis->IHGCMPort.pfnGetRequestor = hgcmGetRequestor; 4423 pThis->IHGCMPort.pfnGetVMMDevSessionId = hgcmGetVMMDevSessionId; 4423 4424 #endif 4424 4425 -
trunk/src/VBox/Devices/VMMDev/VMMDevHGCM.cpp
r75808 r75853 1546 1546 return pCmd->fRequestor; 1547 1547 return VMMDEV_REQUESTOR_LEGACY; 1548 } 1549 1550 /** 1551 * @interface_method_impl{PDMIHGCMPORT,pfnGetVMMDevSessionId} 1552 */ 1553 DECLCALLBACK(uint64_t) hgcmGetVMMDevSessionId(PPDMIHGCMPORT pInterface) 1554 { 1555 PVMMDEV pThis = RT_FROM_MEMBER(pInterface, VMMDevState, IHGCMPort); 1556 return pThis->idSession; 1548 1557 } 1549 1558 -
trunk/src/VBox/Devices/VMMDev/VMMDevHGCM.h
r75769 r75853 32 32 DECLCALLBACK(bool) hgcmIsCmdRestored(PPDMIHGCMPORT pInterface, PVBOXHGCMCMD pCmd); 33 33 DECLCALLBACK(uint32_t) hgcmGetRequestor(PPDMIHGCMPORT pInterface, PVBOXHGCMCMD pCmd); 34 DECLCALLBACK(uint64_t) hgcmGetVMMDevSessionId(PPDMIHGCMPORT pInterface); 34 35 35 36 int vmmdevHGCMSaveState(VMMDevState *pVMMDevState, PSSMHANDLE pSSM); -
trunk/src/VBox/HostServices/GuestControl/service.cpp
r75825 r75853 67 67 #include <VBox/AssertGuest.h> 68 68 #include <VBox/VMMDev.h> 69 #include <VBox/vmm/ssm.h> 69 70 #include <iprt/assert.h> 70 71 #include <iprt/cpp/autores.h> … … 139 140 } 140 141 142 141 143 /** 142 144 * Retains a reference to the command. … … 149 151 return cRefs; 150 152 } 153 151 154 152 155 /** … … 180 183 } 181 184 185 182 186 /** 183 187 * Initializes the command. … … 269 273 } 270 274 275 276 /** 277 * Sets the GUEST_MSG_PEEK_WAIT GUEST_MSG_PEEK_NOWAIT return parameters. 278 * 279 * @param paDstParms The peek parameter vector. 280 * @param cDstParms The number of peek parameters (at least two). 281 * @remarks ASSUMES the parameters has been cleared by clientMsgPeek. 282 */ 283 inline void setPeekReturn(PVBOXHGCMSVCPARM paDstParms, uint32_t cDstParms) 284 { 285 Assert(cDstParms >= 2); 286 if (paDstParms[0].type == VBOX_HGCM_SVC_PARM_32BIT) 287 paDstParms[0].u.uint32 = mMsgType; 288 else 289 paDstParms[0].u.uint64 = mMsgType; 290 paDstParms[1].u.uint32 = mParmCount; 291 292 uint32_t i = RT_MIN(cDstParms, mParmCount + 2); 293 while (i-- > 2) 294 switch (mpParms[i - 2].type) 295 { 296 case VBOX_HGCM_SVC_PARM_32BIT: paDstParms[i].u.uint32 = ~(uint32_t)sizeof(uint32_t); break; 297 case VBOX_HGCM_SVC_PARM_64BIT: paDstParms[i].u.uint32 = ~(uint32_t)sizeof(uint64_t); break; 298 case VBOX_HGCM_SVC_PARM_PTR: paDstParms[i].u.uint32 = mpParms[i - 2].u.pointer.size; break; 299 } 300 } 301 302 303 /** @name Support for old-style (GUEST_MSG_WAIT) operation. 304 * @{ 305 */ 271 306 272 307 /** … … 421 456 return VERR_TOO_MUCH_DATA; 422 457 } 458 459 /** @} */ 423 460 } HostCommand; 424 461 typedef std::list< HostCommand *> HostCmdList; … … 527 564 rc = VINF_SUCCESS; 528 565 529 HostCmdListIter curCmd = mHostCmdList.begin();530 if ( curCmd != mHostCmdList.end())566 HostCmdListIter ItFirstCmd = mHostCmdList.begin(); 567 if (ItFirstCmd != mHostCmdList.end()) 531 568 { 532 HostCommand *p HostCmd = (*curCmd);533 AssertPtrReturn(p HostCmd, VERR_INVALID_POINTER);569 HostCommand *pFirstCmd = (*ItFirstCmd); 570 AssertPtrReturn(pFirstCmd, VERR_INVALID_POINTER); 534 571 535 572 LogFlowThisFunc(("[Client %RU32] Current host command is %RU32 (CID=%RU32, cParms=%RU32, m_cRefs=%RU32)\n", 536 mID, p HostCmd->mMsgType, pHostCmd->m_idContext, pHostCmd->mParmCount, pHostCmd->m_cRefs));573 mID, pFirstCmd->mMsgType, pFirstCmd->m_idContext, pFirstCmd->mParmCount, pFirstCmd->m_cRefs)); 537 574 538 575 if (mIsPending == GUEST_MSG_PEEK_WAIT) 539 576 { 540 HGCMSvcSetU32(&mPendingCon.mParms[0], pHostCmd->mMsgType); 541 HGCMSvcSetU32(&mPendingCon.mParms[1], pHostCmd->mParmCount); 542 uint32_t i = RT_MIN(mPendingCon.mNumParms, pHostCmd->mParmCount + 2); 543 while (i-- > 2) 544 switch (pHostCmd->mpParms[i - 2].type) 545 { 546 case VBOX_HGCM_SVC_PARM_32BIT: mPendingCon.mParms[i].u.uint32 = ~(uint32_t)sizeof(uint32_t); break; 547 case VBOX_HGCM_SVC_PARM_64BIT: mPendingCon.mParms[i].u.uint32 = ~(uint32_t)sizeof(uint64_t); break; 548 case VBOX_HGCM_SVC_PARM_PTR: mPendingCon.mParms[i].u.uint32 = pHostCmd->mpParms[i - 2].u.pointer.size; break; 549 } 550 577 pFirstCmd->setPeekReturn(mPendingCon.mParms, mPendingCon.mNumParms); 551 578 rc = mSvcHelpers->pfnCallComplete(mPendingCon.mHandle, VINF_SUCCESS); 552 579 … … 557 584 } 558 585 else if (mIsPending == GUEST_MSG_WAIT) 559 rc = OldRun(&mPendingCon, p HostCmd);586 rc = OldRun(&mPendingCon, pFirstCmd); 560 587 else 561 588 AssertMsgFailed(("mIsPending=%d\n", mIsPending)); … … 654 681 { 655 682 Assert(!mHostCmdList.empty()); 656 HostCommand *p HostCmd = *mHostCmdList.begin();657 AssertPtr(p HostCmd);658 p HostCmd->SaneRelease();683 HostCommand *pFirstCmd = *mHostCmdList.begin(); 684 AssertPtr(pFirstCmd); 685 pFirstCmd->SaneRelease(); 659 686 mHostCmdList.pop_front(); 660 687 … … 879 906 RTLISTANCHOR mHostCmdList; 880 907 /** Map containing all connected clients, key is HGCM client ID. */ 881 ClientStateMap mClientStateMap; 908 ClientStateMap mClientStateMap; /**< @todo Use VBOXHGCMSVCFNTABLE::cbClient for this! */ 882 909 /** The master HGCM client ID, UINT32_MAX if none. */ 883 910 uint32_t m_idMasterClient; … … 909 936 uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[], uint64_t tsArrival); 910 937 static DECLCALLBACK(int) svcHostCall(void *pvService, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[]); 938 static DECLCALLBACK(int) svcSaveState(void *pvService, uint32_t idClient, void *pvClient, PSSMHANDLE pSSM); 939 static DECLCALLBACK(int) svcLoadState(void *pvService, uint32_t idClient, void *pvClient, PSSMHANDLE pSSM, uint32_t uVersion); 911 940 static DECLCALLBACK(int) svcRegisterExtension(void *pvService, PFNHGCMSVCEXT pfnExtension, void *pvExtension); 912 941 … … 1199 1228 */ 1200 1229 ASSERT_GUEST_MSG_RETURN(cParms >= 2, ("cParms=%u!\n", cParms), VERR_WRONG_PARAMETER_COUNT); 1201 for (uint32_t i = 0; i < cParms; i++) 1230 1231 uint64_t idRestoreCheck = 0; 1232 uint32_t i = 0; 1233 if (paParms[i].type == VBOX_HGCM_SVC_PARM_64BIT) 1234 { 1235 idRestoreCheck = paParms[0].u.uint64; 1236 paParms[0].u.uint64 = 0; 1237 i++; 1238 } 1239 for (; i < cParms; i++) 1202 1240 { 1203 1241 ASSERT_GUEST_MSG_RETURN(paParms[i].type == VBOX_HGCM_SVC_PARM_32BIT, ("#%u type=%u\n", i, paParms[i].type), … … 1211 1249 1212 1250 /* 1251 * Check restore session ID. 1252 */ 1253 if (idRestoreCheck != 0) 1254 { 1255 uint64_t idRestore = mpHelpers->pfnGetVMMDevSessionId(mpHelpers); 1256 if (idRestoreCheck != idRestore) 1257 { 1258 paParms[0].u.uint32 = idRestore; 1259 LogFlowFunc(("[Client %RU32] GUEST_MSG_PEEK_XXXX -> VERR_VM_RESTORED (%#RX64 -> %#RX64)\n", 1260 idClient, idRestoreCheck, idRestore)); 1261 return VERR_VM_RESTORED; 1262 } 1263 Assert(!mpHelpers->pfnIsCallRestored(hCall)); 1264 } 1265 1266 /* 1213 1267 * Return information about the first command if one is pending in the list. 1214 1268 */ … … 1217 1271 { 1218 1272 HostCommand *pFirstCmd = *itFirstCmd; 1219 paParms[0].u.uint32 = pFirstCmd->mMsgType; 1220 paParms[1].u.uint32 = pFirstCmd->mParmCount; 1221 uint32_t i = RT_MIN(cParms, pFirstCmd->mParmCount + 2); 1222 while (i-- > 2) 1223 switch (pFirstCmd->mpParms[i - 2].type) 1224 { 1225 case VBOX_HGCM_SVC_PARM_32BIT: paParms[i].u.uint32 = ~(uint32_t)sizeof(uint32_t); break; 1226 case VBOX_HGCM_SVC_PARM_64BIT: paParms[i].u.uint32 = ~(uint32_t)sizeof(uint64_t); break; 1227 case VBOX_HGCM_SVC_PARM_PTR: paParms[i].u.uint32 = pFirstCmd->mpParms[i - 2].u.pointer.size; break; 1228 } 1229 1273 pFirstCmd->setPeekReturn(paParms, cParms); 1230 1274 LogFlowFunc(("[Client %RU32] GUEST_MSG_PEEK_XXXX -> VINF_SUCCESS (idMsg=%u (%s), cParms=%u)\n", 1231 1275 idClient, pFirstCmd->mMsgType, GstCtrlHostFnName((eHostFn)pFirstCmd->mMsgType), pFirstCmd->mParmCount)); … … 2197 2241 2198 2242 /** 2243 * @interface_method_impl{VBOXHGCMSVCFNTABLE,pfnSaveState} 2244 */ 2245 /*static*/ DECLCALLBACK(int) 2246 GstCtrlService::svcSaveState(void *pvService, uint32_t idClient, void *pvClient, PSSMHANDLE pSSM) 2247 { 2248 RT_NOREF(pvClient); 2249 AssertLogRelReturn(VALID_PTR(pvService), VERR_INVALID_PARAMETER); 2250 SELF *pThis = reinterpret_cast<SELF *>(pvService); 2251 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 2252 2253 SSMR3PutU32(pSSM, 1); 2254 SSMR3PutBool(pSSM, idClient == pThis->m_idMasterClient); 2255 return SSMR3PutBool(pSSM, pThis->m_fLegacyMode); 2256 } 2257 2258 2259 /** 2260 * @interface_method_impl{VBOXHGCMSVCFNTABLE,pfnLoadState} 2261 */ 2262 /*static*/ DECLCALLBACK(int) 2263 GstCtrlService::svcLoadState(void *pvService, uint32_t idClient, void *pvClient, PSSMHANDLE pSSM, uint32_t uVersion) 2264 { 2265 RT_NOREF(pvClient); 2266 AssertLogRelReturn(VALID_PTR(pvService), VERR_INVALID_PARAMETER); 2267 SELF *pThis = reinterpret_cast<SELF *>(pvService); 2268 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 2269 2270 if (uVersion >= HGCM_SAVED_STATE_VERSION) 2271 { 2272 uint32_t uSubVersion; 2273 int rc = SSMR3GetU32(pSSM, &uSubVersion); 2274 AssertRCReturn(rc, rc); 2275 if (uSubVersion != 1) 2276 return SSMR3SetLoadError(pSSM, VERR_SSM_DATA_UNIT_FORMAT_CHANGED, RT_SRC_POS, 2277 "sub version %u, expected 1\n", uSubVersion); 2278 bool fLegacyMode; 2279 rc = SSMR3GetBool(pSSM, &fLegacyMode); 2280 AssertRCReturn(rc, rc); 2281 pThis->m_fLegacyMode = fLegacyMode; 2282 2283 bool fIsMaster; 2284 rc = SSMR3GetBool(pSSM, &fIsMaster); 2285 AssertRCReturn(rc, rc); 2286 if (fIsMaster) 2287 pThis->m_idMasterClient = idClient; 2288 ClientStateMapIter It = pThis->mClientStateMap.find(idClient); 2289 if (It != pThis->mClientStateMap.end()) 2290 It->second.m_fIsMaster = fIsMaster; 2291 else 2292 AssertFailed(); 2293 } 2294 else 2295 { 2296 /* 2297 * For old saved states we have to guess at who should be the master. 2298 * Given how HGCMService::CreateAndConnectClient and associates manage 2299 * and saves the client, the first client connecting will be restored 2300 * first. The only time this might go wrong if the there are zombie 2301 * VBoxService session processes in the restored guest, and I don't 2302 * we need to care too much about that scenario. 2303 * 2304 * Given how HGCM first re-connects the clients before this function 2305 * gets called, there isn't anything we need to do here it turns out. :-) 2306 */ 2307 } 2308 return VINF_SUCCESS; 2309 } 2310 2311 2312 /** 2199 2313 * @interface_method_impl{VBOXHGCMSVCFNTABLE,pfnRegisterExtension, 2200 2314 * Installs a host callback for notifications of property changes.} … … 2203 2317 { 2204 2318 AssertLogRelReturn(VALID_PTR(pvService), VERR_INVALID_PARAMETER); 2205 SELF *pSelf = reinterpret_cast<SELF *>(pvService); 2206 AssertPtrReturn(pSelf, VERR_INVALID_POINTER); 2207 pSelf->mpfnHostCallback = pfnExtension; 2208 pSelf->mpvHostData = pvExtension; 2319 SELF *pThis = reinterpret_cast<SELF *>(pvService); 2320 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 2321 2322 pThis->mpfnHostCallback = pfnExtension; 2323 pThis->mpvHostData = pvExtension; 2209 2324 return VINF_SUCCESS; 2210 2325 } … … 2256 2371 * because we're a class which can have members for that :-). 2257 2372 */ 2258 pTable->cbClient = 0; 2373 pTable->cbClient = 0; /** @todo this is where ClientState should live, isn't it? */ 2259 2374 2260 2375 /* Register functions. */ 2261 pTable->pfnUnload = GstCtrlService::svcUnload;2262 pTable->pfnConnect = GstCtrlService::svcConnect;2263 pTable->pfnDisconnect = GstCtrlService::svcDisconnect;2264 pTable->pfnCall = GstCtrlService::svcCall;2265 pTable->pfnHostCall = GstCtrlService::svcHostCall;2266 pTable->pfnSaveState = NULL; /* The GstCtrlService is stateless, so the normal */2267 pTable->pfnLoadState = NULL; /* construction done before restoring suffices */2268 pTable->pfnRegisterExtension = GstCtrlService::svcRegisterExtension;2376 pTable->pfnUnload = GstCtrlService::svcUnload; 2377 pTable->pfnConnect = GstCtrlService::svcConnect; 2378 pTable->pfnDisconnect = GstCtrlService::svcDisconnect; 2379 pTable->pfnCall = GstCtrlService::svcCall; 2380 pTable->pfnHostCall = GstCtrlService::svcHostCall; 2381 pTable->pfnSaveState = GstCtrlService::svcSaveState; 2382 pTable->pfnLoadState = GstCtrlService::svcLoadState; 2383 pTable->pfnRegisterExtension = GstCtrlService::svcRegisterExtension; 2269 2384 2270 2385 /* Service specific initialization. */ -
trunk/src/VBox/HostServices/GuestControl/testcase/Makefile.kmk
r69111 r75853 35 35 ../service.cpp \ 36 36 tstGuestControlSvc.cpp 37 tstGuestControlSvc_LIBS = $(LIB_RUNTIME) 37 tstGuestControlSvc_LIBS = $(LIB_RUNTIME) $(LIB_VMM) 38 38 39 39 $$(tstGuestControlSvc_0_OUTDIR)/tstGuestControlSvc.run: $$(tstGuestControlSvc_1_STAGE_TARGET) -
trunk/src/VBox/HostServices/SharedClipboard/service.cpp
r75773 r75853 857 857 } CLIPSAVEDSTATEDATA; 858 858 859 static DECLCALLBACK(int) svcLoadState(void *, uint32_t u32ClientID, void *pvClient, PSSMHANDLE pSSM )859 static DECLCALLBACK(int) svcLoadState(void *, uint32_t u32ClientID, void *pvClient, PSSMHANDLE pSSM, uint32_t uVersion) 860 860 { 861 861 #ifndef UNIT_TEST 862 RT_NOREF(uVersion); 862 863 LogRel2 (("svcLoadState: u32ClientID = %d\n", u32ClientID)); 863 864 … … 931 932 932 933 #else /* UNIT_TEST*/ 933 RT_NOREF 3(u32ClientID, pvClient, pSSM);934 RT_NOREF(u32ClientID, pvClient, pSSM, uVersion); 934 935 #endif /* UNIT_TEST */ 935 936 return VINF_SUCCESS; -
trunk/src/VBox/HostServices/SharedFolders/service.cpp
r75773 r75853 242 242 } 243 243 244 static DECLCALLBACK(int) svcLoadState(void *, uint32_t u32ClientID, void *pvClient, PSSMHANDLE pSSM )244 static DECLCALLBACK(int) svcLoadState(void *, uint32_t u32ClientID, void *pvClient, PSSMHANDLE pSSM, uint32_t uVersion) 245 245 { 246 246 #ifndef UNITTEST /* Read this as not yet tested */ 247 RT_NOREF 1(u32ClientID);247 RT_NOREF(u32ClientID, uVersion); 248 248 uint32_t nrMappings; 249 249 SHFLCLIENTDATA *pClient = (SHFLCLIENTDATA *)pvClient; … … 395 395 Log(("SharedFolders host service: successfully loaded state\n")); 396 396 #else 397 RT_NOREF 3(u32ClientID, pvClient, pSSM);397 RT_NOREF(u32ClientID, pvClient, pSSM, uVersion); 398 398 #endif 399 399 return VINF_SUCCESS; -
trunk/src/VBox/HostServices/SharedOpenGL/crserver/crservice.cpp
r75773 r75853 199 199 } 200 200 201 static DECLCALLBACK(int) svcLoadState(void *, uint32_t u32ClientID, void *pvClient, PSSMHANDLE pSSM )201 static DECLCALLBACK(int) svcLoadState(void *, uint32_t u32ClientID, void *pvClient, PSSMHANDLE pSSM, uint32_t uVersion) 202 202 { 203 RT_NOREF(pvClient, uVersion); 203 204 int rc = VINF_SUCCESS; 204 205 NOREF(pvClient);206 205 207 206 Log(("SHARED_CROPENGL svcLoadState: u32ClientID = %d\n", u32ClientID)); -
trunk/src/VBox/Main/include/ConsoleImpl.h
r75527 r75853 740 740 int i_configSerialPort(PCFGMNODE pInst, PortMode_T ePortMode, const char *pszPath, bool fServer); 741 741 static DECLCALLBACK(int) i_configGuestProperties(void *pvConsole); 742 static DECLCALLBACK(int) i_configGuestControl(void *pvConsole);743 742 static DECLCALLBACK(void) i_vmstateChangeCallback(PUVM pUVM, VMSTATE enmState, VMSTATE enmOldState, void *pvUser); 744 743 static DECLCALLBACK(int) i_unplugCpu(Console *pThis, PUVM pUVM, VMCPUID idCpu); -
trunk/src/VBox/Main/include/HGCM.h
r75574 r75853 26 26 #include <VBox/hgcmsvc.h> 27 27 28 /* HGCM saved state version */29 #define HGCM_SSM_VERSION 230 31 28 /* Handle of a HGCM service extension. */ 32 29 struct _HGCMSVCEXTHANDLEDATA; … … 39 36 int HGCMHostReset(void); 40 37 41 int HGCMHostLoad(const char *pszServiceLibrary, const char *pszServiceName, PUVM pUVM );38 int HGCMHostLoad(const char *pszServiceLibrary, const char *pszServiceName, PUVM pUVM, PPDMIHGCMPORT pHgcmPort); 42 39 43 40 int HGCMHostRegisterServiceExtension(HGCMSVCEXTHANDLE *pHandle, const char *pszServiceName, PFNHGCMSVCEXT pfnExtension, void *pvExtension); … … 59 56 60 57 int HGCMHostSaveState(PSSMHANDLE pSSM); 61 int HGCMHostLoadState(PSSMHANDLE pSSM );58 int HGCMHostLoadState(PSSMHANDLE pSSM, uint32_t uVersion); 62 59 63 60 RT_C_DECLS_END -
trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp
r75823 r75853 36 36 #include "ConsoleImpl.h" 37 37 #include "DisplayImpl.h" 38 #ifdef VBOX_WITH_ GUEST_CONTROL38 #ifdef VBOX_WITH_DRAG_AND_DROP 39 39 # include "GuestImpl.h" 40 #endif41 #ifdef VBOX_WITH_DRAG_AND_DROP42 40 # include "GuestDnDPrivate.h" 43 41 #endif … … 3194 3192 */ 3195 3193 rc = i_configGuestProperties(this); 3196 #endif3197 3198 #ifdef VBOX_WITH_GUEST_CONTROL3199 /*3200 * Guest control service.3201 */3202 rc = i_configGuestControl(this);3203 3194 #endif 3204 3195 … … 6235 6226 } 6236 6227 6237 /**6238 * Set up the Guest Control service.6239 */6240 /* static */ int Console::i_configGuestControl(void *pvConsole)6241 {6242 #ifdef VBOX_WITH_GUEST_CONTROL6243 AssertReturn(pvConsole, VERR_INVALID_POINTER);6244 ComObjPtr<Console> pConsole = static_cast<Console *>(pvConsole);6245 6246 /* Load the service */6247 int rc = pConsole->m_pVMMDev->hgcmLoadService("VBoxGuestControlSvc", "VBoxGuestControlSvc");6248 6249 if (RT_FAILURE(rc))6250 {6251 LogRel(("VBoxGuestControlSvc is not available. rc = %Rrc\n", rc));6252 /* That is not a fatal failure. */6253 rc = VINF_SUCCESS;6254 }6255 else6256 {6257 HGCMSVCEXTHANDLE hDummy;6258 rc = HGCMHostRegisterServiceExtension(&hDummy, "VBoxGuestControlSvc",6259 &Guest::i_notifyCtrlDispatcher,6260 pConsole->i_getGuest());6261 if (RT_FAILURE(rc))6262 Log(("Cannot register VBoxGuestControlSvc extension!\n"));6263 else6264 LogRel(("Guest Control service loaded\n"));6265 }6266 6267 return rc;6268 #else /* !VBOX_WITH_GUEST_CONTROL */6269 return VERR_NOT_SUPPORTED;6270 #endif /* !VBOX_WITH_GUEST_CONTROL */6271 } -
trunk/src/VBox/Main/src-client/HGCM.cpp
r75774 r75853 118 118 119 119 PUVM m_pUVM; 120 PPDMIHGCMPORT m_pHgcmPort; 120 121 121 122 /** @name Statistics … … 130 131 * Main HGCM thread methods. 131 132 */ 132 int instanceCreate(const char *pszServiceLibrary, const char *pszServiceName, PUVM pUVM );133 int instanceCreate(const char *pszServiceLibrary, const char *pszServiceName, PUVM pUVM, PPDMIHGCMPORT pHgcmPort); 133 134 void instanceDestroy(void); 134 135 135 136 int saveClientState(uint32_t u32ClientId, PSSMHANDLE pSSM); 136 int loadClientState(uint32_t u32ClientId, PSSMHANDLE pSSM );137 int loadClientState(uint32_t u32ClientId, PSSMHANDLE pSSM, uint32_t uVersion); 137 138 138 139 HGCMService(); … … 150 151 static DECLCALLBACK(int) svcHlpInfoDeregister(void *pvInstance, const char *pszName); 151 152 static DECLCALLBACK(uint32_t) svcHlpGetRequestor(VBOXHGCMCALLHANDLE hCall); 153 static DECLCALLBACK(uint64_t) svcHlpGetVMMDevSessionId(void *pvInstance); 152 154 153 155 public: … … 156 158 * Main HGCM thread methods. 157 159 */ 158 static int LoadService(const char *pszServiceLibrary, const char *pszServiceName, PUVM pUVM );160 static int LoadService(const char *pszServiceLibrary, const char *pszServiceName, PUVM pUVM, PPDMIHGCMPORT pHgcmPort); 159 161 void UnloadService(bool fUvmIsInvalid); 160 162 … … 168 170 169 171 static int SaveState(PSSMHANDLE pSSM); 170 static int LoadState(PSSMHANDLE pSSM );172 static int LoadState(PSSMHANDLE pSSM, uint32_t uVersion); 171 173 172 174 int CreateAndConnectClient(uint32_t *pu32ClientIdOut, uint32_t u32ClientIdIn, uint32_t fRequestor, bool fRestoring); … … 199 201 { 200 202 public: 201 HGCMClient() : HGCMObject(HGCMOBJ_CLIENT), pService(NULL), 202 pvData(NULL) {}; 203 HGCMClient(uint32_t a_fRequestor) 204 : HGCMObject(HGCMOBJ_CLIENT) 205 , pService(NULL) 206 , pvData(NULL) 207 , fRequestor(a_fRequestor) 208 {} 203 209 ~HGCMClient(); 204 210 … … 210 216 /** Client specific data. */ 211 217 void *pvData; 218 219 /** The requestor flags this client was created with. 220 * @sa VMMDevRequestHeader::fRequestor */ 221 uint32_t fRequestor; 222 223 private: /* none of this: */ 224 HGCMClient(); 225 HGCMClient(HGCMClient const &); 226 HGCMClient &operator=(HGCMClient const &); 212 227 }; 213 228 … … 215 230 { 216 231 if (pService->SizeOfClient() > 0) 232 { 217 233 RTMemFree(pvData); 218 } 234 pvData = NULL; 235 } 236 } 237 219 238 220 239 int HGCMClient::Init(HGCMService *pSvc) … … 261 280 #endif 262 281 m_hExtension (NULL), 263 m_pUVM (NULL) 282 m_pUVM (NULL), 283 m_pHgcmPort (NULL) 264 284 { 265 285 RT_ZERO(m_fntable); … … 469 489 { 470 490 public: 491 PSSMHANDLE pSSM; 492 uint32_t uVersion; 471 493 uint32_t u32ClientId; 472 PSSMHANDLE pSSM;473 494 }; 474 495 … … 684 705 if (pClient) 685 706 { 686 if (pSvc->m_fntable.pfnLoadState) 707 /* fRequestor: Restored by the message sender already. */ 708 bool fHaveClientState = pSvc->m_fntable.pfnLoadState != NULL; 709 if (pMsg->uVersion > HGCM_SAVED_STATE_VERSION_V2) 710 rc = SSMR3GetBool(pMsg->pSSM, &fHaveClientState); 711 else 712 rc = VINF_SUCCESS; 713 if (RT_SUCCESS(rc) ) 687 714 { 688 rc = pSvc->m_fntable.pfnLoadState(pSvc->m_fntable.pvService, pMsg->u32ClientId, 689 HGCM_CLIENT_DATA(pSvc, pClient), pMsg->pSSM); 715 if (pSvc->m_fntable.pfnLoadState) 716 rc = pSvc->m_fntable.pfnLoadState(pSvc->m_fntable.pvService, pMsg->u32ClientId, 717 HGCM_CLIENT_DATA(pSvc, pClient), pMsg->pSSM, 718 fHaveClientState ? pMsg->uVersion : 0); 719 else 720 AssertLogRelStmt(!fHaveClientState, rc = VERR_INTERNAL_ERROR_5); 690 721 } 691 692 722 hgcmObjDereference(pClient); 693 723 } … … 710 740 if (pClient) 711 741 { 712 if (pSvc->m_fntable.pfnSaveState) 742 SSMR3PutU32(pMsg->pSSM, pClient->fRequestor); /* Quicker to save this here than in the message sender. */ 743 rc = SSMR3PutBool(pMsg->pSSM, pSvc->m_fntable.pfnSaveState != NULL); 744 if (RT_SUCCESS(rc) && pSvc->m_fntable.pfnSaveState) 713 745 { 714 746 g_fSaveState = true; … … 893 925 } 894 926 895 896 927 /** 897 928 * @interface_method_impl{VBOXHGCMSVCHELPERS,pfnGetRequestor} … … 909 940 910 941 return pHgcmPort->pfnGetRequestor(pHgcmPort, pCmd); 942 } 943 944 /** 945 * @interface_method_impl{VBOXHGCMSVCHELPERS,pfnGetVMMDevSessionId} 946 */ 947 /* static */ DECLCALLBACK(uint64_t) HGCMService::svcHlpGetVMMDevSessionId(void *pvInstance) 948 { 949 HGCMService *pService = static_cast <HGCMService *>(pvInstance); 950 AssertPtrReturn(pService, UINT64_MAX); 951 952 PPDMIHGCMPORT pHgcmPort = pService->m_pHgcmPort; 953 AssertPtrReturn(pHgcmPort, UINT64_MAX); 954 955 return pHgcmPort->pfnGetVMMDevSessionId(pHgcmPort); 911 956 } 912 957 … … 933 978 */ 934 979 935 int HGCMService::instanceCreate(const char *pszServiceLibrary, const char *pszServiceName, PUVM pUVM )980 int HGCMService::instanceCreate(const char *pszServiceLibrary, const char *pszServiceName, PUVM pUVM, PPDMIHGCMPORT pHgcmPort) 936 981 { 937 982 LogFlowFunc(("name %s, lib %s\n", pszServiceName, pszServiceLibrary)); … … 964 1009 else 965 1010 { 1011 m_pUVM = pUVM; 1012 m_pHgcmPort = pHgcmPort; 1013 966 1014 /* Register statistics: */ 967 m_pUVM = pUVM;968 1015 STAMR3RegisterFU(pUVM, &m_StatHandleMsg, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, 969 1016 "Message handling", "/HGCM/%s/Msg", pszServiceName); 970 1017 971 1018 /* Initialize service helpers table. */ 972 m_svcHelpers.pfnCallComplete = svcHlpCallComplete; 973 m_svcHelpers.pvInstance = this; 974 m_svcHelpers.pfnDisconnectClient = svcHlpDisconnectClient; 975 m_svcHelpers.pfnIsCallRestored = svcHlpIsCallRestored; 976 m_svcHelpers.pfnStamRegisterV = svcHlpStamRegisterV; 977 m_svcHelpers.pfnStamDeregisterV = svcHlpStamDeregisterV; 978 m_svcHelpers.pfnInfoRegister = svcHlpInfoRegister; 979 m_svcHelpers.pfnInfoDeregister = svcHlpInfoDeregister; 980 m_svcHelpers.pfnGetRequestor = svcHlpGetRequestor; 1019 m_svcHelpers.pfnCallComplete = svcHlpCallComplete; 1020 m_svcHelpers.pvInstance = this; 1021 m_svcHelpers.pfnDisconnectClient = svcHlpDisconnectClient; 1022 m_svcHelpers.pfnIsCallRestored = svcHlpIsCallRestored; 1023 m_svcHelpers.pfnStamRegisterV = svcHlpStamRegisterV; 1024 m_svcHelpers.pfnStamDeregisterV = svcHlpStamDeregisterV; 1025 m_svcHelpers.pfnInfoRegister = svcHlpInfoRegister; 1026 m_svcHelpers.pfnInfoDeregister = svcHlpInfoDeregister; 1027 m_svcHelpers.pfnGetRequestor = svcHlpGetRequestor; 1028 m_svcHelpers.pfnGetVMMDevSessionId = svcHlpGetVMMDevSessionId; 981 1029 982 1030 /* Execute the load request on the service thread. */ … … 1022 1070 STAMR3DeregisterF(m_pUVM, "/HGCM/%s/*", m_pszSvcName); 1023 1071 m_pUVM = NULL; 1072 m_pHgcmPort = NULL; 1024 1073 1025 1074 RTStrFree(m_pszSvcLibrary); … … 1051 1100 } 1052 1101 1053 int HGCMService::loadClientState(uint32_t u32ClientId, PSSMHANDLE pSSM )1102 int HGCMService::loadClientState(uint32_t u32ClientId, PSSMHANDLE pSSM, uint32_t uVersion) 1054 1103 { 1055 1104 LogFlowFunc(("%s\n", m_pszSvcName)); … … 1062 1111 HGCMMsgLoadSaveStateClient *pMsg = (HGCMMsgLoadSaveStateClient *)pCoreMsg; 1063 1112 1113 pMsg->pSSM = pSSM; 1114 pMsg->uVersion = uVersion; 1064 1115 pMsg->u32ClientId = u32ClientId; 1065 pMsg->pSSM = pSSM;1066 1116 1067 1117 rc = hgcmMsgSend(pMsg); … … 1075 1125 /** The method creates a service and references it. 1076 1126 * 1077 * @param pszServiceLibrary The library to be loaded. 1078 * @param pszServiceName The name of the service. 1079 * @param pUVM The user mode VM handle (for statistics and such). 1080 * @return VBox rc. 1081 * @thread main HGCM 1082 */ 1083 /* static */ int HGCMService::LoadService(const char *pszServiceLibrary, const char *pszServiceName, PUVM pUVM) 1127 * @param pszServiceLibrary The library to be loaded. 1128 * @param pszServiceName The name of the service. 1129 * @param pUVM The user mode VM handle (for statistics and such). 1130 * @param pHgcmPort The VMMDev HGCM port interface. 1131 * 1132 * @return VBox rc. 1133 * @thread main HGCM 1134 */ 1135 /* static */ int HGCMService::LoadService(const char *pszServiceLibrary, const char *pszServiceName, 1136 PUVM pUVM, PPDMIHGCMPORT pHgcmPort) 1084 1137 { 1085 1138 LogFlowFunc(("lib %s, name = %s, pUVM = %p\n", pszServiceLibrary, pszServiceName, pUVM)); … … 1108 1161 { 1109 1162 /* Load the library and call the initialization entry point. */ 1110 rc = pSvc->instanceCreate(pszServiceLibrary, pszServiceName, pUVM );1163 rc = pSvc->instanceCreate(pszServiceLibrary, pszServiceName, pUVM, pHgcmPort); 1111 1164 1112 1165 if (RT_SUCCESS(rc)) … … 1151 1204 1152 1205 if (fUvmIsInvalid) 1206 { 1153 1207 m_pUVM = NULL; 1208 m_pHgcmPort = NULL; 1209 } 1154 1210 1155 1211 /* Remove the service from the list. */ … … 1354 1410 Log(("client id 0x%08X\n", u32ClientId)); 1355 1411 1356 /* Save the client id. */1412 /* Save the client id. (fRequestor is saved via SVC_MSG_SAVESTATE for convenience.) */ 1357 1413 rc = SSMR3PutU32(pSSM, u32ClientId); 1358 1414 AssertRCReturn(rc, rc); … … 1371 1427 /** The method loads saved HGCM state. 1372 1428 * 1373 * @param pSSM The saved state context. 1429 * @param pSSM The saved state handle. 1430 * @param uVersion The state version being loaded. 1374 1431 * @return VBox rc. 1375 1432 * @thread main HGCM 1376 1433 */ 1377 /* static */ int HGCMService::LoadState(PSSMHANDLE pSSM )1434 /* static */ int HGCMService::LoadState(PSSMHANDLE pSSM, uint32_t uVersion) 1378 1435 { 1379 1436 /* Restore handle count to avoid client id conflicts. */ … … 1424 1481 while (cClients--) 1425 1482 { 1426 /* Get the client id. */ 1483 /* Get the client ID and fRequest (convieniently save via SVC_MSG_SAVESTATE 1484 but restored here in time for calling CreateAndConnectClient). */ 1427 1485 uint32_t u32ClientId; 1428 1486 rc = SSMR3GetU32(pSSM, &u32ClientId); 1429 uint32_t fRequestor = VMMDEV_REQUESTOR_LEGACY; /** @todo save/restore fRequestor. */ 1430 if (RT_FAILURE(rc)) 1431 { 1432 pSvc->ReleaseService(); 1433 AssertFailed(); 1434 return rc; 1435 } 1487 uint32_t fRequestor = VMMDEV_REQUESTOR_LEGACY; 1488 if (RT_SUCCESS(rc) && uVersion > HGCM_SAVED_STATE_VERSION_V2) 1489 rc = SSMR3GetU32(pSSM, &fRequestor); 1490 AssertLogRelMsgRCReturnStmt(rc, ("rc=%Rrc, %s\n", rc, szServiceName), pSvc->ReleaseService(), rc); 1436 1491 1437 1492 /* Connect the client. */ 1438 1493 rc = pSvc->CreateAndConnectClient(NULL, u32ClientId, fRequestor, true /*fRestoring*/); 1439 if (RT_FAILURE(rc)) 1440 { 1441 pSvc->ReleaseService(); 1442 AssertLogRelMsgFailed(("rc=%Rrc %s\n", rc, szServiceName)); 1443 return rc; 1444 } 1494 AssertLogRelMsgRCReturnStmt(rc, ("rc=%Rrc, %s\n", rc, szServiceName), pSvc->ReleaseService(), rc); 1445 1495 1446 1496 /* Call the service, so the operation is executed by the service thread. */ 1447 rc = pSvc->loadClientState(u32ClientId, pSSM); 1448 if (RT_FAILURE(rc)) 1449 { 1450 pSvc->ReleaseService(); 1451 AssertLogRelMsgFailed(("rc=%Rrc %s\n", rc, szServiceName)); 1452 return rc; 1453 } 1497 rc = pSvc->loadClientState(u32ClientId, pSSM, uVersion); 1498 AssertLogRelMsgRCReturnStmt(rc, ("rc=%Rrc, %s\n", rc, szServiceName), pSvc->ReleaseService(), rc); 1454 1499 } 1455 1500 … … 1475 1520 1476 1521 /* Allocate a client information structure. */ 1477 HGCMClient *pClient = new HGCMClient();1522 HGCMClient *pClient = new (std::nothrow) HGCMClient(fRequestor); 1478 1523 1479 1524 if (!pClient) … … 1851 1896 /** The user mode VM handle (for statistics and such). */ 1852 1897 PUVM pUVM; 1898 /** The HGCM port on the VMMDev device (for session ID and such). */ 1899 PPDMIHGCMPORT pHgcmPort; 1853 1900 }; 1854 1901 … … 1869 1916 { 1870 1917 public: 1871 /* SSM context. */1918 /** Saved state handle. */ 1872 1919 PSSMHANDLE pSSM; 1920 /** The HGCM saved state version being loaded (ignore for save). */ 1921 uint32_t uVersion; 1873 1922 }; 1874 1923 … … 2031 2080 pMsg->pszServiceName, pMsg->pszServiceLibrary, pMsg->pUVM)); 2032 2081 2033 rc = HGCMService::LoadService(pMsg->pszServiceLibrary, pMsg->pszServiceName, pMsg->pUVM );2082 rc = HGCMService::LoadService(pMsg->pszServiceLibrary, pMsg->pszServiceName, pMsg->pUVM, pMsg->pHgcmPort); 2034 2083 } break; 2035 2084 … … 2106 2155 LogFlowFunc(("HGCM_MSG_LOADSTATE\n")); 2107 2156 2108 rc = HGCMService::LoadState(pMsg->pSSM );2157 rc = HGCMService::LoadState(pMsg->pSSM, pMsg->uVersion); 2109 2158 } break; 2110 2159 … … 2223 2272 * @param pszServiceName The name to be assigned to the service. 2224 2273 * @param pUVM The user mode VM handle (for statistics and such). 2274 * @param pHgcmPort The HGCM port on the VMMDev device (for session ID and such). 2225 2275 * @return VBox rc. 2226 2276 */ 2227 2277 int HGCMHostLoad(const char *pszServiceLibrary, 2228 2278 const char *pszServiceName, 2229 PUVM pUVM) 2279 PUVM pUVM, 2280 PPDMIHGCMPORT pHgcmPort) 2230 2281 { 2231 2282 LogFlowFunc(("lib = %s, name = %s\n", pszServiceLibrary, pszServiceName)); … … 2248 2299 pMsg->pszServiceName = pszServiceName; 2249 2300 pMsg->pUVM = pUVM; 2301 pMsg->pHgcmPort = pHgcmPort; 2250 2302 2251 2303 rc = hgcmMsgSend(pMsg); … … 2403 2455 } 2404 2456 2405 /* Helper to send either HGCM_MSG_SAVESTATE or HGCM_MSG_LOADSTATE messages to the main HGCM thread.2457 /** Helper to send either HGCM_MSG_SAVESTATE or HGCM_MSG_LOADSTATE messages to the main HGCM thread. 2406 2458 * 2407 2459 * @param pSSM The SSM handle. 2408 * @param u32MsgId The message to be sent: HGCM_MSG_SAVESTATE or HGCM_MSG_LOADSTATE. 2460 * @param idMsg The message to be sent: HGCM_MSG_SAVESTATE or HGCM_MSG_LOADSTATE. 2461 * @param uVersion The state version being loaded. 2409 2462 * @return VBox rc. 2410 2463 */ 2411 static int hgcmHostLoadSaveState(PSSMHANDLE pSSM, 2412 uint32_t u32MsgId) 2413 { 2414 LogFlowFunc(("pSSM = %p, u32MsgId = %d\n", pSSM, u32MsgId)); 2464 static int hgcmHostLoadSaveState(PSSMHANDLE pSSM, uint32_t idMsg, uint32_t uVersion) 2465 { 2466 LogFlowFunc(("pSSM = %p, idMsg = %d, uVersion = uVersion\n", pSSM, idMsg)); 2415 2467 2416 2468 HGCMMsgCore *pCoreMsg; 2417 int rc = hgcmMsgAlloc(g_pHgcmThread, &pCoreMsg, u32MsgId, hgcmMainMessageAlloc);2469 int rc = hgcmMsgAlloc(g_pHgcmThread, &pCoreMsg, idMsg, hgcmMainMessageAlloc); 2418 2470 2419 2471 if (RT_SUCCESS(rc)) … … 2423 2475 2424 2476 pMsg->pSSM = pSSM; 2477 pMsg->uVersion = uVersion; 2425 2478 2426 2479 rc = hgcmMsgSend(pMsg); … … 2431 2484 } 2432 2485 2433 /* Save the state of services.2486 /** Save the state of services. 2434 2487 * 2435 2488 * @param pSSM The SSM handle. … … 2438 2491 int HGCMHostSaveState(PSSMHANDLE pSSM) 2439 2492 { 2440 return hgcmHostLoadSaveState(pSSM, HGCM_MSG_SAVESTATE );2441 } 2442 2443 /* Load the state of services.2493 return hgcmHostLoadSaveState(pSSM, HGCM_MSG_SAVESTATE, HGCM_SAVED_STATE_VERSION); 2494 } 2495 2496 /** Load the state of services. 2444 2497 * 2445 2498 * @param pSSM The SSM handle. 2499 * @param uVersion The state version being loaded. 2446 2500 * @return VBox rc. 2447 2501 */ 2448 int HGCMHostLoadState(PSSMHANDLE pSSM )2449 { 2450 return hgcmHostLoadSaveState(pSSM, HGCM_MSG_LOADSTATE );2502 int HGCMHostLoadState(PSSMHANDLE pSSM, uint32_t uVersion) 2503 { 2504 return hgcmHostLoadSaveState(pSSM, HGCM_MSG_LOADSTATE, uVersion); 2451 2505 } 2452 2506 -
trunk/src/VBox/Main/src-client/VMMDevInterface.cpp
r75574 r75853 680 680 LogFlowFunc(("Enter\n")); 681 681 682 if (uVersion != HGCM_SSM_VERSION) 682 if ( uVersion != HGCM_SAVED_STATE_VERSION 683 && uVersion != HGCM_SAVED_STATE_VERSION_V2) 683 684 return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION; 684 685 Assert(uPass == SSM_PASS_FINAL); NOREF(uPass); 685 686 686 return HGCMHostLoadState(pSSM );687 return HGCMHostLoadState(pSSM, uVersion); 687 688 } 688 689 … … 692 693 return VERR_INVALID_STATE; 693 694 695 /** @todo Construct all the services in the VMMDev::drvConstruct()!! */ 696 Assert( (mpDrv && mpDrv->pHGCMPort) 697 || !strcmp(pszServiceLibrary, "VBoxHostChannel") 698 || !strcmp(pszServiceLibrary, "VBoxSharedClipboard") 699 || !strcmp(pszServiceLibrary, "VBoxDragAndDropSvc") 700 || !strcmp(pszServiceLibrary, "VBoxGuestPropSvc") 701 || !strcmp(pszServiceLibrary, "VBoxSharedCrOpenGL") 702 ); 694 703 Console::SafeVMPtrQuiet ptrVM(mParent); 695 return HGCMHostLoad(pszServiceLibrary, pszServiceName, ptrVM.rawUVM() );704 return HGCMHostLoad(pszServiceLibrary, pszServiceName, ptrVM.rawUVM(), mpDrv ? mpDrv->pHGCMPort : NULL); 696 705 } 697 706 … … 864 873 865 874 #ifdef VBOX_WITH_HGCM 866 rc = pThis->pVMMDev->hgcmLoadService(VBOXSHAREDFOLDERS_DLL, 867 "VBoxSharedFolders"); 875 /* 876 * Load & configure the shared folders service. 877 */ 878 rc = pThis->pVMMDev->hgcmLoadService(VBOXSHAREDFOLDERS_DLL, "VBoxSharedFolders"); 868 879 pThis->pVMMDev->fSharedFolderActive = RT_SUCCESS(rc); 869 880 if (RT_SUCCESS(rc)) … … 892 903 LogRel(("Failed to load Shared Folders service %Rrc\n", rc)); 893 904 894 rc = PDMDrvHlpSSMRegisterEx(pDrvIns, HGCM_SSM_VERSION, 4096 /* bad guess */, 905 906 /* 907 * Load and configure guest control service. 908 */ 909 # ifdef VBOX_WITH_GUEST_CONTROL 910 rc = pThis->pVMMDev->hgcmLoadService("VBoxGuestControlSvc", "VBoxGuestControlSvc"); 911 if (RT_SUCCESS(rc)) 912 { 913 HGCMSVCEXTHANDLE hDummy; 914 rc = HGCMHostRegisterServiceExtension(&hDummy, "VBoxGuestControlSvc", 915 &Guest::i_notifyCtrlDispatcher, 916 pThis->pVMMDev->mParent->i_getGuest()); 917 if (RT_SUCCESS(rc)) 918 LogRel(("Guest Control service loaded\n")); 919 else 920 LogRel(("Warning: Cannot register VBoxGuestControlSvc extension! rc=%Rrc\n", rc)); 921 } 922 else 923 LogRel(("Warning!: Failed to load the Guest Control Service! %Rrc\n", rc)); 924 # endif /* VBOX_WITH_GUEST_CONTROL */ 925 926 927 /* 928 * The HGCM saved state. 929 */ 930 rc = PDMDrvHlpSSMRegisterEx(pDrvIns, HGCM_SAVED_STATE_VERSION, 4096 /* bad guess */, 895 931 NULL, NULL, NULL, 896 932 NULL, iface_hgcmSave, NULL,
Note:
See TracChangeset
for help on using the changeset viewer.