Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6013029
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 23, 20262026-05-23T02:29:21+00:00 2026-05-23T02:29:21+00:00

EDIT Oddly enough, I’ve worked around this issue, but it’s still annoying me. I

  • 0

EDIT

Oddly enough, I’ve worked around this issue, but it’s still annoying me. I worked around it by sending too-long writes, with padded zeroes; the code works but sends a few hundred unnecessary bytes. Specifically, I need to send exactly 992-byte packets instead of 7 or 19-byte packets. My question still stands however, why is the Logitech code able to make 7- or 19-byte writes when I cannot.


I’m running into an issue where a specific block of code fails or succeeds apparently depending on the length of the data passed to it. This makes no sense to me; I’m obviously doing something wrong but I can’t tell what.

I have three cases where I’m trying to use the following block of code, which writes a byte stream to a USB device (one of two Logitech G-Series keyboards):

Friend Function WriteData(ByVal Keyboard As GSeriesKeyboard, ByVal Data() As Byte) As Integer
   Dim BytesWritten As Integer = Data.Length
   Dim Success As Boolean = Win32.WriteFile(Keyboard.ExternalIOHandle, Data, Data.Length, BytesWritten, Nothing)
   Dim ErrorCode As Integer = GetLastError()
   Return ErrorCode
End Function

<DllImport("kernel32.dll", SetlastError:=True)> Friend Shared Function WriteFile( _
    ByVal File As SafeFileHandle, _
    ByVal Buffer() As Byte, _
    ByVal NumberOfBytesToWrite As Integer, _
    ByRef NumberOfBytesWritten As Integer, _
    ByRef Overlapped As System.Threading.NativeOverlapped) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function

In the first case, I’m passing a 992-byte stream and the write completes successfully. In the second and third cases, I’m writing either 7 or 19 bytes, and WriteFile generates the errors ERROR_INVALID_USER_BUFFER for 7 bytes, or ERROR_INVALID_PARAMETER for 19 bytes. I’ve opened the handle for reading and writing, non-overlapped.

When using USBTrace, I can see that the default Logitech program is able to write all three cases without trouble, but my own code can only write the 992-byte case. This behavior is the same whether I compile my code as x86 or x64.

The code I’m using to open the handle is this:

    Friend Function OpenInterface(ByVal KeyboardPath As String) As SafeFileHandle

        Dim SecurityData As New SECURITY_ATTRIBUTES()
        Dim security As New DirectorySecurity()
        Dim DescriptorBinary As Byte() = security.GetSecurityDescriptorBinaryForm()
        Dim SecurityDescriptorPtr As IntPtr = Marshal.AllocHGlobal(DescriptorBinary.Length)

        SecurityData.nLength = Marshal.SizeOf(SecurityData)
        Marshal.Copy(DescriptorBinary, 0, SecurityDescriptorPtr, DescriptorBinary.Length)
        SecurityData.lpSecurityDescriptor = SecurityDescriptorPtr

        Dim Handle As SafeFileHandle = Win32.CreateFile(KeyboardPath, GENERIC_READ Or GENERIC_WRITE, _
                                                        FILE_SHARE_READ Or FILE_SHARE_WRITE, SecurityData, _
                                                        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)

        If Handle.IsInvalid Then
            Dim ErrorInfo As New ComponentModel.Win32Exception()
            Debug.Print("Failed to get device IO handle: " & ErrorInfo.Message)
        End If

        Return Handle
    End Function

    Friend Overridable Function BitmapToLcdFormat(ByVal SourceBitmap As Bitmap) As Byte()
        'Base class is for the generic B&W 160x43 LCD.  Override for G19 if I ever get my hands on one
        Dim Data As Byte() = New Byte(991) {}
        ' USBTrace says 992 bytes
        Dim Image(640 * 48) As Byte 'Temp array for image conversion.  Adds additional 5 lines of unused pixels to avoid an out-of-bounds error
        Dim BitmapData As BitmapData = SourceBitmap.LockBits(New Rectangle(0, 0, 160, 43), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb)
        Marshal.Copy(BitmapData.Scan0, Image, 0, (640 * 43))

        Data(0) = &H3 'Set-LCD
        Dim output As Integer = 32 'First byte of image data starts at byte 32; 960 bytes of image data
        Dim ImageOffset As Integer = 0
        For Row As Integer = 0 To 5
            For Column As Integer = 0 To (SourceBitmap.Width << 2) - 1 Step 4

                Dim r As Integer = _
                ((Image(ImageOffset + Column + BitmapData.Stride * 0) And &H80) >> 7) Or _
                ((Image(ImageOffset + Column + BitmapData.Stride * 1) And &H80) >> 6) Or _
                ((Image(ImageOffset + Column + BitmapData.Stride * 2) And &H80) >> 5) Or _
                ((Image(ImageOffset + Column + BitmapData.Stride * 3) And &H80) >> 4) Or _
                ((Image(ImageOffset + Column + BitmapData.Stride * 4) And &H80) >> 3) Or _
                ((Image(ImageOffset + Column + BitmapData.Stride * 5) And &H80) >> 2) Or _
                ((Image(ImageOffset + Column + BitmapData.Stride * 6) And &H80) >> 1) Or _
                ((Image(ImageOffset + Column + BitmapData.Stride * 7) And &H80) >> 0)

                Data(output) = CByte(r)

                output += 1
            Next
            ImageOffset += BitmapData.Stride * 8
        Next
        SourceBitmap.UnlockBits(BitmapData)
        Return Data
    End Function

The exact code blocks that call WriteData() are the following:

(Logitech G15)
    HardwareInterface.WriteData(Me, New Byte() {2, 0, 0, 0, 0, 0, 0})

(Logitech G510)
    HardwareInterface.WriteData(Me, New Byte() {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0})

(Both; the one that works)
    HardwareInterface.WriteData(Me, BitmapToLcdFormat(NewImage)) 'Build 992-byte LCD-format bitmap from source iumage

These specific commands are used to remap the macro (“G”) keys on the boards to different character codes, in this case 00 disables the key. Anyone with a G15/G19/G510 keyboard can see this by disabling their Logitech gamepanel software and re-plugging the keyboard. G3 will act like F3 in notepad (find next), but after restarting the gamepanel software it will no longer do so.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-23T02:29:21+00:00Added an answer on May 23, 2026 at 2:29 am

    I’m sorry this is not a Really Useful Answer, as I’m quite sure that what you are seeing is specific to your particular scenario, and I don’t know this scenario in its entirety.

    But the most likely reason to what you are seeing in my opinion is this. What you are writing to is not a real file (as you undoubtedly know) it’s just an interface to your keyboard, that is surfaced as a file. Because of this, it is not a surprise, that you see completely different set of behaviour from a normal file. You can write to a file in file system most of the time. With the keyboard there could be a protocol that you have to follow to make it work.

    What I think is happening here, is that things you are trying to write that fails, they are not being attempted to be written at the right state. The keyboard for whatever reason does not expect them when you are writing them.

    You are saying that you can see that they are accepted ok with the USBTrace. This means that there is a correct state where they could be written there properly.

    I’d start investigation at looking at the sequence of interactions that you are doing with the keyboard and thinking what could affect the ability of the keyboard to process your input.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

EDIT 4 July: Still struggling with this issue. I'm sure all that's required is
EDIT After staring at this for 2 days, I do see one issue. I
Edit: This question was written in 2008, which was like 3 internet ages ago.
EDIT: This was formerly more explicitly titled: - Best solution to stop Kontiki's KHOST.EXE
EDIT: This question is more about language engineering than C++ itself. I used C++
EDIT What small things which are too easy to overlook do I need to
Edit: This was accidentally posted twice. Original: VB.NET Importing Classes I've seen some code
Edit: I have solved this by myself. See my answer below I have set
Edit: The below question was answered by this . I have a new updated
EDIT : I've gotten the famous question badge with this question, so I figured

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.