0

I have some code I've written that has worked sporadically, and I don't understand the reasons why it succeeds or fails. The code in question is fairly straightforward, a single call to CreateFile() from VB.NET;

Dim Handle As Integer = Win32.CreateFile(KeyboardPath, GENERIC_READ Or GENERIC_WRITE, _
                                         FILE_SHARE_READ Or FILE_SHARE_WRITE, Nothing, _
                                         OPEN_EXISTING, &H80, 0)

The problem is that when I call this, I get the win32 error ERROR_ACCESS_DENIED, but if I remove the GENERIC_READ request, the handle is granted just fine. This has happened before (on a different machine), and I'm completely stumped as to what sequence of events would result in the ability to write to a device and not read from it. The device in question is a Logitech G510 keyboard, and this code has worked fine before on a Vista 32-bit system (I'm now testing it on a Win7 x64 system and fixing all the compatibility issues I can find).

My question is, what can cause CreateFile to sporadically fall back to only allowing write access, what am I doing wrong that's causing it to do so, and how would I go about fixing the issue? I've included the full function below - note that with ONLY the GENERIC_READ flag passed, I also am not allocated a handle (same error)

As reference, the particular device path I've been using is \\?\hid#vid_046d&pid_c22d&mi_00#7&1a08be07&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030} (This is for a Logitech G510 gaming keyboard) Also, the code has performed similarly both with and without administrator privileges, if at all possible I want to be able to run without those privileges as I do not need them (and it doesn't need them on my vista system to work fine).

Private Function OpenInterface(ByVal KeyboardPath As String) As Integer
    Dim Handle As Integer = Win32.CreateFile(KeyboardPath, GENERIC_READ Or GENERIC_WRITE, _
                                             FILE_SHARE_READ Or FILE_SHARE_WRITE, Nothing, _
                                             OPEN_EXISTING, &H80, 0)
    Dim ee As Integer = GetLastError()
    Return Handle
End Function
Sukasa
  • 1,700
  • 4
  • 22
  • 40
  • How can you write to a keyboard? Try opening with only GENERIC_READ if you don't really need to write to it. Also, some classes of devices can be opened with no access and their IOCTLs still work. – Luke Apr 17 '11 at 12:27
  • 1
    [This](http://www.logitech.com/en-us/gaming/mice-keyboard-combos/devices/7246) is the keyboard I'm trying to write to - specifically, the backlight, LED, and LCD panel need to be written to. – Sukasa Apr 17 '11 at 21:58
  • Also, GENERIC_READ alone also exhibits the same issue - I'll add that to the main question. – Sukasa Apr 17 '11 at 21:59
  • Any chance the keyboard is showing up as two devices, one a normal readable keyboard, and one write-only corresponding to all the fancy stuff? Or perhaps a keyboard class driver has already opened the keyboard with sharing mode `FILE_SHARE_WRITE` to get exclusive access to the incoming keystrokes. – Ben Voigt Apr 17 '11 at 22:05
  • @Ben Put in your comment about multiple entries for the same device as an answer, that ended up being what it was. I was looking for device strings matching *vid_046d&pid_c22d&mi_00* when I wanted *vid_046d&pid_c22d&mi_01&col02* - of course that leads to what the mi_xx and col_xx things mean... – Sukasa Apr 17 '11 at 23:48
  • @Sukasa I have a similar question, could you help me? [CreateFile: “Access is denied” even with Administrator privileges - Win7](http://stackoverflow.com/q/8694713/341970) – Ali Jan 03 '12 at 09:54
  • @Ali I have left what will hopefully be a helpful response there. – Sukasa Jan 04 '12 at 01:53

1 Answers1

2

If the keyboard has functions that don't fit well in a normal keyboard class, it may very well expose multiple device instances, one which encompasses the normal keyboard behavior, and one for the fancy stuff.

And one of the instances could well be write-only.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720