]>
Commit | Line | Data |
---|---|---|
a355a365 | 1 | /** @file |
2 | * | |
3 | * Copyright (c) 2011, ARM Limited. All rights reserved. | |
4 | * | |
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 "BdsInternal.h" | |
16 | ||
e862cd50 | 17 | //#include <Library/DxeServicesLib.h> |
a355a365 | 18 | |
19 | STATIC | |
20 | EFI_STATUS | |
21 | BdsLoadFileFromFirmwareVolume ( | |
22 | IN EFI_HANDLE FvHandle, | |
23 | IN CHAR16 *FilePath, | |
24 | IN EFI_FV_FILETYPE FileTypeFilter, | |
25 | OUT EFI_DEVICE_PATH **EfiAppDevicePath | |
26 | ) | |
27 | { | |
28 | EFI_FIRMWARE_VOLUME2_PROTOCOL *FvProtocol; | |
29 | VOID *Key; | |
30 | EFI_STATUS Status, FileStatus; | |
31 | EFI_GUID NameGuid; | |
32 | EFI_FV_FILETYPE FileType; | |
33 | EFI_FV_FILE_ATTRIBUTES Attributes; | |
34 | UINTN Size; | |
35 | UINTN UiStringLen; | |
36 | CHAR16 *UiSection; | |
37 | UINT32 Authentication; | |
38 | EFI_DEVICE_PATH *FvDevicePath; | |
39 | MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileDevicePath; | |
40 | ||
41 | Status = gBS->HandleProtocol (FvHandle,&gEfiFirmwareVolume2ProtocolGuid, (VOID **)&FvProtocol); | |
42 | if (EFI_ERROR(Status)) { | |
43 | return Status; | |
44 | } | |
45 | ||
46 | // Length of FilePath | |
47 | UiStringLen = StrLen (FilePath); | |
48 | ||
49 | // Allocate Key | |
50 | Key = AllocatePool (FvProtocol->KeySize); | |
51 | ASSERT (Key != NULL); | |
52 | ZeroMem (Key, FvProtocol->KeySize); | |
53 | ||
54 | do { | |
55 | // Search in all files | |
56 | FileType = FileTypeFilter; | |
57 | ||
58 | Status = FvProtocol->GetNextFile (FvProtocol, Key, &FileType, &NameGuid, &Attributes, &Size); | |
59 | if (!EFI_ERROR (Status)) { | |
60 | UiSection = NULL; | |
61 | FileStatus = FvProtocol->ReadSection ( | |
62 | FvProtocol, | |
63 | &NameGuid, | |
64 | EFI_SECTION_USER_INTERFACE, | |
65 | 0, | |
66 | (VOID **)&UiSection, | |
67 | &Size, | |
68 | &Authentication | |
69 | ); | |
70 | if (!EFI_ERROR (FileStatus)) { | |
71 | if (StrnCmp (FilePath, UiSection, UiStringLen) == 0) { | |
72 | // | |
73 | // We found a UiString match. | |
74 | // | |
75 | Status = gBS->HandleProtocol (FvHandle, &gEfiDevicePathProtocolGuid, (VOID **)&FvDevicePath); | |
76 | ||
77 | // Generate the Device Path for the file | |
78 | //DevicePath = DuplicateDevicePath(FvDevicePath); | |
79 | EfiInitializeFwVolDevicepathNode (&FileDevicePath, &NameGuid); | |
80 | *EfiAppDevicePath = AppendDevicePathNode (FvDevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&FileDevicePath); | |
81 | ||
82 | FreePool (Key); | |
83 | FreePool (UiSection); | |
84 | return FileStatus; | |
85 | } | |
86 | FreePool (UiSection); | |
87 | } | |
88 | } | |
89 | } while (!EFI_ERROR (Status)); | |
90 | ||
91 | FreePool(Key); | |
92 | return Status; | |
93 | } | |
94 | ||
95 | /** | |
96 | Start an EFI Application from any Firmware Volume | |
97 | ||
98 | @param EfiApp EFI Application Name | |
99 | ||
100 | @retval EFI_SUCCESS All drivers have been connected | |
101 | @retval EFI_NOT_FOUND The Linux kernel Device Path has not been found | |
102 | @retval EFI_OUT_OF_RESOURCES There is not enough resource memory to store the matching results. | |
103 | ||
104 | **/ | |
105 | EFI_STATUS | |
106 | BdsLoadApplication ( | |
107 | IN EFI_HANDLE ParentImageHandle, | |
2755d844 | 108 | IN CHAR16* EfiApp, |
109 | IN UINTN LoadOptionsSize, | |
110 | IN VOID* LoadOptions | |
a355a365 | 111 | ) |
112 | { | |
113 | EFI_STATUS Status; | |
114 | UINTN NoHandles, HandleIndex; | |
115 | EFI_HANDLE *Handles; | |
a355a365 | 116 | EFI_DEVICE_PATH *EfiAppDevicePath; |
117 | ||
118 | // Need to connect every drivers to ensure no dependencies are missing for the application | |
119 | Status = BdsConnectAllDrivers(); | |
120 | if (EFI_ERROR(Status)) { | |
121 | DEBUG ((EFI_D_ERROR, "FAIL to connect all drivers\n")); | |
122 | return Status; | |
123 | } | |
124 | ||
125 | // Search the application in any Firmware Volume | |
126 | Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiFirmwareVolume2ProtocolGuid, NULL, &NoHandles, &Handles); | |
127 | if (EFI_ERROR (Status) || (NoHandles == 0)) { | |
128 | DEBUG ((EFI_D_ERROR, "FAIL to find Firmware Volume\n")); | |
129 | return Status; | |
130 | } | |
131 | ||
132 | // Search in all Firmware Volume for the EFI Application | |
133 | for (HandleIndex = 0; HandleIndex < NoHandles; HandleIndex++) { | |
e862cd50 | 134 | EfiAppDevicePath = NULL; |
a355a365 | 135 | Status = BdsLoadFileFromFirmwareVolume (Handles[HandleIndex], EfiApp, EFI_FV_FILETYPE_APPLICATION, &EfiAppDevicePath); |
136 | if (!EFI_ERROR (Status)) { | |
137 | // Start the application | |
2755d844 | 138 | Status = BdsStartEfiApplication (ParentImageHandle, EfiAppDevicePath, LoadOptionsSize, LoadOptions); |
a355a365 | 139 | return Status; |
140 | } | |
141 | } | |
142 | ||
143 | return Status; | |
144 | } |