Announcement

Collapse
No announcement yet.

List USB info (VID, PID,Revision, etc)

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

  • List USB info (VID, PID,Revision, etc)

    This is for discussion of my sample for obtaining Vendor Id, Product Id, and other information from USB drivers. It is based around the "SetupApi.INC" file from Kev Peel (that can be downloaded from the Pb Files section)
    There is a great wealth of information that can be gathered but for this example I am only after information like
    HardWare Id = PCI\VEN_8086&DEV_27C8&SUBSYS_50041458&REV_01

    Device Type = PCI
    Vendor Id = 8086
    Product Id = 27C8
    SubSystem = 50041458
    Revision = 01
    Code can be found in the source code forum under List USB info (VID, PID,Revision, etc)
    I hope this is of some use
    Last edited by Cliff Nichols; 16 Dec 2007, 12:26 PM. Reason: Updating links
    Engineer's Motto: If it aint broke take it apart and fix it

    "If at 1st you don't succeed... call it version 1.0"

    "Half of Programming is coding"....."The other 90% is DEBUGGING"

    "Document my code????" .... "WHYYY??? do you think they call it CODE? "

  • #2
    Hey Cliff,
    If you like that kind of stuff, you could also play with this,
    it's a variation of a DOS program that I did
    to get info about pci devices in a PC.
    Sadly, theyre is no USB device in Martin's list.

    From
    PCI\VEN_8086&DEV_27C8&SUBSYS_50041458&REV_01

    you will get
    Vendor: Intel Corporation
    Device: 82801G (ICH7 Family) USB UHCI Controller #1
    Subsystem: Unknown
    Revision: 01

    You'll need the data file "pci.db"
    To create it,
    at http://pciids.sourceforge.net/
    in the line "Download the current snapshot of the database dump file: text"
    Right-click on "text" and save as "pci.db"
    Note that lines are separated by linefeed CHR$(10) unix style and not by CHR$(13, 10)

    Code:
      
    'At [URL]http://pciids.sourceforge.net/[/URL]
    'in the line "Download the current snapshot of the database dump file: text"
    'Right-click on "text" and save as "pci.db"
    'Lines are separated by linefeed CHR$(10) unix style and not by CHR$(13, 10)
     
    'Line format:
    'VendorId: v VendorId & $TAB & Description & $TAB & Validation
    'DeviceId: d VendorId & DeviceId & $TAB & Description & $TAB & Validation
    'SubSytem: s VendorId & DeviceId & SubSytem & $TAB & Description & $TAB & Validation
    'Validation is zero if information is validated else it' one
     
    'Example:
    'v  1002    ATI Technologies Inc    0
    'd  1002724b    R580 [Radeon X1900]    0
    's  1002724b10020b12    Radeon X1900 (Primary)    0
    's  1002724b10020b13    Radeon X1900 (Secondary)    0
     
    #COMPILE EXE '#Win 8.04#
    #DIM ALL
    #INCLUDE "WIN32API.INC" '#2005-01-27#
     
    '______________________________________________________________________________
     
    FUNCTION DeviceDescripionGet(sDevice AS STRING) AS STRING
     LOCAL  Index         AS LONG
     LOCAL  FileNo        AS LONG
     LOCAL  sDeviceLo     AS STRING
     LOCAL  sFileBuffer   AS STRING
     LOCAL  VendorId      AS STRING
     LOCAL  DeviceId      AS STRING
     LOCAL  SubSytem      AS STRING
     LOCAL  Revision      AS STRING
     LOCAL  Desc          AS STRING
     STATIC Tab2          AS STRING
     STATIC pciLinesCount AS DWORD
     
     IF pciLinesCount = 0 THEN
       FileNo = FreeFile
       OPEN "pci.db" FOR BINARY as FileNo
       GET$ FileNo, LOF(FileNo), sFileBuffer
       CLOSE FileNo
       pciLinesCount = PARSECOUNT(sFileBuffer, $LF)
       IF pciLinesCount THEN
         DIM pciLines(1 TO pciLinesCount) AS STATIC STRING
         PARSE sFileBuffer, pciLines(), $LF
         sFileBuffer = "" 'Free memory
         Tab2 = $TAB & $TAB
       ELSE
         FUNCTION = "Error !"
         EXIT FUNCTION
       END IF
     END IF
     
     sDeviceLo = LCASE$(sDevice)
     VendorId = MID$(sDeviceLo, INSTR(sDeviceLo, "ven_")    + 4, 4)
     DeviceId = MID$(sDeviceLo, INSTR(sDeviceLo, "dev_")    + 4, 4)
     SubSytem = MID$(sDeviceLo, INSTR(sDeviceLo, "subsys_") + 7, 8)
     Revision = MID$(sDeviceLo, INSTR(sDeviceLo, "rev_")    + 4, 4)
     
     ARRAY SCAN pciLines(), FROM 1 TO 7, = "v" & $TAB & VendorId & $TAB, TO Index
     IF Index THEN
       Desc = "Vendor:" & Tab2 & PARSE$(pciLines(Index), $TAB, 3)
       ARRAY SCAN pciLines(), FROM 1 TO 11, = "d" & $TAB & VendorId & DeviceId & $TAB, TO Index
       IF Index THEN
         Desc = Desc & $CRLF & "Device:" & Tab2 & PARSE$(pciLines(Index), $TAB, 3)
         ARRAY SCAN pciLines(), FROM 1 TO 19, = "s" & $TAB & VendorId & DeviceId & SubSytem & $TAB, TO Index
         IF Index THEN
           Desc = Desc & $CRLF & "Subsystem:" & $TAB & PARSE$(pciLines(Index), $TAB, 3)
         ELSE
           Desc = Desc & $CRLF & "Subsystem:"& $TAB & "Unknown"
         END IF
         IF LEN(Revision) THEN 'Put revision only id vendor and device are known
           Desc = Desc & $CRLF & "Revision:" & Tab2 & Revision
         END IF
       ELSE
         Desc = Desc & $CRLF & "Device:" & Tab2 & "Unknown" & $CRLF & "Subsystem:" & $TAB & "Unknown"
       END IF
     ELSE
       Desc = "Vendor:"    & Tab2 & "Unknown" & $CRLF & _
              "Device:"    & Tab2 & "Unknown" & $CRLF & _
              "Subsystem:" & $TAB & "Unknown"
     END IF
     
     FUNCTION = Desc
     
    END FUNCTION
    '______________________________________________________________________________
     
    FUNCTION PBMAIN() AS LONG
     LOCAL sBuffer AS STRING
     LOCAL sDesc   AS STRING
     
     sBuffer = "PCI\VEN_8086&DEV_27C8&SUBSYS_50041458&REV_01"
     
     sDesc = DeviceDescripionGet(sBuffer)
     
     sBuffer = sBuffer & $CRLF  & $CRLF & sDesc
     MessageBox %HWND_DESKTOP, BYCOPY sBuffer, BYCOPY "pci info", %MB_ICONINFORMATION OR %MB_OK
     
    END FUNCTION
    '______________________________________________________________________________
    Last edited by Pierre Bellisle; 16 Dec 2007, 01:37 PM.

    Comment


    • #3
      Thank You

      Thank You Pierre,
      You must have been reading my mind (don't get too scared though )
      Last week before I cleaned up the code for posting I was actually working on a real "Lookup" on the values to return more useful information. but it was for USB (and just starting on it), but these links give me a heck of a jump on problems I could see coming, and maybe how to get around them.

      I do have to play with the sample you posted a bit because all the answers came back as "UNKNOWN", but I am sure it is probably a tweak or the db I downloaded did not have it in the list?

      Anyways, Thanx again, this will sure give me a jump start
      Engineer's Motto: If it aint broke take it apart and fix it

      "If at 1st you don't succeed... call it version 1.0"

      "Half of Programming is coding"....."The other 90% is DEBUGGING"

      "Document my code????" .... "WHYYY??? do you think they call it CODE? "

      Comment


      • #4
        Cliff,

        You are CLEARLY adroit at SETUPAPI.DLL!
        I'm trying to programmatically find the base addresses of any/all parallel ports on a system. I know SETUPAPI.DLL can do this, but I don't know how.

        The Command line program DEVCON.EXE from the MS device driver toolkit with the command line arguments RESOURCES PCMCIA* will display the I/O addresses of any PCMCIA card installed in the system. Adding ISA* and/or PCI* can find any others. DEVCON.EXE uses SETUPAPI.DLL.

        Do you have any wisdom you care to share about this?

        Thanks

        Comment


        • #5
          Bill,
          What is adroit? (I know I have seen this term before but for the life of me I can not think of it.)

          I'm trying to programmatically find the base addresses of any/all parallel ports on a system. I know SETUPAPI.DLL can do this, but I don't know how.
          I knew I should have bookmarked that block of code when I saw it earlier, I will see if I can find it again. but it may be in the "Downloads" section of the PB Files (best guess at the moment)

          Also anyone that finds the code useful, should give Kev Peel credit, as it was his port in the PB Files that got me started. (I know its in the downloads but can't seem to find it now myself, so glad I kept a copy)

          Bill is it safe to say you are out to find if "LPT1 = address EF8" if I read right? (I know the address may be wrong, but I have all my LPT notes at work and and have not worked with Parallel port in a few years)

          On place that could help you would be Jan Axelson's Lakeview Research who wrote "USB Complete" and "Serial Port Complete" and "Parallel Port Complete" and "Ethernet Complete" and has gathered a TON of links and code and useful information on each of the ports.

          I do need to go back and redo my example for Serial Ports, but since I am on a roll maybe I will grab my parallel port notes from work and add it in as well? (or at least see if I can find some of the answers you may be looking for)

          Seems like the more I learn, the more that I learn there is MORE to learn
          Engineer's Motto: If it aint broke take it apart and fix it

          "If at 1st you don't succeed... call it version 1.0"

          "Half of Programming is coding"....."The other 90% is DEBUGGING"

          "Document my code????" .... "WHYYY??? do you think they call it CODE? "

          Comment


          • #6
            Cliff,

            I've been through the resources you mention (and the resources those resources mention), but, so far nothing does the trick.

            In the good ol' DOS days, parallel ports were enumerated by BIOS and their base addresses could be found starting at 408h (I think) in low memory. With 2K, XP, etc. that has gone away. The aforementioned spot in low memory no longer contains the base addresses of any 'real' parallel port.

            Most of the current crop of PCMCIA or Express Card parallel port cards are 'plug-n-pray' so they install themselves wherever the OS wants.

            I support a medical device that uses a parallel port as it's data pipeline to a PB app I've written. I use in/out ASM statements coupled with a Ring 0 driver to 'bang' the device. I can't use USB printer ports, because none are true parallel ports.

            If I manually enter the parallel port base address found in Device Manager in my program, it works fine. I just can't trust the end user to perform that step. The consequences of an incorrect entry could be dire.

            Thanks

            Comment


            • #7
              Cliff,
              just remember that the database is for pci devices only, not USB devices.

              Bill,
              beside SetupApi you could also use WMI, see wmi info
              and put "Win32_AllocatedResource" in the combobox
              and you should have things like the following...


              Port DeviceID = "LPT1"
              DMAChannel 3, Starting Address 888 (Or 378 hex), Starting Address 1912 (Or 778 hex)

              Serial Port Device ID = "COM1"
              irq Number = 4, Starting Address = 1016 decimal (Or 3F8 in hex)

              Comment


              • #8
                Pierre,

                Thanks so much for your post. I won't pretend to understand what's going on with WMI, but I was able extract the desired info.

                One more 'gotcha'...I also have to support Win98...

                Comment


                • #9
                  Hey Bill,
                  if you want to know more about WMI then you may have a look
                  at the José Roca's WMI Guru's site, http://com.it-berater.org/wmi.htm
                  The WMI Wrappers Generator (TB_WMIGN) is great.

                  For Windows 98 you could do it the same way you did in dos...
                  LPT1 address is PEEK(&H408) + PEEK(&H409) * 256, often 378
                  LPT2 address is PEEK(&H40A) + PEEK(&H40B) * 256, often 278
                  LPT3 address is PEEK(&H40C) + PEEK(&H40D) * 256
                  COM1 address is PEEK(&H400) + PEEK(&H401) * 256, often 3F8
                  COM2 address is PEEK(&H402) + PEEK(&H403) * 256, often 2F8
                  Last edited by Pierre Bellisle; 16 Dec 2007, 10:12 PM.

                  Comment


                  • #10
                    Thanx Pierre, I should have thought before I spoke. Just because my item was PCI\VEN_8086&DEV_27C8&SUBSYS_50041458&REV_01 does not mean it was a PCI device that would be in the list.

                    Bill, If I get the chance the next couple days I will see what it would take to add Parallel Port information
                    Engineer's Motto: If it aint broke take it apart and fix it

                    "If at 1st you don't succeed... call it version 1.0"

                    "Half of Programming is coding"....."The other 90% is DEBUGGING"

                    "Document my code????" .... "WHYYY??? do you think they call it CODE? "

                    Comment


                    • #11
                      Hey Cliff,

                      PCI\VEN_8086&DEV_27C8&SUBSYS_50041458&REV_01
                      is a pci USB controller, meaning that one side of it is connected
                      to the pci bus and the other side is connected to usb ports,

                      From that you should get...
                      Vendor: Intel Corporation
                      Device: 82801G (ICH7 Family) USB UHCI Controller #1
                      Subsystem: Unknown
                      Revision: 01

                      If not then it may be becose you downloaded
                      the wrong database at http://pciids.sourceforge.net/
                      You have to right-click
                      on "text" in the line that have the word "dump" in it.
                      Database lines should like the following...
                      d 808627c8 82801G (ICH7 Family) USB UHCI Controller #1 0
                      Last edited by Pierre Bellisle; 17 Dec 2007, 08:07 AM.

                      Comment


                      • #12
                        @Pierre
                        Thanks, you were right, I grabbed the wrong text file.
                        Also the WMI wrappers are great, but from what I can find, only work on the NT Branch of Windows? (no 95/98/ME, and quite possibly no NT4?)
                        (But that is a matter for "Just how antiquated am I willing to support?")

                        @Bill
                        Just about the time I was going to give up and was almost sure that the "DevCon.exe" was using WMI (especially since its system requirements were Win2K and up), I took one more shot and downloaded a copy and looked at it with "Depends.exe" and not a single sign of WMI that I could find.

                        So I am back to tearing my hair out finding just what function returns the I/O range (Base Address) of these devices like you would see if you got it from the control panel?

                        The good news is if you just need to know if the port is available, that is easy. (I had purposely blocked Parallel Ports in a different sample I did, and as soon as I commented a few lines I got the Parallel Ports back).

                        Bad new is, (Can I guess you are using something like "Inp/Outp" that you have to pass the correct base address to work properly?)

                        @Pierre
                        you mentioned PEEK on the 98 branch of Windows (would that work for the NT branch too?) Also can you point me at the code to do like you said
                        For Windows 98 you could do it the same way you did in dos...
                        LPT1 address is PEEK(&H408) + PEEK(&H409) * 256, often 378
                        LPT2 address is PEEK(&H40A) + PEEK(&H40B) * 256, often 278
                        LPT3 address is PEEK(&H40C) + PEEK(&H40D) * 256
                        COM1 address is PEEK(&H400) + PEEK(&H401) * 256, often 3F8
                        COM2 address is PEEK(&H402) + PEEK(&H403) * 256, often 2F8
                        I wanted to try some ideas once I got a basic concept working. But I gotta learn the basics first, and unless I absolutely have to, I normally stay away from assembly or Peeking and Poking memory addresses, but I won't rule them out.
                        Engineer's Motto: If it aint broke take it apart and fix it

                        "If at 1st you don't succeed... call it version 1.0"

                        "Half of Programming is coding"....."The other 90% is DEBUGGING"

                        "Document my code????" .... "WHYYY??? do you think they call it CODE? "

                        Comment


                        • #13
                          Cliff,

                          Pierre's reply about Win98 does not apply to NT (or any later OS), because those OS's treat IO memory as protected/privileged memory. That's why I had to use a Ring 0 driver to access it. In addition, those low memory locations are populated by BIOS from a scan of 'legacy' ISA port locations. If the port is on a PCMCIA or PCI card, they are usually allocated by PNP of the OS. The low memory loactions are not generally properly updated to reflect any additional ports.

                          The source code for DEVCON.EXE is available from MS, and it does, in fact, use SETUPAPI.DLL. Unfortunately I'm far too obtuse to decipher the C code.

                          You are correct about my use if in/out...I do need actual addresses.

                          BTW - even in XP, you can use DEBUG in a DOS box to look at those low memory addresses (d 0:400). You'll find that those locations report 3 parallel ports at 3BC, 378, & 278 even if you don't have any...there's the rub.

                          Thanks again to you and Pierre for your efforts.

                          Comment


                          • #14
                            Bill, do you have the C code you can post? (Maybe something will jump out at me)

                            I know its frustrating but like you can see from me and Pierre, there are more than one way to skin a cat

                            Actually what frustrates me is that now I look at it, the later dlls (SetupApi and WMI) are not even possible unless the core dll knows how to respond...so obviously the idea exists (Control panel proves that concept)

                            One easy way out (and I hate doing it myself) is if you can't get the info you need (either due to dll or not understanding) then alert the user, and move on till you do or can understand

                            (Although I will admit its another of those "It should be SOOOOoooo simple...why is it sooooo hard"? concepts )
                            Engineer's Motto: If it aint broke take it apart and fix it

                            "If at 1st you don't succeed... call it version 1.0"

                            "Half of Programming is coding"....."The other 90% is DEBUGGING"

                            "Document my code????" .... "WHYYY??? do you think they call it CODE? "

                            Comment

                            Working...
                            X