VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware/FatPkg/EnhancedFatDxe/Info.c@ 102466

Last change on this file since 102466 was 99404, checked in by vboxsync, 23 months ago

Devices/EFI/FirmwareNew: Update to edk2-stable202302 and make it build, bugref:4643

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