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