Отправка IOCTL на 64-битную машину в C#
Я посылаю 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-битных машинах, я получаю действительный путь к устройству. Что-то не так в процессе сборки?
1 ответ
Я получил решение этой проблемы. Проблема заключалась в наборе значений deviceInterfaceDetailData.cbSize. Согласно http://www.pinvoke.net/default.aspx/setupapi.setupdigetdeviceinterfacedetail я изменил значение cbSize на 8 для 64-битных машин, и тогда оно работает!