]> git.proxmox.com Git - mirror_edk2.git/commitdiff
1) Sync EdkCompatibilityPkg with EDK 1.04. The changes includes:
authorqwang12 <qwang12@6f19259b-4bc3-4df7-8a09-765794883524>
Thu, 24 Jan 2008 07:29:31 +0000 (07:29 +0000)
committerqwang12 <qwang12@6f19259b-4bc3-4df7-8a09-765794883524>
Thu, 24 Jan 2008 07:29:31 +0000 (07:29 +0000)
  1.1) Bug fixes. (For details, please check  Documents & files: Snapshot/Release Notes at https://edk.tianocore.org/servlets/ProjectDocumentList?folderID=43&expandFolder=43&folderID=6)
  1.2) Add new UEFI protocol definitions for AbsolutePointer, FormBrowser2, HiiConfigAccess, HiiConfigRouting, HiiDatabase, HiiFont, HiiImage, HiiString, SimpleTextInputEx, DPC protocol.
  1.3) Add Smbios 2.5, 2.6 supports.

  Incompatible changes hilighted:
  1) EFI_MANAGED_NETWORK_PROTOCOL_GUID changed.
  2) EFI_IP4_IPCONFIG_DATA changed.

2) Add in EdkCompatibilityPkg/EdkCompatibilityPkg.dsc to build all libraries in this package.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@4624 6f19259b-4bc3-4df7-8a09-765794883524

90 files changed:
EdkCompatibilityPkg/Sample/Include/EfiCompNameSupport.h [deleted file]
EdkCompatibilityPkg/Sample/Platform/Common.dsc
EdkCompatibilityPkg/Sample/Platform/CommonIa32.dsc
EdkCompatibilityPkg/Sample/Platform/CommonIpf.dsc
EdkCompatibilityPkg/Sample/Platform/CommonX64.dsc
EdkCompatibilityPkg/Sample/Platform/EdkIIGlueLib32.dsc
EdkCompatibilityPkg/Sample/Platform/EdkIIGlueLibAll.dsc
EdkCompatibilityPkg/Sample/Platform/EdkLib32.dsc
EdkCompatibilityPkg/Sample/Platform/EdkLibAll.dsc
EdkCompatibilityPkg/Sample/Platform/Generic/MonoStatusCode/Pei/MonoStatusCode.h [new file with mode: 0644]
EdkCompatibilityPkg/Sample/Platform/Generic/RuntimeDxe/StatusCode/Lib/BsDataHubStatusCode/BsDataHubStatusCode.c
EdkCompatibilityPkg/Sample/Platform/Generic/RuntimeDxe/StatusCode/Lib/BsDataHubStatusCode/BsDataHubStatusCode.h
EdkCompatibilityPkg/Sample/Platform/Generic/RuntimeDxe/StatusCode/Lib/BsSerialStatusCode/BsSerialStatusCode.c
EdkCompatibilityPkg/Sample/Platform/Generic/RuntimeDxe/StatusCode/Lib/Include/BsDataHubStatusCodeLib.h
EdkCompatibilityPkg/Sample/Platform/Generic/RuntimeDxe/StatusCode/Lib/Include/BsSerialStatusCodeLib.h
EdkCompatibilityPkg/Sample/Platform/Generic/RuntimeDxe/StatusCode/Lib/Include/RtMemoryStatusCodeLib.h
EdkCompatibilityPkg/Sample/Platform/Generic/RuntimeDxe/StatusCode/Lib/Include/RtPlatformStatusCodeLib.h
EdkCompatibilityPkg/Sample/Platform/Generic/RuntimeDxe/StatusCode/Lib/Include/RtPort80StatusCodeLib.h
EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/EdkNt32PpiLib.inf [new file with mode: 0644]
EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtAutoscan/NtAutoscan.c [new file with mode: 0644]
EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtAutoscan/NtAutoscan.h [new file with mode: 0644]
EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtFwh/NtFwh.c [new file with mode: 0644]
EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtFwh/NtFwh.h [new file with mode: 0644]
EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtLoadAsDll/NtLoadAsDll.c [new file with mode: 0644]
EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtLoadAsDll/NtLoadAsDll.h [new file with mode: 0644]
EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtPeiLoadFile/NtPeiLoadFile.c [new file with mode: 0644]
EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtPeiLoadFile/NtPeiLoadFile.h [new file with mode: 0644]
EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtThunk/NtThunk.c [new file with mode: 0644]
EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtThunk/NtThunk.h [new file with mode: 0644]
EdkCompatibilityPkg/Sample/Tools/Source/BootsectImage/Makefile [deleted file]
EdkCompatibilityPkg/Sample/Tools/Source/BootsectImage/bootsectimage.c [deleted file]
EdkCompatibilityPkg/Sample/Tools/Source/BootsectImage/fat.h [deleted file]
EdkCompatibilityPkg/Sample/Tools/Source/BootsectImage/mbr.h [deleted file]
EdkCompatibilityPkg/Sample/Tools/Source/Common/FvLib.c
EdkCompatibilityPkg/Sample/Tools/Source/Common/Makefile
EdkCompatibilityPkg/Sample/Tools/Source/CustomizedCompress/makefile
EdkCompatibilityPkg/Sample/Tools/Source/EfiCompress/makefile
EdkCompatibilityPkg/Sample/Tools/Source/EfiRom/EfiRom.c
EdkCompatibilityPkg/Sample/Tools/Source/EfiRom/Makefile
EdkCompatibilityPkg/Sample/Tools/Source/EfildrImage/Makefile [deleted file]
EdkCompatibilityPkg/Sample/Tools/Source/EfildrImage/efildrimage.c [deleted file]
EdkCompatibilityPkg/Sample/Tools/Source/FwImage/Makefile
EdkCompatibilityPkg/Sample/Tools/Source/GenAprioriFile/Makefile
EdkCompatibilityPkg/Sample/Tools/Source/GenBootsector/GetDrvNumOffset.c [deleted file]
EdkCompatibilityPkg/Sample/Tools/Source/GenBootsector/fat.h [deleted file]
EdkCompatibilityPkg/Sample/Tools/Source/GenBootsector/genbootsector.c [deleted file]
EdkCompatibilityPkg/Sample/Tools/Source/GenBootsector/makefile [deleted file]
EdkCompatibilityPkg/Sample/Tools/Source/GenCRC32Section/makefile
EdkCompatibilityPkg/Sample/Tools/Source/GenDepex/GenDepex.c
EdkCompatibilityPkg/Sample/Tools/Source/GenDepex/makefile
EdkCompatibilityPkg/Sample/Tools/Source/GenFfsFile/GenFfsFile.c
EdkCompatibilityPkg/Sample/Tools/Source/GenFfsFile/makefile
EdkCompatibilityPkg/Sample/Tools/Source/GenFvImage/GenFvImageLib.h
EdkCompatibilityPkg/Sample/Tools/Source/GenFvImage/Makefile
EdkCompatibilityPkg/Sample/Tools/Source/GenPage/Makefile [deleted file]
EdkCompatibilityPkg/Sample/Tools/Source/GenPage/VirtualMemory.h [deleted file]
EdkCompatibilityPkg/Sample/Tools/Source/GenPage/genpage.c [deleted file]
EdkCompatibilityPkg/Sample/Tools/Source/GenSection/makefile
EdkCompatibilityPkg/Sample/Tools/Source/GenTEImage/GenTEImage.c [new file with mode: 0644]
EdkCompatibilityPkg/Sample/Tools/Source/GenTEImage/Makefile [new file with mode: 0644]
EdkCompatibilityPkg/Sample/Tools/Source/GuidChk/Makefile
EdkCompatibilityPkg/Sample/Tools/Source/MakeDeps/MakeDeps.c
EdkCompatibilityPkg/Sample/Tools/Source/MakeDeps/Makefile
EdkCompatibilityPkg/Sample/Tools/Source/Makefile
EdkCompatibilityPkg/Sample/Tools/Source/ModifyInf/Makefile
EdkCompatibilityPkg/Sample/Tools/Source/ProcessDsc/Makefile
EdkCompatibilityPkg/Sample/Tools/Source/ProcessDsc/ProcessDsc.c
EdkCompatibilityPkg/Sample/Tools/Source/SetStamp/Makefile
EdkCompatibilityPkg/Sample/Tools/Source/SplitFile/Makefile
EdkCompatibilityPkg/Sample/Tools/Source/StrGather/Makefile
EdkCompatibilityPkg/Sample/Tools/Source/Strip/Makefile [new file with mode: 0644]
EdkCompatibilityPkg/Sample/Tools/Source/Strip/strip.c [new file with mode: 0644]
EdkCompatibilityPkg/Sample/Tools/Source/UefiStrGather/Makefile [new file with mode: 0644]
EdkCompatibilityPkg/Sample/Tools/Source/UefiStrGather/StrGather.c [new file with mode: 0644]
EdkCompatibilityPkg/Sample/Tools/Source/UefiStrGather/StrGather.h [new file with mode: 0644]
EdkCompatibilityPkg/Sample/Tools/Source/UefiStrGather/StringDB.c [new file with mode: 0644]
EdkCompatibilityPkg/Sample/Tools/Source/UefiStrGather/StringDB.h [new file with mode: 0644]
EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/EfiVfr.h [new file with mode: 0644]
EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrCompiler.cpp [new file with mode: 0644]
EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrCompiler.h [new file with mode: 0644]
EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrError.cpp [new file with mode: 0644]
EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrError.h [new file with mode: 0644]
EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrFormPkg.cpp [new file with mode: 0644]
EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrFormPkg.h [new file with mode: 0644]
EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrSyntax.g [new file with mode: 0644]
EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrUtilityLib.cpp [new file with mode: 0644]
EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrUtilityLib.h [new file with mode: 0644]
EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/makefile [new file with mode: 0644]
EdkCompatibilityPkg/Sample/Tools/Source/VcCheck/makefile
EdkCompatibilityPkg/Sample/Tools/Source/VfrCompile/makefile

diff --git a/EdkCompatibilityPkg/Sample/Include/EfiCompNameSupport.h b/EdkCompatibilityPkg/Sample/Include/EfiCompNameSupport.h
deleted file mode 100644 (file)
index 7159588..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/*++\r
-\r
-Copyright (c) 2004, Intel Corporation                                                         \r
-All rights reserved. This program and the accompanying materials                          \r
-are licensed and made available under the terms and conditions of the BSD License         \r
-which accompanies this distribution.  The full text of the license may be found at        \r
-http://opensource.org/licenses/bsd-license.php                                            \r
-                                                                                          \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
-\r
-Module Name:\r
-\r
-  EfiCompNameSupport.h\r
-\r
-Abstract:\r
-\r
-  Private data structures for the Console Splitter driver\r
-\r
---*/\r
-\r
-#ifndef EFI_COMPONENT_NAME_SUPPORT_H\r
-#define EFI_COMPONENT_NAME_SUPPORT_H\r
-\r
-#include "Tiano.h"\r
-\r
-#ifndef EFI_SIZE_REDUCTION_APPLIED\r
-\r
-#define INSTALL_ALL_DRIVER_PROTOCOLS(ImageHandle,               \\r
-                                     SystemTable,               \\r
-                                     DriverBinding,             \\r
-                                     DriverBindingHandle,       \\r
-                                     ComponentName,             \\r
-                                     DriverConfiguration,       \\r
-                                     DriverDiagnostics)         \\r
-        EfiLibInstallAllDriverProtocols ((ImageHandle),         \\r
-                                         (SystemTable),         \\r
-                                         (DriverBinding),       \\r
-                                         (DriverBindingHandle), \\r
-                                         (ComponentName),       \\r
-                                         (DriverConfiguration), \\r
-                                         (DriverDiagnostics))\r
-#else\r
-\r
-#define INSTALL_ALL_DRIVER_PROTOCOLS(ImageHandle,             \\r
-                                     SystemTable,             \\r
-                                     DriverBinding,           \\r
-                                     DriverBindingHandle,     \\r
-                                     ComponentName,           \\r
-                                     DriverConfiguration,     \\r
-                                     DriverDiagnostics)       \\r
-        EfiLibInstallDriverBinding ((ImageHandle),            \\r
-                                    (SystemTable),            \\r
-                                    (DriverBinding),          \\r
-                                    (DriverBindingHandle))\r
-#endif\r
-\r
-#endif\r
index c40c4e7de82a31220b6b29c277faf754da046812..85740c203379ab7956e21f1422cb199eebaf5f0a 100644 (file)
@@ -87,10 +87,15 @@ DEPEX_TYPE = EFI_SECTION_PEI_DEPEX
 DEPEX_TYPE = EFI_SECTION_DXE_DEPEX\r
 !ENDIF\r
 \r
+!IF "$(COMPONENT_TYPE)" != "LIBRARY" && EXIST($(BUILD_DIR)\$(PROCESSOR)\CompilerStub.lib)\r
+LIBS = $(LIBS) $(BUILD_DIR)\$(PROCESSOR)\CompilerStub.lib\r
+!ENDIF\r
+\r
 #\r
 # Command flags for MAKEDEPS tool\r
 #\r
 DEP_FLAGS = -target $** -o $(DEP_FILE) $(INC) -ignorenotfound -q\r
+DEP_FLAGS2 = -target $@ -o $(DEP_FILE) -cl\r
 \r
 [=============================================================================]\r
 #\r
@@ -112,8 +117,15 @@ DEP_FLAGS = -target $** -o $(DEP_FILE) $(INC) -ignorenotfound -q
 [=============================================================================]\r
 [Compile.Ia32.asm,Compile.x64.asm]\r
 \r
+#\r
+# Add build dependency check\r
+#\r
 DEP_FILE    = $(DEST_DIR)\$(FILE)Asm.dep\r
 \r
+!IF EXIST($(DEP_FILE))\r
+!INCLUDE $(DEP_FILE)\r
+!ENDIF\r
+\r
 !IF EXIST($(DEST_DIR)\$(FILE).obj)\r
 DEP_TARGETS = $(DEP_TARGETS) $(DEST_DIR)\$(FILE)Asm.dep\r
 !IF !EXIST($(DEP_FILE))\r
@@ -121,10 +133,6 @@ CREATEDEPS = YES
 !ENDIF\r
 !ENDIF\r
 \r
-!IF EXIST($(DEP_FILE))\r
-!INCLUDE $(DEP_FILE)\r
-!ENDIF\r
-\r
 #\r
 # Update dep file for next round incremental build\r
 #\r
@@ -140,39 +148,58 @@ $(DEST_DIR)\$(FILE).obj : $(SOURCE_FILE_NAME) $(INF_FILENAME) $(ALL_DEPS)
 [=============================================================================]\r
 [Compile.Ipf.s]\r
 \r
+#\r
+# Add build dependency check\r
+#\r
 DEP_FILE    = $(DEST_DIR)\$(FILE)S.dep\r
 \r
-!IF EXIST($(DEST_DIR)\$(FILE).pro)\r
+!IF EXIST($(DEP_FILE))\r
+!INCLUDE $(DEP_FILE)\r
+!ENDIF\r
+\r
+!IF "$(EFI_USE_CL_FOR_DEP)" != "YES"\r
+\r
+!IF EXIST($(DEST_DIR)\$(FILE).obj)\r
 DEP_TARGETS = $(DEP_TARGETS) $(DEST_DIR)\$(FILE)S.dep\r
 !IF !EXIST($(DEP_FILE))\r
 CREATEDEPS = YES\r
 !ENDIF\r
 !ENDIF\r
 \r
-!IF EXIST($(DEP_FILE))\r
-!INCLUDE $(DEP_FILE)\r
-!ENDIF\r
-\r
 #\r
 # Update dep file for next round incremental build\r
 #\r
-$(DEP_FILE) : $(DEST_DIR)\$(FILE).pro\r
+$(DEP_FILE) : $(DEST_DIR)\$(FILE).obj\r
   $(MAKEDEPS) -f $(SOURCE_FILE_NAME) $(DEP_FLAGS)\r
 \r
+!ENDIF\r
+\r
 #\r
 # Compile the file\r
 #\r
-$(DEST_DIR)\$(FILE).pro : $(SOURCE_FILE_NAME) $(INF_FILENAME) $(ALL_DEPS)\r
-  $(CC) $(C_FLAGS_PRO) $(SOURCE_FILE_NAME) > $@\r
-\r
-$(DEST_DIR)\$(FILE).obj : $(DEST_DIR)\$(FILE).pro\r
+$(DEST_DIR)\$(FILE).obj : $(SOURCE_FILE_NAME) $(INF_FILENAME) $(ALL_DEPS)\r
+!IF "$(EFI_USE_CL_FOR_DEP)" != "YES"\r
+  $(CC) $(C_FLAGS_PRO) $(SOURCE_FILE_NAME) > $(DEST_DIR)\$(FILE).pro\r
+!ELSE\r
+  -$(CC) $(C_FLAGS_PRO) $(SOURCE_FILE_NAME) /showIncludes > $(DEST_DIR)\$(FILE).pro 2> $(DEST_DIR)\$(FILE)S.cl\r
+  @$(MAKEDEPS) -f $(DEST_DIR)\$(FILE)S.cl $(DEP_FLAGS2)\r
+!ENDIF\r
   $(ASM) $(ASM_FLAGS) $(DEST_DIR)\$(FILE).pro\r
 \r
 [=============================================================================]\r
 [Compile.Ia32.c,Compile.Ipf.c,Compile.x64.c]\r
 \r
+#\r
+# Add build dependency check\r
+#\r
 DEP_FILE    = $(DEST_DIR)\$(FILE).dep\r
 \r
+!IF EXIST($(DEP_FILE))\r
+!INCLUDE $(DEP_FILE)\r
+!ENDIF\r
+\r
+!IF "$(EFI_USE_CL_FOR_DEP)" != "YES"\r
+\r
 !IF EXIST($(DEST_DIR)\$(FILE).obj)\r
 DEP_TARGETS = $(DEP_TARGETS) $(DEST_DIR)\$(FILE).dep\r
 !IF !EXIST($(DEP_FILE))\r
@@ -180,27 +207,37 @@ CREATEDEPS = YES
 !ENDIF\r
 !ENDIF\r
 \r
-!IF EXIST($(DEP_FILE))\r
-!INCLUDE $(DEP_FILE)\r
-!ENDIF\r
-\r
 #\r
 # Update dep file for next round incremental build\r
 #\r
 $(DEP_FILE) : $(DEST_DIR)\$(FILE).obj\r
   $(MAKEDEPS) -f $(SOURCE_FILE_NAME) $(DEP_FLAGS)\r
 \r
+!ENDIF\r
+  \r
 #\r
 # Compile the file\r
 #\r
 $(DEST_DIR)\$(FILE).obj : $(SOURCE_FILE_NAME) $(INF_FILENAME) $(ALL_DEPS)\r
+!IF "$(EFI_USE_CL_FOR_DEP)" != "YES"\r
   $(CC) $(C_FLAGS) $(SOURCE_FILE_NAME)\r
+!ELSE\r
+  -$(CC) $(C_FLAGS) $(SOURCE_FILE_NAME) /showIncludes > $(DEST_DIR)\$(FILE).cl\r
+  @$(MAKEDEPS) -f $(DEST_DIR)\$(FILE).cl $(DEP_FLAGS2)\r
+!ENDIF\r
 \r
 [=============================================================================]\r
 [Compile.Ebc.c]\r
 \r
+#\r
+# Add build dependency check\r
+#\r
 DEP_FILE    = $(DEST_DIR)\$(FILE).dep\r
 \r
+!IF EXIST($(DEP_FILE))\r
+!INCLUDE $(DEP_FILE)\r
+!ENDIF\r
+\r
 !IF EXIST($(DEST_DIR)\$(FILE).obj)\r
 DEP_TARGETS = $(DEP_TARGETS) $(DEST_DIR)\$(FILE).dep\r
 !IF !EXIST($(DEP_FILE))\r
@@ -208,10 +245,6 @@ CREATEDEPS = YES
 !ENDIF\r
 !ENDIF\r
 \r
-!IF EXIST($(DEP_FILE))\r
-!INCLUDE $(DEP_FILE)\r
-!ENDIF\r
-\r
 #\r
 # Update dep file for next round incremental build\r
 #\r
@@ -351,8 +384,32 @@ clean :
 #\r
 LIB_NAME = $(LIB_DIR)\$(BASE_NAME).lib\r
 \r
+#\r
+# $(DEP_TARGETS) are not needed for binary build.\r
+#\r
+!IF ("$(BINARY)" == "TRUE") || (("$(BINARY)" == "") && ("$(EFI_BINARY_LIBRARY)" == "YES"))\r
+DEP_TARGETS=\r
+CREATEDEPS=\r
+!ENDIF\r
+\r
+#\r
+# Module can be built from source code or binary files. \r
+#\r
+!IF ((("$(BINARY)" == "TRUE") || (("$(BINARY)" == "") && ("$(EFI_BINARY_LIBRARY)" == "YES"))) \\r
+    && EXIST($(EFI_PLATFORM_BIN)\$(PROCESSOR)\$(BASE_NAME).lib))\r
+$(LIB_NAME) : $(EFI_PLATFORM_BIN)\$(PROCESSOR)\$(BASE_NAME).lib\r
+  copy $(EFI_PLATFORM_BIN)\$(PROCESSOR)\$(BASE_NAME).lib $(LIB_NAME) /Y\r
+  if exist $(EFI_PLATFORM_BIN)\$(PROCESSOR)\$(BASE_NAME)Obj.pdb \\r
+  copy $(EFI_PLATFORM_BIN)\$(PROCESSOR)\$(BASE_NAME)Obj.pdb $(DEST_DIR)\$(BASE_NAME)Obj.pdb /Y\r
+!ELSE\r
 $(LIB_NAME) : $(OBJECTS) $(LIBS) $(INF_FILENAME) $(ENV_DEPS)\r
   $(LIB) $(LIB_FLAGS) $(OBJECTS) $(LIBS) /OUT:$@\r
+!IF ("$(EFI_BINARY_BUILD)" == "YES")\r
+  if not exist $(EFI_PLATFORM_BIN)\$(PROCESSOR) mkdir $(EFI_PLATFORM_BIN)\$(PROCESSOR)\r
+  if exist $(LIB_NAME) copy $(LIB_NAME) $(EFI_PLATFORM_BIN)\$(PROCESSOR)\$(BASE_NAME).lib /Y\r
+  if exist $(DEST_DIR)\$(BASE_NAME)Obj.pdb copy $(DEST_DIR)\$(BASE_NAME)Obj.pdb $(EFI_PLATFORM_BIN)\$(PROCESSOR)\$(BASE_NAME)Obj.pdb /Y\r
+!ENDIF\r
+!ENDIF\r
 \r
 !IF "$(CREATEDEPS)"=="YES"\r
 all : $(DEP_TARGETS)\r
@@ -558,10 +615,31 @@ $(TARGET_PE32) : $(TARGET_EFI)
   $(GENSECTION) -I $(TARGET_EFI) -O $(TARGET_PE32) -S EFI_SECTION_PE32\r
 \r
 #\r
-# Run FWImage on the DLL to set it as an EFI image type.\r
+# $(DEP_TARGETS) are not needed for binary build.\r
+#\r
+!IF "$(BINARY)" == "TRUE"\r
+DEP_TARGETS=\r
+CREATEDEPS=\r
+!ENDIF\r
+\r
+#\r
+# Build module to generate *.efi file from source code or binary file. \r
 #\r
+!IF (("$(BINARY)" == "TRUE") && EXIST($(EFI_PLATFORM_BIN)\$(PROCESSOR)\$(BASE_NAME).efi))\r
+LOCALIZE_TARGETS=\r
+$(TARGET_EFI) : $(EFI_PLATFORM_BIN)\$(PROCESSOR)\$(BASE_NAME).efi\r
+  copy $(EFI_PLATFORM_BIN)\$(PROCESSOR)\$(BASE_NAME).efi $(TARGET_EFI) /Y\r
+  if exist $(EFI_PLATFORM_BIN)\$(PROCESSOR)\$(BASE_NAME).pdb \\r
+  copy $(EFI_PLATFORM_BIN)\$(PROCESSOR)\$(BASE_NAME).pdb $(TARGET_PDB) /Y\r
+!ELSE\r
 $(TARGET_EFI) : $(TARGET_DLL) $(INF_FILENAME)\r
   $(FWIMAGE) -t 0 $(COMPONENT_TYPE) $(TARGET_DLL) $(TARGET_EFI)\r
+!IF ("$(EFI_BINARY_BUILD)" == "YES")\r
+  if not exist $(EFI_PLATFORM_BIN)\$(PROCESSOR) mkdir $(EFI_PLATFORM_BIN)\$(PROCESSOR)\r
+  if exist $(TARGET_EFI) copy $(TARGET_EFI) $(EFI_PLATFORM_BIN)\$(PROCESSOR)\$(BASE_NAME).efi /Y\r
+  if exist $(TARGET_PDB) copy $(TARGET_PDB) $(EFI_PLATFORM_BIN)\$(PROCESSOR)\$(BASE_NAME).pdb /Y\r
+!ENDIF\r
+!ENDIF\r
 \r
 !ENDIF\r
 \r
@@ -621,12 +699,18 @@ DPX_SOURCE_FILE = $(DPX_SOURCE_OVERRIDE)
 \r
 !IF "$(DPX_SOURCE_FILE)" != ""\r
 !IF EXIST ($(DPX_SOURCE_FILE))\r
+\r
 #\r
-# Add dependency check for dxs file, because dxs file depends on PPI or \r
-# PROTOCOL guid defintions.\r
+# Add build dependency check\r
 #\r
 DEP_FILE    = $(DEST_DIR)\$(BASE_NAME)dxs.dep\r
 \r
+!IF EXIST($(DEP_FILE))\r
+!INCLUDE $(DEP_FILE)\r
+!ENDIF\r
+\r
+!IF "$(EFI_USE_CL_FOR_DEP)" != "YES"\r
+\r
 !IF EXIST($(TARGET_DPX))\r
 DEP_TARGETS = $(DEP_TARGETS) $(DEST_DIR)\$(BASE_NAME)dxs.dep\r
 !IF !EXIST($(DEP_FILE))\r
@@ -634,17 +718,21 @@ CREATEDEPS = YES
 !ENDIF\r
 !ENDIF\r
 \r
-!IF EXIST($(DEP_FILE))\r
-!INCLUDE $(DEP_FILE)\r
-!ENDIF\r
 #\r
 # Update dep file for next round incremental build\r
 #\r
 $(DEP_FILE) : $(TARGET_DPX)\r
   $(MAKEDEPS) -f $(DPX_SOURCE_FILE) $(DEP_FLAGS)\r
 \r
+!ENDIF\r
+\r
 $(TARGET_DPX) : $(DPX_SOURCE_FILE) $(INF_FILENAME)\r
-  $(CC) /nologo $(INC) $(VERSION_FLAGS) /EP $(DPX_SOURCE_FILE) > $*.tmp1\r
+!IF "$(EFI_USE_CL_FOR_DEP)" != "YES"\r
+  $(CC) $(C_FLAGS_DPX) $(DPX_SOURCE_FILE) > $*.tmp1\r
+!ELSE\r
+  -$(CC) $(C_FLAGS_DPX) $(DPX_SOURCE_FILE) /showIncludes > $*.tmp1 2> $(DEST_DIR)\$(BASE_NAME)dxs.cl\r
+  @$(MAKEDEPS) -f $(DEST_DIR)\$(BASE_NAME)dxs.cl $(DEP_FLAGS2)\r
+!ENDIF\r
   $(GENDEPEX) -I $*.tmp1 -O $*.tmp2\r
   $(GENSECTION) -I $*.tmp2 -O $@ -S $(DEPEX_TYPE)\r
   del $*.tmp1 > NUL\r
@@ -666,8 +754,40 @@ $(TARGET_DPX) :
 !IF "$(COMPONENT_TYPE)" == "COMBINED_PEIM_DRIVER"\r
 !IF "$(DXE_DPX_SOURCE)" != ""\r
 !IF EXIST ($(SOURCE_DIR)\$(DXE_DPX_SOURCE))\r
+\r
+#\r
+# Add build dependency check\r
+#\r
+DEP_FILE    = $(DEST_DIR)\$(BASE_NAME)dxs2.dep\r
+\r
+!IF EXIST($(DEP_FILE))\r
+!INCLUDE $(DEP_FILE)\r
+!ENDIF\r
+\r
+!IF "$(EFI_USE_CL_FOR_DEP)" != "YES"\r
+\r
+!IF EXIST($(TARGET_DXE_DPX))\r
+DEP_TARGETS = $(DEP_TARGETS) $(DEST_DIR)\$(BASE_NAME)dxs2.dep\r
+!IF !EXIST($(DEP_FILE))\r
+CREATEDEPS = YES\r
+!ENDIF\r
+!ENDIF\r
+\r
+#\r
+# Update dep file for next round incremental build\r
+#\r
+$(DEP_FILE) : $(TARGET_DXE_DPX)\r
+  $(MAKEDEPS) -f $(SOURCE_DIR)\$(DXE_DPX_SOURCE) $(DEP_FLAGS)\r
+\r
+!ENDIF\r
+\r
 $(TARGET_DXE_DPX) : $(SOURCE_DIR)\$(DXE_DPX_SOURCE) $(INF_FILENAME)\r
-  $(CC) /nologo $(INC) $(VERSION_FLAGS) /EP $(SOURCE_DIR)\$(DXE_DPX_SOURCE) > $*.tmp1\r
+!IF "$(EFI_USE_CL_FOR_DEP)" != "YES"\r
+  $(CC) $(C_FLAGS_DPX) $(SOURCE_DIR)\$(DXE_DPX_SOURCE) > $*.tmp1\r
+!ELSE\r
+  -$(CC) $(C_FLAGS_DPX) $(SOURCE_DIR)\$(DXE_DPX_SOURCE) /showIncludes > $*.tmp1 2> $(DEST_DIR)\$(BASE_NAME)dxs2.cl\r
+  @$(MAKEDEPS) -f $(DEST_DIR)\$(BASE_NAME)dxs2.cl $(DEP_FLAGS2)\r
+!ENDIF\r
   $(GENDEPEX) -I $*.tmp1 -O $*.tmp2\r
   $(GENSECTION) -I $*.tmp2 -O $@ -S EFI_SECTION_DXE_DEPEX\r
   del $*.tmp1 > NUL\r
@@ -778,10 +898,30 @@ $(TARGET_TES) : $(TARGET_TE)
   $(GENSECTION) -I $(TARGET_TE) -O $(TARGET_TES) -S EFI_SECTION_TE\r
 \r
 #\r
-# Run FWImage on the DLL to set it as an EFI image type.\r
+# $(DEP_TARGETS) are not needed for binary build.\r
+#\r
+!IF "$(BINARY)" == "TRUE"\r
+DEP_TARGETS=\r
+CREATEDEPS=\r
+!ENDIF\r
+\r
 #\r
+# Build module to generate *.efi file from source code or binary file.\r
+#\r
+!IF (("$(BINARY)" == "TRUE") && EXIST($(EFI_PLATFORM_BIN)\$(PROCESSOR)\$(BASE_NAME).efi))\r
+$(TARGET_EFI) : $(EFI_PLATFORM_BIN)\$(PROCESSOR)\$(BASE_NAME).efi\r
+  copy $(EFI_PLATFORM_BIN)\$(PROCESSOR)\$(BASE_NAME).efi $(TARGET_EFI) /Y\r
+  if exist $(EFI_PLATFORM_BIN)\$(PROCESSOR)\$(BASE_NAME).pdb \\r
+  copy $(EFI_PLATFORM_BIN)\$(PROCESSOR)\$(BASE_NAME).pdb $(TARGET_PDB) /Y\r
+!ELSE\r
 $(TARGET_EFI) : $(TARGET_DLL) $(INF_FILENAME)\r
   $(FWIMAGE) $(COMPONENT_TYPE) $(TARGET_DLL) $(TARGET_EFI)\r
+!IF ("$(EFI_BINARY_BUILD)" == "YES")\r
+  if not exist $(EFI_PLATFORM_BIN)\$(PROCESSOR) mkdir $(EFI_PLATFORM_BIN)\$(PROCESSOR)\r
+  if exist $(TARGET_EFI) copy $(TARGET_EFI) $(EFI_PLATFORM_BIN)\$(PROCESSOR)\$(BASE_NAME).efi /Y\r
+  if exist $(TARGET_PDB) copy $(TARGET_PDB) $(EFI_PLATFORM_BIN)\$(PROCESSOR)\$(BASE_NAME).pdb /Y\r
+!ENDIF\r
+!ENDIF\r
 \r
 #\r
 # Run GenTEImage on the built .efi file to create our TE file.\r
@@ -845,12 +985,18 @@ DPX_SOURCE_FILE = $(DPX_SOURCE_OVERRIDE)
 \r
 !IF "$(DPX_SOURCE_FILE)" != ""\r
 !IF EXIST ($(DPX_SOURCE_FILE))\r
+\r
 #\r
-# Add dependency check for dxs file, because dxs file depends on PPI or \r
-# PROTOCOL guid defintions.\r
+# Add build dependency check\r
 #\r
 DEP_FILE    = $(DEST_DIR)\$(BASE_NAME)dxs.dep\r
 \r
+!IF EXIST($(DEP_FILE))\r
+!INCLUDE $(DEP_FILE)\r
+!ENDIF\r
+\r
+!IF "$(EFI_USE_CL_FOR_DEP)" != "YES"\r
+\r
 !IF EXIST($(TARGET_DPX))\r
 DEP_TARGETS = $(DEP_TARGETS) $(DEST_DIR)\$(BASE_NAME)dxs.dep\r
 !IF !EXIST($(DEP_FILE))\r
@@ -858,17 +1004,21 @@ CREATEDEPS = YES
 !ENDIF\r
 !ENDIF\r
 \r
-!IF EXIST($(DEP_FILE))\r
-!INCLUDE $(DEP_FILE)\r
-!ENDIF\r
 #\r
 # Update dep file for next round incremental build\r
 #\r
 $(DEP_FILE) : $(TARGET_DPX)\r
   $(MAKEDEPS) -f $(DPX_SOURCE_FILE) $(DEP_FLAGS)\r
 \r
+!ENDIF\r
+\r
 $(TARGET_DPX) : $(DPX_SOURCE_FILE) $(INF_FILENAME)\r
-  $(CC) /nologo $(INC) $(VERSION_FLAGS) /EP $(DPX_SOURCE_FILE) > $*.tmp1\r
+!IF "$(EFI_USE_CL_FOR_DEP)" != "YES"\r
+  $(CC) $(C_FLAGS_DPX) $(DPX_SOURCE_FILE) > $*.tmp1\r
+!ELSE\r
+  -$(CC) $(C_FLAGS_DPX) $(DPX_SOURCE_FILE) /showIncludes > $*.tmp1 2> $(DEST_DIR)\$(BASE_NAME)dxs.cl\r
+  @$(MAKEDEPS) -f $(DEST_DIR)\$(BASE_NAME)dxs.cl $(DEP_FLAGS2)\r
+!ENDIF\r
   $(GENDEPEX) -I $*.tmp1 -O $*.tmp2\r
   $(GENSECTION) -I $*.tmp2 -O $@ -S $(DEPEX_TYPE)\r
   del $*.tmp1 > NUL\r
@@ -1042,12 +1192,18 @@ DPX_SOURCE_FILE = $(DPX_SOURCE_OVERRIDE)
 \r
 !IF "$(DPX_SOURCE_FILE)" != ""\r
 !IF EXIST ($(DPX_SOURCE_FILE))\r
+\r
 #\r
-# Add dependency check for dxs file, because dxs file depends on PPI or \r
-# PROTOCOL guid defintions.\r
+# Add build dependency check\r
 #\r
 DEP_FILE    = $(DEST_DIR)\$(BASE_NAME)dxs.dep\r
 \r
+!IF EXIST($(DEP_FILE))\r
+!INCLUDE $(DEP_FILE)\r
+!ENDIF\r
+\r
+!IF "$(EFI_USE_CL_FOR_DEP)" != "YES"\r
+\r
 !IF EXIST($(TARGET_DPX))\r
 DEP_TARGETS = $(DEP_TARGETS) $(DEST_DIR)\$(BASE_NAME)dxs.dep\r
 !IF !EXIST($(DEP_FILE))\r
@@ -1055,17 +1211,21 @@ CREATEDEPS = YES
 !ENDIF\r
 !ENDIF\r
 \r
-!IF EXIST($(DEP_FILE))\r
-!INCLUDE $(DEP_FILE)\r
-!ENDIF\r
 #\r
 # Update dep file for next round incremental build\r
 #\r
 $(DEP_FILE) : $(TARGET_DPX)\r
   $(MAKEDEPS) -f $(DPX_SOURCE_FILE) $(DEP_FLAGS)\r
 \r
+!ENDIF\r
+\r
 $(TARGET_DPX) : $(DPX_SOURCE_FILE) $(INF_FILENAME)\r
-  $(CC) /nologo $(INC) $(VERSION_FLAGS) /EP $(DPX_SOURCE_FILE) > $*.tmp1\r
+!IF "$(EFI_USE_CL_FOR_DEP)" != "YES"\r
+  $(CC) $(C_FLAGS_DPX) $(DPX_SOURCE_FILE) > $*.tmp1\r
+!ELSE\r
+  -$(CC) $(C_FLAGS_DPX) $(DPX_SOURCE_FILE) /showIncludes > $*.tmp1 2> $(DEST_DIR)\$(BASE_NAME)dxs.cl\r
+  @$(MAKEDEPS) -f $(DEST_DIR)\$(BASE_NAME)dxs.cl $(DEP_FLAGS2)\r
+!ENDIF\r
   $(GENDEPEX) -I $*.tmp1 -O $*.tmp2\r
   $(GENSECTION) -I $*.tmp2 -O $@ -S $(DEPEX_TYPE)\r
   del $*.tmp1 > NUL\r
@@ -1210,12 +1370,18 @@ DPX_SOURCE_FILE = $(DPX_SOURCE_OVERRIDE)
 \r
 !IF "$(DPX_SOURCE_FILE)" != ""\r
 !IF EXIST ($(DPX_SOURCE_FILE))\r
+\r
 #\r
-# Add dependency check for dxs file, because dxs file depends on PPI or \r
-# PROTOCOL guid defintions.\r
+# Add build dependency check\r
 #\r
 DEP_FILE    = $(DEST_DIR)\$(BASE_NAME)dxs.dep\r
 \r
+!IF EXIST($(DEP_FILE))\r
+!INCLUDE $(DEP_FILE)\r
+!ENDIF\r
+\r
+!IF "$(EFI_USE_CL_FOR_DEP)" != "YES"\r
+\r
 !IF EXIST($(TARGET_DPX))\r
 DEP_TARGETS = $(DEP_TARGETS) $(DEST_DIR)\$(BASE_NAME)dxs.dep\r
 !IF !EXIST($(DEP_FILE))\r
@@ -1223,17 +1389,21 @@ CREATEDEPS = YES
 !ENDIF\r
 !ENDIF\r
 \r
-!IF EXIST($(DEP_FILE))\r
-!INCLUDE $(DEP_FILE)\r
-!ENDIF\r
 #\r
 # Update dep file for next round incremental build\r
 #\r
 $(DEP_FILE) : $(TARGET_DPX)\r
   $(MAKEDEPS) -f $(DPX_SOURCE_FILE) $(DEP_FLAGS)\r
 \r
+!ENDIF\r
+\r
 $(TARGET_DPX) : $(DPX_SOURCE_FILE) $(INF_FILENAME)\r
-  $(CC) /nologo $(INC) $(VERSION_FLAGS) /EP $(DPX_SOURCE_FILE) > $*.tmp1\r
+!IF "$(EFI_USE_CL_FOR_DEP)" != "YES"\r
+  $(CC) $(C_FLAGS_DPX) $(DPX_SOURCE_FILE) > $*.tmp1\r
+!ELSE\r
+  -$(CC) $(C_FLAGS_DPX) $(DPX_SOURCE_FILE) /showIncludes > $*.tmp1 2> $(DEST_DIR)\$(BASE_NAME)dxs.cl\r
+  @$(MAKEDEPS) -f $(DEST_DIR)\$(BASE_NAME)dxs.cl $(DEP_FLAGS2)\r
+!ENDIF\r
   $(GENDEPEX) -I $*.tmp1 -O $*.tmp2\r
   $(GENSECTION) -I $*.tmp2 -O $@ -S $(DEPEX_TYPE)\r
   del $*.tmp1 > NUL\r
@@ -1348,8 +1518,15 @@ LOCALIZE        = YES
 [=============================================================================]\r
 [Compile.Ia32.Vfr,Compile.Ipf.Vfr,Compile.x64.Vfr]\r
 \r
+#\r
+# Add build dependency check\r
+#\r
 DEP_FILE    = $(DEST_DIR)\$(FILE)Vfr.dep\r
 \r
+!IF EXIST($(DEP_FILE))\r
+!INCLUDE $(DEP_FILE)\r
+!ENDIF\r
+\r
 !IF EXIST($(DEST_DIR)\$(FILE).obj)\r
 DEP_TARGETS = $(DEP_TARGETS) $(DEST_DIR)\$(FILE)Vfr.dep\r
 !IF !EXIST($(DEP_FILE))\r
@@ -1357,10 +1534,6 @@ CREATEDEPS = YES
 !ENDIF\r
 !ENDIF\r
 \r
-!IF EXIST($(DEP_FILE))\r
-!INCLUDE $(DEP_FILE)\r
-!ENDIF\r
-\r
 #\r
 # Update dep file for next round incremental build\r
 #\r
@@ -1425,8 +1598,15 @@ $(DEST_DIR)\$(FILE).obj : $(SOURCE_FILE_NAME) $(INF_FILENAME) $(ALL_DEPS)
 [=============================================================================]\r
 [Compile.Ia32.Ifr_Bin,Compile.Ipf.Ifr_Bin,Compile.x64.Ifr_Bin]\r
 \r
+#\r
+# Add build dependency check\r
+#\r
 DEP_FILE    = $(DEST_DIR)\$(FILE)Vfr.dep\r
 \r
+!IF EXIST($(DEP_FILE))\r
+!INCLUDE $(DEP_FILE)\r
+!ENDIF\r
+\r
 !IF EXIST($(DEST_DIR)\$(FILE).obj)\r
 DEP_TARGETS = $(DEP_TARGETS) $(DEST_DIR)\$(FILE)Vfr.dep\r
 !IF !EXIST($(DEP_FILE))\r
@@ -1434,10 +1614,6 @@ CREATEDEPS = YES
 !ENDIF\r
 !ENDIF\r
 \r
-!IF EXIST($(DEP_FILE))\r
-!INCLUDE $(DEP_FILE)\r
-!ENDIF\r
-\r
 #\r
 # Update dep file for next round incremental build\r
 #\r
@@ -1472,8 +1648,15 @@ HII_IFR_PACK_FILES = $(HII_IFR_PACK_FILES) $(DEST_DIR)\$(FILE).hpk
 [=============================================================================]\r
 [Compile.Ebc.Ifr_Bin]\r
 \r
+#\r
+# Add build dependency check\r
+#\r
 DEP_FILE    = $(DEST_DIR)\$(FILE)Vfr.dep\r
 \r
+!IF EXIST($(DEP_FILE))\r
+!INCLUDE $(DEP_FILE)\r
+!ENDIF\r
+\r
 !IF EXIST($(DEST_DIR)\$(FILE).obj)\r
 DEP_TARGETS = $(DEP_TARGETS) $(DEST_DIR)\$(FILE)Vfr.dep\r
 !IF !EXIST($(DEP_FILE))\r
@@ -1481,10 +1664,6 @@ CREATEDEPS = YES
 !ENDIF\r
 !ENDIF\r
 \r
-!IF EXIST($(DEP_FILE))\r
-!INCLUDE $(DEP_FILE)\r
-!ENDIF\r
-\r
 #\r
 # Update dep file for next round incremental build\r
 #\r
index f9fae293590dae95534829d7c3f645add4153db1..52fcb026d00252f9c846bc8b37f7af2285f4dc41 100644 (file)
@@ -275,7 +275,6 @@ IMAGE_SCRIPT =
   }    \r
 }\r
 \r
-\r
 [=============================================================================]\r
 [Package.BS_DRIVER.Default,Package.RT_DRIVER.Default]\r
 PACKAGE.INF\r
@@ -359,6 +358,7 @@ IMAGE_SCRIPT =
     $(SOURCE_FV)Fv.sec\r
   }\r
 }\r
+\r
 [=============================================================================]\r
 #\r
 # Stripped package descriptions for size reduction.\r
@@ -422,6 +422,7 @@ IMAGE_SCRIPT =
 {\r
   $(BASE_NAME).tes\r
 }\r
+\r
 [=============================================================================]\r
 [Package.PE32_PEIM.DefaultStripped]\r
 PACKAGE.INF\r
@@ -504,7 +505,6 @@ IMAGE_SCRIPT =
   }\r
 }\r
 \r
-\r
 [=============================================================================]\r
 [Package.BS_DRIVER.DefaultStripped,Package.RT_DRIVER.DefaultStripped]\r
 PACKAGE.INF\r
@@ -522,7 +522,6 @@ IMAGE_SCRIPT =
   }\r
 }\r
 \r
-\r
 [=============================================================================]\r
 [Package.FvImageFile.DefaultStripped]\r
 PACKAGE.INF\r
@@ -556,3 +555,41 @@ IMAGE_SCRIPT =
 }\r
 \r
 [=============================================================================]\r
+[Package.AcpiTable.Default]\r
+PACKAGE.INF\r
+\[.]\r
+BASE_NAME                   = $(BASE_NAME)\r
+FFS_FILEGUID                = $(FILE_GUID)\r
+FFS_FILETYPE                = EFI_FV_FILETYPE_FREEFORM\r
+FFS_ATTRIB_CHECKSUM         = TRUE\r
+\r
+IMAGE_SCRIPT =\r
+{\r
+  Compress ($(COMPRESS_METHOD)) {\r
+    Tool (\r
+      $(OEMTOOLPATH)\GenCRC32Section\r
+      ARGS= -i $(SECTION_TARGETS)\r
+               $(DEST_DIR)\$(BASE_NAME).ui\r
+            -o $(DEST_DIR)\$(BASE_NAME).crc32\r
+      OUTPUT = $(DEST_DIR)\$(BASE_NAME).crc32\r
+    )\r
+  }\r
+}\r
+\r
+[=============================================================================]\r
+[Package.AcpiTable.DefaultStripped]\r
+PACKAGE.INF\r
+\[.]\r
+BASE_NAME                   = $(BASE_NAME)\r
+FFS_FILEGUID                = $(FILE_GUID)\r
+FFS_FILETYPE                = EFI_FV_FILETYPE_FREEFORM\r
+FFS_ATTRIB_CHECKSUM         = TRUE\r
+\r
+IMAGE_SCRIPT =\r
+{\r
+  Compress ($(COMPRESS_METHOD)) {\r
+    $(SECTION_TARGETS)\r
+  }\r
+}\r
+\r
+[=============================================================================]\r
index 13bfe9171b99959aed1da5821fa03b839016932f..d431a9c72faee3f44de9a525fd61817398af9c80 100644 (file)
@@ -269,7 +269,6 @@ IMAGE_SCRIPT =
   $(BASE_NAME).ver \\r
 }\r
 \r
-\r
 [=============================================================================]\r
 [Package.DxeIplPad.Default]\r
 PACKAGE.INF \r
@@ -285,7 +284,6 @@ IMAGE_SCRIPT =
   $(BASE_NAME).pad \\r
 }\r
 \r
-\r
 [=============================================================================]\r
 [Package.BS_DRIVER.DxeMain]\r
 PACKAGE.INF\r
@@ -304,7 +302,6 @@ IMAGE_SCRIPT =
   }\r
 }\r
 \r
-\r
 [=============================================================================]\r
 [Package.BS_DRIVER.Default,Package.RT_DRIVER.Default,Package.SAL_RT_DRIVER.Default]\r
 PACKAGE.INF\r
@@ -388,4 +385,27 @@ IMAGE_SCRIPT =
     $(SOURCE_FV)Fv.sec\r
   }\r
 }\r
+\r
+[=============================================================================]\r
+[Package.AcpiTable.Default]\r
+PACKAGE.INF\r
+\[.]\r
+BASE_NAME                   = $(BASE_NAME)\r
+FFS_FILEGUID                = $(FILE_GUID)\r
+FFS_FILETYPE                = EFI_FV_FILETYPE_FREEFORM\r
+FFS_ATTRIB_CHECKSUM         = TRUE\r
+\r
+IMAGE_SCRIPT =\r
+{\r
+  Compress ($(COMPRESS_METHOD)) {\r
+    Tool (\r
+      $(OEMTOOLPATH)\GenCRC32Section\r
+      ARGS= -i $(SECTION_TARGETS)\r
+               $(DEST_DIR)\$(BASE_NAME).ui\r
+            -o $(DEST_DIR)\$(BASE_NAME).crc32\r
+      OUTPUT = $(DEST_DIR)\$(BASE_NAME).crc32\r
+    )\r
+  }\r
+}\r
+\r
 [=============================================================================]\r
index 43140493617f7c75384ce63416ee43d1f9d6e7b4..8fdea6f5b1213a47cd926c51c883710c92d36bf1 100644 (file)
@@ -275,7 +275,6 @@ IMAGE_SCRIPT =
   }    \r
 }\r
 \r
-\r
 [=============================================================================]\r
 [Package.BS_DRIVER.Default,Package.RT_DRIVER.Default,Package.SAL_RT_DRIVER.Default]\r
 PACKAGE.INF\r
@@ -406,6 +405,7 @@ IMAGE_SCRIPT =
 {\r
   $(BASE_NAME).tes\r
 }\r
+\r
 [=============================================================================]\r
 [Package.PE32_PEIM.DefaultStripped]\r
 PACKAGE.INF\r
@@ -488,7 +488,6 @@ IMAGE_SCRIPT =
   }\r
 }\r
 \r
-\r
 [=============================================================================]\r
 [Package.BS_DRIVER.DefaultStripped,Package.RT_DRIVER.DefaultStripped,Package.SAL_RT_DRIVER.DefaultStripped]\r
 PACKAGE.INF\r
@@ -506,7 +505,6 @@ IMAGE_SCRIPT =
   }\r
 }\r
 \r
-\r
 [=============================================================================]\r
 [Package.FvImageFile.DefaultStripped]\r
 PACKAGE.INF\r
@@ -539,6 +537,7 @@ IMAGE_SCRIPT =
     $(SOURCE_FV)Fv.sec\r
   }\r
 }\r
+\r
 [=============================================================================]\r
 [Package.SECURITY_CORE.Default|DefaultStripped]\r
 PACKAGE.INF\r
@@ -556,3 +555,41 @@ IMAGE_SCRIPT =
 }\r
 \r
 [=============================================================================]\r
+[Package.AcpiTable.Default]\r
+PACKAGE.INF\r
+\[.]\r
+BASE_NAME                   = $(BASE_NAME)\r
+FFS_FILEGUID                = $(FILE_GUID)\r
+FFS_FILETYPE                = EFI_FV_FILETYPE_FREEFORM\r
+FFS_ATTRIB_CHECKSUM         = TRUE\r
+\r
+IMAGE_SCRIPT =\r
+{\r
+  Compress ($(COMPRESS_METHOD)) {\r
+    Tool (\r
+      $(OEMTOOLPATH)\GenCRC32Section\r
+      ARGS= -i $(SECTION_TARGETS)\r
+               $(DEST_DIR)\$(BASE_NAME).ui\r
+            -o $(DEST_DIR)\$(BASE_NAME).crc32\r
+      OUTPUT = $(DEST_DIR)\$(BASE_NAME).crc32\r
+    )\r
+  }\r
+}\r
+\r
+[=============================================================================]\r
+[Package.AcpiTable.DefaultStripped]\r
+PACKAGE.INF\r
+\[.]\r
+BASE_NAME                   = $(BASE_NAME)\r
+FFS_FILEGUID                = $(FILE_GUID)\r
+FFS_FILETYPE                = EFI_FV_FILETYPE_FREEFORM\r
+FFS_ATTRIB_CHECKSUM         = TRUE\r
+\r
+IMAGE_SCRIPT =\r
+{\r
+  Compress ($(COMPRESS_METHOD)) {\r
+    $(SECTION_TARGETS)\r
+  }\r
+}\r
+\r
+[=============================================================================]\r
index 5c71f411087d458c21b20256bd667684c55f9289..7b7accc9fd1c3d4138b5d23a84276c7fc72002ab 100644 (file)
@@ -37,3 +37,4 @@ $(EDK_PREFIX)Foundation\Library\EdkIIGlueLib\Library\PeiHobLib\PeiHobLib.inf
 $(EDK_PREFIX)Foundation\Library\EdkIIGlueLib\Library\PeiReportStatusCodeLib\PeiReportStatusCodeLib.inf\r
 $(EDK_PREFIX)Foundation\Library\EdkIIGlueLib\Library\PeiResourcePublicationLib\PeiResourcePublicationLib.inf\r
 $(EDK_PREFIX)Foundation\Library\EdkIIGlueLib\Library\PeiSmbusLib\PeiSmbusLib.inf\r
+$(EDK_PREFIX)Foundation\Library\EdkIIGlueLib\Library\PeiPerformanceLib\PeiPerformanceLib.inf\r
index 8879bf37379d10c864ae5d2a76e1bd7fdf61d7f4..6939a7366b068d4ec73ab92dc293f18bc2e91ee1 100644 (file)
@@ -51,4 +51,6 @@ $(EDK_PREFIX)Foundation\Library\EdkIIGlueLib\Library\DxeServicesTableLib\DxeServ
 $(EDK_PREFIX)Foundation\Library\EdkIIGlueLib\Library\EdkDxeSalLib\EdkDxeSalLib.inf\r
 $(EDK_PREFIX)Foundation\Library\EdkIIGlueLib\Library\EdkDxeRuntimeDriverLib\EdkDxeRuntimeDriverLib.inf\r
 $(EDK_PREFIX)Foundation\Library\EdkIIGlueLib\Library\DxeSmbusLib\DxeSmbusLib.inf\r
-$(EDK_PREFIX)Foundation\Library\EdkIIGlueLib\Library\PeiSmbusLib\PeiSmbusLib.inf
\ No newline at end of file
+$(EDK_PREFIX)Foundation\Library\EdkIIGlueLib\Library\PeiSmbusLib\PeiSmbusLib.inf\r
+$(EDK_PREFIX)Foundation\Library\EdkIIGlueLib\Library\DxePerformanceLib\DxePerformanceLib.inf\r
+$(EDK_PREFIX)Foundation\Library\EdkIIGlueLib\Library\PeiPerformanceLib\PeiPerformanceLib.inf\r
index 7be8ebbe8011adbc2a29288c4a8ebe31efcc9e46..3e0aacab21cfba3c1679f722bd1e64615c559d63 100644 (file)
@@ -1,6 +1,6 @@
 #/*++\r
 #\r
-# Copyright (c) 2004 - 2006, Intel Corporation                                                         \r
+# Copyright (c) 2004 - 2007, Intel Corporation                                                         \r
 # All rights reserved. This program and the accompanying materials                          \r
 # are licensed and made available under the terms and conditions of the BSD License         \r
 # which accompanies this distribution.  The full text of the license may be found at        \r
@@ -25,7 +25,6 @@ $(EDK_PREFIX)Foundation\Cpu\Pentium\CpuIA32Lib\CpuIA32Lib.inf
 $(EDK_PREFIX)Foundation\Cpu\Itanium\CpuIA64Lib\CpuIA64Lib.inf\r
 $(EDK_PREFIX)Foundation\Library\CustomizedDecompress\CustomizedDecompress.inf\r
 $(EDK_PREFIX)Foundation\Library\CompilerStub\CompilerStubLib.inf\r
-$(EDK_PREFIX)Foundation\Library\Dxe\Hob\HobLib.inf\r
 \r
 #\r
 # PEI libraries\r
index bdb37b17a03212784d13f491b7f628f233a37229..18169da5501385ff11932f36f4622dc0adcb3ac0 100644 (file)
@@ -25,7 +25,6 @@ $(EDK_PREFIX)Foundation\Cpu\Pentium\CpuIA32Lib\CpuIA32Lib.inf
 $(EDK_PREFIX)Foundation\Cpu\Itanium\CpuIA64Lib\CpuIA64Lib.inf\r
 $(EDK_PREFIX)Foundation\Library\CustomizedDecompress\CustomizedDecompress.inf\r
 $(EDK_PREFIX)Foundation\Library\CompilerStub\CompilerStubLib.inf\r
-$(EDK_PREFIX)Foundation\Library\Dxe\Hob\HobLib.inf\r
 \r
 #\r
 # PEI libraries\r
@@ -42,10 +41,12 @@ $(EDK_PREFIX)Foundation\Core\Dxe\ArchProtocol\ArchProtocolLib.inf
 $(EDK_PREFIX)Foundation\Efi\Protocol\EfiProtocolLib.inf\r
 $(EDK_PREFIX)Foundation\Framework\Protocol\EdkFrameworkProtocolLib.inf\r
 $(EDK_PREFIX)Foundation\Protocol\EdkProtocolLib.inf\r
+$(EDK_PREFIX)Foundation\Library\Dxe\Hob\HobLib.inf\r
 $(EDK_PREFIX)Foundation\Library\Dxe\EfiDriverLib\EfiDriverLib.inf\r
 $(EDK_PREFIX)Foundation\Library\RuntimeDxe\EfiRuntimeLib\EfiRuntimeLib.inf\r
 $(EDK_PREFIX)Foundation\Library\Dxe\Graphics\Graphics.inf\r
 $(EDK_PREFIX)Foundation\Library\Dxe\EfiIfrSupportLib\EfiIfrSupportLib.inf\r
+$(EDK_PREFIX)Foundation\Library\Dxe\UefiEfiIfrSupportLib\UefiEfiIfrSupportLib.inf\r
 $(EDK_PREFIX)Foundation\Library\Dxe\Print\PrintLib.inf\r
 $(EDK_PREFIX)Foundation\Library\Dxe\EfiScriptLib\EfiScriptLib.inf\r
 $(EDK_PREFIX)Foundation\Library\Dxe\EfiUiLib\EfiUiLib.inf\r
@@ -55,9 +56,3 @@ $(EDK_PREFIX)Foundation\Library\Dxe\EfiUiLib\EfiUiLib.inf
 #\r
 $(EDK_PREFIX)Foundation\Library\Dxe\PrintLite\PrintLib.inf\r
 $(EDK_PREFIX)Foundation\Library\Dxe\GraphicsLite\Graphics.inf\r
-\r
-#\r
-# Module Libraries\r
-#\r
-#$(EDK_PREFIX)Sample\Platform\Generic\Dxe\GenericBds\GenericBds.inf\r
-#$(EDK_PREFIX)Sample\Bus\Usb\UsbLib\Dxe\UsbDxeLib.inf\r
diff --git a/EdkCompatibilityPkg/Sample/Platform/Generic/MonoStatusCode/Pei/MonoStatusCode.h b/EdkCompatibilityPkg/Sample/Platform/Generic/MonoStatusCode/Pei/MonoStatusCode.h
new file mode 100644 (file)
index 0000000..7ff3140
--- /dev/null
@@ -0,0 +1,138 @@
+/*++\r
+\r
+Copyright (c) 2004 - 2005, Intel Corporation                                                         \r
+All rights reserved. This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+  \r
+  MonoStatusCode.h\r
+   \r
+Abstract:\r
+\r
+  Monolithic single PEIM to provide the status code functionality.\r
+  The PEIM is a blend of libraries that correspond to the different status code\r
+  listeners that a platform installs.\r
+\r
+--*/\r
+\r
+#ifndef _MONO_STATUS_CODE_H_\r
+#define _MONO_STATUS_CODE_H_\r
+\r
+//\r
+// Statements that include other files.\r
+//\r
+#include "Tiano.h"\r
+#include "Pei.h"\r
+#include "PeiLib.h"\r
+#include "EfiCommonLib.h"\r
+\r
+//\r
+// Driver Produced DXE Protocol Prototypes\r
+//\r
+#include EFI_PPI_PRODUCER (StatusCode)\r
+\r
+//\r
+// Driver Consumed DXE Protocol Prototypes\r
+//\r
+#include EFI_ARCH_PROTOCOL_CONSUMER (StatusCode)\r
+\r
+//\r
+// Driver GUID includes\r
+//\r
+#include EFI_GUID_DEFINITION (StatusCode)\r
+#include EFI_GUID_DEFINITION (StatusCodeCallerId)\r
+#include EFI_GUID_DEFINITION (GlobalVariable)\r
+\r
+extern EFI_GUID mStatusCodeRuntimeGuid;\r
+\r
+//\r
+// Platform specific function Declarations.  These must be implemented in a\r
+// subdirectory named PlatformName in a file named PlatformStatusCode.c.\r
+// See D845GRG\PlatformStatusCode.c for an example of a simple status code\r
+// implementation.\r
+// See Nt32\PlatformStatusCode.c for an example of a status code implementation\r
+// that relocates itself into memory.\r
+//\r
+//\r
+// This is the driver entry point and must be defined.\r
+//\r
+EFI_STATUS\r
+EFIAPI\r
+InstallMonoStatusCode (\r
+  IN EFI_FFS_FILE_HEADER       *FfsHeader,\r
+  IN EFI_PEI_SERVICES          **PeiServices\r
+  )\r
+;\r
+\r
+//\r
+// This is the platform function to initialize the listeners desired by the\r
+// platform.\r
+//\r
+VOID\r
+PlatformInitializeStatusCode (\r
+  IN EFI_FFS_FILE_HEADER       *FfsHeader,\r
+  IN EFI_PEI_SERVICES          **PeiServices\r
+  )\r
+;\r
+\r
+//\r
+// This is the platform function that calls all of the listeners desired by the\r
+// platform.\r
+//\r
+EFI_STATUS\r
+EFIAPI\r
+PlatformReportStatusCode (\r
+  IN EFI_PEI_SERVICES         **PeiServices,\r
+  IN EFI_STATUS_CODE_TYPE     CodeType,\r
+  IN EFI_STATUS_CODE_VALUE    Value,\r
+  IN UINT32                   Instance,\r
+  IN EFI_GUID                 * CallerId,\r
+  IN EFI_STATUS_CODE_DATA     * Data OPTIONAL\r
+  )\r
+;\r
+\r
+//\r
+// Platform independent function Declarations\r
+//\r
+//\r
+// Initialize the status code listeners and publish the status code PPI.\r
+//\r
+VOID\r
+EFIAPI\r
+InitializeMonoStatusCode (\r
+  IN EFI_FFS_FILE_HEADER       *FfsHeader,\r
+  IN EFI_PEI_SERVICES          **PeiServices\r
+  )\r
+;\r
+\r
+//\r
+// Convert a DXE status code call into a PEI status code call.\r
+//\r
+EFI_STATUS\r
+EFIAPI\r
+TranslateDxeStatusCodeToPeiStatusCode (\r
+  IN EFI_STATUS_CODE_TYPE     CodeType,\r
+  IN EFI_STATUS_CODE_VALUE    Value,\r
+  IN UINT32                   Instance,\r
+  IN EFI_GUID                 * CallerId,\r
+  IN EFI_STATUS_CODE_DATA     * Data OPTIONAL\r
+  )\r
+;\r
+\r
+//\r
+// Publish a HOB that contains the listener to be used by DXE.\r
+//\r
+EFI_STATUS\r
+EFIAPI\r
+InitializeDxeReportStatusCode (\r
+  IN EFI_PEI_SERVICES       **PeiServices\r
+  )\r
+;\r
+\r
+#endif\r
index e950126c4f2b73b3caf7ec15d0e5e3ccf6dfc114..980635dc7f01b55cd3b235e8ebf1e0769b6b652c 100644 (file)
@@ -1,6 +1,6 @@
 /*++\r
 \r
-Copyright (c)  2004 - 2006, Intel Corporation                                                         \r
+Copyright (c)  2004 - 2007, Intel Corporation                                                         \r
 All rights reserved. This program and the accompanying materials                          \r
 are licensed and made available under the terms and conditions of the BSD License         \r
 which accompanies this distribution.  The full text of the license may be found at        \r
@@ -26,27 +26,29 @@ Abstract:
 #include "BsDataHubStatusCode.h"\r
 \r
 //\r
-// Globals only work at BootService Time. NOT at Runtime!\r
+// Initialize FIFO to cache records.\r
 //\r
-static EFI_DATA_HUB_PROTOCOL  *mDataHub;\r
-static EFI_LIST_ENTRY         *mRecordHead;\r
-static EFI_LIST_ENTRY         *mRecordTail;\r
-static INTN                   mRecordNum = 0;\r
-static EFI_EVENT              mLogDataHubEvent;\r
-static EFI_LOCK               mStatusCodeReportLock = EFI_INITIALIZE_LOCK_VARIABLE(EFI_TPL_HIGH_LEVEL);\r
-static BOOLEAN                mEventHandlerActive   = FALSE;\r
+STATIC EFI_LIST_ENTRY   mRecordsFifo    = INITIALIZE_LIST_HEAD_VARIABLE (mRecordsFifo);\r
+STATIC EFI_LIST_ENTRY   mRecordsBuffer  = INITIALIZE_LIST_HEAD_VARIABLE (mRecordsBuffer);\r
+STATIC EFI_EVENT        mLogDataHubEvent;\r
+STATIC BOOLEAN          mEventHandlerActive = FALSE;\r
 \r
+//\r
+// Cache data hub protocol.\r
+//\r
+STATIC EFI_DATA_HUB_PROTOCOL     *mDataHubProtocol;\r
 \r
-STATUS_CODE_RECORD_LIST *\r
-AllocateRecordBuffer (\r
+STATIC\r
+DATA_HUB_STATUS_CODE_DATA_RECORD *\r
+AcquireRecordBuffer (\r
   VOID\r
   )\r
 /*++\r
 \r
 Routine Description:\r
 \r
-  Allocate a new record list node and initialize it.\r
-  Inserting the node into the list isn't the task of this function.\r
+  Return one DATAHUB_STATUSCODE_RECORD space.\r
+  The size of free record pool would be extend, if the pool is empty.\r
 \r
 Arguments:\r
 \r
@@ -58,144 +60,94 @@ Returns:
 \r
 --*/\r
 {\r
-  STATUS_CODE_RECORD_LIST *DataBuffer;\r
-\r
-  DataBuffer = NULL;\r
-\r
-  gBS->AllocatePool (EfiBootServicesData, sizeof (STATUS_CODE_RECORD_LIST), &DataBuffer);\r
-  if (DataBuffer == NULL) {\r
-    return NULL;\r
-  }\r
-\r
-  EfiCommonLibZeroMem (DataBuffer, sizeof (STATUS_CODE_RECORD_LIST));\r
-  DataBuffer->Signature = BS_DATA_HUB_STATUS_CODE_SIGNATURE;\r
-\r
-  return DataBuffer;\r
-}\r
-\r
-DATA_HUB_STATUS_CODE_DATA_RECORD *\r
-AquireEmptyRecordBuffer (\r
-  VOID\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Acquire an empty record buffer from the record list if there's free node,\r
-  or allocate one new node and insert it to the list if the list is full and\r
-  the function isn't run in EFI_TPL_HIGH_LEVEL.\r
+  DATAHUB_STATUSCODE_RECORD *Record;\r
+  EFI_TPL                   CurrentTpl;\r
+  EFI_LIST_ENTRY            *Node;\r
+  UINT32                    Index;\r
 \r
-Arguments:\r
-\r
-  None\r
-\r
-Returns:\r
-\r
-  Pointer to new record buffer. NULL if none available.\r
-\r
---*/\r
-{\r
-  EFI_TPL                 OldTpl;\r
-  STATUS_CODE_RECORD_LIST *DataBuffer;\r
+  Record     = NULL;\r
+  CurrentTpl = gBS->RaiseTPL (EFI_TPL_HIGH_LEVEL);\r
 \r
-  DataBuffer = NULL;\r
+  if (!IsListEmpty (&mRecordsBuffer)) {\r
+    Node = GetFirstNode (&mRecordsBuffer);\r
+    RemoveEntryList (Node);\r
 \r
-  //\r
-  // This function must be reentrant because an event with higher priority may interrupt it\r
-  // and also report status code.\r
-  //\r
-  EfiAcquireLock (&mStatusCodeReportLock);\r
-  if (mRecordTail != mRecordHead->ForwardLink) {\r
-    if (mRecordNum != 0) {\r
-      mRecordHead = mRecordHead->ForwardLink;\r
+    Record = _CR (Node, DATAHUB_STATUSCODE_RECORD, Node);\r
+  } else {\r
+    if (CurrentTpl > EFI_TPL_NOTIFY) {\r
+      gBS->RestoreTPL (CurrentTpl);\r
+      return NULL;\r
     }\r
-    DataBuffer = CR (mRecordHead, STATUS_CODE_RECORD_LIST, Link, BS_DATA_HUB_STATUS_CODE_SIGNATURE);\r
-    mRecordNum++;\r
-    EfiReleaseLock (&mStatusCodeReportLock);\r
 \r
-    //\r
-    // Initalize the record buffer is the responsibility of the producer,\r
-    // because the consummer is in a lock so must keep it short.\r
-    //\r
-    EfiCommonLibZeroMem (&DataBuffer->RecordBuffer[0], BYTES_PER_BUFFER);\r
-  } else if (mRecordNum < MAX_RECORD_NUM) {\r
-    //\r
-    // The condition of "mRecordNum < MAX_RECORD_NUM" is not promised,\r
-    // because mRecodeNum may be increased out of this lock.\r
-    //\r
-    EfiReleaseLock (&mStatusCodeReportLock);\r
-\r
-    //\r
-    // Can't allocate additional buffer in EFI_TPL_HIGH_LEVEL.\r
-    // Reporting too many status code in EFI_TPL_HIGH_LEVEL may cause status code lost.\r
-    //\r
-    OldTpl = gBS->RaiseTPL (EFI_TPL_HIGH_LEVEL);\r
-    if (OldTpl == EFI_TPL_HIGH_LEVEL) {\r
+    gBS->RestoreTPL (CurrentTpl);\r
+    \r
+    gBS->AllocatePool (EfiBootServicesData, sizeof (DATAHUB_STATUSCODE_RECORD) * 16, &Record);\r
+    if (Record == NULL) {\r
       return NULL;\r
     }\r
-    gBS->RestoreTPL (OldTpl);\r
-    DataBuffer = AllocateRecordBuffer ();\r
-    if (DataBuffer == NULL) {\r
-      return NULL;\r
+    EfiCommonLibZeroMem (Record, sizeof (DATAHUB_STATUSCODE_RECORD) * 16);    \r
+\r
+\r
+    CurrentTpl = gBS->RaiseTPL (EFI_TPL_HIGH_LEVEL);\r
+    for (Index = 1; Index < 16; Index++) {\r
+      InsertTailList (&mRecordsBuffer, &Record[Index].Node);\r
     }\r
-    EfiAcquireLock (&mStatusCodeReportLock);\r
-    InsertHeadList (mRecordHead, &DataBuffer->Link);\r
-    mRecordHead = mRecordHead->ForwardLink;\r
-    mRecordNum++;\r
-    EfiReleaseLock (&mStatusCodeReportLock);\r
-  } else {\r
-    EfiReleaseLock (&mStatusCodeReportLock);\r
-    return NULL;\r
   }\r
 \r
-  return (DATA_HUB_STATUS_CODE_DATA_RECORD *) DataBuffer->RecordBuffer;\r
+  Record->Signature = BS_DATA_HUB_STATUS_CODE_SIGNATURE;\r
+  InsertTailList (&mRecordsFifo, &Record->Node);\r
+\r
+  gBS->RestoreTPL (CurrentTpl);\r
+\r
+  return (DATA_HUB_STATUS_CODE_DATA_RECORD *) (Record->Data);\r
 }\r
 \r
-EFI_STATUS\r
-ReleaseRecordBuffer (\r
-  IN  STATUS_CODE_RECORD_LIST  *RecordBuffer\r
+STATIC\r
+DATA_HUB_STATUS_CODE_DATA_RECORD *\r
+RetrieveRecord (\r
+  VOID\r
   )\r
 /*++\r
 \r
 Routine Description:\r
 \r
-  Release a buffer in the list, remove some nodes to keep the list inital length.\r
+  Retrieve one record from Records FIFO. The record would be removed from FIFO and \r
+  release to free record buffer.\r
 \r
 Arguments:\r
 \r
-  RecordBuffer          - Buffer to release\r
+  None\r
 \r
 Returns:\r
 \r
-  EFI_SUCCESS           - If DataRecord is valid\r
-  EFI_UNSUPPORTED       - The record list has empty\r
+  Point to record which is ready to be logged, or NULL if the FIFO of record is empty.\r
 \r
---*/\r
+--*/  \r
 {\r
-  ASSERT (RecordBuffer != NULL);\r
+  DATA_HUB_STATUS_CODE_DATA_RECORD  *RecordData;\r
+  DATAHUB_STATUSCODE_RECORD   *Record;\r
+  EFI_LIST_ENTRY              *Node;\r
+  EFI_TPL                     CurrentTpl;\r
+  \r
+  RecordData = NULL;\r
+  \r
+  CurrentTpl = gBS->RaiseTPL (EFI_TPL_HIGH_LEVEL);\r
 \r
-  //\r
-  // The consummer needn't to be reentrient and the producer won't do any meaningful thing\r
-  // when consummer is logging records.\r
-  //\r
-  if (mRecordNum <= 0) {\r
-    return EFI_UNSUPPORTED;\r
-  } else if (mRecordNum > INITIAL_RECORD_NUM) {\r
-    mRecordTail = mRecordTail->ForwardLink;\r
-    RemoveEntryList (&RecordBuffer->Link);\r
-    mRecordNum--;\r
-    gBS->FreePool (RecordBuffer);\r
-  } else {\r
-    if (mRecordNum != 1) {\r
-      mRecordTail = mRecordTail->ForwardLink;\r
-    }\r
-    mRecordNum--;\r
+  if (!IsListEmpty (&mRecordsFifo)) {\r
+    Node = GetFirstNode (&mRecordsFifo);\r
+    Record = CR (Node, DATAHUB_STATUSCODE_RECORD, Node, BS_DATA_HUB_STATUS_CODE_SIGNATURE);\r
+\r
+    RemoveEntryList (&Record->Node);\r
+    InsertTailList (&mRecordsBuffer, &Record->Node);\r
+    Record->Signature = 0;\r
+    RecordData = (DATA_HUB_STATUS_CODE_DATA_RECORD *) Record->Data;\r
   }\r
 \r
-  return EFI_SUCCESS;\r
+  gBS->RestoreTPL (CurrentTpl);\r
+\r
+  return RecordData;\r
 }\r
 \r
-EFI_BOOTSERVICE\r
 EFI_STATUS\r
 EFIAPI\r
 BsDataHubReportStatusCode (\r
@@ -222,31 +174,32 @@ Returns:
 \r
 --*/\r
 {\r
-  DATA_HUB_STATUS_CODE_DATA_RECORD  *DataHub;\r
-  UINT32                            ErrorLevel;\r
-  VA_LIST                           Marker;\r
-  CHAR8                             *Format;\r
-  UINTN                             Index;\r
-  CHAR16                            FormatBuffer[BYTES_PER_RECORD];\r
-\r
-  DataHub = NULL;\r
+  DATA_HUB_STATUS_CODE_DATA_RECORD  *Record;\r
+  UINT32                     ErrorLevel;\r
+  VA_LIST                    Marker;\r
+  CHAR8                      *Format;\r
+  CHAR16                     FormatBuffer[BYTES_PER_RECORD];\r
+  UINTN                      Index;\r
 \r
+  //\r
+  // See whether in runtime phase or not.\r
+  //\r
   if (EfiAtRuntime ()) {\r
     //\r
     // For now all we do is post code at runtime\r
     //\r
     return EFI_SUCCESS;\r
   }\r
+\r
   //\r
-  // If we had an error while in our event handler, then do nothing so\r
-  // that we don't get in an endless loop.\r
+  // Discard new DataHubRecord caused by DataHub->LogData()\r
   //\r
   if (mEventHandlerActive) {\r
     return EFI_SUCCESS;\r
   }\r
 \r
-  DataHub = (DATA_HUB_STATUS_CODE_DATA_RECORD *) AquireEmptyRecordBuffer ();\r
-  if (DataHub == NULL) {\r
+  Record = AcquireRecordBuffer ();\r
+  if (Record == NULL) {\r
     //\r
     // There are no empty record buffer in private buffers\r
     //\r
@@ -255,24 +208,15 @@ Returns:
   //\r
   // Construct Data Hub Extended Data\r
   //\r
-  DataHub->CodeType = CodeType;\r
-  DataHub->Value    = Value;\r
-  DataHub->Instance = Instance;\r
+  Record->CodeType = CodeType;\r
+  Record->Value    = Value;\r
+  Record->Instance = Instance;\r
 \r
   if (CallerId != NULL) {\r
-    EfiCopyMem (&DataHub->CallerId, CallerId, sizeof (EFI_GUID));\r
-  } else {\r
-    EfiZeroMem (&DataHub->CallerId, sizeof (EFI_GUID));\r
+    EfiCopyMem (&Record->CallerId, CallerId, sizeof (EFI_GUID));\r
   }\r
 \r
-  if (Data == NULL) {\r
-    EfiZeroMem (&DataHub->Data, sizeof (EFI_STATUS_CODE_DATA));\r
-  } else {\r
-    //\r
-    // Copy generic Header\r
-    //\r
-    EfiCopyMem (&DataHub->Data, Data, sizeof (EFI_STATUS_CODE_DATA));\r
-\r
+  if (Data != NULL) {\r
     if (ReportStatusCodeExtractDebugInfo (Data, &ErrorLevel, &Marker, &Format)) {\r
       //\r
       // Convert Ascii Format string to Unicode.\r
@@ -287,26 +231,25 @@ Returns:
       // Put processed string into the buffer\r
       //\r
       Index = VSPrint (\r
-                (UINT16 *) (DataHub + 1),\r
+                (CHAR16 *) (Record + 1),\r
                 BYTES_PER_RECORD - (sizeof (DATA_HUB_STATUS_CODE_DATA_RECORD)),\r
                 FormatBuffer,\r
                 Marker\r
                 );\r
-\r
-      //\r
-      // DATA_HUB_STATUS_CODE_DATA_RECORD followed by VSPrint String Buffer\r
-      //\r
-      DataHub->Data.Size = (UINT16) (Index * sizeof (CHAR16));\r
-\r
+                \r
+      EfiCopyMem (&Record->Data.Type, &gEfiStatusCodeDataTypeDebugGuid, sizeof (EFI_GUID));\r
+      Record->Data.HeaderSize = Data->HeaderSize;\r
+      Record->Data.Size = (UINT16) (Index * sizeof (CHAR16));\r
     } else {\r
       //\r
-      // Default behavior is to copy optional data\r
+      // Copy status code data header\r
       //\r
-      if (Data->Size > (BYTES_PER_RECORD - sizeof (DATA_HUB_STATUS_CODE_DATA_RECORD))) {\r
-        DataHub->Data.Size = (UINT16) (BYTES_PER_RECORD - sizeof (DATA_HUB_STATUS_CODE_DATA_RECORD));\r
-      }\r
+      EfiCopyMem (&Record->Data, Data, sizeof (EFI_STATUS_CODE_DATA));\r
 \r
-      EfiCopyMem (DataHub + 1, Data + 1, DataHub->Data.Size);\r
+      if (Data->Size > BYTES_PER_RECORD - sizeof (DATA_HUB_STATUS_CODE_DATA_RECORD)) {\r
+        Record->Data.Size = (UINT16) (BYTES_PER_RECORD - sizeof (DATA_HUB_STATUS_CODE_DATA_RECORD));\r
+      } \r
+      EfiCopyMem ((VOID *) (Record + 1), Data + 1, Record->Data.Size);\r
     }\r
   }\r
 \r
@@ -339,39 +282,34 @@ Returns:
 \r
 --*/\r
 {\r
-  EFI_STATUS                        Status;\r
-  DATA_HUB_STATUS_CODE_DATA_RECORD  *DataRecord;\r
-  UINTN                             Size;\r
+  DATA_HUB_STATUS_CODE_DATA_RECORD  *Record;\r
+  UINT32                            Size;\r
   UINT64                            DataRecordClass;\r
-  EFI_LIST_ENTRY                    *Link;\r
-  STATUS_CODE_RECORD_LIST           *BufferEntry;\r
 \r
   //\r
-  // Set our global flag so we don't recurse if we get an error here.\r
+  // Set global flag so we don't recurse if DataHub->LogData eventually causes new DataHubRecord\r
   //\r
   mEventHandlerActive = TRUE;\r
   \r
   //\r
   // Log DataRecord in Data Hub.\r
-  // If there are multiple DataRecords, Log all of them.\r
+  // Journal records fifo to find all record entry.\r
   //\r
-  Link = mRecordTail;\r
-\r
-  while (mRecordNum != 0) {\r
-    BufferEntry = CR (Link, STATUS_CODE_RECORD_LIST, Link, BS_DATA_HUB_STATUS_CODE_SIGNATURE);\r
-    DataRecord  = (DATA_HUB_STATUS_CODE_DATA_RECORD *) (BufferEntry->RecordBuffer);\r
-    Link        = Link->ForwardLink;\r
-\r
+  while (1) {\r
+    Record = RetrieveRecord ();\r
+    if (Record == NULL) {\r
+      break;\r
+    }\r
     //\r
     // Add in the size of the header we added.\r
     //\r
-    Size = sizeof (DATA_HUB_STATUS_CODE_DATA_RECORD) + DataRecord->Data.Size;\r
+    Size = sizeof (DATA_HUB_STATUS_CODE_DATA_RECORD) + (UINT32) Record->Data.Size;\r
 \r
-    if ((DataRecord->CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE) {\r
+    if ((Record->CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE) {\r
       DataRecordClass = EFI_DATA_RECORD_CLASS_PROGRESS_CODE;\r
-    } else if ((DataRecord->CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) {\r
+    } else if ((Record->CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) {\r
       DataRecordClass = EFI_DATA_RECORD_CLASS_ERROR;\r
-    } else if ((DataRecord->CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_DEBUG_CODE) {\r
+    } else if ((Record->CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_DEBUG_CODE) {\r
       DataRecordClass = EFI_DATA_RECORD_CLASS_DEBUG;\r
     } else {\r
       //\r
@@ -383,45 +321,27 @@ Returns:
         EFI_DATA_RECORD_CLASS_PROGRESS_CODE;\r
     }\r
 \r
-    if (((DataRecord->Instance & EFI_D_ERROR) != 0) &&\r
-        (((DataRecord->Instance & EFI_D_POOL) != 0) || ((DataRecord->Instance & EFI_D_PAGE) != 0))\r
-        ) {\r
-      //\r
-      // If memory error, do not call LogData ().\r
-      //\r
-      ErrorPrint (L"ERROR", "Memory Error\n");\r
-      Status = EFI_OUT_OF_RESOURCES;\r
-    } else {\r
-      //\r
-      // We don't log EFI_D_POOL and EFI_D_PAGE debug info to datahub\r
-      // to avoid recursive logging due to the memory allocation in datahub\r
-      //\r
-      if (DataRecordClass != EFI_DATA_RECORD_CLASS_DEBUG ||\r
-          ((DataRecord->Instance & EFI_D_POOL) == 0 && (DataRecord->Instance & EFI_D_PAGE) == 0)) {\r
-        //\r
-        // Log DataRecord in Data Hub\r
-        //\r
-        Status = mDataHub->LogData (\r
-                             mDataHub,\r
-                             &gEfiStatusCodeGuid,\r
-                             &gEfiStatusCodeRuntimeProtocolGuid,\r
-                             DataRecordClass,\r
-                             DataRecord,\r
-                             (UINT32) Size\r
-                             );\r
-      }\r
-    }\r
+    //\r
+    // Log DataRecord in Data Hub\r
+    //\r
+    \r
+    mDataHubProtocol->LogData (\r
+                        mDataHubProtocol,\r
+                        &gEfiStatusCodeGuid,\r
+                        &gEfiStatusCodeRuntimeProtocolGuid,\r
+                        DataRecordClass,\r
+                        Record,\r
+                        Size\r
+                        );\r
 \r
-    ReleaseRecordBuffer (BufferEntry);\r
   }\r
 \r
   mEventHandlerActive = FALSE;\r
 \r
-  return ;\r
 }\r
 \r
-EFI_BOOTSERVICE\r
 EFI_STATUS\r
+EFIAPI\r
 BsDataHubInitializeStatusCode (\r
   IN EFI_HANDLE         ImageHandle,\r
   IN EFI_SYSTEM_TABLE   *SystemTable\r
@@ -444,38 +364,14 @@ Returns:
 --*/\r
 {\r
   EFI_STATUS              Status;\r
-  STATUS_CODE_RECORD_LIST *DataBuffer;\r
-  UINTN                   Index1;\r
 \r
-  DataBuffer = NULL;\r
-\r
-  Status = gBS->LocateProtocol (&gEfiDataHubProtocolGuid, NULL, &mDataHub);\r
-  //\r
-  // Should never fail due to dependency grammer\r
-  //\r
+  Status = gBS->LocateProtocol (\r
+                  &gEfiDataHubProtocolGuid, \r
+                  NULL, \r
+                  (VOID **) &mDataHubProtocol\r
+                  );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
-  //\r
-  // Initialize a record list with length not greater than INITIAL_RECORD_NUM.\r
-  // If no buffer can be allocated, return EFI_OUT_OF_RESOURCES.\r
-  //\r
-  DataBuffer = AllocateRecordBuffer ();\r
-  if (DataBuffer == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-  mRecordHead = &DataBuffer->Link;\r
-  mRecordTail = mRecordHead;\r
-  InitializeListHead (mRecordHead);\r
-  \r
-  for (Index1 = 1; Index1 < INITIAL_RECORD_NUM; Index1++) {\r
-    DataBuffer = AllocateRecordBuffer ();\r
-    if (DataBuffer == NULL) {\r
-      break;\r
-    }\r
-    InsertHeadList (mRecordHead, &DataBuffer->Link);\r
-  }\r
-\r
-\r
   //\r
   // Create a Notify Event to log data in Data Hub\r
   //\r
@@ -487,5 +383,9 @@ Returns:
                   &mLogDataHubEvent\r
                   );\r
 \r
+  ASSERT_EFI_ERROR (Status);\r
+\r
   return EFI_SUCCESS;\r
 }\r
+\r
+\r
index 7f5d026859dbcf393bc8c8e6fdca312ee3caf8ec..b56bc9bfd3aab857ad01983e17f58ddfe8290651 100644 (file)
@@ -1,6 +1,6 @@
 /*++\r
 \r
-Copyright (c)  2004 - 2006, Intel Corporation                                                         \r
+Copyright (c)  2004 - 2007, Intel Corporation                                                         \r
 All rights reserved. This program and the accompanying materials                          \r
 are licensed and made available under the terms and conditions of the BSD License         \r
 which accompanies this distribution.  The full text of the license may be found at        \r
@@ -52,7 +52,6 @@ Abstract:
 // Private data declarations\r
 //\r
 #define MAX_RECORD_NUM                    1000\r
-#define INITIAL_RECORD_NUM                20\r
 #define BYTES_PER_RECORD                  EFI_STATUS_CODE_DATA_MAX_SIZE\r
 #define BYTES_PER_BUFFER                  (BYTES_PER_RECORD * sizeof (UINT8))\r
 \r
@@ -60,77 +59,63 @@ Abstract:
 \r
 typedef struct {\r
   UINTN           Signature;\r
-  EFI_LIST_ENTRY  Link;\r
-  UINT8           RecordBuffer[BYTES_PER_RECORD];\r
-} STATUS_CODE_RECORD_LIST;\r
+  EFI_LIST_ENTRY  Node;\r
+  UINT8           Data[BYTES_PER_RECORD];\r
+} DATAHUB_STATUSCODE_RECORD;\r
 \r
 //\r
 // Function prototypes\r
 //\r
-STATUS_CODE_RECORD_LIST *\r
-AllocateRecordBuffer (\r
-  VOID\r
-  );\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Allocate a new record list node and initialize it.\r
-  Inserting the node into the list isn't the task of this function.\r
-\r
-Arguments:\r
-\r
-  None\r
-\r
-Returns:\r
-\r
-  A pointer to the new allocated node or NULL if non available\r
-\r
---*/\r
-\r
-DATA_HUB_STATUS_CODE_DATA_RECORD *\r
-AquireEmptyRecordBuffer (\r
-  VOID\r
+EFI_STATUS\r
+EFIAPI\r
+BsDataHubInitializeStatusCode (\r
+  IN EFI_HANDLE         ImageHandle,\r
+  IN EFI_SYSTEM_TABLE   *SystemTable\r
   );\r
 /*++\r
 \r
 Routine Description:\r
 \r
-  Acquire an empty record buffer from the record list if there's free node,\r
-  or allocate one new node and insert it to the list if the list is full and\r
-  the function isn't run in EFI_TPL_HIGH_LEVEL.\r
+  Install a data hub listener.\r
 \r
 Arguments:\r
 \r
-  None\r
+  (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)\r
 \r
 Returns:\r
 \r
-  Pointer to new record buffer. NULL if none available.\r
+  EFI_SUCCESS - Logging Hub protocol installed\r
+  Other       - No protocol installed, unload driver.\r
 \r
 --*/\r
 \r
 EFI_STATUS\r
-ReleaseRecordBuffer (\r
-  IN  STATUS_CODE_RECORD_LIST  *RecordBuffer\r
+EFIAPI\r
+BsDataHubReportStatusCode (\r
+  IN EFI_STATUS_CODE_TYPE     CodeType,\r
+  IN EFI_STATUS_CODE_VALUE    Value,\r
+  IN UINT32                   Instance,\r
+  IN EFI_GUID                 * CallerId,\r
+  IN EFI_STATUS_CODE_DATA     * Data OPTIONAL\r
   );\r
 /*++\r
 \r
 Routine Description:\r
 \r
-  Release a buffer in the list, remove some nodes to keep the list inital length.\r
+  Boot service report status code listener.  This function logs the status code\r
+  into the data hub.\r
+\r
 Arguments:\r
 \r
-  RecordBuffer          - Buffer to release\r
+  Same as gRT->ReportStatusCode (See Tiano Runtime Specification)\r
 \r
 Returns:\r
 \r
-  EFI_SUCCESS           - If DataRecord is valid\r
-  EFI_UNSUPPORTED       - The record list has empty\r
+  None\r
 \r
 --*/\r
 \r
-void\r
+VOID\r
 EFIAPI\r
 LogDataHubEventHandler (\r
   IN  EFI_EVENT     Event,\r
index 483064d737be6eb133afa486af0c42f9cc905856..35fb9a00a452ac39c3eab8ae7b170a77694ba3e9 100644 (file)
@@ -1,6 +1,6 @@
 /*++\r
 \r
-Copyright (c) 2004 - 2005, Intel Corporation                                                         \r
+Copyright (c) 2004 - 2007, Intel Corporation                                                         \r
 All rights reserved. This program and the accompanying materials                          \r
 are licensed and made available under the terms and conditions of the BSD License         \r
 which accompanies this distribution.  The full text of the license may be found at        \r
@@ -2095,6 +2095,7 @@ Returns:
 #endif\r
 \r
 VOID\r
+EFIAPI\r
 BsSerialInitializeStatusCode (\r
   IN EFI_HANDLE         ImageHandle,\r
   IN EFI_SYSTEM_TABLE   *SystemTable\r
@@ -2189,6 +2190,9 @@ Returns:
   } while ((Data & LSR_TXRDY) == 0);\r
 \r
   IoWrite8 (gComBase, Character);\r
+#ifdef SERIAL_OUTPUT_STALL\r
+  EfiStall (SERIAL_OUTPUT_STALL);\r
+#endif\r
 }\r
 \r
 VOID\r
index 6d6dfcd16b20895056f328f901f4075adf57a09d..c15ac01e51b8edb434d4934043225f31bd53abbc 100644 (file)
@@ -1,6 +1,6 @@
 /*++\r
 \r
-Copyright (c) 2004 - 2005, Intel Corporation                                                         \r
+Copyright (c) 2004 - 2007, Intel Corporation                                                         \r
 All rights reserved. This program and the accompanying materials                          \r
 are licensed and made available under the terms and conditions of the BSD License         \r
 which accompanies this distribution.  The full text of the license may be found at        \r
@@ -31,6 +31,7 @@ Abstract:
 // Initialization function\r
 //\r
 VOID\r
+EFIAPI\r
 BsDataHubInitializeStatusCode (\r
   IN EFI_HANDLE         ImageHandle,\r
   IN EFI_SYSTEM_TABLE   *SystemTable\r
@@ -41,6 +42,7 @@ BsDataHubInitializeStatusCode (
 // Status code reporting function\r
 //\r
 EFI_STATUS\r
+EFIAPI\r
 BsDataHubReportStatusCode (\r
   IN EFI_STATUS_CODE_TYPE     CodeType,\r
   IN EFI_STATUS_CODE_VALUE    Value,\r
index e0403cb8eaef74315ed93ad5632bb914269eb3df..761f0da27da5e92d99513198707951c5ff4b6a49 100644 (file)
@@ -1,6 +1,6 @@
 /*++\r
 \r
-Copyright (c) 2004 - 2005, Intel Corporation                                                         \r
+Copyright (c) 2004 - 2007, Intel Corporation                                                         \r
 All rights reserved. This program and the accompanying materials                          \r
 are licensed and made available under the terms and conditions of the BSD License         \r
 which accompanies this distribution.  The full text of the license may be found at        \r
@@ -31,6 +31,7 @@ Abstract:
 // Initialization function\r
 //\r
 VOID\r
+EFIAPI\r
 BsSerialInitializeStatusCode (\r
   IN EFI_HANDLE         ImageHandle,\r
   IN EFI_SYSTEM_TABLE   *SystemTable\r
@@ -41,6 +42,7 @@ BsSerialInitializeStatusCode (
 // Status code reporting function\r
 //\r
 EFI_STATUS\r
+EFIAPI\r
 BsSerialReportStatusCode (\r
   IN EFI_STATUS_CODE_TYPE     CodeType,\r
   IN EFI_STATUS_CODE_VALUE    Value,\r
index 3dadc1d2e4911dd0b0efd154edb49c6ecd0d9e88..24a74f335775535bd7e591da7f0d475bd5c3da67 100644 (file)
@@ -1,6 +1,6 @@
 /*++\r
 \r
-Copyright (c) 2004 - 2005, Intel Corporation                                                         \r
+Copyright (c) 2004 - 2007, Intel Corporation                                                         \r
 All rights reserved. This program and the accompanying materials                          \r
 are licensed and made available under the terms and conditions of the BSD License         \r
 which accompanies this distribution.  The full text of the license may be found at        \r
@@ -31,6 +31,7 @@ Abstract:
 // Initialization function\r
 //\r
 VOID\r
+EFIAPI\r
 RtMemoryInitializeStatusCode (\r
   IN EFI_HANDLE         ImageHandle,\r
   IN EFI_SYSTEM_TABLE   *SystemTable\r
@@ -41,6 +42,7 @@ RtMemoryInitializeStatusCode (
 // Status code reporting function\r
 //\r
 EFI_STATUS\r
+EFIAPI\r
 RtMemoryReportStatusCode (\r
   IN EFI_STATUS_CODE_TYPE     CodeType,\r
   IN EFI_STATUS_CODE_VALUE    Value,\r
@@ -55,7 +57,7 @@ RtMemoryReportStatusCode (
 //\r
 typedef\r
 EFI_STATUS\r
-(*PLATFORM_REPORT_STATUS_CODE) (\r
+(EFIAPI *PLATFORM_REPORT_STATUS_CODE) (\r
   IN EFI_STATUS_CODE_TYPE     Type,\r
   IN EFI_STATUS_CODE_VALUE    Value,\r
   IN UINT32                   Instance,\r
@@ -64,6 +66,7 @@ EFI_STATUS
   );\r
 \r
 VOID\r
+EFIAPI\r
 PlaybackStatusCodes (\r
   IN PLATFORM_REPORT_STATUS_CODE  ReportStatusCode\r
   )\r
index 6979aa1a1baf01e62a346c764fd5bef3996db8e7..22f02b763a9e5145aee31cf9c35bdb9383beb29a 100644 (file)
@@ -1,6 +1,6 @@
 /*++\r
 \r
-Copyright (c) 2004 - 2005, Intel Corporation                                                         \r
+Copyright (c) 2004 - 2007, Intel Corporation                                                         \r
 All rights reserved. This program and the accompanying materials                          \r
 are licensed and made available under the terms and conditions of the BSD License         \r
 which accompanies this distribution.  The full text of the license may be found at        \r
@@ -32,6 +32,7 @@ Abstract:
 // Initialization function\r
 //\r
 VOID\r
+EFIAPI\r
 RtPlatformInitializeStatusCode (\r
   IN EFI_HANDLE         ImageHandle,\r
   IN EFI_SYSTEM_TABLE   *SystemTable\r
@@ -42,6 +43,7 @@ RtPlatformInitializeStatusCode (
 // Status code reporting function\r
 //\r
 EFI_STATUS\r
+EFIAPI\r
 RtPlatformReportStatusCode (\r
   IN EFI_STATUS_CODE_TYPE     CodeType,\r
   IN EFI_STATUS_CODE_VALUE    Value,\r
index 9c57ffb8862c99e63921254affbe840e1310fcd2..854de9b44365f95f69e00a8b32fb2afc6db49ceb 100644 (file)
@@ -1,6 +1,6 @@
 /*++\r
 \r
-Copyright (c) 2004 - 2005, Intel Corporation                                                         \r
+Copyright (c) 2004 - 2007, Intel Corporation                                                         \r
 All rights reserved. This program and the accompanying materials                          \r
 are licensed and made available under the terms and conditions of the BSD License         \r
 which accompanies this distribution.  The full text of the license may be found at        \r
@@ -31,6 +31,7 @@ Abstract:
 // Status code reporting function\r
 //\r
 EFI_STATUS\r
+EFIAPI\r
 RtPort80ReportStatusCode (\r
   IN EFI_STATUS_CODE_TYPE     CodeType,\r
   IN EFI_STATUS_CODE_VALUE    Value,\r
diff --git a/EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/EdkNt32PpiLib.inf b/EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/EdkNt32PpiLib.inf
new file mode 100644 (file)
index 0000000..79bba0b
--- /dev/null
@@ -0,0 +1,53 @@
+/*++                                                               \r
+                                                                   \r
+  Copyright (c) 2004, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+                                                                   \r
+                                                                   \r
+  Module Name:                                                     \r
+                                                                   \r
+    EdkNt32PpiLib.inf                                              \r
+                                                                   \r
+  Abstract:                                                        \r
+                                                                   \r
+    Component description file for the Edk Nt32 PPI library.       \r
+                                                                   \r
+--*/                                                               \r
+                                                                   \r
+[defines]\r
+BASE_NAME=   EdkNt32PpiLib\r
+COMPONENT_TYPE=   LIBRARY\r
+\r
+[includes.common]\r
+  $(EDK_SOURCE)\Sample\Platform\Nt32\r
+  $(EDK_SOURCE)\Foundation\Efi\r
+  $(EDK_SOURCE)\Foundation\Include\r
+  $(EDK_SOURCE)\Foundation\Efi\Include\r
+  $(EDK_SOURCE)\Foundation\Framework\Include\r
+  $(EDK_SOURCE)\Foundation\Include\IndustryStandard\r
+  $(EDK_SOURCE)\Foundation\Include\Pei\r
+  $(EDK_SOURCE)\Foundation\Library\Pei\Include\r
+  $(EDK_SOURCE)\Foundation\Core\Dxe\r
+  $(EDK_SOURCE)\Foundation\Library\Dxe\Include\r
+  $(EDK_SOURCE)\Foundation\Framework \r
+                                   \r
+[nmake.common]\r
+C_STD_INCLUDE=\r
+\r
+[sources.common]\r
+    NtAutoscan\NtAutoscan.h\r
+    NtAutoscan\NtAutoscan.c\r
+    NtFwh\NtFwh.h\r
+    NtFwh\NtFwh.c\r
+    NtLoadAsDll\NtLoadAsDll.h\r
+    NtLoadAsDll\NtLoadAsDll.c\r
+    NtPeiLoadFile\NtPeiLoadFile.h\r
+    NtPeiLoadFile\NtPeiLoadFile.c\r
+    NtThunk\NtThunk.h\r
+    NtThunk\NtThunk.c\r
diff --git a/EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtAutoscan/NtAutoscan.c b/EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtAutoscan/NtAutoscan.c
new file mode 100644 (file)
index 0000000..fc0676f
--- /dev/null
@@ -0,0 +1,29 @@
+/*++\r
+\r
+Copyright (c) 2004, Intel Corporation                                                         \r
+All rights reserved. This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+  \r
+    NtAutoscan.c\r
+\r
+Abstract:\r
+\r
+  Abstraction for the NT Load Image PPI GUID as defined in Tiano\r
+\r
+--*/\r
+\r
+#include "Tiano.h"\r
+#include "PeiBind.h"\r
+#include "PeiApi.h"\r
+#include EFI_PPI_DEFINITION (NtAutoScan)\r
+\r
+EFI_GUID  gPeiNtAutoScanPpiGuid = PEI_NT_AUTOSCAN_PPI_GUID;\r
+\r
+EFI_GUID_STRING(&gPeiNtAutoScanPpiGuid, "NtAutoScan", "NT PEI AUTOSCAN PPI");\r
diff --git a/EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtAutoscan/NtAutoscan.h b/EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtAutoscan/NtAutoscan.h
new file mode 100644 (file)
index 0000000..5351646
--- /dev/null
@@ -0,0 +1,67 @@
+/*++\r
+\r
+Copyright (c) 2004, Intel Corporation                                                         \r
+All rights reserved. This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+  NtAutoscan.h\r
+\r
+Abstract:\r
+\r
+Nt Autoscan PPI\r
+\r
+--*/\r
+\r
+#ifndef _NT_PEI_AUTOSCAN_H_\r
+#define _NT_PEI_AUTOSCAN_H_\r
+\r
+#include "Tiano.h"\r
+#include "PeiHob.h"\r
+\r
+#define PEI_NT_AUTOSCAN_PPI_GUID \\r
+  { \\r
+    0xdce384d, 0x7c, 0x4ba5, 0x94, 0xbd, 0xf, 0x6e, 0xb6, 0x4d, 0x2a, 0xa9 \\r
+  }\r
+\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *PEI_NT_AUTOSCAN) (\r
+  IN  UINTN                 Index,\r
+  OUT EFI_PHYSICAL_ADDRESS  * MemoryBase,\r
+  OUT UINT64                *MemorySize\r
+  );\r
+\r
+/*++\r
+\r
+Routine Description:\r
+  This service is called from Index == 0 until it returns EFI_UNSUPPORTED.\r
+  It allows discontiguous memory regions to be supported by the emulator.\r
+  It uses gSystemMemory[] and gSystemMemoryCount that were created by\r
+  parsing the Windows environment variable EFI_MEMORY_SIZE.\r
+  The size comes from the varaible and the address comes from the call to\r
+  WinNtOpenFile. \r
+\r
+Arguments:\r
+  Index      - Which memory region to use\r
+  MemoryBase - Return Base address of memory region\r
+  MemorySize - Return size in bytes of the memory region\r
+\r
+Returns:\r
+  EFI_SUCCESS - If memory region was mapped\r
+  EFI_UNSUPPORTED - If Index is not supported\r
+\r
+--*/\r
+typedef struct {\r
+  PEI_NT_AUTOSCAN NtAutoScan;\r
+} PEI_NT_AUTOSCAN_PPI;\r
+\r
+extern EFI_GUID gPeiNtAutoScanPpiGuid;\r
+\r
+#endif\r
diff --git a/EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtFwh/NtFwh.c b/EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtFwh/NtFwh.c
new file mode 100644 (file)
index 0000000..d4e1f7c
--- /dev/null
@@ -0,0 +1,29 @@
+/*++\r
+\r
+Copyright (c) 2004, Intel Corporation                                                         \r
+All rights reserved. This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+ NtFwh.c\r
+\r
+Abstract:\r
+\r
+  NT FWH Information PPI GUID as defined in Tiano\r
+\r
+--*/\r
+\r
+#include "Tiano.h"\r
+#include "PeiBind.h"\r
+#include "PeiApi.h"\r
+#include EFI_PPI_DEFINITION (NtFwh)\r
+\r
+EFI_GUID  gNtFwhPpiGuid = NT_FWH_PPI_GUID;\r
+\r
+EFI_GUID_STRING(&gNtFwhPpiGuid, "NtFwh", "NT PEI FWH INFO PPI");\r
diff --git a/EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtFwh/NtFwh.h b/EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtFwh/NtFwh.h
new file mode 100644 (file)
index 0000000..7750db2
--- /dev/null
@@ -0,0 +1,63 @@
+/*++\r
+\r
+Copyright (c) 2004, Intel Corporation                                                         \r
+All rights reserved. This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+  NtFwh.h\r
+\r
+Abstract:\r
+\r
+  WinNt FWH PPI as defined in Tiano\r
+\r
+--*/\r
+\r
+#ifndef _NT_PEI_FWH_H_\r
+#define _NT_PEI_FWH_H_\r
+\r
+#include "Tiano.h"\r
+#include "PeiHob.h"\r
+\r
+#define NT_FWH_PPI_GUID \\r
+  { \\r
+    0x4e76928f, 0x50ad, 0x4334, 0xb0, 0x6b, 0xa8, 0x42, 0x13, 0x10, 0x8a, 0x57 \\r
+  }\r
+\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *NT_FWH_INFORMATION) (\r
+  IN     UINTN                  Index,\r
+  IN OUT EFI_PHYSICAL_ADDRESS   * FdBase,\r
+  IN OUT UINT64                 *FdSize\r
+  );\r
+\r
+/*++\r
+\r
+Routine Description:\r
+  Return the FD Size and base address. Since the FD is loaded from a \r
+  file into Windows memory only the SEC will know it's address.\r
+\r
+Arguments:\r
+  Index  - Which FD, starts at zero.\r
+  FdSize - Size of the FD in bytes\r
+  FdBase - Start address of the FD. Assume it points to an FV Header\r
+\r
+Returns:\r
+  EFI_SUCCESS     - Return the Base address and size of the FV\r
+  EFI_UNSUPPORTED - Index does nto map to an FD in the system\r
+\r
+--*/\r
+typedef struct {\r
+  NT_FWH_INFORMATION  NtFwh;\r
+} NT_FWH_PPI;\r
+\r
+extern EFI_GUID gNtFwhPpiGuid;\r
+\r
+#endif\r
diff --git a/EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtLoadAsDll/NtLoadAsDll.c b/EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtLoadAsDll/NtLoadAsDll.c
new file mode 100644 (file)
index 0000000..ffd8ab8
--- /dev/null
@@ -0,0 +1,28 @@
+/*++\r
+\r
+Copyright (c) 2004, Intel Corporation                                                         \r
+All rights reserved. This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+  \r
+    NtLoadAsDll.c\r
+\r
+Abstract:\r
+\r
+  DXE Initial Program Load PPI GUID as defined in Tiano\r
+\r
+--*/\r
+\r
+#include "Tiano.h"\r
+#include "Pei.h"\r
+#include EFI_PPI_DEFINITION (NtLoadAsDll)\r
+\r
+EFI_GUID  gEfiNtLoadAsDllPpiGuid = EFI_NT_LOAD_AS_DLL_PPI_GUID;\r
+\r
+EFI_GUID_STRING(&gEfiNtLoadAsDllPpiGuid, "NtLoadAsDll", "NT LOAD AS DLL PPI");\r
diff --git a/EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtLoadAsDll/NtLoadAsDll.h b/EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtLoadAsDll/NtLoadAsDll.h
new file mode 100644 (file)
index 0000000..f0062cb
--- /dev/null
@@ -0,0 +1,84 @@
+/*++\r
+\r
+Copyright (c) 2004, Intel Corporation                                                         \r
+All rights reserved. This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+ NtLoadAsDll.h\r
+\r
+Abstract:\r
+\r
+  Nt service Ppi that is used to load PE32s in the NT emulation environment.\r
+\r
+--*/\r
+\r
+#ifndef _NT_LOAD_AS_DLL_H_\r
+#define _NT_LOAD_AS_DLL_H_\r
+\r
+#include "Tiano.h"\r
+\r
+#define EFI_NT_LOAD_AS_DLL_PPI_GUID \\r
+  { \\r
+    0xccc53f6b, 0xa03a, 0x4ed8, 0x83, 0x9a, 0x3, 0xd9, 0x9c, 0x2, 0xb4, 0xe3 \\r
+  }\r
+\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *EFI_NT_LOAD_AS_DLL) (\r
+  IN CHAR8    *PdbFileName,\r
+  IN VOID     **ImageEntryPoint,\r
+  OUT VOID    **ModHandle\r
+  );\r
+\r
+/*++\r
+\r
+Routine Description:\r
+  Loads the .DLL file is present when a PE/COFF file is loaded.  This provides source level\r
+  debugging for drivers that have cooresponding .DLL files on the local system.\r
+\r
+Arguments:\r
+  PdbFileName     - The name of the .PDB file.  This was found from the PE/COFF\r
+                    file's debug directory entry.\r
+  ImageEntryPoint - A pointer to the DLL entry point of the .DLL file was loaded.\r
+\r
+Returns:\r
+  EFI_SUCCESS     - The .DLL file was loaded, and the DLL entry point is returned in ImageEntryPoint\r
+  EFI_NOT_FOUND   - The .DLL file could not be found\r
+  EFI_UNSUPPORTED - The .DLL file was loaded, but the entry point to the .DLL file could not\r
+                    determined.\r
+\r
+--*/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *EFI_NT_FREE_LIBRARY) (\r
+  IN VOID     *ModHandle\r
+  );\r
+\r
+/*++\r
+\r
+Routine Description:\r
+  Free resources allocated by Entry (). ModHandle was returned by\r
+  Entry ().\r
+\r
+Arguments:\r
+  MohHandle  - Handle of the resources to free to undo the work.\r
+\r
+Returns:\r
+  EFI_SUCCESS - \r
+\r
+--*/\r
+typedef struct {\r
+  EFI_NT_LOAD_AS_DLL  Entry;\r
+  EFI_NT_FREE_LIBRARY FreeLibrary;\r
+} EFI_NT_LOAD_AS_DLL_PPI;\r
+\r
+extern EFI_GUID gEfiNtLoadAsDllPpiGuid;\r
+\r
+#endif\r
diff --git a/EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtPeiLoadFile/NtPeiLoadFile.c b/EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtPeiLoadFile/NtPeiLoadFile.c
new file mode 100644 (file)
index 0000000..f1feeb7
--- /dev/null
@@ -0,0 +1,29 @@
+/*++\r
+\r
+Copyright (c) 2004, Intel Corporation                                                         \r
+All rights reserved. This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+ NtPeiLoadFile.c\r
+\r
+Abstract:\r
+\r
+  Abstraction for the NT Load Image PPI GUID as defined in Tiano\r
+\r
+--*/\r
+\r
+#include "Tiano.h"\r
+#include "PeiBind.h"\r
+#include "PeiApi.h"\r
+#include EFI_PPI_DEFINITION (NtPeiLoadFile)\r
+\r
+EFI_GUID  gNtPeiLoadFileGuid = NT_PEI_LOAD_FILE_GUID;\r
+\r
+EFI_GUID_STRING(&gNtPeiLoadFileGuid, "NtPeiLoadFile", "NT PEI LOAD FILE PPI");\r
diff --git a/EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtPeiLoadFile/NtPeiLoadFile.h b/EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtPeiLoadFile/NtPeiLoadFile.h
new file mode 100644 (file)
index 0000000..28f18f4
--- /dev/null
@@ -0,0 +1,66 @@
+/*++\r
+\r
+Copyright (c) 2004, Intel Corporation                                                         \r
+All rights reserved. This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+ NtPeiLoadFile.h\r
+\r
+Abstract:\r
+\r
+  WinNt Load File PPI.\r
+\r
+  When the PEI core is done it calls the DXE IPL via PPI\r
+\r
+--*/\r
+\r
+#ifndef _NT_PEI_LOAD_FILE_H_\r
+#define _NT_PEI_LOAD_FILE_H_\r
+\r
+#include "Tiano.h"\r
+#include "PeiHob.h"\r
+\r
+#define NT_PEI_LOAD_FILE_GUID \\r
+  { \\r
+    0xfd0c65eb, 0x405, 0x4cd2, 0x8a, 0xee, 0xf4, 0x0, 0xef, 0x13, 0xba, 0xc2 \\r
+  }\r
+\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *NT_PEI_LOAD_FILE) (\r
+  VOID                  *Pe32Data,\r
+  EFI_PHYSICAL_ADDRESS  *ImageAddress,\r
+  UINT64                *ImageSize,\r
+  EFI_PHYSICAL_ADDRESS  *EntryPoint\r
+  );\r
+\r
+/*++\r
+\r
+Routine Description:\r
+  Loads and relocates a PE/COFF image into memory.\r
+\r
+Arguments:\r
+  Pe32Data         - The base address of the PE/COFF file that is to be loaded and relocated\r
+  ImageAddress     - The base address of the relocated PE/COFF image\r
+  ImageSize        - The size of the relocated PE/COFF image\r
+  EntryPoint       - The entry point of the relocated PE/COFF image\r
+\r
+Returns:\r
+  EFI_SUCCESS   - The file was loaded and relocated\r
+  EFI_OUT_OF_RESOURCES - There was not enough memory to load and relocate the PE/COFF file\r
+\r
+--*/\r
+typedef struct {\r
+  NT_PEI_LOAD_FILE  PeiLoadFileService;\r
+} NT_PEI_LOAD_FILE_PPI;\r
+\r
+extern EFI_GUID gNtPeiLoadFileGuid;\r
+\r
+#endif\r
diff --git a/EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtThunk/NtThunk.c b/EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtThunk/NtThunk.c
new file mode 100644 (file)
index 0000000..5265c10
--- /dev/null
@@ -0,0 +1,29 @@
+/*++\r
+\r
+Copyright (c) 2004, Intel Corporation                                                         \r
+All rights reserved. This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+ NtThunk.c\r
+\r
+Abstract:\r
+\r
+  Abstraction for the NT Thunk PPI\r
+\r
+--*/\r
+\r
+#include "Tiano.h"\r
+#include "PeiBind.h"\r
+#include "PeiApi.h"\r
+#include EFI_PPI_DEFINITION (NtThunk)\r
+\r
+EFI_GUID  gPeiNtThunkPpiGuid = PEI_NT_THUNK_GUID;\r
+\r
+EFI_GUID_STRING(&gPeiNtThunkPpiGuid, "NtThunk", "NT PEI WINNT THUNK PPI");\r
diff --git a/EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtThunk/NtThunk.h b/EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtThunk/NtThunk.h
new file mode 100644 (file)
index 0000000..663f5f1
--- /dev/null
@@ -0,0 +1,59 @@
+/*++\r
+\r
+Copyright (c) 2004, Intel Corporation                                                         \r
+All rights reserved. This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+  NtThunk.h\r
+\r
+Abstract:\r
+\r
+  WinNt Thunk interface PPI\r
+\r
+--*/\r
+\r
+#ifndef _NT_PEI_WIN_NT_THUNK_H_\r
+#define _NT_PEI_WIN_NT_THUNK_H_\r
+\r
+#include "Tiano.h"\r
+#include "PeiHob.h"\r
+\r
+#define PEI_NT_THUNK_GUID \\r
+  { \\r
+    0x98c281e5, 0xf906, 0x43dd, 0xa9, 0x2b, 0xb0, 0x3, 0xbf, 0x27, 0x65, 0xda \\r
+  }\r
+\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *PEI_NT_THUNK_INTERFACE) (\r
+  IN OUT UINT64                *InterfaceSize,\r
+  IN OUT EFI_PHYSICAL_ADDRESS  * InterfaceBase\r
+  );\r
+\r
+/*++\r
+\r
+Routine Description:\r
+  Export of EFI_WIN_NT_THUNK_PROTOCOL from the Windows SEC.\r
+\r
+Arguments:\r
+  InterfaceSize - sizeof (EFI_WIN_NT_THUNK_PROTOCOL);\r
+  InterfaceBase - Address of the EFI_WIN_NT_THUNK_PROTOCOL\r
+\r
+Returns:\r
+  EFI_SUCCESS - Data returned\r
+\r
+--*/\r
+typedef struct {\r
+  PEI_NT_THUNK_INTERFACE  NtThunk;\r
+} PEI_NT_THUNK_PPI;\r
+\r
+extern EFI_GUID gPeiNtThunkPpiGuid;\r
+\r
+#endif\r
diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/BootsectImage/Makefile b/EdkCompatibilityPkg/Sample/Tools/Source/BootsectImage/Makefile
deleted file mode 100644 (file)
index b067e85..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-#/*++\r
-#  \r
-#  Copyright (c) 2006 - 2007, Intel Corporation                                                         \r
-#  All rights reserved. This program and the accompanying materials                          \r
-#  are licensed and made available under the terms and conditions of the BSD License         \r
-#  which accompanies this distribution.  The full text of the license may be found at        \r
-#  http://opensource.org/licenses/bsd-license.php                                            \r
-#                                                                                            \r
-#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
-#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
-#  \r
-#  Module Name:\r
-#  \r
-#    Makefile\r
-#  \r
-#  Abstract:\r
-#  \r
-#    makefile for building the BootsectImage utility.\r
-#    \r
-#--*/  \r
-\r
-#\r
-# Make sure environmental variable EDK_SOURCE is set\r
-#\r
-!IFNDEF EDK_SOURCE\r
-!ERROR EDK_SOURCE environmental variable not set \r
-!ENDIF\r
-\r
-#\r
-# Do this if you want to compile from this directory\r
-#\r
-!IFNDEF TOOLCHAIN\r
-TOOLCHAIN = TOOLCHAIN_MSVC\r
-!ENDIF\r
-\r
-!INCLUDE $(BUILD_DIR)\PlatformTools.env\r
-\r
-#\r
-# Define some macros we use here. Should get rid of them someday and \r
-# get rid of the extra level of indirection.\r
-#\r
-COMMON_SOURCE      = $(EDK_TOOLS_COMMON)\r
-\r
-#\r
-# Common information\r
-#\r
-\r
-INC=$(INC)\r
-\r
-#\r
-# Target specific information\r
-#\r
-\r
-TARGET_NAME=BootsectImage\r
-TARGET_SOURCE_DIR = $(EDK_TOOLS_SOURCE)\$(TARGET_NAME)\r
-\r
-TARGET_EXE = $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).exe\r
-\r
-TARGET_EXE_SOURCE = "$(TARGET_SOURCE_DIR)\BootsectImage.c"\r
-TARGET_EXE_INCLUDE = "$(TARGET_SOURCE_DIR)\fat.h"  \\r
-                     "$(TARGET_SOURCE_DIR)\mbr.h"  \\r
-\r
-\r
-#\r
-# Build targets\r
-#\r
-\r
-all: $(TARGET_EXE)\r
-\r
-#\r
-# Build EXE\r
-#\r
-\r
-$(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj: $(TARGET_EXE_SOURCE) $(TARGET_EXE_INCLUDE)\r
-  $(CC) $(C_FLAGS) $(INC) $(TARGET_EXE_SOURCE) /Fo$(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj\r
-\r
-#\r
-# Add Binary Build description for this tool.\r
-#\r
-\r
-!IF (("$(EFI_BINARY_TOOLS)" == "YES") && EXIST($(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe))\r
-$(TARGET_EXE): $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe\r
-  copy $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe $(TARGET_EXE) /Y\r
-  if exist $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb \\r
-  copy $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb /Y\r
-!ELSE\r
-$(TARGET_EXE): $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj $(EDK_TOOLS_OUTPUT)\Common.lib\r
-  $(LINK) $(MSVS_LINK_LIBPATHS) $(EDK_TOOLS_OUTPUT)\Common.lib $(L_FLAGS) /out:$(TARGET_EXE) $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj \r
-  if not exist $(EFI_PLATFORM_BIN)\Tools mkdir $(EFI_PLATFORM_BIN)\Tools\r
-  if exist $(TARGET_EXE) copy $(TARGET_EXE) $(EFI_PLATFORM_BIN)\tools\$(TARGET_NAME).exe /Y\r
-  if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb \\r
-  copy $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb /Y\r
-!ENDIF\r
-\r
-clean:\r
-  @if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL\r
-\r
diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/BootsectImage/bootsectimage.c b/EdkCompatibilityPkg/Sample/Tools/Source/BootsectImage/bootsectimage.c
deleted file mode 100644 (file)
index d71a03d..0000000
+++ /dev/null
@@ -1,881 +0,0 @@
-/*++\r
-\r
-Copyright 2006 - 2007, Intel Corporation                                                         \r
-All rights reserved. This program and the accompanying materials                          \r
-are licensed and made available under the terms and conditions of the BSD License         \r
-which accompanies this distribution.  The full text of the license may be found at        \r
-http://opensource.org/licenses/bsd-license.php                                            \r
-                                                                                          \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
-\r
-Module Name:\r
-\r
-  bootsectimage.c\r
-    \r
-Abstract:\r
-  Patch the BPB information in boot sector image file.\r
-  Patch the MBR code in MBR image file.\r
-\r
---*/\r
-\r
-\r
-#include <windows.h>\r
-#include <stdio.h>\r
-#include "fat.h"\r
-#include "mbr.h"\r
-#include "EfiUtilityMsgs.h"\r
-\r
-#define DEBUG_WARN  0x1\r
-#define DEBUG_ERROR 0x2\r
-int WriteToFile (\r
-  void *BootSector, \r
-  char *FileName\r
-  )\r
-/*++\r
-Routine Description:\r
-  Write 512 bytes boot sector to file.\r
-\r
-Arguments:\r
-  BootSector - point to a buffer containing 512 bytes boot sector to write\r
-  FileName   - file to write to\r
-\r
-Return:\r
-  int        - number of bytes wrote,\r
-                 512 indicates write successful\r
-                 0 indicates write failure\r
---*/\r
-{\r
-  FILE *FileHandle;\r
-  int  result;\r
-\r
-  FileHandle = fopen (FileName, "r+b");\r
-  if (FileHandle == NULL) {\r
-    DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "Open file: %s", FileName);\r
-    return 0;\r
-  }\r
-  fseek (FileHandle, 0, SEEK_SET);\r
-\r
-  result = fwrite (BootSector, 1, 512, FileHandle);\r
-  if (result != 512) {\r
-    DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "Write file: %s", FileName);\r
-    result = 0;\r
-  }\r
-\r
-  fclose (FileHandle);\r
-  return result;\r
-}\r
-\r
-int ReadFromFile (\r
-  void *BootSector, \r
-  char *FileName\r
-  )\r
-/*++\r
-Routine Description:\r
-  Read first 512 bytes from file.\r
-\r
-Arguments:\r
-  BootSector - point to a buffer receiving the first 512 bytes data from file\r
-  FileName   - file to read from\r
-\r
-Return:\r
-  int        - number of bytes read,\r
-                 512 indicates read successful\r
-                 0 indicates read failure\r
---*/\r
-{\r
-  FILE *FileHandle;\r
-  int  result;\r
-\r
-  FileHandle = fopen (FileName, "rb");\r
-  if (FileHandle == NULL) {\r
-    DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "Open file: %s", FileName);\r
-    return 0;\r
-  }\r
-\r
-  result = fread (BootSector, 1, 512, FileHandle);\r
-  if (result != 512) {\r
-    DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "Read file: %s", FileName);\r
-    result = 0;\r
-  }\r
-\r
-  fclose (FileHandle);\r
-  return result;\r
-}\r
-\r
-char *\r
-FatTypeToString (\r
-  IN FAT_TYPE        FatType\r
-  )\r
-/*++\r
-Routine Description:\r
-  Convert enum type of FatType to string\r
---*/\r
-{\r
-  switch (FatType) {\r
-  case FatTypeFat12:\r
-    return "FAT12";\r
-  case FatTypeFat16:\r
-    return "FAT16";\r
-  case FatTypeFat32:\r
-    return "FAT32";\r
-  default:\r
-    break;\r
-  }\r
-  return "FAT Unknown";\r
-}\r
-\r
-FAT_TYPE\r
-GetFatType (\r
-  IN FAT_BPB_STRUCT  *FatBpb\r
-  )\r
-/*++\r
-Routine Description:\r
-  Determine the FAT type according to BIOS Paramater Block (BPB) data\r
-\r
-Arguments:\r
-  FatBpb - BIOS Parameter Block (BPB) data, 512 Bytes\r
-\r
-Return:\r
-  FatTypeUnknown - Cannot determine the FAT type\r
-  FatTypeFat12   - FAT12\r
-  FatTypeFat16   - FAT16\r
-  FatTypeFat32   - FAT32\r
---*/\r
-{\r
-  FAT_TYPE FatType;\r
-  UINTN    RootDirSectors;\r
-  UINTN    FATSz;\r
-  UINTN    TotSec;\r
-  UINTN    DataSec;\r
-  UINTN    CountOfClusters;\r
-  CHAR8    FilSysType[9];\r
-\r
-  FatType = FatTypeUnknown;\r
-\r
-  //\r
-  // Simple check\r
-  //\r
-  if (FatBpb->Fat12_16.Signature != FAT_BS_SIGNATURE) {\r
-    DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT: Signature Invalid - %04x, expected - %04x",\r
-        FatBpb->Fat12_16.Signature, FAT_BS_SIGNATURE);\r
-    return FatTypeUnknown;\r
-  }\r
-\r
-  //\r
-  // Check according to FAT spec\r
-  //\r
-  if ((FatBpb->Fat12_16.BS_jmpBoot[0] != FAT_BS_JMP1) &&\r
-      (FatBpb->Fat12_16.BS_jmpBoot[0] != FAT_BS_JMP2)) {\r
-    DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT: BS_jmpBoot - %02x, expected - %02x or %02x",\r
-        FatBpb->Fat12_16.BS_jmpBoot[0], FAT_BS_JMP1, FAT_BS_JMP2);\r
-    return FatTypeUnknown;\r
-  }\r
-\r
-  if ((FatBpb->Fat12_16.BPB_BytsPerSec != 512) &&\r
-      (FatBpb->Fat12_16.BPB_BytsPerSec != 1024) &&\r
-      (FatBpb->Fat12_16.BPB_BytsPerSec != 2048) &&\r
-      (FatBpb->Fat12_16.BPB_BytsPerSec != 4096)) {\r
-    DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT: BPB_BytsPerSec - %04x, expected - %04x, %04x, %04x, or %04x",\r
-        FatBpb->Fat12_16.BPB_BytsPerSec, 512, 1024, 2048, 4096);\r
-    return FatTypeUnknown;\r
-  }\r
-  if (FatBpb->Fat12_16.BPB_BytsPerSec != 512) {\r
-    DebugMsg (NULL, 0, DEBUG_WARN, NULL, "FAT: BPB_BytsPerSec - %04x, expected - %04x",\r
-        FatBpb->Fat12_16.BPB_BytsPerSec, 512);\r
-  }\r
-  if ((FatBpb->Fat12_16.BPB_SecPerClus != 1) &&\r
-      (FatBpb->Fat12_16.BPB_SecPerClus != 2) &&\r
-      (FatBpb->Fat12_16.BPB_SecPerClus != 4) &&\r
-      (FatBpb->Fat12_16.BPB_SecPerClus != 8) &&\r
-      (FatBpb->Fat12_16.BPB_SecPerClus != 16) &&\r
-      (FatBpb->Fat12_16.BPB_SecPerClus != 32) &&\r
-      (FatBpb->Fat12_16.BPB_SecPerClus != 64) &&\r
-      (FatBpb->Fat12_16.BPB_SecPerClus != 128)) {\r
-    DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT: BPB_SecPerClus - %02x, expected - %02x, %02x, %02x, %02x, %02x, %02x, %02x, or %02x",\r
-        FatBpb->Fat12_16.BPB_BytsPerSec, 1, 2, 4, 8, 16, 32, 64, 128);\r
-    return FatTypeUnknown;\r
-  }\r
-  if (FatBpb->Fat12_16.BPB_BytsPerSec * FatBpb->Fat12_16.BPB_SecPerClus > 32 * 1024) {\r
-    DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT: BPB_BytsPerSec * BPB_SecPerClus - %08x, expected <= %08x",\r
-        FatBpb->Fat12_16.BPB_BytsPerSec * FatBpb->Fat12_16.BPB_SecPerClus, 32 * 1024);\r
-    return FatTypeUnknown;\r
-  }\r
-  if (FatBpb->Fat12_16.BPB_RsvdSecCnt == 0) {\r
-    DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT: BPB_RsvdSecCnt - %04x, expected - Non-Zero",\r
-        FatBpb->Fat12_16.BPB_RsvdSecCnt);\r
-    return FatTypeUnknown;\r
-  }\r
-  if (FatBpb->Fat12_16.BPB_NumFATs != 2) {\r
-    DebugMsg (NULL, 0, DEBUG_WARN, NULL, "FAT: BPB_NumFATs - %02x, expected - %02x",\r
-        FatBpb->Fat12_16.BPB_NumFATs, 2);\r
-  }\r
-  if ((FatBpb->Fat12_16.BPB_Media != 0xF0) &&\r
-      (FatBpb->Fat12_16.BPB_Media != 0xF8) &&\r
-      (FatBpb->Fat12_16.BPB_Media != 0xF9) &&\r
-      (FatBpb->Fat12_16.BPB_Media != 0xFA) &&\r
-      (FatBpb->Fat12_16.BPB_Media != 0xFB) &&\r
-      (FatBpb->Fat12_16.BPB_Media != 0xFC) &&\r
-      (FatBpb->Fat12_16.BPB_Media != 0xFD) &&\r
-      (FatBpb->Fat12_16.BPB_Media != 0xFE) &&\r
-      (FatBpb->Fat12_16.BPB_Media != 0xFF)) {\r
-    DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT: BPB_Media - %02x, expected - %02x, %02x, %02x, %02x, %02x, %02x, %02x, %02x, or %02x",\r
-        FatBpb->Fat12_16.BPB_Media, 0xF0, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF);\r
-    return FatTypeUnknown;\r
-  }\r
-\r
-  //\r
-  // Algo in FAT spec\r
-  //\r
-  RootDirSectors = ((FatBpb->Fat12_16.BPB_RootEntCnt * sizeof(FAT_DIRECTORY_ENTRY)) +\r
-                    (FatBpb->Fat12_16.BPB_BytsPerSec - 1)) /\r
-                   FatBpb->Fat12_16.BPB_BytsPerSec;\r
-\r
-  if (FatBpb->Fat12_16.BPB_FATSz16 != 0) {\r
-    FATSz = FatBpb->Fat12_16.BPB_FATSz16;\r
-  } else {\r
-    FATSz = FatBpb->Fat32.BPB_FATSz32;\r
-  }\r
-  if (FATSz == 0) {\r
-    DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT: BPB_FATSz16, BPB_FATSz32 - 0, expected - Non-Zero");\r
-    return FatTypeUnknown;\r
-  }\r
-\r
-  if (FatBpb->Fat12_16.BPB_TotSec16 != 0) {\r
-    TotSec = FatBpb->Fat12_16.BPB_TotSec16;\r
-  } else {\r
-    TotSec = FatBpb->Fat12_16.BPB_TotSec32;\r
-  }\r
-  if (TotSec == 0) {\r
-    DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT: BPB_TotSec16, BPB_TotSec32 - 0, expected - Non-Zero");\r
-    return FatTypeUnknown;\r
-  }\r
-\r
-  DataSec = TotSec - (\r
-                      FatBpb->Fat12_16.BPB_RsvdSecCnt +\r
-                      FatBpb->Fat12_16.BPB_NumFATs * FATSz +\r
-                      RootDirSectors\r
-                     );\r
-\r
-  CountOfClusters = DataSec / FatBpb->Fat12_16.BPB_SecPerClus;\r
-\r
-  if (CountOfClusters < FAT_MAX_FAT12_CLUSTER) {\r
-    FatType = FatTypeFat12;\r
-  } else if (CountOfClusters < FAT_MAX_FAT16_CLUSTER) {\r
-    FatType = FatTypeFat16;\r
-  } else {\r
-    FatType = FatTypeFat32;\r
-  }\r
-  //\r
-  // Check according to FAT spec\r
-  //\r
-  if (((FatType == FatTypeFat12) || (FatType == FatTypeFat16)) &&\r
-       (FatBpb->Fat12_16.BPB_RsvdSecCnt != 1)) {\r
-    DebugMsg (NULL, 0, DEBUG_WARN, NULL, "FAT12_16: BPB_RsvdSecCnt - %04x, expected - %04x",\r
-        FatBpb->Fat12_16.BPB_RsvdSecCnt, 1);\r
-  }\r
-  if ((FatType == FatTypeFat32) &&\r
-       (FatBpb->Fat12_16.BPB_RsvdSecCnt != 32)) {\r
-    DebugMsg (NULL, 0, DEBUG_WARN, NULL, "FAT32: BPB_RsvdSecCnt - %04x, expected - %04x",\r
-        FatBpb->Fat12_16.BPB_RsvdSecCnt, 32);\r
-  }\r
-  if ((FatType == FatTypeFat16) &&\r
-      (FatBpb->Fat12_16.BPB_RootEntCnt != 512)) {\r
-    printf ("WARNING: FAT16: BPB_RootEntCnt - %04x, expected - %04x\n",\r
-        FatBpb->Fat12_16.BPB_RootEntCnt, 512);\r
-  }\r
-  if ((FatType == FatTypeFat32) &&\r
-      (FatBpb->Fat12_16.BPB_RootEntCnt != 0)) {\r
-    DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT32: BPB_RootEntCnt - %04x, expected - %04x",\r
-        FatBpb->Fat12_16.BPB_RootEntCnt, 0);\r
-    return FatTypeUnknown;\r
-  }\r
-  if ((FatType == FatTypeFat32) &&\r
-      (FatBpb->Fat12_16.BPB_TotSec16 != 0)) {\r
-    DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT32: BPB_TotSec16 - %04x, expected - %04x",\r
-        FatBpb->Fat12_16.BPB_TotSec16, 0);\r
-    return FatTypeUnknown;\r
-  }\r
-  if ((FatType == FatTypeFat32) &&\r
-      (FatBpb->Fat12_16.BPB_FATSz16 != 0)) {\r
-    DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT32: BPB_FATSz16 - %04x, expected - %04x",\r
-        FatBpb->Fat12_16.BPB_FATSz16, 0);\r
-    return FatTypeUnknown;\r
-  }\r
-  if ((FatType == FatTypeFat32) &&\r
-      (FatBpb->Fat12_16.BPB_TotSec32 == 0)) {\r
-    DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT32: BPB_TotSec32 - %04x, expected - Non-Zero",\r
-        FatBpb->Fat12_16.BPB_TotSec32);\r
-    return FatTypeUnknown;\r
-  }\r
-  if ((FatType == FatTypeFat32) &&\r
-      (FatBpb->Fat32.BPB_FATSz32 == 0)) {\r
-    DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT32: BPB_FATSz32 - %08x, expected - Non-Zero",\r
-        FatBpb->Fat32.BPB_FATSz32);\r
-    return FatTypeUnknown;\r
-  }\r
-  if ((FatType == FatTypeFat32) &&\r
-      (FatBpb->Fat32.BPB_FSVer != 0)) {\r
-    DebugMsg (NULL, 0, DEBUG_WARN, NULL, "FAT32: BPB_FSVer - %08x, expected - %04x",\r
-        FatBpb->Fat32.BPB_FSVer, 0);\r
-  }\r
-  if ((FatType == FatTypeFat32) &&\r
-      (FatBpb->Fat32.BPB_RootClus != 2)) {\r
-    DebugMsg (NULL, 0, DEBUG_WARN, NULL, "FAT32: BPB_RootClus - %08x, expected - %04x",\r
-        FatBpb->Fat32.BPB_RootClus, 2);\r
-  }\r
-  if ((FatType == FatTypeFat32) &&\r
-      (FatBpb->Fat32.BPB_FSInfo != 1)) {\r
-    DebugMsg (NULL, 0, DEBUG_WARN, NULL, "FAT32: BPB_FSInfo - %08x, expected - %04x",\r
-        FatBpb->Fat32.BPB_FSInfo, 1);\r
-  }\r
-  if ((FatType == FatTypeFat32) &&\r
-      (FatBpb->Fat32.BPB_BkBootSec != 6)) {\r
-    DebugMsg (NULL, 0, DEBUG_WARN, NULL, "FAT32: BPB_BkBootSec - %08x, expected - %04x",\r
-        FatBpb->Fat32.BPB_BkBootSec, 6);\r
-  }\r
-  if ((FatType == FatTypeFat32) &&\r
-      ((*(UINT32 *)FatBpb->Fat32.BPB_Reserved != 0) ||\r
-       (*((UINT32 *)FatBpb->Fat32.BPB_Reserved + 1) != 0) ||\r
-       (*((UINT32 *)FatBpb->Fat32.BPB_Reserved + 2) != 0))) {\r
-    DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT32: BPB_Reserved - %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x, expected - 0",\r
-        FatBpb->Fat32.BPB_Reserved[0],\r
-        FatBpb->Fat32.BPB_Reserved[1],\r
-        FatBpb->Fat32.BPB_Reserved[2],\r
-        FatBpb->Fat32.BPB_Reserved[3],\r
-        FatBpb->Fat32.BPB_Reserved[4],\r
-        FatBpb->Fat32.BPB_Reserved[5],\r
-        FatBpb->Fat32.BPB_Reserved[6],\r
-        FatBpb->Fat32.BPB_Reserved[7],\r
-        FatBpb->Fat32.BPB_Reserved[8],\r
-        FatBpb->Fat32.BPB_Reserved[9],\r
-        FatBpb->Fat32.BPB_Reserved[10],\r
-        FatBpb->Fat32.BPB_Reserved[11]);\r
-    return FatTypeUnknown;\r
-  }\r
-  if (((FatType == FatTypeFat12) || (FatType == FatTypeFat16)) &&\r
-       (FatBpb->Fat12_16.BS_Reserved1 != 0)) {\r
-    DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT12_16: BS_Reserved1 - %02x, expected - 0\n",\r
-        FatBpb->Fat12_16.BS_Reserved1);\r
-    return FatTypeUnknown;\r
-  }\r
-  if ((FatType == FatTypeFat32) &&\r
-      (FatBpb->Fat32.BS_Reserved1 != 0)) {\r
-    DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT32: BS_Reserved1 - %02x, expected - 0\n",\r
-        FatBpb->Fat32.BS_Reserved1);\r
-    return FatTypeUnknown;\r
-  }\r
-  if (((FatType == FatTypeFat12) || (FatType == FatTypeFat16)) &&\r
-       (FatBpb->Fat12_16.BS_BootSig != FAT_BS_BOOTSIG)) {\r
-    DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT12_16: BS_BootSig - %02x, expected - %02x\n",\r
-        FatBpb->Fat12_16.BS_BootSig, FAT_BS_BOOTSIG);\r
-    return FatTypeUnknown;\r
-  }\r
-  if ((FatType == FatTypeFat32) &&\r
-      (FatBpb->Fat32.BS_BootSig != FAT_BS_BOOTSIG)) {\r
-    DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT32: BS_BootSig - %02x, expected - %02x\n",\r
-        FatBpb->Fat32.BS_BootSig, FAT_BS_BOOTSIG);\r
-    return FatTypeUnknown;\r
-  }\r
-  \r
-  if ((FatType == FatTypeFat12) || (FatType == FatTypeFat16)) {\r
-    memcpy (FilSysType, FatBpb->Fat12_16.BS_FilSysType, 8);\r
-    FilSysType[8] = 0;\r
-    if ((FatType == FatTypeFat12) && \r
-        (strcmp (FilSysType, FAT12_FILSYSTYPE) != 0) &&\r
-        (strcmp (FilSysType, FAT_FILSYSTYPE) != 0)) {\r
-      DebugMsg (NULL, 0, DEBUG_WARN, NULL, "FAT12: BS_FilSysType - %s, expected - %s, or %s\n",\r
-          FilSysType, FAT12_FILSYSTYPE, FAT_FILSYSTYPE);\r
-    }\r
-    if ((FatType == FatTypeFat16) && \r
-        (strcmp (FilSysType, FAT16_FILSYSTYPE) != 0) &&\r
-        (strcmp (FilSysType, FAT_FILSYSTYPE) != 0)) {\r
-      DebugMsg (NULL, 0, DEBUG_WARN, NULL, "FAT16: BS_FilSysType - %s, expected - %s, or %s\n",\r
-          FilSysType, FAT16_FILSYSTYPE, FAT_FILSYSTYPE);\r
-    }\r
-  }\r
-  if (FatType == FatTypeFat32) {\r
-    memcpy (FilSysType, FatBpb->Fat32.BS_FilSysType, 8);\r
-    FilSysType[8] = 0;\r
-    if (strcmp (FilSysType, FAT32_FILSYSTYPE) != 0) {\r
-      DebugMsg (NULL, 0, DEBUG_WARN, NULL, "FAT32: BS_FilSysType - %s, expected - %s\n",\r
-          FilSysType, FAT32_FILSYSTYPE);\r
-    }\r
-  }\r
-\r
-  //\r
-  // pass all check, get FAT type\r
-  //\r
-  return FatType;\r
-}\r
-\r
-\r
-void\r
-ParseBootSector (\r
-  char *FileName\r
-  )\r
-{\r
-  FAT_BPB_STRUCT  FatBpb;\r
-  FAT_TYPE        FatType;\r
-  \r
-  if (ReadFromFile ((void *)&FatBpb, FileName) == 0) {\r
-    return ;\r
-  }\r
-  \r
-  FatType = GetFatType (&FatBpb);\r
-  if (FatType <= FatTypeUnknown || FatType >= FatTypeMax) {\r
-    printf ("ERROR: Unknown Fat Type!\n");\r
-    return;\r
-  }\r
-\r
-  printf ("\nBoot Sector %s:\n", FatTypeToString (FatType));\r
-  printf ("\n");\r
-  printf ("  Offset Title                        Data\n");\r
-  printf ("==================================================================\n");\r
-  printf ("  0      JMP instruction              %02x %02x %02x\n",\r
-                                                 FatBpb.Fat12_16.BS_jmpBoot[0],\r
-                                                 FatBpb.Fat12_16.BS_jmpBoot[1],\r
-                                                 FatBpb.Fat12_16.BS_jmpBoot[2]);\r
-  printf ("  3      OEM                          %c%c%c%c%c%c%c%c\n",\r
-                                                 FatBpb.Fat12_16.BS_OEMName[0],\r
-                                                 FatBpb.Fat12_16.BS_OEMName[1],\r
-                                                 FatBpb.Fat12_16.BS_OEMName[2],\r
-                                                 FatBpb.Fat12_16.BS_OEMName[3],\r
-                                                 FatBpb.Fat12_16.BS_OEMName[4],\r
-                                                 FatBpb.Fat12_16.BS_OEMName[5],\r
-                                                 FatBpb.Fat12_16.BS_OEMName[6],\r
-                                                 FatBpb.Fat12_16.BS_OEMName[7]);\r
-  printf ("\n");\r
-  printf ("BIOS Parameter Block\n");\r
-  printf ("  B      Bytes per sector             %04x\n", FatBpb.Fat12_16.BPB_BytsPerSec);\r
-  printf ("  D      Sectors per cluster          %02x\n", FatBpb.Fat12_16.BPB_SecPerClus);\r
-  printf ("  E      Reserved sectors             %04x\n", FatBpb.Fat12_16.BPB_RsvdSecCnt);\r
-  printf ("  10     Number of FATs               %02x\n", FatBpb.Fat12_16.BPB_NumFATs);\r
-  printf ("  11     Root entries                 %04x\n", FatBpb.Fat12_16.BPB_RootEntCnt);\r
-  printf ("  13     Sectors (under 32MB)         %04x\n", FatBpb.Fat12_16.BPB_TotSec16);\r
-  printf ("  15     Media descriptor             %02x\n", FatBpb.Fat12_16.BPB_Media);\r
-  printf ("  16     Sectors per FAT (small vol.) %04x\n", FatBpb.Fat12_16.BPB_FATSz16);\r
-  printf ("  18     Sectors per track            %04x\n", FatBpb.Fat12_16.BPB_SecPerTrk);\r
-  printf ("  1A     Heads                        %04x\n", FatBpb.Fat12_16.BPB_NumHeads);\r
-  printf ("  1C     Hidden sectors               %08x\n", FatBpb.Fat12_16.BPB_HiddSec);\r
-  printf ("  20     Sectors (over 32MB)          %08x\n", FatBpb.Fat12_16.BPB_TotSec32);\r
-  printf ("\n");\r
-  if (FatType != FatTypeFat32) {\r
-    printf ("  24     BIOS drive                   %02x\n", FatBpb.Fat12_16.BS_DrvNum);\r
-    printf ("  25     (Unused)                     %02x\n", FatBpb.Fat12_16.BS_Reserved1);\r
-    printf ("  26     Ext. boot signature          %02x\n", FatBpb.Fat12_16.BS_BootSig);\r
-    printf ("  27     Volume serial number         %08x\n", FatBpb.Fat12_16.BS_VolID);\r
-    printf ("  2B     Volume lable                 %c%c%c%c%c%c%c%c%c%c%c\n",\r
-                                                   FatBpb.Fat12_16.BS_VolLab[0],\r
-                                                   FatBpb.Fat12_16.BS_VolLab[1],\r
-                                                   FatBpb.Fat12_16.BS_VolLab[2],\r
-                                                   FatBpb.Fat12_16.BS_VolLab[3],\r
-                                                   FatBpb.Fat12_16.BS_VolLab[4],\r
-                                                   FatBpb.Fat12_16.BS_VolLab[5],\r
-                                                   FatBpb.Fat12_16.BS_VolLab[6],\r
-                                                   FatBpb.Fat12_16.BS_VolLab[7],\r
-                                                   FatBpb.Fat12_16.BS_VolLab[8],\r
-                                                   FatBpb.Fat12_16.BS_VolLab[9],\r
-                                                   FatBpb.Fat12_16.BS_VolLab[10]);\r
-    printf ("  36     File system                  %c%c%c%c%c%c%c%c\n",\r
-                                                   FatBpb.Fat12_16.BS_FilSysType[0],\r
-                                                   FatBpb.Fat12_16.BS_FilSysType[1],\r
-                                                   FatBpb.Fat12_16.BS_FilSysType[2],\r
-                                                   FatBpb.Fat12_16.BS_FilSysType[3],\r
-                                                   FatBpb.Fat12_16.BS_FilSysType[4],\r
-                                                   FatBpb.Fat12_16.BS_FilSysType[5],\r
-                                                   FatBpb.Fat12_16.BS_FilSysType[6],\r
-                                                   FatBpb.Fat12_16.BS_FilSysType[7]);\r
-    printf ("\n");\r
-  } else {\r
-    printf ("FAT32 Section\n");\r
-    printf ("  24     Sectors per FAT (large vol.) %08x\n", FatBpb.Fat32.BPB_FATSz32);\r
-    printf ("  28     Flags                        %04x\n", FatBpb.Fat32.BPB_ExtFlags);\r
-    printf ("  2A     Version                      %04x\n", FatBpb.Fat32.BPB_FSVer);\r
-    printf ("  2C     Root dir 1st cluster         %08x\n", FatBpb.Fat32.BPB_RootClus);\r
-    printf ("  30     FSInfo sector                %04x\n", FatBpb.Fat32.BPB_FSInfo);\r
-    printf ("  32     Backup boot sector           %04x\n", FatBpb.Fat32.BPB_BkBootSec);\r
-    printf ("  34     (Reserved)                   %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n",\r
-                                                   FatBpb.Fat32.BPB_Reserved[0],\r
-                                                   FatBpb.Fat32.BPB_Reserved[1],\r
-                                                   FatBpb.Fat32.BPB_Reserved[2],\r
-                                                   FatBpb.Fat32.BPB_Reserved[3],\r
-                                                   FatBpb.Fat32.BPB_Reserved[4],\r
-                                                   FatBpb.Fat32.BPB_Reserved[5],\r
-                                                   FatBpb.Fat32.BPB_Reserved[6],\r
-                                                   FatBpb.Fat32.BPB_Reserved[7],\r
-                                                   FatBpb.Fat32.BPB_Reserved[8],\r
-                                                   FatBpb.Fat32.BPB_Reserved[9],\r
-                                                   FatBpb.Fat32.BPB_Reserved[10],\r
-                                                   FatBpb.Fat32.BPB_Reserved[11]);\r
-    printf ("\n");\r
-    printf ("  40     BIOS drive                   %02x\n", FatBpb.Fat32.BS_DrvNum);\r
-    printf ("  41     (Unused)                     %02x\n", FatBpb.Fat32.BS_Reserved1);\r
-    printf ("  42     Ext. boot signature          %02x\n", FatBpb.Fat32.BS_BootSig);\r
-    printf ("  43     Volume serial number         %08x\n", FatBpb.Fat32.BS_VolID);\r
-    printf ("  47     Volume lable                 %c%c%c%c%c%c%c%c%c%c%c\n",\r
-                                                   FatBpb.Fat32.BS_VolLab[0],\r
-                                                   FatBpb.Fat32.BS_VolLab[1],\r
-                                                   FatBpb.Fat32.BS_VolLab[2],\r
-                                                   FatBpb.Fat32.BS_VolLab[3],\r
-                                                   FatBpb.Fat32.BS_VolLab[4],\r
-                                                   FatBpb.Fat32.BS_VolLab[5],\r
-                                                   FatBpb.Fat32.BS_VolLab[6],\r
-                                                   FatBpb.Fat32.BS_VolLab[7],\r
-                                                   FatBpb.Fat32.BS_VolLab[8],\r
-                                                   FatBpb.Fat32.BS_VolLab[9],\r
-                                                   FatBpb.Fat32.BS_VolLab[10]);\r
-    printf ("  52     File system                  %c%c%c%c%c%c%c%c\n",\r
-                                                   FatBpb.Fat32.BS_FilSysType[0],\r
-                                                   FatBpb.Fat32.BS_FilSysType[1],\r
-                                                   FatBpb.Fat32.BS_FilSysType[2],\r
-                                                   FatBpb.Fat32.BS_FilSysType[3],\r
-                                                   FatBpb.Fat32.BS_FilSysType[4],\r
-                                                   FatBpb.Fat32.BS_FilSysType[5],\r
-                                                   FatBpb.Fat32.BS_FilSysType[6],\r
-                                                   FatBpb.Fat32.BS_FilSysType[7]);\r
-    printf ("\n");\r
-  }\r
-  printf ("  1FE    Signature                    %04x\n", FatBpb.Fat12_16.Signature);\r
-  printf ("\n");\r
-\r
-  \r
-  return ;\r
-}\r
-\r
-void\r
-PatchBootSector (\r
-  char *DestFileName,\r
-  char *SourceFileName,\r
-  BOOL ForcePatch\r
-  )\r
-/*++\r
-Routine Description:\r
-  Patch destination file according to the information from source file.\r
-  Only patch BPB data but leave boot code un-touched.\r
-\r
-Arguments:\r
-  DestFileName   - Destination file to patch\r
-  SourceFileName - Source file where patch from\r
---*/\r
-{\r
-  FAT_BPB_STRUCT  DestFatBpb;\r
-  FAT_BPB_STRUCT  SourceFatBpb;\r
-  FAT_TYPE        DestFatType;\r
-  FAT_TYPE        SourceFatType;\r
-  CHAR8           VolLab[11];\r
-  CHAR8           FilSysType[8];\r
-  \r
-  if (ReadFromFile ((void *)&DestFatBpb, DestFileName) == 0) {\r
-    return ;\r
-  }\r
-  if (ReadFromFile ((void *)&SourceFatBpb, SourceFileName) == 0) {\r
-    return ;\r
-  }\r
-  \r
-  DestFatType = GetFatType (&DestFatBpb);\r
-  SourceFatType = GetFatType (&SourceFatBpb);\r
-\r
-  if (DestFatType != SourceFatType) {\r
-    //\r
-    // FAT type mismatch\r
-    //\r
-    if (ForcePatch) {\r
-      DebugMsg (NULL, 0, DEBUG_WARN, NULL, "FAT type mismatch: Dest - %s, Source - %s", \r
-          FatTypeToString(DestFatType), FatTypeToString(SourceFatType));\r
-    } else {\r
-      DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT type mismatch: Dest - %s, Source - %s", \r
-          FatTypeToString(DestFatType), FatTypeToString(SourceFatType));\r
-      return ;\r
-    }\r
-  }\r
-\r
-  if (SourceFatType <= FatTypeUnknown || SourceFatType >= FatTypeMax) {\r
-    DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "Unknown Fat Type!\n");\r
-    return;\r
-  }\r
-\r
-  //\r
-  // Copy BPB/boot data (excluding BS_jmpBoot, BS_OEMName, BootCode and Signature) from SourceFatBpb to DestFatBpb\r
-  //\r
-  printf ("Patching %s BPB: ", FatTypeToString (SourceFatType));\r
-  if (SourceFatType != FatTypeFat32) {\r
-    memcpy (\r
-      &DestFatBpb.Fat12_16.BPB_BytsPerSec,\r
-      &SourceFatBpb.Fat12_16.BPB_BytsPerSec,\r
-      ((UINTN)&DestFatBpb.Fat12_16.Reserved - (UINTN)&DestFatBpb.Fat12_16.BPB_BytsPerSec)\r
-      );\r
-  } else {\r
-    memcpy (\r
-      &DestFatBpb.Fat32.BPB_BytsPerSec,\r
-      &SourceFatBpb.Fat32.BPB_BytsPerSec,\r
-      ((UINTN)&DestFatBpb.Fat32.Reserved - (UINTN)&DestFatBpb.Fat32.BPB_BytsPerSec)\r
-      );\r
-  }\r
-\r
-  //\r
-  // Set BS_VolLab and BS_FilSysType of DestFatBpb\r
-  //\r
-  //        BS_VolLab     BS_FilSysType\r
-  // FAT12: EFI FAT12     FAT12\r
-  // FAT16: EFI FAT16     FAT16\r
-  // FAT32: EFI FAT32     FAT32\r
-  //\r
-  if (SourceFatType == FatTypeFat32) {\r
-    memcpy (VolLab, "EFI FAT32  ", sizeof(VolLab));\r
-    memcpy (FilSysType, FAT32_FILSYSTYPE, sizeof(FilSysType));\r
-  } else if (SourceFatType == FatTypeFat16) {\r
-    memcpy (VolLab, "EFI FAT16  ", sizeof(VolLab));\r
-    memcpy (FilSysType, FAT16_FILSYSTYPE, sizeof(FilSysType));\r
-  } else {\r
-    memcpy (VolLab, "EFI FAT12  ", sizeof(VolLab));\r
-    memcpy (FilSysType, FAT12_FILSYSTYPE, sizeof(FilSysType));\r
-  }\r
-  if (SourceFatType != FatTypeFat32) {\r
-    memcpy (DestFatBpb.Fat12_16.BS_VolLab, VolLab, sizeof(VolLab));\r
-    memcpy (DestFatBpb.Fat12_16.BS_FilSysType, FilSysType, sizeof(FilSysType));\r
-  } else {\r
-    memcpy (DestFatBpb.Fat32.BS_VolLab, VolLab, sizeof(VolLab));\r
-    memcpy (DestFatBpb.Fat32.BS_FilSysType, FilSysType, sizeof(FilSysType));\r
-  }\r
-  \r
-  //\r
-  // Set Signature of DestFatBpb to 55AA\r
-  //\r
-  DestFatBpb.Fat12_16.Signature = FAT_BS_SIGNATURE;\r
-\r
-  //\r
-  // Write DestFatBpb\r
-  //\r
-  if (WriteToFile ((void *)&DestFatBpb, DestFileName)) {\r
-    printf ("successfully!\n");\r
-  } else {\r
-    printf ("failed!\n");\r
-  }\r
-\r
-  return ;\r
-}\r
-\r
-void\r
-ParseMbr (\r
-  char *FileName\r
-  )\r
-{\r
-  MASTER_BOOT_RECORD  Mbr;\r
-  \r
-  if (ReadFromFile ((void *)&Mbr, FileName) == 0) {\r
-    return ;\r
-  }\r
\r
-  printf ("\nMaster Boot Record:\n");\r
-  printf ("\n");\r
-  printf ("  Offset Title                        Value\n");\r
-  printf ("==================================================================\n");\r
-  printf ("  0      Master bootstrap loader code (not list)\n");\r
-  printf ("  1B8    Windows disk signature       %08x\n", Mbr.UniqueMbrSignature);\r
-  printf ("\n");\r
-  printf ("Partition Table Entry #1\n");\r
-  printf ("  1BE    80 = active partition        %02x\n", Mbr.PartitionRecord[0].BootIndicator);\r
-  printf ("  1BF    Start head                   %02x\n", Mbr.PartitionRecord[0].StartHead);\r
-  printf ("  1C0    Start sector                 %02x\n", Mbr.PartitionRecord[0].StartSector);\r
-  printf ("  1C1    Start cylinder               %02x\n", Mbr.PartitionRecord[0].StartTrack);\r
-  printf ("  1C2    Partition type indicator     %02x\n", Mbr.PartitionRecord[0].OSType);\r
-  printf ("  1C3    End head                     %02x\n", Mbr.PartitionRecord[0].EndHead);\r
-  printf ("  1C4    End sector                   %02x\n", Mbr.PartitionRecord[0].EndSector);\r
-  printf ("  1C5    End cylinder                 %02x\n", Mbr.PartitionRecord[0].EndTrack);\r
-  printf ("  1C6    Sectors preceding partition  %08x\n", Mbr.PartitionRecord[0].StartingLBA);\r
-  printf ("  1CA    Sectors in partition         %08x\n", Mbr.PartitionRecord[0].SizeInLBA);\r
-  printf ("\n");\r
-  printf ("Partition Table Entry #2\n");\r
-  printf ("  1CE    80 = active partition        %02x\n", Mbr.PartitionRecord[1].BootIndicator);\r
-  printf ("  1CF    Start head                   %02x\n", Mbr.PartitionRecord[1].StartHead);\r
-  printf ("  1D0    Start sector                 %02x\n", Mbr.PartitionRecord[1].StartSector);\r
-  printf ("  1D1    Start cylinder               %02x\n", Mbr.PartitionRecord[1].StartTrack);\r
-  printf ("  1D2    Partition type indicator     %02x\n", Mbr.PartitionRecord[1].OSType);\r
-  printf ("  1D3    End head                     %02x\n", Mbr.PartitionRecord[1].EndHead);\r
-  printf ("  1D4    End sector                   %02x\n", Mbr.PartitionRecord[1].EndSector);\r
-  printf ("  1D5    End cylinder                 %02x\n", Mbr.PartitionRecord[1].EndTrack);\r
-  printf ("  1D6    Sectors preceding partition  %08x\n", Mbr.PartitionRecord[1].StartingLBA);\r
-  printf ("  1DA    Sectors in partition         %08x\n", Mbr.PartitionRecord[1].SizeInLBA);\r
-  printf ("\n");\r
-  printf ("Partition Table Entry #3\n");\r
-  printf ("  1DE    80 = active partition        %02x\n", Mbr.PartitionRecord[2].BootIndicator);\r
-  printf ("  1DF    Start head                   %02x\n", Mbr.PartitionRecord[2].StartHead);\r
-  printf ("  1E0    Start sector                 %02x\n", Mbr.PartitionRecord[2].StartSector);\r
-  printf ("  1E1    Start cylinder               %02x\n", Mbr.PartitionRecord[2].StartTrack);\r
-  printf ("  1E2    Partition type indicator     %02x\n", Mbr.PartitionRecord[2].OSType);\r
-  printf ("  1E3    End head                     %02x\n", Mbr.PartitionRecord[2].EndHead);\r
-  printf ("  1E4    End sector                   %02x\n", Mbr.PartitionRecord[2].EndSector);\r
-  printf ("  1E5    End cylinder                 %02x\n", Mbr.PartitionRecord[2].EndTrack);\r
-  printf ("  1E6    Sectors preceding partition  %08x\n", Mbr.PartitionRecord[2].StartingLBA);\r
-  printf ("  1EA    Sectors in partition         %08x\n", Mbr.PartitionRecord[2].SizeInLBA);\r
-  printf ("\n");\r
-  printf ("Partition Table Entry #4\n");\r
-  printf ("  1EE    80 = active partition        %02x\n", Mbr.PartitionRecord[3].BootIndicator);\r
-  printf ("  1EF    Start head                   %02x\n", Mbr.PartitionRecord[3].StartHead);\r
-  printf ("  1F0    Start sector                 %02x\n", Mbr.PartitionRecord[3].StartSector);\r
-  printf ("  1F1    Start cylinder               %02x\n", Mbr.PartitionRecord[3].StartTrack);\r
-  printf ("  1F2    Partition type indicator     %02x\n", Mbr.PartitionRecord[3].OSType);\r
-  printf ("  1F3    End head                     %02x\n", Mbr.PartitionRecord[3].EndHead);\r
-  printf ("  1F4    End sector                   %02x\n", Mbr.PartitionRecord[3].EndSector);\r
-  printf ("  1F5    End cylinder                 %02x\n", Mbr.PartitionRecord[3].EndTrack);\r
-  printf ("  1F6    Sectors preceding partition  %08x\n", Mbr.PartitionRecord[3].StartingLBA);\r
-  printf ("  1FA    Sectors in partition         %08x\n", Mbr.PartitionRecord[3].SizeInLBA);\r
-  printf ("\n");\r
-  printf ("  1FE    Signature                    %04x\n", Mbr.Signature);\r
-  printf ("\n");\r
-\r
-  return ;\r
-}\r
-\r
-void\r
-PatchMbr (\r
-  char *DestFileName,\r
-  char *SourceFileName\r
-  )\r
-{\r
-  MASTER_BOOT_RECORD  DestMbr;\r
-  MASTER_BOOT_RECORD  SourceMbr;\r
-  \r
-  if (ReadFromFile ((void *)&DestMbr, DestFileName) == 0) {\r
-    return ;\r
-  }\r
-  if (ReadFromFile ((void *)&SourceMbr, SourceFileName) == 0) {\r
-    return ;\r
-  }\r
-  \r
-  if (SourceMbr.Signature != MBR_SIGNATURE) {\r
-    printf ("ERROR: Invalid MBR!\n");\r
-    return;\r
-  }\r
-\r
-  printf ("Patching MBR:\n");\r
-  memcpy (\r
-    &DestMbr.PartitionRecord[0],\r
-    &SourceMbr.PartitionRecord[0],\r
-    sizeof(DestMbr.PartitionRecord)\r
-    );\r
-\r
-  DestMbr.Signature = MBR_SIGNATURE;\r
-\r
-\r
-  if (WriteToFile ((void *)&DestMbr, DestFileName)) {\r
-    printf ("\tsuccessfully!\n");\r
-  }\r
-\r
-  return ;\r
-}\r
-\r
-void\r
-PrintUsage (\r
-  void\r
-  )\r
-{\r
-  printf (\r
-    "Usage:\n"\r
-    "bootsectimage [-m] [-v] -p SrcImage\n"\r
-    "bootsectimage [-m] [-v] [-f] -g SrcImage DstImage\n"\r
-    "where\n"\r
-    "  -p: parse SrcImage\n"\r
-    "  -g: get info from SrcImage, and patch to DstImage\n"\r
-    "  -f: force patch even FAT type of SrcImage and DstImage mismatch\n"\r
-    "  -m: process MBR instead of boot sector\n"\r
-    "  -v: verbose\n"\r
-    );\r
-}\r
-\r
-int\r
-main (\r
-  int argc,\r
-  char *argv[]\r
-  )\r
-{\r
-  char *SrcImage;\r
-  char *DstImage;\r
-  BOOL ForcePatch;    // -f\r
-  BOOL ProcessMbr;    // -m\r
-  BOOL DoParse;       // -p SrcImage or -g SrcImage DstImage\r
-  BOOL Verbose;       // -v\r
-  \r
-  SrcImage = DstImage = NULL;\r
-  ForcePatch = FALSE;\r
-  ProcessMbr = FALSE;\r
-  DoParse    = TRUE;\r
-  Verbose    = FALSE;\r
-\r
-  SetUtilityName ("bootsectimage");\r
-\r
-  argc--; argv++;\r
-\r
-  if (argc == 0) {\r
-    PrintUsage ();\r
-    return -1;\r
-  }\r
-\r
-  while (argc != 0) {\r
-    if (strcmp (*argv, "-f") == 0) {\r
-      ForcePatch = TRUE;\r
-    } else if (strcmp (*argv, "-p") == 0) {\r
-      DoParse    = TRUE;\r
-      argc--; argv++;\r
-      if (argc < 1) {\r
-        PrintUsage ();\r
-        return -1;\r
-      }\r
-      SrcImage   = *argv;\r
-    } else if (strcmp (*argv, "-g") == 0) {\r
-      DoParse    = FALSE;\r
-      argc--; argv++;\r
-      if (argc < 2) {\r
-        PrintUsage ();\r
-        return -1;\r
-      }\r
-      SrcImage   = *argv;\r
-      argc--; argv++;\r
-      DstImage   = *argv;\r
-    } else if (strcmp (*argv, "-m") == 0) {\r
-      ProcessMbr = TRUE;\r
-    } else if (strcmp (*argv, "-v") == 0) {\r
-      Verbose    = TRUE;\r
-    } else {\r
-      PrintUsage ();\r
-      return -1;\r
-    }\r
-\r
-    argc--; argv++;\r
-  }\r
-\r
-  if (ForcePatch && DoParse) {\r
-    printf ("Cannot apply force(-f) to parse(-p)!\n");\r
-    PrintUsage ();\r
-    return -1;\r
-  }\r
-  if (ForcePatch && !DoParse && ProcessMbr) {\r
-    printf ("Cannot apply force(-f) to processing MBR (-g -m)!\n");\r
-    PrintUsage ();\r
-    return -1;\r
-  }\r
-\r
-  if (Verbose) {\r
-    SetDebugMsgMask (DEBUG_WARN | DEBUG_ERROR);\r
-  } else {\r
-    SetDebugMsgMask (0);\r
-  }\r
-\r
-  if (DoParse) {\r
-    if (ProcessMbr) {\r
-      ParseMbr (SrcImage);\r
-    } else {\r
-      ParseBootSector (SrcImage);\r
-    }\r
-  } else {\r
-    if (ProcessMbr) {\r
-      PatchMbr (DstImage, SrcImage);\r
-    } else {\r
-      PatchBootSector (DstImage, SrcImage, ForcePatch);\r
-    }\r
-  }\r
-\r
-  return 0;\r
-}\r
-\r
diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/BootsectImage/fat.h b/EdkCompatibilityPkg/Sample/Tools/Source/BootsectImage/fat.h
deleted file mode 100644 (file)
index 3303126..0000000
+++ /dev/null
@@ -1,158 +0,0 @@
-/*++\r
-\r
-Copyright 2006, Intel Corporation                                                         \r
-All rights reserved. This program and the accompanying materials                          \r
-are licensed and made available under the terms and conditions of the BSD License         \r
-which accompanies this distribution.  The full text of the license may be found at        \r
-http://opensource.org/licenses/bsd-license.php                                            \r
-                                                                                          \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
-\r
-Module Name:\r
-\r
-    fat.h\r
-    \r
-Abstract:\r
-\r
-Revision History\r
-\r
---*/\r
-\r
-#ifndef _FAT_BPB_H_\r
-#define _FAT_BPB_H_\r
-\r
-#include "Tiano.h"\r
-\r
-#pragma pack(1)\r
-\r
-typedef struct {\r
-  //\r
-  // Fat common field\r
-  //\r
-  UINT8              BS_jmpBoot[3];\r
-  CHAR8              BS_OEMName[8];\r
-  UINT16             BPB_BytsPerSec;\r
-  UINT8              BPB_SecPerClus;\r
-  UINT16             BPB_RsvdSecCnt;\r
-  UINT8              BPB_NumFATs;\r
-  UINT16             BPB_RootEntCnt;\r
-  UINT16             BPB_TotSec16;\r
-  UINT8              BPB_Media;\r
-  UINT16             BPB_FATSz16;\r
-  UINT16             BPB_SecPerTrk;\r
-  UINT16             BPB_NumHeads;\r
-  UINT32             BPB_HiddSec;\r
-  UINT32             BPB_TotSec32;\r
-\r
-  //\r
-  // Fat12/16 specific field\r
-  //\r
-  UINT8              BS_DrvNum;\r
-  UINT8              BS_Reserved1;\r
-  UINT8              BS_BootSig;\r
-  UINT32             BS_VolID;\r
-  CHAR8              BS_VolLab[11];\r
-  CHAR8              BS_FilSysType[8];\r
-\r
-  //\r
-  // Boot Code and Data\r
-  //\r
-  UINT8              Reserved[448];\r
-\r
-  //\r
-  // Fat common signature - 0xAA55\r
-  //\r
-  UINT16             Signature;\r
-} FAT12_16_BPB_STRUCT;\r
-\r
-typedef struct {\r
-  //\r
-  // Fat common field\r
-  //\r
-  UINT8              BS_jmpBoot[3];\r
-  CHAR8              BS_OEMName[8];\r
-  UINT16             BPB_BytsPerSec;\r
-  UINT8              BPB_SecPerClus;\r
-  UINT16             BPB_RsvdSecCnt;\r
-  UINT8              BPB_NumFATs;\r
-  UINT16             BPB_RootEntCnt;\r
-  UINT16             BPB_TotSec16;\r
-  UINT8              BPB_Media;\r
-  UINT16             BPB_FATSz16;\r
-  UINT16             BPB_SecPerTrk;\r
-  UINT16             BPB_NumHeads;\r
-  UINT32             BPB_HiddSec;\r
-  UINT32             BPB_TotSec32;\r
-\r
-  //\r
-  // Fat32 specific field\r
-  //\r
-  UINT32             BPB_FATSz32;\r
-  UINT16             BPB_ExtFlags;\r
-  UINT16             BPB_FSVer;\r
-  UINT32             BPB_RootClus;\r
-  UINT16             BPB_FSInfo;\r
-  UINT16             BPB_BkBootSec;\r
-  UINT8              BPB_Reserved[12];\r
-  UINT8              BS_DrvNum;\r
-  UINT8              BS_Reserved1;\r
-  UINT8              BS_BootSig;\r
-  UINT32             BS_VolID;\r
-  CHAR8              BS_VolLab[11];\r
-  CHAR8              BS_FilSysType[8];\r
-\r
-  //\r
-  // Boot Code and Data\r
-  //\r
-  UINT8              Reserved[420];\r
-\r
-  //\r
-  // Fat common signature - 0xAA55\r
-  //\r
-  UINT16             Signature;\r
-} FAT32_BPB_STRUCT;\r
-\r
-typedef union {\r
-  FAT12_16_BPB_STRUCT   Fat12_16;\r
-  FAT32_BPB_STRUCT      Fat32;\r
-} FAT_BPB_STRUCT;\r
-\r
-typedef enum {\r
-  FatTypeUnknown,\r
-  FatTypeFat12,\r
-  FatTypeFat16,\r
-  FatTypeFat32,\r
-  FatTypeMax\r
-} FAT_TYPE;\r
-\r
-typedef struct {\r
-  CHAR8              DIR_Name[11];\r
-  UINT8              DIR_Attr;\r
-  UINT8              DIR_NTRes;\r
-  UINT8              DIR_CrtTimeTenth;\r
-  UINT16             DIR_CrtTime;\r
-  UINT16             DIR_CrtDate;\r
-  UINT16             DIR_LstAccDate;\r
-  UINT16             DIR_FstClusHI;\r
-  UINT16             DIR_WrtTime;\r
-  UINT16             DIR_WrtDate;\r
-  UINT16             DIR_FstClusLO;\r
-  UINT32             DIR_FileSize;\r
-} FAT_DIRECTORY_ENTRY;\r
-\r
-#pragma pack()\r
-\r
-#define FAT_MAX_FAT12_CLUSTER         0xFF5\r
-#define FAT_MAX_FAT16_CLUSTER         0xFFF5\r
-\r
-#define FAT_BS_SIGNATURE      0xAA55\r
-#define FAT_BS_BOOTSIG        0x29\r
-#define FAT_BS_JMP1           0xEB\r
-#define FAT_BS_JMP2           0xE9\r
-#define FAT_FILSYSTYPE        "FAT     "\r
-#define FAT12_FILSYSTYPE      "FAT12   "\r
-#define FAT16_FILSYSTYPE      "FAT16   "\r
-#define FAT32_FILSYSTYPE      "FAT32   "\r
-\r
-#endif\r
diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/BootsectImage/mbr.h b/EdkCompatibilityPkg/Sample/Tools/Source/BootsectImage/mbr.h
deleted file mode 100644 (file)
index 5a95097..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*++\r
-\r
-Copyright 2006, Intel Corporation                                                         \r
-All rights reserved. This program and the accompanying materials                          \r
-are licensed and made available under the terms and conditions of the BSD License         \r
-which accompanies this distribution.  The full text of the license may be found at        \r
-http://opensource.org/licenses/bsd-license.php                                            \r
-                                                                                          \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
-\r
-Module Name:\r
-\r
-    mbr.h\r
-    \r
-Abstract:\r
-\r
-Revision History\r
-\r
---*/\r
-\r
-#ifndef _MBR_H_\r
-#define _MBR_H_\r
-\r
-#include "Tiano.h"\r
-\r
-#pragma pack(1)\r
-\r
-#define MAX_MBR_PARTITIONS          4\r
-\r
-//\r
-// MBR Partition Entry\r
-//\r
-typedef struct {\r
-  UINT8  BootIndicator;\r
-  UINT8  StartHead;\r
-  UINT8  StartSector;\r
-  UINT8  StartTrack;\r
-  UINT8  OSType;\r
-  UINT8  EndHead;\r
-  UINT8  EndSector;\r
-  UINT8  EndTrack;\r
-  UINT32 StartingLBA;\r
-  UINT32 SizeInLBA;\r
-} MBR_PARTITION_RECORD;\r
-\r
-//\r
-// MBR Partition table\r
-//\r
-typedef struct {\r
-  UINT8                 BootCode[440];\r
-  UINT32                UniqueMbrSignature;\r
-  UINT16                Unknown;\r
-  MBR_PARTITION_RECORD  PartitionRecord[MAX_MBR_PARTITIONS];\r
-  UINT16                Signature;\r
-} MASTER_BOOT_RECORD;\r
-\r
-#pragma pack()\r
-\r
-#define MBR_SIGNATURE               0xAA55\r
-#define EXTENDED_DOS_PARTITION      0x05\r
-#define EXTENDED_WINDOWS_PARTITION  0x0F\r
-\r
-#endif\r
index 4b2bf8114755f91409e07c103e2f9bf5cd5e5b44..d660c07f4b04303a72cc373a1c18d3e670a3b3da 100644 (file)
@@ -390,6 +390,91 @@ Returns:
   return EFI_SUCCESS;\r
 }\r
 \r
+EFI_STATUS\r
+SearchSectionByType (\r
+  IN EFI_FILE_SECTION_POINTER  FirstSection,\r
+  IN UINT8                     *SearchEnd,\r
+  IN EFI_SECTION_TYPE          SectionType,\r
+  IN OUT UINTN                 *StartIndex,\r
+  IN UINTN                     Instance,\r
+  OUT EFI_FILE_SECTION_POINTER *Section\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Helper function to search a sequence of sections from the section pointed\r
+  by FirstSection to SearchEnd for the Instance-th section of type SectionType.\r
+  The current counter is saved in StartIndex and when the section is found, it's\r
+  saved in Section. GUID-defined sections, if special processing is not required,\r
+  are searched recursively in a depth-first manner.\r
+\r
+Arguments:\r
+\r
+  FirstSection The first section to start searching from.\r
+  SearchEnd    The end address to stop search.\r
+  SectionType  The type of section to search.\r
+  StartIndex   The current counter is saved.\r
+  Instance     The requested n-th section number.\r
+  Section      The found section returned.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS             The function completed successfully.\r
+  EFI_NOT_FOUND           The section is not found.\r
+--*/\r
+{\r
+  EFI_FILE_SECTION_POINTER  CurrentSection;\r
+  EFI_FILE_SECTION_POINTER  InnerSection;\r
+  EFI_STATUS                Status;\r
+  UINTN                     SectionSize;\r
+\r
+  CurrentSection = FirstSection;\r
+\r
+  while ((UINTN) CurrentSection.CommonHeader < (UINTN) SearchEnd) {\r
+    if (CurrentSection.CommonHeader->Type == SectionType) {\r
+      (*StartIndex)++;\r
+    }\r
+\r
+    if (*StartIndex == Instance) {\r
+      *Section = CurrentSection;\r
+      return EFI_SUCCESS;\r
+    }\r
+    //\r
+    // If the requesting section is not GUID-defined and\r
+    // we find a GUID-defined section that doesn't need\r
+    // special processing, go ahead to search the requesting\r
+    // section inside the GUID-defined section.\r
+    //\r
+    if (SectionType != EFI_SECTION_GUID_DEFINED &&\r
+        CurrentSection.CommonHeader->Type == EFI_SECTION_GUID_DEFINED &&\r
+        !(CurrentSection.GuidDefinedSection->Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED)) {\r
+      InnerSection.CommonHeader = (EFI_COMMON_SECTION_HEADER *)\r
+        ((UINTN) CurrentSection.CommonHeader + CurrentSection.GuidDefinedSection->DataOffset);\r
+      SectionSize = CurrentSection.CommonHeader->Size[0] +\r
+        (CurrentSection.CommonHeader->Size[1] << 8) + \r
+        (CurrentSection.CommonHeader->Size[2] << 16);\r
+      Status = SearchSectionByType (\r
+                 InnerSection,\r
+                 (UINT8 *) ((UINTN) CurrentSection.CommonHeader + SectionSize),\r
+                 SectionType,\r
+                 StartIndex,\r
+                 Instance,\r
+                 Section\r
+                 );\r
+      if (!EFI_ERROR (Status)) {\r
+        return EFI_SUCCESS;\r
+      }\r
+    }\r
+    //\r
+    // Find next section (including compensating for alignment issues.\r
+    //\r
+    CurrentSection.CommonHeader = (EFI_COMMON_SECTION_HEADER *) ((((UINTN) CurrentSection.CommonHeader) + GetLength (CurrentSection.CommonHeader->Size) + 0x03) & (-1 << 2));\r
+  }\r
+\r
+  return EFI_NOT_FOUND;\r
+}\r
+\r
 EFI_STATUS\r
 GetSectionByType (\r
   IN EFI_FFS_FILE_HEADER          *File,\r
@@ -403,7 +488,8 @@ Routine Description:
 \r
   Find a section in a file by type and instance.  An instance of 1 is the first \r
   instance.  The function will return NULL if a matching section cannot be found.\r
-  The function will not handle encapsulating sections.\r
+  GUID-defined sections, if special processing is not needed, are handled in a\r
+  depth-first manner.\r
 \r
 Arguments:\r
 \r
@@ -448,28 +534,24 @@ Returns:
   //\r
   CurrentSection.CommonHeader = (EFI_COMMON_SECTION_HEADER *) ((UINTN) File + sizeof (EFI_FFS_FILE_HEADER));\r
 \r
-  //\r
-  // Loop as long as we have a valid file\r
-  //\r
-  while ((UINTN) CurrentSection.CommonHeader < (UINTN) File + GetLength (File->Size)) {\r
-    if (CurrentSection.CommonHeader->Type == SectionType) {\r
-      SectionCount++;\r
-    }\r
+  Status = SearchSectionByType (\r
+             CurrentSection,\r
+             (UINT8 *) ((UINTN) File + GetLength (File->Size)),\r
+             SectionType,\r
+             &SectionCount,\r
+             Instance,\r
+             Section\r
+             );\r
 \r
-    if (SectionCount == Instance) {\r
-      *Section = CurrentSection;\r
-      return EFI_SUCCESS;\r
-    }\r
+  if (!EFI_ERROR (Status)) {\r
+    return EFI_SUCCESS;\r
+  } else {\r
     //\r
-    // Find next section (including compensating for alignment issues.\r
+    // Section not found\r
     //\r
-    CurrentSection.CommonHeader = (EFI_COMMON_SECTION_HEADER *) ((((UINTN) CurrentSection.CommonHeader) + GetLength (CurrentSection.CommonHeader->Size) + 0x03) & (-1 << 2));\r
+    (*Section).Code16Section = NULL;\r
+    return EFI_NOT_FOUND;\r
   }\r
-  //\r
-  // Section not found\r
-  //\r
-  (*Section).Code16Section = NULL;\r
-  return EFI_NOT_FOUND;\r
 }\r
 //\r
 // will not parse compressed sections\r
index 464d0e99309ee58df5c697dd590e78fb4ca54cb3..7e0f8fc2ae7b955cc51623e3784315f790674efd 100644 (file)
@@ -100,7 +100,7 @@ all: $(TARGET_LIB)
 "$(EDK_TOOLS_OUTPUT)\PeCoffLoaderEx.obj": "$(EDK_SOURCE)\Foundation\Library\Pei\PeiLib\$(PROCESSOR)\PeCoffLoaderEx.c"\r
   $(CC) $(C_FLAGS) "$(EDK_SOURCE)\Foundation\Library\Pei\PeiLib\$(PROCESSOR)\PeCoffLoaderEx.c" /Fo"$(EDK_TOOLS_OUTPUT)\PeCoffLoaderEx.obj"\r
 \r
-"$(EDK_TOOLS_OUTPUT)\FvLib.obj": "$(TARGET_SOURCE_DIR)\FvLib.c" "$(TARGET_SOURCE_DIR)\FvLib.h" $(EDK_SOURCE)\Sample\Include\Efi2WinNt.h $(EDK_SOURCE)\Foundation\Framework\Include\EfiFirmwareFileSystem.h "$(EDK_SOURCE)\Foundation\Framework\Include\EfiFirmwareVolumeHeader.h"\r
+"$(EDK_TOOLS_OUTPUT)\FvLib.obj": "$(TARGET_SOURCE_DIR)\FvLib.c" "$(TARGET_SOURCE_DIR)\FvLib.h" $(EDK_SOURCE)\Foundation\Framework\Include\EfiFirmwareFileSystem.h "$(EDK_SOURCE)\Foundation\Framework\Include\EfiFirmwareVolumeHeader.h"\r
   $(CC) $(C_FLAGS) "$(TARGET_SOURCE_DIR)\FvLib.c" /Fo"$(EDK_TOOLS_OUTPUT)\FvLib.obj"\r
 \r
 "$(EDK_TOOLS_OUTPUT)\EfiUtilityMsgs.obj": "$(TARGET_SOURCE_DIR)\EfiUtilityMsgs.c" "$(TARGET_SOURCE_DIR)\EfiUtilityMsgs.h"\r
@@ -125,11 +125,13 @@ $(TARGET_LIB): $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).lib
 !ELSE\r
 $(TARGET_LIB): $(OBJECTS)\r
   $(LIB_EXE) $(LIB_FLAGS) $(OBJECTS) /OUT:$(TARGET_LIB)\r
+!IF ("$(EFI_BINARY_BUILD)" == "YES")\r
   if not exist $(EFI_PLATFORM_BIN)\Tools mkdir $(EFI_PLATFORM_BIN)\Tools\r
   if exist $(TARGET_LIB) copy $(TARGET_LIB) $(EFI_PLATFORM_BIN)\tools\$(TARGET_NAME).lib /Y\r
   if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME)Obj.pdb \\r
   copy $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME)Obj.pdb $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME)Obj.pdb /Y\r
 !ENDIF\r
+!ENDIF\r
 \r
 clean:\r
   @if exist $(EDK_TOOLS_OUTPUT)\ParseInf.* del /q $(EDK_TOOLS_OUTPUT)\ParseInf.* > NUL\r
index 4e365145096a132b63ccd2d7e538fdc94073118d..590d0fd78f62df415d60d9b8ebe0d5938284e16a 100644 (file)
@@ -71,11 +71,13 @@ $(TARGET_LIB): $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).lib
 !ELSE\r
 $(TARGET_LIB): $(OBJECTS)\r
   $(LIB_EXE) $(LIB_FLAGS) $(OBJECTS) /OUT:$(TARGET_LIB)\r
+!IF ("$(EFI_BINARY_BUILD)" == "YES")\r
   if not exist $(EFI_PLATFORM_BIN)\Tools mkdir $(EFI_PLATFORM_BIN)\Tools\r
   if exist $(TARGET_LIB) copy $(TARGET_LIB) $(EFI_PLATFORM_BIN)\tools\$(TARGET_NAME).lib /Y\r
   if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME)Obj.pdb \\r
   copy $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME)Obj.pdb $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME)Obj.pdb /Y\r
 !ENDIF\r
+!ENDIF\r
 \r
 clean:\r
   @if exist $(EDK_TOOLS_OUTPUT)\CustomizedCompress.* del /q $(EDK_TOOLS_OUTPUT)\CustomizedCompress.* > NUL\r
index 3f034288e0136aa0b1d03b1ac537a4300a6bef84..5f86d50446facfd126750808df3abd5a77eac9fa 100644 (file)
@@ -79,11 +79,13 @@ $(TARGET_EXE): $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe
 !ELSE\r
 $(TARGET_EXE): $(EDK_TOOLS_OUTPUT)\EfiCompressMain.obj $(TARGET_EXE_LIBS)\r
   $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(EDK_TOOLS_OUTPUT)\EfiCompressMain.obj $(TARGET_EXE_LIBS)\r
+!IF ("$(EFI_BINARY_BUILD)" == "YES")\r
   if not exist $(EFI_PLATFORM_BIN)\Tools mkdir $(EFI_PLATFORM_BIN)\Tools\r
   if exist $(TARGET_EXE) copy $(TARGET_EXE) $(EFI_PLATFORM_BIN)\tools\$(TARGET_NAME).exe /Y\r
   if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb \\r
   copy $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb /Y\r
 !ENDIF\r
+!ENDIF\r
 \r
 clean:\r
   @if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME)Main.* del /q $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME)Main.* > NUL\r
index 06a858166995fe833d40e0fcb6babf8978d77f11..f5ab9ff234af3858e490081d9bc9f4c6e1bf0ac9 100644 (file)
@@ -41,11 +41,11 @@ Abstract:
 //\r
 // END include differences\r
 //\r
-#include "Pci22.h"  // for option ROM header structures\r
+#include "Pci.h"  // for option ROM header structures\r
 //\r
 // Version of this utility\r
 //\r
-#define UTILITY_VERSION "v2.5"\r
+#define UTILITY_VERSION "v2.6"\r
 \r
 //\r
 // Define some status return values\r
@@ -137,6 +137,15 @@ static STRING_LOOKUP  mSubsystemTypes[] = {
   0,\r
   NULL\r
 };\r
+\r
+static char* mCodeTypeStr[] = {\r
+  "PCAT Image",\r
+  "Open Firmware Image",\r
+  "HP PA RISC Image",\r
+  "EFI Image",\r
+  "Undefined"\r
+};\r
+\r
 //\r
 //  Function prototypes\r
 //\r
@@ -353,6 +362,45 @@ BailOut:
 \r
   return Status;\r
 }\r
+  \r
+UINT8\r
+CheckSum (\r
+  UINT8  *Buffer, \r
+  UINT32 DataSize,\r
+  UINT32 PaddingSize\r
+  )\r
+/*++\r
+Routine Description:\r
+  Calculate checksum from DataSize of Buffer.\r
+\r
+Arguments:\r
+  Buffer      - pointer to data buffer\r
+  DataSize    - size of data buffer in bytes\r
+\r
+Return:\r
+  UINT8       - checksum\r
+--*/\r
+{\r
+  UINT8 Checksum = 0;\r
+  while (DataSize-- != 0) {\r
+    Checksum = Checksum + Buffer[DataSize];\r
+  }\r
+  while (PaddingSize-- != 0) {\r
+    Checksum = Checksum + 0xff;\r
+  }\r
+  return Checksum;\r
+}\r
+\r
+char *\r
+GetCodeTypeStr (\r
+  UINT8     CodeType\r
+  )\r
+{\r
+  if (CodeType >= sizeof (mCodeTypeStr) / sizeof (*mCodeTypeStr)) {\r
+    CodeType = sizeof (mCodeTypeStr) / sizeof (*mCodeTypeStr) - 1;\r
+  }\r
+  return mCodeTypeStr[CodeType];\r
+}\r
 \r
 static\r
 int\r
@@ -382,11 +430,12 @@ Returns:
   FILE                      *InFptr;\r
   UINT32                    TotalSize;\r
   UINT32                    FileSize;\r
+  UINT32                    DataSize;\r
+  UINT32                    PaddingSize;\r
   UINT8                     *Buffer;\r
   UINT32                    Status;\r
   PCI_EXPANSION_ROM_HEADER  *RomHdr;\r
   PCI_DATA_STRUCTURE        *PciDs;\r
-  UINT32                    Index;\r
   UINT8                     ByteCheckSum;\r
 \r
   Status = STATUS_SUCCESS;\r
@@ -421,34 +470,14 @@ Returns:
     Status = STATUS_ERROR;\r
     goto BailOut;\r
   }\r
-  //\r
-  // Total size must be an even multiple of 512 bytes, and can't exceed\r
-  // the option ROM image size.\r
-  //\r
-  TotalSize = FileSize;\r
-  if (TotalSize & 0x1FF) {\r
-    TotalSize = (TotalSize + 0x200) &~0x1ff;\r
-  }\r
 \r
-  if (TotalSize > MAX_OPTION_ROM_SIZE) {\r
-    fprintf (\r
-      stdout,\r
-      "ERROR: Option ROM image %s size exceeds limit 0x%X bytes\n",\r
-      InFile->FileName,\r
-      MAX_OPTION_ROM_SIZE\r
-      );\r
-    Status = STATUS_ERROR;\r
-    goto BailOut;\r
-  }\r
-  //\r
-  // Return the size to the caller so they can keep track of the running total.\r
-  //\r
-  *Size = TotalSize;\r
+  \r
+  RomHdr = (PCI_EXPANSION_ROM_HEADER *) Buffer;\r
+  PciDs  = (PCI_DATA_STRUCTURE *) (Buffer + RomHdr->PcirOffset);\r
 \r
   //\r
   // Crude check to make sure it's a legitimate ROM image\r
   //\r
-  RomHdr = (PCI_EXPANSION_ROM_HEADER *) Buffer;\r
   if (RomHdr->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) {\r
     fprintf (stdout, "ERROR: ROM image file has invalid ROM signature\n");\r
     Status = STATUS_ERROR;\r
@@ -464,47 +493,76 @@ Returns:
     goto BailOut;\r
   }\r
 \r
-  PciDs = (PCI_DATA_STRUCTURE *) (Buffer + RomHdr->PcirOffset);\r
   if (PciDs->Signature != PCI_DATA_STRUCTURE_SIGNATURE) {\r
     fprintf (stdout, "ERROR: PCI data structure has invalid signature\n");\r
     Status = STATUS_ERROR;\r
     goto BailOut;\r
   }\r
+\r
+  if ((UINT32) (PciDs->ImageLength * 512) == FileSize) {\r
+    //\r
+    // ImageLength reflects the actual file size correctly.\r
+    //\r
+    DataSize    = FileSize - 1;\r
+    PaddingSize = 0;\r
+    TotalSize   = FileSize;\r
+  } else {\r
+    //\r
+    // ImageLength doesn't reflect the actual file size,\r
+    // 1). add additional 512 bytes if actual file size is multiple of 512\r
+    // 2). add additional X (X <= 512) bytes so that the result size is multiple of 512\r
+    //\r
+    fprintf (stdout, "WARNING: ImageLength in PCI data structure != Actual File Size\n"\r
+                     "         --> add additional padding bytes\n"\r
+                     "         --> adjust ImageLength\n"\r
+            );\r
+    TotalSize   = (FileSize + 0x200) & ~0x1ff;\r
+    DataSize    = FileSize;\r
+    PaddingSize = TotalSize - DataSize - 1;\r
+    PciDs->ImageLength = (UINT16) (TotalSize / 512);\r
+  }\r
+\r
+  //\r
+  // Check size\r
+  //\r
+  if (TotalSize > MAX_OPTION_ROM_SIZE) {\r
+    fprintf (\r
+      stdout,\r
+      "ERROR: Option ROM image %s size exceeds limit 0x%X bytes\n",\r
+      InFile->FileName,\r
+      MAX_OPTION_ROM_SIZE\r
+      );\r
+    Status = STATUS_ERROR;\r
+    goto BailOut;\r
+  }\r
+\r
+  //\r
+  // Return the size to the caller so they can keep track of the running total.\r
+  //\r
+  *Size = TotalSize;\r
+\r
   //\r
   // If this is the last image, then set the LAST bit unless requested not\r
   // to via the command-line -l argument. Otherwise, make sure you clear it.\r
   //\r
   if ((InFile->Next == NULL) && (mOptions.NoLast == 0)) {\r
-    PciDs->Indicator = INDICATOR_LAST;\r
+    PciDs->Indicator |= INDICATOR_LAST;\r
   } else {\r
-    PciDs->Indicator = 0;\r
+    PciDs->Indicator &= ~INDICATOR_LAST;\r
   }\r
 \r
-  ByteCheckSum = 0;\r
-  for (Index = 0; Index < FileSize - 1; Index++) {\r
-    ByteCheckSum = (UINT8) (ByteCheckSum + Buffer[Index]);\r
-  }\r
-\r
-  Buffer[FileSize - 1] = (UINT8) ((~ByteCheckSum) + 1);\r
-  fprintf (stdout, "CheckSUm = %02x\n", (UINT32) Buffer[FileSize - 1]);\r
+  ByteCheckSum = -CheckSum (Buffer, DataSize, PaddingSize);\r
 \r
-  //\r
-  // Now copy the input file contents out to the output file\r
-  //\r
-  if (fwrite (Buffer, FileSize, 1, OutFptr) != 1) {\r
+  if (fwrite (Buffer, DataSize, 1, OutFptr) != 1) {\r
     fprintf (stdout, "ERROR: Failed to write all file bytes to output file\n");\r
     Status = STATUS_ERROR;\r
     goto BailOut;\r
   }\r
 \r
-  TotalSize -= FileSize;\r
-  //\r
-  // Pad the rest of the image to make it a multiple of 512 bytes\r
-  //\r
-  while (TotalSize > 0) {\r
+  while (PaddingSize-- != 0) {\r
     putc (~0, OutFptr);\r
-    TotalSize--;\r
   }\r
+  putc (ByteCheckSum, OutFptr);\r
 \r
 BailOut:\r
   if (InFptr != NULL) {\r
@@ -665,9 +723,8 @@ Returns:
   //\r
   // Total size must be an even multiple of 512 bytes\r
   //\r
-  if (TotalSize & 0x1FF) {\r
-    TotalSize = (TotalSize + 0x200) &~0x1ff;\r
-  }\r
+  TotalSize = (TotalSize + 0x1ff) & ~0x1ff;\r
+\r
   //\r
   // Check size\r
   //\r
@@ -729,7 +786,7 @@ Returns:
   // to via the command-line -l argument.\r
   //\r
   if ((InFile->Next == NULL) && (mOptions.NoLast == 0)) {\r
-    PciDs.Indicator = INDICATOR_LAST;\r
+    PciDs.Indicator |= INDICATOR_LAST;\r
   }\r
   //\r
   // Write the ROM header to the output file\r
@@ -1068,7 +1125,7 @@ Returns:
         //\r
         // Specify binary files with -b\r
         //\r
-        FileFlags = (FileFlags &~FILE_FLAG_EFI) | FILE_FLAG_BINARY;\r
+        FileFlags = (FileFlags & ~FILE_FLAG_EFI) | FILE_FLAG_BINARY;\r
       } else if ((_stricmp (Argv[0], "-e") == 0) || (_stricmp (Argv[0], "-ec") == 0)) {\r
         //\r
         // Specify EFI files with -e. Specify EFI-compressed with -ec.\r
@@ -1280,7 +1337,7 @@ Returns:
     "                       the following FileName",\r
     "      -dump          - to dump the headers of an existing option ROM image",\r
     "",\r
-    "Example usage: EfiRom -v 0xABCD -d 0x1234 -b File1.bin File2.bin -e File1.efi File2.efi ",\r
+    "Example usage: EfiRom -v 0xABCD -d 0x1234 -b File1.bin File2.bin -e File1.efi File2.efi",\r
     "",\r
     NULL\r
   };\r
@@ -1315,8 +1372,9 @@ Returns:
   FILE                          *InFptr;\r
   UINT32                        ImageStart;\r
   UINT32                        ImageCount;\r
+  UINT16                        DeviceId;\r
   EFI_PCI_EXPANSION_ROM_HEADER  EfiRomHdr;\r
-  PCI_DATA_STRUCTURE            PciDs;\r
+  PCI_3_0_DATA_STRUCTURE        PciDs;\r
 \r
   //\r
   // Open the input file\r
@@ -1382,41 +1440,35 @@ Returns:
       );\r
     fprintf (stdout, "    Vendor ID              0x%04X\n", PciDs.VendorId);\r
     fprintf (stdout, "    Device ID              0x%04X\n", PciDs.DeviceId);\r
+    fprintf (stdout, "    Structure Length       0x%04X\n", PciDs.Length);\r
+    fprintf (stdout, "    PCI Revision           0x%02X\n", PciDs.Revision);\r
     fprintf (\r
       stdout,\r
       "    Class Code             0x%06X\n",\r
       (UINT32) (PciDs.ClassCode[0] | (PciDs.ClassCode[1] << 8) | (PciDs.ClassCode[2] << 16))\r
       );\r
     fprintf (stdout, "    Image size             0x%X\n", PciDs.ImageLength * 512);\r
-    fprintf (stdout, "    Code revision:         0x%04X\n", PciDs.CodeRevision);\r
+    fprintf (stdout, "    Code revision          0x%04X\n", PciDs.CodeRevision);\r
     fprintf (stdout, "    Indicator              0x%02X", (UINT32) PciDs.Indicator);\r
     //\r
     // Print the indicator, used to flag the last image\r
     //\r
-    if (PciDs.Indicator == INDICATOR_LAST) {\r
+    if ((PciDs.Indicator & INDICATOR_LAST) == INDICATOR_LAST) {\r
       fprintf (stdout, "   (last image)\n");\r
     } else {\r
       fprintf (stdout, "\n");\r
     }\r
+\r
     //\r
     // Print the code type. If EFI code, then we can provide more info.\r
     //\r
-    fprintf (stdout, "    Code type              0x%02X", (UINT32) PciDs.CodeType);\r
+    fprintf (stdout, "    Code type              0x%02X   (%s)\n", (UINT32) PciDs.CodeType, GetCodeTypeStr (PciDs.CodeType));\r
     if (PciDs.CodeType == PCI_CODE_TYPE_EFI_IMAGE) {\r
-      fprintf (stdout, "   (EFI image)\n");\r
       //\r
       // Re-read the header as an EFI ROM header, then dump more info\r
       //\r
       fprintf (stdout, "  EFI ROM header contents\n");\r
-      if (fseek (InFptr, ImageStart, SEEK_SET)) {\r
-        fprintf (stdout, "ERROR: Failed to re-seek to ROM header structure\n");\r
-        goto BailOut;\r
-      }\r
-\r
-      if (fread (&EfiRomHdr, sizeof (EfiRomHdr), 1, InFptr) != 1) {\r
-        fprintf (stdout, "ERROR: Failed to read EFI PCI ROM header from file\n");\r
-        goto BailOut;\r
-      }\r
+      memcpy (&EfiRomHdr, &PciRomHdr, sizeof (EfiRomHdr));\r
       //\r
       // Now dump more info\r
       //\r
@@ -1450,22 +1502,45 @@ Returns:
         (UINT32) EfiRomHdr.EfiImageHeaderOffset,\r
         (UINT32) (EfiRomHdr.EfiImageHeaderOffset + ImageStart)\r
         );\r
-\r
-    } else {\r
-      //\r
-      // Not an EFI image\r
-      //\r
-      fprintf (stdout, "\n");\r
     }\r
+\r
     //\r
-    // If code type is EFI image, then dump it as well?\r
+    // Dump additional information for PCI 3.0 OpROM\r
     //\r
-    // if (PciDs.CodeType == PCI_CODE_TYPE_EFI_IMAGE) {\r
-    // }\r
+    if (PciDs.Revision >= 3) {\r
+      fprintf (stdout, "  Extended for PCI 3.0\n");\r
+      \r
+      if (PciDs.DeviceListOffset != 0) {\r
+        if (fseek (InFptr, ImageStart + PciRomHdr.PcirOffset + PciDs.DeviceListOffset, SEEK_SET)) {\r
+          fprintf (stdout, "ERROR: Failed to seek to supported Device List\n");\r
+          goto BailOut;\r
+        }\r
+        fprintf (stdout, "    Device ID List         ");\r
+        while (TRUE) {\r
+          if (fread (&DeviceId, sizeof (DeviceId), 1, InFptr) != 1) {\r
+            fprintf (stdout, "ERROR: Failed to read supported DeviceId from DeviceId List\n");\r
+            goto BailOut;\r
+          }\r
+          if (DeviceId == 0) {\r
+            break;\r
+          }\r
+          fprintf (stdout, "0x%04X ", DeviceId);\r
+        }\r
+        fprintf (stdout, "\n");\r
+      }\r
+      fprintf (stdout, "    Max Runtime Image Length 0x%08X\n", PciDs.MaxRuntimeImageLength * 512);\r
+      if (PciDs.Length == sizeof (PCI_3_0_DATA_STRUCTURE)) {\r
+        fprintf (stdout, "    Config Utility Header  0x%04X\n", PciDs.ConfigUtilityCodeHeaderOffset);\r
+        fprintf (stdout, "    DMTF CLP Entry Point   0x%04X\n", PciDs.DMTFCLPEntryPointOffset);\r
+      } else {\r
+        fprintf (stdout, "WARNING: Oprom declars 3.0 revision with wrong structure length 0x%04X\n", PciDs.Length);\r
+      }\r
+    }\r
+\r
     //\r
     // If last image, then we're done\r
     //\r
-    if (PciDs.Indicator == INDICATOR_LAST) {\r
+    if ((PciDs.Indicator & INDICATOR_LAST) == INDICATOR_LAST) {\r
       goto BailOut;\r
     }\r
     //\r
@@ -1543,3 +1618,4 @@ Returns:
 \r
   return "unknown";\r
 }\r
+\r
index 2832154763958a84a46ded787b289a00cfdd03b8..39d39db868c4f5a7a3c781353dd5cf80c59ba929 100644 (file)
@@ -75,11 +75,13 @@ $(TARGET_EXE): $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe
 !ELSE\r
 $(TARGET_EXE): $(OBJECTS)\r
   $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(OBJECTS)\r
+!IF ("$(EFI_BINARY_BUILD)" == "YES")\r
   if not exist $(EFI_PLATFORM_BIN)\Tools mkdir $(EFI_PLATFORM_BIN)\Tools\r
   if exist $(TARGET_EXE) copy $(TARGET_EXE) $(EFI_PLATFORM_BIN)\tools\$(TARGET_NAME).exe /Y\r
   if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb \\r
   copy $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb /Y\r
 !ENDIF\r
+!ENDIF\r
 \r
 clean:\r
   @if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL\r
diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/EfildrImage/Makefile b/EdkCompatibilityPkg/Sample/Tools/Source/EfildrImage/Makefile
deleted file mode 100644 (file)
index 1556801..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-#/*++\r
-#  \r
-#  Copyright (c) 2006 - 2007, Intel Corporation                                                         \r
-#  All rights reserved. This program and the accompanying materials                          \r
-#  are licensed and made available under the terms and conditions of the BSD License         \r
-#  which accompanies this distribution.  The full text of the license may be found at        \r
-#  http://opensource.org/licenses/bsd-license.php                                            \r
-#                                                                                            \r
-#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
-#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
-#  \r
-#  Module Name:\r
-#  \r
-#    Makefile\r
-#  \r
-#  Abstract:\r
-#  \r
-#    makefile for building the EfildrImage utility.\r
-#    \r
-#--*/  \r
-\r
-#\r
-# Make sure environmental variable EDK_SOURCE is set\r
-#\r
-!IFNDEF EDK_SOURCE\r
-!ERROR EDK_SOURCE environmental variable not set \r
-!ENDIF\r
-\r
-#\r
-# Do this if you want to compile from this directory\r
-#\r
-!IFNDEF TOOLCHAIN\r
-TOOLCHAIN = TOOLCHAIN_MSVC\r
-!ENDIF\r
-\r
-!INCLUDE $(BUILD_DIR)\PlatformTools.env\r
-\r
-#\r
-# Define some macros we use here. Should get rid of them someday and \r
-# get rid of the extra level of indirection.\r
-#\r
-COMMON_SOURCE      = $(EDK_TOOLS_COMMON)\r
-\r
-#\r
-# Common information\r
-#\r
-\r
-INC=$(INC)\r
-\r
-#\r
-# Target specific information\r
-#\r
-\r
-TARGET_NAME=EfildrImage\r
-TARGET_SOURCE_DIR = $(EDK_TOOLS_SOURCE)\$(TARGET_NAME)\r
-\r
-TARGET_EXE = $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).exe\r
-\r
-TARGET_EXE_SOURCE = "$(TARGET_SOURCE_DIR)\EfildrImage.c"\r
-TARGET_EXE_INCLUDE = \r
-\r
-\r
-#\r
-# Build targets\r
-#\r
-\r
-all: $(TARGET_EXE)\r
-\r
-#\r
-# Build EXE\r
-#\r
-\r
-$(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj: $(TARGET_EXE_SOURCE) $(TARGET_EXE_INCLUDE)\r
-  $(CC) $(C_FLAGS) $(INC) $(TARGET_EXE_SOURCE) /Fo$(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj\r
-\r
-#\r
-# Add Binary Build description for this tool.\r
-#\r
-\r
-!IF (("$(EFI_BINARY_TOOLS)" == "YES") && EXIST($(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe))\r
-$(TARGET_EXE): $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe\r
-  copy $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe $(TARGET_EXE) /Y\r
-  if exist $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb \\r
-  copy $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb /Y\r
-!ELSE\r
-$(TARGET_EXE): $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj\r
-  $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) /out:$(TARGET_EXE) $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj\r
-  if not exist $(EFI_PLATFORM_BIN)\Tools mkdir $(EFI_PLATFORM_BIN)\Tools\r
-  if exist $(TARGET_EXE) copy $(TARGET_EXE) $(EFI_PLATFORM_BIN)\tools\$(TARGET_NAME).exe /Y\r
-  if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb \\r
-  copy $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb /Y\r
-!ENDIF\r
-\r
-clean:\r
-  @if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL\r
-\r
diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/EfildrImage/efildrimage.c b/EdkCompatibilityPkg/Sample/Tools/Source/EfildrImage/efildrimage.c
deleted file mode 100644 (file)
index c072dd7..0000000
+++ /dev/null
@@ -1,188 +0,0 @@
-/*++\r
-\r
-Copyright 2006 - 2007, Intel Corporation                                                         \r
-All rights reserved. This program and the accompanying materials                          \r
-are licensed and made available under the terms and conditions of the BSD License         \r
-which accompanies this distribution.  The full text of the license may be found at        \r
-http://opensource.org/licenses/bsd-license.php                                            \r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
-\r
-Module Name:\r
-\r
-  efildrimage.c\r
-\r
-Abstract:\r
-\r
-  Creates and EFILDR image.\r
-  This tool combines several PE Image files together using following format denoted as EBNF:\r
-  FILE := EFILDR_HEADER\r
-          EFILDR_IMAGE +\r
-          <PeImageFileContent> +\r
-  The order of EFILDR_IMAGE is same as the order of placing PeImageFileContent.\r
-\r
-Revision History\r
-\r
---*/\r
-\r
-\r
-#include <windows.h>\r
-#include <stdio.h>\r
-#include "Tiano.h"\r
-\r
-#define MAX_PE_IMAGES                  63\r
-#define FILE_TYPE_FIXED_LOADER         0\r
-#define FILE_TYPE_RELOCATABLE_PE_IMAGE 1\r
-\r
-typedef struct {\r
-  UINT32 CheckSum;\r
-  UINT32 Offset;\r
-  UINT32 Length;\r
-  UINT8  FileName[52];\r
-} EFILDR_IMAGE;\r
-\r
-typedef struct {          \r
-  UINT32       Signature;     \r
-  UINT32       HeaderCheckSum;\r
-  UINT32       FileLength;\r
-  UINT32       NumberOfImages;\r
-} EFILDR_HEADER;\r
-\r
-\r
-\r
-VOID\r
-Usage (\r
-  VOID\r
-  )\r
-{\r
-  printf ("Usage: EfiLdrImage OutImage LoaderImage PeImage1 PeImage2 ... PeImageN");\r
-  exit (1);\r
-}\r
-\r
-ULONG\r
-FCopyFile (\r
-  FILE    *in,\r
-  FILE    *out\r
-  )\r
-/*++\r
-Routine Description:\r
-  Write all the content of input file to output file.\r
-\r
-Arguments:\r
-  in  - input file pointer\r
-  out - output file pointer\r
-\r
-Return:\r
-  ULONG : file size of input file\r
---*/\r
-{\r
-  ULONG           filesize, offset, length;\r
-  UCHAR           Buffer[8*1024];\r
-\r
-  fseek (in, 0, SEEK_END);\r
-  filesize = ftell(in);\r
-\r
-  fseek (in, 0, SEEK_SET);\r
-\r
-  offset = 0;\r
-  while (offset < filesize)  {\r
-    length = sizeof(Buffer);\r
-    if (filesize-offset < length) {\r
-      length = filesize-offset;\r
-    }\r
-\r
-    fread (Buffer, length, 1, in);\r
-    fwrite (Buffer, length, 1, out);\r
-    offset += length;\r
-  }\r
-\r
-  return filesize;\r
-}\r
-\r
-\r
-int\r
-main (\r
-  int argc,\r
-  char *argv[]\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-\r
-Arguments:\r
-\r
-\r
-Returns:\r
-\r
-\r
---*/\r
-{\r
-  ULONG         i;\r
-  ULONG         filesize;\r
-  FILE          *fpIn, *fpOut;\r
-  EFILDR_HEADER EfiLdrHeader;\r
-  EFILDR_IMAGE  EfiLdrImage[MAX_PE_IMAGES];\r
-\r
-  if (argc < 4) {\r
-    Usage();\r
-  }\r
-\r
-  //\r
-  // Open output file for write\r
-  //\r
-  fpOut = fopen(argv[1], "w+b");\r
-  if (!fpOut) {\r
-    printf ("efildrimage: Could not open output file %s\n", argv[1]);\r
-    exit(1);\r
-  }\r
-\r
-  memset (&EfiLdrHeader, 0, sizeof (EfiLdrHeader));\r
-  memset (&EfiLdrImage, 0, sizeof (EFILDR_IMAGE) * (argc - 2));\r
-\r
-  memcpy (&EfiLdrHeader.Signature, "EFIL", 4);\r
-  EfiLdrHeader.FileLength = sizeof(EFILDR_HEADER) + sizeof(EFILDR_IMAGE)*(argc-2);\r
-\r
-  //\r
-  // Skip the file header first\r
-  //\r
-  fseek (fpOut, EfiLdrHeader.FileLength, SEEK_SET);\r
-\r
-  //\r
-  // copy all the input files to the output file\r
-  //\r
-  for(i=2;i<(ULONG)argc;i++) {\r
-    //\r
-    // Copy the content of PeImage file to output file\r
-    //\r
-    fpIn = fopen (argv[i], "rb");\r
-    if (!fpIn) {\r
-      printf ("efildrimage: Could not open input file %s\n", argv[i-2]);\r
-      exit(1);\r
-    }\r
-    filesize = FCopyFile (fpIn, fpOut);\r
-    fclose(fpIn);\r
-\r
-    //\r
-    //  And in the same time update the EfiLdrHeader and EfiLdrImage array\r
-    //\r
-    EfiLdrImage[i-2].Offset = EfiLdrHeader.FileLength;\r
-    EfiLdrImage[i-2].Length = filesize;\r
-    strncpy (EfiLdrImage[i-2].FileName, argv[i], sizeof (EfiLdrImage[i-2].FileName) - 1);\r
-    EfiLdrHeader.FileLength += filesize;\r
-    EfiLdrHeader.NumberOfImages++;\r
-  }\r
-\r
-  //\r
-  // Write the image header to the output file finally\r
-  //\r
-  fseek (fpOut, 0, SEEK_SET);\r
-  fwrite (&EfiLdrHeader, sizeof(EFILDR_HEADER)        , 1, fpOut);\r
-  fwrite (&EfiLdrImage , sizeof(EFILDR_IMAGE)*(argc-2), 1, fpOut);\r
-\r
-  fclose (fpOut);\r
-  printf ("Created %s\n", argv[1]);\r
-  return 0;\r
-}\r
-\r
index 216ac9782b572eda7ffe26c26d537b118aa37643..bc31b2329603f16a771474f7c28fc6fbaff49c85 100644 (file)
@@ -76,11 +76,13 @@ $(TARGET_EXE): $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe
 !ELSE\r
 $(TARGET_EXE) : $(OBJECTS)\r
   $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(OBJECTS)\r
+!IF ("$(EFI_BINARY_BUILD)" == "YES")\r
   if not exist $(EFI_PLATFORM_BIN)\Tools mkdir $(EFI_PLATFORM_BIN)\Tools\r
   if exist $(TARGET_EXE) copy $(TARGET_EXE) $(EFI_PLATFORM_BIN)\tools\$(TARGET_NAME).exe /Y\r
   if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb \\r
   copy $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb /Y\r
 !ENDIF\r
+!ENDIF\r
 \r
 clean:\r
   @if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL\r
index 887da4fc8e506f0a80c3fe09e9a5871ebf936b61..82365a4809d9e17c7ae1738e3ad4cbcffae6052b 100644 (file)
@@ -66,11 +66,13 @@ $(TARGET_EXE): $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe
 !ELSE\r
 $(TARGET_EXE): $(OBJECTS) $(LIBS)\r
   $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(OBJECTS)\r
+!IF ("$(EFI_BINARY_BUILD)" == "YES")\r
   if not exist $(EFI_PLATFORM_BIN)\Tools mkdir $(EFI_PLATFORM_BIN)\Tools\r
   if exist $(TARGET_EXE) copy $(TARGET_EXE) $(EFI_PLATFORM_BIN)\tools\$(TARGET_NAME).exe /Y\r
   if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb \\r
   copy $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb /Y\r
 !ENDIF\r
+!ENDIF\r
 \r
 clean:\r
   @if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME)Lib.* del /q $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME)Lib.* > NUL\r
diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/GenBootsector/GetDrvNumOffset.c b/EdkCompatibilityPkg/Sample/Tools/Source/GenBootsector/GetDrvNumOffset.c
deleted file mode 100644 (file)
index d16358b..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-#include "fat.h"\r
-#include <stdio.h>\r
-\r
-INTN\r
-GetDrvNumOffset (\r
-  IN VOID *BootSector\r
-  )\r
-{\r
-  FAT_BPB_STRUCT  *FatBpb;\r
-  UINTN           RootDirSectors;\r
-  UINTN           FATSz;\r
-  UINTN           TotSec;\r
-  UINTN           DataSec;\r
-  UINTN           CountOfClusters;\r
-\r
-  FatBpb  = (FAT_BPB_STRUCT *) BootSector;\r
-\r
-  //\r
-  // Check FAT type algorithm from FAT spec\r
-  //\r
-  RootDirSectors = ((FatBpb->Fat12_16.BPB_RootEntCnt * sizeof(FAT_DIRECTORY_ENTRY)) +\r
-                    (FatBpb->Fat12_16.BPB_BytsPerSec - 1)) / FatBpb->Fat12_16.BPB_BytsPerSec;\r
-\r
-  if (FatBpb->Fat12_16.BPB_FATSz16 != 0) {\r
-    FATSz = FatBpb->Fat12_16.BPB_FATSz16;\r
-  } else {\r
-    FATSz = FatBpb->Fat32.BPB_FATSz32;\r
-  }\r
-  if (FATSz == 0) {\r
-    fprintf (stderr, "ERROR: FAT: BPB_FATSz16, BPB_FATSz32 - 0, expected - Non-Zero\n");\r
-    return -1;\r
-  }\r
-\r
-  if (FatBpb->Fat12_16.BPB_TotSec16 != 0) {\r
-    TotSec = FatBpb->Fat12_16.BPB_TotSec16;\r
-  } else {\r
-    TotSec = FatBpb->Fat12_16.BPB_TotSec32;\r
-  }\r
-  if (TotSec == 0) {\r
-    fprintf (stderr, "ERROR: FAT: BPB_TotSec16, BPB_TotSec32 - 0, expected - Non-Zero\n");\r
-    return -1;\r
-  }\r
-\r
-  DataSec = TotSec - (\r
-                      FatBpb->Fat12_16.BPB_RsvdSecCnt +\r
-                      FatBpb->Fat12_16.BPB_NumFATs * FATSz +\r
-                      RootDirSectors\r
-                     );\r
-\r
-  CountOfClusters = DataSec / FatBpb->Fat12_16.BPB_SecPerClus;\r
-\r
-  if (CountOfClusters < FAT_MAX_FAT16_CLUSTER) {\r
-    return (INTN) ((UINTN) &FatBpb->Fat12_16.BS_DrvNum - (UINTN) FatBpb);\r
-  } else {\r
-    return (INTN) ((UINTN) &FatBpb->Fat32.BS_DrvNum - (UINTN) FatBpb);\r
-  }\r
-}\r
-\r
diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/GenBootsector/fat.h b/EdkCompatibilityPkg/Sample/Tools/Source/GenBootsector/fat.h
deleted file mode 100644 (file)
index 3303126..0000000
+++ /dev/null
@@ -1,158 +0,0 @@
-/*++\r
-\r
-Copyright 2006, Intel Corporation                                                         \r
-All rights reserved. This program and the accompanying materials                          \r
-are licensed and made available under the terms and conditions of the BSD License         \r
-which accompanies this distribution.  The full text of the license may be found at        \r
-http://opensource.org/licenses/bsd-license.php                                            \r
-                                                                                          \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
-\r
-Module Name:\r
-\r
-    fat.h\r
-    \r
-Abstract:\r
-\r
-Revision History\r
-\r
---*/\r
-\r
-#ifndef _FAT_BPB_H_\r
-#define _FAT_BPB_H_\r
-\r
-#include "Tiano.h"\r
-\r
-#pragma pack(1)\r
-\r
-typedef struct {\r
-  //\r
-  // Fat common field\r
-  //\r
-  UINT8              BS_jmpBoot[3];\r
-  CHAR8              BS_OEMName[8];\r
-  UINT16             BPB_BytsPerSec;\r
-  UINT8              BPB_SecPerClus;\r
-  UINT16             BPB_RsvdSecCnt;\r
-  UINT8              BPB_NumFATs;\r
-  UINT16             BPB_RootEntCnt;\r
-  UINT16             BPB_TotSec16;\r
-  UINT8              BPB_Media;\r
-  UINT16             BPB_FATSz16;\r
-  UINT16             BPB_SecPerTrk;\r
-  UINT16             BPB_NumHeads;\r
-  UINT32             BPB_HiddSec;\r
-  UINT32             BPB_TotSec32;\r
-\r
-  //\r
-  // Fat12/16 specific field\r
-  //\r
-  UINT8              BS_DrvNum;\r
-  UINT8              BS_Reserved1;\r
-  UINT8              BS_BootSig;\r
-  UINT32             BS_VolID;\r
-  CHAR8              BS_VolLab[11];\r
-  CHAR8              BS_FilSysType[8];\r
-\r
-  //\r
-  // Boot Code and Data\r
-  //\r
-  UINT8              Reserved[448];\r
-\r
-  //\r
-  // Fat common signature - 0xAA55\r
-  //\r
-  UINT16             Signature;\r
-} FAT12_16_BPB_STRUCT;\r
-\r
-typedef struct {\r
-  //\r
-  // Fat common field\r
-  //\r
-  UINT8              BS_jmpBoot[3];\r
-  CHAR8              BS_OEMName[8];\r
-  UINT16             BPB_BytsPerSec;\r
-  UINT8              BPB_SecPerClus;\r
-  UINT16             BPB_RsvdSecCnt;\r
-  UINT8              BPB_NumFATs;\r
-  UINT16             BPB_RootEntCnt;\r
-  UINT16             BPB_TotSec16;\r
-  UINT8              BPB_Media;\r
-  UINT16             BPB_FATSz16;\r
-  UINT16             BPB_SecPerTrk;\r
-  UINT16             BPB_NumHeads;\r
-  UINT32             BPB_HiddSec;\r
-  UINT32             BPB_TotSec32;\r
-\r
-  //\r
-  // Fat32 specific field\r
-  //\r
-  UINT32             BPB_FATSz32;\r
-  UINT16             BPB_ExtFlags;\r
-  UINT16             BPB_FSVer;\r
-  UINT32             BPB_RootClus;\r
-  UINT16             BPB_FSInfo;\r
-  UINT16             BPB_BkBootSec;\r
-  UINT8              BPB_Reserved[12];\r
-  UINT8              BS_DrvNum;\r
-  UINT8              BS_Reserved1;\r
-  UINT8              BS_BootSig;\r
-  UINT32             BS_VolID;\r
-  CHAR8              BS_VolLab[11];\r
-  CHAR8              BS_FilSysType[8];\r
-\r
-  //\r
-  // Boot Code and Data\r
-  //\r
-  UINT8              Reserved[420];\r
-\r
-  //\r
-  // Fat common signature - 0xAA55\r
-  //\r
-  UINT16             Signature;\r
-} FAT32_BPB_STRUCT;\r
-\r
-typedef union {\r
-  FAT12_16_BPB_STRUCT   Fat12_16;\r
-  FAT32_BPB_STRUCT      Fat32;\r
-} FAT_BPB_STRUCT;\r
-\r
-typedef enum {\r
-  FatTypeUnknown,\r
-  FatTypeFat12,\r
-  FatTypeFat16,\r
-  FatTypeFat32,\r
-  FatTypeMax\r
-} FAT_TYPE;\r
-\r
-typedef struct {\r
-  CHAR8              DIR_Name[11];\r
-  UINT8              DIR_Attr;\r
-  UINT8              DIR_NTRes;\r
-  UINT8              DIR_CrtTimeTenth;\r
-  UINT16             DIR_CrtTime;\r
-  UINT16             DIR_CrtDate;\r
-  UINT16             DIR_LstAccDate;\r
-  UINT16             DIR_FstClusHI;\r
-  UINT16             DIR_WrtTime;\r
-  UINT16             DIR_WrtDate;\r
-  UINT16             DIR_FstClusLO;\r
-  UINT32             DIR_FileSize;\r
-} FAT_DIRECTORY_ENTRY;\r
-\r
-#pragma pack()\r
-\r
-#define FAT_MAX_FAT12_CLUSTER         0xFF5\r
-#define FAT_MAX_FAT16_CLUSTER         0xFFF5\r
-\r
-#define FAT_BS_SIGNATURE      0xAA55\r
-#define FAT_BS_BOOTSIG        0x29\r
-#define FAT_BS_JMP1           0xEB\r
-#define FAT_BS_JMP2           0xE9\r
-#define FAT_FILSYSTYPE        "FAT     "\r
-#define FAT12_FILSYSTYPE      "FAT12   "\r
-#define FAT16_FILSYSTYPE      "FAT16   "\r
-#define FAT32_FILSYSTYPE      "FAT32   "\r
-\r
-#endif\r
diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/GenBootsector/genbootsector.c b/EdkCompatibilityPkg/Sample/Tools/Source/GenBootsector/genbootsector.c
deleted file mode 100644 (file)
index 8438502..0000000
+++ /dev/null
@@ -1,652 +0,0 @@
-/*++\r
-\r
-Copyright 2006 - 2007, Intel Corporation                                                         \r
-All rights reserved. This program and the accompanying materials                          \r
-are licensed and made available under the terms and conditions of the BSD License         \r
-which accompanies this distribution.  The full text of the license may be found at        \r
-http://opensource.org/licenses/bsd-license.php                                            \r
-                                                                                          \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
-\r
-Module Name:\r
-\r
-  genbootsector.c\r
-  \r
-Abstract:\r
-  Reading/writing MBR/DBR.\r
-  NOTE:\r
-    If we write MBR to disk, we just update the MBR code and the partition table wouldn't be over written.\r
-    If we process DBR, we will patch MBR to set first partition active if no active partition exists.\r
-\r
---*/\r
-\r
-#include <windows.h>\r
-#include <stdio.h>\r
-#include <string.h>\r
-\r
-#define MAX_DRIVE                             26\r
-#define PARTITION_TABLE_OFFSET                0x1BE\r
-\r
-#define SIZE_OF_PARTITION_ENTRY               0x10\r
-\r
-#define PARTITION_ENTRY_STARTLBA_OFFSET       8\r
-\r
-#define PARTITION_ENTRY_NUM                   4\r
-\r
-INT\r
-GetDrvNumOffset (\r
-  IN VOID *BootSector\r
-  );\r
-\r
-typedef enum {\r
-  PatchTypeUnknown,\r
-  PatchTypeFloppy,\r
-  PatchTypeIde,\r
-  PatchTypeUsb,\r
-} PATCH_TYPE;\r
-\r
-typedef enum {\r
-  ErrorSuccess,\r
-  ErrorFileCreate,\r
-  ErrorFileReadWrite,\r
-  ErrorNoMbr,\r
-  ErrorFatType\r
-} ERROR_STATUS;\r
-\r
-CHAR *ErrorStatusDesc[] = {\r
-  "Success",\r
-  "Failed to create files",\r
-  "Failed to read/write files",\r
-  "No MBR exists",\r
-  "Failed to detect Fat type"\r
-};\r
-\r
-typedef struct _DRIVE_TYPE_DESC {\r
-  UINT  Type;\r
-  CHAR  *Description;\r
-} DRIVE_TYPE_DESC;\r
-\r
-#define DRIVE_TYPE_ITEM(x) {x, #x}\r
-DRIVE_TYPE_DESC DriveTypeDesc[] = {\r
-  DRIVE_TYPE_ITEM (DRIVE_UNKNOWN),\r
-  DRIVE_TYPE_ITEM (DRIVE_NO_ROOT_DIR),\r
-  DRIVE_TYPE_ITEM (DRIVE_REMOVABLE),\r
-  DRIVE_TYPE_ITEM (DRIVE_FIXED),\r
-  DRIVE_TYPE_ITEM (DRIVE_REMOTE),\r
-  DRIVE_TYPE_ITEM (DRIVE_CDROM),\r
-  DRIVE_TYPE_ITEM (DRIVE_RAMDISK),\r
-  (UINT) -1, NULL\r
-};\r
-\r
-typedef struct _DRIVE_INFO {\r
-  CHAR              VolumeLetter;\r
-  DRIVE_TYPE_DESC   *DriveType;\r
-  UINT              DiskNumber;\r
-} DRIVE_INFO;\r
-\r
-#define BOOT_SECTOR_LBA_OFFSET 0x1FA\r
-\r
-#define IsLetter(x) (((x) >= 'a' && (x) <= 'z') || ((x) >= 'A' && (x) <= 'Z'))\r
-\r
-BOOL\r
-GetDriveInfo (\r
-  CHAR       VolumeLetter,\r
-  DRIVE_INFO *DriveInfo\r
-  )\r
-/*++\r
-Routine Description:\r
-  Get drive information including disk number and drive type,\r
-  where disknumber is useful for reading/writing disk raw data.\r
-  NOTE: Floppy disk doesn't have disk number but it doesn't matter because\r
-        we can reading/writing floppy disk without disk number.\r
-\r
-Arguments:\r
-  VolumeLetter : volume letter, e.g.: C for C:, A for A:\r
-  DriveInfo    : pointer to DRIVE_INFO structure receiving drive information.\r
-\r
-Return:\r
-  TRUE  : successful\r
-  FALSE : failed\r
---*/\r
-{\r
-  HANDLE                  VolumeHandle;\r
-  STORAGE_DEVICE_NUMBER   StorageDeviceNumber;\r
-  DWORD                   BytesReturned;\r
-  BOOL                    Success;\r
-  UINT                    DriveType;\r
-  UINT                    Index;\r
-\r
-  CHAR RootPath[]         = "X:\\";       // "X:\"  -> for GetDriveType\r
-  CHAR VolumeAccessPath[] = "\\\\.\\X:";  // "\\.\X:"  -> to open the volume\r
-\r
-  RootPath[0] = VolumeAccessPath[4] = VolumeLetter;\r
-  DriveType = GetDriveType(RootPath);\r
-  if (DriveType != DRIVE_REMOVABLE && DriveType != DRIVE_FIXED) {\r
-    return FALSE;\r
-  }\r
-\r
-  DriveInfo->VolumeLetter = VolumeLetter;\r
-  VolumeHandle = CreateFile (\r
-                   VolumeAccessPath,\r
-                   0,\r
-                   FILE_SHARE_READ | FILE_SHARE_WRITE,\r
-                   NULL,\r
-                   OPEN_EXISTING,\r
-                   0,\r
-                   NULL\r
-                   );\r
-  if (VolumeHandle == INVALID_HANDLE_VALUE) {\r
-    fprintf (\r
-      stderr, \r
-      "ERROR: CreateFile failed: Volume = %s, LastError = 0x%x\n", \r
-      VolumeAccessPath, \r
-      GetLastError ()\r
-      );\r
-    return FALSE;\r
-  }\r
-\r
-  //\r
-  // Get Disk Number. It should fail when operating on floppy. That's ok \r
-  //  because Disk Number is only needed when operating on Hard or USB disk.\r
-  //\r
-  // To direct write to disk:\r
-  //   for USB and HD: use path = \\.\PHYSICALDRIVEx, where x is Disk Number\r
-  //   for floppy:     use path = \\.\X:, where X can be A or B\r
-  //\r
-  Success = DeviceIoControl(\r
-              VolumeHandle, \r
-              IOCTL_STORAGE_GET_DEVICE_NUMBER,\r
-              NULL, \r
-              0, \r
-              &StorageDeviceNumber, \r
-              sizeof(StorageDeviceNumber),\r
-              &BytesReturned, \r
-              NULL\r
-              );\r
-  //\r
-  // DeviceIoControl should fail if Volume is floppy or network drive.\r
-  //\r
-  if (!Success) {\r
-    DriveInfo->DiskNumber = (UINT) -1;\r
-  } else if (StorageDeviceNumber.DeviceType != FILE_DEVICE_DISK) {\r
-    //\r
-    // Only care about the disk.\r
-    //\r
-    return FALSE;\r
-  } else{\r
-    DriveInfo->DiskNumber = StorageDeviceNumber.DeviceNumber;\r
-  }\r
-  CloseHandle(VolumeHandle);\r
-  \r
-  //\r
-  // Fill in the type string\r
-  //\r
-  DriveInfo->DriveType = NULL;\r
-  for (Index = 0; DriveTypeDesc[Index].Description != NULL; Index ++) {\r
-    if (DriveType == DriveTypeDesc[Index].Type) {\r
-      DriveInfo->DriveType = &DriveTypeDesc[Index];\r
-      break;\r
-    }\r
-  }\r
-\r
-  if (DriveInfo->DriveType == NULL) {\r
-    //\r
-    // Should have a type.\r
-    //\r
-    fprintf (stderr, "ERROR: fetal error!!!\n");\r
-    return FALSE;\r
-  }\r
-  return TRUE;\r
-}\r
-\r
-VOID\r
-ListDrive (\r
-  VOID\r
-  )\r
-/*++\r
-Routine Description:\r
-  List every drive in current system and their information.\r
-\r
---*/\r
-{\r
-  UINT       Index;\r
-  DRIVE_INFO DriveInfo;\r
-  \r
-  UINT Mask =  GetLogicalDrives();\r
-\r
-  for (Index = 0; Index < MAX_DRIVE; Index++) {\r
-    if (((Mask >> Index) & 0x1) == 1) {\r
-      if (GetDriveInfo ('A' + (CHAR) Index, &DriveInfo)) {\r
-        if (Index < 2) {\r
-          // Floppy will occupy 'A' and 'B'\r
-          fprintf (\r
-            stdout,\r
-            "%c: - Type: %s\n",\r
-            DriveInfo.VolumeLetter,\r
-            DriveInfo.DriveType->Description\r
-            );\r
-        }\r
-        else {\r
-          fprintf (\r
-            stdout,\r
-            "%c: - DiskNum: %d, Type: %s\n", \r
-            DriveInfo.VolumeLetter,\r
-            DriveInfo.DiskNumber, \r
-            DriveInfo.DriveType->Description\r
-            );\r
-        }\r
-      }\r
-    }\r
-  }\r
-\r
-}\r
-\r
-INT\r
-GetBootSectorOffset (\r
-  HANDLE     DiskHandle,\r
-  BOOL       WriteToDisk,\r
-  PATCH_TYPE PatchType\r
-  )\r
-/*++\r
-Description:\r
-  Get the offset of boot sector.\r
-  For non-MBR disk, offset is just 0\r
-  for disk with MBR, offset needs to be caculated by parsing MBR\r
-\r
-  NOTE: if no one is active, we will patch MBR to select first partition as active.\r
-\r
-Arguments:\r
-  DiskHandle  : HANDLE of disk\r
-  WriteToDisk : TRUE indicates writing\r
-  PatchType   : PatchTypeFloppy, PatchTypeIde, PatchTypeUsb\r
-\r
-Return:\r
-  -1   : failed\r
-  o.w. : Offset to boot sector\r
---*/\r
-{\r
-  BYTE    DiskPartition[0x200];\r
-  DWORD   BytesReturn;\r
-  DWORD   DbrOffset;\r
-  DWORD   Index;\r
-  BOOL    HasMbr;\r
-\r
-  DbrOffset = 0;\r
-  HasMbr    = FALSE;\r
-  \r
-  SetFilePointer(DiskHandle, 0, NULL, FILE_BEGIN);\r
-  if (!ReadFile (DiskHandle, DiskPartition, 0x200, &BytesReturn, NULL)) {\r
-    return -1;\r
-  }\r
-\r
-  //\r
-  // Check Signature, Jmp, and Boot Indicator.\r
-  // if all pass, we assume MBR found.\r
-  //\r
-\r
-  // Check Signature: 55AA\r
-  if ((DiskPartition[0x1FE] == 0x55) && (DiskPartition[0x1FF] == 0xAA)) {\r
-    // Check Jmp: (EB ?? 90) or (E9 ?? ??)\r
-    if (((DiskPartition[0] != 0xEB) || (DiskPartition[2] != 0x90)) &&\r
-        (DiskPartition[0] != 0xE9)) {\r
-      // Check Boot Indicator: 0x00 or 0x80\r
-      // Boot Indicator is the first byte of Partition Entry\r
-      HasMbr = TRUE;\r
-      for (Index = 0; Index < PARTITION_ENTRY_NUM; ++Index) {\r
-        if ((DiskPartition[PARTITION_TABLE_OFFSET + Index * SIZE_OF_PARTITION_ENTRY] & 0x7F) != 0) {\r
-          HasMbr = FALSE;\r
-          break;\r
-        }\r
-      }\r
-    }\r
-  }\r
-\r
-  if (HasMbr) {\r
-    //\r
-    // Skip MBR\r
-    //\r
-    for (Index = 0; Index < PARTITION_ENTRY_NUM; Index++) {\r
-      //\r
-      // Found Boot Indicator.\r
-      //\r
-      if (DiskPartition[PARTITION_TABLE_OFFSET + (Index * SIZE_OF_PARTITION_ENTRY)] == 0x80) {\r
-        DbrOffset = *(DWORD *)&DiskPartition[PARTITION_TABLE_OFFSET + (Index * SIZE_OF_PARTITION_ENTRY) + PARTITION_ENTRY_STARTLBA_OFFSET];\r
-        break;\r
-      }\r
-    }\r
-    //\r
-    // If no boot indicator, we manually select 1st partition, and patch MBR.\r
-    //\r
-    if (Index == PARTITION_ENTRY_NUM) {\r
-      DbrOffset = *(DWORD *)&DiskPartition[PARTITION_TABLE_OFFSET + PARTITION_ENTRY_STARTLBA_OFFSET];\r
-      if (WriteToDisk && (PatchType == PatchTypeUsb)) {\r
-        SetFilePointer(DiskHandle, 0, NULL, FILE_BEGIN);\r
-        DiskPartition[PARTITION_TABLE_OFFSET] = 0x80;\r
-        WriteFile (DiskHandle, DiskPartition, 0x200, &BytesReturn, NULL);\r
-      }\r
-    }\r
-  }\r
-\r
-  return DbrOffset;\r
-}\r
-\r
-ERROR_STATUS\r
-ProcessBsOrMbr (\r
-  CHAR        *DiskName,\r
-  CHAR        *FileName,\r
-  BOOL        WriteToDisk,\r
-  PATCH_TYPE  PatchType,\r
-  BOOL        ProcessMbr\r
-  )\r
-/*++\r
-Routine Description:\r
-  Writing or reading boot sector or MBR according to the argument.\r
-\r
-Arguments:\r
-  DiskName    : Win32 API recognized string name of disk\r
-  FileName    : file name\r
-  WriteToDisk : TRUE is to write content of file to disk, otherwise, reading content of disk to file\r
-  PatchType   : PatchTypeFloppy, PatchTypeIde, PatchTypeUsb\r
-  ProcessMbr  : TRUE is to process MBR, otherwise, processing boot sector\r
-\r
-Return:\r
-  ErrorSuccess\r
-  ErrorFileCreate\r
-  ErrorFileReadWrite\r
-  ErrorNoMbr\r
-  ErrorFatType\r
---*/\r
-{\r
-  BYTE    DiskPartition[0x200];\r
-  BYTE    DiskPartitionBackup[0x200];\r
-  HANDLE  DiskHandle;\r
-  HANDLE  FileHandle;\r
-  DWORD   BytesReturn;\r
-  DWORD   DbrOffset;\r
-  INT     DrvNumOffset;\r
-\r
-  DiskHandle = CreateFile (\r
-                 DiskName, \r
-                 GENERIC_READ | GENERIC_WRITE, \r
-                 FILE_SHARE_READ, \r
-                 NULL, \r
-                 OPEN_EXISTING, \r
-                 FILE_ATTRIBUTE_NORMAL, \r
-                 NULL\r
-                 );\r
-  if (DiskHandle == INVALID_HANDLE_VALUE) {\r
-    return ErrorFileCreate;\r
-  }\r
-\r
-  FileHandle = CreateFile (\r
-                 FileName,\r
-                 GENERIC_READ | GENERIC_WRITE,\r
-                 0,\r
-                 NULL,\r
-                 OPEN_ALWAYS,\r
-                 FILE_ATTRIBUTE_NORMAL,\r
-                 NULL\r
-                 );\r
-  if (FileHandle == INVALID_HANDLE_VALUE) {\r
-    return ErrorFileCreate;\r
-  }\r
-\r
-  DbrOffset = 0;\r
-  //\r
-  // Skip potential MBR for Ide & USB disk\r
-  //\r
-  if ((PatchType == PatchTypeIde) || (PatchType == PatchTypeUsb)) {\r
-    //\r
-    // Even user just wants to process MBR, we get offset of boot sector here to validate the disk\r
-    //  if disk have MBR, DbrOffset should be greater than 0\r
-    //\r
-    DbrOffset = GetBootSectorOffset (DiskHandle, WriteToDisk, PatchType);\r
-\r
-    if (!ProcessMbr) {\r
-      //\r
-      // 1. Process boot sector, set file pointer to the beginning of boot sector\r
-      //\r
-      SetFilePointer (DiskHandle, DbrOffset * 0x200, NULL, FILE_BEGIN);\r
-    } else if(DbrOffset == 0) {\r
-      //\r
-      // If user want to process Mbr, but no Mbr exists, simply return FALSE\r
-      //\r
-      return ErrorNoMbr;\r
-    } else {\r
-      //\r
-      // 2. Process MBR, set file pointer to 0\r
-      //\r
-      SetFilePointer (DiskHandle, 0, NULL, FILE_BEGIN);\r
-    }\r
-  }\r
-\r
-  //\r
-  // [File Pointer is pointed to beginning of Mbr or Dbr]\r
-  //\r
-  if (WriteToDisk) {\r
-    //\r
-    // Write\r
-    //\r
-    if (!ReadFile (FileHandle, DiskPartition, 0x200, &BytesReturn, NULL)) {\r
-      return ErrorFileReadWrite;\r
-    }\r
-    if (ProcessMbr) {\r
-      //\r
-      // Use original partition table\r
-      //\r
-      if (!ReadFile (DiskHandle, DiskPartitionBackup, 0x200, &BytesReturn, NULL)) {\r
-        return ErrorFileReadWrite;\r
-      }\r
-      memcpy (DiskPartition + 0x1BE, DiskPartitionBackup + 0x1BE, 0x40);\r
-      SetFilePointer (DiskHandle, 0, NULL, FILE_BEGIN);\r
-    }\r
-\r
-    if (!WriteFile (DiskHandle, DiskPartition, 0x200, &BytesReturn, NULL)) {\r
-      return ErrorFileReadWrite;\r
-    }\r
-\r
-  } else {\r
-    //\r
-    // Read\r
-    //\r
-    if (!ReadFile (DiskHandle, DiskPartition, 0x200, &BytesReturn, NULL)) {\r
-      return ErrorFileReadWrite;\r
-    }\r
-\r
-    if (PatchType == PatchTypeUsb) {\r
-      // Manually set BS_DrvNum to 0x80 as window's format.exe has a bug which will clear this field discarding USB disk's MBR. \r
-      // offset of BS_DrvNum is 0x24 for FAT12/16\r
-      //                        0x40 for FAT32\r
-      //\r
-      DrvNumOffset = GetDrvNumOffset (DiskPartition);\r
-      if (DrvNumOffset == -1) {\r
-        return ErrorFatType;\r
-      }\r
-      //\r
-      // Some legacy BIOS require 0x80 discarding MBR.\r
-      // Question left here: is it needed to check Mbr before set 0x80?\r
-      //\r
-      DiskPartition[DrvNumOffset] = ((DbrOffset > 0) ? 0x80 : 0);\r
-  }\r
-\r
-\r
-    if (PatchType == PatchTypeIde) {\r
-      //\r
-      // Patch LBAOffsetForBootSector\r
-      //\r
-      *(DWORD *)&DiskPartition [BOOT_SECTOR_LBA_OFFSET] = DbrOffset;\r
-    }\r
-    if (!WriteFile (FileHandle, DiskPartition, 0x200, &BytesReturn, NULL)) {\r
-      return ErrorFileReadWrite;\r
-    }\r
-  }\r
-  CloseHandle (FileHandle);\r
-  CloseHandle (DiskHandle);\r
-  return ErrorSuccess;\r
-}\r
-\r
-VOID\r
-PrintUsage (\r
-  CHAR* AppName\r
-  )\r
-{\r
-  fprintf (\r
-    stdout,\r
-    "Usage: %s [OPTIONS]...\n"\r
-    "Copy file content from/to bootsector.\n"\r
-    "\n"\r
-    "  -l        list disks\n"\r
-    "  -if=FILE  specified an input, can be files or disks\n"\r
-    "  -of=FILE  specified an output, can be files or disks\n"\r
-    "  -mbr      process MBR also\n"\r
-    "  -h        print this message\n"\r
-    "\n"\r
-    "FILE providing a volume plus a colon (X:), indicates a disk\n"\r
-    "FILE providing other format, indicates a file\n",\r
-    AppName\r
-    );\r
-}\r
\r
-INT\r
-main (\r
-  INT  argc,\r
-  CHAR *argv[]\r
-  )\r
-{\r
-  CHAR          *AppName;\r
-  INT           Index;\r
-  BOOL          ProcessMbr;\r
-  CHAR          VolumeLetter;\r
-  CHAR          *FilePath;\r
-  BOOL          WriteToDisk;\r
-  DRIVE_INFO    DriveInfo;\r
-  PATCH_TYPE    PatchType;\r
-  ERROR_STATUS  Status;\r
-\r
-  CHAR        FloppyPathTemplate[] = "\\\\.\\%c:";\r
-  CHAR        DiskPathTemplate[]   = "\\\\.\\PHYSICALDRIVE%u";\r
-  CHAR        DiskPath[MAX_PATH];\r
-\r
-  AppName = *argv;\r
-  argv ++;\r
-  argc --;\r
-  \r
-  ProcessMbr    = FALSE;\r
-  WriteToDisk   = TRUE;\r
-  FilePath      = NULL;\r
-  VolumeLetter  = 0;\r
-\r
-  //\r
-  // Parse command line\r
-  //\r
-  for (Index = 0; Index < argc; Index ++) {\r
-    if (_stricmp (argv[Index], "-l") == 0) {\r
-      ListDrive ();\r
-      return 0;\r
-    }\r
-    else if (_stricmp (argv[Index], "-mbr") == 0) {\r
-      ProcessMbr = TRUE;\r
-    }\r
-    else if ((_strnicmp (argv[Index], "-if=", 4) == 0) ||\r
-             (_strnicmp (argv[Index], "-of=", 4) == 0)\r
-             ) {\r
-      if (argv[Index][6] == '\0' && argv[Index][5] == ':' && IsLetter (argv[Index][4])) {\r
-        VolumeLetter = argv[Index][4];\r
-        if (_strnicmp (argv[Index], "-if=", 4) == 0) {\r
-          WriteToDisk = FALSE;\r
-        }\r
-      }\r
-      else {\r
-        FilePath = &argv[Index][4];\r
-      }\r
-    }\r
-    else {\r
-      PrintUsage (AppName);\r
-      return 1;\r
-    }\r
-  }\r
-\r
-  //\r
-  // Check parameter\r
-  //\r
-  if (VolumeLetter == 0) {\r
-    fprintf (stderr, "ERROR: Volume isn't provided!\n");\r
-    PrintUsage (AppName);\r
-    return 1;\r
-  }\r
-  \r
-  if (FilePath == NULL) {\r
-    fprintf (stderr, "ERROR: File isn't pvovided!\n");\r
-    PrintUsage (AppName);\r
-    return 1;\r
-  }\r
-    \r
-  PatchType = PatchTypeUnknown;\r
-\r
-  if ((VolumeLetter == 'A') || (VolumeLetter == 'a') || \r
-      (VolumeLetter == 'B') || (VolumeLetter == 'b') \r
-      ) {\r
-    //\r
-    // Floppy\r
-    //\r
-    sprintf (DiskPath, FloppyPathTemplate, VolumeLetter);\r
-    PatchType = PatchTypeFloppy;\r
-  }\r
-  else {\r
-    //\r
-    // Hard/USB disk\r
-    //\r
-    if (!GetDriveInfo (VolumeLetter, &DriveInfo)) {\r
-      fprintf (stderr, "ERROR: GetDriveInfo - 0x%x\n", GetLastError ());\r
-      return 1;\r
-    }\r
-\r
-    //\r
-    // Shouldn't patch my own hard disk, but can read it.\r
-    // very safe then:)\r
-    //\r
-    if (DriveInfo.DriveType->Type == DRIVE_FIXED && WriteToDisk) {\r
-      fprintf (stderr, "ERROR: Write to local harddisk - permission denied!\n");\r
-      return 1;\r
-    }\r
-    \r
-    sprintf (DiskPath, DiskPathTemplate, DriveInfo.DiskNumber);\r
-    if (DriveInfo.DriveType->Type == DRIVE_REMOVABLE) {\r
-      PatchType = PatchTypeUsb;\r
-    }\r
-    else if (DriveInfo.DriveType->Type == DRIVE_FIXED) {\r
-      PatchType = PatchTypeIde;\r
-    }\r
-  }\r
-\r
-  if (PatchType == PatchTypeUnknown) {\r
-    fprintf (stderr, "ERROR: PatchType unknown!\n");\r
-    return 1;\r
-  }\r
-\r
-  //\r
-  // Process DBR (Patch or Read)\r
-  //\r
-  Status = ProcessBsOrMbr (DiskPath, FilePath, WriteToDisk, PatchType, ProcessMbr);\r
-  if (Status == ErrorSuccess) {\r
-    fprintf (\r
-      stdout, \r
-      "%s %s: successfully!\n", \r
-      WriteToDisk ? "Write" : "Read", \r
-      ProcessMbr ? "MBR" : "DBR"\r
-      );\r
-    return 0;\r
-  } else {\r
-    fprintf (\r
-      stderr, \r
-      "%s: %s %s: failed - %s (LastError: 0x%x)!\n",\r
-      (Status == ErrorNoMbr) ? "WARNING" : "ERROR",\r
-      WriteToDisk ? "Write" : "Read", \r
-      ProcessMbr ? "MBR" : "DBR", \r
-      ErrorStatusDesc[Status],\r
-      GetLastError ()\r
-      );\r
-    return 1;\r
-  }\r
-}\r
diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/GenBootsector/makefile b/EdkCompatibilityPkg/Sample/Tools/Source/GenBootsector/makefile
deleted file mode 100644 (file)
index 359f126..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-#/*++\r
-#  \r
-#  Copyright (c) 2006 - 2007, Intel Corporation                                                         \r
-#  All rights reserved. This program and the accompanying materials                          \r
-#  are licensed and made available under the terms and conditions of the BSD License         \r
-#  which accompanies this distribution.  The full text of the license may be found at        \r
-#  http://opensource.org/licenses/bsd-license.php                                            \r
-#                                                                                            \r
-#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
-#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
-#  \r
-#  Module Name:\r
-#  \r
-#    Makefile\r
-#  \r
-#  Abstract:\r
-#  \r
-#    makefile for building the GenBootsector utility.\r
-#    \r
-#--*/  \r
-\r
-#\r
-# Make sure environmental variable EDK_SOURCE is set\r
-#\r
-!IFNDEF EDK_SOURCE\r
-!ERROR EDK_SOURCE environmental variable not set \r
-!ENDIF\r
-\r
-#\r
-# Do this if you want to compile from this directory\r
-#\r
-!IFNDEF TOOLCHAIN\r
-TOOLCHAIN = TOOLCHAIN_MSVC\r
-!ENDIF\r
-\r
-!INCLUDE $(BUILD_DIR)\PlatformTools.env\r
-\r
-#\r
-# Define some macros we use here. Should get rid of them someday and \r
-# get rid of the extra level of indirection.\r
-#\r
-COMMON_SOURCE      = $(EDK_TOOLS_COMMON)\r
-\r
-#\r
-# Common information\r
-#\r
-\r
-INC=$(INC)\r
-\r
-#\r
-# Target specific information\r
-#\r
-\r
-TARGET_NAME=GenBootsector\r
-TARGET_SOURCE_DIR = $(EDK_TOOLS_SOURCE)\$(TARGET_NAME)\r
-\r
-TARGET_EXE = $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).exe\r
-\r
-TARGET_EXE_SOURCE = "$(TARGET_SOURCE_DIR)\GenBootsector.c"\r
-TARGET_EXE_INCLUDE = \r
-\r
-\r
-#\r
-# Build targets\r
-#\r
-\r
-all: $(TARGET_EXE)\r
-\r
-#\r
-# Build EXE\r
-#\r
-$(EDK_TOOLS_OUTPUT)\GetDrvNumOffset.obj: $(TARGET_SOURCE_DIR)\GenBootsector.c $(TARGET_SOURCE_DIR)\fat.h\r
-  $(CC) $(C_FLAGS) $(INC) $(TARGET_SOURCE_DIR)\GetDrvNumOffset.c /Fo$(EDK_TOOLS_OUTPUT)\GetDrvNumOffset.obj\r
-\r
-$(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj: $(TARGET_EXE_SOURCE) $(TARGET_EXE_INCLUDE)\r
-  $(CC) $(C_FLAGS) $(INC) $(TARGET_EXE_SOURCE) /Fo$(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj\r
-\r
-#\r
-# Add Binary Build description for this tool.\r
-#\r
-\r
-!IF (("$(EFI_BINARY_TOOLS)" == "YES") && EXIST($(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe))\r
-$(TARGET_EXE): $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe\r
-  copy $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe $(TARGET_EXE) /Y\r
-  if exist $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb \\r
-  copy $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb /Y\r
-!ELSE\r
-$(TARGET_EXE): $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj $(EDK_TOOLS_OUTPUT)\GetDrvNumOffset.obj\r
-  $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) user32.lib advapi32.lib /out:$(TARGET_EXE) $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj $(EDK_TOOLS_OUTPUT)\GetDrvNumOffset.obj\r
-  if not exist $(EFI_PLATFORM_BIN)\Tools mkdir $(EFI_PLATFORM_BIN)\Tools\r
-  if exist $(TARGET_EXE) copy $(TARGET_EXE) $(EFI_PLATFORM_BIN)\tools\$(TARGET_NAME).exe /Y\r
-  if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb \\r
-  copy $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb /Y\r
-!ENDIF\r
-\r
-clean:\r
-  @if exist $(EDK_TOOLS_OUTPUT)\GetDrvNumOffset.* del $(EDK_TOOLS_OUTPUT)\GetDrvNumOffset.* > NUL\r
-  @if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL\r
-\r
index f6c07f734067d1418a1b94fee0c7a83081f5dd9d..cb4bc3c4084df03638cea5d4dc901d1a7457686f 100644 (file)
@@ -75,11 +75,13 @@ $(TARGET_EXE): $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe
 !ELSE\r
 $(TARGET_EXE): $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj $(TARGET_EXE_LIBS) $(TARGET_DLL)\r
   $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj $(TARGET_LIB)  $(TARGET_EXE_LIBS)\r
+!IF ("$(EFI_BINARY_BUILD)" == "YES")\r
   if not exist $(EFI_PLATFORM_BIN)\Tools mkdir $(EFI_PLATFORM_BIN)\Tools\r
   if exist $(TARGET_EXE) copy $(TARGET_EXE) $(EFI_PLATFORM_BIN)\tools\$(TARGET_NAME).exe /Y\r
   if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb \\r
   copy $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb /Y\r
 !ENDIF\r
+!ENDIF\r
 \r
 clean:\r
   @if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL\r
index cebcc01f9b783874208f21f252c58433b18b93e6..59a8f384b364c5e24912fefa7045f3a37ad68212 100644 (file)
@@ -841,12 +841,12 @@ Returns:
   //\r
   //  Output the calling arguments\r
   //\r
-  printf ("\n\n");\r
-  for (Index = 0; Index < argc; Index++) {\r
-    printf ("%s ", argv[Index]);\r
-  }\r
-\r
-  printf ("\n\n");\r
+  //printf ("\n\n");\r
+  //for (Index = 0; Index < argc; Index++) {\r
+  //  printf ("%s ", argv[Index]);\r
+  //}\r
+  //\r
+  //printf ("\n\n");\r
 \r
   if (argc < 5) {\r
     printf ("Not enough arguments\n");\r
index 4faceb18021fd92aa7ead52bcba710c314055547..504935305e775ef3709436a16ffc542161e5aa56 100644 (file)
@@ -80,11 +80,13 @@ $(TARGET_EXE): $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe
 !ELSE\r
 $(TARGET_EXE): $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj $(TARGET_LIB)\r
   $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj $(TARGET_LIB)\r
+!IF ("$(EFI_BINARY_BUILD)" == "YES")\r
   if not exist $(EFI_PLATFORM_BIN)\Tools mkdir $(EFI_PLATFORM_BIN)\Tools\r
   if exist $(TARGET_EXE) copy $(TARGET_EXE) $(EFI_PLATFORM_BIN)\tools\$(TARGET_NAME).exe /Y\r
   if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb \\r
   copy $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb /Y\r
 !ENDIF\r
+!ENDIF\r
 \r
 #\r
 # Build LIB\r
index 188ca77945ddf98691a3438ddbf22029f6e88382..2e065706331ed219c5527bffb34129d7bee05376 100644 (file)
@@ -24,6 +24,7 @@ Abstract:
 #include "EfiFirmwareFileSystem.h"\r
 #include "EfiFirmwareVolumeHeader.h"\r
 #include "EfiImageFormat.h"\r
+#include "EfiImage.h"\r
 #include "ParseInf.h"\r
 #include "Compress.h"\r
 #include "EfiCustomizedCompress.h"\r
@@ -82,6 +83,39 @@ PrintUsage (
   void\r
   );\r
 \r
+static\r
+void\r
+AddMacro (\r
+  UINT8   *MacroString\r
+  );\r
+\r
+static\r
+UINT8 *\r
+GetMacroValue (\r
+  UINT8   *MacroName\r
+  );\r
+    \r
+static\r
+void\r
+FreeMacros (\r
+  );\r
+\r
+static\r
+STATUS\r
+ReplaceMacros (\r
+  UINT8   *InputFile,\r
+  UINT8   *OutputFile\r
+  );\r
+    \r
+//\r
+// Linked list to keep track of all macros\r
+//\r
+typedef struct _MACRO {\r
+  struct _MACRO   *Next;\r
+  UINT8           *Name;\r
+  UINT8           *Value;\r
+} MACRO;\r
+\r
 //\r
 // Keep globals in this structure\r
 //\r
@@ -90,10 +124,13 @@ static struct {
   UINT8   PrimaryPackagePath[_MAX_PATH];\r
   UINT8   OverridePackagePath[_MAX_PATH];\r
   BOOLEAN Verbose;\r
+  MACRO   *MacroList;\r
 } mGlobals;\r
 \r
 static EFI_GUID mZeroGuid = { 0 };\r
 \r
+static UINT8  MinFfsDataAlignOverride = 0;\r
+\r
 static\r
 void\r
 StripQuotes (\r
@@ -151,8 +188,9 @@ Returns:
 --*/\r
 {\r
   printf ("Usage:\n");\r
-  printf (UTILITY_NAME " -b \"build directory\" -p1 \"package1.inf\" -p2 \"package2.inf\" -v\n");\r
-  printf ("   -b \"build directory\":\n ");\r
+  printf (UTILITY_NAME " -b \"build directory\" -p1 \"package1.inf\" -p2 \"package2.inf\"\n");\r
+  printf ("           -d \"name=value\" -v\n");\r
+  printf ("   -b \"build directory\":\n");\r
   printf ("       specifies the full path to the component build directory.\n");\r
   printf ("   -p1 \"P1_path\":\n");\r
   printf ("       specifies fully qualified file name to the primary package file.\n");\r
@@ -161,6 +199,10 @@ Returns:
   printf ("   -p2 \"P2_path\":\n");\r
   printf ("       specifies fully qualified file name to the override package file.\n");\r
   printf ("       This file will normally exist in the build tip. Optional.\n");\r
+  printf ("   -d \"name=value\":\n");\r
+  printf ("       add a macro definition for package file. Optional.\n");\r
+  printf ("   -v :\n");\r
+  printf ("       verbose. Optional.\n");\r
 }\r
 \r
 static\r
@@ -756,54 +798,6 @@ Returns:
   return ;\r
 }\r
 \r
-static\r
-INT32\r
-ProcessEnvironmentVariable (\r
-  IN CHAR8  *Buffer,\r
-  OUT CHAR8 *NewBuffer\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Converts environment variables to values\r
-\r
-Arguments:\r
-\r
-  Buffer      - Buffer containing Environment Variable String\r
-\r
-  NewBuffer   - Buffer containing value of environment variable\r
-\r
-\r
-Returns:\r
-\r
-  Number of characters from Buffer used\r
-\r
---*/\r
-{\r
-  INT32 Index;\r
-  INT32 Index2;\r
-  CHAR8 VariableBuffer[_MAX_PATH];\r
-\r
-  Index   = 2;\r
-  Index2  = 0;\r
-\r
-  while (Buffer[Index] != ')') {\r
-    VariableBuffer[Index - 2] = Buffer[Index++];\r
-  }\r
-\r
-  VariableBuffer[Index - 2] = 0;\r
-  Index++;\r
-\r
-  if (getenv (VariableBuffer) != NULL) {\r
-    strcpy (NewBuffer, getenv (VariableBuffer));\r
-  } else {\r
-    printf ("Environment variable %s not found!\n", VariableBuffer);\r
-  }\r
-\r
-  return Index;\r
-}\r
-\r
 static\r
 void\r
 SplitAttributesField (\r
@@ -880,7 +874,6 @@ GetToolArguments (
   UINT32      Index2;\r
   UINT32      z;\r
   CHAR8       *CharBuffer;\r
-  INT32       Index;\r
   INT32       ReturnValue;\r
   EFI_STATUS  Status;\r
 \r
@@ -982,17 +975,7 @@ GetToolArguments (
 \r
       ToolArgumentsArray[argc] = CharBuffer;\r
 \r
-      if (Buffer[0] == '$') {\r
-        Index = ProcessEnvironmentVariable (&Buffer[0], ToolArgumentsArray[argc]);\r
-        //\r
-        // if there is string after the environment variable, cat it.\r
-        //\r
-        if ((UINT32) Index < strlen (Buffer)) {\r
-          strcat (ToolArgumentsArray[argc], &Buffer[Index]);\r
-        }\r
-      } else {\r
-        strcpy (ToolArgumentsArray[argc], Buffer);\r
-      }\r
+      strcpy (ToolArgumentsArray[argc], Buffer);\r
 \r
       argc += 1;\r
       ToolArgumentsArray[argc] = NULL;\r
@@ -1010,17 +993,7 @@ GetToolArguments (
 \r
       ZeroMem (InputFileName, sizeof (_MAX_PATH));\r
 \r
-      if (Buffer[0] == '$') {\r
-        Index = ProcessEnvironmentVariable (&Buffer[0], InputFileName);\r
-        //\r
-        // if there is string after the environment variable, cat it.\r
-        //\r
-        if ((UINT32) Index < strlen (Buffer)) {\r
-          strcat (InputFileName, &Buffer[Index]);\r
-        }\r
-      } else {\r
-        strcpy (InputFileName, Buffer);\r
-      }\r
+      strcpy (InputFileName, Buffer);\r
 \r
       InputFlag = FALSE;\r
       continue;\r
@@ -1037,17 +1010,7 @@ GetToolArguments (
 \r
       ZeroMem (OutputFileName, sizeof (_MAX_PATH));\r
 \r
-      if (Buffer[0] == '$') {\r
-        Index = ProcessEnvironmentVariable (&Buffer[0], OutputFileName);\r
-        //\r
-        // if there is string after the environment variable, cat it.\r
-        //\r
-        if ((UINT32) Index < strlen (Buffer)) {\r
-          strcat (OutputFileName, &Buffer[Index]);\r
-        }\r
-      } else {\r
-        strcpy (OutputFileName, Buffer);\r
-      }\r
+      strcpy (OutputFileName, Buffer);\r
 \r
       OutputFlag = FALSE;\r
       continue;\r
@@ -1139,10 +1102,12 @@ Returns:
 {\r
   EFI_STATUS  Status;\r
   UINT32      Size;\r
+  UINT32      OldSize;\r
+  UINT32      Adjust;\r
+  UINT16      TeStrippedSize;\r
   CHAR8       Buffer[_MAX_PATH];\r
   CHAR8       Type[_MAX_PATH];\r
   CHAR8       FileName[_MAX_PATH];\r
-  CHAR8       NewBuffer[_MAX_PATH];\r
   INT32       Index3;\r
   INT32       Index2;\r
   UINT32      ReturnValue;\r
@@ -1157,7 +1122,6 @@ Returns:
   FILE        *InputFile;\r
   UINT8       Temp;\r
   int         returnint;\r
-  INT32       Index;\r
   UINT32      LineNumber;\r
   BOOLEAN     IsError;\r
   EFI_GUID    SignGuid;\r
@@ -1200,11 +1164,7 @@ Returns:
       }\r
 \r
       StripParens (Buffer);\r
-      if (Buffer[0] == '$') {\r
-        ProcessEnvironmentVariable (&Buffer[0], Type);\r
-      } else {\r
-        strcpy (Type, Buffer);\r
-      }\r
+      strcpy (Type, Buffer);\r
       //\r
       // build buffer\r
       //\r
@@ -1275,19 +1235,7 @@ Returns:
       }\r
 \r
       StripParens (Buffer);\r
-\r
-      if (Buffer[0] == '$') {\r
-        Index = ProcessEnvironmentVariable (&Buffer[0], ToolName);\r
-        //\r
-        // if there is string after the environment variable, cat it.\r
-        //\r
-        if ((UINT32) Index < strlen (Buffer)) {\r
-          strcat (ToolName, &Buffer[Index]);\r
-        }\r
-      } else {\r
-        strcpy (ToolName, Buffer);\r
-      }\r
-\r
+      strcpy (ToolName, Buffer);\r
       ToolArgumentsArray[0] = ToolName;\r
 \r
       //\r
@@ -1397,13 +1345,8 @@ Returns:
       if (!isalpha (Buffer[0]) || (Buffer[1] != ':')) {\r
         sprintf (FileName, "%s\\", BuildDirectory);\r
       }\r
-\r
+      \r
       while (Buffer[Index3] != '\n') {\r
-        if (Buffer[Index3] == '$') {\r
-          Index3 += ProcessEnvironmentVariable (&Buffer[Index3], NewBuffer);\r
-          strcat (FileName, NewBuffer);\r
-        }\r
-\r
         if (Buffer[Index3] == 0) {\r
           break;\r
         } else {\r
@@ -1420,6 +1363,7 @@ Returns:
         goto Done;\r
       }\r
 \r
+      OldSize = Size;\r
       fread (&ByteBuffer, sizeof (UINT8), 1, InFile);\r
       while (!feof (InFile)) {\r
         FileBuffer[Size++] = ByteBuffer;\r
@@ -1429,6 +1373,29 @@ Returns:
       fclose (InFile);\r
       InFile = NULL;\r
 \r
+      //\r
+      // Adjust the TE Section for IPF so that the function entries are 16-byte aligned.\r
+      //\r
+      if (Size - OldSize >= sizeof (EFI_COMMON_SECTION_HEADER) + sizeof (EFI_TE_IMAGE_HEADER) &&\r
+          ((EFI_COMMON_SECTION_HEADER *) &FileBuffer[OldSize])->Type == EFI_SECTION_TE        &&\r
+          ((EFI_TE_IMAGE_HEADER *) &FileBuffer[OldSize + 4])->Machine == EFI_IMAGE_MACHINE_IA64) {\r
+        TeStrippedSize = ((EFI_TE_IMAGE_HEADER *) &FileBuffer[OldSize + 4])->StrippedSize;\r
+        Adjust = TeStrippedSize - (OldSize + sizeof (EFI_COMMON_SECTION_HEADER) + sizeof (EFI_TE_IMAGE_HEADER));\r
+        Adjust &= 15;\r
+        if (Adjust > 0) {\r
+          memmove (&FileBuffer[OldSize + Adjust], &FileBuffer[OldSize], Size - OldSize);\r
+          //\r
+          // Pad with RAW Section type\r
+          //\r
+          *(UINT32 *)&FileBuffer[OldSize] = 0x19000000 | Adjust;\r
+          Size += Adjust;\r
+          //\r
+          // Make sure the Data alignment in FFS header is no less than 1 (16-byte aligned)\r
+          //\r
+          MinFfsDataAlignOverride = 1;\r
+        }\r
+      }\r
+\r
       //\r
       // Make sure section ends on a DWORD boundary\r
       //\r
@@ -2252,6 +2219,9 @@ here:
     memset (&FileHeader, 0, sizeof (EFI_FFS_FILE_HEADER));\r
     memcpy (&FileHeader.Name, &FfsGuid, sizeof (EFI_GUID));\r
     FileHeader.Type       = StringToType (FileType);\r
+    if (((FfsAttrib & FFS_ATTRIB_DATA_ALIGNMENT) >> 3) < MinFfsDataAlignOverride) {\r
+      FfsAttrib = (FfsAttrib & ~FFS_ATTRIB_DATA_ALIGNMENT) | (MinFfsDataAlignOverride << 3);\r
+    }\r
     FileHeader.Attributes = FfsAttrib;\r
     //\r
     // Now FileSize includes the EFI_FFS_FILE_HEADER\r
@@ -2396,6 +2366,9 @@ here:
     memset (&FileHeader, 0, sizeof (EFI_FFS_FILE_HEADER));\r
     memcpy (&FileHeader.Name, &FfsGuid, sizeof (EFI_GUID));\r
     FileHeader.Type       = StringToType (FileType);\r
+    if (((FfsAttrib & FFS_ATTRIB_DATA_ALIGNMENT) >> 3) < MinFfsDataAlignOverride) {\r
+      FfsAttrib = (FfsAttrib & ~FFS_ATTRIB_DATA_ALIGNMENT) | (MinFfsDataAlignOverride << 3);\r
+    }\r
     FileHeader.Attributes = FfsAttrib;\r
     //\r
     // From this point on FileSize includes the size of the EFI_FFS_FILE_HEADER\r
@@ -2540,6 +2513,7 @@ Returns:
   //\r
   SetUtilityName (UTILITY_NAME);\r
   Status = ProcessCommandLineArgs (argc, argv);\r
+  FreeMacros ();\r
   if (Status != STATUS_SUCCESS) {\r
     return Status;\r
   }\r
@@ -2577,6 +2551,11 @@ Returns:
 \r
 --*/\r
 {\r
+  STATUS       Status;\r
+  UINT8        *OriginalPrimaryPackagePath;\r
+  UINT8        *OriginalOverridePackagePath;\r
+  UINT8        *PackageName;\r
+  \r
   //\r
   // If no args, then print usage instructions and return an error\r
   //\r
@@ -2584,7 +2563,9 @@ Returns:
     PrintUsage ();\r
     return STATUS_ERROR;\r
   }\r
-\r
+  \r
+  OriginalPrimaryPackagePath = NULL;\r
+  OriginalOverridePackagePath = NULL;\r
   memset (&mGlobals, 0, sizeof (mGlobals));\r
   Argc--;\r
   Argv++;\r
@@ -2617,12 +2598,12 @@ Returns:
         return STATUS_ERROR;\r
       }\r
 \r
-      if (mGlobals.PrimaryPackagePath[0]) {\r
+      if (OriginalPrimaryPackagePath) {\r
         Error (NULL, 0, 0, Argv[0], "option can only be specified once");\r
         return STATUS_ERROR;\r
       }\r
-\r
-      strcpy (mGlobals.PrimaryPackagePath, Argv[1]);\r
+      \r
+      OriginalPrimaryPackagePath = Argv[1];\r
       Argc--;\r
       Argv++;\r
     } else if (_strcmpi (Argv[0], "-p2") == 0) {\r
@@ -2635,12 +2616,12 @@ Returns:
         return STATUS_ERROR;\r
       }\r
 \r
-      if (mGlobals.OverridePackagePath[0]) {\r
+      if (OriginalOverridePackagePath) {\r
         Error (NULL, 0, 0, Argv[0], "option can only be specified once");\r
         return STATUS_ERROR;\r
       }\r
-\r
-      strcpy (mGlobals.OverridePackagePath, Argv[1]);\r
+      \r
+      OriginalOverridePackagePath = Argv[1];\r
       Argc--;\r
       Argv++;\r
     } else if (_strcmpi (Argv[0], "-v") == 0) {\r
@@ -2648,6 +2629,19 @@ Returns:
       // OPTION: -v       verbose\r
       //\r
       mGlobals.Verbose = TRUE;\r
+    } else if (_strcmpi (Argv[0], "-d") == 0) {\r
+      //\r
+      // OPTION: -d  name=value\r
+      // Make sure there is another argument, then add it to our macro list.\r
+      //\r
+      if (Argc < 2) {\r
+        Error (NULL, 0, 0, Argv[0], "option requires the macro definition");\r
+        return STATUS_ERROR;\r
+      }\r
+      \r
+      AddMacro (Argv[1]);\r
+      Argc--;\r
+      Argv++;\r
     } else if (_strcmpi (Argv[0], "-h") == 0) {\r
       //\r
       // OPTION: -h      help\r
@@ -2669,13 +2663,324 @@ Returns:
     Argv++;\r
     Argc--;\r
   }\r
+\r
+  //\r
+  // Must have at least specified the build directory\r
+  //\r
+  if (!mGlobals.BuildDirectory[0]) {\r
+    Error (NULL, 0, 0, "must specify build directory", NULL);\r
+    return STATUS_ERROR;\r
+  }\r
+  \r
   //\r
   // Must have at least specified the package file name\r
   //\r
-  if (mGlobals.PrimaryPackagePath[0] == 0) {\r
+  if (OriginalPrimaryPackagePath == NULL) {\r
     Error (NULL, 0, 0, "must specify primary package file", NULL);\r
     return STATUS_ERROR;\r
   }\r
 \r
+  PackageName = OriginalPrimaryPackagePath + strlen (OriginalPrimaryPackagePath);\r
+  while ((*PackageName != '\\') && (*PackageName != '/') && \r
+         (PackageName != OriginalPrimaryPackagePath)) {\r
+    PackageName--;\r
+  }\r
+  //\r
+  // Skip the '\' or '/'\r
+  //\r
+  if (PackageName != OriginalPrimaryPackagePath) {\r
+    PackageName++;\r
+  }\r
+  sprintf (mGlobals.PrimaryPackagePath, "%s\\%s.new", mGlobals.BuildDirectory, PackageName);\r
+  Status = ReplaceMacros (OriginalPrimaryPackagePath, mGlobals.PrimaryPackagePath);\r
+  if (Status == STATUS_WARNING) {\r
+    //\r
+    // No macro replacement, use the previous package file\r
+    //\r
+    strcpy (mGlobals.PrimaryPackagePath, OriginalPrimaryPackagePath);\r
+  } else if (Status != STATUS_SUCCESS) {\r
+    return Status;\r
+  }\r
+  \r
+  if (OriginalOverridePackagePath != NULL) {\r
+    PackageName = OriginalOverridePackagePath + strlen (OriginalOverridePackagePath);\r
+    while ((*PackageName != '\\') && (*PackageName != '/') && \r
+           (PackageName != OriginalOverridePackagePath)) {\r
+      PackageName--;\r
+    }\r
+    //\r
+    // Skip the '\' or '/'\r
+    //\r
+    if (PackageName != OriginalOverridePackagePath) {\r
+      PackageName++;\r
+    }    \r
+    sprintf (mGlobals.OverridePackagePath, "%s\\%s.new", mGlobals.BuildDirectory, PackageName);\r
+    Status = ReplaceMacros (OriginalOverridePackagePath, mGlobals.OverridePackagePath);\r
+    if (Status == STATUS_WARNING) {\r
+      //\r
+      // No macro replacement, use the previous package file\r
+      //\r
+      strcpy (mGlobals.OverridePackagePath, OriginalOverridePackagePath);\r
+    } else if (Status != STATUS_SUCCESS) {\r
+        return Status;\r
+    }    \r
+  }\r
+\r
   return STATUS_SUCCESS;\r
 }\r
+\r
+static\r
+void\r
+AddMacro (\r
+  UINT8   *MacroString\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Add or override a macro definition.\r
+\r
+Arguments:\r
+\r
+  MacroString  - macro definition string: name=value\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/  \r
+{\r
+  MACRO    *Macro;\r
+  MACRO    *NewMacro;\r
+  UINT8    *Value;\r
+  \r
+  //\r
+  // Seperate macro name and value by '\0'\r
+  //\r
+  for (Value = MacroString; *Value && (*Value != '='); Value++);\r
+  \r
+  if (*Value == '=') {\r
+    *Value = '\0';\r
+    Value ++;\r
+  }\r
+  \r
+  //\r
+  // We now have a macro name and value. \r
+  // Look for an existing macro and overwrite it.\r
+  //\r
+  Macro = mGlobals.MacroList;\r
+  while (Macro) {\r
+    if (_strcmpi (MacroString, Macro->Name) == 0) {\r
+      Macro->Value = Value;\r
+      return;\r
+    }\r
+\r
+    Macro = Macro->Next;\r
+  }\r
+  \r
+  //\r
+  // Does not exist, create a new one\r
+  //\r
+  NewMacro = (MACRO *) malloc (sizeof (MACRO));\r
+  memset ((UINT8 *) NewMacro, 0, sizeof (MACRO));\r
+  NewMacro->Name   = MacroString;\r
+  NewMacro->Value  = Value;\r
+\r
+  //\r
+  // Add it to the head of the list.\r
+  //\r
+  NewMacro->Next = mGlobals.MacroList;\r
+  mGlobals.MacroList = NewMacro;\r
+  \r
+  return;\r
+}\r
+\r
+static\r
+UINT8 *\r
+GetMacroValue (\r
+  UINT8   *MacroName\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Look up a macro.\r
+\r
+Arguments:\r
+\r
+  MacroName  - The name of macro\r
+\r
+Returns:\r
+\r
+  Pointer to the value of the macro if found\r
+  NULL if the macro is not found\r
+\r
+--*/   \r
+{\r
+\r
+  MACRO  *Macro;\r
+  UINT8  *Value;\r
+\r
+  //\r
+  // Scan for macro\r
+  //\r
+  Macro = mGlobals.MacroList;\r
+  while (Macro) {\r
+    if (_strcmpi (MacroName, Macro->Name) == 0) {\r
+      return Macro->Value;\r
+    }\r
+    Macro = Macro->Next;\r
+  }\r
+  \r
+  //\r
+  // Try environment variable\r
+  //\r
+  Value = getenv (MacroName);\r
+  if (Value == NULL) {\r
+    printf ("Environment variable %s not found!\n", MacroName);\r
+  }   \r
+  return Value;\r
+}\r
+  \r
+static\r
+void\r
+FreeMacros (\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Free the macro list.\r
+\r
+Arguments:\r
+\r
+  None\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/    \r
+{\r
+  MACRO    *Macro;\r
+  MACRO    *NextMacro;\r
+  \r
+  Macro = mGlobals.MacroList;\r
+  while (Macro) {\r
+    NextMacro = Macro->Next;\r
+    free (Macro);\r
+    Macro = NextMacro;\r
+  }\r
+  mGlobals.MacroList = NULL;\r
+  \r
+  return;\r
+}\r
+\r
+static\r
+STATUS\r
+ReplaceMacros (\r
+  UINT8   *InputFile,\r
+  UINT8   *OutputFile\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Replace all the macros in InputFile to create the OutputFile.\r
+\r
+Arguments:\r
+\r
+  InputFile         - Input package file for macro replacement\r
+  OutputFile        - Output package file after macro replacement\r
+\r
+Returns:\r
+\r
+  STATUS_SUCCESS    - Output package file is created successfully after the macro replacement.\r
+  STATUS_WARNING    - Output package file is not created because of no macro replacement.\r
+  STATUS_ERROR      - Some error occurred during execution.\r
+\r
+--*/    \r
+{\r
+  FILE   *Fptr;\r
+  UINT8  *SaveStart;\r
+  UINT8  *FromPtr;\r
+  UINT8  *ToPtr;\r
+  UINT8  *Value;\r
+  UINT8  *FileBuffer;\r
+  UINTN  FileSize;\r
+  \r
+  //\r
+  // Get the file size, and then read the entire thing into memory.\r
+  // Allocate extra space for a terminator character.\r
+  //\r
+  if ((Fptr = fopen (InputFile, "r")) == NULL) {\r
+    Error (NULL, 0, 0, InputFile, "can't open input file");\r
+    return STATUS_ERROR;    \r
+  }\r
+  fseek (Fptr, 0, SEEK_END);\r
+  FileSize = ftell (Fptr);\r
+  fseek (Fptr, 0, SEEK_SET);\r
+  FileBuffer = malloc (FileSize + 1);\r
+  if (FileBuffer == NULL) {\r
+    fclose (Fptr);\r
+    Error (NULL, 0, 0, InputFile, "file buffer memory allocation failure");\r
+    return STATUS_ERROR;\r
+  }\r
+  fread (FileBuffer, FileSize, 1, Fptr);\r
+  FileBuffer[FileSize] = '\0';\r
+  fclose (Fptr);\r
+    \r
+  //\r
+  // Walk the entire file, replacing $(MACRO_NAME).\r
+  //\r
+  Fptr = NULL;\r
+  FromPtr = FileBuffer;\r
+  SaveStart = FromPtr;\r
+  while (*FromPtr) {\r
+    if ((*FromPtr == '$') && (*(FromPtr + 1) == '(')) {\r
+      FromPtr += 2;\r
+      for (ToPtr = FromPtr; *ToPtr && (*ToPtr != ')'); ToPtr++);\r
+      if (*ToPtr) {\r
+        //\r
+        // Find an $(MACRO_NAME), replace it\r
+        //\r
+        *ToPtr = '\0';\r
+        Value = GetMacroValue (FromPtr);\r
+        *(FromPtr-2)= '\0';\r
+        if (Fptr == NULL) {\r
+          if ((Fptr = fopen (OutputFile, "w")) == NULL) {\r
+            free (FileBuffer);\r
+            Error (NULL, 0, 0, OutputFile, "can't open output file");\r
+            return STATUS_ERROR;    \r
+          }\r
+        }\r
+        if (Value != NULL) {\r
+          fprintf (Fptr, "%s%s", SaveStart, Value);\r
+        } else {\r
+          fprintf (Fptr, "%s", SaveStart);\r
+        }\r
+        //\r
+        // Continue macro replacement for the remaining string line\r
+        //\r
+        FromPtr = ToPtr+1;\r
+        SaveStart = FromPtr;\r
+        continue;\r
+      } else {\r
+        break;\r
+      }\r
+    } else {\r
+      FromPtr++;\r
+    }\r
+  }\r
+  if (Fptr != NULL) {\r
+    fprintf (Fptr, "%s", SaveStart);\r
+  }\r
+  \r
+  free (FileBuffer);\r
+  if (Fptr != NULL) {\r
+    fclose (Fptr);\r
+    return STATUS_SUCCESS;\r
+  } else {\r
+    return STATUS_WARNING;\r
+  }\r
+}\r
index 85f9cfde9aeb6ef4ce10b01da5a6837a6efb27fa..2be50923adca8dd1b9e078f79bf6672684b5d3d7 100644 (file)
@@ -78,11 +78,13 @@ $(TARGET_EXE): $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe
 $(TARGET_EXE): $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj $(LIBS) $(TARGET_EXE_LIBS)\r
   $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj  \\r
         $(TARGET_LIB)  $(TARGET_EXE_LIBS) \r
+!IF ("$(EFI_BINARY_BUILD)" == "YES")\r
   if not exist $(EFI_PLATFORM_BIN)\Tools mkdir $(EFI_PLATFORM_BIN)\Tools\r
   if exist $(TARGET_EXE) copy $(TARGET_EXE) $(EFI_PLATFORM_BIN)\tools\$(TARGET_NAME).exe /Y\r
   if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb \\r
   copy $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb /Y\r
 !ENDIF\r
+!ENDIF\r
 \r
 clean:\r
   @if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL\r
index e1db1b14683ef0d55247f814dc18df5069f254d7..d275ffbc3a9eeb81c910cf8c3ef7bde2832b86ef 100644 (file)
@@ -26,7 +26,7 @@ Abstract:
 //\r
 // Include files\r
 //\r
-#include "Efi2WinNT.h"\r
+#include <windows.h>\r
 #include "ParseInf.h"\r
 \r
 //\r
index d3b43c0ab7e645f6cc8b0f8c1e09dd28e6e1b165..18243b697b24551aa2648387b7d5a51ee596069b 100644 (file)
@@ -88,11 +88,13 @@ $(TARGET_EXE): $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe
 !ELSE\r
 $(TARGET_EXE): $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj $(TARGET_EXE_LIBS) $(TARGET_LIB)\r
   $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj $(TARGET_LIB)  $(TARGET_EXE_LIBS)\r
+!IF ("$(EFI_BINARY_BUILD)" == "YES")\r
   if not exist $(EFI_PLATFORM_BIN)\Tools mkdir $(EFI_PLATFORM_BIN)\Tools\r
   if exist $(TARGET_EXE) copy $(TARGET_EXE) $(EFI_PLATFORM_BIN)\tools\$(TARGET_NAME).exe /Y\r
   if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb \\r
   copy $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb /Y\r
 !ENDIF\r
+!ENDIF\r
 \r
 #\r
 # Build LIB\r
diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/GenPage/Makefile b/EdkCompatibilityPkg/Sample/Tools/Source/GenPage/Makefile
deleted file mode 100644 (file)
index 8c4addb..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-#/*++\r
-#  \r
-#  Copyright (c) 2006 - 2007, Intel Corporation                                                         \r
-#  All rights reserved. This program and the accompanying materials                          \r
-#  are licensed and made available under the terms and conditions of the BSD License         \r
-#  which accompanies this distribution.  The full text of the license may be found at        \r
-#  http://opensource.org/licenses/bsd-license.php                                            \r
-#                                                                                            \r
-#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
-#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
-#  \r
-#  Module Name:\r
-#  \r
-#    Makefile\r
-#  \r
-#  Abstract:\r
-#  \r
-#    makefile for building the GenPage utility.\r
-#    \r
-#--*/  \r
-\r
-#\r
-# Make sure environmental variable EDK_SOURCE is set\r
-#\r
-!IFNDEF EDK_SOURCE\r
-!ERROR EDK_SOURCE environmental variable not set \r
-!ENDIF\r
-\r
-#\r
-# Do this if you want to compile from this directory\r
-#\r
-!IFNDEF TOOLCHAIN\r
-TOOLCHAIN = TOOLCHAIN_MSVC\r
-!ENDIF\r
-\r
-!INCLUDE $(BUILD_DIR)\PlatformTools.env\r
-\r
-#\r
-# Define some macros we use here. Should get rid of them someday and \r
-# get rid of the extra level of indirection.\r
-#\r
-COMMON_SOURCE      = $(EDK_TOOLS_COMMON)\r
-\r
-#\r
-# Common information\r
-#\r
-\r
-INC=$(INC)\r
-\r
-#\r
-# Target specific information\r
-#\r
-\r
-TARGET_NAME=GenPage\r
-TARGET_SOURCE_DIR = $(EDK_TOOLS_SOURCE)\$(TARGET_NAME)\r
-\r
-TARGET_EXE = $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).exe\r
-\r
-TARGET_EXE_SOURCE = "$(TARGET_SOURCE_DIR)\GenPage.c"\r
-TARGET_EXE_INCLUDE = "$(TARGET_SOURCE_DIR)\VirtualMemory.h"\r
-\r
-#\r
-# Build targets\r
-#\r
-\r
-all: $(TARGET_EXE)\r
-\r
-#\r
-# Build EXE\r
-#\r
-\r
-$(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj: $(TARGET_EXE_SOURCE) $(TARGET_EXE_INCLUDE)\r
-  $(CC) $(C_FLAGS) $(INC) $(TARGET_EXE_SOURCE) /Fo$(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj\r
-\r
-#\r
-# Add Binary Build description for this tool.\r
-#\r
-\r
-!IF (("$(EFI_BINARY_TOOLS)" == "YES") && EXIST($(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe))\r
-$(TARGET_EXE): $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe\r
-  copy $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe $(TARGET_EXE) /Y\r
-  if exist $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb \\r
-  copy $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb /Y\r
-!ELSE\r
-$(TARGET_EXE): $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj\r
-  $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) /out:$(TARGET_EXE) $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj\r
-  if not exist $(EFI_PLATFORM_BIN)\Tools mkdir $(EFI_PLATFORM_BIN)\Tools\r
-  if exist $(TARGET_EXE) copy $(TARGET_EXE) $(EFI_PLATFORM_BIN)\tools\$(TARGET_NAME).exe /Y\r
-  if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb \\r
-  copy $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb /Y\r
-!ENDIF\r
-\r
-clean:\r
-  @if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL\r
-\r
diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/GenPage/VirtualMemory.h b/EdkCompatibilityPkg/Sample/Tools/Source/GenPage/VirtualMemory.h
deleted file mode 100644 (file)
index d9d928f..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-/*++ \r
-\r
-Copyright 2006 - 2007, Intel Corporation                                                         \r
-All rights reserved. This program and the accompanying materials                          \r
-are licensed and made available under the terms and conditions of the BSD License         \r
-which accompanies this distribution.  The full text of the license may be found at        \r
-http://opensource.org/licenses/bsd-license.php                                            \r
-                                                                                          \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
-\r
-Module Name:\r
-  VirtualMemory.h\r
-  \r
-Abstract:\r
-\r
-  x64 Long Mode Virtual Memory Management Definitions  \r
-\r
-  References:\r
-    1) IA-32 Intel(R) Atchitecture Software Developer's Manual Volume 1:Basic Architecture, Intel\r
-    2) IA-32 Intel(R) Atchitecture Software Developer's Manual Volume 2:Instruction Set Reference, Intel\r
-    3) IA-32 Intel(R) Atchitecture Software Developer's Manual Volume 3:System Programmer's Guide, Intel\r
-    4) AMD64 Architecture Programmer's Manual Volume 2: System Programming\r
---*/\r
-\r
-#ifndef _VIRTUAL_MEMORY_H_\r
-#define _VIRTUAL_MEMORY_H_\r
-\r
-#include "Tiano.h"\r
-\r
-#pragma pack(1)\r
-\r
-//\r
-// Page-Map Level-4 Offset (PML4) and\r
-// Page-Directory-Pointer Offset (PDPE) entries 4K & 2MB\r
-//\r
-\r
-typedef union {\r
-  struct {\r
-    UINT64  Present:1;                // 0 = Not present in memory, 1 = Present in memory\r
-    UINT64  ReadWrite:1;              // 0 = Read-Only, 1= Read/Write\r
-    UINT64  UserSupervisor:1;         // 0 = Supervisor, 1=User\r
-    UINT64  WriteThrough:1;           // 0 = Write-Back caching, 1=Write-Through caching\r
-    UINT64  CacheDisabled:1;          // 0 = Cached, 1=Non-Cached\r
-    UINT64  Accessed:1;               // 0 = Not accessed, 1 = Accessed (set by CPU)\r
-    UINT64  Reserved:1;               // Reserved\r
-    UINT64  MustBeZero:2;             // Must Be Zero\r
-    UINT64  Available:3;              // Available for use by system software\r
-    UINT64  PageTableBaseAddress:40;  // Page Table Base Address\r
-    UINT64  AvabilableHigh:11;        // Available for use by system software\r
-    UINT64  Nx:1;                     // No Execute bit\r
-  } Bits;\r
-  UINT64    Uint64;\r
-} X64_PAGE_MAP_AND_DIRECTORY_POINTER_2MB_4K;\r
-\r
-//\r
-// Page-Directory Offset 4K\r
-//\r
-typedef union {\r
-  struct {\r
-    UINT64  Present:1;                // 0 = Not present in memory, 1 = Present in memory\r
-    UINT64  ReadWrite:1;              // 0 = Read-Only, 1= Read/Write\r
-    UINT64  UserSupervisor:1;         // 0 = Supervisor, 1=User\r
-    UINT64  WriteThrough:1;           // 0 = Write-Back caching, 1=Write-Through caching\r
-    UINT64  CacheDisabled:1;          // 0 = Cached, 1=Non-Cached\r
-    UINT64  Accessed:1;               // 0 = Not accessed, 1 = Accessed (set by CPU)\r
-    UINT64  Reserved:1;               // Reserved\r
-    UINT64  MustBeZero:1;             // Must Be Zero\r
-    UINT64  Reserved2:1;              // Reserved\r
-    UINT64  Available:3;              // Available for use by system software\r
-    UINT64  PageTableBaseAddress:40;  // Page Table Base Address\r
-    UINT64  AvabilableHigh:11;        // Available for use by system software\r
-    UINT64  Nx:1;                     // No Execute bit\r
-  } Bits;\r
-  UINT64    Uint64;\r
-} X64_PAGE_DIRECTORY_ENTRY_4K;\r
-\r
-//\r
-// Page Table Entry 4K\r
-//\r
-typedef union {\r
-  struct {\r
-    UINT64  Present:1;                // 0 = Not present in memory, 1 = Present in memory\r
-    UINT64  ReadWrite:1;              // 0 = Read-Only, 1= Read/Write\r
-    UINT64  UserSupervisor:1;         // 0 = Supervisor, 1=User\r
-    UINT64  WriteThrough:1;           // 0 = Write-Back caching, 1=Write-Through caching\r
-    UINT64  CacheDisabled:1;          // 0 = Cached, 1=Non-Cached\r
-    UINT64  Accessed:1;               // 0 = Not accessed, 1 = Accessed (set by CPU)\r
-    UINT64  Dirty:1;                  // 0 = Not Dirty, 1 = written by processor on access to page\r
-    UINT64  PAT:1;                    // 0 = Ignore Page Attribute Table \r
-    UINT64  Global:1;                 // 0 = Not global page, 1 = global page TLB not cleared on CR3 write\r
-    UINT64  Available:3;              // Available for use by system software\r
-    UINT64  PageTableBaseAddress:40;  // Page Table Base Address\r
-    UINT64  AvabilableHigh:11;        // Available for use by system software\r
-    UINT64  Nx:1;                     // 0 = Execute Code, 1 = No Code Execution\r
-  } Bits;\r
-  UINT64    Uint64;\r
-} X64_PAGE_TABLE_ENTRY_4K;\r
-\r
-\r
-//\r
-// Page Table Entry 2MB\r
-//\r
-typedef union {\r
-  struct {\r
-    UINT64  Present:1;                // 0 = Not present in memory, 1 = Present in memory\r
-    UINT64  ReadWrite:1;              // 0 = Read-Only, 1= Read/Write\r
-    UINT64  UserSupervisor:1;         // 0 = Supervisor, 1=User\r
-    UINT64  WriteThrough:1;           // 0 = Write-Back caching, 1=Write-Through caching\r
-    UINT64  CacheDisabled:1;          // 0 = Cached, 1=Non-Cached\r
-    UINT64  Accessed:1;               // 0 = Not accessed, 1 = Accessed (set by CPU)\r
-    UINT64  Dirty:1;                  // 0 = Not Dirty, 1 = written by processor on access to page\r
-    UINT64  MustBe1:1;                // Must be 1 \r
-    UINT64  Global:1;                 // 0 = Not global page, 1 = global page TLB not cleared on CR3 write\r
-    UINT64  Available:3;              // Available for use by system software\r
-    UINT64  PAT:1;                    //\r
-    UINT64  MustBeZero:8;             // Must be zero;\r
-    UINT64  PageTableBaseAddress:31;  // Page Table Base Address\r
-    UINT64  AvabilableHigh:11;        // Available for use by system software\r
-    UINT64  Nx:1;                     // 0 = Execute Code, 1 = No Code Execution\r
-  } Bits;\r
-  UINT64    Uint64;\r
-} X64_PAGE_TABLE_ENTRY_2M;\r
-\r
-#pragma pack()\r
-\r
-#endif \r
diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/GenPage/genpage.c b/EdkCompatibilityPkg/Sample/Tools/Source/GenPage/genpage.c
deleted file mode 100644 (file)
index 7085f19..0000000
+++ /dev/null
@@ -1,344 +0,0 @@
-/*++ \r
-\r
-Copyright 2006 - 2007, Intel Corporation                                                         \r
-All rights reserved. This program and the accompanying materials                          \r
-are licensed and made available under the terms and conditions of the BSD License         \r
-which accompanies this distribution.  The full text of the license may be found at        \r
-http://opensource.org/licenses/bsd-license.php                                            \r
-                                                                                          \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
-\r
-Module Name:\r
-  GenPage.c\r
-  \r
-Abstract:\r
-  Pre-Create a 4G page table (2M pages).\r
-  It's used in DUET x64 build needed to enter LongMode.\r
\r
-  Create 4G page table (2M pages)\r
\r
-                              Linear Address\r
-    63    48 47   39 38           30 29       21 20                          0\r
-   +--------+-------+---------------+-----------+-----------------------------+\r
-               PML4   Directory-Ptr   Directory                 Offset\r
-\r
-   Paging-Structures :=\r
-                        PML4\r
-                        (\r
-                          Directory-Ptr Directory {512}\r
-                        ) {4}\r
---*/\r
-\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include "VirtualMemory.h"\r
-\r
-void\r
-memset (void *, char, long);\r
-\r
-unsigned int\r
-xtoi (char  *);\r
-\r
-#define EFI_PAGE_BASE_OFFSET_IN_LDR 0x70000\r
-#define EFI_PAGE_BASE_ADDRESS       (EFI_PAGE_BASE_OFFSET_IN_LDR + 0x20000)\r
-\r
-unsigned int gPageTableBaseAddress  = EFI_PAGE_BASE_ADDRESS;\r
-unsigned int gPageTableOffsetInFile = EFI_PAGE_BASE_OFFSET_IN_LDR;\r
-\r
-#define EFI_MAX_ENTRY_NUM     512\r
-\r
-#define EFI_PML4_ENTRY_NUM    1\r
-#define EFI_PDPTE_ENTRY_NUM   4\r
-#define EFI_PDE_ENTRY_NUM     EFI_MAX_ENTRY_NUM\r
-\r
-#define EFI_PML4_PAGE_NUM     1\r
-#define EFI_PDPTE_PAGE_NUM    EFI_PML4_ENTRY_NUM\r
-#define EFI_PDE_PAGE_NUM      (EFI_PML4_ENTRY_NUM * EFI_PDPTE_ENTRY_NUM)\r
-\r
-#define EFI_PAGE_NUMBER       (EFI_PML4_PAGE_NUM + EFI_PDPTE_PAGE_NUM + EFI_PDE_PAGE_NUM)\r
-\r
-#define EFI_SIZE_OF_PAGE      0x1000\r
-#define EFI_PAGE_SIZE_2M      0x200000\r
-\r
-#define CONVERT_BIN_PAGE_ADDRESS(a)  ((UINT8 *) a - PageTable + gPageTableBaseAddress)\r
-\r
-\r
-void *\r
-CreateIdentityMappingPageTables (\r
-  void\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-  To create 4G PAE 2M pagetable\r
-\r
-Return:\r
-  void * - buffer containing created pagetable\r
-\r
---*/\r
-{\r
-  UINT64                                        PageAddress;\r
-  UINT8                                         *PageTable;\r
-  UINT8                                         *PageTablePtr;\r
-  int                                           PML4Index;\r
-  int                                           PDPTEIndex;\r
-  int                                           PDEIndex;\r
-  X64_PAGE_MAP_AND_DIRECTORY_POINTER_2MB_4K     *PageMapLevel4Entry;\r
-  X64_PAGE_MAP_AND_DIRECTORY_POINTER_2MB_4K     *PageDirectoryPointerEntry;\r
-  X64_PAGE_TABLE_ENTRY_2M                       *PageDirectoryEntry2MB;\r
-\r
-  PageTable = (void *)malloc (EFI_PAGE_NUMBER * EFI_SIZE_OF_PAGE);\r
-  memset (PageTable, 0, (EFI_PAGE_NUMBER * EFI_SIZE_OF_PAGE));\r
-  PageTablePtr = PageTable;\r
-\r
-  PageAddress = 0;\r
-\r
-  //\r
-  //  Page Table structure 3 level 2MB.\r
-  //\r
-  //                   Page-Map-Level-4-Table        : bits 47-39\r
-  //                   Page-Directory-Pointer-Table  : bits 38-30\r
-  //\r
-  //  Page Table 2MB : Page-Directory(2M)            : bits 29-21\r
-  //\r
-  //\r
-\r
-  PageMapLevel4Entry = (X64_PAGE_MAP_AND_DIRECTORY_POINTER_2MB_4K *)PageTablePtr;\r
-\r
-  for (PML4Index = 0; PML4Index < EFI_PML4_ENTRY_NUM; PML4Index++, PageMapLevel4Entry++) {\r
-    //\r
-    // Each Page-Map-Level-4-Table Entry points to the base address of a Page-Directory-Pointer-Table Entry\r
-    //  \r
-    PageTablePtr += EFI_SIZE_OF_PAGE;\r
-    PageDirectoryPointerEntry = (X64_PAGE_MAP_AND_DIRECTORY_POINTER_2MB_4K *)PageTablePtr;\r
-\r
-    //\r
-    // Make a Page-Map-Level-4-Table Entry\r
-    //\r
-    PageMapLevel4Entry->Uint64 = (UINT64)(UINT32)(CONVERT_BIN_PAGE_ADDRESS (PageDirectoryPointerEntry));\r
-    PageMapLevel4Entry->Bits.ReadWrite = 1;\r
-    PageMapLevel4Entry->Bits.Present = 1;\r
-\r
-    for (PDPTEIndex = 0; PDPTEIndex < EFI_PDPTE_ENTRY_NUM; PDPTEIndex++, PageDirectoryPointerEntry++) {\r
-      //\r
-      // Each Page-Directory-Pointer-Table Entry points to the base address of a Page-Directory Entry\r
-      //       \r
-      PageTablePtr += EFI_SIZE_OF_PAGE;\r
-      PageDirectoryEntry2MB = (X64_PAGE_TABLE_ENTRY_2M *)PageTablePtr;\r
-\r
-      //\r
-      // Make a Page-Directory-Pointer-Table Entry\r
-      //\r
-      PageDirectoryPointerEntry->Uint64 = (UINT64)(UINT32)(CONVERT_BIN_PAGE_ADDRESS (PageDirectoryEntry2MB));\r
-      PageDirectoryPointerEntry->Bits.ReadWrite = 1;\r
-      PageDirectoryPointerEntry->Bits.Present = 1;\r
-\r
-      for (PDEIndex = 0; PDEIndex < EFI_PDE_ENTRY_NUM; PDEIndex++, PageDirectoryEntry2MB++) {\r
-        //\r
-        // Make a Page-Directory Entry\r
-        //\r
-        PageDirectoryEntry2MB->Uint64 = (UINT64)PageAddress;\r
-        PageDirectoryEntry2MB->Bits.ReadWrite = 1;\r
-        PageDirectoryEntry2MB->Bits.Present = 1;\r
-        PageDirectoryEntry2MB->Bits.MustBe1 = 1;\r
-\r
-        PageAddress += EFI_PAGE_SIZE_2M;\r
-      }\r
-    }\r
-  }\r
-\r
-  return PageTable;\r
-}\r
-\r
-int\r
-GenBinPage (\r
-  void *BaseMemory,\r
-  char *NoPageFileName,\r
-  char *PageFileName\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-  Write the buffer containing page table to file at a specified offset.\r
-  Here the offset is defined as EFI_PAGE_BASE_OFFSET_IN_LDR.\r
-\r
-Arguments:\r
-  BaseMemory     - buffer containing page table\r
-  NoPageFileName - file to write page table\r
-  PageFileName   - file save to after writing\r
-\r
-return:\r
-  0  : successful\r
-  -1 : failed\r
-\r
---*/\r
-{\r
-  FILE  *PageFile;\r
-  FILE  *NoPageFile;\r
-  UINT8 Data;\r
-  unsigned long FileSize;\r
-\r
-  //\r
-  // Open files\r
-  //\r
-  PageFile = fopen (PageFileName, "w+b");\r
-  if (PageFile == NULL) {\r
-    fprintf (stderr, "GenBinPage: Could not open file %s\n", PageFileName);\r
-    return -1;\r
-  }\r
-\r
-  NoPageFile = fopen (NoPageFileName, "r+b");\r
-  if (NoPageFile == NULL) {\r
-    fprintf (stderr, "GenBinPage: Could not open file %s\n", NoPageFileName);\r
-    fclose (PageFile);\r
-    return -1;\r
-  }\r
-\r
-  //\r
-  // Check size - should not be great than EFI_PAGE_BASE_OFFSET_IN_LDR\r
-  //\r
-  fseek (NoPageFile, 0, SEEK_END);\r
-  FileSize = ftell (NoPageFile);\r
-  fseek (NoPageFile, 0, SEEK_SET);\r
-  if (FileSize > gPageTableOffsetInFile) {\r
-    fprintf (stderr, "GenBinPage: file size too large - 0x%x\n", FileSize);\r
-    fclose (PageFile);\r
-    fclose (NoPageFile);\r
-    return -1;\r
-  }\r
-\r
-  //\r
-  // Write data\r
-  //\r
-  while (fread (&Data, sizeof(UINT8), 1, NoPageFile)) {\r
-    fwrite (&Data, sizeof(UINT8), 1, PageFile);\r
-  }\r
-\r
-  //\r
-  // Write PageTable\r
-  //\r
-  fseek (PageFile, gPageTableOffsetInFile, SEEK_SET);\r
-  fwrite (BaseMemory, (EFI_PAGE_NUMBER * EFI_SIZE_OF_PAGE), 1, PageFile);\r
-\r
-  //\r
-  // Close files\r
-  //\r
-  fclose (PageFile);\r
-  fclose (NoPageFile);\r
-\r
-  return 0;\r
-}\r
-\r
-int\r
-main (\r
-  int argc,\r
-  char **argv\r
-  )\r
-{\r
-  void *BaseMemory;\r
-  int  result;\r
-\r
-  //\r
-  // Check parameter\r
-  //\r
-  if ((argc != 3) && (argc != 5)) {\r
-    printf ("Usage: GenPage.exe NoPageFile PageFile [<PageTableBaseAddrss> <PageTableOffsetInFile>]\n");\r
-    return 1;\r
-  }\r
-\r
-  //\r
-  // Get PageTable parameter, if have\r
-  //\r
-  if (argc == 5) {\r
-    gPageTableBaseAddress  = xtoi (argv[3]);\r
-    gPageTableOffsetInFile = xtoi (argv[4]);\r
-  }\r
-\r
-  //\r
-  // Create X64 page table\r
-  //\r
-  BaseMemory = CreateIdentityMappingPageTables ();\r
-\r
-  //\r
-  // Add page table to binary file\r
-  //\r
-  result = GenBinPage (BaseMemory, argv[1], argv[2]);\r
-  if (result < 0) {\r
-    return 1;\r
-  }\r
-\r
-  return 0;\r
-}\r
-\r
-unsigned int\r
-xtoi (\r
-  char  *str\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Convert hex string to uint\r
-\r
-Arguments:\r
-\r
-  Str  -  The string\r
-  \r
-Returns:\r
-\r
---*/\r
-{\r
-  unsigned int u;\r
-  char         c;\r
-  unsigned int m;\r
-  \r
-  if (str == NULL) {\r
-    return 0;\r
-  }\r
-  \r
-  m = (unsigned int) -1 >> 4;\r
-  //\r
-  // skip preceeding white space\r
-  //\r
-  while (*str && *str == ' ') {\r
-    str += 1;\r
-  }\r
-  //\r
-  // skip preceeding zeros\r
-  //\r
-  while (*str && *str == '0') {\r
-    str += 1;\r
-  }\r
-  //\r
-  // skip preceeding white space\r
-  //\r
-  if (*str && (*str == 'x' || *str == 'X')) {\r
-    str += 1;\r
-  }\r
-  //\r
-  // convert hex digits\r
-  //\r
-  u = 0;\r
-  c = *(str++);\r
-  while (c) {\r
-    if (c >= 'a' && c <= 'f') {\r
-      c -= 'a' - 'A';\r
-    }\r
-\r
-    if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F')) {\r
-      if (u > m) {\r
-        return (unsigned int) -1;\r
-      }\r
-\r
-      u = u << 4 | c - (c >= 'A' ? 'A' - 10 : '0');\r
-    } else {\r
-      break;\r
-    }\r
-\r
-    c = *(str++);\r
-  }\r
-\r
-  return u;\r
-}\r
-\r
index 053d2376a03afda17a20a0bbdf2add88ad475ccf..963ff16ef29a55405dd42917071a276b160bf5ff 100644 (file)
@@ -72,11 +72,13 @@ $(TARGET_EXE): $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe
 !ELSE\r
 $(TARGET_EXE): $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj $(LIBS) $(TARGET_EXE_LIBS)\r
   $(LINK) /DEBUG $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj $(TARGET_EXE_LIBS)\r
+!IF ("$(EFI_BINARY_BUILD)" == "YES")\r
   if not exist $(EFI_PLATFORM_BIN)\Tools mkdir $(EFI_PLATFORM_BIN)\Tools\r
   if exist $(TARGET_EXE) copy $(TARGET_EXE) $(EFI_PLATFORM_BIN)\tools\$(TARGET_NAME).exe /Y\r
   if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb \\r
   copy $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb /Y\r
 !ENDIF\r
+!ENDIF\r
 \r
 clean:\r
   @if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL\r
diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/GenTEImage/GenTEImage.c b/EdkCompatibilityPkg/Sample/Tools/Source/GenTEImage/GenTEImage.c
new file mode 100644 (file)
index 0000000..6f22782
--- /dev/null
@@ -0,0 +1,929 @@
+/*++\r
+\r
+Copyright (c) 1999 - 2007, Intel Corporation                                                         \r
+All rights reserved. This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+  GenTEImage.c\r
+\r
+Abstract:\r
+\r
+  Utility program to shrink a PE32 image down by replacing\r
+  the DOS, PE, and optional headers with a minimal header.\r
+\r
+--*/\r
+\r
+#include <stdio.h>\r
+#include <string.h>\r
+#include <stdlib.h>\r
+\r
+#include "Tiano.h"\r
+#include "TianoCommon.h"\r
+#include "EfiImage.h" // for PE32 structure definitions\r
+#include "EfiUtilityMsgs.h"\r
+\r
+//\r
+// Version of this utility\r
+//\r
+#define UTILITY_NAME    "GenTEImage"\r
+#define UTILITY_VERSION "v0.11"\r
+\r
+//\r
+// Define the max length of a filename\r
+//\r
+#define MAX_PATH                  256\r
+#define DEFAULT_OUTPUT_EXTENSION  ".te"\r
+\r
+//\r
+// Use this to track our command-line options and globals\r
+//\r
+struct {\r
+  INT8  OutFileName[MAX_PATH];\r
+  INT8  InFileName[MAX_PATH];\r
+  INT8  Verbose;\r
+  INT8  Dump;\r
+} mOptions;\r
+\r
+//\r
+// Use these to convert from machine type value to a named type\r
+//\r
+typedef struct {\r
+  UINT16  Value;\r
+  INT8    *Name;\r
+} STRING_LOOKUP;\r
+\r
+static STRING_LOOKUP  mMachineTypes[] = {\r
+  EFI_IMAGE_MACHINE_IA32,\r
+  "IA32",\r
+  EFI_IMAGE_MACHINE_IA64,\r
+  "IA64",\r
+  EFI_IMAGE_MACHINE_X64,\r
+  "X64",\r
+  EFI_IMAGE_MACHINE_EBC,\r
+  "EBC",\r
+  0,\r
+  NULL\r
+};\r
+\r
+static STRING_LOOKUP  mSubsystemTypes[] = {\r
+  EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION,\r
+  "EFI application",\r
+  EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER,\r
+  "EFI boot service driver",\r
+  EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER,\r
+  "EFI runtime driver",\r
+  0,\r
+  NULL\r
+};\r
+//\r
+//  Function prototypes\r
+//\r
+static\r
+void\r
+Usage (\r
+  VOID\r
+  );\r
+\r
+static\r
+STATUS\r
+ParseCommandLine (\r
+  int       Argc,\r
+  char      *Argv[]\r
+  );\r
+\r
+static\r
+STATUS\r
+CheckPE32File (\r
+  INT8      *FileName,\r
+  FILE      *Fptr,\r
+  UINT16    *MachineType,\r
+  UINT16    *SubSystem\r
+  );\r
+\r
+static\r
+STATUS\r
+ProcessFile (\r
+  INT8      *InFileName,\r
+  INT8      *OutFileName\r
+  );\r
+\r
+static\r
+void\r
+DumpImage (\r
+  INT8      *FileName\r
+  );\r
+\r
+static\r
+INT8                  *\r
+GetMachineTypeStr (\r
+  UINT16    MachineType\r
+  );\r
+\r
+static\r
+INT8                  *\r
+GetSubsystemTypeStr (\r
+  UINT16  SubsystemType\r
+  );\r
+\r
+int\r
+main (\r
+  int   Argc,\r
+  char  *Argv[]\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  \r
+\r
+Arguments:\r
+\r
+  Argc            - standard C main() argument count\r
+\r
+  Argv            - standard C main() argument list\r
+\r
+Returns:\r
+\r
+  0             success\r
+  non-zero      otherwise\r
+\r
+--*/\r
+// GC_TODO:    ] - add argument and description to function comment\r
+{\r
+  INT8    *Ext;\r
+  UINT32  Status;\r
+\r
+  SetUtilityName (UTILITY_NAME);\r
+  //\r
+  // Parse the command line arguments\r
+  //\r
+  if (ParseCommandLine (Argc, Argv)) {\r
+    return STATUS_ERROR;\r
+  }\r
+  //\r
+  // If dumping an image, then do that and quit\r
+  //\r
+  if (mOptions.Dump) {\r
+    DumpImage (mOptions.InFileName);\r
+    goto Finish;\r
+  }\r
+  //\r
+  // Determine the output filename. Either what they specified on\r
+  // the command line, or the first input filename with a different extension.\r
+  //\r
+  if (!mOptions.OutFileName[0]) {\r
+    strcpy (mOptions.OutFileName, mOptions.InFileName);\r
+    //\r
+    // Find the last . on the line and replace the filename extension with\r
+    // the default\r
+    //\r
+    for (Ext = mOptions.OutFileName + strlen (mOptions.OutFileName) - 1;\r
+         (Ext >= mOptions.OutFileName) && (*Ext != '.') && (*Ext != '\\');\r
+         Ext--\r
+        )\r
+      ;\r
+    //\r
+    // If dot here, then insert extension here, otherwise append\r
+    //\r
+    if (*Ext != '.') {\r
+      Ext = mOptions.OutFileName + strlen (mOptions.OutFileName);\r
+    }\r
+\r
+    strcpy (Ext, DEFAULT_OUTPUT_EXTENSION);\r
+  }\r
+  //\r
+  // Make sure we don't have the same filename for input and output files\r
+  //\r
+  if (_stricmp (mOptions.OutFileName, mOptions.InFileName) == 0) {\r
+    Error (NULL, 0, 0, mOptions.OutFileName, "input and output file names must be different");\r
+    goto Finish;\r
+  }\r
+  //\r
+  // Process the file\r
+  //\r
+  ProcessFile (mOptions.InFileName, mOptions.OutFileName);\r
+Finish:\r
+  Status = GetUtilityStatus ();\r
+  return Status;\r
+}\r
+\r
+static\r
+STATUS\r
+ProcessFile (\r
+  INT8      *InFileName,\r
+  INT8      *OutFileName\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  \r
+  Process a PE32 EFI file.\r
+\r
+Arguments:\r
+  \r
+  InFileName      - the file name pointer to the input file\r
+  OutFileName     - the file name pointer to the output file\r
+\r
+Returns:\r
+\r
+  STATUS_SUCCESS  - the process has been finished successfully\r
+  STATUS_ERROR    - error occured during the processing\r
+\r
+--*/\r
+{\r
+  STATUS                      Status;\r
+  FILE                        *InFptr;\r
+  FILE                        *OutFptr;\r
+  UINT16                      MachineType;\r
+  UINT16                      SubSystem;\r
+  EFI_TE_IMAGE_HEADER         TEImageHeader;\r
+  UINT32                      PESigOffset;\r
+  EFI_IMAGE_FILE_HEADER       FileHeader;\r
+  EFI_IMAGE_OPTIONAL_HEADER32 OptionalHeader32;\r
+  EFI_IMAGE_OPTIONAL_HEADER64 OptionalHeader64;\r
+  UINT32                      BytesStripped;\r
+  UINT32                      FileSize;\r
+  UINT8                       *Buffer;\r
+  long                        SaveFilePosition;\r
+\r
+  InFptr  = NULL;\r
+  OutFptr = NULL;\r
+  Buffer  = NULL;\r
+  Status  = STATUS_ERROR;\r
+\r
+  //\r
+  // Try to open the input file\r
+  //\r
+  if ((InFptr = fopen (InFileName, "rb")) == NULL) {\r
+    Error (NULL, 0, 0, InFileName, "failed to open input file for reading");\r
+    return STATUS_ERROR;\r
+  }\r
+  //\r
+  // Double-check the file to make sure it's what we expect it to be\r
+  //\r
+  if (CheckPE32File (InFileName, InFptr, &MachineType, &SubSystem) != STATUS_SUCCESS) {\r
+    goto Finish;\r
+  }\r
+  //\r
+  // Initialize our new header\r
+  //\r
+  memset (&TEImageHeader, 0, sizeof (EFI_TE_IMAGE_HEADER));\r
+\r
+  //\r
+  // Seek to the end to get the file size\r
+  //\r
+  fseek (InFptr, 0, SEEK_END);\r
+  FileSize = ftell (InFptr);\r
+  fseek (InFptr, 0, SEEK_SET);\r
+\r
+  //\r
+  // Per the PE/COFF specification, at offset 0x3C in the file is a 32-bit\r
+  // offset (from the start of the file) to the PE signature, which always\r
+  // follows the MSDOS stub. The PE signature is immediately followed by the\r
+  // COFF file header.\r
+  //\r
+  //\r
+  if (fseek (InFptr, 0x3C, SEEK_SET) != 0) {\r
+    Error (NULL, 0, 0, InFileName, "failed to seek to PE signature in file", NULL);\r
+    goto Finish;\r
+  }\r
+\r
+  if (fread (&PESigOffset, sizeof (PESigOffset), 1, InFptr) != 1) {\r
+    Error (NULL, 0, 0, InFileName, "failed to read PE signature offset from file");\r
+    goto Finish;\r
+  }\r
+\r
+  if (fseek (InFptr, PESigOffset + 4, SEEK_SET) != 0) {\r
+    Error (NULL, 0, 0, InFileName, "failed to seek to PE signature");\r
+    goto Finish;\r
+  }\r
+  //\r
+  // We should now be at the COFF file header. Read it in and verify it's\r
+  // of an image type we support.\r
+  //\r
+  if (fread (&FileHeader, sizeof (EFI_IMAGE_FILE_HEADER), 1, InFptr) != 1) {\r
+    Error (NULL, 0, 0, InFileName, "failed to read file header from image");\r
+    goto Finish;\r
+  }\r
+\r
+  if ((FileHeader.Machine != EFI_IMAGE_MACHINE_IA32) &&\r
+      (FileHeader.Machine != EFI_IMAGE_MACHINE_X64) &&\r
+      (FileHeader.Machine != EFI_IMAGE_MACHINE_IA64)) {\r
+    Error (NULL, 0, 0, InFileName, "image is of an unsupported machine type 0x%X", (UINT32) FileHeader.Machine);\r
+    goto Finish;\r
+  }\r
+  //\r
+  // Calculate the total number of bytes we're going to strip off. The '4' is for the\r
+  // PE signature PE\0\0. Then sanity check the size.\r
+  //\r
+  BytesStripped = PESigOffset + 4 + sizeof (EFI_IMAGE_FILE_HEADER) + FileHeader.SizeOfOptionalHeader;\r
+  if (BytesStripped >= FileSize) {\r
+    Error (NULL, 0, 0, InFileName, "attempt to strip more bytes than the total file size");\r
+    goto Finish;\r
+  }\r
+\r
+  if (BytesStripped &~0xFFFF) {\r
+    Error (NULL, 0, 0, InFileName, "attempt to strip more than 64K bytes", NULL);\r
+    goto Finish;\r
+  }\r
+\r
+  TEImageHeader.StrippedSize = (UINT16) BytesStripped;\r
+\r
+  //\r
+  // Read in the optional header. Assume PE32, and if not, then re-read as PE32+\r
+  //\r
+  SaveFilePosition = ftell (InFptr);\r
+  if (fread (&OptionalHeader32, sizeof (EFI_IMAGE_OPTIONAL_HEADER32), 1, InFptr) != 1) {\r
+    Error (NULL, 0, 0, InFileName, "failed to read optional header from input file");\r
+    goto Finish;\r
+  }\r
+\r
+  if (OptionalHeader32.SectionAlignment != OptionalHeader32.FileAlignment) {\r
+    Error (NULL, 0, 0, InFileName, "Section alignment is not same to file alignment.");\r
+    goto Finish;\r
+  }\r
+\r
+  if (OptionalHeader32.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+    //\r
+    // Fill in our new header with required data directory entries\r
+    //\r
+    TEImageHeader.AddressOfEntryPoint = OptionalHeader32.AddressOfEntryPoint;\r
+    //\r
+    // - BytesStripped + sizeof (EFI_TE_IMAGE_HEADER);\r
+    //\r
+    // We're going to pack the subsystem into 1 byte. Make sure it fits\r
+    //\r
+    if (OptionalHeader32.Subsystem &~0xFF) {\r
+      Error (\r
+        NULL,\r
+        0,\r
+        0,\r
+        InFileName,\r
+        NULL,\r
+        "image subsystem 0x%X cannot be packed into 1 byte",\r
+        (UINT32) OptionalHeader32.Subsystem\r
+        );\r
+      goto Finish;\r
+    }\r
+\r
+    TEImageHeader.Subsystem   = (UINT8) OptionalHeader32.Subsystem;\r
+    TEImageHeader.BaseOfCode  = OptionalHeader32.BaseOfCode;\r
+    TEImageHeader.ImageBase   = (UINT64) (OptionalHeader32.ImageBase);\r
+    if (OptionalHeader32.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {\r
+      TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = OptionalHeader32.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;\r
+      TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = OptionalHeader32.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;\r
+    }\r
+\r
+    if (OptionalHeader32.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {\r
+      TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = OptionalHeader32.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;\r
+      TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = OptionalHeader32.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size;\r
+    }\r
+  } else if (OptionalHeader32.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {\r
+    //\r
+    // Rewind and re-read the optional header\r
+    //\r
+    fseek (InFptr, SaveFilePosition, SEEK_SET);\r
+    if (fread (&OptionalHeader64, sizeof (EFI_IMAGE_OPTIONAL_HEADER64), 1, InFptr) != 1) {\r
+      Error (NULL, 0, 0, InFileName, "failed to re-read optional header from input file");\r
+      goto Finish;\r
+    }\r
+\r
+    TEImageHeader.AddressOfEntryPoint = OptionalHeader64.AddressOfEntryPoint;\r
+    //\r
+    // - BytesStripped + sizeof (EFI_TE_IMAGE_HEADER);\r
+    //\r
+    // We're going to pack the subsystem into 1 byte. Make sure it fits\r
+    //\r
+    if (OptionalHeader64.Subsystem &~0xFF) {\r
+      Error (\r
+        NULL,\r
+        0,\r
+        0,\r
+        InFileName,\r
+        NULL,\r
+        "image subsystem 0x%X cannot be packed into 1 byte",\r
+        (UINT32) OptionalHeader64.Subsystem\r
+        );\r
+      goto Finish;\r
+    }\r
+\r
+    TEImageHeader.Subsystem   = (UINT8) OptionalHeader64.Subsystem;\r
+    TEImageHeader.BaseOfCode  = OptionalHeader64.BaseOfCode;\r
+    TEImageHeader.ImageBase = (UINT64) (OptionalHeader64.ImageBase);\r
+    if (OptionalHeader64.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {\r
+      TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = OptionalHeader64.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;\r
+      TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = OptionalHeader64.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;\r
+    }\r
+\r
+    if (OptionalHeader64.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {\r
+      TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = OptionalHeader64.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;\r
+      TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = OptionalHeader64.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size;\r
+    }\r
+  } else {\r
+    Error (\r
+      NULL,\r
+      0,\r
+      0,\r
+      InFileName,\r
+      "unsupported magic number 0x%X found in optional header",\r
+      (UINT32) OptionalHeader32.Magic\r
+      );\r
+    goto Finish;\r
+  }\r
+  //\r
+  // Fill in the remainder of our new image header\r
+  //\r
+  TEImageHeader.Signature = EFI_TE_IMAGE_HEADER_SIGNATURE;\r
+  TEImageHeader.Machine   = FileHeader.Machine;\r
+  //\r
+  // We're going to pack the number of sections into a single byte. Make sure it fits.\r
+  //\r
+  if (FileHeader.NumberOfSections &~0xFF) {\r
+    Error (\r
+      NULL,\r
+      0,\r
+      0,\r
+      InFileName,\r
+      NULL,\r
+      "image's number of sections 0x%X cannot be packed into 1 byte",\r
+      (UINT32) FileHeader.NumberOfSections\r
+      );\r
+    goto Finish;\r
+  }\r
+\r
+  TEImageHeader.NumberOfSections = (UINT8) FileHeader.NumberOfSections;\r
+\r
+  //\r
+  // Now open our output file\r
+  //\r
+  if ((OutFptr = fopen (OutFileName, "wb")) == NULL) {\r
+    Error (NULL, 0, 0, OutFileName, "failed to open output file for writing");\r
+    goto Finish;\r
+  }\r
+  //\r
+  // Write the TE header\r
+  //\r
+  if (fwrite (&TEImageHeader, sizeof (EFI_TE_IMAGE_HEADER), 1, OutFptr) != 1) {\r
+    Error (NULL, 0, 0, "failed to write image header to output file", NULL);\r
+    goto Finish;\r
+  }\r
+  //\r
+  // Position into the input file, read the part we're not stripping, and\r
+  // write it out.\r
+  //\r
+  fseek (InFptr, BytesStripped, SEEK_SET);\r
+  Buffer = (UINT8 *) malloc (FileSize - BytesStripped);\r
+  if (Buffer == NULL) {\r
+    Error (NULL, 0, 0, "application error", "failed to allocate memory");\r
+    goto Finish;\r
+  }\r
+\r
+  if (fread (Buffer, FileSize - BytesStripped, 1, InFptr) != 1) {\r
+    Error (NULL, 0, 0, InFileName, "failed to read remaining contents of input file");\r
+    goto Finish;\r
+  }\r
+\r
+  if (fwrite (Buffer, FileSize - BytesStripped, 1, OutFptr) != 1) {\r
+    Error (NULL, 0, 0, OutFileName, "failed to write all bytes to output file");\r
+    goto Finish;\r
+  }\r
+\r
+  Status = STATUS_SUCCESS;\r
+\r
+Finish:\r
+  if (InFptr != NULL) {\r
+    fclose (InFptr);\r
+  }\r
+  //\r
+  // Close the output file. If there was an error, delete the output file so\r
+  // that a subsequent build will rebuild it.\r
+  //\r
+  if (OutFptr != NULL) {\r
+    fclose (OutFptr);\r
+    if (GetUtilityStatus () == STATUS_ERROR) {\r
+      remove (OutFileName);\r
+    }\r
+  }\r
+\r
+  //\r
+  // Free up our buffer\r
+  //\r
+  if (Buffer != NULL) {\r
+    free (Buffer);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+static\r
+STATUS\r
+CheckPE32File (\r
+  INT8      *FileName,\r
+  FILE      *Fptr,\r
+  UINT16    *MachineType,\r
+  UINT16    *SubSystem\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  FileName    - GC_TODO: add argument description\r
+  Fptr        - GC_TODO: add argument description\r
+  MachineType - GC_TODO: add argument description\r
+  SubSystem   - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+  /*++\r
+\r
+Routine Description:\r
+  \r
+  Given a file pointer to a supposed PE32 image file, verify that it is indeed a\r
+  PE32 image file, and then return the machine type in the supplied pointer.\r
+\r
+Arguments:\r
+\r
+  Fptr          File pointer to the already-opened PE32 file\r
+  MachineType   Location to stuff the machine type of the PE32 file. This is needed\r
+                because the image may be Itanium-based, IA32, or EBC.\r
+\r
+Returns:\r
+\r
+  0             success\r
+  non-zero      otherwise\r
+\r
+--*/\r
+  EFI_IMAGE_DOS_HEADER      DosHeader;\r
+  EFI_IMAGE_FILE_HEADER     FileHdr;\r
+  EFI_IMAGE_OPTIONAL_HEADER OptionalHdr;\r
+  UINT32                    PESig;\r
+  STATUS                    Status;\r
+\r
+  Status = STATUS_ERROR;\r
+  //\r
+  // Position to the start of the file\r
+  //\r
+  fseek (Fptr, 0, SEEK_SET);\r
+  //\r
+  // Read the DOS header\r
+  //\r
+  if (fread (&DosHeader, sizeof (DosHeader), 1, Fptr) != 1) {\r
+    Error (NULL, 0, 0, FileName, "failed to read the DOS stub from the input file");\r
+    goto Finish;\r
+  }\r
+  //\r
+  // Check the magic number (0x5A4D)\r
+  //\r
+  if (DosHeader.e_magic != EFI_IMAGE_DOS_SIGNATURE) {\r
+    Error (NULL, 0, 0, FileName, "input file does not appear to be a PE32 image (magic number)");\r
+    goto Finish;\r
+  }\r
+  //\r
+  // Position into the file and check the PE signature\r
+  //\r
+  fseek (Fptr, (long) DosHeader.e_lfanew, SEEK_SET);\r
+  if (fread (&PESig, sizeof (PESig), 1, Fptr) != 1) {\r
+    Error (NULL, 0, 0, FileName, "failed to read PE signature bytes");\r
+    goto Finish;\r
+  }\r
+  //\r
+  // Check the PE signature in the header "PE\0\0"\r
+  //\r
+  if (PESig != EFI_IMAGE_NT_SIGNATURE) {\r
+    Error (NULL, 0, 0, FileName, "file does not appear to be a PE32 image (signature)");\r
+    goto Finish;\r
+  }\r
+  //\r
+  // Read the file header\r
+  //\r
+  if (fread (&FileHdr, sizeof (FileHdr), 1, Fptr) != 1) {\r
+    Error (NULL, 0, 0, FileName, "failed to read PE file header from input file");\r
+    goto Finish;\r
+  }\r
+  //\r
+  // Read the optional header so we can get the subsystem\r
+  //\r
+  if (fread (&OptionalHdr, sizeof (OptionalHdr), 1, Fptr) != 1) {\r
+    Error (NULL, 0, 0, FileName, "failed to read COFF optional header from input file");\r
+    goto Finish;\r
+  }\r
+\r
+  *SubSystem = OptionalHdr.Subsystem;\r
+  if (mOptions.Verbose) {\r
+    fprintf (stdout, "  Got subsystem = 0x%X from image\n", (int) *SubSystem);\r
+  }\r
+  //\r
+  // Good to go\r
+  //\r
+  Status = STATUS_SUCCESS;\r
+Finish:\r
+  fseek (Fptr, 0, SEEK_SET);\r
+  return Status;\r
+}\r
+\r
+static\r
+int\r
+ParseCommandLine (\r
+  int         Argc,\r
+  char        *Argv[]\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  \r
+  Given the Argc/Argv program arguments, and a pointer to an options structure,\r
+  parse the command-line options and check their validity.\r
+\r
+\r
+Arguments:\r
+\r
+  Argc            - standard C main() argument count\r
+  Argv            - standard C main() argument list\r
+\r
+Returns:\r
+\r
+  STATUS_SUCCESS    success\r
+  non-zero          otherwise\r
+\r
+--*/\r
+// GC_TODO:    ] - add argument and description to function comment\r
+{\r
+  //\r
+  // Clear out the options\r
+  //\r
+  memset ((char *) &mOptions, 0, sizeof (mOptions));\r
+  //\r
+  // Skip over the program name\r
+  //\r
+  Argc--;\r
+  Argv++;\r
+  //\r
+  // If no arguments, assume they want usage info\r
+  //\r
+  if (Argc == 0) {\r
+    Usage ();\r
+    return STATUS_ERROR;\r
+  }\r
+  //\r
+  // Process until no more arguments\r
+  //\r
+  while ((Argc > 0) && ((Argv[0][0] == '-') || (Argv[0][0] == '/'))) {\r
+    //\r
+    // To simplify string comparisons, replace slashes with dashes\r
+    //\r
+    Argv[0][0] = '-';\r
+    if (_stricmp (Argv[0], "-o") == 0) {\r
+      //\r
+      // Output filename specified with -o\r
+      // Make sure there's another parameter\r
+      //\r
+      if (Argc > 1) {\r
+        strcpy (mOptions.OutFileName, Argv[1]);\r
+      } else {\r
+        Error (NULL, 0, 0, Argv[0], "missing output file name with option");\r
+        Usage ();\r
+        return STATUS_ERROR;\r
+      }\r
+\r
+      Argv++;\r
+      Argc--;\r
+    } else if ((_stricmp (Argv[0], "-h") == 0) || (strcmp (Argv[0], "-?") == 0)) {\r
+      //\r
+      // Help option\r
+      //\r
+      Usage ();\r
+      return STATUS_ERROR;\r
+    } else if (_stricmp (Argv[0], "-v") == 0) {\r
+      //\r
+      // -v for verbose\r
+      //\r
+      mOptions.Verbose = 1;\r
+    } else if (_stricmp (Argv[0], "-dump") == 0) {\r
+      //\r
+      // -dump for dumping an image\r
+      //\r
+      mOptions.Dump = 1;\r
+    } else {\r
+      Error (NULL, 0, 0, Argv[0], "unrecognized option");\r
+      Usage ();\r
+      return STATUS_ERROR;\r
+    }\r
+    //\r
+    // Next argument\r
+    //\r
+    Argv++;\r
+    Argc--;\r
+  }\r
+  //\r
+  // Better be one more arg for input file name\r
+  //\r
+  if (Argc == 0) {\r
+    Error (NULL, 0, 0, "input file name required", NULL);\r
+    Usage ();\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  if (Argc != 1) {\r
+    Error (NULL, 0, 0, Argv[1], "extra arguments on command line");\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  strcpy (mOptions.InFileName, Argv[0]);\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+static\r
+void\r
+Usage (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  \r
+  Print usage information for this utility.\r
+\r
+Arguments:\r
+\r
+  None.\r
+\r
+Returns:\r
+\r
+  Nothing.\r
+\r
+--*/\r
+{\r
+  int               Index;\r
+  static const char *Msg[] = {\r
+    UTILITY_NAME " version "UTILITY_VERSION " - TE image utility",\r
+    "  Generate a TE image from an EFI PE32 image",\r
+    "  Usage: "UTILITY_NAME " {-v} {-dump} {-h|-?} {-o OutFileName} InFileName",\r
+    "                [-e|-b] [FileName(s)]",\r
+    "    where:",\r
+    "      -v             - for verbose output",\r
+    "      -dump          - to dump the input file to a text file",\r
+    "      -h -?          - for this help information",\r
+    "      -o OutFileName - to write output to OutFileName rather than InFileName"DEFAULT_OUTPUT_EXTENSION,\r
+    "      InFileName     - name of the input PE32 file",\r
+    "",\r
+    NULL\r
+  };\r
+  for (Index = 0; Msg[Index] != NULL; Index++) {\r
+    fprintf (stdout, "%s\n", Msg[Index]);\r
+  }\r
+}\r
+\r
+static\r
+VOID\r
+DumpImage (\r
+  INT8    *FileName\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  \r
+  Dump a specified image information\r
+\r
+Arguments:\r
+  \r
+  FileName - File name pointer to the image to dump\r
+\r
+Returns:\r
+\r
+  Nothing.\r
+\r
+--*/\r
+{\r
+  FILE                *InFptr;\r
+  EFI_TE_IMAGE_HEADER TEImageHeader;\r
+  INT8                *NamePtr;\r
+\r
+  //\r
+  // Open the input file\r
+  //\r
+  InFptr  = NULL;\r
+\r
+  if ((InFptr = fopen (FileName, "rb")) == NULL) {\r
+    Error (NULL, 0, 0, FileName, "failed to open input file for reading");\r
+    return ;\r
+  }\r
+\r
+  if (fread (&TEImageHeader, sizeof (EFI_TE_IMAGE_HEADER), 1, InFptr) != 1) {\r
+    Error (NULL, 0, 0, FileName, "failed to read image header from input file");\r
+    goto Finish;\r
+  }\r
+\r
+  if (TEImageHeader.Signature != EFI_TE_IMAGE_HEADER_SIGNATURE) {\r
+    Error (NULL, 0, 0, FileName, "Image does not appear to be a TE image (bad signature)");\r
+    goto Finish;\r
+  }\r
+  //\r
+  // Dump the header\r
+  //\r
+  fprintf (stdout, "Header (%d bytes):\n", sizeof (EFI_TE_IMAGE_HEADER));\r
+  fprintf (stdout, "  Signature:          0x%04X (TE)\n", (UINT32) TEImageHeader.Signature);\r
+  NamePtr = GetMachineTypeStr (TEImageHeader.Machine);\r
+  fprintf (stdout, "  Machine:            0x%04X (%s)\n", (UINT32) TEImageHeader.Machine, NamePtr);\r
+  NamePtr = GetSubsystemTypeStr (TEImageHeader.Subsystem);\r
+  fprintf (stdout, "  Subsystem:          0x%02X (%s)\n", (UINT32) TEImageHeader.Subsystem, NamePtr);\r
+  fprintf (stdout, "  Number of sections  0x%02X\n", (UINT32) TEImageHeader.NumberOfSections);\r
+  fprintf (stdout, "  Stripped size:      0x%04X\n", (UINT32) TEImageHeader.StrippedSize);\r
+  fprintf (stdout, "  Entry point:        0x%08X\n", TEImageHeader.AddressOfEntryPoint);\r
+  fprintf (stdout, "  Base of code:       0x%08X\n", TEImageHeader.BaseOfCode);\r
+  fprintf (stdout, "  Data directories:\n");\r
+  fprintf (\r
+    stdout,\r
+    "    %8X [%8X] RVA [size] of Base Relocation Directory\n",\r
+    TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress,\r
+    TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size\r
+    );\r
+  fprintf (\r
+    stdout,\r
+    "    %8X [%8X] RVA [size] of Debug Directory\n",\r
+    TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress,\r
+    TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size\r
+    );\r
+\r
+Finish:\r
+  if (InFptr != NULL) {\r
+    fclose (InFptr);\r
+  }\r
+}\r
+\r
+static\r
+INT8 *\r
+GetMachineTypeStr (\r
+  UINT16    MachineType\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  MachineType - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+  int Index;\r
+\r
+  for (Index = 0; mMachineTypes[Index].Name != NULL; Index++) {\r
+    if (mMachineTypes[Index].Value == MachineType) {\r
+      return mMachineTypes[Index].Name;\r
+    }\r
+  }\r
+\r
+  return "unknown";\r
+}\r
+\r
+static\r
+INT8 *\r
+GetSubsystemTypeStr (\r
+  UINT16  SubsystemType\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  SubsystemType - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+  int Index;\r
+\r
+  for (Index = 0; mSubsystemTypes[Index].Name != NULL; Index++) {\r
+    if (mSubsystemTypes[Index].Value == SubsystemType) {\r
+      return mSubsystemTypes[Index].Name;\r
+    }\r
+  }\r
+\r
+  return "unknown";\r
+}\r
diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/GenTEImage/Makefile b/EdkCompatibilityPkg/Sample/Tools/Source/GenTEImage/Makefile
new file mode 100644 (file)
index 0000000..3799877
--- /dev/null
@@ -0,0 +1,85 @@
+#/*++\r
+#\r
+#  Copyright (c) 2002 - 2007, Intel Corporation                                                         \r
+#  All rights reserved. This program and the accompanying materials                          \r
+#  are licensed and made available under the terms and conditions of the BSD License         \r
+#  which accompanies this distribution.  The full text of the license may be found at        \r
+#  http://opensource.org/licenses/bsd-license.php                                            \r
+#                                                                                            \r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+#  \r
+#  Module Name:  \r
+#\r
+#    makefile\r
+#\r
+#  Abstract:\r
+#\r
+#    makefile for building the GenTEImage utility.\r
+#\r
+#--*/\r
+\r
+#\r
+# Make sure environmental variable EDK_SOURCE is set\r
+#\r
+!IFNDEF EDK_SOURCE\r
+!ERROR EDK_SOURCE environmental variable not set \r
+!ENDIF\r
+\r
+#\r
+# Define the toolchain which is used to set build options and toolchain paths\r
+#\r
+TOOLCHAIN = TOOLCHAIN_MSVC\r
+\r
+!INCLUDE $(BUILD_DIR)\PlatformTools.env\r
+\r
+#\r
+# Target specific information\r
+#\r
+\r
+TARGET_NAME         = GenTEImage\r
+TARGET_SRC_DIR      = $(EDK_TOOLS_SOURCE)\$(TARGET_NAME)\r
+TARGET_EXE          = $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).exe\r
+\r
+#\r
+# Build targets\r
+#\r
+\r
+all: $(TARGET_EXE)\r
+\r
+OBJECTS   = $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj \r
+\r
+LIBS      = $(EDK_TOOLS_OUTPUT)\Common.lib\r
+\r
+INC_DEPS  = $(EDK_SOURCE)\Foundation\Efi\Include\EfiImage.h\r
+          \r
+#\r
+# Build the EXE by compiling the source files, then linking the resultant\r
+# object files together.\r
+#\r
+\r
+$(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj : $(TARGET_SRC_DIR)\$(TARGET_NAME).c $(INC_DEPS)\r
+  $(CC) $(C_FLAGS) $(TARGET_SRC_DIR)\$(TARGET_NAME).c /Fo$@\r
+\r
+#\r
+# Add Binary Build description for this tools.\r
+#\r
+\r
+!IF (("$(EFI_BINARY_TOOLS)" == "YES") && EXIST($(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe))\r
+$(TARGET_EXE): $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe\r
+  copy $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe $(TARGET_EXE) /Y\r
+  if exist $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb \\r
+  copy $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb /Y\r
+!ELSE\r
+$(TARGET_EXE) : $(OBJECTS) $(LIBS)\r
+  $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(OBJECTS)\r
+!IF ("$(EFI_BINARY_BUILD)" == "YES")\r
+  if not exist $(EFI_PLATFORM_BIN)\Tools mkdir $(EFI_PLATFORM_BIN)\Tools\r
+  if exist $(TARGET_EXE) copy $(TARGET_EXE) $(EFI_PLATFORM_BIN)\tools\$(TARGET_NAME).exe /Y\r
+  if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb \\r
+  copy $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb /Y\r
+!ENDIF\r
+!ENDIF\r
+\r
+clean:\r
+  @if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL\r
index 5aeddd8cadac4cbf5dcdc63e6e7c6df5e808640b..6c029f02029c363355a16199db1cc60d00a801ea 100644 (file)
@@ -85,11 +85,13 @@ $(TARGET_EXE): $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe
 !ELSE\r
 $(TARGET_EXE) : $(OBJECTS)\r
   $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(OBJECTS)\r
+!IF ("$(EFI_BINARY_BUILD)" == "YES")\r
   if not exist $(EFI_PLATFORM_BIN)\Tools mkdir $(EFI_PLATFORM_BIN)\Tools\r
   if exist $(TARGET_EXE) copy $(TARGET_EXE) $(EFI_PLATFORM_BIN)\tools\$(TARGET_NAME).exe /Y\r
   if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb \\r
   copy $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb /Y\r
 !ENDIF\r
+!ENDIF\r
 \r
 clean:\r
   @if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL\r
index bf086e64a44563b2a8afe64f7b623ee2cc4c0698..fb090bc930eb34950d363ee69e488b31200c26e4 100644 (file)
@@ -1,6 +1,6 @@
 /*++\r
 \r
-Copyright (c) 2004 - 2006, Intel Corporation                                                         \r
+Copyright (c) 2004 - 2007, Intel Corporation                                                         \r
 All rights reserved. This program and the accompanying materials                          \r
 are licensed and made available under the terms and conditions of the BSD License         \r
 which accompanies this distribution.  The full text of the license may be found at        \r
@@ -101,6 +101,12 @@ typedef struct _SYMBOL {
   INT8            *Value;\r
 } SYMBOL;\r
 \r
+typedef enum {\r
+  SearchCurrentDir,\r
+  SearchIncludePaths,\r
+  SearchAllPaths,\r
+} FILE_SEARCH_TYPE;\r
+\r
 //\r
 // Here's all our globals. We need a linked list of include paths, a linked\r
 // list of source files, a linked list of subdirectories (appended to each\r
@@ -108,6 +114,7 @@ typedef struct _SYMBOL {
 //\r
 static struct {\r
   STRING_LIST *IncludePaths;            // all include paths to search\r
+  STRING_LIST *ParentPaths;             // all parent paths to search\r
   STRING_LIST *SourceFiles;             // all source files to parse\r
   STRING_LIST *SubDirs;                 // appended to each include path when searching\r
   SYMBOL      *SymbolTable;             // for replacement strings\r
@@ -120,25 +127,37 @@ static struct {
   BOOLEAN     NoDupes;                  // to not list duplicate dependency files (for timing purposes)\r
   BOOLEAN     UseSumDeps;               // use summary dependency files if found\r
   BOOLEAN     IsAsm;                    // The SourceFiles are assembler files\r
+  BOOLEAN     IsCl;                     // The SourceFiles are the output of cl with /showIncludes\r
   INT8        TargetFileName[MAX_PATH]; // target object filename\r
   INT8        SumDepsPath[MAX_PATH];    // path to summary files\r
+  INT8        TmpFileName[MAX_PATH];    // temp file name for output file\r
   INT8        *OutFileName;             // -o option\r
 } mGlobals;\r
 \r
 static\r
 STATUS\r
 ProcessFile (\r
+  INT8              *TargetFileName,\r
+  INT8              *FileName,\r
+  UINT32            NestDepth,\r
+  STRING_LIST       *ProcessedFiles,\r
+  FILE_SEARCH_TYPE  FileSearchType\r
+  );\r
+\r
+static\r
+STATUS\r
+ProcessClOutput (\r
   INT8            *TargetFileName,\r
   INT8            *FileName,\r
-  UINT32          NestDepth,\r
   STRING_LIST     *ProcessedFiles\r
   );\r
 \r
 static\r
 FILE  *\r
 FindFile (\r
-  INT8    *FileName,\r
-  UINT32  FileNameLen\r
+  INT8              *FileName,\r
+  UINT32            FileNameLen,\r
+  FILE_SEARCH_TYPE  FileSearchType\r
   );\r
 \r
 static\r
@@ -258,7 +277,12 @@ Returns:
       strcpy (TargetFileName, mGlobals.TargetFileName);\r
     }\r
 \r
-    Status = ProcessFile (TargetFileName, File->Str, START_NEST_DEPTH, &ProcessedFiles);\r
+    if (mGlobals.IsCl) {\r
+      Status = ProcessClOutput (TargetFileName, File->Str, &ProcessedFiles);\r
+    } else {\r
+      Status = ProcessFile (TargetFileName, File->Str, START_NEST_DEPTH, \r
+                            &ProcessedFiles, SearchCurrentDir);\r
+    }\r
     if (Status != STATUS_SUCCESS) {\r
       goto Finish;\r
     }\r
@@ -282,7 +306,7 @@ Finish:
     ProcessedFiles.Next = TempList;\r
   }\r
   //\r
-  // Close our output file\r
+  // Close our temp output file\r
   //\r
   if ((mGlobals.OutFptr != stdout) && (mGlobals.OutFptr != NULL)) {\r
     fclose (mGlobals.OutFptr);\r
@@ -291,12 +315,22 @@ Finish:
   if (mGlobals.NeverFail) {\r
     return STATUS_SUCCESS;\r
   }\r
-  //\r
-  // If any errors, then delete our output so that it will get created\r
-  // again on a rebuild.\r
-  //\r
-  if ((GetUtilityStatus () == STATUS_ERROR) && (mGlobals.OutFileName != NULL)) {\r
-    remove (mGlobals.OutFileName);\r
+\r
+  if (mGlobals.OutFileName != NULL) {\r
+    if (GetUtilityStatus () == STATUS_ERROR) {\r
+      //\r
+      // If any errors, then delete our temp output\r
+      // Also try to delete target file to improve the incremental build\r
+      //      \r
+      remove (mGlobals.TmpFileName);\r
+      remove (TargetFileName);\r
+    } else {\r
+      //\r
+      // Otherwise, rename temp file to output file\r
+      //\r
+      remove (mGlobals.OutFileName);\r
+      rename (mGlobals.TmpFileName, mGlobals.OutFileName);\r
+    }\r
   }\r
 \r
   return GetUtilityStatus ();\r
@@ -305,10 +339,11 @@ Finish:
 static\r
 STATUS\r
 ProcessFile (\r
-  INT8            *TargetFileName,\r
-  INT8            *FileName,\r
-  UINT32          NestDepth,\r
-  STRING_LIST     *ProcessedFiles\r
+  INT8              *TargetFileName,\r
+  INT8              *FileName,\r
+  UINT32            NestDepth,\r
+  STRING_LIST       *ProcessedFiles,\r
+  FILE_SEARCH_TYPE  FileSearchType\r
   )\r
 /*++\r
 \r
@@ -322,6 +357,7 @@ Arguments:
   FileName       - name of the file to process\r
   NestDepth      - how deep we're nested in includes\r
   ProcessedFiles - list of processed files.\r
+  FileSearchType - search type for FileName\r
 \r
 Returns:\r
 \r
@@ -342,6 +378,7 @@ Returns:
   UINT32      Index;\r
   UINT32      LineNum;\r
   STRING_LIST *ListPtr;\r
+  STRING_LIST ParentPath;\r
 \r
   Status  = STATUS_SUCCESS;\r
   Fptr    = NULL;\r
@@ -380,37 +417,6 @@ Returns:
       return STATUS_SUCCESS;\r
     }\r
   }\r
-  //\r
-  // If we're not doing duplicates, and we've already seen this filename,\r
-  // then return\r
-  //\r
-  if (mGlobals.NoDupes) {\r
-    for (ListPtr = ProcessedFiles->Next; ListPtr != NULL; ListPtr = ListPtr->Next) {\r
-      if (_stricmp (FileName, ListPtr->Str) == 0) {\r
-        break;\r
-      }\r
-    }\r
-    //\r
-    // If we found a match, we're done. If we didn't, create a new element\r
-    // and add it to the list.\r
-    //\r
-    if (ListPtr != NULL) {\r
-      //\r
-      // Print a message if verbose mode\r
-      //\r
-      if (mGlobals.Verbose) {\r
-        DebugMsg (NULL, 0, 0, FileName, "duplicate include -- not processed again");\r
-      }\r
-\r
-      return STATUS_SUCCESS;\r
-    }\r
-\r
-    ListPtr       = malloc (sizeof (STRING_LIST));\r
-    ListPtr->Str  = malloc (strlen (FileName) + 1);\r
-    strcpy (ListPtr->Str, FileName);\r
-    ListPtr->Next         = ProcessedFiles->Next;\r
-    ProcessedFiles->Next  = ListPtr;\r
-  }\r
 \r
   //\r
   // Make sure we didn't exceed our maximum nesting depth\r
@@ -424,14 +430,20 @@ Returns:
   // if we have to.\r
   //\r
   strcpy (FileNameCopy, FileName);\r
-  //\r
-  // Try to open the file locally\r
-  //\r
-  if ((Fptr = fopen (FileNameCopy, "r")) == NULL) {\r
+  \r
+  if (FileSearchType == SearchCurrentDir) {\r
+    //\r
+    // Try to open the source file locally\r
+    //\r
+    if ((Fptr = fopen (FileNameCopy, "r")) == NULL) {\r
+      Error (NULL, 0, 0, FileNameCopy, "could not open source file");\r
+      return STATUS_ERROR;\r
+    }\r
+  } else {\r
     //\r
     // Try to find it among the paths.\r
     //\r
-    Fptr = FindFile (FileNameCopy, sizeof (FileNameCopy));\r
+    Fptr = FindFile (FileNameCopy, sizeof (FileNameCopy), FileSearchType);\r
     if (Fptr == NULL) {\r
       //\r
       // If this is not the top-level file, and the command-line argument\r
@@ -457,11 +469,58 @@ Returns:
       }\r
     }\r
   }\r
+\r
+  //\r
+  // If we're not doing duplicates, and we've already seen this filename,\r
+  // then return\r
+  //\r
+  if (mGlobals.NoDupes) {\r
+    for (ListPtr = ProcessedFiles->Next; ListPtr != NULL; ListPtr = ListPtr->Next) {\r
+      if (_stricmp (FileNameCopy, ListPtr->Str) == 0) {\r
+        break;\r
+      }\r
+    }\r
+    //\r
+    // If we found a match, we're done. If we didn't, create a new element\r
+    // and add it to the list.\r
+    //\r
+    if (ListPtr != NULL) {\r
+      //\r
+      // Print a message if verbose mode\r
+      //\r
+      if (mGlobals.Verbose) {\r
+        DebugMsg (NULL, 0, 0, FileNameCopy, "duplicate include -- not processed again");\r
+      }\r
+      fclose (Fptr);\r
+      return STATUS_SUCCESS;\r
+    }\r
+\r
+    ListPtr       = malloc (sizeof (STRING_LIST));\r
+    ListPtr->Str  = malloc (strlen (FileNameCopy) + 1);\r
+    strcpy (ListPtr->Str, FileNameCopy);\r
+    ListPtr->Next         = ProcessedFiles->Next;\r
+    ProcessedFiles->Next  = ListPtr;\r
+  }\r
+    \r
   //\r
   // Print the dependency, with string substitution\r
   //\r
   PrintDependency (TargetFileName, FileNameCopy);\r
-\r
+  \r
+  //\r
+  // Get the file path and push to ParentPaths\r
+  //\r
+  Cptr = FileNameCopy + strlen (FileNameCopy) - 1;\r
+  for (; (Cptr > FileNameCopy) && (*Cptr != '\\') && (*Cptr != '/'); Cptr--);\r
+  if ((*Cptr == '\\') || (*Cptr == '/')) {\r
+    *(Cptr + 1) = 0;\r
+  } else {\r
+    strcpy (FileNameCopy, ".\\");\r
+  }\r
+  ParentPath.Next = mGlobals.ParentPaths;\r
+  ParentPath.Str = FileNameCopy;\r
+  mGlobals.ParentPaths = &ParentPath;\r
+  \r
   //\r
   // Now read in lines and find all #include lines. Allow them to indent, and\r
   // to put spaces between the # and include.\r
@@ -523,7 +582,8 @@ Returns:
           // Null terminate the filename and try to process it.\r
           //\r
           *EndPtr = 0;\r
-          Status  = ProcessFile (TargetFileName, Cptr, NestDepth + 1, ProcessedFiles);\r
+          Status  = ProcessFile (TargetFileName, Cptr, NestDepth + 1, \r
+                                 ProcessedFiles, SearchAllPaths);\r
         } else {\r
           //\r
           // Handle special #include MACRO_NAME(file)\r
@@ -579,7 +639,8 @@ Returns:
                 //\r
                 // Process immediately, then break out of the outside FOR loop.\r
                 //\r
-                Status = ProcessFile (TargetFileName, MacroIncludeFileName, NestDepth + 1, ProcessedFiles);\r
+                Status = ProcessFile (TargetFileName, MacroIncludeFileName, NestDepth + 1, \r
+                                      ProcessedFiles, SearchAllPaths);\r
                 break;\r
               }\r
             }\r
@@ -615,12 +676,20 @@ Returns:
             //\r
             // If we're processing it, do it\r
             //\r
-            if ((EndChar != '>') || (!mGlobals.NoSystem)) {\r
+            if (EndChar != '>') {\r
               //\r
               // Null terminate the filename and try to process it.\r
               //\r
               *EndPtr = 0;\r
-              Status  = ProcessFile (TargetFileName, Cptr, NestDepth + 1, ProcessedFiles);\r
+              Status  = ProcessFile (TargetFileName, Cptr, NestDepth + 1, \r
+                                     ProcessedFiles, SearchAllPaths);\r
+            } else if (!mGlobals.NoSystem) {\r
+              //\r
+              // Null terminate the filename and try to process it.\r
+              //\r
+              *EndPtr = 0;\r
+              Status  = ProcessFile (TargetFileName, Cptr, NestDepth + 1, \r
+                                     ProcessedFiles, SearchIncludePaths);\r
             }\r
           } else {\r
             Warning (FileNameCopy, LineNum, 0, "malformed include", "missing closing %c", EndChar);\r
@@ -631,6 +700,10 @@ Returns:
       }\r
     }\r
   }\r
+  //\r
+  // Pop the file path from ParentPaths\r
+  //\r
+  mGlobals.ParentPaths = ParentPath.Next;  \r
 \r
 Finish:\r
   //\r
@@ -643,6 +716,120 @@ Finish:
   return Status;\r
 }\r
 \r
+static\r
+STATUS\r
+ProcessClOutput (\r
+  INT8            *TargetFileName,\r
+  INT8            *FileName,\r
+  STRING_LIST     *ProcessedFiles\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Given a source file name, open the file and parse all "Note: including file: xxx.h" lines.\r
+  \r
+Arguments:\r
+\r
+  TargetFileName - name of the usually .obj target\r
+  FileName       - name of the file to process\r
+  ProcessedFiles - list of processed files.\r
+\r
+Returns:\r
+\r
+  standard status.\r
+  \r
+--*/\r
+{\r
+  FILE        *Fptr;\r
+  INT8        Line[MAX_LINE_LEN];\r
+  INT8        IncludeFileName[MAX_LINE_LEN];\r
+  STRING_LIST *ListPtr;\r
+  BOOLEAN     ClError;\r
+  INT32       Ret;\r
+  INT8        Char;\r
+\r
+  if ((Fptr = fopen (FileName, "r")) == NULL) {\r
+    Error (NULL, 0, 0, FileName, "could not open file for reading");\r
+    return STATUS_ERROR;\r
+  }\r
+  if (fgets (Line, sizeof (Line), Fptr) != NULL) {\r
+    //\r
+    // First line is the source file name, print it\r
+    //\r
+    printf ("%s", Line);\r
+  } else {\r
+    //\r
+    // No output from cl\r
+    //\r
+    fclose (Fptr);\r
+    Error (NULL, 0, 0, NULL, "incorrect cl tool path may be used ");\r
+    return STATUS_ERROR;\r
+  }\r
+  \r
+  ClError = FALSE;\r
+  while (fgets (Line, sizeof (Line), Fptr) != NULL) {\r
+    Ret = sscanf (Line, "Note: including file: %s %c", IncludeFileName, &Char);\r
+    if (Ret == 2) {\r
+      //\r
+      // There is space in include file name. It's VS header file. Ignore it.\r
+      //\r
+      continue;\r
+    } else if ( Ret != 1) {\r
+      //\r
+      // Cl error info, print it\r
+      // the tool will return error code to stop the nmake\r
+      //\r
+      ClError = TRUE;\r
+      printf ("%s", Line);\r
+      continue;\r
+    }\r
+    \r
+    //\r
+    // If we're not doing duplicates, and we've already seen this filename,\r
+    // then continue\r
+    //\r
+    if (mGlobals.NoDupes) {\r
+      for (ListPtr = ProcessedFiles->Next; ListPtr != NULL; ListPtr = ListPtr->Next) {\r
+        if (_stricmp (IncludeFileName, ListPtr->Str) == 0) {\r
+          break;\r
+        }\r
+      }\r
+      //\r
+      // If we found a match, we're done. If we didn't, create a new element\r
+      // and add it to the list.\r
+      //\r
+      if (ListPtr != NULL) {\r
+        //\r
+        // Print a message if verbose mode\r
+        //\r
+        if (mGlobals.Verbose) {\r
+          DebugMsg (NULL, 0, 0, IncludeFileName, "duplicate include -- not processed again");\r
+        }\r
+  \r
+        continue;\r
+      }\r
+  \r
+      ListPtr       = malloc (sizeof (STRING_LIST));\r
+      ListPtr->Str  = malloc (strlen (IncludeFileName) + 1);\r
+      strcpy (ListPtr->Str, IncludeFileName);\r
+      ListPtr->Next         = ProcessedFiles->Next;\r
+      ProcessedFiles->Next  = ListPtr;\r
+    }\r
+    \r
+    PrintDependency (TargetFileName, IncludeFileName);\r
+  }\r
+  \r
+  fclose (Fptr);\r
+  \r
+  if (ClError) {\r
+    Error (NULL, 0, 0, NULL, "cl error");\r
+    return STATUS_ERROR;\r
+  } else {\r
+    return STATUS_SUCCESS;\r
+  }\r
+}\r
+\r
 static\r
 void\r
 PrintDependency (\r
@@ -754,8 +941,9 @@ ReplaceSymbols (
 static\r
 FILE *\r
 FindFile (\r
-  INT8    *FileName,\r
-  UINT32  FileNameLen\r
+  INT8              *FileName,\r
+  UINT32            FileNameLen,\r
+  FILE_SEARCH_TYPE  FileSearchType\r
   )\r
 {\r
   FILE        *Fptr;\r
@@ -766,6 +954,49 @@ FindFile (
   //\r
   // Traverse the list of paths and try to find the file\r
   //\r
+  if (FileSearchType == SearchAllPaths) {\r
+    List = mGlobals.ParentPaths;\r
+    while (List != NULL) {\r
+      //\r
+      // Put the path and filename together\r
+      //\r
+      if (strlen (List->Str) + strlen (FileName) + 1 > sizeof (FullFileName)) {\r
+        Error (\r
+          __FILE__,\r
+          __LINE__,\r
+          0,\r
+          "application error",\r
+          "cannot concatenate '%s' + '%s'",\r
+          List->Str,\r
+          FileName\r
+          );\r
+        return NULL;\r
+      }\r
+      //\r
+      // Append the filename to this include path and try to open the file.\r
+      //\r
+      strcpy (FullFileName, List->Str);\r
+      strcat (FullFileName, FileName);\r
+      if ((Fptr = fopen (FullFileName, "r")) != NULL) {\r
+        //\r
+        // Return the file name\r
+        //\r
+        if (FileNameLen <= strlen (FullFileName)) {\r
+          Error (__FILE__, __LINE__, 0, "application error", "internal path name of insufficient length");\r
+          //\r
+          // fprintf (stdout, "File length > %d: %s\n", FileNameLen, FullFileName);\r
+          //\r
+          return NULL;\r
+        }\r
+  \r
+        strcpy (FileName, FullFileName);\r
+        return Fptr;\r
+      }\r
+  \r
+      List = List->Next;\r
+    }    \r
+  }\r
+  \r
   List = mGlobals.IncludePaths;\r
   while (List != NULL) {\r
     //\r
@@ -846,7 +1077,7 @@ ProcessArgs (
   STRING_LIST *LastIncludePath;\r
   STRING_LIST *LastSourceFile;\r
   SYMBOL      *Symbol;\r
-  int         Index;\r
+\r
   //\r
   // Clear our globals\r
   //\r
@@ -957,50 +1188,7 @@ ProcessArgs (
         Usage ();\r
         return STATUS_ERROR;\r
       }\r
-      //\r
-      // The C compiler first looks for #include files in the directory where\r
-      // the source file came from. Add the file's source directory to the\r
-      // list of include paths.\r
-      //\r
-      NewList = malloc (sizeof (STRING_LIST));\r
-      if (NewList == NULL) {\r
-        Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);\r
-        return STATUS_ERROR;\r
-      }\r
-\r
-      NewList->Next = NULL;\r
-      NewList->Str  = malloc (strlen (Argv[1]) + 3);\r
-      if (NewList->Str == NULL) {\r
-        free (NewList);\r
-        Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);\r
-        return STATUS_ERROR;\r
-      }\r
-\r
-      strcpy (NewList->Str, Argv[1]);\r
-      //\r
-      // Back up in the source file name to the last backslash and terminate after it.\r
-      //\r
-      for (Index = strlen (NewList->Str) - 1; (Index > 0) && (NewList->Str[Index] != '\\'); Index--)\r
-        ;\r
-      if (Index < 0) {\r
-        strcpy (NewList->Str, ".\\");\r
-      } else {\r
-        NewList->Str[Index + 1] = 0;\r
-      }\r
-      //\r
-      // Add it to the end of the our list of include paths\r
-      //\r
-      if (mGlobals.IncludePaths == NULL) {\r
-        mGlobals.IncludePaths = NewList;\r
-      } else {\r
-        LastIncludePath->Next = NewList;\r
-      }\r
 \r
-      if (mGlobals.Verbose) {\r
-        fprintf (stdout, "Adding include path: %s\n", NewList->Str);\r
-      }\r
-\r
-      LastIncludePath = NewList;\r
       Argc--;\r
       Argv++;\r
     } else if (_stricmp (Argv[0], "-s") == 0) {\r
@@ -1145,15 +1333,20 @@ ProcessArgs (
       // check for one more arg\r
       //\r
       if (Argc > 1) {\r
+        mGlobals.OutFileName = Argv[1];\r
+        //\r
+        // Use temp file for output\r
+        // This can avoid overwriting previous existed dep file when error \r
+        // ocurred in this tool\r
         //\r
-        // Try to open the file\r
+        sprintf (mGlobals.TmpFileName, "%s2", mGlobals.OutFileName);\r
         //\r
-        if ((mGlobals.OutFptr = fopen (Argv[1], "w")) == NULL) {\r
-          Error (NULL, 0, 0, Argv[1], "could not open file for writing");\r
+        // Try to open the temp file\r
+        //\r
+        if ((mGlobals.OutFptr = fopen (mGlobals.TmpFileName, "w")) == NULL) {\r
+          Error (NULL, 0, 0, mGlobals.TmpFileName, "could not open file for writing");\r
           return STATUS_ERROR;\r
         }\r
-\r
-        mGlobals.OutFileName = Argv[1];\r
       } else {\r
         Error (NULL, 0, 0, Argv[0], "option requires output file name");\r
         Usage ();\r
@@ -1171,7 +1364,17 @@ ProcessArgs (
     } else if (_stricmp (Argv[0], "-ignorenotfound") == 0) {\r
       mGlobals.IgnoreNotFound = TRUE;\r
     } else if (_stricmp (Argv[0], "-asm") == 0) {\r
+      if (mGlobals.IsCl) {\r
+        Error (NULL, 0, 0, Argv[0], "option conflict with -cl");\r
+        return STATUS_ERROR;\r
+      }      \r
       mGlobals.IsAsm = TRUE;\r
+    } else if (_stricmp (Argv[0], "-cl") == 0) {\r
+      if (mGlobals.IsAsm) {\r
+        Error (NULL, 0, 0, Argv[0], "option conflict with -asm");\r
+        return STATUS_ERROR;\r
+      }\r
+      mGlobals.IsCl = TRUE; \r
     } else if ((_stricmp (Argv[0], "-h") == 0) || (strcmp (Argv[0], "-?") == 0)) {\r
       Usage ();\r
       return STATUS_ERROR;\r
@@ -1306,7 +1509,8 @@ Returns:
     //    "      -nodupes         keep track of include files, don't rescan duplicates",\r
     //\r
     "      -usesumdeps path use summary dependency files in 'path' directory.",\r
-    "      -asm             The SourceFile is assembler file",\r
+    "      -asm             The SourceFiles are assembler files",\r
+    "      -cl              The SourceFiles are the output of cl with /showIncludes",\r
     "",\r
     NULL\r
   };\r
index 4cd9084f8ec3fe3d1d91c0d083d1411ef1588300..f24b9ffe719391f865ed38c50e2dc2a721c23825 100644 (file)
@@ -62,8 +62,10 @@ $(TARGET_EXE): $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe
 !ELSE\r
 $(TARGET_EXE) : $(OBJECTS) $(LIBS)\r
   $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(OBJECTS)\r
+!IF ("$(EFI_BINARY_BUILD)" == "YES")\r
   if not exist $(EFI_PLATFORM_BIN)\Tools mkdir $(EFI_PLATFORM_BIN)\Tools\r
   if exist $(TARGET_EXE) copy $(TARGET_EXE) $(EFI_PLATFORM_BIN)\tools\$(TARGET_NAME).exe /Y\r
   if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb \\r
   copy $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb /Y\r
 !ENDIF\r
+!ENDIF\r
index 974c9b4aa9e1fe1e2c132a2e77dda6f6724561fc..57ec6a190b606e59945c676b7182c3a53836b184 100644 (file)
 #\r
 #--*/\r
 \r
-#\r
-# Everything depends on EDK_SOURCE. Make sure it's defined\r
-#\r
-!IFNDEF EDK_SOURCE\r
-!ERROR EDK_SOURCE environmental variable not set\r
-!ENDIF\r
-\r
 #\r
 # Define our toolchain before we include the master settings file\r
 #\r
@@ -42,25 +35,26 @@ MAKEFILES = $(EDK_TOOLS_SOURCE)\Common\Makefile             \
             $(EDK_TOOLS_SOURCE)\GenDepex\Makefile           \\r
             $(EDK_TOOLS_SOURCE)\GenFfsFile\Makefile         \\r
             $(EDK_TOOLS_SOURCE)\GenFvImage\Makefile         \\r
+            $(EDK_TOOLS_SOURCE)\GenTEImage\makefile         \\r
             $(EDK_TOOLS_SOURCE)\FwImage\Makefile            \\r
             $(EDK_TOOLS_SOURCE)\ProcessDsc\makefile         \\r
             $(EDK_TOOLS_SOURCE)\GuidChk\makefile            \\r
             $(EDK_TOOLS_SOURCE)\MakeDeps\makefile           \\r
             $(EDK_TOOLS_SOURCE)\SetStamp\makefile           \\r
+!IF "$(EFI_SPECIFICATION_VERSION)" >= "0x0002000A"\r
+            $(EDK_TOOLS_SOURCE)\UefiVfrCompile\makefile     \\r
+            $(EDK_TOOLS_SOURCE)\UefiStrGather\makefile      \\r
+!ELSE\r
             $(EDK_TOOLS_SOURCE)\VfrCompile\makefile         \\r
             $(EDK_TOOLS_SOURCE)\StrGather\makefile          \\r
-            $(EDK_TOOLS_SOURCE)\BootsectImage\Makefile      \\r
-            $(EDK_TOOLS_SOURCE)\GenBootsector\Makefile      \\r
-            $(EDK_TOOLS_SOURCE)\GenPage\Makefile            \\r
+!ENDIF\r
             $(EDK_TOOLS_SOURCE)\SplitFile\Makefile          \\r
+            $(EDK_TOOLS_SOURCE)\Strip\Makefile              \\r
             $(EDK_TOOLS_SOURCE)\EfiCompress\Makefile        \\r
-            $(EDK_TOOLS_SOURCE)\EfildrImage\Makefile        \\r
             $(EDK_TOOLS_SOURCE)\EfiRom\Makefile             \\r
             $(EDK_TOOLS_SOURCE)\GenAprioriFile\Makefile     \\r
             $(EDK_TOOLS_SOURCE)\ModifyInf\Makefile\r
 \r
-\r
-\r
 #\r
 # Define default all target which calls all our makefiles. The special\r
 # bang (!) tells nmake to do the command for each out-of-date dependent.\r
index f303a54d1091dc02d526f568773985575d5cb1df..523af4d931682ed18344aae44b6ccc2298134a7f 100644 (file)
@@ -72,11 +72,13 @@ $(TARGET_EXE): $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe
 !ELSE\r
 $(TARGET_EXE) : $(OBJECTS)\r
   $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(OBJECTS)\r
+!IF ("$(EFI_BINARY_BUILD)" == "YES")\r
   if not exist $(EFI_PLATFORM_BIN)\Tools mkdir $(EFI_PLATFORM_BIN)\Tools\r
   if exist $(TARGET_EXE) copy $(TARGET_EXE) $(EFI_PLATFORM_BIN)\tools\$(TARGET_NAME).exe /Y\r
   if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb \\r
   copy $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb /Y\r
 !ENDIF\r
+!ENDIF\r
 \r
 clean:\r
   @if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL\r
index c835a800259c8ae94384b4de438df3bc7c38e0b2..b11d3c44ada58720d10dc989015811687555c2d5 100644 (file)
@@ -89,11 +89,13 @@ $(TARGET_EXE): $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe
 !ELSE\r
 $(TARGET_EXE) : $(OBJECTS) $(LIBS)\r
   $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(OBJECTS)\r
+!IF ("$(EFI_BINARY_BUILD)" == "YES")\r
   if not exist $(EFI_PLATFORM_BIN)\Tools mkdir $(EFI_PLATFORM_BIN)\Tools\r
   if exist $(TARGET_EXE) copy $(TARGET_EXE) $(EFI_PLATFORM_BIN)\tools\$(TARGET_NAME).exe /Y\r
   if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb \\r
   copy $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb /Y\r
 !ENDIF\r
+!ENDIF\r
 \r
 clean:\r
   @if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL\r
index 4833b78e0d544996394ea222fa37958be4f2dbd2..5b67632721f2747623da3cff89cc71e419d4bee3 100644 (file)
@@ -554,6 +554,12 @@ AddModuleName (
   INT8    *InfName\r
   );\r
 \r
+static \r
+void\r
+ReplaceSlash (\r
+  INT8    *Path\r
+  );\r
+\r
 /*****************************************************************************/\r
 int\r
 main (\r
@@ -1032,10 +1038,11 @@ Returns:
   // added local symbols\r
   //\r
   ExpandSymbols (ArgLine, Line, sizeof (Line), EXPANDMODE_NO_UNDEFS);\r
-\r
+  \r
   //\r
   // If we have "c:\path\filename"\r
   //\r
+  ReplaceSlash (Line);\r
   if (IsAbsolutePath (Line)) {\r
     ComponentFilePathAbsolute = 1;\r
   } else if (Line[0] == '.') {\r
@@ -1054,7 +1061,7 @@ Returns:
   //\r
   strcpy (ComponentFilePath, Line);\r
   Cptr = ComponentFilePath + strlen (ComponentFilePath) - 1;\r
-  while ((*Cptr != '\\') && (*Cptr != '/') && (Cptr != ComponentFilePath)) {\r
+  while ((*Cptr != '\\') && (Cptr != ComponentFilePath)) {\r
     Cptr--;\r
   }\r
   //\r
@@ -1239,7 +1246,8 @@ Returns:
   // They may have defined DEST_DIR on the component INF line, so it's already\r
   // been defined, If that's the case, then don't set it to the path of this file.\r
   //\r
-  if (GetSymbolValue (DEST_DIR) == NULL) {\r
+  TempCptr = GetSymbolValue (DEST_DIR);\r
+  if (TempCptr == NULL) {\r
     if (ComponentFilePathAbsolute == 0) {\r
       //\r
       // The destination path is $(BUILD_DIR)\$(PROCESSOR)\component_path\r
@@ -1264,6 +1272,8 @@ Returns:
         );\r
     }\r
     AddSymbol (DEST_DIR, FileName, SYM_OVERWRITE | SYM_LOCAL | SYM_FILEPATH);\r
+  } else {\r
+    ReplaceSlash (TempCptr);\r
   }\r
   \r
   //\r
@@ -1818,6 +1828,7 @@ Returns:
   //\r
   OverridePath = GetSymbolValue (SOURCE_OVERRIDE_PATH);\r
   if (OverridePath != NULL) {\r
+    ReplaceSlash (OverridePath);\r
     fprintf (MakeFptr, "INC = $(INC) -I %s\n", OverridePath);\r
     fprintf (MakeFptr, "INC = $(INC) -I %s\\%s \n", OverridePath, Processor);\r
   }\r
@@ -1881,6 +1892,7 @@ ProcessIncludesSectionSingle (
       // Don't process blank lines\r
       //\r
       if (*Cptr) {\r
+        ReplaceSlash (Cptr);\r
         //\r
         // Strip off trailing slash\r
         //\r
@@ -2150,6 +2162,7 @@ ProcessSourceFilesSection (
         //\r
         ExpandSymbols (Cptr, FileName, sizeof (FileName), 0);\r
         AddFileSymbols (FileName);\r
+        ReplaceSlash (FileName);\r
         //\r
         // Set the SOURCE_FILE_NAME symbol. What we have now is the name of\r
         // the file, relative to the location of the INF file. So prepend\r
@@ -2197,6 +2210,7 @@ ProcessSourceFilesSection (
           OverridePath = GetSymbolValue (SOURCE_OVERRIDE_PATH);\r
         }\r
         if (OverridePath != NULL) {\r
+          ReplaceSlash (OverridePath);\r
           //\r
           // See if the file exists. If it does, reset the SOURCE_FILE_NAME symbol.\r
           //\r
@@ -2490,6 +2504,7 @@ ProcessObjectsSingle (
         //\r
         if (!IsIncludeFile (Cptr)) {\r
           ExpandSymbols (Cptr, FileName, sizeof (FileName), 0);\r
+          ReplaceSlash (FileName);\r
           Cptr2 = BuiltFileExtension (FileName);\r
           if (Cptr2 != NULL) {\r
             SetFileExtension (FileName, Cptr2);\r
@@ -2731,8 +2746,10 @@ ProcessIncludeFilesSingle (
         //\r
         ExpandSymbols (Cptr, FileName, sizeof (FileName), 0);\r
         AddFileSymbols (FileName);\r
+        ReplaceSlash (FileName);\r
         if (IsIncludeFile (FileName)) {\r
           if ((OverridePath != NULL) && (!IsAbsolutePath (FileName))) {\r
+            ReplaceSlash (OverridePath);\r
             strcpy (TempFileName, OverridePath);\r
             strcat (TempFileName, "\\");\r
             strcat (TempFileName, FileName);\r
@@ -2743,7 +2760,7 @@ ProcessIncludeFilesSingle (
               // to the beginning of the list of include paths.\r
               //\r
               for (Cptr = TempFileName + strlen (TempFileName) - 1;\r
-                   (Cptr >= TempFileName) && (*Cptr != '\\') && (*Cptr != '/');\r
+                   (Cptr >= TempFileName) && (*Cptr != '\\');\r
                    Cptr--\r
                   )\r
                 ;\r
@@ -2848,9 +2865,9 @@ GetFileParts (
     FP->Extension[0]  = 0;\r
   }\r
   //\r
-  // Now back up and get the base name (include the preceding '\' or '/')\r
+  // Now back up and get the base name (include the preceding '\')\r
   //\r
-  for (; (Cptr > FileNamePtr) && (*Cptr != '\\') && (*Cptr != '/'); Cptr--)\r
+  for (; (Cptr > FileNamePtr) && (*Cptr != '\\'); Cptr--)\r
     ;\r
   FP->BaseName = (char *) malloc (strlen (Cptr) + 1);\r
   strcpy (FP->BaseName, Cptr);\r
@@ -3329,7 +3346,7 @@ MakeFilePath (
   }\r
 \r
   for (;;) {\r
-    for (; *Cptr && (*Cptr != '/') && (*Cptr != '\\'); Cptr++)\r
+    for (; *Cptr && (*Cptr != '\\'); Cptr++)\r
       ;\r
     if (*Cptr) {\r
       SavedChar = *Cptr;\r
@@ -4204,6 +4221,7 @@ Returns:
     FreeCwd = 1;\r
     AddSymbol (BUILD_DIR, Cptr, SYM_OVERWRITE | SYM_GLOBAL | SYM_FILEPATH);\r
   } else {\r
+    ReplaceSlash (Cptr);\r
     FreeCwd = 0;\r
   }\r
 \r
@@ -4359,6 +4377,7 @@ GetEfiSource (
   //\r
   EfiSource = GetSymbolValue (EFI_SOURCE);\r
   if ( EfiSource != NULL) {\r
+    ReplaceSlash (EfiSource);\r
     if (EfiSource[strlen (EfiSource) - 1] == '\\') {\r
       EfiSource[strlen (EfiSource) - 1] = 0;\r
     }    \r
@@ -4370,6 +4389,7 @@ GetEfiSource (
   //\r
   EfiSource = getenv (EFI_SOURCE);\r
   if (EfiSource != NULL) {\r
+    ReplaceSlash (EfiSource);\r
     if (EfiSource[strlen (EfiSource) - 1] == '\\') {\r
       EfiSource[strlen (EfiSource) - 1] = 0;\r
     }\r
@@ -4724,3 +4744,26 @@ Returns:
   return 0;\r
 }\r
 \r
\r
+static \r
+void\r
+ReplaceSlash (\r
+  INT8    *Path\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  \r
+  Replace '/' with '\\'\r
+\r
+Returns:\r
+\r
+--*/\r
+{\r
+  while (*Path) {\r
+    if (*Path == '/') {\r
+      *Path = '\\';\r
+    }\r
+    Path++;\r
+  }\r
+}
\ No newline at end of file
index 39750fb4418827fcfca445a9fcfb2d2066b5f572..13fe39efad2754171076c8f9207368f695fdb703 100644 (file)
@@ -78,11 +78,13 @@ $(TARGET_EXE): $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe
 !ELSE\r
 $(TARGET_EXE) : $(OBJECTS)\r
   $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(OBJECTS)\r
+!IF ("$(EFI_BINARY_BUILD)" == "YES")\r
   if not exist $(EFI_PLATFORM_BIN)\Tools mkdir $(EFI_PLATFORM_BIN)\Tools\r
   if exist $(TARGET_EXE) copy $(TARGET_EXE) $(EFI_PLATFORM_BIN)\tools\$(TARGET_NAME).exe /Y\r
   if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb \\r
   copy $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb /Y\r
 !ENDIF\r
+!ENDIF\r
 \r
 clean:\r
   @if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).*\r
index a90e133cec8a1ed7c129cd41ca32f9a5b67ca0df..d67d9b2bbe998c759c2ff623f3de7483b426b5e1 100644 (file)
@@ -84,11 +84,13 @@ $(TARGET_EXE): $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe
 !ELSE\r
 $(TARGET_EXE): $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj\r
   $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) /out:$(TARGET_EXE) $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj\r
+!IF ("$(EFI_BINARY_BUILD)" == "YES")\r
   if not exist $(EFI_PLATFORM_BIN)\Tools mkdir $(EFI_PLATFORM_BIN)\Tools\r
   if exist $(TARGET_EXE) copy $(TARGET_EXE) $(EFI_PLATFORM_BIN)\tools\$(TARGET_NAME).exe /Y\r
   if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb \\r
   copy $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb /Y\r
 !ENDIF\r
+!ENDIF\r
 \r
 clean:\r
   @if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL\r
index dce81b0e04e33ce72151b68662e667b92545c094..993063d4cec4c7bf2417768fdf3c919eab7b111d 100644 (file)
@@ -79,11 +79,13 @@ $(TARGET_EXE): $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe
 !ELSE\r
 $(TARGET_EXE) : $(OBJECTS) $(LIBS)\r
   $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(OBJECTS)\r
+!IF ("$(EFI_BINARY_BUILD)" == "YES")\r
   if not exist $(EFI_PLATFORM_BIN)\Tools mkdir $(EFI_PLATFORM_BIN)\Tools\r
   if exist $(TARGET_EXE) copy $(TARGET_EXE) $(EFI_PLATFORM_BIN)\tools\$(TARGET_NAME).exe /Y\r
   if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb \\r
   copy $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb /Y\r
 !ENDIF\r
+!ENDIF\r
 \r
 clean:\r
   \r
diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/Strip/Makefile b/EdkCompatibilityPkg/Sample/Tools/Source/Strip/Makefile
new file mode 100644 (file)
index 0000000..99d1b2a
--- /dev/null
@@ -0,0 +1,94 @@
+#/*++\r
+#   \r
+#  Copyright (c) 2006 - 2007, Intel Corporation                                                         \r
+#  All rights reserved. This program and the accompanying materials                          \r
+#  are licensed and made available under the terms and conditions of the BSD License         \r
+#  which accompanies this distribution.  The full text of the license may be found at        \r
+#  http://opensource.org/licenses/bsd-license.php                                            \r
+#                                                                                            \r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+#   \r
+#  Module Name:  makefile\r
+#   \r
+#  Abstract:\r
+#   \r
+#    This file is used to build the Strip utility.\r
+#   \r
+#--*/\r
+\r
+#\r
+# Make sure environmental variable EDK_SOURCE is set\r
+#\r
+!IFNDEF EDK_SOURCE\r
+!ERROR EDK_SOURCE environmental variable not set \r
+!ENDIF\r
+\r
+#\r
+# Do this if you want to compile from this directory\r
+#\r
+!IFNDEF TOOLCHAIN\r
+TOOLCHAIN = TOOLCHAIN_MSVC\r
+!ENDIF\r
+\r
+!INCLUDE $(BUILD_DIR)\PlatformTools.env\r
+\r
+#\r
+# Define some macros we use here. Should get rid of them someday and \r
+# get rid of the extra level of indirection.\r
+#\r
+COMMON_SOURCE      = $(EDK_TOOLS_COMMON)\r
+\r
+#\r
+# Common information\r
+#\r
+\r
+INC=$(INC)\r
+\r
+#\r
+# Target specific information\r
+#\r
+\r
+TARGET_NAME=Strip\r
+TARGET_SOURCE_DIR = $(EDK_TOOLS_SOURCE)\$(TARGET_NAME)\r
+\r
+TARGET_EXE = $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).exe\r
+\r
+TARGET_EXE_SOURCE = "$(TARGET_SOURCE_DIR)\Strip.c"\r
+TARGET_EXE_INCLUDE = \r
+\r
+#\r
+# Build targets\r
+#\r
+\r
+all: $(TARGET_EXE)\r
+\r
+#\r
+# Build EXE\r
+#\r
+\r
+$(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj: $(TARGET_EXE_SOURCE) $(TARGET_EXE_INCLUDE)\r
+  $(CC) $(C_FLAGS) $(INC) $(TARGET_EXE_SOURCE) /Fo$(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj\r
+\r
+#\r
+# Add Binary Build description for this tools.\r
+#\r
+\r
+!IF (("$(EFI_BINARY_TOOLS)" == "YES") && EXIST($(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe))\r
+$(TARGET_EXE): $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe\r
+  copy $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe $(TARGET_EXE) /Y\r
+  if exist $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb \\r
+  copy $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb /Y\r
+!ELSE\r
+$(TARGET_EXE): $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj $(TARGET_EXE_LIBS) $(TARGET_DLL)\r
+  $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj $(TARGET_LIB)  $(TARGET_EXE_LIBS)\r
+!IF ("$(EFI_BINARY_BUILD)" == "YES")\r
+  if not exist $(EFI_PLATFORM_BIN)\Tools mkdir $(EFI_PLATFORM_BIN)\Tools\r
+  if exist $(TARGET_EXE) copy $(TARGET_EXE) $(EFI_PLATFORM_BIN)\tools\$(TARGET_NAME).exe /Y\r
+  if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb \\r
+  copy $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb /Y\r
+!ENDIF\r
+!ENDIF\r
+\r
+clean:\r
+  @if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL\r
diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/Strip/strip.c b/EdkCompatibilityPkg/Sample/Tools/Source/Strip/strip.c
new file mode 100644 (file)
index 0000000..72d7693
--- /dev/null
@@ -0,0 +1,104 @@
+/*++\r
+\r
+Copyright 2006, Intel Corporation                                                         \r
+All rights reserved. This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+  Strip.c\r
+\r
+Abstract:\r
+\r
+  Quick Exe2Bin equivalent.\r
+\r
+--*/\r
+\r
+#include <stdio.h>\r
+#include <memory.h>\r
+#include <string.h>\r
+#include <malloc.h>\r
+\r
+int\r
+main (\r
+  int  argc,\r
+  char *argv[]\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Converts executable files to binary files.\r
+\r
+Arguments:\r
+\r
+  argc   - Number of command line arguments\r
+  argv[] - Array of pointers to the command line arguments\r
+\r
+Returns:\r
+\r
+  Zero     - Function completed successfully.\r
+  Non-zero - Function exited with errors. \r
+\r
+--*/\r
+{\r
+  FILE  *InFile;\r
+  FILE  *OutFile;\r
+  int   Index;\r
+  int   FileSize;\r
+  char  *Buffer;\r
+  char  *Ptrx;\r
+\r
+  if (argc < 3) {\r
+    printf ("Need more args, such as file name to convert and output name\n");\r
+    return -1;\r
+  }\r
+\r
+  InFile  = fopen (argv[1], "rb");\r
+  OutFile = fopen (argv[2], "wb");\r
+\r
+  if (!InFile) {\r
+    printf ("no file, exit\n");\r
+    return -1;\r
+  }\r
+\r
+  if (OutFile == NULL) {\r
+    printf ("Unable to open output file.\n");\r
+    return -1;\r
+  }\r
+\r
+  fseek (InFile, 0, SEEK_END);\r
+  FileSize = ftell (InFile);\r
+\r
+  if (FileSize < 0x200) {\r
+    printf ("%d is not a legal size, exit\n", FileSize);\r
+    return -1;\r
+  }\r
+\r
+  fseek (InFile, 0, SEEK_SET);\r
+\r
+  Buffer = malloc (FileSize);\r
+  if (Buffer == NULL) {\r
+    printf ("Error: Out of resources.\n");\r
+    return -1;\r
+  }\r
+\r
+  fread (Buffer, 1, FileSize, InFile);\r
+\r
+  Ptrx  = Buffer + 0x200;\r
+\r
+  Index = FileSize - 0x200;\r
+\r
+  fwrite (Ptrx, Index, 1, OutFile);\r
+\r
+  fclose (InFile);\r
+  fclose (OutFile);\r
+  free (Buffer);\r
+\r
+  return 0;\r
+}\r
diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/UefiStrGather/Makefile b/EdkCompatibilityPkg/Sample/Tools/Source/UefiStrGather/Makefile
new file mode 100644 (file)
index 0000000..cb8bac2
--- /dev/null
@@ -0,0 +1,103 @@
+#/*++\r
+#  \r
+#  Copyright (c) 2004 - 2007, Intel Corporation                                                         \r
+#  All rights reserved. This program and the accompanying materials                          \r
+#  are licensed and made available under the terms and conditions of the BSD License         \r
+#  which accompanies this distribution.  The full text of the license may be found at        \r
+#  http://opensource.org/licenses/bsd-license.php                                            \r
+#                                                                                            \r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+#  \r
+#  Module Name:\r
+#  \r
+#    Makefile\r
+#  \r
+#  Abstract:\r
+#  \r
+#    makefile for building the StrGather utility.\r
+#    \r
+#--*/  \r
+\r
+#\r
+# Make sure environmental variable EDK_SOURCE is set\r
+#\r
+!IFNDEF EDK_SOURCE\r
+!ERROR EDK_SOURCE environmental variable not set \r
+!ENDIF\r
+\r
+#\r
+# Do this if you want to compile from this directory\r
+#\r
+!IFNDEF TOOLCHAIN\r
+TOOLCHAIN = TOOLCHAIN_MSVC\r
+!ENDIF\r
+\r
+!INCLUDE $(BUILD_DIR)\PlatformTools.env\r
+\r
+#\r
+# Target specific information\r
+#\r
+TARGET_NAME         = StrGather\r
+TARGET_SRC_DIR      = $(EDK_TOOLS_SOURCE)\Uefi$(TARGET_NAME)\r
+TARGET_EXE          = $(EDK_TOOLS_OUTPUT)\StrGather.exe\r
+\r
+#\r
+# Build targets\r
+#\r
+\r
+all: $(TARGET_EXE)\r
+\r
+\r
+LIBS      = "$(EDK_TOOLS_OUTPUT)\Common.lib"\r
+\r
+OBJECTS   = $(EDK_TOOLS_OUTPUT)\StrGather.obj  \\r
+            $(EDK_TOOLS_OUTPUT)\StringDB.obj   \r
+\r
+INC_PATHS = -I $(TARGET_SRC_DIR) \\r
+            -I $(EDK_SOURCE)\Foundation\Include\Ia32 \\r
+            -I $(EDK_SOURCE)\Foundation\Efi\Include \\r
+            -I $(EDK_SOURCE)\Foundation\Framework\Include \\r
+                   -I $(EDK_SOURCE)\Foundation\Include\IndustryStandard \\r
+                       -I $(EDK_SOURCE)\Foundation\         \\r
+                       -I $(EDK_SOURCE)\Foundation\Core\Dxe \\r
+                       -I $(EDK_SOURCE)\Foundation\Efi      \\r
+                       -I $(EDK_SOURCE)\Foundation\Framework \\r
+                       -I $(EDK_TOOLS_SOURCE)\Common \\r
+                       -I $(EDK_SOURCE)\Foundation\Include\r
+\r
+INC_DEPS  = $(TARGET_SRC_DIR)\StrGather.h $(TARGET_SRC_DIR)\StringDB.h \r
+\r
+C_FLAGS = $(C_FLAGS) /W4\r
+\r
+#\r
+# Compile each source file\r
+#\r
+$(EDK_TOOLS_OUTPUT)\StrGather.obj : $(TARGET_SRC_DIR)\StrGather.c $(INC_DEPS)\r
+  $(CC) $(C_FLAGS) $(INC_PATHS) $(TARGET_SRC_DIR)\StrGather.c /Fo$@\r
+\r
+$(EDK_TOOLS_OUTPUT)\StringDB.obj : $(TARGET_SRC_DIR)\StringDB.c $(INC_DEPS)\r
+  $(CC) $(C_FLAGS) $(INC_PATHS) $(TARGET_SRC_DIR)\StringDB.c /Fo$@\r
+\r
+#\r
+# Add Binary Build description for this tools.\r
+#\r
+\r
+!IF (("$(EFI_BINARY_TOOLS)" == "YES") && EXIST($(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe))\r
+$(TARGET_EXE): $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe\r
+  copy $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe $(TARGET_EXE) /Y\r
+  if exist $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb \\r
+  copy $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb /Y\r
+!ELSE\r
+$(TARGET_EXE) : $(OBJECTS) $(LIBS)\r
+  $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(OBJECTS)\r
+!IF ("$(EFI_BINARY_BUILD)" == "YES")\r
+  if not exist $(EFI_PLATFORM_BIN)\Tools mkdir $(EFI_PLATFORM_BIN)\Tools\r
+  if exist $(TARGET_EXE) copy $(TARGET_EXE) $(EFI_PLATFORM_BIN)\tools\$(TARGET_NAME).exe /Y\r
+  if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb \\r
+  copy $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb /Y\r
+!ENDIF\r
+!ENDIF\r
+\r
+clean:\r
+  \r
diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/UefiStrGather/StrGather.c b/EdkCompatibilityPkg/Sample/Tools/Source/UefiStrGather/StrGather.c
new file mode 100644 (file)
index 0000000..03b3cc6
--- /dev/null
@@ -0,0 +1,2829 @@
+/*++\r
+\r
+Copyright (c) 2004 - 2007, Intel Corporation                                                         \r
+All rights reserved. This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+  StrGather.c  \r
+\r
+Abstract:\r
+\r
+  Parse a strings file and create or add to a string database file.\r
+\r
+--*/\r
+\r
+#include <stdio.h>\r
+#include <string.h>\r
+#include <stdlib.h>\r
+#include <ctype.h>\r
+#include <Tiano.h>\r
+#include <EfiUtilityMsgs.h>\r
+#include <EfiHii.h>\r
+#include "StrGather.h"\r
+#include "StringDB.h"\r
+\r
+#define TOOL_VERSION  "0.31"\r
+\r
+typedef UINT16  WCHAR;\r
+\r
+#define MAX_PATH                    1024\r
+#define MAX_NEST_DEPTH              20  // just in case we get in an endless loop.\r
+#define MAX_STRING_IDENTIFIER_NAME  128 // number of wchars\r
+#define MAX_LINE_LEN                400\r
+#define STRING_TOKEN                "STRING_TOKEN"\r
+#define DEFAULT_BASE_NAME           "BaseName"\r
+//\r
+// Operational modes for this utility\r
+//\r
+#define MODE_UNKNOWN  0\r
+#define MODE_PARSE    1\r
+#define MODE_SCAN     2\r
+#define MODE_DUMP     3\r
+\r
+//\r
+// We keep a linked list of these for the source files we process\r
+//\r
+typedef struct _SOURCE_FILE {\r
+  FILE                *Fptr;\r
+  WCHAR               *FileBuffer;\r
+  WCHAR               *FileBufferPtr;\r
+  UINT32              FileSize;\r
+  INT8                FileName[MAX_PATH];\r
+  UINT32              LineNum;\r
+  BOOLEAN             EndOfFile;\r
+  BOOLEAN             SkipToHash;\r
+  struct _SOURCE_FILE *Previous;\r
+  struct _SOURCE_FILE *Next;\r
+  WCHAR               ControlCharacter;\r
+} SOURCE_FILE;\r
+\r
+#define DEFAULT_CONTROL_CHARACTER UNICODE_SLASH\r
+\r
+//\r
+// Here's all our globals. We need a linked list of include paths, a linked\r
+// list of source files, a linked list of subdirectories (appended to each\r
+// include path when searching), and a couple other fields.\r
+//\r
+static struct {\r
+  SOURCE_FILE                 SourceFiles;\r
+  TEXT_STRING_LIST            *IncludePaths;                    // all include paths to search\r
+  TEXT_STRING_LIST            *LastIncludePath;\r
+  TEXT_STRING_LIST            *ScanFileName;\r
+  TEXT_STRING_LIST            *LastScanFileName;\r
+  TEXT_STRING_LIST            *SkipExt;                         // if -skipext .uni\r
+  TEXT_STRING_LIST            *LastSkipExt;\r
+  TEXT_STRING_LIST            *IndirectionFileName;\r
+  TEXT_STRING_LIST            *LastIndirectionFileName;\r
+  TEXT_STRING_LIST            *DatabaseFileName;\r
+  TEXT_STRING_LIST            *LastDatabaseFileName;\r
+  WCHAR_STRING_LIST           *Language;\r
+  WCHAR_STRING_LIST           *LastLanguage;\r
+  WCHAR_MATCHING_STRING_LIST  *IndirectionList;                 // from indirection file(s)\r
+  WCHAR_MATCHING_STRING_LIST  *LastIndirectionList;\r
+  BOOLEAN                     Verbose;                          // for more detailed output\r
+  BOOLEAN                     VerboseDatabaseWrite;             // for more detailed output when writing database\r
+  BOOLEAN                     VerboseDatabaseRead;              // for more detailed output when reading database\r
+  BOOLEAN                     NewDatabase;                      // to start from scratch\r
+  BOOLEAN                     IgnoreNotFound;                   // when scanning\r
+  BOOLEAN                     VerboseScan;\r
+  BOOLEAN                     UnquotedStrings;                  // -uqs option\r
+  INT8                        OutputDatabaseFileName[MAX_PATH];\r
+  INT8                        StringHFileName[MAX_PATH];\r
+  INT8                        StringCFileName[MAX_PATH];        // output .C filename\r
+  INT8                        DumpUFileName[MAX_PATH];          // output unicode dump file name\r
+  INT8                        HiiExportPackFileName[MAX_PATH];  // HII export pack file name\r
+  INT8                        BaseName[MAX_PATH];               // base filename of the strings file\r
+  INT8                        OutputDependencyFileName[MAX_PATH];\r
+  FILE                        *OutputDependencyFptr;\r
+  UINT32                      Mode;\r
+} mGlobals;\r
+\r
+static\r
+BOOLEAN\r
+IsValidIdentifierChar (\r
+  INT8      Char,\r
+  BOOLEAN   FirstChar\r
+  );\r
+\r
+static\r
+void\r
+RewindFile (\r
+  SOURCE_FILE *SourceFile\r
+  );\r
+\r
+static\r
+BOOLEAN\r
+SkipTo (\r
+  SOURCE_FILE *SourceFile,\r
+  WCHAR       WChar,\r
+  BOOLEAN     StopAfterNewline\r
+  );\r
+\r
+static\r
+UINT32\r
+SkipWhiteSpace (\r
+  SOURCE_FILE *SourceFile\r
+  );\r
+\r
+static\r
+BOOLEAN\r
+IsWhiteSpace (\r
+  SOURCE_FILE *SourceFile\r
+  );\r
+\r
+static\r
+BOOLEAN\r
+EndOfFile (\r
+  SOURCE_FILE *SourceFile\r
+  );\r
+\r
+static\r
+void\r
+PreprocessFile (\r
+  SOURCE_FILE *SourceFile\r
+  );\r
+\r
+static\r
+UINT32\r
+GetStringIdentifierName (\r
+  IN SOURCE_FILE  *SourceFile,\r
+  IN OUT WCHAR    *StringIdentifierName,\r
+  IN UINT32       StringIdentifierNameLen\r
+  );\r
+\r
+static\r
+STATUS\r
+GetLanguageIdentifierName (\r
+  IN SOURCE_FILE  *SourceFile,\r
+  IN OUT WCHAR    *LanguageIdentifierName,\r
+  IN UINT32       LanguageIdentifierNameLen,\r
+  IN BOOLEAN      Optional\r
+  );\r
+\r
+static\r
+WCHAR *\r
+GetPrintableLanguageName (\r
+  IN SOURCE_FILE  *SourceFile\r
+  );\r
+\r
+static\r
+STATUS\r
+AddCommandLineLanguage (\r
+  IN INT8          *Language\r
+  );\r
+\r
+static\r
+WCHAR *\r
+GetQuotedString (\r
+  SOURCE_FILE *SourceFile,\r
+  BOOLEAN     Optional\r
+  );\r
+\r
+static\r
+STATUS\r
+ProcessIncludeFile (\r
+  SOURCE_FILE *SourceFile,\r
+  SOURCE_FILE *ParentSourceFile\r
+  );\r
+\r
+static\r
+STATUS\r
+ParseFile (\r
+  SOURCE_FILE *SourceFile\r
+  );\r
+\r
+static\r
+FILE  *\r
+FindFile (\r
+  IN INT8     *FileName,\r
+  OUT INT8    *FoundFileName,\r
+  IN UINT32   FoundFileNameLen\r
+  );\r
+\r
+static\r
+STATUS\r
+ProcessArgs (\r
+  int   Argc,\r
+  char  *Argv[]\r
+  );\r
+\r
+static\r
+STATUS\r
+ProcessFile (\r
+  SOURCE_FILE *SourceFile\r
+  );\r
+\r
+static\r
+UINT32\r
+wstrcmp (\r
+  WCHAR *Buffer,\r
+  WCHAR *Str\r
+  );\r
+\r
+static\r
+WCHAR *\r
+wstrcatenate (\r
+  WCHAR *Dst,\r
+  WCHAR *Src\r
+  );\r
+\r
+static\r
+void\r
+Usage (\r
+  VOID\r
+  );\r
+\r
+static\r
+void\r
+FreeLists (\r
+  VOID\r
+  );\r
+\r
+static\r
+void\r
+ProcessTokenString (\r
+  SOURCE_FILE *SourceFile\r
+  );\r
+\r
+static\r
+void\r
+ProcessTokenInclude (\r
+  SOURCE_FILE *SourceFile\r
+  );\r
+\r
+static\r
+void\r
+ProcessTokenScope (\r
+  SOURCE_FILE *SourceFile\r
+  );\r
+\r
+static\r
+void\r
+ProcessTokenLanguage (\r
+  SOURCE_FILE *SourceFile\r
+  );\r
+\r
+static\r
+void\r
+ProcessTokenLangDef (\r
+  SOURCE_FILE *SourceFile\r
+  );\r
+\r
+static\r
+VOID\r
+ProcessTokenSecondaryLangDef (\r
+  SOURCE_FILE *SourceFile\r
+  );\r
+\r
+static\r
+STATUS\r
+ScanFiles (\r
+  TEXT_STRING_LIST *ScanFiles\r
+  );\r
+\r
+static\r
+STATUS\r
+ParseIndirectionFiles (\r
+  TEXT_STRING_LIST    *Files\r
+  );\r
+\r
+STATUS\r
+StringDBCreateHiiExportPack (\r
+  INT8                *OutputFileName\r
+  );\r
+\r
+int\r
+main (\r
+  int   Argc,\r
+  char  *Argv[]\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Call the routine to parse the command-line options, then process the file.\r
+  \r
+Arguments:\r
+\r
+  Argc - Standard C main() argc and argv.\r
+  Argv - Standard C main() argc and argv.\r
+\r
+Returns:\r
+\r
+  0       if successful\r
+  nonzero otherwise\r
+  \r
+--*/\r
+{\r
+  STATUS  Status;\r
+\r
+  SetUtilityName (PROGRAM_NAME);\r
+  //\r
+  // Process the command-line arguments\r
+  //\r
+  Status = ProcessArgs (Argc, Argv);\r
+  if (Status != STATUS_SUCCESS) {\r
+    return Status;\r
+  }\r
+  //\r
+  // Initialize the database manager\r
+  //\r
+  StringDBConstructor ();\r
+  //\r
+  // We always try to read in an existing database file. It may not\r
+  // exist, which is ok usually.\r
+  //\r
+  if (mGlobals.NewDatabase == 0) {\r
+    //\r
+    // Read all databases specified.\r
+    //\r
+    for (mGlobals.LastDatabaseFileName = mGlobals.DatabaseFileName;\r
+         mGlobals.LastDatabaseFileName != NULL;\r
+         mGlobals.LastDatabaseFileName = mGlobals.LastDatabaseFileName->Next\r
+        ) {\r
+      Status = StringDBReadDatabase (mGlobals.LastDatabaseFileName->Str, TRUE, mGlobals.VerboseDatabaseRead);\r
+      if (Status != STATUS_SUCCESS) {\r
+        return Status;\r
+      }\r
+    }\r
+  }\r
+  //\r
+  // Read indirection file(s) if specified\r
+  //\r
+  if (ParseIndirectionFiles (mGlobals.IndirectionFileName) != STATUS_SUCCESS) {\r
+    goto Finish;\r
+  }\r
+  //\r
+  // If scanning source files, do that now\r
+  //\r
+  if (mGlobals.Mode == MODE_SCAN) {\r
+    ScanFiles (mGlobals.ScanFileName);\r
+  } else if (mGlobals.Mode == MODE_PARSE) {\r
+    //\r
+    // Parsing a unicode strings file\r
+    //\r
+    mGlobals.SourceFiles.ControlCharacter = DEFAULT_CONTROL_CHARACTER;\r
+    if (mGlobals.OutputDependencyFileName[0] != 0) {\r
+      if ((mGlobals.OutputDependencyFptr = fopen (mGlobals.OutputDependencyFileName, "w")) == NULL) {\r
+        Error (NULL, 0, 0, mGlobals.OutputDependencyFileName, "failed to open output dependency file");\r
+        goto Finish;\r
+      }    \r
+    }\r
+    Status = ProcessIncludeFile (&mGlobals.SourceFiles, NULL);\r
+    if (mGlobals.OutputDependencyFptr != NULL) {\r
+      fclose (mGlobals.OutputDependencyFptr);\r
+    }    \r
+    if (Status != STATUS_SUCCESS) {\r
+      goto Finish;\r
+    }\r
+  }\r
+  //\r
+  // Create the string defines header file if there have been no errors.\r
+  //\r
+  ParserSetPosition (NULL, 0);\r
+  if ((mGlobals.StringHFileName[0] != 0) && (GetUtilityStatus () < STATUS_ERROR)) {\r
+    Status = StringDBDumpStringDefines (mGlobals.StringHFileName, mGlobals.BaseName);\r
+    if (Status != EFI_SUCCESS) {\r
+      goto Finish;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Dump the strings to a .c file if there have still been no errors.\r
+  //\r
+  if ((mGlobals.StringCFileName[0] != 0) && (GetUtilityStatus () < STATUS_ERROR)) {\r
+    Status = StringDBDumpCStrings (\r
+              mGlobals.BaseName,\r
+              mGlobals.StringCFileName\r
+              );\r
+    if (Status != EFI_SUCCESS) {\r
+      goto Finish;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Dump the database if requested\r
+  //\r
+  if ((mGlobals.DumpUFileName[0] != 0) && (GetUtilityStatus () < STATUS_ERROR)) {\r
+    StringDBDumpDatabase (NULL, mGlobals.DumpUFileName, FALSE);\r
+  }\r
+  //\r
+  // Dump the string data as HII binary string pack if requested\r
+  //\r
+  if ((mGlobals.HiiExportPackFileName[0] != 0) && (GetUtilityStatus () < STATUS_ERROR)) {\r
+    StringDBCreateHiiExportPack (mGlobals.HiiExportPackFileName);\r
+  }\r
+  //\r
+  // Always update the database if no errors and not in dump mode. If they specified -od\r
+  // for an output database file name, then use that name. Otherwise use the name of\r
+  // the first database file specified with -db\r
+  //\r
+  if ((mGlobals.Mode != MODE_DUMP) && (GetUtilityStatus () < STATUS_ERROR)) {\r
+    if (mGlobals.OutputDatabaseFileName[0]) {\r
+      Status = StringDBWriteDatabase (mGlobals.OutputDatabaseFileName, mGlobals.VerboseDatabaseWrite);\r
+    } else {\r
+      Status = StringDBWriteDatabase (mGlobals.DatabaseFileName->Str, mGlobals.VerboseDatabaseWrite);\r
+    }\r
+\r
+    if (Status != EFI_SUCCESS) {\r
+      goto Finish;\r
+    }\r
+  }\r
+\r
+Finish:\r
+  //\r
+  // Free up memory\r
+  //\r
+  FreeLists ();\r
+  StringDBDestructor ();\r
+  return GetUtilityStatus ();\r
+}\r
+\r
+static\r
+STATUS\r
+ProcessIncludeFile (\r
+  SOURCE_FILE *SourceFile,\r
+  SOURCE_FILE *ParentSourceFile\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Given a source file, open the file and parse it\r
+  \r
+Arguments:\r
+\r
+  SourceFile        - name of file to parse\r
+  ParentSourceFile  - for error reporting purposes, the file that #included SourceFile.\r
+\r
+Returns:\r
+\r
+  Standard status.\r
+  \r
+--*/\r
+{\r
+  static UINT32 NestDepth = 0;\r
+  INT8          FoundFileName[MAX_PATH];\r
+  STATUS        Status;\r
+\r
+  Status = STATUS_SUCCESS;\r
+  NestDepth++;\r
+  //\r
+  // Print the file being processed. Indent so you can tell the include nesting\r
+  // depth.\r
+  //\r
+  if (mGlobals.Verbose) {\r
+    fprintf (stdout, "%*cProcessing file '%s'\n", NestDepth * 2, ' ', SourceFile->FileName);\r
+  }\r
+\r
+  //\r
+  // Make sure we didn't exceed our maximum nesting depth\r
+  //\r
+  if (NestDepth > MAX_NEST_DEPTH) {\r
+    Error (NULL, 0, 0, SourceFile->FileName, "max nesting depth (%d) exceeded", NestDepth);\r
+    Status = STATUS_ERROR;\r
+    goto Finish;\r
+  }\r
+  //\r
+  // Try to open the file locally, and if that fails try along our include paths.\r
+  //\r
+  strcpy (FoundFileName, SourceFile->FileName);\r
+  if ((SourceFile->Fptr = fopen (FoundFileName, "rb")) == NULL) {\r
+    //\r
+    // Try to find it among the paths if it has a parent (that is, it is included\r
+    // by someone else).\r
+    //\r
+    if (ParentSourceFile == NULL) {\r
+      Error (NULL, 0, 0, SourceFile->FileName, "file not found");\r
+      Status = STATUS_ERROR;\r
+      goto Finish;\r
+    }\r
+\r
+    SourceFile->Fptr = FindFile (SourceFile->FileName, FoundFileName, sizeof (FoundFileName));\r
+    if (SourceFile->Fptr == NULL) {\r
+      Error (ParentSourceFile->FileName, ParentSourceFile->LineNum, 0, SourceFile->FileName, "include file not found");\r
+      Status = STATUS_ERROR;\r
+      goto Finish;\r
+    }\r
+  }\r
+  \r
+  //\r
+  // Output the dependency \r
+  //\r
+  if (mGlobals.OutputDependencyFptr != NULL) {\r
+    fprintf (mGlobals.OutputDependencyFptr, "%s : %s\n", mGlobals.DatabaseFileName->Str, FoundFileName);    \r
+    //\r
+    // Add pseudo target to avoid incremental build failure when the file is deleted\r
+    //\r
+    fprintf (mGlobals.OutputDependencyFptr, "%s : \n", FoundFileName); \r
+  }\r
+   \r
+  //\r
+  // Process the file found\r
+  //\r
+  ProcessFile (SourceFile);\r
+\r
+Finish:\r
+  NestDepth--;\r
+  //\r
+  // Close open files and return status\r
+  //\r
+  if (SourceFile->Fptr != NULL) {\r
+    fclose (SourceFile->Fptr);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+static\r
+STATUS\r
+ProcessFile (\r
+  SOURCE_FILE *SourceFile\r
+  )\r
+{\r
+  //\r
+  // Get the file size, and then read the entire thing into memory.\r
+  // Allocate space for a terminator character.\r
+  //\r
+  fseek (SourceFile->Fptr, 0, SEEK_END);\r
+  SourceFile->FileSize = ftell (SourceFile->Fptr);\r
+  fseek (SourceFile->Fptr, 0, SEEK_SET);\r
+  SourceFile->FileBuffer = (WCHAR *) malloc (SourceFile->FileSize + sizeof (WCHAR));\r
+  if (SourceFile->FileBuffer == NULL) {\r
+    Error (NULL, 0, 0, "memory allocation failure", NULL);\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  fread ((VOID *) SourceFile->FileBuffer, SourceFile->FileSize, 1, SourceFile->Fptr);\r
+  SourceFile->FileBuffer[(SourceFile->FileSize / sizeof (WCHAR))] = UNICODE_NULL;\r
+  //\r
+  // Pre-process the file to replace comments with spaces\r
+  //\r
+  PreprocessFile (SourceFile);\r
+  //\r
+  // Parse the file\r
+  //\r
+  ParseFile (SourceFile);\r
+  free (SourceFile->FileBuffer);\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+static\r
+STATUS\r
+ParseFile (\r
+  SOURCE_FILE *SourceFile\r
+  )\r
+{\r
+  BOOLEAN InComment;\r
+  UINT32  Len;\r
+\r
+  //\r
+  // First character of a unicode file is special. Make sure\r
+  //\r
+  if (SourceFile->FileBufferPtr[0] != UNICODE_FILE_START) {\r
+    Error (SourceFile->FileName, 1, 0, SourceFile->FileName, "file does not appear to be a unicode file");\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  SourceFile->FileBufferPtr++;\r
+  InComment = FALSE;\r
+  //\r
+  // Print the first line if in verbose mode\r
+  //\r
+  if (mGlobals.Verbose) {\r
+    printf ("%d: %S\n", SourceFile->LineNum, SourceFile->FileBufferPtr);\r
+  }\r
+  //\r
+  // Since the syntax is relatively straightforward, just switch on the next char\r
+  //\r
+  while (!EndOfFile (SourceFile)) {\r
+    //\r
+    // Check for whitespace\r
+    //\r
+    if (SourceFile->FileBufferPtr[0] == UNICODE_SPACE) {\r
+      SourceFile->FileBufferPtr++;\r
+    } else if (SourceFile->FileBufferPtr[0] == UNICODE_TAB) {\r
+      SourceFile->FileBufferPtr++;\r
+    } else if (SourceFile->FileBufferPtr[0] == UNICODE_CR) {\r
+      SourceFile->FileBufferPtr++;\r
+    } else if (SourceFile->FileBufferPtr[0] == UNICODE_LF) {\r
+      SourceFile->FileBufferPtr++;\r
+      SourceFile->LineNum++;\r
+      if (mGlobals.Verbose) {\r
+        printf ("%d: %S\n", SourceFile->LineNum, SourceFile->FileBufferPtr);\r
+      }\r
+\r
+      InComment = FALSE;\r
+    } else if (SourceFile->FileBufferPtr[0] == 0) {\r
+      SourceFile->FileBufferPtr++;\r
+    } else if (InComment) {\r
+      SourceFile->FileBufferPtr++;\r
+    } else if ((SourceFile->FileBufferPtr[0] == UNICODE_SLASH) && (SourceFile->FileBufferPtr[1] == UNICODE_SLASH)) {\r
+      SourceFile->FileBufferPtr += 2;\r
+      InComment = TRUE;\r
+    } else if (SourceFile->SkipToHash && (SourceFile->FileBufferPtr[0] != SourceFile->ControlCharacter)) {\r
+      SourceFile->FileBufferPtr++;\r
+    } else {\r
+      SourceFile->SkipToHash = FALSE;\r
+      if ((SourceFile->FileBufferPtr[0] == SourceFile->ControlCharacter) &&\r
+          ((Len = wstrcmp (SourceFile->FileBufferPtr + 1, L"include")) > 0)\r
+          ) {\r
+        SourceFile->FileBufferPtr += Len + 1;\r
+        ProcessTokenInclude (SourceFile);\r
+      } else if ((SourceFile->FileBufferPtr[0] == SourceFile->ControlCharacter) &&\r
+               (Len = wstrcmp (SourceFile->FileBufferPtr + 1, L"scope")) > 0\r
+              ) {\r
+        SourceFile->FileBufferPtr += Len + 1;\r
+        ProcessTokenScope (SourceFile);\r
+      } else if ((SourceFile->FileBufferPtr[0] == SourceFile->ControlCharacter) &&\r
+               (Len = wstrcmp (SourceFile->FileBufferPtr + 1, L"language")) > 0\r
+              ) {\r
+        SourceFile->FileBufferPtr += Len + 1;\r
+        ProcessTokenLanguage (SourceFile);\r
+      } else if ((SourceFile->FileBufferPtr[0] == SourceFile->ControlCharacter) &&\r
+               (Len = wstrcmp (SourceFile->FileBufferPtr + 1, L"langdef")) > 0\r
+              ) {\r
+        SourceFile->FileBufferPtr += Len + 1;\r
+        ProcessTokenLangDef (SourceFile);\r
+      } else if ((SourceFile->FileBufferPtr[0] == SourceFile->ControlCharacter) &&\r
+                 (Len = wstrcmp (SourceFile->FileBufferPtr + 1, L"secondarylang")) > 0\r
+                ) {\r
+        SourceFile->FileBufferPtr += Len + 1;\r
+        ProcessTokenSecondaryLangDef (SourceFile);\r
+      } else if ((SourceFile->FileBufferPtr[0] == SourceFile->ControlCharacter) &&\r
+               (Len = wstrcmp (SourceFile->FileBufferPtr + 1, L"string")) > 0\r
+              ) {\r
+        SourceFile->FileBufferPtr += Len + 1;\r
+        ProcessTokenString (SourceFile);\r
+      } else if ((SourceFile->FileBufferPtr[0] == SourceFile->ControlCharacter) &&\r
+               (Len = wstrcmp (SourceFile->FileBufferPtr + 1, L"EFI_BREAKPOINT()")) > 0\r
+              ) {\r
+        SourceFile->FileBufferPtr += Len;\r
+        EFI_BREAKPOINT ();\r
+      } else if ((SourceFile->FileBufferPtr[0] == SourceFile->ControlCharacter) &&\r
+               (SourceFile->FileBufferPtr[1] == UNICODE_EQUAL_SIGN)\r
+              ) {\r
+        SourceFile->ControlCharacter = SourceFile->FileBufferPtr[2];\r
+        SourceFile->FileBufferPtr += 3;\r
+      } else {\r
+        Error (SourceFile->FileName, SourceFile->LineNum, 0, "unrecognized token", "%S", SourceFile->FileBufferPtr);\r
+        //\r
+        // Treat rest of line as a comment.\r
+        //\r
+        InComment = TRUE;\r
+      }\r
+    }\r
+  }\r
+\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+static\r
+void\r
+PreprocessFile (\r
+  SOURCE_FILE *SourceFile\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Preprocess a file to replace all carriage returns with NULLs so\r
+  we can print lines from the file to the screen.\r
+  \r
+Arguments:\r
+  SourceFile - structure that we use to keep track of an input file.\r
+\r
+Returns:\r
+  Nothing.\r
+  \r
+--*/\r
+{\r
+  BOOLEAN InComment;\r
+\r
+  RewindFile (SourceFile);\r
+  InComment = FALSE;\r
+  while (!EndOfFile (SourceFile)) {\r
+    //\r
+    // If a line-feed, then no longer in a comment\r
+    //\r
+    if (SourceFile->FileBufferPtr[0] == UNICODE_LF) {\r
+      SourceFile->FileBufferPtr++;\r
+      SourceFile->LineNum++;\r
+      InComment = 0;\r
+    } else if (SourceFile->FileBufferPtr[0] == UNICODE_CR) {\r
+      //\r
+      // Replace all carriage returns with a NULL so we can print stuff\r
+      //\r
+      SourceFile->FileBufferPtr[0] = 0;\r
+      SourceFile->FileBufferPtr++;\r
+    } else if (InComment) {\r
+      SourceFile->FileBufferPtr[0] = UNICODE_SPACE;\r
+      SourceFile->FileBufferPtr++;\r
+    } else if ((SourceFile->FileBufferPtr[0] == UNICODE_SLASH) && (SourceFile->FileBufferPtr[1] == UNICODE_SLASH)) {\r
+      SourceFile->FileBufferPtr += 2;\r
+      InComment = TRUE;\r
+    } else {\r
+      SourceFile->FileBufferPtr++;\r
+    }\r
+  }\r
+  //\r
+  // Could check for end-of-file and still in a comment, but\r
+  // should not be necessary. So just restore the file pointers.\r
+  //\r
+  RewindFile (SourceFile);\r
+}\r
+\r
+static\r
+WCHAR *\r
+GetPrintableLanguageName (\r
+  IN SOURCE_FILE  *SourceFile\r
+  )\r
+{\r
+  WCHAR   *String;\r
+  WCHAR   *Start;\r
+  WCHAR   *Ptr;\r
+  UINT32  Len;\r
+\r
+  SkipWhiteSpace (SourceFile);\r
+  if (SourceFile->FileBufferPtr[0] != UNICODE_DOUBLE_QUOTE) {\r
+    Error (SourceFile->FileName, SourceFile->LineNum, 0, "expected quoted printable language name", "%S", SourceFile->FileBufferPtr);\r
+    SourceFile->SkipToHash = TRUE;\r
+    return NULL;\r
+  }\r
+\r
+  Len = 0;\r
+  SourceFile->FileBufferPtr++;\r
+  Start = Ptr = SourceFile->FileBufferPtr;\r
+  while (!EndOfFile (SourceFile)) {\r
+    if (SourceFile->FileBufferPtr[0] == UNICODE_CR) {\r
+      Warning (SourceFile->FileName, SourceFile->LineNum, 0, "carriage return found in quoted string", "%S", Start);\r
+      break;\r
+    } else if (SourceFile->FileBufferPtr[0] == UNICODE_DOUBLE_QUOTE) {\r
+      break;\r
+    }\r
+\r
+    SourceFile->FileBufferPtr++;\r
+    Len++;\r
+  }\r
+\r
+  if (SourceFile->FileBufferPtr[0] != UNICODE_DOUBLE_QUOTE) {\r
+    Warning (\r
+      SourceFile->FileName,\r
+      SourceFile->LineNum,\r
+      0,\r
+      "missing closing quote on printable language name string",\r
+      "%S",\r
+      Start\r
+      );\r
+  } else {\r
+    SourceFile->FileBufferPtr++;\r
+  }\r
+  //\r
+  // Now allocate memory for the string and save it off\r
+  //\r
+  String = (WCHAR *) malloc ((Len + 1) * sizeof (WCHAR));\r
+  if (String == NULL) {\r
+    Error (NULL, 0, 0, "memory allocation failed", NULL);\r
+    return NULL;\r
+  }\r
+  //\r
+  // Copy the string from the file buffer to the local copy.\r
+  // We do no reformatting of it whatsoever at this point.\r
+  //\r
+  Ptr = String;\r
+  while (Len > 0) {\r
+    *Ptr = *Start;\r
+    Start++;\r
+    Ptr++;\r
+    Len--;\r
+  }\r
+\r
+  *Ptr = 0;\r
+  //\r
+  // Now format the string to convert \wide and \narrow controls\r
+  //\r
+  StringDBFormatString (String);\r
+  return String;\r
+}\r
+\r
+static struct {\r
+  WCHAR *ISO639;\r
+  WCHAR *RFC3066;\r
+} LanguageConvertTable[] = {\r
+  { L"eng", L"en-US" },\r
+  { L"fra", L"fr-FR" },\r
+  { L"spa", L"es-ES" },\r
+  { NULL, NULL }\r
+};\r
+\r
+WCHAR *\r
+GetLangCode (\r
+  IN WCHAR                        *Lang\r
+  )\r
+{\r
+  UINT32  Index;\r
+  WCHAR   *LangCode;\r
+\r
+  LangCode = NULL;\r
+\r
+  //\r
+  // The Lang is xx-XX format and return.\r
+  //\r
+  if (wcschr (Lang, L'-') != NULL) {\r
+    LangCode = (WCHAR *) malloc ((wcslen (Lang) + 1) * sizeof(WCHAR));\r
+    if (LangCode != NULL) {\r
+      wcscpy (LangCode, Lang);\r
+    }\r
+    return LangCode;\r
+  }\r
+\r
+  //\r
+  // Convert the language accoring to the table.\r
+  //\r
+  for (Index = 0; LanguageConvertTable[Index].ISO639 != NULL; Index++) {\r
+    if (wcscmp(LanguageConvertTable[Index].ISO639, Lang) == 0) {\r
+      LangCode = (WCHAR *) malloc ((wcslen (LanguageConvertTable[Index].RFC3066) + 1) * sizeof (WCHAR));\r
+      if (LangCode != NULL) {\r
+        wcscpy (LangCode, LanguageConvertTable[Index].RFC3066);\r
+      }\r
+      return LangCode;\r
+    }\r
+  }\r
+\r
+  return NULL;\r
+}\r
+\r
+WCHAR *\r
+GetLangCodeList (\r
+  IN WCHAR                        *SecondaryLangList\r
+  )\r
+{\r
+  WCHAR *CodeBeg, *CodeEnd;\r
+  WCHAR *CodeRet;\r
+  WCHAR *LangCodeList = NULL;\r
+  WCHAR *TempLangCodeList = NULL;\r
+\r
+  TempLangCodeList = (WCHAR *) malloc ((wcslen(SecondaryLangList) + 1) * sizeof(WCHAR));\r
+  if (TempLangCodeList == NULL) {\r
+    return NULL;\r
+  }\r
+  wcscpy (TempLangCodeList, SecondaryLangList);\r
+  CodeBeg = TempLangCodeList;\r
+\r
+  while (CodeBeg != NULL) {\r
+    CodeEnd = wcschr (CodeBeg, L';');\r
+    if (CodeEnd != NULL) {\r
+      *CodeEnd = L'\0';\r
+      CodeEnd++;\r
+    }\r
+\r
+    CodeRet = GetLangCode (CodeBeg);\r
+    if (CodeRet != NULL) {\r
+      if (LangCodeList != NULL) {\r
+        LangCodeList = wstrcatenate (LangCodeList, L";");\r
+      }\r
+      LangCodeList = wstrcatenate (LangCodeList, CodeRet);\r
+    }\r
+\r
+    CodeBeg = CodeEnd;\r
+    FREE (CodeRet);\r
+  }\r
+\r
+  free (TempLangCodeList);\r
+\r
+  return LangCodeList;\r
+}\r
+\r
+static\r
+WCHAR *\r
+GetSecondaryLanguageList (\r
+  IN SOURCE_FILE  *SourceFile\r
+  )\r
+{\r
+  WCHAR   *SecondaryLangList = NULL;\r
+  WCHAR   SecondaryLang[MAX_STRING_IDENTIFIER_NAME + 1];\r
+  WCHAR   *LangCodeList;\r
+  WCHAR   *Start;\r
+  WCHAR   *Ptr;\r
+  UINT32  Index;\r
+\r
+  SkipWhiteSpace (SourceFile);\r
+\r
+  if (SourceFile->FileBufferPtr[0] != UNICODE_OPEN_PAREN) {\r
+    Error (SourceFile->FileName, SourceFile->LineNum, 0, "expected open bracket", "%S", SourceFile->FileBufferPtr);\r
+    SourceFile->SkipToHash = TRUE;\r
+    return NULL;\r
+  }\r
+\r
+  Index             = 0;\r
+  SecondaryLang [0] = L'\0';\r
+  SourceFile->FileBufferPtr++;\r
+  Start = Ptr = SourceFile->FileBufferPtr;\r
+  while (!EndOfFile (SourceFile)) {\r
+    if (((SourceFile->FileBufferPtr[0] >= UNICODE_a) && (SourceFile->FileBufferPtr[0] <= UNICODE_z)) ||\r
+               ((SourceFile->FileBufferPtr[0] >= UNICODE_A) && (SourceFile->FileBufferPtr[0] <= UNICODE_Z)) ||\r
+               (SourceFile->FileBufferPtr[0] == UNICODE_MINUS)) {\r
+      if (Index > MAX_STRING_IDENTIFIER_NAME) {\r
+        Error (SourceFile->FileName, SourceFile->LineNum, 0, "secondary language length is too lang", "%S", SourceFile->FileBufferPtr);\r
+        goto Err;\r
+      }\r
+      SecondaryLang[Index] = SourceFile->FileBufferPtr[0];\r
+      Index++;\r
+    } else if (SourceFile->FileBufferPtr[0] == UNICODE_SPACE) {\r
+      SecondaryLang[Index] = L'\0';\r
+\r
+      if (SecondaryLang[0] != L'\0') {\r
+        if (SecondaryLangList != NULL) {\r
+          SecondaryLangList = wstrcatenate (SecondaryLangList, L";");\r
+        }\r
+        SecondaryLangList = wstrcatenate (SecondaryLangList, SecondaryLang);\r
+        Index             = 0;\r
+        SecondaryLang [0] = L'\0';\r
+        SourceFile->FileBufferPtr++;\r
+        continue;\r
+      }\r
+    } else if (SourceFile->FileBufferPtr[0] == UNICODE_CLOSE_PAREN) {\r
+      if (SecondaryLangList != NULL) {\r
+        SecondaryLangList = wstrcatenate (SecondaryLangList, L";");\r
+      }\r
+      SecondaryLangList = wstrcatenate (SecondaryLangList, SecondaryLang);\r
+      break;\r
+    } else {\r
+      Error (SourceFile->FileName, SourceFile->LineNum, 0, "can not recognize the secondary language", "%S", SourceFile->FileBufferPtr);\r
+      goto Err;\r
+    }\r
+\r
+    SourceFile->FileBufferPtr++;\r
+  }\r
+\r
+  if (SourceFile->FileBufferPtr[0] != UNICODE_CLOSE_PAREN) {\r
+    Error (SourceFile->FileName, SourceFile->LineNum, 0, "missing closing bracket", "%S", Start);\r
+  } else {\r
+    SourceFile->FileBufferPtr++;\r
+  }\r
+\r
+  LangCodeList = GetLangCodeList (SecondaryLangList);\r
+  FREE (SecondaryLangList);\r
+  return LangCodeList;\r
+\r
+Err:\r
+  FREE(SecondaryLangList);\r
+  return NULL;\r
+}\r
+\r
+static\r
+WCHAR *\r
+GetQuotedString (\r
+  SOURCE_FILE *SourceFile,\r
+  BOOLEAN     Optional\r
+  )\r
+{\r
+  WCHAR   *String;\r
+  WCHAR   *Start;\r
+  WCHAR   *Ptr;\r
+  UINT32  Len;\r
+  BOOLEAN PreviousBackslash;\r
+\r
+  if (SourceFile->FileBufferPtr[0] != UNICODE_DOUBLE_QUOTE) {\r
+    if (!Optional) {\r
+      Error (SourceFile->FileName, SourceFile->LineNum, 0, "expected quoted string", "%S", SourceFile->FileBufferPtr);\r
+    }\r
+\r
+    return NULL;\r
+  }\r
+\r
+  Len = 0;\r
+  SourceFile->FileBufferPtr++;\r
+  Start             = Ptr = SourceFile->FileBufferPtr;\r
+  PreviousBackslash = FALSE;\r
+  while (!EndOfFile (SourceFile)) {\r
+    if ((SourceFile->FileBufferPtr[0] == UNICODE_DOUBLE_QUOTE) && (!PreviousBackslash)) {\r
+      break;\r
+    } else if (SourceFile->FileBufferPtr[0] == UNICODE_CR) {\r
+      Warning (SourceFile->FileName, SourceFile->LineNum, 0, "carriage return found in quoted string", "%S", Start);\r
+      PreviousBackslash = FALSE;\r
+    } else if (SourceFile->FileBufferPtr[0] == UNICODE_BACKSLASH) {\r
+      PreviousBackslash = TRUE;\r
+    } else {\r
+      PreviousBackslash = FALSE;\r
+    }\r
+\r
+    SourceFile->FileBufferPtr++;\r
+    Len++;\r
+  }\r
+\r
+  if (SourceFile->FileBufferPtr[0] != UNICODE_DOUBLE_QUOTE) {\r
+    Warning (SourceFile->FileName, SourceFile->LineNum, 0, "missing closing quote on string", "%S", Start);\r
+  } else {\r
+    SourceFile->FileBufferPtr++;\r
+  }\r
+  //\r
+  // Now allocate memory for the string and save it off\r
+  //\r
+  String = (WCHAR *) malloc ((Len + 1) * sizeof (WCHAR));\r
+  if (String == NULL) {\r
+    Error (NULL, 0, 0, "memory allocation failed", NULL);\r
+    return NULL;\r
+  }\r
+  //\r
+  // Copy the string from the file buffer to the local copy.\r
+  // We do no reformatting of it whatsoever at this point.\r
+  //\r
+  Ptr = String;\r
+  while (Len > 0) {\r
+    *Ptr = *Start;\r
+    Start++;\r
+    Ptr++;\r
+    Len--;\r
+  }\r
+\r
+  *Ptr = 0;\r
+  return String;\r
+}\r
+//\r
+// Parse:\r
+//    #string STR_ID_NAME\r
+//\r
+// All we can do is call the string database to add the string identifier. Unfortunately\r
+// he'll have to keep track of the last identifier we added.\r
+//\r
+static\r
+void\r
+ProcessTokenString (\r
+  SOURCE_FILE *SourceFile\r
+  )\r
+{\r
+  WCHAR   StringIdentifier[MAX_STRING_IDENTIFIER_NAME + 1];\r
+  UINT16  StringId;\r
+  //\r
+  // Extract the string identifier name and add it to the database.\r
+  //\r
+  if (GetStringIdentifierName (SourceFile, StringIdentifier, sizeof (StringIdentifier)) > 0) {\r
+    StringId = STRING_ID_INVALID;\r
+    StringDBAddStringIdentifier (StringIdentifier, &StringId, 0);\r
+  } else {\r
+    //\r
+    // Error recovery -- skip to the next #\r
+    //\r
+    SourceFile->SkipToHash = TRUE;\r
+  }\r
+}\r
+\r
+static\r
+BOOLEAN\r
+EndOfFile (\r
+  SOURCE_FILE *SourceFile\r
+  )\r
+{\r
+  //\r
+  // The file buffer pointer will typically get updated before the End-of-file flag in the\r
+  // source file structure, so check it first.\r
+  //\r
+  if (SourceFile->FileBufferPtr >= SourceFile->FileBuffer + SourceFile->FileSize / sizeof (WCHAR)) {\r
+    SourceFile->EndOfFile = TRUE;\r
+    return TRUE;\r
+  }\r
+\r
+  if (SourceFile->EndOfFile) {\r
+    return TRUE;\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
+static\r
+UINT32\r
+GetStringIdentifierName (\r
+  IN SOURCE_FILE  *SourceFile,\r
+  IN OUT WCHAR    *StringIdentifierName,\r
+  IN UINT32       StringIdentifierNameLen\r
+  )\r
+{\r
+  UINT32  Len;\r
+  WCHAR   *From;\r
+  WCHAR   *Start;\r
+\r
+  //\r
+  // Skip whitespace\r
+  //\r
+  SkipWhiteSpace (SourceFile);\r
+  if (SourceFile->EndOfFile) {\r
+    Error (SourceFile->FileName, SourceFile->LineNum, 0, "end-of-file encountered", "expected string identifier");\r
+    return 0;\r
+  }\r
+  //\r
+  // Verify first character of name is [A-Za-z]\r
+  //\r
+  Len = 0;\r
+  StringIdentifierNameLen /= 2;\r
+  From  = SourceFile->FileBufferPtr;\r
+  Start = SourceFile->FileBufferPtr;\r
+  if (((SourceFile->FileBufferPtr[0] >= UNICODE_A) && (SourceFile->FileBufferPtr[0] <= UNICODE_Z)) ||\r
+      ((SourceFile->FileBufferPtr[0] >= UNICODE_z) && (SourceFile->FileBufferPtr[0] <= UNICODE_z))\r
+      ) {\r
+    //\r
+    // Do nothing\r
+    //\r
+  } else {\r
+    Error (SourceFile->FileName, SourceFile->LineNum, 0, "invalid character in string identifier name", "%S", Start);\r
+    return 0;\r
+  }\r
+\r
+  while (!EndOfFile (SourceFile)) {\r
+    if (((SourceFile->FileBufferPtr[0] >= UNICODE_A) && (SourceFile->FileBufferPtr[0] <= UNICODE_Z)) ||\r
+        ((SourceFile->FileBufferPtr[0] >= UNICODE_z) && (SourceFile->FileBufferPtr[0] <= UNICODE_z)) ||\r
+        ((SourceFile->FileBufferPtr[0] >= UNICODE_0) && (SourceFile->FileBufferPtr[0] <= UNICODE_9)) ||\r
+        (SourceFile->FileBufferPtr[0] == UNICODE_UNDERSCORE)\r
+        ) {\r
+      Len++;\r
+      if (Len >= StringIdentifierNameLen) {\r
+        Error (SourceFile->FileName, SourceFile->LineNum, 0, "string identifier name too long", "%S", Start);\r
+        return 0;\r
+      }\r
+\r
+      *StringIdentifierName = SourceFile->FileBufferPtr[0];\r
+      StringIdentifierName++;\r
+      SourceFile->FileBufferPtr++;\r
+    } else if (SkipWhiteSpace (SourceFile) == 0) {\r
+      Error (SourceFile->FileName, SourceFile->LineNum, 0, "invalid string identifier name", "%S", Start);\r
+      return 0;\r
+    } else {\r
+      break;\r
+    }\r
+  }\r
+  //\r
+  // Terminate the copy of the string.\r
+  //\r
+  *StringIdentifierName = 0;\r
+  return Len;\r
+}\r
+\r
+static\r
+STATUS\r
+GetLanguageIdentifierName (\r
+  IN SOURCE_FILE  *SourceFile,\r
+  IN OUT WCHAR    *LanguageIdentifierName,\r
+  IN UINT32       LanguageIdentifierNameLen,\r
+  IN BOOLEAN      Optional\r
+  )\r
+{\r
+  UINT32  Len;\r
+  WCHAR   *Start;\r
+  WCHAR   *LangCode;\r
+  WCHAR   *LanguageIdentifier;\r
+\r
+  LanguageIdentifier = LanguageIdentifierName;\r
+\r
+  //\r
+  // Skip whitespace\r
+  //\r
+  SkipWhiteSpace (SourceFile);\r
+  if (SourceFile->EndOfFile) {\r
+    if (!Optional) {\r
+      Error (SourceFile->FileName, SourceFile->LineNum, 0, "end-of-file encountered", "expected language identifier");\r
+      return STATUS_ERROR;\r
+    }\r
+\r
+    return STATUS_SUCCESS;\r
+  }\r
+  //\r
+  // This function is called to optionally get a language identifier name in:\r
+  //   #string STR_ID eng "the string"\r
+  // If it's optional, and we find a double-quote, then return now.\r
+  //\r
+  if (Optional) {\r
+    if (*SourceFile->FileBufferPtr == UNICODE_DOUBLE_QUOTE) {\r
+      return STATUS_SUCCESS;\r
+    }\r
+  }\r
+\r
+  LanguageIdentifierNameLen /= 2;\r
+  //\r
+  // Internal error if we weren't given at least 4 WCHAR's to work with.\r
+  //\r
+  if (LanguageIdentifierNameLen < LANGUAGE_IDENTIFIER_NAME_LEN + 1) {\r
+    Error (\r
+      SourceFile->FileName,\r
+      SourceFile->LineNum,\r
+      0,\r
+      "app error -- language identifier name length is invalid",\r
+      NULL\r
+      );\r
+  }\r
+\r
+  Len   = 0;\r
+  Start = SourceFile->FileBufferPtr;\r
+  while (!EndOfFile (SourceFile)) {\r
+    if (((SourceFile->FileBufferPtr[0] >= UNICODE_a) && (SourceFile->FileBufferPtr[0] <= UNICODE_z)) ||\r
+        ((SourceFile->FileBufferPtr[0] >= UNICODE_A) && (SourceFile->FileBufferPtr[0] <= UNICODE_Z)) ||\r
+        (SourceFile->FileBufferPtr[0] == UNICODE_MINUS)) {\r
+      Len++;\r
+      if (Len > LANGUAGE_IDENTIFIER_NAME_LEN) {\r
+        Error (SourceFile->FileName, SourceFile->LineNum, 0, "language identifier name too long", "%S", Start);\r
+        return STATUS_ERROR;\r
+      }\r
+      *LanguageIdentifierName = SourceFile->FileBufferPtr[0];\r
+      SourceFile->FileBufferPtr++;\r
+      LanguageIdentifierName++;\r
+    } else if (!IsWhiteSpace (SourceFile)) {\r
+      Error (SourceFile->FileName, SourceFile->LineNum, 0, "invalid language identifier name", "%S", Start);\r
+      return STATUS_ERROR;\r
+    } else {\r
+      break;\r
+    }\r
+  }\r
+  //\r
+  // Terminate the copy of the string.\r
+  //\r
+  *LanguageIdentifierName = 0;\r
+  LangCode = GetLangCode (LanguageIdentifier);\r
+  if (LangCode != NULL) {\r
+    wcscpy (LanguageIdentifier, LangCode);\r
+    FREE (LangCode);\r
+  }\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+static\r
+void\r
+ProcessTokenInclude (\r
+  SOURCE_FILE *SourceFile\r
+  )\r
+{\r
+  INT8        IncludeFileName[MAX_PATH];\r
+  INT8        *To;\r
+  UINT32      Len;\r
+  BOOLEAN     ReportedError;\r
+  SOURCE_FILE IncludedSourceFile;\r
+\r
+  ReportedError = FALSE;\r
+  if (SkipWhiteSpace (SourceFile) == 0) {\r
+    Warning (SourceFile->FileName, SourceFile->LineNum, 0, "expected whitespace following #include keyword", NULL);\r
+  }\r
+  //\r
+  // Should be quoted file name\r
+  //\r
+  if (SourceFile->FileBufferPtr[0] != UNICODE_DOUBLE_QUOTE) {\r
+    Error (SourceFile->FileName, SourceFile->LineNum, 0, "expected quoted include file name", NULL);\r
+    goto FailDone;\r
+  }\r
+\r
+  SourceFile->FileBufferPtr++;\r
+  //\r
+  // Copy the filename as ascii to our local string\r
+  //\r
+  To  = IncludeFileName;\r
+  Len = 0;\r
+  while (!EndOfFile (SourceFile)) {\r
+    if ((SourceFile->FileBufferPtr[0] == UNICODE_CR) || (SourceFile->FileBufferPtr[0] == UNICODE_LF)) {\r
+      Error (SourceFile->FileName, SourceFile->LineNum, 0, "end-of-line found in quoted include file name", NULL);\r
+      goto FailDone;\r
+    }\r
+\r
+    if (SourceFile->FileBufferPtr[0] == UNICODE_DOUBLE_QUOTE) {\r
+      SourceFile->FileBufferPtr++;\r
+      break;\r
+    }\r
+    //\r
+    // If too long, then report the error once and process until the closing quote\r
+    //\r
+    Len++;\r
+    if (!ReportedError && (Len >= sizeof (IncludeFileName))) {\r
+      Error (SourceFile->FileName, SourceFile->LineNum, 0, "length of include file name exceeds limit", NULL);\r
+      ReportedError = TRUE;\r
+    }\r
+\r
+    if (!ReportedError) {\r
+      *To = UNICODE_TO_ASCII (SourceFile->FileBufferPtr[0]);\r
+      To++;\r
+    }\r
+\r
+    SourceFile->FileBufferPtr++;\r
+  }\r
+\r
+  if (!ReportedError) {\r
+    *To = 0;\r
+    memset ((char *) &IncludedSourceFile, 0, sizeof (SOURCE_FILE));\r
+    strcpy (IncludedSourceFile.FileName, IncludeFileName);\r
+    IncludedSourceFile.ControlCharacter = DEFAULT_CONTROL_CHARACTER;\r
+    ProcessIncludeFile (&IncludedSourceFile, SourceFile);\r
+    //\r
+    // printf ("including file '%s'\n", IncludeFileName);\r
+    //\r
+  }\r
+\r
+  return ;\r
+FailDone:\r
+  //\r
+  // Error recovery -- skip to next #\r
+  //\r
+  SourceFile->SkipToHash = TRUE;\r
+}\r
+\r
+static\r
+void\r
+ProcessTokenScope (\r
+  SOURCE_FILE *SourceFile\r
+  )\r
+{\r
+  WCHAR StringIdentifier[MAX_STRING_IDENTIFIER_NAME + 1];\r
+  //\r
+  // Extract the scope name\r
+  //\r
+  if (GetStringIdentifierName (SourceFile, StringIdentifier, sizeof (StringIdentifier)) > 0) {\r
+    StringDBSetScope (StringIdentifier);\r
+  }\r
+}\r
+\r
+//\r
+// Parse:  #langdef eng "English"\r
+//         #langdef chn "\wideChinese"\r
+//\r
+static\r
+void\r
+ProcessTokenLangDef (\r
+  SOURCE_FILE *SourceFile\r
+  )\r
+{\r
+  STATUS  Status;\r
+  WCHAR   LanguageIdentifier[MAX_STRING_IDENTIFIER_NAME + 1];\r
+  WCHAR   *PrintableName;\r
+\r
+  Status = GetLanguageIdentifierName (SourceFile, LanguageIdentifier, sizeof (LanguageIdentifier), FALSE);\r
+  if (Status != STATUS_SUCCESS) {\r
+    return;\r
+  }\r
+\r
+  //\r
+  // Extract the printable name\r
+  //\r
+  PrintableName = GetPrintableLanguageName (SourceFile);\r
+  if (PrintableName != NULL) {\r
+    ParserSetPosition (SourceFile->FileName, SourceFile->LineNum);\r
+    StringDBAddLanguage (LanguageIdentifier, PrintableName, NULL);\r
+    FREE (PrintableName);\r
+    return ;\r
+  }\r
+  //\r
+  // Error recovery -- skip to next #\r
+  //\r
+  SourceFile->SkipToHash = TRUE;\r
+}\r
+\r
+static\r
+VOID\r
+ProcessTokenSecondaryLangDef (\r
+  SOURCE_FILE *SourceFile\r
+  )\r
+{\r
+  STATUS        Status;\r
+  LANGUAGE_LIST *Lang;\r
+  WCHAR         LanguageIdentifier[MAX_STRING_IDENTIFIER_NAME + 1];\r
+  WCHAR         *LangCode;\r
+  WCHAR         *SecondaryLangList = NULL;\r
+\r
+  Status = GetLanguageIdentifierName (SourceFile, LanguageIdentifier, sizeof (LanguageIdentifier), FALSE);\r
+  if (Status != STATUS_SUCCESS) {\r
+    return;\r
+  }\r
+  LangCode = GetLangCode(LanguageIdentifier);\r
+  if (LangCode == NULL) {\r
+    return ;\r
+  }\r
+\r
+  Lang = StringDBFindLanguageList (LanguageIdentifier);\r
+  if (Lang == NULL) {\r
+    return;\r
+  }\r
+\r
+  SecondaryLangList = GetSecondaryLanguageList (SourceFile);\r
+  if (SecondaryLangList != NULL) {\r
+    ParserSetPosition (SourceFile->FileName, SourceFile->LineNum);\r
+    Status = StringDBAddSecondaryLanguage (LangCode, GetLangCodeList(SecondaryLangList));\r
+    if (Status != STATUS_SUCCESS) {\r
+      SourceFile->SkipToHash = TRUE;\r
+    }\r
+    FREE (LangCode);\r
+    FREE (SecondaryLangList);\r
+    return ;\r
+  }\r
+  FREE (LangCode);\r
+\r
+\r
+  SourceFile->SkipToHash = TRUE;\r
+}\r
+\r
+static\r
+BOOLEAN\r
+ApparentQuotedString (\r
+  SOURCE_FILE *SourceFile\r
+  )\r
+{\r
+  WCHAR *Ptr;\r
+  //\r
+  // See if the first and last nonblank characters on the line are double quotes\r
+  //\r
+  for (Ptr = SourceFile->FileBufferPtr; *Ptr && (*Ptr == UNICODE_SPACE); Ptr++)\r
+    ;\r
+  if (*Ptr != UNICODE_DOUBLE_QUOTE) {\r
+    return FALSE;\r
+  }\r
+\r
+  while (*Ptr) {\r
+    Ptr++;\r
+  }\r
+\r
+  Ptr--;\r
+  for (; *Ptr && (*Ptr == UNICODE_SPACE); Ptr--)\r
+    ;\r
+  if (*Ptr != UNICODE_DOUBLE_QUOTE) {\r
+    return FALSE;\r
+  }\r
+\r
+  return TRUE;\r
+}\r
+//\r
+// Parse:\r
+//   #language eng "some string " "more string"\r
+//\r
+static\r
+void\r
+ProcessTokenLanguage (\r
+  SOURCE_FILE *SourceFile\r
+  )\r
+{\r
+  STATUS  Status;\r
+  WCHAR   *String;\r
+  WCHAR   *SecondString;\r
+  WCHAR   *TempString;\r
+  WCHAR   *From;\r
+  WCHAR   *To;\r
+  WCHAR   Language[LANGUAGE_IDENTIFIER_NAME_LEN + 1];\r
+  UINT32  Len;\r
+  BOOLEAN PreviousNewline;\r
+  //\r
+  // Get the language identifier\r
+  //\r
+  Language[0] = 0;\r
+  Status = GetLanguageIdentifierName (SourceFile, Language, sizeof (Language), TRUE);\r
+  if (Status != STATUS_SUCCESS) {\r
+    return;\r
+  }\r
+\r
+  //\r
+  // Extract the string value. It's either a quoted string that starts on the current line, or\r
+  // an unquoted string that starts on the following line and continues until the next control\r
+  // character in column 1.\r
+  // Look ahead to find a quote or a newline\r
+  //\r
+  if (SkipTo (SourceFile, UNICODE_DOUBLE_QUOTE, TRUE)) {\r
+    String = GetQuotedString (SourceFile, FALSE);\r
+    if (String != NULL) {\r
+      //\r
+      // Set the position in the file of where we are parsing for error\r
+      // reporting purposes. Then start looking ahead for additional\r
+      // quoted strings, and concatenate them until we get a failure\r
+      // back from the string parser.\r
+      //\r
+      Len = wcslen (String) + 1;\r
+      ParserSetPosition (SourceFile->FileName, SourceFile->LineNum);\r
+      do {\r
+        SkipWhiteSpace (SourceFile);\r
+        SecondString = GetQuotedString (SourceFile, TRUE);\r
+        if (SecondString != NULL) {\r
+          Len += wcslen (SecondString);\r
+          TempString = (WCHAR *) malloc (Len * sizeof (WCHAR));\r
+          if (TempString == NULL) {\r
+            Error (NULL, 0, 0, "application error", "failed to allocate memory");\r
+            return ;\r
+          }\r
+\r
+          wcscpy (TempString, String);\r
+          wcscat (TempString, SecondString);\r
+          free (String);\r
+          free (SecondString);\r
+          String = TempString;\r
+        }\r
+      } while (SecondString != NULL);\r
+      StringDBAddString (Language, NULL, NULL, String, TRUE, 0);\r
+      free (String);\r
+    } else {\r
+      //\r
+      // Error was reported at lower level. Error recovery mode.\r
+      //\r
+      SourceFile->SkipToHash = TRUE;\r
+    }\r
+  } else {\r
+    if (!mGlobals.UnquotedStrings) {\r
+      //\r
+      // They're using unquoted strings. If the next non-blank character is a double quote, and the\r
+      // last non-blank character on the line is a double quote, then more than likely they're using\r
+      // quotes, so they need to put the quoted string on the end of the previous line\r
+      //\r
+      if (ApparentQuotedString (SourceFile)) {\r
+        Warning (\r
+          SourceFile->FileName,\r
+          SourceFile->LineNum,\r
+          0,\r
+          "unexpected quoted string on line",\r
+          "specify -uqs option if necessary"\r
+          );\r
+      }\r
+    }\r
+    //\r
+    // Found end-of-line (hopefully). Skip over it and start taking in characters\r
+    // until we find a control character at the start of a line.\r
+    //\r
+    Len             = 0;\r
+    From            = SourceFile->FileBufferPtr;\r
+    PreviousNewline = FALSE;\r
+    while (!EndOfFile (SourceFile)) {\r
+      if (SourceFile->FileBufferPtr[0] == UNICODE_LF) {\r
+        PreviousNewline = TRUE;\r
+        SourceFile->LineNum++;\r
+      } else {\r
+        Len++;\r
+        if (PreviousNewline && (SourceFile->FileBufferPtr[0] == SourceFile->ControlCharacter)) {\r
+          break;\r
+        }\r
+\r
+        PreviousNewline = FALSE;\r
+      }\r
+\r
+      SourceFile->FileBufferPtr++;\r
+    }\r
+\r
+    if ((Len == 0) && EndOfFile (SourceFile)) {\r
+      Error (SourceFile->FileName, SourceFile->LineNum, 0, "unexpected end of file", NULL);\r
+      SourceFile->SkipToHash = TRUE;\r
+      return ;\r
+    }\r
+    //\r
+    // Now allocate a buffer, copy the characters, and add the string.\r
+    //\r
+    String = (WCHAR *) malloc ((Len + 1) * sizeof (WCHAR));\r
+    if (String == NULL) {\r
+      Error (NULL, 0, 0, "application error", "failed to allocate memory");\r
+      return ;\r
+    }\r
+\r
+    To = String;\r
+    while (From < SourceFile->FileBufferPtr) {\r
+      switch (*From) {\r
+      case UNICODE_LF:\r
+      case 0:\r
+        break;\r
+\r
+      default:\r
+        *To = *From;\r
+        To++;\r
+        break;\r
+      }\r
+\r
+      From++;\r
+    }\r
+\r
+    //\r
+    // String[Len] = 0;\r
+    //\r
+    *To = 0;\r
+    StringDBAddString (Language, NULL, NULL, String, TRUE, 0);\r
+  }\r
+}\r
+\r
+static\r
+BOOLEAN\r
+IsWhiteSpace (\r
+  SOURCE_FILE *SourceFile\r
+  )\r
+{\r
+  switch (SourceFile->FileBufferPtr[0]) {\r
+  case UNICODE_NULL:\r
+  case UNICODE_CR:\r
+  case UNICODE_SPACE:\r
+  case UNICODE_TAB:\r
+  case UNICODE_LF:\r
+    return TRUE;\r
+\r
+  default:\r
+    return FALSE;\r
+  }\r
+}\r
+\r
+static\r
+UINT32\r
+SkipWhiteSpace (\r
+  SOURCE_FILE *SourceFile\r
+  )\r
+{\r
+  UINT32  Count;\r
+\r
+  Count = 0;\r
+  while (!EndOfFile (SourceFile)) {\r
+    Count++;\r
+    switch (*SourceFile->FileBufferPtr) {\r
+    case UNICODE_NULL:\r
+    case UNICODE_CR:\r
+    case UNICODE_SPACE:\r
+    case UNICODE_TAB:\r
+      SourceFile->FileBufferPtr++;\r
+      break;\r
+\r
+    case UNICODE_LF:\r
+      SourceFile->FileBufferPtr++;\r
+      SourceFile->LineNum++;\r
+      if (mGlobals.Verbose) {\r
+        printf ("%d: %S\n", SourceFile->LineNum, SourceFile->FileBufferPtr);\r
+      }\r
+      break;\r
+\r
+    default:\r
+      return Count - 1;\r
+    }\r
+  }\r
+  //\r
+  // Some tokens require trailing whitespace. If we're at the end of the\r
+  // file, then we count that as well.\r
+  //\r
+  if ((Count == 0) && (EndOfFile (SourceFile))) {\r
+    Count++;\r
+  }\r
+\r
+  return Count;\r
+}\r
+\r
+static\r
+UINT32\r
+wstrcmp (\r
+  WCHAR *Buffer,\r
+  WCHAR *Str\r
+  )\r
+{\r
+  UINT32  Len;\r
+\r
+  Len = 0;\r
+  while (*Str == *Buffer) {\r
+    Buffer++;\r
+    Str++;\r
+    Len++;\r
+  }\r
+\r
+  if (*Str) {\r
+    return 0;\r
+  }\r
+\r
+  return Len;\r
+}\r
+\r
+static\r
+WCHAR *\r
+wstrcatenate (\r
+  WCHAR *Dst,\r
+  WCHAR *Src\r
+  )\r
+{\r
+  UINT32 Len  = 0;\r
+  WCHAR  *Bak = Dst;\r
+\r
+  if (Src == NULL) {\r
+    return Dst;\r
+  }\r
+\r
+  if (Dst != NULL) {\r
+    Len = wcslen (Dst);\r
+  }\r
+  Len += wcslen (Src);\r
+  Dst = (WCHAR *) malloc ((Len + 1) * 2);\r
+  if (Dst == NULL) {\r
+    return NULL;\r
+  }\r
+\r
+  Dst[0] = L'\0';\r
+  if (Bak != NULL) {\r
+    wcscpy (Dst, Bak);\r
+    FREE (Bak);\r
+  }\r
+  wcscat (Dst, Src);\r
+  return Dst;\r
+}\r
+\r
+//\r
+// Given a filename, try to find it along the include paths.\r
+//\r
+static\r
+FILE *\r
+FindFile (\r
+  IN INT8    *FileName,\r
+  OUT INT8   *FoundFileName,\r
+  IN UINT32  FoundFileNameLen\r
+  )\r
+{\r
+  FILE              *Fptr;\r
+  TEXT_STRING_LIST  *List;\r
+\r
+  //\r
+  // Traverse the list of paths and try to find the file\r
+  //\r
+  List = mGlobals.IncludePaths;\r
+  while (List != NULL) {\r
+    //\r
+    // Put the path and filename together\r
+    //\r
+    if (strlen (List->Str) + strlen (FileName) + 1 > FoundFileNameLen) {\r
+      Error (PROGRAM_NAME, 0, 0, NULL, "internal error - cannot concatenate path+filename");\r
+      return NULL;\r
+    }\r
+    //\r
+    // Append the filename to this include path and try to open the file.\r
+    //\r
+    strcpy (FoundFileName, List->Str);\r
+    strcat (FoundFileName, FileName);\r
+    if ((Fptr = fopen (FoundFileName, "rb")) != NULL) {\r
+      //\r
+      // Return the file pointer\r
+      //\r
+      return Fptr;\r
+    }\r
+\r
+    List = List->Next;\r
+  }\r
+  //\r
+  // Not found\r
+  //\r
+  FoundFileName[0] = 0;\r
+  return NULL;\r
+}\r
+//\r
+// Process the command-line arguments\r
+//\r
+static\r
+STATUS\r
+ProcessArgs (\r
+  int   Argc,\r
+  char  *Argv[]\r
+  )\r
+{\r
+  TEXT_STRING_LIST  *NewList;\r
+  //\r
+  // Clear our globals\r
+  //\r
+  memset ((char *) &mGlobals, 0, sizeof (mGlobals));\r
+  strcpy (mGlobals.BaseName, DEFAULT_BASE_NAME);\r
+  //\r
+  // Skip program name\r
+  //\r
+  Argc--;\r
+  Argv++;\r
+\r
+  if (Argc == 0) {\r
+    Usage ();\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  mGlobals.Mode = MODE_UNKNOWN;\r
+  //\r
+  // Process until no more -args.\r
+  //\r
+  while ((Argc > 0) && (Argv[0][0] == '-')) {\r
+    //\r
+    // -parse option\r
+    //\r
+    if (_stricmp (Argv[0], "-parse") == 0) {\r
+      if (mGlobals.Mode != MODE_UNKNOWN) {\r
+        Error (NULL, 0, 0, "only one of -parse/-scan/-dump allowed", NULL);\r
+        return STATUS_ERROR;\r
+      }\r
+\r
+      mGlobals.Mode = MODE_PARSE;\r
+      //\r
+      // -scan option\r
+      //\r
+    } else if (_stricmp (Argv[0], "-scan") == 0) {\r
+      if (mGlobals.Mode != MODE_UNKNOWN) {\r
+        Error (NULL, 0, 0, "only one of -parse/-scan/-dump allowed", NULL);\r
+        return STATUS_ERROR;\r
+      }\r
+\r
+      mGlobals.Mode = MODE_SCAN;\r
+      //\r
+      // -vscan verbose scanning option\r
+      //\r
+    } else if (_stricmp (Argv[0], "-vscan") == 0) {\r
+      mGlobals.VerboseScan = TRUE;\r
+      //\r
+      // -dump option\r
+      //\r
+    } else if (_stricmp (Argv[0], "-dump") == 0) {\r
+      if (mGlobals.Mode != MODE_UNKNOWN) {\r
+        Error (NULL, 0, 0, "only one of -parse/-scan/-dump allowed", NULL);\r
+        return STATUS_ERROR;\r
+      }\r
+\r
+      mGlobals.Mode = MODE_DUMP;\r
+    } else if (_stricmp (Argv[0], "-uqs") == 0) {\r
+      mGlobals.UnquotedStrings = TRUE;\r
+      //\r
+      // -i path    add include search path when parsing\r
+      //\r
+    } else if (_stricmp (Argv[0], "-i") == 0) {\r
+      //\r
+      // check for one more arg\r
+      //\r
+      if ((Argc <= 1) || (Argv[1][0] == '-')) {\r
+        Error (PROGRAM_NAME, 0, 0, Argv[0], "missing include path");\r
+        return STATUS_ERROR;\r
+      }\r
+      //\r
+      // Allocate memory for a new list element, fill it in, and\r
+      // add it to our list of include paths. Always make sure it\r
+      // has a "\" on the end of it.\r
+      //\r
+      NewList = malloc (sizeof (TEXT_STRING_LIST));\r
+      if (NewList == NULL) {\r
+        Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure");\r
+        return STATUS_ERROR;\r
+      }\r
+\r
+      memset ((char *) NewList, 0, sizeof (TEXT_STRING_LIST));\r
+      NewList->Str = malloc (strlen (Argv[1]) + 2);\r
+      if (NewList->Str == NULL) {\r
+        free (NewList);\r
+        Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure");\r
+        return STATUS_ERROR;\r
+      }\r
+\r
+      strcpy (NewList->Str, Argv[1]);\r
+      if (NewList->Str[strlen (NewList->Str) - 1] != '\\') {\r
+        strcat (NewList->Str, "\\");\r
+      }\r
+      //\r
+      // Add it to our linked list\r
+      //\r
+      if (mGlobals.IncludePaths == NULL) {\r
+        mGlobals.IncludePaths = NewList;\r
+      } else {\r
+        mGlobals.LastIncludePath->Next = NewList;\r
+      }\r
+\r
+      mGlobals.LastIncludePath = NewList;\r
+      Argc--;\r
+      Argv++;\r
+    } else if (_stricmp (Argv[0], "-if") == 0) {\r
+      //\r
+      // Indirection file -- check for one more arg\r
+      //\r
+      if ((Argc <= 1) || (Argv[1][0] == '-')) {\r
+        Error (PROGRAM_NAME, 0, 0, Argv[0], "missing indirection file name");\r
+        return STATUS_ERROR;\r
+      }\r
+      //\r
+      // Allocate memory for a new list element, fill it in, and\r
+      // add it to our list of include paths. Always make sure it\r
+      // has a "\" on the end of it.\r
+      //\r
+      NewList = malloc (sizeof (TEXT_STRING_LIST));\r
+      if (NewList == NULL) {\r
+        Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure");\r
+        return STATUS_ERROR;\r
+      }\r
+\r
+      memset ((char *) NewList, 0, sizeof (TEXT_STRING_LIST));\r
+      NewList->Str = malloc (strlen (Argv[1]) + 1);\r
+      if (NewList->Str == NULL) {\r
+        free (NewList);\r
+        Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure");\r
+        return STATUS_ERROR;\r
+      }\r
+\r
+      strcpy (NewList->Str, Argv[1]);\r
+      //\r
+      // Add it to our linked list\r
+      //\r
+      if (mGlobals.IndirectionFileName == NULL) {\r
+        mGlobals.IndirectionFileName = NewList;\r
+      } else {\r
+        mGlobals.LastIndirectionFileName->Next = NewList;\r
+      }\r
+\r
+      mGlobals.LastIndirectionFileName = NewList;\r
+      Argc--;\r
+      Argv++;\r
+    } else if (_stricmp (Argv[0], "-db") == 0) {\r
+      //\r
+      // -db option to specify a database file.\r
+      // Check for one more arg (the database file name)\r
+      //\r
+      if ((Argc <= 1) || (Argv[1][0] == '-')) {\r
+        Error (PROGRAM_NAME, 0, 0, Argv[0], "missing database file name");\r
+        return STATUS_ERROR;\r
+      }\r
+\r
+      NewList = malloc (sizeof (TEXT_STRING_LIST));\r
+      if (NewList == NULL) {\r
+        Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure");\r
+        return STATUS_ERROR;\r
+      }\r
+\r
+      memset ((char *) NewList, 0, sizeof (TEXT_STRING_LIST));\r
+      NewList->Str = malloc (strlen (Argv[1]) + 1);\r
+      if (NewList->Str == NULL) {\r
+        free (NewList);\r
+        Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure");\r
+        return STATUS_ERROR;\r
+      }\r
+\r
+      strcpy (NewList->Str, Argv[1]);\r
+      //\r
+      // Add it to our linked list\r
+      //\r
+      if (mGlobals.DatabaseFileName == NULL) {\r
+        mGlobals.DatabaseFileName = NewList;\r
+      } else {\r
+        mGlobals.LastDatabaseFileName->Next = NewList;\r
+      }\r
+\r
+      mGlobals.LastDatabaseFileName = NewList;\r
+      Argc--;\r
+      Argv++;\r
+    } else if (_stricmp (Argv[0], "-ou") == 0) {\r
+      //\r
+      // -ou option to specify an output unicode file to\r
+      // which we can dump our database.\r
+      //\r
+      if ((Argc <= 1) || (Argv[1][0] == '-')) {\r
+        Error (PROGRAM_NAME, 0, 0, Argv[0], "missing database dump output file name");\r
+        return STATUS_ERROR;\r
+      }\r
+\r
+      if (mGlobals.DumpUFileName[0] == 0) {\r
+        strcpy (mGlobals.DumpUFileName, Argv[1]);\r
+      } else {\r
+        Error (PROGRAM_NAME, 0, 0, Argv[1], "-ou option already specified with '%s'", mGlobals.DumpUFileName);\r
+        return STATUS_ERROR;\r
+      }\r
+\r
+      Argc--;\r
+      Argv++;\r
+    } else if (_stricmp (Argv[0], "-hpk") == 0) {\r
+      //\r
+      // -hpk option to create an HII export pack of the input database file\r
+      //\r
+      if ((Argc <= 1) || (Argv[1][0] == '-')) {\r
+        Error (PROGRAM_NAME, 0, 0, Argv[0], "missing raw string data dump output file name");\r
+        return STATUS_ERROR;\r
+      }\r
+\r
+      if (mGlobals.HiiExportPackFileName[0] == 0) {\r
+        strcpy (mGlobals.HiiExportPackFileName, Argv[1]);\r
+      } else {\r
+        Error (PROGRAM_NAME, 0, 0, Argv[1], "-or option already specified with '%s'", mGlobals.HiiExportPackFileName);\r
+        return STATUS_ERROR;\r
+      }\r
+\r
+      Argc--;\r
+      Argv++;\r
+    } else if ((_stricmp (Argv[0], "-?") == 0) || (_stricmp (Argv[0], "-h") == 0)) {\r
+      Usage ();\r
+      return STATUS_ERROR;\r
+    } else if (_stricmp (Argv[0], "-v") == 0) {\r
+      mGlobals.Verbose = 1;\r
+    } else if (_stricmp (Argv[0], "-vdbw") == 0) {\r
+      mGlobals.VerboseDatabaseWrite = 1;\r
+    } else if (_stricmp (Argv[0], "-vdbr") == 0) {\r
+      mGlobals.VerboseDatabaseRead = 1;\r
+    } else if (_stricmp (Argv[0], "-newdb") == 0) {\r
+      mGlobals.NewDatabase = 1;\r
+    } else if (_stricmp (Argv[0], "-ignorenotfound") == 0) {\r
+      mGlobals.IgnoreNotFound = 1;\r
+    } else if (_stricmp (Argv[0], "-oc") == 0) {\r
+      //\r
+      // check for one more arg\r
+      //\r
+      if ((Argc <= 1) || (Argv[1][0] == '-')) {\r
+        Error (PROGRAM_NAME, 0, 0, Argv[0], "missing output C filename");\r
+        return STATUS_ERROR;\r
+      }\r
+\r
+      strcpy (mGlobals.StringCFileName, Argv[1]);\r
+      Argc--;\r
+      Argv++;\r
+    } else if (_stricmp (Argv[0], "-bn") == 0) {\r
+      //\r
+      // check for one more arg\r
+      //\r
+      if ((Argc <= 1) || (Argv[1][0] == '-')) {\r
+        Error (PROGRAM_NAME, 0, 0, Argv[0], "missing base name");\r
+        Usage ();\r
+        return STATUS_ERROR;\r
+      }\r
+\r
+      strcpy (mGlobals.BaseName, Argv[1]);\r
+      Argc--;\r
+      Argv++;\r
+    } else if (_stricmp (Argv[0], "-oh") == 0) {\r
+      //\r
+      // -oh to specify output .h defines file name\r
+      //\r
+      if ((Argc <= 1) || (Argv[1][0] == '-')) {\r
+        Error (PROGRAM_NAME, 0, 0, Argv[0], "missing output .h filename");\r
+        return STATUS_ERROR;\r
+      }\r
+\r
+      strcpy (mGlobals.StringHFileName, Argv[1]);\r
+      Argc--;\r
+      Argv++;\r
+    } else if (_stricmp (Argv[0], "-dep") == 0) {\r
+      //\r
+      // -dep to specify output dependency file name\r
+      //\r
+      if ((Argc <= 1) || (Argv[1][0] == '-')) {\r
+        Error (PROGRAM_NAME, 0, 0, Argv[0], "missing output dependency filename");\r
+        return STATUS_ERROR;\r
+      }\r
+\r
+      strcpy (mGlobals.OutputDependencyFileName, Argv[1]);\r
+      Argc--;\r
+      Argv++;\r
+    } else if (_stricmp (Argv[0], "-skipext") == 0) {\r
+      //\r
+      // -skipext to skip scanning of files with certain filename extensions\r
+      //\r
+      if ((Argc <= 1) || (Argv[1][0] == '-')) {\r
+        Error (PROGRAM_NAME, 0, 0, Argv[0], "missing filename extension");\r
+        return STATUS_ERROR;\r
+      }\r
+      //\r
+      // Allocate memory for a new list element, fill it in, and\r
+      // add it to our list of excluded extensions. Always make sure it\r
+      // has a "." as the first character.\r
+      //\r
+      NewList = malloc (sizeof (TEXT_STRING_LIST));\r
+      if (NewList == NULL) {\r
+        Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure");\r
+        return STATUS_ERROR;\r
+      }\r
+\r
+      memset ((char *) NewList, 0, sizeof (TEXT_STRING_LIST));\r
+      NewList->Str = malloc (strlen (Argv[1]) + 2);\r
+      if (NewList->Str == NULL) {\r
+        free (NewList);\r
+        Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure");\r
+        return STATUS_ERROR;\r
+      }\r
+\r
+      if (Argv[1][0] == '.') {\r
+        strcpy (NewList->Str, Argv[1]);\r
+      } else {\r
+        NewList->Str[0] = '.';\r
+        strcpy (NewList->Str + 1, Argv[1]);\r
+      }\r
+      //\r
+      // Add it to our linked list\r
+      //\r
+      if (mGlobals.SkipExt == NULL) {\r
+        mGlobals.SkipExt = NewList;\r
+      } else {\r
+        mGlobals.LastSkipExt->Next = NewList;\r
+      }\r
+\r
+      mGlobals.LastSkipExt = NewList;\r
+      Argc--;\r
+      Argv++;\r
+    } else if (_stricmp (Argv[0], "-lang") == 0) {\r
+      //\r
+      // "-lang eng" or "-lang spa+cat" to only output certain languages\r
+      //\r
+      if ((Argc <= 1) || (Argv[1][0] == '-')) {\r
+        Error (PROGRAM_NAME, 0, 0, Argv[0], "missing language name");\r
+        Usage ();\r
+        return STATUS_ERROR;\r
+      }\r
+\r
+      if (AddCommandLineLanguage (Argv[1]) != STATUS_SUCCESS) {\r
+        return STATUS_ERROR;\r
+      }\r
+\r
+      Argc--;\r
+      Argv++;\r
+    } else if (_stricmp (Argv[0], "-od") == 0) {\r
+      //\r
+      // Output database file name -- check for another arg\r
+      //\r
+      if ((Argc <= 1) || (Argv[1][0] == '-')) {\r
+        Error (PROGRAM_NAME, 0, 0, Argv[0], "missing output database file name");\r
+        return STATUS_ERROR;\r
+      }\r
+\r
+      strcpy (mGlobals.OutputDatabaseFileName, Argv[1]);\r
+      Argv++;\r
+      Argc--;\r
+    } else {\r
+      //\r
+      // Unrecognized arg\r
+      //\r
+      Error (PROGRAM_NAME, 0, 0, Argv[0], "unrecognized option");\r
+      Usage ();\r
+      return STATUS_ERROR;\r
+    }\r
+\r
+    Argv++;\r
+    Argc--;\r
+  }\r
+  //\r
+  // Make sure they specified the mode parse/scan/dump\r
+  //\r
+  if (mGlobals.Mode == MODE_UNKNOWN) {\r
+    Error (NULL, 0, 0, "must specify one of -parse/-scan/-dump", NULL);\r
+    return STATUS_ERROR;\r
+  }\r
+  //\r
+  // All modes require a database filename\r
+  //\r
+  if (mGlobals.DatabaseFileName == 0) {\r
+    Error (NULL, 0, 0, "must specify a database filename using -db DbFileName", NULL);\r
+    Usage ();\r
+    return STATUS_ERROR;\r
+  }\r
+  //\r
+  // If dumping the database file, then return immediately if all\r
+  // parameters check out.\r
+  //\r
+  if (mGlobals.Mode == MODE_DUMP) {\r
+    //\r
+    // Not much use if they didn't specify -oh or -oc or -ou or -hpk\r
+    //\r
+    if ((mGlobals.DumpUFileName[0] == 0) &&\r
+        (mGlobals.StringHFileName[0] == 0) &&\r
+        (mGlobals.StringCFileName[0] == 0) &&\r
+        (mGlobals.HiiExportPackFileName[0] == 0)\r
+        ) {\r
+      Error (NULL, 0, 0, "-dump without -oc/-oh/-ou/-hpk is a NOP", NULL);\r
+      return STATUS_ERROR;\r
+    }\r
+\r
+    return STATUS_SUCCESS;\r
+  }\r
+  //\r
+  // Had to specify source string file and output string defines header filename.\r
+  //\r
+  if (mGlobals.Mode == MODE_SCAN) {\r
+    if (Argc < 1) {\r
+      Error (PROGRAM_NAME, 0, 0, NULL, "must specify at least one source file to scan with -scan");\r
+      Usage ();\r
+      return STATUS_ERROR;\r
+    }\r
+    //\r
+    // Get the list of filenames\r
+    //\r
+    while (Argc > 0) {\r
+      NewList = malloc (sizeof (TEXT_STRING_LIST));\r
+      if (NewList == NULL) {\r
+        Error (PROGRAM_NAME, 0, 0, "memory allocation failure", NULL);\r
+        return STATUS_ERROR;\r
+      }\r
+\r
+      memset (NewList, 0, sizeof (TEXT_STRING_LIST));\r
+      NewList->Str = (UINT8 *) malloc (strlen (Argv[0]) + 1);\r
+      if (NewList->Str == NULL) {\r
+        Error (PROGRAM_NAME, 0, 0, "memory allocation failure", NULL);\r
+        return STATUS_ERROR;\r
+      }\r
+\r
+      strcpy (NewList->Str, Argv[0]);\r
+      if (mGlobals.ScanFileName == NULL) {\r
+        mGlobals.ScanFileName = NewList;\r
+      } else {\r
+        mGlobals.LastScanFileName->Next = NewList;\r
+      }\r
+\r
+      mGlobals.LastScanFileName = NewList;\r
+      Argc--;\r
+      Argv++;\r
+    }\r
+  } else {\r
+    //\r
+    // Parse mode -- must specify an input unicode file name\r
+    //\r
+    if (Argc < 1) {\r
+      Error (PROGRAM_NAME, 0, 0, NULL, "must specify input unicode string file name with -parse");\r
+      Usage ();\r
+      return STATUS_ERROR;\r
+    }\r
+\r
+    strcpy (mGlobals.SourceFiles.FileName, Argv[0]);\r
+  }\r
+\r
+  return STATUS_SUCCESS;\r
+}\r
+//\r
+// Found "-lang eng,spa+cat" on the command line. Parse the\r
+// language list and save the setting for later processing.\r
+//\r
+static\r
+STATUS\r
+AddCommandLineLanguage (\r
+  IN INT8          *Language\r
+  )\r
+{\r
+  WCHAR_STRING_LIST *WNewList;\r
+  WCHAR             *From;\r
+  WCHAR             *To;\r
+  //\r
+  // Keep processing the input string until we find the end.\r
+  //\r
+  while (*Language) {\r
+    //\r
+    // Allocate memory for a new list element, fill it in, and\r
+    // add it to our list.\r
+    //\r
+    WNewList = MALLOC (sizeof (WCHAR_STRING_LIST));\r
+    if (WNewList == NULL) {\r
+      Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure");\r
+      return STATUS_ERROR;\r
+    }\r
+\r
+    memset ((char *) WNewList, 0, sizeof (WCHAR_STRING_LIST));\r
+    WNewList->Str = malloc ((strlen (Language) + 1) * sizeof (WCHAR));\r
+    if (WNewList->Str == NULL) {\r
+      free (WNewList);\r
+      Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure");\r
+      return STATUS_ERROR;\r
+    }\r
+    //\r
+    // Copy it as unicode to our new structure. Then remove the\r
+    // plus signs in it, and verify each language name is 3 characters\r
+    // long. If we find a comma, then we're done with this group, so\r
+    // break out.\r
+    //\r
+#ifdef USE_VC8\r
+    swprintf (WNewList->Str, (strlen (Language) + 1) * sizeof (WCHAR), L"%S", Language);\r
+#else\r
+    swprintf (WNewList->Str, L"%S", Language);\r
+#endif\r
+    From = To = WNewList->Str;\r
+    while (*From) {\r
+      if (*From == L',') {\r
+        break;\r
+      }\r
+\r
+      if ((wcslen (From) < LANGUAGE_IDENTIFIER_NAME_LEN) ||\r
+            (\r
+              (From[LANGUAGE_IDENTIFIER_NAME_LEN] != 0) &&\r
+              (From[LANGUAGE_IDENTIFIER_NAME_LEN] != UNICODE_PLUS_SIGN) &&\r
+              (From[LANGUAGE_IDENTIFIER_NAME_LEN] != L',')\r
+            )\r
+          ) {\r
+        Error (PROGRAM_NAME, 0, 0, Language, "invalid format for language name on command line");\r
+        FREE (WNewList->Str);\r
+        FREE (WNewList);\r
+        return STATUS_ERROR;\r
+      }\r
+\r
+      wcsncpy (To, From, LANGUAGE_IDENTIFIER_NAME_LEN);\r
+      To += LANGUAGE_IDENTIFIER_NAME_LEN;\r
+      From += LANGUAGE_IDENTIFIER_NAME_LEN;\r
+      if (*From == L'+') {\r
+        From++;\r
+      }\r
+    }\r
+\r
+    *To = 0;\r
+    //\r
+    // Add it to our linked list\r
+    //\r
+    if (mGlobals.Language == NULL) {\r
+      mGlobals.Language = WNewList;\r
+    } else {\r
+      mGlobals.LastLanguage->Next = WNewList;\r
+    }\r
+\r
+    mGlobals.LastLanguage = WNewList;\r
+    //\r
+    // Skip to next entry (comma-separated list)\r
+    //\r
+    while (*Language) {\r
+      if (*Language == L',') {\r
+        Language++;\r
+        break;\r
+      }\r
+\r
+      Language++;\r
+    }\r
+  }\r
+\r
+  return STATUS_SUCCESS;\r
+}\r
+//\r
+// The contents of the text file are expected to be (one per line)\r
+//   STRING_IDENTIFIER_NAME   ScopeName\r
+// For example:\r
+//   STR_ID_MY_FAVORITE_STRING   IBM\r
+//\r
+static\r
+STATUS\r
+ParseIndirectionFiles (\r
+  TEXT_STRING_LIST    *Files\r
+  )\r
+{\r
+  FILE                        *Fptr;\r
+  INT8                        Line[200];\r
+  INT8                        *StringName;\r
+  INT8                        *ScopeName;\r
+  INT8                        *End;\r
+  UINT32                      LineCount;\r
+  WCHAR_MATCHING_STRING_LIST  *NewList;\r
+\r
+  Line[sizeof (Line) - 1] = 0;\r
+  Fptr                    = NULL;\r
+  while (Files != NULL) {\r
+    Fptr      = fopen (Files->Str, "r");\r
+    LineCount = 0;\r
+    if (Fptr == NULL) {\r
+      Error (NULL, 0, 0, Files->Str, "failed to open input indirection file for reading");\r
+      return STATUS_ERROR;\r
+    }\r
+\r
+    while (fgets (Line, sizeof (Line), Fptr) != NULL) {\r
+      //\r
+      // remove terminating newline for error printing purposes.\r
+      //\r
+      if (Line[strlen (Line) - 1] == '\n') {\r
+        Line[strlen (Line) - 1] = 0;\r
+      }\r
+\r
+      LineCount++;\r
+      if (Line[sizeof (Line) - 1] != 0) {\r
+        Error (Files->Str, LineCount, 0, "line length exceeds maximum supported", NULL);\r
+        goto Done;\r
+      }\r
+\r
+      StringName = Line;\r
+      while (*StringName && (isspace (*StringName))) {\r
+        StringName++;\r
+      }\r
+\r
+      if (*StringName) {\r
+        if ((*StringName == '_') || isalpha (*StringName)) {\r
+          End = StringName;\r
+          while ((*End) && (*End == '_') || (isalnum (*End))) {\r
+            End++;\r
+          }\r
+\r
+          if (isspace (*End)) {\r
+            *End = 0;\r
+            End++;\r
+            while (isspace (*End)) {\r
+              End++;\r
+            }\r
+\r
+            if (*End) {\r
+              ScopeName = End;\r
+              while (*End && !isspace (*End)) {\r
+                End++;\r
+              }\r
+\r
+              *End = 0;\r
+              //\r
+              // Add the string name/scope pair\r
+              //\r
+              NewList = malloc (sizeof (WCHAR_MATCHING_STRING_LIST));\r
+              if (NewList == NULL) {\r
+                Error (NULL, 0, 0, "memory allocation error", NULL);\r
+                goto Done;\r
+              }\r
+\r
+              memset (NewList, 0, sizeof (WCHAR_MATCHING_STRING_LIST));\r
+              NewList->Str1 = (WCHAR *) malloc ((strlen (StringName) + 1) * sizeof (WCHAR));\r
+              NewList->Str2 = (WCHAR *) malloc ((strlen (ScopeName) + 1) * sizeof (WCHAR));\r
+              if ((NewList->Str1 == NULL) || (NewList->Str2 == NULL)) {\r
+                Error (NULL, 0, 0, "memory allocation error", NULL);\r
+                goto Done;\r
+              }\r
+\r
+#ifdef USE_VC8\r
+              swprintf (NewList->Str1, (strlen (StringName) + 1) * sizeof (WCHAR), L"%S", StringName);\r
+              swprintf (NewList->Str2, (strlen (ScopeName) + 1) * sizeof (WCHAR), L"%S", ScopeName);\r
+#else\r
+              swprintf (NewList->Str1, L"%S", StringName);\r
+              swprintf (NewList->Str2, L"%S", ScopeName);\r
+#endif\r
+              if (mGlobals.IndirectionList == NULL) {\r
+                mGlobals.IndirectionList = NewList;\r
+              } else {\r
+                mGlobals.LastIndirectionList->Next = NewList;\r
+              }\r
+\r
+              mGlobals.LastIndirectionList = NewList;\r
+            } else {\r
+              Error (Files->Str, LineCount, 0, StringName, "invalid line : expected 'StringIdentifier Scope'");\r
+              goto Done;\r
+            }\r
+          } else {\r
+            Error (Files->Str, LineCount, 0, StringName, "invalid line : expected 'StringIdentifier Scope'");\r
+            goto Done;\r
+          }\r
+        } else {\r
+          Error (Files->Str, LineCount, 0, StringName, "invalid string identifier");\r
+          goto Done;\r
+        }\r
+      }\r
+    }\r
+\r
+    fclose (Fptr);\r
+    Fptr  = NULL;\r
+    Files = Files->Next;\r
+  }\r
+\r
+Done:\r
+  if (Fptr != NULL) {\r
+    fclose (Fptr);\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+static\r
+STATUS\r
+ScanFiles (\r
+  TEXT_STRING_LIST *ScanFiles\r
+  )\r
+{\r
+  char              Line[MAX_LINE_LEN];\r
+  FILE              *Fptr;\r
+  UINT32            LineNum;\r
+  char              *Cptr;\r
+  char              *SavePtr;\r
+  char              *TermPtr;\r
+  char              *StringTokenPos;\r
+  TEXT_STRING_LIST  *SList;\r
+  BOOLEAN           SkipIt;\r
+\r
+  //\r
+  // Put a null-terminator at the end of the line. If we read in\r
+  // a line longer than we support, then we can catch it.\r
+  //\r
+  Line[MAX_LINE_LEN - 1] = 0;\r
+  //\r
+  // Process each file. If they gave us a skip extension list, then\r
+  // skip it if the extension matches.\r
+  //\r
+  while (ScanFiles != NULL) {\r
+    SkipIt = FALSE;\r
+    for (SList = mGlobals.SkipExt; SList != NULL; SList = SList->Next) {\r
+      if ((strlen (ScanFiles->Str) > strlen (SList->Str)) &&\r
+          (strcmp (ScanFiles->Str + strlen (ScanFiles->Str) - strlen (SList->Str), SList->Str) == 0)\r
+          ) {\r
+        SkipIt = TRUE;\r
+        //\r
+        // printf ("Match: %s : %s\n", ScanFiles->Str, SList->Str);\r
+        //\r
+        break;\r
+      }\r
+    }\r
+\r
+    if (!SkipIt) {\r
+      if (mGlobals.VerboseScan) {\r
+        printf ("Scanning %s\n", ScanFiles->Str);\r
+      }\r
+\r
+      Fptr = fopen (ScanFiles->Str, "r");\r
+      if (Fptr == NULL) {\r
+        Error (NULL, 0, 0, ScanFiles->Str, "failed to open input file for scanning");\r
+        return STATUS_ERROR;\r
+      }\r
+\r
+      LineNum = 0;\r
+      while (fgets (Line, sizeof (Line), Fptr) != NULL) {\r
+        LineNum++;\r
+        if (Line[MAX_LINE_LEN - 1] != 0) {\r
+          Error (ScanFiles->Str, LineNum, 0, "line length exceeds maximum supported by tool", NULL);\r
+          fclose (Fptr);\r
+          return STATUS_ERROR;\r
+        }\r
+        //\r
+        // Remove the newline from the input line so we can print a warning message\r
+        //\r
+        if (Line[strlen (Line) - 1] == '\n') {\r
+          Line[strlen (Line) - 1] = 0;\r
+        }\r
+        //\r
+        // Terminate the line at // comments\r
+        //\r
+        Cptr = strstr (Line, "//");\r
+        if (Cptr != NULL) {\r
+          *Cptr = 0;\r
+        }\r
+\r
+        Cptr = Line;\r
+        while ((Cptr = strstr (Cptr, STRING_TOKEN)) != NULL) {\r
+          //\r
+          // Found "STRING_TOKEN". Make sure we don't have NUM_STRING_TOKENS or\r
+          // something like that. Then make sure it's followed by\r
+          // an open parenthesis, a string identifier, and then a closing\r
+          // parenthesis.\r
+          //\r
+          if (mGlobals.VerboseScan) {\r
+            printf (" %d: %s", LineNum, Cptr);\r
+          }\r
+\r
+          if (((Cptr == Line) || (!IsValidIdentifierChar (*(Cptr - 1), FALSE))) &&\r
+              (!IsValidIdentifierChar (*(Cptr + sizeof (STRING_TOKEN) - 1), FALSE))\r
+              ) {\r
+            StringTokenPos  = Cptr;\r
+            SavePtr         = Cptr;\r
+            Cptr += strlen (STRING_TOKEN);\r
+            while (*Cptr && isspace (*Cptr) && (*Cptr != '(')) {\r
+              Cptr++;\r
+            }\r
+\r
+            if (*Cptr != '(') {\r
+              Warning (ScanFiles->Str, LineNum, 0, StringTokenPos, "expected "STRING_TOKEN "(identifier)");\r
+            } else {\r
+              //\r
+              // Skip over the open-parenthesis and find the next non-blank character\r
+              //\r
+              Cptr++;\r
+              while (isspace (*Cptr)) {\r
+                Cptr++;\r
+              }\r
+\r
+              SavePtr = Cptr;\r
+              if ((*Cptr == '_') || isalpha (*Cptr)) {\r
+                while ((*Cptr == '_') || (isalnum (*Cptr))) {\r
+                  Cptr++;\r
+                }\r
+\r
+                TermPtr = Cptr;\r
+                while (*Cptr && isspace (*Cptr)) {\r
+                  Cptr++;\r
+                }\r
+\r
+                if (*Cptr != ')') {\r
+                  Warning (ScanFiles->Str, LineNum, 0, StringTokenPos, "expected "STRING_TOKEN "(identifier)");\r
+                }\r
+\r
+                if (*TermPtr) {\r
+                  *TermPtr  = 0;\r
+                  Cptr      = TermPtr + 1;\r
+                } else {\r
+                  Cptr = TermPtr;\r
+                }\r
+                //\r
+                // Add the string identifier to the list of used strings\r
+                //\r
+                ParserSetPosition (ScanFiles->Str, LineNum);\r
+                StringDBSetStringReferenced (SavePtr, mGlobals.IgnoreNotFound);\r
+                if (mGlobals.VerboseScan) {\r
+                  printf ("...referenced %s", SavePtr);\r
+                }\r
+              } else {\r
+                Warning (ScanFiles->Str, LineNum, 0, StringTokenPos, "expected valid string identifier name");\r
+              }\r
+            }\r
+          } else {\r
+            //\r
+            // Found it, but it's a substring of something else. Advance our pointer.\r
+            //\r
+            Cptr++;\r
+          }\r
+\r
+          if (mGlobals.VerboseScan) {\r
+            printf ("\n");\r
+          }\r
+        }\r
+      }\r
+\r
+      fclose (Fptr);\r
+    } else {\r
+      //\r
+      // Skipping this file type\r
+      //\r
+      if (mGlobals.VerboseScan) {\r
+        printf ("Skip scanning of %s\n", ScanFiles->Str);\r
+      }\r
+    }\r
+\r
+    ScanFiles = ScanFiles->Next;\r
+  }\r
+\r
+  return STATUS_SUCCESS;\r
+}\r
+//\r
+// Free the global string lists we allocated memory for\r
+//\r
+static\r
+void\r
+FreeLists (\r
+  VOID\r
+  )\r
+{\r
+  TEXT_STRING_LIST  *Temp;\r
+  WCHAR_STRING_LIST *WTemp;\r
+\r
+  //\r
+  // Traverse the include paths, freeing each\r
+  //\r
+  while (mGlobals.IncludePaths != NULL) {\r
+    Temp = mGlobals.IncludePaths->Next;\r
+    free (mGlobals.IncludePaths->Str);\r
+    free (mGlobals.IncludePaths);\r
+    mGlobals.IncludePaths = Temp;\r
+  }\r
+  //\r
+  // If we did a scan, then free up our\r
+  // list of files to scan.\r
+  //\r
+  while (mGlobals.ScanFileName != NULL) {\r
+    Temp = mGlobals.ScanFileName->Next;\r
+    free (mGlobals.ScanFileName->Str);\r
+    free (mGlobals.ScanFileName);\r
+    mGlobals.ScanFileName = Temp;\r
+  }\r
+  //\r
+  // If they gave us a list of filename extensions to\r
+  // skip on scan, then free them up.\r
+  //\r
+  while (mGlobals.SkipExt != NULL) {\r
+    Temp = mGlobals.SkipExt->Next;\r
+    free (mGlobals.SkipExt->Str);\r
+    free (mGlobals.SkipExt);\r
+    mGlobals.SkipExt = Temp;\r
+  }\r
+  //\r
+  // Free up any languages specified\r
+  //\r
+  while (mGlobals.Language != NULL) {\r
+    WTemp = mGlobals.Language->Next;\r
+    free (mGlobals.Language->Str);\r
+    free (mGlobals.Language);\r
+    mGlobals.Language = WTemp;\r
+  }\r
+  //\r
+  // Free up our indirection list\r
+  //\r
+  while (mGlobals.IndirectionList != NULL) {\r
+    mGlobals.LastIndirectionList = mGlobals.IndirectionList->Next;\r
+    free (mGlobals.IndirectionList->Str1);\r
+    free (mGlobals.IndirectionList->Str2);\r
+    free (mGlobals.IndirectionList);\r
+    mGlobals.IndirectionList = mGlobals.LastIndirectionList;\r
+  }\r
+\r
+  while (mGlobals.IndirectionFileName != NULL) {\r
+    mGlobals.LastIndirectionFileName = mGlobals.IndirectionFileName->Next;\r
+    free (mGlobals.IndirectionFileName->Str);\r
+    free (mGlobals.IndirectionFileName);\r
+    mGlobals.IndirectionFileName = mGlobals.LastIndirectionFileName;\r
+  }\r
+}\r
+\r
+static\r
+BOOLEAN\r
+IsValidIdentifierChar (\r
+  INT8      Char,\r
+  BOOLEAN   FirstChar\r
+  )\r
+{\r
+  //\r
+  // If it's the first character of an identifier, then\r
+  // it must be one of [A-Za-z_].\r
+  //\r
+  if (FirstChar) {\r
+    if (isalpha (Char) || (Char == '_')) {\r
+      return TRUE;\r
+    }\r
+  } else {\r
+    //\r
+    // If it's not the first character, then it can\r
+    // be one of [A-Za-z_0-9]\r
+    //\r
+    if (isalnum (Char) || (Char == '_')) {\r
+      return TRUE;\r
+    }\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
+static\r
+void\r
+RewindFile (\r
+  SOURCE_FILE *SourceFile\r
+  )\r
+{\r
+  SourceFile->LineNum       = 1;\r
+  SourceFile->FileBufferPtr = SourceFile->FileBuffer;\r
+  SourceFile->EndOfFile     = FALSE;\r
+}\r
+\r
+static\r
+BOOLEAN\r
+SkipTo (\r
+  SOURCE_FILE *SourceFile,\r
+  WCHAR       WChar,\r
+  BOOLEAN     StopAfterNewline\r
+  )\r
+{\r
+  while (!EndOfFile (SourceFile)) {\r
+    //\r
+    // Check for the character of interest\r
+    //\r
+    if (SourceFile->FileBufferPtr[0] == WChar) {\r
+      return TRUE;\r
+    } else {\r
+      if (SourceFile->FileBufferPtr[0] == UNICODE_LF) {\r
+        SourceFile->LineNum++;\r
+        if (StopAfterNewline) {\r
+          SourceFile->FileBufferPtr++;\r
+          if (SourceFile->FileBufferPtr[0] == 0) {\r
+            SourceFile->FileBufferPtr++;\r
+          }\r
+\r
+          return FALSE;\r
+        }\r
+      }\r
+\r
+      SourceFile->FileBufferPtr++;\r
+    }\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
+static\r
+void\r
+Usage (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Print usage information for this utility.\r
+  \r
+Arguments:\r
+\r
+  None.\r
+\r
+Returns:\r
+\r
+  Nothing.\r
+  \r
+--*/\r
+{\r
+  int               Index;\r
+  static const char *Str[] = {\r
+    "",\r
+    PROGRAM_NAME " version "TOOL_VERSION " -- process unicode strings file",\r
+    "  Usage: "PROGRAM_NAME " -parse {parse options} [FileNames]",\r
+    "         "PROGRAM_NAME " -scan {scan options} [FileName]",\r
+    "         "PROGRAM_NAME " -dump {dump options}",\r
+    "    Common options include:",\r
+    "      -h or -?         for this help information",\r
+    "      -db Database     required name of output/input database file",\r
+    "      -bn BaseName     for use in the .h and .c output files",\r
+    "                       Default = "DEFAULT_BASE_NAME,\r
+    "      -v               for verbose output",\r
+    "      -vdbw            for verbose output when writing database",\r
+    "      -vdbr            for verbose output when reading database",\r
+    "      -od FileName     to specify an output database file name",\r
+    "    Parse options include:",\r
+    "      -i IncludePath   add IncludePath to list of search paths",\r
+    "      -dep FileName    to specify an output dependency file name",\r
+    "      -newdb           to not read in existing database file",\r
+    "      -uqs             to indicate that unquoted strings are used",\r
+    "      FileNames        name of one or more unicode files to parse",\r
+    "    Scan options include:",\r
+    "      -scan            scan text file(s) for STRING_TOKEN() usage",\r
+    "      -skipext .ext    to skip scan of files with .ext filename extension",\r
+    "      -ignorenotfound  ignore if a given STRING_TOKEN(STR) is not ",\r
+    "                       found in the database",\r
+    "      FileNames        one or more files to scan",\r
+    "    Dump options include:",\r
+    "      -oc FileName     write string data to FileName",\r
+    "      -oh FileName     write string defines to FileName",\r
+    "      -ou FileName     dump database to unicode file FileName",\r
+    "      -lang Lang       only dump for the language 'Lang'",\r
+    "      -if FileName     to specify an indirection file",\r
+    "      -hpk FileName    to create an HII export pack of the strings",\r
+    "",\r
+    "  The expected process is to parse a unicode string file to create an initial",\r
+    "  database of string identifier names and string definitions. Then text files",\r
+    "  should be scanned for STRING_TOKEN() usages, and the referenced",\r
+    "  strings will be tagged as used in the database. After all files have been",\r
+    "  scanned, then the database should be dumped to create the necessary output",\r
+    "  files.",\r
+    "",\r
+    NULL\r
+  };\r
+  for (Index = 0; Str[Index] != NULL; Index++) {\r
+    fprintf (stdout, "%s\n", Str[Index]);\r
+  }\r
+}\r
diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/UefiStrGather/StrGather.h b/EdkCompatibilityPkg/Sample/Tools/Source/UefiStrGather/StrGather.h
new file mode 100644 (file)
index 0000000..a14ef92
--- /dev/null
@@ -0,0 +1,87 @@
+/*++\r
+\r
+Copyright (c) 2004, Intel Corporation                                                         \r
+All rights reserved. This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+  StrGather.h\r
+\r
+Abstract:\r
+\r
+  Common defines and prototypes for StrGather.\r
+  \r
+--*/\r
+\r
+#ifndef _STR_GATHER_H_\r
+#define _STR_GATHER_H_\r
+\r
+#define MALLOC(size)  malloc (size)\r
+#define FREE(ptr)     do { if ((ptr) != NULL) { free (ptr); } } while (0)\r
+\r
+#define PROGRAM_NAME  "StrGather"\r
+\r
+typedef CHAR16  WCHAR;\r
+\r
+#define UNICODE_TO_ASCII(w)   (INT8) ((w) & 0xFF)\r
+#define ASCII_TO_UNICODE(a)   (WCHAR) ((UINT8) (a))\r
+\r
+#define UNICODE_HASH          L'#'\r
+#define UNICODE_BACKSLASH     L'\\'\r
+#define UNICODE_SLASH         L'/'\r
+#define UNICODE_EQUAL_SIGN    L'='\r
+#define UNICODE_PLUS_SIGN     L'+'\r
+\r
+#define UNICODE_FILE_START    0xFEFF\r
+#define UNICODE_CR            0x000D\r
+#define UNICODE_LF            0x000A\r
+#define UNICODE_NULL          0x0000\r
+#define UNICODE_SPACE         L' '\r
+#define UNICODE_SLASH         L'/'\r
+#define UNICODE_DOUBLE_QUOTE  L'"'\r
+#define UNICODE_OPEN_PAREN    L'('\r
+#define UNICODE_CLOSE_PAREN   L')'\r
+#define UNICODE_Z             L'Z'\r
+#define UNICODE_z             L'z'\r
+#define UNICODE_A             L'A'\r
+#define UNICODE_a             L'a'\r
+#define UNICODE_F             L'F'\r
+#define UNICODE_f             L'f'\r
+#define UNICODE_UNDERSCORE    L'_'\r
+#define UNICODE_MINUS         L'-'\r
+#define UNICODE_0             L'0'\r
+#define UNICODE_9             L'9'\r
+#define UNICODE_TAB           L'\t'\r
+#define UNICODE_NBR_STRING    L"\\nbr"\r
+#define UNICODE_BR_STRING     L"\\br"\r
+#define UNICODE_WIDE_STRING   L"\\wide"\r
+#define UNICODE_NARROW_STRING L"\\narrow"\r
+\r
+//\r
+// This is the length of a valid string identifier\r
+//\r
+#define LANGUAGE_IDENTIFIER_NAME_LEN  128\r
+\r
+typedef struct _TEXT_STRING_LIST {\r
+  struct _TEXT_STRING_LIST  *Next;\r
+  UINT8                     *Str;\r
+} TEXT_STRING_LIST;\r
+\r
+typedef struct _WCHAR_STRING_LIST {\r
+  struct _WCHAR_STRING_LIST *Next;\r
+  WCHAR                     *Str;\r
+} WCHAR_STRING_LIST;\r
+\r
+typedef struct _WCHAR_MATCHING_STRING_LIST {\r
+  struct _WCHAR_MATCHING_STRING_LIST  *Next;\r
+  WCHAR                               *Str1;\r
+  WCHAR                               *Str2;\r
+} WCHAR_MATCHING_STRING_LIST;\r
+\r
+#endif // #ifndef _STR_GATHER_H_\r
diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/UefiStrGather/StringDB.c b/EdkCompatibilityPkg/Sample/Tools/Source/UefiStrGather/StringDB.c
new file mode 100644 (file)
index 0000000..ac6fef8
--- /dev/null
@@ -0,0 +1,2674 @@
+/*++\r
+\r
+Copyright (c) 2004 - 2007, Intel Corporation                                                         \r
+All rights reserved. This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+  StringDB.c\r
+\r
+Abstract:\r
+\r
+  String database implementation\r
+  \r
+--*/\r
+\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+#include <ctype.h>\r
+#include <Tiano.h>\r
+#include <EfiUtilityMsgs.h>\r
+#include <EfiHii.h>\r
+#include "StrGather.h"\r
+#include "StringDb.h"\r
+\r
+static STRING_DB_DATA mDBData;\r
+\r
+static const char     *mSourceFileHeader[] = {\r
+  "//",\r
+  "//  DO NOT EDIT -- auto-generated file",\r
+  "//",\r
+  "//  This file is generated by the string gather utility",\r
+  "//",\r
+  NULL\r
+};\r
+\r
+static\r
+STRING_LIST           *\r
+StringDBFindString (\r
+  WCHAR                       *LanguageName,\r
+  WCHAR                       *StringName,\r
+  WCHAR                       *Scope,\r
+  WCHAR_STRING_LIST           *LanguagesOfInterest,\r
+  WCHAR_MATCHING_STRING_LIST  *IndirectionList\r
+  );\r
+\r
+static\r
+STRING_IDENTIFIER     *\r
+StringDBFindStringIdentifierByName (\r
+  WCHAR *Name\r
+  );\r
+\r
+static\r
+STRING_IDENTIFIER     *\r
+StringDBFindStringIdentifierByIndex (\r
+  UINT32    Index\r
+  );\r
+\r
+static\r
+void\r
+StringDBWriteStandardFileHeader (\r
+  FILE *OutFptr\r
+  );\r
+\r
+static\r
+WCHAR                 *\r
+AsciiToWchar (\r
+  INT8 *Str\r
+  );\r
+\r
+static\r
+CHAR8 *\r
+WcharToAscii (\r
+  WCHAR *Str\r
+  );\r
+\r
+static\r
+WCHAR                 *\r
+DuplicateString (\r
+  WCHAR   *Str\r
+  );\r
+\r
+static\r
+WCHAR *\r
+WstrCatenate (\r
+  WCHAR *Dst,\r
+  WCHAR *Src\r
+  );\r
+\r
+static\r
+STATUS\r
+StringDBWriteStringIdentifier (\r
+  FILE                *DBFptr,\r
+  UINT16              StringId,\r
+  UINT16              Flags,\r
+  WCHAR               *IdentifierName\r
+  );\r
+\r
+static\r
+STATUS\r
+StringDBReadStringIdentifier (\r
+  FILE                *DBFptr\r
+  );\r
+\r
+static\r
+STATUS\r
+StringDBWriteLanguageDefinition (\r
+  FILE            *DBFptr,\r
+  WCHAR           *LanguageName,\r
+  WCHAR           *PrintableLanguageName,\r
+  WCHAR           *SecondaryLanguageList\r
+  );\r
+\r
+static\r
+STATUS\r
+StringDBReadLanguageDefinition (\r
+  FILE            *DBFptr\r
+  );\r
+\r
+static\r
+STATUS\r
+StringDBWriteString (\r
+  FILE            *DBFptr,\r
+  UINT16          Flags,\r
+  WCHAR           *Language,\r
+  WCHAR           *StringName,\r
+  WCHAR           *Scope,\r
+  WCHAR           *Str\r
+  );\r
+\r
+static\r
+STATUS\r
+StringDBReadString (\r
+  FILE            *DBFptr\r
+  );\r
+\r
+static\r
+STATUS\r
+StringDBReadGenericString (\r
+  FILE      *DBFptr,\r
+  UINT16    *Size,\r
+  WCHAR     **Str\r
+  );\r
+\r
+static\r
+STATUS\r
+StringDBWriteGenericString (\r
+  FILE      *DBFptr,\r
+  WCHAR     *Str\r
+  );\r
+\r
+static\r
+void\r
+StringDBAssignStringIndexes (\r
+  VOID\r
+  );\r
+\r
+/*****************************************************************************/\r
+\r
+/*++\r
+\r
+Routine Description:\r
+  Constructor function for the string database handler.\r
+\r
+Arguments:\r
+  None.\r
+\r
+Returns:\r
+  None.\r
+\r
+--*/\r
+void\r
+StringDBConstructor (\r
+  VOID\r
+  )\r
+{\r
+  memset ((char *) &mDBData, 0, sizeof (STRING_DB_DATA));\r
+  mDBData.CurrentScope = DuplicateString (L"NULL");\r
+}\r
+\r
+/*****************************************************************************/\r
+\r
+/*++\r
+\r
+Routine Description:\r
+  Destructor function for the string database handler.\r
+\r
+Arguments:\r
+  None.\r
+\r
+Returns:\r
+  None.\r
+\r
+--*/\r
+void\r
+StringDBDestructor (\r
+  VOID\r
+  )\r
+{\r
+  LANGUAGE_LIST     *NextLang;\r
+  STRING_LIST       *NextStr;\r
+  STRING_IDENTIFIER *NextIdentifier;\r
+  //\r
+  // Close the database file if it's open\r
+  //\r
+  if (mDBData.StringDBFptr != NULL) {\r
+    fclose (mDBData.StringDBFptr);\r
+    mDBData.StringDBFptr = NULL;\r
+  }\r
+  //\r
+  // If we've allocated any strings/languages, free them up\r
+  //\r
+  while (mDBData.LanguageList != NULL) {\r
+    NextLang = mDBData.LanguageList->Next;\r
+    //\r
+    // Free up all strings for this language\r
+    //\r
+    while (mDBData.LanguageList->String != NULL) {\r
+      NextStr = mDBData.LanguageList->String->Next;\r
+      FREE (mDBData.LanguageList->String->Str);\r
+      FREE (mDBData.LanguageList->String);\r
+      mDBData.LanguageList->String = NextStr;\r
+    }\r
+\r
+    FREE (mDBData.LanguageList->SecondaryLanguageList);\r
+    FREE (mDBData.LanguageList->PrintableLanguageName);\r
+    FREE (mDBData.LanguageList);\r
+    mDBData.LanguageList = NextLang;\r
+  }\r
+  //\r
+  // Free up string identifiers\r
+  //\r
+  while (mDBData.StringIdentifier != NULL) {\r
+    NextIdentifier = mDBData.StringIdentifier->Next;\r
+    FREE (mDBData.StringIdentifier->StringName);\r
+    FREE (mDBData.StringIdentifier);\r
+    mDBData.StringIdentifier = NextIdentifier;\r
+  }\r
+  //\r
+  // Free the filename\r
+  //\r
+  if (mDBData.StringDBFileName != NULL) {\r
+    FREE (mDBData.StringDBFileName);\r
+    mDBData.StringDBFileName = NULL;\r
+  }\r
+  //\r
+  // We save a copy of the scope, so free it up if we\r
+  // have one.\r
+  //\r
+  if (mDBData.CurrentScope != NULL) {\r
+    FREE (mDBData.CurrentScope);\r
+    mDBData.CurrentScope = NULL;\r
+  }\r
+}\r
+\r
+/*****************************************************************************/\r
+STATUS\r
+StringDBDumpStringDefines (\r
+  INT8 *FileName,\r
+  INT8 *BaseName\r
+  )\r
+{\r
+  FILE              *Fptr;\r
+  STRING_IDENTIFIER *Identifier;\r
+  INT8              CopyBaseName[100];\r
+  UINT32            Index;\r
+  const INT8        *StrDefHeader[] = {\r
+    "#ifndef _%s_STRINGS_DEFINE_H_\n",\r
+    "#define _%s_STRINGS_DEFINE_H_\n\n",\r
+    NULL\r
+  };\r
+\r
+  if ((Fptr = fopen (FileName, "w")) == NULL) {\r
+    Error (NULL, 0, 0, FileName, "failed to open output string defines file");\r
+    return STATUS_ERROR;\r
+  }\r
+  //\r
+  // Get the base source filename and convert to uppercase.\r
+  //\r
+  if (sizeof (CopyBaseName) <= strlen (BaseName) + 1) {\r
+    Error (NULL, 0, 0, "application error", "StringDBDumpStringDefines() string length insufficient");\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  strcpy (CopyBaseName, BaseName);\r
+  for (Index = 0; CopyBaseName[Index] != 0; Index++) {\r
+    if (islower (CopyBaseName[Index])) {\r
+      CopyBaseName[Index] = (INT8) toupper (CopyBaseName[Index]);\r
+    }\r
+  }\r
+  //\r
+  // Assign index values to the string identifiers\r
+  //\r
+  StringDBAssignStringIndexes ();\r
+  //\r
+  // Write the standard header to the output file, and then the\r
+  // protective #ifndef.\r
+  //\r
+  StringDBWriteStandardFileHeader (Fptr);\r
+  for (Index = 0; StrDefHeader[Index] != NULL; Index++) {\r
+    fprintf (Fptr, StrDefHeader[Index], CopyBaseName);\r
+  }\r
+  //\r
+  // Print all the #defines for the string identifiers. Print identifiers\r
+  // whose names start with '$' as comments. Add comments for string\r
+  // identifiers not used as well.\r
+  //\r
+  Identifier = mDBData.StringIdentifier;\r
+  while (Identifier != NULL) {\r
+    if (Identifier->StringName[0] == L'$') {\r
+      fprintf (Fptr, "// ");\r
+    }\r
+\r
+    if (Identifier->Flags & STRING_FLAGS_REFERENCED) {\r
+      fprintf (Fptr, "#define %-40S 0x%04X\n", Identifier->StringName, Identifier->Index);\r
+    } else {\r
+      fprintf (Fptr, "//#define %-40S 0x%04X // not referenced\n", Identifier->StringName, Identifier->Index);\r
+    }\r
+\r
+    Identifier = Identifier->Next;\r
+  }\r
+\r
+  fprintf (Fptr, "\n#endif\n");\r
+  fclose (Fptr);\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+/*****************************************************************************/\r
+\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Add a string identifier to the database.\r
+\r
+Arguments:\r
+\r
+  StringName      - name of the string identifier. For example "STR_MY_STRING"\r
+  NewId           - if an ID has been assigned\r
+  Flags           - characteristics for the identifier\r
+\r
+Returns:\r
+\r
+  STATUS\r
+\r
+--*/\r
+STATUS\r
+StringDBAddStringIdentifier (\r
+  WCHAR     *StringName,\r
+  UINT16    *NewId,\r
+  UINT16    Flags\r
+  )\r
+{\r
+  STRING_IDENTIFIER *StringIdentifier;\r
+  STATUS            Status;\r
+  //\r
+  // If it was already used for some other language, then we don't\r
+  // need to add it. But set it to the current string identifier.\r
+  // The referenced bit is sticky.\r
+  //\r
+  Status            = STATUS_SUCCESS;\r
+  StringIdentifier  = StringDBFindStringIdentifierByName (StringName);\r
+  if (StringIdentifier != NULL) {\r
+    if (Flags & STRING_FLAGS_REFERENCED) {\r
+      StringIdentifier->Flags |= STRING_FLAGS_REFERENCED;\r
+    }\r
+\r
+    mDBData.CurrentStringIdentifier = StringIdentifier;\r
+    *NewId                          = (UINT16) StringIdentifier->Index;\r
+    return Status;\r
+  }\r
+\r
+  StringIdentifier = (STRING_IDENTIFIER *) MALLOC (sizeof (STRING_IDENTIFIER));\r
+  if (StringIdentifier == NULL) {\r
+    Error (NULL, 0, 0, NULL, "memory allocation error");\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  memset ((char *) StringIdentifier, 0, sizeof (STRING_IDENTIFIER));\r
+  StringIdentifier->StringName = (WCHAR *) malloc ((wcslen (StringName) + 1) * sizeof (WCHAR));\r
+  if (StringIdentifier->StringName == NULL) {\r
+    Error (NULL, 0, 0, NULL, "memory allocation error");\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  wcscpy (StringIdentifier->StringName, StringName);\r
+  if (*NewId != STRING_ID_INVALID) {\r
+    StringIdentifier->Index = *NewId;\r
+    StringIdentifier->Flags |= STRING_FLAGS_INDEX_ASSIGNED;\r
+    if (mDBData.NumStringIdentifiers <= StringIdentifier->Index) {\r
+      mDBData.NumStringIdentifiers = StringIdentifier->Index + 1;\r
+    }\r
+  } else {\r
+    StringIdentifier->Index = mDBData.NumStringIdentifiers++;\r
+  }\r
+\r
+  StringIdentifier->Flags |= Flags;\r
+  //\r
+  // Add it to our list of string identifiers\r
+  //\r
+  if (mDBData.StringIdentifier == NULL) {\r
+    mDBData.StringIdentifier = StringIdentifier;\r
+  } else {\r
+    mDBData.LastStringIdentifier->Next = StringIdentifier;\r
+  }\r
+\r
+  mDBData.LastStringIdentifier    = StringIdentifier;\r
+  mDBData.CurrentStringIdentifier = StringIdentifier;\r
+  *NewId                          = (UINT16) StringIdentifier->Index;\r
+  return Status;\r
+}\r
+\r
+/*****************************************************************************/\r
+\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Add a new string to the database.\r
+\r
+Arguments:\r
+\r
+  LanguageName    - "eng" or "spa" language name\r
+  StringName      - "STR_MY_TEXT" string name\r
+  Scope           - from the #scope statements in the string file\r
+  Format          - if we should format the string\r
+  Flags           - characteristic flags for the string\r
+\r
+Returns:\r
+\r
+  STATUS\r
+\r
+Notes:\r
+\r
+  Several of the fields can be "inherited" from the previous calls to\r
+  our database functions. For example, if scope is NULL here, then\r
+  we'll use the previous setting.\r
+\r
+--*/\r
+STATUS\r
+StringDBAddString (\r
+  WCHAR   *LanguageName,\r
+  WCHAR   *StringName,\r
+  WCHAR   *Scope,\r
+  WCHAR   *String,\r
+  BOOLEAN Format,\r
+  UINT16  Flags\r
+  )\r
+{\r
+  LANGUAGE_LIST     *Lang;\r
+  UINT32            Size;\r
+  STRING_LIST       *Str;\r
+  UINT16            StringIndex;\r
+  STRING_IDENTIFIER *StringIdentifier;\r
+\r
+  //\r
+  // If they specified a language, make sure they've defined it already\r
+  // via a #langdef statement. Otherwise use the current default language.\r
+  //\r
+  if (LanguageName != NULL) {\r
+    Lang = StringDBFindLanguageList (LanguageName);\r
+    if (Lang == NULL) {\r
+      ParserError (0, "language not defined", "%S", LanguageName);\r
+      return STATUS_ERROR;\r
+    } else {\r
+      StringDBSetCurrentLanguage (LanguageName);\r
+    }\r
+  } else {\r
+    Lang = mDBData.CurrentLanguage;\r
+    if (Lang == NULL) {\r
+      //\r
+      // Have to call SetLanguage() first\r
+      //\r
+      ParserError (0, "no language defined", "%S", StringName);\r
+      return STATUS_ERROR;\r
+    }\r
+  }\r
+  //\r
+  // If they didn't define a string identifier, use the last string identifier\r
+  // added.\r
+  //\r
+  if (StringName == NULL) {\r
+    StringName = mDBData.CurrentStringIdentifier->StringName;\r
+    if (StringName == NULL) {\r
+      ParserError (0, "no string identifier previously specified", NULL);\r
+      return STATUS_ERROR;\r
+    }\r
+  }\r
+  //\r
+  // If scope was not specified, use the default setting\r
+  //\r
+  if (Scope != NULL) {\r
+    Scope = DuplicateString (Scope);\r
+  } else {\r
+    Scope = DuplicateString (mDBData.CurrentScope);\r
+  }\r
+  //\r
+  // printf ("Adding string: %S.%S.%S\n", Lang->LanguageName, StringName, Scope);\r
+  //\r
+  // Check for duplicates for this Language.StringName.Scope. Allow multiple\r
+  // definitions of the language name and printable language name, since the\r
+  // user does not specifically define them.\r
+  //\r
+  if (StringDBFindString (Lang->LanguageName, StringName, Scope, NULL, NULL) != NULL) {\r
+    if ((wcscmp (StringName, LANGUAGE_NAME_STRING_NAME) == 0) &&\r
+        (wcscmp (StringName, PRINTABLE_LANGUAGE_NAME_STRING_NAME) == 0)\r
+        ) {\r
+      ParserError (\r
+        0,\r
+        "string multiply defined",\r
+        "Language.Name.Scope = %S.%S.%S",\r
+        Lang->LanguageName,\r
+        StringName,\r
+        Scope\r
+        );\r
+      return STATUS_ERROR;\r
+    }\r
+  }\r
+\r
+  StringIndex = STRING_ID_INVALID;\r
+  if (StringDBAddStringIdentifier (StringName, &StringIndex, Flags) != STATUS_SUCCESS) {\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  StringIdentifier = StringDBFindStringIdentifierByName (StringName);\r
+  //\r
+  // Add this string to the end of the strings for this language.\r
+  //\r
+  Str = (STRING_LIST *) malloc (sizeof (STRING_LIST));\r
+  if (Str == NULL) {\r
+    Error (NULL, 0, 0, NULL, "memory allocation error");\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  memset ((char *) Str, 0, sizeof (STRING_LIST));\r
+  Size              = (wcslen (String) + 1) * sizeof (WCHAR);\r
+  Str->Flags        = Flags;\r
+  Str->Scope        = Scope;\r
+  Str->StringName   = StringIdentifier->StringName;\r
+  Str->LanguageName = DuplicateString (LanguageName);\r
+  Str->Str          = (WCHAR *) MALLOC (Size);\r
+  if (Str->Str == NULL) {\r
+    Error (NULL, 0, 0, NULL, "memory allocation error");\r
+    return STATUS_ERROR;\r
+  }\r
+  //\r
+  // If not formatting, just copy the string.\r
+  //\r
+  wcscpy (Str->Str, String);\r
+  if (Format) {\r
+    StringDBFormatString (Str->Str);\r
+  }\r
+  //\r
+  // Size may change after formatting. We set the size to\r
+  // the actual size of the string, including the null for\r
+  // easier processing later.\r
+  //\r
+  Str->Size = (wcslen (Str->Str) + 1) * sizeof (WCHAR);\r
+  if (Lang->String == NULL) {\r
+    Lang->String = Str;\r
+  } else {\r
+    Lang->LastString->Next = Str;\r
+  }\r
+\r
+  Lang->LastString = Str;\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+/*****************************************************************************/\r
+\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Given a language name, see if a language list for it has been defined\r
+\r
+Arguments:\r
+\r
+  LanguageName    - like "eng"\r
+\r
+Returns:\r
+\r
+  A pointer to the language list\r
+\r
+--*/\r
+LANGUAGE_LIST *\r
+StringDBFindLanguageList (\r
+  WCHAR *LanguageName\r
+  )\r
+{\r
+  LANGUAGE_LIST *Lang;\r
+\r
+  Lang = mDBData.LanguageList;\r
+  while (Lang != NULL) {\r
+    if (wcscmp (LanguageName, Lang->LanguageName) == 0) {\r
+      break;\r
+    }\r
+\r
+    Lang = Lang->Next;\r
+  }\r
+\r
+  return Lang;\r
+}\r
+\r
+/*****************************************************************************/\r
+STATUS\r
+StringDBSetCurrentLanguage (\r
+  WCHAR *LanguageName\r
+  )\r
+{\r
+  LANGUAGE_LIST *Lang;\r
+\r
+  Lang = StringDBFindLanguageList (LanguageName);\r
+  if (Lang == NULL) {\r
+    ParserError (0, "language not previously defined", "%S", LanguageName);\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  mDBData.CurrentLanguage = Lang;\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+/*****************************************************************************/\r
+STATUS\r
+StringDBAddLanguage (\r
+  WCHAR *LanguageName,\r
+  WCHAR *PrintableLanguageName,\r
+  WCHAR *SecondaryLanguageList\r
+  )\r
+{\r
+  LANGUAGE_LIST *Lang;\r
+  //\r
+  // Check for redefinitions\r
+  //\r
+  Lang = StringDBFindLanguageList (LanguageName);\r
+  if (Lang != NULL) {\r
+    //\r
+    // Better be the same printable name\r
+    //\r
+    if (wcscmp (PrintableLanguageName, Lang->PrintableLanguageName) != 0) {\r
+      ParserError (\r
+        0,\r
+        "language redefinition",\r
+        "%S:%S != %S:%S",\r
+        Lang->LanguageName,\r
+        Lang->PrintableLanguageName,\r
+        LanguageName,\r
+        PrintableLanguageName\r
+        );\r
+      return STATUS_ERROR;\r
+      //\r
+      //    } else {\r
+      //      ParserWarning (0, "benign language redefinition", "%S", PrintableLanguageName);\r
+      //      return STATUS_WARNING;\r
+      //\r
+    }\r
+  } else {\r
+    //\r
+    // Allocate memory to keep track of this new language\r
+    //\r
+    Lang = (LANGUAGE_LIST *) malloc (sizeof (LANGUAGE_LIST));\r
+    if (Lang == NULL) {\r
+      Error (NULL, 0, 0, NULL, "memory allocation error");\r
+      return STATUS_ERROR;\r
+    }\r
+\r
+    memset ((char *) Lang, 0, sizeof (LANGUAGE_LIST));\r
+    //\r
+    // Save the language name, then allocate memory to save the\r
+    // printable language name\r
+    //\r
+    Lang->LanguageName = (WCHAR *) malloc ((wcslen (LanguageName) + 1) * 2);\r
+       if (Lang->LanguageName == NULL) {\r
+      Error (NULL, 0, 0, NULL, "memory allocation error");\r
+      return STATUS_ERROR;\r
+    }\r
+    wcscpy (Lang->LanguageName, LanguageName);\r
+    Lang->PrintableLanguageName = (WCHAR *) malloc ((wcslen (PrintableLanguageName) + 1) * sizeof (WCHAR));\r
+    if (Lang->PrintableLanguageName == NULL) {\r
+      Error (NULL, 0, 0, NULL, "memory allocation error");\r
+      FREE (Lang->LanguageName);\r
+      return STATUS_ERROR;\r
+    }\r
+    wcscpy (Lang->PrintableLanguageName, PrintableLanguageName);\r
+\r
+       if (SecondaryLanguageList != NULL) {\r
+      Lang->SecondaryLanguageList = (WCHAR *) malloc ((wcslen (SecondaryLanguageList) + 1) * sizeof (WCHAR));\r
+      if (Lang->SecondaryLanguageList == NULL) {\r
+        Error (NULL, 0, 0, NULL, "memory allocation error");\r
+        FREE (Lang->PrintableLanguageName);\r
+        FREE (Lang->LanguageName);\r
+        return STATUS_ERROR;\r
+      }\r
+      wcscpy (Lang->SecondaryLanguageList, SecondaryLanguageList);\r
+       } else {\r
+      Lang->SecondaryLanguageList = NULL;\r
+       }\r
+\r
+    if (mDBData.LanguageList == NULL) {\r
+      mDBData.LanguageList = Lang;\r
+    } else {\r
+      mDBData.LastLanguageList->Next = Lang;\r
+    }\r
+\r
+    mDBData.LastLanguageList = Lang;\r
+  }\r
+  //\r
+  // Default is to make our active language this new one\r
+  //\r
+  StringDBSetCurrentLanguage (LanguageName);\r
+  //\r
+  // The first two strings for any language are the language name,\r
+  // followed by the printable language name. Add them and set them\r
+  // to referenced so they never get stripped out.\r
+  //\r
+  StringDBAddString (\r
+    LanguageName,\r
+    LANGUAGE_NAME_STRING_NAME,\r
+    NULL,\r
+    LanguageName,\r
+    FALSE,\r
+    STRING_FLAGS_REFERENCED\r
+    );\r
+  StringDBAddString (\r
+    LanguageName,\r
+    PRINTABLE_LANGUAGE_NAME_STRING_NAME,\r
+    NULL,\r
+    PrintableLanguageName,\r
+    FALSE,\r
+    STRING_FLAGS_REFERENCED\r
+    );\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+STATUS\r
+StringDBAddSecondaryLanguage (\r
+  WCHAR *LanguageName,\r
+  WCHAR *SecondaryLanguageList\r
+  )\r
+{\r
+  LANGUAGE_LIST *Lang;\r
+\r
+  Lang = StringDBFindLanguageList (LanguageName);\r
+  if (Lang == NULL) {\r
+    return STATUS_ERROR;\r
+  } else {\r
+    Lang->SecondaryLanguageList = WstrCatenate(Lang->SecondaryLanguageList, SecondaryLanguageList);\r
+    return STATUS_SUCCESS;\r
+  }\r
+}\r
+\r
+/*****************************************************************************/\r
+static\r
+STRING_IDENTIFIER *\r
+StringDBFindStringIdentifierByName (\r
+  WCHAR *StringName\r
+  )\r
+{\r
+  STRING_IDENTIFIER *Identifier;\r
+\r
+  Identifier = mDBData.StringIdentifier;\r
+  while (Identifier != NULL) {\r
+    if (wcscmp (StringName, Identifier->StringName) == 0) {\r
+      return Identifier;\r
+    }\r
+\r
+    Identifier = Identifier->Next;\r
+  }\r
+\r
+  return NULL;\r
+}\r
+\r
+static\r
+STRING_IDENTIFIER *\r
+StringDBFindStringIdentifierByIndex (\r
+  UINT32    StringIndex\r
+  )\r
+{\r
+  STRING_IDENTIFIER *Identifier;\r
+\r
+  Identifier = mDBData.StringIdentifier;\r
+  while (Identifier != NULL) {\r
+    if (Identifier->Index == StringIndex) {\r
+      return Identifier;\r
+    }\r
+\r
+    Identifier = Identifier->Next;\r
+  }\r
+\r
+  return NULL;\r
+}\r
+\r
+/*****************************************************************************/\r
+static\r
+void\r
+StringDBWriteStandardFileHeader (\r
+  FILE *OutFptr\r
+  )\r
+{\r
+  UINT32  TempIndex;\r
+  for (TempIndex = 0; mSourceFileHeader[TempIndex] != NULL; TempIndex++) {\r
+    fprintf (OutFptr, "%s\n", mSourceFileHeader[TempIndex]);\r
+  }\r
+}\r
+\r
+/*****************************************************************************/\r
+\r
+/*++\r
+\r
+Routine Description:\r
+  \r
+  Given a Unicode string from an input file, reformat the string to replace\r
+  backslash control sequences with the appropriate encoding.\r
+\r
+Arguments:\r
+\r
+  String        - pointer to string to reformat\r
+\r
+Returns:\r
+\r
+  Nothing\r
+\r
+--*/\r
+void\r
+StringDBFormatString (\r
+  WCHAR   *String\r
+  )\r
+{\r
+  WCHAR *From;\r
+  WCHAR *To;\r
+  int   HexNibbles;\r
+  WCHAR HexValue;\r
+  //\r
+  // Go through the string and process any formatting characters\r
+  //\r
+  From  = String;\r
+  To    = String;\r
+  while (*From) {\r
+    if (*From == UNICODE_BACKSLASH) {\r
+      //\r
+      // First look for \wide and replace with the appropriate control character. Note that\r
+      // when you have "define STR L"ABC"", then sizeof(ABC) is 8 because the null char is\r
+      // counted. Make adjustments for this. We advance From below, so subtract 2 each time.\r
+      //\r
+      if (wcsncmp (From, UNICODE_WIDE_STRING, sizeof (UNICODE_WIDE_STRING) / sizeof (WCHAR) - 1) == 0) {\r
+        *To = WIDE_CHAR;\r
+        From += sizeof (UNICODE_WIDE_STRING) / sizeof (WCHAR) - 2;\r
+      } else if (wcsncmp (From, UNICODE_NARROW_STRING, sizeof (UNICODE_NARROW_STRING) / sizeof (WCHAR) - 1) == 0) {\r
+        //\r
+        // Found: \narrow\r
+        //\r
+        *To = NARROW_CHAR;\r
+        From += sizeof (UNICODE_NARROW_STRING) / sizeof (WCHAR) - 2;\r
+      } else if (wcsncmp (From, UNICODE_NBR_STRING, sizeof (UNICODE_NBR_STRING) / sizeof (WCHAR) - 1) == 0) {\r
+        //\r
+        // Found: \nbr\r
+        //\r
+        *To = NON_BREAKING_CHAR;\r
+        From += sizeof (UNICODE_NBR_STRING) / sizeof (WCHAR) - 2;\r
+      } else if (wcsncmp (From, UNICODE_BR_STRING, sizeof (UNICODE_BR_STRING) / sizeof (WCHAR) - 1) == 0) {\r
+        //\r
+        // Found: \br -- pass through untouched\r
+        //\r
+        *To = *From;\r
+      } else {\r
+        //\r
+        // Standard one-character control sequences such as \n, \r, \\, or \x\r
+        //\r
+        From++;\r
+        switch (*From) {\r
+        case ASCII_TO_UNICODE ('n'):\r
+          *To = UNICODE_CR;\r
+          To++;\r
+          *To = UNICODE_LF;\r
+          break;\r
+\r
+        //\r
+        // carriage return\r
+        //\r
+        case ASCII_TO_UNICODE ('r'):\r
+          *To = UNICODE_CR;\r
+          break;\r
+\r
+        //\r
+        // backslash\r
+        //\r
+        case UNICODE_BACKSLASH:\r
+          *To = UNICODE_BACKSLASH;\r
+          break;\r
+\r
+        //\r
+        // Tab\r
+        //\r
+        case ASCII_TO_UNICODE ('t'):\r
+          *To = UNICODE_TAB;\r
+          break;\r
+\r
+        //\r
+        // embedded double-quote\r
+        //\r
+        case UNICODE_DOUBLE_QUOTE:\r
+          *To = UNICODE_DOUBLE_QUOTE;\r
+          break;\r
+\r
+        //\r
+        // Hex Unicode character \x1234. We'll process up to 4 hex characters\r
+        //\r
+        case ASCII_TO_UNICODE ('x'):\r
+          HexValue = 0;\r
+          for (HexNibbles = 0; HexNibbles < 4; HexNibbles++) {\r
+            if ((From[1] >= UNICODE_0) && (From[1] <= UNICODE_9)) {\r
+              HexValue = (HexValue << 4) | (From[1] - UNICODE_0);\r
+            } else if ((From[1] >= UNICODE_a) && (From[1] <= UNICODE_f)) {\r
+              HexValue = (HexValue << 4) | (10 + From[1] - UNICODE_a);\r
+            } else if ((From[1] >= UNICODE_A) && (From[1] <= UNICODE_F)) {\r
+              HexValue = (HexValue << 4) | (10 + From[1] - UNICODE_A);\r
+            } else {\r
+              break;\r
+            }\r
+\r
+            From++;\r
+          }\r
+\r
+          if (HexNibbles == 0) {\r
+            ParserWarning (\r
+              0,\r
+              "expected at least one valid hex digit with \\x escaped character in string",\r
+              "\\%C",\r
+              *From\r
+              );\r
+          } else {\r
+            *To = HexValue;\r
+          }\r
+          break;\r
+\r
+        default:\r
+          *To = UNICODE_SPACE;\r
+          ParserWarning (0, "invalid escaped character in string", "\\%C", *From);\r
+          break;\r
+        }\r
+      }\r
+    } else {\r
+      *To = *From;\r
+    }\r
+\r
+    From++;\r
+    To++;\r
+  }\r
+\r
+  *To = 0;\r
+}\r
+\r
+/*****************************************************************************/\r
+STATUS\r
+StringDBReadDatabase (\r
+  INT8    *DBFileName,\r
+  BOOLEAN IgnoreIfNotExist,\r
+  BOOLEAN Verbose\r
+  )\r
+{\r
+  STRING_DB_HEADER    DbHeader;\r
+  STATUS              Status;\r
+  FILE                *DBFptr;\r
+  DB_DATA_ITEM_HEADER DataItemHeader;\r
+\r
+  Status  = STATUS_SUCCESS;\r
+  DBFptr  = NULL;\r
+  //\r
+  //  if (Verbose) {\r
+  //    fprintf (stdout, "Reading database file %s\n", DBFileName);\r
+  //  }\r
+  //\r
+  // Try to open the input file\r
+  //\r
+  if ((DBFptr = fopen (DBFileName, "rb")) == NULL) {\r
+    if (IgnoreIfNotExist) {\r
+      return STATUS_SUCCESS;\r
+    }\r
+\r
+    Error (NULL, 0, 0, DBFileName, "failed to open input database file for reading");\r
+    return STATUS_ERROR;\r
+  }\r
+  //\r
+  // Read and verify the database header\r
+  //\r
+  if (fread ((void *) &DbHeader, sizeof (STRING_DB_HEADER), 1, DBFptr) != 1) {\r
+    Error (NULL, 0, 0, DBFileName, "failed to read header from database file");\r
+    Status = STATUS_ERROR;\r
+    goto Finish;\r
+  }\r
+\r
+  if (DbHeader.Key != STRING_DB_KEY) {\r
+    Error (NULL, 0, 0, DBFileName, "invalid header in database file");\r
+    Status = STATUS_ERROR;\r
+    goto Finish;\r
+  }\r
+\r
+  if ((DbHeader.Version & STRING_DB_MAJOR_VERSION_MASK) != (STRING_DB_VERSION & STRING_DB_MAJOR_VERSION_MASK)) {\r
+    Error (NULL, 0, 0, DBFileName, "incompatible database file version -- rebuild clean");\r
+    Status = STATUS_ERROR;\r
+    goto Finish;\r
+  }\r
+  //\r
+  // Read remaining items\r
+  //\r
+  while (fread (&DataItemHeader, sizeof (DataItemHeader), 1, DBFptr) == 1) {\r
+    switch (DataItemHeader.DataType) {\r
+    case DB_DATA_TYPE_STRING_IDENTIFIER:\r
+      StringDBReadStringIdentifier (DBFptr);\r
+      break;\r
+\r
+    case DB_DATA_TYPE_LANGUAGE_DEFINITION:\r
+      StringDBReadLanguageDefinition (DBFptr);\r
+      break;\r
+\r
+    case DB_DATA_TYPE_STRING_DEFINITION:\r
+      StringDBReadString (DBFptr);\r
+      break;\r
+\r
+    default:\r
+      Error (\r
+        NULL,\r
+        0,\r
+        0,\r
+        "database corrupted",\r
+        "invalid data item type 0x%X at offset 0x%X",\r
+        (UINT32) DataItemHeader.DataType,\r
+        ftell (DBFptr) - sizeof (DataItemHeader)\r
+        );\r
+      Status = STATUS_ERROR;\r
+      goto Finish;\r
+    }\r
+  }\r
+\r
+Finish:\r
+  if (DBFptr != NULL) {\r
+    fclose (DBFptr);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/*****************************************************************************/\r
+\r
+/*++\r
+\r
+Routine Description:\r
+  \r
+  Write everything we know to the output database file. Write:\r
+\r
+  Database header\r
+  String identifiers[]\r
+  StringPacks[]\r
+\r
+Arguments:\r
+\r
+  DBFileName    - name of the file to write to\r
+  Verbose       - for debug purposes, print info messages along the way.\r
+\r
+Returns:\r
+\r
+  STATUS\r
+\r
+--*/\r
+STATUS\r
+StringDBWriteDatabase (\r
+  INT8    *DBFileName,\r
+  BOOLEAN Verbose\r
+  )\r
+{\r
+  STRING_DB_HEADER  DbHeader;\r
+  UINT32            Counter;\r
+  UINT32            StrLen;\r
+  LANGUAGE_LIST     *Lang;\r
+  STRING_IDENTIFIER *StringIdentifier;\r
+  STRING_LIST       *StrList;\r
+  FILE              *DBFptr;\r
+\r
+  if (Verbose) {\r
+    fprintf (stdout, "Writing database %s\n", DBFileName);\r
+  }\r
+\r
+  if ((DBFptr = fopen (DBFileName, "wb")) == NULL) {\r
+    Error (NULL, 0, 0, DBFileName, "failed to open output database file for writing");\r
+    return STATUS_ERROR;\r
+  }\r
+  //\r
+  // Fill in and write the database header\r
+  //\r
+  memset (&DbHeader, 0, sizeof (STRING_DB_HEADER));\r
+  DbHeader.HeaderSize = sizeof (STRING_DB_HEADER);\r
+  DbHeader.Key        = STRING_DB_KEY;\r
+  DbHeader.Version    = STRING_DB_VERSION;\r
+  //\r
+  // Count the number of languages we have\r
+  //\r
+  for (Lang = mDBData.LanguageList; Lang != NULL; Lang = Lang->Next) {\r
+    DbHeader.NumLanguages++;\r
+  }\r
+  //\r
+  // Count up how many string identifiers we have, and total up the\r
+  // size of the names plus the size of the flags field we will\r
+  // write out too.\r
+  //\r
+  DbHeader.NumStringIdenfiers = mDBData.NumStringIdentifiers;\r
+  StringIdentifier            = mDBData.StringIdentifier;\r
+  for (Counter = 0; Counter < mDBData.NumStringIdentifiers; Counter++) {\r
+    StrLen = wcslen (StringIdentifier->StringName) + 1;\r
+    DbHeader.StringIdentifiersSize += StrLen * sizeof (WCHAR) + sizeof (StringIdentifier->Flags);\r
+    StringIdentifier = StringIdentifier->Next;\r
+  }\r
+\r
+  //\r
+  // Write the header\r
+  //\r
+  fwrite (&DbHeader, sizeof (STRING_DB_HEADER), 1, DBFptr);\r
+  if (Verbose) {\r
+    fprintf (stdout, "  Number of string identifiers  0x%04X\n", DbHeader.NumStringIdenfiers);\r
+    fprintf (stdout, "  Number of languages           %d\n", DbHeader.NumLanguages);\r
+  }\r
+  //\r
+  // Write the string identifiers\r
+  //\r
+  for (StringIdentifier = mDBData.StringIdentifier; StringIdentifier != NULL; StringIdentifier = StringIdentifier->Next) {\r
+    StringDBWriteStringIdentifier (\r
+      DBFptr,\r
+      (UINT16) StringIdentifier->Index,\r
+      StringIdentifier->Flags,\r
+      StringIdentifier->StringName\r
+      );\r
+  }\r
+  //\r
+  // Now write all the strings for each language\r
+  //\r
+  for (Lang = mDBData.LanguageList; Lang != NULL; Lang = Lang->Next) {\r
+    StringDBWriteLanguageDefinition (DBFptr, Lang->LanguageName, Lang->PrintableLanguageName, Lang->SecondaryLanguageList);\r
+    for (StrList = Lang->String; StrList != NULL; StrList = StrList->Next) {\r
+      StringDBWriteString (\r
+        DBFptr,\r
+        StrList->Flags,\r
+        Lang->LanguageName,\r
+        StrList->StringName,\r
+        StrList->Scope,\r
+        StrList->Str\r
+        );\r
+    }\r
+  }\r
+\r
+  fclose (DBFptr);\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+STATUS\r
+StringDBSetStringReferenced (\r
+  INT8      *StringIdentifierName,\r
+  BOOLEAN   IgnoreNotFound\r
+  )\r
+{\r
+  STRING_IDENTIFIER *Id;\r
+  WCHAR             *WName;\r
+  STATUS            Status;\r
+  //\r
+  // See if it's already been defined.\r
+  //\r
+  Status  = STATUS_SUCCESS;\r
+  WName   = (WCHAR *) malloc ((strlen (StringIdentifierName) + 1) * sizeof (WCHAR));\r
+#ifdef USE_VC8\r
+  swprintf (WName, (strlen (StringIdentifierName) + 1) * sizeof (WCHAR), L"%S", StringIdentifierName);\r
+#else\r
+  swprintf (WName, L"%S", StringIdentifierName);\r
+#endif\r
+  Id = StringDBFindStringIdentifierByName (WName);\r
+  if (Id != NULL) {\r
+    Id->Flags |= STRING_FLAGS_REFERENCED;\r
+  } else {\r
+    if (IgnoreNotFound == 0) {\r
+      ParserWarning (0, StringIdentifierName, "string identifier not found in database");\r
+      Status = STATUS_WARNING;\r
+    }\r
+  }\r
+\r
+  free (WName);\r
+  return Status;\r
+}\r
+\r
+/*****************************************************************************/\r
+\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Dump the contents of a database to an output unicode file.\r
+\r
+Arguments:\r
+\r
+  DBFileName        - name of the pre-existing database file to read\r
+  OutputFileName    - name of the file to dump the database contents to\r
+  Verbose           - for printing of additional info useful for debugging\r
+\r
+Returns:\r
+\r
+  STATUS\r
+\r
+Notes:\r
+\r
+  There's some issue with the unicode printing routines. Therefore to \r
+  write to the output file properly, open it as binary and use fwrite.\r
+  Ideally we could open it with just L"w" and use fwprintf().\r
+\r
+--*/\r
+STATUS\r
+StringDBDumpDatabase (\r
+  INT8                *DBFileName,\r
+  INT8                *OutputFileName,\r
+  BOOLEAN             Verbose\r
+  )\r
+{\r
+  LANGUAGE_LIST     *Lang;\r
+  STRING_IDENTIFIER *StringIdentifier;\r
+  STRING_LIST       *StrList;\r
+  FILE              *OutFptr;\r
+  WCHAR             WChar;\r
+  WCHAR             *WOutputFileName;\r
+  WCHAR             CrLf[2];\r
+  WCHAR             Line[200];\r
+  WCHAR             *Scope;\r
+  //\r
+  // This function assumes the database has already been read, and\r
+  // we're just dumping our internal data structures to a unicode file.\r
+  //\r
+  if (Verbose) {\r
+    fprintf (stdout, "Dumping database file %s\n", DBFileName);\r
+  }\r
+\r
+  WOutputFileName = AsciiToWchar (OutputFileName);\r
+  OutFptr         = _wfopen (WOutputFileName, L"wb");\r
+  free (WOutputFileName);\r
+  if (OutFptr == NULL) {\r
+    Error (NULL, 0, 0, OutputFileName, "failed to open output file for writing");\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  WChar = UNICODE_FILE_START;\r
+  fwrite (&WChar, sizeof (WCHAR), 1, OutFptr);\r
+  CrLf[1] = UNICODE_LF;\r
+  CrLf[0] = UNICODE_CR;\r
+  //\r
+  // The default control character is '/'. Make it '#' by writing\r
+  // "/=#" to the output file.\r
+  //\r
+#ifdef USE_VC8\r
+  swprintf (Line, wcslen(Line) * sizeof (WCHAR), L"/=#");\r
+#else\r
+  swprintf (Line, L"/=#");\r
+#endif\r
+  fwrite (Line, wcslen (Line) * sizeof (WCHAR), 1, OutFptr);\r
+  fwrite (&CrLf, sizeof (CrLf), 1, OutFptr);\r
+  fwrite (&CrLf, sizeof (CrLf), 1, OutFptr);\r
+  //\r
+  // Dump all the string identifiers and their values\r
+  //\r
+  StringDBAssignStringIndexes ();\r
+  for (StringIdentifier = mDBData.StringIdentifier; StringIdentifier != NULL; StringIdentifier = StringIdentifier->Next) {\r
+    //\r
+    // Write the "#define " string\r
+    //\r
+    if (StringIdentifier->Flags & STRING_FLAGS_REFERENCED) {\r
+#ifdef USE_VC8\r
+      swprintf (\r
+        Line,\r
+        wcslen(Line) * sizeof (WCHAR),\r
+        L"%s %-60.60s 0x%04X",\r
+        DEFINE_STR,\r
+        StringIdentifier->StringName,\r
+        StringIdentifier->Index\r
+        );\r
+#else\r
+      swprintf (\r
+        Line,\r
+        L"%s %-60.60s 0x%04X",\r
+        DEFINE_STR,\r
+        StringIdentifier->StringName,\r
+        StringIdentifier->Index\r
+        );\r
+#endif\r
+    } else {\r
+#ifdef USE_VC8\r
+      swprintf (\r
+        Line,\r
+        wcslen(Line) * sizeof (WCHAR), \r
+        L"%s %-60.60s 0x%04X  // NOT REFERENCED",\r
+        DEFINE_STR,\r
+        StringIdentifier->StringName,\r
+        StringIdentifier->Index\r
+        );\r
+#else\r
+      swprintf (\r
+        Line,\r
+        L"%s %-60.60s 0x%04X  // NOT REFERENCED",\r
+        DEFINE_STR,\r
+        StringIdentifier->StringName,\r
+        StringIdentifier->Index\r
+        );\r
+#endif\r
+    }\r
+\r
+    fwrite (Line, wcslen (Line) * sizeof (WCHAR), 1, OutFptr);\r
+    fwrite (&CrLf, sizeof (CrLf), 1, OutFptr);\r
+  }\r
+\r
+  fwrite (&CrLf, sizeof (CrLf), 1, OutFptr);\r
+  //\r
+  // Now write all the strings for each language.\r
+  //\r
+  WChar = UNICODE_DOUBLE_QUOTE;\r
+  Scope = NULL;\r
+  for (Lang = mDBData.LanguageList; Lang != NULL; Lang = Lang->Next) {\r
+    fwrite (&CrLf, sizeof (CrLf), 1, OutFptr);\r
+#ifdef USE_VC8\r
+    swprintf (Line, wcslen(Line) * sizeof (WCHAR), L"#langdef %s \"%s\"", Lang->LanguageName, Lang->PrintableLanguageName);\r
+#else\r
+    swprintf (Line, L"#langdef %s \"%s\"", Lang->LanguageName, Lang->PrintableLanguageName);\r
+#endif\r
+    fwrite (Line, wcslen (Line) * sizeof (WCHAR), 1, OutFptr);\r
+    fwrite (&CrLf, sizeof (CrLf), 1, OutFptr);\r
+    fwrite (&CrLf, sizeof (CrLf), 1, OutFptr);\r
+    //\r
+    // Now the strings (in double-quotes) for this language. Write\r
+    // #string STR_NAME  #language eng "string"\r
+    //\r
+    for (StrList = Lang->String; StrList != NULL; StrList = StrList->Next) {\r
+      //\r
+      // Print the internal flags for debug\r
+      //\r
+#ifdef USE_VC8\r
+      swprintf (Line, wcslen(Line) * sizeof (WCHAR), L"// flags=0x%02X", (UINT32) StrList->Flags);\r
+#else\r
+      swprintf (Line, L"// flags=0x%02X", (UINT32) StrList->Flags);\r
+#endif\r
+      fwrite (Line, wcslen (Line) * sizeof (WCHAR), 1, OutFptr);\r
+      fwrite (&CrLf, sizeof (CrLf), 1, OutFptr);\r
+      //\r
+      // Print the scope if changed\r
+      //\r
+      if ((Scope == NULL) || (wcscmp (Scope, StrList->Scope) != 0)) {\r
+#ifdef USE_VC8\r
+        swprintf (Line, wcslen(Line) * sizeof (WCHAR), L"#scope %s", StrList->Scope);\r
+#else\r
+        swprintf (Line, L"#scope %s", StrList->Scope);\r
+#endif\r
+        fwrite (Line, wcslen (Line) * sizeof (WCHAR), 1, OutFptr);\r
+        fwrite (&CrLf, sizeof (CrLf), 1, OutFptr);\r
+        Scope = StrList->Scope;\r
+      }\r
+\r
+#ifdef USE_VC8\r
+      swprintf (\r
+        Line,\r
+        wcslen(Line) * sizeof (WCHAR), \r
+        L"#string %-50.50s #language %s \"",\r
+        StrList->StringName,\r
+        Lang->LanguageName\r
+        );\r
+#else\r
+      swprintf (\r
+        Line,\r
+        L"#string %-50.50s #language %s \"",\r
+        StrList->StringName,\r
+        Lang->LanguageName\r
+        );\r
+#endif\r
+      fwrite (Line, wcslen (Line) * sizeof (WCHAR), 1, OutFptr);\r
+      fwrite (StrList->Str, StrList->Size - sizeof (WCHAR), 1, OutFptr);\r
+#ifdef USE_VC8\r
+      swprintf (Line, wcslen(Line) * sizeof (WCHAR), L"\"");\r
+#else\r
+      swprintf (Line, L"\"");\r
+#endif\r
+      fwrite (Line, wcslen (Line) * sizeof (WCHAR), 1, OutFptr);\r
+      fwrite (&CrLf, sizeof (CrLf), 1, OutFptr);\r
+    }\r
+  }\r
+\r
+  fclose (OutFptr);\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+/*****************************************************************************/\r
+\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Given a primary language, a string identifier number, and a list of\r
+  languages, find a secondary string.\r
+\r
+Arguments:\r
+\r
+  LanguageName      - primary language, like "spa"\r
+  StringId          - string index value\r
+  LanguageList      - linked list of "eng", "spa+cat",...\r
+\r
+Returns:\r
+\r
+  Pointer to a secondary string if found. NULL otherwise.\r
+\r
+Notes:\r
\r
+  Given: LanguageName "spa"   and  LanguageList "spa+cat", match the\r
+  "spa" and extract the "cat" and see if there is a string defined\r
+  for "cat".StringId.\r
+\r
+--*/\r
+static\r
+STATUS\r
+StringDBWriteStringIdentifier (\r
+  FILE                *DBFptr,\r
+  UINT16              StringId,\r
+  UINT16              Flags,\r
+  WCHAR               *IdentifierName\r
+  )\r
+{\r
+  DB_DATA_ITEM_HEADER Hdr;\r
+  memset (&Hdr, 0, sizeof (DB_DATA_ITEM_HEADER));\r
+  Hdr.DataType = DB_DATA_TYPE_STRING_IDENTIFIER;\r
+  if (fwrite (&Hdr, sizeof (DB_DATA_ITEM_HEADER), 1, DBFptr) != 1) {\r
+    Error (NULL, 0, 0, "failed to write string to output database file", NULL);\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  if (fwrite (&StringId, sizeof (StringId), 1, DBFptr) != 1) {\r
+    Error (NULL, 0, 0, "failed to write StringId to output database", NULL);\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  if (fwrite (&Flags, sizeof (Flags), 1, DBFptr) != 1) {\r
+    Error (NULL, 0, 0, "failed to write StringId flags to output database", NULL);\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  if (StringDBWriteGenericString (DBFptr, IdentifierName) != STATUS_SUCCESS) {\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+static\r
+STATUS\r
+StringDBReadStringIdentifier (\r
+  FILE                *DBFptr\r
+  )\r
+{\r
+  WCHAR   *IdentifierName;\r
+  UINT16  Flags;\r
+  UINT16  StringId;\r
+  UINT16  Size;\r
+\r
+  if (fread (&StringId, sizeof (StringId), 1, DBFptr) != 1) {\r
+    Error (NULL, 0, 0, "failed to read StringId from database", NULL);\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  if (fread (&Flags, sizeof (Flags), 1, DBFptr) != 1) {\r
+    Error (NULL, 0, 0, "failed to read StringId flags from database", NULL);\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  if (StringDBReadGenericString (DBFptr, &Size, &IdentifierName) != STATUS_SUCCESS) {\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  StringDBAddStringIdentifier (IdentifierName, &StringId, Flags);\r
+  //\r
+  // printf ("STRID:  0x%04X %S\n", (UINT32)StringId, IdentifierName);\r
+  //\r
+  FREE (IdentifierName);\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+static\r
+STATUS\r
+StringDBWriteString (\r
+  FILE            *DBFptr,\r
+  UINT16          Flags,\r
+  WCHAR           *Language,\r
+  WCHAR           *StringName,\r
+  WCHAR           *Scope,\r
+  WCHAR           *Str\r
+  )\r
+{\r
+  DB_DATA_ITEM_HEADER Hdr;\r
+  memset (&Hdr, 0, sizeof (DB_DATA_ITEM_HEADER));\r
+  Hdr.DataType = DB_DATA_TYPE_STRING_DEFINITION;\r
+  if (fwrite (&Hdr, sizeof (DB_DATA_ITEM_HEADER), 1, DBFptr) != 1) {\r
+    Error (NULL, 0, 0, "failed to write string header to output database file", NULL);\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  if (fwrite (&Flags, sizeof (Flags), 1, DBFptr) != 1) {\r
+    Error (NULL, 0, 0, "failed to write string flags to output database", NULL);\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  if (StringDBWriteGenericString (DBFptr, Language) != STATUS_SUCCESS) {\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  if (StringDBWriteGenericString (DBFptr, StringName) != STATUS_SUCCESS) {\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  if (StringDBWriteGenericString (DBFptr, Scope) != STATUS_SUCCESS) {\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  if (StringDBWriteGenericString (DBFptr, Str) != STATUS_SUCCESS) {\r
+    return STATUS_ERROR;\r
+  }\r
+  //\r
+  // printf ("DBWriteString: %S.%S.%S\n", Language, StringName, Scope);\r
+  //\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+static\r
+STATUS\r
+StringDBReadString (\r
+  FILE            *DBFptr\r
+  )\r
+{\r
+  UINT16  Flags;\r
+  UINT16  Size;\r
+  WCHAR   *Language;\r
+  WCHAR   *StringName;\r
+  WCHAR   *Scope;\r
+  WCHAR   *Str;\r
+\r
+  if (fread (&Flags, sizeof (Flags), 1, DBFptr) != 1) {\r
+    Error (NULL, 0, 0, "failed to read string flags from database", NULL);\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  if (StringDBReadGenericString (DBFptr, &Size, &Language) != STATUS_SUCCESS) {\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  if (StringDBReadGenericString (DBFptr, &Size, &StringName) != STATUS_SUCCESS) {\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  if (StringDBReadGenericString (DBFptr, &Size, &Scope) != STATUS_SUCCESS) {\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  if (StringDBReadGenericString (DBFptr, &Size, &Str) != STATUS_SUCCESS) {\r
+    return STATUS_ERROR;\r
+  }\r
+  //\r
+  // If the first or second string (language name and printable language name),\r
+  // then skip them. They're added via language definitions data items in\r
+  // the database.\r
+  //\r
+  if (StringName[0] != L'$') {\r
+    StringDBAddString (Language, StringName, Scope, Str, FALSE, Flags);\r
+  }\r
+  //\r
+  // printf ("DBReadString: %S.%S.%S\n", Language, StringName, Scope);\r
+  //\r
+  FREE (Language);\r
+  FREE (StringName);\r
+  if (Str != NULL) {\r
+    FREE (Str);\r
+  }\r
+\r
+  if (Scope != NULL) {\r
+    FREE (Scope);\r
+  }\r
+\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+static\r
+STATUS\r
+StringDBWriteLanguageDefinition (\r
+  FILE            *DBFptr,\r
+  WCHAR           *LanguageName,\r
+  WCHAR           *PrintableLanguageName,\r
+  WCHAR           *SecondaryLanguageList\r
+  )\r
+{\r
+  DB_DATA_ITEM_HEADER Hdr;\r
+  memset (&Hdr, 0, sizeof (DB_DATA_ITEM_HEADER));\r
+  Hdr.DataType = DB_DATA_TYPE_LANGUAGE_DEFINITION;\r
+  if (fwrite (&Hdr, sizeof (DB_DATA_ITEM_HEADER), 1, DBFptr) != 1) {\r
+    Error (NULL, 0, 0, "failed to write string to output database file", NULL);\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  if (StringDBWriteGenericString (DBFptr, LanguageName) != STATUS_SUCCESS) {\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  if (StringDBWriteGenericString (DBFptr, PrintableLanguageName) != STATUS_SUCCESS) {\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  if (StringDBWriteGenericString (DBFptr, SecondaryLanguageList) != STATUS_SUCCESS) {\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+static\r
+STATUS\r
+StringDBReadLanguageDefinition (\r
+  FILE            *DBFptr\r
+  )\r
+{\r
+  WCHAR   *LanguageName = NULL;\r
+  WCHAR   *PrintableLanguageName = NULL;\r
+  WCHAR   *SecondaryLanguageList = NULL;\r
+  UINT16  Size;\r
+  STATUS  Status;\r
+\r
+  if (StringDBReadGenericString (DBFptr, &Size, &LanguageName) != STATUS_SUCCESS) {\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  if (StringDBReadGenericString (DBFptr, &Size, &PrintableLanguageName) != STATUS_SUCCESS) {\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  if (StringDBReadGenericString (DBFptr, &Size, &SecondaryLanguageList) != STATUS_SUCCESS) {\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  //\r
+  // printf("LANG: %S %S\n", LanguageName, PrintableLanguageName);\r
+  //\r
+  Status = StringDBAddLanguage (LanguageName, PrintableLanguageName, SecondaryLanguageList);\r
+  FREE (LanguageName);\r
+  FREE (PrintableLanguageName);\r
+  FREE (SecondaryLanguageList);\r
+  return Status;\r
+}\r
+//\r
+// All unicode strings in the database consist of a UINT16 length\r
+// field, followed by the string itself. This routine reads one\r
+// of those and returns the info.\r
+//\r
+static\r
+STATUS\r
+StringDBReadGenericString (\r
+  FILE      *DBFptr,\r
+  UINT16    *Size,\r
+  WCHAR     **Str\r
+  )\r
+{\r
+  UINT16  LSize;\r
+  UINT16  Flags;\r
+  WCHAR   *LStr;\r
+\r
+  if (fread (&LSize, sizeof (UINT16), 1, DBFptr) != 1) {\r
+    Error (NULL, 0, 0, "failed to read a string length field from the database", NULL);\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  if (fread (&Flags, sizeof (UINT16), 1, DBFptr) != 1) {\r
+    Error (NULL, 0, 0, "failed to read a string flags field from the database", NULL);\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  LStr = MALLOC (LSize);\r
+  if (LStr == NULL) {\r
+    Error (__FILE__, __LINE__, 0, "memory allocation failed reading the database", NULL);\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  if (fread (LStr, sizeof (WCHAR), (UINT32) LSize / sizeof (WCHAR), DBFptr) != (UINT32) LSize / sizeof (WCHAR)) {\r
+    Error (NULL, 0, 0, "failed to read string from database", NULL);\r
+    Error (NULL, 0, 0, "database read failure", "offset 0x%X", ftell (DBFptr));\r
+    free (LStr);\r
+    return STATUS_ERROR;\r
+  }\r
+  //\r
+  // printf ("DBR: %S\n", LStr);\r
+  //\r
+  // If the flags field indicated we were asked to write a NULL string, then\r
+  // return them a NULL pointer.\r
+  //\r
+  if (Flags & STRING_FLAGS_UNDEFINED) {\r
+    *Size = 0;\r
+    *Str  = NULL;\r
+  } else {\r
+    *Size = LSize;\r
+    *Str  = LStr;\r
+  }\r
+\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+static\r
+STATUS\r
+StringDBWriteGenericString (\r
+  FILE      *DBFptr,\r
+  WCHAR     *Str\r
+  )\r
+{\r
+  UINT16  Size;\r
+  UINT16  Flags;\r
+  WCHAR   ZeroString[1];\r
+  //\r
+  // Strings in the database consist of a size UINT16 followed\r
+  // by the string itself.\r
+  //\r
+  if (Str == NULL) {\r
+    ZeroString[0] = 0;\r
+    Str           = ZeroString;\r
+    Size          = sizeof (ZeroString);\r
+    Flags         = STRING_FLAGS_UNDEFINED;\r
+  } else {\r
+    Flags = 0;\r
+    Size  = (UINT16) ((wcslen (Str) + 1) * sizeof (WCHAR));\r
+  }\r
+\r
+  if (fwrite (&Size, sizeof (UINT16), 1, DBFptr) != 1) {\r
+    Error (NULL, 0, 0, "failed to write string size to database", NULL);\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  if (fwrite (&Flags, sizeof (UINT16), 1, DBFptr) != 1) {\r
+    Error (NULL, 0, 0, "failed to write string flags to database", NULL);\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  if (fwrite (Str, sizeof (WCHAR), Size / sizeof (WCHAR), DBFptr) != Size / sizeof (WCHAR)) {\r
+    Error (NULL, 0, 0, "failed to write string to database", NULL);\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+static\r
+STRING_LIST *\r
+StringDBFindString (\r
+  WCHAR                       *LanguageName,\r
+  WCHAR                       *StringName,\r
+  WCHAR                       *Scope,\r
+  WCHAR_STRING_LIST           *LanguagesOfInterest,\r
+  WCHAR_MATCHING_STRING_LIST  *IndirectionList\r
+  )\r
+{\r
+  LANGUAGE_LIST               *Lang;\r
+  STRING_LIST                 *CurrString;\r
+  WCHAR_MATCHING_STRING_LIST  *IndListPtr;\r
+  WCHAR                       TempLangName[LANGUAGE_IDENTIFIER_NAME_LEN + 1];\r
+  WCHAR                       *WCharPtr;\r
+\r
+  //\r
+  // If we were given an indirection list, then see if one was specified for this\r
+  // string identifier. That is to say, if the indirection says "STR_ID_MY_FAVORITE MyScope",\r
+  // then if this string name matches one in the list, then do a lookup with the\r
+  // specified scope and return that value.\r
+  //\r
+  if (IndirectionList != NULL) {\r
+    for (IndListPtr = IndirectionList; IndListPtr != NULL; IndListPtr = IndListPtr->Next) {\r
+      if (wcscmp (StringName, IndListPtr->Str1) == 0) {\r
+        CurrString = StringDBFindString (LanguageName, StringName, IndListPtr->Str2, LanguagesOfInterest, NULL);\r
+        if (CurrString != NULL) {\r
+          return CurrString;\r
+        }\r
+      }\r
+    }\r
+  }\r
+  //\r
+  // First look for exact match language.stringname\r
+  //\r
+  for (Lang = mDBData.LanguageList; Lang != NULL; Lang = Lang->Next) {\r
+    if (wcscmp (LanguageName, Lang->LanguageName) == 0) {\r
+      //\r
+      // Found language match. Try to find string name match\r
+      //\r
+      for (CurrString = Lang->String; CurrString != NULL; CurrString = CurrString->Next) {\r
+        if (wcscmp (StringName, CurrString->StringName) == 0) {\r
+          //\r
+          // Found a string name match. See if we're supposed to find\r
+          // a scope match.\r
+          //\r
+          if (Scope != NULL) {\r
+            if (wcscmp (CurrString->Scope, Scope) == 0) {\r
+              return CurrString;\r
+            }\r
+          } else {\r
+            return CurrString;\r
+          }\r
+        }\r
+      }\r
+    }\r
+  }\r
+  //\r
+  // If we got here, then we didn't find a match. Look for secondary string\r
+  // matches. That is to say, if we're processing "spa", and they requested\r
+  // "spa+cat", then recursively call with "cat"\r
+  //\r
+  while (LanguagesOfInterest != NULL) {\r
+    //\r
+    // If this is the language we're looking for, then process the\r
+    // languages of interest list for it.\r
+    //\r
+    if (wcsncmp (LanguageName, LanguagesOfInterest->Str, LANGUAGE_IDENTIFIER_NAME_LEN) == 0) {\r
+      WCharPtr = LanguagesOfInterest->Str + LANGUAGE_IDENTIFIER_NAME_LEN;\r
+      while (*WCharPtr) {\r
+        //\r
+        // Double-check the length, though it should have been checked on the\r
+        // command line.\r
+        //\r
+        if (wcslen (WCharPtr) < LANGUAGE_IDENTIFIER_NAME_LEN) {\r
+          Error (NULL, 0, 0, "malformed alternate language list", "%S", LanguagesOfInterest->Str);\r
+          return NULL;\r
+        }\r
+\r
+        wcsncpy (TempLangName, WCharPtr, LANGUAGE_IDENTIFIER_NAME_LEN);\r
+        TempLangName[LANGUAGE_IDENTIFIER_NAME_LEN]  = 0;\r
+        CurrString = StringDBFindString (TempLangName, StringName, NULL, NULL, IndirectionList);\r
+        if (CurrString != NULL) {\r
+          return CurrString;\r
+        }\r
+\r
+        WCharPtr += LANGUAGE_IDENTIFIER_NAME_LEN;\r
+      }\r
+    }\r
+\r
+    LanguagesOfInterest = LanguagesOfInterest->Next;\r
+  }\r
+\r
+  return NULL;\r
+}\r
+\r
+STATUS\r
+StringDBSetScope (\r
+  WCHAR   *Scope\r
+  )\r
+{\r
+  //\r
+  // Free up existing scope memory.\r
+  //\r
+  if (mDBData.CurrentScope != NULL) {\r
+    FREE (mDBData.CurrentScope);\r
+  }\r
+\r
+  mDBData.CurrentScope = DuplicateString (Scope);\r
+  return STATUS_SUCCESS;\r
+}\r
+//\r
+// We typically don't assign index values to string identifiers\r
+// until we're ready to write out files. To reduce the size of\r
+// the output file, re-order the string identifiers to move any\r
+// unreferenced ones to the end. Then we'll walk the list\r
+// again to assign string indexes, keeping track of the last\r
+// one referenced.\r
+//\r
+static\r
+void\r
+StringDBAssignStringIndexes (\r
+  VOID\r
+  )\r
+{\r
+  STRING_IDENTIFIER *StrId;\r
+  STRING_IDENTIFIER *FirstUsed;\r
+  STRING_IDENTIFIER *LastUsed;\r
+  STRING_IDENTIFIER *FirstUnused;\r
+  STRING_IDENTIFIER *LastUnused;\r
+  UINT32            Index;\r
+  UINT32            MaxReferenced;\r
+\r
+  //\r
+  // Create two lists -- used and unused. Then put them together with\r
+  // the unused ones on the end.\r
+  //\r
+  FirstUsed   = NULL;\r
+  LastUsed    = NULL;\r
+  FirstUnused = NULL;\r
+  LastUnused  = NULL;\r
+  StrId       = mDBData.StringIdentifier;\r
+  while (StrId != NULL) {\r
+    if ((StrId->Flags & STRING_FLAGS_REFERENCED) == 0) {\r
+      //\r
+      // Put it on the unused list\r
+      //\r
+      if (FirstUnused == NULL) {\r
+        FirstUnused = StrId;\r
+      } else {\r
+        LastUnused->Next = StrId;\r
+      }\r
+\r
+      LastUnused        = StrId;\r
+      StrId             = StrId->Next;\r
+      LastUnused->Next  = NULL;\r
+    } else {\r
+      //\r
+      // Put it on the used list\r
+      //\r
+      if (FirstUsed == NULL) {\r
+        FirstUsed = StrId;\r
+      } else {\r
+        LastUsed->Next = StrId;\r
+      }\r
+\r
+      LastUsed        = StrId;\r
+      StrId           = StrId->Next;\r
+      LastUsed->Next  = NULL;\r
+    }\r
+  }\r
+  //\r
+  // Join the lists\r
+  //\r
+  if (FirstUsed != NULL) {\r
+    mDBData.StringIdentifier  = FirstUsed;\r
+    LastUsed->Next            = FirstUnused;\r
+  } else {\r
+    mDBData.StringIdentifier = FirstUnused;\r
+  }\r
+\r
+  MaxReferenced = 0;\r
+  Index         = 0;\r
+  for (StrId = mDBData.StringIdentifier; StrId != NULL; StrId = StrId->Next) {\r
+    StrId->Index = Index;\r
+    Index++;\r
+    if (StrId->Flags & STRING_FLAGS_REFERENCED) {\r
+      mDBData.NumStringIdentifiersReferenced = Index;\r
+    }\r
+  }\r
+\r
+  mDBData.NumStringIdentifiers = Index;\r
+}\r
+\r
+static\r
+WCHAR *\r
+DuplicateString (\r
+  WCHAR   *Str\r
+  )\r
+{\r
+  WCHAR *NewStr;\r
+  if (Str == NULL) {\r
+    return NULL;\r
+  }\r
+\r
+  NewStr = MALLOC ((wcslen (Str) + 1) * sizeof (WCHAR));\r
+  if (NewStr == NULL) {\r
+    Error (NULL, 0, 0, "memory allocation failure", NULL);\r
+    return NULL;\r
+  }\r
+\r
+  wcscpy (NewStr, Str);\r
+  return NewStr;\r
+}\r
+\r
+static\r
+WCHAR *\r
+WstrCatenate (\r
+  WCHAR *Dst,\r
+  WCHAR *Src\r
+  )\r
+{\r
+  UINT32 Len  = 0;\r
+  WCHAR  *Bak = Dst;\r
+\r
+  if (Src == NULL) {\r
+    return Dst;\r
+  }\r
+\r
+  if (Dst != NULL) {\r
+    Len = wcslen (Dst);\r
+  }\r
+  Len += wcslen (Src);\r
+  Dst = (WCHAR *) malloc ((Len + 1) * 2);\r
+  if (Dst == NULL) {\r
+    return NULL;\r
+  }\r
+\r
+  Dst[0] = L'\0';\r
+  if (Bak != NULL) {\r
+    wcscpy (Dst, Bak);\r
+    FREE (Bak);\r
+  }\r
+  wcscat (Dst, Src);\r
+  return Dst;\r
+}\r
+\r
+static\r
+WCHAR *\r
+AsciiToWchar (\r
+  INT8 *Str\r
+  )\r
+{\r
+  UINT32  Len;\r
+  WCHAR   *NewStr;\r
+  WCHAR   *Ptr;\r
+\r
+  Len     = strlen (Str) + 1;\r
+  NewStr  = (WCHAR *) malloc (Len * sizeof (WCHAR));\r
+  for (Ptr = NewStr; *Str != 0; Str++, Ptr++) {\r
+    *Ptr = (UINT16) (UINT8) *Str;\r
+  }\r
+\r
+  *Ptr = 0;\r
+  return NewStr;\r
+}\r
+\r
+static\r
+CHAR8 *\r
+WcharToAscii (\r
+  WCHAR *Str\r
+  )\r
+{\r
+  UINT32  Len;\r
+  CHAR8   *NewStr;\r
+  CHAR8   *Ptr;\r
+\r
+  Len     = wcslen (Str) + 1;\r
+  NewStr  = (CHAR8 *) malloc (Len * sizeof (CHAR8));\r
+  for (Ptr = NewStr; *Str != L'\0'; Str++, Ptr++) {\r
+    *Ptr = (CHAR8) *Str;\r
+  }\r
+\r
+  *Ptr = '\0';\r
+  return NewStr;\r
+}\r
+\r
+/*****************************************************************************/\r
+CHAR8 *\r
+unicode2ascii (\r
+  WCHAR *UnicodeStr\r
+  )\r
+{\r
+  CHAR8     *RetStr   = (CHAR8 *)UnicodeStr;\r
+  CHAR8     *AsciiStr = (CHAR8 *)UnicodeStr;\r
+\r
+  while (*UnicodeStr != '\0') {\r
+    *AsciiStr = (CHAR8) *(UnicodeStr++);\r
+    AsciiStr++;\r
+  }\r
+  *AsciiStr = '\0';\r
+\r
+  return RetStr;\r
+}\r
+\r
+STATUS\r
+BuildStringPkgHdr (\r
+  IN  WCHAR                       *PrimaryLangName,\r
+  IN  WCHAR                       *SecondaryLangList,\r
+  IN  UINT32                      Type,\r
+  IN  UINT32                      PkgBlkSize,\r
+  OUT EFI_HII_STRING_PACKAGE_HDR  **StrPkgHdr\r
+  )\r
+{\r
+  UINT32  LangNameLen;\r
+\r
+  LangNameLen = wcslen (PrimaryLangName);\r
+  if (SecondaryLangList != NULL) {\r
+    LangNameLen += wcslen (SecondaryLangList) + 1;\r
+  }\r
+\r
+  *StrPkgHdr = (EFI_HII_STRING_PACKAGE_HDR *) malloc(sizeof (EFI_HII_STRING_PACKAGE_HDR) + LangNameLen);\r
+  if (*StrPkgHdr == NULL) {\r
+    return STATUS_ERROR;\r
+  }\r
+  memset (*StrPkgHdr, 0, sizeof (EFI_HII_STRING_PACKAGE_HDR) + LangNameLen);\r
+\r
+  (*StrPkgHdr)->Header.Type       = Type;\r
+  (*StrPkgHdr)->Header.Length     = PkgBlkSize + sizeof (EFI_HII_STRING_PACKAGE_HDR) + LangNameLen;\r
+  (*StrPkgHdr)->HdrSize           = sizeof (EFI_HII_STRING_PACKAGE_HDR) + LangNameLen;\r
+  (*StrPkgHdr)->StringInfoOffset  = sizeof (EFI_HII_STRING_PACKAGE_HDR) + LangNameLen;\r
+  (*StrPkgHdr)->LanguageWindow[0] = L'\0';\r
+  (*StrPkgHdr)->LanguageName      = (EFI_STRING_ID)1;\r
+\r
+  strcpy ((*StrPkgHdr)->Language, unicode2ascii(PrimaryLangName));\r
+  if (SecondaryLangList != NULL) {\r
+    strcat ((*StrPkgHdr)->Language, ";");\r
+    strcat ((*StrPkgHdr)->Language, unicode2ascii(SecondaryLangList));\r
+  }\r
+\r
+#ifdef DEBUG_STRGATHER\r
+  printf ("STR HDR\t %s\n", (*StrPkgHdr)->Language);\r
+#endif\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+STATUS\r
+BuildStringPkgUCS2Blk (\r
+  IN  EFI_STRING_ID                   StringId,\r
+  IN  WCHAR                           *LangName,\r
+  IN  WCHAR                           *StrName,\r
+  OUT EFI_HII_SIBT_STRING_UCS2_BLOCK  **StrBlk,\r
+  OUT UINT32                          *BlkSize\r
+  )\r
+{\r
+  UINT32      StrLen      = 0;\r
+  STRING_LIST *CurrString = NULL;\r
+\r
+  if ((LangName == NULL) || (StrName == NULL) || (StrBlk == NULL)) {\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  *StrBlk  = NULL;\r
+  *BlkSize = 0;\r
+\r
+  CurrString = StringDBFindString (LangName, StrName, NULL, NULL, NULL);\r
+  if (CurrString == NULL) {\r
+       return STATUS_WARNING;\r
+  }\r
+\r
+  StrLen = wcslen (CurrString->Str);\r
+  *BlkSize = sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK) + StrLen * 2;\r
+  *StrBlk  = (EFI_HII_SIBT_STRING_UCS2_BLOCK *) malloc (*BlkSize);\r
+  if (*StrBlk == NULL) {\r
+    *StrBlk  = NULL;\r
+    *BlkSize = 0;\r
+    return STATUS_ERROR;\r
+  }\r
+  (*StrBlk)->Header.BlockType = EFI_HII_SIBT_STRING_UCS2;\r
+  wcscpy((*StrBlk)->StringText, CurrString->Str);\r
+\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+STATUS\r
+BuildStringPkgSKIP2Blk (\r
+  IN  EFI_STRING_ID                   SkipIdCount,\r
+  OUT EFI_HII_SIBT_SKIP2_BLOCK        **StrBlk\r
+  )\r
+{\r
+  if (StrBlk == NULL) {\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  *StrBlk  = NULL;\r
+\r
+  *StrBlk  = (EFI_HII_SIBT_SKIP2_BLOCK *) malloc (sizeof (EFI_HII_SIBT_SKIP2_BLOCK));\r
+  if (*StrBlk == NULL) {\r
+    *StrBlk  = NULL;\r
+    return STATUS_ERROR;\r
+  }\r
+  (*StrBlk)->Header.BlockType = EFI_HII_SIBT_SKIP2;\r
+  (*StrBlk)->SkipCount        = SkipIdCount;\r
+\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+STATUS\r
+BuildStringPkgEndBlk (\r
+  OUT EFI_HII_SIBT_END_BLOCK **End\r
+  )\r
+{\r
+  *End = (EFI_HII_SIBT_END_BLOCK *) malloc (sizeof (EFI_HII_SIBT_END_BLOCK));\r
+  if (*End == NULL) {\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  (*End)->Header.BlockType = EFI_HII_SIBT_END;\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Create an HII export string pack for the strings in our database.\r
+\r
+Arguments:\r
+\r
+  FileName        - name of the output file to write \r
+\r
+Returns:\r
+\r
+  STATUS\r
+\r
+\r
+--*/\r
+STATUS\r
+StrPkgBlkBufferListAddTail (\r
+  IN EFI_STRING_ID      StringId,\r
+  IN WCHAR              *StrName,\r
+  IN SPkgBlkBuffer      **PkgBufferListHead,\r
+  IN SPkgBlkBuffer      **PkgBufferListTail,\r
+  IN VOID               *Buffer,\r
+  IN UINT32             Size \r
+  )\r
+{\r
+  SPkgBlkBuffer         *pNew = NULL;\r
+#ifdef DEBUG_STRGATHER\r
+  EFI_HII_STRING_BLOCK  *SBlk = (EFI_HII_STRING_BLOCK *)Buffer;\r
+#endif\r
+\r
+  if ((PkgBufferListHead == NULL) || (PkgBufferListTail == NULL)) {\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  pNew = (SPkgBlkBuffer *) malloc (sizeof (SPkgBlkBuffer));\r
+  if (pNew == NULL) {\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  pNew->mBlkBuffer = Buffer;\r
+  pNew->mBlkSize   = Size;\r
+  if ((*PkgBufferListTail) == NULL) {\r
+    (*PkgBufferListHead) = (*PkgBufferListTail) = pNew;\r
+  } else {\r
+    (*PkgBufferListTail)->mNext = pNew;\r
+    (*PkgBufferListTail) = pNew;\r
+    pNew->mNext = NULL;\r
+  }\r
+\r
+#ifdef DEBUG_STRGATHER\r
+  switch (SBlk->BlockType) {\r
+  case EFI_HII_SIBT_STRING_UCS2 :\r
+    printf ("\tID: [%x] TYPE: [UCS2]\t NAME: %S \t STR: %S\n", StringId, StrName, ((EFI_HII_SIBT_STRING_UCS2_BLOCK *)SBlk)->StringText);\r
+    break;\r
+  case EFI_HII_SIBT_SKIP2 :\r
+    printf ("\tID: [NULL] TYPE: [SKIP2] SKIPCOUNT: [%x]\n", ((EFI_HII_SIBT_SKIP2_BLOCK *)SBlk)->SkipCount);\r
+    break;\r
+  case EFI_HII_SIBT_END :\r
+    printf ("\tID: [%x] TYPE: [END]\n", StringId);\r
+    break;\r
+  default :\r
+    printf ("!!!!UNKNOWN STRING TYPE!!!\n");\r
+  }\r
+#endif\r
+\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+VOID\r
+StrPkgHdrFree (\r
+  IN EFI_HII_STRING_PACKAGE_HDR *StrPkgHdr\r
+  )\r
+{\r
+  if (StrPkgHdr != NULL) {\r
+    free (StrPkgHdr);\r
+  }\r
+}\r
+\r
+VOID\r
+StrPkgBlkBufferListFree (\r
+  IN SPkgBlkBuffer *PkgBlkList\r
+  )\r
+{\r
+  SPkgBlkBuffer  *Buffer;\r
+\r
+  while (PkgBlkList != NULL) {\r
+    Buffer      = PkgBlkList;\r
+    PkgBlkList = PkgBlkList->mNext;\r
+\r
+    if (Buffer->mBlkBuffer != NULL) {\r
+      free (Buffer->mBlkBuffer);\r
+    }\r
+    free (Buffer);\r
+  }\r
+}\r
+\r
+VOID\r
+WriteBlockLine (\r
+  IN FILE   *pFile,\r
+  IN UINT32 LineBytes,\r
+  IN INT8   *LineHeader,\r
+  IN INT8   *BlkBuf,\r
+  IN UINT32 BlkSize\r
+  )\r
+{\r
+  UINT32    Index;\r
+\r
+  if ((pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) {\r
+    return;\r
+  }\r
+\r
+  for (Index = 0; Index < BlkSize; Index++) {\r
+    if ((Index % LineBytes) == 0) {\r
+      fprintf (pFile, "\n%s", LineHeader);\r
+    }\r
+    fprintf (pFile, "0x%02X,  ", (UINT8)BlkBuf[Index]);\r
+  }\r
+}\r
+\r
+VOID\r
+WriteBlockEnd (\r
+  IN FILE   *pFile,\r
+  IN UINT32 LineBytes,\r
+  IN INT8   *LineHeader,\r
+  IN INT8   *BlkBuf,\r
+  IN UINT32 BlkSize\r
+  )\r
+{\r
+  UINT32    Index;\r
+\r
+  if ((BlkSize == 0) || (pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) {\r
+    return;\r
+  }\r
+\r
+  for (Index = 0; Index < BlkSize - 1; Index++) {\r
+    if ((Index % LineBytes) == 0) {\r
+      fprintf (pFile, "\n%s", LineHeader);\r
+    }\r
+    fprintf (pFile, "0x%02X,  ", (UINT8)BlkBuf[Index]);\r
+  }\r
+\r
+  if ((Index % LineBytes) == 0) {\r
+    fprintf (pFile, "\n%s", LineHeader);\r
+  }\r
+  fprintf (pFile, "0x%02X\n", (UINT8)BlkBuf[Index]);\r
+}\r
+\r
+#define BYTES_PRE_LINE 0x10\r
+\r
+VOID\r
+StrPkgWriteHdrCFile (\r
+  IN FILE                       *File,\r
+  IN EFI_HII_STRING_PACKAGE_HDR *StrPkgHdr\r
+  )\r
+{\r
+  if (StrPkgHdr != NULL) {\r
+    fprintf (File, "\n  // PACKAGE HEADER\n");\r
+    WriteBlockLine(File, BYTES_PRE_LINE, "  ", (INT8 *)StrPkgHdr, StrPkgHdr->HdrSize);\r
+  }\r
+}\r
+\r
+VOID\r
+StrPkgWirteArrayLength (\r
+  IN FILE                       *File,\r
+  IN UINT32                     PkgNumber,\r
+  IN EFI_HII_STRING_PACKAGE_HDR **PkgHdr\r
+  )\r
+{\r
+  UINT32                        Index;\r
+  UINT32                        ArrayLen;\r
+\r
+  ArrayLen = sizeof (UINT32);\r
+  for (Index = 0; Index < PkgNumber; Index++) {\r
+    if (PkgHdr[Index] != NULL) {\r
+      ArrayLen += PkgHdr[Index]->Header.Length;\r
+    }\r
+  }\r
+\r
+  fprintf (File, "\n  // STRING ARRAY LENGTH\n");\r
+  WriteBlockLine(File, BYTES_PRE_LINE, "  ", (UINT8 *)&ArrayLen, sizeof (UINT32));\r
+}\r
+\r
+VOID\r
+StrPkgWriteBlkListCFile (\r
+  IN FILE                       *File,\r
+  IN SPkgBlkBuffer              *BlkList,\r
+  IN BOOLEAN                    WriteEnd\r
+  )\r
+{\r
+  SPkgBlkBuffer  *Buffer;\r
+\r
+  fprintf (File, "\n\n  // PACKAGE DATA\n");\r
+\r
+  while (BlkList != NULL) {\r
+    Buffer   = BlkList;\r
+    BlkList = BlkList->mNext;\r
+\r
+    if ((Buffer->mNext == NULL) && (WriteEnd == TRUE)) {\r
+      if (Buffer->mBlkBuffer != NULL) {\r
+        WriteBlockEnd (File, BYTES_PRE_LINE, "  ", Buffer->mBlkBuffer, Buffer->mBlkSize);\r
+      }\r
+    } else {\r
+      if (Buffer->mBlkBuffer != NULL) {\r
+        WriteBlockLine(File, BYTES_PRE_LINE, "  ", Buffer->mBlkBuffer, Buffer->mBlkSize);\r
+      }\r
+    }\r
+  }\r
+}\r
+\r
+VOID\r
+StrPkgWriteHdrBinary (\r
+  IN FILE                       *File,\r
+  IN EFI_HII_STRING_PACKAGE_HDR *StrPkgHdr\r
+  )\r
+{\r
+  fwrite (StrPkgHdr, StrPkgHdr->HdrSize, 1, File);\r
+}\r
+\r
+VOID\r
+StrPkgWriteBlkListBinary (\r
+  IN FILE                       *File,\r
+  IN SPkgBlkBuffer              *BlkList\r
+  )\r
+{\r
+  SPkgBlkBuffer  *Buffer;\r
+\r
+  while (BlkList != NULL) {\r
+    Buffer   = BlkList;\r
+    BlkList = BlkList->mNext;\r
+\r
+    if (Buffer->mBlkBuffer != NULL) {\r
+      fwrite (Buffer->mBlkBuffer, Buffer->mBlkSize, 1, File);\r
+    }\r
+  }\r
+}\r
+\r
+STATUS\r
+StringDBGenStrPkgHdrAndBlkList (\r
+  IN  LANGUAGE_LIST              *Lang,\r
+  OUT EFI_HII_STRING_PACKAGE_HDR **StrPkgHdr,\r
+  OUT SPkgBlkBuffer              **BlkList\r
+  )\r
+{\r
+  STATUS                          Status;\r
+  UINT32                          StringIndex;\r
+  EFI_STRING_ID                   StringIdCurrent;\r
+  EFI_STRING_ID                   SkipIdCount;\r
+  UINT32                          BlkSize = 0;\r
+  EFI_HII_SIBT_STRING_UCS2_BLOCK  *StrUCS2Blk  = NULL;\r
+  EFI_HII_SIBT_SKIP2_BLOCK        *StrSKIP2Blk = NULL;\r
+  STRING_IDENTIFIER               *StringIdentifier = NULL;\r
+  EFI_HII_SIBT_END_BLOCK          *EndBlk = NULL;\r
+  UINT32                          PkgBlkSize = 0;\r
+  SPkgBlkBuffer                   *PkgBufferListHead = NULL;\r
+  SPkgBlkBuffer                   *PkgBufferListTail = NULL;\r
+\r
+  if ((Lang == NULL) || (StrPkgHdr == NULL) || (BlkList == NULL)) {\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  //\r
+  // Assign index values to the string identifiers\r
+  //\r
+  StringDBAssignStringIndexes ();\r
+  StringIdCurrent = EFI_STRING_ID_BEGIN;\r
+  SkipIdCount     = 0;\r
+\r
+  for (StringIndex = STRING_ID_PRINTABLE_LANGUAGE_NAME; StringIndex < mDBData.NumStringIdentifiersReferenced; StringIndex++) {\r
+    if ((StringIdentifier = StringDBFindStringIdentifierByIndex (StringIndex)) == NULL) {\r
+      Error (NULL, 0, 0, "internal error", "invalid string index 0x%X", StringIndex);\r
+      goto ExportPackOut;\r
+    }\r
+\r
+    if (StringIdentifier->Flags & STRING_FLAGS_REFERENCED) {\r
+      Status = BuildStringPkgUCS2Blk (StringIdCurrent, Lang->LanguageName, StringIdentifier->StringName, &StrUCS2Blk, &BlkSize);\r
+      switch (Status) {\r
+      case STATUS_ERROR: \r
+        goto ExportPackOut; \r
+        break;\r
+      case STATUS_WARNING :\r
+        SkipIdCount++;\r
+        break;\r
+      case STATUS_SUCCESS :\r
+        if (SkipIdCount == 0) {\r
+          if (StrPkgBlkBufferListAddTail (\r
+                StringIdCurrent, \r
+                StringIdentifier->StringName, \r
+                &PkgBufferListHead, \r
+                &PkgBufferListTail, \r
+                StrUCS2Blk, \r
+                BlkSize\r
+                ) != STATUS_SUCCESS) {\r
+            goto ExportPackOut;\r
+          }\r
+          PkgBlkSize += BlkSize;\r
+        } else {\r
+          if (BuildStringPkgSKIP2Blk (SkipIdCount, &StrSKIP2Blk) != STATUS_SUCCESS) {\r
+            goto ExportPackOut;\r
+          } else {\r
+            if (StrPkgBlkBufferListAddTail (\r
+                StringIdCurrent, \r
+                NULL, \r
+                &PkgBufferListHead, \r
+                &PkgBufferListTail, \r
+                StrSKIP2Blk, \r
+                sizeof (EFI_HII_SIBT_SKIP2_BLOCK)\r
+                ) != STATUS_SUCCESS) {\r
+              goto ExportPackOut;\r
+            }\r
+            PkgBlkSize += sizeof (EFI_HII_SIBT_SKIP2_BLOCK);\r
+            SkipIdCount = 0;\r
+          }\r
+\r
+          if (StrPkgBlkBufferListAddTail (\r
+                StringIdCurrent, \r
+                StringIdentifier->StringName, \r
+                &PkgBufferListHead, \r
+                &PkgBufferListTail, \r
+                StrUCS2Blk, \r
+                BlkSize\r
+                ) != STATUS_SUCCESS) {\r
+            goto ExportPackOut;\r
+          }\r
+          PkgBlkSize += BlkSize;\r
+        }\r
+      }\r
+    }\r
+\r
+    StringIdCurrent++;\r
+  }\r
+\r
+  if (SkipIdCount != 0) {\r
+    if (BuildStringPkgSKIP2Blk (SkipIdCount, &StrSKIP2Blk) != STATUS_SUCCESS) {\r
+      goto ExportPackOut;\r
+    } else {\r
+      if (StrPkgBlkBufferListAddTail (\r
+            StringIdCurrent, \r
+            NULL, \r
+            &PkgBufferListHead, \r
+            &PkgBufferListTail, \r
+            StrSKIP2Blk, \r
+            sizeof (EFI_HII_SIBT_SKIP2_BLOCK)\r
+            ) != STATUS_SUCCESS) {\r
+        goto ExportPackOut;\r
+      }\r
+      PkgBlkSize += sizeof (EFI_HII_SIBT_SKIP2_BLOCK);\r
+      SkipIdCount = 0;\r
+    }\r
+  }\r
+\r
+  if (BuildStringPkgEndBlk (&EndBlk) != STATUS_SUCCESS) {\r
+    goto ExportPackOut;\r
+  } else if (StrPkgBlkBufferListAddTail (\r
+               StringIdCurrent, \r
+               NULL, \r
+               &PkgBufferListHead, \r
+               &PkgBufferListTail, \r
+               EndBlk, \r
+               sizeof (EFI_HII_SIBT_END_BLOCK)\r
+               ) != STATUS_SUCCESS) {\r
+    goto ExportPackOut;\r
+  }\r
+  StringIdCurrent++;\r
+  PkgBlkSize += sizeof (EFI_HII_SIBT_END_BLOCK);\r
+\r
+  if (BuildStringPkgHdr(\r
+        Lang->LanguageName, \r
+        Lang->SecondaryLanguageList,\r
+        EFI_HII_PACKAGE_STRINGS, \r
+        PkgBlkSize, \r
+        StrPkgHdr\r
+        ) != STATUS_SUCCESS) {\r
+    goto ExportPackOut;\r
+  }\r
+\r
+  *BlkList   = PkgBufferListHead;\r
+\r
+  return STATUS_SUCCESS;\r
+\r
+ExportPackOut:\r
+  StrPkgBlkBufferListFree(PkgBufferListHead);\r
+  *BlkList   = NULL;\r
+  *StrPkgHdr = NULL;\r
+  return STATUS_ERROR;\r
+}\r
+\r
+STATUS\r
+StringDBCreateHiiExportPack (\r
+  INT8                        *FileName\r
+  )\r
+{\r
+  FILE                            *File       = NULL;\r
+  LANGUAGE_LIST                   *Lang       = NULL;\r
+  EFI_HII_STRING_PACKAGE_HDR      *StrPkgHdr  = NULL;\r
+  SPkgBlkBuffer                   *BlkList    = NULL;\r
+\r
+  if (FileName == NULL) {\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  if ((File = fopen (FileName, "wb")) == NULL) {\r
+    Error (NULL, 0, 0, FileName, "failed to open output HII export file");\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  for (Lang = mDBData.LanguageList; Lang != NULL; Lang = Lang->Next) {\r
+    if (StringDBGenStrPkgHdrAndBlkList(Lang, &StrPkgHdr, &BlkList) != STATUS_SUCCESS) {\r
+      fclose (File);\r
+      return STATUS_SUCCESS;\r
+    }\r
+\r
+    StrPkgWriteHdrBinary (File, StrPkgHdr);\r
+    StrPkgWriteBlkListBinary (File, BlkList);\r
+\r
+    StrPkgHdrFree (StrPkgHdr);\r
+    StrPkgBlkBufferListFree (BlkList);\r
+  }\r
+\r
+  fclose (File);\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+static const char *gSourceFileHeader[] = {\r
+  "//",\r
+  "//  DO NOT EDIT -- auto-generated file",\r
+  "//",\r
+  "//  This file is generated by the StrGather utility",\r
+  "//",\r
+  NULL\r
+};\r
+\r
+STATUS\r
+StringDBDumpCStrings (\r
+  INT8                            *BaseName,\r
+  INT8                            *FileName\r
+  )\r
+{\r
+  EFI_STATUS                      Status;\r
+  FILE                            *File       = NULL;\r
+  LANGUAGE_LIST                   *Lang       = NULL;\r
+  EFI_HII_STRING_PACKAGE_HDR      **StrPkgHdr = NULL;\r
+  SPkgBlkBuffer                   **BlkList   = NULL;\r
+  UINT32                          Index;\r
+  UINT32                          LangNumber  = 0;\r
+\r
+  if ((BaseName == NULL) || (FileName == NULL)) {\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  if (mDBData.LanguageList == NULL) {\r
+    return STATUS_SUCCESS;\r
+  }\r
+\r
+  for (LangNumber = 0, Lang = mDBData.LanguageList; Lang != NULL; Lang = Lang->Next, LangNumber++)\r
+    ;\r
+\r
+  StrPkgHdr = (EFI_HII_STRING_PACKAGE_HDR **) malloc (sizeof (EFI_HII_STRING_PACKAGE_HDR *) * LangNumber);\r
+  BlkList = (SPkgBlkBuffer **) malloc (sizeof (SPkgBlkBuffer *) * LangNumber);\r
+  for (Index = 0; Index < LangNumber; Index++) {\r
+    StrPkgHdr[Index] = NULL;\r
+    BlkList[Index] = NULL;\r
+  }\r
+\r
+  for (Index = 0, Lang = mDBData.LanguageList; Lang != NULL; Lang = Lang->Next, Index++) {\r
+    Status = StringDBGenStrPkgHdrAndBlkList(Lang, &StrPkgHdr[Index], &BlkList[Index]);\r
+    if (EFI_ERROR(Status)) {\r
+      return Status;\r
+    }\r
+  }\r
+\r
+  if ((File = fopen (FileName, "w")) == NULL) {\r
+    Error (NULL, 0, 0, FileName, "failed to open output C file - %s", FileName);\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  for (Index = 0; gSourceFileHeader[Index] != NULL; Index++) {\r
+    fprintf (File, "%s\n", gSourceFileHeader[Index]);\r
+  }\r
+\r
+  fprintf (File, "\nunsigned char %s[] = {\n", BaseName);\r
+\r
+  //\r
+  // Save the length of the string package array.\r
+  //\r
+  StrPkgWirteArrayLength (File, LangNumber, StrPkgHdr);\r
+\r
+  for (Index = 0, Lang = mDBData.LanguageList; Lang != NULL; Lang = Lang->Next, Index++) {\r
+    if (StrPkgHdr[Index] != NULL) {\r
+      StrPkgWriteHdrCFile (File, StrPkgHdr[Index]);\r
+      StrPkgWriteBlkListCFile (File, BlkList[Index], (Lang->Next == NULL) ? TRUE : FALSE);\r
+    }\r
+\r
+    StrPkgHdrFree (StrPkgHdr[Index]);\r
+    StrPkgBlkBufferListFree (BlkList[Index]);\r
+  }\r
+\r
+  fprintf (File, "\n};\n");\r
+\r
+  fclose (File);\r
+  return STATUS_SUCCESS;\r
+}\r
diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/UefiStrGather/StringDB.h b/EdkCompatibilityPkg/Sample/Tools/Source/UefiStrGather/StringDB.h
new file mode 100644 (file)
index 0000000..6b485c7
--- /dev/null
@@ -0,0 +1,254 @@
+/*++\r
+\r
+Copyright (c) 2004, Intel Corporation                                                         \r
+All rights reserved. This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+  StringDB.h\r
+\r
+Abstract:\r
+\r
+  Common defines and prototypes for string database management\r
+  \r
+--*/\r
+\r
+#ifndef _STRING_DB_H_\r
+#define _STRING_DB_H_\r
+\r
+#define LANGUAGE_NAME_STRING_NAME           L"$LANGUAGE_NAME"\r
+#define PRINTABLE_LANGUAGE_NAME_STRING_NAME L"$PRINTABLE_LANGUAGE_NAME"\r
+\r
+typedef CHAR16  WCHAR;\r
+\r
+#define NARROW_CHAR         0xFFF0\r
+#define WIDE_CHAR           0xFFF1\r
+#define NON_BREAKING_CHAR   0xFFF2\r
+#define GLYPH_WIDTH         8\r
+#define GLYPH_HEIGHT        19\r
+\r
+#define STRING_DB_KEY (('S' << 24) | ('D' << 16) | ('B' << 8) | 'K')\r
+//\r
+// Version supported by this tool\r
+//\r
+#define STRING_DB_VERSION             0x00010000\r
+\r
+#define STRING_DB_MAJOR_VERSION_MASK  0xFFFF0000\r
+#define STRING_DB_MINOR_VERSION_MASK  0x0000FFFF\r
+\r
+#define DEFINE_STR                    L"// #define"\r
+\r
+#define EFI_STRING_ID_BEGIN           0x01\r
+\r
+//\r
+// This is the header that gets written to the top of the\r
+// output binary database file.\r
+//\r
+typedef struct {\r
+  UINT32  Key;\r
+  UINT32  HeaderSize;\r
+  UINT32  Version;\r
+  UINT32  NumStringIdenfiers;\r
+  UINT32  StringIdentifiersSize;\r
+  UINT32  NumLanguages;\r
+} STRING_DB_HEADER;\r
+\r
+//\r
+// When we write out data to the database, we have a UINT16 identifier, which\r
+// indicates what follows, followed by the data. Here's the structure.\r
+//\r
+typedef struct {\r
+  UINT16  DataType;\r
+  UINT16  Reserved;\r
+} DB_DATA_ITEM_HEADER;\r
+\r
+#define DB_DATA_TYPE_INVALID              0x0000\r
+#define DB_DATA_TYPE_STRING_IDENTIFIER    0x0001\r
+#define DB_DATA_TYPE_LANGUAGE_DEFINITION  0x0002\r
+#define DB_DATA_TYPE_STRING_DEFINITION    0x0003\r
+#define DB_DATA_TYPE_LAST                 DB_DATA_TYPE_STRING_DEFINITION\r
+\r
+//\r
+// We have to keep track of a list of languages, each of which has its own\r
+// list of strings. Define a structure to keep track of all languages and\r
+// their list of strings.\r
+//\r
+typedef struct _STRING_LIST {\r
+  struct _STRING_LIST *Next;\r
+  UINT32              Size;         // number of bytes in string, including null terminator\r
+  WCHAR               *LanguageName;\r
+  WCHAR               *StringName;  // for example STR_ID_TEXT1\r
+  WCHAR               *Scope;       //\r
+  WCHAR               *Str;         // the actual string\r
+  UINT16              Flags;        // properties of this string (used, undefined)\r
+} STRING_LIST;\r
+\r
+typedef struct _LANGUAGE_LIST {\r
+  struct _LANGUAGE_LIST *Next;\r
+  WCHAR                 *LanguageName;\r
+  WCHAR                 *PrintableLanguageName;\r
+  WCHAR                 *SecondaryLanguageList;\r
+  STRING_LIST           *String;\r
+  STRING_LIST           *LastString;\r
+} LANGUAGE_LIST;\r
+\r
+//\r
+// We also keep track of all the string identifier names, which we assign unique\r
+// values to. Create a structure to keep track of them all.\r
+//\r
+typedef struct _STRING_IDENTIFIER {\r
+  struct _STRING_IDENTIFIER *Next;\r
+  UINT32                    Index;  // only need 16 bits, but makes it easier with UINT32\r
+  WCHAR                     *StringName;\r
+  UINT16                    Flags;  // if someone referenced it via STRING_TOKEN()\r
+} STRING_IDENTIFIER;\r
+//\r
+// Keep our globals in this structure to be as modular as possible.\r
+//\r
+typedef struct {\r
+  FILE              *StringDBFptr;\r
+  LANGUAGE_LIST     *LanguageList;\r
+  LANGUAGE_LIST     *LastLanguageList;\r
+  LANGUAGE_LIST     *CurrentLanguage;         // keep track of the last language they used\r
+  STRING_IDENTIFIER *StringIdentifier;\r
+  STRING_IDENTIFIER *LastStringIdentifier;\r
+  UINT8             *StringDBFileName;\r
+  UINT32            NumStringIdentifiers;\r
+  UINT32            NumStringIdentifiersReferenced;\r
+  STRING_IDENTIFIER *CurrentStringIdentifier; // keep track of the last string identifier they added\r
+  WCHAR             *CurrentScope;\r
+} STRING_DB_DATA;\r
+\r
+typedef struct _SPkgBlkBuffer {\r
+  UINT32                mBlkSize;\r
+  VOID                  *mBlkBuffer;\r
+  struct _SPkgBlkBuffer *mNext;\r
+} SPkgBlkBuffer;\r
+\r
+void\r
+StringDBConstructor (\r
+  void\r
+  )\r
+;\r
+void\r
+StringDBDestructor (\r
+  void\r
+  )\r
+;\r
+\r
+STATUS\r
+StringDBAddString (\r
+  WCHAR   *LanguageName,\r
+  WCHAR   *StringIdentifier,\r
+  WCHAR   *Scope,\r
+  WCHAR   *String,\r
+  BOOLEAN Format,\r
+  UINT16  Flags\r
+  )\r
+;\r
+\r
+STATUS\r
+StringDBSetScope (\r
+  WCHAR   *Scope\r
+  )\r
+;\r
+\r
+#define STRING_FLAGS_REFERENCED           0x0001  // if referenced somewhere\r
+#define STRING_FLAGS_UNDEFINED            0x0002  // if we added it for padding purposes\r
+#define STRING_FLAGS_INDEX_ASSIGNED       0x0004  // so don't change the index value\r
+#define STRING_ID_INVALID                 0xFFFF\r
+#define STRING_ID_LANGUAGE_NAME           0x0000\r
+#define STRING_ID_PRINTABLE_LANGUAGE_NAME 0x0001\r
+\r
+STATUS\r
+StringDBAddStringIdentifier (\r
+  WCHAR     *StringIdentifier,\r
+  UINT16    *NewId,\r
+  UINT16    Flags\r
+  )\r
+;\r
+\r
+STATUS\r
+StringDBReadDatabase (\r
+  INT8    *DBFileName,\r
+  BOOLEAN IgnoreIfNotExist,\r
+  BOOLEAN Verbose\r
+  )\r
+;\r
+\r
+STATUS\r
+StringDBWriteDatabase (\r
+  INT8    *DBFileName,\r
+  BOOLEAN Verbose\r
+  )\r
+;\r
+\r
+STATUS\r
+StringDBDumpDatabase (\r
+  INT8                *DBFileName,\r
+  INT8                *OutputFileName,\r
+  BOOLEAN             Verbose\r
+  )\r
+;\r
+\r
+STATUS\r
+StringDBAddLanguage (\r
+  WCHAR *LanguageName,\r
+  WCHAR *PrintableLanguageName,\r
+  WCHAR *SecondaryLanguageList\r
+  )\r
+;\r
+\r
+STATUS\r
+StringDBAddSecondaryLanguage (\r
+  WCHAR *LanguageName,\r
+  WCHAR *SecondaryLanguageList\r
+  )\r
+;\r
+\r
+STATUS\r
+StringDBDumpCStrings (\r
+  INT8                            *BaseName,\r
+  INT8                            *FileName\r
+  )\r
+;\r
+\r
+STATUS\r
+StringDBDumpStringDefines (\r
+  INT8                *FileName,\r
+  INT8                *BaseName\r
+  )\r
+;\r
+\r
+STATUS\r
+StringDBSetCurrentLanguage (\r
+  WCHAR *LanguageName\r
+  )\r
+;\r
+\r
+STATUS\r
+StringDBSetStringReferenced (\r
+  INT8      *StringIdentifierName,\r
+  BOOLEAN   IgnoreNotFound\r
+  )\r
+;\r
+\r
+void\r
+StringDBFormatString (\r
+  WCHAR   *String\r
+  )\r
+;\r
+\r
+LANGUAGE_LIST *\r
+StringDBFindLanguageList (\r
+  WCHAR *LanguageName\r
+  )\r
+;\r
+\r
+#endif // #ifndef _STRING_DB_H_\r
diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/EfiVfr.h b/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/EfiVfr.h
new file mode 100644 (file)
index 0000000..43e40ab
--- /dev/null
@@ -0,0 +1,53 @@
+/*++\r
+\r
+Copyright (c) 2004 - 2007, Intel Corporation                                                         \r
+All rights reserved. This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+  EfiVfr.h\r
+\r
+Abstract:\r
+\r
+  Defines and prototypes for the UEFI VFR compiler internal use.\r
+  \r
+--*/\r
+\r
+#ifndef _EFIVFR_H_\r
+#define _EFIVFR_H_\r
+\r
+#include "Tiano.h"\r
+#include "TianoHii.h"\r
+\r
+#define MAX_PATH                 255\r
+#define MAX_LINE_LEN             4096\r
+\r
+#define EFI_IFR_MAX_LENGTH       0xFF\r
+\r
+#define EFI_VARSTORE_ID_INVALID  0\r
+#define EFI_VAROFFSET_INVALID    0xFFFF\r
+#define EFI_VARSTORE_ID_START    0x20\r
+#define EFI_STRING_ID_INVALID    0x0\r
+#define EFI_IMAGE_ID_INVALID     0xFFFF\r
+\r
+typedef enum {\r
+  QUESTION_NORMAL,\r
+  QUESTION_DATE,\r
+  QUESTION_TIME,\r
+} EFI_QUESION_TYPE;\r
+\r
+typedef enum {\r
+  EQUAL,\r
+  LESS_EQUAL,\r
+  LESS_THAN,\r
+  GREATER_THAN,\r
+  GREATER_EQUAL\r
+} EFI_COMPARE_TYPE;\r
+\r
+#endif\r
diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrCompiler.cpp b/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrCompiler.cpp
new file mode 100644 (file)
index 0000000..b1b19b9
--- /dev/null
@@ -0,0 +1,594 @@
+#include "stdio.h"\r
+#include "string.h"\r
+#include "process.h"\r
+#include "VfrCompiler.h"\r
+\r
+\r
+VOID\r
+CVfrCompiler::SET_RUN_STATUS (\r
+  IN COMPILER_RUN_STATUS Status\r
+  )\r
+{\r
+  mRunStatus = Status;\r
+}\r
+\r
+BOOLEAN\r
+CVfrCompiler::IS_RUN_STATUS (\r
+  IN COMPILER_RUN_STATUS Status\r
+  )\r
+{\r
+  return mRunStatus == Status;\r
+}\r
+\r
+VOID\r
+CVfrCompiler::OptionInitialization (\r
+  IN INT32      Argc, \r
+  IN INT8       **Argv\r
+  )\r
+{\r
+  INT32         Index;\r
+\r
+  mOptions.VfrFileName[0]                = '\0';\r
+  mOptions.RecordListFile[0]             = '\0';\r
+  mOptions.CreateRecordListFile          = FALSE;\r
+  mOptions.CreateIfrPkgFile              = FALSE;\r
+  mOptions.PkgOutputFileName[0]          = '\0';\r
+  mOptions.COutputFileName[0]            = '\0';\r
+  mOptions.OutputDirectory[0]            = '\0';\r
+  mOptions.PreprocessorOutputFileName[0] = '\0';\r
+  mOptions.VfrBaseFileName[0]            = '\0';\r
+  mOptions.IncludePaths                  = NULL;\r
+  mOptions.CPreprocessorOptions          = NULL;\r
+\r
+  for (Index = 1; (Index < Argc) && (Argv[Index][0] == '-'); Index++) {\r
+    if ((_stricmp(Argv[Index], "-?") == 0) || (_stricmp(Argv[Index], "-h") == 0)) {\r
+      Usage ();\r
+      SET_RUN_STATUS (STATUS_DEAD);\r
+      return;\r
+    } else if (_stricmp(Argv[Index], "-l") == 0) {\r
+      mOptions.CreateRecordListFile = TRUE;\r
+      gCIfrRecordInfoDB.TurnOn ();\r
+    } else if (_stricmp(Argv[Index], "-i") == 0) {\r
+      Index++;\r
+      if ((Index >= Argc) || (Argv[Index][0] == '-')) {\r
+        printf ("%s -i - missing path argument\n", PROGRAM_NAME);\r
+        goto Fail;\r
+      }\r
+\r
+      AppendIncludePath(Argv[Index]);\r
+    } else if (_stricmp(Argv[Index], "-od") == 0) {\r
+      Index++;\r
+      if ((Index >= Argc) || (Argv[Index][0] == '-')) {\r
+        printf ("%s -od - missing output directory name\n", PROGRAM_NAME);\r
+        goto Fail;\r
+      }\r
+      strcpy (mOptions.OutputDirectory, Argv[Index]);\r
+    } else if (_stricmp(Argv[Index], "-ibin") == 0) {\r
+      mOptions.CreateIfrPkgFile = TRUE;\r
+    } else if (_stricmp(Argv[Index], "-nostrings") == 0) {\r
+    } else if (_stricmp(Argv[Index], "-ppflag") == 0) {\r
+      Index++;\r
+      if ((Index >= Argc) || (Argv[Index][0] == '-')) {\r
+        printf ("%s -od - missing C-preprocessor argument\n", PROGRAM_NAME);\r
+        goto Fail;\r
+      }\r
+\r
+      AppendCPreprocessorOptions (Argv[Index]);\r
+    } else {\r
+      printf ("%s unrecognized option %s\n", PROGRAM_NAME, Argv[Index]);\r
+      Usage ();\r
+      goto Fail;\r
+    }\r
+  }\r
+\r
+  if (Index != Argc - 1) {\r
+    printf ("%s must specify VFR file name", PROGRAM_NAME);\r
+    Usage ();\r
+    goto Fail;\r
+  } else {\r
+    strcpy (mOptions.VfrFileName, Argv[Index]);\r
+  }\r
+\r
+  if (SetBaseFileName() != 0) {\r
+    goto Fail;\r
+  }\r
+  if (SetPkgOutputFileName () != 0) {\r
+    goto Fail;\r
+  }\r
+  if (SetCOutputFileName() != 0) {\r
+    goto Fail;\r
+  }\r
+  if (SetPreprocessorOutputFileName () != 0) {\r
+    goto Fail;\r
+  }\r
+  if (SetRecordListFileName () != 0) {\r
+    goto Fail;\r
+  }\r
+  return;\r
+\r
+Fail:\r
+  SET_RUN_STATUS (STATUS_FAILED);\r
+\r
+  mOptions.VfrFileName[0]                = '\0';\r
+  mOptions.RecordListFile[0]             = '\0';\r
+  mOptions.CreateRecordListFile          = FALSE;\r
+  mOptions.CreateIfrPkgFile              = FALSE;\r
+  mOptions.PkgOutputFileName[0]          = '\0';\r
+  mOptions.COutputFileName[0]            = '\0';\r
+  mOptions.OutputDirectory[0]            = '\0';\r
+  mOptions.PreprocessorOutputFileName[0] = '\0';\r
+  mOptions.VfrBaseFileName[0]            = '\0';\r
+  if (mOptions.IncludePaths != NULL) {\r
+    delete mOptions.IncludePaths;\r
+    mOptions.IncludePaths                = NULL;\r
+  } \r
+  if (mOptions.CPreprocessorOptions != NULL) {\r
+    delete mOptions.CPreprocessorOptions;\r
+    mOptions.CPreprocessorOptions        = NULL;\r
+  }\r
+}\r
+\r
+VOID\r
+CVfrCompiler::AppendIncludePath (\r
+  IN INT8       *PathStr\r
+  )\r
+{\r
+  UINT32  Len           = 0;\r
+  INT8    *IncludePaths = NULL;\r
+\r
+  Len = strlen (" -I ") + strlen (PathStr) + 1;\r
+  if (mOptions.IncludePaths != NULL) {\r
+    Len += strlen (mOptions.IncludePaths);\r
+  }\r
+  IncludePaths = new INT8[Len];\r
+  if (IncludePaths == NULL) {\r
+    printf ("%s memory allocation failure\n", PROGRAM_NAME);\r
+    return;\r
+  }\r
+  IncludePaths[0] = '\0';\r
+  if (mOptions.IncludePaths != NULL) {\r
+    strcat (IncludePaths, mOptions.IncludePaths);\r
+  }\r
+  strcat (IncludePaths, " -I ");\r
+  strcat (IncludePaths, PathStr);\r
+  if (mOptions.IncludePaths != NULL) {\r
+    delete mOptions.IncludePaths;\r
+  }\r
+  mOptions.IncludePaths = IncludePaths;\r
+}\r
+\r
+VOID\r
+CVfrCompiler::AppendCPreprocessorOptions (\r
+  IN INT8       *Options\r
+  )\r
+{\r
+  UINT32  Len           = 0;\r
+  INT8    *Opt          = NULL;\r
+\r
+  Len = strlen (Options) + strlen (" ") + 1;\r
+  if (mOptions.CPreprocessorOptions != NULL) {\r
+    Len += strlen (mOptions.CPreprocessorOptions);\r
+  }\r
+  Opt = new INT8[Len];\r
+  if (Opt == NULL) {\r
+    printf ("%s memory allocation failure\n", PROGRAM_NAME);\r
+    return;\r
+  }\r
+  Opt[0] = 0;\r
+  if (mOptions.CPreprocessorOptions != NULL) {\r
+    strcat (Opt, mOptions.CPreprocessorOptions);\r
+  }\r
+  strcat (Opt, " ");\r
+  strcat (Opt, Options);\r
+  if (mOptions.CPreprocessorOptions != NULL) {\r
+    delete mOptions.CPreprocessorOptions;\r
+  }\r
+  mOptions.CPreprocessorOptions = Opt;\r
+}\r
+\r
+INT8\r
+CVfrCompiler::SetBaseFileName (\r
+  VOID\r
+  )\r
+{\r
+  INT8          *pFileName, *pPath, *pExt;\r
+\r
+  if (mOptions.VfrFileName[0] == '\0') {\r
+    return -1;\r
+  }\r
+\r
+  pFileName = mOptions.VfrFileName;\r
+  while ((pPath = strchr (pFileName, '\\')) != NULL) {\r
+    pFileName = pPath + 1;\r
+  }\r
+\r
+  if (pFileName == NULL) {\r
+    return -1;\r
+  }\r
+\r
+  if ((pExt = strchr (pFileName, '.')) == NULL) {\r
+    return -1;\r
+  }\r
+\r
+  strncpy (mOptions.VfrBaseFileName, pFileName, pExt - pFileName);\r
+  mOptions.VfrBaseFileName[pExt - pFileName] = '\0';\r
+\r
+  return 0;\r
+}\r
+\r
+INT8\r
+CVfrCompiler::SetPkgOutputFileName (\r
+  VOID\r
+  )\r
+{\r
+  if (mOptions.VfrBaseFileName[0] == '\0') {\r
+    return -1;\r
+  }\r
+\r
+  strcpy (mOptions.PkgOutputFileName, mOptions.OutputDirectory);\r
+  strcat (mOptions.PkgOutputFileName, mOptions.VfrBaseFileName);\r
+  strcat (mOptions.PkgOutputFileName, VFR_PACKAGE_FILENAME_EXTENSION);\r
+\r
+  return 0;\r
+}\r
+\r
+INT8\r
+CVfrCompiler::SetCOutputFileName (\r
+  VOID\r
+  )\r
+{\r
+  if (mOptions.VfrBaseFileName[0] == '\0') {\r
+    return -1;\r
+  }\r
+\r
+  strcpy (mOptions.COutputFileName, mOptions.OutputDirectory);\r
+  strcat (mOptions.COutputFileName, mOptions.VfrBaseFileName);\r
+  strcat (mOptions.COutputFileName, ".c");\r
+\r
+  return 0;\r
+}\r
+\r
+INT8\r
+CVfrCompiler::SetPreprocessorOutputFileName (\r
+  VOID\r
+  )\r
+{\r
+  if (mOptions.VfrBaseFileName[0] == '\0') {\r
+    return -1;\r
+  }\r
+\r
+  strcpy (mOptions.PreprocessorOutputFileName, mOptions.OutputDirectory);\r
+  strcat (mOptions.PreprocessorOutputFileName, mOptions.VfrBaseFileName);\r
+  strcat (mOptions.PreprocessorOutputFileName, VFR_PREPROCESS_FILENAME_EXTENSION);\r
+\r
+  return 0;\r
+}\r
+\r
+INT8\r
+CVfrCompiler::SetRecordListFileName (\r
+  VOID\r
+  )\r
+{\r
+  if (mOptions.VfrBaseFileName[0] == '\0') {\r
+    return -1;\r
+  }\r
+\r
+  strcpy (mOptions.RecordListFile, mOptions.OutputDirectory);\r
+  strcat (mOptions.RecordListFile, mOptions.VfrBaseFileName);\r
+  strcat (mOptions.RecordListFile, VFR_RECORDLIST_FILENAME_EXTENSION);\r
+\r
+  return 0;\r
+}\r
+\r
+CVfrCompiler::CVfrCompiler (\r
+  IN INT32      Argc, \r
+  IN INT8       **Argv\r
+  )\r
+{\r
+  mPreProcessCmd = PREPROCESSOR_COMMAND;\r
+  mPreProcessOpt = PREPROCESSOR_OPTIONS;\r
+\r
+  OptionInitialization(Argc, Argv);\r
+\r
+  if ((IS_RUN_STATUS(STATUS_FAILED)) || (IS_RUN_STATUS(STATUS_DEAD))) {\r
+    return;\r
+  }\r
+\r
+  SET_RUN_STATUS(STATUS_INITIALIZED);\r
+}\r
+\r
+CVfrCompiler::~CVfrCompiler (\r
+  VOID\r
+  )\r
+{\r
+  if (mOptions.IncludePaths != NULL) {\r
+    delete mOptions.IncludePaths;\r
+    mOptions.IncludePaths = NULL;\r
+  }\r
+\r
+  if (mOptions.CPreprocessorOptions != NULL) {\r
+    delete mOptions.CPreprocessorOptions;\r
+    mOptions.CPreprocessorOptions = NULL;\r
+  }\r
+\r
+  SET_RUN_STATUS(STATUS_DEAD);\r
+}\r
+\r
+VOID \r
+CVfrCompiler::Usage (\r
+  VOID\r
+  )\r
+{\r
+  UINT32 Index;\r
+  CONST  INT8 *Help[] = {\r
+    " ", \r
+    "VfrCompile version " VFR_COMPILER_VERSION,\r
+    " ",\r
+    "  Usage: VfrCompile {options} [VfrFile]",\r
+    " ",\r
+    "    where options include:",\r
+    "      -? or -h       prints this help",\r
+    "      -l             create an output IFR listing file",\r
+    "      -i IncPath     add IncPath to the search path for VFR included files",\r
+    "      -od OutputDir  deposit all output files to directory OutputDir (default=cwd)",\r
+    "      -ibin          create an IFR HII pack file"\r
+    "      -ppflag        C-preprocessor argument",\r
+    "    where parameters include:",\r
+    "      VfrFile        name of the input VFR script file",\r
+    " ",\r
+    NULL\r
+    };\r
+  for (Index = 0; Help[Index] != NULL; Index++) {\r
+    fprintf (stdout, "%s\n", Help[Index]);\r
+  }\r
+}\r
+\r
+VOID\r
+CVfrCompiler::PreProcess (\r
+  VOID\r
+  )\r
+{\r
+  FILE    *pVfrFile      = NULL;\r
+  UINT32  CmdLen         = 0;\r
+  INT8    *PreProcessCmd = NULL;\r
+\r
+  if (!IS_RUN_STATUS(STATUS_INITIALIZED)) {\r
+    goto Fail;\r
+  }\r
+\r
+  if ((pVfrFile = fopen (mOptions.VfrFileName, "r")) == NULL) {\r
+    printf ("%s could not open input VFR file - %s\n", PROGRAM_NAME, mOptions.VfrFileName);\r
+    goto Fail;\r
+  }\r
+  fclose (pVfrFile);\r
+\r
+  CmdLen = strlen (mPreProcessCmd) + strlen (mPreProcessOpt) + \r
+              strlen (mOptions.VfrFileName) + strlen (mOptions.PreprocessorOutputFileName);\r
+  if (mOptions.CPreprocessorOptions != NULL) {\r
+    CmdLen += strlen (mOptions.CPreprocessorOptions);\r
+  }\r
+  if (mOptions.IncludePaths != NULL) {\r
+    CmdLen += strlen (mOptions.IncludePaths);\r
+  }\r
+\r
+  PreProcessCmd = new INT8[CmdLen + 10];\r
+  if (PreProcessCmd == NULL) {\r
+    printf ("%s could not allocate memory\n", PROGRAM_NAME);\r
+    goto Fail;\r
+  }\r
+  strcpy (PreProcessCmd, mPreProcessCmd), strcat (PreProcessCmd, " ");\r
+  strcat (PreProcessCmd, mPreProcessOpt), strcat (PreProcessCmd, " ");\r
+  if (mOptions.IncludePaths != NULL) {\r
+    strcat (PreProcessCmd, mOptions.IncludePaths), strcat (PreProcessCmd, " ");\r
+  }\r
+  if (mOptions.CPreprocessorOptions != NULL) {\r
+    strcat (PreProcessCmd, mOptions.CPreprocessorOptions), strcat (PreProcessCmd, " ");\r
+  }\r
+  strcat (PreProcessCmd, mOptions.VfrFileName), strcat (PreProcessCmd, " > ");\r
+  strcat (PreProcessCmd, mOptions.PreprocessorOutputFileName);\r
+\r
+  if (system (PreProcessCmd) != 0) {\r
+    printf ("%s failed to spawn C preprocessor on VFR file \n\t - %s\n", PROGRAM_NAME, PreProcessCmd);\r
+    goto Fail;\r
+  }\r
+\r
+  delete PreProcessCmd;\r
+  SET_RUN_STATUS (STATUS_PREPROCESSED);\r
+  return;\r
+\r
+Fail:\r
+  if (!IS_RUN_STATUS(STATUS_DEAD)) {\r
+    SET_RUN_STATUS (STATUS_FAILED);\r
+  }\r
+  delete PreProcessCmd;\r
+}\r
+\r
+extern UINT8 VfrParserStart (IN FILE *);\r
+\r
+VOID\r
+CVfrCompiler::Compile (\r
+  VOID\r
+  )\r
+{\r
+  FILE *VfrFile = NULL;\r
+\r
+  if (!IS_RUN_STATUS(STATUS_PREPROCESSED)) {\r
+    goto Fail;\r
+  }\r
+\r
+  if ((VfrFile = fopen (mOptions.PreprocessorOutputFileName, "r")) == NULL) {\r
+    printf ("%s failed to open input VFR preprocessor output file - %s\n", PROGRAM_NAME, mOptions.PreprocessorOutputFileName);\r
+    goto Fail;\r
+  }\r
+\r
+  if (VfrParserStart (VfrFile) != 0) {\r
+    goto Fail;\r
+  }\r
+\r
+  fclose (VfrFile);\r
+\r
+  if (gCFormPkg.HavePendingUnassigned () == TRUE) {\r
+    gCFormPkg.PendingAssignPrintAll ();\r
+    goto Fail;\r
+  }\r
+\r
+  SET_RUN_STATUS (STATUS_COMPILEED);\r
+  return;\r
+\r
+Fail:\r
+  if (!IS_RUN_STATUS(STATUS_DEAD)) {\r
+    printf ("%s compile error!\n", PROGRAM_NAME);\r
+    SET_RUN_STATUS (STATUS_FAILED);\r
+  }\r
+  if (VfrFile != NULL) {\r
+    fclose (VfrFile);\r
+  }\r
+}\r
+\r
+VOID\r
+CVfrCompiler::GenBinary (\r
+  VOID\r
+  )\r
+{\r
+  FILE                    *pFile = NULL;\r
+\r
+  if (!IS_RUN_STATUS(STATUS_COMPILEED)) {\r
+    goto Fail;\r
+  }\r
+\r
+  if (mOptions.CreateIfrPkgFile == TRUE) {\r
+    if ((pFile = fopen (mOptions.PkgOutputFileName, "wb")) == NULL) {\r
+      printf ("can not open PkgFileName\n", mOptions.PkgOutputFileName);\r
+      goto Fail;\r
+    }\r
+    if (gCFormPkg.BuildPkg (pFile) != VFR_RETURN_SUCCESS) {\r
+      fclose (pFile);\r
+      goto Fail;\r
+    }\r
+    fclose (pFile);\r
+  }\r
+\r
+  SET_RUN_STATUS (STATUS_GENBINARY);\r
+  return;\r
+\r
+Fail:\r
+  if (!IS_RUN_STATUS(STATUS_DEAD)) {\r
+    SET_RUN_STATUS (STATUS_FAILED);\r
+  }\r
+}\r
+\r
+static const char *gSourceFileHeader[] = {\r
+  "//",\r
+  "//  DO NOT EDIT -- auto-generated file",\r
+  "//",\r
+  "//  This file is generated by the vfrcompiler utility",\r
+  "//",\r
+  NULL\r
+};\r
+\r
+VOID\r
+CVfrCompiler::GenCFile (\r
+  VOID\r
+  )\r
+{\r
+  FILE                    *pFile;\r
+  UINT32                  Index;\r
+\r
+  if (!IS_RUN_STATUS(STATUS_GENBINARY)) {\r
+    goto Fail;\r
+  }\r
+\r
+  if ((pFile = fopen (mOptions.COutputFileName, "w")) == NULL) {\r
+    printf ("failed to open output C file - %s\n", mOptions.COutputFileName);\r
+    goto Fail;\r
+  }\r
+\r
+  for (Index = 0; gSourceFileHeader[Index] != NULL; Index++) {\r
+    fprintf (pFile, "%s\n", gSourceFileHeader[Index]);\r
+  }\r
+\r
+  gCVfrBufferConfig.OutputCFile (pFile, mOptions.VfrBaseFileName);\r
+\r
+  if (gCFormPkg.GenCFile (mOptions.VfrBaseFileName, pFile) != VFR_RETURN_SUCCESS) {\r
+    fclose (pFile);\r
+    goto Fail;\r
+  }\r
+  fclose (pFile);\r
+\r
+  SET_RUN_STATUS (STATUS_FINISHED);\r
+  return;\r
+\r
+Fail:\r
+  if (!IS_RUN_STATUS(STATUS_DEAD)) {\r
+    SET_RUN_STATUS (STATUS_FAILED);\r
+  }\r
+}\r
+\r
+VOID\r
+CVfrCompiler::GenRecordListFile (\r
+  VOID\r
+  )\r
+{\r
+  FILE   *pInFile  = NULL;\r
+  FILE   *pOutFile = NULL;\r
+  INT8   LineBuf[MAX_LINE_LEN];\r
+  UINT32 LineNo;\r
+\r
+  if (mOptions.CreateRecordListFile == TRUE) {\r
+    if ((mOptions.PreprocessorOutputFileName[0] == '\0') || (mOptions.RecordListFile[0] == '\0')) {\r
+      return;\r
+    }\r
+\r
+    if ((pInFile = fopen (mOptions.PreprocessorOutputFileName, "r")) == NULL) {\r
+      printf ("%s failed to open input VFR preprocessor output file - %s\n", PROGRAM_NAME, mOptions.PreprocessorOutputFileName);\r
+      return;\r
+    }\r
+\r
+    if ((pOutFile = fopen (mOptions.RecordListFile, "w")) == NULL) {\r
+      printf ("%s failed to open record list file for writing - %s\n", PROGRAM_NAME, mOptions.RecordListFile);\r
+      goto Err1;\r
+    }\r
+\r
+    fprintf (pOutFile, "//\n//  VFR compiler version " VFR_COMPILER_VERSION "\n//\n");\r
+    LineNo = 0;\r
+    while (!feof (pInFile)) {\r
+      if (fgets (LineBuf, MAX_LINE_LEN, pInFile) != NULL) {\r
+        fprintf (pOutFile, "%s", LineBuf);\r
+        LineNo++;\r
+        gCIfrRecordInfoDB.IfrRecordOutput (pOutFile, LineNo);\r
+      }\r
+    }\r
+\r
+    fclose (pOutFile);\r
+    fclose (pInFile);\r
+  }\r
+\r
+  return;\r
+\r
+Err1:\r
+  fclose (pInFile);\r
+}\r
+\r
+INT32\r
+main (\r
+  IN INT32             Argc, \r
+  IN INT8              **Argv\r
+  )\r
+{\r
+  COMPILER_RUN_STATUS  Status;\r
+  CVfrCompiler         Compiler(Argc, Argv);\r
+\r
+  Compiler.PreProcess();\r
+  Compiler.Compile();\r
+  Compiler.GenBinary();\r
+  Compiler.GenCFile();\r
+  Compiler.GenRecordListFile ();\r
+\r
+  Status = Compiler.RunStatus ();\r
+  if ((Status == STATUS_DEAD) || (Status == STATUS_FAILED)) {\r
+    return 2;\r
+  }\r
+\r
+  return 0;\r
+}\r
+\r
diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrCompiler.h b/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrCompiler.h
new file mode 100644 (file)
index 0000000..a980cb5
--- /dev/null
@@ -0,0 +1,90 @@
+#ifndef _VFRCOMPILER_H_\r
+#define _VFRCOMPILER_H_\r
+\r
+#include "Tiano.h"\r
+#include "EfiTypes.h"\r
+#include "EfiVfr.h"\r
+#include "VfrFormPkg.h"\r
+#include "VfrUtilityLib.h"\r
+\r
+#define PROGRAM_NAME                       "VfrCompile"\r
+#define VFR_COMPILER_VERSION               "UEFI 2.1"\r
+\r
+//\r
+// This is how we invoke the C preprocessor on the VFR source file\r
+// to resolve #defines, #includes, etc. To make C source files\r
+// shareable between VFR and drivers, define VFRCOMPILE so that\r
+// #ifdefs can be used in shared .h files.\r
+//\r
+#define PREPROCESSOR_COMMAND                "cl "\r
+#define PREPROCESSOR_OPTIONS                "/nologo /E /TC /DVFRCOMPILE "\r
+\r
+//\r
+// Specify the filename extensions for the files we generate.\r
+//\r
+#define VFR_PREPROCESS_FILENAME_EXTENSION   ".i"\r
+#define VFR_PACKAGE_FILENAME_EXTENSION      ".hpk"\r
+#define VFR_RECORDLIST_FILENAME_EXTENSION   ".lst"\r
+\r
+typedef struct {\r
+  INT8    VfrFileName[MAX_PATH];\r
+  INT8    RecordListFile[MAX_PATH];\r
+  INT8    PkgOutputFileName[MAX_PATH];\r
+  INT8    COutputFileName[MAX_PATH];\r
+  bool    CreateRecordListFile;\r
+  bool    CreateIfrPkgFile;\r
+  INT8    OutputDirectory[MAX_PATH];\r
+  INT8    PreprocessorOutputFileName[MAX_PATH];\r
+  INT8    VfrBaseFileName[MAX_PATH];  // name of input VFR file with no path or extension\r
+  INT8    *IncludePaths;\r
+  INT8    *CPreprocessorOptions;\r
+} OPTIONS;\r
+\r
+typedef enum {\r
+  STATUS_INITIALIZED = 1,\r
+  STATUS_PREPROCESSED,\r
+  STATUS_COMPILEED,\r
+  STATUS_GENBINARY,\r
+  STATUS_FINISHED,\r
+  STATUS_FAILED,\r
+  STATUS_DEAD,\r
+} COMPILER_RUN_STATUS;\r
+\r
+class CVfrCompiler {\r
+private:\r
+  COMPILER_RUN_STATUS  mRunStatus;\r
+  OPTIONS              mOptions;\r
+  INT8                 *mPreProcessCmd;\r
+  INT8                 *mPreProcessOpt;\r
+\r
+  VOID    OptionInitialization (IN INT32 , IN INT8 **);\r
+  VOID    AppendIncludePath (IN INT8 *);\r
+  VOID    AppendCPreprocessorOptions (IN INT8 *);\r
+  INT8    SetBaseFileName (VOID);\r
+  INT8    SetPkgOutputFileName (VOID);\r
+  INT8    SetCOutputFileName(VOID);\r
+  INT8    SetPreprocessorOutputFileName (VOID);\r
+  INT8    SetRecordListFileName (VOID);\r
+\r
+  VOID    SET_RUN_STATUS (IN COMPILER_RUN_STATUS);\r
+  BOOLEAN IS_RUN_STATUS (IN COMPILER_RUN_STATUS);\r
+\r
+public:\r
+  COMPILER_RUN_STATUS RunStatus (VOID) {\r
+    return mRunStatus;\r
+  }\r
+\r
+public:\r
+  CVfrCompiler (IN INT32 , IN INT8 **);\r
+  ~CVfrCompiler ();\r
+\r
+  VOID                Usage (VOID);\r
+\r
+  VOID                PreProcess (VOID);\r
+  VOID                Compile (VOID);\r
+  VOID                GenBinary (VOID);\r
+  VOID                GenCFile (VOID);\r
+  VOID                GenRecordListFile (VOID);\r
+};\r
+\r
+#endif\r
diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrError.cpp b/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrError.cpp
new file mode 100644 (file)
index 0000000..e157577
--- /dev/null
@@ -0,0 +1,197 @@
+#include "stdio.h"\r
+#include "string.h"\r
+#include "stdlib.h"\r
+#include "VfrError.h"\r
+\r
+static SVFR_ERROR_HANDLE VFR_ERROR_HANDLE_TABLE [] = {\r
+  { VFR_RETURN_SUCCESS, NULL },\r
+  { VFR_RETURN_ERROR_SKIPED, NULL },\r
+  { VFR_RETURN_FATAL_ERROR, "fatal error!!" },\r
+\r
+  { VFR_RETURN_MISMATCHED, "unexpected token" },\r
+  { VFR_RETURN_INVALID_PARAMETER, "Invalid parameter" },\r
+  { VFR_RETURN_OUT_FOR_RESOURCES, "system out of memory" },\r
+  { VFR_RETURN_UNSUPPORTED, "unsupported" },\r
+  { VFR_RETURN_REDEFINED, "already defined" },\r
+  { VFR_RETURN_FORMID_REDEFINED, "form id already defined" },\r
+  { VFR_RETURN_QUESTIONID_REDEFINED, "question id already defined" },\r
+  { VFR_RETURN_VARSTOREID_REDEFINED, "varstore id already defined" },\r
+  { VFR_RETURN_UNDEFINED, "undefined" },\r
+  { VFR_RETURN_VAR_NOTDEFINED_BY_QUESTION, "some variable has not defined by a question"},\r
+  { VFR_RETURN_GET_EFIVARSTORE_ERROR, "get efi varstore error"},\r
+  { VFR_RETURN_EFIVARSTORE_USE_ERROR, "can not use the efi varstore like this" },\r
+  { VFR_RETURN_EFIVARSTORE_SIZE_ERROR, "unsupport efi varstore size should be <= 8 bytes" },\r
+  { VFR_RETURN_GET_NVVARSTORE_ERROR, "get name value varstore error" },\r
+  { VFR_RETURN_QVAR_REUSE, "variable reused by more than one question" }, \r
+  { VFR_RETURN_FLAGS_UNSUPPORTED, "flags unsupported" }, \r
+  { VFR_RETURN_ERROR_ARRARY_NUM, "array number error" },\r
+  { VFR_RETURN_DATA_STRING_ERROR, "data field string error or not support"},\r
+  { VFR_RETURN_CODEUNDEFINED, "Undefined Error Code" }\r
+};\r
+\r
+CVfrErrorHandle::CVfrErrorHandle (\r
+  VOID\r
+  )\r
+{\r
+  mScopeRecordListHead = NULL;\r
+  mScopeRecordListTail = NULL;\r
+  mVfrErrorHandleTable = VFR_ERROR_HANDLE_TABLE;\r
+}\r
+\r
+CVfrErrorHandle::~CVfrErrorHandle (\r
+  VOID\r
+  )\r
+{\r
+  SVfrFileScopeRecord *pNode = NULL;\r
+\r
+  while (mScopeRecordListHead != NULL) {\r
+    pNode = mScopeRecordListHead;\r
+    mScopeRecordListHead = mScopeRecordListHead->mNext;\r
+    delete pNode;\r
+  }\r
+\r
+  mScopeRecordListHead = NULL;\r
+  mScopeRecordListTail = NULL;\r
+  mVfrErrorHandleTable = NULL;\r
+}\r
+\r
+SVfrFileScopeRecord::SVfrFileScopeRecord (\r
+  IN INT8     *Record, \r
+  IN UINT32   LineNum\r
+  )\r
+{\r
+  UINT32      Index;\r
+  INT8        *FileName = NULL;\r
+  INT8        *Str      = NULL;\r
+\r
+  mWholeScopeLine      = LineNum;\r
+  mNext                = NULL;\r
+\r
+  Str = strchr (Record, ' ');\r
+  mScopeLineStart = atoi (++Str);\r
+\r
+  Str = strchr (Str, '\"');\r
+  FileName = ++Str;\r
+\r
+  while((Str = strstr (FileName, "\\\\")) != NULL) {\r
+    FileName = Str + 2;\r
+  }\r
+  if ((mFileName = new INT8[strlen(FileName)]) != NULL) {\r
+    for (Index = 0; FileName[Index] != '\"'; Index++) {\r
+      mFileName[Index] = FileName[Index];\r
+    }\r
+    mFileName[Index] = '\0';\r
+  }\r
+\r
+  return;\r
+}\r
+\r
+SVfrFileScopeRecord::~SVfrFileScopeRecord (\r
+  VOID\r
+  )\r
+{\r
+  if (mFileName != NULL) {\r
+    delete mFileName;\r
+  }\r
+}\r
+\r
+VOID\r
+CVfrErrorHandle::ParseFileScopeRecord (\r
+  IN INT8      *Record, \r
+  IN UINT32    WholeScopeLine\r
+  )\r
+{\r
+  INT8                *FullPathName = NULL;\r
+  SVfrFileScopeRecord *pNode        = NULL;\r
+\r
+  if (Record == NULL) {\r
+    return;\r
+  }\r
+\r
+  if ((pNode = new SVfrFileScopeRecord(Record, WholeScopeLine)) == NULL) {\r
+    return;\r
+  }\r
+\r
+  if (mScopeRecordListHead == NULL) {\r
+    mScopeRecordListTail = mScopeRecordListHead = pNode;\r
+  } else {\r
+    mScopeRecordListTail->mNext = pNode;\r
+    mScopeRecordListTail        = pNode;\r
+  }\r
+}\r
+\r
+VOID\r
+CVfrErrorHandle::GetFileNameLineNum (\r
+  IN  UINT32 LineNum,\r
+  OUT INT8   **FileName,\r
+  OUT UINT32 *FileLine\r
+  )\r
+{\r
+  SVfrFileScopeRecord *pNode    = NULL;\r
+\r
+  if ((FileName == NULL) || (FileLine == NULL)) {\r
+    return;\r
+  }\r
+\r
+  *FileName = NULL;\r
+  *FileLine = 0xFFFFFFFF;\r
+\r
+  for (pNode = mScopeRecordListHead; pNode->mNext != NULL; pNode = pNode->mNext) {\r
+    if ((LineNum > pNode->mWholeScopeLine) && (pNode->mNext->mWholeScopeLine > LineNum)) {\r
+      *FileName = pNode->mFileName;\r
+      *FileLine = LineNum - pNode->mWholeScopeLine + pNode->mScopeLineStart - 1;\r
+      return ;\r
+    }\r
+  }\r
+\r
+  *FileName = pNode->mFileName;\r
+  *FileLine = LineNum - pNode->mWholeScopeLine + pNode->mScopeLineStart - 1;\r
+}\r
+\r
+VOID\r
+CVfrErrorHandle::PrintError (\r
+  IN UINT32               LineNum,\r
+  IN INT8                 *TokName,\r
+  IN INT8                 *ErrorMsg\r
+  )\r
+{\r
+  INT8                   *FileName = NULL;\r
+  UINT32                 FileLine;\r
+\r
+  GetFileNameLineNum (LineNum, &FileName, &FileLine);\r
+  printf ("%s line %d: error %s %s\n", FileName, FileLine, TokName, ErrorMsg);\r
+}\r
+\r
+UINT8\r
+CVfrErrorHandle::HandleError (\r
+  IN EFI_VFR_RETURN_CODE  ErrorCode,\r
+  IN UINT32               LineNum,\r
+  IN INT8                 *TokName\r
+  )\r
+{\r
+  UINT32                 Index;\r
+  INT8                   *FileName = NULL;\r
+  UINT32                 FileLine;\r
+  INT8                   *ErrorMsg = NULL;\r
+\r
+  if (mVfrErrorHandleTable == NULL) {\r
+    return 1;\r
+  }\r
+\r
+  for (Index = 0; mVfrErrorHandleTable[Index].mErrorCode != VFR_RETURN_CODEUNDEFINED; Index++) {\r
+    if (ErrorCode == mVfrErrorHandleTable[Index].mErrorCode) {\r
+      ErrorMsg = mVfrErrorHandleTable[Index].mErrorMsg;\r
+      break;\r
+    }\r
+  }\r
+\r
+  if (ErrorMsg != NULL) {\r
+    GetFileNameLineNum (LineNum, &FileName, &FileLine);\r
+    printf ("%s line %d: error %s %s\n", FileName, FileLine, TokName, ErrorMsg);\r
+    return 1;\r
+  } else {\r
+    return 0;\r
+  }\r
+}\r
+\r
+CVfrErrorHandle gCVfrErrorHandle;\r
diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrError.h b/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrError.h
new file mode 100644 (file)
index 0000000..5e8ac51
--- /dev/null
@@ -0,0 +1,67 @@
+#ifndef _VFRERROR_H_\r
+#define _VFRERROR_H_\r
+\r
+#include "Tiano.h"\r
+#include "EfiTypes.h"\r
+\r
+typedef enum {\r
+  VFR_RETURN_SUCCESS = 0,\r
+  VFR_RETURN_ERROR_SKIPED,\r
+  VFR_RETURN_FATAL_ERROR,\r
+  VFR_RETURN_MISMATCHED,\r
+  VFR_RETURN_INVALID_PARAMETER,\r
+  VFR_RETURN_OUT_FOR_RESOURCES,\r
+  VFR_RETURN_UNSUPPORTED,\r
+  VFR_RETURN_REDEFINED,\r
+  VFR_RETURN_FORMID_REDEFINED,\r
+  VFR_RETURN_QUESTIONID_REDEFINED,\r
+  VFR_RETURN_VARSTOREID_REDEFINED,\r
+  VFR_RETURN_UNDEFINED,\r
+  VFR_RETURN_VAR_NOTDEFINED_BY_QUESTION,\r
+  VFR_RETURN_GET_EFIVARSTORE_ERROR,\r
+  VFR_RETURN_EFIVARSTORE_USE_ERROR,\r
+  VFR_RETURN_EFIVARSTORE_SIZE_ERROR,\r
+  VFR_RETURN_GET_NVVARSTORE_ERROR,\r
+  VFR_RETURN_QVAR_REUSE,\r
+  VFR_RETURN_FLAGS_UNSUPPORTED,\r
+  VFR_RETURN_ERROR_ARRARY_NUM,\r
+  VFR_RETURN_DATA_STRING_ERROR,\r
+  VFR_RETURN_CODEUNDEFINED\r
+} EFI_VFR_RETURN_CODE;\r
+\r
+typedef struct _SVFR_ERROR_HANDLE {\r
+  EFI_VFR_RETURN_CODE    mErrorCode;\r
+  INT8                   *mErrorMsg;\r
+} SVFR_ERROR_HANDLE;\r
+\r
+struct SVfrFileScopeRecord {\r
+  INT8                  *mFileName;\r
+  UINT32                mWholeScopeLine;\r
+  UINT32                mScopeLineStart;\r
+  SVfrFileScopeRecord *mNext;\r
+\r
+  SVfrFileScopeRecord (IN INT8 *, IN UINT32);\r
+  ~SVfrFileScopeRecord();\r
+};\r
+\r
+class CVfrErrorHandle {\r
+private:\r
+  SVFR_ERROR_HANDLE   *mVfrErrorHandleTable;\r
+  SVfrFileScopeRecord *mScopeRecordListHead;\r
+  SVfrFileScopeRecord *mScopeRecordListTail;\r
+\r
+public:\r
+  CVfrErrorHandle (VOID);\r
+  ~CVfrErrorHandle (VOID);\r
+\r
+  VOID  ParseFileScopeRecord (IN INT8 *, IN UINT32);\r
+  VOID  GetFileNameLineNum (IN UINT32, OUT INT8 **, OUT UINT32 *);\r
+  UINT8 HandleError (IN EFI_VFR_RETURN_CODE, IN UINT32 LineNum = 0, IN INT8 *TokName = "\0");\r
+  VOID  PrintError (IN UINT32 LineNum = 0, IN INT8 *TokName = "\0", IN INT8 *ErrorMsg = "\0");\r
+};\r
+\r
+#define CHECK_ERROR_RETURN(f, v) do { EFI_VFR_RETURN_CODE r; if ((r = (f)) != (v)) { return r; } } while (0)\r
+\r
+extern CVfrErrorHandle gCVfrErrorHandle;\r
+\r
+#endif\r
diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrFormPkg.cpp b/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrFormPkg.cpp
new file mode 100644 (file)
index 0000000..2ac1b68
--- /dev/null
@@ -0,0 +1,830 @@
+#include "stdio.h"\r
+#include "VfrFormPkg.h"\r
+\r
+/*\r
+ * The definition of CFormPkg's member function\r
+ */\r
+\r
+SPendingAssign::SPendingAssign (\r
+  IN INT8   *Key, \r
+  IN VOID   *Addr, \r
+  IN UINT32 Len, \r
+  IN UINT32 LineNo\r
+  )\r
+{\r
+  if (Key != NULL) {\r
+    mKey = new INT8[strlen (Key) + 1];\r
+    if (mKey != NULL) {\r
+      strcpy (mKey, Key);\r
+    }\r
+  } else {\r
+    mKey = NULL;\r
+  }\r
+  mAddr   = Addr;\r
+  mLen    = Len;\r
+  mFlag   = PENDING;\r
+  mLineNo = LineNo;\r
+  mNext   = NULL;\r
+}\r
+\r
+SPendingAssign::~SPendingAssign (\r
+  VOID\r
+  )\r
+{\r
+  if (mKey != NULL) {\r
+    delete mKey;\r
+  }\r
+  mAddr   = NULL;\r
+  mLen    = 0;\r
+  mLineNo = 0;\r
+  mNext   = NULL;\r
+}\r
+\r
+VOID\r
+SPendingAssign::SetAddrAndLen (\r
+  IN VOID   *Addr, \r
+  IN UINT32 LineNo\r
+  )\r
+{\r
+  mAddr   = Addr;\r
+  mLineNo = LineNo;\r
+}\r
+\r
+VOID\r
+SPendingAssign::AssignValue (\r
+  IN VOID   *Addr, \r
+  IN UINT32 Len\r
+  )\r
+{\r
+  memcpy (mAddr, Addr, (mLen < Len ? mLen : Len));\r
+  mFlag = ASSIGNED;\r
+}\r
+\r
+INT8 *\r
+SPendingAssign::GetKey (\r
+  VOID\r
+  )\r
+{\r
+  return mKey;\r
+}\r
+\r
+CFormPkg::CFormPkg (\r
+  IN UINT32 BufferSize = 4096\r
+  )\r
+{\r
+  CHAR8       *BufferStart;\r
+  CHAR8       *BufferEnd;\r
+  SBufferNode *Node;\r
+\r
+  mPkgLength           = 0;\r
+  mBufferNodeQueueHead = NULL;\r
+  mCurrBufferNode      = NULL;\r
+\r
+  Node = new SBufferNode;\r
+  if (Node == NULL) {\r
+    return ;\r
+  }\r
+  BufferStart = new CHAR8[BufferSize];\r
+  if (BufferStart == NULL) {\r
+    return;\r
+  }\r
+  BufferEnd   = BufferStart + BufferSize;\r
+\r
+  memset (BufferStart, 0, BufferSize);\r
+  Node->mBufferStart   = BufferStart;\r
+  Node->mBufferEnd     = BufferEnd;\r
+  Node->mBufferFree    = BufferStart;\r
+  Node->mNext          = NULL;\r
+\r
+  mBufferSize          = BufferSize;\r
+  mBufferNodeQueueHead = Node;\r
+  mBufferNodeQueueTail = Node;\r
+  mCurrBufferNode      = Node;\r
+}\r
+\r
+CFormPkg::~CFormPkg ()\r
+{\r
+  SBufferNode    *pBNode;\r
+  SPendingAssign *pPNode;\r
+\r
+  while (mBufferNodeQueueHead != NULL) {\r
+    pBNode = mBufferNodeQueueHead;\r
+    mBufferNodeQueueHead = mBufferNodeQueueHead->mNext;\r
+    if (pBNode->mBufferStart != NULL) {\r
+      delete pBNode->mBufferStart;\r
+      delete pBNode;\r
+    }\r
+  }\r
+  mBufferNodeQueueTail = NULL;\r
+  mCurrBufferNode      = NULL;\r
+\r
+  while (PendingAssignList != NULL) {\r
+    pPNode = PendingAssignList;\r
+    PendingAssignList = PendingAssignList->mNext;\r
+    delete pPNode;\r
+  }\r
+  PendingAssignList = NULL;\r
+}\r
+\r
+CHAR8 *\r
+CFormPkg::IfrBinBufferGet (\r
+  IN UINT32 Len\r
+  )\r
+{\r
+  CHAR8 *BinBuffer = NULL;\r
+\r
+  if ((Len == 0) || (Len > mBufferSize)) {\r
+    return NULL;\r
+  }\r
+\r
+  if ((mCurrBufferNode->mBufferFree + Len) <= mCurrBufferNode->mBufferEnd) {\r
+    BinBuffer = mCurrBufferNode->mBufferFree;\r
+    mCurrBufferNode->mBufferFree += Len;\r
+  } else {\r
+    SBufferNode *Node;\r
+\r
+    Node = new SBufferNode;\r
+    if (Node == NULL) {\r
+      return NULL;\r
+    }\r
+\r
+    Node->mBufferStart = new CHAR8[mBufferSize];\r
+    if (Node->mBufferStart == NULL) {\r
+      delete Node;\r
+      return NULL;\r
+    } else {\r
+      memset (Node->mBufferStart, 0, mBufferSize);\r
+      Node->mBufferEnd  = Node->mBufferStart + mBufferSize;\r
+      Node->mBufferFree = Node->mBufferStart;\r
+      Node->mNext       = NULL;\r
+    }\r
+\r
+    if (mBufferNodeQueueTail == NULL) {\r
+      mBufferNodeQueueHead = mBufferNodeQueueTail = Node;\r
+    } else {\r
+      mBufferNodeQueueTail->mNext = Node;\r
+      mBufferNodeQueueTail = Node;\r
+    }\r
+    mCurrBufferNode = Node;\r
+\r
+    //\r
+    // Now try again.\r
+    //\r
+    BinBuffer = mCurrBufferNode->mBufferFree;\r
+    mCurrBufferNode->mBufferFree += Len;\r
+  }\r
+\r
+  mPkgLength += Len;\r
+\r
+  return BinBuffer;\r
+}\r
+\r
+inline\r
+UINT32\r
+CFormPkg::GetPkgLength (\r
+  VOID\r
+  )\r
+{\r
+  return mPkgLength;\r
+}\r
+\r
+VOID\r
+CFormPkg::Open (\r
+  VOID\r
+  )\r
+{\r
+  mReadBufferNode   = mBufferNodeQueueHead;\r
+  mReadBufferOffset = 0;\r
+}\r
+\r
+VOID\r
+CFormPkg::Close (\r
+  VOID\r
+  )\r
+{\r
+  mReadBufferNode   = NULL;\r
+  mReadBufferOffset = 0;\r
+}\r
+\r
+UINT32\r
+CFormPkg::Read (\r
+  IN CHAR8     *Buffer, \r
+  IN UINT32    Size\r
+  )\r
+{\r
+  UINT32       Index;\r
+\r
+  if ((Size == 0) || (Buffer == NULL)) {\r
+    return 0;\r
+  }\r
+\r
+  if (mReadBufferNode == NULL) {\r
+       return 0;\r
+  }\r
+\r
+  for (Index = 0; Index < Size; Index++) {\r
+    if ((mReadBufferNode->mBufferStart + mReadBufferOffset) < mReadBufferNode->mBufferFree) {\r
+      Buffer[Index] = mReadBufferNode->mBufferStart[mReadBufferOffset++];\r
+    } else {\r
+      if ((mReadBufferNode = mReadBufferNode->mNext) == NULL) {\r
+        return Index;\r
+      } else {\r
+        mReadBufferOffset = 0;\r
+        Buffer[Index] = mReadBufferNode->mBufferStart[mReadBufferOffset++];\r
+      }\r
+    }\r
+  }\r
+\r
+  return Size;\r
+}\r
+\r
+EFI_VFR_RETURN_CODE\r
+CFormPkg::BuildPkgHdr (\r
+  OUT EFI_HII_PACKAGE_HEADER **PkgHdr\r
+  )\r
+{\r
+  if (PkgHdr == NULL) {\r
+    return VFR_RETURN_FATAL_ERROR;\r
+  }\r
+\r
+  if (((*PkgHdr) = new EFI_HII_PACKAGE_HEADER) == NULL) {\r
+    return VFR_RETURN_OUT_FOR_RESOURCES;\r
+  }\r
+\r
+  (*PkgHdr)->Type = EFI_HII_PACKAGE_FORM;\r
+  (*PkgHdr)->Length = mPkgLength + sizeof (EFI_HII_PACKAGE_HEADER);\r
+  return VFR_RETURN_SUCCESS;\r
+}\r
+\r
+EFI_VFR_RETURN_CODE\r
+CFormPkg::BuildPkg (\r
+  IN FILE  *Output\r
+  )\r
+{\r
+  EFI_VFR_RETURN_CODE     Ret;\r
+  CHAR8                   Buffer[1024];\r
+  UINT32                  Size;\r
+  EFI_HII_PACKAGE_HEADER  *PkgHdr;\r
+\r
+  if (Output == NULL) {\r
+    return VFR_RETURN_FATAL_ERROR;\r
+  }\r
+\r
+  if ((Ret = BuildPkgHdr(&PkgHdr)) != VFR_RETURN_SUCCESS) {\r
+    return Ret;\r
+  }\r
+  fwrite (PkgHdr, sizeof (EFI_HII_PACKAGE_HEADER), 1, Output);\r
+  delete PkgHdr;\r
+\r
+  Open ();\r
+  while ((Size = Read (Buffer, 1024)) != 0) {\r
+    fwrite (Buffer, Size, 1, Output);\r
+  }\r
+  Close ();\r
+\r
+  return VFR_RETURN_SUCCESS;\r
+}\r
+\r
+VOID\r
+CFormPkg::_WRITE_PKG_LINE (\r
+  IN FILE   *pFile,\r
+  IN UINT32 LineBytes,\r
+  IN INT8   *LineHeader,\r
+  IN INT8   *BlkBuf,\r
+  IN UINT32 BlkSize\r
+  )\r
+{\r
+  UINT32    Index;\r
+\r
+  if ((pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) {\r
+    return;\r
+  }\r
+\r
+  for (Index = 0; Index < BlkSize; Index++) {\r
+    if ((Index % LineBytes) == 0) {\r
+      fprintf (pFile, "\n%s", LineHeader);\r
+    }\r
+    fprintf (pFile, "0x%02X,  ", (UINT8)BlkBuf[Index]);\r
+  }\r
+}\r
+\r
+VOID\r
+CFormPkg::_WRITE_PKG_END (\r
+  IN FILE   *pFile,\r
+  IN UINT32 LineBytes,\r
+  IN INT8   *LineHeader,\r
+  IN INT8   *BlkBuf,\r
+  IN UINT32 BlkSize\r
+  )\r
+{\r
+  UINT32    Index;\r
+\r
+  if ((BlkSize == 0) || (pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) {\r
+    return;\r
+  }\r
+\r
+  for (Index = 0; Index < BlkSize - 1; Index++) {\r
+    if ((Index % LineBytes) == 0) {\r
+      fprintf (pFile, "\n%s", LineHeader);\r
+    }\r
+    fprintf (pFile, "0x%02X,  ", (UINT8)BlkBuf[Index]);\r
+  }\r
+\r
+  if ((Index % LineBytes) == 0) {\r
+    fprintf (pFile, "\n%s", LineHeader);\r
+  }\r
+  fprintf (pFile, "0x%02X\n", (UINT8)BlkBuf[Index]);\r
+}\r
+\r
+#define BYTES_PRE_LINE 0x10\r
+\r
+EFI_VFR_RETURN_CODE \r
+CFormPkg::GenCFile (\r
+  IN INT8 *BaseName,\r
+  IN FILE *pFile\r
+  )\r
+{\r
+  EFI_VFR_RETURN_CODE          Ret;\r
+  INT8                         Buffer[BYTES_PRE_LINE * 8];\r
+  EFI_HII_PACKAGE_HEADER       *PkgHdr;\r
+  UINT32                       PkgLength  = 0;\r
+  UINT32                       ReadSize   = 0;\r
+\r
+  if ((BaseName == NULL) || (pFile == NULL)) {\r
+    return VFR_RETURN_FATAL_ERROR;\r
+  }\r
+\r
+  fprintf (pFile, "\nunsigned char %sBin[] = {\n", BaseName);\r
+\r
+  if ((Ret = BuildPkgHdr(&PkgHdr)) != VFR_RETURN_SUCCESS) {\r
+    return Ret;\r
+  }\r
+\r
+  fprintf (pFile, "  // ARRAY LENGTH\n");\r
+  PkgLength = PkgHdr->Length + sizeof (UINT32);\r
+  _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, "  ", (INT8 *)&PkgLength, sizeof (UINT32));\r
+\r
+  fprintf (pFile, "\n\n  // PACKAGE HEADER\n");\r
+  _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, "  ", (INT8 *)PkgHdr, sizeof (EFI_HII_PACKAGE_HEADER));\r
+  PkgLength = sizeof (EFI_HII_PACKAGE_HEADER);\r
+\r
+  fprintf (pFile, "\n\n  // PACKAGE DATA\n");\r
+  Open ();\r
+  while ((ReadSize = Read ((CHAR8 *)Buffer, BYTES_PRE_LINE * 8)) != 0) {\r
+    PkgLength += ReadSize;\r
+    if (PkgLength < PkgHdr->Length) {\r
+      _WRITE_PKG_LINE (pFile, BYTES_PRE_LINE, "  ", Buffer, ReadSize);\r
+    } else {\r
+      _WRITE_PKG_END (pFile, BYTES_PRE_LINE, "  ", Buffer, ReadSize);\r
+    }\r
+  }\r
+  Close ();\r
+\r
+  delete PkgHdr;\r
+  fprintf (pFile, "\n};\n");\r
+\r
+  return VFR_RETURN_SUCCESS;\r
+}\r
+\r
+EFI_VFR_RETURN_CODE\r
+CFormPkg::AssignPending (\r
+  IN INT8   *Key, \r
+  IN VOID   *ValAddr, \r
+  IN UINT32 ValLen,\r
+  IN UINT32 LineNo\r
+  )\r
+{\r
+  SPendingAssign *pNew;\r
+\r
+  pNew = new SPendingAssign (Key, ValAddr, ValLen, LineNo);\r
+  if (pNew == NULL) {\r
+    return VFR_RETURN_OUT_FOR_RESOURCES;\r
+  }\r
+\r
+  pNew->mNext       = PendingAssignList;\r
+  PendingAssignList = pNew;\r
+  return VFR_RETURN_SUCCESS;\r
+}\r
+\r
+VOID\r
+CFormPkg::DoPendingAssign (\r
+  IN INT8   *Key, \r
+  IN VOID   *ValAddr, \r
+  IN UINT32 ValLen\r
+  )\r
+{\r
+  SPendingAssign *pNode;\r
+\r
+  if ((Key == NULL) || (ValAddr == NULL)) {\r
+    return;\r
+  }\r
+\r
+  for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {\r
+    if (strcmp (pNode->mKey, Key) == 0) {\r
+      pNode->AssignValue (ValAddr, ValLen);\r
+    }\r
+  }\r
+}\r
+\r
+bool\r
+CFormPkg::HavePendingUnassigned (\r
+  VOID\r
+  )\r
+{\r
+  SPendingAssign *pNode;\r
+\r
+  for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {\r
+    if (pNode->mFlag == PENDING) {\r
+      return TRUE;\r
+    }\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
+VOID\r
+CFormPkg::PendingAssignPrintAll (\r
+  VOID\r
+  )\r
+{\r
+  SPendingAssign *pNode;\r
+\r
+  for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {\r
+    if (pNode->mFlag == PENDING) {\r
+      gCVfrErrorHandle.PrintError (pNode->mLineNo, pNode->mKey, "can not assign value because not defined");\r
+    }\r
+  }\r
+}\r
+\r
+CFormPkg gCFormPkg;\r
+\r
+SIfrRecord::SIfrRecord (\r
+  VOID\r
+  )\r
+{\r
+  mIfrBinBuf = NULL;\r
+  mBinBufLen = 0;\r
+  mLineNo    = 0xFFFFFFFF;\r
+  mOffset    = 0xFFFFFFFF;\r
+  mNext      = NULL;\r
+}\r
+\r
+SIfrRecord::~SIfrRecord (\r
+  VOID\r
+  )\r
+{\r
+  if (mIfrBinBuf != NULL) {\r
+    delete mIfrBinBuf;\r
+    mIfrBinBuf = NULL;\r
+  }\r
+  mLineNo      = 0xFFFFFFFF;\r
+  mOffset      = 0xFFFFFFFF;\r
+  mBinBufLen   = 0;\r
+  mNext        = NULL;\r
+}\r
+\r
+CIfrRecordInfoDB::CIfrRecordInfoDB (\r
+  VOID\r
+  )\r
+{\r
+  mSwitch            = FALSE;\r
+  mRecordCount       = EFI_IFR_RECORDINFO_IDX_START;\r
+  mIfrRecordListHead = NULL;\r
+  mIfrRecordListTail = NULL;\r
+}\r
+\r
+CIfrRecordInfoDB::~CIfrRecordInfoDB (\r
+  VOID\r
+  )\r
+{\r
+  SIfrRecord *pNode;\r
+\r
+  while (mIfrRecordListHead != NULL) {\r
+    pNode = mIfrRecordListHead;\r
+    mIfrRecordListHead = mIfrRecordListHead->mNext;\r
+    delete pNode;\r
+  }\r
+}\r
+\r
+SIfrRecord *\r
+CIfrRecordInfoDB::GetRecordInfoFromIdx (\r
+  IN UINT32 RecordIdx\r
+  )\r
+{\r
+  UINT32     Idx;\r
+  SIfrRecord *pNode = NULL;\r
+\r
+  if (RecordIdx == EFI_IFR_RECORDINFO_IDX_INVALUD) {\r
+    return NULL;\r
+  }\r
+\r
+  for (Idx = (EFI_IFR_RECORDINFO_IDX_START + 1), pNode = mIfrRecordListHead; \r
+       (Idx != RecordIdx) && (pNode != NULL); \r
+       Idx++, pNode = pNode->mNext)\r
+  ;\r
+\r
+  return pNode;\r
+}\r
+\r
+UINT32\r
+CIfrRecordInfoDB::IfrRecordRegister (\r
+  IN UINT32 LineNo, \r
+  IN CHAR8  *IfrBinBuf, \r
+  IN UINT8  BinBufLen,\r
+  IN UINT32 Offset\r
+  )\r
+{\r
+  SIfrRecord *pNew;\r
+\r
+  if (mSwitch == FALSE) {\r
+    return EFI_IFR_RECORDINFO_IDX_INVALUD;\r
+  }\r
+\r
+  if ((pNew = new SIfrRecord) == NULL) {\r
+    return EFI_IFR_RECORDINFO_IDX_INVALUD;\r
+  }\r
+\r
+  if (mIfrRecordListHead == NULL) {\r
+    mIfrRecordListHead = pNew;\r
+    mIfrRecordListTail = pNew;\r
+  } else {\r
+    mIfrRecordListTail->mNext = pNew;\r
+    mIfrRecordListTail = pNew;\r
+  }\r
+  mRecordCount++;\r
+\r
+  return mRecordCount;\r
+}\r
+\r
+VOID\r
+CIfrRecordInfoDB::IfrRecordInfoUpdate (\r
+  IN UINT32 RecordIdx, \r
+  IN UINT32 LineNo,\r
+  IN CHAR8  *BinBuf,\r
+  IN UINT8  BinBufLen,\r
+  IN UINT32 Offset\r
+  )\r
+{\r
+  SIfrRecord *pNode;\r
+\r
+  if ((pNode = GetRecordInfoFromIdx (RecordIdx)) == NULL) {\r
+    return;\r
+  }\r
+\r
+  pNode->mLineNo    = LineNo;\r
+  pNode->mOffset    = Offset;\r
+  pNode->mBinBufLen = BinBufLen;\r
+  if (BinBuf != NULL) {\r
+    if (pNode->mIfrBinBuf != NULL) {\r
+      delete pNode->mIfrBinBuf;\r
+    }\r
+    pNode->mIfrBinBuf = new CHAR8[BinBufLen];\r
+    if (pNode->mIfrBinBuf != NULL) {\r
+      memcpy (pNode->mIfrBinBuf, BinBuf, BinBufLen);\r
+    }\r
+  }\r
+}\r
+\r
+VOID\r
+CIfrRecordInfoDB::IfrRecordOutput (\r
+  IN FILE   *File,\r
+  IN UINT32 LineNo\r
+  )\r
+{\r
+  SIfrRecord *pNode;\r
+  UINT8      Index;\r
+\r
+  if (mSwitch == FALSE) {\r
+    return;\r
+  }\r
+\r
+  if (File == NULL) {\r
+    return;\r
+  }\r
+\r
+  for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {\r
+    if (pNode->mLineNo == LineNo) {\r
+      fprintf (File, ">%08X: ", pNode->mOffset);\r
+      if (pNode->mIfrBinBuf != NULL) {\r
+        for (Index = 0; Index < pNode->mBinBufLen; Index++) {\r
+          fprintf (File, "%02X ", pNode->mIfrBinBuf[Index]);\r
+        }\r
+      }\r
+      fprintf (File, "\n");\r
+    }\r
+  }\r
+}\r
+\r
+CIfrRecordInfoDB gCIfrRecordInfoDB;\r
+\r
+VOID\r
+CIfrObj::_EMIT_PENDING_OBJ (\r
+  VOID\r
+  )\r
+{\r
+  CHAR8  *ObjBinBuf = NULL;\r
+\r
+  ObjBinBuf = gCFormPkg.IfrBinBufferGet (mObjBinLen);\r
+  if (ObjBinBuf != NULL) {\r
+    memcpy (ObjBinBuf, mObjBinBuf, mObjBinLen);\r
+  }\r
+\r
+  if (mObjBinBuf != NULL) {\r
+    delete mObjBinBuf;\r
+  }\r
+}\r
+\r
+/*\r
+ * The definition of CIfrObj's member function\r
+ */\r
+static struct {\r
+  UINT8  mSize;\r
+  UINT8  mScope;\r
+} gOpcodeSizesScopeTable[] = {\r
+  { 0, 0 },                                    // EFI_IFR_INVALID - 0x00\r
+  { sizeof (EFI_IFR_FORM), 1 },                // EFI_IFR_FORM_OP\r
+  { sizeof (EFI_IFR_SUBTITLE), 1 },            // EFI_IFR_SUBTITLE_OP\r
+  { sizeof (EFI_IFR_TEXT), 0 },                // EFI_IFR_TEXT_OP\r
+  { sizeof (EFI_IFR_IMAGE), 0 },               // EFI_IFR_IMAGE_OP\r
+  { sizeof (EFI_IFR_ONE_OF), 1 },              // EFI_IFR_ONE_OF_OP - 0x05\r
+  { sizeof (EFI_IFR_CHECKBOX), 1},             // EFI_IFR_CHECKBOX_OP\r
+  { sizeof (EFI_IFR_NUMERIC), 1 },             // EFI_IFR_NUMERIC_OP\r
+  { sizeof (EFI_IFR_PASSWORD), 1 },            // EFI_IFR_PASSWORD_OP\r
+  { sizeof (EFI_IFR_ONE_OF_OPTION), 0 },       // EFI_IFR_ONE_OF_OPTION_OP\r
+  { sizeof (EFI_IFR_SUPPRESS_IF), 1 },         // EFI_IFR_SUPPRESS_IF - 0x0A\r
+  { sizeof (EFI_IFR_LOCKED), 0 },              // EFI_IFR_LOCKED_OP\r
+  { sizeof (EFI_IFR_ACTION), 1 },              // EFI_IFR_ACTION_OP\r
+  { sizeof (EFI_IFR_RESET_BUTTON), 1 },        // EFI_IFR_RESET_BUTTON_OP\r
+  { sizeof (EFI_IFR_FORM_SET), 1 },            // EFI_IFR_FORM_SET_OP -0xE\r
+  { sizeof (EFI_IFR_REF), 0 },                 // EFI_IFR_REF_OP\r
+  { sizeof (EFI_IFR_NO_SUBMIT_IF), 1},         // EFI_IFR_NO_SUBMIT_IF_OP -0x10\r
+  { sizeof (EFI_IFR_INCONSISTENT_IF), 1 },     // EFI_IFR_INCONSISTENT_IF_OP\r
+  { sizeof (EFI_IFR_EQ_ID_VAL), 0 },           // EFI_IFR_EQ_ID_VAL_OP\r
+  { sizeof (EFI_IFR_EQ_ID_ID), 0 },            // EFI_IFR_EQ_ID_ID_OP\r
+  { sizeof (EFI_IFR_EQ_ID_LIST), 0 },          // EFI_IFR_EQ_ID_LIST_OP - 0x14\r
+  { sizeof (EFI_IFR_AND), 0 },                 // EFI_IFR_AND_OP\r
+  { sizeof (EFI_IFR_OR), 0 },                  // EFI_IFR_OR_OP\r
+  { sizeof (EFI_IFR_NOT), 0 },                 // EFI_IFR_NOT_OP\r
+  { sizeof (EFI_IFR_RULE), 1 },                // EFI_IFR_RULE_OP\r
+  { sizeof (EFI_IFR_GRAY_OUT_IF), 1 },         // EFI_IFR_GRAYOUT_IF_OP - 0x19\r
+  { sizeof (EFI_IFR_DATE), 1 },                // EFI_IFR_DATE_OP\r
+  { sizeof (EFI_IFR_TIME), 1 },                // EFI_IFR_TIME_OP\r
+  { sizeof (EFI_IFR_STRING), 1 },              // EFI_IFR_STRING_OP\r
+  { sizeof (EFI_IFR_REFRESH), 1 },             // EFI_IFR_REFRESH_OP\r
+  { sizeof (EFI_IFR_DISABLE_IF), 1 },          // EFI_IFR_DISABLE_IF_OP - 0x1E\r
+  { 0, 0 },                                    // 0x1F\r
+  { sizeof (EFI_IFR_TO_LOWER), 0 },            // EFI_IFR_TO_LOWER_OP - 0x20\r
+  { sizeof (EFI_IFR_TO_UPPER), 0 },            // EFI_IFR_TO_UPPER_OP - 0x21\r
+  { 0, 0 },                                    // 0x22\r
+  { sizeof (EFI_IFR_ORDERED_LIST), 1 },        // EFI_IFR_ORDERED_LIST_OP - 0x23\r
+  { sizeof (EFI_IFR_VARSTORE), 0 },            // EFI_IFR_VARSTORE_OP\r
+  { sizeof (EFI_IFR_VARSTORE_NAME_VALUE), 0 }, // EFI_IFR_VARSTORE_NAME_VALUE_OP\r
+  { sizeof (EFI_IFR_VARSTORE_EFI), 0 },        // EFI_IFR_VARSTORE_EFI_OP\r
+  { sizeof (EFI_IFR_VARSTORE_DEVICE), 1 },     // EFI_IFR_VARSTORE_DEVICE_OP\r
+  { sizeof (EFI_IFR_VERSION), 0 },             // EFI_IFR_VERSION_OP - 0x28\r
+  { sizeof (EFI_IFR_END), 0 },                 // EFI_IFR_END_OP\r
+  { sizeof (EFI_IFR_MATCH), 1 },               // EFI_IFR_MATCH_OP - 0x2A\r
+  { 0, 0 }, { 0, 0} , { 0, 0} , { 0, 0} ,      // 0x2B ~ 0x2E\r
+  { sizeof (EFI_IFR_EQUAL), 0 },               // EFI_IFR_EQUAL_OP - 0x2F\r
+  { sizeof (EFI_IFR_NOT_EQUAL), 0 },           // EFI_IFR_NOT_EQUAL_OP\r
+  { sizeof (EFI_IFR_GREATER_THAN), 0 },        // EFI_IFR_GREATER_THAN_OP\r
+  { sizeof (EFI_IFR_GREATER_EQUAL), 0 },       // EFI_IFR_GREATER_EQUAL_OP\r
+  { sizeof (EFI_IFR_LESS_THAN), 0 },           // EFI_IFR_LESS_THAN_OP\r
+  { sizeof (EFI_IFR_LESS_EQUAL), 0 },          // EFI_IFR_LESS_EQUAL_OP - 0x34\r
+  { sizeof (EFI_IFR_BITWISE_AND), 0 },         // EFI_IFR_BITWISE_AND_OP\r
+  { sizeof (EFI_IFR_BITWISE_OR), 0 },          // EFI_IFR_BITWISE_OR_OP\r
+  { sizeof (EFI_IFR_BITWISE_NOT), 0 },         // EFI_IFR_BITWISE_NOT_OP\r
+  { sizeof (EFI_IFR_SHIFT_LEFT), 0 },          // EFI_IFR_SHIFT_LEFT_OP\r
+  { sizeof (EFI_IFR_SHIFT_RIGHT), 0 },         // EFI_IFR_SHIFT_RIGHT_OP\r
+  { sizeof (EFI_IFR_ADD), 0 },                 // EFI_IFR_ADD_OP - 0x3A\r
+  { sizeof (EFI_IFR_SUBTRACT), 0 },            // EFI_IFR_SUBTRACT_OP\r
+  { sizeof (EFI_IFR_MULTIPLY), 0 },            // EFI_IFR_MULTIPLY_OP\r
+  { sizeof (EFI_IFR_DIVIDE), 0 },              // EFI_IFR_DIVIDE_OP\r
+  { sizeof (EFI_IFR_MODULO), 0 },              // EFI_IFR_MODULO_OP - 0x3E\r
+  { sizeof (EFI_IFR_RULE_REF), 0 },            // EFI_IFR_RULE_REF_OP\r
+  { sizeof (EFI_IFR_QUESTION_REF1), 0 },       // EFI_IFR_QUESTION_REF1_OP\r
+  { sizeof (EFI_IFR_QUESTION_REF2), 0 },       // EFI_IFR_QUESTION_REF2_OP - 0x41\r
+  { sizeof (EFI_IFR_UINT8), 0},                // EFI_IFR_UINT8\r
+  { sizeof (EFI_IFR_UINT16), 0},               // EFI_IFR_UINT16\r
+  { sizeof (EFI_IFR_UINT32), 0},               // EFI_IFR_UINT32\r
+  { sizeof (EFI_IFR_UINT64), 0},               // EFI_IFR_UTNT64\r
+  { sizeof (EFI_IFR_TRUE), 0 },                // EFI_IFR_TRUE_OP - 0x46\r
+  { sizeof (EFI_IFR_FALSE), 0 },               // EFI_IFR_FALSE_OP\r
+  { sizeof (EFI_IFR_TO_UINT), 0 },             // EFI_IFR_TO_UINT_OP\r
+  { sizeof (EFI_IFR_TO_STRING), 0 },           // EFI_IFR_TO_STRING_OP\r
+  { sizeof (EFI_IFR_TO_BOOLEAN), 0 },          // EFI_IFR_TO_BOOLEAN_OP\r
+  { sizeof (EFI_IFR_MID), 0 },                 // EFI_IFR_MID_OP\r
+  { sizeof (EFI_IFR_FIND), 0 },                // EFI_IFR_FIND_OP\r
+  { sizeof (EFI_IFR_TOKEN), 0 },               // EFI_IFR_TOKEN_OP\r
+  { sizeof (EFI_IFR_STRING_REF1), 0 },         // EFI_IFR_STRING_REF1_OP - 0x4E\r
+  { sizeof (EFI_IFR_STRING_REF2), 0 },         // EFI_IFR_STRING_REF2_OP\r
+  { sizeof (EFI_IFR_CONDITIONAL), 0 },         // EFI_IFR_CONDITIONAL_OP\r
+  { sizeof (EFI_IFR_QUESTION_REF3), 0 },       // EFI_IFR_QUESTION_REF3_OP\r
+  { sizeof (EFI_IFR_ZERO), 0 },                // EFI_IFR_ZERO_OP\r
+  { sizeof (EFI_IFR_ONE), 0 },                 // EFI_IFR_ONE_OP\r
+  { sizeof (EFI_IFR_ONES), 0 },                // EFI_IFR_ONES_OP\r
+  { sizeof (EFI_IFR_UNDEFINED), 0 },           // EFI_IFR_UNDEFINED_OP\r
+  { sizeof (EFI_IFR_LENGTH), 0 },              // EFI_IFR_LENGTH_OP\r
+  { sizeof (EFI_IFR_DUP), 0 },                 // EFI_IFR_DUP_OP - 0x57\r
+  { sizeof (EFI_IFR_THIS), 0 },                // EFI_IFR_THIS_OP\r
+  { sizeof (EFI_IFR_SPAN), 0 },                // EFI_IFR_SPAN_OP\r
+  { sizeof (EFI_IFR_VALUE), 1 },               // EFI_IFR_VALUE_OP\r
+  { sizeof (EFI_IFR_DEFAULT), 0 },             // EFI_IFR_DEFAULT_OP\r
+  { sizeof (EFI_IFR_DEFAULTSTORE), 0 },        // EFI_IFR_DEFAULTSTORE_OP - 0x5C\r
+  { 0, 0},                                     // 0x5D\r
+  { sizeof (EFI_IFR_CATENATE), 0 },            // EFI_IFR_CATENATE_OP\r
+  { sizeof (EFI_IFR_GUID), 0 },                // EFI_IFR_GUID_OP\r
+};\r
+\r
+#ifdef CIFROBJ_DEUBG\r
+static struct {\r
+  INT8 *mIfrName;\r
+} gIfrObjPrintDebugTable[] = {\r
+  "EFI_IFR_INVALID",    "EFI_IFR_FORM",                 "EFI_IFR_SUBTITLE",      "EFI_IFR_TEXT",            "EFI_IFR_IMAGE",         "EFI_IFR_ONE_OF",\r
+  "EFI_IFR_CHECKBOX",   "EFI_IFR_NUMERIC",              "EFI_IFR_PASSWORD",      "EFI_IFR_ONE_OF_OPTION",   "EFI_IFR_SUPPRESS_IF",   "EFI_IFR_LOCKED",\r
+  "EFI_IFR_ACTION",     "EFI_IFR_RESET_BUTTON",         "EFI_IFR_FORM_SET",      "EFI_IFR_REF",             "EFI_IFR_NO_SUBMIT_IF",  "EFI_IFR_INCONSISTENT_IF",\r
+  "EFI_IFR_EQ_ID_VAL",  "EFI_IFR_EQ_ID_ID",             "EFI_IFR_EQ_ID_LIST",    "EFI_IFR_AND",             "EFI_IFR_OR",            "EFI_IFR_NOT",\r
+  "EFI_IFR_RULE",       "EFI_IFR_GRAY_OUT_IF",          "EFI_IFR_DATE",          "EFI_IFR_TIME",            "EFI_IFR_STRING",        "EFI_IFR_REFRESH",\r
+  "EFI_IFR_DISABLE_IF", "EFI_IFR_INVALID",              "EFI_IFR_TO_LOWER",      "EFI_IFR_TO_UPPER",        "EFI_IFR_INVALID",       "EFI_IFR_ORDERED_LIST",\r
+  "EFI_IFR_VARSTORE",   "EFI_IFR_VARSTORE_NAME_VALUE",  "EFI_IFR_VARSTORE_EFI",  "EFI_IFR_VARSTORE_DEVICE", "EFI_IFR_VERSION",       "EFI_IFR_END",\r
+  "EFI_IFR_MATCH",      "EFI_IFR_INVALID",              "EFI_IFR_INVALID",       "EFI_IFR_INVALID",         "EFI_IFR_INVALID",       "EFI_IFR_EQUAL",\r
+  "EFI_IFR_NOT_EQUAL",  "EFI_IFR_GREATER_THAN",         "EFI_IFR_GREATER_EQUAL", "EFI_IFR_LESS_THAN",       "EFI_IFR_LESS_EQUAL",    "EFI_IFR_BITWISE_AND",\r
+  "EFI_IFR_BITWISE_OR", "EFI_IFR_BITWISE_NOT",          "EFI_IFR_SHIFT_LEFT",    "EFI_IFR_SHIFT_RIGHT",     "EFI_IFR_ADD",           "EFI_IFR_SUBTRACT",\r
+  "EFI_IFR_MULTIPLY",   "EFI_IFR_DIVIDE",               "EFI_IFR_MODULO",        "EFI_IFR_RULE_REF",        "EFI_IFR_QUESTION_REF1", "EFI_IFR_QUESTION_REF2",\r
+  "EFI_IFR_UINT8",      "EFI_IFR_UINT16",               "EFI_IFR_UINT32",        "EFI_IFR_UINT64",          "EFI_IFR_TRUE",          "EFI_IFR_FALSE",\r
+  "EFI_IFR_TO_UINT",    "EFI_IFR_TO_STRING",            "EFI_IFR_TO_BOOLEAN",    "EFI_IFR_MID",             "EFI_IFR_FIND",          "EFI_IFR_TOKEN",\r
+  "EFI_IFR_STRING_REF1","EFI_IFR_STRING_REF2",          "EFI_IFR_CONDITIONAL",   "EFI_IFR_QUESTION_REF3",   "EFI_IFR_ZERO",          "EFI_IFR_ONE",\r
+  "EFI_IFR_ONES",       "EFI_IFR_UNDEFINED",            "EFI_IFR_LENGTH",        "EFI_IFR_DUP",             "EFI_IFR_THIS",          "EFI_IFR_SPAN",\r
+  "EFI_IFR_VALUE",      "EFI_IFR_DEFAULT",              "EFI_IFR_DEFAULTSTORE",  "EFI_IFR_INVALID",         "EFI_IFR_CATENATE",      "EFI_IFR_GUID",\r
+};\r
+\r
+VOID\r
+CIFROBJ_DEBUG_PRINT (\r
+  IN UINT8 OpCode\r
+  )\r
+{\r
+  printf ("======Create IFR [%s]\n", gIfrObjPrintDebugTable[OpCode].mIfrName);\r
+}\r
+#else\r
+\r
+#define CIFROBJ_DEBUG_PRINT(OpCode)\r
+\r
+#endif\r
+\r
+bool gCreateOp = TRUE;\r
+\r
+CIfrObj::CIfrObj (\r
+  IN  UINT8   OpCode,\r
+  OUT CHAR8   **IfrObj,\r
+  IN  UINT8   ObjBinLen,\r
+  IN  BOOLEAN DelayEmit\r
+  )\r
+{\r
+  mDelayEmit   = DelayEmit;\r
+  mPkgOffset   = gCFormPkg.GetPkgLength ();\r
+  mObjBinLen   = (ObjBinLen == 0) ? gOpcodeSizesScopeTable[OpCode].mSize : ObjBinLen;\r
+  mObjBinBuf   = ((DelayEmit == FALSE) && (gCreateOp == TRUE)) ? gCFormPkg.IfrBinBufferGet (mObjBinLen) : new CHAR8[EFI_IFR_MAX_LENGTH];\r
+  mRecordIdx   = (gCreateOp == TRUE) ? gCIfrRecordInfoDB.IfrRecordRegister (0xFFFFFFFF, mObjBinBuf, mObjBinLen, mPkgOffset) : EFI_IFR_RECORDINFO_IDX_INVALUD;\r
+\r
+  if (IfrObj != NULL) {\r
+    *IfrObj    = mObjBinBuf;\r
+  }\r
+\r
+  CIFROBJ_DEBUG_PRINT (OpCode);\r
+}\r
+\r
+CIfrObj::~CIfrObj (\r
+  VOID\r
+  )\r
+{\r
+  if ((mDelayEmit == TRUE) && ((gCreateOp == TRUE))) {\r
+    _EMIT_PENDING_OBJ ();\r
+  }\r
+\r
+  gCIfrRecordInfoDB.IfrRecordInfoUpdate (mRecordIdx, mLineNo, mObjBinBuf, mObjBinLen, mPkgOffset);\r
+}\r
+\r
+/*\r
+ * The definition of CIfrObj's member function\r
+ */\r
+UINT8 gScopeCount = 0;\r
+\r
+CIfrOpHeader::CIfrOpHeader (\r
+  IN UINT8 OpCode, \r
+  IN VOID *StartAddr,\r
+  IN UINT8 Length \r
+  ) : mHeader ((EFI_IFR_OP_HEADER *)StartAddr) \r
+{\r
+  mHeader->OpCode = OpCode;\r
+  mHeader->Length = (Length == 0) ? gOpcodeSizesScopeTable[OpCode].mSize : Length;\r
+  mHeader->Scope  = (gOpcodeSizesScopeTable[OpCode].mScope + gScopeCount > 0) ? 1 : 0;\r
+}\r
+\r
+CIfrOpHeader::CIfrOpHeader (\r
+  IN CIfrOpHeader &OpHdr\r
+  )\r
+{\r
+  mHeader = OpHdr.mHeader;\r
+}\r
+\r
+UINT32 CIfrForm::FormIdBitMap[EFI_FREE_FORM_ID_BITMAP_SIZE] = {0, };\r
diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrFormPkg.h b/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrFormPkg.h
new file mode 100644 (file)
index 0000000..67afbdd
--- /dev/null
@@ -0,0 +1,2252 @@
+#ifndef _EFIIFRCLASS_H_\r
+#define _EFIIFRCLASS_H_\r
+\r
+#include "string.h"\r
+#include "EfiVfr.h"\r
+#include "VfrError.h"\r
+#include "VfrUtilityLib.h"\r
+\r
+/*\r
+ * The functions below are used for flags setting\r
+ */\r
+static inline BOOLEAN _FLAGS_ZERO (\r
+  IN UINT8 &Flags\r
+  )\r
+{\r
+  return Flags == 0;\r
+}\r
+\r
+static inline VOID _FLAG_CLEAR (\r
+  IN UINT8 &Flags,\r
+  IN UINT8 Mask\r
+  )\r
+{\r
+  Flags &= (~Mask);\r
+}\r
+\r
+static inline UINT8 _FLAG_TEST_AND_CLEAR (\r
+  IN UINT8 &Flags,\r
+  IN UINT8 Mask\r
+  )\r
+{\r
+  UINT8 Ret = Flags & Mask;\r
+  Flags &= (~Mask);\r
+  return Ret;\r
+}\r
+\r
+static inline UINT8 _IS_EQUAL (\r
+  IN UINT8 &Flags,\r
+  IN UINT8 Value\r
+  )\r
+{\r
+  return Flags == Value;\r
+}\r
+\r
+/*\r
+ * The definition of CIfrBin\r
+ */\r
+typedef enum {\r
+  PENDING,\r
+  ASSIGNED\r
+} ASSIGN_FLAG;\r
+\r
+struct SPendingAssign {\r
+  INT8                    *mKey;  // key ! unique\r
+  VOID                    *mAddr;\r
+  UINT32                  mLen;\r
+  ASSIGN_FLAG             mFlag;\r
+  UINT32                  mLineNo;\r
+  struct SPendingAssign   *mNext;\r
+\r
+  SPendingAssign (IN INT8 *, IN VOID *, IN UINT32, IN UINT32);\r
+  ~SPendingAssign ();\r
+\r
+  VOID   SetAddrAndLen (IN VOID *, IN UINT32);\r
+  VOID   AssignValue (IN VOID *, IN UINT32);\r
+  INT8 * GetKey (VOID);\r
+};\r
+\r
+struct SBufferNode {\r
+  CHAR8              *mBufferStart;\r
+  CHAR8              *mBufferEnd;\r
+  CHAR8              *mBufferFree;\r
+  struct SBufferNode *mNext;\r
+};\r
+\r
+class CFormPkg {\r
+private:\r
+  UINT32              mBufferSize;\r
+  SBufferNode         *mBufferNodeQueueHead;\r
+  SBufferNode         *mBufferNodeQueueTail;\r
+  SBufferNode         *mCurrBufferNode;\r
+\r
+  SBufferNode         *mReadBufferNode;\r
+  UINT32              mReadBufferOffset;\r
+\r
+  UINT32              mPkgLength;\r
+\r
+  VOID                _WRITE_PKG_LINE (IN FILE *, IN UINT32 , IN INT8 *, IN INT8 *, IN UINT32);\r
+  VOID                _WRITE_PKG_END (IN FILE *, IN UINT32 , IN INT8 *, IN INT8 *, IN UINT32);\r
+\r
+private:\r
+  SPendingAssign      *PendingAssignList;\r
+\r
+public:\r
+  CFormPkg (IN UINT32 BufferSize);\r
+  ~CFormPkg ();\r
+\r
+  CHAR8             * IfrBinBufferGet (IN UINT32);\r
+  inline UINT32       GetPkgLength (VOID);\r
+\r
+  VOID                Open ();\r
+  UINT32              Read (IN CHAR8 *, IN UINT32);\r
+  VOID                Close ();\r
+\r
+  EFI_VFR_RETURN_CODE BuildPkgHdr (OUT EFI_HII_PACKAGE_HEADER **);\r
+  EFI_VFR_RETURN_CODE BuildPkg (IN FILE *);\r
+  EFI_VFR_RETURN_CODE GenCFile (IN INT8 *, IN FILE *);\r
+\r
+public:\r
+  EFI_VFR_RETURN_CODE AssignPending (IN INT8 *, IN VOID *, IN UINT32, IN UINT32);\r
+  VOID                DoPendingAssign (IN INT8 *, IN VOID *, IN UINT32);\r
+  bool                HavePendingUnassigned (VOID);\r
+  VOID                PendingAssignPrintAll (VOID);\r
+};\r
+\r
+extern CFormPkg gCFormPkg;\r
+\r
+struct SIfrRecord {\r
+  UINT32     mLineNo;\r
+  CHAR8      *mIfrBinBuf;\r
+  UINT8      mBinBufLen;\r
+  UINT32     mOffset;\r
+  SIfrRecord *mNext;\r
+\r
+  SIfrRecord (VOID);\r
+  ~SIfrRecord (VOID);\r
+};\r
+\r
+#define EFI_IFR_RECORDINFO_IDX_INVALUD 0xFFFFFF\r
+#define EFI_IFR_RECORDINFO_IDX_START   0x0\r
+\r
+class CIfrRecordInfoDB {\r
+private:\r
+  bool       mSwitch;\r
+  UINT32     mRecordCount;\r
+  SIfrRecord *mIfrRecordListHead;\r
+  SIfrRecord *mIfrRecordListTail;\r
+\r
+  SIfrRecord * GetRecordInfoFromIdx (IN UINT32);\r
+public:\r
+  CIfrRecordInfoDB (VOID);\r
+  ~CIfrRecordInfoDB (VOID);\r
+\r
+  inline VOID TurnOn (VOID) {\r
+    mSwitch = TRUE;\r
+  }\r
+\r
+  inline VOID TurnOff (VOID) {\r
+    mSwitch = FALSE;\r
+  }\r
+\r
+  UINT32      IfrRecordRegister (IN UINT32, IN CHAR8 *, IN UINT8, IN UINT32);\r
+  VOID        IfrRecordInfoUpdate (IN UINT32, IN UINT32, IN CHAR8*, IN UINT8, IN UINT32);\r
+  VOID        IfrRecordOutput (IN FILE *, IN UINT32 LineNo);\r
+};\r
+\r
+extern CIfrRecordInfoDB gCIfrRecordInfoDB;\r
+\r
+/*\r
+ * The definition of CIfrObj\r
+ */\r
+extern bool  gCreateOp;\r
+\r
+class CIfrObj {\r
+private:\r
+  bool    mDelayEmit;\r
+\r
+  CHAR8   *mObjBinBuf;\r
+  UINT8   mObjBinLen;\r
+  UINT32  mLineNo;\r
+  UINT32  mRecordIdx;\r
+  UINT32  mPkgOffset;\r
+\r
+  VOID    _EMIT_PENDING_OBJ (VOID);\r
+\r
+public:\r
+  CIfrObj (IN UINT8 OpCode, OUT CHAR8 **IfrObj = NULL, IN UINT8 ObjBinLen = 0, IN BOOLEAN DelayEmit = FALSE);\r
+  virtual ~CIfrObj(VOID);\r
+\r
+  inline VOID    SetLineNo (IN UINT32 LineNo) {\r
+    mLineNo = LineNo;\r
+  }\r
+\r
+  inline CHAR8 * GetObjBinAddr (VOID) {\r
+    return mObjBinBuf;\r
+  }\r
+\r
+  inline UINT8   GetObjBinLen (VOID) {\r
+    return mObjBinLen;\r
+  }\r
+\r
+  inline bool ExpendObjBin (IN UINT8 Size) {\r
+    if ((mDelayEmit == TRUE) && ((mObjBinLen + Size) > mObjBinLen)) {\r
+      mObjBinLen += Size;\r
+      return TRUE;\r
+    } else {\r
+      return FALSE;\r
+    }\r
+  }\r
+};\r
+\r
+/*\r
+ * The definition of CIfrOpHeader\r
+ */\r
+class CIfrOpHeader {\r
+private:\r
+  EFI_IFR_OP_HEADER *mHeader;\r
+\r
+public:\r
+  CIfrOpHeader (IN UINT8 OpCode, IN VOID *StartAddr, IN UINT8 Length = 0);\r
+  CIfrOpHeader (IN CIfrOpHeader &);\r
+\r
+  VOID IncLength (UINT8 Size) {\r
+    if ((mHeader->Length + Size) > mHeader->Length) {\r
+      mHeader->Length += Size;\r
+    }\r
+  }\r
+\r
+  VOID DecLength (UINT8 Size) {\r
+    if (mHeader->Length >= Size) {\r
+         mHeader -= Size;\r
+    }\r
+  }\r
+\r
+  UINT8 GetLength () {\r
+    return mHeader->Length;\r
+  }\r
+\r
+  UINT8 GetScope () {\r
+    return mHeader->Scope;\r
+  }\r
+\r
+  VOID SetScope (IN UINT8 Scope) {\r
+    mHeader->Scope = Scope;\r
+  }\r
+};\r
+\r
+extern UINT8 gScopeCount;\r
+\r
+/*\r
+ * The definition of CIfrStatementHeader\r
+ */\r
+class CIfrStatementHeader {\r
+private:\r
+  EFI_IFR_STATEMENT_HEADER *mHeader;\r
+\r
+public:\r
+  CIfrStatementHeader (\r
+    IN EFI_IFR_STATEMENT_HEADER *StartAddr\r
+  ) : mHeader ((EFI_IFR_STATEMENT_HEADER *)StartAddr) {\r
+    mHeader         = StartAddr;\r
+    mHeader->Help   = EFI_STRING_ID_INVALID;\r
+    mHeader->Prompt = EFI_STRING_ID_INVALID;\r
+  }\r
+\r
+  EFI_IFR_STATEMENT_HEADER *GetStatementHeader () {\r
+    return mHeader;\r
+  }\r
+\r
+  VOID SetPrompt (IN EFI_STRING_ID Prompt) {\r
+    mHeader->Prompt = Prompt;\r
+  }\r
+\r
+  VOID SetHelp (IN EFI_STRING_ID Help) {\r
+    mHeader->Help = Help;\r
+  }\r
+};\r
+\r
+/*\r
+ * The definition of CIfrQuestionHeader\r
+ */\r
+#define EFI_IFR_QUESTION_FLAG_DEFAULT 0\r
+\r
+class CIfrQuestionHeader : public CIfrStatementHeader {\r
+private:\r
+  EFI_IFR_QUESTION_HEADER *mHeader;\r
+\r
+  EFI_IFR_STATEMENT_HEADER * QH2SH (EFI_IFR_QUESTION_HEADER *Qheader) {\r
+    return &(Qheader)->Header;\r
+  }\r
+\r
+public:\r
+  EFI_QUESTION_ID QUESTION_ID (VOID) {\r
+    return mHeader->QuestionId;\r
+  }\r
+\r
+  EFI_VARSTORE_ID VARSTORE_ID (VOID) {\r
+    return mHeader->VarStoreId;\r
+  }\r
+\r
+  VOID VARSTORE_INFO (OUT EFI_VARSTORE_INFO *Info) {\r
+    if (Info != NULL) {\r
+      Info->mVarStoreId   = mHeader->VarStoreId;\r
+      memcpy (&Info->mVarStoreId, &mHeader->VarStoreInfo, sizeof (Info->mVarStoreId));\r
+    }\r
+  }\r
+\r
+  UINT8 FLAGS (VOID) {\r
+    return mHeader->Flags;\r
+  }\r
+\r
+public:\r
+  CIfrQuestionHeader (\r
+    IN EFI_IFR_QUESTION_HEADER *StartAddr, \r
+    IN UINT8 Flags = EFI_IFR_QUESTION_FLAG_DEFAULT\r
+  ) : CIfrStatementHeader (QH2SH(StartAddr)) {\r
+    mHeader                         = StartAddr;\r
+    mHeader->QuestionId             = EFI_QUESTION_ID_INVALID;\r
+    mHeader->VarStoreId             = EFI_VARSTORE_ID_INVALID;\r
+    mHeader->VarStoreInfo.VarName   = EFI_STRING_ID_INVALID;\r
+    mHeader->VarStoreInfo.VarOffset = EFI_VAROFFSET_INVALID;\r
+    mHeader->Flags                  = Flags;\r
+  }\r
+\r
+  VOID SetQuestionId (IN EFI_QUESTION_ID QuestionId) {\r
+    mHeader->QuestionId = QuestionId;\r
+  }\r
+\r
+  VOID SetVarStoreInfo (IN EFI_VARSTORE_INFO *Info) {\r
+    mHeader->VarStoreId             = Info->mVarStoreId;\r
+       mHeader->VarStoreInfo.VarName   = Info->mInfo.mVarName;\r
+    mHeader->VarStoreInfo.VarOffset = Info->mInfo.mVarOffset;\r
+  }\r
+\r
+  EFI_VFR_RETURN_CODE SetFlags (IN UINT8 Flags) {\r
+    if (_FLAG_TEST_AND_CLEAR (Flags, EFI_IFR_FLAG_READ_ONLY)) {\r
+      mHeader->Flags |= EFI_IFR_FLAG_READ_ONLY;\r
+    }\r
+\r
+    _FLAG_CLEAR (Flags, 0x02);\r
+\r
+    if (_FLAG_TEST_AND_CLEAR (Flags, EFI_IFR_FLAG_CALLBACK)) {\r
+      mHeader->Flags |= EFI_IFR_FLAG_CALLBACK;\r
+    }\r
+\r
+    _FLAG_CLEAR (Flags, 0x08);\r
+\r
+    if (_FLAG_TEST_AND_CLEAR (Flags, EFI_IFR_FLAG_RESET_REQUIRED)) {\r
+      mHeader->Flags |= EFI_IFR_FLAG_RESET_REQUIRED;\r
+    }\r
+\r
+    _FLAG_CLEAR (Flags, 0x20);\r
+\r
+    if (_FLAG_TEST_AND_CLEAR (Flags, EFI_IFR_FLAG_OPTIONS_ONLY)) {\r
+      mHeader->Flags |= EFI_IFR_FLAG_OPTIONS_ONLY;\r
+    }\r
+\r
+    return _FLAGS_ZERO (Flags) ? VFR_RETURN_SUCCESS : VFR_RETURN_FLAGS_UNSUPPORTED;\r
+  }\r
+};\r
+\r
+static CIfrQuestionHeader *gCurrentQuestion = NULL;\r
+\r
+/*\r
+ * The definition of CIfrMinMaxStepData\r
+ */\r
+class CIfrMinMaxStepData {\r
+private:\r
+  MINMAXSTEP_DATA *mMinMaxStepData;\r
+\r
+public:\r
+  CIfrMinMaxStepData (MINMAXSTEP_DATA *DataAddr) : mMinMaxStepData (DataAddr) {\r
+    mMinMaxStepData->u64.MinValue = 0;\r
+    mMinMaxStepData->u64.MaxValue = 0;\r
+    mMinMaxStepData->u64.Step     = 0;\r
+  }\r
+\r
+  VOID SetMinMaxStepData (IN UINT64 MinValue, IN UINT64 MaxValue, IN UINT64 Step) {\r
+    mMinMaxStepData->u64.MinValue = MinValue;\r
+    mMinMaxStepData->u64.MaxValue = MaxValue;\r
+    mMinMaxStepData->u64.Step     = Step;\r
+  }\r
+\r
+  VOID SetMinMaxStepData (IN UINT32 MinValue, IN UINT32 MaxValue, IN UINT32 Step) {\r
+    mMinMaxStepData->u32.MinValue = MinValue;\r
+    mMinMaxStepData->u32.MaxValue = MaxValue;\r
+    mMinMaxStepData->u32.Step     = Step;\r
+  }\r
+\r
+  VOID SetMinMaxStepData (IN UINT16 MinValue, IN UINT16 MaxValue, IN UINT16 Step) {\r
+    mMinMaxStepData->u16.MinValue = MinValue;\r
+    mMinMaxStepData->u16.MaxValue = MaxValue;\r
+    mMinMaxStepData->u16.Step     = Step;\r
+  }\r
+\r
+  VOID SetMinMaxStepData (IN UINT8 MinValue, IN UINT8 MaxValue, IN UINT8 Step) {\r
+    mMinMaxStepData->u8.MinValue = MinValue;\r
+    mMinMaxStepData->u8.MaxValue = MaxValue;\r
+    mMinMaxStepData->u8.Step     = Step;\r
+  }\r
+\r
+};\r
+\r
+/*\r
+ * The definition of all of the UEFI IFR Objects\r
+ */\r
+class CIfrFormSet : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_FORM_SET *mFormSet;\r
+\r
+public:\r
+  CIfrFormSet () : CIfrObj (EFI_IFR_FORM_SET_OP, (CHAR8 **)&mFormSet),\r
+                   CIfrOpHeader (EFI_IFR_FORM_SET_OP, &mFormSet->Header) {\r
+    mFormSet->Help         = EFI_STRING_ID_INVALID;\r
+    mFormSet->FormSetTitle = EFI_STRING_ID_INVALID;\r
+    memset (&mFormSet->Guid, 0, sizeof (EFI_GUID));\r
+  }\r
+\r
+  VOID SetGuid (IN EFI_GUID *Guid) {\r
+    memcpy (&mFormSet->Guid, Guid, sizeof (EFI_GUID));\r
+  }\r
+\r
+  VOID SetFormSetTitle (IN EFI_STRING_ID FormSetTitle) {\r
+    mFormSet->FormSetTitle = FormSetTitle;\r
+  }\r
+\r
+  VOID SetHelp (IN EFI_STRING_ID Help) {\r
+    mFormSet->Help = Help;\r
+  }\r
+};\r
+\r
+class CIfrEnd : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_END  *mEnd;\r
+\r
+public:\r
+  CIfrEnd () : CIfrObj (EFI_IFR_END_OP, (CHAR8 **)&mEnd),\r
+               CIfrOpHeader (EFI_IFR_END_OP, &mEnd->Header) {}\r
+};\r
+\r
+class CIfrDefaultStore : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_DEFAULTSTORE *mDefaultStore;\r
+\r
+public:\r
+  CIfrDefaultStore () : CIfrObj (EFI_IFR_DEFAULTSTORE_OP, (CHAR8 **)&mDefaultStore),\r
+                       CIfrOpHeader (EFI_IFR_DEFAULTSTORE_OP, &mDefaultStore->Header) {\r
+    mDefaultStore->DefaultId   = EFI_VARSTORE_ID_INVALID;\r
+    mDefaultStore->DefaultName = EFI_STRING_ID_INVALID;\r
+  }\r
+\r
+  VOID SetDefaultName (IN EFI_STRING_ID DefaultName) {\r
+    mDefaultStore->DefaultName = DefaultName;\r
+  }\r
+\r
+  VOID SetDefaultId (IN UINT16 DefaultId) {\r
+    mDefaultStore->DefaultId = DefaultId;\r
+  }\r
+};\r
+\r
+#define EFI_FORM_ID_MAX                    0xFFFF\r
+#define EFI_FREE_FORM_ID_BITMAP_SIZE     ((EFI_FORM_ID_MAX + 1) / EFI_BITS_PER_UINT32)\r
+\r
+class CIfrForm : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_FORM  *mForm;\r
+\r
+  STATIC UINT32 FormIdBitMap[EFI_FREE_FORM_ID_BITMAP_SIZE];\r
+\r
+  STATIC BOOLEAN ChekFormIdFree (IN EFI_FORM_ID FormId) {\r
+    UINT32 Index  = (FormId / EFI_BITS_PER_UINT32);\r
+    UINT32 Offset = (FormId % EFI_BITS_PER_UINT32);\r
+\r
+    return (FormIdBitMap[Index] & (0x80000000 >> Offset)) == 0;\r
+  }\r
+\r
+  STATIC VOID MarkFormIdUsed (IN EFI_FORM_ID FormId) {\r
+    UINT32 Index  = (FormId / EFI_BITS_PER_UINT32);\r
+    UINT32 Offset = (FormId % EFI_BITS_PER_UINT32);\r
+\r
+    FormIdBitMap[Index] |= (0x80000000 >> Offset);\r
+  }\r
+\r
+public:\r
+  CIfrForm () : CIfrObj (EFI_IFR_FORM_OP, (CHAR8 **)&mForm), \r
+                CIfrOpHeader (EFI_IFR_FORM_OP, &mForm->Header) {\r
+    mForm->FormId    = 0;\r
+    mForm->FormTitle = EFI_STRING_ID_INVALID;\r
+  }\r
+\r
+  EFI_VFR_RETURN_CODE SetFormId (IN EFI_FORM_ID FormId) {\r
+    if (CIfrForm::ChekFormIdFree (FormId) == FALSE) {\r
+      return VFR_RETURN_FORMID_REDEFINED;\r
+    }\r
+    mForm->FormId = FormId;\r
+    CIfrForm::MarkFormIdUsed (FormId);\r
+    return VFR_RETURN_SUCCESS;\r
+  }\r
+\r
+  VOID SetFormTitle (IN EFI_STRING_ID FormTitle) {\r
+    mForm->FormTitle = FormTitle;\r
+  }\r
+};\r
+\r
+class CIfrVarStore : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_VARSTORE *mVarStore;\r
+\r
+public:\r
+  CIfrVarStore () : CIfrObj (EFI_IFR_VARSTORE_OP, (CHAR8 **)&mVarStore, sizeof (EFI_IFR_VARSTORE), TRUE), \r
+                   CIfrOpHeader (EFI_IFR_VARSTORE_OP, &mVarStore->Header) {\r
+    mVarStore->VarStoreId = EFI_VARSTORE_ID_INVALID;\r
+    mVarStore->Size       = 0;\r
+    memset (&mVarStore->Guid, 0, sizeof (EFI_GUID));\r
+    mVarStore->Name[0]    = '\0';\r
+  }\r
+\r
+  VOID SetGuid (IN EFI_GUID *Guid) {\r
+    memcpy (&mVarStore->Guid, Guid, sizeof (EFI_GUID));\r
+  }\r
+\r
+  VOID SetVarStoreId (IN EFI_VARSTORE_ID VarStoreId) {\r
+    mVarStore->VarStoreId = VarStoreId;\r
+  }\r
+\r
+  VOID SetSize (IN UINT16 Size) {\r
+    mVarStore->Size = Size;\r
+  }\r
+\r
+  VOID SetName (IN INT8 *Name) {\r
+    UINT8 Len;\r
+\r
+    if (Name != NULL) {\r
+      Len = strlen (Name);\r
+      if (Len != 0) {\r
+        if (ExpendObjBin (Len) == TRUE) {\r
+          IncLength (Len);\r
+          strcpy ((INT8 *)(mVarStore->Name), Name);\r
+        }\r
+      }\r
+    }\r
+  }\r
+};\r
+\r
+class CIfrVarStoreEfi : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_VARSTORE_EFI *mVarStoreEfi;\r
+\r
+public:\r
+  CIfrVarStoreEfi () : CIfrObj (EFI_IFR_VARSTORE_EFI_OP, (CHAR8 **)&mVarStoreEfi), \r
+                      CIfrOpHeader (EFI_IFR_VARSTORE_EFI_OP, &mVarStoreEfi->Header) {\r
+    mVarStoreEfi->VarStoreId = EFI_VAROFFSET_INVALID;\r
+    memset (&mVarStoreEfi->Guid, 0, sizeof (EFI_GUID));\r
+  }\r
+\r
+  VOID SetGuid (IN EFI_GUID *Guid) {\r
+    memcpy (&mVarStoreEfi->Guid, Guid, sizeof (EFI_GUID));\r
+  }\r
+\r
+  VOID SetVarStoreId (IN UINT16 VarStoreId) {\r
+    mVarStoreEfi->VarStoreId = VarStoreId;\r
+  }\r
+\r
+  VOID SetAttributes (IN UINT32 Attributes) {\r
+    mVarStoreEfi->Attributes = Attributes;\r
+  }\r
+};\r
+\r
+class CIfrVarStoreNameValue : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_VARSTORE_NAME_VALUE *mVarStoreNameValue;\r
+\r
+public:\r
+  CIfrVarStoreNameValue () : CIfrObj (EFI_IFR_VARSTORE_NAME_VALUE_OP, (CHAR8 **)&mVarStoreNameValue), \r
+                              CIfrOpHeader (EFI_IFR_VARSTORE_NAME_VALUE_OP, &mVarStoreNameValue->Header) {\r
+    mVarStoreNameValue->VarStoreId = EFI_VAROFFSET_INVALID;\r
+    memset (&mVarStoreNameValue->Guid, 0, sizeof (EFI_GUID));\r
+  }\r
+\r
+  VOID SetGuid (IN EFI_GUID *Guid) {\r
+    memcpy (&mVarStoreNameValue->Guid, Guid, sizeof (EFI_GUID));\r
+  }\r
+\r
+  VOID SetVarStoreId (IN UINT16 VarStoreId) {\r
+    mVarStoreNameValue->VarStoreId = VarStoreId;\r
+  }\r
+};\r
+\r
+class CIfrImage : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_IMAGE *mImage;\r
+\r
+public:\r
+  CIfrImage () : CIfrObj (EFI_IFR_IMAGE_OP, (CHAR8 **)&mImage),\r
+                 CIfrOpHeader (EFI_IFR_FORM_OP, &mImage->Header) {\r
+    mImage->Id = EFI_IMAGE_ID_INVALID;\r
+  }\r
+\r
+  VOID SetImageId (IN EFI_IMAGE_ID ImageId) {\r
+    mImage->Id = ImageId;\r
+  }\r
+};\r
+\r
+class CIfrLocked : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_LOCKED *mLocked;\r
+\r
+public:\r
+  CIfrLocked () : CIfrObj (EFI_IFR_LOCKED_OP, (CHAR8 **)&mLocked),\r
+                  CIfrOpHeader (EFI_IFR_LOCKED_OP, &mLocked->Header) {}\r
+};\r
+\r
+class CIfrRule : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_RULE *mRule;\r
+\r
+public:\r
+  CIfrRule () : CIfrObj (EFI_IFR_RULE_OP, (CHAR8 **)&mRule),\r
+                mRule ((EFI_IFR_RULE *)GetObjBinAddr()),\r
+                CIfrOpHeader (EFI_IFR_RULE_OP, &mRule->Header) {\r
+    mRule->RuleId = EFI_RULE_ID_INVALID;\r
+  }\r
+\r
+  VOID SetRuleId (IN UINT8 RuleId) {\r
+    mRule->RuleId = RuleId;\r
+  }\r
+};\r
+\r
+static EFI_IFR_TYPE_VALUE gZeroEfiIfrTypeValue = {0, };\r
+\r
+class CIfrDefault : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_DEFAULT *mDefault;\r
+\r
+public:\r
+  CIfrDefault (\r
+    IN UINT16             DefaultId = EFI_HII_DEFAULT_CLASS_STANDARD,\r
+    IN UINT8              Type      = EFI_IFR_TYPE_OTHER,\r
+    IN EFI_IFR_TYPE_VALUE Value     = gZeroEfiIfrTypeValue\r
+    ) : CIfrObj (EFI_IFR_DEFAULT_OP, (CHAR8 **)&mDefault),\r
+        CIfrOpHeader (EFI_IFR_DEFAULT_OP, &mDefault->Header) {\r
+    mDefault->Type      = Type;\r
+       mDefault->Value     = Value;\r
+    mDefault->DefaultId = DefaultId;\r
+  }\r
+\r
+  VOID SetDefaultId (IN UINT16 DefaultId) {\r
+    mDefault->DefaultId = DefaultId;\r
+  }\r
+\r
+  VOID SetType (IN UINT8 Type) {\r
+    mDefault->Type = Type;\r
+  }\r
+\r
+  VOID SetValue (IN EFI_IFR_TYPE_VALUE Value) {\r
+    mDefault->Value = Value;\r
+  }\r
+};\r
+\r
+class CIfrValue : public CIfrObj, public CIfrOpHeader{\r
+private:\r
+  EFI_IFR_VALUE *mValue;\r
+\r
+public:\r
+  CIfrValue () : CIfrObj (EFI_IFR_VALUE_OP, (CHAR8 **)&mValue),\r
+                CIfrOpHeader (EFI_IFR_VALUE_OP, &mValue->Header) {}\r
+\r
+};\r
+\r
+class CIfrSubtitle : public CIfrObj, public CIfrOpHeader, public CIfrStatementHeader {\r
+private:\r
+  EFI_IFR_SUBTITLE   *mSubtitle;\r
+\r
+public:\r
+  CIfrSubtitle () : CIfrObj (EFI_IFR_SUBTITLE_OP, (CHAR8 **)&mSubtitle),\r
+                  CIfrOpHeader (EFI_IFR_SUBTITLE_OP, &mSubtitle->Header),\r
+                                 CIfrStatementHeader (&mSubtitle->Statement) {\r
+    mSubtitle->Flags = 0;\r
+  }\r
+\r
+  EFI_VFR_RETURN_CODE SetFlags (IN UINT8 LFlags) {\r
+    if (_FLAG_TEST_AND_CLEAR (LFlags, EFI_IFR_FLAGS_HORIZONTAL)) {\r
+      mSubtitle->Flags |= EFI_IFR_FLAGS_HORIZONTAL;\r
+    }\r
+\r
+    return _FLAGS_ZERO (LFlags) ? VFR_RETURN_SUCCESS : VFR_RETURN_FLAGS_UNSUPPORTED;\r
+  }\r
+};\r
+\r
+class CIfrText : public CIfrObj, public CIfrOpHeader, public CIfrStatementHeader {\r
+private:\r
+  EFI_IFR_TEXT *mText;\r
+\r
+public:\r
+  CIfrText () : CIfrObj (EFI_IFR_TEXT_OP, (CHAR8 **)&mText),\r
+               CIfrOpHeader (EFI_IFR_TEXT_OP, &mText->Header), \r
+               CIfrStatementHeader (&mText->Statement) {\r
+    mText->TextTwo = EFI_STRING_ID_INVALID;\r
+  }\r
+\r
+  VOID SetTextTwo (IN EFI_STRING_ID StringId) {\r
+    mText->TextTwo = StringId;\r
+  }\r
+};\r
+\r
+class CIfrRef : public CIfrObj, public CIfrOpHeader, public CIfrQuestionHeader {\r
+private:\r
+  EFI_IFR_REF *mRef;\r
+\r
+public:\r
+  CIfrRef () : CIfrObj (EFI_IFR_REF_OP, (CHAR8 **)&mRef),\r
+              CIfrOpHeader (EFI_IFR_REF_OP, &mRef->Header), \r
+              CIfrQuestionHeader (&mRef->Question) {\r
+    mRef->FormId = 0;\r
+  }\r
+\r
+  VOID SetFormId (IN EFI_FORM_ID FormId) {\r
+    mRef->FormId = FormId;\r
+  }\r
+};\r
+\r
+class CIfrRef2 : public CIfrObj, public CIfrOpHeader, public CIfrQuestionHeader {\r
+private:\r
+  EFI_IFR_REF2 *mRef2;\r
+\r
+public:\r
+  CIfrRef2 () : CIfrObj (EFI_IFR_REF_OP, (CHAR8 **)&mRef2, sizeof (EFI_IFR_REF2)),\r
+               CIfrOpHeader (EFI_IFR_REF_OP, &mRef2->Header, sizeof (EFI_IFR_REF2)), \r
+               CIfrQuestionHeader (&mRef2->Question) {\r
+    mRef2->FormId     = 0;\r
+    mRef2->QuestionId = EFI_QUESTION_ID_INVALID;\r
+  }\r
+\r
+  VOID SetFormId (IN EFI_FORM_ID FormId) {\r
+    mRef2->FormId = FormId;\r
+  }\r
+\r
+  EFI_VFR_RETURN_CODE SetQuestionId (IN EFI_QUESTION_ID QuestionId) {\r
+    if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
+      return VFR_RETURN_UNDEFINED;\r
+    }\r
+    mRef2->QuestionId = QuestionId;\r
+    return VFR_RETURN_SUCCESS;\r
+  }\r
+};\r
+\r
+class CIfrRef3 : public CIfrObj, public CIfrOpHeader, public CIfrQuestionHeader {\r
+private:\r
+  EFI_IFR_REF3 *mRef3;\r
+\r
+public:\r
+  CIfrRef3 () : CIfrObj (EFI_IFR_REF_OP, (CHAR8 **)&mRef3, sizeof(EFI_IFR_REF3)),\r
+               CIfrOpHeader (EFI_IFR_REF_OP, &mRef3->Header, sizeof (EFI_IFR_REF3)), \r
+               CIfrQuestionHeader (&mRef3->Question) {\r
+    mRef3->FormId     = 0;\r
+    mRef3->QuestionId = EFI_QUESTION_ID_INVALID;\r
+    memset (&mRef3->FormSetId, 0, sizeof (EFI_GUID));\r
+  }\r
+\r
+  VOID SetFormId (IN EFI_FORM_ID FormId) {\r
+    mRef3->FormId = FormId;\r
+  }\r
+\r
+  VOID SetQuestionId (IN EFI_QUESTION_ID QuestionId) {\r
+    mRef3->QuestionId = QuestionId;\r
+  }\r
+\r
+  VOID SetFormSetId (IN EFI_GUID FormSetId) {\r
+    mRef3->FormSetId = FormSetId;\r
+  }\r
+};\r
+\r
+class CIfrRef4 : public CIfrObj, public CIfrOpHeader, public CIfrQuestionHeader {\r
+private:\r
+  EFI_IFR_REF4 *mRef4;\r
+\r
+public:\r
+  CIfrRef4 () : CIfrObj (EFI_IFR_REF_OP, (CHAR8 **)&mRef4, sizeof(EFI_IFR_REF3)),\r
+               CIfrOpHeader (EFI_IFR_REF_OP, &mRef4->Header, sizeof (EFI_IFR_REF3)), \r
+               CIfrQuestionHeader (&mRef4->Question) {\r
+    mRef4->FormId     = 0;\r
+    mRef4->QuestionId = EFI_QUESTION_ID_INVALID;\r
+    memset (&mRef4->FormSetId, 0, sizeof (EFI_GUID));\r
+    mRef4->DevicePath = EFI_STRING_ID_INVALID;\r
+  }\r
+\r
+  VOID SetFormId (IN EFI_FORM_ID FormId) {\r
+    mRef4->FormId = FormId;\r
+  }\r
+\r
+  VOID SetQuestionId (IN EFI_QUESTION_ID QuestionId) {\r
+    mRef4->QuestionId = QuestionId;\r
+  }\r
+\r
+  VOID SetFormSetId (IN EFI_GUID FormSetId) {\r
+    mRef4->FormSetId = FormSetId;\r
+  }\r
+\r
+  VOID SetDevicePath (IN EFI_STRING_ID DevicePath) {\r
+    mRef4->DevicePath = DevicePath;\r
+  }\r
+};\r
+\r
+class CIfrResetButton : public CIfrObj, public CIfrOpHeader, public CIfrStatementHeader {\r
+private:\r
+  EFI_IFR_RESET_BUTTON *mResetButton;\r
+\r
+public:\r
+  CIfrResetButton () : CIfrObj (EFI_IFR_RESET_BUTTON_OP, (CHAR8 **)&mResetButton),\r
+                       CIfrOpHeader (EFI_IFR_RESET_BUTTON_OP, &mResetButton->Header), \r
+                                          CIfrStatementHeader (&mResetButton->Question.Header) {\r
+    mResetButton->DefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;\r
+  }\r
+\r
+  VOID SetDefaultId (IN UINT16 DefaultId) {\r
+    mResetButton->DefaultId = DefaultId;\r
+  }\r
+};\r
+\r
+class CIfrCheckBox : public CIfrObj, public CIfrOpHeader, public CIfrQuestionHeader  {\r
+private:\r
+  EFI_IFR_CHECKBOX *mCheckBox;\r
+\r
+public:\r
+  CIfrCheckBox () : CIfrObj (EFI_IFR_CHECKBOX_OP, (CHAR8 **)&mCheckBox),\r
+                     CIfrOpHeader (EFI_IFR_CHECKBOX_OP, &mCheckBox->Header), \r
+                     CIfrQuestionHeader (&mCheckBox->Question) {\r
+    mCheckBox->Flags = EFI_IFR_CHECKBOX_DEFAULT;\r
+    gCurrentQuestion = this;\r
+  }\r
+\r
+  ~CIfrCheckBox () {\r
+    gCurrentQuestion = NULL;\r
+  }\r
+\r
+  EFI_VFR_RETURN_CODE SetFlags (IN UINT8 HFlags, UINT8 LFlags) {\r
+    EFI_VFR_RETURN_CODE Ret;\r
+\r
+    Ret = CIfrQuestionHeader::SetFlags (HFlags);\r
+    if (Ret != VFR_RETURN_SUCCESS) {\r
+      return Ret;\r
+    }\r
+\r
+    if (_FLAG_TEST_AND_CLEAR (LFlags, EFI_IFR_CHECKBOX_DEFAULT)) {\r
+      mCheckBox->Flags |= EFI_IFR_CHECKBOX_DEFAULT;\r
+    }\r
+\r
+    if (_FLAG_TEST_AND_CLEAR (LFlags, EFI_IFR_CHECKBOX_DEFAULT_MFG)) {\r
+      mCheckBox->Flags |= EFI_IFR_CHECKBOX_DEFAULT_MFG;\r
+    }\r
+\r
+    return _FLAGS_ZERO (LFlags) ? VFR_RETURN_SUCCESS : VFR_RETURN_FLAGS_UNSUPPORTED;\r
+  }\r
+};\r
+\r
+class CIfrAction : public CIfrObj, public CIfrOpHeader, public CIfrQuestionHeader {\r
+private:\r
+  EFI_IFR_ACTION *mAction;\r
+\r
+public:\r
+  CIfrAction () : CIfrObj (EFI_IFR_ACTION_OP, (CHAR8 **)&mAction),\r
+                 CIfrOpHeader (EFI_IFR_ACTION_OP, &mAction->Header), \r
+                 CIfrQuestionHeader (&mAction->Question) {\r
+    mAction->QuestionConfig = EFI_STRING_ID_INVALID;\r
+  }\r
+\r
+  VOID SetQuestionConfig (IN EFI_STRING_ID QuestionConfig) {\r
+    mAction->QuestionConfig = QuestionConfig;\r
+  }\r
+};\r
+\r
+class CIfrDate : public CIfrObj, public CIfrOpHeader, public CIfrQuestionHeader {\r
+private:\r
+  EFI_IFR_DATE *mDate;\r
+\r
+public:\r
+  CIfrDate () : CIfrObj (EFI_IFR_DATE_OP, (CHAR8 **)&mDate),\r
+               CIfrOpHeader (EFI_IFR_DATE_OP, &mDate->Header),\r
+               CIfrQuestionHeader (&mDate->Question) {\r
+    mDate->Flags = 0;\r
+  }\r
+\r
+  EFI_VFR_RETURN_CODE SetFlags (IN UINT8 HFlags, IN UINT8 LFlags) {\r
+    EFI_VFR_RETURN_CODE Ret;\r
+\r
+    Ret = CIfrQuestionHeader::SetFlags (HFlags);\r
+    if (Ret != VFR_RETURN_SUCCESS) {\r
+      return Ret;\r
+    }\r
+\r
+    if (_FLAG_TEST_AND_CLEAR (LFlags, EFI_QF_DATE_YEAR_SUPPRESS)) {\r
+      mDate->Flags |= EFI_QF_DATE_YEAR_SUPPRESS;\r
+    }\r
+\r
+    if (_FLAG_TEST_AND_CLEAR (LFlags, EFI_QF_DATE_MONTH_SUPPRESS)) {\r
+      mDate->Flags |= EFI_QF_DATE_MONTH_SUPPRESS;\r
+    }\r
+\r
+    if (_FLAG_TEST_AND_CLEAR (LFlags, EFI_QF_DATE_DAY_SUPPRESS)) {\r
+      mDate->Flags |= EFI_QF_DATE_DAY_SUPPRESS;\r
+    }\r
+\r
+    if (_FLAG_TEST_AND_CLEAR (LFlags, QF_DATE_STORAGE_NORMAL)) {\r
+      mDate->Flags |= QF_DATE_STORAGE_NORMAL;\r
+    } else if (_FLAG_TEST_AND_CLEAR (LFlags, QF_DATE_STORAGE_TIME)) {\r
+      mDate->Flags |= QF_DATE_STORAGE_TIME;\r
+    } else if (_FLAG_TEST_AND_CLEAR (LFlags, QF_DATE_STORAGE_WAKEUP)) {\r
+      mDate->Flags |= QF_DATE_STORAGE_WAKEUP;\r
+    }\r
+\r
+    return _FLAGS_ZERO (LFlags) ? VFR_RETURN_SUCCESS : VFR_RETURN_FLAGS_UNSUPPORTED;\r
+  }\r
+};\r
+\r
+class CIfrNumeric : public CIfrObj, public CIfrOpHeader, public CIfrQuestionHeader, public CIfrMinMaxStepData {\r
+private:\r
+  EFI_IFR_NUMERIC *mNumeric;\r
+\r
+public:\r
+  CIfrNumeric () : CIfrObj (EFI_IFR_NUMERIC_OP, (CHAR8 **)&mNumeric),\r
+                   CIfrOpHeader (EFI_IFR_NUMERIC_OP, &mNumeric->Header),\r
+                   CIfrQuestionHeader (&mNumeric->Question),\r
+                   CIfrMinMaxStepData (&mNumeric->data) {\r
+    mNumeric->Flags  = EFI_IFR_NUMERIC_SIZE_1 | EFI_IFR_DISPLAY_UINT_DEC;\r
+    gCurrentQuestion = this;\r
+  }\r
+\r
+  ~CIfrNumeric () {\r
+    gCurrentQuestion = NULL;\r
+  }\r
+\r
+  EFI_VFR_RETURN_CODE SetFlags (IN UINT8 HFlags, IN UINT8 LFlags) {\r
+    EFI_VFR_RETURN_CODE Ret;\r
+\r
+    Ret = CIfrQuestionHeader::SetFlags (HFlags);\r
+    if (Ret != VFR_RETURN_SUCCESS) {\r
+      return Ret;\r
+    }\r
+\r
+    if (LFlags & EFI_IFR_DISPLAY) {\r
+      mNumeric->Flags = LFlags;\r
+    } else {\r
+      mNumeric->Flags = LFlags | EFI_IFR_DISPLAY_UINT_DEC;\r
+    }\r
+    return VFR_RETURN_SUCCESS;\r
+  }\r
+};\r
+\r
+class CIfrOneOf : public CIfrObj, public CIfrOpHeader, public CIfrQuestionHeader, public CIfrMinMaxStepData {\r
+private:\r
+  EFI_IFR_ONE_OF *mOneOf;\r
+\r
+public:\r
+  CIfrOneOf () : CIfrObj (EFI_IFR_ONE_OF_OP, (CHAR8 **)&mOneOf),\r
+                 CIfrOpHeader (EFI_IFR_ONE_OF_OP, &mOneOf->Header),\r
+                 CIfrQuestionHeader (&mOneOf->Question),\r
+                 CIfrMinMaxStepData (&mOneOf->data) {\r
+    mOneOf->Flags    = 0;\r
+    gCurrentQuestion = this;\r
+  }\r
+\r
+  ~CIfrOneOf () {\r
+    gCurrentQuestion = NULL;\r
+  }\r
+\r
+  EFI_VFR_RETURN_CODE SetFlags (IN UINT8 HFlags, IN UINT8 LFlags) {\r
+    EFI_VFR_RETURN_CODE Ret;\r
+\r
+    Ret = CIfrQuestionHeader::SetFlags (HFlags);\r
+    if (Ret != VFR_RETURN_SUCCESS) {\r
+      return Ret;\r
+    }\r
+\r
+    if (LFlags & EFI_IFR_DISPLAY) {\r
+      mOneOf->Flags = LFlags;\r
+    } else {\r
+      mOneOf->Flags = LFlags | EFI_IFR_DISPLAY_UINT_DEC;\r
+    }\r
+    return VFR_RETURN_SUCCESS;\r
+  }\r
+};\r
+\r
+class CIfrString : public CIfrObj, public CIfrOpHeader, public CIfrQuestionHeader {\r
+private:\r
+  EFI_IFR_STRING *mString;\r
+\r
+public:\r
+  CIfrString () : CIfrObj (EFI_IFR_STRING_OP, (CHAR8 **)&mString),\r
+                 CIfrOpHeader (EFI_IFR_STRING_OP, &mString->Header),\r
+                 CIfrQuestionHeader (&mString->Question) {\r
+    mString->Flags   = 0;\r
+    mString->MinSize = 0;\r
+    mString->MaxSize = 0;\r
+    gCurrentQuestion = this;\r
+  }\r
+\r
+  ~CIfrString () {\r
+    gCurrentQuestion = NULL;\r
+  }\r
+\r
+  EFI_VFR_RETURN_CODE SetFlags (IN UINT8 HFlags, IN UINT8 LFlags) {\r
+    EFI_VFR_RETURN_CODE Ret;\r
+\r
+    Ret = CIfrQuestionHeader::SetFlags (HFlags);\r
+    if (Ret != VFR_RETURN_SUCCESS) {\r
+      return Ret;\r
+    }\r
+\r
+    if (_FLAG_TEST_AND_CLEAR (LFlags, EFI_IFR_STRING_MULTI_LINE)) {\r
+      mString->Flags |= EFI_IFR_STRING_MULTI_LINE;\r
+    }\r
+\r
+    return _FLAGS_ZERO (LFlags) ? VFR_RETURN_SUCCESS : VFR_RETURN_FLAGS_UNSUPPORTED;\r
+  }\r
+\r
+  VOID SetMinSize (IN UINT8 Flags) {\r
+    mString->MinSize = Flags;\r
+  }\r
+\r
+  VOID SetMaxSize (IN UINT8 MaxSize) {\r
+    mString->MaxSize = MaxSize;\r
+  }\r
+};\r
+\r
+class CIfrPassword : public CIfrObj, public CIfrOpHeader, public CIfrQuestionHeader {\r
+private:\r
+  EFI_IFR_PASSWORD *mPassword;\r
+\r
+public:\r
+  CIfrPassword () : CIfrObj (EFI_IFR_PASSWORD_OP, (CHAR8 **)&mPassword),\r
+                    CIfrOpHeader (EFI_IFR_PASSWORD_OP, &mPassword->Header),\r
+                    CIfrQuestionHeader (&mPassword->Question) {\r
+    mPassword->MinSize = 0;\r
+    mPassword->MaxSize = 0;\r
+    gCurrentQuestion   = this;\r
+  }\r
+\r
+  ~CIfrPassword () {\r
+    gCurrentQuestion = NULL;\r
+  }\r
+\r
+  VOID SetMinSize (IN UINT16 MinSize) {\r
+    mPassword->MinSize = MinSize;\r
+  }\r
+\r
+  VOID SetMaxSize (IN UINT16 MaxSize) {\r
+    mPassword->MaxSize = MaxSize;\r
+  }\r
+};\r
+\r
+class CIfrOrderedList : public CIfrObj, public CIfrOpHeader, public CIfrQuestionHeader {\r
+private:\r
+  EFI_IFR_ORDERED_LIST *mOrderedList;\r
+\r
+public:\r
+  CIfrOrderedList () : CIfrObj (EFI_IFR_ORDERED_LIST_OP, (CHAR8 **)&mOrderedList),\r
+                      CIfrOpHeader (EFI_IFR_ORDERED_LIST_OP, &mOrderedList->Header),\r
+                      CIfrQuestionHeader (&mOrderedList->Question) {\r
+    mOrderedList->MaxContainers = 0;\r
+    mOrderedList->Flags         = 0;\r
+    gCurrentQuestion            = this;\r
+  }\r
+\r
+  ~CIfrOrderedList () {\r
+    gCurrentQuestion = NULL;\r
+  }\r
+\r
+  VOID SetMaxContainers (IN UINT8 MaxContainers) {\r
+    mOrderedList->MaxContainers = MaxContainers;\r
+  }\r
+\r
+  EFI_VFR_RETURN_CODE SetFlags (IN UINT8 HFlags, IN UINT8 LFlags) {\r
+    EFI_VFR_RETURN_CODE Ret;\r
+\r
+    Ret = CIfrQuestionHeader::SetFlags (HFlags);\r
+    if (Ret != VFR_RETURN_SUCCESS) {\r
+      return Ret;\r
+    }\r
+\r
+    if (_FLAG_TEST_AND_CLEAR (LFlags, EFI_IFR_UNIQUE_SET)) {\r
+      mOrderedList->Flags |= EFI_IFR_UNIQUE_SET;\r
+    }\r
+\r
+    if (_FLAG_TEST_AND_CLEAR (LFlags, EFI_IFR_NO_EMPTY_SET)) {\r
+      mOrderedList->Flags |= EFI_IFR_NO_EMPTY_SET;\r
+    }\r
+\r
+    return _FLAGS_ZERO (LFlags) ? VFR_RETURN_SUCCESS : VFR_RETURN_FLAGS_UNSUPPORTED;\r
+  }\r
+};\r
+\r
+class CIfrTime : public CIfrObj, public CIfrOpHeader, public CIfrQuestionHeader {\r
+private:\r
+  EFI_IFR_TIME *mTime;\r
+\r
+public:\r
+  CIfrTime () : CIfrObj (EFI_IFR_TIME_OP, (CHAR8 **)&mTime),\r
+                CIfrOpHeader (EFI_IFR_TIME_OP, &mTime->Header),\r
+                CIfrQuestionHeader (&mTime->Question) {\r
+    mTime->Flags = 0;\r
+  }\r
+\r
+  EFI_VFR_RETURN_CODE SetFlags (IN UINT8 HFlags, IN UINT8 LFlags) {\r
+    EFI_VFR_RETURN_CODE Ret;\r
+\r
+    Ret = CIfrQuestionHeader::SetFlags (HFlags);\r
+    if (Ret != VFR_RETURN_SUCCESS) {\r
+      return Ret;\r
+    }\r
+\r
+    if (_FLAG_TEST_AND_CLEAR (LFlags, QF_TIME_HOUR_SUPPRESS)) {\r
+      mTime->Flags |= QF_TIME_HOUR_SUPPRESS;\r
+    }\r
+\r
+    if (_FLAG_TEST_AND_CLEAR (LFlags, QF_TIME_MINUTE_SUPPRESS)) {\r
+      mTime->Flags |= QF_TIME_MINUTE_SUPPRESS;\r
+    }\r
+\r
+    if (_FLAG_TEST_AND_CLEAR (LFlags, QF_TIME_SECOND_SUPPRESS)) {\r
+      mTime->Flags |= QF_TIME_SECOND_SUPPRESS;\r
+    }\r
+\r
+    if (_FLAG_TEST_AND_CLEAR (LFlags, QF_TIME_STORAGE_NORMAL)) {\r
+      mTime->Flags |= QF_TIME_STORAGE_NORMAL;\r
+    } else if (_FLAG_TEST_AND_CLEAR (LFlags, QF_TIME_STORAGE_TIME)) {\r
+      mTime->Flags |= QF_TIME_STORAGE_TIME;\r
+    } else if (_FLAG_TEST_AND_CLEAR (LFlags, QF_TIME_STORAGE_WAKEUP)) {\r
+      mTime->Flags |= QF_TIME_STORAGE_WAKEUP;\r
+    }\r
+\r
+    return _FLAGS_ZERO (LFlags) ? VFR_RETURN_SUCCESS : VFR_RETURN_FLAGS_UNSUPPORTED;\r
+  }\r
+};\r
+\r
+class CIfrDisableIf : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_DISABLE_IF *mDisableIf;\r
+\r
+public:\r
+  CIfrDisableIf () : CIfrObj (EFI_IFR_DISABLE_IF_OP, (CHAR8 **)&mDisableIf),\r
+                   mDisableIf ((EFI_IFR_DISABLE_IF *) GetObjBinAddr()),\r
+                   CIfrOpHeader (EFI_IFR_DISABLE_IF_OP, &mDisableIf->Header) {}\r
+};\r
+\r
+class CIfrSuppressIf : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_SUPPRESS_IF *mSuppressIf;\r
+\r
+public:\r
+  CIfrSuppressIf () : CIfrObj (EFI_IFR_SUPPRESS_IF_OP, (CHAR8 **)&mSuppressIf),\r
+                     CIfrOpHeader (EFI_IFR_SUPPRESS_IF_OP, &mSuppressIf->Header) {}\r
+};\r
+\r
+class CIfrGrayOutIf : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_GRAY_OUT_IF *mGrayOutIf;\r
+\r
+public:\r
+  CIfrGrayOutIf () : CIfrObj (EFI_IFR_GRAY_OUT_IF_OP, (CHAR8 **)&mGrayOutIf),\r
+                    CIfrOpHeader (EFI_IFR_GRAY_OUT_IF_OP, &mGrayOutIf->Header) {}\r
+};\r
+\r
+class CIfrInconsistentIf : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_INCONSISTENT_IF *mInconsistentIf;\r
+\r
+public:\r
+  CIfrInconsistentIf () : CIfrObj (EFI_IFR_INCONSISTENT_IF_OP, (CHAR8 **)&mInconsistentIf),\r
+                        CIfrOpHeader (EFI_IFR_INCONSISTENT_IF_OP, &mInconsistentIf->Header) {\r
+    mInconsistentIf->Error = EFI_STRING_ID_INVALID;\r
+  }\r
+\r
+  VOID SetError (IN EFI_STRING_ID Error) {\r
+    mInconsistentIf->Error = Error;\r
+  }\r
+};\r
+\r
+class CIfrNoSubmitIf : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_NO_SUBMIT_IF *mNoSubmitIf;\r
+\r
+public:\r
+  CIfrNoSubmitIf () : CIfrObj (EFI_IFR_NO_SUBMIT_IF_OP, (CHAR8 **)&mNoSubmitIf),\r
+                     CIfrOpHeader (EFI_IFR_NO_SUBMIT_IF_OP, &mNoSubmitIf->Header) {\r
+    mNoSubmitIf->Error = EFI_STRING_ID_INVALID;\r
+  }\r
+\r
+  VOID SetError (IN EFI_STRING_ID Error) {\r
+    mNoSubmitIf->Error = Error;\r
+  }\r
+};\r
+\r
+class CIfrRefresh : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_REFRESH *mRefresh;\r
+\r
+public:\r
+  CIfrRefresh () : CIfrObj (EFI_IFR_REFRESH_OP, (CHAR8 **)&mRefresh),\r
+                  CIfrOpHeader (EFI_IFR_REFRESH_OP, &mRefresh->Header) {\r
+    mRefresh->RefreshInterval = 0;\r
+  }\r
+\r
+  VOID SetRefreshInterval (IN UINT8 RefreshInterval) {\r
+    mRefresh->RefreshInterval = RefreshInterval;\r
+  }\r
+};\r
+\r
+class CIfrVarStoreDevice : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_VARSTORE_DEVICE *mVarStoreDevice;\r
+\r
+public:\r
+  CIfrVarStoreDevice () : CIfrObj (EFI_IFR_VARSTORE_DEVICE_OP, (CHAR8 **)&mVarStoreDevice),\r
+                          CIfrOpHeader (EFI_IFR_VARSTORE_DEVICE_OP, &mVarStoreDevice->Header) {\r
+    mVarStoreDevice->DevicePath = EFI_STRING_ID_INVALID;\r
+  }\r
+\r
+  VOID SetDevicePath (IN EFI_STRING_ID DevicePath) {\r
+    mVarStoreDevice->DevicePath = DevicePath;\r
+  }\r
+};\r
+\r
+class CIfrOneOfOption : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_ONE_OF_OPTION *mOneOfOption;\r
+\r
+public:\r
+  CIfrOneOfOption () : CIfrObj (EFI_IFR_ONE_OF_OPTION_OP, (CHAR8 **)&mOneOfOption),\r
+                       CIfrOpHeader (EFI_IFR_ONE_OF_OPTION_OP, &mOneOfOption->Header) {\r
+    mOneOfOption->Flags  = 0;\r
+    mOneOfOption->Option = EFI_STRING_ID_INVALID;\r
+    mOneOfOption->Type   = EFI_IFR_TYPE_OTHER;\r
+    memset (&mOneOfOption->Value, 0, sizeof (mOneOfOption->Value));\r
+  }\r
+\r
+  VOID SetOption (IN EFI_STRING_ID Option) {\r
+    mOneOfOption->Option = Option;\r
+  }\r
+\r
+  EFI_VFR_RETURN_CODE SetFlags (IN UINT8 LFlags) {\r
+    if (_FLAG_TEST_AND_CLEAR (LFlags, EFI_IFR_OPTION_DEFAULT)) {\r
+      mOneOfOption->Flags |= EFI_IFR_OPTION_DEFAULT;\r
+    }\r
+\r
+    if (_FLAG_TEST_AND_CLEAR (LFlags, EFI_IFR_OPTION_DEFAULT_MFG)) {\r
+      mOneOfOption->Flags |= EFI_IFR_OPTION_DEFAULT_MFG;\r
+    }\r
+\r
+    if (_IS_EQUAL (LFlags, EFI_IFR_TYPE_NUM_SIZE_8)) {\r
+      _FLAG_CLEAR (LFlags, EFI_IFR_TYPE_NUM_SIZE_8);\r
+      mOneOfOption->Flags |= EFI_IFR_TYPE_NUM_SIZE_8;\r
+    } else if (_IS_EQUAL (LFlags, EFI_IFR_TYPE_NUM_SIZE_16)) {\r
+      _FLAG_CLEAR (LFlags, EFI_IFR_TYPE_NUM_SIZE_16);\r
+      mOneOfOption->Flags |= EFI_IFR_TYPE_NUM_SIZE_16;\r
+    } else if (_IS_EQUAL (LFlags, EFI_IFR_TYPE_NUM_SIZE_32)) {\r
+      _FLAG_CLEAR (LFlags, EFI_IFR_TYPE_NUM_SIZE_32);\r
+      mOneOfOption->Flags |= EFI_IFR_TYPE_NUM_SIZE_32;\r
+    } else if (_IS_EQUAL (LFlags, EFI_IFR_TYPE_NUM_SIZE_64)) {\r
+      _FLAG_CLEAR (LFlags, EFI_IFR_TYPE_NUM_SIZE_64);\r
+      mOneOfOption->Flags |= EFI_IFR_TYPE_NUM_SIZE_64;\r
+    } else if (_IS_EQUAL (LFlags, EFI_IFR_TYPE_BOOLEAN)) {\r
+      _FLAG_CLEAR (LFlags, EFI_IFR_TYPE_BOOLEAN);\r
+      mOneOfOption->Flags |= EFI_IFR_TYPE_BOOLEAN;\r
+    } else if (_IS_EQUAL (LFlags, EFI_IFR_TYPE_TIME)) {\r
+      _FLAG_CLEAR (LFlags, EFI_IFR_TYPE_TIME);\r
+      mOneOfOption->Flags |= EFI_IFR_TYPE_TIME;\r
+    } else if (_IS_EQUAL (LFlags, EFI_IFR_TYPE_DATE)) {\r
+      _FLAG_CLEAR (LFlags, EFI_IFR_TYPE_DATE);\r
+      mOneOfOption->Flags |= EFI_IFR_TYPE_DATE;\r
+    } else if (_IS_EQUAL (LFlags, EFI_IFR_TYPE_STRING)) {\r
+      _FLAG_CLEAR (LFlags, EFI_IFR_TYPE_STRING);\r
+      mOneOfOption->Flags |= EFI_IFR_TYPE_STRING;\r
+    } else if (_IS_EQUAL (LFlags, EFI_IFR_TYPE_OTHER)) {\r
+      _FLAG_CLEAR (LFlags, EFI_IFR_TYPE_OTHER);\r
+      mOneOfOption->Flags |= EFI_IFR_TYPE_OTHER;\r
+    }\r
+\r
+    return _FLAGS_ZERO (LFlags) ? VFR_RETURN_SUCCESS : VFR_RETURN_FLAGS_UNSUPPORTED;\r
+  }\r
+\r
+  VOID SetType (IN UINT8 Type) {\r
+    mOneOfOption->Type = Type;\r
+  }\r
+\r
+  VOID SetValue (IN EFI_IFR_TYPE_VALUE Value) {\r
+    mOneOfOption->Value = Value;\r
+  }\r
+\r
+  UINT8 GetFlags (VOID) {\r
+    return mOneOfOption->Flags;\r
+  }\r
+};\r
+\r
+static EFI_GUID IfrTianoGuid = EFI_IFR_TIANO_GUID;\r
+\r
+class CIfrClass : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_GUID_CLASS *mClass;\r
+\r
+public:\r
+  CIfrClass () : CIfrObj (EFI_IFR_GUID_OP, (CHAR8 **)&mClass, sizeof (EFI_IFR_GUID_CLASS)),\r
+                CIfrOpHeader (EFI_IFR_GUID_OP, &mClass->Header, sizeof (EFI_IFR_GUID_CLASS)) {\r
+    mClass->ExtendOpCode = EFI_IFR_EXTEND_OP_CLASS;\r
+    mClass->Guid         = IfrTianoGuid;\r
+    mClass->Class        = EFI_NON_DEVICE_CLASS;\r
+  }\r
+\r
+  VOID SetClass (IN UINT16 Class) {\r
+    mClass->Class        = Class;\r
+  }\r
+};\r
+\r
+class CIfrSubClass : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_GUID_SUBCLASS *mSubClass;\r
+\r
+public:\r
+  CIfrSubClass () : CIfrObj (EFI_IFR_GUID_OP, (CHAR8 **)&mSubClass, sizeof (EFI_IFR_GUID_SUBCLASS)),\r
+                    CIfrOpHeader (EFI_IFR_GUID_OP, &mSubClass->Header, sizeof (EFI_IFR_GUID_SUBCLASS)) {\r
+    mSubClass->ExtendOpCode = EFI_IFR_EXTEND_OP_SUBCLASS;\r
+    mSubClass->Guid         = IfrTianoGuid;\r
+    mSubClass->SubClass     = EFI_SETUP_APPLICATION_SUBCLASS;\r
+  }\r
+\r
+  VOID SetSubClass (IN UINT16 SubClass) {\r
+    mSubClass->SubClass = SubClass;\r
+  }\r
+};\r
+\r
+class CIfrLabel : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_GUID_LABEL *mLabel;\r
+\r
+public:\r
+  CIfrLabel () : CIfrObj (EFI_IFR_GUID_OP, (CHAR8 **)&mLabel, sizeof (EFI_IFR_GUID_LABEL)),\r
+                CIfrOpHeader (EFI_IFR_GUID_OP, &mLabel->Header, sizeof (EFI_IFR_GUID_LABEL)) {\r
+    mLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
+    mLabel->Guid         = IfrTianoGuid;\r
+  }\r
+\r
+  VOID SetNumber (IN UINT16 Number) {\r
+    mLabel->Number = Number;\r
+  }\r
+};\r
+\r
+class CIfrBanner : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_GUID_BANNER *mBanner;\r
+\r
+public:\r
+  CIfrBanner () : CIfrObj (EFI_IFR_GUID_OP, (CHAR8 **)&mBanner, sizeof (EFI_IFR_GUID_BANNER)),\r
+                  CIfrOpHeader (EFI_IFR_GUID_OP, &mBanner->Header, sizeof (EFI_IFR_GUID_BANNER)) {\r
+    mBanner->ExtendOpCode = EFI_IFR_EXTEND_OP_BANNER;\r
+    mBanner->Guid         = IfrTianoGuid;\r
+  }\r
+\r
+  VOID SetTitle (IN EFI_STRING_ID StringId) {\r
+    mBanner->Title = StringId;\r
+  }\r
+\r
+  VOID SetLine (IN UINT16 Line) {\r
+    mBanner->LineNumber = Line;\r
+  }\r
+\r
+  VOID SetAlign (IN UINT8 Align) {\r
+    mBanner->Alignment = Align;\r
+  }\r
+};\r
+\r
+class CIfrTimeout : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_GUID_TIMEOUT *mTimeout;\r
+\r
+public:\r
+  CIfrTimeout (IN UINT16 Timeout = 0) : CIfrObj (EFI_IFR_GUID_OP, (CHAR8 **)&mTimeout, sizeof (EFI_IFR_GUID_TIMEOUT)),\r
+                                        CIfrOpHeader (EFI_IFR_GUID_OP, &mTimeout->Header, sizeof (EFI_IFR_GUID_TIMEOUT)) {\r
+    mTimeout->ExtendOpCode = EFI_IFR_EXTEND_OP_TIMEOUT;\r
+    mTimeout->Guid         = IfrTianoGuid;\r
+    mTimeout->TimeOut      = Timeout;\r
+  }\r
+\r
+  VOID SetTimeout (IN UINT16 Timeout) {\r
+    mTimeout->TimeOut = Timeout;\r
+  }\r
+};\r
+\r
+class CIfrDup : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_DUP *mDup;\r
+\r
+public:\r
+  CIfrDup (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_DUP_OP, (CHAR8 **)&mDup),\r
+      CIfrOpHeader (EFI_IFR_DUP_OP, &mDup->Header) {\r
+    SetLineNo (LineNo);\r
+  }\r
+};\r
+\r
+class CIfrEqIdId : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_EQ_ID_ID   *mEqIdId;\r
+\r
+public:\r
+  CIfrEqIdId (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_EQ_ID_ID_OP, (CHAR8 **)&mEqIdId),\r
+                 CIfrOpHeader (EFI_IFR_EQ_ID_ID_OP, &mEqIdId->Header) {\r
+    SetLineNo (LineNo);\r
+    mEqIdId->QuestionId1 = EFI_QUESTION_ID_INVALID;\r
+    mEqIdId->QuestionId2 = EFI_QUESTION_ID_INVALID;\r
+  }\r
+\r
+  VOID SetQuestionId1 (\r
+  IN EFI_QUESTION_ID QuestionId,\r
+  IN INT8            *VarIdStr,\r
+  IN UINT32          LineNo\r
+  ) {\r
+    if (QuestionId != EFI_QUESTION_ID_INVALID) {\r
+      mEqIdId->QuestionId1 = QuestionId;\r
+    } else {\r
+      gCFormPkg.AssignPending (VarIdStr, (VOID *)(&mEqIdId->QuestionId1), sizeof (EFI_QUESTION_ID), LineNo);\r
+    }\r
+  }\r
+\r
+  VOID SetQuestionId2 (\r
+  IN EFI_QUESTION_ID QuestionId,\r
+  IN INT8            *VarIdStr,\r
+  IN UINT32          LineNo\r
+  ) {\r
+    if (QuestionId != EFI_QUESTION_ID_INVALID) {\r
+      mEqIdId->QuestionId2 = QuestionId;\r
+    } else {\r
+      gCFormPkg.AssignPending (VarIdStr, (VOID *)(&mEqIdId->QuestionId2), sizeof (EFI_QUESTION_ID), LineNo);\r
+    }\r
+  }\r
+};\r
+\r
+class CIfrEqIdVal : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_EQ_ID_VAL *mEqIdVal;\r
+\r
+public:\r
+  CIfrEqIdVal (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_EQ_ID_VAL_OP, (CHAR8 **)&mEqIdVal),\r
+      CIfrOpHeader (EFI_IFR_EQ_ID_VAL_OP, &mEqIdVal->Header) {\r
+    SetLineNo (LineNo);\r
+    mEqIdVal->QuestionId = EFI_QUESTION_ID_INVALID;\r
+  }\r
+\r
+  VOID SetQuestionId (\r
+  IN EFI_QUESTION_ID QuestionId,\r
+  IN INT8            *VarIdStr,\r
+  IN UINT32          LineNo\r
+  ) {\r
+    if (QuestionId != EFI_QUESTION_ID_INVALID) {\r
+      mEqIdVal->QuestionId = QuestionId;\r
+    } else {\r
+      gCFormPkg.AssignPending (VarIdStr, (VOID *)(&mEqIdVal->QuestionId), sizeof (EFI_QUESTION_ID), LineNo);\r
+    }\r
+  }\r
+\r
+  VOID SetValue (IN UINT16 Value) {\r
+    mEqIdVal->Value = Value;\r
+  }\r
+};\r
+\r
+class CIfrEqIdList : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_EQ_ID_LIST *mEqIdVList;\r
+\r
+public:\r
+  CIfrEqIdList (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_EQ_ID_LIST_OP, (CHAR8 **)&mEqIdVList, sizeof (EFI_IFR_EQ_ID_LIST), TRUE),\r
+                   CIfrOpHeader (EFI_IFR_EQ_ID_LIST_OP, &mEqIdVList->Header) {\r
+    SetLineNo (LineNo);\r
+    mEqIdVList->QuestionId   = EFI_QUESTION_ID_INVALID;\r
+    mEqIdVList->ListLength   = 0;\r
+    mEqIdVList->ValueList[0] = 0;\r
+  }\r
+\r
+  VOID SetQuestionId (\r
+  IN EFI_QUESTION_ID QuestionId,\r
+  IN INT8            *VarIdStr,\r
+  IN UINT32          LineNo\r
+  ) {\r
+    if (QuestionId != EFI_QUESTION_ID_INVALID) {\r
+      mEqIdVList->QuestionId = QuestionId;\r
+    } else {\r
+      gCFormPkg.AssignPending (VarIdStr, (VOID *)(&mEqIdVList->QuestionId), sizeof (EFI_QUESTION_ID), LineNo);\r
+    }\r
+  }\r
+\r
+  VOID SetListLength (IN UINT16 ListLength) {\r
+    mEqIdVList->ListLength = ListLength;\r
+  }\r
+\r
+  VOID SetValueList (IN UINT16 Index, IN UINT16 Value) {\r
+    if (Index == 0) {\r
+      mEqIdVList->ValueList[0] = Value;\r
+      return;\r
+    }\r
+\r
+    if (ExpendObjBin (sizeof (UINT16)) ==TRUE) {\r
+      IncLength (sizeof (UINT16));\r
+      mEqIdVList->ValueList[Index] = Value;\r
+    }\r
+  }\r
+};\r
+\r
+class CIfrQuestionRef1 : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_QUESTION_REF1 *mQuestionRef1;\r
+\r
+public:\r
+  CIfrQuestionRef1 (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_QUESTION_REF1_OP, (CHAR8 **)&mQuestionRef1),\r
+      CIfrOpHeader (EFI_IFR_QUESTION_REF1_OP, &mQuestionRef1->Header) {\r
+    SetLineNo (LineNo);\r
+    mQuestionRef1->QuestionId = EFI_QUESTION_ID_INVALID;\r
+  }\r
+\r
+  VOID SetQuestionId (\r
+  IN EFI_QUESTION_ID QuestionId,\r
+  IN INT8            *VarIdStr,\r
+  IN UINT32          LineNo\r
+  ) {\r
+    if (QuestionId != EFI_QUESTION_ID_INVALID) {\r
+      mQuestionRef1->QuestionId = QuestionId;\r
+    } else {\r
+      gCFormPkg.AssignPending (VarIdStr, (VOID *)(&mQuestionRef1->QuestionId), sizeof (EFI_QUESTION_ID), LineNo);\r
+    }\r
+  }\r
+};\r
+\r
+class CIfrQuestionRef2 : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_QUESTION_REF2 *mQuestionRef2;\r
+\r
+public:\r
+  CIfrQuestionRef2 (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_QUESTION_REF2_OP, (CHAR8 **)&mQuestionRef2),\r
+      CIfrOpHeader (EFI_IFR_QUESTION_REF2_OP, &mQuestionRef2->Header) {\r
+    SetLineNo (LineNo);\r
+  }\r
+};\r
+\r
+class CIfrQuestionRef3 : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_QUESTION_REF3 *mQuestionRef3;\r
+\r
+public:\r
+  CIfrQuestionRef3 (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_QUESTION_REF3_OP, (CHAR8 **)&mQuestionRef3),\r
+      CIfrOpHeader (EFI_IFR_QUESTION_REF3_OP, &mQuestionRef3->Header) {\r
+    SetLineNo (LineNo);\r
+  }\r
+};\r
+\r
+class CIfrQuestionRef3_2 : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_QUESTION_REF3_2 *mQuestionRef3_2;\r
+\r
+public:\r
+  CIfrQuestionRef3_2 (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_QUESTION_REF3_OP, (CHAR8 **)&mQuestionRef3_2, sizeof (EFI_IFR_QUESTION_REF3_2)),\r
+      CIfrOpHeader (EFI_IFR_QUESTION_REF3_OP, &mQuestionRef3_2->Header, sizeof (EFI_IFR_QUESTION_REF3_2)) {\r
+    SetLineNo (LineNo);\r
+    mQuestionRef3_2->DevicePath = EFI_STRING_ID_INVALID;\r
+  }\r
+\r
+  VOID SetDevicePath (IN EFI_STRING_ID DevicePath) {\r
+    mQuestionRef3_2->DevicePath = DevicePath;\r
+  }\r
+};\r
+\r
+class CIfrQuestionRef3_3 : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_QUESTION_REF3_3 *mQuestionRef3_3;\r
+\r
+public:\r
+  CIfrQuestionRef3_3 (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_QUESTION_REF3_OP, (CHAR8 **)&mQuestionRef3_3, sizeof (EFI_IFR_QUESTION_REF3_3)),\r
+      CIfrOpHeader (EFI_IFR_QUESTION_REF3_OP, &mQuestionRef3_3->Header, sizeof (EFI_IFR_QUESTION_REF3_3)) {\r
+    SetLineNo (LineNo);\r
+    mQuestionRef3_3->DevicePath = EFI_STRING_ID_INVALID;\r
+    memset (&mQuestionRef3_3->Guid, 0, sizeof (EFI_GUID));\r
+  }\r
+\r
+  VOID SetDevicePath (IN EFI_STRING_ID DevicePath) {\r
+    mQuestionRef3_3->DevicePath = DevicePath;\r
+  }\r
+\r
+  VOID SetGuid (IN EFI_GUID *Guid) {\r
+    mQuestionRef3_3->Guid = *Guid;\r
+  }\r
+};\r
+\r
+class CIfrRuleRef : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_RULE_REF *mRuleRef;\r
+\r
+public:\r
+  CIfrRuleRef (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_RULE_REF_OP, (CHAR8 **)&mRuleRef),\r
+      CIfrOpHeader (EFI_IFR_RULE_REF_OP, &mRuleRef->Header) {\r
+    SetLineNo (LineNo);\r
+    mRuleRef->RuleId = EFI_RULE_ID_INVALID;\r
+  }\r
+\r
+  VOID SetRuleId (IN UINT8 RuleId) {\r
+    mRuleRef->RuleId = RuleId;\r
+  }\r
+};\r
+\r
+class CIfrStringRef1 : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_STRING_REF1 *mStringRef1;\r
+\r
+public:\r
+  CIfrStringRef1 (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_STRING_REF1_OP, (CHAR8 **)&mStringRef1),\r
+      CIfrOpHeader (EFI_IFR_STRING_REF1_OP, &mStringRef1->Header) {\r
+    SetLineNo (LineNo);\r
+    mStringRef1->StringId = EFI_STRING_ID_INVALID;\r
+  }\r
+\r
+  VOID SetStringId (IN EFI_STRING_ID StringId) {\r
+    mStringRef1->StringId = StringId;\r
+  }\r
+};\r
+\r
+class CIfrStringRef2 : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_STRING_REF2 *mStringRef2;\r
+\r
+public:\r
+  CIfrStringRef2 (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_STRING_REF2_OP, (CHAR8 **)&mStringRef2),\r
+      CIfrOpHeader (EFI_IFR_STRING_REF2_OP, &mStringRef2->Header) {\r
+    SetLineNo (LineNo);\r
+  }\r
+};\r
+\r
+class CIfrThis : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_THIS *mThis;\r
+\r
+public:\r
+  CIfrThis (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_THIS_OP, (CHAR8 **)&mThis),\r
+      CIfrOpHeader (EFI_IFR_THIS_OP, &mThis->Header) {\r
+    SetLineNo (LineNo);\r
+  }\r
+};\r
+\r
+class CIfrUint8 : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_UINT8 *mUint8;\r
+\r
+public:\r
+  CIfrUint8 (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_UINT8_OP, (CHAR8 **)&mUint8),\r
+      CIfrOpHeader (EFI_IFR_UINT8_OP, &mUint8->Header) {\r
+    SetLineNo (LineNo);\r
+  }\r
+\r
+  VOID SetValue (IN UINT8 Value) {\r
+    mUint8->Value = Value;\r
+  }\r
+};\r
+\r
+class CIfrUint16 : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_UINT16 *mUint16;\r
+\r
+public:\r
+  CIfrUint16 (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_UINT16_OP, (CHAR8 **)&mUint16),\r
+      CIfrOpHeader (EFI_IFR_UINT16_OP, &mUint16->Header) {\r
+    SetLineNo (LineNo);\r
+  }\r
+\r
+  VOID SetValue (IN UINT16 Value) {\r
+    mUint16->Value = Value;\r
+  }\r
+};\r
+\r
+class CIfrUint32 : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_UINT32 *mUint32;\r
+\r
+public:\r
+  CIfrUint32 (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_UINT32_OP, (CHAR8 **)&mUint32),\r
+      CIfrOpHeader (EFI_IFR_UINT32_OP, &mUint32->Header) {\r
+    SetLineNo (LineNo);\r
+  }\r
+\r
+  VOID SetValue (IN UINT32 Value) {\r
+    mUint32->Value = Value;\r
+  }\r
+};\r
+\r
+class CIfrUint64 : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_UINT64 *mUint64;\r
+\r
+public:\r
+  CIfrUint64 (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_UINT64_OP, (CHAR8 **)&mUint64),\r
+      CIfrOpHeader (EFI_IFR_UINT64_OP, &mUint64->Header) {\r
+    SetLineNo (LineNo);\r
+  }\r
+\r
+  VOID SetValue (IN UINT64 Value) {\r
+    mUint64->Value = Value;\r
+  }\r
+};\r
+\r
+class CIfrTrue : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_TRUE *mTrue;\r
+\r
+public:\r
+  CIfrTrue (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_TRUE_OP, (CHAR8 **)&mTrue),\r
+      CIfrOpHeader (EFI_IFR_TRUE_OP, &mTrue->Header) {\r
+    SetLineNo (LineNo);\r
+  }\r
+};\r
+\r
+class CIfrFalse : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_FALSE *mFalse;\r
+\r
+public:\r
+  CIfrFalse (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_FALSE_OP, (CHAR8 **)&mFalse),\r
+      CIfrOpHeader (EFI_IFR_FALSE_OP, &mFalse->Header) {\r
+    SetLineNo (LineNo);\r
+  }\r
+};\r
+\r
+class CIfrOne : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_ONE *mOne;\r
+\r
+public:\r
+  CIfrOne (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_ONE_OP, (CHAR8 **)&mOne),\r
+      CIfrOpHeader (EFI_IFR_ONE_OP, &mOne->Header) {\r
+    SetLineNo (LineNo);\r
+  }\r
+};\r
+\r
+class CIfrOnes : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_ONES *mOnes;\r
+\r
+public:\r
+  CIfrOnes (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_ONES_OP, (CHAR8 **)&mOnes),\r
+      CIfrOpHeader (EFI_IFR_ONES_OP, &mOnes->Header) {\r
+    SetLineNo (LineNo);\r
+  }\r
+};\r
+\r
+class CIfrZero : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_ZERO *mZero;\r
+\r
+public:\r
+  CIfrZero (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_ZERO_OP, (CHAR8 **)&mZero),\r
+      CIfrOpHeader (EFI_IFR_ZERO_OP, &mZero->Header) {\r
+    SetLineNo (LineNo);\r
+  }\r
+};\r
+\r
+class CIfrUndefined : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_UNDEFINED *mUndefined;\r
+\r
+public:\r
+  CIfrUndefined (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_UNDEFINED_OP, (CHAR8 **)&mUndefined),\r
+      CIfrOpHeader (EFI_IFR_UNDEFINED_OP, &mUndefined->Header) {\r
+    SetLineNo (LineNo);\r
+  }\r
+};\r
+\r
+class CIfrVersion : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_VERSION *mVersion;\r
+\r
+public:\r
+  CIfrVersion (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_VERSION_OP, (CHAR8 **)&mVersion),\r
+      CIfrOpHeader (EFI_IFR_VERSION_OP, &mVersion->Header) {\r
+    SetLineNo (LineNo);\r
+  }\r
+};\r
+\r
+class CIfrLength : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_LENGTH *mLength;\r
+\r
+public:\r
+  CIfrLength (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_LENGTH_OP, (CHAR8 **)&mLength),\r
+      CIfrOpHeader (EFI_IFR_LENGTH_OP, &mLength->Header) {\r
+    SetLineNo (LineNo);\r
+  }\r
+};\r
+\r
+class CIfrNot : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_NOT *mNot;\r
+\r
+public:\r
+  CIfrNot (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_NOT_OP, (CHAR8 **)&mNot),\r
+      CIfrOpHeader (EFI_IFR_NOT_OP, &mNot->Header) {\r
+    SetLineNo (LineNo);\r
+  }\r
+};\r
+\r
+class CIfrBitWiseNot : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_BITWISE_NOT *mBitWise;\r
+\r
+public:\r
+  CIfrBitWiseNot (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_BITWISE_NOT_OP, (CHAR8 **)&mBitWise),\r
+      CIfrOpHeader (EFI_IFR_BITWISE_NOT_OP, &mBitWise->Header) {\r
+    SetLineNo (LineNo);\r
+  }\r
+};\r
+\r
+class CIfrToBoolean : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_TO_BOOLEAN *mToBoolean;\r
+\r
+public:\r
+  CIfrToBoolean (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_TO_BOOLEAN_OP, (CHAR8 **)&mToBoolean),\r
+      CIfrOpHeader (EFI_IFR_TO_BOOLEAN_OP, &mToBoolean->Header) {\r
+    SetLineNo (LineNo);\r
+  }\r
+};\r
+\r
+class CIfrToString : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_TO_STRING *mToString;\r
+\r
+public:\r
+  CIfrToString (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_TO_STRING_OP, (CHAR8 **)&mToString),\r
+      CIfrOpHeader (EFI_IFR_TO_STRING_OP, &mToString->Header) {\r
+    SetLineNo (LineNo);\r
+  }\r
+\r
+  VOID SetFormat (IN UINT8 Format) {\r
+    mToString->Format = Format;\r
+  }\r
+};\r
+\r
+class CIfrToUint : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_TO_UINT *mToUint;\r
+\r
+public:\r
+  CIfrToUint (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_TO_UINT_OP, (CHAR8 **)&mToUint),\r
+      CIfrOpHeader (EFI_IFR_TO_UINT_OP, &mToUint->Header) {\r
+    SetLineNo (LineNo);\r
+  }\r
+};\r
+\r
+class CIfrToUpper : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_TO_UPPER *mToUpper;\r
+\r
+public:\r
+  CIfrToUpper (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_TO_UPPER_OP, (CHAR8 **)&mToUpper),\r
+      CIfrOpHeader (EFI_IFR_TO_UPPER_OP, &mToUpper->Header) {\r
+    SetLineNo (LineNo);\r
+  }\r
+};\r
+\r
+class CIfrToLower : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_TO_LOWER *mToLower;\r
+\r
+public:\r
+  CIfrToLower (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_TO_LOWER_OP, (CHAR8 **)&mToLower),\r
+      CIfrOpHeader (EFI_IFR_TO_LOWER_OP, &mToLower->Header) {\r
+    SetLineNo (LineNo);\r
+  }\r
+};\r
+\r
+class CIfrAdd : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_ADD *mAdd;\r
+\r
+public:\r
+  CIfrAdd (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_ADD_OP, (CHAR8 **)&mAdd),\r
+      CIfrOpHeader (EFI_IFR_ADD_OP, &mAdd->Header) {\r
+    SetLineNo (LineNo);\r
+  }\r
+};\r
+\r
+class CIfrBitWiseAnd : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_BITWISE_AND *mBitWiseAnd;\r
+\r
+public:\r
+  CIfrBitWiseAnd (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_BITWISE_AND_OP, (CHAR8 **)&mBitWiseAnd),\r
+      CIfrOpHeader (EFI_IFR_BITWISE_AND_OP, &mBitWiseAnd->Header) {\r
+    SetLineNo(LineNo);\r
+  }\r
+};\r
+\r
+class CIfrBitWiseOr : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_BITWISE_OR *mBitWiseOr;\r
+\r
+public:\r
+  CIfrBitWiseOr (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_BITWISE_OR_OP, (CHAR8 **)&mBitWiseOr),\r
+      CIfrOpHeader (EFI_IFR_BITWISE_OR_OP, &mBitWiseOr->Header) {\r
+    SetLineNo (LineNo);\r
+  }\r
+};\r
+\r
+class CIfrAnd : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_AND *mAnd;\r
+\r
+public:\r
+  CIfrAnd (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_AND_OP, (CHAR8 **)&mAnd),\r
+      CIfrOpHeader (EFI_IFR_AND_OP, &mAnd->Header) {\r
+    SetLineNo (LineNo);\r
+  }\r
+};\r
+\r
+class CIfrCatenate : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_CATENATE *mCatenate;\r
+\r
+public:\r
+  CIfrCatenate (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_CATENATE_OP, (CHAR8 **)&mCatenate),\r
+      CIfrOpHeader (EFI_IFR_CATENATE_OP, &mCatenate->Header) {\r
+    SetLineNo (LineNo);\r
+  }\r
+};\r
+\r
+class CIfrDivide : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_DIVIDE *mDivide;\r
+\r
+public:\r
+  CIfrDivide (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_DIVIDE_OP, (CHAR8 **)&mDivide),\r
+      CIfrOpHeader (EFI_IFR_DIVIDE_OP, &mDivide->Header) {\r
+    SetLineNo (LineNo);\r
+  }\r
+};\r
+\r
+class CIfrEqual : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_EQUAL *mEqual;\r
+\r
+public:\r
+  CIfrEqual (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_EQUAL_OP, (CHAR8 **)&mEqual),\r
+      CIfrOpHeader (EFI_IFR_EQUAL_OP, &mEqual->Header) {\r
+    SetLineNo (LineNo);\r
+  }\r
+};\r
+\r
+class CIfrGreaterEqual : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_GREATER_EQUAL *mGreaterEqual;\r
+\r
+public:\r
+  CIfrGreaterEqual (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_GREATER_EQUAL_OP, (CHAR8 **)&mGreaterEqual),\r
+      CIfrOpHeader (EFI_IFR_GREATER_EQUAL_OP, &mGreaterEqual->Header) {\r
+    SetLineNo (LineNo);\r
+  }\r
+};\r
+\r
+class CIfrGreaterThan : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_GREATER_THAN *mGreaterThan;\r
+\r
+public:\r
+  CIfrGreaterThan (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_GREATER_THAN_OP, (CHAR8 **)&mGreaterThan),\r
+      CIfrOpHeader (EFI_IFR_GREATER_THAN_OP, &mGreaterThan->Header) {\r
+    SetLineNo (LineNo);\r
+  }\r
+};\r
+\r
+class CIfrLessEqual : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_LESS_EQUAL *mLessEqual;\r
+\r
+public:\r
+  CIfrLessEqual (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_LESS_EQUAL_OP, (CHAR8 **)&mLessEqual),\r
+      CIfrOpHeader (EFI_IFR_LESS_EQUAL_OP, &mLessEqual->Header) {\r
+    SetLineNo (LineNo);\r
+  }\r
+};\r
+\r
+class CIfrLessThan : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_LESS_THAN *mLessThan;\r
+\r
+public:\r
+  CIfrLessThan (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_LESS_THAN_OP, (CHAR8 **)&mLessThan),\r
+      CIfrOpHeader (EFI_IFR_LESS_THAN_OP, &mLessThan->Header) {\r
+    SetLineNo (LineNo);\r
+  }\r
+};\r
+\r
+class CIfrMatch : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_MATCH *mMatch;\r
+\r
+public:\r
+  CIfrMatch (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_MATCH_OP, (CHAR8 **)&mMatch),\r
+      CIfrOpHeader (EFI_IFR_MATCH_OP, &mMatch->Header) {\r
+    SetLineNo (LineNo);\r
+  }\r
+};\r
+\r
+class CIfrMultiply : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_MULTIPLY *mMultiply;\r
+\r
+public:\r
+  CIfrMultiply (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_MULTIPLY_OP, (CHAR8 **)&mMultiply),\r
+      CIfrOpHeader (EFI_IFR_MULTIPLY_OP, &mMultiply->Header) {\r
+    SetLineNo (LineNo);\r
+  }\r
+};\r
+\r
+class CIfrModulo : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_MODULO *mModulo;\r
+\r
+public:\r
+  CIfrModulo (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_MODULO_OP, (CHAR8 **)&mModulo),\r
+      CIfrOpHeader (EFI_IFR_MODULO_OP, &mModulo->Header) {\r
+    SetLineNo (LineNo);\r
+  }\r
+};\r
+\r
+class CIfrNotEqual : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_NOT_EQUAL *mNotEqual;\r
+\r
+public:\r
+  CIfrNotEqual (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_NOT_EQUAL_OP, (CHAR8 **)&mNotEqual),\r
+      CIfrOpHeader (EFI_IFR_NOT_EQUAL_OP, &mNotEqual->Header) {\r
+    SetLineNo (LineNo);\r
+  }\r
+};\r
+\r
+class CIfrOr : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_OR *mOr;\r
+\r
+public:\r
+  CIfrOr (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_OR_OP, (CHAR8 **)&mOr),\r
+      CIfrOpHeader (EFI_IFR_OR_OP, &mOr->Header) {\r
+    SetLineNo (LineNo);\r
+  }\r
+};\r
+\r
+class CIfrShiftLeft : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_SHIFT_LEFT *mShiftLeft;\r
+\r
+public:\r
+  CIfrShiftLeft (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_SHIFT_LEFT_OP, (CHAR8 **)&mShiftLeft),\r
+      CIfrOpHeader (EFI_IFR_SHIFT_LEFT_OP, &mShiftLeft->Header) {\r
+    SetLineNo (LineNo);\r
+  }\r
+};\r
+\r
+class CIfrShiftRight : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_SHIFT_RIGHT *mShiftRight;\r
+\r
+public:\r
+  CIfrShiftRight (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_SHIFT_RIGHT_OP, (CHAR8 **)&mShiftRight),\r
+      CIfrOpHeader (EFI_IFR_SHIFT_RIGHT_OP, &mShiftRight->Header) {\r
+    SetLineNo (LineNo);\r
+  }\r
+};\r
+\r
+class CIfrSubtract : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_SUBTRACT *mSubtract;\r
+\r
+public:\r
+  CIfrSubtract (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_SUBTRACT_OP, (CHAR8 **)&mSubtract),\r
+      CIfrOpHeader (EFI_IFR_SUBTRACT_OP, &mSubtract->Header) {\r
+    SetLineNo (LineNo);\r
+  }\r
+};\r
+\r
+class CIfrConditional : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_CONDITIONAL *mConditional;\r
+\r
+public:\r
+  CIfrConditional (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_CONDITIONAL_OP, (CHAR8 **)&mConditional),\r
+      CIfrOpHeader (EFI_IFR_CONDITIONAL_OP, &mConditional->Header) {\r
+    SetLineNo (LineNo);\r
+  }\r
+};\r
+\r
+class CIfrFind : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_FIND *mFind;\r
+\r
+public:\r
+  CIfrFind (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_FIND_OP, (CHAR8 **)&mFind),\r
+      CIfrOpHeader (EFI_IFR_FIND_OP, &mFind->Header) {\r
+    SetLineNo (LineNo);\r
+  }\r
+\r
+  VOID SetFormat (IN UINT8 Format) {\r
+    mFind->Format = Format;\r
+  }\r
+};\r
+\r
+class CIfrMid : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_MID *mMid;\r
+\r
+public:\r
+  CIfrMid (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_MID_OP, (CHAR8 **)&mMid),\r
+      CIfrOpHeader (EFI_IFR_MID_OP, &mMid->Header) {\r
+    SetLineNo (LineNo);\r
+  }\r
+};\r
+\r
+class CIfrToken : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_TOKEN *mToken;\r
+\r
+public:\r
+  CIfrToken (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_TOKEN_OP, (CHAR8 **)&mToken),\r
+      CIfrOpHeader (EFI_IFR_TOKEN_OP, &mToken->Header) {\r
+    SetLineNo (LineNo);\r
+  }\r
+};\r
+\r
+class CIfrSpan : public CIfrObj, public CIfrOpHeader {\r
+private:\r
+  EFI_IFR_SPAN *mSpan;\r
+\r
+public:\r
+  CIfrSpan (\r
+  IN UINT32 LineNo\r
+  ) : CIfrObj (EFI_IFR_SPAN_OP, (CHAR8 **)&mSpan),\r
+      CIfrOpHeader (EFI_IFR_SPAN_OP, &mSpan->Header) {\r
+    SetLineNo (LineNo);\r
+    mSpan->Flags = EFI_IFR_FLAGS_FIRST_MATCHING;\r
+  }\r
+\r
+  EFI_VFR_RETURN_CODE SetFlags (IN UINT8 LFlags) {\r
+    if (_IS_EQUAL (LFlags, EFI_IFR_FLAGS_FIRST_MATCHING)) {\r
+      mSpan->Flags |= EFI_IFR_FLAGS_FIRST_MATCHING;\r
+    } else if (_FLAG_TEST_AND_CLEAR (LFlags, EFI_IFR_FLAGS_FIRST_NON_MATCHING)) {\r
+      mSpan->Flags |= EFI_IFR_FLAGS_FIRST_NON_MATCHING;\r
+    }\r
+\r
+    return _FLAGS_ZERO (LFlags) ? VFR_RETURN_SUCCESS : VFR_RETURN_FLAGS_UNSUPPORTED;\r
+  }\r
+};\r
+\r
+#endif\r
diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrSyntax.g b/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrSyntax.g
new file mode 100644 (file)
index 0000000..6029d9e
--- /dev/null
@@ -0,0 +1,3201 @@
+#header<<\r
+\r
+#include "EfiVfr.h"\r
+#include "VfrFormPkg.h"\r
+#include "VfrError.h"\r
+#include "VfrUtilityLib.h"\r
+#include "AToken.h"\r
+#include "ATokPtr.h"\r
+>>\r
+\r
+<<\r
+#include "stdio.h"\r
+#include "PBlackBox.h"\r
+#include "DLexerBase.h"\r
+#include "VfrLexer.h"    \r
+#include "AToken.h"\r
+\r
+#define GET_LINENO(Obj)       ((Obj)->getLine())\r
+#define SET_LINE_INFO(Obj, L) {(Obj).SetLineNo((L)->getLine());} while (0)\r
+#define CRT_END_OP(Obj)       {CIfrEnd EObj; EObj.SetLineNo ((Obj)->getLine());} while (0)\r
+\r
+typedef ANTLRCommonToken ANTLRToken;\r
+\r
+class CVfrDLGLexer : public VfrLexer\r
+{\r
+public:\r
+  CVfrDLGLexer (DLGFileInput *F) : VfrLexer (F) {};\r
+  INT32 errstd (char *Text) \r
+  { \r
+    printf ("unrecognized input '%s'\n", Text); \r
+  }\r
+};\r
+\r
+UINT8\r
+VfrParserStart (\r
+  IN FILE *File\r
+  )\r
+{\r
+  ParserBlackBox<CVfrDLGLexer, EfiVfrParser, ANTLRToken> VfrParser(File);\r
+  return VfrParser.parser()->vfrProgram();\r
+}\r
+>>\r
+\r
+#lexaction\r
+<<\r
+#include <Error.h>\r
+\r
+>>\r
+\r
+//\r
+// Define a lexical class for parsing quoted strings. Basically\r
+// starts with a double quote, and ends with a double quote that\r
+// is not preceeded with a backslash.\r
+//\r
+#lexclass QUOTED_STRING\r
+#token TheString            "~[\"]*\"" << mode (START); >>     \r
+\r
+//\r
+// Define a lexclass for skipping over C++ style comments\r
+//\r
+#lexclass CPP_COMMENT\r
+#token "~[\n]*"       << skip (); >>\r
+#token "\n"           << skip (); mode (START); newline (); >>\r
+\r
+//\r
+// Standard lexclass is START\r
+//\r
+#lexclass START\r
+\r
+//\r
+// Find start of C++ style comments\r
+//\r
+#token "//"       << skip (); mode (CPP_COMMENT); >>\r
+\r
+//\r
+// Skip whitespace\r
+//\r
+#token "[\ \t]"   << skip (); >> \r
+\r
+//\r
+// Skip over newlines, but count them\r
+//\r
+#token "\n"       << skip (); newline (); >>\r
+\r
+//\r
+// Skip over 'extern' in any included .H file\r
+//\r
+#token "extern"   << skip (); mode (CPP_COMMENT); >>\r
+\r
+//\r
+// Tokens for the different keywords. Syntax is:\r
+// TokenName("ErrorMessageText")    "TokenString"\r
+//   where:\r
+//     TokenName is the token name (must be capitalized) that is used in the rules\r
+//     ErrorMessageText is the string the compiler emits when it detects a syntax error\r
+//     TokenString is the actual matching string used in the user script\r
+//\r
+#token FormPkgType("formpkgtype")               "formpkgtype"\r
+#token OpenBrace("{")                           "\{"\r
+#token CloseBrace("}")                          "\}"\r
+#token OpenParen("(")                           "\("\r
+#token CloseParen(")")                          "\)"\r
+#token OpenBracket("[")                         "\["\r
+#token CloseBracket("]")                        "\]"\r
+\r
+#token LineDefinition                           "#line\ [0-9]+\ \"~[\"]+\"[\ \t]*\n" << gCVfrErrorHandle.ParseFileScopeRecord (begexpr (), line ()); skip (); newline (); >>\r
+#token DevicePath("devicepath")                 "devicepath"\r
+#token FormSet("formset")                       "formset"\r
+#token FormSetId("formsetid")                   "formsetid"\r
+#token EndFormSet("endformset")                 "endformset"\r
+#token Title("title")                           "title"\r
+#token FormId("formid")                         "formid"\r
+#token OneOf("oneof")                           "oneof"\r
+#token EndoneOf("endoneof")                     "endoneof"\r
+#token Prompt("prompt")                         "prompt"\r
+#token OrderedList("orderedlist")               "orderedlist"\r
+#token MaxContainers("maxcontainers")           "maxcontainers"\r
+#token EndList("endlist")                       "endlist"\r
+#token EndForm("endform")                       "endform"\r
+#token EndOneOf("endoneof")                     "endoneof"\r
+#token Form("form")                             "form"\r
+#token Subtitle("subtitle")                     "subtitle"\r
+#token Help("help")                             "help"\r
+#token Text("text")                             "text"\r
+#token Option("option")                         "option"\r
+#token FLAGS("flags")                           "flags"\r
+#token Date("date")                             "date"\r
+#token EndDate("enddate")                       "enddate"\r
+#token Year("year")                             "year"\r
+#token Month("month")                           "month"\r
+#token Day("day")                               "day"\r
+#token Time("time")                             "time"\r
+#token EndTime("endtime")                       "endtime"\r
+#token Hour("hour")                             "hour"\r
+#token Minute("minute")                         "minute"\r
+#token Second("second")                         "second"\r
+#token GrayOutIf("grayoutif")                   "grayoutif"\r
+#token Label("label")                           "label"\r
+#token Timeout("timeout")                       "timeout"\r
+#token Inventory("inventory")                   "inventory"\r
+#token NonNvDataMap("_NON_NV_DATA_MAP")         "_NON_NV_DATA_MAP"\r
+#token Struct("struct")                         "struct"\r
+#token Uint64("UINT64")                         "UINT64"\r
+#token Uint32("UINT32")                         "UINT32"\r
+#token Uint16("UINT16")                         "UINT16"\r
+#token Char16("CHAR16")                         "CHAR16"\r
+#token Uint8("UINT8")                           "UINT8"\r
+#token GUID("guid")                             "guid"\r
+#token CheckBox("checkbox")                     "checkbox"\r
+#token EndCheckBox("endcheckbox")               "endcheckbox"\r
+#token Numeric("numeric")                       "numeric"\r
+#token EndNumeric("endnumeric")                 "endnumeric"            \r
+#token Minimum("minimum")                       "minimum"         \r
+#token Maximum("maximum")                       "maximum"         \r
+#token STEP("step")                             "step"      \r
+#token Default("default")                       "default"         \r
+#token Password("password")                     "password"          \r
+#token EndPassword("endpassword")               "endpassword"             \r
+#token String("string")                         "string"\r
+#token EndString("endstring")                   "endstring"           \r
+#token MinSize("minsize")                       "minsize"         \r
+#token MaxSize("maxsize")                       "maxsize"         \r
+#token Encoding("encoding")                     "encoding"\r
+#token SuppressIf("suppressif")                 "suppressif"\r
+#token DisableIf("disableif")                   "disableif"\r
+#token Hidden("hidden")                         "hidden"\r
+#token Goto("goto")                             "goto"\r
+#token FormSetGuid("formsetguid")               "formsetguid"\r
+#token InconsistentIf("inconsistentif")         "inconsistentif"\r
+#token NoSubmitIf("nosubmitif")                 "nosubmitif"\r
+#token EndIf("endif")                           "endif"\r
+#token Key("key")                               "key"\r
+#token DefaultFlag("DEFAULT")                   "DEFAULT"\r
+#token ManufacturingFlag("MANUFACTURING")       "MANUFACTURING"\r
+#token InteractiveFlag("INTERACTIVE")           "INTERACTIVE"\r
+#token NVAccessFlag("NV_ACCESS")                "NV_ACCESS"\r
+#token ResetRequiredFlag("RESET_REQUIRED")      "RESET_REQUIRED"\r
+#token LateCheckFlag("LATE_CHECK")              "LATE_CHECK"\r
+#token ReadOnlyFlag("READ_ONLY")                "READ_ONLY"\r
+#token CallBackFlag("INTERACTIVE")              "INTERACTIVE"\r
+#token OptionOnlyFlag("OPTIONS_ONLY")           "OPTIONS_ONLY"\r
+#token Class("class")                           "class"\r
+#token Subclass("subclass")                     "subclass"\r
+#token TypeDef("typedef")                       "typedef"\r
+#token Restore("restore")                       "restore"\r
+#token Save("save")                             "save"\r
+#token Defaults("defaults")                     "defaults"\r
+#token Banner("banner")                         "banner"\r
+#token Align("align")                           "align"\r
+#token Left("left")                             "left"\r
+#token Right("right")                           "right"\r
+#token Center("center")                         "center"\r
+#token Line("line")                             "line"\r
+#token Name("name")                             "name"\r
+\r
+#token VarId("varid")                           "varid"\r
+#token Question("question")                     "question"\r
+#token QuestionId("questionid")                 "questionid"\r
+#token Image("image")                           "image"\r
+#token Locked("locked")                         "locked"\r
+#token Rule("rule")                             "rule"\r
+#token EndRule("endrule")                       "endrule"\r
+#token Value("value")                           "value"\r
+#token ResetButton("resetbutton")               "resetbutton"\r
+#token EndResetButton("endresetbutton")         "endresetbutton"\r
+#token DefaultStore("defaultstore")             "defaultstore"\r
+#token Attribute("attribute")                   "attribute"\r
+#token Varstore("varstore")                     "varstore"\r
+#token Efivarstore("efivarstore")               "efivarstore"\r
+#token VarSize("varsize")                       "varsize"\r
+#token NameValueVarStore("namevaluevarstore")   "namevaluevarstore"\r
+#token Action("action")                         "action"\r
+#token Config("config")                         "config"\r
+#token EndAction("endaction")                   "endaction"\r
+#token Refresh("refresh")                       "refresh"\r
+#token Interval("interval")                     "interval"\r
+#token VarstoreDevice("varstoredevice")         "varstoredevice"\r
+//\r
+// Define the class and subclass tokens\r
+//\r
+#token ClassNonDevice("NONDEVICE")                        "NON_DEVICE"\r
+#token ClassDiskDevice("DISK_DEVICE")                     "DISK_DEVICE"\r
+#token ClassVideoDevice("VIDEO_DEVICE")                   "VIDEO_DEVICE"\r
+#token ClassNetworkDevice("NETWORK_DEVICE")               "NETWORK_DEVICE"\r
+#token ClassInputDevice("INPUT_DEVICE")                   "INPUT_DEVICE"\r
+#token ClassOnBoardDevice("ONBOARD_DEVICE")               "ONBOARD_DEVICE"\r
+#token ClassOtherDevice("OTHER_DEVICE")                   "OTHER_DEVICE"\r
+\r
+#token SubclassSetupApplication("SETUP_APPLICATION")      "SETUP_APPLICATION"\r
+#token SubclassGeneralApplication("GENERAL_APPLICATION")  "GENERAL_APPLICATION"\r
+#token SubclassFrontPage("FRONT_PAGE")                    "FRONT_PAGE"\r
+#token SubclassSingleUse("SINGLE_USE")                    "SINGLE_USE"\r
+\r
+//\r
+// This is the overall definition of a VFR form definition script.\r
+//\r
+\r
+vfrProgram > [UINT8 Return] :\r
+  << mParserStatus = 0; >>\r
+  (\r
+    (\r
+         "\#pragma" "pack" "\(" A:Number "\)"          << _PCATCH(mCVfrVarDataTypeDB.Pack (_STOU32(A->getText())), A); >>\r
+      vfrDataStructDefinition\r
+         "\#pragma" "pack" "\(" "\)"                   << mCVfrVarDataTypeDB.UnPack (); >>\r
+    )\r
+    |\r
+    (\r
+      vfrDataStructDefinition\r
+    )\r
+  )*\r
+  vfrFromSetDefinition\r
+  << $Return = mParserStatus; >>\r
+  ;\r
+\r
+//*****************************************************************************\r
+//\r
+// the syntax of data struct definition\r
+//\r
+vfrDataStructDefinition :\r
+  { TypeDef } Struct                                << mCVfrVarDataTypeDB.DeclareDataTypeBegin (); >>\r
+  { NonNVDataMap }\r
+  {\r
+    N1:StringIdentifier                             << _PCATCH(mCVfrVarDataTypeDB.SetNewTypeName (N1->getText()), N1); >>\r
+  }\r
+  OpenBrace \r
+    vfrDataStructFields\r
+  CloseBrace \r
+  { \r
+    N2:StringIdentifier                             << _PCATCH(mCVfrVarDataTypeDB.SetNewTypeName (N2->getText()), N2); >>\r
+  }\r
+  ";"                                               << mCVfrVarDataTypeDB.DeclareDataTypeEnd (); >>\r
+  ;\r
+\r
+vfrDataStructFields :\r
+  (\r
+     dataStructField64     | \r
+        dataStructField32     | \r
+        dataStructField16     | \r
+        dataStructField8      | \r
+     dataStructFieldBool   |\r
+        dataStructFieldString |\r
+        dataStructFieldDate   | \r
+        dataStructFieldTime   |\r
+     dataStructFieldUser\r
+  )*\r
+  ;\r
+\r
+dataStructField64 :\r
+  << UINT32 ArrayNum = 0; >>\r
+  "UINT64" \r
+  N:StringIdentifier \r
+  {\r
+    OpenBracket I:Number CloseBracket               << ArrayNum = _STOU32(I->getText()); >>\r
+  }\r
+  ";"                                               << _PCATCH(mCVfrVarDataTypeDB.DataTypeAddField (N->getText(), "UINT64", ArrayNum), N); >>\r
+  ;\r
+\r
+dataStructField32 :\r
+  << UINT32 ArrayNum = 0; >>\r
+  "UINT32" \r
+  N:StringIdentifier \r
+  {\r
+    OpenBracket I:Number CloseBracket               << ArrayNum = _STOU32(I->getText()); >>\r
+  }\r
+  ";"                                               << _PCATCH(mCVfrVarDataTypeDB.DataTypeAddField (N->getText(), "UINT32", ArrayNum), N); >>\r
+  ;\r
+\r
+dataStructField16 :\r
+  << UINT32 ArrayNum = 0; >>\r
+  ("UINT16" | "CHAR16")\r
+  N:StringIdentifier \r
+  {\r
+    OpenBracket I:Number CloseBracket               << ArrayNum = _STOU32(I->getText()); >>\r
+  }\r
+  ";"                                               << _PCATCH(mCVfrVarDataTypeDB.DataTypeAddField (N->getText(), "UINT16", ArrayNum), N); >>\r
+  ;\r
+\r
+dataStructField8 :\r
+  << UINT32 ArrayNum = 0; >>\r
+  "UINT8"\r
+  N:StringIdentifier \r
+  {\r
+    OpenBracket I:Number CloseBracket               << ArrayNum = _STOU32(I->getText()); >>\r
+  }\r
+  ";"                                               << _PCATCH(mCVfrVarDataTypeDB.DataTypeAddField (N->getText(), "UINT8", ArrayNum), N); >>\r
+  ;\r
+\r
+dataStructFieldBool :\r
+  << UINT32 ArrayNum = 0; >>\r
+  "BOOLEAN"\r
+  N:StringIdentifier \r
+  {\r
+    OpenBracket I:Number CloseBracket               << ArrayNum = _STOU32(I->getText()); >>\r
+  }\r
+  ";"                                               << _PCATCH(mCVfrVarDataTypeDB.DataTypeAddField (N->getText(), "BOOLEAN", ArrayNum), N); >>\r
+  ;\r
+\r
+dataStructFieldString :\r
+  << UINT32 ArrayNum = 0; >>\r
+  "EFI_STRING_ID"\r
+  N:StringIdentifier \r
+  {\r
+    OpenBracket I:Number CloseBracket               << ArrayNum = _STOU32(I->getText()); >>\r
+  }\r
+  ";"                                               << _PCATCH(mCVfrVarDataTypeDB.DataTypeAddField (N->getText(), "EFI_STRING_ID", ArrayNum), N); >>\r
+  ;\r
+\r
+dataStructFieldDate :\r
+  << UINT32 ArrayNum = 0; >>\r
+  "EFI_HII_DATE" \r
+  N:StringIdentifier \r
+  {\r
+    OpenBracket I:Number CloseBracket               << ArrayNum = _STOU32(I->getText()); >>\r
+  }\r
+  ";"                                               << _PCATCH(mCVfrVarDataTypeDB.DataTypeAddField (N->getText(), "EFI_HII_DATE", ArrayNum), N); >>\r
+  ;\r
+\r
+dataStructFieldTime :\r
+  << UINT32 ArrayNum = 0; >>\r
+  "EFI_HII_TIME" \r
+  N:StringIdentifier \r
+  {\r
+    OpenBracket I:Number CloseBracket               << ArrayNum = _STOU32(I->getText()); >>\r
+  }\r
+  ";"                                               << _PCATCH(mCVfrVarDataTypeDB.DataTypeAddField (N->getText(), "EFI_HII_TIME", ArrayNum), N); >>\r
+  ;\r
+\r
+dataStructFieldUser :\r
+  << UINT32 ArrayNum = 0; >>\r
+  T:StringIdentifier\r
+  N:StringIdentifier\r
+  {\r
+    OpenBracket I:Number CloseBracket               << ArrayNum = _STOU32(I->getText()); >>\r
+  }\r
+  ";"                                               << _PCATCH(mCVfrVarDataTypeDB.DataTypeAddField (N->getText(), T->getText(), ArrayNum), T); >>\r
+  ;\r
+\r
+//*****************************************************************************\r
+//\r
+// the syntax of from set definition\r
+//\r
+vfrFromSetDefinition :\r
+  <<\r
+     EFI_GUID    Guid;\r
+     CIfrFormSet FSObj;\r
+     UINT16      C, SC;\r
+  >>\r
+  L:FormSet                                         << SET_LINE_INFO (FSObj, L); >>\r
+  GUID "=" \r
+  OpenBrace\r
+    G1:Number "," G2:Number "," G3:Number "," G4:Number "," G5:Number "," G6:Number "," \r
+    G7:Number "," G8:Number "," G9:Number "," G10:Number "," G11:Number\r
+  CloseBrace\r
+                                                    << \r
+                                                       _CRGUID (&Guid, G1->getText (), G2->getText (), G3->getText (), \r
+                                                                       G4->getText (), G5->getText (), G6->getText (), \r
+                                                                       G7->getText (), G8->getText (), G9->getText (), \r
+                                                                       G10->getText (), G11->getText ()); \r
+                                                       FSObj.SetGuid (&Guid);\r
+                                                    >>\r
+  ","\r
+  Title "=" "STRING_TOKEN" "\(" S1:Number "\)" ","  << FSObj.SetFormSetTitle (_STOSID(S1->getText())); >>\r
+  Help  "=" "STRING_TOKEN" "\(" S2:Number "\)" ","  << FSObj.SetHelp (_STOSID(S2->getText())); >>\r
+  {\r
+    Class "=" classDefinition[C] ","                << {CIfrClass CObj; CObj.SetClass(C);} >>\r
+  }\r
+  {\r
+    Subclass "=" subclassDefinition[SC] ","         << {CIfrSubClass SCObj; SCObj.SetSubClass(SC);} >>\r
+  }\r
+                                                    <<\r
+                                                       _DeclareStandardDefaultStorage (GET_LINENO (L));\r
+                                                       //_DeclareDefaultLinearVarStore (GET_LINENO (L));\r
+                                                    >>\r
+  vfrFormSetList\r
+  E:EndFormSet                                      << CRT_END_OP (E); >>\r
+  ";"\r
+  ;\r
+\r
+vfrFormSetList :\r
+  (\r
+    vfrFormDefinition             |\r
+    vfrStatementImage             |\r
+    vfrStatementVarStoreLinear    |\r
+    vfrStatementVarStoreEfi       |\r
+    vfrStatementVarStoreNameValue |\r
+    vfrStatementDefaultStore      |\r
+    vfrStatementDisableIfFromSet\r
+  )*\r
+  ;\r
+\r
+vfrStatementDefaultStore :\r
+  << UINT16  DefaultId = EFI_HII_DEFAULT_CLASS_STANDARD; >>\r
+  D:DefaultStore N:StringIdentifier ","\r
+  Prompt "=" "STRING_TOKEN" "\(" S:Number "\)"\r
+  {\r
+    "," Attribute "=" A:Number                      << DefaultId = _STOU16(A->getText()); >>\r
+  }\r
+                                                    << \r
+                                                       if (mCVfrDefaultStore.DefaultIdRegistered (DefaultId) == FALSE) {\r
+                                                         CIfrDefaultStore DSObj;\r
+                                                         _PCATCH(mCVfrDefaultStore.RegisterDefaultStore (DSObj.GetObjBinAddr(), N->getText(), _STOSID(S->getText()), DefaultId)), D->getLine();\r
+                                                                                                                DSObj.SetLineNo(D->getLine());\r
+                                                         DSObj.SetDefaultName (_STOSID(S->getText()));\r
+                                                         DSObj.SetDefaultId (DefaultId);\r
+                                                                                                          } else {\r
+                                                         _PCATCH(mCVfrDefaultStore.ReRegisterDefaultStoreById (DefaultId, N->getText(), _STOSID(S->getText()))), D->getLine();\r
+                                                                                                          }\r
+                                                    >>\r
+  ";"\r
+  ;\r
+\r
+vfrStatementVarStoreLinear :\r
+  <<\r
+     EFI_GUID        Guid; \r
+     CIfrVarStore    VSObj;\r
+     INT8            *TypeName;\r
+        UINT32          LineNum;\r
+     EFI_VARSTORE_ID VarStoreId = EFI_VARSTORE_ID_INVALID;\r
+     UINT32          Size;\r
+  >>\r
+  V:Varstore                                        << VSObj.SetLineNo(V->getLine()); >>\r
+  (\r
+      TN:StringIdentifier ","                       << TypeName = TN->getText(); LineNum = TN->getLine(); >>\r
+       | U8:"UINT8" ","                                << TypeName = "UINT8"; LineNum = U8->getLine(); >>\r
+       | U16:"UINT16" ","                              << TypeName = "UINT16"; LineNum = U16->getLine(); >>\r
+       | U32:"UINT32" ","                              << TypeName = "UINT32"; LineNum = U32->getLine(); >>\r
+       | U64:"UINT64" ","                              << TypeName = "UINT64"; LineNum = U64->getLine(); >>\r
+       | D:"EFI_HII_DATE" ","                          << TypeName = "EFI_HII_DATE"; LineNum = D->getLine(); >>\r
+       | T:"EFI_HII_TIME" ","                          << TypeName = "EFI_HII_TIME"; LineNum = T->getLine(); >>\r
+  )\r
+  { Key "=" Number "," }                            // Key is used to assign Varid in Framework VFR but no use in UEFI2.1 VFR\r
+  {\r
+    VarId "=" ID:Number ","                         << VarStoreId = _STOU16(ID->getText()); >>\r
+  }\r
+  Name "=" SN:StringIdentifier ","\r
+  GUID "="\r
+  OpenBrace\r
+    G1:Number "," G2:Number "," G3:Number "," G4:Number "," G5:Number "," G6:Number "," \r
+    G7:Number "," G8:Number "," G9:Number "," G10:Number "," G11:Number\r
+  CloseBrace\r
+                                                    << \r
+                                                       _CRGUID (&Guid, G1->getText (), G2->getText (), G3->getText (), \r
+                                                                       G4->getText (), G5->getText (), G6->getText (), \r
+                                                                       G7->getText (), G8->getText (), G9->getText (), \r
+                                                                       G10->getText (), G11->getText ()); \r
+                                                    >>\r
+                                                    <<\r
+                                                       _PCATCH(mCVfrDataStorage.DeclareBufferVarStore (\r
+                                                                                  SN->getText(), \r
+                                                                                  &Guid, \r
+                                                                                  &mCVfrVarDataTypeDB, \r
+                                                                                  TypeName,\r
+                                                                                                                                                                 VarStoreId\r
+                                                                                  ), LineNum);\r
+                                                    >>\r
+                                                    << \r
+                                                       VSObj.SetGuid (&Guid); \r
+                                                       _PCATCH(mCVfrDataStorage.GetVarStoreId(SN->getText(), &VarStoreId), SN);\r
+                                                       VSObj.SetVarStoreId (VarStoreId);\r
+                                                       _PCATCH(mCVfrVarDataTypeDB.GetDataTypeSize(TypeName, &Size), LineNum);\r
+                                                       VSObj.SetSize (Size);\r
+                                                       VSObj.SetName (SN->getText());\r
+                                                    >>\r
+  ";"\r
+  ;\r
+\r
+vfrStatementVarStoreEfi :\r
+  <<\r
+     EFI_GUID        Guid;\r
+     CIfrVarStoreEfi VSEObj;\r
+     EFI_VARSTORE_ID VarStoreId;\r
+     UINT32          Attr = 0;\r
+  >>\r
+  E:Efivarstore                                     << VSEObj.SetLineNo(E->getLine()); >>\r
+  SN:StringIdentifier ","\r
+  Attribute "=" vfrVarStoreEfiAttr[Attr] ( "\|" vfrVarStoreEfiAttr[Attr] )* ","\r
+                                                    << VSEObj.SetAttributes (Attr); >>\r
+  Name "=" "STRING_TOKEN" "\(" VN:Number "\)" ","\r
+  VarSize "=" N:Number ","\r
+  GUID "=" \r
+  OpenBrace\r
+    G1:Number "," G2:Number "," G3:Number "," G4:Number "," G5:Number "," G6:Number "," \r
+    G7:Number "," G8:Number "," G9:Number "," G10:Number "," G11:Number\r
+  CloseBrace\r
+                                                    << \r
+                                                       _CRGUID (&Guid, G1->getText (), G2->getText (), G3->getText (), \r
+                                                                       G4->getText (), G5->getText (), G6->getText (), \r
+                                                                       G7->getText (), G8->getText (), G9->getText (), \r
+                                                                       G10->getText (), G11->getText ()); \r
+                                                    >>\r
+                                                    << mCVfrDataStorage.DeclareEfiVarStore (SN->getText(), &Guid, _STOSID(VN->getText()), _STOU32(N->getText())); >>\r
+                                                    << \r
+                                                       VSEObj.SetGuid (&Guid);\r
+                                                       _PCATCH(mCVfrDataStorage.GetVarStoreId(SN->getText(), &VarStoreId), SN);\r
+                                                       VSEObj.SetVarStoreId (VarStoreId); \r
+                                                    >>\r
+  ";"\r
+  ;\r
+\r
+vfrVarStoreEfiAttr [UINT32 & Attr] :\r
+  N:Number                                          << $Attr |= _STOU32(N->getText()); >>\r
+  ;\r
+\r
+vfrStatementVarStoreNameValue :\r
+  <<\r
+     EFI_GUID              Guid; \r
+     CIfrVarStoreNameValue VSNVObj;\r
+     EFI_VARSTORE_ID       VarStoreId;\r
+  >>\r
+  L:NameValueVarStore                               << VSNVObj.SetLineNo(L->getLine()); >>\r
+  SN:StringIdentifier ","                           << _PCATCH(mCVfrDataStorage.DeclareNameVarStoreBegin (SN->getText()), SN); >>\r
+  (\r
+    Name "=" "STRING_TOKEN" "\(" N:Number "\)" ","  << _PCATCH(mCVfrDataStorage.NameTableAddItem (_STOSID(N->getText())), SN); >>\r
+  )+\r
+  GUID "=" \r
+  OpenBrace\r
+    G1:Number "," G2:Number "," G3:Number "," G4:Number "," G5:Number "," G6:Number "," \r
+    G7:Number "," G8:Number "," G9:Number "," G10:Number "," G11:Number\r
+  CloseBrace\r
+                                                    << \r
+                                                       _CRGUID (&Guid, G1->getText (), G2->getText (), G3->getText (), \r
+                                                                       G4->getText (), G5->getText (), G6->getText (), \r
+                                                                       G7->getText (), G8->getText (), G9->getText (), \r
+                                                                       G10->getText (), G11->getText ()); \r
+                                                    >>\r
+                                                    << _PCATCH(mCVfrDataStorage.DeclareNameVarStoreEnd (&Guid), SN); >>\r
+                                                    << \r
+                                                       VSNVObj.SetGuid (&Guid);\r
+                                                       _PCATCH(mCVfrDataStorage.GetVarStoreId(SN->getText(), &VarStoreId), SN);\r
+                                                       VSNVObj.SetVarStoreId (VarStoreId); \r
+                                                    >>\r
+  ";"\r
+  ;\r
+\r
+//\r
+// keep classDeinition and validClassNames for compatibility but not generate\r
+// any IFR object\r
+//\r
+classDefinition[UINT16 & Class] :\r
+  << $Class = 0; >>\r
+  validClassNames[$Class] ( "\|" validClassNames[$Class] )*\r
+  ;\r
+  \r
+validClassNames[UINT16 & Class] :\r
+    ClassNonDevice                                  << $Class |= EFI_NON_DEVICE_CLASS; >>\r
+  | ClassDiskDevice                                 << $Class |= EFI_DISK_DEVICE_CLASS; >>\r
+  | ClassVideoDevice                                << $Class |= EFI_VIDEO_DEVICE_CLASS; >>\r
+  | ClassNetworkDevice                              << $Class |= EFI_NETWORK_DEVICE_CLASS; >>\r
+  | ClassInputDevice                                << $Class |= EFI_INPUT_DEVICE_CLASS; >>\r
+  | ClassOnBoardDevice                              << $Class |= EFI_ON_BOARD_DEVICE_CLASS; >>\r
+  | ClassOtherDevice                                << $Class |= EFI_OTHER_DEVICE_CLASS; >>\r
+  | N:Number                                        << $Class |= _STOU16(N->getText()); >>\r
+  ;\r
+\r
+subclassDefinition[UINT16 & SubClass] :\r
+  << $SubClass = 0; >>\r
+    SubclassSetupApplication                        << $SubClass |= EFI_SETUP_APPLICATION_SUBCLASS; >>\r
+  | SubclassGeneralApplication                      << $SubClass |= EFI_GENERAL_APPLICATION_SUBCLASS; >>\r
+  | SubclassFrontPage                               << $SubClass |= EFI_FRONT_PAGE_SUBCLASS; >>\r
+  | SubclassSingleUse                               << $SubClass |= EFI_SINGLE_USE_SUBCLASS; >>\r
+  | N:Number                                        << $SubClass |= _STOU16(N->getText()); >>\r
+  ;\r
+\r
+vfrStatementDisableIfFromSet :\r
+  << CIfrDisableIf DIObj; >>\r
+  D:DisableIf                                       << DIObj.SetLineNo(D->getLine()); >>\r
+  vfrStatementExpression[0] ";"\r
+  vfrFormSetList\r
+  E:EndIf                                           << CRT_END_OP (E); >>\r
+  ";"\r
+  ;\r
+\r
+//*****************************************************************************\r
+//\r
+// the syntax of question header and statement header\r
+//\r
+vfrStatementHeader[CIfrStatementHeader *SHObj] :\r
+  Prompt "=" "STRING_TOKEN" "\(" S1:Number "\)" "," << $SHObj->SetPrompt (_STOSID(S1->getText())); >>\r
+  Help   "=" "STRING_TOKEN" "\(" S2:Number "\)"     << $SHObj->SetHelp (_STOSID(S2->getText())); >>\r
+  ;\r
+\r
+vfrQuestionHeader[CIfrQuestionHeader & QHObj, EFI_QUESION_TYPE QType = QUESTION_NORMAL]:\r
+  <<\r
+     EFI_VARSTORE_INFO Info; \r
+        EFI_QUESTION_ID   QId       = EFI_QUESTION_ID_INVALID;\r
+     INT8              *QName    = NULL;\r
+     INT8              *VarIdStr = NULL;\r
+  >>\r
+  {\r
+    Name "=" QN:StringIdentifier ","                <<\r
+                                                       QName = QN->getText();\r
+                                                       _PCATCH(mCVfrQuestionDB.FindQuestion (QName), VFR_RETURN_UNDEFINED, QN, "has already been used please used anther name");\r
+                                                    >>\r
+  }\r
+  { V:VarId "=" vfrStorageVarId[Info, VarIdStr] "," }\r
+  {\r
+    QuestionId "=" ID:Number ","                    <<\r
+                                                       QId = _STOQID(ID->getText());\r
+                                                       _PCATCH(mCVfrQuestionDB.FindQuestion (QId), VFR_RETURN_UNDEFINED, ID, "has already been used please assign another number"); \r
+                                                    >>\r
+  }\r
+                                                    << \r
+                                                       switch (QType) {\r
+                                                       case QUESTION_NORMAL:\r
+                                                         mCVfrQuestionDB.RegisterQuestion (QName, VarIdStr, QId);\r
+                                                         break;\r
+                                                                                                          case QUESTION_DATE:\r
+                                                                                                                mCVfrQuestionDB.RegisterNewDateQuestion (QName, VarIdStr, QId);\r
+                                                                                                                break;\r
+                                                                                                          case QUESTION_TIME:\r
+                                                                                                                mCVfrQuestionDB.RegisterNewTimeQuestion (QName, VarIdStr, QId);\r
+                                                                                                                break;\r
+                                                                                                          default:\r
+                                                                                                                _PCATCH(VFR_RETURN_FATAL_ERROR);\r
+                                                                                                          }\r
+                                                       $QHObj.SetQuestionId (QId);\r
+                                                       $QHObj.SetVarStoreInfo (&Info);\r
+                                                    >>\r
+  vfrStatementHeader[&$QHObj]\r
+                                                    << _SAVE_CURRQEST_VARINFO (Info); >>\r
+                                                                                                       << if (VarIdStr != NULL) delete VarIdStr; >>\r
+  ;\r
+\r
+vfrQuestionHeaderWithNoStorage[CIfrQuestionHeader *QHObj] :\r
+  <<\r
+        EFI_QUESTION_ID   QId = EFI_QUESTION_ID_INVALID;\r
+     INT8              *QName = NULL;\r
+  >>\r
+  {\r
+    Name "=" QN:StringIdentifier ","                <<\r
+                                                       QName = QN->getText();\r
+                                                       _PCATCH(mCVfrQuestionDB.FindQuestion (QName), VFR_RETURN_UNDEFINED, QN, "has already been used please used anther name");\r
+                                                    >>\r
+  }\r
+  {\r
+    QuestionId "=" ID:Number ","                    <<\r
+                                                       QId = _STOQID(ID->getText());\r
+                                                       _PCATCH(mCVfrQuestionDB.FindQuestion (QId), VFR_RETURN_UNDEFINED, ID, "redefined quesiont ID"); \r
+                                                    >>\r
+  }\r
+                                                    << \r
+                                                       mCVfrQuestionDB.RegisterQuestion (QName, NULL, QId);\r
+                                                       $QHObj->SetQuestionId (QId);\r
+                                                    >>\r
+  vfrStatementHeader[$QHObj]\r
+  ;\r
+\r
+questionheaderFlagsField[UINT8 & Flags] :\r
+    ReadOnlyFlag                                    << $Flags |= 0x01; >>\r
+  | CallBackFlag                                    << $Flags |= 0x04; >>\r
+  | ResetRequiredFlag                               << $Flags |= 0x10; >>\r
+  | OptionOnlyFlag                                  << $Flags |= 0x80; >>\r
+  ;\r
+\r
+vfrStorageVarId[EFI_VARSTORE_INFO & Info, INT8 *&QuestVarIdStr] :\r
+  <<\r
+     UINT32                Idx;\r
+     UINT32                LineNo;\r
+     EFI_VFR_VARSTORE_TYPE VarStoreType = EFI_VFR_VARSTORE_INVALID;\r
+     INT8                  *VarIdStr    = NULL;\r
+     INT8                  *VarStr      = NULL;\r
+     INT8                  *SName       = NULL;\r
+     INT8                  *TName       = NULL;\r
+  >>\r
+  (\r
+    SN1:StringIdentifier                            << SName = SN1->getText(); _STRCAT(&VarIdStr, SN1->getText()); >>\r
+    OpenBracket I1:Number CloseBracket              << Idx = _STOU32(I1->getText()); _STRCAT(&VarIdStr, "["); _STRCAT(&VarIdStr, I1->getText()); _STRCAT(&VarIdStr, "]"); >>\r
+                                                    <<\r
+                                                       _PCATCH(mCVfrDataStorage.GetVarStoreType (SName, VarStoreType), SN1);\r
+                                                       _PCATCH(mCVfrDataStorage.GetVarStoreId (SName, &$Info.mVarStoreId), SN1); \r
+                                                                                                          _PCATCH(mCVfrDataStorage.GetNameVarStoreInfo (&$Info, Idx), SN1);\r
+                                                                                                       >>\r
+  )\r
+  |\r
+  (\r
+    SN2:StringIdentifier                            << SName = SN2->getText(); _STRCAT(&VarIdStr, SName); >>\r
+                                                    <<\r
+                                                       _PCATCH(mCVfrDataStorage.GetVarStoreType (SName, VarStoreType), SN2);\r
+                                                       _PCATCH(mCVfrDataStorage.GetVarStoreId (SName, &$Info.mVarStoreId), SN2);\r
+                                                                                                          if (VarStoreType == EFI_VFR_VARSTORE_BUFFER) {\r
+                                                         _PCATCH(mCVfrDataStorage.GetBufferVarStoreDataTypeName(SName, &TName), SN2);\r
+                                                                                                                _STRCAT(&VarStr, TName);\r
+                                                                                                          }\r
+                                                    >>\r
+  \r
+    (\r
+      "."                                           <<\r
+                                                       _PCATCH(((VarStoreType != EFI_VFR_VARSTORE_BUFFER) ? VFR_RETURN_EFIVARSTORE_USE_ERROR : VFR_RETURN_SUCCESS), SN2);\r
+                                                                                                          _STRCAT(&VarIdStr, "."); _STRCAT(&VarStr, ".");\r
+                                                                                                       >>\r
+      SF:StringIdentifier                           << _STRCAT(&VarIdStr, SF->getText()); _STRCAT(&VarStr, SF->getText()); >>\r
+      {\r
+        OpenBracket I2:Number CloseBracket          << _STRCAT(&VarIdStr, "["); _STRCAT(&VarIdStr, I2->getText()); _STRCAT(&VarIdStr, "]"); >>\r
+                                                    << _STRCAT(&VarStr, "["); _STRCAT(&VarStr, I2->getText()); _STRCAT(&VarStr, "]"); >>\r
+      }\r
+    )*                                              << \r
+                                                       switch (VarStoreType) {\r
+                                                       case EFI_VFR_VARSTORE_EFI:\r
+                                                         _PCATCH(mCVfrDataStorage.GetEfiVarStoreInfo (&$Info), SN2);\r
+                                                         break;\r
+                                                       case EFI_VFR_VARSTORE_BUFFER:\r
+                                                         _PCATCH(mCVfrVarDataTypeDB.GetDataFieldInfo (VarStr, $Info.mInfo.mVarOffset, $Info.mVarType, $Info.mVarTotalSize), SN2->getLine());\r
+                                                         //_PCATCH(mCVfrDataStorage.BufferVarStoreRequestElementAdd (SName, Info), SN2);\r
+                                                         break;\r
+                                                       case EFI_VFR_VARSTORE_NAME:\r
+                                                       default: break;\r
+                                                       }\r
+\r
+                                                       QuestVarIdStr = VarIdStr;\r
+                                                       if (VarStr != NULL) {delete VarStr;}\r
+                                                    >>\r
+  )\r
+  ;\r
+\r
+vfrQuestionDataFieldName [EFI_QUESTION_ID &QId, UINT32 &Mask, INT8 *&VarIdStr, UINT32 &LineNo] :\r
+                                                    << VarIdStr = NULL; LineNo = 0; >>\r
+  (\r
+    SN1:StringIdentifier                            << _STRCAT(&VarIdStr, SN1->getText()); LineNo = SN1->getLine(); >>\r
+    OpenBracket I1:Number CloseBracket              << _STRCAT(&VarIdStr, "["); _STRCAT(&VarIdStr, I1->getText()); _STRCAT(&VarIdStr, "]"); >>\r
+                                                    << mCVfrQuestionDB.GetQuestionId (NULL, VarIdStr, $QId, $Mask); >>\r
+  )\r
+  |\r
+  (\r
+    SN2:StringIdentifier                            << _STRCAT (&VarIdStr, SN2->getText()); LineNo = SN2->getLine(); >>\r
+    (\r
+      "."                                           << _STRCAT (&VarIdStr, "."); >>\r
+      SF:StringIdentifier                           << _STRCAT(&VarIdStr, SF->getText()); >>\r
+      {\r
+        OpenBracket I2:Number CloseBracket          << _STRCAT(&VarIdStr, "["); _STRCAT(&VarIdStr, I2->getText()); _STRCAT(&VarIdStr, "]"); >>\r
+      }\r
+    )*\r
+                                                    << mCVfrQuestionDB.GetQuestionId (NULL, VarIdStr, $QId, $Mask); >>\r
+  )\r
+  ;\r
+\r
+vfrConstantValueField[UINT8 Type] > [EFI_IFR_TYPE_VALUE Value] :\r
+    N1:Number                                       << \r
+                                                       switch ($Type) {\r
+                                                       case EFI_IFR_TYPE_NUM_SIZE_8 :\r
+                                                                                                            $Value.u8     = _STOU8(N1->getText());\r
+                                                                                                                break;\r
+                                                                                                          case EFI_IFR_TYPE_NUM_SIZE_16 :\r
+                                                                                                            $Value.u16    = _STOU16(N1->getText());\r
+                                                                                                                break;\r
+                                                                                                          case EFI_IFR_TYPE_NUM_SIZE_32 :\r
+                                                                                                            $Value.u32    = _STOU32(N1->getText());\r
+                                                                                                                break;\r
+                                                                                                          case EFI_IFR_TYPE_NUM_SIZE_64 :\r
+                                                                                                            $Value.u64    = _STOU64(N1->getText());\r
+                                                                                                                break;\r
+                                                                                                          case EFI_IFR_TYPE_BOOLEAN :\r
+                                                                                                            $Value.b      = _STOU8(N1->getText());\r
+                                                                                                                break;\r
+                                                                                                          case EFI_IFR_TYPE_STRING :\r
+                                                                                                            $Value.string = _STOU16(N1->getText());\r
+                                                                                                                break;\r
+                                                                                                          case EFI_IFR_TYPE_TIME :\r
+                                                                                                          case EFI_IFR_TYPE_DATE :\r
+                                                                                                          default :\r
+                                                                                                                break;\r
+                                                                                                          } \r
+                                                    >>\r
+  | B1:True                                         << $Value.b      = TRUE; >>\r
+  | B2:False                                        << $Value.b      = FALSE; >>\r
+  | O1:One                                          << $Value.u8     = _STOU8(O1->getText()); >>\r
+  | O2:Ones                                         << $Value.u64    = _STOU64(O2->getText()); >>\r
+  | Z:Zero                                          << $Value.u8     = _STOU8(Z->getText()); >>\r
+  | HOUR:Number ":" MINUTE:Number ":" SECOND:Number << $Value.time   = _STOT(HOUR->getText(), MINUTE->getText(), SECOND->getText()); >>\r
+  | YEAR:Number "/" MONTH:Number "/" DAY:Number     << $Value.date   = _STOD(YEAR->getText(), MONTH->getText(), DAY->getText()); >>\r
+  | "STRING_TOKEN" "\(" S1:Number "\)"              << $Value.string = _STOSID(S1->getText()); >>\r
+  ;\r
+\r
+//*****************************************************************************\r
+//\r
+// the syntax of form definition\r
+//\r
+vfrFormDefinition :\r
+  << CIfrForm FObj; >>\r
+  F:Form                                            << FObj.SetLineNo(F->getLine()); >>\r
+  FormId "=" S1:Number ","                          << _PCATCH(FObj.SetFormId (_STOFID(S1->getText())), S1); >>\r
+  Title "=" "STRING_TOKEN" "\(" S2:Number "\)" ";"  << FObj.SetFormTitle (_STOSID(S2->getText())); >>\r
+  (\r
+    vfrStatementImage                        |\r
+    vfrStatementLocked                       |\r
+    vfrStatementRules                        |\r
+    vfrStatementDefault                      |\r
+    vfrStatementStat                         |\r
+    vfrStatementQuestions                    |\r
+    vfrStatementConditional                  |\r
+    vfrStatementLabel                        |\r
+    vfrStatementBanner                       \r
+    // Just for framework vfr compatibility\r
+    //vfrStatementInvalid\r
+  )*\r
+  E:EndForm                                         << CRT_END_OP (E); >>\r
+  ";"\r
+  ;\r
+\r
+vfrStatementRules : \r
+  << CIfrRule RObj; >>\r
+  R:Rule                                            << RObj.SetLineNo(R->getLine()); >>\r
+  S1:StringIdentifier ","                           <<\r
+                                                       mCVfrRulesDB.RegisterRule (S1->getText());\r
+                                                       RObj.SetRuleId (mCVfrRulesDB.GetRuleId(S1->getText())); \r
+                                                    >>\r
+  vfrStatementExpression[0]\r
+  E:EndRule                                         << CRT_END_OP (E); >>\r
+  ";"\r
+  ;\r
+\r
+vfrStatementDefault :\r
+  <<\r
+     BOOLEAN               IsExp         = FALSE;\r
+     EFI_IFR_TYPE_VALUE    Val; \r
+     CIfrDefault           DObj;\r
+     EFI_DEFAULT_ID        DefaultId     = EFI_HII_DEFAULT_CLASS_STANDARD;\r
+     INT8                  *VarStoreName = NULL;\r
+     EFI_VFR_VARSTORE_TYPE VarStoreType  = EFI_VFR_VARSTORE_INVALID;\r
+  >>\r
+  D:Default                                         << DObj.SetLineNo(D->getLine()); >>\r
+  (\r
+    (\r
+        vfrStatementValue ","                       << IsExp = TRUE; DObj.SetScope (1); >>\r
+      | "=" vfrConstantValueField[_GET_CURRQEST_DATATYPE()] > [Val] ","  \r
+                                                    << DObj.SetType (_GET_CURRQEST_DATATYPE()); DObj.SetValue(Val); >>\r
+    )\r
+    {\r
+      DefaultStore "=" SN:StringIdentifier ","      << _PCATCH(mCVfrDefaultStore.GetDefaultId (SN->getText(), &DefaultId), SN); DObj.SetDefaultId (DefaultId); >>\r
+    }\r
+                                                    << \r
+                                                                                                          _PCATCH(mCVfrDataStorage.GetVarStoreName (_GET_CURRQEST_VARTINFO().mVarStoreId, &VarStoreName), D->getLine());\r
+                                                                                                          _PCATCH(mCVfrDataStorage.GetVarStoreType (VarStoreName, VarStoreType), D->getLine());\r
+                                                                                                          if ((IsExp == FALSE) && (VarStoreType == EFI_VFR_VARSTORE_BUFFER)) { \r
+                                                                                                            _PCATCH(mCVfrDefaultStore.BufferVarStoreAltConfigAdd (\r
+                                                                                                                                                    DefaultId, \r
+                                                                                                                                                                        _GET_CURRQEST_VARTINFO(), \r
+                                                                                                                                                                        VarStoreName, \r
+                                                                                                                                                                        _GET_CURRQEST_DATATYPE (), \r
+                                                                                                                                                                        Val), D->getLine()); \r
+                                                                                                          }\r
+                                                                                                       >>\r
+  )\r
+  ;\r
+\r
+vfrStatementStat :\r
+  vfrStatementSubTitle        | \r
+  vfrStatementStaticText      |\r
+  vfrStatementCrossReference\r
+  ;\r
+\r
+vfrStatementQuestions :\r
+  vfrStatementBooleanType     |\r
+  vfrStatementDate            |\r
+  vfrStatementNumericType     |\r
+  vfrStatementStringType      |\r
+  vfrStatementOrderedList     |\r
+  vfrStatementTime\r
+  ;\r
+\r
+vfrStatementConditional :\r
+  vfrStatementDisableIfStat   |\r
+  vfrStatementSuppressIfStat  |\r
+  vfrStatementGrayOutIfStat\r
+  ;\r
+\r
+vfrStatementInvalid :\r
+                                                       << _CRT_OP (FALSE); >>\r
+  (\r
+    vfrStatementInvalidHidden          |\r
+    vfrStatementInvalidInconsistentIf  |\r
+    vfrStatementInvalidInventory       |\r
+    vfrStatementInvalidSaveRestoreDefaults\r
+  )\r
+                                                       << _CRT_OP (TRUE); >>\r
+  ;\r
+\r
+flagsField :\r
+  Number | InteractiveFlag | ManufacturingFlag | DefaultFlag | \r
+  NVAccessFlag | ResetRequiredFlag | LateCheckFlag\r
+  ;\r
+\r
+vfrStatementValue :\r
+  << CIfrValue VObj; >>\r
+  V:Value                                              << VObj.SetLineNo(V->getLine()); >>\r
+  "=" vfrStatementExpression[0]\r
+  ;\r
+\r
+vfrStatementSubTitle :\r
+  << CIfrSubtitle SObj; >>\r
+  L:Subtitle                                           << SObj.SetLineNo(L->getLine()); >>\r
+  Text "=" "STRING_TOKEN" "\(" S:Number "\)"           << SObj.SetPrompt (_STOSID(S->getText())); >>\r
+  {\r
+    "," FLAGS "=" vfrSubtitleFlags[SObj]\r
+  }\r
+  { vfrStatementStatTagList "," }\r
+  E:";"                                                << CRT_END_OP (E); >>\r
+  ;\r
+\r
+vfrSubtitleFlags [CIfrSubtitle & SObj] :\r
+  << UINT8 LFlags = 0; >>\r
+  subtitleFlagsField[LFlags] ( "\|" subtitleFlagsField[LFlags] )*\r
+                                                       << _PCATCH(SObj.SetFlags (LFlags)); >>\r
+  ;\r
+\r
+subtitleFlagsField [UINT8 & Flags] :\r
+    N:Number                                           << $Flags |= _STOU8(N->getText()); >>\r
+  | "HORIZONTAL"                                       << $Flags |= 0x01; >>\r
+  ;\r
+\r
+vfrStatementStaticText :\r
+  << \r
+     UINT8           Flags   = 0;\r
+     EFI_QUESTION_ID QId     = EFI_QUESTION_ID_INVALID;\r
+     EFI_STRING_ID   TxtTwo  = EFI_STRING_ID_INVALID;\r
+   >>\r
+  T:Text\r
+  Help "=" "STRING_TOKEN" "\(" S1:Number "\)" ","\r
+  Text "=" "STRING_TOKEN" "\(" S2:Number "\)"\r
+  {\r
+    "," Text "=" "STRING_TOKEN" "\(" S3:Number "\)"    << TxtTwo = _STOSID(S3->getText()); >>\r
+  }\r
+  {\r
+    "," F:FLAGS "=" staticTextFlagsField[Flags] ( "\|" staticTextFlagsField[Flags] )*\r
+    "," Key "=" KN:Number\r
+  }\r
+                                                       <<\r
+                                                          if (Flags & EFI_IFR_FLAG_CALLBACK) {\r
+                                                            CIfrAction AObj;\r
+                                                            mCVfrQuestionDB.RegisterQuestion (NULL, NULL, QId);\r
+                                                            AObj.SetQuestionId (QId);\r
+                                                            AObj.SetPrompt (_STOSID(S2->getText()));\r
+                                                            AObj.SetHelp (_STOSID(S1->getText()));\r
+                                                            _PCATCH(AObj.SetFlags (Flags), F->getLine());\r
+                                                            AssignQuestionKey (AObj, KN);\r
+                                                            CRT_END_OP (T);\r
+                                                          } else {\r
+                                                                                                                   CIfrText TObj;\r
+                                                                                                                   TObj.SetLineNo (T->getLine());\r
+                                                                                                                       TObj.SetHelp (_STOSID(S1->getText()));\r
+                                                                                                                       TObj.SetPrompt (_STOSID(S2->getText()));\r
+                                                                                                                       TObj.SetTextTwo (TxtTwo);\r
+                                                                                                                 }\r
+                                                       >>\r
+  { "," vfrStatementStatTagList }\r
+  ";"\r
+  ;\r
+\r
+staticTextFlagsField[UINT8 & HFlags] :\r
+    N:Number                                           << _PCATCH(_STOU8(N->getText()) == 0 ? VFR_RETURN_SUCCESS : VFR_RETURN_UNSUPPORTED, N->getLine()); >>\r
+  | questionheaderFlagsField[HFlags]\r
+  ;\r
+\r
+vfrStatementCrossReference :\r
+  vfrStatementGoto            |\r
+  vfrStatementResetButton\r
+  ;\r
+\r
+vfrStatementGoto :\r
+  << \r
+     UINT8               RefType = 1;\r
+     EFI_STRING_ID       DevPath;\r
+     EFI_GUID            FSId;\r
+     EFI_FORM_ID         FId;\r
+        EFI_QUESTION_ID     QId    = EFI_QUESTION_ID_INVALID;\r
+     UINT32              BitMask;\r
+     CIfrQuestionHeader  *QHObj = NULL;\r
+     CIfrRef             *R1Obj = NULL;\r
+     CIfrRef2            *R2Obj = NULL;\r
+     CIfrRef3            *R3Obj = NULL;\r
+     CIfrRef4            *R4Obj = NULL;\r
+  >>\r
+  G:Goto\r
+  (\r
+    (\r
+      DevicePath "=" "STRING_TOKEN" "\(" P:Number "\)" ","\r
+      FormSetGuid "=" \r
+        OpenBrace\r
+          G11:Number "," G12:Number "," G13:Number "," G14:Number "," G15:Number "," G16:Number "," \r
+          G17:Number "," G18:Number "," G19:Number "," G110:Number "," G111:Number\r
+        CloseBrace ","\r
+      FormId "=" F1:Number ","\r
+      Question "=" QN1:Number ","\r
+                                                       << \r
+                                                          RefType = 4;\r
+                                                          _CRGUID (&FSId, G11->getText (), G12->getText (), G13->getText (), \r
+                                                                          G14->getText (), G15->getText (), G16->getText (), \r
+                                                                          G17->getText (), G18->getText (), G19->getText (), \r
+                                                                          G110->getText (), G111->getText ()); \r
+                                                          DevPath = _STOSID(P->getText()); \r
+                                                          FId = _STOFID(F1->getText());\r
+                                                          QId = _STOQID(QN1->getText());\r
+                                                       >>\r
+    )\r
+    |\r
+    (\r
+      FormSetGuid "="\r
+        OpenBrace\r
+          G21:Number "," G22:Number "," G23:Number "," G24:Number "," G25:Number "," G26:Number "," \r
+          G27:Number "," G28:Number "," G29:Number "," G210:Number "," G211:Number\r
+        CloseBrace ","\r
+      FormId "=" F2:Number ","\r
+      Question "=" QN2:Number ","\r
+                                                       <<\r
+                                                          RefType = 3;\r
+                                                          _CRGUID (&FSId, G21->getText (), G22->getText (), G23->getText (), \r
+                                                                          G24->getText (), G25->getText (), G26->getText (), \r
+                                                                          G27->getText (), G28->getText (), G29->getText (), \r
+                                                                          G210->getText (), G211->getText ()); \r
+                                                          FId = _STOFID(F2->getText());\r
+                                                          QId = _STOQID(QN2->getText());\r
+                                                       >>\r
+    )\r
+    |\r
+    (\r
+      FormId "=" F3:Number ","                         << RefType = 2; FId = _STOFID(F3->getText()); >>\r
+      Question "=" \r
+      (\r
+          QN3:StringIdentifier ","                     << mCVfrQuestionDB.GetQuestionId (QN3->getText (), NULL, QId, BitMask); >>\r
+        | QN4:Number ","                               << QId = _STOQID(QN4->getText()); >>\r
+      )\r
+    )\r
+    |\r
+    (\r
+      F4:Number ","                                    << \r
+                                                          RefType = 1;\r
+                                                          FId = _STOFID(F4->getText());\r
+                                                       >>\r
+    )\r
+  )\r
+                                                       <<\r
+                                                          switch (RefType) {\r
+                                                          case 4:\r
+                                                            {\r
+                                                              R4Obj = new CIfrRef4; \r
+                                                              QHObj = R4Obj; \r
+                                                              R4Obj->SetLineNo(G->getLine()); \r
+                                                              R4Obj->SetDevicePath (DevPath); \r
+                                                              R4Obj->SetFormSetId (FSId); \r
+                                                              R4Obj->SetFormId (FId); \r
+                                                              R4Obj->SetQuestionId (QId); \r
+                                                              break;\r
+                                                            }\r
+                                                          case 3:\r
+                                                            {\r
+                                                              R3Obj = new CIfrRef3; \r
+                                                              QHObj = R3Obj; \r
+                                                              R3Obj->SetLineNo(G->getLine()); \r
+                                                              R3Obj->SetFormSetId (FSId); \r
+                                                              R3Obj->SetFormId (FId); \r
+                                                              R3Obj->SetQuestionId (QId); \r
+                                                              break;\r
+                                                            }\r
+                                                          case 2:\r
+                                                            {\r
+                                                              R2Obj = new CIfrRef2; \r
+                                                              QHObj = R2Obj; \r
+                                                              R2Obj->SetLineNo(G->getLine()); \r
+                                                              R2Obj->SetFormId (FId); \r
+                                                              _PCATCH(R2Obj->SetQuestionId (QId), QN3);\r
+                                                              break;\r
+                                                            }\r
+                                                          case 1:\r
+                                                            {\r
+                                                              R1Obj = new CIfrRef;\r
+                                                              QHObj = R1Obj;\r
+                                                              R1Obj->SetLineNo(G->getLine());\r
+                                                              R1Obj->SetFormId (FId);\r
+                                                              break;\r
+                                                            }\r
+                                                          default: break;\r
+                                                          }\r
+                                                       >>\r
+  vfrQuestionHeaderWithNoStorage[QHObj]\r
+  { "," vfrStatementStatTagList }\r
+  { "," F:FLAGS  "=" vfrGotoFlags[QHObj, F->getLine()] }\r
+  {\r
+    "," Key "=" KN:Number                              << AssignQuestionKey (*QHObj, KN); >>\r
+  }\r
+  ";"                                                  << if (R1Obj != NULL) {delete R1Obj;} if (R2Obj != NULL) {delete R2Obj;} if (R3Obj != NULL) {delete R3Obj;} if (R4Obj != NULL) {delete R4Obj;} >>\r
+  ;\r
+\r
+vfrGotoFlags [CIfrQuestionHeader *QHObj, UINT32 LineNum] :\r
+  << UINT8 HFlags = 0; >>\r
+  gotoFlagsField[HFlags] ( "\|" gotoFlagsField[HFlags] )*\r
+                                                       << _PCATCH(QHObj->SetFlags (HFlags), LineNum); >>\r
+  ;\r
+\r
+gotoFlagsField[UINT8 & HFlags] :\r
+    N:Number                                           << _PCATCH(_STOU8(N->getText()) == 0 ? VFR_RETURN_SUCCESS : VFR_RETURN_UNSUPPORTED, N->getLine()); >>\r
+  | questionheaderFlagsField[HFlags]\r
+  ;\r
+\r
+getStringId :\r
+  "STRING_TOKEN" "\("\r
+  IdVal:Number\r
+  "\)"\r
+  ;\r
+\r
+vfrStatementResetButton :\r
+  <<\r
+     CIfrResetButton RBObj; \r
+     UINT16          DefaultId;\r
+  >>\r
+  L:ResetButton                                        << RBObj.SetLineNo(L->getLine()); >>\r
+  DefaultStore \r
+  "=" N:StringIdentifier ","                           << \r
+                                                          _PCATCH(mCVfrDefaultStore.GetDefaultId (N->getText(), &DefaultId), N->getLine());\r
+                                                          RBObj.SetDefaultId (DefaultId);\r
+                                                       >>\r
+  vfrStatementHeader[&RBObj] ","\r
+  { vfrStatementStatTagList "," }\r
+  E:EndResetButton                                     << CRT_END_OP (E); >>\r
+  ";"\r
+  ;\r
+\r
+vfrStatementBooleanType :\r
+  vfrStatementCheckBox |\r
+  vfrStatementAction\r
+  ;\r
+\r
+//*****************************************************\r
+// Syntax of checkbox\r
+//\r
+// Example:\r
+//   checkbox\r
+//     varid       = MySTestData.mField1,\r
+//     prompt      = STRING_TOKEN(STR_CHECK_BOX_PROMPT),\r
+//     help        = STRING_TOKEN(STR_CHECK_BOX_HELP),\r
+//     flags       = CHECKBOX_DEFAULT | CALLBACK,\r
+//     default value = TRUE, defaultstore = MyDefaultStore, \r
+//   endcheckbox;\r
+//\r
+vfrStatementCheckBox :\r
+  <<\r
+     CIfrCheckBox CBObj;\r
+  >>\r
+  L:CheckBox                                           << CBObj.SetLineNo(L->getLine()); >>\r
+  vfrQuestionHeader[CBObj] ","\r
+  { F:FLAGS "=" vfrCheckBoxFlags[CBObj, F->getLine()] "," }\r
+  {\r
+    Key "=" KN:Number  ","                             << AssignQuestionKey (CBObj, KN); >>\r
+  }\r
+  vfrStatementQuestionOptionList\r
+  E:EndCheckBox                                        << CRT_END_OP (E); >>\r
+  ";"\r
+  ; \r
+\r
+vfrCheckBoxFlags [CIfrCheckBox & CBObj, UINT32 LineNum] :\r
+  <<\r
+     UINT8 LFlags = 0;\r
+     UINT8 HFlags = 0;\r
+  >>\r
+  checkboxFlagsField[LFlags, HFlags] ( "\|" checkboxFlagsField[LFlags, HFlags] )*\r
+                                                       << _PCATCH(CBObj.SetFlags (HFlags, LFlags), LineNum); >>\r
+  ;\r
+\r
+checkboxFlagsField[UINT8 & LFlags, UINT8 & HFlags] :\r
+    N:Number                                           << _PCATCH(_STOU8(N->getText()) == 0 ? VFR_RETURN_SUCCESS : VFR_RETURN_UNSUPPORTED, N->getLine()); >>\r
+  | "CHECKBOX_DEFAULT"                                 << $LFlags |= 0x01; >>\r
+  | "CHECKBOX_DEFAULT_MFG"                             << $LFlags |= 0x02; >>\r
+  | questionheaderFlagsField[HFlags]\r
+  ;\r
+\r
+//*****************************************************\r
+// Syntax of action\r
+//\r
+// Example:\r
+//   action\r
+//     prompt      = STRING_TOKEN(STR_ACTION_PROMPT),\r
+//     help        = STRING_TOKEN(STR_ACTION_HELP),\r
+//     flags       = CALLBACK,\r
+//     config      = STRING_TOKEN(STR_ACTION_CONFIG),\r
+//   endaction;\r
+//\r
+vfrStatementAction :\r
+  << CIfrAction AObj; >>\r
+  L:Action                                             << AObj.SetLineNo(L->getLine()); >>\r
+  vfrQuestionHeaderWithNoStorage[&AObj] ","\r
+  { F:FLAGS "=" vfrActionFlags[AObj, F->getLine()] "," }\r
+  Config "=" "STRING_TOKEN" "\(" S:Number "\)" ","     << AObj.SetQuestionConfig (_STOSID(S->getText())); >>\r
+  vfrStatementQuestionTagList\r
+  E:EndAction                                          << CRT_END_OP (E); >>\r
+  ";"\r
+  ;\r
+\r
+vfrActionFlags[CIfrAction & AObj, UINT32 LineNum] :\r
+  << UINT8 HFlags = 0; >>\r
+  actionFlagsField[HFlags] ( "\|" actionFlagsField[HFlags] )*\r
+                                                       << _PCATCH(AObj.SetFlags (HFlags), LineNum); >>\r
+  ;\r
+\r
+actionFlagsField[UINT8 & HFlags] :\r
+    N:Number                                           << _PCATCH(_STOU8(N->getText()) == 0 ? VFR_RETURN_SUCCESS : VFR_RETURN_UNSUPPORTED, N->getLine()); >>\r
+  | questionheaderFlagsField[HFlags]\r
+  ;\r
+\r
+vfrStatementDate :\r
+  <<\r
+     EFI_QUESTION_ID    QId          = EFI_QUESTION_ID_INVALID;\r
+     INT8               *VarIdStr[3] = {NULL, };\r
+     CIfrDate           DObj;\r
+     EFI_IFR_TYPE_VALUE Val;\r
+  >>\r
+  L:Date                                               << DObj.SetLineNo(L->getLine()); >>\r
+  (\r
+    (\r
+      vfrQuestionHeader[DObj, QUESTION_DATE] ","\r
+         { F:FLAGS "=" vfrDateFlags[DObj, F->getLine()] "," }\r
+      vfrStatementQuestionOptionList\r
+    )\r
+    |\r
+    (\r
+      Year VarId "=" D1:StringIdentifier "." D1Y:StringIdentifier ","\r
+                                                       << _STRCAT(&VarIdStr[0], D1->getText()); _STRCAT(&VarIdStr[0], "."); _STRCAT(&VarIdStr[0], D1Y->getText()); >>\r
+      Prompt "=" "STRING_TOKEN" "\(" YP:Number "\)" ","\r
+      Help   "=" "STRING_TOKEN" "\(" YH:Number "\)" ","\r
+      minMaxDateStepDefault[Val.date, 0]\r
+\r
+      Month VarId "=" D2:StringIdentifier "." D2M:StringIdentifier ","\r
+                                                       << _STRCAT(&VarIdStr[1], D2->getText()); _STRCAT(&VarIdStr[1], "."); _STRCAT(&VarIdStr[1], D2M->getText()); >>\r
+      Prompt "=" "STRING_TOKEN" "\(" MP:Number "\)" ","\r
+      Help   "=" "STRING_TOKEN" "\(" MH:Number "\)" ","\r
+      minMaxDateStepDefault[Val.date, 1]\r
+\r
+      Day VarId "=" D3:StringIdentifier "." D3D:StringIdentifier ","\r
+                                                       << _STRCAT(&VarIdStr[2], D3->getText()); _STRCAT(&VarIdStr[2], "."); _STRCAT(&VarIdStr[2], D3D->getText()); >>\r
+      Prompt "=" "STRING_TOKEN" "\(" DP:Number "\)" ","\r
+      Help   "=" "STRING_TOKEN" "\(" DH:Number "\)" ","\r
+      minMaxDateStepDefault[Val.date, 2]\r
+                                                       <<\r
+                                                          mCVfrQuestionDB.RegisterOldDateQuestion (VarIdStr[0], VarIdStr[1], VarIdStr[2], QId); \r
+                                                          DObj.SetQuestionId (QId);\r
+                                                          DObj.SetFlags (EFI_IFR_QUESTION_FLAG_DEFAULT, QF_DATE_STORAGE_TIME);\r
+                                                                                                                 DObj.SetPrompt (_STOSID(YP->getText()));\r
+                                                                                                                 DObj.SetHelp (_STOSID(YH->getText()));\r
+                                                                                                                 if (VarIdStr[0] != NULL) { delete VarIdStr[0]; } if (VarIdStr[1] != NULL) { delete VarIdStr[1]; } if (VarIdStr[2] != NULL) { delete VarIdStr[2]; }\r
+                                                       >>\r
+                                                          << {CIfrDefault DObj(EFI_HII_DEFAULT_CLASS_STANDARD, EFI_IFR_TYPE_DATE, Val);} >>\r
+      ( vfrStatementInconsistentIf )*\r
+    )\r
+  )\r
+  E:EndDate                                            << CRT_END_OP (E); >>\r
+  ";"\r
+  ;\r
+\r
+minMaxDateStepDefault[EFI_HII_DATE & D, UINT8 KeyValue] :\r
+  Minimum   "=" Number ","\r
+  Maximum   "=" Number ","\r
+  { "step"    "=" Number "," }\r
+  {\r
+    "default" "=" N:Number ","                         <<\r
+                                                          switch (KeyValue) {\r
+                                                          case 0: D.Year  = _STOU16(N->getText()); break; \r
+                                                          case 1: D.Month = _STOU8(N->getText()); break; \r
+                                                          case 2: D.Day   = _STOU8(N->getText()); break;\r
+                                                                                                                 } \r
+                                                       >>\r
+  }\r
+  ;\r
+\r
+vfrDateFlags [CIfrDate & DObj, UINT32 LineNum] :\r
+  << UINT8 LFlags = 0; >>\r
+  dateFlagsField[LFlags] ( "\|" dateFlagsField[LFlags] )*\r
+                                                       << _PCATCH(DObj.SetFlags (EFI_IFR_QUESTION_FLAG_DEFAULT, LFlags), LineNum); >>\r
+  ;\r
+\r
+dateFlagsField [UINT8 & Flags] :\r
+    N:Number                                           << $Flags |= _STOU8(N->getText()); >>\r
+  | "YEAR_SUPPRESS"                                    << $Flags |= 0x01; >>\r
+  | "MONTH_SUPPRESS"                                   << $Flags |= 0x02; >>\r
+  | "DAY_SUPPRESS"                                     << $Flags |= 0x04; >>\r
+  | "STORAGE_NORMAL"                                   << $Flags |= 0x00; >>\r
+  | "STORAGE_TIME"                                     << $Flags |= 0x10; >>\r
+  | "STORAGE_WAKEUP"                                   << $Flags |= 0x20; >>\r
+  ;\r
+\r
+vfrStatementNumericType :\r
+  vfrStatementNumeric   |\r
+  vfrStatementOneOf\r
+  ;\r
+\r
+vfrSetMinMaxStep[CIfrMinMaxStepData & MMSDObj] :\r
+  <<\r
+     UINT64 MaxU8 = 0, MinU8 = 0, StepU8 = 0;\r
+     UINT32 MaxU4 = 0, MinU4 = 0, StepU4 = 0;\r
+     UINT16 MaxU2 = 0, MinU2 = 0, StepU2 = 0;\r
+     UINT8  MaxU1 = 0, MinU1 = 0, StepU1 = 0;\r
+  >>\r
+  Minimum   "=" I:Number ","\r
+                                                       <<\r
+                                                          switch (_GET_CURRQEST_DATATYPE ()) {\r
+                                                          case EFI_IFR_TYPE_NUM_SIZE_64 : MinU8 = _STOU64(I->getText()); break;\r
+                                                          case EFI_IFR_TYPE_NUM_SIZE_32 : MinU4 = _STOU32(I->getText()); break;\r
+                                                          case EFI_IFR_TYPE_NUM_SIZE_16 : MinU2 = _STOU16(I->getText()); break;\r
+                                                          case EFI_IFR_TYPE_NUM_SIZE_8 :  MinU1 = _STOU8(I->getText());  break;\r
+                                                          }\r
+                                                                                                          >>\r
+  Maximum   "=" A:Number ","\r
+                                                       <<\r
+                                                          switch (_GET_CURRQEST_DATATYPE ()) {\r
+                                                          case EFI_IFR_TYPE_NUM_SIZE_64 : MaxU8 = _STOU64(A->getText()); break;\r
+                                                          case EFI_IFR_TYPE_NUM_SIZE_32 : MaxU4 = _STOU32(A->getText()); break;\r
+                                                          case EFI_IFR_TYPE_NUM_SIZE_16 : MaxU2 = _STOU16(A->getText()); break;\r
+                                                          case EFI_IFR_TYPE_NUM_SIZE_8 :  MaxU1 = _STOU8(A->getText());  break;\r
+                                                          }\r
+                                                                                                          >>\r
+  {\r
+    STEP    "=" S:Number ","\r
+                                                       <<\r
+                                                          switch (_GET_CURRQEST_DATATYPE ()) {\r
+                                                          case EFI_IFR_TYPE_NUM_SIZE_64 : StepU8 = _STOU64(S->getText()); break;\r
+                                                          case EFI_IFR_TYPE_NUM_SIZE_32 : StepU4 = _STOU32(S->getText()); break;\r
+                                                          case EFI_IFR_TYPE_NUM_SIZE_16 : StepU2 = _STOU16(S->getText()); break;\r
+                                                          case EFI_IFR_TYPE_NUM_SIZE_8 :  StepU1 = _STOU8(S->getText());  break;\r
+                                                          }\r
+                                                                                                          >>\r
+  }\r
+                                                       <<\r
+                                                          switch (_GET_CURRQEST_DATATYPE ()) {\r
+                                                          case EFI_IFR_TYPE_NUM_SIZE_64 : $MMSDObj.SetMinMaxStepData (MinU8, MaxU8, StepU8); break;\r
+                                                          case EFI_IFR_TYPE_NUM_SIZE_32 : $MMSDObj.SetMinMaxStepData (MinU4, MaxU4, StepU4); break;\r
+                                                          case EFI_IFR_TYPE_NUM_SIZE_16 : $MMSDObj.SetMinMaxStepData (MinU2, MaxU2, StepU2); break;\r
+                                                          case EFI_IFR_TYPE_NUM_SIZE_8 :  $MMSDObj.SetMinMaxStepData (MinU1, MaxU1, StepU1);  break;\r
+                                                          }\r
+                                                                                                          >>\r
+  ;\r
+\r
+vfrStatementNumeric :\r
+  <<\r
+     CIfrNumeric NObj;\r
+  >>\r
+  L:Numeric                                            << NObj.SetLineNo(L->getLine()); >>\r
+  vfrQuestionHeader[NObj] ","                          << _PCATCH(NObj.SetFlags (NObj.FLAGS(), _GET_CURRQEST_DATATYPE()), L->getLine()); >>\r
+  { F:FLAGS "=" vfrNumericFlags[NObj, F->getLine()] "," }\r
+  {\r
+    Key   "=" KN:Number ","                            << AssignQuestionKey (NObj, KN); >>\r
+  }\r
+  vfrSetMinMaxStep[NObj]\r
+  vfrStatementQuestionOptionList\r
+  E:EndNumeric                                         << CRT_END_OP (E); >>\r
+  ";"\r
+  ;\r
+\r
+vfrNumericFlags [CIfrNumeric & NObj, UINT32 LineNum] :\r
+  <<\r
+     UINT8 LFlags = _GET_CURRQEST_DATATYPE();\r
+     UINT8 HFlags = 0;\r
+  >>\r
+  numericFlagsField[HFlags, LFlags] ( "\|" numericFlagsField[HFlags, LFlags] )*\r
+                                                       << _PCATCH(NObj.SetFlags (HFlags, LFlags), LineNum); >>\r
+  ;\r
+\r
+numericFlagsField [UINT8 & HFlags, UINT8 & LFlags] :\r
+    N:Number                                           << _PCATCH(_STOU8(N->getText()) == 0 ? VFR_RETURN_SUCCESS : VFR_RETURN_UNSUPPORTED, N->getLine()); >>\r
+  | "DISPLAY_INT_DEC"                                  << $LFlags |= 0x00; >>\r
+  | "DISPLAY_UINT_DEC"                                 << $LFlags |= 0x10; >>\r
+  | "DISPLAY_UINT_HEX"                                 << $LFlags |= 0x20; >>\r
+  | questionheaderFlagsField[HFlags]\r
+  ;\r
+\r
+vfrStatementOneOf :\r
+  <<\r
+     CIfrOneOf OObj;\r
+  >>\r
+  L:OneOf                                              << OObj.SetLineNo(L->getLine()); >>\r
+  vfrQuestionHeader[OObj] ","\r
+  { F:FLAGS "=" vfrOneofFlagsField[OObj, F->getLine()] "," }\r
+  { \r
+    vfrSetMinMaxStep[OObj]\r
+  }\r
+  vfrStatementQuestionOptionList\r
+  E:EndOneOf                                           << CRT_END_OP (E); >>\r
+  ";"\r
+  ;\r
+\r
+vfrOneofFlagsField [CIfrOneOf & OObj, UINT32 LineNum] :\r
+  <<\r
+     UINT8 LFlags = _GET_CURRQEST_DATATYPE();\r
+     UINT8 HFlags = 0;\r
+  >>\r
+  numericFlagsField[HFlags, LFlags] ( "\|" numericFlagsField[HFlags, LFlags] )*\r
+                                                       << _PCATCH(OObj.SetFlags (HFlags, LFlags), LineNum); >>\r
+  ;\r
+\r
+vfrStatementStringType :\r
+  vfrStatementString    |\r
+  vfrStatementPassword\r
+  ;\r
+\r
+vfrStatementString :\r
+  <<\r
+     CIfrString SObj;\r
+  >>\r
+  L:String                                             << SObj.SetLineNo(L->getLine()); >>\r
+  vfrQuestionHeader[SObj] ","                          << _PCATCH(SObj.SetFlags (SObj.FLAGS(), _GET_CURRQEST_DATATYPE()), L->getLine()); >>\r
+  { F:FLAGS "=" vfrStringFlagsField[SObj, F->getLine()] "," }\r
+  {\r
+    Key "=" KN:Number ","                              << AssignQuestionKey (SObj, KN); >>\r
+  }\r
+  MinSize "=" MIN:Number ","                           << SObj.SetMinSize (_STOU8(MIN->getText())); >>\r
+  MaxSize "=" MAX:Number ","                           << SObj.SetMaxSize (_STOU8(MAX->getText())); >>\r
+  vfrStatementQuestionOptionList\r
+  E:EndString                                          << CRT_END_OP (E); >>\r
+  ";"\r
+  ;\r
+\r
+vfrStringFlagsField [CIfrString & SObj, UINT32 LineNum] :\r
+  <<\r
+     UINT8 LFlags = 0;\r
+     UINT8 HFlags = 0;\r
+  >>\r
+  stringFlagsField[HFlags, LFlags] ( "\|" stringFlagsField[HFlags, LFlags] )*\r
+                                                       << _PCATCH(SObj.SetFlags (HFlags, LFlags), LineNum); >>\r
+  ;\r
+\r
+stringFlagsField [UINT8 & HFlags, UINT8 & LFlags] :\r
+    N:Number                                           << _PCATCH(_STOU8(N->getText()) == 0 ? VFR_RETURN_SUCCESS : VFR_RETURN_UNSUPPORTED, N->getLine()); >>\r
+  | "MULTI_LINE"                                       << $LFlags = 0x01; >>\r
+  | questionheaderFlagsField[HFlags]\r
+  ;\r
+\r
+vfrStatementPassword :\r
+  <<\r
+     CIfrPassword PObj; \r
+  >>\r
+  L:Password                                           << PObj.SetLineNo(L->getLine()); >>\r
+  vfrQuestionHeader[PObj] ","\r
+  { F:FLAGS "=" vfrPasswordFlagsField[PObj, F->getLine()] "," }\r
+  {\r
+    Key "=" KN:Number ","                              << AssignQuestionKey (PObj, KN); >>\r
+  }\r
+  MinSize "=" MIN:Number ","                           << PObj.SetMinSize (_STOU16(MIN->getText())); >>\r
+  MaxSize "=" MAX:Number ","                           << PObj.SetMaxSize (_STOU16(MAX->getText())); >>\r
+  { Encoding "=" Number "," }\r
+  vfrStatementQuestionOptionList\r
+  E:EndPassword                                        << CRT_END_OP (E); >>\r
+  ";"\r
+  ;\r
+\r
+vfrPasswordFlagsField [CIfrPassword & PObj, UINT32 LineNum] :\r
+  << UINT8 HFlags = 0; >>\r
+  passwordFlagsField[HFlags] ( "\|" passwordFlagsField[HFlags] )*\r
+                                                       << _PCATCH(PObj.SetFlags(HFlags), LineNum); >>\r
+  ;\r
+\r
+passwordFlagsField [UINT8 & HFlags] :\r
+    N:Number                                           << _PCATCH(_STOU8(N->getText()) == 0 ? VFR_RETURN_SUCCESS : VFR_RETURN_UNSUPPORTED, N->getLine()); >>\r
+  | questionheaderFlagsField[HFlags]\r
+  ;\r
+\r
+vfrStatementOrderedList :\r
+  <<\r
+     CIfrOrderedList OLObj; \r
+  >>\r
+  L:OrderedList                                        << OLObj.SetLineNo(L->getLine()); >>\r
+  vfrQuestionHeader[OLObj] ","\r
+                                                       << OLObj.SetMaxContainers ((UINT8)_GET_CURRQEST_VARSIZE()); >>\r
+  { \r
+    MaxContainers "=" M:Number ","                     << OLObj.SetMaxContainers (_STOU8(M->getText())); >>\r
+  }\r
+  { F:FLAGS "=" vfrOrderedListFlags[OLObj, F->getLine()] }\r
+  vfrStatementQuestionOptionList\r
+  E:EndList                                            << CRT_END_OP (E); >>\r
+  ";"\r
+  ;\r
+\r
+vfrOrderedListFlags [CIfrOrderedList & OLObj, UINT32 LineNum] :\r
+  <<\r
+     UINT8 HFlags = 0;\r
+     UINT8 LFlags = 0;\r
+  >>\r
+  orderedlistFlagsField[HFlags, LFlags] ( "\|" orderedlistFlagsField[HFlags, LFlags] )*\r
+                                                       << _PCATCH(OLObj.SetFlags (HFlags, LFlags), LineNum); >>\r
+  ;\r
+\r
+orderedlistFlagsField [UINT8 & HFlags, UINT8 & LFlags] :\r
+    N:Number                                           << _PCATCH(_STOU8(N->getText()) == 0 ? VFR_RETURN_SUCCESS : VFR_RETURN_UNSUPPORTED, N->getLine()); >>\r
+  | "UNIQUE"                                           << $LFlags |= 0x01; >>\r
+  | "NOEMPTY"                                          << $LFlags |= 0x02; >>\r
+  | questionheaderFlagsField[HFlags]\r
+  ;\r
+\r
+vfrStatementTime :\r
+  <<\r
+     EFI_QUESTION_ID    QId          = EFI_QUESTION_ID_INVALID;\r
+     INT8               *VarIdStr[3] = {NULL, };\r
+     CIfrTime           TObj;\r
+     EFI_IFR_TYPE_VALUE Val;\r
+  >>\r
+  L:Time                                               << TObj.SetLineNo(L->getLine()); >>\r
+  (\r
+    (\r
+      vfrQuestionHeader[TObj, QUESTION_TIME] ","\r
+         { F:FLAGS "=" vfrTimeFlags[TObj, F->getLine()] "," }\r
+      vfrStatementDefault\r
+    )\r
+    |\r
+    (\r
+      Hour VarId "=" T1:StringIdentifier "." T1H:StringIdentifier ","\r
+                                                       << _STRCAT(&VarIdStr[0], T1->getText()); _STRCAT(&VarIdStr[0], "."); _STRCAT(&VarIdStr[0], T1H->getText()); >>\r
+      Prompt "=" "STRING_TOKEN" "\(" HP:Number "\)" ","\r
+      Help   "=" "STRING_TOKEN" "\(" HH:Number "\)" ","\r
+      minMaxTimeStepDefault[Val.time, 0]\r
+\r
+      Minute VarId "=" T2:StringIdentifier "." T2M:StringIdentifier ","\r
+                                                       << _STRCAT(&VarIdStr[1], T2->getText()); _STRCAT(&VarIdStr[1], "."); _STRCAT(&VarIdStr[1], T2M->getText()); >>\r
+      Prompt "=" "STRING_TOKEN" "\(" MP:Number "\)" ","\r
+      Help   "=" "STRING_TOKEN" "\(" MH:Number "\)" ","\r
+      minMaxTimeStepDefault[Val.time, 1]\r
+\r
+      Second VarId "=" T3:StringIdentifier "." T3S:StringIdentifier ","\r
+                                                       << _STRCAT(&VarIdStr[2], T3->getText()); _STRCAT(&VarIdStr[2], "."); _STRCAT(&VarIdStr[2], T3S->getText()); >>\r
+      Prompt "=" "STRING_TOKEN" "\(" SP:Number "\)" ","\r
+      Help   "=" "STRING_TOKEN" "\(" SH:Number "\)" ","\r
+      minMaxTimeStepDefault[Val.time, 2]\r
+                                                       <<\r
+                                                          mCVfrQuestionDB.RegisterOldTimeQuestion (VarIdStr[0], VarIdStr[1], VarIdStr[2], QId); \r
+                                                          TObj.SetQuestionId (QId);\r
+                                                          TObj.SetFlags (EFI_IFR_QUESTION_FLAG_DEFAULT, QF_TIME_STORAGE_TIME);\r
+                                                                                                                 TObj.SetPrompt (_STOSID(HP->getText()));\r
+                                                                                                                 TObj.SetHelp (_STOSID(HH->getText()));\r
+                                                                                                                 if (VarIdStr[0] != NULL) { delete VarIdStr[0]; } if (VarIdStr[1] != NULL) { delete VarIdStr[1]; } if (VarIdStr[2] != NULL) { delete VarIdStr[2]; }\r
+                                                       >>\r
+                                                       << {CIfrDefault DObj(EFI_HII_DEFAULT_CLASS_STANDARD, EFI_IFR_TYPE_TIME, Val);} >>\r
+    )\r
+  )\r
+  E:EndTime                                            << CRT_END_OP (E); >>\r
+  ";"\r
+  ;\r
+\r
+minMaxTimeStepDefault[EFI_HII_TIME & T, UINT8 KeyValue] :\r
+  Minimum   "=" Number ","\r
+  Maximum   "=" Number ","\r
+  { "step"    "=" Number "," }\r
+  {\r
+    "default" "=" N:Number ","                         <<\r
+                                                          switch (KeyValue) {\r
+                                                          case 0: T.Hour   = _STOU8(N->getText()); break; \r
+                                                          case 1: T.Minute = _STOU8(N->getText()); break; \r
+                                                          case 2: T.Second = _STOU8(N->getText()); break;\r
+                                                                                                                 } \r
+                                                       >>\r
+  }\r
+  ;\r
+\r
+vfrTimeFlags [CIfrTime & TObj, UINT32 LineNum] :\r
+  << UINT8 LFlags = 0; >>\r
+  timeFlagsField[LFlags] ( "\|" timeFlagsField[LFlags] )*\r
+                                                       << _PCATCH(TObj.SetFlags(EFI_IFR_QUESTION_FLAG_DEFAULT, LFlags), LineNum); >>\r
+  ;\r
+\r
+timeFlagsField [UINT8 & Flags] :\r
+    N:Number                                           << $Flags |= _STOU8(N->getText()); >>\r
+  | "HOUR_SUPPRESS"                                    << $Flags |= 0x01; >>\r
+  | "MINUTE_SUPPRESS"                                  << $Flags |= 0x02; >>\r
+  | "SECOND_SUPPRESS"                                  << $Flags |= 0x04; >>\r
+  | "STORAGE_NORMAL"                                   << $Flags |= 0x00; >>\r
+  | "STORAGE_TIME"                                     << $Flags |= 0x10; >>\r
+  | "STORAGE_WAKEUP"                                   << $Flags |= 0x20; >>\r
+  ;\r
+\r
+vfrStatementQuestionTag :\r
+  vfrStatementStatTag ","       |\r
+  vfrStatementInconsistentIf    |\r
+  vfrStatementNoSubmitIf        |\r
+  vfrStatementDisableIfQuest    |\r
+  vfrStatementRefresh           |\r
+  vfrStatementVarstoreDevice \r
+  ;\r
+\r
+vfrStatementQuestionTagList :\r
+  ( vfrStatementQuestionTag )*\r
+  ;\r
+\r
+vfrStatementQuestionOptionTag :\r
+  vfrStatementSuppressIfQuest   |\r
+  vfrStatementValue             |\r
+  vfrStatementDefault           |\r
+  vfrStatementOptions\r
+  ;\r
+\r
+vfrStatementQuestionOptionList :\r
+  (\r
+    vfrStatementQuestionTag     |\r
+    vfrStatementQuestionOptionTag \r
+  )*\r
+  ;\r
+\r
+vfrStatementStatList :\r
+  vfrStatementStat                        |\r
+  vfrStatementQuestions                   |\r
+  vfrStatementConditional                 |\r
+  // Just for framework vfr compatibility\r
+  vfrStatementLabel                       \r
+  //vfrStatementInvalid\r
+  ;\r
+\r
+vfrStatementDisableIfStat :\r
+  << CIfrDisableIf DIObj; >>\r
+  L:DisableIf                                          << DIObj.SetLineNo(L->getLine()); >>\r
+  vfrStatementExpression[0] ";"\r
+  ( vfrStatementStatList )*\r
+  E:EndIf                                              << CRT_END_OP (E); >>\r
+  ";"\r
+  ;\r
+\r
+vfrStatementSuppressIfStat :\r
+  << CIfrSuppressIf SIObj; >>\r
+  L:SuppressIf                                         << SIObj.SetLineNo(L->getLine()); >>\r
+  { FLAGS "=" flagsField ( "\|" flagsField )* "," }\r
+  vfrStatementExpression[0] ";"\r
+  ( vfrStatementStatList )*\r
+  E:EndIf                                              << CRT_END_OP (E); >>\r
+  ";"\r
+  ;\r
+\r
+vfrStatementGrayOutIfStat :\r
+  << CIfrGrayOutIf GOIObj; >>\r
+  L:GrayOutIf                                          << GOIObj.SetLineNo(L->getLine()); >>\r
+  { FLAGS "=" flagsField ( "\|" flagsField )* "," }\r
+  vfrStatementExpression[0]\r
+  ";"\r
+  ( vfrStatementStatList )*\r
+  E:EndIf                                              << CRT_END_OP (E); >>\r
+  ";"\r
+  ;\r
+\r
+vfrImageTag :\r
+  << CIfrImage IObj; >>\r
+  L:Image "=" "IMAGE_TOKEN" "\(" S1:Number "\)"        << IObj.SetImageId (_STOSID(S1->getText())); IObj.SetLineNo(L->getLine()); >>\r
+  ;\r
+\r
+vfrLockedTag :\r
+  << CIfrLocked LObj; >>\r
+  L:Locked                                             << LObj.SetLineNo(L->getLine()); >>\r
+  ;\r
+\r
+vfrStatementStatTag :\r
+  vfrImageTag  |\r
+  vfrLockedTag\r
+  ;\r
+\r
+vfrStatementStatTagList :\r
+  vfrStatementStatTag ( "," vfrStatementStatTag )*\r
+  ;\r
+\r
+vfrStatementImage :\r
+  vfrImageTag\r
+  ";"\r
+  ;\r
+\r
+vfrStatementLocked :\r
+  vfrLockedTag\r
+  ";"\r
+  ;\r
+\r
+vfrStatementInconsistentIf :\r
+  << CIfrInconsistentIf IIObj; >>\r
+  L:InconsistentIf                                     << IIObj.SetLineNo(L->getLine()); >>\r
+  Prompt "=" "STRING_TOKEN" "\(" S:Number "\)" ","     << IIObj.SetError (_STOSID(S->getText())); >>\r
+  { FLAGS "=" flagsField ( "\|" flagsField )* "," }\r
+  vfrStatementExpression[0]\r
+  E:EndIf                                              << CRT_END_OP (E); >>\r
+  ;\r
+\r
+vfrStatementNoSubmitIf :\r
+  << CIfrNoSubmitIf NSIObj; >>\r
+  L:NoSubmitIf                                         << NSIObj.SetLineNo(L->getLine()); >>\r
+  Prompt "=" "STRING_TOKEN" "\(" S:Number "\)" ","     << NSIObj.SetError (_STOSID(S->getText())); >>\r
+  { FLAGS "=" flagsField ( "\|" flagsField )* "," }\r
+  vfrStatementExpression[0]\r
+  E:EndIf                                              << CRT_END_OP (E); >>\r
+  ;\r
+\r
+vfrStatementDisableIfQuest :\r
+  << CIfrDisableIf DIObj; >>\r
+  L:DisableIf                                          << DIObj.SetLineNo(L->getLine()); >>\r
+  vfrStatementExpression[0] ";"\r
+  vfrStatementQuestionOptionList\r
+  E:EndIf                                              << CRT_END_OP (E); >>\r
+  ;\r
+\r
+vfrStatementRefresh :\r
+  << CIfrRefresh RObj; >>\r
+  L:Refresh                                            << RObj.SetLineNo(L->getLine()); >>\r
+  Interval "=" I:Number                                << RObj.SetRefreshInterval (_STOU8(I->getText())); >>\r
+  ;\r
+\r
+vfrStatementVarstoreDevice :\r
+  << CIfrVarStoreDevice VDObj; >>\r
+  L:VarstoreDevice                                     << VDObj.SetLineNo(L->getLine()); >>\r
+  "=" "STRING_TOKEN" "\(" S:Number "\)" ","            << VDObj.SetDevicePath (_STOSID(S->getText())); >>\r
+  ;\r
+\r
+vfrStatementSuppressIfQuest :\r
+  << CIfrSuppressIf SIObj; >>\r
+  L:SuppressIf                                         << SIObj.SetLineNo(L->getLine()); >>\r
+  { FLAGS "=" flagsField ( "\|" flagsField )* "," }\r
+  vfrStatementExpression[0] ";"\r
+  vfrStatementQuestionOptionList\r
+  E:EndIf                                              << CRT_END_OP (E); >>\r
+  ;\r
+\r
+vfrStatementOptions :\r
+  vfrStatementOneOfOption\r
+  ;\r
+\r
+vfrStatementOneOfOption :\r
+  <<\r
+     EFI_IFR_TYPE_VALUE Val;\r
+     CIfrOneOfOption    OOOObj;\r
+     INT8               *VarStoreName = NULL;\r
+     \r
+  >>\r
+  L:Option                                             << OOOObj.SetLineNo(L->getLine()); >>\r
+  Text  "=" "STRING_TOKEN" "\(" S:Number "\)" ","      << OOOObj.SetOption (_STOSID(S->getText())); >>\r
+  Value "=" vfrConstantValueField[_GET_CURRQEST_DATATYPE()] >[Val] ","    << OOOObj.SetType (_GET_CURRQEST_DATATYPE()); OOOObj.SetValue (Val); >>\r
+  F:FLAGS "=" vfrOneOfOptionFlags[OOOObj, F->getLine()]\r
+                                                       <<\r
+                                                          if (OOOObj.GetFlags () & 0x10) {\r
+                                                            _PCATCH(mCVfrDataStorage.GetVarStoreName (_GET_CURRQEST_VARTINFO().mVarStoreId, &VarStoreName), L->getLine());\r
+                                                            _PCATCH(mCVfrDefaultStore.BufferVarStoreAltConfigAdd (\r
+                                                                                                                                                   EFI_HII_DEFAULT_CLASS_STANDARD, \r
+                                                                                                                                                                       _GET_CURRQEST_VARTINFO(), \r
+                                                                                                                                                                       VarStoreName, \r
+                                                                                                                                                                   _GET_CURRQEST_DATATYPE (), \r
+                                                                                                                                                                       Val\r
+                                                                                                                                                                       ), L->getLine());\r
+                                                          }\r
+                                                       >>\r
+  { "," Key "=" Number }                               // no use in UEFI2.1 VFR\r
+  (\r
+    "," vfrImageTag                                    << OOOObj.SetScope (1); CIfrEnd EOOOObj; >>\r
+  )*\r
+  ";"\r
+  ;\r
+\r
+vfrOneOfOptionFlags [CIfrOneOfOption & OOOObj, UINT32 LineNum] :\r
+  <<\r
+     UINT8 LFlags = _GET_CURRQEST_DATATYPE();\r
+     UINT8 HFlags = 0;\r
+  >>\r
+  oneofoptionFlagsField[HFlags, LFlags] ( "\|" oneofoptionFlagsField[HFlags, LFlags] )*\r
+                                                       << _PCATCH(gCurrentQuestion->SetFlags(HFlags), LineNum); >>\r
+                                                       << _PCATCH(OOOObj.SetFlags(LFlags), LineNum); >>\r
+  ;\r
+\r
+oneofoptionFlagsField [UINT8 & HFlags, UINT8 & LFlags] :\r
+    N:Number                                           << $LFlags |= _STOU8(N->getText()); >>\r
+  | "OPTION_DEFAULT"                                   << $LFlags |= 0x10; >>\r
+  | "OPTION_DEFAULT_MFG"                               << $LFlags |= 0x20; >>\r
+  | InteractiveFlag                                    << $HFlags |= 0x04; >>\r
+  | NVAccessFlag                                       << $HFlags |= 0x08; >>\r
+  | ResetRequiredFlag                                  << $HFlags |= 0x10; >>\r
+  | LateCheckFlag                                      << $HFlags |= 0x20; >>\r
+  | ManufacturingFlag                                  << $LFlags |= 0x20; >>\r
+  | DefaultFlag                                        << $LFlags |= 0x10; >>\r
+  ;\r
+\r
+//vfrStatementGuid :\r
+//  <<\r
+//     EFI_GUID Guid; \r
+//     CIfrGuid GObj;\r
+//  >>\r
+//  GuidAction\r
+//  GUID "=" \r
+//  OpenBrace\r
+//    G1:Number "," G2:Number "," G3:Number "," G4:Number "," G5:Number "," G6:Number "," \r
+//    G7:Number "," G8:Number "," G9:Number "," G10:Number "," G11:Number\r
+//  CloseBrace\r
+//                                                       << \r
+//                                                          _CRGUID (&Guid, G1->getText (), G2->getText (), G3->getText (), \r
+//                                                                          G4->getText (), G5->getText (), G6->getText (), \r
+//                                                                          G7->getText (), G8->getText (), G9->getText (), \r
+//                                                                          G10->getText (), G11->getText ()); \r
+//                                                       >>\r
+//                                                       << GObj.SetGuid (&Guid); >>\r
+//  ";"\r
+//  ;\r
+\r
+vfrStatementLabel :\r
+  << CIfrLabel LObj; >>\r
+  L:Label                                              << LObj.SetLineNo(L->getLine()); >>\r
+  N:Number                                             << LObj.SetNumber (_STOU16(N->getText())); >>\r
+  ";"\r
+  ;\r
+\r
+vfrStatementBanner :\r
+  << CIfrBanner BObj; >>\r
+  B:Banner { "," }                                     << BObj.SetLineNo(B->getLine()); >>\r
+  Title "=" "STRING_TOKEN" "\(" S:Number "\)" ","      << BObj.SetTitle (_STOSID(S->getText())); >>\r
+  (\r
+    ( \r
+      Line L:Number ","                                << BObj.SetLine (_STOU16(L->getText())); >>\r
+      Align \r
+      (\r
+          Left                                         << BObj.SetAlign (0); >>\r
+        | Center                                       << BObj.SetAlign (1); >>\r
+        | Right                                        << BObj.SetAlign (2); >>\r
+      ) ";"\r
+    )\r
+    |\r
+    (\r
+      Timeout "=" T:Number ";"                         << {CIfrTimeout TObj(_STOU16(T->getText()));} >>\r
+    )\r
+  )\r
+  ;\r
+\r
+//******************************************************************************\r
+//\r
+// keep some syntax for compatibility but not generate any IFR object\r
+//\r
+vfrStatementInvalidHidden : \r
+  Hidden\r
+  Value "=" Number ","\r
+  Key "=" Number ";"\r
+  ;\r
+\r
+vfrStatementInvalidInconsistentIf :\r
+  InconsistentIf\r
+  Prompt "=" "STRING_TOKEN" "\(" S:Number "\)" ","\r
+  { FLAGS "=" flagsField ( "\|" flagsField )* "," }\r
+  vfrStatementExpression[0]\r
+  EndIf\r
+  ";"\r
+  ;\r
+\r
+vfrStatementInvalidInventory :\r
+  Inventory\r
+  Help "=" "STRING_TOKEN" "\(" Number "\)" ","\r
+  Text "=" "STRING_TOKEN" "\(" Number "\)" ","\r
+  {\r
+    Text  "=" "STRING_TOKEN" "\(" Number "\)"\r
+  }\r
+  ";" \r
+  ;\r
+\r
+vfrStatementInvalidSaveRestoreDefaults : \r
+  (Save | Restore)\r
+  Defaults ","\r
+  FormId "=" Number  ","\r
+  Prompt "=" "STRING_TOKEN" "\(" Number "\)" ","\r
+  Help   "=" "STRING_TOKEN" "\(" Number "\)" \r
+  { "," FLAGS "=" flagsField ( "\|" flagsField )* }\r
+  { "," Key   "=" Number }\r
+  ";"\r
+  ;\r
+\r
+//******************************************************************************\r
+//\r
+// The syntax of expression\r
+//\r
+#token Dup("dup")                               "dup"\r
+#token VarEqVal("vareqval")                     "vareqval"\r
+#token Var("var")                               "var"\r
+#token IdEqVal("ideqval")                       "ideqval"\r
+#token IdEqId("ideqid")                         "ideqid"\r
+#token IdEqValList("ideqvallist")               "ideqvallist"\r
+#token QuestionRef("questionref")               "questionref"\r
+#token RuleRef("ruleref")                       "ruleref"\r
+#token StringRef("stringref")                   "stringref"\r
+#token PushThis("pushthis")                     "pushthis"\r
+#token True("TRUE")                             "TRUE"\r
+#token False("FALSE")                           "FALSE"\r
+#token One("ONE")                               "ONE"\r
+#token Ones("ONES")                             "ONES"\r
+#token Zero("ZERO")                             "ZERO"\r
+#token Undefined("UNDEFINED")                   "UNDEFINED"\r
+#token Version("VERSOPM")                       "VERSION"\r
+#token Length("length")                         "length"\r
+#token AND("AND")                               "AND"\r
+#token OR("OR")                                 "OR"\r
+#token NOT("NOT")                               "NOT"\r
+#token BitWiseNot("~")                          "\~"\r
+#token BoolVal("boolval")                       "boolval"\r
+#token StringVal("stringval")                   "stringval"\r
+#token UnIntVal("unintval")                     "unintval"\r
+#token ToUpper("toupper")                       "toupper"\r
+#token ToLower("tolower")                       "tolower"\r
+#token Match("match")                           "match"\r
+#token Catenate("catenate")                     "catenate"\r
+#token QuestionRefVal("questionrefval")         "questionrefval"\r
+#token StringRefVal("stringrefval")             "stringrefval"\r
+\r
+vfrStatementExpression [UINT32 RootLevel, UINT32 ExpOpCount = 0] :\r
+                                                                                                          << if ($RootLevel == 0) {_CLEAR_SAVED_OPHDR ();} >>\r
+  andTerm[$RootLevel, $ExpOpCount]\r
+  (\r
+    L:OR andTerm[$RootLevel, $ExpOpCount]              << $ExpOpCount++; CIfrOr OObj(L->getLine()); >>\r
+  )*\r
+                                                       << if (($RootLevel == 0) && ($ExpOpCount > 1)) {_SET_SAVED_OPHDR_SCOPE(); CIfrEnd EObj; } >>\r
+  ;\r
+\r
+andTerm[UINT32 & RootLevel, UINT32 & ExpOpCount] :\r
+  bitwiseorTerm[$RootLevel, $ExpOpCount]\r
+  (\r
+    L:AND bitwiseorTerm [$RootLevel, $ExpOpCount]       << $ExpOpCount++; CIfrAnd AObj(L->getLine()); >>\r
+  )*\r
+  ;\r
+\r
+bitwiseorTerm [UINT32 & RootLevel, UINT32 & ExpOpCount]:\r
+  bitwiseandTerm[$RootLevel, $ExpOpCount]          \r
+  (\r
+    L:"\|" bitwiseandTerm[$RootLevel, $ExpOpCount]      << $ExpOpCount++; CIfrBitWiseOr BWOObj(L->getLine()); >>\r
+  )*\r
+  ;\r
+\r
+bitwiseandTerm [UINT32 & RootLevel, UINT32 & ExpOpCount]:\r
+  equalTerm[$RootLevel, $ExpOpCount]\r
+  (\r
+    L:"&" equalTerm[$RootLevel, $ExpOpCount]            << $ExpOpCount++; CIfrBitWiseAnd BWAObj(L->getLine()); >>\r
+  )*\r
+  ;\r
+\r
+equalTerm [UINT32 & RootLevel, UINT32 & ExpOpCount]:\r
+  compareTerm[$RootLevel, $ExpOpCount]\r
+  (\r
+    (\r
+      L1:"==" compareTerm[$RootLevel, $ExpOpCount]      << $ExpOpCount++; CIfrEqual EObj(L1->getLine()); >>\r
+    )\r
+    |\r
+    (\r
+      L2:"!=" compareTerm[$RootLevel, $ExpOpCount]      << $ExpOpCount++; CIfrNotEqual NEObj(L2->getLine()); >>\r
+    )\r
+  )*\r
+  ;\r
+\r
+compareTerm [UINT32 & RootLevel, UINT32 & ExpOpCount]:\r
+  shiftTerm[$RootLevel, $ExpOpCount]\r
+  (\r
+    (\r
+      L1:"<" shiftTerm[$RootLevel, $ExpOpCount]         << $ExpOpCount++; CIfrLessThan LTObj(L1->getLine()); >>\r
+    )\r
+    |\r
+    (\r
+      L2:"<=" shiftTerm[$RootLevel, $ExpOpCount]        << $ExpOpCount++; CIfrLessEqual LEObj(L2->getLine()); >>\r
+    )\r
+    |\r
+    (\r
+      L3:">" shiftTerm[$RootLevel, $ExpOpCount]         << $ExpOpCount++; CIfrGreaterThan GTObj(L3->getLine()); >>\r
+    )\r
+    |\r
+    (\r
+      L4:">=" shiftTerm[$RootLevel, $ExpOpCount]        << $ExpOpCount++; CIfrGreaterEqual GEObj(L4->getLine()); >>\r
+    )\r
+  )*\r
+  ;\r
+\r
+shiftTerm [UINT32 & RootLevel, UINT32 & ExpOpCount]:\r
+  addMinusTerm[$RootLevel, $ExpOpCount]           \r
+  (\r
+    (\r
+      L1:"\<<" addMinusTerm[$RootLevel, $ExpOpCount]    << $ExpOpCount++; CIfrShiftLeft SLObj(L1->getLine()); >>\r
+    )\r
+    |\r
+    (\r
+      L2:"\>>" addMinusTerm[$RootLevel, $ExpOpCount]    << $ExpOpCount++; CIfrShiftRight SRObj(L2->getLine()); >>\r
+    )\r
+  )*\r
+  ;\r
+\r
+addMinusTerm [UINT32 & RootLevel, UINT32 & ExpOpCount]:\r
+  multdivmodTerm[$RootLevel, $ExpOpCount]\r
+  (\r
+    (\r
+      L1:"\+" multdivmodTerm[$RootLevel, $ExpOpCount]   << $ExpOpCount++; CIfrAdd AObj(L1->getLine()); >>\r
+    )\r
+    |\r
+    (\r
+      L2:"\-" multdivmodTerm[$RootLevel, $ExpOpCount]   << $ExpOpCount++; CIfrSubtract SObj(L2->getLine()); >>\r
+    )\r
+  )*\r
+  ;\r
+\r
+multdivmodTerm [UINT32 & RootLevel, UINT32 & ExpOpCount]:\r
+  atomTerm[$RootLevel, $ExpOpCount]\r
+  ( \r
+    (\r
+      L1:"\*" atomTerm[$RootLevel, $ExpOpCount]         << $ExpOpCount++; CIfrMultiply MObj(L1->getLine()); >>\r
+    )\r
+    |\r
+    (\r
+      L2:"/" atomTerm[$RootLevel, $ExpOpCount]          << $ExpOpCount++; CIfrDivide DObj(L2->getLine()); >>\r
+    )\r
+    |\r
+    (\r
+      L3:"%" atomTerm[$RootLevel, $ExpOpCount]          << $ExpOpCount++; CIfrModulo MObj(L3->getLine()); >>\r
+    ) \r
+  )*\r
+  ;\r
+\r
+atomTerm [UINT32 & RootLevel, UINT32 & ExpOpCount]:\r
+    vfrExpressionCatenate[$RootLevel, $ExpOpCount]\r
+  | vfrExpressionMatch[$RootLevel, $ExpOpCount]\r
+  | vfrExpressionParen[$RootLevel, $ExpOpCount]\r
+  | vfrExpressionBuildInFunction[$RootLevel, $ExpOpCount]\r
+  | vfrExpressionConstant[$RootLevel, $ExpOpCount]\r
+  | vfrExpressionUnaryOp[$RootLevel, $ExpOpCount]\r
+  | vfrExpressionTernaryOp[$RootLevel, $ExpOpCount]\r
+  | (\r
+      L:NOT\r
+      atomTerm[$RootLevel, $ExpOpCount]                 << { CIfrNot NObj(L->getLine()); $ExpOpCount++; } >>\r
+    )\r
+  ;\r
+\r
+vfrExpressionCatenate [UINT32 & RootLevel, UINT32 & ExpOpCount]:\r
+  L:Catenate\r
+  "\("\r
+  vfrStatementExpression[$RootLevel + 1, $ExpOpCount]\r
+  ","\r
+  vfrStatementExpression[$RootLevel + 1, $ExpOpCount]\r
+  "\)"                                                 << { CIfrCatenate CObj(L->getLine()); $ExpOpCount++; } >>\r
+  ;\r
+\r
+vfrExpressionMatch [UINT32 & RootLevel, UINT32 & ExpOpCount]:\r
+  L:Match\r
+  "\("\r
+  vfrStatementExpression[$RootLevel + 1, $ExpOpCount]\r
+  ","\r
+  vfrStatementExpression[$RootLevel + 1, $ExpOpCount]\r
+  "\)"                                                 << { CIfrMatch MObj(L->getLine()); $ExpOpCount++; } >>\r
+  ;\r
+\r
+vfrExpressionParen [UINT32 & RootLevel, UINT32 & ExpOpCount]:\r
+  "\("\r
+  vfrStatementExpression[$RootLevel + 1, $ExpOpCount]\r
+  "\)"\r
+  ;\r
+\r
+vfrExpressionBuildInFunction [UINT32 & RootLevel, UINT32 & ExpOpCount] :\r
+    dupExp[$RootLevel, $ExpOpCount]\r
+  | ideqvalExp[$RootLevel, $ExpOpCount]\r
+  | ideqidExp[$RootLevel, $ExpOpCount]\r
+  | ideqvallistExp[$RootLevel, $ExpOpCount]\r
+  | questionref13Exp[$RootLevel, $ExpOpCount]\r
+  | rulerefExp[$RootLevel, $ExpOpCount]\r
+  | stringref1Exp[$RootLevel, $ExpOpCount]\r
+  | pushthisExp[$RootLevel, $ExpOpCount]\r
+  ;\r
+\r
+dupExp [UINT32 & RootLevel, UINT32 & ExpOpCount] :\r
+  L:Dup                                                << { CIfrDup DObj(L->getLine()); _SAVE_OPHDR_COND(DObj, ($ExpOpCount == 0)); $ExpOpCount++; } >>\r
+  ;\r
+\r
+ideqvalExp [UINT32 & RootLevel, UINT32 & ExpOpCount] :\r
+  <<\r
+     EFI_QUESTION_ID QId;\r
+     UINT32          Mask;\r
+     UINT16          ConstVal;\r
+     INT8            *VarIdStr;\r
+     UINT32          LineNo;\r
+  >>\r
+  L:IdEqVal\r
+  vfrQuestionDataFieldName[QId, Mask, VarIdStr, LineNo]\r
+  (\r
+    (\r
+      "=="\r
+      V1:Number                                        << ConstVal = _STOU16(V1->getText()); >>\r
+                                                       <<\r
+                                                                                                             if (Mask == 0) {\r
+                                                                                                                       CIfrEqIdVal EIVObj (L->getLine());\r
+                                                                                                                       _SAVE_OPHDR_COND (EIVObj, ($ExpOpCount == 0));\r
+                                                                                                                       EIVObj.SetQuestionId (QId, VarIdStr, LineNo);\r
+                                                                                                                       EIVObj.SetValue (ConstVal);\r
+                                                                                                                       $ExpOpCount++;                                                                                                                  \r
+                                                                                                                 } else {\r
+                                                                                                                       IdEqValDoSpecial ($ExpOpCount, L->getLine(), QId, VarIdStr, Mask, ConstVal, EQUAL);\r
+                                                                                                                 }\r
+                                                                                                          >>\r
+    )\r
+    |\r
+    (\r
+      "<="\r
+      V2:Number                                        << ConstVal = _STOU16(V2->getText()); >>\r
+                                                       << IdEqValDoSpecial ($ExpOpCount, L->getLine(), QId, VarIdStr, Mask, ConstVal, LESS_EQUAL); >>\r
+    )\r
+    |\r
+    (\r
+      "<"\r
+      V3:Number                                        << ConstVal = _STOU16(V3->getText()); >>\r
+                                                       << IdEqValDoSpecial ($ExpOpCount, L->getLine(), QId, VarIdStr, Mask, ConstVal, LESS_THAN); >>\r
+    )\r
+    |\r
+    (\r
+      ">="\r
+      V4:Number                                        << ConstVal = _STOU16(V4->getText()); >>\r
+                                                       << IdEqValDoSpecial ($ExpOpCount, L->getLine(), QId, VarIdStr, Mask, ConstVal, GREATER_EQUAL); >>\r
+    )\r
+    |\r
+    (\r
+      ">"\r
+      V5:Number                                        << ConstVal = _STOU16(V5->getText()); >>\r
+                                                       << IdEqValDoSpecial ($ExpOpCount, L->getLine(), QId, VarIdStr, Mask, ConstVal, GREATER_THAN); >>\r
+    )\r
+  )\r
+  ;\r
+\r
+ideqidExp[UINT32 & RootLevel, UINT32 & ExpOpCount] :\r
+  <<\r
+     EFI_QUESTION_ID QId[2];\r
+     UINT32          Mask[2];\r
+     INT8            *VarIdStr[2];\r
+     UINT32          LineNo[2];\r
+  >>\r
+  L:IdEqId\r
+  vfrQuestionDataFieldName[QId[0], Mask[0], VarIdStr[0], LineNo[0]]\r
+  (\r
+    (\r
+      "==" \r
+      vfrQuestionDataFieldName[QId[1], Mask[1], VarIdStr[1], LineNo[1]]\r
+                                                       <<\r
+                                                                                                             if (Mask[0] & Mask[1]) {\r
+                                                                                                                       IdEqIdDoSpecial ($ExpOpCount, L->getLine(), QId[0], VarIdStr[0], Mask[0], QId[1], VarIdStr[1], Mask[1], EQUAL);\r
+                                                                                                                 } else {\r
+                                                            CIfrEqIdId      EIIObj(L->getLine());\r
+                                                                                                                       _SAVE_OPHDR_COND (EIIObj, ($ExpOpCount == 0));\r
+                                                            EIIObj.SetQuestionId1 (QId[0], VarIdStr[0], LineNo[0]);\r
+                                                                                                                       EIIObj.SetQuestionId2 (QId[1], VarIdStr[1], LineNo[1]);\r
+                                                                                                                       $ExpOpCount++;                                                                                                                  \r
+                                                                                                                 }\r
+                                                                                                          >>\r
+    )\r
+    |\r
+    (\r
+      "<="\r
+      vfrQuestionDataFieldName[QId[1], Mask[1], VarIdStr[1], LineNo[1]]\r
+                                                       << IdEqIdDoSpecial ($ExpOpCount, L->getLine(), QId[0], VarIdStr[0], Mask[0], QId[1], VarIdStr[1], Mask[1], LESS_EQUAL); >>\r
+    )\r
+    |\r
+    (\r
+      "<"\r
+      vfrQuestionDataFieldName[QId[1], Mask[1], VarIdStr[1], LineNo[1]]\r
+                                                       << IdEqIdDoSpecial ($ExpOpCount, L->getLine(), QId[0], VarIdStr[0], Mask[0], QId[1], VarIdStr[1], Mask[1], LESS_THAN); >>\r
+    )\r
+    |\r
+    (\r
+      ">="\r
+      vfrQuestionDataFieldName[QId[1], Mask[1], VarIdStr[1], LineNo[1]]\r
+                                                       << IdEqIdDoSpecial ($ExpOpCount, L->getLine(), QId[0], VarIdStr[0], Mask[0], QId[1], VarIdStr[1], Mask[1], GREATER_EQUAL); >>\r
+    )\r
+    |\r
+    (\r
+      ">"\r
+      vfrQuestionDataFieldName[QId[1], Mask[1], VarIdStr[1], LineNo[1]]\r
+                                                       << IdEqIdDoSpecial ($ExpOpCount, L->getLine(), QId[0], VarIdStr[0], Mask[0], QId[1], VarIdStr[1], Mask[1], GREATER_THAN); >>\r
+    )\r
+  )\r
+  ;\r
+\r
+ideqvallistExp[UINT32 & RootLevel, UINT32 & ExpOpCount] :\r
+  <<\r
+     UINT16          ListLen = 0;\r
+     EFI_QUESTION_ID QId;\r
+     UINT32          Mask;\r
+     UINT16          ValueList[EFI_IFR_MAX_LENGTH] = {0,};\r
+     INT8            *VarIdStr;\r
+     UINT32          LineNo;\r
+  >>\r
+  L:IdEqValList\r
+  vfrQuestionDataFieldName[QId, Mask, VarIdStr, LineNo]\r
+  "==" \r
+  (\r
+    V:Number                                           << ValueList[ListLen] = _STOU16(V->getText()); ListLen++; >>\r
+  )+\r
+                                                       <<\r
+                                                                                                             if (Mask != 0) {\r
+                                                            IdEqListDoSpecial ($ExpOpCount, LineNo, QId, VarIdStr, Mask, ListLen, ValueList);\r
+                                                                                                                 } else {\r
+                                                                                           UINT16       Index;\r
+                                                            CIfrEqIdList EILObj(L->getLine());\r
+                                                                                                                       _SAVE_OPHDR_COND (EILObj, ($ExpOpCount == 0));\r
+                                                            EILObj.SetQuestionId (QId, VarIdStr, LineNo);\r
+                                                                                                                       EILObj.SetListLength (ListLen);\r
+                                                                                                                       for (Index = 0; Index < ListLen; Index++) {\r
+                                                                                                                         EILObj.SetValueList (Index, ValueList[Index]);\r
+                                                                                                                       }\r
+                                                                                                                       $ExpOpCount++;\r
+                                                                                                                 }\r
+                                                                                                          >>\r
+  ;\r
+\r
+vareqvarlExp[UINT32 & RootLevel, UINT32 & ExpOpCount] :\r
+  L:VarEqVal Var "\(" V1:Number "\)" "==" V2:Number    <<\r
+                                                          {\r
+                                                            CIfrUint64 U64Obj1(L->getLine()), U64Obj2(L->getLine()); \r
+                                                            _SAVE_OPHDR_COND (U64Obj1, ($ExpOpCount == 0)); \r
+                                                            U64Obj1.SetValue (_STOU64(V1->getText())); \r
+                                                            U64Obj2.SetValue (_STOU64(V2->getText()));\r
+                                                          }\r
+                                                       >>\r
+                                                       << {CIfrEqual EObj(L->getLine()); } >>\r
+                                                                                                          << $ExpOpCount += 3; >>\r
+  ;\r
+\r
+questionref13Exp[UINT32 & RootLevel, UINT32 & ExpOpCount] :\r
+  <<\r
+     UINT8           Type = 0x1;\r
+     EFI_STRING_ID   DevPath;\r
+     EFI_GUID        Guid;\r
+        EFI_QUESTION_ID QId = EFI_QUESTION_ID_INVALID;\r
+     UINT32          BitMask;\r
+     INT8            *QName = NULL;\r
+     UINT32          LineNo = 0;\r
+  >>\r
+  L:QuestionRef\r
+  (\r
+    (\r
+                                                       << Type = 0x3; >>\r
+      {\r
+        Path "=" "STRING_TOKEN" "\(" S:Number "\)"     << Type = 0x4; DevPath = _STOSID(S->getText()); >>\r
+      }\r
+      {\r
+        GUID "=" \r
+          OpenBrace\r
+            G1:Number "," G2:Number "," G3:Number "," G4:Number "," G5:Number "," G6:Number "," \r
+            G7:Number "," G8:Number "," G9:Number "," G10:Number "," G11:Number\r
+          CloseBrace\r
+                                                       <<\r
+                                                          Type = 0x5;\r
+                                                          _CRGUID (&Guid, G1->getText (), G2->getText (), G3->getText (), \r
+                                                                          G4->getText (), G5->getText (), G6->getText (), \r
+                                                                          G7->getText (), G8->getText (), G9->getText (), \r
+                                                                          G10->getText (), G11->getText ()); \r
+                                                       >>\r
+      }\r
+    )\r
+    |\r
+    (\r
+      "\("\r
+         (\r
+          QN:StringIdentifier                          << \r
+                                                          QName  = QN->getText();\r
+                                                                                                                 LineNo = QN->getLine();\r
+                                                          mCVfrQuestionDB.GetQuestionId (QN->getText(), NULL, QId, BitMask);\r
+                                                       >>\r
+        | ID:Number                                    << QId = _STOQID(ID->getText()); >>\r
+      )\r
+      "\)"\r
+    )\r
+  )\r
+                                                       <<\r
+                                                          switch (Type) {\r
+                                                          case 0x1: {CIfrQuestionRef1 QR1Obj(L->getLine()); _SAVE_OPHDR_COND (QR1Obj, ($ExpOpCount == 0)); QR1Obj.SetQuestionId (QId, QName, LineNo); break;}\r
+                                                          case 0x3: {CIfrQuestionRef3 QR3Obj(L->getLine()); _SAVE_OPHDR_COND (QR3Obj, ($ExpOpCount == 0)); break;}\r
+                                                          case 0x4: {CIfrQuestionRef3_2 QR3_2Obj(L->getLine()); _SAVE_OPHDR_COND (QR3_2Obj, ($ExpOpCount == 0)); QR3_2Obj.SetDevicePath (DevPath); break;}\r
+                                                          case 0x5: {CIfrQuestionRef3_3 QR3_3Obj(L->getLine()); _SAVE_OPHDR_COND (QR3_3Obj, ($ExpOpCount == 0)); QR3_3Obj.SetDevicePath (DevPath); QR3_3Obj.SetGuid (&Guid); break;}\r
+                                                          }\r
+                                                          $ExpOpCount++;\r
+                                                       >>\r
+  ;\r
+\r
+rulerefExp[UINT32 & RootLevel, UINT32 & ExpOpCount] :\r
+  L:RuleRef\r
+  "\(" RN:StringIdentifier "\)"                        << { CIfrRuleRef RRObj(L->getLine()); _SAVE_OPHDR_COND (RRObj, ($ExpOpCount == 0)); RRObj.SetRuleId (mCVfrRulesDB.GetRuleId (RN->getText())); } $ExpOpCount++; >>\r
+  ;\r
+\r
+//******************************************************\r
+// PARSE:\r
+//   stringref (STR_FORM_SET_TITLE)\r
+//\r
+stringref1Exp[UINT32 & RootLevel, UINT32 & ExpOpCount] :\r
+  L:StringRef\r
+  "\(" S:Number "\)"                                   << { CIfrStringRef1 SR1Obj(L->getLine()); _SAVE_OPHDR_COND (SR1Obj, ($ExpOpCount == 0)); SR1Obj.SetStringId (_STOSID(S->getText())); $ExpOpCount++; } >>\r
+  ;\r
+\r
+pushthisExp[UINT32 & RootLevel, UINT32 & ExpOpCount] :\r
+  L:PushThis                                           << { CIfrThis TObj(L->getLine()); _SAVE_OPHDR_COND (TObj, ($ExpOpCount == 0)); $ExpOpCount++; } >>\r
+  ;\r
+\r
+vfrExpressionConstant[UINT32 & RootLevel, UINT32 & ExpOpCount] :\r
+    L1:True                                            << CIfrTrue TObj(L1->getLine()); _SAVE_OPHDR_COND (TObj, ($ExpOpCount == 0)); $ExpOpCount++; >>\r
+  | L2:False                                           << CIfrFalse FObj(L2->getLine()); _SAVE_OPHDR_COND (FObj, ($ExpOpCount == 0)); $ExpOpCount++; >>\r
+  | L3:One                                             << CIfrOne OObj(L3->getLine()); _SAVE_OPHDR_COND (OObj, ($ExpOpCount == 0)); $ExpOpCount++; >>\r
+  | L4:Ones                                            << CIfrOnes OObj(L4->getLine()); _SAVE_OPHDR_COND (OObj, ($ExpOpCount == 0)); $ExpOpCount++; >>\r
+  | L5:Zero                                            << CIfrZero ZObj(L5->getLine()); _SAVE_OPHDR_COND (ZObj, ($ExpOpCount == 0)); $ExpOpCount++; >>\r
+  | L6:Undefined                                       << CIfrUndefined UObj(L6->getLine()); _SAVE_OPHDR_COND (UObj, ($ExpOpCount == 0)); $ExpOpCount++; >>\r
+  | L7:Version                                         << CIfrVersion VObj(L7->getLine()); _SAVE_OPHDR_COND (VObj, ($ExpOpCount == 0)); $ExpOpCount++; >>\r
+  | V:Number                                           << CIfrUint64 U64Obj(V->getLine()); U64Obj.SetValue (_STOU64(V->getText())); _SAVE_OPHDR_COND (U64Obj, ($ExpOpCount == 0)); $ExpOpCount++; >>\r
+  ;\r
+\r
+vfrExpressionUnaryOp[UINT32 & RootLevel, UINT32 & ExpOpCount] :\r
+    lengthExp[$RootLevel, $ExpOpCount]\r
+  | bitwisenotExp[$RootLevel, $ExpOpCount]\r
+  | question2refExp[$RootLevel, $ExpOpCount]\r
+  | stringref2Exp[$RootLevel, $ExpOpCount]\r
+  | unintExp[$RootLevel, $ExpOpCount]\r
+  | toupperExp[$RootLevel, $ExpOpCount]\r
+  | tolwerExp[$RootLevel, $ExpOpCount]\r
+  ;\r
+\r
+lengthExp[UINT32 & RootLevel, UINT32 & ExpOpCount] :\r
+  L:Length\r
+  "\(" vfrStatementExpression[$RootLevel + 1, $ExpOpCount] "\)"\r
+                                                       << { CIfrLength LObj(L->getLine()); $ExpOpCount++; } >>\r
+  ;\r
+\r
+bitwisenotExp[UINT32 & RootLevel, UINT32 & ExpOpCount] :\r
+  L:BitWiseNot\r
+  "\(" vfrStatementExpression[$RootLevel + 1, $ExpOpCount] "\)"\r
+                                                       << { CIfrBitWiseNot BWNObj(L->getLine()); $ExpOpCount++; } >>\r
+  ;\r
+\r
+question2refExp[UINT32 & RootLevel, UINT32 & ExpOpCount] :\r
+  L:QuestionRefVal\r
+  "\(" vfrStatementExpression[$RootLevel + 1, $ExpOpCount] "\)"\r
+                                                       << { CIfrQuestionRef2 QR2Obj(L->getLine()); $ExpOpCount++; } >>\r
+  ;\r
+\r
+stringref2Exp[UINT32 & RootLevel, UINT32 & ExpOpCount] :\r
+  L:StringRefVal\r
+  "\(" vfrStatementExpression[$RootLevel + 1, $ExpOpCount] "\)"\r
+                                                       << { CIfrStringRef2 SR2Obj(L->getLine()); $ExpOpCount++; } >>\r
+  ;\r
+\r
+toboolExp[UINT32 & RootLevel, UINT32 & ExpOpCount] :\r
+  L:BoolVal\r
+  "\(" vfrStatementExpression[$RootLevel + 1, $ExpOpCount] "\)"\r
+                                                       << { CIfrToBoolean TBObj(L->getLine()); $ExpOpCount++; } >>\r
+  ;\r
+\r
+tostringExp[UINT32 & RootLevel, UINT32 & ExpOpCount] :\r
+  << UINT8 Fmt = 0; >>\r
+  L:StringVal\r
+  {\r
+    Format "=" F:Number ","                            << Fmt = _STOU8(F->getText()); >>\r
+  }\r
+  "\(" vfrStatementExpression[$RootLevel + 1, $ExpOpCount] "\)"\r
+                                                       << { CIfrToString TSObj(L->getLine()); TSObj.SetFormat (Fmt); $ExpOpCount++; } >>\r
+  ;\r
+\r
+unintExp[UINT32 & RootLevel, UINT32 & ExpOpCount] :\r
+  L:UnIntVal\r
+  "\(" vfrStatementExpression[$RootLevel + 1, $ExpOpCount] "\)"\r
+                                                       << { CIfrToUint TUObj(L->getLine()); $ExpOpCount++; } >>\r
+  ;\r
+\r
+toupperExp[UINT32 & RootLevel, UINT32 & ExpOpCount] :\r
+  L:ToUpper\r
+  "\(" vfrStatementExpression[$RootLevel + 1, $ExpOpCount] "\)"\r
+                                                       << { CIfrToUpper TUObj(L->getLine()); $ExpOpCount++; } >>\r
+  ;\r
+\r
+tolwerExp[UINT32 & RootLevel, UINT32 & ExpOpCount] :\r
+  L:ToLower\r
+  "\(" vfrStatementExpression[$RootLevel + 1, $ExpOpCount] "\)"\r
+                                                       << { CIfrToLower TLObj(L->getLine()); $ExpOpCount++; } >>\r
+  ;\r
+\r
+vfrExpressionTernaryOp[UINT32 & RootLevel, UINT32 & ExpOpCount] :\r
+    conditionalExp[$RootLevel, $ExpOpCount]\r
+  | findExp[$RootLevel, $ExpOpCount]\r
+  | midExp[$RootLevel, $ExpOpCount]\r
+  | tokenExp[$RootLevel, $ExpOpCount]\r
+  | spanExp[$RootLevel, $ExpOpCount]\r
+  ;\r
+\r
+#token Cond("cond")                                    "cond"\r
+#token Find("find")                                    "find"\r
+#token Mid("mid")                                      "mid"\r
+#token Tok("token")                                    "token"\r
+#token Span("span")                                    "span"\r
+\r
+conditionalExp[UINT32 & RootLevel, UINT32 & ExpOpCount] :\r
+  L:Cond "\("\r
+  vfrStatementExpression[$RootLevel + 1, $ExpOpCount]\r
+  "?"\r
+  vfrStatementExpression[$RootLevel + 1, $ExpOpCount]\r
+  ":"\r
+  vfrStatementExpression[$RootLevel + 1, $ExpOpCount]\r
+  "\)"                                                 << { CIfrConditional CObj(L->getLine()); $ExpOpCount++; } >>\r
+  ;\r
+\r
+findExp[UINT32 & RootLevel, UINT32 & ExpOpCount] :\r
+  << UINT8 Format; >>\r
+  L:Find "\("\r
+  findFormat[Format] ( "\|" findFormat[Format] )*\r
+  ","\r
+  vfrStatementExpression[$RootLevel + 1, $ExpOpCount]\r
+  "," \r
+  vfrStatementExpression[$RootLevel + 1, $ExpOpCount]\r
+  ","\r
+  vfrStatementExpression[$RootLevel + 1, $ExpOpCount]\r
+  "\)"                                                 << { CIfrFind FObj(L->getLine()); FObj.SetFormat (Format); $ExpOpCount++; } >>\r
+  ;\r
+\r
+findFormat [UINT8 & Format] :\r
+    "SENSITIVE"                                        << $Format = 0x00; >>\r
+  | "INSENSITIVE"                                      << $Format = 0x01; >>\r
+  ;\r
+\r
+midExp[UINT32 & RootLevel, UINT32 & ExpOpCount] :\r
+  L:Mid "\("\r
+  vfrStatementExpression[$RootLevel + 1, $ExpOpCount]\r
+  ","\r
+  vfrStatementExpression[$RootLevel + 1, $ExpOpCount]\r
+  ","\r
+  vfrStatementExpression[$RootLevel + 1, $ExpOpCount]\r
+  "\)"                                                 << { CIfrMid MObj(L->getLine()); $ExpOpCount++; } >>\r
+  ;\r
+\r
+tokenExp[UINT32 & RootLevel, UINT32 & ExpOpCount] :\r
+  L:Tok "\("\r
+  vfrStatementExpression[$RootLevel + 1, $ExpOpCount]\r
+  ","\r
+  vfrStatementExpression[$RootLevel + 1, $ExpOpCount]\r
+  "," \r
+  vfrStatementExpression[$RootLevel + 1, $ExpOpCount]\r
+  "\)"                                                 << { CIfrToken TObj(L->getLine()); $ExpOpCount++; } >>\r
+  ;\r
+\r
+spanExp[UINT32 & RootLevel, UINT32 & ExpOpCount] :\r
+  << UINT8 Flags = 0; >>\r
+  S:Span "\("\r
+  FLAGS "=" spanFlags[Flags] ( "\|" spanFlags[Flags] )*\r
+  ","\r
+  vfrStatementExpression[$RootLevel + 1, $ExpOpCount]\r
+  ","\r
+  vfrStatementExpression[$RootLevel + 1, $ExpOpCount]\r
+  ","\r
+  vfrStatementExpression[$RootLevel + 1, $ExpOpCount]\r
+  "\)"                                                 << { CIfrSpan SObj(S->getLine()); SObj.SetFlags(Flags); $ExpOpCount++; } >>\r
+  ;\r
+\r
+spanFlags [UINT8 & Flags] :\r
+    N:Number                                           << $Flags |= _STOU8(N->getText()); >>\r
+  | "LAST_NON_MATCH"                                   << $Flags |= 0x00; >>\r
+  | "FIRST_NON_MATCH"                                  << $Flags |= 0x01; >>\r
+  ;\r
+\r
+#token StringIdentifier("string identifier")    "[A-Za-z_][A-Za-z_0-9]*"\r
+#token Number("numeric value")                  "(0x[0-9A-Fa-f]+) | [0-9]+"\r
+\r
+//******************************************************************************\r
+//\r
+// Parser class definition. \r
+//  \r
+class EfiVfrParser {\r
+<<\r
+private:\r
+  UINT8               mParserStatus;\r
+\r
+  CVfrDefaultStore    mCVfrDefaultStore;\r
+  CVfrVarDataTypeDB   mCVfrVarDataTypeDB;\r
+  CVfrDataStorage     mCVfrDataStorage;\r
+  CVfrQuestionDB      mCVfrQuestionDB;\r
+  CVfrRulesDB         mCVfrRulesDB;\r
+\r
+  CIfrOpHeader        *mCIfrOpHdr;\r
+  VOID                _SAVE_OPHDR_COND (IN CIfrOpHeader &, IN BOOLEAN);\r
+  VOID                _CLEAR_SAVED_OPHDR (VOID);\r
+  VOID                _SET_SAVED_OPHDR_SCOPE (VOID);\r
+\r
+\r
+  EFI_VARSTORE_INFO   mCurrQestVarInfo;\r
+\r
+  VOID                _CRT_OP (IN BOOLEAN);\r
+\r
+  VOID                _SAVE_CURRQEST_VARINFO (IN EFI_VARSTORE_INFO &);\r
+  EFI_VARSTORE_INFO & _GET_CURRQEST_VARTINFO (VOID);\r
+\r
+  UINT8               _GET_CURRQEST_DATATYPE ();\r
+  UINT32              _GET_CURRQEST_VARSIZE ();\r
+\r
+public:\r
+  VOID                _PCATCH (IN EFI_VFR_RETURN_CODE, IN EFI_VFR_RETURN_CODE, IN ANTLRTokenPtr, IN INT8 *);\r
+  VOID                _PCATCH (IN EFI_VFR_RETURN_CODE);\r
+  VOID                _PCATCH (IN EFI_VFR_RETURN_CODE, IN ANTLRTokenPtr);\r
+  VOID                _PCATCH (IN EFI_VFR_RETURN_CODE, IN UINT32);\r
+\r
+  VOID                syn     (ANTLRAbstractToken  *, ANTLRChar *, SetWordType *, ANTLRTokenType, INT32);\r
+\r
+  INT8 *              TrimHex (IN INT8 *, OUT BOOLEAN *);\r
+  UINT8               _STOU8  (IN INT8 *);\r
+  UINT16              _STOU16 (IN INT8 *);\r
+  UINT32              _STOU32 (IN INT8 *);\r
+  UINT64              _STOU64 (IN INT8 *);\r
+  EFI_HII_DATE        _STOD   (IN INT8 *, IN INT8 *, IN INT8 *);\r
+  EFI_HII_TIME        _STOT   (IN INT8 *, IN INT8 *, IN INT8 *);\r
+\r
+  EFI_STRING_ID       _STOSID (IN INT8 *);\r
+  EFI_FORM_ID         _STOFID (IN INT8 *);\r
+  EFI_QUESTION_ID     _STOQID (IN INT8 *);\r
+\r
+  VOID                _STRCAT (IN OUT INT8 **, IN INT8 *);\r
+\r
+  VOID                _CRGUID (EFI_GUID *, INT8 *, INT8 *, INT8 *, INT8 *, INT8 *, INT8 *, INT8 *, INT8 *, INT8 *, INT8 *, INT8 *);\r
+  VOID                _DeclareDefaultLinearVarStore (IN UINT32);\r
+  VOID                _DeclareStandardDefaultStorage (IN UINT32);\r
+\r
+\r
+  VOID                AssignQuestionKey (IN CIfrQuestionHeader &, IN ANTLRTokenPtr);\r
+\r
+  VOID                ConvertIdExpr         (IN UINT32 &, IN UINT32, IN EFI_QUESTION_ID, IN INT8 *, IN UINT32);\r
+  VOID                IdEqValDoSpecial      (IN UINT32 &, IN UINT32, IN EFI_QUESTION_ID, IN INT8 *, IN UINT32, IN UINT16, IN EFI_COMPARE_TYPE);\r
+  VOID                IdEqIdDoSpecial       (IN UINT32 &, IN UINT32, IN EFI_QUESTION_ID, IN INT8 *, IN UINT32, IN EFI_QUESTION_ID, IN INT8 *, IN UINT32, IN EFI_COMPARE_TYPE);\r
+  VOID                IdEqListDoSpecial     (IN UINT32 &, IN UINT32, IN EFI_QUESTION_ID, IN INT8 *, IN UINT32, IN UINT16, IN UINT16 *);\r
+>>\r
+}\r
+\r
+<<\r
+VOID\r
+EfiVfrParser::_SAVE_OPHDR_COND (\r
+  IN CIfrOpHeader &OpHdr, \r
+  IN BOOLEAN      Cond\r
+  )\r
+{\r
+  if (Cond == TRUE) {\r
+#ifdef VFREXP_DEBUG\r
+    printf ("######_SAVE_OPHDR_COND\n");\r
+#endif\r
+    if (mCIfrOpHdr != NULL) {\r
+#ifdef VFREXP_DEBUG\r
+      printf ("######_SAVE_OPHDR_COND Error\n");\r
+#endif\r
+      return ;\r
+    }\r
+       mCIfrOpHdr = new CIfrOpHeader(OpHdr);\r
+  }\r
+}\r
+\r
+VOID\r
+EfiVfrParser::_CLEAR_SAVED_OPHDR (\r
+  VOID\r
+  )\r
+{\r
+#ifdef VFREXP_DEBUG\r
+  printf ("######_CLEAR_SAVED_OPHDR\n");\r
+#endif\r
+  mCIfrOpHdr = NULL;\r
+}\r
+\r
+VOID\r
+EfiVfrParser::_SET_SAVED_OPHDR_SCOPE (\r
+  VOID\r
+  )\r
+{\r
+#ifdef VFREXP_DEBUG\r
+  printf ("#######_SET_SAVED_OPHDR_SCOPE\n");\r
+#endif\r
+  mCIfrOpHdr->SetScope (1);\r
+}\r
+\r
+VOID\r
+EfiVfrParser::_CRT_OP (\r
+  IN BOOLEAN Crt\r
+  )\r
+{\r
+  gCreateOp = Crt;\r
+}\r
+\r
+VOID\r
+EfiVfrParser::_SAVE_CURRQEST_VARINFO (\r
+  IN EFI_VARSTORE_INFO &Info\r
+  )\r
+{\r
+  mCurrQestVarInfo = Info;\r
+}\r
+\r
+EFI_VARSTORE_INFO &\r
+EfiVfrParser::_GET_CURRQEST_VARTINFO (\r
+  VOID\r
+  )\r
+{\r
+  return mCurrQestVarInfo;\r
+}\r
+\r
+UINT8\r
+EfiVfrParser::_GET_CURRQEST_DATATYPE (\r
+  VOID\r
+  )\r
+{\r
+  return mCurrQestVarInfo.mVarType;\r
+}\r
+\r
+UINT32\r
+EfiVfrParser::_GET_CURRQEST_VARSIZE (\r
+  VOID\r
+  )\r
+{\r
+  return mCurrQestVarInfo.mVarTotalSize;\r
+}\r
+\r
+VOID\r
+EfiVfrParser::_PCATCH (\r
+  IN EFI_VFR_RETURN_CODE ReturnCode,\r
+  IN EFI_VFR_RETURN_CODE ExpectCode,\r
+  IN ANTLRTokenPtr       Tok,\r
+  IN INT8                *ErrorMsg\r
+  )\r
+{\r
+  if (ReturnCode != ExpectCode) {\r
+    mParserStatus++;\r
+    gCVfrErrorHandle.PrintError (Tok->getLine(), Tok->getText(), ErrorMsg);\r
+  }\r
+}\r
+\r
+VOID\r
+EfiVfrParser::_PCATCH (\r
+  IN EFI_VFR_RETURN_CODE ReturnCode\r
+  )\r
+{\r
+  mParserStatus += gCVfrErrorHandle.HandleError (ReturnCode);\r
+}\r
+\r
+VOID\r
+EfiVfrParser::_PCATCH (\r
+  IN EFI_VFR_RETURN_CODE ReturnCode,\r
+  IN ANTLRTokenPtr       Tok\r
+  )\r
+{\r
+  mParserStatus += gCVfrErrorHandle.HandleError (ReturnCode, Tok->getLine(), Tok->getText());\r
+}\r
+\r
+VOID\r
+EfiVfrParser::_PCATCH (\r
+  IN EFI_VFR_RETURN_CODE ReturnCode,\r
+  IN UINT32              LineNum\r
+  )\r
+{\r
+  mParserStatus += gCVfrErrorHandle.HandleError (ReturnCode, LineNum);\r
+}\r
+\r
+VOID \r
+EfiVfrParser::syn (\r
+  ANTLRAbstractToken  *Tok, \r
+  ANTLRChar           *Egroup, \r
+  SetWordType         *Eset, \r
+  ANTLRTokenType      ETok, \r
+  INT32               Huh\r
+  )\r
+{\r
+  gCVfrErrorHandle.HandleError (VFR_RETURN_MISMATCHED, Tok->getLine(), Tok->getText());\r
+\r
+  mParserStatus += 1;\r
+}\r
+\r
+INT8 *\r
+EfiVfrParser::TrimHex (\r
+  IN  INT8    *Str,\r
+  OUT BOOLEAN *IsHex\r
+  )\r
+{\r
+  *IsHex = FALSE;\r
+\r
+  while (*Str && *Str == ' ') {\r
+    Str++;\r
+  }\r
+  while (*Str && *Str == '0') {\r
+    Str++;\r
+  }\r
+  if (*Str && (*Str == 'x' || *Str == 'X')) {\r
+    Str++;\r
+    *IsHex = TRUE;\r
+  }\r
+\r
+  return Str;\r
+}\r
+\r
+UINT8\r
+EfiVfrParser::_STOU8 (\r
+  IN INT8 *Str\r
+  )\r
+{\r
+  BOOLEAN IsHex;\r
+  UINT8   Value;\r
+  INT8    c;\r
+\r
+  Str = TrimHex (Str, &IsHex);\r
+  for (Value = 0; (c = *Str) != '\0'; Str++) {\r
+    //\r
+    // BUG: does not handle overflow here\r
+    //\r
+       (IsHex == TRUE) ? (Value <<= 4) : (Value *= 10);\r
+\r
+    if ((IsHex == TRUE) && (c >= 'a') && (c <= 'f')) {\r
+      Value += (c - 'a' + 10);\r
+    }\r
+    if ((IsHex == TRUE) && (c >= 'A') && (c <= 'F')) {\r
+      Value += (c - 'A' + 10);\r
+    }\r
+    if (c >= '0' && c <= '9') {\r
+      Value += (c - '0');\r
+    } \r
+  }\r
+\r
+  return Value;\r
+}\r
+\r
+UINT16\r
+EfiVfrParser::_STOU16 (\r
+  IN INT8 *Str\r
+  )\r
+{\r
+  BOOLEAN IsHex;\r
+  UINT16  Value;\r
+  INT8    c;\r
+\r
+  Str = TrimHex (Str, &IsHex);\r
+  for (Value = 0; (c = *Str) != '\0'; Str++) {\r
+    //\r
+    // BUG: does not handle overflow here\r
+    //\r
+       (IsHex == TRUE) ? (Value <<= 4) : (Value *= 10);\r
+\r
+    if ((IsHex == TRUE) && (c >= 'a') && (c <= 'f')) {\r
+      Value += (c - 'a' + 10);\r
+    }\r
+    if ((IsHex == TRUE) && (c >= 'A') && (c <= 'F')) {\r
+      Value += (c - 'A' + 10);\r
+    }\r
+    if (c >= '0' && c <= '9') {\r
+      Value += (c - '0');\r
+    } \r
+  }\r
+\r
+  return Value;\r
+}\r
+\r
+UINT32\r
+EfiVfrParser::_STOU32 (\r
+  IN INT8 *Str\r
+  )\r
+{\r
+  BOOLEAN IsHex;\r
+  UINT32  Value;\r
+  INT8    c;\r
+\r
+  Str = TrimHex (Str, &IsHex);\r
+  for (Value = 0; (c = *Str) != '\0'; Str++) {\r
+    //\r
+    // BUG: does not handle overflow here\r
+    //\r
+       (IsHex == TRUE) ? (Value <<= 4) : (Value *= 10);\r
+\r
+    if ((IsHex == TRUE) && (c >= 'a') && (c <= 'f')) {\r
+      Value += (c - 'a' + 10);\r
+    }\r
+    if ((IsHex == TRUE) && (c >= 'A') && (c <= 'F')) {\r
+      Value += (c - 'A' + 10);\r
+    }\r
+    if (c >= '0' && c <= '9') {\r
+      Value += (c - '0');\r
+    } \r
+  }\r
+\r
+  return Value;\r
+}\r
+\r
+UINT64\r
+EfiVfrParser::_STOU64 (\r
+  IN INT8 *Str\r
+  )\r
+{ \r
+  BOOLEAN IsHex;\r
+  UINT64  Value;\r
+  INT8    c;\r
+\r
+  Str = TrimHex (Str, &IsHex);\r
+  for (Value = 0; (c = *Str) != '\0'; Str++) {\r
+    //\r
+    // BUG: does not handle overflow here\r
+    //\r
+       (IsHex == TRUE) ? (Value <<= 4) : (Value *= 10);\r
+\r
+    if ((IsHex == TRUE) && (c >= 'a') && (c <= 'f')) {\r
+      Value += (c - 'a' + 10);\r
+    }\r
+    if ((IsHex == TRUE) && (c >= 'A') && (c <= 'F')) {\r
+      Value += (c - 'A' + 10);\r
+    }\r
+    if (c >= '0' && c <= '9') {\r
+      Value += (c - '0');\r
+    } \r
+  }\r
+\r
+  return Value;\r
+} \r
+\r
+EFI_HII_DATE\r
+EfiVfrParser::_STOD (\r
+  IN INT8 *Year, \r
+  IN INT8 *Month, \r
+  IN INT8 *Day\r
+  )\r
+{\r
+  EFI_HII_DATE Date;\r
+\r
+  Date.Year  = _STOU16 (Year);\r
+  Date.Month = _STOU8 (Month);\r
+  Date.Day   = _STOU8 (Day);\r
+\r
+  return Date;\r
+}\r
+\r
+EFI_HII_TIME\r
+EfiVfrParser::_STOT (\r
+  IN INT8 *Hour, \r
+  IN INT8 *Minute, \r
+  IN INT8 *Second\r
+  )\r
+{\r
+  EFI_HII_TIME Time;\r
+\r
+  Time.Hour   = _STOU8 (Hour);\r
+  Time.Minute = _STOU8 (Minute);\r
+  Time.Second = _STOU8 (Second);\r
+\r
+  return Time;\r
+}\r
+\r
+EFI_STRING_ID\r
+EfiVfrParser::_STOSID (\r
+  IN INT8 *Str\r
+  )\r
+{\r
+  return (EFI_STRING_ID)_STOU16(Str);\r
+}\r
+\r
+EFI_FORM_ID\r
+EfiVfrParser::_STOFID (\r
+  IN INT8 *Str\r
+  )\r
+{\r
+  return (EFI_FORM_ID)_STOU16(Str);\r
+}\r
+\r
+EFI_QUESTION_ID \r
+EfiVfrParser::_STOQID (\r
+  IN INT8 *Str\r
+  )\r
+{\r
+  return (EFI_QUESTION_ID)_STOU16(Str);\r
+}\r
+\r
+VOID\r
+EfiVfrParser::_STRCAT (\r
+  IN OUT INT8 **Dest,\r
+  IN INT8     *Src\r
+  )\r
+{\r
+  INT8   *NewStr;\r
+  UINT32 Len;\r
+\r
+  if ((Dest == NULL) || (Src == NULL)) {\r
+    return;\r
+  }\r
+\r
+  Len = (*Dest == NULL) ? 0 : strlen (*Dest);\r
+  Len += strlen (Src);\r
+  if ((NewStr = new INT8[Len + 1]) == NULL) {\r
+    return;\r
+  }\r
+  NewStr[0] = '\0';\r
+  if (*Dest != NULL) {\r
+    strcpy (NewStr, *Dest);\r
+  }\r
+  strcat (NewStr, Src);\r
+\r
+  *Dest = NewStr;\r
+}\r
+\r
+VOID\r
+EfiVfrParser::_CRGUID (\r
+  IN EFI_GUID *Guid, \r
+  IN INT8     *G1, \r
+  IN INT8     *G2, \r
+  IN INT8     *G3, \r
+  IN INT8     *G4, \r
+  IN INT8     *G5, \r
+  IN INT8     *G6, \r
+  IN INT8     *G7, \r
+  IN INT8     *G8, \r
+  IN INT8     *G9, \r
+  IN INT8     *G10, \r
+  IN INT8     *G11\r
+  )\r
+{\r
+  Guid->Data1 = _STOU32 (G1);\r
+  Guid->Data2 = _STOU16 (G2);\r
+  Guid->Data3 = _STOU16 (G3);\r
+  Guid->Data4[0] = _STOU8(G4);\r
+  Guid->Data4[1] = _STOU8(G5);\r
+  Guid->Data4[2] = _STOU8(G6);\r
+  Guid->Data4[3] = _STOU8(G7);\r
+  Guid->Data4[4] = _STOU8(G8);\r
+  Guid->Data4[5] = _STOU8(G9);\r
+  Guid->Data4[6] = _STOU8(G10);\r
+  Guid->Data4[7] = _STOU8(G11);\r
+}\r
+\r
+VOID\r
+EfiVfrParser::_DeclareDefaultLinearVarStore (\r
+  IN UINT32 LineNo\r
+  )\r
+{\r
+  UINT32            Index;\r
+  INT8              **TypeNameList;\r
+  UINT32            ListSize;\r
+  EFI_GUID          DefaultGuid =  { 0x9db3c415, 0xda00, 0x4233, { 0xae, 0xc6, 0x79, 0xb, 0x4f, 0x5b, 0x45, 0x66 } };\r
+\r
+  mCVfrVarDataTypeDB.GetUserDefinedTypeNameList (&TypeNameList, &ListSize);\r
+\r
+  for (Index = 0; Index < ListSize; Index++) {\r
+    UINT32            Size;\r
+    EFI_VARSTORE_ID   VarStoreId;\r
+    CIfrVarStore      VSObj;\r
+\r
+    VSObj.SetLineNo (LineNo);\r
+    mCVfrDataStorage.DeclareBufferVarStore (\r
+                       TypeNameList[Index], \r
+                       &DefaultGuid, \r
+                       &mCVfrVarDataTypeDB, \r
+                       TypeNameList[Index],\r
+                       EFI_VARSTORE_ID_INVALID\r
+                       );\r
+    mCVfrDataStorage.GetVarStoreId(TypeNameList[Index], &VarStoreId);\r
+    VSObj.SetVarStoreId (VarStoreId);\r
+    mCVfrVarDataTypeDB.GetDataTypeSize(TypeNameList[Index], &Size);\r
+    VSObj.SetSize (Size);\r
+    VSObj.SetName (TypeNameList[Index]);\r
+    VSObj.SetGuid (&DefaultGuid);\r
+  }\r
+\r
+  if (mCVfrVarDataTypeDB.IsTypeNameDefined ("Date") == FALSE) {\r
+    UINT32            Size;\r
+    EFI_VARSTORE_ID   VarStoreId;\r
+    CIfrVarStore      VSObj;\r
+\r
+    VSObj.SetLineNo (LineNo);\r
+    mCVfrDataStorage.DeclareBufferVarStore (\r
+                       "Date", \r
+                                          &DefaultGuid, \r
+                                          &mCVfrVarDataTypeDB, \r
+                                          "EFI_HII_DATE",\r
+                       EFI_VARSTORE_ID_INVALID\r
+                       );\r
+    mCVfrDataStorage.GetVarStoreId("Date", &VarStoreId);\r
+    VSObj.SetVarStoreId (VarStoreId);\r
+    mCVfrVarDataTypeDB.GetDataTypeSize("EFI_HII_DATE", &Size);\r
+    VSObj.SetSize (Size);\r
+    VSObj.SetName ("Date");\r
+    VSObj.SetGuid (&DefaultGuid);\r
+  }\r
+\r
+  if (mCVfrVarDataTypeDB.IsTypeNameDefined ("Time") == FALSE) {\r
+    UINT32            Size;\r
+    EFI_VARSTORE_ID   VarStoreId;\r
+    CIfrVarStore      VSObj;\r
+\r
+    VSObj.SetLineNo (LineNo);\r
+    mCVfrDataStorage.DeclareBufferVarStore (\r
+                       "Time", \r
+                       &DefaultGuid, \r
+                       &mCVfrVarDataTypeDB, \r
+                       "EFI_HII_TIME",\r
+                       EFI_VARSTORE_ID_INVALID\r
+                       );\r
+    mCVfrDataStorage.GetVarStoreId("Time", &VarStoreId);\r
+    VSObj.SetVarStoreId (VarStoreId);\r
+    mCVfrVarDataTypeDB.GetDataTypeSize("EFI_HII_TIME", &Size);\r
+    VSObj.SetSize (Size);\r
+       VSObj.SetName ("Time");\r
+    VSObj.SetGuid (&DefaultGuid);\r
+  }\r
+}\r
+\r
+VOID\r
+EfiVfrParser::_DeclareStandardDefaultStorage (\r
+  IN UINT32 LineNo\r
+  )\r
+{\r
+  CIfrDefaultStore DSObj; \r
+\r
+  mCVfrDefaultStore.RegisterDefaultStore (DSObj.GetObjBinAddr(), "Standard Defaults", EFI_STRING_ID_INVALID, EFI_HII_DEFAULT_CLASS_STANDARD);\r
+  DSObj.SetLineNo (LineNo);\r
+  DSObj.SetDefaultName (EFI_STRING_ID_INVALID);\r
+  DSObj.SetDefaultId (EFI_HII_DEFAULT_CLASS_STANDARD);\r
+}\r
+\r
+VOID\r
+EfiVfrParser::AssignQuestionKey (\r
+  IN CIfrQuestionHeader   &QHObj, \r
+  IN ANTLRTokenPtr        KeyTok\r
+  )\r
+{\r
+  UINT16 KeyValue;\r
+\r
+  if (KeyTok == NULL) {\r
+    return;\r
+  }\r
+\r
+  KeyValue = _STOU16 (KeyTok->getText());\r
+\r
+  if (QHObj.FLAGS () & EFI_IFR_FLAG_CALLBACK) {\r
+  /*\r
+   * if the question is not CALLBACK ignore the key.\r
+   */\r
+    _PCATCH(mCVfrQuestionDB.UpdateQuestionId (QHObj.QUESTION_ID(), KeyValue), KeyTok);\r
+    QHObj.SetQuestionId (KeyValue);\r
+  }\r
+}\r
+\r
+VOID\r
+EfiVfrParser::ConvertIdExpr (\r
+  IN UINT32          &ExpOpCount, \r
+  IN UINT32          LineNo,\r
+  IN EFI_QUESTION_ID QId,\r
+  IN INT8            *VarIdStr,\r
+  IN UINT32          BitMask\r
+  )\r
+{\r
+  CIfrQuestionRef1 QR1Obj(LineNo);\r
+  QR1Obj.SetQuestionId (QId, VarIdStr, LineNo);\r
+  _SAVE_OPHDR_COND (QR1Obj, (ExpOpCount == 0));\r
+\r
+  if (BitMask != 0) {\r
+    CIfrUint32       U32Obj(LineNo);\r
+    U32Obj.SetValue (BitMask);\r
+\r
+    CIfrBitWiseAnd   BWAObj(LineNo);\r
+\r
+    CIfrUint8        U8Obj(LineNo);\r
+    switch (BitMask) {\r
+    case DATE_YEAR_BITMASK   : U8Obj.SetValue (0); break;\r
+    case TIME_SECOND_BITMASK : U8Obj.SetValue (0x10); break;\r
+    case DATE_DAY_BITMASK    : U8Obj.SetValue (0x18); break;\r
+    case TIME_HOUR_BITMASK   : U8Obj.SetValue (0); break;\r
+    case TIME_MINUTE_BITMASK : U8Obj.SetValue (0x8); break;\r
+    }\r
+\r
+    CIfrShiftRight   SRObj(LineNo);\r
+  }\r
+\r
+  ExpOpCount += 4;\r
+}\r
+\r
+VOID\r
+EfiVfrParser::IdEqValDoSpecial (\r
+  IN UINT32           &ExpOpCount, \r
+  IN UINT32           LineNo,\r
+  IN EFI_QUESTION_ID  QId,\r
+  IN INT8             *VarIdStr,\r
+  IN UINT32           BitMask,\r
+  IN UINT16           ConstVal,\r
+  IN EFI_COMPARE_TYPE CompareType\r
+  )\r
+{\r
+  ConvertIdExpr (ExpOpCount, LineNo, QId, VarIdStr, BitMask);\r
+\r
+  if (ConstVal > 0xFF) {\r
+    CIfrUint16       U16Obj(LineNo);\r
+    U16Obj.SetValue (ConstVal);\r
+  } else {\r
+    CIfrUint8        U8Obj(LineNo);\r
+    U8Obj.SetValue ((UINT8)ConstVal);\r
+  }\r
+\r
+  switch (CompareType) {\r
+  case EQUAL :\r
+    {\r
+      CIfrEqual EObj(LineNo);\r
+      break;\r
+    }\r
+  case LESS_EQUAL :\r
+    {\r
+      CIfrLessEqual LEObj(LineNo);\r
+      break;\r
+    }\r
+  case LESS_THAN :\r
+    {\r
+      CIfrLessThan LTObj(LineNo);\r
+      break;\r
+    }\r
+  case GREATER_EQUAL :\r
+    {\r
+      CIfrGreaterEqual GEObj(LineNo);\r
+      break;\r
+    }\r
+  case GREATER_THAN :\r
+    {\r
+      CIfrGreaterThan GTObj(LineNo);\r
+      break;\r
+    }\r
+  }\r
+\r
+  ExpOpCount += 2;\r
+}\r
+\r
+VOID\r
+EfiVfrParser::IdEqIdDoSpecial (\r
+  IN UINT32           &ExpOpCount, \r
+  IN UINT32           LineNo,\r
+  IN EFI_QUESTION_ID  QId1,\r
+  IN INT8             *VarId1Str,\r
+  IN UINT32           BitMask1,\r
+  IN EFI_QUESTION_ID  QId2,\r
+  IN INT8             *VarId2Str,\r
+  IN UINT32           BitMask2,\r
+  IN EFI_COMPARE_TYPE CompareType\r
+  )\r
+{\r
+  ConvertIdExpr (ExpOpCount, LineNo, QId1, VarId1Str, BitMask1);\r
+  ConvertIdExpr (ExpOpCount, LineNo, QId2, VarId2Str, BitMask2);\r
+\r
+  switch (CompareType) {\r
+  case EQUAL :\r
+    {\r
+      CIfrEqual EObj(LineNo);\r
+      break;\r
+    }\r
+  case LESS_EQUAL :\r
+    {\r
+      CIfrLessEqual LEObj(LineNo);\r
+      break;\r
+    }\r
+  case LESS_THAN :\r
+    {\r
+      CIfrLessThan LTObj(LineNo);\r
+      break;\r
+    }\r
+  case GREATER_EQUAL :\r
+    {\r
+      CIfrGreaterEqual GEObj(LineNo);\r
+      break;\r
+    }\r
+  case GREATER_THAN :\r
+    {\r
+      CIfrGreaterThan GTObj(LineNo);\r
+      break;\r
+    }\r
+  }\r
+\r
+  ExpOpCount++;\r
+}\r
+\r
+VOID\r
+EfiVfrParser::IdEqListDoSpecial (\r
+  IN UINT32          &ExpOpCount, \r
+  IN UINT32          LineNo,\r
+  IN EFI_QUESTION_ID QId,\r
+  IN INT8            *VarIdStr,\r
+  IN UINT32          BitMask,\r
+  IN UINT16          ListLen,\r
+  IN UINT16          *ValueList\r
+  )\r
+{\r
+  UINT16 Index;\r
+\r
+  if (ListLen == 0) {\r
+    return;\r
+  }\r
+\r
+  IdEqValDoSpecial (ExpOpCount, LineNo, QId, VarIdStr, BitMask, ValueList[0], EQUAL);\r
+  for (Index = 1; Index < ListLen; Index++) {\r
+    IdEqValDoSpecial (ExpOpCount, LineNo, QId, VarIdStr, BitMask, ValueList[Index], EQUAL);\r
+    CIfrOr OObj (LineNo);\r
+    ExpOpCount++;\r
+  }\r
+}\r
+\r
+>>\r
diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrUtilityLib.cpp b/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrUtilityLib.cpp
new file mode 100644 (file)
index 0000000..8ff77e7
--- /dev/null
@@ -0,0 +1,2695 @@
+#include "stdio.h"\r
+#include "stdlib.h"\r
+#include "VfrUtilityLib.h"\r
+#include "VfrFormPkg.h"\r
+\r
+VOID\r
+CVfrBinaryOutput::WriteLine (\r
+  IN FILE   *pFile,\r
+  IN UINT32 LineBytes,\r
+  IN INT8   *LineHeader,\r
+  IN INT8   *BlkBuf,\r
+  IN UINT32 BlkSize\r
+  )\r
+{\r
+  UINT32    Index;\r
+\r
+  if ((pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) {\r
+    return;\r
+  }\r
+\r
+  for (Index = 0; Index < BlkSize; Index++) {\r
+    if ((Index % LineBytes) == 0) {\r
+      fprintf (pFile, "\n%s", LineHeader);\r
+    }\r
+    fprintf (pFile, "0x%02X,  ", (UINT8)BlkBuf[Index]);\r
+  }\r
+}\r
+\r
+VOID\r
+CVfrBinaryOutput::WriteEnd (\r
+  IN FILE   *pFile,\r
+  IN UINT32 LineBytes,\r
+  IN INT8   *LineHeader,\r
+  IN INT8   *BlkBuf,\r
+  IN UINT32 BlkSize\r
+  )\r
+{\r
+  UINT32    Index;\r
+\r
+  if ((BlkSize == 0) || (pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) {\r
+    return;\r
+  }\r
+\r
+  for (Index = 0; Index < BlkSize - 1; Index++) {\r
+    if ((Index % LineBytes) == 0) {\r
+      fprintf (pFile, "\n%s", LineHeader);\r
+    }\r
+    fprintf (pFile, "0x%02X,  ", (UINT8)BlkBuf[Index]);\r
+  }\r
+\r
+  if ((Index % LineBytes) == 0) {\r
+    fprintf (pFile, "\n%s", LineHeader);\r
+  }\r
+  fprintf (pFile, "0x%02X\n", (UINT8)BlkBuf[Index]);\r
+}\r
+\r
+SConfigInfo::SConfigInfo (\r
+  IN UINT8              Type, \r
+  IN UINT16             Offset, \r
+  IN UINT32             Width, \r
+  IN EFI_IFR_TYPE_VALUE Value\r
+  )\r
+{\r
+  mOffset = Offset;\r
+  mWidth  = (UINT16)Width;\r
+  mValue  = new UINT8[mWidth];\r
+  if (mValue == NULL) {\r
+    return;\r
+  }\r
+\r
+  switch (Type) {\r
+  case EFI_IFR_TYPE_NUM_SIZE_8 :\r
+    memcpy (mValue, &Value.u8, mWidth);\r
+    break;\r
+  case EFI_IFR_TYPE_NUM_SIZE_16 :\r
+    memcpy (mValue, &Value.u16, mWidth);\r
+    break;\r
+  case EFI_IFR_TYPE_NUM_SIZE_32 :\r
+    memcpy (mValue, &Value.u32, mWidth);\r
+    break;\r
+  case EFI_IFR_TYPE_NUM_SIZE_64 :\r
+    memcpy (mValue, &Value.u64, mWidth);\r
+    break;\r
+  case EFI_IFR_TYPE_BOOLEAN :\r
+    memcpy (mValue, &Value.b, mWidth);\r
+    break;\r
+  case EFI_IFR_TYPE_TIME :\r
+    memcpy (mValue, &Value.time, mWidth);\r
+    break;\r
+  case EFI_IFR_TYPE_DATE :\r
+    memcpy (mValue, &Value.date, mWidth);\r
+    break;\r
+  case EFI_IFR_TYPE_STRING :\r
+    memcpy (mValue, &Value.string, mWidth);\r
+    break;\r
+  case EFI_IFR_TYPE_OTHER :\r
+    return;\r
+  }\r
+}\r
+\r
+SConfigInfo::~SConfigInfo (\r
+  VOID\r
+  )\r
+{\r
+  BUFFER_SAFE_FREE (mValue);\r
+}\r
+\r
+SConfigItem::SConfigItem (\r
+  IN INT8                *Id, \r
+  IN INT8                *Info\r
+  )\r
+{\r
+  mId          = NULL;\r
+  mInfo        = NULL;\r
+  mInfoStrList = NULL;\r
+  mNext        = NULL;\r
+\r
+  if (Id != NULL) {\r
+    if ((mId = new INT8[strlen (Id) + 1]) != NULL) {\r
+      strcpy (mId, Id);\r
+    }\r
+  }\r
+\r
+  if (Info != NULL) {\r
+    if ((mInfo = new INT8[strlen (Info) + 1]) != NULL) {\r
+      strcpy (mInfo, Info);\r
+    }\r
+  }\r
+}\r
+\r
+SConfigItem::SConfigItem (\r
+  IN INT8                *Id, \r
+  IN INT8                *Info,\r
+  IN UINT8               Type,\r
+  IN UINT16              Offset,\r
+  IN UINT16              Width,\r
+  IN EFI_IFR_TYPE_VALUE  Value\r
+  )\r
+{\r
+  mId          = NULL;\r
+  mInfo        = NULL;\r
+  mInfoStrList = NULL;\r
+  mNext        = NULL;\r
+\r
+  if (Id != NULL) {\r
+    if ((mId = new INT8[strlen (Id) + 1]) != NULL) {\r
+      strcpy (mId, Id);\r
+    }\r
+  }\r
+\r
+  if (Info != NULL) {\r
+    if ((mInfo = new INT8[strlen (Info) + 1]) != NULL) {\r
+      strcpy (mInfo, Info);\r
+    }\r
+  }\r
+\r
+  mInfoStrList = new SConfigInfo(Type, Offset, Width, Value);\r
+}\r
+\r
+SConfigItem::~SConfigItem (\r
+  VOID\r
+  )\r
+{\r
+  SConfigInfo  *Info;\r
+\r
+  BUFFER_SAFE_FREE (mId);\r
+  BUFFER_SAFE_FREE (mInfo);\r
+  while (mInfoStrList != NULL) {\r
+    Info = mInfoStrList;\r
+    mInfoStrList = mInfoStrList->mNext;\r
+\r
+    BUFFER_SAFE_FREE (Info);\r
+  }\r
+}\r
+\r
+UINT8\r
+CVfrBufferConfig::Register (\r
+  IN INT8                *Id, \r
+  IN INT8                *Info\r
+  )\r
+{\r
+  SConfigItem *pNew;\r
+\r
+  if (Select (Id) == 0) {\r
+    return 1;\r
+  }\r
+\r
+  if ((pNew = new SConfigItem (Id, Info)) == NULL) {\r
+    return 2;\r
+  }\r
+  if (mItemListHead == NULL) {\r
+    mItemListHead = pNew;\r
+    mItemListTail = pNew;\r
+  } else {\r
+    mItemListTail->mNext = pNew;\r
+    mItemListTail = pNew;\r
+  }\r
+  mItemListPos    = pNew;\r
+\r
+  return 0;\r
+}\r
+\r
+VOID\r
+CVfrBufferConfig::Open (\r
+  VOID\r
+  )\r
+{\r
+  mItemListPos = mItemListHead;\r
+}\r
+\r
+BOOLEAN\r
+CVfrBufferConfig::Eof(\r
+  VOID\r
+  )\r
+{\r
+  return (mItemListPos == NULL) ? TRUE : FALSE;\r
+}\r
+\r
+UINT8\r
+CVfrBufferConfig::Select (\r
+  IN INT8 *Id,\r
+  IN INT8 *Info\r
+  )\r
+{\r
+  SConfigItem *p;\r
+\r
+  if (Id == NULL) {\r
+    mItemListPos = mItemListHead;\r
+    return 0;\r
+  } else {\r
+    for (p = mItemListHead; p != NULL; p = p->mNext) {\r
+      if (strcmp (p->mId, Id) != 0) {\r
+        continue;\r
+      }\r
+\r
+      if ((p->mInfo != NULL) && (Info != NULL)) {\r
+        if (strcmp (p->mInfo, Info) != 0) {\r
+          continue;\r
+        }\r
+      }\r
+\r
+      mItemListPos = p;\r
+      return 0;\r
+    }\r
+  }\r
+\r
+  return 1;\r
+}\r
+\r
+UINT8\r
+CVfrBufferConfig::Write (\r
+  IN CONST CHAR8         Mode,\r
+  IN INT8                *Id, \r
+  IN INT8                *Info,\r
+  IN UINT8               Type,\r
+  IN UINT16              Offset,\r
+  IN UINT32              Width,\r
+  IN EFI_IFR_TYPE_VALUE  Value\r
+  )\r
+{\r
+  UINT8         Ret;\r
+  SConfigItem   *pItem;\r
+  SConfigInfo   *pInfo;\r
+\r
+  switch (Mode) {\r
+  case 'a' : // add\r
+    if (Select (Id) == 0) {\r
+      if((pInfo = new SConfigInfo (Type, Offset, Width, Value)) == NULL) {\r
+        return 2;\r
+      }\r
+      pInfo->mNext = mItemListPos->mInfoStrList;\r
+      mItemListPos->mInfoStrList = pInfo;\r
+    } else {\r
+      if ((pItem = new SConfigItem (Id, Info, Type, Offset, Width, Value)) == NULL) {\r
+        return 2;\r
+      }\r
+      if (mItemListHead == NULL) {\r
+        mItemListHead = pItem;\r
+        mItemListTail = pItem;\r
+      } else {\r
+        mItemListTail->mNext = pItem;\r
+        mItemListTail = pItem;\r
+      }\r
+      mItemListPos = pItem;\r
+    }\r
+    break;\r
+\r
+  case 'd' : // delete\r
+    if ((Ret = Select (Id)) != 0) {\r
+      return Ret;\r
+    }\r
+\r
+    if (mItemListHead == mItemListPos) {\r
+      mItemListHead = mItemListPos->mNext;\r
+      delete mItemListPos;\r
+      break;\r
+    }\r
+\r
+    for (pItem = mItemListHead; pItem->mNext != mItemListPos; pItem = pItem->mNext)\r
+      ;\r
+\r
+    pItem->mNext = mItemListPos->mNext;\r
+    if (mItemListTail == mItemListPos) {\r
+      mItemListTail = pItem;\r
+    }\r
+    delete mItemListPos;\r
+    mItemListPos = pItem->mNext;\r
+    break;\r
+\r
+  case 'i' : // set info\r
+    if ((Ret = Select (Id)) != 0) {\r
+      return Ret;\r
+    }\r
+    if (mItemListPos->mInfo != NULL) {\r
+      delete mItemListPos->mInfo;\r
+    }\r
+    mItemListPos->mInfo = NULL;\r
+    if (Info != NULL) {\r
+      if ((mItemListPos->mInfo = new INT8[strlen (Info) + 1]) == NULL) {\r
+        return 2;\r
+      }\r
+      strcpy (mItemListPos->mInfo, Info);\r
+    }\r
+    break;\r
+\r
+  default :\r
+    return 1;\r
+  }\r
+\r
+  return 0;\r
+}\r
+\r
+#if 0\r
+UINT8\r
+CVfrBufferConfig::ReadId (\r
+  OUT INT8   **Id, \r
+  OUT INT8   **Info\r
+  )\r
+{\r
+  if (mInfoStrItemListPos == NULL) {\r
+    return 1; // end read or some error occur\r
+  }\r
+\r
+  if (Id != NULL) {\r
+    *Id = new INT8 (strlen (mInfoStrItemListPos->mId + 1));\r
+    strcpy (*Id, mInfoStrItemListPos->mId);\r
+  }\r
+  if (Info != NULL) {\r
+    *Info = new INT8 (strlen (mInfoStrItemListPos->mInfo + 1));\r
+    strcpy (*Info, mInfoStrItemListPos->mInfo);\r
+  }\r
+\r
+  return 0;\r
+}\r
+\r
+UINT8\r
+CVfrBufferConfig::ReadInfo (\r
+  IN  INT8      *Id, \r
+  IN  UINT32    Index,\r
+  IN OUT UINT32 &Number,\r
+  OUT INT8      *Offset,\r
+  OUT INT8      *Width,\r
+  OUT INT8      *Value\r
+  )\r
+{\r
+  UINT8         ret;\r
+  SConfigInfo   *p;\r
+  UINT32        idx;\r
+  UINT32        num;\r
+\r
+  if (Id != NULL) {\r
+    if ((ret = Select (Id)) != 0) {\r
+      return ret;\r
+    }\r
+  }\r
+\r
+  if (mInfoStrItemListPos == NULL) {\r
+    return 1; // end read or some error occur\r
+  }\r
+\r
+  p = mInfoStrItemListPos->mInfoStrList;\r
+  for (idx = 0; (idx < Index) && (p != NULL); idx++) {\r
+    p = p->mNext;\r
+  }\r
+  if (p == NULL) {\r
+    return 1;\r
+  }\r
+\r
+  if (Offset != NULL) {\r
+    Offset[0] = '\0';\r
+  }\r
+  if (Width != NULL) {\r
+    Width[0] = '\0';\r
+  }\r
+  if (Value != NULL) {\r
+    Value[0] = '\0';\r
+  }\r
+\r
+  while (num < Number) {\r
+    if (Offset != NULL) {\r
+      strcat (Offset, p->mOffset);\r
+    }\r
+    if (Width != NULL) {\r
+      strcat (Width, p->mWidth);\r
+    }\r
+    if (Value != NULL) {\r
+      strcat (Value, p->mValue);\r
+    }\r
+\r
+    num++;\r
+    if ((p = p->mNext) == NULL) {\r
+      break;\r
+    }\r
+  }\r
+  Number = num;\r
+\r
+  return 0;\r
+}\r
+\r
+VOID\r
+CVfrBufferConfig::ReadNext (\r
+  VOID\r
+  )\r
+{\r
+  if (mItemListPos != NULL) {\r
+    mItemListPos = mItemListPos->mNext;\r
+  }\r
+}\r
+#endif\r
+\r
+VOID\r
+CVfrBufferConfig::Close (\r
+  VOID\r
+  )\r
+{\r
+  mItemListPos = NULL;\r
+}\r
+\r
+#define BYTES_PRE_LINE 0x10\r
+\r
+VOID\r
+CVfrBufferConfig::OutputCFile (\r
+  IN FILE  *pFile,\r
+  IN INT8  *BaseName\r
+  )\r
+{\r
+  CVfrBinaryOutput Output;\r
+  SConfigItem      *Item;\r
+  SConfigInfo      *Info;\r
+  UINT32           TotalLen;\r
+\r
+  if (pFile == NULL) {\r
+    return;\r
+  }\r
+\r
+  for (Item = mItemListHead; Item != NULL; Item = Item->mNext) {\r
+    if (Item->mInfoStrList != NULL) {\r
+      fprintf (pFile, "\nunsigned char %s%sDefault%04x[] = {", BaseName, Item->mId, Item->mInfo);\r
+\r
+      TotalLen = sizeof (UINT32);\r
+      for (Info = Item->mInfoStrList; Info != NULL; Info = Info->mNext) {\r
+        TotalLen += Info->mWidth + sizeof (UINT16) * 2;\r
+      }\r
+      Output.WriteLine (pFile, BYTES_PRE_LINE, "  ", (INT8 *)&TotalLen, sizeof (UINT32));\r
+\r
+      for (Info = Item->mInfoStrList; Info != NULL; Info = Info->mNext) {\r
+        Output.WriteLine (pFile, BYTES_PRE_LINE, "  ", (INT8 *)&Info->mOffset, sizeof (UINT16));\r
+        Output.WriteLine (pFile, BYTES_PRE_LINE, "  ", (INT8 *)&Info->mWidth, sizeof (UINT16));\r
+        if (Info->mNext == NULL) {\r
+          Output.WriteEnd (pFile, BYTES_PRE_LINE, "  ", (INT8 *)Info->mValue, Info->mWidth);\r
+        } else {\r
+          Output.WriteLine (pFile, BYTES_PRE_LINE, "  ", (INT8 *)Info->mValue, Info->mWidth);\r
+        }\r
+        fprintf (pFile, "\n"); \r
+      }\r
+      fprintf (pFile, "};\n"); \r
+    }\r
+  }\r
+}\r
+\r
+CVfrBufferConfig::CVfrBufferConfig (\r
+  VOID\r
+  )\r
+{\r
+  mItemListHead = NULL;\r
+  mItemListTail = NULL;\r
+  mItemListPos  = NULL;\r
+}\r
+\r
+CVfrBufferConfig::~CVfrBufferConfig (\r
+  VOID\r
+  )\r
+{\r
+  SConfigItem *p;\r
+\r
+  while (mItemListHead != NULL) {\r
+    p = mItemListHead;\r
+    mItemListHead = mItemListHead->mNext;\r
+    delete p;\r
+  }\r
+\r
+  mItemListHead = NULL;\r
+  mItemListTail = NULL;\r
+  mItemListPos  = NULL;\r
+}\r
+\r
+CVfrBufferConfig gCVfrBufferConfig;\r
+\r
+static struct {\r
+  INT8   *mTypeName;\r
+  UINT8  mType;\r
+  UINT32 mSize;\r
+  UINT32 mAlign;\r
+} gInternalTypesTable [] = {\r
+  {"UINT64",        EFI_IFR_TYPE_NUM_SIZE_64, sizeof (UINT64),       sizeof (UINT64)},\r
+  {"UINT32",        EFI_IFR_TYPE_NUM_SIZE_32, sizeof (UINT32),       sizeof (UINT32)},\r
+  {"UINT16",        EFI_IFR_TYPE_NUM_SIZE_16, sizeof (UINT16),       sizeof (UINT16)},\r
+  {"UINT8",         EFI_IFR_TYPE_NUM_SIZE_8,  sizeof (UINT8),        sizeof (UINT8)},\r
+  {"BOOLEAN",       EFI_IFR_TYPE_BOOLEAN,     sizeof (BOOLEAN),      sizeof (BOOLEAN)},\r
+  {"EFI_HII_DATE",  EFI_IFR_TYPE_DATE,        sizeof (EFI_HII_DATE), sizeof (UINT8)},\r
+  {"EFI_STRING_ID", EFI_IFR_TYPE_STRING,      sizeof (EFI_STRING_ID),sizeof (EFI_STRING_ID)},\r
+  {"EFI_HII_TIME",  EFI_IFR_TYPE_TIME,        sizeof (EFI_HII_TIME), sizeof (UINT8)},\r
+  {NULL,            EFI_IFR_TYPE_OTHER,       0,                     0}\r
+};\r
+\r
+STATIC\r
+BOOLEAN\r
+_IS_INTERNAL_TYPE (\r
+  IN INT8 *TypeName\r
+  )\r
+{\r
+  UINT32  Index;\r
+\r
+  if (TypeName == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  for (Index = 0; gInternalTypesTable[Index].mTypeName != NULL; Index++) {\r
+    if (strcmp (TypeName, gInternalTypesTable[Index].mTypeName) == 0) {\r
+      return TRUE;\r
+    }\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
+STATIC\r
+INT8 *\r
+TrimHex (\r
+  IN  INT8    *Str,\r
+  OUT bool    *IsHex\r
+  )\r
+{\r
+  *IsHex = FALSE;\r
+\r
+  while (*Str && *Str == ' ') {\r
+    Str++;\r
+  }\r
+  while (*Str && *Str == '0') {\r
+    Str++;\r
+  }\r
+  if (*Str && (*Str == 'x' || *Str == 'X')) {\r
+    Str++;\r
+    *IsHex = TRUE;\r
+  }\r
+\r
+  return Str;\r
+}\r
+\r
+UINT32\r
+_STR2U32 (\r
+  IN INT8 *Str\r
+  )\r
+{\r
+  bool    IsHex;\r
+  UINT32  Value;\r
+  INT8    c;\r
+\r
+  Str = TrimHex (Str, &IsHex);\r
+  for (Value = 0; (c = *Str) != '\0'; Str++) {\r
+    //\r
+    // BUG: does not handle overflow here\r
+    //\r
+       (IsHex == TRUE) ? (Value <<= 4) : (Value *= 10);\r
+\r
+    if ((IsHex == TRUE) && (c >= 'a') && (c <= 'f')) {\r
+      Value += (c - 'a' + 10);\r
+    }\r
+    if ((IsHex == TRUE) && (c >= 'A') && (c <= 'F')) {\r
+      Value += (c - 'A' + 10);\r
+    }\r
+    if (c >= '0' && c <= '9') {\r
+      Value += (c - '0');\r
+    } \r
+  }\r
+\r
+  return Value;\r
+}\r
+\r
+VOID\r
+CVfrVarDataTypeDB::RegisterNewType (\r
+  IN SVfrDataType  *New\r
+  )\r
+{\r
+  New->mNext               = mDataTypeList;\r
+  mDataTypeList            = New;\r
+}\r
+\r
+EFI_VFR_RETURN_CODE\r
+CVfrVarDataTypeDB::ExtractStructTypeName (\r
+  IN  INT8 *&VarStr, \r
+  OUT INT8 *TName\r
+  )\r
+{\r
+  if (TName == NULL) {\r
+    return VFR_RETURN_FATAL_ERROR;\r
+  }\r
+\r
+  while((*VarStr != '\0') && (*VarStr != '.')) {\r
+    *TName = *VarStr;\r
+    VarStr++;\r
+    TName++;\r
+  }\r
+  *TName = '\0';\r
+  if (*VarStr == '.') {\r
+    VarStr++;\r
+  }\r
+\r
+  return VFR_RETURN_SUCCESS;\r
+}\r
+\r
+EFI_VFR_RETURN_CODE\r
+CVfrVarDataTypeDB::ExtractFieldNameAndArrary (\r
+  IN  INT8   *&VarStr, \r
+  IN  INT8   *FName,\r
+  OUT UINT32 &ArrayIdx\r
+  )\r
+{\r
+  UINT32 Idx;\r
+  INT8   ArrayStr[MAX_NAME_LEN + 1];\r
+\r
+  ArrayIdx = INVALID_ARRAY_INDEX; \r
+\r
+  if (FName == NULL) {\r
+    return VFR_RETURN_FATAL_ERROR;\r
+  }\r
+\r
+  while((*VarStr != '\0') &&\r
+        (*VarStr != '.') && \r
+        (*VarStr != '[') && \r
+        (*VarStr != ']')) {\r
+    *FName = *VarStr;\r
+    VarStr++;\r
+    FName++;\r
+  }\r
+  *FName = '\0';\r
+\r
+  switch (*VarStr) {\r
+  case '.' :\r
+    VarStr++;\r
+  case '\0':\r
+    return VFR_RETURN_SUCCESS;\r
+  case '[' :\r
+    VarStr++;\r
+    for (Idx = 0; (Idx < MAX_NAME_LEN) && (*VarStr != '\0') && (*VarStr != ']'); VarStr++, Idx++) {\r
+      ArrayStr[Idx] = *VarStr;\r
+    }\r
+    ArrayStr[Idx] = '\0';\r
+\r
+    if ((*VarStr != ']') && (ArrayStr[0] == '\0')) {\r
+      return VFR_RETURN_DATA_STRING_ERROR;\r
+    }\r
+    ArrayIdx = _STR2U32 (ArrayStr);\r
+    if (*VarStr == ']') {\r
+      VarStr++;\r
+    }\r
+    return VFR_RETURN_SUCCESS;\r
+  case ']':\r
+    return VFR_RETURN_DATA_STRING_ERROR;\r
+  }\r
+\r
+  return VFR_RETURN_SUCCESS;\r
+}\r
+\r
+EFI_VFR_RETURN_CODE\r
+CVfrVarDataTypeDB::GetTypeField (\r
+  IN  INT8          *FName, \r
+  IN  SVfrDataType  *Type, \r
+  OUT SVfrDataField *&Field\r
+  )\r
+{\r
+  SVfrDataField  *pField = NULL;\r
+\r
+  if ((FName == NULL) && (Type == NULL)) {\r
+    return VFR_RETURN_FATAL_ERROR;\r
+  }\r
+\r
+  for (pField = Type->mMembers; pField != NULL; pField = pField->mNext) {\r
+    if (strcmp (pField->mFieldName, FName) == 0) {\r
+      Field = pField;\r
+      return VFR_RETURN_SUCCESS;\r
+    }\r
+  }\r
+\r
+  return VFR_RETURN_UNDEFINED;\r
+}\r
+\r
+EFI_VFR_RETURN_CODE\r
+CVfrVarDataTypeDB::GetFieldOffset (\r
+  IN  SVfrDataField *Field, \r
+  IN  UINT32        ArrayIdx,\r
+  OUT UINT32        &Offset\r
+  )\r
+{\r
+  if (Field == NULL) {\r
+    return VFR_RETURN_FATAL_ERROR;\r
+  }\r
+\r
+  if ((ArrayIdx != INVALID_ARRAY_INDEX) && ((Field->mArrayNum == 0) || (Field->mArrayNum <= ArrayIdx))) {\r
+    return VFR_RETURN_ERROR_ARRARY_NUM;\r
+  }\r
+\r
+  Offset = Field->mOffset + Field->mFieldType->mTotalSize * ((ArrayIdx == INVALID_ARRAY_INDEX) ? 0 : ArrayIdx);\r
+  return VFR_RETURN_SUCCESS;\r
+}\r
+\r
+UINT8\r
+CVfrVarDataTypeDB::GetFieldWidth (\r
+  IN SVfrDataField *Field\r
+  )\r
+{\r
+  if (Field == NULL) {\r
+    return 0;\r
+  }\r
+\r
+  return Field->mFieldType->mType;\r
+}\r
+\r
+UINT32\r
+CVfrVarDataTypeDB::GetFieldSize (\r
+  IN SVfrDataField *Field,\r
+  IN UINT32       ArrayIdx\r
+  )\r
+{\r
+  if (Field == NULL) {\r
+    return VFR_RETURN_FATAL_ERROR;\r
+  }\r
+\r
+  if ((ArrayIdx == INVALID_ARRAY_INDEX) && (Field->mArrayNum != 0)) {\r
+    return Field->mFieldType->mTotalSize * Field->mArrayNum;\r
+  } else {\r
+    return Field->mFieldType->mTotalSize;\r
+  }\r
+}\r
+\r
+VOID\r
+CVfrVarDataTypeDB::InternalTypesListInit (\r
+  VOID\r
+  )\r
+{\r
+  SVfrDataType *New   = NULL;\r
+  UINT32       Index;\r
+\r
+  for (Index = 0; gInternalTypesTable[Index].mTypeName != NULL; Index++) {\r
+    New                 = new SVfrDataType;\r
+    if (New != NULL) {\r
+      strcpy (New->mTypeName, gInternalTypesTable[Index].mTypeName);\r
+      New->mType        = gInternalTypesTable[Index].mType;\r
+      New->mAlign       = gInternalTypesTable[Index].mAlign;\r
+      New->mTotalSize   = gInternalTypesTable[Index].mSize;\r
+      if (strcmp (gInternalTypesTable[Index].mTypeName, "EFI_HII_DATE") == 0) {\r
+        SVfrDataField *pYearField  = new SVfrDataField;\r
+        SVfrDataField *pMonthField = new SVfrDataField;\r
+        SVfrDataField *pDayField   = new SVfrDataField;\r
+\r
+        strcpy (pYearField->mFieldName, "Year");\r
+        GetDataType ("UINT8", &pYearField->mFieldType);\r
+        pYearField->mOffset      = 0;\r
+        pYearField->mNext        = pMonthField;\r
+        pYearField->mArrayNum    = 0;\r
+\r
+        strcpy (pMonthField->mFieldName, "Month");\r
+        GetDataType ("UINT8", &pMonthField->mFieldType);\r
+        pMonthField->mOffset     = 1;\r
+        pMonthField->mNext       = pDayField;\r
+        pMonthField->mArrayNum   = 0;\r
+\r
+        strcpy (pDayField->mFieldName, "Day");\r
+        GetDataType ("UINT8", &pDayField->mFieldType);\r
+        pDayField->mOffset       = 2;\r
+        pDayField->mNext         = NULL;\r
+        pDayField->mArrayNum     = 0;\r
+\r
+        New->mMembers            = pYearField;\r
+      } else if (strcmp (gInternalTypesTable[Index].mTypeName, "EFI_HII_TIME") == 0) {\r
+        SVfrDataField *pHoursField   = new SVfrDataField;\r
+        SVfrDataField *pMinutesField = new SVfrDataField;\r
+        SVfrDataField *pSecondsField = new SVfrDataField;\r
+\r
+        strcpy (pHoursField->mFieldName, "Hours");\r
+        GetDataType ("UINT8", &pHoursField->mFieldType);\r
+        pHoursField->mOffset     = 0;\r
+        pHoursField->mNext       = pMinutesField;\r
+        pHoursField->mArrayNum   = 0;\r
+\r
+        strcpy (pMinutesField->mFieldName, "Minutes");\r
+        GetDataType ("UINT8", &pMinutesField->mFieldType);\r
+        pMinutesField->mOffset   = 1;\r
+        pMinutesField->mNext     = pSecondsField;\r
+        pMinutesField->mArrayNum = 0;\r
+\r
+        strcpy (pSecondsField->mFieldName, "Seconds");\r
+        GetDataType ("UINT8", &pSecondsField->mFieldType);\r
+        pSecondsField->mOffset   = 2;\r
+        pSecondsField->mNext     = NULL;\r
+        pSecondsField->mArrayNum = 0;\r
+\r
+        New->mMembers            = pHoursField;      \r
+      } else {\r
+        New->mMembers            = NULL;\r
+      }\r
+      New->mNext                 = NULL;\r
+      RegisterNewType (New);\r
+      New                        = NULL;\r
+    }\r
+  }\r
+}\r
+\r
+CVfrVarDataTypeDB::CVfrVarDataTypeDB (\r
+  VOID\r
+  )\r
+{\r
+  mDataTypeList  = NULL;\r
+  mNewDataType   = NULL;\r
+  mCurrDataField = NULL;\r
+  mPackAlign     = DEFAULT_PACK_ALIGN;\r
+\r
+  InternalTypesListInit ();\r
+}\r
+\r
+CVfrVarDataTypeDB::~CVfrVarDataTypeDB (\r
+  VOID\r
+  )\r
+{\r
+  SVfrDataType  *pType;\r
+  SVfrDataField *pField;\r
+\r
+  if (mNewDataType != NULL) {\r
+    delete mNewDataType;\r
+  }\r
+\r
+  while (mDataTypeList != NULL) {\r
+    pType = mDataTypeList;\r
+    mDataTypeList = mDataTypeList->mNext;\r
+    while(pType->mMembers != NULL) {\r
+      pField = pType->mMembers;\r
+      pType->mMembers = pType->mMembers->mNext;\r
+      delete pField;\r
+    }\r
+       delete pType;\r
+  }\r
+\r
+}\r
+\r
+EFI_VFR_RETURN_CODE\r
+CVfrVarDataTypeDB::Pack (\r
+  IN UINT32        Align\r
+  )\r
+{\r
+  if (Align == 0) {\r
+    return VFR_RETURN_INVALID_PARAMETER;\r
+  } else if (Align > 1) {\r
+    mPackAlign = Align + Align % 2;\r
+  } else {\r
+    mPackAlign = Align;\r
+  }\r
+\r
+  return VFR_RETURN_SUCCESS;\r
+}\r
+\r
+VOID\r
+CVfrVarDataTypeDB::UnPack (\r
+  VOID\r
+  )\r
+{\r
+  mPackAlign = DEFAULT_PACK_ALIGN;\r
+}\r
+\r
+VOID\r
+CVfrVarDataTypeDB::DeclareDataTypeBegin (\r
+  VOID\r
+  )\r
+{\r
+  SVfrDataType *pNewType = NULL;\r
+\r
+  pNewType               = new SVfrDataType;\r
+  pNewType->mTypeName[0] = '\0';\r
+  pNewType->mType        = EFI_IFR_TYPE_OTHER;\r
+  pNewType->mAlign       = DEFAULT_ALIGN;\r
+  pNewType->mTotalSize   = 0;\r
+  pNewType->mMembers     = NULL;\r
+  pNewType->mNext        = NULL;\r
+\r
+  mNewDataType           = pNewType;\r
+}\r
+\r
+EFI_VFR_RETURN_CODE\r
+CVfrVarDataTypeDB::SetNewTypeName (\r
+  IN INT8   *TypeName\r
+  )\r
+{\r
+  SVfrDataType *pType;\r
+\r
+  if (mNewDataType == NULL) {\r
+    return VFR_RETURN_ERROR_SKIPED;\r
+  }\r
+  if (TypeName == NULL) {\r
+    return VFR_RETURN_FATAL_ERROR;\r
+  }\r
+  if (strlen(TypeName) >= MAX_NAME_LEN) {\r
+    return VFR_RETURN_INVALID_PARAMETER;\r
+  }\r
+\r
+  for (pType = mDataTypeList; pType != NULL; pType = pType->mNext) {\r
+    if (strcmp(pType->mTypeName, TypeName) == 0) {\r
+      return VFR_RETURN_REDEFINED;\r
+    }\r
+  }\r
+\r
+  strcpy(mNewDataType->mTypeName, TypeName);\r
+  return VFR_RETURN_SUCCESS;\r
+}\r
+\r
+EFI_VFR_RETURN_CODE\r
+CVfrVarDataTypeDB::DataTypeAddField (\r
+  IN INT8   *FieldName, \r
+  IN INT8   *TypeName, \r
+  IN UINT32 ArrayNum\r
+  )\r
+{\r
+  SVfrDataField       *pNewField  = NULL;\r
+  SVfrDataType        *pFieldType = NULL;\r
+  SVfrDataField       *pTmp;\r
+  UINT32              Align;\r
+\r
+  CHECK_ERROR_RETURN (GetDataType (TypeName, &pFieldType), VFR_RETURN_SUCCESS);\r
+\r
+  if (strlen (FieldName) >= MAX_NAME_LEN) {\r
+   return VFR_RETURN_INVALID_PARAMETER;\r
+  }\r
+\r
+  for (pTmp = mNewDataType->mMembers; pTmp != NULL; pTmp = pTmp->mNext) {\r
+    if (strcmp (pTmp->mFieldName, FieldName) == 0) {\r
+      return VFR_RETURN_REDEFINED;\r
+    }\r
+  }\r
+\r
+  Align = MIN (mPackAlign, pFieldType->mAlign);\r
+\r
+  if ((pNewField = new SVfrDataField) == NULL) {\r
+    return VFR_RETURN_OUT_FOR_RESOURCES;\r
+  }\r
+  strcpy (pNewField->mFieldName, FieldName);\r
+  pNewField->mFieldType    = pFieldType;\r
+  pNewField->mArrayNum     = ArrayNum;\r
+  if ((mNewDataType->mTotalSize % Align) == 0) {\r
+    pNewField->mOffset     = mNewDataType->mTotalSize;\r
+  } else {\r
+    pNewField->mOffset     = mNewDataType->mTotalSize + ALIGN_STUFF(mNewDataType->mTotalSize, Align);\r
+  }\r
+  if (mNewDataType->mMembers == NULL) {\r
+    mNewDataType->mMembers = pNewField;\r
+    pNewField->mNext       = NULL;\r
+  } else {\r
+    for (pTmp = mNewDataType->mMembers; pTmp->mNext != NULL; pTmp = pTmp->mNext) \r
+      ;\r
+    pTmp->mNext            = pNewField;\r
+    pNewField->mNext       = NULL;\r
+  }\r
+\r
+  mNewDataType->mAlign     = MIN (mPackAlign, MAX (pFieldType->mAlign, mNewDataType->mAlign));\r
+  mNewDataType->mTotalSize = pNewField->mOffset + (pNewField->mFieldType->mTotalSize) * ((ArrayNum == 0) ? 1 : ArrayNum);\r
+\r
+  return VFR_RETURN_SUCCESS;\r
+}\r
+\r
+VOID\r
+CVfrVarDataTypeDB::DeclareDataTypeEnd (\r
+  VOID\r
+  )\r
+{\r
+  if (mNewDataType->mTypeName[0] == '\0') {\r
+    return;\r
+  }\r
+\r
+  if ((mNewDataType->mTotalSize % mNewDataType->mAlign) !=0) {\r
+    mNewDataType->mTotalSize += ALIGN_STUFF (mNewDataType->mTotalSize, mNewDataType->mAlign);\r
+  }\r
+\r
+  RegisterNewType (mNewDataType);\r
+  mNewDataType             = NULL;\r
+}\r
+\r
+EFI_VFR_RETURN_CODE\r
+CVfrVarDataTypeDB::GetDataType (\r
+  IN  INT8         *TypeName,\r
+  OUT SVfrDataType **DataType\r
+\r
+  )\r
+{\r
+  SVfrDataType *pDataType = NULL;\r
+\r
+  if (TypeName == NULL) {\r
+    return VFR_RETURN_ERROR_SKIPED;\r
+  }\r
+\r
+  if (DataType == NULL) {\r
+    return VFR_RETURN_FATAL_ERROR;\r
+  }\r
+\r
+  *DataType = NULL;\r
+\r
+  for (pDataType = mDataTypeList; pDataType != NULL; pDataType = pDataType->mNext) {\r
+    if (strcmp (TypeName, pDataType->mTypeName) == 0) {\r
+      *DataType = pDataType;\r
+      return VFR_RETURN_SUCCESS;\r
+    }\r
+  }\r
+\r
+  return VFR_RETURN_UNDEFINED;\r
+}\r
+\r
+EFI_VFR_RETURN_CODE\r
+CVfrVarDataTypeDB::GetDataTypeSize (\r
+  IN  INT8   *TypeName,\r
+  OUT UINT32 *Size\r
+  )\r
+{\r
+  SVfrDataType *pDataType = NULL;\r
+\r
+  if (Size == NULL) {\r
+    return VFR_RETURN_FATAL_ERROR;\r
+  }\r
+\r
+  *Size = 0;\r
+\r
+  for (pDataType = mDataTypeList; pDataType != NULL; pDataType = pDataType->mNext) {\r
+    if (strcmp (TypeName, pDataType->mTypeName) == 0) {\r
+      *Size = pDataType->mTotalSize;\r
+      return VFR_RETURN_SUCCESS;\r
+    }\r
+  }\r
+\r
+  return VFR_RETURN_UNDEFINED;\r
+}\r
+\r
+EFI_VFR_RETURN_CODE\r
+CVfrVarDataTypeDB::GetDataFieldInfo (\r
+  IN  INT8     *VarStr, \r
+  OUT UINT16   &Offset, \r
+  OUT UINT8    &Type, \r
+  OUT UINT32   &Size\r
+  )\r
+{\r
+  INT8                TName[MAX_NAME_LEN], FName[MAX_NAME_LEN];\r
+  UINT32              ArrayIdx, Tmp;\r
+  SVfrDataType        *pType  = NULL;\r
+  SVfrDataField       *pField = NULL;\r
+\r
+  Offset = 0;\r
+  Type   = EFI_IFR_TYPE_OTHER;\r
+  Size   = 0;\r
+\r
+  CHECK_ERROR_RETURN (ExtractStructTypeName (VarStr, TName), VFR_RETURN_SUCCESS);\r
+  CHECK_ERROR_RETURN (GetDataType (TName, &pType), VFR_RETURN_SUCCESS);\r
+\r
+  //\r
+  // if it is not struct data type\r
+  //\r
+  Type  = pType->mType;\r
+  Size  = pType->mTotalSize;\r
+\r
+  while (*VarStr != '\0') {\r
+       CHECK_ERROR_RETURN(ExtractFieldNameAndArrary(VarStr, FName, ArrayIdx), VFR_RETURN_SUCCESS);\r
+    CHECK_ERROR_RETURN(GetTypeField (FName, pType, pField), VFR_RETURN_SUCCESS);\r
+    pType  = pField->mFieldType;\r
+    CHECK_ERROR_RETURN(GetFieldOffset (pField, ArrayIdx, Tmp), VFR_RETURN_SUCCESS);\r
+    Offset += Tmp;\r
+    Type   = GetFieldWidth (pField);\r
+    Size   = GetFieldSize (pField, ArrayIdx);\r
+  }\r
+  return VFR_RETURN_SUCCESS;\r
+}\r
+\r
+EFI_VFR_RETURN_CODE\r
+CVfrVarDataTypeDB::GetUserDefinedTypeNameList  (\r
+  OUT INT8      ***NameList, \r
+  OUT UINT32    *ListSize\r
+  )\r
+{\r
+  UINT32       Index;\r
+  SVfrDataType *pType;\r
+\r
+  if ((NameList == NULL) || (ListSize == NULL)) {\r
+    return VFR_RETURN_FATAL_ERROR;\r
+  }\r
+\r
+  *NameList = NULL;\r
+  *ListSize = 0;\r
+\r
+  for (pType = mDataTypeList; pType != NULL; pType = pType->mNext) {\r
+    if (_IS_INTERNAL_TYPE(pType->mTypeName) == FALSE) {\r
+      (*ListSize)++;\r
+    }\r
+  }\r
+\r
+  if (*ListSize == 0) {\r
+    return VFR_RETURN_SUCCESS;\r
+  }\r
+\r
+  if ((*NameList = new INT8*[*ListSize]) == NULL) {\r
+    *ListSize = 0;\r
+    return VFR_RETURN_OUT_FOR_RESOURCES;\r
+  }\r
+\r
+  for (Index = 0, pType = mDataTypeList; pType != NULL; pType = pType->mNext, Index++) {\r
+    if (_IS_INTERNAL_TYPE(pType->mTypeName) == FALSE) {\r
+      (*NameList)[Index] = pType->mTypeName;\r
+    }\r
+  }\r
+  return VFR_RETURN_SUCCESS;\r
+}\r
+\r
+BOOLEAN\r
+CVfrVarDataTypeDB::IsTypeNameDefined (\r
+  IN INT8 *TypeName\r
+  )\r
+{\r
+  SVfrDataType *pType;\r
+\r
+  if (TypeName == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  for (pType = mDataTypeList; pType != NULL; pType = pType->mNext) {\r
+    if (strcmp (pType->mTypeName, TypeName) == 0) {\r
+      return TRUE;\r
+    }\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
+#ifdef CVFR_VARDATATYPEDB_DEBUG\r
+VOID\r
+CVfrVarDataTypeDB::ParserDB (\r
+  VOID\r
+  )\r
+{\r
+  SVfrDataType  *pTNode;\r
+  SVfrDataField *pFNode;\r
+\r
+  printf ("***************************************************************\n");\r
+  printf ("\t\tmPackAlign = %x\n", mPackAlign);\r
+  for (pTNode = mDataTypeList; pTNode != NULL; pTNode = pTNode->mNext) {\r
+    printf ("\t\tstruct %s : mAlign [%x] mTotalSize [%x]\n\n", pTNode->mTypeName, pTNode->mAlign, pTNode->mTotalSize);\r
+    printf ("\t\tstruct %s {\n", pTNode->mTypeName);\r
+    for (pFNode = pTNode->mMembers; pFNode != NULL; pFNode = pFNode->mNext) {\r
+      printf ("\t\t\t%s\t%s\n", pFNode->mFieldType->mTypeName, pFNode->mFieldName);\r
+    }\r
+    printf ("\t\t};\n");\r
+       printf ("---------------------------------------------------------------\n");\r
+  }\r
+  printf ("***************************************************************\n");\r
+}\r
+#endif\r
+\r
+SVfrVarStorageNode::SVfrVarStorageNode (\r
+  IN EFI_GUID              *Guid,\r
+  IN INT8                  *StoreName,\r
+  IN EFI_VARSTORE_ID       VarStoreId,\r
+  IN EFI_STRING_ID         VarName,\r
+  IN UINT32                VarSize\r
+  )\r
+{\r
+  if (Guid != NULL) {\r
+    mGuid = *Guid;\r
+  } else {\r
+    memset (&Guid, 0, sizeof (EFI_GUID));\r
+  }\r
+  if (StoreName != NULL) {\r
+    mVarStoreName = new INT8[strlen(StoreName) + 1];\r
+    strcpy (mVarStoreName, StoreName);\r
+  } else {\r
+    mVarStoreName = NULL;\r
+  }\r
+  mNext                            = NULL;\r
+  mVarStoreId                      = VarStoreId;\r
+  mVarStoreType                    = EFI_VFR_VARSTORE_EFI;\r
+  mStorageInfo.mEfiVar.mEfiVarName = VarName;\r
+  mStorageInfo.mEfiVar.mEfiVarSize = VarSize;\r
+}\r
+\r
+SVfrVarStorageNode::SVfrVarStorageNode (\r
+  IN EFI_GUID              *Guid,\r
+  IN INT8                  *StoreName,\r
+  IN EFI_VARSTORE_ID       VarStoreId,\r
+  IN SVfrDataType          *DataType\r
+  )\r
+{\r
+  if (Guid != NULL) {\r
+    mGuid = *Guid;\r
+  } else {\r
+    memset (&Guid, 0, sizeof (EFI_GUID));\r
+  }\r
+  if (StoreName != NULL) {\r
+    mVarStoreName = new INT8[strlen(StoreName) + 1];\r
+    strcpy (mVarStoreName, StoreName);\r
+  } else {\r
+    mVarStoreName = NULL;\r
+  }\r
+  mNext                    = NULL;\r
+  mVarStoreId              = VarStoreId;\r
+  mVarStoreType            = EFI_VFR_VARSTORE_BUFFER;\r
+  mStorageInfo.mDataType   = DataType;\r
+}\r
+\r
+SVfrVarStorageNode::SVfrVarStorageNode (\r
+  IN INT8                  *StoreName,\r
+  IN EFI_VARSTORE_ID       VarStoreId\r
+  )\r
+{\r
+  if (StoreName != NULL) {\r
+    mVarStoreName = new INT8[strlen(StoreName) + 1];\r
+    strcpy (mVarStoreName, StoreName);\r
+  } else {\r
+    mVarStoreName = NULL;\r
+  }\r
+  mNext                              = NULL;\r
+  mVarStoreId                        = VarStoreId;\r
+  mVarStoreType                      = EFI_VFR_VARSTORE_NAME;\r
+  mStorageInfo.mNameSpace.mNameTable = new EFI_VARSTORE_ID[DEFAULT_NAME_TABLE_ITEMS];\r
+  mStorageInfo.mNameSpace.mTableSize = 0;\r
+}\r
+\r
+SVfrVarStorageNode::~SVfrVarStorageNode (\r
+  VOID\r
+  )\r
+{\r
+  if (mVarStoreName != NULL) {\r
+    delete mVarStoreName;\r
+  }\r
+\r
+  if (mVarStoreType == EFI_VFR_VARSTORE_NAME) {\r
+    delete mStorageInfo.mNameSpace.mNameTable;\r
+  }\r
+}\r
+\r
+CVfrDataStorage::CVfrDataStorage (\r
+  VOID\r
+  )\r
+{\r
+  UINT32 Index;\r
+\r
+  for (Index = 0; Index < EFI_FREE_VARSTORE_ID_BITMAP_SIZE; Index++) {\r
+    mFreeVarStoreIdBitMap[Index] = 0;\r
+  }\r
+\r
+  // Question ID 0 is reserved.\r
+  mFreeVarStoreIdBitMap[0] = 0x80000000;\r
+\r
+  mBufferVarStoreList      = NULL;\r
+  mEfiVarStoreList         = NULL;\r
+  mNameVarStoreList        = NULL;\r
+  mCurrVarStorageNode      = NULL;\r
+  mNewVarStorageNode       = NULL;\r
+}\r
+\r
+CVfrDataStorage::~CVfrDataStorage (\r
+  VOID\r
+  )\r
+{\r
+  SVfrVarStorageNode *pNode;\r
+\r
+  while (mBufferVarStoreList != NULL) {\r
+    pNode = mBufferVarStoreList;\r
+    mBufferVarStoreList = mBufferVarStoreList->mNext;\r
+    delete pNode;\r
+  }\r
+  while (mEfiVarStoreList != NULL) {\r
+    pNode = mEfiVarStoreList;\r
+    mEfiVarStoreList = mEfiVarStoreList->mNext;\r
+    delete pNode;\r
+  }\r
+  while (mNameVarStoreList != NULL) {\r
+    pNode = mNameVarStoreList;\r
+    mNameVarStoreList = mNameVarStoreList->mNext;\r
+    delete pNode;\r
+  }\r
+  if (mNewVarStorageNode != NULL) {\r
+    delete mNewVarStorageNode;\r
+  }\r
+}\r
+\r
+EFI_VARSTORE_ID\r
+CVfrDataStorage::GetFreeVarStoreId (\r
+  VOID\r
+  )\r
+{\r
+  UINT32  Index, Mask, Offset;\r
+\r
+  for (Index = 0; Index < EFI_FREE_VARSTORE_ID_BITMAP_SIZE; Index++) {\r
+    if (mFreeVarStoreIdBitMap[Index] != 0xFFFFFFFF) {\r
+      break;\r
+    }\r
+  }\r
+\r
+  for (Offset = 0, Mask = 0x80000000; Mask != 0; Mask >>= 1, Offset++) {\r
+    if ((mFreeVarStoreIdBitMap[Index] & Mask) == 0) {\r
+      mFreeVarStoreIdBitMap[Index] |= Mask;\r
+      return (EFI_VARSTORE_ID)((Index << EFI_BITS_SHIFT_PER_UINT32) + Offset);\r
+    }\r
+  }\r
+\r
+  return EFI_VARSTORE_ID_INVALID;\r
+}\r
+\r
+BOOLEAN\r
+CVfrDataStorage::ChekVarStoreIdFree (\r
+  IN EFI_VARSTORE_ID VarStoreId\r
+  )\r
+{\r
+  UINT32 Index  = (VarStoreId / EFI_BITS_PER_UINT32);\r
+  UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);\r
+\r
+  return (mFreeVarStoreIdBitMap[Index] & (0x80000000 >> Offset)) == 0;\r
+}\r
+\r
+VOID\r
+CVfrDataStorage::MarkVarStoreIdUsed (\r
+  IN EFI_VARSTORE_ID VarStoreId\r
+  )\r
+{\r
+  UINT32 Index  = (VarStoreId / EFI_BITS_PER_UINT32);\r
+  UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);\r
+\r
+  mFreeVarStoreIdBitMap[Index] |= (0x80000000 >> Offset);\r
+}\r
+\r
+VOID\r
+CVfrDataStorage::MarkVarStoreIdUnused (\r
+  IN EFI_VARSTORE_ID VarStoreId\r
+  )\r
+{\r
+  UINT32 Index  = (VarStoreId / EFI_BITS_PER_UINT32);\r
+  UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);\r
+\r
+  mFreeVarStoreIdBitMap[Index] &= ~(0x80000000 >> Offset);\r
+}\r
+\r
+EFI_VFR_RETURN_CODE\r
+CVfrDataStorage::DeclareNameVarStoreBegin (\r
+  IN INT8     *StoreName\r
+  )\r
+{\r
+  SVfrVarStorageNode *pNode = NULL;\r
+  EFI_VARSTORE_ID    VarStoreId;\r
+\r
+  if (StoreName == NULL) {\r
+    return VFR_RETURN_FATAL_ERROR;\r
+  }\r
+\r
+  for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
+    if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
+      return VFR_RETURN_REDEFINED;\r
+    }\r
+  }\r
+\r
+  VarStoreId = GetFreeVarStoreId ();\r
+  if ((pNode = new SVfrVarStorageNode (StoreName, VarStoreId)) == NULL) {\r
+    return VFR_RETURN_UNDEFINED;\r
+  }\r
+\r
+  mNewVarStorageNode = pNode;\r
+\r
+  return VFR_RETURN_SUCCESS;\r
+}\r
+\r
+EFI_VFR_RETURN_CODE\r
+CVfrDataStorage::NameTableAddItem (\r
+  IN EFI_STRING_ID  Item\r
+  )\r
+{\r
+  EFI_VARSTORE_ID *NewTable, *OldTable;\r
+  UINT32          TableSize;\r
+\r
+  OldTable  = mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable;\r
+  TableSize = mNewVarStorageNode->mStorageInfo.mNameSpace.mTableSize;\r
+\r
+  if ((TableSize != 0) && ((TableSize % DEFAULT_NAME_TABLE_ITEMS) == 0)) {\r
+    if ((NewTable = new EFI_VARSTORE_ID[TableSize + DEFAULT_NAME_TABLE_ITEMS]) == NULL) {\r
+      return VFR_RETURN_OUT_FOR_RESOURCES;\r
+    }\r
+    memcpy (NewTable, OldTable, TableSize);\r
+    mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable = NewTable;\r
+  }\r
+\r
+  mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable[TableSize++] = Item;\r
+  mNewVarStorageNode->mStorageInfo.mNameSpace.mTableSize = TableSize;\r
+\r
+  return VFR_RETURN_SUCCESS;\r
+}\r
+\r
+EFI_VFR_RETURN_CODE\r
+CVfrDataStorage::DeclareNameVarStoreEnd (\r
+  IN EFI_GUID *Guid\r
+  )\r
+{\r
+  mNewVarStorageNode->mGuid = *Guid;\r
+  mNewVarStorageNode->mNext = mNameVarStoreList;\r
+  mNameVarStoreList         = mNewVarStorageNode;\r
+\r
+  mNewVarStorageNode        = NULL;\r
+\r
+  return VFR_RETURN_SUCCESS;\r
+}\r
+\r
+EFI_VFR_RETURN_CODE \r
+CVfrDataStorage::DeclareEfiVarStore (\r
+  IN INT8           *StoreName, \r
+  IN EFI_GUID       *Guid, \r
+  IN EFI_STRING_ID  NameStrId,\r
+  IN UINT32         VarSize\r
+  )\r
+{\r
+  SVfrVarStorageNode *pNode;\r
+  EFI_VARSTORE_ID    VarStoreId;\r
+\r
+  if ((StoreName == NULL) || (Guid == NULL)) {\r
+    return VFR_RETURN_FATAL_ERROR;\r
+  }\r
+\r
+  if (VarSize > sizeof (UINT64)) {\r
+    return VFR_RETURN_EFIVARSTORE_SIZE_ERROR;\r
+  }\r
+\r
+  for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
+    if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
+      return VFR_RETURN_REDEFINED;\r
+    }\r
+  }\r
+\r
+  VarStoreId = GetFreeVarStoreId ();\r
+  if ((pNode = new SVfrVarStorageNode (Guid, StoreName, VarStoreId, NameStrId, VarSize)) == NULL) {\r
+    return VFR_RETURN_OUT_FOR_RESOURCES;\r
+  }\r
+\r
+  pNode->mNext       = mNameVarStoreList;\r
+  mNameVarStoreList  = pNode;\r
+\r
+  return VFR_RETURN_SUCCESS;\r
+}\r
+\r
+EFI_VFR_RETURN_CODE \r
+CVfrDataStorage::DeclareBufferVarStore (\r
+  IN INT8              *StoreName, \r
+  IN EFI_GUID          *Guid, \r
+  IN CVfrVarDataTypeDB *DataTypeDB,\r
+  IN INT8              *TypeName,\r
+  IN EFI_VARSTORE_ID   VarStoreId\r
+  )\r
+{\r
+  SVfrVarStorageNode   *pNew = NULL;\r
+  SVfrDataType         *pDataType = NULL;\r
+\r
+  if ((StoreName == NULL) || (Guid == NULL) || (DataTypeDB == NULL)) {\r
+    return VFR_RETURN_FATAL_ERROR;\r
+  }\r
+\r
+  CHECK_ERROR_RETURN(DataTypeDB->GetDataType (TypeName, &pDataType), VFR_RETURN_SUCCESS);\r
+\r
+  if (VarStoreId == EFI_VARSTORE_ID_INVALID) {\r
+    VarStoreId = GetFreeVarStoreId ();\r
+  } else {\r
+    if (ChekVarStoreIdFree (VarStoreId) == FALSE) {\r
+      return VFR_RETURN_VARSTOREID_REDEFINED;\r
+    }\r
+    MarkVarStoreIdUsed (VarStoreId);\r
+  }\r
+\r
+  if ((pNew = new SVfrVarStorageNode (Guid, StoreName, VarStoreId, pDataType)) == NULL) {\r
+    return VFR_RETURN_OUT_FOR_RESOURCES;\r
+  }\r
+\r
+  pNew->mNext         = mBufferVarStoreList;\r
+  mBufferVarStoreList = pNew;\r
+\r
+  if (gCVfrBufferConfig.Register(StoreName) != 0) {\r
+    return VFR_RETURN_FATAL_ERROR;\r
+  }\r
+\r
+  return VFR_RETURN_SUCCESS;\r
+}\r
+\r
+EFI_VFR_RETURN_CODE \r
+CVfrDataStorage::GetVarStoreId (\r
+  IN  INT8            *StoreName,\r
+  OUT EFI_VARSTORE_ID *VarStoreId\r
+  )\r
+{\r
+  SVfrVarStorageNode    *pNode;\r
+\r
+  for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
+    if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
+      mCurrVarStorageNode = pNode;\r
+      *VarStoreId = pNode->mVarStoreId;\r
+      return VFR_RETURN_SUCCESS;\r
+    }\r
+  }\r
+\r
+  for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
+    if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
+      mCurrVarStorageNode = pNode;\r
+      *VarStoreId = pNode->mVarStoreId;\r
+      return VFR_RETURN_SUCCESS;\r
+    }\r
+  }\r
+\r
+  for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
+    if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
+      mCurrVarStorageNode = pNode;\r
+      *VarStoreId = pNode->mVarStoreId;\r
+      return VFR_RETURN_SUCCESS;\r
+    }\r
+  }\r
+\r
+  mCurrVarStorageNode = NULL;\r
+  *VarStoreId        = EFI_VARSTORE_ID_INVALID;\r
+  return VFR_RETURN_UNDEFINED;\r
+}\r
+\r
+EFI_VFR_RETURN_CODE\r
+CVfrDataStorage::GetBufferVarStoreDataTypeName (\r
+  IN  INT8                   *StoreName,\r
+  OUT INT8                   **DataTypeName\r
+  )\r
+{\r
+  SVfrVarStorageNode    *pNode;\r
+\r
+  if ((StoreName == NULL) || (DataTypeName == NULL)) {\r
+    return VFR_RETURN_FATAL_ERROR;\r
+  }\r
+\r
+  for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
+    if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
+      break;\r
+    }\r
+  }\r
+\r
+  if (pNode == NULL) {\r
+    return VFR_RETURN_UNDEFINED;\r
+  }\r
+\r
+  if (pNode->mStorageInfo.mDataType == NULL) {\r
+    return VFR_RETURN_FATAL_ERROR;\r
+  }\r
+\r
+  *DataTypeName = pNode->mStorageInfo.mDataType->mTypeName;\r
+  return VFR_RETURN_SUCCESS;\r
+}\r
+\r
+EFI_VFR_RETURN_CODE\r
+CVfrDataStorage::GetVarStoreType (\r
+  IN  INT8                   *StoreName,\r
+  OUT EFI_VFR_VARSTORE_TYPE  &VarStoreType\r
+  )\r
+{\r
+  SVfrVarStorageNode    *pNode;\r
+\r
+  if (StoreName == NULL) {\r
+    return VFR_RETURN_FATAL_ERROR;\r
+  }\r
+\r
+  for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
+    if (strcmp (pNode->mVarStoreName, StoreName) == NULL) {\r
+      VarStoreType = pNode->mVarStoreType;\r
+      return VFR_RETURN_SUCCESS;\r
+    }\r
+  }\r
+\r
+  for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
+    if (strcmp (pNode->mVarStoreName, StoreName) == NULL) {\r
+      VarStoreType = pNode->mVarStoreType;\r
+      return VFR_RETURN_SUCCESS;\r
+    }\r
+  }\r
+\r
+  for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
+    if (strcmp (pNode->mVarStoreName, StoreName) == NULL) {\r
+      VarStoreType = pNode->mVarStoreType;\r
+      return VFR_RETURN_SUCCESS;\r
+    }\r
+  }\r
+\r
+  VarStoreType = EFI_VFR_VARSTORE_INVALID;\r
+  return VFR_RETURN_UNDEFINED;\r
+}\r
+\r
+EFI_VFR_RETURN_CODE\r
+CVfrDataStorage::GetVarStoreName (\r
+  IN  EFI_VARSTORE_ID VarStoreId, \r
+  OUT INT8            **VarStoreName\r
+  )\r
+{\r
+  SVfrVarStorageNode    *pNode;\r
+\r
+  if (VarStoreName == NULL) {\r
+    return VFR_RETURN_FATAL_ERROR;\r
+  }\r
+\r
+  for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
+    if (pNode->mVarStoreId == VarStoreId) {\r
+      *VarStoreName = pNode->mVarStoreName;\r
+      return VFR_RETURN_SUCCESS;\r
+    }\r
+  }\r
+\r
+  for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
+    if (pNode->mVarStoreId == VarStoreId) {\r
+      *VarStoreName = pNode->mVarStoreName;\r
+      return VFR_RETURN_SUCCESS;\r
+    }\r
+  }\r
+\r
+  for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
+    if (pNode->mVarStoreId == VarStoreId) {\r
+      *VarStoreName = pNode->mVarStoreName;\r
+      return VFR_RETURN_SUCCESS;\r
+    }\r
+  }\r
+\r
+  *VarStoreName = NULL;\r
+  return VFR_RETURN_UNDEFINED;\r
+}\r
+\r
+EFI_VFR_RETURN_CODE\r
+CVfrDataStorage::GetEfiVarStoreInfo (\r
+  IN OUT EFI_VARSTORE_INFO  *Info\r
+  )\r
+{\r
+  if (Info == NULL) {\r
+    return VFR_RETURN_FATAL_ERROR;\r
+  }\r
+\r
+  if (mCurrVarStorageNode == NULL) {\r
+    return VFR_RETURN_GET_EFIVARSTORE_ERROR;\r
+  }\r
+\r
+  Info->mInfo.mVarName = mCurrVarStorageNode->mStorageInfo.mEfiVar.mEfiVarName;\r
+  Info->mVarTotalSize  = mCurrVarStorageNode->mStorageInfo.mEfiVar.mEfiVarSize;\r
+  switch (Info->mVarTotalSize) {\r
+  case 1:\r
+    Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_8;\r
+    break;\r
+  case 2:\r
+    Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_16;\r
+    break;\r
+  case 4:\r
+    Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_32;\r
+    break;\r
+  case 8:\r
+    Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_64;\r
+    break;\r
+  default :\r
+    return VFR_RETURN_FATAL_ERROR;\r
+  }\r
+\r
+  return VFR_RETURN_SUCCESS;\r
+}\r
+\r
+EFI_VFR_RETURN_CODE\r
+CVfrDataStorage::GetNameVarStoreInfo (\r
+  OUT EFI_VARSTORE_INFO  *Info,\r
+  IN  UINT32             Index\r
+  )\r
+{\r
+  if (Info == NULL) {\r
+    return VFR_RETURN_FATAL_ERROR;\r
+  }\r
+\r
+  if (mCurrVarStorageNode == NULL) {\r
+    return VFR_RETURN_GET_NVVARSTORE_ERROR;\r
+  }\r
+\r
+  Info->mInfo.mVarName = mCurrVarStorageNode->mStorageInfo.mNameSpace.mNameTable[Index];\r
+\r
+  return VFR_RETURN_SUCCESS;\r
+}\r
+\r
+EFI_VFR_RETURN_CODE\r
+CVfrDataStorage::BufferVarStoreRequestElementAdd (\r
+  IN INT8              *StoreName,\r
+  IN EFI_VARSTORE_INFO &Info\r
+  )\r
+{\r
+  INT8                  NewReqElt[128] = {'\0',};\r
+  INT8                  *OldReqElt = NULL;\r
+  SVfrVarStorageNode    *pNode = NULL;\r
+  EFI_IFR_TYPE_VALUE    Value;\r
+\r
+  for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
+    if (strcmp (pNode->mVarStoreName, StoreName) == NULL) {\r
+      break;\r
+    }\r
+  }\r
+\r
+  if (pNode == NULL) {\r
+    return VFR_RETURN_UNDEFINED;\r
+  }\r
+\r
+  gCVfrBufferConfig.Open ();\r
+  Value.u8 = 0;\r
+  if (gCVfrBufferConfig.Write ('a', StoreName, NULL, EFI_IFR_TYPE_NUM_SIZE_8, Info.mInfo.mVarOffset, Info.mVarTotalSize, Value) != 0) {\r
+    return VFR_RETURN_FATAL_ERROR;\r
+  }\r
+  gCVfrBufferConfig.Close ();\r
+\r
+  return VFR_RETURN_SUCCESS;\r
+}\r
+\r
+SVfrDefaultStoreNode::SVfrDefaultStoreNode (\r
+  IN EFI_IFR_DEFAULTSTORE *ObjBinAddr,\r
+  IN INT8                 *RefName, \r
+  IN EFI_STRING_ID        DefaultStoreNameId, \r
+  IN UINT16               DefaultId\r
+  )\r
+{\r
+  mObjBinAddr = ObjBinAddr;\r
+\r
+  if (RefName != NULL) {\r
+    mRefName          = new INT8[strlen (RefName) + 1];\r
+    strcpy (mRefName, RefName);\r
+  } else {\r
+    mRefName          = NULL;\r
+  }\r
+\r
+  mNext               = NULL;\r
+  mDefaultId          = DefaultId;\r
+  mDefaultStoreNameId = DefaultStoreNameId;\r
+}\r
+\r
+SVfrDefaultStoreNode::~SVfrDefaultStoreNode (\r
+  VOID\r
+  )\r
+{\r
+  if (mRefName != NULL) {\r
+    delete mRefName;\r
+  }\r
+}\r
+\r
+CVfrDefaultStore::CVfrDefaultStore (\r
+  VOID\r
+  )\r
+{\r
+  mDefaultStoreList = NULL;\r
+}\r
+\r
+CVfrDefaultStore::~CVfrDefaultStore (\r
+  VOID\r
+  )\r
+{\r
+  SVfrDefaultStoreNode *pTmp = NULL;\r
+\r
+  while (mDefaultStoreList != NULL) {\r
+    pTmp = mDefaultStoreList;\r
+    mDefaultStoreList = mDefaultStoreList->mNext;\r
+    delete pTmp;\r
+  }\r
+}\r
+\r
+EFI_VFR_RETURN_CODE\r
+CVfrDefaultStore::RegisterDefaultStore (\r
+  IN CHAR8                *ObjBinAddr,\r
+  IN INT8                 *RefName,\r
+  IN EFI_STRING_ID        DefaultStoreNameId,\r
+  IN UINT16               DefaultId\r
+  )\r
+{\r
+  SVfrDefaultStoreNode *pNode = NULL;\r
+\r
+  if (RefName == NULL) {\r
+    return VFR_RETURN_FATAL_ERROR;\r
+  }\r
+\r
+  for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {\r
+    if (strcmp (pNode->mRefName, RefName) == 0) {\r
+      return VFR_RETURN_REDEFINED;\r
+    }\r
+  }\r
+\r
+  if ((pNode = new SVfrDefaultStoreNode ((EFI_IFR_DEFAULTSTORE *)ObjBinAddr, RefName, DefaultStoreNameId, DefaultId)) == NULL) {\r
+    return VFR_RETURN_OUT_FOR_RESOURCES;\r
+  }\r
+\r
+  pNode->mNext               = mDefaultStoreList;\r
+  mDefaultStoreList          = pNode;\r
+\r
+  return VFR_RETURN_SUCCESS;\r
+}\r
+\r
+/*\r
+ * assign new reference name or new default store name id only if \r
+ * the original is invalid\r
+ */\r
+EFI_VFR_RETURN_CODE\r
+CVfrDefaultStore::ReRegisterDefaultStoreById (\r
+  IN UINT16          DefaultId,\r
+  IN INT8            *RefName,\r
+  IN EFI_STRING_ID   DefaultStoreNameId\r
+  )\r
+{\r
+  SVfrDefaultStoreNode *pNode = NULL;\r
+\r
+  for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {\r
+    if (pNode->mDefaultId == DefaultId) {\r
+      break;\r
+    }\r
+  }\r
+\r
+  if (pNode == NULL) {\r
+    return VFR_RETURN_UNDEFINED;\r
+  } else {\r
+    if (pNode->mDefaultStoreNameId == EFI_STRING_ID_INVALID) {\r
+      pNode->mDefaultStoreNameId  = DefaultStoreNameId;\r
+      if (pNode->mObjBinAddr != NULL) {\r
+        pNode->mObjBinAddr->DefaultName = DefaultStoreNameId;\r
+      }\r
+    } else {\r
+      return VFR_RETURN_REDEFINED;\r
+    }\r
+\r
+    if (RefName != NULL) {\r
+      delete pNode->mRefName;\r
+      pNode->mRefName = new INT8[strlen (RefName) + 1];\r
+      if (pNode->mRefName != NULL) {\r
+        strcpy (pNode->mRefName, RefName);\r
+      }\r
+    }\r
+  }\r
+\r
+  return VFR_RETURN_SUCCESS;\r
+}\r
+\r
+BOOLEAN\r
+CVfrDefaultStore::DefaultIdRegistered (\r
+  IN UINT16          DefaultId\r
+  )\r
+{\r
+  SVfrDefaultStoreNode *pNode = NULL;\r
+\r
+  for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {\r
+    if (pNode->mDefaultId == DefaultId) {\r
+      return TRUE;\r
+    }\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
+EFI_VFR_RETURN_CODE\r
+CVfrDefaultStore::GetDefaultId (\r
+  IN  INT8            *RefName,\r
+  OUT UINT16          *DefaultId\r
+  )\r
+{\r
+  SVfrDefaultStoreNode *pTmp = NULL;\r
+\r
+  if (DefaultId == NULL) {\r
+    return VFR_RETURN_FATAL_ERROR;\r
+  }\r
+\r
+  for (pTmp = mDefaultStoreList; pTmp != NULL; pTmp = pTmp->mNext) {\r
+    if (strcmp (pTmp->mRefName, RefName) == 0) {\r
+      *DefaultId = pTmp->mDefaultId;\r
+      return VFR_RETURN_SUCCESS;\r
+    }\r
+  }\r
+\r
+  return VFR_RETURN_UNDEFINED;\r
+}\r
+\r
+STATIC\r
+EFI_VFR_RETURN_CODE\r
+AltCfgItemPrintToBuffer (\r
+  IN INT8               *NewAltCfg, \r
+  IN EFI_VARSTORE_INFO  Info, \r
+  IN UINT8              Type,\r
+  IN EFI_IFR_TYPE_VALUE Value\r
+  )\r
+{\r
+  UINT32 Index;\r
+  UINT8  *BufChar = NULL;\r
+  UINT32 Count    = 0;\r
+\r
+  if (NewAltCfg != NULL) {\r
+    Count = sprintf (\r
+              NewAltCfg, \r
+              "&OFFSET=%x&WIDTH=%x&VALUE=", \r
+              Info.mInfo.mVarOffset, \r
+              Info.mVarTotalSize\r
+              );\r
+    NewAltCfg += Count;\r
+\r
+    switch (Type) {\r
+    case EFI_IFR_TYPE_NUM_SIZE_8 :\r
+      Count = sprintf (NewAltCfg, "%x", Value.u8);\r
+      NewAltCfg += Count;\r
+      break;\r
+    case EFI_IFR_TYPE_NUM_SIZE_16 :\r
+      Count = sprintf (NewAltCfg, "%x", Value.u16);\r
+      NewAltCfg += Count;\r
+      break;\r
+    case EFI_IFR_TYPE_NUM_SIZE_32 :\r
+      Count = sprintf (NewAltCfg, "%x", Value.u32);\r
+      NewAltCfg += Count;\r
+      break;\r
+    case EFI_IFR_TYPE_NUM_SIZE_64 :\r
+      Count = sprintf (NewAltCfg, "%x", Value.u64);\r
+      NewAltCfg += Count;\r
+      break;\r
+    case EFI_IFR_TYPE_BOOLEAN :\r
+      Count = sprintf (NewAltCfg, "%x", Value.b);\r
+      NewAltCfg += Count;\r
+      break;\r
+    case EFI_IFR_TYPE_TIME :\r
+#if 1\r
+      Count = sprintf (NewAltCfg, "%x", *((UINT32 *)(&Value.time)));\r
+      NewAltCfg += Count;\r
+#else\r
+      BufChar = (UINT8 *)&Value.time;\r
+      for (Index = 0; Index < sizeof(EFI_HII_TIME); Index++) {\r
+        Count = sprintf (NewAltCfg, "%02x", (UINT8)BufChar[Index]);\r
+        NewAltCfg += Count;\r
+      }\r
+#endif\r
+      break;\r
+    case EFI_IFR_TYPE_DATE :\r
+#if 1\r
+      Count = sprintf (NewAltCfg, "%x", *((UINT32 *)(&Value.date)));\r
+      NewAltCfg += Count;\r
+#else\r
+      BufChar = (UINT8 *)&Value.date;\r
+      for (Index = 0; Index < sizeof(EFI_HII_DATE); Index++) {\r
+        Count = sprintf (NewAltCfg, "%02x", (UINT8)BufChar[Index]);\r
+        NewAltCfg += Count;\r
+      }\r
+#endif\r
+      break;\r
+    case EFI_IFR_TYPE_STRING :\r
+      Count = sprintf (NewAltCfg, "%x", Value.string);\r
+      NewAltCfg += Count;\r
+      break;\r
+    case EFI_IFR_TYPE_OTHER :\r
+      return VFR_RETURN_UNSUPPORTED;\r
+       }\r
+  }\r
+\r
+  return VFR_RETURN_FATAL_ERROR;    \r
+}\r
+\r
+EFI_VFR_RETURN_CODE\r
+CVfrDefaultStore::BufferVarStoreAltConfigAdd (\r
+  IN EFI_VARSTORE_ID    DefaultId,\r
+  IN EFI_VARSTORE_INFO  &Info,\r
+  IN INT8               *VarStoreName,\r
+  IN UINT8              Type,\r
+  IN EFI_IFR_TYPE_VALUE Value\r
+  )\r
+{\r
+  SVfrDefaultStoreNode  *pNode = NULL;\r
+  INT8                  NewAltCfg[2 * 2 * sizeof (UINT16) + 1] = {0,};\r
+\r
+  if (VarStoreName == NULL) {\r
+    return VFR_RETURN_FATAL_ERROR;\r
+  }\r
+\r
+  for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {\r
+    if (pNode->mDefaultId == DefaultId) {\r
+      break;\r
+    }\r
+  }\r
+\r
+  if (pNode == NULL) {\r
+    return VFR_RETURN_UNDEFINED;\r
+  }\r
+\r
+  gCVfrBufferConfig.Open ();\r
+\r
+  sprintf (NewAltCfg, "%04x", pNode->mDefaultId);\r
+  if ((gCVfrBufferConfig.Select(VarStoreName) == 0) && \r
+      (gCVfrBufferConfig.Select(VarStoreName, NewAltCfg) != 0)) {\r
+    if (gCVfrBufferConfig.Write ('i', VarStoreName, NewAltCfg, Type, Info.mInfo.mVarOffset, Info.mVarTotalSize, Value) != 0) {\r
+      goto WriteError;\r
+    }\r
+  }\r
+\r
+  if (gCVfrBufferConfig.Write ('a', VarStoreName, NULL, Type, Info.mInfo.mVarOffset, Info.mVarTotalSize, Value) != 0) {\r
+    goto WriteError;\r
+  }\r
+\r
+  gCVfrBufferConfig.Close ();\r
+\r
+  return VFR_RETURN_SUCCESS;\r
+\r
+WriteError:\r
+  gCVfrBufferConfig.Close ();\r
+  return VFR_RETURN_FATAL_ERROR;\r
+}\r
+\r
+SVfrRuleNode::SVfrRuleNode (\r
+  IN INT8        *RuleName, \r
+  IN UINT8       RuleId\r
+  )\r
+{\r
+  if (RuleName != NULL) {\r
+    mRuleName = new INT8[strlen (RuleName) + 1];\r
+    strcpy (mRuleName, RuleName);\r
+  } else {\r
+    mRuleName = NULL;\r
+  }\r
+\r
+  mNext       = NULL;\r
+  mRuleId     = RuleId;\r
+}\r
+\r
+SVfrRuleNode::~SVfrRuleNode (\r
+  VOID\r
+  )\r
+{\r
+  if (mRuleName != NULL) {\r
+    delete mRuleName;\r
+  }\r
+}\r
+\r
+CVfrRulesDB::CVfrRulesDB ()\r
+{\r
+  mRuleList   = NULL;\r
+  mFreeRuleId = EFI_VARSTORE_ID_START;\r
+}\r
+\r
+CVfrRulesDB::~CVfrRulesDB ()\r
+{\r
+  SVfrRuleNode *pNode;\r
+\r
+  while(mRuleList != NULL) {\r
+    pNode = mRuleList;\r
+    mRuleList = mRuleList->mNext;\r
+    delete pNode;\r
+  }\r
+}\r
+\r
+VOID\r
+CVfrRulesDB::RegisterRule (\r
+  IN INT8   *RuleName\r
+  )\r
+{\r
+  SVfrRuleNode *pNew;\r
+\r
+  if (RuleName == NULL) {\r
+    return ;\r
+  }\r
+\r
+  if ((pNew = new SVfrRuleNode (RuleName, mFreeRuleId)) == NULL) {\r
+    return ;\r
+  }\r
+\r
+  mFreeRuleId++;\r
+\r
+  pNew->mNext = mRuleList;\r
+  mRuleList   = pNew;\r
+}\r
+\r
+UINT8\r
+CVfrRulesDB::GetRuleId (\r
+  IN INT8   *RuleName\r
+  )\r
+{\r
+  SVfrRuleNode *pNode;\r
+\r
+  if (RuleName == NULL) {\r
+    return EFI_RULE_ID_INVALID;\r
+  }\r
+\r
+  for (pNode = mRuleList; pNode != NULL; pNode = pNode->mNext) {\r
+    if (strcmp (pNode->mRuleName, RuleName) == 0) {\r
+      return pNode->mRuleId;\r
+    }\r
+  }\r
+\r
+  return EFI_RULE_ID_INVALID;\r
+}\r
+\r
+CVfrRulesDB gCVfrRulesDB;\r
+\r
+EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (\r
+  VOID\r
+  )\r
+{\r
+  mVarStoreId      = EFI_VARSTORE_ID_INVALID;\r
+  mInfo.mVarName   = EFI_STRING_ID_INVALID;\r
+  mInfo.mVarOffset = EFI_VAROFFSET_INVALID;\r
+  mVarType         = EFI_IFR_TYPE_OTHER;\r
+  mVarTotalSize    = 0;\r
+}\r
+\r
+EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (\r
+  IN EFI_VARSTORE_INFO &Info\r
+  )\r
+{\r
+  mVarStoreId      = Info.mVarStoreId;\r
+  mInfo.mVarName   = Info.mInfo.mVarName;\r
+  mInfo.mVarOffset = Info.mInfo.mVarOffset;\r
+  mVarType         = Info.mVarType;\r
+  mVarTotalSize    = Info.mVarTotalSize;\r
+}\r
+\r
+BOOLEAN \r
+EFI_VARSTORE_INFO::operator == (\r
+  IN EFI_VARSTORE_INFO  *Info\r
+  )\r
+{\r
+  if ((mVarStoreId == Info->mVarStoreId) &&\r
+         (mInfo.mVarName == Info->mInfo.mVarName) &&\r
+      (mInfo.mVarOffset == Info->mInfo.mVarOffset) &&\r
+      (mVarType == Info->mVarType) &&\r
+      (mVarTotalSize == Info->mVarTotalSize)) {\r
+    return TRUE;\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
+static EFI_VARSTORE_INFO gEfiInvalidVarStoreInfo;\r
+\r
+EFI_QUESTION_ID\r
+CVfrQuestionDB::GetFreeQuestionId (\r
+  VOID\r
+  )\r
+{\r
+  UINT32  Index, Mask, Offset;\r
+\r
+  for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {\r
+    if (mFreeQIdBitMap[Index] != 0xFFFFFFFF) {\r
+      break;\r
+    }\r
+  }\r
+\r
+  for (Offset = 0, Mask = 0x80000000; Mask != 0; Mask >>= 1, Offset++) {\r
+    if ((mFreeQIdBitMap[Index] & Mask) == 0) {\r
+      mFreeQIdBitMap[Index] |= Mask;\r
+      return (EFI_QUESTION_ID)((Index << EFI_BITS_SHIFT_PER_UINT32) + Offset);\r
+    }\r
+  }\r
+\r
+  return EFI_QUESTION_ID_INVALID;\r
+}\r
+\r
+BOOLEAN\r
+CVfrQuestionDB::ChekQuestionIdFree (\r
+  IN EFI_QUESTION_ID QId\r
+  )\r
+{\r
+  UINT32 Index  = (QId / EFI_BITS_PER_UINT32);\r
+  UINT32 Offset = (QId % EFI_BITS_PER_UINT32);\r
+\r
+  return (mFreeQIdBitMap[Index] & (0x80000000 >> Offset)) == 0;\r
+}\r
+\r
+VOID \r
+CVfrQuestionDB::MarkQuestionIdUsed (\r
+  IN EFI_QUESTION_ID QId\r
+  )\r
+{\r
+  UINT32 Index  = (QId / EFI_BITS_PER_UINT32);\r
+  UINT32 Offset = (QId % EFI_BITS_PER_UINT32);\r
+\r
+  mFreeQIdBitMap[Index] |= (0x80000000 >> Offset);\r
+}\r
+\r
+VOID \r
+CVfrQuestionDB::MarkQuestionIdUnused (\r
+  IN EFI_QUESTION_ID QId\r
+  )\r
+{\r
+  UINT32 Index  = (QId / EFI_BITS_PER_UINT32);\r
+  UINT32 Offset = (QId % EFI_BITS_PER_UINT32);\r
+\r
+  mFreeQIdBitMap[Index] &= ~(0x80000000 >> Offset);\r
+}\r
+\r
+SVfrQuestionNode::SVfrQuestionNode (\r
+  IN INT8   *Name,\r
+  IN INT8   *VarIdStr,\r
+  IN UINT32 BitMask\r
+  )\r
+{\r
+  mName       = NULL;\r
+  mVarIdStr   = NULL;\r
+  mQuestionId = EFI_QUESTION_ID_INVALID;\r
+  mBitMask    = BitMask;\r
+  mNext       = NULL;\r
+\r
+  if (Name == NULL) {\r
+    mName = new INT8[strlen ("$DEFAULT") + 1];\r
+    strcpy (mName, "$DEFAULT");\r
+  } else {\r
+    mName = new INT8[strlen (Name) + 1];\r
+    strcpy (mName, Name);\r
+  }\r
+\r
+  if (VarIdStr != NULL) {\r
+    mVarIdStr = new INT8[strlen (VarIdStr) + 1];\r
+    strcpy (mVarIdStr, VarIdStr);\r
+  } else {\r
+    mVarIdStr = new INT8[strlen ("$") + 1];\r
+    strcpy (mVarIdStr, "$");\r
+  }\r
+}\r
+\r
+SVfrQuestionNode::~SVfrQuestionNode (\r
+  VOID\r
+  )\r
+{\r
+  if (mName != NULL) {\r
+    delete mName;\r
+  }\r
+\r
+  if (mVarIdStr != NULL) {\r
+    delete mVarIdStr;\r
+  }\r
+}\r
+\r
+CVfrQuestionDB::CVfrQuestionDB ()\r
+{\r
+  UINT32 Index;\r
+\r
+  for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {\r
+    mFreeQIdBitMap[Index] = 0;\r
+  }\r
+\r
+  // Question ID 0 is reserved.\r
+  mFreeQIdBitMap[0] = 0x80000000;\r
+  mQuestionList     = NULL;\r
+}\r
+\r
+CVfrQuestionDB::~CVfrQuestionDB ()\r
+{\r
+  SVfrQuestionNode     *pNode;\r
+\r
+  while (mQuestionList != NULL) {\r
+    pNode = mQuestionList;\r
+    mQuestionList = mQuestionList->mNext;\r
+    delete pNode;\r
+  }\r
+}\r
+\r
+EFI_VFR_RETURN_CODE\r
+CVfrQuestionDB::RegisterQuestion (\r
+  IN     INT8              *Name,\r
+  IN     INT8              *VarIdStr,\r
+  IN OUT EFI_QUESTION_ID   &QuestionId\r
+  )\r
+{\r
+  SVfrQuestionNode *pNode = NULL;\r
+\r
+  if ((Name != NULL) && (FindQuestion(Name) == VFR_RETURN_SUCCESS)) {\r
+    return VFR_RETURN_REDEFINED;\r
+  }\r
+\r
+  if ((pNode = new SVfrQuestionNode (Name, VarIdStr)) == NULL) {\r
+    return VFR_RETURN_OUT_FOR_RESOURCES;\r
+  }\r
+\r
+  if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
+    QuestionId = GetFreeQuestionId ();\r
+  } else {\r
+    if (ChekQuestionIdFree (QuestionId) == FALSE) {\r
+      delete pNode;\r
+      return VFR_RETURN_QUESTIONID_REDEFINED;\r
+    }\r
+    MarkQuestionIdUsed (QuestionId);\r
+  }\r
+  pNode->mQuestionId = QuestionId;\r
+\r
+  pNode->mNext       = mQuestionList;\r
+  mQuestionList      = pNode;\r
+\r
+  gCFormPkg.DoPendingAssign (VarIdStr, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
+\r
+  return VFR_RETURN_SUCCESS;\r
+}\r
+\r
+VOID\r
+CVfrQuestionDB::RegisterOldDateQuestion (\r
+  IN     INT8            *YearVarId, \r
+  IN     INT8            *MonthVarId, \r
+  IN     INT8            *DayVarId, \r
+  IN OUT EFI_QUESTION_ID &QuestionId\r
+  )\r
+{\r
+  SVfrQuestionNode *pNode[3] = {NULL, };\r
+  UINT32           Index;\r
+\r
+  if ((YearVarId == NULL) || (MonthVarId == NULL) || (DayVarId == NULL)) {\r
+    return;\r
+  }\r
+\r
+  if ((pNode[0] = new SVfrQuestionNode (NULL, YearVarId, DATE_YEAR_BITMASK)) == NULL) {\r
+    goto Err;\r
+  }\r
+  if ((pNode[1] = new SVfrQuestionNode (NULL, MonthVarId, DATE_MONTH_BITMASK)) == NULL) {\r
+    goto Err;\r
+  }\r
+  if ((pNode[2] = new SVfrQuestionNode (NULL, DayVarId, DATE_DAY_BITMASK)) == NULL) {\r
+    goto Err;\r
+  }\r
+\r
+  if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
+    QuestionId = GetFreeQuestionId ();\r
+  } else {\r
+    if (ChekQuestionIdFree (QuestionId) == FALSE) {\r
+      goto Err;\r
+    }\r
+    MarkQuestionIdUsed (QuestionId);\r
+  }\r
+\r
+  pNode[0]->mQuestionId = QuestionId;\r
+  pNode[1]->mQuestionId = QuestionId;\r
+  pNode[2]->mQuestionId = QuestionId;\r
+  pNode[0]->mNext       = pNode[1];\r
+  pNode[1]->mNext       = pNode[2];\r
+  pNode[2]->mNext       = mQuestionList;\r
+  mQuestionList         = pNode[0];\r
+\r
+  gCFormPkg.DoPendingAssign (YearVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
+  gCFormPkg.DoPendingAssign (MonthVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
+  gCFormPkg.DoPendingAssign (DayVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
+\r
+  return;\r
+\r
+Err:\r
+  for (Index = 0; Index < 3; Index++) {\r
+    if (pNode[Index] != NULL) {\r
+      delete pNode[Index];\r
+    }\r
+  }\r
+  QuestionId = EFI_QUESTION_ID_INVALID;\r
+}\r
+\r
+VOID\r
+CVfrQuestionDB::RegisterNewDateQuestion (\r
+  IN     INT8            *Name,\r
+  IN     INT8            *BaseVarId, \r
+  IN OUT EFI_QUESTION_ID &QuestionId\r
+  )\r
+{\r
+  SVfrQuestionNode     *pNode[3] = {NULL, };\r
+  UINT32               Len;\r
+  INT8                 *VarIdStr[3] = {NULL, };\r
+  INT8                 Index;\r
+\r
+  if (BaseVarId == NULL) {\r
+    return;\r
+  }\r
+\r
+  Len = strlen (BaseVarId);\r
+\r
+  VarIdStr[0] = new INT8[Len + strlen (".Year") + 1];\r
+  if (VarIdStr[0] != NULL) {\r
+    strcpy (VarIdStr[0], BaseVarId);\r
+    strcat (VarIdStr[0], ".Year");\r
+  }\r
+  VarIdStr[1] = new INT8[Len + strlen (".Month") + 1];\r
+  if (VarIdStr[1] != NULL) {\r
+    strcpy (VarIdStr[1], BaseVarId);\r
+    strcat (VarIdStr[1], ".Month");\r
+  }\r
+  VarIdStr[2] = new INT8[Len + strlen (".Day") + 1];\r
+  if (VarIdStr[2] != NULL) {\r
+    strcpy (VarIdStr[2], BaseVarId);\r
+    strcat (VarIdStr[2], ".Day");\r
+  }\r
+\r
+  if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0], DATE_YEAR_BITMASK)) == NULL) {\r
+    goto Err;\r
+  }\r
+  if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1], DATE_MONTH_BITMASK)) == NULL) {\r
+    goto Err;\r
+  }\r
+  if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2], DATE_DAY_BITMASK)) == NULL) {\r
+    goto Err;\r
+  }\r
+\r
+  if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
+    QuestionId = GetFreeQuestionId ();\r
+  } else {\r
+    if (ChekQuestionIdFree (QuestionId) == FALSE) {\r
+      goto Err;\r
+    }\r
+    MarkQuestionIdUsed (QuestionId);\r
+  }\r
+\r
+  pNode[0]->mQuestionId = QuestionId;\r
+  pNode[1]->mQuestionId = QuestionId;\r
+  pNode[2]->mQuestionId = QuestionId;\r
+  pNode[0]->mNext       = pNode[1];\r
+  pNode[1]->mNext       = pNode[2];\r
+  pNode[2]->mNext       = mQuestionList;\r
+  mQuestionList         = pNode[0];\r
+\r
+  for (Index = 0; Index < 3; Index++) {\r
+    if (VarIdStr[Index] != NULL) {\r
+      delete VarIdStr[Index];\r
+    }\r
+  }\r
+\r
+  gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
+  gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
+  gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
+\r
+  return;\r
+\r
+Err:\r
+  for (Index = 0; Index < 3; Index++) {\r
+    if (pNode[Index] != NULL) {\r
+      delete pNode[Index];\r
+    }\r
+\r
+    if (VarIdStr[Index] != NULL) {\r
+      delete VarIdStr[Index];\r
+    }\r
+  }\r
+}\r
+\r
+VOID\r
+CVfrQuestionDB::RegisterOldTimeQuestion (\r
+  IN     INT8            *HourVarId, \r
+  IN     INT8            *MinuteVarId, \r
+  IN     INT8            *SecondVarId, \r
+  IN OUT EFI_QUESTION_ID &QuestionId\r
+  )\r
+{\r
+  SVfrQuestionNode *pNode[3] = {NULL, };\r
+  UINT32           Index;\r
+\r
+  if ((HourVarId == NULL) || (MinuteVarId == NULL) || (SecondVarId == NULL)) {\r
+    return;\r
+  }\r
+\r
+  if ((pNode[0] = new SVfrQuestionNode (NULL, HourVarId, TIME_HOUR_BITMASK)) == NULL) {\r
+    goto Err;\r
+  }\r
+  if ((pNode[1] = new SVfrQuestionNode (NULL, MinuteVarId, TIME_MINUTE_BITMASK)) == NULL) {\r
+    goto Err;\r
+  }\r
+  if ((pNode[2] = new SVfrQuestionNode (NULL, SecondVarId, TIME_SECOND_BITMASK)) == NULL) {\r
+    goto Err;\r
+  }\r
+\r
+  if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
+    QuestionId = GetFreeQuestionId ();\r
+  } else {\r
+    if (ChekQuestionIdFree (QuestionId) == FALSE) {\r
+      goto Err;\r
+    }\r
+    MarkQuestionIdUsed (QuestionId);\r
+  }\r
+\r
+  pNode[0]->mQuestionId = QuestionId;\r
+  pNode[1]->mQuestionId = QuestionId;\r
+  pNode[2]->mQuestionId = QuestionId;\r
+  pNode[0]->mNext       = pNode[1];\r
+  pNode[1]->mNext       = pNode[2];\r
+  pNode[2]->mNext       = mQuestionList;\r
+  mQuestionList         = pNode[0];\r
+\r
+  gCFormPkg.DoPendingAssign (HourVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
+  gCFormPkg.DoPendingAssign (MinuteVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
+  gCFormPkg.DoPendingAssign (SecondVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
+\r
+  return;\r
+\r
+Err:\r
+  for (Index = 0; Index < 3; Index++) {\r
+    if (pNode[Index] != NULL) {\r
+      delete pNode[Index];\r
+    }\r
+  }\r
+  QuestionId = EFI_QUESTION_ID_INVALID;\r
+}\r
+\r
+VOID\r
+CVfrQuestionDB::RegisterNewTimeQuestion (\r
+  IN     INT8            *Name,\r
+  IN     INT8            *BaseVarId,\r
+  IN OUT EFI_QUESTION_ID &QuestionId\r
+  )\r
+{\r
+  SVfrQuestionNode     *pNode[3] = {NULL, };\r
+  UINT32               Len;\r
+  INT8                 *VarIdStr[3] = {NULL, };\r
+  INT8                 Index;\r
+\r
+  if (BaseVarId == NULL) {\r
+    return;\r
+  }\r
+\r
+  Len = strlen (BaseVarId);\r
+\r
+  VarIdStr[0] = new INT8[Len + strlen (".Hour") + 1];\r
+  if (VarIdStr[0] != NULL) {\r
+    strcpy (VarIdStr[0], BaseVarId);\r
+    strcat (VarIdStr[0], ".Hour");\r
+  }\r
+  VarIdStr[1] = new INT8[Len + strlen (".Minute") + 1];\r
+  if (VarIdStr[1] != NULL) {\r
+    strcpy (VarIdStr[1], BaseVarId);\r
+    strcat (VarIdStr[1], ".Minute");\r
+  }\r
+  VarIdStr[2] = new INT8[Len + strlen (".Second") + 1];\r
+  if (VarIdStr[2] != NULL) {\r
+    strcpy (VarIdStr[2], BaseVarId);\r
+    strcat (VarIdStr[2], ".Second");\r
+  }\r
+\r
+  if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0], TIME_HOUR_BITMASK)) == NULL) {\r
+    goto Err;\r
+  }\r
+  if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1], TIME_MINUTE_BITMASK)) == NULL) {\r
+    goto Err;\r
+  }\r
+  if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2], TIME_SECOND_BITMASK)) == NULL) {\r
+    goto Err;\r
+  }\r
+\r
+  if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
+    QuestionId = GetFreeQuestionId ();\r
+  } else {\r
+    if (ChekQuestionIdFree (QuestionId) == FALSE) {\r
+      goto Err;\r
+    }\r
+    MarkQuestionIdUsed (QuestionId);\r
+  }\r
+\r
+  pNode[0]->mQuestionId = QuestionId;\r
+  pNode[1]->mQuestionId = QuestionId;\r
+  pNode[2]->mQuestionId = QuestionId;\r
+  pNode[0]->mNext       = pNode[1];\r
+  pNode[1]->mNext       = pNode[2];\r
+  pNode[2]->mNext       = mQuestionList;\r
+  mQuestionList         = pNode[0];\r
+\r
+  for (Index = 0; Index < 3; Index++) {\r
+    if (VarIdStr[Index] != NULL) {\r
+      delete VarIdStr[Index];\r
+    }\r
+  }\r
+\r
+  gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
+  gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
+  gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
+\r
+  return;\r
+\r
+Err:\r
+  for (Index = 0; Index < 3; Index++) {\r
+    if (pNode[Index] != NULL) {\r
+      delete pNode[Index];\r
+    }\r
+\r
+    if (VarIdStr[Index] != NULL) {\r
+      delete VarIdStr[Index];\r
+    }\r
+  }\r
+}\r
+\r
+EFI_VFR_RETURN_CODE\r
+CVfrQuestionDB::UpdateQuestionId (\r
+  IN EFI_QUESTION_ID   QId,\r
+  IN EFI_QUESTION_ID   NewQId\r
+  )\r
+{\r
+  SVfrQuestionNode *pNode = NULL;\r
+\r
+  if (ChekQuestionIdFree (NewQId) == FALSE) {\r
+    return VFR_RETURN_REDEFINED;\r
+  }\r
+\r
+  for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {\r
+    if (pNode->mQuestionId == QId) {\r
+      break;\r
+    }\r
+  }\r
+\r
+  if (pNode == NULL) {\r
+    return VFR_RETURN_UNDEFINED;\r
+  }\r
+\r
+  MarkQuestionIdUnused (QId);\r
+  pNode->mQuestionId = NewQId;\r
+  MarkQuestionIdUsed (NewQId);\r
+\r
+  gCFormPkg.DoPendingAssign (pNode->mVarIdStr, (VOID *)&NewQId, sizeof(EFI_QUESTION_ID));\r
+\r
+  return VFR_RETURN_SUCCESS;\r
+}\r
+\r
+VOID \r
+CVfrQuestionDB::GetQuestionId (\r
+  IN  INT8              *Name,\r
+  IN  INT8              *VarIdStr,\r
+  OUT EFI_QUESTION_ID   &QuestionId,\r
+  OUT UINT32            &BitMask\r
+  )\r
+{\r
+  SVfrQuestionNode *pNode;\r
+\r
+  QuestionId = EFI_QUESTION_ID_INVALID;\r
+  BitMask    = 0x00000000;\r
+\r
+  if ((Name == NULL) && (VarIdStr == NULL)) {\r
+    return ;\r
+  }\r
+\r
+  for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {\r
+    if (Name != NULL) {\r
+      if (strcmp (pNode->mName, Name) != 0) {\r
+        continue;\r
+      }\r
+    }\r
+\r
+    if (VarIdStr != NULL) {\r
+      if (strcmp (pNode->mVarIdStr, VarIdStr) != 0) {\r
+        continue;\r
+      }\r
+       }\r
+\r
+    QuestionId = pNode->mQuestionId;\r
+    BitMask    = pNode->mBitMask;\r
+    break;\r
+  }\r
+\r
+  return ;\r
+}\r
+\r
+EFI_VFR_RETURN_CODE \r
+CVfrQuestionDB::FindQuestion (\r
+  IN EFI_QUESTION_ID QuestionId\r
+  )\r
+{\r
+  SVfrQuestionNode *pNode;\r
+\r
+  if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
+    return VFR_RETURN_INVALID_PARAMETER;\r
+  }\r
+\r
+  for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {\r
+    if (pNode->mQuestionId == QuestionId) {\r
+      return VFR_RETURN_SUCCESS;\r
+    }\r
+  }\r
+\r
+  return VFR_RETURN_UNDEFINED;\r
+}\r
+\r
+EFI_VFR_RETURN_CODE \r
+CVfrQuestionDB::FindQuestion (\r
+  IN INT8 *Name\r
+  )\r
+{\r
+  SVfrQuestionNode *pNode;\r
+\r
+  if (Name == NULL) {\r
+    return VFR_RETURN_FATAL_ERROR;\r
+  }\r
+\r
+  for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {\r
+    if (strcmp (pNode->mName, Name) == 0) {\r
+      return VFR_RETURN_SUCCESS;\r
+    }\r
+  }\r
+\r
+  return VFR_RETURN_UNDEFINED;\r
+}\r
+\r
diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrUtilityLib.h b/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrUtilityLib.h
new file mode 100644 (file)
index 0000000..e8c1009
--- /dev/null
@@ -0,0 +1,341 @@
+#ifndef _VFRUTILITYLIB_H_\r
+#define _VFRUTILITYLIB_H_\r
+\r
+#include "Tiano.h"\r
+#include "string.h"\r
+#include "EfiTypes.h"\r
+#include "EfiVfr.h"\r
+#include "VfrError.h"\r
+\r
+#define MAX_NAME_LEN                       64\r
+#define DEFAULT_ALIGN                      1\r
+#define DEFAULT_PACK_ALIGN                 0xFFFFFFFF\r
+#define DEFAULT_NAME_TABLE_ITEMS           1024\r
+\r
+#define EFI_BITS_SHIFT_PER_UINT32          0x5\r
+#define EFI_BITS_PER_UINT32                (1 << EFI_BITS_SHIFT_PER_UINT32)\r
+\r
+#define BUFFER_SAFE_FREE(Buf)              do { if ((Buf) != NULL) { delete (Buf); } } while (0);\r
+\r
+class CVfrBinaryOutput {\r
+public:\r
+  virtual VOID WriteLine (IN FILE *, IN UINT32, IN INT8 *, IN INT8 *, IN UINT32);\r
+  virtual VOID WriteEnd (IN FILE *, IN UINT32, IN INT8 *, IN INT8 *, IN UINT32);\r
+};\r
+\r
+UINT32\r
+_STR2U32 (\r
+  IN INT8 *Str\r
+  );\r
+\r
+struct SConfigInfo {\r
+  UINT16             mOffset;\r
+  UINT16             mWidth;\r
+  UINT8              *mValue;\r
+  SConfigInfo        *mNext;\r
+\r
+  SConfigInfo (IN UINT8, IN UINT16, IN UINT32, IN EFI_IFR_TYPE_VALUE);\r
+  ~SConfigInfo (VOID);\r
+};\r
+\r
+struct SConfigItem {\r
+  INT8          *mId;\r
+  INT8          *mInfo;\r
+  SConfigInfo   *mInfoStrList;\r
+  SConfigItem   *mNext;\r
+\r
+public:\r
+  SConfigItem (IN INT8 *, IN INT8 *);\r
+  SConfigItem (IN INT8 *, IN INT8 *, IN UINT8, IN UINT16, IN UINT16, IN EFI_IFR_TYPE_VALUE);\r
+  virtual ~SConfigItem ();\r
+};\r
+\r
+class CVfrBufferConfig {\r
+private:\r
+  SConfigItem *mItemListHead;\r
+  SConfigItem *mItemListTail;\r
+  SConfigItem *mItemListPos;\r
+\r
+public:\r
+  CVfrBufferConfig (VOID);\r
+  virtual ~CVfrBufferConfig (VOID);\r
+\r
+  virtual UINT8   Register (IN INT8 *, IN INT8 *Info = NULL);\r
+  virtual VOID    Open (VOID);\r
+  virtual BOOLEAN Eof(VOID);\r
+  virtual UINT8   Select (IN INT8 *, IN INT8 *Info = NULL);\r
+  virtual UINT8   Write (IN CONST CHAR8, IN INT8 *, IN INT8 *, IN UINT8, IN UINT16, IN UINT32, IN EFI_IFR_TYPE_VALUE);\r
+#if 0\r
+  virtual UINT8   Read (OUT INT8 **, OUT INT8 **, OUT INT8 **, OUT INT8 **, OUT INT8 **);\r
+#endif\r
+  virtual VOID    Close (VOID);\r
+  virtual VOID    OutputCFile (IN FILE *, IN INT8 *);\r
+};\r
+\r
+extern CVfrBufferConfig gCVfrBufferConfig;\r
+\r
+#define ALIGN_STUFF(Size, Align) ((Align) - (Size) % (Align))\r
+#define INVALID_ARRAY_INDEX      0xFFFFFFFF\r
+\r
+struct SVfrDataType;\r
+\r
+struct SVfrDataField {\r
+  INT8                      mFieldName[MAX_NAME_LEN];\r
+  SVfrDataType              *mFieldType;\r
+  UINT32                    mOffset;\r
+  UINT32                    mArrayNum;\r
+  SVfrDataField             *mNext;\r
+};\r
+\r
+struct SVfrDataType {\r
+  INT8                      mTypeName[MAX_NAME_LEN];\r
+  UINT8                     mType;\r
+  UINT32                    mAlign;\r
+  UINT32                    mTotalSize;\r
+  SVfrDataField             *mMembers;\r
+  SVfrDataType              *mNext;\r
+};\r
+\r
+class CVfrVarDataTypeDB {\r
+private:\r
+  SVfrDataType              *mDataTypeList;\r
+  UINT32                    mPackAlign;\r
+\r
+  SVfrDataType              *mNewDataType;\r
+  SVfrDataType              *mCurrDataType;\r
+  SVfrDataField             *mCurrDataField;\r
+\r
+  VOID InternalTypesListInit (VOID);\r
+  VOID RegisterNewType (IN SVfrDataType *);\r
+\r
+  EFI_VFR_RETURN_CODE ExtractStructTypeName (IN INT8 *&, OUT INT8 *);\r
+  EFI_VFR_RETURN_CODE ExtractFieldNameAndArrary (IN INT8 *&, OUT INT8 *, OUT UINT32 &);\r
+  EFI_VFR_RETURN_CODE GetTypeField (IN INT8 *, IN SVfrDataType *, IN SVfrDataField *&);\r
+  EFI_VFR_RETURN_CODE GetFieldOffset (IN SVfrDataField *, IN UINT32, OUT UINT32 &);\r
+  UINT8               GetFieldWidth (IN SVfrDataField *);\r
+  UINT32              GetFieldSize (IN SVfrDataField *, IN UINT32);\r
+\r
+public:\r
+  CVfrVarDataTypeDB (VOID);\r
+  ~CVfrVarDataTypeDB (VOID);\r
+\r
+  EFI_VFR_RETURN_CODE Pack (IN UINT32);\r
+  VOID                UnPack (VOID);\r
+\r
+  VOID                DeclareDataTypeBegin (VOID);\r
+  EFI_VFR_RETURN_CODE SetNewTypeName (IN INT8 *);\r
+  EFI_VFR_RETURN_CODE DataTypeAddField (IN INT8 *, IN INT8 *, IN UINT32);\r
+  VOID                DeclareDataTypeEnd (VOID);\r
+\r
+  EFI_VFR_RETURN_CODE GetDataType (IN INT8 *, OUT SVfrDataType **);\r
+  EFI_VFR_RETURN_CODE GetDataTypeSize (IN INT8 *, OUT UINT32 *);\r
+  EFI_VFR_RETURN_CODE GetDataFieldInfo (IN INT8 *, OUT UINT16 &, OUT UINT8 &, OUT UINT32 &);\r
+\r
+  EFI_VFR_RETURN_CODE GetUserDefinedTypeNameList (OUT INT8 ***, OUT UINT32 *);\r
+  BOOLEAN             IsTypeNameDefined (IN INT8 *);\r
+\r
+#ifdef CVFR_VARDATATYPEDB_DEBUG\r
+  VOID ParserDB ();\r
+#endif\r
+};\r
+\r
+typedef enum {\r
+  EFI_VFR_VARSTORE_INVALID,\r
+  EFI_VFR_VARSTORE_BUFFER,\r
+  EFI_VFR_VARSTORE_EFI,\r
+  EFI_VFR_VARSTORE_NAME\r
+} EFI_VFR_VARSTORE_TYPE;\r
+\r
+struct SVfrVarStorageNode {\r
+  EFI_GUID                  mGuid;\r
+  INT8                      *mVarStoreName;\r
+  EFI_VARSTORE_ID           mVarStoreId;\r
+  struct SVfrVarStorageNode *mNext;\r
+\r
+  EFI_VFR_VARSTORE_TYPE     mVarStoreType;\r
+  union {\r
+    // EFI Variable\r
+    struct {\r
+      EFI_STRING_ID           mEfiVarName;\r
+      UINT32                  mEfiVarSize;\r
+    } mEfiVar;\r
+\r
+    // Buffer Storage\r
+    SVfrDataType            *mDataType;\r
+\r
+    // NameValue Storage\r
+       struct {\r
+      EFI_STRING_ID         *mNameTable;\r
+      UINT32                mTableSize;\r
+    } mNameSpace;\r
+  } mStorageInfo;\r
+\r
+public:\r
+  SVfrVarStorageNode (IN EFI_GUID *, IN INT8 *, IN EFI_VARSTORE_ID, IN EFI_STRING_ID, IN UINT32);\r
+  SVfrVarStorageNode (IN EFI_GUID *, IN INT8 *, IN EFI_VARSTORE_ID, IN SVfrDataType *);\r
+  SVfrVarStorageNode (IN INT8 *, IN EFI_VARSTORE_ID);\r
+  ~SVfrVarStorageNode (VOID);\r
+};\r
+\r
+struct EFI_VARSTORE_INFO {\r
+  EFI_VARSTORE_ID           mVarStoreId;\r
+  union {\r
+    EFI_STRING_ID           mVarName;\r
+    UINT16                  mVarOffset;\r
+  } mInfo;\r
+  UINT8                     mVarType;\r
+  UINT32                    mVarTotalSize;\r
+\r
+  EFI_VARSTORE_INFO (VOID);\r
+  EFI_VARSTORE_INFO (IN EFI_VARSTORE_INFO &);\r
+  BOOLEAN operator == (IN EFI_VARSTORE_INFO *);\r
+};\r
+\r
+#define EFI_VARSTORE_ID_MAX              0xFFFF\r
+#define EFI_FREE_VARSTORE_ID_BITMAP_SIZE ((EFI_VARSTORE_ID_MAX + 1) / EFI_BITS_PER_UINT32)\r
+\r
+class CVfrDataStorage {\r
+private:\r
+  UINT32                    mFreeVarStoreIdBitMap[EFI_FREE_VARSTORE_ID_BITMAP_SIZE];\r
+\r
+  struct SVfrVarStorageNode *mBufferVarStoreList;\r
+  struct SVfrVarStorageNode *mEfiVarStoreList;\r
+  struct SVfrVarStorageNode *mNameVarStoreList;\r
+\r
+  struct SVfrVarStorageNode *mCurrVarStorageNode;\r
+  struct SVfrVarStorageNode *mNewVarStorageNode;\r
+\r
+private:\r
+\r
+  EFI_VARSTORE_ID GetFreeVarStoreId (VOID);\r
+  BOOLEAN         ChekVarStoreIdFree (IN EFI_VARSTORE_ID);\r
+  VOID            MarkVarStoreIdUsed (IN EFI_VARSTORE_ID);\r
+  VOID            MarkVarStoreIdUnused (IN EFI_VARSTORE_ID);\r
+\r
+public:\r
+  CVfrDataStorage ();\r
+  ~CVfrDataStorage ();\r
+\r
+  EFI_VFR_RETURN_CODE DeclareNameVarStoreBegin (INT8 *);\r
+  EFI_VFR_RETURN_CODE NameTableAddItem (EFI_STRING_ID);\r
+  EFI_VFR_RETURN_CODE DeclareNameVarStoreEnd (EFI_GUID *);\r
+\r
+  EFI_VFR_RETURN_CODE DeclareEfiVarStore (IN INT8 *, IN EFI_GUID *, IN EFI_STRING_ID, IN UINT32);\r
+\r
+  EFI_VFR_RETURN_CODE DeclareBufferVarStore (IN INT8 *, IN EFI_GUID *, IN CVfrVarDataTypeDB *, IN INT8 *, IN EFI_VARSTORE_ID);\r
+\r
+  EFI_VFR_RETURN_CODE GetVarStoreId (IN INT8 *, OUT EFI_VARSTORE_ID *);\r
+  EFI_VFR_RETURN_CODE GetVarStoreType (IN INT8 *, OUT EFI_VFR_VARSTORE_TYPE &);\r
+  EFI_VFR_RETURN_CODE GetVarStoreName (IN EFI_VARSTORE_ID, OUT INT8 **);\r
+\r
+  EFI_VFR_RETURN_CODE GetBufferVarStoreDataTypeName (IN INT8 *, OUT INT8 **);\r
+  EFI_VFR_RETURN_CODE GetEfiVarStoreInfo (IN EFI_VARSTORE_INFO *);\r
+  EFI_VFR_RETURN_CODE GetNameVarStoreInfo (IN EFI_VARSTORE_INFO *, IN UINT32);\r
+\r
+  EFI_VFR_RETURN_CODE BufferVarStoreRequestElementAdd (IN INT8 *, IN EFI_VARSTORE_INFO &);\r
+};\r
+\r
+#define EFI_QUESTION_ID_MAX              0xFFFF\r
+#define EFI_FREE_QUESTION_ID_BITMAP_SIZE ((EFI_QUESTION_ID_MAX + 1) / EFI_BITS_PER_UINT32)\r
+#define EFI_QUESTION_ID_INVALID          0x0\r
+\r
+#define DATE_YEAR_BITMASK                0x0000FFFF\r
+#define DATE_MONTH_BITMASK               0x00FF0000\r
+#define DATE_DAY_BITMASK                 0xFF000000\r
+#define TIME_HOUR_BITMASK                0x000000FF\r
+#define TIME_MINUTE_BITMASK              0x0000FF00\r
+#define TIME_SECOND_BITMASK              0x00FF0000\r
+\r
+struct SVfrQuestionNode {\r
+  INT8                      *mName;\r
+  INT8                      *mVarIdStr;\r
+  EFI_QUESTION_ID           mQuestionId;\r
+  UINT32                    mBitMask;\r
+  SVfrQuestionNode          *mNext;\r
+\r
+  SVfrQuestionNode (IN INT8 *, IN INT8 *, IN UINT32 BitMask = 0);\r
+  ~SVfrQuestionNode ();\r
+};\r
+\r
+class CVfrQuestionDB {\r
+private:\r
+  SVfrQuestionNode          *mQuestionList;\r
+  UINT32                    mFreeQIdBitMap[EFI_FREE_QUESTION_ID_BITMAP_SIZE];\r
+\r
+private:\r
+  EFI_QUESTION_ID GetFreeQuestionId (VOID);\r
+  BOOLEAN         ChekQuestionIdFree (IN EFI_QUESTION_ID);\r
+  VOID            MarkQuestionIdUsed (IN EFI_QUESTION_ID);\r
+  VOID            MarkQuestionIdUnused (IN EFI_QUESTION_ID);\r
+\r
+public:\r
+  CVfrQuestionDB ();\r
+  ~CVfrQuestionDB();\r
+\r
+  EFI_VFR_RETURN_CODE RegisterQuestion (IN INT8 *, IN INT8 *, IN OUT EFI_QUESTION_ID &);\r
+  VOID                RegisterOldDateQuestion (IN INT8 *, IN INT8 *, IN INT8 *, IN OUT EFI_QUESTION_ID &);\r
+  VOID                RegisterNewDateQuestion (IN INT8 *, IN INT8 *, IN OUT EFI_QUESTION_ID &);\r
+  VOID                RegisterOldTimeQuestion (IN INT8 *, IN INT8 *, IN INT8 *, IN OUT EFI_QUESTION_ID &);\r
+  VOID                RegisterNewTimeQuestion (IN INT8 *, IN INT8 *, IN OUT EFI_QUESTION_ID &);\r
+  EFI_VFR_RETURN_CODE UpdateQuestionId (IN EFI_QUESTION_ID, IN EFI_QUESTION_ID);\r
+  VOID                GetQuestionId (IN INT8 *, IN INT8 *, OUT EFI_QUESTION_ID &, OUT UINT32 &);\r
+  EFI_VFR_RETURN_CODE FindQuestion (IN EFI_QUESTION_ID);\r
+  EFI_VFR_RETURN_CODE FindQuestion (IN INT8 *);\r
+ };\r
+\r
+struct SVfrDefaultStoreNode {\r
+  EFI_IFR_DEFAULTSTORE      *mObjBinAddr;\r
+  INT8                      *mRefName;\r
+  EFI_STRING_ID             mDefaultStoreNameId;\r
+  UINT16                    mDefaultId;\r
+\r
+  SVfrDefaultStoreNode      *mNext;\r
+\r
+  SVfrDefaultStoreNode (IN EFI_IFR_DEFAULTSTORE *, IN INT8 *, IN EFI_STRING_ID, IN UINT16);\r
+  ~SVfrDefaultStoreNode();\r
+};\r
+\r
+class CVfrDefaultStore {\r
+private:\r
+  SVfrDefaultStoreNode      *mDefaultStoreList;\r
+\r
+public:\r
+  CVfrDefaultStore ();\r
+  ~CVfrDefaultStore ();\r
+\r
+  EFI_VFR_RETURN_CODE RegisterDefaultStore (IN CHAR8 *, IN INT8 *, IN EFI_STRING_ID, IN UINT16);\r
+  EFI_VFR_RETURN_CODE ReRegisterDefaultStoreById (IN UINT16, IN INT8 *, IN EFI_STRING_ID);\r
+  BOOLEAN             DefaultIdRegistered (IN UINT16);\r
+  EFI_VFR_RETURN_CODE GetDefaultId (IN INT8 *, OUT UINT16 *);\r
+  EFI_VFR_RETURN_CODE BufferVarStoreAltConfigAdd (IN EFI_VARSTORE_ID, IN EFI_VARSTORE_INFO &, IN INT8 *, IN UINT8, IN EFI_IFR_TYPE_VALUE);\r
+};\r
+\r
+#define EFI_RULE_ID_START    0x01\r
+#define EFI_RULE_ID_INVALID  0x00\r
+\r
+struct SVfrRuleNode {\r
+  UINT8                     mRuleId;\r
+  INT8                      *mRuleName;\r
+  SVfrRuleNode              *mNext;\r
+\r
+  SVfrRuleNode(IN INT8 *, IN UINT8);\r
+  ~SVfrRuleNode();\r
+};\r
+\r
+class CVfrRulesDB {\r
+private:\r
+  SVfrRuleNode              *mRuleList;\r
+  UINT8                     mFreeRuleId;\r
+\r
+public:\r
+  CVfrRulesDB ();\r
+  ~CVfrRulesDB();\r
+\r
+  VOID RegisterRule (IN INT8 *);\r
+  UINT8 GetRuleId (IN INT8 *);\r
+};\r
+\r
+#define MIN(v1, v2) (((v1) < (v2)) ? (v1) : (v2))\r
+#define MAX(v1, v2) (((v1) > (v2)) ? (v1) : (v2))\r
+\r
+#endif\r
diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/makefile b/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/makefile
new file mode 100644 (file)
index 0000000..61fd9e4
--- /dev/null
@@ -0,0 +1,149 @@
+#/*++\r
+#  \r
+#  Copyright (c) 2004 - 2007, Intel Corporation                                                         \r
+#  All rights reserved. This program and the accompanying materials                          \r
+#  are licensed and made available under the terms and conditions of the BSD License         \r
+#  which accompanies this distribution.  The full text of the license may be found at        \r
+#  http://opensource.org/licenses/bsd-license.php                                            \r
+#                                                                                            \r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+#  \r
+#  Module Name:\r
+#  \r
+#    makefile\r
+#  \r
+#  Abstract:\r
+#  \r
+#    Makefile for building the EFI VFR compiler\r
+#    \r
+#--*/  \r
+\r
+\r
+!IFNDEF EDK_SOURCE\r
+!ERROR EDK_SOURCE environmental variable not set \r
+!ENDIF\r
+\r
+!IFNDEF TOOLCHAIN\r
+TOOLCHAIN = TOOLCHAIN_MSVC\r
+!ENDIF\r
+\r
+!INCLUDE $(BUILD_DIR)\PlatformTools.env\r
+\r
+.SUFFIXES :\r
+\r
+TARGET_NAME        = VfrCompile\r
+\r
+ETO                = $(EDK_TOOLS_OUTPUT)\r
+SRC                = $(EDK_TOOLS_SOURCE)\Uefi$(TARGET_NAME)\r
+TARGET_EXE         = $(ETO)\$(TARGET_NAME).exe\r
+\r
+\r
+\r
+INC                = -I $(SRC) \\r
+                     -I $(EDK_SOURCE)\Foundation\Include\Ia32 \\r
+                     -I $(EDK_SOURCE)\Foundation\Efi\Include \\r
+                     -I $(EDK_SOURCE)\Foundation\Framework\Include \\r
+                     -I $(EDK_SOURCE)\Foundation\Include\IndustryStandard \\r
+                     -I $(EDK_SOURCE)\Foundation\         \\r
+                     -I $(EDK_SOURCE)\Foundation\Core\Dxe \\r
+                     -I $(EDK_SOURCE)\Foundation\Efi      \\r
+                     -I $(EDK_SOURCE)\Foundation\Framework \\r
+                     -I $(EDK_TOOLS_SOURCE)\Common \\r
+                     -I $(EDK_SOURCE)\Foundation\Include\r
+\r
+ANTLR_FLAGS        = -CC -e3 -ck 3 -k 2\r
+DLG_FLAGS          = -C2 -i -CC\r
+LINK_FLAGS_PCCTS   = /DEBUG  /PDB:$*.pdb\r
+C_FLAGS_PCCTS      = -I. -I$(ANTLR_H) /WX /Od /EHsc /Zi /Fd$(ETO)\$(TARGET_NAME)Obj /D _CRT_SECURE_NO_DEPRECATE $(VERSION_FLAGS) /D PCCTS_USE_NAMESPACE_STD #/D CVFR_VARDATATYPEDB_DEBUG /D CIFROBJ_DEUBG /D VFREXP_DEBUG\r
+\r
+VFR_GRAMMER_FILE   = $(SRC)\VfrSyntax.g\r
+\r
+VFR_ANTLR_SPAWN    = $(ETO)\VfrSyntax.cpp \\r
+                     $(ETO)\EfiVfrParser.cpp \\r
+                     $(ETO)\EfiVfrParser.h \\r
+                     $(ETO)\VfrParser.dlg \\r
+                     $(ETO)\VfrTokens.h\r
+\r
+VFR_DLG_SPAWN      = $(ETO)\VfrLexer.cpp \\r
+                     $(ETO)\VfrLexer.h\r
+\r
+ANTLR_H            = $(PCCTS_DIR)\h\r
+\r
+HEADER_FILES       = $(SRC)\VfrFormPkg.h \\r
+                     $(SRC)\EfiVfr.h \\r
+                     $(SRC)\VfrCompiler.h \\r
+                     $(SRC)\VfrError.h \\r
+                     $(SRC)\VfrUtilityLib.h\r
+\r
+OBJECTS            = $(ETO)\AParser.obj \\r
+                     $(ETO)\DLexerBase.obj \\r
+                     $(ETO)\ATokenBuffer.obj \\r
+                     $(ETO)\VfrSyntax.obj \\r
+                     $(ETO)\EfiVfrParser.obj \\r
+                     $(ETO)\VfrLexer.obj  \\r
+                     $(ETO)\VfrFormPkg.obj \\r
+                     $(ETO)\VfrError.obj \\r
+                     $(ETO)\VfrUtilityLib.obj \\r
+                     $(ETO)\VfrCompiler.obj\r
+\r
+all : $(TARGET_EXE)\r
+\r
+$(VFR_ANTLR_SPAWN) : $(VFR_GRAMMER_FILE)\r
+    $(ANTLR) $(ANTLR_FLAGS) -fl VfrParser.dlg -ft VfrTokens.h -o $(ETO) $(VFR_GRAMMER_FILE)\r
+\r
+$(VFR_DLG_SPAWN) : $(ETO)\VfrParser.dlg\r
+    $(DLG) $(DLG_FLAGS) -cl VfrLexer -o $(ETO) $(ETO)\VfrParser.dlg\r
+\r
+$(ETO)\VfrSyntax.obj : $(ETO)\VfrSyntax.cpp $(VFR_DLG_SPAWN)\r
+    $(CC) -c $(C_FLAGS_PCCTS) /Fo$@ $(INC) $(ETO)\VfrSyntax.cpp\r
+\r
+$(ETO)\EfiVfrParser.obj : $(ETO)\EfiVfrParser.cpp $(ETO)\EfiVfrParser.h $(VFR_DLG_SPAWN)\r
+    $(CC) -c $(C_FLAGS_PCCTS) /Fo$@ $(INC) $(ETO)\EfiVfrParser.cpp\r
+\r
+\r
+$(ETO)\AParser.obj : $(ANTLR_H)\AParser.cpp\r
+    $(CC) -c $(C_FLAGS_PCCTS) /Fo$@ $(ANTLR_H)\AParser.cpp\r
+\r
+$(ETO)\ATokenBuffer.obj : $(ANTLR_H)\ATokenBuffer.cpp\r
+    $(CC) -c $(C_FLAGS_PCCTS) /Fo$@ $(ANTLR_H)\ATokenBuffer.cpp\r
+\r
+$(ETO)\DLexerBase.obj : $(ANTLR_H)\DLexerBase.cpp\r
+    $(CC) -c $(C_FLAGS_PCCTS) /Fo$@ $(ANTLR_H)\DLexerBase.cpp\r
+\r
+$(ETO)\VfrLexer.obj : $(ETO)\VfrLexer.cpp $(VFR_DLG_SPAWN)\r
+    $(CC) -c $(C_FLAGS_PCCTS) /Fo$@ $(INC) $(ETO)\VfrLexer.cpp\r
+\r
+$(ETO)\VfrFormPkg.obj : $(SRC)\VfrFormPkg.cpp $(HEADER_FILES)\r
+    $(CC) -c $(C_FLAGS_PCCTS) $(INC) /Fo$@ $(SRC)\VfrFormPkg.cpp\r
+\r
+$(ETO)\VfrError.obj : $(SRC)\VfrError.cpp $(HEADER_FILES)\r
+    $(CC) -c $(C_FLAGS_PCCTS) $(INC) /Fo$@ $(SRC)\VfrError.cpp\r
+\r
+$(ETO)\VfrUtilityLib.obj : $(SRC)\VfrUtilityLib.cpp $(HEADER_FILES)\r
+    $(CC) -c $(C_FLAGS_PCCTS) $(INC) /Fo$@ $(SRC)\VfrUtilityLib.cpp\r
+\r
+$(ETO)\VfrCompiler.obj : $(SRC)\VfrCompiler.cpp $(HEADER_FILES)\r
+    $(CC) -c $(C_FLAGS_PCCTS) $(INC) /Fo$@ $(SRC)\VfrCompiler.cpp\r
+\r
+#\r
+# Add Binary Build description for this tools.\r
+#\r
+\r
+!IF (("$(EFI_BINARY_TOOLS)" == "YES") && EXIST($(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe))\r
+$(TARGET_EXE): $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe\r
+  copy $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe $(TARGET_EXE) /Y\r
+  if exist $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb \\r
+  copy $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb /Y\r
+!ELSE\r
+$(TARGET_EXE) : $(OBJECTS) $(HEADER_FILES)\r
+  $(LINK) $(MSVS_LINK_LIBPATHS) $(LINK_FLAGS_PCCTS) /OUT:$(TARGET_EXE) $(OBJECTS)\r
+!IF ("$(EFI_BINARY_BUILD)" == "YES")\r
+  if not exist $(EFI_PLATFORM_BIN)\Tools mkdir $(EFI_PLATFORM_BIN)\Tools\r
+  if exist $(TARGET_EXE) copy $(TARGET_EXE) $(EFI_PLATFORM_BIN)\tools\$(TARGET_NAME).exe /Y\r
+  if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb \\r
+  copy $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb /Y\r
+!ENDIF\r
+!ENDIF\r
+\r
+clean:\r
index d0a680c978d345c1f8ecdf7f4493d7db60f93293..45d6690869438b7141cdaa409f0f41355e9aa93b 100644 (file)
@@ -82,11 +82,13 @@ $(TARGET_EXE): $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe
 !ELSE\r
 $(TARGET_EXE) : $(OBJECTS)\r
   $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(OBJECTS)\r
+!IF ("$(EFI_BINARY_BUILD)" == "YES")\r
   if not exist $(EFI_PLATFORM_BIN)\Tools mkdir $(EFI_PLATFORM_BIN)\Tools\r
   if exist $(TARGET_EXE) copy $(TARGET_EXE) $(EFI_PLATFORM_BIN)\tools\$(TARGET_NAME).exe /Y\r
   if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb \\r
   copy $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb /Y\r
 !ENDIF\r
+!ENDIF\r
 \r
 clean:\r
   @if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL\r
index d703b02f315d4a06b5f668e7de67450e0af9445d..f0b7db9fa0b80af5e8dbbbaab935687942094e94 100644 (file)
@@ -162,11 +162,13 @@ $(TARGET_EXE): $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe
 !ELSE\r
 $(TARGET_EXE) : $(OBJECTS) $(LIBS)\r
        $(LINK) $(MSVS_LINK_LIBPATHS) $(LIBS) /DEBUG /OUT:$(TARGET_EXE) $(LINK_FLAGS_PCCTS) $(OBJECTS) /PDB:$*.pdb\r
+!IF ("$(EFI_BINARY_BUILD)" == "YES")\r
   if not exist $(EFI_PLATFORM_BIN)\Tools mkdir $(EFI_PLATFORM_BIN)\Tools\r
   if exist $(TARGET_EXE) copy $(TARGET_EXE) $(EFI_PLATFORM_BIN)\tools\$(TARGET_NAME).exe /Y\r
   if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb \\r
   copy $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb /Y\r
 !ENDIF\r
+!ENDIF\r
 \r
 clean:\r
   \r