Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pInvoke readFile() : Overlapped I/O operation is in progress

Tags:

c#

pinvoke

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?

like image 977
boboch Avatar asked Jul 03 '14 11:07

boboch


1 Answers

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?


How to use overlapped I/O from C# easily?

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 FileStreams 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);
}
like image 171
Lucas Trzesniewski Avatar answered Oct 05 '22 11:10

Lucas Trzesniewski