- Please generate the four files(test.info, teststrings.uni, test.h, test.c).
- They will teach you how to translate your main() function to ShellAppMain().
/*****************************test.info***********************************/
[defines]
BASE_NAME = test
FILE_GUID = 8DF752F2-87B5-4c7b-AA4F-EDDA99DD3058
COMPONENT_TYPE = APPLICATION
[sources.common]
..\ShCommonStrings.uni
testStrings.uni
test.c
test.h
[includes.common]
.
..\Inc
..\Library
$(EDK_SOURCE)\Foundation
$(EDK_SOURCE)\Foundation\Include
$(EDK_SOURCE)\Foundation\Include\IndustryStandard
$(EDK_SOURCE)\Foundation\Efi
$(EDK_SOURCE)\Foundation\Efi\Include
$(EDK_SOURCE)\Foundation\FrameWork
$(EDK_SOURCE)\Foundation\FrameWork\Include
$(EDK_SOURCE)\Foundation\Core\Dxe
$(DEST_DIR)\
[libraries.common]
EfiShellLib
EdkProtocolLib
EdkFrameworkProtocolLib
EfiProtocolLib
ArchProtocolLib
EdkGuidLib
EdkFrameworkGuidLib
EfiGuidLib
/*****************************teststrings.uni***********************************/
#langdef eng "English"
#langdef fra "Français"
#string STR_TEST_TOO_MANY_ARGS #language eng "%hs: Too many arguments\n"
#string STR_TEST_INVALID_ARG #language eng "%hs: Invalid argument - '%hs'\n"
#string STR_TEST_LINE_HELP #language eng "Test Function"
#string STR_TEST_VERBOSE_HELP #language eng "Test Function() print test string.\n"
"\n"
"\n"
"\n"
" 0.\n"
" 1.\n"
" 2.\n"
" 3.\n"
" 4.\n"
" 5.\n"
" 6.\n"
" 7.\n"
"\n"
/*****************************test.h***********************************/
#ifndef _TEST_H
#define _TEST_H
//
//
//
#define EFI_TEST_GUID \
{ \
0x8df752f2, 0x87b5, 0x4c7b, \
{ \
0xaa, 0x4f, 0xed, 0xda, 0x99, 0xdd, 0x30, 0x58 \
} \
}
#endif
/*****************************test.c***********************************/
#include "EfiShellLib.h"
#include "test.h"
extern UINT8 STRING_ARRAY_NAME[];
#include STRING_DEFINES_FILE
EFI_HII_HANDLE HiiHandle;
EFI_GUID EfiTestGuid = EFI_TEST_GUID;
/*
typedef struct {
CHAR16 *FlagStr;
UINT32 FlagID;
UINT32 ConflictMask; //Conflict Flag ID
SHELL_VAR_CHECK_FLAG_TYPE FlagType;
} SHELL_VAR_CHECK_ITEM;
typedef enum {
FlagTypeSingle = 0,
FlagTypeNeedVar,
FlagTypeNeedSet, //Characters will be replaced by the blank.
FlagTypeSkipUnknown //This set will cause the system hang.
} SHELL_VAR_CHECK_FLAG_TYPE;
typedef struct _SHELL_ARG_LIST {
CHAR16 *FlagStr;
CHAR16 *VarStr;
UINTN Index;
struct _SHELL_ARG_LIST *Next;
} SHELL_ARG_LIST;
#define GetNextArg(a) ((a)->Next)
#define GetFirstArg(a) ((a)->VarList)
#define GetFirstFlag(a) ((a)->FlagList)
typedef struct {
SHELL_ARG_LIST *FlagList;
SHELL_ARG_LIST *VarList;
UINTN FlagCount;
UINTN ValueCount;
} SHELL_VAR_CHECK_PACKAGE;
*/
SHELL_VAR_CHECK_ITEM TestCheckList[] = {
{
L"+a",
0x01,
0x02,
FlagTypeSingle
},
{
L"-a",
0x02,
0x01,
FlagTypeSingle
},
{
L"-b",
0x03,
0,
FlagTypeNeedVar
},
{
L"-c",
0x04,
0,
FlagTypeNeedSet
},
{
L"-z",
0x05,
0,
FlagTypeSkipUnknown
},
{
L"-?",
0x02,
0,
FlagTypeSingle
},
{
NULL,
0,
0,
0
}
};
CHAR8 *
test_unicode_str_to_ascii_str (
IN CHAR16 *Source,
OUT CHAR8 *Destination
)
{
ASSERT (Destination != NULL);
ASSERT (Source != NULL);
while (*Source != '\0') {
*(Destination++) = (CHAR8) *(Source++);
}
*Destination = '\0';
return Destination;
}
INTN
unicode_strlen(
IN const CHAR16 *s
) {
const CHAR16 *sc;
for (sc = s; *sc != 0x00; ++sc)
/* nothing */;
return (INTN)((unsigned long long)sc - (unsigned long long)s);
}
EFI_STATUS
EFIAPI
InitializeTest (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
);
EFI_BOOTSHELL_CODE(
EFI_DRIVER_ENTRY_POINT (InitializeTest)
)
EFI_STATUS
EFIAPI
InitializeTest (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
/*++
Routine Description:
Clear the sreen
Arguments:
ImageHandle - The image handle
SystemTable - The system table
Returns:
EFI_SUCCESS - Success
--*/
{
EFI_STATUS Status;
// UINTN Background;
// UINTN ForeColor;
CHAR16 *Useful;
SHELL_VAR_CHECK_CODE RetCode;
SHELL_VAR_CHECK_PACKAGE ChkPck;
SHELL_ARG_LIST *Item;
ZeroMem (&ChkPck, sizeof (SHELL_VAR_CHECK_PACKAGE));
//
// We are no being installed as an internal command driver, initialize
// as an nshell app and run
//
EFI_SHELL_APP_INIT (ImageHandle, SystemTable);
//
// Enable tab key which can pause the output
//
EnableOutputTabPause();
Status = LibInitializeStrings (&HiiHandle, STRING_ARRAY_NAME, &EfiTestGuid);
if (EFI_ERROR (Status)) {
return Status;
}
RetCode = LibCheckVariables (SI, TestCheckList, &ChkPck, &Useful);
if (VarCheckOk != RetCode) {
switch (RetCode) {
case VarCheckUnknown:
PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_UNKNOWN_FLAG), HiiHandle, L"test", Useful);
break;
case VarCheckDuplicate:
PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_DUP_FLAG), HiiHandle, L"test", Useful);
break;
default:
break;
}
Status = EFI_INVALID_PARAMETER;
goto Done;
}
Print(L"test.c:main called with %d parameters\n", ChkPck.FlagCount);
{
int _Argc = (int)ChkPck.FlagCount, i;
char buffer[1024], *str;
int length, argc;
char *argv[20];
if (_Argc > 20)
_Argc = 20;
Item = GetFirstFlag (&ChkPck);
for (i = 0; i < _Argc; i ++) {
Print(L"[%d]=> FlagStr:%s VarStr:%s\n", Item->Index, Item->FlagStr, Item->VarStr);
Item = GetNextArg (Item);
}
str = buffer;
length = 0;
argc = 0;
Item = GetFirstFlag (&ChkPck);
for (i = 0; i < _Argc; i++) {
if (Item->FlagStr != NULL) {
argv[argc] = str + length;
length += (int)unicode_strlen(Item->FlagStr);
if (length > 1024)
break;
test_unicode_str_to_ascii_str(Item->FlagStr, argv[argc]);
argc ++;
if (Item->VarStr != NULL) {
argv[argc] = str + length;
length += (int)unicode_strlen(Item->VarStr);
if (length > 1024)
break;
test_unicode_str_to_ascii_str(Item->VarStr, argv[argc]);
argc ++;
}
}
Item = GetNextArg (Item);
}
// main( argc, argv ); /*Call your main() function here.*/
}
Status = EFI_SUCCESS;
Done:
LibCheckVarFreeVarList (&ChkPck);
LibUnInitializeStrings ();
return Status;
}
EFI_STATUS
EFIAPI
InitializeTestGetLineHelp (
OUT CHAR16 **Str
) {
return LibCmdGetStringByToken (STRING_ARRAY_NAME, &EfiTestGuid, STRING_TOKEN (STR_TEST_LINE_HELP), Str);
}