]> git.proxmox.com Git - mirror_edk2.git/blame - FatPkg/EnhancedFatDxe/Open.c
BaseTools: Library hashing fix and optimization for --hash feature
[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
25 IN FAT_OFILE *OFile,\r
26 OUT FAT_IFILE **PtrIFile\r
27 )\r
b9ec9330
QH
28{\r
29 FAT_IFILE *IFile;\r
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
cae7420b
DB
77 @retval EFI_NOT_FOUND - Conficts between dir intention and attribute.\r
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
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
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
103 WriteMode = (BOOLEAN) (OpenMode & EFI_FILE_MODE_WRITE);\r
104 if (Volume->ReadOnly && WriteMode) {\r
105 return EFI_WRITE_PROTECTED;\r
106 }\r
107 //\r
108 // Verify the source file handle isn't in an error state\r
109 //\r
110 Status = OFile->Error;\r
111 if (EFI_ERROR (Status)) {\r
112 return Status;\r
113 }\r
114 //\r
115 // Get new OFile for the file\r
116 //\r
117 Status = FatLocateOFile (&OFile, FileName, Attributes, NewFileName);\r
118 if (EFI_ERROR (Status)) {\r
119 return Status;\r
120 }\r
121\r
122 if (*NewFileName != 0) {\r
123 //\r
124 // If there's a remaining part of the name, then we had\r
125 // better be creating the file in the directory\r
126 //\r
127 if ((OpenMode & EFI_FILE_MODE_CREATE) == 0) {\r
128 return EFI_NOT_FOUND;\r
129 }\r
130\r
131 Status = FatCreateDirEnt (OFile, NewFileName, Attributes, &DirEnt);\r
132 if (EFI_ERROR (Status)) {\r
133 return Status;\r
134 }\r
135\r
944ac8ab 136 ASSERT (DirEnt != NULL);\r
b9ec9330
QH
137 Status = FatOpenDirEnt (OFile, DirEnt);\r
138 if (EFI_ERROR (Status)) {\r
139 return Status;\r
140 }\r
141\r
142 OFile = DirEnt->OFile;\r
143 if (OFile->ODir != NULL) {\r
144 //\r
145 // If we just created a directory, we need to create "." and ".."\r
146 //\r
147 Status = FatCreateDotDirEnts (OFile);\r
148 if (EFI_ERROR (Status)) {\r
149 return Status;\r
150 }\r
151 }\r
152 }\r
153 //\r
154 // If the file's attribute is read only, and the open is for\r
155 // read-write, then the access is denied.\r
156 //\r
157 FileAttributes = OFile->DirEnt->Entry.Attributes;\r
158 if ((FileAttributes & EFI_FILE_READ_ONLY) != 0 && (FileAttributes & FAT_ATTRIBUTE_DIRECTORY) == 0 && WriteMode) {\r
159 return EFI_ACCESS_DENIED;\r
160 }\r
161 //\r
162 // Create an open instance of the OFile\r
163 //\r
164 Status = FatAllocateIFile (OFile, NewIFile);\r
165 if (EFI_ERROR (Status)) {\r
166 return Status;\r
167 }\r
168\r
169 (*NewIFile)->ReadOnly = (BOOLEAN)!WriteMode;\r
170\r
171 DEBUG ((EFI_D_INFO, "FSOpen: Open '%S' %r\n", FileName, Status));\r
172 return FatOFileFlush (OFile);\r
173}\r
174\r
cae7420b
DB
175/**\r
176\r
177 Implements OpenEx() of Simple File System Protocol.\r
178\r
179 @param FHand - File handle of the file serves as a starting reference point.\r
180 @param NewHandle - Handle of the file that is newly opened.\r
181 @param FileName - File name relative to FHand.\r
182 @param OpenMode - Open mode.\r
183 @param Attributes - Attributes to set if the file is created.\r
184 @param Token - A pointer to the token associated with the transaction.:\r
185\r
186 @retval EFI_INVALID_PARAMETER - The FileName is NULL or the file string is empty.\r
187 The OpenMode is not supported.\r
188 The Attributes is not the valid attributes.\r
189 @retval EFI_OUT_OF_RESOURCES - Can not allocate the memory for file string.\r
190 @retval EFI_SUCCESS - Open the file successfully.\r
191 @return Others - The status of open file.\r
192\r
193**/\r
b9ec9330 194EFI_STATUS\r
833b5a77 195EFIAPI\r
149d6335
RN
196FatOpenEx (\r
197 IN EFI_FILE_PROTOCOL *FHand,\r
198 OUT EFI_FILE_PROTOCOL **NewHandle,\r
199 IN CHAR16 *FileName,\r
200 IN UINT64 OpenMode,\r
201 IN UINT64 Attributes,\r
202 IN OUT EFI_FILE_IO_TOKEN *Token\r
b9ec9330 203 )\r
b9ec9330
QH
204{\r
205 FAT_IFILE *IFile;\r
206 FAT_IFILE *NewIFile;\r
207 FAT_OFILE *OFile;\r
208 EFI_STATUS Status;\r
149d6335 209 FAT_TASK *Task;\r
b9ec9330
QH
210\r
211 //\r
212 // Perform some parameter checking\r
213 //\r
214 if (FileName == NULL) {\r
215 return EFI_INVALID_PARAMETER;\r
216 }\r
217 //\r
218 // Check for a valid mode\r
219 //\r
220 switch (OpenMode) {\r
221 case EFI_FILE_MODE_READ:\r
222 case EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE:\r
223 case EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE:\r
224 break;\r
225\r
226 default:\r
227 return EFI_INVALID_PARAMETER;\r
228 }\r
149d6335 229\r
b9ec9330 230 //\r
e38f26a2 231 // Check for valid Attributes for file creation case.\r
b9ec9330 232 //\r
5ff2f40e 233 if (((OpenMode & EFI_FILE_MODE_CREATE) != 0) && (Attributes & (EFI_FILE_READ_ONLY | (~EFI_FILE_VALID_ATTR))) != 0) {\r
149d6335 234 return EFI_INVALID_PARAMETER;\r
b9ec9330 235 }\r
149d6335 236\r
b9ec9330
QH
237 IFile = IFILE_FROM_FHAND (FHand);\r
238 OFile = IFile->OFile;\r
149d6335
RN
239 Task = NULL;\r
240\r
241 if (Token == NULL) {\r
242 FatWaitNonblockingTask (IFile);\r
243 } else {\r
244 //\r
245 // Caller shouldn't call the non-blocking interfaces if the low layer doesn't support DiskIo2.\r
246 // But if it calls, the below check can avoid crash.\r
247 //\r
248 if (FHand->Revision < EFI_FILE_PROTOCOL_REVISION2) {\r
249 return EFI_UNSUPPORTED;\r
250 }\r
251 Task = FatCreateTask (IFile, Token);\r
252 if (Task == NULL) {\r
253 return EFI_OUT_OF_RESOURCES;\r
254 }\r
255 }\r
b9ec9330
QH
256\r
257 //\r
258 // Lock\r
259 //\r
260 FatAcquireLock ();\r
261\r
262 //\r
263 // Open the file\r
264 //\r
265 Status = FatOFileOpen (OFile, &NewIFile, FileName, OpenMode, (UINT8) Attributes);\r
266\r
267 //\r
268 // If the file was opened, return the handle to the caller\r
269 //\r
270 if (!EFI_ERROR (Status)) {\r
271 *NewHandle = &NewIFile->Handle;\r
272 }\r
273 //\r
274 // Unlock\r
275 //\r
149d6335 276 Status = FatCleanupVolume (OFile->Volume, NULL, Status, Task);\r
b9ec9330
QH
277 FatReleaseLock ();\r
278\r
149d6335
RN
279 if (Token != NULL) {\r
280 if (!EFI_ERROR (Status)) {\r
281 Status = FatQueueTask (IFile, Task);\r
282 } else {\r
283 FatDestroyTask (Task);\r
284 }\r
285 }\r
286\r
b9ec9330
QH
287 return Status;\r
288}\r
149d6335 289\r
cae7420b
DB
290/**\r
291\r
292 Implements Open() of Simple File System Protocol.\r
293\r
294\r
295 @param FHand - File handle of the file serves as a starting reference point.\r
296 @param NewHandle - Handle of the file that is newly opened.\r
297 @param FileName - File name relative to FHand.\r
298 @param OpenMode - Open mode.\r
299 @param Attributes - Attributes to set if the file is created.\r
300\r
301 @retval EFI_INVALID_PARAMETER - The FileName is NULL or the file string is empty.\r
302 The OpenMode is not supported.\r
303 The Attributes is not the valid attributes.\r
304 @retval EFI_OUT_OF_RESOURCES - Can not allocate the memory for file string.\r
305 @retval EFI_SUCCESS - Open the file successfully.\r
306 @return Others - The status of open file.\r
307\r
308**/\r
149d6335
RN
309EFI_STATUS\r
310EFIAPI\r
311FatOpen (\r
312 IN EFI_FILE_PROTOCOL *FHand,\r
313 OUT EFI_FILE_PROTOCOL **NewHandle,\r
314 IN CHAR16 *FileName,\r
315 IN UINT64 OpenMode,\r
316 IN UINT64 Attributes\r
317 )\r
149d6335
RN
318{\r
319 return FatOpenEx (FHand, NewHandle, FileName, OpenMode, Attributes, NULL);\r
320}\r