971 lines
26 KiB
C
971 lines
26 KiB
C
/*++
|
|
|
|
Copyright (c) 1998 Intel Corporation
|
|
|
|
Module Name:
|
|
|
|
protid.c
|
|
|
|
Abstract:
|
|
|
|
Shell environment protocol id information management
|
|
|
|
|
|
|
|
Revision History
|
|
|
|
--*/
|
|
|
|
#include "shelle.h"
|
|
#include "efivar.h"
|
|
#include "LegacyBoot.h"
|
|
#include "VgaClass.h"
|
|
#include "EfiConSplit.h"
|
|
#include "intload.h"
|
|
|
|
#define PROTOCOL_INFO_SIGNATURE EFI_SIGNATURE_32('s','p','i','n')
|
|
|
|
typedef struct {
|
|
UINTN Signature;
|
|
LIST_ENTRY Link;
|
|
|
|
/* parsing info for the protocol */
|
|
|
|
EFI_GUID ProtocolId;
|
|
CHAR16 *IdString;
|
|
SHELLENV_DUMP_PROTOCOL_INFO DumpToken;
|
|
SHELLENV_DUMP_PROTOCOL_INFO DumpInfo;
|
|
|
|
/* database info on which handles are supporting this protocol */
|
|
|
|
UINTN NoHandles;
|
|
EFI_HANDLE *Handles;
|
|
|
|
} PROTOCOL_INFO;
|
|
|
|
|
|
struct {
|
|
CHAR16 *IdString;
|
|
SHELLENV_DUMP_PROTOCOL_INFO DumpInfo;
|
|
SHELLENV_DUMP_PROTOCOL_INFO DumpToken;
|
|
EFI_GUID ProtocolId;
|
|
} SEnvInternalProtocolInfo[] = {
|
|
L"DevIo", NULL, NULL, DEVICE_IO_PROTOCOL,
|
|
L"fs", NULL, NULL, SIMPLE_FILE_SYSTEM_PROTOCOL,
|
|
L"diskio", NULL, NULL, DISK_IO_PROTOCOL,
|
|
L"blkio", SEnvBlkIo, NULL, BLOCK_IO_PROTOCOL,
|
|
L"txtin", NULL, NULL, SIMPLE_TEXT_INPUT_PROTOCOL,
|
|
L"txtout", SEnvTextOut, NULL, SIMPLE_TEXT_OUTPUT_PROTOCOL,
|
|
L"fs", NULL, NULL, SIMPLE_FILE_SYSTEM_PROTOCOL,
|
|
L"load", NULL, NULL, LOAD_FILE_PROTOCOL,
|
|
L"image", SEnvImage, SEnvImageTok, LOADED_IMAGE_PROTOCOL,
|
|
L"varstore", NULL, NULL, VARIABLE_STORE_PROTOCOL,
|
|
L"unicode", NULL, NULL, UNICODE_COLLATION_PROTOCOL,
|
|
L"LegacyBoot", NULL, NULL, LEGACY_BOOT_PROTOCOL,
|
|
L"serialio", NULL, NULL, SERIAL_IO_PROTOCOL,
|
|
L"pxebc", NULL, NULL, EFI_PXE_BASE_CODE_PROTOCOL,
|
|
L"net", NULL, NULL, EFI_SIMPLE_NETWORK_PROTOCOL,
|
|
L"VgaClass", NULL, NULL, VGA_CLASS_DRIVER_PROTOCOL,
|
|
L"TxtOutSplit", NULL, NULL, TEXT_OUT_SPLITER_PROTOCOL,
|
|
L"ErrOutSplit", NULL, NULL, ERROR_OUT_SPLITER_PROTOCOL,
|
|
L"TxtInSplit", NULL, NULL, TEXT_IN_SPLITER_PROTOCOL,
|
|
|
|
L"dpath", SEnvDPath, SEnvDPathTok, DEVICE_PATH_PROTOCOL,
|
|
/* just plain old protocol ids */
|
|
|
|
L"ShellInt", NULL, NULL, SHELL_INTERFACE_PROTOCOL,
|
|
L"SEnv", NULL, NULL, ENVIRONMENT_VARIABLE_ID,
|
|
L"ShellProtId", NULL, NULL, PROTOCOL_ID_ID,
|
|
L"ShellDevPathMap", NULL, NULL, DEVICE_PATH_MAPPING_ID,
|
|
L"ShellAlias", NULL, NULL, ALIAS_ID,
|
|
|
|
/* ID guids */
|
|
L"G0", NULL, NULL, { 0,0,0,0,0,0,0,0,0,0,0 },
|
|
L"Efi", NULL, NULL, EFI_GLOBAL_VARIABLE,
|
|
L"GenFileInfo", NULL, NULL, EFI_FILE_INFO_ID,
|
|
L"FileSysInfo", NULL, NULL, EFI_FILE_SYSTEM_INFO_ID,
|
|
L"PcAnsi", NULL, NULL, DEVICE_PATH_MESSAGING_PC_ANSI,
|
|
L"Vt100", NULL, NULL, DEVICE_PATH_MESSAGING_VT_100,
|
|
L"InternalLoad", NULL, NULL, INTERNAL_LOAD_PROTOCOL,
|
|
L"Unknown Device", NULL, NULL, UNKNOWN_DEVICE_GUID,
|
|
NULL
|
|
} ;
|
|
|
|
/*
|
|
* SEnvProtocolInfo - A list of all known protocol info structures
|
|
*/
|
|
|
|
LIST_ENTRY SEnvProtocolInfo;
|
|
|
|
/*
|
|
*
|
|
*/
|
|
|
|
VOID
|
|
INTERNAL
|
|
SEnvInitProtocolInfo (
|
|
VOID
|
|
)
|
|
{
|
|
InitializeListHead (&SEnvProtocolInfo);
|
|
}
|
|
|
|
|
|
VOID
|
|
INTERNAL
|
|
SEnvLoadInternalProtInfo (
|
|
VOID
|
|
)
|
|
/* Initialize internal protocol handlers */
|
|
{
|
|
UINTN Index;
|
|
|
|
for (Index=0; SEnvInternalProtocolInfo[Index].IdString; Index += 1) {
|
|
SEnvAddProtocol (
|
|
&SEnvInternalProtocolInfo[Index].ProtocolId,
|
|
SEnvInternalProtocolInfo[Index].DumpToken,
|
|
SEnvInternalProtocolInfo[Index].DumpInfo,
|
|
SEnvInternalProtocolInfo[Index].IdString
|
|
);
|
|
}
|
|
}
|
|
|
|
|
|
PROTOCOL_INFO *
|
|
SEnvGetProtById (
|
|
IN EFI_GUID *Protocol,
|
|
IN BOOLEAN GenId
|
|
)
|
|
/* Locate a protocol handle by guid */
|
|
{
|
|
PROTOCOL_INFO *Prot;
|
|
LIST_ENTRY *Link;
|
|
UINTN LastId, Id;
|
|
CHAR16 s[40];
|
|
|
|
ASSERT_LOCKED(&SEnvGuidLock);
|
|
|
|
/*
|
|
* Find the protocol entry for this id
|
|
*/
|
|
|
|
LastId = 0;
|
|
for (Link=SEnvProtocolInfo.Flink; Link != &SEnvProtocolInfo; Link=Link->Flink) {
|
|
Prot = CR(Link, PROTOCOL_INFO, Link, PROTOCOL_INFO_SIGNATURE);
|
|
if (CompareGuid(&Prot->ProtocolId, Protocol) == 0) {
|
|
return Prot;
|
|
}
|
|
|
|
if (Prot->IdString[0] == 'g') {
|
|
Id = Atoi(Prot->IdString+1);
|
|
LastId = Id > LastId ? Id : LastId;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* If the protocol id is not found, gen a string for it if needed
|
|
*/
|
|
|
|
Prot = NULL;
|
|
if (GenId) {
|
|
SPrint (s, sizeof(s), L"g%d", LastId+1);
|
|
Prot = AllocateZeroPool (sizeof(PROTOCOL_INFO));
|
|
if (Prot) {
|
|
Prot->Signature = PROTOCOL_INFO_SIGNATURE;
|
|
CopyMem (&Prot->ProtocolId, Protocol, sizeof(EFI_GUID));
|
|
Prot->IdString = StrDuplicate(s);
|
|
InsertTailList (&SEnvProtocolInfo, &Prot->Link);
|
|
}
|
|
}
|
|
|
|
return Prot;
|
|
}
|
|
|
|
|
|
|
|
PROTOCOL_INFO *
|
|
SEnvGetProtByStr (
|
|
IN CHAR16 *Str
|
|
)
|
|
{
|
|
PROTOCOL_INFO *Prot;
|
|
LIST_ENTRY *Link;
|
|
UINTN Index;
|
|
EFI_GUID Guid;
|
|
CHAR16 c;
|
|
CHAR16 *p;
|
|
|
|
ASSERT_LOCKED(&SEnvGuidLock);
|
|
|
|
/* Search for short name match */
|
|
for (Link=SEnvProtocolInfo.Flink; Link != &SEnvProtocolInfo; Link=Link->Flink) {
|
|
Prot = CR(Link, PROTOCOL_INFO, Link, PROTOCOL_INFO_SIGNATURE);
|
|
if (StriCmp(Prot->IdString, Str) == 0) {
|
|
return Prot;
|
|
}
|
|
}
|
|
|
|
/* Convert Str to guid and then match */
|
|
if (StrLen(Str) == 36 && Str[9] == '-' && Str[19] == '-' && Str[24] == '-') {
|
|
Guid.Data1 = (UINT32) xtoi(Str+0);
|
|
Guid.Data2 = (UINT16) xtoi(Str+10);
|
|
Guid.Data3 = (UINT16) xtoi(Str+15);
|
|
for (Index=0; Index < 8; Index++) {
|
|
p = Str+25+Index*2;
|
|
c = p[3];
|
|
p[3] = 0;
|
|
Guid.Data4[Index] = (UINT8) xtoi(p);
|
|
p[3] = c;
|
|
}
|
|
|
|
for (Link=SEnvProtocolInfo.Flink; Link != &SEnvProtocolInfo; Link=Link->Flink) {
|
|
Prot = CR(Link, PROTOCOL_INFO, Link, PROTOCOL_INFO_SIGNATURE);
|
|
if (CompareGuid(&Prot->ProtocolId, &Guid) == 0) {
|
|
return Prot;
|
|
}
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
EFI_STATUS
|
|
SEnvIGetProtID (
|
|
IN CHAR16 *Str,
|
|
OUT EFI_GUID *ProtId
|
|
)
|
|
{
|
|
PROTOCOL_INFO *Prot;
|
|
EFI_STATUS Status;
|
|
|
|
AcquireLock (&SEnvGuidLock);
|
|
|
|
Status = EFI_NOT_FOUND;
|
|
CopyMem (ProtId, &NullGuid, sizeof(EFI_GUID));
|
|
|
|
Prot = SEnvGetProtByStr (Str);
|
|
if (Prot) {
|
|
CopyMem (ProtId, &Prot->ProtocolId, sizeof(EFI_GUID));
|
|
Status = EFI_SUCCESS;
|
|
}
|
|
|
|
ReleaseLock (&SEnvGuidLock);
|
|
|
|
return Status;
|
|
}
|
|
|
|
VOID
|
|
SEnvAddProtocol (
|
|
IN EFI_GUID *Protocol,
|
|
IN SHELLENV_DUMP_PROTOCOL_INFO DumpToken OPTIONAL,
|
|
IN SHELLENV_DUMP_PROTOCOL_INFO DumpInfo OPTIONAL,
|
|
IN CHAR16 *IdString
|
|
)
|
|
/* Published interface to add protocol handlers */
|
|
{
|
|
SEnvIAddProtocol (TRUE, Protocol, DumpToken, DumpInfo, IdString);
|
|
}
|
|
|
|
|
|
VOID
|
|
INTERNAL
|
|
SEnvIAddProtocol (
|
|
IN BOOLEAN SaveId,
|
|
IN EFI_GUID *Protocol,
|
|
IN SHELLENV_DUMP_PROTOCOL_INFO DumpToken OPTIONAL,
|
|
IN SHELLENV_DUMP_PROTOCOL_INFO DumpInfo OPTIONAL,
|
|
IN CHAR16 *IdString
|
|
)
|
|
/* Internal interface to add protocol handlers */
|
|
{
|
|
PROTOCOL_INFO *Prot;
|
|
BOOLEAN StoreInfo;
|
|
CHAR16 *ObsoleteName;
|
|
|
|
ObsoleteName = NULL;
|
|
StoreInfo = FALSE;
|
|
|
|
AcquireLock (&SEnvGuidLock);
|
|
|
|
/*
|
|
* Get the current protocol info
|
|
*/
|
|
|
|
Prot = SEnvGetProtById (Protocol, FALSE);
|
|
|
|
if (Prot) {
|
|
/*
|
|
* If the name has changed, delete the old var
|
|
*/
|
|
|
|
if (StriCmp (Prot->IdString, IdString)) {
|
|
ObsoleteName = Prot->IdString;
|
|
StoreInfo = TRUE;
|
|
} else {
|
|
FreePool (Prot->IdString);
|
|
}
|
|
|
|
Prot->IdString = NULL;
|
|
|
|
} else {
|
|
|
|
/*
|
|
* Allocate new protocol info
|
|
*/
|
|
|
|
Prot = AllocateZeroPool (sizeof(PROTOCOL_INFO));
|
|
Prot->Signature = PROTOCOL_INFO_SIGNATURE;
|
|
StoreInfo = TRUE;
|
|
|
|
}
|
|
|
|
/*
|
|
* Apply any updates to the protocol info
|
|
*/
|
|
|
|
if (Prot) {
|
|
CopyMem (&Prot->ProtocolId, Protocol, sizeof(EFI_GUID));
|
|
Prot->IdString = StrDuplicate(IdString);
|
|
Prot->DumpToken = DumpToken;
|
|
Prot->DumpInfo = DumpInfo;
|
|
|
|
if (Prot->Link.Flink) {
|
|
RemoveEntryList (&Prot->Link);
|
|
}
|
|
|
|
InsertTailList (&SEnvProtocolInfo, &Prot->Link);
|
|
}
|
|
|
|
ReleaseLock (&SEnvGuidLock);
|
|
|
|
/*
|
|
* If the name changed, delete the old name
|
|
*/
|
|
|
|
if (ObsoleteName) {
|
|
RT->SetVariable (ObsoleteName, &SEnvProtId, 0, 0, NULL);
|
|
FreePool (ObsoleteName);
|
|
}
|
|
|
|
/*
|
|
* Store the protocol idstring to a variable
|
|
*/
|
|
|
|
if (Prot && StoreInfo && SaveId) {
|
|
RT->SetVariable (
|
|
Prot->IdString,
|
|
&SEnvProtId,
|
|
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
|
|
sizeof(EFI_GUID),
|
|
&Prot->ProtocolId
|
|
);
|
|
}
|
|
}
|
|
|
|
|
|
VOID
|
|
INTERNAL
|
|
SEnvLoadHandleProtocolInfo (
|
|
IN EFI_GUID *SkipProtocol
|
|
)
|
|
/* Code to load the internal handle cross-reference info for each protocol */
|
|
{
|
|
PROTOCOL_INFO *Prot;
|
|
LIST_ENTRY *Link;
|
|
|
|
AcquireLock (&SEnvGuidLock);
|
|
|
|
for (Link=SEnvProtocolInfo.Flink; Link != &SEnvProtocolInfo; Link=Link->Flink) {
|
|
Prot = CR(Link, PROTOCOL_INFO, Link, PROTOCOL_INFO_SIGNATURE);
|
|
if (!SkipProtocol || CompareGuid(SkipProtocol, &Prot->ProtocolId) != 0) {
|
|
LibLocateHandle (
|
|
ByProtocol,
|
|
&Prot->ProtocolId,
|
|
NULL,
|
|
&Prot->NoHandles,
|
|
&Prot->Handles
|
|
);
|
|
}
|
|
}
|
|
|
|
ReleaseLock (&SEnvGuidLock);
|
|
}
|
|
|
|
VOID
|
|
INTERNAL
|
|
SEnvFreeHandleProtocolInfo (
|
|
VOID
|
|
)
|
|
/* Free the internal handle cross-reference protocol info */
|
|
{
|
|
PROTOCOL_INFO *Prot;
|
|
LIST_ENTRY *Link;
|
|
|
|
AcquireLock (&SEnvGuidLock);
|
|
|
|
for (Link=SEnvProtocolInfo.Flink; Link != &SEnvProtocolInfo; Link=Link->Flink) {
|
|
Prot = CR(Link, PROTOCOL_INFO, Link, PROTOCOL_INFO_SIGNATURE);
|
|
|
|
if (Prot->NoHandles) {
|
|
FreePool (Prot->Handles);
|
|
Prot->Handles = NULL;
|
|
Prot->NoHandles = 0;
|
|
}
|
|
}
|
|
|
|
ReleaseLock (&SEnvGuidLock);
|
|
}
|
|
|
|
|
|
CHAR16 *
|
|
INTERNAL
|
|
SEnvIGetProtocol (
|
|
IN EFI_GUID *ProtocolId,
|
|
IN BOOLEAN GenId
|
|
)
|
|
/* Published interface to lookup a protocol id string */
|
|
{
|
|
PROTOCOL_INFO *Prot;
|
|
CHAR16 *Id;
|
|
|
|
ASSERT_LOCKED (&SEnvGuidLock);
|
|
Prot = SEnvGetProtById(ProtocolId, GenId);
|
|
Id = Prot ? Prot->IdString : NULL;
|
|
return Id;
|
|
}
|
|
|
|
CHAR16 *
|
|
SEnvGetProtocol (
|
|
IN EFI_GUID *ProtocolId,
|
|
IN BOOLEAN GenId
|
|
)
|
|
/* Published interface to lookup a protocol id string */
|
|
{
|
|
CHAR16 *Id;
|
|
|
|
AcquireLock (&SEnvGuidLock);
|
|
Id = SEnvIGetProtocol(ProtocolId, GenId);
|
|
ReleaseLock (&SEnvGuidLock);
|
|
return Id;
|
|
}
|
|
|
|
|
|
EFI_STATUS
|
|
INTERNAL
|
|
SEnvCmdProt (
|
|
IN EFI_HANDLE ImageHandle,
|
|
IN EFI_SYSTEM_TABLE *SystemTable
|
|
)
|
|
/* Code for internal "prot" command */
|
|
{
|
|
PROTOCOL_INFO *Prot;
|
|
LIST_ENTRY *Link;
|
|
UINTN Len, SLen;
|
|
CHAR16 *p;
|
|
UINTN Index;
|
|
BOOLEAN PageBreaks;
|
|
UINTN TempColumn;
|
|
UINTN ScreenCount;
|
|
UINTN ScreenSize;
|
|
CHAR16 ReturnStr[1];
|
|
|
|
InitializeShellApplication (ImageHandle, SystemTable);
|
|
|
|
PageBreaks = FALSE;
|
|
for (Index = 1;Index < SI->Argc; Index++) {
|
|
p = SI->Argv[Index];
|
|
if (*p == '-') {
|
|
switch (p[1]) {
|
|
case 'b' :
|
|
case 'B' :
|
|
PageBreaks = TRUE;
|
|
ST->ConOut->QueryMode (ST->ConOut, ST->ConOut->Mode->Mode, &TempColumn, &ScreenSize);
|
|
ScreenCount = 0;
|
|
break;
|
|
default :
|
|
Print(L"guid : Unknown flag %s\n",p);
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
}
|
|
|
|
AcquireLock (&SEnvGuidLock);
|
|
|
|
/*
|
|
* Find the protocol entry for this id
|
|
*/
|
|
|
|
SLen = 0;
|
|
for (Link=SEnvProtocolInfo.Flink; Link != &SEnvProtocolInfo; Link=Link->Flink) {
|
|
Prot = CR(Link, PROTOCOL_INFO, Link, PROTOCOL_INFO_SIGNATURE);
|
|
Len = StrLen(Prot->IdString);
|
|
if (StrLen(Prot->IdString) > SLen) {
|
|
SLen = Len;
|
|
}
|
|
}
|
|
|
|
for (Link=SEnvProtocolInfo.Flink; Link != &SEnvProtocolInfo; Link=Link->Flink) {
|
|
Prot = CR(Link, PROTOCOL_INFO, Link, PROTOCOL_INFO_SIGNATURE);
|
|
|
|
/* Can't use Lib function to dump the guid as it may lookup the "short name" for it */
|
|
|
|
/*
|
|
* BUGBUG : Have to release and reacquire the lock for output redirection of this command
|
|
* to work properly. Otherwise, we get an ASSERT from RaiseTPL().
|
|
*/
|
|
|
|
ReleaseLock (&SEnvGuidLock);
|
|
|
|
Print(L" %h-.*s : %08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x %c\n",
|
|
SLen,
|
|
Prot->IdString,
|
|
Prot->ProtocolId.Data1,
|
|
Prot->ProtocolId.Data2,
|
|
Prot->ProtocolId.Data3,
|
|
Prot->ProtocolId.Data4[0],
|
|
Prot->ProtocolId.Data4[1],
|
|
Prot->ProtocolId.Data4[2],
|
|
Prot->ProtocolId.Data4[3],
|
|
Prot->ProtocolId.Data4[4],
|
|
Prot->ProtocolId.Data4[5],
|
|
Prot->ProtocolId.Data4[6],
|
|
Prot->ProtocolId.Data4[7],
|
|
(Prot->DumpToken || Prot->DumpInfo) ? L'*' : L' '
|
|
);
|
|
|
|
if (PageBreaks) {
|
|
ScreenCount++;
|
|
if (ScreenCount > ScreenSize - 4) {
|
|
ScreenCount = 0;
|
|
Print (L"\nPress Return to contiue :");
|
|
Input (L"", ReturnStr, sizeof(ReturnStr)/sizeof(CHAR16));
|
|
Print (L"\n\n");
|
|
}
|
|
}
|
|
|
|
AcquireLock (&SEnvGuidLock);
|
|
}
|
|
|
|
ReleaseLock (&SEnvGuidLock);
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
SEnvDHProt (
|
|
IN BOOLEAN Verbose,
|
|
IN UINTN HandleNo,
|
|
IN EFI_HANDLE Handle
|
|
)
|
|
{
|
|
PROTOCOL_INFO *Prot;
|
|
LIST_ENTRY *Link;
|
|
VOID *Interface;
|
|
UINTN Index;
|
|
EFI_STATUS Status;
|
|
SHELLENV_DUMP_PROTOCOL_INFO Dump;
|
|
|
|
if (!HandleNo) {
|
|
for (HandleNo=0; HandleNo < SEnvNoHandles; HandleNo++) {
|
|
if (SEnvHandles[HandleNo] == Handle) {
|
|
break;
|
|
}
|
|
}
|
|
HandleNo += 1;
|
|
}
|
|
|
|
Print (Verbose ? L"%NHandle %h02x (%hX)\n" : L"%N %h2x: ", HandleNo, Handle);
|
|
|
|
for (Link=SEnvProtocolInfo.Flink; Link != &SEnvProtocolInfo; Link=Link->Flink) {
|
|
Prot = CR(Link, PROTOCOL_INFO, Link, PROTOCOL_INFO_SIGNATURE);
|
|
for (Index=0; Index < Prot->NoHandles; Index++) {
|
|
|
|
/*
|
|
* If this handle supports this protocol, dump it
|
|
*/
|
|
|
|
if (Prot->Handles[Index] == Handle) {
|
|
Dump = Verbose ? Prot->DumpInfo : Prot->DumpToken;
|
|
Status = BS->HandleProtocol (Handle, &Prot->ProtocolId, &Interface);
|
|
if (Verbose) {
|
|
Print (L" %hs ", Prot->IdString);
|
|
if (Dump && !EFI_ERROR(Status)) {
|
|
Dump (Handle, Interface);
|
|
}
|
|
Print (L"\n");
|
|
} else {
|
|
if (Dump && !EFI_ERROR(Status)) {
|
|
Dump (Handle, Interface);
|
|
} else {
|
|
Print (L"%hs ", Prot->IdString);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Print (Verbose ? L"%N" : L"%N\n");
|
|
}
|
|
|
|
EFI_STATUS
|
|
INTERNAL
|
|
SEnvCmdDH (
|
|
IN EFI_HANDLE ImageHandle,
|
|
IN EFI_SYSTEM_TABLE *SystemTable
|
|
)
|
|
/* Code for internal "DH" command */
|
|
{
|
|
BOOLEAN ByProtocol;
|
|
CHAR16 *Arg, *p;
|
|
EFI_STATUS Status;
|
|
UINTN Index;
|
|
PROTOCOL_INFO *Prot;
|
|
BOOLEAN PageBreaks;
|
|
UINTN TempColumn;
|
|
UINTN ScreenCount;
|
|
UINTN ScreenSize;
|
|
CHAR16 ReturnStr[1];
|
|
|
|
/*
|
|
* Initialize
|
|
*/
|
|
|
|
InitializeShellApplication (ImageHandle, SystemTable);
|
|
|
|
Arg = NULL;
|
|
ByProtocol = FALSE;
|
|
|
|
/*
|
|
* Crack args
|
|
*/
|
|
|
|
PageBreaks = FALSE;
|
|
for (Index = 1; Index < SI->Argc; Index += 1) {
|
|
p = SI->Argv[Index];
|
|
if (*p == '-') {
|
|
switch (p[1]) {
|
|
case 'p':
|
|
case 'P':
|
|
ByProtocol = TRUE;
|
|
break;
|
|
|
|
case 'b' :
|
|
case 'B' :
|
|
PageBreaks = TRUE;
|
|
ST->ConOut->QueryMode (ST->ConOut, ST->ConOut->Mode->Mode, &TempColumn, &ScreenSize);
|
|
ScreenCount = 0;
|
|
break;
|
|
|
|
default:
|
|
Print (L"%EDH: Unkown flag %s\n", p);
|
|
Status = EFI_INVALID_PARAMETER;
|
|
goto Done;
|
|
}
|
|
continue;
|
|
}
|
|
|
|
if (!Arg) {
|
|
Arg = p;
|
|
continue;
|
|
}
|
|
|
|
Print (L"%EDH: too many arguments\n");
|
|
Status = EFI_INVALID_PARAMETER;
|
|
goto Done;
|
|
}
|
|
|
|
/*
|
|
*
|
|
* Load handle & protocol info tables
|
|
*/
|
|
|
|
SEnvLoadHandleTable ();
|
|
SEnvLoadHandleProtocolInfo (NULL);
|
|
|
|
if (Arg) {
|
|
|
|
if (ByProtocol) {
|
|
|
|
AcquireLock (&SEnvGuidLock);
|
|
Prot = SEnvGetProtByStr (Arg);
|
|
ReleaseLock (&SEnvGuidLock);
|
|
|
|
if (Prot) {
|
|
|
|
/* Dump the handles on this protocol */
|
|
Print(L"%NHandle dump by protocol '%s'\n", Prot->IdString);
|
|
for (Index=0; Index < Prot->NoHandles; Index++) {
|
|
SEnvDHProt (FALSE, 0, Prot->Handles[Index]);
|
|
|
|
if (PageBreaks) {
|
|
ScreenCount++;
|
|
if (ScreenCount > ScreenSize - 4) {
|
|
ScreenCount = 0;
|
|
Print (L"\nPress Return to contiue :");
|
|
Input (L"", ReturnStr, sizeof(ReturnStr)/sizeof(CHAR16));
|
|
Print (L"\n\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
} else {
|
|
|
|
Print(L"%EDH: Protocol '%s' not found\n", Arg);
|
|
}
|
|
|
|
} else {
|
|
|
|
/* Dump 1 handle */
|
|
Index = SEnvHandleNoFromStr(Arg) - 1;
|
|
if (Index > SEnvNoHandles) {
|
|
|
|
Print(L"%EDH: Invalid handle #\n");
|
|
|
|
} else {
|
|
|
|
SEnvDHProt (TRUE, Index+1, SEnvHandles[Index]);
|
|
|
|
}
|
|
}
|
|
|
|
} else {
|
|
|
|
/* Dump all handles */
|
|
Print(L"%NHandle dump\n");
|
|
for (Index=0; Index < SEnvNoHandles; Index++) {
|
|
SEnvDHProt (FALSE, Index+1, SEnvHandles[Index]);
|
|
|
|
if (PageBreaks) {
|
|
ScreenCount++;
|
|
if (ScreenCount > ScreenSize - 4) {
|
|
ScreenCount = 0;
|
|
Print (L"\nPress Return to contiue :");
|
|
Input (L"", ReturnStr, sizeof(ReturnStr)/sizeof(CHAR16));
|
|
Print (L"\n\n");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Status = EFI_SUCCESS;
|
|
|
|
Done:
|
|
SEnvFreeHandleTable ();
|
|
return Status;
|
|
}
|
|
|
|
|
|
extern LIST_ENTRY SEnvMap;
|
|
extern LIST_ENTRY SEnvEnv;
|
|
extern LIST_ENTRY SEnvAlias;
|
|
|
|
|
|
EFI_STATUS
|
|
SEnvLoadDefaults (
|
|
IN EFI_HANDLE Image,
|
|
IN EFI_SYSTEM_TABLE *SystemTable
|
|
)
|
|
{
|
|
LIST_ENTRY DefCmds;
|
|
POOL_PRINT Path;
|
|
DEFAULT_CMD *Cmd;
|
|
PROTOCOL_INFO *ProtFs, *ProtBlkIo;
|
|
UINTN Index, HandleNo;
|
|
CHAR16 *DefaultMapping;
|
|
|
|
InitializeShellApplication (Image, SystemTable);
|
|
|
|
/*
|
|
* If we have some settings, use those
|
|
*/
|
|
|
|
if (!IsListEmpty(&SEnvMap) || !IsListEmpty(&SEnvEnv) || !IsListEmpty(&SEnvAlias)) {
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/*
|
|
* There are no settings, build some defaults
|
|
*/
|
|
|
|
InitializeListHead (&DefCmds);
|
|
ZeroMem (&Path, sizeof(Path));
|
|
|
|
AcquireLock (&SEnvLock);
|
|
SEnvLoadHandleTable();
|
|
SEnvLoadHandleProtocolInfo (NULL);
|
|
AcquireLock (&SEnvGuidLock);
|
|
ProtFs = SEnvGetProtByStr(L"fs");
|
|
ProtBlkIo = SEnvGetProtByStr(L"blkio");
|
|
ReleaseLock (&SEnvGuidLock);
|
|
|
|
/*
|
|
* Run all the devices that support a File System and add a default
|
|
* mapping and path setting for each device
|
|
*/
|
|
|
|
CatPrint (&Path, L"set path ");
|
|
for (Index=0; Index < ProtFs->NoHandles; Index++) {
|
|
for (HandleNo=0; HandleNo < SEnvNoHandles; HandleNo++) {
|
|
if (SEnvHandles[HandleNo] == ProtFs->Handles[Index]) {
|
|
break;
|
|
}
|
|
}
|
|
HandleNo += 1;
|
|
|
|
Cmd = AllocateZeroPool(sizeof(DEFAULT_CMD));
|
|
Cmd->Line = Cmd->Buffer;
|
|
SPrint(Cmd->Line, sizeof(Cmd->Buffer), L"map fs%x %x", Index, HandleNo);
|
|
InsertTailList(&DefCmds, &Cmd->Link);
|
|
|
|
/* append this device to the path */
|
|
CatPrint (&Path, L"fs%x:\\efi\\tools;fs%x:\\;", Index, Index);
|
|
}
|
|
CatPrint (&Path, L".");
|
|
|
|
/*
|
|
* Run all the devices that support a BlockIo and add a default
|
|
* mapping for the device
|
|
*/
|
|
|
|
for (Index=0; Index < ProtBlkIo->NoHandles; Index++) {
|
|
for (HandleNo=0; HandleNo < SEnvNoHandles; HandleNo++) {
|
|
if (SEnvHandles[HandleNo] == ProtBlkIo->Handles[Index]) {
|
|
break;
|
|
}
|
|
}
|
|
HandleNo += 1;
|
|
|
|
Cmd = AllocateZeroPool(sizeof(DEFAULT_CMD));
|
|
Cmd->Line = Cmd->Buffer;
|
|
SPrint(Cmd->Line, sizeof(Cmd->Buffer), L"map blk%x %x", Index, HandleNo);
|
|
InsertTailList(&DefCmds, &Cmd->Link);
|
|
}
|
|
|
|
/* release handle table resources & lock */
|
|
SEnvFreeHandleTable();
|
|
ReleaseLock (&SEnvLock);
|
|
|
|
/*
|
|
* execute all the queue commands
|
|
*/
|
|
|
|
while (!IsListEmpty(&DefCmds)) {
|
|
Cmd = CR(DefCmds.Flink, DEFAULT_CMD, Link, 0);
|
|
SEnvExecute (Image, Cmd->Line, TRUE);
|
|
RemoveEntryList (&Cmd->Link);
|
|
FreePool (Cmd);
|
|
}
|
|
|
|
SEnvExecute (Image, Path.str, TRUE);
|
|
SEnvExecute (Image, L"alias dir ls", TRUE);
|
|
SEnvExecute (Image, L"alias md mkdir", TRUE);
|
|
SEnvExecute (Image, L"alias rd rm", TRUE);
|
|
SEnvExecute (Image, L"alias del rm", TRUE);
|
|
SEnvExecute (Image, L"alias copy cp", TRUE);
|
|
|
|
DefaultMapping = SEnvGetDefaultMapping(Image);
|
|
if (DefaultMapping!=NULL) {
|
|
ZeroMem (&Path, sizeof(Path));
|
|
CatPrint(&Path,L"%s:",DefaultMapping);
|
|
SEnvExecute (Image, Path.str, TRUE);
|
|
}
|
|
|
|
FreePool (Path.str);
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
SEnvReloadDefaults (
|
|
IN EFI_HANDLE Image,
|
|
IN EFI_SYSTEM_TABLE *SystemTable
|
|
)
|
|
{
|
|
LIST_ENTRY DefCmds;
|
|
POOL_PRINT Path;
|
|
DEFAULT_CMD *Cmd;
|
|
PROTOCOL_INFO *ProtFs, *ProtBlkIo;
|
|
UINTN Index, HandleNo;
|
|
|
|
InitializeShellApplication (Image, SystemTable);
|
|
|
|
/*
|
|
* There are no settings, build some defaults
|
|
*/
|
|
|
|
InitializeListHead (&DefCmds);
|
|
ZeroMem (&Path, sizeof(Path));
|
|
|
|
AcquireLock (&SEnvLock);
|
|
SEnvLoadHandleTable();
|
|
SEnvLoadHandleProtocolInfo (NULL);
|
|
AcquireLock (&SEnvGuidLock);
|
|
ProtFs = SEnvGetProtByStr(L"fs");
|
|
ProtBlkIo = SEnvGetProtByStr(L"blkio");
|
|
ReleaseLock (&SEnvGuidLock);
|
|
|
|
/*
|
|
* Run all the devices that support a File System and add a default
|
|
* mapping and path setting for each device
|
|
*/
|
|
|
|
CatPrint (&Path, L"set path ");
|
|
for (Index=0; Index < ProtFs->NoHandles; Index++) {
|
|
for (HandleNo=0; HandleNo < SEnvNoHandles; HandleNo++) {
|
|
if (SEnvHandles[HandleNo] == ProtFs->Handles[Index]) {
|
|
break;
|
|
}
|
|
}
|
|
HandleNo += 1;
|
|
|
|
Cmd = AllocateZeroPool(sizeof(DEFAULT_CMD));
|
|
Cmd->Line = Cmd->Buffer;
|
|
SPrint(Cmd->Line, sizeof(Cmd->Buffer), L"map fs%x %x", Index, HandleNo);
|
|
InsertTailList(&DefCmds, &Cmd->Link);
|
|
|
|
/* append this device to the path */
|
|
CatPrint (&Path, L"fs%x:\\efi\\tools;fs%x:\\;", Index, Index);
|
|
}
|
|
CatPrint (&Path, L".");
|
|
|
|
/*
|
|
* Run all the devices that support a BlockIo and add a default
|
|
* mapping for the device
|
|
*/
|
|
|
|
for (Index=0; Index < ProtBlkIo->NoHandles; Index++) {
|
|
for (HandleNo=0; HandleNo < SEnvNoHandles; HandleNo++) {
|
|
if (SEnvHandles[HandleNo] == ProtBlkIo->Handles[Index]) {
|
|
break;
|
|
}
|
|
}
|
|
HandleNo += 1;
|
|
|
|
Cmd = AllocateZeroPool(sizeof(DEFAULT_CMD));
|
|
Cmd->Line = Cmd->Buffer;
|
|
SPrint(Cmd->Line, sizeof(Cmd->Buffer), L"map blk%x %x", Index, HandleNo);
|
|
InsertTailList(&DefCmds, &Cmd->Link);
|
|
}
|
|
|
|
/* release handle table resources & lock */
|
|
SEnvFreeHandleTable();
|
|
ReleaseLock (&SEnvLock);
|
|
|
|
/*
|
|
* execute all the queue commands
|
|
*/
|
|
|
|
while (!IsListEmpty(&DefCmds)) {
|
|
Cmd = CR(DefCmds.Flink, DEFAULT_CMD, Link, 0);
|
|
SEnvExecute (Image, Cmd->Line, TRUE);
|
|
RemoveEntryList (&Cmd->Link);
|
|
FreePool (Cmd);
|
|
}
|
|
|
|
SEnvExecute (Image, Path.str, TRUE);
|
|
|
|
FreePool (Path.str);
|
|
return EFI_SUCCESS;
|
|
}
|
|
|