2 Main file for attrib shell level 2 function.
4 (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
5 Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
10 #include "UefiShellLevel2CommandsLib.h"
12 // This function was from from the BdsLib implementation in
13 // IntelFrameworkModulePkg\Library\GenericBdsLib\BdsConnect.c
14 // function name: BdsLibConnectAllEfi
16 This function will connect all current system handles recursively. The
17 connection will finish until every handle's child handle created if it have.
19 @retval EFI_SUCCESS All handles and it's child handle have been
21 @retval EFI_STATUS Return the status of gBS->LocateHandleBuffer().
31 EFI_HANDLE
*HandleBuffer
;
34 Status
= gBS
->LocateHandleBuffer (
41 if (EFI_ERROR (Status
)) {
45 for (Index
= 0; Index
< HandleCount
; Index
++) {
46 Status
= gBS
->ConnectController (HandleBuffer
[Index
], NULL
, NULL
, TRUE
);
49 if (HandleBuffer
!= NULL
) {
50 FreePool (HandleBuffer
);
57 function to load a .EFI driver into memory and possible connect the driver.
59 if FileName is NULL then ASSERT.
61 @param[in] FileName FileName of the driver to load
62 @param[in] Connect Whether to connect or not
64 @retval EFI_SUCCESS the driver was loaded and if Connect was
65 true then connect was attempted. Connection may
67 @retval EFI_OUT_OF_RESOURCES there was insufficient memory
71 IN CONST CHAR16
*FileName
,
72 IN CONST BOOLEAN Connect
75 EFI_HANDLE LoadedDriverHandle
;
77 EFI_DEVICE_PATH_PROTOCOL
*FilePath
;
78 EFI_LOADED_IMAGE_PROTOCOL
*LoadedDriverImage
;
80 LoadedDriverImage
= NULL
;
82 LoadedDriverHandle
= NULL
;
85 ASSERT (FileName
!= NULL
);
88 // Fix local copies of the protocol pointers
90 Status
= CommandInit();
91 ASSERT_EFI_ERROR(Status
);
94 // Convert to DEVICE_PATH
96 FilePath
= gEfiShellProtocol
->GetDevicePathFromFilePath(FileName
);
98 if (FilePath
== NULL
) {
100 return (EFI_INVALID_PARAMETER
);
104 // Use LoadImage to get it into memory
106 Status
= gBS
->LoadImage(
112 &LoadedDriverHandle
);
114 if (EFI_ERROR(Status
)) {
116 // With EFI_SECURITY_VIOLATION retval, the Image was loaded and an ImageHandle was created
117 // with a valid EFI_LOADED_IMAGE_PROTOCOL, but the image can not be started right now.
118 // If the caller doesn't have the option to defer the execution of an image, we should
119 // unload image for the EFI_SECURITY_VIOLATION to avoid resource leak.
121 if (Status
== EFI_SECURITY_VIOLATION
) {
122 gBS
->UnloadImage (LoadedDriverHandle
);
124 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_LOAD_NOT_IMAGE
), gShellLevel2HiiHandle
, FileName
, Status
);
127 // Make sure it is a driver image
129 Status
= gBS
->HandleProtocol (LoadedDriverHandle
, &gEfiLoadedImageProtocolGuid
, (VOID
*) &LoadedDriverImage
);
131 ASSERT (LoadedDriverImage
!= NULL
);
133 if ( EFI_ERROR(Status
)
134 || ( LoadedDriverImage
->ImageCodeType
!= EfiBootServicesCode
135 && LoadedDriverImage
->ImageCodeType
!= EfiRuntimeServicesCode
)
137 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_LOAD_NOT_DRIVER
), gShellLevel2HiiHandle
, FileName
);
140 // Exit and unload the non-driver image
142 gBS
->Exit(LoadedDriverHandle
, EFI_INVALID_PARAMETER
, 0, NULL
);
143 Status
= EFI_INVALID_PARAMETER
;
147 if (!EFI_ERROR(Status
)) {
151 Status
= gBS
->StartImage(LoadedDriverHandle
, NULL
, NULL
);
152 if (EFI_ERROR(Status
)) {
153 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_LOAD_ERROR
), gShellLevel2HiiHandle
, FileName
, Status
);
155 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_LOAD_LOADED
), gShellLevel2HiiHandle
, FileName
, LoadedDriverImage
->ImageBase
, Status
);
159 if (!EFI_ERROR(Status
) && Connect
) {
163 Status
= ConnectAllEfi();
167 // clean up memory...
169 if (FilePath
!= NULL
) {
176 STATIC CONST SHELL_PARAM_ITEM LoadParamList
[] = {
182 Function for 'load' command.
184 @param[in] ImageHandle Handle to the Image (NULL if Internal).
185 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
189 ShellCommandRunLoad (
190 IN EFI_HANDLE ImageHandle
,
191 IN EFI_SYSTEM_TABLE
*SystemTable
196 CHAR16
*ProblemParam
;
197 SHELL_STATUS ShellStatus
;
199 EFI_SHELL_FILE_INFO
*ListHead
;
200 EFI_SHELL_FILE_INFO
*Node
;
204 ShellStatus
= SHELL_SUCCESS
;
207 // initialize the shell lib (we must be in non-auto-init...)
209 Status
= ShellInitialize();
210 ASSERT_EFI_ERROR(Status
);
213 // parse the command line
215 Status
= ShellCommandLineParse (LoadParamList
, &Package
, &ProblemParam
, TRUE
);
216 if (EFI_ERROR(Status
)) {
217 if (Status
== EFI_VOLUME_CORRUPTED
&& ProblemParam
!= NULL
) {
218 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellLevel2HiiHandle
, L
"load", ProblemParam
);
219 FreePool(ProblemParam
);
220 ShellStatus
= SHELL_INVALID_PARAMETER
;
228 if (ShellCommandLineGetFlag(Package
, L
"-?")) {
230 } else if (ShellCommandLineGetRawValue(Package
, 1) == NULL
) {
232 // we didnt get a single file to load parameter
234 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellLevel2HiiHandle
, L
"load");
235 ShellStatus
= SHELL_INVALID_PARAMETER
;
238 ; ShellCommandLineGetRawValue(Package
, ParamCount
) != NULL
241 Status
= ShellOpenFileMetaArg((CHAR16
*)ShellCommandLineGetRawValue(Package
, ParamCount
), EFI_FILE_MODE_READ
, &ListHead
);
242 if (!EFI_ERROR(Status
)) {
243 for ( Node
= (EFI_SHELL_FILE_INFO
*)GetFirstNode(&ListHead
->Link
)
244 ; !IsNull(&ListHead
->Link
, &Node
->Link
)
245 ; Node
= (EFI_SHELL_FILE_INFO
*)GetNextNode(&ListHead
->Link
, &Node
->Link
)
248 // once we have an error preserve that value, but finish the loop.
250 if (EFI_ERROR(Status
)) {
251 LoadDriver(Node
->FullName
, (BOOLEAN
)(ShellCommandLineGetFlag(Package
, L
"-nc")==FALSE
));
253 Status
= LoadDriver(Node
->FullName
, (BOOLEAN
)(ShellCommandLineGetFlag(Package
, L
"-nc")==FALSE
));
255 } // for loop for multi-open
256 if (EFI_ERROR(Status
)) {
257 ShellCloseFileMetaArg(&ListHead
);
259 Status
= ShellCloseFileMetaArg(&ListHead
);;
265 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_NF
), gShellLevel2HiiHandle
, L
"load", (CHAR16
*)ShellCommandLineGetRawValue(Package
, ParamCount
));
266 ShellStatus
= SHELL_NOT_FOUND
;
268 } // for loop for params
272 // free the command line package
274 ShellCommandLineFreeVarList (Package
);
277 if (EFI_ERROR(Status
) && ShellStatus
== SHELL_SUCCESS
) {
278 ShellStatus
= SHELL_DEVICE_ERROR
;
281 return (ShellStatus
);