Merge branch 'devel'

pull/252/head 8.9.0
mbusb 7 years ago
commit 8818a2afbc

@ -1,3 +1,17 @@
Version - 8.9.0
---------------
* Support for GPT based USB disks. BIOS mode works only under USB created under Linux. UEFI for on Windows and Linux
* Added command line option to install sysinux on multibootusb director (use -s or --syslinux)
* Added command line option to direct ISO writing to USB disk (use -r or --raw)
* Boot ISO and IMG directly using memdisk
* Added feature for selecting ISO, IMG, Zip and all files options in file chooser dialog
* Corrected path to menu.lst file for distrs based on grub4dos
* Fix for crash when multicard reader is inserted on the system without a SD card
* Correctly detect USB disk information using udisk2-dbus without crash under Linux
* Fixed an issue where using a path with spaces would cause a qemu boot error
* If distro is not supported, ISO is automatically added using memdisk. You can uninstall later if it does not work
* Added Nano Linux
Version - 8.8.0
---------------
* Fix for crash when listing fixed partition

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -1 +1 @@
8.8.0
8.9.0

@ -101,7 +101,7 @@ Example for writing ISO image to target USB disk (will destroy data on USB disk)
Windows:
python3 multibootusb -c -i -r ../../favourite.iso -t G:
''')
exit(2)
sys.exit(2)
def start_gui():
@ -121,9 +121,9 @@ if __name__ == '__main__':
admin.runAsAdmin()
sys.exit(0)
try:
opts, args = getopt.getopt(sys.argv[1:], 'i:t:yvhcudr',
opts, args = getopt.getopt(sys.argv[1:], 'i:t:yvhcudrs',
['iso=', 'target=', 'yes', 'version', 'help', 'command', 'uninstall', 'debug',
'raw'])
'raw', 'syslinux'])
except getopt.GetoptError:
usage()
sys.exit(2)
@ -151,6 +151,8 @@ if __name__ == '__main__':
config.yes = True
elif opt in ('-r', '--raw'):
config.cli_dd = True
elif opt in ('-s', '--syslinux'):
config.cli_syslinux = True
else:
gui = True
#start_gui()
@ -174,6 +176,8 @@ if gui is False:
elif config.image_path is '' and config.usb_disk is '':
log('\nNo option provided. See the usage below.')
usage()
elif config.cli_syslinux is True and config.usb_disk is not '':
cli_install_syslinux()
elif config.image_path is '' or config.usb_disk is '':
log('\nOptions \'-i\' and \'-t\' must be supplied together. See the usage below.')
usage()

@ -75,7 +75,8 @@ def list_iso(iso_link, suppress_out=True):
file_list = []
_cmd = _7zip + ' l ' + gen.quote(iso_link) + suppress_out
try:
_cmd_out = subprocess.check_output(_cmd, stderr=subprocess.PIPE, shell=True).decode('utf-8', 'ignore').splitlines()
_cmd_out = subprocess.check_output(_cmd, stderr=subprocess.PIPE, stdin=subprocess.DEVNULL,
shell=True).decode('utf-8', 'ignore').splitlines()
except Exception as e:
gen.log(e)
_cmd_out = ''
@ -84,18 +85,6 @@ def list_iso(iso_link, suppress_out=True):
line = line.split()
_path = line[-1]
file_list.append(_path)
'''
for line in _cmd_out:
line = line.split()
if '.....' in line:
if gen.has_digit(line[2]) or gen.has_digit(line[4]):
if len(line) > 6:
f_path = " ".join(line[5:])
file_list.append(f_path)
else:
f_path = line[-1]
file_list.append(f_path)
'''
return file_list

@ -27,6 +27,8 @@ iso_bin_dir = ''
process_exist = None
yes = False
cli_dd = False
cli_syslinux = False
usb_gpt = ''
imager_iso_link = ""
imager_usb_disk_selected = ""

@ -229,6 +229,23 @@ def copy_mbusb_dir_usb(usb_disk):
else:
log('EFI directory already exist. Not copying.')
# For backward compatibility
if not os.path.exists(os.path.join(usb_mount_path, 'EFI', 'BOOT', 'bootx64-gpt.efi')):
shutil.copy(resource_path(os.path.join('data', 'EFI', 'BOOT', 'bootx64-gpt.efi')),
os.path.join(usb_mount_path, 'EFI', 'BOOT', 'bootx64-gpt.efi'))
if not os.path.exists(os.path.join(usb_mount_path, 'EFI', 'BOOT', 'bootx64-msdos.efi')):
shutil.copy(resource_path(os.path.join('data', 'EFI', 'BOOT', 'bootx64-msdos.efi')),
os.path.join(usb_mount_path, 'EFI', 'BOOT', 'bootx64-msdos.efi'))
if not os.path.exists(os.path.join(usb_mount_path, 'multibootusb', 'grub', 'core-gpt.img')):
shutil.copy(resource_path(os.path.join('data', 'multibootusb', 'grub', 'core-gpt.img')),
os.path.join(usb_mount_path, 'multibootusb', 'grub', 'core-gpt.img'))
if not os.path.exists(os.path.join(usb_mount_path, 'multibootusb', 'grub', 'core-msdos.img')):
shutil.copy(resource_path(os.path.join('data', 'multibootusb', 'grub', 'core-msdos.img')),
os.path.join(usb_mount_path, 'multibootusb', 'grub', 'core-msdos.img'))
return result

@ -25,7 +25,7 @@
<item row="1" column="1">
<widget class="QLabel" name="label_6">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;An advanced bootable usb creator with option to install/uninstall multiple distros.&lt;/p&gt;&lt;p align=&quot;center&quot;&gt;This software is written in Python and PyQt. &lt;/p&gt;&lt;p align=&quot;center&quot;&gt;Copyright 2010-2017 Sundar&lt;/p&gt;&lt;p align=&quot;center&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Author(s)&lt;/span&gt;: Sundar, Ian Bruce, LiQiong Lee and Alin Trăistaru (alindt)&lt;/p&gt;&lt;p align=&quot;center&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Licence&lt;/span&gt;: GPL version 2 or later&lt;/p&gt;&lt;p align=&quot;center&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Home page&lt;/span&gt;: &lt;a href=&quot; http://multibootusb.org&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;http://multibootusb.org&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p align=&quot;center&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Help/Email&lt;/span&gt;: feedback.multibootusb@gmail.com&lt;/p&gt;&lt;p align=&quot;center&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Source Code&lt;/span&gt;: &lt;a href=&quot;https://github.com/mbusb/multibootusb&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;https://github.com/mbusb/multibootusb&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;An advanced bootable usb creator with option to install/uninstall multiple distros.&lt;/p&gt;&lt;p align=&quot;center&quot;&gt;This software is written in Python and PyQt. &lt;/p&gt;&lt;p align=&quot;center&quot;&gt;Copyright 2010-2017 Sundar&lt;/p&gt;&lt;p align=&quot;center&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Author(s)&lt;/span&gt;: Sundar, Ian Bruce, LiQiong Lee and Alin Trăistaru (alindt)&lt;/p&gt;&lt;p align=&quot;center&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Licence&lt;/span&gt;: GPL version 2 or later&lt;/p&gt;&lt;p align=&quot;center&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Home page&lt;/span&gt;: &lt;a href=&quot;http://multibootusb.org&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;http://multibootusb.org&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p align=&quot;center&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Help/Email&lt;/span&gt;: feedback.multibootusb@gmail.com&lt;/p&gt;&lt;p align=&quot;center&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Source Code&lt;/span&gt;: &lt;a href=&quot;https://github.com/mbusb/multibootusb&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;https://github.com/mbusb/multibootusb&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>

@ -48,7 +48,7 @@ class Ui_About(object):
def retranslateUi(self, About):
_translate = QtCore.QCoreApplication.translate
About.setWindowTitle(_translate("About", "Dialog"))
self.label_6.setText(_translate("About", "<html><head/><body><p align=\"center\">An advanced bootable usb creator with option to install/uninstall multiple distros.</p><p align=\"center\">This software is written in Python and PyQt. </p><p align=\"center\">Copyright 2010-2017 Sundar</p><p align=\"center\"><span style=\" font-weight:600;\">Author(s)</span>: Sundar, Ian Bruce, LiQiong Lee and Alin Trăistaru (alindt)</p><p align=\"center\"><span style=\" font-weight:600;\">Licence</span>: GPL version 2 or later</p><p align=\"center\"><span style=\" font-weight:600;\">Home page</span>: <a href=\" http://multibootusb.org\"><span style=\" text-decoration: underline; color:#0000ff;\">http://multibootusb.org</span></a></p><p align=\"center\"><span style=\" font-weight:600;\">Help/Email</span>: feedback.multibootusb@gmail.com</p><p align=\"center\"><span style=\" font-weight:600;\">Source Code</span>: <a href=\"https://github.com/mbusb/multibootusb\"><span style=\" text-decoration: underline; color:#0000ff;\">https://github.com/mbusb/multibootusb</span></a></p><p><br/></p></body></html>"))
self.label_6.setText(_translate("About", "<html><head/><body><p align=\"center\">An advanced bootable usb creator with option to install/uninstall multiple distros.</p><p align=\"center\">This software is written in Python and PyQt. </p><p align=\"center\">Copyright 2010-2017 Sundar</p><p align=\"center\"><span style=\" font-weight:600;\">Author(s)</span>: Sundar, Ian Bruce, LiQiong Lee and Alin Trăistaru (alindt)</p><p align=\"center\"><span style=\" font-weight:600;\">Licence</span>: GPL version 2 or later</p><p align=\"center\"><span style=\" font-weight:600;\">Home page</span>: <a href=\"http://multibootusb.org\"><span style=\" text-decoration: underline; color:#0000ff;\">http://multibootusb.org</span></a></p><p align=\"center\"><span style=\" font-weight:600;\">Help/Email</span>: feedback.multibootusb@gmail.com</p><p align=\"center\"><span style=\" font-weight:600;\">Source Code</span>: <a href=\"https://github.com/mbusb/multibootusb\"><span style=\" text-decoration: underline; color:#0000ff;\">https://github.com/mbusb/multibootusb</span></a></p><p><br/></p></body></html>"))
self.button_close.setText(_translate("About", "Close"))
@ -60,4 +60,3 @@ if __name__ == "__main__":
ui.setupUi(About)
About.show()
sys.exit(app.exec_())

@ -60,12 +60,20 @@ def iso_size(iso_link):
return os.path.getsize(iso_link)
def is_readable(iso_link):
return os.access(iso_link, os.R_OK)
def is_bootable(iso_link):
"""
Check if an ISO has the ability to boot.
:return: True if ISO is bootable and False if not.
"""
iso9660fs = ISO9660(iso_link)
try:
iso9660fs = ISO9660(iso_link)
except IOError as e:
log(str(e))
raise
isBootable = iso9660fs.checkISOBootable()
return bool(isBootable)

@ -44,21 +44,21 @@ E_FAILURE = -1
E_DEVICEFILE = -2 # can't write device file
class PrimaryVolume(Structure):
def __init__(self):
self.sysIdentifier = ""
self.volIdentifier = ""
self.volSize = 0
self.volSeq = 0
self.blockSize = 0
self.ptSize = 0
self.ptLRd = 0
self.fsVer = 0
self.rootLoc = 0
self.rootTotal = 0
def __init__(self):
self.sysIdentifier = ""
self.volIdentifier = ""
self.volSize = 0
self.volSeq = 0
self.blockSize = 0
self.ptSize = 0
self.ptLRd = 0
self.fsVer = 0
self.rootLoc = 0
self.rootTotal = 0
class Rrip(Structure):
def __init__(self):
self.offset = -1
self.offset = -1
self.altname = ""
self.devH = 0
self.devL = 0
@ -106,7 +106,10 @@ class ISO9660:
f = open(isofile, 'rb')
except(IOError):
sys.stderr.write("can't open {0}".format(isofile))
sys.exit(-1)
raise
if os.path.getsize(isofile) == 0:
raise IOError("File {0} appears to be empty".format(isofile))
self.isoFile = f
self.priVol = None
@ -803,4 +806,3 @@ if __name__ == '__main__':
else:
gen.log("writeDir(%s)->(%s) with pattern(%s)"%(isodir, o_path, pattern))
sys.exit(iso9660fs.writeDir(isodir, o_path, pattern, r, True))

@ -16,6 +16,7 @@ from .distro import *
from .syslinux import *
from .install import *
from . import imager
from . import syslinux
def read_input_uninstall():
@ -99,6 +100,7 @@ def iso_install(iso_image):
install_progress()
syslinux_distro_dir(config.usb_disk, iso_image, _distro)
syslinux_default(config.usb_disk)
replace_grub_binary()
update_distro_cfg_files(iso_image, config.usb_disk, _distro)
log('Finished installing ' + iso.iso_basename(iso_image))
else:
@ -110,6 +112,7 @@ def iso_install(iso_image):
install_progress()
syslinux_distro_dir(config.usb_disk, iso_image, _distro)
syslinux_default(config.usb_disk)
replace_grub_binary()
update_distro_cfg_files(iso_image, config.usb_disk, _distro)
log('Finished installing ' + iso.iso_basename(iso_image))
else:
@ -167,3 +170,40 @@ def cli_dd():
else:
log('\nAuto install is not recommended in direct writing method. Please choose without \'-y\' option.\n')
sys.exit(2)
def cli_install_syslinux():
"""
Install syslinux on a target USB disk. It will installed on 'multibootusb' directory
:return:
"""
if platform.system() == 'Linux':
if config.usb_disk[-1].isdigit() is not True:
log('Selected USB disk is not a partition. Please enter the partition eg. \'/dev/sdb1\'')
sys.exit(2)
elif is_root() is False:
log("You need to have root privileges to run this script.\nPlease try again using admin privilege (sudo).")
sys.exit(2)
if config.yes is not True:
log('\nInitiating process for installing syslinux on ' + config.usb_disk)
log('Selected target device is : ' + quote(config.usb_disk))
log('Syslinux install directory : \'multibootusb\'\n')
log('Please confirm the option.')
log('Y/y/Yes/yes/YES or N/n/No/no/NO')
if read_input_yes() is True:
if syslinux.syslinux_default(config.usb_disk) is True:
log('Syslinux successfully installed on ' + config.usb_disk)
else:
log('Failed to install syslinux on ' + config.usb_disk)
else:
log('Operation cancelled by user. Exiting...')
sys.exit(2)
else:
log('\nSkipping user input and installing syslinux on ' + config.usb_disk)
if syslinux.syslinux_default(config.usb_disk) is True:
log('Syslinux successfully installed on ' + config.usb_disk)
else:
log('Failed to install syslinux on ' + config.usb_disk)
sys.exit(2)

@ -13,6 +13,7 @@ import signal
from PyQt5 import QtCore, QtGui, QtWidgets
import subprocess
import time
import webbrowser
from scripts.gui.ui_multibootusb import Ui_MainWindow
from scripts.gui.ui_about import Ui_About
from . import usb
@ -130,7 +131,7 @@ Are you SURE you want to enable it?",
about.setWindowTitle("About MultiBootUSB - " + mbusb_version())
about.setWindowIcon(QtGui.QIcon(resource_path(os.path.join("data", "tools", "multibootusb.png"))))
about.ui.button_close.clicked.connect(about.close)
about.ui.label_6.linkActivated.connect(webbrowser.open_new_tab)
about.exec_()
def onComboChange(self):
@ -157,6 +158,9 @@ Are you SURE you want to enable it?",
self.ui.usb_type.setText(config.usb_details.get('devtype', ""))
self.ui.usb_fs.setText(config.usb_details.get('file_system', ""))
# Get the GPT status of the disk and store it on a variable
usb.gpt_device(config.usb_disk)
self.update_list_box(config.usb_disk)
self.ui_update_persistence()
else:
@ -214,6 +218,22 @@ Are you SURE you want to enable it?",
'Img Files(*.img);; All Files(*.*)')[0]
if config.image_path:
# sanity checks
if not is_readable(config.image_path):
QtWidgets.QMessageBox.critical(
self,
"ISO Not readable",
"Sorry, the file \"{0}\" is not readable.".format(config.image_path)
)
return
if iso_size(config.image_path) == 0:
QtWidgets.QMessageBox.critical(
self,
"ISO is an empty file",
"Sorry, the file \"{0}\" contains no data.".format(config.image_path)
)
return
default_dir_path = os.path.dirname(config.image_path)
gen.write_to_file(preference_file_path, default_dir_path)
@ -309,6 +329,7 @@ Are you SURE you want to enable it?",
self.ui.statusbar.showMessage(str("Status: Installing Syslinux..."))
syslinux_distro_dir(config.usb_disk, config.image_path, config.distro)
syslinux_default(config.usb_disk)
replace_grub_binary()
update_distro_cfg_files(config.image_path, config.usb_disk, config.distro, config.persistence)
self.update_list_box(config.usb_disk)
if sys.platform.startswith("linux"):
@ -508,14 +529,23 @@ Are you SURE you want to enable it?",
"No space available on " + config.usb_disk)
self.ui_enable_controls()
else:
reply = QtWidgets.QMessageBox.question(self, 'Review selection...',
'Selected USB disk: %s\n' % config.usb_disk +
'USB mount point: %s\n' % config.usb_mount +
'Selected distro: %s\n\n' % iso_name(
config.image_path) +
'Proceed with installation?',
QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No,
QtWidgets.QMessageBox.No)
if config.distro == 'memdisk_iso':
reply = QtWidgets.QMessageBox.question(self, 'Review selection...',
'The ISO sleceted is not supported at the moment.\n'
'You can try booting ISO using memdisk.\n'
'Distro can be uninstalled anytime from main menu.\n\n'
'Proceed with installation?',
QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No,
QtWidgets.QMessageBox.No)
else:
reply = QtWidgets.QMessageBox.question(self, 'Review selection...',
'Selected USB disk: %s\n' % config.usb_disk +
'USB mount point: %s\n' % config.usb_mount +
'Selected distro: %s\n\n' % iso_name(
config.image_path) +
'Proceed with installation?',
QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No,
QtWidgets.QMessageBox.No)
if reply == QtWidgets.QMessageBox.Yes:
self.ui.slider_persistence.setEnabled(False)

@ -19,23 +19,72 @@ syslinux_path = os.path.join(multibootusb_host_dir(), "syslinux", "bin", "syslin
extlinux_fs = ["ext2", "ext3", "ext4", "Btrfs"]
syslinux_fs = ["vfat", "ntfs", "FAT32", "NTFS"]
mbr_bin = resource_path(os.path.join("data", "tools", "mbr.bin"))
win_gdisk = resource_path(os.path.join('data', 'tools', 'gdisk', 'gdisk.exe'))
def gpt_part_table(usb_disk):
"""
Check if selected USB contain GPT or MBR partition table
:return: True if GPT else False
"""
if platform.system() == "Linux":
_cmd_out = subprocess.check_output("parted " + usb_disk[:-1] + " print", shell=True)
if b'msdos' in _cmd_out:
return False
elif b'gpt' in _cmd_out:
return True
elif platform.system() == 'Windows':
win_usb_disk_no = str(usb.get_physical_disk_number(config.usb_disk))
if config.usb_gpt is True:
return True
elif config.usb_gpt is False:
return False
def get_mbr_bin_path(usb_disk):
"""
Check if partition table type is mbr or gpr using parted command under Linux
:param usb_disk: path to whole USB disk '/dev/sdb'
:return: Path to mbr.bin for use
"""
if config.usb_gpt is False:
log('Using mbr.bin msdos mbr install.')
return resource_path(os.path.join("data", "tools", "mbr.bin"))
elif config.usb_gpt is True:
log('Using gptmbr.bin for mbr install.')
return resource_path(os.path.join("data", "tools", "gptmbr.bin"))
return False
def set_boot_flag(usb_disk):
if platform.system() == "Linux":
log("\nChecking boot flag on " + usb_disk[:-1], '\n')
cmd_out = subprocess.check_output("parted -m -s " + usb_disk[:-1] + " print", shell=True)
if b'boot' in cmd_out:
log("\nDisk " + usb_disk[:-1] + " already has boot flag.\n")
return True
else:
log("\nExecuting ==> parted " + usb_disk[:-1] + " set 1 boot on", '\n')
if subprocess.call("parted " + usb_disk[:-1] + " set 1 boot on", shell=True) == 0:
log("\nBoot flag set to bootable " + usb_disk[:-1], '\n')
if gpt_part_table(usb_disk) is False:
if b'boot' in cmd_out:
log("\nDisk " + usb_disk[:-1] + " already has boot flag.\n")
return True
else:
log("\nUnable to set boot flag on " + usb_disk[:-1], '\n')
return False
log("\nExecuting ==> parted " + usb_disk[:-1] + " set 1 boot on", '\n')
if subprocess.call("parted " + usb_disk[:-1] + " set 1 boot on", shell=True) == 0:
log("\nBoot flag set to bootable " + usb_disk[:-1], '\n')
return True
else:
log("\nUnable to set boot flag on " + usb_disk[:-1], '\n')
return False
elif gpt_part_table(usb_disk) is True:
if b'legacy_boot' in cmd_out:
log("\nGPT Disk " + usb_disk[:-1] + " already has legacy_boot flag.\n")
return True
else:
log("\nExecuting ==> parted " + usb_disk[:-1] + " set 1 legacy_boot on", '\n')
if subprocess.call("parted " + usb_disk[:-1] + " set 1 legacy_boot on", shell=True) == 0:
log("\nBoot flag set to legacy_boot " + usb_disk[:-1], '\n')
return True
else:
log("\nUnable to set legacy_boot flag on " + usb_disk[:-1], '\n')
return False
def syslinux_default(usb_disk):
@ -48,8 +97,17 @@ def syslinux_default(usb_disk):
usb_details = usb.details(usb_disk)
usb_fs = usb_details['file_system']
usb_mount = usb_details['mount_point']
mbr_install_cmd = 'dd bs=440 count=1 conv=notrunc if=' + mbr_bin + ' of=' + usb_disk[:-1]
# log(usb_fs)
mbr_bin = get_mbr_bin_path(usb_disk)
if platform.system() == 'Linux':
mbr_install_cmd = 'dd bs=440 count=1 conv=notrunc if=' + mbr_bin + ' of=' + usb_disk[:-1]
else:
win_usb_disk_no = str(usb.get_physical_disk_number(config.usb_disk))
_windd = resource_path(os.path.join("data", "tools", "dd", "dd.exe"))
_input = "if=" + mbr_bin
_output = 'of=\\\.\\physicaldrive' + win_usb_disk_no
mbr_install_cmd = _windd + ' ' + _input + ' ' + _output + ' count=1'
if usb_fs in extlinux_fs:
extlinu_cmd = extlinux_path + ' --install ' + os.path.join(usb_mount, 'multibootusb')
if os.access(extlinux_path, os.X_OK) is False:
@ -78,6 +136,7 @@ def syslinux_default(usb_disk):
if subprocess.call(syslinux_cmd, shell=True) == 0:
log("\nDefault syslinux install is success...\n")
config.status_text = 'Default syslinux successfully installed...'
log('\nExecuting ==> ' + mbr_install_cmd)
if subprocess.call(mbr_install_cmd, shell=True) == 0:
config.status_text = 'mbr install is success...'
log("\nmbr install is success...\n")
@ -90,12 +149,35 @@ def syslinux_default(usb_disk):
elif platform.system() == "Windows":
syslinux = resource_path(os.path.join(multibootusb_host_dir(), "syslinux", "bin", "syslinux4.exe"))
log('Executing ==>' + syslinux + ' -maf -d multibootusb ' + usb_disk)
config.status_text = 'Installing default syslinux version 4...'
if subprocess.call(syslinux + ' -maf -d multibootusb ' + usb_disk, shell=True) == 0:
# syslinux_cmd = syslinux + ' -maf -d multibootusb ' + usb_disk
if config.usb_gpt is False:
syslinux_cmd = syslinux + ' -maf -d multibootusb ' + usb_disk
else:
syslinux_cmd = syslinux + ' -af -d multibootusb ' + usb_disk
log('Executing ==> ' + syslinux_cmd)
'''
if gpt_part_table(config.usb_disk) is False:
syslinux_cmd = syslinux + ' -maf -d multibootusb ' + usb_disk
else:
syslinux_cmd = syslinux + ' -af -d multibootusb ' + usb_disk
'''
if subprocess.call(syslinux_cmd, shell=True) == 0:
config.status_text = 'Default syslinux successfully installed...'
log("\nDefault syslinux install is success...\n")
return True
# We will need to flash gptmbr.bin only for GPT disk. As of version 8.9.0 this corrupts the gpt disk.
# Therefore not included for BIOS booting. GPT disk may work on UEFI system.
# if gpt_part_table(config.usb_disk) is True:
'''
if config.usb_gpt is False:
log('\nExecuting ==> ' + mbr_install_cmd)
if subprocess.call(mbr_install_cmd, shell=True) == 0:
log("\nmbr install is success...\n")
return True
else:
log('Disk uses GPT and mbr install is not required...')
'''
else:
log("\nFailed to install default syslinux...\n")
config.status_text = 'Failed to install default syslinux...'
@ -203,6 +285,51 @@ def syslinux_distro_dir(usb_disk, iso_link, distro):
else:
log("\nFailed to install syslinux on distro directory...\n")
def replace_grub_binary():
"""
This function checks if correct binary is installed on grub and EFI directory.
If mismatch is found between partition table and binary, replace it correct one.
Default binaries will work for msdos partition table and therefore need not be replaced.
:return:
"""
grub_efi_bin_path = os.path.join(config.usb_mount, 'EFI', 'BOOT', 'bootx64.efi')
grub_efi_bin_gpt_path = os.path.join(config.usb_mount, 'EFI', 'BOOT', 'bootx64-gpt.efi')
grub_efi_bin_msdos_path = os.path.join(config.usb_mount, 'EFI', 'BOOT', 'bootx64-msdos.efi')
core_img_bin_path = os.path.join(config.usb_mount, 'multibootusb', 'grub', 'core.img')
core_img_bin_msdos_path = os.path.join(config.usb_mount, 'multibootusb', 'grub', 'core-msdos.img')
core_img_bin_gpt_path = os.path.join(config.usb_mount, 'multibootusb', 'grub', 'core-gpt.img')
if platform.system() in ['Linux', 'Windows']:
if gpt_part_table(config.usb_disk) is True:
log('Replacing efi binary with gpt compatible one...')
try:
shutil.copy(grub_efi_bin_gpt_path, grub_efi_bin_path)
except Exception as e:
log(e)
log('Failed to replace efi binary...')
log('Replacing core.img binary with gpt compatible one...')
try:
shutil.copy(core_img_bin_gpt_path, core_img_bin_path)
except Exception as e:
log(e)
log('Failed to replace efi binary...')
else:
log('Replacing efi binary with msdos compatible one...')
try:
# shutil.copy(core_img_bin_gpt_path, core_img_bin_path)
shutil.copy(grub_efi_bin_msdos_path, grub_efi_bin_path)
except Exception as e:
log(e)
log('Failed to replace efi binary...')
try:
log('Replacing core.img with msdos compatible one...')
shutil.copy(core_img_bin_msdos_path, core_img_bin_path)
except Exception as e:
log(e)
log('Failed to replace core.img binary...')
if __name__ == '__main__':
if os.geteuid() != 0:
log('Please running this script with sudo/root/admin privilage.')

@ -13,6 +13,7 @@ import shutil
import collections
import ctypes
import subprocess
from . import config
from . import gen
if platform.system() == 'Linux':
from . import udisks
@ -218,7 +219,11 @@ def details_udev(usb_disk_part):
gen.log("ERROR: Unknown disk/partition (%s)" % str(usb_disk_part))
return None
fdisk_cmd_out = subprocess.check_output('fdisk -l ' + usb_disk_part, shell=True)
try:
fdisk_cmd_out = subprocess.check_output('fdisk -l ' + usb_disk_part, shell=True)
except subprocess.CalledProcessError:
gen.log("ERROR: fdisk failed on disk/partition (%s)" % str(usb_disk_part))
return None
if b'Extended' in fdisk_cmd_out:
mount_point = ''
@ -349,6 +354,43 @@ def bytes2human(n):
return "%sB" % n
def gpt_device(dev_name):
"""
Find if the device inserted is GPT or not. We will just change the variable parameter in config file for later use
:param dev_name:
:return: True if GPT else False
"""
if platform.system() == 'Windows':
diskpart_cmd = 'diskpart.exe /s ' + os.path.join('data', 'tools', 'gdisk', 'list-disk.txt')
dev_no = get_physical_disk_number(dev_name)
cmd_out = subprocess.check_output(diskpart_cmd)
cmd_spt = cmd_out.split(b'\r')
for line in cmd_spt:
line = line.decode('utf-8')
if 'Disk ' + dev_no in line:
if '*' not in line.split()[-1]:
config.usb_gpt = False
gen.log('Device ' + dev_name + ' is a MBR disk...')
return False
else:
config.usb_gpt = True
gen.log('Device ' + dev_name + ' is a GPT disk...')
return False
if platform.system() == "Linux":
if gen.has_digit(dev_name):
_cmd_out = subprocess.check_output("parted " + dev_name[:-1] + " print", shell=True)
else:
_cmd_out = subprocess.check_output("parted " + dev_name + " print", shell=True)
if b'msdos' in _cmd_out:
config.usb_gpt = False
gen.log('Device ' + dev_name + ' is a MBR disk...')
return False
elif b'gpt' in _cmd_out:
config.usb_gpt = True
gen.log('Device ' + dev_name + ' is a GPT disk...')
return True
def win_disk_details(disk_drive):
"""
Populate and get details of an USB disk under windows. Minimum required windows version is Vista.
@ -421,8 +463,26 @@ def details(usb_disk_part):
details = details_udisks2(usb_disk_part)
elif platform.system() == 'Windows':
details = win_disk_details(usb_disk_part)
return details
def get_physical_disk_number(usb_disk):
"""
Get the physical disk number as detected ny Windows.
:param usb_disk: USB disk (Like F:)
:return: Disk number.
"""
import wmi
c = wmi.WMI()
for physical_disk in c.Win32_DiskDrive():
for partition in physical_disk.associators("Win32_DiskDriveToDiskPartition"):
for logical_disk in partition.associators("Win32_LogicalDiskToPartition"):
if logical_disk.Caption == usb_disk:
# gen.log("Physical Device Number is " + partition.Caption[6:-14])
return str(partition.Caption[6:-14])
if __name__ == '__main__':
usb_devices = list_devices()
if usb_devices is not None:

Loading…
Cancel
Save