Get drive type with SetupDiGetDeviceRegistryProperty

前端 未结 3 908
广开言路
广开言路 2020-12-17 08:22

I would like to know whether i can get the drive information using the

SP_DEVICE_INTERFACE_DETAIL_DATA\'s DevicePath

my device path looks like below

3条回答
  •  清酒与你
    2020-12-17 08:47

    Given your Storage Device Path:

    • Open the device using CreateFile
    • use DeviceIOControl to issue IOCTL_STORAGE_QUERY_PROPERTY
    • this populates STORAGE_DEVICE_DESCRIPTOR structure
    • which has a STORAGE_BUS_TYPE enumeration:

      STORAGE_DEVICE_DESCRIPTOR {
        DWORD            Version;
        DWORD            Size;
        BYTE             DeviceType;
        BYTE             DeviceTypeModifier;
        BOOLEAN          RemovableMedia;
        BOOLEAN          CommandQueueing;
        DWORD            VendorIdOffset;
        DWORD            ProductIdOffset;
        DWORD            ProductRevisionOffset;
        DWORD            SerialNumberOffset;
        STORAGE_BUS_TYPE BusType;         //<---------------
        DWORD            RawPropertiesLength;
        BYTE             RawDeviceProperties[1];
      

      }

    The different storage bus types are

    • BusTypeScsi: SCSI
    • BusTypeAtapi: ATAPI
    • BusTypeAta: ATA
    • BusType1394: IEEE-1394
    • BusTypeSsa: SSA
    • BusTypeFibre: Fiber Channel
    • BusTypeUsb: USB
    • BusTypeRAID: RAID
    • BusTypeiSCSI: iSCSI
    • BusTypeSas: Serial Attached SCSI (SAS)
    • BusTypeSata: SATA

    So example psueudo-code

    STORAGE_BUS_TYPE GetStorageDeviceBusType(String StorageDevicePath)
    {
       /*
       Given a storage device path of
    
          \?\usb#vid_04f2&pid_0111#5&39fe81e&0&2#{a5dcbf10-6530-11d2-901f-00c04fb951ed}
    
       return its StorageBusType, e.g.:
    
          BusTypeUsb
       */
    
       //Open the disk for reading (must be an administrator)
       HANDLE diskHandle = CreateFile(StorageDevicePath, 
             GENERIC_READ,                        //desired access
             FILE_SHARE_READ | FILE_SHARE_WRITE,  //share mode
             null,                                //security attributes
             OPEN_EXISTING,                       //creation disposition
             FILE_ATTRIBUTE_NORMAL,               //flags and attributes
             0);           
       if (diskHandle == INVALID_HANDLE_VALUE)
          RaiseLastWin32Error();
    
       try
       {
          BOOL res;
          DWORD bytesReturned;
    
          //Set up what we want to query from the drive
          STORAGE_PROPERTY_QUERY query= {};
          query.QueryType = PropertyStandardQuery;
          query.PropertyID = StorageDeviceProperty;
    
          DWORD bufferSize;
    
          // Query for the header to get the required buffer size
          STORAGE_DESCRIPTOR_HEADER header;
          res = DeviceIoControl(diskHandle, IOCTL_STORAGE_QUERY_PROPERTY,
                ref query, sizeof(STORAGE_PROPERTY_QUERY),
                ref header, sizeof(STORAGE_DESCRIPTOR_HEADER),
                out bytesReturned, null);
          if (!res) RaiseLastWin32Error();
          bufferSize = header.Size;
    
          //Allocate the buffer and query for the full property
          STORAGE_DEVICE_DESCRIPTOR *deviceDescriptor = GetMem(bufferSize);
          try
          {
             //Issue IOCTL_STORAGE_QUERY_PROPERTY to get STORAGE_DEVICE_DESCRIPTOR
             res = DeviceIoControl(diskHandle, IOCTL_STORAGE_QUERY_PROPERTY,
                        @query, sizeof(STORAGE_PROPERTY_QUERY),
                        deviceDescriptor, bufferSize,
                        out bytesReturned, null));
             if (!res) 
                RaiseLastWin32Error();
    
             return deviceDescriptor.BusType;
          }
          finally
          {
             FreeMem(deviceDescriptor);
          }
       }
       finally
       {  
          CloseHandle(diskHandle);
       }       
    
    }
    

提交回复
热议问题