搜尋此網誌

2012年10月22日 星期一

How to translate a main() function to ShellAppMain()?


  • 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);
}



沒有留言:

張貼留言