bladellz
驱动小牛
驱动小牛
  • 注册日期2006-03-20
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分1000分
  • 威望121点
  • 贡献值0点
  • 好评度120点
  • 原创分0分
  • 专家分0分
阅读:1602回复:6

怎么是识别U盘

楼主#
更多 发布于:2007-01-05 17:10
  插入U盘后,怎么识别是U盘。 DeviceType,Characteristics都不足以判断啊
znsoft
管理员
管理员
  • 注册日期2001-03-23
  • 最后登录2023-10-25
  • 粉丝300
  • 关注6
  • 积分910分
  • 威望14796点
  • 贡献值7点
  • 好评度2410点
  • 原创分5分
  • 专家分100分
  • 社区居民
  • 最爱沙发
  • 社区明星
沙发#
发布于:2007-01-05 17:14
从应用层识别,向设备发送特殊的ioctrol命令,它会告诉你它的底下是啥总线,如果是usb的,那就是u盘
http://www.zndev.com 免费源码交换网 ----------------------------- 软件创造价值,驱动提供力量! 淡泊以明志,宁静以致远。 ---------------------------------- 勤用搜索,多查资料,先搜再问。
znsoft
管理员
管理员
  • 注册日期2001-03-23
  • 最后登录2023-10-25
  • 粉丝300
  • 关注6
  • 积分910分
  • 威望14796点
  • 贡献值7点
  • 好评度2410点
  • 原创分5分
  • 专家分100分
  • 社区居民
  • 最爱沙发
  • 社区明星
板凳#
发布于: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;
    }




};
http://www.zndev.com 免费源码交换网 ----------------------------- 软件创造价值,驱动提供力量! 淡泊以明志,宁静以致远。 ---------------------------------- 勤用搜索,多查资料,先搜再问。
bladellz
驱动小牛
驱动小牛
  • 注册日期2006-03-20
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分1000分
  • 威望121点
  • 贡献值0点
  • 好评度120点
  • 原创分0分
  • 专家分0分
地板#
发布于:2007-01-06 10:51
驱动没法识别吗?
znsoft
管理员
管理员
  • 注册日期2001-03-23
  • 最后登录2023-10-25
  • 粉丝300
  • 关注6
  • 积分910分
  • 威望14796点
  • 贡献值7点
  • 好评度2410点
  • 原创分5分
  • 专家分100分
  • 社区居民
  • 最爱沙发
  • 社区明星
地下室#
发布于:2007-01-06 10:53
什么意思?这个还不够?

驱动中可以用一样的办法..
http://www.zndev.com 免费源码交换网 ----------------------------- 软件创造价值,驱动提供力量! 淡泊以明志,宁静以致远。 ---------------------------------- 勤用搜索,多查资料,先搜再问。
bladellz
驱动小牛
驱动小牛
  • 注册日期2006-03-20
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分1000分
  • 威望121点
  • 贡献值0点
  • 好评度120点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2007-01-07 15:35
DeviceIoControl
驱动和驱动有类似的API吗?
sosojohn
论坛版主
论坛版主
  • 注册日期2006-01-29
  • 最后登录2021-06-25
  • 粉丝0
  • 关注1
  • 积分1047分
  • 威望535点
  • 贡献值1点
  • 好评度178点
  • 原创分0分
  • 专家分0分
  • 社区居民
6楼#
发布于:2007-02-15 08:55
可以写一个Client驱动读PID,VID等参数,知道读到是USB 存储设备,
游客

返回顶部