**/\r
\r
#include <Library/DebugLib.h>\r
+#include <Library/DevicePathLib.h>\r
+#include <Library/HiiLib.h>\r
#include <Library/UefiBootServicesTableLib.h>\r
+#include <Protocol/DevicePath.h>\r
+#include <Protocol/HiiConfigAccess.h>\r
\r
#include "PlatformConfig.h"\r
\r
+//\r
+// The HiiAddPackages() library function requires that any controller (or\r
+// image) handle, to be associated with the HII packages under installation, be\r
+// "decorated" with a device path. The tradition seems to be a vendor device\r
+// path.\r
+//\r
+// We'd like to associate our HII packages with the driver's image handle. The\r
+// first idea is to use the driver image's device path. Unfortunately, loaded\r
+// images only come with an EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL (not the\r
+// usual EFI_DEVICE_PATH_PROTOCOL), ie. a different GUID. In addition, even the\r
+// EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL interface may be NULL, if the image\r
+// has been loaded from an "unnamed" memory source buffer.\r
+//\r
+// Hence let's just stick with the tradition -- use a dedicated vendor device\r
+// path, with the driver's FILE_GUID.\r
+//\r
+#pragma pack(1)\r
+typedef struct {\r
+ VENDOR_DEVICE_PATH VendorDevicePath;\r
+ EFI_DEVICE_PATH_PROTOCOL End;\r
+} PKG_DEVICE_PATH;\r
+#pragma pack()\r
+\r
+STATIC PKG_DEVICE_PATH mPkgDevicePath = {\r
+ {\r
+ {\r
+ HARDWARE_DEVICE_PATH,\r
+ HW_VENDOR_DP,\r
+ {\r
+ (UINT8) (sizeof (VENDOR_DEVICE_PATH) ),\r
+ (UINT8) (sizeof (VENDOR_DEVICE_PATH) >> 8)\r
+ }\r
+ },\r
+ EFI_CALLER_ID_GUID\r
+ },\r
+ {\r
+ END_DEVICE_PATH_TYPE,\r
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
+ {\r
+ (UINT8) (END_DEVICE_PATH_LENGTH ),\r
+ (UINT8) (END_DEVICE_PATH_LENGTH >> 8)\r
+ }\r
+ }\r
+};\r
+\r
+//\r
+// The configuration interface between the HII engine (form display etc) and\r
+// this driver.\r
+//\r
+STATIC EFI_HII_CONFIG_ACCESS_PROTOCOL mConfigAccess;\r
+\r
+//\r
+// The handle representing our list of packages after installation.\r
+//\r
+STATIC EFI_HII_HANDLE mInstalledPackages;\r
+\r
+//\r
+// The arrays below constitute our HII package list. They are auto-generated by\r
+// the VFR compiler and linked into the driver image during the build.\r
+//\r
+// - The strings package receives its C identifier from the driver's BASE_NAME,\r
+// plus "Strings".\r
+//\r
+// - The forms package receives its C identifier from the VFR file's basename,\r
+// plus "Bin".\r
+//\r
+//\r
+extern UINT8 PlatformDxeStrings[];\r
+extern UINT8 PlatformFormsBin[];\r
+\r
+\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+ExtractConfig (\r
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
+ IN CONST EFI_STRING Request,\r
+ OUT EFI_STRING *Progress,\r
+ OUT EFI_STRING *Results\r
+)\r
+{\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+RouteConfig (\r
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
+ IN CONST EFI_STRING Configuration,\r
+ OUT EFI_STRING *Progress\r
+)\r
+{\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+Callback (\r
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
+ IN EFI_BROWSER_ACTION Action,\r
+ IN EFI_QUESTION_ID QuestionId,\r
+ IN UINT8 Type,\r
+ IN OUT EFI_IFR_TYPE_VALUE *Value,\r
+ OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
+ )\r
+{\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
/**\r
Load and execute the platform configuration.\r
\r
@param[in] SystemTable Pointer to SystemTable.\r
\r
@retval EFI_SUCESS Driver has loaded successfully.\r
+ @retval EFI_OUT_OF_RESOURCES Failed to install HII packages.\r
+ @return Error codes from lower level functions.\r
\r
**/\r
EFI_STATUS\r
IN EFI_SYSTEM_TABLE *SystemTable\r
)\r
{\r
+ EFI_STATUS Status;\r
+\r
ExecutePlatformConfig ();\r
+\r
+ mConfigAccess.ExtractConfig = &ExtractConfig;\r
+ mConfigAccess.RouteConfig = &RouteConfig;\r
+ mConfigAccess.Callback = &Callback;\r
+\r
+ //\r
+ // Declare ourselves suitable for HII communication.\r
+ //\r
+ Status = gBS->InstallMultipleProtocolInterfaces (&ImageHandle,\r
+ &gEfiDevicePathProtocolGuid, &mPkgDevicePath,\r
+ &gEfiHiiConfigAccessProtocolGuid, &mConfigAccess,\r
+ NULL);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Publish the HII package list to HII Database.\r
+ //\r
+ mInstalledPackages = HiiAddPackages (\r
+ &gEfiCallerIdGuid, // PackageListGuid\r
+ ImageHandle, // associated DeviceHandle\r
+ PlatformDxeStrings, // 1st package\r
+ PlatformFormsBin, // 2nd package\r
+ NULL // terminator\r
+ );\r
+ if (mInstalledPackages == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto UninstallProtocols;\r
+ }\r
+\r
return EFI_SUCCESS;\r
+\r
+UninstallProtocols:\r
+ gBS->UninstallMultipleProtocolInterfaces (ImageHandle,\r
+ &gEfiDevicePathProtocolGuid, &mPkgDevicePath,\r
+ &gEfiHiiConfigAccessProtocolGuid, &mConfigAccess,\r
+ NULL);\r
+ return Status;\r
}\r
\r
/**\r
IN EFI_HANDLE ImageHandle\r
)\r
{\r
+ HiiRemovePackages (mInstalledPackages);\r
+ gBS->UninstallMultipleProtocolInterfaces (ImageHandle,\r
+ &gEfiDevicePathProtocolGuid, &mPkgDevicePath,\r
+ &gEfiHiiConfigAccessProtocolGuid, &mConfigAccess,\r
+ NULL);\r
return EFI_SUCCESS;\r
}\r