我正在开发一个 USB 设备作为标准 HID 键盘,并在报告描述符中添加了一个 8 字节的功能报告;我正在编写一个主机应用程序来配置设备。我正在尝试调整精彩的HidLibrary以利用 hid.dll 中的 HidD_GetFeature() 函数。
在我开始发布 c# 代码之前,我会说我已经使用 SimpleHidWrite 实用程序以及 Get 和 Set Feature 命令成功地测试了我的固件,所以我相当有信心这不是问题所在。
包装在 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);
其中(使用测试 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 执行此操作。也就是说,我没有排除任何可能性,欢迎任何想法。
如果我需要提供更多信息,请告诉我。