From 462832ba86efad2c09f34e8e4a8a4f1e31bc23c7 Mon Sep 17 00:00:00 2001 From: mbusb Date: Wed, 4 Apr 2018 23:34:36 +0530 Subject: [PATCH 01/11] Change mode due to FS change. --- build_pkg | 0 setup.py | 0 2 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 build_pkg mode change 100755 => 100644 setup.py diff --git a/build_pkg b/build_pkg old mode 100755 new mode 100644 diff --git a/setup.py b/setup.py old mode 100755 new mode 100644 From c71ed97282a2a0fb125e398ac08bd6fb8e131266 Mon Sep 17 00:00:00 2001 From: shinji-s Date: Sat, 12 May 2018 23:20:24 +0900 Subject: [PATCH 02/11] Catch an error generated while copying iso image to the target. --- scripts/imager.py | 82 ++++++++++++-------------------------------- scripts/mbusb_gui.py | 23 ++++++++----- scripts/osdriver.py | 76 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 113 insertions(+), 68 deletions(-) diff --git a/scripts/imager.py b/scripts/imager.py index 5862502..6ca882b 100644 --- a/scripts/imager.py +++ b/scripts/imager.py @@ -7,32 +7,26 @@ # under the terms of GNU General Public License, v.2 or above # WARNING : Any boot-able USB made using this module will destroy data stored on USB disk. -import os -import subprocess import collections +import io +import os import platform -import signal +import subprocess +import traceback + from PyQt5 import QtWidgets from .gui.ui_multibootusb import Ui_MainWindow from .gen import * -from . import iso from . import config +from . import iso +from . import osdriver from . import progressbar if platform.system() == "Windows": import win32com.client -def dd_linux(): - import time - _input = "if=" + config.image_path - in_file_size = float(os.path.getsize(config.image_path)) - _output = "of=" + config.usb_disk - os.system("umount " + config.usb_disk + "1") - command = ['dd', _input, _output, "bs=1M", "oflag=sync"] - log("Executing ==> " + " ".join(command)) - dd_process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False) - +def dd_iso_image(dd_progress_thread): pbar = progressbar.ProgressBar( maxval=100, widgets=[ @@ -43,52 +37,20 @@ def dd_linux(): ] ).start() - while dd_process.poll() is None: - time.sleep(0.1) # If this time delay is not given, the Popen does not execute the actual command - dd_process.send_signal(signal.SIGUSR1) - dd_process.stderr.flush() - while True: - time.sleep(0.1) - out_error = dd_process.stderr.readline().decode() - if out_error: - if 'bytes' in out_error: - copied = int(out_error.split(' ', 1)[0]) - config.imager_percentage = round((float(copied) / float(in_file_size) * 100)) - pbar.update(config.imager_percentage) - break - - if dd_process.poll() is not None: - log("\nExecuting ==> sync") - os.sync() - log("ISO has been written to USB disk...") - return - - -def dd_win(): - - windd = resource_path(os.path.join("data", "tools", "dd", "dd.exe")) - if os.path.exists(resource_path(os.path.join("data", "tools", "dd", "dd.exe"))): - log("dd exist") - _input = "if=" + config.image_path - in_file_size = float(os.path.getsize(config.image_path) / 1024 / 1024) - _output = "of=\\\.\\" + config.usb_disk - command = [windd, _input, _output, "bs=1M", "--progress"] - log("Executing ==> " + " ".join(command)) - dd_process = subprocess.Popen(command, universal_newlines=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE, - shell=False) - while dd_process.poll() is None: - for line in iter(dd_process.stderr.readline, ''): - line = line.strip() - if 'error' in line.lower() or 'invalid' in line.lower(): - log("Error writing to disk...") - break - if line and line[-1] == 'M': - copied = float(line.strip('M').replace(',', '')) - config.imager_percentage = round((copied / float(in_file_size) * 100)) - - log("ISO has been written to USB disk...") - - return + def gui_update(percentage): + config.imager_percentage = percentage + pbar.update(percentage) + + try: + error = osdriver.dd_iso_image(config.image_path, config.usb_disk, + gui_update) + if error: + dd_progress_thread.set_error(error) + except: + o = io.StringIO() + traceback.print_exc(None, o) + log(o.getvalue()) + dd_progress_thread.set_error(o.getvalue()) class Imager(QtWidgets.QMainWindow, Ui_MainWindow): diff --git a/scripts/mbusb_gui.py b/scripts/mbusb_gui.py index 6e9c885..4b2203d 100644 --- a/scripts/mbusb_gui.py +++ b/scripts/mbusb_gui.py @@ -31,7 +31,7 @@ from .distro import * from .qemu import * from .iso import * # from .imager import * -from .imager import Imager, dd_linux, dd_win +from .imager import Imager, dd_iso_image from . import persistence from . import config from . import admin @@ -731,8 +731,15 @@ Proceed with installation?'''.lstrip() % \ config.process_exist = None msgBox = QtWidgets.QMessageBox() - msgBox.setText("Image succesfully written to USB disk.") - msgBox.setInformativeText("Reboot to boot from USB or test it from Boot ISO/USB tab."); + if self.progress_thread_dd.error: + title = "Failed to write the iso image to the USB disk." + msg = self.progress_thread_dd.error + else: + title = "Image succesfully written to USB disk." + msg = "Reboot to boot from USB or test it from " \ + "Boot ISO/USB tab." + msgBox.setText(title) + msgBox.setInformativeText(msg); msgBox.setStandardButtons(QtWidgets.QMessageBox.Ok) msgBox.setIcon(QtWidgets.QMessageBox.Information) msgBox.exec_() @@ -960,15 +967,15 @@ class DD_Progress(QtCore.QThread): def __init__(self): QtCore.QThread.__init__(self) - - if platform.system() == 'Linux': - self.thread = GenericThread(dd_linux) - elif platform.system() == 'Windows': - self.thread = GenericThread(dd_win) + self.error = None + self.thread = GenericThread(partial(dd_iso_image, self)) def __del__(self): self.wait() + def set_error(self, error): + self.error = error + def run(self): self.thread.start() while self.thread.isRunning(): diff --git a/scripts/osdriver.py b/scripts/osdriver.py index e1e593c..33dfa7a 100644 --- a/scripts/osdriver.py +++ b/scripts/osdriver.py @@ -2,9 +2,12 @@ import logging import logging.handlers import os import platform +import queue import shutil +import signal import subprocess import sys +import time def log(message, info=True, error=False, debug=False, _print=True): @@ -136,6 +139,30 @@ class Base: else: log("%s succeeded." % str(cmd)) + + def dd_iso_image(self, input_, output, gui_update): + in_file_size = os.path.getsize(input_) + + cmd = [self.dd_exe, 'if='+input_, 'of='+output, 'bs=1M'] + self.dd_iso_image_add_args(cmd, input_, output) + log('Executing => ' + str(cmd)) + kw_args = { + 'stdout' : subprocess.PIPE, + 'stderr' : subprocess.PIPE, + 'shell' : False, + } + self.add_dd_iso_image_popen_args(kw_args) + dd_process = subprocess.Popen(cmd, **kw_args) + errors = queue.Queue() + while dd_process.poll() is None: + self.dd_iso_image_readoutput(dd_process, gui_update, in_file_size, + errors) + if dd_process.returncode == 0: + return None + else: + return ''.join([errors.get() for i in range(errors.qsize())]) or \ + "'dd' returned exit-code:%d" % dd_process.returncode + class Windows(Base): def __init__(self): @@ -144,6 +171,26 @@ class Windows(Base): def dd_add_args(self, cmd_vec, input, output, bs, count): pass + def dd_iso_image_add_args(self, cmd_vec, input_, output): + cmd_vec.append('--progress') + + def add_dd_iso_image_popen_args(self, dd_iso_image_popen_args): + dd_iso_image_popen_args['universal_newlines'] = True + + def dd_iso_image_readoutput(self, dd_process, gui_update, in_file_size, + error_log): + for line in iter(dd_process.stderr.readline, ''): + line = line.strip() + if line and line[-1:] == 'M': + bytes_copied = float(line.rstrip('M').replace(',', '')) \ + * 1024 * 1024 + gui_update(byets_copied / in_file_size * 100.) + else: + if 16 < error_log.qsize(): + error_log.get() + error_log.put(line) + # Now the 'dd' process should have completed or going to soon. + def physical_disk(self, usb_disk): return r'\\.\physicaldrive%d' % get_physical_disk_number(usb_disk) @@ -158,6 +205,34 @@ class Linux(Base): def dd_add_args(self, cmd_vec, input, output, bs, count): cmd_vec.append('conv=notrunc') + def dd_iso_image_add_args(self, cmd_vec, input_, output): + cmd_vec.append('oflag=sync') + + def add_dd_iso_image_popen_args(self, dd_iso_image_popen_args): + pass + + def dd_iso_image_readoutput(self, dd_process, gui_update, in_file_size, + error_log): + # If this time delay is not given, the Popen does not execute + # the actual command + time.sleep(0.1) + dd_process.send_signal(signal.SIGUSR1) + dd_process.stderr.flush() + while True: + time.sleep(0.1) + out_error = dd_process.stderr.readline().decode() + if out_error: + if 'bytes' in out_error: + bytes_copied = float(out_error.split(' ', 1)[0]) + gui_update( bytes_copied / in_file_size * 100. ) + break + if 16 < error_log.qsize(): + error_log.get() + error_log.put(out_error) + else: + # stderr is closed + break + def physical_disk(self, usb_disk): return usb_disk.rstrip('0123456789') @@ -177,6 +252,7 @@ for func_name in [ 'run_dd', 'physical_disk', 'mbusb_log_file', + 'dd_iso_image', ]: globals()[func_name] = getattr(osdriver, func_name) From 6c8e518876b8b912ff3a4fdd6b19e728dbdbf67c Mon Sep 17 00:00:00 2001 From: Shinji Suzuki Date: Sun, 13 May 2018 04:49:13 +0900 Subject: [PATCH 03/11] Windows fix --- scripts/osdriver.py | 49 ++++++++++++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/scripts/osdriver.py b/scripts/osdriver.py index 33dfa7a..07bd8af 100644 --- a/scripts/osdriver.py +++ b/scripts/osdriver.py @@ -143,7 +143,8 @@ class Base: def dd_iso_image(self, input_, output, gui_update): in_file_size = os.path.getsize(input_) - cmd = [self.dd_exe, 'if='+input_, 'of='+output, 'bs=1M'] + cmd = [self.dd_exe, 'if=' + input_, + 'of=' + self.dd_iso_image_physical_disk(output), 'bs=1M'] self.dd_iso_image_add_args(cmd, input_, output) log('Executing => ' + str(cmd)) kw_args = { @@ -157,11 +158,9 @@ class Base: while dd_process.poll() is None: self.dd_iso_image_readoutput(dd_process, gui_update, in_file_size, errors) - if dd_process.returncode == 0: - return None - else: - return ''.join([errors.get() for i in range(errors.qsize())]) or \ - "'dd' returned exit-code:%d" % dd_process.returncode + error_list = [errors.get() for i in range(errors.qsize())] + return self.dd_iso_image_interpret_result( + dd_process.returncode, error_list) class Windows(Base): @@ -181,16 +180,32 @@ class Windows(Base): error_log): for line in iter(dd_process.stderr.readline, ''): line = line.strip() - if line and line[-1:] == 'M': - bytes_copied = float(line.rstrip('M').replace(',', '')) \ - * 1024 * 1024 - gui_update(byets_copied / in_file_size * 100.) - else: - if 16 < error_log.qsize(): - error_log.get() - error_log.put(line) + if line: + l = line.replace(',', '') + if l[-1:] == 'M': + bytes_copied = float(l.rstrip('M')) * 1024 * 1024 + elif l.isdigit(): + bytes_copied = float(l) + else: + if 16 < error_log.qsize(): + error_log.get() + error_log.put(line) + continue + gui_update(bytes_copied / in_file_size * 100.) + continue # Now the 'dd' process should have completed or going to soon. + def dd_iso_image_interpret_result(self, returncode, error_list): + # dd.exe always returns 0 + if any([ 'invalid' in s or 'error' in s for s + in [l.lower() for l in error_list] ]): + return '\n'.join(error_list) + else: + return None + + def dd_iso_image_physical_disk(self, usb_disk): + return '\\\\.\\' + usb_disk + def physical_disk(self, usb_disk): return r'\\.\physicaldrive%d' % get_physical_disk_number(usb_disk) @@ -233,6 +248,12 @@ class Linux(Base): # stderr is closed break + def dd_iso_image_interpret_result(self, returncode, error_list): + return None if returncode==0 else '\n'.join(error_list) + + def dd_iso_image_physical_disk(self, usb_disk): + return usb_disk.rstrip('0123456789') + def physical_disk(self, usb_disk): return usb_disk.rstrip('0123456789') From 7e3ef9795a18e7e89fd67f8e25887dce452ff98e Mon Sep 17 00:00:00 2001 From: Shinji Suzuki Date: Sun, 13 May 2018 19:14:58 +0900 Subject: [PATCH 04/11] Log OSError/IOError while attempting to unlzma syslinux modules. Fix typo in a log message. Perform syslinux module replacement for ubuntu. Remove no-op assignment. --- scripts/install.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/scripts/install.py b/scripts/install.py index 8bfc72b..5de34a4 100644 --- a/scripts/install.py +++ b/scripts/install.py @@ -198,11 +198,14 @@ def replace_syslinux_modules(syslinux_version, under_this_dir): try: with lzma.open(dst_path) as f: expanded = f.read() - except (OSError, IOError, lzma.LZMAError): + except lzma.LZMAError: + continue + except (OSError, IOError) as e: + log("%s while accessing %s." % (e, dst_path)) continue with open(dst_path, 'wb') as f: f.write(expanded) - log("Successfully dcompressed %s." % fname) + log("Successfully decompressed %s." % fname) continue try: os.remove(dst_path) @@ -230,13 +233,10 @@ def install_patch(): config.usb_mount, "multibootusb", iso_basename(config.image_path)) config.syslinux_version = isolinux_version(isolinux_path) - if config.distro == 'slitaz': + if config.distro in ['slitaz', 'ubunu']: replace_syslinux_modules(config.syslinux_version, distro_install_dir) - c32box_path = os.path.join(distro_install_dir, 'boot', 'isolinux', - 'c32box.c32') elif config.distro == 'gentoo': replace_syslinux_modules(config.syslinux_version, distro_install_dir) - elif config.distro == 'debian': iso_file_list = iso.iso_file_list(config.image_path) if not any(s.strip().lower().endswith("makeboot.sh") From 4cd545c3ac56cb24b69a0b0ac259a918db48c053 Mon Sep 17 00:00:00 2001 From: shinji-s Date: Mon, 14 May 2018 13:19:19 +0900 Subject: [PATCH 05/11] Unmount before dding iso. --- scripts/imager.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/scripts/imager.py b/scripts/imager.py index 6ca882b..8cd4ebd 100644 --- a/scripts/imager.py +++ b/scripts/imager.py @@ -21,6 +21,7 @@ from . import config from . import iso from . import osdriver from . import progressbar +from . import usb if platform.system() == "Windows": import win32com.client @@ -42,10 +43,11 @@ def dd_iso_image(dd_progress_thread): pbar.update(percentage) try: - error = osdriver.dd_iso_image(config.image_path, config.usb_disk, - gui_update) - if error: - dd_progress_thread.set_error(error) + with usb.UnmountedContext(config.usb_disk, config.update_usb_mount): + error = osdriver.dd_iso_image( + config.image_path, config.usb_disk, gui_update) + if error: + dd_progress_thread.set_error(error) except: o = io.StringIO() traceback.print_exc(None, o) From 6f75388450240642a13ff215f963cb2950f2eb46 Mon Sep 17 00:00:00 2001 From: Shinji Suzuki Date: Tue, 15 May 2018 02:17:31 +0900 Subject: [PATCH 06/11] Add warning about running 'mbr_install_cmd'. --- scripts/syslinux.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/scripts/syslinux.py b/scripts/syslinux.py index 8a8e1d4..48493fc 100644 --- a/scripts/syslinux.py +++ b/scripts/syslinux.py @@ -198,6 +198,12 @@ def syslinux_default(usb_disk): ''' if config.usb_gpt is False: log('\nExecuting ==> ' + mbr_install_cmd) + # + # Updating mbr using dd results in catastrophy. + # Windows will lose track of the filesystem and + # the target volume will go away. + # Never enable this code without proper work around! + # if subprocess.call(mbr_install_cmd, shell=True) == 0: log("\nmbr install is success...\n") return True From 354a8e66889678c2d690aff62fe9e6bf20da36de Mon Sep 17 00:00:00 2001 From: shinji-s Date: Tue, 15 May 2018 03:45:36 +0900 Subject: [PATCH 07/11] Unmount partitions before dding iso image. Catch more exceptions. Avoid using keyword 'type' for a variable name. --- scripts/imager.py | 36 +++++++++++++++++++++++++----------- scripts/udisks.py | 17 ++++++++++++----- scripts/usb.py | 2 +- 3 files changed, 38 insertions(+), 17 deletions(-) diff --git a/scripts/imager.py b/scripts/imager.py index 8cd4ebd..89e54ca 100644 --- a/scripts/imager.py +++ b/scripts/imager.py @@ -21,13 +21,22 @@ from . import config from . import iso from . import osdriver from . import progressbar +from . import udisks from . import usb if platform.system() == "Windows": import win32com.client - def dd_iso_image(dd_progress_thread): + try: + _dd_iso_image(dd_progress_thread) + except: + o = io.StringIO() + traceback.print_exc(None, o) + log(o.getvalue()) + dd_progress_thread.set_error(o.getvalue()) + +def _dd_iso_image(dd_progress_thread): pbar = progressbar.ProgressBar( maxval=100, widgets=[ @@ -42,17 +51,22 @@ def dd_iso_image(dd_progress_thread): config.imager_percentage = percentage pbar.update(percentage) + unmounted_contexts = [ + (usb.UnmountedContext(p[0], config.update_usb_mount), p[0]) for p + in udisks.find_partitions_on(config.usb_disk)] + really_unmounted = [] try: - with usb.UnmountedContext(config.usb_disk, config.update_usb_mount): - error = osdriver.dd_iso_image( - config.image_path, config.usb_disk, gui_update) - if error: - dd_progress_thread.set_error(error) - except: - o = io.StringIO() - traceback.print_exc(None, o) - log(o.getvalue()) - dd_progress_thread.set_error(o.getvalue()) + for c, pname in unmounted_contexts: + c.__enter__() + really_unmounted.append((c, pname)) + error = osdriver.dd_iso_image( + config.image_path, config.usb_disk, gui_update) + if error: + dd_progress_thread.set_error(error) + finally: + for c, pname in really_unmounted: + c.__exit__(None, None, None) + class Imager(QtWidgets.QMainWindow, Ui_MainWindow): diff --git a/scripts/udisks.py b/scripts/udisks.py index 0c330c6..be25ac1 100644 --- a/scripts/udisks.py +++ b/scripts/udisks.py @@ -15,18 +15,25 @@ import os import re -def node_mountpoint(node): +def de_mangle_mountpoint(raw): + return raw.replace('\\040', ' ').replace('\\011', '\t') \ + .replace('\\012', '\n').replace('\\0134', '\\') - def de_mangle(raw): - return raw.replace('\\040', ' ').replace('\\011', '\t').replace('\\012', - '\n').replace('\\0134', '\\') +def node_mountpoint(node): for line in open('/proc/mounts').readlines(): line = line.split() if line[0] == node: - return de_mangle(line[1]) + return de_mangle_mountpoint(line[1]) return None +def find_partitions_on(disk): + assert not disk[-1:].isdigit() + with open('/proc/mounts') as f: + relevant_lines = [l.split(' ') for l in f.readlines() + if l.startswith(disk)] + return [ [v[0], de_mangle_mountpoint(v[1])] + v[2:] for v + in relevant_lines ] class NoUDisks1(Exception): pass diff --git a/scripts/usb.py b/scripts/usb.py index ce02bc8..0fa56ee 100644 --- a/scripts/usb.py +++ b/scripts/usb.py @@ -476,7 +476,7 @@ class UnmountedContext: gen.log("Unmounted %s" % self.usb_disk) return self - def __exit__(self, type, value, traceback_): + def __exit__(self, type_, value, traceback_): if not self.is_relevant: return os.sync() # This should not be strictly necessary From 5b496c3a83164a5e457379c774ea6759ad10d982 Mon Sep 17 00:00:00 2001 From: shinji-s Date: Tue, 15 May 2018 03:49:17 +0900 Subject: [PATCH 08/11] Write to \\.\PhysicalDriveN instead of \\.\X: --- scripts/osdriver.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/scripts/osdriver.py b/scripts/osdriver.py index 07bd8af..dbb0d75 100644 --- a/scripts/osdriver.py +++ b/scripts/osdriver.py @@ -144,7 +144,7 @@ class Base: in_file_size = os.path.getsize(input_) cmd = [self.dd_exe, 'if=' + input_, - 'of=' + self.dd_iso_image_physical_disk(output), 'bs=1M'] + 'of=' + self.physical_disk(output), 'bs=1M'] self.dd_iso_image_add_args(cmd, input_, output) log('Executing => ' + str(cmd)) kw_args = { @@ -203,9 +203,6 @@ class Windows(Base): else: return None - def dd_iso_image_physical_disk(self, usb_disk): - return '\\\\.\\' + usb_disk - def physical_disk(self, usb_disk): return r'\\.\physicaldrive%d' % get_physical_disk_number(usb_disk) @@ -251,9 +248,6 @@ class Linux(Base): def dd_iso_image_interpret_result(self, returncode, error_list): return None if returncode==0 else '\n'.join(error_list) - def dd_iso_image_physical_disk(self, usb_disk): - return usb_disk.rstrip('0123456789') - def physical_disk(self, usb_disk): return usb_disk.rstrip('0123456789') From 24871b5af67362299697a09a301d8491fd4c3dfb Mon Sep 17 00:00:00 2001 From: mbusb Date: Tue, 15 May 2018 11:14:20 +0530 Subject: [PATCH 09/11] Fix for crash when using iso imager --- data/multibootusb/grub.exe | Bin multibootusb | 0 scripts/imager.py | 19 ++++++++++++++----- scripts/osdriver.py | 2 ++ 4 files changed, 16 insertions(+), 5 deletions(-) mode change 100755 => 100644 data/multibootusb/grub.exe mode change 100755 => 100644 multibootusb diff --git a/data/multibootusb/grub.exe b/data/multibootusb/grub.exe old mode 100755 new mode 100644 diff --git a/multibootusb b/multibootusb old mode 100755 new mode 100644 diff --git a/scripts/imager.py b/scripts/imager.py index 5862502..41f0d86 100644 --- a/scripts/imager.py +++ b/scripts/imager.py @@ -12,12 +12,14 @@ import subprocess import collections import platform import signal +import time from PyQt5 import QtWidgets from .gui.ui_multibootusb import Ui_MainWindow from .gen import * from . import iso from . import config from . import progressbar +from . import osdriver if platform.system() == "Windows": import win32com.client @@ -66,16 +68,23 @@ def dd_linux(): def dd_win(): - windd = resource_path(os.path.join("data", "tools", "dd", "dd.exe")) + windd = quote(resource_path(os.path.join("data", "tools", "dd", "dd.exe"))) + usb_disk_no = osdriver.get_physical_disk_number(config.usb_disk) if os.path.exists(resource_path(os.path.join("data", "tools", "dd", "dd.exe"))): log("dd exist") - _input = "if=" + config.image_path + _input = "if=" + config.image_path.strip() + print('.........>', _input) in_file_size = float(os.path.getsize(config.image_path) / 1024 / 1024) - _output = "of=\\\.\\" + config.usb_disk - command = [windd, _input, _output, "bs=1M", "--progress"] - log("Executing ==> " + " ".join(command)) + # _output = "of=\\\.\\PhysicalDrive" + str(usb_disk_no) + # of=\\.\PhysicalDrive1 + _output = "od=" + config.usb_disk + # command = [windd, _input, _output, "bs=1M", "--progress"] + command = windd + ' ' + _input + ' ' + _output + " bs=1M" + " --progress" + # log("Executing ==> " + " ".join(command)) + log("Executing ==> " + command) dd_process = subprocess.Popen(command, universal_newlines=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE, shell=False) + time.sleep(0.1) while dd_process.poll() is None: for line in iter(dd_process.stderr.readline, ''): line = line.strip() diff --git a/scripts/osdriver.py b/scripts/osdriver.py index e1e593c..d3d3aed 100644 --- a/scripts/osdriver.py +++ b/scripts/osdriver.py @@ -59,6 +59,8 @@ def get_physical_disk_number(usb_disk): :param usb_disk: USB disk (Like F:) :return: Disk number. """ + import pythoncom + pythoncom.CoInitialize() partition, logical_disk = wmi_get_drive_info(usb_disk) log("Physical Device Number is %d" % partition.DiskIndex) return partition.DiskIndex From 84393b83f85456c9e4c73b00513c7bb73469425c Mon Sep 17 00:00:00 2001 From: mbusb Date: Thu, 17 May 2018 13:12:29 +0530 Subject: [PATCH 10/11] Make Imager writing to entire disk rather than partition. --- scripts/config.py | 1 + scripts/imager.py | 33 +++++++++++++++++++++++++-------- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/scripts/config.py b/scripts/config.py index d6d1965..d4662a6 100644 --- a/scripts/config.py +++ b/scripts/config.py @@ -35,6 +35,7 @@ imager_usb_disk_selected = "" imager_lock = "" imager_percentage = "" imager_status_text = "" +imager_return = "" install_size = "" diff --git a/scripts/imager.py b/scripts/imager.py index 41f0d86..f8ef5bb 100644 --- a/scripts/imager.py +++ b/scripts/imager.py @@ -66,21 +66,35 @@ def dd_linux(): return +def dd_win_clean_usb(usb_disk_no): + """ + + """ + host_dir = multibootusb_host_dir() + temp_file = os.path.join(host_dir, "preference", "disk_part.txt") + diskpart_text_feed = 'select disk ' + str(usb_disk_no) + '\nclean\nexit' + write_to_file(temp_file, diskpart_text_feed) + config.status_text = 'Cleaning the disk...' + if subprocess.call('diskpart.exe -s ' + temp_file ) == 0: + return True + else: + return False + + def dd_win(): windd = quote(resource_path(os.path.join("data", "tools", "dd", "dd.exe"))) usb_disk_no = osdriver.get_physical_disk_number(config.usb_disk) - if os.path.exists(resource_path(os.path.join("data", "tools", "dd", "dd.exe"))): - log("dd exist") _input = "if=" + config.image_path.strip() - print('.........>', _input) in_file_size = float(os.path.getsize(config.image_path) / 1024 / 1024) - # _output = "of=\\\.\\PhysicalDrive" + str(usb_disk_no) + _output = "of=\\\.\\PhysicalDrive" + str(usb_disk_no) + if dd_win_clean_usb(usb_disk_no) is False: + return # of=\\.\PhysicalDrive1 - _output = "od=" + config.usb_disk + # _output = "od=" + config.usb_disk # 'od=' option should also work. # command = [windd, _input, _output, "bs=1M", "--progress"] command = windd + ' ' + _input + ' ' + _output + " bs=1M" + " --progress" - # log("Executing ==> " + " ".join(command)) + #log("Executing ==> " + " ".join(command)) log("Executing ==> " + command) dd_process = subprocess.Popen(command, universal_newlines=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE, shell=False) @@ -89,13 +103,16 @@ def dd_win(): for line in iter(dd_process.stderr.readline, ''): line = line.strip() if 'error' in line.lower() or 'invalid' in line.lower(): - log("Error writing to disk...") + config.imager_return = False break if line and line[-1] == 'M': copied = float(line.strip('M').replace(',', '')) config.imager_percentage = round((copied / float(in_file_size) * 100)) - log("ISO has been written to USB disk...") + if config.imager_return is False: + log("Error writing to disk...") + else: + log("ISO has been written to USB disk...") return From 696b1ff8f003e99ae72e6a3be2f4de174f4b690f Mon Sep 17 00:00:00 2001 From: mbusb Date: Thu, 17 May 2018 13:48:11 +0530 Subject: [PATCH 11/11] Include imager functionality again which was removed by previous git commit --- scripts/imager.py | 75 ++++++++++++++++++----------------------------- 1 file changed, 28 insertions(+), 47 deletions(-) diff --git a/scripts/imager.py b/scripts/imager.py index 217754d..763360c 100644 --- a/scripts/imager.py +++ b/scripts/imager.py @@ -32,13 +32,16 @@ if platform.system() == "Windows": import win32com.client def dd_iso_image(dd_progress_thread): - try: - _dd_iso_image(dd_progress_thread) - except: - o = io.StringIO() - traceback.print_exc(None, o) - log(o.getvalue()) - dd_progress_thread.set_error(o.getvalue()) + if platform.system() == "Windows": + dd_win() + else: + try: + _dd_iso_image(dd_progress_thread) + except: + o = io.StringIO() + traceback.print_exc(None, o) + log(o.getvalue()) + dd_progress_thread.set_error(o.getvalue()) def _dd_iso_image(dd_progress_thread): pbar = progressbar.ProgressBar( @@ -52,25 +55,25 @@ def _dd_iso_image(dd_progress_thread): ).start() - while dd_process.poll() is None: - time.sleep(0.1) # If this time delay is not given, the Popen does not execute the actual command - dd_process.send_signal(signal.SIGUSR1) - dd_process.stderr.flush() - while True: - time.sleep(0.1) - out_error = dd_process.stderr.readline().decode() - if out_error: - if 'bytes' in out_error: - copied = int(out_error.split(' ', 1)[0]) - config.imager_percentage = round((float(copied) / float(in_file_size) * 100)) - pbar.update(config.imager_percentage) - break + def gui_update(percentage): + config.imager_percentage = percentage + pbar.update(percentage) - if dd_process.poll() is not None: - log("\nExecuting ==> sync") - os.sync() - log("ISO has been written to USB disk...") - return + unmounted_contexts = [ + (usb.UnmountedContext(p[0], config.update_usb_mount), p[0]) for p + in udisks.find_partitions_on(config.usb_disk)] + really_unmounted = [] + try: + for c, pname in unmounted_contexts: + c.__enter__() + really_unmounted.append((c, pname)) + error = osdriver.dd_iso_image( + config.image_path, config.usb_disk, gui_update) + if error: + dd_progress_thread.set_error(error) + finally: + for c, pname in really_unmounted: + c.__exit__(None, None, None) def dd_win_clean_usb(usb_disk_no): @@ -97,7 +100,6 @@ def dd_win(): _output = "of=\\\.\\PhysicalDrive" + str(usb_disk_no) if dd_win_clean_usb(usb_disk_no) is False: return - # of=\\.\PhysicalDrive1 # _output = "od=" + config.usb_disk # 'od=' option should also work. # command = [windd, _input, _output, "bs=1M", "--progress"] command = windd + ' ' + _input + ' ' + _output + " bs=1M" + " --progress" @@ -123,27 +125,6 @@ def dd_win(): return - def gui_update(percentage): - config.imager_percentage = percentage - pbar.update(percentage) - - unmounted_contexts = [ - (usb.UnmountedContext(p[0], config.update_usb_mount), p[0]) for p - in udisks.find_partitions_on(config.usb_disk)] - really_unmounted = [] - try: - for c, pname in unmounted_contexts: - c.__enter__() - really_unmounted.append((c, pname)) - error = osdriver.dd_iso_image( - config.image_path, config.usb_disk, gui_update) - if error: - dd_progress_thread.set_error(error) - finally: - for c, pname in really_unmounted: - c.__exit__(None, None, None) - - class Imager(QtWidgets.QMainWindow, Ui_MainWindow): """