Changeset 31296 in vbox for trunk/src/VBox/Main/HostImpl.cpp
- Timestamp:
- Aug 2, 2010 1:13:14 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/HostImpl.cpp
r30764 r31296 155 155 { 156 156 Data() 157 : 157 158 #ifdef VBOX_WITH_USB 158 : usbListsLock(LOCKCLASS_USBLIST)159 usbListsLock(LOCKCLASS_USBLIST), 159 160 #endif 161 fDVDDrivesListBuilt(false), 162 fFloppyDrivesListBuilt(false) 160 163 {}; 161 164 … … 171 174 USBProxyService *pUSBProxyService; 172 175 #endif /* VBOX_WITH_USB */ 176 177 // list of host drives; lazily created by getDVDDrives() and getFloppyDrives() 178 MediaList llDVDDrives, 179 llFloppyDrives; 180 bool fDVDDrivesListBuilt, 181 fFloppyDrivesListBuilt; 173 182 174 183 #if defined(RT_OS_LINUX) || defined(RT_OS_FREEBSD) … … 409 418 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 410 419 411 MediaList list;412 HRESULT rc = getD VDDrives(list);420 MediaList *pList; 421 HRESULT rc = getDrives(DeviceType_DVD, true /* fRefresh */, pList); 413 422 if (SUCCEEDED(rc)) 414 423 { 415 SafeIfaceArray<IMedium> array( list);424 SafeIfaceArray<IMedium> array(*pList); 416 425 array.detachTo(ComSafeArrayOutArg(aDrives)); 417 426 } … … 435 444 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 436 445 437 MediaList list;438 HRESULT rc = get FloppyDrives(list);446 MediaList *pList; 447 HRESULT rc = getDrives(DeviceType_Floppy, true /* fRefresh */, pList); 439 448 if (SUCCEEDED(rc)) 440 449 { 441 SafeIfaceArray<IMedium> collection( list);450 SafeIfaceArray<IMedium> collection(*pList); 442 451 collection.detachTo(ComSafeArrayOutArg(aDrives)); 443 452 } … … 1510 1519 } 1511 1520 1512 HRESULT Host::getDVDDrives(MediaList &list) 1521 /** 1522 * Sets the given pointer to point to the static list of DVD or floppy 1523 * drives in the Host instance data, depending on the @a mediumType 1524 * parameter. 1525 * 1526 * This builds the list on the first call; it adds or removes host drives 1527 * that may have changed if fRefresh == true. 1528 * 1529 * The caller must hold the Host write lock before calling this. 1530 * To protect the list to which the caller's pointer points, the caller 1531 * must also hold the Host lock. 1532 * 1533 * @param mediumType Must be DeviceType_Floppy or DeviceType_DVD. 1534 * @param fRefresh Whether to refresh the host drives list even if this is not the first call. 1535 * @param pll Caller's pointer which gets set to the static list of host drives. 1536 * @return 1537 */ 1538 HRESULT Host::getDrives(DeviceType_T mediumType, 1539 bool fRefresh, 1540 MediaList *&pll) 1541 { 1542 HRESULT rc = S_OK; 1543 Assert(isWriteLockOnCurrentThread()); 1544 1545 MediaList llNew; 1546 MediaList *pllCached; 1547 bool *pfListBuilt = NULL; 1548 1549 switch (mediumType) 1550 { 1551 case DeviceType_DVD: 1552 if (!m->fDVDDrivesListBuilt || fRefresh) 1553 { 1554 rc = buildDVDDrivesList(llNew); 1555 if (FAILED(rc)) 1556 return rc; 1557 pfListBuilt = &m->fDVDDrivesListBuilt; 1558 } 1559 pllCached = &m->llDVDDrives; 1560 break; 1561 1562 case DeviceType_Floppy: 1563 if (!m->fFloppyDrivesListBuilt || fRefresh) 1564 { 1565 rc = buildFloppyDrivesList(llNew); 1566 if (FAILED(rc)) 1567 return rc; 1568 pfListBuilt = &m->fFloppyDrivesListBuilt; 1569 } 1570 pllCached = &m->llFloppyDrives; 1571 break; 1572 1573 default: 1574 return E_INVALIDARG; 1575 } 1576 1577 if (pfListBuilt) 1578 { 1579 // a list was built in llNew above: 1580 if (!*pfListBuilt) 1581 { 1582 // this was the first call (instance bool is still false): then just copy the whole list and return 1583 *pllCached = llNew; 1584 // and mark the instance data as "built" 1585 *pfListBuilt = true; 1586 } 1587 else 1588 { 1589 // list was built, and this was a subsequent call: then compare the old and the new lists 1590 1591 // remove drives from the cached list which are no longer present 1592 for (MediaList::iterator itCached = pllCached->begin(); 1593 itCached != pllCached->end(); 1594 ++itCached) 1595 { 1596 Medium *pCached = *itCached; 1597 const Utf8Str strLocationCached = pCached->getLocation(); 1598 bool fFound = false; 1599 for (MediaList::iterator itNew = llNew.begin(); 1600 itNew != llNew.end(); 1601 ++itNew) 1602 { 1603 Medium *pNew = *itNew; 1604 const Utf8Str strLocationNew = pNew->getLocation(); 1605 if (strLocationNew == strLocationCached) 1606 { 1607 fFound = true; 1608 break; 1609 } 1610 } 1611 if (!fFound) 1612 itCached = pllCached->erase(itCached); 1613 } 1614 1615 // add drives to the cached list that are not on there yet 1616 for (MediaList::iterator itNew = llNew.begin(); 1617 itNew != llNew.end(); 1618 ++itNew) 1619 { 1620 Medium *pNew = *itNew; 1621 const Utf8Str strLocationNew = pNew->getLocation(); 1622 bool fFound = false; 1623 for (MediaList::iterator itCached = pllCached->begin(); 1624 itCached != pllCached->end(); 1625 ++itCached) 1626 { 1627 Medium *pCached = *itCached; 1628 const Utf8Str strLocationCached = pCached->getLocation(); 1629 if (strLocationNew == strLocationCached) 1630 { 1631 fFound = true; 1632 break; 1633 } 1634 } 1635 1636 if (!fFound) 1637 pllCached->push_back(pNew); 1638 } 1639 } 1640 } 1641 1642 // return cached list to caller 1643 pll = pllCached; 1644 1645 return rc; 1646 } 1647 1648 /** 1649 * Goes through the list of host drives that would be returned by getDrives() 1650 * and looks for a host drive with the given UUID. If found, it sets pMedium 1651 * to that drive; otherwise returns VBOX_E_OBJECT_NOT_FOUND. 1652 * @param mediumType Must be DeviceType_DVD or DeviceType_Floppy. 1653 * @param uuid Medium UUID of host drive to look for. 1654 * @param fRefresh Whether to refresh the host drives list (see getDrives()) 1655 * @param pMedium Medium object, if found… 1656 * @return VBOX_E_OBJECT_NOT_FOUND if not found, or S_OK if found, or errors from getDrives(). 1657 */ 1658 HRESULT Host::findHostDrive(DeviceType_T mediumType, 1659 const Guid &uuid, 1660 bool fRefresh, 1661 ComObjPtr<Medium> &pMedium) 1662 { 1663 MediaList *pllMedia; 1664 1665 AutoWriteLock wlock(this COMMA_LOCKVAL_SRC_POS); 1666 HRESULT rc = getDrives(mediumType, fRefresh, pllMedia); 1667 if (SUCCEEDED(rc)) 1668 { 1669 for (MediaList::iterator it = pllMedia->begin(); 1670 it != pllMedia->end(); 1671 ++it) 1672 { 1673 Medium *pThis = *it; 1674 if (pThis->getId() == uuid) 1675 { 1676 pMedium = pThis; 1677 return S_OK; 1678 } 1679 } 1680 } 1681 1682 return VBOX_E_OBJECT_NOT_FOUND; 1683 } 1684 1685 /** 1686 * Called from getDrives() to build the DVD drives list. 1687 * @param pll 1688 * @return 1689 */ 1690 HRESULT Host::buildDVDDrivesList(MediaList &list) 1513 1691 { 1514 1692 HRESULT rc = S_OK; … … 1623 1801 1624 1802 /** 1625 * Internal implementation for COMGETTER(FloppyDrives) which can be called 1626 * from elsewhere. Caller must hold the Host object write lock! 1803 * Called from getDrives() to build the floppy drives list. 1627 1804 * @param list 1628 1805 * @return 1629 1806 */ 1630 HRESULT Host:: getFloppyDrives(MediaList &list)1807 HRESULT Host::buildFloppyDrivesList(MediaList &list) 1631 1808 { 1632 1809 HRESULT rc = S_OK;
Note:
See TracChangeset
for help on using the changeset viewer.