I am trying to associate C # (.NET Compact Framework 3.5) with a Windows CE 6 R2 streaming driver using P / Invoked DeviceIoControl () calls. For one of the IOCTL codes, the driver requires an input buffer, DeviceIoControl, which is the following unmanaged structure containing a built-in pointer:
typedef struct {
DWORD address;
const void* pBuffer;
DWORD size;
} IOCTL_TWL_WRITEREGS_IN;
I defined the structure in C # as:
[StructLayout(LayoutKind.Sequential)]
public struct IoctlWriteRegsIn
{
public uint Address;
public byte[] Buffer;
public uint Size;
}
and my P / Invoke signature:
[DllImport("coredll.dll", CharSet = CharSet.Unicode, SetLastError = true)]
static extern bool DeviceIoControl(IntPtr hDevice,
UInt32 dwIoControlCode,
ref IoctlWriteRegsIn lpInBuffer,
UInt32 nInBufferSize,
UInt32[] lpOutBuffer,
UInt32 nOutBufferSize,
ref UInt32 lpBytesReturned,
IntPtr lpOverlapped);
However, when I call DeviceIoControl () in C #, it always returns false, with the last Win32 error ERROR_INVALID_PARAMETER. Here is the source code fragment from the IOCTL switch statement in the driver that processes the IOCTL code and performs error checking in the input buffer, where inSize is the nInBufferSize parameter:
case IOCTL_TWL_WRITEREGS:
if ((pInBuffer == NULL) ||
(inSize < sizeof(IOCTL_TWL_WRITEREGS_IN)))
{
SetLastError(ERROR_INVALID_PARAMETER);
break;
}
address = ((IOCTL_TWL_WRITEREGS_IN*)pInBuffer)->address;
pBuffer = ((IOCTL_TWL_WRITEREGS_IN*)pInBuffer)->pBuffer;
size = ((IOCTL_TWL_WRITEREGS_IN*)pInBuffer)->size;
if (inSize < (sizeof(IOCTL_TWL_WRITEREGS_IN) + size))
{
SetLastError(ERROR_INVALID_PARAMETER);
break;
}
rc = TWL_WriteRegs(context, address, pBuffer, size);
, - , , . , , # P/Invoke. ?
,
, ++ - :
IOCTL_TWL_WRITEREGS_IN reg;
reg.address = 0x004B0014;
unsigned char data = 0xBE;
reg.pBuffer = &data;
reg.size = sizeof(char);
BOOL writeSuccess = DeviceIoControl(driver, IOCTL_TWL_WRITEREGS, ®, sizeof(IOCTL_TWL_WRITEREGS_IN) + 1, NULL, 0, NULL, NULL);
: !
JaredPar IntPtr P/Invoke SwDevMan81:
[StructLayout(LayoutKind.Sequential)]
public struct IoctlWriteRegsIn
{
public uint Address;
public IntPtr Buffer;
public uint Size;
}
byte regData = 0xFF;
GCHandle pin = GCHandle.Alloc(regData, GCHandleType.Pinned);
IoctlWriteRegsIn writeInBuffer = new IoctlWriteRegsIn{Address = twlBackupRegA, Buffer = pin.AddrOfPinnedObject(), Size = 1};
bool writeSuccess = DeviceIoControl(driverHandle, IoctlTwlWriteRegs, ref writeInBuffer, (uint) Marshal.SizeOf(writeInBuffer) + 1, IntPtr.Zero, 0, ref numBytesReturned, IntPtr.Zero);
[DllImport("coredll.dll", CharSet = CharSet.Unicode, SetLastError = true)]
static extern bool DeviceIoControl(IntPtr hDevice,
UInt32 dwIoControlCode,
ref IoctlWriteRegsIn lpInBuffer,
UInt32 nInBufferSize,
IntPtr lpOutBuffer,
UInt32 nOutBufferSize,
ref UInt32 lpBytesReturned,
IntPtr lpOverlapped);