diff options
-rw-r--r-- | Library/UefiShellUfmCommandLib/cmds.c | 72 | ||||
-rw-r--r-- | Library/UefiShellUfmCommandLib/cmds.h | 12 |
2 files changed, 84 insertions, 0 deletions
diff --git a/Library/UefiShellUfmCommandLib/cmds.c b/Library/UefiShellUfmCommandLib/cmds.c index 93c5666..30d94b8 100644 --- a/Library/UefiShellUfmCommandLib/cmds.c +++ b/Library/UefiShellUfmCommandLib/cmds.c @@ -1,9 +1,81 @@ #include <Library/UefiLib.h> #include <Library/DebugLib.h> +#include <Library/FileHandleLib.h> #include <Library/MemoryAllocationLib.h> #include "cmds.h" +STATIC BOOLEAN is_dir_empty(SHELL_FILE_HANDLE FileHandle) +{ + EFI_STATUS status; + EFI_FILE_INFO *file_info = NULL; + BOOLEAN no_file = FALSE; + BOOLEAN ret = TRUE; + + for(status = FileHandleFindFirstFile(FileHandle, &file_info); + !no_file && !EFI_ERROR (status); + FileHandleFindNextFile(FileHandle, file_info, &no_file)) + { + if(StrStr(file_info->FileName, L".") != file_info->FileName && + StrStr(file_info->FileName, L"..") != file_info->FileName) { + ret = FALSE; + } + } + return ret; +} + +EFI_STATUS delete_file(EFI_SHELL_FILE_INFO *node) +{ + EFI_SHELL_FILE_INFO *list = NULL, *walker = NULL; + EFI_STATUS status = EFI_SUCCESS; + + if((node->Info->Attribute & EFI_FILE_READ_ONLY) == EFI_FILE_READ_ONLY) + return EFI_ACCESS_DENIED; + + if((node->Info->Attribute & EFI_FILE_DIRECTORY) == EFI_FILE_DIRECTORY) { + if(!is_dir_empty(node->Handle)) + { + status = gEfiShellProtocol->FindFilesInDir(node->Handle, &list); + if(EFI_ERROR(status)) { + if(list) + gEfiShellProtocol->FreeFileList(&list); + return EFI_DEVICE_ERROR; + } + + for(walker = (EFI_SHELL_FILE_INFO *)GetFirstNode(&list->Link); + !IsNull(&list->Link, &walker->Link); + walker = (EFI_SHELL_FILE_INFO *)GetNextNode(&list->Link, &walker->Link)) + { + if(StrCmp(walker->FileName, L".") == 0 || StrCmp(walker->FileName, L"..") == 0) + continue; + + walker->Status = gEfiShellProtocol->OpenFileByName(walker->FullName, &walker->Handle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE); + if(!EFI_ERROR(walker->Status)) + status = delete_file(walker); + else + status = walker->Status; + + if(status != EFI_SUCCESS) { + if(list) + gEfiShellProtocol->FreeFileList(&list); + return status; + } + } + if(list) + gEfiShellProtocol->FreeFileList(&list); + } + } + + if(StrCmp(node->FileName, L".") != 0 && + StrCmp(node->FileName, L"..") != 0) { + // delete the current node + status = gEfiShellProtocol->DeleteFile(node->Handle); + node->Handle = NULL; + } + + return status; +} + EFI_STATUS make_directory(CONST CHAR16 *dir_name) { EFI_STATUS status = EFI_SUCCESS; diff --git a/Library/UefiShellUfmCommandLib/cmds.h b/Library/UefiShellUfmCommandLib/cmds.h index d819d47..f58cdea 100644 --- a/Library/UefiShellUfmCommandLib/cmds.h +++ b/Library/UefiShellUfmCommandLib/cmds.h @@ -5,6 +5,18 @@ #include <Library/ShellLib.h> /* + * Deletes a node including subdirectories + * + * node: the node to start deleting with + * + * return: EFI_SUCCESS The operation was successful + EFI_ACCESS_DENIED A file was read only + EFI_ABORTED The abort was received + EFI_DEVICE_ERROR A device error occurred reading this node +*/ +EFI_STATUS delete_file(EFI_SHELL_FILE_INFO *node); + +/* * Creates one or more directories. * * dir_name: the name of a directory or directories to create |