|
|
/*++
Copyright (c) 1998 Intel Corporation
Module Name:
protid.c Abstract:
Shell environment variable management
Revision History
--*/
#include "shelle.h"
/*
* The different variable catagories */
LIST_ENTRY SEnvEnv; LIST_ENTRY SEnvMap; LIST_ENTRY SEnvAlias;
VOID SEnvInitVariables ( VOID ) { CHAR16 *Name; CHAR16 *Data; UINTN BufferSize; UINTN NameSize, DataSize; EFI_GUID Id; LIST_ENTRY *ListHead; VARIABLE_ID *Var; EFI_STATUS Status; BOOLEAN IsString; UINT32 Attributes; UINTN Size;
/*
* Initialize the different variable lists */
InitializeListHead (&SEnvEnv); InitializeListHead (&SEnvMap); InitializeListHead (&SEnvAlias);
BufferSize = 1024; Name = AllocatePool (BufferSize); Data = AllocatePool (BufferSize); ASSERT(Name && Data);
/*
* Read all the variables in the system and collect ours */
Name[0] = 0; for (; ;) { NameSize = BufferSize; Status = RT->GetNextVariableName (&NameSize, Name, &Id); if (EFI_ERROR(Status)) { break; }
/*
* See if it's a shellenv variable */
ListHead = NULL; IsString = FALSE; if (CompareGuid (&Id, &SEnvEnvId) == 0) { ListHead = &SEnvEnv; IsString = TRUE; }
if (CompareGuid (&Id, &SEnvMapId) == 0) { ListHead = &SEnvMap; }
if (CompareGuid (&Id, &SEnvAliasId) == 0) { ListHead = &SEnvAlias; IsString = TRUE; }
if (ListHead) { DataSize = BufferSize; Status = RT->GetVariable (Name, &Id, &Attributes, &DataSize, Data);
if (!EFI_ERROR(Status)) {
/*
* Add this value */
Size = sizeof(VARIABLE_ID) + StrSize(Name) + DataSize; Var = AllocateZeroPool (Size);
Var->Signature = VARIABLE_SIGNATURE; Var->u.Value = ((UINT8 *) Var) + sizeof(VARIABLE_ID); Var->Name = (CHAR16*) (Var->u.Value + DataSize); Var->ValueSize = DataSize; CopyMem (Var->u.Value, Data, DataSize); CopyMem (Var->Name, Name, NameSize);
if( Attributes & EFI_VARIABLE_NON_VOLATILE ) { Var->Flags = NON_VOL ; } else { Var->Flags = VOL ; }
InsertTailList (ListHead, &Var->Link); } }
/*
* If this is a protocol entry, add it */
if (CompareGuid (&Id, &SEnvProtId) == 0) {
DataSize = BufferSize; Status = RT->GetVariable (Name, &Id, &Attributes, &DataSize, Data);
if (!EFI_ERROR(Status) && DataSize == sizeof (EFI_GUID)) {
SEnvIAddProtocol (FALSE, (EFI_GUID *) Data, NULL, NULL, Name);
} else {
DEBUG ((D_INIT|D_WARN, "SEnvInitVariables: skipping bogus protocol id %s\n", Var->Name)); RT->SetVariable (Name, &SEnvProtId, 0, 0, NULL);
} } }
FreePool (Name); FreePool (Data); }
CHAR16 * SEnvIGetStr ( IN CHAR16 *Name, IN LIST_ENTRY *Head ) { LIST_ENTRY *Link; VARIABLE_ID *Var; CHAR16 *Value;
AcquireLock (&SEnvLock);
Value = NULL; for (Link=Head->Flink; Link != Head; Link=Link->Flink) { Var = CR(Link, VARIABLE_ID, Link, VARIABLE_SIGNATURE); if (StriCmp (Var->Name, Name) == 0) { Value = Var->u.Str; break; } }
ReleaseLock (&SEnvLock); return Value; }
CHAR16 * SEnvGetMap ( IN CHAR16 *Name ) { return SEnvIGetStr (Name, &SEnvMap); }
CHAR16 * SEnvGetEnv ( IN CHAR16 *Name ) { return SEnvIGetStr (Name, &SEnvEnv); }
CHAR16 * SEnvGetAlias ( IN CHAR16 *Name ) { return SEnvIGetStr (Name, &SEnvAlias); }
VOID SEnvSortVarList ( IN LIST_ENTRY *Head ) { ASSERT_LOCKED(&SEnvLock);
return ; }
EFI_STATUS SEnvCmdSA ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable, IN LIST_ENTRY *Head, IN EFI_GUID *Guid ) /* Code for shell "set" & "alias" command */ { LIST_ENTRY *Link; VARIABLE_ID *Var; VARIABLE_ID *Found; CHAR16 *Name; CHAR16 *Value; UINTN Size, SLen, Len; BOOLEAN Delete; EFI_STATUS Status; UINTN Index; CHAR16 *p; BOOLEAN PageBreaks; UINTN TempColumn; UINTN ScreenCount; UINTN ScreenSize; CHAR16 ReturnStr[1]; BOOLEAN Volatile;
InitializeShellApplication (ImageHandle, SystemTable);
Name = NULL; Value = NULL; Delete = FALSE; Status = EFI_SUCCESS; Found = NULL; Volatile = FALSE;
/*
* Crack arguments */
PageBreaks = FALSE; for (Index = 1; Index < SI->Argc; Index += 1) { p = SI->Argv[Index]; if (*p == '-') { switch (p[1]) { case 'd': case 'D': Delete = TRUE; break;
case 'b' : case 'B' : PageBreaks = TRUE; ST->ConOut->QueryMode (ST->ConOut, ST->ConOut->Mode->Mode, &TempColumn, &ScreenSize); ScreenCount = 0; break;
case 'v' : case 'V' : Volatile = TRUE; break;
default: Print (L"%ESet/Alias: Unknown flag %s\n", p); return EFI_INVALID_PARAMETER; } continue; }
if (!Name) { Name = p; continue; }
if (!Value) { Value = p; continue; }
Print (L"%ESet/Alias: too many arguments\n"); return EFI_INVALID_PARAMETER; }
if (Delete && Value) { Print (L"%ESet/Alias: too many arguments\n"); }
/*
* Process */
AcquireLock (&SEnvLock);
if (!Name) { /* dump the list */ SEnvSortVarList (Head);
SLen = 0; for (Link=Head->Flink; Link != Head; Link=Link->Flink) { Var = CR(Link, VARIABLE_ID, Link, VARIABLE_SIGNATURE); Len = StrLen(Var->Name); if (Len > SLen) { SLen = Len; } }
for (Link=Head->Flink; Link != Head; Link=Link->Flink) { Var = CR(Link, VARIABLE_ID, Link, VARIABLE_SIGNATURE); if( Var->Flags == VOL ) { Print(L" * %h-.*s : %s\n", SLen, Var->Name, Var->u.Str); } else { Print(L" %h-.*s : %s\n", SLen, Var->Name, Var->u.Str); }
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 { /*
* Find the specified value */
for (Link=Head->Flink; Link != Head; Link=Link->Flink) { Var = CR(Link, VARIABLE_ID, Link, VARIABLE_SIGNATURE); if (StriCmp(Var->Name, Name) == 0) { Found = Var; break; } }
if (Found && Delete) { /*
* Remove it from the store */
Status = RT->SetVariable (Found->Name, Guid, 0, 0, NULL); if (Status == EFI_NOT_FOUND) { Print (L"Set/Alias: could not find '%hs'\n", Found->Name); Status = EFI_SUCCESS; }
} else if (Value) {
/*
* Add it to the store */
if( Found && ( ( Volatile && ( Found->Flags == NON_VOL ) ) || ( !Volatile && ( Found->Flags == VOL ) ) ) ) { if( Found->Flags == NON_VOL ) { Print (L"Set/Alias: '%hs' already exists as non-volatile variable\n", Found->Name ) ; } else { Print (L"Set/Alias: '%hs' already exists as volatile variable\n", Found->Name ) ; } Found = NULL ; Status = EFI_ACCESS_DENIED ; } else { Status = RT->SetVariable ( Found ? Found->Name : Name, Guid, EFI_VARIABLE_BOOTSERVICE_ACCESS | ( Volatile ? 0 : EFI_VARIABLE_NON_VOLATILE ), StrSize(Value), Value );
if (!EFI_ERROR(Status)) {
/*
* Make a new in memory copy */
Size = sizeof(VARIABLE_ID) + StrSize(Name) + StrSize(Value); Var = AllocateZeroPool (Size);
Var->Signature = VARIABLE_SIGNATURE; Var->u.Value = ((UINT8 *) Var) + sizeof(VARIABLE_ID); Var->Name = (CHAR16*) (Var->u.Value + StrSize(Value)); Var->ValueSize = StrSize(Value); StrCpy (Var->u.Str, Value); StrCpy (Var->Name, Found ? Found->Name : Name); if( Volatile ) { Var->Flags = VOL ; } else { Var->Flags = NON_VOL ; }
InsertTailList (Head, &Var->Link); } }
} else {
if (Found) { Print(L" %hs : %s\n", Var->Name, Var->u.Str); } else { Print(L"'%es' not found\n", Name); }
Found = NULL; }
/*
* Remove the old in memory copy if there was one */
if (Found) { RemoveEntryList (&Found->Link); FreePool (Found); } }
ReleaseLock (&SEnvLock); return Status; }
EFI_STATUS SEnvCmdSet ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) /* Code for internal shell "set" command */ { return SEnvCmdSA (ImageHandle, SystemTable, &SEnvEnv, &SEnvEnvId); }
EFI_STATUS SEnvCmdAlias ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) /* Code for internal shell "set" command */ { return SEnvCmdSA (ImageHandle, SystemTable, &SEnvAlias, &SEnvAliasId); }
|