From 32c16800be03314346c0c769e5b5bce3a9c305ac Mon Sep 17 00:00:00 2001 From: Joursoir Date: Sun, 12 Dec 2021 21:14:42 +0300 Subject: cmds: make deletion of file/directory --- Library/UefiShellUfmCommandLib/cmds.c | 72 +++++++++++++++++++++++++++++++++++ Library/UefiShellUfmCommandLib/cmds.h | 12 ++++++ 2 files changed, 84 insertions(+) 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 #include +#include #include #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 @@ -4,6 +4,18 @@ #include #include +/* + * 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. * -- cgit v1.2.3-18-g5258