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