]> git.proxmox.com Git - mirror_edk2.git/blame - FatPkg/EnhancedFatDxe/Open.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / FatPkg / EnhancedFatDxe / Open.c
CommitLineData
cae7420b
DB
1/** @file\r
2 Routines dealing with file open.\r
b9ec9330 3\r
e38f26a2 4Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>\r
eb6cb4ce 5SPDX-License-Identifier: BSD-2-Clause-Patent\r
b9ec9330 6\r
cae7420b 7**/\r
b9ec9330 8\r
cae7420b 9#include "Fat.h"\r
b9ec9330 10\r
cae7420b 11/**\r
b9ec9330 12\r
cae7420b
DB
13 Create an Open instance for the existing OFile.\r
14 The IFile of the newly opened file is passed out.\r
b9ec9330 15\r
cae7420b
DB
16 @param OFile - The file that serves as a starting reference point.\r
17 @param PtrIFile - The newly generated IFile instance.\r
b9ec9330 18\r
cae7420b
DB
19 @retval EFI_OUT_OF_RESOURCES - Can not allocate the memory for the IFile\r
20 @retval EFI_SUCCESS - Create the new IFile for the OFile successfully\r
b9ec9330 21\r
cae7420b 22**/\r
b9ec9330
QH
23EFI_STATUS\r
24FatAllocateIFile (\r
bcdcc416
MK
25 IN FAT_OFILE *OFile,\r
26 OUT FAT_IFILE **PtrIFile\r
b9ec9330 27 )\r
b9ec9330 28{\r
bcdcc416 29 FAT_IFILE *IFile;\r
b9ec9330
QH
30\r
31 ASSERT_VOLUME_LOCKED (OFile->Volume);\r
32\r
33 //\r
34 // Allocate a new open instance\r
35 //\r
36 IFile = AllocateZeroPool (sizeof (FAT_IFILE));\r
37 if (IFile == NULL) {\r
38 return EFI_OUT_OF_RESOURCES;\r
39 }\r
40\r
41 IFile->Signature = FAT_IFILE_SIGNATURE;\r
42\r
dba03ba1 43 CopyMem (&(IFile->Handle), &FatFileInterface, sizeof (EFI_FILE_PROTOCOL));\r
b9ec9330 44\r
149d6335
RN
45 //\r
46 // Report the correct revision number based on the DiskIo2 availability\r
47 //\r
48 if (OFile->Volume->DiskIo2 != NULL) {\r
49 IFile->Handle.Revision = EFI_FILE_PROTOCOL_REVISION2;\r
50 } else {\r
51 IFile->Handle.Revision = EFI_FILE_PROTOCOL_REVISION;\r
52 }\r
53\r
b9ec9330
QH
54 IFile->OFile = OFile;\r
55 InsertTailList (&OFile->Opens, &IFile->Link);\r
149d6335 56 InitializeListHead (&IFile->Tasks);\r
b9ec9330
QH
57\r
58 *PtrIFile = IFile;\r
59 return EFI_SUCCESS;\r
60}\r
61\r
cae7420b 62/**\r
b9ec9330
QH
63\r
64 Open a file for a file name relative to an existing OFile.\r
65 The IFile of the newly opened file is passed out.\r
66\r
cae7420b
DB
67 @param OFile - The file that serves as a starting reference point.\r
68 @param NewIFile - The newly generated IFile instance.\r
69 @param FileName - The file name relative to the OFile.\r
70 @param OpenMode - Open mode.\r
71 @param Attributes - Attributes to set if the file is created.\r
b9ec9330 72\r
b9ec9330 73\r
cae7420b
DB
74 @retval EFI_SUCCESS - Open the file successfully.\r
75 @retval EFI_INVALID_PARAMETER - The open mode is conflict with the attributes\r
b9ec9330 76 or the file name is not valid.\r
44c9618a 77 @retval EFI_NOT_FOUND - Conflicts between dir intention and attribute.\r
cae7420b
DB
78 @retval EFI_WRITE_PROTECTED - Can't open for write if the volume is read only.\r
79 @retval EFI_ACCESS_DENIED - If the file's attribute is read only, and the\r
b9ec9330 80 open is for read-write fail it.\r
cae7420b 81 @retval EFI_OUT_OF_RESOURCES - Can not allocate the memory.\r
b9ec9330 82\r
cae7420b
DB
83**/\r
84EFI_STATUS\r
85FatOFileOpen (\r
bcdcc416
MK
86 IN FAT_OFILE *OFile,\r
87 OUT FAT_IFILE **NewIFile,\r
88 IN CHAR16 *FileName,\r
89 IN UINT64 OpenMode,\r
90 IN UINT8 Attributes\r
cae7420b 91 )\r
b9ec9330
QH
92{\r
93 FAT_VOLUME *Volume;\r
94 EFI_STATUS Status;\r
95 CHAR16 NewFileName[EFI_PATH_STRING_LENGTH];\r
96 FAT_DIRENT *DirEnt;\r
97 UINT8 FileAttributes;\r
98 BOOLEAN WriteMode;\r
99\r
944ac8ab 100 DirEnt = NULL;\r
b9ec9330
QH
101 Volume = OFile->Volume;\r
102 ASSERT_VOLUME_LOCKED (Volume);\r
bcdcc416 103 WriteMode = (BOOLEAN)(OpenMode & EFI_FILE_MODE_WRITE);\r
b9ec9330
QH
104 if (Volume->ReadOnly && WriteMode) {\r
105 return EFI_WRITE_PROTECTED;\r
106 }\r
bcdcc416 107\r
b9ec9330
QH
108 //\r
109 // Verify the source file handle isn't in an error state\r
110 //\r
111 Status = OFile->Error;\r
112 if (EFI_ERROR (Status)) {\r
113 return Status;\r
114 }\r
bcdcc416 115\r
b9ec9330
QH
116 //\r
117 // Get new OFile for the file\r
118 //\r
119 Status = FatLocateOFile (&OFile, FileName, Attributes, NewFileName);\r
120 if (EFI_ERROR (Status)) {\r
121 return Status;\r
122 }\r
123\r
124 if (*NewFileName != 0) {\r
125 //\r
126 // If there's a remaining part of the name, then we had\r
127 // better be creating the file in the directory\r
128 //\r
129 if ((OpenMode & EFI_FILE_MODE_CREATE) == 0) {\r
130 return EFI_NOT_FOUND;\r
131 }\r
132\r
133 Status = FatCreateDirEnt (OFile, NewFileName, Attributes, &DirEnt);\r
134 if (EFI_ERROR (Status)) {\r
135 return Status;\r
136 }\r
137\r
944ac8ab 138 ASSERT (DirEnt != NULL);\r
b9ec9330
QH
139 Status = FatOpenDirEnt (OFile, DirEnt);\r
140 if (EFI_ERROR (Status)) {\r
141 return Status;\r
142 }\r
143\r
144 OFile = DirEnt->OFile;\r
145 if (OFile->ODir != NULL) {\r
146 //\r
147 // If we just created a directory, we need to create "." and ".."\r
148 //\r
149 Status = FatCreateDotDirEnts (OFile);\r
150 if (EFI_ERROR (Status)) {\r
151 return Status;\r
152 }\r
153 }\r
154 }\r
bcdcc416 155\r
b9ec9330
QH
156 //\r
157 // If the file's attribute is read only, and the open is for\r
158 // read-write, then the access is denied.\r
159 //\r
160 FileAttributes = OFile->DirEnt->Entry.Attributes;\r
bcdcc416 161 if (((FileAttributes & EFI_FILE_READ_ONLY) != 0) && ((FileAttributes & FAT_ATTRIBUTE_DIRECTORY) == 0) && WriteMode) {\r
b9ec9330
QH
162 return EFI_ACCESS_DENIED;\r
163 }\r
bcdcc416 164\r
b9ec9330
QH
165 //\r
166 // Create an open instance of the OFile\r
167 //\r
168 Status = FatAllocateIFile (OFile, NewIFile);\r
169 if (EFI_ERROR (Status)) {\r
170 return Status;\r
171 }\r
172\r
bcdcc416 173 (*NewIFile)->ReadOnly = (BOOLEAN) !WriteMode;\r
b9ec9330 174\r
917e98f3 175 DEBUG ((DEBUG_INFO, "FSOpen: Open '%S' %r\n", FileName, Status));\r
b9ec9330
QH
176 return FatOFileFlush (OFile);\r
177}\r
178\r
cae7420b
DB
179/**\r
180\r
181 Implements OpenEx() of Simple File System Protocol.\r
182\r
183 @param FHand - File handle of the file serves as a starting reference point.\r
184 @param NewHandle - Handle of the file that is newly opened.\r
185 @param FileName - File name relative to FHand.\r
186 @param OpenMode - Open mode.\r
187 @param Attributes - Attributes to set if the file is created.\r
188 @param Token - A pointer to the token associated with the transaction.:\r
189\r
190 @retval EFI_INVALID_PARAMETER - The FileName is NULL or the file string is empty.\r
191 The OpenMode is not supported.\r
192 The Attributes is not the valid attributes.\r
193 @retval EFI_OUT_OF_RESOURCES - Can not allocate the memory for file string.\r
194 @retval EFI_SUCCESS - Open the file successfully.\r
195 @return Others - The status of open file.\r
196\r
197**/\r
b9ec9330 198EFI_STATUS\r
833b5a77 199EFIAPI\r
149d6335 200FatOpenEx (\r
bcdcc416
MK
201 IN EFI_FILE_PROTOCOL *FHand,\r
202 OUT EFI_FILE_PROTOCOL **NewHandle,\r
203 IN CHAR16 *FileName,\r
204 IN UINT64 OpenMode,\r
205 IN UINT64 Attributes,\r
206 IN OUT EFI_FILE_IO_TOKEN *Token\r
b9ec9330 207 )\r
b9ec9330
QH
208{\r
209 FAT_IFILE *IFile;\r
210 FAT_IFILE *NewIFile;\r
211 FAT_OFILE *OFile;\r
212 EFI_STATUS Status;\r
149d6335 213 FAT_TASK *Task;\r
b9ec9330
QH
214\r
215 //\r
216 // Perform some parameter checking\r
217 //\r
218 if (FileName == NULL) {\r
219 return EFI_INVALID_PARAMETER;\r
220 }\r
bcdcc416 221\r
b9ec9330
QH
222 //\r
223 // Check for a valid mode\r
224 //\r
225 switch (OpenMode) {\r
bcdcc416
MK
226 case EFI_FILE_MODE_READ:\r
227 case EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE:\r
228 case EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE:\r
229 break;\r
b9ec9330 230\r
bcdcc416
MK
231 default:\r
232 return EFI_INVALID_PARAMETER;\r
b9ec9330 233 }\r
149d6335 234\r
b9ec9330 235 //\r
e38f26a2 236 // Check for valid Attributes for file creation case.\r
b9ec9330 237 //\r
bcdcc416 238 if (((OpenMode & EFI_FILE_MODE_CREATE) != 0) && ((Attributes & (EFI_FILE_READ_ONLY | (~EFI_FILE_VALID_ATTR))) != 0)) {\r
149d6335 239 return EFI_INVALID_PARAMETER;\r
b9ec9330 240 }\r
149d6335 241\r
b9ec9330
QH
242 IFile = IFILE_FROM_FHAND (FHand);\r
243 OFile = IFile->OFile;\r
149d6335
RN
244 Task = NULL;\r
245\r
246 if (Token == NULL) {\r
247 FatWaitNonblockingTask (IFile);\r
248 } else {\r
249 //\r
250 // Caller shouldn't call the non-blocking interfaces if the low layer doesn't support DiskIo2.\r
251 // But if it calls, the below check can avoid crash.\r
252 //\r
253 if (FHand->Revision < EFI_FILE_PROTOCOL_REVISION2) {\r
254 return EFI_UNSUPPORTED;\r
255 }\r
bcdcc416 256\r
149d6335
RN
257 Task = FatCreateTask (IFile, Token);\r
258 if (Task == NULL) {\r
259 return EFI_OUT_OF_RESOURCES;\r
260 }\r
261 }\r
b9ec9330
QH
262\r
263 //\r
264 // Lock\r
265 //\r
266 FatAcquireLock ();\r
267\r
268 //\r
269 // Open the file\r
270 //\r
bcdcc416 271 Status = FatOFileOpen (OFile, &NewIFile, FileName, OpenMode, (UINT8)Attributes);\r
b9ec9330
QH
272\r
273 //\r
274 // If the file was opened, return the handle to the caller\r
275 //\r
276 if (!EFI_ERROR (Status)) {\r
277 *NewHandle = &NewIFile->Handle;\r
278 }\r
bcdcc416 279\r
b9ec9330
QH
280 //\r
281 // Unlock\r
282 //\r
149d6335 283 Status = FatCleanupVolume (OFile->Volume, NULL, Status, Task);\r
b9ec9330
QH
284 FatReleaseLock ();\r
285\r
149d6335
RN
286 if (Token != NULL) {\r
287 if (!EFI_ERROR (Status)) {\r
288 Status = FatQueueTask (IFile, Task);\r
289 } else {\r
290 FatDestroyTask (Task);\r
291 }\r
292 }\r
293\r
b9ec9330
QH
294 return Status;\r
295}\r
149d6335 296\r
cae7420b
DB
297/**\r
298\r
299 Implements Open() of Simple File System Protocol.\r
300\r
301\r
302 @param FHand - File handle of the file serves as a starting reference point.\r
303 @param NewHandle - Handle of the file that is newly opened.\r
304 @param FileName - File name relative to FHand.\r
305 @param OpenMode - Open mode.\r
306 @param Attributes - Attributes to set if the file is created.\r
307\r
308 @retval EFI_INVALID_PARAMETER - The FileName is NULL or the file string is empty.\r
309 The OpenMode is not supported.\r
310 The Attributes is not the valid attributes.\r
311 @retval EFI_OUT_OF_RESOURCES - Can not allocate the memory for file string.\r
312 @retval EFI_SUCCESS - Open the file successfully.\r
313 @return Others - The status of open file.\r
314\r
315**/\r
149d6335
RN
316EFI_STATUS\r
317EFIAPI\r
318FatOpen (\r
bcdcc416
MK
319 IN EFI_FILE_PROTOCOL *FHand,\r
320 OUT EFI_FILE_PROTOCOL **NewHandle,\r
321 IN CHAR16 *FileName,\r
322 IN UINT64 OpenMode,\r
323 IN UINT64 Attributes\r
149d6335 324 )\r
149d6335
RN
325{\r
326 return FatOpenEx (FHand, NewHandle, FileName, OpenMode, Attributes, NULL);\r
327}\r