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
17 This function will connect all current system handles recursively. The
18 connection will finish until every handle's child handle created if it have.
20 @retval EFI_SUCCESS All handles and it's child handle have been
22 @retval EFI_STATUS Return the status of gBS->LocateHandleBuffer().
32 EFI_HANDLE
*HandleBuffer
;
35 Status
= gBS
->LocateHandleBuffer (
42 if (EFI_ERROR (Status
)) {
46 for (Index
= 0; Index
< HandleCount
; Index
++) {
47 Status
= gBS
->ConnectController (HandleBuffer
[Index
], NULL
, NULL
, TRUE
);
50 if (HandleBuffer
!= NULL
) {
51 FreePool (HandleBuffer
);
58 function to load a .EFI driver into memory and possible connect the driver.
60 if FileName is NULL then ASSERT.
62 @param[in] FileName FileName of the driver to load
63 @param[in] Connect Whether to connect or not
65 @retval EFI_SUCCESS the driver was loaded and if Connect was
66 true then connect was attempted. Connection may
68 @retval EFI_OUT_OF_RESOURCES there was insufficient memory
72 IN CONST CHAR16
*FileName
,
73 IN CONST BOOLEAN Connect
76 EFI_HANDLE LoadedDriverHandle
;
78 EFI_DEVICE_PATH_PROTOCOL
*FilePath
;
79 EFI_LOADED_IMAGE_PROTOCOL
*LoadedDriverImage
;
81 LoadedDriverImage
= NULL
;
83 LoadedDriverHandle
= NULL
;
86 ASSERT (FileName
!= NULL
);
89 // Fix local copies of the protocol pointers
91 Status
= CommandInit ();
92 ASSERT_EFI_ERROR (Status
);
95 // Convert to DEVICE_PATH
97 FilePath
= gEfiShellProtocol
->GetDevicePathFromFilePath (FileName
);
99 if (FilePath
== NULL
) {
101 return (EFI_INVALID_PARAMETER
);
105 // Use LoadImage to get it into memory
107 Status
= gBS
->LoadImage (
116 if (EFI_ERROR (Status
)) {
118 // With EFI_SECURITY_VIOLATION retval, the Image was loaded and an ImageHandle was created
119 // with a valid EFI_LOADED_IMAGE_PROTOCOL, but the image can not be started right now.
120 // If the caller doesn't have the option to defer the execution of an image, we should
121 // unload image for the EFI_SECURITY_VIOLATION to avoid resource leak.
123 if (Status
== EFI_SECURITY_VIOLATION
) {
124 gBS
->UnloadImage (LoadedDriverHandle
);
127 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_LOAD_NOT_IMAGE
), gShellLevel2HiiHandle
, FileName
, Status
);
130 // Make sure it is a driver image
132 Status
= gBS
->HandleProtocol (LoadedDriverHandle
, &gEfiLoadedImageProtocolGuid
, (VOID
*)&LoadedDriverImage
);
134 ASSERT (LoadedDriverImage
!= NULL
);
136 if ( EFI_ERROR (Status
)
137 || ( (LoadedDriverImage
->ImageCodeType
!= EfiBootServicesCode
)
138 && (LoadedDriverImage
->ImageCodeType
!= EfiRuntimeServicesCode
))
141 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_LOAD_NOT_DRIVER
), gShellLevel2HiiHandle
, FileName
);
144 // Exit and unload the non-driver image
146 gBS
->Exit (LoadedDriverHandle
, EFI_INVALID_PARAMETER
, 0, NULL
);
147 Status
= EFI_INVALID_PARAMETER
;
151 if (!EFI_ERROR (Status
)) {
155 Status
= gBS
->StartImage (LoadedDriverHandle
, NULL
, NULL
);
156 if (EFI_ERROR (Status
)) {
157 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_LOAD_ERROR
), gShellLevel2HiiHandle
, FileName
, Status
);
159 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_LOAD_LOADED
), gShellLevel2HiiHandle
, FileName
, LoadedDriverImage
->ImageBase
, Status
);
163 if (!EFI_ERROR (Status
) && Connect
) {
167 Status
= ConnectAllEfi ();
171 // clean up memory...
173 if (FilePath
!= NULL
) {
180 STATIC CONST SHELL_PARAM_ITEM LoadParamList
[] = {
181 { L
"-nc", TypeFlag
},
186 Function for 'load' command.
188 @param[in] ImageHandle Handle to the Image (NULL if Internal).
189 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
193 ShellCommandRunLoad (
194 IN EFI_HANDLE ImageHandle
,
195 IN EFI_SYSTEM_TABLE
*SystemTable
200 CHAR16
*ProblemParam
;
201 SHELL_STATUS ShellStatus
;
203 EFI_SHELL_FILE_INFO
*ListHead
;
204 EFI_SHELL_FILE_INFO
*Node
;
208 ShellStatus
= SHELL_SUCCESS
;
211 // initialize the shell lib (we must be in non-auto-init...)
213 Status
= ShellInitialize ();
214 ASSERT_EFI_ERROR (Status
);
217 // parse the command line
219 Status
= ShellCommandLineParse (LoadParamList
, &Package
, &ProblemParam
, TRUE
);
220 if (EFI_ERROR (Status
)) {
221 if ((Status
== EFI_VOLUME_CORRUPTED
) && (ProblemParam
!= NULL
)) {
222 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellLevel2HiiHandle
, L
"load", ProblemParam
);
223 FreePool (ProblemParam
);
224 ShellStatus
= SHELL_INVALID_PARAMETER
;
232 if (ShellCommandLineGetFlag (Package
, L
"-?")) {
234 } else if (ShellCommandLineGetRawValue (Package
, 1) == NULL
) {
236 // we didnt get a single file to load parameter
238 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellLevel2HiiHandle
, L
"load");
239 ShellStatus
= SHELL_INVALID_PARAMETER
;
242 ; ShellCommandLineGetRawValue (Package
, ParamCount
) != NULL
246 Status
= ShellOpenFileMetaArg ((CHAR16
*)ShellCommandLineGetRawValue (Package
, ParamCount
), EFI_FILE_MODE_READ
, &ListHead
);
247 if (!EFI_ERROR (Status
)) {
248 for ( Node
= (EFI_SHELL_FILE_INFO
*)GetFirstNode (&ListHead
->Link
)
249 ; !IsNull (&ListHead
->Link
, &Node
->Link
)
250 ; Node
= (EFI_SHELL_FILE_INFO
*)GetNextNode (&ListHead
->Link
, &Node
->Link
)
254 // once we have an error preserve that value, but finish the loop.
256 if (EFI_ERROR (Status
)) {
257 LoadDriver (Node
->FullName
, (BOOLEAN
)(ShellCommandLineGetFlag (Package
, L
"-nc") == FALSE
));
259 Status
= LoadDriver (Node
->FullName
, (BOOLEAN
)(ShellCommandLineGetFlag (Package
, L
"-nc") == FALSE
));
261 } // for loop for multi-open
263 if (EFI_ERROR (Status
)) {
264 ShellCloseFileMetaArg (&ListHead
);
266 Status
= ShellCloseFileMetaArg (&ListHead
);
272 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_NF
), gShellLevel2HiiHandle
, L
"load", (CHAR16
*)ShellCommandLineGetRawValue (Package
, ParamCount
));
273 ShellStatus
= SHELL_NOT_FOUND
;
275 } // for loop for params
279 // free the command line package
281 ShellCommandLineFreeVarList (Package
);
284 if (EFI_ERROR (Status
) && (ShellStatus
== SHELL_SUCCESS
)) {
285 ShellStatus
= SHELL_DEVICE_ERROR
;
288 return (ShellStatus
);