From 2c4ace2c2cf853c85d9b32d42e8bae39d88a7355 Mon Sep 17 00:00:00 2001 From: Joursoir Date: Mon, 15 Nov 2021 19:48:08 +0300 Subject: add routines to get dir entries --- Library/UefiShellUfmCommandLib/dir.c | 64 ++++++++++++++++++++++++++++++++++++ Library/UefiShellUfmCommandLib/dir.h | 30 +++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 Library/UefiShellUfmCommandLib/dir.c create mode 100644 Library/UefiShellUfmCommandLib/dir.h diff --git a/Library/UefiShellUfmCommandLib/dir.c b/Library/UefiShellUfmCommandLib/dir.c new file mode 100644 index 0000000..12bc13b --- /dev/null +++ b/Library/UefiShellUfmCommandLib/dir.c @@ -0,0 +1,64 @@ +#include +#include +#include +#include +#include + +#include "dir.h" + +struct dir_list *dirl_alloc(CHAR16 *search_path, CONST UINT64 attr) +{ + EFI_STATUS status = EFI_SUCCESS; + EFI_SHELL_FILE_INFO *list_head = NULL, *node = NULL; + UINTN length = 0; + struct dir_list *dl; + + status = ShellOpenFileMetaArg(search_path, EFI_FILE_MODE_READ, &list_head); + if(EFI_ERROR(status)) + return NULL; + + for(node = (EFI_SHELL_FILE_INFO *)GetFirstNode(&list_head->Link); + !IsNull(&list_head->Link, &node->Link); + node = (EFI_SHELL_FILE_INFO *)GetNextNode(&list_head->Link, &node->Link)) + { + ASSERT(node != NULL); + ASSERT(node->Info != NULL); + ASSERT((node->Info->Attribute & EFI_FILE_VALID_ATTR) == node->Info->Attribute); + + if((node->Info->Attribute & attr) != attr || + StrCmp(node->FileName, L".") == 0) { + EFI_SHELL_FILE_INFO *tmp; + tmp = (EFI_SHELL_FILE_INFO *)GetPreviousNode(&list_head->Link, &node->Link); + + // I have stolen code below in the source code of InternalFreeShellFileInfoNode(): + RemoveEntryList(&node->Link); + FreePool((VOID*)node->Info); + FreePool((VOID*)node->FileName); + FreePool((VOID*)node->FullName); + gEfiShellProtocol->CloseFile(node->Handle); + FreePool(node); + node = tmp; + continue; + } + + length++; + } + + dl = AllocatePool(sizeof(struct dir_list)); + if(!dl) { + ShellCloseFileMetaArg(&list_head); + return NULL; + } + + dl->list_head = list_head; + dl->len = length; + return dl; +} + +VOID dirl_release(struct dir_list *dl) +{ + if(dl->list_head) + ShellCloseFileMetaArg(&dl->list_head); + + FreePool(dl); +} diff --git a/Library/UefiShellUfmCommandLib/dir.h b/Library/UefiShellUfmCommandLib/dir.h new file mode 100644 index 0000000..be560ad --- /dev/null +++ b/Library/UefiShellUfmCommandLib/dir.h @@ -0,0 +1,30 @@ +#ifndef UFM_DIR_H +#define UFM_DIR_H + +#include + +struct dir_list { + EFI_SHELL_FILE_INFO *list_head; + int len; // number of elements in list +}; + +/* + * Opens a directory and gets all its entries + * + * search_path: the pointer to path string + * attr: required file attributes + * + * return: A pointer to the allocated structure or NULL if allocation fails +*/ +struct dir_list *dirl_alloc(CHAR16 *search_path, CONST UINT64 attr); + +/* + * Deletes the directory list, frees the structure + * + * dl: the pointer to the directory list + * + * return: VOID +*/ +VOID dirl_release(struct dir_list *dl); + +#endif /* UFM_DIR_H */ -- cgit v1.2.3-18-g5258