no message
authorhfang <hfang@0aefa8ac-fc23-0410-b7a3-bf826d37e4c2>
Mon, 27 Jun 2005 10:21:41 +0000 (10:21 +0000)
committerhfang <hfang@0aefa8ac-fc23-0410-b7a3-bf826d37e4c2>
Mon, 27 Jun 2005 10:21:41 +0000 (10:21 +0000)
git-svn-id: https://efi-shell.tianocore.org/svn/efi-shell/trunk/Shell@4 0aefa8ac-fc23-0410-b7a3-bf826d37e4c2

339 files changed:
DeviceTree/DevicetreeStrings.uni [new file with mode: 0644]
DeviceTree/devicetree.c [new file with mode: 0644]
DeviceTree/devicetree.h [new file with mode: 0644]
DeviceTree/devicetree.inf [new file with mode: 0644]
EfiCompress/Compress.h [new file with mode: 0644]
EfiCompress/CompressMain.c [new file with mode: 0644]
EfiCompress/CompressStrings.uni [new file with mode: 0644]
EfiCompress/compress.c [new file with mode: 0644]
EfiCompress/compress.inf [new file with mode: 0644]
EfiDecompress/Decompress.c [new file with mode: 0644]
EfiDecompress/Decompress.h [new file with mode: 0644]
EfiDecompress/Decompress.inf [new file with mode: 0644]
EfiDecompress/DecompressStrings.uni [new file with mode: 0644]
IpConfig/IpConfig.c [new file with mode: 0644]
IpConfig/IpConfig.h [new file with mode: 0644]
IpConfig/IpConfig.inf [new file with mode: 0644]
IpConfig/IpConfigStrings.uni [new file with mode: 0644]
Library/CRC.c [new file with mode: 0644]
Library/CRC.h [new file with mode: 0644]
Library/ConsistMapping.c [new file with mode: 0644]
Library/ConsistMapping.h [new file with mode: 0644]
Library/DPath.c [new file with mode: 0644]
Library/DPath.h [new file with mode: 0644]
Library/Data.c [new file with mode: 0644]
Library/Ebc/EfiLibPlat.h [new file with mode: 0644]
Library/Ebc/initplat.c [new file with mode: 0644]
Library/Ebc/math.c [new file with mode: 0644]
Library/EfiPart.h [new file with mode: 0644]
Library/EfiShellLib.h [new file with mode: 0644]
Library/EfiShellLib.inf [new file with mode: 0644]
Library/Event.c [new file with mode: 0644]
Library/Event.h [new file with mode: 0644]
Library/FileIO.c [new file with mode: 0644]
Library/FileIO.h [new file with mode: 0644]
Library/Handle.c [new file with mode: 0644]
Library/Handle.h [new file with mode: 0644]
Library/IA32/efilibplat.h [new file with mode: 0644]
Library/IA32/initplat.c [new file with mode: 0644]
Library/IA32/math.c [new file with mode: 0644]
Library/IO.c [new file with mode: 0644]
Library/IO.h [new file with mode: 0644]
Library/IPF/efilibplat.h [new file with mode: 0644]
Library/IPF/initplat.c [new file with mode: 0644]
Library/IPF/libsalpal.h [new file with mode: 0644]
Library/IPF/math.c [new file with mode: 0644]
Library/IPF/palproc.h [new file with mode: 0644]
Library/IPF/palproc.s [new file with mode: 0644]
Library/IPF/salpal.c [new file with mode: 0644]
Library/Init.c [new file with mode: 0644]
Library/LinkedList.h [new file with mode: 0644]
Library/Lock.c [new file with mode: 0644]
Library/Lock.h [new file with mode: 0644]
Library/Mem.c [new file with mode: 0644]
Library/Mem.h [new file with mode: 0644]
Library/Misc.c [new file with mode: 0644]
Library/Misc.h [new file with mode: 0644]
Library/Perf.c [new file with mode: 0644]
Library/RtData.c [new file with mode: 0644]
Library/ShellDebug.c [new file with mode: 0644]
Library/ShellDebug.h [new file with mode: 0644]
Library/ShellEnvInt.c [new file with mode: 0644]
Library/ShellEnvInt.h [new file with mode: 0644]
Library/Str.c [new file with mode: 0644]
Library/Str.h [new file with mode: 0644]
Library/VarCheck.c [new file with mode: 0644]
Library/VarCheck.h [new file with mode: 0644]
LoadPciRom/LoadPciRom.c [new file with mode: 0644]
LoadPciRom/LoadPciRom.h [new file with mode: 0644]
LoadPciRom/LoadPciRom.inf [new file with mode: 0644]
LoadPciRom/LoadPciRomStrings.uni [new file with mode: 0644]
ShCommonStrings.uni [new file with mode: 0644]
Shell.inf [new file with mode: 0644]
SmbiosView/EventLogInfo.c [new file with mode: 0644]
SmbiosView/EventLogInfo.h [new file with mode: 0644]
SmbiosView/LibSmbios.h [new file with mode: 0644]
SmbiosView/LibSmbiosView.c [new file with mode: 0644]
SmbiosView/LibSmbiosView.h [new file with mode: 0644]
SmbiosView/PrintInfo.c [new file with mode: 0644]
SmbiosView/PrintInfo.h [new file with mode: 0644]
SmbiosView/QueryTable.c [new file with mode: 0644]
SmbiosView/QueryTable.h [new file with mode: 0644]
SmbiosView/SmBiosViewStrings.uni [new file with mode: 0644]
SmbiosView/Smbios.c [new file with mode: 0644]
SmbiosView/Smbios.h [new file with mode: 0644]
SmbiosView/Smbiosview.inf [new file with mode: 0644]
SmbiosView/smbiosview.c [new file with mode: 0644]
SmbiosView/smbiosview.h [new file with mode: 0644]
TelnetMgmt/TelnetMgmt.c [new file with mode: 0644]
TelnetMgmt/TelnetMgmt.h [new file with mode: 0644]
TelnetMgmt/TelnetMgmt.inf [new file with mode: 0644]
TelnetMgmt/TelnetMgmtStrings.uni [new file with mode: 0644]
TelnetMgmt/TelnetServer.h [new file with mode: 0644]
attrib/AttribStrings.uni [new file with mode: 0644]
attrib/attrib.c [new file with mode: 0644]
attrib/attrib.h [new file with mode: 0644]
attrib/attrib.inf [new file with mode: 0644]
cls/cls.c [new file with mode: 0644]
cls/cls.h [new file with mode: 0644]
cls/cls.inf [new file with mode: 0644]
cls/clsstrings.uni [new file with mode: 0644]
comp/CompStrings.uni [new file with mode: 0644]
comp/comp.c [new file with mode: 0644]
comp/comp.h [new file with mode: 0644]
comp/comp.inf [new file with mode: 0644]
cp/CpStrings.uni [new file with mode: 0644]
cp/cp.c [new file with mode: 0644]
cp/cp.h [new file with mode: 0644]
cp/cp.inf [new file with mode: 0644]
date/DateStrings.uni [new file with mode: 0644]
date/date.c [new file with mode: 0644]
date/date.h [new file with mode: 0644]
date/date.inf [new file with mode: 0644]
dblk/DblkStrings.uni [new file with mode: 0644]
dblk/dblk.c [new file with mode: 0644]
dblk/dblk.h [new file with mode: 0644]
dblk/dblk.inf [new file with mode: 0644]
dblk/efidump.c [new file with mode: 0644]
devices/DevicesStrings.uni [new file with mode: 0644]
devices/devices.c [new file with mode: 0644]
devices/devices.h [new file with mode: 0644]
devices/devices.inf [new file with mode: 0644]
dmem/DebugStrings.uni [new file with mode: 0644]
dmem/MemCommonPart.c [new file with mode: 0644]
dmem/MemCommonPart.h [new file with mode: 0644]
dmem/MemStrings.uni [new file with mode: 0644]
dmem/debug.h [new file with mode: 0644]
dmem/dmem.inf [new file with mode: 0644]
dmem/efidump.c [new file with mode: 0644]
dmem/mem.c [new file with mode: 0644]
dmpstore/DmpstoreStrings.uni [new file with mode: 0644]
dmpstore/dmpstore.c [new file with mode: 0644]
dmpstore/dmpstore.h [new file with mode: 0644]
dmpstore/dmpstore.inf [new file with mode: 0644]
drivers/DriversStrings.uni [new file with mode: 0644]
drivers/drivers.c [new file with mode: 0644]
drivers/drivers.h [new file with mode: 0644]
drivers/drivers.inf [new file with mode: 0644]
drvcfg/drvcfg.c [new file with mode: 0644]
drvcfg/drvcfg.h [new file with mode: 0644]
drvcfg/drvcfg.inf [new file with mode: 0644]
drvcfg/drvcfgStrings.uni [new file with mode: 0644]
drvdiag/drvdiag.c [new file with mode: 0644]
drvdiag/drvdiag.h [new file with mode: 0644]
drvdiag/drvdiag.inf [new file with mode: 0644]
drvdiag/drvdiagStrings.uni [new file with mode: 0644]
edit/EditStrings.uni [new file with mode: 0644]
edit/edit.inf [new file with mode: 0644]
edit/editor.h [new file with mode: 0644]
edit/editortype.h [new file with mode: 0644]
edit/libEditor.c [new file with mode: 0644]
edit/libFileBuffer.c [new file with mode: 0644]
edit/libInputBar.c [new file with mode: 0644]
edit/libMenuBar.c [new file with mode: 0644]
edit/libMisc.c [new file with mode: 0644]
edit/libMisc.h [new file with mode: 0644]
edit/libStatusBar.c [new file with mode: 0644]
edit/libTitleBar.c [new file with mode: 0644]
edit/libeditor.h [new file with mode: 0644]
edit/libfilebuffer.h [new file with mode: 0644]
edit/libinputbar.h [new file with mode: 0644]
edit/libmenubar.h [new file with mode: 0644]
edit/libstatusbar.h [new file with mode: 0644]
edit/libtitlebar.h [new file with mode: 0644]
edit/main.c [new file with mode: 0644]
err/DebugMask.h [new file with mode: 0644]
err/ErrStrings.uni [new file with mode: 0644]
err/err.c [new file with mode: 0644]
err/err.h [new file with mode: 0644]
err/err.inf [new file with mode: 0644]
guid/GuidStrings.uni [new file with mode: 0644]
guid/guid.c [new file with mode: 0644]
guid/guid.h [new file with mode: 0644]
guid/guid.inf [new file with mode: 0644]
hexedit/HexeditStrings.uni [new file with mode: 0644]
hexedit/heditor.h [new file with mode: 0644]
hexedit/heditortype.h [new file with mode: 0644]
hexedit/hexedit.inf [new file with mode: 0644]
hexedit/libBufferImage.c [new file with mode: 0644]
hexedit/libEditor.c [new file with mode: 0644]
hexedit/libInputBar.c [new file with mode: 0644]
hexedit/libMemImage.c [new file with mode: 0644]
hexedit/libMenuBar.c [new file with mode: 0644]
hexedit/libMisc.c [new file with mode: 0644]
hexedit/libMisc.h [new file with mode: 0644]
hexedit/libStatusBar.c [new file with mode: 0644]
hexedit/libTitleBar.c [new file with mode: 0644]
hexedit/libbufferimage.h [new file with mode: 0644]
hexedit/libclipboard.c [new file with mode: 0644]
hexedit/libclipboard.h [new file with mode: 0644]
hexedit/libdiskimage.c [new file with mode: 0644]
hexedit/libdiskimage.h [new file with mode: 0644]
hexedit/libeditor.h [new file with mode: 0644]
hexedit/libfileimage.c [new file with mode: 0644]
hexedit/libfileimage.h [new file with mode: 0644]
hexedit/libinputbar.h [new file with mode: 0644]
hexedit/libmemimage.h [new file with mode: 0644]
hexedit/libmenubar.h [new file with mode: 0644]
hexedit/libstatusbar.h [new file with mode: 0644]
hexedit/libtitlebar.h [new file with mode: 0644]
hexedit/main.c [new file with mode: 0644]
inc/shellenv.h [new file with mode: 0644]
inc/shelltypes.h [new file with mode: 0644]
load/LoadStrings.uni [new file with mode: 0644]
load/load.c [new file with mode: 0644]
load/load.h [new file with mode: 0644]
load/load.inf [new file with mode: 0644]
ls/LsStrings.uni [new file with mode: 0644]
ls/ls.c [new file with mode: 0644]
ls/ls.h [new file with mode: 0644]
ls/ls.inf [new file with mode: 0644]
mem/DebugStrings.uni [new file with mode: 0644]
mem/MemCommonPart.c [new file with mode: 0644]
mem/MemCommonPart.h [new file with mode: 0644]
mem/MemStrings.uni [new file with mode: 0644]
mem/debug.h [new file with mode: 0644]
mem/efidump.c [new file with mode: 0644]
mem/mem.inf [new file with mode: 0644]
mem/mm.c [new file with mode: 0644]
memmap/MemmapStrings.uni [new file with mode: 0644]
memmap/memmap.c [new file with mode: 0644]
memmap/memmap.h [new file with mode: 0644]
memmap/memmap.inf [new file with mode: 0644]
mkdir/MkdirStrings.uni [new file with mode: 0644]
mkdir/mkdir.c [new file with mode: 0644]
mkdir/mkdir.h [new file with mode: 0644]
mkdir/mkdir.inf [new file with mode: 0644]
mm/mm.c [new file with mode: 0644]
mm/mm.h [new file with mode: 0644]
mm/mm.inf [new file with mode: 0644]
mm/mmStrings.uni [new file with mode: 0644]
mode/ModeStrings.uni [new file with mode: 0644]
mode/mode.c [new file with mode: 0644]
mode/mode.h [new file with mode: 0644]
mode/mode.inf [new file with mode: 0644]
mount/MountStrings.uni [new file with mode: 0644]
mount/mount.c [new file with mode: 0644]
mount/mount.h [new file with mode: 0644]
mount/mount.inf [new file with mode: 0644]
mv/MvStrings.uni [new file with mode: 0644]
mv/mv.c [new file with mode: 0644]
mv/mv.h [new file with mode: 0644]
mv/mv.inf [new file with mode: 0644]
newshell/FakeHii.c [new file with mode: 0644]
newshell/FakeHii.h [new file with mode: 0644]
newshell/NshellStrings.uni [new file with mode: 0644]
newshell/init.c [new file with mode: 0644]
newshell/nshell.h [new file with mode: 0644]
newshell/nshell.inf [new file with mode: 0644]
openinfo/OpeninfoStrings.uni [new file with mode: 0644]
openinfo/openinfo.c [new file with mode: 0644]
openinfo/openinfo.h [new file with mode: 0644]
openinfo/openinfo.inf [new file with mode: 0644]
pci/PciStrings.uni [new file with mode: 0644]
pci/pci.c [new file with mode: 0644]
pci/pci.h [new file with mode: 0644]
pci/pci.inf [new file with mode: 0644]
pci/pci_class.c [new file with mode: 0644]
pci/pci_class.h [new file with mode: 0644]
reset/ResetStrings.uni [new file with mode: 0644]
reset/reset.c [new file with mode: 0644]
reset/reset.h [new file with mode: 0644]
reset/reset.inf [new file with mode: 0644]
rm/RmStrings.uni [new file with mode: 0644]
rm/rm.c [new file with mode: 0644]
rm/rm.h [new file with mode: 0644]
rm/rm.inf [new file with mode: 0644]
sermode/SermodeStrings.uni [new file with mode: 0644]
sermode/sermode.c [new file with mode: 0644]
sermode/sermode.h [new file with mode: 0644]
sermode/sermode.inf [new file with mode: 0644]
shellenv/CdStrings.uni [new file with mode: 0644]
shellenv/Connect.c [new file with mode: 0644]
shellenv/ConnectStrings.uni [new file with mode: 0644]
shellenv/ConsoleProxy.c [new file with mode: 0644]
shellenv/DhStrings.uni [new file with mode: 0644]
shellenv/EchoStrings.uni [new file with mode: 0644]
shellenv/HelpStrings.uni [new file with mode: 0644]
shellenv/MapStrings.uni [new file with mode: 0644]
shellenv/ScriptCmdStrings.uni [new file with mode: 0644]
shellenv/ShellenvHelpStrings.uni [new file with mode: 0644]
shellenv/ShellenvStrings.uni [new file with mode: 0644]
shellenv/batch.c [new file with mode: 0644]
shellenv/cmddisp.c [new file with mode: 0644]
shellenv/conio.c [new file with mode: 0644]
shellenv/data.c [new file with mode: 0644]
shellenv/dprot.c [new file with mode: 0644]
shellenv/echo.c [new file with mode: 0644]
shellenv/exec.c [new file with mode: 0644]
shellenv/for.c [new file with mode: 0644]
shellenv/goto.c [new file with mode: 0644]
shellenv/handle.c [new file with mode: 0644]
shellenv/help.c [new file with mode: 0644]
shellenv/if.c [new file with mode: 0644]
shellenv/init.c [new file with mode: 0644]
shellenv/map.c [new file with mode: 0644]
shellenv/marg.c [new file with mode: 0644]
shellenv/parsecmd.c [new file with mode: 0644]
shellenv/parsecmd.h [new file with mode: 0644]
shellenv/pause.c [new file with mode: 0644]
shellenv/protid.c [new file with mode: 0644]
shellenv/shelle.h [new file with mode: 0644]
shellenv/shellenvguid.h [new file with mode: 0644]
shellenv/shift.c [new file with mode: 0644]
shellenv/var.c [new file with mode: 0644]
shellenv/wait.c [new file with mode: 0644]
stall/StallStrings.uni [new file with mode: 0644]
stall/stall.c [new file with mode: 0644]
stall/stall.h [new file with mode: 0644]
stall/stall.inf [new file with mode: 0644]
time/TimeStrings.uni [new file with mode: 0644]
time/time.c [new file with mode: 0644]
time/time.h [new file with mode: 0644]
time/time.inf [new file with mode: 0644]
touch/TouchStrings.uni [new file with mode: 0644]
touch/touch.c [new file with mode: 0644]
touch/touch.h [new file with mode: 0644]
touch/touch.inf [new file with mode: 0644]
type/TypeStrings.uni [new file with mode: 0644]
type/type.c [new file with mode: 0644]
type/type.h [new file with mode: 0644]
type/type.inf [new file with mode: 0644]
tzone/TZoneStrings.uni [new file with mode: 0644]
tzone/timezone.inf [new file with mode: 0644]
tzone/tzone.c [new file with mode: 0644]
tzone/tzone.h [new file with mode: 0644]
unload/UnloadStrings.uni [new file with mode: 0644]
unload/unload.c [new file with mode: 0644]
unload/unload.h [new file with mode: 0644]
unload/unload.inf [new file with mode: 0644]
ver/Ipf/ver64.c [new file with mode: 0644]
ver/Ver.inf [new file with mode: 0644]
ver/VerStrings.uni [new file with mode: 0644]
ver/ia32/ver32.c [new file with mode: 0644]
ver/ver.c [new file with mode: 0644]
ver/ver.h [new file with mode: 0644]
vol/Vol.inf [new file with mode: 0644]
vol/VolStrings.uni [new file with mode: 0644]
vol/vol.c [new file with mode: 0644]
vol/vol.h [new file with mode: 0644]

diff --git a/DeviceTree/DevicetreeStrings.uni b/DeviceTree/DevicetreeStrings.uni
new file mode 100644 (file)
index 0000000..cb7f21d
Binary files /dev/null and b/DeviceTree/DevicetreeStrings.uni differ
diff --git a/DeviceTree/devicetree.c b/DeviceTree/devicetree.c
new file mode 100644 (file)
index 0000000..0df8422
--- /dev/null
@@ -0,0 +1,671 @@
+/*++
+Copyright 2005, Intel Corporation                                                         
+All rights reserved. This program and the accompanying materials                          
+are licensed and made available under the terms and conditions of the BSD License         
+which accompanies this distribution. The full text of the license may be found at         
+http://opensource.org/licenses/bsd-license.php                                            
+                                                                                          
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+
+Module Name:
+
+  devicetree.c
+  
+Abstract:
+
+  Shell command "devicetree"
+
+
+
+Revision History
+
+--*/
+
+#include "EfiShellLib.h"
+#include "devicetree.h"
+
+extern UINT8  STRING_ARRAY_NAME[];
+
+//
+// This is the generated header file which includes whatever needs to be exported (strings + IFR)
+//
+#include STRING_DEFINES_FILE
+
+//
+// Global Variables
+//
+EFI_HII_HANDLE  HiiHandle;
+EFI_GUID        EfiDevicetreeGuid = EFI_DEVICETREE_GUID;
+SHELL_VAR_CHECK_ITEM    DevicetreeCheckList[] = {
+  {
+    L"-d",
+    0x01,
+    0,
+    FlagTypeSingle
+  },
+  {
+    L"-l",
+    0x02,
+    0,
+    FlagTypeNeedVar
+  },
+  {
+    L"-b",
+    0x04,
+    0,
+    FlagTypeSingle
+  },
+  {
+    L"-?",
+    0x08,
+    0,
+    FlagTypeSingle
+  },
+  {
+    NULL,
+    0,
+    0,
+    0
+  }
+};
+
+EFI_STATUS
+ShellDeviceTree (
+  IN EFI_HANDLE       ControllerHandle,
+  IN UINTN            Level,
+  IN BOOLEAN          RootOnly,
+  IN BOOLEAN          BestName,
+  IN CHAR8            *Language
+  );
+
+EFI_STATUS
+DevicetreeMain (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  );
+
+EFI_STATUS
+DevicetreeMainOld (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  );
+
+EFI_BOOTSHELL_CODE(
+  EFI_APPLICATION_ENTRY_POINT(DevicetreeMain)
+)
+//
+//
+//
+EFI_STATUS
+DevicetreeMain (
+  IN EFI_HANDLE               ImageHandle,
+  IN EFI_SYSTEM_TABLE         *SystemTable
+  )
+/*++
+
+Routine Description:
+
+  Code for external shell "devicetree" command.
+
+Arguments:
+
+  ImageHandle - The image handle
+  SystemTable - The system table
+
+Returns:
+
+--*/
+{
+  CHAR16                  *Arg;
+  CHAR8                   *Language;
+  BOOLEAN                 BestName;
+  EFI_STATUS              Status;
+  UINTN                   Index;
+  UINTN                   StringIndex;
+  UINTN                   HandleNumber;
+  EFI_HANDLE              Handle;
+  SHELL_VAR_CHECK_CODE    RetCode;
+  CHAR16                  *Useful;
+  SHELL_ARG_LIST          *Item;
+  SHELL_VAR_CHECK_PACKAGE ChkPck;
+
+  BestName = TRUE;
+  Arg = NULL;
+  Language = NULL;
+  Handle = NULL;
+  ZeroMem (&ChkPck, sizeof (SHELL_VAR_CHECK_PACKAGE));
+  EFI_SHELL_APP_INIT (ImageHandle, SystemTable);
+
+  Status = LibInitializeStrings (&HiiHandle, STRING_ARRAY_NAME, &EfiDevicetreeGuid);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  if (!EFI_PROPER_VERSION (1, 10)) {
+    PrintToken (
+      STRING_TOKEN (STR_SHELLENV_GNC_COMMAND_NOT_SUPPORT),
+      HiiHandle,
+      L"devicetree",
+      EFI_VERSION_1_10
+      );
+    Status = EFI_UNSUPPORTED;
+    goto Done;
+  }
+
+  LibFilterNullArgs ();
+  if (IS_OLD_SHELL) {
+    Status = DevicetreeMainOld (ImageHandle, SystemTable);
+    goto Done;
+  }
+  //
+  // Crack args
+  //
+  RetCode = LibCheckVariables (SI, DevicetreeCheckList, &ChkPck, &Useful);
+  if (VarCheckOk != RetCode) {
+    switch (RetCode) {
+    case VarCheckDuplicate:
+      PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_DUP_FLAG), HiiHandle, L"devtree", Useful);
+      break;
+
+    case VarCheckUnknown:
+      PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_UNKNOWN_FLAG), HiiHandle, L"devtree", Useful);
+      break;
+
+    case VarCheckLackValue:
+      PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_LACK_ARG), HiiHandle, L"devtree", Useful);
+      break;
+
+    default:
+      break;
+    }
+
+    Status = EFI_INVALID_PARAMETER;
+    goto Done;
+  }
+  //
+  // Out put help.
+  //
+  if (LibCheckVarGetFlag (&ChkPck, L"-b") != NULL) {
+    EnablePageBreak (DEFAULT_INIT_ROW, DEFAULT_AUTO_LF);
+  }
+
+  if (LibCheckVarGetFlag (&ChkPck, L"-?") != NULL) {
+    if (ChkPck.ValueCount > 0 ||
+        ChkPck.FlagCount > 2 ||
+        (2 == ChkPck.FlagCount && !LibCheckVarGetFlag (&ChkPck, L"-b"))
+        ) {
+      PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_TOO_MANY), HiiHandle, L"devtree");
+      Status = EFI_INVALID_PARAMETER;
+    } else {
+      PrintToken (STRING_TOKEN (STR_DEVTREE_VERBOSEHELP), HiiHandle);
+      Status = EFI_SUCCESS;
+    }
+
+    goto Done;
+  }
+
+  if (ChkPck.ValueCount > 1) {
+    PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_TOO_MANY), HiiHandle, L"devtree");
+    Status = EFI_INVALID_PARAMETER;
+    goto Done;
+  }
+
+  Language = LibGetVariable (VarLanguage, &gEfiGlobalVariableGuid);
+  if (Language == NULL) {
+    Language    = AllocatePool (4);
+    Language[0] = 'e';
+    Language[1] = 'n';
+    Language[2] = 'g';
+    Language[3] = 0;
+  }
+
+  Item = LibCheckVarGetFlag (&ChkPck, L"-l");
+  if (Item) {
+    if (StrLen (Item->VarStr) != 3) {
+      PrintToken (STRING_TOKEN (STR_SHELLENV_PROTID_DEVTREE_BAD_LANG), HiiHandle, L"devtree", Item->VarStr);
+      Status = EFI_INVALID_PARAMETER;
+      goto Done;
+    }
+
+    for (StringIndex = 0; StringIndex < 3; StringIndex++) {
+      Language[StringIndex] = (CHAR8) Item->VarStr[StringIndex];
+    }
+
+    Language[StringIndex] = 0;
+  }
+
+  if (LibCheckVarGetFlag (&ChkPck, L"-d") != NULL) {
+    BestName = FALSE;
+  }
+  //
+  // Load handle & protocol info tables
+  //
+  ShellInitProtocolInfoEnumerator ();
+  ShellInitHandleEnumerator ();
+  if (ChkPck.ValueCount == 1) {
+    Arg           = ChkPck.VarList->VarStr;
+    HandleNumber  = (UINTN) (StrToUIntegerBase (Arg, 16, &Status));
+    if (EFI_ERROR (Status)) {
+      PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_INVALID_ARG), HiiHandle, L"devtree", ChkPck.VarList->VarStr);
+      Status = EFI_INVALID_PARAMETER;
+      goto Done;
+    }
+
+    if ((Handle = ShellHandleFromIndex (HandleNumber - 1)) == NULL) {
+      PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_INVALID_HANDLE_NUM), HiiHandle, L"devtree", ChkPck.VarList->VarStr);
+      Status = EFI_INVALID_PARAMETER;
+      goto Done;
+    }
+  }
+
+  if (Arg) {
+    //
+    // Dump 1 handle
+    //
+    PrintToken (STRING_TOKEN (STR_SHELLENV_PROTID_DEVICE_TREE), HiiHandle);
+    ShellDeviceTree (
+      Handle,
+      1,
+      FALSE,
+      BestName,
+      Language
+      );
+  } else {
+    //
+    // Dump all handles
+    //
+    PrintToken (STRING_TOKEN (STR_SHELLENV_PROTID_DEVICE_TREE), HiiHandle);
+    for (Index = 0; Index < ShellGetHandleNum (); Index++) {
+      BREAK_LOOP_ON_ESC ();
+      ShellDeviceTree (
+        ShellHandleFromIndex (Index),
+        1,
+        TRUE,
+        BestName,
+        Language
+        );
+    }
+  }
+
+  Status = EFI_SUCCESS;
+
+Done:
+  if (Language != NULL) {
+    FreePool (Language);
+  }
+
+  ShellCloseHandleEnumerator ();
+  ShellCloseProtocolInfoEnumerator ();
+  LibCheckVarFreeVarList (&ChkPck);
+  LibUnInitializeStrings ();
+  return Status;
+}
+
+EFI_STATUS
+ShellDeviceTree (
+  IN EFI_HANDLE       ControllerHandle,
+  IN UINTN            Level,
+  IN BOOLEAN          RootOnly,
+  IN BOOLEAN          BestName,
+  IN CHAR8            *Language
+  )
+/*++
+
+Routine Description:
+
+Arguments:
+
+  ControllerHandle - The Controller handle
+  Level            - The device level
+  RootOnly         - Is root only
+  BestName         - The best name
+  Language         - The name language
+
+Returns:
+
+  EFI_SUCCESS - Success
+
+--*/
+{
+  EFI_STATUS                  Status;
+  EFI_LOADED_IMAGE_PROTOCOL   *Image;
+  EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
+  UINT32                      ControllerHandleIndex;
+  UINTN                       HandleCount;
+  EFI_HANDLE                  *HandleBuffer;
+  UINT32                      *HandleType;
+  UINTN                       HandleIndex;
+  UINTN                       ChildIndex;
+  EFI_DEVICE_PATH_PROTOCOL    *DevicePath;
+  UINTN                       ChildHandleCount;
+  EFI_HANDLE                  *ChildHandleBuffer;
+  UINT32                      *ChildHandleType;
+  UINTN                       Index;
+  BOOLEAN                     Root;
+  EFI_STATUS                  ConfigurationStatus;
+  EFI_STATUS                  DiagnosticsStatus;
+  CHAR16                      *DeviceName;
+
+  Status = BS->OpenProtocol (
+                ControllerHandle,
+                &gEfiDriverBindingProtocolGuid,
+                (VOID **) &DriverBinding,
+                NULL,
+                NULL,
+                EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                );
+  if (!EFI_ERROR (Status)) {
+    return EFI_SUCCESS;
+  }
+
+  Status = BS->OpenProtocol (
+                ControllerHandle,
+                &gEfiLoadedImageProtocolGuid,
+                (VOID **) &Image,
+                NULL,
+                NULL,
+                EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                );
+  if (!EFI_ERROR (Status)) {
+    return EFI_SUCCESS;
+  }
+
+  Status = LibScanHandleDatabase (
+            NULL,
+            NULL,
+            ControllerHandle,
+            &ControllerHandleIndex,
+            &HandleCount,
+            &HandleBuffer,
+            &HandleType
+            );
+  if (EFI_ERROR (Status)) {
+    return EFI_SUCCESS;
+  }
+
+  if (RootOnly) {
+    Root = TRUE;
+    for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
+      BREAK_LOOP_ON_ESC ();
+
+      if (HandleType[HandleIndex] & EFI_HANDLE_TYPE_PARENT_HANDLE) {
+        Root = FALSE;
+      }
+    }
+
+    Status = BS->OpenProtocol (
+                  ControllerHandle,
+                  &gEfiDevicePathProtocolGuid,
+                  (VOID **) &DevicePath,
+                  NULL,
+                  NULL,
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                  );
+    if (EFI_ERROR (Status)) {
+      Root = FALSE;
+    }
+
+    if (!Root) {
+      return EFI_SUCCESS;
+    }
+  }
+  //
+  // Display the handle specified by ControllerHandle
+  //
+  for (Index = 0; Index < Level; Index++) {
+    Print (L"  ");
+  }
+
+  PrintToken (
+    STRING_TOKEN (STR_SHELLENV_PROTID_CTRL),
+    HiiHandle,
+    ShellHandleToIndex (ControllerHandle)
+    );
+
+  Status = ShellGetDeviceName (
+            ControllerHandle,
+            BestName,
+            TRUE,
+            Language,
+            &DeviceName,
+            &ConfigurationStatus,
+            &DiagnosticsStatus,
+            FALSE,
+            0
+            );
+  if (DeviceName != NULL) {
+    PrintToken (STRING_TOKEN (STR_SHELLENV_PROTID_ONE_VAR_S), HiiHandle, DeviceName);
+  } else {
+    PrintToken (STRING_TOKEN (STR_SHELLENV_PROTID_UNKNOWN_2), HiiHandle);
+  }
+  //
+  // Print the list of drivers that are managing this controller
+  //
+  for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
+    BREAK_LOOP_ON_ESC ();
+    if (HandleType[HandleIndex] & EFI_HANDLE_TYPE_DRIVER_BINDING_HANDLE &&
+        HandleType[HandleIndex] & EFI_HANDLE_TYPE_DEVICE_DRIVER
+        ) {
+
+      DriverBinding = NULL;
+      Status = BS->OpenProtocol (
+                    HandleBuffer[HandleIndex],
+                    &gEfiDriverBindingProtocolGuid,
+                    (VOID **) &DriverBinding,
+                    NULL,
+                    NULL,
+                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                    );
+
+      Status = LibScanHandleDatabase (
+                HandleBuffer[HandleIndex],
+                NULL,
+                ControllerHandle,
+                &ControllerHandleIndex,
+                &ChildHandleCount,
+                &ChildHandleBuffer,
+                &ChildHandleType
+                );
+
+      if (!EFI_ERROR (Status)) {
+        for (ChildIndex = 0; ChildIndex < ChildHandleCount; ChildIndex++) {
+          BREAK_LOOP_ON_ESC ();
+          if (ChildHandleType[ChildIndex] & EFI_HANDLE_TYPE_CHILD_HANDLE &&
+              ChildHandleType[ChildIndex] & EFI_HANDLE_TYPE_DEVICE_HANDLE
+              ) {
+
+            Status = ShellDeviceTree (
+                      ChildHandleBuffer[ChildIndex],
+                      Level + 1,
+                      FALSE,
+                      BestName,
+                      Language
+                      );
+            if (EFI_ERROR (Status)) {
+              return Status;
+            }
+          }
+        }
+
+        FreePool (ChildHandleBuffer);
+        FreePool (ChildHandleType);
+      }
+    }
+  }
+
+  FreePool (HandleBuffer);
+  FreePool (HandleType);
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+DevicetreeMainGetLineHelp (
+  OUT CHAR16                **Str
+  )
+/*++
+
+Routine Description:
+
+  Get this command's line help
+
+Arguments:
+
+  Str - The line help
+
+Returns:
+
+  EFI_SUCCESS   - Success
+
+--*/
+{
+  return LibCmdGetStringByToken (STRING_ARRAY_NAME, &EfiDevicetreeGuid, STRING_TOKEN (STR_DEVTREE_LINEHELP), Str);
+}
+
+EFI_STATUS
+DevicetreeMainOld (
+  IN EFI_HANDLE               ImageHandle,
+  IN EFI_SYSTEM_TABLE         *SystemTable
+  )
+/*++
+
+Routine Description:
+
+  Code for external shell "devicetree" command.
+
+Arguments:
+
+  ImageHandle - The image handle
+  SystemTable - The system table
+Returns:
+
+--*/
+{
+  CHAR16      *Arg;
+  CHAR16      *Ptr;
+  CHAR8       *Language;
+  BOOLEAN     BestName;
+  EFI_STATUS  Status;
+  UINTN       Index;
+  UINTN       StringIndex;
+  BOOLEAN     PrtHelp;
+
+  Status    = EFI_SUCCESS;
+  PrtHelp   = FALSE;
+  Language  = LibGetVariable (VarLanguage, &gEfiGlobalVariableGuid);
+  if (Language == NULL) {
+    Language    = AllocatePool (4);
+    Language[0] = 'e';
+    Language[1] = 'n';
+    Language[2] = 'g';
+    Language[3] = 0;
+  }
+
+  Arg = NULL;
+  //
+  // Crack args
+  //
+  BestName = TRUE;
+  for (Index = 1; Index < SI->Argc; Index += 1) {
+    Ptr = SI->Argv[Index];
+    if (*Ptr == '-') {
+      switch (Ptr[1]) {
+      case 'l':
+      case 'L':
+        if (*(Ptr + 2) != 0) {
+          for (StringIndex = 0; StringIndex < 3 && Ptr[StringIndex + 2] != 0; StringIndex++) {
+            Language[StringIndex] = (CHAR8) Ptr[StringIndex + 2];
+          }
+
+          Language[StringIndex] = 0;
+        }
+        break;
+
+      case 'd':
+      case 'D':
+        BestName = FALSE;
+        break;
+
+      case 'b':
+      case 'B':
+        EnablePageBreak (DEFAULT_INIT_ROW, DEFAULT_AUTO_LF);
+        break;
+
+      case '?':
+        PrtHelp = TRUE;
+        break;
+
+      default:
+        PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_UNKNOWN_FLAG), HiiHandle, L"devtree", Ptr);
+        Status = EFI_INVALID_PARAMETER;
+        goto Done;
+      }
+
+      continue;
+    }
+
+    if (!Arg) {
+      Arg = Ptr;
+      continue;
+    }
+
+    PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_TOO_MANY), HiiHandle, L"devtree");
+    Status = EFI_INVALID_PARAMETER;
+    goto Done;
+  }
+
+  if (PrtHelp) {
+    PrintToken (STRING_TOKEN (STR_DEVTREE_VERBOSEHELP), HiiHandle);
+    Status = EFI_SUCCESS;
+    goto Done;
+  }
+  //
+  // Load handle & protocol info tables
+  //
+  ShellInitProtocolInfoEnumerator ();
+
+  if (Arg) {
+    //
+    // Dump 1 handle
+    //
+    Index = ShellHandleNoFromStr (Arg) - 1;
+    if (Index < 0) {
+      PrintToken (STRING_TOKEN (STR_SHELLENV_PROTID_DEVTREE_INVALID_HANDLE), HiiHandle, Arg);
+    } else {
+      PrintToken (STRING_TOKEN (STR_SHELLENV_PROTID_DEVICE_TREE), HiiHandle);
+      ShellDeviceTree (
+        ShellHandleFromIndex (Index),
+        1,
+        FALSE,
+        BestName,
+        Language
+        );
+    }
+  } else {
+    //
+    // Dump all handles
+    //
+    PrintToken (STRING_TOKEN (STR_SHELLENV_PROTID_DEVICE_TREE), HiiHandle);
+    for (Index = 0; Index < ShellGetHandleNum (); Index++) {
+      if (GetExecutionBreak ()) {
+        Status = EFI_ABORTED;
+        goto Done;
+      }
+
+      ShellDeviceTree (
+        ShellHandleFromIndex (Index),
+        1,
+        TRUE,
+        BestName,
+        Language
+        );
+    }
+  }
+
+  Status = EFI_SUCCESS;
+
+Done:
+  return Status;
+}
diff --git a/DeviceTree/devicetree.h b/DeviceTree/devicetree.h
new file mode 100644 (file)
index 0000000..296ab5c
--- /dev/null
@@ -0,0 +1,34 @@
+/*++
+
+Copyright 2005, Intel Corporation                                                         
+All rights reserved. This program and the accompanying materials                          
+are licensed and made available under the terms and conditions of the BSD License         
+which accompanies this distribution. The full text of the license may be found at         
+http://opensource.org/licenses/bsd-license.php                                            
+                                                                                          
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+
+Module Name:
+
+  devicetree.h
+
+Abstract:
+
+  declares interface functions
+
+Revision History
+
+--*/
+
+//
+//
+//
+#ifndef _DEVICETREE_H_
+#define _DEVICETREE_H_
+
+#define EFI_DEVICETREE_GUID \
+  { \
+    0xf21044af, 0xeef6, 0x4d58, 0xb4, 0x56, 0x32, 0x86, 0xa0, 0x2b, 0x7c, 0x49 \
+  }
+#endif
diff --git a/DeviceTree/devicetree.inf b/DeviceTree/devicetree.inf
new file mode 100644 (file)
index 0000000..e564169
--- /dev/null
@@ -0,0 +1,79 @@
+#/*++
+#
+#  Copyright 2005, Intel Corporation                                                         
+#  All rights reserved. This program and the accompanying materials                          
+#  are licensed and made available under the terms and conditions of the BSD License         
+#  which accompanies this distribution. The full text of the license may be found at         
+#  http://opensource.org/licenses/bsd-license.php                                            
+#                                                                                            
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+#  
+#  Module Name:
+#
+#    devicetree.inf
+#
+#  Abstract:
+#
+#    Component description file for building an application for the shell
+#    command mount.
+#
+#  Notes:
+#    BASE_NAME   - names the output file (mount.efi here)
+#    FILE_GUID   - required by the build tool, but not used anywhere for this
+#    BUILD_TYPE  - tells the build process to use the 
+#                  [build.$(PROCESSOR).$(BUILD_TYPE)] section of the DSC file
+#                  to build it. Make sure the DSC file has this section.
+#    FV          - define as NULL to indicate to the build tools that the
+#                  final build target does not go into any firmware volume.
+#
+#  Use of this file requires building in and linking the Shell library.
+#  You must also add it to the DSC file somewhere after the shell has been 
+#  built.
+#
+--*/
+
+[defines]
+BASE_NAME            = Devtree
+FILE_GUID            = 040B320B-7821-47e0-9C75-EB692A6DC8BF
+COMPONENT_TYPE       = APPLICATION
+
+
+[sources.common]
+  ..\ShCommonStrings.uni
+  DevicetreeStrings.uni
+  devicetree.c
+  devicetree.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
+
+
+[nmake.common]
+  C_STD_INCLUDE=
+  IMAGE_ENTRY_POINT=DevicetreeMain
+  C_STD_FLAGS = $(C_STD_FLAGS) /DSTRING_ARRAY_NAME=$(BASE_NAME)Strings 
+  C_STD_FLAGS = $(C_STD_FLAGS) /DSTRING_DEFINES_FILE=\"$(BASE_NAME)StrDefs.h\"
+  C_STD_FLAGS = $(C_STD_FLAGS) /DEFI_BOOTSHELL
+
diff --git a/EfiCompress/Compress.h b/EfiCompress/Compress.h
new file mode 100644 (file)
index 0000000..313c772
--- /dev/null
@@ -0,0 +1,60 @@
+/*++
+
+Copyright 2005, Intel Corporation                                                         
+All rights reserved. This program and the accompanying materials                          
+are licensed and made available under the terms and conditions of the BSD License         
+which accompanies this distribution. The full text of the license may be found at         
+http://opensource.org/licenses/bsd-license.php                                            
+                                                                                          
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+
+Module Name:
+
+  Compress.h
+
+Abstract:
+
+  Header file for compression routine
+  
+--*/
+
+#ifndef _EFI_SHELL_COMPRESS_H_
+#define _EFI_SHELL_COMPRESS_H_
+
+#define EFI_COMPRESS_GUID \
+  { \
+    0xfe977fed, 0x19f2, 0x4438, 0xaa, 0x5e, 0x51, 0x9a, 0x68, 0xbc, 0x67, 0x94 \
+  }
+
+EFI_STATUS
+Compress (
+  IN      UINT8   *SrcBuffer,
+  IN      UINT32  SrcSize,
+  IN      UINT8   *DstBuffer,
+  IN OUT  UINT32  *DstSize
+  );
+
+/*++
+
+Routine Description:
+
+  The compression routine.
+
+Arguments:
+
+  SrcBuffer   - The buffer storing the source data
+  SrcSize     - The size of source data
+  DstBuffer   - The buffer to store the compressed data
+  DstSize     - On input, the size of DstBuffer; On output,
+                the size of the actual compressed data.
+
+Returns:
+
+  EFI_BUFFER_TOO_SMALL  - The DstBuffer is too small. In this case,
+                DstSize contains the size needed.
+  EFI_SUCCESS           - Compression is successful.
+
+--*/
+
+#endif
\ No newline at end of file
diff --git a/EfiCompress/CompressMain.c b/EfiCompress/CompressMain.c
new file mode 100644 (file)
index 0000000..a7cd3e7
--- /dev/null
@@ -0,0 +1,462 @@
+/*++
+
+Copyright 2005, Intel Corporation                                                         
+All rights reserved. This program and the accompanying materials                          
+are licensed and made available under the terms and conditions of the BSD License         
+which accompanies this distribution. The full text of the license may be found at         
+http://opensource.org/licenses/bsd-license.php                                            
+                                                                                          
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+
+Module Name:
+
+  compressMain.c
+  
+Abstract:
+
+  EFI shell command "EfiCompress" - compress a file
+
+Revision History
+
+--*/
+
+#include "EfiShellLib.h"
+#include "Compress.h"
+
+extern UINT8    STRING_ARRAY_NAME[];
+
+//
+// This is the generated header file which includes whatever needs to be exported (strings + IFR)
+//
+#include STRING_DEFINES_FILE
+
+EFI_HII_HANDLE  HiiCompressHandle;
+EFI_GUID        EfiCompressGuid = EFI_COMPRESS_GUID;
+SHELL_VAR_CHECK_ITEM    CompressCheckList[] = {
+  {
+    L"-b",
+    0x1,
+    0,
+    FlagTypeSingle
+  },
+  {
+    L"-?",
+    0x2,
+    0,
+    FlagTypeSingle
+  },
+  {
+    NULL,
+    0,
+    0,
+    0
+  }
+};
+
+//
+// Function declarations
+//
+EFI_STATUS
+InitializeCompress (
+  IN EFI_HANDLE           ImageHandle,
+  IN EFI_SYSTEM_TABLE     *SystemTable
+  );
+
+//
+// Entry Point
+//
+EFI_BOOTSHELL_CODE(
+  EFI_APPLICATION_ENTRY_POINT(InitializeCompress)
+)
+
+EFI_STATUS
+InitializeCompress (
+  IN EFI_HANDLE           ImageHandle,
+  IN EFI_SYSTEM_TABLE     *SystemTable
+  )
+/*++
+
+Routine Description:
+  Command entry point. Compress the contents of a file.
+
+Arguments:
+  ImageHandle     The image handle. 
+  SystemTable     The system table.
+
+Returns:
+  EFI_SUCCESS             - The command completed successfully
+  EFI_INVALID_PARAMETER   - Command usage error
+  Other value             - Unknown error
+  
+--*/
+{
+  EFI_LIST_ENTRY          File1List;
+  EFI_LIST_ENTRY          File2List;
+  SHELL_FILE_ARG          *File1Arg;
+  SHELL_FILE_ARG          *File2Arg;
+  EFI_FILE_HANDLE         File2Handle;
+  UINTN                   SourceSize;
+  UINTN                   DestinationSize;
+  UINT8                   *File1Buffer;
+  UINT8                   *File2Buffer;
+  EFI_STATUS              Status;
+  INT32                   Ratio;
+  SHELL_VAR_CHECK_CODE    RetCode;
+  CHAR16                  *Useful;
+  SHELL_ARG_LIST          *Item;
+  SHELL_VAR_CHECK_PACKAGE ChkPck;
+  BOOLEAN                 DstFileExist;
+
+  //
+  // Local variable initializations
+  //
+  File1Buffer             = NULL;
+  File2Buffer             = NULL;
+  DstFileExist            = FALSE;
+  InitializeListHead (&File1List);
+  InitializeListHead (&File2List);
+  ZeroMem (&ChkPck, sizeof (SHELL_VAR_CHECK_PACKAGE));
+  //
+  // We are not being installed as an internal command driver, initialize
+  // as an nshell app and run
+  //
+  EFI_SHELL_APP_INIT (ImageHandle, SystemTable);
+
+  //
+  // Register our string package with HII and return the handle to it.
+  // If previously registered we will simply receive the handle
+  //
+  EFI_SHELL_STR_INIT (HiiCompressHandle, STRING_ARRAY_NAME, EfiCompressGuid);
+
+  if (!EFI_PROPER_VERSION (0, 99)) {
+    PrintToken (
+      STRING_TOKEN (STR_SHELLENV_GNC_COMMAND_NOT_SUPPORT),
+      HiiCompressHandle,
+      L"eficompress",
+      EFI_VERSION_0_99 
+      );
+    Status = EFI_UNSUPPORTED;
+    goto Done;
+  }
+
+  LibFilterNullArgs ();
+  //
+  // Parse command line arguments
+  //
+  RetCode = LibCheckVariables (SI, CompressCheckList, &ChkPck, &Useful);
+  if (VarCheckOk != RetCode) {
+    switch (RetCode) {
+    case VarCheckUnknown:
+      PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_UNKNOWN_FLAG), HiiCompressHandle, L"eficompress", Useful);
+      break;
+
+    default:
+      break;
+    }
+
+    Status = EFI_INVALID_PARAMETER;
+    goto Done;
+  }
+
+  if (LibCheckVarGetFlag (&ChkPck, L"-b")) {
+    EnablePageBreak (DEFAULT_INIT_ROW, DEFAULT_AUTO_LF);
+  }
+
+  if (LibCheckVarGetFlag (&ChkPck, L"-?")) {
+    if (ChkPck.ValueCount > 0 ||
+        ChkPck.FlagCount > 2 ||
+        (2 == ChkPck.FlagCount && !LibCheckVarGetFlag (&ChkPck, L"-b"))
+        ) {
+      PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_TOO_MANY), HiiCompressHandle, L"eficompress");
+      Status = EFI_INVALID_PARAMETER;
+    } else {
+      PrintToken (STRING_TOKEN (STR_EFICOMPRESS_VERBOSEHELP), HiiCompressHandle);
+      Status = EFI_SUCCESS;
+    }
+
+    goto Done;
+  }
+  //
+  // verify number of arguments
+  //
+  if (ChkPck.ValueCount > 2) {
+    PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_TOO_MANY), HiiCompressHandle, L"eficompress");
+    Status = EFI_INVALID_PARAMETER;
+    goto Done;
+  }
+
+  if (ChkPck.ValueCount < 2) {
+    PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_TOO_FEW), HiiCompressHandle, L"eficompress");
+    Status = EFI_INVALID_PARAMETER;
+    goto Done;
+  }
+  //
+  // validate first file
+  //
+  Item    = ChkPck.VarList;
+  Status  = ShellFileMetaArg (Item->VarStr, &File1List);
+  if (EFI_ERROR (Status)) {
+    PrintToken (STRING_TOKEN (STR_COMPRESS_CANNOT_OPEN), HiiCompressHandle, L"eficompress", Item->VarStr, Status);
+    goto Done;
+  }
+  //
+  // empty list
+  //
+  if (IsListEmpty (&File1List)) {
+    Status = EFI_NOT_FOUND;
+    PrintToken (STRING_TOKEN (STR_COMPRESS_CANNOT_OPEN), HiiCompressHandle, L"eficompress", Item->VarStr, Status);
+    goto Done;
+  }
+  //
+  // multiple files
+  //
+  if (File1List.Flink->Flink != &File1List) {
+    PrintToken (STRING_TOKEN (STR_COMPRESS_FIRST_MULT_FILES), HiiCompressHandle, L"eficompress");
+    Status = EFI_INVALID_PARAMETER;
+    goto Done;
+  }
+
+  File1Arg = CR (File1List.Flink, SHELL_FILE_ARG, Link, SHELL_FILE_ARG_SIGNATURE);
+
+  //
+  // Open error
+  //
+  if (EFI_ERROR (File1Arg->Status) || !File1Arg->Handle) {
+    PrintToken (
+      STRING_TOKEN (STR_COMPRESS_CANNOT_OPEN),
+      HiiCompressHandle,
+      L"eficompress",
+      File1Arg->FullName,
+      File1Arg->Status
+      );
+    Status = File1Arg->Status;
+    goto Done;
+  }
+  //
+  // directory
+  //
+  if (File1Arg->Info && (File1Arg->Info->Attribute & EFI_FILE_DIRECTORY)) {
+    PrintToken (STRING_TOKEN (STR_COMPRESS_FIRST_DIR), HiiCompressHandle, L"eficompress");
+    Status = EFI_INVALID_PARAMETER;
+    goto Done;
+  }
+  //
+  // Validate second file
+  //
+  Item    = Item->Next;
+  Status  = ShellFileMetaArg (Item->VarStr, &File2List);
+  if (EFI_ERROR (Status)) {
+    PrintToken (STRING_TOKEN (STR_COMPRESS_CANNOT_OPEN), HiiCompressHandle, L"eficompress", Item->VarStr, Status);
+    goto Done;
+  }
+  //
+  // multiple files
+  //
+  if (File2List.Flink->Flink != &File2List) {
+    PrintToken (STRING_TOKEN (STR_COMPRESS_SECOND_MULT_FILES), HiiCompressHandle, L"eficompress");
+    Status = EFI_INVALID_PARAMETER;
+    goto Done;
+  }
+
+  File2Arg = CR (
+              File2List.Flink,
+              SHELL_FILE_ARG,
+              Link,
+              SHELL_FILE_ARG_SIGNATURE
+              );
+
+  if (!File2Arg->Parent) {
+    PrintToken (
+      STRING_TOKEN (STR_COMPRESS_CANNOT_OPEN),
+      HiiCompressHandle,
+      L"eficompress",
+      File2Arg->FullName,
+      File2Arg->Status
+      );
+    Status = File2Arg->Status;
+    goto Done;
+  }
+  //
+  // directory
+  //
+  if (File2Arg->Info && (File2Arg->Info->Attribute & EFI_FILE_DIRECTORY)) {
+    PrintToken (STRING_TOKEN (STR_COMPRESS_SECOND_DIR), HiiCompressHandle, L"eficompress");
+    Status = EFI_INVALID_PARAMETER;
+    goto Done;
+  }
+  //
+  //
+  //
+  if (File2Arg->Status == EFI_SUCCESS &&
+      File2Arg->OpenMode & EFI_FILE_MODE_READ &&
+      File2Arg->OpenMode & EFI_FILE_MODE_WRITE
+      ) {
+    File2Handle               = File2Arg->Handle;
+    File2Arg->Info->FileSize  = 0;
+    Status = File2Handle->SetInfo (
+                            File2Handle,
+                            &gEfiFileInfoGuid,
+                            (UINTN) File2Arg->Info->Size,
+                            File2Arg->Info
+                            );
+    if (EFI_ERROR (Status)) {
+      PrintToken (
+        STRING_TOKEN (STR_COMPRESS_WRITE_ERROR),
+        HiiCompressHandle,
+        L"eficompress",
+        File2Arg->FullName,
+        Status
+        );
+      Status = EFI_ACCESS_DENIED;
+      goto Done;
+    }
+
+    DstFileExist = TRUE;
+  } else {
+    Status = File2Arg->Parent->Open (
+                                File2Arg->Parent,
+                                &File2Handle,
+                                File2Arg->FileName,
+                                EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE,
+                                0
+                                );
+    if (EFI_ERROR (Status)) {
+      PrintToken (
+        STRING_TOKEN (STR_COMPRESS_CREATE_ERROR),
+        HiiCompressHandle,
+        L"eficompress",
+        File2Arg->FullName,
+        Status
+        );
+      goto Done;
+    }
+  }
+  //
+  // Allocate buffers for both files
+  //
+  SourceSize  = (UINTN) File1Arg->Info->FileSize;
+
+  File1Buffer = AllocatePool (SourceSize);
+  if (File1Buffer == NULL) {
+    PrintToken (STRING_TOKEN (STR_COMPRESS_OUT_OF_MEM), HiiCompressHandle, L"eficompress");
+    Status = EFI_OUT_OF_RESOURCES;
+    goto Done;
+  }
+
+  Status = File1Arg->Handle->Read (File1Arg->Handle, &SourceSize, File1Buffer);
+  if (EFI_ERROR (Status)) {
+    PrintToken (STRING_TOKEN (STR_COMPRESS_READ_ERROR), HiiCompressHandle, L"eficompress", File1Arg->FullName, Status);
+    goto Done;
+  }
+
+  DestinationSize = SourceSize;
+  File2Buffer     = AllocatePool (SourceSize);
+  if (File2Buffer == NULL) {
+    PrintToken (STRING_TOKEN (STR_COMPRESS_OUT_OF_MEM), HiiCompressHandle, L"eficompress");
+    Status = EFI_OUT_OF_RESOURCES;
+    goto Done;
+  }
+
+  Status = Compress (File1Buffer, (UINT32) SourceSize, File2Buffer, (UINT32 *) &DestinationSize);
+
+  if (SourceSize) {
+    Ratio = ((INT32) SourceSize * 100 - (INT32) DestinationSize * 100) / (INT32) SourceSize;
+    if (Ratio >= 0) {
+      PrintToken (
+        STRING_TOKEN (STR_COMPRESS_ORIG_SIZE),
+        HiiCompressHandle,
+        L"eficompress",
+        SourceSize,
+        DestinationSize,
+        Ratio
+        );
+    } else {
+      PrintToken (
+        STRING_TOKEN (STR_COMPRESS_ORIG_SIZE),
+        HiiCompressHandle,
+        L"eficompress",
+        SourceSize,
+        DestinationSize,
+        -Ratio
+        );
+    }
+  } else {
+    PrintToken (
+      STRING_TOKEN (STR_COMPRESS_ORIG_SIZE_2),
+      HiiCompressHandle,
+      L"eficompress",
+      SourceSize,
+      DestinationSize
+      );
+  }
+
+  if (Status == EFI_BUFFER_TOO_SMALL) {
+    FreePool (File2Buffer);
+    File2Buffer = AllocatePool (DestinationSize);
+    if (File2Buffer == NULL) {
+      PrintToken (STRING_TOKEN (STR_COMPRESS_OUT_OF_MEM), HiiCompressHandle, L"eficompress");
+      Status = EFI_OUT_OF_RESOURCES;
+      goto Done;
+    }
+
+    Status = Compress (File1Buffer, (UINT32) SourceSize, File2Buffer, (UINT32 *) &DestinationSize);
+  }
+
+  if (EFI_ERROR (Status)) {
+    PrintToken (STRING_TOKEN (STR_COMPRESS_COMPRESS_ERROR), HiiCompressHandle, L"eficompress", Status);
+    goto Done;
+  }
+
+  Status = File2Handle->Write (File2Handle, &DestinationSize, File2Buffer);
+  if (EFI_ERROR (Status)) {
+    PrintToken (STRING_TOKEN (STR_COMPRESS_WRITE_ERROR), HiiCompressHandle, L"eficompress", File2Arg->FullName, Status);
+    goto Done;
+  }
+
+  if (!DstFileExist) {
+    File2Handle->Close (File2Handle);
+  }
+
+Done:
+  if (File1Buffer) {
+    FreePool (File1Buffer);
+  }
+
+  if (File2Buffer) {
+    FreePool (File2Buffer);
+  }
+
+  ShellFreeFileList (&File1List);
+  ShellFreeFileList (&File2List);
+
+  //
+  // Shell command always succeeds
+  //
+  LibUnInitializeStrings ();
+  LibCheckVarFreeVarList (&ChkPck);
+  return Status;
+}
+
+EFI_STATUS
+InitializeCompressGetLineHelp (
+  OUT CHAR16                     **Str
+  )
+/*++
+
+Routine Description:
+
+  Get this command's line help
+
+Arguments:
+
+  Str - The line help
+
+Returns:
+
+  EFI_SUCCESS   - Success
+
+--*/
+{
+  return LibCmdGetStringByToken (STRING_ARRAY_NAME, &EfiCompressGuid, STRING_TOKEN (STR_EFICOMPRESS_LINEHELP), Str);
+}
diff --git a/EfiCompress/CompressStrings.uni b/EfiCompress/CompressStrings.uni
new file mode 100644 (file)
index 0000000..d359aae
Binary files /dev/null and b/EfiCompress/CompressStrings.uni differ
diff --git a/EfiCompress/compress.c b/EfiCompress/compress.c
new file mode 100644 (file)
index 0000000..7cccbef
--- /dev/null
@@ -0,0 +1,1771 @@
+/*++
+
+Copyright 2005, Intel Corporation                                                         
+All rights reserved. This program and the accompanying materials                          
+are licensed and made available under the terms and conditions of the BSD License         
+which accompanies this distribution. The full text of the license may be found at         
+http://opensource.org/licenses/bsd-license.php                                            
+                                                                                          
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+
+Module Name:
+
+  Compress.c
+
+Abstract:
+
+  Compression routine. The compression algorithm is a mixture of
+  LZ77 and Huffman coding. LZ77 transforms the source data into a
+  sequence of Original Characters and Pointers to repeated strings.
+  This sequence is further divided into Blocks and Huffman codings
+  are applied to each Block.
+
+--*/
+
+#include "EfiShellLib.h"
+
+//
+// Macro Definitions
+//
+typedef INT32 NODE;
+#define UINT8_MAX     0xff
+#define UINT8_BIT     8
+#define THRESHOLD     3
+#define INIT_CRC      0
+#define WNDBIT        19
+#define WNDSIZ        (1U << WNDBIT)
+#define MAXMATCH      256
+#define BLKSIZ        (1U << 14)  // 16 * 1024U
+#define PERC_FLAG     0x80000000U
+#define CODE_BIT      16
+#define NIL           0
+#define MAX_HASH_VAL  (3 * WNDSIZ + (WNDSIZ / 512 + 1) * UINT8_MAX)
+#define HASH(p, c)    ((p) + ((c) << (WNDBIT - 9)) + WNDSIZ * 2)
+#define CRCPOLY       0xA001
+#define UPDATE_CRC(c) mCrc = mCrcTable[(mCrc ^ (c)) & 0xFF] ^ (mCrc >> UINT8_BIT)
+
+//
+// C: the Char&Len Set; P: the Position Set; T: the exTra Set
+//
+#define NC    (UINT8_MAX + MAXMATCH + 2 - THRESHOLD)
+#define CBIT  9
+#define NP    (WNDBIT + 1)
+#define PBIT  5
+#define NT    (CODE_BIT + 3)
+#define TBIT  5
+#if NT > NP
+#define NPT NT
+#else
+#define NPT NP
+#endif
+//
+// Function Prototypes
+//
+STATIC 
+VOID 
+PutDword(
+  IN UINT32 Data
+  );
+
+STATIC
+EFI_STATUS
+AllocateMemory (
+  VOID
+  );
+
+STATIC
+VOID
+FreeMemory (
+  VOID
+  );
+
+STATIC
+VOID
+InitSlide (
+  VOID
+  );
+
+STATIC
+NODE
+Child (
+  IN NODE   q,
+  IN UINT8  c
+  );
+
+STATIC
+VOID
+MakeChild (
+  IN NODE   q,
+  IN UINT8  c,
+  IN NODE   r
+  );
+
+STATIC
+VOID
+Split (
+  IN NODE Old
+  );
+
+STATIC
+VOID
+InsertNode (
+  VOID
+  );
+
+STATIC
+VOID
+DeleteNode (
+  VOID
+  );
+
+STATIC
+VOID
+GetNextMatch (
+  VOID
+  );
+
+STATIC
+EFI_STATUS
+Encode (
+  VOID
+  );
+
+STATIC
+VOID
+CountTFreq (
+  VOID
+  );
+
+STATIC
+VOID
+WritePTLen (
+  IN INT32 n,
+  IN INT32 nbit,
+  IN INT32 Special
+  );
+
+STATIC
+VOID
+WriteCLen (
+  VOID
+  );
+
+STATIC
+VOID
+EncodeC (
+  IN INT32 c
+  );
+
+STATIC
+VOID
+EncodeP (
+  IN UINT32 p
+  );
+
+STATIC
+VOID
+SendBlock (
+  VOID
+  );
+
+STATIC
+VOID
+CompressOutput (
+  IN UINT32 c,
+  IN UINT32 p
+  );
+
+STATIC
+VOID
+HufEncodeStart (
+  VOID
+  );
+
+STATIC
+VOID
+HufEncodeEnd (
+  VOID
+  );
+
+STATIC
+VOID
+MakeCrcTable (
+  VOID
+  );
+
+STATIC
+VOID
+PutBits (
+  IN INT32    n,
+  IN UINT32   x
+  );
+
+STATIC
+INT32
+FreadCrc (
+  OUT UINT8 *p,
+  IN  INT32 n
+  );
+
+STATIC
+VOID
+InitPutBits (
+  VOID
+  );
+
+STATIC
+VOID
+CountLen (
+  IN INT32 i
+  );
+
+STATIC
+VOID
+MakeLen (
+  IN INT32 Root
+  );
+
+STATIC
+VOID
+DownHeap (
+  IN INT32 i
+  );
+
+STATIC
+VOID
+MakeCode (
+  IN  INT32         n,
+  IN  UINT8 Len[    ],
+  OUT UINT16 Code[  ]
+  );
+
+STATIC
+INT32
+MakeTree (
+  IN  INT32             NParm,
+  IN  UINT16  FreqParm[ ],
+  OUT UINT8   LenParm[  ],
+  OUT UINT16  CodeParm[ ]
+  );
+
+//
+//  Global Variables
+//
+STATIC UINT8  *mSrc, *mDst, *mSrcUpperLimit, *mDstUpperLimit;
+
+STATIC UINT8  *mLevel, *mText, *mChildCount, *mBuf, mCLen[NC], mPTLen[NPT], *mLen;
+STATIC INT16  mHeap[NC + 1];
+STATIC INT32  mRemainder, mMatchLen, mBitCount, mHeapSize, mN;
+STATIC UINT32 mBufSiz = 0, mOutputPos, mOutputMask, mSubBitBuf, mCrc;
+STATIC UINT32 mCompSize, mOrigSize;
+
+STATIC UINT16 *mFreq, *mSortPtr, mLenCnt[17], mLeft[2 * NC - 1], mRight[2 * NC - 1], mCrcTable[UINT8_MAX + 1],
+  mCFreq[2 * NC - 1], mCTable[4096], mCCode[NC], mPFreq[2 * NP - 1], mPTCode[NPT], mTFreq[2 * NT - 1];
+
+STATIC NODE   mPos, mMatchPos, mAvail, *mPosition, *mParent, *mPrev, *mNext = NULL;
+
+//
+// functions
+//
+EFI_STATUS
+Compress (
+  IN      UINT8   *SrcBuffer,
+  IN      UINT32  SrcSize,
+  IN      UINT8   *DstBuffer,
+  IN OUT  UINT32  *DstSize
+  )
+/*++
+
+Routine Description:
+
+  The main compression routine.
+
+Arguments:
+
+  SrcBuffer   - The buffer storing the source data
+  SrcSize     - The size of source data
+  DstBuffer   - The buffer to store the compressed data
+  DstSize     - On input, the size of DstBuffer; On output,
+                the size of the actual compressed data.
+
+Returns:
+
+  EFI_BUFFER_TOO_SMALL  - The DstBuffer is too small. In this case,
+                          DstSize contains the size needed.
+  EFI_SUCCESS           - Compression is successful.
+
+  EFI_OUT_OF_RESOURCES  - Out of resources
+--*/
+{
+  EFI_STATUS  Status;
+
+  //
+  // Initializations
+  //
+  mBufSiz         = 0;
+  mBuf            = NULL;
+  mText           = NULL;
+  mLevel          = NULL;
+  mChildCount     = NULL;
+  mPosition       = NULL;
+  mParent         = NULL;
+  mPrev           = NULL;
+  mNext           = NULL;
+
+  mSrc            = SrcBuffer;
+  mSrcUpperLimit  = mSrc + SrcSize;
+  mDst            = DstBuffer;
+  mDstUpperLimit  = mDst +*DstSize;
+
+  PutDword (0L);
+  PutDword (0L);
+
+  MakeCrcTable ();
+
+  mOrigSize             = mCompSize = 0;
+  mCrc                  = INIT_CRC;
+
+  //
+  // Compress it
+  //
+  Status = Encode ();
+  if (EFI_ERROR (Status)) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+  //
+  // Null terminate the compressed data
+  //
+  if (mDst < mDstUpperLimit) {
+    *mDst++ = 0;
+  }
+  //
+  // Fill in compressed size and original size
+  //
+  mDst = DstBuffer;
+  PutDword (mCompSize + 1);
+  PutDword (mOrigSize);
+
+  //
+  // Return
+  //
+  if (mCompSize + 1 + 8 > *DstSize) {
+    *DstSize = mCompSize + 1 + 8;
+    return EFI_BUFFER_TOO_SMALL;
+  } else {
+    *DstSize = mCompSize + 1 + 8;
+    return EFI_SUCCESS;
+  }
+
+}
+
+STATIC
+VOID
+PutDword (
+  IN UINT32 Data
+  )
+/*++
+
+Routine Description:
+
+  Put a dword to output stream
+  
+Arguments:
+
+  Data    - the dword to put
+  
+Returns: (VOID)
+  
+--*/
+{
+  if (mDst < mDstUpperLimit) {
+    *mDst++ = (UINT8) (((UINT8) (Data)) & 0xff);
+  }
+
+  if (mDst < mDstUpperLimit) {
+    *mDst++ = (UINT8) (((UINT8) (Data >> 0x08)) & 0xff);
+  }
+
+  if (mDst < mDstUpperLimit) {
+    *mDst++ = (UINT8) (((UINT8) (Data >> 0x10)) & 0xff);
+  }
+
+  if (mDst < mDstUpperLimit) {
+    *mDst++ = (UINT8) (((UINT8) (Data >> 0x18)) & 0xff);
+  }
+}
+
+STATIC
+EFI_STATUS
+AllocateMemory (
+  VOID
+  )
+/*++
+
+Routine Description:
+
+  Allocate memory spaces for data structures used in compression process
+  
+Arguments: 
+  
+  None
+
+Returns:
+
+  EFI_SUCCESS           - Memory is allocated successfully
+  EFI_OUT_OF_RESOURCES  - Allocation fails
+
+--*/
+{
+  mText       = AllocateZeroPool (WNDSIZ * 2 + MAXMATCH);
+  mLevel      = AllocatePool ((WNDSIZ + UINT8_MAX + 1) * sizeof (*mLevel));
+  mChildCount = AllocatePool ((WNDSIZ + UINT8_MAX + 1) * sizeof (*mChildCount));
+  mPosition   = AllocatePool ((WNDSIZ + UINT8_MAX + 1) * sizeof (*mPosition));
+  mParent     = AllocatePool (WNDSIZ * 2 * sizeof (*mParent));
+  mPrev       = AllocatePool (WNDSIZ * 2 * sizeof (*mPrev));
+  mNext       = AllocatePool ((MAX_HASH_VAL + 1) * sizeof (*mNext));
+
+  mBufSiz     = BLKSIZ;
+  mBuf        = AllocatePool (mBufSiz);
+  while (mBuf == NULL) {
+    mBufSiz = (mBufSiz / 10U) * 9U;
+    if (mBufSiz < 4 * 1024U) {
+      return EFI_OUT_OF_RESOURCES;
+    }
+
+    mBuf = AllocatePool (mBufSiz);
+  }
+
+  mBuf[0] = 0;
+
+  return EFI_SUCCESS;
+}
+
+VOID
+FreeMemory (
+  VOID
+  )
+/*++
+
+Routine Description:
+
+  Called when compression is completed to free memory previously allocated.
+  
+Arguments: (VOID)
+
+Returns: (VOID)
+
+--*/
+{
+  if (mText) {
+    FreePool (mText);
+  }
+
+  if (mLevel) {
+    FreePool (mLevel);
+  }
+
+  if (mChildCount) {
+    FreePool (mChildCount);
+  }
+
+  if (mPosition) {
+    FreePool (mPosition);
+  }
+
+  if (mParent) {
+    FreePool (mParent);
+  }
+
+  if (mPrev) {
+    FreePool (mPrev);
+  }
+
+  if (mNext) {
+    FreePool (mNext);
+  }
+
+  if (mBuf) {
+    FreePool (mBuf);
+  }
+
+  return ;
+}
+
+STATIC
+VOID
+InitSlide (
+  VOID
+  )
+/*++
+
+Routine Description:
+
+  Initialize String Info Log data structures
+  
+Arguments: (VOID)
+
+Returns: (VOID)
+
+--*/
+{
+  NODE  i;
+
+  for (i = WNDSIZ; i <= WNDSIZ + UINT8_MAX; i++) {
+    mLevel[i]     = 1;
+    mPosition[i]  = NIL;  /* sentinel */
+  }
+
+  for (i = WNDSIZ; i < WNDSIZ * 2; i++) {
+    mParent[i] = NIL;
+  }
+
+  mAvail = 1;
+  for (i = 1; i < WNDSIZ - 1; i++) {
+    mNext[i] = (NODE) (i + 1);
+  }
+
+  mNext[WNDSIZ - 1] = NIL;
+  for (i = WNDSIZ * 2; i <= MAX_HASH_VAL; i++) {
+    mNext[i] = NIL;
+  }
+}
+
+STATIC
+NODE
+Child (
+  IN NODE   q,
+  IN UINT8  c
+  )
+/*++
+
+Routine Description:
+
+  Find child node given the parent node and the edge character
+  
+Arguments:
+
+  q       - the parent node
+  c       - the edge character
+  
+Returns:
+
+  The child node (NIL if not found)  
+  
+--*/
+{
+  NODE  r;
+
+  r             = mNext[HASH (q, c)];
+  mParent[NIL]  = q;  /* sentinel */
+  while (mParent[r] != q) {
+    r = mNext[r];
+  }
+
+  return r;
+}
+
+STATIC
+VOID
+MakeChild (
+  IN NODE   q,
+  IN UINT8  c,
+  IN NODE   r
+  )
+/*++
+
+Routine Description:
+
+  Create a new child for a given parent node.
+  
+Arguments:
+
+  q       - the parent node
+  c       - the edge character
+  r       - the child node
+  
+Returns: (VOID)
+
+--*/
+{
+  NODE  h;
+
+  NODE  t;
+
+  h           = (NODE) HASH (q, c);
+  t           = mNext[h];
+  mNext[h]    = r;
+  mNext[r]    = t;
+  mPrev[t]    = r;
+  mPrev[r]    = h;
+  mParent[r]  = q;
+  mChildCount[q]++;
+}
+
+STATIC
+VOID
+Split (
+  NODE Old
+  )
+/*++
+
+Routine Description:
+
+  Split a node.
+  
+Arguments:
+
+  Old     - the node to split
+  
+Returns: (VOID)
+
+--*/
+{
+  NODE  New;
+
+  NODE  t;
+
+  New               = mAvail;
+  mAvail            = mNext[New];
+  mChildCount[New]  = 0;
+  t                 = mPrev[Old];
+  mPrev[New]        = t;
+  mNext[t]          = New;
+  t                 = mNext[Old];
+  mNext[New]        = t;
+  mPrev[t]          = New;
+  mParent[New]      = mParent[Old];
+  mLevel[New]       = (UINT8) mMatchLen;
+  mPosition[New]    = mPos;
+  MakeChild (New, mText[mMatchPos + mMatchLen], Old);
+  MakeChild (New, mText[mPos + mMatchLen], mPos);
+}
+
+STATIC
+VOID
+InsertNode (
+  VOID
+  )
+/*++
+
+Routine Description:
+
+  Insert string info for current position into the String Info Log
+  
+Arguments: (VOID)
+
+Returns: (VOID)
+
+--*/
+{
+  NODE  q;
+
+  NODE  r;
+
+  NODE  j;
+
+  NODE  t;
+  UINT8 c;
+  UINT8 *t1;
+  UINT8 *t2;
+
+  if (mMatchLen >= 4) {
+    //
+    // We have just got a long match, the target tree
+    // can be located by MatchPos + 1. Travese the tree
+    // from bottom up to get to a proper starting point.
+    // The usage of PERC_FLAG ensures proper node deletion
+    // in DeleteNode() later.
+    //
+    mMatchLen--;
+    r = (NODE) ((mMatchPos + 1) | WNDSIZ);
+    q = mParent[r];
+    while (q == NIL) {
+      r = mNext[r];
+      q = mParent[r];
+    }
+
+    while (mLevel[q] >= mMatchLen) {
+      r = q;
+      q = mParent[q];
+    }
+
+    t = q;
+    while (mPosition[t] < 0) {
+      mPosition[t]  = mPos;
+      t             = mParent[t];
+    }
+
+    if (t < WNDSIZ) {
+      mPosition[t] = (NODE) (mPos | (UINT32) PERC_FLAG);
+    }
+  } else {
+    //
+    // Locate the target tree
+    //
+    q = (NODE) (mText[mPos] + WNDSIZ);
+    c = mText[mPos + 1];
+    r = Child (q, c);
+    if (r == NIL) {
+      MakeChild (q, c, mPos);
+      mMatchLen = 1;
+      return ;
+    }
+
+    mMatchLen = 2;
+  }
+  //
+  // Traverse down the tree to find a match.
+  // Update Position value along the route.
+  // Node split or creation is involved.
+  //
+  for (;;) {
+    if (r >= WNDSIZ) {
+      j         = MAXMATCH;
+      mMatchPos = r;
+    } else {
+      j         = mLevel[r];
+      mMatchPos = (NODE) (mPosition[r] & (UINT32)~PERC_FLAG);
+    }
+
+    if (mMatchPos >= mPos) {
+      mMatchPos -= WNDSIZ;
+    }
+
+    t1  = &mText[mPos + mMatchLen];
+    t2  = &mText[mMatchPos + mMatchLen];
+    while (mMatchLen < j) {
+      if (*t1 != *t2) {
+        Split (r);
+        return ;
+      }
+
+      mMatchLen++;
+      t1++;
+      t2++;
+    }
+
+    if (mMatchLen >= MAXMATCH) {
+      break;
+    }
+
+    mPosition[r]  = mPos;
+    q             = r;
+    r             = Child (q, *t1);
+    if (r == NIL) {
+      MakeChild (q, *t1, mPos);
+      return ;
+    }
+
+    mMatchLen++;
+  }
+
+  t             = mPrev[r];
+  mPrev[mPos]   = t;
+  mNext[t]      = mPos;
+  t             = mNext[r];
+  mNext[mPos]   = t;
+  mPrev[t]      = mPos;
+  mParent[mPos] = q;
+  mParent[r]    = NIL;
+
+  //
+  // Special usage of 'next'
+  //
+  mNext[r] = mPos;
+
+}
+
+STATIC
+VOID
+DeleteNode (
+  VOID
+  )
+/*++
+
+Routine Description:
+
+  Delete outdated string info. (The Usage of PERC_FLAG
+  ensures a clean deletion)
+  
+Arguments: (VOID)
+
+Returns: (VOID)
+
+--*/
+{
+  NODE  q;
+
+  NODE  r;
+
+  NODE  s;
+
+  NODE  t;
+
+  NODE  u;
+
+  if (mParent[mPos] == NIL) {
+    return ;
+  }
+
+  r             = mPrev[mPos];
+  s             = mNext[mPos];
+  mNext[r]      = s;
+  mPrev[s]      = r;
+  r             = mParent[mPos];
+  mParent[mPos] = NIL;
+  if (r >= WNDSIZ) {
+    return ;
+  }
+
+  mChildCount[r]--;
+  if (mChildCount[r] > 1) {
+    return ;
+  }
+
+  t = (NODE) (mPosition[r] & (UINT32)~PERC_FLAG);
+  if (t >= mPos) {
+    t -= WNDSIZ;
+  }
+
+  s = t;
+  q = mParent[r];
+  u = mPosition[q];
+  while (u & (UINT32) PERC_FLAG) {
+    u &= (UINT32)~PERC_FLAG;
+    if (u >= mPos) {
+      u -= WNDSIZ;
+    }
+
+    if (u > s) {
+      s = u;
+    }
+
+    mPosition[q]  = (NODE) (s | WNDSIZ);
+    q             = mParent[q];
+    u             = mPosition[q];
+  }
+
+  if (q < WNDSIZ) {
+    if (u >= mPos) {
+      u -= WNDSIZ;
+    }
+
+    if (u > s) {
+      s = u;
+    }
+
+    mPosition[q] = (NODE) (s | WNDSIZ | (UINT32) PERC_FLAG);
+  }
+
+  s           = Child (r, mText[t + mLevel[r]]);
+  t           = mPrev[s];
+  u           = mNext[s];
+  mNext[t]    = u;
+  mPrev[u]    = t;
+  t           = mPrev[r];
+  mNext[t]    = s;
+  mPrev[s]    = t;
+  t           = mNext[r];
+  mPrev[t]    = s;
+  mNext[s]    = t;
+  mParent[s]  = mParent[r];
+  mParent[r]  = NIL;
+  mNext[r]    = mAvail;
+  mAvail      = r;
+}
+
+STATIC
+VOID
+GetNextMatch (
+  VOID
+  )
+/*++
+
+Routine Description:
+
+  Advance the current position (read in new data if needed).
+  Delete outdated string info. Find a match string for current position.
+
+Arguments: (VOID)
+
+Returns: (VOID)
+
+--*/
+{
+  INT32 n;
+  VOID  *Temp;
+
+  mRemainder--;
+  mPos++;
+  if (mPos == WNDSIZ * 2) {
+    Temp = AllocatePool (WNDSIZ + MAXMATCH);
+    CopyMem (Temp, &mText[WNDSIZ], WNDSIZ + MAXMATCH);
+    CopyMem (&mText[0], Temp, WNDSIZ + MAXMATCH);
+    FreePool (Temp);
+    n = FreadCrc (&mText[WNDSIZ + MAXMATCH], WNDSIZ);
+    mRemainder += n;
+    mPos = WNDSIZ;
+  }
+
+  DeleteNode ();
+  InsertNode ();
+}
+
+STATIC
+EFI_STATUS
+Encode (
+  VOID
+  )
+/*++
+
+Routine Description:
+
+  The main controlling routine for compression process.
+
+Arguments: (VOID)
+
+Returns:
+  
+  EFI_SUCCESS           - The compression is successful
+  EFI_OUT_0F_RESOURCES  - Not enough memory for compression process
+
+--*/
+{
+  EFI_STATUS  Status;
+  INT32       LastMatchLen;
+  NODE        LastMatchPos;
+
+  Status = AllocateMemory ();
+  if (EFI_ERROR (Status)) {
+    FreeMemory ();
+    return Status;
+  }
+
+  InitSlide ();
+
+  HufEncodeStart ();
+
+  mRemainder  = FreadCrc (&mText[WNDSIZ], WNDSIZ + MAXMATCH);
+
+  mMatchLen   = 0;
+  mPos        = WNDSIZ;
+  InsertNode ();
+  if (mMatchLen > mRemainder) {
+    mMatchLen = mRemainder;
+  }
+
+  while (mRemainder > 0) {
+    LastMatchLen  = mMatchLen;
+    LastMatchPos  = mMatchPos;
+    GetNextMatch ();
+    if (mMatchLen > mRemainder) {
+      mMatchLen = mRemainder;
+    }
+
+    if (mMatchLen > LastMatchLen || LastMatchLen < THRESHOLD) {
+      //
+      // Not enough benefits are gained by outputting a pointer,
+      // so just output the original character
+      //
+      CompressOutput (mText[mPos - 1], 0);
+    } else {
+      //
+      // Outputting a pointer is beneficial enough, do it.
+      //
+      CompressOutput (
+        LastMatchLen + (UINT8_MAX + 1 - THRESHOLD),
+        (mPos - LastMatchPos - 2) & (WNDSIZ - 1)
+        );
+      LastMatchLen--;
+      while (LastMatchLen > 0) {
+        GetNextMatch ();
+        LastMatchLen--;
+      }
+
+      if (mMatchLen > mRemainder) {
+        mMatchLen = mRemainder;
+      }
+    }
+  }
+
+  HufEncodeEnd ();
+  FreeMemory ();
+  return EFI_SUCCESS;
+}
+
+STATIC
+VOID
+CountTFreq (
+  VOID
+  )
+/*++
+
+Routine Description:
+
+  Count the frequencies for the Extra Set
+  
+Arguments: (VOID)
+
+Returns: (VOID)
+
+--*/
+{
+  INT32 i;
+
+  INT32 k;
+
+  INT32 n;
+
+  INT32 Count;
+
+  for (i = 0; i < NT; i++) {
+    mTFreq[i] = 0;
+  }
+
+  n = NC;
+  while (n > 0 && mCLen[n - 1] == 0) {
+    n--;
+  }
+
+  i = 0;
+  while (i < n) {
+    k = mCLen[i++];
+    if (k == 0) {
+      Count = 1;
+      while (i < n && mCLen[i] == 0) {
+        i++;
+        Count++;
+      }
+
+      if (Count <= 2) {
+        mTFreq[0] = (UINT16) (mTFreq[0] + Count);
+      } else if (Count <= 18) {
+        mTFreq[1]++;
+      } else if (Count == 19) {
+        mTFreq[0]++;
+        mTFreq[1]++;
+      } else {
+        mTFreq[2]++;
+      }
+    } else {
+      mTFreq[k + 2]++;
+    }
+  }
+}
+
+STATIC
+VOID
+WritePTLen (
+  IN INT32 n,
+  IN INT32 nbit,
+  IN INT32 Special
+  )
+/*++
+
+Routine Description:
+
+  Outputs the code length array for the Extra Set or the Position Set.
+  
+Arguments:
+
+  n       - the number of symbols
+  nbit    - the number of bits needed to represent 'n'
+  Special - the special symbol that needs to be take care of
+  
+Returns: (VOID)
+
+--*/
+{
+  INT32 i;
+
+  INT32 k;
+
+  while (n > 0 && mPTLen[n - 1] == 0) {
+    n--;
+  }
+
+  PutBits (nbit, n);
+  i = 0;
+  while (i < n) {
+    k = mPTLen[i++];
+    if (k <= 6) {
+      PutBits (3, k);
+    } else {
+      PutBits (k - 3, (1U << (k - 3)) - 2);
+    }
+
+    if (i == Special) {
+      while (i < 6 && mPTLen[i] == 0) {
+        i++;
+      }
+
+      PutBits (2, (i - 3) & 3);
+    }
+  }
+}
+
+STATIC
+VOID
+WriteCLen (
+  VOID
+  )
+/*++
+
+Routine Description:
+
+  Outputs the code length array for Char&Length Set
+  
+Arguments: (VOID)
+
+Returns: (VOID)
+
+--*/
+{
+  INT32 i;
+
+  INT32 k;
+
+  INT32 n;
+
+  INT32 Count;
+
+  n = NC;
+  while (n > 0 && mCLen[n - 1] == 0) {
+    n--;
+  }
+
+  PutBits (CBIT, n);
+  i = 0;
+  while (i < n) {
+    k = mCLen[i++];
+    if (k == 0) {
+      Count = 1;
+      while (i < n && mCLen[i] == 0) {
+        i++;
+        Count++;
+      }
+
+      if (Count <= 2) {
+        for (k = 0; k < Count; k++) {
+          PutBits (mPTLen[0], mPTCode[0]);
+        }
+      } else if (Count <= 18) {
+        PutBits (mPTLen[1], mPTCode[1]);
+        PutBits (4, Count - 3);
+      } else if (Count == 19) {
+        PutBits (mPTLen[0], mPTCode[0]);
+        PutBits (mPTLen[1], mPTCode[1]);
+        PutBits (4, 15);
+      } else {
+        PutBits (mPTLen[2], mPTCode[2]);
+        PutBits (CBIT, Count - 20);
+      }
+    } else {
+      PutBits (mPTLen[k + 2], mPTCode[k + 2]);
+    }
+  }
+}
+
+STATIC
+VOID
+EncodeC (
+  IN INT32 c
+  )
+{
+  PutBits (mCLen[c], mCCode[c]);
+}
+
+STATIC
+VOID
+EncodeP (
+  IN UINT32 p
+  )
+{
+  UINT32  c;
+
+  UINT32  q;
+
+  c = 0;
+  q = p;
+  while (q) {
+    q >>= 1;
+    c++;
+  }
+
+  PutBits (mPTLen[c], mPTCode[c]);
+  if (c > 1) {
+    PutBits (c - 1, p & (0xFFFFFFFFU >> (32 - c + 1)));
+  }
+}
+
+STATIC
+VOID
+SendBlock (
+  VOID
+  )
+/*++
+
+Routine Description:
+
+  Huffman code the block and output it.
+  
+Arguments:
+
+  None
+
+Returns:
+
+  None
+
+--*/
+{
+  UINT32  i;
+
+  UINT32  j;
+
+  UINT32  k;
+
+  UINT32  Flags;
+
+  UINT32  Root;
+
+  UINT32  Pos;
+
+  UINT32  Size;
+  Flags = 0;
+
+  Root  = MakeTree (NC, mCFreq, mCLen, mCCode);
+  Size  = mCFreq[Root];
+  PutBits (16, Size);
+  if (Root >= NC) {
+    CountTFreq ();
+    Root = MakeTree (NT, mTFreq, mPTLen, mPTCode);
+    if (Root >= NT) {
+      WritePTLen (NT, TBIT, 3);
+    } else {
+      PutBits (TBIT, 0);
+      PutBits (TBIT, Root);
+    }
+
+    WriteCLen ();
+  } else {
+    PutBits (TBIT, 0);
+    PutBits (TBIT, 0);
+    PutBits (CBIT, 0);
+    PutBits (CBIT, Root);
+  }
+
+  Root = MakeTree (NP, mPFreq, mPTLen, mPTCode);
+  if (Root >= NP) {
+    WritePTLen (NP, PBIT, -1);
+  } else {
+    PutBits (PBIT, 0);
+    PutBits (PBIT, Root);
+  }
+
+  Pos = 0;
+  for (i = 0; i < Size; i++) {
+    if (i % UINT8_BIT == 0) {
+      Flags = mBuf[Pos++];
+    } else {
+      Flags <<= 1;
+    }
+
+    if (Flags & (1U << (UINT8_BIT - 1))) {
+      EncodeC (mBuf[Pos++] + (1U << UINT8_BIT));
+      k = mBuf[Pos++];
+      for (j = 0; j < 3; j++) {
+        k <<= UINT8_BIT;
+        k += mBuf[Pos++];
+      }
+
+      EncodeP (k);
+    } else {
+      EncodeC (mBuf[Pos++]);
+    }
+  }
+
+  for (i = 0; i < NC; i++) {
+    mCFreq[i] = 0;
+  }
+
+  for (i = 0; i < NP; i++) {
+    mPFreq[i] = 0;
+  }
+}
+
+STATIC
+VOID
+CompressOutput (
+  IN UINT32 c,
+  IN UINT32 p
+  )
+/*++
+
+Routine Description:
+
+  Outputs an Original Character or a Pointer
+
+Arguments:
+
+  c     - The original character or the 'String Length' element of a Pointer
+  p     - The 'Position' field of a Pointer
+
+Returns: (VOID)
+
+--*/
+{
+  STATIC UINT32 CPos;
+
+  if ((mOutputMask >>= 1) == 0) {
+    mOutputMask = 1U << (UINT8_BIT - 1);
+    //
+    // Check the buffer overflow per outputing UINT8_BIT symbols
+    // which is an Original Character or a Pointer. The biggest
+    // symbol is a Pointer which occupies 5 bytes.
+    //
+    if (mOutputPos >= mBufSiz - 5 * UINT8_BIT) {
+      SendBlock ();
+      mOutputPos = 0;
+    }
+
+    CPos        = mOutputPos++;
+    mBuf[CPos]  = 0;
+  }
+
+  mBuf[mOutputPos++] = (UINT8) c;
+  mCFreq[c]++;
+  if (c >= (1U << UINT8_BIT)) {
+    mBuf[CPos] |= mOutputMask;
+    mBuf[mOutputPos++]  = (UINT8) (p >> 24);
+    mBuf[mOutputPos++]  = (UINT8) (p >> 16);
+    mBuf[mOutputPos++]  = (UINT8) (p >> (UINT8_BIT));
+    mBuf[mOutputPos++]  = (UINT8) p;
+    c                   = 0;
+    while (p) {
+      p >>= 1;
+      c++;
+    }
+
+    mPFreq[c]++;
+  }
+}
+
+STATIC
+VOID
+HufEncodeStart (
+  VOID
+  )
+{
+  INT32 i;
+
+  for (i = 0; i < NC; i++) {
+    mCFreq[i] = 0;
+  }
+
+  for (i = 0; i < NP; i++) {
+    mPFreq[i] = 0;
+  }
+
+  mOutputPos = mOutputMask = 0;
+  InitPutBits ();
+  return ;
+}
+
+STATIC
+VOID
+HufEncodeEnd (
+  VOID
+  )
+{
+  SendBlock ();
+
+  //
+  // Flush remaining bits
+  //
+  PutBits (UINT8_BIT - 1, 0);
+
+  return ;
+}
+
+STATIC
+VOID
+MakeCrcTable (
+  VOID
+  )
+{
+  UINT32  i;
+
+  UINT32  j;
+
+  UINT32  r;
+
+  for (i = 0; i <= UINT8_MAX; i++) {
+    r = i;
+    for (j = 0; j < UINT8_BIT; j++) {
+      if (r & 1) {
+        r = (r >> 1) ^ CRCPOLY;
+      } else {
+        r >>= 1;
+      }
+    }
+
+    mCrcTable[i] = (UINT16) r;
+  }
+}
+
+STATIC
+VOID
+PutBits (
+  IN INT32    n,
+  IN UINT32   x
+  )
+/*++
+
+Routine Description:
+
+  Outputs rightmost n bits of x
+
+Arguments:
+
+  n   - the rightmost n bits of the data is used
+  x   - the data 
+
+Returns: 
+
+  None
+
+--*/
+{
+  UINT8 Temp;
+
+  while (n >= mBitCount) {
+    Temp = (UINT8) (mSubBitBuf | (x >> (n -= mBitCount)));
+    //
+    // n -= mBitCount should never equal to 32
+    //
+    if (mDst < mDstUpperLimit) {
+      *mDst++ = Temp;
+    }
+
+    mCompSize++;
+    mSubBitBuf  = 0;
+    mBitCount   = UINT8_BIT;
+  }
+
+  mSubBitBuf |= x << (mBitCount -= n);
+}
+
+STATIC
+INT32
+FreadCrc (
+  OUT UINT8 *p,
+  IN  INT32 n
+  )
+/*++
+
+Routine Description:
+
+  Read in source data
+  
+Arguments:
+
+  p   - the buffer to hold the data
+  n   - number of bytes to read
+
+Returns:
+
+  number of bytes actually read
+  
+--*/
+{
+  INT32 i;
+
+  for (i = 0; mSrc < mSrcUpperLimit && i < n; i++) {
+    *p++ = *mSrc++;
+  }
+
+  n = i;
+
+  p -= n;
+  mOrigSize += n;
+  i--;
+  while (i >= 0) {
+    UPDATE_CRC (*p++);
+    i--;
+  }
+
+  return n;
+}
+
+STATIC
+VOID
+InitPutBits (
+  VOID
+  )
+{
+  mBitCount   = UINT8_BIT;
+  mSubBitBuf  = 0;
+}
+
+STATIC
+VOID
+CountLen (
+  IN INT32 i
+  )
+/*++
+
+Routine Description:
+
+  Count the number of each code length for a Huffman tree.
+  
+Arguments:
+
+  i   - the top node
+  
+Returns: (VOID)
+
+--*/
+{
+  STATIC INT32  Depth = 0;
+
+  if (i < mN) {
+    mLenCnt[(Depth < 16) ? Depth : 16]++;
+  } else {
+    Depth++;
+    CountLen (mLeft[i]);
+    CountLen (mRight[i]);
+    Depth--;
+  }
+}
+
+STATIC
+VOID
+MakeLen (
+  IN INT32 Root
+  )
+/*++
+
+Routine Description:
+
+  Create code length array for a Huffman tree
+  
+Arguments:
+
+  Root   - the root of the tree
+
+Returns:
+
+  None
+  
+--*/
+{
+  INT32   i;
+
+  INT32   k;
+  UINT32  Cum;
+
+  for (i = 0; i <= 16; i++) {
+    mLenCnt[i] = 0;
+  }
+
+  CountLen (Root);
+
+  //
+  // Adjust the length count array so that
+  // no code will be generated longer than its designated length
+  //
+  Cum = 0;
+  for (i = 16; i > 0; i--) {
+    Cum += mLenCnt[i] << (16 - i);
+  }
+
+  while (Cum != (1U << 16)) {
+    mLenCnt[16]--;
+    for (i = 15; i > 0; i--) {
+      if (mLenCnt[i] != 0) {
+        mLenCnt[i]--;
+        mLenCnt[i + 1] += 2;
+        break;
+      }
+    }
+
+    Cum--;
+  }
+
+  for (i = 16; i > 0; i--) {
+    k = mLenCnt[i];
+    k--;
+    while (k >= 0) {
+      mLen[*mSortPtr++] = (UINT8) i;
+      k--;
+    }
+  }
+}
+
+STATIC
+VOID
+DownHeap (
+  IN INT32 i
+  )
+{
+  INT32 j;
+
+  INT32 k;
+
+  //
+  // priority queue: send i-th entry down heap
+  //
+  k = mHeap[i];
+  j = 2 * i;
+  while (j <= mHeapSize) {
+    if (j < mHeapSize && mFreq[mHeap[j]] > mFreq[mHeap[j + 1]]) {
+      j++;
+    }
+
+    if (mFreq[k] <= mFreq[mHeap[j]]) {
+      break;
+    }
+
+    mHeap[i]  = mHeap[j];
+    i         = j;
+    j         = 2 * i;
+  }
+
+  mHeap[i] = (INT16) k;
+}
+
+STATIC
+VOID
+MakeCode (
+  IN  INT32         n,
+  IN  UINT8 Len[    ],
+  OUT UINT16 Code[  ]
+  )
+/*++
+
+Routine Description:
+
+  Assign code to each symbol based on the code length array
+  
+Arguments:
+
+  n     - number of symbols
+  Len   - the code length array
+  Code  - stores codes for each symbol
+
+Returns: 
+
+  None
+
+--*/
+{
+  INT32   i;
+  UINT16  Start[18];
+
+  Start[1] = 0;
+  for (i = 1; i <= 16; i++) {
+    Start[i + 1] = (UINT16) ((Start[i] + mLenCnt[i]) << 1);
+  }
+
+  for (i = 0; i < n; i++) {
+    Code[i] = Start[Len[i]]++;
+  }
+}
+
+STATIC
+INT32
+MakeTree (
+  IN  INT32             NParm,
+  IN  UINT16  FreqParm[ ],
+  OUT UINT8   LenParm[  ],
+  OUT UINT16  CodeParm[ ]
+  )
+/*++
+
+Routine Description:
+
+  Generates Huffman codes given a frequency distribution of symbols
+  
+Arguments:
+
+  NParm    - number of symbols
+  FreqParm - frequency of each symbol
+  LenParm  - code length for each symbol
+  CodeParm - code for each symbol
+  
+Returns:
+
+  Root of the Huffman tree.
+  
+--*/
+{
+  INT32 i;
+
+  INT32 j;
+
+  INT32 k;
+
+  INT32 Avail;
+
+  //
+  // make tree, calculate len[], return root
+  //
+  mN        = NParm;
+  mFreq     = FreqParm;
+  mLen      = LenParm;
+  Avail     = mN;
+  mHeapSize = 0;
+  mHeap[1]  = 0;
+  for (i = 0; i < mN; i++) {
+    mLen[i] = 0;
+    if (mFreq[i]) {
+      mHeapSize++;
+      mHeap[mHeapSize] = (INT16) i;
+    }
+  }
+
+  if (mHeapSize < 2) {
+    CodeParm[mHeap[1]] = 0;
+    return mHeap[1];
+  }
+
+  for (i = mHeapSize / 2; i >= 1; i--) {
+    //
+    // make priority queue
+    //
+    DownHeap (i);
+  }
+
+  mSortPtr = CodeParm;
+  do {
+    i = mHeap[1];
+    if (i < mN) {
+      *mSortPtr++ = (UINT16) i;
+    }
+
+    mHeap[1] = mHeap[mHeapSize--];
+    DownHeap (1);
+    j = mHeap[1];
+    if (j < mN) {
+      *mSortPtr++ = (UINT16) j;
+    }
+
+    k         = Avail++;
+    mFreq[k]  = (UINT16) (mFreq[i] + mFreq[j]);
+    mHeap[1]  = (INT16) k;
+    DownHeap (1);
+    mLeft[k]  = (UINT16) i;
+    mRight[k] = (UINT16) j;
+  } while (mHeapSize > 1);
+
+  mSortPtr = CodeParm;
+  MakeLen (k);
+  MakeCode (NParm, LenParm, CodeParm);
+
+  //
+  // return root
+  //
+  return k;
+}
diff --git a/EfiCompress/compress.inf b/EfiCompress/compress.inf
new file mode 100644 (file)
index 0000000..97d1d35
--- /dev/null
@@ -0,0 +1,74 @@
+#/*++
+#
+# Copyright 2005, Intel Corporation                                                         
+# All rights reserved. This program and the accompanying materials                          
+# are licensed and made available under the terms and conditions of the BSD License         
+# which accompanies this distribution. The full text of the license may be found at         
+# http://opensource.org/licenses/bsd-license.php                                            
+#                                                                                           
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+# 
+#  Module Name:
+#
+#    compress.inf
+#
+#  Abstract: 
+#
+#    Component description file for EFI Shell module.
+#
+#--*/
+
+[defines]
+BASE_NAME            = eficompress
+FILE_GUID            = A6A236DB-F3FB-4f7f-93BC-0AF7DAA583B9
+COMPONENT_TYPE       = APPLICATION
+
+[sources.common]
+..\ShCommonStrings.uni
+CompressStrings.uni
+compressMain.c
+compress.c
+compress.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
+
+
+[--]
+
+#
+# To enable building shell commands standalone or built into the shell,
+# we will specify some additional DEFINEs on the compile command line.
+#
+[nmake.common]
+  C_PROJ_FLAGS = $(C_PROJ_FLAGS) /Zm500
+  IMAGE_ENTRY_POINT=InitializeCompress
+  C_STD_FLAGS = $(C_STD_FLAGS) /DSTRING_ARRAY_NAME=$(BASE_NAME)Strings 
+  C_STD_FLAGS = $(C_STD_FLAGS) /DSTRING_DEFINES_FILE=\"$(BASE_NAME)StrDefs.h\"
+  C_STD_FLAGS = $(C_STD_FLAGS) /DEFI_BOOTSHELL
+
+
\ No newline at end of file
diff --git a/EfiDecompress/Decompress.c b/EfiDecompress/Decompress.c
new file mode 100644 (file)
index 0000000..9fdb40f
--- /dev/null
@@ -0,0 +1,504 @@
+/*++
+
+Copyright 2005, Intel Corporation                                                         
+All rights reserved. This program and the accompanying materials                          
+are licensed and made available under the terms and conditions of the BSD License         
+which accompanies this distribution. The full text of the license may be found at         
+http://opensource.org/licenses/bsd-license.php                                            
+                                                                                          
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+
+Module Name:
+
+  decompress.c
+  
+Abstract:
+
+  EFI shell command "EfiDecompress" - decompress a file
+
+Revision History
+
+--*/
+
+#include "EfiShellLib.h"
+#include "decompress.h"
+
+extern UINT8    STRING_ARRAY_NAME[];
+
+//
+// This is the generated header file which includes whatever needs to be exported (strings + IFR)
+//
+#include STRING_DEFINES_FILE
+
+#include EFI_PROTOCOL_DEFINITION (TianoDecompress)
+#include EFI_PROTOCOL_DEFINITION (decompress)
+
+EFI_HII_HANDLE  HiiDecompressHandle;
+EFI_GUID        EfiDecompressGuid = EFI_DECOMPRESS_GUID;
+SHELL_VAR_CHECK_ITEM    DecompressCheckList[] = {
+  {
+    L"-b",
+    0x1,
+    0,
+    FlagTypeSingle
+  },
+  {
+    L"-?",
+    0x2,
+    0,
+    FlagTypeSingle
+  },
+  {
+    NULL,
+    0,
+    0,
+    0
+  }
+};
+
+//
+// Function declarations
+//
+EFI_STATUS
+InitializeDecompress (
+  IN EFI_HANDLE           ImageHandle,
+  IN EFI_SYSTEM_TABLE     *SystemTable
+  );
+
+//
+// Entry Point
+//
+EFI_BOOTSHELL_CODE(
+  EFI_APPLICATION_ENTRY_POINT(InitializeDecompress)
+)
+
+EFI_STATUS
+InitializeDecompress (
+  IN EFI_HANDLE           ImageHandle,
+  IN EFI_SYSTEM_TABLE     *SystemTable
+  )
+/*++
+
+Routine Description:
+  Command entry point. Decompress the contents of a file.
+
+Arguments:
+  ImageHandle     The image handle. 
+  SystemTable     The system table.
+
+Returns:
+  EFI_SUCCESS             - The command completed successfully
+  EFI_INVALID_PARAMETER   - Command usage error
+  EFI_OUT_OF_RESOURCES    - Out of memory
+  EFI_UNSUPPORTED         - Protocols unsupported
+  Other value             - Unknown error
+   
+--*/
+{
+  EFI_LIST_ENTRY          File1List;
+  EFI_LIST_ENTRY          File2List;
+  SHELL_FILE_ARG          *File1Arg;
+  SHELL_FILE_ARG          *File2Arg;
+  EFI_FILE_HANDLE         File2Handle;
+  UINTN                   SourceSize;
+  UINTN                   DestinationSize;
+  UINTN                   ScratchSize;
+  UINT8                   *File1Buffer;
+  UINT8                   *File2Buffer;
+  UINT8                   *Scratch;
+  EFI_STATUS              Status;
+  EFI_DECOMPRESS_PROTOCOL *Decompress;
+  SHELL_VAR_CHECK_CODE    RetCode;
+  CHAR16                  *Useful;
+  SHELL_ARG_LIST          *Item;
+  BOOLEAN                 DstFileExist;
+  SHELL_VAR_CHECK_PACKAGE ChkPck;
+  
+  //
+  // Local variable initializations
+  //
+  DstFileExist  = FALSE;
+  File1Buffer   = NULL;
+  File2Buffer   = NULL;
+  Scratch       = NULL;
+  InitializeListHead (&File1List);
+  InitializeListHead (&File2List);
+  ZeroMem (&ChkPck, sizeof (SHELL_VAR_CHECK_PACKAGE));
+  //
+  // We are not being installed as an internal command driver, initialize
+  // as an nshell app and run
+  //
+  EFI_SHELL_APP_INIT (ImageHandle, SystemTable);
+  //
+  // Register our string package with HII and return the handle to it.
+  // If previously registered we will simply receive the handle
+  //
+  EFI_SHELL_STR_INIT (HiiDecompressHandle, STRING_ARRAY_NAME, EfiDecompressGuid);
+
+  if (!EFI_PROPER_VERSION (0, 99)) {
+    PrintToken (
+      STRING_TOKEN (STR_SHELLENV_GNC_COMMAND_NOT_SUPPORT),
+      HiiDecompressHandle,
+      L"efidecompress",
+      EFI_VERSION_0_99 
+      );
+    Status = EFI_UNSUPPORTED;
+    goto Quit;
+  }
+
+  LibFilterNullArgs ();
+  //
+  // Parse command line arguments
+  //
+  RetCode = LibCheckVariables (SI, DecompressCheckList, &ChkPck, &Useful);
+  if (VarCheckOk != RetCode) {
+    switch (RetCode) {
+    case VarCheckUnknown:
+      PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_UNKNOWN_FLAG), HiiDecompressHandle, L"efidecompress", Useful);
+      break;
+
+    default:
+      break;
+    }
+
+    Status = EFI_INVALID_PARAMETER;
+    goto Quit;
+  }
+
+  if (LibCheckVarGetFlag (&ChkPck, L"-b")) {
+    EnablePageBreak (DEFAULT_INIT_ROW, DEFAULT_AUTO_LF);
+  }
+
+  if (LibCheckVarGetFlag (&ChkPck, L"-?")) {
+    if (ChkPck.ValueCount > 0 ||
+        ChkPck.FlagCount > 2 ||
+        (2 == ChkPck.FlagCount && !LibCheckVarGetFlag (&ChkPck, L"-b"))
+        ) {
+      PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_TOO_MANY), HiiDecompressHandle, L"efidecompress");
+      Status = EFI_INVALID_PARAMETER;
+    } else {
+      PrintToken (STRING_TOKEN (STR_EFIDECOMPRESS_VERBOSEHELP), HiiDecompressHandle);
+      Status = EFI_SUCCESS;
+    }
+
+    goto Quit;
+  }
+  //
+  //
+  //
+  Status = LibLocateProtocol (&gEfiTianoDecompressProtocolGuid, &Decompress);
+  if (EFI_ERROR (Status)) {
+    PrintToken (STRING_TOKEN (STR_DECOMPRESS_PROTOCOL_NOT_FOUND), HiiDecompressHandle, L"efidecompress");
+    Status = EFI_UNSUPPORTED;
+    goto Quit;
+  }
+  //
+  // verify number of arguments
+  //
+  if (ChkPck.ValueCount > 2) {
+    PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_TOO_MANY), HiiDecompressHandle, L"efidecompress");
+    Status = EFI_INVALID_PARAMETER;
+    goto Quit;
+  }
+
+  if (ChkPck.ValueCount < 2) {
+    PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_TOO_FEW), HiiDecompressHandle, L"efidecompress");
+    Status = EFI_INVALID_PARAMETER;
+    goto Quit;
+  }
+  //
+  // validate first file
+  //
+  Item    = GetFirstArg (&ChkPck);
+  Status  = ShellFileMetaArg (Item->VarStr, &File1List);
+  if (EFI_ERROR (Status)) {
+    PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_CANNOT_OPEN_FILE), HiiDecompressHandle, L"efidecompress", Item->VarStr);
+    goto Done;
+  }
+  //
+  // empty list
+  //
+  if (IsListEmpty (&File1List)) {
+    Status = EFI_NOT_FOUND;
+    PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_CANNOT_OPEN_FILE), HiiDecompressHandle, L"efidecompress", Item->VarStr);
+    goto Done;
+  }
+  //
+  // multiple files
+  //
+  if (File1List.Flink->Flink != &File1List) {
+    PrintToken (STRING_TOKEN (STR_DECOMPRESS_FIRST_MULT_FILES), HiiDecompressHandle, L"efidecompress");
+    Status = EFI_INVALID_PARAMETER;
+    goto Done;
+  }
+
+  File1Arg = CR (File1List.Flink, SHELL_FILE_ARG, Link, SHELL_FILE_ARG_SIGNATURE);
+
+  //
+  // Open error
+  //
+  if (EFI_ERROR (File1Arg->Status) || !File1Arg->Handle) {
+    PrintToken (
+      STRING_TOKEN (STR_SHELLENV_GNC_CANNOT_OPEN_FILE),
+      HiiDecompressHandle,
+      L"efidecompress",
+      File1Arg->FullName
+      );
+    Status = File1Arg->Status;
+    goto Done;
+  }
+  //
+  // directory
+  //
+  if (File1Arg->Info && (File1Arg->Info->Attribute & EFI_FILE_DIRECTORY)) {
+    PrintToken (STRING_TOKEN (STR_DECOMPRESS_FIRST_ARG_DIR), HiiDecompressHandle, L"efidecompress");
+    Status = EFI_INVALID_PARAMETER;
+    goto Done;
+  }
+  //
+  // Validate second file
+  //
+  Item    = GetNextArg (Item);
+  Status  = ShellFileMetaArg (Item->VarStr, &File2List);
+  if (EFI_ERROR (Status)) {
+    PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_CANNOT_OPEN_FILE), HiiDecompressHandle, L"efidecompress", Item->VarStr);
+    goto Done;
+  }
+  //
+  // empty list
+  //
+  if (IsListEmpty (&File2List)) {
+    Status = EFI_NOT_FOUND;
+    PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_CANNOT_OPEN_FILE), HiiDecompressHandle, L"efidecompress", Item->VarStr);
+    goto Done;
+  }
+  //
+  // multiple files
+  //
+  if (File2List.Flink->Flink != &File2List) {
+    PrintToken (STRING_TOKEN (STR_DECOMPRESS_SECOND_MULT_FILES), HiiDecompressHandle, L"efidecompress");
+    Status = EFI_INVALID_PARAMETER;
+    goto Done;
+  }
+
+  File2Arg = CR (
+              File2List.Flink,
+              SHELL_FILE_ARG,
+              Link,
+              SHELL_FILE_ARG_SIGNATURE
+              );
+
+  if (!File2Arg->Parent) {
+    PrintToken (
+      STRING_TOKEN (STR_SHELLENV_GNC_CANNOT_OPEN_FILE),
+      HiiDecompressHandle,
+      L"efidecompress",
+      File2Arg->FullName
+      );
+    Status = File2Arg->Status;
+    goto Done;
+  }
+  //
+  // directory
+  //
+  if (File2Arg->Info && (File2Arg->Info->Attribute & EFI_FILE_DIRECTORY)) {
+    PrintToken (STRING_TOKEN (STR_DECOMPRESS_SECOND_DIR), HiiDecompressHandle, L"efidecompress");
+    Status = EFI_INVALID_PARAMETER;
+    goto Done;
+  }
+  //
+  // Allocate buffers for both files
+  //
+  SourceSize  = (UINTN) File1Arg->Info->FileSize;
+  File1Buffer = AllocatePool (SourceSize);
+  if (File1Buffer == NULL) {
+    PrintToken (STRING_TOKEN (STR_DECOMPRESS_OUT_OF_MEM), HiiDecompressHandle, L"efidecompress");
+    Status = EFI_OUT_OF_RESOURCES;
+    goto Done;
+  }
+
+  Status = File1Arg->Handle->Read (File1Arg->Handle, &SourceSize, File1Buffer);
+  if (EFI_ERROR (Status)) {
+    PrintToken (
+      STRING_TOKEN (STR_DECOMPRESS_READ_ERROR),
+      HiiDecompressHandle,
+      L"efidecompress",
+      File1Arg->FullName,
+      Status
+      );
+    goto Done;
+  }
+
+  DestinationSize = 0;
+  ScratchSize     = 0;
+  Status = Decompress->GetInfo (
+                        Decompress,
+                        File1Buffer,
+                        (UINT32) SourceSize,
+                        (UINT32 *) &DestinationSize,
+                        (UINT32 *) &ScratchSize
+                        );
+  if (EFI_ERROR (Status)) {
+    PrintToken (
+      STRING_TOKEN (STR_DECOMPRESS_COMPRESSED_DAMAGED),
+      HiiDecompressHandle,
+      L"eficompress",
+      File1Arg->FullName,
+      Status
+      );
+    goto Done;
+  }
+
+  File2Buffer = AllocatePool (DestinationSize);
+  if (File2Buffer == NULL) {
+    PrintToken (STRING_TOKEN (STR_DECOMPRESS_OUT_OF_MEM), HiiDecompressHandle, L"efidecompress");
+    Status = EFI_OUT_OF_RESOURCES;
+    goto Done;
+  }
+
+  Scratch = AllocatePool (ScratchSize);
+  if (Scratch == NULL) {
+    PrintToken (STRING_TOKEN (STR_DECOMPRESS_OUT_OF_MEM), HiiDecompressHandle, L"efidecompress");
+    Status = EFI_OUT_OF_RESOURCES;
+    goto Done;
+  }
+
+  Status = Decompress->Decompress (
+                        Decompress,
+                        File1Buffer,
+                        (UINT32) SourceSize,
+                        File2Buffer,
+                        (UINT32) DestinationSize,
+                        Scratch,
+                        (UINT32) ScratchSize
+                        );
+  if (EFI_ERROR (Status)) {
+    PrintToken (
+      STRING_TOKEN (STR_DECOMPRESS_ERROR),
+      HiiDecompressHandle,
+      L"efidecompress",
+      File1Arg->FullName,
+      Status
+      );
+    goto Done;
+  }
+
+  if (File2Arg->Status == EFI_SUCCESS &&
+      File2Arg->OpenMode & EFI_FILE_MODE_READ &&
+      File2Arg->OpenMode & EFI_FILE_MODE_WRITE
+      ) {
+    File2Handle               = File2Arg->Handle;
+    File2Arg->Info->FileSize  = 0;
+    Status = File2Handle->SetInfo (
+                            File2Handle,
+                            &gEfiFileInfoGuid,
+                            (UINTN) File2Arg->Info->Size,
+                            File2Arg->Info
+                            );
+    Status = File2Handle->Write (File2Handle, &DestinationSize, File2Buffer);
+    if (EFI_ERROR (Status)) {
+      PrintToken (
+        STRING_TOKEN (STR_DECOMPRESS_WRITE_ERROR),
+        HiiDecompressHandle,
+        L"efidecompress",
+        File2Arg->FullName,
+        Status
+        );
+      goto Done;
+    }
+
+    DstFileExist = TRUE;
+  } else {
+    Status = File2Arg->Parent->Open (
+                                File2Arg->Parent,
+                                &File2Handle,
+                                File2Arg->FileName,
+                                EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE,
+                                0
+                                );
+    if (EFI_ERROR (Status)) {
+      PrintToken (
+        STRING_TOKEN (STR_DECOMPRESS_CREATE_ERROR),
+        HiiDecompressHandle,
+        L"efidecompress",
+        File2Arg->FullName,
+        Status
+        );
+      goto Done;
+    }
+
+    Status = File2Handle->Write (File2Handle, &DestinationSize, File2Buffer);
+    if (EFI_ERROR (Status)) {
+      PrintToken (
+        STRING_TOKEN (STR_DECOMPRESS_WRITE_ERROR),
+        HiiDecompressHandle,
+        L"efidecompress",
+        File2Arg->FullName,
+        Status
+        );
+      File2Handle->Close (File2Handle);
+      goto Done;
+    }
+  }
+
+  if (!DstFileExist) {
+    File2Handle->Close (File2Handle);
+  }
+
+  ASSERT (!EFI_ERROR (Status));
+  PrintToken (
+    STRING_TOKEN (STR_DECOMPRESS_SUCCESS),
+    HiiDecompressHandle,
+    L"efidecompress",
+    File1Arg->FullName,
+    File2Arg->FullName
+    );
+
+Done:
+  if (File1Buffer) {
+    FreePool (File1Buffer);
+  }
+
+  if (File2Buffer) {
+    FreePool (File2Buffer);
+  }
+
+  if (Scratch) {
+    FreePool (Scratch);
+  }
+
+  ShellFreeFileList (&File1List);
+  ShellFreeFileList (&File2List);
+
+Quit:
+  //
+  // Shell command always succeeds
+  //
+  LibUnInitializeStrings ();
+  LibCheckVarFreeVarList (&ChkPck);
+  return Status;
+}
+
+EFI_STATUS
+InitializeDecompressGetLineHelp (
+  OUT CHAR16                  **Str
+  )
+/*++
+
+Routine Description:
+
+  Get this command's line help
+
+Arguments:
+
+  Str - The line help
+
+Returns:
+
+  EFI_SUCCESS   - Success
+
+--*/
+{
+  return LibCmdGetStringByToken (STRING_ARRAY_NAME, &EfiDecompressGuid, STRING_TOKEN (STR_EFIDECOMPRESS_LINEHELP), Str);
+}
diff --git a/EfiDecompress/Decompress.h b/EfiDecompress/Decompress.h
new file mode 100644 (file)
index 0000000..3a85b6b
--- /dev/null
@@ -0,0 +1,32 @@
+/*++
+
+Copyright 2005, Intel Corporation                                                         
+All rights reserved. This program and the accompanying materials                          
+are licensed and made available under the terms and conditions of the BSD License         
+which accompanies this distribution. The full text of the license may be found at         
+http://opensource.org/licenses/bsd-license.php                                            
+                                                                                          
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+
+Module Name:
+
+  Decompress.h
+
+Abstract:
+
+  declares interface functions
+
+Revision History
+
+--*/
+
+#ifndef _EFI_SHELL_DECOMPRESS_H_
+#define _EFI_SHELL_DECOMPRESS_H_
+
+#define EFI_DECOMPRESS_GUID \
+  { \
+    0xe15963a9, 0xa05a, 0x480e, 0x91, 0x49, 0x32, 0xe9, 0x24, 0x5d, 0x98, 0xcb \
+  }
+
+#endif
\ No newline at end of file
diff --git a/EfiDecompress/Decompress.inf b/EfiDecompress/Decompress.inf
new file mode 100644 (file)
index 0000000..5a6ae66
--- /dev/null
@@ -0,0 +1,73 @@
+#/*++
+#
+# Copyright 2005, Intel Corporation                                                         
+# All rights reserved. This program and the accompanying materials                          
+# are licensed and made available under the terms and conditions of the BSD License         
+# which accompanies this distribution. The full text of the license may be found at         
+# http://opensource.org/licenses/bsd-license.php                                            
+#                                                                                           
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+# 
+#  Module Name:
+#
+#    decompress.inf
+#
+#  Abstract: 
+#
+#    Component description file for EFI Shell module.
+#
+#--*/
+
+[defines]
+BASE_NAME            = efidecompress
+FILE_GUID            = D9D42564-071C-4d73-8DB0-43C55C62DC4C
+COMPONENT_TYPE       = APPLICATION
+
+[sources.common]
+..\ShCommonStrings.uni
+DecompressStrings.uni
+decompress.c
+decompress.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
+
+
+[--]
+
+#
+# To enable building shell commands standalone or built into the shell,
+# we will specify some additional DEFINEs on the compile command line.
+#
+[nmake.common]
+  C_PROJ_FLAGS = $(C_PROJ_FLAGS) /Zm500
+  IMAGE_ENTRY_POINT=InitializeDecompress
+  C_STD_FLAGS = $(C_STD_FLAGS) /DSTRING_ARRAY_NAME=$(BASE_NAME)Strings 
+  C_STD_FLAGS = $(C_STD_FLAGS) /DSTRING_DEFINES_FILE=\"$(BASE_NAME)StrDefs.h\"
+  C_STD_FLAGS = $(C_STD_FLAGS) /DEFI_BOOTSHELL
+
+
diff --git a/EfiDecompress/DecompressStrings.uni b/EfiDecompress/DecompressStrings.uni
new file mode 100644 (file)
index 0000000..0efb7c8
Binary files /dev/null and b/EfiDecompress/DecompressStrings.uni differ
diff --git a/IpConfig/IpConfig.c b/IpConfig/IpConfig.c
new file mode 100644 (file)
index 0000000..43bdfd1
--- /dev/null
@@ -0,0 +1,879 @@
+/*++
+
+Copyright 2005, Intel Corporation                                                         
+All rights reserved. This program and the accompanying materials                          
+are licensed and made available under the terms and conditions of the BSD License         
+which accompanies this distribution. The full text of the license may be found at         
+http://opensource.org/licenses/bsd-license.php                                            
+                                                                                          
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+
+Module Name:
+
+  IpConfig.c
+  
+Abstract:
+
+  Shell command "IpConfig"
+
+
+Revision History
+
+--*/
+
+#include "EfiShellLib.h"
+#include "IpConfig.h"
+
+extern UINT8  STRING_ARRAY_NAME[];
+
+//
+// This is the generated header file which includes whatever needs to be exported (strings + IFR)
+//
+#include STRING_DEFINES_FILE
+
+#include EFI_PROTOCOL_DEFINITION (PxeBaseCode)
+#include EFI_PROTOCOL_DEFINITION (SimpleNetwork)
+#include EFI_PROTOCOL_DEFINITION (PxeDhcp4)
+
+//
+// Global Variables
+//
+EFI_HII_HANDLE  HiiHandle;
+EFI_GUID        EfiIpConfigGuid = EFI_IPCONFIG_GUID;
+SHELL_VAR_CHECK_ITEM  IpconfigCheckList[] = {
+  {
+    L"-r",
+    0x01,
+    0x16,
+    FlagTypeSingle
+  },
+  {
+    L"-m",
+    0x02,
+    0x11,
+    FlagTypeNeedVar
+  },
+  {
+    L"-c",
+    0x04,
+    0x11,
+    FlagTypeNeedVar
+  },
+  {
+    L"-b",
+    0x08,
+    0,
+    FlagTypeSingle
+  },
+  {
+    L"-?",
+    0x10,
+    0x07,
+    FlagTypeSingle
+  },
+  {
+    NULL,
+    0,
+    0,
+    0
+  }
+};
+
+//
+// MACRO
+//
+#define IPV4_MAC_ADDRESS_LEN  6
+#define EFI_IP_V4_BYTES       4
+#define IP_STRING_MAX_LENGTH  32
+
+EFI_STATUS
+InitializeIpConfig (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  );
+
+EFI_STATUS
+EfiInetAddr (
+  IN  CHAR16            *Ptr,
+  OUT EFI_IP_ADDRESS    *Ip
+  );
+
+EFI_STATUS
+EfiRestartPxeBaseCode (
+  EFI_PXE_BASE_CODE_PROTOCOL   *PxeBaseCode,
+  EFI_PXE_DHCP4_PROTOCOL       *PxeDhcp4
+  );
+
+DHCP4_OP *
+FindDhcp4OptionInBuffer (
+  UINT8 Op,
+  UINTN *SkipPtr,
+  UINT8 *Buffer,
+  UINTN BufferLen
+  )
+/*++
+
+Routine Description:
+
+  Find the Dhcp4 option in the buffer
+
+Arguments:
+
+  Op           - The option
+  SkipPtr      - Skip number
+  Buffer       - The buffer
+  BufferLen    - Buffer length
+
+Returns:
+
+  The DHCP4 option.
+
+--*/
+{
+  UINTN TmpSkip;
+
+  //
+  // A couple of stupidity checks.
+  //
+  if (Buffer == NULL || BufferLen < 4) {
+    return NULL;
+  }
+  //
+  // Assume a skip value of zero if a NULL skip pointer was passed in.
+  //
+  if (SkipPtr == NULL) {
+    SkipPtr = &TmpSkip;
+    TmpSkip = 0;
+  }
+  //
+  //
+  //
+  for (;;) {
+    //
+    // If this is what we are looking for, return a pointer to the option
+    // if the skip counter is zero.
+    //
+    if (*Buffer == Op) {
+      if (*SkipPtr-- == 0) {
+        return (DHCP4_OP *) Buffer;
+      }
+    }
+    //
+    // Special checks for PAD and END options.
+    //
+    switch (*Buffer) {
+    case DHCP4_END:
+      //
+      // Return not found when END is reached.
+      //
+      return NULL;
+
+    case DHCP4_PAD:
+      //
+      // PAD options are always one byte in length.
+      //
+      ++Buffer;
+
+      if (--BufferLen == 0) {
+        return NULL;
+      }
+
+      continue;
+    }
+    //
+    // Return not found if there is not enough space left for more options.
+    //
+    if (BufferLen == 1) {
+      return NULL;
+    }
+
+    if ((UINTN) (Buffer[1] + 2) >= BufferLen) {
+      return NULL;
+    }
+    //
+    // Skip past current option.
+    //
+    Buffer += 2 + Buffer[1];
+  }
+}
+
+DHCP4_OP *
+FindDhcp4Option (
+  UINT8         Op,
+  UINTN         Skip,
+  DHCP4_PACKET  *Packet
+  )
+/*++
+
+Routine Description:
+
+  Find the Dhcp4 option in the buffer
+
+Arguments:
+
+  Op           - The option
+  Skip         - Skip number
+  Packet       - The Dhcp4 packet
+
+Returns:
+
+  The DHCP4 option.
+
+--*/
+{
+  DHCP4_OP  *MaxMessageSizePtr;
+  DHCP4_OP  *OptionOverloadPtr;
+  DHCP4_OP  *OpPtr;
+  UINTN     OptionLen;
+
+  //
+  // Do nothing if Packet pointer is NULL.
+  //
+  if (Packet == NULL) {
+    return NULL;
+  }
+  //
+  // Only the first DHCP4_END can be found.
+  //
+  if (Op == DHCP4_END && Skip != 0) {
+    return NULL;
+  }
+  //
+  // Determine maximum length of options[] field.
+  //
+  OptionLen = sizeof Packet->dhcp4.options;
+
+  MaxMessageSizePtr = FindDhcp4OptionInBuffer (
+                        DHCP4_MAX_MESSAGE_SIZE,
+                        NULL,
+                        Packet->dhcp4.options,
+                        OptionLen
+                        );
+
+  if (MaxMessageSizePtr != NULL) {
+    //
+    // If the option length is not valid (2), return not found.
+    //
+    if (MaxMessageSizePtr->len != 2) {
+      return NULL;
+    }
+
+    OptionLen = (MaxMessageSizePtr->data[0] << 8) | MaxMessageSizePtr->data[1];
+
+    //
+    // If the maximum message length is less than the minimum DHCP4 packet length,
+    // return not found.
+    //
+    if (OptionLen < 300) {
+      return NULL;
+    }
+    //
+    // Set the new options[] field length by subtracting out the fixed portion of
+    // the packet header.
+    //
+    OptionLen -= (UINT8 *) Packet->dhcp4.options - (UINT8 *) Packet;
+  }
+  //
+  // Determine if the sname[] and fname[] fields are overloaded.
+  //
+  OptionOverloadPtr = FindDhcp4OptionInBuffer (
+                        DHCP4_OPTION_OVERLOAD,
+                        NULL,
+                        Packet->dhcp4.options,
+                        OptionLen
+                        );
+
+  if (OptionOverloadPtr->len != 1 || (OptionOverloadPtr->data[0] & 3) == 0) {
+    //
+    // Ignore sname[] and fname[] fields if the overload option is not valid.
+    //
+    OptionOverloadPtr = NULL;
+  }
+  //
+  // Now, look for the caller's option.
+  //
+  OpPtr = FindDhcp4OptionInBuffer (
+            Op,
+            &Skip,
+            Packet->dhcp4.options,
+            OptionLen
+            );
+
+  if (OpPtr != NULL || Skip == 0 || OptionOverloadPtr == NULL) {
+    return OpPtr;
+  }
+
+  if (OptionOverloadPtr->data[0] & DHCP4_OVERLOAD_FNAME) {
+    OpPtr = FindDhcp4OptionInBuffer (
+              Op,
+              &Skip,
+              Packet->dhcp4.fname,
+              sizeof Packet->dhcp4.fname
+              );
+
+    if (OpPtr != NULL || Skip == 0) {
+      return OpPtr;
+    }
+  }
+
+  if (OptionOverloadPtr->data[0] & DHCP4_OVERLOAD_SNAME) {
+    OpPtr = FindDhcp4OptionInBuffer (
+              Op,
+              &Skip,
+              Packet->dhcp4.sname,
+              sizeof Packet->dhcp4.sname
+              );
+  }
+
+  return OpPtr;
+}
+
+EFI_BOOTSHELL_CODE(
+  EFI_APPLICATION_ENTRY_POINT(InitializeIpConfig)
+)
+
+EFI_STATUS
+InitializeIpConfig (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+/*++
+Routine Description:
+
+  Command entry point. 
+
+Arguments:
+
+  ImageHandle     The image handle. 
+  SystemTable     The system table.
+
+Returns:
+
+  EFI_SUCCESS      - The command completed successfully
+  EFI_NOT_STARTED  - PXE bc DHCP has not started yet
+  EFI_NOT_FOUND    - Depending protocol not found
+  EFI_ABORTED      - Set IP address error
+
+--*/
+{
+  EFI_STATUS                  Status;
+  EFI_IP_ADDRESS              IpAddress;
+  EFI_IP_ADDRESS              IpMask;
+  BOOLEAN                     NewIp;
+  BOOLEAN                     NewMsk;
+  EFI_SIMPLE_NETWORK_PROTOCOL *SimpleNetwork;
+  EFI_PXE_BASE_CODE_PROTOCOL  *PxeBaseCode;
+  EFI_PXE_DHCP4_PROTOCOL      *PxeDhcp4;
+  UINTN                       Index;
+  UINT8                       *Ptr;
+  UINTN                       Instance;
+  UINTN                       Count;
+  UINTN                       Bits;
+  UINT32                      Mask;
+  BOOLEAN                     TurnFlag;
+  EFI_HANDLE                  *HandleBuffer;
+  CHAR16                      *Useful;
+  SHELL_ARG_LIST              *Item;
+  SHELL_VAR_CHECK_CODE        RetCode;
+  SHELL_VAR_CHECK_PACKAGE     ChkPck;
+
+  TurnFlag  = FALSE;
+  //
+  // We are no being installed as an internal command driver, initialize
+  // as an nshell app and run
+  //
+  EFI_SHELL_APP_INIT (ImageHandle, SystemTable);
+  //
+  // Register our string package with HII and return the handle to it.
+  // If previously registered we will simply receive the handle
+  //
+  Status = LibInitializeStrings (&HiiHandle, STRING_ARRAY_NAME, &EfiIpConfigGuid);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  if (!EFI_PROPER_VERSION (0, 99)) {
+    PrintToken (
+      STRING_TOKEN (STR_SHELLENV_GNC_COMMAND_NOT_SUPPORT),
+      HiiHandle,
+      L"ipconfig",
+      EFI_VERSION_0_99 
+      );
+    Status = EFI_UNSUPPORTED;
+    goto Done;
+  }
+
+  NewIp   = FALSE;
+  NewMsk  = FALSE;
+  ZeroMem (&ChkPck, sizeof (SHELL_VAR_CHECK_PACKAGE));
+  ZeroMem (&IpAddress, sizeof (EFI_IP_ADDRESS));
+  ZeroMem (&IpMask, sizeof (EFI_IP_ADDRESS));
+
+  LibFilterNullArgs ();
+  RetCode = LibCheckVariables (SI, IpconfigCheckList, &ChkPck, &Useful);
+  if (VarCheckOk != RetCode) {
+    switch (RetCode) {
+    case VarCheckConflict:
+      PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_FLAG_CONFLICT), HiiHandle, L"ipconfig", Useful);
+      break;
+
+    case VarCheckDuplicate:
+      PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_DUP_FLAG), HiiHandle, L"ipconfig", Useful);
+      break;
+
+    case VarCheckLackValue:
+      PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_LACK_ARG), HiiHandle, L"ipconfig", Useful);
+      break;
+
+    case VarCheckUnknown:
+      PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_UNKNOWN_FLAG), HiiHandle, L"ipconfig", Useful);
+      break;
+
+    default:
+      break;
+    }
+
+    Status = EFI_INVALID_PARAMETER;
+    goto Done;
+  }
+
+  if (LibCheckVarGetFlag (&ChkPck, L"-b")) {
+    EnablePageBreak (DEFAULT_INIT_ROW, DEFAULT_AUTO_LF);
+  }
+
+  if (LibCheckVarGetFlag (&ChkPck, L"-?")) {
+    if (ChkPck.ValueCount > 0 ||
+        ChkPck.FlagCount > 2 ||
+        (2 == ChkPck.FlagCount && !LibCheckVarGetFlag (&ChkPck, L"-b"))
+        ) {
+      PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_TOO_MANY), HiiHandle, L"ipconfig");
+      Status = EFI_INVALID_PARAMETER;
+    } else {
+      PrintToken (STRING_TOKEN (STR_IPCONFIG_VERBOSEHELP), HiiHandle);
+      Status = EFI_SUCCESS;
+    }
+
+    goto Done;
+  }
+
+  if (ChkPck.ValueCount > 1) {
+    PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_TOO_MANY), HiiHandle, L"ipconfig");
+    Status = EFI_INVALID_PARAMETER;
+    goto Done;
+  }
+  //
+  // Validate arguments
+  //
+  if (!LibCheckVarGetFlag (&ChkPck, L"-r")) {
+    Item = GetFirstArg (&ChkPck);
+    if (Item) {
+      Status = EfiInetAddr (Item->VarStr, &IpAddress);
+      if (EFI_ERROR (Status)) {
+        PrintToken (STRING_TOKEN (STR_IPCONFIG_INVALID_ARG), HiiHandle, Item->VarStr);
+        goto Done;
+      }
+
+      NewIp = TRUE;
+    }
+
+    Item = LibCheckVarGetFlag (&ChkPck, L"-m");
+    if (Item) {
+      Status = EfiInetAddr (Item->VarStr, &IpMask);
+      if (EFI_ERROR (Status)) {
+        PrintToken (STRING_TOKEN (STR_IPCONFIG_INVALID_ARG), HiiHandle, Item->VarStr);
+        goto Done;
+      }
+
+      Mask = 0;
+      for (Index = 0; Index < 4; Index++) {
+        Mask |= (IpMask.v4.Addr[3 - Index] << (Index * 8));
+      }
+
+      for (Bits = 0; Bits < 32; Bits++) {
+        if (!TurnFlag && (Mask & (1 << Bits))) {
+          TurnFlag = TRUE;
+        }
+
+        if (TurnFlag && !(Mask & (1 << Bits))) {
+          PrintToken (STRING_TOKEN (STR_IPCONFIG_INVALID_ARG), HiiHandle, Item->VarStr);
+          Status = EFI_INVALID_PARAMETER;
+          goto Done;
+        }
+      }
+
+      NewMsk = TRUE;
+    }
+  }
+
+  Instance  = 0;
+  Item      = LibCheckVarGetFlag (&ChkPck, L"-c");
+  if (Item) {
+    Instance = (UINTN) StrToUInteger (Item->VarStr, &Status);
+    if (EFI_ERROR (Status)) {
+      PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_INVALID_ARG), HiiHandle, L"ipconfig", Item->VarStr);
+      Status = EFI_INVALID_PARAMETER;
+      goto Done;
+    }
+  }
+  //
+  // Get MAC address from simple network protocol
+  //
+  Status = LibLocateHandle (
+            ByProtocol,
+            &gEfiSimpleNetworkProtocolGuid,
+            NULL,
+            &Count,
+            &HandleBuffer
+            );
+
+  if (EFI_ERROR (Status) || (Count == 0)) {
+    PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_LOC_PROT_ERR_EX), HiiHandle, L"ipconfig", L"Simple network protocol");
+    Status = EFI_NOT_FOUND;
+    goto Done;
+  }
+
+  if (Instance >= Count) {
+    PrintToken (STRING_TOKEN (STR_IPCONFIG_INS_NOT_SUPPORT), HiiHandle, Instance);
+    Status = EFI_NOT_AVAILABLE_YET;
+    FreePool (HandleBuffer);
+    goto Done;
+  }
+  //
+  // Get SNP Protocol
+  //
+  Status = BS->HandleProtocol (
+                HandleBuffer[Instance],
+                &gEfiSimpleNetworkProtocolGuid,
+                (VOID **) &SimpleNetwork
+                );
+  if (EFI_ERROR (Status)) {
+    PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_LOC_PROT_ERR_EX), HiiHandle, L"ipconfig", L"Simple network protocol");
+    FreePool (HandleBuffer);
+    goto Done;
+  }
+
+  PrintToken (STRING_TOKEN (STR_IPCONFIG_MAC_ADDRESS), HiiHandle);
+  Ptr = (UINT8 *) (UINTN) &SimpleNetwork->Mode->CurrentAddress.Addr;
+  for (Index = 0; Index < IPV4_MAC_ADDRESS_LEN; Index += 1) {
+    PrintToken (STRING_TOKEN (STR_IPCONFIG_ONE_VAR), HiiHandle, Ptr[Index]);
+  }
+
+  Print (L"\n");
+
+  PrintToken (STRING_TOKEN (STR_IPCONFIG_BROADCAST), HiiHandle);
+  Ptr = (UINT8 *) (UINTN) &SimpleNetwork->Mode->BroadcastAddress.Addr;
+  for (Index = 0; Index < IPV4_MAC_ADDRESS_LEN; Index += 1) {
+    PrintToken (STRING_TOKEN (STR_IPCONFIG_ONE_VAR), HiiHandle, Ptr[Index]);
+  }
+
+  Print (L"\n");
+
+  //
+  // Get Pxe Protocol
+  //
+  Status = BS->HandleProtocol (
+                HandleBuffer[Instance],
+                &gEfiPxeBaseCodeProtocolGuid,
+                (VOID **) &PxeBaseCode
+                );
+  if (EFI_ERROR (Status)) {
+    PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_LOC_PROT_ERR_EX), HiiHandle, L"ipconfig", L"PXE base code protocol");
+    FreePool (HandleBuffer);
+    goto Done;
+  }
+  //
+  // Get DHCP4 protocol
+  //
+  Status = BS->HandleProtocol (
+                HandleBuffer[Instance],
+                &gEfiPxeDhcp4ProtocolGuid,
+                (VOID **) &PxeDhcp4
+                );
+  if (EFI_ERROR (Status)) {
+    PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_LOC_PROT_ERR_EX), HiiHandle, L"ipconfig", L"PXE DHCP4 protocol");
+    FreePool (HandleBuffer);
+    goto Done;;
+  }
+
+  Item = LibCheckVarGetFlag (&ChkPck, L"-r");
+  if (Item) {
+    //
+    // Restart the PXE Base Code DHCP
+    //
+    Status = EfiRestartPxeBaseCode (PxeBaseCode, PxeDhcp4);
+    if (EFI_ERROR (Status)) {
+      FreePool (HandleBuffer);
+      Status = EFI_NOT_STARTED;
+      goto Done;
+    }
+  } else {
+    if (!NewIp) {
+      CopyMem (&IpAddress, &PxeBaseCode->Mode->StationIp, sizeof (EFI_IP_ADDRESS));
+    }
+
+    if (!NewMsk) {
+      CopyMem (&IpMask, &PxeBaseCode->Mode->SubnetMask, sizeof (EFI_IP_ADDRESS));
+    }
+    //
+    // call Pxe base code protocol to set station IP address
+    //
+    Status = PxeBaseCode->SetStationIp (
+                            PxeBaseCode,
+                            &IpAddress,
+                            &IpMask
+                            );
+
+    if (EFI_ERROR (Status)) {
+      PrintToken (STRING_TOKEN (STR_IPCONFIG_SET_IP), HiiHandle, Status);
+      FreePool (HandleBuffer);
+      Status = EFI_ABORTED;
+      goto Done;
+    }
+  }
+
+  PrintToken (
+    STRING_TOKEN (STR_IPCONFIG_IP_ADDRESS),
+    HiiHandle,
+    PxeBaseCode->Mode->StationIp.v4.Addr[0],
+    PxeBaseCode->Mode->StationIp.v4.Addr[1],
+    PxeBaseCode->Mode->StationIp.v4.Addr[2],
+    PxeBaseCode->Mode->StationIp.v4.Addr[3]
+    );
+  PrintToken (
+    STRING_TOKEN (STR_IPCONFIG_IP_MASK),
+    HiiHandle,
+    PxeBaseCode->Mode->SubnetMask.v4.Addr[0],
+    PxeBaseCode->Mode->SubnetMask.v4.Addr[1],
+    PxeBaseCode->Mode->SubnetMask.v4.Addr[2],
+    PxeBaseCode->Mode->SubnetMask.v4.Addr[3]
+    );
+
+  FreePool (HandleBuffer);
+
+Done:
+  LibCheckVarFreeVarList (&ChkPck);
+  LibUnInitializeStrings ();
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EfiInetAddr (
+  IN  CHAR16            *Ptr,
+  OUT EFI_IP_ADDRESS    *Ip
+  )
+/*++
+Routine Description:
+
+  Converts a string containing an (Ipv4) Internet Protocol dotted address into
+  a proper address for the IN_ADDR structure.
+
+Arguments:
+
+  Ptr         -  [in] Null-terminated character string representing a number 
+                 expressed in the Internet standard "." (dotted) notation. 
+  IpAddress   -  The Ip address structure to contain result. 
+
+Returns:
+
+  EFI_SUCCESS           - The command completed successfully
+  EFI_INVALID_PARAMETER - Invalid parameter
+
+--*/
+{
+  UINTN           Index;
+  UINT64          Value;
+  CHAR16          *NumPtr;
+  CHAR16          *BreakPtr;
+  CHAR16          ch;
+  EFI_IP_ADDRESS  IpAddress;
+  EFI_STATUS      Status;
+
+  //
+  // reset to zero first
+  //
+  for (Index = 0; Index < EFI_IP_V4_BYTES; Index += 1) {
+    IpAddress.v4.Addr[Index] = 0;
+  }
+
+  Index     = 0;
+  NumPtr    = Ptr;
+  BreakPtr  = Ptr;
+  for (;;) {
+    while (*BreakPtr && L'.' != *BreakPtr) {
+      if (*BreakPtr < L'0' || *BreakPtr > L'9') {
+        return EFI_INVALID_PARAMETER;
+      }
+
+      BreakPtr++;
+    }
+
+    if (BreakPtr - NumPtr < 1 || BreakPtr - NumPtr > 3) {
+      return EFI_INVALID_PARAMETER;
+    }
+
+    ch        = *BreakPtr;
+    *BreakPtr = 0;
+    Value     = StrToUInteger (NumPtr, &Status);
+    *BreakPtr = ch;
+    if (EFI_ERROR (Status) || Value > 255) {
+      return EFI_INVALID_PARAMETER;
+    }
+
+    IpAddress.v4.Addr[Index] = (UINT8) Value;
+
+    if (Index >= 3 || 0 == *BreakPtr) {
+      break;
+    }
+
+    BreakPtr++;
+    NumPtr = BreakPtr;
+    Index++;
+  }
+
+  if (Index != 3 || *BreakPtr) {
+    return EFI_INVALID_PARAMETER;
+  }
+  //
+  // Return the IP value
+  //
+  for (Index = 0; Index < EFI_IP_V4_BYTES; Index += 1) {
+    Ip->v4.Addr[Index] = IpAddress.v4.Addr[Index];
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EfiRestartPxeBaseCode (
+  EFI_PXE_BASE_CODE_PROTOCOL   *PxeBaseCode,
+  EFI_PXE_DHCP4_PROTOCOL       *PxeDhcp4
+  )
+/*++
+Routine Description:
+
+  Restart the PXE base code DHCP service.
+
+Arguments:
+
+  PxeBaseCode   -  The Pointer to PXE base code protocol. 
+  PxeDhcp4      -  The pointer to PxeDhcp4 protocol.
+Returns:
+
+  EFI_SUCCESS           - The command completed successfully
+  EFI_INVALID_PARAMETER - Invalid parameter
+
+--*/
+{
+  EFI_STATUS  Status;
+  DHCP4_OP    *SubnetMaskPtr;
+  DHCP4_OP    *DhcpOp;
+
+  if (PxeBaseCode == NULL) {
+    PrintToken (STRING_TOKEN (STR_IPCONFIG_INVALID_PXE), HiiHandle);
+    return EFI_INVALID_PARAMETER;
+  }
+  //
+  // If PXE base code has started, stop it.
+  //
+  if (PxeBaseCode->Mode->Started) {
+    Status = PxeBaseCode->Stop (PxeBaseCode);
+    if (EFI_ERROR (Status)) {
+      PrintToken (STRING_TOKEN (STR_IPCONFIG_STOP_PXE), HiiHandle, Status);
+    }
+  }
+  //
+  // Start DHCP, UseIpv6 == FALSE
+  //
+  Status = PxeBaseCode->Start (
+                          PxeBaseCode,
+                          FALSE
+                          );
+
+  if (EFI_ERROR (Status)) {
+    PrintToken (STRING_TOKEN (STR_IPCONFIG_START_PXE), HiiHandle, Status);
+  }
+  //
+  // Attempts to complete a DHCPv4 D.O.R.A.
+  // (discover / offer / request / acknowledge)
+  // SortOffses == TRUE, Sorts the  received offers.
+  //
+  Status = PxeDhcp4->Run (PxeDhcp4, 0, NULL);
+
+  if (EFI_ERROR (Status)) {
+    if (Status != EFI_ALREADY_STARTED) {
+      PrintToken (STRING_TOKEN (STR_IPCONFIG_DHCP), HiiHandle, Status);
+      return Status;
+    }
+  }
+
+  if (!PxeDhcp4->Data->SetupCompleted ||
+      !PxeDhcp4->Data->InitCompleted ||
+      !PxeDhcp4->Data->SelectCompleted ||
+      !PxeDhcp4->Data->IsAck
+      ) {
+    PrintToken (STRING_TOKEN (STR_IPCONFIG_DHCP), HiiHandle, Status);
+    return Status;
+  }
+  //
+  // Locate subnet mask inside DHCP options.
+  //
+  SubnetMaskPtr = FindDhcp4Option (
+                    DHCP4_SUBNET_MASK,
+                    0,
+                    &PxeDhcp4->Data->AckNak
+                    );
+
+  if (SubnetMaskPtr == NULL) {
+    PrintToken (STRING_TOKEN (STR_IPCONFIG_DHCP), HiiHandle, Status);
+    return Status;
+  }
+  //
+  // Set station IP information in PxeBc protocol.
+  //
+  Status = PxeBaseCode->SetStationIp (
+                          PxeBaseCode,
+                          (EFI_IP_ADDRESS *) &PxeDhcp4->Data->AckNak.dhcp4.yiaddr,
+                          (EFI_IP_ADDRESS *) SubnetMaskPtr->data
+                          );
+
+  if (EFI_ERROR (Status)) {
+    PrintToken (STRING_TOKEN (STR_IPCONFIG_DHCP), HiiHandle, Status);
+    return Status;
+  }
+
+  DhcpOp = FindDhcp4Option (DHCP4_ROUTER_LIST, 0, &PxeDhcp4->Data->AckNak);
+  if ((!EFI_ERROR (Status)) && (DhcpOp->len != 0) && (PxeBaseCode->Mode->RouteTableEntries == 0)) {
+    PxeBaseCode->Mode->RouteTableEntries++;
+    CopyMem (
+      &(PxeBaseCode->Mode->RouteTable[PxeBaseCode->Mode->RouteTableEntries - 1].GwAddr),
+      DhcpOp->data,
+      4
+      );
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+InitializeIpConfigGetLineHelp (
+  OUT CHAR16              **Str
+  )
+/*++
+
+Routine Description:
+
+  Get this command's line help
+
+Arguments:
+
+  Str - The line help
+
+Returns:
+
+  EFI_SUCCESS   - Success
+
+--*/
+{
+  return LibCmdGetStringByToken (STRING_ARRAY_NAME, &EfiIpConfigGuid, STRING_TOKEN (STR_IPCONFIG_LINEHELP), Str);
+}
diff --git a/IpConfig/IpConfig.h b/IpConfig/IpConfig.h
new file mode 100644 (file)
index 0000000..c6c410d
--- /dev/null
@@ -0,0 +1,32 @@
+/*++
+
+Copyright 2005, Intel Corporation                                                         
+All rights reserved. This program and the accompanying materials                          
+are licensed and made available under the terms and conditions of the BSD License         
+which accompanies this distribution. The full text of the license may be found at         
+http://opensource.org/licenses/bsd-license.php                                            
+                                                                                          
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+
+Module Name:
+
+  IpConfig.h
+
+Abstract:
+
+  declares interface functions
+
+Revision History
+
+--*/
+
+#ifndef _EFI_SHELL_IPCONFIG_H_
+#define _EFI_SHELL_IPCONFIG_H_
+#define EFI_IPCONFIG_GUID \
+  { \
+    0x8252915c, 0xf1e9, 0x435c, 0x81, 0x91, 0xad, 0x2f, 0x82, 0x62, 0x23, 0x73 \
+  }
+
+#endif
\ No newline at end of file
diff --git a/IpConfig/IpConfig.inf b/IpConfig/IpConfig.inf
new file mode 100644 (file)
index 0000000..72ebc7c
--- /dev/null
@@ -0,0 +1,64 @@
+#/*++
+#
+# Copyright 2005, Intel Corporation                                                         
+# All rights reserved. This program and the accompanying materials                          
+# are licensed and made available under the terms and conditions of the BSD License         
+# which accompanies this distribution. The full text of the license may be found at         
+# http://opensource.org/licenses/bsd-license.php                                            
+#                                                                                           
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+# 
+#  Module Name:
+#
+#    IpConfig.inf
+#
+#  Abstract:
+#
+#    Component description file for Ip Config
+#
+#--*/
+
+[defines]
+BASE_NAME            = IpConfig
+FILE_GUID            = 1D73AC03-AF05-44b3-B21E-93A174893FA6
+COMPONENT_TYPE       = APPLICATION
+
+[sources.common]
+  ..\ShCommonStrings.uni
+  IpConfigStrings.uni
+  IpConfig.c
+  IpConfig.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
+
+
+[nmake.common]
+  C_PROJ_FLAGS = $(C_PROJ_FLAGS) /Zm500
+  IMAGE_ENTRY_POINT=InitializeIpConfig
+  C_STD_FLAGS = $(C_STD_FLAGS) /DSTRING_ARRAY_NAME=$(BASE_NAME)Strings 
+  C_STD_FLAGS = $(C_STD_FLAGS) /DSTRING_DEFINES_FILE=\"$(BASE_NAME)StrDefs.h\"
+  C_STD_FLAGS = $(C_STD_FLAGS) /DEFI_BOOTSHELL
+
diff --git a/IpConfig/IpConfigStrings.uni b/IpConfig/IpConfigStrings.uni
new file mode 100644 (file)
index 0000000..7a74fdd
Binary files /dev/null and b/IpConfig/IpConfigStrings.uni differ
diff --git a/Library/CRC.c b/Library/CRC.c
new file mode 100644 (file)
index 0000000..06d55e8
--- /dev/null
@@ -0,0 +1,464 @@
+/*++
+
+Copyright 2005, Intel Corporation                                                         
+All rights reserved. This program and the accompanying materials                          
+are licensed and made available under the terms and conditions of the BSD License         
+which accompanies this distribution. The full text of the license may be found at         
+http://opensource.org/licenses/bsd-license.php                                            
+                                                                                          
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+
+Module Name:
+
+  CRC.c
+
+Abstract:
+
+  CRC32 functions
+
+Revision History
+
+--*/
+
+#include "EfiShelllib.h"
+
+UINT32  CRCTable[256] = {
+  0x00000000,
+  0x77073096,
+  0xEE0E612C,
+  0x990951BA,
+  0x076DC419,
+  0x706AF48F,
+  0xE963A535,
+  0x9E6495A3,
+  0x0EDB8832,
+  0x79DCB8A4,
+  0xE0D5E91E,
+  0x97D2D988,
+  0x09B64C2B,
+  0x7EB17CBD,
+  0xE7B82D07,
+  0x90BF1D91,
+  0x1DB71064,
+  0x6AB020F2,
+  0xF3B97148,
+  0x84BE41DE,
+  0x1ADAD47D,
+  0x6DDDE4EB,
+  0xF4D4B551,
+  0x83D385C7,
+  0x136C9856,
+  0x646BA8C0,
+  0xFD62F97A,
+  0x8A65C9EC,
+  0x14015C4F,
+  0x63066CD9,
+  0xFA0F3D63,
+  0x8D080DF5,
+  0x3B6E20C8,
+  0x4C69105E,
+  0xD56041E4,
+  0xA2677172,
+  0x3C03E4D1,
+  0x4B04D447,
+  0xD20D85FD,
+  0xA50AB56B,
+  0x35B5A8FA,
+  0x42B2986C,
+  0xDBBBC9D6,
+  0xACBCF940,
+  0x32D86CE3,
+  0x45DF5C75,
+  0xDCD60DCF,
+  0xABD13D59,
+  0x26D930AC,
+  0x51DE003A,
+  0xC8D75180,
+  0xBFD06116,
+  0x21B4F4B5,
+  0x56B3C423,
+  0xCFBA9599,
+  0xB8BDA50F,
+  0x2802B89E,
+  0x5F058808,
+  0xC60CD9B2,
+  0xB10BE924,
+  0x2F6F7C87,
+  0x58684C11,
+  0xC1611DAB,
+  0xB6662D3D,
+  0x76DC4190,
+  0x01DB7106,
+  0x98D220BC,
+  0xEFD5102A,
+  0x71B18589,
+  0x06B6B51F,
+  0x9FBFE4A5,
+  0xE8B8D433,
+  0x7807C9A2,
+  0x0F00F934,
+  0x9609A88E,
+  0xE10E9818,
+  0x7F6A0DBB,
+  0x086D3D2D,
+  0x91646C97,
+  0xE6635C01,
+  0x6B6B51F4,
+  0x1C6C6162,
+  0x856530D8,
+  0xF262004E,
+  0x6C0695ED,
+  0x1B01A57B,
+  0x8208F4C1,
+  0xF50FC457,
+  0x65B0D9C6,
+  0x12B7E950,
+  0x8BBEB8EA,
+  0xFCB9887C,
+  0x62DD1DDF,
+  0x15DA2D49,
+  0x8CD37CF3,
+  0xFBD44C65,
+  0x4DB26158,
+  0x3AB551CE,
+  0xA3BC0074,
+  0xD4BB30E2,
+  0x4ADFA541,
+  0x3DD895D7,
+  0xA4D1C46D,
+  0xD3D6F4FB,
+  0x4369E96A,
+  0x346ED9FC,
+  0xAD678846,
+  0xDA60B8D0,
+  0x44042D73,
+  0x33031DE5,
+  0xAA0A4C5F,
+  0xDD0D7CC9,
+  0x5005713C,
+  0x270241AA,
+  0xBE0B1010,
+  0xC90C2086,
+  0x5768B525,
+  0x206F85B3,
+  0xB966D409,
+  0xCE61E49F,
+  0x5EDEF90E,
+  0x29D9C998,
+  0xB0D09822,
+  0xC7D7A8B4,
+  0x59B33D17,
+  0x2EB40D81,
+  0xB7BD5C3B,
+  0xC0BA6CAD,
+  0xEDB88320,
+  0x9ABFB3B6,
+  0x03B6E20C,
+  0x74B1D29A,
+  0xEAD54739,
+  0x9DD277AF,
+  0x04DB2615,
+  0x73DC1683,
+  0xE3630B12,
+  0x94643B84,
+  0x0D6D6A3E,
+  0x7A6A5AA8,
+  0xE40ECF0B,
+  0x9309FF9D,
+  0x0A00AE27,
+  0x7D079EB1,
+  0xF00F9344,
+  0x8708A3D2,
+  0x1E01F268,
+  0x6906C2FE,
+  0xF762575D,
+  0x806567CB,
+  0x196C3671,
+  0x6E6B06E7,
+  0xFED41B76,
+  0x89D32BE0,
+  0x10DA7A5A,
+  0x67DD4ACC,
+  0xF9B9DF6F,
+  0x8EBEEFF9,
+  0x17B7BE43,
+  0x60B08ED5,
+  0xD6D6A3E8,
+  0xA1D1937E,
+  0x38D8C2C4,
+  0x4FDFF252,
+  0xD1BB67F1,
+  0xA6BC5767,
+  0x3FB506DD,
+  0x48B2364B,
+  0xD80D2BDA,
+  0xAF0A1B4C,
+  0x36034AF6,
+  0x41047A60,
+  0xDF60EFC3,
+  0xA867DF55,
+  0x316E8EEF,
+  0x4669BE79,
+  0xCB61B38C,
+  0xBC66831A,
+  0x256FD2A0,
+  0x5268E236,
+  0xCC0C7795,
+  0xBB0B4703,
+  0x220216B9,
+  0x5505262F,
+  0xC5BA3BBE,
+  0xB2BD0B28,
+  0x2BB45A92,
+  0x5CB36A04,
+  0xC2D7FFA7,
+  0xB5D0CF31,
+  0x2CD99E8B,
+  0x5BDEAE1D,
+  0x9B64C2B0,
+  0xEC63F226,
+  0x756AA39C,
+  0x026D930A,
+  0x9C0906A9,
+  0xEB0E363F,
+  0x72076785,
+  0x05005713,
+  0x95BF4A82,
+  0xE2B87A14,
+  0x7BB12BAE,
+  0x0CB61B38,
+  0x92D28E9B,
+  0xE5D5BE0D,
+  0x7CDCEFB7,
+  0x0BDBDF21,
+  0x86D3D2D4,
+  0xF1D4E242,
+  0x68DDB3F8,
+  0x1FDA836E,
+  0x81BE16CD,
+  0xF6B9265B,
+  0x6FB077E1,
+  0x18B74777,
+  0x88085AE6,
+  0xFF0F6A70,
+  0x66063BCA,
+  0x11010B5C,
+  0x8F659EFF,
+  0xF862AE69,
+  0x616BFFD3,
+  0x166CCF45,
+  0xA00AE278,
+  0xD70DD2EE,
+  0x4E048354,
+  0x3903B3C2,
+  0xA7672661,
+  0xD06016F7,
+  0x4969474D,
+  0x3E6E77DB,
+  0xAED16A4A,
+  0xD9D65ADC,
+  0x40DF0B66,
+  0x37D83BF0,
+  0xA9BCAE53,
+  0xDEBB9EC5,
+  0x47B2CF7F,
+  0x30B5FFE9,
+  0xBDBDF21C,
+  0xCABAC28A,
+  0x53B39330,
+  0x24B4A3A6,
+  0xBAD03605,
+  0xCDD70693,
+  0x54DE5729,
+  0x23D967BF,
+  0xB3667A2E,
+  0xC4614AB8,
+  0x5D681B02,
+  0x2A6F2B94,
+  0xB40BBE37,
+  0xC30C8EA1,
+  0x5A05DF1B,
+  0x2D02EF8D
+};
+
+VOID
+SetCrc (
+  IN OUT EFI_TABLE_HEADER *Hdr
+  )
+/*++
+
+Routine Description:
+
+    Updates the CRC32 value in the table header
+
+Arguments:
+
+    Hdr     - The table to update
+
+Returns:
+
+    None
+
+--*/
+{
+  ASSERT (Hdr != NULL);
+  SetCrcAltSize (Hdr->HeaderSize, Hdr);
+}
+
+VOID
+SetCrcAltSize (
+  IN UINTN                  Size,
+  IN OUT EFI_TABLE_HEADER   *Hdr
+  )
+/*++
+
+Routine Description:
+
+    Updates the CRC32 value in the table header
+
+Arguments:
+
+    Size    - Size
+    Hdr     - The table to update
+
+Returns:
+
+    None
+
+--*/
+{
+  ASSERT (Hdr != NULL);
+  Hdr->CRC32  = 0;
+  Hdr->CRC32  = CalculateCrc ((UINT8 *) Hdr, Size);
+}
+
+BOOLEAN
+CheckCrc (
+  IN UINTN                  MaxSize,
+  IN OUT EFI_TABLE_HEADER   *Hdr
+  )
+/*++
+
+Routine Description:
+
+    Checks the CRC32 value in the table header
+
+Arguments:
+
+   MaxSize - The max size
+   Hdr     - The table to check
+
+Returns:
+
+    TRUE if the CRC is OK in the table
+
+--*/
+{
+  ASSERT (Hdr != NULL);
+  return CheckCrcAltSize (MaxSize, Hdr->HeaderSize, Hdr);
+}
+
+BOOLEAN
+CheckCrcAltSize (
+  IN UINTN                  MaxSize,
+  IN UINTN                  Size,
+  IN OUT EFI_TABLE_HEADER   *Hdr
+  )
+/*++
+
+Routine Description:
+
+    Checks the CRC32 value in the table header
+
+Arguments:
+
+    MaxSize - The max size
+    Size    - The size
+    Hdr     - The table to check
+
+Returns:
+
+    TRUE if the CRC is OK in the table
+
+--*/
+{
+  UINT32  Crc;
+  UINT32  OrgCrc;
+  BOOLEAN f;
+  
+  ASSERT (Hdr != NULL);
+
+  if (Size == 0) {
+    //
+    // If header size is 0 CRC will pass so return FALSE here
+    //
+    return FALSE;
+  }
+
+  if (MaxSize && Size > MaxSize) {
+    DEBUG ((EFI_D_ERROR, "CheckCrc32: Size > MaxSize\n"));
+    return FALSE;
+  }
+  //
+  // clear old crc from header
+  //
+  OrgCrc      = Hdr->CRC32;
+  Hdr->CRC32  = 0;
+  Crc         = CalculateCrc ((UINT8 *) Hdr, Size);
+
+  //
+  // set restults
+  //
+  Hdr->CRC32 = OrgCrc;
+
+  //
+  // return status
+  //
+  f = (BOOLEAN) (OrgCrc == (UINT32) Crc);
+  if (!f) {
+    DEBUG ((EFI_D_ERROR, "CheckCrc32: Crc check failed\n"));
+  }
+
+  return f;
+}
+
+UINT32
+CalculateCrc (
+  UINT8 *pt,
+  UINTN Size
+  )
+/*++
+
+Routine Description:
+
+    Calculate the CRC32 value
+
+Arguments:
+
+   pt      - The pointer to the data
+   Size    - The data size
+
+Returns:
+
+    The CRC value of the data
+
+--*/
+{
+  UINTN Crc;
+
+  ASSERT (pt != NULL);
+
+  //
+  // compute crc
+  //
+  Crc = 0xffffffff;
+  while (Size) {
+    Crc = (Crc >> 8) ^ CRCTable[(UINT8) Crc ^ *pt];
+    pt += 1;
+    Size -= 1;
+  }
+
+  Crc = Crc ^ 0xffffffff;
+  return (UINT32) Crc;
+}
diff --git a/Library/CRC.h b/Library/CRC.h
new file mode 100644 (file)
index 0000000..229c64e
--- /dev/null
@@ -0,0 +1,56 @@
+/*++
+
+Copyright 2005, Intel Corporation                                                         
+All rights reserved. This program and the accompanying materials                          
+are licensed and made available under the terms and conditions of the BSD License         
+which accompanies this distribution. The full text of the license may be found at         
+http://opensource.org/licenses/bsd-license.php                                            
+                                                                                          
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+
+Module Name:
+
+  crc.h
+
+Abstract:
+
+  Infomation about the crc function.
+Revision History
+
+--*/
+#ifndef _CRC_H
+#define _CRC_H
+
+VOID
+SetCrc (
+  IN OUT EFI_TABLE_HEADER           *Hdr
+  );
+
+VOID
+SetCrcAltSize (
+  IN UINTN                          Size,
+  IN OUT EFI_TABLE_HEADER           *Hdr
+  );
+
+BOOLEAN
+CheckCrc (
+  IN UINTN                          MaxSize,
+  IN OUT EFI_TABLE_HEADER           *Hdr
+  );
+
+BOOLEAN
+CheckCrcAltSize (
+  IN UINTN                          MaxSize,
+  IN UINTN                          Size,
+  IN OUT EFI_TABLE_HEADER           *Hdr
+  );
+
+UINT32
+CalculateCrc (
+  UINT8 *pt,
+  UINTN Size
+  );
+
+#endif
\ No newline at end of file
diff --git a/Library/ConsistMapping.c b/Library/ConsistMapping.c
new file mode 100644 (file)
index 0000000..c3ad0f6
--- /dev/null
@@ -0,0 +1,1052 @@
+/*++
+
+Copyright 2005, Intel Corporation                                                         
+All rights reserved. This program and the accompanying materials                          
+are licensed and made available under the terms and conditions of the BSD License         
+which accompanies this distribution. The full text of the license may be found at         
+http://opensource.org/licenses/bsd-license.php                                            
+                                                                                          
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+
+Module Name:
+
+  ConsistMapping.c
+  
+Abstract:
+
+  Library function support consist mapping.
+
+Revision History
+
+--*/
+
+#include "EfiShelllib.h"
+
+MTD_NAME  mMTDName[] = {
+  {
+    MTDTypeUnknown,
+    L"f"
+  },
+  {
+    MTDTypeFloppy,
+    L"fp"
+  },
+  {
+    MTDTypeHardDisk,
+    L"hd"
+  },
+  {
+    MTDTypeCDRom,
+    L"cd"
+  },
+  {
+    MTDTypeEnd,
+    NULL
+  }
+};
+
+VOID
+AppendCSDNum2 (
+  IN OUT POOL_PRINT       *Str,
+  IN UINT64               Num
+  )
+{
+  UINT64  Result;
+  UINTN   Rem;
+  
+  ASSERT(Str != NULL);
+  
+  Result = DivU64x32 (Num, 25, &Rem);
+  if (Result > 0) {
+    AppendCSDNum2 (Str, Result);
+  }
+
+  CatPrint (Str, L"%c", Rem + 'a');
+}
+
+VOID
+AppendCSDNum (
+  DEVICE_CONSIST_MAPPING_INFO            *MappingItem,
+  UINT64                                 Num
+  )
+{
+  ASSERT(MappingItem != NULL);
+
+  if (MappingItem->Digital) {
+    CatPrint (&MappingItem->CSD, L"%ld", Num);
+  } else {
+    AppendCSDNum2 (&MappingItem->CSD, Num);
+  }
+
+  MappingItem->Digital = (BOOLEAN)!(MappingItem->Digital);
+}
+
+VOID
+AppendCSDStr (
+  DEVICE_CONSIST_MAPPING_INFO            *MappingItem,
+  CHAR16                                 *Str
+  )
+{
+  CHAR16  *Index;
+  
+  ASSERT(Str != NULL);
+  ASSERT(MappingItem != NULL);
+
+  if (MappingItem->Digital) {
+    //
+    // To aVOID mult-meaning, the mapping is:
+    //  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
+    //  0  16 2  3  4  5  6  7  8  9  10 11 12 13 14 15
+    //
+    for (Index = Str; *Index != 0; Index++) {
+      switch (*Index) {
+      case '0':
+      case '2':
+      case '3':
+      case '4':
+      case '5':
+      case '6':
+      case '7':
+      case '8':
+      case '9':
+        CatPrint (&MappingItem->CSD, L"%c", *Index);
+        break;
+
+      case '1':
+        CatPrint (&MappingItem->CSD, L"16");
+        break;
+
+      case 'a':
+      case 'b':
+      case 'c':
+      case 'd':
+      case 'e':
+      case 'f':
+        CatPrint (&MappingItem->CSD, L"1%c", *Index - 'a' + '0');
+        break;
+
+      case 'A':
+      case 'B':
+      case 'C':
+      case 'D':
+      case 'E':
+      case 'F':
+        CatPrint (&MappingItem->CSD, L"1%c", *Index - 'A' + '0');
+        break;
+      }
+    }
+  } else {
+    for (Index = Str; *Index != 0; Index++) {
+      //
+      //  The mapping is:
+      //  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
+      //  a  b  c  d  e  f  g  h  i  j  k  l  m  n  o  p
+      //
+      if (*Index >= '0' && *Index <= '9') {
+        CatPrint (&MappingItem->CSD, L"%c", *Index - '0' + 'a');
+      } else if (*Index >= 'a' && *Index <= 'f') {
+        CatPrint (&MappingItem->CSD, L"%c", *Index - 'a' + 'k');
+      } else if (*Index >= 'A' && *Index <= 'F') {
+        CatPrint (&MappingItem->CSD, L"%c", *Index - 'A' + 'k');
+      }
+    }
+  }
+
+  MappingItem->Digital = (BOOLEAN)!(MappingItem->Digital);
+}
+
+VOID
+AppendCSDGuid (
+  DEVICE_CONSIST_MAPPING_INFO            *MappingItem,
+  EFI_GUID                               *Guid
+  )
+{
+  CHAR16  Buffer[64];
+  ASSERT(Guid != NULL);
+  ASSERT(MappingItem != NULL);
+
+  SPrint (
+    Buffer,
+    0,
+    L"%08x%04x%04x%02x%02x%02x%02x%02x%02x%02x%02x",
+    Guid->Data1,
+    Guid->Data2,
+    Guid->Data3,
+    Guid->Data4[0],
+    Guid->Data4[1],
+    Guid->Data4[2],
+    Guid->Data4[3],
+    Guid->Data4[4],
+    Guid->Data4[5],
+    Guid->Data4[6],
+    Guid->Data4[7]
+    );
+  StrLwr (Buffer);
+  AppendCSDStr (MappingItem, Buffer);
+}
+
+INTN
+_DevPathCompareAcpi (
+  IN EFI_DEVICE_PATH_PROTOCOL       *DevicePath1,
+  IN EFI_DEVICE_PATH_PROTOCOL       *DevicePath2
+  )
+{
+  ACPI_HID_DEVICE_PATH  *Acpi1;
+  ACPI_HID_DEVICE_PATH  *Acpi2;
+
+  ASSERT(DevicePath1 != NULL);
+  ASSERT(DevicePath2 != NULL);
+
+  Acpi1 = (ACPI_HID_DEVICE_PATH *) DevicePath1;
+  Acpi2 = (ACPI_HID_DEVICE_PATH *) DevicePath2;
+  if (Acpi1->HID > Acpi2->HID || (Acpi1->HID == Acpi2->HID && Acpi1->UID > Acpi2->UID)) {
+    return 1;
+  }
+
+  if (Acpi1->HID == Acpi2->HID && Acpi1->UID == Acpi2->UID) {
+    return 0;
+  }
+
+  return -1;
+}
+
+INTN
+_DevPathComparePci (
+  IN EFI_DEVICE_PATH_PROTOCOL       *DevicePath1,
+  IN EFI_DEVICE_PATH_PROTOCOL       *DevicePath2
+  )
+{
+  PCI_DEVICE_PATH *Pci1;
+  PCI_DEVICE_PATH *Pci2;
+
+  ASSERT(DevicePath1 != NULL);
+  ASSERT(DevicePath2 != NULL);
+
+  Pci1  = (PCI_DEVICE_PATH *) DevicePath1;
+  Pci2  = (PCI_DEVICE_PATH *) DevicePath2;
+  if (Pci1->Device > Pci2->Device || (Pci1->Device == Pci2->Device && Pci1->Function > Pci2->Function)) {
+    return 1;
+  }
+
+  if (Pci1->Device == Pci2->Device && Pci1->Function == Pci2->Function) {
+    return 0;
+  }
+
+  return -1;
+}
+
+INTN
+_DevPathCompareDefault (
+  IN EFI_DEVICE_PATH_PROTOCOL       *DevicePath1,
+  IN EFI_DEVICE_PATH_PROTOCOL       *DevicePath2
+  )
+{
+  UINTN DevPathSize1;
+  UINTN DevPathSize2;
+
+  ASSERT(DevicePath1 != NULL);
+  ASSERT(DevicePath2 != NULL);
+
+  DevPathSize1  = DevicePathNodeLength (DevicePath1);
+  DevPathSize2  = DevicePathNodeLength (DevicePath2);
+  if (DevPathSize1 > DevPathSize2) {
+    return 1;
+  } else if (DevPathSize1 < DevPathSize2) {
+    return -1;
+  } else {
+    return CompareMem (DevicePath1, DevicePath2, DevPathSize1);
+  }
+}
+
+VOID
+_DevPathSerialHardDrive (
+  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePathNode,
+  IN DEVICE_CONSIST_MAPPING_INFO  *MappingItem
+  )
+{
+  HARDDRIVE_DEVICE_PATH *Hd;
+  
+  ASSERT(DevicePathNode != NULL);
+  ASSERT(MappingItem != NULL);
+
+  Hd = (HARDDRIVE_DEVICE_PATH *) DevicePathNode;
+  if (MappingItem->MTD == MTDTypeUnknown) {
+    MappingItem->MTD = MTDTypeHardDisk;
+  }
+
+  AppendCSDNum (MappingItem, Hd->PartitionNumber);
+}
+
+VOID
+_DevPathSerialAtapi (
+  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePathNode,
+  IN DEVICE_CONSIST_MAPPING_INFO  *MappingItem
+  )
+{
+  ATAPI_DEVICE_PATH *Atapi;
+
+  ASSERT(DevicePathNode != NULL);
+  ASSERT(MappingItem != NULL);
+
+  Atapi = (ATAPI_DEVICE_PATH *) DevicePathNode;
+  AppendCSDNum (MappingItem, (Atapi->PrimarySecondary * 2 + Atapi->SlaveMaster));
+}
+
+VOID
+_DevPathSerialCDROM (
+  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePathNode,
+  IN DEVICE_CONSIST_MAPPING_INFO  *MappingItem
+  )
+{
+  CDROM_DEVICE_PATH *Cd;
+
+  ASSERT(DevicePathNode != NULL);
+  ASSERT(MappingItem != NULL);
+
+  Cd                = (CDROM_DEVICE_PATH *) DevicePathNode;
+  MappingItem->MTD  = MTDTypeCDRom;
+  AppendCSDNum (MappingItem, Cd->BootEntry);
+}
+
+VOID
+_DevPathSerialFibre (
+  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePathNode,
+  IN DEVICE_CONSIST_MAPPING_INFO  *MappingItem
+  )
+{
+  FIBRECHANNEL_DEVICE_PATH  *Fibre;
+
+  ASSERT(DevicePathNode != NULL);
+  ASSERT(MappingItem != NULL);
+
+  Fibre = (FIBRECHANNEL_DEVICE_PATH *) DevicePathNode;
+  AppendCSDNum (MappingItem, Fibre->WWN);
+  AppendCSDNum (MappingItem, Fibre->Lun);
+}
+
+VOID
+_DevPathSerialUart (
+  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePathNode,
+  IN DEVICE_CONSIST_MAPPING_INFO  *MappingItem
+  )
+{
+  UART_DEVICE_PATH  *Uart;
+
+  ASSERT(DevicePathNode != NULL);
+  ASSERT(MappingItem != NULL);
+
+  Uart = (UART_DEVICE_PATH *) DevicePathNode;
+  AppendCSDNum (MappingItem, Uart->BaudRate);
+  AppendCSDNum (MappingItem, Uart->DataBits);
+  AppendCSDNum (MappingItem, Uart->Parity);
+  AppendCSDNum (MappingItem, Uart->StopBits);
+}
+
+VOID
+_DevPathSerialUsb (
+  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePathNode,
+  IN DEVICE_CONSIST_MAPPING_INFO  *MappingItem
+  )
+{
+  USB_DEVICE_PATH *Usb;
+
+  ASSERT(DevicePathNode != NULL);
+  ASSERT(MappingItem != NULL);
+
+  Usb = (USB_DEVICE_PATH *) DevicePathNode;
+  AppendCSDNum (MappingItem, Usb->ParentPortNumber);
+  AppendCSDNum (MappingItem, Usb->InterfaceNumber);
+}
+
+VOID
+_DevPathSerialVendor (
+  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePathNode,
+  IN DEVICE_CONSIST_MAPPING_INFO  *MappingItem
+  )
+{
+  VENDOR_DEVICE_PATH  *Vendor;
+
+  ASSERT(DevicePathNode != NULL);
+  ASSERT(MappingItem != NULL);
+
+  Vendor = (VENDOR_DEVICE_PATH *) DevicePathNode;
+  AppendCSDGuid (MappingItem, &Vendor->Guid);
+}
+
+VOID
+_DevPathSerialI2O (
+  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePathNode,
+  IN DEVICE_CONSIST_MAPPING_INFO  *MappingItem
+  )
+{
+  I2O_DEVICE_PATH *I2O;
+
+  ASSERT(DevicePathNode != NULL);
+  ASSERT(MappingItem != NULL);
+
+  I2O = (I2O_DEVICE_PATH *) DevicePathNode;
+  AppendCSDNum (MappingItem, I2O->Tid);
+}
+
+VOID
+_DevPathSerialMacAddr (
+  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePathNode,
+  IN DEVICE_CONSIST_MAPPING_INFO  *MappingItem
+  )
+{
+  MAC_ADDR_DEVICE_PATH  *MAC;
+  UINTN                 HwAddressSize;
+  UINTN                 Index;
+  CHAR16                Buffer[64];
+  CHAR16                *PBuffer;
+
+  ASSERT(DevicePathNode != NULL);
+  ASSERT(MappingItem != NULL);
+
+  MAC           = (MAC_ADDR_DEVICE_PATH *) DevicePathNode;
+
+  HwAddressSize = sizeof (EFI_MAC_ADDRESS);
+  if (MAC->IfType == 0x01 || MAC->IfType == 0x00) {
+    HwAddressSize = 6;
+  }
+
+  for (Index = 0, PBuffer = Buffer; Index < HwAddressSize; Index++, PBuffer += 2) {
+    SPrint (PBuffer, 0, L"%02x", MAC->MacAddress.Addr[Index]);
+  }
+
+  AppendCSDStr (MappingItem, Buffer);
+}
+
+VOID
+_DevPathSerialInfiniBand (
+  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePathNode,
+  IN DEVICE_CONSIST_MAPPING_INFO  *MappingItem
+  )
+{
+  INFINIBAND_DEVICE_PATH  *InfiniBand;
+  UINTN                   Index;
+  CHAR16                  Buffer[64];
+  CHAR16                  *PBuffer;
+
+  ASSERT(DevicePathNode != NULL);
+  ASSERT(MappingItem != NULL);
+
+  InfiniBand = (INFINIBAND_DEVICE_PATH *) DevicePathNode;
+  for (Index = 0, PBuffer = Buffer; Index < 16; Index++, PBuffer += 2) {
+    SPrint (PBuffer, 0, L"%02x", InfiniBand->PortGid[Index]);
+  }
+
+  AppendCSDStr (MappingItem, Buffer);
+  AppendCSDNum (MappingItem, InfiniBand->ServiceId);
+  AppendCSDNum (MappingItem, InfiniBand->TargetPortId);
+  AppendCSDNum (MappingItem, InfiniBand->DeviceId);
+}
+
+VOID
+_DevPathSerialIPv4 (
+  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePathNode,
+  IN DEVICE_CONSIST_MAPPING_INFO  *MappingItem
+  )
+{
+  IPv4_DEVICE_PATH  *IP;
+  CHAR16            Buffer[10];
+
+  ASSERT(DevicePathNode != NULL);
+  ASSERT(MappingItem != NULL);
+
+  IP = (IPv4_DEVICE_PATH *) DevicePathNode;
+  SPrint (
+    Buffer,
+    0,
+    L"%02x%02x%02x%02x",
+    IP->LocalIpAddress.Addr[0],
+    IP->LocalIpAddress.Addr[1],
+    IP->LocalIpAddress.Addr[2],
+    IP->LocalIpAddress.Addr[3]
+    );
+  AppendCSDStr (MappingItem, Buffer);
+  AppendCSDNum (MappingItem, IP->LocalPort);
+  SPrint (
+    Buffer,
+    0,
+    L"%02x%02x%02x%02x",
+    IP->RemoteIpAddress.Addr[0],
+    IP->RemoteIpAddress.Addr[1],
+    IP->RemoteIpAddress.Addr[2],
+    IP->RemoteIpAddress.Addr[3]
+    );
+  AppendCSDStr (MappingItem, Buffer);
+  AppendCSDNum (MappingItem, IP->RemotePort);
+}
+
+VOID
+_DevPathSerialIPv6 (
+  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePathNode,
+  IN DEVICE_CONSIST_MAPPING_INFO  *MappingItem
+  )
+{
+  IPv6_DEVICE_PATH  *IP;
+  UINTN             Index;
+  CHAR16            Buffer[64];
+  CHAR16            *PBuffer;
+
+  ASSERT(DevicePathNode != NULL);
+  ASSERT(MappingItem != NULL);
+
+  IP = (IPv6_DEVICE_PATH *) DevicePathNode;
+  for (Index = 0, PBuffer = Buffer; Index < 16; Index++, PBuffer += 2) {
+    SPrint (PBuffer, 0, L"%02x", IP->LocalIpAddress.Addr[Index]);
+  }
+
+  AppendCSDStr (MappingItem, Buffer);
+  AppendCSDNum (MappingItem, IP->LocalPort);
+  for (Index = 0, PBuffer = Buffer; Index < 16; Index++, PBuffer += 2) {
+    SPrint (PBuffer, 0, L"%02x", IP->RemoteIpAddress.Addr[Index]);
+  }
+
+  AppendCSDStr (MappingItem, Buffer);
+  AppendCSDNum (MappingItem, IP->RemotePort);
+}
+
+VOID
+_DevPathSerialScsi (
+  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePathNode,
+  IN DEVICE_CONSIST_MAPPING_INFO  *MappingItem
+  )
+{
+  SCSI_DEVICE_PATH  *Scsi;
+
+  ASSERT(DevicePathNode != NULL);
+  ASSERT(MappingItem != NULL);
+
+  Scsi = (SCSI_DEVICE_PATH *) DevicePathNode;
+  AppendCSDNum (MappingItem, Scsi->Pun);
+  AppendCSDNum (MappingItem, Scsi->Lun);
+}
+
+VOID
+_DevPathSerial1394 (
+  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePathNode,
+  IN DEVICE_CONSIST_MAPPING_INFO  *MappingItem
+  )
+{
+  F1394_DEVICE_PATH *F1394;
+  CHAR16            Buffer[20];
+  
+  ASSERT(DevicePathNode != NULL);
+  ASSERT(MappingItem != NULL);
+
+  F1394 = (F1394_DEVICE_PATH *) DevicePathNode;
+  SPrint (Buffer, 0, L"%lx", F1394->Guid);
+  AppendCSDStr (MappingItem, Buffer);
+}
+
+VOID
+_DevPathSerialAcpi (
+  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePathNode,
+  IN DEVICE_CONSIST_MAPPING_INFO  *MappingItem
+  )
+{
+  ACPI_HID_DEVICE_PATH  *Acpi;
+
+  ASSERT(DevicePathNode != NULL);
+  ASSERT(MappingItem != NULL);
+
+  Acpi = (ACPI_HID_DEVICE_PATH *) DevicePathNode;
+  if ((Acpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
+    if (EISA_ID_TO_NUM (Acpi->HID) == 0x0604) {
+      MappingItem->MTD = MTDTypeFloppy;
+      AppendCSDNum (MappingItem, Acpi->UID);
+    }
+  }
+}
+
+VOID
+_DevPathSerialDefault (
+  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePathNode,
+  IN DEVICE_CONSIST_MAPPING_INFO  *MappingItem
+  )
+{
+}
+
+DEV_PATH_CONSIST_MAPPING_TABLE  DevPathConsistMappingTable[] = {
+  HARDWARE_DEVICE_PATH,
+  HW_PCI_DP,
+  _DevPathSerialDefault,
+  _DevPathComparePci,
+  HARDWARE_DEVICE_PATH,
+  HW_PCCARD_DP,
+  _DevPathSerialDefault,
+  _DevPathCompareDefault,
+  HARDWARE_DEVICE_PATH,
+  HW_MEMMAP_DP,
+  _DevPathSerialDefault,
+  _DevPathCompareDefault,
+  HARDWARE_DEVICE_PATH,
+  HW_VENDOR_DP,
+  _DevPathSerialDefault,
+  _DevPathCompareDefault,
+  HARDWARE_DEVICE_PATH,
+  HW_CONTROLLER_DP,
+  _DevPathSerialDefault,
+  _DevPathCompareDefault,
+  ACPI_DEVICE_PATH,
+  ACPI_DP,
+  _DevPathSerialAcpi,
+  _DevPathCompareAcpi,
+  MESSAGING_DEVICE_PATH,
+  MSG_ATAPI_DP,
+  _DevPathSerialAtapi,
+  _DevPathCompareDefault,
+  MESSAGING_DEVICE_PATH,
+  MSG_SCSI_DP,
+  _DevPathSerialScsi,
+  _DevPathCompareDefault,
+  MESSAGING_DEVICE_PATH,
+  MSG_FIBRECHANNEL_DP,
+  _DevPathSerialFibre,
+  _DevPathCompareDefault,
+  MESSAGING_DEVICE_PATH,
+  MSG_1394_DP,
+  _DevPathSerial1394,
+  _DevPathCompareDefault,
+  MESSAGING_DEVICE_PATH,
+  MSG_USB_DP,
+  _DevPathSerialUsb,
+  _DevPathCompareDefault,
+  MESSAGING_DEVICE_PATH,
+  MSG_USB_CLASS_DP,
+  _DevPathSerialDefault,
+  _DevPathCompareDefault,
+  MESSAGING_DEVICE_PATH,
+  MSG_I2O_DP,
+  _DevPathSerialI2O,
+  _DevPathCompareDefault,
+  MESSAGING_DEVICE_PATH,
+  MSG_MAC_ADDR_DP,
+  _DevPathSerialMacAddr,
+  _DevPathCompareDefault,
+  MESSAGING_DEVICE_PATH,
+  MSG_IPv4_DP,
+  _DevPathSerialIPv4,
+  _DevPathCompareDefault,
+  MESSAGING_DEVICE_PATH,
+  MSG_IPv6_DP,
+  _DevPathSerialIPv6,
+  _DevPathCompareDefault,
+  MESSAGING_DEVICE_PATH,
+  MSG_INFINIBAND_DP,
+  _DevPathSerialInfiniBand,
+  _DevPathCompareDefault,
+  MESSAGING_DEVICE_PATH,
+  MSG_UART_DP,
+  _DevPathSerialUart,
+  _DevPathCompareDefault,
+  MESSAGING_DEVICE_PATH,
+  MSG_VENDOR_DP,
+  _DevPathSerialVendor,
+  _DevPathCompareDefault,
+  MEDIA_DEVICE_PATH,
+  MEDIA_HARDDRIVE_DP,
+  _DevPathSerialHardDrive,
+  _DevPathCompareDefault,
+  MEDIA_DEVICE_PATH,
+  MEDIA_CDROM_DP,
+  _DevPathSerialCDROM,
+  _DevPathCompareDefault,
+  MEDIA_DEVICE_PATH,
+  MEDIA_VENDOR_DP,
+  _DevPathSerialVendor,
+  _DevPathCompareDefault,
+  MEDIA_DEVICE_PATH,
+  MEDIA_FILEPATH_DP,
+  _DevPathSerialDefault,
+  _DevPathCompareDefault,
+  MEDIA_DEVICE_PATH,
+  MEDIA_PROTOCOL_DP,
+  _DevPathSerialDefault,
+  _DevPathCompareDefault,
+  MEDIA_DEVICE_PATH,
+  MEDIA_FV_FILEPATH_DP,
+  _DevPathSerialDefault,
+  _DevPathCompareDefault,
+  BBS_DEVICE_PATH,
+  BBS_BBS_DP,
+  _DevPathSerialDefault,
+  _DevPathCompareDefault,
+  END_DEVICE_PATH_TYPE,
+  END_INSTANCE_DEVICE_PATH_SUBTYPE,
+  _DevPathSerialDefault,
+  _DevPathCompareDefault,
+  0,
+  0,
+  NULL,
+  NULL
+};
+
+INTN
+DevicePathConsistMappingCompare (
+  IN  VOID             *Buffer1,
+  IN  VOID             *Buffer2
+  )
+{
+  UINTN                     Index;
+  INTN                      CompareResult;
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath1 = *(EFI_DEVICE_PATH_PROTOCOL**)Buffer1;
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath2 = *(EFI_DEVICE_PATH_PROTOCOL**)Buffer2;
+  INTN                      (*CompareFun)(EFI_DEVICE_PATH_PROTOCOL *, EFI_DEVICE_PATH_PROTOCOL *);
+
+  if (DevicePath1 == NULL) {
+    if (DevicePath2 == NULL) {
+      return 0;
+    }
+
+    return -1;
+  }
+
+  if (DevicePath2 == NULL) {
+    return 1;
+  }
+
+  while (!(IsDevicePathEnd (DevicePath1) || IsDevicePathEnd (DevicePath2))) {
+    CompareResult = DevicePathType (DevicePath1) - DevicePathType (DevicePath2);
+    if (CompareResult != 0) {
+      return CompareResult;
+    }
+
+    CompareResult = DevicePathSubType (DevicePath1) - DevicePathSubType (DevicePath2);
+    if (CompareResult != 0) {
+      return CompareResult;
+    }
+
+    CompareFun = NULL;
+    for (Index = 0; DevPathConsistMappingTable[Index].CompareFun; Index += 1) {
+      if (DevicePathType (DevicePath1) == DevPathConsistMappingTable[Index].Type &&
+          DevicePathSubType (DevicePath1) == DevPathConsistMappingTable[Index].SubType
+          ) {
+        CompareFun = DevPathConsistMappingTable[Index].CompareFun;
+        break;
+      }
+    }
+    //
+    // If not found, use a default function
+    //
+    if (!CompareFun) {
+      CompareFun = _DevPathCompareDefault;
+    }
+
+    CompareResult = CompareFun (DevicePath1, DevicePath2);
+    if (CompareResult != 0) {
+      return CompareResult;
+    }
+
+    DevicePath1 = (EFI_DEVICE_PATH_PROTOCOL *) NextDevicePathNode (DevicePath1);
+    DevicePath2 = (EFI_DEVICE_PATH_PROTOCOL *) NextDevicePathNode (DevicePath2);
+  }
+
+  if (IsDevicePathEnd (DevicePath1)) {
+    if (IsDevicePathEnd (DevicePath2)) {
+      return 0;
+    }
+
+    return -1;
+  }
+
+  return 1;
+}
+
+EFI_STATUS
+DevicePathConsistMappingSort (
+  IN  EFI_DEVICE_PATH_PROTOCOL **DevicePathBuffer,
+  IN  UINTN                    DevicePathNum
+  )
+{
+  QSort (DevicePathBuffer, DevicePathNum, sizeof (EFI_DEVICE_PATH_PROTOCOL *), DevicePathConsistMappingCompare);
+  return EFI_SUCCESS;
+}
+
+BOOLEAN
+IsHIDevicePathNode (
+  EFI_DEVICE_PATH_PROTOCOL *DevicePathNode
+  )
+{
+  ACPI_HID_DEVICE_PATH  *Acpi;
+
+  ASSERT(DevicePathNode != NULL);
+
+  if (DevicePathNode->Type == HARDWARE_DEVICE_PATH) {
+    return TRUE;
+  }
+
+  if (DevicePathNode->Type == ACPI_DEVICE_PATH) {
+    Acpi = (ACPI_HID_DEVICE_PATH *) DevicePathNode;
+    switch (EISA_ID_TO_NUM (Acpi->HID)) {
+    case 0x0301:
+    case 0x0401:
+    case 0x0501:
+    case 0x0604:
+      return FALSE;
+    }
+
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+GetHIDevicePath (
+  EFI_DEVICE_PATH_PROTOCOL        *DevicePath
+  )
+{
+  UINTN                     NonHIDevicePathNodeCount;
+  UINTN                     Index;
+  EFI_DEV_PATH              Node;
+  EFI_DEVICE_PATH_PROTOCOL  *HIDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL  *TempDevicePath;
+
+  ASSERT(DevicePath != NULL);
+
+  NonHIDevicePathNodeCount  = 0;
+
+  HIDevicePath              = AllocatePool (sizeof (EFI_DEVICE_PATH_PROTOCOL));
+  SetDevicePathEndNode (HIDevicePath);
+
+  Node.DevPath.Type       = END_DEVICE_PATH_TYPE;
+  Node.DevPath.SubType    = END_INSTANCE_DEVICE_PATH_SUBTYPE;
+  Node.DevPath.Length[0]  = sizeof (EFI_DEVICE_PATH_PROTOCOL);
+  Node.DevPath.Length[1]  = 0;
+
+  while (!IsDevicePathEnd (DevicePath)) {
+    if (IsHIDevicePathNode (DevicePath)) {
+      for (Index = 0; Index < NonHIDevicePathNodeCount; Index++) {
+        TempDevicePath = AppendDevicePathNode (HIDevicePath, &Node.DevPath);
+        FreePool (HIDevicePath);
+        HIDevicePath = TempDevicePath;
+      }
+
+      TempDevicePath = AppendDevicePathNode (HIDevicePath, DevicePath);
+      FreePool (HIDevicePath);
+      HIDevicePath = TempDevicePath;
+    } else {
+      NonHIDevicePathNodeCount++;
+    }
+    //
+    // Next device path node
+    //
+    DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) NextDevicePathNode (DevicePath);
+  }
+
+  return HIDevicePath;
+}
+
+EFI_STATUS
+GetDeviceConsistMappingInfo (
+  DEVICE_CONSIST_MAPPING_INFO    *MappingItem,
+  EFI_DEVICE_PATH_PROTOCOL       *DevicePath
+  )
+{
+  VOID (*SerialFun) (EFI_DEVICE_PATH_PROTOCOL *, DEVICE_CONSIST_MAPPING_INFO *);
+
+  UINTN Index;
+
+  ASSERT(DevicePath != NULL);
+  ASSERT(MappingItem != NULL);
+
+  SetMem (&MappingItem->CSD, sizeof (POOL_PRINT), 0);
+
+  while (!IsDevicePathEnd (DevicePath)) {
+    //
+    // Find the handler to dump this device path node
+    //
+    SerialFun = NULL;
+    for (Index = 0; DevPathConsistMappingTable[Index].SerialFun; Index += 1) {
+
+      if (DevicePathType (DevicePath) == DevPathConsistMappingTable[Index].Type &&
+          DevicePathSubType (DevicePath) == DevPathConsistMappingTable[Index].SubType
+          ) {
+        SerialFun = DevPathConsistMappingTable[Index].SerialFun;
+        break;
+      }
+    }
+    //
+    // If not found, use a generic function
+    //
+    if (!SerialFun) {
+      SerialFun = _DevPathSerialDefault;
+    }
+
+    SerialFun (DevicePath, MappingItem);
+
+    //
+    // Next device path node
+    //
+    DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) NextDevicePathNode (DevicePath);
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ConsistMappingCreateHIDevicePathTable (
+  EFI_DEVICE_PATH_PROTOCOL           ***HIDevicePathTable
+  )
+/*++
+
+Routine Description:
+
+  Create the empty mapping table.
+  
+Arguments:
+  
+  HIDevicePathTable - The device table
+  
+Returns: 
+  EFI_OUT_OF_RESOURCES - Out of resources
+  EFI_SUCCESS          - Success
+
+--*/
+{
+  EFI_HANDLE                *Handle;
+  UINTN                     HandleNum;
+  EFI_DEVICE_PATH_PROTOCOL  **Table;
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
+  EFI_DEVICE_PATH_PROTOCOL  *HIDevicePath;
+  UINTN                     Index;
+
+  Handle = NULL;
+
+  ShellInitHandleEnumerator ();
+  HandleNum = ShellGetHandleNum ();
+  Table     = AllocateZeroPool ((HandleNum + 1) * sizeof (EFI_DEVICE_PATH_PROTOCOL *));
+  if (HIDevicePathTable == NULL) {
+    ShellCloseHandleEnumerator ();
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  for (ShellNextHandle (&Handle); Handle != NULL; ShellNextHandle (&Handle)) {
+    DevicePath = DevicePathFromHandle (*Handle);
+    if (DevicePath == NULL) {
+      continue;
+    }
+
+    HIDevicePath = GetHIDevicePath (DevicePath);
+    if (HIDevicePath == NULL) {
+      continue;
+    }
+
+    for (Index = 0; Table[Index] != NULL; Index++) {
+      if (DevicePathCompare (Table[Index], HIDevicePath) == 0) {
+        FreePool (HIDevicePath);
+        break;
+      }
+    }
+
+    if (Table[Index] == NULL) {
+      Table[Index] = HIDevicePath;
+    }
+  }
+
+  ShellCloseHandleEnumerator ();
+  for (Index = 0; Table[Index] != NULL; Index++)
+    ;
+  DevicePathConsistMappingSort (Table, Index);
+  *HIDevicePathTable = Table;
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ConsistMappingFreeHIDevicePathTable (
+  EFI_DEVICE_PATH_PROTOCOL **HIDevicePathTable
+  )
+{
+  UINTN Index;
+  for (Index = 0; HIDevicePathTable[Index] != NULL; Index++) {
+    FreePool (HIDevicePathTable[Index]);
+  }
+
+  FreePool (HIDevicePathTable);
+  return EFI_SUCCESS;
+}
+
+CHAR16 *
+ConsistMappingGenMappingName (
+  EFI_DEVICE_PATH_PROTOCOL    *DevicePath,
+  EFI_DEVICE_PATH_PROTOCOL    **HIDevicePathTable
+  )
+{
+  POOL_PRINT                  Str;
+  DEVICE_CONSIST_MAPPING_INFO MappingInfo;
+  EFI_DEVICE_PATH_PROTOCOL    *HIDevicePath;
+  UINTN                       Index;
+  UINTN                       NewSize;
+  HIDevicePath = GetHIDevicePath (DevicePath);
+  if (HIDevicePath == NULL) {
+    return NULL;
+  }
+
+  for (Index = 0; HIDevicePathTable[Index] != NULL; Index++) {
+    if (DevicePathCompare (HIDevicePathTable[Index], HIDevicePath) == 0) {
+      break;
+    }
+  }
+
+  FreePool (HIDevicePath);
+  if (HIDevicePathTable[Index] == NULL) {
+    return NULL;
+  }
+
+  MappingInfo.HI      = Index;
+  MappingInfo.MTD     = MTDTypeUnknown;
+  MappingInfo.Digital = FALSE;
+
+  GetDeviceConsistMappingInfo (&MappingInfo, DevicePath);
+
+  SetMem (&Str, sizeof (Str), 0);
+  for (Index = 0; mMTDName[Index].MTDType != MTDTypeEnd; Index++) {
+    if (MappingInfo.MTD == mMTDName[Index].MTDType) {
+      break;
+    }
+  }
+
+  if (mMTDName[Index].MTDType != MTDTypeEnd) {
+    CatPrint (&Str, L"%s", mMTDName[Index].Name);
+  }
+
+  CatPrint (&Str, L"%d", MappingInfo.HI);
+  if (MappingInfo.CSD.str != NULL) {
+    CatPrint (&Str, L"%s", MappingInfo.CSD.str);
+  }
+
+  NewSize           = (Str.len + 1) * sizeof (CHAR16);
+  Str.str           = ReallocatePool (Str.str, NewSize, NewSize);
+  Str.str[Str.len]  = 0;
+  return Str.str;
+}
+
+BOOLEAN
+DevicePathIsChildDevice (
+  IN  EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,
+  IN  EFI_DEVICE_PATH_PROTOCOL *ChildDevicePath
+  )
+{
+  if (ParentDevicePath == NULL || ParentDevicePath == NULL) {
+    return FALSE;
+  }
+
+  while (!(IsDevicePathEnd (ParentDevicePath) || IsDevicePathEnd (ChildDevicePath))) {
+    if (_DevPathCompareDefault (ParentDevicePath, ChildDevicePath) != 0) {
+      return FALSE;
+    }
+
+    ParentDevicePath  = (EFI_DEVICE_PATH_PROTOCOL *) NextDevicePathNode (ParentDevicePath);
+    ChildDevicePath   = (EFI_DEVICE_PATH_PROTOCOL *) NextDevicePathNode (ChildDevicePath);
+  }
+
+  if (IsDevicePathEnd (ParentDevicePath)) {
+    return TRUE;
+  }
+
+  return FALSE;
+}
diff --git a/Library/ConsistMapping.h b/Library/ConsistMapping.h
new file mode 100644 (file)
index 0000000..38bba65
--- /dev/null
@@ -0,0 +1,82 @@
+/*++
+
+Copyright 2005, Intel Corporation                                                         
+All rights reserved. This program and the accompanying materials                          
+are licensed and made available under the terms and conditions of the BSD License         
+which accompanies this distribution. The full text of the license may be found at         
+http://opensource.org/licenses/bsd-license.php                                            
+                                                                                          
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+
+Module Name:
+
+  ConsistMapping.h
+
+Abstract:
+
+  Infomation about the library function support consist mapping.
+Revision History
+
+--*/
+#ifndef _CONSIST_MAPPING_H
+#define _CONSIST_MAPPING_H
+
+typedef enum {
+  MTDTypeUnknown,
+  MTDTypeFloppy,
+  MTDTypeHardDisk,
+  MTDTypeCDRom,
+  MTDTypeEnd
+} MTD_TYPE;
+
+typedef struct {
+  UINTN       HI;
+  MTD_TYPE    MTD;
+  POOL_PRINT  CSD;
+  BOOLEAN     Digital;
+} DEVICE_CONSIST_MAPPING_INFO;
+
+typedef struct {
+  MTD_TYPE  MTDType;
+  CHAR16    *Name;
+} MTD_NAME;
+
+typedef struct {
+  UINT8 Type;
+  UINT8 SubType;
+  VOID (*SerialFun) (EFI_DEVICE_PATH_PROTOCOL *, DEVICE_CONSIST_MAPPING_INFO *);
+  INTN (*CompareFun) (EFI_DEVICE_PATH_PROTOCOL *, EFI_DEVICE_PATH_PROTOCOL *);
+}
+DEV_PATH_CONSIST_MAPPING_TABLE;
+
+EFI_STATUS
+ConsistMappingCreateHIDevicePathTable (
+  EFI_DEVICE_PATH_PROTOCOL           ***HIDevicePathTable
+  );
+
+EFI_STATUS
+ConsistMappingFreeHIDevicePathTable (
+  EFI_DEVICE_PATH_PROTOCOL **HIDevicePathTable
+  );
+
+CHAR16  *
+ConsistMappingGenMappingName (
+  EFI_DEVICE_PATH_PROTOCOL    *Devicepath,
+  EFI_DEVICE_PATH_PROTOCOL    **HIDevicePathTable
+  );
+
+BOOLEAN
+DevicePathIsChildDevice (
+  IN  EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,
+  IN  EFI_DEVICE_PATH_PROTOCOL *ChildDevicePath
+  );
+
+INTN
+DevicePathConsistMappingCompare (
+  IN  VOID *Buffer1,
+  IN  VOID *Buffer2
+  );
+
+#endif
\ No newline at end of file
diff --git a/Library/DPath.c b/Library/DPath.c
new file mode 100644 (file)
index 0000000..71978ce
--- /dev/null
@@ -0,0 +1,1550 @@
+/*++
+
+Copyright 2005, Intel Corporation                                                         
+All rights reserved. This program and the accompanying materials                          
+are licensed and made available under the terms and conditions of the BSD License         
+which accompanies this distribution. The full text of the license may be found at         
+http://opensource.org/licenses/bsd-license.php                                            
+                                                                                          
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+
+Module Name:
+
+    DPath.c
+
+Abstract:
+    Device Path functions
+
+Revision History
+
+--*/
+
+#include "EfiShelllib.h"
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevicePathInstance (
+  IN OUT EFI_DEVICE_PATH_PROTOCOL             **DevicePath,
+  OUT UINTN                                   *Size
+  )
+/*++
+
+Routine Description:
+  Function retrieves the next device path instance from a device path data structure.
+
+Arguments:
+  DevicePath           - A pointer to a device path data structure.
+
+  Size                 - A pointer to the size of a device path instance in bytes.
+
+Returns:
+
+  This function returns a pointer to the current device path instance.  
+  In addition, it returns the size in bytes of the current device path instance in Size, 
+  and a pointer to the next device path instance in DevicePath.  
+  If there are no more device path instances in DevicePath, then DevicePath will be set to NULL.
+
+--*/
+{
+  EFI_DEVICE_PATH_PROTOCOL  *Start;
+  EFI_DEVICE_PATH_PROTOCOL  *Next;
+  EFI_DEVICE_PATH_PROTOCOL  *DevPath;
+  UINTN                     Count;
+
+  ASSERT (Size);
+
+  DevPath = *DevicePath;
+  Start   = DevPath;
+
+  if (!DevPath) {
+    return NULL;
+  }
+  //
+  // Check for end of device path type
+  //
+  for (Count = 0;; Count++) {
+    Next = (EFI_DEVICE_PATH_PROTOCOL *) NextDevicePathNode (DevPath);
+
+    if (IsDevicePathEndType (DevPath)) {
+      break;
+    }
+
+    if (Count > 01000) {
+      DEBUG (
+        (
+        EFI_D_ERROR, "DevicePathInstance Too Long : DevicePath %x Size %d", *DevicePath, ((UINT8 *) DevPath) -
+        ((UINT8 *) Start)
+        )
+        );
+      DumpHex (0, 0, ((UINT8 *) DevPath) - ((UINT8 *) Start), Start);
+      break;
+    }
+
+    DevPath = Next;
+  }
+
+  ASSERT (DevicePathSubType (DevPath) == END_ENTIRE_DEVICE_PATH_SUBTYPE || DevicePathSubType (DevPath) == END_INSTANCE_DEVICE_PATH_SUBTYPE);
+
+  //
+  // Set next position
+  //
+  if (DevicePathSubType (DevPath) == END_ENTIRE_DEVICE_PATH_SUBTYPE) {
+    Next = NULL;
+  }
+
+  *DevicePath = Next;
+
+  //
+  // Return size and start of device path instance
+  //
+  *Size = ((UINT8 *) DevPath) - ((UINT8 *) Start) + sizeof (EFI_DEVICE_PATH_PROTOCOL);
+  return Start;
+}
+
+UINTN
+DevicePathInstanceCount (
+  IN EFI_DEVICE_PATH_PROTOCOL      *DevicePath
+  )
+/*++
+
+Routine Description:
+  Function is used to determine the number of device path instances that exist in a device path.
+
+Arguments:
+  DevicePath           - A pointer to a device path data structure.
+
+Returns:
+
+  This function counts and returns the number of device path instances in DevicePath.
+
+--*/
+{
+  UINTN Count;
+  UINTN Size;
+
+  Count = 0;
+  while (DevicePathInstance (&DevicePath, &Size)) {
+    Count += 1;
+  }
+
+  return Count;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+AppendDevicePath (
+  IN EFI_DEVICE_PATH_PROTOCOL  *Src1,
+  IN EFI_DEVICE_PATH_PROTOCOL  *Src2
+  )
+/*++
+
+Routine Description:
+  Function is used to append a device path to all the instances in another device path.
+
+Arguments:
+  Src1           - A pointer to a device path data structure.
+
+  Src2           - A pointer to a device path data structure.
+
+Returns:
+
+  A pointer to the new device path is returned.  
+  NULL is returned if space for the new device path could not be allocated from pool. 
+  It is up to the caller to free the memory used by Src1 and Src2 if they are no longer needed.
+
+  Src1 may have multiple "instances" and each instance is appended
+  Src2 is appended to each instance is Src1.  (E.g., it's possible
+  to append a new instance to the complete device path by passing 
+  it in Src2)
+
+--*/
+{
+  UINTN                     Src1Size;
+  UINTN                     Src1Inst;
+  UINTN                     Src2Size;
+  UINTN                     Size;
+  EFI_DEVICE_PATH_PROTOCOL  *Dst;
+  EFI_DEVICE_PATH_PROTOCOL  *Inst;
+  UINT8                     *DstPos;
+
+  //
+  // If there's only 1 path, just duplicate it
+  //
+  if (!Src1) {
+    ASSERT (!IsDevicePathUnpacked (Src2));
+    return DuplicateDevicePath (Src2);
+  }
+
+  if (!Src2) {
+    ASSERT (!IsDevicePathUnpacked (Src1));
+    return DuplicateDevicePath (Src1);
+  }
+  //
+  // Verify we're not working with unpacked paths
+  //
+  //
+  // Append Src2 to every instance in Src1
+  //
+  Src1Size  = DevicePathSize (Src1);
+  Src1Inst  = DevicePathInstanceCount (Src1);
+  Src2Size  = DevicePathSize (Src2);
+  Size      = Src2Size * Src1Inst + Src1Size;
+  Size -= Src1Inst * sizeof (EFI_DEVICE_PATH_PROTOCOL);
+
+  Dst = AllocatePool (Size);
+  if (Dst) {
+    DstPos = (UINT8 *) Dst;
+
+    //
+    // Copy all device path instances
+    //
+    Inst = DevicePathInstance (&Src1, &Size);
+    while (Inst) {
+
+      CopyMem (DstPos, Inst, Size);
+      DstPos += Size - sizeof (EFI_DEVICE_PATH_PROTOCOL);
+
+      CopyMem (DstPos, Src2, Src2Size);
+      DstPos += Src2Size - sizeof (EFI_DEVICE_PATH_PROTOCOL);
+
+      SetDevicePathEndNode ((EFI_DEVICE_PATH_PROTOCOL *)DstPos);
+      ((EFI_DEVICE_PATH_PROTOCOL *)DstPos)->SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE; 
+      DstPos += sizeof (EFI_DEVICE_PATH_PROTOCOL);
+
+      Inst = DevicePathInstance (&Src1, &Size);
+    }
+    //
+    // Change last end marker
+    //
+    DstPos -= sizeof (EFI_DEVICE_PATH_PROTOCOL);
+    SetDevicePathEndNode ((EFI_DEVICE_PATH_PROTOCOL *)DstPos);
+  }
+
+  return Dst;
+}
+
+UINTN
+DevicePathSize (
+  IN EFI_DEVICE_PATH_PROTOCOL  *DevPath
+  )
+/*++
+
+Routine Description:
+  Function returns the size of a device path in bytes.
+
+Arguments:
+  DevPath        - A pointer to a device path data structure
+
+Returns:
+
+  Size is returned.
+
+--*/
+{
+  EFI_DEVICE_PATH_PROTOCOL  *Start;
+
+  ASSERT (DevPath != NULL);
+
+  //
+  // Search for the end of the device path structure
+  //
+  Start = DevPath;
+  while (!IsDevicePathEnd (DevPath)) {
+    DevPath = (EFI_DEVICE_PATH_PROTOCOL *) NextDevicePathNode (DevPath);
+  }
+  //
+  // Compute the size
+  //
+  return ((UINTN) DevPath - (UINTN) Start) + sizeof (EFI_DEVICE_PATH_PROTOCOL);
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevicePathFromHandle (
+  IN EFI_HANDLE       Handle
+  )
+/*++
+
+Routine Description:
+  Function retrieves the device path for the specified handle.  
+
+Arguments:
+  Handle           - Handle of the device
+
+Returns:
+
+  If Handle is valid, then a pointer to the device path is returned.  
+  If Handle is not valid, then NULL is returned.
+
+--*/
+{
+  EFI_STATUS                Status;
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
+
+  Status = BS->HandleProtocol (
+                Handle,
+                &gEfiDevicePathProtocolGuid,
+                (VOID *) &DevicePath
+                );
+
+  if (EFI_ERROR (Status)) {
+    DevicePath = NULL;
+  }
+
+  return DevicePath;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DuplicateDevicePath (
+  IN EFI_DEVICE_PATH_PROTOCOL  *DevPath
+  )
+/*++
+
+Routine Description:
+  Function creates a duplicate copy of an existing device path.
+
+Arguments:
+  DevPath        - A pointer to a device path data structure
+
+Returns:
+
+  If the memory is successfully allocated, then the contents of DevPath are copied 
+  to the newly allocated buffer, and a pointer to that buffer is returned.  
+  Otherwise, NULL is returned.
+
+--*/
+{
+  EFI_DEVICE_PATH_PROTOCOL  *NewDevPath;
+  UINTN                     Size;
+
+  ASSERT (DevPath);
+
+  //
+  // Compute the size
+  //
+  Size = DevicePathSize (DevPath);
+
+  //
+  // Make a copy
+  //
+  NewDevPath = AllocatePool (Size);
+  if (NewDevPath != NULL) {
+    CopyMem (NewDevPath, DevPath, Size);
+  }
+
+  return NewDevPath;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+UnpackDevicePath (
+  IN EFI_DEVICE_PATH_PROTOCOL  *DevPath
+  )
+/*++
+
+Routine Description:
+  Function unpacks a device path data structure so that all the nodes of a device path 
+  are naturally aligned.
+
+Arguments:
+  DevPath        - A pointer to a device path data structure
+
+Returns:
+
+  If the memory for the device path is successfully allocated, then a pointer to the 
+  new device path is returned.  Otherwise, NULL is returned.
+
+--*/
+{
+  EFI_DEVICE_PATH_PROTOCOL  *Src;
+  EFI_DEVICE_PATH_PROTOCOL  *Dest;
+  EFI_DEVICE_PATH_PROTOCOL  *NewPath;
+  UINTN                     Size;
+
+  if (DevPath == NULL) {
+    return NULL;
+  }
+  //
+  // Walk device path and round sizes to valid boundries
+  //
+  Src   = DevPath;
+  Size  = 0;
+  for (;;) {
+    Size += DevicePathNodeLength (Src);
+    Size += ALIGN_SIZE (Size);
+
+    if (IsDevicePathEnd (Src)) {
+      break;
+    }
+
+    Src = (EFI_DEVICE_PATH_PROTOCOL *) NextDevicePathNode (Src);
+  }
+  //
+  // Allocate space for the unpacked path
+  //
+  NewPath = AllocateZeroPool (Size);
+  if (NewPath != NULL) {
+
+    ASSERT (((UINTN) NewPath) % MIN_ALIGNMENT_SIZE == 0);
+
+    //
+    // Copy each node
+    //
+    Src   = DevPath;
+    Dest  = NewPath;
+    for (;;) {
+      Size = DevicePathNodeLength (Src);
+      CopyMem (Dest, Src, Size);
+      Size += ALIGN_SIZE (Size);
+      SetDevicePathNodeLength (Dest, Size);
+      Dest->Type |= EFI_DP_TYPE_UNPACKED;
+      Dest = (EFI_DEVICE_PATH_PROTOCOL *) (((UINT8 *) Dest) + Size);
+
+      if (IsDevicePathEnd (Src)) {
+        break;
+      }
+
+      Src = (EFI_DEVICE_PATH_PROTOCOL *) NextDevicePathNode (Src);
+    }
+  }
+
+  return NewPath;
+}
+
+VOID
+_DevPathPci (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  PCI_DEVICE_PATH *Pci;
+
+  ASSERT (Str != NULL);
+  ASSERT (DevPath != NULL);
+
+  Pci = DevPath;
+  CatPrint (Str, L"Pci(%x|%x)", Pci->Device, Pci->Function);
+}
+
+VOID
+_DevPathPccard (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  PCCARD_DEVICE_PATH  *Pccard;
+
+  ASSERT (Str != NULL);
+  ASSERT (DevPath != NULL);
+
+  Pccard = DevPath;
+  CatPrint (Str, L"Pccard(Function%x)", Pccard->FunctionNumber);
+}
+
+VOID
+_DevPathMemMap (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  MEMMAP_DEVICE_PATH  *MemMap;
+
+  ASSERT (Str != NULL);
+  ASSERT (DevPath != NULL);
+
+  MemMap = DevPath;
+  CatPrint (
+    Str,
+    L"MemMap(%d:%.lx-%.lx)",
+    MemMap->MemoryType,
+    MemMap->StartingAddress,
+    MemMap->EndingAddress
+    );
+}
+
+VOID
+_DevPathController (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  CONTROLLER_DEVICE_PATH  *Controller;
+
+  ASSERT (Str != NULL);
+  ASSERT (DevPath != NULL);
+
+  Controller = DevPath;
+  CatPrint (
+    Str,
+    L"Ctrl(%d)",
+    Controller->Controller
+    );
+}
+
+VOID
+_DevPathVendor (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  VENDOR_DEVICE_PATH                *Vendor;
+  CHAR16                            *Type;
+  UNKNOWN_DEVICE_VENDOR_DEVICE_PATH *UnknownDevPath;
+
+  ASSERT (Str != NULL);
+  ASSERT (DevPath != NULL);
+
+  Vendor = DevPath;
+  switch (DevicePathType (&Vendor->Header)) {
+  case HARDWARE_DEVICE_PATH:
+    Type = L"Hw";
+    break;
+
+  case MESSAGING_DEVICE_PATH:
+    Type = L"Msg";
+    break;
+
+  case MEDIA_DEVICE_PATH:
+    Type = L"Media";
+    break;
+
+  default:
+    Type = L"?";
+    break;
+  }
+
+  CatPrint (Str, L"Ven%s(%g", Type, &Vendor->Guid);
+  if (CompareGuid (&Vendor->Guid, &UnknownDeviceGuid) == 0) {
+    //
+    // GUID used by EFI to enumerate an EDD 1.1 device
+    //
+    UnknownDevPath = (UNKNOWN_DEVICE_VENDOR_DEVICE_PATH *) Vendor;
+    CatPrint (Str, L":%02x)", UnknownDevPath->LegacyDriveLetter);
+  } else {
+    CatPrint (Str, L")");
+  }
+}
+
+VOID
+_DevPathAcpi (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  ACPI_HID_DEVICE_PATH  *Acpi;
+
+  ASSERT (Str != NULL);
+  ASSERT (DevPath != NULL);
+
+  Acpi = DevPath;
+  if ((Acpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
+    CatPrint (Str, L"Acpi(PNP%04x,%x)", EISA_ID_TO_NUM (Acpi->HID), Acpi->UID);
+  } else {
+    CatPrint (Str, L"Acpi(%08x,%x)", Acpi->HID, Acpi->UID);
+  }
+}
+
+VOID
+_DevPathAtapi (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  ATAPI_DEVICE_PATH *Atapi;
+
+  ASSERT (Str != NULL);
+  ASSERT (DevPath != NULL);
+
+  Atapi = DevPath;
+  CatPrint (
+    Str,
+    L"Ata(%s,%s)",
+    Atapi->PrimarySecondary ? L"Secondary" : L"Primary",
+    Atapi->SlaveMaster ? L"Slave" : L"Master"
+    );
+}
+
+VOID
+_DevPathScsi (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  SCSI_DEVICE_PATH  *Scsi;
+
+  ASSERT (Str != NULL);
+  ASSERT (DevPath != NULL);
+
+  Scsi = DevPath;
+  CatPrint (Str, L"Scsi(Pun%x,Lun%x)", Scsi->Pun, Scsi->Lun);
+}
+
+VOID
+_DevPathFibre (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  FIBRECHANNEL_DEVICE_PATH  *Fibre;
+
+  ASSERT (Str != NULL);
+  ASSERT (DevPath != NULL);
+
+  Fibre = DevPath;
+  CatPrint (Str, L"Fibre(Wwn%lx,Lun%lx)", Fibre->WWN, Fibre->Lun);
+}
+
+VOID
+_DevPath1394 (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  F1394_DEVICE_PATH *F1394;
+  
+  ASSERT (Str != NULL);
+  ASSERT (DevPath != NULL);
+
+  F1394 = DevPath;
+  CatPrint (Str, L"1394(%lx)", &F1394->Guid);
+}
+
+VOID
+_DevPathUsb (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  USB_DEVICE_PATH *Usb;
+
+  ASSERT (Str != NULL);
+  ASSERT (DevPath != NULL);
+
+  Usb = DevPath;
+  CatPrint (Str, L"Usb(%x, %x)", Usb->ParentPortNumber, Usb->InterfaceNumber);
+}
+
+VOID
+_DevPathUsbClass (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  //
+  // tbd:
+  //
+  USB_CLASS_DEVICE_PATH *UsbClass;
+
+  ASSERT (Str != NULL);
+  ASSERT (DevPath != NULL);
+
+  UsbClass = DevPath;
+  CatPrint (
+    Str,
+    L"Usb Class(%x, %x, %x, %x, %x)",
+    UsbClass->VendorId,
+    UsbClass->ProductId,
+    UsbClass->DeviceClass,
+    UsbClass->DeviceSubClass,
+    UsbClass->DeviceProtocol
+    );
+}
+
+VOID
+_DevPathI2O (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  I2O_DEVICE_PATH *I2O;
+
+  ASSERT (Str != NULL);
+  ASSERT (DevPath != NULL);
+
+  I2O = DevPath;
+  CatPrint (Str, L"I2O(%x)", I2O->Tid);
+}
+
+VOID
+_DevPathMacAddr (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  MAC_ADDR_DEVICE_PATH  *MAC;
+  UINTN                 HwAddressSize;
+  UINTN                 Index;
+
+  ASSERT (Str != NULL);
+  ASSERT (DevPath != NULL);
+
+  MAC           = DevPath;
+
+  HwAddressSize = sizeof (EFI_MAC_ADDRESS);
+  if (MAC->IfType == 0x01 || MAC->IfType == 0x00) {
+    HwAddressSize = 6;
+  }
+
+  CatPrint (Str, L"Mac(");
+
+  for (Index = 0; Index < HwAddressSize; Index++) {
+    CatPrint (Str, L"%02x", MAC->MacAddress.Addr[Index]);
+  }
+
+  CatPrint (Str, L")");
+}
+
+VOID
+_DevPathIPv4 (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  IPv4_DEVICE_PATH  *IP;
+
+  ASSERT (Str != NULL);
+  ASSERT (DevPath != NULL);
+
+  IP = DevPath;
+  CatPrint (
+    Str,
+    L"IPv4(%d.%d.%d.%d:%d)",
+    IP->RemoteIpAddress.Addr[0],
+    IP->RemoteIpAddress.Addr[1],
+    IP->RemoteIpAddress.Addr[2],
+    IP->RemoteIpAddress.Addr[3],
+    IP->RemotePort
+    );
+}
+
+VOID
+_DevPathIPv6 (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  ASSERT (Str != NULL);
+
+  CatPrint (Str, L"IP-v6(not-done)");
+}
+
+VOID
+_DevPathInfiniBand (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  ASSERT (Str != NULL);
+
+  CatPrint (Str, L"InfiniBand(not-done)");
+}
+
+VOID
+_DevPathUart (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  UART_DEVICE_PATH  *Uart;
+  CHAR8             Parity;
+
+  ASSERT (Str != NULL);
+  ASSERT (DevPath != NULL);
+
+  Uart = DevPath;
+  switch (Uart->Parity) {
+  case 0:
+    Parity = 'D';
+    break;
+
+  case 1:
+    Parity = 'N';
+    break;
+
+  case 2:
+    Parity = 'E';
+    break;
+
+  case 3:
+    Parity = 'O';
+    break;
+
+  case 4:
+    Parity = 'M';
+    break;
+
+  case 5:
+    Parity = 'S';
+    break;
+
+  default:
+    Parity = 'x';
+    break;
+  }
+
+  if (Uart->BaudRate == 0) {
+    CatPrint (Str, L"Uart(DEFAULT %c", Parity);
+  } else {
+    CatPrint (Str, L"Uart(%ld %c", Uart->BaudRate, Parity);
+  }
+
+  if (Uart->DataBits == 0) {
+    CatPrint (Str, L"D");
+  } else {
+    CatPrint (Str, L"%d", Uart->DataBits);
+  }
+
+  switch (Uart->StopBits) {
+  case 0:
+    CatPrint (Str, L"D)");
+    break;
+
+  case 1:
+    CatPrint (Str, L"1)");
+    break;
+
+  case 2:
+    CatPrint (Str, L"1.5)");
+    break;
+
+  case 3:
+    CatPrint (Str, L"2)");
+    break;
+
+  default:
+    CatPrint (Str, L"x)");
+    break;
+  }
+}
+
+VOID
+_DevPathHardDrive (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  HARDDRIVE_DEVICE_PATH *Hd;
+
+  ASSERT (Str != NULL);
+  ASSERT (DevPath != NULL);
+
+  Hd = DevPath;
+  switch (Hd->SignatureType) {
+  case SIGNATURE_TYPE_MBR:
+    CatPrint (
+      Str,
+      L"HD(Part%d,Sig%08x)",
+      Hd->PartitionNumber,
+      *((UINT32 *) (&(Hd->Signature[0])))
+      );
+    break;
+
+  case SIGNATURE_TYPE_GUID:
+    CatPrint (
+      Str,
+      L"HD(Part%d,Sig%g)",
+      Hd->PartitionNumber,
+      (EFI_GUID *) &(Hd->Signature[0])
+      );
+    break;
+
+  default:
+    CatPrint (
+      Str,
+      L"HD(Part%d,MBRType=%02x,SigType=%02x)",
+      Hd->PartitionNumber,
+      Hd->MBRType,
+      Hd->SignatureType
+      );
+    break;
+  }
+}
+
+VOID
+_DevPathCDROM (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  CDROM_DEVICE_PATH *Cd;
+
+  ASSERT (Str != NULL);
+  ASSERT (DevPath != NULL);
+
+  Cd = DevPath;
+  CatPrint (Str, L"CDROM(Entry%x)", Cd->BootEntry);
+}
+
+VOID
+_DevPathFilePath (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  FILEPATH_DEVICE_PATH  *Fp;
+  UINTN                 Length;
+  CHAR16                *NewPath;
+
+  ASSERT (Str != NULL);
+  ASSERT (DevPath != NULL);
+
+  Fp      = DevPath;
+  Length  = EfiDevicePathNodeLength (((EFI_DEVICE_PATH_PROTOCOL *) DevPath)) - 4;
+  NewPath = AllocateZeroPool (Length + sizeof (CHAR16));
+  CopyMem (NewPath, Fp->PathName, Length);
+  StrTrim (NewPath, L' ');
+  CatPrint (Str, L"%s", NewPath);
+  FreePool (NewPath);
+}
+
+VOID
+_DevPathMediaProtocol (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  MEDIA_PROTOCOL_DEVICE_PATH  *MediaProt;
+
+  ASSERT (Str != NULL);
+  ASSERT (DevPath != NULL);
+
+  MediaProt = DevPath;
+  CatPrint (Str, L"%g", &MediaProt->Protocol);
+}
+
+VOID
+_DevPathFvFilePath (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvFilePath;
+
+  ASSERT (Str != NULL);
+  ASSERT (DevPath != NULL);
+
+  FvFilePath = DevPath;
+  CatPrint (Str, L"%g", &FvFilePath->NameGuid);
+}
+
+VOID
+_DevPathBssBss (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  BBS_BBS_DEVICE_PATH *BBS;
+  CHAR16              *Type;
+
+  ASSERT (Str != NULL);
+  ASSERT (DevPath != NULL);
+
+  BBS = DevPath;
+  switch (BBS->DeviceType) {
+  case BBS_TYPE_FLOPPY:
+    Type = L"Floppy";
+    break;
+
+  case BBS_TYPE_HARDDRIVE:
+    Type = L"Harddrive";
+    break;
+
+  case BBS_TYPE_CDROM:
+    Type = L"CDROM";
+    break;
+
+  case BBS_TYPE_PCMCIA:
+    Type = L"PCMCIA";
+    break;
+
+  case BBS_TYPE_USB:
+    Type = L"Usb";
+    break;
+
+  case BBS_TYPE_EMBEDDED_NETWORK:
+    Type = L"Net";
+    break;
+
+  default:
+    Type = L"?";
+    break;
+  }
+
+  CatPrint (Str, L"BBS-%s(%a)", Type, BBS->String);
+}
+
+VOID
+_DevPathEndInstance (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  ASSERT (Str != NULL);
+
+  CatPrint (Str, L",");
+}
+
+VOID
+_DevPathNodeUnknown (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  ASSERT (Str != NULL);
+
+  CatPrint (Str, L"?");
+}
+
+struct {
+  UINT8 Type;
+  UINT8 SubType;
+  VOID (*Function) (POOL_PRINT *, VOID *);
+} 
+DevPathTable[] = {
+  HARDWARE_DEVICE_PATH,
+  HW_PCI_DP,
+  _DevPathPci,
+  HARDWARE_DEVICE_PATH,
+  HW_PCCARD_DP,
+  _DevPathPccard,
+  HARDWARE_DEVICE_PATH,
+  HW_MEMMAP_DP,
+  _DevPathMemMap,
+  HARDWARE_DEVICE_PATH,
+  HW_VENDOR_DP,
+  _DevPathVendor,
+  HARDWARE_DEVICE_PATH,
+  HW_CONTROLLER_DP,
+  _DevPathController,
+  ACPI_DEVICE_PATH,
+  ACPI_DP,
+  _DevPathAcpi,
+  MESSAGING_DEVICE_PATH,
+  MSG_ATAPI_DP,
+  _DevPathAtapi,
+  MESSAGING_DEVICE_PATH,
+  MSG_SCSI_DP,
+  _DevPathScsi,
+  MESSAGING_DEVICE_PATH,
+  MSG_FIBRECHANNEL_DP,
+  _DevPathFibre,
+  MESSAGING_DEVICE_PATH,
+  MSG_1394_DP,
+  _DevPath1394,
+  MESSAGING_DEVICE_PATH,
+  MSG_USB_DP,
+  _DevPathUsb,
+  MESSAGING_DEVICE_PATH,
+  MSG_USB_CLASS_DP,
+  _DevPathUsbClass,
+  MESSAGING_DEVICE_PATH,
+  MSG_I2O_DP,
+  _DevPathI2O,
+  MESSAGING_DEVICE_PATH,
+  MSG_MAC_ADDR_DP,
+  _DevPathMacAddr,
+  MESSAGING_DEVICE_PATH,
+  MSG_IPv4_DP,
+  _DevPathIPv4,
+  MESSAGING_DEVICE_PATH,
+  MSG_IPv6_DP,
+  _DevPathIPv6,
+  MESSAGING_DEVICE_PATH,
+  MSG_INFINIBAND_DP,
+  _DevPathInfiniBand,
+  MESSAGING_DEVICE_PATH,
+  MSG_UART_DP,
+  _DevPathUart,
+  MESSAGING_DEVICE_PATH,
+  MSG_VENDOR_DP,
+  _DevPathVendor,
+  MEDIA_DEVICE_PATH,
+  MEDIA_HARDDRIVE_DP,
+  _DevPathHardDrive,
+  MEDIA_DEVICE_PATH,
+  MEDIA_CDROM_DP,
+  _DevPathCDROM,
+  MEDIA_DEVICE_PATH,
+  MEDIA_VENDOR_DP,
+  _DevPathVendor,
+  MEDIA_DEVICE_PATH,
+  MEDIA_FILEPATH_DP,
+  _DevPathFilePath,
+  MEDIA_DEVICE_PATH,
+  MEDIA_PROTOCOL_DP,
+  _DevPathMediaProtocol,
+  MEDIA_DEVICE_PATH,
+  MEDIA_FV_FILEPATH_DP,
+  _DevPathFvFilePath,
+  BBS_DEVICE_PATH,
+  BBS_BBS_DP,
+  _DevPathBssBss,
+  END_DEVICE_PATH_TYPE,
+  END_INSTANCE_DEVICE_PATH_SUBTYPE,
+  _DevPathEndInstance,
+  0,
+  0,
+  NULL
+};
+
+CHAR16 *
+LibDevicePathToStr (
+  IN EFI_DEVICE_PATH_PROTOCOL     *DevPath
+  )
+/*++
+Routine Description:
+    Turns the Device Path into a printable string.  Allcoates
+    the string from pool.  The caller must FreePool the returned
+    string.
+    
+Arguments:
+    Devpath      -  The devices
+    
+Returns:
+    The name of the devpath
+
+--*/
+{
+  POOL_PRINT                Str;
+  EFI_DEVICE_PATH_PROTOCOL  *DevPathNode;
+  VOID (*DumpNode) (POOL_PRINT *, VOID *);
+
+  UINTN Index;
+  UINTN NewSize;
+
+  ZeroMem (&Str, sizeof (Str));
+
+  if (DevPath == NULL) {
+    goto Done;
+  }
+  //
+  // Unpacked the device path
+  //
+  DevPath = UnpackDevicePath (DevPath);
+  ASSERT (DevPath);
+
+  //
+  // Process each device path node
+  //
+  DevPathNode = DevPath;
+  while (!IsDevicePathEnd (DevPathNode)) {
+    //
+    // Find the handler to dump this device path node
+    //
+    DumpNode = NULL;
+    for (Index = 0; DevPathTable[Index].Function; Index += 1) {
+
+      if (DevicePathType (DevPathNode) == DevPathTable[Index].Type &&
+          DevicePathSubType (DevPathNode) == DevPathTable[Index].SubType
+          ) {
+        DumpNode = DevPathTable[Index].Function;
+        break;
+      }
+    }
+    //
+    // If not found, use a generic function
+    //
+    if (!DumpNode) {
+      DumpNode = _DevPathNodeUnknown;
+    }
+    //
+    //  Put a path seperator in if needed
+    //
+    if (Str.len && DumpNode != _DevPathEndInstance) {
+      CatPrint (&Str, L"/");
+    }
+    //
+    // Print this node of the device path
+    //
+    DumpNode (&Str, DevPathNode);
+
+    //
+    // Next device path node
+    //
+    DevPathNode = (EFI_DEVICE_PATH_PROTOCOL *) NextDevicePathNode (DevPathNode);
+  }
+  //
+  // Shrink pool used for string allocation
+  //
+  FreePool (DevPath);
+Done:
+  NewSize           = (Str.len + 1) * sizeof (CHAR16);
+  Str.str           = ReallocatePool (Str.str, NewSize, NewSize);
+  ASSERT(Str.str != NULL);
+  Str.str[Str.len]  = 0;
+  return Str.str;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+AppendDevicePathNode (
+  IN EFI_DEVICE_PATH_PROTOCOL  *Src1,
+  IN EFI_DEVICE_PATH_PROTOCOL  *Src2
+  )
+/*++
+
+Routine Description:
+  Function is used to append a device path node to all the instances in another device path.
+
+Arguments:
+  Src1           - A pointer to a device path data structure.
+
+  Src2           - A pointer to a device path data structure.
+
+Returns:
+
+  This function returns a pointer to the new device path.  
+  If there is not enough temporary pool memory available to complete this function, 
+  then NULL is returned.
+
+  Src1 may have multiple "instances" and each instance is appended
+  Src2 is a signal device path node (without a terminator) that is
+  appended to each instance is Src1.
+
+--*/
+{
+  EFI_DEVICE_PATH_PROTOCOL  *Temp;
+
+  EFI_DEVICE_PATH_PROTOCOL  *Eop;
+  UINTN                     Length;
+  
+  ASSERT (Src1);
+  ASSERT (Src2);
+  //
+  // Build a Src2 that has a terminator on it
+  //
+  Length  = DevicePathNodeLength (Src2);
+  Temp    = AllocatePool (Length + sizeof (EFI_DEVICE_PATH_PROTOCOL));
+  if (!Temp) {
+    return NULL;
+  }
+
+  CopyMem (Temp, Src2, Length);
+  Eop = NextDevicePathNode (Temp);
+  SetDevicePathEndNode (Eop);
+
+  //
+  // Append device paths
+  //
+  Src1 = AppendDevicePath (Src1, Temp);
+  FreePool (Temp);
+  return Src1;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+FileDevicePath (
+  IN EFI_HANDLE                 Device  OPTIONAL,
+  IN CHAR16                     *FileName
+  )
+/*++
+
+Routine Description:
+  Function allocates a device path for a file and appends it to an existing device path.
+
+Arguments:
+  Device         - A pointer to a device handle.
+
+  FileName       - A pointer to a Null-terminated Unicode string.
+
+Returns:
+
+  If Device is not a valid device handle, then a device path for the file specified 
+  by FileName is allocated and returned.
+
+  Results are allocated from pool.  The caller must FreePool the resulting device path 
+  structure
+
+--*/
+{
+  UINTN                     Size;
+  FILEPATH_DEVICE_PATH      *FilePath;
+  EFI_DEVICE_PATH_PROTOCOL  *Eop;
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
+
+  ASSERT (FileName);
+
+  Size        = StrSize (FileName);
+  FilePath    = AllocateZeroPool (Size + SIZE_OF_FILEPATH_DEVICE_PATH + sizeof (EFI_DEVICE_PATH_PROTOCOL));
+  DevicePath  = NULL;
+
+  if (FilePath != NULL) {
+    //
+    // Build a file path
+    //
+    FilePath->Header.Type     = MEDIA_DEVICE_PATH;
+    FilePath->Header.SubType  = MEDIA_FILEPATH_DP;
+    SetDevicePathNodeLength (&FilePath->Header, Size + SIZE_OF_FILEPATH_DEVICE_PATH);
+    CopyMem (FilePath->PathName, FileName, Size);
+    Eop = NextDevicePathNode (&FilePath->Header);
+    SetDevicePathEndNode (Eop);
+
+    //
+    // Append file path to device's device path
+    //
+    DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) FilePath;
+    if (Device) {
+      DevicePath = AppendDevicePath (
+                    DevicePathFromHandle (Device),
+                    DevicePath
+                    );
+      FreePool (FilePath);
+
+      ASSERT (DevicePath);
+    }
+  }
+
+  return DevicePath;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+AppendDevicePathInstance (
+  IN EFI_DEVICE_PATH_PROTOCOL  *Src,
+  IN EFI_DEVICE_PATH_PROTOCOL  *Instance
+  )
+/*++
+
+Routine Description:
+  Function is used to add a device path instance to a device path.
+
+Arguments:
+  Src          - A pointer to a device path data structure
+
+  Instance     - A pointer to a device path instance.
+
+Returns:
+
+  This function returns a pointer to the new device path. 
+  If there is not enough temporary pool memory available to complete this function, 
+  then NULL is returned. It is up to the caller to free the memory used by Src and 
+  Instance if they are no longer needed.
+
+--*/
+{
+  UINT8                     *Ptr;
+  EFI_DEVICE_PATH_PROTOCOL  *DevPath;
+  UINTN                     SrcSize;
+  UINTN                     InstanceSize;
+
+  ASSERT (Instance);
+
+  if (Src == NULL) {
+    return DuplicateDevicePath (Instance);
+  }
+
+  SrcSize       = DevicePathSize (Src);
+  InstanceSize  = DevicePathSize (Instance);
+  Ptr           = AllocatePool (SrcSize + InstanceSize);
+  DevPath       = (EFI_DEVICE_PATH_PROTOCOL *) Ptr;
+  ASSERT (DevPath);
+
+  CopyMem (Ptr, Src, SrcSize);
+  while (!IsDevicePathEnd (DevPath)) {
+    DevPath = NextDevicePathNode (DevPath);
+  }
+  //
+  // Convert the End to an End Instance, since we are
+  //  appending another instacne after this one its a good
+  //  idea.
+  //
+  DevPath->SubType  = END_INSTANCE_DEVICE_PATH_SUBTYPE;
+
+  DevPath           = NextDevicePathNode (DevPath);
+  CopyMem (DevPath, Instance, InstanceSize);
+  return (EFI_DEVICE_PATH_PROTOCOL *) Ptr;
+}
+
+EFI_STATUS
+LibDevicePathToInterface (
+  IN EFI_GUID                   *Protocol,
+  IN EFI_DEVICE_PATH_PROTOCOL   *FilePath,
+  OUT VOID                      **Interface
+  )
+/*++
+
+Routine Description:
+  Function retrieves a protocol interface for a device.
+
+Arguments:
+  Protocol     - The published unique identifier of the protocol.
+
+  FilePath     - A pointer to a device path data structure.
+
+  Interface    - Supplies and address where a pointer to the requested 
+                 Protocol interface is returned.
+
+Returns:
+
+  If a match is found, then the protocol interface of that device is 
+  returned in Interface.  Otherwise, Interface is set to NULL.
+
+--*/
+{
+  EFI_STATUS  Status;
+  EFI_HANDLE  Device;
+  
+  ASSERT (FilePath != NULL);
+  ASSERT (Interface != NULL);
+
+  Status = BS->LocateDevicePath (
+                Protocol,
+                &FilePath,
+                &Device
+                );
+
+  if (!EFI_ERROR (Status)) {
+    //
+    // If we didn't get a direct match return not found
+    //
+    Status = EFI_NOT_FOUND;
+
+    if (IsDevicePathEnd (FilePath)) {
+      //
+      // It was a direct match, lookup the protocol interface
+      //
+      Status = BS->HandleProtocol (
+                    Device,
+                    Protocol,
+                    Interface
+                    );
+    }
+  }
+  //
+  // If there was an error, do not return an interface
+  //
+  if (EFI_ERROR (Status)) {
+    *Interface = NULL;
+  }
+
+  return Status;
+}
+
+BOOLEAN
+LibMatchDevicePaths (
+  IN  EFI_DEVICE_PATH_PROTOCOL *Multi,
+  IN  EFI_DEVICE_PATH_PROTOCOL *Single
+  )
+/*++
+
+Routine Description:
+  Function compares a device path data structure to that of all the nodes of a 
+  second device path instance.
+
+Arguments:
+  Multi        - A pointer to a multi-instance device path data structure.
+
+  Single       - A pointer to a single-instance device path data structure.
+
+Returns:
+
+  The function returns TRUE if the Single is contained within Multi.  
+  Otherwise, FALSE is returned.
+
+--*/
+{
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
+
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePathInst;
+  UINTN                     Size;
+
+  if (!Multi || !Single) {
+    return FALSE;
+  }
+
+  DevicePath      = Multi;
+  DevicePathInst  = DevicePathInstance (&DevicePath, &Size);
+  while (DevicePathInst) {
+    if (CompareMem (Single, DevicePathInst, Size - sizeof (EFI_DEVICE_PATH_PROTOCOL)) == 0) {
+      return TRUE;
+    }
+
+    DevicePathInst = DevicePathInstance (&DevicePath, &Size);
+  }
+
+  return FALSE;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+LibDuplicateDevicePathInstance (
+  IN EFI_DEVICE_PATH_PROTOCOL  *DevPath
+  )
+/*++
+
+Routine Description:
+  Function creates a device path data structure that identically matches the 
+  device path passed in.
+
+Arguments:
+  DevPath      - A pointer to a device path data structure.
+
+Returns:
+
+  The new copy of DevPath is created to identically match the input.  
+  Otherwise, NULL is returned.
+
+--*/
+{
+  EFI_DEVICE_PATH_PROTOCOL  *NewDevPath;
+
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePathInst;
+
+  EFI_DEVICE_PATH_PROTOCOL  *Temp;
+  UINTN                     Size;
+
+  ASSERT (DevPath != NULL);
+  //
+  // get the size of an instance from the input
+  //
+  Temp            = DevPath;
+  DevicePathInst  = DevicePathInstance (&Temp, &Size);
+
+  //
+  // Make a copy
+  //
+  NewDevPath = NULL;
+  if (Size != 0) {
+    NewDevPath = AllocatePool (Size);
+  }
+
+  if (NewDevPath != NULL) {
+    CopyMem (NewDevPath, DevicePathInst, Size);
+  }
+
+  return NewDevPath;
+}
+
+INTN
+DevicePathCompare (
+  IN  EFI_DEVICE_PATH_PROTOCOL *DevicePath1,
+  IN  EFI_DEVICE_PATH_PROTOCOL *DevicePath2
+  )
+/*++
+
+Routine Description:
+  Function compares two device pathes.
+
+Arguments:
+  DevicePath1  - A pointer to a device path data structure.
+
+  DevicePath2  - A pointer to a device path data structure.
+
+Returns:
+
+  The function returns 0 if the two device paths are equal.
+  Otherwise, other value is returned.
+
+--*/
+{
+  UINTN DevPathSize1;
+  UINTN DevPathSize2;
+  
+  ASSERT (DevicePath1);
+  ASSERT (DevicePath2);
+
+  DevPathSize1  = DevicePathSize (DevicePath1);
+  DevPathSize2  = DevicePathSize (DevicePath2);
+
+  if (DevPathSize1 > DevPathSize2) {
+    return 1;
+  } else if (DevPathSize1 < DevPathSize2) {
+    return -1;
+  } else {
+    return CompareMem (DevicePath1, DevicePath2, DevPathSize1);
+  }
+}
+
diff --git a/Library/DPath.h b/Library/DPath.h
new file mode 100644 (file)
index 0000000..dc5d096
--- /dev/null
@@ -0,0 +1,110 @@
+/*++
+
+Copyright 2005, Intel Corporation                                                         
+All rights reserved. This program and the accompanying materials                          
+are licensed and made available under the terms and conditions of the BSD License         
+which accompanies this distribution. The full text of the license may be found at         
+http://opensource.org/licenses/bsd-license.php                                            
+                                                                                          
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+
+Module Name:
+
+    DPath.c
+
+Abstract:
+    Infomation about device path functions
+
+
+
+Revision History
+
+--*/
+#ifndef _D_PATH_H
+#define _D_PATH_H
+EFI_DEVICE_PATH_PROTOCOL  *
+DevicePathFromHandle (
+  IN EFI_HANDLE           Handle
+  );
+
+EFI_DEVICE_PATH_PROTOCOL  *
+DevicePathInstance (
+  IN OUT EFI_DEVICE_PATH_PROTOCOL  **DevicePath,
+  OUT UINTN                        *Size
+  );
+
+EFI_DEVICE_PATH_PROTOCOL  *
+AppendDevicePath (
+  IN EFI_DEVICE_PATH_PROTOCOL      *Src1,
+  IN EFI_DEVICE_PATH_PROTOCOL      *Src2
+  );
+
+UINTN
+DevicePathSize (
+  IN EFI_DEVICE_PATH_PROTOCOL      *DevPath
+  );
+
+EFI_DEVICE_PATH_PROTOCOL  *
+UnpackDevicePath (
+  IN EFI_DEVICE_PATH_PROTOCOL      *DevPath
+  );
+
+BOOLEAN
+LibMatchDevicePaths (
+  IN  EFI_DEVICE_PATH_PROTOCOL      *Multi,
+  IN  EFI_DEVICE_PATH_PROTOCOL      *Single
+  );
+
+EFI_DEVICE_PATH_PROTOCOL          *
+LibDuplicateDevicePathInstance (
+  IN EFI_DEVICE_PATH_PROTOCOL       *DevPath
+  );
+
+UINTN
+DevicePathInstanceCount (
+  IN EFI_DEVICE_PATH_PROTOCOL       *DevicePath
+  );
+
+EFI_DEVICE_PATH_PROTOCOL          *
+AppendDevicePathNode (
+  IN EFI_DEVICE_PATH_PROTOCOL       *Src1,
+  IN EFI_DEVICE_PATH_PROTOCOL       *Src2
+  );
+
+EFI_DEVICE_PATH_PROTOCOL          *
+AppendDevicePathInstance (
+  IN EFI_DEVICE_PATH_PROTOCOL       *Src,
+  IN EFI_DEVICE_PATH_PROTOCOL       *Instance
+  );
+
+EFI_DEVICE_PATH_PROTOCOL          *
+FileDevicePath (
+  IN EFI_HANDLE                               Device  OPTIONAL,
+  IN CHAR16                                   *FileName
+  );
+
+EFI_DEVICE_PATH_PROTOCOL          *
+DuplicateDevicePath (
+  IN EFI_DEVICE_PATH_PROTOCOL       *DevPath
+  );
+
+EFI_STATUS
+LibDevicePathToInterface (
+  IN EFI_GUID                       *Protocol,
+  IN EFI_DEVICE_PATH_PROTOCOL       *FilePath,
+  OUT VOID                          **Interface
+  );
+
+CHAR16                                *
+LibDevicePathToStr (
+  IN EFI_DEVICE_PATH_PROTOCOL         *DevPath
+  );
+
+INTN
+DevicePathCompare (
+  IN  EFI_DEVICE_PATH_PROTOCOL *DevicePath1,
+  IN  EFI_DEVICE_PATH_PROTOCOL *DevicePath2
+  );
+
+#endif
\ No newline at end of file
diff --git a/Library/Data.c b/Library/Data.c
new file mode 100644 (file)
index 0000000..81d4827
--- /dev/null
@@ -0,0 +1,82 @@
+/*++
+
+Copyright 2005, Intel Corporation                                                         
+All rights reserved. This program and the accompanying materials                          
+are licensed and made available under the terms and conditions of the BSD License         
+which accompanies this distribution. The full text of the license may be found at         
+http://opensource.org/licenses/bsd-license.php                                            
+                                                                                          
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+
+Module Name:
+
+    Data.c
+
+Abstract:
+
+    EFI library global data
+
+Revision History
+
+--*/
+
+#include "EfiShelllib.h"
+
+//
+// ShellLibInitialized - TRUE once InitializeShellLib() is called for the first time
+//
+BOOLEAN                         ShellLibInitialized = FALSE;
+
+//
+// ST - pointer to the EFI system table
+//
+EFI_SYSTEM_TABLE                *ST;
+
+//
+// BS - pointer to the boot services table
+//
+EFI_BOOT_SERVICES               *BS;
+
+EFI_SHELL_INTERFACE             *SI;
+
+EFI_SHELL_ENVIRONMENT           *SE;
+
+EFI_SHELL_ENVIRONMENT2          *SE2;
+
+//
+// Default pool allocation type
+//
+EFI_MEMORY_TYPE                 PoolAllocationType = EfiBootServicesData;
+
+//
+// Unicode collation functions that are in use
+//
+EFI_UNICODE_COLLATION_PROTOCOL  LibStubUnicodeInterface = {
+  LibStubStriCmp,
+  LibStubMetaiMatch,
+  LibStubStrLwr,
+  LibStubStrUpr,
+  NULL, // FatToStr
+  NULL, // StrToFat
+  NULL  // SupportedLanguages
+};
+
+EFI_UNICODE_COLLATION_PROTOCOL  *UnicodeInterface = &LibStubUnicodeInterface;
+
+EFI_GUID                        ShellEnvProtocol = SHELL_ENVIRONMENT_INTERFACE_PROTOCOL;
+
+EFI_DEVICE_PATH_PROTOCOL        LibEndDevicePath[] = {
+  END_DEVICE_PATH_TYPE,
+  END_ENTIRE_DEVICE_PATH_SUBTYPE,
+  END_DEVICE_PATH_LENGTH,
+  0
+};
+
+//
+// protocol GUIDs and other miscellaneous GUIDs
+//
+EFI_GUID                        NullGuid                  = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+EFI_GUID                        UnknownDeviceGuid         = UNKNOWN_DEVICE_GUID;
+EFI_GUID                        gEfiMpsTableGuid          = EFI_MPS_TABLE_GUID;
+
diff --git a/Library/Ebc/EfiLibPlat.h b/Library/Ebc/EfiLibPlat.h
new file mode 100644 (file)
index 0000000..a21f30b
--- /dev/null
@@ -0,0 +1,46 @@
+/*++
+
+Copyright 2005, Intel Corporation                                                         
+All rights reserved. This program and the accompanying materials                          
+are licensed and made available under the terms and conditions of the BSD License         
+which accompanies this distribution. The full text of the license may be found at         
+http://opensource.org/licenses/bsd-license.php                                            
+                                                                                          
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+
+Module Name:
+
+    efilibplat.h
+
+Abstract:
+
+    EBC specific defines
+
+--*/
+
+// GC_TODO: add protective #ifndef
+VOID
+InitializeLibPlatform (
+  IN EFI_HANDLE           ImageHandle,
+  IN EFI_SYSTEM_TABLE     *SystemTable
+  )
+/*++
+
+Routine Description:
+
+  GC_TODO: Add function description
+
+Arguments:
+
+  ImageHandle - GC_TODO: add argument description
+  SystemTable - GC_TODO: add argument description
+
+Returns:
+
+  GC_TODO: add return values
+
+--*/
+;
+
+#define MIN_ALIGNMENT_SIZE  8
diff --git a/Library/Ebc/initplat.c b/Library/Ebc/initplat.c
new file mode 100644 (file)
index 0000000..aed9b4b
--- /dev/null
@@ -0,0 +1,35 @@
+/*++
+
+Copyright 2005, Intel Corporation                                                         
+All rights reserved. This program and the accompanying materials                          
+are licensed and made available under the terms and conditions of the BSD License         
+which accompanies this distribution. The full text of the license may be found at         
+http://opensource.org/licenses/bsd-license.php                                            
+                                                                                          
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+
+Module Name:
+
+    initplat.c
+
+Abstract:
+
+
+
+
+Revision History
+
+--*/
+
+#include "EfiShellLib.h"
+
+VOID
+InitializeLibPlatform (
+  IN EFI_HANDLE           ImageHandle,
+  IN EFI_SYSTEM_TABLE     *SystemTable
+  )
+
+{
+  return;
+}
diff --git a/Library/Ebc/math.c b/Library/Ebc/math.c
new file mode 100644 (file)
index 0000000..afeef9b
--- /dev/null
@@ -0,0 +1,129 @@
+/*++
+
+Copyright 2005, Intel Corporation                                                         
+All rights reserved. This program and the accompanying materials                          
+are licensed and made available under the terms and conditions of the BSD License         
+which accompanies this distribution. The full text of the license may be found at         
+http://opensource.org/licenses/bsd-license.php                                            
+                                                                                          
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+
+Module Name:
+  
+    math.c
+
+Abstract:
+
+  Math routines for compatibility with native EFI library routines.
+  
+--*/
+
+#include "Tiano.h"
+
+UINT64
+RShiftU64 (
+  IN UINT64   Operand,
+  IN UINTN    Count
+  )
+/*++
+
+Routine Description:
+
+  GC_TODO: Add function description
+
+Arguments:
+
+  Operand - GC_TODO: add argument description
+  Count   - GC_TODO: add argument description
+
+Returns:
+
+  GC_TODO: add return values
+
+--*/
+{
+  return Operand >> Count;
+}
+
+UINT64
+LShiftU64 (
+  IN UINT64   Operand,
+  IN UINTN    Count
+  )
+/*++
+Routine Description:
+
+  Left shift 64bit by 32bit and get a 64bit result
+
+Arguments:
+
+  Operand - Operand
+  Count   - Shift count
+
+Returns:
+
+--*/
+{
+  return Operand << Count;
+}
+
+UINT64
+DivU64x32 (
+  IN UINT64   Dividend,
+  IN UINTN    Divisor,
+  OUT UINTN   *Remainder OPTIONAL
+  )
+/*++
+
+Routine Description:
+
+  GC_TODO: Add function description
+
+Arguments:
+
+  Dividend  - GC_TODO: add argument description
+  Divisor   - GC_TODO: add argument description
+  Remainder - GC_TODO: add argument description
+
+Returns:
+
+  GC_TODO: add return values
+
+--*/
+{
+  ASSERT (Divisor != 0);
+
+  //
+  // Have to compute twice if remainder. No support for
+  // divide-with-remainder in VM.
+  //
+  if (Remainder != NULL) {
+    *Remainder = Dividend % Divisor;
+  }
+
+  return Dividend / Divisor;
+}
+
+UINT64
+MultU64x32 (
+  IN UINT64   Multiplicand,
+  IN UINTN    Multiplier
+  )
+/*++
+Routine Description:
+
+  Multiple 64bit by 32bit and get a 64bit result
+  
+Arguments:
+
+  Multiplicand - Multiplicand
+  Multiplier   - Multiplier
+
+Returns:
+
+--*/
+{
+  return Multiplicand * Multiplier;
+}
+
diff --git a/Library/EfiPart.h b/Library/EfiPart.h
new file mode 100644 (file)
index 0000000..0e2078d
--- /dev/null
@@ -0,0 +1,58 @@
+/*++
+
+Copyright 2005, Intel Corporation                                                         
+All rights reserved. This program and the accompanying materials                          
+are licensed and made available under the terms and conditions of the BSD License         
+which accompanies this distribution. The full text of the license may be found at         
+http://opensource.org/licenses/bsd-license.php                                            
+                                                                                          
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+
+Module Name:
+
+  efipart.h
+    
+Abstract:   
+  Info about disk partitions and Master Boot Records
+
+Revision History
+
+--*/
+#ifndef _EFI_PART_H
+#define _EFI_PART_H
+
+#define EFI_PARTITION 0xef
+#define MBR_SIZE      512
+
+#pragma pack(1)
+
+typedef struct {
+  UINT8 BootIndicator;
+  UINT8 StartHead;
+  UINT8 StartSector;
+  UINT8 StartTrack;
+  UINT8 OSIndicator;
+  UINT8 EndHead;
+  UINT8 EndSector;
+  UINT8 EndTrack;
+  UINT8 StartingLBA[4];
+  UINT8 SizeInLBA[4];
+} MBR_PARTITION_RECORD;
+
+#define EXTRACT_UINT32(D)   (UINT32) (D[0] | (D[1] << 8) | (D[2] << 16) | (D[3] << 24))
+
+#define MBR_SIGNATURE       0xaa55
+#define MIN_MBR_DEVICE_SIZE 0x80000
+#define MBR_ERRATA_PAD      0x40000 // 128 MB
+#define MAX_MBR_PARTITIONS  4
+typedef struct {
+  UINT8                 BootStrapCode[440];
+  UINT8                 UniqueMbrSignature[4];
+  UINT8                 Unknown[2];
+  MBR_PARTITION_RECORD  Partition[MAX_MBR_PARTITIONS];
+  UINT16                Signature;
+} MASTER_BOOT_RECORD;
+#pragma pack()
+
+#endif
diff --git a/Library/EfiShellLib.h b/Library/EfiShellLib.h
new file mode 100644 (file)
index 0000000..3fedda9
--- /dev/null
@@ -0,0 +1,271 @@
+/*++
+
+Copyright 2005, Intel Corporation                                                         
+All rights reserved. This program and the accompanying materials                          
+are licensed and made available under the terms and conditions of the BSD License         
+which accompanies this distribution. The full text of the license may be found at         
+http://opensource.org/licenses/bsd-license.php                                            
+                                                                                          
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+
+Module Name:
+  
+    EfiShellLib.h
+
+Abstract:
+
+    EFI Shell library functions
+    Header file for EfiShellLib.c
+
+Revision History
+
+--*/
+#ifndef _EFI_SHELL_LIB_INCLUDE_
+#define _EFI_SHELL_LIB_INCLUDE_
+
+#include "Tiano.h"
+#include "ShellEnv.h"
+#include "pci22.h"
+
+#include EFI_ARCH_PROTOCOL_DEFINITION (Bds)
+#include EFI_ARCH_PROTOCOL_DEFINITION (Cpu)
+#include EFI_ARCH_PROTOCOL_DEFINITION (Metronome)
+#include EFI_ARCH_PROTOCOL_DEFINITION (RealTimeClock)
+#include EFI_ARCH_PROTOCOL_DEFINITION (Reset)
+#include EFI_ARCH_PROTOCOL_DEFINITION (Runtime)
+#include EFI_ARCH_PROTOCOL_DEFINITION (StatusCode)
+#include EFI_ARCH_PROTOCOL_DEFINITION (Timer)
+#include EFI_ARCH_PROTOCOL_DEFINITION (Variable)
+#include EFI_ARCH_PROTOCOL_DEFINITION (VariableWrite)
+#include EFI_ARCH_PROTOCOL_DEFINITION (WatchdogTimer)
+#include EFI_GUID_DEFINITION (Acpi)
+#include EFI_GUID_DEFINITION (ConsoleInDevice)
+#include EFI_GUID_DEFINITION (ConsoleOutDevice)
+#include EFI_GUID_DEFINITION (DxeServices)
+#include EFI_GUID_DEFINITION (GlobalVariable)
+#include EFI_GUID_DEFINITION (Gpt)
+#include EFI_GUID_DEFINITION (Mps)
+#include EFI_GUID_DEFINITION (PrimaryConsoleInDevice)
+#include EFI_GUID_DEFINITION (PrimaryConsoleOutDevice)
+#include EFI_GUID_DEFINITION (PrimaryStandardErrorDevice)
+#include EFI_GUID_DEFINITION (SalSystemTable)
+#include EFI_GUID_DEFINITION (Smbios)
+#include EFI_GUID_DEFINITION (StandardErrorDevice)
+#include EFI_PROTOCOL_DEFINITION (BlockIo)
+#include EFI_PROTOCOL_DEFINITION (BusSpecificDriverOverride)
+#include EFI_PROTOCOL_DEFINITION (ComponentName)
+#include EFI_PROTOCOL_DEFINITION (CpuIo)
+#include EFI_PROTOCOL_DEFINITION (DataHub)
+#include EFI_PROTOCOL_DEFINITION (DebugPort)
+#include EFI_PROTOCOL_DEFINITION (DebugSupport)
+#include EFI_PROTOCOL_DEFINITION (Decompress)
+#include EFI_PROTOCOL_DEFINITION (DeviceIO)
+#include EFI_PROTOCOL_DEFINITION (DevicePath)
+#include EFI_PROTOCOL_DEFINITION (DiskIo)
+#include EFI_PROTOCOL_DEFINITION (DriverBinding)
+#include EFI_PROTOCOL_DEFINITION (DriverConfiguration)
+#include EFI_PROTOCOL_DEFINITION (DriverDiagnostics)
+#include EFI_PROTOCOL_DEFINITION (Ebc)
+#include EFI_PROTOCOL_DEFINITION (EfiNetworkInterfaceIdentifier)
+#include EFI_PROTOCOL_DEFINITION (FileSystemInfo)
+#include EFI_PROTOCOL_DEFINITION (FileSystemVolumeLabelInfo)
+#include EFI_PROTOCOL_DEFINITION (FirmwareVolume)
+#include EFI_PROTOCOL_DEFINITION (FirmwareVolumeBlock)
+#include EFI_PROTOCOL_DEFINITION (FormBrowser)
+#include EFI_PROTOCOL_DEFINITION (FormCallback)
+#include EFI_PROTOCOL_DEFINITION (Hii)
+#include EFI_PROTOCOL_DEFINITION (IsaAcpi)
+#include EFI_PROTOCOL_DEFINITION (IsaIo)
+#include EFI_PROTOCOL_DEFINITION (LoadedImage)
+#include EFI_PROTOCOL_DEFINITION (LoadFile)
+#include EFI_PROTOCOL_DEFINITION (PciHostBridgeResourceAllocation)
+#include EFI_PROTOCOL_DEFINITION (PciIo)
+#include EFI_PROTOCOL_DEFINITION (PciRootBridgeIo)
+#include EFI_PROTOCOL_DEFINITION (PxeBaseCode)
+#include EFI_PROTOCOL_DEFINITION (PxeBaseCodeCallback)
+#include EFI_PROTOCOL_DEFINITION (ScsiIo)
+#include EFI_PROTOCOL_DEFINITION (ScsiPassThru)
+#include EFI_PROTOCOL_DEFINITION (SectionExtraction)
+#include EFI_PROTOCOL_DEFINITION (SerialIo)
+#include EFI_PROTOCOL_DEFINITION (SimpleFileSystem)
+#include EFI_PROTOCOL_DEFINITION (SimpleNetwork)
+#include EFI_PROTOCOL_DEFINITION (SimplePointer)
+#include EFI_PROTOCOL_DEFINITION (SimpleTextOut)
+#include EFI_PROTOCOL_DEFINITION (Tcp)
+#include EFI_PROTOCOL_DEFINITION (UgaDraw)
+#include EFI_PROTOCOL_DEFINITION (UgaIo)
+#include EFI_PROTOCOL_DEFINITION (UgaSplash)
+#include EFI_PROTOCOL_DEFINITION (UnicodeCollation)
+#include EFI_PROTOCOL_DEFINITION (UsbHostController)
+#include EFI_PROTOCOL_DEFINITION (UsbIo)
+#include EFI_PROTOCOL_DEFINITION (VariableStore)
+
+#include "efilibplat.h"
+#include "efipart.h"
+#include "ShellDebug.h"
+#include "CRC.h"
+#include "DPath.h"
+#include "Event.h"
+#include "FileIO.h"
+#include "Handle.h"
+#include "IO.h"
+#include "LinkedList.h"
+#include "Lock.h"
+#include "Mem.h"
+#include "Misc.h"
+#include "ShellEnvInt.h"
+#include "Str.h"
+#include "VarCheck.h"
+#include "ConsistMapping.h"
+
+//
+//  Environment variable name constants
+//
+#define VarLanguageCodes    L"LangCodes"
+#define VarLanguage         L"Lang"
+#define VarTimeout          L"Timeout"
+#define VarConsoleIn        L"ConIn"
+#define VarConsoleOut       L"ConOut"
+#define VarErrorOut         L"ErrOut"
+#define VarBootOption       L"Boot%04x"
+#define VarBootOrder        L"BootOrder"
+#define VarBootNext         L"BootNext"
+#define VarBootCurrent      L"BootCurrent"
+#define VarDriverOption     L"Driver%04x"
+#define VarDriverOrder      L"DriverOrder"
+#define VarConsoleInpDev    L"ConInDev"
+#define VarConsoleOutDev    L"ConOutDev"
+#define VarErrorOutDev      L"ErrOutDev"
+#define LanguageCodeEnglish "eng"
+
+#define ISO_639_2_ENTRY_SIZE  3
+
+#define ALIGN_SIZE(a) ((a % MIN_ALIGNMENT_SIZE) ? MIN_ALIGNMENT_SIZE - (a % MIN_ALIGNMENT_SIZE) : 0)
+
+#define EFI_PROPER_VERSION(MajorVer, MinorVer)  (BS->Hdr.Revision >= (MajorVer << 16 | MinorVer))
+#define EFI_VERSION_0_99   L"0.99"
+#define EFI_VERSION_1_10   L"1.10"
+
+#define EFI_REDIRECTION_SAME        EFIERR (1000)
+#define EFI_REDIRECTION_NOT_ALLOWED EFIERR (1001)
+
+//
+// The definitions of the key filter flag
+//
+#define EFI_OUTPUT_SCROLL   0x00000001
+#define EFI_OUTPUT_PAUSE    0x00000002
+#define EFI_EXECUTION_BREAK 0x00000004
+
+#define EFI_HEX_DISP_SIZE   32
+
+//
+//  Global variables
+//
+extern EFI_SYSTEM_TABLE         *ST;
+extern EFI_BOOT_SERVICES        *BS;
+extern EFI_RUNTIME_SERVICES     *RT;
+extern EFI_SHELL_INTERFACE      *SI;
+extern EFI_SHELL_ENVIRONMENT    *SE;
+extern EFI_SHELL_ENVIRONMENT2   *SE2;
+
+extern BOOLEAN                        ShellLibInitialized;
+extern EFI_UNICODE_COLLATION_PROTOCOL *UnicodeInterface;
+extern EFI_DEVICE_PATH_PROTOCOL       LibEndDevicePath[];
+
+//
+// shell envionment protocol and interface protocol
+//
+extern EFI_GUID                 ShellInterfaceProtocol;
+extern EFI_GUID                 ShellEnvProtocol;
+
+//
+// protocol GUIDs and other miscellaneous GUIDs
+//
+extern EFI_GUID                 NullGuid;
+extern EFI_GUID                 UnknownDeviceGuid;
+
+//
+// Memory allocation type
+//
+extern EFI_MEMORY_TYPE          PoolAllocationType;
+extern UINTN                    EFIDebug;
+
+//
+//  debug globals
+//
+extern EFI_SIMPLE_TEXT_OUT_PROTOCOL   *LibRuntimeDebugOut;
+
+//
+// Initialization Functions
+//
+#define EFI_SHELL_APP_INIT(ImageHandle, SystemTable) \
+  if (EFI_ERROR (LibInitializeShellApplication (ImageHandle, SystemTable)) \
+      ) { \
+    return EFI_ABORTED; \
+  }
+
+#define EFI_SHELL_STR_INIT(HiiHandle, ArrayName, Guid) \
+  if (EFI_ERROR (LibInitializeStrings (&(HiiHandle), (ArrayName), &(Guid))) \
+      ) { \
+    return EFI_ABORTED; \
+  }
+  
+VOID
+InitializeShellLib (
+  IN EFI_HANDLE           ImageHandle,
+  IN EFI_SYSTEM_TABLE     *SystemTable
+  );
+
+EFI_STATUS
+LibInitializeStrings (
+  OUT EFI_HII_HANDLE    *HiiLibHandle,
+  IN UINT8              *StringPack,
+  IN EFI_GUID           *StringPackGuid
+  );
+
+EFI_STATUS
+LibUnInitializeStrings (
+  VOID
+  );
+
+EFI_STATUS
+LibInitializeShellApplication (
+  IN EFI_HANDLE                   ImageHandle,
+  IN EFI_SYSTEM_TABLE             *SystemTable
+  );
+
+EFI_STATUS
+InitializeUnicodeSupport (
+  CHAR8 *LangCode
+  );
+
+//
+// Math Functions
+//
+UINT64
+LShiftU64 (
+  IN UINT64   Operand,
+  IN UINTN    Count
+  );
+
+UINT64
+RShiftU64 (
+  IN UINT64   Operand,
+  IN UINTN    Count
+  );
+
+UINT64
+MultU64x32 (
+  IN UINT64   Multiplicand,
+  IN UINTN    Multiplier
+  );
+
+UINT64
+DivU64x32 (
+  IN UINT64   Dividend,
+  IN UINTN    Divisor,
+  OUT UINTN   *Remainder OPTIONAL
+  );
+
+#endif
diff --git a/Library/EfiShellLib.inf b/Library/EfiShellLib.inf
new file mode 100644 (file)
index 0000000..949a445
--- /dev/null
@@ -0,0 +1,80 @@
+#/*++
+#
+# Copyright 2005, Intel Corporation                                                         
+# All rights reserved. This program and the accompanying materials                          
+# are licensed and made available under the terms and conditions of the BSD License         
+# which accompanies this distribution. The full text of the license may be found at         
+# http://opensource.org/licenses/bsd-license.php                                            
+#                                                                                           
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+# 
+#  Module Name:
+#
+#    EfiShellLib.inf
+#
+#  Abstract:
+#
+#    Component description file for the EFI utility library.
+#
+#--*/
+
+[defines]
+BASE_NAME       = EfiShellLib
+COMPONENT_TYPE  = LIBRARY
+
+[sources.common]
+  ShellDebug.c
+  DPath.c
+  Init.c
+  Lock.c
+  Str.c
+  IO.c
+  Mem.c
+  Misc.c
+  Data.c
+  RtData.c
+  ShellEnvInt.c
+  Handle.c
+  FileIO.c
+  ConsistMapping.c
+  CRC.c
+  Event.c
+  Lock.c
+  Perf.c
+  VarCheck.c
+
+[sources.ia32]
+  ia32\math.c
+  ia32\initplat.c
+
+[sources.ipf]
+  ipf\math.c
+  ipf\initplat.c
+  ipf\palproc.s
+  ipf\salpal.c
+
+[sources.EBC]
+  EBC\math.c
+  EBC\initplat.c
+  
+[includes.common]
+  .
+  ..\Inc
+  $(EDK_SOURCE)\Foundation
+  $(EDK_SOURCE)\Foundation\Include
+  $(EDK_SOURCE)\Foundation\Efi
+  $(EDK_SOURCE)\Foundation\Efi\Include
+  $(EDK_SOURCE)\Foundation\FrameWork
+  $(EDK_SOURCE)\Foundation\FrameWork\Include
+  $(EDK_SOURCE)\Foundation\Include\IndustryStandard
+  $(EDK_SOURCE)\Foundation\Core\Dxe
+
+[libraries.common]
+  EdkFrameworkProtocolLib
+  EdkProtocolLib
+  EfiProtocolLib
+  EfiGuidLib
+
+[nmake.common]
+  C_STD_INCLUDE=
diff --git a/Library/Event.c b/Library/Event.c
new file mode 100644 (file)
index 0000000..363d7e1
--- /dev/null
@@ -0,0 +1,219 @@
+/*++
+
+Copyright 2005, Intel Corporation                                                         
+All rights reserved. This program and the accompanying materials                          
+are licensed and made available under the terms and conditions of the BSD License         
+which accompanies this distribution. The full text of the license may be found at         
+http://opensource.org/licenses/bsd-license.php                                            
+                                                                                          
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+
+Module Name:
+
+    Event.c
+
+Abstract:
+
+  The event function
+
+Revision History
+
+--*/
+
+#include "EfiShelllib.h"
+
+EFI_EVENT
+LibCreateProtocolNotifyEvent (
+  IN EFI_GUID             *ProtocolGuid,
+  IN EFI_TPL              NotifyTpl,
+  IN EFI_EVENT_NOTIFY     NotifyFunction,
+  IN VOID                 *NotifyContext,
+  OUT VOID                *Registration
+  )
+/*++
+
+Routine Description:
+  Function creates a notification event and registers that event with all 
+  the protocol instances specified by ProtocolGuid.   
+
+Arguments:
+  ProtocolGuid     - Supplies GUID of the protocol upon whose installation the event is fired.
+
+  NotifyTpl        - Supplies the task priority level of the event notifications.
+
+  NotifyFunction   - Supplies the function to notify when the event is signaled.
+
+  NotifyContext    - The context parameter to pass to NotifyFunction. 
+
+  Registration     - A pointer to a memory location to receive the registration value.  
+                     This value is passed to LibLocateHandle() to obtain new handles that 
+                     have been added that support the ProtocolGuid-specified protocol.
+
+Returns:
+
+  This function returns the notification event that was created.
+
+--*/
+{
+  EFI_STATUS  Status;
+  EFI_EVENT   Event;
+
+  //
+  // Create the event
+  //
+  Status = BS->CreateEvent (
+                EFI_EVENT_NOTIFY_SIGNAL,
+                NotifyTpl,
+                NotifyFunction,
+                NotifyContext,
+                &Event
+                );
+  if (EFI_ERROR (Status)) {
+    return NULL;
+  }
+  //
+  // Register for protocol notifactions on this event
+  //
+  Status = BS->RegisterProtocolNotify (
+                ProtocolGuid,
+                Event,
+                Registration
+                );
+
+  if (EFI_ERROR (Status)) {
+    return NULL;
+  }
+  //
+  // Kick the event so we will perform an initial pass of
+  // current installed drivers
+  //
+  BS->SignalEvent (Event);
+  return Event;
+}
+
+VOID
+WaitForEventWithTimeout (
+  IN  EFI_EVENT       Event,
+  IN  UINTN           Timeout,
+  IN  UINTN           Row,
+  IN  UINTN           Column,
+  IN  CHAR16          *String,
+  IN  EFI_INPUT_KEY   TimeoutKey,
+  OUT EFI_INPUT_KEY   *Key
+  )
+/*++
+
+Routine Description:
+  function prints a string for the given number of seconds until either the 
+  timeout expires, or the user presses a key.
+
+Arguments:
+  Event            - The event to wait for
+
+  Timeout          - A timeout value in 1 second units.
+
+  Row              - A row to print String
+
+  Column           - A column to print String
+
+  String           - The string to display on the standard output device
+
+  TimeoutKey       - The key to return in Key if a timeout occurs
+
+  Key              - Either the key the user pressed or TimeoutKey if the Timeout expired.
+
+Returns:
+
+  none
+
+--*/
+{
+  EFI_STATUS  Status;
+
+  ASSERT (Key);
+  
+  while (Timeout > 0) {
+    PrintAt (Column, Row, String, Timeout);
+    Status = WaitForSingleEvent (Event, 10000000);
+    if (Status == EFI_SUCCESS) {
+      if (!EFI_ERROR (ST->ConIn->ReadKeyStroke (ST->ConIn, Key))) {
+        return ;
+      }
+    }
+
+    Timeout--;
+  }
+
+  *Key = TimeoutKey;
+}
+
+EFI_STATUS
+WaitForSingleEvent (
+  IN EFI_EVENT                  Event,
+  IN UINT64                     Timeout OPTIONAL
+  )
+/*++
+
+Routine Description:
+  Function waits for a given event to fire, or for an optional timeout to expire.
+
+Arguments:
+  Event            - The event to wait for
+
+  Timeout          - An optional timeout value in 100 ns units.
+
+Returns:
+
+  EFI_SUCCESS       - Event fired before Timeout expired.
+  EFI_TIME_OUT     - Timout expired before Event fired..
+
+--*/
+{
+  EFI_STATUS  Status;
+  UINTN       Index;
+  EFI_EVENT   TimerEvent;
+  EFI_EVENT   WaitList[2];
+
+  if (Timeout) {
+    //
+    // Create a timer event
+    //
+    Status = BS->CreateEvent (EFI_EVENT_TIMER, 0, NULL, NULL, &TimerEvent);
+    if (!EFI_ERROR (Status)) {
+      //
+      // Set the timer event
+      //
+      BS->SetTimer (
+            TimerEvent,
+            TimerRelative,
+            Timeout
+            );
+
+      //
+      // Wait for the original event or the timer
+      //
+      WaitList[0] = Event;
+      WaitList[1] = TimerEvent;
+      Status      = BS->WaitForEvent (2, WaitList, &Index);
+      BS->CloseEvent (TimerEvent);
+
+      //
+      // If the timer expired, change the return to timed out
+      //
+      if (!EFI_ERROR (Status) && Index == 1) {
+        Status = EFI_TIMEOUT;
+      }
+    }
+  } else {
+    //
+    // No timeout... just wait on the event
+    //
+    Status = BS->WaitForEvent (1, &Event, &Index);
+    ASSERT (!EFI_ERROR (Status));
+    ASSERT (Index == 0);
+  }
+
+  return Status;
+}
+
diff --git a/Library/Event.h b/Library/Event.h
new file mode 100644 (file)
index 0000000..971dc7b
--- /dev/null
@@ -0,0 +1,53 @@
+/*++
+
+Copyright 2005, Intel Corporation                                                         
+All rights reserved. This program and the accompanying materials                          
+are licensed and made available under the terms and conditions of the BSD License         
+which accompanies this distribution. The full text of the license may be found at         
+http://opensource.org/licenses/bsd-license.php                                            
+                                                                                          
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+
+Module Name:
+
+    event.h
+
+Abstract:
+
+  Information about the event function
+
+
+Revision History
+
+--*/
+#ifndef _EVENT_H
+#define _EVENT_H
+
+EFI_EVENT
+LibCreateProtocolNotifyEvent (
+  IN EFI_GUID                       *ProtocolGuid,
+  IN EFI_TPL                        NotifyTpl,
+  IN EFI_EVENT_NOTIFY               NotifyFunction,
+  IN VOID                           *NotifyContext,
+  OUT VOID                          *Registration
+  );
+
+EFI_STATUS
+WaitForSingleEvent (
+  IN EFI_EVENT                                Event,
+  IN UINT64                                   Timeout OPTIONAL
+  );
+
+VOID
+WaitForEventWithTimeout (
+  IN  EFI_EVENT                     Event,
+  IN  UINTN                         Timeout,
+  IN  UINTN                         Row,
+  IN  UINTN                         Column,
+  IN  CHAR16                        *String,
+  IN  EFI_INPUT_KEY                 TimeoutKey,
+  OUT EFI_INPUT_KEY                 *Key
+  );
+
+#endif
\ No newline at end of file
diff --git a/Library/FileIO.c b/Library/FileIO.c
new file mode 100644 (file)
index 0000000..27ad967
--- /dev/null
@@ -0,0 +1,1398 @@
+/*++
+
+Copyright 2005, Intel Corporation                                                         
+All rights reserved. This program and the accompanying materials                          
+are licensed and made available under the terms and conditions of the BSD License         
+which accompanies this distribution. The full text of the license may be found at         
+http://opensource.org/licenses/bsd-license.php                                            
+                                                                                          
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+
+Module Name:
+
+  FileIo.c
+
+Abstract:
+
+  Implements File I/O function
+
+Revision History
+
+--*/
+
+#include "EfiShelllib.h"
+
+typedef struct _PATH_COMPONENTS {
+  CHAR16                  *Name;
+  struct _PATH_COMPONENTS *Previous;
+  struct _PATH_COMPONENTS *Next;
+} PATH_COMPONENTS;
+
+EFI_FILE_HANDLE
+LibOpenRoot (
+  IN EFI_HANDLE                   DeviceHandle
+  )
+/*++
+
+Routine Description:
+
+  Function opens and returns a file handle to the root directory of a volume.
+
+Arguments:
+
+  DeviceHandle         - A handle for a device
+
+Returns:
+  
+  A valid file handle or NULL is returned
+
+--*/
+{
+  EFI_STATUS                      Status;
+  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Volume;
+  EFI_FILE_HANDLE                 File;
+
+  File = NULL;
+
+  //
+  // Handle the file system interface to the device
+  //
+  Status = BS->HandleProtocol (
+                DeviceHandle,
+                &gEfiSimpleFileSystemProtocolGuid,
+                (VOID *) &Volume
+                );
+
+  //
+  // Open the root directory of the volume
+  //
+  if (!EFI_ERROR (Status)) {
+    Status = Volume->OpenVolume (
+                      Volume,
+                      &File
+                      );
+  }
+  //
+  // Done
+  //
+  return EFI_ERROR (Status) ? NULL : File;
+}
+
+EFI_FILE_INFO *
+LibGetFileInfo (
+  IN EFI_FILE_HANDLE      FileHandle
+  )
+/*++
+
+Routine Description:
+
+  Function gets the file information from an open file descriptor, and stores it 
+  in a buffer allocated from pool.
+
+Arguments:
+
+  FileHandle         - A file handle
+
+Returns:
+  
+  A pointer to a buffer with file information or NULL is returned
+
+--*/
+{
+  EFI_STATUS    Status;
+  EFI_FILE_INFO *Buffer;
+  UINTN         BufferSize;
+
+  ASSERT (FileHandle != NULL);
+  //
+  // Initialize for GrowBuffer loop
+  //
+  Buffer      = NULL;
+  BufferSize  = SIZE_OF_EFI_FILE_INFO + 200;
+
+  //
+  // Call the real function
+  //
+  while (GrowBuffer (&Status, (VOID **) &Buffer, BufferSize)) {
+    Status = FileHandle->GetInfo (
+                          FileHandle,
+                          &gEfiFileInfoGuid,
+                          &BufferSize,
+                          Buffer
+                          );
+  }
+
+  if (EFI_ERROR (Status)) {
+    return NULL;
+  }
+
+  return Buffer;
+}
+
+EFI_STATUS
+LibSetFileInfo (
+  IN EFI_FILE_HANDLE  FileHandle,
+  IN UINTN            BufferSize,
+  IN VOID             *Buffer
+  )
+{
+  ASSERT (FileHandle != NULL);
+  ASSERT (Buffer != NULL);
+  return FileHandle->SetInfo (
+                        FileHandle,
+                        &gEfiFileInfoGuid,
+                        BufferSize,
+                        Buffer
+                        );
+}
+
+EFI_STATUS
+LibSetPosition (
+  IN EFI_FILE_HANDLE  FileHandle,
+  IN UINT64           Position
+  )
+{
+  ASSERT (FileHandle != NULL);
+  return FileHandle->SetPosition (FileHandle, Position);
+}
+
+EFI_STATUS
+LibGetPosition (
+  IN EFI_FILE_HANDLE  FileHandle,
+  OUT UINT64          *Position
+  )
+{
+  ASSERT (FileHandle != NULL);
+  ASSERT (Position != NULL);
+  //
+  // very simple wrapper
+  //
+  return FileHandle->GetPosition (FileHandle, Position);
+}
+
+EFI_STATUS
+LibFlushFile (
+  IN EFI_FILE_HANDLE FileHandle
+  )
+{
+  ASSERT (FileHandle != NULL);
+  //
+  // very simple wrapper
+  //
+  return FileHandle->Flush (FileHandle);
+}
+
+EFI_STATUS
+LibDeleteFile (
+  IN EFI_FILE_HANDLE FileHandle
+  )
+{
+  //
+  // very simple wrapper
+  //
+  ASSERT (FileHandle != NULL);
+  return FileHandle->Delete (FileHandle);
+}
+
+EFI_STATUS
+LibOpenFileByName (
+  IN  CHAR16                            *FileName,
+  OUT EFI_FILE_HANDLE                   *FileHandle,
+  IN UINT64                             OpenMode,
+  IN UINT64                             Attributes
+  )
+{
+  EFI_DEVICE_PATH_PROTOCOL  *FilePath;
+  EFI_HANDLE                DeviceHandle;
+  
+  ASSERT (FileName != NULL);
+  ASSERT (FileHandle != NULL);
+
+  FilePath = SE2->NameToPath (FileName);
+  if (FilePath != NULL) {
+    return LibOpenFile (
+            &FilePath,
+            &DeviceHandle,
+            FileHandle,
+            OpenMode,
+            Attributes
+            );
+  }
+
+  return EFI_DEVICE_ERROR;
+
+}
+
+EFI_STATUS
+LibOpenFile (
+  IN OUT EFI_DEVICE_PATH_PROTOCOL       **FilePath,
+  OUT EFI_HANDLE                        *DeviceHandle,
+  OUT EFI_FILE_HANDLE                   *FileHandle,
+  IN UINT64                             OpenMode,
+  IN UINT64                             Attributes
+  )
+/*++
+
+Routine Description:
+
+    Opens a file for (simple) reading.  The simple read abstraction
+    will access the file access from a file system interface.
+
+Arguments:
+
+    FilePath     - File path
+    DeviceHandle - Device handle
+    FileHandle   - File Handle 
+    OpenMode     - Open Mode
+    Attributes   - The attributes
+
+Returns:
+
+    A handle to access the file
+
+--*/
+{
+  EFI_STATUS            Status;
+  EFI_FILE_HANDLE       LastHandle;
+  FILEPATH_DEVICE_PATH  *FilePathNode;
+
+  ASSERT (FilePath != NULL);
+  ASSERT (DeviceHandle != NULL);
+  ASSERT (FileHandle != NULL);
+  
+  //
+  // File the file system for this file path
+  //
+  Status = BS->LocateDevicePath (&gEfiSimpleFileSystemProtocolGuid, FilePath, DeviceHandle);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  //
+  // Attempt to access the file via a file system interface
+  //
+  *FileHandle = LibOpenRoot (*DeviceHandle);
+  Status      = *FileHandle ? EFI_SUCCESS : EFI_UNSUPPORTED;
+
+  //
+  // To access as a file system, the file path should only
+  // contain file path components.  Follow the file path nodes
+  // and find the target file
+  //
+  FilePathNode = (FILEPATH_DEVICE_PATH *) *FilePath;
+  while (!IsDevicePathEnd (&FilePathNode->Header)) {
+    //
+    // For file system access each node should be a file path component
+    //
+    if (DevicePathType (&FilePathNode->Header) != MEDIA_DEVICE_PATH ||
+        DevicePathSubType (&FilePathNode->Header) != MEDIA_FILEPATH_DP
+        ) {
+      Status = EFI_UNSUPPORTED;
+    }
+    //
+    // If there's been an error, stop
+    //
+    if (EFI_ERROR (Status)) {
+      break;
+    }
+    //
+    // Open this file path node
+    //
+    LastHandle  = *FileHandle;
+    *FileHandle = NULL;
+
+    Status = LastHandle->Open (
+                          LastHandle,
+                          FileHandle,
+                          FilePathNode->PathName,
+                          OpenMode &~EFI_FILE_MODE_CREATE,
+                          0
+                          );
+
+    if ((EFI_ERROR (Status)) && (OpenMode != (OpenMode &~EFI_FILE_MODE_CREATE))) {
+      Status = LastHandle->Open (
+                            LastHandle,
+                            FileHandle,
+                            FilePathNode->PathName,
+                            OpenMode,
+                            Attributes
+                            );
+    }
+    //
+    // Close the last node
+    //
+    LastHandle->Close (LastHandle);
+
+    //
+    // Get the next node
+    //
+    FilePathNode = (FILEPATH_DEVICE_PATH *) NextDevicePathNode (&FilePathNode->Header);
+  }
+
+  if (EFI_ERROR (Status)) {
+    *FileHandle = NULL;
+  }
+
+  return Status;
+}
+
+EFI_STATUS
+LibReadFile (
+  IN EFI_FILE_HANDLE      FileHandle,
+  IN OUT UINTN            *ReadSize,
+  OUT VOID                *Buffer
+  )
+{
+  //
+  // very simple wrapper
+  //
+  return FileHandle->Read (FileHandle, ReadSize, Buffer);
+}
+
+EFI_STATUS
+LibWriteFile (
+  IN EFI_FILE_HANDLE    FileHandle,
+  IN OUT UINTN          *BufferSize,
+  OUT VOID              *Buffer
+  )
+{
+  return FileHandle->Write (
+                      FileHandle,
+                      BufferSize,
+                      Buffer
+                      );
+
+}
+
+EFI_STATUS
+LibCloseFile (
+  IN EFI_FILE_HANDLE     FileHandle
+  )
+{
+  //
+  // very simple wrapper
+  //
+  return FileHandle->Close (FileHandle);
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+LibFileDevicePath (
+  IN EFI_HANDLE                 Device  OPTIONAL,
+  IN CHAR16                     *FileName
+  )
+/*++
+
+Routine Description:
+  Function allocates a device path for a file and appends it to an existing device path.
+
+Arguments:
+  Device         - A pointer to a device handle.
+
+  FileName       - A pointer to a Null-terminated Unicode string.
+
+Returns:
+
+  If Device is not a valid device handle, then a device path for the file specified 
+  by FileName is allocated and returned.
+
+  Results are allocated from pool.  The caller must FreePool the resulting device path 
+  structure
+
+--*/
+{
+  UINTN                     Size;
+  FILEPATH_DEVICE_PATH      *FilePath;
+  EFI_DEVICE_PATH_PROTOCOL  *Eop;
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
+
+  Size        = StrSize (FileName);
+  FilePath    = AllocateZeroPool (Size + SIZE_OF_FILEPATH_DEVICE_PATH + sizeof (EFI_DEVICE_PATH_PROTOCOL));
+  DevicePath  = NULL;
+
+  if (FilePath != NULL) {
+    //
+    // Build a file path
+    //
+    FilePath->Header.Type     = MEDIA_DEVICE_PATH;
+    FilePath->Header.SubType  = MEDIA_FILEPATH_DP;
+    SetDevicePathNodeLength (&FilePath->Header, Size + SIZE_OF_FILEPATH_DEVICE_PATH);
+    CopyMem (FilePath->PathName, FileName, Size);
+    Eop = NextDevicePathNode (&FilePath->Header);
+    SetDevicePathEndNode (Eop);
+
+    //
+    // Append file path to device's device path
+    //
+    DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) FilePath;
+    if (Device != NULL) {
+      DevicePath = AppendDevicePath (
+                    DevicePathFromHandle (Device),
+                    DevicePath
+                    );
+      FreePool (FilePath);
+      ASSERT (DevicePath);
+    }
+  }
+
+  return DevicePath;
+}
+
+EFI_STATUS
+LibFindFirstFile (
+  IN  EFI_FILE_HANDLE                       DirHandle,
+  OUT EFI_FILE_INFO                         *Buffer
+  )
+{
+  EFI_STATUS    Status;
+  EFI_FILE_INFO *DirInfo;
+  UINTN         BufferSize;
+
+  ASSERT (Buffer);
+  
+  BufferSize  = SIZE_OF_EFI_FILE_INFO + 1024;
+  DirInfo     = LibGetFileInfo (DirHandle);
+  if (DirInfo == NULL || !(DirInfo->Attribute & EFI_FILE_DIRECTORY)) {
+    Status = EFI_NOT_FOUND;
+    goto Done;
+  }
+
+  Status = LibSetPosition (DirHandle, 0);
+  if (EFI_ERROR (Status)) {
+    goto Done;
+  }
+
+  Status = LibReadFile (DirHandle, &BufferSize, Buffer);
+
+Done:
+  if (DirInfo != NULL) {
+    FreePool (DirInfo);
+  }
+  return Status;
+}
+
+EFI_STATUS
+LibFindNextFile (
+  IN     EFI_FILE_HANDLE                    DirHandle,
+  OUT EFI_FILE_INFO                         *Buffer,
+  OUT BOOLEAN                               *NoFile
+  )
+{
+  UINTN       BufferSize;
+  EFI_STATUS  Status;
+
+  ASSERT (DirHandle != NULL);
+  ASSERT (Buffer != NULL);
+  ASSERT (NoFile != NULL);
+
+  *NoFile     = FALSE;
+  BufferSize  = SIZE_OF_EFI_FILE_INFO + 1024;
+  //
+  // Large enough
+  //
+  Status = LibReadFile (DirHandle, &BufferSize, Buffer);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  if (BufferSize == 0) {
+    *NoFile = TRUE;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+LibGetFileSize (
+  IN     EFI_FILE_HANDLE                      DirHandle,
+  OUT UINT64                                  *Size
+  )
+{
+  EFI_FILE_INFO *Info;
+  
+  ASSERT (Size != NULL);
+  
+  Info = LibGetFileInfo (DirHandle);
+
+  if (Info != NULL) {
+    *Size = Info->FileSize;
+    FreePool (Info);
+    return EFI_SUCCESS;
+  }
+
+  return EFI_DEVICE_ERROR;
+}
+
+EFI_STATUS
+LibCreateDirectory (
+  IN CHAR16                             *DirName,
+  OUT EFI_FILE_HANDLE                   *FileHandle
+  )
+{
+  return LibOpenFileByName (
+          DirName,
+          FileHandle,
+          EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE,
+          EFI_FILE_DIRECTORY
+          );
+
+}
+
+CHAR16 *
+_ProcessDotInPath (
+  IN CHAR16                       *PathFromRoot
+  )
+{
+  CHAR16          *Result;
+  CHAR16          *p;
+  CHAR16          *q;
+  PATH_COMPONENTS *root;
+  PATH_COMPONENTS *cur;
+  PATH_COMPONENTS *tmp;
+  UINTN           Size;
+
+  ASSERT ('\\' == *PathFromRoot);
+
+  root    = NULL;
+  cur     = NULL;
+  Result  = NULL;
+  Size    = 0;
+  p       = PathFromRoot + 1;
+  while (*p) {
+    q = StrChr (p, '\\');
+    if (q) {
+      *q = 0;
+    }
+
+    tmp = (PATH_COMPONENTS *) AllocateZeroPool (sizeof (PATH_COMPONENTS));
+    if (NULL == tmp) {
+      goto Fail;
+    }
+
+    if (NULL == root) {
+      root  = tmp;
+      cur   = root;
+    } else {
+      tmp->Previous = cur;
+      cur->Next     = tmp;
+      cur           = tmp;
+    }
+
+    tmp->Name = StrDuplicate (p);
+    Size += StrSize (tmp->Name);
+    if (q) {
+      p = q + 1;
+    } else {
+      *p = 0;
+    }
+  }
+
+  cur = root;
+  while (cur) {
+    if (0 == StriCmp (cur->Name, L"..")) {
+      tmp = cur->Previous;
+      if (tmp) {
+        if (tmp->Previous) {
+          tmp->Previous->Next = cur->Next;
+          if (cur->Next) {
+            cur->Next->Previous = tmp->Previous;
+          }
+        } else {
+          root = cur->Next;
+          if (root) {
+            cur->Next->Previous = NULL;
+          }
+        }
+
+        cur = cur->Next;
+        FreePool (tmp->Next->Name);
+        FreePool (tmp->Next);
+        FreePool (tmp->Name);
+        FreePool (tmp);
+      } else {
+        root = cur->Next;
+        if (root) {
+          cur->Next->Previous = NULL;
+        }
+
+        FreePool (cur->Name);
+        FreePool (cur);
+        cur = root;
+      }
+    } else if (0 == StriCmp (cur->Name, L".")) {
+      tmp = cur->Previous;
+      if (tmp) {
+        tmp->Next = cur->Next;
+        if (cur->Next) {
+          cur->Next->Previous = tmp;
+        }
+
+        FreePool (cur->Name);
+        FreePool (cur);
+        cur = tmp->Next;
+      } else {
+        root = cur->Next;
+        if (root) {
+          cur->Next->Previous = NULL;
+        }
+
+        FreePool (cur->Name);
+        FreePool (cur);
+        cur = root;
+      }
+    } else {
+      cur = cur->Next;
+    }
+  }
+
+  Result = AllocateZeroPool (Size + sizeof (UINT16) * 2);
+  if (NULL == Result) {
+    goto Fail;
+  }
+
+  *Result = '\\';
+  tmp     = root;
+  while (tmp) {
+    StrCat (Result, tmp->Name);
+    tmp = tmp->Next;
+    if (tmp) {
+      StrCat (Result, L"\\");
+    }
+  }
+
+Fail:
+  tmp = root;
+  while (tmp) {
+    root = tmp->Next;
+    FreePool (tmp->Name);
+    FreePool (tmp);
+    tmp = root;
+  }
+
+  return Result;
+}
+
+EFI_STATUS
+_CheckContinuousSlash (
+  IN CHAR16                       *PathFromRoot
+  )
+{
+  CHAR16      *p;
+  EFI_STATUS  Status;
+
+  ASSERT (PathFromRoot != NULL);
+
+  p       = PathFromRoot;
+  Status  = EFI_SUCCESS;
+  while (*p) {
+    if ('\\' == *p && '\\' == *(p + 1)) {
+      Status = EFI_INVALID_PARAMETER;
+      break;
+    }
+
+    p++;
+  }
+
+  return Status;
+}
+
+EFI_STATUS
+LibSplitFsAndPath (
+  IN     CHAR16                       *AbPath,
+  IN OUT CHAR16                       **Fs,
+  IN OUT CHAR16                       **Path
+  )
+{
+  EFI_STATUS  Status;
+  CHAR16      *p;
+  UINTN       Size;
+
+  ASSERT (Fs);
+  ASSERT (Path);
+
+  *Fs     = NULL;
+  *Path   = NULL;
+  Status  = EFI_SUCCESS;
+
+  p       = AbPath;
+  while (*p) {
+    if (':' == *p && ('\\' == *(p + 1) || 0 == *(p + 1))) {
+      break;
+    }
+
+    p++;
+  }
+
+  if (0 == *p) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Size  = sizeof (CHAR16) * (UINTN) (p - AbPath + 1);
+  *Fs   = AllocateZeroPool (Size);
+  if (NULL == Fs) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  CopyMem (*Fs, AbPath, Size - sizeof (CHAR16));
+
+  if (*(p + 1)) {
+    *Path = StrDuplicate (p + 1);
+  } else {
+    *Path = StrDuplicate (L"\\");
+  }
+
+  if (NULL == *Path) {
+    FreePool (*Fs);
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  return EFI_SUCCESS;
+}
+
+BOOLEAN
+CompareFsDevice (
+  IN  CHAR16     *FsName1,
+  IN  CHAR16     *FsName2
+  )
+{
+  EFI_STATUS                Status;
+  EFI_DEVICE_PATH_PROTOCOL  *DevPath1;
+  EFI_DEVICE_PATH_PROTOCOL  *DevPath2;
+
+  Status = SE2->GetFsDevicePath (FsName1, &DevPath1);
+  if (EFI_ERROR (Status)) {
+    return FALSE;
+  }
+
+  Status = SE2->GetFsDevicePath (FsName2, &DevPath2);
+  if (EFI_ERROR (Status)) {
+    return FALSE;
+  }
+
+  if (DevicePathCompare (DevPath1, DevPath2) == 0) {
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+EFI_STATUS
+LibIsSubPath (
+  IN CHAR16                       *Parent,
+  IN CHAR16                       *Child,
+  OUT BOOLEAN                     *Result
+  )
+{
+  EFI_STATUS  Status;
+  CHAR16      *PathFromRoot1;
+  CHAR16      *PathFromRoot2;
+  CHAR16      *Fs1;
+  CHAR16      *Fs2;
+  CHAR16      *tmp;
+  UINTN       Index;
+
+  ASSERT (Parent);
+  ASSERT (Child);
+  ASSERT (Result);
+
+  Index         = 0;
+  tmp           = NULL;
+  Fs1           = NULL;
+  Fs2           = NULL;
+  PathFromRoot1 = NULL;
+  PathFromRoot2 = NULL;
+  Status        = EFI_SUCCESS;
+  *Result       = FALSE;
+
+  Status        = _CheckContinuousSlash (Parent);
+  if (EFI_ERROR (Status)) {
+    goto Done;
+  }
+
+  Status = _CheckContinuousSlash (Child);
+  if (EFI_ERROR (Status)) {
+    goto Done;
+  }
+
+  Status = LibSplitFsAndPath (Parent, &Fs1, &PathFromRoot1);
+  if (EFI_ERROR (Status)) {
+    goto Done;
+  }
+
+  Status = LibSplitFsAndPath (Child, &Fs2, &PathFromRoot2);
+  if (EFI_ERROR (Status)) {
+    goto Done;
+  }
+
+  if (!CompareFsDevice (Fs1, Fs2)) {
+    goto Done;
+  }
+
+  tmp           = PathFromRoot1;
+  PathFromRoot1 = _ProcessDotInPath (tmp);
+  FreePool (tmp);
+  if (NULL == PathFromRoot1) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto Done;
+  }
+
+  tmp           = PathFromRoot2;
+  PathFromRoot2 = _ProcessDotInPath (tmp);
+  FreePool (tmp);
+  if (NULL == PathFromRoot2) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto Done;
+  }
+
+  while (PathFromRoot1[Index] && PathFromRoot2[Index] && PathFromRoot1[Index] == PathFromRoot2[Index]) {
+    Index++;
+  }
+
+  if (0 == PathFromRoot1[Index]) {
+    if ('\\' == PathFromRoot1[Index - 1]) {
+      *Result = TRUE;
+    } else {
+      if ('\\' == PathFromRoot2[Index] || 0 == PathFromRoot2[Index]) {
+        *Result = TRUE;
+      }
+    }
+
+    goto Done;
+  }
+
+Done:
+  FreePool (Fs1);
+  FreePool (Fs2);
+  FreePool (PathFromRoot1);
+  FreePool (PathFromRoot2);
+
+  return Status;
+}
+
+CHAR16 *
+LibFormAbsolutePath (
+  IN CHAR16                       *FilePath,
+  IN CHAR16                       *Ref OPTIONAL
+  )
+{
+  CHAR16  *p;
+  CHAR16  *OrgStr;
+  CHAR16  ch;
+  CHAR16  *fs;
+  CHAR16  *PathFromRoot;
+  UINTN   len;
+  
+  ASSERT (FilePath != NULL);
+
+  fs      = NULL;
+  OrgStr  = FilePath;
+  p       = FilePath;
+  while (*p) {
+    if (':' == *p && '\\' == *(p + 1)) {
+      break;
+    }
+
+    p++;
+  }
+
+  if (0 == *p && Ref) {
+    OrgStr  = Ref;
+    p       = Ref;
+    while (*p) {
+      if (':' == *p && '\\' == *(p + 1)) {
+        break;
+      }
+
+      p++;
+    }
+  }
+
+  if (0 == *p) {
+    return NULL;
+  }
+
+  ch  = *p;
+  *p  = 0;
+  fs  = StrDuplicate (OrgStr);
+  *p  = ch;
+  p++;
+  PathFromRoot = AllocateZeroPool (StrSize (p) + sizeof (UINT16));
+  if (NULL == PathFromRoot) {
+    FreePool (fs);
+    return NULL;
+  }
+
+  StrCpy (PathFromRoot, p);
+  if ('\\' != PathFromRoot[StrLen (p) - 1]) {
+    StrCat (PathFromRoot, L"\\");
+  }
+
+  if (OrgStr == Ref) {
+    if ('\\' == *FilePath) {
+      FilePath++;
+    }
+
+    p             = PathFromRoot;
+    PathFromRoot  = AllocateZeroPool (StrSize (p) + StrSize (FilePath));
+    if (NULL == PathFromRoot) {
+      FreePool (fs);
+      FreePool (p);
+      return NULL;
+    }
+
+    StrCpy (PathFromRoot, p);
+    FreePool (p);
+    StrCat (PathFromRoot, FilePath);
+  }
+
+  if (EFI_ERROR (_CheckContinuousSlash (PathFromRoot))) {
+    FreePool (fs);
+    FreePool (PathFromRoot);
+    return NULL;
+  }
+
+  len = StrLen (PathFromRoot);
+  if (len > 1 && '\\' == PathFromRoot[len - 1]) {
+    PathFromRoot[len - 1] = 0;
+  }
+
+  if (StrLen (PathFromRoot) > 1) {
+    p = _ProcessDotInPath (PathFromRoot);
+  } else {
+    p = StrDuplicate (PathFromRoot);
+  }
+
+  FreePool (PathFromRoot);
+
+  len           = StrSize (fs) + StrSize (p) + sizeof (UINT16);
+  PathFromRoot  = AllocateZeroPool (len);
+  if (PathFromRoot) {
+    SPrint (PathFromRoot, len, L"%s:%s", fs, p);
+  }
+
+  FreePool (fs);
+  FreePool (p);
+
+  return PathFromRoot;
+}
+
+EFI_STATUS
+LibCompareFile (
+  IN CHAR16                      *DstFile,
+  IN CHAR16                      *SrcFile,
+  IN OUT BOOLEAN                 *IsSame
+  )
+/*++
+Routine descriptions:
+
+  Check if 2 files are the same, no wild card is suppoted
+
+Arguments:
+
+   DstFile - Dst File
+   SrcFile - Src File
+
+Return:         
+   IsSame = FALSE:  dst is not the src  itself
+   IsSame = TRUE    dst is the src itself
+
+--*/
+{
+  EFI_LIST_ENTRY  SrcList;
+  EFI_LIST_ENTRY  DstList;
+  EFI_STATUS      Status;
+  EFI_LIST_ENTRY  *Link;
+  SHELL_FILE_ARG  *SrcArg;
+  SHELL_FILE_ARG  *DstArg;
+  
+  ASSERT (IsSame != NULL);
+
+  Link    = NULL;
+  SrcArg  = NULL;
+  DstArg  = NULL;
+  InitializeListHead (&SrcList);
+  InitializeListHead (&DstList);
+
+  *IsSame = FALSE;
+
+  Status  = ShellFileMetaArgNoWildCard (DstFile, &DstList);
+
+  if (EFI_ERROR (Status) || IsListEmpty (&DstList)) {
+    goto Done;
+  }
+  //
+  // multi dst
+  //
+  if (DstList.Flink->Flink != &DstList) {
+    Status = EFI_INVALID_PARAMETER;
+    goto Done;
+  }
+
+  DstArg = CR (DstList.Flink, SHELL_FILE_ARG, Link, SHELL_FILE_ARG_SIGNATURE);
+
+  if (SrcFile) {
+    Status = ShellFileMetaArg (SrcFile, &SrcList);
+
+    if (EFI_ERROR (Status) || IsListEmpty (&DstList)) {
+      goto Done;
+    }
+    //
+    // multi dst
+    //
+    if (SrcList.Flink->Flink != &SrcList) {
+      Status = EFI_INVALID_PARAMETER;
+      goto Done;
+    }
+
+    SrcArg = CR (SrcList.Flink, SHELL_FILE_ARG, Link, SHELL_FILE_ARG_SIGNATURE);
+
+    //
+    // At this stage, make sure there is at least one valid src
+    //
+    if (StrCmp (SrcArg->FullName, DstArg->FullName) == 0) {
+      *IsSame = TRUE;
+    }
+  }
+
+Done:
+  ShellFreeFileList (&SrcList);
+  ShellFreeFileList (&DstList);
+  return Status;
+}
+
+EFI_FILE_HANDLE
+LibOpenFilePath (
+  IN EFI_DEVICE_PATH_PROTOCOL   *FilePath,
+  IN UINT64                     FileMode
+  )
+/*++
+
+Routine Description:
+  
+Arguments:
+    FilePath - File path
+    FileMode - File mode
+
+Returns:
+  
+--*/
+{
+  EFI_FILE_HANDLE FileHandle;
+  EFI_HANDLE      DeviceHandle;
+  EFI_STATUS      Status;
+
+  FileHandle    = NULL;
+  DeviceHandle  = NULL;
+  Status = LibOpenFile (
+            &FilePath,
+            &DeviceHandle,
+            &FileHandle,
+            FileMode,
+            0
+            );
+  if (EFI_ERROR (Status)) {
+    return NULL;
+  }
+
+  return FileHandle;
+}
+
+EFI_STATUS
+OpenSimpleReadFile (
+  IN BOOLEAN                        BootPolicy,
+  IN VOID                           *SourceBuffer OPTIONAL,
+  IN UINTN                          SourceSize,
+  IN OUT EFI_DEVICE_PATH_PROTOCOL   **FilePath,
+  OUT EFI_HANDLE                    *DeviceHandle,
+  OUT SIMPLE_READ_FILE              *SimpleReadHandle
+  )
+/*++
+
+Routine Description:
+
+    Opens a file for (simple) reading.  The simple read abstraction
+    will access the file either from a memory copy, from a file
+    system interface, or from the load file interface. 
+
+Arguments:
+
+  BootPolicy       - The boot policy
+  SourceBuffer     - The source buffer
+  SourceSize       - The source size
+  FilePath         - The file path
+  DeviceHandle     - The device handle
+  SimpleReadHandle - The simple read handle
+
+Returns:
+
+    A handle to access the file
+
+--*/
+{
+  SIMPLE_READ_HANDLE        *FHand;
+  EFI_DEVICE_PATH_PROTOCOL  *UserFilePath;
+  EFI_DEVICE_PATH_PROTOCOL  *TempFilePath;
+  EFI_DEVICE_PATH_PROTOCOL  *TempFilePathPtr;
+  FILEPATH_DEVICE_PATH      *FilePathNode;
+  EFI_FILE_HANDLE           FileHandle;
+  EFI_FILE_HANDLE           LastHandle;
+  EFI_STATUS                Status;
+  EFI_LOAD_FILE_PROTOCOL    *LoadFile;
+
+  ASSERT (DeviceHandle != NULL);
+  ASSERT (SimpleReadHandle != NULL);
+  
+  FHand         = NULL;
+  UserFilePath  = *FilePath;
+
+  //
+  // Allocate a new simple read handle structure
+  //
+  FHand = AllocateZeroPool (sizeof (SIMPLE_READ_HANDLE));
+  if (!FHand) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto Done;
+  }
+
+  FHand->Signature  = SIMPLE_READ_SIGNATURE;
+
+  //
+  // If the caller passed a copy of the file, then just use it
+  //
+  if (SourceBuffer) {
+    FHand->Source     = SourceBuffer;
+    FHand->SourceSize = SourceSize;
+    *DeviceHandle     = NULL;
+    Status            = EFI_SUCCESS;
+    goto Done;
+  }
+  //
+  // Attempt to access the file via a file system interface
+  //
+  FileHandle  = NULL;
+  Status      = BS->LocateDevicePath (&gEfiSimpleFileSystemProtocolGuid, FilePath, DeviceHandle);
+  if (!EFI_ERROR (Status)) {
+    FileHandle = LibOpenRoot (*DeviceHandle);
+  }
+
+  Status = FileHandle ? EFI_SUCCESS : EFI_UNSUPPORTED;
+
+  if (EFI_ERROR (Status)) {
+    goto Done;
+  }
+  //
+  // To access as a filesystem, the filepath should only
+  // contain filepath components.  Follow the filepath nodes
+  // and find the target file
+  //
+  FilePathNode = (FILEPATH_DEVICE_PATH *) *FilePath;
+  while (!IsDevicePathEnd (&FilePathNode->Header)) {
+    //
+    // For filesystem access each node should be a filepath component
+    //
+    if (DevicePathType (&FilePathNode->Header) != MEDIA_DEVICE_PATH ||
+        DevicePathSubType (&FilePathNode->Header) != MEDIA_FILEPATH_DP
+        ) {
+      Status = EFI_UNSUPPORTED;
+    }
+    //
+    // If there's been an error, stop
+    //
+    if (EFI_ERROR (Status)) {
+      break;
+    }
+    //
+    // Open this file path node
+    //
+    LastHandle  = FileHandle;
+    FileHandle  = NULL;
+
+    Status = LastHandle->Open (
+                          LastHandle,
+                          &FileHandle,
+                          FilePathNode->PathName,
+                          EFI_FILE_MODE_READ,
+                          0
+                          );
+
+    //
+    // Close the last node
+    //
+    LastHandle->Close (LastHandle);
+
+    //
+    // Get the next node
+    //
+    FilePathNode = (FILEPATH_DEVICE_PATH *) NextDevicePathNode (&FilePathNode->Header);
+  }
+  //
+  // If success, return the FHand
+  //
+  if (!EFI_ERROR (Status)) {
+    ASSERT (FileHandle);
+    FHand->FileHandle = FileHandle;
+    goto Done;
+  }
+  //
+  // Cleanup from filesystem access
+  //
+  if (FileHandle) {
+    FileHandle->Close (FileHandle);
+    FileHandle  = NULL;
+    *FilePath   = UserFilePath;
+  }
+  //
+  // If the error is something other then unsupported, return it
+  //
+  if (Status != EFI_UNSUPPORTED) {
+    goto Done;
+  }
+  //
+  // Attempt to access the file via the load file protocol
+  //
+  Status = LibDevicePathToInterface (&gEfiLoadFileProtocolGuid, *FilePath, (VOID *) &LoadFile);
+  if (!EFI_ERROR (Status)) {
+
+    TempFilePath    = DuplicateDevicePath (*FilePath);
+
+    TempFilePathPtr = TempFilePath;
+
+    Status          = BS->LocateDevicePath (&gEfiLoadFileProtocolGuid, &TempFilePath, DeviceHandle);
+
+    FreePool (TempFilePathPtr);
+
+    //
+    // Determine the size of buffer needed to hold the file
+    //
+    SourceSize = 0;
+    Status = LoadFile->LoadFile (
+                        LoadFile,
+                        *FilePath,
+                        BootPolicy,
+                        &SourceSize,
+                        NULL
+                        );
+
+    //
+    // We expect a buffer too small error to inform us
+    // of the buffer size needed
+    //
+    if (Status == EFI_BUFFER_TOO_SMALL) {
+      SourceBuffer = AllocatePool (SourceSize);
+
+      if (SourceBuffer) {
+        FHand->FreeBuffer = TRUE;
+        FHand->Source     = SourceBuffer;
+        FHand->SourceSize = SourceSize;
+
+        Status = LoadFile->LoadFile (
+                            LoadFile,
+                            *FilePath,
+                            BootPolicy,
+                            &SourceSize,
+                            SourceBuffer
+                            );
+      }
+    }
+    //
+    // If success, return FHand
+    //
+    if (!EFI_ERROR (Status) || Status == EFI_ALREADY_STARTED) {
+      goto Done;
+    }
+  }
+  //
+  // Nothing else to try
+  //
+  DEBUG ((EFI_D_LOAD | EFI_D_WARN, "OpenSimpleReadFile: Device did not support a known load protocol\n"));
+  Status = EFI_UNSUPPORTED;
+
+Done:
+  //
+  // If the file was not accessed, clean up
+  //
+  if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {
+    if (FHand) {
+      if (FHand->FreeBuffer) {
+        FreePool (FHand->Source);
+      }
+
+      FreePool (FHand);
+    }
+  }
+
+  return Status;
+}
+
+EFI_STATUS
+ReadSimpleReadFile (
+  IN SIMPLE_READ_FILE     UserHandle,
+  IN UINTN                Offset,
+  IN OUT UINTN            *ReadSize,
+  OUT VOID                *Buffer
+  )
+{
+  UINTN               EndPos;
+  SIMPLE_READ_HANDLE  *FHand;
+  EFI_STATUS          Status;
+
+  ASSERT (ReadSize);
+  ASSERT (Buffer);
+
+  FHand = UserHandle;
+  ASSERT (FHand->Signature == SIMPLE_READ_SIGNATURE);
+  if&nb