OpenCore  1.0.4
OpenCore Bootloader
Loading...
Searching...
No Matches
OpenFile.c
Go to the documentation of this file.
1
16#include <Uefi.h>
17
18#include <Library/BaseLib.h>
19#include <Library/DebugLib.h>
20#include <Library/DevicePathLib.h>
21#include <Library/OcFileLib.h>
22#include <Library/MemoryAllocationLib.h>
23#include <Library/UefiBootServicesTableLib.h>
24
25#include <Protocol/DevicePath.h>
26#include <Protocol/SimpleFileSystem.h>
27
28EFI_STATUS
30 IN CONST EFI_FILE_PROTOCOL *Directory,
31 OUT EFI_FILE_PROTOCOL **NewHandle,
32 IN CONST CHAR16 *FileName,
33 IN CONST UINT64 OpenMode,
34 IN CONST UINT64 Attributes
35 )
36{
37 EFI_STATUS Status;
38 UINTN Length;
39
40 DEBUG_CODE_BEGIN ();
41 ASSERT (FileName != NULL);
42 ASSERT (NewHandle != NULL);
43 Length = StrLen (FileName);
44 if ((Length > 0) && (FileName[Length - 1] == L'\\')) {
45 DEBUG ((DEBUG_INFO, "OCFS: Filename %s has trailing slash\n", FileName));
46 }
47
48 DEBUG_CODE_END ();
49
50 *NewHandle = NULL;
51 Status = Directory->Open (
52 (EFI_FILE_PROTOCOL *)Directory,
53 NewHandle,
54 (CHAR16 *)FileName,
55 OpenMode,
56 Attributes
57 );
58 //
59 // Some boards like ASUS ROG RAMPAGE VI EXTREME may have malfunctioning FS
60 // drivers that report write protection violation errors for read-only
61 // operations but otherwise function as expected.
62 //
63 // REF: https://github.com/acidanthera/bugtracker/issues/1242
64 //
65 if ( (Status == EFI_WRITE_PROTECTED)
66 && (OpenMode == EFI_FILE_MODE_READ)
67 && (Attributes == 0)
68 && (*NewHandle != NULL))
69 {
70 DEBUG ((
71 DEBUG_VERBOSE,
72 "OCFS: Avoid invalid WP error for Filename %s\n",
73 FileName
74 ));
75 Status = EFI_SUCCESS;
76 }
77
78 return Status;
79}
80
81EFI_STATUS
82EFIAPI
84 IN EFI_HANDLE FileSystemHandle,
85 IN CONST EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath,
86 OUT EFI_FILE_PROTOCOL **File,
87 IN UINT64 OpenMode,
88 IN UINT64 Attributes
89 )
90{
91 EFI_STATUS Status;
92 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem;
93 EFI_FILE_PROTOCOL *LastFile;
94 CONST EFI_DEVICE_PATH_PROTOCOL *FilePathNode;
95 CHAR16 *AlignedPathName;
96 CHAR16 *PathName;
97 UINTN PathLength;
98 EFI_FILE_PROTOCOL *NextFile;
99
100 ASSERT (FileSystemHandle != NULL);
101 ASSERT (RemainingDevicePath != NULL);
102 ASSERT (File != NULL);
103
104 Status = gBS->OpenProtocol (
105 FileSystemHandle,
107 (VOID **)&FileSystem,
109 NULL,
110 EFI_OPEN_PROTOCOL_GET_PROTOCOL
111 );
112 if (EFI_ERROR (Status)) {
113 return Status;
114 }
115
116 //
117 // Open the root directory of the filesystem. After this operation succeeds,
118 // we have to release LastFile on error.
119 //
120 Status = FileSystem->OpenVolume (FileSystem, &LastFile);
121 if (EFI_ERROR (Status)) {
122 return Status;
123 }
124
125 //
126 // Traverse the device path nodes relative to the filesystem.
127 //
128 FilePathNode = RemainingDevicePath;
129 while (!IsDevicePathEnd (FilePathNode)) {
130 if ((DevicePathType (FilePathNode) != MEDIA_DEVICE_PATH) ||
131 (DevicePathSubType (FilePathNode) != MEDIA_FILEPATH_DP))
132 {
133 Status = EFI_INVALID_PARAMETER;
134 goto CloseLastFile;
135 }
136
137 //
138 // FilePathNode->PathName may be unaligned, and the UEFI specification
139 // requires pointers that are passed to protocol member functions to be
140 // aligned. Create an aligned copy of the pathname to match that
141 // and to apply the hack below.
142 //
143 AlignedPathName = AllocateCopyPool (
144 (DevicePathNodeLength (FilePathNode) -
145 SIZE_OF_FILEPATH_DEVICE_PATH),
146 ((CONST FILEPATH_DEVICE_PATH *)FilePathNode)->PathName
147 );
148 if (AlignedPathName == NULL) {
149 Status = EFI_OUT_OF_RESOURCES;
150 goto CloseLastFile;
151 }
152
153 //
154 // This is a compatibility hack for firmware types that do not support
155 // opening filepaths (directories) with a trailing slash.
156 // More details in a852f85986c1fe23fc3a429605e3c560ea800c54 OpenCorePkg commit.
157 //
158 PathLength = StrLen (AlignedPathName);
159 if ((PathLength > 0) && (AlignedPathName[PathLength - 1] == '\\')) {
160 AlignedPathName[PathLength - 1] = '\0';
161 }
162
163 PathName = AlignedPathName;
164
165 //
166 // Open or create the file corresponding to the next pathname fragment.
167 //
168 Status = OcSafeFileOpen (
169 LastFile,
170 &NextFile,
171 PathName,
172 OpenMode,
173 Attributes
174 );
175
176 FreePool (AlignedPathName);
177
178 if (EFI_ERROR (Status)) {
179 goto CloseLastFile;
180 }
181
182 //
183 // Advance to the next device path node.
184 //
185 LastFile->Close (LastFile);
186 LastFile = NextFile;
187 FilePathNode = NextDevicePathNode (FilePathNode);
188 }
189
190 *File = LastFile;
191 return EFI_SUCCESS;
192
193CloseLastFile:
194 LastFile->Close (LastFile);
195
196 //
197 // We are on the error path; we must have set an error Status for returning
198 // to the caller.
199 //
200 ASSERT (EFI_ERROR (Status));
201 return Status;
202}
203
204EFI_STATUS
205EFIAPI
207 IN OUT EFI_DEVICE_PATH_PROTOCOL **FilePath,
208 OUT EFI_FILE_PROTOCOL **File,
209 IN UINT64 OpenMode,
210 IN UINT64 Attributes
211 )
212{
213 EFI_STATUS Status;
214 EFI_HANDLE FileSystemHandle;
215
216 ASSERT (File != NULL);
217 ASSERT (FilePath != NULL);
218
219 //
220 // Look up the filesystem.
221 //
222 Status = gBS->LocateDevicePath (
224 FilePath,
225 &FileSystemHandle
226 );
227 if (EFI_ERROR (Status)) {
228 return Status;
229 }
230
232 FileSystemHandle,
233 *FilePath,
234 File,
235 OpenMode,
236 Attributes
237 );
238}
UINT64 Length
CHAR16 PathName[DMG_FILE_PATH_LEN]
DMG_FILEPATH_DEVICE_PATH FilePath
EFI_HANDLE gImageHandle
EFI_BOOT_SERVICES * gBS
EFI_STATUS EFIAPI OcOpenFileByDevicePath(IN OUT EFI_DEVICE_PATH_PROTOCOL **FilePath, OUT EFI_FILE_PROTOCOL **File, IN UINT64 OpenMode, IN UINT64 Attributes)
Definition OpenFile.c:206
EFI_STATUS OcSafeFileOpen(IN CONST EFI_FILE_PROTOCOL *Directory, OUT EFI_FILE_PROTOCOL **NewHandle, IN CONST CHAR16 *FileName, IN CONST UINT64 OpenMode, IN CONST UINT64 Attributes)
Definition OpenFile.c:29
EFI_STATUS EFIAPI OcOpenFileByRemainingDevicePath(IN EFI_HANDLE FileSystemHandle, IN CONST EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath, OUT EFI_FILE_PROTOCOL **File, IN UINT64 OpenMode, IN UINT64 Attributes)
Definition OpenFile.c:83
EFI_GUID gEfiSimpleFileSystemProtocolGuid
#define ASSERT(x)
Definition coder.h:55