TianoCore EDK2 master
Loading...
Searching...
No Matches
Open.c
Go to the documentation of this file.
1
9#include "Fat.h"
10
25 IN FAT_OFILE *OFile,
26 OUT FAT_IFILE **PtrIFile
27 )
28{
29 FAT_IFILE *IFile;
30
31 ASSERT_VOLUME_LOCKED (OFile->Volume);
32
33 //
34 // Allocate a new open instance
35 //
36 IFile = AllocateZeroPool (sizeof (FAT_IFILE));
37 if (IFile == NULL) {
38 return EFI_OUT_OF_RESOURCES;
39 }
40
41 IFile->Signature = FAT_IFILE_SIGNATURE;
42
43 CopyMem (&(IFile->Handle), &FatFileInterface, sizeof (EFI_FILE_PROTOCOL));
44
45 //
46 // Report the correct revision number based on the DiskIo2 availability
47 //
48 if (OFile->Volume->DiskIo2 != NULL) {
49 IFile->Handle.Revision = EFI_FILE_PROTOCOL_REVISION2;
50 } else {
51 IFile->Handle.Revision = EFI_FILE_PROTOCOL_REVISION;
52 }
53
54 IFile->OFile = OFile;
55 InsertTailList (&OFile->Opens, &IFile->Link);
56 InitializeListHead (&IFile->Tasks);
57
58 *PtrIFile = IFile;
59 return EFI_SUCCESS;
60}
61
86 IN FAT_OFILE *OFile,
87 OUT FAT_IFILE **NewIFile,
88 IN CHAR16 *FileName,
89 IN UINT64 OpenMode,
90 IN UINT8 Attributes
91 )
92{
93 FAT_VOLUME *Volume;
94 EFI_STATUS Status;
95 CHAR16 NewFileName[EFI_PATH_STRING_LENGTH];
96 FAT_DIRENT *DirEnt;
97 UINT8 FileAttributes;
98 BOOLEAN WriteMode;
99
100 DirEnt = NULL;
101 Volume = OFile->Volume;
102 ASSERT_VOLUME_LOCKED (Volume);
103 WriteMode = (BOOLEAN)(OpenMode & EFI_FILE_MODE_WRITE);
104 if (Volume->ReadOnly && WriteMode) {
105 return EFI_WRITE_PROTECTED;
106 }
107
108 //
109 // Verify the source file handle isn't in an error state
110 //
111 Status = OFile->Error;
112 if (EFI_ERROR (Status)) {
113 return Status;
114 }
115
116 //
117 // Get new OFile for the file
118 //
119 Status = FatLocateOFile (&OFile, FileName, Attributes, NewFileName);
120 if (EFI_ERROR (Status)) {
121 return Status;
122 }
123
124 if (*NewFileName != 0) {
125 //
126 // If there's a remaining part of the name, then we had
127 // better be creating the file in the directory
128 //
129 if ((OpenMode & EFI_FILE_MODE_CREATE) == 0) {
130 return EFI_NOT_FOUND;
131 }
132
133 Status = FatCreateDirEnt (OFile, NewFileName, Attributes, &DirEnt);
134 if (EFI_ERROR (Status)) {
135 return Status;
136 }
137
138 ASSERT (DirEnt != NULL);
139 Status = FatOpenDirEnt (OFile, DirEnt);
140 if (EFI_ERROR (Status)) {
141 return Status;
142 }
143
144 OFile = DirEnt->OFile;
145 if (OFile->ODir != NULL) {
146 //
147 // If we just created a directory, we need to create "." and ".."
148 //
149 Status = FatCreateDotDirEnts (OFile);
150 if (EFI_ERROR (Status)) {
151 return Status;
152 }
153 }
154 }
155
156 //
157 // If the file's attribute is read only, and the open is for
158 // read-write, then the access is denied.
159 //
160 FileAttributes = OFile->DirEnt->Entry.Attributes;
161 if (((FileAttributes & EFI_FILE_READ_ONLY) != 0) && ((FileAttributes & FAT_ATTRIBUTE_DIRECTORY) == 0) && WriteMode) {
162 return EFI_ACCESS_DENIED;
163 }
164
165 //
166 // Create an open instance of the OFile
167 //
168 Status = FatAllocateIFile (OFile, NewIFile);
169 if (EFI_ERROR (Status)) {
170 return Status;
171 }
172
173 (*NewIFile)->ReadOnly = (BOOLEAN) !WriteMode;
174
175 DEBUG ((DEBUG_INFO, "FSOpen: Open '%S' %r\n", FileName, Status));
176 return FatOFileFlush (OFile);
177}
178
199EFIAPI
201 IN EFI_FILE_PROTOCOL *FHand,
202 OUT EFI_FILE_PROTOCOL **NewHandle,
203 IN CHAR16 *FileName,
204 IN UINT64 OpenMode,
205 IN UINT64 Attributes,
207 )
208{
209 FAT_IFILE *IFile;
210 FAT_IFILE *NewIFile;
211 FAT_OFILE *OFile;
212 EFI_STATUS Status;
213 FAT_TASK *Task;
214
215 //
216 // Perform some parameter checking
217 //
218 if (FileName == NULL) {
219 return EFI_INVALID_PARAMETER;
220 }
221
222 //
223 // Check for a valid mode
224 //
225 switch (OpenMode) {
226 case EFI_FILE_MODE_READ:
227 case EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE:
228 case EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE:
229 break;
230
231 default:
232 return EFI_INVALID_PARAMETER;
233 }
234
235 //
236 // Check for valid Attributes for file creation case.
237 //
238 if (((OpenMode & EFI_FILE_MODE_CREATE) != 0) && ((Attributes & (EFI_FILE_READ_ONLY | (~EFI_FILE_VALID_ATTR))) != 0)) {
239 return EFI_INVALID_PARAMETER;
240 }
241
242 IFile = IFILE_FROM_FHAND (FHand);
243 OFile = IFile->OFile;
244 Task = NULL;
245
246 if (Token == NULL) {
248 } else {
249 //
250 // Caller shouldn't call the non-blocking interfaces if the low layer doesn't support DiskIo2.
251 // But if it calls, the below check can avoid crash.
252 //
253 if (FHand->Revision < EFI_FILE_PROTOCOL_REVISION2) {
254 return EFI_UNSUPPORTED;
255 }
256
257 Task = FatCreateTask (IFile, Token);
258 if (Task == NULL) {
259 return EFI_OUT_OF_RESOURCES;
260 }
261 }
262
263 //
264 // Lock
265 //
267
268 //
269 // Open the file
270 //
271 Status = FatOFileOpen (OFile, &NewIFile, FileName, OpenMode, (UINT8)Attributes);
272
273 //
274 // If the file was opened, return the handle to the caller
275 //
276 if (!EFI_ERROR (Status)) {
277 *NewHandle = &NewIFile->Handle;
278 }
279
280 //
281 // Unlock
282 //
283 Status = FatCleanupVolume (OFile->Volume, NULL, Status, Task);
285
286 if (Token != NULL) {
287 if (!EFI_ERROR (Status)) {
288 Status = FatQueueTask (IFile, Task);
289 } else {
290 FatDestroyTask (Task);
291 }
292 }
293
294 return Status;
295}
296
317EFIAPI
319 IN EFI_FILE_PROTOCOL *FHand,
320 OUT EFI_FILE_PROTOCOL **NewHandle,
321 IN CHAR16 *FileName,
322 IN UINT64 OpenMode,
323 IN UINT64 Attributes
324 )
325{
326 return FatOpenEx (FHand, NewHandle, FileName, OpenMode, Attributes, NULL);
327}
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)
EFI_STATUS FatCreateDirEnt(IN FAT_OFILE *OFile, IN CHAR16 *FileName, IN UINT8 Attributes, OUT FAT_DIRENT **PtrDirEnt)
EFI_STATUS FatOpenDirEnt(IN FAT_OFILE *Parent, IN FAT_DIRENT *DirEnt)
EFI_STATUS FatLocateOFile(IN OUT FAT_OFILE **PtrOFile, IN CHAR16 *FileName, IN UINT8 Attributes, OUT CHAR16 *NewFileName)
EFI_STATUS FatCreateDotDirEnts(IN FAT_OFILE *OFile)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID FatDestroyTask(FAT_TASK *Task)
Definition: Misc.c:51
FAT_TASK * FatCreateTask(FAT_IFILE *IFile, EFI_FILE_IO_TOKEN *Token)
Definition: Misc.c:24
EFI_STATUS FatQueueTask(IN FAT_IFILE *IFile, IN FAT_TASK *Task)
Definition: Misc.c:124
EFI_STATUS FatOFileFlush(IN FAT_OFILE *OFile)
Definition: Flush.c:218
VOID FatWaitNonblockingTask(FAT_IFILE *IFile)
Definition: Misc.c:75
VOID FatAcquireLock(VOID)
Definition: Misc.c:395
VOID FatReleaseLock(VOID)
Definition: Misc.c:426
EFI_STATUS FatCleanupVolume(IN FAT_VOLUME *Volume, IN FAT_OFILE *OFile, IN EFI_STATUS EfiStatus, IN FAT_TASK *Task)
Definition: Flush.c:382
#define NULL
Definition: Base.h:319
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define DEBUG(Expression)
Definition: DebugLib.h:434
EFI_STATUS FatAllocateIFile(IN FAT_OFILE *OFile, OUT FAT_IFILE **PtrIFile)
Definition: Open.c:24
EFI_STATUS EFIAPI FatOpenEx(IN EFI_FILE_PROTOCOL *FHand, OUT EFI_FILE_PROTOCOL **NewHandle, IN CHAR16 *FileName, IN UINT64 OpenMode, IN UINT64 Attributes, IN OUT EFI_FILE_IO_TOKEN *Token)
Definition: Open.c:200
EFI_STATUS EFIAPI FatOpen(IN EFI_FILE_PROTOCOL *FHand, OUT EFI_FILE_PROTOCOL **NewHandle, IN CHAR16 *FileName, IN UINT64 OpenMode, IN UINT64 Attributes)
Definition: Open.c:318
EFI_STATUS FatOFileOpen(IN FAT_OFILE *OFile, OUT FAT_IFILE **NewIFile, IN CHAR16 *FileName, IN UINT64 OpenMode, IN UINT8 Attributes)
Definition: Open.c:85
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
Definition: Fat.h:217
Definition: Fat.h:227