| 532 | } |
| 533 | |
| 534 | bool CAICHHashSet::ReadRecoveryData(uint64 nPartStartPos, CMemFile* fileDataIn) |
| 535 | { |
| 536 | if (/*eMule TODO !m_pOwner->IsPartFile() ||*/ !(m_eStatus == AICH_VERIFIED || m_eStatus == AICH_TRUSTED) ) { |
| 537 | wxFAIL; |
| 538 | return false; |
| 539 | } |
| 540 | |
| 541 | /* V2 AICH Hash Packet: |
| 542 | <count1 uint16> 16bit-hashs-to-read |
| 543 | (<identifier uint16><hash HASHSIZE>)[count1] AICH hashs |
| 544 | <count2 uint16> 32bit-hashs-to-read |
| 545 | (<identifier uint32><hash HASHSIZE>)[count2] AICH hashs |
| 546 | */ |
| 547 | |
| 548 | // at this time we check the recoverydata for the correct ammounts of hashs only |
| 549 | // all hash are then taken into the tree, depending on there hashidentifier (except the masterhash) |
| 550 | |
| 551 | uint8 nLevel = 0; |
| 552 | uint32 nPartSize = min<uint64>(PARTSIZE, m_pOwner->GetFileSize()-nPartStartPos); |
| 553 | m_pHashTree.FindHash(nPartStartPos, nPartSize,&nLevel); |
| 554 | uint16 nHashsToRead = (nLevel-1) + nPartSize/EMBLOCKSIZE + ((nPartSize % EMBLOCKSIZE != 0 )? 1:0); |
| 555 | |
| 556 | // read hashs with 16 bit identifier |
| 557 | uint16 nHashsAvailable = fileDataIn->ReadUInt16(); |
| 558 | if (fileDataIn->GetLength()-fileDataIn->GetPosition() < nHashsToRead*(HASHSIZE+2u) || (nHashsToRead != nHashsAvailable && nHashsAvailable != 0)) { |
| 559 | // this check is redundant, CSafememfile would catch such an error too |
| 560 | AddDebugLogLineN(logSHAHashSet, |
| 561 | CFormat("Failed to read RecoveryData for '%s' - Received datasize/amounts of hashs was invalid") |
| 562 | % m_pOwner->GetFileName()); |
| 563 | return false; |
| 564 | } |
| 565 | for (uint32 i = 0; i != nHashsAvailable; i++) { |
| 566 | uint16 wHashIdent = fileDataIn->ReadUInt16(); |
| 567 | if (wHashIdent == 1 /*never allow masterhash to be overwritten*/ |
| 568 | || !m_pHashTree.SetHash(fileDataIn, wHashIdent,(-1), false)) |
| 569 | { |
| 570 | AddDebugLogLineN(logSHAHashSet, |
| 571 | CFormat("Failed to read RecoveryData for '%s' - Error when trying to read hash into tree") |
| 572 | % m_pOwner->GetFileName()); |
| 573 | VerifyHashTree(true); // remove invalid hashes which we have already written |
| 574 | return false; |
| 575 | } |
| 576 | } |
| 577 | |
| 578 | |
| 579 | // read hashs with 32bit identifier |
| 580 | if (nHashsAvailable == 0 && fileDataIn->GetLength() - fileDataIn->GetPosition() >= 2) { |
| 581 | nHashsAvailable = fileDataIn->ReadUInt16(); |
| 582 | if (fileDataIn->GetLength()-fileDataIn->GetPosition() < nHashsToRead*(HASHSIZE+4u) || (nHashsToRead != nHashsAvailable && nHashsAvailable != 0)) { |
| 583 | // this check is redundant, CSafememfile would catch such an error too |
| 584 | // TODO: theApp->QueueDebugLogLine(/*DLP_VERYHIGH,*/ false, _T("Failed to read RecoveryData for %s - Received datasize/amounts of hashs was invalid (2)"), m_pOwner->GetFileName() ); |
| 585 | return false; |
| 586 | } |
| 587 | |
| 588 | // TODO: DEBUG_ONLY( theApp->QueueDebugLogLine(/*DLP_VERYHIGH,*/ false, _T("read RecoveryData for %s - Received packet with %u 32bit hash identifiers)"), m_pOwner->GetFileName(), nHashsAvailable ) ); |
| 589 | for (uint32 i = 0; i != nHashsToRead; i++) { |
| 590 | uint32 wHashIdent = fileDataIn->ReadUInt32(); |
| 591 | if (wHashIdent == 1 /*never allow masterhash to be overwritten*/ |
no test coverage detected