WINAPI - 不支持获取 U 盘存储信息的请求

问题描述 投票:0回答:0

我已经知道了U盘的VID和PID,但是我好像访问不到U盘的存储信息。

程序输出一个

GetLastError()
代码50,对应“不支持该请求”。 应该支持,因为我只是想获取存储信息。

这里是最小可重现代码:

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <initguid.h>
#include <Usbiodef.h>
#include <setupapi.h>
#include <errhandlingapi.h>

HANDLE getUsbHandle(DWORD VID, DWORD PID) {
  HANDLE usb_handle = NULL;

  /* Get all the devices */
  HDEVINFO hDevInfo = SetupDiGetClassDevs(&GUID_DEVINTERFACE_USB_DEVICE, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);
  if (hDevInfo == INVALID_HANDLE_VALUE) {
    printf("Failed to get device information set\n");
    return NULL;
  }

  SP_DEVICE_INTERFACE_DATA ifaceData = { 0 };
  ifaceData.cbSize = sizeof(ifaceData);
  DWORD index = 0;

  /* Enumerates over all the devices */
  while (SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &GUID_DEVINTERFACE_USB_DEVICE, index++, &ifaceData)) { 
    SP_DEVICE_INTERFACE_DETAIL_DATA *pDetail = NULL;
    DWORD detailSize = 0;

    SetupDiGetDeviceInterfaceDetail(hDevInfo, &ifaceData, NULL, 0, &detailSize, NULL); // Finding detail size

    pDetail = (SP_DEVICE_INTERFACE_DETAIL_DATA *)malloc(detailSize);
    pDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

    if (!SetupDiGetDeviceInterfaceDetail(hDevInfo, &ifaceData, pDetail, detailSize, NULL, NULL)) {
      printf("Failed to get device interface detail. Error: %i", GetLastError());
      free(pDetail);
      continue;
    }

    DWORD vid, pid;
    sscanf_s(pDetail->DevicePath, "\\\\?\\usb#vid_%04X&pid_%04X#", &vid, &pid); // grab the vid and pid of the device

    if (vid != VID || pid != PID) {
      free(pDetail);
      continue;
    }

    usb_handle = CreateFile(pDetail->DevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); // create a handle to the USB drive

    if (usb_handle == INVALID_HANDLE_VALUE) {
      printf("INVALID HANDLE VALUE: Error: %i\n", GetLastError());
      free(pDetail);
      continue;
    }

    break; // USB which matches VID and PID is found, so break
  }

  SetupDiDestroyDeviceInfoList(hDevInfo); // free unused resources info

  return usb_handle;
}

int main() {
  DWORD VID = 0X090C;
  DWORD PID = 0X1000;

  HANDLE usb_handle = getUsbHandle(VID, PID);

  if (!usb_handle) {
    printf("Null USB handle\n");
    return 1;
  }

  DISK_GEOMETRY_EX diskGeometry; // stores the storage info
  DWORD bytesReturned = 0;

  BOOL result = DeviceIoControl( // get storage info
      usb_handle,
      IOCTL_DISK_GET_DRIVE_GEOMETRY_EX,
      NULL,
      0,
      &diskGeometry,
      sizeof(diskGeometry),
      &bytesReturned,
      NULL
  );
  if (result == FALSE) {
    printf("Failed to get storage info. Error: %i\n", GetLastError());
    printf("Bytes returned: %i\n", bytesReturned);
    return 2;
  }

  printf("Bytes returned: %i\n", bytesReturned);
  printf("Storage: %llu\n\n", diskGeometry.DiskSize.QuadPart);
}

编译使用

gcc main.c - main.exe -lsetupapi

输出:

Failed to get storage info. Error: 50
Bytes returned: 0

50 错误代码对应“不支持该请求。”

c winapi usb-drive
© www.soinside.com 2019 - 2024. All rights reserved.