/** @file Main file for devices shell Driver1 function. (C) Copyright 2012-2015 Hewlett-Packard Development Company, L.P.
Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include "UefiShellDriver1CommandsLib.h" /** Get lots of info about a device from its handle. @param[in] TheHandle The device handle to get info on. @param[in, out] Type On successful return R, B, or D (root, bus, or device) will be placed in this buffer. @param[in, out] Cfg On successful return this buffer will be TRUE if the handle has configuration, FALSE otherwise. @param[in, out] Diag On successful return this buffer will be TRUE if the handle has disgnostics, FALSE otherwise. @param[in, out] Parents On successful return this buffer will be contain the number of parent handles. @param[in, out] Devices On successful return this buffer will be contain the number of devices controlled. @param[in, out] Children On successful return this buffer will be contain the number of child handles. @param[out] Name The pointer to a buffer that will be allocated and contain the string name of the handle. The caller must free this memory. @param[in] Language The language code as defined by the UEFI spec. @retval EFI_SUCCESS The info is there. @retval EFI_INVALID_PARAMETER A parameter was invalid. **/ EFI_STATUS GetDeviceHandleInfo ( IN EFI_HANDLE TheHandle, IN OUT CHAR16 *Type, IN OUT BOOLEAN *Cfg, IN OUT BOOLEAN *Diag, IN OUT UINTN *Parents, IN OUT UINTN *Devices, IN OUT UINTN *Children, OUT CHAR16 **Name, IN CONST CHAR8 *Language ) { EFI_STATUS Status; EFI_HANDLE *HandleBuffer; UINTN Count; if ( (TheHandle == NULL) || (Type == NULL) || (Cfg == NULL) || (Diag == NULL) || (Parents == NULL) || (Devices == NULL) || (Children == NULL) || (Name == NULL)) { return (EFI_INVALID_PARAMETER); } *Cfg = FALSE; *Diag = FALSE; *Children = 0; *Parents = 0; *Devices = 0; *Type = L' '; *Name = CHAR_NULL; HandleBuffer = NULL; Status = EFI_SUCCESS; gEfiShellProtocol->GetDeviceName (TheHandle, EFI_DEVICE_NAME_USE_COMPONENT_NAME|EFI_DEVICE_NAME_USE_DEVICE_PATH, (CHAR8 *)Language, Name); Status = ParseHandleDatabaseForChildControllers (TheHandle, Children, NULL); // if (!EFI_ERROR(Status)) { Status = PARSE_HANDLE_DATABASE_PARENTS (TheHandle, Parents, NULL); if (/*!EFI_ERROR(Status) && */ (Parents != NULL) && (Children != NULL)) { if (*Parents == 0) { *Type = L'R'; } else if (*Children > 0) { *Type = L'B'; } else { *Type = L'D'; } } // } Status = PARSE_HANDLE_DATABASE_UEFI_DRIVERS (TheHandle, Devices, &HandleBuffer); if (!EFI_ERROR (Status) && (Devices != NULL) && (HandleBuffer != NULL)) { for (Count = 0; Count < *Devices; Count++) { if (!EFI_ERROR (gBS->OpenProtocol (HandleBuffer[Count], &gEfiDriverConfigurationProtocolGuid, NULL, NULL, gImageHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) { *Cfg = TRUE; } if (!EFI_ERROR (gBS->OpenProtocol (HandleBuffer[Count], &gEfiDriverDiagnosticsProtocolGuid, NULL, NULL, gImageHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) { *Diag = TRUE; } if (!EFI_ERROR (gBS->OpenProtocol (HandleBuffer[Count], &gEfiDriverDiagnostics2ProtocolGuid, NULL, NULL, gImageHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) { *Diag = TRUE; } } SHELL_FREE_NON_NULL (HandleBuffer); } return (Status); } STATIC CONST SHELL_PARAM_ITEM ParamList[] = { { L"-sfo", TypeFlag }, { L"-l", TypeValue }, { NULL, TypeMax } }; /** Function for 'devices' command. @param[in] ImageHandle Handle to the Image (NULL if Internal). @param[in] SystemTable Pointer to the System Table (NULL if Internal). **/ SHELL_STATUS EFIAPI ShellCommandRunDevices ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; LIST_ENTRY *Package; CHAR16 *ProblemParam; SHELL_STATUS ShellStatus; CHAR8 *Language; EFI_HANDLE *HandleList; EFI_HANDLE *HandleListWalker; CHAR16 Type; BOOLEAN Cfg; BOOLEAN Diag; UINTN Parents; UINTN Devices; UINTN Children; CHAR16 *Name; CONST CHAR16 *Lang; BOOLEAN SfoFlag; ShellStatus = SHELL_SUCCESS; Language = NULL; SfoFlag = FALSE; // // initialize the shell lib (we must be in non-auto-init...) // Status = ShellInitialize (); ASSERT_EFI_ERROR (Status); Status = CommandInit (); ASSERT_EFI_ERROR (Status); // // parse the command line // Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE); if (EFI_ERROR (Status)) { if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDriver1HiiHandle, L"devices", ProblemParam); FreePool (ProblemParam); ShellStatus = SHELL_INVALID_PARAMETER; } else { ASSERT (FALSE); } } else { // // if more than 0 'value' parameters we have too many parameters // if (ShellCommandLineGetRawValue (Package, 1) != NULL) { // // error for too many parameters // ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDriver1HiiHandle, L"devices"); ShellStatus = SHELL_INVALID_PARAMETER; } else { // // get the language if necessary // Lang = ShellCommandLineGetValue (Package, L"-l"); if (Lang != NULL) { Language = AllocateZeroPool (StrSize (Lang)); AsciiSPrint (Language, StrSize (Lang), "%S", Lang); } else if (!ShellCommandLineGetFlag (Package, L"-l")) { ASSERT (Language == NULL); // Language = AllocateZeroPool(10); // AsciiSPrint(Language, 10, "en-us"); } else { ASSERT (Language == NULL); ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"devices", L"-l"); ShellCommandLineFreeVarList (Package); return (SHELL_INVALID_PARAMETER); } // // Print Header // if (ShellCommandLineGetFlag (Package, L"-sfo")) { ShellPrintHiiEx (-1, -1, Language, STRING_TOKEN (STR_GEN_SFO_HEADER), gShellDriver1HiiHandle, L"devices"); SfoFlag = TRUE; } else { ShellPrintHiiEx (-1, -1, Language, STRING_TOKEN (STR_DEVICES_HEADER_LINES), gShellDriver1HiiHandle); } // // loop through each handle // HandleList = GetHandleListByProtocol (NULL); ASSERT (HandleList != NULL); for (HandleListWalker = HandleList ; HandleListWalker != NULL && *HandleListWalker != NULL /*&& !EFI_ERROR(Status)*/ ; HandleListWalker++ ) { // // get all the info on each handle // Name = NULL; Status = GetDeviceHandleInfo (*HandleListWalker, &Type, &Cfg, &Diag, &Parents, &Devices, &Children, &Name, Language); if ((Name != NULL) && ((Parents != 0) || (Devices != 0) || (Children != 0))) { ShellPrintHiiEx ( -1, -1, Language, SfoFlag ? STRING_TOKEN (STR_DEVICES_ITEM_LINE_SFO) : STRING_TOKEN (STR_DEVICES_ITEM_LINE), gShellDriver1HiiHandle, ConvertHandleToHandleIndex (*HandleListWalker), Type, Cfg ? (SfoFlag ? L'Y' : L'X') : (SfoFlag ? L'N' : L'-'), Diag ? (SfoFlag ? L'Y' : L'X') : (SfoFlag ? L'N' : L'-'), Parents, Devices, Children, Name != NULL ? Name : L"" ); } if (Name != NULL) { FreePool (Name); } if (ShellGetExecutionBreakFlag ()) { ShellStatus = SHELL_ABORTED; break; } } if (HandleList != NULL) { FreePool (HandleList); } } SHELL_FREE_NON_NULL (Language); ShellCommandLineFreeVarList (Package); } return (ShellStatus); }