From 95d675b5272d76105e2109a11d8b35f416be8b29 Mon Sep 17 00:00:00 2001 From: qwang12 Date: Thu, 24 Jan 2008 07:29:31 +0000 Subject: [PATCH] 1) Sync EdkCompatibilityPkg with EDK 1.04. The changes includes: 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 --- .../Sample/Include/EfiCompNameSupport.h | 58 - .../Sample/Platform/Common.dsc | 301 +- .../Sample/Platform/CommonIa32.dsc | 43 +- .../Sample/Platform/CommonIpf.dsc | 26 +- .../Sample/Platform/CommonX64.dsc | 43 +- .../Sample/Platform/EdkIIGlueLib32.dsc | 1 + .../Sample/Platform/EdkIIGlueLibAll.dsc | 4 +- .../Sample/Platform/EdkLib32.dsc | 3 +- .../Sample/Platform/EdkLibAll.dsc | 9 +- .../MonoStatusCode/Pei/MonoStatusCode.h | 138 + .../BsDataHubStatusCode/BsDataHubStatusCode.c | 374 +- .../BsDataHubStatusCode/BsDataHubStatusCode.h | 67 +- .../BsSerialStatusCode/BsSerialStatusCode.c | 6 +- .../Lib/Include/BsDataHubStatusCodeLib.h | 4 +- .../Lib/Include/BsSerialStatusCodeLib.h | 4 +- .../Lib/Include/RtMemoryStatusCodeLib.h | 7 +- .../Lib/Include/RtPlatformStatusCodeLib.h | 4 +- .../Lib/Include/RtPort80StatusCodeLib.h | 3 +- .../Platform/Nt32/Ppi/EdkNt32PpiLib.inf | 53 + .../Platform/Nt32/Ppi/NtAutoscan/NtAutoscan.c | 29 + .../Platform/Nt32/Ppi/NtAutoscan/NtAutoscan.h | 67 + .../Sample/Platform/Nt32/Ppi/NtFwh/NtFwh.c | 29 + .../Sample/Platform/Nt32/Ppi/NtFwh/NtFwh.h | 63 + .../Nt32/Ppi/NtLoadAsDll/NtLoadAsDll.c | 28 + .../Nt32/Ppi/NtLoadAsDll/NtLoadAsDll.h | 84 + .../Nt32/Ppi/NtPeiLoadFile/NtPeiLoadFile.c | 29 + .../Nt32/Ppi/NtPeiLoadFile/NtPeiLoadFile.h | 66 + .../Platform/Nt32/Ppi/NtThunk/NtThunk.c | 29 + .../Platform/Nt32/Ppi/NtThunk/NtThunk.h | 59 + .../Source/BootsectImage/bootsectimage.c | 881 ----- .../Sample/Tools/Source/BootsectImage/fat.h | 158 - .../Sample/Tools/Source/BootsectImage/mbr.h | 64 - .../Sample/Tools/Source/Common/FvLib.c | 120 +- .../Sample/Tools/Source/Common/Makefile | 4 +- .../Tools/Source/CustomizedCompress/makefile | 2 + .../Sample/Tools/Source/EfiCompress/makefile | 2 + .../Sample/Tools/Source/EfiRom/EfiRom.c | 228 +- .../Sample/Tools/Source/EfiRom/Makefile | 2 + .../Tools/Source/EfildrImage/efildrimage.c | 188 - .../Sample/Tools/Source/FwImage/Makefile | 2 + .../Tools/Source/GenAprioriFile/Makefile | 2 + .../Source/GenBootsector/GetDrvNumOffset.c | 58 - .../Sample/Tools/Source/GenBootsector/fat.h | 158 - .../Source/GenBootsector/genbootsector.c | 652 ---- .../Tools/Source/GenBootsector/makefile | 99 - .../Tools/Source/GenCRC32Section/makefile | 2 + .../Sample/Tools/Source/GenDepex/GenDepex.c | 12 +- .../Sample/Tools/Source/GenDepex/makefile | 2 + .../Tools/Source/GenFfsFile/GenFfsFile.c | 541 ++- .../Sample/Tools/Source/GenFfsFile/makefile | 2 + .../Tools/Source/GenFvImage/GenFvImageLib.h | 2 +- .../Sample/Tools/Source/GenFvImage/Makefile | 2 + .../Tools/Source/GenPage/VirtualMemory.h | 127 - .../Sample/Tools/Source/GenPage/genpage.c | 344 -- .../Sample/Tools/Source/GenSection/makefile | 2 + .../Tools/Source/GenTEImage/GenTEImage.c | 929 +++++ .../Source/{GenPage => GenTEImage}/Makefile | 68 +- .../Sample/Tools/Source/GuidChk/Makefile | 2 + .../Sample/Tools/Source/MakeDeps/MakeDeps.c | 422 ++- .../Sample/Tools/Source/MakeDeps/Makefile | 2 + .../Sample/Tools/Source/Makefile | 20 +- .../Sample/Tools/Source/ModifyInf/Makefile | 2 + .../Sample/Tools/Source/ProcessDsc/Makefile | 2 + .../Tools/Source/ProcessDsc/ProcessDsc.c | 57 +- .../Sample/Tools/Source/SetStamp/Makefile | 2 + .../Sample/Tools/Source/SplitFile/Makefile | 2 + .../Sample/Tools/Source/StrGather/Makefile | 2 + .../Source/{EfildrImage => Strip}/Makefile | 32 +- .../Sample/Tools/Source/Strip/strip.c | 104 + .../{BootsectImage => UefiStrGather}/Makefile | 64 +- .../Tools/Source/UefiStrGather/StrGather.c | 2829 +++++++++++++++ .../Tools/Source/UefiStrGather/StrGather.h | 87 + .../Tools/Source/UefiStrGather/StringDB.c | 2674 ++++++++++++++ .../Tools/Source/UefiStrGather/StringDB.h | 254 ++ .../Tools/Source/UefiVfrCompile/EfiVfr.h | 53 + .../Source/UefiVfrCompile/VfrCompiler.cpp | 594 +++ .../Tools/Source/UefiVfrCompile/VfrCompiler.h | 90 + .../Tools/Source/UefiVfrCompile/VfrError.cpp | 197 + .../Tools/Source/UefiVfrCompile/VfrError.h | 67 + .../Source/UefiVfrCompile/VfrFormPkg.cpp | 830 +++++ .../Tools/Source/UefiVfrCompile/VfrFormPkg.h | 2252 ++++++++++++ .../Tools/Source/UefiVfrCompile/VfrSyntax.g | 3201 +++++++++++++++++ .../Source/UefiVfrCompile/VfrUtilityLib.cpp | 2695 ++++++++++++++ .../Source/UefiVfrCompile/VfrUtilityLib.h | 341 ++ .../Tools/Source/UefiVfrCompile/makefile | 149 + .../Sample/Tools/Source/VcCheck/makefile | 2 + .../Sample/Tools/Source/VfrCompile/makefile | 2 + 87 files changed, 19727 insertions(+), 3587 deletions(-) delete mode 100644 EdkCompatibilityPkg/Sample/Include/EfiCompNameSupport.h create mode 100644 EdkCompatibilityPkg/Sample/Platform/Generic/MonoStatusCode/Pei/MonoStatusCode.h create mode 100644 EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/EdkNt32PpiLib.inf create mode 100644 EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtAutoscan/NtAutoscan.c create mode 100644 EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtAutoscan/NtAutoscan.h create mode 100644 EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtFwh/NtFwh.c create mode 100644 EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtFwh/NtFwh.h create mode 100644 EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtLoadAsDll/NtLoadAsDll.c create mode 100644 EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtLoadAsDll/NtLoadAsDll.h create mode 100644 EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtPeiLoadFile/NtPeiLoadFile.c create mode 100644 EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtPeiLoadFile/NtPeiLoadFile.h create mode 100644 EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtThunk/NtThunk.c create mode 100644 EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtThunk/NtThunk.h delete mode 100644 EdkCompatibilityPkg/Sample/Tools/Source/BootsectImage/bootsectimage.c delete mode 100644 EdkCompatibilityPkg/Sample/Tools/Source/BootsectImage/fat.h delete mode 100644 EdkCompatibilityPkg/Sample/Tools/Source/BootsectImage/mbr.h delete mode 100644 EdkCompatibilityPkg/Sample/Tools/Source/EfildrImage/efildrimage.c delete mode 100644 EdkCompatibilityPkg/Sample/Tools/Source/GenBootsector/GetDrvNumOffset.c delete mode 100644 EdkCompatibilityPkg/Sample/Tools/Source/GenBootsector/fat.h delete mode 100644 EdkCompatibilityPkg/Sample/Tools/Source/GenBootsector/genbootsector.c delete mode 100644 EdkCompatibilityPkg/Sample/Tools/Source/GenBootsector/makefile delete mode 100644 EdkCompatibilityPkg/Sample/Tools/Source/GenPage/VirtualMemory.h delete mode 100644 EdkCompatibilityPkg/Sample/Tools/Source/GenPage/genpage.c create mode 100644 EdkCompatibilityPkg/Sample/Tools/Source/GenTEImage/GenTEImage.c rename EdkCompatibilityPkg/Sample/Tools/Source/{GenPage => GenTEImage}/Makefile (61%) rename EdkCompatibilityPkg/Sample/Tools/Source/{EfildrImage => Strip}/Makefile (80%) create mode 100644 EdkCompatibilityPkg/Sample/Tools/Source/Strip/strip.c rename EdkCompatibilityPkg/Sample/Tools/Source/{BootsectImage => UefiStrGather}/Makefile (53%) create mode 100644 EdkCompatibilityPkg/Sample/Tools/Source/UefiStrGather/StrGather.c create mode 100644 EdkCompatibilityPkg/Sample/Tools/Source/UefiStrGather/StrGather.h create mode 100644 EdkCompatibilityPkg/Sample/Tools/Source/UefiStrGather/StringDB.c create mode 100644 EdkCompatibilityPkg/Sample/Tools/Source/UefiStrGather/StringDB.h create mode 100644 EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/EfiVfr.h create mode 100644 EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrCompiler.cpp create mode 100644 EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrCompiler.h create mode 100644 EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrError.cpp create mode 100644 EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrError.h create mode 100644 EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrFormPkg.cpp create mode 100644 EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrFormPkg.h create mode 100644 EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrSyntax.g create mode 100644 EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrUtilityLib.cpp create mode 100644 EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrUtilityLib.h create mode 100644 EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/makefile diff --git a/EdkCompatibilityPkg/Sample/Include/EfiCompNameSupport.h b/EdkCompatibilityPkg/Sample/Include/EfiCompNameSupport.h deleted file mode 100644 index 7159588ee1..0000000000 --- a/EdkCompatibilityPkg/Sample/Include/EfiCompNameSupport.h +++ /dev/null @@ -1,58 +0,0 @@ -/*++ - -Copyright (c) 2004, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - EfiCompNameSupport.h - -Abstract: - - Private data structures for the Console Splitter driver - ---*/ - -#ifndef EFI_COMPONENT_NAME_SUPPORT_H -#define EFI_COMPONENT_NAME_SUPPORT_H - -#include "Tiano.h" - -#ifndef EFI_SIZE_REDUCTION_APPLIED - -#define INSTALL_ALL_DRIVER_PROTOCOLS(ImageHandle, \ - SystemTable, \ - DriverBinding, \ - DriverBindingHandle, \ - ComponentName, \ - DriverConfiguration, \ - DriverDiagnostics) \ - EfiLibInstallAllDriverProtocols ((ImageHandle), \ - (SystemTable), \ - (DriverBinding), \ - (DriverBindingHandle), \ - (ComponentName), \ - (DriverConfiguration), \ - (DriverDiagnostics)) -#else - -#define INSTALL_ALL_DRIVER_PROTOCOLS(ImageHandle, \ - SystemTable, \ - DriverBinding, \ - DriverBindingHandle, \ - ComponentName, \ - DriverConfiguration, \ - DriverDiagnostics) \ - EfiLibInstallDriverBinding ((ImageHandle), \ - (SystemTable), \ - (DriverBinding), \ - (DriverBindingHandle)) -#endif - -#endif diff --git a/EdkCompatibilityPkg/Sample/Platform/Common.dsc b/EdkCompatibilityPkg/Sample/Platform/Common.dsc index c40c4e7de8..85740c2033 100644 --- a/EdkCompatibilityPkg/Sample/Platform/Common.dsc +++ b/EdkCompatibilityPkg/Sample/Platform/Common.dsc @@ -87,10 +87,15 @@ DEPEX_TYPE = EFI_SECTION_PEI_DEPEX DEPEX_TYPE = EFI_SECTION_DXE_DEPEX !ENDIF +!IF "$(COMPONENT_TYPE)" != "LIBRARY" && EXIST($(BUILD_DIR)\$(PROCESSOR)\CompilerStub.lib) +LIBS = $(LIBS) $(BUILD_DIR)\$(PROCESSOR)\CompilerStub.lib +!ENDIF + # # Command flags for MAKEDEPS tool # DEP_FLAGS = -target $** -o $(DEP_FILE) $(INC) -ignorenotfound -q +DEP_FLAGS2 = -target $@ -o $(DEP_FILE) -cl [=============================================================================] # @@ -112,8 +117,15 @@ DEP_FLAGS = -target $** -o $(DEP_FILE) $(INC) -ignorenotfound -q [=============================================================================] [Compile.Ia32.asm,Compile.x64.asm] +# +# Add build dependency check +# DEP_FILE = $(DEST_DIR)\$(FILE)Asm.dep +!IF EXIST($(DEP_FILE)) +!INCLUDE $(DEP_FILE) +!ENDIF + !IF EXIST($(DEST_DIR)\$(FILE).obj) DEP_TARGETS = $(DEP_TARGETS) $(DEST_DIR)\$(FILE)Asm.dep !IF !EXIST($(DEP_FILE)) @@ -121,10 +133,6 @@ CREATEDEPS = YES !ENDIF !ENDIF -!IF EXIST($(DEP_FILE)) -!INCLUDE $(DEP_FILE) -!ENDIF - # # Update dep file for next round incremental build # @@ -140,39 +148,58 @@ $(DEST_DIR)\$(FILE).obj : $(SOURCE_FILE_NAME) $(INF_FILENAME) $(ALL_DEPS) [=============================================================================] [Compile.Ipf.s] +# +# Add build dependency check +# DEP_FILE = $(DEST_DIR)\$(FILE)S.dep -!IF EXIST($(DEST_DIR)\$(FILE).pro) +!IF EXIST($(DEP_FILE)) +!INCLUDE $(DEP_FILE) +!ENDIF + +!IF "$(EFI_USE_CL_FOR_DEP)" != "YES" + +!IF EXIST($(DEST_DIR)\$(FILE).obj) DEP_TARGETS = $(DEP_TARGETS) $(DEST_DIR)\$(FILE)S.dep !IF !EXIST($(DEP_FILE)) CREATEDEPS = YES !ENDIF !ENDIF -!IF EXIST($(DEP_FILE)) -!INCLUDE $(DEP_FILE) -!ENDIF - # # Update dep file for next round incremental build # -$(DEP_FILE) : $(DEST_DIR)\$(FILE).pro +$(DEP_FILE) : $(DEST_DIR)\$(FILE).obj $(MAKEDEPS) -f $(SOURCE_FILE_NAME) $(DEP_FLAGS) +!ENDIF + # # Compile the file # -$(DEST_DIR)\$(FILE).pro : $(SOURCE_FILE_NAME) $(INF_FILENAME) $(ALL_DEPS) - $(CC) $(C_FLAGS_PRO) $(SOURCE_FILE_NAME) > $@ - -$(DEST_DIR)\$(FILE).obj : $(DEST_DIR)\$(FILE).pro +$(DEST_DIR)\$(FILE).obj : $(SOURCE_FILE_NAME) $(INF_FILENAME) $(ALL_DEPS) +!IF "$(EFI_USE_CL_FOR_DEP)" != "YES" + $(CC) $(C_FLAGS_PRO) $(SOURCE_FILE_NAME) > $(DEST_DIR)\$(FILE).pro +!ELSE + -$(CC) $(C_FLAGS_PRO) $(SOURCE_FILE_NAME) /showIncludes > $(DEST_DIR)\$(FILE).pro 2> $(DEST_DIR)\$(FILE)S.cl + @$(MAKEDEPS) -f $(DEST_DIR)\$(FILE)S.cl $(DEP_FLAGS2) +!ENDIF $(ASM) $(ASM_FLAGS) $(DEST_DIR)\$(FILE).pro [=============================================================================] [Compile.Ia32.c,Compile.Ipf.c,Compile.x64.c] +# +# Add build dependency check +# DEP_FILE = $(DEST_DIR)\$(FILE).dep +!IF EXIST($(DEP_FILE)) +!INCLUDE $(DEP_FILE) +!ENDIF + +!IF "$(EFI_USE_CL_FOR_DEP)" != "YES" + !IF EXIST($(DEST_DIR)\$(FILE).obj) DEP_TARGETS = $(DEP_TARGETS) $(DEST_DIR)\$(FILE).dep !IF !EXIST($(DEP_FILE)) @@ -180,27 +207,37 @@ CREATEDEPS = YES !ENDIF !ENDIF -!IF EXIST($(DEP_FILE)) -!INCLUDE $(DEP_FILE) -!ENDIF - # # Update dep file for next round incremental build # $(DEP_FILE) : $(DEST_DIR)\$(FILE).obj $(MAKEDEPS) -f $(SOURCE_FILE_NAME) $(DEP_FLAGS) +!ENDIF + # # Compile the file # $(DEST_DIR)\$(FILE).obj : $(SOURCE_FILE_NAME) $(INF_FILENAME) $(ALL_DEPS) +!IF "$(EFI_USE_CL_FOR_DEP)" != "YES" $(CC) $(C_FLAGS) $(SOURCE_FILE_NAME) +!ELSE + -$(CC) $(C_FLAGS) $(SOURCE_FILE_NAME) /showIncludes > $(DEST_DIR)\$(FILE).cl + @$(MAKEDEPS) -f $(DEST_DIR)\$(FILE).cl $(DEP_FLAGS2) +!ENDIF [=============================================================================] [Compile.Ebc.c] +# +# Add build dependency check +# DEP_FILE = $(DEST_DIR)\$(FILE).dep +!IF EXIST($(DEP_FILE)) +!INCLUDE $(DEP_FILE) +!ENDIF + !IF EXIST($(DEST_DIR)\$(FILE).obj) DEP_TARGETS = $(DEP_TARGETS) $(DEST_DIR)\$(FILE).dep !IF !EXIST($(DEP_FILE)) @@ -208,10 +245,6 @@ CREATEDEPS = YES !ENDIF !ENDIF -!IF EXIST($(DEP_FILE)) -!INCLUDE $(DEP_FILE) -!ENDIF - # # Update dep file for next round incremental build # @@ -351,8 +384,32 @@ clean : # LIB_NAME = $(LIB_DIR)\$(BASE_NAME).lib +# +# $(DEP_TARGETS) are not needed for binary build. +# +!IF ("$(BINARY)" == "TRUE") || (("$(BINARY)" == "") && ("$(EFI_BINARY_LIBRARY)" == "YES")) +DEP_TARGETS= +CREATEDEPS= +!ENDIF + +# +# Module can be built from source code or binary files. +# +!IF ((("$(BINARY)" == "TRUE") || (("$(BINARY)" == "") && ("$(EFI_BINARY_LIBRARY)" == "YES"))) \ + && EXIST($(EFI_PLATFORM_BIN)\$(PROCESSOR)\$(BASE_NAME).lib)) +$(LIB_NAME) : $(EFI_PLATFORM_BIN)\$(PROCESSOR)\$(BASE_NAME).lib + copy $(EFI_PLATFORM_BIN)\$(PROCESSOR)\$(BASE_NAME).lib $(LIB_NAME) /Y + if exist $(EFI_PLATFORM_BIN)\$(PROCESSOR)\$(BASE_NAME)Obj.pdb \ + copy $(EFI_PLATFORM_BIN)\$(PROCESSOR)\$(BASE_NAME)Obj.pdb $(DEST_DIR)\$(BASE_NAME)Obj.pdb /Y +!ELSE $(LIB_NAME) : $(OBJECTS) $(LIBS) $(INF_FILENAME) $(ENV_DEPS) $(LIB) $(LIB_FLAGS) $(OBJECTS) $(LIBS) /OUT:$@ +!IF ("$(EFI_BINARY_BUILD)" == "YES") + if not exist $(EFI_PLATFORM_BIN)\$(PROCESSOR) mkdir $(EFI_PLATFORM_BIN)\$(PROCESSOR) + if exist $(LIB_NAME) copy $(LIB_NAME) $(EFI_PLATFORM_BIN)\$(PROCESSOR)\$(BASE_NAME).lib /Y + if exist $(DEST_DIR)\$(BASE_NAME)Obj.pdb copy $(DEST_DIR)\$(BASE_NAME)Obj.pdb $(EFI_PLATFORM_BIN)\$(PROCESSOR)\$(BASE_NAME)Obj.pdb /Y +!ENDIF +!ENDIF !IF "$(CREATEDEPS)"=="YES" all : $(DEP_TARGETS) @@ -558,10 +615,31 @@ $(TARGET_PE32) : $(TARGET_EFI) $(GENSECTION) -I $(TARGET_EFI) -O $(TARGET_PE32) -S EFI_SECTION_PE32 # -# Run FWImage on the DLL to set it as an EFI image type. +# $(DEP_TARGETS) are not needed for binary build. +# +!IF "$(BINARY)" == "TRUE" +DEP_TARGETS= +CREATEDEPS= +!ENDIF + +# +# Build module to generate *.efi file from source code or binary file. # +!IF (("$(BINARY)" == "TRUE") && EXIST($(EFI_PLATFORM_BIN)\$(PROCESSOR)\$(BASE_NAME).efi)) +LOCALIZE_TARGETS= +$(TARGET_EFI) : $(EFI_PLATFORM_BIN)\$(PROCESSOR)\$(BASE_NAME).efi + copy $(EFI_PLATFORM_BIN)\$(PROCESSOR)\$(BASE_NAME).efi $(TARGET_EFI) /Y + if exist $(EFI_PLATFORM_BIN)\$(PROCESSOR)\$(BASE_NAME).pdb \ + copy $(EFI_PLATFORM_BIN)\$(PROCESSOR)\$(BASE_NAME).pdb $(TARGET_PDB) /Y +!ELSE $(TARGET_EFI) : $(TARGET_DLL) $(INF_FILENAME) $(FWIMAGE) -t 0 $(COMPONENT_TYPE) $(TARGET_DLL) $(TARGET_EFI) +!IF ("$(EFI_BINARY_BUILD)" == "YES") + if not exist $(EFI_PLATFORM_BIN)\$(PROCESSOR) mkdir $(EFI_PLATFORM_BIN)\$(PROCESSOR) + if exist $(TARGET_EFI) copy $(TARGET_EFI) $(EFI_PLATFORM_BIN)\$(PROCESSOR)\$(BASE_NAME).efi /Y + if exist $(TARGET_PDB) copy $(TARGET_PDB) $(EFI_PLATFORM_BIN)\$(PROCESSOR)\$(BASE_NAME).pdb /Y +!ENDIF +!ENDIF !ENDIF @@ -621,12 +699,18 @@ DPX_SOURCE_FILE = $(DPX_SOURCE_OVERRIDE) !IF "$(DPX_SOURCE_FILE)" != "" !IF EXIST ($(DPX_SOURCE_FILE)) + # -# Add dependency check for dxs file, because dxs file depends on PPI or -# PROTOCOL guid defintions. +# Add build dependency check # DEP_FILE = $(DEST_DIR)\$(BASE_NAME)dxs.dep +!IF EXIST($(DEP_FILE)) +!INCLUDE $(DEP_FILE) +!ENDIF + +!IF "$(EFI_USE_CL_FOR_DEP)" != "YES" + !IF EXIST($(TARGET_DPX)) DEP_TARGETS = $(DEP_TARGETS) $(DEST_DIR)\$(BASE_NAME)dxs.dep !IF !EXIST($(DEP_FILE)) @@ -634,17 +718,21 @@ CREATEDEPS = YES !ENDIF !ENDIF -!IF EXIST($(DEP_FILE)) -!INCLUDE $(DEP_FILE) -!ENDIF # # Update dep file for next round incremental build # $(DEP_FILE) : $(TARGET_DPX) $(MAKEDEPS) -f $(DPX_SOURCE_FILE) $(DEP_FLAGS) +!ENDIF + $(TARGET_DPX) : $(DPX_SOURCE_FILE) $(INF_FILENAME) - $(CC) /nologo $(INC) $(VERSION_FLAGS) /EP $(DPX_SOURCE_FILE) > $*.tmp1 +!IF "$(EFI_USE_CL_FOR_DEP)" != "YES" + $(CC) $(C_FLAGS_DPX) $(DPX_SOURCE_FILE) > $*.tmp1 +!ELSE + -$(CC) $(C_FLAGS_DPX) $(DPX_SOURCE_FILE) /showIncludes > $*.tmp1 2> $(DEST_DIR)\$(BASE_NAME)dxs.cl + @$(MAKEDEPS) -f $(DEST_DIR)\$(BASE_NAME)dxs.cl $(DEP_FLAGS2) +!ENDIF $(GENDEPEX) -I $*.tmp1 -O $*.tmp2 $(GENSECTION) -I $*.tmp2 -O $@ -S $(DEPEX_TYPE) del $*.tmp1 > NUL @@ -666,8 +754,40 @@ $(TARGET_DPX) : !IF "$(COMPONENT_TYPE)" == "COMBINED_PEIM_DRIVER" !IF "$(DXE_DPX_SOURCE)" != "" !IF EXIST ($(SOURCE_DIR)\$(DXE_DPX_SOURCE)) + +# +# Add build dependency check +# +DEP_FILE = $(DEST_DIR)\$(BASE_NAME)dxs2.dep + +!IF EXIST($(DEP_FILE)) +!INCLUDE $(DEP_FILE) +!ENDIF + +!IF "$(EFI_USE_CL_FOR_DEP)" != "YES" + +!IF EXIST($(TARGET_DXE_DPX)) +DEP_TARGETS = $(DEP_TARGETS) $(DEST_DIR)\$(BASE_NAME)dxs2.dep +!IF !EXIST($(DEP_FILE)) +CREATEDEPS = YES +!ENDIF +!ENDIF + +# +# Update dep file for next round incremental build +# +$(DEP_FILE) : $(TARGET_DXE_DPX) + $(MAKEDEPS) -f $(SOURCE_DIR)\$(DXE_DPX_SOURCE) $(DEP_FLAGS) + +!ENDIF + $(TARGET_DXE_DPX) : $(SOURCE_DIR)\$(DXE_DPX_SOURCE) $(INF_FILENAME) - $(CC) /nologo $(INC) $(VERSION_FLAGS) /EP $(SOURCE_DIR)\$(DXE_DPX_SOURCE) > $*.tmp1 +!IF "$(EFI_USE_CL_FOR_DEP)" != "YES" + $(CC) $(C_FLAGS_DPX) $(SOURCE_DIR)\$(DXE_DPX_SOURCE) > $*.tmp1 +!ELSE + -$(CC) $(C_FLAGS_DPX) $(SOURCE_DIR)\$(DXE_DPX_SOURCE) /showIncludes > $*.tmp1 2> $(DEST_DIR)\$(BASE_NAME)dxs2.cl + @$(MAKEDEPS) -f $(DEST_DIR)\$(BASE_NAME)dxs2.cl $(DEP_FLAGS2) +!ENDIF $(GENDEPEX) -I $*.tmp1 -O $*.tmp2 $(GENSECTION) -I $*.tmp2 -O $@ -S EFI_SECTION_DXE_DEPEX del $*.tmp1 > NUL @@ -778,10 +898,30 @@ $(TARGET_TES) : $(TARGET_TE) $(GENSECTION) -I $(TARGET_TE) -O $(TARGET_TES) -S EFI_SECTION_TE # -# Run FWImage on the DLL to set it as an EFI image type. +# $(DEP_TARGETS) are not needed for binary build. +# +!IF "$(BINARY)" == "TRUE" +DEP_TARGETS= +CREATEDEPS= +!ENDIF + # +# Build module to generate *.efi file from source code or binary file. +# +!IF (("$(BINARY)" == "TRUE") && EXIST($(EFI_PLATFORM_BIN)\$(PROCESSOR)\$(BASE_NAME).efi)) +$(TARGET_EFI) : $(EFI_PLATFORM_BIN)\$(PROCESSOR)\$(BASE_NAME).efi + copy $(EFI_PLATFORM_BIN)\$(PROCESSOR)\$(BASE_NAME).efi $(TARGET_EFI) /Y + if exist $(EFI_PLATFORM_BIN)\$(PROCESSOR)\$(BASE_NAME).pdb \ + copy $(EFI_PLATFORM_BIN)\$(PROCESSOR)\$(BASE_NAME).pdb $(TARGET_PDB) /Y +!ELSE $(TARGET_EFI) : $(TARGET_DLL) $(INF_FILENAME) $(FWIMAGE) $(COMPONENT_TYPE) $(TARGET_DLL) $(TARGET_EFI) +!IF ("$(EFI_BINARY_BUILD)" == "YES") + if not exist $(EFI_PLATFORM_BIN)\$(PROCESSOR) mkdir $(EFI_PLATFORM_BIN)\$(PROCESSOR) + if exist $(TARGET_EFI) copy $(TARGET_EFI) $(EFI_PLATFORM_BIN)\$(PROCESSOR)\$(BASE_NAME).efi /Y + if exist $(TARGET_PDB) copy $(TARGET_PDB) $(EFI_PLATFORM_BIN)\$(PROCESSOR)\$(BASE_NAME).pdb /Y +!ENDIF +!ENDIF # # Run GenTEImage on the built .efi file to create our TE file. @@ -845,12 +985,18 @@ DPX_SOURCE_FILE = $(DPX_SOURCE_OVERRIDE) !IF "$(DPX_SOURCE_FILE)" != "" !IF EXIST ($(DPX_SOURCE_FILE)) + # -# Add dependency check for dxs file, because dxs file depends on PPI or -# PROTOCOL guid defintions. +# Add build dependency check # DEP_FILE = $(DEST_DIR)\$(BASE_NAME)dxs.dep +!IF EXIST($(DEP_FILE)) +!INCLUDE $(DEP_FILE) +!ENDIF + +!IF "$(EFI_USE_CL_FOR_DEP)" != "YES" + !IF EXIST($(TARGET_DPX)) DEP_TARGETS = $(DEP_TARGETS) $(DEST_DIR)\$(BASE_NAME)dxs.dep !IF !EXIST($(DEP_FILE)) @@ -858,17 +1004,21 @@ CREATEDEPS = YES !ENDIF !ENDIF -!IF EXIST($(DEP_FILE)) -!INCLUDE $(DEP_FILE) -!ENDIF # # Update dep file for next round incremental build # $(DEP_FILE) : $(TARGET_DPX) $(MAKEDEPS) -f $(DPX_SOURCE_FILE) $(DEP_FLAGS) +!ENDIF + $(TARGET_DPX) : $(DPX_SOURCE_FILE) $(INF_FILENAME) - $(CC) /nologo $(INC) $(VERSION_FLAGS) /EP $(DPX_SOURCE_FILE) > $*.tmp1 +!IF "$(EFI_USE_CL_FOR_DEP)" != "YES" + $(CC) $(C_FLAGS_DPX) $(DPX_SOURCE_FILE) > $*.tmp1 +!ELSE + -$(CC) $(C_FLAGS_DPX) $(DPX_SOURCE_FILE) /showIncludes > $*.tmp1 2> $(DEST_DIR)\$(BASE_NAME)dxs.cl + @$(MAKEDEPS) -f $(DEST_DIR)\$(BASE_NAME)dxs.cl $(DEP_FLAGS2) +!ENDIF $(GENDEPEX) -I $*.tmp1 -O $*.tmp2 $(GENSECTION) -I $*.tmp2 -O $@ -S $(DEPEX_TYPE) del $*.tmp1 > NUL @@ -1042,12 +1192,18 @@ DPX_SOURCE_FILE = $(DPX_SOURCE_OVERRIDE) !IF "$(DPX_SOURCE_FILE)" != "" !IF EXIST ($(DPX_SOURCE_FILE)) + # -# Add dependency check for dxs file, because dxs file depends on PPI or -# PROTOCOL guid defintions. +# Add build dependency check # DEP_FILE = $(DEST_DIR)\$(BASE_NAME)dxs.dep +!IF EXIST($(DEP_FILE)) +!INCLUDE $(DEP_FILE) +!ENDIF + +!IF "$(EFI_USE_CL_FOR_DEP)" != "YES" + !IF EXIST($(TARGET_DPX)) DEP_TARGETS = $(DEP_TARGETS) $(DEST_DIR)\$(BASE_NAME)dxs.dep !IF !EXIST($(DEP_FILE)) @@ -1055,17 +1211,21 @@ CREATEDEPS = YES !ENDIF !ENDIF -!IF EXIST($(DEP_FILE)) -!INCLUDE $(DEP_FILE) -!ENDIF # # Update dep file for next round incremental build # $(DEP_FILE) : $(TARGET_DPX) $(MAKEDEPS) -f $(DPX_SOURCE_FILE) $(DEP_FLAGS) +!ENDIF + $(TARGET_DPX) : $(DPX_SOURCE_FILE) $(INF_FILENAME) - $(CC) /nologo $(INC) $(VERSION_FLAGS) /EP $(DPX_SOURCE_FILE) > $*.tmp1 +!IF "$(EFI_USE_CL_FOR_DEP)" != "YES" + $(CC) $(C_FLAGS_DPX) $(DPX_SOURCE_FILE) > $*.tmp1 +!ELSE + -$(CC) $(C_FLAGS_DPX) $(DPX_SOURCE_FILE) /showIncludes > $*.tmp1 2> $(DEST_DIR)\$(BASE_NAME)dxs.cl + @$(MAKEDEPS) -f $(DEST_DIR)\$(BASE_NAME)dxs.cl $(DEP_FLAGS2) +!ENDIF $(GENDEPEX) -I $*.tmp1 -O $*.tmp2 $(GENSECTION) -I $*.tmp2 -O $@ -S $(DEPEX_TYPE) del $*.tmp1 > NUL @@ -1210,12 +1370,18 @@ DPX_SOURCE_FILE = $(DPX_SOURCE_OVERRIDE) !IF "$(DPX_SOURCE_FILE)" != "" !IF EXIST ($(DPX_SOURCE_FILE)) + # -# Add dependency check for dxs file, because dxs file depends on PPI or -# PROTOCOL guid defintions. +# Add build dependency check # DEP_FILE = $(DEST_DIR)\$(BASE_NAME)dxs.dep +!IF EXIST($(DEP_FILE)) +!INCLUDE $(DEP_FILE) +!ENDIF + +!IF "$(EFI_USE_CL_FOR_DEP)" != "YES" + !IF EXIST($(TARGET_DPX)) DEP_TARGETS = $(DEP_TARGETS) $(DEST_DIR)\$(BASE_NAME)dxs.dep !IF !EXIST($(DEP_FILE)) @@ -1223,17 +1389,21 @@ CREATEDEPS = YES !ENDIF !ENDIF -!IF EXIST($(DEP_FILE)) -!INCLUDE $(DEP_FILE) -!ENDIF # # Update dep file for next round incremental build # $(DEP_FILE) : $(TARGET_DPX) $(MAKEDEPS) -f $(DPX_SOURCE_FILE) $(DEP_FLAGS) +!ENDIF + $(TARGET_DPX) : $(DPX_SOURCE_FILE) $(INF_FILENAME) - $(CC) /nologo $(INC) $(VERSION_FLAGS) /EP $(DPX_SOURCE_FILE) > $*.tmp1 +!IF "$(EFI_USE_CL_FOR_DEP)" != "YES" + $(CC) $(C_FLAGS_DPX) $(DPX_SOURCE_FILE) > $*.tmp1 +!ELSE + -$(CC) $(C_FLAGS_DPX) $(DPX_SOURCE_FILE) /showIncludes > $*.tmp1 2> $(DEST_DIR)\$(BASE_NAME)dxs.cl + @$(MAKEDEPS) -f $(DEST_DIR)\$(BASE_NAME)dxs.cl $(DEP_FLAGS2) +!ENDIF $(GENDEPEX) -I $*.tmp1 -O $*.tmp2 $(GENSECTION) -I $*.tmp2 -O $@ -S $(DEPEX_TYPE) del $*.tmp1 > NUL @@ -1348,8 +1518,15 @@ LOCALIZE = YES [=============================================================================] [Compile.Ia32.Vfr,Compile.Ipf.Vfr,Compile.x64.Vfr] +# +# Add build dependency check +# DEP_FILE = $(DEST_DIR)\$(FILE)Vfr.dep +!IF EXIST($(DEP_FILE)) +!INCLUDE $(DEP_FILE) +!ENDIF + !IF EXIST($(DEST_DIR)\$(FILE).obj) DEP_TARGETS = $(DEP_TARGETS) $(DEST_DIR)\$(FILE)Vfr.dep !IF !EXIST($(DEP_FILE)) @@ -1357,10 +1534,6 @@ CREATEDEPS = YES !ENDIF !ENDIF -!IF EXIST($(DEP_FILE)) -!INCLUDE $(DEP_FILE) -!ENDIF - # # Update dep file for next round incremental build # @@ -1425,8 +1598,15 @@ $(DEST_DIR)\$(FILE).obj : $(SOURCE_FILE_NAME) $(INF_FILENAME) $(ALL_DEPS) [=============================================================================] [Compile.Ia32.Ifr_Bin,Compile.Ipf.Ifr_Bin,Compile.x64.Ifr_Bin] +# +# Add build dependency check +# DEP_FILE = $(DEST_DIR)\$(FILE)Vfr.dep +!IF EXIST($(DEP_FILE)) +!INCLUDE $(DEP_FILE) +!ENDIF + !IF EXIST($(DEST_DIR)\$(FILE).obj) DEP_TARGETS = $(DEP_TARGETS) $(DEST_DIR)\$(FILE)Vfr.dep !IF !EXIST($(DEP_FILE)) @@ -1434,10 +1614,6 @@ CREATEDEPS = YES !ENDIF !ENDIF -!IF EXIST($(DEP_FILE)) -!INCLUDE $(DEP_FILE) -!ENDIF - # # Update dep file for next round incremental build # @@ -1472,8 +1648,15 @@ HII_IFR_PACK_FILES = $(HII_IFR_PACK_FILES) $(DEST_DIR)\$(FILE).hpk [=============================================================================] [Compile.Ebc.Ifr_Bin] +# +# Add build dependency check +# DEP_FILE = $(DEST_DIR)\$(FILE)Vfr.dep +!IF EXIST($(DEP_FILE)) +!INCLUDE $(DEP_FILE) +!ENDIF + !IF EXIST($(DEST_DIR)\$(FILE).obj) DEP_TARGETS = $(DEP_TARGETS) $(DEST_DIR)\$(FILE)Vfr.dep !IF !EXIST($(DEP_FILE)) @@ -1481,10 +1664,6 @@ CREATEDEPS = YES !ENDIF !ENDIF -!IF EXIST($(DEP_FILE)) -!INCLUDE $(DEP_FILE) -!ENDIF - # # Update dep file for next round incremental build # diff --git a/EdkCompatibilityPkg/Sample/Platform/CommonIa32.dsc b/EdkCompatibilityPkg/Sample/Platform/CommonIa32.dsc index f9fae29359..52fcb026d0 100644 --- a/EdkCompatibilityPkg/Sample/Platform/CommonIa32.dsc +++ b/EdkCompatibilityPkg/Sample/Platform/CommonIa32.dsc @@ -275,7 +275,6 @@ IMAGE_SCRIPT = } } - [=============================================================================] [Package.BS_DRIVER.Default,Package.RT_DRIVER.Default] PACKAGE.INF @@ -359,6 +358,7 @@ IMAGE_SCRIPT = $(SOURCE_FV)Fv.sec } } + [=============================================================================] # # Stripped package descriptions for size reduction. @@ -422,6 +422,7 @@ IMAGE_SCRIPT = { $(BASE_NAME).tes } + [=============================================================================] [Package.PE32_PEIM.DefaultStripped] PACKAGE.INF @@ -504,7 +505,6 @@ IMAGE_SCRIPT = } } - [=============================================================================] [Package.BS_DRIVER.DefaultStripped,Package.RT_DRIVER.DefaultStripped] PACKAGE.INF @@ -522,7 +522,6 @@ IMAGE_SCRIPT = } } - [=============================================================================] [Package.FvImageFile.DefaultStripped] PACKAGE.INF @@ -556,3 +555,41 @@ IMAGE_SCRIPT = } [=============================================================================] +[Package.AcpiTable.Default] +PACKAGE.INF +\[.] +BASE_NAME = $(BASE_NAME) +FFS_FILEGUID = $(FILE_GUID) +FFS_FILETYPE = EFI_FV_FILETYPE_FREEFORM +FFS_ATTRIB_CHECKSUM = TRUE + +IMAGE_SCRIPT = +{ + Compress ($(COMPRESS_METHOD)) { + Tool ( + $(OEMTOOLPATH)\GenCRC32Section + ARGS= -i $(SECTION_TARGETS) + $(DEST_DIR)\$(BASE_NAME).ui + -o $(DEST_DIR)\$(BASE_NAME).crc32 + OUTPUT = $(DEST_DIR)\$(BASE_NAME).crc32 + ) + } +} + +[=============================================================================] +[Package.AcpiTable.DefaultStripped] +PACKAGE.INF +\[.] +BASE_NAME = $(BASE_NAME) +FFS_FILEGUID = $(FILE_GUID) +FFS_FILETYPE = EFI_FV_FILETYPE_FREEFORM +FFS_ATTRIB_CHECKSUM = TRUE + +IMAGE_SCRIPT = +{ + Compress ($(COMPRESS_METHOD)) { + $(SECTION_TARGETS) + } +} + +[=============================================================================] diff --git a/EdkCompatibilityPkg/Sample/Platform/CommonIpf.dsc b/EdkCompatibilityPkg/Sample/Platform/CommonIpf.dsc index 13bfe9171b..d431a9c72f 100644 --- a/EdkCompatibilityPkg/Sample/Platform/CommonIpf.dsc +++ b/EdkCompatibilityPkg/Sample/Platform/CommonIpf.dsc @@ -269,7 +269,6 @@ IMAGE_SCRIPT = $(BASE_NAME).ver \ } - [=============================================================================] [Package.DxeIplPad.Default] PACKAGE.INF @@ -285,7 +284,6 @@ IMAGE_SCRIPT = $(BASE_NAME).pad \ } - [=============================================================================] [Package.BS_DRIVER.DxeMain] PACKAGE.INF @@ -304,7 +302,6 @@ IMAGE_SCRIPT = } } - [=============================================================================] [Package.BS_DRIVER.Default,Package.RT_DRIVER.Default,Package.SAL_RT_DRIVER.Default] PACKAGE.INF @@ -388,4 +385,27 @@ IMAGE_SCRIPT = $(SOURCE_FV)Fv.sec } } + +[=============================================================================] +[Package.AcpiTable.Default] +PACKAGE.INF +\[.] +BASE_NAME = $(BASE_NAME) +FFS_FILEGUID = $(FILE_GUID) +FFS_FILETYPE = EFI_FV_FILETYPE_FREEFORM +FFS_ATTRIB_CHECKSUM = TRUE + +IMAGE_SCRIPT = +{ + Compress ($(COMPRESS_METHOD)) { + Tool ( + $(OEMTOOLPATH)\GenCRC32Section + ARGS= -i $(SECTION_TARGETS) + $(DEST_DIR)\$(BASE_NAME).ui + -o $(DEST_DIR)\$(BASE_NAME).crc32 + OUTPUT = $(DEST_DIR)\$(BASE_NAME).crc32 + ) + } +} + [=============================================================================] diff --git a/EdkCompatibilityPkg/Sample/Platform/CommonX64.dsc b/EdkCompatibilityPkg/Sample/Platform/CommonX64.dsc index 4314049361..8fdea6f5b1 100644 --- a/EdkCompatibilityPkg/Sample/Platform/CommonX64.dsc +++ b/EdkCompatibilityPkg/Sample/Platform/CommonX64.dsc @@ -275,7 +275,6 @@ IMAGE_SCRIPT = } } - [=============================================================================] [Package.BS_DRIVER.Default,Package.RT_DRIVER.Default,Package.SAL_RT_DRIVER.Default] PACKAGE.INF @@ -406,6 +405,7 @@ IMAGE_SCRIPT = { $(BASE_NAME).tes } + [=============================================================================] [Package.PE32_PEIM.DefaultStripped] PACKAGE.INF @@ -488,7 +488,6 @@ IMAGE_SCRIPT = } } - [=============================================================================] [Package.BS_DRIVER.DefaultStripped,Package.RT_DRIVER.DefaultStripped,Package.SAL_RT_DRIVER.DefaultStripped] PACKAGE.INF @@ -506,7 +505,6 @@ IMAGE_SCRIPT = } } - [=============================================================================] [Package.FvImageFile.DefaultStripped] PACKAGE.INF @@ -539,6 +537,7 @@ IMAGE_SCRIPT = $(SOURCE_FV)Fv.sec } } + [=============================================================================] [Package.SECURITY_CORE.Default|DefaultStripped] PACKAGE.INF @@ -556,3 +555,41 @@ IMAGE_SCRIPT = } [=============================================================================] +[Package.AcpiTable.Default] +PACKAGE.INF +\[.] +BASE_NAME = $(BASE_NAME) +FFS_FILEGUID = $(FILE_GUID) +FFS_FILETYPE = EFI_FV_FILETYPE_FREEFORM +FFS_ATTRIB_CHECKSUM = TRUE + +IMAGE_SCRIPT = +{ + Compress ($(COMPRESS_METHOD)) { + Tool ( + $(OEMTOOLPATH)\GenCRC32Section + ARGS= -i $(SECTION_TARGETS) + $(DEST_DIR)\$(BASE_NAME).ui + -o $(DEST_DIR)\$(BASE_NAME).crc32 + OUTPUT = $(DEST_DIR)\$(BASE_NAME).crc32 + ) + } +} + +[=============================================================================] +[Package.AcpiTable.DefaultStripped] +PACKAGE.INF +\[.] +BASE_NAME = $(BASE_NAME) +FFS_FILEGUID = $(FILE_GUID) +FFS_FILETYPE = EFI_FV_FILETYPE_FREEFORM +FFS_ATTRIB_CHECKSUM = TRUE + +IMAGE_SCRIPT = +{ + Compress ($(COMPRESS_METHOD)) { + $(SECTION_TARGETS) + } +} + +[=============================================================================] diff --git a/EdkCompatibilityPkg/Sample/Platform/EdkIIGlueLib32.dsc b/EdkCompatibilityPkg/Sample/Platform/EdkIIGlueLib32.dsc index 5c71f41108..7b7accc9fd 100644 --- a/EdkCompatibilityPkg/Sample/Platform/EdkIIGlueLib32.dsc +++ b/EdkCompatibilityPkg/Sample/Platform/EdkIIGlueLib32.dsc @@ -37,3 +37,4 @@ $(EDK_PREFIX)Foundation\Library\EdkIIGlueLib\Library\PeiHobLib\PeiHobLib.inf $(EDK_PREFIX)Foundation\Library\EdkIIGlueLib\Library\PeiReportStatusCodeLib\PeiReportStatusCodeLib.inf $(EDK_PREFIX)Foundation\Library\EdkIIGlueLib\Library\PeiResourcePublicationLib\PeiResourcePublicationLib.inf $(EDK_PREFIX)Foundation\Library\EdkIIGlueLib\Library\PeiSmbusLib\PeiSmbusLib.inf +$(EDK_PREFIX)Foundation\Library\EdkIIGlueLib\Library\PeiPerformanceLib\PeiPerformanceLib.inf diff --git a/EdkCompatibilityPkg/Sample/Platform/EdkIIGlueLibAll.dsc b/EdkCompatibilityPkg/Sample/Platform/EdkIIGlueLibAll.dsc index 8879bf3737..6939a7366b 100644 --- a/EdkCompatibilityPkg/Sample/Platform/EdkIIGlueLibAll.dsc +++ b/EdkCompatibilityPkg/Sample/Platform/EdkIIGlueLibAll.dsc @@ -51,4 +51,6 @@ $(EDK_PREFIX)Foundation\Library\EdkIIGlueLib\Library\DxeServicesTableLib\DxeServ $(EDK_PREFIX)Foundation\Library\EdkIIGlueLib\Library\EdkDxeSalLib\EdkDxeSalLib.inf $(EDK_PREFIX)Foundation\Library\EdkIIGlueLib\Library\EdkDxeRuntimeDriverLib\EdkDxeRuntimeDriverLib.inf $(EDK_PREFIX)Foundation\Library\EdkIIGlueLib\Library\DxeSmbusLib\DxeSmbusLib.inf -$(EDK_PREFIX)Foundation\Library\EdkIIGlueLib\Library\PeiSmbusLib\PeiSmbusLib.inf \ No newline at end of file +$(EDK_PREFIX)Foundation\Library\EdkIIGlueLib\Library\PeiSmbusLib\PeiSmbusLib.inf +$(EDK_PREFIX)Foundation\Library\EdkIIGlueLib\Library\DxePerformanceLib\DxePerformanceLib.inf +$(EDK_PREFIX)Foundation\Library\EdkIIGlueLib\Library\PeiPerformanceLib\PeiPerformanceLib.inf diff --git a/EdkCompatibilityPkg/Sample/Platform/EdkLib32.dsc b/EdkCompatibilityPkg/Sample/Platform/EdkLib32.dsc index 7be8ebbe80..3e0aacab21 100644 --- a/EdkCompatibilityPkg/Sample/Platform/EdkLib32.dsc +++ b/EdkCompatibilityPkg/Sample/Platform/EdkLib32.dsc @@ -1,6 +1,6 @@ #/*++ # -# Copyright (c) 2004 - 2006, Intel Corporation +# Copyright (c) 2004 - 2007, Intel Corporation # All rights reserved. This program and the accompanying materials # are licensed and made available under the terms and conditions of the BSD License # which accompanies this distribution. The full text of the license may be found at @@ -25,7 +25,6 @@ $(EDK_PREFIX)Foundation\Cpu\Pentium\CpuIA32Lib\CpuIA32Lib.inf $(EDK_PREFIX)Foundation\Cpu\Itanium\CpuIA64Lib\CpuIA64Lib.inf $(EDK_PREFIX)Foundation\Library\CustomizedDecompress\CustomizedDecompress.inf $(EDK_PREFIX)Foundation\Library\CompilerStub\CompilerStubLib.inf -$(EDK_PREFIX)Foundation\Library\Dxe\Hob\HobLib.inf # # PEI libraries diff --git a/EdkCompatibilityPkg/Sample/Platform/EdkLibAll.dsc b/EdkCompatibilityPkg/Sample/Platform/EdkLibAll.dsc index bdb37b17a0..18169da550 100644 --- a/EdkCompatibilityPkg/Sample/Platform/EdkLibAll.dsc +++ b/EdkCompatibilityPkg/Sample/Platform/EdkLibAll.dsc @@ -25,7 +25,6 @@ $(EDK_PREFIX)Foundation\Cpu\Pentium\CpuIA32Lib\CpuIA32Lib.inf $(EDK_PREFIX)Foundation\Cpu\Itanium\CpuIA64Lib\CpuIA64Lib.inf $(EDK_PREFIX)Foundation\Library\CustomizedDecompress\CustomizedDecompress.inf $(EDK_PREFIX)Foundation\Library\CompilerStub\CompilerStubLib.inf -$(EDK_PREFIX)Foundation\Library\Dxe\Hob\HobLib.inf # # PEI libraries @@ -42,10 +41,12 @@ $(EDK_PREFIX)Foundation\Core\Dxe\ArchProtocol\ArchProtocolLib.inf $(EDK_PREFIX)Foundation\Efi\Protocol\EfiProtocolLib.inf $(EDK_PREFIX)Foundation\Framework\Protocol\EdkFrameworkProtocolLib.inf $(EDK_PREFIX)Foundation\Protocol\EdkProtocolLib.inf +$(EDK_PREFIX)Foundation\Library\Dxe\Hob\HobLib.inf $(EDK_PREFIX)Foundation\Library\Dxe\EfiDriverLib\EfiDriverLib.inf $(EDK_PREFIX)Foundation\Library\RuntimeDxe\EfiRuntimeLib\EfiRuntimeLib.inf $(EDK_PREFIX)Foundation\Library\Dxe\Graphics\Graphics.inf $(EDK_PREFIX)Foundation\Library\Dxe\EfiIfrSupportLib\EfiIfrSupportLib.inf +$(EDK_PREFIX)Foundation\Library\Dxe\UefiEfiIfrSupportLib\UefiEfiIfrSupportLib.inf $(EDK_PREFIX)Foundation\Library\Dxe\Print\PrintLib.inf $(EDK_PREFIX)Foundation\Library\Dxe\EfiScriptLib\EfiScriptLib.inf $(EDK_PREFIX)Foundation\Library\Dxe\EfiUiLib\EfiUiLib.inf @@ -55,9 +56,3 @@ $(EDK_PREFIX)Foundation\Library\Dxe\EfiUiLib\EfiUiLib.inf # $(EDK_PREFIX)Foundation\Library\Dxe\PrintLite\PrintLib.inf $(EDK_PREFIX)Foundation\Library\Dxe\GraphicsLite\Graphics.inf - -# -# Module Libraries -# -#$(EDK_PREFIX)Sample\Platform\Generic\Dxe\GenericBds\GenericBds.inf -#$(EDK_PREFIX)Sample\Bus\Usb\UsbLib\Dxe\UsbDxeLib.inf diff --git a/EdkCompatibilityPkg/Sample/Platform/Generic/MonoStatusCode/Pei/MonoStatusCode.h b/EdkCompatibilityPkg/Sample/Platform/Generic/MonoStatusCode/Pei/MonoStatusCode.h new file mode 100644 index 0000000000..7ff3140fa6 --- /dev/null +++ b/EdkCompatibilityPkg/Sample/Platform/Generic/MonoStatusCode/Pei/MonoStatusCode.h @@ -0,0 +1,138 @@ +/*++ + +Copyright (c) 2004 - 2005, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + MonoStatusCode.h + +Abstract: + + Monolithic single PEIM to provide the status code functionality. + The PEIM is a blend of libraries that correspond to the different status code + listeners that a platform installs. + +--*/ + +#ifndef _MONO_STATUS_CODE_H_ +#define _MONO_STATUS_CODE_H_ + +// +// Statements that include other files. +// +#include "Tiano.h" +#include "Pei.h" +#include "PeiLib.h" +#include "EfiCommonLib.h" + +// +// Driver Produced DXE Protocol Prototypes +// +#include EFI_PPI_PRODUCER (StatusCode) + +// +// Driver Consumed DXE Protocol Prototypes +// +#include EFI_ARCH_PROTOCOL_CONSUMER (StatusCode) + +// +// Driver GUID includes +// +#include EFI_GUID_DEFINITION (StatusCode) +#include EFI_GUID_DEFINITION (StatusCodeCallerId) +#include EFI_GUID_DEFINITION (GlobalVariable) + +extern EFI_GUID mStatusCodeRuntimeGuid; + +// +// Platform specific function Declarations. These must be implemented in a +// subdirectory named PlatformName in a file named PlatformStatusCode.c. +// See D845GRG\PlatformStatusCode.c for an example of a simple status code +// implementation. +// See Nt32\PlatformStatusCode.c for an example of a status code implementation +// that relocates itself into memory. +// +// +// This is the driver entry point and must be defined. +// +EFI_STATUS +EFIAPI +InstallMonoStatusCode ( + IN EFI_FFS_FILE_HEADER *FfsHeader, + IN EFI_PEI_SERVICES **PeiServices + ) +; + +// +// This is the platform function to initialize the listeners desired by the +// platform. +// +VOID +PlatformInitializeStatusCode ( + IN EFI_FFS_FILE_HEADER *FfsHeader, + IN EFI_PEI_SERVICES **PeiServices + ) +; + +// +// This is the platform function that calls all of the listeners desired by the +// platform. +// +EFI_STATUS +EFIAPI +PlatformReportStatusCode ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_STATUS_CODE_TYPE CodeType, + IN EFI_STATUS_CODE_VALUE Value, + IN UINT32 Instance, + IN EFI_GUID * CallerId, + IN EFI_STATUS_CODE_DATA * Data OPTIONAL + ) +; + +// +// Platform independent function Declarations +// +// +// Initialize the status code listeners and publish the status code PPI. +// +VOID +EFIAPI +InitializeMonoStatusCode ( + IN EFI_FFS_FILE_HEADER *FfsHeader, + IN EFI_PEI_SERVICES **PeiServices + ) +; + +// +// Convert a DXE status code call into a PEI status code call. +// +EFI_STATUS +EFIAPI +TranslateDxeStatusCodeToPeiStatusCode ( + IN EFI_STATUS_CODE_TYPE CodeType, + IN EFI_STATUS_CODE_VALUE Value, + IN UINT32 Instance, + IN EFI_GUID * CallerId, + IN EFI_STATUS_CODE_DATA * Data OPTIONAL + ) +; + +// +// Publish a HOB that contains the listener to be used by DXE. +// +EFI_STATUS +EFIAPI +InitializeDxeReportStatusCode ( + IN EFI_PEI_SERVICES **PeiServices + ) +; + +#endif diff --git a/EdkCompatibilityPkg/Sample/Platform/Generic/RuntimeDxe/StatusCode/Lib/BsDataHubStatusCode/BsDataHubStatusCode.c b/EdkCompatibilityPkg/Sample/Platform/Generic/RuntimeDxe/StatusCode/Lib/BsDataHubStatusCode/BsDataHubStatusCode.c index e950126c4f..980635dc7f 100644 --- a/EdkCompatibilityPkg/Sample/Platform/Generic/RuntimeDxe/StatusCode/Lib/BsDataHubStatusCode/BsDataHubStatusCode.c +++ b/EdkCompatibilityPkg/Sample/Platform/Generic/RuntimeDxe/StatusCode/Lib/BsDataHubStatusCode/BsDataHubStatusCode.c @@ -1,6 +1,6 @@ /*++ -Copyright (c) 2004 - 2006, Intel Corporation +Copyright (c) 2004 - 2007, Intel Corporation All rights reserved. This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -26,27 +26,29 @@ Abstract: #include "BsDataHubStatusCode.h" // -// Globals only work at BootService Time. NOT at Runtime! +// Initialize FIFO to cache records. // -static EFI_DATA_HUB_PROTOCOL *mDataHub; -static EFI_LIST_ENTRY *mRecordHead; -static EFI_LIST_ENTRY *mRecordTail; -static INTN mRecordNum = 0; -static EFI_EVENT mLogDataHubEvent; -static EFI_LOCK mStatusCodeReportLock = EFI_INITIALIZE_LOCK_VARIABLE(EFI_TPL_HIGH_LEVEL); -static BOOLEAN mEventHandlerActive = FALSE; +STATIC EFI_LIST_ENTRY mRecordsFifo = INITIALIZE_LIST_HEAD_VARIABLE (mRecordsFifo); +STATIC EFI_LIST_ENTRY mRecordsBuffer = INITIALIZE_LIST_HEAD_VARIABLE (mRecordsBuffer); +STATIC EFI_EVENT mLogDataHubEvent; +STATIC BOOLEAN mEventHandlerActive = FALSE; +// +// Cache data hub protocol. +// +STATIC EFI_DATA_HUB_PROTOCOL *mDataHubProtocol; -STATUS_CODE_RECORD_LIST * -AllocateRecordBuffer ( +STATIC +DATA_HUB_STATUS_CODE_DATA_RECORD * +AcquireRecordBuffer ( VOID ) /*++ Routine Description: - Allocate a new record list node and initialize it. - Inserting the node into the list isn't the task of this function. + Return one DATAHUB_STATUSCODE_RECORD space. + The size of free record pool would be extend, if the pool is empty. Arguments: @@ -58,144 +60,94 @@ Returns: --*/ { - STATUS_CODE_RECORD_LIST *DataBuffer; - - DataBuffer = NULL; - - gBS->AllocatePool (EfiBootServicesData, sizeof (STATUS_CODE_RECORD_LIST), &DataBuffer); - if (DataBuffer == NULL) { - return NULL; - } - - EfiCommonLibZeroMem (DataBuffer, sizeof (STATUS_CODE_RECORD_LIST)); - DataBuffer->Signature = BS_DATA_HUB_STATUS_CODE_SIGNATURE; - - return DataBuffer; -} - -DATA_HUB_STATUS_CODE_DATA_RECORD * -AquireEmptyRecordBuffer ( - VOID - ) -/*++ - -Routine Description: - - Acquire an empty record buffer from the record list if there's free node, - or allocate one new node and insert it to the list if the list is full and - the function isn't run in EFI_TPL_HIGH_LEVEL. + DATAHUB_STATUSCODE_RECORD *Record; + EFI_TPL CurrentTpl; + EFI_LIST_ENTRY *Node; + UINT32 Index; -Arguments: - - None - -Returns: - - Pointer to new record buffer. NULL if none available. - ---*/ -{ - EFI_TPL OldTpl; - STATUS_CODE_RECORD_LIST *DataBuffer; + Record = NULL; + CurrentTpl = gBS->RaiseTPL (EFI_TPL_HIGH_LEVEL); - DataBuffer = NULL; + if (!IsListEmpty (&mRecordsBuffer)) { + Node = GetFirstNode (&mRecordsBuffer); + RemoveEntryList (Node); - // - // This function must be reentrant because an event with higher priority may interrupt it - // and also report status code. - // - EfiAcquireLock (&mStatusCodeReportLock); - if (mRecordTail != mRecordHead->ForwardLink) { - if (mRecordNum != 0) { - mRecordHead = mRecordHead->ForwardLink; + Record = _CR (Node, DATAHUB_STATUSCODE_RECORD, Node); + } else { + if (CurrentTpl > EFI_TPL_NOTIFY) { + gBS->RestoreTPL (CurrentTpl); + return NULL; } - DataBuffer = CR (mRecordHead, STATUS_CODE_RECORD_LIST, Link, BS_DATA_HUB_STATUS_CODE_SIGNATURE); - mRecordNum++; - EfiReleaseLock (&mStatusCodeReportLock); - // - // Initalize the record buffer is the responsibility of the producer, - // because the consummer is in a lock so must keep it short. - // - EfiCommonLibZeroMem (&DataBuffer->RecordBuffer[0], BYTES_PER_BUFFER); - } else if (mRecordNum < MAX_RECORD_NUM) { - // - // The condition of "mRecordNum < MAX_RECORD_NUM" is not promised, - // because mRecodeNum may be increased out of this lock. - // - EfiReleaseLock (&mStatusCodeReportLock); - - // - // Can't allocate additional buffer in EFI_TPL_HIGH_LEVEL. - // Reporting too many status code in EFI_TPL_HIGH_LEVEL may cause status code lost. - // - OldTpl = gBS->RaiseTPL (EFI_TPL_HIGH_LEVEL); - if (OldTpl == EFI_TPL_HIGH_LEVEL) { + gBS->RestoreTPL (CurrentTpl); + + gBS->AllocatePool (EfiBootServicesData, sizeof (DATAHUB_STATUSCODE_RECORD) * 16, &Record); + if (Record == NULL) { return NULL; } - gBS->RestoreTPL (OldTpl); - DataBuffer = AllocateRecordBuffer (); - if (DataBuffer == NULL) { - return NULL; + EfiCommonLibZeroMem (Record, sizeof (DATAHUB_STATUSCODE_RECORD) * 16); + + + CurrentTpl = gBS->RaiseTPL (EFI_TPL_HIGH_LEVEL); + for (Index = 1; Index < 16; Index++) { + InsertTailList (&mRecordsBuffer, &Record[Index].Node); } - EfiAcquireLock (&mStatusCodeReportLock); - InsertHeadList (mRecordHead, &DataBuffer->Link); - mRecordHead = mRecordHead->ForwardLink; - mRecordNum++; - EfiReleaseLock (&mStatusCodeReportLock); - } else { - EfiReleaseLock (&mStatusCodeReportLock); - return NULL; } - return (DATA_HUB_STATUS_CODE_DATA_RECORD *) DataBuffer->RecordBuffer; + Record->Signature = BS_DATA_HUB_STATUS_CODE_SIGNATURE; + InsertTailList (&mRecordsFifo, &Record->Node); + + gBS->RestoreTPL (CurrentTpl); + + return (DATA_HUB_STATUS_CODE_DATA_RECORD *) (Record->Data); } -EFI_STATUS -ReleaseRecordBuffer ( - IN STATUS_CODE_RECORD_LIST *RecordBuffer +STATIC +DATA_HUB_STATUS_CODE_DATA_RECORD * +RetrieveRecord ( + VOID ) /*++ Routine Description: - Release a buffer in the list, remove some nodes to keep the list inital length. + Retrieve one record from Records FIFO. The record would be removed from FIFO and + release to free record buffer. Arguments: - RecordBuffer - Buffer to release + None Returns: - EFI_SUCCESS - If DataRecord is valid - EFI_UNSUPPORTED - The record list has empty + Point to record which is ready to be logged, or NULL if the FIFO of record is empty. ---*/ +--*/ { - ASSERT (RecordBuffer != NULL); + DATA_HUB_STATUS_CODE_DATA_RECORD *RecordData; + DATAHUB_STATUSCODE_RECORD *Record; + EFI_LIST_ENTRY *Node; + EFI_TPL CurrentTpl; + + RecordData = NULL; + + CurrentTpl = gBS->RaiseTPL (EFI_TPL_HIGH_LEVEL); - // - // The consummer needn't to be reentrient and the producer won't do any meaningful thing - // when consummer is logging records. - // - if (mRecordNum <= 0) { - return EFI_UNSUPPORTED; - } else if (mRecordNum > INITIAL_RECORD_NUM) { - mRecordTail = mRecordTail->ForwardLink; - RemoveEntryList (&RecordBuffer->Link); - mRecordNum--; - gBS->FreePool (RecordBuffer); - } else { - if (mRecordNum != 1) { - mRecordTail = mRecordTail->ForwardLink; - } - mRecordNum--; + if (!IsListEmpty (&mRecordsFifo)) { + Node = GetFirstNode (&mRecordsFifo); + Record = CR (Node, DATAHUB_STATUSCODE_RECORD, Node, BS_DATA_HUB_STATUS_CODE_SIGNATURE); + + RemoveEntryList (&Record->Node); + InsertTailList (&mRecordsBuffer, &Record->Node); + Record->Signature = 0; + RecordData = (DATA_HUB_STATUS_CODE_DATA_RECORD *) Record->Data; } - return EFI_SUCCESS; + gBS->RestoreTPL (CurrentTpl); + + return RecordData; } -EFI_BOOTSERVICE EFI_STATUS EFIAPI BsDataHubReportStatusCode ( @@ -222,31 +174,32 @@ Returns: --*/ { - DATA_HUB_STATUS_CODE_DATA_RECORD *DataHub; - UINT32 ErrorLevel; - VA_LIST Marker; - CHAR8 *Format; - UINTN Index; - CHAR16 FormatBuffer[BYTES_PER_RECORD]; - - DataHub = NULL; + DATA_HUB_STATUS_CODE_DATA_RECORD *Record; + UINT32 ErrorLevel; + VA_LIST Marker; + CHAR8 *Format; + CHAR16 FormatBuffer[BYTES_PER_RECORD]; + UINTN Index; + // + // See whether in runtime phase or not. + // if (EfiAtRuntime ()) { // // For now all we do is post code at runtime // return EFI_SUCCESS; } + // - // If we had an error while in our event handler, then do nothing so - // that we don't get in an endless loop. + // Discard new DataHubRecord caused by DataHub->LogData() // if (mEventHandlerActive) { return EFI_SUCCESS; } - DataHub = (DATA_HUB_STATUS_CODE_DATA_RECORD *) AquireEmptyRecordBuffer (); - if (DataHub == NULL) { + Record = AcquireRecordBuffer (); + if (Record == NULL) { // // There are no empty record buffer in private buffers // @@ -255,24 +208,15 @@ Returns: // // Construct Data Hub Extended Data // - DataHub->CodeType = CodeType; - DataHub->Value = Value; - DataHub->Instance = Instance; + Record->CodeType = CodeType; + Record->Value = Value; + Record->Instance = Instance; if (CallerId != NULL) { - EfiCopyMem (&DataHub->CallerId, CallerId, sizeof (EFI_GUID)); - } else { - EfiZeroMem (&DataHub->CallerId, sizeof (EFI_GUID)); + EfiCopyMem (&Record->CallerId, CallerId, sizeof (EFI_GUID)); } - if (Data == NULL) { - EfiZeroMem (&DataHub->Data, sizeof (EFI_STATUS_CODE_DATA)); - } else { - // - // Copy generic Header - // - EfiCopyMem (&DataHub->Data, Data, sizeof (EFI_STATUS_CODE_DATA)); - + if (Data != NULL) { if (ReportStatusCodeExtractDebugInfo (Data, &ErrorLevel, &Marker, &Format)) { // // Convert Ascii Format string to Unicode. @@ -287,26 +231,25 @@ Returns: // Put processed string into the buffer // Index = VSPrint ( - (UINT16 *) (DataHub + 1), + (CHAR16 *) (Record + 1), BYTES_PER_RECORD - (sizeof (DATA_HUB_STATUS_CODE_DATA_RECORD)), FormatBuffer, Marker ); - - // - // DATA_HUB_STATUS_CODE_DATA_RECORD followed by VSPrint String Buffer - // - DataHub->Data.Size = (UINT16) (Index * sizeof (CHAR16)); - + + EfiCopyMem (&Record->Data.Type, &gEfiStatusCodeDataTypeDebugGuid, sizeof (EFI_GUID)); + Record->Data.HeaderSize = Data->HeaderSize; + Record->Data.Size = (UINT16) (Index * sizeof (CHAR16)); } else { // - // Default behavior is to copy optional data + // Copy status code data header // - if (Data->Size > (BYTES_PER_RECORD - sizeof (DATA_HUB_STATUS_CODE_DATA_RECORD))) { - DataHub->Data.Size = (UINT16) (BYTES_PER_RECORD - sizeof (DATA_HUB_STATUS_CODE_DATA_RECORD)); - } + EfiCopyMem (&Record->Data, Data, sizeof (EFI_STATUS_CODE_DATA)); - EfiCopyMem (DataHub + 1, Data + 1, DataHub->Data.Size); + if (Data->Size > BYTES_PER_RECORD - sizeof (DATA_HUB_STATUS_CODE_DATA_RECORD)) { + Record->Data.Size = (UINT16) (BYTES_PER_RECORD - sizeof (DATA_HUB_STATUS_CODE_DATA_RECORD)); + } + EfiCopyMem ((VOID *) (Record + 1), Data + 1, Record->Data.Size); } } @@ -339,39 +282,34 @@ Returns: --*/ { - EFI_STATUS Status; - DATA_HUB_STATUS_CODE_DATA_RECORD *DataRecord; - UINTN Size; + DATA_HUB_STATUS_CODE_DATA_RECORD *Record; + UINT32 Size; UINT64 DataRecordClass; - EFI_LIST_ENTRY *Link; - STATUS_CODE_RECORD_LIST *BufferEntry; // - // Set our global flag so we don't recurse if we get an error here. + // Set global flag so we don't recurse if DataHub->LogData eventually causes new DataHubRecord // mEventHandlerActive = TRUE; // // Log DataRecord in Data Hub. - // If there are multiple DataRecords, Log all of them. + // Journal records fifo to find all record entry. // - Link = mRecordTail; - - while (mRecordNum != 0) { - BufferEntry = CR (Link, STATUS_CODE_RECORD_LIST, Link, BS_DATA_HUB_STATUS_CODE_SIGNATURE); - DataRecord = (DATA_HUB_STATUS_CODE_DATA_RECORD *) (BufferEntry->RecordBuffer); - Link = Link->ForwardLink; - + while (1) { + Record = RetrieveRecord (); + if (Record == NULL) { + break; + } // // Add in the size of the header we added. // - Size = sizeof (DATA_HUB_STATUS_CODE_DATA_RECORD) + DataRecord->Data.Size; + Size = sizeof (DATA_HUB_STATUS_CODE_DATA_RECORD) + (UINT32) Record->Data.Size; - if ((DataRecord->CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE) { + if ((Record->CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE) { DataRecordClass = EFI_DATA_RECORD_CLASS_PROGRESS_CODE; - } else if ((DataRecord->CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) { + } else if ((Record->CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) { DataRecordClass = EFI_DATA_RECORD_CLASS_ERROR; - } else if ((DataRecord->CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_DEBUG_CODE) { + } else if ((Record->CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_DEBUG_CODE) { DataRecordClass = EFI_DATA_RECORD_CLASS_DEBUG; } else { // @@ -383,45 +321,27 @@ Returns: EFI_DATA_RECORD_CLASS_PROGRESS_CODE; } - if (((DataRecord->Instance & EFI_D_ERROR) != 0) && - (((DataRecord->Instance & EFI_D_POOL) != 0) || ((DataRecord->Instance & EFI_D_PAGE) != 0)) - ) { - // - // If memory error, do not call LogData (). - // - ErrorPrint (L"ERROR", "Memory Error\n"); - Status = EFI_OUT_OF_RESOURCES; - } else { - // - // We don't log EFI_D_POOL and EFI_D_PAGE debug info to datahub - // to avoid recursive logging due to the memory allocation in datahub - // - if (DataRecordClass != EFI_DATA_RECORD_CLASS_DEBUG || - ((DataRecord->Instance & EFI_D_POOL) == 0 && (DataRecord->Instance & EFI_D_PAGE) == 0)) { - // - // Log DataRecord in Data Hub - // - Status = mDataHub->LogData ( - mDataHub, - &gEfiStatusCodeGuid, - &gEfiStatusCodeRuntimeProtocolGuid, - DataRecordClass, - DataRecord, - (UINT32) Size - ); - } - } + // + // Log DataRecord in Data Hub + // + + mDataHubProtocol->LogData ( + mDataHubProtocol, + &gEfiStatusCodeGuid, + &gEfiStatusCodeRuntimeProtocolGuid, + DataRecordClass, + Record, + Size + ); - ReleaseRecordBuffer (BufferEntry); } mEventHandlerActive = FALSE; - return ; } -EFI_BOOTSERVICE EFI_STATUS +EFIAPI BsDataHubInitializeStatusCode ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable @@ -444,38 +364,14 @@ Returns: --*/ { EFI_STATUS Status; - STATUS_CODE_RECORD_LIST *DataBuffer; - UINTN Index1; - DataBuffer = NULL; - - Status = gBS->LocateProtocol (&gEfiDataHubProtocolGuid, NULL, &mDataHub); - // - // Should never fail due to dependency grammer - // + Status = gBS->LocateProtocol ( + &gEfiDataHubProtocolGuid, + NULL, + (VOID **) &mDataHubProtocol + ); ASSERT_EFI_ERROR (Status); - // - // Initialize a record list with length not greater than INITIAL_RECORD_NUM. - // If no buffer can be allocated, return EFI_OUT_OF_RESOURCES. - // - DataBuffer = AllocateRecordBuffer (); - if (DataBuffer == NULL) { - return EFI_OUT_OF_RESOURCES; - } - mRecordHead = &DataBuffer->Link; - mRecordTail = mRecordHead; - InitializeListHead (mRecordHead); - - for (Index1 = 1; Index1 < INITIAL_RECORD_NUM; Index1++) { - DataBuffer = AllocateRecordBuffer (); - if (DataBuffer == NULL) { - break; - } - InsertHeadList (mRecordHead, &DataBuffer->Link); - } - - // // Create a Notify Event to log data in Data Hub // @@ -487,5 +383,9 @@ Returns: &mLogDataHubEvent ); + ASSERT_EFI_ERROR (Status); + return EFI_SUCCESS; } + + diff --git a/EdkCompatibilityPkg/Sample/Platform/Generic/RuntimeDxe/StatusCode/Lib/BsDataHubStatusCode/BsDataHubStatusCode.h b/EdkCompatibilityPkg/Sample/Platform/Generic/RuntimeDxe/StatusCode/Lib/BsDataHubStatusCode/BsDataHubStatusCode.h index 7f5d026859..b56bc9bfd3 100644 --- a/EdkCompatibilityPkg/Sample/Platform/Generic/RuntimeDxe/StatusCode/Lib/BsDataHubStatusCode/BsDataHubStatusCode.h +++ b/EdkCompatibilityPkg/Sample/Platform/Generic/RuntimeDxe/StatusCode/Lib/BsDataHubStatusCode/BsDataHubStatusCode.h @@ -1,6 +1,6 @@ /*++ -Copyright (c) 2004 - 2006, Intel Corporation +Copyright (c) 2004 - 2007, Intel Corporation All rights reserved. This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -52,7 +52,6 @@ Abstract: // Private data declarations // #define MAX_RECORD_NUM 1000 -#define INITIAL_RECORD_NUM 20 #define BYTES_PER_RECORD EFI_STATUS_CODE_DATA_MAX_SIZE #define BYTES_PER_BUFFER (BYTES_PER_RECORD * sizeof (UINT8)) @@ -60,77 +59,63 @@ Abstract: typedef struct { UINTN Signature; - EFI_LIST_ENTRY Link; - UINT8 RecordBuffer[BYTES_PER_RECORD]; -} STATUS_CODE_RECORD_LIST; + EFI_LIST_ENTRY Node; + UINT8 Data[BYTES_PER_RECORD]; +} DATAHUB_STATUSCODE_RECORD; // // Function prototypes // -STATUS_CODE_RECORD_LIST * -AllocateRecordBuffer ( - VOID - ); -/*++ - -Routine Description: - - Allocate a new record list node and initialize it. - Inserting the node into the list isn't the task of this function. - -Arguments: - - None - -Returns: - - A pointer to the new allocated node or NULL if non available - ---*/ - -DATA_HUB_STATUS_CODE_DATA_RECORD * -AquireEmptyRecordBuffer ( - VOID +EFI_STATUS +EFIAPI +BsDataHubInitializeStatusCode ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable ); /*++ Routine Description: - Acquire an empty record buffer from the record list if there's free node, - or allocate one new node and insert it to the list if the list is full and - the function isn't run in EFI_TPL_HIGH_LEVEL. + Install a data hub listener. Arguments: - None + (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT) Returns: - Pointer to new record buffer. NULL if none available. + EFI_SUCCESS - Logging Hub protocol installed + Other - No protocol installed, unload driver. --*/ EFI_STATUS -ReleaseRecordBuffer ( - IN STATUS_CODE_RECORD_LIST *RecordBuffer +EFIAPI +BsDataHubReportStatusCode ( + IN EFI_STATUS_CODE_TYPE CodeType, + IN EFI_STATUS_CODE_VALUE Value, + IN UINT32 Instance, + IN EFI_GUID * CallerId, + IN EFI_STATUS_CODE_DATA * Data OPTIONAL ); /*++ Routine Description: - Release a buffer in the list, remove some nodes to keep the list inital length. + Boot service report status code listener. This function logs the status code + into the data hub. + Arguments: - RecordBuffer - Buffer to release + Same as gRT->ReportStatusCode (See Tiano Runtime Specification) Returns: - EFI_SUCCESS - If DataRecord is valid - EFI_UNSUPPORTED - The record list has empty + None --*/ -void +VOID EFIAPI LogDataHubEventHandler ( IN EFI_EVENT Event, diff --git a/EdkCompatibilityPkg/Sample/Platform/Generic/RuntimeDxe/StatusCode/Lib/BsSerialStatusCode/BsSerialStatusCode.c b/EdkCompatibilityPkg/Sample/Platform/Generic/RuntimeDxe/StatusCode/Lib/BsSerialStatusCode/BsSerialStatusCode.c index 483064d737..35fb9a00a4 100644 --- a/EdkCompatibilityPkg/Sample/Platform/Generic/RuntimeDxe/StatusCode/Lib/BsSerialStatusCode/BsSerialStatusCode.c +++ b/EdkCompatibilityPkg/Sample/Platform/Generic/RuntimeDxe/StatusCode/Lib/BsSerialStatusCode/BsSerialStatusCode.c @@ -1,6 +1,6 @@ /*++ -Copyright (c) 2004 - 2005, Intel Corporation +Copyright (c) 2004 - 2007, Intel Corporation All rights reserved. This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -2095,6 +2095,7 @@ Returns: #endif VOID +EFIAPI BsSerialInitializeStatusCode ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable @@ -2189,6 +2190,9 @@ Returns: } while ((Data & LSR_TXRDY) == 0); IoWrite8 (gComBase, Character); +#ifdef SERIAL_OUTPUT_STALL + EfiStall (SERIAL_OUTPUT_STALL); +#endif } VOID diff --git a/EdkCompatibilityPkg/Sample/Platform/Generic/RuntimeDxe/StatusCode/Lib/Include/BsDataHubStatusCodeLib.h b/EdkCompatibilityPkg/Sample/Platform/Generic/RuntimeDxe/StatusCode/Lib/Include/BsDataHubStatusCodeLib.h index 6d6dfcd16b..c15ac01e51 100644 --- a/EdkCompatibilityPkg/Sample/Platform/Generic/RuntimeDxe/StatusCode/Lib/Include/BsDataHubStatusCodeLib.h +++ b/EdkCompatibilityPkg/Sample/Platform/Generic/RuntimeDxe/StatusCode/Lib/Include/BsDataHubStatusCodeLib.h @@ -1,6 +1,6 @@ /*++ -Copyright (c) 2004 - 2005, Intel Corporation +Copyright (c) 2004 - 2007, Intel Corporation All rights reserved. This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -31,6 +31,7 @@ Abstract: // Initialization function // VOID +EFIAPI BsDataHubInitializeStatusCode ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable @@ -41,6 +42,7 @@ BsDataHubInitializeStatusCode ( // Status code reporting function // EFI_STATUS +EFIAPI BsDataHubReportStatusCode ( IN EFI_STATUS_CODE_TYPE CodeType, IN EFI_STATUS_CODE_VALUE Value, diff --git a/EdkCompatibilityPkg/Sample/Platform/Generic/RuntimeDxe/StatusCode/Lib/Include/BsSerialStatusCodeLib.h b/EdkCompatibilityPkg/Sample/Platform/Generic/RuntimeDxe/StatusCode/Lib/Include/BsSerialStatusCodeLib.h index e0403cb8ea..761f0da27d 100644 --- a/EdkCompatibilityPkg/Sample/Platform/Generic/RuntimeDxe/StatusCode/Lib/Include/BsSerialStatusCodeLib.h +++ b/EdkCompatibilityPkg/Sample/Platform/Generic/RuntimeDxe/StatusCode/Lib/Include/BsSerialStatusCodeLib.h @@ -1,6 +1,6 @@ /*++ -Copyright (c) 2004 - 2005, Intel Corporation +Copyright (c) 2004 - 2007, Intel Corporation All rights reserved. This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -31,6 +31,7 @@ Abstract: // Initialization function // VOID +EFIAPI BsSerialInitializeStatusCode ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable @@ -41,6 +42,7 @@ BsSerialInitializeStatusCode ( // Status code reporting function // EFI_STATUS +EFIAPI BsSerialReportStatusCode ( IN EFI_STATUS_CODE_TYPE CodeType, IN EFI_STATUS_CODE_VALUE Value, diff --git a/EdkCompatibilityPkg/Sample/Platform/Generic/RuntimeDxe/StatusCode/Lib/Include/RtMemoryStatusCodeLib.h b/EdkCompatibilityPkg/Sample/Platform/Generic/RuntimeDxe/StatusCode/Lib/Include/RtMemoryStatusCodeLib.h index 3dadc1d2e4..24a74f3357 100644 --- a/EdkCompatibilityPkg/Sample/Platform/Generic/RuntimeDxe/StatusCode/Lib/Include/RtMemoryStatusCodeLib.h +++ b/EdkCompatibilityPkg/Sample/Platform/Generic/RuntimeDxe/StatusCode/Lib/Include/RtMemoryStatusCodeLib.h @@ -1,6 +1,6 @@ /*++ -Copyright (c) 2004 - 2005, Intel Corporation +Copyright (c) 2004 - 2007, Intel Corporation All rights reserved. This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -31,6 +31,7 @@ Abstract: // Initialization function // VOID +EFIAPI RtMemoryInitializeStatusCode ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable @@ -41,6 +42,7 @@ RtMemoryInitializeStatusCode ( // Status code reporting function // EFI_STATUS +EFIAPI RtMemoryReportStatusCode ( IN EFI_STATUS_CODE_TYPE CodeType, IN EFI_STATUS_CODE_VALUE Value, @@ -55,7 +57,7 @@ RtMemoryReportStatusCode ( // typedef EFI_STATUS -(*PLATFORM_REPORT_STATUS_CODE) ( +(EFIAPI *PLATFORM_REPORT_STATUS_CODE) ( IN EFI_STATUS_CODE_TYPE Type, IN EFI_STATUS_CODE_VALUE Value, IN UINT32 Instance, @@ -64,6 +66,7 @@ EFI_STATUS ); VOID +EFIAPI PlaybackStatusCodes ( IN PLATFORM_REPORT_STATUS_CODE ReportStatusCode ) diff --git a/EdkCompatibilityPkg/Sample/Platform/Generic/RuntimeDxe/StatusCode/Lib/Include/RtPlatformStatusCodeLib.h b/EdkCompatibilityPkg/Sample/Platform/Generic/RuntimeDxe/StatusCode/Lib/Include/RtPlatformStatusCodeLib.h index 6979aa1a1b..22f02b763a 100644 --- a/EdkCompatibilityPkg/Sample/Platform/Generic/RuntimeDxe/StatusCode/Lib/Include/RtPlatformStatusCodeLib.h +++ b/EdkCompatibilityPkg/Sample/Platform/Generic/RuntimeDxe/StatusCode/Lib/Include/RtPlatformStatusCodeLib.h @@ -1,6 +1,6 @@ /*++ -Copyright (c) 2004 - 2005, Intel Corporation +Copyright (c) 2004 - 2007, Intel Corporation All rights reserved. This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -32,6 +32,7 @@ Abstract: // Initialization function // VOID +EFIAPI RtPlatformInitializeStatusCode ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable @@ -42,6 +43,7 @@ RtPlatformInitializeStatusCode ( // Status code reporting function // EFI_STATUS +EFIAPI RtPlatformReportStatusCode ( IN EFI_STATUS_CODE_TYPE CodeType, IN EFI_STATUS_CODE_VALUE Value, diff --git a/EdkCompatibilityPkg/Sample/Platform/Generic/RuntimeDxe/StatusCode/Lib/Include/RtPort80StatusCodeLib.h b/EdkCompatibilityPkg/Sample/Platform/Generic/RuntimeDxe/StatusCode/Lib/Include/RtPort80StatusCodeLib.h index 9c57ffb886..854de9b443 100644 --- a/EdkCompatibilityPkg/Sample/Platform/Generic/RuntimeDxe/StatusCode/Lib/Include/RtPort80StatusCodeLib.h +++ b/EdkCompatibilityPkg/Sample/Platform/Generic/RuntimeDxe/StatusCode/Lib/Include/RtPort80StatusCodeLib.h @@ -1,6 +1,6 @@ /*++ -Copyright (c) 2004 - 2005, Intel Corporation +Copyright (c) 2004 - 2007, Intel Corporation All rights reserved. This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -31,6 +31,7 @@ Abstract: // Status code reporting function // EFI_STATUS +EFIAPI RtPort80ReportStatusCode ( IN EFI_STATUS_CODE_TYPE CodeType, IN EFI_STATUS_CODE_VALUE Value, diff --git a/EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/EdkNt32PpiLib.inf b/EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/EdkNt32PpiLib.inf new file mode 100644 index 0000000000..79bba0b2db --- /dev/null +++ b/EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/EdkNt32PpiLib.inf @@ -0,0 +1,53 @@ +/*++ + + Copyright (c) 2004, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + + Module Name: + + EdkNt32PpiLib.inf + + Abstract: + + Component description file for the Edk Nt32 PPI library. + +--*/ + +[defines] +BASE_NAME= EdkNt32PpiLib +COMPONENT_TYPE= LIBRARY + +[includes.common] + $(EDK_SOURCE)\Sample\Platform\Nt32 + $(EDK_SOURCE)\Foundation\Efi + $(EDK_SOURCE)\Foundation\Include + $(EDK_SOURCE)\Foundation\Efi\Include + $(EDK_SOURCE)\Foundation\Framework\Include + $(EDK_SOURCE)\Foundation\Include\IndustryStandard + $(EDK_SOURCE)\Foundation\Include\Pei + $(EDK_SOURCE)\Foundation\Library\Pei\Include + $(EDK_SOURCE)\Foundation\Core\Dxe + $(EDK_SOURCE)\Foundation\Library\Dxe\Include + $(EDK_SOURCE)\Foundation\Framework + +[nmake.common] +C_STD_INCLUDE= + +[sources.common] + NtAutoscan\NtAutoscan.h + NtAutoscan\NtAutoscan.c + NtFwh\NtFwh.h + NtFwh\NtFwh.c + NtLoadAsDll\NtLoadAsDll.h + NtLoadAsDll\NtLoadAsDll.c + NtPeiLoadFile\NtPeiLoadFile.h + NtPeiLoadFile\NtPeiLoadFile.c + NtThunk\NtThunk.h + NtThunk\NtThunk.c diff --git a/EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtAutoscan/NtAutoscan.c b/EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtAutoscan/NtAutoscan.c new file mode 100644 index 0000000000..fc0676f449 --- /dev/null +++ b/EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtAutoscan/NtAutoscan.c @@ -0,0 +1,29 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + NtAutoscan.c + +Abstract: + + Abstraction for the NT Load Image PPI GUID as defined in Tiano + +--*/ + +#include "Tiano.h" +#include "PeiBind.h" +#include "PeiApi.h" +#include EFI_PPI_DEFINITION (NtAutoScan) + +EFI_GUID gPeiNtAutoScanPpiGuid = PEI_NT_AUTOSCAN_PPI_GUID; + +EFI_GUID_STRING(&gPeiNtAutoScanPpiGuid, "NtAutoScan", "NT PEI AUTOSCAN PPI"); diff --git a/EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtAutoscan/NtAutoscan.h b/EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtAutoscan/NtAutoscan.h new file mode 100644 index 0000000000..5351646198 --- /dev/null +++ b/EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtAutoscan/NtAutoscan.h @@ -0,0 +1,67 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + NtAutoscan.h + +Abstract: + +Nt Autoscan PPI + +--*/ + +#ifndef _NT_PEI_AUTOSCAN_H_ +#define _NT_PEI_AUTOSCAN_H_ + +#include "Tiano.h" +#include "PeiHob.h" + +#define PEI_NT_AUTOSCAN_PPI_GUID \ + { \ + 0xdce384d, 0x7c, 0x4ba5, 0x94, 0xbd, 0xf, 0x6e, 0xb6, 0x4d, 0x2a, 0xa9 \ + } + +typedef +EFI_STATUS +(EFIAPI *PEI_NT_AUTOSCAN) ( + IN UINTN Index, + OUT EFI_PHYSICAL_ADDRESS * MemoryBase, + OUT UINT64 *MemorySize + ); + +/*++ + +Routine Description: + This service is called from Index == 0 until it returns EFI_UNSUPPORTED. + It allows discontiguous memory regions to be supported by the emulator. + It uses gSystemMemory[] and gSystemMemoryCount that were created by + parsing the Windows environment variable EFI_MEMORY_SIZE. + The size comes from the varaible and the address comes from the call to + WinNtOpenFile. + +Arguments: + Index - Which memory region to use + MemoryBase - Return Base address of memory region + MemorySize - Return size in bytes of the memory region + +Returns: + EFI_SUCCESS - If memory region was mapped + EFI_UNSUPPORTED - If Index is not supported + +--*/ +typedef struct { + PEI_NT_AUTOSCAN NtAutoScan; +} PEI_NT_AUTOSCAN_PPI; + +extern EFI_GUID gPeiNtAutoScanPpiGuid; + +#endif diff --git a/EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtFwh/NtFwh.c b/EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtFwh/NtFwh.c new file mode 100644 index 0000000000..d4e1f7c055 --- /dev/null +++ b/EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtFwh/NtFwh.c @@ -0,0 +1,29 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + NtFwh.c + +Abstract: + + NT FWH Information PPI GUID as defined in Tiano + +--*/ + +#include "Tiano.h" +#include "PeiBind.h" +#include "PeiApi.h" +#include EFI_PPI_DEFINITION (NtFwh) + +EFI_GUID gNtFwhPpiGuid = NT_FWH_PPI_GUID; + +EFI_GUID_STRING(&gNtFwhPpiGuid, "NtFwh", "NT PEI FWH INFO PPI"); diff --git a/EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtFwh/NtFwh.h b/EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtFwh/NtFwh.h new file mode 100644 index 0000000000..7750db2ce7 --- /dev/null +++ b/EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtFwh/NtFwh.h @@ -0,0 +1,63 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + NtFwh.h + +Abstract: + + WinNt FWH PPI as defined in Tiano + +--*/ + +#ifndef _NT_PEI_FWH_H_ +#define _NT_PEI_FWH_H_ + +#include "Tiano.h" +#include "PeiHob.h" + +#define NT_FWH_PPI_GUID \ + { \ + 0x4e76928f, 0x50ad, 0x4334, 0xb0, 0x6b, 0xa8, 0x42, 0x13, 0x10, 0x8a, 0x57 \ + } + +typedef +EFI_STATUS +(EFIAPI *NT_FWH_INFORMATION) ( + IN UINTN Index, + IN OUT EFI_PHYSICAL_ADDRESS * FdBase, + IN OUT UINT64 *FdSize + ); + +/*++ + +Routine Description: + Return the FD Size and base address. Since the FD is loaded from a + file into Windows memory only the SEC will know it's address. + +Arguments: + Index - Which FD, starts at zero. + FdSize - Size of the FD in bytes + FdBase - Start address of the FD. Assume it points to an FV Header + +Returns: + EFI_SUCCESS - Return the Base address and size of the FV + EFI_UNSUPPORTED - Index does nto map to an FD in the system + +--*/ +typedef struct { + NT_FWH_INFORMATION NtFwh; +} NT_FWH_PPI; + +extern EFI_GUID gNtFwhPpiGuid; + +#endif diff --git a/EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtLoadAsDll/NtLoadAsDll.c b/EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtLoadAsDll/NtLoadAsDll.c new file mode 100644 index 0000000000..ffd8ab8fe2 --- /dev/null +++ b/EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtLoadAsDll/NtLoadAsDll.c @@ -0,0 +1,28 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + NtLoadAsDll.c + +Abstract: + + DXE Initial Program Load PPI GUID as defined in Tiano + +--*/ + +#include "Tiano.h" +#include "Pei.h" +#include EFI_PPI_DEFINITION (NtLoadAsDll) + +EFI_GUID gEfiNtLoadAsDllPpiGuid = EFI_NT_LOAD_AS_DLL_PPI_GUID; + +EFI_GUID_STRING(&gEfiNtLoadAsDllPpiGuid, "NtLoadAsDll", "NT LOAD AS DLL PPI"); diff --git a/EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtLoadAsDll/NtLoadAsDll.h b/EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtLoadAsDll/NtLoadAsDll.h new file mode 100644 index 0000000000..f0062cb678 --- /dev/null +++ b/EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtLoadAsDll/NtLoadAsDll.h @@ -0,0 +1,84 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + NtLoadAsDll.h + +Abstract: + + Nt service Ppi that is used to load PE32s in the NT emulation environment. + +--*/ + +#ifndef _NT_LOAD_AS_DLL_H_ +#define _NT_LOAD_AS_DLL_H_ + +#include "Tiano.h" + +#define EFI_NT_LOAD_AS_DLL_PPI_GUID \ + { \ + 0xccc53f6b, 0xa03a, 0x4ed8, 0x83, 0x9a, 0x3, 0xd9, 0x9c, 0x2, 0xb4, 0xe3 \ + } + +typedef +EFI_STATUS +(EFIAPI *EFI_NT_LOAD_AS_DLL) ( + IN CHAR8 *PdbFileName, + IN VOID **ImageEntryPoint, + OUT VOID **ModHandle + ); + +/*++ + +Routine Description: + Loads the .DLL file is present when a PE/COFF file is loaded. This provides source level + debugging for drivers that have cooresponding .DLL files on the local system. + +Arguments: + PdbFileName - The name of the .PDB file. This was found from the PE/COFF + file's debug directory entry. + ImageEntryPoint - A pointer to the DLL entry point of the .DLL file was loaded. + +Returns: + EFI_SUCCESS - The .DLL file was loaded, and the DLL entry point is returned in ImageEntryPoint + EFI_NOT_FOUND - The .DLL file could not be found + EFI_UNSUPPORTED - The .DLL file was loaded, but the entry point to the .DLL file could not + determined. + +--*/ +typedef +EFI_STATUS +(EFIAPI *EFI_NT_FREE_LIBRARY) ( + IN VOID *ModHandle + ); + +/*++ + +Routine Description: + Free resources allocated by Entry (). ModHandle was returned by + Entry (). + +Arguments: + MohHandle - Handle of the resources to free to undo the work. + +Returns: + EFI_SUCCESS - + +--*/ +typedef struct { + EFI_NT_LOAD_AS_DLL Entry; + EFI_NT_FREE_LIBRARY FreeLibrary; +} EFI_NT_LOAD_AS_DLL_PPI; + +extern EFI_GUID gEfiNtLoadAsDllPpiGuid; + +#endif diff --git a/EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtPeiLoadFile/NtPeiLoadFile.c b/EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtPeiLoadFile/NtPeiLoadFile.c new file mode 100644 index 0000000000..f1feeb7aa2 --- /dev/null +++ b/EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtPeiLoadFile/NtPeiLoadFile.c @@ -0,0 +1,29 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + NtPeiLoadFile.c + +Abstract: + + Abstraction for the NT Load Image PPI GUID as defined in Tiano + +--*/ + +#include "Tiano.h" +#include "PeiBind.h" +#include "PeiApi.h" +#include EFI_PPI_DEFINITION (NtPeiLoadFile) + +EFI_GUID gNtPeiLoadFileGuid = NT_PEI_LOAD_FILE_GUID; + +EFI_GUID_STRING(&gNtPeiLoadFileGuid, "NtPeiLoadFile", "NT PEI LOAD FILE PPI"); diff --git a/EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtPeiLoadFile/NtPeiLoadFile.h b/EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtPeiLoadFile/NtPeiLoadFile.h new file mode 100644 index 0000000000..28f18f46a0 --- /dev/null +++ b/EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtPeiLoadFile/NtPeiLoadFile.h @@ -0,0 +1,66 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + NtPeiLoadFile.h + +Abstract: + + WinNt Load File PPI. + + When the PEI core is done it calls the DXE IPL via PPI + +--*/ + +#ifndef _NT_PEI_LOAD_FILE_H_ +#define _NT_PEI_LOAD_FILE_H_ + +#include "Tiano.h" +#include "PeiHob.h" + +#define NT_PEI_LOAD_FILE_GUID \ + { \ + 0xfd0c65eb, 0x405, 0x4cd2, 0x8a, 0xee, 0xf4, 0x0, 0xef, 0x13, 0xba, 0xc2 \ + } + +typedef +EFI_STATUS +(EFIAPI *NT_PEI_LOAD_FILE) ( + VOID *Pe32Data, + EFI_PHYSICAL_ADDRESS *ImageAddress, + UINT64 *ImageSize, + EFI_PHYSICAL_ADDRESS *EntryPoint + ); + +/*++ + +Routine Description: + Loads and relocates a PE/COFF image into memory. + +Arguments: + Pe32Data - The base address of the PE/COFF file that is to be loaded and relocated + ImageAddress - The base address of the relocated PE/COFF image + ImageSize - The size of the relocated PE/COFF image + EntryPoint - The entry point of the relocated PE/COFF image + +Returns: + EFI_SUCCESS - The file was loaded and relocated + EFI_OUT_OF_RESOURCES - There was not enough memory to load and relocate the PE/COFF file + +--*/ +typedef struct { + NT_PEI_LOAD_FILE PeiLoadFileService; +} NT_PEI_LOAD_FILE_PPI; + +extern EFI_GUID gNtPeiLoadFileGuid; + +#endif diff --git a/EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtThunk/NtThunk.c b/EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtThunk/NtThunk.c new file mode 100644 index 0000000000..5265c10e39 --- /dev/null +++ b/EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtThunk/NtThunk.c @@ -0,0 +1,29 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + NtThunk.c + +Abstract: + + Abstraction for the NT Thunk PPI + +--*/ + +#include "Tiano.h" +#include "PeiBind.h" +#include "PeiApi.h" +#include EFI_PPI_DEFINITION (NtThunk) + +EFI_GUID gPeiNtThunkPpiGuid = PEI_NT_THUNK_GUID; + +EFI_GUID_STRING(&gPeiNtThunkPpiGuid, "NtThunk", "NT PEI WINNT THUNK PPI"); diff --git a/EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtThunk/NtThunk.h b/EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtThunk/NtThunk.h new file mode 100644 index 0000000000..663f5f14ff --- /dev/null +++ b/EdkCompatibilityPkg/Sample/Platform/Nt32/Ppi/NtThunk/NtThunk.h @@ -0,0 +1,59 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + NtThunk.h + +Abstract: + + WinNt Thunk interface PPI + +--*/ + +#ifndef _NT_PEI_WIN_NT_THUNK_H_ +#define _NT_PEI_WIN_NT_THUNK_H_ + +#include "Tiano.h" +#include "PeiHob.h" + +#define PEI_NT_THUNK_GUID \ + { \ + 0x98c281e5, 0xf906, 0x43dd, 0xa9, 0x2b, 0xb0, 0x3, 0xbf, 0x27, 0x65, 0xda \ + } + +typedef +EFI_STATUS +(EFIAPI *PEI_NT_THUNK_INTERFACE) ( + IN OUT UINT64 *InterfaceSize, + IN OUT EFI_PHYSICAL_ADDRESS * InterfaceBase + ); + +/*++ + +Routine Description: + Export of EFI_WIN_NT_THUNK_PROTOCOL from the Windows SEC. + +Arguments: + InterfaceSize - sizeof (EFI_WIN_NT_THUNK_PROTOCOL); + InterfaceBase - Address of the EFI_WIN_NT_THUNK_PROTOCOL + +Returns: + EFI_SUCCESS - Data returned + +--*/ +typedef struct { + PEI_NT_THUNK_INTERFACE NtThunk; +} PEI_NT_THUNK_PPI; + +extern EFI_GUID gPeiNtThunkPpiGuid; + +#endif diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/BootsectImage/bootsectimage.c b/EdkCompatibilityPkg/Sample/Tools/Source/BootsectImage/bootsectimage.c deleted file mode 100644 index d71a03df0b..0000000000 --- a/EdkCompatibilityPkg/Sample/Tools/Source/BootsectImage/bootsectimage.c +++ /dev/null @@ -1,881 +0,0 @@ -/*++ - -Copyright 2006 - 2007, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - bootsectimage.c - -Abstract: - Patch the BPB information in boot sector image file. - Patch the MBR code in MBR image file. - ---*/ - - -#include -#include -#include "fat.h" -#include "mbr.h" -#include "EfiUtilityMsgs.h" - -#define DEBUG_WARN 0x1 -#define DEBUG_ERROR 0x2 -int WriteToFile ( - void *BootSector, - char *FileName - ) -/*++ -Routine Description: - Write 512 bytes boot sector to file. - -Arguments: - BootSector - point to a buffer containing 512 bytes boot sector to write - FileName - file to write to - -Return: - int - number of bytes wrote, - 512 indicates write successful - 0 indicates write failure ---*/ -{ - FILE *FileHandle; - int result; - - FileHandle = fopen (FileName, "r+b"); - if (FileHandle == NULL) { - DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "Open file: %s", FileName); - return 0; - } - fseek (FileHandle, 0, SEEK_SET); - - result = fwrite (BootSector, 1, 512, FileHandle); - if (result != 512) { - DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "Write file: %s", FileName); - result = 0; - } - - fclose (FileHandle); - return result; -} - -int ReadFromFile ( - void *BootSector, - char *FileName - ) -/*++ -Routine Description: - Read first 512 bytes from file. - -Arguments: - BootSector - point to a buffer receiving the first 512 bytes data from file - FileName - file to read from - -Return: - int - number of bytes read, - 512 indicates read successful - 0 indicates read failure ---*/ -{ - FILE *FileHandle; - int result; - - FileHandle = fopen (FileName, "rb"); - if (FileHandle == NULL) { - DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "Open file: %s", FileName); - return 0; - } - - result = fread (BootSector, 1, 512, FileHandle); - if (result != 512) { - DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "Read file: %s", FileName); - result = 0; - } - - fclose (FileHandle); - return result; -} - -char * -FatTypeToString ( - IN FAT_TYPE FatType - ) -/*++ -Routine Description: - Convert enum type of FatType to string ---*/ -{ - switch (FatType) { - case FatTypeFat12: - return "FAT12"; - case FatTypeFat16: - return "FAT16"; - case FatTypeFat32: - return "FAT32"; - default: - break; - } - return "FAT Unknown"; -} - -FAT_TYPE -GetFatType ( - IN FAT_BPB_STRUCT *FatBpb - ) -/*++ -Routine Description: - Determine the FAT type according to BIOS Paramater Block (BPB) data - -Arguments: - FatBpb - BIOS Parameter Block (BPB) data, 512 Bytes - -Return: - FatTypeUnknown - Cannot determine the FAT type - FatTypeFat12 - FAT12 - FatTypeFat16 - FAT16 - FatTypeFat32 - FAT32 ---*/ -{ - FAT_TYPE FatType; - UINTN RootDirSectors; - UINTN FATSz; - UINTN TotSec; - UINTN DataSec; - UINTN CountOfClusters; - CHAR8 FilSysType[9]; - - FatType = FatTypeUnknown; - - // - // Simple check - // - if (FatBpb->Fat12_16.Signature != FAT_BS_SIGNATURE) { - DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT: Signature Invalid - %04x, expected - %04x", - FatBpb->Fat12_16.Signature, FAT_BS_SIGNATURE); - return FatTypeUnknown; - } - - // - // Check according to FAT spec - // - if ((FatBpb->Fat12_16.BS_jmpBoot[0] != FAT_BS_JMP1) && - (FatBpb->Fat12_16.BS_jmpBoot[0] != FAT_BS_JMP2)) { - DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT: BS_jmpBoot - %02x, expected - %02x or %02x", - FatBpb->Fat12_16.BS_jmpBoot[0], FAT_BS_JMP1, FAT_BS_JMP2); - return FatTypeUnknown; - } - - if ((FatBpb->Fat12_16.BPB_BytsPerSec != 512) && - (FatBpb->Fat12_16.BPB_BytsPerSec != 1024) && - (FatBpb->Fat12_16.BPB_BytsPerSec != 2048) && - (FatBpb->Fat12_16.BPB_BytsPerSec != 4096)) { - DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT: BPB_BytsPerSec - %04x, expected - %04x, %04x, %04x, or %04x", - FatBpb->Fat12_16.BPB_BytsPerSec, 512, 1024, 2048, 4096); - return FatTypeUnknown; - } - if (FatBpb->Fat12_16.BPB_BytsPerSec != 512) { - DebugMsg (NULL, 0, DEBUG_WARN, NULL, "FAT: BPB_BytsPerSec - %04x, expected - %04x", - FatBpb->Fat12_16.BPB_BytsPerSec, 512); - } - if ((FatBpb->Fat12_16.BPB_SecPerClus != 1) && - (FatBpb->Fat12_16.BPB_SecPerClus != 2) && - (FatBpb->Fat12_16.BPB_SecPerClus != 4) && - (FatBpb->Fat12_16.BPB_SecPerClus != 8) && - (FatBpb->Fat12_16.BPB_SecPerClus != 16) && - (FatBpb->Fat12_16.BPB_SecPerClus != 32) && - (FatBpb->Fat12_16.BPB_SecPerClus != 64) && - (FatBpb->Fat12_16.BPB_SecPerClus != 128)) { - DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT: BPB_SecPerClus - %02x, expected - %02x, %02x, %02x, %02x, %02x, %02x, %02x, or %02x", - FatBpb->Fat12_16.BPB_BytsPerSec, 1, 2, 4, 8, 16, 32, 64, 128); - return FatTypeUnknown; - } - if (FatBpb->Fat12_16.BPB_BytsPerSec * FatBpb->Fat12_16.BPB_SecPerClus > 32 * 1024) { - DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT: BPB_BytsPerSec * BPB_SecPerClus - %08x, expected <= %08x", - FatBpb->Fat12_16.BPB_BytsPerSec * FatBpb->Fat12_16.BPB_SecPerClus, 32 * 1024); - return FatTypeUnknown; - } - if (FatBpb->Fat12_16.BPB_RsvdSecCnt == 0) { - DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT: BPB_RsvdSecCnt - %04x, expected - Non-Zero", - FatBpb->Fat12_16.BPB_RsvdSecCnt); - return FatTypeUnknown; - } - if (FatBpb->Fat12_16.BPB_NumFATs != 2) { - DebugMsg (NULL, 0, DEBUG_WARN, NULL, "FAT: BPB_NumFATs - %02x, expected - %02x", - FatBpb->Fat12_16.BPB_NumFATs, 2); - } - if ((FatBpb->Fat12_16.BPB_Media != 0xF0) && - (FatBpb->Fat12_16.BPB_Media != 0xF8) && - (FatBpb->Fat12_16.BPB_Media != 0xF9) && - (FatBpb->Fat12_16.BPB_Media != 0xFA) && - (FatBpb->Fat12_16.BPB_Media != 0xFB) && - (FatBpb->Fat12_16.BPB_Media != 0xFC) && - (FatBpb->Fat12_16.BPB_Media != 0xFD) && - (FatBpb->Fat12_16.BPB_Media != 0xFE) && - (FatBpb->Fat12_16.BPB_Media != 0xFF)) { - DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT: BPB_Media - %02x, expected - %02x, %02x, %02x, %02x, %02x, %02x, %02x, %02x, or %02x", - FatBpb->Fat12_16.BPB_Media, 0xF0, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF); - return FatTypeUnknown; - } - - // - // Algo in FAT spec - // - RootDirSectors = ((FatBpb->Fat12_16.BPB_RootEntCnt * sizeof(FAT_DIRECTORY_ENTRY)) + - (FatBpb->Fat12_16.BPB_BytsPerSec - 1)) / - FatBpb->Fat12_16.BPB_BytsPerSec; - - if (FatBpb->Fat12_16.BPB_FATSz16 != 0) { - FATSz = FatBpb->Fat12_16.BPB_FATSz16; - } else { - FATSz = FatBpb->Fat32.BPB_FATSz32; - } - if (FATSz == 0) { - DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT: BPB_FATSz16, BPB_FATSz32 - 0, expected - Non-Zero"); - return FatTypeUnknown; - } - - if (FatBpb->Fat12_16.BPB_TotSec16 != 0) { - TotSec = FatBpb->Fat12_16.BPB_TotSec16; - } else { - TotSec = FatBpb->Fat12_16.BPB_TotSec32; - } - if (TotSec == 0) { - DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT: BPB_TotSec16, BPB_TotSec32 - 0, expected - Non-Zero"); - return FatTypeUnknown; - } - - DataSec = TotSec - ( - FatBpb->Fat12_16.BPB_RsvdSecCnt + - FatBpb->Fat12_16.BPB_NumFATs * FATSz + - RootDirSectors - ); - - CountOfClusters = DataSec / FatBpb->Fat12_16.BPB_SecPerClus; - - if (CountOfClusters < FAT_MAX_FAT12_CLUSTER) { - FatType = FatTypeFat12; - } else if (CountOfClusters < FAT_MAX_FAT16_CLUSTER) { - FatType = FatTypeFat16; - } else { - FatType = FatTypeFat32; - } - // - // Check according to FAT spec - // - if (((FatType == FatTypeFat12) || (FatType == FatTypeFat16)) && - (FatBpb->Fat12_16.BPB_RsvdSecCnt != 1)) { - DebugMsg (NULL, 0, DEBUG_WARN, NULL, "FAT12_16: BPB_RsvdSecCnt - %04x, expected - %04x", - FatBpb->Fat12_16.BPB_RsvdSecCnt, 1); - } - if ((FatType == FatTypeFat32) && - (FatBpb->Fat12_16.BPB_RsvdSecCnt != 32)) { - DebugMsg (NULL, 0, DEBUG_WARN, NULL, "FAT32: BPB_RsvdSecCnt - %04x, expected - %04x", - FatBpb->Fat12_16.BPB_RsvdSecCnt, 32); - } - if ((FatType == FatTypeFat16) && - (FatBpb->Fat12_16.BPB_RootEntCnt != 512)) { - printf ("WARNING: FAT16: BPB_RootEntCnt - %04x, expected - %04x\n", - FatBpb->Fat12_16.BPB_RootEntCnt, 512); - } - if ((FatType == FatTypeFat32) && - (FatBpb->Fat12_16.BPB_RootEntCnt != 0)) { - DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT32: BPB_RootEntCnt - %04x, expected - %04x", - FatBpb->Fat12_16.BPB_RootEntCnt, 0); - return FatTypeUnknown; - } - if ((FatType == FatTypeFat32) && - (FatBpb->Fat12_16.BPB_TotSec16 != 0)) { - DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT32: BPB_TotSec16 - %04x, expected - %04x", - FatBpb->Fat12_16.BPB_TotSec16, 0); - return FatTypeUnknown; - } - if ((FatType == FatTypeFat32) && - (FatBpb->Fat12_16.BPB_FATSz16 != 0)) { - DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT32: BPB_FATSz16 - %04x, expected - %04x", - FatBpb->Fat12_16.BPB_FATSz16, 0); - return FatTypeUnknown; - } - if ((FatType == FatTypeFat32) && - (FatBpb->Fat12_16.BPB_TotSec32 == 0)) { - DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT32: BPB_TotSec32 - %04x, expected - Non-Zero", - FatBpb->Fat12_16.BPB_TotSec32); - return FatTypeUnknown; - } - if ((FatType == FatTypeFat32) && - (FatBpb->Fat32.BPB_FATSz32 == 0)) { - DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT32: BPB_FATSz32 - %08x, expected - Non-Zero", - FatBpb->Fat32.BPB_FATSz32); - return FatTypeUnknown; - } - if ((FatType == FatTypeFat32) && - (FatBpb->Fat32.BPB_FSVer != 0)) { - DebugMsg (NULL, 0, DEBUG_WARN, NULL, "FAT32: BPB_FSVer - %08x, expected - %04x", - FatBpb->Fat32.BPB_FSVer, 0); - } - if ((FatType == FatTypeFat32) && - (FatBpb->Fat32.BPB_RootClus != 2)) { - DebugMsg (NULL, 0, DEBUG_WARN, NULL, "FAT32: BPB_RootClus - %08x, expected - %04x", - FatBpb->Fat32.BPB_RootClus, 2); - } - if ((FatType == FatTypeFat32) && - (FatBpb->Fat32.BPB_FSInfo != 1)) { - DebugMsg (NULL, 0, DEBUG_WARN, NULL, "FAT32: BPB_FSInfo - %08x, expected - %04x", - FatBpb->Fat32.BPB_FSInfo, 1); - } - if ((FatType == FatTypeFat32) && - (FatBpb->Fat32.BPB_BkBootSec != 6)) { - DebugMsg (NULL, 0, DEBUG_WARN, NULL, "FAT32: BPB_BkBootSec - %08x, expected - %04x", - FatBpb->Fat32.BPB_BkBootSec, 6); - } - if ((FatType == FatTypeFat32) && - ((*(UINT32 *)FatBpb->Fat32.BPB_Reserved != 0) || - (*((UINT32 *)FatBpb->Fat32.BPB_Reserved + 1) != 0) || - (*((UINT32 *)FatBpb->Fat32.BPB_Reserved + 2) != 0))) { - DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT32: BPB_Reserved - %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x, expected - 0", - FatBpb->Fat32.BPB_Reserved[0], - FatBpb->Fat32.BPB_Reserved[1], - FatBpb->Fat32.BPB_Reserved[2], - FatBpb->Fat32.BPB_Reserved[3], - FatBpb->Fat32.BPB_Reserved[4], - FatBpb->Fat32.BPB_Reserved[5], - FatBpb->Fat32.BPB_Reserved[6], - FatBpb->Fat32.BPB_Reserved[7], - FatBpb->Fat32.BPB_Reserved[8], - FatBpb->Fat32.BPB_Reserved[9], - FatBpb->Fat32.BPB_Reserved[10], - FatBpb->Fat32.BPB_Reserved[11]); - return FatTypeUnknown; - } - if (((FatType == FatTypeFat12) || (FatType == FatTypeFat16)) && - (FatBpb->Fat12_16.BS_Reserved1 != 0)) { - DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT12_16: BS_Reserved1 - %02x, expected - 0\n", - FatBpb->Fat12_16.BS_Reserved1); - return FatTypeUnknown; - } - if ((FatType == FatTypeFat32) && - (FatBpb->Fat32.BS_Reserved1 != 0)) { - DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT32: BS_Reserved1 - %02x, expected - 0\n", - FatBpb->Fat32.BS_Reserved1); - return FatTypeUnknown; - } - if (((FatType == FatTypeFat12) || (FatType == FatTypeFat16)) && - (FatBpb->Fat12_16.BS_BootSig != FAT_BS_BOOTSIG)) { - DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT12_16: BS_BootSig - %02x, expected - %02x\n", - FatBpb->Fat12_16.BS_BootSig, FAT_BS_BOOTSIG); - return FatTypeUnknown; - } - if ((FatType == FatTypeFat32) && - (FatBpb->Fat32.BS_BootSig != FAT_BS_BOOTSIG)) { - DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT32: BS_BootSig - %02x, expected - %02x\n", - FatBpb->Fat32.BS_BootSig, FAT_BS_BOOTSIG); - return FatTypeUnknown; - } - - if ((FatType == FatTypeFat12) || (FatType == FatTypeFat16)) { - memcpy (FilSysType, FatBpb->Fat12_16.BS_FilSysType, 8); - FilSysType[8] = 0; - if ((FatType == FatTypeFat12) && - (strcmp (FilSysType, FAT12_FILSYSTYPE) != 0) && - (strcmp (FilSysType, FAT_FILSYSTYPE) != 0)) { - DebugMsg (NULL, 0, DEBUG_WARN, NULL, "FAT12: BS_FilSysType - %s, expected - %s, or %s\n", - FilSysType, FAT12_FILSYSTYPE, FAT_FILSYSTYPE); - } - if ((FatType == FatTypeFat16) && - (strcmp (FilSysType, FAT16_FILSYSTYPE) != 0) && - (strcmp (FilSysType, FAT_FILSYSTYPE) != 0)) { - DebugMsg (NULL, 0, DEBUG_WARN, NULL, "FAT16: BS_FilSysType - %s, expected - %s, or %s\n", - FilSysType, FAT16_FILSYSTYPE, FAT_FILSYSTYPE); - } - } - if (FatType == FatTypeFat32) { - memcpy (FilSysType, FatBpb->Fat32.BS_FilSysType, 8); - FilSysType[8] = 0; - if (strcmp (FilSysType, FAT32_FILSYSTYPE) != 0) { - DebugMsg (NULL, 0, DEBUG_WARN, NULL, "FAT32: BS_FilSysType - %s, expected - %s\n", - FilSysType, FAT32_FILSYSTYPE); - } - } - - // - // pass all check, get FAT type - // - return FatType; -} - - -void -ParseBootSector ( - char *FileName - ) -{ - FAT_BPB_STRUCT FatBpb; - FAT_TYPE FatType; - - if (ReadFromFile ((void *)&FatBpb, FileName) == 0) { - return ; - } - - FatType = GetFatType (&FatBpb); - if (FatType <= FatTypeUnknown || FatType >= FatTypeMax) { - printf ("ERROR: Unknown Fat Type!\n"); - return; - } - - printf ("\nBoot Sector %s:\n", FatTypeToString (FatType)); - printf ("\n"); - printf (" Offset Title Data\n"); - printf ("==================================================================\n"); - printf (" 0 JMP instruction %02x %02x %02x\n", - FatBpb.Fat12_16.BS_jmpBoot[0], - FatBpb.Fat12_16.BS_jmpBoot[1], - FatBpb.Fat12_16.BS_jmpBoot[2]); - printf (" 3 OEM %c%c%c%c%c%c%c%c\n", - FatBpb.Fat12_16.BS_OEMName[0], - FatBpb.Fat12_16.BS_OEMName[1], - FatBpb.Fat12_16.BS_OEMName[2], - FatBpb.Fat12_16.BS_OEMName[3], - FatBpb.Fat12_16.BS_OEMName[4], - FatBpb.Fat12_16.BS_OEMName[5], - FatBpb.Fat12_16.BS_OEMName[6], - FatBpb.Fat12_16.BS_OEMName[7]); - printf ("\n"); - printf ("BIOS Parameter Block\n"); - printf (" B Bytes per sector %04x\n", FatBpb.Fat12_16.BPB_BytsPerSec); - printf (" D Sectors per cluster %02x\n", FatBpb.Fat12_16.BPB_SecPerClus); - printf (" E Reserved sectors %04x\n", FatBpb.Fat12_16.BPB_RsvdSecCnt); - printf (" 10 Number of FATs %02x\n", FatBpb.Fat12_16.BPB_NumFATs); - printf (" 11 Root entries %04x\n", FatBpb.Fat12_16.BPB_RootEntCnt); - printf (" 13 Sectors (under 32MB) %04x\n", FatBpb.Fat12_16.BPB_TotSec16); - printf (" 15 Media descriptor %02x\n", FatBpb.Fat12_16.BPB_Media); - printf (" 16 Sectors per FAT (small vol.) %04x\n", FatBpb.Fat12_16.BPB_FATSz16); - printf (" 18 Sectors per track %04x\n", FatBpb.Fat12_16.BPB_SecPerTrk); - printf (" 1A Heads %04x\n", FatBpb.Fat12_16.BPB_NumHeads); - printf (" 1C Hidden sectors %08x\n", FatBpb.Fat12_16.BPB_HiddSec); - printf (" 20 Sectors (over 32MB) %08x\n", FatBpb.Fat12_16.BPB_TotSec32); - printf ("\n"); - if (FatType != FatTypeFat32) { - printf (" 24 BIOS drive %02x\n", FatBpb.Fat12_16.BS_DrvNum); - printf (" 25 (Unused) %02x\n", FatBpb.Fat12_16.BS_Reserved1); - printf (" 26 Ext. boot signature %02x\n", FatBpb.Fat12_16.BS_BootSig); - printf (" 27 Volume serial number %08x\n", FatBpb.Fat12_16.BS_VolID); - printf (" 2B Volume lable %c%c%c%c%c%c%c%c%c%c%c\n", - FatBpb.Fat12_16.BS_VolLab[0], - FatBpb.Fat12_16.BS_VolLab[1], - FatBpb.Fat12_16.BS_VolLab[2], - FatBpb.Fat12_16.BS_VolLab[3], - FatBpb.Fat12_16.BS_VolLab[4], - FatBpb.Fat12_16.BS_VolLab[5], - FatBpb.Fat12_16.BS_VolLab[6], - FatBpb.Fat12_16.BS_VolLab[7], - FatBpb.Fat12_16.BS_VolLab[8], - FatBpb.Fat12_16.BS_VolLab[9], - FatBpb.Fat12_16.BS_VolLab[10]); - printf (" 36 File system %c%c%c%c%c%c%c%c\n", - FatBpb.Fat12_16.BS_FilSysType[0], - FatBpb.Fat12_16.BS_FilSysType[1], - FatBpb.Fat12_16.BS_FilSysType[2], - FatBpb.Fat12_16.BS_FilSysType[3], - FatBpb.Fat12_16.BS_FilSysType[4], - FatBpb.Fat12_16.BS_FilSysType[5], - FatBpb.Fat12_16.BS_FilSysType[6], - FatBpb.Fat12_16.BS_FilSysType[7]); - printf ("\n"); - } else { - printf ("FAT32 Section\n"); - printf (" 24 Sectors per FAT (large vol.) %08x\n", FatBpb.Fat32.BPB_FATSz32); - printf (" 28 Flags %04x\n", FatBpb.Fat32.BPB_ExtFlags); - printf (" 2A Version %04x\n", FatBpb.Fat32.BPB_FSVer); - printf (" 2C Root dir 1st cluster %08x\n", FatBpb.Fat32.BPB_RootClus); - printf (" 30 FSInfo sector %04x\n", FatBpb.Fat32.BPB_FSInfo); - printf (" 32 Backup boot sector %04x\n", FatBpb.Fat32.BPB_BkBootSec); - printf (" 34 (Reserved) %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", - FatBpb.Fat32.BPB_Reserved[0], - FatBpb.Fat32.BPB_Reserved[1], - FatBpb.Fat32.BPB_Reserved[2], - FatBpb.Fat32.BPB_Reserved[3], - FatBpb.Fat32.BPB_Reserved[4], - FatBpb.Fat32.BPB_Reserved[5], - FatBpb.Fat32.BPB_Reserved[6], - FatBpb.Fat32.BPB_Reserved[7], - FatBpb.Fat32.BPB_Reserved[8], - FatBpb.Fat32.BPB_Reserved[9], - FatBpb.Fat32.BPB_Reserved[10], - FatBpb.Fat32.BPB_Reserved[11]); - printf ("\n"); - printf (" 40 BIOS drive %02x\n", FatBpb.Fat32.BS_DrvNum); - printf (" 41 (Unused) %02x\n", FatBpb.Fat32.BS_Reserved1); - printf (" 42 Ext. boot signature %02x\n", FatBpb.Fat32.BS_BootSig); - printf (" 43 Volume serial number %08x\n", FatBpb.Fat32.BS_VolID); - printf (" 47 Volume lable %c%c%c%c%c%c%c%c%c%c%c\n", - FatBpb.Fat32.BS_VolLab[0], - FatBpb.Fat32.BS_VolLab[1], - FatBpb.Fat32.BS_VolLab[2], - FatBpb.Fat32.BS_VolLab[3], - FatBpb.Fat32.BS_VolLab[4], - FatBpb.Fat32.BS_VolLab[5], - FatBpb.Fat32.BS_VolLab[6], - FatBpb.Fat32.BS_VolLab[7], - FatBpb.Fat32.BS_VolLab[8], - FatBpb.Fat32.BS_VolLab[9], - FatBpb.Fat32.BS_VolLab[10]); - printf (" 52 File system %c%c%c%c%c%c%c%c\n", - FatBpb.Fat32.BS_FilSysType[0], - FatBpb.Fat32.BS_FilSysType[1], - FatBpb.Fat32.BS_FilSysType[2], - FatBpb.Fat32.BS_FilSysType[3], - FatBpb.Fat32.BS_FilSysType[4], - FatBpb.Fat32.BS_FilSysType[5], - FatBpb.Fat32.BS_FilSysType[6], - FatBpb.Fat32.BS_FilSysType[7]); - printf ("\n"); - } - printf (" 1FE Signature %04x\n", FatBpb.Fat12_16.Signature); - printf ("\n"); - - - return ; -} - -void -PatchBootSector ( - char *DestFileName, - char *SourceFileName, - BOOL ForcePatch - ) -/*++ -Routine Description: - Patch destination file according to the information from source file. - Only patch BPB data but leave boot code un-touched. - -Arguments: - DestFileName - Destination file to patch - SourceFileName - Source file where patch from ---*/ -{ - FAT_BPB_STRUCT DestFatBpb; - FAT_BPB_STRUCT SourceFatBpb; - FAT_TYPE DestFatType; - FAT_TYPE SourceFatType; - CHAR8 VolLab[11]; - CHAR8 FilSysType[8]; - - if (ReadFromFile ((void *)&DestFatBpb, DestFileName) == 0) { - return ; - } - if (ReadFromFile ((void *)&SourceFatBpb, SourceFileName) == 0) { - return ; - } - - DestFatType = GetFatType (&DestFatBpb); - SourceFatType = GetFatType (&SourceFatBpb); - - if (DestFatType != SourceFatType) { - // - // FAT type mismatch - // - if (ForcePatch) { - DebugMsg (NULL, 0, DEBUG_WARN, NULL, "FAT type mismatch: Dest - %s, Source - %s", - FatTypeToString(DestFatType), FatTypeToString(SourceFatType)); - } else { - DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT type mismatch: Dest - %s, Source - %s", - FatTypeToString(DestFatType), FatTypeToString(SourceFatType)); - return ; - } - } - - if (SourceFatType <= FatTypeUnknown || SourceFatType >= FatTypeMax) { - DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "Unknown Fat Type!\n"); - return; - } - - // - // Copy BPB/boot data (excluding BS_jmpBoot, BS_OEMName, BootCode and Signature) from SourceFatBpb to DestFatBpb - // - printf ("Patching %s BPB: ", FatTypeToString (SourceFatType)); - if (SourceFatType != FatTypeFat32) { - memcpy ( - &DestFatBpb.Fat12_16.BPB_BytsPerSec, - &SourceFatBpb.Fat12_16.BPB_BytsPerSec, - ((UINTN)&DestFatBpb.Fat12_16.Reserved - (UINTN)&DestFatBpb.Fat12_16.BPB_BytsPerSec) - ); - } else { - memcpy ( - &DestFatBpb.Fat32.BPB_BytsPerSec, - &SourceFatBpb.Fat32.BPB_BytsPerSec, - ((UINTN)&DestFatBpb.Fat32.Reserved - (UINTN)&DestFatBpb.Fat32.BPB_BytsPerSec) - ); - } - - // - // Set BS_VolLab and BS_FilSysType of DestFatBpb - // - // BS_VolLab BS_FilSysType - // FAT12: EFI FAT12 FAT12 - // FAT16: EFI FAT16 FAT16 - // FAT32: EFI FAT32 FAT32 - // - if (SourceFatType == FatTypeFat32) { - memcpy (VolLab, "EFI FAT32 ", sizeof(VolLab)); - memcpy (FilSysType, FAT32_FILSYSTYPE, sizeof(FilSysType)); - } else if (SourceFatType == FatTypeFat16) { - memcpy (VolLab, "EFI FAT16 ", sizeof(VolLab)); - memcpy (FilSysType, FAT16_FILSYSTYPE, sizeof(FilSysType)); - } else { - memcpy (VolLab, "EFI FAT12 ", sizeof(VolLab)); - memcpy (FilSysType, FAT12_FILSYSTYPE, sizeof(FilSysType)); - } - if (SourceFatType != FatTypeFat32) { - memcpy (DestFatBpb.Fat12_16.BS_VolLab, VolLab, sizeof(VolLab)); - memcpy (DestFatBpb.Fat12_16.BS_FilSysType, FilSysType, sizeof(FilSysType)); - } else { - memcpy (DestFatBpb.Fat32.BS_VolLab, VolLab, sizeof(VolLab)); - memcpy (DestFatBpb.Fat32.BS_FilSysType, FilSysType, sizeof(FilSysType)); - } - - // - // Set Signature of DestFatBpb to 55AA - // - DestFatBpb.Fat12_16.Signature = FAT_BS_SIGNATURE; - - // - // Write DestFatBpb - // - if (WriteToFile ((void *)&DestFatBpb, DestFileName)) { - printf ("successfully!\n"); - } else { - printf ("failed!\n"); - } - - return ; -} - -void -ParseMbr ( - char *FileName - ) -{ - MASTER_BOOT_RECORD Mbr; - - if (ReadFromFile ((void *)&Mbr, FileName) == 0) { - return ; - } - - printf ("\nMaster Boot Record:\n"); - printf ("\n"); - printf (" Offset Title Value\n"); - printf ("==================================================================\n"); - printf (" 0 Master bootstrap loader code (not list)\n"); - printf (" 1B8 Windows disk signature %08x\n", Mbr.UniqueMbrSignature); - printf ("\n"); - printf ("Partition Table Entry #1\n"); - printf (" 1BE 80 = active partition %02x\n", Mbr.PartitionRecord[0].BootIndicator); - printf (" 1BF Start head %02x\n", Mbr.PartitionRecord[0].StartHead); - printf (" 1C0 Start sector %02x\n", Mbr.PartitionRecord[0].StartSector); - printf (" 1C1 Start cylinder %02x\n", Mbr.PartitionRecord[0].StartTrack); - printf (" 1C2 Partition type indicator %02x\n", Mbr.PartitionRecord[0].OSType); - printf (" 1C3 End head %02x\n", Mbr.PartitionRecord[0].EndHead); - printf (" 1C4 End sector %02x\n", Mbr.PartitionRecord[0].EndSector); - printf (" 1C5 End cylinder %02x\n", Mbr.PartitionRecord[0].EndTrack); - printf (" 1C6 Sectors preceding partition %08x\n", Mbr.PartitionRecord[0].StartingLBA); - printf (" 1CA Sectors in partition %08x\n", Mbr.PartitionRecord[0].SizeInLBA); - printf ("\n"); - printf ("Partition Table Entry #2\n"); - printf (" 1CE 80 = active partition %02x\n", Mbr.PartitionRecord[1].BootIndicator); - printf (" 1CF Start head %02x\n", Mbr.PartitionRecord[1].StartHead); - printf (" 1D0 Start sector %02x\n", Mbr.PartitionRecord[1].StartSector); - printf (" 1D1 Start cylinder %02x\n", Mbr.PartitionRecord[1].StartTrack); - printf (" 1D2 Partition type indicator %02x\n", Mbr.PartitionRecord[1].OSType); - printf (" 1D3 End head %02x\n", Mbr.PartitionRecord[1].EndHead); - printf (" 1D4 End sector %02x\n", Mbr.PartitionRecord[1].EndSector); - printf (" 1D5 End cylinder %02x\n", Mbr.PartitionRecord[1].EndTrack); - printf (" 1D6 Sectors preceding partition %08x\n", Mbr.PartitionRecord[1].StartingLBA); - printf (" 1DA Sectors in partition %08x\n", Mbr.PartitionRecord[1].SizeInLBA); - printf ("\n"); - printf ("Partition Table Entry #3\n"); - printf (" 1DE 80 = active partition %02x\n", Mbr.PartitionRecord[2].BootIndicator); - printf (" 1DF Start head %02x\n", Mbr.PartitionRecord[2].StartHead); - printf (" 1E0 Start sector %02x\n", Mbr.PartitionRecord[2].StartSector); - printf (" 1E1 Start cylinder %02x\n", Mbr.PartitionRecord[2].StartTrack); - printf (" 1E2 Partition type indicator %02x\n", Mbr.PartitionRecord[2].OSType); - printf (" 1E3 End head %02x\n", Mbr.PartitionRecord[2].EndHead); - printf (" 1E4 End sector %02x\n", Mbr.PartitionRecord[2].EndSector); - printf (" 1E5 End cylinder %02x\n", Mbr.PartitionRecord[2].EndTrack); - printf (" 1E6 Sectors preceding partition %08x\n", Mbr.PartitionRecord[2].StartingLBA); - printf (" 1EA Sectors in partition %08x\n", Mbr.PartitionRecord[2].SizeInLBA); - printf ("\n"); - printf ("Partition Table Entry #4\n"); - printf (" 1EE 80 = active partition %02x\n", Mbr.PartitionRecord[3].BootIndicator); - printf (" 1EF Start head %02x\n", Mbr.PartitionRecord[3].StartHead); - printf (" 1F0 Start sector %02x\n", Mbr.PartitionRecord[3].StartSector); - printf (" 1F1 Start cylinder %02x\n", Mbr.PartitionRecord[3].StartTrack); - printf (" 1F2 Partition type indicator %02x\n", Mbr.PartitionRecord[3].OSType); - printf (" 1F3 End head %02x\n", Mbr.PartitionRecord[3].EndHead); - printf (" 1F4 End sector %02x\n", Mbr.PartitionRecord[3].EndSector); - printf (" 1F5 End cylinder %02x\n", Mbr.PartitionRecord[3].EndTrack); - printf (" 1F6 Sectors preceding partition %08x\n", Mbr.PartitionRecord[3].StartingLBA); - printf (" 1FA Sectors in partition %08x\n", Mbr.PartitionRecord[3].SizeInLBA); - printf ("\n"); - printf (" 1FE Signature %04x\n", Mbr.Signature); - printf ("\n"); - - return ; -} - -void -PatchMbr ( - char *DestFileName, - char *SourceFileName - ) -{ - MASTER_BOOT_RECORD DestMbr; - MASTER_BOOT_RECORD SourceMbr; - - if (ReadFromFile ((void *)&DestMbr, DestFileName) == 0) { - return ; - } - if (ReadFromFile ((void *)&SourceMbr, SourceFileName) == 0) { - return ; - } - - if (SourceMbr.Signature != MBR_SIGNATURE) { - printf ("ERROR: Invalid MBR!\n"); - return; - } - - printf ("Patching MBR:\n"); - memcpy ( - &DestMbr.PartitionRecord[0], - &SourceMbr.PartitionRecord[0], - sizeof(DestMbr.PartitionRecord) - ); - - DestMbr.Signature = MBR_SIGNATURE; - - - if (WriteToFile ((void *)&DestMbr, DestFileName)) { - printf ("\tsuccessfully!\n"); - } - - return ; -} - -void -PrintUsage ( - void - ) -{ - printf ( - "Usage:\n" - "bootsectimage [-m] [-v] -p SrcImage\n" - "bootsectimage [-m] [-v] [-f] -g SrcImage DstImage\n" - "where\n" - " -p: parse SrcImage\n" - " -g: get info from SrcImage, and patch to DstImage\n" - " -f: force patch even FAT type of SrcImage and DstImage mismatch\n" - " -m: process MBR instead of boot sector\n" - " -v: verbose\n" - ); -} - -int -main ( - int argc, - char *argv[] - ) -{ - char *SrcImage; - char *DstImage; - BOOL ForcePatch; // -f - BOOL ProcessMbr; // -m - BOOL DoParse; // -p SrcImage or -g SrcImage DstImage - BOOL Verbose; // -v - - SrcImage = DstImage = NULL; - ForcePatch = FALSE; - ProcessMbr = FALSE; - DoParse = TRUE; - Verbose = FALSE; - - SetUtilityName ("bootsectimage"); - - argc--; argv++; - - if (argc == 0) { - PrintUsage (); - return -1; - } - - while (argc != 0) { - if (strcmp (*argv, "-f") == 0) { - ForcePatch = TRUE; - } else if (strcmp (*argv, "-p") == 0) { - DoParse = TRUE; - argc--; argv++; - if (argc < 1) { - PrintUsage (); - return -1; - } - SrcImage = *argv; - } else if (strcmp (*argv, "-g") == 0) { - DoParse = FALSE; - argc--; argv++; - if (argc < 2) { - PrintUsage (); - return -1; - } - SrcImage = *argv; - argc--; argv++; - DstImage = *argv; - } else if (strcmp (*argv, "-m") == 0) { - ProcessMbr = TRUE; - } else if (strcmp (*argv, "-v") == 0) { - Verbose = TRUE; - } else { - PrintUsage (); - return -1; - } - - argc--; argv++; - } - - if (ForcePatch && DoParse) { - printf ("Cannot apply force(-f) to parse(-p)!\n"); - PrintUsage (); - return -1; - } - if (ForcePatch && !DoParse && ProcessMbr) { - printf ("Cannot apply force(-f) to processing MBR (-g -m)!\n"); - PrintUsage (); - return -1; - } - - if (Verbose) { - SetDebugMsgMask (DEBUG_WARN | DEBUG_ERROR); - } else { - SetDebugMsgMask (0); - } - - if (DoParse) { - if (ProcessMbr) { - ParseMbr (SrcImage); - } else { - ParseBootSector (SrcImage); - } - } else { - if (ProcessMbr) { - PatchMbr (DstImage, SrcImage); - } else { - PatchBootSector (DstImage, SrcImage, ForcePatch); - } - } - - return 0; -} - diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/BootsectImage/fat.h b/EdkCompatibilityPkg/Sample/Tools/Source/BootsectImage/fat.h deleted file mode 100644 index 330312688b..0000000000 --- a/EdkCompatibilityPkg/Sample/Tools/Source/BootsectImage/fat.h +++ /dev/null @@ -1,158 +0,0 @@ -/*++ - -Copyright 2006, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - fat.h - -Abstract: - -Revision History - ---*/ - -#ifndef _FAT_BPB_H_ -#define _FAT_BPB_H_ - -#include "Tiano.h" - -#pragma pack(1) - -typedef struct { - // - // Fat common field - // - UINT8 BS_jmpBoot[3]; - CHAR8 BS_OEMName[8]; - UINT16 BPB_BytsPerSec; - UINT8 BPB_SecPerClus; - UINT16 BPB_RsvdSecCnt; - UINT8 BPB_NumFATs; - UINT16 BPB_RootEntCnt; - UINT16 BPB_TotSec16; - UINT8 BPB_Media; - UINT16 BPB_FATSz16; - UINT16 BPB_SecPerTrk; - UINT16 BPB_NumHeads; - UINT32 BPB_HiddSec; - UINT32 BPB_TotSec32; - - // - // Fat12/16 specific field - // - UINT8 BS_DrvNum; - UINT8 BS_Reserved1; - UINT8 BS_BootSig; - UINT32 BS_VolID; - CHAR8 BS_VolLab[11]; - CHAR8 BS_FilSysType[8]; - - // - // Boot Code and Data - // - UINT8 Reserved[448]; - - // - // Fat common signature - 0xAA55 - // - UINT16 Signature; -} FAT12_16_BPB_STRUCT; - -typedef struct { - // - // Fat common field - // - UINT8 BS_jmpBoot[3]; - CHAR8 BS_OEMName[8]; - UINT16 BPB_BytsPerSec; - UINT8 BPB_SecPerClus; - UINT16 BPB_RsvdSecCnt; - UINT8 BPB_NumFATs; - UINT16 BPB_RootEntCnt; - UINT16 BPB_TotSec16; - UINT8 BPB_Media; - UINT16 BPB_FATSz16; - UINT16 BPB_SecPerTrk; - UINT16 BPB_NumHeads; - UINT32 BPB_HiddSec; - UINT32 BPB_TotSec32; - - // - // Fat32 specific field - // - UINT32 BPB_FATSz32; - UINT16 BPB_ExtFlags; - UINT16 BPB_FSVer; - UINT32 BPB_RootClus; - UINT16 BPB_FSInfo; - UINT16 BPB_BkBootSec; - UINT8 BPB_Reserved[12]; - UINT8 BS_DrvNum; - UINT8 BS_Reserved1; - UINT8 BS_BootSig; - UINT32 BS_VolID; - CHAR8 BS_VolLab[11]; - CHAR8 BS_FilSysType[8]; - - // - // Boot Code and Data - // - UINT8 Reserved[420]; - - // - // Fat common signature - 0xAA55 - // - UINT16 Signature; -} FAT32_BPB_STRUCT; - -typedef union { - FAT12_16_BPB_STRUCT Fat12_16; - FAT32_BPB_STRUCT Fat32; -} FAT_BPB_STRUCT; - -typedef enum { - FatTypeUnknown, - FatTypeFat12, - FatTypeFat16, - FatTypeFat32, - FatTypeMax -} FAT_TYPE; - -typedef struct { - CHAR8 DIR_Name[11]; - UINT8 DIR_Attr; - UINT8 DIR_NTRes; - UINT8 DIR_CrtTimeTenth; - UINT16 DIR_CrtTime; - UINT16 DIR_CrtDate; - UINT16 DIR_LstAccDate; - UINT16 DIR_FstClusHI; - UINT16 DIR_WrtTime; - UINT16 DIR_WrtDate; - UINT16 DIR_FstClusLO; - UINT32 DIR_FileSize; -} FAT_DIRECTORY_ENTRY; - -#pragma pack() - -#define FAT_MAX_FAT12_CLUSTER 0xFF5 -#define FAT_MAX_FAT16_CLUSTER 0xFFF5 - -#define FAT_BS_SIGNATURE 0xAA55 -#define FAT_BS_BOOTSIG 0x29 -#define FAT_BS_JMP1 0xEB -#define FAT_BS_JMP2 0xE9 -#define FAT_FILSYSTYPE "FAT " -#define FAT12_FILSYSTYPE "FAT12 " -#define FAT16_FILSYSTYPE "FAT16 " -#define FAT32_FILSYSTYPE "FAT32 " - -#endif diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/BootsectImage/mbr.h b/EdkCompatibilityPkg/Sample/Tools/Source/BootsectImage/mbr.h deleted file mode 100644 index 5a95097dc1..0000000000 --- a/EdkCompatibilityPkg/Sample/Tools/Source/BootsectImage/mbr.h +++ /dev/null @@ -1,64 +0,0 @@ -/*++ - -Copyright 2006, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - mbr.h - -Abstract: - -Revision History - ---*/ - -#ifndef _MBR_H_ -#define _MBR_H_ - -#include "Tiano.h" - -#pragma pack(1) - -#define MAX_MBR_PARTITIONS 4 - -// -// MBR Partition Entry -// -typedef struct { - UINT8 BootIndicator; - UINT8 StartHead; - UINT8 StartSector; - UINT8 StartTrack; - UINT8 OSType; - UINT8 EndHead; - UINT8 EndSector; - UINT8 EndTrack; - UINT32 StartingLBA; - UINT32 SizeInLBA; -} MBR_PARTITION_RECORD; - -// -// MBR Partition table -// -typedef struct { - UINT8 BootCode[440]; - UINT32 UniqueMbrSignature; - UINT16 Unknown; - MBR_PARTITION_RECORD PartitionRecord[MAX_MBR_PARTITIONS]; - UINT16 Signature; -} MASTER_BOOT_RECORD; - -#pragma pack() - -#define MBR_SIGNATURE 0xAA55 -#define EXTENDED_DOS_PARTITION 0x05 -#define EXTENDED_WINDOWS_PARTITION 0x0F - -#endif diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/Common/FvLib.c b/EdkCompatibilityPkg/Sample/Tools/Source/Common/FvLib.c index 4b2bf81147..d660c07f4b 100644 --- a/EdkCompatibilityPkg/Sample/Tools/Source/Common/FvLib.c +++ b/EdkCompatibilityPkg/Sample/Tools/Source/Common/FvLib.c @@ -390,6 +390,91 @@ Returns: return EFI_SUCCESS; } +EFI_STATUS +SearchSectionByType ( + IN EFI_FILE_SECTION_POINTER FirstSection, + IN UINT8 *SearchEnd, + IN EFI_SECTION_TYPE SectionType, + IN OUT UINTN *StartIndex, + IN UINTN Instance, + OUT EFI_FILE_SECTION_POINTER *Section + ) +/*++ + +Routine Description: + + Helper function to search a sequence of sections from the section pointed + by FirstSection to SearchEnd for the Instance-th section of type SectionType. + The current counter is saved in StartIndex and when the section is found, it's + saved in Section. GUID-defined sections, if special processing is not required, + are searched recursively in a depth-first manner. + +Arguments: + + FirstSection The first section to start searching from. + SearchEnd The end address to stop search. + SectionType The type of section to search. + StartIndex The current counter is saved. + Instance The requested n-th section number. + Section The found section returned. + +Returns: + + EFI_SUCCESS The function completed successfully. + EFI_NOT_FOUND The section is not found. +--*/ +{ + EFI_FILE_SECTION_POINTER CurrentSection; + EFI_FILE_SECTION_POINTER InnerSection; + EFI_STATUS Status; + UINTN SectionSize; + + CurrentSection = FirstSection; + + while ((UINTN) CurrentSection.CommonHeader < (UINTN) SearchEnd) { + if (CurrentSection.CommonHeader->Type == SectionType) { + (*StartIndex)++; + } + + if (*StartIndex == Instance) { + *Section = CurrentSection; + return EFI_SUCCESS; + } + // + // If the requesting section is not GUID-defined and + // we find a GUID-defined section that doesn't need + // special processing, go ahead to search the requesting + // section inside the GUID-defined section. + // + if (SectionType != EFI_SECTION_GUID_DEFINED && + CurrentSection.CommonHeader->Type == EFI_SECTION_GUID_DEFINED && + !(CurrentSection.GuidDefinedSection->Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED)) { + InnerSection.CommonHeader = (EFI_COMMON_SECTION_HEADER *) + ((UINTN) CurrentSection.CommonHeader + CurrentSection.GuidDefinedSection->DataOffset); + SectionSize = CurrentSection.CommonHeader->Size[0] + + (CurrentSection.CommonHeader->Size[1] << 8) + + (CurrentSection.CommonHeader->Size[2] << 16); + Status = SearchSectionByType ( + InnerSection, + (UINT8 *) ((UINTN) CurrentSection.CommonHeader + SectionSize), + SectionType, + StartIndex, + Instance, + Section + ); + if (!EFI_ERROR (Status)) { + return EFI_SUCCESS; + } + } + // + // Find next section (including compensating for alignment issues. + // + CurrentSection.CommonHeader = (EFI_COMMON_SECTION_HEADER *) ((((UINTN) CurrentSection.CommonHeader) + GetLength (CurrentSection.CommonHeader->Size) + 0x03) & (-1 << 2)); + } + + return EFI_NOT_FOUND; +} + EFI_STATUS GetSectionByType ( IN EFI_FFS_FILE_HEADER *File, @@ -403,7 +488,8 @@ Routine Description: Find a section in a file by type and instance. An instance of 1 is the first instance. The function will return NULL if a matching section cannot be found. - The function will not handle encapsulating sections. + GUID-defined sections, if special processing is not needed, are handled in a + depth-first manner. Arguments: @@ -448,28 +534,24 @@ Returns: // CurrentSection.CommonHeader = (EFI_COMMON_SECTION_HEADER *) ((UINTN) File + sizeof (EFI_FFS_FILE_HEADER)); - // - // Loop as long as we have a valid file - // - while ((UINTN) CurrentSection.CommonHeader < (UINTN) File + GetLength (File->Size)) { - if (CurrentSection.CommonHeader->Type == SectionType) { - SectionCount++; - } + Status = SearchSectionByType ( + CurrentSection, + (UINT8 *) ((UINTN) File + GetLength (File->Size)), + SectionType, + &SectionCount, + Instance, + Section + ); - if (SectionCount == Instance) { - *Section = CurrentSection; - return EFI_SUCCESS; - } + if (!EFI_ERROR (Status)) { + return EFI_SUCCESS; + } else { // - // Find next section (including compensating for alignment issues. + // Section not found // - CurrentSection.CommonHeader = (EFI_COMMON_SECTION_HEADER *) ((((UINTN) CurrentSection.CommonHeader) + GetLength (CurrentSection.CommonHeader->Size) + 0x03) & (-1 << 2)); + (*Section).Code16Section = NULL; + return EFI_NOT_FOUND; } - // - // Section not found - // - (*Section).Code16Section = NULL; - return EFI_NOT_FOUND; } // // will not parse compressed sections diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/Common/Makefile b/EdkCompatibilityPkg/Sample/Tools/Source/Common/Makefile index 464d0e9930..7e0f8fc2ae 100644 --- a/EdkCompatibilityPkg/Sample/Tools/Source/Common/Makefile +++ b/EdkCompatibilityPkg/Sample/Tools/Source/Common/Makefile @@ -100,7 +100,7 @@ all: $(TARGET_LIB) "$(EDK_TOOLS_OUTPUT)\PeCoffLoaderEx.obj": "$(EDK_SOURCE)\Foundation\Library\Pei\PeiLib\$(PROCESSOR)\PeCoffLoaderEx.c" $(CC) $(C_FLAGS) "$(EDK_SOURCE)\Foundation\Library\Pei\PeiLib\$(PROCESSOR)\PeCoffLoaderEx.c" /Fo"$(EDK_TOOLS_OUTPUT)\PeCoffLoaderEx.obj" -"$(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" +"$(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" $(CC) $(C_FLAGS) "$(TARGET_SOURCE_DIR)\FvLib.c" /Fo"$(EDK_TOOLS_OUTPUT)\FvLib.obj" "$(EDK_TOOLS_OUTPUT)\EfiUtilityMsgs.obj": "$(TARGET_SOURCE_DIR)\EfiUtilityMsgs.c" "$(TARGET_SOURCE_DIR)\EfiUtilityMsgs.h" @@ -125,11 +125,13 @@ $(TARGET_LIB): $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).lib !ELSE $(TARGET_LIB): $(OBJECTS) $(LIB_EXE) $(LIB_FLAGS) $(OBJECTS) /OUT:$(TARGET_LIB) +!IF ("$(EFI_BINARY_BUILD)" == "YES") if not exist $(EFI_PLATFORM_BIN)\Tools mkdir $(EFI_PLATFORM_BIN)\Tools if exist $(TARGET_LIB) copy $(TARGET_LIB) $(EFI_PLATFORM_BIN)\tools\$(TARGET_NAME).lib /Y if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME)Obj.pdb \ copy $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME)Obj.pdb $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME)Obj.pdb /Y !ENDIF +!ENDIF clean: @if exist $(EDK_TOOLS_OUTPUT)\ParseInf.* del /q $(EDK_TOOLS_OUTPUT)\ParseInf.* > NUL diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/CustomizedCompress/makefile b/EdkCompatibilityPkg/Sample/Tools/Source/CustomizedCompress/makefile index 4e36514509..590d0fd78f 100644 --- a/EdkCompatibilityPkg/Sample/Tools/Source/CustomizedCompress/makefile +++ b/EdkCompatibilityPkg/Sample/Tools/Source/CustomizedCompress/makefile @@ -71,11 +71,13 @@ $(TARGET_LIB): $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).lib !ELSE $(TARGET_LIB): $(OBJECTS) $(LIB_EXE) $(LIB_FLAGS) $(OBJECTS) /OUT:$(TARGET_LIB) +!IF ("$(EFI_BINARY_BUILD)" == "YES") if not exist $(EFI_PLATFORM_BIN)\Tools mkdir $(EFI_PLATFORM_BIN)\Tools if exist $(TARGET_LIB) copy $(TARGET_LIB) $(EFI_PLATFORM_BIN)\tools\$(TARGET_NAME).lib /Y if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME)Obj.pdb \ copy $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME)Obj.pdb $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME)Obj.pdb /Y !ENDIF +!ENDIF clean: @if exist $(EDK_TOOLS_OUTPUT)\CustomizedCompress.* del /q $(EDK_TOOLS_OUTPUT)\CustomizedCompress.* > NUL diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/EfiCompress/makefile b/EdkCompatibilityPkg/Sample/Tools/Source/EfiCompress/makefile index 3f034288e0..5f86d50446 100644 --- a/EdkCompatibilityPkg/Sample/Tools/Source/EfiCompress/makefile +++ b/EdkCompatibilityPkg/Sample/Tools/Source/EfiCompress/makefile @@ -79,11 +79,13 @@ $(TARGET_EXE): $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe !ELSE $(TARGET_EXE): $(EDK_TOOLS_OUTPUT)\EfiCompressMain.obj $(TARGET_EXE_LIBS) $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(EDK_TOOLS_OUTPUT)\EfiCompressMain.obj $(TARGET_EXE_LIBS) +!IF ("$(EFI_BINARY_BUILD)" == "YES") if not exist $(EFI_PLATFORM_BIN)\Tools mkdir $(EFI_PLATFORM_BIN)\Tools if exist $(TARGET_EXE) copy $(TARGET_EXE) $(EFI_PLATFORM_BIN)\tools\$(TARGET_NAME).exe /Y if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb \ copy $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb /Y !ENDIF +!ENDIF clean: @if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME)Main.* del /q $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME)Main.* > NUL diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/EfiRom/EfiRom.c b/EdkCompatibilityPkg/Sample/Tools/Source/EfiRom/EfiRom.c index 06a8581669..f5ab9ff234 100644 --- a/EdkCompatibilityPkg/Sample/Tools/Source/EfiRom/EfiRom.c +++ b/EdkCompatibilityPkg/Sample/Tools/Source/EfiRom/EfiRom.c @@ -41,11 +41,11 @@ Abstract: // // END include differences // -#include "Pci22.h" // for option ROM header structures +#include "Pci.h" // for option ROM header structures // // Version of this utility // -#define UTILITY_VERSION "v2.5" +#define UTILITY_VERSION "v2.6" // // Define some status return values @@ -137,6 +137,15 @@ static STRING_LOOKUP mSubsystemTypes[] = { 0, NULL }; + +static char* mCodeTypeStr[] = { + "PCAT Image", + "Open Firmware Image", + "HP PA RISC Image", + "EFI Image", + "Undefined" +}; + // // Function prototypes // @@ -353,6 +362,45 @@ BailOut: return Status; } + +UINT8 +CheckSum ( + UINT8 *Buffer, + UINT32 DataSize, + UINT32 PaddingSize + ) +/*++ +Routine Description: + Calculate checksum from DataSize of Buffer. + +Arguments: + Buffer - pointer to data buffer + DataSize - size of data buffer in bytes + +Return: + UINT8 - checksum +--*/ +{ + UINT8 Checksum = 0; + while (DataSize-- != 0) { + Checksum = Checksum + Buffer[DataSize]; + } + while (PaddingSize-- != 0) { + Checksum = Checksum + 0xff; + } + return Checksum; +} + +char * +GetCodeTypeStr ( + UINT8 CodeType + ) +{ + if (CodeType >= sizeof (mCodeTypeStr) / sizeof (*mCodeTypeStr)) { + CodeType = sizeof (mCodeTypeStr) / sizeof (*mCodeTypeStr) - 1; + } + return mCodeTypeStr[CodeType]; +} static int @@ -382,11 +430,12 @@ Returns: FILE *InFptr; UINT32 TotalSize; UINT32 FileSize; + UINT32 DataSize; + UINT32 PaddingSize; UINT8 *Buffer; UINT32 Status; PCI_EXPANSION_ROM_HEADER *RomHdr; PCI_DATA_STRUCTURE *PciDs; - UINT32 Index; UINT8 ByteCheckSum; Status = STATUS_SUCCESS; @@ -421,34 +470,14 @@ Returns: Status = STATUS_ERROR; goto BailOut; } - // - // Total size must be an even multiple of 512 bytes, and can't exceed - // the option ROM image size. - // - TotalSize = FileSize; - if (TotalSize & 0x1FF) { - TotalSize = (TotalSize + 0x200) &~0x1ff; - } - if (TotalSize > MAX_OPTION_ROM_SIZE) { - fprintf ( - stdout, - "ERROR: Option ROM image %s size exceeds limit 0x%X bytes\n", - InFile->FileName, - MAX_OPTION_ROM_SIZE - ); - Status = STATUS_ERROR; - goto BailOut; - } - // - // Return the size to the caller so they can keep track of the running total. - // - *Size = TotalSize; + + RomHdr = (PCI_EXPANSION_ROM_HEADER *) Buffer; + PciDs = (PCI_DATA_STRUCTURE *) (Buffer + RomHdr->PcirOffset); // // Crude check to make sure it's a legitimate ROM image // - RomHdr = (PCI_EXPANSION_ROM_HEADER *) Buffer; if (RomHdr->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) { fprintf (stdout, "ERROR: ROM image file has invalid ROM signature\n"); Status = STATUS_ERROR; @@ -464,47 +493,76 @@ Returns: goto BailOut; } - PciDs = (PCI_DATA_STRUCTURE *) (Buffer + RomHdr->PcirOffset); if (PciDs->Signature != PCI_DATA_STRUCTURE_SIGNATURE) { fprintf (stdout, "ERROR: PCI data structure has invalid signature\n"); Status = STATUS_ERROR; goto BailOut; } + + if ((UINT32) (PciDs->ImageLength * 512) == FileSize) { + // + // ImageLength reflects the actual file size correctly. + // + DataSize = FileSize - 1; + PaddingSize = 0; + TotalSize = FileSize; + } else { + // + // ImageLength doesn't reflect the actual file size, + // 1). add additional 512 bytes if actual file size is multiple of 512 + // 2). add additional X (X <= 512) bytes so that the result size is multiple of 512 + // + fprintf (stdout, "WARNING: ImageLength in PCI data structure != Actual File Size\n" + " --> add additional padding bytes\n" + " --> adjust ImageLength\n" + ); + TotalSize = (FileSize + 0x200) & ~0x1ff; + DataSize = FileSize; + PaddingSize = TotalSize - DataSize - 1; + PciDs->ImageLength = (UINT16) (TotalSize / 512); + } + + // + // Check size + // + if (TotalSize > MAX_OPTION_ROM_SIZE) { + fprintf ( + stdout, + "ERROR: Option ROM image %s size exceeds limit 0x%X bytes\n", + InFile->FileName, + MAX_OPTION_ROM_SIZE + ); + Status = STATUS_ERROR; + goto BailOut; + } + + // + // Return the size to the caller so they can keep track of the running total. + // + *Size = TotalSize; + // // If this is the last image, then set the LAST bit unless requested not // to via the command-line -l argument. Otherwise, make sure you clear it. // if ((InFile->Next == NULL) && (mOptions.NoLast == 0)) { - PciDs->Indicator = INDICATOR_LAST; + PciDs->Indicator |= INDICATOR_LAST; } else { - PciDs->Indicator = 0; + PciDs->Indicator &= ~INDICATOR_LAST; } - ByteCheckSum = 0; - for (Index = 0; Index < FileSize - 1; Index++) { - ByteCheckSum = (UINT8) (ByteCheckSum + Buffer[Index]); - } - - Buffer[FileSize - 1] = (UINT8) ((~ByteCheckSum) + 1); - fprintf (stdout, "CheckSUm = %02x\n", (UINT32) Buffer[FileSize - 1]); + ByteCheckSum = -CheckSum (Buffer, DataSize, PaddingSize); - // - // Now copy the input file contents out to the output file - // - if (fwrite (Buffer, FileSize, 1, OutFptr) != 1) { + if (fwrite (Buffer, DataSize, 1, OutFptr) != 1) { fprintf (stdout, "ERROR: Failed to write all file bytes to output file\n"); Status = STATUS_ERROR; goto BailOut; } - TotalSize -= FileSize; - // - // Pad the rest of the image to make it a multiple of 512 bytes - // - while (TotalSize > 0) { + while (PaddingSize-- != 0) { putc (~0, OutFptr); - TotalSize--; } + putc (ByteCheckSum, OutFptr); BailOut: if (InFptr != NULL) { @@ -665,9 +723,8 @@ Returns: // // Total size must be an even multiple of 512 bytes // - if (TotalSize & 0x1FF) { - TotalSize = (TotalSize + 0x200) &~0x1ff; - } + TotalSize = (TotalSize + 0x1ff) & ~0x1ff; + // // Check size // @@ -729,7 +786,7 @@ Returns: // to via the command-line -l argument. // if ((InFile->Next == NULL) && (mOptions.NoLast == 0)) { - PciDs.Indicator = INDICATOR_LAST; + PciDs.Indicator |= INDICATOR_LAST; } // // Write the ROM header to the output file @@ -1068,7 +1125,7 @@ Returns: // // Specify binary files with -b // - FileFlags = (FileFlags &~FILE_FLAG_EFI) | FILE_FLAG_BINARY; + FileFlags = (FileFlags & ~FILE_FLAG_EFI) | FILE_FLAG_BINARY; } else if ((_stricmp (Argv[0], "-e") == 0) || (_stricmp (Argv[0], "-ec") == 0)) { // // Specify EFI files with -e. Specify EFI-compressed with -ec. @@ -1280,7 +1337,7 @@ Returns: " the following FileName", " -dump - to dump the headers of an existing option ROM image", "", - "Example usage: EfiRom -v 0xABCD -d 0x1234 -b File1.bin File2.bin -e File1.efi File2.efi ", + "Example usage: EfiRom -v 0xABCD -d 0x1234 -b File1.bin File2.bin -e File1.efi File2.efi", "", NULL }; @@ -1315,8 +1372,9 @@ Returns: FILE *InFptr; UINT32 ImageStart; UINT32 ImageCount; + UINT16 DeviceId; EFI_PCI_EXPANSION_ROM_HEADER EfiRomHdr; - PCI_DATA_STRUCTURE PciDs; + PCI_3_0_DATA_STRUCTURE PciDs; // // Open the input file @@ -1382,41 +1440,35 @@ Returns: ); fprintf (stdout, " Vendor ID 0x%04X\n", PciDs.VendorId); fprintf (stdout, " Device ID 0x%04X\n", PciDs.DeviceId); + fprintf (stdout, " Structure Length 0x%04X\n", PciDs.Length); + fprintf (stdout, " PCI Revision 0x%02X\n", PciDs.Revision); fprintf ( stdout, " Class Code 0x%06X\n", (UINT32) (PciDs.ClassCode[0] | (PciDs.ClassCode[1] << 8) | (PciDs.ClassCode[2] << 16)) ); fprintf (stdout, " Image size 0x%X\n", PciDs.ImageLength * 512); - fprintf (stdout, " Code revision: 0x%04X\n", PciDs.CodeRevision); + fprintf (stdout, " Code revision 0x%04X\n", PciDs.CodeRevision); fprintf (stdout, " Indicator 0x%02X", (UINT32) PciDs.Indicator); // // Print the indicator, used to flag the last image // - if (PciDs.Indicator == INDICATOR_LAST) { + if ((PciDs.Indicator & INDICATOR_LAST) == INDICATOR_LAST) { fprintf (stdout, " (last image)\n"); } else { fprintf (stdout, "\n"); } + // // Print the code type. If EFI code, then we can provide more info. // - fprintf (stdout, " Code type 0x%02X", (UINT32) PciDs.CodeType); + fprintf (stdout, " Code type 0x%02X (%s)\n", (UINT32) PciDs.CodeType, GetCodeTypeStr (PciDs.CodeType)); if (PciDs.CodeType == PCI_CODE_TYPE_EFI_IMAGE) { - fprintf (stdout, " (EFI image)\n"); // // Re-read the header as an EFI ROM header, then dump more info // fprintf (stdout, " EFI ROM header contents\n"); - if (fseek (InFptr, ImageStart, SEEK_SET)) { - fprintf (stdout, "ERROR: Failed to re-seek to ROM header structure\n"); - goto BailOut; - } - - if (fread (&EfiRomHdr, sizeof (EfiRomHdr), 1, InFptr) != 1) { - fprintf (stdout, "ERROR: Failed to read EFI PCI ROM header from file\n"); - goto BailOut; - } + memcpy (&EfiRomHdr, &PciRomHdr, sizeof (EfiRomHdr)); // // Now dump more info // @@ -1450,22 +1502,45 @@ Returns: (UINT32) EfiRomHdr.EfiImageHeaderOffset, (UINT32) (EfiRomHdr.EfiImageHeaderOffset + ImageStart) ); - - } else { - // - // Not an EFI image - // - fprintf (stdout, "\n"); } + // - // If code type is EFI image, then dump it as well? + // Dump additional information for PCI 3.0 OpROM // - // if (PciDs.CodeType == PCI_CODE_TYPE_EFI_IMAGE) { - // } + if (PciDs.Revision >= 3) { + fprintf (stdout, " Extended for PCI 3.0\n"); + + if (PciDs.DeviceListOffset != 0) { + if (fseek (InFptr, ImageStart + PciRomHdr.PcirOffset + PciDs.DeviceListOffset, SEEK_SET)) { + fprintf (stdout, "ERROR: Failed to seek to supported Device List\n"); + goto BailOut; + } + fprintf (stdout, " Device ID List "); + while (TRUE) { + if (fread (&DeviceId, sizeof (DeviceId), 1, InFptr) != 1) { + fprintf (stdout, "ERROR: Failed to read supported DeviceId from DeviceId List\n"); + goto BailOut; + } + if (DeviceId == 0) { + break; + } + fprintf (stdout, "0x%04X ", DeviceId); + } + fprintf (stdout, "\n"); + } + fprintf (stdout, " Max Runtime Image Length 0x%08X\n", PciDs.MaxRuntimeImageLength * 512); + if (PciDs.Length == sizeof (PCI_3_0_DATA_STRUCTURE)) { + fprintf (stdout, " Config Utility Header 0x%04X\n", PciDs.ConfigUtilityCodeHeaderOffset); + fprintf (stdout, " DMTF CLP Entry Point 0x%04X\n", PciDs.DMTFCLPEntryPointOffset); + } else { + fprintf (stdout, "WARNING: Oprom declars 3.0 revision with wrong structure length 0x%04X\n", PciDs.Length); + } + } + // // If last image, then we're done // - if (PciDs.Indicator == INDICATOR_LAST) { + if ((PciDs.Indicator & INDICATOR_LAST) == INDICATOR_LAST) { goto BailOut; } // @@ -1543,3 +1618,4 @@ Returns: return "unknown"; } + diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/EfiRom/Makefile b/EdkCompatibilityPkg/Sample/Tools/Source/EfiRom/Makefile index 2832154763..39d39db868 100644 --- a/EdkCompatibilityPkg/Sample/Tools/Source/EfiRom/Makefile +++ b/EdkCompatibilityPkg/Sample/Tools/Source/EfiRom/Makefile @@ -75,11 +75,13 @@ $(TARGET_EXE): $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe !ELSE $(TARGET_EXE): $(OBJECTS) $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(OBJECTS) +!IF ("$(EFI_BINARY_BUILD)" == "YES") if not exist $(EFI_PLATFORM_BIN)\Tools mkdir $(EFI_PLATFORM_BIN)\Tools if exist $(TARGET_EXE) copy $(TARGET_EXE) $(EFI_PLATFORM_BIN)\tools\$(TARGET_NAME).exe /Y if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb \ copy $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb /Y !ENDIF +!ENDIF clean: @if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/EfildrImage/efildrimage.c b/EdkCompatibilityPkg/Sample/Tools/Source/EfildrImage/efildrimage.c deleted file mode 100644 index c072dd73ac..0000000000 --- a/EdkCompatibilityPkg/Sample/Tools/Source/EfildrImage/efildrimage.c +++ /dev/null @@ -1,188 +0,0 @@ -/*++ - -Copyright 2006 - 2007, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - efildrimage.c - -Abstract: - - Creates and EFILDR image. - This tool combines several PE Image files together using following format denoted as EBNF: - FILE := EFILDR_HEADER - EFILDR_IMAGE + - + - The order of EFILDR_IMAGE is same as the order of placing PeImageFileContent. - -Revision History - ---*/ - - -#include -#include -#include "Tiano.h" - -#define MAX_PE_IMAGES 63 -#define FILE_TYPE_FIXED_LOADER 0 -#define FILE_TYPE_RELOCATABLE_PE_IMAGE 1 - -typedef struct { - UINT32 CheckSum; - UINT32 Offset; - UINT32 Length; - UINT8 FileName[52]; -} EFILDR_IMAGE; - -typedef struct { - UINT32 Signature; - UINT32 HeaderCheckSum; - UINT32 FileLength; - UINT32 NumberOfImages; -} EFILDR_HEADER; - - - -VOID -Usage ( - VOID - ) -{ - printf ("Usage: EfiLdrImage OutImage LoaderImage PeImage1 PeImage2 ... PeImageN"); - exit (1); -} - -ULONG -FCopyFile ( - FILE *in, - FILE *out - ) -/*++ -Routine Description: - Write all the content of input file to output file. - -Arguments: - in - input file pointer - out - output file pointer - -Return: - ULONG : file size of input file ---*/ -{ - ULONG filesize, offset, length; - UCHAR Buffer[8*1024]; - - fseek (in, 0, SEEK_END); - filesize = ftell(in); - - fseek (in, 0, SEEK_SET); - - offset = 0; - while (offset < filesize) { - length = sizeof(Buffer); - if (filesize-offset < length) { - length = filesize-offset; - } - - fread (Buffer, length, 1, in); - fwrite (Buffer, length, 1, out); - offset += length; - } - - return filesize; -} - - -int -main ( - int argc, - char *argv[] - ) -/*++ - -Routine Description: - - -Arguments: - - -Returns: - - ---*/ -{ - ULONG i; - ULONG filesize; - FILE *fpIn, *fpOut; - EFILDR_HEADER EfiLdrHeader; - EFILDR_IMAGE EfiLdrImage[MAX_PE_IMAGES]; - - if (argc < 4) { - Usage(); - } - - // - // Open output file for write - // - fpOut = fopen(argv[1], "w+b"); - if (!fpOut) { - printf ("efildrimage: Could not open output file %s\n", argv[1]); - exit(1); - } - - memset (&EfiLdrHeader, 0, sizeof (EfiLdrHeader)); - memset (&EfiLdrImage, 0, sizeof (EFILDR_IMAGE) * (argc - 2)); - - memcpy (&EfiLdrHeader.Signature, "EFIL", 4); - EfiLdrHeader.FileLength = sizeof(EFILDR_HEADER) + sizeof(EFILDR_IMAGE)*(argc-2); - - // - // Skip the file header first - // - fseek (fpOut, EfiLdrHeader.FileLength, SEEK_SET); - - // - // copy all the input files to the output file - // - for(i=2;i<(ULONG)argc;i++) { - // - // Copy the content of PeImage file to output file - // - fpIn = fopen (argv[i], "rb"); - if (!fpIn) { - printf ("efildrimage: Could not open input file %s\n", argv[i-2]); - exit(1); - } - filesize = FCopyFile (fpIn, fpOut); - fclose(fpIn); - - // - // And in the same time update the EfiLdrHeader and EfiLdrImage array - // - EfiLdrImage[i-2].Offset = EfiLdrHeader.FileLength; - EfiLdrImage[i-2].Length = filesize; - strncpy (EfiLdrImage[i-2].FileName, argv[i], sizeof (EfiLdrImage[i-2].FileName) - 1); - EfiLdrHeader.FileLength += filesize; - EfiLdrHeader.NumberOfImages++; - } - - // - // Write the image header to the output file finally - // - fseek (fpOut, 0, SEEK_SET); - fwrite (&EfiLdrHeader, sizeof(EFILDR_HEADER) , 1, fpOut); - fwrite (&EfiLdrImage , sizeof(EFILDR_IMAGE)*(argc-2), 1, fpOut); - - fclose (fpOut); - printf ("Created %s\n", argv[1]); - return 0; -} - diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/FwImage/Makefile b/EdkCompatibilityPkg/Sample/Tools/Source/FwImage/Makefile index 216ac9782b..bc31b23296 100644 --- a/EdkCompatibilityPkg/Sample/Tools/Source/FwImage/Makefile +++ b/EdkCompatibilityPkg/Sample/Tools/Source/FwImage/Makefile @@ -76,11 +76,13 @@ $(TARGET_EXE): $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe !ELSE $(TARGET_EXE) : $(OBJECTS) $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(OBJECTS) +!IF ("$(EFI_BINARY_BUILD)" == "YES") if not exist $(EFI_PLATFORM_BIN)\Tools mkdir $(EFI_PLATFORM_BIN)\Tools if exist $(TARGET_EXE) copy $(TARGET_EXE) $(EFI_PLATFORM_BIN)\tools\$(TARGET_NAME).exe /Y if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb \ copy $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb /Y !ENDIF +!ENDIF clean: @if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/GenAprioriFile/Makefile b/EdkCompatibilityPkg/Sample/Tools/Source/GenAprioriFile/Makefile index 887da4fc8e..82365a4809 100644 --- a/EdkCompatibilityPkg/Sample/Tools/Source/GenAprioriFile/Makefile +++ b/EdkCompatibilityPkg/Sample/Tools/Source/GenAprioriFile/Makefile @@ -66,11 +66,13 @@ $(TARGET_EXE): $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe !ELSE $(TARGET_EXE): $(OBJECTS) $(LIBS) $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(OBJECTS) +!IF ("$(EFI_BINARY_BUILD)" == "YES") if not exist $(EFI_PLATFORM_BIN)\Tools mkdir $(EFI_PLATFORM_BIN)\Tools if exist $(TARGET_EXE) copy $(TARGET_EXE) $(EFI_PLATFORM_BIN)\tools\$(TARGET_NAME).exe /Y if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb \ copy $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb /Y !ENDIF +!ENDIF clean: @if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME)Lib.* del /q $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME)Lib.* > NUL diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/GenBootsector/GetDrvNumOffset.c b/EdkCompatibilityPkg/Sample/Tools/Source/GenBootsector/GetDrvNumOffset.c deleted file mode 100644 index d16358b4e7..0000000000 --- a/EdkCompatibilityPkg/Sample/Tools/Source/GenBootsector/GetDrvNumOffset.c +++ /dev/null @@ -1,58 +0,0 @@ -#include "fat.h" -#include - -INTN -GetDrvNumOffset ( - IN VOID *BootSector - ) -{ - FAT_BPB_STRUCT *FatBpb; - UINTN RootDirSectors; - UINTN FATSz; - UINTN TotSec; - UINTN DataSec; - UINTN CountOfClusters; - - FatBpb = (FAT_BPB_STRUCT *) BootSector; - - // - // Check FAT type algorithm from FAT spec - // - RootDirSectors = ((FatBpb->Fat12_16.BPB_RootEntCnt * sizeof(FAT_DIRECTORY_ENTRY)) + - (FatBpb->Fat12_16.BPB_BytsPerSec - 1)) / FatBpb->Fat12_16.BPB_BytsPerSec; - - if (FatBpb->Fat12_16.BPB_FATSz16 != 0) { - FATSz = FatBpb->Fat12_16.BPB_FATSz16; - } else { - FATSz = FatBpb->Fat32.BPB_FATSz32; - } - if (FATSz == 0) { - fprintf (stderr, "ERROR: FAT: BPB_FATSz16, BPB_FATSz32 - 0, expected - Non-Zero\n"); - return -1; - } - - if (FatBpb->Fat12_16.BPB_TotSec16 != 0) { - TotSec = FatBpb->Fat12_16.BPB_TotSec16; - } else { - TotSec = FatBpb->Fat12_16.BPB_TotSec32; - } - if (TotSec == 0) { - fprintf (stderr, "ERROR: FAT: BPB_TotSec16, BPB_TotSec32 - 0, expected - Non-Zero\n"); - return -1; - } - - DataSec = TotSec - ( - FatBpb->Fat12_16.BPB_RsvdSecCnt + - FatBpb->Fat12_16.BPB_NumFATs * FATSz + - RootDirSectors - ); - - CountOfClusters = DataSec / FatBpb->Fat12_16.BPB_SecPerClus; - - if (CountOfClusters < FAT_MAX_FAT16_CLUSTER) { - return (INTN) ((UINTN) &FatBpb->Fat12_16.BS_DrvNum - (UINTN) FatBpb); - } else { - return (INTN) ((UINTN) &FatBpb->Fat32.BS_DrvNum - (UINTN) FatBpb); - } -} - diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/GenBootsector/fat.h b/EdkCompatibilityPkg/Sample/Tools/Source/GenBootsector/fat.h deleted file mode 100644 index 330312688b..0000000000 --- a/EdkCompatibilityPkg/Sample/Tools/Source/GenBootsector/fat.h +++ /dev/null @@ -1,158 +0,0 @@ -/*++ - -Copyright 2006, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - fat.h - -Abstract: - -Revision History - ---*/ - -#ifndef _FAT_BPB_H_ -#define _FAT_BPB_H_ - -#include "Tiano.h" - -#pragma pack(1) - -typedef struct { - // - // Fat common field - // - UINT8 BS_jmpBoot[3]; - CHAR8 BS_OEMName[8]; - UINT16 BPB_BytsPerSec; - UINT8 BPB_SecPerClus; - UINT16 BPB_RsvdSecCnt; - UINT8 BPB_NumFATs; - UINT16 BPB_RootEntCnt; - UINT16 BPB_TotSec16; - UINT8 BPB_Media; - UINT16 BPB_FATSz16; - UINT16 BPB_SecPerTrk; - UINT16 BPB_NumHeads; - UINT32 BPB_HiddSec; - UINT32 BPB_TotSec32; - - // - // Fat12/16 specific field - // - UINT8 BS_DrvNum; - UINT8 BS_Reserved1; - UINT8 BS_BootSig; - UINT32 BS_VolID; - CHAR8 BS_VolLab[11]; - CHAR8 BS_FilSysType[8]; - - // - // Boot Code and Data - // - UINT8 Reserved[448]; - - // - // Fat common signature - 0xAA55 - // - UINT16 Signature; -} FAT12_16_BPB_STRUCT; - -typedef struct { - // - // Fat common field - // - UINT8 BS_jmpBoot[3]; - CHAR8 BS_OEMName[8]; - UINT16 BPB_BytsPerSec; - UINT8 BPB_SecPerClus; - UINT16 BPB_RsvdSecCnt; - UINT8 BPB_NumFATs; - UINT16 BPB_RootEntCnt; - UINT16 BPB_TotSec16; - UINT8 BPB_Media; - UINT16 BPB_FATSz16; - UINT16 BPB_SecPerTrk; - UINT16 BPB_NumHeads; - UINT32 BPB_HiddSec; - UINT32 BPB_TotSec32; - - // - // Fat32 specific field - // - UINT32 BPB_FATSz32; - UINT16 BPB_ExtFlags; - UINT16 BPB_FSVer; - UINT32 BPB_RootClus; - UINT16 BPB_FSInfo; - UINT16 BPB_BkBootSec; - UINT8 BPB_Reserved[12]; - UINT8 BS_DrvNum; - UINT8 BS_Reserved1; - UINT8 BS_BootSig; - UINT32 BS_VolID; - CHAR8 BS_VolLab[11]; - CHAR8 BS_FilSysType[8]; - - // - // Boot Code and Data - // - UINT8 Reserved[420]; - - // - // Fat common signature - 0xAA55 - // - UINT16 Signature; -} FAT32_BPB_STRUCT; - -typedef union { - FAT12_16_BPB_STRUCT Fat12_16; - FAT32_BPB_STRUCT Fat32; -} FAT_BPB_STRUCT; - -typedef enum { - FatTypeUnknown, - FatTypeFat12, - FatTypeFat16, - FatTypeFat32, - FatTypeMax -} FAT_TYPE; - -typedef struct { - CHAR8 DIR_Name[11]; - UINT8 DIR_Attr; - UINT8 DIR_NTRes; - UINT8 DIR_CrtTimeTenth; - UINT16 DIR_CrtTime; - UINT16 DIR_CrtDate; - UINT16 DIR_LstAccDate; - UINT16 DIR_FstClusHI; - UINT16 DIR_WrtTime; - UINT16 DIR_WrtDate; - UINT16 DIR_FstClusLO; - UINT32 DIR_FileSize; -} FAT_DIRECTORY_ENTRY; - -#pragma pack() - -#define FAT_MAX_FAT12_CLUSTER 0xFF5 -#define FAT_MAX_FAT16_CLUSTER 0xFFF5 - -#define FAT_BS_SIGNATURE 0xAA55 -#define FAT_BS_BOOTSIG 0x29 -#define FAT_BS_JMP1 0xEB -#define FAT_BS_JMP2 0xE9 -#define FAT_FILSYSTYPE "FAT " -#define FAT12_FILSYSTYPE "FAT12 " -#define FAT16_FILSYSTYPE "FAT16 " -#define FAT32_FILSYSTYPE "FAT32 " - -#endif diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/GenBootsector/genbootsector.c b/EdkCompatibilityPkg/Sample/Tools/Source/GenBootsector/genbootsector.c deleted file mode 100644 index 8438502b7c..0000000000 --- a/EdkCompatibilityPkg/Sample/Tools/Source/GenBootsector/genbootsector.c +++ /dev/null @@ -1,652 +0,0 @@ -/*++ - -Copyright 2006 - 2007, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - genbootsector.c - -Abstract: - Reading/writing MBR/DBR. - NOTE: - If we write MBR to disk, we just update the MBR code and the partition table wouldn't be over written. - If we process DBR, we will patch MBR to set first partition active if no active partition exists. - ---*/ - -#include -#include -#include - -#define MAX_DRIVE 26 -#define PARTITION_TABLE_OFFSET 0x1BE - -#define SIZE_OF_PARTITION_ENTRY 0x10 - -#define PARTITION_ENTRY_STARTLBA_OFFSET 8 - -#define PARTITION_ENTRY_NUM 4 - -INT -GetDrvNumOffset ( - IN VOID *BootSector - ); - -typedef enum { - PatchTypeUnknown, - PatchTypeFloppy, - PatchTypeIde, - PatchTypeUsb, -} PATCH_TYPE; - -typedef enum { - ErrorSuccess, - ErrorFileCreate, - ErrorFileReadWrite, - ErrorNoMbr, - ErrorFatType -} ERROR_STATUS; - -CHAR *ErrorStatusDesc[] = { - "Success", - "Failed to create files", - "Failed to read/write files", - "No MBR exists", - "Failed to detect Fat type" -}; - -typedef struct _DRIVE_TYPE_DESC { - UINT Type; - CHAR *Description; -} DRIVE_TYPE_DESC; - -#define DRIVE_TYPE_ITEM(x) {x, #x} -DRIVE_TYPE_DESC DriveTypeDesc[] = { - DRIVE_TYPE_ITEM (DRIVE_UNKNOWN), - DRIVE_TYPE_ITEM (DRIVE_NO_ROOT_DIR), - DRIVE_TYPE_ITEM (DRIVE_REMOVABLE), - DRIVE_TYPE_ITEM (DRIVE_FIXED), - DRIVE_TYPE_ITEM (DRIVE_REMOTE), - DRIVE_TYPE_ITEM (DRIVE_CDROM), - DRIVE_TYPE_ITEM (DRIVE_RAMDISK), - (UINT) -1, NULL -}; - -typedef struct _DRIVE_INFO { - CHAR VolumeLetter; - DRIVE_TYPE_DESC *DriveType; - UINT DiskNumber; -} DRIVE_INFO; - -#define BOOT_SECTOR_LBA_OFFSET 0x1FA - -#define IsLetter(x) (((x) >= 'a' && (x) <= 'z') || ((x) >= 'A' && (x) <= 'Z')) - -BOOL -GetDriveInfo ( - CHAR VolumeLetter, - DRIVE_INFO *DriveInfo - ) -/*++ -Routine Description: - Get drive information including disk number and drive type, - where disknumber is useful for reading/writing disk raw data. - NOTE: Floppy disk doesn't have disk number but it doesn't matter because - we can reading/writing floppy disk without disk number. - -Arguments: - VolumeLetter : volume letter, e.g.: C for C:, A for A: - DriveInfo : pointer to DRIVE_INFO structure receiving drive information. - -Return: - TRUE : successful - FALSE : failed ---*/ -{ - HANDLE VolumeHandle; - STORAGE_DEVICE_NUMBER StorageDeviceNumber; - DWORD BytesReturned; - BOOL Success; - UINT DriveType; - UINT Index; - - CHAR RootPath[] = "X:\\"; // "X:\" -> for GetDriveType - CHAR VolumeAccessPath[] = "\\\\.\\X:"; // "\\.\X:" -> to open the volume - - RootPath[0] = VolumeAccessPath[4] = VolumeLetter; - DriveType = GetDriveType(RootPath); - if (DriveType != DRIVE_REMOVABLE && DriveType != DRIVE_FIXED) { - return FALSE; - } - - DriveInfo->VolumeLetter = VolumeLetter; - VolumeHandle = CreateFile ( - VolumeAccessPath, - 0, - FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, - OPEN_EXISTING, - 0, - NULL - ); - if (VolumeHandle == INVALID_HANDLE_VALUE) { - fprintf ( - stderr, - "ERROR: CreateFile failed: Volume = %s, LastError = 0x%x\n", - VolumeAccessPath, - GetLastError () - ); - return FALSE; - } - - // - // Get Disk Number. It should fail when operating on floppy. That's ok - // because Disk Number is only needed when operating on Hard or USB disk. - // - // To direct write to disk: - // for USB and HD: use path = \\.\PHYSICALDRIVEx, where x is Disk Number - // for floppy: use path = \\.\X:, where X can be A or B - // - Success = DeviceIoControl( - VolumeHandle, - IOCTL_STORAGE_GET_DEVICE_NUMBER, - NULL, - 0, - &StorageDeviceNumber, - sizeof(StorageDeviceNumber), - &BytesReturned, - NULL - ); - // - // DeviceIoControl should fail if Volume is floppy or network drive. - // - if (!Success) { - DriveInfo->DiskNumber = (UINT) -1; - } else if (StorageDeviceNumber.DeviceType != FILE_DEVICE_DISK) { - // - // Only care about the disk. - // - return FALSE; - } else{ - DriveInfo->DiskNumber = StorageDeviceNumber.DeviceNumber; - } - CloseHandle(VolumeHandle); - - // - // Fill in the type string - // - DriveInfo->DriveType = NULL; - for (Index = 0; DriveTypeDesc[Index].Description != NULL; Index ++) { - if (DriveType == DriveTypeDesc[Index].Type) { - DriveInfo->DriveType = &DriveTypeDesc[Index]; - break; - } - } - - if (DriveInfo->DriveType == NULL) { - // - // Should have a type. - // - fprintf (stderr, "ERROR: fetal error!!!\n"); - return FALSE; - } - return TRUE; -} - -VOID -ListDrive ( - VOID - ) -/*++ -Routine Description: - List every drive in current system and their information. - ---*/ -{ - UINT Index; - DRIVE_INFO DriveInfo; - - UINT Mask = GetLogicalDrives(); - - for (Index = 0; Index < MAX_DRIVE; Index++) { - if (((Mask >> Index) & 0x1) == 1) { - if (GetDriveInfo ('A' + (CHAR) Index, &DriveInfo)) { - if (Index < 2) { - // Floppy will occupy 'A' and 'B' - fprintf ( - stdout, - "%c: - Type: %s\n", - DriveInfo.VolumeLetter, - DriveInfo.DriveType->Description - ); - } - else { - fprintf ( - stdout, - "%c: - DiskNum: %d, Type: %s\n", - DriveInfo.VolumeLetter, - DriveInfo.DiskNumber, - DriveInfo.DriveType->Description - ); - } - } - } - } - -} - -INT -GetBootSectorOffset ( - HANDLE DiskHandle, - BOOL WriteToDisk, - PATCH_TYPE PatchType - ) -/*++ -Description: - Get the offset of boot sector. - For non-MBR disk, offset is just 0 - for disk with MBR, offset needs to be caculated by parsing MBR - - NOTE: if no one is active, we will patch MBR to select first partition as active. - -Arguments: - DiskHandle : HANDLE of disk - WriteToDisk : TRUE indicates writing - PatchType : PatchTypeFloppy, PatchTypeIde, PatchTypeUsb - -Return: - -1 : failed - o.w. : Offset to boot sector ---*/ -{ - BYTE DiskPartition[0x200]; - DWORD BytesReturn; - DWORD DbrOffset; - DWORD Index; - BOOL HasMbr; - - DbrOffset = 0; - HasMbr = FALSE; - - SetFilePointer(DiskHandle, 0, NULL, FILE_BEGIN); - if (!ReadFile (DiskHandle, DiskPartition, 0x200, &BytesReturn, NULL)) { - return -1; - } - - // - // Check Signature, Jmp, and Boot Indicator. - // if all pass, we assume MBR found. - // - - // Check Signature: 55AA - if ((DiskPartition[0x1FE] == 0x55) && (DiskPartition[0x1FF] == 0xAA)) { - // Check Jmp: (EB ?? 90) or (E9 ?? ??) - if (((DiskPartition[0] != 0xEB) || (DiskPartition[2] != 0x90)) && - (DiskPartition[0] != 0xE9)) { - // Check Boot Indicator: 0x00 or 0x80 - // Boot Indicator is the first byte of Partition Entry - HasMbr = TRUE; - for (Index = 0; Index < PARTITION_ENTRY_NUM; ++Index) { - if ((DiskPartition[PARTITION_TABLE_OFFSET + Index * SIZE_OF_PARTITION_ENTRY] & 0x7F) != 0) { - HasMbr = FALSE; - break; - } - } - } - } - - if (HasMbr) { - // - // Skip MBR - // - for (Index = 0; Index < PARTITION_ENTRY_NUM; Index++) { - // - // Found Boot Indicator. - // - if (DiskPartition[PARTITION_TABLE_OFFSET + (Index * SIZE_OF_PARTITION_ENTRY)] == 0x80) { - DbrOffset = *(DWORD *)&DiskPartition[PARTITION_TABLE_OFFSET + (Index * SIZE_OF_PARTITION_ENTRY) + PARTITION_ENTRY_STARTLBA_OFFSET]; - break; - } - } - // - // If no boot indicator, we manually select 1st partition, and patch MBR. - // - if (Index == PARTITION_ENTRY_NUM) { - DbrOffset = *(DWORD *)&DiskPartition[PARTITION_TABLE_OFFSET + PARTITION_ENTRY_STARTLBA_OFFSET]; - if (WriteToDisk && (PatchType == PatchTypeUsb)) { - SetFilePointer(DiskHandle, 0, NULL, FILE_BEGIN); - DiskPartition[PARTITION_TABLE_OFFSET] = 0x80; - WriteFile (DiskHandle, DiskPartition, 0x200, &BytesReturn, NULL); - } - } - } - - return DbrOffset; -} - -ERROR_STATUS -ProcessBsOrMbr ( - CHAR *DiskName, - CHAR *FileName, - BOOL WriteToDisk, - PATCH_TYPE PatchType, - BOOL ProcessMbr - ) -/*++ -Routine Description: - Writing or reading boot sector or MBR according to the argument. - -Arguments: - DiskName : Win32 API recognized string name of disk - FileName : file name - WriteToDisk : TRUE is to write content of file to disk, otherwise, reading content of disk to file - PatchType : PatchTypeFloppy, PatchTypeIde, PatchTypeUsb - ProcessMbr : TRUE is to process MBR, otherwise, processing boot sector - -Return: - ErrorSuccess - ErrorFileCreate - ErrorFileReadWrite - ErrorNoMbr - ErrorFatType ---*/ -{ - BYTE DiskPartition[0x200]; - BYTE DiskPartitionBackup[0x200]; - HANDLE DiskHandle; - HANDLE FileHandle; - DWORD BytesReturn; - DWORD DbrOffset; - INT DrvNumOffset; - - DiskHandle = CreateFile ( - DiskName, - GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - NULL - ); - if (DiskHandle == INVALID_HANDLE_VALUE) { - return ErrorFileCreate; - } - - FileHandle = CreateFile ( - FileName, - GENERIC_READ | GENERIC_WRITE, - 0, - NULL, - OPEN_ALWAYS, - FILE_ATTRIBUTE_NORMAL, - NULL - ); - if (FileHandle == INVALID_HANDLE_VALUE) { - return ErrorFileCreate; - } - - DbrOffset = 0; - // - // Skip potential MBR for Ide & USB disk - // - if ((PatchType == PatchTypeIde) || (PatchType == PatchTypeUsb)) { - // - // Even user just wants to process MBR, we get offset of boot sector here to validate the disk - // if disk have MBR, DbrOffset should be greater than 0 - // - DbrOffset = GetBootSectorOffset (DiskHandle, WriteToDisk, PatchType); - - if (!ProcessMbr) { - // - // 1. Process boot sector, set file pointer to the beginning of boot sector - // - SetFilePointer (DiskHandle, DbrOffset * 0x200, NULL, FILE_BEGIN); - } else if(DbrOffset == 0) { - // - // If user want to process Mbr, but no Mbr exists, simply return FALSE - // - return ErrorNoMbr; - } else { - // - // 2. Process MBR, set file pointer to 0 - // - SetFilePointer (DiskHandle, 0, NULL, FILE_BEGIN); - } - } - - // - // [File Pointer is pointed to beginning of Mbr or Dbr] - // - if (WriteToDisk) { - // - // Write - // - if (!ReadFile (FileHandle, DiskPartition, 0x200, &BytesReturn, NULL)) { - return ErrorFileReadWrite; - } - if (ProcessMbr) { - // - // Use original partition table - // - if (!ReadFile (DiskHandle, DiskPartitionBackup, 0x200, &BytesReturn, NULL)) { - return ErrorFileReadWrite; - } - memcpy (DiskPartition + 0x1BE, DiskPartitionBackup + 0x1BE, 0x40); - SetFilePointer (DiskHandle, 0, NULL, FILE_BEGIN); - } - - if (!WriteFile (DiskHandle, DiskPartition, 0x200, &BytesReturn, NULL)) { - return ErrorFileReadWrite; - } - - } else { - // - // Read - // - if (!ReadFile (DiskHandle, DiskPartition, 0x200, &BytesReturn, NULL)) { - return ErrorFileReadWrite; - } - - if (PatchType == PatchTypeUsb) { - // Manually set BS_DrvNum to 0x80 as window's format.exe has a bug which will clear this field discarding USB disk's MBR. - // offset of BS_DrvNum is 0x24 for FAT12/16 - // 0x40 for FAT32 - // - DrvNumOffset = GetDrvNumOffset (DiskPartition); - if (DrvNumOffset == -1) { - return ErrorFatType; - } - // - // Some legacy BIOS require 0x80 discarding MBR. - // Question left here: is it needed to check Mbr before set 0x80? - // - DiskPartition[DrvNumOffset] = ((DbrOffset > 0) ? 0x80 : 0); - } - - - if (PatchType == PatchTypeIde) { - // - // Patch LBAOffsetForBootSector - // - *(DWORD *)&DiskPartition [BOOT_SECTOR_LBA_OFFSET] = DbrOffset; - } - if (!WriteFile (FileHandle, DiskPartition, 0x200, &BytesReturn, NULL)) { - return ErrorFileReadWrite; - } - } - CloseHandle (FileHandle); - CloseHandle (DiskHandle); - return ErrorSuccess; -} - -VOID -PrintUsage ( - CHAR* AppName - ) -{ - fprintf ( - stdout, - "Usage: %s [OPTIONS]...\n" - "Copy file content from/to bootsector.\n" - "\n" - " -l list disks\n" - " -if=FILE specified an input, can be files or disks\n" - " -of=FILE specified an output, can be files or disks\n" - " -mbr process MBR also\n" - " -h print this message\n" - "\n" - "FILE providing a volume plus a colon (X:), indicates a disk\n" - "FILE providing other format, indicates a file\n", - AppName - ); -} - -INT -main ( - INT argc, - CHAR *argv[] - ) -{ - CHAR *AppName; - INT Index; - BOOL ProcessMbr; - CHAR VolumeLetter; - CHAR *FilePath; - BOOL WriteToDisk; - DRIVE_INFO DriveInfo; - PATCH_TYPE PatchType; - ERROR_STATUS Status; - - CHAR FloppyPathTemplate[] = "\\\\.\\%c:"; - CHAR DiskPathTemplate[] = "\\\\.\\PHYSICALDRIVE%u"; - CHAR DiskPath[MAX_PATH]; - - AppName = *argv; - argv ++; - argc --; - - ProcessMbr = FALSE; - WriteToDisk = TRUE; - FilePath = NULL; - VolumeLetter = 0; - - // - // Parse command line - // - for (Index = 0; Index < argc; Index ++) { - if (_stricmp (argv[Index], "-l") == 0) { - ListDrive (); - return 0; - } - else if (_stricmp (argv[Index], "-mbr") == 0) { - ProcessMbr = TRUE; - } - else if ((_strnicmp (argv[Index], "-if=", 4) == 0) || - (_strnicmp (argv[Index], "-of=", 4) == 0) - ) { - if (argv[Index][6] == '\0' && argv[Index][5] == ':' && IsLetter (argv[Index][4])) { - VolumeLetter = argv[Index][4]; - if (_strnicmp (argv[Index], "-if=", 4) == 0) { - WriteToDisk = FALSE; - } - } - else { - FilePath = &argv[Index][4]; - } - } - else { - PrintUsage (AppName); - return 1; - } - } - - // - // Check parameter - // - if (VolumeLetter == 0) { - fprintf (stderr, "ERROR: Volume isn't provided!\n"); - PrintUsage (AppName); - return 1; - } - - if (FilePath == NULL) { - fprintf (stderr, "ERROR: File isn't pvovided!\n"); - PrintUsage (AppName); - return 1; - } - - PatchType = PatchTypeUnknown; - - if ((VolumeLetter == 'A') || (VolumeLetter == 'a') || - (VolumeLetter == 'B') || (VolumeLetter == 'b') - ) { - // - // Floppy - // - sprintf (DiskPath, FloppyPathTemplate, VolumeLetter); - PatchType = PatchTypeFloppy; - } - else { - // - // Hard/USB disk - // - if (!GetDriveInfo (VolumeLetter, &DriveInfo)) { - fprintf (stderr, "ERROR: GetDriveInfo - 0x%x\n", GetLastError ()); - return 1; - } - - // - // Shouldn't patch my own hard disk, but can read it. - // very safe then:) - // - if (DriveInfo.DriveType->Type == DRIVE_FIXED && WriteToDisk) { - fprintf (stderr, "ERROR: Write to local harddisk - permission denied!\n"); - return 1; - } - - sprintf (DiskPath, DiskPathTemplate, DriveInfo.DiskNumber); - if (DriveInfo.DriveType->Type == DRIVE_REMOVABLE) { - PatchType = PatchTypeUsb; - } - else if (DriveInfo.DriveType->Type == DRIVE_FIXED) { - PatchType = PatchTypeIde; - } - } - - if (PatchType == PatchTypeUnknown) { - fprintf (stderr, "ERROR: PatchType unknown!\n"); - return 1; - } - - // - // Process DBR (Patch or Read) - // - Status = ProcessBsOrMbr (DiskPath, FilePath, WriteToDisk, PatchType, ProcessMbr); - if (Status == ErrorSuccess) { - fprintf ( - stdout, - "%s %s: successfully!\n", - WriteToDisk ? "Write" : "Read", - ProcessMbr ? "MBR" : "DBR" - ); - return 0; - } else { - fprintf ( - stderr, - "%s: %s %s: failed - %s (LastError: 0x%x)!\n", - (Status == ErrorNoMbr) ? "WARNING" : "ERROR", - WriteToDisk ? "Write" : "Read", - ProcessMbr ? "MBR" : "DBR", - ErrorStatusDesc[Status], - GetLastError () - ); - return 1; - } -} diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/GenBootsector/makefile b/EdkCompatibilityPkg/Sample/Tools/Source/GenBootsector/makefile deleted file mode 100644 index 359f126111..0000000000 --- a/EdkCompatibilityPkg/Sample/Tools/Source/GenBootsector/makefile +++ /dev/null @@ -1,99 +0,0 @@ -#/*++ -# -# Copyright (c) 2006 - 2007, Intel Corporation -# All rights reserved. This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -# Module Name: -# -# Makefile -# -# Abstract: -# -# makefile for building the GenBootsector utility. -# -#--*/ - -# -# Make sure environmental variable EDK_SOURCE is set -# -!IFNDEF EDK_SOURCE -!ERROR EDK_SOURCE environmental variable not set -!ENDIF - -# -# Do this if you want to compile from this directory -# -!IFNDEF TOOLCHAIN -TOOLCHAIN = TOOLCHAIN_MSVC -!ENDIF - -!INCLUDE $(BUILD_DIR)\PlatformTools.env - -# -# Define some macros we use here. Should get rid of them someday and -# get rid of the extra level of indirection. -# -COMMON_SOURCE = $(EDK_TOOLS_COMMON) - -# -# Common information -# - -INC=$(INC) - -# -# Target specific information -# - -TARGET_NAME=GenBootsector -TARGET_SOURCE_DIR = $(EDK_TOOLS_SOURCE)\$(TARGET_NAME) - -TARGET_EXE = $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).exe - -TARGET_EXE_SOURCE = "$(TARGET_SOURCE_DIR)\GenBootsector.c" -TARGET_EXE_INCLUDE = - - -# -# Build targets -# - -all: $(TARGET_EXE) - -# -# Build EXE -# -$(EDK_TOOLS_OUTPUT)\GetDrvNumOffset.obj: $(TARGET_SOURCE_DIR)\GenBootsector.c $(TARGET_SOURCE_DIR)\fat.h - $(CC) $(C_FLAGS) $(INC) $(TARGET_SOURCE_DIR)\GetDrvNumOffset.c /Fo$(EDK_TOOLS_OUTPUT)\GetDrvNumOffset.obj - -$(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj: $(TARGET_EXE_SOURCE) $(TARGET_EXE_INCLUDE) - $(CC) $(C_FLAGS) $(INC) $(TARGET_EXE_SOURCE) /Fo$(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj - -# -# Add Binary Build description for this tool. -# - -!IF (("$(EFI_BINARY_TOOLS)" == "YES") && EXIST($(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe)) -$(TARGET_EXE): $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe - copy $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe $(TARGET_EXE) /Y - if exist $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb \ - copy $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb /Y -!ELSE -$(TARGET_EXE): $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj $(EDK_TOOLS_OUTPUT)\GetDrvNumOffset.obj - $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) user32.lib advapi32.lib /out:$(TARGET_EXE) $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj $(EDK_TOOLS_OUTPUT)\GetDrvNumOffset.obj - if not exist $(EFI_PLATFORM_BIN)\Tools mkdir $(EFI_PLATFORM_BIN)\Tools - if exist $(TARGET_EXE) copy $(TARGET_EXE) $(EFI_PLATFORM_BIN)\tools\$(TARGET_NAME).exe /Y - if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb \ - copy $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb /Y -!ENDIF - -clean: - @if exist $(EDK_TOOLS_OUTPUT)\GetDrvNumOffset.* del $(EDK_TOOLS_OUTPUT)\GetDrvNumOffset.* > NUL - @if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL - diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/GenCRC32Section/makefile b/EdkCompatibilityPkg/Sample/Tools/Source/GenCRC32Section/makefile index f6c07f7340..cb4bc3c408 100644 --- a/EdkCompatibilityPkg/Sample/Tools/Source/GenCRC32Section/makefile +++ b/EdkCompatibilityPkg/Sample/Tools/Source/GenCRC32Section/makefile @@ -75,11 +75,13 @@ $(TARGET_EXE): $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe !ELSE $(TARGET_EXE): $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj $(TARGET_EXE_LIBS) $(TARGET_DLL) $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj $(TARGET_LIB) $(TARGET_EXE_LIBS) +!IF ("$(EFI_BINARY_BUILD)" == "YES") if not exist $(EFI_PLATFORM_BIN)\Tools mkdir $(EFI_PLATFORM_BIN)\Tools if exist $(TARGET_EXE) copy $(TARGET_EXE) $(EFI_PLATFORM_BIN)\tools\$(TARGET_NAME).exe /Y if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb \ copy $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb /Y !ENDIF +!ENDIF clean: @if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/GenDepex/GenDepex.c b/EdkCompatibilityPkg/Sample/Tools/Source/GenDepex/GenDepex.c index cebcc01f9b..59a8f384b3 100644 --- a/EdkCompatibilityPkg/Sample/Tools/Source/GenDepex/GenDepex.c +++ b/EdkCompatibilityPkg/Sample/Tools/Source/GenDepex/GenDepex.c @@ -841,12 +841,12 @@ Returns: // // Output the calling arguments // - printf ("\n\n"); - for (Index = 0; Index < argc; Index++) { - printf ("%s ", argv[Index]); - } - - printf ("\n\n"); + //printf ("\n\n"); + //for (Index = 0; Index < argc; Index++) { + // printf ("%s ", argv[Index]); + //} + // + //printf ("\n\n"); if (argc < 5) { printf ("Not enough arguments\n"); diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/GenDepex/makefile b/EdkCompatibilityPkg/Sample/Tools/Source/GenDepex/makefile index 4faceb1802..504935305e 100644 --- a/EdkCompatibilityPkg/Sample/Tools/Source/GenDepex/makefile +++ b/EdkCompatibilityPkg/Sample/Tools/Source/GenDepex/makefile @@ -80,11 +80,13 @@ $(TARGET_EXE): $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe !ELSE $(TARGET_EXE): $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj $(TARGET_LIB) $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj $(TARGET_LIB) +!IF ("$(EFI_BINARY_BUILD)" == "YES") if not exist $(EFI_PLATFORM_BIN)\Tools mkdir $(EFI_PLATFORM_BIN)\Tools if exist $(TARGET_EXE) copy $(TARGET_EXE) $(EFI_PLATFORM_BIN)\tools\$(TARGET_NAME).exe /Y if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb \ copy $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb /Y !ENDIF +!ENDIF # # Build LIB diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/GenFfsFile/GenFfsFile.c b/EdkCompatibilityPkg/Sample/Tools/Source/GenFfsFile/GenFfsFile.c index 188ca77945..2e06570633 100644 --- a/EdkCompatibilityPkg/Sample/Tools/Source/GenFfsFile/GenFfsFile.c +++ b/EdkCompatibilityPkg/Sample/Tools/Source/GenFfsFile/GenFfsFile.c @@ -24,6 +24,7 @@ Abstract: #include "EfiFirmwareFileSystem.h" #include "EfiFirmwareVolumeHeader.h" #include "EfiImageFormat.h" +#include "EfiImage.h" #include "ParseInf.h" #include "Compress.h" #include "EfiCustomizedCompress.h" @@ -82,6 +83,39 @@ PrintUsage ( void ); +static +void +AddMacro ( + UINT8 *MacroString + ); + +static +UINT8 * +GetMacroValue ( + UINT8 *MacroName + ); + +static +void +FreeMacros ( + ); + +static +STATUS +ReplaceMacros ( + UINT8 *InputFile, + UINT8 *OutputFile + ); + +// +// Linked list to keep track of all macros +// +typedef struct _MACRO { + struct _MACRO *Next; + UINT8 *Name; + UINT8 *Value; +} MACRO; + // // Keep globals in this structure // @@ -90,10 +124,13 @@ static struct { UINT8 PrimaryPackagePath[_MAX_PATH]; UINT8 OverridePackagePath[_MAX_PATH]; BOOLEAN Verbose; + MACRO *MacroList; } mGlobals; static EFI_GUID mZeroGuid = { 0 }; +static UINT8 MinFfsDataAlignOverride = 0; + static void StripQuotes ( @@ -151,8 +188,9 @@ Returns: --*/ { printf ("Usage:\n"); - printf (UTILITY_NAME " -b \"build directory\" -p1 \"package1.inf\" -p2 \"package2.inf\" -v\n"); - printf (" -b \"build directory\":\n "); + printf (UTILITY_NAME " -b \"build directory\" -p1 \"package1.inf\" -p2 \"package2.inf\"\n"); + printf (" -d \"name=value\" -v\n"); + printf (" -b \"build directory\":\n"); printf (" specifies the full path to the component build directory.\n"); printf (" -p1 \"P1_path\":\n"); printf (" specifies fully qualified file name to the primary package file.\n"); @@ -161,6 +199,10 @@ Returns: printf (" -p2 \"P2_path\":\n"); printf (" specifies fully qualified file name to the override package file.\n"); printf (" This file will normally exist in the build tip. Optional.\n"); + printf (" -d \"name=value\":\n"); + printf (" add a macro definition for package file. Optional.\n"); + printf (" -v :\n"); + printf (" verbose. Optional.\n"); } static @@ -756,54 +798,6 @@ Returns: return ; } -static -INT32 -ProcessEnvironmentVariable ( - IN CHAR8 *Buffer, - OUT CHAR8 *NewBuffer - ) -/*++ - -Routine Description: - - Converts environment variables to values - -Arguments: - - Buffer - Buffer containing Environment Variable String - - NewBuffer - Buffer containing value of environment variable - - -Returns: - - Number of characters from Buffer used - ---*/ -{ - INT32 Index; - INT32 Index2; - CHAR8 VariableBuffer[_MAX_PATH]; - - Index = 2; - Index2 = 0; - - while (Buffer[Index] != ')') { - VariableBuffer[Index - 2] = Buffer[Index++]; - } - - VariableBuffer[Index - 2] = 0; - Index++; - - if (getenv (VariableBuffer) != NULL) { - strcpy (NewBuffer, getenv (VariableBuffer)); - } else { - printf ("Environment variable %s not found!\n", VariableBuffer); - } - - return Index; -} - static void SplitAttributesField ( @@ -880,7 +874,6 @@ GetToolArguments ( UINT32 Index2; UINT32 z; CHAR8 *CharBuffer; - INT32 Index; INT32 ReturnValue; EFI_STATUS Status; @@ -982,17 +975,7 @@ GetToolArguments ( ToolArgumentsArray[argc] = CharBuffer; - if (Buffer[0] == '$') { - Index = ProcessEnvironmentVariable (&Buffer[0], ToolArgumentsArray[argc]); - // - // if there is string after the environment variable, cat it. - // - if ((UINT32) Index < strlen (Buffer)) { - strcat (ToolArgumentsArray[argc], &Buffer[Index]); - } - } else { - strcpy (ToolArgumentsArray[argc], Buffer); - } + strcpy (ToolArgumentsArray[argc], Buffer); argc += 1; ToolArgumentsArray[argc] = NULL; @@ -1010,17 +993,7 @@ GetToolArguments ( ZeroMem (InputFileName, sizeof (_MAX_PATH)); - if (Buffer[0] == '$') { - Index = ProcessEnvironmentVariable (&Buffer[0], InputFileName); - // - // if there is string after the environment variable, cat it. - // - if ((UINT32) Index < strlen (Buffer)) { - strcat (InputFileName, &Buffer[Index]); - } - } else { - strcpy (InputFileName, Buffer); - } + strcpy (InputFileName, Buffer); InputFlag = FALSE; continue; @@ -1037,17 +1010,7 @@ GetToolArguments ( ZeroMem (OutputFileName, sizeof (_MAX_PATH)); - if (Buffer[0] == '$') { - Index = ProcessEnvironmentVariable (&Buffer[0], OutputFileName); - // - // if there is string after the environment variable, cat it. - // - if ((UINT32) Index < strlen (Buffer)) { - strcat (OutputFileName, &Buffer[Index]); - } - } else { - strcpy (OutputFileName, Buffer); - } + strcpy (OutputFileName, Buffer); OutputFlag = FALSE; continue; @@ -1139,10 +1102,12 @@ Returns: { EFI_STATUS Status; UINT32 Size; + UINT32 OldSize; + UINT32 Adjust; + UINT16 TeStrippedSize; CHAR8 Buffer[_MAX_PATH]; CHAR8 Type[_MAX_PATH]; CHAR8 FileName[_MAX_PATH]; - CHAR8 NewBuffer[_MAX_PATH]; INT32 Index3; INT32 Index2; UINT32 ReturnValue; @@ -1157,7 +1122,6 @@ Returns: FILE *InputFile; UINT8 Temp; int returnint; - INT32 Index; UINT32 LineNumber; BOOLEAN IsError; EFI_GUID SignGuid; @@ -1200,11 +1164,7 @@ Returns: } StripParens (Buffer); - if (Buffer[0] == '$') { - ProcessEnvironmentVariable (&Buffer[0], Type); - } else { - strcpy (Type, Buffer); - } + strcpy (Type, Buffer); // // build buffer // @@ -1275,19 +1235,7 @@ Returns: } StripParens (Buffer); - - if (Buffer[0] == '$') { - Index = ProcessEnvironmentVariable (&Buffer[0], ToolName); - // - // if there is string after the environment variable, cat it. - // - if ((UINT32) Index < strlen (Buffer)) { - strcat (ToolName, &Buffer[Index]); - } - } else { - strcpy (ToolName, Buffer); - } - + strcpy (ToolName, Buffer); ToolArgumentsArray[0] = ToolName; // @@ -1397,13 +1345,8 @@ Returns: if (!isalpha (Buffer[0]) || (Buffer[1] != ':')) { sprintf (FileName, "%s\\", BuildDirectory); } - + while (Buffer[Index3] != '\n') { - if (Buffer[Index3] == '$') { - Index3 += ProcessEnvironmentVariable (&Buffer[Index3], NewBuffer); - strcat (FileName, NewBuffer); - } - if (Buffer[Index3] == 0) { break; } else { @@ -1420,6 +1363,7 @@ Returns: goto Done; } + OldSize = Size; fread (&ByteBuffer, sizeof (UINT8), 1, InFile); while (!feof (InFile)) { FileBuffer[Size++] = ByteBuffer; @@ -1429,6 +1373,29 @@ Returns: fclose (InFile); InFile = NULL; + // + // Adjust the TE Section for IPF so that the function entries are 16-byte aligned. + // + if (Size - OldSize >= sizeof (EFI_COMMON_SECTION_HEADER) + sizeof (EFI_TE_IMAGE_HEADER) && + ((EFI_COMMON_SECTION_HEADER *) &FileBuffer[OldSize])->Type == EFI_SECTION_TE && + ((EFI_TE_IMAGE_HEADER *) &FileBuffer[OldSize + 4])->Machine == EFI_IMAGE_MACHINE_IA64) { + TeStrippedSize = ((EFI_TE_IMAGE_HEADER *) &FileBuffer[OldSize + 4])->StrippedSize; + Adjust = TeStrippedSize - (OldSize + sizeof (EFI_COMMON_SECTION_HEADER) + sizeof (EFI_TE_IMAGE_HEADER)); + Adjust &= 15; + if (Adjust > 0) { + memmove (&FileBuffer[OldSize + Adjust], &FileBuffer[OldSize], Size - OldSize); + // + // Pad with RAW Section type + // + *(UINT32 *)&FileBuffer[OldSize] = 0x19000000 | Adjust; + Size += Adjust; + // + // Make sure the Data alignment in FFS header is no less than 1 (16-byte aligned) + // + MinFfsDataAlignOverride = 1; + } + } + // // Make sure section ends on a DWORD boundary // @@ -2252,6 +2219,9 @@ here: memset (&FileHeader, 0, sizeof (EFI_FFS_FILE_HEADER)); memcpy (&FileHeader.Name, &FfsGuid, sizeof (EFI_GUID)); FileHeader.Type = StringToType (FileType); + if (((FfsAttrib & FFS_ATTRIB_DATA_ALIGNMENT) >> 3) < MinFfsDataAlignOverride) { + FfsAttrib = (FfsAttrib & ~FFS_ATTRIB_DATA_ALIGNMENT) | (MinFfsDataAlignOverride << 3); + } FileHeader.Attributes = FfsAttrib; // // Now FileSize includes the EFI_FFS_FILE_HEADER @@ -2396,6 +2366,9 @@ here: memset (&FileHeader, 0, sizeof (EFI_FFS_FILE_HEADER)); memcpy (&FileHeader.Name, &FfsGuid, sizeof (EFI_GUID)); FileHeader.Type = StringToType (FileType); + if (((FfsAttrib & FFS_ATTRIB_DATA_ALIGNMENT) >> 3) < MinFfsDataAlignOverride) { + FfsAttrib = (FfsAttrib & ~FFS_ATTRIB_DATA_ALIGNMENT) | (MinFfsDataAlignOverride << 3); + } FileHeader.Attributes = FfsAttrib; // // From this point on FileSize includes the size of the EFI_FFS_FILE_HEADER @@ -2540,6 +2513,7 @@ Returns: // SetUtilityName (UTILITY_NAME); Status = ProcessCommandLineArgs (argc, argv); + FreeMacros (); if (Status != STATUS_SUCCESS) { return Status; } @@ -2577,6 +2551,11 @@ Returns: --*/ { + STATUS Status; + UINT8 *OriginalPrimaryPackagePath; + UINT8 *OriginalOverridePackagePath; + UINT8 *PackageName; + // // If no args, then print usage instructions and return an error // @@ -2584,7 +2563,9 @@ Returns: PrintUsage (); return STATUS_ERROR; } - + + OriginalPrimaryPackagePath = NULL; + OriginalOverridePackagePath = NULL; memset (&mGlobals, 0, sizeof (mGlobals)); Argc--; Argv++; @@ -2617,12 +2598,12 @@ Returns: return STATUS_ERROR; } - if (mGlobals.PrimaryPackagePath[0]) { + if (OriginalPrimaryPackagePath) { Error (NULL, 0, 0, Argv[0], "option can only be specified once"); return STATUS_ERROR; } - - strcpy (mGlobals.PrimaryPackagePath, Argv[1]); + + OriginalPrimaryPackagePath = Argv[1]; Argc--; Argv++; } else if (_strcmpi (Argv[0], "-p2") == 0) { @@ -2635,12 +2616,12 @@ Returns: return STATUS_ERROR; } - if (mGlobals.OverridePackagePath[0]) { + if (OriginalOverridePackagePath) { Error (NULL, 0, 0, Argv[0], "option can only be specified once"); return STATUS_ERROR; } - - strcpy (mGlobals.OverridePackagePath, Argv[1]); + + OriginalOverridePackagePath = Argv[1]; Argc--; Argv++; } else if (_strcmpi (Argv[0], "-v") == 0) { @@ -2648,6 +2629,19 @@ Returns: // OPTION: -v verbose // mGlobals.Verbose = TRUE; + } else if (_strcmpi (Argv[0], "-d") == 0) { + // + // OPTION: -d name=value + // Make sure there is another argument, then add it to our macro list. + // + if (Argc < 2) { + Error (NULL, 0, 0, Argv[0], "option requires the macro definition"); + return STATUS_ERROR; + } + + AddMacro (Argv[1]); + Argc--; + Argv++; } else if (_strcmpi (Argv[0], "-h") == 0) { // // OPTION: -h help @@ -2669,13 +2663,324 @@ Returns: Argv++; Argc--; } + + // + // Must have at least specified the build directory + // + if (!mGlobals.BuildDirectory[0]) { + Error (NULL, 0, 0, "must specify build directory", NULL); + return STATUS_ERROR; + } + // // Must have at least specified the package file name // - if (mGlobals.PrimaryPackagePath[0] == 0) { + if (OriginalPrimaryPackagePath == NULL) { Error (NULL, 0, 0, "must specify primary package file", NULL); return STATUS_ERROR; } + PackageName = OriginalPrimaryPackagePath + strlen (OriginalPrimaryPackagePath); + while ((*PackageName != '\\') && (*PackageName != '/') && + (PackageName != OriginalPrimaryPackagePath)) { + PackageName--; + } + // + // Skip the '\' or '/' + // + if (PackageName != OriginalPrimaryPackagePath) { + PackageName++; + } + sprintf (mGlobals.PrimaryPackagePath, "%s\\%s.new", mGlobals.BuildDirectory, PackageName); + Status = ReplaceMacros (OriginalPrimaryPackagePath, mGlobals.PrimaryPackagePath); + if (Status == STATUS_WARNING) { + // + // No macro replacement, use the previous package file + // + strcpy (mGlobals.PrimaryPackagePath, OriginalPrimaryPackagePath); + } else if (Status != STATUS_SUCCESS) { + return Status; + } + + if (OriginalOverridePackagePath != NULL) { + PackageName = OriginalOverridePackagePath + strlen (OriginalOverridePackagePath); + while ((*PackageName != '\\') && (*PackageName != '/') && + (PackageName != OriginalOverridePackagePath)) { + PackageName--; + } + // + // Skip the '\' or '/' + // + if (PackageName != OriginalOverridePackagePath) { + PackageName++; + } + sprintf (mGlobals.OverridePackagePath, "%s\\%s.new", mGlobals.BuildDirectory, PackageName); + Status = ReplaceMacros (OriginalOverridePackagePath, mGlobals.OverridePackagePath); + if (Status == STATUS_WARNING) { + // + // No macro replacement, use the previous package file + // + strcpy (mGlobals.OverridePackagePath, OriginalOverridePackagePath); + } else if (Status != STATUS_SUCCESS) { + return Status; + } + } + return STATUS_SUCCESS; } + +static +void +AddMacro ( + UINT8 *MacroString + ) +/*++ + +Routine Description: + + Add or override a macro definition. + +Arguments: + + MacroString - macro definition string: name=value + +Returns: + + None + +--*/ +{ + MACRO *Macro; + MACRO *NewMacro; + UINT8 *Value; + + // + // Seperate macro name and value by '\0' + // + for (Value = MacroString; *Value && (*Value != '='); Value++); + + if (*Value == '=') { + *Value = '\0'; + Value ++; + } + + // + // We now have a macro name and value. + // Look for an existing macro and overwrite it. + // + Macro = mGlobals.MacroList; + while (Macro) { + if (_strcmpi (MacroString, Macro->Name) == 0) { + Macro->Value = Value; + return; + } + + Macro = Macro->Next; + } + + // + // Does not exist, create a new one + // + NewMacro = (MACRO *) malloc (sizeof (MACRO)); + memset ((UINT8 *) NewMacro, 0, sizeof (MACRO)); + NewMacro->Name = MacroString; + NewMacro->Value = Value; + + // + // Add it to the head of the list. + // + NewMacro->Next = mGlobals.MacroList; + mGlobals.MacroList = NewMacro; + + return; +} + +static +UINT8 * +GetMacroValue ( + UINT8 *MacroName + ) +/*++ + +Routine Description: + + Look up a macro. + +Arguments: + + MacroName - The name of macro + +Returns: + + Pointer to the value of the macro if found + NULL if the macro is not found + +--*/ +{ + + MACRO *Macro; + UINT8 *Value; + + // + // Scan for macro + // + Macro = mGlobals.MacroList; + while (Macro) { + if (_strcmpi (MacroName, Macro->Name) == 0) { + return Macro->Value; + } + Macro = Macro->Next; + } + + // + // Try environment variable + // + Value = getenv (MacroName); + if (Value == NULL) { + printf ("Environment variable %s not found!\n", MacroName); + } + return Value; +} + +static +void +FreeMacros ( + ) +/*++ + +Routine Description: + + Free the macro list. + +Arguments: + + None + +Returns: + + None + +--*/ +{ + MACRO *Macro; + MACRO *NextMacro; + + Macro = mGlobals.MacroList; + while (Macro) { + NextMacro = Macro->Next; + free (Macro); + Macro = NextMacro; + } + mGlobals.MacroList = NULL; + + return; +} + +static +STATUS +ReplaceMacros ( + UINT8 *InputFile, + UINT8 *OutputFile + ) +/*++ + +Routine Description: + + Replace all the macros in InputFile to create the OutputFile. + +Arguments: + + InputFile - Input package file for macro replacement + OutputFile - Output package file after macro replacement + +Returns: + + STATUS_SUCCESS - Output package file is created successfully after the macro replacement. + STATUS_WARNING - Output package file is not created because of no macro replacement. + STATUS_ERROR - Some error occurred during execution. + +--*/ +{ + FILE *Fptr; + UINT8 *SaveStart; + UINT8 *FromPtr; + UINT8 *ToPtr; + UINT8 *Value; + UINT8 *FileBuffer; + UINTN FileSize; + + // + // Get the file size, and then read the entire thing into memory. + // Allocate extra space for a terminator character. + // + if ((Fptr = fopen (InputFile, "r")) == NULL) { + Error (NULL, 0, 0, InputFile, "can't open input file"); + return STATUS_ERROR; + } + fseek (Fptr, 0, SEEK_END); + FileSize = ftell (Fptr); + fseek (Fptr, 0, SEEK_SET); + FileBuffer = malloc (FileSize + 1); + if (FileBuffer == NULL) { + fclose (Fptr); + Error (NULL, 0, 0, InputFile, "file buffer memory allocation failure"); + return STATUS_ERROR; + } + fread (FileBuffer, FileSize, 1, Fptr); + FileBuffer[FileSize] = '\0'; + fclose (Fptr); + + // + // Walk the entire file, replacing $(MACRO_NAME). + // + Fptr = NULL; + FromPtr = FileBuffer; + SaveStart = FromPtr; + while (*FromPtr) { + if ((*FromPtr == '$') && (*(FromPtr + 1) == '(')) { + FromPtr += 2; + for (ToPtr = FromPtr; *ToPtr && (*ToPtr != ')'); ToPtr++); + if (*ToPtr) { + // + // Find an $(MACRO_NAME), replace it + // + *ToPtr = '\0'; + Value = GetMacroValue (FromPtr); + *(FromPtr-2)= '\0'; + if (Fptr == NULL) { + if ((Fptr = fopen (OutputFile, "w")) == NULL) { + free (FileBuffer); + Error (NULL, 0, 0, OutputFile, "can't open output file"); + return STATUS_ERROR; + } + } + if (Value != NULL) { + fprintf (Fptr, "%s%s", SaveStart, Value); + } else { + fprintf (Fptr, "%s", SaveStart); + } + // + // Continue macro replacement for the remaining string line + // + FromPtr = ToPtr+1; + SaveStart = FromPtr; + continue; + } else { + break; + } + } else { + FromPtr++; + } + } + if (Fptr != NULL) { + fprintf (Fptr, "%s", SaveStart); + } + + free (FileBuffer); + if (Fptr != NULL) { + fclose (Fptr); + return STATUS_SUCCESS; + } else { + return STATUS_WARNING; + } +} diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/GenFfsFile/makefile b/EdkCompatibilityPkg/Sample/Tools/Source/GenFfsFile/makefile index 85f9cfde9a..2be50923ad 100644 --- a/EdkCompatibilityPkg/Sample/Tools/Source/GenFfsFile/makefile +++ b/EdkCompatibilityPkg/Sample/Tools/Source/GenFfsFile/makefile @@ -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) $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj \ $(TARGET_LIB) $(TARGET_EXE_LIBS) +!IF ("$(EFI_BINARY_BUILD)" == "YES") if not exist $(EFI_PLATFORM_BIN)\Tools mkdir $(EFI_PLATFORM_BIN)\Tools if exist $(TARGET_EXE) copy $(TARGET_EXE) $(EFI_PLATFORM_BIN)\tools\$(TARGET_NAME).exe /Y if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb \ copy $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb /Y !ENDIF +!ENDIF clean: @if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/GenFvImage/GenFvImageLib.h b/EdkCompatibilityPkg/Sample/Tools/Source/GenFvImage/GenFvImageLib.h index e1db1b1468..d275ffbc3a 100644 --- a/EdkCompatibilityPkg/Sample/Tools/Source/GenFvImage/GenFvImageLib.h +++ b/EdkCompatibilityPkg/Sample/Tools/Source/GenFvImage/GenFvImageLib.h @@ -26,7 +26,7 @@ Abstract: // // Include files // -#include "Efi2WinNT.h" +#include #include "ParseInf.h" // diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/GenFvImage/Makefile b/EdkCompatibilityPkg/Sample/Tools/Source/GenFvImage/Makefile index d3b43c0ab7..18243b697b 100644 --- a/EdkCompatibilityPkg/Sample/Tools/Source/GenFvImage/Makefile +++ b/EdkCompatibilityPkg/Sample/Tools/Source/GenFvImage/Makefile @@ -88,11 +88,13 @@ $(TARGET_EXE): $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe !ELSE $(TARGET_EXE): $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj $(TARGET_EXE_LIBS) $(TARGET_LIB) $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj $(TARGET_LIB) $(TARGET_EXE_LIBS) +!IF ("$(EFI_BINARY_BUILD)" == "YES") if not exist $(EFI_PLATFORM_BIN)\Tools mkdir $(EFI_PLATFORM_BIN)\Tools if exist $(TARGET_EXE) copy $(TARGET_EXE) $(EFI_PLATFORM_BIN)\tools\$(TARGET_NAME).exe /Y if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb \ copy $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb /Y !ENDIF +!ENDIF # # Build LIB diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/GenPage/VirtualMemory.h b/EdkCompatibilityPkg/Sample/Tools/Source/GenPage/VirtualMemory.h deleted file mode 100644 index d9d928f4e4..0000000000 --- a/EdkCompatibilityPkg/Sample/Tools/Source/GenPage/VirtualMemory.h +++ /dev/null @@ -1,127 +0,0 @@ -/*++ - -Copyright 2006 - 2007, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - VirtualMemory.h - -Abstract: - - x64 Long Mode Virtual Memory Management Definitions - - References: - 1) IA-32 Intel(R) Atchitecture Software Developer's Manual Volume 1:Basic Architecture, Intel - 2) IA-32 Intel(R) Atchitecture Software Developer's Manual Volume 2:Instruction Set Reference, Intel - 3) IA-32 Intel(R) Atchitecture Software Developer's Manual Volume 3:System Programmer's Guide, Intel - 4) AMD64 Architecture Programmer's Manual Volume 2: System Programming ---*/ - -#ifndef _VIRTUAL_MEMORY_H_ -#define _VIRTUAL_MEMORY_H_ - -#include "Tiano.h" - -#pragma pack(1) - -// -// Page-Map Level-4 Offset (PML4) and -// Page-Directory-Pointer Offset (PDPE) entries 4K & 2MB -// - -typedef union { - struct { - UINT64 Present:1; // 0 = Not present in memory, 1 = Present in memory - UINT64 ReadWrite:1; // 0 = Read-Only, 1= Read/Write - UINT64 UserSupervisor:1; // 0 = Supervisor, 1=User - UINT64 WriteThrough:1; // 0 = Write-Back caching, 1=Write-Through caching - UINT64 CacheDisabled:1; // 0 = Cached, 1=Non-Cached - UINT64 Accessed:1; // 0 = Not accessed, 1 = Accessed (set by CPU) - UINT64 Reserved:1; // Reserved - UINT64 MustBeZero:2; // Must Be Zero - UINT64 Available:3; // Available for use by system software - UINT64 PageTableBaseAddress:40; // Page Table Base Address - UINT64 AvabilableHigh:11; // Available for use by system software - UINT64 Nx:1; // No Execute bit - } Bits; - UINT64 Uint64; -} X64_PAGE_MAP_AND_DIRECTORY_POINTER_2MB_4K; - -// -// Page-Directory Offset 4K -// -typedef union { - struct { - UINT64 Present:1; // 0 = Not present in memory, 1 = Present in memory - UINT64 ReadWrite:1; // 0 = Read-Only, 1= Read/Write - UINT64 UserSupervisor:1; // 0 = Supervisor, 1=User - UINT64 WriteThrough:1; // 0 = Write-Back caching, 1=Write-Through caching - UINT64 CacheDisabled:1; // 0 = Cached, 1=Non-Cached - UINT64 Accessed:1; // 0 = Not accessed, 1 = Accessed (set by CPU) - UINT64 Reserved:1; // Reserved - UINT64 MustBeZero:1; // Must Be Zero - UINT64 Reserved2:1; // Reserved - UINT64 Available:3; // Available for use by system software - UINT64 PageTableBaseAddress:40; // Page Table Base Address - UINT64 AvabilableHigh:11; // Available for use by system software - UINT64 Nx:1; // No Execute bit - } Bits; - UINT64 Uint64; -} X64_PAGE_DIRECTORY_ENTRY_4K; - -// -// Page Table Entry 4K -// -typedef union { - struct { - UINT64 Present:1; // 0 = Not present in memory, 1 = Present in memory - UINT64 ReadWrite:1; // 0 = Read-Only, 1= Read/Write - UINT64 UserSupervisor:1; // 0 = Supervisor, 1=User - UINT64 WriteThrough:1; // 0 = Write-Back caching, 1=Write-Through caching - UINT64 CacheDisabled:1; // 0 = Cached, 1=Non-Cached - UINT64 Accessed:1; // 0 = Not accessed, 1 = Accessed (set by CPU) - UINT64 Dirty:1; // 0 = Not Dirty, 1 = written by processor on access to page - UINT64 PAT:1; // 0 = Ignore Page Attribute Table - UINT64 Global:1; // 0 = Not global page, 1 = global page TLB not cleared on CR3 write - UINT64 Available:3; // Available for use by system software - UINT64 PageTableBaseAddress:40; // Page Table Base Address - UINT64 AvabilableHigh:11; // Available for use by system software - UINT64 Nx:1; // 0 = Execute Code, 1 = No Code Execution - } Bits; - UINT64 Uint64; -} X64_PAGE_TABLE_ENTRY_4K; - - -// -// Page Table Entry 2MB -// -typedef union { - struct { - UINT64 Present:1; // 0 = Not present in memory, 1 = Present in memory - UINT64 ReadWrite:1; // 0 = Read-Only, 1= Read/Write - UINT64 UserSupervisor:1; // 0 = Supervisor, 1=User - UINT64 WriteThrough:1; // 0 = Write-Back caching, 1=Write-Through caching - UINT64 CacheDisabled:1; // 0 = Cached, 1=Non-Cached - UINT64 Accessed:1; // 0 = Not accessed, 1 = Accessed (set by CPU) - UINT64 Dirty:1; // 0 = Not Dirty, 1 = written by processor on access to page - UINT64 MustBe1:1; // Must be 1 - UINT64 Global:1; // 0 = Not global page, 1 = global page TLB not cleared on CR3 write - UINT64 Available:3; // Available for use by system software - UINT64 PAT:1; // - UINT64 MustBeZero:8; // Must be zero; - UINT64 PageTableBaseAddress:31; // Page Table Base Address - UINT64 AvabilableHigh:11; // Available for use by system software - UINT64 Nx:1; // 0 = Execute Code, 1 = No Code Execution - } Bits; - UINT64 Uint64; -} X64_PAGE_TABLE_ENTRY_2M; - -#pragma pack() - -#endif diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/GenPage/genpage.c b/EdkCompatibilityPkg/Sample/Tools/Source/GenPage/genpage.c deleted file mode 100644 index 7085f198aa..0000000000 --- a/EdkCompatibilityPkg/Sample/Tools/Source/GenPage/genpage.c +++ /dev/null @@ -1,344 +0,0 @@ -/*++ - -Copyright 2006 - 2007, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - GenPage.c - -Abstract: - Pre-Create a 4G page table (2M pages). - It's used in DUET x64 build needed to enter LongMode. - - Create 4G page table (2M pages) - - Linear Address - 63 48 47 39 38 30 29 21 20 0 - +--------+-------+---------------+-----------+-----------------------------+ - PML4 Directory-Ptr Directory Offset - - Paging-Structures := - PML4 - ( - Directory-Ptr Directory {512} - ) {4} ---*/ - -#include -#include -#include "VirtualMemory.h" - -void -memset (void *, char, long); - -unsigned int -xtoi (char *); - -#define EFI_PAGE_BASE_OFFSET_IN_LDR 0x70000 -#define EFI_PAGE_BASE_ADDRESS (EFI_PAGE_BASE_OFFSET_IN_LDR + 0x20000) - -unsigned int gPageTableBaseAddress = EFI_PAGE_BASE_ADDRESS; -unsigned int gPageTableOffsetInFile = EFI_PAGE_BASE_OFFSET_IN_LDR; - -#define EFI_MAX_ENTRY_NUM 512 - -#define EFI_PML4_ENTRY_NUM 1 -#define EFI_PDPTE_ENTRY_NUM 4 -#define EFI_PDE_ENTRY_NUM EFI_MAX_ENTRY_NUM - -#define EFI_PML4_PAGE_NUM 1 -#define EFI_PDPTE_PAGE_NUM EFI_PML4_ENTRY_NUM -#define EFI_PDE_PAGE_NUM (EFI_PML4_ENTRY_NUM * EFI_PDPTE_ENTRY_NUM) - -#define EFI_PAGE_NUMBER (EFI_PML4_PAGE_NUM + EFI_PDPTE_PAGE_NUM + EFI_PDE_PAGE_NUM) - -#define EFI_SIZE_OF_PAGE 0x1000 -#define EFI_PAGE_SIZE_2M 0x200000 - -#define CONVERT_BIN_PAGE_ADDRESS(a) ((UINT8 *) a - PageTable + gPageTableBaseAddress) - - -void * -CreateIdentityMappingPageTables ( - void - ) -/*++ - -Routine Description: - To create 4G PAE 2M pagetable - -Return: - void * - buffer containing created pagetable - ---*/ -{ - UINT64 PageAddress; - UINT8 *PageTable; - UINT8 *PageTablePtr; - int PML4Index; - int PDPTEIndex; - int PDEIndex; - X64_PAGE_MAP_AND_DIRECTORY_POINTER_2MB_4K *PageMapLevel4Entry; - X64_PAGE_MAP_AND_DIRECTORY_POINTER_2MB_4K *PageDirectoryPointerEntry; - X64_PAGE_TABLE_ENTRY_2M *PageDirectoryEntry2MB; - - PageTable = (void *)malloc (EFI_PAGE_NUMBER * EFI_SIZE_OF_PAGE); - memset (PageTable, 0, (EFI_PAGE_NUMBER * EFI_SIZE_OF_PAGE)); - PageTablePtr = PageTable; - - PageAddress = 0; - - // - // Page Table structure 3 level 2MB. - // - // Page-Map-Level-4-Table : bits 47-39 - // Page-Directory-Pointer-Table : bits 38-30 - // - // Page Table 2MB : Page-Directory(2M) : bits 29-21 - // - // - - PageMapLevel4Entry = (X64_PAGE_MAP_AND_DIRECTORY_POINTER_2MB_4K *)PageTablePtr; - - for (PML4Index = 0; PML4Index < EFI_PML4_ENTRY_NUM; PML4Index++, PageMapLevel4Entry++) { - // - // Each Page-Map-Level-4-Table Entry points to the base address of a Page-Directory-Pointer-Table Entry - // - PageTablePtr += EFI_SIZE_OF_PAGE; - PageDirectoryPointerEntry = (X64_PAGE_MAP_AND_DIRECTORY_POINTER_2MB_4K *)PageTablePtr; - - // - // Make a Page-Map-Level-4-Table Entry - // - PageMapLevel4Entry->Uint64 = (UINT64)(UINT32)(CONVERT_BIN_PAGE_ADDRESS (PageDirectoryPointerEntry)); - PageMapLevel4Entry->Bits.ReadWrite = 1; - PageMapLevel4Entry->Bits.Present = 1; - - for (PDPTEIndex = 0; PDPTEIndex < EFI_PDPTE_ENTRY_NUM; PDPTEIndex++, PageDirectoryPointerEntry++) { - // - // Each Page-Directory-Pointer-Table Entry points to the base address of a Page-Directory Entry - // - PageTablePtr += EFI_SIZE_OF_PAGE; - PageDirectoryEntry2MB = (X64_PAGE_TABLE_ENTRY_2M *)PageTablePtr; - - // - // Make a Page-Directory-Pointer-Table Entry - // - PageDirectoryPointerEntry->Uint64 = (UINT64)(UINT32)(CONVERT_BIN_PAGE_ADDRESS (PageDirectoryEntry2MB)); - PageDirectoryPointerEntry->Bits.ReadWrite = 1; - PageDirectoryPointerEntry->Bits.Present = 1; - - for (PDEIndex = 0; PDEIndex < EFI_PDE_ENTRY_NUM; PDEIndex++, PageDirectoryEntry2MB++) { - // - // Make a Page-Directory Entry - // - PageDirectoryEntry2MB->Uint64 = (UINT64)PageAddress; - PageDirectoryEntry2MB->Bits.ReadWrite = 1; - PageDirectoryEntry2MB->Bits.Present = 1; - PageDirectoryEntry2MB->Bits.MustBe1 = 1; - - PageAddress += EFI_PAGE_SIZE_2M; - } - } - } - - return PageTable; -} - -int -GenBinPage ( - void *BaseMemory, - char *NoPageFileName, - char *PageFileName - ) -/*++ - -Routine Description: - Write the buffer containing page table to file at a specified offset. - Here the offset is defined as EFI_PAGE_BASE_OFFSET_IN_LDR. - -Arguments: - BaseMemory - buffer containing page table - NoPageFileName - file to write page table - PageFileName - file save to after writing - -return: - 0 : successful - -1 : failed - ---*/ -{ - FILE *PageFile; - FILE *NoPageFile; - UINT8 Data; - unsigned long FileSize; - - // - // Open files - // - PageFile = fopen (PageFileName, "w+b"); - if (PageFile == NULL) { - fprintf (stderr, "GenBinPage: Could not open file %s\n", PageFileName); - return -1; - } - - NoPageFile = fopen (NoPageFileName, "r+b"); - if (NoPageFile == NULL) { - fprintf (stderr, "GenBinPage: Could not open file %s\n", NoPageFileName); - fclose (PageFile); - return -1; - } - - // - // Check size - should not be great than EFI_PAGE_BASE_OFFSET_IN_LDR - // - fseek (NoPageFile, 0, SEEK_END); - FileSize = ftell (NoPageFile); - fseek (NoPageFile, 0, SEEK_SET); - if (FileSize > gPageTableOffsetInFile) { - fprintf (stderr, "GenBinPage: file size too large - 0x%x\n", FileSize); - fclose (PageFile); - fclose (NoPageFile); - return -1; - } - - // - // Write data - // - while (fread (&Data, sizeof(UINT8), 1, NoPageFile)) { - fwrite (&Data, sizeof(UINT8), 1, PageFile); - } - - // - // Write PageTable - // - fseek (PageFile, gPageTableOffsetInFile, SEEK_SET); - fwrite (BaseMemory, (EFI_PAGE_NUMBER * EFI_SIZE_OF_PAGE), 1, PageFile); - - // - // Close files - // - fclose (PageFile); - fclose (NoPageFile); - - return 0; -} - -int -main ( - int argc, - char **argv - ) -{ - void *BaseMemory; - int result; - - // - // Check parameter - // - if ((argc != 3) && (argc != 5)) { - printf ("Usage: GenPage.exe NoPageFile PageFile [ ]\n"); - return 1; - } - - // - // Get PageTable parameter, if have - // - if (argc == 5) { - gPageTableBaseAddress = xtoi (argv[3]); - gPageTableOffsetInFile = xtoi (argv[4]); - } - - // - // Create X64 page table - // - BaseMemory = CreateIdentityMappingPageTables (); - - // - // Add page table to binary file - // - result = GenBinPage (BaseMemory, argv[1], argv[2]); - if (result < 0) { - return 1; - } - - return 0; -} - -unsigned int -xtoi ( - char *str - ) -/*++ - -Routine Description: - - Convert hex string to uint - -Arguments: - - Str - The string - -Returns: - ---*/ -{ - unsigned int u; - char c; - unsigned int m; - - if (str == NULL) { - return 0; - } - - m = (unsigned int) -1 >> 4; - // - // skip preceeding white space - // - while (*str && *str == ' ') { - str += 1; - } - // - // skip preceeding zeros - // - while (*str && *str == '0') { - str += 1; - } - // - // skip preceeding white space - // - if (*str && (*str == 'x' || *str == 'X')) { - str += 1; - } - // - // convert hex digits - // - u = 0; - c = *(str++); - while (c) { - if (c >= 'a' && c <= 'f') { - c -= 'a' - 'A'; - } - - if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F')) { - if (u > m) { - return (unsigned int) -1; - } - - u = u << 4 | c - (c >= 'A' ? 'A' - 10 : '0'); - } else { - break; - } - - c = *(str++); - } - - return u; -} - diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/GenSection/makefile b/EdkCompatibilityPkg/Sample/Tools/Source/GenSection/makefile index 053d2376a0..963ff16ef2 100644 --- a/EdkCompatibilityPkg/Sample/Tools/Source/GenSection/makefile +++ b/EdkCompatibilityPkg/Sample/Tools/Source/GenSection/makefile @@ -72,11 +72,13 @@ $(TARGET_EXE): $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe !ELSE $(TARGET_EXE): $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj $(LIBS) $(TARGET_EXE_LIBS) $(LINK) /DEBUG $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj $(TARGET_EXE_LIBS) +!IF ("$(EFI_BINARY_BUILD)" == "YES") if not exist $(EFI_PLATFORM_BIN)\Tools mkdir $(EFI_PLATFORM_BIN)\Tools if exist $(TARGET_EXE) copy $(TARGET_EXE) $(EFI_PLATFORM_BIN)\tools\$(TARGET_NAME).exe /Y if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb \ copy $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb /Y !ENDIF +!ENDIF clean: @if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/GenTEImage/GenTEImage.c b/EdkCompatibilityPkg/Sample/Tools/Source/GenTEImage/GenTEImage.c new file mode 100644 index 0000000000..6f22782daf --- /dev/null +++ b/EdkCompatibilityPkg/Sample/Tools/Source/GenTEImage/GenTEImage.c @@ -0,0 +1,929 @@ +/*++ + +Copyright (c) 1999 - 2007, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + GenTEImage.c + +Abstract: + + Utility program to shrink a PE32 image down by replacing + the DOS, PE, and optional headers with a minimal header. + +--*/ + +#include +#include +#include + +#include "Tiano.h" +#include "TianoCommon.h" +#include "EfiImage.h" // for PE32 structure definitions +#include "EfiUtilityMsgs.h" + +// +// Version of this utility +// +#define UTILITY_NAME "GenTEImage" +#define UTILITY_VERSION "v0.11" + +// +// Define the max length of a filename +// +#define MAX_PATH 256 +#define DEFAULT_OUTPUT_EXTENSION ".te" + +// +// Use this to track our command-line options and globals +// +struct { + INT8 OutFileName[MAX_PATH]; + INT8 InFileName[MAX_PATH]; + INT8 Verbose; + INT8 Dump; +} mOptions; + +// +// Use these to convert from machine type value to a named type +// +typedef struct { + UINT16 Value; + INT8 *Name; +} STRING_LOOKUP; + +static STRING_LOOKUP mMachineTypes[] = { + EFI_IMAGE_MACHINE_IA32, + "IA32", + EFI_IMAGE_MACHINE_IA64, + "IA64", + EFI_IMAGE_MACHINE_X64, + "X64", + EFI_IMAGE_MACHINE_EBC, + "EBC", + 0, + NULL +}; + +static STRING_LOOKUP mSubsystemTypes[] = { + EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION, + "EFI application", + EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER, + "EFI boot service driver", + EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER, + "EFI runtime driver", + 0, + NULL +}; +// +// Function prototypes +// +static +void +Usage ( + VOID + ); + +static +STATUS +ParseCommandLine ( + int Argc, + char *Argv[] + ); + +static +STATUS +CheckPE32File ( + INT8 *FileName, + FILE *Fptr, + UINT16 *MachineType, + UINT16 *SubSystem + ); + +static +STATUS +ProcessFile ( + INT8 *InFileName, + INT8 *OutFileName + ); + +static +void +DumpImage ( + INT8 *FileName + ); + +static +INT8 * +GetMachineTypeStr ( + UINT16 MachineType + ); + +static +INT8 * +GetSubsystemTypeStr ( + UINT16 SubsystemType + ); + +int +main ( + int Argc, + char *Argv[] + ) +/*++ + +Routine Description: + + +Arguments: + + Argc - standard C main() argument count + + Argv - standard C main() argument list + +Returns: + + 0 success + non-zero otherwise + +--*/ +// GC_TODO: ] - add argument and description to function comment +{ + INT8 *Ext; + UINT32 Status; + + SetUtilityName (UTILITY_NAME); + // + // Parse the command line arguments + // + if (ParseCommandLine (Argc, Argv)) { + return STATUS_ERROR; + } + // + // If dumping an image, then do that and quit + // + if (mOptions.Dump) { + DumpImage (mOptions.InFileName); + goto Finish; + } + // + // Determine the output filename. Either what they specified on + // the command line, or the first input filename with a different extension. + // + if (!mOptions.OutFileName[0]) { + strcpy (mOptions.OutFileName, mOptions.InFileName); + // + // Find the last . on the line and replace the filename extension with + // the default + // + for (Ext = mOptions.OutFileName + strlen (mOptions.OutFileName) - 1; + (Ext >= mOptions.OutFileName) && (*Ext != '.') && (*Ext != '\\'); + Ext-- + ) + ; + // + // If dot here, then insert extension here, otherwise append + // + if (*Ext != '.') { + Ext = mOptions.OutFileName + strlen (mOptions.OutFileName); + } + + strcpy (Ext, DEFAULT_OUTPUT_EXTENSION); + } + // + // Make sure we don't have the same filename for input and output files + // + if (_stricmp (mOptions.OutFileName, mOptions.InFileName) == 0) { + Error (NULL, 0, 0, mOptions.OutFileName, "input and output file names must be different"); + goto Finish; + } + // + // Process the file + // + ProcessFile (mOptions.InFileName, mOptions.OutFileName); +Finish: + Status = GetUtilityStatus (); + return Status; +} + +static +STATUS +ProcessFile ( + INT8 *InFileName, + INT8 *OutFileName + ) +/*++ + +Routine Description: + + Process a PE32 EFI file. + +Arguments: + + InFileName - the file name pointer to the input file + OutFileName - the file name pointer to the output file + +Returns: + + STATUS_SUCCESS - the process has been finished successfully + STATUS_ERROR - error occured during the processing + +--*/ +{ + STATUS Status; + FILE *InFptr; + FILE *OutFptr; + UINT16 MachineType; + UINT16 SubSystem; + EFI_TE_IMAGE_HEADER TEImageHeader; + UINT32 PESigOffset; + EFI_IMAGE_FILE_HEADER FileHeader; + EFI_IMAGE_OPTIONAL_HEADER32 OptionalHeader32; + EFI_IMAGE_OPTIONAL_HEADER64 OptionalHeader64; + UINT32 BytesStripped; + UINT32 FileSize; + UINT8 *Buffer; + long SaveFilePosition; + + InFptr = NULL; + OutFptr = NULL; + Buffer = NULL; + Status = STATUS_ERROR; + + // + // Try to open the input file + // + if ((InFptr = fopen (InFileName, "rb")) == NULL) { + Error (NULL, 0, 0, InFileName, "failed to open input file for reading"); + return STATUS_ERROR; + } + // + // Double-check the file to make sure it's what we expect it to be + // + if (CheckPE32File (InFileName, InFptr, &MachineType, &SubSystem) != STATUS_SUCCESS) { + goto Finish; + } + // + // Initialize our new header + // + memset (&TEImageHeader, 0, sizeof (EFI_TE_IMAGE_HEADER)); + + // + // Seek to the end to get the file size + // + fseek (InFptr, 0, SEEK_END); + FileSize = ftell (InFptr); + fseek (InFptr, 0, SEEK_SET); + + // + // Per the PE/COFF specification, at offset 0x3C in the file is a 32-bit + // offset (from the start of the file) to the PE signature, which always + // follows the MSDOS stub. The PE signature is immediately followed by the + // COFF file header. + // + // + if (fseek (InFptr, 0x3C, SEEK_SET) != 0) { + Error (NULL, 0, 0, InFileName, "failed to seek to PE signature in file", NULL); + goto Finish; + } + + if (fread (&PESigOffset, sizeof (PESigOffset), 1, InFptr) != 1) { + Error (NULL, 0, 0, InFileName, "failed to read PE signature offset from file"); + goto Finish; + } + + if (fseek (InFptr, PESigOffset + 4, SEEK_SET) != 0) { + Error (NULL, 0, 0, InFileName, "failed to seek to PE signature"); + goto Finish; + } + // + // We should now be at the COFF file header. Read it in and verify it's + // of an image type we support. + // + if (fread (&FileHeader, sizeof (EFI_IMAGE_FILE_HEADER), 1, InFptr) != 1) { + Error (NULL, 0, 0, InFileName, "failed to read file header from image"); + goto Finish; + } + + if ((FileHeader.Machine != EFI_IMAGE_MACHINE_IA32) && + (FileHeader.Machine != EFI_IMAGE_MACHINE_X64) && + (FileHeader.Machine != EFI_IMAGE_MACHINE_IA64)) { + Error (NULL, 0, 0, InFileName, "image is of an unsupported machine type 0x%X", (UINT32) FileHeader.Machine); + goto Finish; + } + // + // Calculate the total number of bytes we're going to strip off. The '4' is for the + // PE signature PE\0\0. Then sanity check the size. + // + BytesStripped = PESigOffset + 4 + sizeof (EFI_IMAGE_FILE_HEADER) + FileHeader.SizeOfOptionalHeader; + if (BytesStripped >= FileSize) { + Error (NULL, 0, 0, InFileName, "attempt to strip more bytes than the total file size"); + goto Finish; + } + + if (BytesStripped &~0xFFFF) { + Error (NULL, 0, 0, InFileName, "attempt to strip more than 64K bytes", NULL); + goto Finish; + } + + TEImageHeader.StrippedSize = (UINT16) BytesStripped; + + // + // Read in the optional header. Assume PE32, and if not, then re-read as PE32+ + // + SaveFilePosition = ftell (InFptr); + if (fread (&OptionalHeader32, sizeof (EFI_IMAGE_OPTIONAL_HEADER32), 1, InFptr) != 1) { + Error (NULL, 0, 0, InFileName, "failed to read optional header from input file"); + goto Finish; + } + + if (OptionalHeader32.SectionAlignment != OptionalHeader32.FileAlignment) { + Error (NULL, 0, 0, InFileName, "Section alignment is not same to file alignment."); + goto Finish; + } + + if (OptionalHeader32.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { + // + // Fill in our new header with required data directory entries + // + TEImageHeader.AddressOfEntryPoint = OptionalHeader32.AddressOfEntryPoint; + // + // - BytesStripped + sizeof (EFI_TE_IMAGE_HEADER); + // + // We're going to pack the subsystem into 1 byte. Make sure it fits + // + if (OptionalHeader32.Subsystem &~0xFF) { + Error ( + NULL, + 0, + 0, + InFileName, + NULL, + "image subsystem 0x%X cannot be packed into 1 byte", + (UINT32) OptionalHeader32.Subsystem + ); + goto Finish; + } + + TEImageHeader.Subsystem = (UINT8) OptionalHeader32.Subsystem; + TEImageHeader.BaseOfCode = OptionalHeader32.BaseOfCode; + TEImageHeader.ImageBase = (UINT64) (OptionalHeader32.ImageBase); + if (OptionalHeader32.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) { + TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = OptionalHeader32.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress; + TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = OptionalHeader32.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size; + } + + if (OptionalHeader32.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) { + TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = OptionalHeader32.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress; + TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = OptionalHeader32.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size; + } + } else if (OptionalHeader32.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) { + // + // Rewind and re-read the optional header + // + fseek (InFptr, SaveFilePosition, SEEK_SET); + if (fread (&OptionalHeader64, sizeof (EFI_IMAGE_OPTIONAL_HEADER64), 1, InFptr) != 1) { + Error (NULL, 0, 0, InFileName, "failed to re-read optional header from input file"); + goto Finish; + } + + TEImageHeader.AddressOfEntryPoint = OptionalHeader64.AddressOfEntryPoint; + // + // - BytesStripped + sizeof (EFI_TE_IMAGE_HEADER); + // + // We're going to pack the subsystem into 1 byte. Make sure it fits + // + if (OptionalHeader64.Subsystem &~0xFF) { + Error ( + NULL, + 0, + 0, + InFileName, + NULL, + "image subsystem 0x%X cannot be packed into 1 byte", + (UINT32) OptionalHeader64.Subsystem + ); + goto Finish; + } + + TEImageHeader.Subsystem = (UINT8) OptionalHeader64.Subsystem; + TEImageHeader.BaseOfCode = OptionalHeader64.BaseOfCode; + TEImageHeader.ImageBase = (UINT64) (OptionalHeader64.ImageBase); + if (OptionalHeader64.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) { + TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = OptionalHeader64.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress; + TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = OptionalHeader64.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size; + } + + if (OptionalHeader64.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) { + TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = OptionalHeader64.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress; + TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = OptionalHeader64.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size; + } + } else { + Error ( + NULL, + 0, + 0, + InFileName, + "unsupported magic number 0x%X found in optional header", + (UINT32) OptionalHeader32.Magic + ); + goto Finish; + } + // + // Fill in the remainder of our new image header + // + TEImageHeader.Signature = EFI_TE_IMAGE_HEADER_SIGNATURE; + TEImageHeader.Machine = FileHeader.Machine; + // + // We're going to pack the number of sections into a single byte. Make sure it fits. + // + if (FileHeader.NumberOfSections &~0xFF) { + Error ( + NULL, + 0, + 0, + InFileName, + NULL, + "image's number of sections 0x%X cannot be packed into 1 byte", + (UINT32) FileHeader.NumberOfSections + ); + goto Finish; + } + + TEImageHeader.NumberOfSections = (UINT8) FileHeader.NumberOfSections; + + // + // Now open our output file + // + if ((OutFptr = fopen (OutFileName, "wb")) == NULL) { + Error (NULL, 0, 0, OutFileName, "failed to open output file for writing"); + goto Finish; + } + // + // Write the TE header + // + if (fwrite (&TEImageHeader, sizeof (EFI_TE_IMAGE_HEADER), 1, OutFptr) != 1) { + Error (NULL, 0, 0, "failed to write image header to output file", NULL); + goto Finish; + } + // + // Position into the input file, read the part we're not stripping, and + // write it out. + // + fseek (InFptr, BytesStripped, SEEK_SET); + Buffer = (UINT8 *) malloc (FileSize - BytesStripped); + if (Buffer == NULL) { + Error (NULL, 0, 0, "application error", "failed to allocate memory"); + goto Finish; + } + + if (fread (Buffer, FileSize - BytesStripped, 1, InFptr) != 1) { + Error (NULL, 0, 0, InFileName, "failed to read remaining contents of input file"); + goto Finish; + } + + if (fwrite (Buffer, FileSize - BytesStripped, 1, OutFptr) != 1) { + Error (NULL, 0, 0, OutFileName, "failed to write all bytes to output file"); + goto Finish; + } + + Status = STATUS_SUCCESS; + +Finish: + if (InFptr != NULL) { + fclose (InFptr); + } + // + // Close the output file. If there was an error, delete the output file so + // that a subsequent build will rebuild it. + // + if (OutFptr != NULL) { + fclose (OutFptr); + if (GetUtilityStatus () == STATUS_ERROR) { + remove (OutFileName); + } + } + + // + // Free up our buffer + // + if (Buffer != NULL) { + free (Buffer); + } + + return Status; +} + +static +STATUS +CheckPE32File ( + INT8 *FileName, + FILE *Fptr, + UINT16 *MachineType, + UINT16 *SubSystem + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + FileName - GC_TODO: add argument description + Fptr - GC_TODO: add argument description + MachineType - GC_TODO: add argument description + SubSystem - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +{ + /*++ + +Routine Description: + + Given a file pointer to a supposed PE32 image file, verify that it is indeed a + PE32 image file, and then return the machine type in the supplied pointer. + +Arguments: + + Fptr File pointer to the already-opened PE32 file + MachineType Location to stuff the machine type of the PE32 file. This is needed + because the image may be Itanium-based, IA32, or EBC. + +Returns: + + 0 success + non-zero otherwise + +--*/ + EFI_IMAGE_DOS_HEADER DosHeader; + EFI_IMAGE_FILE_HEADER FileHdr; + EFI_IMAGE_OPTIONAL_HEADER OptionalHdr; + UINT32 PESig; + STATUS Status; + + Status = STATUS_ERROR; + // + // Position to the start of the file + // + fseek (Fptr, 0, SEEK_SET); + // + // Read the DOS header + // + if (fread (&DosHeader, sizeof (DosHeader), 1, Fptr) != 1) { + Error (NULL, 0, 0, FileName, "failed to read the DOS stub from the input file"); + goto Finish; + } + // + // Check the magic number (0x5A4D) + // + if (DosHeader.e_magic != EFI_IMAGE_DOS_SIGNATURE) { + Error (NULL, 0, 0, FileName, "input file does not appear to be a PE32 image (magic number)"); + goto Finish; + } + // + // Position into the file and check the PE signature + // + fseek (Fptr, (long) DosHeader.e_lfanew, SEEK_SET); + if (fread (&PESig, sizeof (PESig), 1, Fptr) != 1) { + Error (NULL, 0, 0, FileName, "failed to read PE signature bytes"); + goto Finish; + } + // + // Check the PE signature in the header "PE\0\0" + // + if (PESig != EFI_IMAGE_NT_SIGNATURE) { + Error (NULL, 0, 0, FileName, "file does not appear to be a PE32 image (signature)"); + goto Finish; + } + // + // Read the file header + // + if (fread (&FileHdr, sizeof (FileHdr), 1, Fptr) != 1) { + Error (NULL, 0, 0, FileName, "failed to read PE file header from input file"); + goto Finish; + } + // + // Read the optional header so we can get the subsystem + // + if (fread (&OptionalHdr, sizeof (OptionalHdr), 1, Fptr) != 1) { + Error (NULL, 0, 0, FileName, "failed to read COFF optional header from input file"); + goto Finish; + } + + *SubSystem = OptionalHdr.Subsystem; + if (mOptions.Verbose) { + fprintf (stdout, " Got subsystem = 0x%X from image\n", (int) *SubSystem); + } + // + // Good to go + // + Status = STATUS_SUCCESS; +Finish: + fseek (Fptr, 0, SEEK_SET); + return Status; +} + +static +int +ParseCommandLine ( + int Argc, + char *Argv[] + ) +/*++ + +Routine Description: + + Given the Argc/Argv program arguments, and a pointer to an options structure, + parse the command-line options and check their validity. + + +Arguments: + + Argc - standard C main() argument count + Argv - standard C main() argument list + +Returns: + + STATUS_SUCCESS success + non-zero otherwise + +--*/ +// GC_TODO: ] - add argument and description to function comment +{ + // + // Clear out the options + // + memset ((char *) &mOptions, 0, sizeof (mOptions)); + // + // Skip over the program name + // + Argc--; + Argv++; + // + // If no arguments, assume they want usage info + // + if (Argc == 0) { + Usage (); + return STATUS_ERROR; + } + // + // Process until no more arguments + // + while ((Argc > 0) && ((Argv[0][0] == '-') || (Argv[0][0] == '/'))) { + // + // To simplify string comparisons, replace slashes with dashes + // + Argv[0][0] = '-'; + if (_stricmp (Argv[0], "-o") == 0) { + // + // Output filename specified with -o + // Make sure there's another parameter + // + if (Argc > 1) { + strcpy (mOptions.OutFileName, Argv[1]); + } else { + Error (NULL, 0, 0, Argv[0], "missing output file name with option"); + Usage (); + return STATUS_ERROR; + } + + Argv++; + Argc--; + } else if ((_stricmp (Argv[0], "-h") == 0) || (strcmp (Argv[0], "-?") == 0)) { + // + // Help option + // + Usage (); + return STATUS_ERROR; + } else if (_stricmp (Argv[0], "-v") == 0) { + // + // -v for verbose + // + mOptions.Verbose = 1; + } else if (_stricmp (Argv[0], "-dump") == 0) { + // + // -dump for dumping an image + // + mOptions.Dump = 1; + } else { + Error (NULL, 0, 0, Argv[0], "unrecognized option"); + Usage (); + return STATUS_ERROR; + } + // + // Next argument + // + Argv++; + Argc--; + } + // + // Better be one more arg for input file name + // + if (Argc == 0) { + Error (NULL, 0, 0, "input file name required", NULL); + Usage (); + return STATUS_ERROR; + } + + if (Argc != 1) { + Error (NULL, 0, 0, Argv[1], "extra arguments on command line"); + return STATUS_ERROR; + } + + strcpy (mOptions.InFileName, Argv[0]); + return STATUS_SUCCESS; +} + +static +void +Usage ( + VOID + ) +/*++ + +Routine Description: + + Print usage information for this utility. + +Arguments: + + None. + +Returns: + + Nothing. + +--*/ +{ + int Index; + static const char *Msg[] = { + UTILITY_NAME " version "UTILITY_VERSION " - TE image utility", + " Generate a TE image from an EFI PE32 image", + " Usage: "UTILITY_NAME " {-v} {-dump} {-h|-?} {-o OutFileName} InFileName", + " [-e|-b] [FileName(s)]", + " where:", + " -v - for verbose output", + " -dump - to dump the input file to a text file", + " -h -? - for this help information", + " -o OutFileName - to write output to OutFileName rather than InFileName"DEFAULT_OUTPUT_EXTENSION, + " InFileName - name of the input PE32 file", + "", + NULL + }; + for (Index = 0; Msg[Index] != NULL; Index++) { + fprintf (stdout, "%s\n", Msg[Index]); + } +} + +static +VOID +DumpImage ( + INT8 *FileName + ) +/*++ + +Routine Description: + + Dump a specified image information + +Arguments: + + FileName - File name pointer to the image to dump + +Returns: + + Nothing. + +--*/ +{ + FILE *InFptr; + EFI_TE_IMAGE_HEADER TEImageHeader; + INT8 *NamePtr; + + // + // Open the input file + // + InFptr = NULL; + + if ((InFptr = fopen (FileName, "rb")) == NULL) { + Error (NULL, 0, 0, FileName, "failed to open input file for reading"); + return ; + } + + if (fread (&TEImageHeader, sizeof (EFI_TE_IMAGE_HEADER), 1, InFptr) != 1) { + Error (NULL, 0, 0, FileName, "failed to read image header from input file"); + goto Finish; + } + + if (TEImageHeader.Signature != EFI_TE_IMAGE_HEADER_SIGNATURE) { + Error (NULL, 0, 0, FileName, "Image does not appear to be a TE image (bad signature)"); + goto Finish; + } + // + // Dump the header + // + fprintf (stdout, "Header (%d bytes):\n", sizeof (EFI_TE_IMAGE_HEADER)); + fprintf (stdout, " Signature: 0x%04X (TE)\n", (UINT32) TEImageHeader.Signature); + NamePtr = GetMachineTypeStr (TEImageHeader.Machine); + fprintf (stdout, " Machine: 0x%04X (%s)\n", (UINT32) TEImageHeader.Machine, NamePtr); + NamePtr = GetSubsystemTypeStr (TEImageHeader.Subsystem); + fprintf (stdout, " Subsystem: 0x%02X (%s)\n", (UINT32) TEImageHeader.Subsystem, NamePtr); + fprintf (stdout, " Number of sections 0x%02X\n", (UINT32) TEImageHeader.NumberOfSections); + fprintf (stdout, " Stripped size: 0x%04X\n", (UINT32) TEImageHeader.StrippedSize); + fprintf (stdout, " Entry point: 0x%08X\n", TEImageHeader.AddressOfEntryPoint); + fprintf (stdout, " Base of code: 0x%08X\n", TEImageHeader.BaseOfCode); + fprintf (stdout, " Data directories:\n"); + fprintf ( + stdout, + " %8X [%8X] RVA [size] of Base Relocation Directory\n", + TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress, + TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size + ); + fprintf ( + stdout, + " %8X [%8X] RVA [size] of Debug Directory\n", + TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress, + TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size + ); + +Finish: + if (InFptr != NULL) { + fclose (InFptr); + } +} + +static +INT8 * +GetMachineTypeStr ( + UINT16 MachineType + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + MachineType - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +{ + int Index; + + for (Index = 0; mMachineTypes[Index].Name != NULL; Index++) { + if (mMachineTypes[Index].Value == MachineType) { + return mMachineTypes[Index].Name; + } + } + + return "unknown"; +} + +static +INT8 * +GetSubsystemTypeStr ( + UINT16 SubsystemType + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + SubsystemType - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +{ + int Index; + + for (Index = 0; mSubsystemTypes[Index].Name != NULL; Index++) { + if (mSubsystemTypes[Index].Value == SubsystemType) { + return mSubsystemTypes[Index].Name; + } + } + + return "unknown"; +} diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/GenPage/Makefile b/EdkCompatibilityPkg/Sample/Tools/Source/GenTEImage/Makefile similarity index 61% rename from EdkCompatibilityPkg/Sample/Tools/Source/GenPage/Makefile rename to EdkCompatibilityPkg/Sample/Tools/Source/GenTEImage/Makefile index 8c4addb43d..3799877b92 100644 --- a/EdkCompatibilityPkg/Sample/Tools/Source/GenPage/Makefile +++ b/EdkCompatibilityPkg/Sample/Tools/Source/GenTEImage/Makefile @@ -1,6 +1,6 @@ #/*++ -# -# Copyright (c) 2006 - 2007, Intel Corporation +# +# Copyright (c) 2002 - 2007, Intel Corporation # All rights reserved. This program and the accompanying materials # are licensed and made available under the terms and conditions of the BSD License # which accompanies this distribution. The full text of the license may be found at @@ -9,15 +9,15 @@ # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. # -# Module Name: -# -# Makefile -# +# Module Name: +# +# makefile +# # Abstract: -# -# makefile for building the GenPage utility. -# -#--*/ +# +# makefile for building the GenTEImage utility. +# +#--*/ # # Make sure environmental variable EDK_SOURCE is set @@ -27,37 +27,19 @@ !ENDIF # -# Do this if you want to compile from this directory +# Define the toolchain which is used to set build options and toolchain paths # -!IFNDEF TOOLCHAIN TOOLCHAIN = TOOLCHAIN_MSVC -!ENDIF !INCLUDE $(BUILD_DIR)\PlatformTools.env -# -# Define some macros we use here. Should get rid of them someday and -# get rid of the extra level of indirection. -# -COMMON_SOURCE = $(EDK_TOOLS_COMMON) - -# -# Common information -# - -INC=$(INC) - # # Target specific information # -TARGET_NAME=GenPage -TARGET_SOURCE_DIR = $(EDK_TOOLS_SOURCE)\$(TARGET_NAME) - -TARGET_EXE = $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).exe - -TARGET_EXE_SOURCE = "$(TARGET_SOURCE_DIR)\GenPage.c" -TARGET_EXE_INCLUDE = "$(TARGET_SOURCE_DIR)\VirtualMemory.h" +TARGET_NAME = GenTEImage +TARGET_SRC_DIR = $(EDK_TOOLS_SOURCE)\$(TARGET_NAME) +TARGET_EXE = $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).exe # # Build targets @@ -65,15 +47,22 @@ TARGET_EXE_INCLUDE = "$(TARGET_SOURCE_DIR)\VirtualMemory.h" all: $(TARGET_EXE) +OBJECTS = $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj + +LIBS = $(EDK_TOOLS_OUTPUT)\Common.lib + +INC_DEPS = $(EDK_SOURCE)\Foundation\Efi\Include\EfiImage.h + # -# Build EXE +# Build the EXE by compiling the source files, then linking the resultant +# object files together. # -$(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj: $(TARGET_EXE_SOURCE) $(TARGET_EXE_INCLUDE) - $(CC) $(C_FLAGS) $(INC) $(TARGET_EXE_SOURCE) /Fo$(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj +$(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj : $(TARGET_SRC_DIR)\$(TARGET_NAME).c $(INC_DEPS) + $(CC) $(C_FLAGS) $(TARGET_SRC_DIR)\$(TARGET_NAME).c /Fo$@ # -# Add Binary Build description for this tool. +# Add Binary Build description for this tools. # !IF (("$(EFI_BINARY_TOOLS)" == "YES") && EXIST($(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe)) @@ -82,14 +71,15 @@ $(TARGET_EXE): $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe if exist $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb \ copy $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb /Y !ELSE -$(TARGET_EXE): $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj - $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) /out:$(TARGET_EXE) $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj +$(TARGET_EXE) : $(OBJECTS) $(LIBS) + $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(OBJECTS) +!IF ("$(EFI_BINARY_BUILD)" == "YES") if not exist $(EFI_PLATFORM_BIN)\Tools mkdir $(EFI_PLATFORM_BIN)\Tools if exist $(TARGET_EXE) copy $(TARGET_EXE) $(EFI_PLATFORM_BIN)\tools\$(TARGET_NAME).exe /Y if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb \ copy $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb /Y !ENDIF +!ENDIF clean: @if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL - diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/GuidChk/Makefile b/EdkCompatibilityPkg/Sample/Tools/Source/GuidChk/Makefile index 5aeddd8cad..6c029f0202 100644 --- a/EdkCompatibilityPkg/Sample/Tools/Source/GuidChk/Makefile +++ b/EdkCompatibilityPkg/Sample/Tools/Source/GuidChk/Makefile @@ -85,11 +85,13 @@ $(TARGET_EXE): $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe !ELSE $(TARGET_EXE) : $(OBJECTS) $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(OBJECTS) +!IF ("$(EFI_BINARY_BUILD)" == "YES") if not exist $(EFI_PLATFORM_BIN)\Tools mkdir $(EFI_PLATFORM_BIN)\Tools if exist $(TARGET_EXE) copy $(TARGET_EXE) $(EFI_PLATFORM_BIN)\tools\$(TARGET_NAME).exe /Y if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb \ copy $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb /Y !ENDIF +!ENDIF clean: @if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/MakeDeps/MakeDeps.c b/EdkCompatibilityPkg/Sample/Tools/Source/MakeDeps/MakeDeps.c index bf086e64a4..fb090bc930 100644 --- a/EdkCompatibilityPkg/Sample/Tools/Source/MakeDeps/MakeDeps.c +++ b/EdkCompatibilityPkg/Sample/Tools/Source/MakeDeps/MakeDeps.c @@ -1,6 +1,6 @@ /*++ -Copyright (c) 2004 - 2006, Intel Corporation +Copyright (c) 2004 - 2007, Intel Corporation All rights reserved. This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -101,6 +101,12 @@ typedef struct _SYMBOL { INT8 *Value; } SYMBOL; +typedef enum { + SearchCurrentDir, + SearchIncludePaths, + SearchAllPaths, +} FILE_SEARCH_TYPE; + // // Here's all our globals. We need a linked list of include paths, a linked // list of source files, a linked list of subdirectories (appended to each @@ -108,6 +114,7 @@ typedef struct _SYMBOL { // static struct { STRING_LIST *IncludePaths; // all include paths to search + STRING_LIST *ParentPaths; // all parent paths to search STRING_LIST *SourceFiles; // all source files to parse STRING_LIST *SubDirs; // appended to each include path when searching SYMBOL *SymbolTable; // for replacement strings @@ -120,25 +127,37 @@ static struct { BOOLEAN NoDupes; // to not list duplicate dependency files (for timing purposes) BOOLEAN UseSumDeps; // use summary dependency files if found BOOLEAN IsAsm; // The SourceFiles are assembler files + BOOLEAN IsCl; // The SourceFiles are the output of cl with /showIncludes INT8 TargetFileName[MAX_PATH]; // target object filename INT8 SumDepsPath[MAX_PATH]; // path to summary files + INT8 TmpFileName[MAX_PATH]; // temp file name for output file INT8 *OutFileName; // -o option } mGlobals; static STATUS ProcessFile ( + INT8 *TargetFileName, + INT8 *FileName, + UINT32 NestDepth, + STRING_LIST *ProcessedFiles, + FILE_SEARCH_TYPE FileSearchType + ); + +static +STATUS +ProcessClOutput ( INT8 *TargetFileName, INT8 *FileName, - UINT32 NestDepth, STRING_LIST *ProcessedFiles ); static FILE * FindFile ( - INT8 *FileName, - UINT32 FileNameLen + INT8 *FileName, + UINT32 FileNameLen, + FILE_SEARCH_TYPE FileSearchType ); static @@ -258,7 +277,12 @@ Returns: strcpy (TargetFileName, mGlobals.TargetFileName); } - Status = ProcessFile (TargetFileName, File->Str, START_NEST_DEPTH, &ProcessedFiles); + if (mGlobals.IsCl) { + Status = ProcessClOutput (TargetFileName, File->Str, &ProcessedFiles); + } else { + Status = ProcessFile (TargetFileName, File->Str, START_NEST_DEPTH, + &ProcessedFiles, SearchCurrentDir); + } if (Status != STATUS_SUCCESS) { goto Finish; } @@ -282,7 +306,7 @@ Finish: ProcessedFiles.Next = TempList; } // - // Close our output file + // Close our temp output file // if ((mGlobals.OutFptr != stdout) && (mGlobals.OutFptr != NULL)) { fclose (mGlobals.OutFptr); @@ -291,12 +315,22 @@ Finish: if (mGlobals.NeverFail) { return STATUS_SUCCESS; } - // - // If any errors, then delete our output so that it will get created - // again on a rebuild. - // - if ((GetUtilityStatus () == STATUS_ERROR) && (mGlobals.OutFileName != NULL)) { - remove (mGlobals.OutFileName); + + if (mGlobals.OutFileName != NULL) { + if (GetUtilityStatus () == STATUS_ERROR) { + // + // If any errors, then delete our temp output + // Also try to delete target file to improve the incremental build + // + remove (mGlobals.TmpFileName); + remove (TargetFileName); + } else { + // + // Otherwise, rename temp file to output file + // + remove (mGlobals.OutFileName); + rename (mGlobals.TmpFileName, mGlobals.OutFileName); + } } return GetUtilityStatus (); @@ -305,10 +339,11 @@ Finish: static STATUS ProcessFile ( - INT8 *TargetFileName, - INT8 *FileName, - UINT32 NestDepth, - STRING_LIST *ProcessedFiles + INT8 *TargetFileName, + INT8 *FileName, + UINT32 NestDepth, + STRING_LIST *ProcessedFiles, + FILE_SEARCH_TYPE FileSearchType ) /*++ @@ -322,6 +357,7 @@ Arguments: FileName - name of the file to process NestDepth - how deep we're nested in includes ProcessedFiles - list of processed files. + FileSearchType - search type for FileName Returns: @@ -342,6 +378,7 @@ Returns: UINT32 Index; UINT32 LineNum; STRING_LIST *ListPtr; + STRING_LIST ParentPath; Status = STATUS_SUCCESS; Fptr = NULL; @@ -380,37 +417,6 @@ Returns: return STATUS_SUCCESS; } } - // - // If we're not doing duplicates, and we've already seen this filename, - // then return - // - if (mGlobals.NoDupes) { - for (ListPtr = ProcessedFiles->Next; ListPtr != NULL; ListPtr = ListPtr->Next) { - if (_stricmp (FileName, ListPtr->Str) == 0) { - break; - } - } - // - // If we found a match, we're done. If we didn't, create a new element - // and add it to the list. - // - if (ListPtr != NULL) { - // - // Print a message if verbose mode - // - if (mGlobals.Verbose) { - DebugMsg (NULL, 0, 0, FileName, "duplicate include -- not processed again"); - } - - return STATUS_SUCCESS; - } - - ListPtr = malloc (sizeof (STRING_LIST)); - ListPtr->Str = malloc (strlen (FileName) + 1); - strcpy (ListPtr->Str, FileName); - ListPtr->Next = ProcessedFiles->Next; - ProcessedFiles->Next = ListPtr; - } // // Make sure we didn't exceed our maximum nesting depth @@ -424,14 +430,20 @@ Returns: // if we have to. // strcpy (FileNameCopy, FileName); - // - // Try to open the file locally - // - if ((Fptr = fopen (FileNameCopy, "r")) == NULL) { + + if (FileSearchType == SearchCurrentDir) { + // + // Try to open the source file locally + // + if ((Fptr = fopen (FileNameCopy, "r")) == NULL) { + Error (NULL, 0, 0, FileNameCopy, "could not open source file"); + return STATUS_ERROR; + } + } else { // // Try to find it among the paths. // - Fptr = FindFile (FileNameCopy, sizeof (FileNameCopy)); + Fptr = FindFile (FileNameCopy, sizeof (FileNameCopy), FileSearchType); if (Fptr == NULL) { // // If this is not the top-level file, and the command-line argument @@ -457,11 +469,58 @@ Returns: } } } + + // + // If we're not doing duplicates, and we've already seen this filename, + // then return + // + if (mGlobals.NoDupes) { + for (ListPtr = ProcessedFiles->Next; ListPtr != NULL; ListPtr = ListPtr->Next) { + if (_stricmp (FileNameCopy, ListPtr->Str) == 0) { + break; + } + } + // + // If we found a match, we're done. If we didn't, create a new element + // and add it to the list. + // + if (ListPtr != NULL) { + // + // Print a message if verbose mode + // + if (mGlobals.Verbose) { + DebugMsg (NULL, 0, 0, FileNameCopy, "duplicate include -- not processed again"); + } + fclose (Fptr); + return STATUS_SUCCESS; + } + + ListPtr = malloc (sizeof (STRING_LIST)); + ListPtr->Str = malloc (strlen (FileNameCopy) + 1); + strcpy (ListPtr->Str, FileNameCopy); + ListPtr->Next = ProcessedFiles->Next; + ProcessedFiles->Next = ListPtr; + } + // // Print the dependency, with string substitution // PrintDependency (TargetFileName, FileNameCopy); - + + // + // Get the file path and push to ParentPaths + // + Cptr = FileNameCopy + strlen (FileNameCopy) - 1; + for (; (Cptr > FileNameCopy) && (*Cptr != '\\') && (*Cptr != '/'); Cptr--); + if ((*Cptr == '\\') || (*Cptr == '/')) { + *(Cptr + 1) = 0; + } else { + strcpy (FileNameCopy, ".\\"); + } + ParentPath.Next = mGlobals.ParentPaths; + ParentPath.Str = FileNameCopy; + mGlobals.ParentPaths = &ParentPath; + // // Now read in lines and find all #include lines. Allow them to indent, and // to put spaces between the # and include. @@ -523,7 +582,8 @@ Returns: // Null terminate the filename and try to process it. // *EndPtr = 0; - Status = ProcessFile (TargetFileName, Cptr, NestDepth + 1, ProcessedFiles); + Status = ProcessFile (TargetFileName, Cptr, NestDepth + 1, + ProcessedFiles, SearchAllPaths); } else { // // Handle special #include MACRO_NAME(file) @@ -579,7 +639,8 @@ Returns: // // Process immediately, then break out of the outside FOR loop. // - Status = ProcessFile (TargetFileName, MacroIncludeFileName, NestDepth + 1, ProcessedFiles); + Status = ProcessFile (TargetFileName, MacroIncludeFileName, NestDepth + 1, + ProcessedFiles, SearchAllPaths); break; } } @@ -615,12 +676,20 @@ Returns: // // If we're processing it, do it // - if ((EndChar != '>') || (!mGlobals.NoSystem)) { + if (EndChar != '>') { // // Null terminate the filename and try to process it. // *EndPtr = 0; - Status = ProcessFile (TargetFileName, Cptr, NestDepth + 1, ProcessedFiles); + Status = ProcessFile (TargetFileName, Cptr, NestDepth + 1, + ProcessedFiles, SearchAllPaths); + } else if (!mGlobals.NoSystem) { + // + // Null terminate the filename and try to process it. + // + *EndPtr = 0; + Status = ProcessFile (TargetFileName, Cptr, NestDepth + 1, + ProcessedFiles, SearchIncludePaths); } } else { Warning (FileNameCopy, LineNum, 0, "malformed include", "missing closing %c", EndChar); @@ -631,6 +700,10 @@ Returns: } } } + // + // Pop the file path from ParentPaths + // + mGlobals.ParentPaths = ParentPath.Next; Finish: // @@ -643,6 +716,120 @@ Finish: return Status; } +static +STATUS +ProcessClOutput ( + INT8 *TargetFileName, + INT8 *FileName, + STRING_LIST *ProcessedFiles + ) +/*++ + +Routine Description: + + Given a source file name, open the file and parse all "Note: including file: xxx.h" lines. + +Arguments: + + TargetFileName - name of the usually .obj target + FileName - name of the file to process + ProcessedFiles - list of processed files. + +Returns: + + standard status. + +--*/ +{ + FILE *Fptr; + INT8 Line[MAX_LINE_LEN]; + INT8 IncludeFileName[MAX_LINE_LEN]; + STRING_LIST *ListPtr; + BOOLEAN ClError; + INT32 Ret; + INT8 Char; + + if ((Fptr = fopen (FileName, "r")) == NULL) { + Error (NULL, 0, 0, FileName, "could not open file for reading"); + return STATUS_ERROR; + } + if (fgets (Line, sizeof (Line), Fptr) != NULL) { + // + // First line is the source file name, print it + // + printf ("%s", Line); + } else { + // + // No output from cl + // + fclose (Fptr); + Error (NULL, 0, 0, NULL, "incorrect cl tool path may be used "); + return STATUS_ERROR; + } + + ClError = FALSE; + while (fgets (Line, sizeof (Line), Fptr) != NULL) { + Ret = sscanf (Line, "Note: including file: %s %c", IncludeFileName, &Char); + if (Ret == 2) { + // + // There is space in include file name. It's VS header file. Ignore it. + // + continue; + } else if ( Ret != 1) { + // + // Cl error info, print it + // the tool will return error code to stop the nmake + // + ClError = TRUE; + printf ("%s", Line); + continue; + } + + // + // If we're not doing duplicates, and we've already seen this filename, + // then continue + // + if (mGlobals.NoDupes) { + for (ListPtr = ProcessedFiles->Next; ListPtr != NULL; ListPtr = ListPtr->Next) { + if (_stricmp (IncludeFileName, ListPtr->Str) == 0) { + break; + } + } + // + // If we found a match, we're done. If we didn't, create a new element + // and add it to the list. + // + if (ListPtr != NULL) { + // + // Print a message if verbose mode + // + if (mGlobals.Verbose) { + DebugMsg (NULL, 0, 0, IncludeFileName, "duplicate include -- not processed again"); + } + + continue; + } + + ListPtr = malloc (sizeof (STRING_LIST)); + ListPtr->Str = malloc (strlen (IncludeFileName) + 1); + strcpy (ListPtr->Str, IncludeFileName); + ListPtr->Next = ProcessedFiles->Next; + ProcessedFiles->Next = ListPtr; + } + + PrintDependency (TargetFileName, IncludeFileName); + } + + fclose (Fptr); + + if (ClError) { + Error (NULL, 0, 0, NULL, "cl error"); + return STATUS_ERROR; + } else { + return STATUS_SUCCESS; + } +} + static void PrintDependency ( @@ -754,8 +941,9 @@ ReplaceSymbols ( static FILE * FindFile ( - INT8 *FileName, - UINT32 FileNameLen + INT8 *FileName, + UINT32 FileNameLen, + FILE_SEARCH_TYPE FileSearchType ) { FILE *Fptr; @@ -766,6 +954,49 @@ FindFile ( // // Traverse the list of paths and try to find the file // + if (FileSearchType == SearchAllPaths) { + List = mGlobals.ParentPaths; + while (List != NULL) { + // + // Put the path and filename together + // + if (strlen (List->Str) + strlen (FileName) + 1 > sizeof (FullFileName)) { + Error ( + __FILE__, + __LINE__, + 0, + "application error", + "cannot concatenate '%s' + '%s'", + List->Str, + FileName + ); + return NULL; + } + // + // Append the filename to this include path and try to open the file. + // + strcpy (FullFileName, List->Str); + strcat (FullFileName, FileName); + if ((Fptr = fopen (FullFileName, "r")) != NULL) { + // + // Return the file name + // + if (FileNameLen <= strlen (FullFileName)) { + Error (__FILE__, __LINE__, 0, "application error", "internal path name of insufficient length"); + // + // fprintf (stdout, "File length > %d: %s\n", FileNameLen, FullFileName); + // + return NULL; + } + + strcpy (FileName, FullFileName); + return Fptr; + } + + List = List->Next; + } + } + List = mGlobals.IncludePaths; while (List != NULL) { // @@ -846,7 +1077,7 @@ ProcessArgs ( STRING_LIST *LastIncludePath; STRING_LIST *LastSourceFile; SYMBOL *Symbol; - int Index; + // // Clear our globals // @@ -957,50 +1188,7 @@ ProcessArgs ( Usage (); return STATUS_ERROR; } - // - // The C compiler first looks for #include files in the directory where - // the source file came from. Add the file's source directory to the - // list of include paths. - // - NewList = malloc (sizeof (STRING_LIST)); - if (NewList == NULL) { - Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); - return STATUS_ERROR; - } - - NewList->Next = NULL; - NewList->Str = malloc (strlen (Argv[1]) + 3); - if (NewList->Str == NULL) { - free (NewList); - Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); - return STATUS_ERROR; - } - - strcpy (NewList->Str, Argv[1]); - // - // Back up in the source file name to the last backslash and terminate after it. - // - for (Index = strlen (NewList->Str) - 1; (Index > 0) && (NewList->Str[Index] != '\\'); Index--) - ; - if (Index < 0) { - strcpy (NewList->Str, ".\\"); - } else { - NewList->Str[Index + 1] = 0; - } - // - // Add it to the end of the our list of include paths - // - if (mGlobals.IncludePaths == NULL) { - mGlobals.IncludePaths = NewList; - } else { - LastIncludePath->Next = NewList; - } - if (mGlobals.Verbose) { - fprintf (stdout, "Adding include path: %s\n", NewList->Str); - } - - LastIncludePath = NewList; Argc--; Argv++; } else if (_stricmp (Argv[0], "-s") == 0) { @@ -1145,15 +1333,20 @@ ProcessArgs ( // check for one more arg // if (Argc > 1) { + mGlobals.OutFileName = Argv[1]; + // + // Use temp file for output + // This can avoid overwriting previous existed dep file when error + // ocurred in this tool // - // Try to open the file + sprintf (mGlobals.TmpFileName, "%s2", mGlobals.OutFileName); // - if ((mGlobals.OutFptr = fopen (Argv[1], "w")) == NULL) { - Error (NULL, 0, 0, Argv[1], "could not open file for writing"); + // Try to open the temp file + // + if ((mGlobals.OutFptr = fopen (mGlobals.TmpFileName, "w")) == NULL) { + Error (NULL, 0, 0, mGlobals.TmpFileName, "could not open file for writing"); return STATUS_ERROR; } - - mGlobals.OutFileName = Argv[1]; } else { Error (NULL, 0, 0, Argv[0], "option requires output file name"); Usage (); @@ -1171,7 +1364,17 @@ ProcessArgs ( } else if (_stricmp (Argv[0], "-ignorenotfound") == 0) { mGlobals.IgnoreNotFound = TRUE; } else if (_stricmp (Argv[0], "-asm") == 0) { + if (mGlobals.IsCl) { + Error (NULL, 0, 0, Argv[0], "option conflict with -cl"); + return STATUS_ERROR; + } mGlobals.IsAsm = TRUE; + } else if (_stricmp (Argv[0], "-cl") == 0) { + if (mGlobals.IsAsm) { + Error (NULL, 0, 0, Argv[0], "option conflict with -asm"); + return STATUS_ERROR; + } + mGlobals.IsCl = TRUE; } else if ((_stricmp (Argv[0], "-h") == 0) || (strcmp (Argv[0], "-?") == 0)) { Usage (); return STATUS_ERROR; @@ -1306,7 +1509,8 @@ Returns: // " -nodupes keep track of include files, don't rescan duplicates", // " -usesumdeps path use summary dependency files in 'path' directory.", - " -asm The SourceFile is assembler file", + " -asm The SourceFiles are assembler files", + " -cl The SourceFiles are the output of cl with /showIncludes", "", NULL }; diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/MakeDeps/Makefile b/EdkCompatibilityPkg/Sample/Tools/Source/MakeDeps/Makefile index 4cd9084f8e..f24b9ffe71 100644 --- a/EdkCompatibilityPkg/Sample/Tools/Source/MakeDeps/Makefile +++ b/EdkCompatibilityPkg/Sample/Tools/Source/MakeDeps/Makefile @@ -62,8 +62,10 @@ $(TARGET_EXE): $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe !ELSE $(TARGET_EXE) : $(OBJECTS) $(LIBS) $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(OBJECTS) +!IF ("$(EFI_BINARY_BUILD)" == "YES") if not exist $(EFI_PLATFORM_BIN)\Tools mkdir $(EFI_PLATFORM_BIN)\Tools if exist $(TARGET_EXE) copy $(TARGET_EXE) $(EFI_PLATFORM_BIN)\tools\$(TARGET_NAME).exe /Y if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb \ copy $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb /Y !ENDIF +!ENDIF diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/Makefile b/EdkCompatibilityPkg/Sample/Tools/Source/Makefile index 974c9b4aa9..57ec6a190b 100644 --- a/EdkCompatibilityPkg/Sample/Tools/Source/Makefile +++ b/EdkCompatibilityPkg/Sample/Tools/Source/Makefile @@ -17,13 +17,6 @@ # #--*/ -# -# Everything depends on EDK_SOURCE. Make sure it's defined -# -!IFNDEF EDK_SOURCE -!ERROR EDK_SOURCE environmental variable not set -!ENDIF - # # Define our toolchain before we include the master settings file # @@ -42,25 +35,26 @@ MAKEFILES = $(EDK_TOOLS_SOURCE)\Common\Makefile \ $(EDK_TOOLS_SOURCE)\GenDepex\Makefile \ $(EDK_TOOLS_SOURCE)\GenFfsFile\Makefile \ $(EDK_TOOLS_SOURCE)\GenFvImage\Makefile \ + $(EDK_TOOLS_SOURCE)\GenTEImage\makefile \ $(EDK_TOOLS_SOURCE)\FwImage\Makefile \ $(EDK_TOOLS_SOURCE)\ProcessDsc\makefile \ $(EDK_TOOLS_SOURCE)\GuidChk\makefile \ $(EDK_TOOLS_SOURCE)\MakeDeps\makefile \ $(EDK_TOOLS_SOURCE)\SetStamp\makefile \ +!IF "$(EFI_SPECIFICATION_VERSION)" >= "0x0002000A" + $(EDK_TOOLS_SOURCE)\UefiVfrCompile\makefile \ + $(EDK_TOOLS_SOURCE)\UefiStrGather\makefile \ +!ELSE $(EDK_TOOLS_SOURCE)\VfrCompile\makefile \ $(EDK_TOOLS_SOURCE)\StrGather\makefile \ - $(EDK_TOOLS_SOURCE)\BootsectImage\Makefile \ - $(EDK_TOOLS_SOURCE)\GenBootsector\Makefile \ - $(EDK_TOOLS_SOURCE)\GenPage\Makefile \ +!ENDIF $(EDK_TOOLS_SOURCE)\SplitFile\Makefile \ + $(EDK_TOOLS_SOURCE)\Strip\Makefile \ $(EDK_TOOLS_SOURCE)\EfiCompress\Makefile \ - $(EDK_TOOLS_SOURCE)\EfildrImage\Makefile \ $(EDK_TOOLS_SOURCE)\EfiRom\Makefile \ $(EDK_TOOLS_SOURCE)\GenAprioriFile\Makefile \ $(EDK_TOOLS_SOURCE)\ModifyInf\Makefile - - # # Define default all target which calls all our makefiles. The special # bang (!) tells nmake to do the command for each out-of-date dependent. diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/ModifyInf/Makefile b/EdkCompatibilityPkg/Sample/Tools/Source/ModifyInf/Makefile index f303a54d10..523af4d931 100644 --- a/EdkCompatibilityPkg/Sample/Tools/Source/ModifyInf/Makefile +++ b/EdkCompatibilityPkg/Sample/Tools/Source/ModifyInf/Makefile @@ -72,11 +72,13 @@ $(TARGET_EXE): $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe !ELSE $(TARGET_EXE) : $(OBJECTS) $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(OBJECTS) +!IF ("$(EFI_BINARY_BUILD)" == "YES") if not exist $(EFI_PLATFORM_BIN)\Tools mkdir $(EFI_PLATFORM_BIN)\Tools if exist $(TARGET_EXE) copy $(TARGET_EXE) $(EFI_PLATFORM_BIN)\tools\$(TARGET_NAME).exe /Y if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb \ copy $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb /Y !ENDIF +!ENDIF clean: @if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/ProcessDsc/Makefile b/EdkCompatibilityPkg/Sample/Tools/Source/ProcessDsc/Makefile index c835a80025..b11d3c44ad 100644 --- a/EdkCompatibilityPkg/Sample/Tools/Source/ProcessDsc/Makefile +++ b/EdkCompatibilityPkg/Sample/Tools/Source/ProcessDsc/Makefile @@ -89,11 +89,13 @@ $(TARGET_EXE): $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe !ELSE $(TARGET_EXE) : $(OBJECTS) $(LIBS) $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(OBJECTS) +!IF ("$(EFI_BINARY_BUILD)" == "YES") if not exist $(EFI_PLATFORM_BIN)\Tools mkdir $(EFI_PLATFORM_BIN)\Tools if exist $(TARGET_EXE) copy $(TARGET_EXE) $(EFI_PLATFORM_BIN)\tools\$(TARGET_NAME).exe /Y if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb \ copy $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb /Y !ENDIF +!ENDIF clean: @if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/ProcessDsc/ProcessDsc.c b/EdkCompatibilityPkg/Sample/Tools/Source/ProcessDsc/ProcessDsc.c index 4833b78e0d..5b67632721 100644 --- a/EdkCompatibilityPkg/Sample/Tools/Source/ProcessDsc/ProcessDsc.c +++ b/EdkCompatibilityPkg/Sample/Tools/Source/ProcessDsc/ProcessDsc.c @@ -554,6 +554,12 @@ AddModuleName ( INT8 *InfName ); +static +void +ReplaceSlash ( + INT8 *Path + ); + /*****************************************************************************/ int main ( @@ -1032,10 +1038,11 @@ Returns: // added local symbols // ExpandSymbols (ArgLine, Line, sizeof (Line), EXPANDMODE_NO_UNDEFS); - + // // If we have "c:\path\filename" // + ReplaceSlash (Line); if (IsAbsolutePath (Line)) { ComponentFilePathAbsolute = 1; } else if (Line[0] == '.') { @@ -1054,7 +1061,7 @@ Returns: // strcpy (ComponentFilePath, Line); Cptr = ComponentFilePath + strlen (ComponentFilePath) - 1; - while ((*Cptr != '\\') && (*Cptr != '/') && (Cptr != ComponentFilePath)) { + while ((*Cptr != '\\') && (Cptr != ComponentFilePath)) { Cptr--; } // @@ -1239,7 +1246,8 @@ Returns: // They may have defined DEST_DIR on the component INF line, so it's already // been defined, If that's the case, then don't set it to the path of this file. // - if (GetSymbolValue (DEST_DIR) == NULL) { + TempCptr = GetSymbolValue (DEST_DIR); + if (TempCptr == NULL) { if (ComponentFilePathAbsolute == 0) { // // The destination path is $(BUILD_DIR)\$(PROCESSOR)\component_path @@ -1264,6 +1272,8 @@ Returns: ); } AddSymbol (DEST_DIR, FileName, SYM_OVERWRITE | SYM_LOCAL | SYM_FILEPATH); + } else { + ReplaceSlash (TempCptr); } // @@ -1818,6 +1828,7 @@ Returns: // OverridePath = GetSymbolValue (SOURCE_OVERRIDE_PATH); if (OverridePath != NULL) { + ReplaceSlash (OverridePath); fprintf (MakeFptr, "INC = $(INC) -I %s\n", OverridePath); fprintf (MakeFptr, "INC = $(INC) -I %s\\%s \n", OverridePath, Processor); } @@ -1881,6 +1892,7 @@ ProcessIncludesSectionSingle ( // Don't process blank lines // if (*Cptr) { + ReplaceSlash (Cptr); // // Strip off trailing slash // @@ -2150,6 +2162,7 @@ ProcessSourceFilesSection ( // ExpandSymbols (Cptr, FileName, sizeof (FileName), 0); AddFileSymbols (FileName); + ReplaceSlash (FileName); // // Set the SOURCE_FILE_NAME symbol. What we have now is the name of // the file, relative to the location of the INF file. So prepend @@ -2197,6 +2210,7 @@ ProcessSourceFilesSection ( OverridePath = GetSymbolValue (SOURCE_OVERRIDE_PATH); } if (OverridePath != NULL) { + ReplaceSlash (OverridePath); // // See if the file exists. If it does, reset the SOURCE_FILE_NAME symbol. // @@ -2490,6 +2504,7 @@ ProcessObjectsSingle ( // if (!IsIncludeFile (Cptr)) { ExpandSymbols (Cptr, FileName, sizeof (FileName), 0); + ReplaceSlash (FileName); Cptr2 = BuiltFileExtension (FileName); if (Cptr2 != NULL) { SetFileExtension (FileName, Cptr2); @@ -2731,8 +2746,10 @@ ProcessIncludeFilesSingle ( // ExpandSymbols (Cptr, FileName, sizeof (FileName), 0); AddFileSymbols (FileName); + ReplaceSlash (FileName); if (IsIncludeFile (FileName)) { if ((OverridePath != NULL) && (!IsAbsolutePath (FileName))) { + ReplaceSlash (OverridePath); strcpy (TempFileName, OverridePath); strcat (TempFileName, "\\"); strcat (TempFileName, FileName); @@ -2743,7 +2760,7 @@ ProcessIncludeFilesSingle ( // to the beginning of the list of include paths. // for (Cptr = TempFileName + strlen (TempFileName) - 1; - (Cptr >= TempFileName) && (*Cptr != '\\') && (*Cptr != '/'); + (Cptr >= TempFileName) && (*Cptr != '\\'); Cptr-- ) ; @@ -2848,9 +2865,9 @@ GetFileParts ( FP->Extension[0] = 0; } // - // Now back up and get the base name (include the preceding '\' or '/') + // Now back up and get the base name (include the preceding '\') // - for (; (Cptr > FileNamePtr) && (*Cptr != '\\') && (*Cptr != '/'); Cptr--) + for (; (Cptr > FileNamePtr) && (*Cptr != '\\'); Cptr--) ; FP->BaseName = (char *) malloc (strlen (Cptr) + 1); strcpy (FP->BaseName, Cptr); @@ -3329,7 +3346,7 @@ MakeFilePath ( } for (;;) { - for (; *Cptr && (*Cptr != '/') && (*Cptr != '\\'); Cptr++) + for (; *Cptr && (*Cptr != '\\'); Cptr++) ; if (*Cptr) { SavedChar = *Cptr; @@ -4204,6 +4221,7 @@ Returns: FreeCwd = 1; AddSymbol (BUILD_DIR, Cptr, SYM_OVERWRITE | SYM_GLOBAL | SYM_FILEPATH); } else { + ReplaceSlash (Cptr); FreeCwd = 0; } @@ -4359,6 +4377,7 @@ GetEfiSource ( // EfiSource = GetSymbolValue (EFI_SOURCE); if ( EfiSource != NULL) { + ReplaceSlash (EfiSource); if (EfiSource[strlen (EfiSource) - 1] == '\\') { EfiSource[strlen (EfiSource) - 1] = 0; } @@ -4370,6 +4389,7 @@ GetEfiSource ( // EfiSource = getenv (EFI_SOURCE); if (EfiSource != NULL) { + ReplaceSlash (EfiSource); if (EfiSource[strlen (EfiSource) - 1] == '\\') { EfiSource[strlen (EfiSource) - 1] = 0; } @@ -4724,3 +4744,26 @@ Returns: return 0; } + +static +void +ReplaceSlash ( + INT8 *Path + ) +/*++ + +Routine Description: + + Replace '/' with '\\' + +Returns: + +--*/ +{ + while (*Path) { + if (*Path == '/') { + *Path = '\\'; + } + Path++; + } +} \ No newline at end of file diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/SetStamp/Makefile b/EdkCompatibilityPkg/Sample/Tools/Source/SetStamp/Makefile index 39750fb441..13fe39efad 100644 --- a/EdkCompatibilityPkg/Sample/Tools/Source/SetStamp/Makefile +++ b/EdkCompatibilityPkg/Sample/Tools/Source/SetStamp/Makefile @@ -78,11 +78,13 @@ $(TARGET_EXE): $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe !ELSE $(TARGET_EXE) : $(OBJECTS) $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(OBJECTS) +!IF ("$(EFI_BINARY_BUILD)" == "YES") if not exist $(EFI_PLATFORM_BIN)\Tools mkdir $(EFI_PLATFORM_BIN)\Tools if exist $(TARGET_EXE) copy $(TARGET_EXE) $(EFI_PLATFORM_BIN)\tools\$(TARGET_NAME).exe /Y if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb \ copy $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb /Y !ENDIF +!ENDIF clean: @if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/SplitFile/Makefile b/EdkCompatibilityPkg/Sample/Tools/Source/SplitFile/Makefile index a90e133cec..d67d9b2bbe 100644 --- a/EdkCompatibilityPkg/Sample/Tools/Source/SplitFile/Makefile +++ b/EdkCompatibilityPkg/Sample/Tools/Source/SplitFile/Makefile @@ -84,11 +84,13 @@ $(TARGET_EXE): $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe !ELSE $(TARGET_EXE): $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) /out:$(TARGET_EXE) $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj +!IF ("$(EFI_BINARY_BUILD)" == "YES") if not exist $(EFI_PLATFORM_BIN)\Tools mkdir $(EFI_PLATFORM_BIN)\Tools if exist $(TARGET_EXE) copy $(TARGET_EXE) $(EFI_PLATFORM_BIN)\tools\$(TARGET_NAME).exe /Y if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb \ copy $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb /Y !ENDIF +!ENDIF clean: @if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/StrGather/Makefile b/EdkCompatibilityPkg/Sample/Tools/Source/StrGather/Makefile index dce81b0e04..993063d4ce 100644 --- a/EdkCompatibilityPkg/Sample/Tools/Source/StrGather/Makefile +++ b/EdkCompatibilityPkg/Sample/Tools/Source/StrGather/Makefile @@ -79,11 +79,13 @@ $(TARGET_EXE): $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe !ELSE $(TARGET_EXE) : $(OBJECTS) $(LIBS) $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(OBJECTS) +!IF ("$(EFI_BINARY_BUILD)" == "YES") if not exist $(EFI_PLATFORM_BIN)\Tools mkdir $(EFI_PLATFORM_BIN)\Tools if exist $(TARGET_EXE) copy $(TARGET_EXE) $(EFI_PLATFORM_BIN)\tools\$(TARGET_NAME).exe /Y if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb \ copy $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb /Y !ENDIF +!ENDIF clean: diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/EfildrImage/Makefile b/EdkCompatibilityPkg/Sample/Tools/Source/Strip/Makefile similarity index 80% rename from EdkCompatibilityPkg/Sample/Tools/Source/EfildrImage/Makefile rename to EdkCompatibilityPkg/Sample/Tools/Source/Strip/Makefile index 155680107d..99d1b2a0ee 100644 --- a/EdkCompatibilityPkg/Sample/Tools/Source/EfildrImage/Makefile +++ b/EdkCompatibilityPkg/Sample/Tools/Source/Strip/Makefile @@ -1,5 +1,5 @@ #/*++ -# +# # Copyright (c) 2006 - 2007, Intel Corporation # All rights reserved. This program and the accompanying materials # are licensed and made available under the terms and conditions of the BSD License @@ -8,16 +8,14 @@ # # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -# Module Name: -# -# Makefile -# +# +# Module Name: makefile +# # Abstract: -# -# makefile for building the EfildrImage utility. -# -#--*/ +# +# This file is used to build the Strip utility. +# +#--*/ # # Make sure environmental variable EDK_SOURCE is set @@ -51,15 +49,14 @@ INC=$(INC) # Target specific information # -TARGET_NAME=EfildrImage +TARGET_NAME=Strip TARGET_SOURCE_DIR = $(EDK_TOOLS_SOURCE)\$(TARGET_NAME) TARGET_EXE = $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).exe -TARGET_EXE_SOURCE = "$(TARGET_SOURCE_DIR)\EfildrImage.c" +TARGET_EXE_SOURCE = "$(TARGET_SOURCE_DIR)\Strip.c" TARGET_EXE_INCLUDE = - # # Build targets # @@ -74,7 +71,7 @@ $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj: $(TARGET_EXE_SOURCE) $(TARGET_EXE_INCLUD $(CC) $(C_FLAGS) $(INC) $(TARGET_EXE_SOURCE) /Fo$(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj # -# Add Binary Build description for this tool. +# Add Binary Build description for this tools. # !IF (("$(EFI_BINARY_TOOLS)" == "YES") && EXIST($(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe)) @@ -83,14 +80,15 @@ $(TARGET_EXE): $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe if exist $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb \ copy $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb /Y !ELSE -$(TARGET_EXE): $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj - $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) /out:$(TARGET_EXE) $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj +$(TARGET_EXE): $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj $(TARGET_EXE_LIBS) $(TARGET_DLL) + $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj $(TARGET_LIB) $(TARGET_EXE_LIBS) +!IF ("$(EFI_BINARY_BUILD)" == "YES") if not exist $(EFI_PLATFORM_BIN)\Tools mkdir $(EFI_PLATFORM_BIN)\Tools if exist $(TARGET_EXE) copy $(TARGET_EXE) $(EFI_PLATFORM_BIN)\tools\$(TARGET_NAME).exe /Y if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb \ copy $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb /Y !ENDIF +!ENDIF clean: @if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL - diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/Strip/strip.c b/EdkCompatibilityPkg/Sample/Tools/Source/Strip/strip.c new file mode 100644 index 0000000000..72d76939c6 --- /dev/null +++ b/EdkCompatibilityPkg/Sample/Tools/Source/Strip/strip.c @@ -0,0 +1,104 @@ +/*++ + +Copyright 2006, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + Strip.c + +Abstract: + + Quick Exe2Bin equivalent. + +--*/ + +#include +#include +#include +#include + +int +main ( + int argc, + char *argv[] + ) +/*++ + +Routine Description: + + Converts executable files to binary files. + +Arguments: + + argc - Number of command line arguments + argv[] - Array of pointers to the command line arguments + +Returns: + + Zero - Function completed successfully. + Non-zero - Function exited with errors. + +--*/ +{ + FILE *InFile; + FILE *OutFile; + int Index; + int FileSize; + char *Buffer; + char *Ptrx; + + if (argc < 3) { + printf ("Need more args, such as file name to convert and output name\n"); + return -1; + } + + InFile = fopen (argv[1], "rb"); + OutFile = fopen (argv[2], "wb"); + + if (!InFile) { + printf ("no file, exit\n"); + return -1; + } + + if (OutFile == NULL) { + printf ("Unable to open output file.\n"); + return -1; + } + + fseek (InFile, 0, SEEK_END); + FileSize = ftell (InFile); + + if (FileSize < 0x200) { + printf ("%d is not a legal size, exit\n", FileSize); + return -1; + } + + fseek (InFile, 0, SEEK_SET); + + Buffer = malloc (FileSize); + if (Buffer == NULL) { + printf ("Error: Out of resources.\n"); + return -1; + } + + fread (Buffer, 1, FileSize, InFile); + + Ptrx = Buffer + 0x200; + + Index = FileSize - 0x200; + + fwrite (Ptrx, Index, 1, OutFile); + + fclose (InFile); + fclose (OutFile); + free (Buffer); + + return 0; +} diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/BootsectImage/Makefile b/EdkCompatibilityPkg/Sample/Tools/Source/UefiStrGather/Makefile similarity index 53% rename from EdkCompatibilityPkg/Sample/Tools/Source/BootsectImage/Makefile rename to EdkCompatibilityPkg/Sample/Tools/Source/UefiStrGather/Makefile index b067e85619..cb8bac26d3 100644 --- a/EdkCompatibilityPkg/Sample/Tools/Source/BootsectImage/Makefile +++ b/EdkCompatibilityPkg/Sample/Tools/Source/UefiStrGather/Makefile @@ -1,6 +1,6 @@ #/*++ # -# Copyright (c) 2006 - 2007, Intel Corporation +# Copyright (c) 2004 - 2007, Intel Corporation # All rights reserved. This program and the accompanying materials # are licensed and made available under the terms and conditions of the BSD License # which accompanies this distribution. The full text of the license may be found at @@ -15,7 +15,7 @@ # # Abstract: # -# makefile for building the BootsectImage utility. +# makefile for building the StrGather utility. # #--*/ @@ -36,46 +36,51 @@ TOOLCHAIN = TOOLCHAIN_MSVC !INCLUDE $(BUILD_DIR)\PlatformTools.env # -# Define some macros we use here. Should get rid of them someday and -# get rid of the extra level of indirection. +# Target specific information # -COMMON_SOURCE = $(EDK_TOOLS_COMMON) +TARGET_NAME = StrGather +TARGET_SRC_DIR = $(EDK_TOOLS_SOURCE)\Uefi$(TARGET_NAME) +TARGET_EXE = $(EDK_TOOLS_OUTPUT)\StrGather.exe # -# Common information +# Build targets # -INC=$(INC) +all: $(TARGET_EXE) -# -# Target specific information -# -TARGET_NAME=BootsectImage -TARGET_SOURCE_DIR = $(EDK_TOOLS_SOURCE)\$(TARGET_NAME) +LIBS = "$(EDK_TOOLS_OUTPUT)\Common.lib" -TARGET_EXE = $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).exe +OBJECTS = $(EDK_TOOLS_OUTPUT)\StrGather.obj \ + $(EDK_TOOLS_OUTPUT)\StringDB.obj -TARGET_EXE_SOURCE = "$(TARGET_SOURCE_DIR)\BootsectImage.c" -TARGET_EXE_INCLUDE = "$(TARGET_SOURCE_DIR)\fat.h" \ - "$(TARGET_SOURCE_DIR)\mbr.h" \ +INC_PATHS = -I $(TARGET_SRC_DIR) \ + -I $(EDK_SOURCE)\Foundation\Include\Ia32 \ + -I $(EDK_SOURCE)\Foundation\Efi\Include \ + -I $(EDK_SOURCE)\Foundation\Framework\Include \ + -I $(EDK_SOURCE)\Foundation\Include\IndustryStandard \ + -I $(EDK_SOURCE)\Foundation\ \ + -I $(EDK_SOURCE)\Foundation\Core\Dxe \ + -I $(EDK_SOURCE)\Foundation\Efi \ + -I $(EDK_SOURCE)\Foundation\Framework \ + -I $(EDK_TOOLS_SOURCE)\Common \ + -I $(EDK_SOURCE)\Foundation\Include +INC_DEPS = $(TARGET_SRC_DIR)\StrGather.h $(TARGET_SRC_DIR)\StringDB.h -# -# Build targets -# - -all: $(TARGET_EXE) +C_FLAGS = $(C_FLAGS) /W4 # -# Build EXE +# Compile each source file # +$(EDK_TOOLS_OUTPUT)\StrGather.obj : $(TARGET_SRC_DIR)\StrGather.c $(INC_DEPS) + $(CC) $(C_FLAGS) $(INC_PATHS) $(TARGET_SRC_DIR)\StrGather.c /Fo$@ -$(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj: $(TARGET_EXE_SOURCE) $(TARGET_EXE_INCLUDE) - $(CC) $(C_FLAGS) $(INC) $(TARGET_EXE_SOURCE) /Fo$(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj +$(EDK_TOOLS_OUTPUT)\StringDB.obj : $(TARGET_SRC_DIR)\StringDB.c $(INC_DEPS) + $(CC) $(C_FLAGS) $(INC_PATHS) $(TARGET_SRC_DIR)\StringDB.c /Fo$@ # -# Add Binary Build description for this tool. +# Add Binary Build description for this tools. # !IF (("$(EFI_BINARY_TOOLS)" == "YES") && EXIST($(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe)) @@ -84,14 +89,15 @@ $(TARGET_EXE): $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe if exist $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb \ copy $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb /Y !ELSE -$(TARGET_EXE): $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj $(EDK_TOOLS_OUTPUT)\Common.lib - $(LINK) $(MSVS_LINK_LIBPATHS) $(EDK_TOOLS_OUTPUT)\Common.lib $(L_FLAGS) /out:$(TARGET_EXE) $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).obj +$(TARGET_EXE) : $(OBJECTS) $(LIBS) + $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(OBJECTS) +!IF ("$(EFI_BINARY_BUILD)" == "YES") if not exist $(EFI_PLATFORM_BIN)\Tools mkdir $(EFI_PLATFORM_BIN)\Tools if exist $(TARGET_EXE) copy $(TARGET_EXE) $(EFI_PLATFORM_BIN)\tools\$(TARGET_NAME).exe /Y if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb \ copy $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb /Y !ENDIF +!ENDIF clean: - @if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL - + diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/UefiStrGather/StrGather.c b/EdkCompatibilityPkg/Sample/Tools/Source/UefiStrGather/StrGather.c new file mode 100644 index 0000000000..03b3cc6f41 --- /dev/null +++ b/EdkCompatibilityPkg/Sample/Tools/Source/UefiStrGather/StrGather.c @@ -0,0 +1,2829 @@ +/*++ + +Copyright (c) 2004 - 2007, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + StrGather.c + +Abstract: + + Parse a strings file and create or add to a string database file. + +--*/ + +#include +#include +#include +#include +#include +#include +#include +#include "StrGather.h" +#include "StringDB.h" + +#define TOOL_VERSION "0.31" + +typedef UINT16 WCHAR; + +#define MAX_PATH 1024 +#define MAX_NEST_DEPTH 20 // just in case we get in an endless loop. +#define MAX_STRING_IDENTIFIER_NAME 128 // number of wchars +#define MAX_LINE_LEN 400 +#define STRING_TOKEN "STRING_TOKEN" +#define DEFAULT_BASE_NAME "BaseName" +// +// Operational modes for this utility +// +#define MODE_UNKNOWN 0 +#define MODE_PARSE 1 +#define MODE_SCAN 2 +#define MODE_DUMP 3 + +// +// We keep a linked list of these for the source files we process +// +typedef struct _SOURCE_FILE { + FILE *Fptr; + WCHAR *FileBuffer; + WCHAR *FileBufferPtr; + UINT32 FileSize; + INT8 FileName[MAX_PATH]; + UINT32 LineNum; + BOOLEAN EndOfFile; + BOOLEAN SkipToHash; + struct _SOURCE_FILE *Previous; + struct _SOURCE_FILE *Next; + WCHAR ControlCharacter; +} SOURCE_FILE; + +#define DEFAULT_CONTROL_CHARACTER UNICODE_SLASH + +// +// Here's all our globals. We need a linked list of include paths, a linked +// list of source files, a linked list of subdirectories (appended to each +// include path when searching), and a couple other fields. +// +static struct { + SOURCE_FILE SourceFiles; + TEXT_STRING_LIST *IncludePaths; // all include paths to search + TEXT_STRING_LIST *LastIncludePath; + TEXT_STRING_LIST *ScanFileName; + TEXT_STRING_LIST *LastScanFileName; + TEXT_STRING_LIST *SkipExt; // if -skipext .uni + TEXT_STRING_LIST *LastSkipExt; + TEXT_STRING_LIST *IndirectionFileName; + TEXT_STRING_LIST *LastIndirectionFileName; + TEXT_STRING_LIST *DatabaseFileName; + TEXT_STRING_LIST *LastDatabaseFileName; + WCHAR_STRING_LIST *Language; + WCHAR_STRING_LIST *LastLanguage; + WCHAR_MATCHING_STRING_LIST *IndirectionList; // from indirection file(s) + WCHAR_MATCHING_STRING_LIST *LastIndirectionList; + BOOLEAN Verbose; // for more detailed output + BOOLEAN VerboseDatabaseWrite; // for more detailed output when writing database + BOOLEAN VerboseDatabaseRead; // for more detailed output when reading database + BOOLEAN NewDatabase; // to start from scratch + BOOLEAN IgnoreNotFound; // when scanning + BOOLEAN VerboseScan; + BOOLEAN UnquotedStrings; // -uqs option + INT8 OutputDatabaseFileName[MAX_PATH]; + INT8 StringHFileName[MAX_PATH]; + INT8 StringCFileName[MAX_PATH]; // output .C filename + INT8 DumpUFileName[MAX_PATH]; // output unicode dump file name + INT8 HiiExportPackFileName[MAX_PATH]; // HII export pack file name + INT8 BaseName[MAX_PATH]; // base filename of the strings file + INT8 OutputDependencyFileName[MAX_PATH]; + FILE *OutputDependencyFptr; + UINT32 Mode; +} mGlobals; + +static +BOOLEAN +IsValidIdentifierChar ( + INT8 Char, + BOOLEAN FirstChar + ); + +static +void +RewindFile ( + SOURCE_FILE *SourceFile + ); + +static +BOOLEAN +SkipTo ( + SOURCE_FILE *SourceFile, + WCHAR WChar, + BOOLEAN StopAfterNewline + ); + +static +UINT32 +SkipWhiteSpace ( + SOURCE_FILE *SourceFile + ); + +static +BOOLEAN +IsWhiteSpace ( + SOURCE_FILE *SourceFile + ); + +static +BOOLEAN +EndOfFile ( + SOURCE_FILE *SourceFile + ); + +static +void +PreprocessFile ( + SOURCE_FILE *SourceFile + ); + +static +UINT32 +GetStringIdentifierName ( + IN SOURCE_FILE *SourceFile, + IN OUT WCHAR *StringIdentifierName, + IN UINT32 StringIdentifierNameLen + ); + +static +STATUS +GetLanguageIdentifierName ( + IN SOURCE_FILE *SourceFile, + IN OUT WCHAR *LanguageIdentifierName, + IN UINT32 LanguageIdentifierNameLen, + IN BOOLEAN Optional + ); + +static +WCHAR * +GetPrintableLanguageName ( + IN SOURCE_FILE *SourceFile + ); + +static +STATUS +AddCommandLineLanguage ( + IN INT8 *Language + ); + +static +WCHAR * +GetQuotedString ( + SOURCE_FILE *SourceFile, + BOOLEAN Optional + ); + +static +STATUS +ProcessIncludeFile ( + SOURCE_FILE *SourceFile, + SOURCE_FILE *ParentSourceFile + ); + +static +STATUS +ParseFile ( + SOURCE_FILE *SourceFile + ); + +static +FILE * +FindFile ( + IN INT8 *FileName, + OUT INT8 *FoundFileName, + IN UINT32 FoundFileNameLen + ); + +static +STATUS +ProcessArgs ( + int Argc, + char *Argv[] + ); + +static +STATUS +ProcessFile ( + SOURCE_FILE *SourceFile + ); + +static +UINT32 +wstrcmp ( + WCHAR *Buffer, + WCHAR *Str + ); + +static +WCHAR * +wstrcatenate ( + WCHAR *Dst, + WCHAR *Src + ); + +static +void +Usage ( + VOID + ); + +static +void +FreeLists ( + VOID + ); + +static +void +ProcessTokenString ( + SOURCE_FILE *SourceFile + ); + +static +void +ProcessTokenInclude ( + SOURCE_FILE *SourceFile + ); + +static +void +ProcessTokenScope ( + SOURCE_FILE *SourceFile + ); + +static +void +ProcessTokenLanguage ( + SOURCE_FILE *SourceFile + ); + +static +void +ProcessTokenLangDef ( + SOURCE_FILE *SourceFile + ); + +static +VOID +ProcessTokenSecondaryLangDef ( + SOURCE_FILE *SourceFile + ); + +static +STATUS +ScanFiles ( + TEXT_STRING_LIST *ScanFiles + ); + +static +STATUS +ParseIndirectionFiles ( + TEXT_STRING_LIST *Files + ); + +STATUS +StringDBCreateHiiExportPack ( + INT8 *OutputFileName + ); + +int +main ( + int Argc, + char *Argv[] + ) +/*++ + +Routine Description: + + Call the routine to parse the command-line options, then process the file. + +Arguments: + + Argc - Standard C main() argc and argv. + Argv - Standard C main() argc and argv. + +Returns: + + 0 if successful + nonzero otherwise + +--*/ +{ + STATUS Status; + + SetUtilityName (PROGRAM_NAME); + // + // Process the command-line arguments + // + Status = ProcessArgs (Argc, Argv); + if (Status != STATUS_SUCCESS) { + return Status; + } + // + // Initialize the database manager + // + StringDBConstructor (); + // + // We always try to read in an existing database file. It may not + // exist, which is ok usually. + // + if (mGlobals.NewDatabase == 0) { + // + // Read all databases specified. + // + for (mGlobals.LastDatabaseFileName = mGlobals.DatabaseFileName; + mGlobals.LastDatabaseFileName != NULL; + mGlobals.LastDatabaseFileName = mGlobals.LastDatabaseFileName->Next + ) { + Status = StringDBReadDatabase (mGlobals.LastDatabaseFileName->Str, TRUE, mGlobals.VerboseDatabaseRead); + if (Status != STATUS_SUCCESS) { + return Status; + } + } + } + // + // Read indirection file(s) if specified + // + if (ParseIndirectionFiles (mGlobals.IndirectionFileName) != STATUS_SUCCESS) { + goto Finish; + } + // + // If scanning source files, do that now + // + if (mGlobals.Mode == MODE_SCAN) { + ScanFiles (mGlobals.ScanFileName); + } else if (mGlobals.Mode == MODE_PARSE) { + // + // Parsing a unicode strings file + // + mGlobals.SourceFiles.ControlCharacter = DEFAULT_CONTROL_CHARACTER; + if (mGlobals.OutputDependencyFileName[0] != 0) { + if ((mGlobals.OutputDependencyFptr = fopen (mGlobals.OutputDependencyFileName, "w")) == NULL) { + Error (NULL, 0, 0, mGlobals.OutputDependencyFileName, "failed to open output dependency file"); + goto Finish; + } + } + Status = ProcessIncludeFile (&mGlobals.SourceFiles, NULL); + if (mGlobals.OutputDependencyFptr != NULL) { + fclose (mGlobals.OutputDependencyFptr); + } + if (Status != STATUS_SUCCESS) { + goto Finish; + } + } + // + // Create the string defines header file if there have been no errors. + // + ParserSetPosition (NULL, 0); + if ((mGlobals.StringHFileName[0] != 0) && (GetUtilityStatus () < STATUS_ERROR)) { + Status = StringDBDumpStringDefines (mGlobals.StringHFileName, mGlobals.BaseName); + if (Status != EFI_SUCCESS) { + goto Finish; + } + } + + // + // Dump the strings to a .c file if there have still been no errors. + // + if ((mGlobals.StringCFileName[0] != 0) && (GetUtilityStatus () < STATUS_ERROR)) { + Status = StringDBDumpCStrings ( + mGlobals.BaseName, + mGlobals.StringCFileName + ); + if (Status != EFI_SUCCESS) { + goto Finish; + } + } + + // + // Dump the database if requested + // + if ((mGlobals.DumpUFileName[0] != 0) && (GetUtilityStatus () < STATUS_ERROR)) { + StringDBDumpDatabase (NULL, mGlobals.DumpUFileName, FALSE); + } + // + // Dump the string data as HII binary string pack if requested + // + if ((mGlobals.HiiExportPackFileName[0] != 0) && (GetUtilityStatus () < STATUS_ERROR)) { + StringDBCreateHiiExportPack (mGlobals.HiiExportPackFileName); + } + // + // Always update the database if no errors and not in dump mode. If they specified -od + // for an output database file name, then use that name. Otherwise use the name of + // the first database file specified with -db + // + if ((mGlobals.Mode != MODE_DUMP) && (GetUtilityStatus () < STATUS_ERROR)) { + if (mGlobals.OutputDatabaseFileName[0]) { + Status = StringDBWriteDatabase (mGlobals.OutputDatabaseFileName, mGlobals.VerboseDatabaseWrite); + } else { + Status = StringDBWriteDatabase (mGlobals.DatabaseFileName->Str, mGlobals.VerboseDatabaseWrite); + } + + if (Status != EFI_SUCCESS) { + goto Finish; + } + } + +Finish: + // + // Free up memory + // + FreeLists (); + StringDBDestructor (); + return GetUtilityStatus (); +} + +static +STATUS +ProcessIncludeFile ( + SOURCE_FILE *SourceFile, + SOURCE_FILE *ParentSourceFile + ) +/*++ + +Routine Description: + + Given a source file, open the file and parse it + +Arguments: + + SourceFile - name of file to parse + ParentSourceFile - for error reporting purposes, the file that #included SourceFile. + +Returns: + + Standard status. + +--*/ +{ + static UINT32 NestDepth = 0; + INT8 FoundFileName[MAX_PATH]; + STATUS Status; + + Status = STATUS_SUCCESS; + NestDepth++; + // + // Print the file being processed. Indent so you can tell the include nesting + // depth. + // + if (mGlobals.Verbose) { + fprintf (stdout, "%*cProcessing file '%s'\n", NestDepth * 2, ' ', SourceFile->FileName); + } + + // + // Make sure we didn't exceed our maximum nesting depth + // + if (NestDepth > MAX_NEST_DEPTH) { + Error (NULL, 0, 0, SourceFile->FileName, "max nesting depth (%d) exceeded", NestDepth); + Status = STATUS_ERROR; + goto Finish; + } + // + // Try to open the file locally, and if that fails try along our include paths. + // + strcpy (FoundFileName, SourceFile->FileName); + if ((SourceFile->Fptr = fopen (FoundFileName, "rb")) == NULL) { + // + // Try to find it among the paths if it has a parent (that is, it is included + // by someone else). + // + if (ParentSourceFile == NULL) { + Error (NULL, 0, 0, SourceFile->FileName, "file not found"); + Status = STATUS_ERROR; + goto Finish; + } + + SourceFile->Fptr = FindFile (SourceFile->FileName, FoundFileName, sizeof (FoundFileName)); + if (SourceFile->Fptr == NULL) { + Error (ParentSourceFile->FileName, ParentSourceFile->LineNum, 0, SourceFile->FileName, "include file not found"); + Status = STATUS_ERROR; + goto Finish; + } + } + + // + // Output the dependency + // + if (mGlobals.OutputDependencyFptr != NULL) { + fprintf (mGlobals.OutputDependencyFptr, "%s : %s\n", mGlobals.DatabaseFileName->Str, FoundFileName); + // + // Add pseudo target to avoid incremental build failure when the file is deleted + // + fprintf (mGlobals.OutputDependencyFptr, "%s : \n", FoundFileName); + } + + // + // Process the file found + // + ProcessFile (SourceFile); + +Finish: + NestDepth--; + // + // Close open files and return status + // + if (SourceFile->Fptr != NULL) { + fclose (SourceFile->Fptr); + } + + return Status; +} + +static +STATUS +ProcessFile ( + SOURCE_FILE *SourceFile + ) +{ + // + // Get the file size, and then read the entire thing into memory. + // Allocate space for a terminator character. + // + fseek (SourceFile->Fptr, 0, SEEK_END); + SourceFile->FileSize = ftell (SourceFile->Fptr); + fseek (SourceFile->Fptr, 0, SEEK_SET); + SourceFile->FileBuffer = (WCHAR *) malloc (SourceFile->FileSize + sizeof (WCHAR)); + if (SourceFile->FileBuffer == NULL) { + Error (NULL, 0, 0, "memory allocation failure", NULL); + return STATUS_ERROR; + } + + fread ((VOID *) SourceFile->FileBuffer, SourceFile->FileSize, 1, SourceFile->Fptr); + SourceFile->FileBuffer[(SourceFile->FileSize / sizeof (WCHAR))] = UNICODE_NULL; + // + // Pre-process the file to replace comments with spaces + // + PreprocessFile (SourceFile); + // + // Parse the file + // + ParseFile (SourceFile); + free (SourceFile->FileBuffer); + return STATUS_SUCCESS; +} + +static +STATUS +ParseFile ( + SOURCE_FILE *SourceFile + ) +{ + BOOLEAN InComment; + UINT32 Len; + + // + // First character of a unicode file is special. Make sure + // + if (SourceFile->FileBufferPtr[0] != UNICODE_FILE_START) { + Error (SourceFile->FileName, 1, 0, SourceFile->FileName, "file does not appear to be a unicode file"); + return STATUS_ERROR; + } + + SourceFile->FileBufferPtr++; + InComment = FALSE; + // + // Print the first line if in verbose mode + // + if (mGlobals.Verbose) { + printf ("%d: %S\n", SourceFile->LineNum, SourceFile->FileBufferPtr); + } + // + // Since the syntax is relatively straightforward, just switch on the next char + // + while (!EndOfFile (SourceFile)) { + // + // Check for whitespace + // + if (SourceFile->FileBufferPtr[0] == UNICODE_SPACE) { + SourceFile->FileBufferPtr++; + } else if (SourceFile->FileBufferPtr[0] == UNICODE_TAB) { + SourceFile->FileBufferPtr++; + } else if (SourceFile->FileBufferPtr[0] == UNICODE_CR) { + SourceFile->FileBufferPtr++; + } else if (SourceFile->FileBufferPtr[0] == UNICODE_LF) { + SourceFile->FileBufferPtr++; + SourceFile->LineNum++; + if (mGlobals.Verbose) { + printf ("%d: %S\n", SourceFile->LineNum, SourceFile->FileBufferPtr); + } + + InComment = FALSE; + } else if (SourceFile->FileBufferPtr[0] == 0) { + SourceFile->FileBufferPtr++; + } else if (InComment) { + SourceFile->FileBufferPtr++; + } else if ((SourceFile->FileBufferPtr[0] == UNICODE_SLASH) && (SourceFile->FileBufferPtr[1] == UNICODE_SLASH)) { + SourceFile->FileBufferPtr += 2; + InComment = TRUE; + } else if (SourceFile->SkipToHash && (SourceFile->FileBufferPtr[0] != SourceFile->ControlCharacter)) { + SourceFile->FileBufferPtr++; + } else { + SourceFile->SkipToHash = FALSE; + if ((SourceFile->FileBufferPtr[0] == SourceFile->ControlCharacter) && + ((Len = wstrcmp (SourceFile->FileBufferPtr + 1, L"include")) > 0) + ) { + SourceFile->FileBufferPtr += Len + 1; + ProcessTokenInclude (SourceFile); + } else if ((SourceFile->FileBufferPtr[0] == SourceFile->ControlCharacter) && + (Len = wstrcmp (SourceFile->FileBufferPtr + 1, L"scope")) > 0 + ) { + SourceFile->FileBufferPtr += Len + 1; + ProcessTokenScope (SourceFile); + } else if ((SourceFile->FileBufferPtr[0] == SourceFile->ControlCharacter) && + (Len = wstrcmp (SourceFile->FileBufferPtr + 1, L"language")) > 0 + ) { + SourceFile->FileBufferPtr += Len + 1; + ProcessTokenLanguage (SourceFile); + } else if ((SourceFile->FileBufferPtr[0] == SourceFile->ControlCharacter) && + (Len = wstrcmp (SourceFile->FileBufferPtr + 1, L"langdef")) > 0 + ) { + SourceFile->FileBufferPtr += Len + 1; + ProcessTokenLangDef (SourceFile); + } else if ((SourceFile->FileBufferPtr[0] == SourceFile->ControlCharacter) && + (Len = wstrcmp (SourceFile->FileBufferPtr + 1, L"secondarylang")) > 0 + ) { + SourceFile->FileBufferPtr += Len + 1; + ProcessTokenSecondaryLangDef (SourceFile); + } else if ((SourceFile->FileBufferPtr[0] == SourceFile->ControlCharacter) && + (Len = wstrcmp (SourceFile->FileBufferPtr + 1, L"string")) > 0 + ) { + SourceFile->FileBufferPtr += Len + 1; + ProcessTokenString (SourceFile); + } else if ((SourceFile->FileBufferPtr[0] == SourceFile->ControlCharacter) && + (Len = wstrcmp (SourceFile->FileBufferPtr + 1, L"EFI_BREAKPOINT()")) > 0 + ) { + SourceFile->FileBufferPtr += Len; + EFI_BREAKPOINT (); + } else if ((SourceFile->FileBufferPtr[0] == SourceFile->ControlCharacter) && + (SourceFile->FileBufferPtr[1] == UNICODE_EQUAL_SIGN) + ) { + SourceFile->ControlCharacter = SourceFile->FileBufferPtr[2]; + SourceFile->FileBufferPtr += 3; + } else { + Error (SourceFile->FileName, SourceFile->LineNum, 0, "unrecognized token", "%S", SourceFile->FileBufferPtr); + // + // Treat rest of line as a comment. + // + InComment = TRUE; + } + } + } + + return STATUS_SUCCESS; +} + +static +void +PreprocessFile ( + SOURCE_FILE *SourceFile + ) +/*++ + +Routine Description: + Preprocess a file to replace all carriage returns with NULLs so + we can print lines from the file to the screen. + +Arguments: + SourceFile - structure that we use to keep track of an input file. + +Returns: + Nothing. + +--*/ +{ + BOOLEAN InComment; + + RewindFile (SourceFile); + InComment = FALSE; + while (!EndOfFile (SourceFile)) { + // + // If a line-feed, then no longer in a comment + // + if (SourceFile->FileBufferPtr[0] == UNICODE_LF) { + SourceFile->FileBufferPtr++; + SourceFile->LineNum++; + InComment = 0; + } else if (SourceFile->FileBufferPtr[0] == UNICODE_CR) { + // + // Replace all carriage returns with a NULL so we can print stuff + // + SourceFile->FileBufferPtr[0] = 0; + SourceFile->FileBufferPtr++; + } else if (InComment) { + SourceFile->FileBufferPtr[0] = UNICODE_SPACE; + SourceFile->FileBufferPtr++; + } else if ((SourceFile->FileBufferPtr[0] == UNICODE_SLASH) && (SourceFile->FileBufferPtr[1] == UNICODE_SLASH)) { + SourceFile->FileBufferPtr += 2; + InComment = TRUE; + } else { + SourceFile->FileBufferPtr++; + } + } + // + // Could check for end-of-file and still in a comment, but + // should not be necessary. So just restore the file pointers. + // + RewindFile (SourceFile); +} + +static +WCHAR * +GetPrintableLanguageName ( + IN SOURCE_FILE *SourceFile + ) +{ + WCHAR *String; + WCHAR *Start; + WCHAR *Ptr; + UINT32 Len; + + SkipWhiteSpace (SourceFile); + if (SourceFile->FileBufferPtr[0] != UNICODE_DOUBLE_QUOTE) { + Error (SourceFile->FileName, SourceFile->LineNum, 0, "expected quoted printable language name", "%S", SourceFile->FileBufferPtr); + SourceFile->SkipToHash = TRUE; + return NULL; + } + + Len = 0; + SourceFile->FileBufferPtr++; + Start = Ptr = SourceFile->FileBufferPtr; + while (!EndOfFile (SourceFile)) { + if (SourceFile->FileBufferPtr[0] == UNICODE_CR) { + Warning (SourceFile->FileName, SourceFile->LineNum, 0, "carriage return found in quoted string", "%S", Start); + break; + } else if (SourceFile->FileBufferPtr[0] == UNICODE_DOUBLE_QUOTE) { + break; + } + + SourceFile->FileBufferPtr++; + Len++; + } + + if (SourceFile->FileBufferPtr[0] != UNICODE_DOUBLE_QUOTE) { + Warning ( + SourceFile->FileName, + SourceFile->LineNum, + 0, + "missing closing quote on printable language name string", + "%S", + Start + ); + } else { + SourceFile->FileBufferPtr++; + } + // + // Now allocate memory for the string and save it off + // + String = (WCHAR *) malloc ((Len + 1) * sizeof (WCHAR)); + if (String == NULL) { + Error (NULL, 0, 0, "memory allocation failed", NULL); + return NULL; + } + // + // Copy the string from the file buffer to the local copy. + // We do no reformatting of it whatsoever at this point. + // + Ptr = String; + while (Len > 0) { + *Ptr = *Start; + Start++; + Ptr++; + Len--; + } + + *Ptr = 0; + // + // Now format the string to convert \wide and \narrow controls + // + StringDBFormatString (String); + return String; +} + +static struct { + WCHAR *ISO639; + WCHAR *RFC3066; +} LanguageConvertTable[] = { + { L"eng", L"en-US" }, + { L"fra", L"fr-FR" }, + { L"spa", L"es-ES" }, + { NULL, NULL } +}; + +WCHAR * +GetLangCode ( + IN WCHAR *Lang + ) +{ + UINT32 Index; + WCHAR *LangCode; + + LangCode = NULL; + + // + // The Lang is xx-XX format and return. + // + if (wcschr (Lang, L'-') != NULL) { + LangCode = (WCHAR *) malloc ((wcslen (Lang) + 1) * sizeof(WCHAR)); + if (LangCode != NULL) { + wcscpy (LangCode, Lang); + } + return LangCode; + } + + // + // Convert the language accoring to the table. + // + for (Index = 0; LanguageConvertTable[Index].ISO639 != NULL; Index++) { + if (wcscmp(LanguageConvertTable[Index].ISO639, Lang) == 0) { + LangCode = (WCHAR *) malloc ((wcslen (LanguageConvertTable[Index].RFC3066) + 1) * sizeof (WCHAR)); + if (LangCode != NULL) { + wcscpy (LangCode, LanguageConvertTable[Index].RFC3066); + } + return LangCode; + } + } + + return NULL; +} + +WCHAR * +GetLangCodeList ( + IN WCHAR *SecondaryLangList + ) +{ + WCHAR *CodeBeg, *CodeEnd; + WCHAR *CodeRet; + WCHAR *LangCodeList = NULL; + WCHAR *TempLangCodeList = NULL; + + TempLangCodeList = (WCHAR *) malloc ((wcslen(SecondaryLangList) + 1) * sizeof(WCHAR)); + if (TempLangCodeList == NULL) { + return NULL; + } + wcscpy (TempLangCodeList, SecondaryLangList); + CodeBeg = TempLangCodeList; + + while (CodeBeg != NULL) { + CodeEnd = wcschr (CodeBeg, L';'); + if (CodeEnd != NULL) { + *CodeEnd = L'\0'; + CodeEnd++; + } + + CodeRet = GetLangCode (CodeBeg); + if (CodeRet != NULL) { + if (LangCodeList != NULL) { + LangCodeList = wstrcatenate (LangCodeList, L";"); + } + LangCodeList = wstrcatenate (LangCodeList, CodeRet); + } + + CodeBeg = CodeEnd; + FREE (CodeRet); + } + + free (TempLangCodeList); + + return LangCodeList; +} + +static +WCHAR * +GetSecondaryLanguageList ( + IN SOURCE_FILE *SourceFile + ) +{ + WCHAR *SecondaryLangList = NULL; + WCHAR SecondaryLang[MAX_STRING_IDENTIFIER_NAME + 1]; + WCHAR *LangCodeList; + WCHAR *Start; + WCHAR *Ptr; + UINT32 Index; + + SkipWhiteSpace (SourceFile); + + if (SourceFile->FileBufferPtr[0] != UNICODE_OPEN_PAREN) { + Error (SourceFile->FileName, SourceFile->LineNum, 0, "expected open bracket", "%S", SourceFile->FileBufferPtr); + SourceFile->SkipToHash = TRUE; + return NULL; + } + + Index = 0; + SecondaryLang [0] = L'\0'; + SourceFile->FileBufferPtr++; + Start = Ptr = SourceFile->FileBufferPtr; + while (!EndOfFile (SourceFile)) { + if (((SourceFile->FileBufferPtr[0] >= UNICODE_a) && (SourceFile->FileBufferPtr[0] <= UNICODE_z)) || + ((SourceFile->FileBufferPtr[0] >= UNICODE_A) && (SourceFile->FileBufferPtr[0] <= UNICODE_Z)) || + (SourceFile->FileBufferPtr[0] == UNICODE_MINUS)) { + if (Index > MAX_STRING_IDENTIFIER_NAME) { + Error (SourceFile->FileName, SourceFile->LineNum, 0, "secondary language length is too lang", "%S", SourceFile->FileBufferPtr); + goto Err; + } + SecondaryLang[Index] = SourceFile->FileBufferPtr[0]; + Index++; + } else if (SourceFile->FileBufferPtr[0] == UNICODE_SPACE) { + SecondaryLang[Index] = L'\0'; + + if (SecondaryLang[0] != L'\0') { + if (SecondaryLangList != NULL) { + SecondaryLangList = wstrcatenate (SecondaryLangList, L";"); + } + SecondaryLangList = wstrcatenate (SecondaryLangList, SecondaryLang); + Index = 0; + SecondaryLang [0] = L'\0'; + SourceFile->FileBufferPtr++; + continue; + } + } else if (SourceFile->FileBufferPtr[0] == UNICODE_CLOSE_PAREN) { + if (SecondaryLangList != NULL) { + SecondaryLangList = wstrcatenate (SecondaryLangList, L";"); + } + SecondaryLangList = wstrcatenate (SecondaryLangList, SecondaryLang); + break; + } else { + Error (SourceFile->FileName, SourceFile->LineNum, 0, "can not recognize the secondary language", "%S", SourceFile->FileBufferPtr); + goto Err; + } + + SourceFile->FileBufferPtr++; + } + + if (SourceFile->FileBufferPtr[0] != UNICODE_CLOSE_PAREN) { + Error (SourceFile->FileName, SourceFile->LineNum, 0, "missing closing bracket", "%S", Start); + } else { + SourceFile->FileBufferPtr++; + } + + LangCodeList = GetLangCodeList (SecondaryLangList); + FREE (SecondaryLangList); + return LangCodeList; + +Err: + FREE(SecondaryLangList); + return NULL; +} + +static +WCHAR * +GetQuotedString ( + SOURCE_FILE *SourceFile, + BOOLEAN Optional + ) +{ + WCHAR *String; + WCHAR *Start; + WCHAR *Ptr; + UINT32 Len; + BOOLEAN PreviousBackslash; + + if (SourceFile->FileBufferPtr[0] != UNICODE_DOUBLE_QUOTE) { + if (!Optional) { + Error (SourceFile->FileName, SourceFile->LineNum, 0, "expected quoted string", "%S", SourceFile->FileBufferPtr); + } + + return NULL; + } + + Len = 0; + SourceFile->FileBufferPtr++; + Start = Ptr = SourceFile->FileBufferPtr; + PreviousBackslash = FALSE; + while (!EndOfFile (SourceFile)) { + if ((SourceFile->FileBufferPtr[0] == UNICODE_DOUBLE_QUOTE) && (!PreviousBackslash)) { + break; + } else if (SourceFile->FileBufferPtr[0] == UNICODE_CR) { + Warning (SourceFile->FileName, SourceFile->LineNum, 0, "carriage return found in quoted string", "%S", Start); + PreviousBackslash = FALSE; + } else if (SourceFile->FileBufferPtr[0] == UNICODE_BACKSLASH) { + PreviousBackslash = TRUE; + } else { + PreviousBackslash = FALSE; + } + + SourceFile->FileBufferPtr++; + Len++; + } + + if (SourceFile->FileBufferPtr[0] != UNICODE_DOUBLE_QUOTE) { + Warning (SourceFile->FileName, SourceFile->LineNum, 0, "missing closing quote on string", "%S", Start); + } else { + SourceFile->FileBufferPtr++; + } + // + // Now allocate memory for the string and save it off + // + String = (WCHAR *) malloc ((Len + 1) * sizeof (WCHAR)); + if (String == NULL) { + Error (NULL, 0, 0, "memory allocation failed", NULL); + return NULL; + } + // + // Copy the string from the file buffer to the local copy. + // We do no reformatting of it whatsoever at this point. + // + Ptr = String; + while (Len > 0) { + *Ptr = *Start; + Start++; + Ptr++; + Len--; + } + + *Ptr = 0; + return String; +} +// +// Parse: +// #string STR_ID_NAME +// +// All we can do is call the string database to add the string identifier. Unfortunately +// he'll have to keep track of the last identifier we added. +// +static +void +ProcessTokenString ( + SOURCE_FILE *SourceFile + ) +{ + WCHAR StringIdentifier[MAX_STRING_IDENTIFIER_NAME + 1]; + UINT16 StringId; + // + // Extract the string identifier name and add it to the database. + // + if (GetStringIdentifierName (SourceFile, StringIdentifier, sizeof (StringIdentifier)) > 0) { + StringId = STRING_ID_INVALID; + StringDBAddStringIdentifier (StringIdentifier, &StringId, 0); + } else { + // + // Error recovery -- skip to the next # + // + SourceFile->SkipToHash = TRUE; + } +} + +static +BOOLEAN +EndOfFile ( + SOURCE_FILE *SourceFile + ) +{ + // + // The file buffer pointer will typically get updated before the End-of-file flag in the + // source file structure, so check it first. + // + if (SourceFile->FileBufferPtr >= SourceFile->FileBuffer + SourceFile->FileSize / sizeof (WCHAR)) { + SourceFile->EndOfFile = TRUE; + return TRUE; + } + + if (SourceFile->EndOfFile) { + return TRUE; + } + + return FALSE; +} + +static +UINT32 +GetStringIdentifierName ( + IN SOURCE_FILE *SourceFile, + IN OUT WCHAR *StringIdentifierName, + IN UINT32 StringIdentifierNameLen + ) +{ + UINT32 Len; + WCHAR *From; + WCHAR *Start; + + // + // Skip whitespace + // + SkipWhiteSpace (SourceFile); + if (SourceFile->EndOfFile) { + Error (SourceFile->FileName, SourceFile->LineNum, 0, "end-of-file encountered", "expected string identifier"); + return 0; + } + // + // Verify first character of name is [A-Za-z] + // + Len = 0; + StringIdentifierNameLen /= 2; + From = SourceFile->FileBufferPtr; + Start = SourceFile->FileBufferPtr; + if (((SourceFile->FileBufferPtr[0] >= UNICODE_A) && (SourceFile->FileBufferPtr[0] <= UNICODE_Z)) || + ((SourceFile->FileBufferPtr[0] >= UNICODE_z) && (SourceFile->FileBufferPtr[0] <= UNICODE_z)) + ) { + // + // Do nothing + // + } else { + Error (SourceFile->FileName, SourceFile->LineNum, 0, "invalid character in string identifier name", "%S", Start); + return 0; + } + + while (!EndOfFile (SourceFile)) { + if (((SourceFile->FileBufferPtr[0] >= UNICODE_A) && (SourceFile->FileBufferPtr[0] <= UNICODE_Z)) || + ((SourceFile->FileBufferPtr[0] >= UNICODE_z) && (SourceFile->FileBufferPtr[0] <= UNICODE_z)) || + ((SourceFile->FileBufferPtr[0] >= UNICODE_0) && (SourceFile->FileBufferPtr[0] <= UNICODE_9)) || + (SourceFile->FileBufferPtr[0] == UNICODE_UNDERSCORE) + ) { + Len++; + if (Len >= StringIdentifierNameLen) { + Error (SourceFile->FileName, SourceFile->LineNum, 0, "string identifier name too long", "%S", Start); + return 0; + } + + *StringIdentifierName = SourceFile->FileBufferPtr[0]; + StringIdentifierName++; + SourceFile->FileBufferPtr++; + } else if (SkipWhiteSpace (SourceFile) == 0) { + Error (SourceFile->FileName, SourceFile->LineNum, 0, "invalid string identifier name", "%S", Start); + return 0; + } else { + break; + } + } + // + // Terminate the copy of the string. + // + *StringIdentifierName = 0; + return Len; +} + +static +STATUS +GetLanguageIdentifierName ( + IN SOURCE_FILE *SourceFile, + IN OUT WCHAR *LanguageIdentifierName, + IN UINT32 LanguageIdentifierNameLen, + IN BOOLEAN Optional + ) +{ + UINT32 Len; + WCHAR *Start; + WCHAR *LangCode; + WCHAR *LanguageIdentifier; + + LanguageIdentifier = LanguageIdentifierName; + + // + // Skip whitespace + // + SkipWhiteSpace (SourceFile); + if (SourceFile->EndOfFile) { + if (!Optional) { + Error (SourceFile->FileName, SourceFile->LineNum, 0, "end-of-file encountered", "expected language identifier"); + return STATUS_ERROR; + } + + return STATUS_SUCCESS; + } + // + // This function is called to optionally get a language identifier name in: + // #string STR_ID eng "the string" + // If it's optional, and we find a double-quote, then return now. + // + if (Optional) { + if (*SourceFile->FileBufferPtr == UNICODE_DOUBLE_QUOTE) { + return STATUS_SUCCESS; + } + } + + LanguageIdentifierNameLen /= 2; + // + // Internal error if we weren't given at least 4 WCHAR's to work with. + // + if (LanguageIdentifierNameLen < LANGUAGE_IDENTIFIER_NAME_LEN + 1) { + Error ( + SourceFile->FileName, + SourceFile->LineNum, + 0, + "app error -- language identifier name length is invalid", + NULL + ); + } + + Len = 0; + Start = SourceFile->FileBufferPtr; + while (!EndOfFile (SourceFile)) { + if (((SourceFile->FileBufferPtr[0] >= UNICODE_a) && (SourceFile->FileBufferPtr[0] <= UNICODE_z)) || + ((SourceFile->FileBufferPtr[0] >= UNICODE_A) && (SourceFile->FileBufferPtr[0] <= UNICODE_Z)) || + (SourceFile->FileBufferPtr[0] == UNICODE_MINUS)) { + Len++; + if (Len > LANGUAGE_IDENTIFIER_NAME_LEN) { + Error (SourceFile->FileName, SourceFile->LineNum, 0, "language identifier name too long", "%S", Start); + return STATUS_ERROR; + } + *LanguageIdentifierName = SourceFile->FileBufferPtr[0]; + SourceFile->FileBufferPtr++; + LanguageIdentifierName++; + } else if (!IsWhiteSpace (SourceFile)) { + Error (SourceFile->FileName, SourceFile->LineNum, 0, "invalid language identifier name", "%S", Start); + return STATUS_ERROR; + } else { + break; + } + } + // + // Terminate the copy of the string. + // + *LanguageIdentifierName = 0; + LangCode = GetLangCode (LanguageIdentifier); + if (LangCode != NULL) { + wcscpy (LanguageIdentifier, LangCode); + FREE (LangCode); + } + return STATUS_SUCCESS; +} + +static +void +ProcessTokenInclude ( + SOURCE_FILE *SourceFile + ) +{ + INT8 IncludeFileName[MAX_PATH]; + INT8 *To; + UINT32 Len; + BOOLEAN ReportedError; + SOURCE_FILE IncludedSourceFile; + + ReportedError = FALSE; + if (SkipWhiteSpace (SourceFile) == 0) { + Warning (SourceFile->FileName, SourceFile->LineNum, 0, "expected whitespace following #include keyword", NULL); + } + // + // Should be quoted file name + // + if (SourceFile->FileBufferPtr[0] != UNICODE_DOUBLE_QUOTE) { + Error (SourceFile->FileName, SourceFile->LineNum, 0, "expected quoted include file name", NULL); + goto FailDone; + } + + SourceFile->FileBufferPtr++; + // + // Copy the filename as ascii to our local string + // + To = IncludeFileName; + Len = 0; + while (!EndOfFile (SourceFile)) { + if ((SourceFile->FileBufferPtr[0] == UNICODE_CR) || (SourceFile->FileBufferPtr[0] == UNICODE_LF)) { + Error (SourceFile->FileName, SourceFile->LineNum, 0, "end-of-line found in quoted include file name", NULL); + goto FailDone; + } + + if (SourceFile->FileBufferPtr[0] == UNICODE_DOUBLE_QUOTE) { + SourceFile->FileBufferPtr++; + break; + } + // + // If too long, then report the error once and process until the closing quote + // + Len++; + if (!ReportedError && (Len >= sizeof (IncludeFileName))) { + Error (SourceFile->FileName, SourceFile->LineNum, 0, "length of include file name exceeds limit", NULL); + ReportedError = TRUE; + } + + if (!ReportedError) { + *To = UNICODE_TO_ASCII (SourceFile->FileBufferPtr[0]); + To++; + } + + SourceFile->FileBufferPtr++; + } + + if (!ReportedError) { + *To = 0; + memset ((char *) &IncludedSourceFile, 0, sizeof (SOURCE_FILE)); + strcpy (IncludedSourceFile.FileName, IncludeFileName); + IncludedSourceFile.ControlCharacter = DEFAULT_CONTROL_CHARACTER; + ProcessIncludeFile (&IncludedSourceFile, SourceFile); + // + // printf ("including file '%s'\n", IncludeFileName); + // + } + + return ; +FailDone: + // + // Error recovery -- skip to next # + // + SourceFile->SkipToHash = TRUE; +} + +static +void +ProcessTokenScope ( + SOURCE_FILE *SourceFile + ) +{ + WCHAR StringIdentifier[MAX_STRING_IDENTIFIER_NAME + 1]; + // + // Extract the scope name + // + if (GetStringIdentifierName (SourceFile, StringIdentifier, sizeof (StringIdentifier)) > 0) { + StringDBSetScope (StringIdentifier); + } +} + +// +// Parse: #langdef eng "English" +// #langdef chn "\wideChinese" +// +static +void +ProcessTokenLangDef ( + SOURCE_FILE *SourceFile + ) +{ + STATUS Status; + WCHAR LanguageIdentifier[MAX_STRING_IDENTIFIER_NAME + 1]; + WCHAR *PrintableName; + + Status = GetLanguageIdentifierName (SourceFile, LanguageIdentifier, sizeof (LanguageIdentifier), FALSE); + if (Status != STATUS_SUCCESS) { + return; + } + + // + // Extract the printable name + // + PrintableName = GetPrintableLanguageName (SourceFile); + if (PrintableName != NULL) { + ParserSetPosition (SourceFile->FileName, SourceFile->LineNum); + StringDBAddLanguage (LanguageIdentifier, PrintableName, NULL); + FREE (PrintableName); + return ; + } + // + // Error recovery -- skip to next # + // + SourceFile->SkipToHash = TRUE; +} + +static +VOID +ProcessTokenSecondaryLangDef ( + SOURCE_FILE *SourceFile + ) +{ + STATUS Status; + LANGUAGE_LIST *Lang; + WCHAR LanguageIdentifier[MAX_STRING_IDENTIFIER_NAME + 1]; + WCHAR *LangCode; + WCHAR *SecondaryLangList = NULL; + + Status = GetLanguageIdentifierName (SourceFile, LanguageIdentifier, sizeof (LanguageIdentifier), FALSE); + if (Status != STATUS_SUCCESS) { + return; + } + LangCode = GetLangCode(LanguageIdentifier); + if (LangCode == NULL) { + return ; + } + + Lang = StringDBFindLanguageList (LanguageIdentifier); + if (Lang == NULL) { + return; + } + + SecondaryLangList = GetSecondaryLanguageList (SourceFile); + if (SecondaryLangList != NULL) { + ParserSetPosition (SourceFile->FileName, SourceFile->LineNum); + Status = StringDBAddSecondaryLanguage (LangCode, GetLangCodeList(SecondaryLangList)); + if (Status != STATUS_SUCCESS) { + SourceFile->SkipToHash = TRUE; + } + FREE (LangCode); + FREE (SecondaryLangList); + return ; + } + FREE (LangCode); + + + SourceFile->SkipToHash = TRUE; +} + +static +BOOLEAN +ApparentQuotedString ( + SOURCE_FILE *SourceFile + ) +{ + WCHAR *Ptr; + // + // See if the first and last nonblank characters on the line are double quotes + // + for (Ptr = SourceFile->FileBufferPtr; *Ptr && (*Ptr == UNICODE_SPACE); Ptr++) + ; + if (*Ptr != UNICODE_DOUBLE_QUOTE) { + return FALSE; + } + + while (*Ptr) { + Ptr++; + } + + Ptr--; + for (; *Ptr && (*Ptr == UNICODE_SPACE); Ptr--) + ; + if (*Ptr != UNICODE_DOUBLE_QUOTE) { + return FALSE; + } + + return TRUE; +} +// +// Parse: +// #language eng "some string " "more string" +// +static +void +ProcessTokenLanguage ( + SOURCE_FILE *SourceFile + ) +{ + STATUS Status; + WCHAR *String; + WCHAR *SecondString; + WCHAR *TempString; + WCHAR *From; + WCHAR *To; + WCHAR Language[LANGUAGE_IDENTIFIER_NAME_LEN + 1]; + UINT32 Len; + BOOLEAN PreviousNewline; + // + // Get the language identifier + // + Language[0] = 0; + Status = GetLanguageIdentifierName (SourceFile, Language, sizeof (Language), TRUE); + if (Status != STATUS_SUCCESS) { + return; + } + + // + // Extract the string value. It's either a quoted string that starts on the current line, or + // an unquoted string that starts on the following line and continues until the next control + // character in column 1. + // Look ahead to find a quote or a newline + // + if (SkipTo (SourceFile, UNICODE_DOUBLE_QUOTE, TRUE)) { + String = GetQuotedString (SourceFile, FALSE); + if (String != NULL) { + // + // Set the position in the file of where we are parsing for error + // reporting purposes. Then start looking ahead for additional + // quoted strings, and concatenate them until we get a failure + // back from the string parser. + // + Len = wcslen (String) + 1; + ParserSetPosition (SourceFile->FileName, SourceFile->LineNum); + do { + SkipWhiteSpace (SourceFile); + SecondString = GetQuotedString (SourceFile, TRUE); + if (SecondString != NULL) { + Len += wcslen (SecondString); + TempString = (WCHAR *) malloc (Len * sizeof (WCHAR)); + if (TempString == NULL) { + Error (NULL, 0, 0, "application error", "failed to allocate memory"); + return ; + } + + wcscpy (TempString, String); + wcscat (TempString, SecondString); + free (String); + free (SecondString); + String = TempString; + } + } while (SecondString != NULL); + StringDBAddString (Language, NULL, NULL, String, TRUE, 0); + free (String); + } else { + // + // Error was reported at lower level. Error recovery mode. + // + SourceFile->SkipToHash = TRUE; + } + } else { + if (!mGlobals.UnquotedStrings) { + // + // They're using unquoted strings. If the next non-blank character is a double quote, and the + // last non-blank character on the line is a double quote, then more than likely they're using + // quotes, so they need to put the quoted string on the end of the previous line + // + if (ApparentQuotedString (SourceFile)) { + Warning ( + SourceFile->FileName, + SourceFile->LineNum, + 0, + "unexpected quoted string on line", + "specify -uqs option if necessary" + ); + } + } + // + // Found end-of-line (hopefully). Skip over it and start taking in characters + // until we find a control character at the start of a line. + // + Len = 0; + From = SourceFile->FileBufferPtr; + PreviousNewline = FALSE; + while (!EndOfFile (SourceFile)) { + if (SourceFile->FileBufferPtr[0] == UNICODE_LF) { + PreviousNewline = TRUE; + SourceFile->LineNum++; + } else { + Len++; + if (PreviousNewline && (SourceFile->FileBufferPtr[0] == SourceFile->ControlCharacter)) { + break; + } + + PreviousNewline = FALSE; + } + + SourceFile->FileBufferPtr++; + } + + if ((Len == 0) && EndOfFile (SourceFile)) { + Error (SourceFile->FileName, SourceFile->LineNum, 0, "unexpected end of file", NULL); + SourceFile->SkipToHash = TRUE; + return ; + } + // + // Now allocate a buffer, copy the characters, and add the string. + // + String = (WCHAR *) malloc ((Len + 1) * sizeof (WCHAR)); + if (String == NULL) { + Error (NULL, 0, 0, "application error", "failed to allocate memory"); + return ; + } + + To = String; + while (From < SourceFile->FileBufferPtr) { + switch (*From) { + case UNICODE_LF: + case 0: + break; + + default: + *To = *From; + To++; + break; + } + + From++; + } + + // + // String[Len] = 0; + // + *To = 0; + StringDBAddString (Language, NULL, NULL, String, TRUE, 0); + } +} + +static +BOOLEAN +IsWhiteSpace ( + SOURCE_FILE *SourceFile + ) +{ + switch (SourceFile->FileBufferPtr[0]) { + case UNICODE_NULL: + case UNICODE_CR: + case UNICODE_SPACE: + case UNICODE_TAB: + case UNICODE_LF: + return TRUE; + + default: + return FALSE; + } +} + +static +UINT32 +SkipWhiteSpace ( + SOURCE_FILE *SourceFile + ) +{ + UINT32 Count; + + Count = 0; + while (!EndOfFile (SourceFile)) { + Count++; + switch (*SourceFile->FileBufferPtr) { + case UNICODE_NULL: + case UNICODE_CR: + case UNICODE_SPACE: + case UNICODE_TAB: + SourceFile->FileBufferPtr++; + break; + + case UNICODE_LF: + SourceFile->FileBufferPtr++; + SourceFile->LineNum++; + if (mGlobals.Verbose) { + printf ("%d: %S\n", SourceFile->LineNum, SourceFile->FileBufferPtr); + } + break; + + default: + return Count - 1; + } + } + // + // Some tokens require trailing whitespace. If we're at the end of the + // file, then we count that as well. + // + if ((Count == 0) && (EndOfFile (SourceFile))) { + Count++; + } + + return Count; +} + +static +UINT32 +wstrcmp ( + WCHAR *Buffer, + WCHAR *Str + ) +{ + UINT32 Len; + + Len = 0; + while (*Str == *Buffer) { + Buffer++; + Str++; + Len++; + } + + if (*Str) { + return 0; + } + + return Len; +} + +static +WCHAR * +wstrcatenate ( + WCHAR *Dst, + WCHAR *Src + ) +{ + UINT32 Len = 0; + WCHAR *Bak = Dst; + + if (Src == NULL) { + return Dst; + } + + if (Dst != NULL) { + Len = wcslen (Dst); + } + Len += wcslen (Src); + Dst = (WCHAR *) malloc ((Len + 1) * 2); + if (Dst == NULL) { + return NULL; + } + + Dst[0] = L'\0'; + if (Bak != NULL) { + wcscpy (Dst, Bak); + FREE (Bak); + } + wcscat (Dst, Src); + return Dst; +} + +// +// Given a filename, try to find it along the include paths. +// +static +FILE * +FindFile ( + IN INT8 *FileName, + OUT INT8 *FoundFileName, + IN UINT32 FoundFileNameLen + ) +{ + FILE *Fptr; + TEXT_STRING_LIST *List; + + // + // Traverse the list of paths and try to find the file + // + List = mGlobals.IncludePaths; + while (List != NULL) { + // + // Put the path and filename together + // + if (strlen (List->Str) + strlen (FileName) + 1 > FoundFileNameLen) { + Error (PROGRAM_NAME, 0, 0, NULL, "internal error - cannot concatenate path+filename"); + return NULL; + } + // + // Append the filename to this include path and try to open the file. + // + strcpy (FoundFileName, List->Str); + strcat (FoundFileName, FileName); + if ((Fptr = fopen (FoundFileName, "rb")) != NULL) { + // + // Return the file pointer + // + return Fptr; + } + + List = List->Next; + } + // + // Not found + // + FoundFileName[0] = 0; + return NULL; +} +// +// Process the command-line arguments +// +static +STATUS +ProcessArgs ( + int Argc, + char *Argv[] + ) +{ + TEXT_STRING_LIST *NewList; + // + // Clear our globals + // + memset ((char *) &mGlobals, 0, sizeof (mGlobals)); + strcpy (mGlobals.BaseName, DEFAULT_BASE_NAME); + // + // Skip program name + // + Argc--; + Argv++; + + if (Argc == 0) { + Usage (); + return STATUS_ERROR; + } + + mGlobals.Mode = MODE_UNKNOWN; + // + // Process until no more -args. + // + while ((Argc > 0) && (Argv[0][0] == '-')) { + // + // -parse option + // + if (_stricmp (Argv[0], "-parse") == 0) { + if (mGlobals.Mode != MODE_UNKNOWN) { + Error (NULL, 0, 0, "only one of -parse/-scan/-dump allowed", NULL); + return STATUS_ERROR; + } + + mGlobals.Mode = MODE_PARSE; + // + // -scan option + // + } else if (_stricmp (Argv[0], "-scan") == 0) { + if (mGlobals.Mode != MODE_UNKNOWN) { + Error (NULL, 0, 0, "only one of -parse/-scan/-dump allowed", NULL); + return STATUS_ERROR; + } + + mGlobals.Mode = MODE_SCAN; + // + // -vscan verbose scanning option + // + } else if (_stricmp (Argv[0], "-vscan") == 0) { + mGlobals.VerboseScan = TRUE; + // + // -dump option + // + } else if (_stricmp (Argv[0], "-dump") == 0) { + if (mGlobals.Mode != MODE_UNKNOWN) { + Error (NULL, 0, 0, "only one of -parse/-scan/-dump allowed", NULL); + return STATUS_ERROR; + } + + mGlobals.Mode = MODE_DUMP; + } else if (_stricmp (Argv[0], "-uqs") == 0) { + mGlobals.UnquotedStrings = TRUE; + // + // -i path add include search path when parsing + // + } else if (_stricmp (Argv[0], "-i") == 0) { + // + // check for one more arg + // + if ((Argc <= 1) || (Argv[1][0] == '-')) { + Error (PROGRAM_NAME, 0, 0, Argv[0], "missing include path"); + return STATUS_ERROR; + } + // + // Allocate memory for a new list element, fill it in, and + // add it to our list of include paths. Always make sure it + // has a "\" on the end of it. + // + NewList = malloc (sizeof (TEXT_STRING_LIST)); + if (NewList == NULL) { + Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure"); + return STATUS_ERROR; + } + + memset ((char *) NewList, 0, sizeof (TEXT_STRING_LIST)); + NewList->Str = malloc (strlen (Argv[1]) + 2); + if (NewList->Str == NULL) { + free (NewList); + Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure"); + return STATUS_ERROR; + } + + strcpy (NewList->Str, Argv[1]); + if (NewList->Str[strlen (NewList->Str) - 1] != '\\') { + strcat (NewList->Str, "\\"); + } + // + // Add it to our linked list + // + if (mGlobals.IncludePaths == NULL) { + mGlobals.IncludePaths = NewList; + } else { + mGlobals.LastIncludePath->Next = NewList; + } + + mGlobals.LastIncludePath = NewList; + Argc--; + Argv++; + } else if (_stricmp (Argv[0], "-if") == 0) { + // + // Indirection file -- check for one more arg + // + if ((Argc <= 1) || (Argv[1][0] == '-')) { + Error (PROGRAM_NAME, 0, 0, Argv[0], "missing indirection file name"); + return STATUS_ERROR; + } + // + // Allocate memory for a new list element, fill it in, and + // add it to our list of include paths. Always make sure it + // has a "\" on the end of it. + // + NewList = malloc (sizeof (TEXT_STRING_LIST)); + if (NewList == NULL) { + Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure"); + return STATUS_ERROR; + } + + memset ((char *) NewList, 0, sizeof (TEXT_STRING_LIST)); + NewList->Str = malloc (strlen (Argv[1]) + 1); + if (NewList->Str == NULL) { + free (NewList); + Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure"); + return STATUS_ERROR; + } + + strcpy (NewList->Str, Argv[1]); + // + // Add it to our linked list + // + if (mGlobals.IndirectionFileName == NULL) { + mGlobals.IndirectionFileName = NewList; + } else { + mGlobals.LastIndirectionFileName->Next = NewList; + } + + mGlobals.LastIndirectionFileName = NewList; + Argc--; + Argv++; + } else if (_stricmp (Argv[0], "-db") == 0) { + // + // -db option to specify a database file. + // Check for one more arg (the database file name) + // + if ((Argc <= 1) || (Argv[1][0] == '-')) { + Error (PROGRAM_NAME, 0, 0, Argv[0], "missing database file name"); + return STATUS_ERROR; + } + + NewList = malloc (sizeof (TEXT_STRING_LIST)); + if (NewList == NULL) { + Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure"); + return STATUS_ERROR; + } + + memset ((char *) NewList, 0, sizeof (TEXT_STRING_LIST)); + NewList->Str = malloc (strlen (Argv[1]) + 1); + if (NewList->Str == NULL) { + free (NewList); + Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure"); + return STATUS_ERROR; + } + + strcpy (NewList->Str, Argv[1]); + // + // Add it to our linked list + // + if (mGlobals.DatabaseFileName == NULL) { + mGlobals.DatabaseFileName = NewList; + } else { + mGlobals.LastDatabaseFileName->Next = NewList; + } + + mGlobals.LastDatabaseFileName = NewList; + Argc--; + Argv++; + } else if (_stricmp (Argv[0], "-ou") == 0) { + // + // -ou option to specify an output unicode file to + // which we can dump our database. + // + if ((Argc <= 1) || (Argv[1][0] == '-')) { + Error (PROGRAM_NAME, 0, 0, Argv[0], "missing database dump output file name"); + return STATUS_ERROR; + } + + if (mGlobals.DumpUFileName[0] == 0) { + strcpy (mGlobals.DumpUFileName, Argv[1]); + } else { + Error (PROGRAM_NAME, 0, 0, Argv[1], "-ou option already specified with '%s'", mGlobals.DumpUFileName); + return STATUS_ERROR; + } + + Argc--; + Argv++; + } else if (_stricmp (Argv[0], "-hpk") == 0) { + // + // -hpk option to create an HII export pack of the input database file + // + if ((Argc <= 1) || (Argv[1][0] == '-')) { + Error (PROGRAM_NAME, 0, 0, Argv[0], "missing raw string data dump output file name"); + return STATUS_ERROR; + } + + if (mGlobals.HiiExportPackFileName[0] == 0) { + strcpy (mGlobals.HiiExportPackFileName, Argv[1]); + } else { + Error (PROGRAM_NAME, 0, 0, Argv[1], "-or option already specified with '%s'", mGlobals.HiiExportPackFileName); + return STATUS_ERROR; + } + + Argc--; + Argv++; + } else if ((_stricmp (Argv[0], "-?") == 0) || (_stricmp (Argv[0], "-h") == 0)) { + Usage (); + return STATUS_ERROR; + } else if (_stricmp (Argv[0], "-v") == 0) { + mGlobals.Verbose = 1; + } else if (_stricmp (Argv[0], "-vdbw") == 0) { + mGlobals.VerboseDatabaseWrite = 1; + } else if (_stricmp (Argv[0], "-vdbr") == 0) { + mGlobals.VerboseDatabaseRead = 1; + } else if (_stricmp (Argv[0], "-newdb") == 0) { + mGlobals.NewDatabase = 1; + } else if (_stricmp (Argv[0], "-ignorenotfound") == 0) { + mGlobals.IgnoreNotFound = 1; + } else if (_stricmp (Argv[0], "-oc") == 0) { + // + // check for one more arg + // + if ((Argc <= 1) || (Argv[1][0] == '-')) { + Error (PROGRAM_NAME, 0, 0, Argv[0], "missing output C filename"); + return STATUS_ERROR; + } + + strcpy (mGlobals.StringCFileName, Argv[1]); + Argc--; + Argv++; + } else if (_stricmp (Argv[0], "-bn") == 0) { + // + // check for one more arg + // + if ((Argc <= 1) || (Argv[1][0] == '-')) { + Error (PROGRAM_NAME, 0, 0, Argv[0], "missing base name"); + Usage (); + return STATUS_ERROR; + } + + strcpy (mGlobals.BaseName, Argv[1]); + Argc--; + Argv++; + } else if (_stricmp (Argv[0], "-oh") == 0) { + // + // -oh to specify output .h defines file name + // + if ((Argc <= 1) || (Argv[1][0] == '-')) { + Error (PROGRAM_NAME, 0, 0, Argv[0], "missing output .h filename"); + return STATUS_ERROR; + } + + strcpy (mGlobals.StringHFileName, Argv[1]); + Argc--; + Argv++; + } else if (_stricmp (Argv[0], "-dep") == 0) { + // + // -dep to specify output dependency file name + // + if ((Argc <= 1) || (Argv[1][0] == '-')) { + Error (PROGRAM_NAME, 0, 0, Argv[0], "missing output dependency filename"); + return STATUS_ERROR; + } + + strcpy (mGlobals.OutputDependencyFileName, Argv[1]); + Argc--; + Argv++; + } else if (_stricmp (Argv[0], "-skipext") == 0) { + // + // -skipext to skip scanning of files with certain filename extensions + // + if ((Argc <= 1) || (Argv[1][0] == '-')) { + Error (PROGRAM_NAME, 0, 0, Argv[0], "missing filename extension"); + return STATUS_ERROR; + } + // + // Allocate memory for a new list element, fill it in, and + // add it to our list of excluded extensions. Always make sure it + // has a "." as the first character. + // + NewList = malloc (sizeof (TEXT_STRING_LIST)); + if (NewList == NULL) { + Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure"); + return STATUS_ERROR; + } + + memset ((char *) NewList, 0, sizeof (TEXT_STRING_LIST)); + NewList->Str = malloc (strlen (Argv[1]) + 2); + if (NewList->Str == NULL) { + free (NewList); + Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure"); + return STATUS_ERROR; + } + + if (Argv[1][0] == '.') { + strcpy (NewList->Str, Argv[1]); + } else { + NewList->Str[0] = '.'; + strcpy (NewList->Str + 1, Argv[1]); + } + // + // Add it to our linked list + // + if (mGlobals.SkipExt == NULL) { + mGlobals.SkipExt = NewList; + } else { + mGlobals.LastSkipExt->Next = NewList; + } + + mGlobals.LastSkipExt = NewList; + Argc--; + Argv++; + } else if (_stricmp (Argv[0], "-lang") == 0) { + // + // "-lang eng" or "-lang spa+cat" to only output certain languages + // + if ((Argc <= 1) || (Argv[1][0] == '-')) { + Error (PROGRAM_NAME, 0, 0, Argv[0], "missing language name"); + Usage (); + return STATUS_ERROR; + } + + if (AddCommandLineLanguage (Argv[1]) != STATUS_SUCCESS) { + return STATUS_ERROR; + } + + Argc--; + Argv++; + } else if (_stricmp (Argv[0], "-od") == 0) { + // + // Output database file name -- check for another arg + // + if ((Argc <= 1) || (Argv[1][0] == '-')) { + Error (PROGRAM_NAME, 0, 0, Argv[0], "missing output database file name"); + return STATUS_ERROR; + } + + strcpy (mGlobals.OutputDatabaseFileName, Argv[1]); + Argv++; + Argc--; + } else { + // + // Unrecognized arg + // + Error (PROGRAM_NAME, 0, 0, Argv[0], "unrecognized option"); + Usage (); + return STATUS_ERROR; + } + + Argv++; + Argc--; + } + // + // Make sure they specified the mode parse/scan/dump + // + if (mGlobals.Mode == MODE_UNKNOWN) { + Error (NULL, 0, 0, "must specify one of -parse/-scan/-dump", NULL); + return STATUS_ERROR; + } + // + // All modes require a database filename + // + if (mGlobals.DatabaseFileName == 0) { + Error (NULL, 0, 0, "must specify a database filename using -db DbFileName", NULL); + Usage (); + return STATUS_ERROR; + } + // + // If dumping the database file, then return immediately if all + // parameters check out. + // + if (mGlobals.Mode == MODE_DUMP) { + // + // Not much use if they didn't specify -oh or -oc or -ou or -hpk + // + if ((mGlobals.DumpUFileName[0] == 0) && + (mGlobals.StringHFileName[0] == 0) && + (mGlobals.StringCFileName[0] == 0) && + (mGlobals.HiiExportPackFileName[0] == 0) + ) { + Error (NULL, 0, 0, "-dump without -oc/-oh/-ou/-hpk is a NOP", NULL); + return STATUS_ERROR; + } + + return STATUS_SUCCESS; + } + // + // Had to specify source string file and output string defines header filename. + // + if (mGlobals.Mode == MODE_SCAN) { + if (Argc < 1) { + Error (PROGRAM_NAME, 0, 0, NULL, "must specify at least one source file to scan with -scan"); + Usage (); + return STATUS_ERROR; + } + // + // Get the list of filenames + // + while (Argc > 0) { + NewList = malloc (sizeof (TEXT_STRING_LIST)); + if (NewList == NULL) { + Error (PROGRAM_NAME, 0, 0, "memory allocation failure", NULL); + return STATUS_ERROR; + } + + memset (NewList, 0, sizeof (TEXT_STRING_LIST)); + NewList->Str = (UINT8 *) malloc (strlen (Argv[0]) + 1); + if (NewList->Str == NULL) { + Error (PROGRAM_NAME, 0, 0, "memory allocation failure", NULL); + return STATUS_ERROR; + } + + strcpy (NewList->Str, Argv[0]); + if (mGlobals.ScanFileName == NULL) { + mGlobals.ScanFileName = NewList; + } else { + mGlobals.LastScanFileName->Next = NewList; + } + + mGlobals.LastScanFileName = NewList; + Argc--; + Argv++; + } + } else { + // + // Parse mode -- must specify an input unicode file name + // + if (Argc < 1) { + Error (PROGRAM_NAME, 0, 0, NULL, "must specify input unicode string file name with -parse"); + Usage (); + return STATUS_ERROR; + } + + strcpy (mGlobals.SourceFiles.FileName, Argv[0]); + } + + return STATUS_SUCCESS; +} +// +// Found "-lang eng,spa+cat" on the command line. Parse the +// language list and save the setting for later processing. +// +static +STATUS +AddCommandLineLanguage ( + IN INT8 *Language + ) +{ + WCHAR_STRING_LIST *WNewList; + WCHAR *From; + WCHAR *To; + // + // Keep processing the input string until we find the end. + // + while (*Language) { + // + // Allocate memory for a new list element, fill it in, and + // add it to our list. + // + WNewList = MALLOC (sizeof (WCHAR_STRING_LIST)); + if (WNewList == NULL) { + Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure"); + return STATUS_ERROR; + } + + memset ((char *) WNewList, 0, sizeof (WCHAR_STRING_LIST)); + WNewList->Str = malloc ((strlen (Language) + 1) * sizeof (WCHAR)); + if (WNewList->Str == NULL) { + free (WNewList); + Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure"); + return STATUS_ERROR; + } + // + // Copy it as unicode to our new structure. Then remove the + // plus signs in it, and verify each language name is 3 characters + // long. If we find a comma, then we're done with this group, so + // break out. + // +#ifdef USE_VC8 + swprintf (WNewList->Str, (strlen (Language) + 1) * sizeof (WCHAR), L"%S", Language); +#else + swprintf (WNewList->Str, L"%S", Language); +#endif + From = To = WNewList->Str; + while (*From) { + if (*From == L',') { + break; + } + + if ((wcslen (From) < LANGUAGE_IDENTIFIER_NAME_LEN) || + ( + (From[LANGUAGE_IDENTIFIER_NAME_LEN] != 0) && + (From[LANGUAGE_IDENTIFIER_NAME_LEN] != UNICODE_PLUS_SIGN) && + (From[LANGUAGE_IDENTIFIER_NAME_LEN] != L',') + ) + ) { + Error (PROGRAM_NAME, 0, 0, Language, "invalid format for language name on command line"); + FREE (WNewList->Str); + FREE (WNewList); + return STATUS_ERROR; + } + + wcsncpy (To, From, LANGUAGE_IDENTIFIER_NAME_LEN); + To += LANGUAGE_IDENTIFIER_NAME_LEN; + From += LANGUAGE_IDENTIFIER_NAME_LEN; + if (*From == L'+') { + From++; + } + } + + *To = 0; + // + // Add it to our linked list + // + if (mGlobals.Language == NULL) { + mGlobals.Language = WNewList; + } else { + mGlobals.LastLanguage->Next = WNewList; + } + + mGlobals.LastLanguage = WNewList; + // + // Skip to next entry (comma-separated list) + // + while (*Language) { + if (*Language == L',') { + Language++; + break; + } + + Language++; + } + } + + return STATUS_SUCCESS; +} +// +// The contents of the text file are expected to be (one per line) +// STRING_IDENTIFIER_NAME ScopeName +// For example: +// STR_ID_MY_FAVORITE_STRING IBM +// +static +STATUS +ParseIndirectionFiles ( + TEXT_STRING_LIST *Files + ) +{ + FILE *Fptr; + INT8 Line[200]; + INT8 *StringName; + INT8 *ScopeName; + INT8 *End; + UINT32 LineCount; + WCHAR_MATCHING_STRING_LIST *NewList; + + Line[sizeof (Line) - 1] = 0; + Fptr = NULL; + while (Files != NULL) { + Fptr = fopen (Files->Str, "r"); + LineCount = 0; + if (Fptr == NULL) { + Error (NULL, 0, 0, Files->Str, "failed to open input indirection file for reading"); + return STATUS_ERROR; + } + + while (fgets (Line, sizeof (Line), Fptr) != NULL) { + // + // remove terminating newline for error printing purposes. + // + if (Line[strlen (Line) - 1] == '\n') { + Line[strlen (Line) - 1] = 0; + } + + LineCount++; + if (Line[sizeof (Line) - 1] != 0) { + Error (Files->Str, LineCount, 0, "line length exceeds maximum supported", NULL); + goto Done; + } + + StringName = Line; + while (*StringName && (isspace (*StringName))) { + StringName++; + } + + if (*StringName) { + if ((*StringName == '_') || isalpha (*StringName)) { + End = StringName; + while ((*End) && (*End == '_') || (isalnum (*End))) { + End++; + } + + if (isspace (*End)) { + *End = 0; + End++; + while (isspace (*End)) { + End++; + } + + if (*End) { + ScopeName = End; + while (*End && !isspace (*End)) { + End++; + } + + *End = 0; + // + // Add the string name/scope pair + // + NewList = malloc (sizeof (WCHAR_MATCHING_STRING_LIST)); + if (NewList == NULL) { + Error (NULL, 0, 0, "memory allocation error", NULL); + goto Done; + } + + memset (NewList, 0, sizeof (WCHAR_MATCHING_STRING_LIST)); + NewList->Str1 = (WCHAR *) malloc ((strlen (StringName) + 1) * sizeof (WCHAR)); + NewList->Str2 = (WCHAR *) malloc ((strlen (ScopeName) + 1) * sizeof (WCHAR)); + if ((NewList->Str1 == NULL) || (NewList->Str2 == NULL)) { + Error (NULL, 0, 0, "memory allocation error", NULL); + goto Done; + } + +#ifdef USE_VC8 + swprintf (NewList->Str1, (strlen (StringName) + 1) * sizeof (WCHAR), L"%S", StringName); + swprintf (NewList->Str2, (strlen (ScopeName) + 1) * sizeof (WCHAR), L"%S", ScopeName); +#else + swprintf (NewList->Str1, L"%S", StringName); + swprintf (NewList->Str2, L"%S", ScopeName); +#endif + if (mGlobals.IndirectionList == NULL) { + mGlobals.IndirectionList = NewList; + } else { + mGlobals.LastIndirectionList->Next = NewList; + } + + mGlobals.LastIndirectionList = NewList; + } else { + Error (Files->Str, LineCount, 0, StringName, "invalid line : expected 'StringIdentifier Scope'"); + goto Done; + } + } else { + Error (Files->Str, LineCount, 0, StringName, "invalid line : expected 'StringIdentifier Scope'"); + goto Done; + } + } else { + Error (Files->Str, LineCount, 0, StringName, "invalid string identifier"); + goto Done; + } + } + } + + fclose (Fptr); + Fptr = NULL; + Files = Files->Next; + } + +Done: + if (Fptr != NULL) { + fclose (Fptr); + return STATUS_ERROR; + } + + return STATUS_SUCCESS; +} + +static +STATUS +ScanFiles ( + TEXT_STRING_LIST *ScanFiles + ) +{ + char Line[MAX_LINE_LEN]; + FILE *Fptr; + UINT32 LineNum; + char *Cptr; + char *SavePtr; + char *TermPtr; + char *StringTokenPos; + TEXT_STRING_LIST *SList; + BOOLEAN SkipIt; + + // + // Put a null-terminator at the end of the line. If we read in + // a line longer than we support, then we can catch it. + // + Line[MAX_LINE_LEN - 1] = 0; + // + // Process each file. If they gave us a skip extension list, then + // skip it if the extension matches. + // + while (ScanFiles != NULL) { + SkipIt = FALSE; + for (SList = mGlobals.SkipExt; SList != NULL; SList = SList->Next) { + if ((strlen (ScanFiles->Str) > strlen (SList->Str)) && + (strcmp (ScanFiles->Str + strlen (ScanFiles->Str) - strlen (SList->Str), SList->Str) == 0) + ) { + SkipIt = TRUE; + // + // printf ("Match: %s : %s\n", ScanFiles->Str, SList->Str); + // + break; + } + } + + if (!SkipIt) { + if (mGlobals.VerboseScan) { + printf ("Scanning %s\n", ScanFiles->Str); + } + + Fptr = fopen (ScanFiles->Str, "r"); + if (Fptr == NULL) { + Error (NULL, 0, 0, ScanFiles->Str, "failed to open input file for scanning"); + return STATUS_ERROR; + } + + LineNum = 0; + while (fgets (Line, sizeof (Line), Fptr) != NULL) { + LineNum++; + if (Line[MAX_LINE_LEN - 1] != 0) { + Error (ScanFiles->Str, LineNum, 0, "line length exceeds maximum supported by tool", NULL); + fclose (Fptr); + return STATUS_ERROR; + } + // + // Remove the newline from the input line so we can print a warning message + // + if (Line[strlen (Line) - 1] == '\n') { + Line[strlen (Line) - 1] = 0; + } + // + // Terminate the line at // comments + // + Cptr = strstr (Line, "//"); + if (Cptr != NULL) { + *Cptr = 0; + } + + Cptr = Line; + while ((Cptr = strstr (Cptr, STRING_TOKEN)) != NULL) { + // + // Found "STRING_TOKEN". Make sure we don't have NUM_STRING_TOKENS or + // something like that. Then make sure it's followed by + // an open parenthesis, a string identifier, and then a closing + // parenthesis. + // + if (mGlobals.VerboseScan) { + printf (" %d: %s", LineNum, Cptr); + } + + if (((Cptr == Line) || (!IsValidIdentifierChar (*(Cptr - 1), FALSE))) && + (!IsValidIdentifierChar (*(Cptr + sizeof (STRING_TOKEN) - 1), FALSE)) + ) { + StringTokenPos = Cptr; + SavePtr = Cptr; + Cptr += strlen (STRING_TOKEN); + while (*Cptr && isspace (*Cptr) && (*Cptr != '(')) { + Cptr++; + } + + if (*Cptr != '(') { + Warning (ScanFiles->Str, LineNum, 0, StringTokenPos, "expected "STRING_TOKEN "(identifier)"); + } else { + // + // Skip over the open-parenthesis and find the next non-blank character + // + Cptr++; + while (isspace (*Cptr)) { + Cptr++; + } + + SavePtr = Cptr; + if ((*Cptr == '_') || isalpha (*Cptr)) { + while ((*Cptr == '_') || (isalnum (*Cptr))) { + Cptr++; + } + + TermPtr = Cptr; + while (*Cptr && isspace (*Cptr)) { + Cptr++; + } + + if (*Cptr != ')') { + Warning (ScanFiles->Str, LineNum, 0, StringTokenPos, "expected "STRING_TOKEN "(identifier)"); + } + + if (*TermPtr) { + *TermPtr = 0; + Cptr = TermPtr + 1; + } else { + Cptr = TermPtr; + } + // + // Add the string identifier to the list of used strings + // + ParserSetPosition (ScanFiles->Str, LineNum); + StringDBSetStringReferenced (SavePtr, mGlobals.IgnoreNotFound); + if (mGlobals.VerboseScan) { + printf ("...referenced %s", SavePtr); + } + } else { + Warning (ScanFiles->Str, LineNum, 0, StringTokenPos, "expected valid string identifier name"); + } + } + } else { + // + // Found it, but it's a substring of something else. Advance our pointer. + // + Cptr++; + } + + if (mGlobals.VerboseScan) { + printf ("\n"); + } + } + } + + fclose (Fptr); + } else { + // + // Skipping this file type + // + if (mGlobals.VerboseScan) { + printf ("Skip scanning of %s\n", ScanFiles->Str); + } + } + + ScanFiles = ScanFiles->Next; + } + + return STATUS_SUCCESS; +} +// +// Free the global string lists we allocated memory for +// +static +void +FreeLists ( + VOID + ) +{ + TEXT_STRING_LIST *Temp; + WCHAR_STRING_LIST *WTemp; + + // + // Traverse the include paths, freeing each + // + while (mGlobals.IncludePaths != NULL) { + Temp = mGlobals.IncludePaths->Next; + free (mGlobals.IncludePaths->Str); + free (mGlobals.IncludePaths); + mGlobals.IncludePaths = Temp; + } + // + // If we did a scan, then free up our + // list of files to scan. + // + while (mGlobals.ScanFileName != NULL) { + Temp = mGlobals.ScanFileName->Next; + free (mGlobals.ScanFileName->Str); + free (mGlobals.ScanFileName); + mGlobals.ScanFileName = Temp; + } + // + // If they gave us a list of filename extensions to + // skip on scan, then free them up. + // + while (mGlobals.SkipExt != NULL) { + Temp = mGlobals.SkipExt->Next; + free (mGlobals.SkipExt->Str); + free (mGlobals.SkipExt); + mGlobals.SkipExt = Temp; + } + // + // Free up any languages specified + // + while (mGlobals.Language != NULL) { + WTemp = mGlobals.Language->Next; + free (mGlobals.Language->Str); + free (mGlobals.Language); + mGlobals.Language = WTemp; + } + // + // Free up our indirection list + // + while (mGlobals.IndirectionList != NULL) { + mGlobals.LastIndirectionList = mGlobals.IndirectionList->Next; + free (mGlobals.IndirectionList->Str1); + free (mGlobals.IndirectionList->Str2); + free (mGlobals.IndirectionList); + mGlobals.IndirectionList = mGlobals.LastIndirectionList; + } + + while (mGlobals.IndirectionFileName != NULL) { + mGlobals.LastIndirectionFileName = mGlobals.IndirectionFileName->Next; + free (mGlobals.IndirectionFileName->Str); + free (mGlobals.IndirectionFileName); + mGlobals.IndirectionFileName = mGlobals.LastIndirectionFileName; + } +} + +static +BOOLEAN +IsValidIdentifierChar ( + INT8 Char, + BOOLEAN FirstChar + ) +{ + // + // If it's the first character of an identifier, then + // it must be one of [A-Za-z_]. + // + if (FirstChar) { + if (isalpha (Char) || (Char == '_')) { + return TRUE; + } + } else { + // + // If it's not the first character, then it can + // be one of [A-Za-z_0-9] + // + if (isalnum (Char) || (Char == '_')) { + return TRUE; + } + } + + return FALSE; +} + +static +void +RewindFile ( + SOURCE_FILE *SourceFile + ) +{ + SourceFile->LineNum = 1; + SourceFile->FileBufferPtr = SourceFile->FileBuffer; + SourceFile->EndOfFile = FALSE; +} + +static +BOOLEAN +SkipTo ( + SOURCE_FILE *SourceFile, + WCHAR WChar, + BOOLEAN StopAfterNewline + ) +{ + while (!EndOfFile (SourceFile)) { + // + // Check for the character of interest + // + if (SourceFile->FileBufferPtr[0] == WChar) { + return TRUE; + } else { + if (SourceFile->FileBufferPtr[0] == UNICODE_LF) { + SourceFile->LineNum++; + if (StopAfterNewline) { + SourceFile->FileBufferPtr++; + if (SourceFile->FileBufferPtr[0] == 0) { + SourceFile->FileBufferPtr++; + } + + return FALSE; + } + } + + SourceFile->FileBufferPtr++; + } + } + + return FALSE; +} + +static +void +Usage ( + VOID + ) +/*++ + +Routine Description: + + Print usage information for this utility. + +Arguments: + + None. + +Returns: + + Nothing. + +--*/ +{ + int Index; + static const char *Str[] = { + "", + PROGRAM_NAME " version "TOOL_VERSION " -- process unicode strings file", + " Usage: "PROGRAM_NAME " -parse {parse options} [FileNames]", + " "PROGRAM_NAME " -scan {scan options} [FileName]", + " "PROGRAM_NAME " -dump {dump options}", + " Common options include:", + " -h or -? for this help information", + " -db Database required name of output/input database file", + " -bn BaseName for use in the .h and .c output files", + " Default = "DEFAULT_BASE_NAME, + " -v for verbose output", + " -vdbw for verbose output when writing database", + " -vdbr for verbose output when reading database", + " -od FileName to specify an output database file name", + " Parse options include:", + " -i IncludePath add IncludePath to list of search paths", + " -dep FileName to specify an output dependency file name", + " -newdb to not read in existing database file", + " -uqs to indicate that unquoted strings are used", + " FileNames name of one or more unicode files to parse", + " Scan options include:", + " -scan scan text file(s) for STRING_TOKEN() usage", + " -skipext .ext to skip scan of files with .ext filename extension", + " -ignorenotfound ignore if a given STRING_TOKEN(STR) is not ", + " found in the database", + " FileNames one or more files to scan", + " Dump options include:", + " -oc FileName write string data to FileName", + " -oh FileName write string defines to FileName", + " -ou FileName dump database to unicode file FileName", + " -lang Lang only dump for the language 'Lang'", + " -if FileName to specify an indirection file", + " -hpk FileName to create an HII export pack of the strings", + "", + " The expected process is to parse a unicode string file to create an initial", + " database of string identifier names and string definitions. Then text files", + " should be scanned for STRING_TOKEN() usages, and the referenced", + " strings will be tagged as used in the database. After all files have been", + " scanned, then the database should be dumped to create the necessary output", + " files.", + "", + NULL + }; + for (Index = 0; Str[Index] != NULL; Index++) { + fprintf (stdout, "%s\n", Str[Index]); + } +} diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/UefiStrGather/StrGather.h b/EdkCompatibilityPkg/Sample/Tools/Source/UefiStrGather/StrGather.h new file mode 100644 index 0000000000..a14ef923fc --- /dev/null +++ b/EdkCompatibilityPkg/Sample/Tools/Source/UefiStrGather/StrGather.h @@ -0,0 +1,87 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + StrGather.h + +Abstract: + + Common defines and prototypes for StrGather. + +--*/ + +#ifndef _STR_GATHER_H_ +#define _STR_GATHER_H_ + +#define MALLOC(size) malloc (size) +#define FREE(ptr) do { if ((ptr) != NULL) { free (ptr); } } while (0) + +#define PROGRAM_NAME "StrGather" + +typedef CHAR16 WCHAR; + +#define UNICODE_TO_ASCII(w) (INT8) ((w) & 0xFF) +#define ASCII_TO_UNICODE(a) (WCHAR) ((UINT8) (a)) + +#define UNICODE_HASH L'#' +#define UNICODE_BACKSLASH L'\\' +#define UNICODE_SLASH L'/' +#define UNICODE_EQUAL_SIGN L'=' +#define UNICODE_PLUS_SIGN L'+' + +#define UNICODE_FILE_START 0xFEFF +#define UNICODE_CR 0x000D +#define UNICODE_LF 0x000A +#define UNICODE_NULL 0x0000 +#define UNICODE_SPACE L' ' +#define UNICODE_SLASH L'/' +#define UNICODE_DOUBLE_QUOTE L'"' +#define UNICODE_OPEN_PAREN L'(' +#define UNICODE_CLOSE_PAREN L')' +#define UNICODE_Z L'Z' +#define UNICODE_z L'z' +#define UNICODE_A L'A' +#define UNICODE_a L'a' +#define UNICODE_F L'F' +#define UNICODE_f L'f' +#define UNICODE_UNDERSCORE L'_' +#define UNICODE_MINUS L'-' +#define UNICODE_0 L'0' +#define UNICODE_9 L'9' +#define UNICODE_TAB L'\t' +#define UNICODE_NBR_STRING L"\\nbr" +#define UNICODE_BR_STRING L"\\br" +#define UNICODE_WIDE_STRING L"\\wide" +#define UNICODE_NARROW_STRING L"\\narrow" + +// +// This is the length of a valid string identifier +// +#define LANGUAGE_IDENTIFIER_NAME_LEN 128 + +typedef struct _TEXT_STRING_LIST { + struct _TEXT_STRING_LIST *Next; + UINT8 *Str; +} TEXT_STRING_LIST; + +typedef struct _WCHAR_STRING_LIST { + struct _WCHAR_STRING_LIST *Next; + WCHAR *Str; +} WCHAR_STRING_LIST; + +typedef struct _WCHAR_MATCHING_STRING_LIST { + struct _WCHAR_MATCHING_STRING_LIST *Next; + WCHAR *Str1; + WCHAR *Str2; +} WCHAR_MATCHING_STRING_LIST; + +#endif // #ifndef _STR_GATHER_H_ diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/UefiStrGather/StringDB.c b/EdkCompatibilityPkg/Sample/Tools/Source/UefiStrGather/StringDB.c new file mode 100644 index 0000000000..ac6fef8577 --- /dev/null +++ b/EdkCompatibilityPkg/Sample/Tools/Source/UefiStrGather/StringDB.c @@ -0,0 +1,2674 @@ +/*++ + +Copyright (c) 2004 - 2007, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + StringDB.c + +Abstract: + + String database implementation + +--*/ + +#include +#include +#include +#include +#include +#include +#include +#include "StrGather.h" +#include "StringDb.h" + +static STRING_DB_DATA mDBData; + +static const char *mSourceFileHeader[] = { + "//", + "// DO NOT EDIT -- auto-generated file", + "//", + "// This file is generated by the string gather utility", + "//", + NULL +}; + +static +STRING_LIST * +StringDBFindString ( + WCHAR *LanguageName, + WCHAR *StringName, + WCHAR *Scope, + WCHAR_STRING_LIST *LanguagesOfInterest, + WCHAR_MATCHING_STRING_LIST *IndirectionList + ); + +static +STRING_IDENTIFIER * +StringDBFindStringIdentifierByName ( + WCHAR *Name + ); + +static +STRING_IDENTIFIER * +StringDBFindStringIdentifierByIndex ( + UINT32 Index + ); + +static +void +StringDBWriteStandardFileHeader ( + FILE *OutFptr + ); + +static +WCHAR * +AsciiToWchar ( + INT8 *Str + ); + +static +CHAR8 * +WcharToAscii ( + WCHAR *Str + ); + +static +WCHAR * +DuplicateString ( + WCHAR *Str + ); + +static +WCHAR * +WstrCatenate ( + WCHAR *Dst, + WCHAR *Src + ); + +static +STATUS +StringDBWriteStringIdentifier ( + FILE *DBFptr, + UINT16 StringId, + UINT16 Flags, + WCHAR *IdentifierName + ); + +static +STATUS +StringDBReadStringIdentifier ( + FILE *DBFptr + ); + +static +STATUS +StringDBWriteLanguageDefinition ( + FILE *DBFptr, + WCHAR *LanguageName, + WCHAR *PrintableLanguageName, + WCHAR *SecondaryLanguageList + ); + +static +STATUS +StringDBReadLanguageDefinition ( + FILE *DBFptr + ); + +static +STATUS +StringDBWriteString ( + FILE *DBFptr, + UINT16 Flags, + WCHAR *Language, + WCHAR *StringName, + WCHAR *Scope, + WCHAR *Str + ); + +static +STATUS +StringDBReadString ( + FILE *DBFptr + ); + +static +STATUS +StringDBReadGenericString ( + FILE *DBFptr, + UINT16 *Size, + WCHAR **Str + ); + +static +STATUS +StringDBWriteGenericString ( + FILE *DBFptr, + WCHAR *Str + ); + +static +void +StringDBAssignStringIndexes ( + VOID + ); + +/*****************************************************************************/ + +/*++ + +Routine Description: + Constructor function for the string database handler. + +Arguments: + None. + +Returns: + None. + +--*/ +void +StringDBConstructor ( + VOID + ) +{ + memset ((char *) &mDBData, 0, sizeof (STRING_DB_DATA)); + mDBData.CurrentScope = DuplicateString (L"NULL"); +} + +/*****************************************************************************/ + +/*++ + +Routine Description: + Destructor function for the string database handler. + +Arguments: + None. + +Returns: + None. + +--*/ +void +StringDBDestructor ( + VOID + ) +{ + LANGUAGE_LIST *NextLang; + STRING_LIST *NextStr; + STRING_IDENTIFIER *NextIdentifier; + // + // Close the database file if it's open + // + if (mDBData.StringDBFptr != NULL) { + fclose (mDBData.StringDBFptr); + mDBData.StringDBFptr = NULL; + } + // + // If we've allocated any strings/languages, free them up + // + while (mDBData.LanguageList != NULL) { + NextLang = mDBData.LanguageList->Next; + // + // Free up all strings for this language + // + while (mDBData.LanguageList->String != NULL) { + NextStr = mDBData.LanguageList->String->Next; + FREE (mDBData.LanguageList->String->Str); + FREE (mDBData.LanguageList->String); + mDBData.LanguageList->String = NextStr; + } + + FREE (mDBData.LanguageList->SecondaryLanguageList); + FREE (mDBData.LanguageList->PrintableLanguageName); + FREE (mDBData.LanguageList); + mDBData.LanguageList = NextLang; + } + // + // Free up string identifiers + // + while (mDBData.StringIdentifier != NULL) { + NextIdentifier = mDBData.StringIdentifier->Next; + FREE (mDBData.StringIdentifier->StringName); + FREE (mDBData.StringIdentifier); + mDBData.StringIdentifier = NextIdentifier; + } + // + // Free the filename + // + if (mDBData.StringDBFileName != NULL) { + FREE (mDBData.StringDBFileName); + mDBData.StringDBFileName = NULL; + } + // + // We save a copy of the scope, so free it up if we + // have one. + // + if (mDBData.CurrentScope != NULL) { + FREE (mDBData.CurrentScope); + mDBData.CurrentScope = NULL; + } +} + +/*****************************************************************************/ +STATUS +StringDBDumpStringDefines ( + INT8 *FileName, + INT8 *BaseName + ) +{ + FILE *Fptr; + STRING_IDENTIFIER *Identifier; + INT8 CopyBaseName[100]; + UINT32 Index; + const INT8 *StrDefHeader[] = { + "#ifndef _%s_STRINGS_DEFINE_H_\n", + "#define _%s_STRINGS_DEFINE_H_\n\n", + NULL + }; + + if ((Fptr = fopen (FileName, "w")) == NULL) { + Error (NULL, 0, 0, FileName, "failed to open output string defines file"); + return STATUS_ERROR; + } + // + // Get the base source filename and convert to uppercase. + // + if (sizeof (CopyBaseName) <= strlen (BaseName) + 1) { + Error (NULL, 0, 0, "application error", "StringDBDumpStringDefines() string length insufficient"); + return STATUS_ERROR; + } + + strcpy (CopyBaseName, BaseName); + for (Index = 0; CopyBaseName[Index] != 0; Index++) { + if (islower (CopyBaseName[Index])) { + CopyBaseName[Index] = (INT8) toupper (CopyBaseName[Index]); + } + } + // + // Assign index values to the string identifiers + // + StringDBAssignStringIndexes (); + // + // Write the standard header to the output file, and then the + // protective #ifndef. + // + StringDBWriteStandardFileHeader (Fptr); + for (Index = 0; StrDefHeader[Index] != NULL; Index++) { + fprintf (Fptr, StrDefHeader[Index], CopyBaseName); + } + // + // Print all the #defines for the string identifiers. Print identifiers + // whose names start with '$' as comments. Add comments for string + // identifiers not used as well. + // + Identifier = mDBData.StringIdentifier; + while (Identifier != NULL) { + if (Identifier->StringName[0] == L'$') { + fprintf (Fptr, "// "); + } + + if (Identifier->Flags & STRING_FLAGS_REFERENCED) { + fprintf (Fptr, "#define %-40S 0x%04X\n", Identifier->StringName, Identifier->Index); + } else { + fprintf (Fptr, "//#define %-40S 0x%04X // not referenced\n", Identifier->StringName, Identifier->Index); + } + + Identifier = Identifier->Next; + } + + fprintf (Fptr, "\n#endif\n"); + fclose (Fptr); + return STATUS_SUCCESS; +} + +/*****************************************************************************/ + +/*++ + +Routine Description: + + Add a string identifier to the database. + +Arguments: + + StringName - name of the string identifier. For example "STR_MY_STRING" + NewId - if an ID has been assigned + Flags - characteristics for the identifier + +Returns: + + STATUS + +--*/ +STATUS +StringDBAddStringIdentifier ( + WCHAR *StringName, + UINT16 *NewId, + UINT16 Flags + ) +{ + STRING_IDENTIFIER *StringIdentifier; + STATUS Status; + // + // If it was already used for some other language, then we don't + // need to add it. But set it to the current string identifier. + // The referenced bit is sticky. + // + Status = STATUS_SUCCESS; + StringIdentifier = StringDBFindStringIdentifierByName (StringName); + if (StringIdentifier != NULL) { + if (Flags & STRING_FLAGS_REFERENCED) { + StringIdentifier->Flags |= STRING_FLAGS_REFERENCED; + } + + mDBData.CurrentStringIdentifier = StringIdentifier; + *NewId = (UINT16) StringIdentifier->Index; + return Status; + } + + StringIdentifier = (STRING_IDENTIFIER *) MALLOC (sizeof (STRING_IDENTIFIER)); + if (StringIdentifier == NULL) { + Error (NULL, 0, 0, NULL, "memory allocation error"); + return STATUS_ERROR; + } + + memset ((char *) StringIdentifier, 0, sizeof (STRING_IDENTIFIER)); + StringIdentifier->StringName = (WCHAR *) malloc ((wcslen (StringName) + 1) * sizeof (WCHAR)); + if (StringIdentifier->StringName == NULL) { + Error (NULL, 0, 0, NULL, "memory allocation error"); + return STATUS_ERROR; + } + + wcscpy (StringIdentifier->StringName, StringName); + if (*NewId != STRING_ID_INVALID) { + StringIdentifier->Index = *NewId; + StringIdentifier->Flags |= STRING_FLAGS_INDEX_ASSIGNED; + if (mDBData.NumStringIdentifiers <= StringIdentifier->Index) { + mDBData.NumStringIdentifiers = StringIdentifier->Index + 1; + } + } else { + StringIdentifier->Index = mDBData.NumStringIdentifiers++; + } + + StringIdentifier->Flags |= Flags; + // + // Add it to our list of string identifiers + // + if (mDBData.StringIdentifier == NULL) { + mDBData.StringIdentifier = StringIdentifier; + } else { + mDBData.LastStringIdentifier->Next = StringIdentifier; + } + + mDBData.LastStringIdentifier = StringIdentifier; + mDBData.CurrentStringIdentifier = StringIdentifier; + *NewId = (UINT16) StringIdentifier->Index; + return Status; +} + +/*****************************************************************************/ + +/*++ + +Routine Description: + + Add a new string to the database. + +Arguments: + + LanguageName - "eng" or "spa" language name + StringName - "STR_MY_TEXT" string name + Scope - from the #scope statements in the string file + Format - if we should format the string + Flags - characteristic flags for the string + +Returns: + + STATUS + +Notes: + + Several of the fields can be "inherited" from the previous calls to + our database functions. For example, if scope is NULL here, then + we'll use the previous setting. + +--*/ +STATUS +StringDBAddString ( + WCHAR *LanguageName, + WCHAR *StringName, + WCHAR *Scope, + WCHAR *String, + BOOLEAN Format, + UINT16 Flags + ) +{ + LANGUAGE_LIST *Lang; + UINT32 Size; + STRING_LIST *Str; + UINT16 StringIndex; + STRING_IDENTIFIER *StringIdentifier; + + // + // If they specified a language, make sure they've defined it already + // via a #langdef statement. Otherwise use the current default language. + // + if (LanguageName != NULL) { + Lang = StringDBFindLanguageList (LanguageName); + if (Lang == NULL) { + ParserError (0, "language not defined", "%S", LanguageName); + return STATUS_ERROR; + } else { + StringDBSetCurrentLanguage (LanguageName); + } + } else { + Lang = mDBData.CurrentLanguage; + if (Lang == NULL) { + // + // Have to call SetLanguage() first + // + ParserError (0, "no language defined", "%S", StringName); + return STATUS_ERROR; + } + } + // + // If they didn't define a string identifier, use the last string identifier + // added. + // + if (StringName == NULL) { + StringName = mDBData.CurrentStringIdentifier->StringName; + if (StringName == NULL) { + ParserError (0, "no string identifier previously specified", NULL); + return STATUS_ERROR; + } + } + // + // If scope was not specified, use the default setting + // + if (Scope != NULL) { + Scope = DuplicateString (Scope); + } else { + Scope = DuplicateString (mDBData.CurrentScope); + } + // + // printf ("Adding string: %S.%S.%S\n", Lang->LanguageName, StringName, Scope); + // + // Check for duplicates for this Language.StringName.Scope. Allow multiple + // definitions of the language name and printable language name, since the + // user does not specifically define them. + // + if (StringDBFindString (Lang->LanguageName, StringName, Scope, NULL, NULL) != NULL) { + if ((wcscmp (StringName, LANGUAGE_NAME_STRING_NAME) == 0) && + (wcscmp (StringName, PRINTABLE_LANGUAGE_NAME_STRING_NAME) == 0) + ) { + ParserError ( + 0, + "string multiply defined", + "Language.Name.Scope = %S.%S.%S", + Lang->LanguageName, + StringName, + Scope + ); + return STATUS_ERROR; + } + } + + StringIndex = STRING_ID_INVALID; + if (StringDBAddStringIdentifier (StringName, &StringIndex, Flags) != STATUS_SUCCESS) { + return STATUS_ERROR; + } + + StringIdentifier = StringDBFindStringIdentifierByName (StringName); + // + // Add this string to the end of the strings for this language. + // + Str = (STRING_LIST *) malloc (sizeof (STRING_LIST)); + if (Str == NULL) { + Error (NULL, 0, 0, NULL, "memory allocation error"); + return STATUS_ERROR; + } + + memset ((char *) Str, 0, sizeof (STRING_LIST)); + Size = (wcslen (String) + 1) * sizeof (WCHAR); + Str->Flags = Flags; + Str->Scope = Scope; + Str->StringName = StringIdentifier->StringName; + Str->LanguageName = DuplicateString (LanguageName); + Str->Str = (WCHAR *) MALLOC (Size); + if (Str->Str == NULL) { + Error (NULL, 0, 0, NULL, "memory allocation error"); + return STATUS_ERROR; + } + // + // If not formatting, just copy the string. + // + wcscpy (Str->Str, String); + if (Format) { + StringDBFormatString (Str->Str); + } + // + // Size may change after formatting. We set the size to + // the actual size of the string, including the null for + // easier processing later. + // + Str->Size = (wcslen (Str->Str) + 1) * sizeof (WCHAR); + if (Lang->String == NULL) { + Lang->String = Str; + } else { + Lang->LastString->Next = Str; + } + + Lang->LastString = Str; + return STATUS_SUCCESS; +} + +/*****************************************************************************/ + +/*++ + +Routine Description: + + Given a language name, see if a language list for it has been defined + +Arguments: + + LanguageName - like "eng" + +Returns: + + A pointer to the language list + +--*/ +LANGUAGE_LIST * +StringDBFindLanguageList ( + WCHAR *LanguageName + ) +{ + LANGUAGE_LIST *Lang; + + Lang = mDBData.LanguageList; + while (Lang != NULL) { + if (wcscmp (LanguageName, Lang->LanguageName) == 0) { + break; + } + + Lang = Lang->Next; + } + + return Lang; +} + +/*****************************************************************************/ +STATUS +StringDBSetCurrentLanguage ( + WCHAR *LanguageName + ) +{ + LANGUAGE_LIST *Lang; + + Lang = StringDBFindLanguageList (LanguageName); + if (Lang == NULL) { + ParserError (0, "language not previously defined", "%S", LanguageName); + return STATUS_ERROR; + } + + mDBData.CurrentLanguage = Lang; + return STATUS_SUCCESS; +} + +/*****************************************************************************/ +STATUS +StringDBAddLanguage ( + WCHAR *LanguageName, + WCHAR *PrintableLanguageName, + WCHAR *SecondaryLanguageList + ) +{ + LANGUAGE_LIST *Lang; + // + // Check for redefinitions + // + Lang = StringDBFindLanguageList (LanguageName); + if (Lang != NULL) { + // + // Better be the same printable name + // + if (wcscmp (PrintableLanguageName, Lang->PrintableLanguageName) != 0) { + ParserError ( + 0, + "language redefinition", + "%S:%S != %S:%S", + Lang->LanguageName, + Lang->PrintableLanguageName, + LanguageName, + PrintableLanguageName + ); + return STATUS_ERROR; + // + // } else { + // ParserWarning (0, "benign language redefinition", "%S", PrintableLanguageName); + // return STATUS_WARNING; + // + } + } else { + // + // Allocate memory to keep track of this new language + // + Lang = (LANGUAGE_LIST *) malloc (sizeof (LANGUAGE_LIST)); + if (Lang == NULL) { + Error (NULL, 0, 0, NULL, "memory allocation error"); + return STATUS_ERROR; + } + + memset ((char *) Lang, 0, sizeof (LANGUAGE_LIST)); + // + // Save the language name, then allocate memory to save the + // printable language name + // + Lang->LanguageName = (WCHAR *) malloc ((wcslen (LanguageName) + 1) * 2); + if (Lang->LanguageName == NULL) { + Error (NULL, 0, 0, NULL, "memory allocation error"); + return STATUS_ERROR; + } + wcscpy (Lang->LanguageName, LanguageName); + Lang->PrintableLanguageName = (WCHAR *) malloc ((wcslen (PrintableLanguageName) + 1) * sizeof (WCHAR)); + if (Lang->PrintableLanguageName == NULL) { + Error (NULL, 0, 0, NULL, "memory allocation error"); + FREE (Lang->LanguageName); + return STATUS_ERROR; + } + wcscpy (Lang->PrintableLanguageName, PrintableLanguageName); + + if (SecondaryLanguageList != NULL) { + Lang->SecondaryLanguageList = (WCHAR *) malloc ((wcslen (SecondaryLanguageList) + 1) * sizeof (WCHAR)); + if (Lang->SecondaryLanguageList == NULL) { + Error (NULL, 0, 0, NULL, "memory allocation error"); + FREE (Lang->PrintableLanguageName); + FREE (Lang->LanguageName); + return STATUS_ERROR; + } + wcscpy (Lang->SecondaryLanguageList, SecondaryLanguageList); + } else { + Lang->SecondaryLanguageList = NULL; + } + + if (mDBData.LanguageList == NULL) { + mDBData.LanguageList = Lang; + } else { + mDBData.LastLanguageList->Next = Lang; + } + + mDBData.LastLanguageList = Lang; + } + // + // Default is to make our active language this new one + // + StringDBSetCurrentLanguage (LanguageName); + // + // The first two strings for any language are the language name, + // followed by the printable language name. Add them and set them + // to referenced so they never get stripped out. + // + StringDBAddString ( + LanguageName, + LANGUAGE_NAME_STRING_NAME, + NULL, + LanguageName, + FALSE, + STRING_FLAGS_REFERENCED + ); + StringDBAddString ( + LanguageName, + PRINTABLE_LANGUAGE_NAME_STRING_NAME, + NULL, + PrintableLanguageName, + FALSE, + STRING_FLAGS_REFERENCED + ); + return STATUS_SUCCESS; +} + +STATUS +StringDBAddSecondaryLanguage ( + WCHAR *LanguageName, + WCHAR *SecondaryLanguageList + ) +{ + LANGUAGE_LIST *Lang; + + Lang = StringDBFindLanguageList (LanguageName); + if (Lang == NULL) { + return STATUS_ERROR; + } else { + Lang->SecondaryLanguageList = WstrCatenate(Lang->SecondaryLanguageList, SecondaryLanguageList); + return STATUS_SUCCESS; + } +} + +/*****************************************************************************/ +static +STRING_IDENTIFIER * +StringDBFindStringIdentifierByName ( + WCHAR *StringName + ) +{ + STRING_IDENTIFIER *Identifier; + + Identifier = mDBData.StringIdentifier; + while (Identifier != NULL) { + if (wcscmp (StringName, Identifier->StringName) == 0) { + return Identifier; + } + + Identifier = Identifier->Next; + } + + return NULL; +} + +static +STRING_IDENTIFIER * +StringDBFindStringIdentifierByIndex ( + UINT32 StringIndex + ) +{ + STRING_IDENTIFIER *Identifier; + + Identifier = mDBData.StringIdentifier; + while (Identifier != NULL) { + if (Identifier->Index == StringIndex) { + return Identifier; + } + + Identifier = Identifier->Next; + } + + return NULL; +} + +/*****************************************************************************/ +static +void +StringDBWriteStandardFileHeader ( + FILE *OutFptr + ) +{ + UINT32 TempIndex; + for (TempIndex = 0; mSourceFileHeader[TempIndex] != NULL; TempIndex++) { + fprintf (OutFptr, "%s\n", mSourceFileHeader[TempIndex]); + } +} + +/*****************************************************************************/ + +/*++ + +Routine Description: + + Given a Unicode string from an input file, reformat the string to replace + backslash control sequences with the appropriate encoding. + +Arguments: + + String - pointer to string to reformat + +Returns: + + Nothing + +--*/ +void +StringDBFormatString ( + WCHAR *String + ) +{ + WCHAR *From; + WCHAR *To; + int HexNibbles; + WCHAR HexValue; + // + // Go through the string and process any formatting characters + // + From = String; + To = String; + while (*From) { + if (*From == UNICODE_BACKSLASH) { + // + // First look for \wide and replace with the appropriate control character. Note that + // when you have "define STR L"ABC"", then sizeof(ABC) is 8 because the null char is + // counted. Make adjustments for this. We advance From below, so subtract 2 each time. + // + if (wcsncmp (From, UNICODE_WIDE_STRING, sizeof (UNICODE_WIDE_STRING) / sizeof (WCHAR) - 1) == 0) { + *To = WIDE_CHAR; + From += sizeof (UNICODE_WIDE_STRING) / sizeof (WCHAR) - 2; + } else if (wcsncmp (From, UNICODE_NARROW_STRING, sizeof (UNICODE_NARROW_STRING) / sizeof (WCHAR) - 1) == 0) { + // + // Found: \narrow + // + *To = NARROW_CHAR; + From += sizeof (UNICODE_NARROW_STRING) / sizeof (WCHAR) - 2; + } else if (wcsncmp (From, UNICODE_NBR_STRING, sizeof (UNICODE_NBR_STRING) / sizeof (WCHAR) - 1) == 0) { + // + // Found: \nbr + // + *To = NON_BREAKING_CHAR; + From += sizeof (UNICODE_NBR_STRING) / sizeof (WCHAR) - 2; + } else if (wcsncmp (From, UNICODE_BR_STRING, sizeof (UNICODE_BR_STRING) / sizeof (WCHAR) - 1) == 0) { + // + // Found: \br -- pass through untouched + // + *To = *From; + } else { + // + // Standard one-character control sequences such as \n, \r, \\, or \x + // + From++; + switch (*From) { + case ASCII_TO_UNICODE ('n'): + *To = UNICODE_CR; + To++; + *To = UNICODE_LF; + break; + + // + // carriage return + // + case ASCII_TO_UNICODE ('r'): + *To = UNICODE_CR; + break; + + // + // backslash + // + case UNICODE_BACKSLASH: + *To = UNICODE_BACKSLASH; + break; + + // + // Tab + // + case ASCII_TO_UNICODE ('t'): + *To = UNICODE_TAB; + break; + + // + // embedded double-quote + // + case UNICODE_DOUBLE_QUOTE: + *To = UNICODE_DOUBLE_QUOTE; + break; + + // + // Hex Unicode character \x1234. We'll process up to 4 hex characters + // + case ASCII_TO_UNICODE ('x'): + HexValue = 0; + for (HexNibbles = 0; HexNibbles < 4; HexNibbles++) { + if ((From[1] >= UNICODE_0) && (From[1] <= UNICODE_9)) { + HexValue = (HexValue << 4) | (From[1] - UNICODE_0); + } else if ((From[1] >= UNICODE_a) && (From[1] <= UNICODE_f)) { + HexValue = (HexValue << 4) | (10 + From[1] - UNICODE_a); + } else if ((From[1] >= UNICODE_A) && (From[1] <= UNICODE_F)) { + HexValue = (HexValue << 4) | (10 + From[1] - UNICODE_A); + } else { + break; + } + + From++; + } + + if (HexNibbles == 0) { + ParserWarning ( + 0, + "expected at least one valid hex digit with \\x escaped character in string", + "\\%C", + *From + ); + } else { + *To = HexValue; + } + break; + + default: + *To = UNICODE_SPACE; + ParserWarning (0, "invalid escaped character in string", "\\%C", *From); + break; + } + } + } else { + *To = *From; + } + + From++; + To++; + } + + *To = 0; +} + +/*****************************************************************************/ +STATUS +StringDBReadDatabase ( + INT8 *DBFileName, + BOOLEAN IgnoreIfNotExist, + BOOLEAN Verbose + ) +{ + STRING_DB_HEADER DbHeader; + STATUS Status; + FILE *DBFptr; + DB_DATA_ITEM_HEADER DataItemHeader; + + Status = STATUS_SUCCESS; + DBFptr = NULL; + // + // if (Verbose) { + // fprintf (stdout, "Reading database file %s\n", DBFileName); + // } + // + // Try to open the input file + // + if ((DBFptr = fopen (DBFileName, "rb")) == NULL) { + if (IgnoreIfNotExist) { + return STATUS_SUCCESS; + } + + Error (NULL, 0, 0, DBFileName, "failed to open input database file for reading"); + return STATUS_ERROR; + } + // + // Read and verify the database header + // + if (fread ((void *) &DbHeader, sizeof (STRING_DB_HEADER), 1, DBFptr) != 1) { + Error (NULL, 0, 0, DBFileName, "failed to read header from database file"); + Status = STATUS_ERROR; + goto Finish; + } + + if (DbHeader.Key != STRING_DB_KEY) { + Error (NULL, 0, 0, DBFileName, "invalid header in database file"); + Status = STATUS_ERROR; + goto Finish; + } + + if ((DbHeader.Version & STRING_DB_MAJOR_VERSION_MASK) != (STRING_DB_VERSION & STRING_DB_MAJOR_VERSION_MASK)) { + Error (NULL, 0, 0, DBFileName, "incompatible database file version -- rebuild clean"); + Status = STATUS_ERROR; + goto Finish; + } + // + // Read remaining items + // + while (fread (&DataItemHeader, sizeof (DataItemHeader), 1, DBFptr) == 1) { + switch (DataItemHeader.DataType) { + case DB_DATA_TYPE_STRING_IDENTIFIER: + StringDBReadStringIdentifier (DBFptr); + break; + + case DB_DATA_TYPE_LANGUAGE_DEFINITION: + StringDBReadLanguageDefinition (DBFptr); + break; + + case DB_DATA_TYPE_STRING_DEFINITION: + StringDBReadString (DBFptr); + break; + + default: + Error ( + NULL, + 0, + 0, + "database corrupted", + "invalid data item type 0x%X at offset 0x%X", + (UINT32) DataItemHeader.DataType, + ftell (DBFptr) - sizeof (DataItemHeader) + ); + Status = STATUS_ERROR; + goto Finish; + } + } + +Finish: + if (DBFptr != NULL) { + fclose (DBFptr); + } + + return Status; +} + +/*****************************************************************************/ + +/*++ + +Routine Description: + + Write everything we know to the output database file. Write: + + Database header + String identifiers[] + StringPacks[] + +Arguments: + + DBFileName - name of the file to write to + Verbose - for debug purposes, print info messages along the way. + +Returns: + + STATUS + +--*/ +STATUS +StringDBWriteDatabase ( + INT8 *DBFileName, + BOOLEAN Verbose + ) +{ + STRING_DB_HEADER DbHeader; + UINT32 Counter; + UINT32 StrLen; + LANGUAGE_LIST *Lang; + STRING_IDENTIFIER *StringIdentifier; + STRING_LIST *StrList; + FILE *DBFptr; + + if (Verbose) { + fprintf (stdout, "Writing database %s\n", DBFileName); + } + + if ((DBFptr = fopen (DBFileName, "wb")) == NULL) { + Error (NULL, 0, 0, DBFileName, "failed to open output database file for writing"); + return STATUS_ERROR; + } + // + // Fill in and write the database header + // + memset (&DbHeader, 0, sizeof (STRING_DB_HEADER)); + DbHeader.HeaderSize = sizeof (STRING_DB_HEADER); + DbHeader.Key = STRING_DB_KEY; + DbHeader.Version = STRING_DB_VERSION; + // + // Count the number of languages we have + // + for (Lang = mDBData.LanguageList; Lang != NULL; Lang = Lang->Next) { + DbHeader.NumLanguages++; + } + // + // Count up how many string identifiers we have, and total up the + // size of the names plus the size of the flags field we will + // write out too. + // + DbHeader.NumStringIdenfiers = mDBData.NumStringIdentifiers; + StringIdentifier = mDBData.StringIdentifier; + for (Counter = 0; Counter < mDBData.NumStringIdentifiers; Counter++) { + StrLen = wcslen (StringIdentifier->StringName) + 1; + DbHeader.StringIdentifiersSize += StrLen * sizeof (WCHAR) + sizeof (StringIdentifier->Flags); + StringIdentifier = StringIdentifier->Next; + } + + // + // Write the header + // + fwrite (&DbHeader, sizeof (STRING_DB_HEADER), 1, DBFptr); + if (Verbose) { + fprintf (stdout, " Number of string identifiers 0x%04X\n", DbHeader.NumStringIdenfiers); + fprintf (stdout, " Number of languages %d\n", DbHeader.NumLanguages); + } + // + // Write the string identifiers + // + for (StringIdentifier = mDBData.StringIdentifier; StringIdentifier != NULL; StringIdentifier = StringIdentifier->Next) { + StringDBWriteStringIdentifier ( + DBFptr, + (UINT16) StringIdentifier->Index, + StringIdentifier->Flags, + StringIdentifier->StringName + ); + } + // + // Now write all the strings for each language + // + for (Lang = mDBData.LanguageList; Lang != NULL; Lang = Lang->Next) { + StringDBWriteLanguageDefinition (DBFptr, Lang->LanguageName, Lang->PrintableLanguageName, Lang->SecondaryLanguageList); + for (StrList = Lang->String; StrList != NULL; StrList = StrList->Next) { + StringDBWriteString ( + DBFptr, + StrList->Flags, + Lang->LanguageName, + StrList->StringName, + StrList->Scope, + StrList->Str + ); + } + } + + fclose (DBFptr); + return STATUS_SUCCESS; +} + +STATUS +StringDBSetStringReferenced ( + INT8 *StringIdentifierName, + BOOLEAN IgnoreNotFound + ) +{ + STRING_IDENTIFIER *Id; + WCHAR *WName; + STATUS Status; + // + // See if it's already been defined. + // + Status = STATUS_SUCCESS; + WName = (WCHAR *) malloc ((strlen (StringIdentifierName) + 1) * sizeof (WCHAR)); +#ifdef USE_VC8 + swprintf (WName, (strlen (StringIdentifierName) + 1) * sizeof (WCHAR), L"%S", StringIdentifierName); +#else + swprintf (WName, L"%S", StringIdentifierName); +#endif + Id = StringDBFindStringIdentifierByName (WName); + if (Id != NULL) { + Id->Flags |= STRING_FLAGS_REFERENCED; + } else { + if (IgnoreNotFound == 0) { + ParserWarning (0, StringIdentifierName, "string identifier not found in database"); + Status = STATUS_WARNING; + } + } + + free (WName); + return Status; +} + +/*****************************************************************************/ + +/*++ + +Routine Description: + + Dump the contents of a database to an output unicode file. + +Arguments: + + DBFileName - name of the pre-existing database file to read + OutputFileName - name of the file to dump the database contents to + Verbose - for printing of additional info useful for debugging + +Returns: + + STATUS + +Notes: + + There's some issue with the unicode printing routines. Therefore to + write to the output file properly, open it as binary and use fwrite. + Ideally we could open it with just L"w" and use fwprintf(). + +--*/ +STATUS +StringDBDumpDatabase ( + INT8 *DBFileName, + INT8 *OutputFileName, + BOOLEAN Verbose + ) +{ + LANGUAGE_LIST *Lang; + STRING_IDENTIFIER *StringIdentifier; + STRING_LIST *StrList; + FILE *OutFptr; + WCHAR WChar; + WCHAR *WOutputFileName; + WCHAR CrLf[2]; + WCHAR Line[200]; + WCHAR *Scope; + // + // This function assumes the database has already been read, and + // we're just dumping our internal data structures to a unicode file. + // + if (Verbose) { + fprintf (stdout, "Dumping database file %s\n", DBFileName); + } + + WOutputFileName = AsciiToWchar (OutputFileName); + OutFptr = _wfopen (WOutputFileName, L"wb"); + free (WOutputFileName); + if (OutFptr == NULL) { + Error (NULL, 0, 0, OutputFileName, "failed to open output file for writing"); + return STATUS_ERROR; + } + + WChar = UNICODE_FILE_START; + fwrite (&WChar, sizeof (WCHAR), 1, OutFptr); + CrLf[1] = UNICODE_LF; + CrLf[0] = UNICODE_CR; + // + // The default control character is '/'. Make it '#' by writing + // "/=#" to the output file. + // +#ifdef USE_VC8 + swprintf (Line, wcslen(Line) * sizeof (WCHAR), L"/=#"); +#else + swprintf (Line, L"/=#"); +#endif + fwrite (Line, wcslen (Line) * sizeof (WCHAR), 1, OutFptr); + fwrite (&CrLf, sizeof (CrLf), 1, OutFptr); + fwrite (&CrLf, sizeof (CrLf), 1, OutFptr); + // + // Dump all the string identifiers and their values + // + StringDBAssignStringIndexes (); + for (StringIdentifier = mDBData.StringIdentifier; StringIdentifier != NULL; StringIdentifier = StringIdentifier->Next) { + // + // Write the "#define " string + // + if (StringIdentifier->Flags & STRING_FLAGS_REFERENCED) { +#ifdef USE_VC8 + swprintf ( + Line, + wcslen(Line) * sizeof (WCHAR), + L"%s %-60.60s 0x%04X", + DEFINE_STR, + StringIdentifier->StringName, + StringIdentifier->Index + ); +#else + swprintf ( + Line, + L"%s %-60.60s 0x%04X", + DEFINE_STR, + StringIdentifier->StringName, + StringIdentifier->Index + ); +#endif + } else { +#ifdef USE_VC8 + swprintf ( + Line, + wcslen(Line) * sizeof (WCHAR), + L"%s %-60.60s 0x%04X // NOT REFERENCED", + DEFINE_STR, + StringIdentifier->StringName, + StringIdentifier->Index + ); +#else + swprintf ( + Line, + L"%s %-60.60s 0x%04X // NOT REFERENCED", + DEFINE_STR, + StringIdentifier->StringName, + StringIdentifier->Index + ); +#endif + } + + fwrite (Line, wcslen (Line) * sizeof (WCHAR), 1, OutFptr); + fwrite (&CrLf, sizeof (CrLf), 1, OutFptr); + } + + fwrite (&CrLf, sizeof (CrLf), 1, OutFptr); + // + // Now write all the strings for each language. + // + WChar = UNICODE_DOUBLE_QUOTE; + Scope = NULL; + for (Lang = mDBData.LanguageList; Lang != NULL; Lang = Lang->Next) { + fwrite (&CrLf, sizeof (CrLf), 1, OutFptr); +#ifdef USE_VC8 + swprintf (Line, wcslen(Line) * sizeof (WCHAR), L"#langdef %s \"%s\"", Lang->LanguageName, Lang->PrintableLanguageName); +#else + swprintf (Line, L"#langdef %s \"%s\"", Lang->LanguageName, Lang->PrintableLanguageName); +#endif + fwrite (Line, wcslen (Line) * sizeof (WCHAR), 1, OutFptr); + fwrite (&CrLf, sizeof (CrLf), 1, OutFptr); + fwrite (&CrLf, sizeof (CrLf), 1, OutFptr); + // + // Now the strings (in double-quotes) for this language. Write + // #string STR_NAME #language eng "string" + // + for (StrList = Lang->String; StrList != NULL; StrList = StrList->Next) { + // + // Print the internal flags for debug + // +#ifdef USE_VC8 + swprintf (Line, wcslen(Line) * sizeof (WCHAR), L"// flags=0x%02X", (UINT32) StrList->Flags); +#else + swprintf (Line, L"// flags=0x%02X", (UINT32) StrList->Flags); +#endif + fwrite (Line, wcslen (Line) * sizeof (WCHAR), 1, OutFptr); + fwrite (&CrLf, sizeof (CrLf), 1, OutFptr); + // + // Print the scope if changed + // + if ((Scope == NULL) || (wcscmp (Scope, StrList->Scope) != 0)) { +#ifdef USE_VC8 + swprintf (Line, wcslen(Line) * sizeof (WCHAR), L"#scope %s", StrList->Scope); +#else + swprintf (Line, L"#scope %s", StrList->Scope); +#endif + fwrite (Line, wcslen (Line) * sizeof (WCHAR), 1, OutFptr); + fwrite (&CrLf, sizeof (CrLf), 1, OutFptr); + Scope = StrList->Scope; + } + +#ifdef USE_VC8 + swprintf ( + Line, + wcslen(Line) * sizeof (WCHAR), + L"#string %-50.50s #language %s \"", + StrList->StringName, + Lang->LanguageName + ); +#else + swprintf ( + Line, + L"#string %-50.50s #language %s \"", + StrList->StringName, + Lang->LanguageName + ); +#endif + fwrite (Line, wcslen (Line) * sizeof (WCHAR), 1, OutFptr); + fwrite (StrList->Str, StrList->Size - sizeof (WCHAR), 1, OutFptr); +#ifdef USE_VC8 + swprintf (Line, wcslen(Line) * sizeof (WCHAR), L"\""); +#else + swprintf (Line, L"\""); +#endif + fwrite (Line, wcslen (Line) * sizeof (WCHAR), 1, OutFptr); + fwrite (&CrLf, sizeof (CrLf), 1, OutFptr); + } + } + + fclose (OutFptr); + return STATUS_SUCCESS; +} + +/*****************************************************************************/ + +/*++ + +Routine Description: + + Given a primary language, a string identifier number, and a list of + languages, find a secondary string. + +Arguments: + + LanguageName - primary language, like "spa" + StringId - string index value + LanguageList - linked list of "eng", "spa+cat",... + +Returns: + + Pointer to a secondary string if found. NULL otherwise. + +Notes: + + Given: LanguageName "spa" and LanguageList "spa+cat", match the + "spa" and extract the "cat" and see if there is a string defined + for "cat".StringId. + +--*/ +static +STATUS +StringDBWriteStringIdentifier ( + FILE *DBFptr, + UINT16 StringId, + UINT16 Flags, + WCHAR *IdentifierName + ) +{ + DB_DATA_ITEM_HEADER Hdr; + memset (&Hdr, 0, sizeof (DB_DATA_ITEM_HEADER)); + Hdr.DataType = DB_DATA_TYPE_STRING_IDENTIFIER; + if (fwrite (&Hdr, sizeof (DB_DATA_ITEM_HEADER), 1, DBFptr) != 1) { + Error (NULL, 0, 0, "failed to write string to output database file", NULL); + return STATUS_ERROR; + } + + if (fwrite (&StringId, sizeof (StringId), 1, DBFptr) != 1) { + Error (NULL, 0, 0, "failed to write StringId to output database", NULL); + return STATUS_ERROR; + } + + if (fwrite (&Flags, sizeof (Flags), 1, DBFptr) != 1) { + Error (NULL, 0, 0, "failed to write StringId flags to output database", NULL); + return STATUS_ERROR; + } + + if (StringDBWriteGenericString (DBFptr, IdentifierName) != STATUS_SUCCESS) { + return STATUS_ERROR; + } + + return STATUS_SUCCESS; +} + +static +STATUS +StringDBReadStringIdentifier ( + FILE *DBFptr + ) +{ + WCHAR *IdentifierName; + UINT16 Flags; + UINT16 StringId; + UINT16 Size; + + if (fread (&StringId, sizeof (StringId), 1, DBFptr) != 1) { + Error (NULL, 0, 0, "failed to read StringId from database", NULL); + return STATUS_ERROR; + } + + if (fread (&Flags, sizeof (Flags), 1, DBFptr) != 1) { + Error (NULL, 0, 0, "failed to read StringId flags from database", NULL); + return STATUS_ERROR; + } + + if (StringDBReadGenericString (DBFptr, &Size, &IdentifierName) != STATUS_SUCCESS) { + return STATUS_ERROR; + } + + StringDBAddStringIdentifier (IdentifierName, &StringId, Flags); + // + // printf ("STRID: 0x%04X %S\n", (UINT32)StringId, IdentifierName); + // + FREE (IdentifierName); + return STATUS_SUCCESS; +} + +static +STATUS +StringDBWriteString ( + FILE *DBFptr, + UINT16 Flags, + WCHAR *Language, + WCHAR *StringName, + WCHAR *Scope, + WCHAR *Str + ) +{ + DB_DATA_ITEM_HEADER Hdr; + memset (&Hdr, 0, sizeof (DB_DATA_ITEM_HEADER)); + Hdr.DataType = DB_DATA_TYPE_STRING_DEFINITION; + if (fwrite (&Hdr, sizeof (DB_DATA_ITEM_HEADER), 1, DBFptr) != 1) { + Error (NULL, 0, 0, "failed to write string header to output database file", NULL); + return STATUS_ERROR; + } + + if (fwrite (&Flags, sizeof (Flags), 1, DBFptr) != 1) { + Error (NULL, 0, 0, "failed to write string flags to output database", NULL); + return STATUS_ERROR; + } + + if (StringDBWriteGenericString (DBFptr, Language) != STATUS_SUCCESS) { + return STATUS_ERROR; + } + + if (StringDBWriteGenericString (DBFptr, StringName) != STATUS_SUCCESS) { + return STATUS_ERROR; + } + + if (StringDBWriteGenericString (DBFptr, Scope) != STATUS_SUCCESS) { + return STATUS_ERROR; + } + + if (StringDBWriteGenericString (DBFptr, Str) != STATUS_SUCCESS) { + return STATUS_ERROR; + } + // + // printf ("DBWriteString: %S.%S.%S\n", Language, StringName, Scope); + // + return STATUS_SUCCESS; +} + +static +STATUS +StringDBReadString ( + FILE *DBFptr + ) +{ + UINT16 Flags; + UINT16 Size; + WCHAR *Language; + WCHAR *StringName; + WCHAR *Scope; + WCHAR *Str; + + if (fread (&Flags, sizeof (Flags), 1, DBFptr) != 1) { + Error (NULL, 0, 0, "failed to read string flags from database", NULL); + return STATUS_ERROR; + } + + if (StringDBReadGenericString (DBFptr, &Size, &Language) != STATUS_SUCCESS) { + return STATUS_ERROR; + } + + if (StringDBReadGenericString (DBFptr, &Size, &StringName) != STATUS_SUCCESS) { + return STATUS_ERROR; + } + + if (StringDBReadGenericString (DBFptr, &Size, &Scope) != STATUS_SUCCESS) { + return STATUS_ERROR; + } + + if (StringDBReadGenericString (DBFptr, &Size, &Str) != STATUS_SUCCESS) { + return STATUS_ERROR; + } + // + // If the first or second string (language name and printable language name), + // then skip them. They're added via language definitions data items in + // the database. + // + if (StringName[0] != L'$') { + StringDBAddString (Language, StringName, Scope, Str, FALSE, Flags); + } + // + // printf ("DBReadString: %S.%S.%S\n", Language, StringName, Scope); + // + FREE (Language); + FREE (StringName); + if (Str != NULL) { + FREE (Str); + } + + if (Scope != NULL) { + FREE (Scope); + } + + return STATUS_SUCCESS; +} + +static +STATUS +StringDBWriteLanguageDefinition ( + FILE *DBFptr, + WCHAR *LanguageName, + WCHAR *PrintableLanguageName, + WCHAR *SecondaryLanguageList + ) +{ + DB_DATA_ITEM_HEADER Hdr; + memset (&Hdr, 0, sizeof (DB_DATA_ITEM_HEADER)); + Hdr.DataType = DB_DATA_TYPE_LANGUAGE_DEFINITION; + if (fwrite (&Hdr, sizeof (DB_DATA_ITEM_HEADER), 1, DBFptr) != 1) { + Error (NULL, 0, 0, "failed to write string to output database file", NULL); + return STATUS_ERROR; + } + + if (StringDBWriteGenericString (DBFptr, LanguageName) != STATUS_SUCCESS) { + return STATUS_ERROR; + } + + if (StringDBWriteGenericString (DBFptr, PrintableLanguageName) != STATUS_SUCCESS) { + return STATUS_ERROR; + } + + if (StringDBWriteGenericString (DBFptr, SecondaryLanguageList) != STATUS_SUCCESS) { + return STATUS_ERROR; + } + + return STATUS_SUCCESS; +} + +static +STATUS +StringDBReadLanguageDefinition ( + FILE *DBFptr + ) +{ + WCHAR *LanguageName = NULL; + WCHAR *PrintableLanguageName = NULL; + WCHAR *SecondaryLanguageList = NULL; + UINT16 Size; + STATUS Status; + + if (StringDBReadGenericString (DBFptr, &Size, &LanguageName) != STATUS_SUCCESS) { + return STATUS_ERROR; + } + + if (StringDBReadGenericString (DBFptr, &Size, &PrintableLanguageName) != STATUS_SUCCESS) { + return STATUS_ERROR; + } + + if (StringDBReadGenericString (DBFptr, &Size, &SecondaryLanguageList) != STATUS_SUCCESS) { + return STATUS_ERROR; + } + + // + // printf("LANG: %S %S\n", LanguageName, PrintableLanguageName); + // + Status = StringDBAddLanguage (LanguageName, PrintableLanguageName, SecondaryLanguageList); + FREE (LanguageName); + FREE (PrintableLanguageName); + FREE (SecondaryLanguageList); + return Status; +} +// +// All unicode strings in the database consist of a UINT16 length +// field, followed by the string itself. This routine reads one +// of those and returns the info. +// +static +STATUS +StringDBReadGenericString ( + FILE *DBFptr, + UINT16 *Size, + WCHAR **Str + ) +{ + UINT16 LSize; + UINT16 Flags; + WCHAR *LStr; + + if (fread (&LSize, sizeof (UINT16), 1, DBFptr) != 1) { + Error (NULL, 0, 0, "failed to read a string length field from the database", NULL); + return STATUS_ERROR; + } + + if (fread (&Flags, sizeof (UINT16), 1, DBFptr) != 1) { + Error (NULL, 0, 0, "failed to read a string flags field from the database", NULL); + return STATUS_ERROR; + } + + LStr = MALLOC (LSize); + if (LStr == NULL) { + Error (__FILE__, __LINE__, 0, "memory allocation failed reading the database", NULL); + return STATUS_ERROR; + } + + if (fread (LStr, sizeof (WCHAR), (UINT32) LSize / sizeof (WCHAR), DBFptr) != (UINT32) LSize / sizeof (WCHAR)) { + Error (NULL, 0, 0, "failed to read string from database", NULL); + Error (NULL, 0, 0, "database read failure", "offset 0x%X", ftell (DBFptr)); + free (LStr); + return STATUS_ERROR; + } + // + // printf ("DBR: %S\n", LStr); + // + // If the flags field indicated we were asked to write a NULL string, then + // return them a NULL pointer. + // + if (Flags & STRING_FLAGS_UNDEFINED) { + *Size = 0; + *Str = NULL; + } else { + *Size = LSize; + *Str = LStr; + } + + return STATUS_SUCCESS; +} + +static +STATUS +StringDBWriteGenericString ( + FILE *DBFptr, + WCHAR *Str + ) +{ + UINT16 Size; + UINT16 Flags; + WCHAR ZeroString[1]; + // + // Strings in the database consist of a size UINT16 followed + // by the string itself. + // + if (Str == NULL) { + ZeroString[0] = 0; + Str = ZeroString; + Size = sizeof (ZeroString); + Flags = STRING_FLAGS_UNDEFINED; + } else { + Flags = 0; + Size = (UINT16) ((wcslen (Str) + 1) * sizeof (WCHAR)); + } + + if (fwrite (&Size, sizeof (UINT16), 1, DBFptr) != 1) { + Error (NULL, 0, 0, "failed to write string size to database", NULL); + return STATUS_ERROR; + } + + if (fwrite (&Flags, sizeof (UINT16), 1, DBFptr) != 1) { + Error (NULL, 0, 0, "failed to write string flags to database", NULL); + return STATUS_ERROR; + } + + if (fwrite (Str, sizeof (WCHAR), Size / sizeof (WCHAR), DBFptr) != Size / sizeof (WCHAR)) { + Error (NULL, 0, 0, "failed to write string to database", NULL); + return STATUS_ERROR; + } + + return STATUS_SUCCESS; +} + +static +STRING_LIST * +StringDBFindString ( + WCHAR *LanguageName, + WCHAR *StringName, + WCHAR *Scope, + WCHAR_STRING_LIST *LanguagesOfInterest, + WCHAR_MATCHING_STRING_LIST *IndirectionList + ) +{ + LANGUAGE_LIST *Lang; + STRING_LIST *CurrString; + WCHAR_MATCHING_STRING_LIST *IndListPtr; + WCHAR TempLangName[LANGUAGE_IDENTIFIER_NAME_LEN + 1]; + WCHAR *WCharPtr; + + // + // If we were given an indirection list, then see if one was specified for this + // string identifier. That is to say, if the indirection says "STR_ID_MY_FAVORITE MyScope", + // then if this string name matches one in the list, then do a lookup with the + // specified scope and return that value. + // + if (IndirectionList != NULL) { + for (IndListPtr = IndirectionList; IndListPtr != NULL; IndListPtr = IndListPtr->Next) { + if (wcscmp (StringName, IndListPtr->Str1) == 0) { + CurrString = StringDBFindString (LanguageName, StringName, IndListPtr->Str2, LanguagesOfInterest, NULL); + if (CurrString != NULL) { + return CurrString; + } + } + } + } + // + // First look for exact match language.stringname + // + for (Lang = mDBData.LanguageList; Lang != NULL; Lang = Lang->Next) { + if (wcscmp (LanguageName, Lang->LanguageName) == 0) { + // + // Found language match. Try to find string name match + // + for (CurrString = Lang->String; CurrString != NULL; CurrString = CurrString->Next) { + if (wcscmp (StringName, CurrString->StringName) == 0) { + // + // Found a string name match. See if we're supposed to find + // a scope match. + // + if (Scope != NULL) { + if (wcscmp (CurrString->Scope, Scope) == 0) { + return CurrString; + } + } else { + return CurrString; + } + } + } + } + } + // + // If we got here, then we didn't find a match. Look for secondary string + // matches. That is to say, if we're processing "spa", and they requested + // "spa+cat", then recursively call with "cat" + // + while (LanguagesOfInterest != NULL) { + // + // If this is the language we're looking for, then process the + // languages of interest list for it. + // + if (wcsncmp (LanguageName, LanguagesOfInterest->Str, LANGUAGE_IDENTIFIER_NAME_LEN) == 0) { + WCharPtr = LanguagesOfInterest->Str + LANGUAGE_IDENTIFIER_NAME_LEN; + while (*WCharPtr) { + // + // Double-check the length, though it should have been checked on the + // command line. + // + if (wcslen (WCharPtr) < LANGUAGE_IDENTIFIER_NAME_LEN) { + Error (NULL, 0, 0, "malformed alternate language list", "%S", LanguagesOfInterest->Str); + return NULL; + } + + wcsncpy (TempLangName, WCharPtr, LANGUAGE_IDENTIFIER_NAME_LEN); + TempLangName[LANGUAGE_IDENTIFIER_NAME_LEN] = 0; + CurrString = StringDBFindString (TempLangName, StringName, NULL, NULL, IndirectionList); + if (CurrString != NULL) { + return CurrString; + } + + WCharPtr += LANGUAGE_IDENTIFIER_NAME_LEN; + } + } + + LanguagesOfInterest = LanguagesOfInterest->Next; + } + + return NULL; +} + +STATUS +StringDBSetScope ( + WCHAR *Scope + ) +{ + // + // Free up existing scope memory. + // + if (mDBData.CurrentScope != NULL) { + FREE (mDBData.CurrentScope); + } + + mDBData.CurrentScope = DuplicateString (Scope); + return STATUS_SUCCESS; +} +// +// We typically don't assign index values to string identifiers +// until we're ready to write out files. To reduce the size of +// the output file, re-order the string identifiers to move any +// unreferenced ones to the end. Then we'll walk the list +// again to assign string indexes, keeping track of the last +// one referenced. +// +static +void +StringDBAssignStringIndexes ( + VOID + ) +{ + STRING_IDENTIFIER *StrId; + STRING_IDENTIFIER *FirstUsed; + STRING_IDENTIFIER *LastUsed; + STRING_IDENTIFIER *FirstUnused; + STRING_IDENTIFIER *LastUnused; + UINT32 Index; + UINT32 MaxReferenced; + + // + // Create two lists -- used and unused. Then put them together with + // the unused ones on the end. + // + FirstUsed = NULL; + LastUsed = NULL; + FirstUnused = NULL; + LastUnused = NULL; + StrId = mDBData.StringIdentifier; + while (StrId != NULL) { + if ((StrId->Flags & STRING_FLAGS_REFERENCED) == 0) { + // + // Put it on the unused list + // + if (FirstUnused == NULL) { + FirstUnused = StrId; + } else { + LastUnused->Next = StrId; + } + + LastUnused = StrId; + StrId = StrId->Next; + LastUnused->Next = NULL; + } else { + // + // Put it on the used list + // + if (FirstUsed == NULL) { + FirstUsed = StrId; + } else { + LastUsed->Next = StrId; + } + + LastUsed = StrId; + StrId = StrId->Next; + LastUsed->Next = NULL; + } + } + // + // Join the lists + // + if (FirstUsed != NULL) { + mDBData.StringIdentifier = FirstUsed; + LastUsed->Next = FirstUnused; + } else { + mDBData.StringIdentifier = FirstUnused; + } + + MaxReferenced = 0; + Index = 0; + for (StrId = mDBData.StringIdentifier; StrId != NULL; StrId = StrId->Next) { + StrId->Index = Index; + Index++; + if (StrId->Flags & STRING_FLAGS_REFERENCED) { + mDBData.NumStringIdentifiersReferenced = Index; + } + } + + mDBData.NumStringIdentifiers = Index; +} + +static +WCHAR * +DuplicateString ( + WCHAR *Str + ) +{ + WCHAR *NewStr; + if (Str == NULL) { + return NULL; + } + + NewStr = MALLOC ((wcslen (Str) + 1) * sizeof (WCHAR)); + if (NewStr == NULL) { + Error (NULL, 0, 0, "memory allocation failure", NULL); + return NULL; + } + + wcscpy (NewStr, Str); + return NewStr; +} + +static +WCHAR * +WstrCatenate ( + WCHAR *Dst, + WCHAR *Src + ) +{ + UINT32 Len = 0; + WCHAR *Bak = Dst; + + if (Src == NULL) { + return Dst; + } + + if (Dst != NULL) { + Len = wcslen (Dst); + } + Len += wcslen (Src); + Dst = (WCHAR *) malloc ((Len + 1) * 2); + if (Dst == NULL) { + return NULL; + } + + Dst[0] = L'\0'; + if (Bak != NULL) { + wcscpy (Dst, Bak); + FREE (Bak); + } + wcscat (Dst, Src); + return Dst; +} + +static +WCHAR * +AsciiToWchar ( + INT8 *Str + ) +{ + UINT32 Len; + WCHAR *NewStr; + WCHAR *Ptr; + + Len = strlen (Str) + 1; + NewStr = (WCHAR *) malloc (Len * sizeof (WCHAR)); + for (Ptr = NewStr; *Str != 0; Str++, Ptr++) { + *Ptr = (UINT16) (UINT8) *Str; + } + + *Ptr = 0; + return NewStr; +} + +static +CHAR8 * +WcharToAscii ( + WCHAR *Str + ) +{ + UINT32 Len; + CHAR8 *NewStr; + CHAR8 *Ptr; + + Len = wcslen (Str) + 1; + NewStr = (CHAR8 *) malloc (Len * sizeof (CHAR8)); + for (Ptr = NewStr; *Str != L'\0'; Str++, Ptr++) { + *Ptr = (CHAR8) *Str; + } + + *Ptr = '\0'; + return NewStr; +} + +/*****************************************************************************/ +CHAR8 * +unicode2ascii ( + WCHAR *UnicodeStr + ) +{ + CHAR8 *RetStr = (CHAR8 *)UnicodeStr; + CHAR8 *AsciiStr = (CHAR8 *)UnicodeStr; + + while (*UnicodeStr != '\0') { + *AsciiStr = (CHAR8) *(UnicodeStr++); + AsciiStr++; + } + *AsciiStr = '\0'; + + return RetStr; +} + +STATUS +BuildStringPkgHdr ( + IN WCHAR *PrimaryLangName, + IN WCHAR *SecondaryLangList, + IN UINT32 Type, + IN UINT32 PkgBlkSize, + OUT EFI_HII_STRING_PACKAGE_HDR **StrPkgHdr + ) +{ + UINT32 LangNameLen; + + LangNameLen = wcslen (PrimaryLangName); + if (SecondaryLangList != NULL) { + LangNameLen += wcslen (SecondaryLangList) + 1; + } + + *StrPkgHdr = (EFI_HII_STRING_PACKAGE_HDR *) malloc(sizeof (EFI_HII_STRING_PACKAGE_HDR) + LangNameLen); + if (*StrPkgHdr == NULL) { + return STATUS_ERROR; + } + memset (*StrPkgHdr, 0, sizeof (EFI_HII_STRING_PACKAGE_HDR) + LangNameLen); + + (*StrPkgHdr)->Header.Type = Type; + (*StrPkgHdr)->Header.Length = PkgBlkSize + sizeof (EFI_HII_STRING_PACKAGE_HDR) + LangNameLen; + (*StrPkgHdr)->HdrSize = sizeof (EFI_HII_STRING_PACKAGE_HDR) + LangNameLen; + (*StrPkgHdr)->StringInfoOffset = sizeof (EFI_HII_STRING_PACKAGE_HDR) + LangNameLen; + (*StrPkgHdr)->LanguageWindow[0] = L'\0'; + (*StrPkgHdr)->LanguageName = (EFI_STRING_ID)1; + + strcpy ((*StrPkgHdr)->Language, unicode2ascii(PrimaryLangName)); + if (SecondaryLangList != NULL) { + strcat ((*StrPkgHdr)->Language, ";"); + strcat ((*StrPkgHdr)->Language, unicode2ascii(SecondaryLangList)); + } + +#ifdef DEBUG_STRGATHER + printf ("STR HDR\t %s\n", (*StrPkgHdr)->Language); +#endif + return STATUS_SUCCESS; +} + +STATUS +BuildStringPkgUCS2Blk ( + IN EFI_STRING_ID StringId, + IN WCHAR *LangName, + IN WCHAR *StrName, + OUT EFI_HII_SIBT_STRING_UCS2_BLOCK **StrBlk, + OUT UINT32 *BlkSize + ) +{ + UINT32 StrLen = 0; + STRING_LIST *CurrString = NULL; + + if ((LangName == NULL) || (StrName == NULL) || (StrBlk == NULL)) { + return STATUS_ERROR; + } + + *StrBlk = NULL; + *BlkSize = 0; + + CurrString = StringDBFindString (LangName, StrName, NULL, NULL, NULL); + if (CurrString == NULL) { + return STATUS_WARNING; + } + + StrLen = wcslen (CurrString->Str); + *BlkSize = sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK) + StrLen * 2; + *StrBlk = (EFI_HII_SIBT_STRING_UCS2_BLOCK *) malloc (*BlkSize); + if (*StrBlk == NULL) { + *StrBlk = NULL; + *BlkSize = 0; + return STATUS_ERROR; + } + (*StrBlk)->Header.BlockType = EFI_HII_SIBT_STRING_UCS2; + wcscpy((*StrBlk)->StringText, CurrString->Str); + + return STATUS_SUCCESS; +} + +STATUS +BuildStringPkgSKIP2Blk ( + IN EFI_STRING_ID SkipIdCount, + OUT EFI_HII_SIBT_SKIP2_BLOCK **StrBlk + ) +{ + if (StrBlk == NULL) { + return STATUS_ERROR; + } + + *StrBlk = NULL; + + *StrBlk = (EFI_HII_SIBT_SKIP2_BLOCK *) malloc (sizeof (EFI_HII_SIBT_SKIP2_BLOCK)); + if (*StrBlk == NULL) { + *StrBlk = NULL; + return STATUS_ERROR; + } + (*StrBlk)->Header.BlockType = EFI_HII_SIBT_SKIP2; + (*StrBlk)->SkipCount = SkipIdCount; + + return STATUS_SUCCESS; +} + +STATUS +BuildStringPkgEndBlk ( + OUT EFI_HII_SIBT_END_BLOCK **End + ) +{ + *End = (EFI_HII_SIBT_END_BLOCK *) malloc (sizeof (EFI_HII_SIBT_END_BLOCK)); + if (*End == NULL) { + return STATUS_ERROR; + } + + (*End)->Header.BlockType = EFI_HII_SIBT_END; + return STATUS_SUCCESS; +} + +/*++ + +Routine Description: + + Create an HII export string pack for the strings in our database. + +Arguments: + + FileName - name of the output file to write + +Returns: + + STATUS + + +--*/ +STATUS +StrPkgBlkBufferListAddTail ( + IN EFI_STRING_ID StringId, + IN WCHAR *StrName, + IN SPkgBlkBuffer **PkgBufferListHead, + IN SPkgBlkBuffer **PkgBufferListTail, + IN VOID *Buffer, + IN UINT32 Size + ) +{ + SPkgBlkBuffer *pNew = NULL; +#ifdef DEBUG_STRGATHER + EFI_HII_STRING_BLOCK *SBlk = (EFI_HII_STRING_BLOCK *)Buffer; +#endif + + if ((PkgBufferListHead == NULL) || (PkgBufferListTail == NULL)) { + return STATUS_ERROR; + } + + pNew = (SPkgBlkBuffer *) malloc (sizeof (SPkgBlkBuffer)); + if (pNew == NULL) { + return STATUS_ERROR; + } + + pNew->mBlkBuffer = Buffer; + pNew->mBlkSize = Size; + if ((*PkgBufferListTail) == NULL) { + (*PkgBufferListHead) = (*PkgBufferListTail) = pNew; + } else { + (*PkgBufferListTail)->mNext = pNew; + (*PkgBufferListTail) = pNew; + pNew->mNext = NULL; + } + +#ifdef DEBUG_STRGATHER + switch (SBlk->BlockType) { + case EFI_HII_SIBT_STRING_UCS2 : + printf ("\tID: [%x] TYPE: [UCS2]\t NAME: %S \t STR: %S\n", StringId, StrName, ((EFI_HII_SIBT_STRING_UCS2_BLOCK *)SBlk)->StringText); + break; + case EFI_HII_SIBT_SKIP2 : + printf ("\tID: [NULL] TYPE: [SKIP2] SKIPCOUNT: [%x]\n", ((EFI_HII_SIBT_SKIP2_BLOCK *)SBlk)->SkipCount); + break; + case EFI_HII_SIBT_END : + printf ("\tID: [%x] TYPE: [END]\n", StringId); + break; + default : + printf ("!!!!UNKNOWN STRING TYPE!!!\n"); + } +#endif + + return STATUS_SUCCESS; +} + +VOID +StrPkgHdrFree ( + IN EFI_HII_STRING_PACKAGE_HDR *StrPkgHdr + ) +{ + if (StrPkgHdr != NULL) { + free (StrPkgHdr); + } +} + +VOID +StrPkgBlkBufferListFree ( + IN SPkgBlkBuffer *PkgBlkList + ) +{ + SPkgBlkBuffer *Buffer; + + while (PkgBlkList != NULL) { + Buffer = PkgBlkList; + PkgBlkList = PkgBlkList->mNext; + + if (Buffer->mBlkBuffer != NULL) { + free (Buffer->mBlkBuffer); + } + free (Buffer); + } +} + +VOID +WriteBlockLine ( + IN FILE *pFile, + IN UINT32 LineBytes, + IN INT8 *LineHeader, + IN INT8 *BlkBuf, + IN UINT32 BlkSize + ) +{ + UINT32 Index; + + if ((pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) { + return; + } + + for (Index = 0; Index < BlkSize; Index++) { + if ((Index % LineBytes) == 0) { + fprintf (pFile, "\n%s", LineHeader); + } + fprintf (pFile, "0x%02X, ", (UINT8)BlkBuf[Index]); + } +} + +VOID +WriteBlockEnd ( + IN FILE *pFile, + IN UINT32 LineBytes, + IN INT8 *LineHeader, + IN INT8 *BlkBuf, + IN UINT32 BlkSize + ) +{ + UINT32 Index; + + if ((BlkSize == 0) || (pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) { + return; + } + + for (Index = 0; Index < BlkSize - 1; Index++) { + if ((Index % LineBytes) == 0) { + fprintf (pFile, "\n%s", LineHeader); + } + fprintf (pFile, "0x%02X, ", (UINT8)BlkBuf[Index]); + } + + if ((Index % LineBytes) == 0) { + fprintf (pFile, "\n%s", LineHeader); + } + fprintf (pFile, "0x%02X\n", (UINT8)BlkBuf[Index]); +} + +#define BYTES_PRE_LINE 0x10 + +VOID +StrPkgWriteHdrCFile ( + IN FILE *File, + IN EFI_HII_STRING_PACKAGE_HDR *StrPkgHdr + ) +{ + if (StrPkgHdr != NULL) { + fprintf (File, "\n // PACKAGE HEADER\n"); + WriteBlockLine(File, BYTES_PRE_LINE, " ", (INT8 *)StrPkgHdr, StrPkgHdr->HdrSize); + } +} + +VOID +StrPkgWirteArrayLength ( + IN FILE *File, + IN UINT32 PkgNumber, + IN EFI_HII_STRING_PACKAGE_HDR **PkgHdr + ) +{ + UINT32 Index; + UINT32 ArrayLen; + + ArrayLen = sizeof (UINT32); + for (Index = 0; Index < PkgNumber; Index++) { + if (PkgHdr[Index] != NULL) { + ArrayLen += PkgHdr[Index]->Header.Length; + } + } + + fprintf (File, "\n // STRING ARRAY LENGTH\n"); + WriteBlockLine(File, BYTES_PRE_LINE, " ", (UINT8 *)&ArrayLen, sizeof (UINT32)); +} + +VOID +StrPkgWriteBlkListCFile ( + IN FILE *File, + IN SPkgBlkBuffer *BlkList, + IN BOOLEAN WriteEnd + ) +{ + SPkgBlkBuffer *Buffer; + + fprintf (File, "\n\n // PACKAGE DATA\n"); + + while (BlkList != NULL) { + Buffer = BlkList; + BlkList = BlkList->mNext; + + if ((Buffer->mNext == NULL) && (WriteEnd == TRUE)) { + if (Buffer->mBlkBuffer != NULL) { + WriteBlockEnd (File, BYTES_PRE_LINE, " ", Buffer->mBlkBuffer, Buffer->mBlkSize); + } + } else { + if (Buffer->mBlkBuffer != NULL) { + WriteBlockLine(File, BYTES_PRE_LINE, " ", Buffer->mBlkBuffer, Buffer->mBlkSize); + } + } + } +} + +VOID +StrPkgWriteHdrBinary ( + IN FILE *File, + IN EFI_HII_STRING_PACKAGE_HDR *StrPkgHdr + ) +{ + fwrite (StrPkgHdr, StrPkgHdr->HdrSize, 1, File); +} + +VOID +StrPkgWriteBlkListBinary ( + IN FILE *File, + IN SPkgBlkBuffer *BlkList + ) +{ + SPkgBlkBuffer *Buffer; + + while (BlkList != NULL) { + Buffer = BlkList; + BlkList = BlkList->mNext; + + if (Buffer->mBlkBuffer != NULL) { + fwrite (Buffer->mBlkBuffer, Buffer->mBlkSize, 1, File); + } + } +} + +STATUS +StringDBGenStrPkgHdrAndBlkList ( + IN LANGUAGE_LIST *Lang, + OUT EFI_HII_STRING_PACKAGE_HDR **StrPkgHdr, + OUT SPkgBlkBuffer **BlkList + ) +{ + STATUS Status; + UINT32 StringIndex; + EFI_STRING_ID StringIdCurrent; + EFI_STRING_ID SkipIdCount; + UINT32 BlkSize = 0; + EFI_HII_SIBT_STRING_UCS2_BLOCK *StrUCS2Blk = NULL; + EFI_HII_SIBT_SKIP2_BLOCK *StrSKIP2Blk = NULL; + STRING_IDENTIFIER *StringIdentifier = NULL; + EFI_HII_SIBT_END_BLOCK *EndBlk = NULL; + UINT32 PkgBlkSize = 0; + SPkgBlkBuffer *PkgBufferListHead = NULL; + SPkgBlkBuffer *PkgBufferListTail = NULL; + + if ((Lang == NULL) || (StrPkgHdr == NULL) || (BlkList == NULL)) { + return STATUS_ERROR; + } + + // + // Assign index values to the string identifiers + // + StringDBAssignStringIndexes (); + StringIdCurrent = EFI_STRING_ID_BEGIN; + SkipIdCount = 0; + + for (StringIndex = STRING_ID_PRINTABLE_LANGUAGE_NAME; StringIndex < mDBData.NumStringIdentifiersReferenced; StringIndex++) { + if ((StringIdentifier = StringDBFindStringIdentifierByIndex (StringIndex)) == NULL) { + Error (NULL, 0, 0, "internal error", "invalid string index 0x%X", StringIndex); + goto ExportPackOut; + } + + if (StringIdentifier->Flags & STRING_FLAGS_REFERENCED) { + Status = BuildStringPkgUCS2Blk (StringIdCurrent, Lang->LanguageName, StringIdentifier->StringName, &StrUCS2Blk, &BlkSize); + switch (Status) { + case STATUS_ERROR: + goto ExportPackOut; + break; + case STATUS_WARNING : + SkipIdCount++; + break; + case STATUS_SUCCESS : + if (SkipIdCount == 0) { + if (StrPkgBlkBufferListAddTail ( + StringIdCurrent, + StringIdentifier->StringName, + &PkgBufferListHead, + &PkgBufferListTail, + StrUCS2Blk, + BlkSize + ) != STATUS_SUCCESS) { + goto ExportPackOut; + } + PkgBlkSize += BlkSize; + } else { + if (BuildStringPkgSKIP2Blk (SkipIdCount, &StrSKIP2Blk) != STATUS_SUCCESS) { + goto ExportPackOut; + } else { + if (StrPkgBlkBufferListAddTail ( + StringIdCurrent, + NULL, + &PkgBufferListHead, + &PkgBufferListTail, + StrSKIP2Blk, + sizeof (EFI_HII_SIBT_SKIP2_BLOCK) + ) != STATUS_SUCCESS) { + goto ExportPackOut; + } + PkgBlkSize += sizeof (EFI_HII_SIBT_SKIP2_BLOCK); + SkipIdCount = 0; + } + + if (StrPkgBlkBufferListAddTail ( + StringIdCurrent, + StringIdentifier->StringName, + &PkgBufferListHead, + &PkgBufferListTail, + StrUCS2Blk, + BlkSize + ) != STATUS_SUCCESS) { + goto ExportPackOut; + } + PkgBlkSize += BlkSize; + } + } + } + + StringIdCurrent++; + } + + if (SkipIdCount != 0) { + if (BuildStringPkgSKIP2Blk (SkipIdCount, &StrSKIP2Blk) != STATUS_SUCCESS) { + goto ExportPackOut; + } else { + if (StrPkgBlkBufferListAddTail ( + StringIdCurrent, + NULL, + &PkgBufferListHead, + &PkgBufferListTail, + StrSKIP2Blk, + sizeof (EFI_HII_SIBT_SKIP2_BLOCK) + ) != STATUS_SUCCESS) { + goto ExportPackOut; + } + PkgBlkSize += sizeof (EFI_HII_SIBT_SKIP2_BLOCK); + SkipIdCount = 0; + } + } + + if (BuildStringPkgEndBlk (&EndBlk) != STATUS_SUCCESS) { + goto ExportPackOut; + } else if (StrPkgBlkBufferListAddTail ( + StringIdCurrent, + NULL, + &PkgBufferListHead, + &PkgBufferListTail, + EndBlk, + sizeof (EFI_HII_SIBT_END_BLOCK) + ) != STATUS_SUCCESS) { + goto ExportPackOut; + } + StringIdCurrent++; + PkgBlkSize += sizeof (EFI_HII_SIBT_END_BLOCK); + + if (BuildStringPkgHdr( + Lang->LanguageName, + Lang->SecondaryLanguageList, + EFI_HII_PACKAGE_STRINGS, + PkgBlkSize, + StrPkgHdr + ) != STATUS_SUCCESS) { + goto ExportPackOut; + } + + *BlkList = PkgBufferListHead; + + return STATUS_SUCCESS; + +ExportPackOut: + StrPkgBlkBufferListFree(PkgBufferListHead); + *BlkList = NULL; + *StrPkgHdr = NULL; + return STATUS_ERROR; +} + +STATUS +StringDBCreateHiiExportPack ( + INT8 *FileName + ) +{ + FILE *File = NULL; + LANGUAGE_LIST *Lang = NULL; + EFI_HII_STRING_PACKAGE_HDR *StrPkgHdr = NULL; + SPkgBlkBuffer *BlkList = NULL; + + if (FileName == NULL) { + return STATUS_ERROR; + } + + if ((File = fopen (FileName, "wb")) == NULL) { + Error (NULL, 0, 0, FileName, "failed to open output HII export file"); + return STATUS_ERROR; + } + + for (Lang = mDBData.LanguageList; Lang != NULL; Lang = Lang->Next) { + if (StringDBGenStrPkgHdrAndBlkList(Lang, &StrPkgHdr, &BlkList) != STATUS_SUCCESS) { + fclose (File); + return STATUS_SUCCESS; + } + + StrPkgWriteHdrBinary (File, StrPkgHdr); + StrPkgWriteBlkListBinary (File, BlkList); + + StrPkgHdrFree (StrPkgHdr); + StrPkgBlkBufferListFree (BlkList); + } + + fclose (File); + return STATUS_SUCCESS; +} + +static const char *gSourceFileHeader[] = { + "//", + "// DO NOT EDIT -- auto-generated file", + "//", + "// This file is generated by the StrGather utility", + "//", + NULL +}; + +STATUS +StringDBDumpCStrings ( + INT8 *BaseName, + INT8 *FileName + ) +{ + EFI_STATUS Status; + FILE *File = NULL; + LANGUAGE_LIST *Lang = NULL; + EFI_HII_STRING_PACKAGE_HDR **StrPkgHdr = NULL; + SPkgBlkBuffer **BlkList = NULL; + UINT32 Index; + UINT32 LangNumber = 0; + + if ((BaseName == NULL) || (FileName == NULL)) { + return STATUS_ERROR; + } + + if (mDBData.LanguageList == NULL) { + return STATUS_SUCCESS; + } + + for (LangNumber = 0, Lang = mDBData.LanguageList; Lang != NULL; Lang = Lang->Next, LangNumber++) + ; + + StrPkgHdr = (EFI_HII_STRING_PACKAGE_HDR **) malloc (sizeof (EFI_HII_STRING_PACKAGE_HDR *) * LangNumber); + BlkList = (SPkgBlkBuffer **) malloc (sizeof (SPkgBlkBuffer *) * LangNumber); + for (Index = 0; Index < LangNumber; Index++) { + StrPkgHdr[Index] = NULL; + BlkList[Index] = NULL; + } + + for (Index = 0, Lang = mDBData.LanguageList; Lang != NULL; Lang = Lang->Next, Index++) { + Status = StringDBGenStrPkgHdrAndBlkList(Lang, &StrPkgHdr[Index], &BlkList[Index]); + if (EFI_ERROR(Status)) { + return Status; + } + } + + if ((File = fopen (FileName, "w")) == NULL) { + Error (NULL, 0, 0, FileName, "failed to open output C file - %s", FileName); + return STATUS_ERROR; + } + + for (Index = 0; gSourceFileHeader[Index] != NULL; Index++) { + fprintf (File, "%s\n", gSourceFileHeader[Index]); + } + + fprintf (File, "\nunsigned char %s[] = {\n", BaseName); + + // + // Save the length of the string package array. + // + StrPkgWirteArrayLength (File, LangNumber, StrPkgHdr); + + for (Index = 0, Lang = mDBData.LanguageList; Lang != NULL; Lang = Lang->Next, Index++) { + if (StrPkgHdr[Index] != NULL) { + StrPkgWriteHdrCFile (File, StrPkgHdr[Index]); + StrPkgWriteBlkListCFile (File, BlkList[Index], (Lang->Next == NULL) ? TRUE : FALSE); + } + + StrPkgHdrFree (StrPkgHdr[Index]); + StrPkgBlkBufferListFree (BlkList[Index]); + } + + fprintf (File, "\n};\n"); + + fclose (File); + return STATUS_SUCCESS; +} diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/UefiStrGather/StringDB.h b/EdkCompatibilityPkg/Sample/Tools/Source/UefiStrGather/StringDB.h new file mode 100644 index 0000000000..6b485c7c9e --- /dev/null +++ b/EdkCompatibilityPkg/Sample/Tools/Source/UefiStrGather/StringDB.h @@ -0,0 +1,254 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + StringDB.h + +Abstract: + + Common defines and prototypes for string database management + +--*/ + +#ifndef _STRING_DB_H_ +#define _STRING_DB_H_ + +#define LANGUAGE_NAME_STRING_NAME L"$LANGUAGE_NAME" +#define PRINTABLE_LANGUAGE_NAME_STRING_NAME L"$PRINTABLE_LANGUAGE_NAME" + +typedef CHAR16 WCHAR; + +#define NARROW_CHAR 0xFFF0 +#define WIDE_CHAR 0xFFF1 +#define NON_BREAKING_CHAR 0xFFF2 +#define GLYPH_WIDTH 8 +#define GLYPH_HEIGHT 19 + +#define STRING_DB_KEY (('S' << 24) | ('D' << 16) | ('B' << 8) | 'K') +// +// Version supported by this tool +// +#define STRING_DB_VERSION 0x00010000 + +#define STRING_DB_MAJOR_VERSION_MASK 0xFFFF0000 +#define STRING_DB_MINOR_VERSION_MASK 0x0000FFFF + +#define DEFINE_STR L"// #define" + +#define EFI_STRING_ID_BEGIN 0x01 + +// +// This is the header that gets written to the top of the +// output binary database file. +// +typedef struct { + UINT32 Key; + UINT32 HeaderSize; + UINT32 Version; + UINT32 NumStringIdenfiers; + UINT32 StringIdentifiersSize; + UINT32 NumLanguages; +} STRING_DB_HEADER; + +// +// When we write out data to the database, we have a UINT16 identifier, which +// indicates what follows, followed by the data. Here's the structure. +// +typedef struct { + UINT16 DataType; + UINT16 Reserved; +} DB_DATA_ITEM_HEADER; + +#define DB_DATA_TYPE_INVALID 0x0000 +#define DB_DATA_TYPE_STRING_IDENTIFIER 0x0001 +#define DB_DATA_TYPE_LANGUAGE_DEFINITION 0x0002 +#define DB_DATA_TYPE_STRING_DEFINITION 0x0003 +#define DB_DATA_TYPE_LAST DB_DATA_TYPE_STRING_DEFINITION + +// +// We have to keep track of a list of languages, each of which has its own +// list of strings. Define a structure to keep track of all languages and +// their list of strings. +// +typedef struct _STRING_LIST { + struct _STRING_LIST *Next; + UINT32 Size; // number of bytes in string, including null terminator + WCHAR *LanguageName; + WCHAR *StringName; // for example STR_ID_TEXT1 + WCHAR *Scope; // + WCHAR *Str; // the actual string + UINT16 Flags; // properties of this string (used, undefined) +} STRING_LIST; + +typedef struct _LANGUAGE_LIST { + struct _LANGUAGE_LIST *Next; + WCHAR *LanguageName; + WCHAR *PrintableLanguageName; + WCHAR *SecondaryLanguageList; + STRING_LIST *String; + STRING_LIST *LastString; +} LANGUAGE_LIST; + +// +// We also keep track of all the string identifier names, which we assign unique +// values to. Create a structure to keep track of them all. +// +typedef struct _STRING_IDENTIFIER { + struct _STRING_IDENTIFIER *Next; + UINT32 Index; // only need 16 bits, but makes it easier with UINT32 + WCHAR *StringName; + UINT16 Flags; // if someone referenced it via STRING_TOKEN() +} STRING_IDENTIFIER; +// +// Keep our globals in this structure to be as modular as possible. +// +typedef struct { + FILE *StringDBFptr; + LANGUAGE_LIST *LanguageList; + LANGUAGE_LIST *LastLanguageList; + LANGUAGE_LIST *CurrentLanguage; // keep track of the last language they used + STRING_IDENTIFIER *StringIdentifier; + STRING_IDENTIFIER *LastStringIdentifier; + UINT8 *StringDBFileName; + UINT32 NumStringIdentifiers; + UINT32 NumStringIdentifiersReferenced; + STRING_IDENTIFIER *CurrentStringIdentifier; // keep track of the last string identifier they added + WCHAR *CurrentScope; +} STRING_DB_DATA; + +typedef struct _SPkgBlkBuffer { + UINT32 mBlkSize; + VOID *mBlkBuffer; + struct _SPkgBlkBuffer *mNext; +} SPkgBlkBuffer; + +void +StringDBConstructor ( + void + ) +; +void +StringDBDestructor ( + void + ) +; + +STATUS +StringDBAddString ( + WCHAR *LanguageName, + WCHAR *StringIdentifier, + WCHAR *Scope, + WCHAR *String, + BOOLEAN Format, + UINT16 Flags + ) +; + +STATUS +StringDBSetScope ( + WCHAR *Scope + ) +; + +#define STRING_FLAGS_REFERENCED 0x0001 // if referenced somewhere +#define STRING_FLAGS_UNDEFINED 0x0002 // if we added it for padding purposes +#define STRING_FLAGS_INDEX_ASSIGNED 0x0004 // so don't change the index value +#define STRING_ID_INVALID 0xFFFF +#define STRING_ID_LANGUAGE_NAME 0x0000 +#define STRING_ID_PRINTABLE_LANGUAGE_NAME 0x0001 + +STATUS +StringDBAddStringIdentifier ( + WCHAR *StringIdentifier, + UINT16 *NewId, + UINT16 Flags + ) +; + +STATUS +StringDBReadDatabase ( + INT8 *DBFileName, + BOOLEAN IgnoreIfNotExist, + BOOLEAN Verbose + ) +; + +STATUS +StringDBWriteDatabase ( + INT8 *DBFileName, + BOOLEAN Verbose + ) +; + +STATUS +StringDBDumpDatabase ( + INT8 *DBFileName, + INT8 *OutputFileName, + BOOLEAN Verbose + ) +; + +STATUS +StringDBAddLanguage ( + WCHAR *LanguageName, + WCHAR *PrintableLanguageName, + WCHAR *SecondaryLanguageList + ) +; + +STATUS +StringDBAddSecondaryLanguage ( + WCHAR *LanguageName, + WCHAR *SecondaryLanguageList + ) +; + +STATUS +StringDBDumpCStrings ( + INT8 *BaseName, + INT8 *FileName + ) +; + +STATUS +StringDBDumpStringDefines ( + INT8 *FileName, + INT8 *BaseName + ) +; + +STATUS +StringDBSetCurrentLanguage ( + WCHAR *LanguageName + ) +; + +STATUS +StringDBSetStringReferenced ( + INT8 *StringIdentifierName, + BOOLEAN IgnoreNotFound + ) +; + +void +StringDBFormatString ( + WCHAR *String + ) +; + +LANGUAGE_LIST * +StringDBFindLanguageList ( + WCHAR *LanguageName + ) +; + +#endif // #ifndef _STRING_DB_H_ diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/EfiVfr.h b/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/EfiVfr.h new file mode 100644 index 0000000000..43e40ab6af --- /dev/null +++ b/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/EfiVfr.h @@ -0,0 +1,53 @@ +/*++ + +Copyright (c) 2004 - 2007, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + EfiVfr.h + +Abstract: + + Defines and prototypes for the UEFI VFR compiler internal use. + +--*/ + +#ifndef _EFIVFR_H_ +#define _EFIVFR_H_ + +#include "Tiano.h" +#include "TianoHii.h" + +#define MAX_PATH 255 +#define MAX_LINE_LEN 4096 + +#define EFI_IFR_MAX_LENGTH 0xFF + +#define EFI_VARSTORE_ID_INVALID 0 +#define EFI_VAROFFSET_INVALID 0xFFFF +#define EFI_VARSTORE_ID_START 0x20 +#define EFI_STRING_ID_INVALID 0x0 +#define EFI_IMAGE_ID_INVALID 0xFFFF + +typedef enum { + QUESTION_NORMAL, + QUESTION_DATE, + QUESTION_TIME, +} EFI_QUESION_TYPE; + +typedef enum { + EQUAL, + LESS_EQUAL, + LESS_THAN, + GREATER_THAN, + GREATER_EQUAL +} EFI_COMPARE_TYPE; + +#endif diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrCompiler.cpp b/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrCompiler.cpp new file mode 100644 index 0000000000..b1b19b90bf --- /dev/null +++ b/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrCompiler.cpp @@ -0,0 +1,594 @@ +#include "stdio.h" +#include "string.h" +#include "process.h" +#include "VfrCompiler.h" + + +VOID +CVfrCompiler::SET_RUN_STATUS ( + IN COMPILER_RUN_STATUS Status + ) +{ + mRunStatus = Status; +} + +BOOLEAN +CVfrCompiler::IS_RUN_STATUS ( + IN COMPILER_RUN_STATUS Status + ) +{ + return mRunStatus == Status; +} + +VOID +CVfrCompiler::OptionInitialization ( + IN INT32 Argc, + IN INT8 **Argv + ) +{ + INT32 Index; + + mOptions.VfrFileName[0] = '\0'; + mOptions.RecordListFile[0] = '\0'; + mOptions.CreateRecordListFile = FALSE; + mOptions.CreateIfrPkgFile = FALSE; + mOptions.PkgOutputFileName[0] = '\0'; + mOptions.COutputFileName[0] = '\0'; + mOptions.OutputDirectory[0] = '\0'; + mOptions.PreprocessorOutputFileName[0] = '\0'; + mOptions.VfrBaseFileName[0] = '\0'; + mOptions.IncludePaths = NULL; + mOptions.CPreprocessorOptions = NULL; + + for (Index = 1; (Index < Argc) && (Argv[Index][0] == '-'); Index++) { + if ((_stricmp(Argv[Index], "-?") == 0) || (_stricmp(Argv[Index], "-h") == 0)) { + Usage (); + SET_RUN_STATUS (STATUS_DEAD); + return; + } else if (_stricmp(Argv[Index], "-l") == 0) { + mOptions.CreateRecordListFile = TRUE; + gCIfrRecordInfoDB.TurnOn (); + } else if (_stricmp(Argv[Index], "-i") == 0) { + Index++; + if ((Index >= Argc) || (Argv[Index][0] == '-')) { + printf ("%s -i - missing path argument\n", PROGRAM_NAME); + goto Fail; + } + + AppendIncludePath(Argv[Index]); + } else if (_stricmp(Argv[Index], "-od") == 0) { + Index++; + if ((Index >= Argc) || (Argv[Index][0] == '-')) { + printf ("%s -od - missing output directory name\n", PROGRAM_NAME); + goto Fail; + } + strcpy (mOptions.OutputDirectory, Argv[Index]); + } else if (_stricmp(Argv[Index], "-ibin") == 0) { + mOptions.CreateIfrPkgFile = TRUE; + } else if (_stricmp(Argv[Index], "-nostrings") == 0) { + } else if (_stricmp(Argv[Index], "-ppflag") == 0) { + Index++; + if ((Index >= Argc) || (Argv[Index][0] == '-')) { + printf ("%s -od - missing C-preprocessor argument\n", PROGRAM_NAME); + goto Fail; + } + + AppendCPreprocessorOptions (Argv[Index]); + } else { + printf ("%s unrecognized option %s\n", PROGRAM_NAME, Argv[Index]); + Usage (); + goto Fail; + } + } + + if (Index != Argc - 1) { + printf ("%s must specify VFR file name", PROGRAM_NAME); + Usage (); + goto Fail; + } else { + strcpy (mOptions.VfrFileName, Argv[Index]); + } + + if (SetBaseFileName() != 0) { + goto Fail; + } + if (SetPkgOutputFileName () != 0) { + goto Fail; + } + if (SetCOutputFileName() != 0) { + goto Fail; + } + if (SetPreprocessorOutputFileName () != 0) { + goto Fail; + } + if (SetRecordListFileName () != 0) { + goto Fail; + } + return; + +Fail: + SET_RUN_STATUS (STATUS_FAILED); + + mOptions.VfrFileName[0] = '\0'; + mOptions.RecordListFile[0] = '\0'; + mOptions.CreateRecordListFile = FALSE; + mOptions.CreateIfrPkgFile = FALSE; + mOptions.PkgOutputFileName[0] = '\0'; + mOptions.COutputFileName[0] = '\0'; + mOptions.OutputDirectory[0] = '\0'; + mOptions.PreprocessorOutputFileName[0] = '\0'; + mOptions.VfrBaseFileName[0] = '\0'; + if (mOptions.IncludePaths != NULL) { + delete mOptions.IncludePaths; + mOptions.IncludePaths = NULL; + } + if (mOptions.CPreprocessorOptions != NULL) { + delete mOptions.CPreprocessorOptions; + mOptions.CPreprocessorOptions = NULL; + } +} + +VOID +CVfrCompiler::AppendIncludePath ( + IN INT8 *PathStr + ) +{ + UINT32 Len = 0; + INT8 *IncludePaths = NULL; + + Len = strlen (" -I ") + strlen (PathStr) + 1; + if (mOptions.IncludePaths != NULL) { + Len += strlen (mOptions.IncludePaths); + } + IncludePaths = new INT8[Len]; + if (IncludePaths == NULL) { + printf ("%s memory allocation failure\n", PROGRAM_NAME); + return; + } + IncludePaths[0] = '\0'; + if (mOptions.IncludePaths != NULL) { + strcat (IncludePaths, mOptions.IncludePaths); + } + strcat (IncludePaths, " -I "); + strcat (IncludePaths, PathStr); + if (mOptions.IncludePaths != NULL) { + delete mOptions.IncludePaths; + } + mOptions.IncludePaths = IncludePaths; +} + +VOID +CVfrCompiler::AppendCPreprocessorOptions ( + IN INT8 *Options + ) +{ + UINT32 Len = 0; + INT8 *Opt = NULL; + + Len = strlen (Options) + strlen (" ") + 1; + if (mOptions.CPreprocessorOptions != NULL) { + Len += strlen (mOptions.CPreprocessorOptions); + } + Opt = new INT8[Len]; + if (Opt == NULL) { + printf ("%s memory allocation failure\n", PROGRAM_NAME); + return; + } + Opt[0] = 0; + if (mOptions.CPreprocessorOptions != NULL) { + strcat (Opt, mOptions.CPreprocessorOptions); + } + strcat (Opt, " "); + strcat (Opt, Options); + if (mOptions.CPreprocessorOptions != NULL) { + delete mOptions.CPreprocessorOptions; + } + mOptions.CPreprocessorOptions = Opt; +} + +INT8 +CVfrCompiler::SetBaseFileName ( + VOID + ) +{ + INT8 *pFileName, *pPath, *pExt; + + if (mOptions.VfrFileName[0] == '\0') { + return -1; + } + + pFileName = mOptions.VfrFileName; + while ((pPath = strchr (pFileName, '\\')) != NULL) { + pFileName = pPath + 1; + } + + if (pFileName == NULL) { + return -1; + } + + if ((pExt = strchr (pFileName, '.')) == NULL) { + return -1; + } + + strncpy (mOptions.VfrBaseFileName, pFileName, pExt - pFileName); + mOptions.VfrBaseFileName[pExt - pFileName] = '\0'; + + return 0; +} + +INT8 +CVfrCompiler::SetPkgOutputFileName ( + VOID + ) +{ + if (mOptions.VfrBaseFileName[0] == '\0') { + return -1; + } + + strcpy (mOptions.PkgOutputFileName, mOptions.OutputDirectory); + strcat (mOptions.PkgOutputFileName, mOptions.VfrBaseFileName); + strcat (mOptions.PkgOutputFileName, VFR_PACKAGE_FILENAME_EXTENSION); + + return 0; +} + +INT8 +CVfrCompiler::SetCOutputFileName ( + VOID + ) +{ + if (mOptions.VfrBaseFileName[0] == '\0') { + return -1; + } + + strcpy (mOptions.COutputFileName, mOptions.OutputDirectory); + strcat (mOptions.COutputFileName, mOptions.VfrBaseFileName); + strcat (mOptions.COutputFileName, ".c"); + + return 0; +} + +INT8 +CVfrCompiler::SetPreprocessorOutputFileName ( + VOID + ) +{ + if (mOptions.VfrBaseFileName[0] == '\0') { + return -1; + } + + strcpy (mOptions.PreprocessorOutputFileName, mOptions.OutputDirectory); + strcat (mOptions.PreprocessorOutputFileName, mOptions.VfrBaseFileName); + strcat (mOptions.PreprocessorOutputFileName, VFR_PREPROCESS_FILENAME_EXTENSION); + + return 0; +} + +INT8 +CVfrCompiler::SetRecordListFileName ( + VOID + ) +{ + if (mOptions.VfrBaseFileName[0] == '\0') { + return -1; + } + + strcpy (mOptions.RecordListFile, mOptions.OutputDirectory); + strcat (mOptions.RecordListFile, mOptions.VfrBaseFileName); + strcat (mOptions.RecordListFile, VFR_RECORDLIST_FILENAME_EXTENSION); + + return 0; +} + +CVfrCompiler::CVfrCompiler ( + IN INT32 Argc, + IN INT8 **Argv + ) +{ + mPreProcessCmd = PREPROCESSOR_COMMAND; + mPreProcessOpt = PREPROCESSOR_OPTIONS; + + OptionInitialization(Argc, Argv); + + if ((IS_RUN_STATUS(STATUS_FAILED)) || (IS_RUN_STATUS(STATUS_DEAD))) { + return; + } + + SET_RUN_STATUS(STATUS_INITIALIZED); +} + +CVfrCompiler::~CVfrCompiler ( + VOID + ) +{ + if (mOptions.IncludePaths != NULL) { + delete mOptions.IncludePaths; + mOptions.IncludePaths = NULL; + } + + if (mOptions.CPreprocessorOptions != NULL) { + delete mOptions.CPreprocessorOptions; + mOptions.CPreprocessorOptions = NULL; + } + + SET_RUN_STATUS(STATUS_DEAD); +} + +VOID +CVfrCompiler::Usage ( + VOID + ) +{ + UINT32 Index; + CONST INT8 *Help[] = { + " ", + "VfrCompile version " VFR_COMPILER_VERSION, + " ", + " Usage: VfrCompile {options} [VfrFile]", + " ", + " where options include:", + " -? or -h prints this help", + " -l create an output IFR listing file", + " -i IncPath add IncPath to the search path for VFR included files", + " -od OutputDir deposit all output files to directory OutputDir (default=cwd)", + " -ibin create an IFR HII pack file" + " -ppflag C-preprocessor argument", + " where parameters include:", + " VfrFile name of the input VFR script file", + " ", + NULL + }; + for (Index = 0; Help[Index] != NULL; Index++) { + fprintf (stdout, "%s\n", Help[Index]); + } +} + +VOID +CVfrCompiler::PreProcess ( + VOID + ) +{ + FILE *pVfrFile = NULL; + UINT32 CmdLen = 0; + INT8 *PreProcessCmd = NULL; + + if (!IS_RUN_STATUS(STATUS_INITIALIZED)) { + goto Fail; + } + + if ((pVfrFile = fopen (mOptions.VfrFileName, "r")) == NULL) { + printf ("%s could not open input VFR file - %s\n", PROGRAM_NAME, mOptions.VfrFileName); + goto Fail; + } + fclose (pVfrFile); + + CmdLen = strlen (mPreProcessCmd) + strlen (mPreProcessOpt) + + strlen (mOptions.VfrFileName) + strlen (mOptions.PreprocessorOutputFileName); + if (mOptions.CPreprocessorOptions != NULL) { + CmdLen += strlen (mOptions.CPreprocessorOptions); + } + if (mOptions.IncludePaths != NULL) { + CmdLen += strlen (mOptions.IncludePaths); + } + + PreProcessCmd = new INT8[CmdLen + 10]; + if (PreProcessCmd == NULL) { + printf ("%s could not allocate memory\n", PROGRAM_NAME); + goto Fail; + } + strcpy (PreProcessCmd, mPreProcessCmd), strcat (PreProcessCmd, " "); + strcat (PreProcessCmd, mPreProcessOpt), strcat (PreProcessCmd, " "); + if (mOptions.IncludePaths != NULL) { + strcat (PreProcessCmd, mOptions.IncludePaths), strcat (PreProcessCmd, " "); + } + if (mOptions.CPreprocessorOptions != NULL) { + strcat (PreProcessCmd, mOptions.CPreprocessorOptions), strcat (PreProcessCmd, " "); + } + strcat (PreProcessCmd, mOptions.VfrFileName), strcat (PreProcessCmd, " > "); + strcat (PreProcessCmd, mOptions.PreprocessorOutputFileName); + + if (system (PreProcessCmd) != 0) { + printf ("%s failed to spawn C preprocessor on VFR file \n\t - %s\n", PROGRAM_NAME, PreProcessCmd); + goto Fail; + } + + delete PreProcessCmd; + SET_RUN_STATUS (STATUS_PREPROCESSED); + return; + +Fail: + if (!IS_RUN_STATUS(STATUS_DEAD)) { + SET_RUN_STATUS (STATUS_FAILED); + } + delete PreProcessCmd; +} + +extern UINT8 VfrParserStart (IN FILE *); + +VOID +CVfrCompiler::Compile ( + VOID + ) +{ + FILE *VfrFile = NULL; + + if (!IS_RUN_STATUS(STATUS_PREPROCESSED)) { + goto Fail; + } + + if ((VfrFile = fopen (mOptions.PreprocessorOutputFileName, "r")) == NULL) { + printf ("%s failed to open input VFR preprocessor output file - %s\n", PROGRAM_NAME, mOptions.PreprocessorOutputFileName); + goto Fail; + } + + if (VfrParserStart (VfrFile) != 0) { + goto Fail; + } + + fclose (VfrFile); + + if (gCFormPkg.HavePendingUnassigned () == TRUE) { + gCFormPkg.PendingAssignPrintAll (); + goto Fail; + } + + SET_RUN_STATUS (STATUS_COMPILEED); + return; + +Fail: + if (!IS_RUN_STATUS(STATUS_DEAD)) { + printf ("%s compile error!\n", PROGRAM_NAME); + SET_RUN_STATUS (STATUS_FAILED); + } + if (VfrFile != NULL) { + fclose (VfrFile); + } +} + +VOID +CVfrCompiler::GenBinary ( + VOID + ) +{ + FILE *pFile = NULL; + + if (!IS_RUN_STATUS(STATUS_COMPILEED)) { + goto Fail; + } + + if (mOptions.CreateIfrPkgFile == TRUE) { + if ((pFile = fopen (mOptions.PkgOutputFileName, "wb")) == NULL) { + printf ("can not open PkgFileName\n", mOptions.PkgOutputFileName); + goto Fail; + } + if (gCFormPkg.BuildPkg (pFile) != VFR_RETURN_SUCCESS) { + fclose (pFile); + goto Fail; + } + fclose (pFile); + } + + SET_RUN_STATUS (STATUS_GENBINARY); + return; + +Fail: + if (!IS_RUN_STATUS(STATUS_DEAD)) { + SET_RUN_STATUS (STATUS_FAILED); + } +} + +static const char *gSourceFileHeader[] = { + "//", + "// DO NOT EDIT -- auto-generated file", + "//", + "// This file is generated by the vfrcompiler utility", + "//", + NULL +}; + +VOID +CVfrCompiler::GenCFile ( + VOID + ) +{ + FILE *pFile; + UINT32 Index; + + if (!IS_RUN_STATUS(STATUS_GENBINARY)) { + goto Fail; + } + + if ((pFile = fopen (mOptions.COutputFileName, "w")) == NULL) { + printf ("failed to open output C file - %s\n", mOptions.COutputFileName); + goto Fail; + } + + for (Index = 0; gSourceFileHeader[Index] != NULL; Index++) { + fprintf (pFile, "%s\n", gSourceFileHeader[Index]); + } + + gCVfrBufferConfig.OutputCFile (pFile, mOptions.VfrBaseFileName); + + if (gCFormPkg.GenCFile (mOptions.VfrBaseFileName, pFile) != VFR_RETURN_SUCCESS) { + fclose (pFile); + goto Fail; + } + fclose (pFile); + + SET_RUN_STATUS (STATUS_FINISHED); + return; + +Fail: + if (!IS_RUN_STATUS(STATUS_DEAD)) { + SET_RUN_STATUS (STATUS_FAILED); + } +} + +VOID +CVfrCompiler::GenRecordListFile ( + VOID + ) +{ + FILE *pInFile = NULL; + FILE *pOutFile = NULL; + INT8 LineBuf[MAX_LINE_LEN]; + UINT32 LineNo; + + if (mOptions.CreateRecordListFile == TRUE) { + if ((mOptions.PreprocessorOutputFileName[0] == '\0') || (mOptions.RecordListFile[0] == '\0')) { + return; + } + + if ((pInFile = fopen (mOptions.PreprocessorOutputFileName, "r")) == NULL) { + printf ("%s failed to open input VFR preprocessor output file - %s\n", PROGRAM_NAME, mOptions.PreprocessorOutputFileName); + return; + } + + if ((pOutFile = fopen (mOptions.RecordListFile, "w")) == NULL) { + printf ("%s failed to open record list file for writing - %s\n", PROGRAM_NAME, mOptions.RecordListFile); + goto Err1; + } + + fprintf (pOutFile, "//\n// VFR compiler version " VFR_COMPILER_VERSION "\n//\n"); + LineNo = 0; + while (!feof (pInFile)) { + if (fgets (LineBuf, MAX_LINE_LEN, pInFile) != NULL) { + fprintf (pOutFile, "%s", LineBuf); + LineNo++; + gCIfrRecordInfoDB.IfrRecordOutput (pOutFile, LineNo); + } + } + + fclose (pOutFile); + fclose (pInFile); + } + + return; + +Err1: + fclose (pInFile); +} + +INT32 +main ( + IN INT32 Argc, + IN INT8 **Argv + ) +{ + COMPILER_RUN_STATUS Status; + CVfrCompiler Compiler(Argc, Argv); + + Compiler.PreProcess(); + Compiler.Compile(); + Compiler.GenBinary(); + Compiler.GenCFile(); + Compiler.GenRecordListFile (); + + Status = Compiler.RunStatus (); + if ((Status == STATUS_DEAD) || (Status == STATUS_FAILED)) { + return 2; + } + + return 0; +} + diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrCompiler.h b/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrCompiler.h new file mode 100644 index 0000000000..a980cb5b1a --- /dev/null +++ b/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrCompiler.h @@ -0,0 +1,90 @@ +#ifndef _VFRCOMPILER_H_ +#define _VFRCOMPILER_H_ + +#include "Tiano.h" +#include "EfiTypes.h" +#include "EfiVfr.h" +#include "VfrFormPkg.h" +#include "VfrUtilityLib.h" + +#define PROGRAM_NAME "VfrCompile" +#define VFR_COMPILER_VERSION "UEFI 2.1" + +// +// This is how we invoke the C preprocessor on the VFR source file +// to resolve #defines, #includes, etc. To make C source files +// shareable between VFR and drivers, define VFRCOMPILE so that +// #ifdefs can be used in shared .h files. +// +#define PREPROCESSOR_COMMAND "cl " +#define PREPROCESSOR_OPTIONS "/nologo /E /TC /DVFRCOMPILE " + +// +// Specify the filename extensions for the files we generate. +// +#define VFR_PREPROCESS_FILENAME_EXTENSION ".i" +#define VFR_PACKAGE_FILENAME_EXTENSION ".hpk" +#define VFR_RECORDLIST_FILENAME_EXTENSION ".lst" + +typedef struct { + INT8 VfrFileName[MAX_PATH]; + INT8 RecordListFile[MAX_PATH]; + INT8 PkgOutputFileName[MAX_PATH]; + INT8 COutputFileName[MAX_PATH]; + bool CreateRecordListFile; + bool CreateIfrPkgFile; + INT8 OutputDirectory[MAX_PATH]; + INT8 PreprocessorOutputFileName[MAX_PATH]; + INT8 VfrBaseFileName[MAX_PATH]; // name of input VFR file with no path or extension + INT8 *IncludePaths; + INT8 *CPreprocessorOptions; +} OPTIONS; + +typedef enum { + STATUS_INITIALIZED = 1, + STATUS_PREPROCESSED, + STATUS_COMPILEED, + STATUS_GENBINARY, + STATUS_FINISHED, + STATUS_FAILED, + STATUS_DEAD, +} COMPILER_RUN_STATUS; + +class CVfrCompiler { +private: + COMPILER_RUN_STATUS mRunStatus; + OPTIONS mOptions; + INT8 *mPreProcessCmd; + INT8 *mPreProcessOpt; + + VOID OptionInitialization (IN INT32 , IN INT8 **); + VOID AppendIncludePath (IN INT8 *); + VOID AppendCPreprocessorOptions (IN INT8 *); + INT8 SetBaseFileName (VOID); + INT8 SetPkgOutputFileName (VOID); + INT8 SetCOutputFileName(VOID); + INT8 SetPreprocessorOutputFileName (VOID); + INT8 SetRecordListFileName (VOID); + + VOID SET_RUN_STATUS (IN COMPILER_RUN_STATUS); + BOOLEAN IS_RUN_STATUS (IN COMPILER_RUN_STATUS); + +public: + COMPILER_RUN_STATUS RunStatus (VOID) { + return mRunStatus; + } + +public: + CVfrCompiler (IN INT32 , IN INT8 **); + ~CVfrCompiler (); + + VOID Usage (VOID); + + VOID PreProcess (VOID); + VOID Compile (VOID); + VOID GenBinary (VOID); + VOID GenCFile (VOID); + VOID GenRecordListFile (VOID); +}; + +#endif diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrError.cpp b/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrError.cpp new file mode 100644 index 0000000000..e1575770a8 --- /dev/null +++ b/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrError.cpp @@ -0,0 +1,197 @@ +#include "stdio.h" +#include "string.h" +#include "stdlib.h" +#include "VfrError.h" + +static SVFR_ERROR_HANDLE VFR_ERROR_HANDLE_TABLE [] = { + { VFR_RETURN_SUCCESS, NULL }, + { VFR_RETURN_ERROR_SKIPED, NULL }, + { VFR_RETURN_FATAL_ERROR, "fatal error!!" }, + + { VFR_RETURN_MISMATCHED, "unexpected token" }, + { VFR_RETURN_INVALID_PARAMETER, "Invalid parameter" }, + { VFR_RETURN_OUT_FOR_RESOURCES, "system out of memory" }, + { VFR_RETURN_UNSUPPORTED, "unsupported" }, + { VFR_RETURN_REDEFINED, "already defined" }, + { VFR_RETURN_FORMID_REDEFINED, "form id already defined" }, + { VFR_RETURN_QUESTIONID_REDEFINED, "question id already defined" }, + { VFR_RETURN_VARSTOREID_REDEFINED, "varstore id already defined" }, + { VFR_RETURN_UNDEFINED, "undefined" }, + { VFR_RETURN_VAR_NOTDEFINED_BY_QUESTION, "some variable has not defined by a question"}, + { VFR_RETURN_GET_EFIVARSTORE_ERROR, "get efi varstore error"}, + { VFR_RETURN_EFIVARSTORE_USE_ERROR, "can not use the efi varstore like this" }, + { VFR_RETURN_EFIVARSTORE_SIZE_ERROR, "unsupport efi varstore size should be <= 8 bytes" }, + { VFR_RETURN_GET_NVVARSTORE_ERROR, "get name value varstore error" }, + { VFR_RETURN_QVAR_REUSE, "variable reused by more than one question" }, + { VFR_RETURN_FLAGS_UNSUPPORTED, "flags unsupported" }, + { VFR_RETURN_ERROR_ARRARY_NUM, "array number error" }, + { VFR_RETURN_DATA_STRING_ERROR, "data field string error or not support"}, + { VFR_RETURN_CODEUNDEFINED, "Undefined Error Code" } +}; + +CVfrErrorHandle::CVfrErrorHandle ( + VOID + ) +{ + mScopeRecordListHead = NULL; + mScopeRecordListTail = NULL; + mVfrErrorHandleTable = VFR_ERROR_HANDLE_TABLE; +} + +CVfrErrorHandle::~CVfrErrorHandle ( + VOID + ) +{ + SVfrFileScopeRecord *pNode = NULL; + + while (mScopeRecordListHead != NULL) { + pNode = mScopeRecordListHead; + mScopeRecordListHead = mScopeRecordListHead->mNext; + delete pNode; + } + + mScopeRecordListHead = NULL; + mScopeRecordListTail = NULL; + mVfrErrorHandleTable = NULL; +} + +SVfrFileScopeRecord::SVfrFileScopeRecord ( + IN INT8 *Record, + IN UINT32 LineNum + ) +{ + UINT32 Index; + INT8 *FileName = NULL; + INT8 *Str = NULL; + + mWholeScopeLine = LineNum; + mNext = NULL; + + Str = strchr (Record, ' '); + mScopeLineStart = atoi (++Str); + + Str = strchr (Str, '\"'); + FileName = ++Str; + + while((Str = strstr (FileName, "\\\\")) != NULL) { + FileName = Str + 2; + } + if ((mFileName = new INT8[strlen(FileName)]) != NULL) { + for (Index = 0; FileName[Index] != '\"'; Index++) { + mFileName[Index] = FileName[Index]; + } + mFileName[Index] = '\0'; + } + + return; +} + +SVfrFileScopeRecord::~SVfrFileScopeRecord ( + VOID + ) +{ + if (mFileName != NULL) { + delete mFileName; + } +} + +VOID +CVfrErrorHandle::ParseFileScopeRecord ( + IN INT8 *Record, + IN UINT32 WholeScopeLine + ) +{ + INT8 *FullPathName = NULL; + SVfrFileScopeRecord *pNode = NULL; + + if (Record == NULL) { + return; + } + + if ((pNode = new SVfrFileScopeRecord(Record, WholeScopeLine)) == NULL) { + return; + } + + if (mScopeRecordListHead == NULL) { + mScopeRecordListTail = mScopeRecordListHead = pNode; + } else { + mScopeRecordListTail->mNext = pNode; + mScopeRecordListTail = pNode; + } +} + +VOID +CVfrErrorHandle::GetFileNameLineNum ( + IN UINT32 LineNum, + OUT INT8 **FileName, + OUT UINT32 *FileLine + ) +{ + SVfrFileScopeRecord *pNode = NULL; + + if ((FileName == NULL) || (FileLine == NULL)) { + return; + } + + *FileName = NULL; + *FileLine = 0xFFFFFFFF; + + for (pNode = mScopeRecordListHead; pNode->mNext != NULL; pNode = pNode->mNext) { + if ((LineNum > pNode->mWholeScopeLine) && (pNode->mNext->mWholeScopeLine > LineNum)) { + *FileName = pNode->mFileName; + *FileLine = LineNum - pNode->mWholeScopeLine + pNode->mScopeLineStart - 1; + return ; + } + } + + *FileName = pNode->mFileName; + *FileLine = LineNum - pNode->mWholeScopeLine + pNode->mScopeLineStart - 1; +} + +VOID +CVfrErrorHandle::PrintError ( + IN UINT32 LineNum, + IN INT8 *TokName, + IN INT8 *ErrorMsg + ) +{ + INT8 *FileName = NULL; + UINT32 FileLine; + + GetFileNameLineNum (LineNum, &FileName, &FileLine); + printf ("%s line %d: error %s %s\n", FileName, FileLine, TokName, ErrorMsg); +} + +UINT8 +CVfrErrorHandle::HandleError ( + IN EFI_VFR_RETURN_CODE ErrorCode, + IN UINT32 LineNum, + IN INT8 *TokName + ) +{ + UINT32 Index; + INT8 *FileName = NULL; + UINT32 FileLine; + INT8 *ErrorMsg = NULL; + + if (mVfrErrorHandleTable == NULL) { + return 1; + } + + for (Index = 0; mVfrErrorHandleTable[Index].mErrorCode != VFR_RETURN_CODEUNDEFINED; Index++) { + if (ErrorCode == mVfrErrorHandleTable[Index].mErrorCode) { + ErrorMsg = mVfrErrorHandleTable[Index].mErrorMsg; + break; + } + } + + if (ErrorMsg != NULL) { + GetFileNameLineNum (LineNum, &FileName, &FileLine); + printf ("%s line %d: error %s %s\n", FileName, FileLine, TokName, ErrorMsg); + return 1; + } else { + return 0; + } +} + +CVfrErrorHandle gCVfrErrorHandle; diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrError.h b/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrError.h new file mode 100644 index 0000000000..5e8ac51ec9 --- /dev/null +++ b/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrError.h @@ -0,0 +1,67 @@ +#ifndef _VFRERROR_H_ +#define _VFRERROR_H_ + +#include "Tiano.h" +#include "EfiTypes.h" + +typedef enum { + VFR_RETURN_SUCCESS = 0, + VFR_RETURN_ERROR_SKIPED, + VFR_RETURN_FATAL_ERROR, + VFR_RETURN_MISMATCHED, + VFR_RETURN_INVALID_PARAMETER, + VFR_RETURN_OUT_FOR_RESOURCES, + VFR_RETURN_UNSUPPORTED, + VFR_RETURN_REDEFINED, + VFR_RETURN_FORMID_REDEFINED, + VFR_RETURN_QUESTIONID_REDEFINED, + VFR_RETURN_VARSTOREID_REDEFINED, + VFR_RETURN_UNDEFINED, + VFR_RETURN_VAR_NOTDEFINED_BY_QUESTION, + VFR_RETURN_GET_EFIVARSTORE_ERROR, + VFR_RETURN_EFIVARSTORE_USE_ERROR, + VFR_RETURN_EFIVARSTORE_SIZE_ERROR, + VFR_RETURN_GET_NVVARSTORE_ERROR, + VFR_RETURN_QVAR_REUSE, + VFR_RETURN_FLAGS_UNSUPPORTED, + VFR_RETURN_ERROR_ARRARY_NUM, + VFR_RETURN_DATA_STRING_ERROR, + VFR_RETURN_CODEUNDEFINED +} EFI_VFR_RETURN_CODE; + +typedef struct _SVFR_ERROR_HANDLE { + EFI_VFR_RETURN_CODE mErrorCode; + INT8 *mErrorMsg; +} SVFR_ERROR_HANDLE; + +struct SVfrFileScopeRecord { + INT8 *mFileName; + UINT32 mWholeScopeLine; + UINT32 mScopeLineStart; + SVfrFileScopeRecord *mNext; + + SVfrFileScopeRecord (IN INT8 *, IN UINT32); + ~SVfrFileScopeRecord(); +}; + +class CVfrErrorHandle { +private: + SVFR_ERROR_HANDLE *mVfrErrorHandleTable; + SVfrFileScopeRecord *mScopeRecordListHead; + SVfrFileScopeRecord *mScopeRecordListTail; + +public: + CVfrErrorHandle (VOID); + ~CVfrErrorHandle (VOID); + + VOID ParseFileScopeRecord (IN INT8 *, IN UINT32); + VOID GetFileNameLineNum (IN UINT32, OUT INT8 **, OUT UINT32 *); + UINT8 HandleError (IN EFI_VFR_RETURN_CODE, IN UINT32 LineNum = 0, IN INT8 *TokName = "\0"); + VOID PrintError (IN UINT32 LineNum = 0, IN INT8 *TokName = "\0", IN INT8 *ErrorMsg = "\0"); +}; + +#define CHECK_ERROR_RETURN(f, v) do { EFI_VFR_RETURN_CODE r; if ((r = (f)) != (v)) { return r; } } while (0) + +extern CVfrErrorHandle gCVfrErrorHandle; + +#endif diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrFormPkg.cpp b/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrFormPkg.cpp new file mode 100644 index 0000000000..2ac1b681bf --- /dev/null +++ b/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrFormPkg.cpp @@ -0,0 +1,830 @@ +#include "stdio.h" +#include "VfrFormPkg.h" + +/* + * The definition of CFormPkg's member function + */ + +SPendingAssign::SPendingAssign ( + IN INT8 *Key, + IN VOID *Addr, + IN UINT32 Len, + IN UINT32 LineNo + ) +{ + if (Key != NULL) { + mKey = new INT8[strlen (Key) + 1]; + if (mKey != NULL) { + strcpy (mKey, Key); + } + } else { + mKey = NULL; + } + mAddr = Addr; + mLen = Len; + mFlag = PENDING; + mLineNo = LineNo; + mNext = NULL; +} + +SPendingAssign::~SPendingAssign ( + VOID + ) +{ + if (mKey != NULL) { + delete mKey; + } + mAddr = NULL; + mLen = 0; + mLineNo = 0; + mNext = NULL; +} + +VOID +SPendingAssign::SetAddrAndLen ( + IN VOID *Addr, + IN UINT32 LineNo + ) +{ + mAddr = Addr; + mLineNo = LineNo; +} + +VOID +SPendingAssign::AssignValue ( + IN VOID *Addr, + IN UINT32 Len + ) +{ + memcpy (mAddr, Addr, (mLen < Len ? mLen : Len)); + mFlag = ASSIGNED; +} + +INT8 * +SPendingAssign::GetKey ( + VOID + ) +{ + return mKey; +} + +CFormPkg::CFormPkg ( + IN UINT32 BufferSize = 4096 + ) +{ + CHAR8 *BufferStart; + CHAR8 *BufferEnd; + SBufferNode *Node; + + mPkgLength = 0; + mBufferNodeQueueHead = NULL; + mCurrBufferNode = NULL; + + Node = new SBufferNode; + if (Node == NULL) { + return ; + } + BufferStart = new CHAR8[BufferSize]; + if (BufferStart == NULL) { + return; + } + BufferEnd = BufferStart + BufferSize; + + memset (BufferStart, 0, BufferSize); + Node->mBufferStart = BufferStart; + Node->mBufferEnd = BufferEnd; + Node->mBufferFree = BufferStart; + Node->mNext = NULL; + + mBufferSize = BufferSize; + mBufferNodeQueueHead = Node; + mBufferNodeQueueTail = Node; + mCurrBufferNode = Node; +} + +CFormPkg::~CFormPkg () +{ + SBufferNode *pBNode; + SPendingAssign *pPNode; + + while (mBufferNodeQueueHead != NULL) { + pBNode = mBufferNodeQueueHead; + mBufferNodeQueueHead = mBufferNodeQueueHead->mNext; + if (pBNode->mBufferStart != NULL) { + delete pBNode->mBufferStart; + delete pBNode; + } + } + mBufferNodeQueueTail = NULL; + mCurrBufferNode = NULL; + + while (PendingAssignList != NULL) { + pPNode = PendingAssignList; + PendingAssignList = PendingAssignList->mNext; + delete pPNode; + } + PendingAssignList = NULL; +} + +CHAR8 * +CFormPkg::IfrBinBufferGet ( + IN UINT32 Len + ) +{ + CHAR8 *BinBuffer = NULL; + + if ((Len == 0) || (Len > mBufferSize)) { + return NULL; + } + + if ((mCurrBufferNode->mBufferFree + Len) <= mCurrBufferNode->mBufferEnd) { + BinBuffer = mCurrBufferNode->mBufferFree; + mCurrBufferNode->mBufferFree += Len; + } else { + SBufferNode *Node; + + Node = new SBufferNode; + if (Node == NULL) { + return NULL; + } + + Node->mBufferStart = new CHAR8[mBufferSize]; + if (Node->mBufferStart == NULL) { + delete Node; + return NULL; + } else { + memset (Node->mBufferStart, 0, mBufferSize); + Node->mBufferEnd = Node->mBufferStart + mBufferSize; + Node->mBufferFree = Node->mBufferStart; + Node->mNext = NULL; + } + + if (mBufferNodeQueueTail == NULL) { + mBufferNodeQueueHead = mBufferNodeQueueTail = Node; + } else { + mBufferNodeQueueTail->mNext = Node; + mBufferNodeQueueTail = Node; + } + mCurrBufferNode = Node; + + // + // Now try again. + // + BinBuffer = mCurrBufferNode->mBufferFree; + mCurrBufferNode->mBufferFree += Len; + } + + mPkgLength += Len; + + return BinBuffer; +} + +inline +UINT32 +CFormPkg::GetPkgLength ( + VOID + ) +{ + return mPkgLength; +} + +VOID +CFormPkg::Open ( + VOID + ) +{ + mReadBufferNode = mBufferNodeQueueHead; + mReadBufferOffset = 0; +} + +VOID +CFormPkg::Close ( + VOID + ) +{ + mReadBufferNode = NULL; + mReadBufferOffset = 0; +} + +UINT32 +CFormPkg::Read ( + IN CHAR8 *Buffer, + IN UINT32 Size + ) +{ + UINT32 Index; + + if ((Size == 0) || (Buffer == NULL)) { + return 0; + } + + if (mReadBufferNode == NULL) { + return 0; + } + + for (Index = 0; Index < Size; Index++) { + if ((mReadBufferNode->mBufferStart + mReadBufferOffset) < mReadBufferNode->mBufferFree) { + Buffer[Index] = mReadBufferNode->mBufferStart[mReadBufferOffset++]; + } else { + if ((mReadBufferNode = mReadBufferNode->mNext) == NULL) { + return Index; + } else { + mReadBufferOffset = 0; + Buffer[Index] = mReadBufferNode->mBufferStart[mReadBufferOffset++]; + } + } + } + + return Size; +} + +EFI_VFR_RETURN_CODE +CFormPkg::BuildPkgHdr ( + OUT EFI_HII_PACKAGE_HEADER **PkgHdr + ) +{ + if (PkgHdr == NULL) { + return VFR_RETURN_FATAL_ERROR; + } + + if (((*PkgHdr) = new EFI_HII_PACKAGE_HEADER) == NULL) { + return VFR_RETURN_OUT_FOR_RESOURCES; + } + + (*PkgHdr)->Type = EFI_HII_PACKAGE_FORM; + (*PkgHdr)->Length = mPkgLength + sizeof (EFI_HII_PACKAGE_HEADER); + return VFR_RETURN_SUCCESS; +} + +EFI_VFR_RETURN_CODE +CFormPkg::BuildPkg ( + IN FILE *Output + ) +{ + EFI_VFR_RETURN_CODE Ret; + CHAR8 Buffer[1024]; + UINT32 Size; + EFI_HII_PACKAGE_HEADER *PkgHdr; + + if (Output == NULL) { + return VFR_RETURN_FATAL_ERROR; + } + + if ((Ret = BuildPkgHdr(&PkgHdr)) != VFR_RETURN_SUCCESS) { + return Ret; + } + fwrite (PkgHdr, sizeof (EFI_HII_PACKAGE_HEADER), 1, Output); + delete PkgHdr; + + Open (); + while ((Size = Read (Buffer, 1024)) != 0) { + fwrite (Buffer, Size, 1, Output); + } + Close (); + + return VFR_RETURN_SUCCESS; +} + +VOID +CFormPkg::_WRITE_PKG_LINE ( + IN FILE *pFile, + IN UINT32 LineBytes, + IN INT8 *LineHeader, + IN INT8 *BlkBuf, + IN UINT32 BlkSize + ) +{ + UINT32 Index; + + if ((pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) { + return; + } + + for (Index = 0; Index < BlkSize; Index++) { + if ((Index % LineBytes) == 0) { + fprintf (pFile, "\n%s", LineHeader); + } + fprintf (pFile, "0x%02X, ", (UINT8)BlkBuf[Index]); + } +} + +VOID +CFormPkg::_WRITE_PKG_END ( + IN FILE *pFile, + IN UINT32 LineBytes, + IN INT8 *LineHeader, + IN INT8 *BlkBuf, + IN UINT32 BlkSize + ) +{ + UINT32 Index; + + if ((BlkSize == 0) || (pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) { + return; + } + + for (Index = 0; Index < BlkSize - 1; Index++) { + if ((Index % LineBytes) == 0) { + fprintf (pFile, "\n%s", LineHeader); + } + fprintf (pFile, "0x%02X, ", (UINT8)BlkBuf[Index]); + } + + if ((Index % LineBytes) == 0) { + fprintf (pFile, "\n%s", LineHeader); + } + fprintf (pFile, "0x%02X\n", (UINT8)BlkBuf[Index]); +} + +#define BYTES_PRE_LINE 0x10 + +EFI_VFR_RETURN_CODE +CFormPkg::GenCFile ( + IN INT8 *BaseName, + IN FILE *pFile + ) +{ + EFI_VFR_RETURN_CODE Ret; + INT8 Buffer[BYTES_PRE_LINE * 8]; + EFI_HII_PACKAGE_HEADER *PkgHdr; + UINT32 PkgLength = 0; + UINT32 ReadSize = 0; + + if ((BaseName == NULL) || (pFile == NULL)) { + return VFR_RETURN_FATAL_ERROR; + } + + fprintf (pFile, "\nunsigned char %sBin[] = {\n", BaseName); + + if ((Ret = BuildPkgHdr(&PkgHdr)) != VFR_RETURN_SUCCESS) { + return Ret; + } + + fprintf (pFile, " // ARRAY LENGTH\n"); + PkgLength = PkgHdr->Length + sizeof (UINT32); + _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, " ", (INT8 *)&PkgLength, sizeof (UINT32)); + + fprintf (pFile, "\n\n // PACKAGE HEADER\n"); + _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, " ", (INT8 *)PkgHdr, sizeof (EFI_HII_PACKAGE_HEADER)); + PkgLength = sizeof (EFI_HII_PACKAGE_HEADER); + + fprintf (pFile, "\n\n // PACKAGE DATA\n"); + Open (); + while ((ReadSize = Read ((CHAR8 *)Buffer, BYTES_PRE_LINE * 8)) != 0) { + PkgLength += ReadSize; + if (PkgLength < PkgHdr->Length) { + _WRITE_PKG_LINE (pFile, BYTES_PRE_LINE, " ", Buffer, ReadSize); + } else { + _WRITE_PKG_END (pFile, BYTES_PRE_LINE, " ", Buffer, ReadSize); + } + } + Close (); + + delete PkgHdr; + fprintf (pFile, "\n};\n"); + + return VFR_RETURN_SUCCESS; +} + +EFI_VFR_RETURN_CODE +CFormPkg::AssignPending ( + IN INT8 *Key, + IN VOID *ValAddr, + IN UINT32 ValLen, + IN UINT32 LineNo + ) +{ + SPendingAssign *pNew; + + pNew = new SPendingAssign (Key, ValAddr, ValLen, LineNo); + if (pNew == NULL) { + return VFR_RETURN_OUT_FOR_RESOURCES; + } + + pNew->mNext = PendingAssignList; + PendingAssignList = pNew; + return VFR_RETURN_SUCCESS; +} + +VOID +CFormPkg::DoPendingAssign ( + IN INT8 *Key, + IN VOID *ValAddr, + IN UINT32 ValLen + ) +{ + SPendingAssign *pNode; + + if ((Key == NULL) || (ValAddr == NULL)) { + return; + } + + for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) { + if (strcmp (pNode->mKey, Key) == 0) { + pNode->AssignValue (ValAddr, ValLen); + } + } +} + +bool +CFormPkg::HavePendingUnassigned ( + VOID + ) +{ + SPendingAssign *pNode; + + for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) { + if (pNode->mFlag == PENDING) { + return TRUE; + } + } + + return FALSE; +} + +VOID +CFormPkg::PendingAssignPrintAll ( + VOID + ) +{ + SPendingAssign *pNode; + + for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) { + if (pNode->mFlag == PENDING) { + gCVfrErrorHandle.PrintError (pNode->mLineNo, pNode->mKey, "can not assign value because not defined"); + } + } +} + +CFormPkg gCFormPkg; + +SIfrRecord::SIfrRecord ( + VOID + ) +{ + mIfrBinBuf = NULL; + mBinBufLen = 0; + mLineNo = 0xFFFFFFFF; + mOffset = 0xFFFFFFFF; + mNext = NULL; +} + +SIfrRecord::~SIfrRecord ( + VOID + ) +{ + if (mIfrBinBuf != NULL) { + delete mIfrBinBuf; + mIfrBinBuf = NULL; + } + mLineNo = 0xFFFFFFFF; + mOffset = 0xFFFFFFFF; + mBinBufLen = 0; + mNext = NULL; +} + +CIfrRecordInfoDB::CIfrRecordInfoDB ( + VOID + ) +{ + mSwitch = FALSE; + mRecordCount = EFI_IFR_RECORDINFO_IDX_START; + mIfrRecordListHead = NULL; + mIfrRecordListTail = NULL; +} + +CIfrRecordInfoDB::~CIfrRecordInfoDB ( + VOID + ) +{ + SIfrRecord *pNode; + + while (mIfrRecordListHead != NULL) { + pNode = mIfrRecordListHead; + mIfrRecordListHead = mIfrRecordListHead->mNext; + delete pNode; + } +} + +SIfrRecord * +CIfrRecordInfoDB::GetRecordInfoFromIdx ( + IN UINT32 RecordIdx + ) +{ + UINT32 Idx; + SIfrRecord *pNode = NULL; + + if (RecordIdx == EFI_IFR_RECORDINFO_IDX_INVALUD) { + return NULL; + } + + for (Idx = (EFI_IFR_RECORDINFO_IDX_START + 1), pNode = mIfrRecordListHead; + (Idx != RecordIdx) && (pNode != NULL); + Idx++, pNode = pNode->mNext) + ; + + return pNode; +} + +UINT32 +CIfrRecordInfoDB::IfrRecordRegister ( + IN UINT32 LineNo, + IN CHAR8 *IfrBinBuf, + IN UINT8 BinBufLen, + IN UINT32 Offset + ) +{ + SIfrRecord *pNew; + + if (mSwitch == FALSE) { + return EFI_IFR_RECORDINFO_IDX_INVALUD; + } + + if ((pNew = new SIfrRecord) == NULL) { + return EFI_IFR_RECORDINFO_IDX_INVALUD; + } + + if (mIfrRecordListHead == NULL) { + mIfrRecordListHead = pNew; + mIfrRecordListTail = pNew; + } else { + mIfrRecordListTail->mNext = pNew; + mIfrRecordListTail = pNew; + } + mRecordCount++; + + return mRecordCount; +} + +VOID +CIfrRecordInfoDB::IfrRecordInfoUpdate ( + IN UINT32 RecordIdx, + IN UINT32 LineNo, + IN CHAR8 *BinBuf, + IN UINT8 BinBufLen, + IN UINT32 Offset + ) +{ + SIfrRecord *pNode; + + if ((pNode = GetRecordInfoFromIdx (RecordIdx)) == NULL) { + return; + } + + pNode->mLineNo = LineNo; + pNode->mOffset = Offset; + pNode->mBinBufLen = BinBufLen; + if (BinBuf != NULL) { + if (pNode->mIfrBinBuf != NULL) { + delete pNode->mIfrBinBuf; + } + pNode->mIfrBinBuf = new CHAR8[BinBufLen]; + if (pNode->mIfrBinBuf != NULL) { + memcpy (pNode->mIfrBinBuf, BinBuf, BinBufLen); + } + } +} + +VOID +CIfrRecordInfoDB::IfrRecordOutput ( + IN FILE *File, + IN UINT32 LineNo + ) +{ + SIfrRecord *pNode; + UINT8 Index; + + if (mSwitch == FALSE) { + return; + } + + if (File == NULL) { + return; + } + + for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) { + if (pNode->mLineNo == LineNo) { + fprintf (File, ">%08X: ", pNode->mOffset); + if (pNode->mIfrBinBuf != NULL) { + for (Index = 0; Index < pNode->mBinBufLen; Index++) { + fprintf (File, "%02X ", pNode->mIfrBinBuf[Index]); + } + } + fprintf (File, "\n"); + } + } +} + +CIfrRecordInfoDB gCIfrRecordInfoDB; + +VOID +CIfrObj::_EMIT_PENDING_OBJ ( + VOID + ) +{ + CHAR8 *ObjBinBuf = NULL; + + ObjBinBuf = gCFormPkg.IfrBinBufferGet (mObjBinLen); + if (ObjBinBuf != NULL) { + memcpy (ObjBinBuf, mObjBinBuf, mObjBinLen); + } + + if (mObjBinBuf != NULL) { + delete mObjBinBuf; + } +} + +/* + * The definition of CIfrObj's member function + */ +static struct { + UINT8 mSize; + UINT8 mScope; +} gOpcodeSizesScopeTable[] = { + { 0, 0 }, // EFI_IFR_INVALID - 0x00 + { sizeof (EFI_IFR_FORM), 1 }, // EFI_IFR_FORM_OP + { sizeof (EFI_IFR_SUBTITLE), 1 }, // EFI_IFR_SUBTITLE_OP + { sizeof (EFI_IFR_TEXT), 0 }, // EFI_IFR_TEXT_OP + { sizeof (EFI_IFR_IMAGE), 0 }, // EFI_IFR_IMAGE_OP + { sizeof (EFI_IFR_ONE_OF), 1 }, // EFI_IFR_ONE_OF_OP - 0x05 + { sizeof (EFI_IFR_CHECKBOX), 1}, // EFI_IFR_CHECKBOX_OP + { sizeof (EFI_IFR_NUMERIC), 1 }, // EFI_IFR_NUMERIC_OP + { sizeof (EFI_IFR_PASSWORD), 1 }, // EFI_IFR_PASSWORD_OP + { sizeof (EFI_IFR_ONE_OF_OPTION), 0 }, // EFI_IFR_ONE_OF_OPTION_OP + { sizeof (EFI_IFR_SUPPRESS_IF), 1 }, // EFI_IFR_SUPPRESS_IF - 0x0A + { sizeof (EFI_IFR_LOCKED), 0 }, // EFI_IFR_LOCKED_OP + { sizeof (EFI_IFR_ACTION), 1 }, // EFI_IFR_ACTION_OP + { sizeof (EFI_IFR_RESET_BUTTON), 1 }, // EFI_IFR_RESET_BUTTON_OP + { sizeof (EFI_IFR_FORM_SET), 1 }, // EFI_IFR_FORM_SET_OP -0xE + { sizeof (EFI_IFR_REF), 0 }, // EFI_IFR_REF_OP + { sizeof (EFI_IFR_NO_SUBMIT_IF), 1}, // EFI_IFR_NO_SUBMIT_IF_OP -0x10 + { sizeof (EFI_IFR_INCONSISTENT_IF), 1 }, // EFI_IFR_INCONSISTENT_IF_OP + { sizeof (EFI_IFR_EQ_ID_VAL), 0 }, // EFI_IFR_EQ_ID_VAL_OP + { sizeof (EFI_IFR_EQ_ID_ID), 0 }, // EFI_IFR_EQ_ID_ID_OP + { sizeof (EFI_IFR_EQ_ID_LIST), 0 }, // EFI_IFR_EQ_ID_LIST_OP - 0x14 + { sizeof (EFI_IFR_AND), 0 }, // EFI_IFR_AND_OP + { sizeof (EFI_IFR_OR), 0 }, // EFI_IFR_OR_OP + { sizeof (EFI_IFR_NOT), 0 }, // EFI_IFR_NOT_OP + { sizeof (EFI_IFR_RULE), 1 }, // EFI_IFR_RULE_OP + { sizeof (EFI_IFR_GRAY_OUT_IF), 1 }, // EFI_IFR_GRAYOUT_IF_OP - 0x19 + { sizeof (EFI_IFR_DATE), 1 }, // EFI_IFR_DATE_OP + { sizeof (EFI_IFR_TIME), 1 }, // EFI_IFR_TIME_OP + { sizeof (EFI_IFR_STRING), 1 }, // EFI_IFR_STRING_OP + { sizeof (EFI_IFR_REFRESH), 1 }, // EFI_IFR_REFRESH_OP + { sizeof (EFI_IFR_DISABLE_IF), 1 }, // EFI_IFR_DISABLE_IF_OP - 0x1E + { 0, 0 }, // 0x1F + { sizeof (EFI_IFR_TO_LOWER), 0 }, // EFI_IFR_TO_LOWER_OP - 0x20 + { sizeof (EFI_IFR_TO_UPPER), 0 }, // EFI_IFR_TO_UPPER_OP - 0x21 + { 0, 0 }, // 0x22 + { sizeof (EFI_IFR_ORDERED_LIST), 1 }, // EFI_IFR_ORDERED_LIST_OP - 0x23 + { sizeof (EFI_IFR_VARSTORE), 0 }, // EFI_IFR_VARSTORE_OP + { sizeof (EFI_IFR_VARSTORE_NAME_VALUE), 0 }, // EFI_IFR_VARSTORE_NAME_VALUE_OP + { sizeof (EFI_IFR_VARSTORE_EFI), 0 }, // EFI_IFR_VARSTORE_EFI_OP + { sizeof (EFI_IFR_VARSTORE_DEVICE), 1 }, // EFI_IFR_VARSTORE_DEVICE_OP + { sizeof (EFI_IFR_VERSION), 0 }, // EFI_IFR_VERSION_OP - 0x28 + { sizeof (EFI_IFR_END), 0 }, // EFI_IFR_END_OP + { sizeof (EFI_IFR_MATCH), 1 }, // EFI_IFR_MATCH_OP - 0x2A + { 0, 0 }, { 0, 0} , { 0, 0} , { 0, 0} , // 0x2B ~ 0x2E + { sizeof (EFI_IFR_EQUAL), 0 }, // EFI_IFR_EQUAL_OP - 0x2F + { sizeof (EFI_IFR_NOT_EQUAL), 0 }, // EFI_IFR_NOT_EQUAL_OP + { sizeof (EFI_IFR_GREATER_THAN), 0 }, // EFI_IFR_GREATER_THAN_OP + { sizeof (EFI_IFR_GREATER_EQUAL), 0 }, // EFI_IFR_GREATER_EQUAL_OP + { sizeof (EFI_IFR_LESS_THAN), 0 }, // EFI_IFR_LESS_THAN_OP + { sizeof (EFI_IFR_LESS_EQUAL), 0 }, // EFI_IFR_LESS_EQUAL_OP - 0x34 + { sizeof (EFI_IFR_BITWISE_AND), 0 }, // EFI_IFR_BITWISE_AND_OP + { sizeof (EFI_IFR_BITWISE_OR), 0 }, // EFI_IFR_BITWISE_OR_OP + { sizeof (EFI_IFR_BITWISE_NOT), 0 }, // EFI_IFR_BITWISE_NOT_OP + { sizeof (EFI_IFR_SHIFT_LEFT), 0 }, // EFI_IFR_SHIFT_LEFT_OP + { sizeof (EFI_IFR_SHIFT_RIGHT), 0 }, // EFI_IFR_SHIFT_RIGHT_OP + { sizeof (EFI_IFR_ADD), 0 }, // EFI_IFR_ADD_OP - 0x3A + { sizeof (EFI_IFR_SUBTRACT), 0 }, // EFI_IFR_SUBTRACT_OP + { sizeof (EFI_IFR_MULTIPLY), 0 }, // EFI_IFR_MULTIPLY_OP + { sizeof (EFI_IFR_DIVIDE), 0 }, // EFI_IFR_DIVIDE_OP + { sizeof (EFI_IFR_MODULO), 0 }, // EFI_IFR_MODULO_OP - 0x3E + { sizeof (EFI_IFR_RULE_REF), 0 }, // EFI_IFR_RULE_REF_OP + { sizeof (EFI_IFR_QUESTION_REF1), 0 }, // EFI_IFR_QUESTION_REF1_OP + { sizeof (EFI_IFR_QUESTION_REF2), 0 }, // EFI_IFR_QUESTION_REF2_OP - 0x41 + { sizeof (EFI_IFR_UINT8), 0}, // EFI_IFR_UINT8 + { sizeof (EFI_IFR_UINT16), 0}, // EFI_IFR_UINT16 + { sizeof (EFI_IFR_UINT32), 0}, // EFI_IFR_UINT32 + { sizeof (EFI_IFR_UINT64), 0}, // EFI_IFR_UTNT64 + { sizeof (EFI_IFR_TRUE), 0 }, // EFI_IFR_TRUE_OP - 0x46 + { sizeof (EFI_IFR_FALSE), 0 }, // EFI_IFR_FALSE_OP + { sizeof (EFI_IFR_TO_UINT), 0 }, // EFI_IFR_TO_UINT_OP + { sizeof (EFI_IFR_TO_STRING), 0 }, // EFI_IFR_TO_STRING_OP + { sizeof (EFI_IFR_TO_BOOLEAN), 0 }, // EFI_IFR_TO_BOOLEAN_OP + { sizeof (EFI_IFR_MID), 0 }, // EFI_IFR_MID_OP + { sizeof (EFI_IFR_FIND), 0 }, // EFI_IFR_FIND_OP + { sizeof (EFI_IFR_TOKEN), 0 }, // EFI_IFR_TOKEN_OP + { sizeof (EFI_IFR_STRING_REF1), 0 }, // EFI_IFR_STRING_REF1_OP - 0x4E + { sizeof (EFI_IFR_STRING_REF2), 0 }, // EFI_IFR_STRING_REF2_OP + { sizeof (EFI_IFR_CONDITIONAL), 0 }, // EFI_IFR_CONDITIONAL_OP + { sizeof (EFI_IFR_QUESTION_REF3), 0 }, // EFI_IFR_QUESTION_REF3_OP + { sizeof (EFI_IFR_ZERO), 0 }, // EFI_IFR_ZERO_OP + { sizeof (EFI_IFR_ONE), 0 }, // EFI_IFR_ONE_OP + { sizeof (EFI_IFR_ONES), 0 }, // EFI_IFR_ONES_OP + { sizeof (EFI_IFR_UNDEFINED), 0 }, // EFI_IFR_UNDEFINED_OP + { sizeof (EFI_IFR_LENGTH), 0 }, // EFI_IFR_LENGTH_OP + { sizeof (EFI_IFR_DUP), 0 }, // EFI_IFR_DUP_OP - 0x57 + { sizeof (EFI_IFR_THIS), 0 }, // EFI_IFR_THIS_OP + { sizeof (EFI_IFR_SPAN), 0 }, // EFI_IFR_SPAN_OP + { sizeof (EFI_IFR_VALUE), 1 }, // EFI_IFR_VALUE_OP + { sizeof (EFI_IFR_DEFAULT), 0 }, // EFI_IFR_DEFAULT_OP + { sizeof (EFI_IFR_DEFAULTSTORE), 0 }, // EFI_IFR_DEFAULTSTORE_OP - 0x5C + { 0, 0}, // 0x5D + { sizeof (EFI_IFR_CATENATE), 0 }, // EFI_IFR_CATENATE_OP + { sizeof (EFI_IFR_GUID), 0 }, // EFI_IFR_GUID_OP +}; + +#ifdef CIFROBJ_DEUBG +static struct { + INT8 *mIfrName; +} gIfrObjPrintDebugTable[] = { + "EFI_IFR_INVALID", "EFI_IFR_FORM", "EFI_IFR_SUBTITLE", "EFI_IFR_TEXT", "EFI_IFR_IMAGE", "EFI_IFR_ONE_OF", + "EFI_IFR_CHECKBOX", "EFI_IFR_NUMERIC", "EFI_IFR_PASSWORD", "EFI_IFR_ONE_OF_OPTION", "EFI_IFR_SUPPRESS_IF", "EFI_IFR_LOCKED", + "EFI_IFR_ACTION", "EFI_IFR_RESET_BUTTON", "EFI_IFR_FORM_SET", "EFI_IFR_REF", "EFI_IFR_NO_SUBMIT_IF", "EFI_IFR_INCONSISTENT_IF", + "EFI_IFR_EQ_ID_VAL", "EFI_IFR_EQ_ID_ID", "EFI_IFR_EQ_ID_LIST", "EFI_IFR_AND", "EFI_IFR_OR", "EFI_IFR_NOT", + "EFI_IFR_RULE", "EFI_IFR_GRAY_OUT_IF", "EFI_IFR_DATE", "EFI_IFR_TIME", "EFI_IFR_STRING", "EFI_IFR_REFRESH", + "EFI_IFR_DISABLE_IF", "EFI_IFR_INVALID", "EFI_IFR_TO_LOWER", "EFI_IFR_TO_UPPER", "EFI_IFR_INVALID", "EFI_IFR_ORDERED_LIST", + "EFI_IFR_VARSTORE", "EFI_IFR_VARSTORE_NAME_VALUE", "EFI_IFR_VARSTORE_EFI", "EFI_IFR_VARSTORE_DEVICE", "EFI_IFR_VERSION", "EFI_IFR_END", + "EFI_IFR_MATCH", "EFI_IFR_INVALID", "EFI_IFR_INVALID", "EFI_IFR_INVALID", "EFI_IFR_INVALID", "EFI_IFR_EQUAL", + "EFI_IFR_NOT_EQUAL", "EFI_IFR_GREATER_THAN", "EFI_IFR_GREATER_EQUAL", "EFI_IFR_LESS_THAN", "EFI_IFR_LESS_EQUAL", "EFI_IFR_BITWISE_AND", + "EFI_IFR_BITWISE_OR", "EFI_IFR_BITWISE_NOT", "EFI_IFR_SHIFT_LEFT", "EFI_IFR_SHIFT_RIGHT", "EFI_IFR_ADD", "EFI_IFR_SUBTRACT", + "EFI_IFR_MULTIPLY", "EFI_IFR_DIVIDE", "EFI_IFR_MODULO", "EFI_IFR_RULE_REF", "EFI_IFR_QUESTION_REF1", "EFI_IFR_QUESTION_REF2", + "EFI_IFR_UINT8", "EFI_IFR_UINT16", "EFI_IFR_UINT32", "EFI_IFR_UINT64", "EFI_IFR_TRUE", "EFI_IFR_FALSE", + "EFI_IFR_TO_UINT", "EFI_IFR_TO_STRING", "EFI_IFR_TO_BOOLEAN", "EFI_IFR_MID", "EFI_IFR_FIND", "EFI_IFR_TOKEN", + "EFI_IFR_STRING_REF1","EFI_IFR_STRING_REF2", "EFI_IFR_CONDITIONAL", "EFI_IFR_QUESTION_REF3", "EFI_IFR_ZERO", "EFI_IFR_ONE", + "EFI_IFR_ONES", "EFI_IFR_UNDEFINED", "EFI_IFR_LENGTH", "EFI_IFR_DUP", "EFI_IFR_THIS", "EFI_IFR_SPAN", + "EFI_IFR_VALUE", "EFI_IFR_DEFAULT", "EFI_IFR_DEFAULTSTORE", "EFI_IFR_INVALID", "EFI_IFR_CATENATE", "EFI_IFR_GUID", +}; + +VOID +CIFROBJ_DEBUG_PRINT ( + IN UINT8 OpCode + ) +{ + printf ("======Create IFR [%s]\n", gIfrObjPrintDebugTable[OpCode].mIfrName); +} +#else + +#define CIFROBJ_DEBUG_PRINT(OpCode) + +#endif + +bool gCreateOp = TRUE; + +CIfrObj::CIfrObj ( + IN UINT8 OpCode, + OUT CHAR8 **IfrObj, + IN UINT8 ObjBinLen, + IN BOOLEAN DelayEmit + ) +{ + mDelayEmit = DelayEmit; + mPkgOffset = gCFormPkg.GetPkgLength (); + mObjBinLen = (ObjBinLen == 0) ? gOpcodeSizesScopeTable[OpCode].mSize : ObjBinLen; + mObjBinBuf = ((DelayEmit == FALSE) && (gCreateOp == TRUE)) ? gCFormPkg.IfrBinBufferGet (mObjBinLen) : new CHAR8[EFI_IFR_MAX_LENGTH]; + mRecordIdx = (gCreateOp == TRUE) ? gCIfrRecordInfoDB.IfrRecordRegister (0xFFFFFFFF, mObjBinBuf, mObjBinLen, mPkgOffset) : EFI_IFR_RECORDINFO_IDX_INVALUD; + + if (IfrObj != NULL) { + *IfrObj = mObjBinBuf; + } + + CIFROBJ_DEBUG_PRINT (OpCode); +} + +CIfrObj::~CIfrObj ( + VOID + ) +{ + if ((mDelayEmit == TRUE) && ((gCreateOp == TRUE))) { + _EMIT_PENDING_OBJ (); + } + + gCIfrRecordInfoDB.IfrRecordInfoUpdate (mRecordIdx, mLineNo, mObjBinBuf, mObjBinLen, mPkgOffset); +} + +/* + * The definition of CIfrObj's member function + */ +UINT8 gScopeCount = 0; + +CIfrOpHeader::CIfrOpHeader ( + IN UINT8 OpCode, + IN VOID *StartAddr, + IN UINT8 Length + ) : mHeader ((EFI_IFR_OP_HEADER *)StartAddr) +{ + mHeader->OpCode = OpCode; + mHeader->Length = (Length == 0) ? gOpcodeSizesScopeTable[OpCode].mSize : Length; + mHeader->Scope = (gOpcodeSizesScopeTable[OpCode].mScope + gScopeCount > 0) ? 1 : 0; +} + +CIfrOpHeader::CIfrOpHeader ( + IN CIfrOpHeader &OpHdr + ) +{ + mHeader = OpHdr.mHeader; +} + +UINT32 CIfrForm::FormIdBitMap[EFI_FREE_FORM_ID_BITMAP_SIZE] = {0, }; diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrFormPkg.h b/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrFormPkg.h new file mode 100644 index 0000000000..67afbdd369 --- /dev/null +++ b/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrFormPkg.h @@ -0,0 +1,2252 @@ +#ifndef _EFIIFRCLASS_H_ +#define _EFIIFRCLASS_H_ + +#include "string.h" +#include "EfiVfr.h" +#include "VfrError.h" +#include "VfrUtilityLib.h" + +/* + * The functions below are used for flags setting + */ +static inline BOOLEAN _FLAGS_ZERO ( + IN UINT8 &Flags + ) +{ + return Flags == 0; +} + +static inline VOID _FLAG_CLEAR ( + IN UINT8 &Flags, + IN UINT8 Mask + ) +{ + Flags &= (~Mask); +} + +static inline UINT8 _FLAG_TEST_AND_CLEAR ( + IN UINT8 &Flags, + IN UINT8 Mask + ) +{ + UINT8 Ret = Flags & Mask; + Flags &= (~Mask); + return Ret; +} + +static inline UINT8 _IS_EQUAL ( + IN UINT8 &Flags, + IN UINT8 Value + ) +{ + return Flags == Value; +} + +/* + * The definition of CIfrBin + */ +typedef enum { + PENDING, + ASSIGNED +} ASSIGN_FLAG; + +struct SPendingAssign { + INT8 *mKey; // key ! unique + VOID *mAddr; + UINT32 mLen; + ASSIGN_FLAG mFlag; + UINT32 mLineNo; + struct SPendingAssign *mNext; + + SPendingAssign (IN INT8 *, IN VOID *, IN UINT32, IN UINT32); + ~SPendingAssign (); + + VOID SetAddrAndLen (IN VOID *, IN UINT32); + VOID AssignValue (IN VOID *, IN UINT32); + INT8 * GetKey (VOID); +}; + +struct SBufferNode { + CHAR8 *mBufferStart; + CHAR8 *mBufferEnd; + CHAR8 *mBufferFree; + struct SBufferNode *mNext; +}; + +class CFormPkg { +private: + UINT32 mBufferSize; + SBufferNode *mBufferNodeQueueHead; + SBufferNode *mBufferNodeQueueTail; + SBufferNode *mCurrBufferNode; + + SBufferNode *mReadBufferNode; + UINT32 mReadBufferOffset; + + UINT32 mPkgLength; + + VOID _WRITE_PKG_LINE (IN FILE *, IN UINT32 , IN INT8 *, IN INT8 *, IN UINT32); + VOID _WRITE_PKG_END (IN FILE *, IN UINT32 , IN INT8 *, IN INT8 *, IN UINT32); + +private: + SPendingAssign *PendingAssignList; + +public: + CFormPkg (IN UINT32 BufferSize); + ~CFormPkg (); + + CHAR8 * IfrBinBufferGet (IN UINT32); + inline UINT32 GetPkgLength (VOID); + + VOID Open (); + UINT32 Read (IN CHAR8 *, IN UINT32); + VOID Close (); + + EFI_VFR_RETURN_CODE BuildPkgHdr (OUT EFI_HII_PACKAGE_HEADER **); + EFI_VFR_RETURN_CODE BuildPkg (IN FILE *); + EFI_VFR_RETURN_CODE GenCFile (IN INT8 *, IN FILE *); + +public: + EFI_VFR_RETURN_CODE AssignPending (IN INT8 *, IN VOID *, IN UINT32, IN UINT32); + VOID DoPendingAssign (IN INT8 *, IN VOID *, IN UINT32); + bool HavePendingUnassigned (VOID); + VOID PendingAssignPrintAll (VOID); +}; + +extern CFormPkg gCFormPkg; + +struct SIfrRecord { + UINT32 mLineNo; + CHAR8 *mIfrBinBuf; + UINT8 mBinBufLen; + UINT32 mOffset; + SIfrRecord *mNext; + + SIfrRecord (VOID); + ~SIfrRecord (VOID); +}; + +#define EFI_IFR_RECORDINFO_IDX_INVALUD 0xFFFFFF +#define EFI_IFR_RECORDINFO_IDX_START 0x0 + +class CIfrRecordInfoDB { +private: + bool mSwitch; + UINT32 mRecordCount; + SIfrRecord *mIfrRecordListHead; + SIfrRecord *mIfrRecordListTail; + + SIfrRecord * GetRecordInfoFromIdx (IN UINT32); +public: + CIfrRecordInfoDB (VOID); + ~CIfrRecordInfoDB (VOID); + + inline VOID TurnOn (VOID) { + mSwitch = TRUE; + } + + inline VOID TurnOff (VOID) { + mSwitch = FALSE; + } + + UINT32 IfrRecordRegister (IN UINT32, IN CHAR8 *, IN UINT8, IN UINT32); + VOID IfrRecordInfoUpdate (IN UINT32, IN UINT32, IN CHAR8*, IN UINT8, IN UINT32); + VOID IfrRecordOutput (IN FILE *, IN UINT32 LineNo); +}; + +extern CIfrRecordInfoDB gCIfrRecordInfoDB; + +/* + * The definition of CIfrObj + */ +extern bool gCreateOp; + +class CIfrObj { +private: + bool mDelayEmit; + + CHAR8 *mObjBinBuf; + UINT8 mObjBinLen; + UINT32 mLineNo; + UINT32 mRecordIdx; + UINT32 mPkgOffset; + + VOID _EMIT_PENDING_OBJ (VOID); + +public: + CIfrObj (IN UINT8 OpCode, OUT CHAR8 **IfrObj = NULL, IN UINT8 ObjBinLen = 0, IN BOOLEAN DelayEmit = FALSE); + virtual ~CIfrObj(VOID); + + inline VOID SetLineNo (IN UINT32 LineNo) { + mLineNo = LineNo; + } + + inline CHAR8 * GetObjBinAddr (VOID) { + return mObjBinBuf; + } + + inline UINT8 GetObjBinLen (VOID) { + return mObjBinLen; + } + + inline bool ExpendObjBin (IN UINT8 Size) { + if ((mDelayEmit == TRUE) && ((mObjBinLen + Size) > mObjBinLen)) { + mObjBinLen += Size; + return TRUE; + } else { + return FALSE; + } + } +}; + +/* + * The definition of CIfrOpHeader + */ +class CIfrOpHeader { +private: + EFI_IFR_OP_HEADER *mHeader; + +public: + CIfrOpHeader (IN UINT8 OpCode, IN VOID *StartAddr, IN UINT8 Length = 0); + CIfrOpHeader (IN CIfrOpHeader &); + + VOID IncLength (UINT8 Size) { + if ((mHeader->Length + Size) > mHeader->Length) { + mHeader->Length += Size; + } + } + + VOID DecLength (UINT8 Size) { + if (mHeader->Length >= Size) { + mHeader -= Size; + } + } + + UINT8 GetLength () { + return mHeader->Length; + } + + UINT8 GetScope () { + return mHeader->Scope; + } + + VOID SetScope (IN UINT8 Scope) { + mHeader->Scope = Scope; + } +}; + +extern UINT8 gScopeCount; + +/* + * The definition of CIfrStatementHeader + */ +class CIfrStatementHeader { +private: + EFI_IFR_STATEMENT_HEADER *mHeader; + +public: + CIfrStatementHeader ( + IN EFI_IFR_STATEMENT_HEADER *StartAddr + ) : mHeader ((EFI_IFR_STATEMENT_HEADER *)StartAddr) { + mHeader = StartAddr; + mHeader->Help = EFI_STRING_ID_INVALID; + mHeader->Prompt = EFI_STRING_ID_INVALID; + } + + EFI_IFR_STATEMENT_HEADER *GetStatementHeader () { + return mHeader; + } + + VOID SetPrompt (IN EFI_STRING_ID Prompt) { + mHeader->Prompt = Prompt; + } + + VOID SetHelp (IN EFI_STRING_ID Help) { + mHeader->Help = Help; + } +}; + +/* + * The definition of CIfrQuestionHeader + */ +#define EFI_IFR_QUESTION_FLAG_DEFAULT 0 + +class CIfrQuestionHeader : public CIfrStatementHeader { +private: + EFI_IFR_QUESTION_HEADER *mHeader; + + EFI_IFR_STATEMENT_HEADER * QH2SH (EFI_IFR_QUESTION_HEADER *Qheader) { + return &(Qheader)->Header; + } + +public: + EFI_QUESTION_ID QUESTION_ID (VOID) { + return mHeader->QuestionId; + } + + EFI_VARSTORE_ID VARSTORE_ID (VOID) { + return mHeader->VarStoreId; + } + + VOID VARSTORE_INFO (OUT EFI_VARSTORE_INFO *Info) { + if (Info != NULL) { + Info->mVarStoreId = mHeader->VarStoreId; + memcpy (&Info->mVarStoreId, &mHeader->VarStoreInfo, sizeof (Info->mVarStoreId)); + } + } + + UINT8 FLAGS (VOID) { + return mHeader->Flags; + } + +public: + CIfrQuestionHeader ( + IN EFI_IFR_QUESTION_HEADER *StartAddr, + IN UINT8 Flags = EFI_IFR_QUESTION_FLAG_DEFAULT + ) : CIfrStatementHeader (QH2SH(StartAddr)) { + mHeader = StartAddr; + mHeader->QuestionId = EFI_QUESTION_ID_INVALID; + mHeader->VarStoreId = EFI_VARSTORE_ID_INVALID; + mHeader->VarStoreInfo.VarName = EFI_STRING_ID_INVALID; + mHeader->VarStoreInfo.VarOffset = EFI_VAROFFSET_INVALID; + mHeader->Flags = Flags; + } + + VOID SetQuestionId (IN EFI_QUESTION_ID QuestionId) { + mHeader->QuestionId = QuestionId; + } + + VOID SetVarStoreInfo (IN EFI_VARSTORE_INFO *Info) { + mHeader->VarStoreId = Info->mVarStoreId; + mHeader->VarStoreInfo.VarName = Info->mInfo.mVarName; + mHeader->VarStoreInfo.VarOffset = Info->mInfo.mVarOffset; + } + + EFI_VFR_RETURN_CODE SetFlags (IN UINT8 Flags) { + if (_FLAG_TEST_AND_CLEAR (Flags, EFI_IFR_FLAG_READ_ONLY)) { + mHeader->Flags |= EFI_IFR_FLAG_READ_ONLY; + } + + _FLAG_CLEAR (Flags, 0x02); + + if (_FLAG_TEST_AND_CLEAR (Flags, EFI_IFR_FLAG_CALLBACK)) { + mHeader->Flags |= EFI_IFR_FLAG_CALLBACK; + } + + _FLAG_CLEAR (Flags, 0x08); + + if (_FLAG_TEST_AND_CLEAR (Flags, EFI_IFR_FLAG_RESET_REQUIRED)) { + mHeader->Flags |= EFI_IFR_FLAG_RESET_REQUIRED; + } + + _FLAG_CLEAR (Flags, 0x20); + + if (_FLAG_TEST_AND_CLEAR (Flags, EFI_IFR_FLAG_OPTIONS_ONLY)) { + mHeader->Flags |= EFI_IFR_FLAG_OPTIONS_ONLY; + } + + return _FLAGS_ZERO (Flags) ? VFR_RETURN_SUCCESS : VFR_RETURN_FLAGS_UNSUPPORTED; + } +}; + +static CIfrQuestionHeader *gCurrentQuestion = NULL; + +/* + * The definition of CIfrMinMaxStepData + */ +class CIfrMinMaxStepData { +private: + MINMAXSTEP_DATA *mMinMaxStepData; + +public: + CIfrMinMaxStepData (MINMAXSTEP_DATA *DataAddr) : mMinMaxStepData (DataAddr) { + mMinMaxStepData->u64.MinValue = 0; + mMinMaxStepData->u64.MaxValue = 0; + mMinMaxStepData->u64.Step = 0; + } + + VOID SetMinMaxStepData (IN UINT64 MinValue, IN UINT64 MaxValue, IN UINT64 Step) { + mMinMaxStepData->u64.MinValue = MinValue; + mMinMaxStepData->u64.MaxValue = MaxValue; + mMinMaxStepData->u64.Step = Step; + } + + VOID SetMinMaxStepData (IN UINT32 MinValue, IN UINT32 MaxValue, IN UINT32 Step) { + mMinMaxStepData->u32.MinValue = MinValue; + mMinMaxStepData->u32.MaxValue = MaxValue; + mMinMaxStepData->u32.Step = Step; + } + + VOID SetMinMaxStepData (IN UINT16 MinValue, IN UINT16 MaxValue, IN UINT16 Step) { + mMinMaxStepData->u16.MinValue = MinValue; + mMinMaxStepData->u16.MaxValue = MaxValue; + mMinMaxStepData->u16.Step = Step; + } + + VOID SetMinMaxStepData (IN UINT8 MinValue, IN UINT8 MaxValue, IN UINT8 Step) { + mMinMaxStepData->u8.MinValue = MinValue; + mMinMaxStepData->u8.MaxValue = MaxValue; + mMinMaxStepData->u8.Step = Step; + } + +}; + +/* + * The definition of all of the UEFI IFR Objects + */ +class CIfrFormSet : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_FORM_SET *mFormSet; + +public: + CIfrFormSet () : CIfrObj (EFI_IFR_FORM_SET_OP, (CHAR8 **)&mFormSet), + CIfrOpHeader (EFI_IFR_FORM_SET_OP, &mFormSet->Header) { + mFormSet->Help = EFI_STRING_ID_INVALID; + mFormSet->FormSetTitle = EFI_STRING_ID_INVALID; + memset (&mFormSet->Guid, 0, sizeof (EFI_GUID)); + } + + VOID SetGuid (IN EFI_GUID *Guid) { + memcpy (&mFormSet->Guid, Guid, sizeof (EFI_GUID)); + } + + VOID SetFormSetTitle (IN EFI_STRING_ID FormSetTitle) { + mFormSet->FormSetTitle = FormSetTitle; + } + + VOID SetHelp (IN EFI_STRING_ID Help) { + mFormSet->Help = Help; + } +}; + +class CIfrEnd : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_END *mEnd; + +public: + CIfrEnd () : CIfrObj (EFI_IFR_END_OP, (CHAR8 **)&mEnd), + CIfrOpHeader (EFI_IFR_END_OP, &mEnd->Header) {} +}; + +class CIfrDefaultStore : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_DEFAULTSTORE *mDefaultStore; + +public: + CIfrDefaultStore () : CIfrObj (EFI_IFR_DEFAULTSTORE_OP, (CHAR8 **)&mDefaultStore), + CIfrOpHeader (EFI_IFR_DEFAULTSTORE_OP, &mDefaultStore->Header) { + mDefaultStore->DefaultId = EFI_VARSTORE_ID_INVALID; + mDefaultStore->DefaultName = EFI_STRING_ID_INVALID; + } + + VOID SetDefaultName (IN EFI_STRING_ID DefaultName) { + mDefaultStore->DefaultName = DefaultName; + } + + VOID SetDefaultId (IN UINT16 DefaultId) { + mDefaultStore->DefaultId = DefaultId; + } +}; + +#define EFI_FORM_ID_MAX 0xFFFF +#define EFI_FREE_FORM_ID_BITMAP_SIZE ((EFI_FORM_ID_MAX + 1) / EFI_BITS_PER_UINT32) + +class CIfrForm : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_FORM *mForm; + + STATIC UINT32 FormIdBitMap[EFI_FREE_FORM_ID_BITMAP_SIZE]; + + STATIC BOOLEAN ChekFormIdFree (IN EFI_FORM_ID FormId) { + UINT32 Index = (FormId / EFI_BITS_PER_UINT32); + UINT32 Offset = (FormId % EFI_BITS_PER_UINT32); + + return (FormIdBitMap[Index] & (0x80000000 >> Offset)) == 0; + } + + STATIC VOID MarkFormIdUsed (IN EFI_FORM_ID FormId) { + UINT32 Index = (FormId / EFI_BITS_PER_UINT32); + UINT32 Offset = (FormId % EFI_BITS_PER_UINT32); + + FormIdBitMap[Index] |= (0x80000000 >> Offset); + } + +public: + CIfrForm () : CIfrObj (EFI_IFR_FORM_OP, (CHAR8 **)&mForm), + CIfrOpHeader (EFI_IFR_FORM_OP, &mForm->Header) { + mForm->FormId = 0; + mForm->FormTitle = EFI_STRING_ID_INVALID; + } + + EFI_VFR_RETURN_CODE SetFormId (IN EFI_FORM_ID FormId) { + if (CIfrForm::ChekFormIdFree (FormId) == FALSE) { + return VFR_RETURN_FORMID_REDEFINED; + } + mForm->FormId = FormId; + CIfrForm::MarkFormIdUsed (FormId); + return VFR_RETURN_SUCCESS; + } + + VOID SetFormTitle (IN EFI_STRING_ID FormTitle) { + mForm->FormTitle = FormTitle; + } +}; + +class CIfrVarStore : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_VARSTORE *mVarStore; + +public: + CIfrVarStore () : CIfrObj (EFI_IFR_VARSTORE_OP, (CHAR8 **)&mVarStore, sizeof (EFI_IFR_VARSTORE), TRUE), + CIfrOpHeader (EFI_IFR_VARSTORE_OP, &mVarStore->Header) { + mVarStore->VarStoreId = EFI_VARSTORE_ID_INVALID; + mVarStore->Size = 0; + memset (&mVarStore->Guid, 0, sizeof (EFI_GUID)); + mVarStore->Name[0] = '\0'; + } + + VOID SetGuid (IN EFI_GUID *Guid) { + memcpy (&mVarStore->Guid, Guid, sizeof (EFI_GUID)); + } + + VOID SetVarStoreId (IN EFI_VARSTORE_ID VarStoreId) { + mVarStore->VarStoreId = VarStoreId; + } + + VOID SetSize (IN UINT16 Size) { + mVarStore->Size = Size; + } + + VOID SetName (IN INT8 *Name) { + UINT8 Len; + + if (Name != NULL) { + Len = strlen (Name); + if (Len != 0) { + if (ExpendObjBin (Len) == TRUE) { + IncLength (Len); + strcpy ((INT8 *)(mVarStore->Name), Name); + } + } + } + } +}; + +class CIfrVarStoreEfi : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_VARSTORE_EFI *mVarStoreEfi; + +public: + CIfrVarStoreEfi () : CIfrObj (EFI_IFR_VARSTORE_EFI_OP, (CHAR8 **)&mVarStoreEfi), + CIfrOpHeader (EFI_IFR_VARSTORE_EFI_OP, &mVarStoreEfi->Header) { + mVarStoreEfi->VarStoreId = EFI_VAROFFSET_INVALID; + memset (&mVarStoreEfi->Guid, 0, sizeof (EFI_GUID)); + } + + VOID SetGuid (IN EFI_GUID *Guid) { + memcpy (&mVarStoreEfi->Guid, Guid, sizeof (EFI_GUID)); + } + + VOID SetVarStoreId (IN UINT16 VarStoreId) { + mVarStoreEfi->VarStoreId = VarStoreId; + } + + VOID SetAttributes (IN UINT32 Attributes) { + mVarStoreEfi->Attributes = Attributes; + } +}; + +class CIfrVarStoreNameValue : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_VARSTORE_NAME_VALUE *mVarStoreNameValue; + +public: + CIfrVarStoreNameValue () : CIfrObj (EFI_IFR_VARSTORE_NAME_VALUE_OP, (CHAR8 **)&mVarStoreNameValue), + CIfrOpHeader (EFI_IFR_VARSTORE_NAME_VALUE_OP, &mVarStoreNameValue->Header) { + mVarStoreNameValue->VarStoreId = EFI_VAROFFSET_INVALID; + memset (&mVarStoreNameValue->Guid, 0, sizeof (EFI_GUID)); + } + + VOID SetGuid (IN EFI_GUID *Guid) { + memcpy (&mVarStoreNameValue->Guid, Guid, sizeof (EFI_GUID)); + } + + VOID SetVarStoreId (IN UINT16 VarStoreId) { + mVarStoreNameValue->VarStoreId = VarStoreId; + } +}; + +class CIfrImage : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_IMAGE *mImage; + +public: + CIfrImage () : CIfrObj (EFI_IFR_IMAGE_OP, (CHAR8 **)&mImage), + CIfrOpHeader (EFI_IFR_FORM_OP, &mImage->Header) { + mImage->Id = EFI_IMAGE_ID_INVALID; + } + + VOID SetImageId (IN EFI_IMAGE_ID ImageId) { + mImage->Id = ImageId; + } +}; + +class CIfrLocked : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_LOCKED *mLocked; + +public: + CIfrLocked () : CIfrObj (EFI_IFR_LOCKED_OP, (CHAR8 **)&mLocked), + CIfrOpHeader (EFI_IFR_LOCKED_OP, &mLocked->Header) {} +}; + +class CIfrRule : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_RULE *mRule; + +public: + CIfrRule () : CIfrObj (EFI_IFR_RULE_OP, (CHAR8 **)&mRule), + mRule ((EFI_IFR_RULE *)GetObjBinAddr()), + CIfrOpHeader (EFI_IFR_RULE_OP, &mRule->Header) { + mRule->RuleId = EFI_RULE_ID_INVALID; + } + + VOID SetRuleId (IN UINT8 RuleId) { + mRule->RuleId = RuleId; + } +}; + +static EFI_IFR_TYPE_VALUE gZeroEfiIfrTypeValue = {0, }; + +class CIfrDefault : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_DEFAULT *mDefault; + +public: + CIfrDefault ( + IN UINT16 DefaultId = EFI_HII_DEFAULT_CLASS_STANDARD, + IN UINT8 Type = EFI_IFR_TYPE_OTHER, + IN EFI_IFR_TYPE_VALUE Value = gZeroEfiIfrTypeValue + ) : CIfrObj (EFI_IFR_DEFAULT_OP, (CHAR8 **)&mDefault), + CIfrOpHeader (EFI_IFR_DEFAULT_OP, &mDefault->Header) { + mDefault->Type = Type; + mDefault->Value = Value; + mDefault->DefaultId = DefaultId; + } + + VOID SetDefaultId (IN UINT16 DefaultId) { + mDefault->DefaultId = DefaultId; + } + + VOID SetType (IN UINT8 Type) { + mDefault->Type = Type; + } + + VOID SetValue (IN EFI_IFR_TYPE_VALUE Value) { + mDefault->Value = Value; + } +}; + +class CIfrValue : public CIfrObj, public CIfrOpHeader{ +private: + EFI_IFR_VALUE *mValue; + +public: + CIfrValue () : CIfrObj (EFI_IFR_VALUE_OP, (CHAR8 **)&mValue), + CIfrOpHeader (EFI_IFR_VALUE_OP, &mValue->Header) {} + +}; + +class CIfrSubtitle : public CIfrObj, public CIfrOpHeader, public CIfrStatementHeader { +private: + EFI_IFR_SUBTITLE *mSubtitle; + +public: + CIfrSubtitle () : CIfrObj (EFI_IFR_SUBTITLE_OP, (CHAR8 **)&mSubtitle), + CIfrOpHeader (EFI_IFR_SUBTITLE_OP, &mSubtitle->Header), + CIfrStatementHeader (&mSubtitle->Statement) { + mSubtitle->Flags = 0; + } + + EFI_VFR_RETURN_CODE SetFlags (IN UINT8 LFlags) { + if (_FLAG_TEST_AND_CLEAR (LFlags, EFI_IFR_FLAGS_HORIZONTAL)) { + mSubtitle->Flags |= EFI_IFR_FLAGS_HORIZONTAL; + } + + return _FLAGS_ZERO (LFlags) ? VFR_RETURN_SUCCESS : VFR_RETURN_FLAGS_UNSUPPORTED; + } +}; + +class CIfrText : public CIfrObj, public CIfrOpHeader, public CIfrStatementHeader { +private: + EFI_IFR_TEXT *mText; + +public: + CIfrText () : CIfrObj (EFI_IFR_TEXT_OP, (CHAR8 **)&mText), + CIfrOpHeader (EFI_IFR_TEXT_OP, &mText->Header), + CIfrStatementHeader (&mText->Statement) { + mText->TextTwo = EFI_STRING_ID_INVALID; + } + + VOID SetTextTwo (IN EFI_STRING_ID StringId) { + mText->TextTwo = StringId; + } +}; + +class CIfrRef : public CIfrObj, public CIfrOpHeader, public CIfrQuestionHeader { +private: + EFI_IFR_REF *mRef; + +public: + CIfrRef () : CIfrObj (EFI_IFR_REF_OP, (CHAR8 **)&mRef), + CIfrOpHeader (EFI_IFR_REF_OP, &mRef->Header), + CIfrQuestionHeader (&mRef->Question) { + mRef->FormId = 0; + } + + VOID SetFormId (IN EFI_FORM_ID FormId) { + mRef->FormId = FormId; + } +}; + +class CIfrRef2 : public CIfrObj, public CIfrOpHeader, public CIfrQuestionHeader { +private: + EFI_IFR_REF2 *mRef2; + +public: + CIfrRef2 () : CIfrObj (EFI_IFR_REF_OP, (CHAR8 **)&mRef2, sizeof (EFI_IFR_REF2)), + CIfrOpHeader (EFI_IFR_REF_OP, &mRef2->Header, sizeof (EFI_IFR_REF2)), + CIfrQuestionHeader (&mRef2->Question) { + mRef2->FormId = 0; + mRef2->QuestionId = EFI_QUESTION_ID_INVALID; + } + + VOID SetFormId (IN EFI_FORM_ID FormId) { + mRef2->FormId = FormId; + } + + EFI_VFR_RETURN_CODE SetQuestionId (IN EFI_QUESTION_ID QuestionId) { + if (QuestionId == EFI_QUESTION_ID_INVALID) { + return VFR_RETURN_UNDEFINED; + } + mRef2->QuestionId = QuestionId; + return VFR_RETURN_SUCCESS; + } +}; + +class CIfrRef3 : public CIfrObj, public CIfrOpHeader, public CIfrQuestionHeader { +private: + EFI_IFR_REF3 *mRef3; + +public: + CIfrRef3 () : CIfrObj (EFI_IFR_REF_OP, (CHAR8 **)&mRef3, sizeof(EFI_IFR_REF3)), + CIfrOpHeader (EFI_IFR_REF_OP, &mRef3->Header, sizeof (EFI_IFR_REF3)), + CIfrQuestionHeader (&mRef3->Question) { + mRef3->FormId = 0; + mRef3->QuestionId = EFI_QUESTION_ID_INVALID; + memset (&mRef3->FormSetId, 0, sizeof (EFI_GUID)); + } + + VOID SetFormId (IN EFI_FORM_ID FormId) { + mRef3->FormId = FormId; + } + + VOID SetQuestionId (IN EFI_QUESTION_ID QuestionId) { + mRef3->QuestionId = QuestionId; + } + + VOID SetFormSetId (IN EFI_GUID FormSetId) { + mRef3->FormSetId = FormSetId; + } +}; + +class CIfrRef4 : public CIfrObj, public CIfrOpHeader, public CIfrQuestionHeader { +private: + EFI_IFR_REF4 *mRef4; + +public: + CIfrRef4 () : CIfrObj (EFI_IFR_REF_OP, (CHAR8 **)&mRef4, sizeof(EFI_IFR_REF3)), + CIfrOpHeader (EFI_IFR_REF_OP, &mRef4->Header, sizeof (EFI_IFR_REF3)), + CIfrQuestionHeader (&mRef4->Question) { + mRef4->FormId = 0; + mRef4->QuestionId = EFI_QUESTION_ID_INVALID; + memset (&mRef4->FormSetId, 0, sizeof (EFI_GUID)); + mRef4->DevicePath = EFI_STRING_ID_INVALID; + } + + VOID SetFormId (IN EFI_FORM_ID FormId) { + mRef4->FormId = FormId; + } + + VOID SetQuestionId (IN EFI_QUESTION_ID QuestionId) { + mRef4->QuestionId = QuestionId; + } + + VOID SetFormSetId (IN EFI_GUID FormSetId) { + mRef4->FormSetId = FormSetId; + } + + VOID SetDevicePath (IN EFI_STRING_ID DevicePath) { + mRef4->DevicePath = DevicePath; + } +}; + +class CIfrResetButton : public CIfrObj, public CIfrOpHeader, public CIfrStatementHeader { +private: + EFI_IFR_RESET_BUTTON *mResetButton; + +public: + CIfrResetButton () : CIfrObj (EFI_IFR_RESET_BUTTON_OP, (CHAR8 **)&mResetButton), + CIfrOpHeader (EFI_IFR_RESET_BUTTON_OP, &mResetButton->Header), + CIfrStatementHeader (&mResetButton->Question.Header) { + mResetButton->DefaultId = EFI_HII_DEFAULT_CLASS_STANDARD; + } + + VOID SetDefaultId (IN UINT16 DefaultId) { + mResetButton->DefaultId = DefaultId; + } +}; + +class CIfrCheckBox : public CIfrObj, public CIfrOpHeader, public CIfrQuestionHeader { +private: + EFI_IFR_CHECKBOX *mCheckBox; + +public: + CIfrCheckBox () : CIfrObj (EFI_IFR_CHECKBOX_OP, (CHAR8 **)&mCheckBox), + CIfrOpHeader (EFI_IFR_CHECKBOX_OP, &mCheckBox->Header), + CIfrQuestionHeader (&mCheckBox->Question) { + mCheckBox->Flags = EFI_IFR_CHECKBOX_DEFAULT; + gCurrentQuestion = this; + } + + ~CIfrCheckBox () { + gCurrentQuestion = NULL; + } + + EFI_VFR_RETURN_CODE SetFlags (IN UINT8 HFlags, UINT8 LFlags) { + EFI_VFR_RETURN_CODE Ret; + + Ret = CIfrQuestionHeader::SetFlags (HFlags); + if (Ret != VFR_RETURN_SUCCESS) { + return Ret; + } + + if (_FLAG_TEST_AND_CLEAR (LFlags, EFI_IFR_CHECKBOX_DEFAULT)) { + mCheckBox->Flags |= EFI_IFR_CHECKBOX_DEFAULT; + } + + if (_FLAG_TEST_AND_CLEAR (LFlags, EFI_IFR_CHECKBOX_DEFAULT_MFG)) { + mCheckBox->Flags |= EFI_IFR_CHECKBOX_DEFAULT_MFG; + } + + return _FLAGS_ZERO (LFlags) ? VFR_RETURN_SUCCESS : VFR_RETURN_FLAGS_UNSUPPORTED; + } +}; + +class CIfrAction : public CIfrObj, public CIfrOpHeader, public CIfrQuestionHeader { +private: + EFI_IFR_ACTION *mAction; + +public: + CIfrAction () : CIfrObj (EFI_IFR_ACTION_OP, (CHAR8 **)&mAction), + CIfrOpHeader (EFI_IFR_ACTION_OP, &mAction->Header), + CIfrQuestionHeader (&mAction->Question) { + mAction->QuestionConfig = EFI_STRING_ID_INVALID; + } + + VOID SetQuestionConfig (IN EFI_STRING_ID QuestionConfig) { + mAction->QuestionConfig = QuestionConfig; + } +}; + +class CIfrDate : public CIfrObj, public CIfrOpHeader, public CIfrQuestionHeader { +private: + EFI_IFR_DATE *mDate; + +public: + CIfrDate () : CIfrObj (EFI_IFR_DATE_OP, (CHAR8 **)&mDate), + CIfrOpHeader (EFI_IFR_DATE_OP, &mDate->Header), + CIfrQuestionHeader (&mDate->Question) { + mDate->Flags = 0; + } + + EFI_VFR_RETURN_CODE SetFlags (IN UINT8 HFlags, IN UINT8 LFlags) { + EFI_VFR_RETURN_CODE Ret; + + Ret = CIfrQuestionHeader::SetFlags (HFlags); + if (Ret != VFR_RETURN_SUCCESS) { + return Ret; + } + + if (_FLAG_TEST_AND_CLEAR (LFlags, EFI_QF_DATE_YEAR_SUPPRESS)) { + mDate->Flags |= EFI_QF_DATE_YEAR_SUPPRESS; + } + + if (_FLAG_TEST_AND_CLEAR (LFlags, EFI_QF_DATE_MONTH_SUPPRESS)) { + mDate->Flags |= EFI_QF_DATE_MONTH_SUPPRESS; + } + + if (_FLAG_TEST_AND_CLEAR (LFlags, EFI_QF_DATE_DAY_SUPPRESS)) { + mDate->Flags |= EFI_QF_DATE_DAY_SUPPRESS; + } + + if (_FLAG_TEST_AND_CLEAR (LFlags, QF_DATE_STORAGE_NORMAL)) { + mDate->Flags |= QF_DATE_STORAGE_NORMAL; + } else if (_FLAG_TEST_AND_CLEAR (LFlags, QF_DATE_STORAGE_TIME)) { + mDate->Flags |= QF_DATE_STORAGE_TIME; + } else if (_FLAG_TEST_AND_CLEAR (LFlags, QF_DATE_STORAGE_WAKEUP)) { + mDate->Flags |= QF_DATE_STORAGE_WAKEUP; + } + + return _FLAGS_ZERO (LFlags) ? VFR_RETURN_SUCCESS : VFR_RETURN_FLAGS_UNSUPPORTED; + } +}; + +class CIfrNumeric : public CIfrObj, public CIfrOpHeader, public CIfrQuestionHeader, public CIfrMinMaxStepData { +private: + EFI_IFR_NUMERIC *mNumeric; + +public: + CIfrNumeric () : CIfrObj (EFI_IFR_NUMERIC_OP, (CHAR8 **)&mNumeric), + CIfrOpHeader (EFI_IFR_NUMERIC_OP, &mNumeric->Header), + CIfrQuestionHeader (&mNumeric->Question), + CIfrMinMaxStepData (&mNumeric->data) { + mNumeric->Flags = EFI_IFR_NUMERIC_SIZE_1 | EFI_IFR_DISPLAY_UINT_DEC; + gCurrentQuestion = this; + } + + ~CIfrNumeric () { + gCurrentQuestion = NULL; + } + + EFI_VFR_RETURN_CODE SetFlags (IN UINT8 HFlags, IN UINT8 LFlags) { + EFI_VFR_RETURN_CODE Ret; + + Ret = CIfrQuestionHeader::SetFlags (HFlags); + if (Ret != VFR_RETURN_SUCCESS) { + return Ret; + } + + if (LFlags & EFI_IFR_DISPLAY) { + mNumeric->Flags = LFlags; + } else { + mNumeric->Flags = LFlags | EFI_IFR_DISPLAY_UINT_DEC; + } + return VFR_RETURN_SUCCESS; + } +}; + +class CIfrOneOf : public CIfrObj, public CIfrOpHeader, public CIfrQuestionHeader, public CIfrMinMaxStepData { +private: + EFI_IFR_ONE_OF *mOneOf; + +public: + CIfrOneOf () : CIfrObj (EFI_IFR_ONE_OF_OP, (CHAR8 **)&mOneOf), + CIfrOpHeader (EFI_IFR_ONE_OF_OP, &mOneOf->Header), + CIfrQuestionHeader (&mOneOf->Question), + CIfrMinMaxStepData (&mOneOf->data) { + mOneOf->Flags = 0; + gCurrentQuestion = this; + } + + ~CIfrOneOf () { + gCurrentQuestion = NULL; + } + + EFI_VFR_RETURN_CODE SetFlags (IN UINT8 HFlags, IN UINT8 LFlags) { + EFI_VFR_RETURN_CODE Ret; + + Ret = CIfrQuestionHeader::SetFlags (HFlags); + if (Ret != VFR_RETURN_SUCCESS) { + return Ret; + } + + if (LFlags & EFI_IFR_DISPLAY) { + mOneOf->Flags = LFlags; + } else { + mOneOf->Flags = LFlags | EFI_IFR_DISPLAY_UINT_DEC; + } + return VFR_RETURN_SUCCESS; + } +}; + +class CIfrString : public CIfrObj, public CIfrOpHeader, public CIfrQuestionHeader { +private: + EFI_IFR_STRING *mString; + +public: + CIfrString () : CIfrObj (EFI_IFR_STRING_OP, (CHAR8 **)&mString), + CIfrOpHeader (EFI_IFR_STRING_OP, &mString->Header), + CIfrQuestionHeader (&mString->Question) { + mString->Flags = 0; + mString->MinSize = 0; + mString->MaxSize = 0; + gCurrentQuestion = this; + } + + ~CIfrString () { + gCurrentQuestion = NULL; + } + + EFI_VFR_RETURN_CODE SetFlags (IN UINT8 HFlags, IN UINT8 LFlags) { + EFI_VFR_RETURN_CODE Ret; + + Ret = CIfrQuestionHeader::SetFlags (HFlags); + if (Ret != VFR_RETURN_SUCCESS) { + return Ret; + } + + if (_FLAG_TEST_AND_CLEAR (LFlags, EFI_IFR_STRING_MULTI_LINE)) { + mString->Flags |= EFI_IFR_STRING_MULTI_LINE; + } + + return _FLAGS_ZERO (LFlags) ? VFR_RETURN_SUCCESS : VFR_RETURN_FLAGS_UNSUPPORTED; + } + + VOID SetMinSize (IN UINT8 Flags) { + mString->MinSize = Flags; + } + + VOID SetMaxSize (IN UINT8 MaxSize) { + mString->MaxSize = MaxSize; + } +}; + +class CIfrPassword : public CIfrObj, public CIfrOpHeader, public CIfrQuestionHeader { +private: + EFI_IFR_PASSWORD *mPassword; + +public: + CIfrPassword () : CIfrObj (EFI_IFR_PASSWORD_OP, (CHAR8 **)&mPassword), + CIfrOpHeader (EFI_IFR_PASSWORD_OP, &mPassword->Header), + CIfrQuestionHeader (&mPassword->Question) { + mPassword->MinSize = 0; + mPassword->MaxSize = 0; + gCurrentQuestion = this; + } + + ~CIfrPassword () { + gCurrentQuestion = NULL; + } + + VOID SetMinSize (IN UINT16 MinSize) { + mPassword->MinSize = MinSize; + } + + VOID SetMaxSize (IN UINT16 MaxSize) { + mPassword->MaxSize = MaxSize; + } +}; + +class CIfrOrderedList : public CIfrObj, public CIfrOpHeader, public CIfrQuestionHeader { +private: + EFI_IFR_ORDERED_LIST *mOrderedList; + +public: + CIfrOrderedList () : CIfrObj (EFI_IFR_ORDERED_LIST_OP, (CHAR8 **)&mOrderedList), + CIfrOpHeader (EFI_IFR_ORDERED_LIST_OP, &mOrderedList->Header), + CIfrQuestionHeader (&mOrderedList->Question) { + mOrderedList->MaxContainers = 0; + mOrderedList->Flags = 0; + gCurrentQuestion = this; + } + + ~CIfrOrderedList () { + gCurrentQuestion = NULL; + } + + VOID SetMaxContainers (IN UINT8 MaxContainers) { + mOrderedList->MaxContainers = MaxContainers; + } + + EFI_VFR_RETURN_CODE SetFlags (IN UINT8 HFlags, IN UINT8 LFlags) { + EFI_VFR_RETURN_CODE Ret; + + Ret = CIfrQuestionHeader::SetFlags (HFlags); + if (Ret != VFR_RETURN_SUCCESS) { + return Ret; + } + + if (_FLAG_TEST_AND_CLEAR (LFlags, EFI_IFR_UNIQUE_SET)) { + mOrderedList->Flags |= EFI_IFR_UNIQUE_SET; + } + + if (_FLAG_TEST_AND_CLEAR (LFlags, EFI_IFR_NO_EMPTY_SET)) { + mOrderedList->Flags |= EFI_IFR_NO_EMPTY_SET; + } + + return _FLAGS_ZERO (LFlags) ? VFR_RETURN_SUCCESS : VFR_RETURN_FLAGS_UNSUPPORTED; + } +}; + +class CIfrTime : public CIfrObj, public CIfrOpHeader, public CIfrQuestionHeader { +private: + EFI_IFR_TIME *mTime; + +public: + CIfrTime () : CIfrObj (EFI_IFR_TIME_OP, (CHAR8 **)&mTime), + CIfrOpHeader (EFI_IFR_TIME_OP, &mTime->Header), + CIfrQuestionHeader (&mTime->Question) { + mTime->Flags = 0; + } + + EFI_VFR_RETURN_CODE SetFlags (IN UINT8 HFlags, IN UINT8 LFlags) { + EFI_VFR_RETURN_CODE Ret; + + Ret = CIfrQuestionHeader::SetFlags (HFlags); + if (Ret != VFR_RETURN_SUCCESS) { + return Ret; + } + + if (_FLAG_TEST_AND_CLEAR (LFlags, QF_TIME_HOUR_SUPPRESS)) { + mTime->Flags |= QF_TIME_HOUR_SUPPRESS; + } + + if (_FLAG_TEST_AND_CLEAR (LFlags, QF_TIME_MINUTE_SUPPRESS)) { + mTime->Flags |= QF_TIME_MINUTE_SUPPRESS; + } + + if (_FLAG_TEST_AND_CLEAR (LFlags, QF_TIME_SECOND_SUPPRESS)) { + mTime->Flags |= QF_TIME_SECOND_SUPPRESS; + } + + if (_FLAG_TEST_AND_CLEAR (LFlags, QF_TIME_STORAGE_NORMAL)) { + mTime->Flags |= QF_TIME_STORAGE_NORMAL; + } else if (_FLAG_TEST_AND_CLEAR (LFlags, QF_TIME_STORAGE_TIME)) { + mTime->Flags |= QF_TIME_STORAGE_TIME; + } else if (_FLAG_TEST_AND_CLEAR (LFlags, QF_TIME_STORAGE_WAKEUP)) { + mTime->Flags |= QF_TIME_STORAGE_WAKEUP; + } + + return _FLAGS_ZERO (LFlags) ? VFR_RETURN_SUCCESS : VFR_RETURN_FLAGS_UNSUPPORTED; + } +}; + +class CIfrDisableIf : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_DISABLE_IF *mDisableIf; + +public: + CIfrDisableIf () : CIfrObj (EFI_IFR_DISABLE_IF_OP, (CHAR8 **)&mDisableIf), + mDisableIf ((EFI_IFR_DISABLE_IF *) GetObjBinAddr()), + CIfrOpHeader (EFI_IFR_DISABLE_IF_OP, &mDisableIf->Header) {} +}; + +class CIfrSuppressIf : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_SUPPRESS_IF *mSuppressIf; + +public: + CIfrSuppressIf () : CIfrObj (EFI_IFR_SUPPRESS_IF_OP, (CHAR8 **)&mSuppressIf), + CIfrOpHeader (EFI_IFR_SUPPRESS_IF_OP, &mSuppressIf->Header) {} +}; + +class CIfrGrayOutIf : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_GRAY_OUT_IF *mGrayOutIf; + +public: + CIfrGrayOutIf () : CIfrObj (EFI_IFR_GRAY_OUT_IF_OP, (CHAR8 **)&mGrayOutIf), + CIfrOpHeader (EFI_IFR_GRAY_OUT_IF_OP, &mGrayOutIf->Header) {} +}; + +class CIfrInconsistentIf : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_INCONSISTENT_IF *mInconsistentIf; + +public: + CIfrInconsistentIf () : CIfrObj (EFI_IFR_INCONSISTENT_IF_OP, (CHAR8 **)&mInconsistentIf), + CIfrOpHeader (EFI_IFR_INCONSISTENT_IF_OP, &mInconsistentIf->Header) { + mInconsistentIf->Error = EFI_STRING_ID_INVALID; + } + + VOID SetError (IN EFI_STRING_ID Error) { + mInconsistentIf->Error = Error; + } +}; + +class CIfrNoSubmitIf : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_NO_SUBMIT_IF *mNoSubmitIf; + +public: + CIfrNoSubmitIf () : CIfrObj (EFI_IFR_NO_SUBMIT_IF_OP, (CHAR8 **)&mNoSubmitIf), + CIfrOpHeader (EFI_IFR_NO_SUBMIT_IF_OP, &mNoSubmitIf->Header) { + mNoSubmitIf->Error = EFI_STRING_ID_INVALID; + } + + VOID SetError (IN EFI_STRING_ID Error) { + mNoSubmitIf->Error = Error; + } +}; + +class CIfrRefresh : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_REFRESH *mRefresh; + +public: + CIfrRefresh () : CIfrObj (EFI_IFR_REFRESH_OP, (CHAR8 **)&mRefresh), + CIfrOpHeader (EFI_IFR_REFRESH_OP, &mRefresh->Header) { + mRefresh->RefreshInterval = 0; + } + + VOID SetRefreshInterval (IN UINT8 RefreshInterval) { + mRefresh->RefreshInterval = RefreshInterval; + } +}; + +class CIfrVarStoreDevice : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_VARSTORE_DEVICE *mVarStoreDevice; + +public: + CIfrVarStoreDevice () : CIfrObj (EFI_IFR_VARSTORE_DEVICE_OP, (CHAR8 **)&mVarStoreDevice), + CIfrOpHeader (EFI_IFR_VARSTORE_DEVICE_OP, &mVarStoreDevice->Header) { + mVarStoreDevice->DevicePath = EFI_STRING_ID_INVALID; + } + + VOID SetDevicePath (IN EFI_STRING_ID DevicePath) { + mVarStoreDevice->DevicePath = DevicePath; + } +}; + +class CIfrOneOfOption : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_ONE_OF_OPTION *mOneOfOption; + +public: + CIfrOneOfOption () : CIfrObj (EFI_IFR_ONE_OF_OPTION_OP, (CHAR8 **)&mOneOfOption), + CIfrOpHeader (EFI_IFR_ONE_OF_OPTION_OP, &mOneOfOption->Header) { + mOneOfOption->Flags = 0; + mOneOfOption->Option = EFI_STRING_ID_INVALID; + mOneOfOption->Type = EFI_IFR_TYPE_OTHER; + memset (&mOneOfOption->Value, 0, sizeof (mOneOfOption->Value)); + } + + VOID SetOption (IN EFI_STRING_ID Option) { + mOneOfOption->Option = Option; + } + + EFI_VFR_RETURN_CODE SetFlags (IN UINT8 LFlags) { + if (_FLAG_TEST_AND_CLEAR (LFlags, EFI_IFR_OPTION_DEFAULT)) { + mOneOfOption->Flags |= EFI_IFR_OPTION_DEFAULT; + } + + if (_FLAG_TEST_AND_CLEAR (LFlags, EFI_IFR_OPTION_DEFAULT_MFG)) { + mOneOfOption->Flags |= EFI_IFR_OPTION_DEFAULT_MFG; + } + + if (_IS_EQUAL (LFlags, EFI_IFR_TYPE_NUM_SIZE_8)) { + _FLAG_CLEAR (LFlags, EFI_IFR_TYPE_NUM_SIZE_8); + mOneOfOption->Flags |= EFI_IFR_TYPE_NUM_SIZE_8; + } else if (_IS_EQUAL (LFlags, EFI_IFR_TYPE_NUM_SIZE_16)) { + _FLAG_CLEAR (LFlags, EFI_IFR_TYPE_NUM_SIZE_16); + mOneOfOption->Flags |= EFI_IFR_TYPE_NUM_SIZE_16; + } else if (_IS_EQUAL (LFlags, EFI_IFR_TYPE_NUM_SIZE_32)) { + _FLAG_CLEAR (LFlags, EFI_IFR_TYPE_NUM_SIZE_32); + mOneOfOption->Flags |= EFI_IFR_TYPE_NUM_SIZE_32; + } else if (_IS_EQUAL (LFlags, EFI_IFR_TYPE_NUM_SIZE_64)) { + _FLAG_CLEAR (LFlags, EFI_IFR_TYPE_NUM_SIZE_64); + mOneOfOption->Flags |= EFI_IFR_TYPE_NUM_SIZE_64; + } else if (_IS_EQUAL (LFlags, EFI_IFR_TYPE_BOOLEAN)) { + _FLAG_CLEAR (LFlags, EFI_IFR_TYPE_BOOLEAN); + mOneOfOption->Flags |= EFI_IFR_TYPE_BOOLEAN; + } else if (_IS_EQUAL (LFlags, EFI_IFR_TYPE_TIME)) { + _FLAG_CLEAR (LFlags, EFI_IFR_TYPE_TIME); + mOneOfOption->Flags |= EFI_IFR_TYPE_TIME; + } else if (_IS_EQUAL (LFlags, EFI_IFR_TYPE_DATE)) { + _FLAG_CLEAR (LFlags, EFI_IFR_TYPE_DATE); + mOneOfOption->Flags |= EFI_IFR_TYPE_DATE; + } else if (_IS_EQUAL (LFlags, EFI_IFR_TYPE_STRING)) { + _FLAG_CLEAR (LFlags, EFI_IFR_TYPE_STRING); + mOneOfOption->Flags |= EFI_IFR_TYPE_STRING; + } else if (_IS_EQUAL (LFlags, EFI_IFR_TYPE_OTHER)) { + _FLAG_CLEAR (LFlags, EFI_IFR_TYPE_OTHER); + mOneOfOption->Flags |= EFI_IFR_TYPE_OTHER; + } + + return _FLAGS_ZERO (LFlags) ? VFR_RETURN_SUCCESS : VFR_RETURN_FLAGS_UNSUPPORTED; + } + + VOID SetType (IN UINT8 Type) { + mOneOfOption->Type = Type; + } + + VOID SetValue (IN EFI_IFR_TYPE_VALUE Value) { + mOneOfOption->Value = Value; + } + + UINT8 GetFlags (VOID) { + return mOneOfOption->Flags; + } +}; + +static EFI_GUID IfrTianoGuid = EFI_IFR_TIANO_GUID; + +class CIfrClass : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_GUID_CLASS *mClass; + +public: + CIfrClass () : CIfrObj (EFI_IFR_GUID_OP, (CHAR8 **)&mClass, sizeof (EFI_IFR_GUID_CLASS)), + CIfrOpHeader (EFI_IFR_GUID_OP, &mClass->Header, sizeof (EFI_IFR_GUID_CLASS)) { + mClass->ExtendOpCode = EFI_IFR_EXTEND_OP_CLASS; + mClass->Guid = IfrTianoGuid; + mClass->Class = EFI_NON_DEVICE_CLASS; + } + + VOID SetClass (IN UINT16 Class) { + mClass->Class = Class; + } +}; + +class CIfrSubClass : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_GUID_SUBCLASS *mSubClass; + +public: + CIfrSubClass () : CIfrObj (EFI_IFR_GUID_OP, (CHAR8 **)&mSubClass, sizeof (EFI_IFR_GUID_SUBCLASS)), + CIfrOpHeader (EFI_IFR_GUID_OP, &mSubClass->Header, sizeof (EFI_IFR_GUID_SUBCLASS)) { + mSubClass->ExtendOpCode = EFI_IFR_EXTEND_OP_SUBCLASS; + mSubClass->Guid = IfrTianoGuid; + mSubClass->SubClass = EFI_SETUP_APPLICATION_SUBCLASS; + } + + VOID SetSubClass (IN UINT16 SubClass) { + mSubClass->SubClass = SubClass; + } +}; + +class CIfrLabel : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_GUID_LABEL *mLabel; + +public: + CIfrLabel () : CIfrObj (EFI_IFR_GUID_OP, (CHAR8 **)&mLabel, sizeof (EFI_IFR_GUID_LABEL)), + CIfrOpHeader (EFI_IFR_GUID_OP, &mLabel->Header, sizeof (EFI_IFR_GUID_LABEL)) { + mLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; + mLabel->Guid = IfrTianoGuid; + } + + VOID SetNumber (IN UINT16 Number) { + mLabel->Number = Number; + } +}; + +class CIfrBanner : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_GUID_BANNER *mBanner; + +public: + CIfrBanner () : CIfrObj (EFI_IFR_GUID_OP, (CHAR8 **)&mBanner, sizeof (EFI_IFR_GUID_BANNER)), + CIfrOpHeader (EFI_IFR_GUID_OP, &mBanner->Header, sizeof (EFI_IFR_GUID_BANNER)) { + mBanner->ExtendOpCode = EFI_IFR_EXTEND_OP_BANNER; + mBanner->Guid = IfrTianoGuid; + } + + VOID SetTitle (IN EFI_STRING_ID StringId) { + mBanner->Title = StringId; + } + + VOID SetLine (IN UINT16 Line) { + mBanner->LineNumber = Line; + } + + VOID SetAlign (IN UINT8 Align) { + mBanner->Alignment = Align; + } +}; + +class CIfrTimeout : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_GUID_TIMEOUT *mTimeout; + +public: + CIfrTimeout (IN UINT16 Timeout = 0) : CIfrObj (EFI_IFR_GUID_OP, (CHAR8 **)&mTimeout, sizeof (EFI_IFR_GUID_TIMEOUT)), + CIfrOpHeader (EFI_IFR_GUID_OP, &mTimeout->Header, sizeof (EFI_IFR_GUID_TIMEOUT)) { + mTimeout->ExtendOpCode = EFI_IFR_EXTEND_OP_TIMEOUT; + mTimeout->Guid = IfrTianoGuid; + mTimeout->TimeOut = Timeout; + } + + VOID SetTimeout (IN UINT16 Timeout) { + mTimeout->TimeOut = Timeout; + } +}; + +class CIfrDup : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_DUP *mDup; + +public: + CIfrDup ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_DUP_OP, (CHAR8 **)&mDup), + CIfrOpHeader (EFI_IFR_DUP_OP, &mDup->Header) { + SetLineNo (LineNo); + } +}; + +class CIfrEqIdId : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_EQ_ID_ID *mEqIdId; + +public: + CIfrEqIdId ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_EQ_ID_ID_OP, (CHAR8 **)&mEqIdId), + CIfrOpHeader (EFI_IFR_EQ_ID_ID_OP, &mEqIdId->Header) { + SetLineNo (LineNo); + mEqIdId->QuestionId1 = EFI_QUESTION_ID_INVALID; + mEqIdId->QuestionId2 = EFI_QUESTION_ID_INVALID; + } + + VOID SetQuestionId1 ( + IN EFI_QUESTION_ID QuestionId, + IN INT8 *VarIdStr, + IN UINT32 LineNo + ) { + if (QuestionId != EFI_QUESTION_ID_INVALID) { + mEqIdId->QuestionId1 = QuestionId; + } else { + gCFormPkg.AssignPending (VarIdStr, (VOID *)(&mEqIdId->QuestionId1), sizeof (EFI_QUESTION_ID), LineNo); + } + } + + VOID SetQuestionId2 ( + IN EFI_QUESTION_ID QuestionId, + IN INT8 *VarIdStr, + IN UINT32 LineNo + ) { + if (QuestionId != EFI_QUESTION_ID_INVALID) { + mEqIdId->QuestionId2 = QuestionId; + } else { + gCFormPkg.AssignPending (VarIdStr, (VOID *)(&mEqIdId->QuestionId2), sizeof (EFI_QUESTION_ID), LineNo); + } + } +}; + +class CIfrEqIdVal : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_EQ_ID_VAL *mEqIdVal; + +public: + CIfrEqIdVal ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_EQ_ID_VAL_OP, (CHAR8 **)&mEqIdVal), + CIfrOpHeader (EFI_IFR_EQ_ID_VAL_OP, &mEqIdVal->Header) { + SetLineNo (LineNo); + mEqIdVal->QuestionId = EFI_QUESTION_ID_INVALID; + } + + VOID SetQuestionId ( + IN EFI_QUESTION_ID QuestionId, + IN INT8 *VarIdStr, + IN UINT32 LineNo + ) { + if (QuestionId != EFI_QUESTION_ID_INVALID) { + mEqIdVal->QuestionId = QuestionId; + } else { + gCFormPkg.AssignPending (VarIdStr, (VOID *)(&mEqIdVal->QuestionId), sizeof (EFI_QUESTION_ID), LineNo); + } + } + + VOID SetValue (IN UINT16 Value) { + mEqIdVal->Value = Value; + } +}; + +class CIfrEqIdList : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_EQ_ID_LIST *mEqIdVList; + +public: + CIfrEqIdList ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_EQ_ID_LIST_OP, (CHAR8 **)&mEqIdVList, sizeof (EFI_IFR_EQ_ID_LIST), TRUE), + CIfrOpHeader (EFI_IFR_EQ_ID_LIST_OP, &mEqIdVList->Header) { + SetLineNo (LineNo); + mEqIdVList->QuestionId = EFI_QUESTION_ID_INVALID; + mEqIdVList->ListLength = 0; + mEqIdVList->ValueList[0] = 0; + } + + VOID SetQuestionId ( + IN EFI_QUESTION_ID QuestionId, + IN INT8 *VarIdStr, + IN UINT32 LineNo + ) { + if (QuestionId != EFI_QUESTION_ID_INVALID) { + mEqIdVList->QuestionId = QuestionId; + } else { + gCFormPkg.AssignPending (VarIdStr, (VOID *)(&mEqIdVList->QuestionId), sizeof (EFI_QUESTION_ID), LineNo); + } + } + + VOID SetListLength (IN UINT16 ListLength) { + mEqIdVList->ListLength = ListLength; + } + + VOID SetValueList (IN UINT16 Index, IN UINT16 Value) { + if (Index == 0) { + mEqIdVList->ValueList[0] = Value; + return; + } + + if (ExpendObjBin (sizeof (UINT16)) ==TRUE) { + IncLength (sizeof (UINT16)); + mEqIdVList->ValueList[Index] = Value; + } + } +}; + +class CIfrQuestionRef1 : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_QUESTION_REF1 *mQuestionRef1; + +public: + CIfrQuestionRef1 ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_QUESTION_REF1_OP, (CHAR8 **)&mQuestionRef1), + CIfrOpHeader (EFI_IFR_QUESTION_REF1_OP, &mQuestionRef1->Header) { + SetLineNo (LineNo); + mQuestionRef1->QuestionId = EFI_QUESTION_ID_INVALID; + } + + VOID SetQuestionId ( + IN EFI_QUESTION_ID QuestionId, + IN INT8 *VarIdStr, + IN UINT32 LineNo + ) { + if (QuestionId != EFI_QUESTION_ID_INVALID) { + mQuestionRef1->QuestionId = QuestionId; + } else { + gCFormPkg.AssignPending (VarIdStr, (VOID *)(&mQuestionRef1->QuestionId), sizeof (EFI_QUESTION_ID), LineNo); + } + } +}; + +class CIfrQuestionRef2 : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_QUESTION_REF2 *mQuestionRef2; + +public: + CIfrQuestionRef2 ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_QUESTION_REF2_OP, (CHAR8 **)&mQuestionRef2), + CIfrOpHeader (EFI_IFR_QUESTION_REF2_OP, &mQuestionRef2->Header) { + SetLineNo (LineNo); + } +}; + +class CIfrQuestionRef3 : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_QUESTION_REF3 *mQuestionRef3; + +public: + CIfrQuestionRef3 ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_QUESTION_REF3_OP, (CHAR8 **)&mQuestionRef3), + CIfrOpHeader (EFI_IFR_QUESTION_REF3_OP, &mQuestionRef3->Header) { + SetLineNo (LineNo); + } +}; + +class CIfrQuestionRef3_2 : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_QUESTION_REF3_2 *mQuestionRef3_2; + +public: + CIfrQuestionRef3_2 ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_QUESTION_REF3_OP, (CHAR8 **)&mQuestionRef3_2, sizeof (EFI_IFR_QUESTION_REF3_2)), + CIfrOpHeader (EFI_IFR_QUESTION_REF3_OP, &mQuestionRef3_2->Header, sizeof (EFI_IFR_QUESTION_REF3_2)) { + SetLineNo (LineNo); + mQuestionRef3_2->DevicePath = EFI_STRING_ID_INVALID; + } + + VOID SetDevicePath (IN EFI_STRING_ID DevicePath) { + mQuestionRef3_2->DevicePath = DevicePath; + } +}; + +class CIfrQuestionRef3_3 : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_QUESTION_REF3_3 *mQuestionRef3_3; + +public: + CIfrQuestionRef3_3 ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_QUESTION_REF3_OP, (CHAR8 **)&mQuestionRef3_3, sizeof (EFI_IFR_QUESTION_REF3_3)), + CIfrOpHeader (EFI_IFR_QUESTION_REF3_OP, &mQuestionRef3_3->Header, sizeof (EFI_IFR_QUESTION_REF3_3)) { + SetLineNo (LineNo); + mQuestionRef3_3->DevicePath = EFI_STRING_ID_INVALID; + memset (&mQuestionRef3_3->Guid, 0, sizeof (EFI_GUID)); + } + + VOID SetDevicePath (IN EFI_STRING_ID DevicePath) { + mQuestionRef3_3->DevicePath = DevicePath; + } + + VOID SetGuid (IN EFI_GUID *Guid) { + mQuestionRef3_3->Guid = *Guid; + } +}; + +class CIfrRuleRef : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_RULE_REF *mRuleRef; + +public: + CIfrRuleRef ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_RULE_REF_OP, (CHAR8 **)&mRuleRef), + CIfrOpHeader (EFI_IFR_RULE_REF_OP, &mRuleRef->Header) { + SetLineNo (LineNo); + mRuleRef->RuleId = EFI_RULE_ID_INVALID; + } + + VOID SetRuleId (IN UINT8 RuleId) { + mRuleRef->RuleId = RuleId; + } +}; + +class CIfrStringRef1 : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_STRING_REF1 *mStringRef1; + +public: + CIfrStringRef1 ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_STRING_REF1_OP, (CHAR8 **)&mStringRef1), + CIfrOpHeader (EFI_IFR_STRING_REF1_OP, &mStringRef1->Header) { + SetLineNo (LineNo); + mStringRef1->StringId = EFI_STRING_ID_INVALID; + } + + VOID SetStringId (IN EFI_STRING_ID StringId) { + mStringRef1->StringId = StringId; + } +}; + +class CIfrStringRef2 : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_STRING_REF2 *mStringRef2; + +public: + CIfrStringRef2 ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_STRING_REF2_OP, (CHAR8 **)&mStringRef2), + CIfrOpHeader (EFI_IFR_STRING_REF2_OP, &mStringRef2->Header) { + SetLineNo (LineNo); + } +}; + +class CIfrThis : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_THIS *mThis; + +public: + CIfrThis ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_THIS_OP, (CHAR8 **)&mThis), + CIfrOpHeader (EFI_IFR_THIS_OP, &mThis->Header) { + SetLineNo (LineNo); + } +}; + +class CIfrUint8 : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_UINT8 *mUint8; + +public: + CIfrUint8 ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_UINT8_OP, (CHAR8 **)&mUint8), + CIfrOpHeader (EFI_IFR_UINT8_OP, &mUint8->Header) { + SetLineNo (LineNo); + } + + VOID SetValue (IN UINT8 Value) { + mUint8->Value = Value; + } +}; + +class CIfrUint16 : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_UINT16 *mUint16; + +public: + CIfrUint16 ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_UINT16_OP, (CHAR8 **)&mUint16), + CIfrOpHeader (EFI_IFR_UINT16_OP, &mUint16->Header) { + SetLineNo (LineNo); + } + + VOID SetValue (IN UINT16 Value) { + mUint16->Value = Value; + } +}; + +class CIfrUint32 : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_UINT32 *mUint32; + +public: + CIfrUint32 ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_UINT32_OP, (CHAR8 **)&mUint32), + CIfrOpHeader (EFI_IFR_UINT32_OP, &mUint32->Header) { + SetLineNo (LineNo); + } + + VOID SetValue (IN UINT32 Value) { + mUint32->Value = Value; + } +}; + +class CIfrUint64 : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_UINT64 *mUint64; + +public: + CIfrUint64 ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_UINT64_OP, (CHAR8 **)&mUint64), + CIfrOpHeader (EFI_IFR_UINT64_OP, &mUint64->Header) { + SetLineNo (LineNo); + } + + VOID SetValue (IN UINT64 Value) { + mUint64->Value = Value; + } +}; + +class CIfrTrue : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_TRUE *mTrue; + +public: + CIfrTrue ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_TRUE_OP, (CHAR8 **)&mTrue), + CIfrOpHeader (EFI_IFR_TRUE_OP, &mTrue->Header) { + SetLineNo (LineNo); + } +}; + +class CIfrFalse : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_FALSE *mFalse; + +public: + CIfrFalse ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_FALSE_OP, (CHAR8 **)&mFalse), + CIfrOpHeader (EFI_IFR_FALSE_OP, &mFalse->Header) { + SetLineNo (LineNo); + } +}; + +class CIfrOne : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_ONE *mOne; + +public: + CIfrOne ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_ONE_OP, (CHAR8 **)&mOne), + CIfrOpHeader (EFI_IFR_ONE_OP, &mOne->Header) { + SetLineNo (LineNo); + } +}; + +class CIfrOnes : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_ONES *mOnes; + +public: + CIfrOnes ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_ONES_OP, (CHAR8 **)&mOnes), + CIfrOpHeader (EFI_IFR_ONES_OP, &mOnes->Header) { + SetLineNo (LineNo); + } +}; + +class CIfrZero : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_ZERO *mZero; + +public: + CIfrZero ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_ZERO_OP, (CHAR8 **)&mZero), + CIfrOpHeader (EFI_IFR_ZERO_OP, &mZero->Header) { + SetLineNo (LineNo); + } +}; + +class CIfrUndefined : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_UNDEFINED *mUndefined; + +public: + CIfrUndefined ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_UNDEFINED_OP, (CHAR8 **)&mUndefined), + CIfrOpHeader (EFI_IFR_UNDEFINED_OP, &mUndefined->Header) { + SetLineNo (LineNo); + } +}; + +class CIfrVersion : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_VERSION *mVersion; + +public: + CIfrVersion ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_VERSION_OP, (CHAR8 **)&mVersion), + CIfrOpHeader (EFI_IFR_VERSION_OP, &mVersion->Header) { + SetLineNo (LineNo); + } +}; + +class CIfrLength : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_LENGTH *mLength; + +public: + CIfrLength ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_LENGTH_OP, (CHAR8 **)&mLength), + CIfrOpHeader (EFI_IFR_LENGTH_OP, &mLength->Header) { + SetLineNo (LineNo); + } +}; + +class CIfrNot : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_NOT *mNot; + +public: + CIfrNot ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_NOT_OP, (CHAR8 **)&mNot), + CIfrOpHeader (EFI_IFR_NOT_OP, &mNot->Header) { + SetLineNo (LineNo); + } +}; + +class CIfrBitWiseNot : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_BITWISE_NOT *mBitWise; + +public: + CIfrBitWiseNot ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_BITWISE_NOT_OP, (CHAR8 **)&mBitWise), + CIfrOpHeader (EFI_IFR_BITWISE_NOT_OP, &mBitWise->Header) { + SetLineNo (LineNo); + } +}; + +class CIfrToBoolean : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_TO_BOOLEAN *mToBoolean; + +public: + CIfrToBoolean ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_TO_BOOLEAN_OP, (CHAR8 **)&mToBoolean), + CIfrOpHeader (EFI_IFR_TO_BOOLEAN_OP, &mToBoolean->Header) { + SetLineNo (LineNo); + } +}; + +class CIfrToString : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_TO_STRING *mToString; + +public: + CIfrToString ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_TO_STRING_OP, (CHAR8 **)&mToString), + CIfrOpHeader (EFI_IFR_TO_STRING_OP, &mToString->Header) { + SetLineNo (LineNo); + } + + VOID SetFormat (IN UINT8 Format) { + mToString->Format = Format; + } +}; + +class CIfrToUint : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_TO_UINT *mToUint; + +public: + CIfrToUint ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_TO_UINT_OP, (CHAR8 **)&mToUint), + CIfrOpHeader (EFI_IFR_TO_UINT_OP, &mToUint->Header) { + SetLineNo (LineNo); + } +}; + +class CIfrToUpper : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_TO_UPPER *mToUpper; + +public: + CIfrToUpper ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_TO_UPPER_OP, (CHAR8 **)&mToUpper), + CIfrOpHeader (EFI_IFR_TO_UPPER_OP, &mToUpper->Header) { + SetLineNo (LineNo); + } +}; + +class CIfrToLower : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_TO_LOWER *mToLower; + +public: + CIfrToLower ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_TO_LOWER_OP, (CHAR8 **)&mToLower), + CIfrOpHeader (EFI_IFR_TO_LOWER_OP, &mToLower->Header) { + SetLineNo (LineNo); + } +}; + +class CIfrAdd : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_ADD *mAdd; + +public: + CIfrAdd ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_ADD_OP, (CHAR8 **)&mAdd), + CIfrOpHeader (EFI_IFR_ADD_OP, &mAdd->Header) { + SetLineNo (LineNo); + } +}; + +class CIfrBitWiseAnd : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_BITWISE_AND *mBitWiseAnd; + +public: + CIfrBitWiseAnd ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_BITWISE_AND_OP, (CHAR8 **)&mBitWiseAnd), + CIfrOpHeader (EFI_IFR_BITWISE_AND_OP, &mBitWiseAnd->Header) { + SetLineNo(LineNo); + } +}; + +class CIfrBitWiseOr : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_BITWISE_OR *mBitWiseOr; + +public: + CIfrBitWiseOr ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_BITWISE_OR_OP, (CHAR8 **)&mBitWiseOr), + CIfrOpHeader (EFI_IFR_BITWISE_OR_OP, &mBitWiseOr->Header) { + SetLineNo (LineNo); + } +}; + +class CIfrAnd : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_AND *mAnd; + +public: + CIfrAnd ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_AND_OP, (CHAR8 **)&mAnd), + CIfrOpHeader (EFI_IFR_AND_OP, &mAnd->Header) { + SetLineNo (LineNo); + } +}; + +class CIfrCatenate : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_CATENATE *mCatenate; + +public: + CIfrCatenate ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_CATENATE_OP, (CHAR8 **)&mCatenate), + CIfrOpHeader (EFI_IFR_CATENATE_OP, &mCatenate->Header) { + SetLineNo (LineNo); + } +}; + +class CIfrDivide : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_DIVIDE *mDivide; + +public: + CIfrDivide ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_DIVIDE_OP, (CHAR8 **)&mDivide), + CIfrOpHeader (EFI_IFR_DIVIDE_OP, &mDivide->Header) { + SetLineNo (LineNo); + } +}; + +class CIfrEqual : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_EQUAL *mEqual; + +public: + CIfrEqual ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_EQUAL_OP, (CHAR8 **)&mEqual), + CIfrOpHeader (EFI_IFR_EQUAL_OP, &mEqual->Header) { + SetLineNo (LineNo); + } +}; + +class CIfrGreaterEqual : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_GREATER_EQUAL *mGreaterEqual; + +public: + CIfrGreaterEqual ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_GREATER_EQUAL_OP, (CHAR8 **)&mGreaterEqual), + CIfrOpHeader (EFI_IFR_GREATER_EQUAL_OP, &mGreaterEqual->Header) { + SetLineNo (LineNo); + } +}; + +class CIfrGreaterThan : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_GREATER_THAN *mGreaterThan; + +public: + CIfrGreaterThan ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_GREATER_THAN_OP, (CHAR8 **)&mGreaterThan), + CIfrOpHeader (EFI_IFR_GREATER_THAN_OP, &mGreaterThan->Header) { + SetLineNo (LineNo); + } +}; + +class CIfrLessEqual : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_LESS_EQUAL *mLessEqual; + +public: + CIfrLessEqual ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_LESS_EQUAL_OP, (CHAR8 **)&mLessEqual), + CIfrOpHeader (EFI_IFR_LESS_EQUAL_OP, &mLessEqual->Header) { + SetLineNo (LineNo); + } +}; + +class CIfrLessThan : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_LESS_THAN *mLessThan; + +public: + CIfrLessThan ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_LESS_THAN_OP, (CHAR8 **)&mLessThan), + CIfrOpHeader (EFI_IFR_LESS_THAN_OP, &mLessThan->Header) { + SetLineNo (LineNo); + } +}; + +class CIfrMatch : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_MATCH *mMatch; + +public: + CIfrMatch ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_MATCH_OP, (CHAR8 **)&mMatch), + CIfrOpHeader (EFI_IFR_MATCH_OP, &mMatch->Header) { + SetLineNo (LineNo); + } +}; + +class CIfrMultiply : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_MULTIPLY *mMultiply; + +public: + CIfrMultiply ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_MULTIPLY_OP, (CHAR8 **)&mMultiply), + CIfrOpHeader (EFI_IFR_MULTIPLY_OP, &mMultiply->Header) { + SetLineNo (LineNo); + } +}; + +class CIfrModulo : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_MODULO *mModulo; + +public: + CIfrModulo ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_MODULO_OP, (CHAR8 **)&mModulo), + CIfrOpHeader (EFI_IFR_MODULO_OP, &mModulo->Header) { + SetLineNo (LineNo); + } +}; + +class CIfrNotEqual : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_NOT_EQUAL *mNotEqual; + +public: + CIfrNotEqual ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_NOT_EQUAL_OP, (CHAR8 **)&mNotEqual), + CIfrOpHeader (EFI_IFR_NOT_EQUAL_OP, &mNotEqual->Header) { + SetLineNo (LineNo); + } +}; + +class CIfrOr : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_OR *mOr; + +public: + CIfrOr ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_OR_OP, (CHAR8 **)&mOr), + CIfrOpHeader (EFI_IFR_OR_OP, &mOr->Header) { + SetLineNo (LineNo); + } +}; + +class CIfrShiftLeft : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_SHIFT_LEFT *mShiftLeft; + +public: + CIfrShiftLeft ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_SHIFT_LEFT_OP, (CHAR8 **)&mShiftLeft), + CIfrOpHeader (EFI_IFR_SHIFT_LEFT_OP, &mShiftLeft->Header) { + SetLineNo (LineNo); + } +}; + +class CIfrShiftRight : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_SHIFT_RIGHT *mShiftRight; + +public: + CIfrShiftRight ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_SHIFT_RIGHT_OP, (CHAR8 **)&mShiftRight), + CIfrOpHeader (EFI_IFR_SHIFT_RIGHT_OP, &mShiftRight->Header) { + SetLineNo (LineNo); + } +}; + +class CIfrSubtract : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_SUBTRACT *mSubtract; + +public: + CIfrSubtract ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_SUBTRACT_OP, (CHAR8 **)&mSubtract), + CIfrOpHeader (EFI_IFR_SUBTRACT_OP, &mSubtract->Header) { + SetLineNo (LineNo); + } +}; + +class CIfrConditional : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_CONDITIONAL *mConditional; + +public: + CIfrConditional ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_CONDITIONAL_OP, (CHAR8 **)&mConditional), + CIfrOpHeader (EFI_IFR_CONDITIONAL_OP, &mConditional->Header) { + SetLineNo (LineNo); + } +}; + +class CIfrFind : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_FIND *mFind; + +public: + CIfrFind ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_FIND_OP, (CHAR8 **)&mFind), + CIfrOpHeader (EFI_IFR_FIND_OP, &mFind->Header) { + SetLineNo (LineNo); + } + + VOID SetFormat (IN UINT8 Format) { + mFind->Format = Format; + } +}; + +class CIfrMid : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_MID *mMid; + +public: + CIfrMid ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_MID_OP, (CHAR8 **)&mMid), + CIfrOpHeader (EFI_IFR_MID_OP, &mMid->Header) { + SetLineNo (LineNo); + } +}; + +class CIfrToken : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_TOKEN *mToken; + +public: + CIfrToken ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_TOKEN_OP, (CHAR8 **)&mToken), + CIfrOpHeader (EFI_IFR_TOKEN_OP, &mToken->Header) { + SetLineNo (LineNo); + } +}; + +class CIfrSpan : public CIfrObj, public CIfrOpHeader { +private: + EFI_IFR_SPAN *mSpan; + +public: + CIfrSpan ( + IN UINT32 LineNo + ) : CIfrObj (EFI_IFR_SPAN_OP, (CHAR8 **)&mSpan), + CIfrOpHeader (EFI_IFR_SPAN_OP, &mSpan->Header) { + SetLineNo (LineNo); + mSpan->Flags = EFI_IFR_FLAGS_FIRST_MATCHING; + } + + EFI_VFR_RETURN_CODE SetFlags (IN UINT8 LFlags) { + if (_IS_EQUAL (LFlags, EFI_IFR_FLAGS_FIRST_MATCHING)) { + mSpan->Flags |= EFI_IFR_FLAGS_FIRST_MATCHING; + } else if (_FLAG_TEST_AND_CLEAR (LFlags, EFI_IFR_FLAGS_FIRST_NON_MATCHING)) { + mSpan->Flags |= EFI_IFR_FLAGS_FIRST_NON_MATCHING; + } + + return _FLAGS_ZERO (LFlags) ? VFR_RETURN_SUCCESS : VFR_RETURN_FLAGS_UNSUPPORTED; + } +}; + +#endif diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrSyntax.g b/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrSyntax.g new file mode 100644 index 0000000000..6029d9e2d8 --- /dev/null +++ b/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrSyntax.g @@ -0,0 +1,3201 @@ +#header<< + +#include "EfiVfr.h" +#include "VfrFormPkg.h" +#include "VfrError.h" +#include "VfrUtilityLib.h" +#include "AToken.h" +#include "ATokPtr.h" +>> + +<< +#include "stdio.h" +#include "PBlackBox.h" +#include "DLexerBase.h" +#include "VfrLexer.h" +#include "AToken.h" + +#define GET_LINENO(Obj) ((Obj)->getLine()) +#define SET_LINE_INFO(Obj, L) {(Obj).SetLineNo((L)->getLine());} while (0) +#define CRT_END_OP(Obj) {CIfrEnd EObj; EObj.SetLineNo ((Obj)->getLine());} while (0) + +typedef ANTLRCommonToken ANTLRToken; + +class CVfrDLGLexer : public VfrLexer +{ +public: + CVfrDLGLexer (DLGFileInput *F) : VfrLexer (F) {}; + INT32 errstd (char *Text) + { + printf ("unrecognized input '%s'\n", Text); + } +}; + +UINT8 +VfrParserStart ( + IN FILE *File + ) +{ + ParserBlackBox VfrParser(File); + return VfrParser.parser()->vfrProgram(); +} +>> + +#lexaction +<< +#include + +>> + +// +// Define a lexical class for parsing quoted strings. Basically +// starts with a double quote, and ends with a double quote that +// is not preceeded with a backslash. +// +#lexclass QUOTED_STRING +#token TheString "~[\"]*\"" << mode (START); >> + +// +// Define a lexclass for skipping over C++ style comments +// +#lexclass CPP_COMMENT +#token "~[\n]*" << skip (); >> +#token "\n" << skip (); mode (START); newline (); >> + +// +// Standard lexclass is START +// +#lexclass START + +// +// Find start of C++ style comments +// +#token "//" << skip (); mode (CPP_COMMENT); >> + +// +// Skip whitespace +// +#token "[\ \t]" << skip (); >> + +// +// Skip over newlines, but count them +// +#token "\n" << skip (); newline (); >> + +// +// Skip over 'extern' in any included .H file +// +#token "extern" << skip (); mode (CPP_COMMENT); >> + +// +// Tokens for the different keywords. Syntax is: +// TokenName("ErrorMessageText") "TokenString" +// where: +// TokenName is the token name (must be capitalized) that is used in the rules +// ErrorMessageText is the string the compiler emits when it detects a syntax error +// TokenString is the actual matching string used in the user script +// +#token FormPkgType("formpkgtype") "formpkgtype" +#token OpenBrace("{") "\{" +#token CloseBrace("}") "\}" +#token OpenParen("(") "\(" +#token CloseParen(")") "\)" +#token OpenBracket("[") "\[" +#token CloseBracket("]") "\]" + +#token LineDefinition "#line\ [0-9]+\ \"~[\"]+\"[\ \t]*\n" << gCVfrErrorHandle.ParseFileScopeRecord (begexpr (), line ()); skip (); newline (); >> +#token DevicePath("devicepath") "devicepath" +#token FormSet("formset") "formset" +#token FormSetId("formsetid") "formsetid" +#token EndFormSet("endformset") "endformset" +#token Title("title") "title" +#token FormId("formid") "formid" +#token OneOf("oneof") "oneof" +#token EndoneOf("endoneof") "endoneof" +#token Prompt("prompt") "prompt" +#token OrderedList("orderedlist") "orderedlist" +#token MaxContainers("maxcontainers") "maxcontainers" +#token EndList("endlist") "endlist" +#token EndForm("endform") "endform" +#token EndOneOf("endoneof") "endoneof" +#token Form("form") "form" +#token Subtitle("subtitle") "subtitle" +#token Help("help") "help" +#token Text("text") "text" +#token Option("option") "option" +#token FLAGS("flags") "flags" +#token Date("date") "date" +#token EndDate("enddate") "enddate" +#token Year("year") "year" +#token Month("month") "month" +#token Day("day") "day" +#token Time("time") "time" +#token EndTime("endtime") "endtime" +#token Hour("hour") "hour" +#token Minute("minute") "minute" +#token Second("second") "second" +#token GrayOutIf("grayoutif") "grayoutif" +#token Label("label") "label" +#token Timeout("timeout") "timeout" +#token Inventory("inventory") "inventory" +#token NonNvDataMap("_NON_NV_DATA_MAP") "_NON_NV_DATA_MAP" +#token Struct("struct") "struct" +#token Uint64("UINT64") "UINT64" +#token Uint32("UINT32") "UINT32" +#token Uint16("UINT16") "UINT16" +#token Char16("CHAR16") "CHAR16" +#token Uint8("UINT8") "UINT8" +#token GUID("guid") "guid" +#token CheckBox("checkbox") "checkbox" +#token EndCheckBox("endcheckbox") "endcheckbox" +#token Numeric("numeric") "numeric" +#token EndNumeric("endnumeric") "endnumeric" +#token Minimum("minimum") "minimum" +#token Maximum("maximum") "maximum" +#token STEP("step") "step" +#token Default("default") "default" +#token Password("password") "password" +#token EndPassword("endpassword") "endpassword" +#token String("string") "string" +#token EndString("endstring") "endstring" +#token MinSize("minsize") "minsize" +#token MaxSize("maxsize") "maxsize" +#token Encoding("encoding") "encoding" +#token SuppressIf("suppressif") "suppressif" +#token DisableIf("disableif") "disableif" +#token Hidden("hidden") "hidden" +#token Goto("goto") "goto" +#token FormSetGuid("formsetguid") "formsetguid" +#token InconsistentIf("inconsistentif") "inconsistentif" +#token NoSubmitIf("nosubmitif") "nosubmitif" +#token EndIf("endif") "endif" +#token Key("key") "key" +#token DefaultFlag("DEFAULT") "DEFAULT" +#token ManufacturingFlag("MANUFACTURING") "MANUFACTURING" +#token InteractiveFlag("INTERACTIVE") "INTERACTIVE" +#token NVAccessFlag("NV_ACCESS") "NV_ACCESS" +#token ResetRequiredFlag("RESET_REQUIRED") "RESET_REQUIRED" +#token LateCheckFlag("LATE_CHECK") "LATE_CHECK" +#token ReadOnlyFlag("READ_ONLY") "READ_ONLY" +#token CallBackFlag("INTERACTIVE") "INTERACTIVE" +#token OptionOnlyFlag("OPTIONS_ONLY") "OPTIONS_ONLY" +#token Class("class") "class" +#token Subclass("subclass") "subclass" +#token TypeDef("typedef") "typedef" +#token Restore("restore") "restore" +#token Save("save") "save" +#token Defaults("defaults") "defaults" +#token Banner("banner") "banner" +#token Align("align") "align" +#token Left("left") "left" +#token Right("right") "right" +#token Center("center") "center" +#token Line("line") "line" +#token Name("name") "name" + +#token VarId("varid") "varid" +#token Question("question") "question" +#token QuestionId("questionid") "questionid" +#token Image("image") "image" +#token Locked("locked") "locked" +#token Rule("rule") "rule" +#token EndRule("endrule") "endrule" +#token Value("value") "value" +#token ResetButton("resetbutton") "resetbutton" +#token EndResetButton("endresetbutton") "endresetbutton" +#token DefaultStore("defaultstore") "defaultstore" +#token Attribute("attribute") "attribute" +#token Varstore("varstore") "varstore" +#token Efivarstore("efivarstore") "efivarstore" +#token VarSize("varsize") "varsize" +#token NameValueVarStore("namevaluevarstore") "namevaluevarstore" +#token Action("action") "action" +#token Config("config") "config" +#token EndAction("endaction") "endaction" +#token Refresh("refresh") "refresh" +#token Interval("interval") "interval" +#token VarstoreDevice("varstoredevice") "varstoredevice" +// +// Define the class and subclass tokens +// +#token ClassNonDevice("NONDEVICE") "NON_DEVICE" +#token ClassDiskDevice("DISK_DEVICE") "DISK_DEVICE" +#token ClassVideoDevice("VIDEO_DEVICE") "VIDEO_DEVICE" +#token ClassNetworkDevice("NETWORK_DEVICE") "NETWORK_DEVICE" +#token ClassInputDevice("INPUT_DEVICE") "INPUT_DEVICE" +#token ClassOnBoardDevice("ONBOARD_DEVICE") "ONBOARD_DEVICE" +#token ClassOtherDevice("OTHER_DEVICE") "OTHER_DEVICE" + +#token SubclassSetupApplication("SETUP_APPLICATION") "SETUP_APPLICATION" +#token SubclassGeneralApplication("GENERAL_APPLICATION") "GENERAL_APPLICATION" +#token SubclassFrontPage("FRONT_PAGE") "FRONT_PAGE" +#token SubclassSingleUse("SINGLE_USE") "SINGLE_USE" + +// +// This is the overall definition of a VFR form definition script. +// + +vfrProgram > [UINT8 Return] : + << mParserStatus = 0; >> + ( + ( + "\#pragma" "pack" "\(" A:Number "\)" << _PCATCH(mCVfrVarDataTypeDB.Pack (_STOU32(A->getText())), A); >> + vfrDataStructDefinition + "\#pragma" "pack" "\(" "\)" << mCVfrVarDataTypeDB.UnPack (); >> + ) + | + ( + vfrDataStructDefinition + ) + )* + vfrFromSetDefinition + << $Return = mParserStatus; >> + ; + +//***************************************************************************** +// +// the syntax of data struct definition +// +vfrDataStructDefinition : + { TypeDef } Struct << mCVfrVarDataTypeDB.DeclareDataTypeBegin (); >> + { NonNVDataMap } + { + N1:StringIdentifier << _PCATCH(mCVfrVarDataTypeDB.SetNewTypeName (N1->getText()), N1); >> + } + OpenBrace + vfrDataStructFields + CloseBrace + { + N2:StringIdentifier << _PCATCH(mCVfrVarDataTypeDB.SetNewTypeName (N2->getText()), N2); >> + } + ";" << mCVfrVarDataTypeDB.DeclareDataTypeEnd (); >> + ; + +vfrDataStructFields : + ( + dataStructField64 | + dataStructField32 | + dataStructField16 | + dataStructField8 | + dataStructFieldBool | + dataStructFieldString | + dataStructFieldDate | + dataStructFieldTime | + dataStructFieldUser + )* + ; + +dataStructField64 : + << UINT32 ArrayNum = 0; >> + "UINT64" + N:StringIdentifier + { + OpenBracket I:Number CloseBracket << ArrayNum = _STOU32(I->getText()); >> + } + ";" << _PCATCH(mCVfrVarDataTypeDB.DataTypeAddField (N->getText(), "UINT64", ArrayNum), N); >> + ; + +dataStructField32 : + << UINT32 ArrayNum = 0; >> + "UINT32" + N:StringIdentifier + { + OpenBracket I:Number CloseBracket << ArrayNum = _STOU32(I->getText()); >> + } + ";" << _PCATCH(mCVfrVarDataTypeDB.DataTypeAddField (N->getText(), "UINT32", ArrayNum), N); >> + ; + +dataStructField16 : + << UINT32 ArrayNum = 0; >> + ("UINT16" | "CHAR16") + N:StringIdentifier + { + OpenBracket I:Number CloseBracket << ArrayNum = _STOU32(I->getText()); >> + } + ";" << _PCATCH(mCVfrVarDataTypeDB.DataTypeAddField (N->getText(), "UINT16", ArrayNum), N); >> + ; + +dataStructField8 : + << UINT32 ArrayNum = 0; >> + "UINT8" + N:StringIdentifier + { + OpenBracket I:Number CloseBracket << ArrayNum = _STOU32(I->getText()); >> + } + ";" << _PCATCH(mCVfrVarDataTypeDB.DataTypeAddField (N->getText(), "UINT8", ArrayNum), N); >> + ; + +dataStructFieldBool : + << UINT32 ArrayNum = 0; >> + "BOOLEAN" + N:StringIdentifier + { + OpenBracket I:Number CloseBracket << ArrayNum = _STOU32(I->getText()); >> + } + ";" << _PCATCH(mCVfrVarDataTypeDB.DataTypeAddField (N->getText(), "BOOLEAN", ArrayNum), N); >> + ; + +dataStructFieldString : + << UINT32 ArrayNum = 0; >> + "EFI_STRING_ID" + N:StringIdentifier + { + OpenBracket I:Number CloseBracket << ArrayNum = _STOU32(I->getText()); >> + } + ";" << _PCATCH(mCVfrVarDataTypeDB.DataTypeAddField (N->getText(), "EFI_STRING_ID", ArrayNum), N); >> + ; + +dataStructFieldDate : + << UINT32 ArrayNum = 0; >> + "EFI_HII_DATE" + N:StringIdentifier + { + OpenBracket I:Number CloseBracket << ArrayNum = _STOU32(I->getText()); >> + } + ";" << _PCATCH(mCVfrVarDataTypeDB.DataTypeAddField (N->getText(), "EFI_HII_DATE", ArrayNum), N); >> + ; + +dataStructFieldTime : + << UINT32 ArrayNum = 0; >> + "EFI_HII_TIME" + N:StringIdentifier + { + OpenBracket I:Number CloseBracket << ArrayNum = _STOU32(I->getText()); >> + } + ";" << _PCATCH(mCVfrVarDataTypeDB.DataTypeAddField (N->getText(), "EFI_HII_TIME", ArrayNum), N); >> + ; + +dataStructFieldUser : + << UINT32 ArrayNum = 0; >> + T:StringIdentifier + N:StringIdentifier + { + OpenBracket I:Number CloseBracket << ArrayNum = _STOU32(I->getText()); >> + } + ";" << _PCATCH(mCVfrVarDataTypeDB.DataTypeAddField (N->getText(), T->getText(), ArrayNum), T); >> + ; + +//***************************************************************************** +// +// the syntax of from set definition +// +vfrFromSetDefinition : + << + EFI_GUID Guid; + CIfrFormSet FSObj; + UINT16 C, SC; + >> + L:FormSet << SET_LINE_INFO (FSObj, L); >> + GUID "=" + OpenBrace + G1:Number "," G2:Number "," G3:Number "," G4:Number "," G5:Number "," G6:Number "," + G7:Number "," G8:Number "," G9:Number "," G10:Number "," G11:Number + CloseBrace + << + _CRGUID (&Guid, G1->getText (), G2->getText (), G3->getText (), + G4->getText (), G5->getText (), G6->getText (), + G7->getText (), G8->getText (), G9->getText (), + G10->getText (), G11->getText ()); + FSObj.SetGuid (&Guid); + >> + "," + Title "=" "STRING_TOKEN" "\(" S1:Number "\)" "," << FSObj.SetFormSetTitle (_STOSID(S1->getText())); >> + Help "=" "STRING_TOKEN" "\(" S2:Number "\)" "," << FSObj.SetHelp (_STOSID(S2->getText())); >> + { + Class "=" classDefinition[C] "," << {CIfrClass CObj; CObj.SetClass(C);} >> + } + { + Subclass "=" subclassDefinition[SC] "," << {CIfrSubClass SCObj; SCObj.SetSubClass(SC);} >> + } + << + _DeclareStandardDefaultStorage (GET_LINENO (L)); + //_DeclareDefaultLinearVarStore (GET_LINENO (L)); + >> + vfrFormSetList + E:EndFormSet << CRT_END_OP (E); >> + ";" + ; + +vfrFormSetList : + ( + vfrFormDefinition | + vfrStatementImage | + vfrStatementVarStoreLinear | + vfrStatementVarStoreEfi | + vfrStatementVarStoreNameValue | + vfrStatementDefaultStore | + vfrStatementDisableIfFromSet + )* + ; + +vfrStatementDefaultStore : + << UINT16 DefaultId = EFI_HII_DEFAULT_CLASS_STANDARD; >> + D:DefaultStore N:StringIdentifier "," + Prompt "=" "STRING_TOKEN" "\(" S:Number "\)" + { + "," Attribute "=" A:Number << DefaultId = _STOU16(A->getText()); >> + } + << + if (mCVfrDefaultStore.DefaultIdRegistered (DefaultId) == FALSE) { + CIfrDefaultStore DSObj; + _PCATCH(mCVfrDefaultStore.RegisterDefaultStore (DSObj.GetObjBinAddr(), N->getText(), _STOSID(S->getText()), DefaultId)), D->getLine(); + DSObj.SetLineNo(D->getLine()); + DSObj.SetDefaultName (_STOSID(S->getText())); + DSObj.SetDefaultId (DefaultId); + } else { + _PCATCH(mCVfrDefaultStore.ReRegisterDefaultStoreById (DefaultId, N->getText(), _STOSID(S->getText()))), D->getLine(); + } + >> + ";" + ; + +vfrStatementVarStoreLinear : + << + EFI_GUID Guid; + CIfrVarStore VSObj; + INT8 *TypeName; + UINT32 LineNum; + EFI_VARSTORE_ID VarStoreId = EFI_VARSTORE_ID_INVALID; + UINT32 Size; + >> + V:Varstore << VSObj.SetLineNo(V->getLine()); >> + ( + TN:StringIdentifier "," << TypeName = TN->getText(); LineNum = TN->getLine(); >> + | U8:"UINT8" "," << TypeName = "UINT8"; LineNum = U8->getLine(); >> + | U16:"UINT16" "," << TypeName = "UINT16"; LineNum = U16->getLine(); >> + | U32:"UINT32" "," << TypeName = "UINT32"; LineNum = U32->getLine(); >> + | U64:"UINT64" "," << TypeName = "UINT64"; LineNum = U64->getLine(); >> + | D:"EFI_HII_DATE" "," << TypeName = "EFI_HII_DATE"; LineNum = D->getLine(); >> + | T:"EFI_HII_TIME" "," << TypeName = "EFI_HII_TIME"; LineNum = T->getLine(); >> + ) + { Key "=" Number "," } // Key is used to assign Varid in Framework VFR but no use in UEFI2.1 VFR + { + VarId "=" ID:Number "," << VarStoreId = _STOU16(ID->getText()); >> + } + Name "=" SN:StringIdentifier "," + GUID "=" + OpenBrace + G1:Number "," G2:Number "," G3:Number "," G4:Number "," G5:Number "," G6:Number "," + G7:Number "," G8:Number "," G9:Number "," G10:Number "," G11:Number + CloseBrace + << + _CRGUID (&Guid, G1->getText (), G2->getText (), G3->getText (), + G4->getText (), G5->getText (), G6->getText (), + G7->getText (), G8->getText (), G9->getText (), + G10->getText (), G11->getText ()); + >> + << + _PCATCH(mCVfrDataStorage.DeclareBufferVarStore ( + SN->getText(), + &Guid, + &mCVfrVarDataTypeDB, + TypeName, + VarStoreId + ), LineNum); + >> + << + VSObj.SetGuid (&Guid); + _PCATCH(mCVfrDataStorage.GetVarStoreId(SN->getText(), &VarStoreId), SN); + VSObj.SetVarStoreId (VarStoreId); + _PCATCH(mCVfrVarDataTypeDB.GetDataTypeSize(TypeName, &Size), LineNum); + VSObj.SetSize (Size); + VSObj.SetName (SN->getText()); + >> + ";" + ; + +vfrStatementVarStoreEfi : + << + EFI_GUID Guid; + CIfrVarStoreEfi VSEObj; + EFI_VARSTORE_ID VarStoreId; + UINT32 Attr = 0; + >> + E:Efivarstore << VSEObj.SetLineNo(E->getLine()); >> + SN:StringIdentifier "," + Attribute "=" vfrVarStoreEfiAttr[Attr] ( "\|" vfrVarStoreEfiAttr[Attr] )* "," + << VSEObj.SetAttributes (Attr); >> + Name "=" "STRING_TOKEN" "\(" VN:Number "\)" "," + VarSize "=" N:Number "," + GUID "=" + OpenBrace + G1:Number "," G2:Number "," G3:Number "," G4:Number "," G5:Number "," G6:Number "," + G7:Number "," G8:Number "," G9:Number "," G10:Number "," G11:Number + CloseBrace + << + _CRGUID (&Guid, G1->getText (), G2->getText (), G3->getText (), + G4->getText (), G5->getText (), G6->getText (), + G7->getText (), G8->getText (), G9->getText (), + G10->getText (), G11->getText ()); + >> + << mCVfrDataStorage.DeclareEfiVarStore (SN->getText(), &Guid, _STOSID(VN->getText()), _STOU32(N->getText())); >> + << + VSEObj.SetGuid (&Guid); + _PCATCH(mCVfrDataStorage.GetVarStoreId(SN->getText(), &VarStoreId), SN); + VSEObj.SetVarStoreId (VarStoreId); + >> + ";" + ; + +vfrVarStoreEfiAttr [UINT32 & Attr] : + N:Number << $Attr |= _STOU32(N->getText()); >> + ; + +vfrStatementVarStoreNameValue : + << + EFI_GUID Guid; + CIfrVarStoreNameValue VSNVObj; + EFI_VARSTORE_ID VarStoreId; + >> + L:NameValueVarStore << VSNVObj.SetLineNo(L->getLine()); >> + SN:StringIdentifier "," << _PCATCH(mCVfrDataStorage.DeclareNameVarStoreBegin (SN->getText()), SN); >> + ( + Name "=" "STRING_TOKEN" "\(" N:Number "\)" "," << _PCATCH(mCVfrDataStorage.NameTableAddItem (_STOSID(N->getText())), SN); >> + )+ + GUID "=" + OpenBrace + G1:Number "," G2:Number "," G3:Number "," G4:Number "," G5:Number "," G6:Number "," + G7:Number "," G8:Number "," G9:Number "," G10:Number "," G11:Number + CloseBrace + << + _CRGUID (&Guid, G1->getText (), G2->getText (), G3->getText (), + G4->getText (), G5->getText (), G6->getText (), + G7->getText (), G8->getText (), G9->getText (), + G10->getText (), G11->getText ()); + >> + << _PCATCH(mCVfrDataStorage.DeclareNameVarStoreEnd (&Guid), SN); >> + << + VSNVObj.SetGuid (&Guid); + _PCATCH(mCVfrDataStorage.GetVarStoreId(SN->getText(), &VarStoreId), SN); + VSNVObj.SetVarStoreId (VarStoreId); + >> + ";" + ; + +// +// keep classDeinition and validClassNames for compatibility but not generate +// any IFR object +// +classDefinition[UINT16 & Class] : + << $Class = 0; >> + validClassNames[$Class] ( "\|" validClassNames[$Class] )* + ; + +validClassNames[UINT16 & Class] : + ClassNonDevice << $Class |= EFI_NON_DEVICE_CLASS; >> + | ClassDiskDevice << $Class |= EFI_DISK_DEVICE_CLASS; >> + | ClassVideoDevice << $Class |= EFI_VIDEO_DEVICE_CLASS; >> + | ClassNetworkDevice << $Class |= EFI_NETWORK_DEVICE_CLASS; >> + | ClassInputDevice << $Class |= EFI_INPUT_DEVICE_CLASS; >> + | ClassOnBoardDevice << $Class |= EFI_ON_BOARD_DEVICE_CLASS; >> + | ClassOtherDevice << $Class |= EFI_OTHER_DEVICE_CLASS; >> + | N:Number << $Class |= _STOU16(N->getText()); >> + ; + +subclassDefinition[UINT16 & SubClass] : + << $SubClass = 0; >> + SubclassSetupApplication << $SubClass |= EFI_SETUP_APPLICATION_SUBCLASS; >> + | SubclassGeneralApplication << $SubClass |= EFI_GENERAL_APPLICATION_SUBCLASS; >> + | SubclassFrontPage << $SubClass |= EFI_FRONT_PAGE_SUBCLASS; >> + | SubclassSingleUse << $SubClass |= EFI_SINGLE_USE_SUBCLASS; >> + | N:Number << $SubClass |= _STOU16(N->getText()); >> + ; + +vfrStatementDisableIfFromSet : + << CIfrDisableIf DIObj; >> + D:DisableIf << DIObj.SetLineNo(D->getLine()); >> + vfrStatementExpression[0] ";" + vfrFormSetList + E:EndIf << CRT_END_OP (E); >> + ";" + ; + +//***************************************************************************** +// +// the syntax of question header and statement header +// +vfrStatementHeader[CIfrStatementHeader *SHObj] : + Prompt "=" "STRING_TOKEN" "\(" S1:Number "\)" "," << $SHObj->SetPrompt (_STOSID(S1->getText())); >> + Help "=" "STRING_TOKEN" "\(" S2:Number "\)" << $SHObj->SetHelp (_STOSID(S2->getText())); >> + ; + +vfrQuestionHeader[CIfrQuestionHeader & QHObj, EFI_QUESION_TYPE QType = QUESTION_NORMAL]: + << + EFI_VARSTORE_INFO Info; + EFI_QUESTION_ID QId = EFI_QUESTION_ID_INVALID; + INT8 *QName = NULL; + INT8 *VarIdStr = NULL; + >> + { + Name "=" QN:StringIdentifier "," << + QName = QN->getText(); + _PCATCH(mCVfrQuestionDB.FindQuestion (QName), VFR_RETURN_UNDEFINED, QN, "has already been used please used anther name"); + >> + } + { V:VarId "=" vfrStorageVarId[Info, VarIdStr] "," } + { + QuestionId "=" ID:Number "," << + QId = _STOQID(ID->getText()); + _PCATCH(mCVfrQuestionDB.FindQuestion (QId), VFR_RETURN_UNDEFINED, ID, "has already been used please assign another number"); + >> + } + << + switch (QType) { + case QUESTION_NORMAL: + mCVfrQuestionDB.RegisterQuestion (QName, VarIdStr, QId); + break; + case QUESTION_DATE: + mCVfrQuestionDB.RegisterNewDateQuestion (QName, VarIdStr, QId); + break; + case QUESTION_TIME: + mCVfrQuestionDB.RegisterNewTimeQuestion (QName, VarIdStr, QId); + break; + default: + _PCATCH(VFR_RETURN_FATAL_ERROR); + } + $QHObj.SetQuestionId (QId); + $QHObj.SetVarStoreInfo (&Info); + >> + vfrStatementHeader[&$QHObj] + << _SAVE_CURRQEST_VARINFO (Info); >> + << if (VarIdStr != NULL) delete VarIdStr; >> + ; + +vfrQuestionHeaderWithNoStorage[CIfrQuestionHeader *QHObj] : + << + EFI_QUESTION_ID QId = EFI_QUESTION_ID_INVALID; + INT8 *QName = NULL; + >> + { + Name "=" QN:StringIdentifier "," << + QName = QN->getText(); + _PCATCH(mCVfrQuestionDB.FindQuestion (QName), VFR_RETURN_UNDEFINED, QN, "has already been used please used anther name"); + >> + } + { + QuestionId "=" ID:Number "," << + QId = _STOQID(ID->getText()); + _PCATCH(mCVfrQuestionDB.FindQuestion (QId), VFR_RETURN_UNDEFINED, ID, "redefined quesiont ID"); + >> + } + << + mCVfrQuestionDB.RegisterQuestion (QName, NULL, QId); + $QHObj->SetQuestionId (QId); + >> + vfrStatementHeader[$QHObj] + ; + +questionheaderFlagsField[UINT8 & Flags] : + ReadOnlyFlag << $Flags |= 0x01; >> + | CallBackFlag << $Flags |= 0x04; >> + | ResetRequiredFlag << $Flags |= 0x10; >> + | OptionOnlyFlag << $Flags |= 0x80; >> + ; + +vfrStorageVarId[EFI_VARSTORE_INFO & Info, INT8 *&QuestVarIdStr] : + << + UINT32 Idx; + UINT32 LineNo; + EFI_VFR_VARSTORE_TYPE VarStoreType = EFI_VFR_VARSTORE_INVALID; + INT8 *VarIdStr = NULL; + INT8 *VarStr = NULL; + INT8 *SName = NULL; + INT8 *TName = NULL; + >> + ( + SN1:StringIdentifier << SName = SN1->getText(); _STRCAT(&VarIdStr, SN1->getText()); >> + OpenBracket I1:Number CloseBracket << Idx = _STOU32(I1->getText()); _STRCAT(&VarIdStr, "["); _STRCAT(&VarIdStr, I1->getText()); _STRCAT(&VarIdStr, "]"); >> + << + _PCATCH(mCVfrDataStorage.GetVarStoreType (SName, VarStoreType), SN1); + _PCATCH(mCVfrDataStorage.GetVarStoreId (SName, &$Info.mVarStoreId), SN1); + _PCATCH(mCVfrDataStorage.GetNameVarStoreInfo (&$Info, Idx), SN1); + >> + ) + | + ( + SN2:StringIdentifier << SName = SN2->getText(); _STRCAT(&VarIdStr, SName); >> + << + _PCATCH(mCVfrDataStorage.GetVarStoreType (SName, VarStoreType), SN2); + _PCATCH(mCVfrDataStorage.GetVarStoreId (SName, &$Info.mVarStoreId), SN2); + if (VarStoreType == EFI_VFR_VARSTORE_BUFFER) { + _PCATCH(mCVfrDataStorage.GetBufferVarStoreDataTypeName(SName, &TName), SN2); + _STRCAT(&VarStr, TName); + } + >> + + ( + "." << + _PCATCH(((VarStoreType != EFI_VFR_VARSTORE_BUFFER) ? VFR_RETURN_EFIVARSTORE_USE_ERROR : VFR_RETURN_SUCCESS), SN2); + _STRCAT(&VarIdStr, "."); _STRCAT(&VarStr, "."); + >> + SF:StringIdentifier << _STRCAT(&VarIdStr, SF->getText()); _STRCAT(&VarStr, SF->getText()); >> + { + OpenBracket I2:Number CloseBracket << _STRCAT(&VarIdStr, "["); _STRCAT(&VarIdStr, I2->getText()); _STRCAT(&VarIdStr, "]"); >> + << _STRCAT(&VarStr, "["); _STRCAT(&VarStr, I2->getText()); _STRCAT(&VarStr, "]"); >> + } + )* << + switch (VarStoreType) { + case EFI_VFR_VARSTORE_EFI: + _PCATCH(mCVfrDataStorage.GetEfiVarStoreInfo (&$Info), SN2); + break; + case EFI_VFR_VARSTORE_BUFFER: + _PCATCH(mCVfrVarDataTypeDB.GetDataFieldInfo (VarStr, $Info.mInfo.mVarOffset, $Info.mVarType, $Info.mVarTotalSize), SN2->getLine()); + //_PCATCH(mCVfrDataStorage.BufferVarStoreRequestElementAdd (SName, Info), SN2); + break; + case EFI_VFR_VARSTORE_NAME: + default: break; + } + + QuestVarIdStr = VarIdStr; + if (VarStr != NULL) {delete VarStr;} + >> + ) + ; + +vfrQuestionDataFieldName [EFI_QUESTION_ID &QId, UINT32 &Mask, INT8 *&VarIdStr, UINT32 &LineNo] : + << VarIdStr = NULL; LineNo = 0; >> + ( + SN1:StringIdentifier << _STRCAT(&VarIdStr, SN1->getText()); LineNo = SN1->getLine(); >> + OpenBracket I1:Number CloseBracket << _STRCAT(&VarIdStr, "["); _STRCAT(&VarIdStr, I1->getText()); _STRCAT(&VarIdStr, "]"); >> + << mCVfrQuestionDB.GetQuestionId (NULL, VarIdStr, $QId, $Mask); >> + ) + | + ( + SN2:StringIdentifier << _STRCAT (&VarIdStr, SN2->getText()); LineNo = SN2->getLine(); >> + ( + "." << _STRCAT (&VarIdStr, "."); >> + SF:StringIdentifier << _STRCAT(&VarIdStr, SF->getText()); >> + { + OpenBracket I2:Number CloseBracket << _STRCAT(&VarIdStr, "["); _STRCAT(&VarIdStr, I2->getText()); _STRCAT(&VarIdStr, "]"); >> + } + )* + << mCVfrQuestionDB.GetQuestionId (NULL, VarIdStr, $QId, $Mask); >> + ) + ; + +vfrConstantValueField[UINT8 Type] > [EFI_IFR_TYPE_VALUE Value] : + N1:Number << + switch ($Type) { + case EFI_IFR_TYPE_NUM_SIZE_8 : + $Value.u8 = _STOU8(N1->getText()); + break; + case EFI_IFR_TYPE_NUM_SIZE_16 : + $Value.u16 = _STOU16(N1->getText()); + break; + case EFI_IFR_TYPE_NUM_SIZE_32 : + $Value.u32 = _STOU32(N1->getText()); + break; + case EFI_IFR_TYPE_NUM_SIZE_64 : + $Value.u64 = _STOU64(N1->getText()); + break; + case EFI_IFR_TYPE_BOOLEAN : + $Value.b = _STOU8(N1->getText()); + break; + case EFI_IFR_TYPE_STRING : + $Value.string = _STOU16(N1->getText()); + break; + case EFI_IFR_TYPE_TIME : + case EFI_IFR_TYPE_DATE : + default : + break; + } + >> + | B1:True << $Value.b = TRUE; >> + | B2:False << $Value.b = FALSE; >> + | O1:One << $Value.u8 = _STOU8(O1->getText()); >> + | O2:Ones << $Value.u64 = _STOU64(O2->getText()); >> + | Z:Zero << $Value.u8 = _STOU8(Z->getText()); >> + | HOUR:Number ":" MINUTE:Number ":" SECOND:Number << $Value.time = _STOT(HOUR->getText(), MINUTE->getText(), SECOND->getText()); >> + | YEAR:Number "/" MONTH:Number "/" DAY:Number << $Value.date = _STOD(YEAR->getText(), MONTH->getText(), DAY->getText()); >> + | "STRING_TOKEN" "\(" S1:Number "\)" << $Value.string = _STOSID(S1->getText()); >> + ; + +//***************************************************************************** +// +// the syntax of form definition +// +vfrFormDefinition : + << CIfrForm FObj; >> + F:Form << FObj.SetLineNo(F->getLine()); >> + FormId "=" S1:Number "," << _PCATCH(FObj.SetFormId (_STOFID(S1->getText())), S1); >> + Title "=" "STRING_TOKEN" "\(" S2:Number "\)" ";" << FObj.SetFormTitle (_STOSID(S2->getText())); >> + ( + vfrStatementImage | + vfrStatementLocked | + vfrStatementRules | + vfrStatementDefault | + vfrStatementStat | + vfrStatementQuestions | + vfrStatementConditional | + vfrStatementLabel | + vfrStatementBanner + // Just for framework vfr compatibility + //vfrStatementInvalid + )* + E:EndForm << CRT_END_OP (E); >> + ";" + ; + +vfrStatementRules : + << CIfrRule RObj; >> + R:Rule << RObj.SetLineNo(R->getLine()); >> + S1:StringIdentifier "," << + mCVfrRulesDB.RegisterRule (S1->getText()); + RObj.SetRuleId (mCVfrRulesDB.GetRuleId(S1->getText())); + >> + vfrStatementExpression[0] + E:EndRule << CRT_END_OP (E); >> + ";" + ; + +vfrStatementDefault : + << + BOOLEAN IsExp = FALSE; + EFI_IFR_TYPE_VALUE Val; + CIfrDefault DObj; + EFI_DEFAULT_ID DefaultId = EFI_HII_DEFAULT_CLASS_STANDARD; + INT8 *VarStoreName = NULL; + EFI_VFR_VARSTORE_TYPE VarStoreType = EFI_VFR_VARSTORE_INVALID; + >> + D:Default << DObj.SetLineNo(D->getLine()); >> + ( + ( + vfrStatementValue "," << IsExp = TRUE; DObj.SetScope (1); >> + | "=" vfrConstantValueField[_GET_CURRQEST_DATATYPE()] > [Val] "," + << DObj.SetType (_GET_CURRQEST_DATATYPE()); DObj.SetValue(Val); >> + ) + { + DefaultStore "=" SN:StringIdentifier "," << _PCATCH(mCVfrDefaultStore.GetDefaultId (SN->getText(), &DefaultId), SN); DObj.SetDefaultId (DefaultId); >> + } + << + _PCATCH(mCVfrDataStorage.GetVarStoreName (_GET_CURRQEST_VARTINFO().mVarStoreId, &VarStoreName), D->getLine()); + _PCATCH(mCVfrDataStorage.GetVarStoreType (VarStoreName, VarStoreType), D->getLine()); + if ((IsExp == FALSE) && (VarStoreType == EFI_VFR_VARSTORE_BUFFER)) { + _PCATCH(mCVfrDefaultStore.BufferVarStoreAltConfigAdd ( + DefaultId, + _GET_CURRQEST_VARTINFO(), + VarStoreName, + _GET_CURRQEST_DATATYPE (), + Val), D->getLine()); + } + >> + ) + ; + +vfrStatementStat : + vfrStatementSubTitle | + vfrStatementStaticText | + vfrStatementCrossReference + ; + +vfrStatementQuestions : + vfrStatementBooleanType | + vfrStatementDate | + vfrStatementNumericType | + vfrStatementStringType | + vfrStatementOrderedList | + vfrStatementTime + ; + +vfrStatementConditional : + vfrStatementDisableIfStat | + vfrStatementSuppressIfStat | + vfrStatementGrayOutIfStat + ; + +vfrStatementInvalid : + << _CRT_OP (FALSE); >> + ( + vfrStatementInvalidHidden | + vfrStatementInvalidInconsistentIf | + vfrStatementInvalidInventory | + vfrStatementInvalidSaveRestoreDefaults + ) + << _CRT_OP (TRUE); >> + ; + +flagsField : + Number | InteractiveFlag | ManufacturingFlag | DefaultFlag | + NVAccessFlag | ResetRequiredFlag | LateCheckFlag + ; + +vfrStatementValue : + << CIfrValue VObj; >> + V:Value << VObj.SetLineNo(V->getLine()); >> + "=" vfrStatementExpression[0] + ; + +vfrStatementSubTitle : + << CIfrSubtitle SObj; >> + L:Subtitle << SObj.SetLineNo(L->getLine()); >> + Text "=" "STRING_TOKEN" "\(" S:Number "\)" << SObj.SetPrompt (_STOSID(S->getText())); >> + { + "," FLAGS "=" vfrSubtitleFlags[SObj] + } + { vfrStatementStatTagList "," } + E:";" << CRT_END_OP (E); >> + ; + +vfrSubtitleFlags [CIfrSubtitle & SObj] : + << UINT8 LFlags = 0; >> + subtitleFlagsField[LFlags] ( "\|" subtitleFlagsField[LFlags] )* + << _PCATCH(SObj.SetFlags (LFlags)); >> + ; + +subtitleFlagsField [UINT8 & Flags] : + N:Number << $Flags |= _STOU8(N->getText()); >> + | "HORIZONTAL" << $Flags |= 0x01; >> + ; + +vfrStatementStaticText : + << + UINT8 Flags = 0; + EFI_QUESTION_ID QId = EFI_QUESTION_ID_INVALID; + EFI_STRING_ID TxtTwo = EFI_STRING_ID_INVALID; + >> + T:Text + Help "=" "STRING_TOKEN" "\(" S1:Number "\)" "," + Text "=" "STRING_TOKEN" "\(" S2:Number "\)" + { + "," Text "=" "STRING_TOKEN" "\(" S3:Number "\)" << TxtTwo = _STOSID(S3->getText()); >> + } + { + "," F:FLAGS "=" staticTextFlagsField[Flags] ( "\|" staticTextFlagsField[Flags] )* + "," Key "=" KN:Number + } + << + if (Flags & EFI_IFR_FLAG_CALLBACK) { + CIfrAction AObj; + mCVfrQuestionDB.RegisterQuestion (NULL, NULL, QId); + AObj.SetQuestionId (QId); + AObj.SetPrompt (_STOSID(S2->getText())); + AObj.SetHelp (_STOSID(S1->getText())); + _PCATCH(AObj.SetFlags (Flags), F->getLine()); + AssignQuestionKey (AObj, KN); + CRT_END_OP (T); + } else { + CIfrText TObj; + TObj.SetLineNo (T->getLine()); + TObj.SetHelp (_STOSID(S1->getText())); + TObj.SetPrompt (_STOSID(S2->getText())); + TObj.SetTextTwo (TxtTwo); + } + >> + { "," vfrStatementStatTagList } + ";" + ; + +staticTextFlagsField[UINT8 & HFlags] : + N:Number << _PCATCH(_STOU8(N->getText()) == 0 ? VFR_RETURN_SUCCESS : VFR_RETURN_UNSUPPORTED, N->getLine()); >> + | questionheaderFlagsField[HFlags] + ; + +vfrStatementCrossReference : + vfrStatementGoto | + vfrStatementResetButton + ; + +vfrStatementGoto : + << + UINT8 RefType = 1; + EFI_STRING_ID DevPath; + EFI_GUID FSId; + EFI_FORM_ID FId; + EFI_QUESTION_ID QId = EFI_QUESTION_ID_INVALID; + UINT32 BitMask; + CIfrQuestionHeader *QHObj = NULL; + CIfrRef *R1Obj = NULL; + CIfrRef2 *R2Obj = NULL; + CIfrRef3 *R3Obj = NULL; + CIfrRef4 *R4Obj = NULL; + >> + G:Goto + ( + ( + DevicePath "=" "STRING_TOKEN" "\(" P:Number "\)" "," + FormSetGuid "=" + OpenBrace + G11:Number "," G12:Number "," G13:Number "," G14:Number "," G15:Number "," G16:Number "," + G17:Number "," G18:Number "," G19:Number "," G110:Number "," G111:Number + CloseBrace "," + FormId "=" F1:Number "," + Question "=" QN1:Number "," + << + RefType = 4; + _CRGUID (&FSId, G11->getText (), G12->getText (), G13->getText (), + G14->getText (), G15->getText (), G16->getText (), + G17->getText (), G18->getText (), G19->getText (), + G110->getText (), G111->getText ()); + DevPath = _STOSID(P->getText()); + FId = _STOFID(F1->getText()); + QId = _STOQID(QN1->getText()); + >> + ) + | + ( + FormSetGuid "=" + OpenBrace + G21:Number "," G22:Number "," G23:Number "," G24:Number "," G25:Number "," G26:Number "," + G27:Number "," G28:Number "," G29:Number "," G210:Number "," G211:Number + CloseBrace "," + FormId "=" F2:Number "," + Question "=" QN2:Number "," + << + RefType = 3; + _CRGUID (&FSId, G21->getText (), G22->getText (), G23->getText (), + G24->getText (), G25->getText (), G26->getText (), + G27->getText (), G28->getText (), G29->getText (), + G210->getText (), G211->getText ()); + FId = _STOFID(F2->getText()); + QId = _STOQID(QN2->getText()); + >> + ) + | + ( + FormId "=" F3:Number "," << RefType = 2; FId = _STOFID(F3->getText()); >> + Question "=" + ( + QN3:StringIdentifier "," << mCVfrQuestionDB.GetQuestionId (QN3->getText (), NULL, QId, BitMask); >> + | QN4:Number "," << QId = _STOQID(QN4->getText()); >> + ) + ) + | + ( + F4:Number "," << + RefType = 1; + FId = _STOFID(F4->getText()); + >> + ) + ) + << + switch (RefType) { + case 4: + { + R4Obj = new CIfrRef4; + QHObj = R4Obj; + R4Obj->SetLineNo(G->getLine()); + R4Obj->SetDevicePath (DevPath); + R4Obj->SetFormSetId (FSId); + R4Obj->SetFormId (FId); + R4Obj->SetQuestionId (QId); + break; + } + case 3: + { + R3Obj = new CIfrRef3; + QHObj = R3Obj; + R3Obj->SetLineNo(G->getLine()); + R3Obj->SetFormSetId (FSId); + R3Obj->SetFormId (FId); + R3Obj->SetQuestionId (QId); + break; + } + case 2: + { + R2Obj = new CIfrRef2; + QHObj = R2Obj; + R2Obj->SetLineNo(G->getLine()); + R2Obj->SetFormId (FId); + _PCATCH(R2Obj->SetQuestionId (QId), QN3); + break; + } + case 1: + { + R1Obj = new CIfrRef; + QHObj = R1Obj; + R1Obj->SetLineNo(G->getLine()); + R1Obj->SetFormId (FId); + break; + } + default: break; + } + >> + vfrQuestionHeaderWithNoStorage[QHObj] + { "," vfrStatementStatTagList } + { "," F:FLAGS "=" vfrGotoFlags[QHObj, F->getLine()] } + { + "," Key "=" KN:Number << AssignQuestionKey (*QHObj, KN); >> + } + ";" << if (R1Obj != NULL) {delete R1Obj;} if (R2Obj != NULL) {delete R2Obj;} if (R3Obj != NULL) {delete R3Obj;} if (R4Obj != NULL) {delete R4Obj;} >> + ; + +vfrGotoFlags [CIfrQuestionHeader *QHObj, UINT32 LineNum] : + << UINT8 HFlags = 0; >> + gotoFlagsField[HFlags] ( "\|" gotoFlagsField[HFlags] )* + << _PCATCH(QHObj->SetFlags (HFlags), LineNum); >> + ; + +gotoFlagsField[UINT8 & HFlags] : + N:Number << _PCATCH(_STOU8(N->getText()) == 0 ? VFR_RETURN_SUCCESS : VFR_RETURN_UNSUPPORTED, N->getLine()); >> + | questionheaderFlagsField[HFlags] + ; + +getStringId : + "STRING_TOKEN" "\(" + IdVal:Number + "\)" + ; + +vfrStatementResetButton : + << + CIfrResetButton RBObj; + UINT16 DefaultId; + >> + L:ResetButton << RBObj.SetLineNo(L->getLine()); >> + DefaultStore + "=" N:StringIdentifier "," << + _PCATCH(mCVfrDefaultStore.GetDefaultId (N->getText(), &DefaultId), N->getLine()); + RBObj.SetDefaultId (DefaultId); + >> + vfrStatementHeader[&RBObj] "," + { vfrStatementStatTagList "," } + E:EndResetButton << CRT_END_OP (E); >> + ";" + ; + +vfrStatementBooleanType : + vfrStatementCheckBox | + vfrStatementAction + ; + +//***************************************************** +// Syntax of checkbox +// +// Example: +// checkbox +// varid = MySTestData.mField1, +// prompt = STRING_TOKEN(STR_CHECK_BOX_PROMPT), +// help = STRING_TOKEN(STR_CHECK_BOX_HELP), +// flags = CHECKBOX_DEFAULT | CALLBACK, +// default value = TRUE, defaultstore = MyDefaultStore, +// endcheckbox; +// +vfrStatementCheckBox : + << + CIfrCheckBox CBObj; + >> + L:CheckBox << CBObj.SetLineNo(L->getLine()); >> + vfrQuestionHeader[CBObj] "," + { F:FLAGS "=" vfrCheckBoxFlags[CBObj, F->getLine()] "," } + { + Key "=" KN:Number "," << AssignQuestionKey (CBObj, KN); >> + } + vfrStatementQuestionOptionList + E:EndCheckBox << CRT_END_OP (E); >> + ";" + ; + +vfrCheckBoxFlags [CIfrCheckBox & CBObj, UINT32 LineNum] : + << + UINT8 LFlags = 0; + UINT8 HFlags = 0; + >> + checkboxFlagsField[LFlags, HFlags] ( "\|" checkboxFlagsField[LFlags, HFlags] )* + << _PCATCH(CBObj.SetFlags (HFlags, LFlags), LineNum); >> + ; + +checkboxFlagsField[UINT8 & LFlags, UINT8 & HFlags] : + N:Number << _PCATCH(_STOU8(N->getText()) == 0 ? VFR_RETURN_SUCCESS : VFR_RETURN_UNSUPPORTED, N->getLine()); >> + | "CHECKBOX_DEFAULT" << $LFlags |= 0x01; >> + | "CHECKBOX_DEFAULT_MFG" << $LFlags |= 0x02; >> + | questionheaderFlagsField[HFlags] + ; + +//***************************************************** +// Syntax of action +// +// Example: +// action +// prompt = STRING_TOKEN(STR_ACTION_PROMPT), +// help = STRING_TOKEN(STR_ACTION_HELP), +// flags = CALLBACK, +// config = STRING_TOKEN(STR_ACTION_CONFIG), +// endaction; +// +vfrStatementAction : + << CIfrAction AObj; >> + L:Action << AObj.SetLineNo(L->getLine()); >> + vfrQuestionHeaderWithNoStorage[&AObj] "," + { F:FLAGS "=" vfrActionFlags[AObj, F->getLine()] "," } + Config "=" "STRING_TOKEN" "\(" S:Number "\)" "," << AObj.SetQuestionConfig (_STOSID(S->getText())); >> + vfrStatementQuestionTagList + E:EndAction << CRT_END_OP (E); >> + ";" + ; + +vfrActionFlags[CIfrAction & AObj, UINT32 LineNum] : + << UINT8 HFlags = 0; >> + actionFlagsField[HFlags] ( "\|" actionFlagsField[HFlags] )* + << _PCATCH(AObj.SetFlags (HFlags), LineNum); >> + ; + +actionFlagsField[UINT8 & HFlags] : + N:Number << _PCATCH(_STOU8(N->getText()) == 0 ? VFR_RETURN_SUCCESS : VFR_RETURN_UNSUPPORTED, N->getLine()); >> + | questionheaderFlagsField[HFlags] + ; + +vfrStatementDate : + << + EFI_QUESTION_ID QId = EFI_QUESTION_ID_INVALID; + INT8 *VarIdStr[3] = {NULL, }; + CIfrDate DObj; + EFI_IFR_TYPE_VALUE Val; + >> + L:Date << DObj.SetLineNo(L->getLine()); >> + ( + ( + vfrQuestionHeader[DObj, QUESTION_DATE] "," + { F:FLAGS "=" vfrDateFlags[DObj, F->getLine()] "," } + vfrStatementQuestionOptionList + ) + | + ( + Year VarId "=" D1:StringIdentifier "." D1Y:StringIdentifier "," + << _STRCAT(&VarIdStr[0], D1->getText()); _STRCAT(&VarIdStr[0], "."); _STRCAT(&VarIdStr[0], D1Y->getText()); >> + Prompt "=" "STRING_TOKEN" "\(" YP:Number "\)" "," + Help "=" "STRING_TOKEN" "\(" YH:Number "\)" "," + minMaxDateStepDefault[Val.date, 0] + + Month VarId "=" D2:StringIdentifier "." D2M:StringIdentifier "," + << _STRCAT(&VarIdStr[1], D2->getText()); _STRCAT(&VarIdStr[1], "."); _STRCAT(&VarIdStr[1], D2M->getText()); >> + Prompt "=" "STRING_TOKEN" "\(" MP:Number "\)" "," + Help "=" "STRING_TOKEN" "\(" MH:Number "\)" "," + minMaxDateStepDefault[Val.date, 1] + + Day VarId "=" D3:StringIdentifier "." D3D:StringIdentifier "," + << _STRCAT(&VarIdStr[2], D3->getText()); _STRCAT(&VarIdStr[2], "."); _STRCAT(&VarIdStr[2], D3D->getText()); >> + Prompt "=" "STRING_TOKEN" "\(" DP:Number "\)" "," + Help "=" "STRING_TOKEN" "\(" DH:Number "\)" "," + minMaxDateStepDefault[Val.date, 2] + << + mCVfrQuestionDB.RegisterOldDateQuestion (VarIdStr[0], VarIdStr[1], VarIdStr[2], QId); + DObj.SetQuestionId (QId); + DObj.SetFlags (EFI_IFR_QUESTION_FLAG_DEFAULT, QF_DATE_STORAGE_TIME); + DObj.SetPrompt (_STOSID(YP->getText())); + DObj.SetHelp (_STOSID(YH->getText())); + if (VarIdStr[0] != NULL) { delete VarIdStr[0]; } if (VarIdStr[1] != NULL) { delete VarIdStr[1]; } if (VarIdStr[2] != NULL) { delete VarIdStr[2]; } + >> + << {CIfrDefault DObj(EFI_HII_DEFAULT_CLASS_STANDARD, EFI_IFR_TYPE_DATE, Val);} >> + ( vfrStatementInconsistentIf )* + ) + ) + E:EndDate << CRT_END_OP (E); >> + ";" + ; + +minMaxDateStepDefault[EFI_HII_DATE & D, UINT8 KeyValue] : + Minimum "=" Number "," + Maximum "=" Number "," + { "step" "=" Number "," } + { + "default" "=" N:Number "," << + switch (KeyValue) { + case 0: D.Year = _STOU16(N->getText()); break; + case 1: D.Month = _STOU8(N->getText()); break; + case 2: D.Day = _STOU8(N->getText()); break; + } + >> + } + ; + +vfrDateFlags [CIfrDate & DObj, UINT32 LineNum] : + << UINT8 LFlags = 0; >> + dateFlagsField[LFlags] ( "\|" dateFlagsField[LFlags] )* + << _PCATCH(DObj.SetFlags (EFI_IFR_QUESTION_FLAG_DEFAULT, LFlags), LineNum); >> + ; + +dateFlagsField [UINT8 & Flags] : + N:Number << $Flags |= _STOU8(N->getText()); >> + | "YEAR_SUPPRESS" << $Flags |= 0x01; >> + | "MONTH_SUPPRESS" << $Flags |= 0x02; >> + | "DAY_SUPPRESS" << $Flags |= 0x04; >> + | "STORAGE_NORMAL" << $Flags |= 0x00; >> + | "STORAGE_TIME" << $Flags |= 0x10; >> + | "STORAGE_WAKEUP" << $Flags |= 0x20; >> + ; + +vfrStatementNumericType : + vfrStatementNumeric | + vfrStatementOneOf + ; + +vfrSetMinMaxStep[CIfrMinMaxStepData & MMSDObj] : + << + UINT64 MaxU8 = 0, MinU8 = 0, StepU8 = 0; + UINT32 MaxU4 = 0, MinU4 = 0, StepU4 = 0; + UINT16 MaxU2 = 0, MinU2 = 0, StepU2 = 0; + UINT8 MaxU1 = 0, MinU1 = 0, StepU1 = 0; + >> + Minimum "=" I:Number "," + << + switch (_GET_CURRQEST_DATATYPE ()) { + case EFI_IFR_TYPE_NUM_SIZE_64 : MinU8 = _STOU64(I->getText()); break; + case EFI_IFR_TYPE_NUM_SIZE_32 : MinU4 = _STOU32(I->getText()); break; + case EFI_IFR_TYPE_NUM_SIZE_16 : MinU2 = _STOU16(I->getText()); break; + case EFI_IFR_TYPE_NUM_SIZE_8 : MinU1 = _STOU8(I->getText()); break; + } + >> + Maximum "=" A:Number "," + << + switch (_GET_CURRQEST_DATATYPE ()) { + case EFI_IFR_TYPE_NUM_SIZE_64 : MaxU8 = _STOU64(A->getText()); break; + case EFI_IFR_TYPE_NUM_SIZE_32 : MaxU4 = _STOU32(A->getText()); break; + case EFI_IFR_TYPE_NUM_SIZE_16 : MaxU2 = _STOU16(A->getText()); break; + case EFI_IFR_TYPE_NUM_SIZE_8 : MaxU1 = _STOU8(A->getText()); break; + } + >> + { + STEP "=" S:Number "," + << + switch (_GET_CURRQEST_DATATYPE ()) { + case EFI_IFR_TYPE_NUM_SIZE_64 : StepU8 = _STOU64(S->getText()); break; + case EFI_IFR_TYPE_NUM_SIZE_32 : StepU4 = _STOU32(S->getText()); break; + case EFI_IFR_TYPE_NUM_SIZE_16 : StepU2 = _STOU16(S->getText()); break; + case EFI_IFR_TYPE_NUM_SIZE_8 : StepU1 = _STOU8(S->getText()); break; + } + >> + } + << + switch (_GET_CURRQEST_DATATYPE ()) { + case EFI_IFR_TYPE_NUM_SIZE_64 : $MMSDObj.SetMinMaxStepData (MinU8, MaxU8, StepU8); break; + case EFI_IFR_TYPE_NUM_SIZE_32 : $MMSDObj.SetMinMaxStepData (MinU4, MaxU4, StepU4); break; + case EFI_IFR_TYPE_NUM_SIZE_16 : $MMSDObj.SetMinMaxStepData (MinU2, MaxU2, StepU2); break; + case EFI_IFR_TYPE_NUM_SIZE_8 : $MMSDObj.SetMinMaxStepData (MinU1, MaxU1, StepU1); break; + } + >> + ; + +vfrStatementNumeric : + << + CIfrNumeric NObj; + >> + L:Numeric << NObj.SetLineNo(L->getLine()); >> + vfrQuestionHeader[NObj] "," << _PCATCH(NObj.SetFlags (NObj.FLAGS(), _GET_CURRQEST_DATATYPE()), L->getLine()); >> + { F:FLAGS "=" vfrNumericFlags[NObj, F->getLine()] "," } + { + Key "=" KN:Number "," << AssignQuestionKey (NObj, KN); >> + } + vfrSetMinMaxStep[NObj] + vfrStatementQuestionOptionList + E:EndNumeric << CRT_END_OP (E); >> + ";" + ; + +vfrNumericFlags [CIfrNumeric & NObj, UINT32 LineNum] : + << + UINT8 LFlags = _GET_CURRQEST_DATATYPE(); + UINT8 HFlags = 0; + >> + numericFlagsField[HFlags, LFlags] ( "\|" numericFlagsField[HFlags, LFlags] )* + << _PCATCH(NObj.SetFlags (HFlags, LFlags), LineNum); >> + ; + +numericFlagsField [UINT8 & HFlags, UINT8 & LFlags] : + N:Number << _PCATCH(_STOU8(N->getText()) == 0 ? VFR_RETURN_SUCCESS : VFR_RETURN_UNSUPPORTED, N->getLine()); >> + | "DISPLAY_INT_DEC" << $LFlags |= 0x00; >> + | "DISPLAY_UINT_DEC" << $LFlags |= 0x10; >> + | "DISPLAY_UINT_HEX" << $LFlags |= 0x20; >> + | questionheaderFlagsField[HFlags] + ; + +vfrStatementOneOf : + << + CIfrOneOf OObj; + >> + L:OneOf << OObj.SetLineNo(L->getLine()); >> + vfrQuestionHeader[OObj] "," + { F:FLAGS "=" vfrOneofFlagsField[OObj, F->getLine()] "," } + { + vfrSetMinMaxStep[OObj] + } + vfrStatementQuestionOptionList + E:EndOneOf << CRT_END_OP (E); >> + ";" + ; + +vfrOneofFlagsField [CIfrOneOf & OObj, UINT32 LineNum] : + << + UINT8 LFlags = _GET_CURRQEST_DATATYPE(); + UINT8 HFlags = 0; + >> + numericFlagsField[HFlags, LFlags] ( "\|" numericFlagsField[HFlags, LFlags] )* + << _PCATCH(OObj.SetFlags (HFlags, LFlags), LineNum); >> + ; + +vfrStatementStringType : + vfrStatementString | + vfrStatementPassword + ; + +vfrStatementString : + << + CIfrString SObj; + >> + L:String << SObj.SetLineNo(L->getLine()); >> + vfrQuestionHeader[SObj] "," << _PCATCH(SObj.SetFlags (SObj.FLAGS(), _GET_CURRQEST_DATATYPE()), L->getLine()); >> + { F:FLAGS "=" vfrStringFlagsField[SObj, F->getLine()] "," } + { + Key "=" KN:Number "," << AssignQuestionKey (SObj, KN); >> + } + MinSize "=" MIN:Number "," << SObj.SetMinSize (_STOU8(MIN->getText())); >> + MaxSize "=" MAX:Number "," << SObj.SetMaxSize (_STOU8(MAX->getText())); >> + vfrStatementQuestionOptionList + E:EndString << CRT_END_OP (E); >> + ";" + ; + +vfrStringFlagsField [CIfrString & SObj, UINT32 LineNum] : + << + UINT8 LFlags = 0; + UINT8 HFlags = 0; + >> + stringFlagsField[HFlags, LFlags] ( "\|" stringFlagsField[HFlags, LFlags] )* + << _PCATCH(SObj.SetFlags (HFlags, LFlags), LineNum); >> + ; + +stringFlagsField [UINT8 & HFlags, UINT8 & LFlags] : + N:Number << _PCATCH(_STOU8(N->getText()) == 0 ? VFR_RETURN_SUCCESS : VFR_RETURN_UNSUPPORTED, N->getLine()); >> + | "MULTI_LINE" << $LFlags = 0x01; >> + | questionheaderFlagsField[HFlags] + ; + +vfrStatementPassword : + << + CIfrPassword PObj; + >> + L:Password << PObj.SetLineNo(L->getLine()); >> + vfrQuestionHeader[PObj] "," + { F:FLAGS "=" vfrPasswordFlagsField[PObj, F->getLine()] "," } + { + Key "=" KN:Number "," << AssignQuestionKey (PObj, KN); >> + } + MinSize "=" MIN:Number "," << PObj.SetMinSize (_STOU16(MIN->getText())); >> + MaxSize "=" MAX:Number "," << PObj.SetMaxSize (_STOU16(MAX->getText())); >> + { Encoding "=" Number "," } + vfrStatementQuestionOptionList + E:EndPassword << CRT_END_OP (E); >> + ";" + ; + +vfrPasswordFlagsField [CIfrPassword & PObj, UINT32 LineNum] : + << UINT8 HFlags = 0; >> + passwordFlagsField[HFlags] ( "\|" passwordFlagsField[HFlags] )* + << _PCATCH(PObj.SetFlags(HFlags), LineNum); >> + ; + +passwordFlagsField [UINT8 & HFlags] : + N:Number << _PCATCH(_STOU8(N->getText()) == 0 ? VFR_RETURN_SUCCESS : VFR_RETURN_UNSUPPORTED, N->getLine()); >> + | questionheaderFlagsField[HFlags] + ; + +vfrStatementOrderedList : + << + CIfrOrderedList OLObj; + >> + L:OrderedList << OLObj.SetLineNo(L->getLine()); >> + vfrQuestionHeader[OLObj] "," + << OLObj.SetMaxContainers ((UINT8)_GET_CURRQEST_VARSIZE()); >> + { + MaxContainers "=" M:Number "," << OLObj.SetMaxContainers (_STOU8(M->getText())); >> + } + { F:FLAGS "=" vfrOrderedListFlags[OLObj, F->getLine()] } + vfrStatementQuestionOptionList + E:EndList << CRT_END_OP (E); >> + ";" + ; + +vfrOrderedListFlags [CIfrOrderedList & OLObj, UINT32 LineNum] : + << + UINT8 HFlags = 0; + UINT8 LFlags = 0; + >> + orderedlistFlagsField[HFlags, LFlags] ( "\|" orderedlistFlagsField[HFlags, LFlags] )* + << _PCATCH(OLObj.SetFlags (HFlags, LFlags), LineNum); >> + ; + +orderedlistFlagsField [UINT8 & HFlags, UINT8 & LFlags] : + N:Number << _PCATCH(_STOU8(N->getText()) == 0 ? VFR_RETURN_SUCCESS : VFR_RETURN_UNSUPPORTED, N->getLine()); >> + | "UNIQUE" << $LFlags |= 0x01; >> + | "NOEMPTY" << $LFlags |= 0x02; >> + | questionheaderFlagsField[HFlags] + ; + +vfrStatementTime : + << + EFI_QUESTION_ID QId = EFI_QUESTION_ID_INVALID; + INT8 *VarIdStr[3] = {NULL, }; + CIfrTime TObj; + EFI_IFR_TYPE_VALUE Val; + >> + L:Time << TObj.SetLineNo(L->getLine()); >> + ( + ( + vfrQuestionHeader[TObj, QUESTION_TIME] "," + { F:FLAGS "=" vfrTimeFlags[TObj, F->getLine()] "," } + vfrStatementDefault + ) + | + ( + Hour VarId "=" T1:StringIdentifier "." T1H:StringIdentifier "," + << _STRCAT(&VarIdStr[0], T1->getText()); _STRCAT(&VarIdStr[0], "."); _STRCAT(&VarIdStr[0], T1H->getText()); >> + Prompt "=" "STRING_TOKEN" "\(" HP:Number "\)" "," + Help "=" "STRING_TOKEN" "\(" HH:Number "\)" "," + minMaxTimeStepDefault[Val.time, 0] + + Minute VarId "=" T2:StringIdentifier "." T2M:StringIdentifier "," + << _STRCAT(&VarIdStr[1], T2->getText()); _STRCAT(&VarIdStr[1], "."); _STRCAT(&VarIdStr[1], T2M->getText()); >> + Prompt "=" "STRING_TOKEN" "\(" MP:Number "\)" "," + Help "=" "STRING_TOKEN" "\(" MH:Number "\)" "," + minMaxTimeStepDefault[Val.time, 1] + + Second VarId "=" T3:StringIdentifier "." T3S:StringIdentifier "," + << _STRCAT(&VarIdStr[2], T3->getText()); _STRCAT(&VarIdStr[2], "."); _STRCAT(&VarIdStr[2], T3S->getText()); >> + Prompt "=" "STRING_TOKEN" "\(" SP:Number "\)" "," + Help "=" "STRING_TOKEN" "\(" SH:Number "\)" "," + minMaxTimeStepDefault[Val.time, 2] + << + mCVfrQuestionDB.RegisterOldTimeQuestion (VarIdStr[0], VarIdStr[1], VarIdStr[2], QId); + TObj.SetQuestionId (QId); + TObj.SetFlags (EFI_IFR_QUESTION_FLAG_DEFAULT, QF_TIME_STORAGE_TIME); + TObj.SetPrompt (_STOSID(HP->getText())); + TObj.SetHelp (_STOSID(HH->getText())); + if (VarIdStr[0] != NULL) { delete VarIdStr[0]; } if (VarIdStr[1] != NULL) { delete VarIdStr[1]; } if (VarIdStr[2] != NULL) { delete VarIdStr[2]; } + >> + << {CIfrDefault DObj(EFI_HII_DEFAULT_CLASS_STANDARD, EFI_IFR_TYPE_TIME, Val);} >> + ) + ) + E:EndTime << CRT_END_OP (E); >> + ";" + ; + +minMaxTimeStepDefault[EFI_HII_TIME & T, UINT8 KeyValue] : + Minimum "=" Number "," + Maximum "=" Number "," + { "step" "=" Number "," } + { + "default" "=" N:Number "," << + switch (KeyValue) { + case 0: T.Hour = _STOU8(N->getText()); break; + case 1: T.Minute = _STOU8(N->getText()); break; + case 2: T.Second = _STOU8(N->getText()); break; + } + >> + } + ; + +vfrTimeFlags [CIfrTime & TObj, UINT32 LineNum] : + << UINT8 LFlags = 0; >> + timeFlagsField[LFlags] ( "\|" timeFlagsField[LFlags] )* + << _PCATCH(TObj.SetFlags(EFI_IFR_QUESTION_FLAG_DEFAULT, LFlags), LineNum); >> + ; + +timeFlagsField [UINT8 & Flags] : + N:Number << $Flags |= _STOU8(N->getText()); >> + | "HOUR_SUPPRESS" << $Flags |= 0x01; >> + | "MINUTE_SUPPRESS" << $Flags |= 0x02; >> + | "SECOND_SUPPRESS" << $Flags |= 0x04; >> + | "STORAGE_NORMAL" << $Flags |= 0x00; >> + | "STORAGE_TIME" << $Flags |= 0x10; >> + | "STORAGE_WAKEUP" << $Flags |= 0x20; >> + ; + +vfrStatementQuestionTag : + vfrStatementStatTag "," | + vfrStatementInconsistentIf | + vfrStatementNoSubmitIf | + vfrStatementDisableIfQuest | + vfrStatementRefresh | + vfrStatementVarstoreDevice + ; + +vfrStatementQuestionTagList : + ( vfrStatementQuestionTag )* + ; + +vfrStatementQuestionOptionTag : + vfrStatementSuppressIfQuest | + vfrStatementValue | + vfrStatementDefault | + vfrStatementOptions + ; + +vfrStatementQuestionOptionList : + ( + vfrStatementQuestionTag | + vfrStatementQuestionOptionTag + )* + ; + +vfrStatementStatList : + vfrStatementStat | + vfrStatementQuestions | + vfrStatementConditional | + // Just for framework vfr compatibility + vfrStatementLabel + //vfrStatementInvalid + ; + +vfrStatementDisableIfStat : + << CIfrDisableIf DIObj; >> + L:DisableIf << DIObj.SetLineNo(L->getLine()); >> + vfrStatementExpression[0] ";" + ( vfrStatementStatList )* + E:EndIf << CRT_END_OP (E); >> + ";" + ; + +vfrStatementSuppressIfStat : + << CIfrSuppressIf SIObj; >> + L:SuppressIf << SIObj.SetLineNo(L->getLine()); >> + { FLAGS "=" flagsField ( "\|" flagsField )* "," } + vfrStatementExpression[0] ";" + ( vfrStatementStatList )* + E:EndIf << CRT_END_OP (E); >> + ";" + ; + +vfrStatementGrayOutIfStat : + << CIfrGrayOutIf GOIObj; >> + L:GrayOutIf << GOIObj.SetLineNo(L->getLine()); >> + { FLAGS "=" flagsField ( "\|" flagsField )* "," } + vfrStatementExpression[0] + ";" + ( vfrStatementStatList )* + E:EndIf << CRT_END_OP (E); >> + ";" + ; + +vfrImageTag : + << CIfrImage IObj; >> + L:Image "=" "IMAGE_TOKEN" "\(" S1:Number "\)" << IObj.SetImageId (_STOSID(S1->getText())); IObj.SetLineNo(L->getLine()); >> + ; + +vfrLockedTag : + << CIfrLocked LObj; >> + L:Locked << LObj.SetLineNo(L->getLine()); >> + ; + +vfrStatementStatTag : + vfrImageTag | + vfrLockedTag + ; + +vfrStatementStatTagList : + vfrStatementStatTag ( "," vfrStatementStatTag )* + ; + +vfrStatementImage : + vfrImageTag + ";" + ; + +vfrStatementLocked : + vfrLockedTag + ";" + ; + +vfrStatementInconsistentIf : + << CIfrInconsistentIf IIObj; >> + L:InconsistentIf << IIObj.SetLineNo(L->getLine()); >> + Prompt "=" "STRING_TOKEN" "\(" S:Number "\)" "," << IIObj.SetError (_STOSID(S->getText())); >> + { FLAGS "=" flagsField ( "\|" flagsField )* "," } + vfrStatementExpression[0] + E:EndIf << CRT_END_OP (E); >> + ; + +vfrStatementNoSubmitIf : + << CIfrNoSubmitIf NSIObj; >> + L:NoSubmitIf << NSIObj.SetLineNo(L->getLine()); >> + Prompt "=" "STRING_TOKEN" "\(" S:Number "\)" "," << NSIObj.SetError (_STOSID(S->getText())); >> + { FLAGS "=" flagsField ( "\|" flagsField )* "," } + vfrStatementExpression[0] + E:EndIf << CRT_END_OP (E); >> + ; + +vfrStatementDisableIfQuest : + << CIfrDisableIf DIObj; >> + L:DisableIf << DIObj.SetLineNo(L->getLine()); >> + vfrStatementExpression[0] ";" + vfrStatementQuestionOptionList + E:EndIf << CRT_END_OP (E); >> + ; + +vfrStatementRefresh : + << CIfrRefresh RObj; >> + L:Refresh << RObj.SetLineNo(L->getLine()); >> + Interval "=" I:Number << RObj.SetRefreshInterval (_STOU8(I->getText())); >> + ; + +vfrStatementVarstoreDevice : + << CIfrVarStoreDevice VDObj; >> + L:VarstoreDevice << VDObj.SetLineNo(L->getLine()); >> + "=" "STRING_TOKEN" "\(" S:Number "\)" "," << VDObj.SetDevicePath (_STOSID(S->getText())); >> + ; + +vfrStatementSuppressIfQuest : + << CIfrSuppressIf SIObj; >> + L:SuppressIf << SIObj.SetLineNo(L->getLine()); >> + { FLAGS "=" flagsField ( "\|" flagsField )* "," } + vfrStatementExpression[0] ";" + vfrStatementQuestionOptionList + E:EndIf << CRT_END_OP (E); >> + ; + +vfrStatementOptions : + vfrStatementOneOfOption + ; + +vfrStatementOneOfOption : + << + EFI_IFR_TYPE_VALUE Val; + CIfrOneOfOption OOOObj; + INT8 *VarStoreName = NULL; + + >> + L:Option << OOOObj.SetLineNo(L->getLine()); >> + Text "=" "STRING_TOKEN" "\(" S:Number "\)" "," << OOOObj.SetOption (_STOSID(S->getText())); >> + Value "=" vfrConstantValueField[_GET_CURRQEST_DATATYPE()] >[Val] "," << OOOObj.SetType (_GET_CURRQEST_DATATYPE()); OOOObj.SetValue (Val); >> + F:FLAGS "=" vfrOneOfOptionFlags[OOOObj, F->getLine()] + << + if (OOOObj.GetFlags () & 0x10) { + _PCATCH(mCVfrDataStorage.GetVarStoreName (_GET_CURRQEST_VARTINFO().mVarStoreId, &VarStoreName), L->getLine()); + _PCATCH(mCVfrDefaultStore.BufferVarStoreAltConfigAdd ( + EFI_HII_DEFAULT_CLASS_STANDARD, + _GET_CURRQEST_VARTINFO(), + VarStoreName, + _GET_CURRQEST_DATATYPE (), + Val + ), L->getLine()); + } + >> + { "," Key "=" Number } // no use in UEFI2.1 VFR + ( + "," vfrImageTag << OOOObj.SetScope (1); CIfrEnd EOOOObj; >> + )* + ";" + ; + +vfrOneOfOptionFlags [CIfrOneOfOption & OOOObj, UINT32 LineNum] : + << + UINT8 LFlags = _GET_CURRQEST_DATATYPE(); + UINT8 HFlags = 0; + >> + oneofoptionFlagsField[HFlags, LFlags] ( "\|" oneofoptionFlagsField[HFlags, LFlags] )* + << _PCATCH(gCurrentQuestion->SetFlags(HFlags), LineNum); >> + << _PCATCH(OOOObj.SetFlags(LFlags), LineNum); >> + ; + +oneofoptionFlagsField [UINT8 & HFlags, UINT8 & LFlags] : + N:Number << $LFlags |= _STOU8(N->getText()); >> + | "OPTION_DEFAULT" << $LFlags |= 0x10; >> + | "OPTION_DEFAULT_MFG" << $LFlags |= 0x20; >> + | InteractiveFlag << $HFlags |= 0x04; >> + | NVAccessFlag << $HFlags |= 0x08; >> + | ResetRequiredFlag << $HFlags |= 0x10; >> + | LateCheckFlag << $HFlags |= 0x20; >> + | ManufacturingFlag << $LFlags |= 0x20; >> + | DefaultFlag << $LFlags |= 0x10; >> + ; + +//vfrStatementGuid : +// << +// EFI_GUID Guid; +// CIfrGuid GObj; +// >> +// GuidAction +// GUID "=" +// OpenBrace +// G1:Number "," G2:Number "," G3:Number "," G4:Number "," G5:Number "," G6:Number "," +// G7:Number "," G8:Number "," G9:Number "," G10:Number "," G11:Number +// CloseBrace +// << +// _CRGUID (&Guid, G1->getText (), G2->getText (), G3->getText (), +// G4->getText (), G5->getText (), G6->getText (), +// G7->getText (), G8->getText (), G9->getText (), +// G10->getText (), G11->getText ()); +// >> +// << GObj.SetGuid (&Guid); >> +// ";" +// ; + +vfrStatementLabel : + << CIfrLabel LObj; >> + L:Label << LObj.SetLineNo(L->getLine()); >> + N:Number << LObj.SetNumber (_STOU16(N->getText())); >> + ";" + ; + +vfrStatementBanner : + << CIfrBanner BObj; >> + B:Banner { "," } << BObj.SetLineNo(B->getLine()); >> + Title "=" "STRING_TOKEN" "\(" S:Number "\)" "," << BObj.SetTitle (_STOSID(S->getText())); >> + ( + ( + Line L:Number "," << BObj.SetLine (_STOU16(L->getText())); >> + Align + ( + Left << BObj.SetAlign (0); >> + | Center << BObj.SetAlign (1); >> + | Right << BObj.SetAlign (2); >> + ) ";" + ) + | + ( + Timeout "=" T:Number ";" << {CIfrTimeout TObj(_STOU16(T->getText()));} >> + ) + ) + ; + +//****************************************************************************** +// +// keep some syntax for compatibility but not generate any IFR object +// +vfrStatementInvalidHidden : + Hidden + Value "=" Number "," + Key "=" Number ";" + ; + +vfrStatementInvalidInconsistentIf : + InconsistentIf + Prompt "=" "STRING_TOKEN" "\(" S:Number "\)" "," + { FLAGS "=" flagsField ( "\|" flagsField )* "," } + vfrStatementExpression[0] + EndIf + ";" + ; + +vfrStatementInvalidInventory : + Inventory + Help "=" "STRING_TOKEN" "\(" Number "\)" "," + Text "=" "STRING_TOKEN" "\(" Number "\)" "," + { + Text "=" "STRING_TOKEN" "\(" Number "\)" + } + ";" + ; + +vfrStatementInvalidSaveRestoreDefaults : + (Save | Restore) + Defaults "," + FormId "=" Number "," + Prompt "=" "STRING_TOKEN" "\(" Number "\)" "," + Help "=" "STRING_TOKEN" "\(" Number "\)" + { "," FLAGS "=" flagsField ( "\|" flagsField )* } + { "," Key "=" Number } + ";" + ; + +//****************************************************************************** +// +// The syntax of expression +// +#token Dup("dup") "dup" +#token VarEqVal("vareqval") "vareqval" +#token Var("var") "var" +#token IdEqVal("ideqval") "ideqval" +#token IdEqId("ideqid") "ideqid" +#token IdEqValList("ideqvallist") "ideqvallist" +#token QuestionRef("questionref") "questionref" +#token RuleRef("ruleref") "ruleref" +#token StringRef("stringref") "stringref" +#token PushThis("pushthis") "pushthis" +#token True("TRUE") "TRUE" +#token False("FALSE") "FALSE" +#token One("ONE") "ONE" +#token Ones("ONES") "ONES" +#token Zero("ZERO") "ZERO" +#token Undefined("UNDEFINED") "UNDEFINED" +#token Version("VERSOPM") "VERSION" +#token Length("length") "length" +#token AND("AND") "AND" +#token OR("OR") "OR" +#token NOT("NOT") "NOT" +#token BitWiseNot("~") "\~" +#token BoolVal("boolval") "boolval" +#token StringVal("stringval") "stringval" +#token UnIntVal("unintval") "unintval" +#token ToUpper("toupper") "toupper" +#token ToLower("tolower") "tolower" +#token Match("match") "match" +#token Catenate("catenate") "catenate" +#token QuestionRefVal("questionrefval") "questionrefval" +#token StringRefVal("stringrefval") "stringrefval" + +vfrStatementExpression [UINT32 RootLevel, UINT32 ExpOpCount = 0] : + << if ($RootLevel == 0) {_CLEAR_SAVED_OPHDR ();} >> + andTerm[$RootLevel, $ExpOpCount] + ( + L:OR andTerm[$RootLevel, $ExpOpCount] << $ExpOpCount++; CIfrOr OObj(L->getLine()); >> + )* + << if (($RootLevel == 0) && ($ExpOpCount > 1)) {_SET_SAVED_OPHDR_SCOPE(); CIfrEnd EObj; } >> + ; + +andTerm[UINT32 & RootLevel, UINT32 & ExpOpCount] : + bitwiseorTerm[$RootLevel, $ExpOpCount] + ( + L:AND bitwiseorTerm [$RootLevel, $ExpOpCount] << $ExpOpCount++; CIfrAnd AObj(L->getLine()); >> + )* + ; + +bitwiseorTerm [UINT32 & RootLevel, UINT32 & ExpOpCount]: + bitwiseandTerm[$RootLevel, $ExpOpCount] + ( + L:"\|" bitwiseandTerm[$RootLevel, $ExpOpCount] << $ExpOpCount++; CIfrBitWiseOr BWOObj(L->getLine()); >> + )* + ; + +bitwiseandTerm [UINT32 & RootLevel, UINT32 & ExpOpCount]: + equalTerm[$RootLevel, $ExpOpCount] + ( + L:"&" equalTerm[$RootLevel, $ExpOpCount] << $ExpOpCount++; CIfrBitWiseAnd BWAObj(L->getLine()); >> + )* + ; + +equalTerm [UINT32 & RootLevel, UINT32 & ExpOpCount]: + compareTerm[$RootLevel, $ExpOpCount] + ( + ( + L1:"==" compareTerm[$RootLevel, $ExpOpCount] << $ExpOpCount++; CIfrEqual EObj(L1->getLine()); >> + ) + | + ( + L2:"!=" compareTerm[$RootLevel, $ExpOpCount] << $ExpOpCount++; CIfrNotEqual NEObj(L2->getLine()); >> + ) + )* + ; + +compareTerm [UINT32 & RootLevel, UINT32 & ExpOpCount]: + shiftTerm[$RootLevel, $ExpOpCount] + ( + ( + L1:"<" shiftTerm[$RootLevel, $ExpOpCount] << $ExpOpCount++; CIfrLessThan LTObj(L1->getLine()); >> + ) + | + ( + L2:"<=" shiftTerm[$RootLevel, $ExpOpCount] << $ExpOpCount++; CIfrLessEqual LEObj(L2->getLine()); >> + ) + | + ( + L3:">" shiftTerm[$RootLevel, $ExpOpCount] << $ExpOpCount++; CIfrGreaterThan GTObj(L3->getLine()); >> + ) + | + ( + L4:">=" shiftTerm[$RootLevel, $ExpOpCount] << $ExpOpCount++; CIfrGreaterEqual GEObj(L4->getLine()); >> + ) + )* + ; + +shiftTerm [UINT32 & RootLevel, UINT32 & ExpOpCount]: + addMinusTerm[$RootLevel, $ExpOpCount] + ( + ( + L1:"\<<" addMinusTerm[$RootLevel, $ExpOpCount] << $ExpOpCount++; CIfrShiftLeft SLObj(L1->getLine()); >> + ) + | + ( + L2:"\>>" addMinusTerm[$RootLevel, $ExpOpCount] << $ExpOpCount++; CIfrShiftRight SRObj(L2->getLine()); >> + ) + )* + ; + +addMinusTerm [UINT32 & RootLevel, UINT32 & ExpOpCount]: + multdivmodTerm[$RootLevel, $ExpOpCount] + ( + ( + L1:"\+" multdivmodTerm[$RootLevel, $ExpOpCount] << $ExpOpCount++; CIfrAdd AObj(L1->getLine()); >> + ) + | + ( + L2:"\-" multdivmodTerm[$RootLevel, $ExpOpCount] << $ExpOpCount++; CIfrSubtract SObj(L2->getLine()); >> + ) + )* + ; + +multdivmodTerm [UINT32 & RootLevel, UINT32 & ExpOpCount]: + atomTerm[$RootLevel, $ExpOpCount] + ( + ( + L1:"\*" atomTerm[$RootLevel, $ExpOpCount] << $ExpOpCount++; CIfrMultiply MObj(L1->getLine()); >> + ) + | + ( + L2:"/" atomTerm[$RootLevel, $ExpOpCount] << $ExpOpCount++; CIfrDivide DObj(L2->getLine()); >> + ) + | + ( + L3:"%" atomTerm[$RootLevel, $ExpOpCount] << $ExpOpCount++; CIfrModulo MObj(L3->getLine()); >> + ) + )* + ; + +atomTerm [UINT32 & RootLevel, UINT32 & ExpOpCount]: + vfrExpressionCatenate[$RootLevel, $ExpOpCount] + | vfrExpressionMatch[$RootLevel, $ExpOpCount] + | vfrExpressionParen[$RootLevel, $ExpOpCount] + | vfrExpressionBuildInFunction[$RootLevel, $ExpOpCount] + | vfrExpressionConstant[$RootLevel, $ExpOpCount] + | vfrExpressionUnaryOp[$RootLevel, $ExpOpCount] + | vfrExpressionTernaryOp[$RootLevel, $ExpOpCount] + | ( + L:NOT + atomTerm[$RootLevel, $ExpOpCount] << { CIfrNot NObj(L->getLine()); $ExpOpCount++; } >> + ) + ; + +vfrExpressionCatenate [UINT32 & RootLevel, UINT32 & ExpOpCount]: + L:Catenate + "\(" + vfrStatementExpression[$RootLevel + 1, $ExpOpCount] + "," + vfrStatementExpression[$RootLevel + 1, $ExpOpCount] + "\)" << { CIfrCatenate CObj(L->getLine()); $ExpOpCount++; } >> + ; + +vfrExpressionMatch [UINT32 & RootLevel, UINT32 & ExpOpCount]: + L:Match + "\(" + vfrStatementExpression[$RootLevel + 1, $ExpOpCount] + "," + vfrStatementExpression[$RootLevel + 1, $ExpOpCount] + "\)" << { CIfrMatch MObj(L->getLine()); $ExpOpCount++; } >> + ; + +vfrExpressionParen [UINT32 & RootLevel, UINT32 & ExpOpCount]: + "\(" + vfrStatementExpression[$RootLevel + 1, $ExpOpCount] + "\)" + ; + +vfrExpressionBuildInFunction [UINT32 & RootLevel, UINT32 & ExpOpCount] : + dupExp[$RootLevel, $ExpOpCount] + | ideqvalExp[$RootLevel, $ExpOpCount] + | ideqidExp[$RootLevel, $ExpOpCount] + | ideqvallistExp[$RootLevel, $ExpOpCount] + | questionref13Exp[$RootLevel, $ExpOpCount] + | rulerefExp[$RootLevel, $ExpOpCount] + | stringref1Exp[$RootLevel, $ExpOpCount] + | pushthisExp[$RootLevel, $ExpOpCount] + ; + +dupExp [UINT32 & RootLevel, UINT32 & ExpOpCount] : + L:Dup << { CIfrDup DObj(L->getLine()); _SAVE_OPHDR_COND(DObj, ($ExpOpCount == 0)); $ExpOpCount++; } >> + ; + +ideqvalExp [UINT32 & RootLevel, UINT32 & ExpOpCount] : + << + EFI_QUESTION_ID QId; + UINT32 Mask; + UINT16 ConstVal; + INT8 *VarIdStr; + UINT32 LineNo; + >> + L:IdEqVal + vfrQuestionDataFieldName[QId, Mask, VarIdStr, LineNo] + ( + ( + "==" + V1:Number << ConstVal = _STOU16(V1->getText()); >> + << + if (Mask == 0) { + CIfrEqIdVal EIVObj (L->getLine()); + _SAVE_OPHDR_COND (EIVObj, ($ExpOpCount == 0)); + EIVObj.SetQuestionId (QId, VarIdStr, LineNo); + EIVObj.SetValue (ConstVal); + $ExpOpCount++; + } else { + IdEqValDoSpecial ($ExpOpCount, L->getLine(), QId, VarIdStr, Mask, ConstVal, EQUAL); + } + >> + ) + | + ( + "<=" + V2:Number << ConstVal = _STOU16(V2->getText()); >> + << IdEqValDoSpecial ($ExpOpCount, L->getLine(), QId, VarIdStr, Mask, ConstVal, LESS_EQUAL); >> + ) + | + ( + "<" + V3:Number << ConstVal = _STOU16(V3->getText()); >> + << IdEqValDoSpecial ($ExpOpCount, L->getLine(), QId, VarIdStr, Mask, ConstVal, LESS_THAN); >> + ) + | + ( + ">=" + V4:Number << ConstVal = _STOU16(V4->getText()); >> + << IdEqValDoSpecial ($ExpOpCount, L->getLine(), QId, VarIdStr, Mask, ConstVal, GREATER_EQUAL); >> + ) + | + ( + ">" + V5:Number << ConstVal = _STOU16(V5->getText()); >> + << IdEqValDoSpecial ($ExpOpCount, L->getLine(), QId, VarIdStr, Mask, ConstVal, GREATER_THAN); >> + ) + ) + ; + +ideqidExp[UINT32 & RootLevel, UINT32 & ExpOpCount] : + << + EFI_QUESTION_ID QId[2]; + UINT32 Mask[2]; + INT8 *VarIdStr[2]; + UINT32 LineNo[2]; + >> + L:IdEqId + vfrQuestionDataFieldName[QId[0], Mask[0], VarIdStr[0], LineNo[0]] + ( + ( + "==" + vfrQuestionDataFieldName[QId[1], Mask[1], VarIdStr[1], LineNo[1]] + << + if (Mask[0] & Mask[1]) { + IdEqIdDoSpecial ($ExpOpCount, L->getLine(), QId[0], VarIdStr[0], Mask[0], QId[1], VarIdStr[1], Mask[1], EQUAL); + } else { + CIfrEqIdId EIIObj(L->getLine()); + _SAVE_OPHDR_COND (EIIObj, ($ExpOpCount == 0)); + EIIObj.SetQuestionId1 (QId[0], VarIdStr[0], LineNo[0]); + EIIObj.SetQuestionId2 (QId[1], VarIdStr[1], LineNo[1]); + $ExpOpCount++; + } + >> + ) + | + ( + "<=" + vfrQuestionDataFieldName[QId[1], Mask[1], VarIdStr[1], LineNo[1]] + << IdEqIdDoSpecial ($ExpOpCount, L->getLine(), QId[0], VarIdStr[0], Mask[0], QId[1], VarIdStr[1], Mask[1], LESS_EQUAL); >> + ) + | + ( + "<" + vfrQuestionDataFieldName[QId[1], Mask[1], VarIdStr[1], LineNo[1]] + << IdEqIdDoSpecial ($ExpOpCount, L->getLine(), QId[0], VarIdStr[0], Mask[0], QId[1], VarIdStr[1], Mask[1], LESS_THAN); >> + ) + | + ( + ">=" + vfrQuestionDataFieldName[QId[1], Mask[1], VarIdStr[1], LineNo[1]] + << IdEqIdDoSpecial ($ExpOpCount, L->getLine(), QId[0], VarIdStr[0], Mask[0], QId[1], VarIdStr[1], Mask[1], GREATER_EQUAL); >> + ) + | + ( + ">" + vfrQuestionDataFieldName[QId[1], Mask[1], VarIdStr[1], LineNo[1]] + << IdEqIdDoSpecial ($ExpOpCount, L->getLine(), QId[0], VarIdStr[0], Mask[0], QId[1], VarIdStr[1], Mask[1], GREATER_THAN); >> + ) + ) + ; + +ideqvallistExp[UINT32 & RootLevel, UINT32 & ExpOpCount] : + << + UINT16 ListLen = 0; + EFI_QUESTION_ID QId; + UINT32 Mask; + UINT16 ValueList[EFI_IFR_MAX_LENGTH] = {0,}; + INT8 *VarIdStr; + UINT32 LineNo; + >> + L:IdEqValList + vfrQuestionDataFieldName[QId, Mask, VarIdStr, LineNo] + "==" + ( + V:Number << ValueList[ListLen] = _STOU16(V->getText()); ListLen++; >> + )+ + << + if (Mask != 0) { + IdEqListDoSpecial ($ExpOpCount, LineNo, QId, VarIdStr, Mask, ListLen, ValueList); + } else { + UINT16 Index; + CIfrEqIdList EILObj(L->getLine()); + _SAVE_OPHDR_COND (EILObj, ($ExpOpCount == 0)); + EILObj.SetQuestionId (QId, VarIdStr, LineNo); + EILObj.SetListLength (ListLen); + for (Index = 0; Index < ListLen; Index++) { + EILObj.SetValueList (Index, ValueList[Index]); + } + $ExpOpCount++; + } + >> + ; + +vareqvarlExp[UINT32 & RootLevel, UINT32 & ExpOpCount] : + L:VarEqVal Var "\(" V1:Number "\)" "==" V2:Number << + { + CIfrUint64 U64Obj1(L->getLine()), U64Obj2(L->getLine()); + _SAVE_OPHDR_COND (U64Obj1, ($ExpOpCount == 0)); + U64Obj1.SetValue (_STOU64(V1->getText())); + U64Obj2.SetValue (_STOU64(V2->getText())); + } + >> + << {CIfrEqual EObj(L->getLine()); } >> + << $ExpOpCount += 3; >> + ; + +questionref13Exp[UINT32 & RootLevel, UINT32 & ExpOpCount] : + << + UINT8 Type = 0x1; + EFI_STRING_ID DevPath; + EFI_GUID Guid; + EFI_QUESTION_ID QId = EFI_QUESTION_ID_INVALID; + UINT32 BitMask; + INT8 *QName = NULL; + UINT32 LineNo = 0; + >> + L:QuestionRef + ( + ( + << Type = 0x3; >> + { + Path "=" "STRING_TOKEN" "\(" S:Number "\)" << Type = 0x4; DevPath = _STOSID(S->getText()); >> + } + { + GUID "=" + OpenBrace + G1:Number "," G2:Number "," G3:Number "," G4:Number "," G5:Number "," G6:Number "," + G7:Number "," G8:Number "," G9:Number "," G10:Number "," G11:Number + CloseBrace + << + Type = 0x5; + _CRGUID (&Guid, G1->getText (), G2->getText (), G3->getText (), + G4->getText (), G5->getText (), G6->getText (), + G7->getText (), G8->getText (), G9->getText (), + G10->getText (), G11->getText ()); + >> + } + ) + | + ( + "\(" + ( + QN:StringIdentifier << + QName = QN->getText(); + LineNo = QN->getLine(); + mCVfrQuestionDB.GetQuestionId (QN->getText(), NULL, QId, BitMask); + >> + | ID:Number << QId = _STOQID(ID->getText()); >> + ) + "\)" + ) + ) + << + switch (Type) { + case 0x1: {CIfrQuestionRef1 QR1Obj(L->getLine()); _SAVE_OPHDR_COND (QR1Obj, ($ExpOpCount == 0)); QR1Obj.SetQuestionId (QId, QName, LineNo); break;} + case 0x3: {CIfrQuestionRef3 QR3Obj(L->getLine()); _SAVE_OPHDR_COND (QR3Obj, ($ExpOpCount == 0)); break;} + case 0x4: {CIfrQuestionRef3_2 QR3_2Obj(L->getLine()); _SAVE_OPHDR_COND (QR3_2Obj, ($ExpOpCount == 0)); QR3_2Obj.SetDevicePath (DevPath); break;} + case 0x5: {CIfrQuestionRef3_3 QR3_3Obj(L->getLine()); _SAVE_OPHDR_COND (QR3_3Obj, ($ExpOpCount == 0)); QR3_3Obj.SetDevicePath (DevPath); QR3_3Obj.SetGuid (&Guid); break;} + } + $ExpOpCount++; + >> + ; + +rulerefExp[UINT32 & RootLevel, UINT32 & ExpOpCount] : + L:RuleRef + "\(" RN:StringIdentifier "\)" << { CIfrRuleRef RRObj(L->getLine()); _SAVE_OPHDR_COND (RRObj, ($ExpOpCount == 0)); RRObj.SetRuleId (mCVfrRulesDB.GetRuleId (RN->getText())); } $ExpOpCount++; >> + ; + +//****************************************************** +// PARSE: +// stringref (STR_FORM_SET_TITLE) +// +stringref1Exp[UINT32 & RootLevel, UINT32 & ExpOpCount] : + L:StringRef + "\(" S:Number "\)" << { CIfrStringRef1 SR1Obj(L->getLine()); _SAVE_OPHDR_COND (SR1Obj, ($ExpOpCount == 0)); SR1Obj.SetStringId (_STOSID(S->getText())); $ExpOpCount++; } >> + ; + +pushthisExp[UINT32 & RootLevel, UINT32 & ExpOpCount] : + L:PushThis << { CIfrThis TObj(L->getLine()); _SAVE_OPHDR_COND (TObj, ($ExpOpCount == 0)); $ExpOpCount++; } >> + ; + +vfrExpressionConstant[UINT32 & RootLevel, UINT32 & ExpOpCount] : + L1:True << CIfrTrue TObj(L1->getLine()); _SAVE_OPHDR_COND (TObj, ($ExpOpCount == 0)); $ExpOpCount++; >> + | L2:False << CIfrFalse FObj(L2->getLine()); _SAVE_OPHDR_COND (FObj, ($ExpOpCount == 0)); $ExpOpCount++; >> + | L3:One << CIfrOne OObj(L3->getLine()); _SAVE_OPHDR_COND (OObj, ($ExpOpCount == 0)); $ExpOpCount++; >> + | L4:Ones << CIfrOnes OObj(L4->getLine()); _SAVE_OPHDR_COND (OObj, ($ExpOpCount == 0)); $ExpOpCount++; >> + | L5:Zero << CIfrZero ZObj(L5->getLine()); _SAVE_OPHDR_COND (ZObj, ($ExpOpCount == 0)); $ExpOpCount++; >> + | L6:Undefined << CIfrUndefined UObj(L6->getLine()); _SAVE_OPHDR_COND (UObj, ($ExpOpCount == 0)); $ExpOpCount++; >> + | L7:Version << CIfrVersion VObj(L7->getLine()); _SAVE_OPHDR_COND (VObj, ($ExpOpCount == 0)); $ExpOpCount++; >> + | V:Number << CIfrUint64 U64Obj(V->getLine()); U64Obj.SetValue (_STOU64(V->getText())); _SAVE_OPHDR_COND (U64Obj, ($ExpOpCount == 0)); $ExpOpCount++; >> + ; + +vfrExpressionUnaryOp[UINT32 & RootLevel, UINT32 & ExpOpCount] : + lengthExp[$RootLevel, $ExpOpCount] + | bitwisenotExp[$RootLevel, $ExpOpCount] + | question2refExp[$RootLevel, $ExpOpCount] + | stringref2Exp[$RootLevel, $ExpOpCount] + | unintExp[$RootLevel, $ExpOpCount] + | toupperExp[$RootLevel, $ExpOpCount] + | tolwerExp[$RootLevel, $ExpOpCount] + ; + +lengthExp[UINT32 & RootLevel, UINT32 & ExpOpCount] : + L:Length + "\(" vfrStatementExpression[$RootLevel + 1, $ExpOpCount] "\)" + << { CIfrLength LObj(L->getLine()); $ExpOpCount++; } >> + ; + +bitwisenotExp[UINT32 & RootLevel, UINT32 & ExpOpCount] : + L:BitWiseNot + "\(" vfrStatementExpression[$RootLevel + 1, $ExpOpCount] "\)" + << { CIfrBitWiseNot BWNObj(L->getLine()); $ExpOpCount++; } >> + ; + +question2refExp[UINT32 & RootLevel, UINT32 & ExpOpCount] : + L:QuestionRefVal + "\(" vfrStatementExpression[$RootLevel + 1, $ExpOpCount] "\)" + << { CIfrQuestionRef2 QR2Obj(L->getLine()); $ExpOpCount++; } >> + ; + +stringref2Exp[UINT32 & RootLevel, UINT32 & ExpOpCount] : + L:StringRefVal + "\(" vfrStatementExpression[$RootLevel + 1, $ExpOpCount] "\)" + << { CIfrStringRef2 SR2Obj(L->getLine()); $ExpOpCount++; } >> + ; + +toboolExp[UINT32 & RootLevel, UINT32 & ExpOpCount] : + L:BoolVal + "\(" vfrStatementExpression[$RootLevel + 1, $ExpOpCount] "\)" + << { CIfrToBoolean TBObj(L->getLine()); $ExpOpCount++; } >> + ; + +tostringExp[UINT32 & RootLevel, UINT32 & ExpOpCount] : + << UINT8 Fmt = 0; >> + L:StringVal + { + Format "=" F:Number "," << Fmt = _STOU8(F->getText()); >> + } + "\(" vfrStatementExpression[$RootLevel + 1, $ExpOpCount] "\)" + << { CIfrToString TSObj(L->getLine()); TSObj.SetFormat (Fmt); $ExpOpCount++; } >> + ; + +unintExp[UINT32 & RootLevel, UINT32 & ExpOpCount] : + L:UnIntVal + "\(" vfrStatementExpression[$RootLevel + 1, $ExpOpCount] "\)" + << { CIfrToUint TUObj(L->getLine()); $ExpOpCount++; } >> + ; + +toupperExp[UINT32 & RootLevel, UINT32 & ExpOpCount] : + L:ToUpper + "\(" vfrStatementExpression[$RootLevel + 1, $ExpOpCount] "\)" + << { CIfrToUpper TUObj(L->getLine()); $ExpOpCount++; } >> + ; + +tolwerExp[UINT32 & RootLevel, UINT32 & ExpOpCount] : + L:ToLower + "\(" vfrStatementExpression[$RootLevel + 1, $ExpOpCount] "\)" + << { CIfrToLower TLObj(L->getLine()); $ExpOpCount++; } >> + ; + +vfrExpressionTernaryOp[UINT32 & RootLevel, UINT32 & ExpOpCount] : + conditionalExp[$RootLevel, $ExpOpCount] + | findExp[$RootLevel, $ExpOpCount] + | midExp[$RootLevel, $ExpOpCount] + | tokenExp[$RootLevel, $ExpOpCount] + | spanExp[$RootLevel, $ExpOpCount] + ; + +#token Cond("cond") "cond" +#token Find("find") "find" +#token Mid("mid") "mid" +#token Tok("token") "token" +#token Span("span") "span" + +conditionalExp[UINT32 & RootLevel, UINT32 & ExpOpCount] : + L:Cond "\(" + vfrStatementExpression[$RootLevel + 1, $ExpOpCount] + "?" + vfrStatementExpression[$RootLevel + 1, $ExpOpCount] + ":" + vfrStatementExpression[$RootLevel + 1, $ExpOpCount] + "\)" << { CIfrConditional CObj(L->getLine()); $ExpOpCount++; } >> + ; + +findExp[UINT32 & RootLevel, UINT32 & ExpOpCount] : + << UINT8 Format; >> + L:Find "\(" + findFormat[Format] ( "\|" findFormat[Format] )* + "," + vfrStatementExpression[$RootLevel + 1, $ExpOpCount] + "," + vfrStatementExpression[$RootLevel + 1, $ExpOpCount] + "," + vfrStatementExpression[$RootLevel + 1, $ExpOpCount] + "\)" << { CIfrFind FObj(L->getLine()); FObj.SetFormat (Format); $ExpOpCount++; } >> + ; + +findFormat [UINT8 & Format] : + "SENSITIVE" << $Format = 0x00; >> + | "INSENSITIVE" << $Format = 0x01; >> + ; + +midExp[UINT32 & RootLevel, UINT32 & ExpOpCount] : + L:Mid "\(" + vfrStatementExpression[$RootLevel + 1, $ExpOpCount] + "," + vfrStatementExpression[$RootLevel + 1, $ExpOpCount] + "," + vfrStatementExpression[$RootLevel + 1, $ExpOpCount] + "\)" << { CIfrMid MObj(L->getLine()); $ExpOpCount++; } >> + ; + +tokenExp[UINT32 & RootLevel, UINT32 & ExpOpCount] : + L:Tok "\(" + vfrStatementExpression[$RootLevel + 1, $ExpOpCount] + "," + vfrStatementExpression[$RootLevel + 1, $ExpOpCount] + "," + vfrStatementExpression[$RootLevel + 1, $ExpOpCount] + "\)" << { CIfrToken TObj(L->getLine()); $ExpOpCount++; } >> + ; + +spanExp[UINT32 & RootLevel, UINT32 & ExpOpCount] : + << UINT8 Flags = 0; >> + S:Span "\(" + FLAGS "=" spanFlags[Flags] ( "\|" spanFlags[Flags] )* + "," + vfrStatementExpression[$RootLevel + 1, $ExpOpCount] + "," + vfrStatementExpression[$RootLevel + 1, $ExpOpCount] + "," + vfrStatementExpression[$RootLevel + 1, $ExpOpCount] + "\)" << { CIfrSpan SObj(S->getLine()); SObj.SetFlags(Flags); $ExpOpCount++; } >> + ; + +spanFlags [UINT8 & Flags] : + N:Number << $Flags |= _STOU8(N->getText()); >> + | "LAST_NON_MATCH" << $Flags |= 0x00; >> + | "FIRST_NON_MATCH" << $Flags |= 0x01; >> + ; + +#token StringIdentifier("string identifier") "[A-Za-z_][A-Za-z_0-9]*" +#token Number("numeric value") "(0x[0-9A-Fa-f]+) | [0-9]+" + +//****************************************************************************** +// +// Parser class definition. +// +class EfiVfrParser { +<< +private: + UINT8 mParserStatus; + + CVfrDefaultStore mCVfrDefaultStore; + CVfrVarDataTypeDB mCVfrVarDataTypeDB; + CVfrDataStorage mCVfrDataStorage; + CVfrQuestionDB mCVfrQuestionDB; + CVfrRulesDB mCVfrRulesDB; + + CIfrOpHeader *mCIfrOpHdr; + VOID _SAVE_OPHDR_COND (IN CIfrOpHeader &, IN BOOLEAN); + VOID _CLEAR_SAVED_OPHDR (VOID); + VOID _SET_SAVED_OPHDR_SCOPE (VOID); + + + EFI_VARSTORE_INFO mCurrQestVarInfo; + + VOID _CRT_OP (IN BOOLEAN); + + VOID _SAVE_CURRQEST_VARINFO (IN EFI_VARSTORE_INFO &); + EFI_VARSTORE_INFO & _GET_CURRQEST_VARTINFO (VOID); + + UINT8 _GET_CURRQEST_DATATYPE (); + UINT32 _GET_CURRQEST_VARSIZE (); + +public: + VOID _PCATCH (IN EFI_VFR_RETURN_CODE, IN EFI_VFR_RETURN_CODE, IN ANTLRTokenPtr, IN INT8 *); + VOID _PCATCH (IN EFI_VFR_RETURN_CODE); + VOID _PCATCH (IN EFI_VFR_RETURN_CODE, IN ANTLRTokenPtr); + VOID _PCATCH (IN EFI_VFR_RETURN_CODE, IN UINT32); + + VOID syn (ANTLRAbstractToken *, ANTLRChar *, SetWordType *, ANTLRTokenType, INT32); + + INT8 * TrimHex (IN INT8 *, OUT BOOLEAN *); + UINT8 _STOU8 (IN INT8 *); + UINT16 _STOU16 (IN INT8 *); + UINT32 _STOU32 (IN INT8 *); + UINT64 _STOU64 (IN INT8 *); + EFI_HII_DATE _STOD (IN INT8 *, IN INT8 *, IN INT8 *); + EFI_HII_TIME _STOT (IN INT8 *, IN INT8 *, IN INT8 *); + + EFI_STRING_ID _STOSID (IN INT8 *); + EFI_FORM_ID _STOFID (IN INT8 *); + EFI_QUESTION_ID _STOQID (IN INT8 *); + + VOID _STRCAT (IN OUT INT8 **, IN INT8 *); + + VOID _CRGUID (EFI_GUID *, INT8 *, INT8 *, INT8 *, INT8 *, INT8 *, INT8 *, INT8 *, INT8 *, INT8 *, INT8 *, INT8 *); + VOID _DeclareDefaultLinearVarStore (IN UINT32); + VOID _DeclareStandardDefaultStorage (IN UINT32); + + + VOID AssignQuestionKey (IN CIfrQuestionHeader &, IN ANTLRTokenPtr); + + VOID ConvertIdExpr (IN UINT32 &, IN UINT32, IN EFI_QUESTION_ID, IN INT8 *, IN UINT32); + VOID IdEqValDoSpecial (IN UINT32 &, IN UINT32, IN EFI_QUESTION_ID, IN INT8 *, IN UINT32, IN UINT16, IN EFI_COMPARE_TYPE); + 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); + VOID IdEqListDoSpecial (IN UINT32 &, IN UINT32, IN EFI_QUESTION_ID, IN INT8 *, IN UINT32, IN UINT16, IN UINT16 *); +>> +} + +<< +VOID +EfiVfrParser::_SAVE_OPHDR_COND ( + IN CIfrOpHeader &OpHdr, + IN BOOLEAN Cond + ) +{ + if (Cond == TRUE) { +#ifdef VFREXP_DEBUG + printf ("######_SAVE_OPHDR_COND\n"); +#endif + if (mCIfrOpHdr != NULL) { +#ifdef VFREXP_DEBUG + printf ("######_SAVE_OPHDR_COND Error\n"); +#endif + return ; + } + mCIfrOpHdr = new CIfrOpHeader(OpHdr); + } +} + +VOID +EfiVfrParser::_CLEAR_SAVED_OPHDR ( + VOID + ) +{ +#ifdef VFREXP_DEBUG + printf ("######_CLEAR_SAVED_OPHDR\n"); +#endif + mCIfrOpHdr = NULL; +} + +VOID +EfiVfrParser::_SET_SAVED_OPHDR_SCOPE ( + VOID + ) +{ +#ifdef VFREXP_DEBUG + printf ("#######_SET_SAVED_OPHDR_SCOPE\n"); +#endif + mCIfrOpHdr->SetScope (1); +} + +VOID +EfiVfrParser::_CRT_OP ( + IN BOOLEAN Crt + ) +{ + gCreateOp = Crt; +} + +VOID +EfiVfrParser::_SAVE_CURRQEST_VARINFO ( + IN EFI_VARSTORE_INFO &Info + ) +{ + mCurrQestVarInfo = Info; +} + +EFI_VARSTORE_INFO & +EfiVfrParser::_GET_CURRQEST_VARTINFO ( + VOID + ) +{ + return mCurrQestVarInfo; +} + +UINT8 +EfiVfrParser::_GET_CURRQEST_DATATYPE ( + VOID + ) +{ + return mCurrQestVarInfo.mVarType; +} + +UINT32 +EfiVfrParser::_GET_CURRQEST_VARSIZE ( + VOID + ) +{ + return mCurrQestVarInfo.mVarTotalSize; +} + +VOID +EfiVfrParser::_PCATCH ( + IN EFI_VFR_RETURN_CODE ReturnCode, + IN EFI_VFR_RETURN_CODE ExpectCode, + IN ANTLRTokenPtr Tok, + IN INT8 *ErrorMsg + ) +{ + if (ReturnCode != ExpectCode) { + mParserStatus++; + gCVfrErrorHandle.PrintError (Tok->getLine(), Tok->getText(), ErrorMsg); + } +} + +VOID +EfiVfrParser::_PCATCH ( + IN EFI_VFR_RETURN_CODE ReturnCode + ) +{ + mParserStatus += gCVfrErrorHandle.HandleError (ReturnCode); +} + +VOID +EfiVfrParser::_PCATCH ( + IN EFI_VFR_RETURN_CODE ReturnCode, + IN ANTLRTokenPtr Tok + ) +{ + mParserStatus += gCVfrErrorHandle.HandleError (ReturnCode, Tok->getLine(), Tok->getText()); +} + +VOID +EfiVfrParser::_PCATCH ( + IN EFI_VFR_RETURN_CODE ReturnCode, + IN UINT32 LineNum + ) +{ + mParserStatus += gCVfrErrorHandle.HandleError (ReturnCode, LineNum); +} + +VOID +EfiVfrParser::syn ( + ANTLRAbstractToken *Tok, + ANTLRChar *Egroup, + SetWordType *Eset, + ANTLRTokenType ETok, + INT32 Huh + ) +{ + gCVfrErrorHandle.HandleError (VFR_RETURN_MISMATCHED, Tok->getLine(), Tok->getText()); + + mParserStatus += 1; +} + +INT8 * +EfiVfrParser::TrimHex ( + IN INT8 *Str, + OUT BOOLEAN *IsHex + ) +{ + *IsHex = FALSE; + + while (*Str && *Str == ' ') { + Str++; + } + while (*Str && *Str == '0') { + Str++; + } + if (*Str && (*Str == 'x' || *Str == 'X')) { + Str++; + *IsHex = TRUE; + } + + return Str; +} + +UINT8 +EfiVfrParser::_STOU8 ( + IN INT8 *Str + ) +{ + BOOLEAN IsHex; + UINT8 Value; + INT8 c; + + Str = TrimHex (Str, &IsHex); + for (Value = 0; (c = *Str) != '\0'; Str++) { + // + // BUG: does not handle overflow here + // + (IsHex == TRUE) ? (Value <<= 4) : (Value *= 10); + + if ((IsHex == TRUE) && (c >= 'a') && (c <= 'f')) { + Value += (c - 'a' + 10); + } + if ((IsHex == TRUE) && (c >= 'A') && (c <= 'F')) { + Value += (c - 'A' + 10); + } + if (c >= '0' && c <= '9') { + Value += (c - '0'); + } + } + + return Value; +} + +UINT16 +EfiVfrParser::_STOU16 ( + IN INT8 *Str + ) +{ + BOOLEAN IsHex; + UINT16 Value; + INT8 c; + + Str = TrimHex (Str, &IsHex); + for (Value = 0; (c = *Str) != '\0'; Str++) { + // + // BUG: does not handle overflow here + // + (IsHex == TRUE) ? (Value <<= 4) : (Value *= 10); + + if ((IsHex == TRUE) && (c >= 'a') && (c <= 'f')) { + Value += (c - 'a' + 10); + } + if ((IsHex == TRUE) && (c >= 'A') && (c <= 'F')) { + Value += (c - 'A' + 10); + } + if (c >= '0' && c <= '9') { + Value += (c - '0'); + } + } + + return Value; +} + +UINT32 +EfiVfrParser::_STOU32 ( + IN INT8 *Str + ) +{ + BOOLEAN IsHex; + UINT32 Value; + INT8 c; + + Str = TrimHex (Str, &IsHex); + for (Value = 0; (c = *Str) != '\0'; Str++) { + // + // BUG: does not handle overflow here + // + (IsHex == TRUE) ? (Value <<= 4) : (Value *= 10); + + if ((IsHex == TRUE) && (c >= 'a') && (c <= 'f')) { + Value += (c - 'a' + 10); + } + if ((IsHex == TRUE) && (c >= 'A') && (c <= 'F')) { + Value += (c - 'A' + 10); + } + if (c >= '0' && c <= '9') { + Value += (c - '0'); + } + } + + return Value; +} + +UINT64 +EfiVfrParser::_STOU64 ( + IN INT8 *Str + ) +{ + BOOLEAN IsHex; + UINT64 Value; + INT8 c; + + Str = TrimHex (Str, &IsHex); + for (Value = 0; (c = *Str) != '\0'; Str++) { + // + // BUG: does not handle overflow here + // + (IsHex == TRUE) ? (Value <<= 4) : (Value *= 10); + + if ((IsHex == TRUE) && (c >= 'a') && (c <= 'f')) { + Value += (c - 'a' + 10); + } + if ((IsHex == TRUE) && (c >= 'A') && (c <= 'F')) { + Value += (c - 'A' + 10); + } + if (c >= '0' && c <= '9') { + Value += (c - '0'); + } + } + + return Value; +} + +EFI_HII_DATE +EfiVfrParser::_STOD ( + IN INT8 *Year, + IN INT8 *Month, + IN INT8 *Day + ) +{ + EFI_HII_DATE Date; + + Date.Year = _STOU16 (Year); + Date.Month = _STOU8 (Month); + Date.Day = _STOU8 (Day); + + return Date; +} + +EFI_HII_TIME +EfiVfrParser::_STOT ( + IN INT8 *Hour, + IN INT8 *Minute, + IN INT8 *Second + ) +{ + EFI_HII_TIME Time; + + Time.Hour = _STOU8 (Hour); + Time.Minute = _STOU8 (Minute); + Time.Second = _STOU8 (Second); + + return Time; +} + +EFI_STRING_ID +EfiVfrParser::_STOSID ( + IN INT8 *Str + ) +{ + return (EFI_STRING_ID)_STOU16(Str); +} + +EFI_FORM_ID +EfiVfrParser::_STOFID ( + IN INT8 *Str + ) +{ + return (EFI_FORM_ID)_STOU16(Str); +} + +EFI_QUESTION_ID +EfiVfrParser::_STOQID ( + IN INT8 *Str + ) +{ + return (EFI_QUESTION_ID)_STOU16(Str); +} + +VOID +EfiVfrParser::_STRCAT ( + IN OUT INT8 **Dest, + IN INT8 *Src + ) +{ + INT8 *NewStr; + UINT32 Len; + + if ((Dest == NULL) || (Src == NULL)) { + return; + } + + Len = (*Dest == NULL) ? 0 : strlen (*Dest); + Len += strlen (Src); + if ((NewStr = new INT8[Len + 1]) == NULL) { + return; + } + NewStr[0] = '\0'; + if (*Dest != NULL) { + strcpy (NewStr, *Dest); + } + strcat (NewStr, Src); + + *Dest = NewStr; +} + +VOID +EfiVfrParser::_CRGUID ( + IN EFI_GUID *Guid, + IN INT8 *G1, + IN INT8 *G2, + IN INT8 *G3, + IN INT8 *G4, + IN INT8 *G5, + IN INT8 *G6, + IN INT8 *G7, + IN INT8 *G8, + IN INT8 *G9, + IN INT8 *G10, + IN INT8 *G11 + ) +{ + Guid->Data1 = _STOU32 (G1); + Guid->Data2 = _STOU16 (G2); + Guid->Data3 = _STOU16 (G3); + Guid->Data4[0] = _STOU8(G4); + Guid->Data4[1] = _STOU8(G5); + Guid->Data4[2] = _STOU8(G6); + Guid->Data4[3] = _STOU8(G7); + Guid->Data4[4] = _STOU8(G8); + Guid->Data4[5] = _STOU8(G9); + Guid->Data4[6] = _STOU8(G10); + Guid->Data4[7] = _STOU8(G11); +} + +VOID +EfiVfrParser::_DeclareDefaultLinearVarStore ( + IN UINT32 LineNo + ) +{ + UINT32 Index; + INT8 **TypeNameList; + UINT32 ListSize; + EFI_GUID DefaultGuid = { 0x9db3c415, 0xda00, 0x4233, { 0xae, 0xc6, 0x79, 0xb, 0x4f, 0x5b, 0x45, 0x66 } }; + + mCVfrVarDataTypeDB.GetUserDefinedTypeNameList (&TypeNameList, &ListSize); + + for (Index = 0; Index < ListSize; Index++) { + UINT32 Size; + EFI_VARSTORE_ID VarStoreId; + CIfrVarStore VSObj; + + VSObj.SetLineNo (LineNo); + mCVfrDataStorage.DeclareBufferVarStore ( + TypeNameList[Index], + &DefaultGuid, + &mCVfrVarDataTypeDB, + TypeNameList[Index], + EFI_VARSTORE_ID_INVALID + ); + mCVfrDataStorage.GetVarStoreId(TypeNameList[Index], &VarStoreId); + VSObj.SetVarStoreId (VarStoreId); + mCVfrVarDataTypeDB.GetDataTypeSize(TypeNameList[Index], &Size); + VSObj.SetSize (Size); + VSObj.SetName (TypeNameList[Index]); + VSObj.SetGuid (&DefaultGuid); + } + + if (mCVfrVarDataTypeDB.IsTypeNameDefined ("Date") == FALSE) { + UINT32 Size; + EFI_VARSTORE_ID VarStoreId; + CIfrVarStore VSObj; + + VSObj.SetLineNo (LineNo); + mCVfrDataStorage.DeclareBufferVarStore ( + "Date", + &DefaultGuid, + &mCVfrVarDataTypeDB, + "EFI_HII_DATE", + EFI_VARSTORE_ID_INVALID + ); + mCVfrDataStorage.GetVarStoreId("Date", &VarStoreId); + VSObj.SetVarStoreId (VarStoreId); + mCVfrVarDataTypeDB.GetDataTypeSize("EFI_HII_DATE", &Size); + VSObj.SetSize (Size); + VSObj.SetName ("Date"); + VSObj.SetGuid (&DefaultGuid); + } + + if (mCVfrVarDataTypeDB.IsTypeNameDefined ("Time") == FALSE) { + UINT32 Size; + EFI_VARSTORE_ID VarStoreId; + CIfrVarStore VSObj; + + VSObj.SetLineNo (LineNo); + mCVfrDataStorage.DeclareBufferVarStore ( + "Time", + &DefaultGuid, + &mCVfrVarDataTypeDB, + "EFI_HII_TIME", + EFI_VARSTORE_ID_INVALID + ); + mCVfrDataStorage.GetVarStoreId("Time", &VarStoreId); + VSObj.SetVarStoreId (VarStoreId); + mCVfrVarDataTypeDB.GetDataTypeSize("EFI_HII_TIME", &Size); + VSObj.SetSize (Size); + VSObj.SetName ("Time"); + VSObj.SetGuid (&DefaultGuid); + } +} + +VOID +EfiVfrParser::_DeclareStandardDefaultStorage ( + IN UINT32 LineNo + ) +{ + CIfrDefaultStore DSObj; + + mCVfrDefaultStore.RegisterDefaultStore (DSObj.GetObjBinAddr(), "Standard Defaults", EFI_STRING_ID_INVALID, EFI_HII_DEFAULT_CLASS_STANDARD); + DSObj.SetLineNo (LineNo); + DSObj.SetDefaultName (EFI_STRING_ID_INVALID); + DSObj.SetDefaultId (EFI_HII_DEFAULT_CLASS_STANDARD); +} + +VOID +EfiVfrParser::AssignQuestionKey ( + IN CIfrQuestionHeader &QHObj, + IN ANTLRTokenPtr KeyTok + ) +{ + UINT16 KeyValue; + + if (KeyTok == NULL) { + return; + } + + KeyValue = _STOU16 (KeyTok->getText()); + + if (QHObj.FLAGS () & EFI_IFR_FLAG_CALLBACK) { + /* + * if the question is not CALLBACK ignore the key. + */ + _PCATCH(mCVfrQuestionDB.UpdateQuestionId (QHObj.QUESTION_ID(), KeyValue), KeyTok); + QHObj.SetQuestionId (KeyValue); + } +} + +VOID +EfiVfrParser::ConvertIdExpr ( + IN UINT32 &ExpOpCount, + IN UINT32 LineNo, + IN EFI_QUESTION_ID QId, + IN INT8 *VarIdStr, + IN UINT32 BitMask + ) +{ + CIfrQuestionRef1 QR1Obj(LineNo); + QR1Obj.SetQuestionId (QId, VarIdStr, LineNo); + _SAVE_OPHDR_COND (QR1Obj, (ExpOpCount == 0)); + + if (BitMask != 0) { + CIfrUint32 U32Obj(LineNo); + U32Obj.SetValue (BitMask); + + CIfrBitWiseAnd BWAObj(LineNo); + + CIfrUint8 U8Obj(LineNo); + switch (BitMask) { + case DATE_YEAR_BITMASK : U8Obj.SetValue (0); break; + case TIME_SECOND_BITMASK : U8Obj.SetValue (0x10); break; + case DATE_DAY_BITMASK : U8Obj.SetValue (0x18); break; + case TIME_HOUR_BITMASK : U8Obj.SetValue (0); break; + case TIME_MINUTE_BITMASK : U8Obj.SetValue (0x8); break; + } + + CIfrShiftRight SRObj(LineNo); + } + + ExpOpCount += 4; +} + +VOID +EfiVfrParser::IdEqValDoSpecial ( + IN UINT32 &ExpOpCount, + IN UINT32 LineNo, + IN EFI_QUESTION_ID QId, + IN INT8 *VarIdStr, + IN UINT32 BitMask, + IN UINT16 ConstVal, + IN EFI_COMPARE_TYPE CompareType + ) +{ + ConvertIdExpr (ExpOpCount, LineNo, QId, VarIdStr, BitMask); + + if (ConstVal > 0xFF) { + CIfrUint16 U16Obj(LineNo); + U16Obj.SetValue (ConstVal); + } else { + CIfrUint8 U8Obj(LineNo); + U8Obj.SetValue ((UINT8)ConstVal); + } + + switch (CompareType) { + case EQUAL : + { + CIfrEqual EObj(LineNo); + break; + } + case LESS_EQUAL : + { + CIfrLessEqual LEObj(LineNo); + break; + } + case LESS_THAN : + { + CIfrLessThan LTObj(LineNo); + break; + } + case GREATER_EQUAL : + { + CIfrGreaterEqual GEObj(LineNo); + break; + } + case GREATER_THAN : + { + CIfrGreaterThan GTObj(LineNo); + break; + } + } + + ExpOpCount += 2; +} + +VOID +EfiVfrParser::IdEqIdDoSpecial ( + IN UINT32 &ExpOpCount, + IN UINT32 LineNo, + IN EFI_QUESTION_ID QId1, + IN INT8 *VarId1Str, + IN UINT32 BitMask1, + IN EFI_QUESTION_ID QId2, + IN INT8 *VarId2Str, + IN UINT32 BitMask2, + IN EFI_COMPARE_TYPE CompareType + ) +{ + ConvertIdExpr (ExpOpCount, LineNo, QId1, VarId1Str, BitMask1); + ConvertIdExpr (ExpOpCount, LineNo, QId2, VarId2Str, BitMask2); + + switch (CompareType) { + case EQUAL : + { + CIfrEqual EObj(LineNo); + break; + } + case LESS_EQUAL : + { + CIfrLessEqual LEObj(LineNo); + break; + } + case LESS_THAN : + { + CIfrLessThan LTObj(LineNo); + break; + } + case GREATER_EQUAL : + { + CIfrGreaterEqual GEObj(LineNo); + break; + } + case GREATER_THAN : + { + CIfrGreaterThan GTObj(LineNo); + break; + } + } + + ExpOpCount++; +} + +VOID +EfiVfrParser::IdEqListDoSpecial ( + IN UINT32 &ExpOpCount, + IN UINT32 LineNo, + IN EFI_QUESTION_ID QId, + IN INT8 *VarIdStr, + IN UINT32 BitMask, + IN UINT16 ListLen, + IN UINT16 *ValueList + ) +{ + UINT16 Index; + + if (ListLen == 0) { + return; + } + + IdEqValDoSpecial (ExpOpCount, LineNo, QId, VarIdStr, BitMask, ValueList[0], EQUAL); + for (Index = 1; Index < ListLen; Index++) { + IdEqValDoSpecial (ExpOpCount, LineNo, QId, VarIdStr, BitMask, ValueList[Index], EQUAL); + CIfrOr OObj (LineNo); + ExpOpCount++; + } +} + +>> diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrUtilityLib.cpp b/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrUtilityLib.cpp new file mode 100644 index 0000000000..8ff77e783b --- /dev/null +++ b/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrUtilityLib.cpp @@ -0,0 +1,2695 @@ +#include "stdio.h" +#include "stdlib.h" +#include "VfrUtilityLib.h" +#include "VfrFormPkg.h" + +VOID +CVfrBinaryOutput::WriteLine ( + IN FILE *pFile, + IN UINT32 LineBytes, + IN INT8 *LineHeader, + IN INT8 *BlkBuf, + IN UINT32 BlkSize + ) +{ + UINT32 Index; + + if ((pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) { + return; + } + + for (Index = 0; Index < BlkSize; Index++) { + if ((Index % LineBytes) == 0) { + fprintf (pFile, "\n%s", LineHeader); + } + fprintf (pFile, "0x%02X, ", (UINT8)BlkBuf[Index]); + } +} + +VOID +CVfrBinaryOutput::WriteEnd ( + IN FILE *pFile, + IN UINT32 LineBytes, + IN INT8 *LineHeader, + IN INT8 *BlkBuf, + IN UINT32 BlkSize + ) +{ + UINT32 Index; + + if ((BlkSize == 0) || (pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) { + return; + } + + for (Index = 0; Index < BlkSize - 1; Index++) { + if ((Index % LineBytes) == 0) { + fprintf (pFile, "\n%s", LineHeader); + } + fprintf (pFile, "0x%02X, ", (UINT8)BlkBuf[Index]); + } + + if ((Index % LineBytes) == 0) { + fprintf (pFile, "\n%s", LineHeader); + } + fprintf (pFile, "0x%02X\n", (UINT8)BlkBuf[Index]); +} + +SConfigInfo::SConfigInfo ( + IN UINT8 Type, + IN UINT16 Offset, + IN UINT32 Width, + IN EFI_IFR_TYPE_VALUE Value + ) +{ + mOffset = Offset; + mWidth = (UINT16)Width; + mValue = new UINT8[mWidth]; + if (mValue == NULL) { + return; + } + + switch (Type) { + case EFI_IFR_TYPE_NUM_SIZE_8 : + memcpy (mValue, &Value.u8, mWidth); + break; + case EFI_IFR_TYPE_NUM_SIZE_16 : + memcpy (mValue, &Value.u16, mWidth); + break; + case EFI_IFR_TYPE_NUM_SIZE_32 : + memcpy (mValue, &Value.u32, mWidth); + break; + case EFI_IFR_TYPE_NUM_SIZE_64 : + memcpy (mValue, &Value.u64, mWidth); + break; + case EFI_IFR_TYPE_BOOLEAN : + memcpy (mValue, &Value.b, mWidth); + break; + case EFI_IFR_TYPE_TIME : + memcpy (mValue, &Value.time, mWidth); + break; + case EFI_IFR_TYPE_DATE : + memcpy (mValue, &Value.date, mWidth); + break; + case EFI_IFR_TYPE_STRING : + memcpy (mValue, &Value.string, mWidth); + break; + case EFI_IFR_TYPE_OTHER : + return; + } +} + +SConfigInfo::~SConfigInfo ( + VOID + ) +{ + BUFFER_SAFE_FREE (mValue); +} + +SConfigItem::SConfigItem ( + IN INT8 *Id, + IN INT8 *Info + ) +{ + mId = NULL; + mInfo = NULL; + mInfoStrList = NULL; + mNext = NULL; + + if (Id != NULL) { + if ((mId = new INT8[strlen (Id) + 1]) != NULL) { + strcpy (mId, Id); + } + } + + if (Info != NULL) { + if ((mInfo = new INT8[strlen (Info) + 1]) != NULL) { + strcpy (mInfo, Info); + } + } +} + +SConfigItem::SConfigItem ( + IN INT8 *Id, + IN INT8 *Info, + IN UINT8 Type, + IN UINT16 Offset, + IN UINT16 Width, + IN EFI_IFR_TYPE_VALUE Value + ) +{ + mId = NULL; + mInfo = NULL; + mInfoStrList = NULL; + mNext = NULL; + + if (Id != NULL) { + if ((mId = new INT8[strlen (Id) + 1]) != NULL) { + strcpy (mId, Id); + } + } + + if (Info != NULL) { + if ((mInfo = new INT8[strlen (Info) + 1]) != NULL) { + strcpy (mInfo, Info); + } + } + + mInfoStrList = new SConfigInfo(Type, Offset, Width, Value); +} + +SConfigItem::~SConfigItem ( + VOID + ) +{ + SConfigInfo *Info; + + BUFFER_SAFE_FREE (mId); + BUFFER_SAFE_FREE (mInfo); + while (mInfoStrList != NULL) { + Info = mInfoStrList; + mInfoStrList = mInfoStrList->mNext; + + BUFFER_SAFE_FREE (Info); + } +} + +UINT8 +CVfrBufferConfig::Register ( + IN INT8 *Id, + IN INT8 *Info + ) +{ + SConfigItem *pNew; + + if (Select (Id) == 0) { + return 1; + } + + if ((pNew = new SConfigItem (Id, Info)) == NULL) { + return 2; + } + if (mItemListHead == NULL) { + mItemListHead = pNew; + mItemListTail = pNew; + } else { + mItemListTail->mNext = pNew; + mItemListTail = pNew; + } + mItemListPos = pNew; + + return 0; +} + +VOID +CVfrBufferConfig::Open ( + VOID + ) +{ + mItemListPos = mItemListHead; +} + +BOOLEAN +CVfrBufferConfig::Eof( + VOID + ) +{ + return (mItemListPos == NULL) ? TRUE : FALSE; +} + +UINT8 +CVfrBufferConfig::Select ( + IN INT8 *Id, + IN INT8 *Info + ) +{ + SConfigItem *p; + + if (Id == NULL) { + mItemListPos = mItemListHead; + return 0; + } else { + for (p = mItemListHead; p != NULL; p = p->mNext) { + if (strcmp (p->mId, Id) != 0) { + continue; + } + + if ((p->mInfo != NULL) && (Info != NULL)) { + if (strcmp (p->mInfo, Info) != 0) { + continue; + } + } + + mItemListPos = p; + return 0; + } + } + + return 1; +} + +UINT8 +CVfrBufferConfig::Write ( + IN CONST CHAR8 Mode, + IN INT8 *Id, + IN INT8 *Info, + IN UINT8 Type, + IN UINT16 Offset, + IN UINT32 Width, + IN EFI_IFR_TYPE_VALUE Value + ) +{ + UINT8 Ret; + SConfigItem *pItem; + SConfigInfo *pInfo; + + switch (Mode) { + case 'a' : // add + if (Select (Id) == 0) { + if((pInfo = new SConfigInfo (Type, Offset, Width, Value)) == NULL) { + return 2; + } + pInfo->mNext = mItemListPos->mInfoStrList; + mItemListPos->mInfoStrList = pInfo; + } else { + if ((pItem = new SConfigItem (Id, Info, Type, Offset, Width, Value)) == NULL) { + return 2; + } + if (mItemListHead == NULL) { + mItemListHead = pItem; + mItemListTail = pItem; + } else { + mItemListTail->mNext = pItem; + mItemListTail = pItem; + } + mItemListPos = pItem; + } + break; + + case 'd' : // delete + if ((Ret = Select (Id)) != 0) { + return Ret; + } + + if (mItemListHead == mItemListPos) { + mItemListHead = mItemListPos->mNext; + delete mItemListPos; + break; + } + + for (pItem = mItemListHead; pItem->mNext != mItemListPos; pItem = pItem->mNext) + ; + + pItem->mNext = mItemListPos->mNext; + if (mItemListTail == mItemListPos) { + mItemListTail = pItem; + } + delete mItemListPos; + mItemListPos = pItem->mNext; + break; + + case 'i' : // set info + if ((Ret = Select (Id)) != 0) { + return Ret; + } + if (mItemListPos->mInfo != NULL) { + delete mItemListPos->mInfo; + } + mItemListPos->mInfo = NULL; + if (Info != NULL) { + if ((mItemListPos->mInfo = new INT8[strlen (Info) + 1]) == NULL) { + return 2; + } + strcpy (mItemListPos->mInfo, Info); + } + break; + + default : + return 1; + } + + return 0; +} + +#if 0 +UINT8 +CVfrBufferConfig::ReadId ( + OUT INT8 **Id, + OUT INT8 **Info + ) +{ + if (mInfoStrItemListPos == NULL) { + return 1; // end read or some error occur + } + + if (Id != NULL) { + *Id = new INT8 (strlen (mInfoStrItemListPos->mId + 1)); + strcpy (*Id, mInfoStrItemListPos->mId); + } + if (Info != NULL) { + *Info = new INT8 (strlen (mInfoStrItemListPos->mInfo + 1)); + strcpy (*Info, mInfoStrItemListPos->mInfo); + } + + return 0; +} + +UINT8 +CVfrBufferConfig::ReadInfo ( + IN INT8 *Id, + IN UINT32 Index, + IN OUT UINT32 &Number, + OUT INT8 *Offset, + OUT INT8 *Width, + OUT INT8 *Value + ) +{ + UINT8 ret; + SConfigInfo *p; + UINT32 idx; + UINT32 num; + + if (Id != NULL) { + if ((ret = Select (Id)) != 0) { + return ret; + } + } + + if (mInfoStrItemListPos == NULL) { + return 1; // end read or some error occur + } + + p = mInfoStrItemListPos->mInfoStrList; + for (idx = 0; (idx < Index) && (p != NULL); idx++) { + p = p->mNext; + } + if (p == NULL) { + return 1; + } + + if (Offset != NULL) { + Offset[0] = '\0'; + } + if (Width != NULL) { + Width[0] = '\0'; + } + if (Value != NULL) { + Value[0] = '\0'; + } + + while (num < Number) { + if (Offset != NULL) { + strcat (Offset, p->mOffset); + } + if (Width != NULL) { + strcat (Width, p->mWidth); + } + if (Value != NULL) { + strcat (Value, p->mValue); + } + + num++; + if ((p = p->mNext) == NULL) { + break; + } + } + Number = num; + + return 0; +} + +VOID +CVfrBufferConfig::ReadNext ( + VOID + ) +{ + if (mItemListPos != NULL) { + mItemListPos = mItemListPos->mNext; + } +} +#endif + +VOID +CVfrBufferConfig::Close ( + VOID + ) +{ + mItemListPos = NULL; +} + +#define BYTES_PRE_LINE 0x10 + +VOID +CVfrBufferConfig::OutputCFile ( + IN FILE *pFile, + IN INT8 *BaseName + ) +{ + CVfrBinaryOutput Output; + SConfigItem *Item; + SConfigInfo *Info; + UINT32 TotalLen; + + if (pFile == NULL) { + return; + } + + for (Item = mItemListHead; Item != NULL; Item = Item->mNext) { + if (Item->mInfoStrList != NULL) { + fprintf (pFile, "\nunsigned char %s%sDefault%04x[] = {", BaseName, Item->mId, Item->mInfo); + + TotalLen = sizeof (UINT32); + for (Info = Item->mInfoStrList; Info != NULL; Info = Info->mNext) { + TotalLen += Info->mWidth + sizeof (UINT16) * 2; + } + Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (INT8 *)&TotalLen, sizeof (UINT32)); + + for (Info = Item->mInfoStrList; Info != NULL; Info = Info->mNext) { + Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (INT8 *)&Info->mOffset, sizeof (UINT16)); + Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (INT8 *)&Info->mWidth, sizeof (UINT16)); + if (Info->mNext == NULL) { + Output.WriteEnd (pFile, BYTES_PRE_LINE, " ", (INT8 *)Info->mValue, Info->mWidth); + } else { + Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (INT8 *)Info->mValue, Info->mWidth); + } + fprintf (pFile, "\n"); + } + fprintf (pFile, "};\n"); + } + } +} + +CVfrBufferConfig::CVfrBufferConfig ( + VOID + ) +{ + mItemListHead = NULL; + mItemListTail = NULL; + mItemListPos = NULL; +} + +CVfrBufferConfig::~CVfrBufferConfig ( + VOID + ) +{ + SConfigItem *p; + + while (mItemListHead != NULL) { + p = mItemListHead; + mItemListHead = mItemListHead->mNext; + delete p; + } + + mItemListHead = NULL; + mItemListTail = NULL; + mItemListPos = NULL; +} + +CVfrBufferConfig gCVfrBufferConfig; + +static struct { + INT8 *mTypeName; + UINT8 mType; + UINT32 mSize; + UINT32 mAlign; +} gInternalTypesTable [] = { + {"UINT64", EFI_IFR_TYPE_NUM_SIZE_64, sizeof (UINT64), sizeof (UINT64)}, + {"UINT32", EFI_IFR_TYPE_NUM_SIZE_32, sizeof (UINT32), sizeof (UINT32)}, + {"UINT16", EFI_IFR_TYPE_NUM_SIZE_16, sizeof (UINT16), sizeof (UINT16)}, + {"UINT8", EFI_IFR_TYPE_NUM_SIZE_8, sizeof (UINT8), sizeof (UINT8)}, + {"BOOLEAN", EFI_IFR_TYPE_BOOLEAN, sizeof (BOOLEAN), sizeof (BOOLEAN)}, + {"EFI_HII_DATE", EFI_IFR_TYPE_DATE, sizeof (EFI_HII_DATE), sizeof (UINT8)}, + {"EFI_STRING_ID", EFI_IFR_TYPE_STRING, sizeof (EFI_STRING_ID),sizeof (EFI_STRING_ID)}, + {"EFI_HII_TIME", EFI_IFR_TYPE_TIME, sizeof (EFI_HII_TIME), sizeof (UINT8)}, + {NULL, EFI_IFR_TYPE_OTHER, 0, 0} +}; + +STATIC +BOOLEAN +_IS_INTERNAL_TYPE ( + IN INT8 *TypeName + ) +{ + UINT32 Index; + + if (TypeName == NULL) { + return FALSE; + } + + for (Index = 0; gInternalTypesTable[Index].mTypeName != NULL; Index++) { + if (strcmp (TypeName, gInternalTypesTable[Index].mTypeName) == 0) { + return TRUE; + } + } + + return FALSE; +} + +STATIC +INT8 * +TrimHex ( + IN INT8 *Str, + OUT bool *IsHex + ) +{ + *IsHex = FALSE; + + while (*Str && *Str == ' ') { + Str++; + } + while (*Str && *Str == '0') { + Str++; + } + if (*Str && (*Str == 'x' || *Str == 'X')) { + Str++; + *IsHex = TRUE; + } + + return Str; +} + +UINT32 +_STR2U32 ( + IN INT8 *Str + ) +{ + bool IsHex; + UINT32 Value; + INT8 c; + + Str = TrimHex (Str, &IsHex); + for (Value = 0; (c = *Str) != '\0'; Str++) { + // + // BUG: does not handle overflow here + // + (IsHex == TRUE) ? (Value <<= 4) : (Value *= 10); + + if ((IsHex == TRUE) && (c >= 'a') && (c <= 'f')) { + Value += (c - 'a' + 10); + } + if ((IsHex == TRUE) && (c >= 'A') && (c <= 'F')) { + Value += (c - 'A' + 10); + } + if (c >= '0' && c <= '9') { + Value += (c - '0'); + } + } + + return Value; +} + +VOID +CVfrVarDataTypeDB::RegisterNewType ( + IN SVfrDataType *New + ) +{ + New->mNext = mDataTypeList; + mDataTypeList = New; +} + +EFI_VFR_RETURN_CODE +CVfrVarDataTypeDB::ExtractStructTypeName ( + IN INT8 *&VarStr, + OUT INT8 *TName + ) +{ + if (TName == NULL) { + return VFR_RETURN_FATAL_ERROR; + } + + while((*VarStr != '\0') && (*VarStr != '.')) { + *TName = *VarStr; + VarStr++; + TName++; + } + *TName = '\0'; + if (*VarStr == '.') { + VarStr++; + } + + return VFR_RETURN_SUCCESS; +} + +EFI_VFR_RETURN_CODE +CVfrVarDataTypeDB::ExtractFieldNameAndArrary ( + IN INT8 *&VarStr, + IN INT8 *FName, + OUT UINT32 &ArrayIdx + ) +{ + UINT32 Idx; + INT8 ArrayStr[MAX_NAME_LEN + 1]; + + ArrayIdx = INVALID_ARRAY_INDEX; + + if (FName == NULL) { + return VFR_RETURN_FATAL_ERROR; + } + + while((*VarStr != '\0') && + (*VarStr != '.') && + (*VarStr != '[') && + (*VarStr != ']')) { + *FName = *VarStr; + VarStr++; + FName++; + } + *FName = '\0'; + + switch (*VarStr) { + case '.' : + VarStr++; + case '\0': + return VFR_RETURN_SUCCESS; + case '[' : + VarStr++; + for (Idx = 0; (Idx < MAX_NAME_LEN) && (*VarStr != '\0') && (*VarStr != ']'); VarStr++, Idx++) { + ArrayStr[Idx] = *VarStr; + } + ArrayStr[Idx] = '\0'; + + if ((*VarStr != ']') && (ArrayStr[0] == '\0')) { + return VFR_RETURN_DATA_STRING_ERROR; + } + ArrayIdx = _STR2U32 (ArrayStr); + if (*VarStr == ']') { + VarStr++; + } + return VFR_RETURN_SUCCESS; + case ']': + return VFR_RETURN_DATA_STRING_ERROR; + } + + return VFR_RETURN_SUCCESS; +} + +EFI_VFR_RETURN_CODE +CVfrVarDataTypeDB::GetTypeField ( + IN INT8 *FName, + IN SVfrDataType *Type, + OUT SVfrDataField *&Field + ) +{ + SVfrDataField *pField = NULL; + + if ((FName == NULL) && (Type == NULL)) { + return VFR_RETURN_FATAL_ERROR; + } + + for (pField = Type->mMembers; pField != NULL; pField = pField->mNext) { + if (strcmp (pField->mFieldName, FName) == 0) { + Field = pField; + return VFR_RETURN_SUCCESS; + } + } + + return VFR_RETURN_UNDEFINED; +} + +EFI_VFR_RETURN_CODE +CVfrVarDataTypeDB::GetFieldOffset ( + IN SVfrDataField *Field, + IN UINT32 ArrayIdx, + OUT UINT32 &Offset + ) +{ + if (Field == NULL) { + return VFR_RETURN_FATAL_ERROR; + } + + if ((ArrayIdx != INVALID_ARRAY_INDEX) && ((Field->mArrayNum == 0) || (Field->mArrayNum <= ArrayIdx))) { + return VFR_RETURN_ERROR_ARRARY_NUM; + } + + Offset = Field->mOffset + Field->mFieldType->mTotalSize * ((ArrayIdx == INVALID_ARRAY_INDEX) ? 0 : ArrayIdx); + return VFR_RETURN_SUCCESS; +} + +UINT8 +CVfrVarDataTypeDB::GetFieldWidth ( + IN SVfrDataField *Field + ) +{ + if (Field == NULL) { + return 0; + } + + return Field->mFieldType->mType; +} + +UINT32 +CVfrVarDataTypeDB::GetFieldSize ( + IN SVfrDataField *Field, + IN UINT32 ArrayIdx + ) +{ + if (Field == NULL) { + return VFR_RETURN_FATAL_ERROR; + } + + if ((ArrayIdx == INVALID_ARRAY_INDEX) && (Field->mArrayNum != 0)) { + return Field->mFieldType->mTotalSize * Field->mArrayNum; + } else { + return Field->mFieldType->mTotalSize; + } +} + +VOID +CVfrVarDataTypeDB::InternalTypesListInit ( + VOID + ) +{ + SVfrDataType *New = NULL; + UINT32 Index; + + for (Index = 0; gInternalTypesTable[Index].mTypeName != NULL; Index++) { + New = new SVfrDataType; + if (New != NULL) { + strcpy (New->mTypeName, gInternalTypesTable[Index].mTypeName); + New->mType = gInternalTypesTable[Index].mType; + New->mAlign = gInternalTypesTable[Index].mAlign; + New->mTotalSize = gInternalTypesTable[Index].mSize; + if (strcmp (gInternalTypesTable[Index].mTypeName, "EFI_HII_DATE") == 0) { + SVfrDataField *pYearField = new SVfrDataField; + SVfrDataField *pMonthField = new SVfrDataField; + SVfrDataField *pDayField = new SVfrDataField; + + strcpy (pYearField->mFieldName, "Year"); + GetDataType ("UINT8", &pYearField->mFieldType); + pYearField->mOffset = 0; + pYearField->mNext = pMonthField; + pYearField->mArrayNum = 0; + + strcpy (pMonthField->mFieldName, "Month"); + GetDataType ("UINT8", &pMonthField->mFieldType); + pMonthField->mOffset = 1; + pMonthField->mNext = pDayField; + pMonthField->mArrayNum = 0; + + strcpy (pDayField->mFieldName, "Day"); + GetDataType ("UINT8", &pDayField->mFieldType); + pDayField->mOffset = 2; + pDayField->mNext = NULL; + pDayField->mArrayNum = 0; + + New->mMembers = pYearField; + } else if (strcmp (gInternalTypesTable[Index].mTypeName, "EFI_HII_TIME") == 0) { + SVfrDataField *pHoursField = new SVfrDataField; + SVfrDataField *pMinutesField = new SVfrDataField; + SVfrDataField *pSecondsField = new SVfrDataField; + + strcpy (pHoursField->mFieldName, "Hours"); + GetDataType ("UINT8", &pHoursField->mFieldType); + pHoursField->mOffset = 0; + pHoursField->mNext = pMinutesField; + pHoursField->mArrayNum = 0; + + strcpy (pMinutesField->mFieldName, "Minutes"); + GetDataType ("UINT8", &pMinutesField->mFieldType); + pMinutesField->mOffset = 1; + pMinutesField->mNext = pSecondsField; + pMinutesField->mArrayNum = 0; + + strcpy (pSecondsField->mFieldName, "Seconds"); + GetDataType ("UINT8", &pSecondsField->mFieldType); + pSecondsField->mOffset = 2; + pSecondsField->mNext = NULL; + pSecondsField->mArrayNum = 0; + + New->mMembers = pHoursField; + } else { + New->mMembers = NULL; + } + New->mNext = NULL; + RegisterNewType (New); + New = NULL; + } + } +} + +CVfrVarDataTypeDB::CVfrVarDataTypeDB ( + VOID + ) +{ + mDataTypeList = NULL; + mNewDataType = NULL; + mCurrDataField = NULL; + mPackAlign = DEFAULT_PACK_ALIGN; + + InternalTypesListInit (); +} + +CVfrVarDataTypeDB::~CVfrVarDataTypeDB ( + VOID + ) +{ + SVfrDataType *pType; + SVfrDataField *pField; + + if (mNewDataType != NULL) { + delete mNewDataType; + } + + while (mDataTypeList != NULL) { + pType = mDataTypeList; + mDataTypeList = mDataTypeList->mNext; + while(pType->mMembers != NULL) { + pField = pType->mMembers; + pType->mMembers = pType->mMembers->mNext; + delete pField; + } + delete pType; + } + +} + +EFI_VFR_RETURN_CODE +CVfrVarDataTypeDB::Pack ( + IN UINT32 Align + ) +{ + if (Align == 0) { + return VFR_RETURN_INVALID_PARAMETER; + } else if (Align > 1) { + mPackAlign = Align + Align % 2; + } else { + mPackAlign = Align; + } + + return VFR_RETURN_SUCCESS; +} + +VOID +CVfrVarDataTypeDB::UnPack ( + VOID + ) +{ + mPackAlign = DEFAULT_PACK_ALIGN; +} + +VOID +CVfrVarDataTypeDB::DeclareDataTypeBegin ( + VOID + ) +{ + SVfrDataType *pNewType = NULL; + + pNewType = new SVfrDataType; + pNewType->mTypeName[0] = '\0'; + pNewType->mType = EFI_IFR_TYPE_OTHER; + pNewType->mAlign = DEFAULT_ALIGN; + pNewType->mTotalSize = 0; + pNewType->mMembers = NULL; + pNewType->mNext = NULL; + + mNewDataType = pNewType; +} + +EFI_VFR_RETURN_CODE +CVfrVarDataTypeDB::SetNewTypeName ( + IN INT8 *TypeName + ) +{ + SVfrDataType *pType; + + if (mNewDataType == NULL) { + return VFR_RETURN_ERROR_SKIPED; + } + if (TypeName == NULL) { + return VFR_RETURN_FATAL_ERROR; + } + if (strlen(TypeName) >= MAX_NAME_LEN) { + return VFR_RETURN_INVALID_PARAMETER; + } + + for (pType = mDataTypeList; pType != NULL; pType = pType->mNext) { + if (strcmp(pType->mTypeName, TypeName) == 0) { + return VFR_RETURN_REDEFINED; + } + } + + strcpy(mNewDataType->mTypeName, TypeName); + return VFR_RETURN_SUCCESS; +} + +EFI_VFR_RETURN_CODE +CVfrVarDataTypeDB::DataTypeAddField ( + IN INT8 *FieldName, + IN INT8 *TypeName, + IN UINT32 ArrayNum + ) +{ + SVfrDataField *pNewField = NULL; + SVfrDataType *pFieldType = NULL; + SVfrDataField *pTmp; + UINT32 Align; + + CHECK_ERROR_RETURN (GetDataType (TypeName, &pFieldType), VFR_RETURN_SUCCESS); + + if (strlen (FieldName) >= MAX_NAME_LEN) { + return VFR_RETURN_INVALID_PARAMETER; + } + + for (pTmp = mNewDataType->mMembers; pTmp != NULL; pTmp = pTmp->mNext) { + if (strcmp (pTmp->mFieldName, FieldName) == 0) { + return VFR_RETURN_REDEFINED; + } + } + + Align = MIN (mPackAlign, pFieldType->mAlign); + + if ((pNewField = new SVfrDataField) == NULL) { + return VFR_RETURN_OUT_FOR_RESOURCES; + } + strcpy (pNewField->mFieldName, FieldName); + pNewField->mFieldType = pFieldType; + pNewField->mArrayNum = ArrayNum; + if ((mNewDataType->mTotalSize % Align) == 0) { + pNewField->mOffset = mNewDataType->mTotalSize; + } else { + pNewField->mOffset = mNewDataType->mTotalSize + ALIGN_STUFF(mNewDataType->mTotalSize, Align); + } + if (mNewDataType->mMembers == NULL) { + mNewDataType->mMembers = pNewField; + pNewField->mNext = NULL; + } else { + for (pTmp = mNewDataType->mMembers; pTmp->mNext != NULL; pTmp = pTmp->mNext) + ; + pTmp->mNext = pNewField; + pNewField->mNext = NULL; + } + + mNewDataType->mAlign = MIN (mPackAlign, MAX (pFieldType->mAlign, mNewDataType->mAlign)); + mNewDataType->mTotalSize = pNewField->mOffset + (pNewField->mFieldType->mTotalSize) * ((ArrayNum == 0) ? 1 : ArrayNum); + + return VFR_RETURN_SUCCESS; +} + +VOID +CVfrVarDataTypeDB::DeclareDataTypeEnd ( + VOID + ) +{ + if (mNewDataType->mTypeName[0] == '\0') { + return; + } + + if ((mNewDataType->mTotalSize % mNewDataType->mAlign) !=0) { + mNewDataType->mTotalSize += ALIGN_STUFF (mNewDataType->mTotalSize, mNewDataType->mAlign); + } + + RegisterNewType (mNewDataType); + mNewDataType = NULL; +} + +EFI_VFR_RETURN_CODE +CVfrVarDataTypeDB::GetDataType ( + IN INT8 *TypeName, + OUT SVfrDataType **DataType + + ) +{ + SVfrDataType *pDataType = NULL; + + if (TypeName == NULL) { + return VFR_RETURN_ERROR_SKIPED; + } + + if (DataType == NULL) { + return VFR_RETURN_FATAL_ERROR; + } + + *DataType = NULL; + + for (pDataType = mDataTypeList; pDataType != NULL; pDataType = pDataType->mNext) { + if (strcmp (TypeName, pDataType->mTypeName) == 0) { + *DataType = pDataType; + return VFR_RETURN_SUCCESS; + } + } + + return VFR_RETURN_UNDEFINED; +} + +EFI_VFR_RETURN_CODE +CVfrVarDataTypeDB::GetDataTypeSize ( + IN INT8 *TypeName, + OUT UINT32 *Size + ) +{ + SVfrDataType *pDataType = NULL; + + if (Size == NULL) { + return VFR_RETURN_FATAL_ERROR; + } + + *Size = 0; + + for (pDataType = mDataTypeList; pDataType != NULL; pDataType = pDataType->mNext) { + if (strcmp (TypeName, pDataType->mTypeName) == 0) { + *Size = pDataType->mTotalSize; + return VFR_RETURN_SUCCESS; + } + } + + return VFR_RETURN_UNDEFINED; +} + +EFI_VFR_RETURN_CODE +CVfrVarDataTypeDB::GetDataFieldInfo ( + IN INT8 *VarStr, + OUT UINT16 &Offset, + OUT UINT8 &Type, + OUT UINT32 &Size + ) +{ + INT8 TName[MAX_NAME_LEN], FName[MAX_NAME_LEN]; + UINT32 ArrayIdx, Tmp; + SVfrDataType *pType = NULL; + SVfrDataField *pField = NULL; + + Offset = 0; + Type = EFI_IFR_TYPE_OTHER; + Size = 0; + + CHECK_ERROR_RETURN (ExtractStructTypeName (VarStr, TName), VFR_RETURN_SUCCESS); + CHECK_ERROR_RETURN (GetDataType (TName, &pType), VFR_RETURN_SUCCESS); + + // + // if it is not struct data type + // + Type = pType->mType; + Size = pType->mTotalSize; + + while (*VarStr != '\0') { + CHECK_ERROR_RETURN(ExtractFieldNameAndArrary(VarStr, FName, ArrayIdx), VFR_RETURN_SUCCESS); + CHECK_ERROR_RETURN(GetTypeField (FName, pType, pField), VFR_RETURN_SUCCESS); + pType = pField->mFieldType; + CHECK_ERROR_RETURN(GetFieldOffset (pField, ArrayIdx, Tmp), VFR_RETURN_SUCCESS); + Offset += Tmp; + Type = GetFieldWidth (pField); + Size = GetFieldSize (pField, ArrayIdx); + } + return VFR_RETURN_SUCCESS; +} + +EFI_VFR_RETURN_CODE +CVfrVarDataTypeDB::GetUserDefinedTypeNameList ( + OUT INT8 ***NameList, + OUT UINT32 *ListSize + ) +{ + UINT32 Index; + SVfrDataType *pType; + + if ((NameList == NULL) || (ListSize == NULL)) { + return VFR_RETURN_FATAL_ERROR; + } + + *NameList = NULL; + *ListSize = 0; + + for (pType = mDataTypeList; pType != NULL; pType = pType->mNext) { + if (_IS_INTERNAL_TYPE(pType->mTypeName) == FALSE) { + (*ListSize)++; + } + } + + if (*ListSize == 0) { + return VFR_RETURN_SUCCESS; + } + + if ((*NameList = new INT8*[*ListSize]) == NULL) { + *ListSize = 0; + return VFR_RETURN_OUT_FOR_RESOURCES; + } + + for (Index = 0, pType = mDataTypeList; pType != NULL; pType = pType->mNext, Index++) { + if (_IS_INTERNAL_TYPE(pType->mTypeName) == FALSE) { + (*NameList)[Index] = pType->mTypeName; + } + } + return VFR_RETURN_SUCCESS; +} + +BOOLEAN +CVfrVarDataTypeDB::IsTypeNameDefined ( + IN INT8 *TypeName + ) +{ + SVfrDataType *pType; + + if (TypeName == NULL) { + return FALSE; + } + + for (pType = mDataTypeList; pType != NULL; pType = pType->mNext) { + if (strcmp (pType->mTypeName, TypeName) == 0) { + return TRUE; + } + } + + return FALSE; +} + +#ifdef CVFR_VARDATATYPEDB_DEBUG +VOID +CVfrVarDataTypeDB::ParserDB ( + VOID + ) +{ + SVfrDataType *pTNode; + SVfrDataField *pFNode; + + printf ("***************************************************************\n"); + printf ("\t\tmPackAlign = %x\n", mPackAlign); + for (pTNode = mDataTypeList; pTNode != NULL; pTNode = pTNode->mNext) { + printf ("\t\tstruct %s : mAlign [%x] mTotalSize [%x]\n\n", pTNode->mTypeName, pTNode->mAlign, pTNode->mTotalSize); + printf ("\t\tstruct %s {\n", pTNode->mTypeName); + for (pFNode = pTNode->mMembers; pFNode != NULL; pFNode = pFNode->mNext) { + printf ("\t\t\t%s\t%s\n", pFNode->mFieldType->mTypeName, pFNode->mFieldName); + } + printf ("\t\t};\n"); + printf ("---------------------------------------------------------------\n"); + } + printf ("***************************************************************\n"); +} +#endif + +SVfrVarStorageNode::SVfrVarStorageNode ( + IN EFI_GUID *Guid, + IN INT8 *StoreName, + IN EFI_VARSTORE_ID VarStoreId, + IN EFI_STRING_ID VarName, + IN UINT32 VarSize + ) +{ + if (Guid != NULL) { + mGuid = *Guid; + } else { + memset (&Guid, 0, sizeof (EFI_GUID)); + } + if (StoreName != NULL) { + mVarStoreName = new INT8[strlen(StoreName) + 1]; + strcpy (mVarStoreName, StoreName); + } else { + mVarStoreName = NULL; + } + mNext = NULL; + mVarStoreId = VarStoreId; + mVarStoreType = EFI_VFR_VARSTORE_EFI; + mStorageInfo.mEfiVar.mEfiVarName = VarName; + mStorageInfo.mEfiVar.mEfiVarSize = VarSize; +} + +SVfrVarStorageNode::SVfrVarStorageNode ( + IN EFI_GUID *Guid, + IN INT8 *StoreName, + IN EFI_VARSTORE_ID VarStoreId, + IN SVfrDataType *DataType + ) +{ + if (Guid != NULL) { + mGuid = *Guid; + } else { + memset (&Guid, 0, sizeof (EFI_GUID)); + } + if (StoreName != NULL) { + mVarStoreName = new INT8[strlen(StoreName) + 1]; + strcpy (mVarStoreName, StoreName); + } else { + mVarStoreName = NULL; + } + mNext = NULL; + mVarStoreId = VarStoreId; + mVarStoreType = EFI_VFR_VARSTORE_BUFFER; + mStorageInfo.mDataType = DataType; +} + +SVfrVarStorageNode::SVfrVarStorageNode ( + IN INT8 *StoreName, + IN EFI_VARSTORE_ID VarStoreId + ) +{ + if (StoreName != NULL) { + mVarStoreName = new INT8[strlen(StoreName) + 1]; + strcpy (mVarStoreName, StoreName); + } else { + mVarStoreName = NULL; + } + mNext = NULL; + mVarStoreId = VarStoreId; + mVarStoreType = EFI_VFR_VARSTORE_NAME; + mStorageInfo.mNameSpace.mNameTable = new EFI_VARSTORE_ID[DEFAULT_NAME_TABLE_ITEMS]; + mStorageInfo.mNameSpace.mTableSize = 0; +} + +SVfrVarStorageNode::~SVfrVarStorageNode ( + VOID + ) +{ + if (mVarStoreName != NULL) { + delete mVarStoreName; + } + + if (mVarStoreType == EFI_VFR_VARSTORE_NAME) { + delete mStorageInfo.mNameSpace.mNameTable; + } +} + +CVfrDataStorage::CVfrDataStorage ( + VOID + ) +{ + UINT32 Index; + + for (Index = 0; Index < EFI_FREE_VARSTORE_ID_BITMAP_SIZE; Index++) { + mFreeVarStoreIdBitMap[Index] = 0; + } + + // Question ID 0 is reserved. + mFreeVarStoreIdBitMap[0] = 0x80000000; + + mBufferVarStoreList = NULL; + mEfiVarStoreList = NULL; + mNameVarStoreList = NULL; + mCurrVarStorageNode = NULL; + mNewVarStorageNode = NULL; +} + +CVfrDataStorage::~CVfrDataStorage ( + VOID + ) +{ + SVfrVarStorageNode *pNode; + + while (mBufferVarStoreList != NULL) { + pNode = mBufferVarStoreList; + mBufferVarStoreList = mBufferVarStoreList->mNext; + delete pNode; + } + while (mEfiVarStoreList != NULL) { + pNode = mEfiVarStoreList; + mEfiVarStoreList = mEfiVarStoreList->mNext; + delete pNode; + } + while (mNameVarStoreList != NULL) { + pNode = mNameVarStoreList; + mNameVarStoreList = mNameVarStoreList->mNext; + delete pNode; + } + if (mNewVarStorageNode != NULL) { + delete mNewVarStorageNode; + } +} + +EFI_VARSTORE_ID +CVfrDataStorage::GetFreeVarStoreId ( + VOID + ) +{ + UINT32 Index, Mask, Offset; + + for (Index = 0; Index < EFI_FREE_VARSTORE_ID_BITMAP_SIZE; Index++) { + if (mFreeVarStoreIdBitMap[Index] != 0xFFFFFFFF) { + break; + } + } + + for (Offset = 0, Mask = 0x80000000; Mask != 0; Mask >>= 1, Offset++) { + if ((mFreeVarStoreIdBitMap[Index] & Mask) == 0) { + mFreeVarStoreIdBitMap[Index] |= Mask; + return (EFI_VARSTORE_ID)((Index << EFI_BITS_SHIFT_PER_UINT32) + Offset); + } + } + + return EFI_VARSTORE_ID_INVALID; +} + +BOOLEAN +CVfrDataStorage::ChekVarStoreIdFree ( + IN EFI_VARSTORE_ID VarStoreId + ) +{ + UINT32 Index = (VarStoreId / EFI_BITS_PER_UINT32); + UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32); + + return (mFreeVarStoreIdBitMap[Index] & (0x80000000 >> Offset)) == 0; +} + +VOID +CVfrDataStorage::MarkVarStoreIdUsed ( + IN EFI_VARSTORE_ID VarStoreId + ) +{ + UINT32 Index = (VarStoreId / EFI_BITS_PER_UINT32); + UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32); + + mFreeVarStoreIdBitMap[Index] |= (0x80000000 >> Offset); +} + +VOID +CVfrDataStorage::MarkVarStoreIdUnused ( + IN EFI_VARSTORE_ID VarStoreId + ) +{ + UINT32 Index = (VarStoreId / EFI_BITS_PER_UINT32); + UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32); + + mFreeVarStoreIdBitMap[Index] &= ~(0x80000000 >> Offset); +} + +EFI_VFR_RETURN_CODE +CVfrDataStorage::DeclareNameVarStoreBegin ( + IN INT8 *StoreName + ) +{ + SVfrVarStorageNode *pNode = NULL; + EFI_VARSTORE_ID VarStoreId; + + if (StoreName == NULL) { + return VFR_RETURN_FATAL_ERROR; + } + + for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) { + if (strcmp (pNode->mVarStoreName, StoreName) == 0) { + return VFR_RETURN_REDEFINED; + } + } + + VarStoreId = GetFreeVarStoreId (); + if ((pNode = new SVfrVarStorageNode (StoreName, VarStoreId)) == NULL) { + return VFR_RETURN_UNDEFINED; + } + + mNewVarStorageNode = pNode; + + return VFR_RETURN_SUCCESS; +} + +EFI_VFR_RETURN_CODE +CVfrDataStorage::NameTableAddItem ( + IN EFI_STRING_ID Item + ) +{ + EFI_VARSTORE_ID *NewTable, *OldTable; + UINT32 TableSize; + + OldTable = mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable; + TableSize = mNewVarStorageNode->mStorageInfo.mNameSpace.mTableSize; + + if ((TableSize != 0) && ((TableSize % DEFAULT_NAME_TABLE_ITEMS) == 0)) { + if ((NewTable = new EFI_VARSTORE_ID[TableSize + DEFAULT_NAME_TABLE_ITEMS]) == NULL) { + return VFR_RETURN_OUT_FOR_RESOURCES; + } + memcpy (NewTable, OldTable, TableSize); + mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable = NewTable; + } + + mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable[TableSize++] = Item; + mNewVarStorageNode->mStorageInfo.mNameSpace.mTableSize = TableSize; + + return VFR_RETURN_SUCCESS; +} + +EFI_VFR_RETURN_CODE +CVfrDataStorage::DeclareNameVarStoreEnd ( + IN EFI_GUID *Guid + ) +{ + mNewVarStorageNode->mGuid = *Guid; + mNewVarStorageNode->mNext = mNameVarStoreList; + mNameVarStoreList = mNewVarStorageNode; + + mNewVarStorageNode = NULL; + + return VFR_RETURN_SUCCESS; +} + +EFI_VFR_RETURN_CODE +CVfrDataStorage::DeclareEfiVarStore ( + IN INT8 *StoreName, + IN EFI_GUID *Guid, + IN EFI_STRING_ID NameStrId, + IN UINT32 VarSize + ) +{ + SVfrVarStorageNode *pNode; + EFI_VARSTORE_ID VarStoreId; + + if ((StoreName == NULL) || (Guid == NULL)) { + return VFR_RETURN_FATAL_ERROR; + } + + if (VarSize > sizeof (UINT64)) { + return VFR_RETURN_EFIVARSTORE_SIZE_ERROR; + } + + for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) { + if (strcmp (pNode->mVarStoreName, StoreName) == 0) { + return VFR_RETURN_REDEFINED; + } + } + + VarStoreId = GetFreeVarStoreId (); + if ((pNode = new SVfrVarStorageNode (Guid, StoreName, VarStoreId, NameStrId, VarSize)) == NULL) { + return VFR_RETURN_OUT_FOR_RESOURCES; + } + + pNode->mNext = mNameVarStoreList; + mNameVarStoreList = pNode; + + return VFR_RETURN_SUCCESS; +} + +EFI_VFR_RETURN_CODE +CVfrDataStorage::DeclareBufferVarStore ( + IN INT8 *StoreName, + IN EFI_GUID *Guid, + IN CVfrVarDataTypeDB *DataTypeDB, + IN INT8 *TypeName, + IN EFI_VARSTORE_ID VarStoreId + ) +{ + SVfrVarStorageNode *pNew = NULL; + SVfrDataType *pDataType = NULL; + + if ((StoreName == NULL) || (Guid == NULL) || (DataTypeDB == NULL)) { + return VFR_RETURN_FATAL_ERROR; + } + + CHECK_ERROR_RETURN(DataTypeDB->GetDataType (TypeName, &pDataType), VFR_RETURN_SUCCESS); + + if (VarStoreId == EFI_VARSTORE_ID_INVALID) { + VarStoreId = GetFreeVarStoreId (); + } else { + if (ChekVarStoreIdFree (VarStoreId) == FALSE) { + return VFR_RETURN_VARSTOREID_REDEFINED; + } + MarkVarStoreIdUsed (VarStoreId); + } + + if ((pNew = new SVfrVarStorageNode (Guid, StoreName, VarStoreId, pDataType)) == NULL) { + return VFR_RETURN_OUT_FOR_RESOURCES; + } + + pNew->mNext = mBufferVarStoreList; + mBufferVarStoreList = pNew; + + if (gCVfrBufferConfig.Register(StoreName) != 0) { + return VFR_RETURN_FATAL_ERROR; + } + + return VFR_RETURN_SUCCESS; +} + +EFI_VFR_RETURN_CODE +CVfrDataStorage::GetVarStoreId ( + IN INT8 *StoreName, + OUT EFI_VARSTORE_ID *VarStoreId + ) +{ + SVfrVarStorageNode *pNode; + + for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) { + if (strcmp (pNode->mVarStoreName, StoreName) == 0) { + mCurrVarStorageNode = pNode; + *VarStoreId = pNode->mVarStoreId; + return VFR_RETURN_SUCCESS; + } + } + + for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) { + if (strcmp (pNode->mVarStoreName, StoreName) == 0) { + mCurrVarStorageNode = pNode; + *VarStoreId = pNode->mVarStoreId; + return VFR_RETURN_SUCCESS; + } + } + + for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) { + if (strcmp (pNode->mVarStoreName, StoreName) == 0) { + mCurrVarStorageNode = pNode; + *VarStoreId = pNode->mVarStoreId; + return VFR_RETURN_SUCCESS; + } + } + + mCurrVarStorageNode = NULL; + *VarStoreId = EFI_VARSTORE_ID_INVALID; + return VFR_RETURN_UNDEFINED; +} + +EFI_VFR_RETURN_CODE +CVfrDataStorage::GetBufferVarStoreDataTypeName ( + IN INT8 *StoreName, + OUT INT8 **DataTypeName + ) +{ + SVfrVarStorageNode *pNode; + + if ((StoreName == NULL) || (DataTypeName == NULL)) { + return VFR_RETURN_FATAL_ERROR; + } + + for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) { + if (strcmp (pNode->mVarStoreName, StoreName) == 0) { + break; + } + } + + if (pNode == NULL) { + return VFR_RETURN_UNDEFINED; + } + + if (pNode->mStorageInfo.mDataType == NULL) { + return VFR_RETURN_FATAL_ERROR; + } + + *DataTypeName = pNode->mStorageInfo.mDataType->mTypeName; + return VFR_RETURN_SUCCESS; +} + +EFI_VFR_RETURN_CODE +CVfrDataStorage::GetVarStoreType ( + IN INT8 *StoreName, + OUT EFI_VFR_VARSTORE_TYPE &VarStoreType + ) +{ + SVfrVarStorageNode *pNode; + + if (StoreName == NULL) { + return VFR_RETURN_FATAL_ERROR; + } + + for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) { + if (strcmp (pNode->mVarStoreName, StoreName) == NULL) { + VarStoreType = pNode->mVarStoreType; + return VFR_RETURN_SUCCESS; + } + } + + for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) { + if (strcmp (pNode->mVarStoreName, StoreName) == NULL) { + VarStoreType = pNode->mVarStoreType; + return VFR_RETURN_SUCCESS; + } + } + + for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) { + if (strcmp (pNode->mVarStoreName, StoreName) == NULL) { + VarStoreType = pNode->mVarStoreType; + return VFR_RETURN_SUCCESS; + } + } + + VarStoreType = EFI_VFR_VARSTORE_INVALID; + return VFR_RETURN_UNDEFINED; +} + +EFI_VFR_RETURN_CODE +CVfrDataStorage::GetVarStoreName ( + IN EFI_VARSTORE_ID VarStoreId, + OUT INT8 **VarStoreName + ) +{ + SVfrVarStorageNode *pNode; + + if (VarStoreName == NULL) { + return VFR_RETURN_FATAL_ERROR; + } + + for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) { + if (pNode->mVarStoreId == VarStoreId) { + *VarStoreName = pNode->mVarStoreName; + return VFR_RETURN_SUCCESS; + } + } + + for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) { + if (pNode->mVarStoreId == VarStoreId) { + *VarStoreName = pNode->mVarStoreName; + return VFR_RETURN_SUCCESS; + } + } + + for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) { + if (pNode->mVarStoreId == VarStoreId) { + *VarStoreName = pNode->mVarStoreName; + return VFR_RETURN_SUCCESS; + } + } + + *VarStoreName = NULL; + return VFR_RETURN_UNDEFINED; +} + +EFI_VFR_RETURN_CODE +CVfrDataStorage::GetEfiVarStoreInfo ( + IN OUT EFI_VARSTORE_INFO *Info + ) +{ + if (Info == NULL) { + return VFR_RETURN_FATAL_ERROR; + } + + if (mCurrVarStorageNode == NULL) { + return VFR_RETURN_GET_EFIVARSTORE_ERROR; + } + + Info->mInfo.mVarName = mCurrVarStorageNode->mStorageInfo.mEfiVar.mEfiVarName; + Info->mVarTotalSize = mCurrVarStorageNode->mStorageInfo.mEfiVar.mEfiVarSize; + switch (Info->mVarTotalSize) { + case 1: + Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_8; + break; + case 2: + Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_16; + break; + case 4: + Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_32; + break; + case 8: + Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_64; + break; + default : + return VFR_RETURN_FATAL_ERROR; + } + + return VFR_RETURN_SUCCESS; +} + +EFI_VFR_RETURN_CODE +CVfrDataStorage::GetNameVarStoreInfo ( + OUT EFI_VARSTORE_INFO *Info, + IN UINT32 Index + ) +{ + if (Info == NULL) { + return VFR_RETURN_FATAL_ERROR; + } + + if (mCurrVarStorageNode == NULL) { + return VFR_RETURN_GET_NVVARSTORE_ERROR; + } + + Info->mInfo.mVarName = mCurrVarStorageNode->mStorageInfo.mNameSpace.mNameTable[Index]; + + return VFR_RETURN_SUCCESS; +} + +EFI_VFR_RETURN_CODE +CVfrDataStorage::BufferVarStoreRequestElementAdd ( + IN INT8 *StoreName, + IN EFI_VARSTORE_INFO &Info + ) +{ + INT8 NewReqElt[128] = {'\0',}; + INT8 *OldReqElt = NULL; + SVfrVarStorageNode *pNode = NULL; + EFI_IFR_TYPE_VALUE Value; + + for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) { + if (strcmp (pNode->mVarStoreName, StoreName) == NULL) { + break; + } + } + + if (pNode == NULL) { + return VFR_RETURN_UNDEFINED; + } + + gCVfrBufferConfig.Open (); + Value.u8 = 0; + if (gCVfrBufferConfig.Write ('a', StoreName, NULL, EFI_IFR_TYPE_NUM_SIZE_8, Info.mInfo.mVarOffset, Info.mVarTotalSize, Value) != 0) { + return VFR_RETURN_FATAL_ERROR; + } + gCVfrBufferConfig.Close (); + + return VFR_RETURN_SUCCESS; +} + +SVfrDefaultStoreNode::SVfrDefaultStoreNode ( + IN EFI_IFR_DEFAULTSTORE *ObjBinAddr, + IN INT8 *RefName, + IN EFI_STRING_ID DefaultStoreNameId, + IN UINT16 DefaultId + ) +{ + mObjBinAddr = ObjBinAddr; + + if (RefName != NULL) { + mRefName = new INT8[strlen (RefName) + 1]; + strcpy (mRefName, RefName); + } else { + mRefName = NULL; + } + + mNext = NULL; + mDefaultId = DefaultId; + mDefaultStoreNameId = DefaultStoreNameId; +} + +SVfrDefaultStoreNode::~SVfrDefaultStoreNode ( + VOID + ) +{ + if (mRefName != NULL) { + delete mRefName; + } +} + +CVfrDefaultStore::CVfrDefaultStore ( + VOID + ) +{ + mDefaultStoreList = NULL; +} + +CVfrDefaultStore::~CVfrDefaultStore ( + VOID + ) +{ + SVfrDefaultStoreNode *pTmp = NULL; + + while (mDefaultStoreList != NULL) { + pTmp = mDefaultStoreList; + mDefaultStoreList = mDefaultStoreList->mNext; + delete pTmp; + } +} + +EFI_VFR_RETURN_CODE +CVfrDefaultStore::RegisterDefaultStore ( + IN CHAR8 *ObjBinAddr, + IN INT8 *RefName, + IN EFI_STRING_ID DefaultStoreNameId, + IN UINT16 DefaultId + ) +{ + SVfrDefaultStoreNode *pNode = NULL; + + if (RefName == NULL) { + return VFR_RETURN_FATAL_ERROR; + } + + for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) { + if (strcmp (pNode->mRefName, RefName) == 0) { + return VFR_RETURN_REDEFINED; + } + } + + if ((pNode = new SVfrDefaultStoreNode ((EFI_IFR_DEFAULTSTORE *)ObjBinAddr, RefName, DefaultStoreNameId, DefaultId)) == NULL) { + return VFR_RETURN_OUT_FOR_RESOURCES; + } + + pNode->mNext = mDefaultStoreList; + mDefaultStoreList = pNode; + + return VFR_RETURN_SUCCESS; +} + +/* + * assign new reference name or new default store name id only if + * the original is invalid + */ +EFI_VFR_RETURN_CODE +CVfrDefaultStore::ReRegisterDefaultStoreById ( + IN UINT16 DefaultId, + IN INT8 *RefName, + IN EFI_STRING_ID DefaultStoreNameId + ) +{ + SVfrDefaultStoreNode *pNode = NULL; + + for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) { + if (pNode->mDefaultId == DefaultId) { + break; + } + } + + if (pNode == NULL) { + return VFR_RETURN_UNDEFINED; + } else { + if (pNode->mDefaultStoreNameId == EFI_STRING_ID_INVALID) { + pNode->mDefaultStoreNameId = DefaultStoreNameId; + if (pNode->mObjBinAddr != NULL) { + pNode->mObjBinAddr->DefaultName = DefaultStoreNameId; + } + } else { + return VFR_RETURN_REDEFINED; + } + + if (RefName != NULL) { + delete pNode->mRefName; + pNode->mRefName = new INT8[strlen (RefName) + 1]; + if (pNode->mRefName != NULL) { + strcpy (pNode->mRefName, RefName); + } + } + } + + return VFR_RETURN_SUCCESS; +} + +BOOLEAN +CVfrDefaultStore::DefaultIdRegistered ( + IN UINT16 DefaultId + ) +{ + SVfrDefaultStoreNode *pNode = NULL; + + for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) { + if (pNode->mDefaultId == DefaultId) { + return TRUE; + } + } + + return FALSE; +} + +EFI_VFR_RETURN_CODE +CVfrDefaultStore::GetDefaultId ( + IN INT8 *RefName, + OUT UINT16 *DefaultId + ) +{ + SVfrDefaultStoreNode *pTmp = NULL; + + if (DefaultId == NULL) { + return VFR_RETURN_FATAL_ERROR; + } + + for (pTmp = mDefaultStoreList; pTmp != NULL; pTmp = pTmp->mNext) { + if (strcmp (pTmp->mRefName, RefName) == 0) { + *DefaultId = pTmp->mDefaultId; + return VFR_RETURN_SUCCESS; + } + } + + return VFR_RETURN_UNDEFINED; +} + +STATIC +EFI_VFR_RETURN_CODE +AltCfgItemPrintToBuffer ( + IN INT8 *NewAltCfg, + IN EFI_VARSTORE_INFO Info, + IN UINT8 Type, + IN EFI_IFR_TYPE_VALUE Value + ) +{ + UINT32 Index; + UINT8 *BufChar = NULL; + UINT32 Count = 0; + + if (NewAltCfg != NULL) { + Count = sprintf ( + NewAltCfg, + "&OFFSET=%x&WIDTH=%x&VALUE=", + Info.mInfo.mVarOffset, + Info.mVarTotalSize + ); + NewAltCfg += Count; + + switch (Type) { + case EFI_IFR_TYPE_NUM_SIZE_8 : + Count = sprintf (NewAltCfg, "%x", Value.u8); + NewAltCfg += Count; + break; + case EFI_IFR_TYPE_NUM_SIZE_16 : + Count = sprintf (NewAltCfg, "%x", Value.u16); + NewAltCfg += Count; + break; + case EFI_IFR_TYPE_NUM_SIZE_32 : + Count = sprintf (NewAltCfg, "%x", Value.u32); + NewAltCfg += Count; + break; + case EFI_IFR_TYPE_NUM_SIZE_64 : + Count = sprintf (NewAltCfg, "%x", Value.u64); + NewAltCfg += Count; + break; + case EFI_IFR_TYPE_BOOLEAN : + Count = sprintf (NewAltCfg, "%x", Value.b); + NewAltCfg += Count; + break; + case EFI_IFR_TYPE_TIME : +#if 1 + Count = sprintf (NewAltCfg, "%x", *((UINT32 *)(&Value.time))); + NewAltCfg += Count; +#else + BufChar = (UINT8 *)&Value.time; + for (Index = 0; Index < sizeof(EFI_HII_TIME); Index++) { + Count = sprintf (NewAltCfg, "%02x", (UINT8)BufChar[Index]); + NewAltCfg += Count; + } +#endif + break; + case EFI_IFR_TYPE_DATE : +#if 1 + Count = sprintf (NewAltCfg, "%x", *((UINT32 *)(&Value.date))); + NewAltCfg += Count; +#else + BufChar = (UINT8 *)&Value.date; + for (Index = 0; Index < sizeof(EFI_HII_DATE); Index++) { + Count = sprintf (NewAltCfg, "%02x", (UINT8)BufChar[Index]); + NewAltCfg += Count; + } +#endif + break; + case EFI_IFR_TYPE_STRING : + Count = sprintf (NewAltCfg, "%x", Value.string); + NewAltCfg += Count; + break; + case EFI_IFR_TYPE_OTHER : + return VFR_RETURN_UNSUPPORTED; + } + } + + return VFR_RETURN_FATAL_ERROR; +} + +EFI_VFR_RETURN_CODE +CVfrDefaultStore::BufferVarStoreAltConfigAdd ( + IN EFI_VARSTORE_ID DefaultId, + IN EFI_VARSTORE_INFO &Info, + IN INT8 *VarStoreName, + IN UINT8 Type, + IN EFI_IFR_TYPE_VALUE Value + ) +{ + SVfrDefaultStoreNode *pNode = NULL; + INT8 NewAltCfg[2 * 2 * sizeof (UINT16) + 1] = {0,}; + + if (VarStoreName == NULL) { + return VFR_RETURN_FATAL_ERROR; + } + + for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) { + if (pNode->mDefaultId == DefaultId) { + break; + } + } + + if (pNode == NULL) { + return VFR_RETURN_UNDEFINED; + } + + gCVfrBufferConfig.Open (); + + sprintf (NewAltCfg, "%04x", pNode->mDefaultId); + if ((gCVfrBufferConfig.Select(VarStoreName) == 0) && + (gCVfrBufferConfig.Select(VarStoreName, NewAltCfg) != 0)) { + if (gCVfrBufferConfig.Write ('i', VarStoreName, NewAltCfg, Type, Info.mInfo.mVarOffset, Info.mVarTotalSize, Value) != 0) { + goto WriteError; + } + } + + if (gCVfrBufferConfig.Write ('a', VarStoreName, NULL, Type, Info.mInfo.mVarOffset, Info.mVarTotalSize, Value) != 0) { + goto WriteError; + } + + gCVfrBufferConfig.Close (); + + return VFR_RETURN_SUCCESS; + +WriteError: + gCVfrBufferConfig.Close (); + return VFR_RETURN_FATAL_ERROR; +} + +SVfrRuleNode::SVfrRuleNode ( + IN INT8 *RuleName, + IN UINT8 RuleId + ) +{ + if (RuleName != NULL) { + mRuleName = new INT8[strlen (RuleName) + 1]; + strcpy (mRuleName, RuleName); + } else { + mRuleName = NULL; + } + + mNext = NULL; + mRuleId = RuleId; +} + +SVfrRuleNode::~SVfrRuleNode ( + VOID + ) +{ + if (mRuleName != NULL) { + delete mRuleName; + } +} + +CVfrRulesDB::CVfrRulesDB () +{ + mRuleList = NULL; + mFreeRuleId = EFI_VARSTORE_ID_START; +} + +CVfrRulesDB::~CVfrRulesDB () +{ + SVfrRuleNode *pNode; + + while(mRuleList != NULL) { + pNode = mRuleList; + mRuleList = mRuleList->mNext; + delete pNode; + } +} + +VOID +CVfrRulesDB::RegisterRule ( + IN INT8 *RuleName + ) +{ + SVfrRuleNode *pNew; + + if (RuleName == NULL) { + return ; + } + + if ((pNew = new SVfrRuleNode (RuleName, mFreeRuleId)) == NULL) { + return ; + } + + mFreeRuleId++; + + pNew->mNext = mRuleList; + mRuleList = pNew; +} + +UINT8 +CVfrRulesDB::GetRuleId ( + IN INT8 *RuleName + ) +{ + SVfrRuleNode *pNode; + + if (RuleName == NULL) { + return EFI_RULE_ID_INVALID; + } + + for (pNode = mRuleList; pNode != NULL; pNode = pNode->mNext) { + if (strcmp (pNode->mRuleName, RuleName) == 0) { + return pNode->mRuleId; + } + } + + return EFI_RULE_ID_INVALID; +} + +CVfrRulesDB gCVfrRulesDB; + +EFI_VARSTORE_INFO::EFI_VARSTORE_INFO ( + VOID + ) +{ + mVarStoreId = EFI_VARSTORE_ID_INVALID; + mInfo.mVarName = EFI_STRING_ID_INVALID; + mInfo.mVarOffset = EFI_VAROFFSET_INVALID; + mVarType = EFI_IFR_TYPE_OTHER; + mVarTotalSize = 0; +} + +EFI_VARSTORE_INFO::EFI_VARSTORE_INFO ( + IN EFI_VARSTORE_INFO &Info + ) +{ + mVarStoreId = Info.mVarStoreId; + mInfo.mVarName = Info.mInfo.mVarName; + mInfo.mVarOffset = Info.mInfo.mVarOffset; + mVarType = Info.mVarType; + mVarTotalSize = Info.mVarTotalSize; +} + +BOOLEAN +EFI_VARSTORE_INFO::operator == ( + IN EFI_VARSTORE_INFO *Info + ) +{ + if ((mVarStoreId == Info->mVarStoreId) && + (mInfo.mVarName == Info->mInfo.mVarName) && + (mInfo.mVarOffset == Info->mInfo.mVarOffset) && + (mVarType == Info->mVarType) && + (mVarTotalSize == Info->mVarTotalSize)) { + return TRUE; + } + + return FALSE; +} + +static EFI_VARSTORE_INFO gEfiInvalidVarStoreInfo; + +EFI_QUESTION_ID +CVfrQuestionDB::GetFreeQuestionId ( + VOID + ) +{ + UINT32 Index, Mask, Offset; + + for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) { + if (mFreeQIdBitMap[Index] != 0xFFFFFFFF) { + break; + } + } + + for (Offset = 0, Mask = 0x80000000; Mask != 0; Mask >>= 1, Offset++) { + if ((mFreeQIdBitMap[Index] & Mask) == 0) { + mFreeQIdBitMap[Index] |= Mask; + return (EFI_QUESTION_ID)((Index << EFI_BITS_SHIFT_PER_UINT32) + Offset); + } + } + + return EFI_QUESTION_ID_INVALID; +} + +BOOLEAN +CVfrQuestionDB::ChekQuestionIdFree ( + IN EFI_QUESTION_ID QId + ) +{ + UINT32 Index = (QId / EFI_BITS_PER_UINT32); + UINT32 Offset = (QId % EFI_BITS_PER_UINT32); + + return (mFreeQIdBitMap[Index] & (0x80000000 >> Offset)) == 0; +} + +VOID +CVfrQuestionDB::MarkQuestionIdUsed ( + IN EFI_QUESTION_ID QId + ) +{ + UINT32 Index = (QId / EFI_BITS_PER_UINT32); + UINT32 Offset = (QId % EFI_BITS_PER_UINT32); + + mFreeQIdBitMap[Index] |= (0x80000000 >> Offset); +} + +VOID +CVfrQuestionDB::MarkQuestionIdUnused ( + IN EFI_QUESTION_ID QId + ) +{ + UINT32 Index = (QId / EFI_BITS_PER_UINT32); + UINT32 Offset = (QId % EFI_BITS_PER_UINT32); + + mFreeQIdBitMap[Index] &= ~(0x80000000 >> Offset); +} + +SVfrQuestionNode::SVfrQuestionNode ( + IN INT8 *Name, + IN INT8 *VarIdStr, + IN UINT32 BitMask + ) +{ + mName = NULL; + mVarIdStr = NULL; + mQuestionId = EFI_QUESTION_ID_INVALID; + mBitMask = BitMask; + mNext = NULL; + + if (Name == NULL) { + mName = new INT8[strlen ("$DEFAULT") + 1]; + strcpy (mName, "$DEFAULT"); + } else { + mName = new INT8[strlen (Name) + 1]; + strcpy (mName, Name); + } + + if (VarIdStr != NULL) { + mVarIdStr = new INT8[strlen (VarIdStr) + 1]; + strcpy (mVarIdStr, VarIdStr); + } else { + mVarIdStr = new INT8[strlen ("$") + 1]; + strcpy (mVarIdStr, "$"); + } +} + +SVfrQuestionNode::~SVfrQuestionNode ( + VOID + ) +{ + if (mName != NULL) { + delete mName; + } + + if (mVarIdStr != NULL) { + delete mVarIdStr; + } +} + +CVfrQuestionDB::CVfrQuestionDB () +{ + UINT32 Index; + + for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) { + mFreeQIdBitMap[Index] = 0; + } + + // Question ID 0 is reserved. + mFreeQIdBitMap[0] = 0x80000000; + mQuestionList = NULL; +} + +CVfrQuestionDB::~CVfrQuestionDB () +{ + SVfrQuestionNode *pNode; + + while (mQuestionList != NULL) { + pNode = mQuestionList; + mQuestionList = mQuestionList->mNext; + delete pNode; + } +} + +EFI_VFR_RETURN_CODE +CVfrQuestionDB::RegisterQuestion ( + IN INT8 *Name, + IN INT8 *VarIdStr, + IN OUT EFI_QUESTION_ID &QuestionId + ) +{ + SVfrQuestionNode *pNode = NULL; + + if ((Name != NULL) && (FindQuestion(Name) == VFR_RETURN_SUCCESS)) { + return VFR_RETURN_REDEFINED; + } + + if ((pNode = new SVfrQuestionNode (Name, VarIdStr)) == NULL) { + return VFR_RETURN_OUT_FOR_RESOURCES; + } + + if (QuestionId == EFI_QUESTION_ID_INVALID) { + QuestionId = GetFreeQuestionId (); + } else { + if (ChekQuestionIdFree (QuestionId) == FALSE) { + delete pNode; + return VFR_RETURN_QUESTIONID_REDEFINED; + } + MarkQuestionIdUsed (QuestionId); + } + pNode->mQuestionId = QuestionId; + + pNode->mNext = mQuestionList; + mQuestionList = pNode; + + gCFormPkg.DoPendingAssign (VarIdStr, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID)); + + return VFR_RETURN_SUCCESS; +} + +VOID +CVfrQuestionDB::RegisterOldDateQuestion ( + IN INT8 *YearVarId, + IN INT8 *MonthVarId, + IN INT8 *DayVarId, + IN OUT EFI_QUESTION_ID &QuestionId + ) +{ + SVfrQuestionNode *pNode[3] = {NULL, }; + UINT32 Index; + + if ((YearVarId == NULL) || (MonthVarId == NULL) || (DayVarId == NULL)) { + return; + } + + if ((pNode[0] = new SVfrQuestionNode (NULL, YearVarId, DATE_YEAR_BITMASK)) == NULL) { + goto Err; + } + if ((pNode[1] = new SVfrQuestionNode (NULL, MonthVarId, DATE_MONTH_BITMASK)) == NULL) { + goto Err; + } + if ((pNode[2] = new SVfrQuestionNode (NULL, DayVarId, DATE_DAY_BITMASK)) == NULL) { + goto Err; + } + + if (QuestionId == EFI_QUESTION_ID_INVALID) { + QuestionId = GetFreeQuestionId (); + } else { + if (ChekQuestionIdFree (QuestionId) == FALSE) { + goto Err; + } + MarkQuestionIdUsed (QuestionId); + } + + pNode[0]->mQuestionId = QuestionId; + pNode[1]->mQuestionId = QuestionId; + pNode[2]->mQuestionId = QuestionId; + pNode[0]->mNext = pNode[1]; + pNode[1]->mNext = pNode[2]; + pNode[2]->mNext = mQuestionList; + mQuestionList = pNode[0]; + + gCFormPkg.DoPendingAssign (YearVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID)); + gCFormPkg.DoPendingAssign (MonthVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID)); + gCFormPkg.DoPendingAssign (DayVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID)); + + return; + +Err: + for (Index = 0; Index < 3; Index++) { + if (pNode[Index] != NULL) { + delete pNode[Index]; + } + } + QuestionId = EFI_QUESTION_ID_INVALID; +} + +VOID +CVfrQuestionDB::RegisterNewDateQuestion ( + IN INT8 *Name, + IN INT8 *BaseVarId, + IN OUT EFI_QUESTION_ID &QuestionId + ) +{ + SVfrQuestionNode *pNode[3] = {NULL, }; + UINT32 Len; + INT8 *VarIdStr[3] = {NULL, }; + INT8 Index; + + if (BaseVarId == NULL) { + return; + } + + Len = strlen (BaseVarId); + + VarIdStr[0] = new INT8[Len + strlen (".Year") + 1]; + if (VarIdStr[0] != NULL) { + strcpy (VarIdStr[0], BaseVarId); + strcat (VarIdStr[0], ".Year"); + } + VarIdStr[1] = new INT8[Len + strlen (".Month") + 1]; + if (VarIdStr[1] != NULL) { + strcpy (VarIdStr[1], BaseVarId); + strcat (VarIdStr[1], ".Month"); + } + VarIdStr[2] = new INT8[Len + strlen (".Day") + 1]; + if (VarIdStr[2] != NULL) { + strcpy (VarIdStr[2], BaseVarId); + strcat (VarIdStr[2], ".Day"); + } + + if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0], DATE_YEAR_BITMASK)) == NULL) { + goto Err; + } + if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1], DATE_MONTH_BITMASK)) == NULL) { + goto Err; + } + if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2], DATE_DAY_BITMASK)) == NULL) { + goto Err; + } + + if (QuestionId == EFI_QUESTION_ID_INVALID) { + QuestionId = GetFreeQuestionId (); + } else { + if (ChekQuestionIdFree (QuestionId) == FALSE) { + goto Err; + } + MarkQuestionIdUsed (QuestionId); + } + + pNode[0]->mQuestionId = QuestionId; + pNode[1]->mQuestionId = QuestionId; + pNode[2]->mQuestionId = QuestionId; + pNode[0]->mNext = pNode[1]; + pNode[1]->mNext = pNode[2]; + pNode[2]->mNext = mQuestionList; + mQuestionList = pNode[0]; + + for (Index = 0; Index < 3; Index++) { + if (VarIdStr[Index] != NULL) { + delete VarIdStr[Index]; + } + } + + gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID)); + gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID)); + gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID)); + + return; + +Err: + for (Index = 0; Index < 3; Index++) { + if (pNode[Index] != NULL) { + delete pNode[Index]; + } + + if (VarIdStr[Index] != NULL) { + delete VarIdStr[Index]; + } + } +} + +VOID +CVfrQuestionDB::RegisterOldTimeQuestion ( + IN INT8 *HourVarId, + IN INT8 *MinuteVarId, + IN INT8 *SecondVarId, + IN OUT EFI_QUESTION_ID &QuestionId + ) +{ + SVfrQuestionNode *pNode[3] = {NULL, }; + UINT32 Index; + + if ((HourVarId == NULL) || (MinuteVarId == NULL) || (SecondVarId == NULL)) { + return; + } + + if ((pNode[0] = new SVfrQuestionNode (NULL, HourVarId, TIME_HOUR_BITMASK)) == NULL) { + goto Err; + } + if ((pNode[1] = new SVfrQuestionNode (NULL, MinuteVarId, TIME_MINUTE_BITMASK)) == NULL) { + goto Err; + } + if ((pNode[2] = new SVfrQuestionNode (NULL, SecondVarId, TIME_SECOND_BITMASK)) == NULL) { + goto Err; + } + + if (QuestionId == EFI_QUESTION_ID_INVALID) { + QuestionId = GetFreeQuestionId (); + } else { + if (ChekQuestionIdFree (QuestionId) == FALSE) { + goto Err; + } + MarkQuestionIdUsed (QuestionId); + } + + pNode[0]->mQuestionId = QuestionId; + pNode[1]->mQuestionId = QuestionId; + pNode[2]->mQuestionId = QuestionId; + pNode[0]->mNext = pNode[1]; + pNode[1]->mNext = pNode[2]; + pNode[2]->mNext = mQuestionList; + mQuestionList = pNode[0]; + + gCFormPkg.DoPendingAssign (HourVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID)); + gCFormPkg.DoPendingAssign (MinuteVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID)); + gCFormPkg.DoPendingAssign (SecondVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID)); + + return; + +Err: + for (Index = 0; Index < 3; Index++) { + if (pNode[Index] != NULL) { + delete pNode[Index]; + } + } + QuestionId = EFI_QUESTION_ID_INVALID; +} + +VOID +CVfrQuestionDB::RegisterNewTimeQuestion ( + IN INT8 *Name, + IN INT8 *BaseVarId, + IN OUT EFI_QUESTION_ID &QuestionId + ) +{ + SVfrQuestionNode *pNode[3] = {NULL, }; + UINT32 Len; + INT8 *VarIdStr[3] = {NULL, }; + INT8 Index; + + if (BaseVarId == NULL) { + return; + } + + Len = strlen (BaseVarId); + + VarIdStr[0] = new INT8[Len + strlen (".Hour") + 1]; + if (VarIdStr[0] != NULL) { + strcpy (VarIdStr[0], BaseVarId); + strcat (VarIdStr[0], ".Hour"); + } + VarIdStr[1] = new INT8[Len + strlen (".Minute") + 1]; + if (VarIdStr[1] != NULL) { + strcpy (VarIdStr[1], BaseVarId); + strcat (VarIdStr[1], ".Minute"); + } + VarIdStr[2] = new INT8[Len + strlen (".Second") + 1]; + if (VarIdStr[2] != NULL) { + strcpy (VarIdStr[2], BaseVarId); + strcat (VarIdStr[2], ".Second"); + } + + if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0], TIME_HOUR_BITMASK)) == NULL) { + goto Err; + } + if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1], TIME_MINUTE_BITMASK)) == NULL) { + goto Err; + } + if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2], TIME_SECOND_BITMASK)) == NULL) { + goto Err; + } + + if (QuestionId == EFI_QUESTION_ID_INVALID) { + QuestionId = GetFreeQuestionId (); + } else { + if (ChekQuestionIdFree (QuestionId) == FALSE) { + goto Err; + } + MarkQuestionIdUsed (QuestionId); + } + + pNode[0]->mQuestionId = QuestionId; + pNode[1]->mQuestionId = QuestionId; + pNode[2]->mQuestionId = QuestionId; + pNode[0]->mNext = pNode[1]; + pNode[1]->mNext = pNode[2]; + pNode[2]->mNext = mQuestionList; + mQuestionList = pNode[0]; + + for (Index = 0; Index < 3; Index++) { + if (VarIdStr[Index] != NULL) { + delete VarIdStr[Index]; + } + } + + gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID)); + gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID)); + gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID)); + + return; + +Err: + for (Index = 0; Index < 3; Index++) { + if (pNode[Index] != NULL) { + delete pNode[Index]; + } + + if (VarIdStr[Index] != NULL) { + delete VarIdStr[Index]; + } + } +} + +EFI_VFR_RETURN_CODE +CVfrQuestionDB::UpdateQuestionId ( + IN EFI_QUESTION_ID QId, + IN EFI_QUESTION_ID NewQId + ) +{ + SVfrQuestionNode *pNode = NULL; + + if (ChekQuestionIdFree (NewQId) == FALSE) { + return VFR_RETURN_REDEFINED; + } + + for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) { + if (pNode->mQuestionId == QId) { + break; + } + } + + if (pNode == NULL) { + return VFR_RETURN_UNDEFINED; + } + + MarkQuestionIdUnused (QId); + pNode->mQuestionId = NewQId; + MarkQuestionIdUsed (NewQId); + + gCFormPkg.DoPendingAssign (pNode->mVarIdStr, (VOID *)&NewQId, sizeof(EFI_QUESTION_ID)); + + return VFR_RETURN_SUCCESS; +} + +VOID +CVfrQuestionDB::GetQuestionId ( + IN INT8 *Name, + IN INT8 *VarIdStr, + OUT EFI_QUESTION_ID &QuestionId, + OUT UINT32 &BitMask + ) +{ + SVfrQuestionNode *pNode; + + QuestionId = EFI_QUESTION_ID_INVALID; + BitMask = 0x00000000; + + if ((Name == NULL) && (VarIdStr == NULL)) { + return ; + } + + for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) { + if (Name != NULL) { + if (strcmp (pNode->mName, Name) != 0) { + continue; + } + } + + if (VarIdStr != NULL) { + if (strcmp (pNode->mVarIdStr, VarIdStr) != 0) { + continue; + } + } + + QuestionId = pNode->mQuestionId; + BitMask = pNode->mBitMask; + break; + } + + return ; +} + +EFI_VFR_RETURN_CODE +CVfrQuestionDB::FindQuestion ( + IN EFI_QUESTION_ID QuestionId + ) +{ + SVfrQuestionNode *pNode; + + if (QuestionId == EFI_QUESTION_ID_INVALID) { + return VFR_RETURN_INVALID_PARAMETER; + } + + for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) { + if (pNode->mQuestionId == QuestionId) { + return VFR_RETURN_SUCCESS; + } + } + + return VFR_RETURN_UNDEFINED; +} + +EFI_VFR_RETURN_CODE +CVfrQuestionDB::FindQuestion ( + IN INT8 *Name + ) +{ + SVfrQuestionNode *pNode; + + if (Name == NULL) { + return VFR_RETURN_FATAL_ERROR; + } + + for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) { + if (strcmp (pNode->mName, Name) == 0) { + return VFR_RETURN_SUCCESS; + } + } + + return VFR_RETURN_UNDEFINED; +} + diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrUtilityLib.h b/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrUtilityLib.h new file mode 100644 index 0000000000..e8c1009101 --- /dev/null +++ b/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrUtilityLib.h @@ -0,0 +1,341 @@ +#ifndef _VFRUTILITYLIB_H_ +#define _VFRUTILITYLIB_H_ + +#include "Tiano.h" +#include "string.h" +#include "EfiTypes.h" +#include "EfiVfr.h" +#include "VfrError.h" + +#define MAX_NAME_LEN 64 +#define DEFAULT_ALIGN 1 +#define DEFAULT_PACK_ALIGN 0xFFFFFFFF +#define DEFAULT_NAME_TABLE_ITEMS 1024 + +#define EFI_BITS_SHIFT_PER_UINT32 0x5 +#define EFI_BITS_PER_UINT32 (1 << EFI_BITS_SHIFT_PER_UINT32) + +#define BUFFER_SAFE_FREE(Buf) do { if ((Buf) != NULL) { delete (Buf); } } while (0); + +class CVfrBinaryOutput { +public: + virtual VOID WriteLine (IN FILE *, IN UINT32, IN INT8 *, IN INT8 *, IN UINT32); + virtual VOID WriteEnd (IN FILE *, IN UINT32, IN INT8 *, IN INT8 *, IN UINT32); +}; + +UINT32 +_STR2U32 ( + IN INT8 *Str + ); + +struct SConfigInfo { + UINT16 mOffset; + UINT16 mWidth; + UINT8 *mValue; + SConfigInfo *mNext; + + SConfigInfo (IN UINT8, IN UINT16, IN UINT32, IN EFI_IFR_TYPE_VALUE); + ~SConfigInfo (VOID); +}; + +struct SConfigItem { + INT8 *mId; + INT8 *mInfo; + SConfigInfo *mInfoStrList; + SConfigItem *mNext; + +public: + SConfigItem (IN INT8 *, IN INT8 *); + SConfigItem (IN INT8 *, IN INT8 *, IN UINT8, IN UINT16, IN UINT16, IN EFI_IFR_TYPE_VALUE); + virtual ~SConfigItem (); +}; + +class CVfrBufferConfig { +private: + SConfigItem *mItemListHead; + SConfigItem *mItemListTail; + SConfigItem *mItemListPos; + +public: + CVfrBufferConfig (VOID); + virtual ~CVfrBufferConfig (VOID); + + virtual UINT8 Register (IN INT8 *, IN INT8 *Info = NULL); + virtual VOID Open (VOID); + virtual BOOLEAN Eof(VOID); + virtual UINT8 Select (IN INT8 *, IN INT8 *Info = NULL); + virtual UINT8 Write (IN CONST CHAR8, IN INT8 *, IN INT8 *, IN UINT8, IN UINT16, IN UINT32, IN EFI_IFR_TYPE_VALUE); +#if 0 + virtual UINT8 Read (OUT INT8 **, OUT INT8 **, OUT INT8 **, OUT INT8 **, OUT INT8 **); +#endif + virtual VOID Close (VOID); + virtual VOID OutputCFile (IN FILE *, IN INT8 *); +}; + +extern CVfrBufferConfig gCVfrBufferConfig; + +#define ALIGN_STUFF(Size, Align) ((Align) - (Size) % (Align)) +#define INVALID_ARRAY_INDEX 0xFFFFFFFF + +struct SVfrDataType; + +struct SVfrDataField { + INT8 mFieldName[MAX_NAME_LEN]; + SVfrDataType *mFieldType; + UINT32 mOffset; + UINT32 mArrayNum; + SVfrDataField *mNext; +}; + +struct SVfrDataType { + INT8 mTypeName[MAX_NAME_LEN]; + UINT8 mType; + UINT32 mAlign; + UINT32 mTotalSize; + SVfrDataField *mMembers; + SVfrDataType *mNext; +}; + +class CVfrVarDataTypeDB { +private: + SVfrDataType *mDataTypeList; + UINT32 mPackAlign; + + SVfrDataType *mNewDataType; + SVfrDataType *mCurrDataType; + SVfrDataField *mCurrDataField; + + VOID InternalTypesListInit (VOID); + VOID RegisterNewType (IN SVfrDataType *); + + EFI_VFR_RETURN_CODE ExtractStructTypeName (IN INT8 *&, OUT INT8 *); + EFI_VFR_RETURN_CODE ExtractFieldNameAndArrary (IN INT8 *&, OUT INT8 *, OUT UINT32 &); + EFI_VFR_RETURN_CODE GetTypeField (IN INT8 *, IN SVfrDataType *, IN SVfrDataField *&); + EFI_VFR_RETURN_CODE GetFieldOffset (IN SVfrDataField *, IN UINT32, OUT UINT32 &); + UINT8 GetFieldWidth (IN SVfrDataField *); + UINT32 GetFieldSize (IN SVfrDataField *, IN UINT32); + +public: + CVfrVarDataTypeDB (VOID); + ~CVfrVarDataTypeDB (VOID); + + EFI_VFR_RETURN_CODE Pack (IN UINT32); + VOID UnPack (VOID); + + VOID DeclareDataTypeBegin (VOID); + EFI_VFR_RETURN_CODE SetNewTypeName (IN INT8 *); + EFI_VFR_RETURN_CODE DataTypeAddField (IN INT8 *, IN INT8 *, IN UINT32); + VOID DeclareDataTypeEnd (VOID); + + EFI_VFR_RETURN_CODE GetDataType (IN INT8 *, OUT SVfrDataType **); + EFI_VFR_RETURN_CODE GetDataTypeSize (IN INT8 *, OUT UINT32 *); + EFI_VFR_RETURN_CODE GetDataFieldInfo (IN INT8 *, OUT UINT16 &, OUT UINT8 &, OUT UINT32 &); + + EFI_VFR_RETURN_CODE GetUserDefinedTypeNameList (OUT INT8 ***, OUT UINT32 *); + BOOLEAN IsTypeNameDefined (IN INT8 *); + +#ifdef CVFR_VARDATATYPEDB_DEBUG + VOID ParserDB (); +#endif +}; + +typedef enum { + EFI_VFR_VARSTORE_INVALID, + EFI_VFR_VARSTORE_BUFFER, + EFI_VFR_VARSTORE_EFI, + EFI_VFR_VARSTORE_NAME +} EFI_VFR_VARSTORE_TYPE; + +struct SVfrVarStorageNode { + EFI_GUID mGuid; + INT8 *mVarStoreName; + EFI_VARSTORE_ID mVarStoreId; + struct SVfrVarStorageNode *mNext; + + EFI_VFR_VARSTORE_TYPE mVarStoreType; + union { + // EFI Variable + struct { + EFI_STRING_ID mEfiVarName; + UINT32 mEfiVarSize; + } mEfiVar; + + // Buffer Storage + SVfrDataType *mDataType; + + // NameValue Storage + struct { + EFI_STRING_ID *mNameTable; + UINT32 mTableSize; + } mNameSpace; + } mStorageInfo; + +public: + SVfrVarStorageNode (IN EFI_GUID *, IN INT8 *, IN EFI_VARSTORE_ID, IN EFI_STRING_ID, IN UINT32); + SVfrVarStorageNode (IN EFI_GUID *, IN INT8 *, IN EFI_VARSTORE_ID, IN SVfrDataType *); + SVfrVarStorageNode (IN INT8 *, IN EFI_VARSTORE_ID); + ~SVfrVarStorageNode (VOID); +}; + +struct EFI_VARSTORE_INFO { + EFI_VARSTORE_ID mVarStoreId; + union { + EFI_STRING_ID mVarName; + UINT16 mVarOffset; + } mInfo; + UINT8 mVarType; + UINT32 mVarTotalSize; + + EFI_VARSTORE_INFO (VOID); + EFI_VARSTORE_INFO (IN EFI_VARSTORE_INFO &); + BOOLEAN operator == (IN EFI_VARSTORE_INFO *); +}; + +#define EFI_VARSTORE_ID_MAX 0xFFFF +#define EFI_FREE_VARSTORE_ID_BITMAP_SIZE ((EFI_VARSTORE_ID_MAX + 1) / EFI_BITS_PER_UINT32) + +class CVfrDataStorage { +private: + UINT32 mFreeVarStoreIdBitMap[EFI_FREE_VARSTORE_ID_BITMAP_SIZE]; + + struct SVfrVarStorageNode *mBufferVarStoreList; + struct SVfrVarStorageNode *mEfiVarStoreList; + struct SVfrVarStorageNode *mNameVarStoreList; + + struct SVfrVarStorageNode *mCurrVarStorageNode; + struct SVfrVarStorageNode *mNewVarStorageNode; + +private: + + EFI_VARSTORE_ID GetFreeVarStoreId (VOID); + BOOLEAN ChekVarStoreIdFree (IN EFI_VARSTORE_ID); + VOID MarkVarStoreIdUsed (IN EFI_VARSTORE_ID); + VOID MarkVarStoreIdUnused (IN EFI_VARSTORE_ID); + +public: + CVfrDataStorage (); + ~CVfrDataStorage (); + + EFI_VFR_RETURN_CODE DeclareNameVarStoreBegin (INT8 *); + EFI_VFR_RETURN_CODE NameTableAddItem (EFI_STRING_ID); + EFI_VFR_RETURN_CODE DeclareNameVarStoreEnd (EFI_GUID *); + + EFI_VFR_RETURN_CODE DeclareEfiVarStore (IN INT8 *, IN EFI_GUID *, IN EFI_STRING_ID, IN UINT32); + + EFI_VFR_RETURN_CODE DeclareBufferVarStore (IN INT8 *, IN EFI_GUID *, IN CVfrVarDataTypeDB *, IN INT8 *, IN EFI_VARSTORE_ID); + + EFI_VFR_RETURN_CODE GetVarStoreId (IN INT8 *, OUT EFI_VARSTORE_ID *); + EFI_VFR_RETURN_CODE GetVarStoreType (IN INT8 *, OUT EFI_VFR_VARSTORE_TYPE &); + EFI_VFR_RETURN_CODE GetVarStoreName (IN EFI_VARSTORE_ID, OUT INT8 **); + + EFI_VFR_RETURN_CODE GetBufferVarStoreDataTypeName (IN INT8 *, OUT INT8 **); + EFI_VFR_RETURN_CODE GetEfiVarStoreInfo (IN EFI_VARSTORE_INFO *); + EFI_VFR_RETURN_CODE GetNameVarStoreInfo (IN EFI_VARSTORE_INFO *, IN UINT32); + + EFI_VFR_RETURN_CODE BufferVarStoreRequestElementAdd (IN INT8 *, IN EFI_VARSTORE_INFO &); +}; + +#define EFI_QUESTION_ID_MAX 0xFFFF +#define EFI_FREE_QUESTION_ID_BITMAP_SIZE ((EFI_QUESTION_ID_MAX + 1) / EFI_BITS_PER_UINT32) +#define EFI_QUESTION_ID_INVALID 0x0 + +#define DATE_YEAR_BITMASK 0x0000FFFF +#define DATE_MONTH_BITMASK 0x00FF0000 +#define DATE_DAY_BITMASK 0xFF000000 +#define TIME_HOUR_BITMASK 0x000000FF +#define TIME_MINUTE_BITMASK 0x0000FF00 +#define TIME_SECOND_BITMASK 0x00FF0000 + +struct SVfrQuestionNode { + INT8 *mName; + INT8 *mVarIdStr; + EFI_QUESTION_ID mQuestionId; + UINT32 mBitMask; + SVfrQuestionNode *mNext; + + SVfrQuestionNode (IN INT8 *, IN INT8 *, IN UINT32 BitMask = 0); + ~SVfrQuestionNode (); +}; + +class CVfrQuestionDB { +private: + SVfrQuestionNode *mQuestionList; + UINT32 mFreeQIdBitMap[EFI_FREE_QUESTION_ID_BITMAP_SIZE]; + +private: + EFI_QUESTION_ID GetFreeQuestionId (VOID); + BOOLEAN ChekQuestionIdFree (IN EFI_QUESTION_ID); + VOID MarkQuestionIdUsed (IN EFI_QUESTION_ID); + VOID MarkQuestionIdUnused (IN EFI_QUESTION_ID); + +public: + CVfrQuestionDB (); + ~CVfrQuestionDB(); + + EFI_VFR_RETURN_CODE RegisterQuestion (IN INT8 *, IN INT8 *, IN OUT EFI_QUESTION_ID &); + VOID RegisterOldDateQuestion (IN INT8 *, IN INT8 *, IN INT8 *, IN OUT EFI_QUESTION_ID &); + VOID RegisterNewDateQuestion (IN INT8 *, IN INT8 *, IN OUT EFI_QUESTION_ID &); + VOID RegisterOldTimeQuestion (IN INT8 *, IN INT8 *, IN INT8 *, IN OUT EFI_QUESTION_ID &); + VOID RegisterNewTimeQuestion (IN INT8 *, IN INT8 *, IN OUT EFI_QUESTION_ID &); + EFI_VFR_RETURN_CODE UpdateQuestionId (IN EFI_QUESTION_ID, IN EFI_QUESTION_ID); + VOID GetQuestionId (IN INT8 *, IN INT8 *, OUT EFI_QUESTION_ID &, OUT UINT32 &); + EFI_VFR_RETURN_CODE FindQuestion (IN EFI_QUESTION_ID); + EFI_VFR_RETURN_CODE FindQuestion (IN INT8 *); + }; + +struct SVfrDefaultStoreNode { + EFI_IFR_DEFAULTSTORE *mObjBinAddr; + INT8 *mRefName; + EFI_STRING_ID mDefaultStoreNameId; + UINT16 mDefaultId; + + SVfrDefaultStoreNode *mNext; + + SVfrDefaultStoreNode (IN EFI_IFR_DEFAULTSTORE *, IN INT8 *, IN EFI_STRING_ID, IN UINT16); + ~SVfrDefaultStoreNode(); +}; + +class CVfrDefaultStore { +private: + SVfrDefaultStoreNode *mDefaultStoreList; + +public: + CVfrDefaultStore (); + ~CVfrDefaultStore (); + + EFI_VFR_RETURN_CODE RegisterDefaultStore (IN CHAR8 *, IN INT8 *, IN EFI_STRING_ID, IN UINT16); + EFI_VFR_RETURN_CODE ReRegisterDefaultStoreById (IN UINT16, IN INT8 *, IN EFI_STRING_ID); + BOOLEAN DefaultIdRegistered (IN UINT16); + EFI_VFR_RETURN_CODE GetDefaultId (IN INT8 *, OUT UINT16 *); + EFI_VFR_RETURN_CODE BufferVarStoreAltConfigAdd (IN EFI_VARSTORE_ID, IN EFI_VARSTORE_INFO &, IN INT8 *, IN UINT8, IN EFI_IFR_TYPE_VALUE); +}; + +#define EFI_RULE_ID_START 0x01 +#define EFI_RULE_ID_INVALID 0x00 + +struct SVfrRuleNode { + UINT8 mRuleId; + INT8 *mRuleName; + SVfrRuleNode *mNext; + + SVfrRuleNode(IN INT8 *, IN UINT8); + ~SVfrRuleNode(); +}; + +class CVfrRulesDB { +private: + SVfrRuleNode *mRuleList; + UINT8 mFreeRuleId; + +public: + CVfrRulesDB (); + ~CVfrRulesDB(); + + VOID RegisterRule (IN INT8 *); + UINT8 GetRuleId (IN INT8 *); +}; + +#define MIN(v1, v2) (((v1) < (v2)) ? (v1) : (v2)) +#define MAX(v1, v2) (((v1) > (v2)) ? (v1) : (v2)) + +#endif diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/makefile b/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/makefile new file mode 100644 index 0000000000..61fd9e4641 --- /dev/null +++ b/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/makefile @@ -0,0 +1,149 @@ +#/*++ +# +# Copyright (c) 2004 - 2007, Intel Corporation +# All rights reserved. This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# Module Name: +# +# makefile +# +# Abstract: +# +# Makefile for building the EFI VFR compiler +# +#--*/ + + +!IFNDEF EDK_SOURCE +!ERROR EDK_SOURCE environmental variable not set +!ENDIF + +!IFNDEF TOOLCHAIN +TOOLCHAIN = TOOLCHAIN_MSVC +!ENDIF + +!INCLUDE $(BUILD_DIR)\PlatformTools.env + +.SUFFIXES : + +TARGET_NAME = VfrCompile + +ETO = $(EDK_TOOLS_OUTPUT) +SRC = $(EDK_TOOLS_SOURCE)\Uefi$(TARGET_NAME) +TARGET_EXE = $(ETO)\$(TARGET_NAME).exe + + + +INC = -I $(SRC) \ + -I $(EDK_SOURCE)\Foundation\Include\Ia32 \ + -I $(EDK_SOURCE)\Foundation\Efi\Include \ + -I $(EDK_SOURCE)\Foundation\Framework\Include \ + -I $(EDK_SOURCE)\Foundation\Include\IndustryStandard \ + -I $(EDK_SOURCE)\Foundation\ \ + -I $(EDK_SOURCE)\Foundation\Core\Dxe \ + -I $(EDK_SOURCE)\Foundation\Efi \ + -I $(EDK_SOURCE)\Foundation\Framework \ + -I $(EDK_TOOLS_SOURCE)\Common \ + -I $(EDK_SOURCE)\Foundation\Include + +ANTLR_FLAGS = -CC -e3 -ck 3 -k 2 +DLG_FLAGS = -C2 -i -CC +LINK_FLAGS_PCCTS = /DEBUG /PDB:$*.pdb +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 + +VFR_GRAMMER_FILE = $(SRC)\VfrSyntax.g + +VFR_ANTLR_SPAWN = $(ETO)\VfrSyntax.cpp \ + $(ETO)\EfiVfrParser.cpp \ + $(ETO)\EfiVfrParser.h \ + $(ETO)\VfrParser.dlg \ + $(ETO)\VfrTokens.h + +VFR_DLG_SPAWN = $(ETO)\VfrLexer.cpp \ + $(ETO)\VfrLexer.h + +ANTLR_H = $(PCCTS_DIR)\h + +HEADER_FILES = $(SRC)\VfrFormPkg.h \ + $(SRC)\EfiVfr.h \ + $(SRC)\VfrCompiler.h \ + $(SRC)\VfrError.h \ + $(SRC)\VfrUtilityLib.h + +OBJECTS = $(ETO)\AParser.obj \ + $(ETO)\DLexerBase.obj \ + $(ETO)\ATokenBuffer.obj \ + $(ETO)\VfrSyntax.obj \ + $(ETO)\EfiVfrParser.obj \ + $(ETO)\VfrLexer.obj \ + $(ETO)\VfrFormPkg.obj \ + $(ETO)\VfrError.obj \ + $(ETO)\VfrUtilityLib.obj \ + $(ETO)\VfrCompiler.obj + +all : $(TARGET_EXE) + +$(VFR_ANTLR_SPAWN) : $(VFR_GRAMMER_FILE) + $(ANTLR) $(ANTLR_FLAGS) -fl VfrParser.dlg -ft VfrTokens.h -o $(ETO) $(VFR_GRAMMER_FILE) + +$(VFR_DLG_SPAWN) : $(ETO)\VfrParser.dlg + $(DLG) $(DLG_FLAGS) -cl VfrLexer -o $(ETO) $(ETO)\VfrParser.dlg + +$(ETO)\VfrSyntax.obj : $(ETO)\VfrSyntax.cpp $(VFR_DLG_SPAWN) + $(CC) -c $(C_FLAGS_PCCTS) /Fo$@ $(INC) $(ETO)\VfrSyntax.cpp + +$(ETO)\EfiVfrParser.obj : $(ETO)\EfiVfrParser.cpp $(ETO)\EfiVfrParser.h $(VFR_DLG_SPAWN) + $(CC) -c $(C_FLAGS_PCCTS) /Fo$@ $(INC) $(ETO)\EfiVfrParser.cpp + + +$(ETO)\AParser.obj : $(ANTLR_H)\AParser.cpp + $(CC) -c $(C_FLAGS_PCCTS) /Fo$@ $(ANTLR_H)\AParser.cpp + +$(ETO)\ATokenBuffer.obj : $(ANTLR_H)\ATokenBuffer.cpp + $(CC) -c $(C_FLAGS_PCCTS) /Fo$@ $(ANTLR_H)\ATokenBuffer.cpp + +$(ETO)\DLexerBase.obj : $(ANTLR_H)\DLexerBase.cpp + $(CC) -c $(C_FLAGS_PCCTS) /Fo$@ $(ANTLR_H)\DLexerBase.cpp + +$(ETO)\VfrLexer.obj : $(ETO)\VfrLexer.cpp $(VFR_DLG_SPAWN) + $(CC) -c $(C_FLAGS_PCCTS) /Fo$@ $(INC) $(ETO)\VfrLexer.cpp + +$(ETO)\VfrFormPkg.obj : $(SRC)\VfrFormPkg.cpp $(HEADER_FILES) + $(CC) -c $(C_FLAGS_PCCTS) $(INC) /Fo$@ $(SRC)\VfrFormPkg.cpp + +$(ETO)\VfrError.obj : $(SRC)\VfrError.cpp $(HEADER_FILES) + $(CC) -c $(C_FLAGS_PCCTS) $(INC) /Fo$@ $(SRC)\VfrError.cpp + +$(ETO)\VfrUtilityLib.obj : $(SRC)\VfrUtilityLib.cpp $(HEADER_FILES) + $(CC) -c $(C_FLAGS_PCCTS) $(INC) /Fo$@ $(SRC)\VfrUtilityLib.cpp + +$(ETO)\VfrCompiler.obj : $(SRC)\VfrCompiler.cpp $(HEADER_FILES) + $(CC) -c $(C_FLAGS_PCCTS) $(INC) /Fo$@ $(SRC)\VfrCompiler.cpp + +# +# Add Binary Build description for this tools. +# + +!IF (("$(EFI_BINARY_TOOLS)" == "YES") && EXIST($(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe)) +$(TARGET_EXE): $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe + copy $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe $(TARGET_EXE) /Y + if exist $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb \ + copy $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb /Y +!ELSE +$(TARGET_EXE) : $(OBJECTS) $(HEADER_FILES) + $(LINK) $(MSVS_LINK_LIBPATHS) $(LINK_FLAGS_PCCTS) /OUT:$(TARGET_EXE) $(OBJECTS) +!IF ("$(EFI_BINARY_BUILD)" == "YES") + if not exist $(EFI_PLATFORM_BIN)\Tools mkdir $(EFI_PLATFORM_BIN)\Tools + if exist $(TARGET_EXE) copy $(TARGET_EXE) $(EFI_PLATFORM_BIN)\tools\$(TARGET_NAME).exe /Y + if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb \ + copy $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb /Y +!ENDIF +!ENDIF + +clean: diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/VcCheck/makefile b/EdkCompatibilityPkg/Sample/Tools/Source/VcCheck/makefile index d0a680c978..45d6690869 100644 --- a/EdkCompatibilityPkg/Sample/Tools/Source/VcCheck/makefile +++ b/EdkCompatibilityPkg/Sample/Tools/Source/VcCheck/makefile @@ -82,11 +82,13 @@ $(TARGET_EXE): $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe !ELSE $(TARGET_EXE) : $(OBJECTS) $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(OBJECTS) +!IF ("$(EFI_BINARY_BUILD)" == "YES") if not exist $(EFI_PLATFORM_BIN)\Tools mkdir $(EFI_PLATFORM_BIN)\Tools if exist $(TARGET_EXE) copy $(TARGET_EXE) $(EFI_PLATFORM_BIN)\tools\$(TARGET_NAME).exe /Y if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb \ copy $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb /Y !ENDIF +!ENDIF clean: @if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/VfrCompile/makefile b/EdkCompatibilityPkg/Sample/Tools/Source/VfrCompile/makefile index d703b02f31..f0b7db9fa0 100644 --- a/EdkCompatibilityPkg/Sample/Tools/Source/VfrCompile/makefile +++ b/EdkCompatibilityPkg/Sample/Tools/Source/VfrCompile/makefile @@ -162,11 +162,13 @@ $(TARGET_EXE): $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe !ELSE $(TARGET_EXE) : $(OBJECTS) $(LIBS) $(LINK) $(MSVS_LINK_LIBPATHS) $(LIBS) /DEBUG /OUT:$(TARGET_EXE) $(LINK_FLAGS_PCCTS) $(OBJECTS) /PDB:$*.pdb +!IF ("$(EFI_BINARY_BUILD)" == "YES") if not exist $(EFI_PLATFORM_BIN)\Tools mkdir $(EFI_PLATFORM_BIN)\Tools if exist $(TARGET_EXE) copy $(TARGET_EXE) $(EFI_PLATFORM_BIN)\tools\$(TARGET_NAME).exe /Y if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb \ copy $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb /Y !ENDIF +!ENDIF clean: -- 2.39.2