First (Alpha) release of ShellPkg
[mirror_edk2.git] / ShellPkg / Library / BaseShellLib / BaseShellLib.c
CommitLineData
94b17fa1 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 <Protocol/EfiShellEnvironment2.h>\r
24#include <Protocol/EfiShellInterface.h>\r
25#include <Protocol/EfiShell.h>\r
26#include <Protocol/EfiShellParameters.h>\r
27#include <Protocol/SimpleFileSystem.h>\r
28\r
29#define MAX_FILE_NAME_LEN 522 // (20 * (6+5+2))+1) unicode characters from EFI FAT spec (doubled for bytes)\r
30#define FIND_XXXXX_FILE_BUFFER_SIZE (SIZE_OF_EFI_FILE_INFO + MAX_FILE_NAME_LEN)\r
31\r
32EFI_SHELL_ENVIRONMENT2 *mEfiShellEnvironment2;\r
33EFI_SHELL_INTERFACE *mEfiShellInterface;\r
34EFI_SHELL_PROTOCOL *mEfiShellProtocol;\r
35EFI_SHELL_PARAMETERS_PROTOCOL *mEfiShellParametersProtocol;\r
36EFI_HANDLE mEfiShellEnvironment2Handle;\r
37EFI_LIST_ENTRY *mOldStyleFileList;\r
38\r
39/**\r
40 helper function to find ShellEnvironment2 for constructor\r
41**/\r
42EFI_STATUS\r
43EFIAPI\r
44ShellFindSE2 (\r
45 IN EFI_HANDLE ImageHandle\r
46 )\r
47{\r
48 EFI_STATUS Status;\r
49 EFI_HANDLE *Buffer;\r
50 UINTN BufferSize;\r
51 UINTN HandleIndex;\r
52\r
53 BufferSize = 0;\r
54 Buffer = NULL;\r
55 Status = gBS->OpenProtocol(ImageHandle, \r
56 &gEfiShellEnvironment2Guid,\r
57 (VOID **)&mEfiShellEnvironment2,\r
58 ImageHandle,\r
59 NULL,\r
60 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
61 );\r
62 //\r
63 // look for the mEfiShellEnvironment2 protocol at a higher level\r
64 //\r
65 if (EFI_ERROR (Status) || !(CompareGuid (&mEfiShellEnvironment2->SESGuid, &gEfiShellEnvironment2ExtGuid) != FALSE &&\r
66 (mEfiShellEnvironment2->MajorVersion > EFI_SHELL_MAJOR_VER ||\r
67 (mEfiShellEnvironment2->MajorVersion == EFI_SHELL_MAJOR_VER && mEfiShellEnvironment2->MinorVersion >= EFI_SHELL_MINOR_VER)))) {\r
68 //\r
69 // figure out how big of a buffer we need.\r
70 //\r
71 Status = gBS->LocateHandle (ByProtocol,\r
72 &gEfiShellEnvironment2Guid,\r
73 NULL, // ignored for ByProtocol\r
74 &BufferSize,\r
75 Buffer\r
76 );\r
77 ASSERT(Status == EFI_BUFFER_TOO_SMALL);\r
78 Buffer = (EFI_HANDLE*)AllocatePool(BufferSize);\r
79 ASSERT(Buffer != NULL);\r
80 Status = gBS->LocateHandle (ByProtocol,\r
81 &gEfiShellEnvironment2Guid,\r
82 NULL, // ignored for ByProtocol\r
83 &BufferSize,\r
84 Buffer\r
85 );\r
86 if (!EFI_ERROR (Status)) {\r
87 //\r
88 // now parse the list of returned handles\r
89 //\r
90 Status = EFI_NOT_FOUND;\r
91 for (HandleIndex = 0; HandleIndex < (BufferSize/sizeof(Buffer[0])); HandleIndex++) {\r
92 Status = gBS->OpenProtocol(Buffer[HandleIndex], \r
93 &gEfiShellEnvironment2Guid,\r
94 (VOID **)&mEfiShellEnvironment2,\r
95 ImageHandle,\r
96 NULL,\r
97 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
98 );\r
99 if (CompareGuid (&mEfiShellEnvironment2->SESGuid, &gEfiShellEnvironment2ExtGuid) != FALSE &&\r
100 (mEfiShellEnvironment2->MajorVersion > EFI_SHELL_MAJOR_VER ||\r
101 (mEfiShellEnvironment2->MajorVersion == EFI_SHELL_MAJOR_VER && mEfiShellEnvironment2->MinorVersion >= EFI_SHELL_MINOR_VER))) {\r
102 mEfiShellEnvironment2Handle = Buffer[HandleIndex];\r
103 Status = EFI_SUCCESS;\r
104 break;\r
105 }\r
106 }\r
107 }\r
108 }\r
109 if (Buffer != NULL) {\r
110 FreePool (Buffer);\r
111 }\r
112 return (Status);\r
113}\r
114\r
115/**\r
116 Constructor for the Shell library.\r
117\r
118 Initialize the library and determine if the underlying is a UEFI Shell 2.0 or an EFI shell.\r
119\r
120 @param ImageHandle the image handle of the process\r
121 @param SystemTable the EFI System Table pointer\r
122\r
123 @retval EFI_SUCCESS the initialization was complete sucessfully\r
124 @return others an error ocurred during initialization\r
125**/\r
126EFI_STATUS\r
127EFIAPI\r
128ShellLibConstructor (\r
129 IN EFI_HANDLE ImageHandle,\r
130 IN EFI_SYSTEM_TABLE *SystemTable\r
131 )\r
132{\r
133 EFI_STATUS Status;\r
134\r
135 ASSERT(SystemTable != NULL);\r
136 ASSERT(gBS != NULL);\r
137\r
138 mEfiShellEnvironment2 = NULL;\r
139 mEfiShellProtocol = NULL;\r
140 mEfiShellParametersProtocol = NULL;\r
141 mEfiShellInterface = NULL;\r
142 mEfiShellEnvironment2Handle = NULL;\r
143 mOldStyleFileList = NULL;\r
144\r
145 //\r
146 // UEFI 2.0 shell interfaces (used preferentially)\r
147 //\r
148 Status = gBS->OpenProtocol(ImageHandle, \r
149 &gEfiShellProtocolGuid,\r
150 (VOID **)&mEfiShellProtocol,\r
151 ImageHandle,\r
152 NULL,\r
153 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
154 );\r
155 if (EFI_ERROR(Status)) {\r
156 mEfiShellProtocol = NULL;\r
157 }\r
158 Status = gBS->OpenProtocol(ImageHandle, \r
159 &gEfiShellParametersProtocolGuid,\r
160 (VOID **)&mEfiShellParametersProtocol,\r
161 ImageHandle,\r
162 NULL,\r
163 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
164 );\r
165 if (EFI_ERROR(Status)) {\r
166 mEfiShellParametersProtocol = NULL;\r
167 }\r
168\r
169 if (mEfiShellParametersProtocol == NULL || mEfiShellProtocol == NULL) {\r
170 //\r
171 // Moved to seperate function due to complexity\r
172 //\r
173 Status = ShellFindSE2(ImageHandle);\r
174\r
175 if (EFI_ERROR(Status)) {\r
176 DEBUG((DEBUG_ERROR, "Status: 0x%08x\r\n", Status));\r
177 mEfiShellEnvironment2 = NULL;\r
178 }\r
179 Status = gBS->OpenProtocol(ImageHandle, \r
180 &gEfiShellInterfaceGuid,\r
181 (VOID **)&mEfiShellInterface,\r
182 ImageHandle,\r
183 NULL,\r
184 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
185 );\r
186 if (EFI_ERROR(Status)) {\r
187 mEfiShellInterface = NULL;\r
188 }\r
189 }\r
190 //\r
191 // only success getting 2 of either the old or new, but no 1/2 and 1/2\r
192 //\r
193 if ((mEfiShellEnvironment2 != NULL && mEfiShellInterface != NULL) || \r
194 (mEfiShellProtocol != NULL && mEfiShellParametersProtocol != NULL) ) {\r
195 return (EFI_SUCCESS);\r
196 }\r
197 return (EFI_NOT_FOUND);\r
198}\r
199\r
200/**\r
201 Destructory for the library. free any resources.\r
202**/\r
203EFI_STATUS\r
204EFIAPI\r
205ShellLibDestructor (\r
206 IN EFI_HANDLE ImageHandle,\r
207 IN EFI_SYSTEM_TABLE *SystemTable\r
208 )\r
209{\r
210 if (mEfiShellEnvironment2 != NULL) {\r
211 gBS->CloseProtocol(mEfiShellEnvironment2Handle==NULL?ImageHandle:mEfiShellEnvironment2Handle,\r
212 &gEfiShellEnvironment2Guid,\r
213 ImageHandle,\r
214 NULL);\r
215 }\r
216 if (mEfiShellInterface != NULL) {\r
217 gBS->CloseProtocol(ImageHandle,\r
218 &gEfiShellInterfaceGuid,\r
219 ImageHandle,\r
220 NULL); \r
221 }\r
222 if (mEfiShellProtocol != NULL) {\r
223 gBS->CloseProtocol(ImageHandle,\r
224 &gEfiShellProtocolGuid,\r
225 ImageHandle,\r
226 NULL); \r
227 }\r
228 if (mEfiShellParametersProtocol != NULL) {\r
229 gBS->CloseProtocol(ImageHandle,\r
230 &gEfiShellParametersProtocolGuid,\r
231 ImageHandle,\r
232 NULL); \r
233 }\r
234 return (EFI_SUCCESS);\r
235}\r
236/**\r
237 This function will retrieve the information about the file for the handle \r
238 specified and store it in allocated pool memory.\r
239\r
240