This is a shell application to dump dynamic PCD settings. Type DumpDynPcd -?/h/H to get help information. Type DumpDynPcd -v/V to get version information. Type DumpDynPcd [PcdName] to get Pcd information. https://bugzilla.tianocore.org/show_bug.cgi?id=1541 v2:1.Add static for global variables. 2.Change the parameter amount of InternalStrnCatGrow in DumpDynPcd.c. 3.Add open brace according to EDK II C Coding Standards Specification. 4.Remove the dependency on ShellPkg.dec in DumpDynPcd.inf. v3:Add static for all global variables and internal functions. Cc: Jian J Wang <jian.j.wang@intel.com> Cc: Ray Ni <ray.ni@intel.com> Cc: Star Zeng <star.zeng@intel.com> Cc: Eric Dong <eric.dong@intel.com> Signed-off-by: Shenglei Zhang <shenglei.zhang@intel.com> Reviewed-by: Hao A Wu <hao.a.wu@intel.com>
		
			
				
	
	
		
			611 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			611 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
|   A shell application to dump dynamic PCD settings.
 | |
| 
 | |
|   Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
 | |
|   SPDX-License-Identifier: BSD-2-Clause-Patent
 | |
| 
 | |
| **/
 | |
| 
 | |
| #include <Uefi.h>
 | |
| #include <PiDxe.h>
 | |
| #include <Library/BaseLib.h>
 | |
| #include <Library/DebugLib.h>
 | |
| #include <Library/MemoryAllocationLib.h>
 | |
| #include <Library/UefiBootServicesTableLib.h>
 | |
| #include <Library/UefiLib.h>
 | |
| 
 | |
| 
 | |
| #include <Protocol/UnicodeCollation.h>
 | |
| #include <Protocol/PiPcd.h>
 | |
| #include <Protocol/Pcd.h>
 | |
| #include <Protocol/PiPcdInfo.h>
 | |
| #include <Protocol/PcdInfo.h>
 | |
| #include <Protocol/ShellParameters.h>
 | |
| #include <Protocol/Shell.h>
 | |
| 
 | |
| 
 | |
| //
 | |
| // String token ID of help message text.
 | |
| // Shell supports to find help message in the resource section of an application image if
 | |
| // .MAN file is not found. This global variable is added to make build tool recognizes
 | |
| // that the help string is consumed by user and then build tool will add the string into
 | |
| // the resource section. Thus the application can use '-?' option to show help message in
 | |
| // Shell.
 | |
| //
 | |
| GLOBAL_REMOVE_IF_UNREFERENCED EFI_STRING_ID mStrDumpDynPcdHelpTokenId = STRING_TOKEN (STR_DUMP_DYN_PCD_HELP_INFORMATION);
 | |
| 
 | |
| #define MAJOR_VERSION   1
 | |
| #define MINOR_VERSION   0
 | |
| 
 | |
| static EFI_UNICODE_COLLATION_PROTOCOL  *mUnicodeCollation  = NULL;
 | |
| static EFI_PCD_PROTOCOL                *mPiPcd             = NULL;
 | |
| static PCD_PROTOCOL                    *mPcd               = NULL;
 | |
| static EFI_GET_PCD_INFO_PROTOCOL       *mPiPcdInfo         = NULL;
 | |
| static GET_PCD_INFO_PROTOCOL           *mPcdInfo           = NULL;
 | |
| static CHAR16                   *mTempPcdNameBuffer = NULL;
 | |
| static UINTN                     mTempPcdNameBufferSize = 0;
 | |
| 
 | |
| static CONST CHAR8 mHex[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
 | |
| 
 | |
| static UINTN  Argc;
 | |
| static CHAR16 **Argv;
 | |
| 
 | |
| 
 | |
| /**
 | |
| 
 | |
|   This function parse application ARG.
 | |
| 
 | |
|   @return Status
 | |
| **/
 | |
| static
 | |
| EFI_STATUS
 | |
| GetArg (
 | |
|   VOID
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS                    Status;
 | |
|   EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters;
 | |
| 
 | |
|   Status = gBS->HandleProtocol (
 | |
|                   gImageHandle,
 | |
|                   &gEfiShellParametersProtocolGuid,
 | |
|                   (VOID**)&ShellParameters
 | |
|                   );
 | |
|   if (EFI_ERROR(Status)) {
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   Argc = ShellParameters->Argc;
 | |
|   Argv = ShellParameters->Argv;
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| /**
 | |
|    Display current version.
 | |
| **/
 | |
| static
 | |
| VOID
 | |
| ShowVersion (
 | |
|   )
 | |
| {
 | |
|   Print (L"DumpDynPcd Version %d.%02d\n", MAJOR_VERSION, MINOR_VERSION);
 | |
| }
 | |
| 
 | |
| /**
 | |
|    Display Usage and Help information.
 | |
| **/
 | |
| static
 | |
| VOID
 | |
| ShowHelp (
 | |
|   )
 | |
| {
 | |
|   Print (L"Dump dynamic[ex] PCD info.\n");
 | |
|   Print (L"\n");
 | |
|   Print (L"DumpDynPcd [PcdName]\n");
 | |
|   Print (L"\n");
 | |
|   Print (L"  PcdName    Specifies the name of PCD.\n");
 | |
|   Print (L"             A literal[or partial] name or a pattern as specified in\n");
 | |
|   Print (L"             the MetaiMatch() function of the EFI_UNICODE_COLLATION2_PROCOOL.\n");
 | |
|   Print (L"             If it is absent, dump all PCDs' info.\n");
 | |
|   Print (L"The PCD data is printed as hexadecimal dump.\n");
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Dump some hexadecimal data to the screen.
 | |
| 
 | |
|   @param[in] Indent     How many spaces to indent the output.
 | |
|   @param[in] Offset     The offset of the printing.
 | |
|   @param[in] DataSize   The size in bytes of UserData.
 | |
|   @param[in] UserData   The data to print out.
 | |
| **/
 | |
| static
 | |
| VOID
 | |
| DumpHex (
 | |
|   IN UINTN        Indent,
 | |
|   IN UINTN        Offset,
 | |
|   IN UINTN        DataSize,
 | |
|   IN VOID         *UserData
 | |
|   )
 | |
| {
 | |
|   UINT8 *Data;
 | |
| 
 | |
|   CHAR8 Val[50];
 | |
| 
 | |
|   CHAR8 Str[20];
 | |
| 
 | |
|   UINT8 TempByte;
 | |
|   UINTN Size;
 | |
|   UINTN Index;
 | |
| 
 | |
|   Data = UserData;
 | |
|   while (DataSize != 0) {
 | |
|     Size = 16;
 | |
|     if (Size > DataSize) {
 | |
|       Size = DataSize;
 | |
|     }
 | |
| 
 | |
|     for (Index = 0; Index < Size; Index += 1) {
 | |
|       TempByte            = Data[Index];
 | |
|       Val[Index * 3 + 0]  = mHex[TempByte >> 4];
 | |
|       Val[Index * 3 + 1]  = mHex[TempByte & 0xF];
 | |
|       Val[Index * 3 + 2]  = (CHAR8) ((Index == 7) ? '-' : ' ');
 | |
|       Str[Index]          = (CHAR8) ((TempByte < ' ' || TempByte > 'z') ? '.' : TempByte);
 | |
|     }
 | |
| 
 | |
|     Val[Index * 3]  = 0;
 | |
|     Str[Index]      = 0;
 | |
|     Print (L"%*a%08X: %-48a *%a*\r\n", Indent, "", Offset, Val, Str);
 | |
| 
 | |
|     Data += Size;
 | |
|     Offset += Size;
 | |
|     DataSize -= Size;
 | |
|   }
 | |
| }
 | |
| 
 | |
| 
 | |
| /**
 | |
|   Safely append with automatic string resizing given length of Destination and
 | |
|   desired length of copy from Source.
 | |
| 
 | |
|   append the first D characters of Source to the end of Destination, where D is
 | |
|   the lesser of Count and the StrLen() of Source. If appending those D characters
 | |
|   will fit within Destination (whose Size is given as CurrentSize) and
 | |
|   still leave room for a NULL terminator, then those characters are appended,
 | |
|   starting at the original terminating NULL of Destination, and a new terminating
 | |
|   NULL is appended.
 | |
| 
 | |
|   If appending D characters onto Destination will result in a overflow of the size
 | |
|   given in CurrentSize the string will be grown such that the copy can be performed
 | |
|   and CurrentSize will be updated to the new size.
 | |
| 
 | |
|   If Source is NULL, there is nothing to append, just return the current buffer in
 | |
|   Destination.
 | |
| 
 | |
|   if Destination is NULL, then ASSERT()
 | |
|   if Destination's current length (including NULL terminator) is already more then
 | |
|   CurrentSize, then ASSERT()
 | |
| 
 | |
|   @param[in, out] Destination   The String to append onto
 | |
|   @param[in, out] CurrentSize   on call the number of bytes in Destination.  On
 | |
|                                 return possibly the new size (still in bytes).  if NULL
 | |
|                                 then allocate whatever is needed.
 | |
|   @param[in]      Source        The String to append from
 | |
| 
 | |
|   @return Destination           return the resultant string.
 | |
| **/
 | |
| static
 | |
| CHAR16*
 | |
| InternalStrnCatGrow (
 | |
|   IN OUT CHAR16           **Destination,
 | |
|   IN OUT UINTN            *CurrentSize,
 | |
|   IN     CONST CHAR16     *Source
 | |
|   )
 | |
| {
 | |
|   UINTN DestinationStartSize;
 | |
|   UINTN NewSize;
 | |
|   UINTN SourceLen;
 | |
| 
 | |
|   SourceLen = StrLen(Source);
 | |
| 
 | |
|   //
 | |
|   // ASSERTs
 | |
|   //
 | |
|   ASSERT(Destination != NULL);
 | |
| 
 | |
|   //
 | |
|   // If there's nothing to do then just return Destination
 | |
|   //
 | |
|   if (Source == NULL) {
 | |
|     return (*Destination);
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // allow for un-initialized pointers, based on size being 0
 | |
|   //
 | |
|   if (CurrentSize != NULL && *CurrentSize == 0) {
 | |
|     *Destination = NULL;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // allow for NULL pointers address as Destination
 | |
|   //
 | |
|   if (*Destination != NULL) {
 | |
|     ASSERT(CurrentSize != 0);
 | |
|     DestinationStartSize = StrSize(*Destination);
 | |
|     ASSERT(DestinationStartSize <= *CurrentSize);
 | |
|   } else {
 | |
|     DestinationStartSize = 0;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Test and grow if required
 | |
|   //
 | |
|   if (CurrentSize != NULL) {
 | |
|     NewSize = *CurrentSize;
 | |
|     if (NewSize < DestinationStartSize + (SourceLen * sizeof(CHAR16))) {
 | |
|       while (NewSize < (DestinationStartSize + (SourceLen*sizeof(CHAR16)))) {
 | |
|         NewSize += 2 * SourceLen * sizeof(CHAR16);
 | |
|       }
 | |
|       *Destination = ReallocatePool(*CurrentSize, NewSize, *Destination);
 | |
|       *CurrentSize = NewSize;
 | |
|     }
 | |
|   } else {
 | |
|     NewSize = (SourceLen + 1)*sizeof(CHAR16);
 | |
|     *Destination = AllocateZeroPool(NewSize);
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Now use standard StrnCat on a big enough buffer
 | |
|   //
 | |
|   if (*Destination == NULL) {
 | |
|     return (NULL);
 | |
|   }
 | |
| 
 | |
|   StrnCatS(*Destination, NewSize/sizeof(CHAR16), Source, SourceLen);
 | |
|   return *Destination;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Get PCD type string based on input PCD type.
 | |
| 
 | |
|   @param[in]    TokenSpace      PCD Token Space.
 | |
|   @param[in]    PcdType         The input PCD type.
 | |
| 
 | |
|   @return       Pointer to PCD type string.
 | |
| **/
 | |
| static
 | |
| CHAR16 *
 | |
| GetPcdTypeString (
 | |
|   IN CONST EFI_GUID     *TokenSpace,
 | |
|   IN EFI_PCD_TYPE       PcdType
 | |
|   )
 | |
| {
 | |
|   UINTN  BufLen;
 | |
|   CHAR16 *RetString;
 | |
| 
 | |
|   BufLen      = 0;
 | |
|   RetString   = NULL;
 | |
| 
 | |
|   switch (PcdType) {
 | |
|     case EFI_PCD_TYPE_8:
 | |
|       InternalStrnCatGrow (&RetString, &BufLen, L"UINT8");
 | |
|       break;
 | |
|     case EFI_PCD_TYPE_16:
 | |
|       InternalStrnCatGrow (&RetString, &BufLen, L"UINT16");
 | |
|       break;
 | |
|     case EFI_PCD_TYPE_32:
 | |
|       InternalStrnCatGrow (&RetString, &BufLen, L"UINT32");
 | |
|       break;
 | |
|     case EFI_PCD_TYPE_64:
 | |
|       InternalStrnCatGrow (&RetString, &BufLen, L"UINT64");
 | |
|       break;
 | |
|     case EFI_PCD_TYPE_BOOL:
 | |
|       InternalStrnCatGrow (&RetString, &BufLen, L"BOOLEAN");
 | |
|       break;
 | |
|     case EFI_PCD_TYPE_PTR:
 | |
|       InternalStrnCatGrow (&RetString, &BufLen, L"POINTER");
 | |
|       break;
 | |
|     default:
 | |
|       InternalStrnCatGrow (&RetString, &BufLen, L"UNKNOWN");
 | |
|       break;
 | |
|   }
 | |
| 
 | |
|   if (TokenSpace == NULL) {
 | |
|     InternalStrnCatGrow (&RetString, &BufLen, L":DYNAMIC");
 | |
|   } else {
 | |
|     InternalStrnCatGrow (&RetString, &BufLen, L":DYNAMICEX");
 | |
|   }
 | |
| 
 | |
|   return RetString;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Dump PCD info.
 | |
| 
 | |
|   @param[in]    TokenSpace      PCD Token Space.
 | |
|   @param[in]    TokenNumber     PCD Token Number.
 | |
|   @param[in]    PcdInfo         Pointer to PCD info.
 | |
| **/
 | |
| static
 | |
| VOID
 | |
| DumpPcdInfo (
 | |
|   IN CONST EFI_GUID     *TokenSpace,
 | |
|   IN UINTN              TokenNumber,
 | |
|   IN EFI_PCD_INFO       *PcdInfo
 | |
|   )
 | |
| {
 | |
|   CHAR16                *RetString;
 | |
|   UINT8                 Uint8;
 | |
|   UINT16                Uint16;
 | |
|   UINT32                Uint32;
 | |
|   UINT64                Uint64;
 | |
|   BOOLEAN               Boolean;
 | |
|   VOID                  *PcdData;
 | |
| 
 | |
|   RetString = NULL;
 | |
| 
 | |
|   if (PcdInfo->PcdName != NULL) {
 | |
|     Print (L"%a\n", PcdInfo->PcdName);
 | |
|   } else {
 | |
|     if (TokenSpace == NULL) {
 | |
|       Print (L"Default Token Space\n");
 | |
|     } else {
 | |
|       Print (L"%g\n", TokenSpace);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   RetString = GetPcdTypeString (TokenSpace, PcdInfo->PcdType);
 | |
| 
 | |
|   switch (PcdInfo->PcdType) {
 | |
|     case EFI_PCD_TYPE_8:
 | |
|       if (TokenSpace == NULL) {
 | |
|         Uint8 = mPcd->Get8 (TokenNumber);
 | |
|       } else {
 | |
|         Uint8 = mPiPcd->Get8 (TokenSpace, TokenNumber);
 | |
|       }
 | |
|       Print (L"  Token = 0x%08x - Type = %H%-17s%N - Size = 0x%x - Value = 0x%x\n", TokenNumber, RetString, PcdInfo->PcdSize, Uint8);
 | |
|       break;
 | |
|     case EFI_PCD_TYPE_16:
 | |
|       if (TokenSpace == NULL) {
 | |
|         Uint16 = mPcd->Get16 (TokenNumber);
 | |
|       } else {
 | |
|         Uint16 = mPiPcd->Get16 (TokenSpace, TokenNumber);
 | |
|       }
 | |
|       Print (L"  Token = 0x%08x - Type = %H%-17s%N - Size = 0x%x - Value = 0x%x\n", TokenNumber, RetString, PcdInfo->PcdSize, Uint16);
 | |
|       break;
 | |
|     case EFI_PCD_TYPE_32:
 | |
|       if (TokenSpace == NULL) {
 | |
|         Uint32 = mPcd->Get32 (TokenNumber);
 | |
|       } else {
 | |
|         Uint32 = mPiPcd->Get32 (TokenSpace, TokenNumber);
 | |
|       }
 | |
|       Print (L"  Token = 0x%08x - Type = %H%-17s%N - Size = 0x%x - Value = 0x%x\n", TokenNumber, RetString, PcdInfo->PcdSize, Uint32);
 | |
|       break;
 | |
|     case EFI_PCD_TYPE_64:
 | |
|       if (TokenSpace == NULL) {
 | |
|         Uint64 = mPcd->Get64 (TokenNumber);
 | |
|       } else {
 | |
|         Uint64 = mPiPcd->Get64 (TokenSpace, TokenNumber);
 | |
|       }
 | |
|       Print (L"  Token = 0x%08x - Type = %H%-17s%N - Size = 0x%x - Value = 0x%lx\n", TokenNumber, RetString, PcdInfo->PcdSize, Uint64);
 | |
|       break;
 | |
|     case EFI_PCD_TYPE_BOOL:
 | |
|       if (TokenSpace == NULL) {
 | |
|         Boolean = mPcd->GetBool (TokenNumber);
 | |
|       } else {
 | |
|         Boolean = mPiPcd->GetBool (TokenSpace, TokenNumber);
 | |
|       }
 | |
|       Print (L"  Token = 0x%08x - Type = %H%-17s%N - Size = 0x%x - Value = %a\n", TokenNumber, RetString, PcdInfo->PcdSize, Boolean ? "TRUE" : "FALSE");
 | |
|       break;
 | |
|     case EFI_PCD_TYPE_PTR:
 | |
|       if (TokenSpace == NULL) {
 | |
|         PcdData = mPcd->GetPtr (TokenNumber);
 | |
|       } else {
 | |
|         PcdData = mPiPcd->GetPtr (TokenSpace, TokenNumber);
 | |
|       }
 | |
|       Print (L"  Token = 0x%08x - Type = %H%-17s%N - Size = 0x%x\n", TokenNumber, RetString, PcdInfo->PcdSize);
 | |
|       DumpHex (2, 0, PcdInfo->PcdSize, PcdData);
 | |
|       break;
 | |
|     default:
 | |
|       return;
 | |
|   }
 | |
| 
 | |
|   if (RetString != NULL) {
 | |
|     FreePool (RetString);
 | |
|   }
 | |
|   Print (L"\n");
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Show one or all PCDs' info.
 | |
| 
 | |
|   @param[in]  InputPcdName       Pointer to PCD name to show. If NULL, show all PCDs' info.
 | |
| 
 | |
|   @retval EFI_SUCCESS            Command completed successfully.
 | |
|   @retval EFI_OUT_OF_RESOURCES   Not enough resources were available to run the command.
 | |
|   @retval EFI_ABORTED            Aborted by user.
 | |
|   @retval EFI_NOT_FOUND          The specified PCD is not found.
 | |
| **/
 | |
| static
 | |
| EFI_STATUS
 | |
| ProcessPcd (
 | |
|   IN CHAR16     *InputPcdName
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS            Status;
 | |
|   EFI_GUID              *TokenSpace;
 | |
|   UINTN                 TokenNumber;
 | |
|   EFI_PCD_INFO          PcdInfo;
 | |
|   BOOLEAN               Found;
 | |
|   UINTN                 PcdNameSize;
 | |
| 
 | |
|   PcdInfo.PcdName = NULL;
 | |
|   PcdInfo.PcdSize = 0;
 | |
|   PcdInfo.PcdType = 0xFF;
 | |
|   Found = FALSE;
 | |
| 
 | |
|   Print (L"Current system SKU ID: 0x%x\n\n", mPiPcdInfo->GetSku ());
 | |
| 
 | |
|   TokenSpace = NULL;
 | |
|   do {
 | |
|     TokenNumber = 0;
 | |
|     do {
 | |
|       Status = mPiPcd->GetNextToken (TokenSpace, &TokenNumber);
 | |
|       if (!EFI_ERROR (Status) && TokenNumber != 0) {
 | |
|         if (TokenSpace == NULL) {
 | |
|           //
 | |
|           // PCD in default Token Space.
 | |
|           //
 | |
|           mPcdInfo->GetInfo (TokenNumber, &PcdInfo);
 | |
|         } else {
 | |
|           mPiPcdInfo->GetInfo (TokenSpace, TokenNumber, &PcdInfo);
 | |
|         }
 | |
|         if (InputPcdName != NULL) {
 | |
|           if (PcdInfo.PcdName == NULL) {
 | |
|             continue;
 | |
|           }
 | |
|           PcdNameSize = AsciiStrSize (PcdInfo.PcdName) * sizeof (CHAR16);
 | |
|           if (mTempPcdNameBuffer == NULL) {
 | |
|             mTempPcdNameBufferSize = PcdNameSize;
 | |
|             mTempPcdNameBuffer = AllocatePool (mTempPcdNameBufferSize);
 | |
|           } else if (mTempPcdNameBufferSize < PcdNameSize) {
 | |
|             mTempPcdNameBuffer = ReallocatePool (mTempPcdNameBufferSize, PcdNameSize, mTempPcdNameBuffer);
 | |
|             mTempPcdNameBufferSize = PcdNameSize;
 | |
|           }
 | |
|           if (mTempPcdNameBuffer == NULL) {
 | |
|             return EFI_OUT_OF_RESOURCES;
 | |
|           }
 | |
|           AsciiStrToUnicodeStrS (PcdInfo.PcdName, mTempPcdNameBuffer, mTempPcdNameBufferSize / sizeof (CHAR16));
 | |
|           //
 | |
|           // Compare the input PCD name with the PCD name in PCD database.
 | |
|           //
 | |
|           if ((StrStr (mTempPcdNameBuffer, InputPcdName) != NULL) ||
 | |
|               (mUnicodeCollation != NULL && mUnicodeCollation->MetaiMatch (mUnicodeCollation, mTempPcdNameBuffer, InputPcdName))) {
 | |
|             //
 | |
|             // Found matched PCD.
 | |
|             //
 | |
|             DumpPcdInfo (TokenSpace, TokenNumber, &PcdInfo);
 | |
|             Found = TRUE;
 | |
|           }
 | |
|         } else {
 | |
|           DumpPcdInfo (TokenSpace, TokenNumber, &PcdInfo);
 | |
|         }
 | |
|       }
 | |
|     } while (!EFI_ERROR (Status) && TokenNumber != 0);
 | |
| 
 | |
|     Status = mPiPcd->GetNextTokenSpace ((CONST EFI_GUID **) &TokenSpace);
 | |
|   } while (!EFI_ERROR (Status) && TokenSpace != NULL);
 | |
| 
 | |
|   if ((InputPcdName != NULL) && !Found) {
 | |
|     //
 | |
|     // The specified PCD is not found, print error.
 | |
|     //
 | |
|     Print (L"%EError. %NNo matching PCD found: %s.\n", InputPcdName);
 | |
|     return EFI_NOT_FOUND;
 | |
|   }
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Main entrypoint for DumpDynPcd shell application.
 | |
| 
 | |
|   @param[in]  ImageHandle     The image handle.
 | |
|   @param[in]  SystemTable     The system table.
 | |
| 
 | |
|   @retval EFI_SUCCESS            Command completed successfully.
 | |
|   @retval EFI_INVALID_PARAMETER  Command usage error.
 | |
|   @retval EFI_OUT_OF_RESOURCES   Not enough resources were available to run the command.
 | |
|   @retval EFI_ABORTED            Aborted by user.
 | |
|   @retval EFI_NOT_FOUND          The specified PCD is not found.
 | |
|   @retval Others                 Error status returned from gBS->LocateProtocol.
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| DumpDynPcdMain (
 | |
|   IN EFI_HANDLE        ImageHandle,
 | |
|   IN EFI_SYSTEM_TABLE  *SystemTable
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS    Status;
 | |
|   CHAR16        *InputPcdName;
 | |
| 
 | |
|   InputPcdName  = NULL;
 | |
| 
 | |
|   Status = gBS->LocateProtocol(&gEfiUnicodeCollation2ProtocolGuid, NULL, (VOID **) &mUnicodeCollation);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     mUnicodeCollation = NULL;
 | |
|   }
 | |
| 
 | |
|   Status = gBS->LocateProtocol (&gEfiPcdProtocolGuid, NULL, (VOID **) &mPiPcd);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     Print (L"DumpDynPcd: %EError. %NPI PCD protocol is not present.\n");
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   Status = gBS->LocateProtocol (&gEfiGetPcdInfoProtocolGuid, NULL, (VOID **) &mPiPcdInfo);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     Print (L"DumpDynPcd: %EError. %NPI PCD info protocol is not present.\n");
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   Status = gBS->LocateProtocol (&gPcdProtocolGuid, NULL, (VOID **) &mPcd);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     Print (L"DumpDynPcd: %EError. %NPCD protocol is not present.\n");
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   Status = gBS->LocateProtocol (&gGetPcdInfoProtocolGuid, NULL, (VOID **) &mPcdInfo);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     Print (L"DumpDynPcd: %EError. %NPCD info protocol is not present.\n");
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // get the command line arguments
 | |
|   //
 | |
|   Status = GetArg();
 | |
|   if (EFI_ERROR(Status)){
 | |
|     Print (L"DumpDynPcd: %EError. %NThe input parameters are not recognized.\n");
 | |
|     Status = EFI_INVALID_PARAMETER;
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   if (Argc > 2){
 | |
|     Print (L"DumpDynPcd: %EError. %NToo many arguments specified.\n");
 | |
|     Status = EFI_INVALID_PARAMETER;
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   if (Argc == 1){
 | |
|     Status = ProcessPcd (InputPcdName);
 | |
|     goto Done;
 | |
|   }
 | |
| 
 | |
|   if ((StrCmp(Argv[1], L"-?") == 0)||(StrCmp(Argv[1], L"-h") == 0)||(StrCmp(Argv[1], L"-H") == 0)){
 | |
|     ShowHelp ();
 | |
|     goto Done;
 | |
|   } else {
 | |
|     if ((StrCmp(Argv[1], L"-v") == 0)||(StrCmp(Argv[1], L"-V") == 0)){
 | |
|       ShowVersion ();
 | |
|       goto Done;
 | |
|     } else {
 | |
|       if (StrStr(Argv[1], L"-") != NULL){
 | |
|         Print (L"DumpDynPcd: %EError. %NThe argument '%B%s%N' is invalid.\n", Argv[1]);
 | |
|         goto Done;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   InputPcdName = Argv[1];
 | |
|   Status = ProcessPcd (InputPcdName);
 | |
| 
 | |
|   Done:
 | |
| 
 | |
|   if (mTempPcdNameBuffer != NULL) {
 | |
|     FreePool (mTempPcdNameBuffer);
 | |
|   }
 | |
| 
 | |
|   return Status;
 | |
| }
 | |
| 
 |