I'm trying to develop a function to communicate with an electronic card. I need to use the readFile() function :
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool ReadFile(IntPtr hFile, ref byte lpBuffer,
uint nNumberOfBytesToRead, out uint lpNumberOfBytesRead, Overlapped lpOverlapped);
My function is :
EventObject = CreateEvent(IntPtr.Zero,true,true,"");
lastError = Marshal.GetLastWin32Error();
HIDOverlapped = new System.Threading.Overlapped();
HIDOverlapped.OffsetLow = 0;
HIDOverlapped.OffsetHigh = 0;
HIDOverlapped.EventHandleIntPtr = EventObject;
readHandle = CreateFile(MyDeviceInterfaceDetailData.DevicePath, (GENERIC_READ | GENERIC_WRITE), (FILE_SHARE_READ | FILE_SHARE_WRITE), IntPtr.Zero, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, IntPtr.Zero);
uint numberOfBytesRead;
readBuffer= new byte[8];
string byteValue;
bool result = ReadFile(readHandle, ref readBuffer[0], (uint)capabilities.InputReportByteLength, out numberOfBytesRead, HIDOverlapped);
lastError = Marshal.GetLastWin32Error(); //Problem
The function Marshal.GetLastWin32Error()
in the last line returns error code 997.
In the sencond passage, an other error appears with the code 0xc0000005 (FatalExecutionEngineError) and the software crash.
Have you got an idea of what I can tried?
This is not a problem.
Error code 997 is ERROR_IO_PENDING
, which is what ReadFile
will return upon starting an overlapped read.
From the docs:
Note The GetLastError code ERROR_IO_PENDING is not a failure; it designates the read operation is pending completion asynchronously. For more information, see Remarks.
Remarks:
ReadFile may return before the read operation is complete. In this scenario, ReadFile returns FALSE and the GetLastError function returns ERROR_IO_PENDING, which allows the calling process to continue while the system completes the read operation.
Is using overlapped I/O a requirement?
Using this function definition:
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern SafeFileHandle CreateFile(string lpFileName, uint dwDesiredAccess, uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition, uint dwFlagsAndAttributes, IntPtr hTemplateFile);
You can create regular FileStream
s from a file opened with the Win API:
var fileHandle = CreateFile(.....);
if (fileHandle.IsInvalid)
Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
// The last parameter of the FileStream constructor (isAsync) will make the class use async I/O
using (var stream = new FileStream(fileHandle, FileAccess.ReadWrite, 4096, true))
{
var buffer = new byte[4096];
// Asynchronously read 4kb
var bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With