1

レポート記述子に8バイトの機能レポートが追加された標準のHIDキーボードとしてUSBデバイスを開発しています。デバイスを構成するためのホストアプリを作成しています。hid.dllのHidD_GetFeature()関数を利用するように素晴らしいHidLibraryを適応させようとしています。

c#コードの投稿を開始する前に、GetとSet Featureコマンドの両方でSimpleHidWriteユーティリティを使用してファームウェアを正常にテストしたと言うので、それは問題ではないとかなり確信しています。

HidLibrary APIでラップされたHidD_SetFeature()関数はうまく機能します。デバイスに8バイトを書き込むことができ、SimpleHidWriteツールを使用してそれらが正しく保存されていることを確認しました。ただし、HidD_GetFeature()を使用してこれらのバイトをプルバックすることはできず、その理由については困惑しています。

これが私が適切な詳細であると信じているものです。

まず、値を使用してライブラリに組み込まれたCreateFile呼び出しを実行します。

[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    internal static IntPtr CreateFile(
        string lpFileName,
        uint dwDesiredAccess,
        int dwShareMode,
        ref HidLibrary.NativeMethods.SECURITY_ATTRIBUTES lpSecurityAttributes,
        int dwCreationDisposition,
        int dwFlagsAndAttributes,
        int hTemplateFile);

ここで(test vid / pidを使用):

lpFileName = "\\?\hid#vid_03eb&pid_2042#7&1fef463f&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}"
dwDesiredAccess = 0
dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE (0x01 | 0x02)
lpSecurityAttributes = { bInheritHandle = true, lpSecurityDescriptor = 0, nLength = 12 }
dwCreationDisposition = OPEN_EXISTING (3)
dwFlagsAndAttributes = 0
hTemplateFile = 0

インポート定義:

[DllImport("hid.dll", SetLastError = true)]
    static internal extern bool HidD_GetFeature(IntPtr hidDeviceObject, ref byte[] lpReportBuffer, int reportBufferLength);

そして最後に、私が作成しているAPIメソッドは、現在HidD_GetFeature()呼び出しでエラー23(ERROR_CRC)で失敗しています。

    public bool ReadFeatureData(byte reportId, out byte[] data)
    {
        if (_deviceCapabilities.FeatureReportByteLength <= 0)
        {
            data = new byte[0];
            return false;
        }
        // FeatureReportByteLength returns 9 (byte 0 is the report id and 8 bytes for the actual report length)
        data = new byte[_deviceCapabilities.FeatureReportByteLength];

        //yields a 9-byte array
        var buffer = this.CreateFeatureInputBuffer(); 
        buffer[0] = reportId;

        IntPtr hidHandle = IntPtr.Zero;
        bool success = false;
        try
        {
            // Performs the CreateFile call above resulting in an IntPtr handle
            hidHandle = OpenDeviceIO(_devicePath, NativeMethods.ACCESS_NONE);

            success = NativeMethods.HidD_GetFeature(hidHandle, ref buffer, buffer.Length);
            // at this point, success is false, and buffer has gone from 9 bytes to 1

            if(success)
            {
                Array.Copy(buffer, 0, data, 0, Math.Min(data.Length, _deviceCapabilities.FeatureReportByteLength));
            }
            else
            {
                //Yes, i know casting to a byte isn't good here; it's dirty but helping me debug for now
                data[0] = (byte)Marshal.GetLastWin32Error(); //returns 23 (verified, actual) - ERROR_CRC
            }

        }
        catch (Exception exception)
        {
            throw new Exception(string.Format("Error accessing HID device '{0}'.", _devicePath), exception);
        }
        finally
        {
            if (hidHandle != IntPtr.Zero)
                CloseDeviceIO(hidHandle);
        }

        return success;
    }

キーボードやマウスなどのシステムデバイスの操作に問題があることを読みましたが、ここで再生される場合とされない場合がありますが、私が試した方法でデバイスを操作できることはわかっています。 SimpleHidWriteを使用してこれを行います。とはいえ、私は何も除外しておらず、どんなアイデアも歓迎します。

さらに情報を提供する必要がある場合はお知らせください。

4

2 に答える 2

1

はい、あなたの宣言が問題です。

使用する:

    [DllImport("hid.dll", SetLastError = true)]
    protected static extern bool HidD_GetFeature(   IntPtr hDevInfo,
                                                    Byte[] lpReportBuffer, 
                                                    Int32 ReportBufferLength);

いいえ: ref または out

于 2013-06-18T07:42:17.280 に答える
1

この宣言が問題かもしれないと思います。

[DllImport("hid.dll", SetLastError = true)]
    static internal extern bool HidD_GetFeature(IntPtr hidDeviceObject, ref byte[] lpReportBuffer, int reportBufferLength);

lpReportBuffer refパラメータをoutに変更するか、完全に省略してみてください。

于 2013-02-02T07:40:19.700 に答える