在 C# 中将 IOCTL 发送到 64 位计算机

本文关键字:计算机 中将 IOCTL | 更新日期: 2023-09-27 18:31:00

我正在将IOCTL发送到我的键盘过滤器驱动程序,代码如下:

Guid GUID_DEVINTERFACE_KBFILTER = new Guid(0x3fb7299d, 0x6847, 0x4490, 0xb0, 0xc9, 0x99, 0xe0, 0x98, 0x6a, 0xb8, 0x86);
IntPtr handle = SetupDiGetClassDevs(ref GUID_DEVINTERFACE_KBFILTER, IntPtr.Zero, IntPtr.Zero, (int)(DiGetClassFlags.DIGCF_PRESENT | DiGetClassFlags.DIGCF_DEVICEINTERFACE));
if (handle != INVALID_HANDLE_VALUE)
{
    bool Success = true;
    int i = 0;
    while (Success)
    {
        SP_DEVICE_INTERFACE_DATA deviceInterfaceData = new SP_DEVICE_INTERFACE_DATA();
        deviceInterfaceData.cbSize = Marshal.SizeOf(deviceInterfaceData);
        // start the enumeration
        Success = SetupDiEnumDeviceInterfaces(handle, IntPtr.Zero, ref GUID_DEVINTERFACE_KBFILTER, (uint)i, ref deviceInterfaceData);
        if (Success)
        {
            // build a DevInfo Data structure
            SP_DEVINFO_DATA devInfoData = new SP_DEVINFO_DATA();
            devInfoData.cbSize = (uint)Marshal.SizeOf(devInfoData);
            // build a Device Interface Detail Data structure
            deviceInterfaceDetailData = new SP_DEVICE_INTERFACE_DETAIL_DATA();
            deviceInterfaceDetailData.cbSize = 4 + Marshal.SystemDefaultCharSize;
            // now we can get some more detailed information
            uint nRequiredSize = 0;
            int nBytes = BUFFER_SIZE;
            if (SetupDiGetDeviceInterfaceDetail(handle, ref deviceInterfaceData, ref deviceInterfaceDetailData, (uint)nBytes, out nRequiredSize, ref devInfoData))
            {
                uint ptrPrevious;
                CM_Get_Parent(out ptrPrevious, devInfoData.DevInst, 0);
                // Now we get the InstanceID of the USB level device
                IntPtr ptrInstanceBuf = Marshal.AllocHGlobal(nBytes);
                CM_Get_Device_ID(ptrPrevious, ptrInstanceBuf, nBytes, 0);
                string InstanceID = Marshal.PtrToStringAuto(ptrInstanceBuf);
                Marshal.FreeHGlobal(ptrInstanceBuf);
            }
        }
        i++;
    }
}
SetupDiDestroyDeviceInfoList(handle);
if (string.IsNullOrEmpty(deviceInterfaceDetailData.DevicePath))
{
    return false;
}

之后的代码工作正常。问题就在这里,这适用于 32 位机器,但在 64 位机器上不起作用。在 64 位机器中,deviceInterfaceDetailData.DevicePath 为空,而在 32 位机器中,我得到一个有效的设备路径。构建过程中有问题吗?

在 C# 中将 IOCTL 发送到 64 位计算机

我得到了这个问题的解决方案。问题是设置了 deviceInterfaceDetailData.cbSize 值。根据 http://www.pinvoke.net/default.aspx/setupapi.setupdigetdeviceinterfacedetail 我将 8 位机器的 cbSize 值更改为 64,然后它可以工作!