From 890c2663420cf4d4d4fec5fd11f5e39b22792c16 Mon Sep 17 00:00:00 2001 From: mbusb Date: Sat, 3 Dec 2016 15:36:47 +0530 Subject: [PATCH] Inform user about the requirement of admin privilege. Added option to list all drives (including fixed). Fixed the bug 'maximum 2047 mb allowed'. --- build_pkg | 0 multibootusb | 6 +- scripts/config.py | 2 + scripts/gui/multibootusb.ui | 194 +++++++++++++++++---------------- scripts/gui/ui_multibootusb.py | 114 ++++++++++--------- scripts/mbusb_gui.py | 56 ++++++++-- scripts/qemu.py | 5 +- scripts/usb.py | 67 ++++++++---- 8 files changed, 267 insertions(+), 177 deletions(-) mode change 100644 => 100755 build_pkg mode change 100644 => 100755 multibootusb diff --git a/build_pkg b/build_pkg old mode 100644 new mode 100755 diff --git a/multibootusb b/multibootusb old mode 100644 new mode 100755 index 2fd4b593..b46973d2 --- a/multibootusb +++ b/multibootusb @@ -43,8 +43,12 @@ def usage(): def start_gui(): - print('Starting multibootusb GUI...') from scripts import mbusb_gui + print('Starting multibootusb GUI...') + if platform.system() == 'Linux': + if os.getuid() != 0: + print('\n\n\nAdmin privilege is required to run multibootusb.\n If you are running from source try ' + '\'sudo python3 ./multibootusb\'\n or you can try \'multibootusb-pkexec\' (post install)\n\n\n') mbusb_gui.main_gui() diff --git a/scripts/config.py b/scripts/config.py index 74744f54..e80a1879 100644 --- a/scripts/config.py +++ b/scripts/config.py @@ -20,6 +20,8 @@ uninstall_distro_dir_path = "" iso_file_list = '' +process_exist = None + imager_iso_link = "" imager_usb_disk_selected = "" imager_lock = "" diff --git a/scripts/gui/multibootusb.ui b/scripts/gui/multibootusb.ui index 4d3b0f85..62fc9a3b 100644 --- a/scripts/gui/multibootusb.ui +++ b/scripts/gui/multibootusb.ui @@ -33,54 +33,18 @@ - - - - <html><head/><body><p align="center"><span style=" font-weight:600;">Step 3</span></p></body></html> - - - - - - - false - - - Choose Persistence size. Not all distros supports persistence... - - - false - - - Qt::Horizontal - - - QSlider::TicksBothSides - - - 0 - - - - - - - Close - - - - Detect USB + Detect - Refresh USB + Detect Drives @@ -89,6 +53,26 @@ + + + + + + + 0 + + + + + + + Create + + + + + + @@ -103,15 +87,41 @@ - - + + - Create + Close - - + + + + <html><head/><body><p align="center"><span style=" font-weight:600;">Step 3</span></p></body></html> + + + + + + + false + + + Choose Persistence size. Not all distros supports persistence... + + + false + + + Qt::Horizontal + + + QSlider::TicksBothSides + + + 0 + + @@ -133,55 +143,6 @@ - - - - Browse ISO - - - - - - - <html><head/><body><p><span style=" font-weight:600;">Persistence</span></p></body></html> - - - - - - - - - - 0 - - - - - - - - 0 - 0 - - - - false - - - false - - - QFrame::Plain - - - - - - false - - - @@ -229,6 +190,55 @@ + + + + Browse ISO + + + + + + + <html><head/><body><p><span style=" font-weight:600;">Persistence</span></p></body></html> + + + + + + + All Drives + + + + + + + + 0 + 0 + + + + false + + + false + + + QFrame::Plain + + + + + + Qt::AutoText + + + false + + + diff --git a/scripts/gui/ui_multibootusb.py b/scripts/gui/ui_multibootusb.py index 7bbb0d3f..d5c89131 100644 --- a/scripts/gui/ui_multibootusb.py +++ b/scripts/gui/ui_multibootusb.py @@ -1,8 +1,8 @@ # -*- coding: utf-8 -*- -# Form implementation generated from reading ui file 'scripts/gui/multibootusb.ui' +# Form implementation generated from reading ui file 'scripts\gui\multibootusb.ui' # -# Created by: PyQt5 UI code generator 5.5.1 +# Created by: PyQt5 UI code generator 5.6 # # WARNING! All changes made in this file will be lost! @@ -19,26 +19,13 @@ def setupUi(self, Dialog): self.tab_3 = QtWidgets.QWidget() self.tab_3.setObjectName("tab_3") self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.tab_3) + self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0) self.horizontalLayout_2.setObjectName("horizontalLayout_2") self.gridLayout = QtWidgets.QGridLayout() self.gridLayout.setObjectName("gridLayout") self.label_persistence_value = QtWidgets.QLabel(self.tab_3) self.label_persistence_value.setObjectName("label_persistence_value") self.gridLayout.addWidget(self.label_persistence_value, 5, 2, 1, 1) - self.labelstep3 = QtWidgets.QLabel(self.tab_3) - self.labelstep3.setObjectName("labelstep3") - self.gridLayout.addWidget(self.labelstep3, 5, 5, 1, 1) - self.slider_persistence = QtWidgets.QSlider(self.tab_3) - self.slider_persistence.setEnabled(False) - self.slider_persistence.setAutoFillBackground(False) - self.slider_persistence.setOrientation(QtCore.Qt.Horizontal) - self.slider_persistence.setTickPosition(QtWidgets.QSlider.TicksBothSides) - self.slider_persistence.setTickInterval(0) - self.slider_persistence.setObjectName("slider_persistence") - self.gridLayout.addWidget(self.slider_persistence, 5, 1, 1, 1) - self.close = QtWidgets.QPushButton(self.tab_3) - self.close.setObjectName("close") - self.gridLayout.addWidget(self.close, 5, 3, 1, 1) self.verticalLayout_11 = QtWidgets.QVBoxLayout() self.verticalLayout_11.setObjectName("verticalLayout_11") self.groupBox_11 = QtWidgets.QGroupBox(self.tab_3) @@ -50,18 +37,39 @@ def setupUi(self, Dialog): self.horizontalLayout_8.addWidget(self.detect_usb) self.verticalLayout_11.addWidget(self.groupBox_11) self.gridLayout.addLayout(self.verticalLayout_11, 1, 3, 1, 2) + self.listWidget = QtWidgets.QListWidget(self.tab_3) + self.listWidget.setObjectName("listWidget") + self.gridLayout.addWidget(self.listWidget, 0, 0, 4, 3) + self.progressBar = QtWidgets.QProgressBar(self.tab_3) + self.progressBar.setProperty("value", 0) + self.progressBar.setObjectName("progressBar") + self.gridLayout.addWidget(self.progressBar, 7, 0, 1, 6) + self.create = QtWidgets.QPushButton(self.tab_3) + self.create.setObjectName("create") + self.gridLayout.addWidget(self.create, 5, 4, 1, 1) + self.comboBox = QtWidgets.QComboBox(self.tab_3) + self.comboBox.setObjectName("comboBox") + self.gridLayout.addWidget(self.comboBox, 0, 3, 1, 1) self.labelstep1 = QtWidgets.QLabel(self.tab_3) self.labelstep1.setObjectName("labelstep1") self.gridLayout.addWidget(self.labelstep1, 0, 5, 1, 1) self.labelstep2 = QtWidgets.QLabel(self.tab_3) self.labelstep2.setObjectName("labelstep2") self.gridLayout.addWidget(self.labelstep2, 4, 5, 1, 1) - self.create = QtWidgets.QPushButton(self.tab_3) - self.create.setObjectName("create") - self.gridLayout.addWidget(self.create, 5, 4, 1, 1) - self.comboBox = QtWidgets.QComboBox(self.tab_3) - self.comboBox.setObjectName("comboBox") - self.gridLayout.addWidget(self.comboBox, 0, 3, 1, 2) + self.close = QtWidgets.QPushButton(self.tab_3) + self.close.setObjectName("close") + self.gridLayout.addWidget(self.close, 5, 3, 1, 1) + self.labelstep3 = QtWidgets.QLabel(self.tab_3) + self.labelstep3.setObjectName("labelstep3") + self.gridLayout.addWidget(self.labelstep3, 5, 5, 1, 1) + self.slider_persistence = QtWidgets.QSlider(self.tab_3) + self.slider_persistence.setEnabled(False) + self.slider_persistence.setAutoFillBackground(False) + self.slider_persistence.setOrientation(QtCore.Qt.Horizontal) + self.slider_persistence.setTickPosition(QtWidgets.QSlider.TicksBothSides) + self.slider_persistence.setTickInterval(0) + self.slider_persistence.setObjectName("slider_persistence") + self.gridLayout.addWidget(self.slider_persistence, 5, 1, 1, 1) self.groupBox = QtWidgets.QGroupBox(self.tab_3) self.groupBox.setObjectName("groupBox") self.verticalLayout = QtWidgets.QVBoxLayout(self.groupBox) @@ -73,28 +81,6 @@ def setupUi(self, Dialog): self.gridLayout_5.addWidget(self.uninstall, 0, 0, 1, 1) self.verticalLayout.addLayout(self.gridLayout_5) self.gridLayout.addWidget(self.groupBox, 3, 3, 1, 2) - self.browse_iso = QtWidgets.QPushButton(self.tab_3) - self.browse_iso.setObjectName("browse_iso") - self.gridLayout.addWidget(self.browse_iso, 4, 4, 1, 1) - self.label_persistence = QtWidgets.QLabel(self.tab_3) - self.label_persistence.setObjectName("label_persistence") - self.gridLayout.addWidget(self.label_persistence, 5, 0, 1, 1) - self.listWidget = QtWidgets.QListWidget(self.tab_3) - self.listWidget.setObjectName("listWidget") - self.gridLayout.addWidget(self.listWidget, 0, 0, 4, 3) - self.progressBar = QtWidgets.QProgressBar(self.tab_3) - self.progressBar.setProperty("value", 0) - self.progressBar.setObjectName("progressBar") - self.gridLayout.addWidget(self.progressBar, 7, 0, 1, 6) - self.status = QtWidgets.QLabel(self.tab_3) - self.status.setMinimumSize(QtCore.QSize(0, 0)) - self.status.setAcceptDrops(False) - self.status.setAutoFillBackground(False) - self.status.setFrameShadow(QtWidgets.QFrame.Plain) - self.status.setText("") - self.status.setScaledContents(False) - self.status.setObjectName("status") - self.gridLayout.addWidget(self.status, 6, 0, 1, 6) self.lineEdit = QtWidgets.QLineEdit(self.tab_3) self.lineEdit.setObjectName("lineEdit") self.gridLayout.addWidget(self.lineEdit, 4, 0, 1, 4) @@ -118,11 +104,31 @@ def setupUi(self, Dialog): self.usb_mount.setObjectName("usb_mount") self.verticalLayout_5.addWidget(self.usb_mount) self.gridLayout.addWidget(self.groupBox_6, 2, 3, 1, 3) + self.browse_iso = QtWidgets.QPushButton(self.tab_3) + self.browse_iso.setObjectName("browse_iso") + self.gridLayout.addWidget(self.browse_iso, 4, 4, 1, 1) + self.label_persistence = QtWidgets.QLabel(self.tab_3) + self.label_persistence.setObjectName("label_persistence") + self.gridLayout.addWidget(self.label_persistence, 5, 0, 1, 1) + self.checkBox_all_drives = QtWidgets.QCheckBox(self.tab_3) + self.checkBox_all_drives.setObjectName("checkBox_all_drives") + self.gridLayout.addWidget(self.checkBox_all_drives, 0, 4, 1, 1) + self.status = QtWidgets.QLabel(self.tab_3) + self.status.setMinimumSize(QtCore.QSize(0, 0)) + self.status.setAcceptDrops(False) + self.status.setAutoFillBackground(False) + self.status.setFrameShadow(QtWidgets.QFrame.Plain) + self.status.setText("") + self.status.setTextFormat(QtCore.Qt.AutoText) + self.status.setScaledContents(False) + self.status.setObjectName("status") + self.gridLayout.addWidget(self.status, 6, 0, 1, 6) self.horizontalLayout_2.addLayout(self.gridLayout) self.tabWidget.addTab(self.tab_3, "") self.imager = QtWidgets.QWidget() self.imager.setObjectName("imager") self.horizontalLayout_7 = QtWidgets.QHBoxLayout(self.imager) + self.horizontalLayout_7.setContentsMargins(0, 0, 0, 0) self.horizontalLayout_7.setObjectName("horizontalLayout_7") self.gridLayout_9 = QtWidgets.QGridLayout() self.gridLayout_9.setObjectName("gridLayout_9") @@ -206,6 +212,7 @@ def setupUi(self, Dialog): self.syslinux_ab = QtWidgets.QWidget() self.syslinux_ab.setObjectName("syslinux_ab") self.horizontalLayout_3 = QtWidgets.QHBoxLayout(self.syslinux_ab) + self.horizontalLayout_3.setContentsMargins(0, 0, 0, 0) self.horizontalLayout_3.setObjectName("horizontalLayout_3") self.gridLayout_2 = QtWidgets.QGridLayout() self.gridLayout_2.setObjectName("gridLayout_2") @@ -250,6 +257,7 @@ def setupUi(self, Dialog): self.tab = QtWidgets.QWidget() self.tab.setObjectName("tab") self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.tab) + self.verticalLayout_2.setContentsMargins(0, 0, 0, 0) self.verticalLayout_2.setObjectName("verticalLayout_2") self.groupBox_5 = QtWidgets.QGroupBox(self.tab) self.groupBox_5.setObjectName("groupBox_5") @@ -342,6 +350,7 @@ def setupUi(self, Dialog): self.tab_2 = QtWidgets.QWidget() self.tab_2.setObjectName("tab_2") self.horizontalLayout_6 = QtWidgets.QHBoxLayout(self.tab_2) + self.horizontalLayout_6.setContentsMargins(0, 0, 0, 0) self.horizontalLayout_6.setObjectName("horizontalLayout_6") self.gridLayout_10 = QtWidgets.QGridLayout() self.gridLayout_10.setObjectName("gridLayout_10") @@ -368,24 +377,25 @@ def retranslateUi(self, Dialog): _translate = QtCore.QCoreApplication.translate Dialog.setWindowTitle(_translate("Dialog", "multibootusb")) self.label_persistence_value.setText(_translate("Dialog", "0 MB")) - self.labelstep3.setText(_translate("Dialog", "

Step 3

")) - self.slider_persistence.setToolTip(_translate("Dialog", "Choose Persistence size. Not all distros supports persistence...")) - self.close.setText(_translate("Dialog", "Close")) - self.groupBox_11.setTitle(_translate("Dialog", "Detect USB")) - self.detect_usb.setText(_translate("Dialog", "Refresh USB")) + self.groupBox_11.setTitle(_translate("Dialog", "Detect")) + self.detect_usb.setText(_translate("Dialog", "Detect Drives")) + self.create.setText(_translate("Dialog", "Create")) self.labelstep1.setText(_translate("Dialog", "

Step 1

")) self.labelstep2.setText(_translate("Dialog", "

Step 2

")) - self.create.setText(_translate("Dialog", "Create")) + self.close.setText(_translate("Dialog", "Close")) + self.labelstep3.setText(_translate("Dialog", "

Step 3

")) + self.slider_persistence.setToolTip(_translate("Dialog", "Choose Persistence size. Not all distros supports persistence...")) self.groupBox.setTitle(_translate("Dialog", "Uninstall (Optional)")) self.uninstall.setText(_translate("Dialog", "Uninstall Distro")) - self.browse_iso.setText(_translate("Dialog", "Browse ISO")) - self.label_persistence.setText(_translate("Dialog", "

Persistence

")) self.groupBox_6.setTitle(_translate("Dialog", "USB Details")) self.usb_dev.setText(_translate("Dialog", "Drive ::")) self.usb_vendor.setText(_translate("Dialog", "Vendor ::")) self.usb_model.setText(_translate("Dialog", "Model::")) self.usb_size.setText(_translate("Dialog", "Size ::")) self.usb_mount.setText(_translate("Dialog", "Mount ::")) + self.browse_iso.setText(_translate("Dialog", "Browse ISO")) + self.label_persistence.setText(_translate("Dialog", "

Persistence

")) + self.checkBox_all_drives.setText(_translate("Dialog", "All Drives")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_3), _translate("Dialog", "MultiBootUSB")) self.groupBox_7.setTitle(_translate("Dialog", "Imager")) self.groupBox_9.setTitle(_translate("Dialog", "-------------- USB details -------------------")) diff --git a/scripts/mbusb_gui.py b/scripts/mbusb_gui.py index 11a2ceed..6010fd87 100644 --- a/scripts/mbusb_gui.py +++ b/scripts/mbusb_gui.py @@ -40,6 +40,7 @@ def __init__(self): self.ui.setupUi(self) # Main Tab + self.ui.checkBox_all_drives.clicked.connect(self.add_device) self.ui.detect_usb.clicked.connect(self.onRefereshClick) self.ui.close.clicked.connect(self.on_close_Click) self.ui.browse_iso.clicked.connect(self.browse_iso) @@ -92,7 +93,11 @@ def add_device(self): Adds list of available USB devices to GUI combobox. :return: """ - detected_device = usb.list() + self.ui.comboBox.clear() + if self.ui.checkBox_all_drives.isChecked(): + detected_device = usb.list(partition=1, fixed=True) + else: + detected_device = usb.list() if bool(detected_device): for device in detected_device: self.ui.comboBox.addItem(str(device)) @@ -132,8 +137,12 @@ def update_gui_oncombobox(self, usb_disk): config.usb_mount = self.usb_details['mount_point'] self.ui.usb_dev.setText("Drive :: " + usb_disk) # self.label.setFont(QtGui.QFont("Times",weight=QtGui.QFont.Bold)) - self.ui.usb_vendor.setText("Vendor :: " + self.usb_details['vendor']) - self.ui.usb_model.setText("Model :: " + self.usb_details['model']) + if platform.system() == 'Windows': + self.ui.usb_vendor.setText("FileSystem :: " + self.usb_details['file_system']) + self.ui.usb_model.setText("Label :: " + self.usb_details['label']) + else: + self.ui.usb_vendor.setText("Vendor :: " + self.usb_details['vendor']) + self.ui.usb_model.setText("Model :: " + self.usb_details['model']) self.ui.usb_size.setText("Total Size :: " + str(usb.bytes2human(self.usb_details['size_total']))) self.ui.usb_mount.setText("Mount :: " + self.usb_details['mount_point']) self.update_list_box(usb_disk) @@ -206,6 +215,7 @@ def install_syslinux(self): os.system('sync') self.ui.status.clear() QtWidgets.QMessageBox.information(self, 'Finished...', iso_name(config.iso_link) + ' has been successfully installed.') + config.process_exist = None def onInstall_syslinuxClick(self): """ @@ -349,6 +359,7 @@ def onCreateClick(self): if reply == QtWidgets.QMessageBox.Yes: self.ui.slider_persistence.setEnabled(False) + config.process_exist = True self.progress_thread_install.start() else: @@ -374,6 +385,7 @@ def dd_finished(self): self.ui.pushButton.setEnabled(True) self.ui.imager_bootable.setText("Bootable ISO :: ") self.ui.imager_iso_size.setText("ISO Size :: ") + config.process_exist = None QtWidgets.QMessageBox.information(self, 'Finished...', 'ISO has been written to USB disk.\nPlease reboot your ' 'system to boot from USB.') @@ -420,6 +432,7 @@ def dd_write(self): if reply == QtWidgets.QMessageBox.Yes: self.dd_start() + config.process_exist = True self.progress_thread_dd.start() def on_close_Click(self): @@ -435,16 +448,20 @@ def closeEvent(self, event): :param event: Close event. :return: """ - reply = QtWidgets.QMessageBox.question(self, 'Exit MultiBootUSB...', - "Do you really want to quit multibootusb?", QtWidgets.QMessageBox.Yes, - QtWidgets.QMessageBox.No) - if reply == QtWidgets.QMessageBox.Yes: - print("Closing multibootusb...") + if config.process_exist == None: event.accept() - sys.exit(0) else: - print("Close event cancelled.") - event.ignore() + reply = QtWidgets.QMessageBox.question(self, 'Exit MultiBootUSB...', + "A process is still running.\n" + "Do you really want to quit multibootusb?", QtWidgets.QMessageBox.Yes, + QtWidgets.QMessageBox.No) + if reply == QtWidgets.QMessageBox.Yes: + print("Closing multibootusb...") + event.accept() + sys.exit(0) + else: + print("Close event cancelled.") + event.ignore() class GuiInstallProgress(QtCore.QThread): @@ -578,6 +595,20 @@ def run(self): self.function(*self.args, **self.kwargs) return + +def show_admin_info(): + """ + Show simple information box reminding user to run the software with admin/root privilege. + Only required under Linux as the windows executable always will start with admin privilege. + :return: + """ + msg = QtWidgets.QMessageBox() + msg.setIcon(QtWidgets.QMessageBox.Information) + msg.setText('Admin privilege is required to run multibootusb.\n If you are running from source try ' + '\'sudo python3 ./multibootusb\'\n or you can try \'multibootusb-pkexec\' (post install)') + msg.exec_() + + def main_gui(): app = QtWidgets.QApplication(sys.argv) window = AppGui() @@ -585,4 +616,7 @@ def main_gui(): window.show() window.setWindowTitle("MultiBootUSB - " + mbusb_version()) window.setWindowIcon(QtGui.QIcon(resource_path(os.path.join("data", "tools", "multibootusb.png")))) + if platform.system() == 'Linux': + if os.getuid() != 0: + show_admin_info() sys.exit(app.exec_()) diff --git a/scripts/qemu.py b/scripts/qemu.py index 2d6b85ee..9809c6ce 100644 --- a/scripts/qemu.py +++ b/scripts/qemu.py @@ -129,7 +129,7 @@ def qemu_iso_ram(self): elif self.ui.ram_iso_1024.isChecked(): return str(1024) elif self.ui.ram_iso_2048.isChecked(): - return str(2048) + return str(2047) else: return None @@ -147,7 +147,7 @@ def qemu_usb_ram(self): if self.ui.ram_usb_1024.isChecked(): return str(1024) if self.ui.ram_usb_2048.isChecked(): - return str(2048) + return str(2047) else: return None @@ -174,6 +174,7 @@ def check_qemu_exist(self): print(resource_path(os.path.join("data", "tools", "qemu", "qemu-system-x86_64.exe"))) return resource_path(os.path.join("data", "tools", "qemu", "qemu-system-x86_64.exe")) + def get_physical_disk_number(self, usb_disk): """ Get the physical disk number as detected ny Windows. diff --git a/scripts/usb.py b/scripts/usb.py index 6d77057a..b29f3beb 100644 --- a/scripts/usb.py +++ b/scripts/usb.py @@ -12,6 +12,12 @@ import shutil import collections import ctypes +if platform.system() == 'Windows': + import psutil + import win32com.client + import win32com.client + import wmi + import pythoncom def is_block(usb_disk): @@ -74,7 +80,7 @@ def disk_usage(mount_path): raise NotImplementedError("Platform not supported.") -def list(partition=1): +def list(partition=1, fixed=None): """ List inserted USB devices. :return: USB devices as list. @@ -86,15 +92,19 @@ def list(partition=1): try: - # pyudev is good enough to detect USB devices on modern Linux - # machines. + # pyudev is good enough to detect USB devices on modern Linux machines. print("Using pyudev for detecting USB drives...") context = pyudev.Context() - for device in context.list_devices(subsystem='block', DEVTYPE='partition', - ID_FS_USAGE="filesystem", ID_TYPE="disk", - ID_BUS="usb"): - if device['ID_BUS'] == "usb" and device['DEVTYPE'] == "partition": - # print(device['DEVNAME']) + if fixed is None: + for device in context.list_devices(subsystem='block', DEVTYPE='partition', + ID_FS_USAGE="filesystem", ID_TYPE="disk", + ID_BUS="usb"): + # if device['ID_BUS'] == "usb" and device['DEVTYPE'] == "partition": + if device['ID_BUS'] in ("usb", "scsi") and device['DEVTYPE'] == "partition": + # print(device['DEVNAME']) + devices.append(str(device['DEVNAME'])) + else: + for device in context.list_devices(subsystem='block', DEVTYPE='partition'): devices.append(str(device['DEVNAME'])) except: bus = dbus.SystemBus() @@ -139,12 +149,28 @@ def list(partition=1): print("No USB device found...") elif platform.system() == "Windows": - import win32com.client - oFS = win32com.client.Dispatch("Scripting.FileSystemObject") - oDrives = oFS.Drives - for drive in oDrives: - if drive.DriveType == 1 and drive.IsReady: - devices.append(drive) + if fixed is not None: + for drive in psutil.disk_partitions(): + if 'cdrom' in drive.opts or drive.fstype == '': + # Skip cdrom drives or the disk with no filesystem + continue + devices.append(drive[0][:-1]) + else: + try: + # Try new method using psutil. It should also detect USB 3.0 (but not tested by me) + for drive in psutil.disk_partitions(): + if 'cdrom' in drive.opts or drive.fstype == '': + # Skip cdrom drives or the disk with no filesystem + continue + if 'removable' in drive.opts: + devices.append(drive[0][:-1]) + except: + # Revert back to old method if psutil fails (which is unlikely) + oFS = win32com.client.Dispatch("Scripting.FileSystemObject") + oDrives = oFS.Drives + for drive in oDrives: + if drive.DriveType == 1 and drive.IsReady: + devices.append(drive) if devices: return devices @@ -169,7 +195,8 @@ def details_udev(usb_disk_part): for device in context.list_devices(subsystem='block', DEVTYPE='partition', ID_FS_USAGE="filesystem", ID_TYPE="disk", ID_BUS="usb"): - if device['ID_BUS'] == "usb" and device['DEVTYPE'] == "partition": + # if device['ID_BUS'] == "usb" and device['DEVTYPE'] == "partition": + if device['ID_BUS'] in ("usb", "scsi") and device['DEVTYPE'] == "partition": if (device['DEVNAME']) == usb_disk_part: uuid = str(device['ID_FS_UUID']) file_system = str(device['ID_FS_TYPE']) @@ -279,13 +306,9 @@ def win_disk_details(disk_drive): :param disk_drive: USB disk like 'G:' :return: See the details(usb_disk_part) function for return values. """ - import win32com.client - import wmi - import pythoncom pythoncom.CoInitialize() vendor = 'Not_Found' model = 'Not_Found' - c = wmi.WMI() selected_usb_part = str(disk_drive) oFS = win32com.client.Dispatch("Scripting.FileSystemObject") d = oFS.GetDrive(oFS.GetDriveName(oFS.GetAbsolutePathName(selected_usb_part))) @@ -300,12 +323,18 @@ def win_disk_details(disk_drive): size_total = shutil.disk_usage(mount_point)[0] size_used = shutil.disk_usage(mount_point)[1] size_free = shutil.disk_usage(mount_point)[2] + ''' + # The below code works only from vista and above. I have removed it as many people reported that the software + # was not working under windows xp. Even then, it is significantly slow if 'All Drives' option is checked. + # Removing the code doesn't affect the functionality as it is only used to find vendor id and model of the drive. + c = wmi.WMI() for physical_disk in c.Win32_DiskDrive(InterfaceType="USB"): for partition in physical_disk.associators("Win32_DiskDriveToDiskPartition"): for logical_disk in partition.associators("Win32_LogicalDiskToPartition"): if logical_disk.Caption == disk_drive: vendor = (physical_disk.PNPDeviceID.split('&VEN_'))[1].split('&PROD_')[0] model = (physical_disk.PNPDeviceID.split('&PROD_'))[1].split('&REV_')[0] + ''' return {'uuid': uuid, 'file_system': file_system, 'label': label, 'mount_point': mount_point, 'size_total': size_total, 'size_used': size_used, 'size_free': size_free,