PInvoke TCHAR[] ??? Having trouble with this.

  • Thread starter Thread starter Michael
  • Start date Start date
M

Michael

Hi all,


I'm having trouble PInvoking a TCHAR[ ] within a struct.
I'll paste the specific struct's API definition below.
I've tried so many numerous variations.
The main Win32 error I get is 0x3f0 / 515L which amounts to ERROR_NO_TOKEN.
Every single instance of this in the past was due to mistakes I made while
within PInvoked structs.
Is anybody able to point me to documentation or just tell me outright how to
do this?
I've been PInvoking a bit for the last few months but never ran accross this
specific data type--not until now.
Any questions or request for more info? Feel free to ask away.

Thanks a lot,
-MH


typedef struct _SP_DRVINFO_DATA {
DWORD cbSize;
DWORD DriverType;
ULONG_PTR Reserved;
TCHAR Description[LINE_LEN];
TCHAR MfgName[LINE_LEN];
TCHAR ProviderName[LINE_LEN];
FILETIME DriverDate;
DWORDLONG DriverVersion;
} SP_DRVINFOR_DATA, *PSP_DRVINFO_DATA;
 
| Hi all,
|
|
| I'm having trouble PInvoking a TCHAR[ ] within a struct.
| I'll paste the specific struct's API definition below.
| I've tried so many numerous variations.
| The main Win32 error I get is 0x3f0 / 515L which amounts to
ERROR_NO_TOKEN.
| Every single instance of this in the past was due to mistakes I made while
| within PInvoked structs.
| Is anybody able to point me to documentation or just tell me outright how
to
| do this?
| I've been PInvoking a bit for the last few months but never ran accross
this
| specific data type--not until now.
| Any questions or request for more info? Feel free to ask away.
|
| Thanks a lot,
| -MH
|
|
| typedef struct _SP_DRVINFO_DATA {
| DWORD cbSize;
| DWORD DriverType;
| ULONG_PTR Reserved;
| TCHAR Description[LINE_LEN];
| TCHAR MfgName[LINE_LEN];
| TCHAR ProviderName[LINE_LEN];
| FILETIME DriverDate;
| DWORDLONG DriverVersion;
| } SP_DRVINFOR_DATA, *PSP_DRVINFO_DATA;
|
|

Please show us your C# struct declaration, and the API's declaration (the
DllImport statement).

A win32 error code is a single integer value, but you say ... Win32 error I
get is 0x3f0 / 515L ..., mind to explain what you really mean here?

Willy.
 
Willy Denoyette said:
| Hi all,
|
|
| I'm having trouble PInvoking a TCHAR[ ] within a struct.
| I'll paste the specific struct's API definition below.
| I've tried so many numerous variations.
| The main Win32 error I get is 0x3f0 / 515L which amounts to
ERROR_NO_TOKEN.
| Every single instance of this in the past was due to mistakes I made
while
| within PInvoked structs.
| Is anybody able to point me to documentation or just tell me outright
how
to
| do this?
| I've been PInvoking a bit for the last few months but never ran accross
this
| specific data type--not until now.
| Any questions or request for more info? Feel free to ask away.
|
| Thanks a lot,
| -MH
|
|
| typedef struct _SP_DRVINFO_DATA {
| DWORD cbSize;
| DWORD DriverType;
| ULONG_PTR Reserved;
| TCHAR Description[LINE_LEN];
| TCHAR MfgName[LINE_LEN];
| TCHAR ProviderName[LINE_LEN];
| FILETIME DriverDate;
| DWORDLONG DriverVersion;
| } SP_DRVINFOR_DATA, *PSP_DRVINFO_DATA;
|
|

Please show us your C# struct declaration, and the API's declaration (the
DllImport statement).

A win32 error code is a single integer value, but you say ... Win32 error
I
get is 0x3f0 / 515L ..., mind to explain what you really mean here?

Willy.
Willy,

Sorry for the confusion. 0x3f0 = 515. I put both depending on what's easier
to recognize.
In the the winerror.h file, it's #defined with 515L. In VS2005 I see it
repored in hex value--
just trying to cover all bases.

the API's declaration is above. My C# declaration is below along w/ the
DllImport of the
function consuming it. My SP_DEVINFO_DATA is used in other Win32 PInvoke
function calls and works so far :).

Thanks,


[DllImport("setupapi.dll", CharSet = CharSet.Ansi, SetLastError = true)]
internal static extern System.Boolean SetupDiGetSelectedDriver
(
System.IntPtr DeviceInfoSet,
ref SP_DEVINFO_DATA DeviceInfoData,
out SP_DRVINFO_DATA DriverInfoData
);


[StructLayout(LayoutKind.Sequential)]
internal class SP_DRVINFO_DATA
{
public System.UInt32 cbSize;
public System.UInt32 DriverType;
public System.IntPtr Reserved;


[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public System.String Description;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public System.String MfgName;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public System.String ProviderName;

public FileTime DriverDate;

public System.UInt64 DriverVersion;
}

[StructLayout(LayoutKind.Sequential)]
internal struct SP_DEVINFO_DATA
{
public System.UInt32 cbSize;
public System.Guid ClassGuid;
public System.UInt32 DevInst;
public System.IntPtr Reserved;
}
 
|
| | >
| > | > | Hi all,
| > |
| > |
| > | I'm having trouble PInvoking a TCHAR[ ] within a struct.
| > | I'll paste the specific struct's API definition below.
| > | I've tried so many numerous variations.
| > | The main Win32 error I get is 0x3f0 / 515L which amounts to
| > ERROR_NO_TOKEN.
| > | Every single instance of this in the past was due to mistakes I made
| > while
| > | within PInvoked structs.
| > | Is anybody able to point me to documentation or just tell me outright
| > how
| > to
| > | do this?
| > | I've been PInvoking a bit for the last few months but never ran
accross
| > this
| > | specific data type--not until now.
| > | Any questions or request for more info? Feel free to ask away.
| > |
| > | Thanks a lot,
| > | -MH
| > |
| > |
| > | typedef struct _SP_DRVINFO_DATA {
| > | DWORD cbSize;
| > | DWORD DriverType;
| > | ULONG_PTR Reserved;
| > | TCHAR Description[LINE_LEN];
| > | TCHAR MfgName[LINE_LEN];
| > | TCHAR ProviderName[LINE_LEN];
| > | FILETIME DriverDate;
| > | DWORDLONG DriverVersion;
| > | } SP_DRVINFOR_DATA, *PSP_DRVINFO_DATA;
| > |
| > |
| >
| > Please show us your C# struct declaration, and the API's declaration
(the
| > DllImport statement).
| >
| > A win32 error code is a single integer value, but you say ... Win32
error
| > I
| > get is 0x3f0 / 515L ..., mind to explain what you really mean here?
| >
| > Willy.
| >
| >
| Willy,
|
| Sorry for the confusion. 0x3f0 = 515. I put both depending on what's
easier
| to recognize.
| In the the winerror.h file, it's #defined with 515L. In VS2005 I see it
| repored in hex value--
| just trying to cover all bases.
|


| the API's declaration is above. My C# declaration is below along w/ the
| DllImport of the
| function consuming it. My SP_DEVINFO_DATA is used in other Win32 PInvoke
| function calls and works so far :).
|
| Thanks,
|
|
| [DllImport("setupapi.dll", CharSet = CharSet.Ansi, SetLastError = true)]
| internal static extern System.Boolean SetupDiGetSelectedDriver
| (
| System.IntPtr DeviceInfoSet,
| ref SP_DEVINFO_DATA DeviceInfoData,
| out SP_DRVINFO_DATA DriverInfoData
| );
|
|
| [StructLayout(LayoutKind.Sequential)]
| internal class SP_DRVINFO_DATA
| {
| public System.UInt32 cbSize;
| public System.UInt32 DriverType;
| public System.IntPtr Reserved;
|
|
| [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
| public System.String Description;
|
| [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
| public System.String MfgName;
|
| [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
| public System.String ProviderName;
|
| public FileTime DriverDate;
|
| public System.UInt64 DriverVersion;
| }
|
| [StructLayout(LayoutKind.Sequential)]
| internal struct SP_DEVINFO_DATA
| {
| public System.UInt32 cbSize;
| public System.Guid ClassGuid;
| public System.UInt32 DevInst;
| public System.IntPtr Reserved;
| }


Hmmm... 0x3fO = 1008 ;-)
Are you sure you pass a valid DeviceInfoSet handle? The error code 1008
cannot be due to an error in SP_DRVINFO_DATA, it's a return argument.

To prove yourself:
Try calling the API passing a IntPtr as third argument (change the API
declaration accordingly)..

Allocate a buffer large enough to hole the structure and pass the IntPtr to
the API.
....
IntPtr DriverInfoData = Marshal.AllocHGlobal(2048);
... SetupDiGetSelectedDriver(...,.., out DriverInfoData );
when done, check the return and when OK, marshal the buffer to the structure
using Marshal.PtrToStructure.
and free the allocated unmanaged buffer by calling
Marshal.FreeHGlobal(DriverInfoData);


Some remarks:
- Use the UNICODE version of the API's whenever available and do it
consequetally throughout your code, so here use CharSet.Unicode for both the
API and the structure declaration.

- Make SP_DRVINFO_DATA a structure like :

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
internal struct SP_DRVINFO_DATA



Willy.
 
Back
Top