|
阅读:1704回复:6
怎么是识别U盘
插入U盘后,怎么识别是U盘。 DeviceType,Characteristics都不足以判断啊
|
|
|
沙发#
发布于:2007-01-05 17:14
从应用层识别,向设备发送特殊的ioctrol命令,它会告诉你它的底下是啥总线,如果是usb的,那就是u盘
|
|
|
|
板凳#
发布于:2007-01-05 17:16
#pragma once
#include <tchar.h>
#include <winioctl.h>
/*
* USB 输助函数
* Author: M.Y
* Version: 1.0
* Revision: 1
*/
typedef enum _Sg_disk_type
{
NONE_TYPE=0,
IDE_DISK,
USB_DISK,
F1394_DISK, // 1394总线盘
}
SG_DISK_TYPE;
// SetupDiGetInterfaceDeviceDetail所需要的输出长度
#define INTERFACE_DETAIL_SIZE (1024)
// IOCTL_STORAGE_GET_MEDIA_TYPES_EX可能返回不止一条DEVICE_MEDIA_INFO,故定义足够的空间
#define MEDIA_INFO_SIZE (sizeof(GET_MEDIA_TYPES) + sizeof(DEVICE_MEDIA_INFO) * 15)
#define IOCTL_STORAGE_QUERY_PROPERTY CTL_CODE(IOCTL_STORAGE_BASE, 0x0500, METHOD_BUFFERED, FILE_ANY_ACCESS)
// 查询存储设备属性的类型
typedef enum _STORAGE_QUERY_TYPE {
PropertyStandardQuery = 0, // 读取描述
PropertyExistsQuery, // 测试是否支持
PropertyMaskQuery, // 读取指定的描述
PropertyQueryMaxDefined // 验证数据
} STORAGE_QUERY_TYPE, *PSTORAGE_QUERY_TYPE;
// 查询存储设备还是适配器属性
typedef enum _STORAGE_PROPERTY_ID {
StorageDeviceProperty = 0, // 查询设备属性
StorageAdapterProperty // 查询适配器属性
} STORAGE_PROPERTY_ID, *PSTORAGE_PROPERTY_ID;
// 查询属性输入的数据结构
typedef struct _STORAGE_PROPERTY_QUERY {
STORAGE_PROPERTY_ID PropertyId; // 设备/适配器
STORAGE_QUERY_TYPE QueryType; // 查询类型
UCHAR AdditionalParameters[1]; // 额外的数据(仅定义了象征性的1个字节)
} STORAGE_PROPERTY_QUERY, *PSTORAGE_PROPERTY_QUERY;
// 查询属性输出的数据结构
typedef struct _STORAGE_DEVICE_DESCRIPTOR {
ULONG Version; // 版本
ULONG Size; // 结构大小
UCHAR DeviceType; // 设备类型
UCHAR DeviceTypeModifier; // SCSI-2额外的设备类型
BOOLEAN RemovableMedia; // 是否可移动
BOOLEAN CommandQueueing; // 是否支持命令队列
ULONG VendorIdOffset; // 厂家设定值的偏移
ULONG ProductIdOffset; // 产品ID的偏移
ULONG ProductRevisionOffset; // 产品版本的偏移
ULONG SerialNumberOffset; // 序列号的偏移
STORAGE_BUS_TYPE BusType; // 总线类型
ULONG RawPropertiesLength; // 额外的属性数据长度
UCHAR RawDeviceProperties[1]; // 额外的属性数据(仅定义了象征性的1个字节)
} STORAGE_DEVICE_DESCRIPTOR, *PSTORAGE_DEVICE_DESCRIPTOR;
class SgUSB
{
public:
static SG_DISK_TYPE GetDriveType(TCHAR chDrv)
{
TCHAR szDeviceName[7]=_T("\\\\?\\x:");
SG_DISK_TYPE disktype;
PSTORAGE_DEVICE_DESCRIPTOR pDevDesc;
pDevDesc = (PSTORAGE_DEVICE_DESCRIPTOR)new BYTE[sizeof(STORAGE_DEVICE_DESCRIPTOR) + 512 - 1];
pDevDesc->Size = sizeof(STORAGE_DEVICE_DESCRIPTOR) + 512 - 1;
szDeviceName[4]=chDrv;
HANDLE hHandle=OpenDevice(szDeviceName);
if( hHandle == INVALID_HANDLE_VALUE )
return NONE_TYPE;
if(GetDriveProperty(hHandle,pDevDesc) )
{
switch(pDevDesc->BusType )
{
case BusType1394:
disktype = F1394_DISK;
break;
case BusTypeUsb:
disktype =USB_DISK;
break;
default:
disktype= NONE_TYPE;
}
}
else
disktype= NONE_TYPE;
delete []pDevDesc;
CloseHandle(hHandle);
return disktype;
}
static HANDLE OpenDevice(LPCTSTR pszDevicePath)
{
HANDLE hDevice;
// 打开设备
hDevice= ::CreateFile(pszDevicePath, // 设备路径
GENERIC_READ | GENERIC_WRITE, // 读写方式
FILE_SHARE_READ | FILE_SHARE_WRITE, // 共享方式
NULL, // 默认的安全描述符
OPEN_EXISTING, // 创建方式
0, // 不需设置文件属性
NULL); // 不需参照模板文件
return hDevice;
}
static BOOL GetDriveGeometry(HANDLE hDevice, PDISK_GEOMETRY pGeometry)
{
PGET_MEDIA_TYPES pMediaTypes; // 内部用的输出缓冲区
DWORD dwOutBytes; // 输出数据长度
BOOL bResult; // DeviceIoControl的返回结果
// 申请内部用的输出缓冲区
pMediaTypes = (PGET_MEDIA_TYPES)::GlobalAlloc(LMEM_ZEROINIT, MEDIA_INFO_SIZE);
// 用IOCTL_STORAGE_GET_MEDIA_TYPES_EX取介质类型参数
bResult = ::DeviceIoControl(hDevice, // 设备句柄
IOCTL_STORAGE_GET_MEDIA_TYPES_EX, // 取介质类型参数
NULL, 0, // 不需要输入数据
pMediaTypes, MEDIA_INFO_SIZE, // 输出数据缓冲区
&dwOutBytes, // 输出数据长度
(LPOVERLAPPED)NULL); // 用同步I/O
if(bResult)
{
// 注意到结构DEVICE_MEDIA_INFO是在结构DISK_GEOMETRY的基础上扩充的
// 为简化程序,用memcpy代替如下多条赋值语句:
// pGeometry->MediaType = (MEDIA_TYPE)pMediaTypes->MediaInfo[0].DeviceSpecific.DiskInfo.MediaType;
// pGeometry->Cylinders = pMediaTypes->MediaInfo[0].DeviceSpecific.DiskInfo.Cylinders;
// pGeometry->TracksPerCylinder = pMediaTypes->MediaInfo[0].DeviceSpecific.DiskInfo.TracksPerCylinder;
// ... ...
::memcpy(pGeometry, pMediaTypes->MediaInfo, sizeof(DISK_GEOMETRY));
}
// 释放内部缓冲区
::GlobalFree(pMediaTypes);
return bResult;
}
static BOOL GetDriveProperty(HANDLE hDevice, PSTORAGE_DEVICE_DESCRIPTOR pDevDesc)
{
STORAGE_PROPERTY_QUERY Query; // 查询输入参数
DWORD dwOutBytes; // IOCTL输出数据长度
BOOL bResult; // IOCTL返回值
// 指定查询方式
Query.PropertyId = StorageDeviceProperty;
Query.QueryType = PropertyStandardQuery;
// 用IOCTL_STORAGE_QUERY_PROPERTY取设备属性信息
bResult = ::DeviceIoControl(hDevice, // 设备句柄
IOCTL_STORAGE_QUERY_PROPERTY, // 取设备属性信息
&Query, sizeof(STORAGE_PROPERTY_QUERY), // 输入数据缓冲区
pDevDesc, pDevDesc->Size, // 输出数据缓冲区
&dwOutBytes, // 输出数据长度
(LPOVERLAPPED)NULL); // 用同步I/O
return bResult;
}
}; |
|
|
|
地板#
发布于:2007-01-06 10:51
驱动没法识别吗?
|
|
|
地下室#
发布于:2007-01-06 10:53
什么意思?这个还不够?
驱动中可以用一样的办法.. |
|
|
|
5楼#
发布于:2007-01-07 15:35
DeviceIoControl
驱动和驱动有类似的API吗? |
|
|
6楼#
发布于:2007-02-15 08:55
可以写一个Client驱动读PID,VID等参数,知道读到是USB 存储设备,
|
|