I am facing the issue while getting the data from Device using USB communication (HID) in .Net Core or .Net7.0. Actually, I have a legacy code in C# .Net Framework4.5. I wanted to convert the whole project into .Net7.0 (CrossPlatform). I have created the seprate .Net core project and migrate all the classes and implementation into .Net7.0 Project. No change in code except project type have been change from .Net Framework 4.5 to .Net 7.0. All the project havs compiled fine. Later on I will execute the app in Linux Plateform.
When I execute the code in legacy (.Net Framework4.5) the SetupDiGetClassDevs() return correct IntPtr value ex: 0x011ec428 but when I execute the another project .Net7.0 (.Net Core Cross platform) then SetupDiGetClassDevs() return Long value 0x0000019b739b51c0.
deviceInfoSet = SetupDiGetClassDevs(ref myGuid, IntPtr.Zero, IntPtr.Zero, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
Because of return value long "0x000002c2960b3280 value insted of IntPtr 0x00f25f80" from like deviceInfoSet my application give exception as below line
IntPtr pDevicePathName = new IntPtr(detailDataBuffer.ToInt32() + 4);
Exception : Arithmetic operation resulted in an overflow.
using System;
using System.Runtime.InteropServices;
namespace CrossPlateformDevices
{
sealed internal partial class DeviceManagement
{
internal Boolean FindDeviceFromGuid(System.Guid myGuid, ref String[] devicePathName)
{
Int32 bufferSize = 0;
IntPtr detailDataBuffer = IntPtr.Zero;
Boolean deviceFound;
IntPtr deviceInfoSet = new System.IntPtr();
Boolean lastDevice = false;
Int32 memberIndex = 0;
SP_DEVICE_INTERFACE_DATA MyDeviceInterfaceData = new SP_DEVICE_INTERFACE_DATA();
Boolean success;
try
{
**deviceInfoSet = SetupDiGetClassDevs(ref myGuid, IntPtr.Zero, IntPtr.Zero, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);**
deviceFound = false;
memberIndex = 0;
Console.WriteLine("****** Inside DeviceManagement.FindDeviceFromGuid.SetupDiGetClassDevs ******");
/// The cbSize element of the MyDeviceInterfaceData structure must be set to
/// the structure's size in bytes.
/// The size is 28 bytes for 32-bit code and 32 bits for 64-bit code.
MyDeviceInterfaceData.cbSize = Marshal.SizeOf(MyDeviceInterfaceData);
do
{
success = SetupDiEnumDeviceInterfaces
(deviceInfoSet,
IntPtr.Zero,
ref myGuid,
memberIndex,
ref MyDeviceInterfaceData);
/// Find out if a device information set was retrieved.
Console.WriteLine("****** " + memberIndex + " Inside DeviceManagement.FindDeviceFromGuid.SetupDiEnumDeviceInterfaces success ******" + success);
if (!success)
{
lastDevice = true;
}
else
{
success = SetupDiGetDeviceInterfaceDetail
(deviceInfoSet,
ref MyDeviceInterfaceData,
IntPtr.Zero,
0,
ref bufferSize,
IntPtr.Zero);
/// Allocate memory for the SP_DEVICE_INTERFACE_DETAIL_DATA structure using the returned buffer size.
Console.WriteLine("****** Inside DeviceManagement.FindDeviceFromGuid.SetupDiGetDeviceInterfaceDetail success ******" + success);
detailDataBuffer = Marshal.AllocHGlobal(bufferSize);
/// Store cbSize in the first bytes of the array. The number of bytes varies with 32- and 64-bit systems.
Marshal.WriteInt32(detailDataBuffer, (IntPtr.Size == 4) ? (4 + Marshal.SystemDefaultCharSize) : 8);
/// Call SetupDiGetDeviceInterfaceDetail again.
/// This time, pass a pointer to DetailDataBuffer
/// and the returned required buffer size.
success = SetupDiGetDeviceInterfaceDetail
(deviceInfoSet,
ref MyDeviceInterfaceData,
detailDataBuffer,
bufferSize,
ref bufferSize,
IntPtr.Zero);
/// Skip over cbsize (4 bytes) to get the address of the devicePathName.
Console.WriteLine("****** Inside DeviceManagement.FindDeviceFromGuid.SetupDiGetDeviceInterfaceDetail success ******" + success);
IntPtr pDevicePathName = new IntPtr(detailDataBuffer.ToInt32() + 4);
/// Get the String containing the devicePathName.
devicePathName[memberIndex] = Marshal.PtrToStringAuto(pDevicePathName);
if (detailDataBuffer != IntPtr.Zero)
{
/// Free the memory allocated previously by AllocHGlobal.
Marshal.FreeHGlobal(detailDataBuffer);
}
deviceFound = true;
}
memberIndex = memberIndex + 1;
}
while (!((lastDevice == true)));
return deviceFound;
}
catch (Exception ex)
{
Console.WriteLine("****** Inside DeviceManagement.FindDeviceFromGuid ****** ex: " + ex);
return false;
}
finally
{
/// ***
/// API function
/// summary
/// Frees the memory reserved for the DeviceInfoSet returned by SetupDiGetClassDevs.
/// parameters
/// DeviceInfoSet returned by SetupDiGetClassDevs.
/// returns
/// True on success.
/// ***
if (deviceInfoSet != IntPtr.Zero)
{
SetupDiDestroyDeviceInfoList(deviceInfoSet);
}
}
}
}
}
API declarations :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace CrossPlateformDevices
{
internal sealed partial class DeviceManagement
{
///<summary >
/// API declarations relating to device management (SetupDixxx and
/// RegisterDeviceNotification functions).
/// </summary>
/// from dbt.h
internal const Int32 DBT_DEVICEARRIVAL = 0X8000;
internal const Int32 DBT_DEVNODES_CHANGED = 0x0007;
internal const Int32 DBT_DEVICEREMOVECOMPLETE = 0X8004;
internal const Int32 DBT_DEVTYP_DEVICEINTERFACE = 5;
internal const Int32 DBT_DEVTYP_HANDLE = 6;
internal const Int32 DEVICE_NOTIFY_ALL_INTERFACE_CLASSES = 4;
internal const Int32 DEVICE_NOTIFY_SERVICE_HANDLE = 1;
internal const Int32 DEVICE_NOTIFY_WINDOW_HANDLE = 0;
internal const Int32 WM_DEVICECHANGE = 0X219;
/// from setupapi.h
internal const Int32 DIGCF_PRESENT = 2;
internal const Int32 DIGCF_DEVICEINTERFACE = 0X10;
/// Two declarations for the DEV_BROADCAST_DEVICEINTERFACE structure.
/// Use this one in the call to RegisterDeviceNotification() and
/// in checking dbch_devicetype in a DEV_BROADCAST_HDR structure:
[StructLayout(LayoutKind.Sequential)]
internal class DEV_BROADCAST_DEVICEINTERFACE
{
internal Int32 dbcc_size;
internal Int32 dbcc_devicetype;
internal Int32 dbcc_reserved;
internal Guid dbcc_classguid;
internal Int16 dbcc_name;
}
/// Use this to read the dbcc_name String and classguid:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
internal class DEV_BROADCAST_DEVICEINTERFACE_1
{
internal Int32 dbcc_size;
internal Int32 dbcc_devicetype;
internal Int32 dbcc_reserved;
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.U1, SizeConst = 16)]
internal Byte[] dbcc_classguid;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 255)]
internal Char[] dbcc_name;
}
[StructLayout(LayoutKind.Sequential)]
internal class DEV_BROADCAST_HDR
{
internal Int32 dbch_size;
internal Int32 dbch_devicetype;
internal Int32 dbch_reserved;
}
internal struct SP_DEVICE_INTERFACE_DATA
{
internal Int32 cbSize;
internal System.Guid InterfaceClassGuid;
internal Int32 Flags;
internal IntPtr Reserved;
}
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
internal static extern IntPtr RegisterDeviceNotification(IntPtr hRecipient, IntPtr NotificationFilter, Int32 Flags);
[DllImport("setupapi.dll", SetLastError = true)]
internal static extern Int32 SetupDiCreateDeviceInfoList(ref System.Guid ClassGuid, Int32 hwndParent);
[DllImport("setupapi.dll", SetLastError = true)]
internal static extern Int32 SetupDiDestroyDeviceInfoList(IntPtr DeviceInfoSet);
[DllImport("setupapi.dll", SetLastError = true)]
internal static extern Boolean SetupDiEnumDeviceInterfaces(IntPtr DeviceInfoSet, IntPtr DeviceInfoData, ref System.Guid InterfaceClassGuid, Int32 MemberIndex, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData);
[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
internal static extern IntPtr SetupDiGetClassDevs(ref System.Guid ClassGuid, IntPtr Enumerator, IntPtr hwndParent, Int32 Flags);
[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
internal static extern Boolean SetupDiGetDeviceInterfaceDetail(IntPtr DeviceInfoSet, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData, IntPtr DeviceInterfaceDetailData, Int32 DeviceInterfaceDetailDataSize, ref Int32 RequiredSize, IntPtr DeviceInfoData);
[DllImport("user32.dll", SetLastError = true)]
internal static extern Boolean UnregisterDeviceNotification(IntPtr Handle);
}
}
Correct result when code compile in .NetFramework4.5 code
strong text

InCorrect result when code compile in .Net7.0 or.Net Core Value


