]> git.proxmox.com Git - mirror_edk2.git/blob - FatPkg/EnhancedFatDxe/Open.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / FatPkg / EnhancedFatDxe / Open.c
1 /** @file
2 Routines dealing with file open.
3
4 Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
9 #include "Fat.h"
10
11 /**
12
13 Create an Open instance for the existing OFile.
14 The IFile of the newly opened file is passed out.
15
16 @param OFile - The file that serves as a starting reference point.
17 @param PtrIFile - The newly generated IFile instance.
18
19 @retval EFI_OUT_OF_RESOURCES - Can not allocate the memory for the IFile
20 @retval EFI_SUCCESS - Create the new IFile for the OFile successfully
21
22 **/
23 EFI_STATUS
24 FatAllocateIFile (
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
62 /**
63
64 Open a file for a file name relative to an existing OFile.
65 The IFile of the newly opened file is passed out.
66
67 @param OFile - The file that serves as a starting reference point.
68 @param NewIFile - The newly generated IFile instance.
69 @param FileName - The file name relative to the OFile.
70 @param OpenMode - Open mode.
71 @param Attributes - Attributes to set if the file is created.
72
73
74 @retval EFI_SUCCESS - Open the file successfully.
75 @retval EFI_INVALID_PARAMETER - The open mode is conflict with the attributes
76 or the file name is not valid.
77 @retval EFI_NOT_FOUND - Conflicts between dir intention and attribute.
78 @retval EFI_WRITE_PROTECTED - Can't open for write if the volume is read only.
79 @retval EFI_ACCESS_DENIED - If the file's attribute is read only, and the
80 open is for read-write fail it.
81 @retval EFI_OUT_OF_RESOURCES - Can not allocate the memory.
82
83 **/
84 EFI_STATUS
85 FatOFileOpen (
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
179 /**
180
181 Implements OpenEx() of Simple File System Protocol.
182
183 @param FHand - File handle of the file serves as a starting reference point.
184 @param NewHandle - Handle of the file that is newly opened.
185 @param FileName - File name relative to FHand.
186 @param OpenMode - Open mode.
187 @param Attributes - Attributes to set if the file is created.
188 @param Token - A pointer to the token associated with the transaction.:
189
190 @retval EFI_INVALID_PARAMETER - The FileName is NULL or the file string is empty.
191 The OpenMode is not supported.
192 The Attributes is not the valid attributes.
193 @retval EFI_OUT_OF_RESOURCES - Can not allocate the memory for file string.
194 @retval EFI_SUCCESS - Open the file successfully.
195 @return Others - The status of open file.
196
197 **/
198 EFI_STATUS
199 EFIAPI
200 FatOpenEx (
201 IN EFI_FILE_PROTOCOL *FHand,
202 OUT EFI_FILE_PROTOCOL **NewHandle,
203 IN CHAR16 *FileName,
204 IN UINT64 OpenMode,
205 IN UINT64 Attributes,
206 IN OUT EFI_FILE_IO_TOKEN *Token
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) {
247 FatWaitNonblockingTask (IFile);
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 //
266 FatAcquireLock ();
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);
284 FatReleaseLock ();
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
297 /**
298
299 Implements Open() of Simple File System Protocol.
300
301
302 @param FHand - File handle of the file serves as a starting reference point.
303 @param NewHandle - Handle of the file that is newly opened.
304 @param FileName - File name relative to FHand.
305 @param OpenMode - Open mode.
306 @param Attributes - Attributes to set if the file is created.
307
308 @retval EFI_INVALID_PARAMETER - The FileName is NULL or the file string is empty.
309 The OpenMode is not supported.
310 The Attributes is not the valid attributes.
311 @retval EFI_OUT_OF_RESOURCES - Can not allocate the memory for file string.
312 @retval EFI_SUCCESS - Open the file successfully.
313 @return Others - The status of open file.
314
315 **/
316 EFI_STATUS
317 EFIAPI
318 FatOpen (
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 }