sharpdx / SharpDX

SharpDX GitHub Repository
http://sharpdx.org
MIT License
1.68k stars 641 forks source link

[RawInput] Strange Garbage Data in Device.KeyboardInput handler #1050

Open malware-dev opened 6 years ago

malware-dev commented 6 years ago

I am getting seemingly garbage data when attempting to get keyboard input. Am I doing something stupid?

static class Program
{
    public static RenderForm RenderForm { get; private set; }

    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        RenderForm = new RenderForm();
        RenderForm.ClientSize = new Size(1280, 720);
        RenderForm.Show();
        Device.RegisterDevice(UsagePage.Generic, UsageId.GenericKeyboard, DeviceFlags.None);
        Device.KeyboardInput += OnKeyboardInput;
        RenderLoop.Run(RenderForm, RenderCallback);
    }

    static void OnKeyboardInput(object sender, KeyboardInputEventArgs e)
    {
        Debug.WriteLine(e.Key + " " + e.ScanCodeFlags + " " + e.MakeCode + " " + e.ExtraInformation + " " + e.State);
        if (e.Key == Keys.Escape)
            RenderForm.Close();
    }

    static void RenderCallback()
    {

    }
}

Output: (x64-build, pressing keys wildly)

None -11937 -5248 2359 679385015
None -11937 -5248 2359 679385015
None -11937 -5248 2359 679385015
None -11937 -5248 2359 679385015
None -11937 -5248 2359 679385015
None -11937 -5248 2359 679385015
None -11937 -5248 2359 679385015
None -11937 -5248 2359 679385015
None -11937 -5248 2359 679385015

Output: (AnyCPU build, pressing esc only)

LButton, OemClear 751 -5632 11923952 32
1913 751 -5632 11923952 32
2084 751 -5632 11923952 32
11894 751 -5632 11923952 32
758 751 -5632 11923952 32
7528 751 -5632 11923952 32
2886 751 -5632 11923952 32
11900 751 -5632 11923952 32
2895 751 -5632 11923952 32
862 751 -5632 11923952 32
864 751 -5632 11923952 32
2900 751 -5632 11923952 32
2901 751 -5632 11923952 32
2906 751 -5632 11923952 32
7353 751 -5632 11923952 32
3971 751 -5632 11923952 32
867 751 -5632 11923952 32
2111 751 -5632 11923952 32
2112 751 -5632 11923952 32
11932 751 -5632 11923952 32
6230 751 -5632 11923952 32
848 751 -5632 11923952 32
6005 751 -5632 11923952 32
828 751 -5632 11923952 32
amerkoleci commented 6 years ago

SharpDX creates new instance of KeyboardInputEventArgs which causes garbage.

https://github.com/sharpdx/SharpDX/blob/8dc1f64a9424c6b0dc8b9009f70e144ded03f1d7/Source/SharpDX.RawInput/Device.cs, inside HandleMessage method.

Xanadar89 commented 5 years ago

Yep, I have the same problem on 4.2.0 and 4.1.0, on the 4.0.1 everything works perfectly fine

S0nix12 commented 5 years ago

Got the same problem seems to work with 4.1.0-ci217 but as of 4.1.0 it only returns weird values.

Kharzette commented 5 years ago

It looks like the data coming back from user32 is ok, but the RawInput struct is ordered incorrectly: makecode Header size is 24 so the bottom watch value should be where MakeCode lives. However it is 17 when I thought it would be 18 (I think I hit w, but maybe I hit q by accident?).

There's alot of strange generated code for this stuff that I can't fathom yet so I need to do some more digging.

bpxhmemcpy commented 5 years ago

Generated code for RawInput.Data union handling changed from "Explicit+FieldOffset" (v4.0.1) to "Native sub struct marshalling", therefore "HandleMessage" should use "MarshalFrom":

var rawInput = default(RawInput);
rawInput.__MarshalFrom(ref *(RawInput.__Native*)rawInputDataPtr);

switch (rawInput.Header.Type)
{
    case DeviceType.HumanInputDevice:
        RawInput?.Invoke(null, new HidInputEventArgs(ref rawInput, hwnd));
        break;

    case DeviceType.Keyboard:
        KeyboardInput?.Invoke(null, new KeyboardInputEventArgs(ref rawInput, hwnd));
        break;

    case DeviceType.Mouse:
        MouseInput?.Invoke(null, new MouseInputEventArgs(ref rawInput, hwnd));
        break;
}

or revert back to "Explicit+FieldOffset"

xoofx commented 5 years ago

@jkoritzinsky Could you have a look at this codegen issue?

myblindy commented 5 years ago

This is still an issue, I'm forced to revert to 4.0.1 for now