VirtualBox

Changeset 47533 in vbox for trunk/src


Ignore:
Timestamp:
Aug 3, 2013 10:31:16 PM (11 years ago)
Author:
vboxsync
Message:

Rewrote fs-win.cpp into a pure native NT version, this fixes the symbolic-link-in-path-not-followed issues that caused by having to guess the volume root in order to make the win32 (wrapper) API happy.

Location:
trunk/src/VBox/Runtime
Files:
3 added
4 edited
2 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/Makefile.kmk

    r47206 r47533  
    584584        generic/RTThreadGetNativeState-generic.cpp \
    585585        nt/RTErrConvertFromNtStatus.cpp \
     586        r3/nt/fs-nt.cpp \
     587        r3/nt/pathint-nt.cpp \
    586588        r3/posix/env-posix.cpp \
    587589        r3/win/RTHandleGetStandard-win.cpp \
     
    595597        r3/win/errvars-win.cpp \
    596598        r3/win/fileio-win.cpp \
    597         r3/win/fs-win.cpp \
    598599        r3/win/init-win.cpp \
    599600        r3/win/ldrNative-win.cpp \
  • trunk/src/VBox/Runtime/nt/RTErrConvertFromNtStatus.cpp

    r44528 r47533  
    55
    66/*
    7  * Copyright (C) 2006-2010 Oracle Corporation
     7 * Copyright (C) 2006-2013 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    4141    switch (lNativeCode)
    4242    {
    43         case STATUS_SUCCESS:
    44             return VINF_SUCCESS;
    45         case STATUS_ALERTED:
    46         case STATUS_USER_APC:
    47             return VERR_INTERRUPTED;
    48         case STATUS_OBJECT_NAME_NOT_FOUND:
    49             return VERR_FILE_NOT_FOUND;
     43        case STATUS_SUCCESS:                return VINF_SUCCESS;
     44
     45        case STATUS_ALERTED:                return VERR_INTERRUPTED;
     46        case STATUS_USER_APC:               return VERR_INTERRUPTED;
     47
     48        case STATUS_INVALID_HANDLE:         return VERR_INVALID_HANDLE;
     49        case STATUS_INVALID_PARAMETER:      return VERR_INVALID_PARAMETER;
     50        case STATUS_INVALID_DEVICE_REQUEST: return VERR_IO_BAD_COMMAND;
     51        case STATUS_ACCESS_DENIED:          return VERR_ACCESS_DENIED;
     52        case STATUS_OBJECT_NAME_INVALID:    return VERR_INVALID_NAME;
     53        case STATUS_OBJECT_NAME_NOT_FOUND:  return VERR_FILE_NOT_FOUND;
     54        case STATUS_OBJECT_PATH_INVALID:    return VERR_INVALID_NAME;
     55        case STATUS_OBJECT_PATH_NOT_FOUND:  return VERR_PATH_NOT_FOUND;
    5056    }
    5157
    5258    /* unknown error. */
    53     AssertMsgFailed(("Unhandled error %ld\n", lNativeCode));
     59    AssertMsgFailed(("Unhandled error %#lx (%lu)\n", lNativeCode, lNativeCode));
    5460    return VERR_UNRESOLVED_ERROR;
    5561}
  • trunk/src/VBox/Runtime/r3/nt/fs-nt.cpp

    r47515 r47533  
    11/* $Id$ */
    22/** @file
    3  * IPRT - File System, Win32.
     3 * IPRT - File System, Native NT.
    44 */
    55
    66/*
    7  * Copyright (C) 2006-2010 Oracle Corporation
     7 * Copyright (C) 2006-2013 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    3030*******************************************************************************/
    3131#define LOG_GROUP RTLOGGROUP_FS
    32 #include <windows.h>
     32#include "internal-r3-nt.h"
    3333
    3434#include <iprt/fs.h>
     
    4141#include "internal/fs.h"
    4242
    43 /* from ntdef.h */
    44 typedef LONG NTSTATUS;
    45 
    46 /* from ntddk.h */
    47 typedef struct _IO_STATUS_BLOCK {
    48     union {
    49         NTSTATUS Status;
    50         PVOID Pointer;
    51     };
    52     ULONG_PTR Information;
    53 } IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
    54 
    55 typedef enum _FSINFOCLASS {
    56     FileFsAttributeInformation = 5,
    57 } FS_INFORMATION_CLASS, *PFS_INFORMATION_CLASS;
    58 
    59 /* from ntifs.h */
    60 
    61 typedef struct _FILE_FS_ATTRIBUTE_INFORMATION {
    62     ULONG FileSystemAttributes;
    63     LONG MaximumComponentNameLength;
    64     ULONG FIleSystemNameLength;
    65     WCHAR FileSystemName[1];
    66 } FILE_FS_ATTRIBUTE_INFORMATION, *PFILE_FS_ATTRIBUTE_INFORMATION;
    67 
    68 extern "C" NTSTATUS NTAPI NtQueryVolumeInformationFile(HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG, FS_INFORMATION_CLASS);
    69 
    70 /**
    71  * Checks quickly if this is an correct root specification.
    72  * Root specs ends with a slash of some kind.
    73  *
    74  * @returns indicator.
    75  * @param   pszFsPath       Path to check.
    76  */
    77 static bool rtFsIsRoot(const char *pszFsPath)
    78 {
    79     /*
    80      * UNC has exactly two slashes..
    81      *
    82      * Anything else starting with slashe(s) requires
    83      * expansion and will have to take the long road.
    84      */
    85     if (RTPATH_IS_SLASH(pszFsPath[0]))
    86     {
    87         if (    !RTPATH_IS_SLASH(pszFsPath[1])
    88             ||  RTPATH_IS_SLASH(pszFsPath[2]))
    89             return false;
    90 
    91         /* end of machine name */
    92         const char *pszSlash = strpbrk(pszFsPath + 2, "\\/");
    93         if (!pszSlash)
    94             return false;
    95 
    96         /* end of service name. */
    97         pszSlash = strpbrk(pszSlash + 1, "\\/");
    98         if (!pszSlash)
    99             return false;
    100 
    101         return pszSlash[1] == '\0';
    102     }
    103 
    104     /*
    105      * Ok the other alternative is driver letter.
    106      */
    107     return  pszFsPath[0] >= 'A' && pszFsPath[0] <= 'Z'
    108         &&  pszFsPath[1] == ':'
    109         &&  RTPATH_IS_SLASH(pszFsPath[2])
    110         && !pszFsPath[3];
    111 }
    112 
    113 
    114 
    115 /**
    116  * Finds the root of the specified volume.
    117  *
    118  * @returns iprt status code.
    119  * @param   pszFsPath       Path within the filesystem. Verified as one byte or more.
    120  * @param   ppwszFsRoot     Where to store the returned string. Free with rtFsFreeRoot(),
    121  */
    122 static int rtFsGetRoot(const char *pszFsPath, PRTUTF16 *ppwszFsRoot)
    123 {
    124     /*
    125      * Do straight forward stuff first,
    126      */
    127     if (rtFsIsRoot(pszFsPath))
    128         return RTStrToUtf16(pszFsPath, ppwszFsRoot);
    129 
    130     /*
    131      * Expand and add slash (if required).
    132      */
    133     char szFullPath[RTPATH_MAX];
    134     int rc = RTPathAbs(pszFsPath, szFullPath, sizeof(szFullPath));
    135     if (RT_FAILURE(rc))
    136         return rc;
    137     size_t cb = strlen(szFullPath);
    138     if (!RTPATH_IS_SLASH(szFullPath[cb - 1]))
    139     {
    140         AssertReturn(cb + 1 < RTPATH_MAX, VERR_FILENAME_TOO_LONG);
    141         szFullPath[cb] = '\\';
    142         szFullPath[++cb] = '\0';
    143     }
    144 
    145     /*
    146      * Convert the path.
    147      */
    148     rc = RTStrToUtf16(szFullPath, ppwszFsRoot);
    149     if (RT_FAILURE(rc))
    150         return rc == VERR_BUFFER_OVERFLOW ? VERR_FILENAME_TOO_LONG : rc;
    151 
    152     /*
    153      * Walk the path until our proper API is happy or there is no more path left.
    154      */
    155     PRTUTF16 pwszStart = *ppwszFsRoot;
    156     if (!GetVolumeInformationW(pwszStart, NULL, 0, NULL, NULL, 0, NULL, 0))
    157     {
    158         PRTUTF16 pwszEnd = pwszStart + RTUtf16Len(pwszStart);
    159         PRTUTF16 pwszMin = pwszStart + 2;
    160         do
    161         {
    162             /* Strip off the last path component. */
    163             while (pwszEnd-- > pwszMin)
    164                 if (RTPATH_IS_SLASH(*pwszEnd))
    165                     break;
    166             AssertReturn(pwszEnd >= pwszMin, VERR_INTERNAL_ERROR); /* leaks, but that's irrelevant for an internal error. */
    167             pwszEnd[1] = '\0';
    168         } while (!GetVolumeInformationW(pwszStart, NULL, 0, NULL, NULL, 0, NULL, 0));
    169     }
    170 
    171     return VINF_SUCCESS;
    172 }
    173 
    174 /**
    175  * Frees string returned by rtFsGetRoot().
    176  */
    177 static void rtFsFreeRoot(PRTUTF16 pwszFsRoot)
    178 {
    179     RTUtf16Free(pwszFsRoot);
    180 }
     43
    18144
    18245
     
    18447                             uint32_t *pcbBlock, uint32_t *pcbSector)
    18548{
    186     /*
    187      * Validate & get valid root path.
    188      */
    189     AssertMsgReturn(VALID_PTR(pszFsPath) && *pszFsPath, ("%p", pszFsPath), VERR_INVALID_PARAMETER);
    190     PRTUTF16 pwszFsRoot;
    191     int rc = rtFsGetRoot(pszFsPath, &pwszFsRoot);
    192     if (RT_FAILURE(rc))
    193         return rc;
    194 
    195     /*
    196      * Free and total.
    197      */
    198     if (pcbTotal || pcbFree)
    199     {
    200         ULARGE_INTEGER cbTotal;
    201         ULARGE_INTEGER cbFree;
    202         if (GetDiskFreeSpaceExW(pwszFsRoot, &cbFree, &cbTotal, NULL))
    203         {
     49    AssertPtrReturn(pszFsPath, VERR_INVALID_POINTER);
     50
     51    /*
     52     * Open the file/dir/whatever.
     53     */
     54    HANDLE hFile;
     55    int rc = rtNtPathOpen(pszFsPath,
     56                          GENERIC_READ,
     57                          FILE_ATTRIBUTE_NORMAL,
     58                          FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
     59                          FILE_OPEN,
     60                          FILE_OPEN_FOR_BACKUP_INTENT,
     61                          OBJ_CASE_INSENSITIVE,
     62                          &hFile,
     63                          NULL);
     64    if (RT_SUCCESS(rc))
     65    {
     66        /*
     67         * Get the volume information.
     68         */
     69        FILE_FS_SIZE_INFORMATION FsSizeInfo;
     70        IO_STATUS_BLOCK Ios = MY_IO_STATUS_BLOCK_INITIALIZER;
     71        NTSTATUS rcNt = NtQueryVolumeInformationFile(hFile, &Ios, &FsSizeInfo, sizeof(FsSizeInfo), FileFsSizeInformation);
     72        if (NT_SUCCESS(rcNt))
     73        {
     74            /*
     75             * Calculate the return values.
     76             */
    20477            if (pcbTotal)
    205                 *pcbTotal = cbTotal.QuadPart;
     78            {
     79                *pcbTotal = FsSizeInfo.TotalAllocationUnits.QuadPart
     80                          * FsSizeInfo.SectorsPerAllocationUnit
     81                          * FsSizeInfo.BytesPerSector;
     82                if (   *pcbTotal / FsSizeInfo.SectorsPerAllocationUnit / FsSizeInfo.BytesPerSector
     83                    != FsSizeInfo.TotalAllocationUnits.QuadPart)
     84                    *pcbTotal = UINT64_MAX;
     85            }
     86
    20687            if (pcbFree)
    207                 *pcbFree  = cbFree.QuadPart;
     88            {
     89                *pcbFree = FsSizeInfo.AvailableAllocationUnits.QuadPart
     90                         * FsSizeInfo.SectorsPerAllocationUnit
     91                         * FsSizeInfo.BytesPerSector;
     92                if (   *pcbFree / FsSizeInfo.SectorsPerAllocationUnit / FsSizeInfo.BytesPerSector
     93                    != FsSizeInfo.AvailableAllocationUnits.QuadPart)
     94                    *pcbFree = UINT64_MAX;
     95            }
     96
     97            if (pcbBlock)
     98            {
     99                *pcbBlock  = FsSizeInfo.SectorsPerAllocationUnit * FsSizeInfo.BytesPerSector;
     100                if (*pcbBlock / FsSizeInfo.BytesPerSector != FsSizeInfo.SectorsPerAllocationUnit)
     101                    rc = VERR_OUT_OF_RANGE;
     102            }
     103
     104            if (pcbSector)
     105                *pcbSector = FsSizeInfo.BytesPerSector;
    208106        }
    209107        else
    210         {
    211             DWORD Err = GetLastError();
    212             rc = RTErrConvertFromWin32(Err);
    213             Log(("RTFsQuerySizes(%s,): GetDiskFreeSpaceEx failed with lasterr %d (%Rrc)\n",
    214                  pszFsPath, Err, rc));
    215         }
    216     }
    217 
    218     /*
    219      * Block and sector size.
    220      */
    221     if (    RT_SUCCESS(rc)
    222         &&  (pcbBlock || pcbSector))
    223     {
    224         DWORD dwDummy1, dwDummy2;
    225         DWORD cbSector;
    226         DWORD cSectorsPerCluster;
    227         if (GetDiskFreeSpaceW(pwszFsRoot, &cSectorsPerCluster, &cbSector, &dwDummy1, &dwDummy2))
    228         {
    229             if (pcbBlock)
    230                 *pcbBlock = cbSector * cSectorsPerCluster;
    231             if (pcbSector)
    232                 *pcbSector = cbSector;
     108            rc = RTErrConvertFromNtStatus(rcNt);
     109
     110        rtNtPathClose(hFile);
     111    }
     112    return rc;
     113}
     114
     115
     116RTR3DECL(int) RTFsQuerySerial(const char *pszFsPath, uint32_t *pu32Serial)
     117{
     118    /*
     119     * Validate & get valid root path.
     120     */
     121    AssertPtrReturn(pszFsPath, VERR_INVALID_POINTER);
     122    AssertPtrReturn(pu32Serial, VERR_INVALID_POINTER);
     123
     124    /*
     125     * Open the file/dir/whatever.
     126     */
     127    HANDLE hFile;
     128    int rc = rtNtPathOpen(pszFsPath,
     129                          GENERIC_READ,
     130                          FILE_ATTRIBUTE_NORMAL,
     131                          FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
     132                          FILE_OPEN,
     133                          FILE_OPEN_FOR_BACKUP_INTENT,
     134                          OBJ_CASE_INSENSITIVE,
     135                          &hFile,
     136                          NULL);
     137    if (RT_SUCCESS(rc))
     138    {
     139        /*
     140         * Get the volume information.
     141         */
     142        union
     143        {
     144             FILE_FS_VOLUME_INFORMATION FsVolInfo;
     145             uint8_t abBuf[sizeof(FILE_FS_VOLUME_INFORMATION) + 4096];
     146        } u;
     147        IO_STATUS_BLOCK Ios = MY_IO_STATUS_BLOCK_INITIALIZER;
     148        NTSTATUS rcNt = NtQueryVolumeInformationFile(hFile, &Ios, &u, sizeof(u), FileFsVolumeInformation);
     149        if (NT_SUCCESS(rcNt))
     150            *pu32Serial = u.FsVolInfo.VolumeSerialNumber;
     151        else
     152            rc = RTErrConvertFromNtStatus(rcNt);
     153
     154        rtNtPathClose(hFile);
     155    }
     156    return rc;
     157}
     158
     159
     160RTR3DECL(int) RTFsQueryProperties(const char *pszFsPath, PRTFSPROPERTIES pProperties)
     161{
     162    /*
     163     * Validate & get valid root path.
     164     */
     165    AssertPtrReturn(pszFsPath, VERR_INVALID_POINTER);
     166    AssertPtrReturn(pProperties, VERR_INVALID_POINTER);
     167
     168    /*
     169     * Open the file/dir/whatever.
     170     */
     171    HANDLE hFile;
     172    int rc = rtNtPathOpen(pszFsPath,
     173                          GENERIC_READ,
     174                          FILE_ATTRIBUTE_NORMAL,
     175                          FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
     176                          FILE_OPEN,
     177                          FILE_OPEN_FOR_BACKUP_INTENT,
     178                          OBJ_CASE_INSENSITIVE,
     179                          &hFile,
     180                          NULL);
     181    if (RT_SUCCESS(rc))
     182    {
     183        /*
     184         * Get the volume information.
     185         */
     186        union
     187        {
     188            FILE_FS_ATTRIBUTE_INFORMATION FsAttrInfo;
     189            uint8_t abBuf[sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 4096];
     190        } u;
     191        IO_STATUS_BLOCK Ios = MY_IO_STATUS_BLOCK_INITIALIZER;
     192        NTSTATUS rcNt = NtQueryVolumeInformationFile(hFile, &Ios, &u, sizeof(u), FileFsAttributeInformation);
     193        if (NT_SUCCESS(rcNt))
     194        {
     195            FILE_FS_DEVICE_INFORMATION FsDevInfo;
     196            rcNt = NtQueryVolumeInformationFile(hFile, &Ios, &FsDevInfo, sizeof(FsDevInfo), FileFsDeviceInformation);
     197            if (NT_SUCCESS(rcNt))
     198            {
     199                /*
     200                 * Fill in the return structure.
     201                 */
     202                memset(pProperties, 0, sizeof(*pProperties));
     203                pProperties->cbMaxComponent   = u.FsAttrInfo.MaximumComponentNameLength;
     204                pProperties->fFileCompression = !!(u.FsAttrInfo.FileSystemAttributes & FILE_FILE_COMPRESSION);
     205                pProperties->fCompressed      = !!(u.FsAttrInfo.FileSystemAttributes & FILE_VOLUME_IS_COMPRESSED);
     206                pProperties->fReadOnly        = !!(u.FsAttrInfo.FileSystemAttributes & FILE_READ_ONLY_VOLUME);
     207                pProperties->fSupportsUnicode = !!(u.FsAttrInfo.FileSystemAttributes & FILE_UNICODE_ON_DISK);
     208                pProperties->fCaseSensitive   = false;    /* win32 is case preserving only */
     209                /** @todo r=bird: What about FILE_CASE_SENSITIVE_SEARCH ?  Is this set for NTFS
     210                 *        as well perchance?  If so, better mention it instead of just setting
     211                 *        fCaseSensitive to false. */
     212
     213                /* figure the remote stuff */
     214                pProperties->fRemote          = RT_BOOL(FsDevInfo.Characteristics & FILE_REMOTE_DEVICE);
     215            }
     216            else
     217                rc = RTErrConvertFromNtStatus(rcNt);
    233218        }
    234219        else
    235         {
    236             DWORD Err = GetLastError();
    237             rc = RTErrConvertFromWin32(Err);
    238             Log(("RTFsQuerySizes(%s,): GetDiskFreeSpace failed with lasterr %d (%Rrc)\n",
    239                  pszFsPath, Err, rc));
    240         }
    241     }
    242 
    243     rtFsFreeRoot(pwszFsRoot);
    244     return rc;
    245 }
    246 
    247 
    248 /**
    249  * Query the serial number of a filesystem.
    250  *
    251  * @returns iprt status code.
    252  * @param   pszFsPath       Path within the mounted filesystem.
    253  * @param   pu32Serial      Where to store the serial number.
    254  */
    255 RTR3DECL(int) RTFsQuerySerial(const char *pszFsPath, uint32_t *pu32Serial)
    256 {
    257     /*
    258      * Validate & get valid root path.
    259      */
    260     AssertMsgReturn(VALID_PTR(pszFsPath) && *pszFsPath, ("%p", pszFsPath), VERR_INVALID_PARAMETER);
    261     AssertMsgReturn(VALID_PTR(pu32Serial), ("%p", pu32Serial), VERR_INVALID_PARAMETER);
    262     PRTUTF16 pwszFsRoot;
    263     int rc = rtFsGetRoot(pszFsPath, &pwszFsRoot);
    264     if (RT_FAILURE(rc))
    265         return rc;
    266 
    267     /*
    268      * Do work.
    269      */
    270     DWORD   dwMaxName;
    271     DWORD   dwFlags;
    272     DWORD   dwSerial;
    273     if (GetVolumeInformationW(pwszFsRoot, NULL, 0, &dwSerial, &dwMaxName, &dwFlags, NULL, 0))
    274         *pu32Serial = dwSerial;
    275     else
    276     {
    277         DWORD Err = GetLastError();
    278         rc = RTErrConvertFromWin32(Err);
    279         Log(("RTFsQuerySizes(%s,): GetDiskFreeSpaceEx failed with lasterr %d (%Rrc)\n",
    280              pszFsPath, Err, rc));
    281     }
    282 
    283     RTUtf16Free(pwszFsRoot);
    284     return rc;
    285 }
    286 
    287 
    288 /**
    289  * Query the properties of a mounted filesystem.
    290  *
    291  * @returns iprt status code.
    292  * @param   pszFsPath       Path within the mounted filesystem.
    293  * @param   pProperties     Where to store the properties.
    294  */
    295 RTR3DECL(int) RTFsQueryProperties(const char *pszFsPath, PRTFSPROPERTIES pProperties)
    296 {
    297     /*
    298      * Validate & get valid root path.
    299      */
    300     AssertMsgReturn(VALID_PTR(pszFsPath) && *pszFsPath, ("%p", pszFsPath), VERR_INVALID_PARAMETER);
    301     AssertMsgReturn(VALID_PTR(pProperties), ("%p", pProperties), VERR_INVALID_PARAMETER);
    302     PRTUTF16 pwszFsRoot;
    303     int rc = rtFsGetRoot(pszFsPath, &pwszFsRoot);
    304     if (RT_FAILURE(rc))
    305         return rc;
    306 
    307     /*
    308      * Do work.
    309      */
    310     DWORD   dwMaxName;
    311     DWORD   dwFlags;
    312     DWORD   dwSerial;
    313     if (GetVolumeInformationW(pwszFsRoot, NULL, 0, &dwSerial, &dwMaxName, &dwFlags, NULL, 0))
    314     {
    315         memset(pProperties, 0, sizeof(*pProperties));
    316         pProperties->cbMaxComponent   = dwMaxName;
    317         pProperties->fFileCompression = !!(dwFlags & FILE_FILE_COMPRESSION);
    318         pProperties->fCompressed      = !!(dwFlags & FILE_VOLUME_IS_COMPRESSED);
    319         pProperties->fReadOnly        = !!(dwFlags & FILE_READ_ONLY_VOLUME);
    320         pProperties->fSupportsUnicode = !!(dwFlags & FILE_UNICODE_ON_DISK);
    321         pProperties->fCaseSensitive   = false;    /* win32 is case preserving only */
    322         /** @todo r=bird: What about FILE_CASE_SENSITIVE_SEARCH ?  Is this set for NTFS
    323          *        as well perchance?  If so, better mention it instead of just setting
    324          *        fCaseSensitive to false. */
    325         pProperties->fRemote          = false;    /* no idea yet */
    326     }
    327     else
    328     {
    329         DWORD Err = GetLastError();
    330         rc = RTErrConvertFromWin32(Err);
    331         Log(("RTFsQuerySizes(%s,): GetVolumeInformation failed with lasterr %d (%Rrc)\n",
    332              pszFsPath, Err, rc));
    333     }
    334 
    335     RTUtf16Free(pwszFsRoot);
     220            rc = RTErrConvertFromNtStatus(rcNt);
     221
     222        rtNtPathClose(hFile);
     223    }
    336224    return rc;
    337225}
     
    347235 * @param   cch2                The length of the second string.
    348236 */
    349 static bool rtFsWinAreEqual(WCHAR const *pwsz1, size_t cch1, const char *psz2, size_t cch2)
     237static bool rtFsCompWideStrAndAscii(WCHAR const *pwsz1, size_t cch1, const char *psz2, size_t cch2)
    350238{
    351239    if (cch1 != cch2 * 2)
     
    364252RTR3DECL(int) RTFsQueryType(const char *pszFsPath, PRTFSTYPE penmType)
    365253{
     254    /*
     255     * Validate input.
     256     */
    366257    *penmType = RTFSTYPE_UNKNOWN;
    367 
    368258    AssertPtrReturn(pszFsPath, VERR_INVALID_POINTER);
    369259    AssertReturn(*pszFsPath, VERR_INVALID_PARAMETER);
    370260
    371261    /*
    372      * Convert the path and try open it.
    373      */
    374     PRTUTF16 pwszFsPath;
    375     int rc = RTStrToUtf16(pszFsPath, &pwszFsPath);
     262     * Open the file/dir/whatever.
     263     */
     264    HANDLE hFile;
     265    int rc = rtNtPathOpen(pszFsPath,
     266                          GENERIC_READ,
     267                          FILE_ATTRIBUTE_NORMAL,
     268                          FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
     269                          FILE_OPEN,
     270                          FILE_OPEN_FOR_BACKUP_INTENT,
     271                          OBJ_CASE_INSENSITIVE,
     272                          &hFile,
     273                          NULL);
    376274    if (RT_SUCCESS(rc))
    377275    {
    378         HANDLE hFile = CreateFileW(pwszFsPath,
    379                                    GENERIC_READ,
    380                                    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
    381                                    NULL,
    382                                    OPEN_EXISTING,
    383                                    FILE_FLAG_BACKUP_SEMANTICS,
    384                                    NULL);
    385         if (hFile != INVALID_HANDLE_VALUE)
    386         {
    387             /*
    388              * Use the NT api directly to get the file system name.
    389              */
    390             char            abBuf[8192];
    391             IO_STATUS_BLOCK Ios;
    392             NTSTATUS        rcNt = NtQueryVolumeInformationFile(hFile, &Ios,
    393                                                                 abBuf, sizeof(abBuf),
    394                                                                 FileFsAttributeInformation);
    395             if (rcNt >= 0)
    396             {
    397                 PFILE_FS_ATTRIBUTE_INFORMATION pFsAttrInfo = (PFILE_FS_ATTRIBUTE_INFORMATION)abBuf;
    398                 if (pFsAttrInfo->FIleSystemNameLength)
    399                 {
    400                 }
    401 #define IS_FS(szName) \
    402     rtFsWinAreEqual(pFsAttrInfo->FileSystemName, pFsAttrInfo->FIleSystemNameLength, szName, sizeof(szName) - 1)
    403                 if (IS_FS("NTFS"))
    404                     *penmType = RTFSTYPE_NTFS;
    405                 else if (IS_FS("FAT"))
    406                     *penmType = RTFSTYPE_FAT;
    407                 else if (IS_FS("FAT32"))
    408                     *penmType = RTFSTYPE_FAT;
    409                 else if (IS_FS("VBoxSharedFolderFS"))
    410                     *penmType = RTFSTYPE_VBOXSHF;
     276        /*
     277         * Get the file system name.
     278         */
     279        union
     280        {
     281            FILE_FS_ATTRIBUTE_INFORMATION FsAttrInfo;
     282            uint8_t abBuf[sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 4096];
     283        } u;
     284        IO_STATUS_BLOCK Ios = MY_IO_STATUS_BLOCK_INITIALIZER;
     285        NTSTATUS rcNt = NtQueryVolumeInformationFile(hFile, &Ios, &u, sizeof(u), FileFsAttributeInformation);
     286        if (NT_SUCCESS(rcNt))
     287        {
     288#define IS_FS(a_szName) \
     289rtFsCompWideStrAndAscii(u.FsAttrInfo.FileSystemName, u.FsAttrInfo.FileSystemNameLength, RT_STR_TUPLE(a_szName))
     290            if (IS_FS("NTFS"))
     291                *penmType = RTFSTYPE_NTFS;
     292            else if (IS_FS("FAT"))
     293                *penmType = RTFSTYPE_FAT;
     294            else if (IS_FS("FAT32"))
     295                *penmType = RTFSTYPE_FAT;
     296            else if (IS_FS("VBoxSharedFolderFS"))
     297                *penmType = RTFSTYPE_VBOXSHF;
    411298#undef IS_FS
    412             }
    413             else
    414                 rc = RTErrConvertFromNtStatus(rcNt);
    415             CloseHandle(hFile);
    416299        }
    417300        else
    418             rc = RTErrConvertFromWin32(GetLastError());
    419         RTUtf16Free(pwszFsPath);
     301            rc = RTErrConvertFromNtStatus(rcNt);
     302
     303        rtNtPathClose(hFile);
    420304    }
    421305    return rc;
    422306}
     307
  • trunk/src/VBox/Runtime/r3/win/ntdll-mini-implib.c

    r43386 r47533  
    3737typedef INT     MEMORY_INFORMATION_CLASS;
    3838typedef INT     PROCESSINFOCLASS;
     39typedef PVOID   POBJECT_ATTRIBUTES;
    3940
    4041
     
    113114
    114115
     116
     117/* Handles: */
     118
     119NTSYSAPI NTSTATUS NTAPI NtCreateFile(OUT PHANDLE FileHandle,
     120                                     IN ACCESS_MASK DesiredAccess,
     121                                     IN POBJECT_ATTRIBUTES ObjectAttributes,
     122                                     OUT PIO_STATUS_BLOCK IoStatusBlock,
     123                                     IN PLARGE_INTEGER AllocationSize OPTIONAL,
     124                                     IN ULONG FileAttributes,
     125                                     IN ULONG ShareAccess,
     126                                     IN ULONG CreateDisposition,
     127                                     IN ULONG CreateOptions,
     128                                     IN PVOID EaBuffer,
     129                                     IN ULONG EaLength)
     130{
     131    return -1;
     132}
     133
     134NTSYSAPI NTSTATUS NTAPI NtClose(IN HANDLE Handle)
     135{
     136    return -1;
     137}
     138
  • trunk/src/VBox/Runtime/r3/win/ntdll-mini-implib.def

    r44529 r47533  
    55
    66;
    7 ; Copyright (C) 2010-2012 Oracle Corporation
     7; Copyright (C) 2010-2013 Oracle Corporation
    88;
    99; This file is part of VirtualBox Open Source Edition (OSE), as
     
    3535    NtQueryVolumeInformationFile
    3636    NtQueryVirtualMemory
    37 
     37    NtCreateFile
     38    NtClose
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