- Timestamp:
- Sep 12, 2008 5:37:42 PM (16 years ago)
- Location:
- trunk/src/VBox/Main
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/HostImpl.cpp
r12400 r12439 80 80 # include <shlobj.h> 81 81 # include <cfgmgr32.h> 82 83 # ifdef VBOX_WITH_NETFLT 84 85 # endif /* VBOX_WITH_NETFLT */ 86 #include <Netcfgn.h> 82 87 #endif /* RT_OS_WINDOWS */ 83 88 … … 1150 1155 return rc; 1151 1156 } 1157 1158 # ifdef VBOX_WITH_NETFLT 1159 1160 #define VBOX_NETCFG_LOCK_TIME_OUT 5000 1161 1162 /*TODO: should use some real VBox app name */ 1163 #define VBOX_NETCFG_APP_NAME L"VirtualBox" 1164 1165 /* 1166 * Release reference 1167 */ 1168 static VOID vboxNetCfgWinReleaseRef (IN IUnknown* punk) 1169 { 1170 if(punk) 1171 { 1172 punk->Release(); 1173 } 1174 1175 return; 1176 } 1177 1178 /* 1179 * Get a reference to INetCfg. 1180 * 1181 * fGetWriteLock [in] If TRUE, Write lock.requested. 1182 * lpszAppName [in] Application name requesting the reference. 1183 * ppnc [out] Reference to INetCfg. 1184 * lpszLockedBy [in] Optional. Application who holds the write lock. 1185 * 1186 * Returns: S_OK on sucess, otherwise an error code. 1187 */ 1188 static HRESULT vboxNetCfgWinQueryINetCfg (IN BOOL fGetWriteLock, 1189 IN LPCWSTR lpszAppName, 1190 OUT INetCfg** ppnc, 1191 OUT LPWSTR *lpszLockedBy) 1192 { 1193 INetCfg *pnc = NULL; 1194 INetCfgLock *pncLock = NULL; 1195 HRESULT hr = S_OK; 1196 1197 /* 1198 * Initialize the output parameters. 1199 */ 1200 *ppnc = NULL; 1201 1202 if ( lpszLockedBy ) 1203 { 1204 *lpszLockedBy = NULL; 1205 } 1206 /* 1207 * Initialize COM 1208 */ 1209 hr = CoInitialize( NULL ); 1210 1211 if ( hr == S_OK ) 1212 { 1213 1214 /* 1215 * Create the object implementing INetCfg. 1216 */ 1217 hr = CoCreateInstance( CLSID_CNetCfg, 1218 NULL, CLSCTX_INPROC_SERVER, 1219 IID_INetCfg, 1220 (void**)&pnc ); 1221 if ( hr == S_OK ) 1222 { 1223 1224 if ( fGetWriteLock ) 1225 { 1226 1227 /* 1228 * Get the locking reference 1229 */ 1230 hr = pnc->QueryInterface( IID_INetCfgLock, 1231 (LPVOID *)&pncLock ); 1232 if ( hr == S_OK ) 1233 { 1234 1235 /* 1236 * Attempt to lock the INetCfg for read/write 1237 */ 1238 hr = pncLock->AcquireWriteLock( VBOX_NETCFG_LOCK_TIME_OUT, 1239 lpszAppName, 1240 lpszLockedBy); 1241 if (hr == S_FALSE ) 1242 { 1243 hr = NETCFG_E_NO_WRITE_LOCK; 1244 } 1245 } 1246 } 1247 1248 if ( hr == S_OK ) 1249 { 1250 1251 /* 1252 * Initialize the INetCfg object. 1253 */ 1254 hr = pnc->Initialize( NULL ); 1255 1256 if ( hr == S_OK ) 1257 { 1258 *ppnc = pnc; 1259 pnc->AddRef(); 1260 } 1261 else 1262 { 1263 1264 /* 1265 * Initialize failed, if obtained lock, release it 1266 */ 1267 if ( pncLock ) 1268 { 1269 pncLock->ReleaseWriteLock(); 1270 } 1271 } 1272 } 1273 1274 vboxNetCfgWinReleaseRef( pncLock ); 1275 vboxNetCfgWinReleaseRef( pnc ); 1276 } 1277 1278 /* 1279 * In case of error, uninitialize COM. 1280 */ 1281 if ( hr != S_OK ) 1282 { 1283 CoUninitialize(); 1284 } 1285 } 1286 1287 return hr; 1288 } 1289 1290 /* 1291 * Get a reference to INetCfg. 1292 * 1293 * pnc [in] Reference to INetCfg to release. 1294 * fHasWriteLock [in] If TRUE, reference was held with write lock. 1295 * 1296 * Returns: S_OK on sucess, otherwise an error code. 1297 * 1298 */ 1299 static HRESULT vboxNetCfgWinReleaseINetCfg (IN INetCfg* pnc, 1300 IN BOOL fHasWriteLock) 1301 { 1302 INetCfgLock *pncLock = NULL; 1303 HRESULT hr = S_OK; 1304 1305 /* 1306 * Uninitialize INetCfg 1307 */ 1308 hr = pnc->Uninitialize(); 1309 1310 /* 1311 * If write lock is present, unlock it 1312 */ 1313 if ( hr == S_OK && fHasWriteLock ) 1314 { 1315 1316 /* 1317 * Get the locking reference 1318 */ 1319 hr = pnc->QueryInterface( IID_INetCfgLock, 1320 (LPVOID *)&pncLock); 1321 if ( hr == S_OK ) 1322 { 1323 hr = pncLock->ReleaseWriteLock(); 1324 vboxNetCfgWinReleaseRef( pncLock ); 1325 } 1326 } 1327 1328 vboxNetCfgWinReleaseRef( pnc ); 1329 1330 /* 1331 * Uninitialize COM. 1332 */ 1333 CoUninitialize(); 1334 1335 return hr; 1336 } 1337 1338 /* 1339 * Get network component enumerator reference. 1340 * 1341 * Arguments: 1342 * pnc [in] Reference to INetCfg. 1343 * pguidClass [in] Class GUID of the network component. 1344 * ppencc [out] Enumerator reference. 1345 * 1346 * Returns: S_OK on sucess, otherwise an error code. 1347 */ 1348 static HRESULT vboxNetCfgWinGetComponentEnum (INetCfg* pnc, 1349 IN const GUID* pguidClass, 1350 OUT IEnumNetCfgComponent **ppencc) 1351 { 1352 INetCfgClass *pncclass; 1353 HRESULT hr; 1354 1355 *ppencc = NULL; 1356 1357 /* 1358 * Get the class reference. 1359 */ 1360 hr = pnc->QueryNetCfgClass( pguidClass, 1361 IID_INetCfgClass, 1362 (PVOID *)&pncclass ); 1363 1364 if ( hr == S_OK ) 1365 { 1366 1367 /* 1368 * Get the enumerator reference. 1369 */ 1370 hr = pncclass->EnumComponents( ppencc ); 1371 1372 /* 1373 * We don't need the class reference any more. 1374 */ 1375 vboxNetCfgWinReleaseRef( pncclass ); 1376 } 1377 1378 return hr; 1379 } 1380 1381 /* 1382 * Enumerates the first network component. 1383 * 1384 * Arguments: 1385 * pencc [in] Component enumerator reference. 1386 * ppncc [out] Network component reference. 1387 * 1388 * Returns: S_OK on sucess, otherwise an error code. 1389 */ 1390 static HRESULT vboxNetCfgWinGetFirstComponent (IN IEnumNetCfgComponent* pencc, 1391 OUT INetCfgComponent **ppncc) 1392 { 1393 HRESULT hr; 1394 ULONG ulCount; 1395 1396 *ppncc = NULL; 1397 1398 pencc->Reset(); 1399 1400 hr = pencc->Next( 1, 1401 ppncc, 1402 &ulCount ); 1403 return hr; 1404 } 1405 1406 /* 1407 * Enumerate the next network component. 1408 * 1409 * The function behaves just like vboxNetCfgWinGetFirstComponent if 1410 * it is called right after vboxNetCfgWinGetComponentEnum. 1411 * 1412 * Arguments: 1413 * pencc [in] Component enumerator reference. 1414 * ppncc [out] Network component reference. 1415 * 1416 * Returns: S_OK on sucess, otherwise an error code. 1417 */ 1418 static HRESULT vboxNetCfgWinGetNextComponent (IN IEnumNetCfgComponent* pencc, 1419 OUT INetCfgComponent **ppncc) 1420 { 1421 HRESULT hr; 1422 ULONG ulCount; 1423 1424 *ppncc = NULL; 1425 1426 hr = pencc->Next( 1, 1427 ppncc, 1428 &ulCount ); 1429 return hr; 1430 } 1431 1432 /* 1433 * Install a network component(protocols, clients and services) 1434 * given its INF file. 1435 * Arguments: 1436 * pnc [in] Reference to INetCfg. 1437 * lpszComponentId [in] PnpID of the network component. 1438 * pguidClass [in] Class GUID of the network component. 1439 * 1440 * Returns: S_OK on sucess, otherwise an error code. 1441 */ 1442 static HRESULT vboxNetCfgWinInstallComponent(IN INetCfg* pnc, 1443 IN LPCWSTR szComponentId, 1444 IN const GUID* pguidClass) 1445 { 1446 INetCfgClassSetup *pncClassSetup = NULL; 1447 INetCfgComponent *pncc = NULL; 1448 OBO_TOKEN OboToken; 1449 HRESULT hr = S_OK; 1450 1451 /* 1452 * OBO_TOKEN specifies on whose behalf this 1453 * component is being installed. 1454 * Set it to OBO_USER so that szComponentId will be installed 1455 * on behalf of the user. 1456 */ 1457 1458 ZeroMemory( &OboToken, 1459 sizeof(OboToken) ); 1460 OboToken.Type = OBO_USER; 1461 1462 /* 1463 * Get component's setup class reference. 1464 */ 1465 hr = pnc->QueryNetCfgClass ( pguidClass, 1466 IID_INetCfgClassSetup, 1467 (void**)&pncClassSetup ); 1468 if ( hr == S_OK ) { 1469 1470 hr = pncClassSetup->Install( szComponentId, 1471 &OboToken, 1472 0, 1473 0, /* Upgrade from build number. */ 1474 NULL, /* Answerfile name */ 1475 NULL, /* Answerfile section name */ 1476 &pncc ); /* Reference after the component */ 1477 if ( S_OK == hr ) { /* is installed. */ 1478 1479 /* 1480 * we don't need to use pncc (INetCfgComponent), release it 1481 */ 1482 vboxNetCfgWinReleaseRef( pncc ); 1483 } 1484 1485 vboxNetCfgWinReleaseRef( pncClassSetup ); 1486 } 1487 1488 return hr; 1489 } 1490 1491 /* 1492 * Install a network component(protocols, clients and services) 1493 * given its INF file. 1494 * 1495 * Arguments: 1496 * pnc [in] Reference to INetCfg. 1497 * lpszComponentId [in] PnpID of the network component. 1498 * pguidClass [in] Class GUID of the network component. 1499 * lpszInfFullPath [in] INF file to install from. 1500 * 1501 * Returns: S_OK on sucess, otherwise an error code. 1502 */ 1503 static HRESULT vboxNetCfgWinInstallNetComponent (IN INetCfg *pnc, 1504 IN LPCWSTR lpszComponentId, 1505 IN const GUID *pguidClass, 1506 IN LPCWSTR lpszInfFullPath) 1507 { 1508 DWORD dwError; 1509 HRESULT hr = S_OK; 1510 WCHAR Drive[_MAX_DRIVE]; 1511 WCHAR Dir[_MAX_DIR]; 1512 WCHAR DirWithDrive[_MAX_DRIVE+_MAX_DIR]; 1513 1514 /* 1515 * If full path to INF has been specified, the INF 1516 * needs to be copied using Setup API to ensure that any other files 1517 * that the primary INF copies will be correctly found by Setup API 1518 */ 1519 1520 if ( lpszInfFullPath ) 1521 { 1522 1523 /* 1524 * Get the path where the INF file is. 1525 */ 1526 _wsplitpath( lpszInfFullPath, Drive, Dir, NULL, NULL ); 1527 1528 wcscpy( DirWithDrive, Drive ); 1529 wcscat( DirWithDrive, Dir ); 1530 1531 /* 1532 * Copy the INF file and other files referenced in the INF file. 1533 */ 1534 if ( !SetupCopyOEMInfW(lpszInfFullPath, 1535 DirWithDrive, /* Other files are in the */ 1536 /* same dir. as primary INF */ 1537 SPOST_PATH, /* First param is path to INF */ 1538 0, /* Default copy style */ 1539 NULL, /* Name of the INF after */ 1540 /* it's copied to %windir%\inf */ 1541 0, /* Max buf. size for the above */ 1542 NULL, /* Required size if non-null */ 1543 NULL) ) /* Optionally get the filename */ 1544 /* part of Inf name after it is copied. */ 1545 { 1546 dwError = GetLastError(); 1547 1548 hr = HRESULT_FROM_WIN32( dwError ); 1549 } 1550 } 1551 1552 if ( S_OK == hr ) 1553 { 1554 1555 /* 1556 * Install the network component. 1557 */ 1558 hr = vboxNetCfgWinInstallComponent( pnc, 1559 lpszComponentId, 1560 pguidClass ); 1561 if ( hr == S_OK ) 1562 { 1563 1564 /* 1565 * On success, apply the changes 1566 */ 1567 hr = pnc->Apply(); 1568 } 1569 } 1570 1571 return hr; 1572 } 1573 1574 /* 1575 * List installed network components of specific class. 1576 * 1577 * Arguments: 1578 * hwndTree [in] Tree handle in which to list. 1579 * pguidClass [in] Class GUID of the network compoent class. 1580 * 1581 * Returns: None. 1582 */ 1583 static HRESULT vboxNetCfgWinQueryComponentInstalled(IN INetCfg *pnc, IN const GUID* pguidClass, IN LPWSTR pnpId, OUT bool * pResult) 1584 { 1585 IEnumNetCfgComponent *pencc; 1586 INetCfgComponent *pncc; 1587 HRESULT hr; 1588 LPWSTR lpszId; 1589 1590 1591 *pResult = false; 1592 1593 1594 /* 1595 * Get Component Enumerator Interface. 1596 */ 1597 hr = vboxNetCfgWinGetComponentEnum( pnc, 1598 pguidClass, 1599 &pencc ); 1600 if ( hr == S_OK ) 1601 { 1602 1603 hr = vboxNetCfgWinGetFirstComponent( pencc, &pncc ); 1604 1605 while( hr == S_OK ) 1606 { 1607 1608 hr = pncc->GetId( &lpszId ); 1609 1610 if ( hr == S_OK ) 1611 { 1612 if(!wcscmp(lpszId, pnpId)) 1613 { 1614 *pResult = true; 1615 vboxNetCfgWinReleaseRef( pncc ); 1616 break; 1617 } 1618 } 1619 1620 vboxNetCfgWinReleaseRef( pncc ); 1621 1622 hr = vboxNetCfgWinGetNextComponent( pencc, &pncc ); 1623 } 1624 1625 vboxNetCfgWinReleaseRef( pencc ); 1626 } 1627 else 1628 { 1629 Log(("Failed to get the network component enumerator.")); 1630 } 1631 1632 1633 return hr; 1634 } 1635 1636 /* 1637 * Install a network component from an INF file. 1638 * 1639 * Arguments: 1640 * lpszInfFile [in] INF file. 1641 * lpszPnpID [in] PnpID of the network component to install. 1642 * pguidClass [in] Class GUID of the network component. 1643 * 1644 * Returns: None. 1645 */ 1646 static HRESULT vboxNetCfgWinInstallSpecifiedComponent (LPWSTR lpszInfFile, 1647 LPWSTR lpszPnpID, 1648 const GUID *pguidClass, 1649 bool bForceInstall) 1650 { 1651 INetCfg *pnc; 1652 LPWSTR lpszApp; 1653 HRESULT hr; 1654 1655 hr = vboxNetCfgWinQueryINetCfg( TRUE, 1656 VBOX_NETCFG_APP_NAME, 1657 &pnc, 1658 &lpszApp ); 1659 1660 if ( hr == S_OK ) 1661 { 1662 bool bInstall = true; 1663 1664 if(!bForceInstall) 1665 { 1666 /* check if it is installed already */ 1667 bool bInstalled = false; 1668 hr = vboxNetCfgWinQueryComponentInstalled(pnc, pguidClass, lpszPnpID, &bInstalled); 1669 if(hr == S_OK && bInstalled) 1670 { 1671 /* no need to install */ 1672 bInstall = false; 1673 } 1674 } 1675 1676 if(bInstall) 1677 { 1678 /* 1679 * Install the network component. 1680 */ 1681 hr = vboxNetCfgWinInstallNetComponent( pnc, 1682 lpszPnpID, 1683 pguidClass, 1684 lpszInfFile ); 1685 if ( (hr == S_OK) || (hr == NETCFG_S_REBOOT) ) 1686 { 1687 1688 hr = pnc->Apply(); 1689 } 1690 else 1691 { 1692 if ( hr != HRESULT_FROM_WIN32(ERROR_CANCELLED) ) 1693 { 1694 Log(("Couldn't install the network component." )); 1695 } 1696 } 1697 1698 } 1699 vboxNetCfgWinReleaseINetCfg( pnc, 1700 TRUE ); 1701 } 1702 else 1703 { 1704 if ( (hr == NETCFG_E_NO_WRITE_LOCK) && lpszApp ) 1705 { 1706 Log(("%s currently holds the lock, try later.", lpszApp)); 1707 1708 CoTaskMemFree( lpszApp ); 1709 } 1710 else 1711 { 1712 Log(("Couldn't the get notify object interface.")); 1713 } 1714 } 1715 1716 return hr; 1717 } 1718 1719 /** 1720 * increments the reference to the netflt - to - aHostNetworkInterface binding reference count 1721 * the exec flow: 1722 * 1. if netflt is NOT installed currently - install it 1723 * 2. if the NetFlt is not bound to the specified adapter - bind it 1724 * 3. increase the binding reference count - 1725 */ 1726 STDMETHODIMP 1727 Host::NetFltAcquire (IHostNetworkInterface *aHostNetworkInterface, 1728 IProgress **aProgress) 1729 { 1730 HRESULT rc = S_OK; 1731 1732 /* TODO: encorporate with the VBoxSVC helper infastructure */ 1733 1734 return rc; 1735 } 1736 1737 /** 1738 * decrements the reference to the netflt - to - aHostNetworkInterface binding reference count 1739 */ 1740 STDMETHODIMP 1741 Host::NetFltRelease (IHostNetworkInterface *aHostNetworkInterface, 1742 IProgress **aProgress) 1743 { 1744 HRESULT rc = S_OK; 1745 1746 /* TODO: encorporate with the VBoxSVC helper infastructure */ 1747 1748 return rc; 1749 } 1750 # endif /*VBOX_WITH_NETFLT*/ 1152 1751 1153 1752 #endif /* RT_OS_WINDOWS */ -
trunk/src/VBox/Main/include/HostImpl.h
r11258 r12439 99 99 IHostNetworkInterface **aHostNetworkInterface, 100 100 IProgress **aProgress); 101 # ifdef VBOX_WITH_NETFLT 102 /* 103 * increments the reference to the netflt - to - aHostNetworkInterface binding reference count 104 * the exec flow: 105 * 1. if netflt is NOT installed currently - install it 106 * 2. if the NetFlt is not bound to the specified adapter - bind it 107 * 3. increase the binding reference count - 108 */ 109 STDMETHOD(NetFltAcquire) (IHostNetworkInterface *aHostNetworkInterface, 110 IProgress **aProgress); 111 112 /* 113 * decrements the reference to the netflt - to - aHostNetworkInterface binding reference count 114 */ 115 STDMETHOD(NetFltRelease) (IHostNetworkInterface *aHostNetworkInterface, 116 IProgress **aProgress); 117 # endif /*VBOX_WITH_NETFLT*/ 101 118 #endif 102 119 STDMETHOD(CreateUSBDeviceFilter) (INPTR BSTR aName, IHostUSBDeviceFilter **aFilter);
Note:
See TracChangeset
for help on using the changeset viewer.