From 5ffb319df1c563bdb5dc7f23c143bd25e7624cc7 Mon Sep 17 00:00:00 2001 From: Volker Ruppert Date: Tue, 5 Jan 2021 21:57:13 +0000 Subject: [PATCH] Rewrite of the disk image mode handling. Disk image modes are now stored as string constants instead of hardcoded values. Available modes are detected at Bochs startup and stored in a string array before initializing options. In the plugins case additional modes are read from the plugins list. If plugins are off, the hdimage_locator_c registry is used. Related changes in all parts of Bochs that need the hdimage stuff. TODO #1: Network and sound drivers could be handled in a similar way. TODO #2: Make disk image mode detection work again in plugins mode. --- bochs/config.cc | 15 ++- bochs/gui/siminterface.cc | 28 +--- bochs/gui/siminterface.h | 22 +--- bochs/iodev/devices.cc | 5 +- bochs/iodev/floppy.cc | 4 +- bochs/iodev/harddrv.cc | 10 +- bochs/iodev/hdimage/hdimage.cc | 231 ++++++++++++++++++++++----------- bochs/iodev/hdimage/hdimage.h | 17 ++- bochs/iodev/usb/usb_cbi.cc | 19 ++- bochs/iodev/usb/usb_cbi.h | 6 +- bochs/iodev/usb/usb_msd.cc | 13 +- bochs/iodev/usb/usb_msd.h | 4 +- bochs/main.cc | 38 +++--- bochs/misc/bxcompat.h | 29 +---- bochs/misc/bximage.cc | 78 ++++++++--- bochs/plugin.cc | 37 ++++++ bochs/plugin.h | 6 + 17 files changed, 331 insertions(+), 231 deletions(-) diff --git a/bochs/config.cc b/bochs/config.cc index a897c9656..7bc01989e 100644 --- a/bochs/config.cc +++ b/bochs/config.cc @@ -2,7 +2,7 @@ // $Id$ ///////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2002-2020 The Bochs Project +// Copyright (C) 2002-2021 The Bochs Project // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -21,6 +21,7 @@ #include "bochs.h" #include "bxversion.h" #include "iodev/iodev.h" +#include "iodev/hdimage/hdimage.h" #include "param_names.h" #include @@ -1217,6 +1218,7 @@ void bx_init_options() floppy->set_options(floppy->SHOW_PARENT); // ATA/ATAPI subtree + bx_hdimage_ctl.init(); // initialize available disk image modes bx_list_c *ata = new bx_list_c(root_param, "ata", "ATA/ATAPI Options"); ata->set_options(ata->USE_TAB_WINDOW); @@ -1333,9 +1335,8 @@ void bx_init_options() "mode", "Type of disk image", "Mode of the ATA harddisk", - hdimage_mode_names, - BX_HDIMAGE_MODE_FLAT, - BX_HDIMAGE_MODE_FLAT); + bx_hdimage_ctl.get_mode_names(), + 0, 0); mode->set_ask_format("Enter mode of ATA device, (flat, concat, etc.): [%s] "); status = new bx_param_enum_c(menu, @@ -1356,9 +1357,9 @@ void bx_init_options() deplist = new bx_list_c(NULL); deplist->add(journal); mode->set_dependent_list(deplist, 0); - mode->set_dependent_bitmap(BX_HDIMAGE_MODE_UNDOABLE, 1); - mode->set_dependent_bitmap(BX_HDIMAGE_MODE_VOLATILE, 1); - mode->set_dependent_bitmap(BX_HDIMAGE_MODE_VVFAT, 1); + mode->set_dependent_bitmap(bx_hdimage_ctl.get_mode_id("undoable"), 1); + mode->set_dependent_bitmap(bx_hdimage_ctl.get_mode_id("volatile"), 1); + mode->set_dependent_bitmap(bx_hdimage_ctl.get_mode_id("vvfat"), 1); bx_param_num_c *cylinders = new bx_param_num_c(menu, "cylinders", diff --git a/bochs/gui/siminterface.cc b/bochs/gui/siminterface.cc index 6841b3841..3643e0230 100644 --- a/bochs/gui/siminterface.cc +++ b/bochs/gui/siminterface.cc @@ -2,7 +2,7 @@ // $Id$ ///////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2002-2020 The Bochs Project +// Copyright (C) 2002-2021 The Bochs Project // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -120,7 +120,6 @@ public: virtual int set_log_prefix(const char *prefix); virtual int get_debugger_log_file(char *path, int len); virtual int set_debugger_log_file(const char *path); - virtual int hdimage_get_mode(const char *mode); virtual void set_notify_callback(bxevent_handler func, void *arg); virtual void get_notify_callback(bxevent_handler *func, void **arg); virtual BxEvent* sim_to_ci_event(BxEvent *event); @@ -542,31 +541,6 @@ const char *sound_driver_names[] = { NULL }; -const char *hdimage_mode_names[] = { - "flat", - "concat", - "external", - "dll", - "sparse", - "vmware3", - "vmware4", - "undoable", - "growing", - "volatile", - "vvfat", - "vpc", - "vbox", - NULL -}; - -int bx_real_sim_c::hdimage_get_mode(const char *mode) -{ - for (int i = 0; i <= BX_HDIMAGE_MODE_LAST; i++) { - if (!strcmp(mode, hdimage_mode_names[i])) return i; - } - return -1; -} - void bx_real_sim_c::set_notify_callback(bxevent_handler func, void *arg) { bxevent_callback = func; diff --git a/bochs/gui/siminterface.h b/bochs/gui/siminterface.h index 00c51adec..8a61ad29b 100644 --- a/bochs/gui/siminterface.h +++ b/bochs/gui/siminterface.h @@ -2,7 +2,7 @@ // $Id$ ///////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2001-2020 The Bochs Project +// Copyright (C) 2001-2021 The Bochs Project // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -566,24 +566,6 @@ enum { }; #define BX_ATA_TRANSLATION_LAST BX_ATA_TRANSLATION_AUTO -enum { - BX_HDIMAGE_MODE_FLAT, - BX_HDIMAGE_MODE_CONCAT, - BX_HDIMAGE_MODE_EXTDISKSIM, - BX_HDIMAGE_MODE_DLL_HD, - BX_HDIMAGE_MODE_SPARSE, - BX_HDIMAGE_MODE_VMWARE3, - BX_HDIMAGE_MODE_VMWARE4, - BX_HDIMAGE_MODE_UNDOABLE, - BX_HDIMAGE_MODE_GROWING, - BX_HDIMAGE_MODE_VOLATILE, - BX_HDIMAGE_MODE_VVFAT, - BX_HDIMAGE_MODE_VPC, - BX_HDIMAGE_MODE_VBOX -}; -#define BX_HDIMAGE_MODE_LAST BX_HDIMAGE_MODE_VBOX -#define BX_HDIMAGE_MODE_UNKNOWN -1 - enum { BX_CLOCK_SYNC_NONE, BX_CLOCK_SYNC_REALTIME, @@ -652,7 +634,6 @@ BOCHSAPI extern const char *floppy_type_names[]; BOCHSAPI extern int floppy_type_n_sectors[]; BOCHSAPI extern const char *media_status_names[]; BOCHSAPI extern const char *bochs_bootdisk_names[]; -BOCHSAPI extern const char *hdimage_mode_names[]; BOCHSAPI extern const char *sound_driver_names[]; //////////////////////////////////////////////////////////////////// @@ -730,7 +711,6 @@ public: virtual int set_log_prefix(const char *prefix) {return -1;} virtual int get_debugger_log_file(char *path, int len) {return -1;} virtual int set_debugger_log_file(const char *path) {return -1;} - virtual int hdimage_get_mode(const char *mode) {return -1;} // The CI calls set_notify_callback to register its event handler function. // This event handler function is called whenever the simulator needs to diff --git a/bochs/iodev/devices.cc b/bochs/iodev/devices.cc index ae7dd79e1..3b8a0d148 100644 --- a/bochs/iodev/devices.cc +++ b/bochs/iodev/devices.cc @@ -2,7 +2,7 @@ // $Id$ ///////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2002-2020 The Bochs Project +// Copyright (C) 2002-2021 The Bochs Project // // I/O port handlers API Copyright (C) 2003 by Frank Cornelis // @@ -72,6 +72,7 @@ bx_devices_c::~bx_devices_c() if (paste.buf != NULL) { delete [] paste.buf; } + bx_hdimage_ctl.exit(); } void bx_devices_c::init_stubs() @@ -182,7 +183,6 @@ void bx_devices_c::init(BX_MEM_C *newmem) // "by hand" in this file. Basically, we're using core plugins when we // want to control the init order. // - bx_hdimage_ctl.init(); #if BX_NETWORKING network_enabled = is_network_enabled(); if (network_enabled) @@ -463,7 +463,6 @@ void bx_devices_c::exit() // unload optional and user plugins first bx_unload_plugins(); bx_unload_core_plugins(); - bx_hdimage_ctl.exit(); #if BX_NETWORKING if (network_enabled) bx_netmod_ctl.exit(); diff --git a/bochs/iodev/floppy.cc b/bochs/iodev/floppy.cc index 343fd6a69..485705d93 100644 --- a/bochs/iodev/floppy.cc +++ b/bochs/iodev/floppy.cc @@ -2,7 +2,7 @@ // $Id$ ///////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2002-2020 The Bochs Project +// Copyright (C) 2002-2021 The Bochs Project // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -1598,7 +1598,7 @@ bx_bool bx_floppy_ctrl_c::evaluate_media(Bit8u devtype, Bit8u type, char *path, // use virtual VFAT support if requested if (!strncmp(path, "vvfat:", 6) && (devtype == FDRIVE_350HD)) { - media->vvfat = DEV_hdimage_init_image(BX_HDIMAGE_MODE_VVFAT, 1474560, ""); + media->vvfat = DEV_hdimage_init_image("vvfat", 1474560, ""); if (media->vvfat != NULL) { if (media->vvfat->open(path + 6) == 0) { media->type = BX_FLOPPY_1_44; diff --git a/bochs/iodev/harddrv.cc b/bochs/iodev/harddrv.cc index 24e908ade..e4c699ce1 100644 --- a/bochs/iodev/harddrv.cc +++ b/bochs/iodev/harddrv.cc @@ -2,7 +2,7 @@ // $Id$ ///////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2001-2020 The Bochs Project +// Copyright (C) 2001-2021 The Bochs Project // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -172,11 +172,12 @@ bx_hard_drive_c::~bx_hard_drive_c() void bx_hard_drive_c::init(void) { - Bit8u channel, image_mode; + Bit8u channel; char string[5]; char sbtext[8]; char ata_name[20]; char pname[10]; + const char *image_mode; bx_list_c *base; BX_DEBUG(("Init $Id$")); @@ -303,14 +304,13 @@ void bx_hard_drive_c::init(void) int sect_size = atoi(SIM->get_param_enum("sect_size", base)->get_selected()); Bit64u disk_size = (Bit64u)cyl * heads * spt * sect_size; - image_mode = SIM->get_param_enum("mode", base)->get(); + image_mode = SIM->get_param_enum("mode", base)->get_selected(); channels[channel].drives[device].hdimage = DEV_hdimage_init_image(image_mode, disk_size, SIM->get_param_string("journal", base)->getptr()); if (channels[channel].drives[device].hdimage != NULL) { BX_INFO(("HD on ata%d-%d: '%s', '%s' mode", channel, device, - SIM->get_param_string("path", base)->getptr(), - hdimage_mode_names[image_mode])); + SIM->get_param_string("path", base)->getptr(), image_mode)); } else { // it's safe to return here on failure return; diff --git a/bochs/iodev/hdimage/hdimage.cc b/bochs/iodev/hdimage/hdimage.cc index 3fa3f2b1a..75d3ac54a 100644 --- a/bochs/iodev/hdimage/hdimage.cc +++ b/bochs/iodev/hdimage/hdimage.cc @@ -2,7 +2,7 @@ // $Id$ ///////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2002-2020 The Bochs Project +// Copyright (C) 2002-2021 The Bochs Project // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -60,6 +60,21 @@ bx_hdimage_ctl_c bx_hdimage_ctl; +const Bit8u n_hdimage_builtin_modes = 8; + +const char *builtin_mode_names[n_hdimage_builtin_modes] = { + "flat", + "concat", + "external", + "sparse", + "dll", + "growing", + "undoable", + "volatile" +}; + +const char **hdimage_mode_names; + bx_hdimage_ctl_c::bx_hdimage_ctl_c() { put("hdimage", "IMG"); @@ -67,77 +82,110 @@ bx_hdimage_ctl_c::bx_hdimage_ctl_c() void bx_hdimage_ctl_c::init(void) { + Bit8u count = n_hdimage_builtin_modes; + #if !BX_PLUGINS - BX_INFO(("Disk image modules:")); - BX_INFO((" flat")); - BX_INFO((" concat")); - BX_INFO((" sparse")); - BX_INFO((" growing")); - BX_INFO((" undoable")); - BX_INFO((" volatile")); - hdimage_locator_c::print_modules(); + count += hdimage_locator_c::get_modules_count(); #else - // TODO + count += PLUG_get_plugins_count(PLUGTYPE_IMG); #endif + hdimage_mode_names = (const char**) malloc((count + 1) * sizeof(char*)); + for (Bit8u i = 0; i < n_hdimage_builtin_modes; i++) { + hdimage_mode_names[i] = builtin_mode_names[i]; + } + Bit8u n = 0; + for (Bit8u i = n_hdimage_builtin_modes; i < count; i++) { +#if !BX_PLUGINS + hdimage_mode_names[i] = hdimage_locator_c::get_module_name(n); +#else + hdimage_mode_names[i] = PLUG_get_plugin_name(PLUGTYPE_IMG, n); +#endif + n++; + } + hdimage_mode_names[count] = NULL; +} + +const char **bx_hdimage_ctl_c::get_mode_names(void) +{ + return hdimage_mode_names; +} + +int bx_hdimage_ctl_c::get_mode_id(const char *mode) +{ + int i = 0; + + while (hdimage_mode_names[i] != NULL) { + if (!strcmp(mode, hdimage_mode_names[i])) return i; + i++; + } + return -1; +} + +void bx_hdimage_ctl_c::list_modules(void) +{ + char list[60]; + Bit8u i = 0; + size_t len = 0, len1; + + BX_INFO(("Disk image modules")); + list[0] = 0; + while (hdimage_mode_names[i] != NULL) { + len1 = strlen(hdimage_mode_names[i]); + if ((len + len1 + 1) > 60) { + BX_INFO((" %s", list)); + list[0] = 0; + len = 0; + } + strcat(list, " "); + strcat(list, hdimage_mode_names[i]); + len = strlen(list); + i++; + } + if (len > 0) { + BX_INFO((" %s", list)); + } } void bx_hdimage_ctl_c::exit(void) { + free(hdimage_mode_names); hdimage_locator_c::cleanup(); } -device_image_t* bx_hdimage_ctl_c::init_image(Bit8u image_mode, Bit64u disk_size, const char *journal) +device_image_t* bx_hdimage_ctl_c::init_image(const char *image_mode, Bit64u disk_size, const char *journal) { device_image_t *hdimage = NULL; // instantiate the right class - switch (image_mode) { - - case BX_HDIMAGE_MODE_FLAT: - hdimage = new flat_image_t(); - break; - - case BX_HDIMAGE_MODE_CONCAT: - hdimage = new concat_image_t(); - break; - + if (!strcmp(image_mode, "flat")) { + hdimage = new flat_image_t(); + } else if (!strcmp(image_mode, "concat")) { + hdimage = new concat_image_t(); #if EXTERNAL_DISK_SIMULATOR - case BX_HDIMAGE_MODE_EXTDISKSIM: - hdimage = new EXTERNAL_DISK_SIMULATOR_CLASS(); - break; + } else if (!strcmp(image_mode, "external")) { + hdimage = new EXTERNAL_DISK_SIMULATOR_CLASS(); #endif //EXTERNAL_DISK_SIMULATOR - #ifdef WIN32 - case BX_HDIMAGE_MODE_DLL_HD: - hdimage = new dll_image_t(); - break; + } else if (!strcmp(image_mode, "dll")) { + hdimage = new dll_image_t(); #endif //DLL_HD_SUPPORT - - case BX_HDIMAGE_MODE_SPARSE: - hdimage = new sparse_image_t(); - break; - - case BX_HDIMAGE_MODE_UNDOABLE: - hdimage = new undoable_image_t(journal); - break; - - case BX_HDIMAGE_MODE_GROWING: - hdimage = new growing_image_t(); - break; - - case BX_HDIMAGE_MODE_VOLATILE: - hdimage = new volatile_image_t(journal); - break; - - default: - if (!hdimage_locator_c::module_present(hdimage_mode_names[image_mode])) { + } else if (!strcmp(image_mode, "sparse")) { + hdimage = new sparse_image_t(); + } else if (!strcmp(image_mode, "undoable")) { + hdimage = new undoable_image_t(journal); + } else if (!strcmp(image_mode, "growing")) { + hdimage = new growing_image_t(); + } else if (!strcmp(image_mode, "volatile")) { + hdimage = new volatile_image_t(journal); + } else { + if (!hdimage_locator_c::module_present(image_mode)) { #if BX_PLUGINS - PLUG_load_img_plugin(hdimage_mode_names[image_mode]); + PLUG_load_img_plugin(image_mode); #else - BX_PANIC(("Disk image mode '%s' not available", hdimage_mode_names[image_mode])); + BX_PANIC(("Disk image mode '%s' not available", image_mode)); #endif } - hdimage = hdimage_locator_c::create(hdimage_mode_names[image_mode], disk_size, journal); + hdimage = hdimage_locator_c::create(image_mode, disk_size, journal); } return hdimage; } @@ -151,7 +199,8 @@ cdrom_base_c* bx_hdimage_ctl_c::init_cdrom(const char *dev) #endif } -hdimage_locator_c *hdimage_locator_c::all; +hdimage_locator_c *hdimage_locator_c::all = NULL; +Bit8u hdimage_locator_c::count = 0; // // Each disk image module has a static locator class that registers @@ -159,9 +208,18 @@ hdimage_locator_c *hdimage_locator_c::all; // hdimage_locator_c::hdimage_locator_c(const char *mode) { - next = all; - all = this; + hdimage_locator_c *ptr; + this->mode = mode; + this->next = NULL; + if (all == NULL) { + all = this; + } else { + ptr = all; + while (ptr->next) ptr = ptr->next; + ptr->next = this; + } + count++; } hdimage_locator_c::~hdimage_locator_c() @@ -185,18 +243,27 @@ hdimage_locator_c::~hdimage_locator_c() } } -void hdimage_locator_c::print_modules() +Bit8u hdimage_locator_c::get_modules_count() { - hdimage_locator_c *ptr = 0; - - for (ptr = all; ptr != NULL; ptr = ptr->next) { - BX_INFO((" %s", ptr->mode);) - } + return count; } -bx_bool hdimage_locator_c::module_present(const char *mode) +const char* hdimage_locator_c::get_module_name(Bit8u index) { - hdimage_locator_c *ptr = 0; + hdimage_locator_c *ptr; + Bit8u n = 0; + + for (ptr = all; ptr != NULL; ptr = ptr->next) { + if (n == index) + return ptr->mode; + n++; + } + return NULL; +} + +bool hdimage_locator_c::module_present(const char *mode) +{ + hdimage_locator_c *ptr; for (ptr = all; ptr != NULL; ptr = ptr->next) { if (strcmp(mode, ptr->mode) == 0) @@ -359,9 +426,9 @@ int hdimage_open_file(const char *pathname, int flags, Bit64u *fsize, FILETIME * return fd; } -int hdimage_detect_image_mode(const char *pathname) +bool hdimage_detect_image_mode(const char *pathname, const char **image_mode) { - int result = BX_HDIMAGE_MODE_UNKNOWN; + bool result = false; Bit64u image_size = 0; int fd = hdimage_open_file(pathname, O_RDONLY, &image_size, NULL); @@ -370,21 +437,28 @@ int hdimage_detect_image_mode(const char *pathname) } if (sparse_image_t::check_format(fd, image_size) == HDIMAGE_FORMAT_OK) { - result = BX_HDIMAGE_MODE_SPARSE; + *image_mode = "sparse"; + result = true; } else if (growing_image_t::check_format(fd, image_size) == HDIMAGE_FORMAT_OK) { - result = BX_HDIMAGE_MODE_GROWING; + *image_mode = "growing"; + result = true; #if !BX_PLUGINS || defined(BXIMAGE) } else if (vbox_image_t::check_format(fd, image_size) >= HDIMAGE_FORMAT_OK) { - result = BX_HDIMAGE_MODE_VBOX; + *image_mode = "vbox"; + result = true; } else if (vmware3_image_t::check_format(fd, image_size) == HDIMAGE_FORMAT_OK) { - result = BX_HDIMAGE_MODE_VMWARE3; + *image_mode = "vmware3"; + result = true; } else if (vmware4_image_t::check_format(fd, image_size) == HDIMAGE_FORMAT_OK) { - result = BX_HDIMAGE_MODE_VMWARE4; + *image_mode = "vmware4"; + result = true; } else if (vpc_image_t::check_format(fd, image_size) >= HDIMAGE_FORMAT_OK) { - result = BX_HDIMAGE_MODE_VPC; + *image_mode = "vpc"; + result = true; #endif } else if (flat_image_t::check_format(fd, image_size) == HDIMAGE_FORMAT_OK) { - result = BX_HDIMAGE_MODE_FLAT; + *image_mode = "flat"; + result = true; } ::close(fd); @@ -2210,18 +2284,19 @@ undoable_image_t::~undoable_image_t() int undoable_image_t::open(const char* pathname, int flags) { + const char* image_mode = NULL; + UNUSED(flags); if (access(pathname, F_OK) < 0) { BX_PANIC(("r/o disk image doesn't exist")); } - int mode = hdimage_detect_image_mode(pathname); - if (mode == BX_HDIMAGE_MODE_UNKNOWN) { + if (!hdimage_detect_image_mode(pathname, &image_mode)) { BX_PANIC(("r/o disk image mode not detected")); return -1; } else { - BX_INFO(("base image mode = '%s'", hdimage_mode_names[mode])); + BX_INFO(("base image mode = '%s'", image_mode)); } - ro_disk = DEV_hdimage_init_image(mode, 0, NULL); + ro_disk = DEV_hdimage_init_image(image_mode, 0, NULL); if (ro_disk == NULL) { return -1; } @@ -2364,19 +2439,19 @@ int volatile_image_t::open(const char* pathname, int flags) { int filedes; Bit32u timestamp; + const char* image_mode = NULL; UNUSED(flags); if (access(pathname, F_OK) < 0) { BX_PANIC(("r/o disk image doesn't exist")); } - int mode = hdimage_detect_image_mode(pathname); - if (mode == BX_HDIMAGE_MODE_UNKNOWN) { + if (!hdimage_detect_image_mode(pathname, &image_mode)) { BX_PANIC(("r/o disk image mode not detected")); return -1; } else { - BX_INFO(("base image mode = '%s'", hdimage_mode_names[mode])); + BX_INFO(("base image mode = '%s'", image_mode)); } - ro_disk = DEV_hdimage_init_image(mode, 0, NULL); + ro_disk = DEV_hdimage_init_image(image_mode, 0, NULL); if (ro_disk == NULL) { return -1; } diff --git a/bochs/iodev/hdimage/hdimage.h b/bochs/iodev/hdimage/hdimage.h index 2d8752b95..3fd06a494 100644 --- a/bochs/iodev/hdimage/hdimage.h +++ b/bochs/iodev/hdimage/hdimage.h @@ -2,7 +2,7 @@ // $Id$ ///////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2005-2020 The Bochs Project +// Copyright (C) 2005-2021 The Bochs Project // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -149,7 +149,7 @@ int hdimage_open_file(const char *pathname, int flags, Bit64u *fsize, time_t *mt #else BOCHSAPI_MSVCONLY int hdimage_open_file(const char *pathname, int flags, Bit64u *fsize, FILETIME *mtime); #endif -int hdimage_detect_image_mode(const char *pathname); +bool hdimage_detect_image_mode(const char *pathname, const char **image_mode); BOCHSAPI_MSVCONLY bx_bool hdimage_backup_file(int fd, const char *backup_fname); BOCHSAPI_MSVCONLY bx_bool hdimage_copy_file(const char *src, const char *dst); bx_bool coherency_check(device_image_t *ro_disk, redolog_t *redolog); @@ -610,8 +610,11 @@ public: bx_hdimage_ctl_c(); virtual ~bx_hdimage_ctl_c() {} void init(void); + const char **get_mode_names(); + int get_mode_id(const char *mode); + void list_modules(void); void exit(void); - device_image_t *init_image(Bit8u image_mode, Bit64u disk_size, const char *journal); + device_image_t *init_image(const char *image_mode, Bit64u disk_size, const char *journal); cdrom_base_c *init_cdrom(const char *dev); }; @@ -624,15 +627,17 @@ BOCHSAPI extern bx_hdimage_ctl_c bx_hdimage_ctl; // class BOCHSAPI_MSVCONLY hdimage_locator_c { public: - static bx_bool module_present(const char *mode); - static void print_modules(); - static void cleanup(); + static bool module_present(const char *mode); + static Bit8u get_modules_count(void); + static const char* get_module_name(Bit8u index); + static void cleanup(void); static device_image_t *create(const char *mode, Bit64u disk_size, const char *journal); protected: hdimage_locator_c(const char *mode); virtual ~hdimage_locator_c(); virtual device_image_t *allocate(Bit64u disk_size, const char *journal) = 0; private: + static Bit8u count; static hdimage_locator_c *all; hdimage_locator_c *next; const char *mode; diff --git a/bochs/iodev/usb/usb_cbi.cc b/bochs/iodev/usb/usb_cbi.cc index 372b16042..0638e2d61 100644 --- a/bochs/iodev/usb/usb_cbi.cc +++ b/bochs/iodev/usb/usb_cbi.cc @@ -5,7 +5,7 @@ // UFI/CBI floppy disk storage device support // // Copyright (c) 2015 Benjamin David Lunt -// Copyright (C) 2015-2020 The Bochs Project +// Copyright (C) 2015-2021 The Bochs Project // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -352,13 +352,12 @@ usb_cbi_device_c::usb_cbi_device_c(const char *filename) ptr1 = strtok(tmpfname, ":"); ptr2 = strtok(NULL, ":"); if ((ptr2 == NULL) || (strlen(ptr1) < 2)) { - s.image_mode = BX_HDIMAGE_MODE_FLAT; + s.image_mode = strdup("flat"); s.fname = filename; } else { - s.image_mode = SIM->hdimage_get_mode(ptr1); + s.image_mode = strdup(ptr1); s.fname = filename+strlen(ptr1)+1; - if ((s.image_mode != BX_HDIMAGE_MODE_FLAT) && - (s.image_mode != BX_HDIMAGE_MODE_VVFAT)) { + if (strcmp(s.image_mode, "flat") && strcmp(s.image_mode, "vvfat")) { BX_PANIC(("USB floppy only supports image modes 'flat' and 'vvfat'")); } } @@ -381,7 +380,7 @@ usb_cbi_device_c::usb_cbi_device_c(const char *filename) "Image mode", "Mode of the floppy image", fdimage_mode_names, 0, 0); - if (s.image_mode == BX_HDIMAGE_MODE_VVFAT) { + if (!strcmp(s.image_mode, "vvfat")) { mode->set(1); } mode->set_handler(floppy_param_handler); @@ -417,6 +416,7 @@ usb_cbi_device_c::~usb_cbi_device_c(void) set_inserted(0); if (s.dev_buffer != NULL) delete [] s.dev_buffer; + free(s.image_mode); if (SIM->is_wx_selected()) { bx_list_c *usb = (bx_list_c*)SIM->get_param("ports.usb"); usb->remove(s.config->get_name()); @@ -446,7 +446,7 @@ bx_bool usb_cbi_device_c::set_option(const char *option) bx_bool usb_cbi_device_c::init() { if (set_inserted(1)) { - sprintf(s.info_txt, "USB CBI: path='%s', mode='%s'", s.fname, hdimage_mode_names[s.image_mode]); + sprintf(s.info_txt, "USB CBI: path='%s', mode='%s'", s.fname, s.image_mode); } else { sprintf(s.info_txt, "USB CBI: media not present"); } @@ -1210,14 +1210,11 @@ void usb_cbi_device_c::cancel_packet(USBPacket *p) bx_bool usb_cbi_device_c::set_inserted(bx_bool value) { - Bit8u mode; - s.inserted = value; if (value) { s.fname = SIM->get_param_string("path", s.config)->getptr(); if ((strlen(s.fname) > 0) && (strcmp(s.fname, "none"))) { - mode = SIM->get_param_enum("mode", s.config)->get(); - s.image_mode = (mode == 1) ? BX_HDIMAGE_MODE_VVFAT : BX_HDIMAGE_MODE_FLAT; + s.image_mode = strdup(SIM->get_param_enum("mode", s.config)->get_selected()); s.hdimage = DEV_hdimage_init_image(s.image_mode, 1474560, ""); if ((s.hdimage->open(s.fname)) < 0) { BX_ERROR(("could not open floppy image file '%s'", s.fname)); diff --git a/bochs/iodev/usb/usb_cbi.h b/bochs/iodev/usb/usb_cbi.h index d9afee6b0..01592aeb4 100644 --- a/bochs/iodev/usb/usb_cbi.h +++ b/bochs/iodev/usb/usb_cbi.h @@ -4,8 +4,8 @@ // // UFI/CBI floppy disk storage device support // -// Copyright (c) 2015 Benjamin David Lunt -// Copyright (C) 2015 The Bochs Project +// Copyright (c) 2015 Benjamin David Lunt +// Copyright (C) 2015-2021 The Bochs Project // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -77,7 +77,7 @@ private: // members handled by runtime config device_image_t *hdimage; const char *fname; - Bit8u image_mode; + char *image_mode; bx_bool inserted; // 0 = media not present bx_bool wp; // 0 = not write_protected, 1 = write_protected bx_bool status_changed; diff --git a/bochs/iodev/usb/usb_msd.cc b/bochs/iodev/usb/usb_msd.cc index afb29b146..5df7881d6 100644 --- a/bochs/iodev/usb/usb_msd.cc +++ b/bochs/iodev/usb/usb_msd.cc @@ -6,7 +6,7 @@ // // Copyright (c) 2006 CodeSourcery. // Written by Paul Brook -// Copyright (C) 2009-2020 The Bochs Project +// Copyright (C) 2009-2021 The Bochs Project // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -355,10 +355,10 @@ usb_msd_device_c::usb_msd_device_c(usbdev_type type, const char *filename) ptr1 = strtok(tmpfname, ":"); ptr2 = strtok(NULL, ":"); if ((ptr2 == NULL) || (strlen(ptr1) < 2)) { - s.image_mode = BX_HDIMAGE_MODE_FLAT; + s.image_mode = strdup("flat"); strcpy(s.fname, filename); } else { - s.image_mode = SIM->hdimage_get_mode(ptr1); + s.image_mode = strdup(ptr1); strcpy(s.fname, filename+strlen(ptr1)+1); } s.journal[0] = 0; @@ -405,6 +405,7 @@ usb_msd_device_c::~usb_msd_device_c(void) if (s.hdimage != NULL) { s.hdimage->close(); delete s.hdimage; + free(s.image_mode); } else if (s.cdrom != NULL) { delete s.cdrom; if (SIM->is_wx_selected()) { @@ -428,7 +429,7 @@ bx_bool usb_msd_device_c::set_option(const char *option) BX_ERROR(("Option 'journal' is only valid for USB disks")); } } else if (!strncmp(option, "size:", 5)) { - if ((d.type == USB_DEV_TYPE_DISK) && (s.image_mode == BX_HDIMAGE_MODE_VVFAT)) { + if ((d.type == USB_DEV_TYPE_DISK) && (!strcmp(s.image_mode, "vvfat"))) { s.size = (int)strtol(option+5, &suffix, 10); if (!strcmp(suffix, "G")) { s.size <<= 10; @@ -468,7 +469,7 @@ bx_bool usb_msd_device_c::init() { if (d.type == USB_DEV_TYPE_DISK) { s.hdimage = DEV_hdimage_init_image(s.image_mode, 0, s.journal); - if (s.image_mode == BX_HDIMAGE_MODE_VVFAT) { + if (!strcmp(s.image_mode, "vvfat")) { Bit64u hdsize = ((Bit64u)s.size) << 20; s.hdimage->cylinders = (unsigned)(hdsize/16.0/63.0/512.0); s.hdimage->heads = 16; @@ -484,7 +485,7 @@ bx_bool usb_msd_device_c::init() s.scsi_dev = new scsi_device_t(s.hdimage, 0, usb_msd_command_complete, (void*)this); } sprintf(s.info_txt, "USB HD: path='%s', mode='%s', sect_size=%d", s.fname, - hdimage_mode_names[s.image_mode], s.hdimage->sect_size); + s.image_mode, s.hdimage->sect_size); } else if (d.type == USB_DEV_TYPE_CDROM) { s.cdrom = DEV_hdimage_init_cdrom(s.fname); s.scsi_dev = new scsi_device_t(s.cdrom, 0, usb_msd_command_complete, (void*)this); diff --git a/bochs/iodev/usb/usb_msd.h b/bochs/iodev/usb/usb_msd.h index 4a89c5e75..2bc677079 100644 --- a/bochs/iodev/usb/usb_msd.h +++ b/bochs/iodev/usb/usb_msd.h @@ -6,7 +6,7 @@ // // Copyright (c) 2006 CodeSourcery. // Written by Paul Brook -// Copyright (C) 2009-2020 The Bochs Project +// Copyright (C) 2009-2021 The Bochs Project // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -59,7 +59,7 @@ protected: private: struct { // members set in constructor / init - Bit8u image_mode; + char *image_mode; device_image_t *hdimage; cdrom_base_c *cdrom; scsi_device_t *scsi_dev; diff --git a/bochs/main.cc b/bochs/main.cc index 694a11fe3..0016b2666 100644 --- a/bochs/main.cc +++ b/bochs/main.cc @@ -2,7 +2,7 @@ // $Id$ ///////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2001-2020 The Bochs Project +// Copyright (C) 2001-2021 The Bochs Project // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -27,6 +27,7 @@ #endif #include "cpu/cpu.h" #include "iodev/iodev.h" +#include "iodev/hdimage/hdimage.h" #ifdef HAVE_LOCALE_H #include @@ -608,6 +609,21 @@ int bx_init_main(int argc, char *argv[]) // initalization must be done early because some destructors expect // the bochs config options to exist by the time they are called. bx_init_bx_dbg(); + +#if BX_PLUGINS && BX_HAVE_GETENV && BX_HAVE_SETENV + // set a default plugin path, in case the user did not specify one + if (getenv("LTDL_LIBRARY_PATH") != NULL) { + BX_INFO(("LTDL_LIBRARY_PATH is set to '%s'", getenv("LTDL_LIBRARY_PATH"))); + } else { + BX_INFO(("LTDL_LIBRARY_PATH not set. using compile time default '%s'", + BX_PLUGIN_PATH)); + setenv("LTDL_LIBRARY_PATH", BX_PLUGIN_PATH, 1); + } +#endif + // initialize plugin system. This must happen before we attempt to + // load any modules. + plugin_startup(); + bx_init_options(); bx_print_header(); @@ -806,9 +822,7 @@ int bx_init_main(int argc, char *argv[]) CFRelease(bxshareDir); } #endif -#if BX_PLUGINS - // set a default plugin path, in case the user did not specify one -#if BX_WITH_CARBON +#if BX_PLUGINS && BX_WITH_CARBON // if there is no stdin, then we must create our own LTDL_LIBRARY_PATH. // also if there is no LTDL_LIBRARY_PATH, but we have a bundle since we're here // This is here so that it is available whenever --with-carbon is defined but @@ -842,16 +856,7 @@ int bx_init_main(int argc, char *argv[]) BX_INFO(("now my LTDL_LIBRARY_PATH is %s", getenv("LTDL_LIBRARY_PATH"))); CFRelease(libDir); } -#elif BX_HAVE_GETENV && BX_HAVE_SETENV - if (getenv("LTDL_LIBRARY_PATH") != NULL) { - BX_INFO(("LTDL_LIBRARY_PATH is set to '%s'", getenv("LTDL_LIBRARY_PATH"))); - } else { - BX_INFO(("LTDL_LIBRARY_PATH not set. using compile time default '%s'", - BX_PLUGIN_PATH)); - setenv("LTDL_LIBRARY_PATH", BX_PLUGIN_PATH, 1); - } -#endif -#endif /* if BX_PLUGINS */ +#endif /* if BX_PLUGINS && BX_WITH_CARBON */ #if BX_HAVE_GETENV && BX_HAVE_SETENV if (getenv("BXSHARE") != NULL) { BX_INFO(("BXSHARE is set to '%s'", getenv("BXSHARE"))); @@ -870,10 +875,6 @@ int bx_init_main(int argc, char *argv[]) // we don't have getenv or setenv. Do nothing. #endif - // initialize plugin system. This must happen before we attempt to - // load any modules. - plugin_startup(); - int norcfile = 1; if (SIM->get_param_bool(BXPN_RESTORE_FLAG)->get()) { @@ -1291,6 +1292,7 @@ void bx_init_hardware() #endif BX_INFO((" VGA extension support: vbe%s%s", BX_SUPPORT_CLGD54XX?" cirrus":"", BX_SUPPORT_VOODOO?" voodoo":"")); + bx_hdimage_ctl.list_modules(); // Check if there is a romimage if (SIM->get_param_string(BXPN_ROM_PATH)->isempty()) { diff --git a/bochs/misc/bxcompat.h b/bochs/misc/bxcompat.h index 671eea345..3626726fe 100644 --- a/bochs/misc/bxcompat.h +++ b/bochs/misc/bxcompat.h @@ -3,7 +3,7 @@ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2013 Volker Ruppert -// Copyright (C) 2001-2020 The Bochs Project +// Copyright (C) 2001-2021 The Bochs Project // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -41,29 +41,6 @@ #include #include -#ifdef BXIMAGE -// copied from siminterface.h -enum { - BX_HDIMAGE_MODE_FLAT, - BX_HDIMAGE_MODE_CONCAT, - BX_HDIMAGE_MODE_EXTDISKSIM, - BX_HDIMAGE_MODE_DLL_HD, - BX_HDIMAGE_MODE_SPARSE, - BX_HDIMAGE_MODE_VMWARE3, - BX_HDIMAGE_MODE_VMWARE4, - BX_HDIMAGE_MODE_UNDOABLE, - BX_HDIMAGE_MODE_GROWING, - BX_HDIMAGE_MODE_VOLATILE, - BX_HDIMAGE_MODE_VVFAT, - BX_HDIMAGE_MODE_VPC, - BX_HDIMAGE_MODE_VBOX -}; -#define BX_HDIMAGE_MODE_LAST BX_HDIMAGE_MODE_VBOX -#define BX_HDIMAGE_MODE_UNKNOWN -1 - -extern const char *hdimage_mode_names[]; -#endif - // definitions for compatibility with Bochs #ifndef UNUSED # define UNUSED(x) ((void)x) @@ -88,9 +65,9 @@ extern int bx_interactive; class device_image_t; void myexit(int code); -device_image_t* init_image(Bit8u image_mode); +device_image_t* init_image_2(const char *image_mode); -#define DEV_hdimage_init_image(a,b,c) init_image(a) +#define DEV_hdimage_init_image(a,b,c) init_image_2(a) #else diff --git a/bochs/misc/bximage.cc b/bochs/misc/bximage.cc index eb5a73fce..97963ba3d 100644 --- a/bochs/misc/bximage.cc +++ b/bochs/misc/bximage.cc @@ -2,7 +2,7 @@ // $Id$ ///////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2001-2020 The Bochs Project +// Copyright (C) 2001-2021 The Bochs Project // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -87,6 +87,22 @@ const int bx_max_hd_megs = (int)(((1 << BX_MAX_CYL_BITS) - 1) * 16.0 * 63.0 / 2048.0); +enum { + BX_HDIMAGE_MODE_FLAT, + BX_HDIMAGE_MODE_CONCAT, + BX_HDIMAGE_MODE_EXTDISKSIM, + BX_HDIMAGE_MODE_DLL_HD, + BX_HDIMAGE_MODE_SPARSE, + BX_HDIMAGE_MODE_VMWARE3, + BX_HDIMAGE_MODE_VMWARE4, + BX_HDIMAGE_MODE_UNDOABLE, + BX_HDIMAGE_MODE_GROWING, + BX_HDIMAGE_MODE_VOLATILE, + BX_HDIMAGE_MODE_VVFAT, + BX_HDIMAGE_MODE_VPC, + BX_HDIMAGE_MODE_VBOX +}; + const char *hdimage_mode_names[] = { "flat", "concat", @@ -155,6 +171,17 @@ const char *sectsize_menu = "\nChoose the size of hard disk sectors.\nPlease typ const char *sectsize_choices[] = { "512","1024","4096" }; int sectsize_n_choices = 3; +int hdimage_get_mode_id(const char *mode) +{ + int i = 0; + + while (hdimage_mode_names[i] != NULL) { + if (!strcmp(mode, hdimage_mode_names[i])) return i; + i++; + } + return -1; +} + #if !BX_HAVE_SNPRINTF #include /* XXX use real snprintf */ @@ -355,7 +382,7 @@ int ask_string(const char *prompt, char *the_default, char *out) return 0; } -device_image_t* init_image(Bit8u image_mode) +device_image_t* init_image(int image_mode) { device_image_t *hdimage = NULL; @@ -403,6 +430,11 @@ device_image_t* init_image(Bit8u image_mode) return hdimage; } +device_image_t* init_image_2(const char *image_mode) +{ + return init_image(hdimage_get_mode_id(image_mode)); +} + int create_image_file(const char *filename) { int fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC @@ -765,17 +797,18 @@ void convert_image(int newimgmode, Bit64u newsize) int mode = -1; Bit64u i, sc, s; char buffer[512], null_sector[512]; + const char *image_mode = NULL; bx_bool error = 0; printf("\n"); memset(null_sector, 0, 512); if (newsize == 0) { if (!strncmp(bx_filename_1, "concat:", 7)) { - mode = BX_HDIMAGE_MODE_CONCAT; + image_mode = "concat"; strcpy(bx_filename_1, &bx_filename_1[7]); #ifdef WIN32 } else if (!strncmp(bx_filename_1, "dll:", 4)) { - mode = BX_HDIMAGE_MODE_DLL_HD; + image_mode = "dll"; strcpy(bx_filename_1, &bx_filename_1[4]); #endif } @@ -783,10 +816,12 @@ void convert_image(int newimgmode, Bit64u newsize) if (access(bx_filename_1, F_OK) < 0) { fatal("source disk image doesn't exist"); } - if (mode == -1) { - mode = hdimage_detect_image_mode(bx_filename_1); + if (image_mode == NULL) { + if (hdimage_detect_image_mode(bx_filename_1, &image_mode)) { + mode = hdimage_get_mode_id(image_mode); + } } - if (mode == BX_HDIMAGE_MODE_UNKNOWN) { + if (mode == -1) { fatal("source disk image mode not detected"); } else { printf("source image mode = '%s'\n", hdimage_mode_names[mode]); @@ -846,14 +881,17 @@ void commit_redolog() { device_image_t *base_image; redolog_t *redolog; - int ret; + int mode = -1, ret; + const char *image_mode = NULL; printf("\n"); if (access(bx_filename_1, F_OK) < 0) { fatal("base disk image doesn't exist"); } - int mode = hdimage_detect_image_mode(bx_filename_1); - if (mode == BX_HDIMAGE_MODE_UNKNOWN) + if (hdimage_detect_image_mode(bx_filename_1, &image_mode)) { + mode = hdimage_get_mode_id(image_mode); + } + if (mode == -1) fatal("base disk image mode not detected"); base_image = init_image(mode); @@ -1093,18 +1131,22 @@ void check_image_names() int get_image_mode_and_hdsize(const char *filename, int *hdsize_megs) { device_image_t *source_image; + int mode = -1; + const char *image_mode = NULL; - int imgmode = hdimage_detect_image_mode(filename); - if (imgmode == BX_HDIMAGE_MODE_UNKNOWN) + if (hdimage_detect_image_mode(bx_filename_1, &image_mode)) { + mode = hdimage_get_mode_id(image_mode); + } + if (mode == -1) fatal("source disk image mode not detected"); - source_image = init_image(imgmode); + source_image = init_image(mode); if (source_image->open(bx_filename_1, O_RDONLY) < 0) { fatal("cannot open source disk image"); } else { *hdsize_megs = (int)(source_image->hd_size >> 20); source_image->close(); } - return imgmode; + return mode; } int CDECL main(int argc, char *argv[]) @@ -1113,6 +1155,7 @@ int CDECL main(int argc, char *argv[]) int imgmode = 0; Bit64u hdsize = 0; device_image_t *hdimage; + const char *image_mode = NULL; if (!parse_cmdline(argc, argv)) myexit(1); @@ -1321,8 +1364,11 @@ int CDECL main(int argc, char *argv[]) break; case BXIMAGE_MODE_IMAGE_INFO: - imgmode = hdimage_detect_image_mode(bx_filename_1); - if (imgmode == BX_HDIMAGE_MODE_UNKNOWN) { + imgmode = -1; + if (hdimage_detect_image_mode(bx_filename_1, &image_mode)) { + imgmode = hdimage_get_mode_id(image_mode); + } + if (imgmode == -1) { fatal("disk image mode not detected"); } else { printf("\ndisk image mode = '%s'\n", hdimage_mode_names[imgmode]); diff --git a/bochs/plugin.cc b/bochs/plugin.cc index c99bf35ca..c9a0aef63 100644 --- a/bochs/plugin.cc +++ b/bochs/plugin.cc @@ -368,6 +368,43 @@ void plugins_search(void) delete [] pgn_path; } +Bit8u bx_get_plugins_count(plugintype_t type) +{ + plugin_t *temp; + Bit8u count = 0; + + if (plugins != NULL) { + temp = plugins; + + while (temp != NULL) { + if (type == temp->type) + count++; + temp = temp->next; + } + } + return count; +} + +const char* bx_get_plugin_name(plugintype_t type, Bit8u index) +{ + plugin_t *temp; + int count = 0; + + if (plugins != NULL) { + temp = plugins; + + while (temp != NULL) { + if (type == temp->type) { + if (count == index) + return temp->name; + count++; + } + temp = temp->next; + } + } + return NULL; +} + /************************************************************************/ /* Plugin initialization / deinitialization */ /************************************************************************/ diff --git a/bochs/plugin.h b/bochs/plugin.h index 3ea8cc651..eb879c3da 100644 --- a/bochs/plugin.h +++ b/bochs/plugin.h @@ -82,6 +82,8 @@ extern "C" { #if BX_PLUGINS +#define PLUG_get_plugins_count(a) bx_get_plugins_count(a) +#define PLUG_get_plugin_name(a,b) bx_get_plugin_name(a,b) #define PLUG_load_plugin(name,type) {bx_load_plugin(#name,type);} #define PLUG_load_gui_plugin(name) bx_load_plugin(name,PLUGTYPE_GUI) #define PLUG_load_opt_plugin(name) bx_load_plugin(name,PLUGTYPE_OPTIONAL) @@ -341,6 +343,10 @@ BOCHSAPI extern void (*pluginSetHRQHackCallback)(void (*callback)(void)); void plugin_abort(void); +#if BX_PLUGINS +Bit8u bx_get_plugins_count(plugintype_t type); +const char* bx_get_plugin_name(plugintype_t type, Bit8u index); +#endif int bx_load_plugin(const char *name, plugintype_t type); extern void bx_unload_plugin(const char *name, bx_bool devflag); extern void bx_init_plugins(void);