CloverBootloader/FileSystems/FatPkg/EnhancedFatDxe/Hash.c
2019-09-03 12:58:42 +03:00

219 lines
4.5 KiB
C

/*++
Copyright (c) 2005 - 2015, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the Software
License Agreement which accompanies this distribution.
Module Name:
Hash.c
Abstract:
Hash table operations
Revision History
--*/
#include "Fat.h"
STATIC
UINT32
FatHashLongName (
IN CHAR16 *LongNameString
)
/*++
Routine Description:
Get hash value for long name.
Arguments:
LongNameString - The long name string to be hashed.
Returns:
HashValue.
--*/
{
UINT32 HashValue;
CHAR16 UpCasedLongFileName[EFI_PATH_STRING_LENGTH];
StrnCpyS (
UpCasedLongFileName,
sizeof (UpCasedLongFileName) / sizeof (UpCasedLongFileName[0]),
LongNameString,
sizeof (UpCasedLongFileName) / sizeof (UpCasedLongFileName[0]) - 1
);
FatStrUpr (UpCasedLongFileName);
gBS->CalculateCrc32 (UpCasedLongFileName, StrSize (UpCasedLongFileName), &HashValue);
return (HashValue & HASH_TABLE_MASK);
}
STATIC
UINT32
FatHashShortName (
IN CHAR8 *ShortNameString
)
/*++
Routine Description:
Get hash value for short name.
Arguments:
ShortNameString - The short name string to be hashed.
Returns:
HashValue
--*/
{
UINT32 HashValue;
gBS->CalculateCrc32 (ShortNameString, FAT_NAME_LEN, &HashValue);
return (HashValue & HASH_TABLE_MASK);
}
FAT_DIRENT **
FatLongNameHashSearch (
IN FAT_ODIR *ODir,
IN CHAR16 *LongNameString
)
/*++
Routine Description:
Search the long name hash table for the directory entry.
Arguments:
ODir - The directory to be searched.
LongNameString - The long name string to search.
Returns:
The previous long name hash node of the directory entry.
--*/
{
FAT_DIRENT **PreviousHashNode;
for (PreviousHashNode = &ODir->LongNameHashTable[FatHashLongName (LongNameString)];
*PreviousHashNode != NULL;
PreviousHashNode = &(*PreviousHashNode)->LongNameForwardLink
) {
if (FatStriCmp (LongNameString, (*PreviousHashNode)->FileString) == 0) {
break;
}
}
return PreviousHashNode;
}
FAT_DIRENT **
FatShortNameHashSearch (
IN FAT_ODIR *ODir,
IN CHAR8 *ShortNameString
)
/*++
Routine Description:
Search the short name hash table for the directory entry.
Arguments:
ODir - The directory to be searched.
ShortNameString - The short name string to search.
Returns:
The previous short name hash node of the directory entry.
--*/
{
FAT_DIRENT **PreviousHashNode;
for (PreviousHashNode = &ODir->ShortNameHashTable[FatHashShortName (ShortNameString)];
*PreviousHashNode != NULL;
PreviousHashNode = &(*PreviousHashNode)->ShortNameForwardLink
) {
if (CompareMem (ShortNameString, (*PreviousHashNode)->Entry.FileName, FAT_NAME_LEN) == 0) {
break;
}
}
return PreviousHashNode;
}
VOID
FatInsertToHashTable (
IN FAT_ODIR *ODir,
IN FAT_DIRENT *DirEnt
)
/*++
Routine Description:
Insert directory entry to hash table.
Arguments:
ODir - The parent directory.
DirEnt - The directory entry node.
Returns:
None.
--*/
{
FAT_DIRENT **HashTable;
UINT32 HashTableIndex;
//
// Insert hash table index for short name
//
HashTableIndex = FatHashShortName (DirEnt->Entry.FileName);
HashTable = ODir->ShortNameHashTable;
DirEnt->ShortNameForwardLink = HashTable[HashTableIndex];
HashTable[HashTableIndex] = DirEnt;
//
// Insert hash table index for long name
//
HashTableIndex = FatHashLongName (DirEnt->FileString);
HashTable = ODir->LongNameHashTable;
DirEnt->LongNameForwardLink = HashTable[HashTableIndex];
HashTable[HashTableIndex] = DirEnt;
}
VOID
FatDeleteFromHashTable (
IN FAT_ODIR *ODir,
IN FAT_DIRENT *DirEnt
)
/*++
Routine Description:
Delete directory entry from hash table.
Arguments:
ODir - The parent directory.
DirEnt - The directory entry node.
Returns:
None.
--*/
{
*FatShortNameHashSearch (ODir, DirEnt->Entry.FileName) = DirEnt->ShortNameForwardLink;
*FatLongNameHashSearch (ODir, DirEnt->FileString) = DirEnt->LongNameForwardLink;
}