Announcement

Collapse
No announcement yet.

USB DeviceIoControl and No HID

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

  • USB DeviceIoControl and No HID

    As many of you know, for months now I have been researching USB and how it works, what it takes to communicate, and if communicating with the correct device.

    On top of trying to make it "Simple" for someone else to follow. (good luck there )

    Anyways, I am hoping someone can clear my head and point out what I am doing wrong? (Even if its just a generic DeviceIoControl on a plain text file? (please no more examples about scuzzy drives, hard drives etc..) As I am trying to get my head wrapped around the "Kindergarten" phase of generic concepts.)

    Where I am stuck is getting a Descriptor, so I can learn about the device I am looking at. (Yes I know this is easily done on Device attach/Detach etc...but I am looking at if my program runs after the device is attached, and determine if it is the one that I need to talk to)

    Anyways, Sample Code below, and real code I hope to post soon.
    (Real code currently returns either invalid handle, incorrect parameter, or does not support) but if I can get just 1 known device to work correctly then I am sure I can figure out why or why not the others do or don't

    Any help you can give will be GREATLY appreciated

    Code:
    #COMPILE EXE
    #DIM ALL
    #INCLUDE "WIN32API.INC"                 'Define Windows OS variables and functions
    
    '*** Got from Docs but may be wrong
         %BMREQUEST_STANDARD               = 0
         %BMREQUEST_TO_DEVICE              = 0
         %USB_DEVICE_DESCRIPTOR_TYPE                 = &H01
    
         TYPE USB_SETUP_PACKET
              bmRequest AS BYTE
              bRequest AS BYTE
              wValue AS WORD
              wIndex AS WORD
              wLength AS WORD
         END TYPE
         TYPE USB_DESCRIPTOR_REQUEST
              ConnectionIndex AS DWORD
              SetupPacket AS USB_SETUP_PACKET
         END TYPE
    
         %USB_REQUEST_GET_DESCRIPTOR                 = &H06
    
         TYPE USB_DEVICE_DESCRIPTOR
              bLength AS BYTE
              bDescriptorType AS BYTE
              bcdUSB AS WORD
              bDeviceClass AS BYTE
              bDeviceSubClass AS BYTE
              bDeviceProtocol AS BYTE
              bMaxPacketSize0 AS BYTE
              idVendor AS WORD
              idProduct AS WORD
              bcdDevice AS WORD
              iManufacturer AS BYTE
              iProduct AS BYTE
              iSerialNumber AS BYTE
              bNumConfigurations AS BYTE
         END TYPE
    
    FUNCTION PBMAIN () AS LONG
         LOCAL ErrFunc AS DWORD
         LOCAL ErrorBuff AS ASCIIZ * %MAX_PATH
    '*** DeviceIoControl Parameters
         LOCAL DevHndl AS DWORD                  'handle to device of interest
         LOCAL dwIoControlCode AS DWORD          'control code of operation to perform
    '    LPVOID lpInBuffer,   // pointer to buffer to supply input data
         LOCAL lpInBuffer AS USB_DESCRIPTOR_REQUEST
         LOCAL nInBufferSize AS DWORD            'size of input buffer
    '    LPVOID lpOutBuffer,  // pointer to buffer to receive output data
         LOCAL lpOutBuffer AS USB_DEVICE_DESCRIPTOR
         LOCAL nOutBufferSize AS DWORD           'size of output buffer
    '    LPDWORD lpBytesReturned,  // pointer to variable to receive output byte count
         LOCAL lpBytesReturned AS DWORD
         LOCAL OverlappedType AS Overlapped      'pointer to overlapped structure for asynchronous operation
    
    '     ErrFunc = CreateFile("COM1", %GENERIC_READ OR %GENERIC_WRITE, 0, BYVAL 0, %OPEN_EXISTING, %FILE_FLAG_OVERLAPPED, %NULL)        'Windows Friendly Name
         DevHndl = CreateFile("\\?\acpi#pnp0501#1#{86e0d1e0-8089-11d0-9ce4-08003e301f73}", %GENERIC_READ OR %GENERIC_WRITE, 0, BYVAL 0, %OPEN_EXISTING, %FILE_FLAG_OVERLAPPED, %NULL)        'Windows REAL Name
    '*********************************** ERROR CHECKING **************************************
    ErrFunc = GetLastError()           'Check for the error
    FormatMessage %FORMAT_MESSAGE_FROM_SYSTEM, BYVAL %NULL, ErrFunc, %NULL, ErrorBuff, SIZEOF(ErrorBuff), BYVAL %NULL  'Format the message
    MSGBOX STR$(ErrFunc) + $TAB + ErrorBuff
    '******************************** END ERROR CHECKING *************************************
    
    
         DevHndl = CloseHandle(DevHndl)          'Close Handle whether its valid or not       '<--- Not sure if this does anything on a invalid handle?
    '*********************************** ERROR CHECKING **************************************
    ErrFunc = GetLastError()           'Check for the error
    FormatMessage %FORMAT_MESSAGE_FROM_SYSTEM, BYVAL %NULL, ErrFunc, %NULL, ErrorBuff, SIZEOF(ErrorBuff), BYVAL %NULL  'Format the message
    MSGBOX STR$(ErrFunc) + $TAB + ErrorBuff
    '******************************** END ERROR CHECKING *************************************
    
    '     OverLappedType.Offset = 0
    '     OverLappedType.OffsetHigh = 0
    '     OverLappedType.hEvent = 0
    
         lpInBuffer.ConnectionIndex = 1                              '<--- Tried 0 (like I think it should be but tried 1 just in case)
         lpInBuffer.SetupPacket.bmRequest = %BMREQUEST_STANDARD      '<--- Not sure if correct, but tried for getting 1st peice of info
         lpInBuffer.SetupPacket.bRequest = %USB_REQUEST_GET_DESCRIPTOR    '<--- Not sure if correct, but tried for getting 1st peice of info
         lpInBuffer.SetupPacket.wValue = %USB_DEVICE_DESCRIPTOR_TYPE '<--- Not sure if correct, but tried for getting 1st peice of info
         lpInBuffer.SetupPacket.wIndex = 0                           '<--- Not sure if correct, but tried for getting 1st peice of info
         lpInBuffer.SetupPacket.wLength = SIZEOF(lpInBuffer.SetupPacket)  '<--- Not sure if correct, but tried for getting 1st peice of info
    '*** Fill in info to be gotten
         dwIoControlCode =  %USB_REQUEST_GET_DESCRIPTOR
         nInBufferSize = SIZEOF(lpInBuffer)
         nOutBufferSize = SIZEOF(lpOutBuffer)
    '     ErrFunc = DeviceIoControl(hDevice, dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize, lpBytesReturned, OverlappedType)
         IF DevHndl <> %INVALID_HANDLE_VALUE THEN
              ErrFunc = DeviceIoControl(DevHndl, dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize, lpBytesReturned, BYVAL %NULL)
         END IF
    '*********************************** ERROR CHECKING **************************************
    ErrFunc = GetLastError()           'Check for the error
    FormatMessage %FORMAT_MESSAGE_FROM_SYSTEM, BYVAL %NULL, ErrFunc, %NULL, ErrorBuff, SIZEOF(ErrorBuff), BYVAL %NULL  'Format the message
    MSGBOX "Get Descriptor = " + STR$(ErrFunc) + $TAB + ErrorBuff
    '******************************** END ERROR CHECKING *************************************
    END FUNCTION
    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
    Hi Cliff,
    following code works fine on my PC,
    Make sure that zPortName is correct for you.

    Have fun...

    Code:
    #COMPILE EXE '#Win 8.04#
    #DIM ALL
    #INCLUDE "Win32Api.inc" '#2005-01-27#
     
    %USB_DEVICE_DESCRIPTOR_TYPE              = 1
    %USB_REQUEST_GET_DESCRIPTOR              = 6
    %USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION = 260
    %FILE_DEVICE_UNKNOWN                     = 34 '0x0022
    %FILE_DEVICE_USB                         = %FILE_DEVICE_UNKNOWN
    %FILE_ANY_ACCESS                         = 0
    %METHOD_BUFFERED                         = 0
     
    TYPE USB_SETUP_PACKET
    bmRequest AS BYTE
    bRequest  AS BYTE
    wValue    AS WORD
    wIndex    AS WORD
    wLength   AS WORD
    END TYPE
     
    TYPE USB_DESCRIPTOR_REQUEST
    ConnectionIndex AS LONG
    SetupPacket     AS USB_SETUP_PACKET
    DATA            AS STRING * 2048
    END TYPE
     
    TYPE USB_DEVICE_DESCRIPTOR
    bLength            AS BYTE 'Length in bytes, of this descriptor.
    bDescriptorType    AS BYTE 'Descriptor type, must be set to USB_DEVICE_DESCRIPTOR_TYPE.
    bcdUSB             AS WORD 'Version of the USB specification that this descriptor structure complies with. This value is a binary-coded decimal number.
    bDeviceClass       AS BYTE 'Class code of the device as assigned by the USB specification group.
    bDeviceSubClass    AS BYTE 'Subclass code of the device as assigned by the USB specification group.
    bDeviceProtocol    AS BYTE 'Protocol code of the device as assigned by the USB specification group.
    bMaxPacketSize0    AS BYTE 'Maximum packet size, in bytes, for endpoint zero of the device. The value must be set to 8, 16, 32, or 64.
    idVendor           AS WORD 'Vendor identifier for the device as assigned by the USB specification committee.
    idProduct          AS WORD 'Product identifier. This value is assigned by the manufacturer and is device-specific.
    bcdDevice          AS WORD 'Version of the device. This value is a binary-coded decimal number.
    iManufacturer      AS BYTE 'Device-defined index of the string descriptor that provides a string containing the name of the manufacturer of this device.
    iProduct           AS BYTE 'Device-defined index of the string descriptor that provides a string that contains a description of the device.
    iSerialNumber      AS BYTE 'Device-defined index of the string descriptor that provides a string that contains a manufacturer-determined serial number for the device.
    bNumConfigurations AS BYTE 'Total number of possible configurations for the device.
    END TYPE
    '______________________________________________________________________________
     
    FUNCTION CTL_CODE(BYVAL dwDeviceType AS DWORD, BYVAL dwFunction AS DWORD, _
                      BYVAL dwMethod AS DWORD, BYVAL dwAccess AS DWORD) AS DWORD
     
    'Thank to Erwin van de Wiel
    SHIFT LEFT dwDeviceType, 16
    SHIFT LEFT dwAccess, 14
    SHIFT LEFT dwFunction, 2
    FUNCTION = dwDeviceType OR dwAccess OR dwFunction OR dwMethod
     
    END FUNCTION
    '______________________________________________________________________________
     
    FUNCTION PBMAIN () AS LONG
    LOCAL IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION AS DWORD
    LOCAL SA                                            AS SECURITY_ATTRIBUTES
    LOCAL DeviceBuffer                                  AS USB_DESCRIPTOR_REQUEST
    LOCAL zBuffer                                       AS ASCIIZ * %MAX_PATH
    LOCAL zPortName                                     AS ASCIIZ * %MAX_PATH
    LOCAL PortIndex                                     AS LONG
    LOCAL LastError                                     AS DWORD
    LOCAL hDevice                                       AS DWORD
    LOCAL BytesReturned                                 AS DWORD
    LOCAL Index                                         AS BYTE
     
    SA.nLength = SIZEOF(SECURITY_ATTRIBUTES)
    SA.lpSecurityDescriptor = 0
    SA.bInheritHandle = %FALSE
     
    'To work, a device must be connected to a valid portname
    'Next line work on my PC...
    zPortName = "\\.\USB#ROOT_HUB#4&1a0027b6&0#{f18a0e88-c30c-11d0-8815-00a0c906bed8}"
     
    'Next line is from your previous post...
    'zPortName = [noparse]"\\?\acpi#pnp0501#1#{86e0d1e0-8089-11d0-9ce4-08003e301f73}[/noparse]
     
    hDevice = CreateFile(zPortName, %GENERIC_READ, 0, SA, %OPEN_EXISTING, BYVAL 0, %NULL)
    IF hDevice = %INVALID_HANDLE_VALUE THEN
    MSGBOX "Invalid handle value !"
    ELSE
    IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION = CTL_Code(%FILE_DEVICE_USB, _
      %USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, %METHOD_BUFFERED, %FILE_ANY_ACCESS)
     
    PortIndex = 1
    Index = 0
    DeviceBuffer.ConnectionIndex       = PortIndex
    DeviceBuffer.SetupPacket.bmRequest = &h80
    DeviceBuffer.SetupPacket.bRequest  = %USB_REQUEST_GET_DESCRIPTOR
    DeviceBuffer.SetupPacket.wValue    = (%USB_DEVICE_DESCRIPTOR_TYPE * 256) + Index
    DeviceBuffer.SetupPacket.wIndex    = 0 'Should be Language id
    DeviceBuffer.SetupPacket.wLength   = SIZEOF(DeviceBuffer.SetupPacket)
     
    IF DeviceIoControl(hDevice, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, _
    DeviceBuffer, SIZEOF(DeviceBuffer), _
    DeviceBuffer, SIZEOF(DeviceBuffer), _
    BytesReturned, BYVAL %NULL) THEN
      MSGBOX "Success !"
    ELSE
      LastError = GetLastError
      FormatMessage %FORMAT_MESSAGE_FROM_SYSTEM, BYVAL %NULL, LastError, %NULL, _
        zBuffer, SIZEOF(zBuffer), BYVAL %NULL
      MSGBOX "Error" & STR$(LastError) & " : " & zBuffer
    END IF
    CloseHandle hDevice
    END IF
     
    END FUNCTION
    '______________________________________________________________________________
    '
    Last edited by Pierre Bellisle; 13 Apr 2021, 06:44 PM.

    Comment


    • #3
      Thanks Pierre, That gives me a big jump on what I have spent the last few days trying to port and understand the basics of.

      Unfortunately, changing zPort to a known location, I still get
      Error 87: The parameter is incorrect
      (Just 1 of the MANY reasons I am running around in circles with error codes like that. What parameter? is it a part of SetupPacket? Index? Message Requested? a type pointed at another type? etc.....)

      but I digress

      Thank you for the snippet though, maybe I can figure out what is right or wrong.
      (By the way, do you know what the ROOT HUB device you were talking to was?)
      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, iz zPort is valid, then are you sure that a USB device is connected to this port ?
        Other than that you could play with <PortIndex> and <Index>.
        Last edited by Pierre Bellisle; 19 Mar 2008, 04:42 PM.

        Comment


        • #5
          Pierre,
          Absolutely. I am using 2 known ports to me, and ensuring they are not in use already as well.
          'zPortName = "\\?\acpi#pnp0501#1#{86e0d1e0-8089-11d0-9ce4-08003e301f73}
          is a standard serial port "COM1" that I can open/close/communicate by standard means.

          'zPortName = "\\?\usb#vid_10c4&pid_ea61#0002#{3C5E1462-5695-4E18-876B-F3F3D08AAF18}"
          Is a Usb port, with another of the same device attached, and I can access it by standard means of its dll.

          Anything that passes CreateFile, either gives me the incorrect parameter, or if I fiddle with the values I can get Error 1

          If I can just get 1 device (I do not care what it is, as long as I know it works) to actually work, then I can figure things out.

          Unfortunately all the docs show exactly what you have for code too, so now I am trying to break down every minute detail (filling URB and etc) just to see if I can determine a cause....because obviously it should work, but until I can get a working sample to base from, I am just shooting in the dark.
          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
            And if you downoad UsbView what do yo you got ?

            http://www.google.ca/search?hl=fr&q=...gle&meta=lr%3D


            Also, I have some code that I do not want to share yet
            but if you want, for a short period, you can download and try it...
            The exe and dat file: Usb.zip
            As usual you try at your own risk,
            all I can say is that it works great on my PC,
            except that I did not test "External HUB".

            It does almost the same as UsbView.

            If it works OK then we will know for sure
            that the code I previously posted is correct in your context.
            Last edited by Pierre Bellisle; 19 Mar 2008, 06:50 PM.

            Comment


            • #7
              Thank you again Pierre
              I keep losing the link to that program (everytime I need it I can NOT seem to find it.
              (probably because I know I am close, and can not see the tree from the forest )

              Since you said it was ok, one PM on its way in a min.

              Meanwhile, I am breaking down your example step by step and commenting on where in the docs I found each piece.

              Cliff
              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


              • #8
                No PM needed, I did change my previous post,
                just have to download...

                Comment


                • #9
                  Jezus Pierre,
                  Are you sure we are not attacking the same hard concepts at different points?

                  Although your sample is MUCH faster (I think I know why, but ) but in some areas, you seem to be "Leap Years ahead of me"

                  I especially like the color coding (once its up to the point that your documentation indicates what each color is supposed to mean....but from quick looks, I think I kinda follow the pattern)

                  I also love the database lookup....(still ton faster than what I got working)...Is it from our other conversation of looking up VID PID into something human useful?
                  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


                  • #10
                    Yellow is for controller, white is for controller description,
                    green is for port description, blue is for device descriptor,
                    red is for the data from the Usb-id.txt file
                    witch is downloaded from http://www.linux-usb.org/,
                    bright white is for language available from the device,
                    violet is for the multiple device node descriptors.

                    About the data lookup routine, I started it from scratch
                    becose this file is formatted in a simplier way.

                    Tell me if you find any bug...

                    Comment


                    • #11
                      I haven't looked deep yet, but guess what?
                      Vista had absolutely NO PROBLEMS

                      (I would've thought a Vista would blow up for something stupid)

                      I can see though why you want to keep the code you learned to yourself till you are ready though

                      You are definitely "Leap-Years" ahead of me in some areas, and I will be the 1st to admit it
                      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


                      • #12
                        About code posting,
                        I almost stopped to post in the code forum
                        becose I'm not confortable with the fact that
                        I won't be able to edit it after a while.
                        Reposting instead of editing is not an option for me.

                        If you want it, in a couple of days, I'll may post the code
                        temporarily on my web site but it need some
                        clean up first and more optimisation.

                        Comment


                        • #13
                          I would DEFINITELY be interested
                          It could help me clean up my mind in areas I am having trouble with. Currently trying to get a handle on USB, I think somebody threw me under a bus

                          I found myself trying to translate the following files into *.inc files since each one has 1 or 2 tiny pieces that the other needs for USB to work. (I figured, if I have to translate 1 or 2 pieces, why not just do the whole file?)

                          Files in progress
                          • Usb100.h
                          • Usb.h
                          • UsbIoCtl.h
                          • UsbIoDef.h
                          • WinIoCtl.inc '<--- Thankfully this was already done and I found it in my PB\WinApi folder
                          • ntddk.h
                          Hopefully I won't have to translate PshPack1.h and PopPack.h as well, but will not know till I get the others done.
                          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


                          • #14
                            Pierre,
                            Until you get the chance to post, can you (and others) take a look at your original code slightly modified? (I added all the comments and questions I could think of at the moment, as I spent the day trying to decipher MSDN docs and testing to see if I was right or wrong, but I am TOTALLY stuck)

                            Code:
                            #COMPILE EXE '#Win 8.04#
                            #DIM ALL
                            #INCLUDE "Win32Api.inc" '#2005-01-27#
                            '*********************************************************************************************
                            '*** Constants and variables below as described in *.h files from M$, and hopefully soon   ***
                            '*** ported to PB *.inc files                                                              ***
                            '*********************************************************************************************
                            %USB_DEVICE_DESCRIPTOR_TYPE              = 1                          '<--- Found in Usb100.h
                            %USB_REQUEST_GET_DESCRIPTOR              = 6                          '<--- Found in Usb100.h
                            %USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION = 260                        '<--- Found in UsbIoDef.h
                            %FILE_DEVICE_UNKNOWN                     = 34 '0x0022                 '<--- Found in WinIoCtl.inc
                            %FILE_DEVICE_USB                         = %FILE_DEVICE_UNKNOWN       '<--- Found in UsbIoDef.h
                            %FILE_ANY_ACCESS                         = 0                          '<--- Found in WinIoCtl.inc
                            %METHOD_BUFFERED                         = 0                          '<--- Found in WinIoCtl.inc
                            %BMREQUEST_DEVICE_TO_HOST                = 1   'Direction of commo    '<--- Found in Usb100.h
                            
                            TYPE USB_SETUP_PACKET                                                 '<--- Not found, but assume Pierre convert of Usb100.h due to the parts in the UDT?
                                 bmRequest AS BYTE
                                 bRequest  AS BYTE
                                 wValue    AS WORD
                                 wIndex    AS WORD
                                 wLength   AS WORD
                            END TYPE
                            
                            TYPE USB_DESCRIPTOR_REQUEST                                           '<--- Found in UsbIoCtl.h
                                 ConnectionIndex AS LONG
                                 SetupPacket     AS USB_SETUP_PACKET
                                 SetupData       AS STRING * 2048                                 '<--- Is SetupData 2048 chars for a reason?
                            END TYPE
                            '______________________________________________________________________________
                            '*** CTL_CODE macro found in WinIoCtl.inc
                            FUNCTION CTL_CODE(BYVAL dwDeviceType AS DWORD, BYVAL dwFunction AS DWORD, BYVAL dwMethod AS DWORD, BYVAL dwAccess AS DWORD) AS DWORD
                            '     Thank to Erwin van de Wiel
                                 SHIFT LEFT dwDeviceType, 16
                                 SHIFT LEFT dwAccess, 14
                                 SHIFT LEFT dwFunction, 2
                                 FUNCTION = dwDeviceType OR dwAccess OR dwFunction OR dwMethod
                            END FUNCTION
                            '______________________________________________________________________________
                            
                            FUNCTION PBMAIN () AS LONG
                                 LOCAL IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION    AS DWORD
                                 LOCAL SA                                               AS SECURITY_ATTRIBUTES
                                 LOCAL DeviceBuffer                                     AS USB_DESCRIPTOR_REQUEST
                                 LOCAL zBuffer                                          AS ASCIIZ * %MAX_PATH
                                 LOCAL zPortName                                        AS ASCIIZ * %MAX_PATH
                                 LOCAL PortIndex                                        AS LONG
                                 LOCAL LastError                                        AS DWORD
                                 LOCAL hDevice                                          AS DWORD
                                 LOCAL BytesReturned                                    AS DWORD
                                 LOCAL Index                                            AS BYTE
                            '*** Not sure if I need security attributes?
                             SA.nLength = SIZEOF(SECURITY_ATTRIBUTES)
                             SA.lpSecurityDescriptor = 0
                             SA.bInheritHandle = %FALSE
                            '*** To work, a device must be connected to a valid portname. Use USBView to locate a valid Usb Root Hub
                            '*** Pierre's Root Hub
                            '     zPortName = "\\.\USB#ROOT_HUB#4&1a0027b6&0#{f18a0e88-c30c-11d0-8815-00a0c906bed8}"
                            '*** My Root Hub Work
                            '     zPortName = "\\?\USB#ROOT_HUB#4&737e51b&0#{f18a0e88-c30c-11d0-8815-00a0c906bed8}"    '<--- Does not seem to matter if started with \\.\ or \\?\
                            '*** My Root Hub Home
                                 zPortName = "\\?\USB#ROOT_HUB20#4&26681169&0#{f18a0e88-c30c-11d0-8815-00a0c906bed8}"    '<--- Does not seem to matter if started with \\.\ or \\?\
                            
                                 hDevice = CreateFile(zPortName, %GENERIC_READ, 0, SA, %OPEN_EXISTING, BYVAL 0, %NULL)
                                 IF hDevice = %INVALID_HANDLE_VALUE THEN
                            MSGBOX "Invalid handle value !"
                                 ELSE
                            '*** IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION value is created by calling the CTL_Code macro (located in WinIoCtl.Inc)
                                 IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION = CTL_Code(%FILE_DEVICE_USB, %USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, %METHOD_BUFFERED, %FILE_ANY_ACCESS)
                            '*** The USB_DESCRIPTOR_REQUEST structure is used with the IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION
                            '*** I/O control request to retrieve one or more descriptors for the device that is associated with the indicated connection index.
                                 PortIndex                          = 1                 'Port Index is 1 based (using 0 will cause invalid parameter)
                                 Index                              = 0                 '<--- Changing this value changes the responses to show the index you used?.
                                                                                        '<--- 0 = 1-0-0-0-128-6-    0    -1-0-0-8-0-18-1-16-1-0-0-0-64
                                                                                        '<--- 1 = 1-0-0-0-128-6-    1    -1-0-0-8-0-18-1-16-1-0-0-0-64
                                                                                        '<--- 200 = 1-0-0-0-128-6-  200  -1-0-0-8-0-18-1-16-1-0-0-0-64
                                 DeviceBuffer.ConnectionIndex       = PortIndex
                            '*** On input to the IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION I/O control request, the USB stack ignores the value of bmRequest and inserts a value of 0x80
                                 DeviceBuffer.SetupPacket.bmRequest = &h80              '<--- Set anyways for readability
                            '*** On input to the IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION I/O control request, the USB stack ignores the value of bRequest and inserts a value of 0x06 (%USB_REQUEST_GET_DESCRIPTOR)
                                 DeviceBuffer.SetupPacket.bRequest  = %USB_REQUEST_GET_DESCRIPTOR        '<--- Set anyways for readability
                            '*** On input to the IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION I/O control request, the caller should specify the type of descriptor to retrieve in the high byte of wValue and the descriptor index in the low byte
                            '*** Descriptor type                                        Meaning
                            '*** USB_DEVICE_DESCRIPTOR_TYPE (0x01)            Instructs the USB stack to return the device descriptor.
                            '*** USB_CONFIGURATION_DESCRIPTOR_TYPE (0x02)     Instructs the USB stack to return the configuration descriptor and all interface, endpoint, class-specific, and vendor-specific descriptors associated with the current configuration..
                            '*** USB_STRING_DESCRIPTOR_TYPE (0x03)            Instructs the USB stack to return the indicated string descriptor.
                            '*** USB_INTERFACE_DESCRIPTOR_TYPE (0x04)         Instructs the USB stack to return the indicated interface descriptor.
                            '*** USB_ENDPOINT_DESCRIPTOR_TYPE (0x05)          Instructs the USB stack to return the indicated endpoint descriptor.
                            
                            '******************************************** POINT OF CONFUSION *****************************************
                            '*** Pierre's Original
                            '   DeviceBuffer.SetupPacket.wValue    = (%USB_DEVICE_DESCRIPTOR_TYPE * 256) + Index      '<--- 257 total returns 1-0-0-0-128-6-    0    -1-0-0-8-0-18-1-16-1-0-0-0-64
                            '*** My interpretation
                            '     DeviceBuffer.SetupPacket.wValue    = %MAX_PATH + 2                                    '<--- 257 total returns 1-0-0-0-128-6-    6    -1-0-0-8-0-18-1-16-1-0-0-0-64
                            '*** I am not sure the difference in the above except Descriptor should be High Byte, and Descriptor index should be Low Byte
                                 LOCAL SetupHiByte AS BYTE
                                 LOCAL SetupLoByte AS BYTE
                                 SetupHiByte = %USB_DEVICE_DESCRIPTOR_TYPE
                                 SetupLoByte = PortIndex                                '<--- I am only guessing what "Descriptor Index" may be cause I can not find it in the docs
                                                                                        '<--- If I use Index(0) I get      1-0-0-0-128-6-    0    -1-0-0-8-0-18-1-16-1-0-0-0-64
                                                                                        '<--- If I use PortIndex(1) I get  1-0-0-0-128-6-    1    -1-0-0-8-0-18-1-16-1-0-0-0-64
                                 DeviceBuffer.SetupPacket.wValue = MAK(WORD, SetupLoByte, SetupHiByte)
                            '*************************************************** END CONFUSION ****************************************
                                 DeviceBuffer.SetupPacket.wIndex    = 0 'Should be Language id
                                 DeviceBuffer.SetupPacket.wLength   = SIZEOF(DeviceBuffer.SetupPacket)
                            
                            
                               IF DeviceIoControl(hDevice, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, _
                                                  DeviceBuffer, SIZEOF(DeviceBuffer), _
                                                  DeviceBuffer, SIZEOF(DeviceBuffer), _
                                                  BytesReturned, BYVAL %NULL) THEN
                            '*********************************************** Point of Confusion
                            '*** All chars in DeviceBuffer are unprintable so uncomment below if wanting to see values
                            LOCAL i AS LONG
                            LOCAL Msg AS STRING
                            FOR i = 1 TO BytesReturned
                                 MSG = msg +  STR$(ASC(MID$(DeviceBuffer, i, 1))) + SPACE$(3)
                            NEXT i
                                 MSGBOX "Success !" + $CR _
                                           + "Buffer = " + $TAB + zBuffer + $CR _
                                           + "Buffer Size = " + $TAB + STR$(SIZEOF(DeviceBuffer)) + $CR _
                                           + "IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION" + $TAB + STR$(IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION) + $CR _
                                           + "1st char in Buffer = " + $TAB + STR$(ASC(DeviceBuffer)) + $CR _
                                           + "SetupPacket Size = " + $TAB + STR$(SIZEOF(DeviceBuffer.SetupPacket)) + $CR _
                                           + "Bytes Returned" + $TAB + STR$(BytesReturned) + $CR _
                                           + "Device Buffer Setup Packet = " + $TAB + DeviceBuffer.SetupData + $CR _
                                           + "Msg = " + Msg
                            '*** 1.) Msg does not show anything?, but if I make Msg a MsgBox for each char they show.
                            '*** 2.) Ok so I got some info....where is it? what is it? How do I use it?
                            '*** My best guess is something to do with one or more of the *.inc files that I am still working on translating?
                            '************************************************* END CONFUSION **********************************************
                               ELSE
                                 LastError = GetLastError
                                 FormatMessage %FORMAT_MESSAGE_FROM_SYSTEM, BYVAL %NULL, LastError, %NULL, _
                                               zBuffer, SIZEOF(zBuffer), BYVAL %NULL
                                 MSGBOX "Error" & STR$(LastError) & " : " & zBuffer + $CR + STR$(IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION) _
                                      + $CR + STR$(SIZEOF(DeviceBuffer)) + $CR + STR$(ASC(DeviceBuffer)) + $CR + STR$(SIZEOF(DeviceBuffer.SetupPacket)) _
                                      + $CR + STR$(BytesReturned)
                               END IF
                               CloseHandle hDevice
                             END IF
                            
                            END FUNCTION
                            '______________________________________________________________________________
                            '
                            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


                            • #15
                              Q: Is SetupData 2048 chars for a reason ?

                              No, I choose a big buffer to avoid problem while experimentation.
                              I'm not sure yet but I think that it should be set to %MAXIMUM_USB_STRING_LENGTH (255)
                              ------------------------------------
                              About security attributes, I had no problems either I use it or not,
                              so we probably won't need it, this have to be verified.
                              ------------------------------------
                              For <<(%USB_DEVICE_DESCRIPTOR_TYPE * 256) + Index>>
                              this is equivalent to Hi(BYTE) and LO(BYTE).
                              So I could also have used MAK(WORD, Index, %USB_DEVICE_DESCRIPTOR_TYPE)
                              or SHIFT LEFT and OR...
                              ------------------------------------
                              Q: All chars in DeviceBuffer are unprintable

                              DeviceBuffer is of USB_DESCRIPTOR_REQUEST type.
                              So you could try only if %SUCCESS
                              DeviceBuffer.ConnectionIndex
                              DeviceBuffer.SetupPacket.bmRequest
                              DeviceBuffer.SetupPacket.wValue
                              DeviceBuffer.SetupPacket.wIndex
                              DeviceBuffer.SetupPacket.wLength
                              The data part is request dependant.
                              ------------------------------------
                              Also, a better name for USB_SETUP_PACKET
                              would have been SETUP_PACKET
                              and is a part of USB_DESCRIPTOR_REQUEST

                              Code:
                              So I translated...
                               
                              typedef struct _USB_DESCRIPTOR_REQUEST {
                                ULONG ConnectionIndex;
                                struct {
                                  UCHAR  bmRequest;
                                  UCHAR  bRequest;
                                  USHORT  wValue;
                                  USHORT  wIndex;
                                  USHORT  wLength;
                                } SetupPacket;
                                UCHAR  DATA[0];
                              } USB_DESCRIPTOR_REQUEST, *PUSB_DESCRIPTOR_REQUEST;
                               
                              TO...
                               
                              TYPE USB_SETUP_PACKET                                              
                                bmRequest AS BYTE
                                bRequest  AS BYTE
                                wValue    AS WORD
                                wIndex    AS WORD
                                wLength   AS WORD
                              END TYPE
                               
                              AND
                               
                              TYPE USB_DESCRIPTOR_REQUEST                                        
                                ConnectionIndex AS LONG
                                SetupPacket     AS USB_SETUP_PACKET
                                SetupData       AS STRING * 2048                            
                              END TYPE
                               
                              but following also acceptable
                               
                              TYPE USB_DESCRIPTOR_REQUEST                                        
                                ConnectionIndex AS LONG
                                bmRequest AS BYTE
                                bRequest  AS BYTE
                                wValue    AS WORD
                                wIndex    AS WORD
                                wLength   AS WORD
                                SetupData AS STRING * 2048                            
                              END TYPE
                              Last edited by Pierre Bellisle; 20 Apr 2021, 06:11 PM.

                              Comment


                              • #16

                                As soon as I looked at DeviceBuffer.SetupData then I started getting values that I would have expected.
                                • bLength = 18 '<--- Checks out as Device Descriptor
                                  bDescriptorType = 1 '<--- Checks out from USB Complete for "Device"
                                  bcdUSB = (I am on the right track but missing something stupid)


                                Currently that block of code is using
                                Code:
                                LOCAL bLength AS BYTE
                                LOCAL bDescriptorType AS BYTE
                                LOCAL bcdUSB AS WORD
                                LOCAL bDeviceClass AS BYTE
                                LOCAL bDeviceSubclass AS BYTE
                                LOCAL bDeviceProtocol AS BYTE
                                LOCAL bMaxPacketSize AS BYTE
                                LOCAL idVendor AS WORD
                                LOCAL idProduct AS WORD
                                LOCAL bcdDevice AS WORD
                                LOCAL iManufacturer AS BYTE
                                LOCAL iProduct AS BYTE
                                LOCAL iSerialNumber AS BYTE
                                LOCAL bNumConfigurations AS BYTE
                                
                                bLength = ASC(MID$(DeviceBuffer.SetupData, 1,1))
                                bDescriptorType = ASC(MID$(DeviceBuffer.SetupData, 2,1))
                                bcdUSB = ASC(MID$(DeviceBuffer.SetupData, 3,1)) + ASC(MID$(DeviceBuffer.SetupData, 4,1))
                                bDeviceClass = ASC(MID$(DeviceBuffer.SetupData, 5,1))
                                bDeviceSubclass = ASC(MID$(DeviceBuffer.SetupData, 6,1))
                                bDeviceProtocol = ASC(MID$(DeviceBuffer.SetupData, 7,1))
                                bMaxPacketSize = ASC(MID$(DeviceBuffer.SetupData, 8,1))
                                idVendor = ASC(MID$(DeviceBuffer.SetupData, 9,1)) + ASC(MID$(DeviceBuffer.SetupData, 10,1))
                                idProduct = ASC(MID$(DeviceBuffer.SetupData, 11,1)) + ASC(MID$(DeviceBuffer.SetupData, 12,1))
                                bcdDevice = ASC(MID$(DeviceBuffer.SetupData, 13,2)) + ASC(MID$(DeviceBuffer.SetupData, 14,1))
                                iManufacturer = ASC(MID$(DeviceBuffer.SetupData, 15,1))
                                iProduct = ASC(MID$(DeviceBuffer.SetupData, 16,1))
                                iSerialNumber = ASC(MID$(DeviceBuffer.SetupData, 17,1))
                                bNumConfigurations = ASC(MID$(DeviceBuffer.SetupData, 18,1))
                                I think bcdUSB is telling me its a USB 1.1 device but can not get the format right.
                                bMaxPacketSize = 64 (Telling me high-speed)

                                But all my other values are zeroes????? I would find it odd that idVendor and idProduct not filled in for a root hub?????

                                I have to be making a mistake or still missing something
                                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


                                • #17
                                  Cliff,

                                  here is the CC code...

                                  USB digger for PB/CC

                                  Have fun...
                                  Last edited by Pierre Bellisle; 22 Mar 2008, 09:33 PM.

                                  Comment


                                  • #18
                                    Thank you SOOOOoooo much Pierre

                                    At least now I have a fighting chance at figuring out the documentation

                                    I take it you usually use PbCC though cause I had to make a bunch of Minor changes to get it to work in PbWin?

                                    You also showed me a few "Points of Interest" that I usually avoid (just cause the time to learn vs what I am trying to do at the time) that I hope to take a second look at.

                                    Hopefully tomorrow I can parse through things (If Easter doesn't get in the way) and work out how I understand things vs code shown vs UsbView

                                    By the way...nomatter how you feel your code is..it is WELL worth posting..Such a hard concept, and you made it so simple that I do not think anyone could blame you for a glitch or 2

                                    In the words of my generation... MOST EXCELLLLLLLLENT work dude!!!!
                                    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


                                    • #19
                                      Just updated, check that you have the latest...

                                      Also, if you have an external HUB, tell me if code works...

                                      [Added]
                                      Did another update

                                      USB digger for PB/CC

                                      There is also USB digger for PB/Win that use a treeview and a textbox
                                      .
                                      .
                                      Don't forget to get http://www.linux-usb.org/usb.ids and save as "Usb-id.txt"
                                      .
                                      .
                                      Last edited by Pierre Bellisle; 22 Mar 2008, 10:31 PM.

                                      Comment


                                      • #20
                                        Another update to both version...

                                        Comment

                                        Working...
                                        X