/** @file Main file for DrvCfg shell Driver1 function. (C) Copyright 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" #include #include STATIC CONST EFI_GUID *CfgGuidList[] = { &gEfiDriverConfigurationProtocolGuid, &gEfiDriverConfiguration2ProtocolGuid, NULL }; /** Find the EFI_HII_HANDLE by device path. @param[in] DevPath1 The Device Path to match. @param[out] HiiHandle The EFI_HII_HANDLE after the converstion. @param[in] HiiDb The Hii database protocol @retval EFI_SUCCESS The operation was successful. @retval EFI_NOT_FOUND There was no EFI_HII_HANDLE found for that deviec path. **/ EFI_STATUS FindHiiHandleViaDevPath ( IN CONST EFI_DEVICE_PATH_PROTOCOL *DevPath1, OUT EFI_HII_HANDLE *HiiHandle, IN EFI_HII_DATABASE_PROTOCOL *HiiDb ) { EFI_HII_HANDLE *HandleBuffer; UINTN HandleBufferSize; VOID *MainBuffer; UINTN MainBufferSize; EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader; EFI_HII_PACKAGE_HEADER *PackageHeader; UINTN LoopVariable; EFI_DEVICE_PATH_PROTOCOL *DevPath2; EFI_STATUS Status; ASSERT (DevPath1 != NULL); ASSERT (HiiHandle != NULL); ASSERT (*HiiHandle == NULL); ASSERT (HiiDb != NULL); HandleBufferSize = 0; HandleBuffer = NULL; Status = HiiDb->ListPackageLists (HiiDb, EFI_HII_PACKAGE_DEVICE_PATH, NULL, &HandleBufferSize, HandleBuffer); if (Status == EFI_BUFFER_TOO_SMALL) { HandleBuffer = AllocateZeroPool (HandleBufferSize); if (HandleBuffer == NULL) { Status = EFI_OUT_OF_RESOURCES; } else { Status = HiiDb->ListPackageLists (HiiDb, EFI_HII_PACKAGE_DEVICE_PATH, NULL, &HandleBufferSize, HandleBuffer); } } if (EFI_ERROR (Status)) { SHELL_FREE_NON_NULL (HandleBuffer); return (Status); } if (HandleBuffer == NULL) { return EFI_NOT_FOUND; } for (LoopVariable = 0; LoopVariable < (HandleBufferSize/sizeof (HandleBuffer[0])) && *HiiHandle == NULL; LoopVariable++) { MainBufferSize = 0; MainBuffer = NULL; Status = HiiDb->ExportPackageLists (HiiDb, HandleBuffer[LoopVariable], &MainBufferSize, MainBuffer); if (Status == EFI_BUFFER_TOO_SMALL) { MainBuffer = AllocateZeroPool (MainBufferSize); if (MainBuffer != NULL) { Status = HiiDb->ExportPackageLists (HiiDb, HandleBuffer[LoopVariable], &MainBufferSize, MainBuffer); } } if (EFI_ERROR (Status)) { continue; } // // Enumerate through the block of returned memory. // This should actually be a small block, but we need to be sure. // for (PackageListHeader = (EFI_HII_PACKAGE_LIST_HEADER *)MainBuffer ; PackageListHeader != NULL && ((CHAR8 *)PackageListHeader) < (((CHAR8 *)MainBuffer)+MainBufferSize) && *HiiHandle == NULL ; PackageListHeader = (EFI_HII_PACKAGE_LIST_HEADER *)(((CHAR8 *)(PackageListHeader)) + PackageListHeader->PackageLength)) { for (PackageHeader = (EFI_HII_PACKAGE_HEADER *)(((CHAR8 *)(PackageListHeader))+sizeof (EFI_HII_PACKAGE_LIST_HEADER)) ; PackageHeader != NULL && ((CHAR8 *)PackageHeader) < (((CHAR8 *)MainBuffer)+MainBufferSize) && PackageHeader->Type != EFI_HII_PACKAGE_END && *HiiHandle == NULL ; PackageHeader = (EFI_HII_PACKAGE_HEADER *)(((CHAR8 *)(PackageHeader))+PackageHeader->Length)) { if (PackageHeader->Type == EFI_HII_PACKAGE_DEVICE_PATH) { DevPath2 = (EFI_DEVICE_PATH_PROTOCOL *)(((CHAR8 *)PackageHeader) + sizeof (EFI_HII_PACKAGE_HEADER)); if (DevicePathCompare (&DevPath1, &DevPath2) == 0) { *HiiHandle = HandleBuffer[LoopVariable]; break; } } } } SHELL_FREE_NON_NULL (MainBuffer); } SHELL_FREE_NON_NULL (HandleBuffer); if (*HiiHandle == NULL) { return (EFI_NOT_FOUND); } return (EFI_SUCCESS); } /** Convert a EFI_HANDLE to a EFI_HII_HANDLE. @param[in] Handle The EFI_HANDLE to convert. @param[out] HiiHandle The EFI_HII_HANDLE after the converstion. @param[in] HiiDb The Hii database protocol @retval EFI_SUCCESS The operation was successful. **/ EFI_STATUS ConvertHandleToHiiHandle ( IN CONST EFI_HANDLE Handle, OUT EFI_HII_HANDLE *HiiHandle, IN EFI_HII_DATABASE_PROTOCOL *HiiDb ) { EFI_STATUS Status; EFI_DEVICE_PATH_PROTOCOL *DevPath1; if ((HiiHandle == NULL) || (HiiDb == NULL)) { return (EFI_INVALID_PARAMETER); } *HiiHandle = NULL; if (Handle == NULL) { return (EFI_SUCCESS); } DevPath1 = NULL; Status = gBS->OpenProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID **)&DevPath1, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); if (EFI_ERROR (Status) || (DevPath1 == NULL)) { return (EFI_NOT_FOUND); } return (FindHiiHandleViaDevPath (DevPath1, HiiHandle, HiiDb)); } /** Function to print out all HII configuration information to a file. @param[in] Handle The handle to get info on. NULL to do all handles. @param[in] FileName The filename to rwite the info to. **/ SHELL_STATUS ConfigToFile ( IN CONST EFI_HANDLE Handle, IN CONST CHAR16 *FileName ) { EFI_HII_DATABASE_PROTOCOL *HiiDatabase; EFI_STATUS Status; VOID *MainBuffer; UINTN MainBufferSize; EFI_HII_HANDLE HiiHandle; SHELL_FILE_HANDLE FileHandle; HiiDatabase = NULL; MainBufferSize = 0; MainBuffer = NULL; FileHandle = NULL; Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, 0); if (EFI_ERROR (Status)) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDriver1HiiHandle, L"drvcfg", FileName, Status ); return (SHELL_DEVICE_ERROR); } // // Locate HII Database protocol // Status = gBS->LocateProtocol ( &gEfiHiiDatabaseProtocolGuid, NULL, (VOID **)&HiiDatabase ); if (EFI_ERROR (Status) || (HiiDatabase == NULL)) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_GEN_PROTOCOL_NF), gShellDriver1HiiHandle, L"drvcfg", L"EfiHiiDatabaseProtocol", &gEfiHiiDatabaseProtocolGuid ); ShellCloseFile (&FileHandle); return (SHELL_NOT_FOUND); } HiiHandle = NULL; Status = ConvertHandleToHiiHandle (Handle, &HiiHandle, HiiDatabase); if (EFI_ERROR (Status)) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_GEN_HANDLE_NOT), gShellDriver1HiiHandle, L"drvcfg", ConvertHandleToHandleIndex (Handle), L"Device" ); ShellCloseFile (&FileHandle); return (SHELL_DEVICE_ERROR); } Status = HiiDatabase->ExportPackageLists (HiiDatabase, HiiHandle, &MainBufferSize, MainBuffer); if (Status == EFI_BUFFER_TOO_SMALL) { MainBuffer = AllocateZeroPool (MainBufferSize); Status = HiiDatabase->ExportPackageLists (HiiDatabase, HiiHandle, &MainBufferSize, MainBuffer); } Status = ShellWriteFile (FileHandle, &MainBufferSize, MainBuffer); ShellCloseFile (&FileHandle); SHELL_FREE_NON_NULL (MainBuffer); if (EFI_ERROR (Status)) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_FILE_WRITE_FAIL), gShellDriver1HiiHandle, L"drvcfg", FileName ); return (SHELL_DEVICE_ERROR); } ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_DRVCFG_COMP), gShellDriver1HiiHandle ); return (SHELL_SUCCESS); } /** Function to read in HII configuration information from a file. @param[in] Handle The handle to get info for. @param[in] FileName The filename to read the info from. **/ SHELL_STATUS ConfigFromFile ( IN EFI_HANDLE Handle, IN CONST CHAR16 *FileName ) { EFI_HII_DATABASE_PROTOCOL *HiiDatabase; EFI_STATUS Status; VOID *MainBuffer; UINT64 Temp; UINTN MainBufferSize; EFI_HII_HANDLE HiiHandle; SHELL_FILE_HANDLE FileHandle; CHAR16 *TempDevPathString; EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader; EFI_HII_PACKAGE_HEADER *PackageHeader; EFI_DEVICE_PATH_PROTOCOL *DevPath; UINTN HandleIndex; HiiDatabase = NULL; MainBufferSize = 0; MainBuffer = NULL; FileHandle = NULL; Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ, 0); if (EFI_ERROR (Status)) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDriver1HiiHandle, L"drvcfg", FileName, Status ); return (SHELL_DEVICE_ERROR); } // // Locate HII Database protocol // Status = gBS->LocateProtocol ( &gEfiHiiDatabaseProtocolGuid, NULL, (VOID **)&HiiDatabase ); if (EFI_ERROR (Status) || (HiiDatabase == NULL)) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_GEN_PROTOCOL_NF), gShellDriver1HiiHandle, L"drvcfg", L"EfiHiiDatabaseProtocol", &gEfiHiiDatabaseProtocolGuid ); ShellCloseFile (&FileHandle); return (SHELL_NOT_FOUND); } Status = ShellGetFileSize (FileHandle, &Temp); MainBufferSize = (UINTN)Temp; if (EFI_ERROR (Status)) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_FILE_READ_FAIL), gShellDriver1HiiHandle, L"drvcfg", FileName ); ShellCloseFile (&FileHandle); return (SHELL_DEVICE_ERROR); } MainBuffer = AllocateZeroPool ((UINTN)MainBufferSize); if (EFI_ERROR (Status)) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellDriver1HiiHandle, L"drvcfg" ); ShellCloseFile (&FileHandle); return (SHELL_DEVICE_ERROR); } Status = ShellReadFile (FileHandle, &MainBufferSize, MainBuffer); if (EFI_ERROR (Status)) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_FILE_READ_FAIL), gShellDriver1HiiHandle, L"drvcfg", FileName ); ShellCloseFile (&FileHandle); SHELL_FREE_NON_NULL (MainBuffer); return (SHELL_DEVICE_ERROR); } ShellCloseFile (&FileHandle); if (Handle != NULL) { // // User override in place. Just do it. // HiiHandle = NULL; Status = ConvertHandleToHiiHandle (Handle, &HiiHandle, HiiDatabase); if (EFI_ERROR (Status)) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_GEN_HANDLE_NOT), gShellDriver1HiiHandle, L"drvcfg", ConvertHandleToHandleIndex (Handle), L"Device" ); ShellCloseFile (&FileHandle); return (SHELL_DEVICE_ERROR); } Status = HiiDatabase->UpdatePackageList (HiiDatabase, HiiHandle, MainBuffer); if (EFI_ERROR (Status)) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_GEN_UEFI_FUNC_WARN), gShellDriver1HiiHandle, L"drvcfg", L"HiiDatabase->UpdatePackageList", Status ); return (SHELL_DEVICE_ERROR); } } else { // // we need to parse the buffer and try to match the device paths for each item to try to find it's device path. // for (PackageListHeader = (EFI_HII_PACKAGE_LIST_HEADER *)MainBuffer ; PackageListHeader != NULL && ((CHAR8 *)PackageListHeader) < (((CHAR8 *)MainBuffer)+MainBufferSize) ; PackageListHeader = (EFI_HII_PACKAGE_LIST_HEADER *)(((CHAR8 *)(PackageListHeader)) + PackageListHeader->PackageLength)) { for (PackageHeader = (EFI_HII_PACKAGE_HEADER *)(((CHAR8 *)(PackageListHeader))+sizeof (EFI_HII_PACKAGE_LIST_HEADER)) ; PackageHeader != NULL && ((CHAR8 *)PackageHeader) < (((CHAR8 *)MainBuffer)+MainBufferSize) && PackageHeader->Type != EFI_HII_PACKAGE_END ; PackageHeader = (EFI_HII_PACKAGE_HEADER *)(((CHAR8 *)(PackageHeader))+PackageHeader->Length)) { if (PackageHeader->Type == EFI_HII_PACKAGE_DEVICE_PATH) { HiiHandle = NULL; Status = FindHiiHandleViaDevPath ((EFI_DEVICE_PATH_PROTOCOL *)(((CHAR8 *)PackageHeader) + sizeof (EFI_HII_PACKAGE_HEADER)), &HiiHandle, HiiDatabase); if (EFI_ERROR (Status)) { // // print out an error. // TempDevPathString = ConvertDevicePathToText ((EFI_DEVICE_PATH_PROTOCOL *)(((CHAR8 *)PackageHeader) + sizeof (EFI_HII_PACKAGE_HEADER)), TRUE, TRUE); ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_DRVCFG_IN_FILE_NF), gShellDriver1HiiHandle, TempDevPathString ); SHELL_FREE_NON_NULL (TempDevPathString); } else { Status = HiiDatabase->UpdatePackageList (HiiDatabase, HiiHandle, PackageListHeader); if (EFI_ERROR (Status)) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_GEN_UEFI_FUNC_WARN), gShellDriver1HiiHandle, L"drvcfg", L"HiiDatabase->UpdatePackageList", Status ); return (SHELL_DEVICE_ERROR); } else { DevPath = (EFI_DEVICE_PATH_PROTOCOL *)(((CHAR8 *)PackageHeader) + sizeof (EFI_HII_PACKAGE_HEADER)); gBS->LocateDevicePath (&gEfiHiiConfigAccessProtocolGuid, &DevPath, &Handle); HandleIndex = ConvertHandleToHandleIndex (Handle); ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_DRVCFG_DONE_HII), gShellDriver1HiiHandle, HandleIndex ); } } } } } } SHELL_FREE_NON_NULL (MainBuffer); ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_DRVCFG_COMP), gShellDriver1HiiHandle ); return (SHELL_SUCCESS); } /** Present a requested action to the user. @param[in] DriverImageHandle The handle for the driver to configure. @param[in] ControllerHandle The handle of the device being managed by the Driver specified. @param[in] ChildHandle The handle of a child device of the specified device. @param[in] ActionRequired The required HII action. @retval SHELL_INVALID_PARAMETER A parameter has a invalid value. **/ EFI_STATUS ShellCmdDriverConfigurationProcessActionRequired ( EFI_HANDLE DriverImageHandle, EFI_HANDLE ControllerHandle, EFI_HANDLE ChildHandle, EFI_DRIVER_CONFIGURATION_ACTION_REQUIRED ActionRequired ) { EFI_HANDLE ConnectControllerContextOverride[2]; switch (ActionRequired) { case EfiDriverConfigurationActionNone: ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DRVCFG_NONE), gShellDriver1HiiHandle); break; case EfiDriverConfigurationActionStopController: ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DRVCFG_STOP), gShellDriver1HiiHandle); ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DRVCFG_ENTER_S), gShellDriver1HiiHandle, L"stop controller"); ShellPromptForResponse (ShellPromptResponseTypeEnterContinue, NULL, NULL); gBS->DisconnectController (ControllerHandle, DriverImageHandle, ChildHandle); ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DRVCFG_CTLR_S), gShellDriver1HiiHandle, L"stopped"); break; case EfiDriverConfigurationActionRestartController: ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DRVCFG_RESTART_S), gShellDriver1HiiHandle, L"controller"); ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DRVCFG_ENTER_S), gShellDriver1HiiHandle, L"restart controller"); ShellPromptForResponse (ShellPromptResponseTypeEnterContinue, NULL, NULL); gBS->DisconnectController (ControllerHandle, DriverImageHandle, ChildHandle); ConnectControllerContextOverride[0] = DriverImageHandle; ConnectControllerContextOverride[1] = NULL; gBS->ConnectController (ControllerHandle, ConnectControllerContextOverride, NULL, TRUE); ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DRVCFG_CTLR_S), gShellDriver1HiiHandle, L"restarted"); break; case EfiDriverConfigurationActionRestartPlatform: ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DRVCFG_RESTART_S), gShellDriver1HiiHandle, L"platform"); ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DRVCFG_ENTER_S), gShellDriver1HiiHandle, L"restart platform"); ShellPromptForResponse (ShellPromptResponseTypeEnterContinue, NULL, NULL); gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL); break; default: return (EFI_INVALID_PARAMETER); } return EFI_SUCCESS; } /** Do the configuration in an environment without HII. @param[in] Language The language code. @param[in] ForceDefaults TRUE to force defaults, FALSE otherwise. @param[in] DefaultType If ForceDefaults is TRUE, specifies the default type. @param[in] AllChildren TRUE to configure all children, FALSE otherwise. @param[in] ValidateOptions TRUE to validate existing options, FALSE otherwise. @param[in] SetOptions TRUE to set options, FALSE otherwise. @param[in] DriverImageHandle The handle for the driver to configure. @param[in] DeviceHandle The handle of the device being managed by the Driver specified. @param[in] ChildHandle The handle of a child device of the specified device. @retval SHELL_NOT_FOUND A specified handle could not be found. @retval SHELL_INVALID_PARAMETER A parameter has a invalid value. **/ SHELL_STATUS PreHiiDrvCfg ( IN CONST CHAR8 *Language, IN BOOLEAN ForceDefaults, IN UINT32 DefaultType, IN BOOLEAN AllChildren, IN BOOLEAN ValidateOptions, IN BOOLEAN SetOptions, IN EFI_HANDLE DriverImageHandle, IN EFI_HANDLE DeviceHandle, IN EFI_HANDLE ChildHandle ) { EFI_STATUS Status; SHELL_STATUS ShellStatus; UINTN OuterLoopCounter; CHAR8 *BestLanguage; UINTN DriverImageHandleCount; EFI_HANDLE *DriverImageHandleBuffer; UINTN HandleCount; EFI_HANDLE *HandleBuffer; UINTN *HandleType; UINTN LoopCounter; UINTN ChildIndex; UINTN ChildHandleCount; EFI_HANDLE *ChildHandleBuffer; UINTN *ChildHandleType; EFI_DRIVER_CONFIGURATION_ACTION_REQUIRED ActionRequired; EFI_DRIVER_CONFIGURATION_PROTOCOL *DriverConfiguration; BOOLEAN Iso639Language; UINTN HandleIndex1; UINTN HandleIndex2; UINTN HandleIndex3; ShellStatus = SHELL_SUCCESS; if ((ChildHandle == NULL) && AllChildren) { SetOptions = FALSE; } if (ForceDefaults) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_DRVCFG_FORCE_D), gShellDriver1HiiHandle, DefaultType ); } else if (ValidateOptions) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_DRVCFG_VALIDATE), gShellDriver1HiiHandle ); } else if (SetOptions) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_DRVCFG_SET), gShellDriver1HiiHandle ); } if (DriverImageHandle == 0) { DriverImageHandleBuffer = GetHandleListByProtocolList (CfgGuidList); if (DriverImageHandleBuffer == NULL) { ShellStatus = SHELL_NOT_FOUND; goto Done; } for ( HandleBuffer = DriverImageHandleBuffer, DriverImageHandleCount = 0 ; HandleBuffer != NULL && *HandleBuffer != NULL ; HandleBuffer++, DriverImageHandleCount++) { } } else { DriverImageHandleCount = 1; // // Allocate buffer to hold the image handle so as to // keep consistent with the above clause // DriverImageHandleBuffer = AllocatePool (sizeof (EFI_HANDLE)); ASSERT (DriverImageHandleBuffer); DriverImageHandleBuffer[0] = DriverImageHandle; } for (OuterLoopCounter = 0; OuterLoopCounter < DriverImageHandleCount; OuterLoopCounter++) { Iso639Language = FALSE; Status = gBS->OpenProtocol ( DriverImageHandleBuffer[OuterLoopCounter], &gEfiDriverConfiguration2ProtocolGuid, (VOID **)&DriverConfiguration, NULL, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL ); if (EFI_ERROR (Status)) { Iso639Language = TRUE; Status = gBS->OpenProtocol ( DriverImageHandleBuffer[OuterLoopCounter], &gEfiDriverConfigurationProtocolGuid, (VOID **)&DriverConfiguration, NULL, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL ); } if (EFI_ERROR (Status)) { // ShellPrintHiiEx( // -1, // -1, // NULL, // STRING_TOKEN (STR_DRVCFG_NOT_SUPPORT), // gShellDriver1HiiHandle, // ConvertHandleToHandleIndex (DriverImageHandleBuffer[OuterLoopCounter]) // ); ShellStatus = SHELL_UNSUPPORTED; continue; } BestLanguage = GetBestLanguage ( DriverConfiguration->SupportedLanguages, Iso639Language, Language != NULL ? Language : "", DriverConfiguration->SupportedLanguages, NULL ); if (BestLanguage == NULL) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"drvcfg", L"-l" ); ShellStatus = SHELL_INVALID_PARAMETER; continue; } Status = ParseHandleDatabaseByRelationshipWithType ( DriverImageHandleBuffer[OuterLoopCounter], NULL, &HandleCount, &HandleBuffer, &HandleType ); if (EFI_ERROR (Status)) { continue; } if (SetOptions && (DeviceHandle == NULL)) { gST->ConOut->ClearScreen (gST->ConOut); Status = DriverConfiguration->SetOptions ( DriverConfiguration, NULL, NULL, BestLanguage, &ActionRequired ); gST->ConOut->ClearScreen (gST->ConOut); ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_DRVCFG_ALL_LANG), gShellDriver1HiiHandle, ConvertHandleToHandleIndex (DriverImageHandleBuffer[OuterLoopCounter]), DriverConfiguration->SupportedLanguages ); if (!EFI_ERROR (Status)) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_DRVCFG_OPTIONS_SET), gShellDriver1HiiHandle ); for (LoopCounter = 0; LoopCounter < HandleCount; LoopCounter++) { if ((HandleType[LoopCounter] & HR_CONTROLLER_HANDLE) == HR_CONTROLLER_HANDLE) { ShellCmdDriverConfigurationProcessActionRequired ( DriverImageHandleBuffer[OuterLoopCounter], HandleBuffer[LoopCounter], NULL, ActionRequired ); } } } else { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_DRVCFG_NOT_SET), gShellDriver1HiiHandle, Status ); } continue; } for (LoopCounter = 0; LoopCounter < HandleCount; LoopCounter++) { if ((HandleType[LoopCounter] & HR_CONTROLLER_HANDLE) != HR_CONTROLLER_HANDLE) { continue; } if ((DeviceHandle != NULL) && (DeviceHandle != HandleBuffer[LoopCounter])) { continue; } if (ChildHandle == NULL) { HandleIndex1 = ConvertHandleToHandleIndex (DriverImageHandleBuffer[OuterLoopCounter]); HandleIndex2 = ConvertHandleToHandleIndex (HandleBuffer[LoopCounter]); ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_DRVCFG_CTRL_LANG), gShellDriver1HiiHandle, HandleIndex1, HandleIndex2, DriverConfiguration->SupportedLanguages ); if (ForceDefaults) { Status = DriverConfiguration->ForceDefaults ( DriverConfiguration, HandleBuffer[LoopCounter], NULL, DefaultType, &ActionRequired ); if (!EFI_ERROR (Status)) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_DRVCFG_DEF_FORCED), gShellDriver1HiiHandle ); ShellCmdDriverConfigurationProcessActionRequired ( DriverImageHandleBuffer[OuterLoopCounter], HandleBuffer[LoopCounter], NULL, ActionRequired ); } else { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_DRVCFG_FORCE_FAILED), gShellDriver1HiiHandle, Status ); ShellStatus = SHELL_DEVICE_ERROR; } } else if (ValidateOptions) { Status = DriverConfiguration->OptionsValid ( DriverConfiguration, HandleBuffer[LoopCounter], NULL ); if (!EFI_ERROR (Status)) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_DRVCFG_OPTIONS_VALID), gShellDriver1HiiHandle ); } else { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_DRVCFG_OPTIONS_INV), gShellDriver1HiiHandle, Status ); ShellStatus = SHELL_DEVICE_ERROR; } } else if (SetOptions) { gST->ConOut->ClearScreen (gST->ConOut); Status = DriverConfiguration->SetOptions ( DriverConfiguration, HandleBuffer[LoopCounter], NULL, BestLanguage, &ActionRequired ); gST->ConOut->ClearScreen (gST->ConOut); HandleIndex1 = ConvertHandleToHandleIndex (DriverImageHandleBuffer[OuterLoopCounter]); HandleIndex2 = ConvertHandleToHandleIndex (HandleBuffer[LoopCounter]); ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_DRVCFG_CTRL_LANG), gShellDriver1HiiHandle, HandleIndex1, HandleIndex2, DriverConfiguration->SupportedLanguages ); if (!EFI_ERROR (Status)) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_DRVCFG_OPTIONS_SET), gShellDriver1HiiHandle ); ShellCmdDriverConfigurationProcessActionRequired ( DriverImageHandleBuffer[OuterLoopCounter], HandleBuffer[LoopCounter], NULL, ActionRequired ); } else { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_DRVCFG_NOT_SET), gShellDriver1HiiHandle, Status ); ShellStatus = SHELL_DEVICE_ERROR; } } else { Print (L"\n"); } } if ((ChildHandle == NULL) && !AllChildren) { continue; } Status = ParseHandleDatabaseByRelationshipWithType ( DriverImageHandleBuffer[OuterLoopCounter], HandleBuffer[LoopCounter], &ChildHandleCount, &ChildHandleBuffer, &ChildHandleType ); if (EFI_ERROR (Status)) { continue; } for (ChildIndex = 0; ChildIndex < ChildHandleCount; ChildIndex++) { if ((ChildHandleType[ChildIndex] & HR_CHILD_HANDLE) != HR_CHILD_HANDLE) { continue; } if ((ChildHandle != NULL) && (ChildHandle != ChildHandleBuffer[ChildIndex])) { continue; } HandleIndex1 = ConvertHandleToHandleIndex (DriverImageHandleBuffer[OuterLoopCounter]); HandleIndex2 = ConvertHandleToHandleIndex (HandleBuffer[LoopCounter]); HandleIndex3 = ConvertHandleToHandleIndex (ChildHandleBuffer[ChildIndex]); ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_DRVCFG_CHILD_LANG), gShellDriver1HiiHandle, HandleIndex1, HandleIndex2, HandleIndex3, DriverConfiguration->SupportedLanguages ); if (ForceDefaults) { Status = DriverConfiguration->ForceDefaults ( DriverConfiguration, HandleBuffer[LoopCounter], ChildHandleBuffer[ChildIndex], DefaultType, &ActionRequired ); if (!EFI_ERROR (Status)) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_DRVCFG_DEF_FORCED), gShellDriver1HiiHandle ); ShellCmdDriverConfigurationProcessActionRequired ( DriverImageHandleBuffer[OuterLoopCounter], HandleBuffer[LoopCounter], ChildHandleBuffer[ChildIndex], ActionRequired ); } else { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_DRVCFG_FORCE_FAILED), gShellDriver1HiiHandle, Status ); ShellStatus = SHELL_DEVICE_ERROR; } } else if (ValidateOptions) { Status = DriverConfiguration->OptionsValid ( DriverConfiguration, HandleBuffer[LoopCounter], ChildHandleBuffer[ChildIndex] ); if (!EFI_ERROR (Status)) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_DRVCFG_OPTIONS_VALID), gShellDriver1HiiHandle ); } else { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_DRVCFG_OPTIONS_INV), gShellDriver1HiiHandle, Status ); ShellStatus = SHELL_DEVICE_ERROR; } } else if (SetOptions) { gST->ConOut->ClearScreen (gST->ConOut); Status = DriverConfiguration->SetOptions ( DriverConfiguration, HandleBuffer[LoopCounter], ChildHandleBuffer[ChildIndex], BestLanguage, &ActionRequired ); gST->ConOut->ClearScreen (gST->ConOut); HandleIndex1 = ConvertHandleToHandleIndex (DriverImageHandleBuffer[OuterLoopCounter]); HandleIndex2 = ConvertHandleToHandleIndex (HandleBuffer[LoopCounter]); HandleIndex3 = ConvertHandleToHandleIndex (ChildHandleBuffer[ChildIndex]); ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_DRVCFG_CHILD_LANG), gShellDriver1HiiHandle, HandleIndex1, HandleIndex2, HandleIndex3, DriverConfiguration->SupportedLanguages ); if (!EFI_ERROR (Status)) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_DRVCFG_OPTIONS_SET), gShellDriver1HiiHandle ); ShellCmdDriverConfigurationProcessActionRequired ( DriverImageHandleBuffer[OuterLoopCounter], HandleBuffer[LoopCounter], ChildHandleBuffer[ChildIndex], ActionRequired ); } else { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_DRVCFG_NOT_SET), gShellDriver1HiiHandle, Status ); ShellStatus = SHELL_DEVICE_ERROR; } } else { Print (L"\n"); } } FreePool (ChildHandleBuffer); FreePool (ChildHandleType); } FreePool (BestLanguage); FreePool (HandleBuffer); FreePool (HandleType); } if ((DriverImageHandle != NULL) && (DriverImageHandleCount != 0)) { FreePool (DriverImageHandleBuffer); } Done: return ShellStatus; } /** Function to print out configuration information on all configurable handles. @param[in] ChildrenToo TRUE to tewst for children. @param[in] Language ASCII string for language code. @param[in] UseHii TRUE to check for Hii and DPC, FALSE for DCP only. @retval SHELL_SUCCESS The operation was successful. **/ SHELL_STATUS PrintConfigInfoOnAll ( IN CONST BOOLEAN ChildrenToo, IN CONST CHAR8 *Language, IN CONST BOOLEAN UseHii ) { EFI_HANDLE *HandleList; EFI_HANDLE *CurrentHandle; BOOLEAN Found; UINTN Index2; Found = FALSE; HandleList = NULL; CurrentHandle = NULL; if (UseHii) { // // HII method // HandleList = GetHandleListByProtocol (&gEfiHiiConfigAccessProtocolGuid); for (CurrentHandle = HandleList; CurrentHandle != NULL && *CurrentHandle != NULL; CurrentHandle++) { Found = TRUE; Index2 = *CurrentHandle == NULL ? 0 : ConvertHandleToHandleIndex (*CurrentHandle); ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_DRVCFG_LINE_HII), gShellDriver1HiiHandle, Index2 ); } SHELL_FREE_NON_NULL (HandleList); } if (PreHiiDrvCfg ( Language, FALSE, 0, ChildrenToo, FALSE, FALSE, 0, 0, 0 ) == SHELL_SUCCESS) { Found = TRUE; } if (!Found) { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DRVCFG_NONE_FOUND), gShellDriver1HiiHandle); return (SHELL_SUCCESS); } return (SHELL_SUCCESS); } STATIC CONST SHELL_PARAM_ITEM ParamListHii[] = { { L"-s", TypeFlag }, { L"-l", TypeValue }, { L"-f", TypeValue }, { L"-o", TypeValue }, { L"-i", TypeValue }, { NULL, TypeMax } }; STATIC CONST SHELL_PARAM_ITEM ParamListPreHii[] = { { L"-c", TypeFlag }, { L"-s", TypeFlag }, { L"-v", TypeFlag }, { L"-l", TypeValue }, { L"-f", TypeValue }, { NULL, TypeMax } }; /** Function for 'drvcfg' 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 ShellCommandRunDrvCfg ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; LIST_ENTRY *Package; CHAR16 *ProblemParam; SHELL_STATUS ShellStatus; CHAR8 *Language; CONST CHAR16 *Lang; CONST CHAR16 *HandleIndex1; CONST CHAR16 *HandleIndex2; CONST CHAR16 *HandleIndex3; CONST CHAR16 *ForceTypeString; BOOLEAN Force; BOOLEAN Set; BOOLEAN Validate; BOOLEAN InFromFile; BOOLEAN OutToFile; BOOLEAN AllChildren; BOOLEAN UseHii; UINT32 ForceType; UINT64 Intermediate; EFI_HANDLE Handle1; EFI_HANDLE Handle2; EFI_HANDLE Handle3; CONST CHAR16 *FileName; ShellStatus = SHELL_SUCCESS; Status = EFI_SUCCESS; Language = NULL; UseHii = TRUE; ProblemParam = NULL; // // 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 (ParamListHii, &Package, &ProblemParam, TRUE); if (EFI_ERROR (Status) || (ShellCommandLineGetCount (Package) > 2)) { UseHii = FALSE; if (Package != NULL) { ShellCommandLineFreeVarList (Package); } SHELL_FREE_NON_NULL (ProblemParam); Status = ShellCommandLineParse (ParamListPreHii, &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"drvcfg", ProblemParam); FreePool (ProblemParam); ShellStatus = SHELL_INVALID_PARAMETER; goto Done; } else { ASSERT (FALSE); } } } if (ShellStatus == SHELL_SUCCESS) { if (ShellCommandLineGetCount (Package) > 4) { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDriver1HiiHandle, L"drvcfg"); ShellStatus = SHELL_INVALID_PARAMETER; goto Done; } Lang = ShellCommandLineGetValue (Package, L"-l"); if (Lang != NULL) { Language = AllocateZeroPool (StrSize (Lang)); AsciiSPrint (Language, StrSize (Lang), "%S", Lang); } else if (ShellCommandLineGetFlag (Package, L"-l")) { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"drvcfg", L"-l"); ShellStatus = SHELL_INVALID_PARAMETER; goto Done; } Set = ShellCommandLineGetFlag (Package, L"-s"); Validate = ShellCommandLineGetFlag (Package, L"-v"); InFromFile = ShellCommandLineGetFlag (Package, L"-i"); OutToFile = ShellCommandLineGetFlag (Package, L"-o"); AllChildren = ShellCommandLineGetFlag (Package, L"-c"); Force = ShellCommandLineGetFlag (Package, L"-f"); ForceTypeString = ShellCommandLineGetValue (Package, L"-f"); if (OutToFile) { FileName = ShellCommandLineGetValue (Package, L"-o"); } else if (InFromFile) { FileName = ShellCommandLineGetValue (Package, L"-i"); } else { FileName = NULL; } if (InFromFile && EFI_ERROR (ShellFileExists (FileName))) { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FIND_FAIL), gShellDriver1HiiHandle, L"drvcfg", FileName); ShellStatus = SHELL_INVALID_PARAMETER; goto Done; } if (OutToFile && !EFI_ERROR (ShellFileExists (FileName))) { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_EXIST), gShellDriver1HiiHandle, L"drvcfg", FileName); ShellStatus = SHELL_INVALID_PARAMETER; goto Done; } if (Force && (ForceTypeString == NULL)) { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"drvcfg", L"-f"); ShellStatus = SHELL_INVALID_PARAMETER; goto Done; } if (Force) { Status = ShellConvertStringToUint64 (ForceTypeString, &Intermediate, FALSE, FALSE); if (EFI_ERROR (Status)) { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellDriver1HiiHandle, L"drvcfg", ForceTypeString, L"-f"); ShellStatus = SHELL_INVALID_PARAMETER; goto Done; } ForceType = (UINT32)Intermediate; } else { ForceType = 0; } HandleIndex1 = ShellCommandLineGetRawValue (Package, 1); Handle1 = NULL; if ((HandleIndex1 != NULL) && !EFI_ERROR (ShellConvertStringToUint64 (HandleIndex1, &Intermediate, TRUE, FALSE))) { Handle1 = ConvertHandleIndexToHandle ((UINTN)Intermediate); if ((Handle1 == NULL) || ((UINT64)(UINTN)Intermediate != Intermediate)) { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, L"drvcfg", HandleIndex1); ShellStatus = SHELL_INVALID_PARAMETER; goto Done; } } HandleIndex2 = ShellCommandLineGetRawValue (Package, 2); Handle2 = NULL; if ((HandleIndex2 != NULL) && !EFI_ERROR (ShellConvertStringToUint64 (HandleIndex2, &Intermediate, TRUE, FALSE))) { Handle2 = ConvertHandleIndexToHandle ((UINTN)Intermediate); if ((Handle2 == NULL) || ((UINT64)(UINTN)Intermediate != Intermediate)) { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, L"drvcfg", HandleIndex2); ShellStatus = SHELL_INVALID_PARAMETER; goto Done; } } HandleIndex3 = ShellCommandLineGetRawValue (Package, 3); Handle3 = NULL; if ((HandleIndex3 != NULL) && !EFI_ERROR (ShellConvertStringToUint64 (HandleIndex3, &Intermediate, TRUE, FALSE))) { Handle3 = ConvertHandleIndexToHandle ((UINTN)Intermediate); if ((Handle3 == NULL) || ((UINT64)(UINTN)Intermediate != Intermediate)) { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, L"drvcfg", HandleIndex3); ShellStatus = SHELL_INVALID_PARAMETER; goto Done; } } if ((InFromFile || OutToFile) && (FileName == NULL)) { if (FileName == NULL) { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"drvcfg", InFromFile ? L"-i" : L"-o"); } else { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_HANDLE_REQ), gShellDriver1HiiHandle, L"drvcfg"); } ShellStatus = SHELL_INVALID_PARAMETER; goto Done; } if (!UseHii && (InFromFile || OutToFile)) { if (InFromFile) { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDriver1HiiHandle, L"drvcfg", L"-i"); ShellStatus = SHELL_INVALID_PARAMETER; goto Done; } if (OutToFile) { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDriver1HiiHandle, L"drvcfg", L"-o"); ShellStatus = SHELL_INVALID_PARAMETER; goto Done; } } if (Validate && Force) { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDriver1HiiHandle, L"drvcfg", L"-v", L"-f"); ShellStatus = SHELL_INVALID_PARAMETER; goto Done; } if (Validate && Set) { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDriver1HiiHandle, L"drvcfg", L"-v", L"-s"); ShellStatus = SHELL_INVALID_PARAMETER; goto Done; } if (Set && Force) { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDriver1HiiHandle, L"drvcfg", L"-s", L"-f"); ShellStatus = SHELL_INVALID_PARAMETER; goto Done; } if (OutToFile && InFromFile) { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDriver1HiiHandle, L"drvcfg", L"-i", L"-o"); ShellStatus = SHELL_INVALID_PARAMETER; goto Done; } // // We do HII first. // if (UseHii) { if ((Handle1 != NULL) && EFI_ERROR (gBS->OpenProtocol (Handle1, &gEfiHiiConfigAccessProtocolGuid, NULL, gImageHandle, NULL, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) { // // no HII on this handle. // ShellStatus = SHELL_UNSUPPORTED; } else if (Validate) { } else if (Force) { } else if (Set) { } else if (InFromFile) { ShellStatus = ConfigFromFile (Handle1, FileName); if ((Handle1 != NULL) && (ShellStatus == SHELL_SUCCESS)) { goto Done; } } else if (OutToFile) { ShellStatus = ConfigToFile (Handle1, FileName); if ((Handle1 != NULL) && (ShellStatus == SHELL_SUCCESS)) { goto Done; } } else if (HandleIndex1 == NULL) { // // display all that are configurable // ShellStatus = PrintConfigInfoOnAll (AllChildren, Language, UseHii); goto Done; } else { if (!EFI_ERROR (gBS->OpenProtocol (Handle1, &gEfiHiiConfigAccessProtocolGuid, NULL, gImageHandle, NULL, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_DRVCFG_LINE_HII), gShellDriver1HiiHandle, ConvertHandleToHandleIndex (Handle1) ); goto Done; } } } // // We allways need to do this one since it does both by default. // if (!InFromFile && !OutToFile) { ShellStatus = PreHiiDrvCfg ( Language, Force, ForceType, AllChildren, Validate, Set, Handle1, Handle2, Handle3 ); } if (ShellStatus == SHELL_UNSUPPORTED) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_DRVCFG_NOT_SUPPORT), gShellDriver1HiiHandle, ConvertHandleToHandleIndex (Handle1) ); } } Done: ShellCommandLineFreeVarList (Package); SHELL_FREE_NON_NULL (Language); return (ShellStatus); }