2 Routines dealing with file open.
4 Copyright (c) 2005 - 2014, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials are licensed and made available
6 under the terms and conditions of the BSD License which accompanies this
7 distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 Create an Open instance for the existing OFile.
20 The IFile of the newly opened file is passed out.
22 @param OFile - The file that serves as a starting reference point.
23 @param PtrIFile - The newly generated IFile instance.
25 @retval EFI_OUT_OF_RESOURCES - Can not allocate the memory for the IFile
26 @retval EFI_SUCCESS - Create the new IFile for the OFile successfully
32 OUT FAT_IFILE
**PtrIFile
37 ASSERT_VOLUME_LOCKED (OFile
->Volume
);
40 // Allocate a new open instance
42 IFile
= AllocateZeroPool (sizeof (FAT_IFILE
));
44 return EFI_OUT_OF_RESOURCES
;
47 IFile
->Signature
= FAT_IFILE_SIGNATURE
;
49 CopyMem (&(IFile
->Handle
), &FatFileInterface
, sizeof (EFI_FILE_PROTOCOL
));
52 // Report the correct revision number based on the DiskIo2 availability
54 if (OFile
->Volume
->DiskIo2
!= NULL
) {
55 IFile
->Handle
.Revision
= EFI_FILE_PROTOCOL_REVISION2
;
57 IFile
->Handle
.Revision
= EFI_FILE_PROTOCOL_REVISION
;
61 InsertTailList (&OFile
->Opens
, &IFile
->Link
);
62 InitializeListHead (&IFile
->Tasks
);
70 Open a file for a file name relative to an existing OFile.
71 The IFile of the newly opened file is passed out.
73 @param OFile - The file that serves as a starting reference point.
74 @param NewIFile - The newly generated IFile instance.
75 @param FileName - The file name relative to the OFile.
76 @param OpenMode - Open mode.
77 @param Attributes - Attributes to set if the file is created.
80 @retval EFI_SUCCESS - Open the file successfully.
81 @retval EFI_INVALID_PARAMETER - The open mode is conflict with the attributes
82 or the file name is not valid.
83 @retval EFI_NOT_FOUND - Conficts between dir intention and attribute.
84 @retval EFI_WRITE_PROTECTED - Can't open for write if the volume is read only.
85 @retval EFI_ACCESS_DENIED - If the file's attribute is read only, and the
86 open is for read-write fail it.
87 @retval EFI_OUT_OF_RESOURCES - Can not allocate the memory.
93 OUT FAT_IFILE
**NewIFile
,
101 CHAR16 NewFileName
[EFI_PATH_STRING_LENGTH
];
103 UINT8 FileAttributes
;
107 Volume
= OFile
->Volume
;
108 ASSERT_VOLUME_LOCKED (Volume
);
109 WriteMode
= (BOOLEAN
) (OpenMode
& EFI_FILE_MODE_WRITE
);
110 if (Volume
->ReadOnly
&& WriteMode
) {
111 return EFI_WRITE_PROTECTED
;
114 // Verify the source file handle isn't in an error state
116 Status
= OFile
->Error
;
117 if (EFI_ERROR (Status
)) {
121 // Get new OFile for the file
123 Status
= FatLocateOFile (&OFile
, FileName
, Attributes
, NewFileName
);
124 if (EFI_ERROR (Status
)) {
128 if (*NewFileName
!= 0) {
130 // If there's a remaining part of the name, then we had
131 // better be creating the file in the directory
133 if ((OpenMode
& EFI_FILE_MODE_CREATE
) == 0) {
134 return EFI_NOT_FOUND
;
137 Status
= FatCreateDirEnt (OFile
, NewFileName
, Attributes
, &DirEnt
);
138 if (EFI_ERROR (Status
)) {
142 ASSERT (DirEnt
!= NULL
);
143 Status
= FatOpenDirEnt (OFile
, DirEnt
);
144 if (EFI_ERROR (Status
)) {
148 OFile
= DirEnt
->OFile
;
149 if (OFile
->ODir
!= NULL
) {
151 // If we just created a directory, we need to create "." and ".."
153 Status
= FatCreateDotDirEnts (OFile
);
154 if (EFI_ERROR (Status
)) {
160 // If the file's attribute is read only, and the open is for
161 // read-write, then the access is denied.
163 FileAttributes
= OFile
->DirEnt
->Entry
.Attributes
;
164 if ((FileAttributes
& EFI_FILE_READ_ONLY
) != 0 && (FileAttributes
& FAT_ATTRIBUTE_DIRECTORY
) == 0 && WriteMode
) {
165 return EFI_ACCESS_DENIED
;
168 // Create an open instance of the OFile
170 Status
= FatAllocateIFile (OFile
, NewIFile
);
171 if (EFI_ERROR (Status
)) {
175 (*NewIFile
)->ReadOnly
= (BOOLEAN
)!WriteMode
;
177 DEBUG ((EFI_D_INFO
, "FSOpen: Open '%S' %r\n", FileName
, Status
));
178 return FatOFileFlush (OFile
);
183 Implements OpenEx() of Simple File System Protocol.
185 @param FHand - File handle of the file serves as a starting reference point.
186 @param NewHandle - Handle of the file that is newly opened.
187 @param FileName - File name relative to FHand.
188 @param OpenMode - Open mode.
189 @param Attributes - Attributes to set if the file is created.
190 @param Token - A pointer to the token associated with the transaction.:
192 @retval EFI_INVALID_PARAMETER - The FileName is NULL or the file string is empty.
193 The OpenMode is not supported.
194 The Attributes is not the valid attributes.
195 @retval EFI_OUT_OF_RESOURCES - Can not allocate the memory for file string.
196 @retval EFI_SUCCESS - Open the file successfully.
197 @return Others - The status of open file.
203 IN EFI_FILE_PROTOCOL
*FHand
,
204 OUT EFI_FILE_PROTOCOL
**NewHandle
,
207 IN UINT64 Attributes
,
208 IN OUT EFI_FILE_IO_TOKEN
*Token
218 // Perform some parameter checking
220 if (FileName
== NULL
) {
221 return EFI_INVALID_PARAMETER
;
224 // Check for a valid mode
227 case EFI_FILE_MODE_READ
:
228 case EFI_FILE_MODE_READ
| EFI_FILE_MODE_WRITE
:
229 case EFI_FILE_MODE_READ
| EFI_FILE_MODE_WRITE
| EFI_FILE_MODE_CREATE
:
233 return EFI_INVALID_PARAMETER
;
237 // Check for valid Attributes for file creation case.
239 if (((OpenMode
& EFI_FILE_MODE_CREATE
) != 0) && (Attributes
& (EFI_FILE_READ_ONLY
| (~EFI_FILE_VALID_ATTR
))) != 0) {
240 return EFI_INVALID_PARAMETER
;
243 IFile
= IFILE_FROM_FHAND (FHand
);
244 OFile
= IFile
->OFile
;
248 FatWaitNonblockingTask (IFile
);
251 // Caller shouldn't call the non-blocking interfaces if the low layer doesn't support DiskIo2.
252 // But if it calls, the below check can avoid crash.
254 if (FHand
->Revision
< EFI_FILE_PROTOCOL_REVISION2
) {
255 return EFI_UNSUPPORTED
;
257 Task
= FatCreateTask (IFile
, Token
);
259 return EFI_OUT_OF_RESOURCES
;
271 Status
= FatOFileOpen (OFile
, &NewIFile
, FileName
, OpenMode
, (UINT8
) Attributes
);
274 // If the file was opened, return the handle to the caller
276 if (!EFI_ERROR (Status
)) {
277 *NewHandle
= &NewIFile
->Handle
;
282 Status
= FatCleanupVolume (OFile
->Volume
, NULL
, Status
, Task
);
286 if (!EFI_ERROR (Status
)) {
287 Status
= FatQueueTask (IFile
, Task
);
289 FatDestroyTask (Task
);
298 Implements Open() of Simple File System Protocol.
301 @param FHand - File handle of the file serves as a starting reference point.
302 @param NewHandle - Handle of the file that is newly opened.
303 @param FileName - File name relative to FHand.
304 @param OpenMode - Open mode.
305 @param Attributes - Attributes to set if the file is created.
307 @retval EFI_INVALID_PARAMETER - The FileName is NULL or the file string is empty.
308 The OpenMode is not supported.
309 The Attributes is not the valid attributes.
310 @retval EFI_OUT_OF_RESOURCES - Can not allocate the memory for file string.
311 @retval EFI_SUCCESS - Open the file successfully.
312 @return Others - The status of open file.
318 IN EFI_FILE_PROTOCOL
*FHand
,
319 OUT EFI_FILE_PROTOCOL
**NewHandle
,
325 return FatOpenEx (FHand
, NewHandle
, FileName
, OpenMode
, Attributes
, NULL
);