1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
| #!/usr/bin/env python3
# -*- coding: utf-8 -*-
from ctypes import windll
import string
import struct
from typing import Dict, List, Tuple
import win32file
import winioctlcon
import win32api
def get_drives_path() -> List[str]:
bitmask = windll.kernel32.GetLogicalDrives()
drivers = []
for path in (f"{letter}:" for letter in string.ascii_uppercase):
if bitmask & 1:
drivers.append(path)
bitmask >>= 1
return drivers
def get_drive_total_size(label: str) -> int:
try:
_, total, _ = win32file.GetDiskFreeSpaceEx(label)
return total
except:
return 0
def get_drive_name_type(label: str) -> Tuple[str, str]:
try:
name, _, _, _, type = win32api.GetVolumeInformation(label)
except:
return ("", "")
return (name, type)
IOCTL_STORAGE_QUERY_PROPERTY = winioctlcon.CTL_CODE(
winioctlcon.IOCTL_STORAGE_BASE,
0x500,
winioctlcon.METHOD_BUFFERED,
winioctlcon.FILE_ANY_ACCESS,
)
def is_usb_bus_type(label: str) -> bool:
path = f"\\\\.\\{label}"
handle = win32file.CreateFileW(
path,
0,
win32file.FILE_SHARE_READ | win32file.FILE_SHARE_WRITE,
None,
win32file.OPEN_EXISTING,
0,
None,
)
bus_type = winioctlcon.BusTypeUnknown
try:
query = struct.pack("iii", 0, 0, 0)
devd = win32file.DeviceIoControl(
handle,
IOCTL_STORAGE_QUERY_PROPERTY,
query,
struct.calcsize("LLcc??LLLLiLi"),
None,
)
bus_type = struct.unpack("LLcc??LLLLiLi", devd)[10]
finally:
handle.Close()
return bus_type == winioctlcon.BusTypeUsb
def is_usb_drive(label: str) -> bool:
type = windll.kernel32.GetDriveTypeW(label)
if type == win32file.DRIVE_REMOVABLE:
return True
elif type != win32file.DRIVE_FIXED:
return False
elif not is_usb_bus_type(label):
return False
return True
def get_usb_list() -> List:
usb_drive_paths = [
(path, get_drive_total_size(path), *get_drive_name_type(path))
for path in get_drives_path()
if is_usb_drive(path)
]
return [
usb
for usb in usb_drive_paths
if usb[1] > 0 and usb[3] in ["NTFS", "FAT", "exFAT", "FAT32"]
]
print(get_usb_list())
|