REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3737 Apply uncrustify changes to .c/.h files in the FatPkg package Cc: Andrew Fish <afish@apple.com> Cc: Leif Lindholm <leif@nuviainc.com> Cc: Michael D Kinney <michael.d.kinney@intel.com> Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com> Reviewed-by: Ray Ni <ray.ni@intel.com>
		
			
				
	
	
		
			512 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			512 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  Functions for manipulating file names.
 | 
						|
 | 
						|
Copyright (c) 2005 - 2015, Intel Corporation. All rights reserved.<BR>
 | 
						|
SPDX-License-Identifier: BSD-2-Clause-Patent
 | 
						|
 | 
						|
**/
 | 
						|
 | 
						|
#include "Fat.h"
 | 
						|
 | 
						|
/**
 | 
						|
 | 
						|
  This function checks whether the input FileName is a valid 8.3 short name.
 | 
						|
  If the input FileName is a valid 8.3, the output is the 8.3 short name;
 | 
						|
  otherwise, the output is the base tag of 8.3 short name.
 | 
						|
 | 
						|
  @param  FileName              - The input unicode filename.
 | 
						|
  @param  File8Dot3Name         - The output ascii 8.3 short name or base tag of 8.3 short name.
 | 
						|
 | 
						|
  @retval TRUE                  - The input unicode filename is a valid 8.3 short name.
 | 
						|
  @retval FALSE                 - The input unicode filename is not a valid 8.3 short name.
 | 
						|
 | 
						|
**/
 | 
						|
BOOLEAN
 | 
						|
FatCheckIs8Dot3Name (
 | 
						|
  IN  CHAR16  *FileName,
 | 
						|
  OUT CHAR8   *File8Dot3Name
 | 
						|
  )
 | 
						|
{
 | 
						|
  BOOLEAN  PossibleShortName;
 | 
						|
  CHAR16   *TempName;
 | 
						|
  CHAR16   *ExtendName;
 | 
						|
  CHAR16   *SeparateDot;
 | 
						|
  UINTN    MainNameLen;
 | 
						|
  UINTN    ExtendNameLen;
 | 
						|
 | 
						|
  PossibleShortName = TRUE;
 | 
						|
  SeparateDot       = NULL;
 | 
						|
  SetMem (File8Dot3Name, FAT_NAME_LEN, ' ');
 | 
						|
  for (TempName = FileName; *TempName != '\0'; TempName++) {
 | 
						|
    if (*TempName == L'.') {
 | 
						|
      SeparateDot = TempName;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (SeparateDot == NULL) {
 | 
						|
    //
 | 
						|
    // Extended filename is not detected
 | 
						|
    //
 | 
						|
    MainNameLen   = TempName - FileName;
 | 
						|
    ExtendName    = TempName;
 | 
						|
    ExtendNameLen = 0;
 | 
						|
  } else {
 | 
						|
    //
 | 
						|
    // Extended filename is detected
 | 
						|
    //
 | 
						|
    MainNameLen   = SeparateDot - FileName;
 | 
						|
    ExtendName    = SeparateDot + 1;
 | 
						|
    ExtendNameLen = TempName - ExtendName;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // We scan the filename for the second time
 | 
						|
  // to check if there exists any extra blanks and dots
 | 
						|
  //
 | 
						|
  while (--TempName >= FileName) {
 | 
						|
    if (((*TempName == L'.') || (*TempName == L' ')) && (TempName != SeparateDot)) {
 | 
						|
      //
 | 
						|
      // There exist extra blanks and dots
 | 
						|
      //
 | 
						|
      PossibleShortName = FALSE;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (MainNameLen == 0) {
 | 
						|
    PossibleShortName = FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  if (MainNameLen > FAT_MAIN_NAME_LEN) {
 | 
						|
    PossibleShortName = FALSE;
 | 
						|
    MainNameLen       = FAT_MAIN_NAME_LEN;
 | 
						|
  }
 | 
						|
 | 
						|
  if (ExtendNameLen > FAT_EXTEND_NAME_LEN) {
 | 
						|
    PossibleShortName = FALSE;
 | 
						|
    ExtendNameLen     = FAT_EXTEND_NAME_LEN;
 | 
						|
  }
 | 
						|
 | 
						|
  if (FatStrToFat (FileName, MainNameLen, File8Dot3Name)) {
 | 
						|
    PossibleShortName = FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  if (FatStrToFat (ExtendName, ExtendNameLen, File8Dot3Name + FAT_MAIN_NAME_LEN)) {
 | 
						|
    PossibleShortName = FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  return PossibleShortName;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 | 
						|
  Trim the trailing blanks of fat name.
 | 
						|
 | 
						|
  @param  Name                  - The Char8 string needs to be trimmed.
 | 
						|
  @param  Len                   - The length of the fat name.
 | 
						|
 | 
						|
  The real length of the fat name after the trailing blanks are trimmed.
 | 
						|
 | 
						|
**/
 | 
						|
STATIC
 | 
						|
UINTN
 | 
						|
FatTrimAsciiTrailingBlanks (
 | 
						|
  IN CHAR8  *Name,
 | 
						|
  IN UINTN  Len
 | 
						|
  )
 | 
						|
{
 | 
						|
  while (Len > 0 && Name[Len - 1] == ' ') {
 | 
						|
    Len--;
 | 
						|
  }
 | 
						|
 | 
						|
  return Len;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 | 
						|
  Convert the ascii fat name to the unicode string and strip trailing spaces,
 | 
						|
  and if necessary, convert the unicode string to lower case.
 | 
						|
 | 
						|
  @param  FatName               - The Char8 string needs to be converted.
 | 
						|
  @param  Len                   - The length of the fat name.
 | 
						|
  @param  LowerCase             - Indicate whether to convert the string to lower case.
 | 
						|
  @param  Str                   - The result of the conversion.
 | 
						|
 | 
						|
**/
 | 
						|
VOID
 | 
						|
FatNameToStr (
 | 
						|
  IN  CHAR8   *FatName,
 | 
						|
  IN  UINTN   Len,
 | 
						|
  IN  UINTN   LowerCase,
 | 
						|
  OUT CHAR16  *Str
 | 
						|
  )
 | 
						|
{
 | 
						|
  //
 | 
						|
  // First, trim the trailing blanks
 | 
						|
  //
 | 
						|
  Len = FatTrimAsciiTrailingBlanks (FatName, Len);
 | 
						|
  //
 | 
						|
  // Convert fat string to unicode string
 | 
						|
  //
 | 
						|
  FatFatToStr (Len, FatName, Str);
 | 
						|
 | 
						|
  //
 | 
						|
  // If the name is to be lower cased, do it now
 | 
						|
  //
 | 
						|
  if (LowerCase != 0) {
 | 
						|
    FatStrLwr (Str);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 | 
						|
  This function generates 8Dot3 name from user specified name for a newly created file.
 | 
						|
 | 
						|
  @param  Parent                - The parent directory.
 | 
						|
  @param  DirEnt                - The directory entry whose 8Dot3Name needs to be generated.
 | 
						|
 | 
						|
**/
 | 
						|
VOID
 | 
						|
FatCreate8Dot3Name (
 | 
						|
  IN FAT_OFILE   *Parent,
 | 
						|
  IN FAT_DIRENT  *DirEnt
 | 
						|
  )
 | 
						|
{
 | 
						|
  CHAR8  *ShortName;
 | 
						|
  CHAR8  *ShortNameChar;
 | 
						|
  UINTN  BaseTagLen;
 | 
						|
  UINTN  Index;
 | 
						|
  UINTN  Retry;
 | 
						|
  UINT8  Segment;
 | 
						|
 | 
						|
  union {
 | 
						|
    UINT32    Crc;
 | 
						|
    struct HEX_DATA {
 | 
						|
      UINT8    Segment : HASH_VALUE_TAG_LEN;
 | 
						|
    } Hex[HASH_VALUE_TAG_LEN];
 | 
						|
  } HashValue;
 | 
						|
  //
 | 
						|
  // Make sure the whole directory has been loaded
 | 
						|
  //
 | 
						|
  ASSERT (Parent->ODir->EndOfDir);
 | 
						|
  ShortName = DirEnt->Entry.FileName;
 | 
						|
 | 
						|
  //
 | 
						|
  // Trim trailing blanks of 8.3 name
 | 
						|
  //
 | 
						|
  BaseTagLen = FatTrimAsciiTrailingBlanks (ShortName, FAT_MAIN_NAME_LEN);
 | 
						|
  if (BaseTagLen > SPEC_BASE_TAG_LEN) {
 | 
						|
    BaseTagLen = SPEC_BASE_TAG_LEN;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // We first use the algorithm described by spec.
 | 
						|
  //
 | 
						|
  ShortNameChar    = ShortName + BaseTagLen;
 | 
						|
  *ShortNameChar++ = '~';
 | 
						|
  *ShortNameChar   = '1';
 | 
						|
  Retry            = 0;
 | 
						|
  while (*FatShortNameHashSearch (Parent->ODir, ShortName) != NULL) {
 | 
						|
    *ShortNameChar = (CHAR8)(*ShortNameChar + 1);
 | 
						|
    if (++Retry == MAX_SPEC_RETRY) {
 | 
						|
      //
 | 
						|
      // We use new algorithm to generate 8.3 name
 | 
						|
      //
 | 
						|
      ASSERT (DirEnt->FileString != NULL);
 | 
						|
      gBS->CalculateCrc32 (DirEnt->FileString, StrSize (DirEnt->FileString), &HashValue.Crc);
 | 
						|
 | 
						|
      if (BaseTagLen > HASH_BASE_TAG_LEN) {
 | 
						|
        BaseTagLen = HASH_BASE_TAG_LEN;
 | 
						|
      }
 | 
						|
 | 
						|
      ShortNameChar = ShortName + BaseTagLen;
 | 
						|
      for (Index = 0; Index < HASH_VALUE_TAG_LEN; Index++) {
 | 
						|
        Segment = HashValue.Hex[Index].Segment;
 | 
						|
        if (Segment > 9) {
 | 
						|
          *ShortNameChar++ = (CHAR8)(Segment - 10 + 'A');
 | 
						|
        } else {
 | 
						|
          *ShortNameChar++ = (CHAR8)(Segment + '0');
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      *ShortNameChar++ = '~';
 | 
						|
      *ShortNameChar   = '1';
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 | 
						|
  Check the string is lower case or upper case
 | 
						|
  and it is used by fatname to dir entry count
 | 
						|
 | 
						|
  @param Str                   - The string which needs to be checked.
 | 
						|
  @param InCaseFlag            - The input case flag which is returned when the string is lower case.
 | 
						|
 | 
						|
  @retval OutCaseFlag           - The output case flag.
 | 
						|
 | 
						|
**/
 | 
						|
STATIC
 | 
						|
UINT8
 | 
						|
FatCheckNameCase (
 | 
						|
  IN CHAR16  *Str,
 | 
						|
  IN UINT8   InCaseFlag
 | 
						|
  )
 | 
						|
{
 | 
						|
  CHAR16  Buffer[FAT_MAIN_NAME_LEN + 1 + FAT_EXTEND_NAME_LEN + 1];
 | 
						|
  UINT8   OutCaseFlag;
 | 
						|
 | 
						|
  //
 | 
						|
  // Assume the case of input string is mixed
 | 
						|
  //
 | 
						|
  OutCaseFlag = FAT_CASE_MIXED;
 | 
						|
  //
 | 
						|
  // Lower case a copy of the string, if it matches the
 | 
						|
  // original then the string is lower case
 | 
						|
  //
 | 
						|
  StrCpyS (Buffer, ARRAY_SIZE (Buffer), Str);
 | 
						|
  FatStrLwr (Buffer);
 | 
						|
  if (StrCmp (Str, Buffer) == 0) {
 | 
						|
    OutCaseFlag = InCaseFlag;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Upper case a copy of the string, if it matches the
 | 
						|
  // original then the string is upper case
 | 
						|
  //
 | 
						|
  StrCpyS (Buffer, ARRAY_SIZE (Buffer), Str);
 | 
						|
  FatStrUpr (Buffer);
 | 
						|
  if (StrCmp (Str, Buffer) == 0) {
 | 
						|
    OutCaseFlag = 0;
 | 
						|
  }
 | 
						|
 | 
						|
  return OutCaseFlag;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 | 
						|
  Set the caseflag value for the directory entry.
 | 
						|
 | 
						|
  @param DirEnt                - The logical directory entry whose caseflag value is to be set.
 | 
						|
 | 
						|
**/
 | 
						|
VOID
 | 
						|
FatSetCaseFlag (
 | 
						|
  IN FAT_DIRENT  *DirEnt
 | 
						|
  )
 | 
						|
{
 | 
						|
  CHAR16  LfnBuffer[FAT_MAIN_NAME_LEN + 1 + FAT_EXTEND_NAME_LEN + 1];
 | 
						|
  CHAR16  *TempCharPtr;
 | 
						|
  CHAR16  *ExtendName;
 | 
						|
  CHAR16  *FileNameCharPtr;
 | 
						|
  UINT8   CaseFlag;
 | 
						|
 | 
						|
  ExtendName      = NULL;
 | 
						|
  TempCharPtr     = LfnBuffer;
 | 
						|
  FileNameCharPtr = DirEnt->FileString;
 | 
						|
  ASSERT (StrSize (DirEnt->FileString) <= sizeof (LfnBuffer));
 | 
						|
  while ((*TempCharPtr = *FileNameCharPtr) != 0) {
 | 
						|
    if (*TempCharPtr == L'.') {
 | 
						|
      ExtendName = TempCharPtr;
 | 
						|
    }
 | 
						|
 | 
						|
    TempCharPtr++;
 | 
						|
    FileNameCharPtr++;
 | 
						|
  }
 | 
						|
 | 
						|
  CaseFlag = 0;
 | 
						|
  if (ExtendName != NULL) {
 | 
						|
    *ExtendName = 0;
 | 
						|
    ExtendName++;
 | 
						|
    CaseFlag = (UINT8)(CaseFlag | FatCheckNameCase (ExtendName, FAT_CASE_EXT_LOWER));
 | 
						|
  }
 | 
						|
 | 
						|
  CaseFlag = (UINT8)(CaseFlag | FatCheckNameCase (LfnBuffer, FAT_CASE_NAME_LOWER));
 | 
						|
  if ((CaseFlag & FAT_CASE_MIXED) == 0) {
 | 
						|
    //
 | 
						|
    // We just need one directory entry to store this file name entry
 | 
						|
    //
 | 
						|
    DirEnt->Entry.CaseFlag = CaseFlag;
 | 
						|
  } else {
 | 
						|
    //
 | 
						|
    // We need one extra directory entry to store the mixed case entry
 | 
						|
    //
 | 
						|
    DirEnt->Entry.CaseFlag = 0;
 | 
						|
    DirEnt->EntryCount++;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 | 
						|
  Convert the 8.3 ASCII fat name to cased Unicode string according to case flag.
 | 
						|
 | 
						|
  @param  DirEnt                - The corresponding directory entry.
 | 
						|
  @param  FileString            - The output Unicode file name.
 | 
						|
  @param  FileStringMax           The max length of FileString.
 | 
						|
 | 
						|
**/
 | 
						|
VOID
 | 
						|
FatGetFileNameViaCaseFlag (
 | 
						|
  IN     FAT_DIRENT  *DirEnt,
 | 
						|
  IN OUT CHAR16      *FileString,
 | 
						|
  IN     UINTN       FileStringMax
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINT8   CaseFlag;
 | 
						|
  CHAR8   *File8Dot3Name;
 | 
						|
  CHAR16  TempExt[1 + FAT_EXTEND_NAME_LEN + 1];
 | 
						|
 | 
						|
  //
 | 
						|
  // Store file extension like ".txt"
 | 
						|
  //
 | 
						|
  CaseFlag      = DirEnt->Entry.CaseFlag;
 | 
						|
  File8Dot3Name = DirEnt->Entry.FileName;
 | 
						|
 | 
						|
  FatNameToStr (File8Dot3Name, FAT_MAIN_NAME_LEN, CaseFlag & FAT_CASE_NAME_LOWER, FileString);
 | 
						|
  FatNameToStr (File8Dot3Name + FAT_MAIN_NAME_LEN, FAT_EXTEND_NAME_LEN, CaseFlag & FAT_CASE_EXT_LOWER, &TempExt[1]);
 | 
						|
  if (TempExt[1] != 0) {
 | 
						|
    TempExt[0] = L'.';
 | 
						|
    StrCatS (FileString, FileStringMax, TempExt);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 | 
						|
  Get the Check sum for a short name.
 | 
						|
 | 
						|
  @param  ShortNameString       - The short name for a file.
 | 
						|
 | 
						|
  @retval Sum                   - UINT8 checksum.
 | 
						|
 | 
						|
**/
 | 
						|
UINT8
 | 
						|
FatCheckSum (
 | 
						|
  IN CHAR8  *ShortNameString
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINTN  ShortNameLen;
 | 
						|
  UINT8  Sum;
 | 
						|
 | 
						|
  Sum = 0;
 | 
						|
  for (ShortNameLen = FAT_NAME_LEN; ShortNameLen != 0; ShortNameLen--) {
 | 
						|
    Sum = (UINT8)((((Sum & 1) != 0) ? 0x80 : 0) + (Sum >> 1) + *ShortNameString++);
 | 
						|
  }
 | 
						|
 | 
						|
  return Sum;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 | 
						|
  Takes Path as input, returns the next name component
 | 
						|
  in Name, and returns the position after Name (e.g., the
 | 
						|
  start of the next name component)
 | 
						|
 | 
						|
  @param  Path                  - The path of one file.
 | 
						|
  @param  Name                  - The next name component in Path.
 | 
						|
 | 
						|
  The position after Name in the Path
 | 
						|
 | 
						|
**/
 | 
						|
CHAR16 *
 | 
						|
FatGetNextNameComponent (
 | 
						|
  IN  CHAR16  *Path,
 | 
						|
  OUT CHAR16  *Name
 | 
						|
  )
 | 
						|
{
 | 
						|
  while (*Path != 0 && *Path != PATH_NAME_SEPARATOR) {
 | 
						|
    *Name++ = *Path++;
 | 
						|
  }
 | 
						|
 | 
						|
  *Name = 0;
 | 
						|
  //
 | 
						|
  // Get off of trailing path name separator
 | 
						|
  //
 | 
						|
  while (*Path == PATH_NAME_SEPARATOR) {
 | 
						|
    Path++;
 | 
						|
  }
 | 
						|
 | 
						|
  return Path;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 | 
						|
  Check whether the IFileName is valid long file name. If the IFileName is a valid
 | 
						|
  long file name, then we trim the possible leading blanks and leading/trailing dots.
 | 
						|
  the trimmed filename is stored in OutputFileName
 | 
						|
 | 
						|
  @param  InputFileName         - The input file name.
 | 
						|
  @param  OutputFileName        - The output file name.
 | 
						|
 | 
						|
  @retval TRUE                  - The InputFileName is a valid long file name.
 | 
						|
  @retval FALSE                 - The InputFileName is not a valid long file name.
 | 
						|
 | 
						|
**/
 | 
						|
BOOLEAN
 | 
						|
FatFileNameIsValid (
 | 
						|
  IN  CHAR16  *InputFileName,
 | 
						|
  OUT CHAR16  *OutputFileName
 | 
						|
  )
 | 
						|
{
 | 
						|
  CHAR16  *TempNamePointer;
 | 
						|
  CHAR16  TempChar;
 | 
						|
 | 
						|
  //
 | 
						|
  // Trim Leading blanks
 | 
						|
  //
 | 
						|
  while (*InputFileName == L' ') {
 | 
						|
    InputFileName++;
 | 
						|
  }
 | 
						|
 | 
						|
  TempNamePointer = OutputFileName;
 | 
						|
  while (*InputFileName != 0) {
 | 
						|
    *TempNamePointer++ = *InputFileName++;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Trim Trailing blanks and dots
 | 
						|
  //
 | 
						|
  while (TempNamePointer > OutputFileName) {
 | 
						|
    TempChar = *(TempNamePointer - 1);
 | 
						|
    if ((TempChar != L' ') && (TempChar != L'.')) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
    TempNamePointer--;
 | 
						|
  }
 | 
						|
 | 
						|
  *TempNamePointer = 0;
 | 
						|
 | 
						|
  //
 | 
						|
  // Per FAT Spec the file name should meet the following criteria:
 | 
						|
  //   C1. Length (FileLongName) <= 255
 | 
						|
  //   C2. Length (X:FileFullPath<NUL>) <= 260
 | 
						|
  // Here we check C1.
 | 
						|
  //
 | 
						|
  if (TempNamePointer - OutputFileName > EFI_FILE_STRING_LENGTH) {
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // See if there is any illegal characters within the name
 | 
						|
  //
 | 
						|
  do {
 | 
						|
    if ((*OutputFileName < 0x20) ||
 | 
						|
        (*OutputFileName == '\"') ||
 | 
						|
        (*OutputFileName == '*') ||
 | 
						|
        (*OutputFileName == '/') ||
 | 
						|
        (*OutputFileName == ':') ||
 | 
						|
        (*OutputFileName == '<') ||
 | 
						|
        (*OutputFileName == '>') ||
 | 
						|
        (*OutputFileName == '?') ||
 | 
						|
        (*OutputFileName == '\\') ||
 | 
						|
        (*OutputFileName == '|')
 | 
						|
        )
 | 
						|
    {
 | 
						|
      return FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
    OutputFileName++;
 | 
						|
  } while (*OutputFileName != 0);
 | 
						|
 | 
						|
  return TRUE;
 | 
						|
}
 |