I'm basically trying to detect a simple USB detection and retrieve certain information from it.
Doing so, for a regular USB FLASH drive is quite simple, as most of the MSDN samples show.
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);
and later on, wait for a WM_DEVICECHANGE message with DBT_DEVICEARRIVAL
i actually get 2 sequential messages:
dbcc_name of the first message :
\\?\USB#VID_0781&PID_5597#4C530001210518100555#{a5dcbf10-6530-11d2-901f-00c04fb951ed}
dbcc_name of the second message:
\\?\USBSTOR#Disk&Ven_SanDisk&Prod_Cruzer_Glide_3.0&Rev_1.00#4C530001210518100555&0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}
From this one, i can actually retrieve the friendaly name and so on.
Now, my problem occurs when i try to do the same with phone connection.
When i plug my phone using a regular USB cable, i get
\\?\USB#VID_18D1&PID_4EE2#00c5c6f0839a25d4#{a5dcbf10-6530-11d2-901f-00c04fb951ed}
SetupDiGetDeviceRegistryProperty with SPDRP_DEVICEDESC returns USB Composite Device
And when i grant file transfer storage permissions on my mobile, i get a second message with:
\\?\USB#VID_18D1&PID_4EE2#00c5c6f0839a25d4#{a5dcbf10-6530-11d2-901f-00c04fb951ed}
without a friendly name, using the
SetupDiGetDeviceRegistryProperty(hDevInfo, &spDevInfoData,
SPDRP_DEVICEDESC, &DataT, (PBYTE)buf, sizeof(buf), &nSize)
function.
So couple of questions here:
How does windows recognize this as a mobile device, and even shows its name in the notifications bar (Nexus 5x, Select to choose what happens with this device)?
Lets say i would like to copy certain files from or to it. how do i get device handle or device path for WriteFile / CreateFile
How come GetLogicalDrivesStrings retrieves a new drive("c:\\\0d:\\\0") for a regular USB flash drive but doesn't do the same for mobile connection?
Look at the dialog on your phone. You probably picked an option named "MTP". This is a file sharing protocol. On the other hand, the USB stick uses a block storage protocol. That's why you get the USBSTOR announcement.
Block storage allows for dumb devices, and requires intelligence on the host (Windows). It's just a few million 512-byte sectors. Turning that into files is the responsibility of the FAT (or NTFS) driver.
Since block storage uses the FAT driver, it gets a drive letter just like internal hard disks, and can be accessed via CopyFile. Since MTP devices aren't managed by the file system, they don't have drive letters.
Why do mobile phones use MTP then? The big advantage is that MTP allows the phone to be much more in control. It can decide on a file by file basis whether to show it to the USB host.
(Disclosure: you can do that with FAT as well, but my former employer may still have a patent on that. Search for "Data storage access device patent TomTom" if this matters to you)
when a smartphone is connected it appears at first as a SCSI device. then USB protocol supports several attributes (beside vendorID and productID) from that an operating system can get informations like the device name (NEXUS 5x,...) for this especially the attribute fields manufacturer and product
so windows does not 'know' it is a smartphone
the following is the output of udevadm info -a -p /sys/class/scsi_host/... on linux:
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"
then it depends what function you activate on your smartphone. if you want to activate tethering windows will get notified by the android device and load the RNDIS driver. the notification mechanism is a rest of the USB connection
if you want to write or read files from the androids mass storage you have to activate the mass storage option and windows will get notified and 'mount' the android as a file system
so an android has implemented multiple interfaces / USB device classes in its USB structure and the user has to choose which interface to activate (tethering -> RNDIS, storage -> USB mass storage class,...)
this is also the reason why no new drive c:\\\0d:\\\0 appears when you connect the android to windows. At first the android appears as a SCSI device with no specified function (SCSI Target)
For communication with the android in SCSI mode see http://www.stackoverflow.com/questions/3316284/sending-a-specific-scsi-command-to-a-scsi-device-in-windows
if you want to read or write the phones (internal, SD card) activate the mass storage option and you can use the normal USB mass storage interface (like USB memory stick)
for getting the dbcc_name maybe see http://www.stackoverflow.com/questions/2208722/how-to-get-friendly-device-name-from-dev-broadcast-deviceinterface-and-device-in
Related
I want to Read/Write sector (not in File System) from Android device internal storage and SD card.
The android device is connected via MTP.
Normally, we can use CreateFile/ReadFile/WriteFile API functions for Read/Write sector from DISK in Windows. Also, can use fopen/fread/fwrite functions in Linux.
But about the android device which is connected via MTP, I have no experience.
If it is possible, please tell me a method.
I want to do it using C/C++ in Windows or Linux.
Thank you. 💖
What you are asking for is not possible.
The whole point of MTP is to abstract away the mass storage aspect and even the file system. You are communicating over a protocol that is based on commands like "copy this file", "what folders are there", etc., and it's up to the device to interpret these commands. Some devices (not Android, but some older handhelds) would even have a layer of file conversion for Office documents while transferring them.
This way, the device can keep using its storage while allowing you to access it as well. In the "mass storage device" mode that older Android versions supported, the storage medium had to be unmounted while it was made accessible to the PC. With MTP that does not happen. So, it wouldn't be logical to have a way to modify individual sectors over MTP, as that would clash with the device's file system drivers' authority over the storage medium, and also it would bypass security mechanisms.
(Technically, a phone manufacturer could implement a vendor-specific custom command over MTP for accessing sectors, but why would anyone do that?)
If you want to know how to access individual files though (using MTP as intended), the keyword you need is Windows Portable Devices. (Not sure about Linux.)
The only other way to gain low-level access would be over ADB shell, but that would require a rooted device, otherwise you wouldn't be able to access the storage devices directly from within Android.
I have managed to enumerate all the connected USB ports using SetupDi calls. Sample code is available at this link.
Please could any one tell me how can I find what device is connected to USB port like whether it is any HID device or any Disk drive?
Thanks.
I would recommend looking at the USBView sample in the WDK. If you are unfamiliar with this, simply run it - this tool walks the entire USB tree on the system and prints out information and descriptor listings for each device.
In your case, I'd start at the RefreshTree() function in this sample, you can then follow the code to see how it enumerates the host controllers, hubs and finally devices. For each device that you find you can look at the bInterfaceClass in the interface descriptors to find out what types of interfaces it is advertising (in your case 0x03 for HID Interface Class and 0x08 for Mass Storage Class).
The easiest way to get the source to this sample is to install the 7.1.0 WDK which is currently available here:
http://www.microsoft.com/en-us/download/details.aspx?id=11800
First of all, we are working with a 3rd party software that ties itself to a USB device. When this USB device is disconnected and reconnected, the software cannot communicate with the device will stop working until the program is restarted. i.e. It only detects the USB device on startup.
Windows is able to see the device, but goes through the full detection/driver installation procedure every time it is reconnected, even if it is reconnected to the same USB port.
The difficulty here is that we have no way of modifying the third party software to poll for the appropriate USB device after the device is unplugged.
As such, we would like to ask if anyone has knowledge on how to go about writing a c++ program to save a USB state/register, prevent Windows from re-enumerating the USB port upon re-connection, and restoring the saved state/register. If so, we would appreciate some guidance in this endeavor. Naturally, we are open to other approaches to solving this issue.
You can't do this at application level. USB is managed by drivers. Furthermore, while the details of USB devices are managed by specific drivers, the basics (such as enumeration) are handled by the standard Windows USB driver. That's logical: Windows has to enumerate the device first to determine its Vendor ID and Product ID, which then determines the specific driver to load.
As for the full reinstallation on every reinsertion, that suggests a violation of the USB spec by the device or the Windows API by the driver. My first guess would be that the device doesn't have a proper serial number.
I would be using a USB hub to connect multiple devices. I want to fix a specific USB device to a particular slot. Then check if it is done properly.
The way I am planning to achieve this is to get the complete USB path like
PCIROOT(0)#PCI(1D00)#USBROOT(0)#USB(1)#USB(2)#USB(3)#USB(3)
I can get this particular string in w7 via device property but the same is not available in wXP.
You can build this path by using the SetupAPI.
The device manager is built with this.
You start with CM_Locate_DevNode and enumerate children with CM_Get_Child.
I strongly advise you against what you're planning to do. AFAIK a USB device MUST function regardless on the USB port it's plugged in. If you'll creating such a device, forget e.g. about the "Certified for Windows" logo.
Just handle WM_DEVICECHANGE message, then use e.g. WMI to search for the USB device you're interested in. Here's my article about it: that time I coded C# language, however WMI has C++ API as well.
I would like to get USB hard disk serial number ,vendor id ,product id without WMI,I found the
USBSTOR\Disk&Ven_ST932042&Prod___5VJ101RR&Rev_SDM1\222256410122&0
the serial number is 5VJ101RR but it show in the product id which is wrong,
how can i get the correct USB disk vendor id,product id, serial number
My develop environment is visual c++ 2008
thanks
A simple way to get VID and PID would be to load the devices INI file from %WINDOWS%\System32, I think that is where the INIs are usually copied. If you know the name of the INI file then it is trivial. If you are looking for a programmatic method, you can enumerate the USB bus using the Win32 Setup API.
If you have installed the Wnidows Driver Kit on your machine, take a look at the USBVIEW sample application. It demonstrates how you can enumerate the USB bus and get a list of all devices including their PID and VID.
To get the serial number, look at the GetVolumeInformation() system call.