~ubuntu-branches/ubuntu/natty/virtualbox-ose/natty-updates

« back to all changes in this revision

Viewing changes to src/VBox/Main/HostImpl.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Felix Geyer
  • Date: 2010-10-15 02:12:28 UTC
  • mfrom: (0.3.10 upstream) (0.4.19 sid)
  • Revision ID: james.westby@ubuntu.com-20101015021228-5e6vbxgtes8mg189
Tags: 3.2.10-dfsg-1ubuntu1
* Merge from Debian unstable, remaining changes:
  - VirtualBox should go in Accessories, not in System tools.
    - debian/virtualbox-ose-qt.files/virtualbox-ose.desktop
  - Add Apport hook.
    - debian/virtualbox-ose.files/source_virtualbox-ose.py
    - debian/virtualbox-ose.install
  - Drop *-source packages.
* Add ubuntu-01-fix-build-gcc45.patch to fix FTBFS due to uninitalized
  variables. Thanks to Lubomir Rintel <lkundrak@v3.sk> for the patch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
61
61
# include <errno.h>
62
62
# include <limits.h>
63
63
# include <stdio.h>
64
 
# ifdef VBOX_SOLARIS_NSL_RESOLVED
65
 
#  include <libdevinfo.h>
66
 
# endif
 
64
# include <libdevinfo.h>
 
65
# include <sys/mkdev.h>
 
66
# include <sys/scsi/generic/inquiry.h>
67
67
# include <net/if.h>
68
68
# include <sys/socket.h>
69
69
# include <sys/sockio.h>
81
81
extern "C" char *getfullrawname(char *);
82
82
# endif
83
83
# include "solaris/DynLoadLibSolaris.h"
 
84
 
 
85
/**
 
86
 * Solaris DVD drive list as returned by getDVDInfoFromDevTree().
 
87
 */
 
88
typedef struct SOLARISDVD
 
89
{
 
90
    struct SOLARISDVD *pNext;
 
91
    char szDescription[512];
 
92
    char szRawDiskPath[PATH_MAX];
 
93
} SOLARISDVD;
 
94
/** Pointer to a Solaris DVD descriptor. */
 
95
typedef SOLARISDVD *PSOLARISDVD;
 
96
 
84
97
#endif /* RT_OS_SOLARIS */
85
98
 
86
99
#ifdef RT_OS_WINDOWS
1538
1551
# ifdef VBOX_USE_LIBHAL
1539
1552
        if (!getDVDInfoFromHal(list))
1540
1553
# endif
1541
 
        // Not all Solaris versions ship with libhal.
1542
 
        // So use a fallback approach similar to Linux.
1543
1554
        {
1544
 
            if (RTEnvExistEx(RTENV_DEFAULT, "VBOX_CDROM"))
1545
 
            {
1546
 
                char *cdromEnv = RTEnvDupEx(RTENV_DEFAULT, "VBOX_CDROM");
1547
 
                char *saveStr = NULL;
1548
 
                char *cdromDrive = NULL;
1549
 
                if (cdromEnv)
1550
 
                    cdromDrive = strtok_r(cdromEnv, ":", &saveStr);
1551
 
                while (cdromDrive)
1552
 
                {
1553
 
                    if (validateDevice(cdromDrive, true))
1554
 
                    {
1555
 
                        ComObjPtr<Medium> hostDVDDriveObj;
1556
 
                        hostDVDDriveObj.createObject();
1557
 
                        hostDVDDriveObj->init(m->pParent, DeviceType_DVD, Bstr(cdromDrive));
1558
 
                        list.push_back(hostDVDDriveObj);
1559
 
                    }
1560
 
                    cdromDrive = strtok_r(NULL, ":", &saveStr);
1561
 
                }
1562
 
                RTStrFree(cdromEnv);
1563
 
            }
1564
 
            else
1565
 
            {
1566
 
                // this might work on Solaris version older than Nevada.
1567
 
                if (validateDevice("/cdrom/cdrom0", true))
1568
 
                {
1569
 
                    ComObjPtr<Medium> hostDVDDriveObj;
1570
 
                    hostDVDDriveObj.createObject();
1571
 
                    hostDVDDriveObj->init(m->pParent, DeviceType_DVD, Bstr("cdrom/cdrom0"));
1572
 
                    list.push_back(hostDVDDriveObj);
1573
 
                }
1574
 
 
1575
 
                // check the mounted drives
1576
 
                parseMountTable(MNTTAB, list);
1577
 
            }
 
1555
            getDVDInfoFromDevTree(list);
1578
1556
        }
1579
1557
 
1580
1558
#elif defined(RT_OS_LINUX) || defined(RT_OS_FREEBSD)
1793
1771
////////////////////////////////////////////////////////////////////////////////
1794
1772
 
1795
1773
#if defined(RT_OS_SOLARIS) && defined(VBOX_USE_LIBHAL)
 
1774
 
 
1775
/**
 
1776
 * Helper function to get the slice number from a device path
 
1777
 *
 
1778
 * @param   pszDevLinkPath      Pointer to a device path (/dev/(r)dsk/c7d1t0d0s3 etc.)
 
1779
 * @returns Pointer to the slice portion of the given path.
 
1780
 */
 
1781
static char *solarisGetSliceFromPath(const char *pszDevLinkPath)
 
1782
{
 
1783
    char *pszFound = NULL;
 
1784
    char *pszSlice = strrchr(pszDevLinkPath, 's');
 
1785
    char *pszDisk  = strrchr(pszDevLinkPath, 'd');
 
1786
    if (pszSlice && pszSlice > pszDisk)
 
1787
        pszFound = pszSlice;
 
1788
    else
 
1789
        pszFound = pszDisk;
 
1790
 
 
1791
    if (pszFound && RT_C_IS_DIGIT(pszFound[1]))
 
1792
        return pszFound;
 
1793
 
 
1794
    return NULL;
 
1795
}
 
1796
 
 
1797
/**
 
1798
 * Walk device links and returns an allocated path for the first one in the snapshot.
 
1799
 *
 
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.
 
1803
 */
 
1804
static int solarisWalkDevLink(di_devlink_t DevLink, void *pvArg)
 
1805
{
 
1806
    char **ppszPath = (char **)pvArg;
 
1807
    *ppszPath = strdup(di_devlink_path(DevLink));
 
1808
    return DI_WALK_TERMINATE;
 
1809
}
 
1810
 
 
1811
/**
 
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.
 
1816
 */
 
1817
static int solarisWalkDeviceNodeForDVD(di_node_t Node, void *pvArg)
 
1818
{
 
1819
    PSOLARISDVD *ppDrives = (PSOLARISDVD *)pvArg;
 
1820
 
 
1821
    char *pszClass = NULL;
 
1822
    if (   di_prop_lookup_strings(DDI_DEV_T_ANY, Node, "class", &pszClass) > 0
 
1823
        && !strcmp(pszClass, "scsi"))                                                   /* SCSI */
 
1824
    {
 
1825
        int *pInt = NULL;
 
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 */
 
1829
        {
 
1830
            char *pszProduct = NULL;
 
1831
            if (di_prop_lookup_strings(DDI_DEV_T_ANY, Node, "inquiry-product-id", &pszProduct) > 0)
 
1832
            {
 
1833
                char *pszVendor = NULL;
 
1834
                if (di_prop_lookup_strings(DDI_DEV_T_ANY, Node, "inquiry-vendor-id", &pszVendor) > 0)
 
1835
                {
 
1836
                    /*
 
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.
 
1839
                     */
 
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 */);
 
1843
                    if (DevLink)
 
1844
                    {
 
1845
                        while ((Minor = di_minor_next(Node, Minor)) != DI_MINOR_NIL)
 
1846
                        {
 
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)
 
1851
                            {
 
1852
                                continue;
 
1853
                            }
 
1854
 
 
1855
                            char *pszMinorPath = di_devfs_minor_path(Minor);
 
1856
                            if (!pszMinorPath)
 
1857
                                continue;
 
1858
 
 
1859
                            char *pszDevLinkPath = NULL;
 
1860
                            di_devlink_walk(DevLink, NULL, pszMinorPath, DI_PRIMARY_LINK, &pszDevLinkPath, solarisWalkDevLink);
 
1861
                            di_devfs_path_free(pszMinorPath);
 
1862
 
 
1863
                            if (pszDevLinkPath)
 
1864
                            {
 
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 */
 
1868
                                {
 
1869
                                    /*
 
1870
                                     * We've got a fully qualified DVD drive. Add it to the list.
 
1871
                                     */
 
1872
                                    PSOLARISDVD pDrive = (PSOLARISDVD)RTMemAllocZ(sizeof(SOLARISDVD));
 
1873
                                    if (RT_LIKELY(pDrive))
 
1874
                                    {
 
1875
                                        RTStrPrintf(pDrive->szDescription, sizeof(pDrive->szDescription), "%s %s", pszVendor, pszProduct);
 
1876
                                        RTStrCopy(pDrive->szRawDiskPath, sizeof(pDrive->szRawDiskPath), pszDevLinkPath);
 
1877
                                        if (*ppDrives)
 
1878
                                            pDrive->pNext = *ppDrives;
 
1879
                                        *ppDrives = pDrive;
 
1880
                                    }
 
1881
                                }
 
1882
                                free(pszDevLinkPath);
 
1883
                            }
 
1884
                        }
 
1885
                        di_devlink_fini(&DevLink);
 
1886
                    }
 
1887
                }
 
1888
            }
 
1889
        }
 
1890
    }
 
1891
    return DI_WALK_CONTINUE;
 
1892
}
 
1893
 
 
1894
/**
 
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.
 
1897
 */
 
1898
void Host::getDVDInfoFromDevTree(std::list<ComObjPtr<Medium> > &list)
 
1899
{
 
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);
 
1904
 
 
1905
    di_fini(RootNode);
 
1906
 
 
1907
    while (pDrives)
 
1908
    {
 
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);
 
1913
 
 
1914
        void *pvDrive = pDrives;
 
1915
        pDrives = pDrives->pNext;
 
1916
        RTMemFree(pvDrive);
 
1917
    }
 
1918
}
 
1919
 
1796
1920
/* Solaris hosts, loading libhal at runtime */
1797
1921
 
1798
1922
/**