TianoCore EDK2 master
Loading...
Searching...
No Matches
LoadFileOnFv2.c
Go to the documentation of this file.
1
9#include <PiDxe.h>
10
11#include <Guid/LzmaDecompress.h>
12#include <Protocol/LoadFile.h>
13#include <Protocol/DevicePath.h>
16
17#include <Library/DebugLib.h>
18#include <Library/UefiLib.h>
24
25#define LOAD_FILE_ON_FV2_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('l', 'f', 'f', 'v')
26
27typedef struct {
28 UINTN Signature;
30 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
32 EFI_GUID NameGuid;
33 LIST_ENTRY Link;
35
36#define LOAD_FILE_ON_FV2_PRIVATE_DATA_FROM_THIS(a) CR (a, LOAD_FILE_ON_FV2_PRIVATE_DATA, LoadFile, LOAD_FILE_ON_FV2_PRIVATE_DATA_SIGNATURE)
37#define LOAD_FILE_ON_FV2_PRIVATE_DATA_FROM_LINK(a) CR (a, LOAD_FILE_ON_FV2_PRIVATE_DATA, Link, LOAD_FILE_ON_FV2_PRIVATE_DATA_SIGNATURE)
38
39VOID *mFvRegistration;
40LIST_ENTRY mPrivateDataList;
41
70EFIAPI
74 IN BOOLEAN BootPolicy,
75 IN OUT UINTN *BufferSize,
76 IN VOID *Buffer OPTIONAL
77 )
78{
79 EFI_STATUS Status;
81 VOID *Pe32Buffer;
82 UINTN Pe32BufferSize;
83 UINT32 AuthenticationStatus;
84
85 if ((This == NULL) || (BufferSize == NULL)) {
86 return EFI_INVALID_PARAMETER;
87 }
88
89 //
90 // Only support BootPolicy
91 //
92 if (!BootPolicy) {
93 return EFI_UNSUPPORTED;
94 }
95
96 //
97 // Get private context data
98 //
99 Private = LOAD_FILE_ON_FV2_PRIVATE_DATA_FROM_THIS (This);
100
101 //
102 // Determine the size of the PE32 section
103 //
104 Pe32Buffer = NULL;
105 Pe32BufferSize = 0;
106 Status = Private->Fv->ReadSection (
107 Private->Fv,
108 &Private->NameGuid,
110 0,
111 &Pe32Buffer,
112 &Pe32BufferSize,
113 &AuthenticationStatus
114 );
115 if (EFI_ERROR (Status)) {
116 return Status;
117 }
118
119 //
120 // If the buffer passed in is not large enough, return the size of the required
121 // buffer in BufferSize and return EFI_BUFFER_TOO_SMALL
122 //
123 if ((*BufferSize < Pe32BufferSize) || (Buffer == NULL)) {
124 *BufferSize = Pe32BufferSize;
125 return EFI_BUFFER_TOO_SMALL;
126 }
127
128 //
129 // The buffer passed in is large enough, so read the PE32 section directly into
130 // the buffer, update BufferSize with the actual size read, and return the status
131 // from ReadSection()
132 //
133 return Private->Fv->ReadSection (
134 Private->Fv,
135 &Private->NameGuid,
137 0,
138 &Buffer,
139 BufferSize,
140 &AuthenticationStatus
141 );
142}
143
144LOAD_FILE_ON_FV2_PRIVATE_DATA mLoadFileOnFv2PrivateDataTemplate = {
145 LOAD_FILE_ON_FV2_PRIVATE_DATA_SIGNATURE,
146 {
148 }
149};
150
160BOOLEAN
161EFIAPI
163 IN EFI_GUID *NameGuid
164 )
165{
166 LIST_ENTRY *Entry;
168
169 if (IsListEmpty (&mPrivateDataList)) {
170 return FALSE;
171 }
172
173 for (Entry = (&mPrivateDataList)->ForwardLink; Entry != (&mPrivateDataList); Entry = Entry->ForwardLink) {
174 PrivateData = LOAD_FILE_ON_FV2_PRIVATE_DATA_FROM_LINK (Entry);
175 if (CompareGuid (NameGuid, &PrivateData->NameGuid)) {
176 DEBUG ((DEBUG_INFO, "LoadFileOnFv2:FileLoadProtocol has been installed in:%g\n", NameGuid));
177 return TRUE;
178 }
179 }
180
181 return FALSE;
182}
183
194EFIAPI
196 IN EFI_HANDLE Device,
197 IN EFI_GUID *NameGuid,
198 IN CONST CHAR16 *FileName
199 )
200{
201 UINTN Size;
202 FILEPATH_DEVICE_PATH *FilePath;
203 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
206
207 EfiInitializeFwVolDevicepathNode (&FileNode, NameGuid);
208 DevicePath = AppendDevicePathNode (
209 DevicePathFromHandle (Device),
210 (EFI_DEVICE_PATH_PROTOCOL *)&FileNode
211 );
212
213 Size = StrSize (FileName);
214 FileDevicePath = AllocatePool (Size + SIZE_OF_FILEPATH_DEVICE_PATH + END_DEVICE_PATH_LENGTH);
215 if (FileDevicePath != NULL) {
217 FilePath->Header.Type = MEDIA_DEVICE_PATH;
218 FilePath->Header.SubType = MEDIA_FILEPATH_DP;
219 CopyMem (&FilePath->PathName, FileName, Size);
220 SetDevicePathNodeLength (&FilePath->Header, Size + SIZE_OF_FILEPATH_DEVICE_PATH);
221 SetDevicePathEndNode (NextDevicePathNode (&FilePath->Header));
222
223 DevicePath = AppendDevicePath (DevicePath, FileDevicePath);
225 }
226
227 return DevicePath;
228}
229
236VOID
237EFIAPI
239 EFI_HANDLE Handle
240 )
241{
242 EFI_STATUS Status;
246 EFI_PHYSICAL_ADDRESS Address;
247 EFI_FV_FILETYPE FileType;
248 UINTN Key;
249 EFI_GUID NameGuid;
250 EFI_FV_FILE_ATTRIBUTES Attributes;
251 UINTN Size;
252 EFI_HANDLE LoadFileHandle;
253 UINT32 AuthenticationStatus;
254 CHAR16 *UiName;
255 UINTN UiNameSize;
256
257 DEBUG ((DEBUG_INFO, "LoadFileOnFv2:Find a FV!\n"));
258 Status = gBS->HandleProtocol (Handle, &gEfiFirmwareVolume2ProtocolGuid, (VOID **)&Fv);
259 ASSERT_EFI_ERROR (Status);
260 Status = gBS->HandleProtocol (Handle, &gEfiFirmwareVolumeBlockProtocolGuid, (VOID **)&Fvb);
261 Fvb->GetPhysicalAddress (Fvb, &Address);
262 DEBUG ((DEBUG_INFO, "LoadFileOnFv2:Fvb->Address=%x \n", Address));
263
264 //
265 // Use Firmware Volume 2 Protocol to search for a FFS files of type
266 // EFI_FV_FILETYPE_APPLICATION and produce a LoadFile protocol for
267 // each one found.
268 //
269 FileType = EFI_FV_FILETYPE_APPLICATION;
270 Key = 0;
271 while (TRUE) {
272 Status = Fv->GetNextFile (Fv, &Key, &FileType, &NameGuid, &Attributes, &Size);
273 if (EFI_ERROR (Status)) {
274 break;
275 }
276
277 UiName = NULL;
278 Status = Fv->ReadSection (
279 Fv,
280 &NameGuid,
281 EFI_SECTION_USER_INTERFACE,
282 0,
283 (VOID **)&UiName,
284 &UiNameSize,
285 &AuthenticationStatus
286 );
287 if (EFI_ERROR (Status)) {
288 continue;
289 }
290
291 if (!IsInPrivateList (&NameGuid)) {
292 Private = (LOAD_FILE_ON_FV2_PRIVATE_DATA *)AllocateCopyPool (sizeof (mLoadFileOnFv2PrivateDataTemplate), &mLoadFileOnFv2PrivateDataTemplate);
293 ASSERT (Private != NULL);
294 Private->Fv = Fv;
295 Private->DevicePath = CreateFileDevicePath (Handle, &NameGuid, UiName);
296 CopyGuid (&Private->NameGuid, &NameGuid);
297 LoadFileHandle = NULL;
298 DEBUG ((DEBUG_INFO, "Find a APPLICATION in this FV!\n"));
299 Status = gBS->InstallMultipleProtocolInterfaces (
300 &LoadFileHandle,
301 &gEfiDevicePathProtocolGuid,
302 Private->DevicePath,
303 &gEfiLoadFileProtocolGuid,
304 &Private->LoadFile,
305 NULL
306 );
307 if (!EFI_ERROR (Status)) {
308 InsertTailList (&mPrivateDataList, &Private->Link);
309 } else {
310 DEBUG ((DEBUG_ERROR, "Application with the same name %s has been installed.!\n", UiName));
311 FreePool (Private->DevicePath);
312 FreePool (Private);
313 }
314 }
315 }
316}
317
328VOID
329EFIAPI
331 IN EFI_EVENT Event,
332 IN VOID *Context
333 )
334{
335 EFI_STATUS Status;
336 UINTN BufferSize;
337 EFI_HANDLE *Handle;
338 UINTN Index;
339 EFI_HANDLE *CurHandle;
340
341 Handle = NULL;
342 Index = 0;
343 BufferSize = sizeof (EFI_HANDLE);
344 Handle = AllocateZeroPool (BufferSize);
345 if (Handle == NULL) {
346 return;
347 }
348
349 Status = gBS->LocateHandle (
351 &gEfiFirmwareVolume2ProtocolGuid,
352 NULL,
353 &BufferSize,
354 Handle
355 );
356 if (EFI_BUFFER_TOO_SMALL == Status) {
357 FreePool (Handle);
358 Handle = AllocateZeroPool (BufferSize);
359 if (Handle == NULL) {
360 return;
361 }
362
363 Status = gBS->LocateHandle (
365 &gEfiFirmwareVolume2ProtocolGuid,
366 NULL,
367 &BufferSize,
368 Handle
369 );
370 if (EFI_ERROR (Status)) {
371 return;
372 }
373 } else if (EFI_ERROR (Status)) {
374 return;
375 }
376
377 CurHandle = Handle;
378 for (Index = 0; Index < BufferSize/sizeof (EFI_HANDLE); Index++) {
379 CurHandle = Handle + Index;
380 //
381 // Install LoadFile Protocol
382 //
383 InstallFileLoadProtocol (*CurHandle);
384 }
385
386 if (Handle != NULL) {
387 FreePool (Handle);
388 }
389}
390
401EFIAPI
403 IN EFI_HANDLE ImageHandle,
404 IN EFI_SYSTEM_TABLE *SystemTable
405 )
406{
407 InitializeListHead (&mPrivateDataList);
408
410 &gEfiFirmwareVolume2ProtocolGuid,
411 TPL_CALLBACK,
413 NULL,
414 &mFvRegistration
415 );
416
418 &gLzmaCustomDecompressGuid,
419 TPL_CALLBACK,
421 NULL,
422 &mFvRegistration
423 );
424
425 return EFI_SUCCESS;
426}
UINT64 UINTN
UINTN EFIAPI StrSize(IN CONST CHAR16 *String)
Definition: String.c:72
BOOLEAN EFIAPI IsListEmpty(IN CONST LIST_ENTRY *ListHead)
Definition: LinkedList.c:403
LIST_ENTRY *EFIAPI InitializeListHead(IN OUT LIST_ENTRY *ListHead)
Definition: LinkedList.c:182
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
Definition: LinkedList.c:259
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
Definition: MemLibGuid.c:73
GUID *EFIAPI CopyGuid(OUT GUID *DestinationGuid, IN CONST GUID *SourceGuid)
Definition: MemLibGuid.c:39
#define MEDIA_FILEPATH_DP
Definition: DevicePath.h:1098
UINT16 EFIAPI SetDevicePathNodeLength(IN OUT VOID *Node, IN UINTN Length)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI AppendDevicePathNode(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath OPTIONAL, IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode OPTIONAL)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI FileDevicePath(IN EFI_HANDLE Device OPTIONAL, IN CONST CHAR16 *FileName)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI NextDevicePathNode(IN CONST VOID *Node)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI DevicePathFromHandle(IN EFI_HANDLE Handle)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI AppendDevicePath(IN CONST EFI_DEVICE_PATH_PROTOCOL *FirstDevicePath OPTIONAL, IN CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath OPTIONAL)
VOID EFIAPI SetDevicePathEndNode(OUT VOID *Node)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
VOID *EFIAPI AllocateCopyPool(IN UINTN AllocationSize, IN CONST VOID *Buffer)
VOID EFIAPI InstallFileLoadProtocol(EFI_HANDLE Handle)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI CreateFileDevicePath(IN EFI_HANDLE Device, IN EFI_GUID *NameGuid, IN CONST CHAR16 *FileName)
VOID EFIAPI FvNotificationEvent(IN EFI_EVENT Event, IN VOID *Context)
EFI_STATUS EFIAPI LoadFileOnFv2Intialize(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
EFI_STATUS EFIAPI LoadFileOnFv2LoadFile(IN EFI_LOAD_FILE_PROTOCOL *This, IN EFI_DEVICE_PATH_PROTOCOL *FilePath, IN BOOLEAN BootPolicy, IN OUT UINTN *BufferSize, IN VOID *Buffer OPTIONAL)
Definition: LoadFileOnFv2.c:71
BOOLEAN EFIAPI IsInPrivateList(IN EFI_GUID *NameGuid)
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define EFI_SECTION_PE32
UINT32 EFI_FV_FILE_ATTRIBUTES
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_EVENT
Definition: UefiBaseType.h:37
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
VOID EFIAPI EfiInitializeFwVolDevicepathNode(IN OUT MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvDevicePathNode, IN CONST EFI_GUID *NameGuid)
Definition: UefiNotTiano.c:325
EFI_EVENT EFIAPI EfiCreateProtocolNotifyEvent(IN EFI_GUID *ProtocolGuid, IN EFI_TPL NotifyTpl, IN EFI_EVENT_NOTIFY NotifyFunction, IN VOID *NotifyContext OPTIONAL, OUT VOID **Registration)
Definition: UefiLib.c:134
@ ByProtocol
Definition: UefiSpec.h:1518
Definition: Base.h:213