Some questions related to serial number of USB, storages and readers

I'm currently working (or you can say, playing) with methods to obtain serial number of disk drives and have observed some scenarios that would like to have explanation. I appreciate any knowledge about them. I'll split the concerns into cases for easy reading.

To getting started, I understand that an USB reports a device identification number in the form
USB\VID_<4 characters of vendor id>&PID_<4 characters of product id>\<identification number>
where the identification number can be the serial number of the USB, or generated by the system if there isn't one. The identification number is formed by some rules of Windows related to information reported by the bus.

  1. I have an USB (let's call this A) connected to the PC. Its device instance id is USB\VID_xxxx&PID_yyyy\6&123456&1. I beleive that 6&123456&1 is the identification number generated by the system, not the actual serial of A (since it has the 6& prefix and &1 postfix). At the beginning, this ID number persists when I plug A into different port of the PC. However, after some time i call CM_Setup_Devnode on the USB, this ID changes. Note that this change does not happens every time CM_Setup_Devnode is triggered, but it does occasionally

[?] My question: Why doesn't this ID number change on changing the port, but on CM_Setup_Devnode calls, and on random times?

  1. I have another USB (let's call this B) and B has a serial X. I can extract this serial from both an USB kernel lower filter driver and SetupDi APIs. However, from the filesystem point of view, I cannot retrieve this using IOCTL_STORAGE_QUERY_PROPERTY: it returns only garbage characters. I did a small check using smartctl on the disk drive mounted by B and smartctl also cannot get the serial number of it

[?] My question: Is it true that X is the serial number of the USB only, not the disk inside it? (therefore I cannot get the serial of the disk drive inside the USB)

  1. I have a Seagate hard disk drive dock (the Seagate dock) and a Samsung HDD. When the HDD is put into the dock, I saw the USB Mass Storage entry in Device Manager, which i think is of the dock. The dock reports its device identification number as USB\VID_mmmm&PID_nnnn\2JHKDGF. I thought the 2JHKDGF is the serial number of the dock, however the tag on the dock shows another serial number.

[?] My question: Why is the dock report another serial number than on the tag? Which one should i follow?

  1. I have another disk drive dock, a Unitek one, which use usbjmicron protocol to communicate between the disk and PC. I put the Samsung HDD into this Unitek dock and check the device identification number of the dock, which now reports the serial number of the HDD in a messy way (the characters of the serial is messed up in an undefined order - not big endian nor little endian). I put another Western Digital Purple HDD (WDP HDD) to the dock, and now the device identification number reports another serial number (which is not of the WPD HDD)

[?] My question: Why is the identification number of the dock inteferred with the serial number of the disks, in a messy way?

  1. In case (3), the identification number of the Seagate dock persists for all HDD and port connected. In case (4), the identification number of the Unitek dock changes when a new HDD is inserted

[?] My question: Why is that? Does it relate to the protocol used for communication?

  1. I have a card reader. When I insert my SD card to it and try to get the disk drive information, I can only get the information of the card reader

[?] My question: Why is that? Is it true that the SD card does not specify any disk information and the only thing it store is the data and therefore, it must be read by a reader? If it's correct, then is it true that I cannot distinguish different SD cards?

Final question: I want to identify and distinguish the USB drive, the HDDs, cards, dock and card reader. From the above scenarios, what conclusion bellow is good? What other conclusion should I make, or should I adjust any of them?

  • USB can be identify and distinguished by the device identification number reported by the USB. The serial number (if there is) is also the serial number of the drive inside it

  • Other kinds of disk can be identified by their model, product name, revision (if there is), and serial number

  • Some docks does not have reliable serial number

  • Card readers can be identified by the device identification number

  • SD cards cannot be distinguised

Again, I would like to send thanks for reading my questions and give answers/references to all my concerns.

6&123456&1

Officially, this hardware identifier is undocumented, and any reliance on it is unsupported. Unofficially, it has stayed the same since USB support was introduced. The "6" says you are plugged into the 6th hub layer. The middle number is randomized. The final "1" is your port number in the hub, which might not relate to physical port numbers in any identifiable way.

That identifier will definitely change when you unplug/replug. More specifically, a new identifier will be created. If someone has a file open on the device, the old device object cannot be deleted until all the handles are closed.

Yes, the serial number in the USB\xxx hardware identifier is the serial number from the USB Device Descriptor. Many disk drive manufacturers do not program serial numbers in their descriptors.

USB disk drives use a SCSI command set. The SCSI command set was established LONG before USB was ever thought of, and has its own serial number protocol. Further, the USB scheme has to work with ALL USB devices. At the time the USB storage device is enumerated, there might not even be a drive installed.

So, you need to use the disk drive abstractions to extract the disk drive serial number, not the USB abstractions.

1 Like

Hi Tim,

Unofficially, it has stayed the same since USB support was introduced. The "6" says you are plugged into the 6th hub layer. The middle number is randomized. The final "1" is your port number in the hub, which might not relate to physical port numbers in any identifiable way.
That identifier will definitely change when you unplug/replug.

Thanks for the explanation on the randomized identifier. So if I understand you right, if a USB doesn't have a serial number, that identifier with be randomized everytime I replug the USB. So, for the behavior of CM_Setup_Devnode on the USB, it is the same as a replug, so the identifier will likely be change. If there is a change, it is because its logical port number and logical hub number has changed (not the physical port). Am i correct?

You need to use the disk drive abstractions to extract the disk drive serial number, not the USB abstractions

I also notice this and tried to use IOCTL_STORAGE_QUERY_PROPERTY on \\??\\PhysicalDriveX to get the serial number of the disk drive. As I wrote in case (2), for some USB, I cannot get the serial number of the disk drive. More specifically, the USB B only returns ☺♥ for the serial field (i inserted all the blanks here for correctness). So, can i conclude that these smiles and hearts are the serial number of the disk drive, or it does not have any serial number at all? If it truly does not have any serial number, why does it report such garbage characters?

Update: I have a related 7th question. Pardon me to put it here since I suddenly recalled it but cannot edit my original post:

  1. The Samsung HDD has 4 partitions displayed on My Computer. In my minifilter, I receive InstanceSetupCallback for the different pair of (disk number:partition): (1;0), (1;1), (1;2), (1;3). For the first partition (1;0), I notice that it associates with a disk object and therefore, use DEVPKEY_Device_Parent to get the parent's device instance ID of the disk USB\xxx, which is the of the dock in this case. For the other partition, I can only get ROOT\volmgr\0000, which is the device instance ID of the Volume Manager.

[?] My question: I would like to know how the volumes of the same hard disk drive are organized and their relationships to the disk object, the USB stack and volume manager. Can I get the physical parent of the volume when I'm at partition x (x != 0) and how?