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]
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
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
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
Hello Roger:
Any chance you can post your USB code or provide a download link?
Best Regards,
SS
SideSwipe,
At the end of his first post is a d/l link for the ZIP
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.
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