|
| | >
| > | > | 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.