vc 识别移动硬盘 U盘,本地硬盘
说明:
有时候我们在做设备监控的时候,要识别一些链接设备,在使用函数GetDriveType的时候,U盘可以返回DRIVE_REMOVABLE,而本地硬盘硬盘和移动硬盘DRIVE_FIXED,因此还需要进一步来识别。识别方法为判断设备的总线类型即可:需要用到的数据类型以及函数有:
//将所有的卷存储在buffer中,格式为:C:/NULLD:/NULLE:/NULL
DWORD GetLogicalDriveStrings(
DWORD nBufferLength, // size of buffer
LPTSTR lpBuffer // drive strings buffer);
//判断设备类型: UINT GetDriveType( LPCTSTR lpRootPathName // root directory); 返回值有: #define DRIVE_UNKNOWN 0 #define DRIVE_NO_ROOT_DIR 1 #define DRIVE_REMOVABLE 2 #define DRIVE_FIXED 3 #define DRIVE_REMOTE 4 #define DRIVE_CDROM 5 #define DRIVE_RAMDISK 6 //DeviceIoControl要查询的类型 typedef struct _STORAGE_PROPERTY_QUERY { // ID of the property being retrieved STORAGE_PROPERTY_ID PropertyId;//使用前要对此字段赋值 // Flags indicating the type of query being performed STORAGE_QUERY_TYPE QueryType; //使用前要对此字段赋值 // Space for additional parameters if necessary BYTE AdditionalParameters[1]; } STORAGE_PROPERTY_QUERY, *PSTORAGE_PROPERTY_QUERY; // STORAGE_PROPERTY_ID枚举类型 typedef enum _STORAGE_PROPERTY_ID { StorageDeviceProperty = 0, StorageAdapterProperty, StorageDeviceIdProperty, StorageDeviceUniqueIdProperty, // See storduid.h for details StorageDeviceWriteCacheProperty, StorageMiniportProperty, StorageAccessAlignmentProperty, StorageDeviceSeekPenaltyProperty, StorageDeviceTrimProperty, StorageDeviceWriteAggregationProperty, StorageDeviceDeviceTelemetryProperty, StorageDeviceLBProvisioningProperty, StorageDevicePowerProperty, StorageDeviceCopyOffloadProperty, StorageDeviceResiliencyProperty, StorageDeviceMediumProductType, } STORAGE_PROPERTY_ID, *PSTORAGE_PROPERTY_ID; //STORAGE_QUERY_TYPE枚举 typedef enum _STORAGE_QUERY_TYPE { PropertyStandardQuery = 0, // Retrieves the descriptor PropertyExistsQuery, // Used to test whether the descriptor is supported PropertyMaskQuery, // Used to retrieve a mask of writeable fields in the descriptor PropertyQueryMaxDefined // use to validate the value } STORAGE_QUERY_TYPE, *PSTORAGE_QUERY_TYPE; //我们的输出结构: typedef _Struct_size_bytes_(Size) struct _STORAGE_DEVICE_DESCRIPTOR { // Sizeof(STORAGE_DEVICE_DESCRIPTOR) DWORD Version; // Total size of the descriptor, including the space for additional data and id strings DWORD Size; // The SCSI-2 device type BYTE DeviceType; // The SCSI-2 device type modifier (if any) - this may be zero BYTE DeviceTypeModifier; // Flag indicating whether the device's media (if any) is removable. This // field should be ignored for media-less devices BOOLEAN RemovableMedia; // Flag indicating whether the device can support mulitple outstanding // commands. The actual synchronization in this case is the responsibility of the port driver. BOOLEAN CommandQueueing; // Byte offset to the zero-terminated ascii string containing the device's // vendor id string. For devices with no such ID this will be zero DWORD VendorIdOffset; // Byte offset to the zero-terminated ascii string containing the device's // product id string. For devices with no such ID this will be zero DWORD ProductIdOffset; // Byte offset to the zero-terminated ascii string containing the device's // product revision string. For devices with no such string this will be zero DWORD ProductRevisionOffset; // Byte offset to the zero-terminated ascii string containing the device's // serial number. For devices with no serial number this will be zero DWORD SerialNumberOffset; // Contains the bus type (as defined above) of the device. It should be // used to interpret the raw device properties at the end of this structure // (if any) STORAGE_BUS_TYPE BusType; // The number of bytes of bus-specific data which have been appended to this descriptor DWORD RawPropertiesLength; // Place holder for the first byte of the bus specific property data BYTE RawDeviceProperties[1]; } STORAGE_DEVICE_DESCRIPTOR, *PSTORAGE_DEVICE_DESCRIPTOR; //最后要根据BusType字段来判断 看一些这个类型: typedef enum _STORAGE_BUS_TYPE { BusTypeUnknown = 0x00, BusTypeScsi, BusTypeAtapi, BusTypeAta, BusType1394, BusTypeSsa, BusTypeFibre, BusTypeUsb,//这个就是移动硬盘了 BusTypeRAID, BusTypeiScsi, BusTypeSas, BusTypeSata, BusTypeSd, BusTypeMmc, BusTypeVirtual, BusTypeFileBackedVirtual, BusTypeSpaces, BusTypeNvme, BusTypeMax, BusTypeMaxReserved = 0x7F } STORAGE_BUS_TYPE, *PSTORAGE_BUS_TYPE; //下面附一段代码测试: int _tmain(int argc, _TCHAR* argv[]) { DWORD dwReturnLen = 0; PWCHAR pDrive = NULL; WCHAR wszDrive[MAX_PATH] = { 0 }; dwReturnLen = GetLogicalDriveStringsW(MAX_PATH, wszDrive); //WCHAR wszName[MAX_PATH] = { 0 }; HANDLE hDevice = NULL; if (dwReturnLen < MAX_PATH) { pDrive = wszDrive; while (*pDrive) { UINT uType = 0; uType = GetDriveTypeW(pDrive); if (uType == DRIVE_REMOVABLE) { printf("%ws:U盘.\n", pDrive); } else if (uType == DRIVE_CDROM) { printf("%ws:光驱.\n", pDrive); } else if (uType == DRIVE_FIXED) { //进一步判断移动硬盘或者本地硬盘 wstring wstrName(L"\\\\.\\"); wstrName.append(pDrive, 2); /*经测试\\.\C:\这种格式打不开, *如换成\\.\C:就可以打开了 */ hDevice = CreateFileW( wstrName.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (INVALID_HANDLE_VALUE == hDevice) { printf("createFile error code:(0x%08x).\n", GetLastError()); getchar(); return 0; } //输入查询参数 STORAGE_PROPERTY_QUERY PropertyQuery; //初始化PropertyQuery PropertyQuery.PropertyId = StorageDeviceProperty; PropertyQuery.QueryType = PropertyStandardQuery; BOOL bResult; DWORD dwBytesReturned = 0; //查询结果结构 STORAGE_DEVICE_DESCRIPTOR deviceDescriptor = { 0 }; deviceDescriptor.Size = sizeof(STORAGE_DEVICE_DESCRIPTOR); //STORAGE_BUS_TYPE bResult = DeviceIoControl( hDevice, IOCTL_STORAGE_QUERY_PROPERTY, //系统内置控制码 &PropertyQuery, sizeof(STORAGE_PROPERTY_QUERY), &deviceDescriptor, deviceDescriptor.Size, &dwBytesReturned, NULL); if (bResult) { //依据总线类型来判断 //printf("device:%ws storage bus type:%d \n", pDrive, deviceDescriptor.BusType); if (BusTypeUsb == deviceDescriptor.BusType) printf("%ws:移动硬盘 \n", pDrive); else //这里还可以再进一步详细划分 printf("%ws:本地硬盘 \n", pDrive); } CloseHandle(hDevice); hDevice = NULL; } else //if (uType == DRIVE_UNKNOWN) { printf("%ws:未知.\n", pDrive); } pDrive += 4; } } getchar(); return 0; }
测试结果:
说明:这里的结果是我自己的电脑上插了两个U盘,分别是8G和16G的,还有一个移动硬盘,自带一个光驱,安装了一个虚拟光驱。可以都能正确的识别出来
参考链接:
posted on 2018-10-09 11:23 priarieNew 阅读(1193) 评论(0) 编辑 收藏 举报