VirtualBox

Changeset 69720 in vbox for trunk/src/VBox/Runtime/r3/nt


Ignore:
Timestamp:
Nov 16, 2017 4:18:19 PM (7 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
119101
Message:

IPRT: More work on directory relative APIs (NT mainly) and VFS; introducing RTRmDir (test) tool.

  • Added RTVfsDirRemoveDir
  • Native NT implementation of RTDirRelRemoveDir.
  • Improved the RTFS_TYPE_DIRECTORY case of rtVfsStdDir_UnlinkEntry.
  • Added two new status code conversions to RTErrConvertFromNtStatus.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r3/nt/dirrel-r3-nt.cpp

    r69718 r69720  
    217217
    218218
    219 /**
    220  * Creates a directory relative to @a hDir.
    221  *
    222  * @returns IPRT status code.
    223  * @param   hDir            The directory @a pszRelPath is relative to.
    224  * @param   pszRelPath      The relative path to the directory to create.
    225  * @param   fMode           The mode of the new directory.
    226  * @param   fCreate         Create flags, RTDIRCREATE_FLAGS_XXX.
    227  * @param   phSubDir        Where to return the handle of the created directory.
    228  *                          Optional.
    229  *
    230  * @sa      RTDirCreate
    231  */
    232219RTDECL(int) RTDirRelDirCreate(PRTDIR hDir, const char *pszRelPath, RTFMODE fMode, uint32_t fCreate, PRTDIR *phSubDir)
    233220{
     
    321308
    322309
    323 /**
    324  * Removes a directory relative to @a hDir if empty.
    325  *
    326  * @returns IPRT status code.
    327  * @param   hDir            The directory @a pszRelPath is relative to.
    328  * @param   pszRelPath      The relative path to the directory to remove.
    329  *
    330  * @sa      RTDirRemove
    331  */
    332310RTDECL(int) RTDirRelDirRemove(PRTDIR hDir, const char *pszRelPath)
    333311{
     
    336314    AssertReturn(pThis->u32Magic == RTDIR_MAGIC, VERR_INVALID_HANDLE);
    337315
    338 
    339     char szPath[RTPATH_MAX];
    340     int rc = rtDirRelBuildFullPath(pThis, szPath, sizeof(szPath), pszRelPath);
    341     if (RT_SUCCESS(rc))
    342     {
    343 RTAssertMsg2("DBG: RTDirRelDirRemove(%s)...\n", szPath);
    344         rc = RTDirRemove(szPath);
     316    /*
     317     * Convert and normalize the path.
     318     */
     319    UNICODE_STRING NtName;
     320    HANDLE hRoot = pThis->hDir;
     321    int rc = RTNtPathRelativeFromUtf8(&NtName, &hRoot, pszRelPath, RTDIRREL_NT_GET_ASCENT(pThis),
     322                                      pThis->enmInfoClass == FileMaximumInformation);
     323    if (RT_SUCCESS(rc))
     324    {
     325        HANDLE              hSubDir = RTNT_INVALID_HANDLE_VALUE;
     326        IO_STATUS_BLOCK     Ios     = RTNT_IO_STATUS_BLOCK_INITIALIZER;
     327        OBJECT_ATTRIBUTES   ObjAttr;
     328        InitializeObjectAttributes(&ObjAttr, &NtName, 0 /*fAttrib*/, hRoot, NULL);
     329
     330        NTSTATUS rcNt = NtCreateFile(&hSubDir,
     331                                     DELETE | SYNCHRONIZE,
     332                                     &ObjAttr,
     333                                     &Ios,
     334                                     NULL /*AllocationSize*/,
     335                                     FILE_ATTRIBUTE_NORMAL,
     336                                     FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
     337                                     FILE_OPEN,
     338                                     FILE_DIRECTORY_FILE | FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_REPARSE_POINT,
     339                                     NULL /*EaBuffer*/,
     340                                     0 /*EaLength*/);
     341        if (NT_SUCCESS(rcNt))
     342        {
     343            FILE_DISPOSITION_INFORMATION DispInfo;
     344            DispInfo.DeleteFile = TRUE;
     345            RTNT_IO_STATUS_BLOCK_REINIT(&Ios);
     346            rcNt = NtSetInformationFile(hSubDir, &Ios, &DispInfo, sizeof(DispInfo), FileDispositionInformation);
     347
     348            NTSTATUS rcNt2 = NtClose(hSubDir);
     349            if (!NT_SUCCESS(rcNt2) && NT_SUCCESS(rcNt))
     350                rcNt = rcNt2;
     351        }
     352
     353        if (NT_SUCCESS(rcNt))
     354            rc = VINF_SUCCESS;
     355        else
     356            rc = RTErrConvertFromNtStatus(rcNt);
     357
     358        RTNtPathFree(&NtName, NULL);
    345359    }
    346360    return 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