Serenity Operating System
at master 90 lines 3.6 kB view raw
1/* 2 * Copyright (c) 2022, Samuel Bowman <sam@sambowman.tech> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <Applications/PartitionEditor/PartitionEditorWindowGML.h> 8#include <Applications/PartitionEditor/PartitionModel.h> 9#include <LibCore/DeprecatedFile.h> 10#include <LibCore/Directory.h> 11#include <LibCore/System.h> 12#include <LibGUI/Application.h> 13#include <LibGUI/ComboBox.h> 14#include <LibGUI/ItemListModel.h> 15#include <LibGUI/Menu.h> 16#include <LibGUI/MessageBox.h> 17#include <LibGUI/TableView.h> 18#include <unistd.h> 19 20static Vector<DeprecatedString> get_device_paths() 21{ 22 auto device_paths = Vector<DeprecatedString>(); 23 // FIXME: Propagate errors. 24 (void)Core::Directory::for_each_entry("/dev"sv, Core::DirIterator::Flags::SkipParentAndBaseDir, [&](auto const& entry, auto const& directory) -> ErrorOr<IterationDecision> { 25 auto full_path = LexicalPath::join(directory.path().string(), entry.name).string(); 26 if (Core::DeprecatedFile::is_block_device(full_path)) 27 device_paths.append(full_path); 28 return IterationDecision::Continue; 29 }); 30 return device_paths; 31} 32 33ErrorOr<int> serenity_main(Main::Arguments arguments) 34{ 35 TRY(Core::System::pledge("stdio recvfd sendfd rpath unix")); 36 37 auto app = TRY(GUI::Application::try_create(arguments)); 38 39 TRY(Core::System::pledge("stdio recvfd sendfd rpath")); 40 TRY(Core::System::unveil("/dev", "r")); 41 TRY(Core::System::unveil("/res", "r")); 42 TRY(Core::System::unveil(nullptr, nullptr)); 43 44 auto app_icon = TRY(GUI::Icon::try_create_default_icon("app-partition-editor"sv)); 45 46 auto window = TRY(GUI::Window::try_create()); 47 window->set_title("Partition Editor"); 48 window->resize(640, 400); 49 window->set_icon(app_icon.bitmap_for_size(16)); 50 51 if (getuid() != 0) { 52 auto error_message = "PartitionEditor must be run as root in order to open raw block devices and read partition tables."sv; 53 GUI::MessageBox::show_error(window, error_message); 54 return Error::from_string_view(error_message); 55 } 56 57 auto widget = TRY(window->set_main_widget<GUI::Widget>()); 58 TRY(widget->load_from_gml(partition_editor_window_gml)); 59 60 auto device_paths = get_device_paths(); 61 62 auto partition_model = PartitionEditor::PartitionModel::create(); 63 TRY(partition_model->set_device_path(device_paths.first())); 64 65 auto& device_combobox = *widget->find_descendant_of_type_named<GUI::ComboBox>("device_combobox"); 66 device_combobox.set_model(GUI::ItemListModel<DeprecatedString>::create(device_paths)); 67 device_combobox.set_only_allow_values_from_model(true); 68 device_combobox.set_selected_index(0); 69 device_combobox.on_change = [&](auto const& path, auto const&) { 70 auto result = partition_model->set_device_path(path); 71 if (result.is_error()) 72 GUI::MessageBox::show_error(window, DeprecatedString::formatted("No partition table found for device {}", path)); 73 }; 74 75 auto& partition_table_view = *widget->find_descendant_of_type_named<GUI::TableView>("partition_table_view"); 76 partition_table_view.set_model(partition_model); 77 partition_table_view.set_focus(true); 78 79 auto& file_menu = window->add_menu("&File"); 80 file_menu.add_action(GUI::CommonActions::make_quit_action([&](auto&) { 81 app->quit(); 82 })); 83 84 auto help_menu = TRY(window->try_add_menu("&Help")); 85 TRY(help_menu->try_add_action(GUI::CommonActions::make_command_palette_action(window))); 86 TRY(help_menu->try_add_action(GUI::CommonActions::make_about_action("Partition Editor", app_icon, window))); 87 88 window->show(); 89 return app->exec(); 90}