News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

USB HID Finder

Started by Roger, April 15, 2009, 04:50:47 PM

Previous topic - Next topic

Roger

Hi Everyone,

I have been writing a little program to identify HID devices on the USB and to learn how to communicate with them. It seems to work with Win98 but as far as I can see XP will not let it see Mice or Keyboards.

When I have done more work on the HID Device itself (based on a PIC Microcontroller) I expect to post a version which does more.

[attachment deleted by admin]

Roger

Hi Everyone,

XP does claim exclusive ownership of keyboards and mice and will not let my program have a handle to access them or my own device when it is configured as a keyboard.
Furthermore once it has enumerated a particular device as a keyboard/mouse, it assumes any device with the same VID and PID values is a keyboard/mouse and so changing the HID report descriptor is not sufficient to change the device unless the PID is changed at the same time.

I would like to know what it makes of other versions of windows if anyone happens to try it.

Regards Roger

MichaelW

Running on my Windows 2000 system:

Looking for HID Devices


HID found - not Valid
HID found - not Valid

That's all Folks
Press Return


This code is sloppy, but as far as it goes it appears to work:

; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    include \masm32\include\masm32rt.inc
    include \masm32\include\setupapi.inc

    includelib \masm32\lib\setupapi.lib

    DIGCF_PRESENT         equ 00000002h
    DIGCF_ALLCLASSES      equ 00000004h
    DIGCF_PROFILE         equ 00000008h
    DIGCF_DEVICEINTERFACE equ 00000010h

    HDEVINFO typedef DWORD

    SP_DEVICE_INTERFACE_DATA STRUCT
      cbSize              DWORD ?
      InterfaceClassGuid  GUID  <>
      Flags               DWORD ?
      Reserved            DWORD ?
    SP_DEVICE_INTERFACE_DATA ENDS

    ;-------------------------
    ; #define ANYSIZE_ARRAY 1
    ;-------------------------

    SP_DEVICE_INTERFACE_DETAIL_DATA STRUCT
      cbSize      DWORD ?
      DevicePath  BYTE  ANYSIZE_ARRAY dup(?)
    SP_DEVICE_INTERFACE_DETAIL_DATA ENDS

    ;-------------------------------------------------------
    ; For this I used the w2k version of the import library
    ; from the Microsoft Windows Server 2003 SP1 DDK.
    ;-------------------------------------------------------

    includelib hid.lib

    LPGUID typedef ptr GUID

    HidD_GetHidGuid PROTO HidGuid:LPGUID

; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    .data

      guid    GUID      <>
      lpsz    LPOLESTR  0
      hdi     HDEVINFO  0
      spdid   SP_DEVICE_INTERFACE_DATA <SIZEOF SP_DEVICE_INTERFACE_DATA>
      SIZEOFSPDIDD = SIZEOF SP_DEVICE_INTERFACE_DETAIL_DATA
      spdidd  SP_DEVICE_INTERFACE_DETAIL_DATA <SIZEOFSPDIDD>
              db 1024 dup(0)

    .code
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    print str$(SIZEOFSPDIDD),13,10

    invoke HidD_GetHidGuid, ADDR guid
    print str$(eax),13,10
    invoke StringFromIID, ADDR guid, ADDR lpsz
    print str$(eax),13,10,13,10
    invoke crt_printf, chr$("%S%c%c"), lpsz, 10, 10

    invoke SetupDiGetClassDevs, ADDR guid, NULL, 0, DIGCF_DEVICEINTERFACE
    mov hdi, eax
    print str$(hdi),13,10,13,10

    xor ebx, ebx

  @@:

    invoke SetupDiEnumDeviceInterfaces, hdi, NULL, ADDR guid, ebx, ADDR spdid
    .IF eax == 0
      invoke GetLastError
      .IF eax != ERROR_NO_MORE_ITEMS
        print "SetupDiEnumDeviceInterfaces unexpected error",13,10
      .ENDIF
      jmp @F
    .ENDIF
    invoke SetupDiGetDeviceInterfaceDetail, hdi, ADDR spdid, ADDR spdidd,
                                            1024, NULL, NULL
    print str$(eax),13,10,13,10

    print ADDR spdidd.DevicePath,13,10

    inc ebx
    jmp @B

  @@:

    invoke SetupDiDestroyDeviceInfoList, hdi
    print str$(eax),13,10,13,10

    inkey "Press any key to exit..."
    exit
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start


5
1872367808
0

{4D1E55B2-F16F-11CF-88CB-001111000030}

1264440

1

\\?\hid#vid_045e&pid_0059&col01#6&4f7278c&0&0000#{4d1e55b2-f16f-11cf-88cb-001111
000030}
1

\\?\hid#vid_045e&pid_0059&col02#6&4f7278c&0&0001#{4d1e55b2-f16f-11cf-88cb-001111
000030}
1

eschew obfuscation

Roger

Hi Michael,

Thank you for trying it. It seems Win2000 works the same as XP.

As far as I can see your code does the same as mine until you print the path string in spdidd.  At this point I used CreateFile to get a handle to the device and it is this which XP does not like.
I now have my own device running and XP will let me have the handle to it and so I can get the VID, PID and text strings to display.
The next program is going to need to get the VID & PID so that I can use them to identify my own device and the communicate with it.

I was interested to see that you used SetupDiGetDeviceInterfaceDetail just once with a large buffer whereas all the references I have found, including MSDN, require it to be used twice, first to get the buffer size and second to use the size obtained.

Regards Roger

SideSwipe

Hello Roger:

Any chance you can post your USB code or provide a download link?

Best Regards,
SS
"Crashing through life !"

dedndave

SideSwipe,
   At the end of his first post is a d/l link for the ZIP

tenkey

Quote from: Roger on April 16, 2009, 09:39:19 PM
Furthermore once it has enumerated a particular device as a keyboard/mouse, it assumes any device with the same VID and PID values is a keyboard/mouse and so changing the HID report descriptor is not sufficient to change the device unless the PID is changed at the same time.
Have you tried removing the VID/PID entry from the registry? This is required if you are changing device drivers for the same VID/PID.
A programming language is low level when its programs require attention to the irrelevant.
Alan Perlis, Epigram #8

Roger

Hi Tenkey,


Quote from: tenkey on April 30, 2009, 04:32:41 AM
Have you tried removing the VID/PID entry from the registry? This is required if you are changing device drivers for the same VID/PID.

Not yet!

It is much easier to change the value of the PID as it is declared data in my device's firmware. Eventually, when the project is finished or I run out of PIDs (I've used about 4 of 256), I will have to do so.

Regards Roger