1 /** @file 2 Main file for devices shell Driver1 function. 3 4 (C) Copyright 2012-2015 Hewlett-Packard Development Company, L.P.<BR> 5 Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR> 6 This program and the accompanying materials 7 are licensed and made available under the terms and conditions of the BSD License 8 which accompanies this distribution. The full text of the license may be found at 9 http://opensource.org/licenses/bsd-license.php 10 11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 13 14 **/ 15 16 #include "UefiShellDriver1CommandsLib.h" 17 18 /** 19 Get lots of info about a device from its handle. 20 21 @param[in] TheHandle The device handle to get info on. 22 @param[in, out] Type On successful return R, B, or D (root, bus, or 23 device) will be placed in this buffer. 24 @param[in, out] Cfg On successful return this buffer will be 25 TRUE if the handle has configuration, FALSE 26 otherwise. 27 @param[in, out] Diag On successful return this buffer will be 28 TRUE if the handle has disgnostics, FALSE 29 otherwise. 30 @param[in, out] Parents On successful return this buffer will be 31 contain the number of parent handles. 32 @param[in, out] Devices On successful return this buffer will be 33 contain the number of devices controlled. 34 @param[in, out] Children On successful return this buffer will be 35 contain the number of child handles. 36 @param[out] Name The pointer to a buffer that will be allocated 37 and contain the string name of the handle. 38 The caller must free this memory. 39 @param[in] Language The language code as defined by the UEFI spec. 40 41 @retval EFI_SUCCESS The info is there. 42 @retval EFI_INVALID_PARAMETER A parameter was invalid. 43 **/ 44 EFI_STATUS 45 EFIAPI 46 GetDeviceHandleInfo ( 47 IN EFI_HANDLE TheHandle, 48 IN OUT CHAR16 *Type, 49 IN OUT BOOLEAN *Cfg, 50 IN OUT BOOLEAN *Diag, 51 IN OUT UINTN *Parents, 52 IN OUT UINTN *Devices, 53 IN OUT UINTN *Children, 54 OUT CHAR16 **Name, 55 IN CONST CHAR8 *Language 56 ) 57 { 58 EFI_STATUS Status; 59 EFI_HANDLE *HandleBuffer; 60 UINTN Count; 61 62 if (TheHandle == NULL 63 || Type == NULL 64 || Cfg == NULL 65 || Diag == NULL 66 || Parents == NULL 67 || Devices == NULL 68 || Children == NULL 69 || Name == NULL ) { 70 return (EFI_INVALID_PARAMETER); 71 } 72 73 *Cfg = FALSE; 74 *Diag = FALSE; 75 *Children = 0; 76 *Parents = 0; 77 *Devices = 0; 78 *Type = L' '; 79 *Name = CHAR_NULL; 80 HandleBuffer = NULL; 81 Status = EFI_SUCCESS; 82 83 gEfiShellProtocol->GetDeviceName(TheHandle, EFI_DEVICE_NAME_USE_COMPONENT_NAME|EFI_DEVICE_NAME_USE_DEVICE_PATH, (CHAR8*)Language, Name); 84 85 Status = ParseHandleDatabaseForChildControllers(TheHandle, Children, NULL); 86 // if (!EFI_ERROR(Status)) { 87 Status = PARSE_HANDLE_DATABASE_PARENTS(TheHandle, Parents, NULL); 88 if (/*!EFI_ERROR(Status) && */Parents != NULL && Children != NULL) { 89 if (*Parents == 0) { 90 *Type = L'R'; 91 } else if (*Children > 0) { 92 *Type = L'B'; 93 } else { 94 *Type = L'D'; 95 } 96 } 97 // } 98 Status = PARSE_HANDLE_DATABASE_UEFI_DRIVERS(TheHandle, Devices, &HandleBuffer); 99 if (!EFI_ERROR(Status) && Devices != NULL && HandleBuffer != NULL) { 100 for (Count = 0 ; Count < *Devices ; Count++) { 101 if (!EFI_ERROR(gBS->OpenProtocol(HandleBuffer[Count], &gEfiDriverConfigurationProtocolGuid, NULL, NULL, gImageHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) { 102 *Cfg = TRUE; 103 } 104 if (!EFI_ERROR(gBS->OpenProtocol(HandleBuffer[Count], &gEfiDriverDiagnosticsProtocolGuid, NULL, NULL, gImageHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) { 105 *Diag = TRUE; 106 } 107 if (!EFI_ERROR(gBS->OpenProtocol(HandleBuffer[Count], &gEfiDriverDiagnostics2ProtocolGuid, NULL, NULL, gImageHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) { 108 *Diag = TRUE; 109 } 110 } 111 SHELL_FREE_NON_NULL(HandleBuffer); 112 } 113 114 return (Status); 115 } 116 117 STATIC CONST SHELL_PARAM_ITEM ParamList[] = { 118 {L"-sfo", TypeFlag}, 119 {L"-l", TypeValue}, 120 {NULL, TypeMax} 121 }; 122 123 /** 124 Function for 'devices' command. 125 126 @param[in] ImageHandle Handle to the Image (NULL if Internal). 127 @param[in] SystemTable Pointer to the System Table (NULL if Internal). 128 **/ 129 SHELL_STATUS 130 EFIAPI 131 ShellCommandRunDevices ( 132 IN EFI_HANDLE ImageHandle, 133 IN EFI_SYSTEM_TABLE *SystemTable 134 ) 135 { 136 EFI_STATUS Status; 137 LIST_ENTRY *Package; 138 CHAR16 *ProblemParam; 139 SHELL_STATUS ShellStatus; 140 CHAR8 *Language; 141 EFI_HANDLE *HandleList; 142 EFI_HANDLE *HandleListWalker; 143 CHAR16 Type; 144 BOOLEAN Cfg; 145 BOOLEAN Diag; 146 UINTN Parents; 147 UINTN Devices; 148 UINTN Children; 149 CHAR16 *Name; 150 CONST CHAR16 *Lang; 151 BOOLEAN SfoFlag; 152 153 ShellStatus = SHELL_SUCCESS; 154 Language = NULL; 155 SfoFlag = FALSE; 156 157 // 158 // initialize the shell lib (we must be in non-auto-init...) 159 // 160 Status = ShellInitialize(); 161 ASSERT_EFI_ERROR(Status); 162 163 Status = CommandInit(); 164 ASSERT_EFI_ERROR(Status); 165 166 // 167 // parse the command line 168 // 169 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE); 170 if (EFI_ERROR(Status)) { 171 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) { 172 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDriver1HiiHandle, L"devices", ProblemParam); 173 FreePool(ProblemParam); 174 ShellStatus = SHELL_INVALID_PARAMETER; 175 } else { 176 ASSERT(FALSE); 177 } 178 } else { 179 // 180 // if more than 0 'value' parameters we have too many parameters 181 // 182 if (ShellCommandLineGetRawValue(Package, 1) != NULL){ 183 // 184 // error for too many parameters 185 // 186 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDriver1HiiHandle, L"devices"); 187 ShellStatus = SHELL_INVALID_PARAMETER; 188 } else { 189 // 190 // get the language if necessary 191 // 192 Lang = ShellCommandLineGetValue(Package, L"-l"); 193 if (Lang != NULL) { 194 Language = AllocateZeroPool(StrSize(Lang)); 195 AsciiSPrint(Language, StrSize(Lang), "%S", Lang); 196 } else if (!ShellCommandLineGetFlag(Package, L"-l")){ 197 ASSERT(Language == NULL); 198 // Language = AllocateZeroPool(10); 199 // AsciiSPrint(Language, 10, "en-us"); 200 } else { 201 ASSERT(Language == NULL); 202 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"devices", L"-l"); 203 ShellCommandLineFreeVarList (Package); 204 return (SHELL_INVALID_PARAMETER); 205 } 206 207 208 // 209 // Print Header 210 211 // 212 if (ShellCommandLineGetFlag (Package, L"-sfo")) { 213 ShellPrintHiiEx (-1, -1, Language, STRING_TOKEN (STR_GEN_SFO_HEADER), gShellDriver1HiiHandle, L"devices"); 214 SfoFlag = TRUE; 215 } else { 216 ShellPrintHiiEx (-1, -1, Language, STRING_TOKEN (STR_DEVICES_HEADER_LINES), gShellDriver1HiiHandle); 217 } 218 219 // 220 // loop through each handle 221 // 222 HandleList = GetHandleListByProtocol(NULL); 223 ASSERT(HandleList != NULL); 224 for (HandleListWalker = HandleList 225 ; HandleListWalker != NULL && *HandleListWalker != NULL /*&& !EFI_ERROR(Status)*/ 226 ; HandleListWalker++ 227 ){ 228 229 // 230 // get all the info on each handle 231 // 232 Name = NULL; 233 Status = GetDeviceHandleInfo(*HandleListWalker, &Type, &Cfg, &Diag, &Parents, &Devices, &Children, &Name, Language); 234 if (Name != NULL && (Parents != 0 || Devices != 0 || Children != 0)) { 235 ShellPrintHiiEx ( 236 -1, 237 -1, 238 Language, 239 SfoFlag?STRING_TOKEN (STR_DEVICES_ITEM_LINE_SFO):STRING_TOKEN (STR_DEVICES_ITEM_LINE), 240 gShellDriver1HiiHandle, 241 ConvertHandleToHandleIndex (*HandleListWalker), 242 Type, 243 Cfg?(SfoFlag?L'Y':L'X'):(SfoFlag?L'N':L'-'), 244 Diag?(SfoFlag?L'Y':L'X'):(SfoFlag?L'N':L'-'), 245 Parents, 246 Devices, 247 Children, 248 Name!=NULL?Name:L"<UNKNOWN>"); 249 } 250 if (Name != NULL) { 251 FreePool(Name); 252 } 253 if (ShellGetExecutionBreakFlag ()) { 254 ShellStatus = SHELL_ABORTED; 255 break; 256 } 257 258 } 259 260 if (HandleList != NULL) { 261 FreePool(HandleList); 262 } 263 264 } 265 SHELL_FREE_NON_NULL(Language); 266 ShellCommandLineFreeVarList (Package); 267 } 268 return (ShellStatus); 269 } 270 271