473,387 Members | 1,420 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

C# HID and Vista 64

Well I am working on trying to get some HID code to work on Windows XP,
Vista 32, and Vista 64. Working on XP and Vista 32 was easy as there are
some great resources on the web; however Vista 64 is a whole other problem.
The first problem was an easy one all the samples show this structure:

[StructLayout(LayoutKind.Sequential)]
public struct SP_DEVICE_INTERFACE_DATA
{
public int cbSize;
public System.Guid InterfaceClassGuid;
public int Flags;
public IntPtr Reserved;
}

For calling the this method, SetupDiEnumDeviceInterfaces, in the
SetupAPI.dll; however most exaple has Reserved as just an Int and on a 64
bit platform that doesn't give you the correct size for an IntPtr. So all
my following problems are related to Vista 64.

Now that I have gotten past that part I am having problems with this method,
SetupDiGetDeviceInterfaceDetail, in SetupAPI.dll. When I call I this method
I get this error from GetLastError: "An attempt was made to reference a
token that does not exist."

Here is what my declartions look like:

[DllImport("setupapi.dll", CharSet = CharSet.Auto)]
static public extern bool SetupDiGetDeviceInterfaceDetail(IntPtr
DeviceInfoSet, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData, IntPtr
DeviceInterfaceDetailData, int DeviceInterfaceDetailDataSize, ref int
RequiredSize, IntPtr DeviceInfoData);

[StructLayout(LayoutKind.Sequential)]
public struct SP_DEVICE_INTERFACE_DATA
{
public int cbSize;
public System.Guid InterfaceClassGuid;
public int Flags;
public IntPtr Reserved;
}

[StructLayout(LayoutKind.Sequential)]
public struct SP_DEVICE_INTERFACE_DETAIL_DATA
{
public int cbSize;
public string DevicePath;
}

The program makes 2 calls to SetupDiGetDeviceInterfaceDetail. The first
call it to get the size of the structure and the second returns a pointer to
the data. However on the frist run both picese return the same error that I
stated above. Here is what the first call looks like:

Success =
DeviceManagementApiDeclarations.SetupDiGetDeviceIn terfaceDetail(
DeviceInfoSet,
ref MyDeviceInterfaceData,
IntPtr.Zero, 0, ref BufferSize, IntPtr.Zero);

Here is the deifinition of the caribales used:
Scuesses = bool
DeviceInforSet = IntPtr
BufferSize = int

After the API call this data is called:

// Store the structure's size.
//MyDeviceInterfaceDetailData.cbSize =
MyDeviceInterfaceDetailData.ToString().Length;
MyDeviceInterfaceDetailData.cbSize =
Marshal.SizeOf(MyDeviceInterfaceDetailData);

// Allocate memory for the MyDeviceInterfaceDetailData Structure using
the returned buffer size.
IntPtr DetailDataBuffer = Marshal.AllocHGlobal(BufferSize);

// Store cbSize in the first 4 bytes of the array
Marshal.WriteInt32(DetailDataBuffer, 4 +
Marshal.SystemDefaultCharSize);
Debug.WriteLine("cbsize = " + MyDeviceInterfaceDetailData.cbSize);

I am pretty sure I would need to change the 4 + to 8 + for 64 bit, but I am
not positive.

Then I call SetupDiGetDeviceInterfaceDetail again:

Success =
DeviceManagementApiDeclarations.SetupDiGetDeviceIn terfaceDetail (
DeviceInfoSet,
ref MyDeviceInterfaceData,
DetailDataBuffer,
BufferSize,
ref BufferSize,
IntPtr.Zero);

After that call this code is run:

IntPtr pdevicePathName = IntPtr.Zero;
if ( Marshal.SizeOf( DeviceInfoSet ) == 4 )
pdevicePathName = new IntPtr(DetailDataBuffer.ToInt32() +
Marshal.SizeOf(DeviceInfoSet));
else
pdevicePathName = new IntPtr(DetailDataBuffer.ToInt64() +
Marshal.SizeOf(DeviceInfoSet));

// Get the String containing the devicePathName.
SingledevicePathName = Marshal.PtrToStringAuto(pdevicePathName);
devicePathName[MemberIndex] = SingledevicePathName;

I just added the code to increment these values based on the Size of IntPtr.

The next time this code runs for the next HID device I get this error: The
supplied user buffer is not valid for the requested operation.

Any help would be greatly appriciated.

Thanks,

Eric Renken

Jun 4 '07 #1
17 6516
>
Any help would be greatly appriciated.
Since all your problems have to do with p/invoke definitions, it would be
well worth your while to make a small C++/CLI dll project to handle all the
API calls. If you make a "public ref class" in C++/CLI and add it to your
application references, it will appear in your C# program just like any C#
class would. Since all the examples are already in C++, this should make
your life a lot easier.
>
Thanks,

Eric Renken

Jun 5 '07 #2
Hi Eric,

I agree with Ben here that writing the code in C++/CLI will be easier and
cleaner.

Setupapi.dll also has a 32-bit version at %windir%\syswow64. If 32-bit
interop is already working fine, why not just compile your C# program in
32-bit so that it calls into 32-bit setupapi.dll?
Regards,
Walter Wang (wa****@online.microsoft.com, remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.

Jun 5 '07 #3
"Eric Renken" <Er********@newsgroup.nospamwrote in message
news:0D**********************************@microsof t.com...
Well I am working on trying to get some HID code to work on Windows XP,
Vista 32, and Vista 64. Working on XP and Vista 32 was easy as there are
some great resources on the web; however Vista 64 is a whole other
problem. The first problem was an easy one all the samples show this
structure:

[StructLayout(LayoutKind.Sequential)]
public struct SP_DEVICE_INTERFACE_DATA
{
public int cbSize;
public System.Guid InterfaceClassGuid;
public int Flags;
public IntPtr Reserved;
}

For calling the this method, SetupDiEnumDeviceInterfaces, in the
SetupAPI.dll; however most exaple has Reserved as just an Int and on a 64
bit platform that doesn't give you the correct size for an IntPtr. So all
my following problems are related to Vista 64.

Now that I have gotten past that part I am having problems with this
method, SetupDiGetDeviceInterfaceDetail, in SetupAPI.dll. When I call I
this method I get this error from GetLastError: "An attempt was made to
reference a token that does not exist."

Here is what my declartions look like:

[DllImport("setupapi.dll", CharSet = CharSet.Auto)]
static public extern bool SetupDiGetDeviceInterfaceDetail(IntPtr
DeviceInfoSet, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData, IntPtr
DeviceInterfaceDetailData, int DeviceInterfaceDetailDataSize, ref int
RequiredSize, IntPtr DeviceInfoData);

[StructLayout(LayoutKind.Sequential)]
public struct SP_DEVICE_INTERFACE_DATA
{
public int cbSize;
public System.Guid InterfaceClassGuid;
public int Flags;
public IntPtr Reserved;
}

[StructLayout(LayoutKind.Sequential)]
public struct SP_DEVICE_INTERFACE_DETAIL_DATA
{
public int cbSize;
public string DevicePath;
}

The program makes 2 calls to SetupDiGetDeviceInterfaceDetail. The first
call it to get the size of the structure and the second returns a pointer
to the data. However on the frist run both picese return the same error
that I stated above. Here is what the first call looks like:

Success =
DeviceManagementApiDeclarations.SetupDiGetDeviceIn terfaceDetail(
DeviceInfoSet,
ref MyDeviceInterfaceData,
IntPtr.Zero, 0, ref BufferSize, IntPtr.Zero);

Here is the deifinition of the caribales used:
Scuesses = bool
DeviceInforSet = IntPtr
BufferSize = int

After the API call this data is called:

// Store the structure's size.
//MyDeviceInterfaceDetailData.cbSize =
MyDeviceInterfaceDetailData.ToString().Length;
MyDeviceInterfaceDetailData.cbSize =
Marshal.SizeOf(MyDeviceInterfaceDetailData);

// Allocate memory for the MyDeviceInterfaceDetailData Structure
using the returned buffer size.
IntPtr DetailDataBuffer = Marshal.AllocHGlobal(BufferSize);

// Store cbSize in the first 4 bytes of the array
Marshal.WriteInt32(DetailDataBuffer, 4 +
Marshal.SystemDefaultCharSize);
Debug.WriteLine("cbsize = " + MyDeviceInterfaceDetailData.cbSize);

I am pretty sure I would need to change the 4 + to 8 + for 64 bit, but I
am not positive.

Then I call SetupDiGetDeviceInterfaceDetail again:

Success =
DeviceManagementApiDeclarations.SetupDiGetDeviceIn terfaceDetail (
DeviceInfoSet,
ref MyDeviceInterfaceData,
DetailDataBuffer,
BufferSize,
ref BufferSize,
IntPtr.Zero);

After that call this code is run:

IntPtr pdevicePathName = IntPtr.Zero;
if ( Marshal.SizeOf( DeviceInfoSet ) == 4 )
pdevicePathName = new IntPtr(DetailDataBuffer.ToInt32() +
Marshal.SizeOf(DeviceInfoSet));
else
pdevicePathName = new IntPtr(DetailDataBuffer.ToInt64() +
Marshal.SizeOf(DeviceInfoSet));

// Get the String containing the devicePathName.
SingledevicePathName = Marshal.PtrToStringAuto(pdevicePathName);
devicePathName[MemberIndex] = SingledevicePathName;

I just added the code to increment these values based on the Size of
IntPtr.

The next time this code runs for the next HID device I get this error:
The supplied user buffer is not valid for the requested operation.

Any help would be greatly appriciated.

Thanks,

Eric Renken


It makes no sense to call SetupDiGetDeviceInterfaceDetail a second time when
the first call did NOT return ERROR_INSUFFICIENT_BUFFER.
Anyway, you need to pass a valid SP_DEVICE_INTERFACE_DATA when calling
SetupDiGetDeviceInterfaceDetail , that is you need to pass a structure that
is returned from a call to SetupDiEnumDeviceInterfaces ; it's not clear
whether you did call this API from your explanation.
So, please post some more code, especially what you did before calling
SetupDiGetDeviceInterfaceDetail is what we need.

Willy.
Jun 5 '07 #4
Thanks everyone for the information. Walter, I did think about having that
DLL run as 32-bit only to make it work, but I am kind of interested in
getting this to work as a 64 bit HID. I think it will help other people
that are trying to do this.

I have never created a C++/CLI I assume I just need to make a C++ project
CLR Class Library.

Thanks,

Eric Renken
"Eric Renken" <Er********@newsgroup.nospamwrote in message
news:0D**********************************@microsof t.com...
Well I am working on trying to get some HID code to work on Windows XP,
Vista 32, and Vista 64. Working on XP and Vista 32 was easy as there are
some great resources on the web; however Vista 64 is a whole other
problem. The first problem was an easy one all the samples show this
structure:

[StructLayout(LayoutKind.Sequential)]
public struct SP_DEVICE_INTERFACE_DATA
{
public int cbSize;
public System.Guid InterfaceClassGuid;
public int Flags;
public IntPtr Reserved;
}

For calling the this method, SetupDiEnumDeviceInterfaces, in the
SetupAPI.dll; however most exaple has Reserved as just an Int and on a 64
bit platform that doesn't give you the correct size for an IntPtr. So all
my following problems are related to Vista 64.

Now that I have gotten past that part I am having problems with this
method, SetupDiGetDeviceInterfaceDetail, in SetupAPI.dll. When I call I
this method I get this error from GetLastError: "An attempt was made to
reference a token that does not exist."

Here is what my declartions look like:

[DllImport("setupapi.dll", CharSet = CharSet.Auto)]
static public extern bool SetupDiGetDeviceInterfaceDetail(IntPtr
DeviceInfoSet, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData, IntPtr
DeviceInterfaceDetailData, int DeviceInterfaceDetailDataSize, ref int
RequiredSize, IntPtr DeviceInfoData);

[StructLayout(LayoutKind.Sequential)]
public struct SP_DEVICE_INTERFACE_DATA
{
public int cbSize;
public System.Guid InterfaceClassGuid;
public int Flags;
public IntPtr Reserved;
}

[StructLayout(LayoutKind.Sequential)]
public struct SP_DEVICE_INTERFACE_DETAIL_DATA
{
public int cbSize;
public string DevicePath;
}

The program makes 2 calls to SetupDiGetDeviceInterfaceDetail. The first
call it to get the size of the structure and the second returns a pointer
to the data. However on the frist run both picese return the same error
that I stated above. Here is what the first call looks like:

Success =
DeviceManagementApiDeclarations.SetupDiGetDeviceIn terfaceDetail(
DeviceInfoSet,
ref MyDeviceInterfaceData,
IntPtr.Zero, 0, ref BufferSize, IntPtr.Zero);

Here is the deifinition of the caribales used:
Scuesses = bool
DeviceInforSet = IntPtr
BufferSize = int

After the API call this data is called:

// Store the structure's size.
//MyDeviceInterfaceDetailData.cbSize =
MyDeviceInterfaceDetailData.ToString().Length;
MyDeviceInterfaceDetailData.cbSize =
Marshal.SizeOf(MyDeviceInterfaceDetailData);

// Allocate memory for the MyDeviceInterfaceDetailData Structure
using the returned buffer size.
IntPtr DetailDataBuffer = Marshal.AllocHGlobal(BufferSize);

// Store cbSize in the first 4 bytes of the array
Marshal.WriteInt32(DetailDataBuffer, 4 +
Marshal.SystemDefaultCharSize);
Debug.WriteLine("cbsize = " + MyDeviceInterfaceDetailData.cbSize);

I am pretty sure I would need to change the 4 + to 8 + for 64 bit, but I
am not positive.

Then I call SetupDiGetDeviceInterfaceDetail again:

Success =
DeviceManagementApiDeclarations.SetupDiGetDeviceIn terfaceDetail (
DeviceInfoSet,
ref MyDeviceInterfaceData,
DetailDataBuffer,
BufferSize,
ref BufferSize,
IntPtr.Zero);

After that call this code is run:

IntPtr pdevicePathName = IntPtr.Zero;
if ( Marshal.SizeOf( DeviceInfoSet ) == 4 )
pdevicePathName = new IntPtr(DetailDataBuffer.ToInt32() +
Marshal.SizeOf(DeviceInfoSet));
else
pdevicePathName = new IntPtr(DetailDataBuffer.ToInt64() +
Marshal.SizeOf(DeviceInfoSet));

// Get the String containing the devicePathName.
SingledevicePathName = Marshal.PtrToStringAuto(pdevicePathName);
devicePathName[MemberIndex] = SingledevicePathName;

I just added the code to increment these values based on the Size of
IntPtr.

The next time this code runs for the next HID device I get this error:
The supplied user buffer is not valid for the requested operation.

Any help would be greatly appriciated.

Thanks,

Eric Renken

Jun 5 '07 #5
I do have a valid structure from SetupDiEnumDeviceInterfaces. Here is the
code that I call there:

Result =
DeviceManagementApiDeclarations.SetupDiEnumDeviceI nterfaces (
DeviceInfoSet,
0,
ref myGuid,
MemberIndex,
ref MyDeviceInterfaceData);

This returns correctly and I don't have any errors.

myGuid = System.Guid
MyDeviceInterfaceData = SP_DEVICE_INTERFACE_DATA

This code is not my own and is based on the code from there:
http://www.lvr.com/hidpage.htm.

Hope this extra code helps. FYI I don't call the code to get the Interface
details if Result= 0.

Thanks,

Eric Renken
"Willy Denoyette [MVP]" <wi*************@telenet.bewrote in message
news:76**********************************@microsof t.com...
"Eric Renken" <Er********@newsgroup.nospamwrote in message
news:0D**********************************@microsof t.com...
>Well I am working on trying to get some HID code to work on Windows XP,
Vista 32, and Vista 64. Working on XP and Vista 32 was easy as there are
some great resources on the web; however Vista 64 is a whole other
problem. The first problem was an easy one all the samples show this
structure:

[StructLayout(LayoutKind.Sequential)]
public struct SP_DEVICE_INTERFACE_DATA
{
public int cbSize;
public System.Guid InterfaceClassGuid;
public int Flags;
public IntPtr Reserved;
}

For calling the this method, SetupDiEnumDeviceInterfaces, in the
SetupAPI.dll; however most exaple has Reserved as just an Int and on a 64
bit platform that doesn't give you the correct size for an IntPtr. So
all my following problems are related to Vista 64.

Now that I have gotten past that part I am having problems with this
method, SetupDiGetDeviceInterfaceDetail, in SetupAPI.dll. When I call I
this method I get this error from GetLastError: "An attempt was made to
reference a token that does not exist."

Here is what my declartions look like:

[DllImport("setupapi.dll", CharSet = CharSet.Auto)]
static public extern bool SetupDiGetDeviceInterfaceDetail(IntPtr
DeviceInfoSet, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData, IntPtr
DeviceInterfaceDetailData, int DeviceInterfaceDetailDataSize, ref int
RequiredSize, IntPtr DeviceInfoData);

[StructLayout(LayoutKind.Sequential)]
public struct SP_DEVICE_INTERFACE_DATA
{
public int cbSize;
public System.Guid InterfaceClassGuid;
public int Flags;
public IntPtr Reserved;
}

[StructLayout(LayoutKind.Sequential)]
public struct SP_DEVICE_INTERFACE_DETAIL_DATA
{
public int cbSize;
public string DevicePath;
}

The program makes 2 calls to SetupDiGetDeviceInterfaceDetail. The first
call it to get the size of the structure and the second returns a pointer
to the data. However on the frist run both picese return the same error
that I stated above. Here is what the first call looks like:

Success =
DeviceManagementApiDeclarations.SetupDiGetDeviceIn terfaceDetail(
DeviceInfoSet,
ref MyDeviceInterfaceData,
IntPtr.Zero, 0, ref BufferSize, IntPtr.Zero);

Here is the deifinition of the caribales used:
Scuesses = bool
DeviceInforSet = IntPtr
BufferSize = int

After the API call this data is called:

// Store the structure's size.
//MyDeviceInterfaceDetailData.cbSize =
MyDeviceInterfaceDetailData.ToString().Length;
MyDeviceInterfaceDetailData.cbSize =
Marshal.SizeOf(MyDeviceInterfaceDetailData);

// Allocate memory for the MyDeviceInterfaceDetailData Structure
using the returned buffer size.
IntPtr DetailDataBuffer = Marshal.AllocHGlobal(BufferSize);

// Store cbSize in the first 4 bytes of the array
Marshal.WriteInt32(DetailDataBuffer, 4 +
Marshal.SystemDefaultCharSize);
Debug.WriteLine("cbsize = " + MyDeviceInterfaceDetailData.cbSize);

I am pretty sure I would need to change the 4 + to 8 + for 64 bit, but I
am not positive.

Then I call SetupDiGetDeviceInterfaceDetail again:

Success =
DeviceManagementApiDeclarations.SetupDiGetDeviceI nterfaceDetail (
DeviceInfoSet,
ref MyDeviceInterfaceData,
DetailDataBuffer,
BufferSize,
ref BufferSize,
IntPtr.Zero);

After that call this code is run:

IntPtr pdevicePathName = IntPtr.Zero;
if ( Marshal.SizeOf( DeviceInfoSet ) == 4 )
pdevicePathName = new IntPtr(DetailDataBuffer.ToInt32() +
Marshal.SizeOf(DeviceInfoSet));
else
pdevicePathName = new IntPtr(DetailDataBuffer.ToInt64() +
Marshal.SizeOf(DeviceInfoSet));

// Get the String containing the devicePathName.
SingledevicePathName = Marshal.PtrToStringAuto(pdevicePathName);
devicePathName[MemberIndex] = SingledevicePathName;

I just added the code to increment these values based on the Size of
IntPtr.

The next time this code runs for the next HID device I get this error:
The supplied user buffer is not valid for the requested operation.

Any help would be greatly appriciated.

Thanks,

Eric Renken

It makes no sense to call SetupDiGetDeviceInterfaceDetail a second time
when the first call did NOT return ERROR_INSUFFICIENT_BUFFER.
Anyway, you need to pass a valid SP_DEVICE_INTERFACE_DATA when calling
SetupDiGetDeviceInterfaceDetail , that is you need to pass a structure
that is returned from a call to SetupDiEnumDeviceInterfaces ; it's not
clear whether you did call this API from your explanation.
So, please post some more code, especially what you did before calling
SetupDiGetDeviceInterfaceDetail is what we need.

Willy.


Jun 5 '07 #6

"Eric Renken" <Er********@newsgroup.nospamwrote in message
news:e6**************@TK2MSFTNGP06.phx.gbl...
Thanks everyone for the information. Walter, I did think about having
that DLL run as 32-bit only to make it work, but I am kind of interested
in getting this to work as a 64 bit HID. I think it will help other
people that are trying to do this.

I have never created a C++/CLI I assume I just need to make a C++ project
CLR Class Library.
Yes, and you'll almost certainly want these, taken from my C++/CLI project
with identical intention (the winsock2 is optional, but if you happen to
need it place it above windows.h):

#define INITGUID

#include <winsock2.h>

#include <windows.h>

#include <setupapi.h>

#include <cfgmgr32.h>

#include <devguid.h>

#include <regstr.h>

#include <assert.h>

#include <dbt.h>

With those, you no longer need *any* of your own declarations.

>
Thanks,

Eric Renken
"Eric Renken" <Er********@newsgroup.nospamwrote in message
news:0D**********************************@microsof t.com...
>Well I am working on trying to get some HID code to work on Windows XP,
Vista 32, and Vista 64. Working on XP and Vista 32 was easy as there are
some great resources on the web; however Vista 64 is a whole other
problem. The first problem was an easy one all the samples show this
structure:

[StructLayout(LayoutKind.Sequential)]
public struct SP_DEVICE_INTERFACE_DATA
{
public int cbSize;
public System.Guid InterfaceClassGuid;
public int Flags;
public IntPtr Reserved;
}

For calling the this method, SetupDiEnumDeviceInterfaces, in the
SetupAPI.dll; however most exaple has Reserved as just an Int and on a 64
bit platform that doesn't give you the correct size for an IntPtr. So
all my following problems are related to Vista 64.

Now that I have gotten past that part I am having problems with this
method, SetupDiGetDeviceInterfaceDetail, in SetupAPI.dll. When I call I
this method I get this error from GetLastError: "An attempt was made to
reference a token that does not exist."

Here is what my declartions look like:

[DllImport("setupapi.dll", CharSet = CharSet.Auto)]
static public extern bool SetupDiGetDeviceInterfaceDetail(IntPtr
DeviceInfoSet, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData, IntPtr
DeviceInterfaceDetailData, int DeviceInterfaceDetailDataSize, ref int
RequiredSize, IntPtr DeviceInfoData);

[StructLayout(LayoutKind.Sequential)]
public struct SP_DEVICE_INTERFACE_DATA
{
public int cbSize;
public System.Guid InterfaceClassGuid;
public int Flags;
public IntPtr Reserved;
}

[StructLayout(LayoutKind.Sequential)]
public struct SP_DEVICE_INTERFACE_DETAIL_DATA
{
public int cbSize;
public string DevicePath;
}

The program makes 2 calls to SetupDiGetDeviceInterfaceDetail. The first
call it to get the size of the structure and the second returns a pointer
to the data. However on the frist run both picese return the same error
that I stated above. Here is what the first call looks like:

Success =
DeviceManagementApiDeclarations.SetupDiGetDeviceIn terfaceDetail(
DeviceInfoSet,
ref MyDeviceInterfaceData,
IntPtr.Zero, 0, ref BufferSize, IntPtr.Zero);

Here is the deifinition of the caribales used:
Scuesses = bool
DeviceInforSet = IntPtr
BufferSize = int

After the API call this data is called:

// Store the structure's size.
//MyDeviceInterfaceDetailData.cbSize =
MyDeviceInterfaceDetailData.ToString().Length;
MyDeviceInterfaceDetailData.cbSize =
Marshal.SizeOf(MyDeviceInterfaceDetailData);

// Allocate memory for the MyDeviceInterfaceDetailData Structure
using the returned buffer size.
IntPtr DetailDataBuffer = Marshal.AllocHGlobal(BufferSize);

// Store cbSize in the first 4 bytes of the array
Marshal.WriteInt32(DetailDataBuffer, 4 +
Marshal.SystemDefaultCharSize);
Debug.WriteLine("cbsize = " + MyDeviceInterfaceDetailData.cbSize);

I am pretty sure I would need to change the 4 + to 8 + for 64 bit, but I
am not positive.

Then I call SetupDiGetDeviceInterfaceDetail again:

Success =
DeviceManagementApiDeclarations.SetupDiGetDeviceI nterfaceDetail (
DeviceInfoSet,
ref MyDeviceInterfaceData,
DetailDataBuffer,
BufferSize,
ref BufferSize,
IntPtr.Zero);

After that call this code is run:

IntPtr pdevicePathName = IntPtr.Zero;
if ( Marshal.SizeOf( DeviceInfoSet ) == 4 )
pdevicePathName = new IntPtr(DetailDataBuffer.ToInt32() +
Marshal.SizeOf(DeviceInfoSet));
else
pdevicePathName = new IntPtr(DetailDataBuffer.ToInt64() +
Marshal.SizeOf(DeviceInfoSet));

// Get the String containing the devicePathName.
SingledevicePathName = Marshal.PtrToStringAuto(pdevicePathName);
devicePathName[MemberIndex] = SingledevicePathName;

I just added the code to increment these values based on the Size of
IntPtr.

The next time this code runs for the next HID device I get this error:
The supplied user buffer is not valid for the requested operation.

Any help would be greatly appriciated.

Thanks,

Eric Renken


Jun 5 '07 #7
Well the C++/CLI is a great idea, but I don't have time to figure out how to
write it. I'm not that much of a C++ programmer. I don't want to put this
entire application in 32 bit format just because 1 DLL is having problems.

This code should work it is just a size of some of the objects. Once I get
this code working I should pretty much be home free, once I can get the
WaitForSingleObject section working on the WriteFile.

We would probably be interested in hiring someone to consult with us to get
this working in Vista 64.

Thanks,

Eric Renken
"Walter Wang [MSFT]" <wa****@online.microsoft.comwrote in message
news:WI**************@TK2MSFTNGHUB02.phx.gbl...
Hi Eric,

I agree with Ben here that writing the code in C++/CLI will be easier and
cleaner.

Setupapi.dll also has a 32-bit version at %windir%\syswow64. If 32-bit
interop is already working fine, why not just compile your C# program in
32-bit so that it calls into 32-bit setupapi.dll?
Regards,
Walter Wang (wa****@online.microsoft.com, remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no
rights.

Jun 6 '07 #8
Hi Eric,

I'm not familiar with the HID related code so currently I'm not able to
reproduce the issue you described. If you have a working reproducible
project at hand, that would be great.

Regards,
Walter Wang (wa****@online.microsoft.com, remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.

Jun 7 '07 #9
"Eric Renken" <Er********@newsgroup.nospamwrote in message
news:%2****************@TK2MSFTNGP03.phx.gbl...
>I do have a valid structure from SetupDiEnumDeviceInterfaces. Here is the
code that I call there:

Result =
DeviceManagementApiDeclarations.SetupDiEnumDeviceI nterfaces (
DeviceInfoSet,
0,
ref myGuid,
MemberIndex,
ref MyDeviceInterfaceData);

This returns correctly and I don't have any errors.

myGuid = System.Guid
MyDeviceInterfaceData = SP_DEVICE_INTERFACE_DATA

This code is not my own and is based on the code from there:
http://www.lvr.com/hidpage.htm.

Hope this extra code helps. FYI I don't call the code to get the
Interface details if Result= 0.
Eric, seems like my latest reply on this got lost somewhere. What you should
do is take care of the padding and alignment of your structures. To do this
simply set the Pack argument in your SP_DEVICE_INTERFACE_DETAIL_DATA
StructLayout attribute to 4, like this.
[StructLayout(LayoutKind.Sequential), Pack=4]

Willy.

Jun 7 '07 #10
Hi Eric,

Thanks for the code.

First issue:

If you're using Marshal.GetLastError, you should include "SetLastError =
true" in your DllImportAttribute; otherwise the last error code isn't
correct. If you add this assertion after first call to
SetupDiGetDeviceInterfaceDetail:

Debug.Assert(error == ERROR_INSUFFICIENT_BUFFER);

The assertion will fail since the reported error code isn't correct.

Next, setupapi.h uses pack(8) for x64 and pack(1) for x86:

#ifdef _WIN64
#include <pshpack8.h // Assume 8-byte (64-bit) packing throughout
#else
#include <pshpack1.h // Assume byte packing throughout (32-bit processor)
#endif

So you will need to declare your struct accordingly:

[StructLayout(LayoutKind.Sequential, Pack=8)]

This also affects the size of SP_DEVICE_INTERFACE_DETAIL_DATA: on x64, the
size will be 8, on x86, the size will be 6. Therefore, after you get the
size and allocated the buffer, use this code on x64:

Marshal.WriterInt32(detailDataBuffer, 8)

I don't think you will be able to use "Any CPU" configuration to make the
code run on both x86 and x64, you may have to use conditional compilation
to compile different assembly.

Hope this helps.
Regards,
Walter Wang (wa****@online.microsoft.com, remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.

Jun 8 '07 #11
Thanks for the tip on SetLastError and the
Marshal.WriteInt32(detailDataBuffer, 8).

I changed this line of code:
Marshal.WriteInt32(detailDataBuffer, Marshal.SizeOf(deviceInformationSet) +
Marshal.SystemDefaultCharSize);

To this:
if (Marshal.SizeOf(typeof(IntPtr)) == 4)
Marshal.WriteInt32(detailDataBuffer, Marshal.SizeOf(deviceInformationSet) +
Marshal.SystemDefaultCharSize);
else
Marshal.WriteInt32(detailDataBuffer, Marshal.SizeOf(typeof(IntPtr)));

And now this part works on x86 and x64 machines. I don't even use the
SP_DEVICE_INTERFACE_DETAIL_DATA structure so I removed it from the code.
Now on to the next steps on loading the HID device that I want.

I'll be back when I hit the next problem.

Thanks for all the help.

Eric Renken


"Walter Wang [MSFT]" <wa****@online.microsoft.comwrote in message
news:RW**************@TK2MSFTNGHUB02.phx.gbl...
Hi Eric,

Thanks for the code.

First issue:

If you're using Marshal.GetLastError, you should include "SetLastError =
true" in your DllImportAttribute; otherwise the last error code isn't
correct. If you add this assertion after first call to
SetupDiGetDeviceInterfaceDetail:

Debug.Assert(error == ERROR_INSUFFICIENT_BUFFER);

The assertion will fail since the reported error code isn't correct.

Next, setupapi.h uses pack(8) for x64 and pack(1) for x86:

#ifdef _WIN64
#include <pshpack8.h // Assume 8-byte (64-bit) packing throughout
#else
#include <pshpack1.h // Assume byte packing throughout (32-bit
processor)
#endif

So you will need to declare your struct accordingly:

[StructLayout(LayoutKind.Sequential, Pack=8)]

This also affects the size of SP_DEVICE_INTERFACE_DETAIL_DATA: on x64, the
size will be 8, on x86, the size will be 6. Therefore, after you get the
size and allocated the buffer, use this code on x64:

Marshal.WriterInt32(detailDataBuffer, 8)

I don't think you will be able to use "Any CPU" configuration to make the
code run on both x86 and x64, you may have to use conditional compilation
to compile different assembly.

Hope this helps.
Regards,
Walter Wang (wa****@online.microsoft.com, remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no
rights.

Jun 8 '07 #12
Hi Eric,

I'm sorry but I cannot clearly tell you what might be wrong since I'm not
clear about following points and the code is not complete yet to reproduce
the issue you mentioned.

1) Is the issue also x64 only?
2) How can I test the code?

If by any chance that you could run the equivalent code in C++, I would
recommend that you test some core function in C++ first, interacting with
hardware is much easier if you're using C/C++.
Regards,
Walter Wang (wa****@online.microsoft.com, remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.

Jun 11 '07 #13
Yes this is x64 only. I can send you the entire project but without the
hardware device I am using I am not sure how you could reproduce. Right now
I am using a prototype piece of hardware. That said with a couple code
change you should be able to easily modify my code to work with any HID
device. Let me know if you want the project.

Eric Renken
"Walter Wang [MSFT]" <wa****@online.microsoft.comwrote in message
news:3%****************@TK2MSFTNGHUB02.phx.gbl...
Hi Eric,

I'm sorry but I cannot clearly tell you what might be wrong since I'm not
clear about following points and the code is not complete yet to reproduce
the issue you mentioned.

1) Is the issue also x64 only?
2) How can I test the code?

If by any chance that you could run the equivalent code in C++, I would
recommend that you test some core function in C++ first, interacting with
hardware is much easier if you're using C/C++.
Regards,
Walter Wang (wa****@online.microsoft.com, remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no
rights.

Jun 11 '07 #14
Hi Eric,

Please feel free to send me the project. Thanks.
Regards,
Walter Wang (wa****@online.microsoft.com, remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.

Jun 12 '07 #15
Can I email it to you? There is some stuff I woul prefer not to release to
the world.

Thanks,

Eric Renken

"Walter Wang [MSFT]" <wa****@online.microsoft.comwrote in message
news:xb**************@TK2MSFTNGHUB02.phx.gbl...
Hi Eric,

Please feel free to send me the project. Thanks.
Regards,
Walter Wang (wa****@online.microsoft.com, remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no
rights.
Jun 12 '07 #16
Hi Eric,

Sorry for not being very clear in my last reply. I meant to send me via
email, my email address is in my signature. Thanks.
Regards,
Walter Wang (wa****@online.microsoft.com, remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.

Jun 13 '07 #17
OK, I finally have it reading and writing on x86 and x64. Now to work on an
OVERLAPPED read, so you may be hearing from me again. Just so everyone
knows the key to getting it to work on x64 was this:

fixed (byte* p = buffer)
{
result = FileIOAPIDeclarations.ReadFile(_hidHandle, p, buffer.Length,
&bytesRead, IntPtr.Zero);
Debug.WriteLine(MyDebugging.ResultOfAPICall("ReadF ile"));
}

fixed (byte* p = buffer)
{
FileIOAPIDeclarations.WriteFile(_hidHandle, p, buffer.Length,
&bytesWritten, IntPtr.Zero);
Debug.WriteLine(MyDebugging.ResultOfAPICall("Write File"));
}

The fixed keyword was the key. Otherwise all that was in your buffer was an
array of 0.

I also had to change the WriteFile and ReadFile declarations to handle this:

[DllImport("kernel32.dll", SetLastError = true)]
static public extern unsafe int ReadFile(IntPtr hFile, void* lpBuffer, int
nNumberOfBytesToRead, int* lpNumberOfBytesRead, IntPtr lpOverlapped);
[DllImport("kernel32.dll", SetLastError = true)]
static public extern unsafe int WriteFile(IntPtr hFile, void* lpBuffer,
int nNumberOfBytesToWrite, int* lpNumberOfBytesWritten, IntPtr
lpOverlapped);

Well I hope this helps someone else.

Eric Renken

"Eric Renken" <Er********@newsgroup.nospamwrote in message
news:0D**********************************@microsof t.com...
Well I am working on trying to get some HID code to work on Windows XP,
Vista 32, and Vista 64. Working on XP and Vista 32 was easy as there are
some great resources on the web; however Vista 64 is a whole other
problem. The first problem was an easy one all the samples show this
structure:

[StructLayout(LayoutKind.Sequential)]
public struct SP_DEVICE_INTERFACE_DATA
{
public int cbSize;
public System.Guid InterfaceClassGuid;
public int Flags;
public IntPtr Reserved;
}

For calling the this method, SetupDiEnumDeviceInterfaces, in the
SetupAPI.dll; however most exaple has Reserved as just an Int and on a 64
bit platform that doesn't give you the correct size for an IntPtr. So all
my following problems are related to Vista 64.

Now that I have gotten past that part I am having problems with this
method, SetupDiGetDeviceInterfaceDetail, in SetupAPI.dll. When I call I
this method I get this error from GetLastError: "An attempt was made to
reference a token that does not exist."

Here is what my declartions look like:

[DllImport("setupapi.dll", CharSet = CharSet.Auto)]
static public extern bool SetupDiGetDeviceInterfaceDetail(IntPtr
DeviceInfoSet, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData, IntPtr
DeviceInterfaceDetailData, int DeviceInterfaceDetailDataSize, ref int
RequiredSize, IntPtr DeviceInfoData);

[StructLayout(LayoutKind.Sequential)]
public struct SP_DEVICE_INTERFACE_DATA
{
public int cbSize;
public System.Guid InterfaceClassGuid;
public int Flags;
public IntPtr Reserved;
}

[StructLayout(LayoutKind.Sequential)]
public struct SP_DEVICE_INTERFACE_DETAIL_DATA
{
public int cbSize;
public string DevicePath;
}

The program makes 2 calls to SetupDiGetDeviceInterfaceDetail. The first
call it to get the size of the structure and the second returns a pointer
to the data. However on the frist run both picese return the same error
that I stated above. Here is what the first call looks like:

Success =
DeviceManagementApiDeclarations.SetupDiGetDeviceIn terfaceDetail(
DeviceInfoSet,
ref MyDeviceInterfaceData,
IntPtr.Zero, 0, ref BufferSize, IntPtr.Zero);

Here is the deifinition of the caribales used:
Scuesses = bool
DeviceInforSet = IntPtr
BufferSize = int

After the API call this data is called:

// Store the structure's size.
//MyDeviceInterfaceDetailData.cbSize =
MyDeviceInterfaceDetailData.ToString().Length;
MyDeviceInterfaceDetailData.cbSize =
Marshal.SizeOf(MyDeviceInterfaceDetailData);

// Allocate memory for the MyDeviceInterfaceDetailData Structure
using the returned buffer size.
IntPtr DetailDataBuffer = Marshal.AllocHGlobal(BufferSize);

// Store cbSize in the first 4 bytes of the array
Marshal.WriteInt32(DetailDataBuffer, 4 +
Marshal.SystemDefaultCharSize);
Debug.WriteLine("cbsize = " + MyDeviceInterfaceDetailData.cbSize);

I am pretty sure I would need to change the 4 + to 8 + for 64 bit, but I
am not positive.

Then I call SetupDiGetDeviceInterfaceDetail again:

Success =
DeviceManagementApiDeclarations.SetupDiGetDeviceIn terfaceDetail (
DeviceInfoSet,
ref MyDeviceInterfaceData,
DetailDataBuffer,
BufferSize,
ref BufferSize,
IntPtr.Zero);

After that call this code is run:

IntPtr pdevicePathName = IntPtr.Zero;
if ( Marshal.SizeOf( DeviceInfoSet ) == 4 )
pdevicePathName = new IntPtr(DetailDataBuffer.ToInt32() +
Marshal.SizeOf(DeviceInfoSet));
else
pdevicePathName = new IntPtr(DetailDataBuffer.ToInt64() +
Marshal.SizeOf(DeviceInfoSet));

// Get the String containing the devicePathName.
SingledevicePathName = Marshal.PtrToStringAuto(pdevicePathName);
devicePathName[MemberIndex] = SingledevicePathName;

I just added the code to increment these values based on the Size of
IntPtr.

The next time this code runs for the next HID device I get this error:
The supplied user buffer is not valid for the requested operation.

Any help would be greatly appriciated.

Thanks,

Eric Renken

Jun 21 '07 #18

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

9
by: salad | last post by:
Due to an earlier posting I read in this newsgroup regarding Office 2007 beta, I downloaded it. After I DL'd it, I got an invitation from MS to get WinVista. I am now wondering if, since both...
13
by: Mark Rae | last post by:
Hi, On Friday I attended the Microsoft EVO conference in London where they talked about Vista, Office 2007 and Exchange 2007 and how they all work together beautifully, how they were all...
56
by: Squishy | last post by:
I tried installing my VS2005 Pro on Vista Ultimate 32 bit RTM today and got errors stating that VS2005 was not compatible with Vista. Microsoft......please pull your finger out of my ass and tell...
0
by: salad | last post by:
I took the Bart down to San Francisco and joined a couple thousand other nerds to watch the Vista/Office launch. The receptionist was quite pleasant and getting the event packets a smooth...
6
by: j2ee.singh | last post by:
Hi, I'm looking to buy a new laptop primarily to learn & practice .NET and C#. My Question is: Is there any requirement for .NET and C# in terms of the following Operating Systems: -...
19
by: =?Utf-8?B?TWlrZTk5MDA=?= | last post by:
When there is a shortcut of our app on the desctop, the app is not run until all the security in control panel of win vista is cleared. What to do to not have this problem. We do not want to tell...
2
by: 13Rockes | last post by:
I am in the process of writing programs using VB6 in XP Pro. However, I am thinking about starting over using VB2005 as my company is migrating to Vista. Two questions... What kinds of...
2
by: David | last post by:
I purchased a Dell for development and selected Vista Business as the OS. I am mostly working on ASP.net, Visual Studio 2005/2008, and SQL 2005. I am considering a switch back to XP pro (Dell...
11
by: idoublepress | last post by:
Hi all, I've been struggling with an issue that I hope you can comment on or provide suggestions to. Our .NET 2.0 (VS2005) based product is crashing (when the user selects a particular feature on...
10
by: nik | last post by:
Hi, I've compiled my application on my vista machine, and it won't run at all on my xp machine. In the windows error report I get Exception code; 0xe0434f4d. I searched for that exception, but...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.