VirtualBox

Changeset 77681 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Mar 13, 2019 3:26:52 PM (6 years ago)
Author:
vboxsync
Message:

IPRT: Adding an extended file open API that returns the action taken (opened, created, replaced, truncated) for addressing tickref:9276. Windows implementation only thus far.

Location:
trunk/src/VBox/Runtime
Files:
1 added
2 edited

Legend:

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

    r77641 r77681  
    166166RTR3DECL(int) RTFileOpen(PRTFILE pFile, const char *pszFilename, uint64_t fOpen)
    167167{
     168    return RTFileOpenEx(pszFilename, fOpen, pFile, NULL);
     169}
     170
     171
     172RTDECL(int) RTFileOpenEx(const char *pszFilename, uint64_t fOpen, PRTFILE phFile, PRTFILEACTION penmActionTaken)
     173{
    168174    /*
    169175     * Validate input.
    170176     */
    171     if (!pFile)
    172     {
    173         AssertMsgFailed(("Invalid pFile\n"));
    174         return VERR_INVALID_PARAMETER;
    175     }
    176     *pFile = NIL_RTFILE;
    177     if (!pszFilename)
    178     {
    179         AssertMsgFailed(("Invalid pszFilename\n"));
    180         return VERR_INVALID_PARAMETER;
    181     }
     177    AssertReturn(phFile, VERR_INVALID_PARAMETER);
     178    *phFile = NIL_RTFILE;
     179    if (penmActionTaken)
     180        *penmActionTaken = RTFILEACTION_INVALID;
     181    AssertReturn(pszFilename, VERR_INVALID_PARAMETER);
    182182
    183183    /*
     
    208208            break;
    209209        default:
    210             AssertMsgFailed(("Impossible fOpen=%#llx\n", fOpen));
    211             return VERR_INVALID_PARAMETER;
     210            AssertMsgFailedReturn(("Impossible fOpen=%#llx\n", fOpen), VERR_INVALID_FLAGS);
    212211    }
    213212
     
    236235            RT_FALL_THRU();
    237236        default:
    238             AssertMsgFailed(("Impossible fOpen=%#llx\n", fOpen));
    239             return VERR_INVALID_PARAMETER;
     237            AssertMsgFailedReturn(("Impossible fOpen=%#llx\n", fOpen), VERR_INVALID_FLAGS);
    240238    }
    241239    if (dwCreationDisposition == TRUNCATE_EXISTING)
     
    257255                case RTFILE_O_READWRITE:     dwDesiredAccess |= FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES | SYNCHRONIZE; break;
    258256                default:
    259                     AssertMsgFailed(("Impossible fOpen=%#llx\n", fOpen));
    260                     return VERR_INVALID_PARAMETER;
     257                    AssertMsgFailedReturn(("Impossible fOpen=%#llx\n", fOpen), VERR_INVALID_FLAGS);
    261258            }
    262259    }
     
    275272        case RTFILE_O_DENY_NOT_DELETE | RTFILE_O_DENY_READWRITE:dwShareMode = FILE_SHARE_DELETE; break;
    276273        default:
    277             AssertMsgFailed(("Impossible fOpen=%#llx\n", fOpen));
    278             return VERR_INVALID_PARAMETER;
     274            AssertMsgFailedReturn(("Impossible fOpen=%#llx\n", fOpen), VERR_INVALID_FLAGS);
    279275    }
    280276
     
    315311                                   dwFlagsAndAttributes,
    316312                                   NULL);
     313        DWORD const dwErr = GetLastError();
    317314        if (hFile != INVALID_HANDLE_VALUE)
    318315        {
    319             bool fCreated = dwCreationDisposition == CREATE_ALWAYS
    320                          || dwCreationDisposition == CREATE_NEW
    321                          || (dwCreationDisposition == OPEN_ALWAYS && GetLastError() == 0);
    322 
    323316            /*
    324              * Turn off indexing of directory through Windows Indexing Service.
     317             * Calculate the action taken value.
    325318             */
    326             if (    fCreated
    327                 &&  (fOpen & RTFILE_O_NOT_CONTENT_INDEXED))
    328             {
     319            RTFILEACTION enmActionTaken;
     320            switch (dwCreationDisposition)
     321            {
     322                case CREATE_NEW:
     323                    enmActionTaken = RTFILEACTION_CREATED;
     324                    break;
     325                case CREATE_ALWAYS:
     326                    AssertMsg(dwErr == ERROR_ALREADY_EXISTS || dwErr == NO_ERROR, ("%u\n", dwErr));
     327                    enmActionTaken = dwErr == ERROR_ALREADY_EXISTS ? RTFILEACTION_REPLACED : RTFILEACTION_CREATED;
     328                    break;
     329                case OPEN_EXISTING:
     330                    enmActionTaken = RTFILEACTION_OPENED;
     331                    break;
     332                case OPEN_ALWAYS:
     333                    AssertMsg(dwErr == ERROR_ALREADY_EXISTS || dwErr == NO_ERROR, ("%u\n", dwErr));
     334                    enmActionTaken = dwErr == ERROR_ALREADY_EXISTS ? RTFILEACTION_OPENED : RTFILEACTION_CREATED;
     335                    break;
     336                case TRUNCATE_EXISTING:
     337                    enmActionTaken = RTFILEACTION_TRUNCATED;
     338                    break;
     339                default:
     340                    AssertMsgFailed(("%d %#x\n", dwCreationDisposition, dwCreationDisposition));
     341                    enmActionTaken = RTFILEACTION_INVALID;
     342                    break;
     343            }
     344
     345            /*
     346             * Turn off indexing of directory through Windows Indexing Service if
     347             * we created a new file or replaced an existing one.
     348             */
     349            if (   (fOpen & RTFILE_O_NOT_CONTENT_INDEXED)
     350                && (   enmActionTaken == RTFILEACTION_CREATED
     351                    || enmActionTaken == RTFILEACTION_REPLACED) )
     352            {
     353                /** @todo there must be a way to do this via the handle! */
    329354                if (!SetFileAttributesW(pwszFilename, FILE_ATTRIBUTE_NOT_CONTENT_INDEXED))
    330355                    rc = RTErrConvertFromWin32(GetLastError());
    331356            }
    332357            /*
    333              * Do we need to truncate the file?
     358             * If RTFILEACTION_OPENED, we may need to truncate the file.
    334359             */
    335             else if (    !fCreated
    336                      &&     (fOpen & (RTFILE_O_TRUNCATE | RTFILE_O_ACTION_MASK))
    337                          == (RTFILE_O_TRUNCATE | RTFILE_O_OPEN_CREATE))
    338             {
    339                 if (!SetEndOfFile(hFile))
     360            else if (  (fOpen & (RTFILE_O_TRUNCATE | RTFILE_O_ACTION_MASK)) == (RTFILE_O_TRUNCATE | RTFILE_O_OPEN_CREATE)
     361                     && enmActionTaken == RTFILEACTION_OPENED)
     362            {
     363                if (SetEndOfFile(hFile))
     364                    enmActionTaken = RTFILEACTION_TRUNCATED;
     365                else
    340366                    rc = RTErrConvertFromWin32(GetLastError());
    341367            }
     368            if (penmActionTaken)
     369                *penmActionTaken = enmActionTaken;
    342370            if (RT_SUCCESS(rc))
    343371            {
    344                 *pFile = (RTFILE)hFile;
    345                 Assert((HANDLE)*pFile == hFile);
     372                *phFile = (RTFILE)hFile;
     373                Assert((HANDLE)*phFile == hFile);
    346374                RTPathWinFree(pwszFilename);
    347375                return VINF_SUCCESS;
     
    351379        }
    352380        else
    353             rc = RTErrConvertFromWin32(GetLastError());
     381        {
     382            if (   penmActionTaken
     383                && dwCreationDisposition == CREATE_NEW
     384                && dwErr == ERROR_FILE_EXISTS)
     385                *penmActionTaken = RTFILEACTION_ALREADY_EXISTS;
     386            rc = RTErrConvertFromWin32(dwErr);
     387        }
    354388        RTPathWinFree(pwszFilename);
    355389    }
  • trunk/src/VBox/Runtime/testcase/Makefile.kmk

    r76553 r77681  
    160160        tstRTNtPath-1 \
    161161        ntGetTimerResolution \
    162         tstRTDarwinMachKernel
     162        tstRTDarwinMachKernel \
     163        tstRTFileOpenEx-1
    163164
    164165PROGRAMS.linux += \
     
    364365tstRTFileModeStringToFlags_SOURCES = tstRTFileModeStringToFlags.cpp
    365366
     367tstRTFileOpenEx-1_TEMPLATE = VBOXR3TSTEXE
     368tstRTFileOpenEx-1_SOURCES = tstRTFileOpenEx-1.cpp
     369
    366370tstFileAppendWin-1_TEMPLATE = VBOXR3TSTEXE
    367371tstFileAppendWin-1_SOURCES = tstFileAppendWin-1.cpp
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