]> git.proxmox.com Git - mirror_edk2.git/blob - SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigFileExplorer.c
SecurityPkg: Use FileExplorerLib in SecureBootConfigDxe
[mirror_edk2.git] / SecurityPkg / VariableAuthenticated / SecureBootConfigDxe / SecureBootConfigFileExplorer.c
1 /** @file
2 Internal file explorer functions for SecureBoot configuration module.
3
4 Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include "SecureBootConfigImpl.h"
16
17 VOID *mStartOpCodeHandle = NULL;
18 VOID *mEndOpCodeHandle = NULL;
19 EFI_IFR_GUID_LABEL *mStartLabel = NULL;
20 EFI_IFR_GUID_LABEL *mEndLabel = NULL;
21
22 /**
23 Refresh the global UpdateData structure.
24
25 **/
26 VOID
27 RefreshUpdateData (
28 VOID
29 )
30 {
31 //
32 // Free current updated date
33 //
34 if (mStartOpCodeHandle != NULL) {
35 HiiFreeOpCodeHandle (mStartOpCodeHandle);
36 }
37
38 //
39 // Create new OpCode Handle
40 //
41 mStartOpCodeHandle = HiiAllocateOpCodeHandle ();
42
43 //
44 // Create Hii Extend Label OpCode as the start opcode
45 //
46 mStartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
47 mStartOpCodeHandle,
48 &gEfiIfrTianoGuid,
49 NULL,
50 sizeof (EFI_IFR_GUID_LABEL)
51 );
52 mStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
53 }
54
55 /**
56 Clean up the dynamic opcode at label and form specified by both LabelId.
57
58 @param[in] LabelId It is both the Form ID and Label ID for opcode deletion.
59 @param[in] PrivateData Module private data.
60
61 **/
62 VOID
63 CleanUpPage (
64 IN UINT16 LabelId,
65 IN SECUREBOOT_CONFIG_PRIVATE_DATA *PrivateData
66 )
67 {
68 RefreshUpdateData ();
69
70 //
71 // Remove all op-codes from dynamic page
72 //
73 mStartLabel->Number = LabelId;
74 HiiUpdateForm (
75 PrivateData->HiiHandle,
76 &gSecureBootConfigFormSetGuid,
77 LabelId,
78 mStartOpCodeHandle, // Label LabelId
79 mEndOpCodeHandle // LABEL_END
80 );
81 }
82
83 /**
84 This function will open a file or directory referenced by DevicePath.
85
86 This function opens a file with the open mode according to the file path. The
87 Attributes is valid only for EFI_FILE_MODE_CREATE.
88
89 @param[in, out] FilePath On input, the device path to the file.
90 On output, the remaining device path.
91 @param[out] FileHandle Pointer to the file handle.
92 @param[in] OpenMode The mode to open the file with.
93 @param[in] Attributes The file's file attributes.
94
95 @retval EFI_SUCCESS The information was set.
96 @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.
97 @retval EFI_UNSUPPORTED Could not open the file path.
98 @retval EFI_NOT_FOUND The specified file could not be found on the
99 device or the file system could not be found on
100 the device.
101 @retval EFI_NO_MEDIA The device has no medium.
102 @retval EFI_MEDIA_CHANGED The device has a different medium in it or the
103 medium is no longer supported.
104 @retval EFI_DEVICE_ERROR The device reported an error.
105 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
106 @retval EFI_WRITE_PROTECTED The file or medium is write protected.
107 @retval EFI_ACCESS_DENIED The file was opened read only.
108 @retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the
109 file.
110 @retval EFI_VOLUME_FULL The volume is full.
111 **/
112 EFI_STATUS
113 EFIAPI
114 OpenFileByDevicePath(
115 IN OUT EFI_DEVICE_PATH_PROTOCOL **FilePath,
116 OUT EFI_FILE_HANDLE *FileHandle,
117 IN UINT64 OpenMode,
118 IN UINT64 Attributes
119 )
120 {
121 EFI_STATUS Status;
122 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *EfiSimpleFileSystemProtocol;
123 EFI_FILE_PROTOCOL *Handle1;
124 EFI_FILE_PROTOCOL *Handle2;
125 EFI_HANDLE DeviceHandle;
126
127 if ((FilePath == NULL || FileHandle == NULL)) {
128 return EFI_INVALID_PARAMETER;
129 }
130
131 Status = gBS->LocateDevicePath (
132 &gEfiSimpleFileSystemProtocolGuid,
133 FilePath,
134 &DeviceHandle
135 );
136 if (EFI_ERROR (Status)) {
137 return Status;
138 }
139
140 Status = gBS->OpenProtocol(
141 DeviceHandle,
142 &gEfiSimpleFileSystemProtocolGuid,
143 (VOID**)&EfiSimpleFileSystemProtocol,
144 gImageHandle,
145 NULL,
146 EFI_OPEN_PROTOCOL_GET_PROTOCOL
147 );
148 if (EFI_ERROR (Status)) {
149 return Status;
150 }
151
152 Status = EfiSimpleFileSystemProtocol->OpenVolume(EfiSimpleFileSystemProtocol, &Handle1);
153 if (EFI_ERROR (Status)) {
154 FileHandle = NULL;
155 return Status;
156 }
157
158 //
159 // go down directories one node at a time.
160 //
161 while (!IsDevicePathEnd (*FilePath)) {
162 //
163 // For file system access each node should be a file path component
164 //
165 if (DevicePathType (*FilePath) != MEDIA_DEVICE_PATH ||
166 DevicePathSubType (*FilePath) != MEDIA_FILEPATH_DP
167 ) {
168 FileHandle = NULL;
169 return (EFI_INVALID_PARAMETER);
170 }
171 //
172 // Open this file path node
173 //
174 Handle2 = Handle1;
175 Handle1 = NULL;
176
177 //
178 // Try to test opening an existing file
179 //
180 Status = Handle2->Open (
181 Handle2,
182 &Handle1,
183 ((FILEPATH_DEVICE_PATH*)*FilePath)->PathName,
184 OpenMode &~EFI_FILE_MODE_CREATE,
185 0
186 );
187
188 //
189 // see if the error was that it needs to be created
190 //
191 if ((EFI_ERROR (Status)) && (OpenMode != (OpenMode &~EFI_FILE_MODE_CREATE))) {
192 Status = Handle2->Open (
193 Handle2,
194 &Handle1,
195 ((FILEPATH_DEVICE_PATH*)*FilePath)->PathName,
196 OpenMode,
197 Attributes
198 );
199 }
200 //
201 // Close the last node
202 //
203 Handle2->Close (Handle2);
204
205 if (EFI_ERROR(Status)) {
206 return (Status);
207 }
208
209 //
210 // Get the next node
211 //
212 *FilePath = NextDevicePathNode (*FilePath);
213 }
214
215 //
216 // This is a weak spot since if the undefined SHELL_FILE_HANDLE format changes this must change also!
217 //
218 *FileHandle = (VOID*)Handle1;
219 return EFI_SUCCESS;
220 }
221
222
223 /**
224 Extract filename from device path. The returned buffer is allocated using AllocateCopyPool.
225 The caller is responsible for freeing the allocated buffer using FreePool().
226
227 @param DevicePath Device path.
228
229 @return A new allocated string that represents the file name.
230
231 **/
232 CHAR16 *
233 ExtractFileNameFromDevicePath (
234 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
235 )
236 {
237 CHAR16 *String;
238 CHAR16 *MatchString;
239 CHAR16 *LastMatch;
240 CHAR16 *FileName;
241 UINTN Length;
242
243 ASSERT(DevicePath != NULL);
244
245 String = DevicePathToStr(DevicePath);
246 MatchString = String;
247 LastMatch = String;
248
249 while(MatchString != NULL){
250 LastMatch = MatchString + 1;
251 MatchString = StrStr(LastMatch,L"\\");
252 }
253
254 Length = StrLen(LastMatch);
255 FileName = AllocateCopyPool ((Length + 1) * sizeof(CHAR16), LastMatch);
256 *(FileName + Length) = 0;
257
258 FreePool(String);
259
260 return FileName;
261 }
262
263
264 /**
265 Update the form base on the selected file.
266
267 @param FilePath Point to the file path.
268 @param FormId The form need to display.
269
270 @retval TRUE Exit caller function.
271 @retval FALSE Not exit caller function.
272
273 **/
274 BOOLEAN
275 UpdatePage(
276 IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
277 IN EFI_FORM_ID FormId
278 )
279 {
280 CHAR16 *FileName;
281 EFI_STRING_ID StringToken;
282
283 if (FilePath != NULL){
284 FileName = ExtractFileNameFromDevicePath(FilePath);
285 StringToken = HiiSetString (gSecureBootPrivateData->HiiHandle, 0, FileName, NULL);
286 } else {
287 FileName = HiiGetString (gSecureBootPrivateData->HiiHandle, STRING_TOKEN (STR_NULL), NULL);
288 ASSERT (FileName != NULL);
289 StringToken = HiiSetString (gSecureBootPrivateData->HiiHandle, 0, FileName, NULL);
290 }
291
292 gSecureBootPrivateData->FileContext->FileName = FileName;
293
294 OpenFileByDevicePath(
295 &FilePath,
296 &gSecureBootPrivateData->FileContext->FHandle,
297 EFI_FILE_MODE_READ,
298 0
299 );
300 //
301 // Create Subtitle op-code for the display string of the option.
302 //
303 RefreshUpdateData ();
304 mStartLabel->Number = FormId;
305
306 HiiCreateSubTitleOpCode (
307 mStartOpCodeHandle,
308 StringToken,
309 0,
310 0,
311 0
312 );
313
314 HiiUpdateForm (
315 gSecureBootPrivateData->HiiHandle,
316 &gSecureBootConfigFormSetGuid,
317 FormId,
318 mStartOpCodeHandle, // Label FormId
319 mEndOpCodeHandle // LABEL_END
320 );
321
322 return TRUE;
323 }
324
325 /**
326 Update the PK form base on the input file path info.
327
328 @param FilePath Point to the file path.
329
330 @retval TRUE Exit caller function.
331 @retval FALSE Not exit caller function.
332 **/
333 BOOLEAN
334 UpdatePKFromFile (
335 IN EFI_DEVICE_PATH_PROTOCOL *FilePath
336 )
337 {
338 return UpdatePage(FilePath, FORMID_ENROLL_PK_FORM);
339
340 }
341
342 /**
343 Update the KEK form base on the input file path info.
344
345 @param FilePath Point to the file path.
346
347 @retval TRUE Exit caller function.
348 @retval FALSE Not exit caller function.
349 **/
350 BOOLEAN
351 UpdateKEKFromFile (
352 IN EFI_DEVICE_PATH_PROTOCOL *FilePath
353 )
354 {
355 return UpdatePage(FilePath, FORMID_ENROLL_KEK_FORM);
356 }
357
358 /**
359 Update the DB form base on the input file path info.
360
361 @param FilePath Point to the file path.
362
363 @retval TRUE Exit caller function.
364 @retval FALSE Not exit caller function.
365 **/
366 BOOLEAN
367 UpdateDBFromFile (
368 IN EFI_DEVICE_PATH_PROTOCOL *FilePath
369 )
370 {
371 return UpdatePage(FilePath, SECUREBOOT_ENROLL_SIGNATURE_TO_DB);
372 }
373
374 /**
375 Update the DBX form base on the input file path info.
376
377 @param FilePath Point to the file path.
378
379 @retval TRUE Exit caller function.
380 @retval FALSE Not exit caller function.
381 **/
382 BOOLEAN
383 UpdateDBXFromFile (
384 IN EFI_DEVICE_PATH_PROTOCOL *FilePath
385 )
386 {
387 return UpdatePage(FilePath, SECUREBOOT_ENROLL_SIGNATURE_TO_DBX);
388 }
389
390 /**
391 Update the DBT form base on the input file path info.
392
393 @param FilePath Point to the file path.
394
395 @retval TRUE Exit caller function.
396 @retval FALSE Not exit caller function.
397 **/
398 BOOLEAN
399 UpdateDBTFromFile (
400 IN EFI_DEVICE_PATH_PROTOCOL *FilePath
401 )
402 {
403 return UpdatePage(FilePath, SECUREBOOT_ENROLL_SIGNATURE_TO_DBT);
404 }
405