]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellLevel2CommandsLib/Load.c
ShellPkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / ShellPkg / Library / UefiShellLevel2CommandsLib / Load.c
CommitLineData
a405b86d 1/** @file\r
2 Main file for attrib shell level 2 function.\r
3\r
c011b6c9 4 (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>\r
ba0014b9 5 Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>\r
56ba3746 6 SPDX-License-Identifier: BSD-2-Clause-Patent\r
a405b86d 7\r
8**/\r
9\r
10#include "UefiShellLevel2CommandsLib.h"\r
11\r
12// This function was from from the BdsLib implementation in\r
13// IntelFrameworkModulePkg\Library\GenericBdsLib\BdsConnect.c\r
14// function name: BdsLibConnectAllEfi\r
15/**\r
16 This function will connect all current system handles recursively. The\r
17 connection will finish until every handle's child handle created if it have.\r
18\r
19 @retval EFI_SUCCESS All handles and it's child handle have been\r
20 connected\r
21 @retval EFI_STATUS Return the status of gBS->LocateHandleBuffer().\r
22\r
23**/\r
24EFI_STATUS\r
a405b86d 25ConnectAllEfi (\r
26 VOID\r
27 )\r
28{\r
29 EFI_STATUS Status;\r
30 UINTN HandleCount;\r
31 EFI_HANDLE *HandleBuffer;\r
32 UINTN Index;\r
33\r
34 Status = gBS->LocateHandleBuffer (\r
35 AllHandles,\r
36 NULL,\r
37 NULL,\r
38 &HandleCount,\r
39 &HandleBuffer\r
40 );\r
41 if (EFI_ERROR (Status)) {\r
42 return Status;\r
43 }\r
44\r
45 for (Index = 0; Index < HandleCount; Index++) {\r
46 Status = gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE);\r
47 }\r
48\r
49 if (HandleBuffer != NULL) {\r
50 FreePool (HandleBuffer);\r
51 }\r
52\r
53 return EFI_SUCCESS;\r
54}\r
55\r
56/**\r
57 function to load a .EFI driver into memory and possible connect the driver.\r
58\r
59 if FileName is NULL then ASSERT.\r
60\r
61 @param[in] FileName FileName of the driver to load\r
62 @param[in] Connect Whether to connect or not\r
63\r
64 @retval EFI_SUCCESS the driver was loaded and if Connect was\r
65 true then connect was attempted. Connection may\r
66 have failed.\r
67 @retval EFI_OUT_OF_RESOURCES there was insufficient memory\r
68**/\r
69EFI_STATUS\r
a405b86d 70LoadDriver(\r
71 IN CONST CHAR16 *FileName,\r
72 IN CONST BOOLEAN Connect\r
73 )\r
74{\r
75 EFI_HANDLE LoadedDriverHandle;\r
76 EFI_STATUS Status;\r
a405b86d 77 EFI_DEVICE_PATH_PROTOCOL *FilePath;\r
78 EFI_LOADED_IMAGE_PROTOCOL *LoadedDriverImage;\r
79\r
80 LoadedDriverImage = NULL;\r
81 FilePath = NULL;\r
a405b86d 82 LoadedDriverHandle = NULL;\r
83 Status = EFI_SUCCESS;\r
84\r
85 ASSERT (FileName != NULL);\r
86\r
87 //\r
88 // Fix local copies of the protocol pointers\r
89 //\r
90 Status = CommandInit();\r
91 ASSERT_EFI_ERROR(Status);\r
92\r
93 //\r
94 // Convert to DEVICE_PATH\r
95 //\r
96 FilePath = gEfiShellProtocol->GetDevicePathFromFilePath(FileName);\r
97\r
98 if (FilePath == NULL) {\r
99 ASSERT(FALSE);\r
100 return (EFI_INVALID_PARAMETER);\r
101 }\r
102\r
103 //\r
104 // Use LoadImage to get it into memory\r
105 //\r
106 Status = gBS->LoadImage(\r
107 FALSE,\r
108 gImageHandle,\r
109 FilePath,\r
110 NULL,\r
111 0,\r
112 &LoadedDriverHandle);\r
113\r
114 if (EFI_ERROR(Status)) {\r
115 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_LOAD_NOT_IMAGE), gShellLevel2HiiHandle, FileName, Status);\r
116 } else {\r
117 //\r
118 // Make sure it is a driver image\r
119 //\r
120 Status = gBS->HandleProtocol (LoadedDriverHandle, &gEfiLoadedImageProtocolGuid, (VOID *) &LoadedDriverImage);\r
121\r
122 ASSERT (LoadedDriverImage != NULL);\r
123\r
124 if ( EFI_ERROR(Status)\r
125 || ( LoadedDriverImage->ImageCodeType != EfiBootServicesCode\r
126 && LoadedDriverImage->ImageCodeType != EfiRuntimeServicesCode)\r
127 ){\r
128 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_LOAD_NOT_DRIVER), gShellLevel2HiiHandle, FileName);\r
129\r
130 //\r
131 // Exit and unload the non-driver image\r
132 //\r
133 gBS->Exit(LoadedDriverHandle, EFI_INVALID_PARAMETER, 0, NULL);\r
134 Status = EFI_INVALID_PARAMETER;\r
135 }\r
136 }\r
137\r
138 if (!EFI_ERROR(Status)) {\r
139 //\r
140 // Start the image\r
141 //\r
142 Status = gBS->StartImage(LoadedDriverHandle, NULL, NULL);\r
143 if (EFI_ERROR(Status)) {\r
144 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_LOAD_ERROR), gShellLevel2HiiHandle, FileName, Status);\r
145 } else {\r
146 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_LOAD_LOADED), gShellLevel2HiiHandle, FileName, LoadedDriverImage->ImageBase, Status);\r
147 }\r
148 }\r
149\r
150 if (!EFI_ERROR(Status) && Connect) {\r
151 //\r
152 // Connect it...\r
153 //\r
154 Status = ConnectAllEfi();\r
155 }\r
156\r
157 //\r
158 // clean up memory...\r
159 //\r
160 if (FilePath != NULL) {\r
161 FreePool(FilePath);\r
162 }\r
163\r
164 return (Status);\r
165}\r
166\r
167STATIC CONST SHELL_PARAM_ITEM LoadParamList[] = {\r
168 {L"-nc", TypeFlag},\r
169 {NULL, TypeMax}\r
170 };\r
171\r
172/**\r
173 Function for 'load' command.\r
174\r
175 @param[in] ImageHandle Handle to the Image (NULL if Internal).\r
176 @param[in] SystemTable Pointer to the System Table (NULL if Internal).\r
177**/\r
178SHELL_STATUS\r
179EFIAPI\r
180ShellCommandRunLoad (\r
181 IN EFI_HANDLE ImageHandle,\r
182 IN EFI_SYSTEM_TABLE *SystemTable\r
183 )\r
184{\r
185 EFI_STATUS Status;\r
186 LIST_ENTRY *Package;\r
187 CHAR16 *ProblemParam;\r
188 SHELL_STATUS ShellStatus;\r
189 UINTN ParamCount;\r
190 EFI_SHELL_FILE_INFO *ListHead;\r
191 EFI_SHELL_FILE_INFO *Node;\r
192\r
193 ListHead = NULL;\r
194 ProblemParam = NULL;\r
195 ShellStatus = SHELL_SUCCESS;\r
196\r
197 //\r
198 // initialize the shell lib (we must be in non-auto-init...)\r
199 //\r
200 Status = ShellInitialize();\r
201 ASSERT_EFI_ERROR(Status);\r
202\r
203 //\r
204 // parse the command line\r
205 //\r
206 Status = ShellCommandLineParse (LoadParamList, &Package, &ProblemParam, TRUE);\r
207 if (EFI_ERROR(Status)) {\r
208 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {\r
ba0014b9 209 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"load", ProblemParam);\r
a405b86d 210 FreePool(ProblemParam);\r
211 ShellStatus = SHELL_INVALID_PARAMETER;\r
212 } else {\r
213 ASSERT(FALSE);\r
214 }\r
215 } else {\r
216 //\r
217 // check for "-?"\r
218 //\r
219 if (ShellCommandLineGetFlag(Package, L"-?")) {\r
220 ASSERT(FALSE);\r
221 } else if (ShellCommandLineGetRawValue(Package, 1) == NULL) {\r
222 //\r
223 // we didnt get a single file to load parameter\r
224 //\r
ba0014b9 225 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel2HiiHandle, L"load");\r
a405b86d 226 ShellStatus = SHELL_INVALID_PARAMETER;\r
227 } else {\r
228 for ( ParamCount = 1\r
229 ; ShellCommandLineGetRawValue(Package, ParamCount) != NULL\r
230 ; ParamCount++\r
231 ){\r
232 Status = ShellOpenFileMetaArg((CHAR16*)ShellCommandLineGetRawValue(Package, ParamCount), EFI_FILE_MODE_READ, &ListHead);\r
233 if (!EFI_ERROR(Status)) {\r
234 for ( Node = (EFI_SHELL_FILE_INFO *)GetFirstNode(&ListHead->Link)\r
235 ; !IsNull(&ListHead->Link, &Node->Link)\r
236 ; Node = (EFI_SHELL_FILE_INFO *)GetNextNode(&ListHead->Link, &Node->Link)\r
237 ){\r
238 //\r
239 // once we have an error preserve that value, but finish the loop.\r
240 //\r
241 if (EFI_ERROR(Status)) {\r
b54fd049 242 LoadDriver(Node->FullName, (BOOLEAN)(ShellCommandLineGetFlag(Package, L"-nc")==FALSE));\r
a405b86d 243 } else {\r
b54fd049 244 Status = LoadDriver(Node->FullName, (BOOLEAN)(ShellCommandLineGetFlag(Package, L"-nc")==FALSE));\r
a405b86d 245 }\r
246 } // for loop for multi-open\r
247 if (EFI_ERROR(Status)) {\r
248 ShellCloseFileMetaArg(&ListHead);\r
249 } else {\r
250 Status = ShellCloseFileMetaArg(&ListHead);;\r
251 }\r
252 } else {\r
253 //\r
254 // no files found.\r
255 //\r
ba0014b9 256 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_NF), gShellLevel2HiiHandle, L"load", (CHAR16*)ShellCommandLineGetRawValue(Package, ParamCount));\r
a405b86d 257 ShellStatus = SHELL_NOT_FOUND;\r
258 }\r
259 } // for loop for params\r
260 }\r
261\r
262 //\r
263 // free the command line package\r
264 //\r
265 ShellCommandLineFreeVarList (Package);\r
266 }\r
267\r
268 if (EFI_ERROR(Status) && ShellStatus == SHELL_SUCCESS) {\r
269 ShellStatus = SHELL_DEVICE_ERROR;\r
270 }\r
271\r
272 return (ShellStatus);\r
273}\r