status_t user_menu(Directory** _bootVolume) { Menu* menu = new(std::nothrow) Menu(MAIN_MENU); Menu* safeModeMenu = NULL; Menu* debugMenu = NULL; MenuItem* item; TRACE(("user_menu: enter\n")); // Add boot volume menu->AddItem(item = new(std::nothrow) MenuItem("Select boot volume", add_boot_volume_menu(*_bootVolume))); // Add safe mode menu->AddItem(item = new(std::nothrow) MenuItem("Select safe mode options", safeModeMenu = add_safe_mode_menu())); // add debug menu menu->AddItem(item = new(std::nothrow) MenuItem("Select debug options", debugMenu = add_debug_menu())); // Add platform dependent menus platform_add_menus(menu); menu->AddSeparatorItem(); menu->AddItem(item = new(std::nothrow) MenuItem("Reboot")); item->SetTarget(user_menu_reboot); item->SetShortcut('r'); menu->AddItem(item = new(std::nothrow) MenuItem("Continue booting")); if (*_bootVolume == NULL) { item->SetEnabled(false); menu->ItemAt(0)->Select(true); } else item->SetShortcut('b'); menu->Run(); // See if a new boot device has been selected, and propagate that back if (item->Data() != NULL) *_bootVolume = (Directory*)item->Data(); apply_safe_mode_options(safeModeMenu); apply_safe_mode_options(debugMenu); delete menu; TRACE(("user_menu: leave\n")); return B_OK; }
static void apply_safe_mode_options(Menu *menu) { MenuItemIterator iterator = menu->ItemIterator(); MenuItem *item; char buffer[2048]; int32 pos = 0; buffer[0] = '\0'; while ((item = iterator.Next()) != NULL) { if (item->Type() == MENU_ITEM_SEPARATOR || !item->IsMarked() || item->Data() == NULL || (uint32)pos > sizeof(buffer)) continue; size_t totalBytes = snprintf(buffer + pos, sizeof(buffer) - pos, "%s true\n", (const char *)item->Data()); pos += std::min(totalBytes, sizeof(buffer) - pos - 1); } add_safe_mode_settings(buffer); }