diff --git a/BaseTools/BinWrappers/PosixLike/ProductDataFormatter b/BaseTools/BinWrappers/PosixLike/ProductDataFormatter new file mode 100644 index 00000000000..b088bd63e0e --- /dev/null +++ b/BaseTools/BinWrappers/PosixLike/ProductDataFormatter @@ -0,0 +1,14 @@ +#!/usr/bin/env bash +#python `dirname $0`/RunToolFromSource.py `basename $0` $* + +# If a ${PYTHON_COMMAND} command is available, use it in preference to python +if command -v ${PYTHON_COMMAND} >/dev/null 2>&1; then + python_exe=${PYTHON_COMMAND} +fi + +full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here +dir=$(dirname "$full_cmd") +exe=$(basename "$full_cmd") + +export PYTHONPATH="$dir/../../Source/Python${PYTHONPATH:+:"$PYTHONPATH"}" +exec "${python_exe:-python}" "$dir/../../Source/Python/$exe/$exe.py" "$@" \ No newline at end of file diff --git a/BaseTools/BinWrappers/WindowsLike/ProductDataFormatter.bat b/BaseTools/BinWrappers/WindowsLike/ProductDataFormatter.bat new file mode 100644 index 00000000000..9616cd893be --- /dev/null +++ b/BaseTools/BinWrappers/WindowsLike/ProductDataFormatter.bat @@ -0,0 +1,3 @@ +@setlocal +@set ToolName=%~n0% +@%PYTHON_COMMAND% %BASE_TOOLS_PATH%\Source\Python\%ToolName%\%ToolName%.py %* diff --git a/BaseTools/Conf/build_rule.template b/BaseTools/Conf/build_rule.template index 03ece19486a..ad3319387cc 100755 --- a/BaseTools/Conf/build_rule.template +++ b/BaseTools/Conf/build_rule.template @@ -112,8 +112,11 @@ # 1.01 - Add MASM for Microsoft ARM assembly files. "MS-ARMx-Assembly-Code-File.COMMON.COMMON" # 2.00 - Add .slib and .efi support in the sources file # 2.01 - Add support for DEPS_FLAGS as well as +# 2.23 - Add OemData Definitions +# 2.24 - Add .arc and .ver file type to add .rsrc sections to EFI images. +# 2.25 - Split OemData rule into intermediate binary and final binary rules. -#!VERSION=2.01 +#!VERSION=2.25 [C-Code-File] @@ -546,6 +549,43 @@ "$(MTOC)" -subsystem $(MODULE_TYPE) $(MTOC_FLAGS) $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.dll $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.pecoff "$(GENFW)" -o ${dst} -c $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.pecoff $(GENFW_FLAGS) +# MU_CHANGE BEGIN +[C-Code-File-OemDataIntermediate] + + ?.productdatac + + + $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.productdatabin.i + + + $(MAKE_FILE) + + + "$(CC)" /Fo$(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj $(DEPS_FLAGS) /nologo /c /FIAutoGen.h /TC /Dmain=main $(INC) ${src} + "$(DLINK)" /OUT:$(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.dll /NODEFAULTLIB /ENTRY:main /SUBSYSTEM:CONSOLE $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj + "$(GENFW)" -o $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.productdatabin.i -b $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.dll $(GENFW_FLAGS) + + + "$(CC)" $(DEPS_FLAGS) -c -o $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj $(CC_FLAGS) -fno-toplevel-reorder -x c $(DEPS_FLAGS) $(INC) ${src} + "$(DLINK)" -o $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.dll $(DLINK_COMMON) -u $(IMAGE_ENTRY_POINT) $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj $(CC_FLAGS) + "$(GENFW)" -o $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.productdatabin.i -b $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.dll $(GENFW_FLAGS) + + + "$(CC)" $(DEPS_FLAGS) -c -o $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj -O0 -fkeep-static-consts --language=c $(DEPS_FLAGS) $(INC) ${src} + "$(DLINK)" /OUT:$(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.dll /NODEFAULTLIB /ENTRY:main /SUBSYSTEM:CONSOLE $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj + "$(GENFW)" -o $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.productdatabin.i -b $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.dll $(GENFW_FLAGS) + +[ProductDataIntermediate-to-ProductDataBin] + + ?.productdatabin.i + + + $(OUTPUT_DIR)(+)${s_dir}(+)$(MODULE_NAME).productdatabin + + + ProductDataFormatter $(OUTPUT_DIR)(+)${s_dir} $(OUTPUT_DIR)(+)${s_dir}(+)$(MODULE_NAME).productdatabin + +# MU_CHANGE END [Masm16-Code-File] diff --git a/BaseTools/Source/Python/ProductDataFormatter/ProductDataFormatter.py b/BaseTools/Source/Python/ProductDataFormatter/ProductDataFormatter.py new file mode 100644 index 00000000000..53788c36d5d --- /dev/null +++ b/BaseTools/Source/Python/ProductDataFormatter/ProductDataFormatter.py @@ -0,0 +1,119 @@ +# @file +# +# Formats a collection of intermediate product data binary files +# in a given directory into a single product binary file +# +# Copyright (C) Microsoft Corporation. All rights reserved. +# +## + +import glob +import io +import os +import struct +from collections import namedtuple +from pathlib import Path + +class ProductDataFormatter: + STRUCT_SIGNATURE = b"__SDSH__" + ITEM_SIGNATURE = b"_SDDATA_" + PRODUCT_ID = b"__MSFT__" + + def __init__(self, directory_path): + if not os.path.isdir(directory_path): + raise NotADirectoryError( + f"{directory_path} is an invalid directory!") + + self._directory_path = Path(directory_path) + + def _get_bins(self): + return self._directory_path.rglob('*.productdatabin.i') + + def _get_signed_item(self, file_path): + with open(file_path, 'rb') as bin_file: + bin_data = bytearray(bin_file.read()) + + signed_item_pos = 0 + while True: + signed_item_pos = bin_data.find( + self.ITEM_SIGNATURE, signed_item_pos) + + if signed_item_pos == -1: + return + + ItemHeader = namedtuple('ItemHeader', 'sig header_len id len') + + item_header = ItemHeader._make(struct.unpack_from( + '