Announcement

Collapse
No announcement yet.

SD card or USB stick

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • #61
    Not exactly, for instance, most USB devices I got have real serial number.
    Windows will attribute one when there is none, it will be build randomly and also in relation to the hub/port number I think, this is based on observations.
    See Get USB devices serial number
    Also Raymond Chen Why does Windows not recognize my USB device as the same device if I plug it into a different port?
    Plus How USB Devices are Assigned Container IDs
    See USB hardware serial number using WMI by Patrice

    The hex-ascii conversion above is for IDE Sata hard disk.
    "2020202057202d445857314743454c304e4e3239" will give "WD-WXG1EC0LNN92" for my Western Digital drive.
    It's a more direct read for USB device.


    Comment


    • #62
      All,
      I'm thinking the easy solution to this is to have the User format the card and give it a name "SD CARD".

      Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Search\VolumeInfoCache\E:

      The VolumeLabel for drive E: then becomes "SD CARD". Yes, I know that does not prevent a USB stick from being named SD CARD but if the drive E: interface is interrogated/enumerated further then you would likely determine that drive E: is a built in interface with only 1 serial number. 1 serial number is the key here.

      Since the Volume name is limited to 11 characters this convention may be more informative: "SD_8GB". So you only have to look for "SD_" in the VolumeInfoCache for each drive letter.

      Note: I just purchased a DigiPower Universal 42-in-1 Multi-Card reader/writer.
      Even though it has 4 slots it has only 1 interface.

      Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Portable Devices\Devices\
      SWD
      #WPDBUSENUM
      #_??_USBSTOR
      #DISK&VEN_MASS&PROD_STORAGE_DEVICE&REV__
      #125D20140310&0
      #{53F56307-B6BF-11D0-94F2-00A0C91EFB8B}

      With SD card inserted the FriendlyName is "SD_8GB"

      Note:
      All my card readers are showing up as one of these:
      VEN_MASS
      VEN_GENERIC-
      VEN_GENERIC
      Whereas
      a USB stick is showing up as:
      VEN_USB
      Last edited by Jim Fritts; 14 Sep 2019, 05:54 PM.

      Comment


      • #63
        Pierre,

        Following your link in post #57 to DeviceChange after modifying it to run by making the changes that Peter suggested I noticed that the Interface Name is just \. Any idea why? The \ is the start of it but there should be more to it like this:
        \?\USB#VID_05AC&PID_1294&MI_00#0#{6bdd1fc6-810f-11d0-bec7-08002be2092f}

        Comment


        • #64
          Yes, it's an asciiz versus a wide string confusion. I will update the code soon...

          Thanks for the report.
          Pierre

          Comment


          • #65
            Ahh Yes.
            Thank you!

            Here is the updated code.

            NOTE:
            This was the solution to the problem.

            Code:
            ' // Size = 32 bytes
            TYPE DEV_BROADCAST_DEVICEINTERFACE_A DWORD    'replacement
               dbcc_size       AS DWORD        ' DWORD
               dbcc_devicetype AS DWORD        ' DWORD
               dbcc_reserved   AS DWORD        ' DWORD
               dbcc_classguid  AS GUID         ' GUID
               dbcc_name       AS WSTRINGZ * 1   ' char dbcc_name[1]
            END TYPE

            Comment


            • #66
              In fact, for the code to do all it can, it should be WSTRINGZ * 2.
              SIZEOF(DEV_BROADCAST_DEVICEINTERFACE) is crucial when using RegisterDeviceNotification().
              As often, there is many way to make all this work.
              I used NotificationFilter.DbDiSize = SIZEOF(DEV_BROADCAST_DEVICEINTERFACE) + 4

              Beside this, many other things had to be updated...
              My latest version is always at WM_DEVICECHANGE & SHCNE_DISKEVENTS

              Note: If you don't find "TYPE DEV_BROADCAST_DEVICEINTERFACE DWORD" in code, refresh the code frame from within your browser...
              Last edited by Pierre Bellisle; 15 Sep 2019, 07:50 PM.

              Comment


              • #67
                I'm wondering if this needs to be changed as well:
                Code:
                ' // Size = 16 bytes        'replacement
                TYPE DEV_BROADCAST_PORT_A DWORD
                   dbcp_size       AS DWORD        ' DWORD
                   dbcp_devicetype AS DWORD        ' DWORD
                   dbcp_reserved   AS DWORD        ' DWORD
                   dbcp_name       AS ASCIIZ * 1   ' char dbcp_name[1]  // variable-length 'may need to be WSTRINGZ
                END TYPE
                I have not been able to test it.

                Pierre,
                No MoveWindow found and refresh did not help. I even closed and reopened the browser. Probably a cache issue.

                Comment


                • #68
                  ASCIIZ * 1 and WSTRINGZ * 1 contain zero assignable characters. The 1 character of length (in each case) holds the terminating nul.

                  In Z strings the number includes the nul. In fixed length strings the number is the count of assignable characters.
                  Dale

                  Comment


                  • #69
                    I was thinking that
                    dbcp_name AS ASCIIZ * 1 needs to be a WSTRINGZ

                    The internal handling of the data in the documentation is not as specific as in
                    DEV_BROADCAST_DEVICEINTERFACE_A but I'd like to believe they are using a similar method.

                    Comment


                    • #70
                      Jim,
                      if no "MoveWindow" is found in code then the right frame was not refreshed.
                      As an example, in the portable PaleMoon browser, I got to right click the right frame, choose "This frame" and then "Reload frame".

                      Comment


                      • #71
                        Rephrase - With either STRINGZ (aka ASCIIZ) or WSTRINGZ the "* 1" part is probably nonsense (unless the object is to store 1 or 2 nul bytes). I state no opinion on wide characters or not.

                        IT IS THE LENGTH I'M BRINGING TO YOUR ATTENTION.
                        Dale

                        Comment


                        • #72
                          Originally posted by Dale Yarker View Post
                          Rephrase - With either STRINGZ (aka ASCIIZ) or WSTRINGZ the "* 1" part is probably nonsense (unless the object is to store 1 or 2 nul bytes). I state no opinion on wide characters or not.

                          IT IS THE LENGTH I'M BRINGING TO YOUR ATTENTION.
                          It is correct. It is just used to account for the Null terminator when the structure, including the actual device name string, is passed. It is not used for the actual device name.

                          https://docs.microsoft.com/en-us/win...iceinterface_a

                          "dbcc_size
                          The size of this structure, in bytes. This is the size of the members plus the actual length of the dbcc_name string (the null character is accounted for by the declaration of dbcc_name as a one-character array.)"

                          Comment


                          • #73
                            In DEV_BROADCAST_DEVICEINTERFACEA Microsoft define char dbcc_name[1]; - José goes dbcc_name AS ASCIIZ * 1
                            In DEV_BROADCAST_DEVICEINTERFACEW Microsoft define TCHAR dbcc_name[1]; - José goes dbcc_name AS AS WSTRINGZ * 1

                            Knowing that SIZEOF(DEV_BROADCAST_DEVICEINTERFACE) is crucial when using RegisterDeviceNotification(),
                            I looked at Josés include again and noticed that
                            TYPE DEV_BROADCAST_DEVICEINTERFACE DWORD
                            The DWORD type suffix alignment have the effect of resolving the problem.

                            Then having .DbDiName as wide or asciiz won't cause any trouble because
                            it will only serve as a reference for a WSTRINGZ or ASCIIZ pointer that will be, of course, longer than WSTRINGZ * 1 or ASCIIZ * 1.

                            I've updated WM_DEVICECHANGE & SHCNE_DISKEVENTS again to include the DEV_BROADCAST_DEVICEINTERFACE DWORD type suffix.
                            Main reason is to be PB-Win 9-10 compatible.

                            Comment


                            • #74
                              Then the object is to store a 0.

                              But stated size of the TYPE is 32 in one post and 16 in another
                              3 DWORDs and GUID = 28
                              3 DWORDs = 12
                              One or two bytes of 0 won't fix that!
                              Last edited by Dale Yarker; 15 Sep 2019, 08:09 PM. Reason: corrected sums
                              Dale

                              Comment


                              • #75
                                Or relying on DWORD alignment and a zero (or two) to force up to 32 bytes. In which case ASCIIZ or WSTRINGZ makes no difference!

                                Dale

                                Comment


                                • #76
                                  NOTE:

                                  This produced a partial string of just a \.

                                  Code:
                                   
                                  ' // Size = 32 bytes TYPE DEV_BROADCAST_DEVICEINTERFACE_A DWORD 'replacement dbcc_size AS DWORD ' DWORD dbcc_devicetype AS DWORD ' DWORD dbcc_reserved AS DWORD ' DWORD dbcc_classguid AS GUID ' GUID dbcc_name AS ASCIIZ * 1 ' char dbcc_name[1]
                                  END TYPE
                                  Whereas, this did work providing the entire string data
                                  \\?\STORAGE#VOLUME#_??_USBSTOR#DISK&VEN_GENERIC-&PROD_MULTI-CARD&REV_1.00#20071114173400000&0#{53F56307-B6BF-11D0-94F2-00A0C91EFB8B}#{53F5630D-B6BF-11D0-94F2-00A0C91EFB8B}

                                  Code:
                                   
                                  ' // Size = 32 bytes TYPE DEV_BROADCAST_DEVICEINTERFACE_A DWORD 'replacement dbcc_size AS DWORD ' DWORD dbcc_devicetype AS DWORD ' DWORD dbcc_reserved AS DWORD ' DWORD dbcc_classguid AS GUID ' GUID dbcc_name AS WSTRINGZ * 1 ' char dbcc_name[1]
                                  END TYPE
                                  Yes, Correct dbcc_name is a one-character array that is expanded by internal processes. It initially holds a CHR$(0). The internal processes use UNICODE no matter if you perform _W or a _A function call.

                                  See the working version here.

                                  Comment


                                  • #77
                                    Q> Or relying on DWORD alignment and a zero (or two) to force up to 32 bytes. In which case ASCIIZ or WSTRINGZ makes no difference!

                                    It will make a difference, without DWORD alignment SIZEOF(DEV_BROADCAST_DEVICEINTERFACE)
                                    will be reported as 29 bytes with the current code using ASCIIZ and RegisterDeviceNotification() will fail.

                                    My goal is to be Win-10 and Win-9 compatible and to respect José's definitions,
                                    so, since .DbDiName serve only as a reference to get a pointer, I used #IF %PB_REVISION to set a Wide or Ansi stringz pointer.
                                    All this could have been done in many ways, I chose this one, it's clean and not too hard to follow ...

                                    WM_DEVICECHANGE & SHCNE_DISKEVENTS

                                    Comment


                                    • #78
                                      Too bad the friendly name is not available. The DEV_BROADCAST_PORT_A is never queried during arrival and removal. Yes, I am referring to dbcp_name. Perhaps customization is necessary. Just throwing that out there.

                                      See Post #67. That is the direction I am trying to go in.

                                      As Noted in Post #62:
                                      All my card readers are showing up as one of these:
                                      VEN_MASS
                                      VEN_GENERIC-
                                      VEN_GENERIC

                                      Whereas

                                      a USB stick is showing up as:
                                      VEN_USB

                                      Now that the DEV_BROADCAST_DEVICEINTERFACE_A is working, it looks to me that we have something to discriminate between SD Card and USB Stick.

                                      Here is a USB stick:
                                      Click image for larger version

Name:	New Bitmap Image.jpg
Views:	66
Size:	53.4 KB
ID:	784799

                                      Peter,
                                      What do you think?

                                      Comment


                                      • #79
                                        That seems to work!...
                                        But I can't distinguish between SD, CF, of MSpro as I see...
                                        (have to dig up my old CF and MSPro cards, haven't used them in ages...)
                                        Regards,
                                        Peter

                                        Comment


                                        • #80
                                          Ok,
                                          I just validated this change in the port type:
                                          Code:
                                          ' // Size = 16 bytes        'replacement
                                          TYPE DEV_BROADCAST_PORT_A DWORD
                                             dbcp_size       AS DWORD        ' DWORD
                                             dbcp_devicetype AS DWORD        ' DWORD
                                             dbcp_reserved   AS DWORD        ' DWORD
                                          dbcp_name       AS WSTRINGZ * 1   ' char dbcp_name[1]  // variable-length 'cannot be ASCIIZ here
                                          END TYPE
                                          NOTE:
                                          José type update for DEV_BROADCAST_PORT_A.

                                          dbcp_name provides the same info as dbcc_name with a few question marks at the beginning of the text added.

                                          Gee, I was hoping for more information (friendlyname) like "SD_8GB". Dang

                                          Not to worry. That info can be extracted from the registry here:
                                          Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Search\VolumeInfoCache\E:

                                          E: was extracted from Device Change Info here:
                                          DBT_DEVTYP_VOLUME
                                          - Drive letter: E:

                                          Got it. See version 7
                                          Tells you the Volume Label from the registry and determines if the device is a USB device or an SD Card based on previous device testing results.

                                          Note: my SD Card is a SanDisk Ultra Plus MicoSD embedded in an SD adapter.
                                          Last edited by Jim Fritts; 16 Sep 2019, 10:23 AM.

                                          Comment

                                          Working...
                                          X