/** @file
  Provides interface to shell MAN file parser.

  Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
  Copyright 2015 Dell Inc.
  This program and the accompanying materials
  are licensed and made available under the terms and conditions of the BSD License
  which accompanies this distribution.  The full text of the license may be found at
  http://opensource.org/licenses/bsd-license.php

  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include "Shell.h"

#define SHELL_MAN_HII_GUID \
{ \
  0xf62ccd0c, 0x2449, 0x453c, { 0x8a, 0xcb, 0x8c, 0xc5, 0x7c, 0xf0, 0x2a, 0x97 } \
}

EFI_HII_HANDLE  mShellManHiiHandle    = NULL;
EFI_HANDLE      mShellManDriverHandle = NULL;


SHELL_MAN_HII_VENDOR_DEVICE_PATH  mShellManHiiDevicePath = {
  {
    {
      HARDWARE_DEVICE_PATH,
      HW_VENDOR_DP,
      {
        (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
        (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
      }
    },
    SHELL_MAN_HII_GUID
  },
  {
    END_DEVICE_PATH_TYPE,
    END_ENTIRE_DEVICE_PATH_SUBTYPE,
    {
      (UINT8) (END_DEVICE_PATH_LENGTH),
      (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
    }
  }
};


/**
  Convert a Unicode character to upper case only if
  it maps to a valid small-case ASCII character.

  This internal function only deal with Unicode character
  which maps to a valid small-case ASCII character, i.e.
  L'a' to L'z'. For other Unicode character, the input character
  is returned directly.

  @param  Char  The character to convert.

  @retval LowerCharacter   If the Char is with range L'a' to L'z'.
  @retval Unchanged        Otherwise.

**/
CHAR16
InternalShellCharToUpper (
  IN CHAR16  Char
  );

/**
  Verifies that the filename has .EFI on the end.

  allocates a new buffer and copies the name (appending .EFI if necessary).
  Caller to free the buffer.

  @param[in] NameString            original name string

  @return                          the new filename with .efi as the extension.
**/
CHAR16 *
GetExecuatableFileName (
  IN CONST CHAR16    *NameString
  )
{
  CHAR16  *Buffer;
  CHAR16  *SuffixStr;
  if (NameString == NULL) {
    return (NULL);
  }

  //
  // Fix the file name
  //
  if (StrnCmp(NameString+StrLen(NameString)-StrLen(L".efi"), L".efi", StrLen(L".efi"))==0) {
    Buffer = AllocateCopyPool(StrSize(NameString), NameString);
  } else if (StrnCmp(NameString+StrLen(NameString)-StrLen(L".man"), L".man", StrLen(L".man"))==0) {
    Buffer = AllocateCopyPool(StrSize(NameString), NameString);
    if (Buffer != NULL) {
      SuffixStr = Buffer+StrLen(Buffer)-StrLen(L".man");
      StrnCpyS (SuffixStr, StrSize(L".man")/sizeof(CHAR16), L".efi", StrLen(L".efi"));
    }
  } else {
    Buffer = AllocateZeroPool(StrSize(NameString) + StrLen(L".efi")*sizeof(CHAR16));
    if (Buffer != NULL) {
      StrnCpyS( Buffer,
                (StrSize(NameString) + StrLen(L".efi")*sizeof(CHAR16))/sizeof(CHAR16),
                NameString,
                StrLen(NameString)
                );
      StrnCatS( Buffer,
                (StrSize(NameString) + StrLen(L".efi")*sizeof(CHAR16))/sizeof(CHAR16),
                L".efi",
                StrLen(L".efi")
                );
    }
  }
  return (Buffer);

}

/**
  Verifies that the filename has .MAN on the end.

  allocates a new buffer and copies the name (appending .MAN if necessary)

  ASSERT if ManFileName is NULL

  @param[in] ManFileName            original filename

  @return the new filename with .man as the extension.
**/
CHAR16 *
GetManFileName(
  IN CONST CHAR16 *ManFileName
  )
{
  CHAR16 *Buffer;
  if (ManFileName == NULL) {
    return (NULL);
  }
  //
  // Fix the file name
  //
  if (StrnCmp(ManFileName+StrLen(ManFileName)-4, L".man", 4)==0) {
    Buffer = AllocateCopyPool(StrSize(ManFileName), ManFileName);
  } else {
    Buffer = AllocateZeroPool(StrSize(ManFileName) + 4*sizeof(CHAR16));
    if (Buffer != NULL) {
      StrnCpyS( Buffer, 
                (StrSize(ManFileName) + 4*sizeof(CHAR16))/sizeof(CHAR16), 
                ManFileName, 
                StrLen(ManFileName)
                );
      StrnCatS( Buffer, 
                (StrSize(ManFileName) + 4*sizeof(CHAR16))/sizeof(CHAR16),
                L".man", 
                4
                );
    }
  }
  return (Buffer);
}

/**
  Search the path environment variable for possible locations and test for
  which one contains a man file with the name specified.  If a valid file is found
  stop searching and return the (opened) SHELL_FILE_HANDLE for that file.

  @param[in] FileName           Name of the file to find and open.
  @param[out] Handle            Pointer to the handle of the found file.  The
                                value of this is undefined for return values
                                except EFI_SUCCESS.

  @retval EFI_SUCCESS           The file was found.  Handle is a valid SHELL_FILE_HANDLE
  @retval EFI_INVALID_PARAMETER A parameter had an invalid value.
  @retval EFI_NOT_FOUND         The file was not found.
**/
EFI_STATUS
SearchPathForFile(
  IN CONST CHAR16             *FileName,
  OUT SHELL_FILE_HANDLE       *Handle
  )
{
  CHAR16          *FullFileName;
  EFI_STATUS      Status;

  if ( FileName     == NULL
    || Handle       == NULL
    || StrLen(FileName) == 0
   ){
    return (EFI_INVALID_PARAMETER);
  }

  FullFileName = ShellFindFilePath(FileName);
  if (FullFileName == NULL) {
    return (EFI_NOT_FOUND);
  }

  //
  // now open that file
  //
  Status = EfiShellOpenFileByName(FullFileName, Handle, EFI_FILE_MODE_READ);
  FreePool(FullFileName);

  return (Status);
}

/**
  parses through Buffer (which is MAN file formatted) and returns the
  detailed help for any sub section specified in the comma seperated list of
  sections provided.  If the end of the file or a .TH section is found then
  return.

  Upon a sucessful return the caller is responsible to free the memory in *HelpText

  @param[in] Buffer             Buffer to read from
  @param[in] Sections           name of command's sub sections to find
  @param[in] HelpText           pointer to pointer to string where text goes.
  @param[in] HelpSize           pointer to size of allocated HelpText (may be updated)

  @retval EFI_OUT_OF_RESOURCES  a memory allocation failed.
  @retval EFI_SUCCESS           the section was found and its description sotred in
                                an alloceted buffer.
**/
EFI_STATUS
ManBufferFindSections(
  IN CONST CHAR16 *Buffer,
  IN CONST CHAR16 *Sections,
  IN CHAR16       **HelpText,
  IN UINTN        *HelpSize
  )
{
  EFI_STATUS          Status;
  CONST CHAR16        *CurrentLocation;
  BOOLEAN             CurrentlyReading;
  CHAR16              *SectionName;
  UINTN               SectionLen;
  BOOLEAN             Found;
  CHAR16              *TempString;
  CHAR16              *TempString2;

  if ( Buffer     == NULL
    || HelpText   == NULL
    || HelpSize   == NULL
   ){
    return (EFI_INVALID_PARAMETER);
  }

  Status            = EFI_SUCCESS;
  CurrentlyReading  = FALSE;
  Found             = FALSE;

  for (CurrentLocation = Buffer,TempString = NULL
    ;  CurrentLocation != NULL && *CurrentLocation != CHAR_NULL
    ;  CurrentLocation=StrStr(CurrentLocation, L"\r\n"),TempString = NULL
   ){
    while(CurrentLocation[0] == L'\r' || CurrentLocation[0] == L'\n') {
      CurrentLocation++;
    }
    if (CurrentLocation[0] == L'#') {
      //
      // Skip comment lines
      //
      continue;
    }
    if (StrnCmp(CurrentLocation, L".TH", 3) == 0) {
      //
      // we hit the end of this commands section so stop.
      //
      break;
    }
    if (StrnCmp(CurrentLocation, L".SH ", 4) == 0) {
      if (Sections == NULL) {
        CurrentlyReading = TRUE;
        continue;
      } else if (CurrentlyReading) {
        CurrentlyReading = FALSE;
      }
      CurrentLocation += 4;
      //
      // is this a section we want to read in?
      //
      if (StrLen(CurrentLocation)!=0) {
        TempString2 = StrStr(CurrentLocation, L" ");
        TempString2 = MIN(TempString2, StrStr(CurrentLocation, L"\r"));
        TempString2 = MIN(TempString2, StrStr(CurrentLocation, L"\n"));
        ASSERT(TempString == NULL);
        TempString = StrnCatGrow(&TempString, NULL, CurrentLocation, TempString2==NULL?0:TempString2 - CurrentLocation);
        if (TempString == NULL) {
          Status = EFI_OUT_OF_RESOURCES;
          break;
        }
        SectionName = TempString;
        SectionLen = StrLen(SectionName);
        SectionName = StrStr(Sections, SectionName);
        if (SectionName == NULL) {
          SHELL_FREE_NON_NULL(TempString);
          continue;
        }
        if (*(SectionName + SectionLen) == CHAR_NULL || *(SectionName + SectionLen) == L',') {
          CurrentlyReading = TRUE;
        }
      }
    } else if (CurrentlyReading) {
      Found = TRUE;
      if (StrLen(CurrentLocation)!=0) {
        TempString2 = StrStr(CurrentLocation, L"\r");
        TempString2 = MIN(TempString2, StrStr(CurrentLocation, L"\n"));
        ASSERT(TempString == NULL);
        TempString = StrnCatGrow(&TempString, NULL, CurrentLocation, TempString2==NULL?0:TempString2 - CurrentLocation);
        if (TempString == NULL) {
          Status = EFI_OUT_OF_RESOURCES;
          break;
        }
        //
        // copy and save the current line.
        //
        ASSERT((*HelpText == NULL && *HelpSize == 0) || (*HelpText != NULL));
        StrnCatGrow (HelpText, HelpSize, TempString, 0);
        if (HelpText == NULL) {
          Status = EFI_OUT_OF_RESOURCES;
          break;
        }
        StrnCatGrow (HelpText, HelpSize, L"\r\n", 0);
        if (HelpText == NULL) {
          Status = EFI_OUT_OF_RESOURCES;
          break;
        }
      }
    }
    SHELL_FREE_NON_NULL(TempString);
  }
  SHELL_FREE_NON_NULL(TempString);
  if (!Found && !EFI_ERROR(Status)) {
    return (EFI_NOT_FOUND);
  }
  return (Status);
}

/**
  parses through the MAN file specified by SHELL_FILE_HANDLE and returns the
  detailed help for any sub section specified in the comma seperated list of
  sections provided.  If the end of the file or a .TH section is found then
  return.

  Upon a sucessful return the caller is responsible to free the memory in *HelpText

  @param[in] Handle             FileHandle to read from
  @param[in] Sections           name of command's sub sections to find
  @param[out] HelpText          pointer to pointer to string where text goes.
  @param[out] HelpSize          pointer to size of allocated HelpText (may be updated)
  @param[in] Ascii              TRUE if the file is ASCII, FALSE otherwise.

  @retval EFI_OUT_OF_RESOURCES  a memory allocation failed.
  @retval EFI_SUCCESS           the section was found and its description sotred in
                                an alloceted buffer.
**/
EFI_STATUS
ManFileFindSections(
  IN SHELL_FILE_HANDLE  Handle,
  IN CONST CHAR16       *Sections,
  OUT CHAR16            **HelpText,
  OUT UINTN             *HelpSize,
  IN BOOLEAN            Ascii
  )
{
  EFI_STATUS          Status;
  CHAR16              *ReadLine;
  UINTN               Size;
  BOOLEAN             CurrentlyReading;
  CHAR16              *SectionName;
  UINTN               SectionLen;
  BOOLEAN             Found;

  if ( Handle     == NULL
    || HelpText   == NULL
    || HelpSize   == NULL
   ){
    return (EFI_INVALID_PARAMETER);
  }

  Status            = EFI_SUCCESS;
  CurrentlyReading  = FALSE;
  Size              = 1024;
  Found             = FALSE;

  ReadLine          = AllocateZeroPool(Size);
  if (ReadLine == NULL) {
    return (EFI_OUT_OF_RESOURCES);
  }

  for (;!ShellFileHandleEof(Handle);Size = 1024) {
    Status = ShellFileHandleReadLine(Handle, ReadLine, &Size, TRUE, &Ascii);
    if (ReadLine[0] == L'#') {
      //
      // Skip comment lines
      //
      continue;
    }
    //
    // ignore too small of buffer...
    //
    if (Status == EFI_BUFFER_TOO_SMALL) {
      Status = EFI_SUCCESS;
    }
    if (EFI_ERROR(Status)) {
      break;
    } else if (StrnCmp(ReadLine, L".TH", 3) == 0) {
      //
      // we hit the end of this commands section so stop.
      //
      break;
    } else if (StrnCmp(ReadLine, L".SH", 3) == 0) {
      if (Sections == NULL) {
        CurrentlyReading = TRUE;
        continue;
      }
      //
      // we found a section
      //
      if (CurrentlyReading) {
        CurrentlyReading = FALSE;
      }
      //
      // is this a section we want to read in?
      //
      for ( SectionName = ReadLine + 3
          ; *SectionName == L' '
          ; SectionName++);
      SectionLen = StrLen(SectionName);
      SectionName = StrStr(Sections, SectionName);
      if (SectionName == NULL) {
        continue;
      }
      if (*(SectionName + SectionLen) == CHAR_NULL || *(SectionName + SectionLen) == L',') {
        CurrentlyReading = TRUE;
      }
    } else if (CurrentlyReading) {
      Found = TRUE;
      //
      // copy and save the current line.
      //
      ASSERT((*HelpText == NULL && *HelpSize == 0) || (*HelpText != NULL));
      StrnCatGrow (HelpText, HelpSize, ReadLine, 0);
      StrnCatGrow (HelpText, HelpSize, L"\r\n", 0);
    }
  }
  FreePool(ReadLine);
  if (!Found && !EFI_ERROR(Status)) {
    return (EFI_NOT_FOUND);
  }
  return (Status);
}

/**
  parses through the MAN file formatted Buffer and returns the
  "Brief Description" for the .TH section as specified by Command.  If the
  command section is not found return EFI_NOT_FOUND.

  Upon a sucessful return the caller is responsible to free the memory in *BriefDesc

  @param[in] Buffer             Buffer to read from
  @param[in] Command            name of command's section to find
  @param[in] BriefDesc          pointer to pointer to string where description goes.
  @param[in] BriefSize          pointer to size of allocated BriefDesc

  @retval EFI_OUT_OF_RESOURCES  a memory allocation failed.
  @retval EFI_SUCCESS           the section was found and its description sotred in
                                an alloceted buffer.
**/
EFI_STATUS
ManBufferFindTitleSection(
  IN CHAR16         **Buffer,
  IN CONST CHAR16   *Command,
  IN CHAR16         **BriefDesc,
  IN UINTN          *BriefSize
  )
{
  EFI_STATUS    Status;
  CHAR16        *TitleString;
  CHAR16        *TitleEnd;
  CHAR16        *CurrentLocation;
  UINTN         TitleLength;
  UINTN         Start;
  CONST CHAR16  StartString[] = L".TH ";
  CONST CHAR16  EndString[]   = L" 0 ";

  if ( Buffer     == NULL
    || Command    == NULL
    || (BriefDesc != NULL && BriefSize == NULL)
   ){
    return (EFI_INVALID_PARAMETER);
  }

  Status    = EFI_SUCCESS;

  //
  // Do not pass any leading path information that may be present to IsTitleHeader().
  //
  Start = StrLen(Command);
  while ((Start != 0)
         && (*(Command + Start - 1) != L'\\')
         && (*(Command + Start - 1) != L'/')
         && (*(Command + Start - 1) != L':')) {
    --Start;
  }

  //
  // more characters for StartString and EndString
  //
  TitleLength = StrSize(Command + Start) + (StrLen(StartString) + StrLen(EndString)) * sizeof(CHAR16);
  TitleString = AllocateZeroPool(TitleLength);
  if (TitleString == NULL) {
    return (EFI_OUT_OF_RESOURCES);
  }
  StrCpyS(TitleString, TitleLength/sizeof(CHAR16), StartString);
  StrCatS(TitleString, TitleLength/sizeof(CHAR16), Command + Start);
  StrCatS(TitleString, TitleLength/sizeof(CHAR16), EndString);

  CurrentLocation = StrStr(*Buffer, TitleString);
  if (CurrentLocation == NULL){
    Status = EFI_NOT_FOUND;
  } else {
    //
    // we found it so copy out the rest of the line into BriefDesc
    // After skipping any spaces or zeroes
    //
    for (CurrentLocation += StrLen(TitleString)
      ;  *CurrentLocation == L' ' || *CurrentLocation == L'0' || *CurrentLocation == L'1' || *CurrentLocation == L'\"'
      ;  CurrentLocation++);

    TitleEnd = StrStr(CurrentLocation, L"\"");
    if (TitleEnd == NULL) {
      Status = EFI_DEVICE_ERROR;
    } else {
      if (BriefDesc != NULL) {
        *BriefSize = StrSize(TitleEnd);
        *BriefDesc = AllocateZeroPool(*BriefSize);
        if (*BriefDesc == NULL) {
          Status = EFI_OUT_OF_RESOURCES;
        } else {
          StrnCpyS(*BriefDesc, (*BriefSize)/sizeof(CHAR16), CurrentLocation, TitleEnd-CurrentLocation);
        }
      }

      for (CurrentLocation = TitleEnd
        ;  *CurrentLocation != L'\n'
        ;  CurrentLocation++);
      for (
        ;  *CurrentLocation == L' ' || *CurrentLocation == L'\n' || *CurrentLocation == L'\r'
        ;  CurrentLocation++);
      *Buffer = CurrentLocation;
    }
  }

  FreePool(TitleString);
  return (Status);
}

/**
  Parses a line from a MAN file to see if it is the Title Header. If it is, then
  if the "Brief Description" is desired, allocate a buffer for it and return a
  copy. Upon a sucessful return the caller is responsible to free the memory in
  *BriefDesc

  Uses a simple state machine that allows "unlimited" whitespace before and after the
  ".TH", compares Command and the MAN file commnd name without respect to case, and
  allows "unlimited" whitespace and '0' and '1' characters before the Short Description.
  The PCRE regex describing this functionality is: ^\s*\.TH\s+(\S)\s[\s01]*(.*)$
  where group 1 is the Command Name and group 2 is the Short Description.

  @param[in] Command             name of command whose MAN file we think Line came from
  @param[in] Line                Pointer to a line from the MAN file
  @param[out] BriefDesc          pointer to pointer to string where description goes.
  @param[out] BriefSize          pointer to size of allocated BriefDesc
  @param[out] Found              TRUE if the Title Header was found and it belongs to Command

  @retval TRUE   Line contained the Title Header
  @retval FALSE  Line did not contain the Title Header
**/
BOOLEAN
IsTitleHeader(
  IN CONST CHAR16       *Command,
  IN CHAR16             *Line,
  OUT CHAR16            **BriefDesc OPTIONAL,
  OUT UINTN             *BriefSize OPTIONAL,
  OUT BOOLEAN           *Found
  )
{
  // The states of a simple state machine used to recognize a title header line
  // and to extract the Short Description, if desired.
  typedef enum {
    LookForThMacro, LookForCommandName, CompareCommands, GetBriefDescription, Final
  } STATEVALUES;

  STATEVALUES  State;
  UINTN        CommandIndex; // Indexes Command as we compare its chars to the MAN file.
  BOOLEAN      ReturnValue;  // TRUE if this the Title Header line of *some* MAN file.
  BOOLEAN      ReturnFound;  // TRUE if this the Title Header line of *the desired* MAN file.

  ReturnValue = FALSE;
  ReturnFound = FALSE;
  CommandIndex = 0;
  State = LookForThMacro;

  do {

    if (*Line == L'\0') {
      break;
    }

    switch (State) {

      // Handle "^\s*.TH\s"
      // Go to state LookForCommandName if the title header macro is present; otherwise,
      // eat white space. If we see something other than white space, this is not a
      // title header line.
      case LookForThMacro:
        if (StrnCmp (L".TH ", Line, 4) == 0 || StrnCmp (L".TH\t", Line, 4) == 0) {
          Line += 4;
          State = LookForCommandName;
        }
        else if (*Line == L' ' || *Line == L'\t') {
          Line++;
        }
        else {
          State = Final;
        }
      break;

      // Handle "\s*"
      // Eat any "extra" whitespace after the title header macro (we have already seen
      // at least one white space character). Go to state CompareCommands when a
      // non-white space is seen.
      case LookForCommandName:
        if (*Line == L' ' || *Line == L'\t') {
          Line++;
        }
        else {
          ReturnValue = TRUE;  // This is *some* command's title header line.
          State = CompareCommands;
          // Do not increment Line; it points to the first character of the command
          // name on the title header line.
        }
      break;

      // Handle "(\S)\s"
      // Compare Command to the title header command name, ignoring case. When we
      // reach the end of the command (i.e. we see white space), the next state
      // depends on whether the caller wants a copy of the Brief Description.
      case CompareCommands:
        if (*Line == L' ' || *Line == L'\t') {
          ReturnFound = TRUE;  // This is the desired command's title header line.
          State = (BriefDesc == NULL) ? Final : GetBriefDescription;
        }
        else if (InternalShellCharToUpper (*Line) != InternalShellCharToUpper (*(Command + CommandIndex++))) {
          State = Final;
        }
        Line++;
      break;

      // Handle "[\s01]*(.*)$"
      // Skip whitespace, '0', and '1' characters, if any, prior to the brief description.
      // Return the description to the caller.
      case GetBriefDescription:
        if (*Line != L' ' && *Line != L'\t' && *Line != L'0' && *Line != L'1') {
          *BriefSize = StrSize(Line);
          *BriefDesc = AllocateZeroPool(*BriefSize);
          if (*BriefDesc != NULL) {
            StrCpyS(*BriefDesc, (*BriefSize)/sizeof(CHAR16), Line);
          }
          State = Final;
        }
        Line++;
      break;

      default:
       break;
    }

  } while (State < Final);

  *Found = ReturnFound;
  return ReturnValue;
}

/**
  parses through the MAN file specified by SHELL_FILE_HANDLE and returns the
  "Brief Description" for the .TH section as specified by Command.  If the
  command section is not found return EFI_NOT_FOUND.

  Upon a sucessful return the caller is responsible to free the memory in *BriefDesc

  @param[in] Handle              FileHandle to read from
  @param[in] Command             name of command's section to find as entered on the
                                 command line (may be a relative or absolute path or
                                 be in any case: upper, lower, or mixed in numerous ways!).
  @param[out] BriefDesc          pointer to pointer to string where description goes.
  @param[out] BriefSize          pointer to size of allocated BriefDesc
  @param[in, out] Ascii          TRUE if the file is ASCII, FALSE otherwise, will be
                                 set if the file handle is at the 0 position.

  @retval EFI_OUT_OF_RESOURCES  a memory allocation failed.
  @retval EFI_SUCCESS           the section was found and its description stored in
                                an allocated buffer if requested.
**/
EFI_STATUS
ManFileFindTitleSection(
  IN SHELL_FILE_HANDLE  Handle,
  IN CONST CHAR16       *Command,
  OUT CHAR16            **BriefDesc OPTIONAL,
  OUT UINTN             *BriefSize OPTIONAL,
  IN OUT BOOLEAN        *Ascii
  )
{
  EFI_STATUS  Status;
  CHAR16      *ReadLine;
  UINTN       Size;
  BOOLEAN     Found;
  UINTN       Start;

  if ( Handle     == NULL
    || Command    == NULL
    || (BriefDesc != NULL && BriefSize == NULL)
   ){
    return (EFI_INVALID_PARAMETER);
  }

  Status    = EFI_SUCCESS;
  Size      = 1024;
  Found     = FALSE;

  ReadLine  = AllocateZeroPool(Size);
  if (ReadLine == NULL) {
    return (EFI_OUT_OF_RESOURCES);
  }

  //
  // Do not pass any leading path information that may be present to IsTitleHeader().
  //
  Start = StrLen(Command);
  while ((Start != 0)
         && (*(Command + Start - 1) != L'\\')
         && (*(Command + Start - 1) != L'/')
         && (*(Command + Start - 1) != L':')) {
    --Start;
  }

  for (;!ShellFileHandleEof(Handle);Size = 1024) {
   Status = ShellFileHandleReadLine(Handle, ReadLine, &Size, TRUE, Ascii);
    //
    // ignore too small of buffer...
    //
    if (EFI_ERROR(Status) && Status != EFI_BUFFER_TOO_SMALL) {
      break;
    }

    Status = EFI_NOT_FOUND;
    if (IsTitleHeader (Command+Start, ReadLine, BriefDesc, BriefSize, &Found)) {
      Status = Found ? EFI_SUCCESS : EFI_NOT_FOUND;
      break;
    }
  }

  FreePool(ReadLine);
  return (Status);
}

/**
  This function returns the help information for the specified command. The help text
  will be parsed from a UEFI Shell manual page. (see UEFI Shell 2.0 Appendix B)

  If Sections is specified, then each section name listed will be compared in a casesensitive
  manner, to the section names described in Appendix B. If the section exists,
  it will be appended to the returned help text. If the section does not exist, no
  information will be returned. If Sections is NULL, then all help text information
  available will be returned.

  if BriefDesc is NULL, then the breif description will not be savedd seperatly,
  but placed first in the main HelpText.

  @param[in] ManFileName        Points to the NULL-terminated UEFI Shell MAN file name.
  @param[in] Command            Points to the NULL-terminated UEFI Shell command name.
  @param[in] Sections           Points to the NULL-terminated comma-delimited
                                section names to return. If NULL, then all
                                sections will be returned.
  @param[out] BriefDesc         On return, points to a callee-allocated buffer
                                containing brief description text.
  @param[out] HelpText          On return, points to a callee-allocated buffer
                                containing all specified help text.

  @retval EFI_SUCCESS           The help text was returned.
  @retval EFI_OUT_OF_RESOURCES  The necessary buffer could not be allocated to hold the
                                returned help text.
  @retval EFI_INVALID_PARAMETER HelpText is NULL.
  @retval EFI_INVALID_PARAMETER ManFileName is invalid.
  @retval EFI_NOT_FOUND         There is no help text available for Command.
**/
EFI_STATUS
ProcessManFile(
  IN CONST CHAR16 *ManFileName,
  IN CONST CHAR16 *Command,
  IN CONST CHAR16 *Sections OPTIONAL,
  OUT CHAR16      **BriefDesc OPTIONAL,
  OUT CHAR16      **HelpText
  )
{
  CHAR16            *TempString;
  SHELL_FILE_HANDLE FileHandle;
  EFI_HANDLE        CmdFileImgHandle;
  EFI_STATUS        Status;
  UINTN             HelpSize;
  UINTN             BriefSize;
  UINTN             StringIdWalker;
  BOOLEAN           Ascii;
  CHAR16            *TempString2;
  CHAR16            *CmdFileName;
  CHAR16            *CmdFilePathName;
  CHAR16            *StringBuff;
  EFI_DEVICE_PATH_PROTOCOL      *FileDevPath;
  EFI_DEVICE_PATH_PROTOCOL      *DevPath;
  EFI_HII_PACKAGE_LIST_HEADER   *PackageListHeader;

  if ( ManFileName == NULL
    || Command     == NULL
    || HelpText    == NULL
   ){
    return (EFI_INVALID_PARAMETER);
  }

  HelpSize          = 0;
  BriefSize         = 0;
  StringIdWalker    = 0;
  TempString        = NULL;
  Ascii             = FALSE;
  CmdFileName       = NULL;
  CmdFilePathName   = NULL;
  CmdFileImgHandle  = NULL;
  StringBuff        = NULL;
  PackageListHeader = NULL;
  FileDevPath       = NULL;
  DevPath           = NULL;

  //
  // See if it's in HII first
  //
  TempString = ShellCommandGetCommandHelp(Command);
  if (TempString != NULL) {
    TempString2 = TempString;
    Status = ManBufferFindTitleSection(&TempString2, Command, BriefDesc, &BriefSize);
    if (!EFI_ERROR(Status) && HelpText != NULL){
      Status = ManBufferFindSections(TempString2, Sections, HelpText, &HelpSize);
    }
  } else {
    //
    // If the image is a external app, check .MAN file first.
    //
    FileHandle    = NULL;
    TempString  = GetManFileName(ManFileName);
    if (TempString == NULL) {
      return (EFI_INVALID_PARAMETER);
    }

    Status = SearchPathForFile(TempString, &FileHandle);
    if (EFI_ERROR(Status)) {
      FileDevPath = FileDevicePath(NULL, TempString);
      DevPath = AppendDevicePath (ShellInfoObject.ImageDevPath, FileDevPath);
      Status = InternalOpenFileDevicePath(DevPath, &FileHandle, EFI_FILE_MODE_READ, 0);
      SHELL_FREE_NON_NULL(FileDevPath);
      SHELL_FREE_NON_NULL(DevPath);
    }

    if (!EFI_ERROR(Status)) {
      HelpSize  = 0;
      BriefSize = 0;
      Status = ManFileFindTitleSection(FileHandle, Command, BriefDesc, &BriefSize, &Ascii);
      if (!EFI_ERROR(Status) && HelpText != NULL){
        Status = ManFileFindSections(FileHandle, Sections, HelpText, &HelpSize, Ascii);
      }
      ShellInfoObject.NewEfiShellProtocol->CloseFile(FileHandle);
      if (!EFI_ERROR(Status)) {
        //
        // Get help text from .MAN file success.
        //
        goto Done;
      }
    }

    //
    // Load the app image to check  EFI_HII_PACKAGE_LIST_PROTOCOL.
    //
    CmdFileName     = GetExecuatableFileName(TempString);
    if (CmdFileName == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto Done;
    }
    //
    // If the file in CWD then use the file name, else use the full
    // path name.
    //
    CmdFilePathName = ShellFindFilePath(CmdFileName);
    if (CmdFilePathName == NULL) {
      Status = EFI_NOT_FOUND;
      goto Done;
    }
    DevPath = ShellInfoObject.NewEfiShellProtocol->GetDevicePathFromFilePath(CmdFilePathName);
    Status      = gBS->LoadImage(FALSE, gImageHandle, DevPath, NULL, 0, &CmdFileImgHandle);
    if(EFI_ERROR(Status)) {
      *HelpText = NULL;
      goto Done;
    }
    Status = gBS->OpenProtocol(
                    CmdFileImgHandle,
                    &gEfiHiiPackageListProtocolGuid,
                    (VOID**)&PackageListHeader,
                    gImageHandle,
                    NULL,
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );
    if(EFI_ERROR(Status)) {
      *HelpText = NULL;
      goto Done;
    }

    //
    // If get package list on image handle, install it on HiiDatabase.
    //
    Status = gBS->InstallProtocolInterface (
                    &mShellManDriverHandle,
                    &gEfiDevicePathProtocolGuid,
                    EFI_NATIVE_INTERFACE,
                    &mShellManHiiDevicePath
                    );
    if (EFI_ERROR(Status)) {
      goto Done;
    }

    Status = gHiiDatabase->NewPackageList (
                            gHiiDatabase,
                            PackageListHeader,
                            mShellManDriverHandle,
                            &mShellManHiiHandle
                            );
    if (EFI_ERROR (Status)) {
      goto Done;
    }

    StringIdWalker = 1;
    do {
        SHELL_FREE_NON_NULL(StringBuff);
        if (BriefDesc != NULL) {
          SHELL_FREE_NON_NULL(*BriefDesc);
        }
        StringBuff = HiiGetString (mShellManHiiHandle, (EFI_STRING_ID)StringIdWalker, NULL);
        if (StringBuff == NULL) {
          Status = EFI_NOT_FOUND;
          goto Done;
        }
        TempString2 = StringBuff;
        Status = ManBufferFindTitleSection(&TempString2, Command, BriefDesc, &BriefSize);
        if (!EFI_ERROR(Status) && HelpText != NULL){
          Status = ManBufferFindSections(TempString2, Sections, HelpText, &HelpSize);
        }
        if (!EFI_ERROR(Status)){
          //
          // Found what we need and return
          //
          goto Done;
        }

        StringIdWalker += 1;
    } while (StringIdWalker < 0xFFFF && StringBuff != NULL);

  }

Done:
  if (mShellManDriverHandle != NULL) {
    gBS->UninstallProtocolInterface (
            mShellManDriverHandle,
            &gEfiDevicePathProtocolGuid,
            &mShellManHiiDevicePath
           );
    mShellManDriverHandle = NULL;
  }

  if (mShellManHiiHandle != NULL) {
    HiiRemovePackages (mShellManHiiHandle);
    mShellManHiiHandle = NULL;
  }

  if (CmdFileImgHandle != NULL) {
    Status = gBS->UnloadImage (CmdFileImgHandle);
  }

  SHELL_FREE_NON_NULL(StringBuff);
  SHELL_FREE_NON_NULL(TempString);
  SHELL_FREE_NON_NULL(CmdFileName);
  SHELL_FREE_NON_NULL(CmdFilePathName);
  SHELL_FREE_NON_NULL(FileDevPath);
  SHELL_FREE_NON_NULL(DevPath);

  return (Status);
}

