I’m trying to port the test application(echoapp.cpp in KMDF\echo\exe) for WDF UMDF echo driver’s to C#, for the purpose of getting a basic GUI up for building other driver test application.
Although my c# code follows the steps of the c++ code in echoapp.cpp, I somehow can’t get pass this problem with SetupDiEnumDeviceInterfaces, error 1784, ERROR_INVALID_USER_BUFFER. I thought it might be the buffer size, but I manually checked it - it’s the same as the CPP code- 28.
SP_DEVICE_INTERFACE_DATA dia = new SP_DEVICE_INTERFACE_DATA();
dia.cbSize = (UInt32) Marshal.SizeOf(dia); //this should be 28; verified w/ Win32 code
I’m on Wndow XP SP2.
I hope someone can still help me out in this Christmas season… Is anyone still here??? ![]()
Here’s my C# code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace APP_CS
{
public partial class TEST : Form
{
public Guid GUID_DEVINTERFACE_ECHO;
[StructLayout(LayoutKind.Sequential)]
public class SP_DEVICE_INTERFACE_DATA
{
public UInt32 cbSize;
public Guid InterfaceClassGuid;
public UInt32 Flags;
public IntPtr Reserved;
};
[StructLayout(LayoutKind.Sequential)]
public class SP_DEVINFO_DATA
{
public uint cbSize;
public Guid ClassGuid;
public uint DevInst; // DEVINST handle
public IntPtr Reserved;
};
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct SP_DEVICE_INTERFACE_DETAIL_DATA
{
public UInt32 cbSize;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string DevicePath;
}
public UInt32 DIGCF_DEFAULT = 0x00000001; // only valid with DIGCF_DEVICEINTERFACE
public UInt32 DIGCF_PRESENT = 0x00000002;
public UInt32 DIGCF_ALLCLASSES = 0x00000004;
public UInt32 DIGCF_PROFILE = 0x00000008;
public UInt32 DIGCF_DEVICEINTERFACE = 0x00000010;
public const short INVALID_HANDLE_VALUE = -1;
[DllImport(@“setupapi.dll”, CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr SetupDiGetClassDevs(
ref Guid ClassGuid, [MarshalAs(UnmanagedType.LPTStr)] string Enumerator,
IntPtr hwndParent, UInt32 Flags);
[DllImport(@“setupapi.dll”, CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool SetupDiEnumDeviceInterfaces(
IntPtr lpDeviceInfoSet, IntPtr devInfo, ref Guid gClass,
Int32 nIndex, ref SP_DEVICE_INTERFACE_DATA oInterfaceData);
[DllImport(@“setupapi.dll”, CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool SetupDiDestroyDeviceInfoList(IntPtr hDevInfo);
[DllImport(@“setupapi.dll”, CharSet = CharSet.Auto, SetLastError = true)]
public static extern Boolean SetupDiGetDeviceInterfaceDetail(
IntPtr hDevInfo,
ref SP_DEVICE_INTERFACE_DATA deviceInterfaceData,
IntPtr deviceInterfaceDetailData,
UInt32 deviceInterfaceDetailDataSize,
out UInt32 requiredSize,
IntPtr deviceInfoData
);
[DllImport(@“setupapi.dll”, SetLastError = true)]
public static extern Boolean SetupDiGetDeviceInterfaceDetail(
IntPtr hDevInfo,
ref SP_DEVICE_INTERFACE_DATA deviceInterfaceData,
ref SP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailData,
UInt32 deviceInterfaceDetailDataSize,
out UInt32 requiredSize,
IntPtr deviceInfoData
);
[DllImport(“Kernel32.dll”, ExactSpelling = true, CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool CloseHandle(int hHandle);
// CreateFile is is Overloaded for having SecurityAttributes or not
[DllImport(“Kernel32.dll”, CharSet = CharSet.Auto, SetLastError = true)]
public static extern int CreateFile(String lpFileName,
int dwDesiredAccess, int dwShareMode, IntPtr lpSecurityAttributes,
int dwCreationDisposition, int dwFlagsAndAttributes,
int hTemplateFile);
[DllImport(“Kernel32.dll”, CharSet = CharSet.Auto, SetLastError = true)]
public static extern int CreateFile(String lpFileName, int
dwDesiredAccess, int dwShareMode, SECURITY_ATTRIBUTES
lpSecurityAttributes, int dwCreationDisposition, int
dwFlagsAndAttributes, int hTemplateFile);
// DeviceIoControl is Overloaded for byte or int data
[DllImport(“Kernel32.dll”, CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool DeviceIoControl(
int hDevice, int dwIoControlCode, byte InBuffer,
int nInBufferSize, byte OutBuffer, int nOutBufferSize,
ref int pBytesReturned, int pOverlapped);
[DllImport(“Kernel32.dll”, CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool DeviceIoControl(
int hDevice, int dwIoControlCode, int InBuffer,
int nInBufferSize, int OutBuffer, int nOutBufferSize,
ref int pBytesReturned, int pOverlapped);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct SECURITY_ATTRIBUTES
{
public int nLength; // DWORD
public IntPtr lpSecurityDescriptor; // LPVOID
public int bInheritHandle; // BOOL
}
private Boolean initDone = false;
private string devicePath;
public TEST()
{
InitializeComponent();
GUID_DEVINTERFACE_ECHO=new Guid(0xcdc35b6e, 0xbe4, 0x4936, 0xbf, 0x5f, 0x55, 0x37, 0x38, 0xa, 0x7c, 0x1a);
}
private void BTNWRITE_Click(object sender, EventArgs e)
{
int i = 0;
UInt32 RequiredSize = 0, nSize;
if (!initDone)
{
status.Text = “Init start”;
IntPtr h = SetupDiGetClassDevs(ref GUID_DEVINTERFACE_ECHO,
null, IntPtr.Zero, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
if (h.ToInt32() == INVALID_HANDLE_VALUE)
{
status.Text = “SetupDiGetClassDevs failed!”;
return;
}
// create a Device Interface Data structure
SP_DEVICE_INTERFACE_DATA dia = new SP_DEVICE_INTERFACE_DATA();
dia.cbSize = (UInt32) Marshal.SizeOf(dia); //this should be 28; verified by working Win32 program
// start the enumeration
bool Success = SetupDiEnumDeviceInterfaces(h, IntPtr.Zero,
ref GUID_DEVINTERFACE_ECHO, i, ref dia);
if (!Success)
{
int err = Marshal.GetLastWin32Error();
status.Text = “SetupDiEnumDeviceInterfaces failed.” + err;
SetupDiDestroyDeviceInfoList(h);
return;
}
//two step process to get interface detail; first the size; then the interface
if (!SetupDiGetDeviceInterfaceDetail(h, ref dia, IntPtr.Zero, 0, out RequiredSize, IntPtr.Zero))
{
status.Text = “1st SetupDiGetDeviceInterfaceDetail call failed.”;
return;
}
SP_DEVICE_INTERFACE_DETAIL_DATA didd = new SP_DEVICE_INTERFACE_DETAIL_DATA();
if (IntPtr.Size == 8)
didd.cbSize = 8;
else
didd.cbSize = 5;
nSize = RequiredSize;
Success = SetupDiGetDeviceInterfaceDetail(h, ref dia,
ref didd, nSize, out RequiredSize, IntPtr.Zero);
if (!Success)
{
status.Text = “2nd SetupDiGetDeviceInterfaceDetail call failed.”;
SetupDiDestroyDeviceInfoList(h);
return;
}
devicePath = didd.DevicePath;
status.Text = didd.DevicePath;
}
else
{
status.Text = “Init Done” + devicePath;
}
}
}
}