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