]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellLevel2CommandsLib/Load.c
pointer verification (not NULL) and buffer overrun fixes.
[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
84 EFI_DEVICE_PATH_PROTOCOL *Node;\r
85 EFI_DEVICE_PATH_PROTOCOL *FilePath;\r
86 EFI_LOADED_IMAGE_PROTOCOL *LoadedDriverImage;\r
87\r
88 LoadedDriverImage = NULL;\r
89 FilePath = NULL;\r
90 Node = NULL;\r
91 LoadedDriverHandle = NULL;\r
92 Status = EFI_SUCCESS;\r
93\r
94 ASSERT (FileName != NULL);\r
95\r
96 //\r
97 // Fix local copies of the protocol pointers\r
98 //\r
99 Status = CommandInit();\r
100 ASSERT_EFI_ERROR(Status);\r
101\r
102 //\r
103 // Convert to DEVICE_PATH\r
104 //\r
105 FilePath = gEfiShellProtocol->GetDevicePathFromFilePath(FileName);\r
106\r
107 if (FilePath == NULL) {\r
108 ASSERT(FALSE);\r
109 return (EFI_INVALID_PARAMETER);\r
110 }\r
111\r
112 //\r
113 // Use LoadImage to get it into memory\r
114 //\r
115 Status = gBS->LoadImage(\r
116 FALSE,\r
117 gImageHandle,\r
118 FilePath,\r
119 NULL,\r
120 0,\r
121 &LoadedDriverHandle);\r
122\r
123 if (EFI_ERROR(Status)) {\r
124 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_LOAD_NOT_IMAGE), gShellLevel2HiiHandle, FileName, Status);\r
125 } else {\r
126 //\r
127 // Make sure it is a driver image\r
128 //\r
129 Status = gBS->HandleProtocol (LoadedDriverHandle, &gEfiLoadedImageProtocolGuid, (VOID *) &LoadedDriverImage);\r
130\r
131 ASSERT (LoadedDriverImage != NULL);\r
132\r
133 if ( EFI_ERROR(Status)\r
134 || ( LoadedDriverImage->ImageCodeType != EfiBootServicesCode\r
135 && LoadedDriverImage->ImageCodeType != EfiRuntimeServicesCode)\r
136 ){\r
137 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_LOAD_NOT_DRIVER), gShellLevel2HiiHandle, FileName);\r
138\r
139 //\r
140 // Exit and unload the non-driver image\r
141 //\r
142 gBS->Exit(LoadedDriverHandle, EFI_INVALID_PARAMETER, 0, NULL);\r
143 Status = EFI_INVALID_PARAMETER;\r
144 }\r
145 }\r
146\r
147 if (!EFI_ERROR(Status)) {\r
148 //\r
149 // Start the image\r
150 //\r
151 Status = gBS->StartImage(LoadedDriverHandle, NULL, NULL);\r
152 if (EFI_ERROR(Status)) {\r
153 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_LOAD_ERROR), gShellLevel2HiiHandle, FileName, Status);\r
154 } else {\r
155 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_LOAD_LOADED), gShellLevel2HiiHandle, FileName, LoadedDriverImage->ImageBase, Status);\r
156 }\r
157 }\r
158\r
159 if (!EFI_ERROR(Status) && Connect) {\r
160 //\r
161 // Connect it...\r
162 //\r
163 Status = ConnectAllEfi();\r
164 }\r
165\r
166 //\r
167 // clean up memory...\r
168 //\r
169 if (FilePath != NULL) {\r
170 FreePool(FilePath);\r
171 }\r
172\r
173 return (Status);\r
174}\r
175\r
176STATIC CONST SHELL_PARAM_ITEM LoadParamList[] = {\r
177 {L"-nc", TypeFlag},\r
178 {NULL, TypeMax}\r
179 };\r
180\r
181/**\r
182 Function for 'load' command.\r
183\r
184 @param[in] ImageHandle Handle to the Image (NULL if Internal).\r
185 @param[in] SystemTable Pointer to the System Table (NULL if Internal).\r
186**/\r
187SHELL_STATUS\r
188EFIAPI\r
189ShellCommandRunLoad (\r
190 IN EFI_HANDLE ImageHandle,\r
191 IN EFI_SYSTEM_TABLE *SystemTable\r
192 )\r
193{\r
194 EFI_STATUS Status;\r
195 LIST_ENTRY *Package;\r
196 CHAR16 *ProblemParam;\r
197 SHELL_STATUS ShellStatus;\r
198 UINTN ParamCount;\r
199 EFI_SHELL_FILE_INFO *ListHead;\r
200 EFI_SHELL_FILE_INFO *Node;\r
201\r
202 ListHead = NULL;\r
203 ProblemParam = NULL;\r
204 ShellStatus = SHELL_SUCCESS;\r
205\r
206 //\r
207 // initialize the shell lib (we must be in non-auto-init...)\r
208 //\r
209 Status = ShellInitialize();\r
210 ASSERT_EFI_ERROR(Status);\r
211\r
212 //\r
213 // parse the command line\r
214 //\r
215 Status = ShellCommandLineParse (LoadParamList, &Package, &ProblemParam, TRUE);\r
216 if (EFI_ERROR(Status)) {\r
217 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {\r
218 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, ProblemParam);\r
219 FreePool(ProblemParam);\r
220 ShellStatus = SHELL_INVALID_PARAMETER;\r
221 } else {\r
222 ASSERT(FALSE);\r
223 }\r
224 } else {\r
225 //\r
226 // check for "-?"\r
227 //\r
228 if (ShellCommandLineGetFlag(Package, L"-?")) {\r
229 ASSERT(FALSE);\r
230 } else if (ShellCommandLineGetRawValue(Package, 1) == NULL) {\r
231 //\r
232 // we didnt get a single file to load parameter\r
233 //\r
234 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel2HiiHandle);\r
235 ShellStatus = SHELL_INVALID_PARAMETER;\r
236 } else {\r
237 for ( ParamCount = 1\r
238 ; ShellCommandLineGetRawValue(Package, ParamCount) != NULL\r
239 ; ParamCount++\r
240 ){\r
241 Status = ShellOpenFileMetaArg((CHAR16*)ShellCommandLineGetRawValue(Package, ParamCount), EFI_FILE_MODE_READ, &ListHead);\r
242 if (!EFI_ERROR(Status)) {\r
243 for ( Node = (EFI_SHELL_FILE_INFO *)GetFirstNode(&ListHead->Link)\r
244 ; !IsNull(&ListHead->Link, &Node->Link)\r
245 ; Node = (EFI_SHELL_FILE_INFO *)GetNextNode(&ListHead->Link, &Node->Link)\r
246 ){\r
247 //\r
248 // once we have an error preserve that value, but finish the loop.\r
249 //\r
250 if (EFI_ERROR(Status)) {\r
b54fd049 251 LoadDriver(Node->FullName, (BOOLEAN)(ShellCommandLineGetFlag(Package, L"-nc")==FALSE));\r
a405b86d 252 } else {\r
b54fd049 253 Status = LoadDriver(Node->FullName, (BOOLEAN)(ShellCommandLineGetFlag(Package, L"-nc")==FALSE));\r
a405b86d 254 }\r
255 } // for loop for multi-open\r
256 if (EFI_ERROR(Status)) {\r
257 ShellCloseFileMetaArg(&ListHead);\r
258 } else {\r
259 Status = ShellCloseFileMetaArg(&ListHead);;\r
260 }\r
261 } else {\r
262 //\r
263 // no files found.\r
264 //\r
265 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_NF), gShellLevel2HiiHandle, (CHAR16*)ShellCommandLineGetRawValue(Package, ParamCount));\r
266 ShellStatus = SHELL_NOT_FOUND;\r
267 }\r
268 } // for loop for params\r
269 }\r
270\r
271 //\r
272 // free the command line package\r
273 //\r
274 ShellCommandLineFreeVarList (Package);\r
275 }\r
276\r
277 if (EFI_ERROR(Status) && ShellStatus == SHELL_SUCCESS) {\r
278 ShellStatus = SHELL_DEVICE_ERROR;\r
279 }\r
280\r
281 return (ShellStatus);\r
282}\r