Changeset 69889 in vbox
- Timestamp:
- Nov 30, 2017 6:28:41 PM (7 years ago)
- svn:sync-xref-src-repo-rev:
- 119354
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/fs/ntfsvfs.cpp
r69888 r69889 247 247 void *pvBitmap; 248 248 /** @} */ 249 250 /** Lower to uppercase conversion table for this filesystem. 251 * This always has 64K valid entries. */ 252 PRTUTF16 pawcUpcase; 249 253 250 254 /** Root of the MFT record tree (RTFSNTFSMFTREC). */ … … 1163 1167 1164 1168 1165 1166 1169 /** 1167 1170 * Destroys a core structure. … … 1531 1534 pTable = &pSubRec->Extents; 1532 1535 } 1536 } 1537 1538 1539 /** 1540 * Loads, validates and setups the '$UpCase' (NTFS_MFT_IDX_UP_CASE) MFT entry. 1541 * 1542 * This is needed for filename lookups, I think. 1543 * 1544 * @returns IPRT status code 1545 * @param pThis The NTFS volume instance. Will set pawcUpcase. 1546 * @param pErrInfo Where to return additional error info. 1547 */ 1548 static int rtFsNtfsVolLoadUpCase(PRTFSNTFSVOL pThis, PRTERRINFO pErrInfo) 1549 { 1550 PRTFSNTFSCORE pCore; 1551 int rc = rtFsNtfsVol_NewCoreForMftIdx(pThis, NTFS_MFT_IDX_UP_CASE, &pCore, pErrInfo); 1552 if (RT_SUCCESS(rc)) 1553 { 1554 PRTFSNTFSATTR pDataAttr = rtFsNtfsCore_FindUnnamedAttribute(pCore, NTFS_AT_DATA); 1555 if (pDataAttr) 1556 { 1557 /* 1558 * Validate the '$Upcase' MFT record. 1559 */ 1560 uint32_t const cbMin = 512; 1561 uint32_t const cbMax = _128K; 1562 if (!pDataAttr->pAttrHdr->fNonResident) 1563 rc = RTERRINFO_LOG_REL_SET(pErrInfo, VERR_VFS_BOGUS_FORMAT, "$UpCasea unnamed DATA attribute is resident!"); 1564 else if ( (uint64_t)RT_LE2H_U64(pDataAttr->pAttrHdr->u.NonRes.cbAllocated) < cbMin 1565 || (uint64_t)RT_LE2H_U64(pDataAttr->pAttrHdr->u.NonRes.cbAllocated) > cbMax) 1566 rc = RTERRINFO_LOG_REL_SET_F(pErrInfo, VERR_VFS_BOGUS_FORMAT, 1567 "$UpCase unnamed DATA attribute allocated size is out of range: %#RX64, expected at least %#RX32 and no more than %#RX32", 1568 RT_LE2H_U64(pDataAttr->pAttrHdr->u.NonRes.cbAllocated), cbMin, cbMax); 1569 else if ( (uint64_t)RT_LE2H_U64(pDataAttr->pAttrHdr->u.NonRes.cbData) < cbMin 1570 || (uint64_t)RT_LE2H_U64(pDataAttr->pAttrHdr->u.NonRes.cbData) 1571 > (uint64_t)RT_LE2H_U64(pDataAttr->pAttrHdr->u.NonRes.cbData) 1572 || ((uint64_t)RT_LE2H_U64(pDataAttr->pAttrHdr->u.NonRes.cbData) & 1) ) 1573 rc = RTERRINFO_LOG_REL_SET_F(pErrInfo, VERR_VFS_BOGUS_FORMAT, 1574 "$UpCase unnamed DATA attribute initialized size is out of range: %#RX64, expected at least %#RX32 and no more than %#RX64", 1575 RT_LE2H_U64(pDataAttr->pAttrHdr->u.NonRes.cbData), cbMin, 1576 RT_LE2H_U64(pDataAttr->pAttrHdr->u.NonRes.cbAllocated) ); 1577 else if ( (uint64_t)RT_LE2H_U64(pDataAttr->pAttrHdr->u.NonRes.cbInitialized) < cbMin 1578 || (uint64_t)RT_LE2H_U64(pDataAttr->pAttrHdr->u.NonRes.cbInitialized) 1579 > (uint64_t)RT_LE2H_U64(pDataAttr->pAttrHdr->u.NonRes.cbAllocated) 1580 || ((uint64_t)RT_LE2H_U64(pDataAttr->pAttrHdr->u.NonRes.cbInitialized) & 1) ) 1581 rc = RTERRINFO_LOG_REL_SET_F(pErrInfo, VERR_VFS_BOGUS_FORMAT, 1582 "$UpCase unnamed DATA attribute initialized size is out of range: %#RX64, expected at least %#RX32 and no more than %#RX64", 1583 RT_LE2H_U64(pDataAttr->pAttrHdr->u.NonRes.cbInitialized), cbMin, 1584 RT_LE2H_U64(pDataAttr->pAttrHdr->u.NonRes.cbAllocated) ); 1585 else if (pDataAttr->pAttrHdr->u.NonRes.uCompressionUnit != 0) 1586 rc = RTERRINFO_LOG_REL_SET_F(pErrInfo, VERR_VFS_BOGUS_FORMAT, 1587 "$UpCase unnamed DATA attribute is compressed: %#x", 1588 pDataAttr->pAttrHdr->u.NonRes.uCompressionUnit); 1589 else 1590 { 1591 PRTFSNTFSATTR pFilenameAttr = rtFsNtfsCore_FindUnnamedAttribute(pCore, NTFS_AT_FILENAME); 1592 if (!pFilenameAttr) 1593 rc = RTERRINFO_LOG_REL_SET(pErrInfo, VERR_VFS_BOGUS_FORMAT, "$UpCase has no FILENAME attribute!"); 1594 else if (pFilenameAttr->pAttrHdr->fNonResident) 1595 rc = RTERRINFO_LOG_REL_SET(pErrInfo, VERR_VFS_BOGUS_FORMAT, "$UpCase FILENAME attribute is non-resident!"); 1596 else if (pFilenameAttr->pAttrHdr->u.Res.cbValue < RT_UOFFSETOF(NTFSATFILENAME, wszFilename[7])) 1597 rc = RTERRINFO_LOG_REL_SET_F(pErrInfo, VERR_VFS_BOGUS_FORMAT, 1598 "$UpCase FILENAME attribute value size is too small: %#x", 1599 pFilenameAttr->pAttrHdr->u.Res.cbValue); 1600 else 1601 { 1602 PNTFSATFILENAME pFilename = (PNTFSATFILENAME)( (uint8_t *)pFilenameAttr->pAttrHdr 1603 + pFilenameAttr->pAttrHdr->u.Res.offValue); 1604 if ( pFilename->cwcFilename != 7 1605 || RTUtf16NICmpAscii(pFilename->wszFilename, "$UpCase", 7) != 0) 1606 rc = RTERRINFO_LOG_REL_SET_F(pErrInfo, VERR_VFS_BOGUS_FORMAT, 1607 "$UpCase FILENAME isn't '$UpCase': '%.*ls'", 1608 pFilename->cwcFilename, pFilename->wszFilename); 1609 else 1610 { 1611 /* 1612 * Allocate memory for the uppercase table and read it. 1613 */ 1614 PRTUTF16 pawcUpcase; 1615 pThis->pawcUpcase = pawcUpcase = (PRTUTF16)RTMemAlloc(_64K * sizeof(pThis->pawcUpcase[0])); 1616 if (pawcUpcase) 1617 { 1618 for (size_t i = 0; i < _64K; i++) 1619 pawcUpcase[i] = (uint16_t)i; 1620 1621 rc = rtFsNtfsAttr_Read(pDataAttr, 0, pawcUpcase, pDataAttr->pAttrHdr->u.NonRes.cbData); 1622 if (RT_SUCCESS(rc)) 1623 { 1624 /* 1625 * Check the data. 1626 */ 1627 for (size_t i = 1; i < _64K; i++) 1628 if (pawcUpcase[i] == 0) 1629 { 1630 rc = RTERRINFO_LOG_REL_SET_F(pErrInfo, VERR_VFS_BOGUS_FORMAT, 1631 "$UpCase entry %#x is zero!", i); 1632 break; 1633 } 1634 1635 /* 1636 * While we still have the $UpCase file open, check it against the allocation bitmap. 1637 */ 1638 if (RT_SUCCESS(rc)) 1639 rc = rtFsNtfsVolCheckBitmap(pThis, pDataAttr, "$UpCase", pErrInfo); 1640 1641 /* We're done, no need for special success return here though. */ 1642 } 1643 else 1644 rc = RTERRINFO_LOG_REL_SET_F(pErrInfo, rc, "Error reading $UpCase data into memory"); 1645 } 1646 else 1647 rc = VERR_NO_MEMORY; 1648 } 1649 } 1650 } 1651 } 1652 else 1653 rc = RTERRINFO_LOG_REL_SET(pErrInfo, VERR_VFS_BOGUS_FORMAT, "MFT record #0 has no unnamed DATA attribute!"); 1654 rtFsNtfsCore_Release(pCore); 1655 } 1656 else 1657 rc = RTERRINFO_LOG_REL_SET(pErrInfo, rc, "Error reading $UpCase MFT record"); 1658 return rc; 1533 1659 } 1534 1660 … … 1655 1781 return rc; 1656 1782 } 1657 1658 1783 1659 1784 … … 1950 2075 if (RT_SUCCESS(rc)) 1951 2076 rc = rtFsNtfsVolLoadBitmap(pThis, pErrInfo); 2077 if (RT_SUCCESS(rc)) 2078 rc = rtFsNtfsVolLoadUpCase(pThis, pErrInfo); 1952 2079 RTMemTmpFree(pvBuf); 1953 2080 if (RT_SUCCESS(rc))
Note:
See TracChangeset
for help on using the changeset viewer.