VirtualBox

Changeset 30185 in vbox


Ignore:
Timestamp:
Jun 14, 2010 8:38:54 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
62642
Message:

AsyncCompletion/File: Quick fix for raw disks on Windows

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/PDMAsyncCompletionFile.cpp

    r30136 r30185  
    3838#include <iprt/thread.h>
    3939#include <iprt/path.h>
     40
     41#ifdef RT_OS_WINDOWS
     42# define _WIN32_WINNT 0x0500
     43# include <windows.h>
     44# include <winioctl.h>
     45#endif
    4046
    4147#include "PDMAsyncCompletionFileInternal.h"
     
    598604}
    599605
     606/**
     607 * Get the size of the given file.
     608 * Works for block devices too.
     609 *
     610 * @returns VBox status code.
     611 * @param   hFile    The file handle.
     612 * @param   pcbSize  Where to store the size of the file on success.
     613 */
     614static int pdmacFileEpNativeGetSize(RTFILE hFile, uint64_t *pcbSize)
     615{
     616    int rc = VINF_SUCCESS;
     617    uint64_t cbSize = 0;
     618
     619    rc = RTFileGetSize(hFile, &cbSize);
     620    if (RT_SUCCESS(rc) && (cbSize != 0))
     621        *pcbSize = cbSize;
     622    else
     623    {
     624#ifdef RT_OS_WINDOWS
     625        DISK_GEOMETRY DriveGeo;
     626        DWORD cbDriveGeo;
     627        if (DeviceIoControl((HANDLE)hFile,
     628                            IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0,
     629                            &DriveGeo, sizeof(DriveGeo), &cbDriveGeo, NULL))
     630        {
     631            if (   DriveGeo.MediaType == FixedMedia
     632                || DriveGeo.MediaType == RemovableMedia)
     633            {
     634                cbSize =     DriveGeo.Cylinders.QuadPart
     635                         *   DriveGeo.TracksPerCylinder
     636                         *   DriveGeo.SectorsPerTrack
     637                         *   DriveGeo.BytesPerSector;
     638
     639                GET_LENGTH_INFORMATION DiskLenInfo;
     640                DWORD junk;
     641                if (DeviceIoControl((HANDLE)hFile,
     642                                    IOCTL_DISK_GET_LENGTH_INFO, NULL, 0,
     643                                    &DiskLenInfo, sizeof(DiskLenInfo), &junk, (LPOVERLAPPED)NULL))
     644                {
     645                    /* IOCTL_DISK_GET_LENGTH_INFO is supported -- override cbSize. */
     646                    cbSize = DiskLenInfo.Length.QuadPart;
     647                }
     648
     649                rc = VINF_SUCCESS;
     650            }
     651            else
     652            {
     653                rc = VERR_INVALID_PARAMETER;
     654            }
     655        }
     656        else
     657        {
     658            rc = RTErrConvertFromWin32(GetLastError());
     659        }
     660#else
     661        /* Could be a block device */
     662        rc = RTFileSeek(hFile, 0, RTFILE_SEEK_END, &cbSize);
     663
     664#endif
     665        if (RT_SUCCESS(rc) && (cbSize != 0))
     666            *pcbSize = cbSize;
     667        else if (RT_SUCCESS(rc))
     668            rc = VERR_NOT_SUPPORTED;
     669    }
     670
     671    return rc;
     672}
     673
    600674static int pdmacFileInitialize(PPDMASYNCCOMPLETIONEPCLASS pClassGlobals, PCFGMNODE pCfgNode)
    601675{
     
    748822            uint64_t cbSize;
    749823
    750             rc = RTFileGetSize(File, &cbSize);
     824            rc = pdmacFileEpNativeGetSize(File, &cbSize);
     825            Assert(RT_FAILURE(rc) || cbSize != 0);
     826
    751827            if (RT_SUCCESS(rc) && ((cbSize % 512) == 0))
    752828                fFileFlags |= RTFILE_O_NO_CACHE;
     
    804880        pEpFile->fFlags = fFileFlags;
    805881
    806         rc = RTFileGetSize(pEpFile->File, (uint64_t *)&pEpFile->cbFile);
    807         if (RT_SUCCESS(rc) && (pEpFile->cbFile == 0))
    808         {
    809             /* Could be a block device */
    810             rc = RTFileSeek(pEpFile->File, 0, RTFILE_SEEK_END, (uint64_t *)&pEpFile->cbFile);
    811         }
     882        rc = pdmacFileEpNativeGetSize(pEpFile->File, (uint64_t *)&pEpFile->cbFile);
     883        Assert(RT_FAILURE(rc) || pEpFile->cbFile != 0);
    812884
    813885        if (RT_SUCCESS(rc))
Note: See TracChangeset for help on using the changeset viewer.

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