MS-DOS-Devicetreiber mit Assembler oder Borland C++ 3.1



  • Wo gibt es im Internet noch ein Assemblerforum, in dem man auf jemanden hoffen darf, der schon einmal einen Device-Treiber unter DOS geschrieben hat?

    Habe nämlich das Problem beim Schreiben eines zeichenorierntierten Devices (z.B.) "MYDEVICE" , das man als Datei öffnen können soll, daß die Funktion 8 oder 9 (Output) erst nach(!) Schließen der Datei MYDEVICE oder nach fflush() aufgerufen wird, doch ich muß zeichenweise im Deviece Aktionen ausführen.

    (liegt es an einem DOS-Buffer beim Schreiben in Dateien, der das verhindert und/oder wie kann ich den Flush vom Device aus und nicht vom Anwenderprogramm aus erzwingen oder stimmt mit meinen Strukturen zum Device (vielleicht schon beim Oupen) etwas nicht (das Attributwort ist übrigens zwingend E840h)?



  • Verwendest du fopen/fwrite & co? Da ist klar, dass gepuffert wird, das hat mit deinem device gar nix zu tun. Wenn beim fflush deine Treiberfunktion aufgerufen wird, passt doch eh alles.



  • Ringding schrieb:

    Verwendest du fopen/fwrite & co? Da ist klar, dass gepuffert wird, das hat mit deinem device gar nix zu tun. Wenn beim fflush deine Treiberfunktion aufgerufen wird, passt doch eh alles.

    Nein, da paßt leider gar nichts. Denn Der Treiber muß(!) universell sein und auf jedes Zeichen einzeln antworten. Ich habe also keinen Einfluß auf die Anwenderprogramme, dei den Treiber nutzen (sind nicht nur von mir) doch es gibt Treiber, die so etwas (zeichenweise reagieren) können.

    Bin noch nicht ganz sicher, ob Das Buffern im Anwenderprogramm liegt;
    wenn es aber so sein sollte muß ich vielleicht einen Weg finden z.B. die Buffergröße des Anwenderprogramms vom Treiber heraus auf 0 zu setzen, damit bei jedem Zeichen der Buffer überquillt und so "OUT" des Treibers aufgerufen wird.

    Vielleicht wird beim OPEN des Dateidevices (Funktion 13) ja ein Pointer auf die Buffergröße übergeben. Habe aber nicht genug Informationen über die internen vorgänge im DOS dazu und weiß auch nicht, ob das der richtige Weg wäre (bin leider kein Assembler-.Fachmann, muß das aber irgendwie zum Laufen bekommen).



  • Wenn das Anwendungsprogramm will, dass der Treiber jedes Zeichen sofort mitbekommt, dann muss er eben write verwenden und nicht fwrite. fwrite ist eine C-Funktion, die nach Belieben puffern kann.



  • Ringding schrieb:

    Wenn das Anwendungsprogramm will, dass der Treiber jedes Zeichen sofort mitbekommt, dann muss er eben write verwenden und nicht fwrite. fwrite ist eine C-Funktion, die nach Belieben puffern kann.

    Die Anwenderprogramme existieren schon und sind nicht von mir und können auch nicht mehr verändert werden!

    Es gibt keinen anderen Weg, als den Treiber auf jedes Zeichen einzeln reagieren zu lassen, und da es Treiber am Markt gibt, die das können,
    ist es definitiv möglich.
    Nur weiß wohl niemand wie man vom Device aus nach dem OPEN-Befehl mit den ja dann bekannten Adressen von DOS auf den Device-Datei-Buffer zeigt und seine Größe verändern kann!? 😞



  • So nen Thread gabs doch grade erst. Auch von dir, nehm ich an. Wieso fängst du einen neuen an?



  • Bashar schrieb:

    So nen Thread gabs doch grade erst. Auch von dir, nehm ich an. Wieso fängst du einen neuen an?

    Weil er 1. eigentlich nichts mit C zu tun hat (falsche Rubrik und wurde vom Admin nach "Compiler" verschoben)

    und

    2. Keiner eine Antwort auf meine Frage geben konnte wie der OUT-Funktionsaufruf bei jedem Zeichen einzeln zu erzeugen wäre
    (weiß wohl auch niemand, der sich in Forem herumtreibt oder läßt sich sein DOS-Insiderwissen anderswo richtig gut bezahlen...?)



  • Ich kann nach wie vor dein Problem nicht 100% verstehen. Wenn ein write()-Aufruf eines Programms nicht 1:1 mit einem Treiberaufruf korrespondieren würde, würde mich das sehr wundern.



  • Ringding schrieb:

    Ich kann nach wie vor dein Problem nicht 100% verstehen. Wenn ein write()-Aufruf eines Programms nicht 1:1 mit einem Treiberaufruf korrespondieren würde, würde mich das sehr wundern.

    Ich versuche noch einmal zu beschreiben wie es sein sollte:
    Wenn ein Anwenderprogramm (egal ob in Pascal, Assembler oder C) mein Device MYDEVICE mit z.B.
    mydev=fopen (“MYDEVICE“,“wb“); öffnet und danach mit z.B. fprintf(mydev,“%c“,‘X‘); ein ‘X‘ in das Device schreibt, sollte der OUTPUT-Befehl 8 oder OUTPUT_WITH_VERIFY-Befehl 9 sofort bei jedem Zeichen angesprochen werden und nicht nur nach fflush() oder fclose().

    Um das zu kontrollieren bzw. zu kontrollieren, ob beim zeichenweisen Schreiben überhaupt irgend etwas im Device aufgerufen wird) setze ich in der Interruptroutine (hier ein Auszug):
    cld | push ds | push es | push ax | push bx | push cx | push dx | push di | push si
    mov ax,cs:rq_seg ; ES wiederherstellen
    mov es,ax
    mov bx,cs:rq_ofs ; BX wiederherstellen
    mov al,es:[bx].rq_cmd ; Command Code auslesen
    rol al,1 ; mal 2
    lea di,cmd_tab ; Laden der Befehlstabelle
    mov ah,0
    add di,ax ; Index zum Tabellenanfang addiert danach Kontrollausgabe:
    ->hier also bevor danach der indirekte Sprung
    jmp word ptr[di]
    auf die Befehlsverarbeitungs tabelle ausgeführt wird, eine Marke indem ich entweder ein buntes Kästchen in den Videospeicher poke oder über COM1 mit
    mov dx,03f8h
    out dx,al
    ein Zeichen an einen anderen Rechner ausgebe.

    Doch nur bei fopen() und fclose() bzw. nach fflush() signalisiert der Treiber, daß er aufgerufen wurde (nicht bei fprintf() o.ä.).

    Wenn es wirklich daran liegt, daß DOS einen separaten Buffer verwaltet, der das sofortige Ansprechen eines Device-Treibers verhindert, müßte man vielleicht die DOS-Zeichen-Buffergröße auf 0 setzen indem man schon beim OPEN-Befehl 13 versucht, den Zeiger auf den Buffer bzw. den Zeiger auf die Buffergröße zu ermitteln und dann dort in den Speicher des Anwenderprogrammes eine Buffergröße von '0' schreiben.

    In <dos.h> wird da glaube ich so eine Struktur definiert:
    typedef struct FILE {
    unsigned int _flag; /* Flags /
    unsigned int _count; /
    Count remaining /
    int _ugetc; /
    Ungot character */
    unsigned char *_ptr; /* Pointer */
    unsigned char *_buf; /* Buffer /
    unsigned int _conn; /
    Connection /
    unsigned int _resp; /
    Response mailbox token for RMX */
    } FILE; // weiß aber auch nicht, wo da die Größe ist (in _buf ?)

    Aber vielleicht liegt es auch an etwas ganz anderem...?



  • user4711 schrieb:

    Es gibt keinen anderen Weg, als den Treiber auf jedes Zeichen einzeln reagieren zu lassen, und da es Treiber am Markt gibt, die das können,
    ist es definitiv möglich.

    Na so einen Treiber würde ich ja gerne mal sehen! (Will sagen, ich halte es eigentlich, aus den im anderen Thread genannten Gründen, nicht für möglich.)

    Kannst du mal noch mehr Infos rausrücken? Du hast gesagt, das Anwenderprogramm wär schon fertig und nicht mehr zu ändern. Mit was für Geräten arbeitet das normalerweise? Arbeitet es da nicht gepuffert? Oder hängt das vom Gerät bzw. vom Treiber ab?



  • Wo ist der andere Thread?





  • Ah danke, da hab ich sogar gepostet... 😉



  • Bashar schrieb:

    ... mit was für Geräten arbeitet das normalerweise? Arbeitet es da nicht gepuffert? Oder hängt das vom Gerät bzw. vom Treiber ab?

    Die Anwenderprogramme benutzen nur die Funktion des Lesens und Schreibens des Treibers und das klappt mit den anderen Treibern eben zeichenweise mit allen File-Opreationen (nur eben mit meinem Treiber nicht).

    Also entweder Buffert DOS doch nicht und ich mache einen anderen Fehler im Treiber oder es ist Möglich den Buffer zu Umgehen/Kürzen.
    Warum soll das denn auch nicht möglich sein, wenn man weiß, wo DOS intern den Buffer eines Fies und seiner Größe hingelegt hat.

    Oder weiß das nur Bill Gates persönlich ? 😉



  • user4711 schrieb:

    Die Anwenderprogramme benutzen nur die Funktion des Lesens und Schreibens des Treibers und das klappt mit den anderen Treibern eben zeichenweise mit allen File-Opreationen (nur eben mit meinem Treiber nicht).

    Und diese Programme arbeite ganz normal mit stdio-Funktionen ohne fflush und schalten die Pufferung nicht ab? Hast du den Quelltext?

    Also entweder Buffert DOS doch nicht und ich mache einen anderen Fehler im Treiber oder es ist Möglich den Buffer zu Umgehen/Kürzen.
    Warum soll das denn auch nicht möglich sein, wenn man weiß, wo DOS intern den Buffer eines Fies und seiner Größe hingelegt hat.

    Das Problem ist, dass der Puffer nicht von DOS verwaltet wird, sondern innerhalb der Anwendung. Die Kette ist ungefähr so:

    1. Du rufst fprintf auf
    2. Daten werden formatiert (z.B. %d für int usw.) und in den Puffer geschrieben
    3. Wenn der Puffer geleert werden soll (fflush, fclose, oder wenn er voll ist) wird sein Inhalt an das entsprechende Filehandle gesendet, d.h. dem Treiber übergeben
    4. Der Treiber verarbeitet die Daten.

    Du kannst vom Treiber her logischerweise erst ab Schritt 4 eingreifen.



  • Queltexte habe ich natürlich nicht. Den Treiber, der so etwas macht zwar schon, aber alle Disassembler, die ich probiert habe, liefern keine Resultate, die man für ein reverse Engineering gebrauchen könnte.

    Ich vergaß noch zu sagen, daß die Anwenderprogramme nach den Zeichen noch ein CR LF senden, aber auch das veranlaßt bei mir noch kein Schreiben in den Treiber.

    Fakt ist jedenfalls, daß der Treiber existiert und zeichenweise (mit CR LF) funktioniert und zwar mit Anwenderprogrammen, die sowohl unter Pascal, C und Assembler (INT21 AH=40h) geschrieben sind. (Und daß ich ihn auch unbedingt! irgendwie zum Laufen bekommen muß, und wenn es das Letzte ist, was ich auf dieser Erde mache...)


Anmelden zum Antworten