我基本上试图检测简单的USB检测并从中检索某些信息。
这样做,对于常规USB FLASH
驱动器非常简单,因为大多数MSDN示例都显示。
HDEVNOTIFY hDevNotify;
DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;
ZeroMemory( &NotificationFilter, sizeof(NotificationFilter) );
NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
NotificationFilter.dbcc_classguid = GUID_DEVINTERFACE_USB_DEVICE;
hDevNotify = RegisterDeviceNotification(hWnd, &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE);
以及稍后,等待WM_DEVICECHANGE
消息DBT_DEVICEARRIVAL
我实际上得到了两条连续的消息:
第一条消息的 dbcc_name
:
\\?\USB#VID_0781&PID_5597#4C530001210518100555#{a5dcbf10-6530-11d2-901f-00c04fb951ed}
dbcc_name
第二条消息:
\\?\USBSTOR#Disk&Ven_SanDisk&Prod_Cruzer_Glide_3.0&Rev_1.00#4C530001210518100555&0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}
从这一个,我实际上可以检索友好名称等等。
现在,当我尝试使用手机连接时,我的问题就出现了。
当我使用普通USB线插入手机时,我
\\?\USB#VID_18D1&PID_4EE2#00c5c6f0839a25d4#{a5dcbf10-6530-11d2-901f-00c04fb951ed}
带有SetupDiGetDeviceRegistryProperty
的 SPDRP_DEVICEDESC
会返回USB Composite Device
当我在手机上授予文件传输存储权限时,我会收到第二条消息:
\\?\USB#VID_18D1&PID_4EE2#00c5c6f0839a25d4#{a5dcbf10-6530-11d2-901f-00c04fb951ed}
没有友好名称,使用
SetupDiGetDeviceRegistryProperty(hDevInfo, &spDevInfoData,
SPDRP_DEVICEDESC, &DataT, (PBYTE)buf, sizeof(buf), &nSize)
功能
这里有几个问题:
Windows如何将其识别为移动设备,甚至在通知栏中显示其名称( Nexus 5x ,选择以选择此设备会发生什么情况?)
让我们说我想从中复制某些文件。我如何获得WriteFile / CreateFile
GetLogicalDrivesStrings
如何为常规USB闪存驱动器检索新驱动器(" c:\\\0d:\\\0
")但对移动连接不做同样的操作
答案 0 :(得分:0)
查看手机上的对话框。你可能选择了一个名为" MTP"的选项。这是一个文件共享协议。另一方面,USB记忆棒使用块存储协议。这就是你获得USBSTOR
公告的原因。
块存储允许使用愚蠢的设备,并且需要主机上的智能(Windows)。它只有几百万个512字节的扇区。将其转换为文件是FAT(或NTFS)驱动程序的责任。
由于块存储使用FAT驱动程序,它会像内部硬盘一样获得驱动器号,并且可以通过CopyFile
访问。由于MTP设备不受文件系统管理,因此它们没有驱动器号。
为什么手机会使用MTP呢?最大的优势是MTP可以让手机更加可控。它可以逐个文件地决定是否将其显示给USB主机。
(披露:你也可以用FAT做到这一点,但我的前雇主可能仍然拥有专利。搜索"数据存储访问设备专利TomTom"如果这对你很重要)
答案 1 :(得分:0)
连接智能手机时,它首先显示为SCSI设备。那么USB协议支持几个属性(在vendorID
和productID
旁边),操作系统可以获得这样的信息,例如设备名称( NEXUS 5x ,...)属性字段manufacturer
和product
所以Windows不知道它是智能手机
以下是linux上udevadm info -a -p /sys/class/scsi_host/...
的输出:
looking at device '/devices/pci0000:00/0000:00:12.2/usb1/1-3/1-3:1.0/host42/scsi_host/host42':
KERNEL=="host42"
SUBSYSTEM=="scsi_host"
DRIVER==""
ATTR{unique_id}=="0"
ATTR{host_busy}=="0"
ATTR{cmd_per_lun}=="1"
ATTR{can_queue}=="1"
ATTR{sg_tablesize}=="65535"
ATTR{sg_prot_tablesize}=="0"
ATTR{unchecked_isa_dma}=="0"
ATTR{proc_name}=="usb-storage"
ATTR{state}=="running"
ATTR{supported_mode}=="Initiator"
ATTR{active_mode}=="Initiator"
ATTR{prot_capabilities}=="0"
ATTR{prot_guard_type}=="0"
looking at parent device '/devices/pci0000:00/0000:00:12.2/usb1/1-3/1-3:1.0/host42':
KERNELS=="host42"
SUBSYSTEMS=="scsi"
DRIVERS==""
looking at parent device '/devices/pci0000:00/0000:00:12.2/usb1/1-3/1-3:1.0':
KERNELS=="1-3:1.0"
SUBSYSTEMS=="usb"
DRIVERS=="usb-storage"
ATTRS{bInterfaceNumber}=="00"
ATTRS{bAlternateSetting}==" 0"
ATTRS{bNumEndpoints}=="02"
ATTRS{bInterfaceClass}=="08"
ATTRS{bInterfaceSubClass}=="06"
ATTRS{bInterfaceProtocol}=="50"
ATTRS{supports_autosuspend}=="1"
ATTRS{interface}=="Mass Storage"
looking at parent device '/devices/pci0000:00/0000:00:12.2/usb1/1-3':
KERNELS=="1-3"
SUBSYSTEMS=="usb"
DRIVERS=="usb"
ATTRS{configuration}==""
ATTRS{bNumInterfaces}==" 1"
ATTRS{bConfigurationValue}=="1"
ATTRS{bmAttributes}=="c0"
ATTRS{bMaxPower}=="500mA"
ATTRS{urbnum}=="195"
ATTRS{idVendor}=="feed"
ATTRS{idProduct}=="2002"
ATTRS{bcdDevice}=="ffff"
ATTRS{bDeviceClass}=="00"
ATTRS{bDeviceSubClass}=="00"
ATTRS{bDeviceProtocol}=="00"
ATTRS{bNumConfigurations}=="1"
ATTRS{bMaxPacketSize0}=="64"
ATTRS{speed}=="480"
ATTRS{busnum}=="1"
ATTRS{devnum}=="34"
ATTRS{devpath}=="3"
ATTRS{version}==" 2.00"
ATTRS{maxchild}=="0"
ATTRS{quirks}=="0x0"
ATTRS{avoid_reset_quirk}=="0"
ATTRS{authorized}=="1"
ATTRS{manufacturer}=="MediaTek"
ATTRS{product}=="X5"
ATTRS{serial}=="0123456789ABCDEF"
然后取决于您在智能手机上激活的功能。如果你想激活网络共享窗口将获得Android设备通知并加载RNDIS驱动程序。通知机制是USB连接的其余部分
如果你想从机器人大容量存储中写入或读取文件,你必须激活大容量存储选项,Windows将收到通知,并将android“挂载”为文件系统
所以android已经在其USB结构中实现了多个接口/ USB设备类,用户必须选择激活哪个接口(网络共享 - > RNDIS,存储 - > USB海量存储类,...)
这也是将android连接到Windows时没有出现新驱动器c:\\\0d:\\\0
的原因。首先,android显示为没有指定功能的SCSI设备(SCSI Target)
要在SCSI模式下与android通信,请参阅http://www.stackoverflow.com/questions/3316284/sending-a-specific-scsi-command-to-a-scsi-device-in-windows
如果您想要读取或写入手机(内部,SD卡)激活大容量存储选项,您可以使用普通的USB大容量存储接口(如USB记忆棒)
获取dbcc_name
的