/** @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); }