1 /** @file 2 Main file for Drivers shell Driver1 function. 3 4 (C) Copyright 2012-2015 Hewlett-Packard Development Company, L.P.<BR> 5 Copyright (c) 2010 - 2015, 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 #define MAX_LEN_DRIVER_NAME 35 19 20 STATIC CONST SHELL_PARAM_ITEM ParamList[] = { 21 {L"-sfo", TypeFlag}, 22 {L"-l", TypeValue}, 23 {NULL, TypeMax} 24 }; 25 26 /** 27 Get a device path (in text format) for a given handle. 28 29 @param[in] TheHandle The handle to get the device path for. 30 31 @retval NULL An error occured. 32 @return A pointer to the driver path as a string. The callee must 33 free this memory. 34 **/ 35 CHAR16* 36 EFIAPI 37 GetDevicePathTextForHandle( 38 IN EFI_HANDLE TheHandle 39 ) 40 { 41 EFI_STATUS Status; 42 EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; 43 EFI_DEVICE_PATH_PROTOCOL *ImageDevicePath; 44 EFI_DEVICE_PATH_PROTOCOL *FinalPath; 45 CHAR16 *RetVal; 46 47 FinalPath = NULL; 48 49 Status = gBS->OpenProtocol ( 50 TheHandle, 51 &gEfiLoadedImageProtocolGuid, 52 (VOID**)&LoadedImage, 53 gImageHandle, 54 NULL, 55 EFI_OPEN_PROTOCOL_GET_PROTOCOL 56 ); 57 if (!EFI_ERROR (Status)) { 58 Status = gBS->OpenProtocol ( 59 LoadedImage->DeviceHandle, 60 &gEfiDevicePathProtocolGuid, 61 (VOID**)&ImageDevicePath, 62 gImageHandle, 63 NULL, 64 EFI_OPEN_PROTOCOL_GET_PROTOCOL 65 ); 66 if (!EFI_ERROR (Status)) { 67 FinalPath = AppendDevicePath (ImageDevicePath, LoadedImage->FilePath); 68 gBS->CloseProtocol( 69 LoadedImage->DeviceHandle, 70 &gEfiDevicePathProtocolGuid, 71 gImageHandle, 72 NULL); 73 } 74 gBS->CloseProtocol( 75 TheHandle, 76 &gEfiLoadedImageProtocolGuid, 77 gImageHandle, 78 NULL); 79 } 80 81 if (FinalPath == NULL) { 82 return (NULL); 83 } 84 RetVal = gEfiShellProtocol->GetFilePathFromDevicePath(FinalPath); 85 if (RetVal == NULL) { 86 RetVal = ConvertDevicePathToText(FinalPath, TRUE, TRUE); 87 } 88 FreePool(FinalPath); 89 return (RetVal); 90 } 91 92 /** 93 Determine if the given handle has Driver Configuration protocol. 94 95 @param[in] TheHandle The handle to the driver to test. 96 97 @retval TRUE The driver does have Driver Configuration. 98 @retval FALSE The driver does not have Driver Configuration. 99 **/ 100 BOOLEAN 101 EFIAPI 102 ReturnDriverConfig( 103 IN CONST EFI_HANDLE TheHandle 104 ) 105 { 106 EFI_STATUS Status; 107 Status = gBS->OpenProtocol((EFI_HANDLE)TheHandle, &gEfiDriverConfigurationProtocolGuid, NULL, gImageHandle, NULL, EFI_OPEN_PROTOCOL_TEST_PROTOCOL); 108 if (EFI_ERROR(Status)) { 109 return (FALSE); 110 } 111 return (TRUE); 112 } 113 114 /** 115 Determine if the given handle has DriverDiagnostics protocol. 116 117 @param[in] TheHandle The handle to the driver to test. 118 119 @retval TRUE The driver does have Driver Diasgnostics. 120 @retval FALSE The driver does not have Driver Diagnostics. 121 **/ 122 BOOLEAN 123 EFIAPI 124 ReturnDriverDiag( 125 IN CONST EFI_HANDLE TheHandle 126 ) 127 { 128 EFI_STATUS Status; 129 Status = gBS->OpenProtocol((EFI_HANDLE)TheHandle, &gEfiDriverDiagnostics2ProtocolGuid, NULL, gImageHandle, NULL, EFI_OPEN_PROTOCOL_TEST_PROTOCOL); 130 if (EFI_ERROR(Status)) { 131 Status = gBS->OpenProtocol((EFI_HANDLE)TheHandle, &gEfiDriverDiagnosticsProtocolGuid, NULL, gImageHandle, NULL, EFI_OPEN_PROTOCOL_TEST_PROTOCOL); 132 if (EFI_ERROR(Status)) { 133 return (FALSE); 134 } 135 } 136 return (TRUE); 137 } 138 139 /** 140 Finds and returns the version of the driver specified by TheHandle. 141 142 @param[in] TheHandle The driver handle to get the version of. 143 144 @return The version of the driver. 145 @retval 0xFFFFFFFF An error ocurred. 146 **/ 147 UINT32 148 EFIAPI 149 ReturnDriverVersion( 150 IN CONST EFI_HANDLE TheHandle 151 ) 152 { 153 EFI_DRIVER_BINDING_PROTOCOL *DriverBinding; 154 EFI_STATUS Status; 155 UINT32 RetVal; 156 157 RetVal = (UINT32)-1; 158 159 Status = gBS->OpenProtocol((EFI_HANDLE)TheHandle, &gEfiDriverBindingProtocolGuid, (VOID**)&DriverBinding, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); 160 if (!EFI_ERROR(Status)) { 161 RetVal = DriverBinding->Version; 162 gBS->CloseProtocol(TheHandle, &gEfiDriverBindingProtocolGuid, gImageHandle, NULL); 163 } 164 return (RetVal); 165 } 166 167 /** 168 Function for 'drivers' command. 169 170 @param[in] ImageHandle Handle to the Image (NULL if Internal). 171 @param[in] SystemTable Pointer to the System Table (NULL if Internal). 172 **/ 173 SHELL_STATUS 174 EFIAPI 175 ShellCommandRunDrivers ( 176 IN EFI_HANDLE ImageHandle, 177 IN EFI_SYSTEM_TABLE *SystemTable 178 ) 179 { 180 EFI_STATUS Status; 181 LIST_ENTRY *Package; 182 CHAR16 *ProblemParam; 183 SHELL_STATUS ShellStatus; 184 CHAR8 *Language; 185 CONST CHAR16 *Lang; 186 EFI_HANDLE *HandleList; 187 EFI_HANDLE *HandleWalker; 188 UINTN ChildCount; 189 UINTN DeviceCount; 190 CHAR16 *Temp2; 191 CONST CHAR16 *FullDriverName; 192 CHAR16 *TruncatedDriverName; 193 CHAR16 *FormatString; 194 UINT32 DriverVersion; 195 BOOLEAN DriverConfig; 196 BOOLEAN DriverDiag; 197 BOOLEAN SfoFlag; 198 199 ShellStatus = SHELL_SUCCESS; 200 Status = EFI_SUCCESS; 201 Language = NULL; 202 FormatString = NULL; 203 SfoFlag = FALSE; 204 205 // 206 // initialize the shell lib (we must be in non-auto-init...) 207 // 208 Status = ShellInitialize(); 209 ASSERT_EFI_ERROR(Status); 210 211 Status = CommandInit(); 212 ASSERT_EFI_ERROR(Status); 213 214 // 215 // parse the command line 216 // 217 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE); 218 if (EFI_ERROR(Status)) { 219 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) { 220 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDriver1HiiHandle, L"drivers", ProblemParam); 221 FreePool(ProblemParam); 222 ShellStatus = SHELL_INVALID_PARAMETER; 223 } else { 224 ASSERT(FALSE); 225 } 226 } else { 227 if (ShellCommandLineGetCount(Package) > 1) { 228 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDriver1HiiHandle, L"drivers"); 229 ShellStatus = SHELL_INVALID_PARAMETER; 230 } else { 231 if (ShellCommandLineGetFlag(Package, L"-l")){ 232 Lang = ShellCommandLineGetValue(Package, L"-l"); 233 if (Lang != NULL) { 234 Language = AllocateZeroPool(StrSize(Lang)); 235 AsciiSPrint(Language, StrSize(Lang), "%S", Lang); 236 } else { 237 ASSERT(Language == NULL); 238 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"drivers", L"-l"); 239 ShellCommandLineFreeVarList (Package); 240 return (SHELL_INVALID_PARAMETER); 241 } 242 } 243 244 if (ShellCommandLineGetFlag (Package, L"-sfo")) { 245 SfoFlag = TRUE; 246 FormatString = HiiGetString (gShellDriver1HiiHandle, STRING_TOKEN (STR_DRIVERS_ITEM_LINE_SFO), Language); 247 // 248 // print the SFO header 249 // 250 ShellPrintHiiEx ( 251 -1, 252 -1, 253 Language, 254 STRING_TOKEN (STR_GEN_SFO_HEADER), 255 gShellDriver1HiiHandle, 256 L"drivers"); 257 } else { 258 FormatString = HiiGetString (gShellDriver1HiiHandle, STRING_TOKEN (STR_DRIVERS_ITEM_LINE), Language); 259 // 260 // print the header row 261 // 262 ShellPrintHiiEx( 263 -1, 264 -1, 265 Language, 266 STRING_TOKEN (STR_DRIVERS_HEADER_LINES), 267 gShellDriver1HiiHandle); 268 } 269 270 HandleList = GetHandleListByProtocol(&gEfiDriverBindingProtocolGuid); 271 for (HandleWalker = HandleList ; HandleWalker != NULL && *HandleWalker != NULL ; HandleWalker++){ 272 ChildCount = 0; 273 DeviceCount = 0; 274 Status = ParseHandleDatabaseForChildDevices (*HandleWalker, &ChildCount , NULL); 275 Status = PARSE_HANDLE_DATABASE_DEVICES (*HandleWalker, &DeviceCount, NULL); 276 Temp2 = GetDevicePathTextForHandle(*HandleWalker); 277 DriverVersion = ReturnDriverVersion(*HandleWalker); 278 DriverConfig = ReturnDriverConfig(*HandleWalker); 279 DriverDiag = ReturnDriverDiag (*HandleWalker); 280 FullDriverName = GetStringNameFromHandle(*HandleWalker, Language); 281 282 TruncatedDriverName = NULL; 283 if (!SfoFlag && (FullDriverName != NULL)) { 284 TruncatedDriverName = AllocateZeroPool ((MAX_LEN_DRIVER_NAME + 1) * sizeof (CHAR16)); 285 StrnCpyS (TruncatedDriverName, MAX_LEN_DRIVER_NAME + 1, FullDriverName, MAX_LEN_DRIVER_NAME); 286 } 287 288 ShellPrintEx( 289 -1, 290 -1, 291 FormatString, 292 ConvertHandleToHandleIndex(*HandleWalker), 293 DriverVersion, 294 ChildCount > 0?L'B':(DeviceCount > 0?L'D':L'?'), 295 DriverConfig?L'Y':L'N', 296 DriverDiag?L'Y':L'N', 297 DeviceCount, 298 ChildCount, 299 SfoFlag?FullDriverName:TruncatedDriverName, 300 Temp2==NULL?L"":Temp2 301 ); 302 if (TruncatedDriverName != NULL) { 303 FreePool (TruncatedDriverName); 304 } 305 if (Temp2 != NULL) { 306 FreePool(Temp2); 307 } 308 309 if (ShellGetExecutionBreakFlag ()) { 310 ShellStatus = SHELL_ABORTED; 311 break; 312 } 313 } 314 } 315 SHELL_FREE_NON_NULL(Language); 316 ShellCommandLineFreeVarList (Package); 317 SHELL_FREE_NON_NULL(FormatString); 318 } 319 320 return (ShellStatus); 321 } 322