VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/FirmwareNew/FatPkg/EnhancedFatDxe/Info.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: 16.7 KB
Line 
1/** @file
2 Routines dealing with setting/getting file/volume info
3
4Copyright (c) 2005 - 2015, 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**/
16
17#include "Fat.h"
18
19/**
20
21 Get the volume's info into Buffer.
22
23 @param Volume - FAT file system volume.
24 @param BufferSize - Size of Buffer.
25 @param Buffer - Buffer containing volume info.
26
27 @retval EFI_SUCCESS - Get the volume info successfully.
28 @retval EFI_BUFFER_TOO_SMALL - The buffer is too small.
29
30**/
31EFI_STATUS
32FatGetVolumeInfo (
33 IN FAT_VOLUME *Volume,
34 IN OUT UINTN *BufferSize,
35 OUT VOID *Buffer
36 );
37
38/**
39
40 Set the volume's info.
41
42 @param Volume - FAT file system volume.
43 @param BufferSize - Size of Buffer.
44 @param Buffer - Buffer containing the new volume info.
45
46 @retval EFI_SUCCESS - Set the volume info successfully.
47 @retval EFI_BAD_BUFFER_SIZE - The buffer size is error.
48 @retval EFI_WRITE_PROTECTED - The volume is read only.
49 @return other - An error occurred when operation the disk.
50
51**/
52EFI_STATUS
53FatSetVolumeInfo (
54 IN FAT_VOLUME *Volume,
55 IN UINTN BufferSize,
56 IN VOID *Buffer
57 );
58
59/**
60
61 Set or Get the some types info of the file into Buffer.
62
63 @param IsSet - TRUE:The access is set, else is get
64 @param FHand - The handle of file
65 @param Type - The type of the info
66 @param BufferSize - Size of Buffer
67 @param Buffer - Buffer containing volume info
68
69 @retval EFI_SUCCESS - Get the info successfully
70 @retval EFI_DEVICE_ERROR - Can not find the OFile for the file
71
72**/
73EFI_STATUS
74FatSetOrGetInfo (
75 IN BOOLEAN IsSet,
76 IN EFI_FILE_PROTOCOL *FHand,
77 IN EFI_GUID *Type,
78 IN OUT UINTN *BufferSize,
79 IN OUT VOID *Buffer
80 );
81
82/**
83
84 Get the open file's info into Buffer.
85
86 @param OFile - The open file.
87 @param BufferSize - Size of Buffer.
88 @param Buffer - Buffer containing file info.
89
90 @retval EFI_SUCCESS - Get the file info successfully.
91 @retval EFI_BUFFER_TOO_SMALL - The buffer is too small.
92
93**/
94EFI_STATUS
95FatGetFileInfo (
96 IN FAT_OFILE *OFile,
97 IN OUT UINTN *BufferSize,
98 OUT VOID *Buffer
99 )
100{
101 return FatGetDirEntInfo (OFile->Volume, OFile->DirEnt, BufferSize, Buffer);
102}
103
104/**
105
106 Get the volume's info into Buffer.
107
108 @param Volume - FAT file system volume.
109 @param BufferSize - Size of Buffer.
110 @param Buffer - Buffer containing volume info.
111
112 @retval EFI_SUCCESS - Get the volume info successfully.
113 @retval EFI_BUFFER_TOO_SMALL - The buffer is too small.
114
115**/
116EFI_STATUS
117FatGetVolumeInfo (
118 IN FAT_VOLUME *Volume,
119 IN OUT UINTN *BufferSize,
120 OUT VOID *Buffer
121 )
122{
123 UINTN Size;
124 UINTN NameSize;
125 UINTN ResultSize;
126 CHAR16 Name[FAT_NAME_LEN + 1];
127 EFI_STATUS Status;
128 EFI_FILE_SYSTEM_INFO *Info;
129 UINT8 ClusterAlignment;
130
131 Size = SIZE_OF_EFI_FILE_SYSTEM_INFO;
132 Status = FatGetVolumeEntry (Volume, Name);
133 NameSize = StrSize (Name);
134 ResultSize = Size + NameSize;
135 ClusterAlignment = Volume->ClusterAlignment;
136
137 //
138 // If we don't have valid info, compute it now
139 //
140 FatComputeFreeInfo (Volume);
141
142 Status = EFI_BUFFER_TOO_SMALL;
143 if (*BufferSize >= ResultSize) {
144 Status = EFI_SUCCESS;
145
146 Info = Buffer;
147 ZeroMem (Info, SIZE_OF_EFI_FILE_SYSTEM_INFO);
148
149 Info->Size = ResultSize;
150 Info->ReadOnly = Volume->ReadOnly;
151 Info->BlockSize = (UINT32) Volume->ClusterSize;
152 Info->VolumeSize = LShiftU64 (Volume->MaxCluster, ClusterAlignment);
153 Info->FreeSpace = LShiftU64 (
154 Volume->FatInfoSector.FreeInfo.ClusterCount,
155 ClusterAlignment
156 );
157 CopyMem ((CHAR8 *) Buffer + Size, Name, NameSize);
158 }
159
160 *BufferSize = ResultSize;
161 return Status;
162}
163
164/**
165
166 Get the volume's label info into Buffer.
167
168 @param Volume - FAT file system volume.
169 @param BufferSize - Size of Buffer.
170 @param Buffer - Buffer containing volume's label info.
171
172 @retval EFI_SUCCESS - Get the volume's label info successfully.
173 @retval EFI_BUFFER_TOO_SMALL - The buffer is too small.
174
175**/
176EFI_STATUS
177FatGetVolumeLabelInfo (
178 IN FAT_VOLUME *Volume,
179 IN OUT UINTN *BufferSize,
180 OUT VOID *Buffer
181 )
182{
183 UINTN Size;
184 UINTN NameSize;
185 UINTN ResultSize;
186 CHAR16 Name[FAT_NAME_LEN + 1];
187 EFI_STATUS Status;
188
189 Size = SIZE_OF_EFI_FILE_SYSTEM_VOLUME_LABEL;
190 Status = FatGetVolumeEntry (Volume, Name);
191 NameSize = StrSize (Name);
192 ResultSize = Size + NameSize;
193
194 Status = EFI_BUFFER_TOO_SMALL;
195 if (*BufferSize >= ResultSize) {
196 Status = EFI_SUCCESS;
197 CopyMem ((CHAR8 *) Buffer + Size, Name, NameSize);
198 }
199
200 *BufferSize = ResultSize;
201 return Status;
202}
203
204/**
205
206 Set the volume's info.
207
208 @param Volume - FAT file system volume.
209 @param BufferSize - Size of Buffer.
210 @param Buffer - Buffer containing the new volume info.
211
212 @retval EFI_SUCCESS - Set the volume info successfully.
213 @retval EFI_BAD_BUFFER_SIZE - The buffer size is error.
214 @retval EFI_WRITE_PROTECTED - The volume is read only.
215 @return other - An error occurred when operation the disk.
216
217**/
218EFI_STATUS
219FatSetVolumeInfo (
220 IN FAT_VOLUME *Volume,
221 IN UINTN BufferSize,
222 IN VOID *Buffer
223 )
224{
225 EFI_FILE_SYSTEM_INFO *Info;
226
227 Info = (EFI_FILE_SYSTEM_INFO *) Buffer;
228
229 if (BufferSize < SIZE_OF_EFI_FILE_SYSTEM_INFO + 2 || Info->Size > BufferSize) {
230 return EFI_BAD_BUFFER_SIZE;
231 }
232
233 return FatSetVolumeEntry (Volume, Info->VolumeLabel);
234}
235
236/**
237
238 Set the volume's label info.
239
240 @param Volume - FAT file system volume.
241 @param BufferSize - Size of Buffer.
242 @param Buffer - Buffer containing the new volume label info.
243
244 @retval EFI_SUCCESS - Set the volume label info successfully.
245 @retval EFI_WRITE_PROTECTED - The disk is write protected.
246 @retval EFI_BAD_BUFFER_SIZE - The buffer size is error.
247 @return other - An error occurred when operation the disk.
248
249**/
250EFI_STATUS
251FatSetVolumeLabelInfo (
252 IN FAT_VOLUME *Volume,
253 IN UINTN BufferSize,
254 IN VOID *Buffer
255 )
256{
257 EFI_FILE_SYSTEM_VOLUME_LABEL *Info;
258
259 Info = (EFI_FILE_SYSTEM_VOLUME_LABEL *) Buffer;
260
261 if (BufferSize < SIZE_OF_EFI_FILE_SYSTEM_VOLUME_LABEL + 2) {
262 return EFI_BAD_BUFFER_SIZE;
263 }
264
265 return FatSetVolumeEntry (Volume, Info->VolumeLabel);
266}
267
268/**
269
270 Set the file info.
271
272 @param Volume - FAT file system volume.
273 @param IFile - The instance of the open file.
274 @param OFile - The open file.
275 @param BufferSize - Size of Buffer.
276 @param Buffer - Buffer containing the new file info.
277
278 @retval EFI_SUCCESS - Set the file info successfully.
279 @retval EFI_ACCESS_DENIED - It is the root directory
280 or the directory attribute bit can not change
281 or try to change a directory size
282 or something else.
283 @retval EFI_UNSUPPORTED - The new file size is larger than 4GB.
284 @retval EFI_WRITE_PROTECTED - The disk is write protected.
285 @retval EFI_BAD_BUFFER_SIZE - The buffer size is error.
286 @retval EFI_INVALID_PARAMETER - The time info or attributes info is error.
287 @retval EFI_OUT_OF_RESOURCES - Can not allocate new memory.
288 @retval EFI_VOLUME_CORRUPTED - The volume is corrupted.
289 @return other - An error occurred when operation the disk.
290
291**/
292EFI_STATUS
293FatSetFileInfo (
294 IN FAT_VOLUME *Volume,
295 IN FAT_IFILE *IFile,
296 IN FAT_OFILE *OFile,
297 IN UINTN BufferSize,
298 IN VOID *Buffer
299 )
300{
301 EFI_STATUS Status;
302 EFI_FILE_INFO *NewInfo;
303 FAT_OFILE *DotOFile;
304 FAT_OFILE *Parent;
305 CHAR16 NewFileName[EFI_PATH_STRING_LENGTH];
306 EFI_TIME ZeroTime;
307 FAT_DIRENT *DirEnt;
308 FAT_DIRENT *TempDirEnt;
309 UINT8 NewAttribute;
310 BOOLEAN ReadOnly;
311
312 ZeroMem (&ZeroTime, sizeof (EFI_TIME));
313 Parent = OFile->Parent;
314 DirEnt = OFile->DirEnt;
315 //
316 // If this is the root directory, we can't make any updates
317 //
318 if (Parent == NULL) {
319 return EFI_ACCESS_DENIED;
320 }
321 //
322 // Make sure there's a valid input buffer
323 //
324 NewInfo = Buffer;
325 if (BufferSize < SIZE_OF_EFI_FILE_INFO + 2 || NewInfo->Size > BufferSize) {
326 return EFI_BAD_BUFFER_SIZE;
327 }
328
329 ReadOnly = (BOOLEAN)(IFile->ReadOnly || (DirEnt->Entry.Attributes & EFI_FILE_READ_ONLY));
330 //
331 // if a zero time is specified, then the original time is preserved
332 //
333 if (CompareMem (&ZeroTime, &NewInfo->CreateTime, sizeof (EFI_TIME)) != 0) {
334 if (!FatIsValidTime (&NewInfo->CreateTime)) {
335 return EFI_INVALID_PARAMETER;
336 }
337
338 if (!ReadOnly) {
339 FatEfiTimeToFatTime (&NewInfo->CreateTime, &DirEnt->Entry.FileCreateTime);
340 }
341 }
342
343 if (CompareMem (&ZeroTime, &NewInfo->ModificationTime, sizeof (EFI_TIME)) != 0) {
344 if (!FatIsValidTime (&NewInfo->ModificationTime)) {
345 return EFI_INVALID_PARAMETER;
346 }
347
348 if (!ReadOnly) {
349 FatEfiTimeToFatTime (&NewInfo->ModificationTime, &DirEnt->Entry.FileModificationTime);
350 }
351
352 OFile->PreserveLastModification = TRUE;
353 }
354
355 if (NewInfo->Attribute & (~EFI_FILE_VALID_ATTR)) {
356 return EFI_INVALID_PARAMETER;
357 }
358
359 NewAttribute = (UINT8) NewInfo->Attribute;
360 //
361 // Can not change the directory attribute bit
362 //
363 if ((NewAttribute ^ DirEnt->Entry.Attributes) & EFI_FILE_DIRECTORY) {
364 return EFI_ACCESS_DENIED;
365 }
366 //
367 // Set the current attributes even if the IFile->ReadOnly is TRUE
368 //
369 DirEnt->Entry.Attributes = (UINT8) ((DirEnt->Entry.Attributes &~EFI_FILE_VALID_ATTR) | NewAttribute);
370 //
371 // Open the filename and see if it refers to an existing file
372 //
373 Status = FatLocateOFile (&Parent, NewInfo->FileName, DirEnt->Entry.Attributes, NewFileName);
374 if (EFI_ERROR (Status)) {
375 return Status;
376 }
377
378 if (*NewFileName != 0) {
379 //
380 // File was not found. We do not allow rename of the current directory if
381 // there are open files below the current directory
382 //
383 if (!IsListEmpty (&OFile->ChildHead) || Parent == OFile) {
384 return EFI_ACCESS_DENIED;
385 }
386
387 if (ReadOnly) {
388 return EFI_ACCESS_DENIED;
389 }
390
391 Status = FatRemoveDirEnt (OFile->Parent, DirEnt);
392 if (EFI_ERROR (Status)) {
393 return Status;
394 }
395 //
396 // Create new dirent
397 //
398 Status = FatCreateDirEnt (Parent, NewFileName, DirEnt->Entry.Attributes, &TempDirEnt);
399 if (EFI_ERROR (Status)) {
400 return Status;
401 }
402
403 FatCloneDirEnt (TempDirEnt, DirEnt);
404 FatFreeDirEnt (DirEnt);
405 DirEnt = TempDirEnt;
406 DirEnt->OFile = OFile;
407 OFile->DirEnt = DirEnt;
408 OFile->Parent = Parent;
409 RemoveEntryList (&OFile->ChildLink);
410 InsertHeadList (&Parent->ChildHead, &OFile->ChildLink);
411 //
412 // If this is a directory, synchronize its dot directory entry
413 //
414 if (OFile->ODir != NULL) {
415 //
416 // Syncronize its dot entry
417 //
418 FatResetODirCursor (OFile);
419 ASSERT (OFile->Parent != NULL);
420 for (DotOFile = OFile; DotOFile != OFile->Parent->Parent; DotOFile = DotOFile->Parent) {
421 Status = FatGetNextDirEnt (OFile, &DirEnt);
422 if (EFI_ERROR (Status) || DirEnt == NULL || !FatIsDotDirEnt (DirEnt)) {
423 return EFI_VOLUME_CORRUPTED;
424 }
425
426 FatCloneDirEnt (DirEnt, DotOFile->DirEnt);
427 Status = FatStoreDirEnt (OFile, DirEnt);
428 if (EFI_ERROR (Status)) {
429 return Status;
430 }
431 }
432 }
433 //
434 // If the file is renamed, we should append the ARCHIVE attribute
435 //
436 OFile->Archive = TRUE;
437 } else if (Parent != OFile) {
438 //
439 // filename is to a different filename that already exists
440 //
441 return EFI_ACCESS_DENIED;
442 }
443 //
444 // If the file size has changed, apply it
445 //
446 if (NewInfo->FileSize != OFile->FileSize) {
447 if (OFile->ODir != NULL || ReadOnly) {
448 //
449 // If this is a directory or the file is read only, we can't change the file size
450 //
451 return EFI_ACCESS_DENIED;
452 }
453
454 if (NewInfo->FileSize > OFile->FileSize) {
455 Status = FatExpandOFile (OFile, NewInfo->FileSize);
456 } else {
457 Status = FatTruncateOFile (OFile, (UINTN) NewInfo->FileSize);
458 }
459
460 if (EFI_ERROR (Status)) {
461 return Status;
462 }
463
464 FatUpdateDirEntClusterSizeInfo (OFile);
465 }
466
467 OFile->Dirty = TRUE;
468 return FatOFileFlush (OFile);
469}
470
471/**
472
473 Set or Get the some types info of the file into Buffer.
474
475 @param IsSet - TRUE:The access is set, else is get
476 @param FHand - The handle of file
477 @param Type - The type of the info
478 @param BufferSize - Size of Buffer
479 @param Buffer - Buffer containing volume info
480
481 @retval EFI_SUCCESS - Get the info successfully
482 @retval EFI_DEVICE_ERROR - Can not find the OFile for the file
483
484**/
485EFI_STATUS
486FatSetOrGetInfo (
487 IN BOOLEAN IsSet,
488 IN EFI_FILE_PROTOCOL *FHand,
489 IN EFI_GUID *Type,
490 IN OUT UINTN *BufferSize,
491 IN OUT VOID *Buffer
492 )
493{
494 FAT_IFILE *IFile;
495 FAT_OFILE *OFile;
496 FAT_VOLUME *Volume;
497 EFI_STATUS Status;
498
499 IFile = IFILE_FROM_FHAND (FHand);
500 OFile = IFile->OFile;
501 Volume = OFile->Volume;
502
503 Status = OFile->Error;
504 if (Status == EFI_NOT_FOUND) {
505 return EFI_DEVICE_ERROR;
506 }
507
508 FatWaitNonblockingTask (IFile);
509
510 FatAcquireLock ();
511
512 //
513 // Verify the file handle isn't in an error state
514 //
515 if (!EFI_ERROR (Status)) {
516 //
517 // Get the proper information based on the request
518 //
519 Status = EFI_UNSUPPORTED;
520 if (IsSet) {
521 if (CompareGuid (Type, &gEfiFileInfoGuid)) {
522 Status = Volume->ReadOnly ? EFI_WRITE_PROTECTED : FatSetFileInfo (Volume, IFile, OFile, *BufferSize, Buffer);
523 }
524
525 if (CompareGuid (Type, &gEfiFileSystemInfoGuid)) {
526 Status = Volume->ReadOnly ? EFI_WRITE_PROTECTED : FatSetVolumeInfo (Volume, *BufferSize, Buffer);
527 }
528
529 if (CompareGuid (Type, &gEfiFileSystemVolumeLabelInfoIdGuid)) {
530 Status = Volume->ReadOnly ? EFI_WRITE_PROTECTED : FatSetVolumeLabelInfo (Volume, *BufferSize, Buffer);
531 }
532 } else {
533 if (CompareGuid (Type, &gEfiFileInfoGuid)) {
534 Status = FatGetFileInfo (OFile, BufferSize, Buffer);
535 }
536
537 if (CompareGuid (Type, &gEfiFileSystemInfoGuid)) {
538 Status = FatGetVolumeInfo (Volume, BufferSize, Buffer);
539 }
540
541 if (CompareGuid (Type, &gEfiFileSystemVolumeLabelInfoIdGuid)) {
542 Status = FatGetVolumeLabelInfo (Volume, BufferSize, Buffer);
543 }
544 }
545 }
546
547 Status = FatCleanupVolume (Volume, NULL, Status, NULL);
548
549 FatReleaseLock ();
550 return Status;
551}
552
553/**
554
555 Get the some types info of the file into Buffer.
556
557 @param FHand - The handle of file.
558 @param Type - The type of the info.
559 @param BufferSize - Size of Buffer.
560 @param Buffer - Buffer containing volume info.
561
562 @retval EFI_SUCCESS - Get the info successfully.
563 @retval EFI_DEVICE_ERROR - Can not find the OFile for the file.
564
565**/
566EFI_STATUS
567EFIAPI
568FatGetInfo (
569 IN EFI_FILE_PROTOCOL *FHand,
570 IN EFI_GUID *Type,
571 IN OUT UINTN *BufferSize,
572 OUT VOID *Buffer
573 )
574{
575 return FatSetOrGetInfo (FALSE, FHand, Type, BufferSize, Buffer);
576}
577
578/**
579
580 Set the some types info of the file into Buffer.
581
582 @param FHand - The handle of file.
583 @param Type - The type of the info.
584 @param BufferSize - Size of Buffer
585 @param Buffer - Buffer containing volume info.
586
587 @retval EFI_SUCCESS - Set the info successfully.
588 @retval EFI_DEVICE_ERROR - Can not find the OFile for the file.
589
590**/
591EFI_STATUS
592EFIAPI
593FatSetInfo (
594 IN EFI_FILE_PROTOCOL *FHand,
595 IN EFI_GUID *Type,
596 IN UINTN BufferSize,
597 IN VOID *Buffer
598 )
599{
600 return FatSetOrGetInfo (TRUE, FHand, Type, &BufferSize, Buffer);
601}
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