Delete.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. /** @file
  2. Function that deletes a file.
  3. Copyright (c) 2005 - 2013, Intel Corporation. All rights reserved.<BR>
  4. SPDX-License-Identifier: BSD-2-Clause-Patent
  5. **/
  6. #include "Fat.h"
  7. /**
  8. Deletes the file & Closes the file handle.
  9. @param FHand - Handle to the file to delete.
  10. @retval EFI_SUCCESS - Delete the file successfully.
  11. @retval EFI_WARN_DELETE_FAILURE - Fail to delete the file.
  12. **/
  13. EFI_STATUS
  14. EFIAPI
  15. FatDelete (
  16. IN EFI_FILE_PROTOCOL *FHand
  17. )
  18. {
  19. FAT_IFILE *IFile;
  20. FAT_OFILE *OFile;
  21. FAT_DIRENT *DirEnt;
  22. EFI_STATUS Status;
  23. UINTN Round;
  24. IFile = IFILE_FROM_FHAND (FHand);
  25. OFile = IFile->OFile;
  26. FatWaitNonblockingTask (IFile);
  27. //
  28. // Lock the volume
  29. //
  30. FatAcquireLock ();
  31. //
  32. // If the file is read-only, then don't delete it
  33. //
  34. if (IFile->ReadOnly) {
  35. Status = EFI_WRITE_PROTECTED;
  36. goto Done;
  37. }
  38. //
  39. // If the file is the root dir, then don't delete it
  40. //
  41. if (OFile->Parent == NULL) {
  42. Status = EFI_ACCESS_DENIED;
  43. goto Done;
  44. }
  45. //
  46. // If the file has a permanant error, skip the delete
  47. //
  48. Status = OFile->Error;
  49. if (!EFI_ERROR (Status)) {
  50. //
  51. // If this is a directory, make sure it's empty before
  52. // allowing it to be deleted
  53. //
  54. if (OFile->ODir != NULL) {
  55. //
  56. // We do not allow to delete nonempty directory
  57. //
  58. FatResetODirCursor (OFile);
  59. for (Round = 0; Round < 3; Round++) {
  60. Status = FatGetNextDirEnt (OFile, &DirEnt);
  61. if ((EFI_ERROR (Status)) ||
  62. ((Round < 2) && (DirEnt == NULL || !FatIsDotDirEnt (DirEnt))) ||
  63. ((Round == 2) && (DirEnt != NULL))
  64. ) {
  65. Status = EFI_ACCESS_DENIED;
  66. goto Done;
  67. }
  68. }
  69. }
  70. //
  71. // Return the file's space by setting its size to 0
  72. //
  73. FatTruncateOFile (OFile, 0);
  74. //
  75. // Free the directory entry for this file
  76. //
  77. Status = FatRemoveDirEnt (OFile->Parent, OFile->DirEnt);
  78. if (EFI_ERROR (Status)) {
  79. goto Done;
  80. }
  81. //
  82. // Set a permanent error for this OFile in case there
  83. // are still opened IFiles attached
  84. //
  85. OFile->Error = EFI_NOT_FOUND;
  86. } else if (OFile->Error == EFI_NOT_FOUND) {
  87. Status = EFI_SUCCESS;
  88. }
  89. Done:
  90. //
  91. // Always close the handle
  92. //
  93. FatIFileClose (IFile);
  94. //
  95. // Done
  96. //
  97. Status = FatCleanupVolume (OFile->Volume, NULL, Status, NULL);
  98. FatReleaseLock ();
  99. if (EFI_ERROR (Status)) {
  100. Status = EFI_WARN_DELETE_FAILURE;
  101. }
  102. return Status;
  103. }