![](/img/trans.png)
[英]Using python code how do i get the disks name and disk state in azure
[英]Python and GetVolumeInformationW and GetDriveTypeW: list all disks and get disk info and filesystem flags
在 python3 上使用 windows API: https : //docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getvolumeinformationw
如何在不安裝任何其他外部模塊的情況下,通過這個函數GetVolumeInformationW獲取這些值(file_system_flags、max_component_length 和 serial_number)?
import ctypes
kernel32 = ctypes.windll.kernel32
volumeNameBuffer = ctypes.create_unicode_buffer(1024)
fileSystemNameBuffer = ctypes.create_unicode_buffer(1024)
serial_number = None
max_component_length = None
file_system_flags = None
target_disk = 'C:\\'
rc = kernel32.GetVolumeInformationW(
ctypes.c_wchar_p(target_disk),
volumeNameBuffer, ctypes.sizeof(volumeNameBuffer),
serial_number,
max_component_length,
file_system_flags,
fileSystemNameBuffer, ctypes.sizeof(fileSystemNameBuffer)
)
mount_point = target_disk[:-1]
disk_label = volumeNameBuffer.value
fs_type = fileSystemNameBuffer.value
max_length = max_component_length
flags = file_system_flags
serial = serial_number
print(mount_point, disk_label, fs_type, max_length, flags, serial)
補充:如何將文件系統標志轉換為人類可讀的格式?
my_disk_flag = 0x3e706ff
hex_flags = [0x00000002, 0x00000001, 0x20000000, 0x00000010, 0x00040000, 0x00000008, 0x00080000, 0x00100000, 0x00020000, 0x00800000, 0x00400000, 0x00010000, 0x01000000, 0x00000080, 0x00000040, 0x00200000, 0x02000000, 0x00000004, 0x00008000, 0x00000020, 0x08000000]
str_flags = ['FILE_CASE_PRESERVED_NAMES', 'FILE_CASE_SENSITIVE_SEARCH', 'FILE_DAX_VOLUME', 'FILE_FILE_COMPRESSION', 'FILE_NAMED_STREAMS', 'FILE_PERSISTENT_ACLS', 'FILE_READ_ONLY_VOLUME', 'FILE_SEQUENTIAL_WRITE_ONCE', 'FILE_SUPPORTS_ENCRYPTION', 'FILE_SUPPORTS_EXTENDED_ATTRIBUTES', 'FILE_SUPPORTS_HARD_LINKS', 'FILE_SUPPORTS_OBJECT_IDS', 'FILE_SUPPORTS_OPEN_BY_FILE_ID', 'FILE_SUPPORTS_REPARSE_POINTS', 'FILE_SUPPORTS_SPARSE_FILES', 'FILE_SUPPORTS_TRANSACTIONS', 'FILE_SUPPORTS_USN_JOURNAL', 'FILE_UNICODE_ON_DISK', 'FILE_VOLUME_IS_COMPRESSED', 'FILE_VOLUME_QUOTAS', 'FILE_SUPPORTS_BLOCK_REFCOUNTING']
創建該類型的實例並通過引用傳遞它。 它相當於在 C 中聲明一個局部變量並傳遞它的地址,例如DWORD flags;
並作為&flags
傳遞為輸出參數。
它還通過聲明函數調用的.argtypes
和.restype
來幫助 ctypes 錯誤檢查,這類似於聲明 C 原型。 ctypes.wintypes
有許多適用於 Windows 的預定義類型:
import ctypes as ct
from ctypes import wintypes as w
dll = ct.WinDLL('kernel32')
dll.GetVolumeInformationW.argtypes = w.LPCWSTR,w.LPWSTR,w.DWORD,w.LPDWORD,w.LPDWORD,w.LPDWORD,w.LPWSTR,w.DWORD
dll.GetVolumeInformationW.restype = w.BOOL
volumeNameBuffer = ct.create_unicode_buffer(w.MAX_PATH + 1)
fileSystemNameBuffer = ct.create_unicode_buffer(w.MAX_PATH + 1)
serial_number = w.DWORD()
max_component_length = w.DWORD()
file_system_flags = w.DWORD()
target_disk = 'C:\\'
if dll.GetVolumeInformationW(target_disk,
volumeNameBuffer, ct.sizeof(volumeNameBuffer),
ct.byref(serial_number),
ct.byref(max_component_length),
ct.byref(file_system_flags),
fileSystemNameBuffer, ct.sizeof(fileSystemNameBuffer)):
mount_point = target_disk[:-1]
disk_label = volumeNameBuffer.value
fs_type = fileSystemNameBuffer.value
max_length = max_component_length.value
flags = file_system_flags.value
serial = serial_number.value
print(f'{mount_point} {disk_label} {fs_type} {max_length} {flags:#x} {serial:#08x}')
為了將來參考,我將在此處留下有關如何列出所有磁盤並獲取其類似 fstab 的信息的完整代碼
import ctypes as ct
import string
from ctypes import wintypes as w
from enum import IntFlag
from pathlib import Path
class FSFlags(IntFlag):
FILE_CASE_SENSITIVE_SEARCH = 0x00000001
FILE_CASE_PRESERVED_NAMES = 0x00000002
FILE_UNICODE_ON_DISK = 0x00000004
FILE_PERSISTENT_ACLS = 0x00000008
FILE_FILE_COMPRESSION = 0x00000010
FILE_VOLUME_QUOTAS = 0x00000020
FILE_SUPPORTS_SPARSE_FILES = 0x00000040
FILE_SUPPORTS_REPARSE_POINTS = 0x00000080
FILE_VOLUME_IS_COMPRESSED = 0x00008000
FILE_SUPPORTS_OBJECT_IDS = 0x00010000
FILE_SUPPORTS_ENCRYPTION = 0x00020000
FILE_NAMED_STREAMS = 0x00040000
FILE_READ_ONLY_VOLUME = 0x00080000
FILE_SEQUENTIAL_WRITE_ONCE = 0x00100000
FILE_SUPPORTS_TRANSACTIONS = 0x00200000
FILE_SUPPORTS_HARD_LINKS = 0x00400000
FILE_SUPPORTS_EXTENDED_ATTRIBUTES = 0x00800000
FILE_SUPPORTS_OPEN_BY_FILE_ID = 0x01000000
FILE_SUPPORTS_USN_JOURNAL = 0x02000000
FILE_SUPPORTS_BLOCK_REFCOUNTING = 0x08000000
FILE_DAX_VOLUME = 0x20000000
def validate(result,func,args):
if not result:
raise ct.WinError(ct.get_last_error())
return None
dll = ct.WinDLL('kernel32',use_last_error=True)
dll.GetVolumeInformationW.argtypes = w.LPCWSTR,w.LPWSTR,w.DWORD,w.LPDWORD,w.LPDWORD,w.LPDWORD,w.LPWSTR,w.DWORD
dll.GetVolumeInformationW.restype = w.BOOL
dll.GetVolumeInformationW.errcheck = validate
volumeNameBuffer = ct.create_unicode_buffer(w.MAX_PATH + 1)
fileSystemNameBuffer = ct.create_unicode_buffer(w.MAX_PATH + 1)
serial_number = w.DWORD()
max_component_length = w.DWORD()
file_system_flags = w.DWORD()
lst_available_disks = [f'{d}:\\' for d in string.ascii_uppercase if Path(f'{d}:\\').exists()]
lst_disk_types = ['DRIVE_UNKNOWN', 'DRIVE_NO_ROOT_DIR', 'DRIVE_REMOVABLE', 'DRIVE_FIXED', 'DRIVE_REMOTE', 'DRIVE_CDROM', 'DRIVE_RAMDISK']
for target_disk in lst_available_disks:
disk_type_index = dll.GetDriveTypeW(target_disk)
dll.GetVolumeInformationW(target_disk,
volumeNameBuffer, ct.sizeof(volumeNameBuffer),
ct.byref(serial_number),
ct.byref(max_component_length),
ct.byref(file_system_flags),
fileSystemNameBuffer, ct.sizeof(fileSystemNameBuffer))
mount_point = target_disk
disk_label = volumeNameBuffer.value
fs_type = fileSystemNameBuffer.value
max_length = max_component_length.value
flags = FSFlags(file_system_flags.value)
serial = serial_number.value
if 'FILE_READ_ONLY_VOLUME' in str(flags):
read_write_status = 'ro'
else:
read_write_status = 'rw'
extra_tab_label = ''
if len(disk_label) < 8: extra_tab_label = '\t'
extra_tab_type = ''
if len(lst_disk_types[disk_type_index]) < 12: extra_tab_type = '\t'
print(f'{disk_label}{extra_tab_label}\t{mount_point}\t{fs_type}\t{max_length}\t{serial}\t{read_write_status},{lst_disk_types[disk_type_index]}{extra_tab_type}\t{flags=}\n')
輸出(只需用零替換磁盤序列):
Win10 C:\ NTFS 255 0000000000 rw,DRIVE_FIXED flags=<FSFlags.FILE_SUPPORTS_USN_JOURNAL|FILE_SUPPORTS_OPEN_BY_FILE_ID|FILE_SUPPORTS_EXTENDED_ATTRIBUTES|FILE_SUPPORTS_HARD_LINKS|FILE_SUPPORTS_TRANSACTIONS|FILE_NAMED_STREAMS|FILE_SUPPORTS_ENCRYPTION|FILE_SUPPORTS_OBJECT_IDS|1024|512|FILE_SUPPORTS_REPARSE_POINTS|FILE_SUPPORTS_SPARSE_FILES|FILE_VOLUME_QUOTAS|FILE_FILE_COMPRESSION|FILE_PERSISTENT_ACLS|FILE_UNICODE_ON_DISK|FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH: 65472255>
D:\ FAT32 255 0000000000 rw,DRIVE_FIXED flags=<FSFlags.FILE_SUPPORTS_ENCRYPTION|512|FILE_UNICODE_ON_DISK|FILE_CASE_PRESERVED_NAMES: 131590>
DRV061107 E:\ CDFS 110 0000000000 ro,DRIVE_CDROM flags=<FSFlags.FILE_SUPPORTS_OPEN_BY_FILE_ID|FILE_READ_ONLY_VOLUME|FILE_UNICODE_ON_DISK|FILE_CASE_SENSITIVE_SEARCH: 17301509>
Ventoy F:\ exFAT 255 0000000000 rw,DRIVE_REMOVABLE flags=<FSFlags.FILE_SUPPORTS_ENCRYPTION|512|FILE_UNICODE_ON_DISK|FILE_CASE_PRESERVED_NAMES: 131590>
VTOYEFI G:\ FAT 255 0000000000 rw,DRIVE_REMOVABLE flags=<FSFlags.FILE_SUPPORTS_ENCRYPTION|512|FILE_UNICODE_ON_DISK|FILE_CASE_PRESERVED_NAMES: 131590>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.