diff options
author | Joursoir <chat@joursoir.net> | 2021-12-12 21:14:42 +0300 |
---|---|---|
committer | Joursoir <chat@joursoir.net> | 2021-12-12 21:14:42 +0300 |
commit | 32c16800be03314346c0c769e5b5bce3a9c305ac (patch) | |
tree | 1c6b7e37c572a1c1fcda651da4630143a9af398a /Library/UefiShellUfmCommandLib/cmds.c | |
parent | 8c3e73dad73befa4564c51eeb86685dd0f93a618 (diff) | |
download | ufm-32c16800be03314346c0c769e5b5bce3a9c305ac.tar.gz ufm-32c16800be03314346c0c769e5b5bce3a9c305ac.tar.bz2 ufm-32c16800be03314346c0c769e5b5bce3a9c305ac.zip |
cmds: make deletion of file/directory
Diffstat (limited to 'Library/UefiShellUfmCommandLib/cmds.c')
-rw-r--r-- | Library/UefiShellUfmCommandLib/cmds.c | 72 |
1 files changed, 72 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; |