From be8c0d2e628c0c8d1e2ea9cad3eedb21ad1975b8 Mon Sep 17 00:00:00 2001 From: Sundar Date: Sat, 30 Dec 2017 23:16:23 +0530 Subject: [PATCH 1/8] version file update --- data/version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/version.txt b/data/version.txt index e5c1510..f7ee066 100644 --- a/data/version.txt +++ b/data/version.txt @@ -1 +1 @@ -8.9.0 +9.0.0 From f4bd0343bb673eb4b0458b177f835d0f5120d5dc Mon Sep 17 00:00:00 2001 From: Sundar Date: Wed, 3 Jan 2018 21:00:42 +0530 Subject: [PATCH 2/8] Include missing files in setup.py --- setup.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 500fe61..a5d31e0 100644 --- a/setup.py +++ b/setup.py @@ -77,6 +77,8 @@ setup( ('/usr/share/multibootusb/data/multibootusb', ["data/multibootusb/syslinux.cfg"]), ('/usr/share/multibootusb/data/multibootusb', ["data/multibootusb/vesamenu.c32"]), ('/usr/share/multibootusb/data/multibootusb/grub', root_files('data/multibootusb/grub')), - ('/usr/share/multibootusb/data/multibootusb/grub/i386-pc', get_data('data/multibootusb/grub')), + ('/usr/share/multibootusb/data/multibootusb/grub/i386-pc', get_data('data/multibootusb/grub/i386-pc')), + ('/usr/share/multibootusb/data/multibootusb/grub/x86_64-efi', get_data('data/multibootusb/grub/x86_64-efi')), + ('/usr/share/multibootusb/data/multibootusb/grub/menus', get_data('data/multibootusb/grub/menus')), ('/usr/share/multibootusb/data/tools/syslinux', get_data('data/tools/syslinux'))] ) From 89ca0a94cad83202c0057666c94d822db802aba5 Mon Sep 17 00:00:00 2001 From: Sundar Date: Thu, 4 Jan 2018 00:41:00 +0530 Subject: [PATCH 3/8] New release - version 9.1.0 --- .gitignore | 3 +++ CHANGELOG | 6 ++++++ build_pkg | 7 +++++++ scripts/gen.py | 7 +++++++ setup.py | 8 +++++--- 5 files changed, 28 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index c8969d3..bd763b8 100644 --- a/.gitignore +++ b/.gitignore @@ -95,6 +95,9 @@ ENV/ # Source file multibootusb*.tar.gz +# Temp files +data/multibootusb/grub/menus.zip + # Setup file multibootusb*.exe diff --git a/CHANGELOG b/CHANGELOG index 9f25cf1..ad83534 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,9 @@ +Version - 9.1.0 +--------------- +* Included missing EFI modules +* Fix for application crashing crashing on windows system +* New option to boot distros directly from ISOs. To availe this option, you need to copy ISO files in /multibootusb/iso + Version - 9.0.0 --------------- * Improved UEFI support diff --git a/build_pkg b/build_pkg index 4b8fd1a..ae4021c 100644 --- a/build_pkg +++ b/build_pkg @@ -309,7 +309,14 @@ def usage(): sys.exit(-1) + if __name__ == '__main__': + # Ensure to pack all menus to packaging directory + if os.path.exists(os.path.join('data', 'multibootusb', 'grub', 'menus.zip')): + os.remove(os.path.join('data', 'multibootusb', 'grub', 'menus.zip')) + shutil.make_archive(os.path.join('data', 'multibootusb', 'grub', 'menus'), + 'zip', os.path.join('data', 'multibootusb', 'grub', 'menus')) + if platform.system() == 'Linux': print('Converting line ending to Linux for proper functioning.') os.system('dos2unix multibootusb') diff --git a/scripts/gen.py b/scripts/gen.py index d047873..195e4c3 100644 --- a/scripts/gen.py +++ b/scripts/gen.py @@ -264,6 +264,13 @@ def copy_mbusb_dir_usb(usb_disk): if not os.path.exists(os.path.join(usb_mount_path, 'multibootusb', 'iso')): os.makedirs(os.path.join(usb_mount_path, 'multibootusb', 'iso')) + # Update the menu files from resource path to USB directory. + try: + with zipfile.ZipFile(resource_path(os.path.join('data', 'multibootusb', 'grub', 'menus.zip')), "r") as z: + z.extractall(os.path.join(usb_mount_path, 'multibootusb', 'grub', 'menus')) + except: + log('Unable to extract menu files to USB disk.') + return result diff --git a/setup.py b/setup.py index a5d31e0..82eec3b 100644 --- a/setup.py +++ b/setup.py @@ -10,6 +10,7 @@ from distutils.core import setup #from setuptools import setup, find_packages import os from scripts.gen import mbusb_version +import shutil Version = mbusb_version() @@ -48,7 +49,8 @@ setup( version=Version, packages=['scripts', 'scripts.pyudev', 'scripts.pyudev.device', 'scripts.pyudev._ctypeslib', 'scripts.pyudev._os', 'scripts.gui', 'scripts.progressbar'], - #packages=find_packages(), + # packages=find_packages(), + include_package_data=True, scripts=['multibootusb', 'multibootusb-pkexec'], platforms=['Linux'], url='http://multibootusb.org/', @@ -56,7 +58,8 @@ setup( author='Sundar', author_email='feedback.multibootusb@gmail.com', description='Create multi boot live Linux on a USB disk...', - long_description='multibootusb is an advanced cross-platform application for installing/uninstalling Linux operating systems on to a single USB flash drives.', + long_description='multibootusb is an advanced cross-platform application for installing/uninstalling Linux operating \ + systems on to a single USB flash drives.', data_files=[("/usr/share/applications", ["data/multibootusb.desktop"]), ('/usr/share/pixmaps', ["data/tools/multibootusb.png"]), ('/usr/share/polkit-1/actions/', ['org.debian.pkexec.run-multibootusb.policy']), @@ -79,6 +82,5 @@ setup( ('/usr/share/multibootusb/data/multibootusb/grub', root_files('data/multibootusb/grub')), ('/usr/share/multibootusb/data/multibootusb/grub/i386-pc', get_data('data/multibootusb/grub/i386-pc')), ('/usr/share/multibootusb/data/multibootusb/grub/x86_64-efi', get_data('data/multibootusb/grub/x86_64-efi')), - ('/usr/share/multibootusb/data/multibootusb/grub/menus', get_data('data/multibootusb/grub/menus')), ('/usr/share/multibootusb/data/tools/syslinux', get_data('data/tools/syslinux'))] ) From 1139faa5b8b721ac20e054416641668eca5b8d22 Mon Sep 17 00:00:00 2001 From: Gabriel Magno Date: Fri, 5 Jan 2018 14:25:18 -0200 Subject: [PATCH 4/8] Fix parted magic grub label --- scripts/update_cfg_file.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/update_cfg_file.py b/scripts/update_cfg_file.py index 43ffba5..6fb818a 100644 --- a/scripts/update_cfg_file.py +++ b/scripts/update_cfg_file.py @@ -106,7 +106,7 @@ def update_distro_cfg_files(iso_link, usb_disk, distro, persistence=0): flags=re.I) string = re.sub(r'linux_32=\"', 'linux_32=\"/multibootusb/' + iso_basename(iso_link), string, flags=re.I) - string = re.sub(r'initrd_img=\"', 'linux_32=\"/multibootusb/' + iso_basename(iso_link), string, + string = re.sub(r'initrd_img=\"', 'initrd_img=\"/multibootusb/' + iso_basename(iso_link), string, flags=re.I) string = re.sub(r'initrd_img32=\"', 'initrd_img32=\"/multibootusb/' + iso_basename(iso_link), string, flags=re.I) From 7657e7c70cb289bdce91199f2c069fe19944a493 Mon Sep 17 00:00:00 2001 From: Shinji Suzuki Date: Sat, 3 Mar 2018 06:13:10 +0900 Subject: [PATCH 5/8] Fixed dependency of get_physical_disk_number() on locale setting and removed code duplication. --- scripts/gen.py | 18 ++++++++++++++++++ scripts/qemu.py | 23 +++-------------------- scripts/syslinux.py | 5 ++--- scripts/usb.py | 20 ++------------------ 4 files changed, 25 insertions(+), 41 deletions(-) diff --git a/scripts/gen.py b/scripts/gen.py index 195e4c3..b5f4bf9 100644 --- a/scripts/gen.py +++ b/scripts/gen.py @@ -494,6 +494,24 @@ class MemoryCheck(): totalMemory = os.popen("free -m").readlines()[1].split()[1] return int(totalMemory) +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. + """ + assert platform.system() == 'Windows' + 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: + log("Physical Device Number is %d" % physical_disk.Index) + return physical_disk.Index + raise RuntimeError('Failed to obtain device number for drive ' + usb_disk) + + if __name__ == '__main__': log(quote("""Test-string""")) log(has_digit("test-string-with-01-digit")) diff --git a/scripts/qemu.py b/scripts/qemu.py index 4fb7a82..aa88547 100644 --- a/scripts/qemu.py +++ b/scripts/qemu.py @@ -85,10 +85,11 @@ class Qemu(QtWidgets.QMainWindow, Ui_MainWindow): ram = "" if platform.system() == "Windows": - disk_number = self.get_physical_disk_number(qemu_usb_disk) + disk_number = get_physical_disk_number(qemu_usb_disk) parent_dir = os.getcwd() os.chdir(resource_path(os.path.join("data", "tools", "qemu"))) - cmd = quote(qemu) + ' -L . -boot c' + ram + ' -hda //./PhysicalDrive' + disk_number + cmd = quote(qemu) + ' -L . -boot c' + ram \ + + ' -hda //./PhysicalDrive' + str(disk_number) try: log("Executing ==> " + cmd) @@ -156,21 +157,3 @@ class Qemu(QtWidgets.QMainWindow, Ui_MainWindow): return qemu - @staticmethod - 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: -# log physical_disk.Caption -# log partition.Caption -# log logical_disk.Caption - log("Physical Device Number is " + partition.Caption[6:-14]) - return str(partition.Caption[6:-14]) diff --git a/scripts/syslinux.py b/scripts/syslinux.py index 6b2906d..a187dd8 100644 --- a/scripts/syslinux.py +++ b/scripts/syslinux.py @@ -39,7 +39,6 @@ def gpt_part_table(usb_disk): 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: @@ -107,10 +106,10 @@ def syslinux_default(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)) + win_usb_disk_no = 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 + _output = 'of=\\\.\\physicaldrive' + str(win_usb_disk_no) mbr_install_cmd = _windd + ' ' + _input + ' ' + _output + ' count=1' if usb_fs in extlinux_fs: diff --git a/scripts/usb.py b/scripts/usb.py index 19f07bd..e964277 100644 --- a/scripts/usb.py +++ b/scripts/usb.py @@ -365,13 +365,13 @@ def gpt_device(dev_name): startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW diskpart_cmd = 'wmic partition get name, type' # We have to check using byte code else it crashes when system language is other than English - dev_no = get_physical_disk_number(dev_name).encode() + dev_no = gen.get_physical_disk_number(dev_name) cmd_out = subprocess.check_output(diskpart_cmd, subprocess.SW_HIDE, startupinfo=startupinfo) gen.log(cmd_out) cmd_spt = cmd_out.split(b'\r') for line in cmd_spt: # line = line('utf-8') - if b'#' + dev_no + b',' in line: + if b'#%d,' % dev_no in line: if b'GPT' not in line: config.usb_gpt = False gen.log('Device ' + dev_name + ' is a MBR disk...') @@ -472,22 +472,6 @@ def 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: From 07a0601a9a6c37ea2f7c00527808aa3329d21cfe Mon Sep 17 00:00:00 2001 From: Shinji Suzuki Date: Sat, 3 Mar 2018 09:21:46 +0900 Subject: [PATCH 6/8] Simplify implementation of get_physical_drive() using Win32_DiskPartition method rather than Win32_DiskDrive method. --- scripts/gen.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/scripts/gen.py b/scripts/gen.py index b5f4bf9..c8c64e6 100644 --- a/scripts/gen.py +++ b/scripts/gen.py @@ -503,12 +503,13 @@ def get_physical_disk_number(usb_disk): assert platform.system() == 'Windows' 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: - log("Physical Device Number is %d" % physical_disk.Index) - return physical_disk.Index + for partition in c.Win32_DiskPartition(): + logical_disks = partition.associators("Win32_LogicalDiskToPartition") + # Here, 'disk' is a windows logical drive rather than a physical drive + for disk in logical_disks: + if disk.Caption == usb_disk: + log("Physical Device Number is %d" % partition.DiskIndex) + return partition.DiskIndex raise RuntimeError('Failed to obtain device number for drive ' + usb_disk) From 1ac993077dea85381ca1a85db0929ffd25558597 Mon Sep 17 00:00:00 2001 From: Shinji Suzuki Date: Sat, 3 Mar 2018 17:05:34 +0900 Subject: [PATCH 7/8] Have gpt_device() use 'wmi' module rather than spawn diskpart.exe --- scripts/gen.py | 23 +++++++++++++---------- scripts/usb.py | 26 ++++++-------------------- 2 files changed, 19 insertions(+), 30 deletions(-) diff --git a/scripts/gen.py b/scripts/gen.py index c8c64e6..e468729 100644 --- a/scripts/gen.py +++ b/scripts/gen.py @@ -494,12 +494,7 @@ class MemoryCheck(): totalMemory = os.popen("free -m").readlines()[1].split()[1] return int(totalMemory) -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. - """ +def wmi_get_drive_info(usb_disk): assert platform.system() == 'Windows' import wmi c = wmi.WMI() @@ -508,10 +503,18 @@ def get_physical_disk_number(usb_disk): # Here, 'disk' is a windows logical drive rather than a physical drive for disk in logical_disks: if disk.Caption == usb_disk: - log("Physical Device Number is %d" % partition.DiskIndex) - return partition.DiskIndex - raise RuntimeError('Failed to obtain device number for drive ' + usb_disk) - + return (partition, disk) + raise RuntimeError('Failed to obtain drive information ' + usb_disk) + +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. + """ + partition, logical_disk = wmi_get_drive_info(usb_disk) + log("Physical Device Number is %d" % partition.DiskIndex) + return partition.DiskIndex if __name__ == '__main__': log(quote("""Test-string""")) diff --git a/scripts/usb.py b/scripts/usb.py index e964277..38ad6be 100644 --- a/scripts/usb.py +++ b/scripts/usb.py @@ -361,26 +361,12 @@ def gpt_device(dev_name): :return: True if GPT else False """ if platform.system() == 'Windows': - startupinfo = subprocess.STARTUPINFO() - startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW - diskpart_cmd = 'wmic partition get name, type' - # We have to check using byte code else it crashes when system language is other than English - dev_no = gen.get_physical_disk_number(dev_name) - cmd_out = subprocess.check_output(diskpart_cmd, subprocess.SW_HIDE, startupinfo=startupinfo) - gen.log(cmd_out) - cmd_spt = cmd_out.split(b'\r') - for line in cmd_spt: - # line = line('utf-8') - if b'#%d,' % dev_no in line: - if b'GPT' not in line: - 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 True - + partition, disk = gen.wmi_get_drive_info(dev_name) + is_gpt = partition.Type.startswith('GPT:') + gen.log('Device %s is a %s disk...' % + (dev_name, is_gpt and 'GPT' or 'MBR')) + config.usb_gpt = is_gpt + return is_gpt if platform.system() == "Linux": if gen.has_digit(dev_name): _cmd_out = subprocess.check_output("parted " + dev_name[:-1] + " print", shell=True) From 31a08eeb642843a111e670d5f753320a0ccad69d Mon Sep 17 00:00:00 2001 From: Shinji Suzuki Date: Sun, 4 Mar 2018 21:06:53 +0900 Subject: [PATCH 8/8] Avoid updating bootx64.efi and grub.img if source files are missing. --- scripts/syslinux.py | 54 ++++++++++++++++++--------------------------- 1 file changed, 22 insertions(+), 32 deletions(-) diff --git a/scripts/syslinux.py b/scripts/syslinux.py index a187dd8..b962618 100644 --- a/scripts/syslinux.py +++ b/scripts/syslinux.py @@ -297,42 +297,32 @@ def replace_grub_binary(): 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...') + # There used to be msdos/gpt specific files installed and relevant + # ones were copied to target files. But those specific files were + # removed by commit ec0f8d95f98f65541c8734623d97f4bd3cbecf0f. + # Therefore, as of commit d3c7aa7dc72b3d442c854a6a89071d3f5995ec27, + # code segment below is effectively no-op. + + if platform.system() not in ['Linux', 'Windows']: + return + + ptype = gpt_part_table(config.usb_disk) and '-gpt.' or '-msdos.' + + for dir_, fname in [ + (os.path.join(config.usb_mount, 'EFI', 'BOOT'), 'bootx64.efi'), + (os.path.join(config.usb_mount, 'multibootusb', 'grub'), 'grub.img') + ]: + base, ext = fname.split('.') + src = os.path.join(dir_, base + ptype + ext) + dst = os.path.join(dir_, fname) + if os.path.exists(src): try: - log('Replacing core.img with msdos compatible one...') - shutil.copy(core_img_bin_msdos_path, core_img_bin_path) + log('Replacing %s with %s...' % (dst, src)) + shutil.copy(src, dst) except Exception as e: log(e) - log('Failed to replace core.img binary...') - + log('Failed to replace %s with %s...' % (dst, src)) if __name__ == '__main__': if os.geteuid() != 0: