Changeset 75736 in vbox
- Timestamp:
- Nov 26, 2018 3:32:10 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlSession.cpp
r75727 r75736 1132 1132 uint32_t uSessionID = pThread->StartupInfo.uSessionID; 1133 1133 1134 uint32_t uClientID;1135 int rc = VbglR3GuestCtrlConnect(& uClientID);1134 uint32_t idClient; 1135 int rc = VbglR3GuestCtrlConnect(&idClient); 1136 1136 if (RT_SUCCESS(rc)) 1137 1137 { 1138 VGSvcVerbose(3, "Session ID=%RU32 thread running, client ID=%RU32\n", uSessionID, uClientID);1138 VGSvcVerbose(3, "Session ID=%RU32 thread running, client ID=%RU32\n", uSessionID, idClient); 1139 1139 1140 1140 /* The session thread is not interested in receiving any commands; 1141 1141 * tell the host service. */ 1142 rc = VbglR3GuestCtrlMsgFilterSet( uClientID, 0 /* Skip all */, 0 /* Filter mask to add */, 0 /* Filter mask to remove */);1142 rc = VbglR3GuestCtrlMsgFilterSet(idClient, 0 /* Skip all */, 0 /* Filter mask to add */, 0 /* Filter mask to remove */); 1143 1143 if (RT_FAILURE(rc)) 1144 1144 { … … 1190 1190 VBGLR3GUESTCTRLCMDCTX hostCtx = 1191 1191 { 1192 /* .idClient = */ uClientID,1192 /* .idClient = */ idClient, 1193 1193 /* .idContext = */ VBOX_GUESTCTRL_CONTEXTID_MAKE_SESSION(uSessionID), 1194 1194 /* .uProtocol = */ pThread->StartupInfo.uProtocol, … … 1292 1292 /* Report final status. */ 1293 1293 Assert(uSessionStatus != GUEST_SESSION_NOTIFYTYPE_UNDEFINED); 1294 VBGLR3GUESTCTRLCMDCTX ctx = { uClientID, VBOX_GUESTCTRL_CONTEXTID_MAKE_SESSION(uSessionID) };1294 VBGLR3GUESTCTRLCMDCTX ctx = { idClient, VBOX_GUESTCTRL_CONTEXTID_MAKE_SESSION(uSessionID) }; 1295 1295 rc2 = VbglR3GuestCtrlSessionNotify(&ctx, uSessionStatus, uSessionRc); 1296 1296 if (RT_FAILURE(rc2)) 1297 1297 VGSvcError("Reporting session ID=%RU32 final status failed with rc=%Rrc\n", uSessionID, rc2); 1298 1298 1299 VbglR3GuestCtrlDisconnect( uClientID);1299 VbglR3GuestCtrlDisconnect(idClient); 1300 1300 1301 1301 VGSvcVerbose(3, "Session ID=%RU32 thread ended with rc=%Rrc\n", uSessionID, rc); … … 1304 1304 1305 1305 1306 /** 1307 * Main message handler for the guest control session process. 1308 * 1309 * @returns exit code. 1310 * @param pSession Pointer to g_Session. 1311 * @thread main. 1312 */ 1306 1313 static RTEXITCODE vgsvcGstCtrlSessionSpawnWorker(PVBOXSERVICECTRLSESSION pSession) 1307 1314 { 1308 1315 AssertPtrReturn(pSession, RTEXITCODE_FAILURE); 1309 1310 bool fSessionFilter = true;1311 1312 1316 VGSvcVerbose(0, "Hi, this is guest session ID=%RU32\n", pSession->StartupInfo.uSessionID); 1313 1317 1314 uint32_t uClientID; 1315 int rc = VbglR3GuestCtrlConnect(&uClientID); 1316 if (RT_SUCCESS(rc)) 1317 { 1318 /* Set session filter. This prevents the guest control host service from 1319 sending messages which belong to another session we don't want to handle. */ 1320 uint32_t uFilterAdd = VBOX_GUESTCTRL_FILTER_BY_SESSION(pSession->StartupInfo.uSessionID); 1321 rc = VbglR3GuestCtrlMsgFilterSet(uClientID, 1322 VBOX_GUESTCTRL_CONTEXTID_MAKE_SESSION(pSession->StartupInfo.uSessionID), 1323 uFilterAdd, 0 /* Filter remove */); 1324 VGSvcVerbose(3, "Setting message filterAdd=0x%x returned %Rrc\n", uFilterAdd, rc); 1325 1326 if ( RT_FAILURE(rc) 1327 && rc == VERR_NOT_SUPPORTED) 1328 { 1329 /* No session filter available. Skip. */ 1330 fSessionFilter = false; 1331 1332 rc = VINF_SUCCESS; 1333 } 1334 1335 VGSvcVerbose(1, "Using client ID=%RU32\n", uClientID); 1318 /* 1319 * Connect to the host service. 1320 */ 1321 uint32_t idClient; 1322 int rc = VbglR3GuestCtrlConnect(&idClient); 1323 if (RT_FAILURE(rc)) 1324 return VGSvcError("Error connecting to guest control service, rc=%Rrc\n", rc); 1325 1326 /* 1327 * Set session filter. This prevents the guest control host service from 1328 * sending messages which belong to another session we don't want to handle. 1329 * 1330 * Note! Earlier versions of this code would issue GUEST_SESSION_NOTIFYTYPE_STARTED 1331 * even if this failed, then shutdown after that. Since there was no 1332 * comments explain why, I (bird) assume is was an unintentional glitch. 1333 * 1334 * Note! There was also a fSessionFilter being set on VERR_NOT_SUPPORTED here 1335 * but since it wasn't use, I assume it was just a leftover from some 1336 * earlier workaround for host behaviour/whatever... 1337 */ 1338 uint32_t uFilterAdd = VBOX_GUESTCTRL_FILTER_BY_SESSION(pSession->StartupInfo.uSessionID); 1339 rc = VbglR3GuestCtrlMsgFilterSet(idClient, 1340 VBOX_GUESTCTRL_CONTEXTID_MAKE_SESSION(pSession->StartupInfo.uSessionID), 1341 uFilterAdd, 0 /* Filter remove */); 1342 VGSvcVerbose(3, "Setting message filterAdd=0x%x returned %Rrc\n", uFilterAdd, rc); 1343 if ( RT_SUCCESS(rc) 1344 || rc == VERR_NOT_SUPPORTED /* No session filter available. Ignore. */ ) 1345 { 1346 VGSvcVerbose(1, "Using client ID=%RU32\n", idClient); 1347 1348 /* 1349 * Report started status. 1350 * If session status cannot be posted to the host for some reason, bail out. 1351 */ 1352 VBGLR3GUESTCTRLCMDCTX ctx = { idClient, VBOX_GUESTCTRL_CONTEXTID_MAKE_SESSION(pSession->StartupInfo.uSessionID) }; 1353 rc = VbglR3GuestCtrlSessionNotify(&ctx, GUEST_SESSION_NOTIFYTYPE_STARTED, VINF_SUCCESS); 1354 if (RT_SUCCESS(rc)) 1355 { 1356 /* 1357 * Allocate a scratch buffer for commands which also send payload data with them. 1358 */ 1359 /** @todo Make buffer size configurable via guest properties/argv! */ 1360 uint32_t cbScratchBuf = _64K; 1361 Assert(RT_IS_POWER_OF_TWO(cbScratchBuf)); /** @todo r=bird: No idea why this needs to be the case... */ 1362 uint8_t *pvScratchBuf = (uint8_t *)RTMemAlloc(cbScratchBuf); 1363 if (pvScratchBuf) 1364 { 1365 /* 1366 * Message processing loop. 1367 */ 1368 VBGLR3GUESTCTRLCMDCTX CtxHost = { idClient, 0 /* Context ID */, pSession->StartupInfo.uProtocol, 0 }; 1369 for (;;) 1370 { 1371 VGSvcVerbose(3, "Waiting for host msg ...\n"); 1372 uint32_t uMsg = 0; 1373 uint32_t cParms = 0; 1374 rc = VbglR3GuestCtrlMsgWaitFor(idClient, &uMsg, &cParms); 1375 if ( RT_SUCCESS(rc) 1376 || rc == VERR_TOO_MUCH_DATA) 1377 { 1378 VGSvcVerbose(4, "Msg=%RU32 (%RU32 parms) retrieved (%Rrc)\n", uMsg, cParms, rc); 1379 1380 /* 1381 * Set number of parameters for current host context and pass it on to the session handler. 1382 * Note! Only when handling HOST_SESSION_CLOSE is the rc used. 1383 */ 1384 CtxHost.uNumParms = cParms; 1385 bool fShutdown = false; 1386 rc = VGSvcGstCtrlSessionHandler(pSession, uMsg, &CtxHost, pvScratchBuf, cbScratchBuf, &fShutdown); 1387 if (fShutdown) 1388 break; 1389 } 1390 else /** @todo Shouldn't we have a plan for handling connection loss and such? Now, we'll just spin like crazy. */ 1391 VGSvcVerbose(3, "Getting host message failed with %Rrc\n", rc); /* VERR_GEN_IO_FAILURE seems to be normal if ran into timeout. */ 1392 1393 /* Let others run (guests are often single CPU) ... */ 1394 RTThreadYield(); 1395 } 1396 1397 /* 1398 * Shutdown. 1399 */ 1400 RTMemFree(pvScratchBuf); 1401 } 1402 else 1403 rc = VERR_NO_MEMORY; 1404 1405 VGSvcVerbose(0, "Session %RU32 ended\n", pSession->StartupInfo.uSessionID); 1406 } 1407 else 1408 VGSvcError("Reporting session ID=%RU32 started status failed with rc=%Rrc\n", pSession->StartupInfo.uSessionID, rc); 1336 1409 } 1337 1410 else 1338 { 1339 VGSvcError("Error connecting to guest control service, rc=%Rrc\n", rc); 1340 return RTEXITCODE_FAILURE; 1341 } 1342 1343 /* Report started status. */ 1344 VBGLR3GUESTCTRLCMDCTX ctx = { uClientID, VBOX_GUESTCTRL_CONTEXTID_MAKE_SESSION(pSession->StartupInfo.uSessionID) }; 1345 int rc2 = VbglR3GuestCtrlSessionNotify(&ctx, GUEST_SESSION_NOTIFYTYPE_STARTED, VINF_SUCCESS); 1346 if (RT_FAILURE(rc2)) 1347 { 1348 VGSvcError("Reporting session ID=%RU32 started status failed with rc=%Rrc\n", pSession->StartupInfo.uSessionID, rc2); 1349 1350 /* 1351 * If session status cannot be posted to the host for 1352 * some reason, bail out. 1353 */ 1354 if (RT_SUCCESS(rc)) 1355 rc = rc2; 1356 } 1357 1358 /* Allocate a scratch buffer for commands which also send 1359 * payload data with them. */ 1360 uint32_t cbScratchBuf = _64K; /** @todo Make buffer size configurable via guest properties/argv! */ 1361 AssertReturn(RT_IS_POWER_OF_TWO(cbScratchBuf), RTEXITCODE_FAILURE); 1362 uint8_t *pvScratchBuf = NULL; 1363 if (RT_SUCCESS(rc)) 1364 { 1365 pvScratchBuf = (uint8_t *)RTMemAlloc(cbScratchBuf); 1366 if (!pvScratchBuf) 1367 rc = VERR_NO_MEMORY; 1368 } 1369 1370 if (RT_SUCCESS(rc)) 1371 { 1372 bool fShutdown = false; 1373 1374 VBGLR3GUESTCTRLCMDCTX ctxHost = { uClientID, 0 /* Context ID */, pSession->StartupInfo.uProtocol }; 1375 for (;;) 1376 { 1377 VGSvcVerbose(3, "Waiting for host msg ...\n"); 1378 uint32_t uMsg = 0; 1379 uint32_t cParms = 0; 1380 rc = VbglR3GuestCtrlMsgWaitFor(uClientID, &uMsg, &cParms); 1381 if ( rc == VINF_SUCCESS 1382 || rc == VERR_TOO_MUCH_DATA) 1383 { 1384 VGSvcVerbose(4, "Msg=%RU32 (%RU32 parms) retrieved (%Rrc)\n", uMsg, cParms, rc); 1385 1386 /* Set number of parameters for current host context and pass it on to the 1387 session handler. 1388 Note! Only when handling HOST_SESSION_CLOSE is the rc used. */ 1389 ctxHost.uNumParms = cParms; 1390 rc = VGSvcGstCtrlSessionHandler(pSession, uMsg, &ctxHost, pvScratchBuf, cbScratchBuf, &fShutdown); 1391 if (fShutdown) 1392 break; 1393 } 1394 else if (RT_FAILURE(rc)) 1395 VGSvcVerbose(3, "Getting host message failed with %Rrc\n", rc); /* VERR_GEN_IO_FAILURE seems to be normal if ran into timeout. */ 1396 1397 /* Let others run ... */ 1398 RTThreadYield(); 1399 } 1400 } 1401 1402 VGSvcVerbose(0, "Session %RU32 ended\n", pSession->StartupInfo.uSessionID); 1403 1404 if (pvScratchBuf) 1405 RTMemFree(pvScratchBuf); 1406 1407 if (uClientID) 1408 { 1409 VGSvcVerbose(3, "Disconnecting client ID=%RU32 ...\n", uClientID); 1410 VbglR3GuestCtrlDisconnect(uClientID); 1411 } 1411 VGSvcError("Setting message filterAdd=0x%x failed with rc=%Rrc\n", pSession->StartupInfo.uSessionID, rc); 1412 1413 VGSvcVerbose(3, "Disconnecting client ID=%RU32 ...\n", idClient); 1414 VbglR3GuestCtrlDisconnect(idClient); 1412 1415 1413 1416 VGSvcVerbose(3, "Session worker returned with rc=%Rrc\n", rc);
Note:
See TracChangeset
for help on using the changeset viewer.

