VirtualBox

Changeset 77681 in 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
Files:
1 added
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/file.h

    r77632 r77681  
    140140#define RTFILE_O_DENY_MASK              UINT32_C(0x000000f0)
    141141
    142 /** Action: Open an existing file (the default action). */
     142/** Action: Open an existing file. */
    143143#define RTFILE_O_OPEN                   UINT32_C(0x00000700)
    144144/** Action: Create a new file or open an existing one. */
     
    243243
    244244
     245/** Action taken by RTFileOpenEx. */
     246typedef enum RTFILEACTION
     247{
     248    /** Invalid zero value.   */
     249    RTFILEACTION_INVALID = 0,
     250    /** Existing file was opened (returned by RTFILE_O_OPEN and
     251     * RTFILE_O_OPEN_CREATE). */
     252    RTFILEACTION_OPENED,
     253    /** New file was created (returned by RTFILE_O_CREATE and
     254     * RTFILE_O_OPEN_CREATE). */
     255    RTFILEACTION_CREATED,
     256    /** Existing file was replaced (returned by RTFILE_O_CREATE_REPLACE). */
     257    RTFILEACTION_REPLACED,
     258    /** Existing file was truncated (returned if RTFILE_O_TRUNCATE take effect). */
     259    RTFILEACTION_TRUNCATED,
     260    /** The file already exists (returned by RTFILE_O_CREATE on failure). */
     261    RTFILEACTION_ALREADY_EXISTS,
     262    /** End of valid values. */
     263    RTFILEACTION_END,
     264    /** Type size hack.   */
     265    RTFILEACTION_32BIT_HACK = 0x7fffffff
     266} RTFILEACTION;
     267/** Pointer to action taken value (RTFileOpenEx).    */
     268typedef RTFILEACTION *PRTFILEACTION;
     269
     270
    245271#ifdef IN_RING3
    246272/**
     
    292318 */
    293319RTDECL(int)  RTFileOpenV(PRTFILE pFile, uint64_t fOpen, const char *pszFilenameFmt, va_list va) RT_IPRT_FORMAT_ATTR(3, 0);
     320
     321/**
     322 * Open a file, extended version.
     323 *
     324 * @returns iprt status code.
     325 * @param   pszFilename     Path to the file which is to be opened. (UTF-8)
     326 * @param   fOpen           Open flags, i.e a combination of the RTFILE_O_* defines.
     327 *                          The ACCESS, ACTION and DENY flags are mandatory!
     328 * @param   phFile          Where to store the handle to the opened file.
     329 * @param   penmActionTaken Where to return an indicator of which action was
     330 *                          taken.  This is optional and it is recommended to
     331 *                          pass NULL when not strictly needed as it adds
     332 *                          complexity (slower) on posix systems.
     333 */
     334RTDECL(int)  RTFileOpenEx(const char *pszFilename, uint64_t fOpen, PRTFILE phFile, PRTFILEACTION penmActionTaken);
    294335
    295336/**
  • trunk/include/iprt/mangling.h

    r77658 r77681  
    935935# define RTFileOpen                                     RT_MANGLER(RTFileOpen)
    936936# define RTFileOpenBitBucket                            RT_MANGLER(RTFileOpenBitBucket)
     937# define RTFileOpenEx                                   RT_MANGLER(RTFileOpenEx)
    937938# define RTFileOpenF                                    RT_MANGLER(RTFileOpenF)
    938939# define RTFileOpenV                                    RT_MANGLER(RTFileOpenV)
  • 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