USB Gerät abgesteckt - ERROR_OPERATION_ABORTED [gelöst]



  • Ich habe hier ein USB Gerät, das tut so als ob's ne serielle Schnittstelle wäre.
    Wenn ich ein Handle zu diesem Gerät habe, das Gerät dann abstecke, und danach eine Funktion wie WriteFile aufrufe (mit dem Handle auf das nichtmehr vorhandene Gerät)... dann bekomme ich von Windows als Fehlercode 995 zurück (ERROR_OPERATION_ABORTED).

    Ist das "normal" - bzw. richtiger: bekommt man immer diesen Fehlercode, wenn man versucht ein Handle zu verwenden, welches auf ein Gerät verweist, welches es (warum auch immer) nichtmehr gibt?

    Ich würde den Fall "wurde abgesteckt" nämlich gerne erkennen, da ich in dem Fall einen Worker-Thread beenden kann/sollte.

    Oder gibt's eine andere gute Möglichkeit zu erkennen ob das Handle sozusagen ins Nichts verweist?



  • OK, hihi, hab wohl nicht lange genug probiert.

    Der Fehlercode den ich suchte ich ERROR_DEVICE_NOT_CONNECTED (1167), und er kommt auch, bloss nicht sofort.
    Komisch, aber in meinem Fall gottseidank egal.

    Wenn ich das Gerät abstecke, bekomme ich als erstes ERROR_GEN_FAILURE (31), dann ERROR_OPERATION_ABORTED (995), und dann erst ERROR_DEVICE_NOT_CONNECTED (1167).



  • hustbaer schrieb:

    Wenn ich das Gerät abstecke, bekomme ich als erstes ERROR_GEN_FAILURE (31), dann ERROR_OPERATION_ABORTED (995), und dann erst ERROR_DEVICE_NOT_CONNECTED (1167).

    Hi hustbaer,
    wie hast Du das herausgefunden?
    Machst Du eine kleine Warteschleife, in der laufend GetLastError() abgefragt wird? D.h. die Rückgabewerte ändern sich nacheinander?

    Oder sind das die verschiedenen Fehlermeldungen nach jedem neuen Versuch von WriteFile() mit jeweils anschließendem GetLastError()?

    Martin



  • Mmacher schrieb:

    Oder sind das die verschiedenen Fehlermeldungen nach jedem neuen Versuch von WriteFile() mit jeweils anschließendem GetLastError()?

    Genau das.

    Der Returnwert von GetLastError ist schon "stabil", das wäre ja ziemlich schlimm wenn er das nicht wäre 🙂



  • Danke für die Info.
    Ich selbst habe auch häufig mit seriellen Schnittstellen zu tun.

    Speziell bei IC's von Fa. FTDI gibt es ein Event für "surprise removal" oder so ähnlich. Falls dies Dich interessiert, kann ich Dir die Infos dazu schreiben, ich selbst habe (aus Zeitmangel) diese funktion noch nicht benutzt.

    Unabhängig davon: Falls ich bei einer seriellen Kommunikation ein Problem (also Fehlermeldung egal welcher Art) habe, dann schließe ich den Port und öffne ihn sofort wieder.
    Durch Auswertung von CreateFile() und GetLastError() weiß ich dann 100%ig sicher, ob der Port noch vorhanden ist oder nicht.

    Folgende Fehlermeldungen nach CreateFile() sind meines Wissens nach möglich (auf die schnelle zusammenkopiert):

    handle_comport = CreateFile( tcsz_portname, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL );
        if ( handle_comport != INVALID_HANDLE_VALUE )
        {
          CloseHandle( handle_comport );
          return( "COM-Port vorhanden und frei verfügbar" );
        }
        else
        {
          //CreateFile() ist fehlgeschlagen -> Fehlercode von GetLastError() auswerten.
          switch ( GetLastError() )
          {
            case ERROR_ACCESS_DENIED:                               //=5 Port ist bereits belegt.
            case ERROR_SHARING_VIOLATION:                           //=32 Port ist bereits belegt.
            case ERROR_IRQ_BUSY:                                    //=1119 Es konnte ein Gerät nicht geöffnet werden, das einen IRQ
                                                                    //zusammen mit anderen Geräten verwendet. Mindestens ein weiteres
                                                                    //Gerät, das diesen IRQ verwendet, war bereits geöffnet (1).
            return( "COM-Port vorhanden, aber anderweitig belegt" );
            break;
    
            case ERROR_GEN_FAILURE:                                 //=31 kommt bei einem deaktivierten IrDA-Port vor (1).
            case ERROR_SEM_TIMEOUT:                                 //=121 The semaphore timeout period has expired (2).
            case ERROR_SERIAL_NO_DEVICE:                            //=1118 Es konnte kein serielles Gerät erfolgreich initialisiert werden.
            return( "COM-Port vorhanden, aber fehlerhaft" );
            break;
    
      //      case ERROR_FILE_NOT_FOUND:                              //=2 COM-Port existiert nicht.
            default:                                                //Unerwartete Fehlermeldung -> Im Zweifel "nicht vorhanden".
            return( "COM-Port nicht vorhanden" );
            break;
          }
        }
    

    Nur mal so als kleine Dreingabe von mir 😉
    Martin



  • Danke für die Info.
    Brauch ich zwar nicht, ist aber nett, und vielleicht hilft's ja jmd. anderem 🙂

    Ich prüfe jetzt einfach auf ERROR_DEVICE_NOT_CONNECTED -- wenn ich ERROR_DEVICE_NOT_CONNECTED sehe, beende ich den Kommunikations-Thread, und versuche garnicht erst weiter irgendwas mit dem Device zu machen. Ist eigentlich ne Fleissaufgabe, denn in meinem Fall macht es eigentlich keinen Unterschied -- nur dass das Programm halt nicht weiterhin erfolglos versucht mit dem Device zu reden.



  • Hab mal durch kurze Tests (quick and dirty) herausgefunden, daß der gewünschte Fehlercode ERROR_DEVICE_NOT_CONNECTED manchmal erst nach dem vierten (!) Versuch von WriteFile() kommt.

    Sieht also irgendwie nicht ganz zuverlässig aus, sich nur diesem Fehlercode zu vertrauen.
    In der nächsten Treiberversion (oder anderer Hersteller) kanns schon wieder anders aussehen 😞

    Ist das vielleicht irgendwo dokumentiert?
    Welchen USB-RS232 Konverter verwendest Du? (Sorry falls ich zu neugierig bin 😉 )

    Martin



  • Da es für die Anwendung um die es geht nicht kritisch ist, den Fall "Gerät abgesteckt" zu erkennen, lasse ich es so. Wie ich schon geschreiben habe, ich könnte auch weiterhin versuchen mit dem Gerät zu kommunizieren - würde keinen Unterschied machen.

    Dass es unterschiedlich lange dauern kann ist mir auch schon aufgefallen.

    Um welchen USB Chip es sich dabei handelt kann ich dir nichtmal sagen. Ist auf jeden Fall kein USB RS323 Konverter, sondern ein PIC, der halt ne USB Schnittstelle mit drauf hat, und sich einfach als Serielle Schnittstelle ausgibt. Sozusagen. Eine echte RS323 existiert dabei aber nirgends. (Merkt man auch schon dadurch, dass es vollkommen egal ist, welche Baudrate, Handshake etc. man einstellt)


Log in to reply