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