See the UEFI Shell Specification (currently version 2.2, January 2016) for all the details on the protocol.

There is a page on TianoCore which attempts to explain how to create a UEFI shell application. It was written some time ago and is woefully inadequate for somebody who is trying to learn how to make use of the EFI_SHELL_PROTOCOL. Few of the example applications provided in UDK2015 are invoked in the described manner. The page needs to be completely rewritten and a complete working example included.

Moving on, how can an application access the functions exposed by the EFI_SHELL_PROTOCOL? It turns out that there is a single global instance of the EFI_SHELL_PROTOCOL per shell instance – not one per application. Note, however, if you have nested copies of the UEFI Shell you may have multiple copies of the EFI_SHELL_PROTOCOL protocol. Personally, I have never got nested copies of a UEFI Shell to reliably work for any period of time on any platform so far, including the Intel S1200V3RPS server board which is the current reference board for UEFI development.

One way of accessing the functions exposed by EFI_SHELL_PROTOCOL is via the global pointer gEfiShellProtocol:

As usual, it is assumed that you are familiar with the various UEFI specifications and UDK2015 if you are reading this blog post so no detailed explanation of the code or the build process is provided.

There is a “flaw” in the above code which renders this application unusable in a UEFI shell script. My code returns Status as an exit code; Status is of type EFI_STATUS. If the application is to be used within a script, it needs to return one of the SHELL_STATUS values defined in ShellBase.h.