Laden...

HID : 997 overlapped i/o operation is in progress Fehlermeldung

Erstellt von moelski vor 10 Jahren Letzter Beitrag vor 10 Jahren 5.642 Views
M
moelski Themenstarter:in
183 Beiträge seit 2011
vor 10 Jahren
HID : 997 overlapped i/o operation is in progress Fehlermeldung

Moin !

Ich habe mir eine Klasse geschrieben um mit einem HID Device zu kommunizieren. Nur leider stoße ich dabei auf ein Problem beim Daten senden:

Fehlermeldung:
997 overlapped i/o operation is in progress

Der Datenempfang läuft über ein Asynchrones Lesen mittels BeginAsyncRead / ReadCompleted. Das funktioniert auch ohne Probleme.
Das Daten Senden wollte ich auch über einen eigenen Thread lösen. Doch sobald ich die Daten schicke bekomme ich eben den oben genannten Fehler. (Die Daten werden zum Senden in eine Queue eingetragen, der Thread über EventWaitHandle angestoßen und dann die Daten gesendet)
Sende ich die Daten aus dem UI Thread direkt klappt alles anstandslos.

Muss ich aufgrund des asynchronen Lesens evtl. Lesen und Schreiben gegeneinander sperren?

Kann mir evtl. jemand einen Tip geben woren das liegen könnte?

Greetz Dominik

D
30 Beiträge seit 2013
vor 10 Jahren

Hallo moelski,

hört sich so an als ob gleichzeitig geschrieben und gelesen werden würde.
Während du im UI Thread async liest, probiert dein anderer Thread zu senden. Dies führt zum Fehler, wie wenn du in eine normale Datei schreibst.
Ich denke du solltest probieren die Threads zu synchronisieren.

Gruß Der_Blob

49.485 Beiträge seit 2005
vor 10 Jahren

Hallo moelski,

bei einem Human Interface Device sollten die Datenmengen eher gering sein. Warum willst du überhaupt aus einem anderen Thread darauf zugreifen? Mir erscheint es ratsam, nur aus dem GUI-Thread auf das HID zu zugreifen ... so wie es das HID von dir scheinbar auch will.

herbivore

M
moelski Themenstarter:in
183 Beiträge seit 2011
vor 10 Jahren

Moin !

Ich denke du solltest probieren ead zum die Threads zu synchronisieren.

Wie könnte ich das angehen? Der Fehler tritt beim Schreiben auf. Und ich schreibe nur einen Output Report mit 65 Byte raus.
Das würde bedeuten dass das Gerät schon mit dem Senden anfängt ohne das der gesamte Report empfangen wurde.
Wie könnte ich den Asynchronen Read denn so lange blocken bis mein Schreibvorgang durch ist ?

bei einem Human Interface Device sollten die Datenmengen eher gering sein.

Sind sie ja im Grunde auch. Das Problem habe ich schon direkt beim ersten Report. Und die Menge der Daten kann ich im Übrigen gar nicht beeinflussen da vom Gerät vorgegeben.

Warum willst du überhaupt aus einem anderen Thread darauf zugreifen?

Ich hätte gerne den Thread für HID Handling getrennt vom UI. Ob das nun zwingend notwendig ist sei mal dahin gestellt. Aber es sollte im Grunde doch funktionieren !?

Mir erscheint es ratsam, nur aus dem GUI-Thread auf das HID zu zugreifen ... so wie es das HID von dir scheinbar auch will.

Müsste es dem HID Device nicht Schnuppe sein von wo die Daten kommen? Auch eine serielle Schnittstelle arbeitet in einem eigenen Thread bezüglich Datenkommunikation. Das sollte bei HID auch klappen.

Nachtrag ...
Ich habe jetzt mal das BeginAsyncRead(); auskommentiert. Bedeutet ja das er erst gar nicht versucht Daten zu lesen. Selbst dann bekomme ich den Fehler 997. 🤔

Greetz Dominik

49.485 Beiträge seit 2005
vor 10 Jahren

Hallo moelski,

Ich hätte gerne den Thread für HID Handling getrennt vom UI. Ob das nun zwingend notwendig ist sei mal dahin gestellt. Aber es sollte im Grunde doch funktionieren !?

wichtig ist doch nur, dass der Code sauber getrennt ist. Für dieses Trennung, ist doch nicht wichtig, in welchem Thread er läuft.

Müsste es dem HID Device nicht Schnuppe sein von wo die Daten kommen?

Die Eingabe gehört genauso zum UI wie die Ausgabe. Insofern gehört die Kommunikation mit einem HID aus meiner Sicht konzeptionell in den GUI-Thread. Die Key-Events von der Tatstatur laufen ja auch im GUI-Thread.

Wie könnte ich den Asynchronen Read denn so lange blocken bis mein Schreibvorgang durch ist ?

Das sollte man gar nicht tun, sondern den Mechanismus nutzen, den die asynchrone Methode anbietet, um zu signalisieren, dass sie fertig ist und da alles weitere tun.

herbivore

D
30 Beiträge seit 2013
vor 10 Jahren

Hi moelski,

probiere mal das Lesen mit allen damit verbunden Objekten auszukommentieren und nur zu schreiben und sage mal was passiert. Ich denke mal zum Lesen und Schreiben in den Stream benutzt du den BinaryReader/Writer. Sobald eine dieser Klassen am Stream ist ( ist sie ab Instanzierung ) kann keine andere Klasse den Stream nutzen.

Wenn das zutrifft, kann man es über Threadsynchronisierung oder aber in einem Thread, wie von herbivore angesprochen, lösen.

Gruß Der_Blob

P.S.: Interessehalber, über was für ein HID reden wir?

M
moelski Themenstarter:in
183 Beiträge seit 2011
vor 10 Jahren

Moin !

Ich denke mal zum Lesen und Schreiben in den Stream benutzt du den BinaryReader/Writer. Sobald eine dieser Klassen am Stream ist ( ist sie ab Instanzierung ) kann keine andere Klasse den Stream nutzen.

Ich kann deinen Vorschlag heute Abend mal testen. Aber vorab mal hierzu...
Was ich dann aber nicht verstehe warum es mit dem UI Thread (schreiben) und einem Pool Thread (lesen mittels Async) funktioniert, nicht aber mit einem eigenen Thread für Schreiben. 🤔

Interessehalber, über was für ein HID reden wir?

Unterschiedliche ... z.B.
Hitec HTS-Navi 2.4GHz USB Telemetry Receiver
IISI Cockpit

PS: Wäre es ok wenn ich hier mal meine HID Klasse einstelle? Vielleicht sieht ja jemand auf den ersten Blick des Pudels Kern und kann dazu was sagen?

Greetz Dominik

D
30 Beiträge seit 2013
vor 10 Jahren

Hi!

Wäre es ok wenn ich hier mal meine HID Klasse einstelle?

Ich denke wir rätseln schon ziemlich lange im dunkeln. 😄
Das könnte aber im Wiederspruch mit [Hinweis] Wie poste ich richtig? Punkt 4 stehen. Warte mal, was herbivore meint.

Was ich dann aber nicht verstehe warum es mit dem UI Thread (schreiben) und einem Pool Thread (lesen mittels Async) funktioniert, nicht aber mit einem eigenen Thread für Schreiben.

Ich denke das hat was mit Reihenfolge zu tun. Wenn du im UI Thread schreibst und dann async liest, um dein UI nicht einzufrieren, geht das, denn du liest und schreibst ja nicht geleichzeitig.

Danke für die Beispiele der HID's
Der_Blob

49.485 Beiträge seit 2005
vor 10 Jahren

Hallo moelski,

Wäre es ok wenn ich hier mal meine HID Klasse einstelle?

nein, dass solltest du nicht tun. Erstelle besser ein minimales Testprogramm, das den Fehler zeigt, wie es in [Tutorial] Vertrackte Fehler durch Vergleich von echtem Projekt mit minimalem Testprojekt finden. Möglicherweise findest du dabei schon den Fehler. Wenn nicht, ist wenigstens der Code-Umfang bestmöglich reduziert.

herbivore

D
30 Beiträge seit 2013
vor 10 Jahren

Nabend,

führst du auch immer sauber Dispose() bzw. Flush() aus. Vielleicht müssen wir nicht so komplex denken.

Schönen Abend noch
Der_Blob

M
moelski Themenstarter:in
183 Beiträge seit 2011
vor 10 Jahren

Moin !

Ich verstehe es nicht. Es gibt auf CodeProject dieses Sample:
A USB HID Component for C#

Wenn ich die Testanwendung starte klappt alles super. Ich bekomme keine Fehler beim Schreiben.

Nun habe ich den minimalen Code aus der Application rausgezogen der nötig wäre um mit einem HID Device zu kommunizieren. Im Grunde nur ein Kommando hinschicken und das ergebnis empfangen.
Der DevicePath ist hard codiert ...

Hier mal der Code:

namespace HIDTest997
{
    using System;
    using System.ComponentModel;
    using System.IO;
    using System.Runtime.InteropServices;

    using Microsoft.Win32.SafeHandles;

    class Program
    {
        #region Sniffer Stuff

        private static IntPtr m_hHandle;
        private static FileStream m_oFile;
        private static int m_nInputReportLength;

        /// <summary>CreateFile : Open file for read</summary>
        protected const uint GENERIC_READ = 0x80000000;
        /// <summary>CreateFile : Open file for write</summary>
        protected const uint GENERIC_WRITE = 0x40000000;
        /// <summary>CreateFile : Resource to be "created" must exist</summary>
        protected const uint OPEN_EXISTING = 3;
        /// <summary>CreateFile : Open handle for overlapped operations</summary>
        protected const uint FILE_FLAG_OVERLAPPED = 0x40000000;
        /// <summary>Simple representation of the handle returned when CreateFile fails.</summary>
        protected static IntPtr InvalidHandleValue = new IntPtr(-1);

        [DllImport("kernel32.dll", SetLastError = true)]
        protected static extern IntPtr CreateFile([MarshalAs(UnmanagedType.LPStr)] string strName, uint nAccess, uint nShareMode, IntPtr lpSecurity, uint nCreationFlags, uint nAttributes, IntPtr lpTemplate);

        #endregion

        static void Main(string[] args)
        {
            string strPath = @"\\?\hid#vid_04d8&pid_fd93#8&2a005973&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}";
            
            m_hHandle = CreateFile(strPath, GENERIC_READ | GENERIC_WRITE, 0, IntPtr.Zero, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, IntPtr.Zero);

            if (m_hHandle != InvalidHandleValue || m_hHandle == null)
            {
                try
                {
                    m_nInputReportLength = 65; 

                    m_oFile = new FileStream(
                        new SafeFileHandle(m_hHandle, false),
                        FileAccess.Read | FileAccess.Write,
                        m_nInputReportLength,
                        true);

                    BeginAsyncRead(); // kick off the first asynchronous read                              
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Failed to get the detailed data from the hid.");
                }
            }
            else 
            {
                m_hHandle = IntPtr.Zero;
                Console.WriteLine("Failed to create device file");
            }

            byte[] send = new byte[65];
            send[1] = 2;

            ShowError("Befor Write");

            try
            {
                m_oFile.Write(send, 0, 65);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            
            ShowError("After Write");

            Console.ReadKey();
        }

        private static void BeginAsyncRead()
        {
            byte[] arrInputReport = new byte[m_nInputReportLength];

            ShowError("Befor Read");
            
            try
            {
                m_oFile.BeginRead(arrInputReport, 0, m_nInputReportLength, new AsyncCallback(ReadCompleted), arrInputReport);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            
            ShowError("After Read");
        }

        protected static void ReadCompleted(IAsyncResult iResult)
        {
            byte[] arrBuff = (byte[])iResult.AsyncState;	// retrieve the read buffer
            try
            {
                m_oFile.EndRead(iResult);
                try
                {
                    string hex = BitConverter.ToString(arrBuff).Replace("-", " ");
                    Console.WriteLine(hex);
                }
                finally
                {
                    BeginAsyncRead();
                }
            }
            catch (IOException ex)	// if we got an IO exception, the device was removed
            {
                Console.WriteLine("Error IO");
            }
        }

        private static void ShowError(string addon)
        {
            int lastWin32Error = Marshal.GetLastWin32Error();
            if (lastWin32Error != 0)
            {
                string win32ErrorMessage = new Win32Exception(lastWin32Error).Message;
                Console.WriteLine("[{2}] {0} (ErrorID : {1})", win32ErrorMessage, lastWin32Error, addon);
            }
            else
            {
                Console.WriteLine("[{0}] OK", addon);
            }
        }
    }
}

Wenn ich die App Starte dann kommt irgendwann BeginAsyncRead. "Befor Read" liefert noch 0 als Error. Aber sobald das BeginRead durchlaufen wurde kriege ich den 997. Und das obwohl der Code 1:1 kopiert ist aus der Testanwendung von Codeproject. Ich verstehe es gerade nicht 🤔

Wenn ich das BeginAsyncRead auskommentiere dann sollte er ja nur noch das Kommando senden. Aber auch hier kriege ich bei After Write den 997.

immer sauber Dispose()

Im Moment noch nicht. Denn ich möchte ja das Handle und den FileStream nutzen und nicht löschen. Aber du hast Recht. Das muss ich auf jeden Fall noch ergänzen. Hilft aber auch nicht bei meinem Problem - schon getestet.

bzw. Flush()

Flush hift nicht. Habe ich auch noch bei keiner HID umsetzung gesehen dass das wer genutzt hätte.

So ich hoffe der Code ist kurz genug =) und evtl. kann jemand den großen misteriösen Bug sehen. 🤔
Kann doch nicht sein das es an der Consolen App hängt, oder?
Wobei den Fehler 997 hatte ich auch schon in einer WinForms Anwendung.

Greetz Dominik

D
30 Beiträge seit 2013
vor 10 Jahren

Hi moelski,

also das der Auruf der Methode BeginAsynRead() eine Endlosschleife aufbaut, die andauernd ohne Pause liest ist dir klar, oder? Wenn man dann noch schreibt fliegt dir's um die Ohren.

Wenn ich das BeginAsyncRead auskommentiere, dann schlägt's fehl.

Keine Ahnung ?(
Hier muss wohl irgendwas, wie exemplarisch die Länge des Streams, nebenbei gelesen werden. Vielleicht schreibt zur selben Zeit auch das HID.

Flush hift nicht.

Die Methode gibt es eh nur bei den Writern. Ich dachte du benutzt den BinaryWriter, aber du nutzt direkt den Stream.

Gruß
Der_Blob

M
moelski Themenstarter:in
183 Beiträge seit 2011
vor 10 Jahren

Moin !

also das der Auruf der Methode BeginAsynRead() eine Endlosschleife aufbaut, die andauernd ohne Pause liest ist dir klar, oder?

Nein bis jetzt nicht. Warum sollte da eine Endlosschleife entstehen? Das Device sendet nur auf Anfrage. Und wenn mehrere Pakete kommen sollen die ja auch gelesen werden.

Ich nutze doch gerade BeginAsynRead / ReadComplete damit der Empfang möglichst im Hintergrund abläuft.

Vielleicht schreibt zur selben Zeit auch das HID.

Def. nein. Das meldet sich nur auf Anfrage.

Greetz Dominik

D
30 Beiträge seit 2013
vor 10 Jahren

Da bin ich mal wieder,

wegen der Endlosschleife, ist eine einfache Geschichte. In BeginAsyncRead() stubst du einen AsyncRead() an mit der Größe des Arrays. Das Lesen wird auch probiert wenn dein Array die Größe 0 hat. Irgendwann kommt dann ReadCompleted dort beendest du das Lesen und rufst im finally erneut BeginAsyncRead() auf. Dort wird dann wieder probiert zu lesen. Das setzt sich endlos fort. Daher kommt das Dauerlesen , was deinen Schreibvorgang blockiert. Hier liegt, meine ich, das Problem.
Um das zu Lösen kannst du entweder Schreiben und Lesen in einem Thread nacheinander laufen lassen (auf jede Frage kommt auch eine Antwort) oder die Threads synchronisieren.

Schönen Tag noch
Der_Blob

M
moelski Themenstarter:in
183 Beiträge seit 2011
vor 10 Jahren

Aha, jetzt wird ein Schuh draus 🙂
Werde ich heute Abend testen. Habe jetzt erst Kinderdienst und Sankt Martin vor der Brust 👅

Nachtrag:
Ich fürchte das ist es auch nicht. Denn wenn ich bei BeginAsyncRead und ReadCompleted einen Breakpoint setze, dann komme ich da auch nur an wenn Daten ankommen. Eine Endlos Loop kann ich da nicht entdecken.
Und die Umsetzung bei dem CodeProject Sample hat das auch genau so implementiert wie oben gezeigt.

Greetz Dominik

M
moelski Themenstarter:in
183 Beiträge seit 2011
vor 10 Jahren

Es ist zum Haare raufen. Beim USB Sniffer von CodeProject habe ich jetzt auch den 997 Fehler.
X(

Langsam habe ich keine Ideen mehr.
Hast du evtl. noch einen Tip herbivore?

Updates:
Ich habe jetzt mal die 32Bit Version auf XP getestet. Dort kriege ich den 997 nicht.
Weiterhin habe ich die UAC auf meinem Win7 64Bit mal ausgeschaltet. Hat aber auch nichts genutzt.

Greetz Dominik

M
moelski Themenstarter:in
183 Beiträge seit 2011
vor 10 Jahren

Moin die Herren,

ich denke ich kann zum einen eine Lösung aufzeigen und zum anderen auch (hoffentlich) ein paar
Details erklären ..

Fangen wir mit letzterem an ...
Ich glaube man darf den windows Fehler 997 nicht als Fehler betrachten sondern nur als Hinweis 👅 Und wenn man sich mal genau den fehlertext ansieht "Overlapped I/O Operation Is in Progress" wird auch klar warum. Die Meldung besagt ja nur das eine Overlapped Operation noch am Werken ist. Nicht mehr und nicht weniger. Auf mein Problem gemünzt bedeutet dass das Schreiben oder das Lesen noch nicht zu Ende ist.

Ich bin dann im Netz über die Win Funktion GetOverlappedResult gestolpert. Und irgendwann hatte ich dann wieder mein geschätztes Buch "USB Complete 4th Edition" auf dem Tisch. Und siehe da ... Dort wird das lesen und Schreiben von HID Reports ganz anders gehandhabt nämlich über WriteFile und ReadFile.
Und bei ReadFile gab es dann auch ein Beispiel wie man denn auf den Fehler 997 reagiert. Dort wird ein Event verwendet das durch ReadFile getriggert wird und letztlich einen Timeout liefert oder eben das komplette Ergebnis.

Ich habe das dann mal in eine Demo gegossen und siehe da ... es gibt zwar noch 997 Meldungen, aber die sind auch logisch denn wenn keine daten kommen kann der lesevorgang nicht abgeschlossen werden. Das führt dann zu einem Timeout und das Spiel geht von vorne los.

**Wenn ich die Testanwendung unter Win32 XP laufen lasse habe ich noch ein kleines Problem. Dort sagt er mir den Fehler 3 "The system cannot find the path specified.". Das verstehe ich noch nicht ganz zumal die Daten sauber weggeschrieben werden und WriteFile auch Success meldet.
Vielleicht hat da jemand eine Idee. **

Aber das grundproblem mit Fehler 997 scheint gelöst (oder sagen wir mal verstanden).

Hier noch meine aktuelle Testapp auf das Wesentliche gestrippt:

namespace HIDTest997
{
    using System;
    using System.ComponentModel;
    using System.Runtime.InteropServices;
    using System.Threading;

    using Microsoft.Win32.SafeHandles;

    class Program 
    {
        private const string strPath = @"\\?\hid#vid_04d8&pid_fd93#9&32d3c4cd&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}";
        //  private const string strPath = @"\\?\hid#vid_04d8&pid_fd93#6&21343d7a&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}";
        
        #region Sniffer Stuff

        private static SafeFileHandle readHandle;
        private static SafeFileHandle writeHandle; 

        private static int m_nInputReportLength;

        internal const Int32 FILE_FLAG_OVERLAPPED = 0X40000000;
        internal const Int32 FILE_SHARE_READ = 1;
        internal const Int32 FILE_SHARE_WRITE = 2;
        internal const UInt32 GENERIC_READ = 0X80000000;
        internal const UInt32 GENERIC_WRITE = 0X40000000;
        internal const Int32 INVALID_HANDLE_VALUE = -1;
        internal const Int32 OPEN_EXISTING = 3;
        internal const Int32 WAIT_TIMEOUT = 0X102;
        internal const Int32 WAIT_OBJECT_0 = 0;    

        [DllImport("kernel32.dll", SetLastError = true)]
        internal static extern Int32 CancelIo(SafeFileHandle hFile);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        internal static extern IntPtr CreateEvent(IntPtr SecurityAttributes, Boolean bManualReset, Boolean bInitialState, String lpName);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        internal static extern SafeFileHandle CreateFile(String lpFileName, UInt32 dwDesiredAccess, Int32 dwShareMode, IntPtr lpSecurityAttributes, Int32 dwCreationDisposition, Int32 dwFlagsAndAttributes, Int32 hTemplateFile);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        internal static extern Boolean GetOverlappedResult(SafeFileHandle hFile, IntPtr lpOverlapped, ref Int32 lpNumberOfBytesTransferred, Boolean bWait);

        [DllImport("kernel32.dll", SetLastError = true)]
        internal static extern Boolean ReadFile(SafeFileHandle hFile, IntPtr lpBuffer, Int32 nNumberOfBytesToRead, ref Int32 lpNumberOfBytesRead, IntPtr lpOverlapped);

        [DllImport("kernel32.dll", SetLastError = true)]
        internal static extern Int32 WaitForSingleObject(IntPtr hHandle, Int32 dwMilliseconds);

        [DllImport("kernel32.dll", SetLastError = true)]
        internal static extern Boolean WriteFile(SafeFileHandle hFile, Byte[] lpBuffer, Int32 nNumberOfBytesToWrite, ref Int32 lpNumberOfBytesWritten, IntPtr lpOverlapped); 

        #endregion
        
        static void Main(string[] args)
        {
            Thread InOutThread = new Thread(DoInOut) { Name = "HID IO Thread" };
        //    this.ContinueThread = true;

            InOutThread.Start();

            byte[] send = new byte[65];
            send[1] = 2;

            writeHandle = CreateFile(strPath, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, 0);
            if (!writeHandle.IsInvalid)
            {
                Int32 numberOfBytesWritten = 0;
                Boolean success = false; 

                try
                {
                    m_nInputReportLength = 65;
                    success = WriteFile(writeHandle, send, send.Length, ref numberOfBytesWritten, IntPtr.Zero);
                    Console.WriteLine("WriteFile success = " + success + " " + numberOfBytesWritten);

                    success = WriteFile(writeHandle, send, send.Length, ref numberOfBytesWritten, IntPtr.Zero);
                    Console.WriteLine("WriteFile success = " + success + " " + numberOfBytesWritten);

                    if (!success)
                    {
                        if (!writeHandle.IsInvalid)
                        {
                            writeHandle.Close();
                        }
                    } 
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Failed to get the detailed data from the hid.");
                }
            }
            else 
            {
                Console.WriteLine("Handle Invalid");
            }

            Console.ReadKey();
        }

        private static void DoInOut()
        {
            readHandle = CreateFile(strPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);

            IntPtr eventObject = IntPtr.Zero;
            NativeOverlapped HidOverlapped = new NativeOverlapped();
            IntPtr nonManagedBuffer = IntPtr.Zero;
            IntPtr nonManagedOverlapped = IntPtr.Zero;
            Int32 numberOfBytesRead = 0;
            Int32 result = 0;

            var inputReportBuffer = new Byte[65]; 

            while (true)
            {
                try
                {
                    //  Set up the overlapped structure for ReadFile.

                    eventObject = CreateEvent(IntPtr.Zero, false, false, "");

                    HidOverlapped.OffsetLow = 0;
                    HidOverlapped.OffsetHigh = 0;
                    HidOverlapped.EventHandle = eventObject;    

                    // Allocate memory for the input buffer and overlapped structure. 

                    nonManagedBuffer = Marshal.AllocHGlobal(inputReportBuffer.Length);
                    nonManagedOverlapped = Marshal.AllocHGlobal(Marshal.SizeOf(HidOverlapped));
                    Marshal.StructureToPtr(HidOverlapped, nonManagedOverlapped, false);

                    ShowError("Befor Read");
                    var success = ReadFile(readHandle, nonManagedBuffer, inputReportBuffer.Length, ref numberOfBytesRead, nonManagedOverlapped);
                    ShowError("After Read");

                    if (!success)
                    {
                        Console.WriteLine("waiting for ReadFile");

                        result = WaitForSingleObject(eventObject, 3000);

                        switch (result)
                        {
                            case WAIT_OBJECT_0:

                                //  ReadFile has completed

                                success = true;
                                Console.WriteLine("ReadFile completed successfully.");

                                GetOverlappedResult(readHandle, nonManagedOverlapped, ref numberOfBytesRead, false);

                                break;

                            case WAIT_TIMEOUT:

                                //  Cancel the operation on timeout

                                //CancelTransfer(hidHandle, readHandle, writeHandle, eventObject);
                                Console.WriteLine("Readfile timeout");
                                success = false;
                                break;
                            default:

                                //  Cancel the operation on other error.

                                //CancelTransfer(hidHandle, readHandle, writeHandle, eventObject);
                                Console.WriteLine("Readfile undefined error");
                                success = false;
                                break;
                        }
                    }

                    if (success)
                    {
                        // A report was received.
                        // Copy the received data to inputReportBuffer for the application to use.

                        Marshal.Copy(nonManagedBuffer, inputReportBuffer, 0, numberOfBytesRead);

                        string hex = BitConverter.ToString(inputReportBuffer).Replace("-", " ");
                        Console.WriteLine(hex);
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    throw;
                }    
            }
        }

        private static void ShowError(string addon)
        {
            int lastWin32Error = Marshal.GetLastWin32Error();
            if (lastWin32Error != 0)
            {
                string win32ErrorMessage = new Win32Exception(lastWin32Error).Message;
                Console.WriteLine("[{2}] {0} (ErrorID : {1})", win32ErrorMessage, lastWin32Error, addon);
            }
            else
            {
                Console.WriteLine("[{0}] OK", addon);
            }
        }
    }
}

Greetz Dominik