| 556 | } |
| 557 | |
| 558 | bool CASC_FILE_TREE::SetNodeFileName(PCASC_FILE_NODE pFileNode, const char * szFileName) |
| 559 | { |
| 560 | ULONGLONG FileNameHash = 0; |
| 561 | PCASC_FILE_NODE pFolderNode = NULL; |
| 562 | CASC_PATH<char> PathBuffer; |
| 563 | LPCSTR szNodeBegin = szFileName; |
| 564 | size_t nFileNode = NodeTable.IndexOf(pFileNode); |
| 565 | size_t i; |
| 566 | DWORD Parent = 0; |
| 567 | |
| 568 | // Sanity checks |
| 569 | assert(szFileName != NULL && szFileName[0] != 0); |
| 570 | |
| 571 | // Traverse the entire path. For each subfolder, we insert an appropriate fake entry |
| 572 | for(i = 0; szFileName[i] != 0; i++) |
| 573 | { |
| 574 | char chOneChar = szFileName[i]; |
| 575 | |
| 576 | // Is there a path separator, such as '\\' or '/'? |
| 577 | // Also support TVFS "mount points", like "DivideAndConquer.w3m:war3map.doo" |
| 578 | if(PathSeparators[chOneChar]) |
| 579 | { |
| 580 | size_t nHashLength = i; |
| 581 | |
| 582 | // If there is a reparse point mark (':'), we need to include it as part of the name |
| 583 | if(PathSeparators[chOneChar] == 0x02) |
| 584 | { |
| 585 | PathBuffer.AppendChar(chOneChar); |
| 586 | nHashLength++; |
| 587 | } |
| 588 | |
| 589 | // Calculate hash of the file name up to the end of the node name |
| 590 | FileNameHash = CalcNormNameHash(PathBuffer, nHashLength); |
| 591 | |
| 592 | // If the entry is not there yet, create new one |
| 593 | if((pFolderNode = Find(FileNameHash)) == NULL) |
| 594 | { |
| 595 | // Insert new entry to the tree |
| 596 | pFolderNode = InsertNew(); |
| 597 | if(pFolderNode == NULL) |
| 598 | return false; |
| 599 | |
| 600 | // Fill-in flags, name hash and parent |
| 601 | pFolderNode->Flags |= (chOneChar == ':') ? (CFN_FLAG_FOLDER | CFN_FLAG_MOUNT_POINT) : CFN_FLAG_FOLDER; |
| 602 | pFolderNode->FileNameHash = FileNameHash; |
| 603 | pFolderNode->Parent = Parent; |
| 604 | FolderNodes++; |
| 605 | |
| 606 | // Set the node sub name to the node |
| 607 | SetNodePlainName(pFolderNode, szNodeBegin, szFileName + i); |
| 608 | |
| 609 | // Insert the entry to the name map |
| 610 | InsertToNameMap(pFolderNode); |
| 611 | } |
| 612 | |
| 613 | // In case we're in the middle a mount point construction (called by CASC_FILE_TREE::InsertByName()), |
| 614 | // then we can get into situation where the call to Find() found the newly constructed item. |
| 615 | // In that case, we just set the name and bail out |
no test coverage detected