/** @file Main file for DrvCfg shell Driver1 function. (C) Copyright 2015 Hewlett-Packard Development Company, L.P.
Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at http://opensource.org/licenses/bsd-license.php THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. **/ #include "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 EFIAPI 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 EFIAPI 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 EFIAPI 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 EFIAPI 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 EFIAPI 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 EFIAPI 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 EFIAPI 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); }