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




"Michael" <mhugh@xxxxxxxxxx> wrote in message
news:OmenxgQ3GHA.3828@xxxxxxxxxxxxxxxxxxxxxxx
|
| "Willy Denoyette [MVP]" <willy.denoyette@xxxxxxxxxx> wrote in message
| news:uDM5uPQ3GHA.600@xxxxxxxxxxxxxxxxxxxxxxx
| >
| > "Michael" <mhugh@xxxxxxxxxx> wrote in message
| > news:u3GHWvP3GHA.4164@xxxxxxxxxxxxxxxxxxxxxxx
| > | 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.


.



Relevant Pages

  • Re: PInvoke TCHAR[] ??? Having trouble with this.
    ... | I'm having trouble PInvoking a TCHARwithin a struct. ... Please show us your C# struct declaration, ... public System.UInt32 DriverType; ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Sending HTTP request
    ... Using gethostbyname() API you'll be able to get the host address. ... With socketAPI you'll create a new socket descriptor. ... have headers files for C language (both struct definition and function ...
    (comp.sys.ibm.as400.misc)
  • Re: Pointer to "base" type - what does the Standard say about this?
    ... Since the `api' is the first element ... in each struct, it is always safe to convert the struct pointer to ... all of my implementations can (and in fact ... The interfaces are used by the rest of the ...
    (comp.lang.c)
  • Re: Decrypting EFS file
    ... However, this API has a callback that must be fed with data from the file, ... INCLUDING the $EFS stream containing the encryption-related stuff. ... > DWORD m_dwVersionMinor; ... > struct EFS_ENTRY_HEADER ...
    (microsoft.public.windows.file_system)
  • Re: Sending HTTP request
    ... from CLLE or RPGLE ... Using gethostbyname() API you'll be able to get the host address. ... have headers files for C language (both struct definition and function ...
    (comp.sys.ibm.as400.misc)