#winapi #storage #ioctl
Вопрос:
Я пытаюсь получить STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR
устройства хранения данных, запросив IOCTL_STORAGE_QUERY_PROPERTY
IOCTL с правильно заполненной STORAGE_PROPERTY_QUERY
структурой. Это отлично работает для хранения без USB, но для USB-накопителя это не работает ERROR_INVALID_FUNCTION
.
Я также проверил, существует ли это свойство, установив значение QueryType
PropertyExistsQuery
и не предоставляя выходной буфер. Оказывается, он существует. Я не понимаю, почему это не сработает ERROR_INVALID_FUNCTION
.
Вот сокращенная версия кода, который я использовал (без обработки ошибок и т. Д.):
#include <Windows.h>
#include <SetupAPI.h>
#include <stdio.h>
int main(void){
HDEVINFO diskClassDevs;
diskClassDevs = SetupDiGetClassDevs(amp;GUID_DEVINTERFACE_DISK,
NULL,
NULL,
DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
DWORD devIdx = 0;
SP_DEVICE_INTERFACE_DATA devInterfaceData;
devInterfaceData.cbSize = sizeof(devInterfaceData);
while(SetupDiEnumDeviceInterfaces(diskClassDevs,
NULL,
amp;GUID_DEVINTERFACE_DISK,
devIdx,
amp;devInterfaceData)){
devIdx ;
DWORD requiredSize;
DWORD result = SetupDiGetDeviceInterfaceDetail(diskClassDevs,
amp;devInterfaceData,
NULL,
0,
amp;requiredSize,
0);
SP_DEVICE_INTERFACE_DETAIL_DATA *devInterfaceDetailData;
devInterfaceDetailData = malloc(requiredSize);
devInterfaceDetailData->cbSize = sizeof(*devInterfaceDetailData);
SP_DEVINFO_DATA devInfoData;
devInfoData.cbSize = sizeof(devInfoData);
result = SetupDiGetDeviceInterfaceDetail(diskClassDevs,
amp;devInterfaceData,
devInterfaceDetailData,
requiredSize,
NULL,
amp;devInfoData);
HANDLE devHandle;
devHandle = CreateFile(devInterfaceDetailData->DevicePath,
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL);
STORAGE_DESCRIPTOR_HEADER diskDescriptorSizeInfo;
diskDescriptorSizeInfo.Version = sizeof(diskDescriptorSizeInfo);
STORAGE_PROPERTY_QUERY diskProperty;
diskProperty.QueryType = PropertyStandardQuery;
diskProperty.PropertyId = StorageDeviceProperty;
result = DeviceIoControl(devHandle,
IOCTL_STORAGE_QUERY_PROPERTY,
amp;diskProperty,
sizeof(diskProperty),
amp;diskDescriptorSizeInfo,
sizeof(diskDescriptorSizeInfo),
amp;requiredSize,
NULL);
STORAGE_DEVICE_DESCRIPTOR *diskDescriptor;
diskDescriptor = malloc(diskDescriptorSizeInfo.Size);
diskDescriptor->Version = diskDescriptorSizeInfo.Size;
result = DeviceIoControl(devHandle,
IOCTL_STORAGE_QUERY_PROPERTY,
amp;diskProperty,
sizeof(diskProperty),
diskDescriptor,
diskDescriptorSizeInfo.Size,
amp;requiredSize,
NULL);
printf("Bus Type: %sn", (diskDescriptor->BusType == 7 ? "USB" : "not USB"));
//GET STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR HERE
diskProperty.PropertyId = StorageAccessAlignmentProperty;
STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR diskAlignment;
diskAlignment.Version = sizeof(diskAlignment);
result = DeviceIoControl(devHandle,
IOCTL_STORAGE_QUERY_PROPERTY,
amp;diskProperty,
sizeof(diskProperty),
amp;diskAlignment,
sizeof(diskAlignment),
amp;requiredSize,
NULL);
if(!result){
printf("IOCTL_STORAGE_QUERY_PROPERTY failed (Error: %lu)n", GetLastError());
}else{
printf("Physical sector size: %lun", diskAlignment.BytesPerPhysicalSector);
}
printf("----------------n");
}
}
Комментарии:
1. просто некоторые устройства не могут реализовать это свойство и вернуть
STATUS_INVALID_DEVICE_REQUEST
. посмотрите, как это было сделано здесь и здесь . дляPropertyExistsQuery
обычно всегда возвращаемого ок — этот запрос не информативен2. Я понимаю, спасибо. В чем причина того, что для PropertyExists обычно возвращается ok , независимо от того, можно ли запросить свойство?
3. но я вставляю вам ссылку на реализацию — github.com/microsoft/Windows-driver-samples/blob/master/storage/… — для
if (query->QueryType == PropertyExistsQuery)
всегдаstatus = STATUS_SUCCESS; goto Exit;
, для других типов запросов —if (query->QueryType != PropertyStandardQuery)
— возвращена ошибкаstatus = STATUS_NOT_SUPPORTED; goto Exit;
иPropertyStandardQuery
зависит от драйвера порта