Problem with SetupDiEnumDeviceInterfaces()

  • Thread starter Thread starter Jason
  • Start date Start date
J

Jason

Hello,

I'm trying to call this method from C# but it's returning false.
Marshal.GetLastWin32Error() returns 8 which means "Not enough storage is
available to process this command". Can someone elaborate what this means
please? Is this a marsahling parameter problem?

I've declared the method as
[DllImport("setupapi.dll")]
public static extern bool SetupDiEnumDeviceInterfaces(
IntPtr DeviceInfoSet, SP_DEVINFO_DATA DeviceInfoData, ref Guid
InterfaceClassGuid,
int MemberIndex, SP_DEVICE_INTERFACE_DATA DeviceInterfaceData );


I set up the return data structure by
SP_DEVICE_INTERFACE_DATA devdata = new SP_DEVICE_INTERFACE_DATA();
devdata.SetSize();

I've hardcoded the size since I can't used sizeof().

Then I call
if( !SetupDiEnumDeviceInterfaces( info, null, ref guid, instance,
devdata ) )
....

Both SP_DEVINFO_DATA and SP_DEVICE_INTERFACE_DATA have been declared as
classes so I can pass null if needed.
[StructLayout(LayoutKind.Sequential)]
public class SP_DEVICE_INTERFACE_DATA
{
internal UInt32 cbSize;
internal Guid InterfaceClassGuid;
internal UInt32 Flags;
internal IntPtr Reserved;

public void SetSize()
{
cbSize = 32;
InterfaceClassGuid = Guid.NewGuid();
}
}

I've tried the same thing with C++ and it works. I don't really want to
create a managed C++ dll to use this function so I'd greatly appreciate any
suggestions to where I'm going wrong.

Regards,

Jason Browne.
 
Jason,
I've hardcoded the size since I can't used sizeof().

You can use Marshal.SizeOf().

[StructLayout(LayoutKind.Sequential)]
public class SP_DEVICE_INTERFACE_DATA
{
internal UInt32 cbSize;
internal Guid InterfaceClassGuid;
internal UInt32 Flags;
internal IntPtr Reserved;

public void SetSize()
{
cbSize = 32;
InterfaceClassGuid = Guid.NewGuid();
}
}

Unless you're running on a 64-bit OS, the total size should be 28
bytes, not 32 (since a Guid32 is 16 bytes, UInt32 is 4 and IntPtr is 4
or 8 depending of the platform).



Mattias
 
Mattias Sjögren said:
Jason,


You can use Marshal.SizeOf().

Cheers, I missed that. Very useful.
[StructLayout(LayoutKind.Sequential)]
public class SP_DEVICE_INTERFACE_DATA
{
internal UInt32 cbSize;
internal Guid InterfaceClassGuid;
internal UInt32 Flags;
internal IntPtr Reserved;

public void SetSize()
{
cbSize = 32;
InterfaceClassGuid = Guid.NewGuid();
}
}

Unless you're running on a 64-bit OS, the total size should be 28
bytes, not 32 (since a Guid32 is 16 bytes, UInt32 is 4 and IntPtr is 4
or 8 depending of the platform).

Oops, yes it should be 28 but I got desperate when I was getting that "Not
enough storage is available to process this command" error message so I
started experimenting! That wasn't supposed to be in the post :-)

As there was no comment on how the method was declared, I've been back over
the code and discovered my error. I declared DIGCF_DEVICEINTERFACE to be 10
instead of 0x10! That's solved that error.

Thanks Mattias for taking the time to look at my problem and pointing out
Marshal.SizeOf() to me.

Jason Browne.
 
Back
Top