> 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

Reply via email to