> On Dec 13, 2014, at 10:43 AM, John Smith <johnrandomsmi...@gmail.com> wrote:
>
> As a thanks to Thomas, and to pay it forward for everyone who comes after me,
> here's a slightly modified compiling version of what he wrote. There are some
> parts (like continuously re-reading the directory file) which I found
> counter-intuitive and I doubt I would have figured out on my own by reading
> the spec, which is why skeleton code is so important. It would be great if
> someone started a repository
>
Not sure about how to start a new repository, but you need to contribute under
a license structure.
The edk2 is BSD + TianoCore Contribution Agreement. Technically speaking you
should add your copyright (required to enforce the license), and the BDS
license to the code. The TianoCore Contribution Agreement is only required in
the check in message, or an email like this to make a contribution (The
Contribution Agreement is required as BSD is to ambiguous about IP rights)
Contributed-under: TianoCore Contribution Agreement 1.0
Thanks,
Andrew Fish
> ////////////////////////////////////////////////////////////////////
> /** @file
> Brief Description of UEFI MyHelloWorld
> Detailed Description of UEFI MyHelloWorld
> Copyright for UEFI MyHelloWorld
> License for UEFI MyHelloWorld
> **/
>
> #pragma warning( disable : 4090 ) //couldn't find a way around this...maybe
> someone can post the fix
>
You are converting between CONST and non-CONST device paths without casting.
That changes the compilers view of the variable type, so you have to cast to be
explicit.
> //relative to MyWorkspace/MdePkg/Include/...
> #include <Uefi.h>
> #include <Library/UefiApplicationEntryPoint.h>
You don’t need this include.
> #include <Library/UefiLib.h>
> #include <Protocol/SimpleFileSystem.h>
> #include <Library/MemoryAllocationLib.h>
> #include <Guid/FileInfo.h>
> #include <Library/DebugLib.h>
> #include <Library/DevicePathLib.h> //for FileDevicePath
>
> EFI_GUID gEfiSimpleFileSystemProtocolGuid =
> EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID;
You don’t need this, just add it to the INF [Protocols] section and the global
will exist when you link, the extern is in <Protocol/SimpleFileSystem.h>
> EFI_BOOT_SERVICES *gBS;
You don’t need this, and it will likely break other compilers (Duplicate
definition).
You should just add:
#include <Library/UefiBootServicesTableLib.h>
and this to the INF file [LibraryClasses] section
UefiBootServicesTableLib
>
> EFI_STATUS
> EFIAPI
> ProcessFilesInDir (
> IN EFI_FILE_HANDLE Dir,
> IN EFI_DEVICE_PATH CONST *DirDp
> );
>
> EFI_STATUS
> EFIAPI PerFileFunc (
> IN EFI_FILE_HANDLE Dir,
> IN EFI_DEVICE_PATH *DirDp,
> IN EFI_FILE_INFO *FileInfo,
> IN EFI_DEVICE_PATH *Dp
> );
>
> /**
> The entry point for the application.
>
> @param[in] ImageHandle The firmware allocated handle for the EFI image.
> @param[in] SystemTable A pointer to the EFI System Table.
>
> @retval EFI_SUCCESS The entry point is executed successfully.
> @retval other Some error occurs when executing this entry point.
>
> loop through all volumes and recurse through all files in
> each volume and call a user defined function to do
> some processing on each file
> */
> EFI_STATUS
> EFIAPI
> UefiMain (
> IN EFI_HANDLE ImageHandle,
> IN EFI_SYSTEM_TABLE *SystemTable
> )
> {
> EFI_HANDLE AgentHandle;
> EFI_STATUS Status;
> UINTN NumHandles;
> EFI_HANDLE *Handles;
> UINTN Index;
> VOID *Context;
>
> AgentHandle = ImageHandle;
>
> // gets all handles with simple file system installed
> Status = gBS->LocateHandleBuffer (
> ByProtocol,
> &gEfiSimpleFileSystemProtocolGuid,
> NULL,
> &NumHandles,
> &Handles
> );
> if (EFI_ERROR (Status)) {
> return Status;
> }
>
> // loop through all handles we just got
> for (Index = 0; Index < NumHandles; Index++) {
> EFI_FILE_HANDLE Root;
> EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Fs;
> EFI_DEVICE_PATH *Dp;
>
> // get simple file system protocol instance
> // from current handle
> Status = gBS->OpenProtocol (
> Handles[Index],
> &gEfiSimpleFileSystemProtocolGuid,
> &Fs,
> NULL,
> AgentHandle,
> EFI_OPEN_PROTOCOL_GET_PROTOCOL
> );
> if (EFI_ERROR (Status)) {
> DEBUG ((EFI_D_ERROR, "Missing EFI_SIMPLE_FILE_SYSTEM_PROTOCOL on
> handle.\n"));
> continue;
> }
>
> // get device path instance from current handle
> Status = gBS->OpenProtocol (
> Handles[Index],
> &gEfiDevicePathProtocolGuid,
> &Dp,
> NULL,
> AgentHandle,
> EFI_OPEN_PROTOCOL_GET_PROTOCOL
> );
> if (EFI_ERROR (Status)) {
> DEBUG ((EFI_D_ERROR, "Missing EFI_DEVICE_PATH_PROTOCOL on handle.\n"));
> continue;
> }
>
> // open root dir from current simple file system
> Status = Fs->OpenVolume (Fs, &Root);
> if (EFI_ERROR (Status)) {
> DEBUG ((EFI_D_ERROR, "Unable to open volume.\n"));
> continue;
> }
>
> // recursively process files in root dir
> Context = NULL;
> Status = ProcessFilesInDir (Root, Dp);
> Root->Close (Root);
> if (EFI_ERROR (Status)) {
> DEBUG ((EFI_D_ERROR, "ProcessFilesInDir error. Continuing with next
> volume...\n"));
> continue;
> }
>
> }
>
> Print(L"Done successfully\n");
>
> return EFI_SUCCESS;
> }
>
> //I have no idea what the max length of a file path is in EFI
> #define MAX_FILE_INFO_SIZE 1024
>
> /**
> recurse through directory, calling a user defined
> function for each file
> */
> EFI_STATUS
> EFIAPI
> ProcessFilesInDir (
> IN EFI_FILE_HANDLE Dir,
> IN EFI_DEVICE_PATH CONST *DirDp
> )
> {
> EFI_STATUS Status;
> EFI_FILE_INFO *FileInfo;
> CHAR16 *FileName;
> UINTN FileInfoSize;
> EFI_DEVICE_PATH *Dp;
>
> // big enough to hold EFI_FILE_INFO struct and
> // the whole file path
> FileInfo = AllocatePool (MAX_FILE_INFO_SIZE);
> if (FileInfo == NULL) {
> return EFI_OUT_OF_RESOURCES;
> }
>
> for (;;) {
> // get the next file's info. there's an internal position
> // that gets incremented when you read from a directory
> // so that subsequent reads gets the next file's info
> FileInfoSize = MAX_FILE_INFO_SIZE;
> Status = Dir->Read (Dir, &FileInfoSize, (VOID *) FileInfo);
> if (EFI_ERROR (Status) || FileInfoSize == 0) { //this is how we
> eventually exit this function when we run out of files
> if (Status == EFI_BUFFER_TOO_SMALL) {
> Print (L"EFI_FILE_INFO > MAX_FILE_INFO_SIZE. Increase the size\n");
> }
> FreePool (FileInfo);
> return Status;
> }
>
> FileName = FileInfo->FileName;
>
> // skip files named . or ..
> if (StrCmp (FileName, L".") == 0 || StrCmp (FileName, L"..") == 0) {
> continue;
> }
>
> // so we have absolute device path to child file/dir
> Dp = FileDevicePath (DirDp, FileName);
> if (Dp == NULL) {
> FreePool (FileInfo);
> return EFI_OUT_OF_RESOURCES;
> }
>
> // Do whatever processing on the file
> PerFileFunc (Dir, DirDp, FileInfo, Dp);
>
> if (FileInfo->Attribute & EFI_FILE_DIRECTORY) {
> //
> // recurse
> //
>
> EFI_FILE_HANDLE NewDir;
>
> Status = Dir->Open (Dir, &NewDir, FileName, EFI_FILE_MODE_READ, 0);
> if (Status != EFI_SUCCESS) {
> FreePool (FileInfo);
> FreePool (Dp);
> return Status;
> }
> NewDir->SetPosition (NewDir, 0);
>
> Status = ProcessFilesInDir (NewDir,Dp);
> Dir->Close (NewDir);
> if (Status != EFI_SUCCESS) {
> FreePool (FileInfo);
> FreePool (Dp);
> return Status;
> }
> }
>
> FreePool (Dp);
> }
> }
>
> EFI_STATUS
> EFIAPI PerFileFunc (
> IN EFI_FILE_HANDLE Dir,
> IN EFI_DEVICE_PATH *DirDp,
> IN EFI_FILE_INFO *FileInfo,
> IN EFI_DEVICE_PATH *Dp
> )
> {
> EFI_STATUS Status;
> EFI_FILE_HANDLE File;
>
> Print (L"Path = %s FileName = %s\n", ConvertDevicePathToText(DirDp, TRUE,
> TRUE), FileInfo->FileName);
>
> // read the file into a buffer
> Status = Dir->Open (Dir, &File, FileInfo->FileName, EFI_FILE_MODE_READ, 0);
> if (EFI_ERROR (Status)) {
> return Status;
> }
>
> // reset position just in case
> File->SetPosition (File, 0);
>
> // ****Do stuff on the file here****
>
> Dir->Close (File);
>
> return EFI_SUCCESS;
> }
>
> ////////////////////////////////////////////////////////////////////
>
> V/R
>
> JRS
>
>
> On Thu, Dec 11, 2014 at 2:50 PM, Thomas Rognon <tcrog...@gmail.com
> <mailto:tcrog...@gmail.com>> wrote:
> oops ignore FsHandle parameter in ProcessFiles()
>
> On Thu, Dec 11, 2014 at 1:47 PM, Thomas Rognon <tcrog...@gmail.com
> <mailto:tcrog...@gmail.com>> wrote:
> I was bored and feeling in high spirits, so I wrote some code for you. Also,
> I agree it would be nice to have example snippets on the tianocore website
> for common tasks. If someone sets that up, I'd contribute.
>
> I didn't compile this, so please forgive any mistakes.
>
> /**
> loop through all volumes and recurse through all files in
> each volume and call a user defined function to do
> some processing on each file
> */
> EFI_STATUS
> EFIAPI
> ProcessFiles (
> IN EFI_HANDLE AgentHandle,
> IN EFI_HANDLE FsHandle,
> IN PROCESS_FILES_CALLOUT Callout,
> IN VOID *Context
> )
> {
> EFI_STATUS Status;
> UINTN NumHandles;
> EFI_HANDLE *Handles;
> UINTN Index;
>
> // gets all handles with simple file system installed
> Status = gBS->LocateHandleBuffer (
> ByProtocol,
> &gEfiSimpleFileSystemProtocolGuid,
> NULL,
> &NumHandles,
> &Handles
> );
> if (EFI_ERROR (Status)) {
> return Status;
> }
>
> // loop through all handles we just got
> for (Index = 0; Index < NumHandles; Index++) {
> EFI_FILE_HANDLE Root;
> EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Fs;
> EFI_DEVICE_PATH *Dp;
>
> // get simple file system protocol instance
> // from current handle
> Status = gBS->OpenProtocol (
> Handles[Index],
> &gEfiSimpleFileSystemProtocolGuid,
> &Fs,
> NULL,
> AgentHandle,
> EFI_OPEN_PROTOCOL_GET_PROTOCOL
> );
> if (EFI_ERROR (Status)) {
> DEBUG ((EFI_D_ERROR, "Missing EFI_SIMPLE_FILE_SYSTEM_PROTOCOL on
> handle.\n"));
> continue;
> }
>
> // get device path instance from current handle
> Status = gBS->OpenProtocol (
> Handles[Index],
> &gEfiDevicePathProtocolGuid,
> &Dp,
> NULL,
> AgentHandle,
> EFI_OPEN_PROTOCOL_GET_PROTOCOL
> );
> if (EFI_ERROR (Status)) {
> DEBUG ((EFI_D_ERROR, "Missing EFI_DEVICE_PATH_PROTOCOL on handle.\n"));
> continue;
> }
>
> // open root dir from current simple file system
> Status = Fs->OpenVolume (Fs, &Root);
> if (EFI_ERROR (Status)) {
> DEBUG ((EFI_D_ERROR, "Unable to open volume.\n"));
> continue;
> }
>
> // recursively process files in root dir
> Status = ProcessFilesInDir (
> Root,
> Dp,
> Callout,
> Context
> );
> Root->Close (Root);
> if (EFI_ERROR (Status)) {
> DEBUG ((EFI_D_ERROR, "ProcessFilesInDir error. Continuing with next
> volume...\n"));
> continue;
> }
> }
>
> return EFI_SUCCESS;
> }
>
> /**
> recurse through directory, calling a user defined
> function for each file
> */
> EFI_STATUS
> EFIAPI
> ProcessFilesInDir (
> IN EFI_FILE_HANDLE Dir,
> IN EFI_DEVICE_PATH CONST *DirDp,
> IN PROCESS_FILES_CALLOUT Callout,
> IN VOID *Context
> )
> {
> EFI_STATUS Status;
> EFI_FILE_INFO *FileInfo;
> CHAR16 *FileName;
> UINTN FileInfoSize;
> EFI_DEVICE_PATH *Dp;
> EFI_FILE_HANDLE File;
>
> // big enough to hold EFI_FILE_INFO struct and
> // the whole file path
> FileInfo = AllocatePool (MAX_FILE_INFO_SIZE);
> if (FileInfo == NULL) {
> return EFI_OUT_OF_RESOURCES;
> }
>
> for (;;) {
> // get the next file's info. there's an internal position
> // that gets incremented when you read from a directory
> // so that subsequent reads gets the next file's info
> FileInfoSize = MAX_FILE_INFO_SIZE;
> Status = Dir->Read (Dir, &FileInfoSize, (VOID *) FileInfo);
> if (EFI_ERROR (Status) || FileInfoSize == 0) {
> FreePool (FileInfo);
> return Status;
> }
>
> FileName = FileInfo->FileName;
>
> // skip files named . or ..
> if (StrCmp (FileName, L".") == 0 || StrCmp (FileName, L"..") == 0) {
> continue;
> }
>
> // so we have absolute device path to child file/dir
> Dp = AppendFileDevicePath (DirDp, FileName);
> if (Dp == NULL) {
> FreePool (FileInfo);
> return EFI_OUT_OF_RESOURCES;
> }
>
> // read the file into a buffer
> Status = Dir->Open (Dir, &File, FileName, EFI_FILE_MODE_READ, 0);
> if (EFI_ERROR (Status)) {
> FreePool (FileInfo);
> FreePool (Dp);
> return Status;
> }
> // reset position just in case
> File->SetPosition (File, 0);
>
> // send all this stuff to a callout for processing
> Callout (Dp, FileInfo, File, Context);
>
> Dir->Close (File);
>
> if (FileInfo->Attribute & EFI_FILE_DIRECTORY) {
> //
> // recurse
> //
>
> EFI_FILE_HANDLE NewDir;
>
> Status = Dir->Open (Dir, &NewDir, FileName, EFI_FILE_MODE_READ, 0);
> if (Status != EFI_SUCCESS) {
> FreePool (FileInfo);
> FreePool (Dp);
> return Status;
> }
> NewDir->SetPosition (NewDir, 0);
> Status = ProcessFilesInDir (
> NewDir,
> Dp,
> Callout,
> Context
> );
> Dir->Close (NewDir);
> if (Status != EFI_SUCCESS) {
> FreePool (FileInfo);
> FreePool (Dp);
> return Status;
> }
> }
>
> FreePool (Dp);
> }
> }
>
>
>
> On Thu, Dec 11, 2014 at 1:31 PM, John Smith <johnrandomsmi...@gmail.com
> <mailto:johnrandomsmi...@gmail.com>> wrote:
> Thank you, that looks like it will get me very close. I had went into the
> ShellPkg at one point while wandering the directory structure, but went into
> Application rather than Library and then finding nothing I backed out and
> went elsewhere (BDS).
>
> V/R
>
> JRS
>
> On Thu, Dec 11, 2014 at 2:02 PM, Thomas Rognon <tcrog...@gmail.com
> <mailto:tcrog...@gmail.com>> wrote:
> Not skeleton code, but look at ls in ShellPkg
>
> https://svn.code.sf.net/p/edk2/code/trunk/edk2/ShellPkg/Library/UefiShellLevel2CommandsLib/Ls.c
>
> <https://svn.code.sf.net/p/edk2/code/trunk/edk2/ShellPkg/Library/UefiShellLevel2CommandsLib/Ls.c>
>
> On Thu, Dec 11, 2014 at 11:35 AM, John Smith <johnrandomsmi...@gmail.com
> <mailto:johnrandomsmi...@gmail.com>> wrote:
> Anyone know where I can get an example of walking through the filesystem with
> a UEFI application?
>
> More generally, is there a set of skeleton code examples like Microsoft does
> for kernel development?
>
> V/R
>
> JRS
>
> ------------------------------------------------------------------------------
> Download BIRT iHub F-Type - The Free Enterprise-Grade BIRT Server
> from Actuate! Instantly Supercharge Your Business Reports and Dashboards
> with Interactivity, Sharing, Native Excel Exports, App Integration & more
> Get technology previously reserved for billion-dollar corporations, FREE
> http://pubads.g.doubleclick.net/gampad/clk?id=164703151&iu=/4140/ostg.clktrk
> <http://pubads.g.doubleclick.net/gampad/clk?id=164703151&iu=/4140/ostg.clktrk>
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.sourceforge.net <mailto:edk2-devel@lists.sourceforge.net>
> https://lists.sourceforge.net/lists/listinfo/edk2-devel
> <https://lists.sourceforge.net/lists/listinfo/edk2-devel>
>
>
> ------------------------------------------------------------------------------
> Download BIRT iHub F-Type - The Free Enterprise-Grade BIRT Server
> from Actuate! Instantly Supercharge Your Business Reports and Dashboards
> with Interactivity, Sharing, Native Excel Exports, App Integration & more
> Get technology previously reserved for billion-dollar corporations, FREE
> http://pubads.g.doubleclick.net/gampad/clk?id=164703151&iu=/4140/ostg.clktrk
> <http://pubads.g.doubleclick.net/gampad/clk?id=164703151&iu=/4140/ostg.clktrk>
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.sourceforge.net <mailto:edk2-devel@lists.sourceforge.net>
> https://lists.sourceforge.net/lists/listinfo/edk2-devel
> <https://lists.sourceforge.net/lists/listinfo/edk2-devel>
>
>
>
> ------------------------------------------------------------------------------
> Download BIRT iHub F-Type - The Free Enterprise-Grade BIRT Server
> from Actuate! Instantly Supercharge Your Business Reports and Dashboards
> with Interactivity, Sharing, Native Excel Exports, App Integration & more
> Get technology previously reserved for billion-dollar corporations, FREE
> http://pubads.g.doubleclick.net/gampad/clk?id=164703151&iu=/4140/ostg.clktrk
> <http://pubads.g.doubleclick.net/gampad/clk?id=164703151&iu=/4140/ostg.clktrk>
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.sourceforge.net <mailto:edk2-devel@lists.sourceforge.net>
> https://lists.sourceforge.net/lists/listinfo/edk2-devel
> <https://lists.sourceforge.net/lists/listinfo/edk2-devel>
>
>
> ------------------------------------------------------------------------------
> Download BIRT iHub F-Type - The Free Enterprise-Grade BIRT Server
> from Actuate! Instantly Supercharge Your Business Reports and Dashboards
> with Interactivity, Sharing, Native Excel Exports, App Integration & more
> Get technology previously reserved for billion-dollar corporations, FREE
> http://pubads.g.doubleclick.net/gampad/clk?id=164703151&iu=/4140/ostg.clktrk
> <http://pubads.g.doubleclick.net/gampad/clk?id=164703151&iu=/4140/ostg.clktrk>
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.sourceforge.net <mailto:edk2-devel@lists.sourceforge.net>
> https://lists.sourceforge.net/lists/listinfo/edk2-devel
> <https://lists.sourceforge.net/lists/listinfo/edk2-devel>
>
>
> ------------------------------------------------------------------------------
> Download BIRT iHub F-Type - The Free Enterprise-Grade BIRT Server
> from Actuate! Instantly Supercharge Your Business Reports and Dashboards
> with Interactivity, Sharing, Native Excel Exports, App Integration & more
> Get technology previously reserved for billion-dollar corporations, FREE
> http://pubads.g.doubleclick.net/gampad/clk?id=164703151&iu=/4140/ostg.clktrk_______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/edk2-devel
------------------------------------------------------------------------------
Download BIRT iHub F-Type - The Free Enterprise-Grade BIRT Server
from Actuate! Instantly Supercharge Your Business Reports and Dashboards
with Interactivity, Sharing, Native Excel Exports, App Integration & more
Get technology previously reserved for billion-dollar corporations, FREE
http://pubads.g.doubleclick.net/gampad/clk?id=164703151&iu=/4140/ostg.clktrk
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel