Drivers.c 13 KB

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