]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - ShellPkg/Library/BaseShellLib/BaseShellLib.c
fixed to build under IPF.
[mirror_edk2.git] / ShellPkg / Library / BaseShellLib / BaseShellLib.c
... / ...
CommitLineData
1/** @file\r
2 Provides interface to shell functionality for shell commands and applications.\r
3\r
4Copyright (c) 2006 - 2009, Intel Corporation\r
5All rights reserved. This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include <Uefi.h>\r
16#include <Library/ShellLib.h>\r
17#include <Library/UefiBootServicesTableLib.h>\r
18#include <Library/BaseLib.h>\r
19#include <Library/BaseMemoryLib.h>\r
20#include <Library/DebugLib.h>\r
21#include <Library/MemoryAllocationLib.h>\r
22#include <Library/DevicePathLib.h>\r
23#include <Library/PcdLib.h>\r
24#include <Library/FileHandleLib.h>\r
25#include <Protocol/EfiShellEnvironment2.h>\r
26#include <Protocol/EfiShellInterface.h>\r
27#include <Protocol/EfiShell.h>\r
28#include <Protocol/EfiShellParameters.h>\r
29#include <Protocol/SimpleFileSystem.h>\r
30\r
31#include "BaseShellLib.h"\r
32\r
33#define MAX_FILE_NAME_LEN 522 // (20 * (6+5+2))+1) unicode characters from EFI FAT spec (doubled for bytes)\r
34#define FIND_XXXXX_FILE_BUFFER_SIZE (SIZE_OF_EFI_FILE_INFO + MAX_FILE_NAME_LEN)\r
35\r
36//\r
37// This is not static since it's extern in the .h file\r
38//\r
39SHELL_PARAM_ITEM EmptyParamList[] = {\r
40 {NULL, TypeMax}\r
41 };\r
42\r
43//\r
44// Static file globals for the shell library\r
45//\r
46STATIC EFI_SHELL_ENVIRONMENT2 *mEfiShellEnvironment2;\r
47STATIC EFI_SHELL_INTERFACE *mEfiShellInterface;\r
48STATIC EFI_SHELL_PROTOCOL *mEfiShellProtocol;\r
49STATIC EFI_SHELL_PARAMETERS_PROTOCOL *mEfiShellParametersProtocol;\r
50STATIC EFI_HANDLE mEfiShellEnvironment2Handle;\r
51STATIC FILE_HANDLE_FUNCTION_MAP FileFunctionMap;\r
52\r
53/**\r
54 helper function to find ShellEnvironment2 for constructor\r
55**/\r
56EFI_STATUS\r
57EFIAPI\r
58ShellFindSE2 (\r
59 IN EFI_HANDLE ImageHandle\r
60 )\r
61{\r
62 EFI_STATUS Status;\r
63 EFI_HANDLE *Buffer;\r
64 UINTN BufferSize;\r
65 UINTN HandleIndex;\r
66\r
67 BufferSize = 0;\r
68 Buffer = NULL;\r
69 Status = gBS->OpenProtocol(ImageHandle, \r
70 &gEfiShellEnvironment2Guid,\r
71 (VOID **)&mEfiShellEnvironment2,\r
72 ImageHandle,\r
73 NULL,\r
74 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
75 );\r
76 //\r
77 // look for the mEfiShellEnvironment2 protocol at a higher level\r
78 //\r
79 if (EFI_ERROR (Status) || !(CompareGuid (&mEfiShellEnvironment2->SESGuid, &gEfiShellEnvironment2ExtGuid) != FALSE &&\r
80 (mEfiShellEnvironment2->MajorVersion > EFI_SHELL_MAJOR_VER ||\r
81 (mEfiShellEnvironment2->MajorVersion == EFI_SHELL_MAJOR_VER && mEfiShellEnvironment2->MinorVersion >= EFI_SHELL_MINOR_VER)))) {\r
82 //\r
83 // figure out how big of a buffer we need.\r
84 //\r
85 Status = gBS->LocateHandle (ByProtocol,\r
86 &gEfiShellEnvironment2Guid,\r
87 NULL, // ignored for ByProtocol\r
88 &BufferSize,\r
89 Buffer\r
90 );\r
91 ASSERT(Status == EFI_BUFFER_TOO_SMALL);\r
92 Buffer = (EFI_HANDLE*)AllocatePool(BufferSize);\r
93 ASSERT(Buffer != NULL);\r
94 Status = gBS->LocateHandle (ByProtocol,\r
95 &gEfiShellEnvironment2Guid,\r
96 NULL, // ignored for ByProtocol\r
97 &BufferSize,\r
98 Buffer\r
99 );\r
100 if (!EFI_ERROR (Status)) {\r
101 //\r
102 // now parse the list of returned handles\r
103 //\r
104 Status = EFI_NOT_FOUND;\r
105 for (HandleIndex = 0; HandleIndex < (BufferSize/sizeof(Buffer[0])); HandleIndex++) {\r
106 Status = gBS->OpenProtocol(Buffer[HandleIndex], \r
107 &gEfiShellEnvironment2Guid,\r
108 (VOID **)&mEfiShellEnvironment2,\r
109 ImageHandle,\r
110 NULL,\r
111 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
112 );\r
113 if (CompareGuid (&mEfiShellEnvironment2->SESGuid, &gEfiShellEnvironment2ExtGuid) != FALSE &&\r
114 (mEfiShellEnvironment2->MajorVersion > EFI_SHELL_MAJOR_VER ||\r
115 (mEfiShellEnvironment2->MajorVersion == EFI_SHELL_MAJOR_VER && mEfiShellEnvironment2->MinorVersion >= EFI_SHELL_MINOR_VER))) {\r
116 mEfiShellEnvironment2Handle = Buffer[HandleIndex];\r
117 Status = EFI_SUCCESS;\r
118 break;\r
119 }\r
120 }\r
121 }\r
122 }\r
123 if (Buffer != NULL) {\r
124 FreePool (Buffer);\r
125 }\r
126 return (Status);\r
127}\r
128\r
129EFI_STATUS\r
130EFIAPI\r
131ShellLibConstructorWorker (\r
132 IN EFI_HANDLE ImageHandle,\r
133 IN EFI_SYSTEM_TABLE *SystemTable\r
134){\r
135 EFI_STATUS Status;\r
136\r
137 //\r
138 // UEFI 2.0 shell interfaces (used preferentially)\r
139 //\r
140 Status = gBS->OpenProtocol(ImageHandle, \r
141 &gEfiShellProtocolGuid,\r
142 (VOID **)&mEfiShellProtocol,\r
143 ImageHandle,\r
144 NULL,\r
145 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
146 );\r
147 if (EFI_ERROR(Status)) {\r
148 mEfiShellProtocol = NULL;\r
149 }\r
150 Status = gBS->OpenProtocol(ImageHandle, \r
151 &gEfiShellParametersProtocolGuid,\r
152 (VOID **)&mEfiShellParametersProtocol,\r
153 ImageHandle,\r
154 NULL,\r
155 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
156 );\r
157 if (EFI_ERROR(Status)) {\r
158 mEfiShellParametersProtocol = NULL;\r
159 }\r
160\r
161 if (mEfiShellParametersProtocol == NULL || mEfiShellProtocol == NULL) {\r
162 //\r
163 // Moved to seperate function due to complexity\r
164 //\r
165 Status = ShellFindSE2(ImageHandle);\r
166\r
167 if (EFI_ERROR(Status)) {\r
168 DEBUG((DEBUG_ERROR, "Status: 0x%08x\r\n", Status));\r
169 mEfiShellEnvironment2 = NULL;\r
170 }\r
171 Status = gBS->OpenProtocol(ImageHandle, \r
172 &gEfiShellInterfaceGuid,\r
173 (VOID **)&mEfiShellInterface,\r
174 ImageHandle,\r
175 NULL,\r
176 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
177 );\r
178 if (EFI_ERROR(Status)) {\r
179 mEfiShellInterface = NULL;\r
180 }\r
181 }\r
182 //\r
183 // only success getting 2 of either the old or new, but no 1/2 and 1/2\r
184 //\r
185 if ((mEfiShellEnvironment2 != NULL && mEfiShellInterface != NULL) || \r
186 (mEfiShellProtocol != NULL && mEfiShellParametersProtocol != NULL) ) {\r
187 if (mEfiShellProtocol != NULL) {\r
188 FileFunctionMap.GetFileInfo = mEfiShellProtocol->GetFileInfo;\r
189 FileFunctionMap.SetFileInfo = mEfiShellProtocol->SetFileInfo;\r
190 FileFunctionMap.ReadFile = mEfiShellProtocol->ReadFile;\r
191 FileFunctionMap.WriteFile = mEfiShellProtocol->WriteFile;\r
192 FileFunctionMap.CloseFile = mEfiShellProtocol->CloseFile;\r
193 FileFunctionMap.DeleteFile = mEfiShellProtocol->DeleteFile;\r
194 FileFunctionMap.GetFilePosition = mEfiShellProtocol->GetFilePosition;\r
195 FileFunctionMap.SetFilePosition = mEfiShellProtocol->SetFilePosition;\r
196 FileFunctionMap.FlushFile = mEfiShellProtocol->FlushFile;\r
197 FileFunctionMap.GetFileSize = mEfiShellProtocol->GetFileSize;\r
198 } else {\r
199 FileFunctionMap.GetFileInfo = FileHandleGetInfo;\r
200 FileFunctionMap.SetFileInfo = FileHandleSetInfo;\r
201 FileFunctionMap.ReadFile = FileHandleRead;\r
202 FileFunctionMap.WriteFile = FileHandleWrite;\r
203 FileFunctionMap.CloseFile = FileHandleClose;\r
204 FileFunctionMap.DeleteFile = FileHandleDelete;\r
205 FileFunctionMap.GetFilePosition = FileHandleGetPosition;\r
206 FileFunctionMap.SetFilePosition = FileHandleSetPosition;\r
207 FileFunctionMap.FlushFile = FileHandleFlush;\r
208 FileFunctionMap.GetFileSize = FileHandleGetSize;\r
209 }\r
210 return (EFI_SUCCESS);\r
211 }\r
212 return (EFI_NOT_FOUND);\r
213}\r
214/**\r
215 Constructor for the Shell library.\r
216\r
217 Initialize the library and determine if the underlying is a UEFI Shell 2.0 or an EFI shell.\r
218\r
219 @param ImageHandle the image handle of the process\r
220 @param SystemTable the EFI System Table pointer\r
221\r
222 @retval EFI_SUCCESS the initialization was complete sucessfully\r
223 @return others an error ocurred during initialization\r
224**/\r
225EFI_STATUS\r
226EFIAPI\r
227ShellLibConstructor (\r
228 IN EFI_HANDLE ImageHandle,\r
229 IN EFI_SYSTEM_TABLE *SystemTable\r
230 )\r
231{\r
232\r
233\r
234 mEfiShellEnvironment2 = NULL;\r
235 mEfiShellProtocol = NULL;\r
236 mEfiShellParametersProtocol = NULL;\r
237 mEfiShellInterface = NULL;\r
238 mEfiShellEnvironment2Handle = NULL;\r
239\r
240 ///@todo make a worker constructor so initialize function works\r
241 //\r
242 // verify that auto initialize is not set false\r
243 // \r
244 if (PcdGetBool(PcdShellLibAutoInitialize) == 0) {\r
245 return (EFI_SUCCESS);\r
246 }\r
247 \r
248 return (ShellLibConstructorWorker(ImageHandle, SystemTable));\r
249}\r
250\r
251/**\r
252 Destructory for the library. free any resources.\r
253**/\r
254EFI_STATUS\r
255EFIAPI\r
256ShellLibDestructor (\r
257 IN EFI_HANDLE ImageHandle,\r
258 IN EFI_SYSTEM_TABLE *SystemTable\r
259 )\r
260{\r
261 if (mEfiShellEnvironment2 != NULL) {\r
262 gBS->CloseProtocol(mEfiShellEnvironment2Handle==NULL?ImageHandle:mEfiShellEnvironment2Handle,\r
263 &gEfiShellEnvironment2Guid,\r
264 ImageHandle,\r
265 NULL);\r
266 mEfiShellEnvironment2 = NULL;\r
267 }\r
268 if (mEfiShellInterface != NULL) {\r
269 gBS->CloseProtocol(ImageHandle,\r
270 &gEfiShellInterfaceGuid,\r
271 ImageHandle,\r
272 NULL); \r
273 mEfiShellInterface = NULL;\r
274 }\r
275 if (mEfiShellProtocol != NULL) {\r
276 gBS->CloseProtocol(ImageHandle,\r
277 &gEfiShellProtocolGuid,\r
278 ImageHandle,\r
279 NULL); \r
280 mEfiShellProtocol = NULL;\r
281 }\r
282 if (mEfiShellParametersProtocol != NULL) {\r
283 gBS->CloseProtocol(ImageHandle,\r
284 &gEfiShellParametersProtocolGuid,\r
285 ImageHandle,\r
286 NULL); \r
287 mEfiShellParametersProtocol = NULL;\r
288 }\r
289 mEfiShellEnvironment2Handle = NULL;\r
290 return (EFI_SUCCESS);\r
291}\r
292\r
293/**\r
294 This function causes the shell library to initialize itself. If the shell library\r
295 is already initialized it will de-initialize all the current protocol poitners and\r
296 re-populate them again.\r
297\r
298 When the library is used with PcdShellLibAutoInitialize set to true this function\r
299 will return EFI_SUCCESS and perform no actions.\r
300\r
301 This function is intended for internal access for shell commands only.\r
302\r
303 @retval EFI_SUCCESS the initialization was complete sucessfully\r
304\r
305**/\r
306EFI_STATUS\r
307EFIAPI\r
308ShellInitialize (\r
309 ) {\r
310 //\r
311 // if auto initialize is not false then skip\r
312 //\r
313 if (PcdGetBool(PcdShellLibAutoInitialize) != 0) {\r
314 return (EFI_SUCCESS);\r
315 }\r
316\r
317 //\r
318 // deinit the current stuff\r
319 //\r
320 ASSERT_EFI_ERROR(ShellLibDestructor(gImageHandle, gST));\r
321\r
322 //\r
323 // init the new stuff\r
324 //\r
325 return (ShellLibConstructorWorker(gImageHandle, gST));\r
326}\r
327\r
328/**\r
329 This function will retrieve the information about the file for the handle \r
330 specified and store it in allocated pool memory.\r
331\r
332