Changeset 66710 in vbox
- Timestamp:
- Apr 27, 2017 11:01:59 PM (8 years ago)
- svn:sync-xref-src-repo-rev:
- 115109
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/filesystem/fatvfs.cpp
r66709 r66710 2567 2567 cwcName = 0; 2568 2568 } 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 */ 2587 static 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 2569 2647 rtFsFatDir_ReleaseBufferAfterReading(pThis, uBufferLock); 2570 2648 } … … 2628 2706 static bool rtFsFatDir_NeedLongName(const char *pszEntry, bool fIs8Dot3Name, PCFATDIRENTRY pDirEntry) 2629 2707 { 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. */ 2630 2714 if (!fIs8Dot3Name) 2631 2715 return true; 2632 2716 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 } 2636 2753 } 2637 2754 … … 2736 2853 static int rtFsFatDir_GenerateShortName(PRTFSFATDIR pThis, const char *pszEntry, PFATDIRENTRY pDirEntry) 2737 2854 { 2738 FATDIRENTRY DirEntryIgn;2739 bool fLongIgn;2740 uint32_t offEntryInDirIgn;2741 2742 2855 /* Do some input parsing. */ 2743 2856 const char *pszExt = RTPathSuffix(pszEntry); … … 2758 2871 { 2759 2872 szShortName[7] = iLastDigit + '0'; 2760 int rc = rtFsFatDir_FindEntry (pThis, szShortName, &offEntryInDirIgn, &fLongIgn, &DirEntryIgn);2873 int rc = rtFsFatDir_FindEntryShort(pThis, szShortName); 2761 2874 if (rc == VERR_FILE_NOT_FOUND) 2762 2875 { … … 2777 2890 szShortName[6] = iFirstDigit + '0'; 2778 2891 szShortName[7] = iLastDigit + '0'; 2779 int rc = rtFsFatDir_FindEntry (pThis, szShortName, &offEntryInDirIgn, &fLongIgn, &DirEntryIgn);2892 int rc = rtFsFatDir_FindEntryShort(pThis, szShortName); 2780 2893 if (rc == VERR_FILE_NOT_FOUND) 2781 2894 { … … 2794 2907 { 2795 2908 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); 2797 2910 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); 2804 2917 if (rc == VERR_FILE_NOT_FOUND) 2805 2918 {
Note:
See TracChangeset
for help on using the changeset viewer.