VirtualBox

Changeset 66710 in vbox


Ignore:
Timestamp:
Apr 27, 2017 11:01:59 PM (8 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
115109
Message:

fatvfs.cpp: Finished rtFsFatDir_NeedLongName and fixed a bug in rtFsFatDir_GenerateShortName.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/filesystem/fatvfs.cpp

    r66709 r66710  
    25672567                cwcName = 0;
    25682568        }
     2569
     2570        rtFsFatDir_ReleaseBufferAfterReading(pThis, uBufferLock);
     2571    }
     2572
     2573    return VERR_FILE_NOT_FOUND;
     2574}
     2575
     2576
     2577/**
     2578 * Watered down version of rtFsFatDir_FindEntry that is used by the short name
     2579 * generator to check for duplicates.
     2580 *
     2581 * @returns IPRT status code.
     2582 * @retval  VERR_FILE_NOT_FOUND if not found.
     2583 * @retval  VINF_SUCCESS if found.
     2584 * @param   pThis           The directory to search.
     2585 * @param   pszEntry        The entry to look for.
     2586 */
     2587static int rtFsFatDir_FindEntryShort(PRTFSFATDIR pThis, const char *pszName8Dot3)
     2588{
     2589    Assert(strlen(pszName8Dot3) == 8+3);
     2590
     2591    /*
     2592     * Scan the directory buffer by buffer.
     2593     */
     2594    uint32_t            offEntryInDir   = 0;
     2595    uint32_t const      cbDir           = pThis->Core.cbObject;
     2596    Assert(RT_ALIGN_32(cbDir, sizeof(FATDIRENTRY)) == cbDir);
     2597
     2598    while (offEntryInDir < cbDir)
     2599    {
     2600        /* Get chunk of entries starting at offEntryInDir. */
     2601        uint32_t            uBufferLock = UINT32_MAX;
     2602        uint32_t            cEntries    = 0;
     2603        PCFATDIRENTRYUNION  paEntries   = NULL;
     2604        int rc = rtFsFatDir_GetEntriesAt(pThis, offEntryInDir, &paEntries, &cEntries, &uBufferLock);
     2605        if (RT_FAILURE(rc))
     2606            return rc;
     2607
     2608        /*
     2609         * Now work thru each of the entries.
     2610         */
     2611        for (uint32_t iEntry = 0; iEntry < cEntries; iEntry++, offEntryInDir += sizeof(FATDIRENTRY))
     2612        {
     2613            switch ((uint8_t)paEntries[iEntry].Entry.achName[0])
     2614            {
     2615                default:
     2616                    break;
     2617                case FATDIRENTRY_CH0_DELETED:
     2618                    continue;
     2619                case FATDIRENTRY_CH0_END_OF_DIR:
     2620                    if (pThis->Core.pVol->enmBpbVersion >= RTFSFATBPBVER_DOS_2_0)
     2621                    {
     2622                        rtFsFatDir_ReleaseBufferAfterReading(pThis, uBufferLock);
     2623                        return VERR_FILE_NOT_FOUND;
     2624                    }
     2625                    break; /* Technically a valid entry before DOS 2.0, or so some claim. */
     2626            }
     2627
     2628            /*
     2629             * Skip long filename slots.
     2630             */
     2631            if (   paEntries[iEntry].Slot.fAttrib == FAT_ATTR_NAME_SLOT
     2632                && paEntries[iEntry].Slot.idxZero == 0
     2633                && paEntries[iEntry].Slot.fZero   == 0
     2634                && (paEntries[iEntry].Slot.idSlot & ~FATDIRNAMESLOT_FIRST_SLOT_FLAG) <= FATDIRNAMESLOT_HIGHEST_SLOT_ID
     2635                && (paEntries[iEntry].Slot.idSlot & ~FATDIRNAMESLOT_FIRST_SLOT_FLAG) != 0)
     2636            { /* skipped */ }
     2637            /*
     2638             * Regular directory entry. Do the matching, first 8.3 then long name.
     2639             */
     2640            else if (memcmp(paEntries[iEntry].Entry.achName, pszName8Dot3, sizeof(paEntries[iEntry].Entry.achName)) == 0)
     2641            {
     2642                rtFsFatDir_ReleaseBufferAfterReading(pThis, uBufferLock);
     2643                return VINF_SUCCESS;
     2644            }
     2645        }
     2646
    25692647        rtFsFatDir_ReleaseBufferAfterReading(pThis, uBufferLock);
    25702648    }
     
    26282706static bool rtFsFatDir_NeedLongName(const char *pszEntry, bool fIs8Dot3Name, PCFATDIRENTRY pDirEntry)
    26292707{
     2708    /*
     2709     * Check the easy ways out first.
     2710     */
     2711
     2712    /* If we couldn't make a straight 8-dot-3 name out of it, the we
     2713       must do the long name thing.  No question. */
    26302714    if (!fIs8Dot3Name)
    26312715        return true;
    26322716
    2633     /** @todo check case here. */
    2634     RT_NOREF(pszEntry, pDirEntry);
    2635     return false;
     2717    /* If both lower case flags are set, then the whole name must be
     2718       lowercased, so we won't need a long entry. */
     2719    if (pDirEntry->fCase == (FATDIRENTRY_CASE_F_LOWER_BASE | FATDIRENTRY_CASE_F_LOWER_EXT))
     2720        return false;
     2721
     2722    /*
     2723     * Okay, check out the whole string then, part by part.  (This is code
     2724     * similar to rtFsFatDir_CalcCaseFlags.)
     2725     */
     2726    uint8_t fCurrent = pDirEntry->fCase & FATDIRENTRY_CASE_F_LOWER_BASE;
     2727    for (;;)
     2728    {
     2729        RTUNICP uc;
     2730        int rc = RTStrGetCpEx(&pszEntry, &uc);
     2731        if (RT_SUCCESS(rc))
     2732        {
     2733            if (uc != 0)
     2734            {
     2735                if (uc != '.')
     2736                {
     2737                    if (   fCurrent
     2738                        || !RTUniCpIsLower(uc))
     2739                    { /* okay */ }
     2740                    else
     2741                        return true;
     2742                }
     2743                else
     2744                    fCurrent = pDirEntry->fCase & FATDIRENTRY_CASE_F_LOWER_EXT;
     2745            }
     2746            /* It checked out to the end, so we don't need a long name. */
     2747            else
     2748                return false;
     2749        }
     2750        else
     2751            return true;
     2752    }
    26362753}
    26372754
     
    27362853static int rtFsFatDir_GenerateShortName(PRTFSFATDIR pThis, const char *pszEntry, PFATDIRENTRY pDirEntry)
    27372854{
    2738     FATDIRENTRY DirEntryIgn;
    2739     bool        fLongIgn;
    2740     uint32_t    offEntryInDirIgn;
    2741 
    27422855    /* Do some input parsing. */
    27432856    const char  *pszExt      = RTPathSuffix(pszEntry);
     
    27582871    {
    27592872        szShortName[7] = iLastDigit + '0';
    2760         int rc = rtFsFatDir_FindEntry(pThis, szShortName, &offEntryInDirIgn, &fLongIgn, &DirEntryIgn);
     2873        int rc = rtFsFatDir_FindEntryShort(pThis, szShortName);
    27612874        if (rc == VERR_FILE_NOT_FOUND)
    27622875        {
     
    27772890            szShortName[6] = iFirstDigit + '0';
    27782891            szShortName[7] = iLastDigit  + '0';
    2779             int rc = rtFsFatDir_FindEntry(pThis, szShortName, &offEntryInDirIgn, &fLongIgn, &DirEntryIgn);
     2892            int rc = rtFsFatDir_FindEntryShort(pThis, szShortName);
    27802893            if (rc == VERR_FILE_NOT_FOUND)
    27812894            {
     
    27942907    {
    27952908        char    szHex[68];
    2796         ssize_t cchHex = RTStrFormatU32(szHex, sizeof(szHex), RTRandU32(), 16, 5, 0, RTSTR_F_CAPITAL | RTSTR_F_WIDTH);
     2909        ssize_t cchHex = RTStrFormatU32(szHex, sizeof(szHex), RTRandU32(), 16, 5, 0, RTSTR_F_CAPITAL | RTSTR_F_WIDTH | RTSTR_F_ZEROPAD);
    27972910        AssertReturn(cchHex >= 5, VERR_NET_NOT_UNIQUE_NAME);
    2798         szShortName[7] = szHex[cchHex];
    2799         szShortName[6] = szHex[cchHex - 1];
    2800         szShortName[5] = szHex[cchHex - 2];
    2801         szShortName[4] = szHex[cchHex - 3];
    2802         szShortName[3] = szHex[cchHex - 4];
    2803         int rc = rtFsFatDir_FindEntry(pThis, szShortName, &offEntryInDirIgn, &fLongIgn, &DirEntryIgn);
     2911        szShortName[7] = szHex[cchHex - 1];
     2912        szShortName[6] = szHex[cchHex - 2];
     2913        szShortName[5] = szHex[cchHex - 3];
     2914        szShortName[4] = szHex[cchHex - 4];
     2915        szShortName[3] = szHex[cchHex - 5];
     2916        int rc = rtFsFatDir_FindEntryShort(pThis, szShortName);
    28042917        if (rc == VERR_FILE_NOT_FOUND)
    28052918        {
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