Win32 盘符,设备号和硬盘型号

原发布地址

原Issue评论,讨论 KDiskMark Windows 支持需要的工作

列出设备

逻辑设备

GetLogicalDrives 会返回一组位码,值为1的位的位置加上’A’就是它代表的盘符

from win32api import GetLogicalDrives

# for example, `0b_1100` means there are C:/ and D:/.
def logical_drives():
   bit_mask = GetLogicalDrives()
   for offset in range(26):
      alphabet = chr(ord('A') + offset)
      if (1 << offset) & bit_mask:
          yield alphabet

使用 Powershell1:
Get-Volume
使用 mountvol.exe
mountvol /L
使用 FindFirstVolumeW and FindNextVolumeW
from winsys._kernel32 import FindFirstVolume, FindNextVolume
handle, first = FindFirstVolume()
volumes = [first]

while (volume := FindNextVolume(handle)) and isinstance(volume, str):
    volumes.append(volume)

print(volumes)

获取硬盘型号

盘符 -> 硬盘型号

使用 Powershell2
Get-Disk (Get-Partition -DriveLetter 'C').DiskNumber | select -Prop FriendlyName

盘符或任意卷 -> 设备号

使用 Powershell (只支持盘符)
(Get-Partition -DriveLetter 'C').DiskNumber
使用 IOCTL_STORAGE_GET_DEVICE_NUMBER
#include <stdio.h>
#include <Windows.h>
#include <fileapi.h>
#include <winioctl.h>

int get_disk_number_by_drive_letter(char letter) {
    char logical_drive_path[7];
    sprintf(logical_drive_path, "\\\\.\\%c:", letter);
    // '\\?\Volume{<GUID>}' is also applicable to this
    HANDLE hDevice = CreateFileA(logical_drive_path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
    if (hDevice == INVALID_HANDLE_VALUE) {
        fprintf(stderr, "Failed to open device. Error code: %lu\n", GetLastError());
        return -1;
    }

    STORAGE_DEVICE_NUMBER device_number;
    DWORD bytes_returned;
    if (!DeviceIoControl(hDevice, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &device_number, sizeof(device_number), &bytes_returned, NULL)) {
        fprintf(stderr, "IOCTL_STORAGE_GET_DEVICE_NUMBER failed. Error code: %lu\n", GetLastError());
        CloseHandle(hDevice);
        return -1;
    }

    CloseHandle(hDevice);
    return device_number.DeviceNumber;
}

设备号 -> 硬盘型号

使用 Powershell
Get-Disk | select -Prop Number,FriendlyName
使用 wmic
wmic diskdrive get index,model
使用 wmi
from win32com.client import GetObject

def get_diskdrive_info():
    wmi = GetObject(r"winmgmts:\\.\root\cimv2")
    disks = wmi.ExecQuery("SELECT * FROM Win32_DiskDrive")

    disk_info = {disk.Index: disk.Model for disk in disks}
    return disk_info

disk_info = sorted(get_diskdrive_info().items())

for index, model in disk_info:
    print(f"{index}: {model}")

Anyway, the most accurate way is to call smartctl ... X:

其他可能要用到的系统调用

QueryDosDeviceW 可以用来从盘符获取卷编号(也可以用来列出卷,如果传入None),即 \Device\HarddiskVolumeX 中的 X 。

GetDiskFreeSpaceExA 可以拿到对调用用户可用的空间(详见配额),总硬盘大小和总可用空间。

from win32file import GetDiskFreeSpaceEx
list(map(lambda size: size / (1024**3), GetDiskFreeSpaceEx("C:")))
# [58.516212463378906, 117.97948837280273, 58.516212463378906]

尾声

感谢3的 Win32 Paths 解释


  1. https://winreg-kb.readthedocs.io/en/latest/sources/system-keys/Mounted-devices.html#notes) ↩︎

  2. https://superuser.com/a/1147305 ↩︎

  3. https://chrisdenton.github.io/omnipath/Overview.html ↩︎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值