Changeset 69910 in vbox for trunk/src/VBox/Runtime/common/fs
- Timestamp:
- Dec 3, 2017 5:06:56 PM (7 years ago)
- svn:sync-xref-src-repo-rev:
- 119388
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/fs/ntfsvfs.cpp
r69903 r69910 265 265 /** The MFT record size. */ 266 266 uint32_t cbMftRecord; 267 /** The index recordsize. */268 uint32_t cb IndexRecord;267 /** The default index (B-tree) node size. */ 268 uint32_t cbDefaultIndexNode; 269 269 270 270 /** The volume serial number. */ … … 306 306 *********************************************************************************************************************************/ 307 307 static uint32_t rtFsNtfsCore_Release(PRTFSNTFSCORE pThis); 308 #ifdef LOG_ENABLED 309 static void rtFsNtfsVol_LogIndexRoot(PCNTFSATINDEXROOT pIdxRoot, uint32_t cbIdxRoot); 310 #endif 308 311 309 312 … … 580 583 //case NTFS_AT_VOLUME_INFORMATION: 581 584 //case NTFS_AT_DATA: 582 //case NTFS_AT_INDEX_ROOT: 585 586 case NTFS_AT_INDEX_ROOT: 587 rtFsNtfsVol_LogIndexRoot((PCNTFSATINDEXROOT)pbValue, cbValue); 588 break; 589 583 590 //case NTFS_AT_INDEX_ALLOCATION: 584 591 //case NTFS_AT_BITMAP: … … 637 644 uint32_t const cbMaxPairs = cbAttrib - offMappingPairs; 638 645 int64_t iVnc = pHdr->u.NonRes.iVcnFirst; 639 Log2(("NTFS: Mapping Pairs: %.*Rhxsd\n", cbMaxPairs, pbPairs)); 646 if (cbMaxPairs < 48) 647 Log2(("NTFS: Mapping Pairs: cbMaxPairs=%#x %.*Rhxs\n", cbMaxPairs, cbMaxPairs, pbPairs)); 648 else 649 Log2(("NTFS: Mapping Pairs: cbMaxPairs=%#x\n%.*Rhxd\n", cbMaxPairs, cbMaxPairs, pbPairs)); 640 650 if (!iVnc && !*pbPairs) 641 651 Log2(("NTFS: [0]: Empty\n")); … … 643 653 { 644 654 if (iVnc != 0) 645 Log2(("NTFS: [0 ]: VCN=%#012RX64 L %#012RX64 - not mapped\n", 0, iVnc));655 Log2(("NTFS: [00/0x000]: VCN=%#012RX64 L %#012RX64 - not mapped\n", 0, iVnc)); 646 656 int64_t iLnc = 0; 647 657 uint32_t iPair = 0; … … 656 666 if (offPairs + cbRun > cbMaxPairs) 657 667 { 658 Log2(("NTFS: [% d]: run overrun! cbRun=%#x bLengths=%#x offPairs=%#x cbMaxPairs=%#x\n",659 iPair, cbRun, bLengths, offPairs, cbMaxPairs));668 Log2(("NTFS: [%02d/%#05x]: run overrun! cbRun=%#x bLengths=%#x offPairs=%#x cbMaxPairs=%#x\n", 669 iPair, offPairs, cbRun, bLengths, offPairs, cbMaxPairs)); 660 670 break; 661 671 } 672 //Log2(("NTFS: @%#05x: %.*Rhxs\n", offPairs, cbRun + 1, &pbPairs[offPairs])); 662 673 663 674 /* Value 1: Number of (virtual) clusters in this run. */ … … 683 694 cLcnDelta = (cLcnDelta << 8) + *pbNum--; 684 695 iLnc += cLcnDelta; 685 Log2(("NTFS: [% d]: VNC=%#012RX64 L %#012RX64 => LNC=%#012RX64\n",686 iPair, iVnc, cClustersInRun, iLnc));696 Log2(("NTFS: [%02d/%#05x]: VNC=%#012RX64 L %#012RX64 => LNC=%#012RX64\n", 697 iPair, offPairs, iVnc, cClustersInRun, iLnc)); 687 698 } 688 699 else 689 Log2(("NTFS: [% d]: VNC=%#012RX64 L %#012RX64 => HOLE\n",690 iPair, iVnc, cClustersInRun));700 Log2(("NTFS: [%02d/%#05x]: VNC=%#012RX64 L %#012RX64 => HOLE\n", 701 iPair, offPairs, iVnc, cClustersInRun)); 691 702 692 703 /* Advance. */ … … 1240 1251 { 1241 1252 rc = RTVfsFileReadAt(pVol->hVfsBacking, pTable->paExtents[iExtent].off + off, pvBuf, cbThisRead, NULL); 1253 Log4(("NTFS: Volume read: @%#RX64 LB %#zx -> %Rrc\n", pTable->paExtents[iExtent].off + off, cbThisRead, rc)); 1242 1254 if (RT_FAILURE(rc)) 1243 1255 break; … … 1284 1296 1285 1297 /** 1298 * 1299 * @returns 1300 * @param pRecHdr . 1301 * @param cbRec . 1302 * @param fRelaxedUsa . 1303 * @param pErrInfo . 1304 * 1305 * @see https://msdn.microsoft.com/en-us/library/bb470212%28v=vs.85%29.aspx 1306 */ 1307 static int rtFsNtfsRec_DoMultiSectorFixups(PNTFSRECHDR pRecHdr, uint32_t cbRec, bool fRelaxedUsa, PRTERRINFO pErrInfo) 1308 { 1309 /* 1310 * Do sanity checking. 1311 */ 1312 uint16_t offUpdateSeqArray = RT_LE2H_U16(pRecHdr->offUpdateSeqArray); 1313 uint16_t cUpdateSeqEntries = RT_LE2H_U16(pRecHdr->cUpdateSeqEntries); 1314 if ( !(cbRec & (NTFS_MULTI_SECTOR_STRIDE - 1)) 1315 && !(offUpdateSeqArray & 1) /* two byte aligned */ 1316 && cUpdateSeqEntries == 1 + cbRec / NTFS_MULTI_SECTOR_STRIDE 1317 && offUpdateSeqArray + (uint32_t)cUpdateSeqEntries * 2U < NTFS_MULTI_SECTOR_STRIDE - 2U) 1318 { 1319 uint16_t const *pauUsa = (uint16_t const *)((uint8_t *)pRecHdr + offUpdateSeqArray); 1320 1321 /* 1322 * The first update seqence array entry is the value stored at 1323 * the fixup locations at the end of the blocks. We read this 1324 * and check each of the blocks. 1325 */ 1326 uint16_t const uCheck = *pauUsa++; 1327 cUpdateSeqEntries--; 1328 for (uint16_t iBlock = 0; iBlock < cUpdateSeqEntries; iBlock++) 1329 { 1330 uint16_t const *puBlockCheck = (uint16_t const *)((uint8_t *)pRecHdr + (iBlock + 1) * NTFS_MULTI_SECTOR_STRIDE - 2U); 1331 if (*puBlockCheck == uCheck) 1332 { /* likely */ } 1333 else if (!fRelaxedUsa) 1334 return RTERRINFO_LOG_REL_SET_F(pErrInfo, VERR_VFS_BOGUS_OFFSET, 1335 "Multisector transfer error: block #%u ends with %#x instead of %#x (fixup: %#x)", 1336 iBlock, RT_LE2H_U16(*puBlockCheck), RT_LE2H_U16(uCheck), RT_LE2H_U16(pauUsa[iBlock]) ); 1337 else 1338 { 1339 Log(("NTFS: Multisector transfer warning: block #%u ends with %#x instead of %#x (fixup: %#x)\n", 1340 iBlock, RT_LE2H_U16(*puBlockCheck), RT_LE2H_U16(uCheck), RT_LE2H_U16(pauUsa[iBlock]) )); 1341 return VINF_SUCCESS; 1342 } 1343 } 1344 1345 /* 1346 * Apply the fixups. 1347 * Note! We advanced pauUsa above, so it's now at the fixup values. 1348 */ 1349 for (uint16_t iBlock = 0; iBlock < cUpdateSeqEntries; iBlock++) 1350 { 1351 uint16_t *puFixup = (uint16_t *)((uint8_t *)pRecHdr + (iBlock + 1) * NTFS_MULTI_SECTOR_STRIDE - 2U); 1352 *puFixup = pauUsa[iBlock]; 1353 } 1354 return VINF_SUCCESS; 1355 } 1356 if (fRelaxedUsa) 1357 { 1358 Log(("NTFS: Ignoring bogus multisector update sequence: cbRec=%#x uMagic=%#RX32 offUpdateSeqArray=%#x cUpdateSeqEntries=%#x\n", 1359 cbRec, RT_LE2H_U32(pRecHdr->uMagic), offUpdateSeqArray, cUpdateSeqEntries )); 1360 return VINF_SUCCESS; 1361 } 1362 return RTERRINFO_LOG_REL_SET_F(pErrInfo, VERR_VFS_BOGUS_OFFSET, 1363 "Bogus multisector update sequence: cbRec=%#x uMagic=%#RX32 offUpdateSeqArray=%#x cUpdateSeqEntries=%#x", 1364 cbRec, RT_LE2H_U32(pRecHdr->uMagic), offUpdateSeqArray, cUpdateSeqEntries); 1365 } 1366 1367 1368 /** 1286 1369 * Allocate and parse an MFT record, returning a core object structure. 1287 1370 * … … 1289 1372 * @param pThis The NTFS volume instance. 1290 1373 * @param idxMft The index of the MTF record. 1374 * @param fRelaxedUsa Relaxed update sequence checking. Won't fail if 1375 * checks doesn't work or not present. 1291 1376 * @param ppCore Where to return the core object structure. 1292 1377 * @param pErrInfo Where to return error details. Optional. 1293 1378 */ 1294 static int rtFsNtfsVol_NewCoreForMftIdx(PRTFSNTFSVOL pThis, uint64_t idxMft, PRTFSNTFSCORE *ppCore, PRTERRINFO pErrInfo) 1379 static int rtFsNtfsVol_NewCoreForMftIdx(PRTFSNTFSVOL pThis, uint64_t idxMft, bool fRelaxedUsa, 1380 PRTFSNTFSCORE *ppCore, PRTERRINFO pErrInfo) 1295 1381 { 1296 1382 *ppCore = NULL; … … 1303 1389 uint64_t offRec = idxMft * pThis->cbMftRecord; 1304 1390 int rc = rtFsNtfsAttr_Read(pThis->pMftData, offRec, pRec->pbRec, pThis->cbMftRecord); 1391 if (RT_SUCCESS(rc)) 1392 rc = rtFsNtfsRec_DoMultiSectorFixups(&pRec->pFileRec->Hdr, pThis->cbMftRecord, fRelaxedUsa, pErrInfo); 1305 1393 if (RT_SUCCESS(rc)) 1306 1394 { … … 1469 1557 */ 1470 1558 1559 #ifdef LOG_ENABLED 1560 1561 /** 1562 * Logs an index header and all the entries. 1563 * 1564 * @param pIdxHdr The index header. 1565 * @param cbIndex The number of valid bytes starting with the header. 1566 * @param offIndex The offset of the index header into the parent 1567 * structure. 1568 * @param pszPrefix The log prefix. 1569 * @param uIdxType The index type. 1570 */ 1571 static void rtFsNtfsVol_LogIndexHdrAndEntries(PCNTFSINDEXHDR pIdxHdr, uint32_t cbIndex, uint32_t offIndex, 1572 const char *pszPrefix, uint32_t uIdxType) 1573 { 1574 if (!LogIs2Enabled()) 1575 return; 1576 1577 /* 1578 * Do the header. 1579 */ 1580 if (cbIndex <= sizeof(*pIdxHdr)) 1581 { 1582 Log2(("NTFS: %s: Error! Not enough space for the index header! cbIndex=%#x, index head needs %#x\n", 1583 pszPrefix, cbIndex, sizeof(*pIdxHdr))); 1584 return; 1585 } 1586 1587 Log2(("NTFS: %s: offFirstEntry %#x%s\n", pszPrefix, RT_LE2H_U32(pIdxHdr->offFirstEntry), 1588 RT_LE2H_U32(pIdxHdr->offFirstEntry) >= cbIndex ? " !out-of-bounds!" : "")); 1589 Log2(("NTFS: %s: cbUsed %#x%s\n", pszPrefix, RT_LE2H_U32(pIdxHdr->cbUsed), 1590 RT_LE2H_U32(pIdxHdr->cbUsed) > cbIndex ? " !out-of-bounds!" : "")); 1591 Log2(("NTFS: %s: cbAllocated %#x%s\n", pszPrefix, RT_LE2H_U32(pIdxHdr->cbAllocated), 1592 RT_LE2H_U32(pIdxHdr->cbAllocated) > cbIndex ? " !out-of-bounds!" : "")); 1593 Log2(("NTFS: %s: fFlags %#x (%s%s)\n", pszPrefix, pIdxHdr->fFlags, 1594 pIdxHdr->fFlags & NTFSINDEXHDR_F_INTERNAL ? "internal" : "leaf", 1595 pIdxHdr->fFlags & ~NTFSINDEXHDR_F_INTERNAL ? " !!unknown-flags!!" : "")); 1596 if (pIdxHdr->abReserved[0]) Log2(("NTFS: %s: abReserved[0] %#x\n", pszPrefix, pIdxHdr->abReserved[0])); 1597 if (pIdxHdr->abReserved[1]) Log2(("NTFS: %s: abReserved[0] %#x\n", pszPrefix, pIdxHdr->abReserved[1])); 1598 if (pIdxHdr->abReserved[2]) Log2(("NTFS: %s: abReserved[0] %#x\n", pszPrefix, pIdxHdr->abReserved[2])); 1599 1600 /* 1601 * The entries. 1602 */ 1603 bool fSeenEnd = false; 1604 uint32_t iEntry = 0; 1605 uint32_t offCurEntry = RT_LE2H_U32(pIdxHdr->offFirstEntry); 1606 while (offCurEntry < cbIndex) 1607 { 1608 if (offCurEntry + sizeof(NTFSIDXENTRYHDR) > cbIndex) 1609 { 1610 Log2(("NTFS: Entry[%#04x]: Out of bounds: %#x LB %#x, max %#x\n", 1611 iEntry, offCurEntry, sizeof(NTFSIDXENTRYHDR), cbIndex)); 1612 break; 1613 } 1614 PCNTFSIDXENTRYHDR pEntryHdr = (PCNTFSIDXENTRYHDR)((uint8_t const *)pIdxHdr + offCurEntry); 1615 Log2(("NTFS: [%#04x]: @%#05x/@%#05x cbEntry=%#x cbKey=%#x fFlags=%#x (%s%s%s)\n", 1616 iEntry, offCurEntry, offCurEntry + offIndex, RT_LE2H_U16(pEntryHdr->cbEntry), RT_LE2H_U16(pEntryHdr->cbKey), 1617 RT_LE2H_U16(pEntryHdr->fFlags), 1618 pEntryHdr->fFlags & NTFSIDXENTRYHDR_F_INTERNAL ? "internal" : "leaf", 1619 pEntryHdr->fFlags & NTFSIDXENTRYHDR_F_END ? " end" : "", 1620 pEntryHdr->fFlags & ~(NTFSIDXENTRYHDR_F_INTERNAL | NTFSIDXENTRYHDR_F_END) ? " !unknown!" : "")); 1621 if (uIdxType == NTFSATINDEXROOT_TYPE_DIR) 1622 Log2(("NTFS: FileMftRec %#RX64 sqn %#x\n", 1623 NTFSMFTREF_GET_IDX(&pEntryHdr->u.FileMftRec), NTFSMFTREF_GET_SEQ(&pEntryHdr->u.FileMftRec) )); 1624 else 1625 Log2(("NTFS: offData=%#x cbData=%#x uReserved=%#x\n", 1626 RT_LE2H_U16(pEntryHdr->u.View.offData), RT_LE2H_U16(pEntryHdr->u.View.cbData), 1627 RT_LE2H_U32(pEntryHdr->u.View.uReserved) )); 1628 if (pEntryHdr->fFlags & NTFSIDXENTRYHDR_F_INTERNAL) 1629 Log2(("NTFS: Subnode=%#RX64\n", RT_LE2H_U64(NTFSIDXENTRYHDR_GET_SUBNODE(pEntryHdr)) )); 1630 1631 if ( RT_LE2H_U16(pEntryHdr->cbKey) >= sizeof(NTFSATFILENAME) 1632 && uIdxType == NTFSATINDEXROOT_TYPE_DIR) 1633 { 1634 PCNTFSATFILENAME pFilename = (PCNTFSATFILENAME)(pEntryHdr + 1); 1635 Log2(("NTFS: Filename=%.*ls\n", pFilename->cwcFilename, pFilename->wszFilename)); 1636 } 1637 1638 1639 /* next */ 1640 iEntry++; 1641 offCurEntry += RT_LE2H_U16(pEntryHdr->cbEntry); 1642 fSeenEnd = RT_BOOL(pEntryHdr->fFlags & NTFSIDXENTRYHDR_F_END); 1643 if (fSeenEnd || RT_LE2H_U16(pEntryHdr->cbEntry) < sizeof(*pEntryHdr)) 1644 break; 1645 } 1646 if (!fSeenEnd) 1647 Log2(("NTFS: %s: Warning! Missing NTFSIDXENTRYHDR_F_END node!\n", pszPrefix)); 1648 } 1649 1650 static void rtFsNtfsVol_LogIndexNode(PCNTFSATINDEXALLOC pIdxNode, uint32_t cbIdxNode, uint32_t uType) 1651 { 1652 if (!LogIs2Enabled()) 1653 return; 1654 if (cbIdxNode < sizeof(*pIdxNode)) 1655 Log2(("NTFS: Index Node: Error! Too small! cbIdxNode=%#x, index node needs %#x\n", cbIdxNode, sizeof(*pIdxNode))); 1656 else 1657 { 1658 Log2(("NTFS: Index Node: uMagic %#x\n", RT_LE2H_U32(pIdxNode->RecHdr.uMagic))); 1659 Log2(("NTFS: Index Node: UpdateSeqArray %#x L %#x\n", 1660 RT_LE2H_U16(pIdxNode->RecHdr.offUpdateSeqArray), RT_LE2H_U16(pIdxNode->RecHdr.cUpdateSeqEntries) )); 1661 Log2(("NTFS: Index Node: uLsn %#RX64\n", RT_LE2H_U64(pIdxNode->uLsn) )); 1662 Log2(("NTFS: Index Node: iSelfAddress %#RX64\n", RT_LE2H_U64(pIdxNode->iSelfAddress) )); 1663 if (pIdxNode->RecHdr.uMagic == NTFSREC_MAGIC_INDEX_ALLOC) 1664 rtFsNtfsVol_LogIndexHdrAndEntries(&pIdxNode->Hdr, cbIdxNode - RT_UOFFSETOF(NTFSATINDEXALLOC, Hdr), 1665 RT_UOFFSETOF(NTFSATINDEXALLOC, Hdr), "Index Node Hdr", uType); 1666 else 1667 Log2(("NTFS: Index Node: !Error! Invalid magic!\n")); 1668 } 1669 } 1670 1671 1672 /** 1673 * Logs a index root structure and what follows (index header + entries). 1674 * 1675 * @param pIdxRoot The index root. 1676 * @param cbIdxRoot Number of valid bytes starting with @a pIdxRoot. 1677 */ 1678 static void rtFsNtfsVol_LogIndexRoot(PCNTFSATINDEXROOT pIdxRoot, uint32_t cbIdxRoot) 1679 { 1680 if (!LogIs2Enabled()) 1681 return; 1682 if (cbIdxRoot < sizeof(*pIdxRoot)) 1683 Log2(("NTFS: Index Root: Error! Too small! cbIndex=%#x, index head needs %#x\n", cbIdxRoot, sizeof(*pIdxRoot))); 1684 else 1685 { 1686 Log2(("NTFS: Index Root: cbIdxRoot %#x\n", cbIdxRoot)); 1687 Log2(("NTFS: Index Root: uType %#x %s\n", RT_LE2H_U32(pIdxRoot->uType), 1688 pIdxRoot->uType == NTFSATINDEXROOT_TYPE_VIEW ? "view" 1689 : pIdxRoot->uType == NTFSATINDEXROOT_TYPE_DIR ? "directory" : "!unknown!")); 1690 Log2(("NTFS: Index Root: uCollationRules %#x %s\n", RT_LE2H_U32(pIdxRoot->uCollationRules), 1691 pIdxRoot->uCollationRules == NTFS_COLLATION_BINARY ? "binary" 1692 : pIdxRoot->uCollationRules == NTFS_COLLATION_FILENAME ? "filename" 1693 : pIdxRoot->uCollationRules == NTFS_COLLATION_UNICODE_STRING ? "unicode-string" 1694 : pIdxRoot->uCollationRules == NTFS_COLLATION_UINT32 ? "uint32" 1695 : pIdxRoot->uCollationRules == NTFS_COLLATION_SID ? "sid" 1696 : pIdxRoot->uCollationRules == NTFS_COLLATION_UINT32_PAIR ? "uint32-pair" 1697 : pIdxRoot->uCollationRules == NTFS_COLLATION_UINT32_SEQ ? "uint32-sequence" : "!unknown!")); 1698 Log2(("NTFS: Index Root: cbIndexNode %#x\n", RT_LE2H_U32(pIdxRoot->cbIndexNode) )); 1699 Log2(("NTFS: Index Root: cAddressesPerIndexNode %#x => cbNodeAddressingUnit=%#x\n", 1700 pIdxRoot->cAddressesPerIndexNode, RT_LE2H_U32(pIdxRoot->cbIndexNode) / RT_MAX(1, pIdxRoot->cAddressesPerIndexNode) )); 1701 if (pIdxRoot->abReserved[0]) Log2(("NTFS: Index Root: abReserved[0] %#x\n", pIdxRoot->abReserved[0])); 1702 if (pIdxRoot->abReserved[1]) Log2(("NTFS: Index Root: abReserved[1] %#x\n", pIdxRoot->abReserved[1])); 1703 if (pIdxRoot->abReserved[2]) Log2(("NTFS: Index Root: abReserved[2] %#x\n", pIdxRoot->abReserved[2])); 1704 1705 rtFsNtfsVol_LogIndexHdrAndEntries(&pIdxRoot->Hdr, cbIdxRoot - RT_UOFFSETOF(NTFSATINDEXROOT, Hdr), 1706 RT_UOFFSETOF(NTFSATINDEXROOT, Hdr), "Index Root Hdr", pIdxRoot->uType); 1707 } 1708 } 1709 1710 #endif /* LOG_ENABLED */ 1711 1471 1712 1472 1713 static int rtFsNtfsVol_NewSharedDirFromCore(PRTFSNTFSVOL pThis, PRTFSNTFSCORE pCore, PRTFSNTFSDIRSHRD *ppSharedDir, … … 1478 1719 * Look for the index root and do some quick checks of it first. 1479 1720 */ 1480 PRTFSNTFSATTR pRootAttr = rtFsNtfsCore_FindNamedAttributeAscii(pCore, NTFS_AT_ FILENAME,1481 NTFS_DIR_ATTRIBUTE_NAME, NTFS_AT_INDEX_ROOT);1721 PRTFSNTFSATTR pRootAttr = rtFsNtfsCore_FindNamedAttributeAscii(pCore, NTFS_AT_INDEX_ROOT, 1722 RT_STR_TUPLE(NTFS_DIR_ATTRIBUTE_NAME)); 1482 1723 if (!pRootAttr) 1483 1724 return RTERRINFO_LOG_REL_SET_F(pErrInfo, VERR_VFS_BOGUS_FORMAT, "%s: Found no INDEX_ROOT attribute named $I30", pszWhat); 1484 1725 if (pRootAttr->pAttrHdr->fNonResident) 1485 1726 return RTERRINFO_LOG_REL_SET_F(pErrInfo, VERR_VFS_BOGUS_FORMAT, "%s: INDEX_ROOT is is not resident", pszWhat); 1486 1727 if (pRootAttr->cbResident < sizeof(NTFSATINDEXROOT)) 1728 return RTERRINFO_LOG_REL_SET_F(pErrInfo, VERR_VFS_BOGUS_FORMAT, "%s: INDEX_ROOT is too small: %#x, min %#x ", 1729 pRootAttr->cbResident, sizeof(pRootAttr->cbResident)); 1730 1731 PCNTFSATINDEXROOT pIdxRoot = (PCNTFSATINDEXROOT)NTFSATTRIBHDR_GET_RES_VALUE_PTR(pRootAttr->pAttrHdr); 1732 #ifdef LOG_ENABLED 1733 rtFsNtfsVol_LogIndexRoot(pIdxRoot, pRootAttr->cbResident); 1734 #endif 1735 NOREF(pIdxRoot); 1736 // if (pIdxRoot->uType) 1737 // { 1738 // } 1487 1739 1488 1740 #if 1 /* later */ … … 1492 1744 * 1493 1745 */ 1494 PRTFSNTFSATTR p AllocAttr = rtFsNtfsCore_FindNamedAttributeAscii(pCore, NTFS_AT_FILENAME,1495 NTFS_DIR_ATTRIBUTE_NAME, NTFS_AT_INDEX_ALLOCATION);1496 PRTFSNTFSATTR p BitmapAttr = rtFsNtfsCore_FindNamedAttributeAscii(pCore, NTFS_AT_FILENAME,1497 NTFS_DIR_ATTRIBUTE_NAME, NTFS_AT_BITMAP);1746 PRTFSNTFSATTR pIndexAlloc = rtFsNtfsCore_FindNamedAttributeAscii(pCore, NTFS_AT_INDEX_ALLOCATION, 1747 RT_STR_TUPLE(NTFS_DIR_ATTRIBUTE_NAME)); 1748 PRTFSNTFSATTR pIndexBitmap = rtFsNtfsCore_FindNamedAttributeAscii(pCore, NTFS_AT_BITMAP, 1749 RT_STR_TUPLE(NTFS_DIR_ATTRIBUTE_NAME)); 1498 1750 #endif 1499 1751 return VINF_SUCCESS; … … 1781 2033 */ 1782 2034 PRTFSNTFSCORE pCore; 1783 int rc = rtFsNtfsVol_NewCoreForMftIdx(pThis, NTFS_MFT_IDX_ROOT, &pCore, pErrInfo);2035 int rc = rtFsNtfsVol_NewCoreForMftIdx(pThis, NTFS_MFT_IDX_ROOT, false /*fRelaxedUsa*/, &pCore, pErrInfo); // DON'T COMMIT 1784 2036 if (RT_SUCCESS(rc)) 1785 2037 { … … 1805 2057 else 1806 2058 { 1807 PRTFSNTFSATTR pIndexRoot = rtFsNtfsCore_FindNamedAttributeAscii(pCore, NTFS_AT_ FILENAME,1808 NTFS_DIR_ATTRIBUTE_NAME, NTFS_AT_INDEX_ROOT);1809 PRTFSNTFSATTR pIndexAlloc = rtFsNtfsCore_FindNamedAttributeAscii(pCore, NTFS_AT_ FILENAME,1810 NTFS_DIR_ATTRIBUTE_NAME, NTFS_AT_INDEX_ALLOCATION);1811 PRTFSNTFSATTR pIndexBitmap = rtFsNtfsCore_FindNamedAttributeAscii(pCore, NTFS_AT_ FILENAME,1812 NTFS_DIR_ATTRIBUTE_NAME, NTFS_AT_BITMAP);2059 PRTFSNTFSATTR pIndexRoot = rtFsNtfsCore_FindNamedAttributeAscii(pCore, NTFS_AT_INDEX_ROOT, 2060 RT_STR_TUPLE(NTFS_DIR_ATTRIBUTE_NAME)); 2061 PRTFSNTFSATTR pIndexAlloc = rtFsNtfsCore_FindNamedAttributeAscii(pCore, NTFS_AT_INDEX_ALLOCATION, 2062 RT_STR_TUPLE(NTFS_DIR_ATTRIBUTE_NAME)); 2063 PRTFSNTFSATTR pIndexBitmap = rtFsNtfsCore_FindNamedAttributeAscii(pCore, NTFS_AT_BITMAP, 2064 RT_STR_TUPLE(NTFS_DIR_ATTRIBUTE_NAME)); 1813 2065 if (!pIndexRoot) 1814 2066 rc = RTERRINFO_LOG_REL_SET(pErrInfo, VERR_VFS_BOGUS_FORMAT, "RootDir: Found no INDEX_ROOT attribute named $I30"); … … 1857 2109 { 1858 2110 PRTFSNTFSCORE pCore; 1859 int rc = rtFsNtfsVol_NewCoreForMftIdx(pThis, NTFS_MFT_IDX_UP_CASE, &pCore, pErrInfo);2111 int rc = rtFsNtfsVol_NewCoreForMftIdx(pThis, NTFS_MFT_IDX_UP_CASE, false /*fRelaxedUsa*/, &pCore, pErrInfo); 1860 2112 if (RT_SUCCESS(rc)) 1861 2113 { … … 1979 2231 { 1980 2232 PRTFSNTFSCORE pCore; 1981 int rc = rtFsNtfsVol_NewCoreForMftIdx(pThis, NTFS_MFT_IDX_BITMAP, &pCore, pErrInfo);2233 int rc = rtFsNtfsVol_NewCoreForMftIdx(pThis, NTFS_MFT_IDX_BITMAP, false /*fRelaxedUsa*/, &pCore, pErrInfo); 1982 2234 if (RT_SUCCESS(rc)) 1983 2235 { … … 2102 2354 { 2103 2355 PRTFSNTFSCORE pCore; 2104 int rc = rtFsNtfsVol_NewCoreForMftIdx(pThis, NTFS_MFT_IDX_VOLUME, &pCore, pErrInfo);2356 int rc = rtFsNtfsVol_NewCoreForMftIdx(pThis, NTFS_MFT_IDX_VOLUME, false /*fRelaxedUsa*/, &pCore, pErrInfo); 2105 2357 if (RT_SUCCESS(rc)) 2106 2358 { … … 2184 2436 AssertReturn(pRec, VERR_NO_MEMORY); 2185 2437 2438 #if 0 && defined(LOG_ENABLED) 2439 for (uint32_t i = 0; i < 128; i++) 2440 { 2441 uint64_t const offDisk = (pThis->uLcnMft << pThis->cClusterShift) + i * pThis->cbMftRecord; 2442 int rc = RTVfsFileReadAt(pThis->hVfsBacking, offDisk, pRec->pbRec, pThis->cbMftRecord, NULL); 2443 if (RT_SUCCESS(rc)) 2444 { 2445 pRec->TreeNode.Key = i; 2446 rtfsNtfsMftRec_Log(pRec, pThis->cbMftRecord); 2447 pRec->TreeNode.Key = 0; 2448 } 2449 } 2450 #endif 2451 2186 2452 uint64_t const offDisk = pThis->uLcnMft << pThis->cClusterShift; 2187 2453 int rc = RTVfsFileReadAt(pThis->hVfsBacking, offDisk, pRec->pbRec, pThis->cbMftRecord, NULL); 2188 2454 if (RT_SUCCESS(rc)) 2189 2455 { 2456 rc = rtFsNtfsRec_DoMultiSectorFixups(&pRec->pFileRec->Hdr, pThis->cbMftRecord, true, pErrInfo); 2457 if (RT_SUCCESS(rc)) 2458 { 2190 2459 #ifdef LOG_ENABLED 2191 rtfsNtfsMftRec_Log(pRec, pThis->cbMftRecord);2460 rtfsNtfsMftRec_Log(pRec, pThis->cbMftRecord); 2192 2461 #endif 2193 rc = rtFsNtfsVol_ParseMft(pThis, pRec, pErrInfo); 2462 rc = rtFsNtfsVol_ParseMft(pThis, pRec, pErrInfo); 2463 } 2194 2464 if (RT_SUCCESS(rc)) 2195 2465 { … … 2398 2668 "Unsupported NTFS MFT record size: %#x", pThis->cbMftRecord); 2399 2669 2400 /* NTFS BPB: Index blocksize */2401 if (pBootSector->Bpb.Ntfs.cCluster PerIndexBlock>= 0)2402 { 2403 if ( !RT_IS_POWER_OF_TWO((uint32_t)pBootSector->Bpb.Ntfs.cCluster PerIndexBlock)2404 || pBootSector->Bpb.Ntfs.cCluster PerIndexBlock== 0)2670 /* NTFS BPB: Default index node size */ 2671 if (pBootSector->Bpb.Ntfs.cClustersPerIndexNode >= 0) 2672 { 2673 if ( !RT_IS_POWER_OF_TWO((uint32_t)pBootSector->Bpb.Ntfs.cClustersPerIndexNode) 2674 || pBootSector->Bpb.Ntfs.cClustersPerIndexNode == 0) 2405 2675 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT, 2406 "NTFS clusters-per-index-blockis zero or not a power of two: %#x",2407 pBootSector->Bpb.Ntfs.cCluster PerIndexBlock);2408 pThis->cb IndexRecord = (uint32_t)pBootSector->Bpb.Ntfs.cClusterPerIndexBlock<< pThis->cClusterShift;2409 Assert(pThis->cb IndexRecord == pBootSector->Bpb.Ntfs.cClusterPerIndexBlock* pThis->cbCluster);2410 } 2411 else if ( pBootSector->Bpb.Ntfs.cCluster PerIndexBlock< -322412 || pBootSector->Bpb.Ntfs.cCluster PerIndexBlock> -9)2676 "NTFS default clusters-per-index-tree-node is zero or not a power of two: %#x", 2677 pBootSector->Bpb.Ntfs.cClustersPerIndexNode); 2678 pThis->cbDefaultIndexNode = (uint32_t)pBootSector->Bpb.Ntfs.cClustersPerIndexNode << pThis->cClusterShift; 2679 Assert(pThis->cbDefaultIndexNode == pBootSector->Bpb.Ntfs.cClustersPerIndexNode * pThis->cbCluster); 2680 } 2681 else if ( pBootSector->Bpb.Ntfs.cClustersPerIndexNode < -32 2682 || pBootSector->Bpb.Ntfs.cClustersPerIndexNode > -9) 2413 2683 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT, 2414 "NTFS clusters-per-index-blockis out of shift range: %d",2415 pBootSector->Bpb.Ntfs.cCluster PerIndexBlock);2684 "NTFS default clusters-per-index-tree-node is out of shift range: %d", 2685 pBootSector->Bpb.Ntfs.cClustersPerIndexNode); 2416 2686 else 2417 pThis->cb IndexRecord= UINT32_C(1) << -pBootSector->Bpb.Ntfs.cClustersPerMftRecord;2418 Log2(("NTFS BPB: cb IndexRecord=%#x\n", pThis->cbIndexRecord));2687 pThis->cbDefaultIndexNode = UINT32_C(1) << -pBootSector->Bpb.Ntfs.cClustersPerMftRecord; 2688 Log2(("NTFS BPB: cbDefaultIndexNode=%#x\n", pThis->cbDefaultIndexNode)); 2419 2689 2420 2690 pThis->uSerialNo = RT_LE2H_U64(pBootSector->Bpb.Ntfs.uSerialNumber);
Note:
See TracChangeset
for help on using the changeset viewer.