From: santapanda on
Hello,

I have a C# application using P/Invoke on several SetupDIxxx methods. I am
attempting to pass an SP_DEVINFO_DATA object to the SetupDiEnumDeviceInfo()
method. I have setup the SP_DEVINFO_DATA struct as follows:

[StructLayout(LayoutKind.Sequential)]
public struct SP_DEVINFO_DATA
{
public int cbSize;
public System.Guid ClassGuid;
public int DevInst;
public int Reserved;
}

Based on articles in the MSDN Library, and an example i found on
pinvoke.net, I know I'm supposed to set my object's cbsize to
sizeof(SP_DEVINFO_DATA).

Here is my code:
=====================
[...]
SP_DEVINFO_DATA devInfoData = new SP_DEVINFO_DATA();
IntPtr deviceInfoSet = SetupDiGetClassDevs (ref guids[0], null, 0,
DIGCF_PRESENT | DIGCF_ALLCLASSES);

if (deviceInfoSet != INVALID_HANDLE_VALUE)
{
int devIndex = 0;
devInfoData.cbSize = Marshal.SizeOf(devInfoData);
bool success = SetupDiEnumDeviceInfo(deviceInfoSet, devIndex,
out devInfoData);
[...]
}
=====================

When I run, I get the error: "The supplied user buffer is not valid for the
requested operation." The documentation from MSDN states this error is
generated when "the cbSize member is not set correctly for an output
parameter".

This is my first time using P/Invoke and working with Windows APIs. So
please help me understand how to pass the correct cbSize value. When I ran
debugger, the cbSize is 0 when the object is going in, but when it comes out
the cbSize is 28. I tried setting cbSize prior to calling the
SetupDiEnumDeviceInfo method to various values like 28 and 1024, but I still
got the same error.

Thanks!
From: holycow on
Your definition of SP_DEVINFO_DATA differs from one given by pinvoke.net:
http://pinvoke.net/default.aspx/Structures/SP_DEVINFO_DATA.html

If your machine is 64 bit, this will matter.



"santapanda" <santapanda(a)discussions.microsoft.com> wrote in message
news:F889AC4D-6A3E-410C-9923-EF714631BA00(a)microsoft.com...
> Hello,
>
> I have a C# application using P/Invoke on several SetupDIxxx methods. I am
> attempting to pass an SP_DEVINFO_DATA object to the
> SetupDiEnumDeviceInfo()
> method. I have setup the SP_DEVINFO_DATA struct as follows:
>
> [StructLayout(LayoutKind.Sequential)]
> public struct SP_DEVINFO_DATA
> {
> public int cbSize;
> public System.Guid ClassGuid;
> public int DevInst;
> public int Reserved;
> }
>
> Based on articles in the MSDN Library, and an example i found on
> pinvoke.net, I know I'm supposed to set my object's cbsize to
> sizeof(SP_DEVINFO_DATA).
>
> Here is my code:
> =====================
> [...]
> SP_DEVINFO_DATA devInfoData = new SP_DEVINFO_DATA();
> IntPtr deviceInfoSet = SetupDiGetClassDevs (ref guids[0], null, 0,
> DIGCF_PRESENT | DIGCF_ALLCLASSES);
>
> if (deviceInfoSet != INVALID_HANDLE_VALUE)
> {
> int devIndex = 0;
> devInfoData.cbSize = Marshal.SizeOf(devInfoData);
> bool success = SetupDiEnumDeviceInfo(deviceInfoSet, devIndex,
> out devInfoData);
> [...]
> }
> =====================
>
> When I run, I get the error: "The supplied user buffer is not valid for
> the
> requested operation." The documentation from MSDN states this error is
> generated when "the cbSize member is not set correctly for an output
> parameter".
>
> This is my first time using P/Invoke and working with Windows APIs. So
> please help me understand how to pass the correct cbSize value. When I
> ran
> debugger, the cbSize is 0 when the object is going in, but when it comes
> out
> the cbSize is 28. I tried setting cbSize prior to calling the
> SetupDiEnumDeviceInfo method to various values like 28 and 1024, but I
> still
> got the same error.
>
> Thanks!

From: santapanda on
Thank you,

I changed the structure to the definition provided in pinvoke.net. After
making that change the line

devInfoData.cbSize = Marshal.SizeOf(devInfoData);

produced a compilation error about implicit conversion from 'int' to 'uint'.
So instead, I changed the line to read

devInfoData.cbSize = 32;

32 is the size pinvoke.net states for 64bit structure; 28 bytes is for 32-bit.

Thanks again!

"holycow" wrote:

> Your definition of SP_DEVINFO_DATA differs from one given by pinvoke.net:
> http://pinvoke.net/default.aspx/Structures/SP_DEVINFO_DATA.html
>
> If your machine is 64 bit, this will matter.
>
>
>
> "santapanda" <santapanda(a)discussions.microsoft.com> wrote in message
> news:F889AC4D-6A3E-410C-9923-EF714631BA00(a)microsoft.com...
> > Hello,
> >
> > I have a C# application using P/Invoke on several SetupDIxxx methods. I am
> > attempting to pass an SP_DEVINFO_DATA object to the
> > SetupDiEnumDeviceInfo()
> > method. I have setup the SP_DEVINFO_DATA struct as follows:
> >
> > [StructLayout(LayoutKind.Sequential)]
> > public struct SP_DEVINFO_DATA
> > {
> > public int cbSize;
> > public System.Guid ClassGuid;
> > public int DevInst;
> > public int Reserved;
> > }
> >
> > Based on articles in the MSDN Library, and an example i found on
> > pinvoke.net, I know I'm supposed to set my object's cbsize to
> > sizeof(SP_DEVINFO_DATA).
> >
> > Here is my code:
> > =====================
> > [...]
> > SP_DEVINFO_DATA devInfoData = new SP_DEVINFO_DATA();
> > IntPtr deviceInfoSet = SetupDiGetClassDevs (ref guids[0], null, 0,
> > DIGCF_PRESENT | DIGCF_ALLCLASSES);
> >
> > if (deviceInfoSet != INVALID_HANDLE_VALUE)
> > {
> > int devIndex = 0;
> > devInfoData.cbSize = Marshal.SizeOf(devInfoData);
> > bool success = SetupDiEnumDeviceInfo(deviceInfoSet, devIndex,
> > out devInfoData);
> > [...]
> > }
> > =====================
> >
> > When I run, I get the error: "The supplied user buffer is not valid for
> > the
> > requested operation." The documentation from MSDN states this error is
> > generated when "the cbSize member is not set correctly for an output
> > parameter".
> >
> > This is my first time using P/Invoke and working with Windows APIs. So
> > please help me understand how to pass the correct cbSize value. When I
> > ran
> > debugger, the cbSize is 0 when the object is going in, but when it comes
> > out
> > the cbSize is 28. I tried setting cbSize prior to calling the
> > SetupDiEnumDeviceInfo method to various values like 28 and 1024, but I
> > still
> > got the same error.
> >
> > Thanks!
>
From: m on
IMHO, the better solution is to add an explicit conversion (cast) or to
change the struct def'n to match the data type (of the same size) that you
can provide. Constants are very useful, but can be annoying when the aren't
;)

"santapanda" <santapanda(a)discussions.microsoft.com> wrote in message
news:7B5E070D-8587-43E2-A57E-5C3468E7238B(a)microsoft.com...
> Thank you,
>
> I changed the structure to the definition provided in pinvoke.net. After
> making that change the line
>
> devInfoData.cbSize = Marshal.SizeOf(devInfoData);
>
> produced a compilation error about implicit conversion from 'int' to
> 'uint'.
> So instead, I changed the line to read
>
> devInfoData.cbSize = 32;
>
> 32 is the size pinvoke.net states for 64bit structure; 28 bytes is for
> 32-bit.
>
> Thanks again!
>
> "holycow" wrote:
>
>> Your definition of SP_DEVINFO_DATA differs from one given by pinvoke.net:
>> http://pinvoke.net/default.aspx/Structures/SP_DEVINFO_DATA.html
>>
>> If your machine is 64 bit, this will matter.
>>
>>
>>
>> "santapanda" <santapanda(a)discussions.microsoft.com> wrote in message
>> news:F889AC4D-6A3E-410C-9923-EF714631BA00(a)microsoft.com...
>> > Hello,
>> >
>> > I have a C# application using P/Invoke on several SetupDIxxx methods. I
>> > am
>> > attempting to pass an SP_DEVINFO_DATA object to the
>> > SetupDiEnumDeviceInfo()
>> > method. I have setup the SP_DEVINFO_DATA struct as follows:
>> >
>> > [StructLayout(LayoutKind.Sequential)]
>> > public struct SP_DEVINFO_DATA
>> > {
>> > public int cbSize;
>> > public System.Guid ClassGuid;
>> > public int DevInst;
>> > public int Reserved;
>> > }
>> >
>> > Based on articles in the MSDN Library, and an example i found on
>> > pinvoke.net, I know I'm supposed to set my object's cbsize to
>> > sizeof(SP_DEVINFO_DATA).
>> >
>> > Here is my code:
>> > =====================
>> > [...]
>> > SP_DEVINFO_DATA devInfoData = new SP_DEVINFO_DATA();
>> > IntPtr deviceInfoSet = SetupDiGetClassDevs (ref guids[0], null, 0,
>> > DIGCF_PRESENT | DIGCF_ALLCLASSES);
>> >
>> > if (deviceInfoSet != INVALID_HANDLE_VALUE)
>> > {
>> > int devIndex = 0;
>> > devInfoData.cbSize = Marshal.SizeOf(devInfoData);
>> > bool success = SetupDiEnumDeviceInfo(deviceInfoSet, devIndex,
>> > out devInfoData);
>> > [...]
>> > }
>> > =====================
>> >
>> > When I run, I get the error: "The supplied user buffer is not valid for
>> > the
>> > requested operation." The documentation from MSDN states this error is
>> > generated when "the cbSize member is not set correctly for an output
>> > parameter".
>> >
>> > This is my first time using P/Invoke and working with Windows APIs. So
>> > please help me understand how to pass the correct cbSize value. When I
>> > ran
>> > debugger, the cbSize is 0 when the object is going in, but when it
>> > comes
>> > out
>> > the cbSize is 28. I tried setting cbSize prior to calling the
>> > SetupDiEnumDeviceInfo method to various values like 28 and 1024, but I
>> > still
>> > got the same error.
>> >
>> > Thanks!
>>
From: santapanda on
Hi,

Interesting suggestion, but I'm not sure I understand 100%. Are you saying
add the cast to:

devInfoData.cbSize = (uint) Marshal.SizeOf(devInfoData)

I had originally declared cbsize as an int, and that's what started the
errors. But after reading your suggestion, I wonder if I should explicitly
set cbSize in my struct:

[StructLayout(LayoutKind.Sequential)]
public struct SP_DEVINFO_DATA
{
public int cbSize = 32;
public System.Guid ClassGuid;
public int DevInst;
public int Reserved;
}

Is that possible?



"m" wrote:

> IMHO, the better solution is to add an explicit conversion (cast) or to
> change the struct def'n to match the data type (of the same size) that you
> can provide. Constants are very useful, but can be annoying when the aren't
> ;)
>
> "santapanda" <santapanda(a)discussions.microsoft.com> wrote in message
> news:7B5E070D-8587-43E2-A57E-5C3468E7238B(a)microsoft.com...
> > Thank you,
> >
> > I changed the structure to the definition provided in pinvoke.net. After
> > making that change the line
> >
> > devInfoData.cbSize = Marshal.SizeOf(devInfoData);
> >
> > produced a compilation error about implicit conversion from 'int' to
> > 'uint'.
> > So instead, I changed the line to read
> >
> > devInfoData.cbSize = 32;
> >
> > 32 is the size pinvoke.net states for 64bit structure; 28 bytes is for
> > 32-bit.
> >
> > Thanks again!
> >
> > "holycow" wrote:
> >
> >> Your definition of SP_DEVINFO_DATA differs from one given by pinvoke.net:
> >> http://pinvoke.net/default.aspx/Structures/SP_DEVINFO_DATA.html
> >>
> >> If your machine is 64 bit, this will matter.
> >>
> >>
> >>
> >> "santapanda" <santapanda(a)discussions.microsoft.com> wrote in message
> >> news:F889AC4D-6A3E-410C-9923-EF714631BA00(a)microsoft.com...
> >> > Hello,
> >> >
> >> > I have a C# application using P/Invoke on several SetupDIxxx methods. I
> >> > am
> >> > attempting to pass an SP_DEVINFO_DATA object to the
> >> > SetupDiEnumDeviceInfo()
> >> > method. I have setup the SP_DEVINFO_DATA struct as follows:
> >> >
> >> > [StructLayout(LayoutKind.Sequential)]
> >> > public struct SP_DEVINFO_DATA
> >> > {
> >> > public int cbSize;
> >> > public System.Guid ClassGuid;
> >> > public int DevInst;
> >> > public int Reserved;
> >> > }
> >> >
> >> > Based on articles in the MSDN Library, and an example i found on
> >> > pinvoke.net, I know I'm supposed to set my object's cbsize to
> >> > sizeof(SP_DEVINFO_DATA).
> >> >
> >> > Here is my code:
> >> > =====================
> >> > [...]
> >> > SP_DEVINFO_DATA devInfoData = new SP_DEVINFO_DATA();
> >> > IntPtr deviceInfoSet = SetupDiGetClassDevs (ref guids[0], null, 0,
> >> > DIGCF_PRESENT | DIGCF_ALLCLASSES);
> >> >
> >> > if (deviceInfoSet != INVALID_HANDLE_VALUE)
> >> > {
> >> > int devIndex = 0;
> >> > devInfoData.cbSize = Marshal.SizeOf(devInfoData);
> >> > bool success = SetupDiEnumDeviceInfo(deviceInfoSet, devIndex,
> >> > out devInfoData);
> >> > [...]
> >> > }
> >> > =====================
> >> >
> >> > When I run, I get the error: "The supplied user buffer is not valid for
> >> > the
> >> > requested operation." The documentation from MSDN states this error is
> >> > generated when "the cbSize member is not set correctly for an output
> >> > parameter".
> >> >
> >> > This is my first time using P/Invoke and working with Windows APIs. So
> >> > please help me understand how to pass the correct cbSize value. When I
> >> > ran
> >> > debugger, the cbSize is 0 when the object is going in, but when it
> >> > comes
> >> > out
> >> > the cbSize is 28. I tried setting cbSize prior to calling the
> >> > SetupDiEnumDeviceInfo method to various values like 28 and 1024, but I
> >> > still
> >> > got the same error.
> >> >
> >> > Thanks!
> >>
> .
>