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