mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-08 02:34:06 -04:00
Workaround for bug on some Windows 10 machines that were upgraded from a previous windows version that was preventing calibre from detecting devices
This commit is contained in:
parent
d29f34face
commit
17e7e7bdb3
@ -13,6 +13,8 @@ from ctypes import (
|
|||||||
wstring_at, addressof, create_unicode_buffer, string_at, c_uint64 as QWORD)
|
wstring_at, addressof, create_unicode_buffer, string_at, c_uint64 as QWORD)
|
||||||
from ctypes.wintypes import DWORD, WORD, ULONG, LPCWSTR, HWND, BOOL, LPWSTR, UINT, BYTE, HANDLE
|
from ctypes.wintypes import DWORD, WORD, ULONG, LPCWSTR, HWND, BOOL, LPWSTR, UINT, BYTE, HANDLE
|
||||||
|
|
||||||
|
from calibre import prints
|
||||||
|
|
||||||
is64bit = sys.maxsize > (1 << 32)
|
is64bit = sys.maxsize > (1 << 32)
|
||||||
|
|
||||||
# Data and function type definitions {{{
|
# Data and function type definitions {{{
|
||||||
@ -315,7 +317,7 @@ def iterdescendants(parent_devinst):
|
|||||||
for gc in iterdescendants(child):
|
for gc in iterdescendants(child):
|
||||||
yield gc
|
yield gc
|
||||||
|
|
||||||
def get_all_removable_drives():
|
def get_all_removable_drives(allow_fixed=False):
|
||||||
mask = GetLogicalDrives()
|
mask = GetLogicalDrives()
|
||||||
ans = {}
|
ans = {}
|
||||||
buf = create_unicode_buffer(100)
|
buf = create_unicode_buffer(100)
|
||||||
@ -323,7 +325,10 @@ def get_all_removable_drives():
|
|||||||
drive_present = bool(mask & 0b1)
|
drive_present = bool(mask & 0b1)
|
||||||
mask >>= 1
|
mask >>= 1
|
||||||
drive_root = drive_letter + ':' + os.sep
|
drive_root = drive_letter + ':' + os.sep
|
||||||
if drive_present and GetDriveType(drive_root) == DRIVE_REMOVABLE: # Removable, present drive
|
if not drive_present:
|
||||||
|
continue
|
||||||
|
drive_type = GetDriveType(drive_root)
|
||||||
|
if drive_type == DRIVE_REMOVABLE or (allow_fixed and drive_type == DRIVE_FIXED): # Removable, present drive
|
||||||
try:
|
try:
|
||||||
GetVolumeNameForVolumeMountPoint(drive_root, buf, len(buf))
|
GetVolumeNameForVolumeMountPoint(drive_root, buf, len(buf))
|
||||||
except WindowsError:
|
except WindowsError:
|
||||||
@ -437,12 +442,28 @@ def drive_letter_from_volume_devpath(devpath, drive_map):
|
|||||||
return drive_map.get(pbuf.value)
|
return drive_map.get(pbuf.value)
|
||||||
|
|
||||||
def get_removable_drives(debug=False):
|
def get_removable_drives(debug=False):
|
||||||
drive_map = get_all_removable_drives()
|
pbuf = create_unicode_buffer(512)
|
||||||
|
mask = GetLogicalDrives()
|
||||||
|
drives = {letter:GetDriveType(letter + ':' + os.sep) for i, letter in enumerate(string.ascii_uppercase) if mask & (1 << i)}
|
||||||
|
if debug:
|
||||||
|
prints('Drive type map: %s' % drives)
|
||||||
|
drive_map = {}
|
||||||
|
for letter, drive_type in drives.iteritems():
|
||||||
|
# We need to allow both removable and fixed drives because some windows
|
||||||
|
# 10 machines that have been upgraded from a previous windows release
|
||||||
|
# mark USB drives as fixed. The fixed drives will only be added if
|
||||||
|
# "USBSTOR" in present in the volume device path, indicating that the drives,
|
||||||
|
# are, in fact, USB drives.
|
||||||
|
if drive_type in (DRIVE_REMOVABLE, DRIVE_FIXED):
|
||||||
|
try:
|
||||||
|
GetVolumeNameForVolumeMountPoint(letter + ':' + os.sep, pbuf, len(pbuf))
|
||||||
|
except WindowsError:
|
||||||
|
continue
|
||||||
|
drive_map[pbuf.value] = letter
|
||||||
if not drive_map:
|
if not drive_map:
|
||||||
raise NoRemovableDrives('No removable drives found!')
|
raise NoRemovableDrives('No removable drives found!')
|
||||||
|
|
||||||
buf = None
|
buf = None
|
||||||
pbuf = create_unicode_buffer(512)
|
|
||||||
ans = {}
|
ans = {}
|
||||||
with get_device_set() as dev_list:
|
with get_device_set() as dev_list:
|
||||||
interface_data = SP_DEVICE_INTERFACE_DATA()
|
interface_data = SP_DEVICE_INTERFACE_DATA()
|
||||||
@ -471,8 +492,11 @@ def get_removable_drives(debug=False):
|
|||||||
candidates.append(devpath)
|
candidates.append(devpath)
|
||||||
|
|
||||||
drive_letter = drive_letter_from_volume_devpath(devpath, drive_map)
|
drive_letter = drive_letter_from_volume_devpath(devpath, drive_map)
|
||||||
if drive_letter:
|
drive_type = drives.get(drive_letter)
|
||||||
|
if drive_type == DRIVE_REMOVABLE or (drive_type == DRIVE_FIXED and 'usbstor' in devpath.lower()):
|
||||||
ans[drive_letter] = candidates
|
ans[drive_letter] = candidates
|
||||||
|
if debug:
|
||||||
|
prints('Found volume with device path:', devpath, ' Drive letter:', drive_letter)
|
||||||
return ans
|
return ans
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
@ -514,7 +538,7 @@ def get_drive_letters_for_device(vendor_id, product_id, debug=False):
|
|||||||
break
|
break
|
||||||
if found_at is None:
|
if found_at is None:
|
||||||
if debug:
|
if debug:
|
||||||
print('Could not find device matching vid=0x%x pid=0x%x: %r' % (vendor_id, product_id))
|
prints('Could not find device matching vid=0x%x pid=0x%x: %r' % (vendor_id, product_id))
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
# Get the device ids for all descendants of the found device
|
# Get the device ids for all descendants of the found device
|
||||||
@ -523,11 +547,11 @@ def get_drive_letters_for_device(vendor_id, product_id, debug=False):
|
|||||||
devid, wbuf = get_device_id(devinst, buf=wbuf)
|
devid, wbuf = get_device_id(devinst, buf=wbuf)
|
||||||
device_ids.add(devid.upper().replace(os.sep, '#'))
|
device_ids.add(devid.upper().replace(os.sep, '#'))
|
||||||
if debug:
|
if debug:
|
||||||
print('Device ids for vid=0x%x pid=0x%x: %r' % (vendor_id, product_id, device_ids))
|
prints('Device ids for vid=0x%x pid=0x%x: %r' % (vendor_id, product_id, device_ids))
|
||||||
if not device_ids:
|
if not device_ids:
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
drive_map = get_all_removable_drives()
|
drive_map = get_all_removable_drives(allow_fixed=True)
|
||||||
if not drive_map:
|
if not drive_map:
|
||||||
raise NoRemovableDrives('No removable drives found!')
|
raise NoRemovableDrives('No removable drives found!')
|
||||||
|
|
||||||
@ -549,7 +573,7 @@ def get_drive_letters_for_device(vendor_id, product_id, debug=False):
|
|||||||
matched = True
|
matched = True
|
||||||
break
|
break
|
||||||
if debug:
|
if debug:
|
||||||
print('Found volume with device path: %s Matches a device_id: %s' % (devpath, matched))
|
prints('Found volume with device path: %s Matches a device_id: %s' % (devpath, matched))
|
||||||
if matched:
|
if matched:
|
||||||
drive_letter = drive_letter_from_volume_devpath(devpath, drive_map)
|
drive_letter = drive_letter_from_volume_devpath(devpath, drive_map)
|
||||||
if drive_letter:
|
if drive_letter:
|
||||||
@ -667,7 +691,7 @@ def develop(vendor_id=0x1949, product_id=0x4, do_eject=False):
|
|||||||
print()
|
print()
|
||||||
print('Is device connected:', is_usb_device_connected(vendor_id, product_id))
|
print('Is device connected:', is_usb_device_connected(vendor_id, product_id))
|
||||||
print('\nAll removable drives:')
|
print('\nAll removable drives:')
|
||||||
pprint(get_all_removable_drives())
|
pprint(get_all_removable_drives(allow_fixed=False))
|
||||||
print('\nRemovable drives:')
|
print('\nRemovable drives:')
|
||||||
rd = get_removable_drives(debug=True)
|
rd = get_removable_drives(debug=True)
|
||||||
pprint(rd)
|
pprint(rd)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user