VirtualBox

Changeset 64246 in vbox


Ignore:
Timestamp:
Oct 13, 2016 1:08:51 PM (8 years ago)
Author:
vboxsync
Message:

Devices/Storage/DrvHost*: Move determining the medai size to the host specific sources

Location:
trunk/src/VBox/Devices/Storage
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Storage/DrvHostBase-darwin.cpp

    r64239 r64246  
    122122}
    123123
     124
     125DECLHIDDEN(int) drvHostBaseGetMediaSizeOs(PDRVHOSTBASE pThis, uint64_t *pcb)
     126{
     127    /*
     128     * Try a READ_CAPACITY command...
     129     */
     130    struct
     131    {
     132        uint32_t cBlocks;
     133        uint32_t cbBlock;
     134    }           Buf = {0, 0};
     135    uint32_t    cbBuf = sizeof(Buf);
     136    uint8_t     abCmd[16] =
     137    {
     138        SCSI_READ_CAPACITY, 0, 0, 0, 0, 0, 0,
     139        0,0,0,0,0,0,0,0,0
     140    };
     141    int rc = drvHostBaseScsiCmdOs(pThis, abCmd, 6, PDMMEDIATXDIR_FROM_DEVICE, &Buf, &cbBuf, NULL, 0, 0);
     142    if (RT_SUCCESS(rc))
     143    {
     144        Assert(cbBuf == sizeof(Buf));
     145        Buf.cBlocks = RT_BE2H_U32(Buf.cBlocks);
     146        Buf.cbBlock = RT_BE2H_U32(Buf.cbBlock);
     147        //if (Buf.cbBlock > 2048) /* everyone else is doing this... check if it needed/right.*/
     148        //    Buf.cbBlock = 2048;
     149        pThis->cbBlock = Buf.cbBlock;
     150
     151        *pcb = (uint64_t)Buf.cBlocks * Buf.cbBlock;
     152    }
     153    return rc;
     154}
     155
  • trunk/src/VBox/Devices/Storage/DrvHostBase-freebsd.cpp

    r64239 r64246  
    123123}
    124124
     125
     126DECLHIDDEN(int) drvHostBaseGetMediaSizeOs(PDRVHOSTBASE pThis, uint64_t *pcb)
     127{
     128    /*
     129     * Try a READ_CAPACITY command...
     130     */
     131    struct
     132    {
     133        uint32_t cBlocks;
     134        uint32_t cbBlock;
     135    }           Buf = {0, 0};
     136    uint32_t    cbBuf = sizeof(Buf);
     137    uint8_t     abCmd[16] =
     138    {
     139        SCSI_READ_CAPACITY, 0, 0, 0, 0, 0, 0,
     140        0,0,0,0,0,0,0,0,0
     141    };
     142    int rc = drvHostBaseScsiCmdOs(pThis, abCmd, 6, PDMMEDIATXDIR_FROM_DEVICE, &Buf, &cbBuf, NULL, 0, 0);
     143    if (RT_SUCCESS(rc))
     144    {
     145        Assert(cbBuf == sizeof(Buf));
     146        Buf.cBlocks = RT_BE2H_U32(Buf.cBlocks);
     147        Buf.cbBlock = RT_BE2H_U32(Buf.cbBlock);
     148        //if (Buf.cbBlock > 2048) /* everyone else is doing this... check if it needed/right.*/
     149        //    Buf.cbBlock = 2048;
     150        pThis->cbBlock = Buf.cbBlock;
     151
     152        *pcb = (uint64_t)Buf.cBlocks * Buf.cbBlock;
     153    }
     154    return rc;
     155}
     156
  • trunk/src/VBox/Devices/Storage/DrvHostBase-linux.cpp

    r64244 r64246  
    3131# include "swab.h"
    3232#endif
     33#include <linux/fd.h>
    3334#include <linux/cdrom.h>
    3435#include <limits.h>
     
    127128}
    128129
     130DECLHIDDEN(int) drvHostBaseGetMediaSizeOs(PDRVHOSTBASE pThis, uint64_t *pcb)
     131{
     132    int rc = VERR_INVALID_STATE;
     133
     134    if (PDMMEDIATYPE_IS_FLOPPY(pThis->enmType))
     135    {
     136        rc = ioctl(RTFileToNative(pThis->hFileDevice), FDFLUSH);
     137        if (rc)
     138        {
     139            rc = RTErrConvertFromErrno (errno);
     140            Log(("DrvHostFloppy: FDFLUSH ioctl(%s) failed, errno=%d rc=%Rrc\n", pThis->pszDevice, errno, rc));
     141            return rc;
     142        }
     143
     144        floppy_drive_struct DrvStat;
     145        rc = ioctl(RTFileToNative(pThis->hFileDevice), FDGETDRVSTAT, &DrvStat);
     146        if (rc)
     147        {
     148            rc = RTErrConvertFromErrno(errno);
     149            Log(("DrvHostFloppy: FDGETDRVSTAT ioctl(%s) failed, errno=%d rc=%Rrc\n", pThis->pszDevice, errno, rc));
     150            return rc;
     151        }
     152        pThis->fReadOnly = !(DrvStat.flags & FD_DISK_WRITABLE);
     153        rc = RTFileSeek(pThis->hFileDevice, 0, RTFILE_SEEK_END, pcb);
     154    }
     155    else if (pThis->enmType == PDMMEDIATYPE_CDROM || pThis->enmType == PDMMEDIATYPE_DVD)
     156    {
     157        /* Clear the media-changed-since-last-call-thingy just to be on the safe side. */
     158        ioctl(RTFileToNative(pThis->hFileDevice), CDROM_MEDIA_CHANGED, CDSL_CURRENT);
     159        rc = RTFileSeek(pThis->hFileDevice, 0, RTFILE_SEEK_END, pcb);
     160    }
     161
     162    return rc;
     163}
     164
  • trunk/src/VBox/Devices/Storage/DrvHostBase-solaris.cpp

    r64242 r64246  
    167167}
    168168
     169DECLHIDDEN(int) drvHostBaseGetMediaSizeOs(PDRVHOSTBASE pThis, uint64_t *pcb)
     170{
     171    /*
     172     * Sun docs suggests using DKIOCGGEOM instead of DKIOCGMEDIAINFO, but
     173     * Sun themselves use DKIOCGMEDIAINFO for DVDs/CDs, and use DKIOCGGEOM
     174     * for secondary storage devices.
     175     */
     176    struct dk_minfo MediaInfo;
     177    if (ioctl(RTFileToNative(pThis->hFileRawDevice), DKIOCGMEDIAINFO, &MediaInfo) == 0)
     178    {
     179        *pcb = MediaInfo.dki_capacity * (uint64_t)MediaInfo.dki_lbsize;
     180        return VINF_SUCCESS;
     181    }
     182    return RTFileSeek(pThis->hFileDevice, 0, RTFILE_SEEK_END, pcb);
     183}
     184
  • trunk/src/VBox/Devices/Storage/DrvHostBase-win.cpp

    r64245 r64246  
    113113}
    114114
     115DECLHIDDEN(int) drvHostBaseGetMediaSizeOs(PDRVHOSTBASE pThis, uint64_t *pcb)
     116{
     117    int rc = VERR_GENERAL_FAILURE;
     118
     119    if (PDMMEDIATYPE_IS_FLOPPY(pThis->enmType))
     120    {
     121        DISK_GEOMETRY   geom;
     122        DWORD           cbBytesReturned;
     123        int             cbSectors;
     124
     125        memset(&geom, 0, sizeof(geom));
     126        rc = DeviceIoControl((HANDLE)RTFileToNative(pThis->hFileDevice), IOCTL_DISK_GET_DRIVE_GEOMETRY,
     127                             NULL, 0, &geom, sizeof(geom), &cbBytesReturned,  NULL);
     128        if (rc) {
     129            cbSectors = geom.Cylinders.QuadPart * geom.TracksPerCylinder * geom.SectorsPerTrack;
     130            *pcb = cbSectors * geom.BytesPerSector;
     131            rc = VINF_SUCCESS;
     132        }
     133        else
     134        {
     135            DWORD   dwLastError;
     136
     137            dwLastError = GetLastError();
     138            rc = RTErrConvertFromWin32(dwLastError);
     139            Log(("DrvHostFloppy: IOCTL_DISK_GET_DRIVE_GEOMETRY(%s) failed, LastError=%d rc=%Rrc\n",
     140                 pThis->pszDevice, dwLastError, rc));
     141            return rc;
     142        }
     143    }
     144    else
     145    {
     146        /* use NT api, retry a few times if the media is being verified. */
     147        IO_STATUS_BLOCK             IoStatusBlock = {0};
     148        FILE_FS_SIZE_INFORMATION    FsSize= {0};
     149        NTSTATUS rcNt = NtQueryVolumeInformationFile((HANDLE)RTFileToNative(pThis->hFileDevice),  &IoStatusBlock,
     150                                                     &FsSize, sizeof(FsSize), FileFsSizeInformation);
     151        int cRetries = 5;
     152        while (rcNt == STATUS_VERIFY_REQUIRED && cRetries-- > 0)
     153        {
     154            RTThreadSleep(10);
     155            rcNt = NtQueryVolumeInformationFile((HANDLE)RTFileToNative(pThis->hFileDevice),  &IoStatusBlock,
     156                                                &FsSize, sizeof(FsSize), FileFsSizeInformation);
     157        }
     158        if (rcNt >= 0)
     159        {
     160            *pcb = FsSize.TotalAllocationUnits.QuadPart * FsSize.BytesPerSector;
     161            return VINF_SUCCESS;
     162        }
     163
     164        /* convert nt status code to VBox status code. */
     165        /** @todo Make conversion function!. */
     166        switch (rcNt)
     167        {
     168            case STATUS_NO_MEDIA_IN_DEVICE:     rc = VERR_MEDIA_NOT_PRESENT; break;
     169            case STATUS_VERIFY_REQUIRED:        rc = VERR_TRY_AGAIN; break;
     170        }
     171        LogFlow(("drvHostBaseGetMediaSize: NtQueryVolumeInformationFile -> %#lx\n", rcNt, rc));
     172    }
     173    return rc;
     174}
     175
  • trunk/src/VBox/Devices/Storage/DrvHostBase.cpp

    r64239 r64246  
    11331133static DECLCALLBACK(int) drvHostBaseGetMediaSize(PDRVHOSTBASE pThis, uint64_t *pcb)
    11341134{
    1135 #if defined(RT_OS_DARWIN) || defined(RT_OS_FREEBSD)
    1136     /*
    1137      * Try a READ_CAPACITY command...
    1138      */
    1139     struct
    1140     {
    1141         uint32_t cBlocks;
    1142         uint32_t cbBlock;
    1143     }           Buf = {0, 0};
    1144     uint32_t    cbBuf = sizeof(Buf);
    1145     uint8_t     abCmd[16] =
    1146     {
    1147         SCSI_READ_CAPACITY, 0, 0, 0, 0, 0, 0,
    1148         0,0,0,0,0,0,0,0,0
    1149     };
    1150     int rc = drvHostBaseScsiCmdOs(pThis, abCmd, 6, PDMMEDIATXDIR_FROM_DEVICE, &Buf, &cbBuf, NULL, 0, 0);
    1151     if (RT_SUCCESS(rc))
    1152     {
    1153         Assert(cbBuf == sizeof(Buf));
    1154         Buf.cBlocks = RT_BE2H_U32(Buf.cBlocks);
    1155         Buf.cbBlock = RT_BE2H_U32(Buf.cbBlock);
    1156         //if (Buf.cbBlock > 2048) /* everyone else is doing this... check if it needed/right.*/
    1157         //    Buf.cbBlock = 2048;
    1158         pThis->cbBlock = Buf.cbBlock;
    1159 
    1160         *pcb = (uint64_t)Buf.cBlocks * Buf.cbBlock;
    1161     }
    1162     return rc;
    1163 
    1164 #elif defined(RT_OS_SOLARIS)
    1165     /*
    1166      * Sun docs suggests using DKIOCGGEOM instead of DKIOCGMEDIAINFO, but
    1167      * Sun themselves use DKIOCGMEDIAINFO for DVDs/CDs, and use DKIOCGGEOM
    1168      * for secondary storage devices.
    1169      */
    1170     struct dk_minfo MediaInfo;
    1171     if (ioctl(RTFileToNative(pThis->hFileRawDevice), DKIOCGMEDIAINFO, &MediaInfo) == 0)
    1172     {
    1173         *pcb = MediaInfo.dki_capacity * (uint64_t)MediaInfo.dki_lbsize;
    1174         return VINF_SUCCESS;
    1175     }
    1176     return RTFileSeek(pThis->hFileDevice, 0, RTFILE_SEEK_END, pcb);
    1177 
    1178 #elif defined(RT_OS_WINDOWS)
    1179     /* use NT api, retry a few times if the media is being verified. */
    1180     IO_STATUS_BLOCK             IoStatusBlock = {0};
    1181     FILE_FS_SIZE_INFORMATION    FsSize= {0};
    1182     NTSTATUS rcNt = NtQueryVolumeInformationFile((HANDLE)RTFileToNative(pThis->hFileDevice),  &IoStatusBlock,
    1183                                                  &FsSize, sizeof(FsSize), FileFsSizeInformation);
    1184     int cRetries = 5;
    1185     while (rcNt == STATUS_VERIFY_REQUIRED && cRetries-- > 0)
    1186     {
    1187         RTThreadSleep(10);
    1188         rcNt = NtQueryVolumeInformationFile((HANDLE)RTFileToNative(pThis->hFileDevice),  &IoStatusBlock,
    1189                                             &FsSize, sizeof(FsSize), FileFsSizeInformation);
    1190     }
    1191     if (rcNt >= 0)
    1192     {
    1193         *pcb = FsSize.TotalAllocationUnits.QuadPart * FsSize.BytesPerSector;
    1194         return VINF_SUCCESS;
    1195     }
    1196 
    1197     /* convert nt status code to VBox status code. */
    1198     /** @todo Make conversion function!. */
    1199     int rc = VERR_GENERAL_FAILURE;
    1200     switch (rcNt)
    1201     {
    1202         case STATUS_NO_MEDIA_IN_DEVICE:     rc = VERR_MEDIA_NOT_PRESENT; break;
    1203         case STATUS_VERIFY_REQUIRED:        rc = VERR_TRY_AGAIN; break;
    1204     }
    1205     LogFlow(("drvHostBaseGetMediaSize: NtQueryVolumeInformationFile -> %#lx\n", rcNt, rc));
    1206     return rc;
    1207 #else
    1208     return RTFileSeek(pThis->hFileDevice, 0, RTFILE_SEEK_END, pcb);
    1209 #endif
     1135    return drvHostBaseGetMediaSizeOs(pThis, pcb);
    12101136}
    12111137
  • trunk/src/VBox/Devices/Storage/DrvHostBase.h

    r64240 r64246  
    193193                                     void *pvBuf, uint32_t *pcbBuf, uint8_t *pbSense, size_t cbSense, uint32_t cTimeoutMillies);
    194194
     195DECLHIDDEN(int) drvHostBaseGetMediaSizeOs(PDRVHOSTBASE pThis, uint64_t *pcb);
    195196
    196197/** Makes a PDRVHOSTBASE out of a PPDMIMOUNT. */
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