儲存庫 vbox 的更動 67519
- 時間撮記:
- 2017-6-20 下午07:51:26 (7 年 以前)
- 檔案:
-
- 修改 1 筆資料
圖例:
- 未更動
- 新增
- 刪除
-
trunk/src/VBox/Runtime/common/fs/isomakerimport.cpp
r67516 r67519 67 67 /** The configuration index of the file. */ 68 68 uint32_t idxObj; 69 /** Namespaces the file has been seen in already (RTFSISOMAKER_NAMESPACE_XXX). */ 70 uint32_t fNamespaces; 71 /** Pointer to the next file with the same block number. */ 72 struct RTFSISOMKIMPBLOCK2FILE *pNext; 69 73 } RTFSISOMKIMPBLOCK2FILE; 70 74 /** Pointer to a block-2-file translation node. */ … … 277 281 static DECLCALLBACK(int) rtFsIsoMakerImportDestroyData2File(PAVLU32NODECORE pNode, void *pvUser) 278 282 { 283 PRTFSISOMKIMPBLOCK2FILE pBlock2File = (PRTFSISOMKIMPBLOCK2FILE)pNode; 284 if (pBlock2File) 285 { 286 PRTFSISOMKIMPBLOCK2FILE pNext; 287 while ((pNext = pBlock2File->pNext) != NULL) 288 { 289 pBlock2File->pNext = pNext->pNext; 290 pNext->pNext = NULL; 291 RTMemFree(pNext); 292 } 293 RTMemFree(pNode); 294 } 295 279 296 RT_NOREF(pvUser); 280 RTMemFree(pNode); 297 return VINF_SUCCESS; 298 } 299 300 301 /** 302 * Adds a directory and names it given its ISO-9660 directory record and parent. 303 * 304 * @returns IPRT status code (safe to ignore). 305 * @param pThis The importer instance. 306 * @param pDirRec The directory record. 307 * @param fNamespace The namespace flag. 308 * @param idxParent Parent directory. 309 * @param pszName The name. 310 * @param cDepth The depth to add it with. 311 * @param pTodoList The todo list (for directories). 312 */ 313 static int rtFsIsoImportProcessIso9660AddAndNameDirectory(PRTFSISOMKIMPORTER pThis, PCISO9660DIRREC pDirRec, 314 uint32_t fNamespace, uint32_t idxParent, const char *pszName, 315 uint8_t cDepth, PRTLISTANCHOR pTodoList) 316 { 317 Assert(pDirRec->fFileFlags & ISO9660_FILE_FLAGS_DIRECTORY); 318 uint32_t idxObj; 319 int rc = RTFsIsoMakerAddUnnamedDir(pThis->hIsoMaker, &idxObj); 320 if (RT_SUCCESS(rc)) 321 { 322 Log3((" --> added directory #%#x\n", idxObj)); 323 pThis->pResults->cAddedDirs++; 324 325 /* 326 * Enter the object into the namespace. 327 */ 328 rc = RTFsIsoMakerObjSetNameAndParent(pThis->hIsoMaker, idxObj, idxParent, fNamespace, pszName); 329 if (RT_SUCCESS(rc)) 330 { 331 pThis->pResults->cAddedNames++; 332 333 /* 334 * Push it onto the traversal stack. 335 */ 336 PRTFSISOMKIMPDIR pImpDir = (PRTFSISOMKIMPDIR)RTMemAlloc(sizeof(*pImpDir)); 337 if (pImpDir) 338 { 339 pImpDir->cbDir = ISO9660_GET_ENDIAN(&pDirRec->cbData); 340 pImpDir->offDirBlock = ISO9660_GET_ENDIAN(&pDirRec->offExtent); 341 pImpDir->idxObj = idxObj; 342 pImpDir->cDepth = cDepth; 343 RTListAppend(pTodoList, &pImpDir->Entry); 344 } 345 else 346 rc = rtFsIsoImpError(pThis, VERR_NO_MEMORY, "Could not allocate RTFSISOMKIMPDIR"); 347 } 348 else 349 rc = rtFsIsoImpError(pThis, rc, "Error naming directory '%s'", pszName); 350 } 351 else 352 rc = rtFsIsoImpError(pThis, rc, "Error adding directory '%s': %Rrc", pszName, pDirRec->fFileFlags, rc); 353 return rc; 354 } 355 356 357 /** 358 * Adds a file and names it given its ISO-9660 directory record and parent. 359 * 360 * @returns IPRT status code (safe to ignore). 361 * @param pThis The importer instance. 362 * @param pDirRec The directory record. 363 * @param fNamespace The namespace flag. 364 * @param idxParent Parent directory. 365 * @param pszName The name. 366 */ 367 static int rtFsIsoImportProcessIso9660AddAndNameFile(PRTFSISOMKIMPORTER pThis, PCISO9660DIRREC pDirRec, 368 uint32_t fNamespace, uint32_t idxParent, const char *pszName) 369 { 370 int rc; 371 372 /* 373 * First we must make sure the common source file has been added. 374 */ 375 if (pThis->idxSrcFile != UINT32_MAX) 376 { /* likely */ } 377 else 378 { 379 rc = RTFsIsoMakerAddCommonSourceFile(pThis->hIsoMaker, pThis->hSrcFile, &pThis->idxSrcFile); 380 if (RT_FAILURE(rc)) 381 return rtFsIsoImpError(pThis, rc, "RTFsIsoMakerAddCommonSourceFile failed: %Rrc", rc); 382 Assert(pThis->idxSrcFile != UINT32_MAX); 383 } 384 385 /* 386 * Lookup the data block if the file has a non-zero length. The aim is to 387 * find files across namespaces while bearing in mind that files in the same 388 * namespace may share data storage, i.e. what in a traditional unix file 389 * system would be called hardlinked. Problem is that the core engine doesn't 390 * do hardlinking yet and assume each file has exactly one name per namespace. 391 */ 392 uint32_t idxObj = UINT32_MAX; 393 PRTFSISOMKIMPBLOCK2FILE pBlock2File = NULL; 394 PRTFSISOMKIMPBLOCK2FILE pBlock2FilePrev = NULL; 395 if (ISO9660_GET_ENDIAN(&pDirRec->cbData) > 0) /* no data tracking for zero byte files */ 396 { 397 pBlock2File = (PRTFSISOMKIMPBLOCK2FILE)RTAvlU32Get(&pThis->Block2FileRoot, ISO9660_GET_ENDIAN(&pDirRec->offExtent)); 398 if (pBlock2File) 399 { 400 if (!(pBlock2File->fNamespaces & fNamespace)) 401 { 402 pBlock2File->fNamespaces |= fNamespace; 403 idxObj = pBlock2File->idxObj; 404 } 405 else 406 { 407 do 408 { 409 pBlock2FilePrev = pBlock2File; 410 pBlock2File = pBlock2File->pNext; 411 } while (pBlock2File && (pBlock2File->fNamespaces & fNamespace)); 412 if (pBlock2File) 413 { 414 pBlock2File->fNamespaces |= fNamespace; 415 idxObj = pBlock2File->idxObj; 416 } 417 } 418 } 419 } 420 421 /* 422 * If the above lookup didn't succeed, add a new file with a lookup record. 423 */ 424 if (idxObj == UINT32_MAX) 425 { 426 rc = RTFsIsoMakerAddUnnamedFileWithCommonSrc(pThis->hIsoMaker, pThis->idxSrcFile, 427 ISO9660_GET_ENDIAN(&pDirRec->offExtent) * (uint64_t)ISO9660_SECTOR_SIZE, 428 ISO9660_GET_ENDIAN(&pDirRec->cbData), NULL /*pObjInfo*/, &idxObj); 429 if (RT_FAILURE(rc)) 430 return rtFsIsoImpError(pThis, rc, "Error adding file '%s': %Rrc", pszName, rc); 431 Assert(idxObj != UINT32_MAX); 432 433 /* Update statistics. */ 434 pThis->pResults->cAddedFiles++; 435 if (ISO9660_GET_ENDIAN(&pDirRec->cbData) > 0) 436 { 437 pThis->pResults->cbAddedDataBlocks += RT_ALIGN_32(ISO9660_GET_ENDIAN(&pDirRec->cbData), ISO9660_SECTOR_SIZE); 438 439 /* Lookup record. */ 440 pBlock2File = (PRTFSISOMKIMPBLOCK2FILE)RTMemAlloc(sizeof(*pBlock2File)); 441 AssertReturn(pBlock2File, rtFsIsoImpError(pThis, VERR_NO_MEMORY, "Could not allocate RTFSISOMKIMPBLOCK2FILE")); 442 443 pBlock2File->idxObj = idxObj; 444 pBlock2File->Core.Key = ISO9660_GET_ENDIAN(&pDirRec->offExtent); 445 pBlock2File->fNamespaces = fNamespace; 446 pBlock2File->pNext = NULL; 447 if (!pBlock2FilePrev) 448 { 449 bool fRc = RTAvlU32Insert(&pThis->Block2FileRoot, &pBlock2File->Core); 450 Assert(fRc); RT_NOREF(fRc); 451 } 452 else 453 { 454 pBlock2FilePrev->pNext = pBlock2File; 455 pBlock2FilePrev->Core.pLeft = NULL; 456 pBlock2FilePrev->Core.pRight = NULL; 457 } 458 } 459 } 460 461 /* 462 * Enter the object into the namespace. 463 */ 464 rc = RTFsIsoMakerObjSetNameAndParent(pThis->hIsoMaker, idxObj, idxParent, fNamespace, pszName); 465 if (RT_SUCCESS(rc)) 466 pThis->pResults->cAddedNames++; 467 else 468 return rtFsIsoImpError(pThis, rc, "Error adding directory '%s': %Rrc", pszName, pDirRec->fFileFlags, rc); 281 469 return VINF_SUCCESS; 282 470 } … … 404 592 Log3(("rtFsIsoImportProcessIso9660TreeWorker: Starting at @%#RX64 LB %#RX32 (out of %#RX32) in %#x\n", 405 593 off - cbChunk, cbChunk, cbChunk + cbDir, idxDir)); 594 const uint32_t fNamespace = fUnicode ? RTFSISOMAKER_NAMESPACE_JOLIET : RTFSISOMAKER_NAMESPACE_ISO_9660; 406 595 while (cbChunk > 0) 407 596 { … … 522 711 RT_NOREF(pbSys); 523 712 } 713 524 714 /* 525 715 * Add the object. 526 716 */ 527 PRTFSISOMKIMPBLOCK2FILE pBlock2File = NULL;528 uint32_t idxObj = UINT32_MAX;529 717 if (pDirRec->fFileFlags & ISO9660_FILE_FLAGS_DIRECTORY) 530 { 531 rc = RTFsIsoMakerAddUnnamedDir(pThis->hIsoMaker, &idxObj); 532 Log3((" --> added directory #%#x\n", idxObj)); 533 if (RT_SUCCESS(rc)) 534 pThis->pResults->cAddedDirs++; 535 } 718 rtFsIsoImportProcessIso9660AddAndNameDirectory(pThis, pDirRec, fNamespace, idxDir, 719 pThis->szNameBuf, cDepth + 1, pTodoList); 536 720 else 537 { 538 /* Add the common source file if we haven't done that already. */ 539 if (pThis->idxSrcFile != UINT32_MAX) 540 { /* likely */ } 541 else 542 { 543 rc = RTFsIsoMakerAddCommonSourceFile(pThis->hIsoMaker, pThis->hSrcFile, &pThis->idxSrcFile); 544 if (RT_FAILURE(rc)) 545 return rtFsIsoImpError(pThis, rc, "RTFsIsoMakerAddCommonSourceFile failed: %Rrc", rc); 546 Assert(pThis->idxSrcFile != UINT32_MAX); 547 } 548 549 if (ISO9660_GET_ENDIAN(&pDirRec->cbData) > 0) /* no data tracking for zero byte files */ 550 pBlock2File = (PRTFSISOMKIMPBLOCK2FILE)RTAvlU32Get(&pThis->Block2FileRoot, ISO9660_GET_ENDIAN(&pDirRec->offExtent)); 551 /** @todo Check whether pBlock2File is already used in the current namespace as we don't 552 * support hardlinking at present. Seeing trouble with \dists\trusty\restricted\binary-i386\Packages.gz 553 * on ubuntu-14.04.3-desktop-amd64.iso disappearing as it's probably identical 554 * to g:\dists\trusty\main\binary-i386\Packages.gz. */ 555 if (!pBlock2File) 556 { 557 rc = RTFsIsoMakerAddUnnamedFileWithCommonSrc(pThis->hIsoMaker, pThis->idxSrcFile, 558 ISO9660_GET_ENDIAN(&pDirRec->offExtent) * (uint64_t)ISO9660_SECTOR_SIZE, 559 ISO9660_GET_ENDIAN(&pDirRec->cbData), NULL /*pObjInfo*/, &idxObj); 560 Log3((" --> added new file #%#x\n", idxObj)); 561 if (RT_SUCCESS(rc)) 562 { 563 pThis->pResults->cAddedFiles++; 564 pThis->pResults->cbAddedDataBlocks += RT_ALIGN_32(ISO9660_GET_ENDIAN(&pDirRec->cbData), ISO9660_SECTOR_SIZE); 565 } 566 } 567 else 568 { 569 idxObj = pBlock2File->idxObj; 570 Log3((" --> existing file #%#x'\n", idxObj)); 571 rc = VINF_SUCCESS; 572 } 573 } 574 575 if (RT_SUCCESS(rc)) 576 { 577 /* 578 * Enter the object into the namespace. 579 */ 580 rc = RTFsIsoMakerObjSetNameAndParent(pThis->hIsoMaker, idxObj, idxDir, 581 !fUnicode ? RTFSISOMAKER_NAMESPACE_ISO_9660 : RTFSISOMAKER_NAMESPACE_JOLIET, 582 pThis->szNameBuf); 583 if (RT_SUCCESS(rc)) 584 { 585 pThis->pResults->cAddedNames++; 586 587 /* 588 * Remember the data location if this is a file, if it's a 589 * directory push it onto the traversal stack. 590 */ 591 if (pDirRec->fFileFlags & ISO9660_FILE_FLAGS_DIRECTORY) 592 { 593 PRTFSISOMKIMPDIR pImpDir = (PRTFSISOMKIMPDIR)RTMemAlloc(sizeof(*pImpDir)); 594 AssertReturn(pImpDir, rtFsIsoImpError(pThis, VERR_NO_MEMORY, "Could not allocate RTFSISOMKIMPDIR")); 595 pImpDir->cbDir = ISO9660_GET_ENDIAN(&pDirRec->cbData); 596 pImpDir->offDirBlock = ISO9660_GET_ENDIAN(&pDirRec->offExtent); 597 pImpDir->idxObj = idxObj; 598 pImpDir->cDepth = cDepth + 1; 599 RTListAppend(pTodoList, &pImpDir->Entry); 600 } 601 else if ( !pBlock2File 602 && ISO9660_GET_ENDIAN(&pDirRec->cbData) > 0 /* no data tracking for zero byte files */) 603 { 604 pBlock2File = (PRTFSISOMKIMPBLOCK2FILE)RTMemAlloc(sizeof(*pBlock2File)); 605 AssertReturn(pBlock2File, rtFsIsoImpError(pThis, VERR_NO_MEMORY, "Could not allocate RTFSISOMKIMPBLOCK2FILE")); 606 pBlock2File->idxObj = idxObj; 607 pBlock2File->Core.Key = ISO9660_GET_ENDIAN(&pDirRec->offExtent); 608 bool fRc = RTAvlU32Insert(&pThis->Block2FileRoot, &pBlock2File->Core); 609 Assert(fRc); RT_NOREF(fRc); 610 } 611 } 612 else 613 rtFsIsoImpError(pThis, rc, "Invalid name at %#RX64: %.Rhxs", 614 off - cbChunk, pDirRec->bFileIdLength, pDirRec->achFileId); 615 } 616 else 617 rtFsIsoImpError(pThis, rc, "Error adding '%s' (fFileFlags=%#x): %Rrc", 618 pThis->szNameBuf, pDirRec->fFileFlags, rc); 721 rtFsIsoImportProcessIso9660AddAndNameFile(pThis, pDirRec, fNamespace, idxDir, pThis->szNameBuf); 619 722 } 620 723 else
注意:
瀏覽 TracChangeset
來幫助您使用更動檢視器