+// Locate a single tool from the specified Locations using one of the
+// specified Names and add it to the menu.
+static VOID FindTool(CHAR16 *Locations, CHAR16 *Names, CHAR16 *Description, UINTN Icon) {
+ UINTN j = 0, k, VolumeIndex;
+ CHAR16 *DirName, *FileName, *PathName, FullDescription[256];
+
+ while ((DirName = FindCommaDelimited(Locations, j++)) != NULL) {
+ k = 0;
+ while ((FileName = FindCommaDelimited(Names, k++)) != NULL) {
+ PathName = StrDuplicate(DirName);
+ MergeStrings(&PathName, FileName, (StriCmp(PathName, L"\\") == 0) ? 0 : L'\\');
+ for (VolumeIndex = 0; VolumeIndex < VolumesCount; VolumeIndex++) {
+ if ((Volumes[VolumeIndex]->RootDir != NULL) && (FileExists(Volumes[VolumeIndex]->RootDir, PathName))) {
+ SPrint(FullDescription, 255, L"%s at %s on %s", Description, PathName, Volumes[VolumeIndex]->VolName);
+ AddToolEntry(Volumes[VolumeIndex]->DeviceHandle, PathName, FullDescription, BuiltinIcon(Icon), 'S', FALSE);
+ } // if
+ } // for
+ MyFreePool(PathName);
+ MyFreePool(FileName);
+ } // while Names
+ MyFreePool(DirName);
+ } // while Locations
+} // VOID FindTool()
+
+// Add the second-row tags containing built-in and external tools (EFI shell,
+// reboot, etc.)
+static VOID ScanForTools(VOID) {
+ CHAR16 *FileName = NULL, *VolName = NULL, *MokLocations, Description[256];
+ REFIT_MENU_ENTRY *TempMenuEntry;
+ UINTN i, j, VolumeIndex;
+ UINT64 osind;
+ CHAR8 *b = 0;
+
+ MokLocations = StrDuplicate(MOK_LOCATIONS);
+ if (MokLocations != NULL)
+ MergeStrings(&MokLocations, SelfDirPath, L',');
+
+ for (i = 0; i < NUM_TOOLS; i++) {
+ switch(GlobalConfig.ShowTools[i]) {
+ // NOTE: Be sure that FileName is NULL at the end of each case.
+ case TAG_SHUTDOWN:
+ TempMenuEntry = CopyMenuEntry(&MenuEntryShutdown);
+ TempMenuEntry->Image = BuiltinIcon(BUILTIN_ICON_FUNC_SHUTDOWN);
+ AddMenuEntry(&MainMenu, TempMenuEntry);
+ break;
+
+ case TAG_REBOOT:
+ TempMenuEntry = CopyMenuEntry(&MenuEntryReset);
+ TempMenuEntry->Image = BuiltinIcon(BUILTIN_ICON_FUNC_RESET);
+ AddMenuEntry(&MainMenu, TempMenuEntry);
+ break;
+
+ case TAG_ABOUT:
+ TempMenuEntry = CopyMenuEntry(&MenuEntryAbout);
+ TempMenuEntry->Image = BuiltinIcon(BUILTIN_ICON_FUNC_ABOUT);
+ AddMenuEntry(&MainMenu, TempMenuEntry);
+ break;
+
+ case TAG_EXIT:
+ TempMenuEntry = CopyMenuEntry(&MenuEntryExit);
+ TempMenuEntry->Image = BuiltinIcon(BUILTIN_ICON_FUNC_EXIT);
+ AddMenuEntry(&MainMenu, TempMenuEntry);
+ break;
+
+ case TAG_FIRMWARE:
+ if (EfivarGetRaw(&GlobalGuid, L"OsIndicationsSupported", &b, &j) == EFI_SUCCESS) {
+ osind = (UINT64)*b;
+ if (osind & EFI_OS_INDICATIONS_BOOT_TO_FW_UI) {
+ TempMenuEntry = CopyMenuEntry(&MenuEntryFirmware);
+ TempMenuEntry->Image = BuiltinIcon(BUILTIN_ICON_FUNC_FIRMWARE);
+ AddMenuEntry(&MainMenu, TempMenuEntry);
+ } // if
+ } // if
+ break;
+
+ case TAG_SHELL:
+ j = 0;
+ while ((FileName = FindCommaDelimited(SHELL_NAMES, j++)) != NULL) {
+ if (FileExists(SelfRootDir, FileName)) {
+ AddToolEntry(SelfLoadedImage->DeviceHandle, FileName, L"EFI Shell", BuiltinIcon(BUILTIN_ICON_TOOL_SHELL),
+ 'S', FALSE);
+ }
+ MyFreePool(FileName);
+ } // while
+ break;
+
+ case TAG_GPTSYNC:
+ j = 0;
+ while ((FileName = FindCommaDelimited(GPTSYNC_NAMES, j++)) != NULL) {
+ if (FileExists(SelfRootDir, FileName)) {
+ AddToolEntry(SelfLoadedImage->DeviceHandle, FileName, L"Hybrid MBR tool", BuiltinIcon(BUILTIN_ICON_TOOL_PART),
+ 'P', FALSE);
+ } // if
+ MyFreePool(FileName);
+ } // while
+ FileName = NULL;
+ break;
+
+ case TAG_GDISK:
+ j = 0;
+ while ((FileName = FindCommaDelimited(GDISK_NAMES, j++)) != NULL) {
+ if (FileExists(SelfRootDir, FileName)) {
+ AddToolEntry(SelfLoadedImage->DeviceHandle, FileName, L"disk partitioning tool",
+ BuiltinIcon(BUILTIN_ICON_TOOL_PART), 'G', FALSE);
+ } // if
+ MyFreePool(FileName);
+ } // while
+ FileName = NULL;
+ break;
+
+ case TAG_NETBOOT:
+ j = 0;
+ while ((FileName = FindCommaDelimited(NETBOOT_NAMES, j++)) != NULL) {
+ if (FileExists(SelfRootDir, FileName)) {
+ AddToolEntry(SelfLoadedImage->DeviceHandle, FileName, L"Netboot",
+ BuiltinIcon(BUILTIN_ICON_TOOL_NETBOOT), 'N', FALSE);
+ } // if
+ MyFreePool(FileName);
+ } // while
+ FileName = NULL;
+ break;
+
+ case TAG_APPLE_RECOVERY:
+ FileName = StrDuplicate(L"\\com.apple.recovery.boot\\boot.efi");
+ for (VolumeIndex = 0; VolumeIndex < VolumesCount; VolumeIndex++) {
+ if ((Volumes[VolumeIndex]->RootDir != NULL) && (FileExists(Volumes[VolumeIndex]->RootDir, FileName))) {
+ SPrint(Description, 255, L"Apple Recovery on %s", Volumes[VolumeIndex]->VolName);
+ AddToolEntry(Volumes[VolumeIndex]->DeviceHandle, FileName, Description,
+ BuiltinIcon(BUILTIN_ICON_TOOL_APPLE_RESCUE), 'R', TRUE);
+ } // if
+ } // for
+ MyFreePool(FileName);
+ FileName = NULL;
+ break;
+
+ case TAG_WINDOWS_RECOVERY:
+ j = 0;
+ while ((FileName = FindCommaDelimited(GlobalConfig.WindowsRecoveryFiles, j++)) != NULL) {
+ SplitVolumeAndFilename(&FileName, &VolName);
+ for (VolumeIndex = 0; VolumeIndex < VolumesCount; VolumeIndex++) {
+ if ((Volumes[VolumeIndex]->RootDir != NULL) && (FileExists(Volumes[VolumeIndex]->RootDir, FileName)) &&
+ ((VolName == NULL) || (StriCmp(VolName, Volumes[VolumeIndex]->VolName) == 0))) {
+ SPrint(Description, 255, L"Microsoft Recovery on %s", Volumes[VolumeIndex]->VolName);
+ AddToolEntry(Volumes[VolumeIndex]->DeviceHandle, FileName, Description,
+ BuiltinIcon(BUILTIN_ICON_TOOL_WINDOWS_RESCUE), 'R', TRUE);
+ } // if
+ } // for
+ } // while
+ MyFreePool(FileName);
+ FileName = NULL;
+ MyFreePool(VolName);
+ VolName = NULL;
+ break;
+
+ case TAG_MOK_TOOL:
+ FindTool(MokLocations, MOK_NAMES, L"MOK utility", BUILTIN_ICON_TOOL_MOK_TOOL);
+ break;
+
+ case TAG_MEMTEST:
+ FindTool(MEMTEST_LOCATIONS, MEMTEST_NAMES, L"Memory test utility", BUILTIN_ICON_TOOL_MEMTEST);
+ break;
+
+ } // switch()
+ } // for
+} // static VOID ScanForTools
+
+// Rescan for boot loaders
+static VOID RescanAll(BOOLEAN DisplayMessage) {
+ EG_PIXEL BGColor;
+
+ BGColor.b = 255;
+ BGColor.g = 175;
+ BGColor.r = 100;
+ BGColor.a = 0;
+ if (DisplayMessage)
+ egDisplayMessage(L"Scanning for new boot loaders; please wait....", &BGColor);
+ FreeList((VOID ***) &(MainMenu.Entries), &MainMenu.EntryCount);
+ MainMenu.Entries = NULL;
+ MainMenu.EntryCount = 0;
+ ReadConfig(GlobalConfig.ConfigFilename);
+ ConnectAllDriversToAllControllers();
+ ScanVolumes();
+ ScanForBootloaders();
+ ScanForTools();
+ SetupScreen();
+} // VOID RescanAll()
+
+#ifdef __MAKEWITH_TIANO
+
+// Minimal initialization function
+static VOID InitializeLib(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable) {
+ gST = SystemTable;
+ // gImageHandle = ImageHandle;
+ gBS = SystemTable->BootServices;
+ // gRS = SystemTable->RuntimeServices;
+ gRT = SystemTable->RuntimeServices; // Some BDS functions need gRT to be set
+ EfiGetSystemConfigurationTable (&gEfiDxeServicesTableGuid, (VOID **) &gDS);
+
+// InitializeConsoleSim();
+}
+
+#endif
+
+// Set up our own Secure Boot extensions....
+// Returns TRUE on success, FALSE otherwise
+static BOOLEAN SecureBootSetup(VOID) {
+ EFI_STATUS Status;
+ BOOLEAN Success = FALSE;
+
+ if (secure_mode() && ShimLoaded()) {
+ Status = security_policy_install();
+ if (Status == EFI_SUCCESS) {
+ Success = TRUE;
+ } else {
+ Print(L"Failed to install MOK Secure Boot extensions");
+ }
+ }
+ return Success;
+} // VOID SecureBootSetup()
+
+// Remove our own Secure Boot extensions....
+// Returns TRUE on success, FALSE otherwise
+static BOOLEAN SecureBootUninstall(VOID) {
+ EFI_STATUS Status;
+ BOOLEAN Success = TRUE;
+
+ if (secure_mode()) {
+ Status = security_policy_uninstall();
+ if (Status != EFI_SUCCESS) {
+ Success = FALSE;
+ BeginTextScreen(L"Secure Boot Policy Failure");
+ Print(L"Failed to uninstall MOK Secure Boot extensions; forcing a reboot.");
+ PauseForKey();
+ refit_call4_wrapper(RT->ResetSystem, EfiResetCold, EFI_SUCCESS, 0, NULL);
+ }
+ }
+ return Success;
+} // VOID SecureBootUninstall
+
+// Sets the global configuration filename; will be CONFIG_FILE_NAME unless the
+// "-c" command-line option is set, in which case that takes precedence.
+// If an error is encountered, leaves the value alone (it should be set to
+// CONFIG_FILE_NAME when GlobalConfig is initialized).
+static VOID SetConfigFilename(EFI_HANDLE ImageHandle) {
+ EFI_LOADED_IMAGE *Info;
+ CHAR16 *Options, *FileName;
+ EFI_STATUS Status;
+ INTN Where;
+
+ Status = refit_call3_wrapper(BS->HandleProtocol, ImageHandle, &LoadedImageProtocol, (VOID **) &Info);
+ if ((Status == EFI_SUCCESS) && (Info->LoadOptionsSize > 0)) {
+ Options = (CHAR16 *) Info->LoadOptions;
+ Where = FindSubString(L" -c ", Options);
+ if (Where >= 0) {
+ FileName = StrDuplicate(&Options[Where + 4]);
+ Where = FindSubString(L" ", FileName);
+ if (Where > 0)
+ FileName[Where] = L'\0';
+
+ if (FileExists(SelfDir, FileName)) {
+ GlobalConfig.ConfigFilename = FileName;
+ } else {
+ Print(L"Specified configuration file (%s) doesn't exist; using\n'refind.conf' default\n", FileName);
+ MyFreePool(FileName);
+ } // if/else
+ } // if
+ } // if
+} // VOID SetConfigFilename()
+