VirtualBox

Ignore:
Timestamp:
Aug 28, 2020 2:40:55 PM (4 years ago)
Author:
vboxsync
Message:

Main: bugref:9224: Main+VBoxManageDisk+doc part

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/src-server/linux/HostHardwareLinux.cpp

    r82968 r85929  
    11/* $Id$ */
    22/** @file
    3  * Classes for handling hardware detection under Linux.  Please feel free to
    4  * expand these to work for other systems (Solaris!) or to add new ones for
    5  * other systems.
     3 * VirtualBox Main - Code for handling hardware detection under Linux, VBoxSVC.
    64 */
    75
     
    1816 */
    1917
    20 #define LOG_GROUP LOG_GROUP_MAIN
    21 
    2218
    2319/*********************************************************************************************************************************
    2420*   Header Files                                                                                                                 *
    2521*********************************************************************************************************************************/
    26 
    27 #include <HostHardwareLinux.h>
    28 #include <vector.h>
     22#define LOG_GROUP LOG_GROUP_MAIN
     23#include "HostHardwareLinux.h"
    2924
    3025#include <VBox/err.h>
     
    7166*   Global Variables                                                                                                             *
    7267*********************************************************************************************************************************/
    73 
    7468#ifdef TESTCASE
    7569static bool testing() { return true; }
     
    8781*   Typedefs and Defines                                                                                                         *
    8882*********************************************************************************************************************************/
    89 
    90 static int getDriveInfoFromEnv(const char *pcszVar, DriveInfoList *pList,
    91                                bool isDVD, bool *pfSuccess);
    92 static int getDriveInfoFromSysfs(DriveInfoList *pList, bool isDVD,
    93                                  bool *pfSuccess);
     83typedef enum SysfsWantDevice_T
     84{
     85    DVD,
     86    Floppy,
     87    FixedDisk
     88} SysfsWantDevice_T;
     89
     90
     91/*********************************************************************************************************************************
     92*   Internal Functions                                                                                                           *
     93*********************************************************************************************************************************/
     94static int getDriveInfoFromEnv(const char *pcszVar, DriveInfoList *pList, bool isDVD, bool *pfSuccess) RT_NOTHROW_PROTO;
     95static int getDriveInfoFromSysfs(DriveInfoList *pList, SysfsWantDevice_T wantDevice, bool *pfSuccess) RT_NOTHROW_PROTO;
     96
    9497
    9598/** Find the length of a string, ignoring trailing non-ascii or control
    96  * characters */
    97 static size_t strLenStripped(const char *pcsz)
     99 * characters
     100 * @note Code duplicated in HostHardwareFreeBSD.cpp  */
     101static size_t strLenStripped(const char *pcsz) RT_NOTHROW_DEF
    98102{
    99103    size_t cch = 0;
    100104    for (size_t i = 0; pcsz[i] != '\0'; ++i)
    101         if (pcsz[i] > 32 && pcsz[i] < 127)
     105        if (pcsz[i] > 32 /*space*/ && pcsz[i] < 127 /*delete*/)
    102106            cch = i;
    103107    return cch + 1;
     
    114118 * @param  pszName   where to store the name retrieved
    115119 */
    116 static bool floppyGetName(const char *pcszNode, unsigned Number,
    117                           floppy_drive_name pszName)
     120static bool floppyGetName(const char *pcszNode, unsigned Number, floppy_drive_name pszName) RT_NOTHROW_DEF
    118121{
    119122    AssertPtrReturn(pcszNode, false);
     
    145148 *                       FDC 1)
    146149 * @param   pszDesc      where to store the device description (optional)
    147  * @param   cchDesc      the size of the buffer in @a pszDesc
     150 * @param   cbDesc       the size of the buffer in @a pszDesc
    148151 * @param   pszUdi       where to store the device UDI (optional)
    149  * @param   cchUdi       the size of the buffer in @a pszUdi
     152 * @param   cbUdi        the size of the buffer in @a pszUdi
    150153 */
    151 static void floppyCreateDeviceStrings(const floppy_drive_name pcszName,
    152                                       unsigned Number, char *pszDesc,
    153                                       size_t cchDesc, char *pszUdi,
    154                                       size_t cchUdi)
     154static void floppyCreateDeviceStrings(const floppy_drive_name pcszName, unsigned Number,
     155                                      char *pszDesc, size_t cbDesc, char *pszUdi, size_t cbUdi) RT_NOTHROW_DEF
    155156{
    156157    AssertPtrNullReturnVoid(pcszName);
    157158    AssertPtrNullReturnVoid(pszDesc);
    158     AssertReturnVoid(!pszDesc || cchDesc > 0);
     159    AssertReturnVoid(!pszDesc || cbDesc > 0);
    159160    AssertPtrNullReturnVoid(pszUdi);
    160     AssertReturnVoid(!pszUdi || cchUdi > 0);
     161    AssertReturnVoid(!pszUdi || cbUdi > 0);
    161162    AssertReturnVoid(Number <= 7);
    162163    if (pcszName)
     
    175176        }
    176177        if (pszDesc)
    177             RTStrPrintf(pszDesc, cchDesc, "%s %s K%s", pcszSize, &pcszName[1],
     178            RTStrPrintf(pszDesc, cbDesc, "%s %s K%s", pcszSize, &pcszName[1],
    178179                        Number > 3 ? ", FDC 2" : "");
    179180    }
     
    181182    {
    182183        if (pszDesc)
    183             RTStrPrintf(pszDesc, cchDesc, "FDD %d%s", (Number & 4) + 1,
     184            RTStrPrintf(pszDesc, cbDesc, "FDD %d%s", (Number & 4) + 1,
    184185                        Number > 3 ? ", FDC 2" : "");
    185186    }
    186187    if (pszUdi)
    187         RTStrPrintf(pszUdi, cchUdi,
     188        RTStrPrintf(pszUdi, cbUdi,
    188189                    "/org/freedesktop/Hal/devices/platform_floppy_%u_storage",
    189190                    Number);
     
    194195 * Check whether a device number might correspond to a CD-ROM device according
    195196 * to Documentation/devices.txt in the Linux kernel source.
     197 *
    196198 * @returns true if it might, false otherwise
    197199 * @param   Number  the device number (major and minor combination)
    198200 */
    199 static bool isCdromDevNum(dev_t Number)
     201static bool isCdromDevNum(dev_t Number) RT_NOTHROW_DEF
    200202{
    201203    int major = major(Number);
    202204    int minor = minor(Number);
    203     if ((major == IDE0_MAJOR) && !(minor & 0x3f))
     205    if (major == IDE0_MAJOR && !(minor & 0x3f))
    204206        return true;
    205207    if (major == SCSI_CDROM_MAJOR)
     
    215217    if (major == MITSUMI_X_CDROM_MAJOR)
    216218        return true;
    217     if ((major == IDE1_MAJOR) && !(minor & 0x3f))
     219    if (major == IDE1_MAJOR && !(minor & 0x3f))
    218220        return true;
    219221    if (major == MITSUMI_CDROM_MAJOR)
     
    235237    if (major == CM206_CDROM_MAJOR)
    236238        return true;
    237     if ((major == IDE3_MAJOR) && !(minor & 0x3f))
     239    if (major == IDE3_MAJOR && !(minor & 0x3f))
    238240        return true;
    239241    if (major == 46 /* Parallel port ATAPI CD-ROM */)  /* no #define */
    240242        return true;
    241     if ((major == IDE4_MAJOR) && !(minor & 0x3f))
    242         return true;
    243     if ((major == IDE5_MAJOR) && !(minor & 0x3f))
    244         return true;
    245     if ((major == IDE6_MAJOR) && !(minor & 0x3f))
    246         return true;
    247     if ((major == IDE7_MAJOR) && !(minor & 0x3f))
    248         return true;
    249     if ((major == IDE8_MAJOR) && !(minor & 0x3f))
    250         return true;
    251     if ((major == IDE9_MAJOR) && !(minor & 0x3f))
     243    if (major == IDE4_MAJOR && !(minor & 0x3f))
     244        return true;
     245    if (major == IDE5_MAJOR && !(minor & 0x3f))
     246        return true;
     247    if (major == IDE6_MAJOR && !(minor & 0x3f))
     248        return true;
     249    if (major == IDE7_MAJOR && !(minor & 0x3f))
     250        return true;
     251    if (major == IDE8_MAJOR && !(minor & 0x3f))
     252        return true;
     253    if (major == IDE9_MAJOR && !(minor & 0x3f))
    252254        return true;
    253255    if (major == 113 /* VIOCD_MAJOR */)
     
    259261/**
    260262 * Send an SCSI INQUIRY command to a device and return selected information.
     263 *
    261264 * @returns  iprt status code
    262  * @returns  VERR_TRY_AGAIN if the query failed but might succeed next time
     265 * @retval   VERR_TRY_AGAIN if the query failed but might succeed next time
    263266 * @param pcszNode    the full path to the device node
    264  * @param pu8Type    where to store the SCSI device type on success (optional)
    265  * @param pchVendor  where to store the vendor id string on success (optional)
    266  * @param cchVendor  the size of the @a pchVendor buffer
    267  * @param pchModel   where to store the product id string on success (optional)
    268  * @param cchModel   the size of the @a pchModel buffer
     267 * @param pbType     where to store the SCSI device type on success (optional)
     268 * @param pszVendor  where to store the vendor id string on success (optional)
     269 * @param cbVendor   the size of the @a pszVendor buffer
     270 * @param pszModel   where to store the product id string on success (optional)
     271 * @param cchModel   the size of the @a pszModel buffer
    269272 * @note check documentation on the SCSI INQUIRY command and the Linux kernel
    270273 *       SCSI headers included above if you want to understand what is going
    271274 *       on in this method.
    272275 */
    273 static int cdromDoInquiry(const char *pcszNode, uint8_t *pu8Type,
    274                           char *pchVendor, size_t cchVendor, char *pchModel,
    275                           size_t cchModel)
    276 {
    277     LogRelFlowFunc(("pcszNode=%s, pu8Type=%p, pchVendor=%p, cchVendor=%llu, pchModel=%p, cchModel=%llu\n",
    278                     pcszNode, pu8Type, pchVendor, cchVendor, pchModel,
    279                     cchModel));
     276static int cdromDoInquiry(const char *pcszNode, uint8_t *pbType, char *pszVendor, size_t cbVendor,
     277                          char *pszModel, size_t cbModel) RT_NOTHROW_DEF
     278{
     279    LogRelFlowFunc(("pcszNode=%s, pbType=%p, pszVendor=%p, cbVendor=%zu, pszModel=%p, cbModel=%zu\n",
     280                    pcszNode, pbType, pszVendor, cbVendor, pszModel, cbModel));
    280281    AssertPtrReturn(pcszNode, VERR_INVALID_POINTER);
    281     AssertPtrNullReturn(pu8Type, VERR_INVALID_POINTER);
    282     AssertPtrNullReturn(pchVendor, VERR_INVALID_POINTER);
    283     AssertPtrNullReturn(pchModel, VERR_INVALID_POINTER);
    284 
    285     RTFILE hFile;
     282    AssertPtrNullReturn(pbType, VERR_INVALID_POINTER);
     283    AssertPtrNullReturn(pszVendor, VERR_INVALID_POINTER);
     284    AssertPtrNullReturn(pszModel, VERR_INVALID_POINTER);
     285
     286    RTFILE hFile = NIL_RTFILE;
    286287    int rc = RTFileOpen(&hFile, pcszNode, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE | RTFILE_O_NON_BLOCK);
    287288    if (RT_SUCCESS(rc))
    288289    {
    289         int                             rcIoCtl        = 0;
    290         unsigned char                   u8Response[96] = { 0 };
     290        int                             rcIoCtl          = 0;
     291        unsigned char                   auchResponse[96] = { 0 };
    291292        struct cdrom_generic_command    CdromCommandReq;
    292293        RT_ZERO(CdromCommandReq);
    293294        CdromCommandReq.cmd[0]         = INQUIRY;
    294         CdromCommandReq.cmd[4]         = sizeof(u8Response);
    295         CdromCommandReq.buffer         = u8Response;
    296         CdromCommandReq.buflen         = sizeof(u8Response);
     295        CdromCommandReq.cmd[4]         = sizeof(auchResponse);
     296        CdromCommandReq.buffer         = auchResponse;
     297        CdromCommandReq.buflen         = sizeof(auchResponse);
    297298        CdromCommandReq.data_direction = CGC_DATA_READ;
    298299        CdromCommandReq.timeout        = 5000;  /* ms */
     
    304305        if (RT_SUCCESS(rc))
    305306        {
    306             if (pu8Type)
    307                 *pu8Type = u8Response[0] & 0x1f;
    308             if (pchVendor)
    309                 RTStrPrintf(pchVendor, cchVendor, "%.8s",
    310                             &u8Response[8] /* vendor id string */);
    311             if (pchModel)
    312                 RTStrPrintf(pchModel, cchModel, "%.16s",
    313                             &u8Response[16] /* product id string */);
     307            if (pbType)
     308                *pbType = auchResponse[0] & 0x1f;
     309            if (pszVendor)
     310            {
     311                RTStrPrintf(pszVendor, cbVendor, "%.8s", &auchResponse[8] /* vendor id string */);
     312                RTStrPurgeEncoding(pszVendor);
     313            }
     314            if (pszModel)
     315            {
     316                RTStrPrintf(pszModel, cbModel, "%.16s", &auchResponse[16] /* product id string */);
     317                RTStrPurgeEncoding(pszModel);
     318            }
    314319            LogRelFlowFunc(("returning success: type=%u, vendor=%.8s, product=%.16s\n",
    315                             u8Response[0] & 0x1f, &u8Response[8], &u8Response[16]));
     320                            auchResponse[0] & 0x1f, &auchResponse[8], &auchResponse[16]));
    316321            return VINF_SUCCESS;
    317322        }
     
    328333 * @param pcszModel   the product ID string
    329334 * @param pszDesc    where to store the description string (optional)
    330  * @param cchDesc    the size of the buffer in @a pszDesc
     335 * @param cbDesc     the size of the buffer in @a pszDesc
    331336 * @param pszUdi     where to store the UDI string (optional)
    332  * @param cchUdi     the size of the buffer in @a pszUdi
     337 * @param cbUdi      the size of the buffer in @a pszUdi
     338 *
     339 * @note  Used for more than DVDs these days.
    333340 */
    334 /* static */
    335 void dvdCreateDeviceStrings(const char *pcszVendor, const char *pcszModel,
    336                             char *pszDesc, size_t cchDesc, char *pszUdi,
    337                             size_t cchUdi)
     341static void dvdCreateDeviceStrings(const char *pcszVendor, const char *pcszModel,
     342                                   char *pszDesc, size_t cbDesc, char *pszUdi, size_t cbUdi) RT_NOEXCEPT
    338343{
    339344    AssertPtrReturnVoid(pcszVendor);
    340345    AssertPtrReturnVoid(pcszModel);
    341346    AssertPtrNullReturnVoid(pszDesc);
    342     AssertReturnVoid(!pszDesc || cchDesc > 0);
     347    AssertReturnVoid(!pszDesc || cbDesc > 0);
    343348    AssertPtrNullReturnVoid(pszUdi);
    344     AssertReturnVoid(!pszUdi || cchUdi > 0);
    345     char szCleaned[128];
     349    AssertReturnVoid(!pszUdi || cbUdi > 0);
     350
    346351    size_t cchVendor = strLenStripped(pcszVendor);
    347352    size_t cchModel = strLenStripped(pcszModel);
    348353
    349354    /* Create a cleaned version of the model string for the UDI string. */
     355    char szCleaned[128];
    350356    for (unsigned i = 0; i < sizeof(szCleaned) && pcszModel[i] != '\0'; ++i)
    351357        if (   (pcszModel[i] >= '0' && pcszModel[i] <= '9')
     
    360366    {
    361367        if (cchVendor > 0)
    362             RTStrPrintf(pszDesc, cchDesc, "%.*s %s", cchVendor, pcszVendor,
    363                         cchModel > 0 ? pcszModel : "(unknown drive model)");
     368        {
     369            RTStrPrintf(pszDesc, cbDesc, "%.*s %s", cchVendor, pcszVendor, cchModel > 0 ? pcszModel : "(unknown drive model)");
     370            RTStrPurgeEncoding(pszDesc);
     371        }
    364372        else
    365             RTStrPrintf(pszDesc, cchDesc, "%s", pcszModel);
     373            RTStrCopy(pszDesc, cbDesc, pcszModel);
    366374    }
    367375    /* Construct the UDI string */
     
    369377    {
    370378        if (cchModel > 0)
    371             RTStrPrintf(pszUdi, cchUdi,
    372                         "/org/freedesktop/Hal/devices/storage_model_%s",
    373                         szCleaned);
     379            RTStrPrintf(pszUdi, cbUdi, "/org/freedesktop/Hal/devices/storage_model_%s", szCleaned);
    374380        else
    375381            pszUdi[0] = '\0';
     
    381387 * Check whether a device node points to a valid device and create a UDI and
    382388 * a description for it, and store the device number, if it does.
     389 *
    383390 * @returns true if the device is valid, false otherwise
    384391 * @param   pcszNode   the path to the device node
     
    386393 * @param   pDevice   where to store the device node (optional)
    387394 * @param   pszDesc   where to store the device description (optional)
    388  * @param   cchDesc   the size of the buffer in @a pszDesc
     395 * @param   cbDesc    the size of the buffer in @a pszDesc
    389396 * @param   pszUdi    where to store the device UDI (optional)
    390  * @param   cchUdi    the size of the buffer in @a pszUdi
     397 * @param   cbUdi     the size of the buffer in @a pszUdi
    391398 */
    392399static bool devValidateDevice(const char *pcszNode, bool isDVD, dev_t *pDevice,
    393                               char *pszDesc, size_t cchDesc, char *pszUdi,
    394                               size_t cchUdi)
     400                              char *pszDesc, size_t cbDesc, char *pszUdi, size_t cbUdi) RT_NOTHROW_DEF
    395401{
    396402    AssertPtrReturn(pcszNode, false);
    397403    AssertPtrNullReturn(pDevice, false);
    398404    AssertPtrNullReturn(pszDesc, false);
    399     AssertReturn(!pszDesc || cchDesc > 0, false);
     405    AssertReturn(!pszDesc || cbDesc > 0, false);
    400406    AssertPtrNullReturn(pszUdi, false);
    401     AssertReturn(!pszUdi || cchUdi > 0, false);
     407    AssertReturn(!pszUdi || cbUdi > 0, false);
     408
    402409    RTFSOBJINFO ObjInfo;
    403410    if (RT_FAILURE(RTPathQueryInfo(pcszNode, &ObjInfo, RTFSOBJATTRADD_UNIX)))
     
    407414    if (pDevice)
    408415        *pDevice = ObjInfo.Attr.u.Unix.Device;
     416
    409417    if (isDVD)
    410418    {
     
    419427        if (u8Type != TYPE_ROM)
    420428            return false;
    421         dvdCreateDeviceStrings(szVendor, szModel, pszDesc, cchDesc,
    422                                pszUdi, cchUdi);
     429        dvdCreateDeviceStrings(szVendor, szModel, pszDesc, cbDesc, pszUdi, cbUdi);
    423430    }
    424431    else
    425432    {
    426         /* Floppies on Linux are legacy devices with hardcoded majors and
    427          * minors */
    428         unsigned Number;
    429         floppy_drive_name szName;
     433        /* Floppies on Linux are legacy devices with hardcoded majors and minors */
    430434        if (major(ObjInfo.Attr.u.Unix.Device) != FLOPPY_MAJOR)
    431435            return false;
     436
     437        unsigned Number;
    432438        switch (minor(ObjInfo.Attr.u.Unix.Device))
    433439        {
     
    441447                return false;
    442448        }
     449
     450        floppy_drive_name szName;
    443451        if (!floppyGetName(pcszNode, Number, szName))
    444452            return false;
    445         floppyCreateDeviceStrings(szName, Number, pszDesc, cchDesc, pszUdi,
    446                                   cchUdi);
     453        floppyCreateDeviceStrings(szName, Number, pszDesc, cbDesc, pszUdi, cbUdi);
    447454    }
    448455    return true;
     
    450457
    451458
    452 int VBoxMainDriveInfo::updateDVDs ()
     459int VBoxMainDriveInfo::updateDVDs() RT_NOEXCEPT
    453460{
    454461    LogFlowThisFunc(("entered\n"));
    455     int rc = VINF_SUCCESS;
    456     bool success = false;  /* Have we succeeded in finding anything yet? */
     462    int rc;
    457463    try
    458464    {
    459         mDVDList.clear ();
     465        mDVDList.clear();
    460466        /* Always allow the user to override our auto-detection using an
    461467         * environment variable. */
    462         if (RT_SUCCESS(rc) && (!success || testing()))
    463             rc = getDriveInfoFromEnv ("VBOX_CDROM", &mDVDList, true /* isDVD */,
    464                                       &success);
     468        bool fSuccess = false;  /* Have we succeeded in finding anything yet? */
     469        rc = getDriveInfoFromEnv("VBOX_CDROM", &mDVDList, true /* isDVD */, &fSuccess);
    465470        setNoProbe(false);
    466         if (RT_SUCCESS(rc) && (!success || testing()))
    467             rc = getDriveInfoFromSysfs(&mDVDList, true /* isDVD */, &success);
     471        if (RT_SUCCESS(rc) && (!fSuccess || testing()))
     472            rc = getDriveInfoFromSysfs(&mDVDList, DVD, &fSuccess);
    468473        if (RT_SUCCESS(rc) && testing())
    469474        {
    470475            setNoProbe(true);
    471             rc = getDriveInfoFromSysfs(&mDVDList, true /* isDVD */, &success);
    472         }
    473     }
    474     catch(std::bad_alloc &e)
     476            rc = getDriveInfoFromSysfs(&mDVDList, DVD, &fSuccess);
     477        }
     478    }
     479    catch (std::bad_alloc &e)
    475480    {
    476481        rc = VERR_NO_MEMORY;
     
    480485}
    481486
    482 int VBoxMainDriveInfo::updateFloppies ()
     487int VBoxMainDriveInfo::updateFloppies() RT_NOEXCEPT
    483488{
    484489    LogFlowThisFunc(("entered\n"));
    485     int rc = VINF_SUCCESS;
    486     bool success = false;  /* Have we succeeded in finding anything yet? */
     490    int rc;
    487491    try
    488492    {
    489         mFloppyList.clear ();
    490         if (RT_SUCCESS(rc) && (!success || testing()))
    491             rc = getDriveInfoFromEnv("VBOX_FLOPPY", &mFloppyList,
    492                                      false /* isDVD */, &success);
     493        mFloppyList.clear();
     494        bool fSuccess = false;  /* Have we succeeded in finding anything yet? */
     495        rc = getDriveInfoFromEnv("VBOX_FLOPPY", &mFloppyList, false /* isDVD */, &fSuccess);
    493496        setNoProbe(false);
    494         if (   RT_SUCCESS(rc) && (!success || testing()))
    495             rc = getDriveInfoFromSysfs(&mFloppyList, false /* isDVD */,
    496                                        &success);
     497        if (RT_SUCCESS(rc) && (!fSuccess || testing()))
     498            rc = getDriveInfoFromSysfs(&mFloppyList, Floppy, &fSuccess);
    497499        if (RT_SUCCESS(rc) && testing())
    498500        {
    499501            setNoProbe(true);
    500             rc = getDriveInfoFromSysfs(&mFloppyList, false /* isDVD */, &success);
    501         }
    502     }
    503     catch(std::bad_alloc &e)
     502            rc = getDriveInfoFromSysfs(&mFloppyList, Floppy, &fSuccess);
     503        }
     504    }
     505    catch (std::bad_alloc &)
    504506    {
    505507        rc = VERR_NO_MEMORY;
     
    507509    LogFlowThisFunc(("rc=%Rrc\n", rc));
    508510    return rc;
     511}
     512
     513int VBoxMainDriveInfo::updateFixedDrives() RT_NOEXCEPT
     514{
     515    LogFlowThisFunc(("entered\n"));
     516    int vrc;
     517    try
     518    {
     519        mFixedDriveList.clear();
     520        setNoProbe(false);
     521        bool fSuccess = false;  /* Have we succeeded in finding anything yet? */
     522        vrc = getDriveInfoFromSysfs(&mFixedDriveList, FixedDisk, &fSuccess);
     523        if (RT_SUCCESS(vrc) && testing())
     524        {
     525            setNoProbe(true);
     526            vrc = getDriveInfoFromSysfs(&mFixedDriveList, FixedDisk, &fSuccess);
     527        }
     528    }
     529    catch (std::bad_alloc &)
     530    {
     531        vrc = VERR_NO_MEMORY;
     532    }
     533    LogFlowThisFunc(("vrc=%Rrc\n", vrc));
     534    return vrc;
    509535}
    510536
     
    513539 * Extract the names of drives from an environment variable and add them to a
    514540 * list if they are valid.
     541 *
    515542 * @returns iprt status code
    516543 * @param   pcszVar     the name of the environment variable.  The variable
     
    521548 * @param   pfSuccess  this will be set to true if we found at least one drive
    522549 *                     and to false otherwise.  Optional.
     550 *
     551 * @note    This is duplicated in HostHardwareFreeBSD.cpp.
    523552 */
    524 /* static */
    525 int getDriveInfoFromEnv(const char *pcszVar, DriveInfoList *pList,
    526                         bool isDVD, bool *pfSuccess)
     553static int getDriveInfoFromEnv(const char *pcszVar, DriveInfoList *pList, bool isDVD, bool *pfSuccess) RT_NOTHROW_DEF
    527554{
    528555    AssertPtrReturn(pcszVar, VERR_INVALID_POINTER);
    529556    AssertPtrReturn(pList, VERR_INVALID_POINTER);
    530557    AssertPtrNullReturn(pfSuccess, VERR_INVALID_POINTER);
    531     LogFlowFunc(("pcszVar=%s, pList=%p, isDVD=%d, pfSuccess=%p\n", pcszVar,
    532                  pList, isDVD, pfSuccess));
     558    LogFlowFunc(("pcszVar=%s, pList=%p, isDVD=%d, pfSuccess=%p\n", pcszVar, pList, isDVD, pfSuccess));
    533559    int rc = VINF_SUCCESS;
    534560    bool success = false;
     
    537563    try
    538564    {
    539         const char *pcszCurrent = pszFreeMe;
    540         while (pcszCurrent && *pcszCurrent != '\0')
    541         {
    542             const char *pcszNext = strchr(pcszCurrent, ':');
    543             char szPath[RTPATH_MAX], szReal[RTPATH_MAX];
     565        char *pszCurrent = pszFreeMe;
     566        while (pszCurrent && *pszCurrent != '\0')
     567        {
     568            char *pszNext = strchr(pszCurrent, ':');
     569            if (pszNext)
     570                *pszNext++ = '\0';
     571
     572            char szReal[RTPATH_MAX];
    544573            char szDesc[256], szUdi[256];
    545             if (pcszNext)
    546                 RTStrPrintf(szPath, sizeof(szPath), "%.*s",
    547                             pcszNext - pcszCurrent - 1, pcszCurrent);
    548             else
    549                 RTStrPrintf(szPath, sizeof(szPath), "%s", pcszCurrent);
    550             if (   RT_SUCCESS(RTPathReal(szPath, szReal, sizeof(szReal)))
    551                 && devValidateDevice(szReal, isDVD, NULL, szDesc,
    552                                      sizeof(szDesc), szUdi, sizeof(szUdi)))
     574            if (   RT_SUCCESS(RTPathReal(pszCurrent, szReal, sizeof(szReal)))
     575                && devValidateDevice(szReal, isDVD, NULL, szDesc, sizeof(szDesc), szUdi, sizeof(szUdi)))
    553576            {
    554577                pList->push_back(DriveInfo(szReal, szUdi, szDesc));
    555578                success = true;
    556579            }
    557             pcszCurrent = pcszNext ? pcszNext + 1 : NULL;
     580            pszCurrent = pszNext;
    558581        }
    559582        if (pfSuccess != NULL)
    560583            *pfSuccess = success;
    561584    }
    562     catch(std::bad_alloc &e)
     585    catch (std::bad_alloc &)
    563586    {
    564587        rc = VERR_NO_MEMORY;
     
    570593
    571594
    572 class sysfsBlockDev
     595class SysfsBlockDev
    573596{
    574597public:
    575     sysfsBlockDev(const char *pcszName, bool wantDVD)
    576             : mpcszName(pcszName), mwantDVD(wantDVD), misConsistent(true),
    577               misValid(false)
     598    SysfsBlockDev(const char *pcszName, SysfsWantDevice_T wantDevice) RT_NOEXCEPT
     599        : mpcszName(pcszName), mWantDevice(wantDevice), misConsistent(true), misValid(false)
    578600    {
    579601        if (findDeviceNode())
    580602        {
    581             if (mwantDVD)
    582                 validateAndInitForDVD();
    583             else
    584                 validateAndInitForFloppy();
     603            switch (mWantDevice)
     604            {
     605                case DVD:    validateAndInitForDVD(); break;
     606                case Floppy: validateAndInitForFloppy(); break;
     607                default:     validateAndInitForFixedDisk(); break;
     608            }
    585609        }
    586610    }
     
    588612    /** The name of the subdirectory of /sys/block for this device */
    589613    const char *mpcszName;
    590     /** Are we looking for a floppy or a DVD device? */
    591     bool mwantDVD;
     614    /** Are we looking for a floppy, a DVD or a fixed disk device? */
     615    SysfsWantDevice_T mWantDevice;
    592616    /** The device node for the device */
    593617    char mszNode[RTPATH_MAX];
     
    609633     * @returns boolean success value
    610634     */
    611     bool findDeviceNode()
     635    bool findDeviceNode() RT_NOEXCEPT
    612636    {
    613637        dev_t dev = 0;
     
    618642            return false;
    619643        }
    620         rc = RTLinuxCheckDevicePath(dev, RTFS_TYPE_DEV_BLOCK, mszNode,
    621                                     sizeof(mszNode), "%s", mpcszName);
    622         if (RT_FAILURE(rc))
    623             return false;
    624         return true;
     644        rc = RTLinuxCheckDevicePath(dev, RTFS_TYPE_DEV_BLOCK, mszNode, sizeof(mszNode), "%s", mpcszName);
     645        return RT_SUCCESS(rc);
    625646    }
    626647
     
    630651     * poking the device, and if that fails we fall back to an SCSI INQUIRY
    631652     * command. */
    632     void validateAndInitForDVD()
    633     {
    634         char szVendor[128], szModel[128];
     653    void validateAndInitForDVD() RT_NOEXCEPT
     654    {
    635655        int64_t type = 0;
    636656        int rc = RTLinuxSysFsReadIntFile(10, &type, "block/%s/device/type", mpcszName);
     
    639659        if (type == TYPE_ROM)
    640660        {
    641             rc = RTLinuxSysFsReadStrFile(szVendor, sizeof(szVendor), NULL,
    642                                         "block/%s/device/vendor", mpcszName);
     661            char szVendor[128];
     662            rc = RTLinuxSysFsReadStrFile(szVendor, sizeof(szVendor), NULL, "block/%s/device/vendor", mpcszName);
    643663            if (RT_SUCCESS(rc))
    644664            {
    645                 rc = RTLinuxSysFsReadStrFile(szModel, sizeof(szModel), NULL,
    646                                             "block/%s/device/model", mpcszName);
     665                char szModel[128];
     666                rc = RTLinuxSysFsReadStrFile(szModel, sizeof(szModel), NULL, "block/%s/device/model", mpcszName);
    647667                if (RT_SUCCESS(rc))
    648668                {
    649669                    misValid = true;
    650                     dvdCreateDeviceStrings(szVendor, szModel,
    651                                            mszDesc, sizeof(mszDesc),
    652                                            mszUdi, sizeof(mszUdi));
     670                    dvdCreateDeviceStrings(szVendor, szModel, mszDesc, sizeof(mszDesc), mszUdi, sizeof(mszUdi));
    653671                    return;
    654672                }
     
    663681     * data members for the object based on the returned data.
    664682     */
    665     void probeAndInitForDVD()
     683    void probeAndInitForDVD() RT_NOEXCEPT
    666684    {
    667685        AssertReturnVoid(mszNode[0] != '\0');
    668         uint8_t u8Type = 0;
     686        uint8_t bType = 0;
    669687        char szVendor[128] = "";
    670688        char szModel[128] = "";
    671         int rc = cdromDoInquiry(mszNode, &u8Type, szVendor,
    672                                 sizeof(szVendor), szModel,
    673                                 sizeof(szModel));
    674         if (RT_SUCCESS(rc) && (u8Type == TYPE_ROM))
     689        int rc = cdromDoInquiry(mszNode, &bType, szVendor, sizeof(szVendor), szModel, sizeof(szModel));
     690        if (RT_SUCCESS(rc) && bType == TYPE_ROM)
    675691        {
    676692            misValid = true;
    677             dvdCreateDeviceStrings(szVendor, szModel, mszDesc, sizeof(mszDesc),
    678                                    mszUdi, sizeof(mszUdi));
     693            dvdCreateDeviceStrings(szVendor, szModel, mszDesc, sizeof(mszDesc), mszUdi, sizeof(mszUdi));
    679694        }
    680695    }
     
    684699     * support floppies using the basic "floppy" driver, we check the driver
    685700     * using the entry name and a driver-specific ioctl. */
    686     void validateAndInitForFloppy()
    687     {
    688         bool haveName = false;
     701    void validateAndInitForFloppy() RT_NOEXCEPT
     702    {
    689703        floppy_drive_name szName;
    690704        char szDriver[8];
     
    695709            || mpcszName[3] != '\0')
    696710            return;
     711        bool fHaveName = false;
    697712        if (!noProbe())
    698             haveName = floppyGetName(mszNode, mpcszName[2] - '0', szName);
     713            fHaveName = floppyGetName(mszNode, mpcszName[2] - '0', szName);
    699714        int rc = RTLinuxSysFsGetLinkDest(szDriver, sizeof(szDriver), NULL, "block/%s/%s",
    700715                                         mpcszName, "device/driver");
     
    704719                return;
    705720        }
    706         else if (!haveName)
     721        else if (!fHaveName)
    707722            return;
    708         floppyCreateDeviceStrings(haveName ? szName : NULL,
     723        floppyCreateDeviceStrings(fHaveName ? szName : NULL,
    709724                                  mpcszName[2] - '0', mszDesc,
    710725                                  sizeof(mszDesc), mszUdi, sizeof(mszUdi));
     
    712727    }
    713728
     729    void validateAndInitForFixedDisk() RT_NOEXCEPT
     730    {
     731        /*
     732         * For current task only device path is needed. Therefore, device probing
     733         * is skipped and other fields are empty if there aren't files in the
     734         * device entry.
     735         */
     736        int64_t type = 0;
     737        int rc = RTLinuxSysFsReadIntFile(10, &type, "block/%s/device/type", mpcszName);
     738        if (RT_SUCCESS(rc) && type != TYPE_DISK)
     739            return;
     740        char szVendor[128];
     741        rc = RTLinuxSysFsReadStrFile(szVendor, sizeof(szVendor), NULL, "block/%s/device/vendor", mpcszName);
     742        if (RT_SUCCESS(rc))
     743        {
     744            char szModel[128];
     745            rc = RTLinuxSysFsReadStrFile(szModel, sizeof(szModel), NULL, "block/%s/device/model", mpcszName);
     746            if (RT_SUCCESS(rc))
     747            {
     748                misValid = true;
     749                dvdCreateDeviceStrings(szVendor, szModel, mszDesc, sizeof(mszDesc), mszUdi, sizeof(mszUdi));
     750                return;
     751            }
     752        }
     753    }
     754
    714755public:
    715     bool isConsistent()
     756    bool isConsistent() const RT_NOEXCEPT
    716757    {
    717758        return misConsistent;
    718759    }
    719     bool isValid()
     760    bool isValid() const RT_NOEXCEPT
    720761    {
    721762        return misValid;
    722763    }
    723     const char *getDesc()
     764    const char *getDesc() const RT_NOEXCEPT
    724765    {
    725766        return mszDesc;
    726767    }
    727     const char *getUdi()
     768    const char *getUdi() const RT_NOEXCEPT
    728769    {
    729770        return mszUdi;
    730771    }
    731     const char *getNode()
     772    const char *getNode() const RT_NOEXCEPT
    732773    {
    733774        return mszNode;
     
    739780 * drives attached to the system.
    740781 * @returns iprt status code
    741  * @param   pList      where to add information about the drives detected
    742  * @param   isDVD      are we looking for DVDs or floppies?
    743  * @param   pfSuccess  Did we find anything?
     782 * @param   pList       where to add information about the drives detected
     783 * @param   wantDevice  The kind of devices we're looking for.
     784 * @param   pfSuccess   Did we find anything?
    744785 *
    745786 * @returns IPRT status code
     787 * @throws  Nothing.
    746788 */
    747 /* static */
    748 int getDriveInfoFromSysfs(DriveInfoList *pList, bool isDVD, bool *pfSuccess)
     789static int getDriveInfoFromSysfs(DriveInfoList *pList, SysfsWantDevice_T wantDevice, bool *pfSuccess) RT_NOTHROW_DEF
    749790{
    750791    AssertPtrReturn(pList, VERR_INVALID_POINTER);
    751792    AssertPtrNullReturn(pfSuccess, VERR_INVALID_POINTER); /* Valid or Null */
    752     LogFlowFunc (("pList=%p, isDVD=%u, pfSuccess=%p\n",
    753                   pList, (unsigned) isDVD, pfSuccess));
    754     RTDIR hDir;
    755     int rc;
    756     bool fSuccess = false;
    757     unsigned cFound = 0;
    758 
     793    LogFlowFunc (("pList=%p, wantDevice=%u, pfSuccess=%p\n",
     794                  pList, (unsigned)wantDevice, pfSuccess));
    759795    if (!RTPathExists("/sys"))
    760796        return VINF_SUCCESS;
    761     rc = RTDirOpen(&hDir, "/sys/block");
     797
     798    bool fSuccess = true;
     799    unsigned cFound = 0;
     800    RTDIR hDir = NIL_RTDIR;
     801    int rc = RTDirOpen(&hDir, "/sys/block");
    762802    /* This might mean that sysfs semantics have changed */
    763803    AssertReturn(rc != VERR_FILE_NOT_FOUND, VINF_SUCCESS);
    764     fSuccess = true;
    765804    if (RT_SUCCESS(rc))
    766805    {
     
    774813            if (entry.szName[0] == '.')
    775814                continue;
    776             sysfsBlockDev dev(entry.szName, isDVD);
     815            SysfsBlockDev dev(entry.szName, wantDevice);
    777816            /* This might mean that sysfs semantics have changed */
    778817            AssertBreakStmt(dev.isConsistent(), fSuccess = false);
     
    783822                pList->push_back(DriveInfo(dev.getNode(), dev.getUdi(), dev.getDesc()));
    784823            }
    785             catch(std::bad_alloc &e)
     824            catch (std::bad_alloc &e)
    786825            {
    787826                rc = VERR_NO_MEMORY;
     
    794833    if (rc == VERR_NO_MORE_FILES)
    795834        rc = VINF_SUCCESS;
    796     if (RT_FAILURE(rc))
     835    else if (RT_FAILURE(rc))
    797836        /* Clean up again */
    798         for (unsigned i = 0; i < cFound; ++i)
     837        while (cFound-- > 0)
    799838            pList->pop_back();
    800839    if (pfSuccess)
    801840        *pfSuccess = fSuccess;
    802     LogFlow (("rc=%Rrc, fSuccess=%u\n", rc, (unsigned) fSuccess));
     841    LogFlow (("rc=%Rrc, fSuccess=%u\n", rc, (unsigned)fSuccess));
    803842    return rc;
    804843}
     
    807846/** Helper for readFilePathsFromDir().  Adds a path to the vector if it is not
    808847 * NULL and not a dotfile (".", "..", ".*"). */
    809 static int maybeAddPathToVector(const char *pcszPath, const char *pcszEntry,
    810                                 VECTOR_PTR(char *) *pvecpchDevs)
    811 {
    812     char *pszPath;
    813 
     848static int maybeAddPathToVector(const char *pcszPath, const char *pcszEntry, VECTOR_PTR(char *) *pvecpchDevs) RT_NOTHROW_DEF
     849{
    814850    if (!pcszPath)
    815851        return 0;
    816852    if (pcszEntry[0] == '.')
    817853        return 0;
    818     pszPath = RTStrDup(pcszPath);
    819     if (!pszPath)
    820         return ENOMEM;
    821     if (RT_FAILURE(VEC_PUSH_BACK_PTR(pvecpchDevs, char *, pszPath)))
    822         return ENOMEM;
    823     return 0;
    824 }
    825 
    826 /** Helper for readFilePaths().  Adds the entries from the open directory
    827  * @a pDir to the vector @a pvecpchDevs using either the full path or the
    828  * realpath() and skipping hidden files and files on which realpath() fails. */
    829 static int readFilePathsFromDir(const char *pcszPath, DIR *pDir,
    830                                 VECTOR_PTR(char *) *pvecpchDevs, int withRealPath)
     854    char *pszPath = RTStrDup(pcszPath);
     855    if (pszPath)
     856    {
     857        int vrc = VEC_PUSH_BACK_PTR(pvecpchDevs, char *, pszPath);
     858        if (RT_SUCCESS(vrc))
     859            return 0;
     860    }
     861    return ENOMEM;
     862}
     863
     864/**
     865 * Helper for readFilePaths().
     866 *
     867 * Adds the entries from the open directory @a pDir to the vector @a pvecpchDevs
     868 * using either the full path or the realpath() and skipping hidden files
     869 * and files on which realpath() fails.
     870 */
     871static int readFilePathsFromDir(const char *pcszPath, DIR *pDir, VECTOR_PTR(char *) *pvecpchDevs, int withRealPath) RT_NOTHROW_DEF
    831872{
    832873    struct dirent entry, *pResult;
     
    837878# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
    838879#endif
    839     for (err = readdir_r(pDir, &entry, &pResult); pResult;
     880    for (err = readdir_r(pDir, &entry, &pResult);
     881         pResult /** @todo r=bird: && err == 0 ? */;
    840882         err = readdir_r(pDir, &entry, &pResult))
    841883#if RT_GNUC_PREREQ(4, 6)
     
    869911 * @param   withRealPath  whether to canonicalise the filename with realpath
    870912 */
    871 static int readFilePaths(const char *pcszPath, VECTOR_PTR(char *) *pvecpchDevs,
    872                          int withRealPath)
    873 {
    874     DIR *pDir;
    875     int err;
    876 
     913static int readFilePaths(const char *pcszPath, VECTOR_PTR(char *) *pvecpchDevs, int withRealPath) RT_NOTHROW_DEF
     914{
    877915    AssertPtrReturn(pvecpchDevs, EINVAL);
    878916    AssertReturn(VEC_SIZE_PTR(pvecpchDevs) == 0, EINVAL);
    879917    AssertPtrReturn(pcszPath, EINVAL);
    880918
    881     pDir = opendir(pcszPath);
     919    DIR *pDir = opendir(pcszPath);
    882920    if (!pDir)
    883921        return RTErrConvertFromErrno(errno);
    884     err = readFilePathsFromDir(pcszPath, pDir, pvecpchDevs, withRealPath);
     922    int err = readFilePathsFromDir(pcszPath, pDir, pvecpchDevs, withRealPath);
    885923    if (closedir(pDir) < 0 && !err)
    886924        err = errno;
     
    12621300        mImpl = new hotplugNullImpl(pcszDevicesRoot);
    12631301    }
    1264     catch(std::bad_alloc &e)
     1302    catch (std::bad_alloc &e)
    12651303    { }
    12661304}
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette