VirtualBox

Ignore:
Timestamp:
Aug 4, 2013 1:52:13 PM (11 years ago)
Author:
vboxsync
Message:

split the directory open/enum/close code out of dir-win.cpp and into direnum-win.cpp.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r3/win/dir-win.cpp

    r44528 r47534  
    11/* $Id$ */
    22/** @file
    3  * IPRT - Directory, win32.
     3 * IPRT - Directory, Windows.
    44 */
    55
     
    3131#define LOG_GROUP RTLOGGROUP_DIR
    3232#include <Windows.h>
    33 #include <io.h>
    3433
    3534#include <iprt/dir.h>
    3635#include <iprt/path.h>
    37 #include <iprt/alloc.h>
     36#include <iprt/mem.h>
    3837#include <iprt/string.h>
    3938#include <iprt/assert.h>
    40 #include <iprt/param.h>
    4139#include <iprt/err.h>
    4240#include <iprt/file.h>
     
    4442#include "internal/fs.h"
    4543#include "internal/path.h"
    46 #include "internal/dir.h"
    4744
    4845
     
    130127
    131128
    132 int rtDirNativeOpen(PRTDIR pDir, char *pszPathBuf)
    133 {
    134     /*
    135      * Setup the search expression.
    136      *
    137      * pszPathBuf is pointing to the return 4K return buffer for the RTPathReal()
    138      * call in rtDirOpenCommon(), so all we gota do is check that we don't overflow
    139      * it when adding the wildcard expression.
    140      */
    141     size_t cbExpr;
    142     const char *pszExpr;
    143     if (pDir->enmFilter == RTDIRFILTER_WINNT)
    144     {
    145         pszExpr = pDir->pszFilter;
    146         cbExpr  = pDir->cchFilter + 1;
    147     }
    148     else
    149     {
    150         pszExpr = "*";
    151         cbExpr  = sizeof("*");
    152     }
    153     if (pDir->cchPath + cbExpr > RTPATH_MAX)
    154         return VERR_FILENAME_TOO_LONG;
    155     memcpy(pszPathBuf + pDir->cchPath, pszExpr, cbExpr);
    156 
    157 
    158     /*
    159      * Attempt opening the search.
    160      */
    161     int rc = VINF_SUCCESS;
    162     PRTUTF16 pwszName;
    163     rc = RTStrToUtf16(pszPathBuf, &pwszName);
    164     if (RT_SUCCESS(rc))
    165     {
    166         pDir->hDir    = FindFirstFileW((LPCWSTR)pwszName, &pDir->Data);
    167         if (pDir->hDir != INVALID_HANDLE_VALUE)
    168             pDir->fDataUnread = true;
    169         else
    170         {
    171             DWORD dwErr = GetLastError();
    172             /* Theoretical case of an empty directory or more normal case of no matches. */
    173             if (   dwErr == ERROR_FILE_NOT_FOUND
    174                 || dwErr == ERROR_NO_MORE_FILES /* ???*/)
    175                 pDir->fDataUnread = false;
    176             else
    177                 rc = RTErrConvertFromWin32(GetLastError());
    178         }
    179         RTUtf16Free(pwszName);
    180     }
    181 
    182     return rc;
    183 }
    184 
    185 
    186 RTDECL(int) RTDirClose(PRTDIR pDir)
    187 {
    188     /*
    189      * Validate input.
    190      */
    191     if (!pDir)
    192         return VERR_INVALID_PARAMETER;
    193     if (pDir->u32Magic != RTDIR_MAGIC)
    194     {
    195         AssertMsgFailed(("Invalid pDir=%p\n", pDir));
    196         return VERR_INVALID_PARAMETER;
    197     }
    198 
    199     /*
    200      * Close the handle.
    201      */
    202     pDir->u32Magic++;
    203     if (pDir->hDir != INVALID_HANDLE_VALUE)
    204     {
    205         BOOL fRc = FindClose(pDir->hDir);
    206         Assert(fRc);
    207         pDir->hDir = INVALID_HANDLE_VALUE;
    208     }
    209     RTStrFree(pDir->pszName);
    210     pDir->pszName = NULL;
    211     RTMemFree(pDir);
    212 
    213     return VINF_SUCCESS;
    214 }
    215 
    216 
    217 RTDECL(int) RTDirRead(PRTDIR pDir, PRTDIRENTRY pDirEntry, size_t *pcbDirEntry)
    218 {
    219     /*
    220      * Validate input.
    221      */
    222     if (!pDir || pDir->u32Magic != RTDIR_MAGIC)
    223     {
    224         AssertMsgFailed(("Invalid pDir=%p\n", pDir));
    225         return VERR_INVALID_PARAMETER;
    226     }
    227     if (!pDirEntry)
    228     {
    229         AssertMsgFailed(("Invalid pDirEntry=%p\n", pDirEntry));
    230         return VERR_INVALID_PARAMETER;
    231     }
    232     size_t cbDirEntry = sizeof(*pDirEntry);
    233     if (pcbDirEntry)
    234     {
    235         cbDirEntry = *pcbDirEntry;
    236         if (cbDirEntry < RT_UOFFSETOF(RTDIRENTRY, szName[2]))
    237         {
    238             AssertMsgFailed(("Invalid *pcbDirEntry=%d (min %d)\n", *pcbDirEntry, RT_OFFSETOF(RTDIRENTRY, szName[2])));
    239             return VERR_INVALID_PARAMETER;
    240         }
    241     }
    242 
    243     /*
    244      * Fetch data?
    245      */
    246     if (!pDir->fDataUnread)
    247     {
    248         RTStrFree(pDir->pszName);
    249         pDir->pszName = NULL;
    250 
    251         BOOL fRc = FindNextFileW(pDir->hDir, &pDir->Data);
    252         if (!fRc)
    253         {
    254             int iErr = GetLastError();
    255             if (pDir->hDir == INVALID_HANDLE_VALUE || iErr == ERROR_NO_MORE_FILES)
    256                 return VERR_NO_MORE_FILES;
    257             return RTErrConvertFromWin32(iErr);
    258         }
    259     }
    260 
    261     /*
    262      * Convert the filename to UTF-8.
    263      */
    264     if (!pDir->pszName)
    265     {
    266         int rc = RTUtf16ToUtf8((PCRTUTF16)pDir->Data.cFileName, &pDir->pszName);
    267         if (RT_FAILURE(rc))
    268         {
    269             pDir->pszName = NULL;
    270             return rc;
    271         }
    272         pDir->cchName = strlen(pDir->pszName);
    273     }
    274 
    275     /*
    276      * Check if we've got enough space to return the data.
    277      */
    278     const char  *pszName    = pDir->pszName;
    279     const size_t cchName    = pDir->cchName;
    280     const size_t cbRequired = RT_OFFSETOF(RTDIRENTRY, szName[1]) + cchName;
    281     if (pcbDirEntry)
    282         *pcbDirEntry = cbRequired;
    283     if (cbRequired > cbDirEntry)
    284         return VERR_BUFFER_OVERFLOW;
    285 
    286     /*
    287      * Setup the returned data.
    288      */
    289     pDir->fDataUnread  = false;
    290     pDirEntry->INodeId = 0; /** @todo we can use the fileid here if we must (see GetFileInformationByHandle). */
    291     pDirEntry->enmType = pDir->Data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
    292                        ? RTDIRENTRYTYPE_DIRECTORY : RTDIRENTRYTYPE_FILE;
    293     pDirEntry->cbName  = (uint16_t)cchName;
    294     Assert(pDirEntry->cbName == cchName);
    295     memcpy(pDirEntry->szName, pszName, cchName + 1);
    296 
    297     return VINF_SUCCESS;
    298 }
    299 
    300 
    301 RTDECL(int) RTDirReadEx(PRTDIR pDir, PRTDIRENTRYEX pDirEntry, size_t *pcbDirEntry, RTFSOBJATTRADD enmAdditionalAttribs, uint32_t fFlags)
    302 {
    303     /** @todo Symlinks: Find[First|Next]FileW will return info about
    304         the link, so RTPATH_F_FOLLOW_LINK is not handled correctly. */
    305     /*
    306      * Validate input.
    307      */
    308     if (!pDir || pDir->u32Magic != RTDIR_MAGIC)
    309     {
    310         AssertMsgFailed(("Invalid pDir=%p\n", pDir));
    311         return VERR_INVALID_PARAMETER;
    312     }
    313     if (!pDirEntry)
    314     {
    315         AssertMsgFailed(("Invalid pDirEntry=%p\n", pDirEntry));
    316         return VERR_INVALID_PARAMETER;
    317     }
    318     if (    enmAdditionalAttribs < RTFSOBJATTRADD_NOTHING
    319         ||  enmAdditionalAttribs > RTFSOBJATTRADD_LAST)
    320     {
    321         AssertMsgFailed(("Invalid enmAdditionalAttribs=%p\n", enmAdditionalAttribs));
    322         return VERR_INVALID_PARAMETER;
    323     }
    324     AssertMsgReturn(RTPATH_F_IS_VALID(fFlags, 0), ("%#x\n", fFlags), VERR_INVALID_PARAMETER);
    325     size_t cbDirEntry = sizeof(*pDirEntry);
    326     if (pcbDirEntry)
    327     {
    328         cbDirEntry = *pcbDirEntry;
    329         if (cbDirEntry < RT_UOFFSETOF(RTDIRENTRYEX, szName[2]))
    330         {
    331             AssertMsgFailed(("Invalid *pcbDirEntry=%d (min %d)\n", *pcbDirEntry, RT_OFFSETOF(RTDIRENTRYEX, szName[2])));
    332             return VERR_INVALID_PARAMETER;
    333         }
    334     }
    335 
    336     /*
    337      * Fetch data?
    338      */
    339     if (!pDir->fDataUnread)
    340     {
    341         RTStrFree(pDir->pszName);
    342         pDir->pszName = NULL;
    343 
    344         BOOL fRc = FindNextFileW(pDir->hDir, &pDir->Data);
    345         if (!fRc)
    346         {
    347             int iErr = GetLastError();
    348             if (pDir->hDir == INVALID_HANDLE_VALUE || iErr == ERROR_NO_MORE_FILES)
    349                 return VERR_NO_MORE_FILES;
    350             return RTErrConvertFromWin32(iErr);
    351         }
    352     }
    353 
    354     /*
    355      * Convert the filename to UTF-8.
    356      */
    357     if (!pDir->pszName)
    358     {
    359         int rc = RTUtf16ToUtf8((PCRTUTF16)pDir->Data.cFileName, &pDir->pszName);
    360         if (RT_FAILURE(rc))
    361         {
    362             pDir->pszName = NULL;
    363             return rc;
    364         }
    365         pDir->cchName = strlen(pDir->pszName);
    366     }
    367 
    368     /*
    369      * Check if we've got enough space to return the data.
    370      */
    371     const char  *pszName    = pDir->pszName;
    372     const size_t cchName    = pDir->cchName;
    373     const size_t cbRequired = RT_OFFSETOF(RTDIRENTRYEX, szName[1]) + cchName;
    374     if (pcbDirEntry)
    375         *pcbDirEntry = cbRequired;
    376     if (cbRequired > cbDirEntry)
    377         return VERR_BUFFER_OVERFLOW;
    378 
    379     /*
    380      * Setup the returned data.
    381      */
    382     pDir->fDataUnread  = false;
    383     pDirEntry->cbName  = (uint16_t)cchName;
    384     Assert(pDirEntry->cbName == cchName);
    385     memcpy(pDirEntry->szName, pszName, cchName + 1);
    386     if (pDir->Data.cAlternateFileName[0])
    387     {
    388         /* copy and calc length */
    389         PCRTUTF16 pwszSrc = (PCRTUTF16)pDir->Data.cAlternateFileName;
    390         PRTUTF16  pwszDst = pDirEntry->wszShortName;
    391         uint32_t  off = 0;
    392         while (pwszSrc[off] && off < RT_ELEMENTS(pDirEntry->wszShortName) - 1U)
    393         {
    394             pwszDst[off] = pwszSrc[off];
    395             off++;
    396         }
    397         pDirEntry->cwcShortName = (uint16_t)off;
    398 
    399         /* zero the rest */
    400         do
    401             pwszDst[off++] = '\0';
    402         while (off < RT_ELEMENTS(pDirEntry->wszShortName));
    403     }
    404     else
    405     {
    406         memset(pDirEntry->wszShortName, 0, sizeof(pDirEntry->wszShortName));
    407         pDirEntry->cwcShortName = 0;
    408     }
    409 
    410     pDirEntry->Info.cbObject    = ((uint64_t)pDir->Data.nFileSizeHigh << 32)
    411                                 |  (uint64_t)pDir->Data.nFileSizeLow;
    412     pDirEntry->Info.cbAllocated = pDirEntry->Info.cbObject;
    413 
    414     Assert(sizeof(uint64_t) == sizeof(pDir->Data.ftCreationTime));
    415     RTTimeSpecSetNtTime(&pDirEntry->Info.BirthTime,         *(uint64_t *)&pDir->Data.ftCreationTime);
    416     RTTimeSpecSetNtTime(&pDirEntry->Info.AccessTime,        *(uint64_t *)&pDir->Data.ftLastAccessTime);
    417     RTTimeSpecSetNtTime(&pDirEntry->Info.ModificationTime,  *(uint64_t *)&pDir->Data.ftLastWriteTime);
    418     pDirEntry->Info.ChangeTime  = pDirEntry->Info.ModificationTime;
    419 
    420     pDirEntry->Info.Attr.fMode  = rtFsModeFromDos((pDir->Data.dwFileAttributes << RTFS_DOS_SHIFT) & RTFS_DOS_MASK_NT,
    421                                                    pszName, cchName);
    422 
    423     /*
    424      * Requested attributes (we cannot provide anything actually).
    425      */
    426     switch (enmAdditionalAttribs)
    427     {
    428         case RTFSOBJATTRADD_EASIZE:
    429             pDirEntry->Info.Attr.enmAdditional          = RTFSOBJATTRADD_EASIZE;
    430             pDirEntry->Info.Attr.u.EASize.cb            = 0;
    431             break;
    432 
    433         case RTFSOBJATTRADD_UNIX:
    434             pDirEntry->Info.Attr.enmAdditional          = RTFSOBJATTRADD_UNIX;
    435             pDirEntry->Info.Attr.u.Unix.uid             = ~0U;
    436             pDirEntry->Info.Attr.u.Unix.gid             = ~0U;
    437             pDirEntry->Info.Attr.u.Unix.cHardlinks      = 1;
    438             pDirEntry->Info.Attr.u.Unix.INodeIdDevice   = 0; /** @todo Use the volume serial number (see GetFileInformationByHandle). */
    439             pDirEntry->Info.Attr.u.Unix.INodeId         = 0; /** @todo Use the fileid (see GetFileInformationByHandle). */
    440             pDirEntry->Info.Attr.u.Unix.fFlags          = 0;
    441             pDirEntry->Info.Attr.u.Unix.GenerationId    = 0;
    442             pDirEntry->Info.Attr.u.Unix.Device          = 0;
    443             break;
    444 
    445         case RTFSOBJATTRADD_NOTHING:
    446             pDirEntry->Info.Attr.enmAdditional          = RTFSOBJATTRADD_NOTHING;
    447             break;
    448 
    449         case RTFSOBJATTRADD_UNIX_OWNER:
    450             pDirEntry->Info.Attr.enmAdditional          = RTFSOBJATTRADD_UNIX_OWNER;
    451             pDirEntry->Info.Attr.u.UnixOwner.uid        = ~0U;
    452             pDirEntry->Info.Attr.u.UnixOwner.szName[0]  = '\0'; /** @todo return something sensible here. */
    453             break;
    454 
    455         case RTFSOBJATTRADD_UNIX_GROUP:
    456             pDirEntry->Info.Attr.enmAdditional          = RTFSOBJATTRADD_UNIX_GROUP;
    457             pDirEntry->Info.Attr.u.UnixGroup.gid        = ~0U;
    458             pDirEntry->Info.Attr.u.UnixGroup.szName[0]  = '\0';
    459             break;
    460 
    461         default:
    462             AssertMsgFailed(("Impossible!\n"));
    463             return VERR_INTERNAL_ERROR;
    464     }
    465 
    466     return VINF_SUCCESS;
    467 }
    468 
    469 
    470129RTDECL(int) RTDirRename(const char *pszSrc, const char *pszDst, unsigned fRename)
    471130{
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