VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/FirmwareNew/FatPkg/EnhancedFatDxe/Open.c@ 77662

Last change on this file since 77662 was 77662, checked in by vboxsync, 6 years ago

EFI: First step in UDK2018 merge. Does not build yet.

  • Property svn:eol-style set to native
File size: 9.1 KB
Line 
1/** @file
2 Routines dealing with file open.
3
4Copyright (c) 2005 - 2014, Intel Corporation. All rights reserved.<BR>
5This program and the accompanying materials are licensed and made available
6under the terms and conditions of the BSD License which accompanies this
7distribution. The full text of the license may be found at
8http://opensource.org/licenses/bsd-license.php
9
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13**/
14
15#include "Fat.h"
16
17/**
18
19 Create an Open instance for the existing OFile.
20 The IFile of the newly opened file is passed out.
21
22 @param OFile - The file that serves as a starting reference point.
23 @param PtrIFile - The newly generated IFile instance.
24
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
27
28**/
29EFI_STATUS
30FatAllocateIFile (
31 IN FAT_OFILE *OFile,
32 OUT FAT_IFILE **PtrIFile
33 )
34{
35 FAT_IFILE *IFile;
36
37 ASSERT_VOLUME_LOCKED (OFile->Volume);
38
39 //
40 // Allocate a new open instance
41 //
42 IFile = AllocateZeroPool (sizeof (FAT_IFILE));
43 if (IFile == NULL) {
44 return EFI_OUT_OF_RESOURCES;
45 }
46
47 IFile->Signature = FAT_IFILE_SIGNATURE;
48
49 CopyMem (&(IFile->Handle), &FatFileInterface, sizeof (EFI_FILE_PROTOCOL));
50
51 //
52 // Report the correct revision number based on the DiskIo2 availability
53 //
54 if (OFile->Volume->DiskIo2 != NULL) {
55 IFile->Handle.Revision = EFI_FILE_PROTOCOL_REVISION2;
56 } else {
57 IFile->Handle.Revision = EFI_FILE_PROTOCOL_REVISION;
58 }
59
60 IFile->OFile = OFile;
61 InsertTailList (&OFile->Opens, &IFile->Link);
62 InitializeListHead (&IFile->Tasks);
63
64 *PtrIFile = IFile;
65 return EFI_SUCCESS;
66}
67
68/**
69
70 Open a file for a file name relative to an existing OFile.
71 The IFile of the newly opened file is passed out.
72
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.
78
79
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.
88
89**/
90EFI_STATUS
91FatOFileOpen (
92 IN FAT_OFILE *OFile,
93 OUT FAT_IFILE **NewIFile,
94 IN CHAR16 *FileName,
95 IN UINT64 OpenMode,
96 IN UINT8 Attributes
97 )
98{
99 FAT_VOLUME *Volume;
100 EFI_STATUS Status;
101 CHAR16 NewFileName[EFI_PATH_STRING_LENGTH];
102 FAT_DIRENT *DirEnt;
103 UINT8 FileAttributes;
104 BOOLEAN WriteMode;
105
106 DirEnt = NULL;
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;
112 }
113 //
114 // Verify the source file handle isn't in an error state
115 //
116 Status = OFile->Error;
117 if (EFI_ERROR (Status)) {
118 return Status;
119 }
120 //
121 // Get new OFile for the file
122 //
123 Status = FatLocateOFile (&OFile, FileName, Attributes, NewFileName);
124 if (EFI_ERROR (Status)) {
125 return Status;
126 }
127
128 if (*NewFileName != 0) {
129 //
130 // If there's a remaining part of the name, then we had
131 // better be creating the file in the directory
132 //
133 if ((OpenMode & EFI_FILE_MODE_CREATE) == 0) {
134 return EFI_NOT_FOUND;
135 }
136
137 Status = FatCreateDirEnt (OFile, NewFileName, Attributes, &DirEnt);
138 if (EFI_ERROR (Status)) {
139 return Status;
140 }
141
142 ASSERT (DirEnt != NULL);
143 Status = FatOpenDirEnt (OFile, DirEnt);
144 if (EFI_ERROR (Status)) {
145 return Status;
146 }
147
148 OFile = DirEnt->OFile;
149 if (OFile->ODir != NULL) {
150 //
151 // If we just created a directory, we need to create "." and ".."
152 //
153 Status = FatCreateDotDirEnts (OFile);
154 if (EFI_ERROR (Status)) {
155 return Status;
156 }
157 }
158 }
159 //
160 // If the file's attribute is read only, and the open is for
161 // read-write, then the access is denied.
162 //
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;
166 }
167 //
168 // Create an open instance of the OFile
169 //
170 Status = FatAllocateIFile (OFile, NewIFile);
171 if (EFI_ERROR (Status)) {
172 return Status;
173 }
174
175 (*NewIFile)->ReadOnly = (BOOLEAN)!WriteMode;
176
177 DEBUG ((EFI_D_INFO, "FSOpen: Open '%S' %r\n", FileName, Status));
178 return FatOFileFlush (OFile);
179}
180
181/**
182
183 Implements OpenEx() of Simple File System Protocol.
184
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.:
191
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.
198
199**/
200EFI_STATUS
201EFIAPI
202FatOpenEx (
203 IN EFI_FILE_PROTOCOL *FHand,
204 OUT EFI_FILE_PROTOCOL **NewHandle,
205 IN CHAR16 *FileName,
206 IN UINT64 OpenMode,
207 IN UINT64 Attributes,
208 IN OUT EFI_FILE_IO_TOKEN *Token
209 )
210{
211 FAT_IFILE *IFile;
212 FAT_IFILE *NewIFile;
213 FAT_OFILE *OFile;
214 EFI_STATUS Status;
215 FAT_TASK *Task;
216
217 //
218 // Perform some parameter checking
219 //
220 if (FileName == NULL) {
221 return EFI_INVALID_PARAMETER;
222 }
223 //
224 // Check for a valid mode
225 //
226 switch (OpenMode) {
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:
230 break;
231
232 default:
233 return EFI_INVALID_PARAMETER;
234 }
235
236 //
237 // Check for valid Attributes for file creation case.
238 //
239 if (((OpenMode & EFI_FILE_MODE_CREATE) != 0) && (Attributes & (EFI_FILE_READ_ONLY | (~EFI_FILE_VALID_ATTR))) != 0) {
240 return EFI_INVALID_PARAMETER;
241 }
242
243 IFile = IFILE_FROM_FHAND (FHand);
244 OFile = IFile->OFile;
245 Task = NULL;
246
247 if (Token == NULL) {
248 FatWaitNonblockingTask (IFile);
249 } else {
250 //
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.
253 //
254 if (FHand->Revision < EFI_FILE_PROTOCOL_REVISION2) {
255 return EFI_UNSUPPORTED;
256 }
257 Task = FatCreateTask (IFile, Token);
258 if (Task == NULL) {
259 return EFI_OUT_OF_RESOURCES;
260 }
261 }
262
263 //
264 // Lock
265 //
266 FatAcquireLock ();
267
268 //
269 // Open the file
270 //
271 Status = FatOFileOpen (OFile, &NewIFile, FileName, OpenMode, (UINT8) Attributes);
272
273 //
274 // If the file was opened, return the handle to the caller
275 //
276 if (!EFI_ERROR (Status)) {
277 *NewHandle = &NewIFile->Handle;
278 }
279 //
280 // Unlock
281 //
282 Status = FatCleanupVolume (OFile->Volume, NULL, Status, Task);
283 FatReleaseLock ();
284
285 if (Token != NULL) {
286 if (!EFI_ERROR (Status)) {
287 Status = FatQueueTask (IFile, Task);
288 } else {
289 FatDestroyTask (Task);
290 }
291 }
292
293 return Status;
294}
295
296/**
297
298 Implements Open() of Simple File System Protocol.
299
300
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.
306
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.
313
314**/
315EFI_STATUS
316EFIAPI
317FatOpen (
318 IN EFI_FILE_PROTOCOL *FHand,
319 OUT EFI_FILE_PROTOCOL **NewHandle,
320 IN CHAR16 *FileName,
321 IN UINT64 OpenMode,
322 IN UINT64 Attributes
323 )
324{
325 return FatOpenEx (FHand, NewHandle, FileName, OpenMode, Attributes, NULL);
326}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette