1538
1551
# ifdef VBOX_USE_LIBHAL
1539
1552
if (!getDVDInfoFromHal(list))
1541
// Not all Solaris versions ship with libhal.
1542
// So use a fallback approach similar to Linux.
1544
if (RTEnvExistEx(RTENV_DEFAULT, "VBOX_CDROM"))
1546
char *cdromEnv = RTEnvDupEx(RTENV_DEFAULT, "VBOX_CDROM");
1547
char *saveStr = NULL;
1548
char *cdromDrive = NULL;
1550
cdromDrive = strtok_r(cdromEnv, ":", &saveStr);
1553
if (validateDevice(cdromDrive, true))
1555
ComObjPtr<Medium> hostDVDDriveObj;
1556
hostDVDDriveObj.createObject();
1557
hostDVDDriveObj->init(m->pParent, DeviceType_DVD, Bstr(cdromDrive));
1558
list.push_back(hostDVDDriveObj);
1560
cdromDrive = strtok_r(NULL, ":", &saveStr);
1562
RTStrFree(cdromEnv);
1566
// this might work on Solaris version older than Nevada.
1567
if (validateDevice("/cdrom/cdrom0", true))
1569
ComObjPtr<Medium> hostDVDDriveObj;
1570
hostDVDDriveObj.createObject();
1571
hostDVDDriveObj->init(m->pParent, DeviceType_DVD, Bstr("cdrom/cdrom0"));
1572
list.push_back(hostDVDDriveObj);
1575
// check the mounted drives
1576
parseMountTable(MNTTAB, list);
1555
getDVDInfoFromDevTree(list);
1580
1558
#elif defined(RT_OS_LINUX) || defined(RT_OS_FREEBSD)
1793
1771
////////////////////////////////////////////////////////////////////////////////
1795
1773
#if defined(RT_OS_SOLARIS) && defined(VBOX_USE_LIBHAL)
1776
* Helper function to get the slice number from a device path
1778
* @param pszDevLinkPath Pointer to a device path (/dev/(r)dsk/c7d1t0d0s3 etc.)
1779
* @returns Pointer to the slice portion of the given path.
1781
static char *solarisGetSliceFromPath(const char *pszDevLinkPath)
1783
char *pszFound = NULL;
1784
char *pszSlice = strrchr(pszDevLinkPath, 's');
1785
char *pszDisk = strrchr(pszDevLinkPath, 'd');
1786
if (pszSlice && pszSlice > pszDisk)
1787
pszFound = pszSlice;
1791
if (pszFound && RT_C_IS_DIGIT(pszFound[1]))
1798
* Walk device links and returns an allocated path for the first one in the snapshot.
1800
* @param DevLink Handle to the device link being walked.
1801
* @param pvArg Opaque data containing the pointer to the path.
1802
* @returns Pointer to an allocated device path string.
1804
static int solarisWalkDevLink(di_devlink_t DevLink, void *pvArg)
1806
char **ppszPath = (char **)pvArg;
1807
*ppszPath = strdup(di_devlink_path(DevLink));
1808
return DI_WALK_TERMINATE;
1812
* Walk all devices in the system and enumerate CD/DVD drives.
1813
* @param Node Handle to the current node.
1814
* @param pvArg Opaque data (holds list pointer).
1815
* @returns Solaris specific code whether to continue walking or not.
1817
static int solarisWalkDeviceNodeForDVD(di_node_t Node, void *pvArg)
1819
PSOLARISDVD *ppDrives = (PSOLARISDVD *)pvArg;
1821
char *pszClass = NULL;
1822
if ( di_prop_lookup_strings(DDI_DEV_T_ANY, Node, "class", &pszClass) > 0
1823
&& !strcmp(pszClass, "scsi")) /* SCSI */
1826
if (di_prop_lookup_ints(DDI_DEV_T_ANY, Node, "inquiry-device-type", &pInt) > 0
1827
&& ( *pInt == DTYPE_RODIRECT /* CDROM */
1828
|| *pInt == DTYPE_OPTICAL)) /* Optical Drive */
1830
char *pszProduct = NULL;
1831
if (di_prop_lookup_strings(DDI_DEV_T_ANY, Node, "inquiry-product-id", &pszProduct) > 0)
1833
char *pszVendor = NULL;
1834
if (di_prop_lookup_strings(DDI_DEV_T_ANY, Node, "inquiry-vendor-id", &pszVendor) > 0)
1837
* Found a DVD drive, we need to scan the minor nodes to find the correct
1838
* slice that represents the whole drive. "s2" is always the whole drive for CD/DVDs.
1840
int Major = di_driver_major(Node);
1841
di_minor_t Minor = DI_MINOR_NIL;
1842
di_devlink_handle_t DevLink = di_devlink_init(NULL /* name */, 0 /* flags */);
1845
while ((Minor = di_minor_next(Node, Minor)) != DI_MINOR_NIL)
1847
dev_t Dev = di_minor_devt(Minor);
1848
if ( Major != (int)major(Dev)
1849
|| di_minor_spectype(Minor) == S_IFBLK
1850
|| di_minor_type(Minor) != DDM_MINOR)
1855
char *pszMinorPath = di_devfs_minor_path(Minor);
1859
char *pszDevLinkPath = NULL;
1860
di_devlink_walk(DevLink, NULL, pszMinorPath, DI_PRIMARY_LINK, &pszDevLinkPath, solarisWalkDevLink);
1861
di_devfs_path_free(pszMinorPath);
1865
char *pszSlice = solarisGetSliceFromPath(pszDevLinkPath);
1866
if ( pszSlice && !strcmp(pszSlice, "s2")
1867
&& !strncmp(pszDevLinkPath, "/dev/rdsk", sizeof("/dev/rdsk") - 1)) /* We want only raw disks */
1870
* We've got a fully qualified DVD drive. Add it to the list.
1872
PSOLARISDVD pDrive = (PSOLARISDVD)RTMemAllocZ(sizeof(SOLARISDVD));
1873
if (RT_LIKELY(pDrive))
1875
RTStrPrintf(pDrive->szDescription, sizeof(pDrive->szDescription), "%s %s", pszVendor, pszProduct);
1876
RTStrCopy(pDrive->szRawDiskPath, sizeof(pDrive->szRawDiskPath), pszDevLinkPath);
1878
pDrive->pNext = *ppDrives;
1882
free(pszDevLinkPath);
1885
di_devlink_fini(&DevLink);
1891
return DI_WALK_CONTINUE;
1895
* Solaris specific function to enumerate CD/DVD drives via the device tree.
1896
* Works on Solaris 10 as well as OpenSolaris without depending on libhal.
1898
void Host::getDVDInfoFromDevTree(std::list<ComObjPtr<Medium> > &list)
1900
PSOLARISDVD pDrives = NULL;
1901
di_node_t RootNode = di_init("/", DINFOCPYALL);
1902
if (RootNode != DI_NODE_NIL)
1903
di_walk_node(RootNode, DI_WALK_CLDFIRST, &pDrives, solarisWalkDeviceNodeForDVD);
1909
ComObjPtr<Medium> hostDVDDriveObj;
1910
hostDVDDriveObj.createObject();
1911
hostDVDDriveObj->init(m->pParent, DeviceType_DVD, Bstr(pDrives->szRawDiskPath), Bstr(pDrives->szDescription));
1912
list.push_back(hostDVDDriveObj);
1914
void *pvDrive = pDrives;
1915
pDrives = pDrives->pNext;
1796
1920
/* Solaris hosts, loading libhal at runtime */