Merge pull request #371 from shinji-s/devel

Fix uuid generation from NTFS/FAT32 partition on Windows.
pull/374/head
multibootusb 6 years ago committed by GitHub
commit 4d6e19ed41
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -2,6 +2,7 @@ import logging
import logging.handlers
import os
import platform
import shutil
import subprocess
import sys
@ -62,6 +63,7 @@ def get_physical_disk_number(usb_disk):
log("Physical Device Number is %d" % partition.DiskIndex)
return partition.DiskIndex
def wmi_get_drive_info(usb_disk):
assert platform.system() == 'Windows'
import wmi
@ -75,6 +77,53 @@ def wmi_get_drive_info(usb_disk):
raise RuntimeError('Failed to obtain drive information ' + usb_disk)
def wmi_get_drive_info_ex(usb_disk):
assert platform.system() == 'Windows'
partition, disk = wmi_get_drive_info(usb_disk)
#print (disk.Caption, partition.StartingOffset, partition.DiskIndex,
# disk.FileSystem, disk.VolumeName)
# Extract Volume serial number off of the boot sector because
# retrieval via COM object 'Scripting.FileSystemObject' or wmi interface
# truncates NTFS serial number to 32 bits.
with open('//./Physicaldrive%d'%partition.DiskIndex, 'rb') as f:
f.seek(int(partition.StartingOffset))
bs_ = f.read(512)
serial_extractor = {
'NTFS' : lambda bs: \
''.join('%02X' % c for c in reversed(bs[0x48:0x48+8])),
'FAT32' : lambda bs: \
'%02X%02X-%02X%02X' % tuple(
map(int,reversed(bs[67:71])))
}.get(disk.FileSystem, lambda bs: None)
uuid = serial_extractor(bs_)
mount_point = usb_disk + '\\'
size_total, size_used, size_free \
= shutil.disk_usage(mount_point)[:3]
r = {
'uuid' : uuid,
'file_system' : disk.FileSystem,
'label' : disk.VolumeName.strip() or 'No_label',
'mount_point' : mount_point,
'size_total' : size_total,
'size_used' : size_used,
'size_free' : size_free,
'vendor' : 'Not_Found',
'model' : 'Not_Found',
'devtype' : {
0 : 'Unknown',
1 : 'Fixed Disk',
2 : 'Removable Disk',
3 : 'Local Disk',
4 : 'Network Drive',
5 : 'Compact Disc',
6 : 'RAM Disk',
}.get(disk.DriveType, 'DiskType(%d)' % disk.DriveType),
'disk_index' : partition.DiskIndex,
}
# print (r)
return r
class Base:

@ -20,6 +20,8 @@ if platform.system()=='Linux':
from . import config
from . import gen
from . import osdriver
if platform.system() == 'Linux':
from . import udisks
UDISKS = udisks.get_udisks(ver=None)
@ -488,49 +490,6 @@ class UnmountedContext:
gen.log("Mounted %s" % (self.usb_disk))
def win_disk_details(disk_drive):
"""
Populate and get details of an USB disk under windows. Minimum required windows version is Vista.
:param disk_drive: USB disk like 'G:'
:return: See the details(usb_disk_part) function for return values.
"""
pythoncom.CoInitialize()
vendor = 'Not_Found'
model = 'Not_Found'
devtype = 'Not_Found'
selected_usb_part = str(disk_drive)
oFS = win32com.client.Dispatch("Scripting.FileSystemObject")
d = oFS.GetDrive(oFS.GetDriveName(oFS.GetAbsolutePathName(selected_usb_part)))
selected_usb_device = d.DriveLetter
if d.DriveType == 1:
devtype = "Removable Disk"
elif d.DriveType == 2:
devtype = "Fixed Disk"
label = (d.VolumeName).strip()
if not label.strip():
label = "No_label"
mount_point = selected_usb_device + ":\\"
serno = "%X" % (int(d.SerialNumber) & 0xFFFFFFFF)
uuid = serno[:4] + '-' + serno[4:]
file_system = (d.FileSystem).strip()
size_total, size_used, size_free = shutil.disk_usage(mount_point)[:3]
# 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,
'vendor': vendor, 'model': model, 'devtype': devtype}
def check_vfat_filesystem(usb_disk, result=None):
p = subprocess.Popen(['fsck.vfat', '-n', usb_disk],
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
@ -585,7 +544,7 @@ def details(usb_disk_part):
except:
details = details_udisks2(usb_disk_part)
elif platform.system() == 'Windows':
details = win_disk_details(usb_disk_part)
details = osdriver.wmi_get_drive_info_ex(usb_disk_part)
return details

Loading…
Cancel
Save