diff options
author | Joursoir <chat@joursoir.net> | 2021-11-15 19:48:08 +0300 |
---|---|---|
committer | Joursoir <chat@joursoir.net> | 2021-11-15 19:48:08 +0300 |
commit | 2c4ace2c2cf853c85d9b32d42e8bae39d88a7355 (patch) | |
tree | 2e7a53fd8832f16c4fa992b1df6070dd108b6508 /Library/UefiShellUfmCommandLib/dir.c | |
parent | 3e17a10f5f691159cb9fc778f0a3a463ea0b3bee (diff) | |
download | ufm-2c4ace2c2cf853c85d9b32d42e8bae39d88a7355.tar.gz ufm-2c4ace2c2cf853c85d9b32d42e8bae39d88a7355.tar.bz2 ufm-2c4ace2c2cf853c85d9b32d42e8bae39d88a7355.zip |
add routines to get dir entries
Diffstat (limited to 'Library/UefiShellUfmCommandLib/dir.c')
-rw-r--r-- | Library/UefiShellUfmCommandLib/dir.c | 64 |
1 files changed, 64 insertions, 0 deletions
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 <Library/UefiLib.h> +#include <Library/DebugLib.h> +#include <Library/ShellLib.h> +#include <Library/BaseLib.h> +#include <Library/MemoryAllocationLib.h> + +#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); +} |