Changeset 6981 in vbox for trunk/src/VBox/Main
- Timestamp:
- Feb 18, 2008 10:05:36 AM (17 years ago)
- svn:sync-xref-src-repo-rev:
- 28172
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/hgcm/HGCM.cpp
r6967 r6981 97 97 char *m_pszSvcName; 98 98 char *m_pszSvcLibrary; 99 99 100 100 RTLDRMOD m_hLdrMod; 101 101 PFNVBOXHGCMSVCLOAD m_pfnLoad; … … 107 107 108 108 uint32_t *m_paClientIds; 109 109 110 110 HGCMSVCEXTHANDLE m_hExtension; 111 111 … … 126 126 127 127 static DECLCALLBACK(void) svcHlpCallComplete (VBOXHGCMCALLHANDLE callHandle, int32_t rc); 128 128 static DECLCALLBACK(void) svcHlpDisconnectClient (void *pvInstance, uint32_t u32ClientId); 129 129 130 public: 130 131 … … 147 148 148 149 int CreateAndConnectClient (uint32_t *pu32ClientIdOut, uint32_t u32ClientIdIn); 149 int DisconnectClient (uint32_t u32ClientId );150 int DisconnectClient (uint32_t u32ClientId, bool fFromService); 150 151 151 152 int HostCall (uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM *paParms); … … 239 240 * If only library name is specified, then try to load it from: 240 241 * - RTPathAppPrivateArch 241 * - RTPathSharedLibs (legacy) 242 * - RTPathSharedLibs 243 * - default system LIBPATH. 242 244 */ 243 245 int rc = VINF_SUCCESS; 244 246 245 247 if (RTPathHavePath (pszName)) 246 248 { … … 250 252 else 251 253 { 254 if (strlen (pszName) >= RTPATH_MAX) 255 { 256 return VERR_FILENAME_TOO_LONG; 257 } 258 252 259 /* Try default locations. */ 253 260 char szBase[RTPATH_MAX]; 254 261 255 262 /* Get the appropriate base path. */ 256 263 int i; 257 for (i = 0; i < 2; i++)264 for (i = 0; i < 3; i++) 258 265 { 259 266 if (i == 0) … … 261 268 rc = RTPathAppPrivateArch(szBase, sizeof (szBase)); 262 269 } 263 else 270 else if (i == 1) 264 271 { 265 272 rc = RTPathSharedLibs(szBase, sizeof (szBase)); 266 273 } 267 274 else 275 { 276 szBase[0] = 0; 277 rc = VINF_SUCCESS; 278 } 279 268 280 if (RT_SUCCESS(rc)) 269 281 { 270 282 char szPath[RTPATH_MAX]; 271 283 272 284 /* szPath = pszBase + pszName */ 273 rc = RTPathAbsEx (szBase, pszName, szPath, sizeof (szPath)); 274 285 if (szBase[0] != 0) 286 { 287 rc = RTPathAbsEx (szBase, pszName, szPath, sizeof (szPath)); 288 } 289 else 290 { 291 strcpy (szPath, pszName); 292 } 293 275 294 if (RT_SUCCESS(rc)) 276 295 { 277 296 rc = RTLdrLoad (szPath, phLdrMod); 278 297 279 298 if (RT_SUCCESS(rc)) 280 299 { … … 286 305 } 287 306 } 288 307 289 308 return rc; 290 309 } … … 430 449 public: 431 450 HGCMMsgHeader () : pCmd (NULL), pHGCMPort (NULL) {}; 432 451 433 452 /* Command pointer/identifier. */ 434 453 PVBOXHGCMCMD pCmd; … … 501 520 case SVC_MSG_HOSTCALL: return new HGCMMsgHostCallSvc (); 502 521 case SVC_MSG_GUESTCALL: return new HGCMMsgCall (); 503 case SVC_MSG_LOADSTATE: 522 case SVC_MSG_LOADSTATE: 504 523 case SVC_MSG_SAVESTATE: return new HGCMMsgLoadSaveStateClient (); 505 524 case SVC_MSG_REGEXT: return new HGCMMsgSvcRegisterExtension (); … … 676 695 } 677 696 } break; 678 697 679 698 case SVC_MSG_REGEXT: 680 699 { … … 682 701 683 702 LogFlowFunc(("SVC_MSG_REGEXT handle = %p, pfn = %p\n", pMsg->handle, pMsg->pfnExtension)); 684 703 685 704 if (pSvc->m_hExtension) 686 705 { … … 697 716 rc = VERR_NOT_SUPPORTED; 698 717 } 699 718 700 719 if (VBOX_SUCCESS (rc)) 701 720 { … … 710 729 711 730 LogFlowFunc(("SVC_MSG_UNREGEXT handle = %p\n", pMsg->handle)); 712 731 713 732 if (pSvc->m_hExtension != pMsg->handle) 714 733 { … … 725 744 rc = VERR_NOT_SUPPORTED; 726 745 } 727 746 728 747 pSvc->m_hExtension = NULL; 729 748 } … … 753 772 if (pMsgCore->MsgId () == SVC_MSG_GUESTCALL) 754 773 { 755 /* Only call the completion for these messages. The helper 774 /* Only call the completion for these messages. The helper 756 775 * is called by the service, and the service does not get 757 776 * any other messages. … … 765 784 } 766 785 786 /* static */ DECLCALLBACK(void) HGCMService::svcHlpDisconnectClient (void *pvInstance, uint32_t u32ClientId) 787 { 788 HGCMService *pService = static_cast <HGCMService *> (pvInstance); 789 790 if (pService) 791 { 792 pService->DisconnectClient (u32ClientId, true); 793 } 794 } 795 767 796 static DECLCALLBACK(void) hgcmMsgCompletionCallback (int32_t result, HGCMMsgCore *pMsgCore) 768 797 { … … 803 832 RTStrFree (m_pszSvcLibrary); 804 833 m_pszSvcLibrary = NULL; 805 834 806 835 RTStrFree (m_pszSvcName); 807 836 m_pszSvcName = NULL; 808 837 809 838 rc = VERR_NO_MEMORY; 810 839 } … … 812 841 { 813 842 /* Initialize service helpers table. */ 814 m_svcHelpers.pfnCallComplete = svcHlpCallComplete; 815 m_svcHelpers.pvInstance = this; 816 843 m_svcHelpers.pfnCallComplete = svcHlpCallComplete; 844 m_svcHelpers.pvInstance = this; 845 m_svcHelpers.pfnDisconnectClient = svcHlpDisconnectClient; 846 817 847 /* Execute the load request on the service thread. */ 818 848 HGCMMSGHANDLE hMsg; … … 924 954 HGCMService *pSvc; 925 955 int rc = HGCMService::ResolveService (&pSvc, pszServiceName); 926 956 927 957 if (VBOX_SUCCESS (rc)) 928 958 { … … 950 980 pSvc->m_pSvcNext = sm_pSvcListHead; 951 981 pSvc->m_pSvcPrev = NULL; 952 982 953 983 if (sm_pSvcListHead) 954 984 { … … 1079 1109 ASMAtomicIncU32 (&m_u32RefCnt); 1080 1110 LogFlowFunc(("m_u32RefCnt = %d\n", m_u32RefCnt)); 1081 } 1111 } 1082 1112 1083 1113 /** The method dereferences a service and deletes it when no more refs. … … 1116 1146 { 1117 1147 LogFlowFunc(("handle %d\n", pSvc->m_paClientIds[0])); 1118 pSvc->DisconnectClient (pSvc->m_paClientIds[0] );1148 pSvc->DisconnectClient (pSvc->m_paClientIds[0], false); 1119 1149 } 1120 1150 … … 1138 1168 1139 1169 LogFlowFunc(("%d services to be saved:\n", sm_cServices)); 1140 1170 1141 1171 /* Save number of services. */ 1142 1172 rc = SSMR3PutU32(pSSM, sm_cServices); … … 1210 1240 rc = SSMR3GetU32(pSSM, &cServices); 1211 1241 AssertRCReturn(rc, rc); 1212 1242 1213 1243 LogFlowFunc(("%d services to be restored:\n", cServices)); 1214 1244 … … 1219 1249 AssertRCReturn(rc, rc); 1220 1250 AssertReturn(u32 <= VBOX_HGCM_SVC_NAME_MAX_BYTES, VERR_SSM_UNEXPECTED_DATA); 1221 1251 1222 1252 char *pszServiceName = (char *)alloca (u32); 1223 1253 … … 1225 1255 rc = SSMR3GetStrZ(pSSM, pszServiceName, u32); 1226 1256 AssertRCReturn(rc, rc); 1227 1257 1228 1258 LogFlowFunc(("Restoring service [%s]\n", pszServiceName)); 1229 1259 1230 1260 /* Resolve the service instance. */ 1231 HGCMService *pSvc; 1261 HGCMService *pSvc; 1232 1262 rc = ResolveService (&pSvc, pszServiceName); 1233 1263 AssertReturn(pSvc, VERR_SSM_UNEXPECTED_DATA); 1234 1264 1235 1265 /* Get the number of clients. */ 1236 1266 uint32_t cClients; … … 1301 1331 1302 1332 uint32_t handle; 1303 1333 1304 1334 if (pu32ClientIdOut != NULL) 1305 1335 { … … 1335 1365 1336 1366 rc = hgcmMsgSend (hMsg); 1337 1367 1338 1368 if (VBOX_SUCCESS (rc)) 1339 1369 { … … 1345 1375 m_cClientsAllocated += 64; 1346 1376 } 1347 1377 1348 1378 m_paClientIds[m_cClients] = handle; 1349 1379 m_cClients++; … … 1365 1395 ReferenceService (); 1366 1396 } 1367 1397 1368 1398 LogFlowFunc(("rc = %Vrc\n", rc)); 1369 1399 return rc; … … 1375 1405 * @return VBox rc. 1376 1406 */ 1377 int HGCMService::DisconnectClient (uint32_t u32ClientId) 1378 { 1379 LogFlowFunc(("client id = %d\n", u32ClientId)); 1380 1381 /* Call the service. */ 1382 HGCMMSGHANDLE hMsg; 1383 1384 int rc = hgcmMsgAlloc (m_thread, &hMsg, SVC_MSG_DISCONNECT, hgcmMessageAllocSvc); 1385 1386 if (VBOX_SUCCESS(rc)) 1387 { 1388 HGCMMsgSvcDisconnect *pMsg = (HGCMMsgSvcDisconnect *)hgcmObjReference (hMsg, HGCMOBJ_MSG); 1389 AssertRelease(pMsg); 1390 1391 pMsg->u32ClientId = u32ClientId; 1392 1393 hgcmObjDereference (pMsg); 1394 1395 rc = hgcmMsgSend (hMsg); 1396 1407 int HGCMService::DisconnectClient (uint32_t u32ClientId, bool fFromService) 1408 { 1409 int rc = VINF_SUCCESS; 1410 1411 LogFlowFunc(("client id = %d, fFromService = %d\n", u32ClientId, fFromService)); 1412 1413 if (!fFromService) 1414 { 1415 /* Call the service. */ 1416 HGCMMSGHANDLE hMsg; 1417 1418 rc = hgcmMsgAlloc (m_thread, &hMsg, SVC_MSG_DISCONNECT, hgcmMessageAllocSvc); 1419 1420 if (VBOX_SUCCESS(rc)) 1421 { 1422 HGCMMsgSvcDisconnect *pMsg = (HGCMMsgSvcDisconnect *)hgcmObjReference (hMsg, HGCMOBJ_MSG); 1423 AssertRelease(pMsg); 1424 1425 pMsg->u32ClientId = u32ClientId; 1426 1427 hgcmObjDereference (pMsg); 1428 1429 rc = hgcmMsgSend (hMsg); 1430 } 1431 } 1432 1433 if (VBOX_SUCCESS (rc)) 1434 { 1397 1435 /* Remove the client id from the array in any case. */ 1398 1436 int i; … … 1403 1441 { 1404 1442 m_cClients--; 1405 1443 1406 1444 if (m_cClients > i) 1407 1445 { 1408 1446 memmove (&m_paClientIds[i], &m_paClientIds[i + 1], m_cClients - i); 1409 1447 } 1410 1448 1411 1449 break; 1412 1450 } … … 1552 1590 1553 1591 1554 /* 1592 /* 1555 1593 * Main HGCM thread that manages services. 1556 1594 */ 1557 1595 1558 1596 /* Messages processed by the main HGCM thread. */ 1559 1597 #define HGCM_MSG_CONNECT (10) /* Connect a client to a service. */ … … 1649 1687 case HGCM_MSG_LOAD: return new HGCMMsgMainLoad (); 1650 1688 case HGCM_MSG_HOSTCALL: return new HGCMMsgMainHostCall (); 1651 case HGCM_MSG_LOADSTATE: 1689 case HGCM_MSG_LOADSTATE: 1652 1690 case HGCM_MSG_SAVESTATE: return new HGCMMsgMainLoadSaveState (); 1653 1691 case HGCM_MSG_RESET: return new HGCMMsgMainReset (); … … 1730 1768 1731 1769 /* Call the service instance to disconnect the client. */ 1732 rc = pService->DisconnectClient (pMsg->u32ClientId );1770 rc = pService->DisconnectClient (pMsg->u32ClientId, false); 1733 1771 1734 1772 hgcmObjDereference (pClient); … … 1801 1839 { 1802 1840 HGCMMsgMainRegisterExtension *pMsg = (HGCMMsgMainRegisterExtension *)pMsgCore; 1803 1841 1804 1842 LogFlowFunc(("HGCM_MSG_REGEXT\n")); 1805 1843 1806 1844 /* Allocate the handle data. */ 1807 1845 HGCMSVCEXTHANDLE handle = (HGCMSVCEXTHANDLE)RTMemAllocZ (sizeof (struct _HGCMSVCEXTHANDLEDATA) 1808 1846 + strlen (pMsg->pszServiceName) 1809 1847 + sizeof (char)); 1810 1848 1811 1849 if (handle == NULL) 1812 1850 { … … 1817 1855 handle->pszServiceName = (char *)((uint8_t *)handle + sizeof (struct _HGCMSVCEXTHANDLEDATA)); 1818 1856 strcpy (handle->pszServiceName, pMsg->pszServiceName); 1819 1857 1820 1858 HGCMService *pService; 1821 1859 rc = HGCMService::ResolveService (&pService, handle->pszServiceName); … … 1827 1865 pService->ReleaseService (); 1828 1866 } 1829 1867 1830 1868 if (VBOX_FAILURE (rc)) 1831 1869 { … … 1854 1892 pService->ReleaseService (); 1855 1893 } 1856 1894 1857 1895 RTMemFree (pMsg->handle); 1858 1896 } break; … … 2219 2257 HGCMMsgMainHostCall *pMsg = (HGCMMsgMainHostCall *)hgcmObjReference (hMsg, HGCMOBJ_MSG); 2220 2258 AssertRelease(pMsg); 2221 2259 2222 2260 pMsg->pszServiceName = (char *)pszServiceName; 2223 2261 pMsg->u32Function = u32Function; … … 2237 2275 { 2238 2276 LogFlowFunc(("\n")); 2239 2277 2240 2278 /* Disconnect all clients. 2241 2279 */
Note:
See TracChangeset
for help on using the changeset viewer.