Changeset 64246 in vbox
- Timestamp:
- Oct 13, 2016 1:08:51 PM (8 years ago)
- Location:
- trunk/src/VBox/Devices/Storage
- Files:
-
- 7 edited
-
DrvHostBase-darwin.cpp (modified) (1 diff)
-
DrvHostBase-freebsd.cpp (modified) (1 diff)
-
DrvHostBase-linux.cpp (modified) (2 diffs)
-
DrvHostBase-solaris.cpp (modified) (1 diff)
-
DrvHostBase-win.cpp (modified) (1 diff)
-
DrvHostBase.cpp (modified) (1 diff)
-
DrvHostBase.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DrvHostBase-darwin.cpp
r64239 r64246 122 122 } 123 123 124 125 DECLHIDDEN(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 123 123 } 124 124 125 126 DECLHIDDEN(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 31 31 # include "swab.h" 32 32 #endif 33 #include <linux/fd.h> 33 34 #include <linux/cdrom.h> 34 35 #include <limits.h> … … 127 128 } 128 129 130 DECLHIDDEN(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 167 167 } 168 168 169 DECLHIDDEN(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 113 113 } 114 114 115 DECLHIDDEN(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 1133 1133 static DECLCALLBACK(int) drvHostBaseGetMediaSize(PDRVHOSTBASE pThis, uint64_t *pcb) 1134 1134 { 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); 1210 1136 } 1211 1137 -
trunk/src/VBox/Devices/Storage/DrvHostBase.h
r64240 r64246 193 193 void *pvBuf, uint32_t *pcbBuf, uint8_t *pbSense, size_t cbSense, uint32_t cTimeoutMillies); 194 194 195 DECLHIDDEN(int) drvHostBaseGetMediaSizeOs(PDRVHOSTBASE pThis, uint64_t *pcb); 195 196 196 197 /** Makes a PDRVHOSTBASE out of a PPDMIMOUNT. */
Note:
See TracChangeset
for help on using the changeset viewer.

