EDN Admin
Well-known member
Hello Experts, I have the following codes for getting devices and it works on both XP and Vista (32bit).<br/>
<br/>
But when I run it on Windows 7 (64bit) & Server 2008 (64bit), I got this error "The supplied user buffer is not valid for the requested operation" ..<br/>
<br/>
I am quite new to API. I have googled and MSDNed about 2 or 3 days already but no luck.<br/>
<br/>
Is it something to do with IntPrt or datatypes in the Structs? Could you please point me out which one is causing the error on 64 bit.
Any help would be much appreciated. Thanks.
<div style="color:black; background-color:white
<pre><span style="color:blue public <span style="color:blue void GetDevices()
{
Native.SP_DEVICE_INTERFACE_DATA interfaceData = <span style="color:blue new Native.SP_DEVICE_INTERFACE_DATA();
interfaceData.cbSize = Marshal.SizeOf(interfaceData);
<span style="color:blue if (!Native.SetupDiEnumDeviceInterfaces(_deviceInfoSet, <span style="color:blue null, <span style="color:blue ref _classGuid, index, interfaceData))
{
<span style="color:blue int error = Marshal.GetLastWin32Error();
<span style="color:blue if (error != Native.ERROR_NO_MORE_ITEMS)
<span style="color:blue throw <span style="color:blue new Win32Exception(error); <span style="color:green //<--- *** Error here
<span style="color:blue break;
}
Native.SP_DEVINFO_DATA devData = <span style="color:blue new Native.SP_DEVINFO_DATA();
<span style="color:blue int size = 0;
<span style="color:blue if (!Native.SetupDiGetDeviceInterfaceDetail(_deviceInfoSet, interfaceData, IntPtr.Zero, 0, <span style="color:blue ref size, devData))
{
<span style="color:blue int error = Marshal.GetLastWin32Error();
<span style="color:blue if (error != Native.ERROR_INSUFFICIENT_BUFFER)
<span style="color:blue throw <span style="color:blue new Win32Exception(error);
}
IntPtr buffer = Marshal.AllocHGlobal(size);
Native.SP_DEVICE_INTERFACE_DETAIL_DATA detailData = <span style="color:blue new Native.SP_DEVICE_INTERFACE_DETAIL_DATA();
detailData.cbSize = Marshal.SizeOf(<span style="color:blue typeof(Native.SP_DEVICE_INTERFACE_DETAIL_DATA));
Marshal.StructureToPtr(detailData, buffer, <span style="color:blue false);
<span style="color:blue if (!Native.SetupDiGetDeviceInterfaceDetail(_deviceInfoSet, interfaceData, buffer, size, <span style="color:blue ref size, devData))
{
Marshal.FreeHGlobal(buffer);
<span style="color:blue throw <span style="color:blue new Win32Exception(Marshal.GetLastWin32Error());
}
IntPtr pDevicePath = (IntPtr)((<span style="color:blue int)buffer + Marshal.SizeOf(<span style="color:blue typeof(<span style="color:blue int)));
<span style="color:blue string devicePath = Marshal.PtrToStringAuto(pDevicePath);
Marshal.FreeHGlobal(buffer);
Native.STORAGE_DEVICE_NUMBER storageDeviceNumber = GetDeviceNumber(devicePath);
Device device = CreateDevice(<span style="color:blue this, devData, devicePath, storageDeviceNumber.DeviceNumber);
}
<span style="color:blue public <span style="color:blue class Native
{
[StructLayout(LayoutKind.Sequential)]
<span style="color:blue internal <span style="color:blue class SP_DEVINFO_DATA
{
<span style="color:blue internal <span style="color:blue int cbSize = Marshal.SizeOf(<span style="color:blue typeof(SP_DEVINFO_DATA));
<span style="color:blue internal Guid classGuid = Guid.Empty;
<span style="color:blue internal <span style="color:blue int devInst = 0;
<span style="color:blue internal <span style="color:blue int reserved = 0;
}
[StructLayout(LayoutKind.Sequential, Pack = 2)]
<span style="color:blue internal <span style="color:blue struct SP_DEVICE_INTERFACE_DETAIL_DATA
{
<span style="color:blue internal <span style="color:blue int cbSize;
<span style="color:blue internal <span style="color:blue short devicePath;
}
[StructLayout(LayoutKind.Sequential)]
<span style="color:blue internal <span style="color:blue class SP_DEVICE_INTERFACE_DATA
{
<span style="color:blue internal <span style="color:blue int cbSize = Marshal.SizeOf(<span style="color:blue typeof(SP_DEVICE_INTERFACE_DATA));
<span style="color:blue internal Guid interfaceClassGuid = Guid.Empty;
<span style="color:blue internal <span style="color:blue int flags = 0;
<span style="color:blue internal <span style="color:blue int reserved = 0;
}
[DllImport(<span style="color:#a31515 "setupapi.dll")]
<span style="color:blue internal <span style="color:blue static <span style="color:blue extern IntPtr SetupDiGetClassDevs(
<span style="color:blue ref Guid classGuid,
<span style="color:blue int enumerator,
IntPtr hwndParent,
<span style="color:blue int flags);
[DllImport(<span style="color:#a31515 "setupapi.dll", SetLastError = <span style="color:blue true, CharSet = CharSet.Auto)]
<span style="color:blue internal <span style="color:blue static <span style="color:blue extern <span style="color:blue bool SetupDiEnumDeviceInterfaces(
IntPtr deviceInfoSet,
SP_DEVINFO_DATA deviceInfoData,
<span style="color:blue ref Guid interfaceClassGuid,
<span style="color:blue int memberIndex,
SP_DEVICE_INTERFACE_DATA deviceInterfaceData);
[DllImport(<span style="color:#a31515 "setupapi.dll")]
<span style="color:blue internal <span style="color:blue static <span style="color:blue extern <span style="color:blue bool SetupDiOpenDeviceInfo(
IntPtr deviceInfoSet,
<span style="color:blue string deviceInstanceId,
IntPtr hwndParent,
<span style="color:blue int openFlags,
SP_DEVINFO_DATA deviceInfoData
);
[DllImport(<span style="color:#a31515 "setupapi.dll", SetLastError = <span style="color:blue true, CharSet = CharSet.Auto)]
<span style="color:blue internal <span style="color:blue static <span style="color:blue extern <span style="color:blue bool SetupDiGetDeviceInterfaceDetail(
IntPtr deviceInfoSet,
SP_DEVICE_INTERFACE_DATA deviceInterfaceData,
IntPtr deviceInterfaceDetailData,
<span style="color:blue int deviceInterfaceDetailDataSize,
<span style="color:blue ref <span style="color:blue int requiredSize,
SP_DEVINFO_DATA deviceInfoData);
}
[/code]
<br/>
View the full article
<br/>
But when I run it on Windows 7 (64bit) & Server 2008 (64bit), I got this error "The supplied user buffer is not valid for the requested operation" ..<br/>
<br/>
I am quite new to API. I have googled and MSDNed about 2 or 3 days already but no luck.<br/>
<br/>
Is it something to do with IntPrt or datatypes in the Structs? Could you please point me out which one is causing the error on 64 bit.
Any help would be much appreciated. Thanks.
<div style="color:black; background-color:white
<pre><span style="color:blue public <span style="color:blue void GetDevices()
{
Native.SP_DEVICE_INTERFACE_DATA interfaceData = <span style="color:blue new Native.SP_DEVICE_INTERFACE_DATA();
interfaceData.cbSize = Marshal.SizeOf(interfaceData);
<span style="color:blue if (!Native.SetupDiEnumDeviceInterfaces(_deviceInfoSet, <span style="color:blue null, <span style="color:blue ref _classGuid, index, interfaceData))
{
<span style="color:blue int error = Marshal.GetLastWin32Error();
<span style="color:blue if (error != Native.ERROR_NO_MORE_ITEMS)
<span style="color:blue throw <span style="color:blue new Win32Exception(error); <span style="color:green //<--- *** Error here
<span style="color:blue break;
}
Native.SP_DEVINFO_DATA devData = <span style="color:blue new Native.SP_DEVINFO_DATA();
<span style="color:blue int size = 0;
<span style="color:blue if (!Native.SetupDiGetDeviceInterfaceDetail(_deviceInfoSet, interfaceData, IntPtr.Zero, 0, <span style="color:blue ref size, devData))
{
<span style="color:blue int error = Marshal.GetLastWin32Error();
<span style="color:blue if (error != Native.ERROR_INSUFFICIENT_BUFFER)
<span style="color:blue throw <span style="color:blue new Win32Exception(error);
}
IntPtr buffer = Marshal.AllocHGlobal(size);
Native.SP_DEVICE_INTERFACE_DETAIL_DATA detailData = <span style="color:blue new Native.SP_DEVICE_INTERFACE_DETAIL_DATA();
detailData.cbSize = Marshal.SizeOf(<span style="color:blue typeof(Native.SP_DEVICE_INTERFACE_DETAIL_DATA));
Marshal.StructureToPtr(detailData, buffer, <span style="color:blue false);
<span style="color:blue if (!Native.SetupDiGetDeviceInterfaceDetail(_deviceInfoSet, interfaceData, buffer, size, <span style="color:blue ref size, devData))
{
Marshal.FreeHGlobal(buffer);
<span style="color:blue throw <span style="color:blue new Win32Exception(Marshal.GetLastWin32Error());
}
IntPtr pDevicePath = (IntPtr)((<span style="color:blue int)buffer + Marshal.SizeOf(<span style="color:blue typeof(<span style="color:blue int)));
<span style="color:blue string devicePath = Marshal.PtrToStringAuto(pDevicePath);
Marshal.FreeHGlobal(buffer);
Native.STORAGE_DEVICE_NUMBER storageDeviceNumber = GetDeviceNumber(devicePath);
Device device = CreateDevice(<span style="color:blue this, devData, devicePath, storageDeviceNumber.DeviceNumber);
}
<span style="color:blue public <span style="color:blue class Native
{
[StructLayout(LayoutKind.Sequential)]
<span style="color:blue internal <span style="color:blue class SP_DEVINFO_DATA
{
<span style="color:blue internal <span style="color:blue int cbSize = Marshal.SizeOf(<span style="color:blue typeof(SP_DEVINFO_DATA));
<span style="color:blue internal Guid classGuid = Guid.Empty;
<span style="color:blue internal <span style="color:blue int devInst = 0;
<span style="color:blue internal <span style="color:blue int reserved = 0;
}
[StructLayout(LayoutKind.Sequential, Pack = 2)]
<span style="color:blue internal <span style="color:blue struct SP_DEVICE_INTERFACE_DETAIL_DATA
{
<span style="color:blue internal <span style="color:blue int cbSize;
<span style="color:blue internal <span style="color:blue short devicePath;
}
[StructLayout(LayoutKind.Sequential)]
<span style="color:blue internal <span style="color:blue class SP_DEVICE_INTERFACE_DATA
{
<span style="color:blue internal <span style="color:blue int cbSize = Marshal.SizeOf(<span style="color:blue typeof(SP_DEVICE_INTERFACE_DATA));
<span style="color:blue internal Guid interfaceClassGuid = Guid.Empty;
<span style="color:blue internal <span style="color:blue int flags = 0;
<span style="color:blue internal <span style="color:blue int reserved = 0;
}
[DllImport(<span style="color:#a31515 "setupapi.dll")]
<span style="color:blue internal <span style="color:blue static <span style="color:blue extern IntPtr SetupDiGetClassDevs(
<span style="color:blue ref Guid classGuid,
<span style="color:blue int enumerator,
IntPtr hwndParent,
<span style="color:blue int flags);
[DllImport(<span style="color:#a31515 "setupapi.dll", SetLastError = <span style="color:blue true, CharSet = CharSet.Auto)]
<span style="color:blue internal <span style="color:blue static <span style="color:blue extern <span style="color:blue bool SetupDiEnumDeviceInterfaces(
IntPtr deviceInfoSet,
SP_DEVINFO_DATA deviceInfoData,
<span style="color:blue ref Guid interfaceClassGuid,
<span style="color:blue int memberIndex,
SP_DEVICE_INTERFACE_DATA deviceInterfaceData);
[DllImport(<span style="color:#a31515 "setupapi.dll")]
<span style="color:blue internal <span style="color:blue static <span style="color:blue extern <span style="color:blue bool SetupDiOpenDeviceInfo(
IntPtr deviceInfoSet,
<span style="color:blue string deviceInstanceId,
IntPtr hwndParent,
<span style="color:blue int openFlags,
SP_DEVINFO_DATA deviceInfoData
);
[DllImport(<span style="color:#a31515 "setupapi.dll", SetLastError = <span style="color:blue true, CharSet = CharSet.Auto)]
<span style="color:blue internal <span style="color:blue static <span style="color:blue extern <span style="color:blue bool SetupDiGetDeviceInterfaceDetail(
IntPtr deviceInfoSet,
SP_DEVICE_INTERFACE_DATA deviceInterfaceData,
IntPtr deviceInterfaceDetailData,
<span style="color:blue int deviceInterfaceDetailDataSize,
<span style="color:blue ref <span style="color:blue int requiredSize,
SP_DEVINFO_DATA deviceInfoData);
}
[/code]
<br/>
View the full article