VB6 - Get USB Flash Media Serial without WMI or Admin Rights-VBForums
Results 1 to 18 of 18

Thread: VB6 - Get USB Flash Media Serial without WMI or Admin Rights

  1. #1

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    11,601

    Question VB6 - Get USB Flash Media Serial without WMI or Admin Rights

    This is a Proposal

    Update: This is only partially successful, working properly in Vista and later but not XP.

    I am not putting this forward as "finished code, ready for prime time" but instead as a proposed technique and a testing prototype.

    If we get enough positive testing feedback (and possibly some adjustments or bug fixes) it may well be of use in the future.

    As a code sample needing more testing, I've marked this thread with a "question mark" icon. But it looks good enough and the prototype contains enough other useful sample code to be worth posting here instead of in the Testing forum. If the moderators disagree they can always move it of course.


    Some Background

    Authors of portable software designed to be installed onto a Flash Drive often need some way to enforce licensing. Usually they do this through an installer utility that verifies the number of copies left and then performs the install.

    The "copies left" part is important because often the product license allows only 1, 2, or some limited number of Flash Drives to be installed to. Some of the better products allow an uninstall as well allowing license recapture, permitting users to move a license from an old device onto a new one.

    None of that is addressed here. Beyond that however there is a need for license enforcement, and that's the issue that is addressed here.


    Flash Devices and Software Licensing

    The kinds of devices I'm talking about are USB Flash Drives and Flash media cards used in "USB Card Reader" devices.

    These normally have a media serial number asigned during manufacture that can't be trivially altered, unlike the volume serial number created during formatting. So this MediaSerial value can often be used in license enforcement much as other things like network adapter MAC addresses and hard drive serial numbers can for non-portable desktop software.


    Getting the MediaSerial

    Obtaining drive media serial numbers can be fairly painful.

    Some people try to use hardware-level I/O which can be reliable but fails without admin rights in modern Windows versions. Others rely on WMI which does he same thing via a system service that many people disable because (a.) it's a pig, and (b.) it's a potential security hazard.

    Even though shutting it off has become more difficult to sustain in modern Windows versions (as parts of the system management utilities have moved to .Net there is more and more sloppy use of WMI by these tools), it would be cleaner and safer to use some non-WMI approach. After all, WMI is an administration tool, not something an application should ever rely on.

    Another aproach involves going through USB enumeration data, either through API calls or directly from the registry. This can also get a bit convoluted.


    Proposal and Prototype

    It appears that starting with Windows 2000 we can get the MediaSerial by fishing around in the registry key:
    HKLM\SYSTEM\MountedDevices
    My idea is that given a drive letter to check, if we can (a.) verify that the drive is a "removable" type drive, and (b.) verify that the device is "ready" then the \DosDevices\x: value contains the info we need in a predictable format (where "x" is our drive letter).

    This indeed seems to be the same or very similar information format used by enumeration spelunking techniques, but in this case we don't have to fish around as much. Of course those "verification" steps amount to the same thing, but we have less coding to do in our application.

    Notes:
    This approach works without using WMI and does not require administrator rights.

    It is not intended as a means of getting hard drive serial numbers, but you might consider the WGA attributes as a possible solution.

    It does not work for USB hard drives.

    Issues

    I have tested this with a number of types of Flash memory devices on a number of systems, but I still don't know if this technique is accurate enough "for prime time." It needs further testing.

    So far I have tested it on Windows Vista 32-bit, Windows Vista 64-bit, and Windows 7 32-bit. I plan to test on Windows XP 32-bit soon.

    I have tried several models of SanDisk USB Flash Drives. I've also tested several kinds of Flash memory cards in several card drives ("readers"): SmartMedia, XD, SD & microSD, and CF.

    So far so good, the results are consistent with those of the 3rd party utility ListUsbDrives by Uwe Sieber. Reports of more test results would be appreciated. Also look at a discussion of some issues in comments at the head of DriveInfo.cls.


    Additional Drive Attributes

    As written, my prototype is a VB6 Class, included here as part of a demo Project.

    It can also return a number of other things about the drives on a system, some of them are also useful in a "licensed portable software installer" program.


    WGA Attributes

    The DriveInfo class also has properties for fetching several Windows Genuine Advantage registry key values. These may or may not prove useful to you for licensing purposes. Their presence and reliability is probably such that they'd prove impractical.

    This topic is also addressed in the comments inside DriveInfo.cls.

    I included these because they might be of value to some people. A lot of people aren't aware of them.


    Feedback

    If anyone has some serious experience with using the WGA attributes for licensing that might be of interest. Otherwise opinions about this are off topic - I already know this isn't solid data. If you've used this for license enforcement and can give us a "viability" reading on it that would worth hearing about.

    I just don't want to see 300 posts about how dumb the idea of using WGA is, ok? One or two are plenty!

    Of much more interest to me (and probably to others) would be test results for MediaSerial values using other equipment and software configurations, and any bug reports or suggestions that improve the heuristics used.

    32 vs. 64-bit doesn't appear important. Windows 2000, Windows XP, and Windows 8 test coverage would be useful though. The same is true for Server OSs such as Windows Server 2003, 2003 R2, 2008, and 2008 R2.

    Other Flash Drive media results would be good too. So far I haven't found any that don't return unique MediaSerial values except for an Android Phone's internal media I'm suspicious of. Even there its microSD card returned good results.


    Testing

    The easiest approach here may be to just compile the example Project and copy the EXE to a Flash Drive. It has no dependencies that are not already present in the target range of Windows OSs (Win2K and later).

    For local testing you won't even need to copy the program. Just run from the IDE or compile and then run the EXE.

    Use the Report menu to report on all drives or else those that appear to be returning recognized MediaSerial values.

    Of course without plugging in a USB Flash Drive or memory card the test wouldn't be too meaningful.
    Attached Images Attached Images  
    Attached Files Attached Files
    Last edited by dilettante; Mar 31st, 2012 at 06:25 AM.

  2. #2
    Addicted Member
    Join Date
    Mar 2007
    Location
    India
    Posts
    189

    Re: VB6 - Get USB Flash Media Serial without WMI or Admin Rights

    Hi,

    Thanks for this sample.

    I am not getting the output as you have stated.

    Here is your software's output on my PC
    SystemDrive() = "C:\"

    WgaHDSerial = ""
    WgaMAC = ""
    WgaUGD = ""

    Drives() = "C:\",
    "D:\",
    "E:\",
    "F:\",
    "G:\",
    "H:\",
    "I:\"

    Reporting all drives:

    CheckDrive("C:\")
    CheckResult = 0
    CheckText = "CheckDrive completed successfully."
    ErrorCode = 0
    ErrorText = "The operation completed successfully. "
    DriveType = 3
    DriveTypeText = "Fixed"
    FileSystem = "NTFS"
    FreeBytes = 160,237,871,104
    MaxComponentLength = 255
    MediaSerial = ""
    TotalBytes = 214,745,575,424
    VolName = "Drv_C"
    VolSerial = "CC86-3003"

    CheckDrive("D:\")
    CheckResult = 0
    CheckText = "CheckDrive completed successfully."
    ErrorCode = 0
    ErrorText = "The operation completed successfully. "
    DriveType = 3
    DriveTypeText = "Fixed"
    FileSystem = "NTFS"
    FreeBytes = 92,263,530,496
    MaxComponentLength = 255
    MediaSerial = ""
    TotalBytes = 214,745,575,424
    VolName = "Drv_D"
    VolSerial = "1CB8-9E56"

    CheckDrive("E:\")
    CheckResult = 0
    CheckText = "CheckDrive completed successfully."
    ErrorCode = 0
    ErrorText = "The operation completed successfully. "
    DriveType = 3
    DriveTypeText = "Fixed"
    FileSystem = "NTFS"
    FreeBytes = 4,749,410,304
    MaxComponentLength = 255
    MediaSerial = ""
    TotalBytes = 70,605,770,752
    VolName = "Drv_E"
    VolSerial = "44C9-23BD"

    CheckDrive("F:\")
    CheckResult = 0
    CheckText = "CheckDrive completed successfully."
    ErrorCode = 0
    ErrorText = "The operation completed successfully. "
    DriveType = 5
    DriveTypeText = "CD-ROM"
    FileSystem = "CDFS"
    FreeBytes = 0
    MaxComponentLength = 110
    MediaSerial = ""
    TotalBytes = 113,930,240
    VolName = "SoftKey3"
    VolSerial = "0B32-5C52"

    CheckDrive("G:\")
    CheckResult = 0
    CheckText = "CheckDrive completed successfully."
    ErrorCode = 0
    ErrorText = "The operation completed successfully. "
    DriveType = 3
    DriveTypeText = "Fixed"
    FileSystem = "NTFS"
    FreeBytes = 77,676,544
    MaxComponentLength = 255
    MediaSerial = ""
    TotalBytes = 104,853,504
    VolName = "System Reserved"
    VolSerial = "92D8-2DF9"

    CheckDrive("H:\")
    CheckResult = 0
    CheckText = "CheckDrive completed successfully."
    ErrorCode = 0
    ErrorText = "The operation completed successfully. "
    DriveType = 3
    DriveTypeText = "Fixed"
    FileSystem = "NTFS"
    FreeBytes = 238,477,864,960
    MaxComponentLength = 255
    MediaSerial = ""
    TotalBytes = 249,952,202,752
    VolName = "Drv_H"
    VolSerial = "16EC-1404"

    CheckDrive("I:\")
    CheckResult = 0
    CheckText = "CheckDrive completed successfully."
    ErrorCode = 0
    ErrorText = "The operation completed successfully. "
    DriveType = 2
    DriveTypeText = "Removable"
    FileSystem = "FAT32"
    FreeBytes = 2,145,959,936
    MaxComponentLength = 255
    MediaSerial = ""
    TotalBytes = 3,997,851,648
    VolName = "Yogi_USB"
    VolSerial = "B0D9-50B1"

    Reported 7 drives.
    As you must have already observed that WgaHDSerial, WgaMAC & WgaUGD are coming up empty.

    My PC is Intel Pentium D with 4 GB RAM and Two HDDs.

    Regards,

    Yogi Yang

  3. #3

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    11,601

    Re: VB6 - Get USB Flash Media Serial without WMI or Admin Rights

    The lack of data returned by the WGA properties isn't really surprising. There are probably several categories of machines that will never have this data. For example machines with Windows installed under Microsoft Volume License programs probably won't if users have never performed any downloads requiring WGA validation.

    Your drive I:\ results are of more interest.

    What sort of drive is this?

    I may have to post a "diagnostic" version of the program to aid in troubleshooting this issue. I should have thought about doing that earlier I suppose.

    Thanks for posting those results.

  4. #4

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    11,601

    Re: VB6 - Get USB Flash Media Serial without WMI or Admin Rights

    Ok, here is a version that has another menu choice to display all removable devices along with a hex dump of their "DosDevice" registry value's contents.

    This should make it easier to figure out where the logic fails for some devices, though it will report on floppy drives and such as well. In feedback please specify which of your USB Flash drives get an empty MediaSerial value. It would help to know which drive letter, what make/model/type of device it is, and of course to see the dump of the DosDevice data.

    Thanks.
    Attached Files Attached Files

  5. #5
    Addicted Member
    Join Date
    Mar 2007
    Location
    India
    Posts
    189

    Re: VB6 - Get USB Flash Media Serial without WMI or Admin Rights

    Quote Originally Posted by dilettante View Post
    Your drive I:\ results are of more interest.
    Drive I: is my USB pen drive which is a Kingston DataTraveller 120.

    I also use a USB monitor software called USB Safely Remove version 4.6.2.x

    Hope this help.

    Regards,
    Last edited by yogiyang; Mar 20th, 2012 at 10:03 AM. Reason: Forgot to mention usage of a USm monitor software

  6. #6
    Addicted Member
    Join Date
    Mar 2007
    Location
    India
    Posts
    189

    Re: VB6 - Get USB Flash Media Serial without WMI or Admin Rights

    Here is the dump from your program

    *** Dump of DosDevice contents ***
    0000 5c 3f 3f 5c 53 54 4f 52 41 47 45 23 52 65 6d 6f \??\STORAGE#Remo
    0010 76 61 62 6c 65 4d 65 64 69 61 23 37 26 36 36 39 vableMedia#7&669
    0020 34 37 36 32 26 30 26 52 4d 23 7b 35 33 66 35 36 4762&0&RM#{53f56
    0030 33 30 64 2d 62 36 62 66 2d 31 31 64 30 2d 39 34 30d-b6bf-11d0-94
    0040 66 32 2d 30 30 61 30 63 39 31 65 66 62 38 62 7d f2-00a0c91efb8b}


    Reported 1 removable drives with DosDevice dump.

  7. #7

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    11,601

    Re: VB6 - Get USB Flash Media Serial without WMI or Admin Rights

    Interesting.

    This is reported as a STORAGE class device, not the expected USBSTOR class.

    What kind of device is it? Is it a Flash Memory based device? What value should be reported as the serial number for this one?

    Which version of Windows are you testing on?

  8. #8
    Addicted Member
    Join Date
    Mar 2007
    Location
    India
    Posts
    189

    Re: VB6 - Get USB Flash Media Serial without WMI or Admin Rights

    Quote Originally Posted by dilettante View Post
    Which version of Windows are you testing on?
    I am using Window XP with SP3.

    Quote Originally Posted by dilettante View Post
    What kind of device is it?

    Is it a Flash Memory based device?

    What value should be reported as the serial number for this one?
    It a normal USB 4GB pen drive.

    No it is not Flash Memory based device.

    I have another utility developed someone in .NET using VS2010.

    This utility reports following details:
    Manufacturer: Kingston
    Product Name: DataTraveller 120
    Vendor ID: 0931
    Product ID: 6544
    Serial No.: 001CC0EC34BFC030569708CC

    Finally your software returns following for SanDisk U3 Cruzer Micro USB Pen Drive:

    CheckDrive("J:\")
    CheckResult = 0
    CheckText = "CheckDrive completed successfully."
    ErrorCode = 0
    ErrorText = "The operation completed successfully. "
    DriveType = 2
    DriveTypeText = "Removable"
    FileSystem = "FAT32"
    FreeBytes = 263,843,840
    MaxComponentLength = 255
    MediaSerial = ""
    TotalBytes = 4,006,072,320
    VolName = "MAIN_USB"
    VolSerial = "484C-4F78"
    *** Dump of DosDevice contents ***
    0000 5c 3f 3f 5c 53 54 4f 52 41 47 45 23 52 65 6d 6f \??\STORAGE#Remo
    0010 76 61 62 6c 65 4d 65 64 69 61 23 37 26 31 34 62 vableMedia#7&14b
    0020 34 64 30 31 38 26 30 26 52 4d 23 7b 35 33 66 35 4d018&0&RM#{53f5
    0030 36 33 30 64 2d 62 36 62 66 2d 31 31 64 30 2d 39 630d-b6bf-11d0-9
    0040 34 66 32 2d 30 30 61 30 63 39 31 65 66 62 38 62 4f2-00a0c91efb8b
    0050 7d
    BTW I am also attaching the .NET project for your reference. Just in case it may help you.

    Regards,
    Attached Files Attached Files

  9. #9

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    11,601

    Re: VB6 - Get USB Flash Media Serial without WMI or Admin Rights

    Sorry, somehow I had missed your comments in post #5 above, oops! The Kingston DataTraveller series products are indeed Flash Memory devices, and actually fairly generic ones from what the Kingston data sheets say. Hmm.

    I'm not sure whether USB Safely Remove has an impact here. I suppose it might but I'll have to look deeper.

    What I suspect now is that XP handles these devices somewhat differently from the way Vista, Windows 7, and Windows 8 do. It could actually be the USB drivers rather than Windows itself, but in most cases we'd be using the generic drivers that come with Windows. But for all I know USB Safely Remove installs a custom driver.

    I'll have to try some of the devices that I have here on an XP machine.


    That .Net project appears to be using hardware-level I/O that requires admin rights on current versions of Windows. Windows XP was the last version allowing such unsecured access. So that defeats the intended purpose I was targeting, which requires access to the serial number when the user does not have admin rights.

    This caused no end of problems for existing software that "broke" when users moved away from XP.

    This did seem all too easy, so perhaps the idea just isn't going to work for enough systems to make it viable.

  10. #10
    Hyperactive Member
    Join Date
    Aug 2010
    Location
    Canada
    Posts
    364

    Re: VB6 - Get USB Flash Media Serial without WMI or Admin Rights

    What about trying the hardware level IO first, and if it fails then trying your method?

    If WinVista+ consistently works with your method and the admin/hardware IO method when logged in as an administrator, and WinXP works consistently with only the hardware IO method, then this should be sufficient for the code to perform as expected under the vast majority of scenarios.

  11. #11

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    11,601

    Re: VB6 - Get USB Flash Media Serial without WMI or Admin Rights

    Yeah, that's an idea. I'll take another look at this soon when I can have a few more devices and an XP system to test on.

  12. #12

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    11,601

    Re: VB6 - Get USB Flash Media Serial without WMI or Admin Rights

    After testing I've confirmed that XP doesn't store the necessary information for USB Flash drives where Vista and later do, so more effort is required in order to support XP.

    I can use hardware I/O (actually this seems to be driver interrogation) to get serial numbers w/o admin rights for internal hard drives but it doesn't return a serial number for USB Flash drives or even for USB hard drives. Same results for this on XP, Vista, and Win7.

    Actually true hardware I/O can also get the serial number from internal hard drives, but this requires admin rights and still doesn't work for USB devices.

    It appears that the info is available for USB drives, but it may take a lot more effort to get it.


    The more I fiddle with this the shakier it all seems. It looks like a new version of Windows could easily come along and break what's working now. Even the WMI method is erratic about returning the information, requiring different logic for various OSs.

  13. #13

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    11,601

    Re: VB6 - Get USB Flash Media Serial without WMI or Admin Rights

    Quote Originally Posted by dilettante View Post
    I can use hardware I/O (actually this seems to be driver interrogation) to get serial numbers w/o admin rights for internal hard drives...
    This isn't true for all combinations of OS and drive either.

    It looks like a more reliable method for either hard drives or flash drives will be substantially more work. So much so that if I get it working I probably won't be just giving it away.


    The approach I was exploring here seems to be a dead end.

    Sorry if I got anyone's hopes up!

  14. #14

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    11,601

    Thumbs up Another Approach: This Time For Sure?

    I meant to follow up on this but I haven't gotten around to cleaning up the code until now.


    Trying Again

    Here is another approach to getting USB Flash Drive media serial numbers.

    It does not work for regular hard drives, SSDs, or even USB hard drives or SSDs, or any other type of drive. It is very specialized, but after all the goal here was reliably getting USB Flash Drive serial numbers.

    It seems to be reliable for your typical USB Flash Drive devices as well as Flash Memory Card media connected via at least some USB "readers." As far as I can determine it should work for Window XP or anything later (through at least Windows 8).

    I have only tested it on Vista SP2 and Windows 7 SP1 however. I don't have a handy XP machine or Win8 machine to test it on right now.


    Setup API

    This uses the second technique outlined in Emmet Gray's much-linked article How to get the Serial Number from a USB disk.

    The code given there was some version of VB.Net, and he appears to have another example written in some version of C# as well but I didn't look at that. I have rewritten this in VB6 doing some major cleanup, taking care of some handle leaks and stripping out some redundant logic. I also added a filter for only "removable drives" since USB hard drives return a bogus result using his code.

    This is now a VB6 Class UsbFlashSerial with just one method Lookup that you pass a drive letter to.

    This returns either the USB Flash Drive media serial number or an empty String. The empty String value means the drive was not removable, not a USB drive, some API call error occurred, etc. I did not bother providing any API error codes or other information about failed calls because the way you'd probably use this code in your own programs a simple good-or-bad is all you can use anyway.

    Good results should be the actual media serial number. I have not tested what happens if you call this passing a drive letter for one partition of a (rare) partitioned USB Flash Drive.


    Looks Pretty Clean

    This might be what you want if you don't require pre-XP support. It doesn't require admin rights, and it doesn't use WMI so you don't have to worry about the WMI Service being active.

    The code is "packaged" as a Class so your program can create an instance, look up the drive serial number(s), and release the instance. This saves memory over the life of your program compared to putting the code in a static (BAS) module.


    The Attachment

    The attachment is a simple demo program listing all of the drives found and the results of calling Lookup on them. You should be able to just take the UsbFlashSerial.cls module from this demo project and use it in your own programs - it doesn't need any other files.

    Maybe somebody can test this on an XP machine and report their results before I get around to it.
    Attached Files Attached Files

  15. #15
    Addicted Member
    Join Date
    Mar 2007
    Location
    India
    Posts
    189

    Re: VB6 - Get USB Flash Media Serial without WMI or Admin Rights

    I thank you for your efforts. I will test it on XP and get back if there are any problems with its functioning.

  16. #16

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    11,601

    Re: VB6 - Get USB Flash Media Serial without WMI or Admin Rights

    I hope this proves to work and be reliable for people.

    I left out all of the other things like enumerating the drives, returning drive types and returning hard drive serial numbers. The last one turns out to be complicated too: some methods work for IDE/ATA drives, other ones work for true SCSI drives, and I haven't found one that works for USB hard drives. Results can be hit or miss even using WMI.

  17. #17
    Addicted Member
    Join Date
    Mar 2007
    Location
    India
    Posts
    189

    Re: VB6 - Get USB Flash Media Serial without WMI or Admin Rights

    Quote Originally Posted by dilettante View Post
    I hope this proves to work and be reliable for people.
    Sorry to be so late in giving update. I was tied up in other tasks.

    Your code is working properly for me. I tested it under WinXP and Win7 x64.

    It detected and give proper firmware number of my USB pen drive.

    Thanks for sharing your hardwork with us...

    Regards,

  18. #18

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    11,601

    Re: VB6 - Get USB Flash Media Serial without WMI or Admin Rights

    Thanks, I'm glad it seems to be working for you. I haven't plugged a monitor, keyboard, and mouse into my XP system to test this myself yet either. Hopefully we now have a reliable way to do this in VB6 programs.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Featured


Click Here to Expand Forum to Full Width

Survey posted by VBForums.