How to get page break functionality in UEFI applications


Konstantin Aladyshev
 

All UEFI shell commands have page break functionality.
If the command is called with the "-b" argument and the output is too
long, output would be splitted to pages with this message after each
page:
```
Press ENTER to continue or 'Q' break:
```
How to get this functionality in your custom UEFI applications?

I've tried to use `ShellCEntryLib` as the entry point and have changed
all of my `Print(...)` statements to the `ShellPrintEx(-1,-1,...)` in
my UEFI application, but none of that have worked.

From the inspection of code I see that the aforementioned string is
defined in a file
https://github.com/tianocore/edk2/blob/master/ShellPkg/Application/Shell/Shell.uni
and used in a file
https://github.com/tianocore/edk2/blob/master/ShellPkg/Application/Shell/ConsoleLogger.c
in a `ConsoleLoggerPrintWithPageBreak` function.

`ConsoleLoggerPrintWithPageBreak` is called from the
`ConsoleLoggerOutputString` function, which itself is set to the
`(*ConsoleInfo)->OurConOut.OutputString`.

But in the same file I see:
`gST->ConOut = &(*ConsoleInfo)->OurConOut;`

As the `Print` function uses `gST->ConOut->OutputString` internally,
in the end it looks like it should call
`ConsoleLoggerPrintWithPageBreak`. But apparently this is not
happening? Why? What am I missing here?

ShellLib library class is included in my DSC file:
```
[LibraryClasses]
ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
```
As `-?` option produces some output, I guess command line argument
parsing is happening successfully:
```
FS0:\> GOPInfo.efi -?
No help could be found for command 'GOPInfo.efi'.
```

Best regards,
Konstantin Aladyshev


Konstantin Aladyshev
 

I've managed to get the aforementioned functionality by using `EnablePageBreak` function from the EFI_SHELL_PROTOCOL:
```
EFI_SHELL_PROTOCOL* ShellProtocol;
Status = gBS->LocateProtocol(
&gEfiShellProtocolGuid,
NULL,
(VOID **)&ShellProtocol
);

if (EFI_ERROR(Status)) {
Print(L"Can't open EFI_SHELL_PROTOCOL: %r\n", Status);
return EFI_SUCCESS;
}

Print(L"PageBreak %s\n", (ShellProtocol->GetPageBreak()) ? L"enabled" : L"disabled");

ShellProtocol->EnablePageBreak();
```

But I still want to know, how to get automatic `-b` parameter parsing in your apps.

Also with this approach I've noticed that the `PageBreak` is always disabled at the start of an application. Why is this happening if `EFI_SHELL_PROTOCOL` is a global protocol? Why `PageBreak` is not enabled on the second launch of my application?